aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_mbx.c
diff options
context:
space:
mode:
authorDavid C Somayajulu <david.somayajulu@qlogic.com>2007-01-22 15:26:11 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-01-27 10:15:46 -0500
commit477ffb9d8732f30e7ab2d20f6ed0c22bad37a4a5 (patch)
treed8633736db9eb4609d935bc5ff0c1a8fba5d07f4 /drivers/scsi/qla4xxx/ql4_mbx.c
parent938e2ac0b7ac72d264783b0b548eb6078c295294 (diff)
[SCSI] qla4xxx: bug fixes
The included patch fixes the following issues: 1. qla3xxx/qla4xxx co-existence issue which can result in a lockup when qla3xxx driver is unloaded, or when ifdown; ifup is performed on one of the interfaces correponding to qla3xxx. This is because qla4xxx HBA supports one ethernet and iscsi interfaces per port. Both iscsi and ethernet interfaces share the same state machine. The problem has to do with synchronizing access to the state machine in the event of a reset 2. mutex_lock() is sometimes not followed by mutex_unlock() prior to invoking a msleep() in qla4xxx_mailbox_command() Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/qla4xxx/ql4_mbx.c')
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c35
1 files changed, 21 insertions, 14 deletions
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
157mbox_exit: 163mbox_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}