|
@@ -40,6 +40,8 @@ MODULE_PARM_DESC(ql4xextended_error_logging,
|
|
"Option to enable extended error logging, "
|
|
"Option to enable extended error logging, "
|
|
"Default is 0 - no logging, 1 - debug logging");
|
|
"Default is 0 - no logging, 1 - debug logging");
|
|
|
|
|
|
|
|
+int ql4_mod_unload = 0;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* SCSI host template entry points
|
|
* SCSI host template entry points
|
|
*/
|
|
*/
|
|
@@ -422,6 +424,9 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
|
|
goto qc_host_busy;
|
|
goto qc_host_busy;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags))
|
|
|
|
+ goto qc_host_busy;
|
|
|
|
+
|
|
spin_unlock_irq(ha->host->host_lock);
|
|
spin_unlock_irq(ha->host->host_lock);
|
|
|
|
|
|
srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done);
|
|
srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done);
|
|
@@ -707,16 +712,12 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha)
|
|
return stat;
|
|
return stat;
|
|
}
|
|
}
|
|
|
|
|
|
-/**
|
|
|
|
- * qla4xxx_soft_reset - performs soft reset.
|
|
|
|
- * @ha: Pointer to host adapter structure.
|
|
|
|
- **/
|
|
|
|
-int qla4xxx_soft_reset(struct scsi_qla_host *ha)
|
|
|
|
|
|
+static void qla4xxx_hw_reset(struct scsi_qla_host *ha)
|
|
{
|
|
{
|
|
- uint32_t max_wait_time;
|
|
|
|
- unsigned long flags = 0;
|
|
|
|
- int status = QLA_ERROR;
|
|
|
|
uint32_t ctrl_status;
|
|
uint32_t ctrl_status;
|
|
|
|
+ unsigned long flags = 0;
|
|
|
|
+
|
|
|
|
+ DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__));
|
|
|
|
|
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
|
|
|
|
@@ -733,6 +734,20 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha)
|
|
readl(&ha->reg->ctrl_status);
|
|
readl(&ha->reg->ctrl_status);
|
|
|
|
|
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * qla4xxx_soft_reset - performs soft reset.
|
|
|
|
+ * @ha: Pointer to host adapter structure.
|
|
|
|
+ **/
|
|
|
|
+int qla4xxx_soft_reset(struct scsi_qla_host *ha)
|
|
|
|
+{
|
|
|
|
+ uint32_t max_wait_time;
|
|
|
|
+ unsigned long flags = 0;
|
|
|
|
+ int status = QLA_ERROR;
|
|
|
|
+ uint32_t ctrl_status;
|
|
|
|
+
|
|
|
|
+ qla4xxx_hw_reset(ha);
|
|
|
|
|
|
/* Wait until the Network Reset Intr bit is cleared */
|
|
/* Wait until the Network Reset Intr bit is cleared */
|
|
max_wait_time = RESET_INTR_TOV;
|
|
max_wait_time = RESET_INTR_TOV;
|
|
@@ -966,10 +981,12 @@ static void qla4xxx_do_dpc(struct work_struct *work)
|
|
struct scsi_qla_host *ha =
|
|
struct scsi_qla_host *ha =
|
|
container_of(work, struct scsi_qla_host, dpc_work);
|
|
container_of(work, struct scsi_qla_host, dpc_work);
|
|
struct ddb_entry *ddb_entry, *dtemp;
|
|
struct ddb_entry *ddb_entry, *dtemp;
|
|
|
|
+ int status = QLA_ERROR;
|
|
|
|
|
|
DEBUG2(printk("scsi%ld: %s: DPC handler waking up."
|
|
DEBUG2(printk("scsi%ld: %s: DPC handler waking up."
|
|
- "flags = 0x%08lx, dpc_flags = 0x%08lx\n",
|
|
|
|
- ha->host_no, __func__, ha->flags, ha->dpc_flags));
|
|
|
|
|
|
+ "flags = 0x%08lx, dpc_flags = 0x%08lx ctrl_stat = 0x%08x\n",
|
|
|
|
+ ha->host_no, __func__, ha->flags, ha->dpc_flags,
|
|
|
|
+ readw(&ha->reg->ctrl_status)));
|
|
|
|
|
|
/* Initialization not yet finished. Don't do anything yet. */
|
|
/* Initialization not yet finished. Don't do anything yet. */
|
|
if (!test_bit(AF_INIT_DONE, &ha->flags))
|
|
if (!test_bit(AF_INIT_DONE, &ha->flags))
|
|
@@ -983,31 +1000,28 @@ static void qla4xxx_do_dpc(struct work_struct *work)
|
|
test_bit(DPC_RESET_HA, &ha->dpc_flags))
|
|
test_bit(DPC_RESET_HA, &ha->dpc_flags))
|
|
qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
|
|
qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST);
|
|
|
|
|
|
- if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
|
|
|
|
|
|
+ if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) {
|
|
uint8_t wait_time = RESET_INTR_TOV;
|
|
uint8_t wait_time = RESET_INTR_TOV;
|
|
- unsigned long flags = 0;
|
|
|
|
-
|
|
|
|
- qla4xxx_flush_active_srbs(ha);
|
|
|
|
|
|
|
|
- spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
|
|
while ((readw(&ha->reg->ctrl_status) &
|
|
while ((readw(&ha->reg->ctrl_status) &
|
|
(CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) {
|
|
(CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) {
|
|
if (--wait_time == 0)
|
|
if (--wait_time == 0)
|
|
break;
|
|
break;
|
|
-
|
|
|
|
- spin_unlock_irqrestore(&ha->hardware_lock,
|
|
|
|
- flags);
|
|
|
|
-
|
|
|
|
msleep(1000);
|
|
msleep(1000);
|
|
-
|
|
|
|
- spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
|
|
}
|
|
}
|
|
- spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
|
|
-
|
|
|
|
if (wait_time == 0)
|
|
if (wait_time == 0)
|
|
DEBUG2(printk("scsi%ld: %s: SR|FSR "
|
|
DEBUG2(printk("scsi%ld: %s: SR|FSR "
|
|
"bit not cleared-- resetting\n",
|
|
"bit not cleared-- resetting\n",
|
|
ha->host_no, __func__));
|
|
ha->host_no, __func__));
|
|
|
|
+ qla4xxx_flush_active_srbs(ha);
|
|
|
|
+ if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) {
|
|
|
|
+ qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
|
|
|
|
+ status = qla4xxx_initialize_adapter(ha,
|
|
|
|
+ PRESERVE_DDB_LIST);
|
|
|
|
+ }
|
|
|
|
+ clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
|
|
|
|
+ if (status == QLA_SUCCESS)
|
|
|
|
+ qla4xxx_enable_intrs(ha);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1062,7 +1076,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha)
|
|
|
|
|
|
/* Issue Soft Reset to put firmware in unknown state */
|
|
/* Issue Soft Reset to put firmware in unknown state */
|
|
if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
|
|
if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS)
|
|
- qla4xxx_soft_reset(ha);
|
|
|
|
|
|
+ qla4xxx_hw_reset(ha);
|
|
|
|
|
|
/* Remove timer thread, if present */
|
|
/* Remove timer thread, if present */
|
|
if (ha->timer_active)
|
|
if (ha->timer_active)
|
|
@@ -1198,7 +1212,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
|
|
INIT_LIST_HEAD(&ha->free_srb_q);
|
|
INIT_LIST_HEAD(&ha->free_srb_q);
|
|
|
|
|
|
mutex_init(&ha->mbox_sem);
|
|
mutex_init(&ha->mbox_sem);
|
|
- init_waitqueue_head(&ha->mailbox_wait_queue);
|
|
|
|
|
|
|
|
spin_lock_init(&ha->hardware_lock);
|
|
spin_lock_init(&ha->hardware_lock);
|
|
|
|
|
|
@@ -1665,6 +1678,7 @@ no_srp_cache:
|
|
|
|
|
|
static void __exit qla4xxx_module_exit(void)
|
|
static void __exit qla4xxx_module_exit(void)
|
|
{
|
|
{
|
|
|
|
+ ql4_mod_unload = 1;
|
|
pci_unregister_driver(&qla4xxx_pci_driver);
|
|
pci_unregister_driver(&qla4xxx_pci_driver);
|
|
iscsi_unregister_transport(&qla4xxx_iscsi_transport);
|
|
iscsi_unregister_transport(&qla4xxx_iscsi_transport);
|
|
kmem_cache_destroy(srb_cachep);
|
|
kmem_cache_destroy(srb_cachep);
|