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.c78
1 files changed, 77 insertions, 1 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index ee47820c30a6..cd15678f9ada 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -68,12 +68,34 @@ MODULE_PARM_DESC(ql4xmaxqdepth,
68 " Maximum queue depth to report for target devices.\n" 68 " Maximum queue depth to report for target devices.\n"
69 "\t\t Default: 32."); 69 "\t\t Default: 32.");
70 70
71static int ql4xqfulltracking = 1;
72module_param(ql4xqfulltracking, int, S_IRUGO | S_IWUSR);
73MODULE_PARM_DESC(ql4xqfulltracking,
74 " Enable or disable dynamic tracking and adjustment of\n"
75 "\t\t scsi device queue depth.\n"
76 "\t\t 0 - Disable.\n"
77 "\t\t 1 - Enable. (Default)");
78
71static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO; 79static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO;
72module_param(ql4xsess_recovery_tmo, int, S_IRUGO); 80module_param(ql4xsess_recovery_tmo, int, S_IRUGO);
73MODULE_PARM_DESC(ql4xsess_recovery_tmo, 81MODULE_PARM_DESC(ql4xsess_recovery_tmo,
74 " Target Session Recovery Timeout.\n" 82 " Target Session Recovery Timeout.\n"
75 "\t\t Default: 120 sec."); 83 "\t\t Default: 120 sec.");
76 84
85int ql4xmdcapmask = 0x1F;
86module_param(ql4xmdcapmask, int, S_IRUGO);
87MODULE_PARM_DESC(ql4xmdcapmask,
88 " Set the Minidump driver capture mask level.\n"
89 "\t\t Default is 0x1F.\n"
90 "\t\t Can be set to 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F");
91
92int ql4xenablemd = 1;
93module_param(ql4xenablemd, int, S_IRUGO | S_IWUSR);
94MODULE_PARM_DESC(ql4xenablemd,
95 " Set to enable minidump.\n"
96 "\t\t 0 - disable minidump\n"
97 "\t\t 1 - enable minidump (Default)");
98
77static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); 99static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha);
78/* 100/*
79 * SCSI host template entry points 101 * SCSI host template entry points
@@ -140,6 +162,8 @@ static int qla4xxx_slave_configure(struct scsi_device *device);
140static void qla4xxx_slave_destroy(struct scsi_device *sdev); 162static void qla4xxx_slave_destroy(struct scsi_device *sdev);
141static umode_t ql4_attr_is_visible(int param_type, int param); 163static umode_t ql4_attr_is_visible(int param_type, int param);
142static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type); 164static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
165static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth,
166 int reason);
143 167
144static struct qla4_8xxx_legacy_intr_set legacy_intr[] = 168static struct qla4_8xxx_legacy_intr_set legacy_intr[] =
145 QLA82XX_LEGACY_INTR_CONFIG; 169 QLA82XX_LEGACY_INTR_CONFIG;
@@ -159,6 +183,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
159 .slave_configure = qla4xxx_slave_configure, 183 .slave_configure = qla4xxx_slave_configure,
160 .slave_alloc = qla4xxx_slave_alloc, 184 .slave_alloc = qla4xxx_slave_alloc,
161 .slave_destroy = qla4xxx_slave_destroy, 185 .slave_destroy = qla4xxx_slave_destroy,
186 .change_queue_depth = qla4xxx_change_queue_depth,
162 187
163 .this_id = -1, 188 .this_id = -1,
164 .cmd_per_lun = 3, 189 .cmd_per_lun = 3,
@@ -1555,19 +1580,53 @@ static void qla4xxx_session_destroy(struct iscsi_cls_session *cls_sess)
1555 struct iscsi_session *sess; 1580 struct iscsi_session *sess;
1556 struct ddb_entry *ddb_entry; 1581 struct ddb_entry *ddb_entry;
1557 struct scsi_qla_host *ha; 1582 struct scsi_qla_host *ha;
1558 unsigned long flags; 1583 unsigned long flags, wtime;
1584 struct dev_db_entry *fw_ddb_entry = NULL;
1585 dma_addr_t fw_ddb_entry_dma;
1586 uint32_t ddb_state;
1587 int ret;
1559 1588
1560 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__)); 1589 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__));
1561 sess = cls_sess->dd_data; 1590 sess = cls_sess->dd_data;
1562 ddb_entry = sess->dd_data; 1591 ddb_entry = sess->dd_data;
1563 ha = ddb_entry->ha; 1592 ha = ddb_entry->ha;
1564 1593
1594 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1595 &fw_ddb_entry_dma, GFP_KERNEL);
1596 if (!fw_ddb_entry) {
1597 ql4_printk(KERN_ERR, ha,
1598 "%s: Unable to allocate dma buffer\n", __func__);
1599 goto destroy_session;
1600 }
1601
1602 wtime = jiffies + (HZ * LOGOUT_TOV);
1603 do {
1604 ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,
1605 fw_ddb_entry, fw_ddb_entry_dma,
1606 NULL, NULL, &ddb_state, NULL,
1607 NULL, NULL);
1608 if (ret == QLA_ERROR)
1609 goto destroy_session;
1610
1611 if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) ||
1612 (ddb_state == DDB_DS_SESSION_FAILED))
1613 goto destroy_session;
1614
1615 schedule_timeout_uninterruptible(HZ);
1616 } while ((time_after(wtime, jiffies)));
1617
1618destroy_session:
1565 qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index); 1619 qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
1566 1620
1567 spin_lock_irqsave(&ha->hardware_lock, flags); 1621 spin_lock_irqsave(&ha->hardware_lock, flags);
1568 qla4xxx_free_ddb(ha, ddb_entry); 1622 qla4xxx_free_ddb(ha, ddb_entry);
1569 spin_unlock_irqrestore(&ha->hardware_lock, flags); 1623 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1624
1570 iscsi_session_teardown(cls_sess); 1625 iscsi_session_teardown(cls_sess);
1626
1627 if (fw_ddb_entry)
1628 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1629 fw_ddb_entry, fw_ddb_entry_dma);
1571} 1630}
1572 1631
1573static struct iscsi_cls_conn * 1632static struct iscsi_cls_conn *
@@ -2220,6 +2279,9 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
2220 dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues, 2279 dma_free_coherent(&ha->pdev->dev, ha->queues_len, ha->queues,
2221 ha->queues_dma); 2280 ha->queues_dma);
2222 2281
2282 if (ha->fw_dump)
2283 vfree(ha->fw_dump);
2284
2223 ha->queues_len = 0; 2285 ha->queues_len = 0;
2224 ha->queues = NULL; 2286 ha->queues = NULL;
2225 ha->queues_dma = 0; 2287 ha->queues_dma = 0;
@@ -2229,6 +2291,8 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
2229 ha->response_dma = 0; 2291 ha->response_dma = 0;
2230 ha->shadow_regs = NULL; 2292 ha->shadow_regs = NULL;
2231 ha->shadow_regs_dma = 0; 2293 ha->shadow_regs_dma = 0;
2294 ha->fw_dump = NULL;
2295 ha->fw_dump_size = 0;
2232 2296
2233 /* Free srb pool. */ 2297 /* Free srb pool. */
2234 if (ha->srb_mempool) 2298 if (ha->srb_mempool)
@@ -5023,6 +5087,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
5023 5087
5024 set_bit(AF_INIT_DONE, &ha->flags); 5088 set_bit(AF_INIT_DONE, &ha->flags);
5025 5089
5090 qla4_8xxx_alloc_sysfs_attr(ha);
5091
5026 printk(KERN_INFO 5092 printk(KERN_INFO
5027 " QLogic iSCSI HBA Driver version: %s\n" 5093 " QLogic iSCSI HBA Driver version: %s\n"
5028 " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n", 5094 " QLogic ISP%04x @ %s, host#=%ld, fw=%02d.%02d.%02d.%02d\n",
@@ -5149,6 +5215,7 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
5149 iscsi_boot_destroy_kset(ha->boot_kset); 5215 iscsi_boot_destroy_kset(ha->boot_kset);
5150 5216
5151 qla4xxx_destroy_fw_ddb_session(ha); 5217 qla4xxx_destroy_fw_ddb_session(ha);
5218 qla4_8xxx_free_sysfs_attr(ha);
5152 5219
5153 scsi_remove_host(ha->host); 5220 scsi_remove_host(ha->host);
5154 5221
@@ -5217,6 +5284,15 @@ static void qla4xxx_slave_destroy(struct scsi_device *sdev)
5217 scsi_deactivate_tcq(sdev, 1); 5284 scsi_deactivate_tcq(sdev, 1);
5218} 5285}
5219 5286
5287static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth,
5288 int reason)
5289{
5290 if (!ql4xqfulltracking)
5291 return -EOPNOTSUPP;
5292
5293 return iscsi_change_queue_depth(sdev, qdepth, reason);
5294}
5295
5220/** 5296/**
5221 * qla4xxx_del_from_active_array - returns an active srb 5297 * qla4xxx_del_from_active_array - returns an active srb
5222 * @ha: Pointer to host adapter structure. 5298 * @ha: Pointer to host adapter structure.