aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx/ql4_mbx.c
diff options
context:
space:
mode:
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}