diff options
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_def.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_glbl.h | 1 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_init.c | 18 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_isr.c | 4 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_mbx.c | 35 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 64 | ||||
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_version.h | 2 |
7 files changed, 73 insertions, 52 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index 4249e52a5592..6f4cf2dd2f4a 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h | |||
@@ -418,7 +418,6 @@ struct scsi_qla_host { | |||
418 | * concurrently. | 418 | * concurrently. |
419 | */ | 419 | */ |
420 | struct mutex mbox_sem; | 420 | struct mutex mbox_sem; |
421 | wait_queue_head_t mailbox_wait_queue; | ||
422 | 421 | ||
423 | /* temporary mailbox status registers */ | 422 | /* temporary mailbox status registers */ |
424 | volatile uint8_t mbox_status_count; | 423 | volatile uint8_t mbox_status_count; |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 2122967bbf0b..e021eb5db2b2 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -76,4 +76,5 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, | |||
76 | extern int ql4xextended_error_logging; | 76 | extern int ql4xextended_error_logging; |
77 | extern int ql4xdiscoverywait; | 77 | extern int ql4xdiscoverywait; |
78 | extern int ql4xdontresethba; | 78 | extern int ql4xdontresethba; |
79 | extern int ql4_mod_unload; | ||
79 | #endif /* _QLA4x_GBL_H */ | 80 | #endif /* _QLA4x_GBL_H */ |
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c index cc210f297a78..b907b06d72ab 100644 --- a/drivers/scsi/qla4xxx/ql4_init.c +++ b/drivers/scsi/qla4xxx/ql4_init.c | |||
@@ -958,25 +958,25 @@ static int qla4xxx_start_firmware_from_flash(struct scsi_qla_host *ha) | |||
958 | return status; | 958 | return status; |
959 | } | 959 | } |
960 | 960 | ||
961 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a) | 961 | int ql4xxx_lock_drvr_wait(struct scsi_qla_host *ha) |
962 | { | 962 | { |
963 | #define QL4_LOCK_DRVR_WAIT 300 | 963 | #define QL4_LOCK_DRVR_WAIT 30 |
964 | #define QL4_LOCK_DRVR_SLEEP 100 | 964 | #define QL4_LOCK_DRVR_SLEEP 1 |
965 | 965 | ||
966 | int drvr_wait = QL4_LOCK_DRVR_WAIT; | 966 | int drvr_wait = QL4_LOCK_DRVR_WAIT; |
967 | while (drvr_wait) { | 967 | while (drvr_wait) { |
968 | if (ql4xxx_lock_drvr(a) == 0) { | 968 | if (ql4xxx_lock_drvr(ha) == 0) { |
969 | msleep(QL4_LOCK_DRVR_SLEEP); | 969 | ssleep(QL4_LOCK_DRVR_SLEEP); |
970 | if (drvr_wait) { | 970 | if (drvr_wait) { |
971 | DEBUG2(printk("scsi%ld: %s: Waiting for " | 971 | DEBUG2(printk("scsi%ld: %s: Waiting for " |
972 | "Global Init Semaphore...n", | 972 | "Global Init Semaphore(%d)...n", |
973 | a->host_no, | 973 | ha->host_no, |
974 | __func__)); | 974 | __func__, drvr_wait)); |
975 | } | 975 | } |
976 | drvr_wait -= QL4_LOCK_DRVR_SLEEP; | 976 | drvr_wait -= QL4_LOCK_DRVR_SLEEP; |
977 | } else { | 977 | } else { |
978 | DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " | 978 | DEBUG2(printk("scsi%ld: %s: Global Init Semaphore " |
979 | "acquired.n", a->host_no, __func__)); | 979 | "acquired.n", ha->host_no, __func__)); |
980 | return QLA_SUCCESS; | 980 | return QLA_SUCCESS; |
981 | } | 981 | } |
982 | } | 982 | } |
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index ef975e0dc87f..35b9e36a0e8d 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c | |||
@@ -433,7 +433,6 @@ static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha, | |||
433 | readl(&ha->reg->mailbox[i]); | 433 | readl(&ha->reg->mailbox[i]); |
434 | 434 | ||
435 | set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); | 435 | set_bit(AF_MBOX_COMMAND_DONE, &ha->flags); |
436 | wake_up(&ha->mailbox_wait_queue); | ||
437 | } | 436 | } |
438 | } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { | 437 | } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) { |
439 | /* Immediately process the AENs that don't require much work. | 438 | /* Immediately process the AENs that don't require much work. |
@@ -686,7 +685,8 @@ irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id) | |||
686 | &ha->reg->ctrl_status); | 685 | &ha->reg->ctrl_status); |
687 | readl(&ha->reg->ctrl_status); | 686 | readl(&ha->reg->ctrl_status); |
688 | 687 | ||
689 | set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); | 688 | if (!ql4_mod_unload) |
689 | set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); | ||
690 | 690 | ||
691 | break; | 691 | break; |
692 | } else if (intr_status & INTR_PENDING) { | 692 | } else if (intr_status & INTR_PENDING) { |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index b721dc5dd711..7f28657eef3f 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
@@ -29,18 +29,30 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
29 | u_long wait_count; | 29 | u_long wait_count; |
30 | uint32_t intr_status; | 30 | uint32_t intr_status; |
31 | unsigned long flags = 0; | 31 | unsigned long flags = 0; |
32 | DECLARE_WAITQUEUE(wait, current); | ||
33 | |||
34 | mutex_lock(&ha->mbox_sem); | ||
35 | |||
36 | /* Mailbox code active */ | ||
37 | set_bit(AF_MBOX_COMMAND, &ha->flags); | ||
38 | 32 | ||
39 | /* Make sure that pointers are valid */ | 33 | /* Make sure that pointers are valid */ |
40 | if (!mbx_cmd || !mbx_sts) { | 34 | if (!mbx_cmd || !mbx_sts) { |
41 | DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " | 35 | DEBUG2(printk("scsi%ld: %s: Invalid mbx_cmd or mbx_sts " |
42 | "pointer\n", ha->host_no, __func__)); | 36 | "pointer\n", ha->host_no, __func__)); |
43 | goto mbox_exit; | 37 | return status; |
38 | } | ||
39 | /* Mailbox code active */ | ||
40 | wait_count = MBOX_TOV * 100; | ||
41 | |||
42 | while (wait_count--) { | ||
43 | mutex_lock(&ha->mbox_sem); | ||
44 | if (!test_bit(AF_MBOX_COMMAND, &ha->flags)) { | ||
45 | set_bit(AF_MBOX_COMMAND, &ha->flags); | ||
46 | mutex_unlock(&ha->mbox_sem); | ||
47 | break; | ||
48 | } | ||
49 | mutex_unlock(&ha->mbox_sem); | ||
50 | if (!wait_count) { | ||
51 | DEBUG2(printk("scsi%ld: %s: mbox_sem failed\n", | ||
52 | ha->host_no, __func__)); | ||
53 | return status; | ||
54 | } | ||
55 | msleep(10); | ||
44 | } | 56 | } |
45 | 57 | ||
46 | /* To prevent overwriting mailbox registers for a command that has | 58 | /* To prevent overwriting mailbox registers for a command that has |
@@ -73,8 +85,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
73 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 85 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
74 | 86 | ||
75 | /* Wait for completion */ | 87 | /* Wait for completion */ |
76 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
77 | add_wait_queue(&ha->mailbox_wait_queue, &wait); | ||
78 | 88 | ||
79 | /* | 89 | /* |
80 | * If we don't want status, don't wait for the mailbox command to | 90 | * If we don't want status, don't wait for the mailbox command to |
@@ -83,8 +93,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
83 | */ | 93 | */ |
84 | if (outCount == 0) { | 94 | if (outCount == 0) { |
85 | status = QLA_SUCCESS; | 95 | status = QLA_SUCCESS; |
86 | set_current_state(TASK_RUNNING); | ||
87 | remove_wait_queue(&ha->mailbox_wait_queue, &wait); | ||
88 | goto mbox_exit; | 96 | goto mbox_exit; |
89 | } | 97 | } |
90 | /* Wait for command to complete */ | 98 | /* Wait for command to complete */ |
@@ -108,8 +116,6 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
108 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 116 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
109 | msleep(10); | 117 | msleep(10); |
110 | } | 118 | } |
111 | set_current_state(TASK_RUNNING); | ||
112 | remove_wait_queue(&ha->mailbox_wait_queue, &wait); | ||
113 | 119 | ||
114 | /* Check for mailbox timeout. */ | 120 | /* Check for mailbox timeout. */ |
115 | if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { | 121 | if (!test_bit(AF_MBOX_COMMAND_DONE, &ha->flags)) { |
@@ -155,9 +161,10 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount, | |||
155 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 161 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
156 | 162 | ||
157 | mbox_exit: | 163 | mbox_exit: |
164 | mutex_lock(&ha->mbox_sem); | ||
158 | clear_bit(AF_MBOX_COMMAND, &ha->flags); | 165 | clear_bit(AF_MBOX_COMMAND, &ha->flags); |
159 | clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); | ||
160 | mutex_unlock(&ha->mbox_sem); | 166 | mutex_unlock(&ha->mbox_sem); |
167 | clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags); | ||
161 | 168 | ||
162 | return status; | 169 | return status; |
163 | } | 170 | } |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index 9ef693c8809a..81fb7bd44f01 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -40,6 +40,8 @@ MODULE_PARM_DESC(ql4xextended_error_logging, | |||
40 | "Option to enable extended error logging, " | 40 | "Option to enable extended error logging, " |
41 | "Default is 0 - no logging, 1 - debug logging"); | 41 | "Default is 0 - no logging, 1 - debug logging"); |
42 | 42 | ||
43 | int ql4_mod_unload = 0; | ||
44 | |||
43 | /* | 45 | /* |
44 | * SCSI host template entry points | 46 | * SCSI host template entry points |
45 | */ | 47 | */ |
@@ -422,6 +424,9 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd, | |||
422 | goto qc_host_busy; | 424 | goto qc_host_busy; |
423 | } | 425 | } |
424 | 426 | ||
427 | if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) | ||
428 | goto qc_host_busy; | ||
429 | |||
425 | spin_unlock_irq(ha->host->host_lock); | 430 | spin_unlock_irq(ha->host->host_lock); |
426 | 431 | ||
427 | srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done); | 432 | srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done); |
@@ -707,16 +712,12 @@ static int qla4xxx_cmd_wait(struct scsi_qla_host *ha) | |||
707 | return stat; | 712 | return stat; |
708 | } | 713 | } |
709 | 714 | ||
710 | /** | 715 | static void qla4xxx_hw_reset(struct scsi_qla_host *ha) |
711 | * qla4xxx_soft_reset - performs soft reset. | ||
712 | * @ha: Pointer to host adapter structure. | ||
713 | **/ | ||
714 | int qla4xxx_soft_reset(struct scsi_qla_host *ha) | ||
715 | { | 716 | { |
716 | uint32_t max_wait_time; | ||
717 | unsigned long flags = 0; | ||
718 | int status = QLA_ERROR; | ||
719 | uint32_t ctrl_status; | 717 | uint32_t ctrl_status; |
718 | unsigned long flags = 0; | ||
719 | |||
720 | DEBUG2(printk(KERN_ERR "scsi%ld: %s\n", ha->host_no, __func__)); | ||
720 | 721 | ||
721 | spin_lock_irqsave(&ha->hardware_lock, flags); | 722 | spin_lock_irqsave(&ha->hardware_lock, flags); |
722 | 723 | ||
@@ -733,6 +734,20 @@ int qla4xxx_soft_reset(struct scsi_qla_host *ha) | |||
733 | readl(&ha->reg->ctrl_status); | 734 | readl(&ha->reg->ctrl_status); |
734 | 735 | ||
735 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 736 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
737 | } | ||
738 | |||
739 | /** | ||
740 | * qla4xxx_soft_reset - performs soft reset. | ||
741 | * @ha: Pointer to host adapter structure. | ||
742 | **/ | ||
743 | int qla4xxx_soft_reset(struct scsi_qla_host *ha) | ||
744 | { | ||
745 | uint32_t max_wait_time; | ||
746 | unsigned long flags = 0; | ||
747 | int status = QLA_ERROR; | ||
748 | uint32_t ctrl_status; | ||
749 | |||
750 | qla4xxx_hw_reset(ha); | ||
736 | 751 | ||
737 | /* Wait until the Network Reset Intr bit is cleared */ | 752 | /* Wait until the Network Reset Intr bit is cleared */ |
738 | max_wait_time = RESET_INTR_TOV; | 753 | max_wait_time = RESET_INTR_TOV; |
@@ -966,10 +981,12 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
966 | struct scsi_qla_host *ha = | 981 | struct scsi_qla_host *ha = |
967 | container_of(work, struct scsi_qla_host, dpc_work); | 982 | container_of(work, struct scsi_qla_host, dpc_work); |
968 | struct ddb_entry *ddb_entry, *dtemp; | 983 | struct ddb_entry *ddb_entry, *dtemp; |
984 | int status = QLA_ERROR; | ||
969 | 985 | ||
970 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up." | 986 | DEBUG2(printk("scsi%ld: %s: DPC handler waking up." |
971 | "flags = 0x%08lx, dpc_flags = 0x%08lx\n", | 987 | "flags = 0x%08lx, dpc_flags = 0x%08lx ctrl_stat = 0x%08x\n", |
972 | ha->host_no, __func__, ha->flags, ha->dpc_flags)); | 988 | ha->host_no, __func__, ha->flags, ha->dpc_flags, |
989 | readw(&ha->reg->ctrl_status))); | ||
973 | 990 | ||
974 | /* Initialization not yet finished. Don't do anything yet. */ | 991 | /* Initialization not yet finished. Don't do anything yet. */ |
975 | if (!test_bit(AF_INIT_DONE, &ha->flags)) | 992 | if (!test_bit(AF_INIT_DONE, &ha->flags)) |
@@ -983,31 +1000,28 @@ static void qla4xxx_do_dpc(struct work_struct *work) | |||
983 | test_bit(DPC_RESET_HA, &ha->dpc_flags)) | 1000 | test_bit(DPC_RESET_HA, &ha->dpc_flags)) |
984 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); | 1001 | qla4xxx_recover_adapter(ha, PRESERVE_DDB_LIST); |
985 | 1002 | ||
986 | if (test_and_clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { | 1003 | if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags)) { |
987 | uint8_t wait_time = RESET_INTR_TOV; | 1004 | uint8_t wait_time = RESET_INTR_TOV; |
988 | unsigned long flags = 0; | ||
989 | |||
990 | qla4xxx_flush_active_srbs(ha); | ||
991 | 1005 | ||
992 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
993 | while ((readw(&ha->reg->ctrl_status) & | 1006 | while ((readw(&ha->reg->ctrl_status) & |
994 | (CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) { | 1007 | (CSR_SOFT_RESET | CSR_FORCE_SOFT_RESET)) != 0) { |
995 | if (--wait_time == 0) | 1008 | if (--wait_time == 0) |
996 | break; | 1009 | break; |
997 | |||
998 | spin_unlock_irqrestore(&ha->hardware_lock, | ||
999 | flags); | ||
1000 | |||
1001 | msleep(1000); | 1010 | msleep(1000); |
1002 | |||
1003 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
1004 | } | 1011 | } |
1005 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
1006 | |||
1007 | if (wait_time == 0) | 1012 | if (wait_time == 0) |
1008 | DEBUG2(printk("scsi%ld: %s: SR|FSR " | 1013 | DEBUG2(printk("scsi%ld: %s: SR|FSR " |
1009 | "bit not cleared-- resetting\n", | 1014 | "bit not cleared-- resetting\n", |
1010 | ha->host_no, __func__)); | 1015 | ha->host_no, __func__)); |
1016 | qla4xxx_flush_active_srbs(ha); | ||
1017 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) { | ||
1018 | qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS); | ||
1019 | status = qla4xxx_initialize_adapter(ha, | ||
1020 | PRESERVE_DDB_LIST); | ||
1021 | } | ||
1022 | clear_bit(DPC_RESET_HA_INTR, &ha->dpc_flags); | ||
1023 | if (status == QLA_SUCCESS) | ||
1024 | qla4xxx_enable_intrs(ha); | ||
1011 | } | 1025 | } |
1012 | } | 1026 | } |
1013 | 1027 | ||
@@ -1062,7 +1076,7 @@ static void qla4xxx_free_adapter(struct scsi_qla_host *ha) | |||
1062 | 1076 | ||
1063 | /* Issue Soft Reset to put firmware in unknown state */ | 1077 | /* Issue Soft Reset to put firmware in unknown state */ |
1064 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) | 1078 | if (ql4xxx_lock_drvr_wait(ha) == QLA_SUCCESS) |
1065 | qla4xxx_soft_reset(ha); | 1079 | qla4xxx_hw_reset(ha); |
1066 | 1080 | ||
1067 | /* Remove timer thread, if present */ | 1081 | /* Remove timer thread, if present */ |
1068 | if (ha->timer_active) | 1082 | if (ha->timer_active) |
@@ -1198,7 +1212,6 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev, | |||
1198 | INIT_LIST_HEAD(&ha->free_srb_q); | 1212 | INIT_LIST_HEAD(&ha->free_srb_q); |
1199 | 1213 | ||
1200 | mutex_init(&ha->mbox_sem); | 1214 | mutex_init(&ha->mbox_sem); |
1201 | init_waitqueue_head(&ha->mailbox_wait_queue); | ||
1202 | 1215 | ||
1203 | spin_lock_init(&ha->hardware_lock); | 1216 | spin_lock_init(&ha->hardware_lock); |
1204 | 1217 | ||
@@ -1665,6 +1678,7 @@ no_srp_cache: | |||
1665 | 1678 | ||
1666 | static void __exit qla4xxx_module_exit(void) | 1679 | static void __exit qla4xxx_module_exit(void) |
1667 | { | 1680 | { |
1681 | ql4_mod_unload = 1; | ||
1668 | pci_unregister_driver(&qla4xxx_pci_driver); | 1682 | pci_unregister_driver(&qla4xxx_pci_driver); |
1669 | iscsi_unregister_transport(&qla4xxx_iscsi_transport); | 1683 | iscsi_unregister_transport(&qla4xxx_iscsi_transport); |
1670 | kmem_cache_destroy(srb_cachep); | 1684 | kmem_cache_destroy(srb_cachep); |
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h index 454e19c8ad68..e5183a697d1f 100644 --- a/drivers/scsi/qla4xxx/ql4_version.h +++ b/drivers/scsi/qla4xxx/ql4_version.h | |||
@@ -5,4 +5,4 @@ | |||
5 | * See LICENSE.qla4xxx for copyright and licensing details. | 5 | * See LICENSE.qla4xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define QLA4XXX_DRIVER_VERSION "5.00.07-k" | 8 | #define QLA4XXX_DRIVER_VERSION "5.00.07-k1" |