aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_os.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_os.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c146
1 files changed, 95 insertions, 51 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 967836ef5ab..a4acb0dd7be 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -29,10 +29,6 @@ static struct kmem_cache *srb_cachep;
29/* 29/*
30 * Module parameter information and variables 30 * Module parameter information and variables
31 */ 31 */
32int ql4xdiscoverywait = 60;
33module_param(ql4xdiscoverywait, int, S_IRUGO | S_IWUSR);
34MODULE_PARM_DESC(ql4xdiscoverywait, "Discovery wait time");
35
36int ql4xdontresethba = 0; 32int ql4xdontresethba = 0;
37module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); 33module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR);
38MODULE_PARM_DESC(ql4xdontresethba, 34MODULE_PARM_DESC(ql4xdontresethba,
@@ -55,6 +51,17 @@ MODULE_PARM_DESC(ql4xenablemsix,
55 " 2 = enable MSI interrupt mechanism."); 51 " 2 = enable MSI interrupt mechanism.");
56 52
57#define QL4_DEF_QDEPTH 32 53#define QL4_DEF_QDEPTH 32
54static int ql4xmaxqdepth = QL4_DEF_QDEPTH;
55module_param(ql4xmaxqdepth, int, S_IRUGO | S_IWUSR);
56MODULE_PARM_DESC(ql4xmaxqdepth,
57 "Maximum queue depth to report for target devices.\n"
58 " Default: 32.");
59
60static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO;
61module_param(ql4xsess_recovery_tmo, int, S_IRUGO);
62MODULE_PARM_DESC(ql4xsess_recovery_tmo,
63 "Target Session Recovery Timeout.\n"
64 " Default: 30 sec.");
58 65
59/* 66/*
60 * SCSI host template entry points 67 * SCSI host template entry points
@@ -165,7 +172,7 @@ static void qla4xxx_recovery_timedout(struct iscsi_cls_session *session)
165 DEBUG2(printk("scsi%ld: %s: ddb [%d] session recovery timeout " 172 DEBUG2(printk("scsi%ld: %s: ddb [%d] session recovery timeout "
166 "of (%d) secs exhausted, marking device DEAD.\n", 173 "of (%d) secs exhausted, marking device DEAD.\n",
167 ha->host_no, __func__, ddb_entry->fw_ddb_index, 174 ha->host_no, __func__, ddb_entry->fw_ddb_index,
168 QL4_SESS_RECOVERY_TMO)); 175 ddb_entry->sess->recovery_tmo));
169 } 176 }
170} 177}
171 178
@@ -295,7 +302,7 @@ int qla4xxx_add_sess(struct ddb_entry *ddb_entry)
295{ 302{
296 int err; 303 int err;
297 304
298 ddb_entry->sess->recovery_tmo = QL4_SESS_RECOVERY_TMO; 305 ddb_entry->sess->recovery_tmo = ql4xsess_recovery_tmo;
299 306
300 err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index); 307 err = iscsi_add_session(ddb_entry->sess, ddb_entry->fw_ddb_index);
301 if (err) { 308 if (err) {
@@ -753,12 +760,6 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
753 if (!pci_channel_offline(ha->pdev)) 760 if (!pci_channel_offline(ha->pdev))
754 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w); 761 pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
755 762
756 if (test_bit(AF_HBA_GOING_AWAY, &ha->flags)) {
757 DEBUG2(ql4_printk(KERN_INFO, ha, "%s exited. HBA GOING AWAY\n",
758 __func__));
759 return;
760 }
761
762 if (is_qla8022(ha)) { 763 if (is_qla8022(ha)) {
763 qla4_8xxx_watchdog(ha); 764 qla4_8xxx_watchdog(ha);
764 } 765 }
@@ -1067,7 +1068,6 @@ void qla4xxx_dead_adapter_cleanup(struct scsi_qla_host *ha)
1067 1068
1068 /* Disable the board */ 1069 /* Disable the board */
1069 ql4_printk(KERN_INFO, ha, "Disabling the board\n"); 1070 ql4_printk(KERN_INFO, ha, "Disabling the board\n");
1070 set_bit(AF_HBA_GOING_AWAY, &ha->flags);
1071 1071
1072 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16); 1072 qla4xxx_abort_active_cmds(ha, DID_NO_CONNECT << 16);
1073 qla4xxx_mark_all_devices_missing(ha); 1073 qla4xxx_mark_all_devices_missing(ha);
@@ -1218,6 +1218,27 @@ recover_ha_init_adapter:
1218 return status; 1218 return status;
1219} 1219}
1220 1220
1221static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha)
1222{
1223 struct ddb_entry *ddb_entry, *dtemp;
1224
1225 list_for_each_entry_safe(ddb_entry, dtemp, &ha->ddb_list, list) {
1226 if ((atomic_read(&ddb_entry->state) == DDB_STATE_MISSING) ||
1227 (atomic_read(&ddb_entry->state) == DDB_STATE_DEAD)) {
1228 if (ddb_entry->fw_ddb_device_state ==
1229 DDB_DS_SESSION_ACTIVE) {
1230 atomic_set(&ddb_entry->state, DDB_STATE_ONLINE);
1231 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
1232 " marked ONLINE\n", ha->host_no, __func__,
1233 ddb_entry->fw_ddb_index);
1234
1235 iscsi_unblock_session(ddb_entry->sess);
1236 } else
1237 qla4xxx_relogin_device(ha, ddb_entry);
1238 }
1239 }
1240}
1241
1221void qla4xxx_wake_dpc(struct scsi_qla_host *ha) 1242void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
1222{ 1243{
1223 if (ha->dpc_thread && 1244 if (ha->dpc_thread &&
@@ -1259,11 +1280,6 @@ static void qla4xxx_do_dpc(struct work_struct *work)
1259 goto do_dpc_exit; 1280 goto do_dpc_exit;
1260 } 1281 }
1261 1282
1262 /* HBA is in the process of being permanently disabled.
1263 * Don't process anything */
1264 if (test_bit(AF_HBA_GOING_AWAY, &ha->flags))
1265 return;
1266
1267 if (is_qla8022(ha)) { 1283 if (is_qla8022(ha)) {
1268 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) { 1284 if (test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags)) {
1269 qla4_8xxx_idc_lock(ha); 1285 qla4_8xxx_idc_lock(ha);
@@ -1331,13 +1347,7 @@ dpc_post_reset_ha:
1331 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { 1347 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) {
1332 if (!test_bit(AF_LINK_UP, &ha->flags)) { 1348 if (!test_bit(AF_LINK_UP, &ha->flags)) {
1333 /* ---- link down? --- */ 1349 /* ---- link down? --- */
1334 list_for_each_entry_safe(ddb_entry, dtemp, 1350 qla4xxx_mark_all_devices_missing(ha);
1335 &ha->ddb_list, list) {
1336 if (atomic_read(&ddb_entry->state) ==
1337 DDB_STATE_ONLINE)
1338 qla4xxx_mark_device_missing(ha,
1339 ddb_entry);
1340 }
1341 } else { 1351 } else {
1342 /* ---- link up? --- * 1352 /* ---- link up? --- *
1343 * F/W will auto login to all devices ONLY ONCE after 1353 * F/W will auto login to all devices ONLY ONCE after
@@ -1346,30 +1356,7 @@ dpc_post_reset_ha:
1346 * manually relogin to devices when recovering from 1356 * manually relogin to devices when recovering from
1347 * connection failures, logouts, expired KATO, etc. */ 1357 * connection failures, logouts, expired KATO, etc. */
1348 1358
1349 list_for_each_entry_safe(ddb_entry, dtemp, 1359 qla4xxx_relogin_all_devices(ha);
1350 &ha->ddb_list, list) {
1351 if ((atomic_read(&ddb_entry->state) ==
1352 DDB_STATE_MISSING) ||
1353 (atomic_read(&ddb_entry->state) ==
1354 DDB_STATE_DEAD)) {
1355 if (ddb_entry->fw_ddb_device_state ==
1356 DDB_DS_SESSION_ACTIVE) {
1357 atomic_set(&ddb_entry->state,
1358 DDB_STATE_ONLINE);
1359 ql4_printk(KERN_INFO, ha,
1360 "scsi%ld: %s: ddb[%d]"
1361 " marked ONLINE\n",
1362 ha->host_no, __func__,
1363 ddb_entry->fw_ddb_index);
1364
1365 iscsi_unblock_session(
1366 ddb_entry->sess);
1367 } else
1368 qla4xxx_relogin_device(
1369 ha, ddb_entry);
1370 }
1371
1372 }
1373 } 1360 }
1374 } 1361 }
1375 1362
@@ -1630,6 +1617,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
1630 uint8_t init_retry_count = 0; 1617 uint8_t init_retry_count = 0;
1631 char buf[34]; 1618 char buf[34];
1632 struct qla4_8xxx_legacy_intr_set *nx_legacy_intr; 1619 struct qla4_8xxx_legacy_intr_set *nx_legacy_intr;
1620 uint32_t dev_state;
1633 1621
1634 if (pci_enable_device(pdev)) 1622 if (pci_enable_device(pdev))
1635 return -1; 1623 return -1;
@@ -1713,6 +1701,18 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
1713 status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST); 1701 status = qla4xxx_initialize_adapter(ha, REBUILD_DDB_LIST);
1714 while ((!test_bit(AF_ONLINE, &ha->flags)) && 1702 while ((!test_bit(AF_ONLINE, &ha->flags)) &&
1715 init_retry_count++ < MAX_INIT_RETRIES) { 1703 init_retry_count++ < MAX_INIT_RETRIES) {
1704
1705 if (is_qla8022(ha)) {
1706 qla4_8xxx_idc_lock(ha);
1707 dev_state = qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
1708 qla4_8xxx_idc_unlock(ha);
1709 if (dev_state == QLA82XX_DEV_FAILED) {
1710 ql4_printk(KERN_WARNING, ha, "%s: don't retry "
1711 "initialize adapter. H/W is in failed state\n",
1712 __func__);
1713 break;
1714 }
1715 }
1716 DEBUG2(printk("scsi: %s: retrying adapter initialization " 1716 DEBUG2(printk("scsi: %s: retrying adapter initialization "
1717 "(%d)\n", __func__, init_retry_count)); 1717 "(%d)\n", __func__, init_retry_count));
1718 1718
@@ -1815,6 +1815,44 @@ probe_disable_device:
1815} 1815}
1816 1816
1817/** 1817/**
1818 * qla4xxx_prevent_other_port_reinit - prevent other port from re-initialize
1819 * @ha: pointer to adapter structure
1820 *
1821 * Mark the other ISP-4xxx port to indicate that the driver is being removed,
1822 * so that the other port will not re-initialize while in the process of
1823 * removing the ha due to driver unload or hba hotplug.
1824 **/
1825static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)
1826{
1827 struct scsi_qla_host *other_ha = NULL;
1828 struct pci_dev *other_pdev = NULL;
1829 int fn = ISP4XXX_PCI_FN_2;
1830
1831 /*iscsi function numbers for ISP4xxx is 1 and 3*/
1832 if (PCI_FUNC(ha->pdev->devfn) & BIT_1)
1833 fn = ISP4XXX_PCI_FN_1;
1834
1835 other_pdev =
1836 pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),
1837 ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),
1838 fn));
1839
1840 /* Get other_ha if other_pdev is valid and state is enable*/
1841 if (other_pdev) {
1842 if (atomic_read(&other_pdev->enable_cnt)) {
1843 other_ha = pci_get_drvdata(other_pdev);
1844 if (other_ha) {
1845 set_bit(AF_HA_REMOVAL, &other_ha->flags);
1846 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: "
1847 "Prevent %s reinit\n", __func__,
1848 dev_name(&other_ha->pdev->dev)));
1849 }
1850 }
1851 pci_dev_put(other_pdev);
1852 }
1853}
1854
1855/**
1818 * qla4xxx_remove_adapter - calback function to remove adapter. 1856 * qla4xxx_remove_adapter - calback function to remove adapter.
1819 * @pci_dev: PCI device pointer 1857 * @pci_dev: PCI device pointer
1820 **/ 1858 **/
@@ -1824,7 +1862,8 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
1824 1862
1825 ha = pci_get_drvdata(pdev); 1863 ha = pci_get_drvdata(pdev);
1826 1864
1827 set_bit(AF_HBA_GOING_AWAY, &ha->flags); 1865 if (!is_qla8022(ha))
1866 qla4xxx_prevent_other_port_reinit(ha);
1828 1867
1829 /* remove devs from iscsi_sessions to scsi_devices */ 1868 /* remove devs from iscsi_sessions to scsi_devices */
1830 qla4xxx_free_ddb_list(ha); 1869 qla4xxx_free_ddb_list(ha);
@@ -1868,10 +1907,15 @@ static int qla4xxx_slave_alloc(struct scsi_device *sdev)
1868{ 1907{
1869 struct iscsi_cls_session *sess = starget_to_session(sdev->sdev_target); 1908 struct iscsi_cls_session *sess = starget_to_session(sdev->sdev_target);
1870 struct ddb_entry *ddb = sess->dd_data; 1909 struct ddb_entry *ddb = sess->dd_data;
1910 int queue_depth = QL4_DEF_QDEPTH;
1871 1911
1872 sdev->hostdata = ddb; 1912 sdev->hostdata = ddb;
1873 sdev->tagged_supported = 1; 1913 sdev->tagged_supported = 1;
1874 scsi_activate_tcq(sdev, QL4_DEF_QDEPTH); 1914
1915 if (ql4xmaxqdepth != 0 && ql4xmaxqdepth <= 0xffffU)
1916 queue_depth = ql4xmaxqdepth;
1917
1918 scsi_activate_tcq(sdev, queue_depth);
1875 return 0; 1919 return 0;
1876} 1920}
1877 1921