xref: /freebsd/sys/dev/smartpqi/smartpqi_event.c (revision 7ea28254ec5376b5deb86c136e1838d0134dbb22)
11e66f787SSean Bruno /*-
2*7ea28254SJohn Hall  * Copyright 2016-2023 Microchip Technology, Inc. and/or its subsidiaries.
31e66f787SSean Bruno  *
41e66f787SSean Bruno  * Redistribution and use in source and binary forms, with or without
51e66f787SSean Bruno  * modification, are permitted provided that the following conditions
61e66f787SSean Bruno  * are met:
71e66f787SSean Bruno  * 1. Redistributions of source code must retain the above copyright
81e66f787SSean Bruno  *    notice, this list of conditions and the following disclaimer.
91e66f787SSean Bruno  * 2. Redistributions in binary form must reproduce the above copyright
101e66f787SSean Bruno  *    notice, this list of conditions and the following disclaimer in the
111e66f787SSean Bruno  *    documentation and/or other materials provided with the distribution.
121e66f787SSean Bruno  *
131e66f787SSean Bruno  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
141e66f787SSean Bruno  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
151e66f787SSean Bruno  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
161e66f787SSean Bruno  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
171e66f787SSean Bruno  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
181e66f787SSean Bruno  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
191e66f787SSean Bruno  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
201e66f787SSean Bruno  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
211e66f787SSean Bruno  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
221e66f787SSean Bruno  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
231e66f787SSean Bruno  * SUCH DAMAGE.
241e66f787SSean Bruno  */
251e66f787SSean Bruno 
261e66f787SSean Bruno 
271e66f787SSean Bruno #include"smartpqi_includes.h"
281e66f787SSean Bruno 
291e66f787SSean Bruno /*
301e66f787SSean Bruno  * Function to rescan the devices connected to adapter.
311e66f787SSean Bruno  */
321e66f787SSean Bruno int
pqisrc_rescan_devices(pqisrc_softstate_t * softs)331e66f787SSean Bruno pqisrc_rescan_devices(pqisrc_softstate_t *softs)
341e66f787SSean Bruno {
351e66f787SSean Bruno 	int ret;
361e66f787SSean Bruno 
371e66f787SSean Bruno 	DBG_FUNC("IN\n");
381e66f787SSean Bruno 
391e66f787SSean Bruno 	os_sema_lock(&softs->scan_lock);
401e66f787SSean Bruno 
411e66f787SSean Bruno 	ret = pqisrc_scan_devices(softs);
421e66f787SSean Bruno 
431e66f787SSean Bruno 	os_sema_unlock(&softs->scan_lock);
441e66f787SSean Bruno 
451e66f787SSean Bruno 	DBG_FUNC("OUT\n");
461e66f787SSean Bruno 
471e66f787SSean Bruno 	return ret;
481e66f787SSean Bruno }
491e66f787SSean Bruno 
509fac68fcSPAPANI SRIKANTH void
pqisrc_wait_for_rescan_complete(pqisrc_softstate_t * softs)519fac68fcSPAPANI SRIKANTH pqisrc_wait_for_rescan_complete(pqisrc_softstate_t *softs)
52b17f4335SSean Bruno {
53b17f4335SSean Bruno 	os_sema_lock(&softs->scan_lock);
54b17f4335SSean Bruno 	os_sema_unlock(&softs->scan_lock);
55b17f4335SSean Bruno }
56b17f4335SSean Bruno 
571e66f787SSean Bruno /*
581e66f787SSean Bruno  * Subroutine to acknowledge the events processed by the driver to the adapter.
591e66f787SSean Bruno  */
601e66f787SSean Bruno static void
pqisrc_acknowledge_event(pqisrc_softstate_t * softs,struct pqi_event * event)611e66f787SSean Bruno pqisrc_acknowledge_event(pqisrc_softstate_t *softs,
621e66f787SSean Bruno 	struct pqi_event *event)
631e66f787SSean Bruno {
641e66f787SSean Bruno 
65*7ea28254SJohn Hall 	int ret;
661e66f787SSean Bruno 	pqi_event_acknowledge_request_t request;
671e66f787SSean Bruno 	ib_queue_t *ib_q = &softs->op_raid_ib_q[0];
681e66f787SSean Bruno 	int tmo = PQISRC_EVENT_ACK_RESP_TIMEOUT;
691e66f787SSean Bruno 	memset(&request,0,sizeof(request));
701e66f787SSean Bruno 
711e66f787SSean Bruno 	DBG_FUNC("IN\n");
721e66f787SSean Bruno 
731e66f787SSean Bruno 	request.header.iu_type = PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT;
741e66f787SSean Bruno 	request.header.iu_length = (sizeof(pqi_event_acknowledge_request_t) -
751e66f787SSean Bruno 								PQI_REQUEST_HEADER_LENGTH);
761e66f787SSean Bruno 	request.event_type = event->event_type;
771e66f787SSean Bruno 	request.event_id   = event->event_id;
781e66f787SSean Bruno 	request.additional_event_id = event->additional_event_id;
791e66f787SSean Bruno 
801e66f787SSean Bruno 	/* Submit Event Acknowledge */
81*7ea28254SJohn Hall 	ret = pqisrc_submit_cmnd(softs, ib_q, &request);
82*7ea28254SJohn Hall 	if (ret != PQI_STATUS_SUCCESS) {
83*7ea28254SJohn Hall 		DBG_ERR("Unable to submit acknowledge command\n");
84*7ea28254SJohn Hall 		goto out;
85*7ea28254SJohn Hall 	}
861e66f787SSean Bruno 
871e66f787SSean Bruno 	/*
881e66f787SSean Bruno 	 * We have to special-case this type of request because the firmware
891e66f787SSean Bruno 	 * does not generate an interrupt when this type of request completes.
901e66f787SSean Bruno 	 * Therefore, we have to poll until we see that the firmware has
911e66f787SSean Bruno 	 * consumed the request before we move on.
921e66f787SSean Bruno 	 */
931e66f787SSean Bruno 
941e66f787SSean Bruno 	COND_WAIT(((ib_q->pi_local) == *(ib_q->ci_virt_addr)), tmo);
951e66f787SSean Bruno 		if (tmo <= 0) {
961e66f787SSean Bruno 			DBG_ERR("wait for event acknowledge timed out\n");
971e66f787SSean Bruno 			DBG_ERR("tmo : %d\n",tmo);
981e66f787SSean Bruno  		}
991e66f787SSean Bruno 
100*7ea28254SJohn Hall out:
1011e66f787SSean Bruno 	DBG_FUNC("OUT\n");
1021e66f787SSean Bruno }
1031e66f787SSean Bruno 
1041e66f787SSean Bruno /*
1051e66f787SSean Bruno  * Acknowledge processed events to the adapter.
1061e66f787SSean Bruno  */
1071e66f787SSean Bruno void
pqisrc_ack_all_events(void * arg1)1081e66f787SSean Bruno pqisrc_ack_all_events(void *arg1)
1091e66f787SSean Bruno {
1101e66f787SSean Bruno 	int i;
1111e66f787SSean Bruno 	struct pqi_event *pending_event;
1121e66f787SSean Bruno 	pqisrc_softstate_t *softs = (pqisrc_softstate_t*)arg1;
1131e66f787SSean Bruno 
1141e66f787SSean Bruno 	DBG_FUNC(" IN\n");
1151e66f787SSean Bruno 
1169fac68fcSPAPANI SRIKANTH 
1171e66f787SSean Bruno 	pending_event = &softs->pending_events[0];
1181e66f787SSean Bruno 	for (i=0; i < PQI_NUM_SUPPORTED_EVENTS; i++) {
1191e66f787SSean Bruno 		if (pending_event->pending == true) {
1201e66f787SSean Bruno 			pending_event->pending = false;
1211e66f787SSean Bruno 			pqisrc_acknowledge_event(softs, pending_event);
1221e66f787SSean Bruno 		}
1231e66f787SSean Bruno 		pending_event++;
1241e66f787SSean Bruno 	}
1251e66f787SSean Bruno 
1261e66f787SSean Bruno 	/* Rescan devices except for heartbeat event */
1271e66f787SSean Bruno 	if ((pqisrc_rescan_devices(softs)) != PQI_STATUS_SUCCESS) {
1281e66f787SSean Bruno 			DBG_ERR(" Failed to Re-Scan devices\n ");
1291e66f787SSean Bruno 	}
1301e66f787SSean Bruno 	DBG_FUNC(" OUT\n");
1311e66f787SSean Bruno 
1321e66f787SSean Bruno }
1331e66f787SSean Bruno 
1341e66f787SSean Bruno /*
1351e66f787SSean Bruno  * Get event index from event type to validate the type of event.
1361e66f787SSean Bruno  */
1371e66f787SSean Bruno static int
pqisrc_event_type_to_event_index(unsigned event_type)1381e66f787SSean Bruno pqisrc_event_type_to_event_index(unsigned event_type)
1391e66f787SSean Bruno {
1401e66f787SSean Bruno 	int index;
1411e66f787SSean Bruno 
1421e66f787SSean Bruno 	switch (event_type) {
1431e66f787SSean Bruno 	case PQI_EVENT_TYPE_HOTPLUG:
1441e66f787SSean Bruno 		index = PQI_EVENT_HOTPLUG;
1451e66f787SSean Bruno 		break;
1461e66f787SSean Bruno 	case PQI_EVENT_TYPE_HARDWARE:
1471e66f787SSean Bruno 		index = PQI_EVENT_HARDWARE;
1481e66f787SSean Bruno 		break;
1491e66f787SSean Bruno 	case PQI_EVENT_TYPE_PHYSICAL_DEVICE:
1501e66f787SSean Bruno 		index = PQI_EVENT_PHYSICAL_DEVICE;
1511e66f787SSean Bruno 		break;
1521e66f787SSean Bruno 	case PQI_EVENT_TYPE_LOGICAL_DEVICE:
1531e66f787SSean Bruno 		index = PQI_EVENT_LOGICAL_DEVICE;
1541e66f787SSean Bruno 		break;
1551e66f787SSean Bruno 	case PQI_EVENT_TYPE_AIO_STATE_CHANGE:
1561e66f787SSean Bruno 		index = PQI_EVENT_AIO_STATE_CHANGE;
1571e66f787SSean Bruno 		break;
1581e66f787SSean Bruno 	case PQI_EVENT_TYPE_AIO_CONFIG_CHANGE:
1591e66f787SSean Bruno 		index = PQI_EVENT_AIO_CONFIG_CHANGE;
1601e66f787SSean Bruno 		break;
1611e66f787SSean Bruno 	default:
1621e66f787SSean Bruno 		index = -1;
1631e66f787SSean Bruno 		break;
1641e66f787SSean Bruno 	}
1651e66f787SSean Bruno 
1661e66f787SSean Bruno 	return index;
1671e66f787SSean Bruno }
1681e66f787SSean Bruno 
1691e66f787SSean Bruno /*
1701e66f787SSean Bruno  * Function used to process the events supported by the adapter.
1711e66f787SSean Bruno  */
1721e66f787SSean Bruno int
pqisrc_process_event_intr_src(pqisrc_softstate_t * softs,int obq_id)1731e66f787SSean Bruno pqisrc_process_event_intr_src(pqisrc_softstate_t *softs,int obq_id)
1741e66f787SSean Bruno {
1751e66f787SSean Bruno 	uint32_t obq_pi,obq_ci;
1761e66f787SSean Bruno 	pqi_event_response_t response;
1771e66f787SSean Bruno 	ob_queue_t *event_q;
1781e66f787SSean Bruno 	struct pqi_event *pending_event;
1791e66f787SSean Bruno 	boolean_t  need_delayed_work = false;
1801e66f787SSean Bruno 
1811e66f787SSean Bruno 	DBG_FUNC(" IN\n");
1821e66f787SSean Bruno 
1831e66f787SSean Bruno 	event_q = &softs->event_q;
1841e66f787SSean Bruno 	obq_ci = event_q->ci_local;
1851e66f787SSean Bruno 	obq_pi = *(event_q->pi_virt_addr);
1861e66f787SSean Bruno 
1871e66f787SSean Bruno 	while(1) {
1881e66f787SSean Bruno 		int event_index;
189*7ea28254SJohn Hall 		DBG_INFO("Event queue_id : %d, ci : %u, pi : %u\n",obq_id, obq_ci, obq_pi);
1901e66f787SSean Bruno 		if (obq_pi == obq_ci)
1911e66f787SSean Bruno 			break;
1921e66f787SSean Bruno 
1931e66f787SSean Bruno 		need_delayed_work = true;
1941e66f787SSean Bruno 
1951e66f787SSean Bruno 		/* Copy the response */
1961e66f787SSean Bruno 		memcpy(&response, event_q->array_virt_addr + (obq_ci * event_q->elem_size),
1971e66f787SSean Bruno 					sizeof(pqi_event_response_t));
198*7ea28254SJohn Hall 		DBG_INIT("event iu_type=0x%x event_type=0x%x\n",
199*7ea28254SJohn Hall 			response.header.iu_type, response.event_type);
2001e66f787SSean Bruno 
2011e66f787SSean Bruno 		event_index = pqisrc_event_type_to_event_index(response.event_type);
202*7ea28254SJohn Hall 		if ( event_index == PQI_EVENT_LOGICAL_DEVICE) {
203*7ea28254SJohn Hall 			softs->ld_rescan = true;
204*7ea28254SJohn Hall 		}
2051e66f787SSean Bruno 
2061e66f787SSean Bruno 		if (event_index >= 0) {
2071e66f787SSean Bruno 			if(response.request_acknowledge) {
2081e66f787SSean Bruno 				pending_event = &softs->pending_events[event_index];
2091e66f787SSean Bruno 				pending_event->pending = true;
2101e66f787SSean Bruno 				pending_event->event_type = response.event_type;
2111e66f787SSean Bruno 				pending_event->event_id = response.event_id;
2121e66f787SSean Bruno 				pending_event->additional_event_id = response.additional_event_id;
2131e66f787SSean Bruno 			}
2141e66f787SSean Bruno 		}
2151e66f787SSean Bruno 
2161e66f787SSean Bruno 	obq_ci = (obq_ci + 1) % event_q->num_elem;
2171e66f787SSean Bruno 	}
2181e66f787SSean Bruno     /* Update CI */
2191e66f787SSean Bruno 	event_q->ci_local = obq_ci;
2201e66f787SSean Bruno 	PCI_MEM_PUT32(softs, event_q->ci_register_abs,
2211e66f787SSean Bruno         event_q->ci_register_offset, event_q->ci_local);
2221e66f787SSean Bruno 
2231e66f787SSean Bruno 	/*Adding events to the task queue for acknowledging*/
2241e66f787SSean Bruno 	if (need_delayed_work == true) {
2251e66f787SSean Bruno 		os_eventtaskqueue_enqueue(softs);
2261e66f787SSean Bruno 	}
2271e66f787SSean Bruno 
2281e66f787SSean Bruno 	DBG_FUNC("OUT");
2291e66f787SSean Bruno 	return PQI_STATUS_SUCCESS;
2301e66f787SSean Bruno 
2319fac68fcSPAPANI SRIKANTH 
2321e66f787SSean Bruno }
2331e66f787SSean Bruno 
2341e66f787SSean Bruno /*
235*7ea28254SJohn Hall  * Function used to build and send the vendor general request
236*7ea28254SJohn Hall  * Used for configuring PQI feature bits between firmware and driver
237*7ea28254SJohn Hall  */
238*7ea28254SJohn Hall int
pqisrc_build_send_vendor_request(pqisrc_softstate_t * softs,struct pqi_vendor_general_request * request)239*7ea28254SJohn Hall pqisrc_build_send_vendor_request(pqisrc_softstate_t *softs,
240*7ea28254SJohn Hall 	struct pqi_vendor_general_request *request)
241*7ea28254SJohn Hall {
242*7ea28254SJohn Hall 	int ret = PQI_STATUS_SUCCESS;
243*7ea28254SJohn Hall 	ib_queue_t *op_ib_q = &softs->op_raid_ib_q[PQI_DEFAULT_IB_QUEUE];
244*7ea28254SJohn Hall 	ob_queue_t *ob_q = &softs->op_ob_q[PQI_DEFAULT_IB_QUEUE];
245*7ea28254SJohn Hall 
246*7ea28254SJohn Hall 	rcb_t *rcb = NULL;
247*7ea28254SJohn Hall 
248*7ea28254SJohn Hall 	/* Get the tag */
249*7ea28254SJohn Hall 	request->request_id = pqisrc_get_tag(&softs->taglist);
250*7ea28254SJohn Hall 	if (INVALID_ELEM == request->request_id) {
251*7ea28254SJohn Hall 		DBG_ERR("Tag not available\n");
252*7ea28254SJohn Hall 		ret = PQI_STATUS_FAILURE;
253*7ea28254SJohn Hall 		goto err_notag;
254*7ea28254SJohn Hall 	}
255*7ea28254SJohn Hall 
256*7ea28254SJohn Hall 	request->response_id = ob_q->q_id;
257*7ea28254SJohn Hall 
258*7ea28254SJohn Hall 	rcb = &softs->rcb[request->request_id];
259*7ea28254SJohn Hall 
260*7ea28254SJohn Hall 	rcb->req_pending = true;
261*7ea28254SJohn Hall 	rcb->tag = request->request_id;
262*7ea28254SJohn Hall 
263*7ea28254SJohn Hall 	ret = pqisrc_submit_cmnd(softs, op_ib_q, request);
264*7ea28254SJohn Hall 
265*7ea28254SJohn Hall 	if (ret != PQI_STATUS_SUCCESS) {
266*7ea28254SJohn Hall 		DBG_ERR("Unable to submit command\n");
267*7ea28254SJohn Hall 		goto err_out;
268*7ea28254SJohn Hall 	}
269*7ea28254SJohn Hall 
270*7ea28254SJohn Hall 	ret = pqisrc_wait_on_condition(softs, rcb, PQISRC_CMD_TIMEOUT);
271*7ea28254SJohn Hall 	if (ret != PQI_STATUS_SUCCESS) {
272*7ea28254SJohn Hall 		DBG_ERR("Management request timed out!\n");
273*7ea28254SJohn Hall 		goto err_out;
274*7ea28254SJohn Hall 	}
275*7ea28254SJohn Hall 
276*7ea28254SJohn Hall 	ret = rcb->status;
277*7ea28254SJohn Hall 
278*7ea28254SJohn Hall err_out:
279*7ea28254SJohn Hall 	os_reset_rcb(rcb);
280*7ea28254SJohn Hall 	pqisrc_put_tag(&softs->taglist, request->request_id);
281*7ea28254SJohn Hall err_notag:
282*7ea28254SJohn Hall 	DBG_FUNC("OUT \n");
283*7ea28254SJohn Hall 	return ret;
284*7ea28254SJohn Hall }
285*7ea28254SJohn Hall 
286*7ea28254SJohn Hall /*
2871e66f787SSean Bruno  * Function used to send a general management request to adapter.
2881e66f787SSean Bruno  */
2899fac68fcSPAPANI SRIKANTH int
pqisrc_submit_management_req(pqisrc_softstate_t * softs,pqi_event_config_request_t * request)2909fac68fcSPAPANI SRIKANTH pqisrc_submit_management_req(pqisrc_softstate_t *softs,
2911e66f787SSean Bruno                                       pqi_event_config_request_t *request)
2921e66f787SSean Bruno {
2931e66f787SSean Bruno 	int ret = PQI_STATUS_SUCCESS;
2941e66f787SSean Bruno 	ib_queue_t *op_ib_q = &softs->op_raid_ib_q[0];
2951e66f787SSean Bruno 	rcb_t *rcb = NULL;
2961e66f787SSean Bruno 
2971e66f787SSean Bruno 	DBG_FUNC(" IN\n");
2981e66f787SSean Bruno 
2991e66f787SSean Bruno 	/* Get the tag */
3001e66f787SSean Bruno 	request->request_id = pqisrc_get_tag(&softs->taglist);
3011e66f787SSean Bruno 	if (INVALID_ELEM == request->request_id) {
3021e66f787SSean Bruno 		DBG_ERR("Tag not available\n");
3031e66f787SSean Bruno 		ret = PQI_STATUS_FAILURE;
3041e66f787SSean Bruno 		goto err_out;
3051e66f787SSean Bruno 	}
3061e66f787SSean Bruno 
3071e66f787SSean Bruno 	rcb = &softs->rcb[request->request_id];
3081e66f787SSean Bruno 	rcb->req_pending = true;
3091e66f787SSean Bruno 	rcb->tag = request->request_id;
310*7ea28254SJohn Hall 
3111e66f787SSean Bruno 	/* Submit command on operational raid ib queue */
3121e66f787SSean Bruno 	ret = pqisrc_submit_cmnd(softs, op_ib_q, request);
3131e66f787SSean Bruno 	if (ret != PQI_STATUS_SUCCESS) {
3141e66f787SSean Bruno 		DBG_ERR("  Unable to submit command\n");
3151e66f787SSean Bruno 		goto err_cmd;
3161e66f787SSean Bruno 	}
3171e66f787SSean Bruno 
3189fac68fcSPAPANI SRIKANTH 	ret = pqisrc_wait_on_condition(softs, rcb, PQISRC_CMD_TIMEOUT);
319*7ea28254SJohn Hall 
3201e66f787SSean Bruno 	if (ret != PQI_STATUS_SUCCESS) {
3211e66f787SSean Bruno 		DBG_ERR("Management request timed out !!\n");
3221e66f787SSean Bruno 		goto err_cmd;
3231e66f787SSean Bruno 	}
3241e66f787SSean Bruno 
3251e66f787SSean Bruno 	os_reset_rcb(rcb);
3261e66f787SSean Bruno  	pqisrc_put_tag(&softs->taglist,request->request_id);
3271e66f787SSean Bruno 	DBG_FUNC("OUT\n");
3281e66f787SSean Bruno 	return ret;
3291e66f787SSean Bruno 
3301e66f787SSean Bruno err_cmd:
3311e66f787SSean Bruno 	os_reset_rcb(rcb);
3321e66f787SSean Bruno 	pqisrc_put_tag(&softs->taglist,request->request_id);
3331e66f787SSean Bruno err_out:
3341e66f787SSean Bruno 	DBG_FUNC(" failed OUT : %d\n", ret);
3351e66f787SSean Bruno 	return ret;
3361e66f787SSean Bruno }
3371e66f787SSean Bruno 
3381e66f787SSean Bruno /*
3391e66f787SSean Bruno  * Build and send the general management request.
3401e66f787SSean Bruno  */
3411e66f787SSean Bruno static int
pqi_event_configure(pqisrc_softstate_t * softs,pqi_event_config_request_t * request,dma_mem_t * buff)3421e66f787SSean Bruno pqi_event_configure(pqisrc_softstate_t *softs ,
3431e66f787SSean Bruno                               pqi_event_config_request_t *request,
3441e66f787SSean Bruno                               dma_mem_t *buff)
3451e66f787SSean Bruno {
3461e66f787SSean Bruno         int ret = PQI_STATUS_SUCCESS;
3471e66f787SSean Bruno 
3481e66f787SSean Bruno 	DBG_FUNC(" IN\n");
3491e66f787SSean Bruno 
3501e66f787SSean Bruno 	request->header.comp_feature = 0x00;
3511e66f787SSean Bruno 	request->header.iu_length = sizeof(pqi_event_config_request_t) -
3521e66f787SSean Bruno 		    PQI_REQUEST_HEADER_LENGTH; /* excluding IU header length */
3531e66f787SSean Bruno 
3541e66f787SSean Bruno 	/*Op OQ id where response to be delivered */
3551e66f787SSean Bruno 	request->response_queue_id = softs->op_ob_q[0].q_id;
3561e66f787SSean Bruno 	request->buffer_length 	   = buff->size;
3571e66f787SSean Bruno 	request->sg_desc.addr 	   = buff->dma_addr;
3581e66f787SSean Bruno 	request->sg_desc.length    = buff->size;
3591e66f787SSean Bruno 	request->sg_desc.zero 	   = 0;
3601e66f787SSean Bruno 	request->sg_desc.type 	   = SGL_DESCRIPTOR_CODE_LAST_ALTERNATIVE_SGL_SEGMENT;
3611e66f787SSean Bruno 
3621e66f787SSean Bruno 	/* submit management req IU*/
3631e66f787SSean Bruno 	ret = pqisrc_submit_management_req(softs,request);
3641e66f787SSean Bruno 	if(ret)
3651e66f787SSean Bruno 		goto err_out;
3661e66f787SSean Bruno 
3679fac68fcSPAPANI SRIKANTH 
3681e66f787SSean Bruno 	DBG_FUNC(" OUT\n");
3691e66f787SSean Bruno 	return ret;
3701e66f787SSean Bruno 
3711e66f787SSean Bruno err_out:
3721e66f787SSean Bruno 	DBG_FUNC("Failed OUT\n");
3731e66f787SSean Bruno 	return ret;
3741e66f787SSean Bruno }
3751e66f787SSean Bruno 
3761e66f787SSean Bruno /*
3771e66f787SSean Bruno  * Prepare REPORT EVENT CONFIGURATION IU to request that
3781e66f787SSean Bruno  * event configuration information be reported.
3791e66f787SSean Bruno  */
3809fac68fcSPAPANI SRIKANTH int
pqisrc_report_event_config(pqisrc_softstate_t * softs)3819fac68fcSPAPANI SRIKANTH pqisrc_report_event_config(pqisrc_softstate_t *softs)
3821e66f787SSean Bruno {
3831e66f787SSean Bruno 
3841e66f787SSean Bruno 	int ret,i ;
3851e66f787SSean Bruno 	pqi_event_config_request_t request;
3861e66f787SSean Bruno 	pqi_event_config_t  *event_config_p ;
3871e66f787SSean Bruno 	dma_mem_t  buf_report_event ;
3881e66f787SSean Bruno 	/*bytes to be allocaed for report event config data-in buffer */
3891e66f787SSean Bruno 	uint32_t alloc_size = sizeof(pqi_event_config_t) ;
3901e66f787SSean Bruno 	memset(&request, 0 , sizeof(request));
3911e66f787SSean Bruno 
3921e66f787SSean Bruno 	DBG_FUNC(" IN\n");
3931e66f787SSean Bruno 
3941e66f787SSean Bruno 	memset(&buf_report_event, 0, sizeof(struct dma_mem));
395*7ea28254SJohn Hall 	os_strlcpy(buf_report_event.tag, "pqi_report_event_buf", sizeof(buf_report_event.tag)); ;
3961e66f787SSean Bruno 	buf_report_event.size 	= alloc_size;
3971e66f787SSean Bruno 	buf_report_event.align 	= PQISRC_DEFAULT_DMA_ALIGN;
3981e66f787SSean Bruno 
3991e66f787SSean Bruno 	/* allocate memory */
4001e66f787SSean Bruno 	ret = os_dma_mem_alloc(softs, &buf_report_event);
4011e66f787SSean Bruno 	if (ret) {
4021e66f787SSean Bruno 		DBG_ERR("Failed to Allocate report event config buffer : %d\n", ret);
4031e66f787SSean Bruno 		goto err_out;
4041e66f787SSean Bruno 	}
4051e66f787SSean Bruno 	DBG_INFO("buf_report_event.dma_addr	= %p \n",(void*)buf_report_event.dma_addr);
4061e66f787SSean Bruno 	DBG_INFO("buf_report_event.virt_addr 	= %p \n",(void*)buf_report_event.virt_addr);
4071e66f787SSean Bruno 
4081e66f787SSean Bruno 	request.header.iu_type = PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG;
4091e66f787SSean Bruno 
4101e66f787SSean Bruno 	/* Event configuration */
4111e66f787SSean Bruno 	ret=pqi_event_configure(softs,&request,&buf_report_event);
4121e66f787SSean Bruno 	if(ret)
4131e66f787SSean Bruno 		goto free_mem;
4141e66f787SSean Bruno 
4151e66f787SSean Bruno 
4161e66f787SSean Bruno 	event_config_p = (pqi_event_config_t*)buf_report_event.virt_addr;
4171e66f787SSean Bruno 	softs->event_config.num_event_descriptors = MIN(event_config_p->num_event_descriptors,
4181e66f787SSean Bruno 		                                            PQI_MAX_EVENT_DESCRIPTORS) ;
4191e66f787SSean Bruno 
4201e66f787SSean Bruno         for (i=0; i < softs->event_config.num_event_descriptors ;i++){
4211e66f787SSean Bruno 		softs->event_config.descriptors[i].event_type =
4221e66f787SSean Bruno 					event_config_p->descriptors[i].event_type;
4231e66f787SSean Bruno 	}
4241e66f787SSean Bruno         /* free the allocated memory*/
4251e66f787SSean Bruno 	os_dma_mem_free(softs, &buf_report_event);
4261e66f787SSean Bruno 
4271e66f787SSean Bruno 	DBG_FUNC(" OUT\n");
4281e66f787SSean Bruno 	return ret;
4291e66f787SSean Bruno 
4301e66f787SSean Bruno free_mem:
4311e66f787SSean Bruno 	os_dma_mem_free(softs, &buf_report_event);
4321e66f787SSean Bruno err_out:
4331e66f787SSean Bruno 	DBG_FUNC("Failed OUT\n");
4341e66f787SSean Bruno 	return PQI_STATUS_FAILURE;
4351e66f787SSean Bruno }
4361e66f787SSean Bruno 
4371e66f787SSean Bruno /*
4381e66f787SSean Bruno  * Prepare SET EVENT CONFIGURATION IU to request that
4391e66f787SSean Bruno  * event configuration parameters be set.
4401e66f787SSean Bruno  */
4419fac68fcSPAPANI SRIKANTH int
pqisrc_set_event_config(pqisrc_softstate_t * softs)4429fac68fcSPAPANI SRIKANTH pqisrc_set_event_config(pqisrc_softstate_t *softs)
4431e66f787SSean Bruno {
4441e66f787SSean Bruno 
4451e66f787SSean Bruno 	int ret,i;
4461e66f787SSean Bruno 	pqi_event_config_request_t request;
4471e66f787SSean Bruno 	pqi_event_config_t *event_config_p;
4481e66f787SSean Bruno 	dma_mem_t buf_set_event;
4491e66f787SSean Bruno 	/*bytes to be allocaed for set event config data-out buffer */
4501e66f787SSean Bruno 	uint32_t alloc_size = sizeof(pqi_event_config_t);
4511e66f787SSean Bruno 	memset(&request, 0 , sizeof(request));
4521e66f787SSean Bruno 
4531e66f787SSean Bruno 	DBG_FUNC(" IN\n");
4541e66f787SSean Bruno 
4551e66f787SSean Bruno  	memset(&buf_set_event, 0, sizeof(struct dma_mem));
456*7ea28254SJohn Hall 	os_strlcpy(buf_set_event.tag, "pqi_set_event_buf", sizeof(buf_set_event.tag));
4571e66f787SSean Bruno 	buf_set_event.size 	= alloc_size;
4581e66f787SSean Bruno 	buf_set_event.align 	= PQISRC_DEFAULT_DMA_ALIGN;
4591e66f787SSean Bruno 
4601e66f787SSean Bruno 	/* allocate memory */
4611e66f787SSean Bruno 	ret = os_dma_mem_alloc(softs, &buf_set_event);
4621e66f787SSean Bruno 	if (ret) {
4631e66f787SSean Bruno 		DBG_ERR("Failed to Allocate set event config buffer : %d\n", ret);
4641e66f787SSean Bruno 		goto err_out;
4651e66f787SSean Bruno 	}
4661e66f787SSean Bruno 
4671e66f787SSean Bruno 	DBG_INFO("buf_set_event.dma_addr  	= %p\n",(void*)buf_set_event.dma_addr);
4681e66f787SSean Bruno 	DBG_INFO("buf_set_event.virt_addr 	= %p\n",(void*)buf_set_event.virt_addr);
4691e66f787SSean Bruno 
4701e66f787SSean Bruno 	request.header.iu_type = PQI_REQUEST_IU_SET_EVENT_CONFIG;
4711e66f787SSean Bruno 	request.iu_specific.global_event_oq_id = softs->event_q.q_id;
4721e66f787SSean Bruno 
4731e66f787SSean Bruno 	/*pointer to data-out buffer*/
4741e66f787SSean Bruno 
4751e66f787SSean Bruno 	event_config_p = (pqi_event_config_t *)buf_set_event.virt_addr;
4761e66f787SSean Bruno 
4771e66f787SSean Bruno 	event_config_p->num_event_descriptors = softs->event_config.num_event_descriptors;
4781e66f787SSean Bruno 
4799fac68fcSPAPANI SRIKANTH 
4801e66f787SSean Bruno 	for (i=0; i < softs->event_config.num_event_descriptors ; i++){
4811e66f787SSean Bruno 		event_config_p->descriptors[i].event_type =
4821e66f787SSean Bruno 					softs->event_config.descriptors[i].event_type;
4831e66f787SSean Bruno 		if( pqisrc_event_type_to_event_index(event_config_p->descriptors[i].event_type) != -1)
4841e66f787SSean Bruno 			event_config_p->descriptors[i].oq_id = softs->event_q.q_id;
4851e66f787SSean Bruno 		else
4861e66f787SSean Bruno 			event_config_p->descriptors[i].oq_id = 0; /* Not supported this event. */
4871e66f787SSean Bruno 
4889fac68fcSPAPANI SRIKANTH 
4891e66f787SSean Bruno 	}
4901e66f787SSean Bruno         /* Event configuration */
4911e66f787SSean Bruno 	ret = pqi_event_configure(softs,&request,&buf_set_event);
4921e66f787SSean Bruno 		if(ret)
4931e66f787SSean Bruno 			goto free_mem;
4941e66f787SSean Bruno 
4951e66f787SSean Bruno 	os_dma_mem_free(softs, &buf_set_event);
4961e66f787SSean Bruno 
4971e66f787SSean Bruno 	DBG_FUNC(" OUT\n");
4981e66f787SSean Bruno 	return ret;
4991e66f787SSean Bruno 
5001e66f787SSean Bruno free_mem:
5011e66f787SSean Bruno 	os_dma_mem_free(softs, &buf_set_event);
5021e66f787SSean Bruno err_out:
5031e66f787SSean Bruno 	DBG_FUNC("Failed OUT\n");
5041e66f787SSean Bruno 	return PQI_STATUS_FAILURE;
5051e66f787SSean Bruno 
5061e66f787SSean Bruno }
507