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