xref: /freebsd/sys/dev/smartpqi/smartpqi_helper.c (revision 2f06449d64298fe508e3c585b45effd69a72d696)
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 used to validate the adapter health.
311e66f787SSean Bruno  */
329fac68fcSPAPANI SRIKANTH boolean_t
pqisrc_ctrl_offline(pqisrc_softstate_t * softs)339fac68fcSPAPANI SRIKANTH pqisrc_ctrl_offline(pqisrc_softstate_t *softs)
341e66f787SSean Bruno {
351e66f787SSean Bruno 	DBG_FUNC("IN\n");
361e66f787SSean Bruno 
371e66f787SSean Bruno 	DBG_FUNC("OUT\n");
381e66f787SSean Bruno 
391e66f787SSean Bruno 	return !softs->ctrl_online;
401e66f787SSean Bruno }
41b17f4335SSean Bruno /* Function used set/clear legacy INTx bit in Legacy Interrupt INTx
42b17f4335SSean Bruno  * mask clear pqi register
43b17f4335SSean Bruno  */
449fac68fcSPAPANI SRIKANTH void
pqisrc_configure_legacy_intx(pqisrc_softstate_t * softs,boolean_t enable_intx)459fac68fcSPAPANI SRIKANTH pqisrc_configure_legacy_intx(pqisrc_softstate_t *softs, boolean_t enable_intx)
46b17f4335SSean Bruno {
47b17f4335SSean Bruno 	uint32_t intx_mask;
48b17f4335SSean Bruno 
49b17f4335SSean Bruno  	DBG_FUNC("IN\n");
50b17f4335SSean Bruno 
51*7ea28254SJohn Hall 	intx_mask = PCI_MEM_GET32(softs, 0, PQI_LEGACY_INTR_MASK_CLR);
52b17f4335SSean Bruno 	intx_mask |= PQISRC_LEGACY_INTX_MASK;
53*7ea28254SJohn Hall 	PCI_MEM_PUT32(softs, 0, PQI_LEGACY_INTR_MASK_CLR ,intx_mask);
54b17f4335SSean Bruno 
55b17f4335SSean Bruno  	DBG_FUNC("OUT\n");
56b17f4335SSean Bruno }
57b17f4335SSean Bruno 
581e66f787SSean Bruno /*
591e66f787SSean Bruno  * Function used to take exposed devices to OS as offline.
601e66f787SSean Bruno  */
619fac68fcSPAPANI SRIKANTH void
pqisrc_take_devices_offline(pqisrc_softstate_t * softs)629fac68fcSPAPANI SRIKANTH pqisrc_take_devices_offline(pqisrc_softstate_t *softs)
631e66f787SSean Bruno {
641e66f787SSean Bruno 	pqi_scsi_dev_t *device = NULL;
65*7ea28254SJohn Hall 	int i;
661e66f787SSean Bruno 
671e66f787SSean Bruno 	DBG_FUNC("IN\n");
681e66f787SSean Bruno 	for(i = 0; i < PQI_MAX_DEVICES; i++) {
69*7ea28254SJohn Hall 		device = softs->dev_list[i];
70*7ea28254SJohn Hall 		if(device == NULL)
711e66f787SSean Bruno 			continue;
721e66f787SSean Bruno 		pqisrc_remove_device(softs, device);
731e66f787SSean Bruno 	}
741e66f787SSean Bruno 
751e66f787SSean Bruno 	DBG_FUNC("OUT\n");
761e66f787SSean Bruno }
771e66f787SSean Bruno 
781e66f787SSean Bruno /*
791e66f787SSean Bruno  * Function used to take adapter offline.
801e66f787SSean Bruno  */
819fac68fcSPAPANI SRIKANTH void
pqisrc_take_ctrl_offline(pqisrc_softstate_t * softs)829fac68fcSPAPANI SRIKANTH pqisrc_take_ctrl_offline(pqisrc_softstate_t *softs)
831e66f787SSean Bruno {
841e66f787SSean Bruno 	DBG_FUNC("IN\n");
851e66f787SSean Bruno 
869fac68fcSPAPANI SRIKANTH 	int lockupcode = 0;
879fac68fcSPAPANI SRIKANTH 
88*7ea28254SJohn Hall 	softs->ctrl_online = false;
89*7ea28254SJohn Hall 
909fac68fcSPAPANI SRIKANTH 	if (SIS_IS_KERNEL_PANIC(softs)) {
919fac68fcSPAPANI SRIKANTH 		lockupcode = PCI_MEM_GET32(softs, &softs->ioa_reg->mb[7], LEGACY_SIS_SRCV_OFFSET_MAILBOX_7);
92d53e97bbSGordon Bergling         DBG_ERR("Controller FW is not running, Lockup code = %x\n", lockupcode);
939fac68fcSPAPANI SRIKANTH 	}
949fac68fcSPAPANI SRIKANTH 	else {
951e66f787SSean Bruno 	pqisrc_trigger_nmi_sis(softs);
969fac68fcSPAPANI SRIKANTH 	}
979fac68fcSPAPANI SRIKANTH 
981e66f787SSean Bruno 	os_complete_outstanding_cmds_nodevice(softs);
999fac68fcSPAPANI SRIKANTH 	pqisrc_wait_for_rescan_complete(softs);
1001e66f787SSean Bruno 	pqisrc_take_devices_offline(softs);
1011e66f787SSean Bruno 
1021e66f787SSean Bruno 	DBG_FUNC("OUT\n");
1031e66f787SSean Bruno }
1041e66f787SSean Bruno 
1051e66f787SSean Bruno /*
1061e66f787SSean Bruno  * Timer handler for the adapter heart-beat.
1071e66f787SSean Bruno  */
1089fac68fcSPAPANI SRIKANTH void
pqisrc_heartbeat_timer_handler(pqisrc_softstate_t * softs)1099fac68fcSPAPANI SRIKANTH pqisrc_heartbeat_timer_handler(pqisrc_softstate_t *softs)
1101e66f787SSean Bruno {
1111e66f787SSean Bruno 	uint8_t take_offline = false;
112*7ea28254SJohn Hall 	uint64_t new_heartbeat;
113*7ea28254SJohn Hall 	static uint32_t running_ping_cnt = 0;
1141e66f787SSean Bruno 
1151e66f787SSean Bruno 	DBG_FUNC("IN\n");
1161e66f787SSean Bruno 
117*7ea28254SJohn Hall 	new_heartbeat = CTRLR_HEARTBEAT_CNT(softs);
118*7ea28254SJohn Hall 	DBG_IO("heartbeat old=%lx new=%lx\n", softs->prev_heartbeat_count, new_heartbeat);
119*7ea28254SJohn Hall 
120*7ea28254SJohn Hall 	if (new_heartbeat == softs->prev_heartbeat_count) {
1211e66f787SSean Bruno 		take_offline = true;
1221e66f787SSean Bruno 		goto take_ctrl_offline;
1231e66f787SSean Bruno 	}
124*7ea28254SJohn Hall 
125*7ea28254SJohn Hall #if 1
126*7ea28254SJohn Hall 	/* print every 30 calls (should print once/minute) */
127*7ea28254SJohn Hall 	running_ping_cnt++;
128*7ea28254SJohn Hall 
129*7ea28254SJohn Hall 	if ((running_ping_cnt % 30) == 0)
130*7ea28254SJohn Hall 		print_all_counters(softs, COUNTER_FLAG_ONLY_NON_ZERO);
131*7ea28254SJohn Hall #endif
132*7ea28254SJohn Hall 
133*7ea28254SJohn Hall 	softs->prev_heartbeat_count = new_heartbeat;
1341e66f787SSean Bruno 
1351e66f787SSean Bruno take_ctrl_offline:
1361e66f787SSean Bruno 	if (take_offline){
1371e66f787SSean Bruno 		DBG_ERR("controller is offline\n");
1381e66f787SSean Bruno 		os_stop_heartbeat_timer(softs);
139*7ea28254SJohn Hall 		pqisrc_take_ctrl_offline(softs);
1401e66f787SSean Bruno 	}
1411e66f787SSean Bruno 	DBG_FUNC("OUT\n");
1421e66f787SSean Bruno }
1431e66f787SSean Bruno 
1441e66f787SSean Bruno /*
1451e66f787SSean Bruno  * Conditional variable management routine for internal commands.
1461e66f787SSean Bruno  */
1479fac68fcSPAPANI SRIKANTH int
pqisrc_wait_on_condition(pqisrc_softstate_t * softs,rcb_t * rcb,uint32_t timeout_in_msec)1489fac68fcSPAPANI SRIKANTH pqisrc_wait_on_condition(pqisrc_softstate_t *softs, rcb_t *rcb,
1499fac68fcSPAPANI SRIKANTH 				uint32_t timeout_in_msec)
1509fac68fcSPAPANI SRIKANTH {
1511e66f787SSean Bruno 	DBG_FUNC("IN\n");
1521e66f787SSean Bruno 
1531e66f787SSean Bruno 	int ret = PQI_STATUS_SUCCESS;
1549fac68fcSPAPANI SRIKANTH 
1559fac68fcSPAPANI SRIKANTH 	/* 1 msec = 500 usec * 2 */
1569fac68fcSPAPANI SRIKANTH 	uint32_t loop_cnt = timeout_in_msec * 2;
1579fac68fcSPAPANI SRIKANTH 	uint32_t i = 0;
1581e66f787SSean Bruno 
1591e66f787SSean Bruno 	while (rcb->req_pending == true) {
1601e66f787SSean Bruno 		OS_SLEEP(500); /* Micro sec */
1611e66f787SSean Bruno 		/* Polling needed for FreeBSD : since ithread routine is not scheduled
1629fac68fcSPAPANI SRIKANTH 		 * during bootup, we could use polling until interrupts are
1639fac68fcSPAPANI SRIKANTH 		 * enabled (using 'if (cold)'to check for the boot time before
1649fac68fcSPAPANI SRIKANTH 		 * interrupts are enabled). */
1651e66f787SSean Bruno 		IS_POLLING_REQUIRED(softs);
1661e66f787SSean Bruno 
1679fac68fcSPAPANI SRIKANTH 		if ((timeout_in_msec != TIMEOUT_INFINITE) && (i++ == loop_cnt)) {
1681e66f787SSean Bruno 			DBG_ERR("ERR: Requested cmd timed out !!!\n");
1691e66f787SSean Bruno 			ret = PQI_STATUS_TIMEOUT;
1709fac68fcSPAPANI SRIKANTH 			rcb->timedout = true;
1711e66f787SSean Bruno 			break;
1721e66f787SSean Bruno 		}
1731e66f787SSean Bruno 
1741e66f787SSean Bruno 		if (pqisrc_ctrl_offline(softs)) {
1751e66f787SSean Bruno 			DBG_ERR("Controller is Offline");
1761e66f787SSean Bruno 			ret = PQI_STATUS_FAILURE;
1771e66f787SSean Bruno 			break;
1781e66f787SSean Bruno 		}
1799fac68fcSPAPANI SRIKANTH 
1801e66f787SSean Bruno 	}
1811e66f787SSean Bruno 	rcb->req_pending = true;
1821e66f787SSean Bruno 
1831e66f787SSean Bruno 	DBG_FUNC("OUT\n");
1841e66f787SSean Bruno 
1851e66f787SSean Bruno 	return ret;
1861e66f787SSean Bruno }
1871e66f787SSean Bruno 
1881e66f787SSean Bruno /* Function used to validate the device wwid. */
1899fac68fcSPAPANI SRIKANTH boolean_t
pqisrc_device_equal(pqi_scsi_dev_t * dev1,pqi_scsi_dev_t * dev2)1909fac68fcSPAPANI SRIKANTH pqisrc_device_equal(pqi_scsi_dev_t *dev1,
1911e66f787SSean Bruno 	pqi_scsi_dev_t *dev2)
1921e66f787SSean Bruno {
1931e66f787SSean Bruno 	return dev1->wwid == dev2->wwid;
1941e66f787SSean Bruno }
1951e66f787SSean Bruno 
1961e66f787SSean Bruno /* Function used to validate the device scsi3addr. */
1979fac68fcSPAPANI SRIKANTH boolean_t
pqisrc_scsi3addr_equal(uint8_t * scsi3addr1,uint8_t * scsi3addr2)1989fac68fcSPAPANI SRIKANTH pqisrc_scsi3addr_equal(uint8_t *scsi3addr1, uint8_t *scsi3addr2)
1991e66f787SSean Bruno {
2001e66f787SSean Bruno 	return memcmp(scsi3addr1, scsi3addr2, 8) == 0;
2011e66f787SSean Bruno }
2021e66f787SSean Bruno 
2031e66f787SSean Bruno /* Function used to validate hba_lunid */
2049fac68fcSPAPANI SRIKANTH boolean_t
pqisrc_is_hba_lunid(uint8_t * scsi3addr)2059fac68fcSPAPANI SRIKANTH pqisrc_is_hba_lunid(uint8_t *scsi3addr)
2061e66f787SSean Bruno {
207*7ea28254SJohn Hall 	return pqisrc_scsi3addr_equal(scsi3addr, RAID_CTLR_LUNID);
2081e66f787SSean Bruno }
2091e66f787SSean Bruno 
2101e66f787SSean Bruno /* Function used to validate type of device */
2119fac68fcSPAPANI SRIKANTH boolean_t
pqisrc_is_logical_device(pqi_scsi_dev_t * device)2129fac68fcSPAPANI SRIKANTH pqisrc_is_logical_device(pqi_scsi_dev_t *device)
2131e66f787SSean Bruno {
2141e66f787SSean Bruno 	return !device->is_physical_device;
2151e66f787SSean Bruno }
2161e66f787SSean Bruno 
2171e66f787SSean Bruno /* Function used to sanitize inquiry string */
2189fac68fcSPAPANI SRIKANTH void
pqisrc_sanitize_inquiry_string(unsigned char * s,int len)2199fac68fcSPAPANI SRIKANTH pqisrc_sanitize_inquiry_string(unsigned char *s, int len)
2201e66f787SSean Bruno {
2211e66f787SSean Bruno 	boolean_t terminated = false;
2221e66f787SSean Bruno 
2231e66f787SSean Bruno 	DBG_FUNC("IN\n");
2241e66f787SSean Bruno 
2251e66f787SSean Bruno 	for (; len > 0; (--len, ++s)) {
2261e66f787SSean Bruno 		if (*s == 0)
2271e66f787SSean Bruno 			terminated = true;
2281e66f787SSean Bruno 		if (terminated || *s < 0x20 || *s > 0x7e)
2291e66f787SSean Bruno 			*s = ' ';
2301e66f787SSean Bruno 	}
2311e66f787SSean Bruno 
2321e66f787SSean Bruno 	DBG_FUNC("OUT\n");
2331e66f787SSean Bruno }
2341e66f787SSean Bruno 
2351e66f787SSean Bruno static char *raid_levels[] = {
2361e66f787SSean Bruno 	"RAID 0",
2371e66f787SSean Bruno 	"RAID 4",
2381e66f787SSean Bruno 	"RAID 1(1+0)",
2391e66f787SSean Bruno 	"RAID 5",
2401e66f787SSean Bruno 	"RAID 5+1",
241*7ea28254SJohn Hall 	"RAID 6",
242*7ea28254SJohn Hall 	"RAID 1(Triple)",
2431e66f787SSean Bruno };
2441e66f787SSean Bruno 
2451e66f787SSean Bruno /* Get the RAID level from the index */
2469fac68fcSPAPANI SRIKANTH char *
pqisrc_raidlevel_to_string(uint8_t raid_level)2479fac68fcSPAPANI SRIKANTH pqisrc_raidlevel_to_string(uint8_t raid_level)
2481e66f787SSean Bruno {
2491e66f787SSean Bruno 	DBG_FUNC("IN\n");
2501e66f787SSean Bruno 	if (raid_level < ARRAY_SIZE(raid_levels))
2511e66f787SSean Bruno 		return raid_levels[raid_level];
2521e66f787SSean Bruno 	DBG_FUNC("OUT\n");
2531e66f787SSean Bruno 
2541e66f787SSean Bruno 	return " ";
2551e66f787SSean Bruno }
2561e66f787SSean Bruno 
2571e66f787SSean Bruno /* Debug routine for displaying device info */
pqisrc_display_device_info(pqisrc_softstate_t * softs,char * action,pqi_scsi_dev_t * device)2584f77349dSWarner Losh void pqisrc_display_device_info(pqisrc_softstate_t *softs,
2591e66f787SSean Bruno 	char *action, pqi_scsi_dev_t *device)
2601e66f787SSean Bruno {
2614f77349dSWarner Losh 	if (device->is_physical_device) {
2624f77349dSWarner Losh 		DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
2634f77349dSWarner Losh 		"SSDSmartPathCap%c En%c Exp%c qd=%d\n",
2644f77349dSWarner Losh 		action,
2654f77349dSWarner Losh 		device->bus,
2664f77349dSWarner Losh 		device->target,
2674f77349dSWarner Losh 		device->lun,
2684f77349dSWarner Losh 		device->vendor,
2694f77349dSWarner Losh 		device->model,
2704f77349dSWarner Losh 		"Physical",
2714f77349dSWarner Losh 		device->offload_config ? '+' : '-',
2724f77349dSWarner Losh 		device->offload_enabled_pending ? '+' : '-',
2734f77349dSWarner Losh 		device->expose_device ? '+' : '-',
2744f77349dSWarner Losh 		device->queue_depth);
2754f77349dSWarner Losh 	} else if (device->devtype == RAID_DEVICE) {
2764f77349dSWarner Losh 		DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
2774f77349dSWarner Losh 		"SSDSmartPathCap%c En%c Exp%c qd=%d\n",
2784f77349dSWarner Losh 		action,
2794f77349dSWarner Losh 		device->bus,
2804f77349dSWarner Losh 		device->target,
2814f77349dSWarner Losh 		device->lun,
2824f77349dSWarner Losh 		device->vendor,
2834f77349dSWarner Losh 		device->model,
2844f77349dSWarner Losh 		"Controller",
2854f77349dSWarner Losh 		device->offload_config ? '+' : '-',
2864f77349dSWarner Losh 		device->offload_enabled_pending ? '+' : '-',
2874f77349dSWarner Losh 		device->expose_device ? '+' : '-',
2884f77349dSWarner Losh 		device->queue_depth);
2894f77349dSWarner Losh 	} else if (device->devtype == CONTROLLER_DEVICE) {
2904f77349dSWarner Losh 		DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
2914f77349dSWarner Losh 		"SSDSmartPathCap%c En%c Exp%c qd=%d\n",
2924f77349dSWarner Losh 		action,
2934f77349dSWarner Losh 		device->bus,
2944f77349dSWarner Losh 		device->target,
2954f77349dSWarner Losh 		device->lun,
2964f77349dSWarner Losh 		device->vendor,
2974f77349dSWarner Losh 		device->model,
2984f77349dSWarner Losh 		"External",
2994f77349dSWarner Losh 		device->offload_config ? '+' : '-',
3004f77349dSWarner Losh 		device->offload_enabled_pending ? '+' : '-',
3014f77349dSWarner Losh 		device->expose_device ? '+' : '-',
3024f77349dSWarner Losh 		device->queue_depth);
3034f77349dSWarner Losh 	} else {
3044f77349dSWarner Losh 		DBG_NOTE("%s scsi BTL %d:%d:%d:  %.8s %.16s %-12s "
3054f77349dSWarner Losh 		"SSDSmartPathCap%c En%c Exp%c qd=%d devtype=%d\n",
3061e66f787SSean Bruno 		action,
3071e66f787SSean Bruno 		device->bus,
3081e66f787SSean Bruno 		device->target,
3091e66f787SSean Bruno 		device->lun,
3101e66f787SSean Bruno 		device->vendor,
3111e66f787SSean Bruno 		device->model,
3121e66f787SSean Bruno 		pqisrc_raidlevel_to_string(device->raid_level),
3131e66f787SSean Bruno 		device->offload_config ? '+' : '-',
3141e66f787SSean Bruno 		device->offload_enabled_pending ? '+' : '-',
3151e66f787SSean Bruno 		device->expose_device ? '+' : '-',
3164f77349dSWarner Losh 		device->queue_depth,
3174f77349dSWarner Losh 		device->devtype);
3181e66f787SSean Bruno 	pqisrc_raidlevel_to_string(device->raid_level); /* To use this function */
3191e66f787SSean Bruno 	}
3204f77349dSWarner Losh }
3211e66f787SSean Bruno 
3221e66f787SSean Bruno /* validate the structure sizes */
3239fac68fcSPAPANI SRIKANTH void
check_struct_sizes(void)324fb1c2168SDimitry Andric check_struct_sizes(void)
3251e66f787SSean Bruno {
3261e66f787SSean Bruno 
3271e66f787SSean Bruno     ASSERT(sizeof(SCSI3Addr_struct)== 2);
3281e66f787SSean Bruno     ASSERT(sizeof(PhysDevAddr_struct) == 8);
3291e66f787SSean Bruno     ASSERT(sizeof(LogDevAddr_struct)== 8);
3301e66f787SSean Bruno     ASSERT(sizeof(LUNAddr_struct)==8);
3311e66f787SSean Bruno     ASSERT(sizeof(RequestBlock_struct) == 20);
3321e66f787SSean Bruno     ASSERT(sizeof(MoreErrInfo_struct)== 8);
3331e66f787SSean Bruno     ASSERT(sizeof(ErrorInfo_struct)== 48);
3349fac68fcSPAPANI SRIKANTH     /* Checking the size of IOCTL_Command_struct for both
3359fac68fcSPAPANI SRIKANTH        64 bit and 32 bit system*/
3369fac68fcSPAPANI SRIKANTH     ASSERT(sizeof(IOCTL_Command_struct)== 86 ||
3379fac68fcSPAPANI SRIKANTH            sizeof(IOCTL_Command_struct)== 82);
3381e66f787SSean Bruno     ASSERT(sizeof(struct bmic_host_wellness_driver_version)== 42);
3391e66f787SSean Bruno     ASSERT(sizeof(struct bmic_host_wellness_time)== 20);
3401e66f787SSean Bruno     ASSERT(sizeof(struct pqi_dev_adminq_cap)== 8);
3411e66f787SSean Bruno     ASSERT(sizeof(struct admin_q_param)== 4);
3421e66f787SSean Bruno     ASSERT(sizeof(struct pqi_registers)== 256);
3431e66f787SSean Bruno     ASSERT(sizeof(struct ioa_registers)== 4128);
3441e66f787SSean Bruno     ASSERT(sizeof(struct pqi_pref_settings)==4);
3451e66f787SSean Bruno     ASSERT(sizeof(struct pqi_cap)== 20);
3461e66f787SSean Bruno     ASSERT(sizeof(iu_header_t)== 4);
3471e66f787SSean Bruno     ASSERT(sizeof(gen_adm_req_iu_t)== 64);
3481e66f787SSean Bruno     ASSERT(sizeof(gen_adm_resp_iu_t)== 64);
3491e66f787SSean Bruno     ASSERT(sizeof(op_q_params) == 9);
3501e66f787SSean Bruno     ASSERT(sizeof(raid_path_error_info_elem_t)== 276);
3511e66f787SSean Bruno     ASSERT(sizeof(aio_path_error_info_elem_t)== 276);
3521e66f787SSean Bruno     ASSERT(sizeof(struct init_base_struct)== 24);
3531e66f787SSean Bruno     ASSERT(sizeof(pqi_iu_layer_desc_t)== 16);
3541e66f787SSean Bruno     ASSERT(sizeof(pqi_dev_cap_t)== 576);
3551e66f787SSean Bruno     ASSERT(sizeof(pqi_aio_req_t)== 128);
3561e66f787SSean Bruno     ASSERT(sizeof(pqisrc_raid_req_t)== 128);
3579fac68fcSPAPANI SRIKANTH     ASSERT(sizeof(pqi_raid_tmf_req_t)== 32);
3589fac68fcSPAPANI SRIKANTH     ASSERT(sizeof(pqi_aio_tmf_req_t)== 32);
3591e66f787SSean Bruno     ASSERT(sizeof(struct pqi_io_response)== 16);
3601e66f787SSean Bruno     ASSERT(sizeof(struct sense_header_scsi)== 8);
3611e66f787SSean Bruno     ASSERT(sizeof(reportlun_header_t)==8);
3621e66f787SSean Bruno     ASSERT(sizeof(reportlun_ext_entry_t)== 24);
3631e66f787SSean Bruno     ASSERT(sizeof(reportlun_data_ext_t)== 32);
3641e66f787SSean Bruno     ASSERT(sizeof(raidmap_data_t)==8);
3651e66f787SSean Bruno     ASSERT(sizeof(pqisrc_raid_map_t)== 8256);
3661e66f787SSean Bruno     ASSERT(sizeof(bmic_ident_ctrl_t)== 325);
3671e66f787SSean Bruno     ASSERT(sizeof(bmic_ident_physdev_t)==2048);
3681e66f787SSean Bruno 
3691e66f787SSean Bruno }
3709fac68fcSPAPANI SRIKANTH 
371*7ea28254SJohn Hall #if 0
3729fac68fcSPAPANI SRIKANTH uint32_t
3739fac68fcSPAPANI SRIKANTH pqisrc_count_num_scsi_active_requests_on_dev(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
3749fac68fcSPAPANI SRIKANTH {
3759fac68fcSPAPANI SRIKANTH 	uint32_t i, active_io = 0;
3769fac68fcSPAPANI SRIKANTH 	rcb_t* rcb;
3779fac68fcSPAPANI SRIKANTH 
3789fac68fcSPAPANI SRIKANTH 	for(i = 1; i <= softs->max_outstanding_io; i++) {
3799fac68fcSPAPANI SRIKANTH 		rcb = &softs->rcb[i];
3809fac68fcSPAPANI SRIKANTH 		if(rcb && IS_OS_SCSICMD(rcb) && (rcb->dvp == device) && rcb->req_pending) {
3819fac68fcSPAPANI SRIKANTH 			active_io++;
3829fac68fcSPAPANI SRIKANTH 		}
3839fac68fcSPAPANI SRIKANTH 	}
3849fac68fcSPAPANI SRIKANTH 	return active_io;
3859fac68fcSPAPANI SRIKANTH }
3869fac68fcSPAPANI SRIKANTH 
3879fac68fcSPAPANI SRIKANTH void
3889fac68fcSPAPANI SRIKANTH check_device_pending_commands_to_complete(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
3899fac68fcSPAPANI SRIKANTH {
3909fac68fcSPAPANI SRIKANTH 	uint32_t tag = softs->max_outstanding_io, active_requests;
391*7ea28254SJohn Hall 	uint64_t timeout = 0, delay_in_usec = 1000; /* In micro Seconds  */
3929fac68fcSPAPANI SRIKANTH 	rcb_t* rcb;
3939fac68fcSPAPANI SRIKANTH 
3949fac68fcSPAPANI SRIKANTH 	DBG_FUNC("IN\n");
3959fac68fcSPAPANI SRIKANTH 
3969fac68fcSPAPANI SRIKANTH 	active_requests = pqisrc_count_num_scsi_active_requests_on_dev(softs, device);
3979fac68fcSPAPANI SRIKANTH 
3989fac68fcSPAPANI SRIKANTH 	DBG_WARN("Device Outstanding IO count = %u\n", active_requests);
3999fac68fcSPAPANI SRIKANTH 
4009fac68fcSPAPANI SRIKANTH 	if(!active_requests)
4019fac68fcSPAPANI SRIKANTH 		return;
4029fac68fcSPAPANI SRIKANTH 
4039fac68fcSPAPANI SRIKANTH 	do {
4049fac68fcSPAPANI SRIKANTH 		rcb = &softs->rcb[tag];
4059fac68fcSPAPANI SRIKANTH 		if(rcb && IS_OS_SCSICMD(rcb) && (rcb->dvp == device) && rcb->req_pending) {
406*7ea28254SJohn Hall 			OS_SLEEP(delay_in_usec);
4079fac68fcSPAPANI SRIKANTH 			timeout += delay_in_usec;
4089fac68fcSPAPANI SRIKANTH 		}
4099fac68fcSPAPANI SRIKANTH 		else
4109fac68fcSPAPANI SRIKANTH 			tag--;
4119fac68fcSPAPANI SRIKANTH 		if(timeout >= PQISRC_PENDING_IO_TIMEOUT_USEC) {
4129fac68fcSPAPANI SRIKANTH 			DBG_WARN("timed out waiting for pending IO\n");
4139fac68fcSPAPANI SRIKANTH 			return;
4149fac68fcSPAPANI SRIKANTH 		}
4159fac68fcSPAPANI SRIKANTH 	} while(tag);
4169fac68fcSPAPANI SRIKANTH }
4179fac68fcSPAPANI SRIKANTH #endif
4189fac68fcSPAPANI SRIKANTH 
4199fac68fcSPAPANI SRIKANTH void
pqisrc_wait_for_device_commands_to_complete(pqisrc_softstate_t * softs,pqi_scsi_dev_t * device)4209fac68fcSPAPANI SRIKANTH pqisrc_wait_for_device_commands_to_complete(pqisrc_softstate_t *softs, pqi_scsi_dev_t *device)
4219fac68fcSPAPANI SRIKANTH {
422*7ea28254SJohn Hall 	uint64_t timeout_in_usec = 0, delay_in_usec = 1000; /* In microseconds */
4239fac68fcSPAPANI SRIKANTH 
4249fac68fcSPAPANI SRIKANTH 	DBG_FUNC("IN\n");
4259fac68fcSPAPANI SRIKANTH 
4269fac68fcSPAPANI SRIKANTH 	if(!softs->ctrl_online)
4279fac68fcSPAPANI SRIKANTH 		return;
4289fac68fcSPAPANI SRIKANTH 
4299fac68fcSPAPANI SRIKANTH #if PQISRC_DEVICE_IO_COUNTER
430*7ea28254SJohn Hall 	DBG_WARN_BTL(device,"Device Outstanding IO count = %lu\n", pqisrc_read_device_active_io(softs, device));
4319fac68fcSPAPANI SRIKANTH 
4329fac68fcSPAPANI SRIKANTH 	while(pqisrc_read_device_active_io(softs, device)) {
433*7ea28254SJohn Hall 		OS_BUSYWAIT(delay_in_usec); /* In microseconds */
4349fac68fcSPAPANI SRIKANTH 		if(!softs->ctrl_online) {
4359fac68fcSPAPANI SRIKANTH 			DBG_WARN("Controller Offline was detected.\n");
4369fac68fcSPAPANI SRIKANTH 		}
4379fac68fcSPAPANI SRIKANTH 		timeout_in_usec += delay_in_usec;
4389fac68fcSPAPANI SRIKANTH 		if(timeout_in_usec >= PQISRC_PENDING_IO_TIMEOUT_USEC) {
439*7ea28254SJohn Hall 			DBG_WARN_BTL(device,"timed out waiting for pending IO. DeviceOutStandingIo's=%lu\n",
4409fac68fcSPAPANI SRIKANTH                                  pqisrc_read_device_active_io(softs, device));
4419fac68fcSPAPANI SRIKANTH 			return;
4429fac68fcSPAPANI SRIKANTH 		}
4439fac68fcSPAPANI SRIKANTH 	}
4449fac68fcSPAPANI SRIKANTH #else
4459fac68fcSPAPANI SRIKANTH 	check_device_pending_commands_to_complete(softs, device);
4469fac68fcSPAPANI SRIKANTH #endif
4479fac68fcSPAPANI SRIKANTH }
448