diff options
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 840 |
1 files changed, 532 insertions, 308 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index a76efd99d007..d5fb79a88001 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -10,10 +10,13 @@ | |||
10 | #include <scsi/scsi_tcq.h> | 10 | #include <scsi/scsi_tcq.h> |
11 | 11 | ||
12 | static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); | 12 | static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); |
13 | static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t); | 13 | static void qla2x00_process_completed_request(struct scsi_qla_host *, |
14 | static void qla2x00_status_entry(scsi_qla_host_t *, void *); | 14 | struct req_que *, uint32_t); |
15 | static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *); | ||
15 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); | 16 | static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *); |
16 | static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); | 17 | static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *, |
18 | sts_entry_t *); | ||
19 | static struct scsi_qla_host *qla2x00_get_rsp_host(struct rsp_que *); | ||
17 | 20 | ||
18 | /** | 21 | /** |
19 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. | 22 | * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200. |
@@ -27,24 +30,28 @@ static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *); | |||
27 | irqreturn_t | 30 | irqreturn_t |
28 | qla2100_intr_handler(int irq, void *dev_id) | 31 | qla2100_intr_handler(int irq, void *dev_id) |
29 | { | 32 | { |
30 | scsi_qla_host_t *ha; | 33 | scsi_qla_host_t *vha; |
34 | struct qla_hw_data *ha; | ||
31 | struct device_reg_2xxx __iomem *reg; | 35 | struct device_reg_2xxx __iomem *reg; |
32 | int status; | 36 | int status; |
33 | unsigned long iter; | 37 | unsigned long iter; |
34 | uint16_t hccr; | 38 | uint16_t hccr; |
35 | uint16_t mb[4]; | 39 | uint16_t mb[4]; |
40 | struct rsp_que *rsp; | ||
36 | 41 | ||
37 | ha = (scsi_qla_host_t *) dev_id; | 42 | rsp = (struct rsp_que *) dev_id; |
38 | if (!ha) { | 43 | if (!rsp) { |
39 | printk(KERN_INFO | 44 | printk(KERN_INFO |
40 | "%s(): NULL host pointer\n", __func__); | 45 | "%s(): NULL response queue pointer\n", __func__); |
41 | return (IRQ_NONE); | 46 | return (IRQ_NONE); |
42 | } | 47 | } |
43 | 48 | ||
49 | ha = rsp->hw; | ||
44 | reg = &ha->iobase->isp; | 50 | reg = &ha->iobase->isp; |
45 | status = 0; | 51 | status = 0; |
46 | 52 | ||
47 | spin_lock(&ha->hardware_lock); | 53 | spin_lock(&ha->hardware_lock); |
54 | vha = qla2x00_get_rsp_host(rsp); | ||
48 | for (iter = 50; iter--; ) { | 55 | for (iter = 50; iter--; ) { |
49 | hccr = RD_REG_WORD(®->hccr); | 56 | hccr = RD_REG_WORD(®->hccr); |
50 | if (hccr & HCCR_RISC_PAUSE) { | 57 | if (hccr & HCCR_RISC_PAUSE) { |
@@ -59,8 +66,8 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
59 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); | 66 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
60 | RD_REG_WORD(®->hccr); | 67 | RD_REG_WORD(®->hccr); |
61 | 68 | ||
62 | ha->isp_ops->fw_dump(ha, 1); | 69 | ha->isp_ops->fw_dump(vha, 1); |
63 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 70 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
64 | break; | 71 | break; |
65 | } else if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) | 72 | } else if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) |
66 | break; | 73 | break; |
@@ -72,24 +79,24 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
72 | /* Get mailbox data. */ | 79 | /* Get mailbox data. */ |
73 | mb[0] = RD_MAILBOX_REG(ha, reg, 0); | 80 | mb[0] = RD_MAILBOX_REG(ha, reg, 0); |
74 | if (mb[0] > 0x3fff && mb[0] < 0x8000) { | 81 | if (mb[0] > 0x3fff && mb[0] < 0x8000) { |
75 | qla2x00_mbx_completion(ha, mb[0]); | 82 | qla2x00_mbx_completion(vha, mb[0]); |
76 | status |= MBX_INTERRUPT; | 83 | status |= MBX_INTERRUPT; |
77 | } else if (mb[0] > 0x7fff && mb[0] < 0xc000) { | 84 | } else if (mb[0] > 0x7fff && mb[0] < 0xc000) { |
78 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); | 85 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); |
79 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); | 86 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); |
80 | mb[3] = RD_MAILBOX_REG(ha, reg, 3); | 87 | mb[3] = RD_MAILBOX_REG(ha, reg, 3); |
81 | qla2x00_async_event(ha, mb); | 88 | qla2x00_async_event(vha, rsp, mb); |
82 | } else { | 89 | } else { |
83 | /*EMPTY*/ | 90 | /*EMPTY*/ |
84 | DEBUG2(printk("scsi(%ld): Unrecognized " | 91 | DEBUG2(printk("scsi(%ld): Unrecognized " |
85 | "interrupt type (%d).\n", | 92 | "interrupt type (%d).\n", |
86 | ha->host_no, mb[0])); | 93 | vha->host_no, mb[0])); |
87 | } | 94 | } |
88 | /* Release mailbox registers. */ | 95 | /* Release mailbox registers. */ |
89 | WRT_REG_WORD(®->semaphore, 0); | 96 | WRT_REG_WORD(®->semaphore, 0); |
90 | RD_REG_WORD(®->semaphore); | 97 | RD_REG_WORD(®->semaphore); |
91 | } else { | 98 | } else { |
92 | qla2x00_process_response_queue(ha); | 99 | qla2x00_process_response_queue(rsp); |
93 | 100 | ||
94 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 101 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
95 | RD_REG_WORD(®->hccr); | 102 | RD_REG_WORD(®->hccr); |
@@ -118,25 +125,29 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
118 | irqreturn_t | 125 | irqreturn_t |
119 | qla2300_intr_handler(int irq, void *dev_id) | 126 | qla2300_intr_handler(int irq, void *dev_id) |
120 | { | 127 | { |
121 | scsi_qla_host_t *ha; | 128 | scsi_qla_host_t *vha; |
122 | struct device_reg_2xxx __iomem *reg; | 129 | struct device_reg_2xxx __iomem *reg; |
123 | int status; | 130 | int status; |
124 | unsigned long iter; | 131 | unsigned long iter; |
125 | uint32_t stat; | 132 | uint32_t stat; |
126 | uint16_t hccr; | 133 | uint16_t hccr; |
127 | uint16_t mb[4]; | 134 | uint16_t mb[4]; |
135 | struct rsp_que *rsp; | ||
136 | struct qla_hw_data *ha; | ||
128 | 137 | ||
129 | ha = (scsi_qla_host_t *) dev_id; | 138 | rsp = (struct rsp_que *) dev_id; |
130 | if (!ha) { | 139 | if (!rsp) { |
131 | printk(KERN_INFO | 140 | printk(KERN_INFO |
132 | "%s(): NULL host pointer\n", __func__); | 141 | "%s(): NULL response queue pointer\n", __func__); |
133 | return (IRQ_NONE); | 142 | return (IRQ_NONE); |
134 | } | 143 | } |
135 | 144 | ||
145 | ha = rsp->hw; | ||
136 | reg = &ha->iobase->isp; | 146 | reg = &ha->iobase->isp; |
137 | status = 0; | 147 | status = 0; |
138 | 148 | ||
139 | spin_lock(&ha->hardware_lock); | 149 | spin_lock(&ha->hardware_lock); |
150 | vha = qla2x00_get_rsp_host(rsp); | ||
140 | for (iter = 50; iter--; ) { | 151 | for (iter = 50; iter--; ) { |
141 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 152 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
142 | if (stat & HSR_RISC_PAUSED) { | 153 | if (stat & HSR_RISC_PAUSED) { |
@@ -159,8 +170,8 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
159 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); | 170 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); |
160 | RD_REG_WORD(®->hccr); | 171 | RD_REG_WORD(®->hccr); |
161 | 172 | ||
162 | ha->isp_ops->fw_dump(ha, 1); | 173 | ha->isp_ops->fw_dump(vha, 1); |
163 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 174 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
164 | break; | 175 | break; |
165 | } else if ((stat & HSR_RISC_INT) == 0) | 176 | } else if ((stat & HSR_RISC_INT) == 0) |
166 | break; | 177 | break; |
@@ -170,7 +181,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
170 | case 0x2: | 181 | case 0x2: |
171 | case 0x10: | 182 | case 0x10: |
172 | case 0x11: | 183 | case 0x11: |
173 | qla2x00_mbx_completion(ha, MSW(stat)); | 184 | qla2x00_mbx_completion(vha, MSW(stat)); |
174 | status |= MBX_INTERRUPT; | 185 | status |= MBX_INTERRUPT; |
175 | 186 | ||
176 | /* Release mailbox registers. */ | 187 | /* Release mailbox registers. */ |
@@ -181,26 +192,26 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
181 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); | 192 | mb[1] = RD_MAILBOX_REG(ha, reg, 1); |
182 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); | 193 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); |
183 | mb[3] = RD_MAILBOX_REG(ha, reg, 3); | 194 | mb[3] = RD_MAILBOX_REG(ha, reg, 3); |
184 | qla2x00_async_event(ha, mb); | 195 | qla2x00_async_event(vha, rsp, mb); |
185 | break; | 196 | break; |
186 | case 0x13: | 197 | case 0x13: |
187 | qla2x00_process_response_queue(ha); | 198 | qla2x00_process_response_queue(rsp); |
188 | break; | 199 | break; |
189 | case 0x15: | 200 | case 0x15: |
190 | mb[0] = MBA_CMPLT_1_16BIT; | 201 | mb[0] = MBA_CMPLT_1_16BIT; |
191 | mb[1] = MSW(stat); | 202 | mb[1] = MSW(stat); |
192 | qla2x00_async_event(ha, mb); | 203 | qla2x00_async_event(vha, rsp, mb); |
193 | break; | 204 | break; |
194 | case 0x16: | 205 | case 0x16: |
195 | mb[0] = MBA_SCSI_COMPLETION; | 206 | mb[0] = MBA_SCSI_COMPLETION; |
196 | mb[1] = MSW(stat); | 207 | mb[1] = MSW(stat); |
197 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); | 208 | mb[2] = RD_MAILBOX_REG(ha, reg, 2); |
198 | qla2x00_async_event(ha, mb); | 209 | qla2x00_async_event(vha, rsp, mb); |
199 | break; | 210 | break; |
200 | default: | 211 | default: |
201 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " | 212 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " |
202 | "(%d).\n", | 213 | "(%d).\n", |
203 | ha->host_no, stat & 0xff)); | 214 | vha->host_no, stat & 0xff)); |
204 | break; | 215 | break; |
205 | } | 216 | } |
206 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); | 217 | WRT_REG_WORD(®->hccr, HCCR_CLR_RISC_INT); |
@@ -223,10 +234,11 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
223 | * @mb0: Mailbox0 register | 234 | * @mb0: Mailbox0 register |
224 | */ | 235 | */ |
225 | static void | 236 | static void |
226 | qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0) | 237 | qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) |
227 | { | 238 | { |
228 | uint16_t cnt; | 239 | uint16_t cnt; |
229 | uint16_t __iomem *wptr; | 240 | uint16_t __iomem *wptr; |
241 | struct qla_hw_data *ha = vha->hw; | ||
230 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 242 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
231 | 243 | ||
232 | /* Load return mailbox registers. */ | 244 | /* Load return mailbox registers. */ |
@@ -247,10 +259,10 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0) | |||
247 | 259 | ||
248 | if (ha->mcp) { | 260 | if (ha->mcp) { |
249 | DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n", | 261 | DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n", |
250 | __func__, ha->host_no, ha->mcp->mb[0])); | 262 | __func__, vha->host_no, ha->mcp->mb[0])); |
251 | } else { | 263 | } else { |
252 | DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n", | 264 | DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n", |
253 | __func__, ha->host_no)); | 265 | __func__, vha->host_no)); |
254 | } | 266 | } |
255 | } | 267 | } |
256 | 268 | ||
@@ -260,7 +272,7 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0) | |||
260 | * @mb: Mailbox registers (0 - 3) | 272 | * @mb: Mailbox registers (0 - 3) |
261 | */ | 273 | */ |
262 | void | 274 | void |
263 | qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | 275 | qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) |
264 | { | 276 | { |
265 | #define LS_UNKNOWN 2 | 277 | #define LS_UNKNOWN 2 |
266 | static char *link_speeds[5] = { "1", "2", "?", "4", "8" }; | 278 | static char *link_speeds[5] = { "1", "2", "?", "4", "8" }; |
@@ -268,6 +280,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
268 | uint16_t handle_cnt; | 280 | uint16_t handle_cnt; |
269 | uint16_t cnt; | 281 | uint16_t cnt; |
270 | uint32_t handles[5]; | 282 | uint32_t handles[5]; |
283 | struct qla_hw_data *ha = vha->hw; | ||
271 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 284 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
272 | uint32_t rscn_entry, host_pid; | 285 | uint32_t rscn_entry, host_pid; |
273 | uint8_t rscn_queue_index; | 286 | uint8_t rscn_queue_index; |
@@ -329,17 +342,19 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
329 | 342 | ||
330 | switch (mb[0]) { | 343 | switch (mb[0]) { |
331 | case MBA_SCSI_COMPLETION: /* Fast Post */ | 344 | case MBA_SCSI_COMPLETION: /* Fast Post */ |
332 | if (!ha->flags.online) | 345 | if (!vha->flags.online) |
333 | break; | 346 | break; |
334 | 347 | ||
335 | for (cnt = 0; cnt < handle_cnt; cnt++) | 348 | for (cnt = 0; cnt < handle_cnt; cnt++) |
336 | qla2x00_process_completed_request(ha, handles[cnt]); | 349 | qla2x00_process_completed_request(vha, rsp->req, |
350 | handles[cnt]); | ||
337 | break; | 351 | break; |
338 | 352 | ||
339 | case MBA_RESET: /* Reset */ | 353 | case MBA_RESET: /* Reset */ |
340 | DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no)); | 354 | DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", |
355 | vha->host_no)); | ||
341 | 356 | ||
342 | set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 357 | set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
343 | break; | 358 | break; |
344 | 359 | ||
345 | case MBA_SYSTEM_ERR: /* System Error */ | 360 | case MBA_SYSTEM_ERR: /* System Error */ |
@@ -347,70 +362,70 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
347 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", | 362 | "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n", |
348 | mb[1], mb[2], mb[3]); | 363 | mb[1], mb[2], mb[3]); |
349 | 364 | ||
350 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | 365 | qla2x00_post_hwe_work(vha, mb[0], mb[1], mb[2], mb[3]); |
351 | ha->isp_ops->fw_dump(ha, 1); | 366 | ha->isp_ops->fw_dump(vha, 1); |
352 | 367 | ||
353 | if (IS_FWI2_CAPABLE(ha)) { | 368 | if (IS_FWI2_CAPABLE(ha)) { |
354 | if (mb[1] == 0 && mb[2] == 0) { | 369 | if (mb[1] == 0 && mb[2] == 0) { |
355 | qla_printk(KERN_ERR, ha, | 370 | qla_printk(KERN_ERR, ha, |
356 | "Unrecoverable Hardware Error: adapter " | 371 | "Unrecoverable Hardware Error: adapter " |
357 | "marked OFFLINE!\n"); | 372 | "marked OFFLINE!\n"); |
358 | ha->flags.online = 0; | 373 | vha->flags.online = 0; |
359 | } else | 374 | } else |
360 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 375 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
361 | } else if (mb[1] == 0) { | 376 | } else if (mb[1] == 0) { |
362 | qla_printk(KERN_INFO, ha, | 377 | qla_printk(KERN_INFO, ha, |
363 | "Unrecoverable Hardware Error: adapter marked " | 378 | "Unrecoverable Hardware Error: adapter marked " |
364 | "OFFLINE!\n"); | 379 | "OFFLINE!\n"); |
365 | ha->flags.online = 0; | 380 | vha->flags.online = 0; |
366 | } else | 381 | } else |
367 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 382 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
368 | break; | 383 | break; |
369 | 384 | ||
370 | case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ | 385 | case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */ |
371 | DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n", | 386 | DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n", |
372 | ha->host_no)); | 387 | vha->host_no)); |
373 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); | 388 | qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n"); |
374 | 389 | ||
375 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | 390 | qla2x00_post_hwe_work(vha, mb[0], mb[1], mb[2], mb[3]); |
376 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 391 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
377 | break; | 392 | break; |
378 | 393 | ||
379 | case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ | 394 | case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */ |
380 | DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n", | 395 | DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n", |
381 | ha->host_no)); | 396 | vha->host_no)); |
382 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); | 397 | qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n"); |
383 | 398 | ||
384 | qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]); | 399 | qla2x00_post_hwe_work(vha, mb[0], mb[1], mb[2], mb[3]); |
385 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 400 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
386 | break; | 401 | break; |
387 | 402 | ||
388 | case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ | 403 | case MBA_WAKEUP_THRES: /* Request Queue Wake-up */ |
389 | DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n", | 404 | DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n", |
390 | ha->host_no)); | 405 | vha->host_no)); |
391 | break; | 406 | break; |
392 | 407 | ||
393 | case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ | 408 | case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ |
394 | DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", ha->host_no, | 409 | DEBUG2(printk("scsi(%ld): LIP occurred (%x).\n", vha->host_no, |
395 | mb[1])); | 410 | mb[1])); |
396 | qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]); | 411 | qla_printk(KERN_INFO, ha, "LIP occurred (%x).\n", mb[1]); |
397 | 412 | ||
398 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 413 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
399 | atomic_set(&ha->loop_state, LOOP_DOWN); | 414 | atomic_set(&vha->loop_state, LOOP_DOWN); |
400 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 415 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
401 | qla2x00_mark_all_devices_lost(ha, 1); | 416 | qla2x00_mark_all_devices_lost(vha, 1); |
402 | } | 417 | } |
403 | 418 | ||
404 | if (ha->parent) { | 419 | if (vha->vp_idx) { |
405 | atomic_set(&ha->vp_state, VP_FAILED); | 420 | atomic_set(&vha->vp_state, VP_FAILED); |
406 | fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED); | 421 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); |
407 | } | 422 | } |
408 | 423 | ||
409 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 424 | set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); |
410 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 425 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
411 | 426 | ||
412 | ha->flags.management_server_logged_in = 0; | 427 | vha->flags.management_server_logged_in = 0; |
413 | qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]); | 428 | qla2x00_post_aen_work(vha, FCH_EVT_LIP, mb[1]); |
414 | break; | 429 | break; |
415 | 430 | ||
416 | case MBA_LOOP_UP: /* Loop Up Event */ | 431 | case MBA_LOOP_UP: /* Loop Up Event */ |
@@ -425,59 +440,59 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
425 | } | 440 | } |
426 | 441 | ||
427 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n", | 442 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n", |
428 | ha->host_no, link_speed)); | 443 | vha->host_no, link_speed)); |
429 | qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n", | 444 | qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n", |
430 | link_speed); | 445 | link_speed); |
431 | 446 | ||
432 | ha->flags.management_server_logged_in = 0; | 447 | vha->flags.management_server_logged_in = 0; |
433 | qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate); | 448 | qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate); |
434 | break; | 449 | break; |
435 | 450 | ||
436 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 451 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
437 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " | 452 | DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN " |
438 | "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3])); | 453 | "(%x %x %x).\n", vha->host_no, mb[1], mb[2], mb[3])); |
439 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", | 454 | qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n", |
440 | mb[1], mb[2], mb[3]); | 455 | mb[1], mb[2], mb[3]); |
441 | 456 | ||
442 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 457 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
443 | atomic_set(&ha->loop_state, LOOP_DOWN); | 458 | atomic_set(&vha->loop_state, LOOP_DOWN); |
444 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 459 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
445 | ha->device_flags |= DFLG_NO_CABLE; | 460 | vha->device_flags |= DFLG_NO_CABLE; |
446 | qla2x00_mark_all_devices_lost(ha, 1); | 461 | qla2x00_mark_all_devices_lost(vha, 1); |
447 | } | 462 | } |
448 | 463 | ||
449 | if (ha->parent) { | 464 | if (vha->vp_idx) { |
450 | atomic_set(&ha->vp_state, VP_FAILED); | 465 | atomic_set(&vha->vp_state, VP_FAILED); |
451 | fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED); | 466 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); |
452 | } | 467 | } |
453 | 468 | ||
454 | ha->flags.management_server_logged_in = 0; | 469 | vha->flags.management_server_logged_in = 0; |
455 | ha->link_data_rate = PORT_SPEED_UNKNOWN; | 470 | ha->link_data_rate = PORT_SPEED_UNKNOWN; |
456 | qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0); | 471 | qla2x00_post_aen_work(vha, FCH_EVT_LINKDOWN, 0); |
457 | break; | 472 | break; |
458 | 473 | ||
459 | case MBA_LIP_RESET: /* LIP reset occurred */ | 474 | case MBA_LIP_RESET: /* LIP reset occurred */ |
460 | DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n", | 475 | DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n", |
461 | ha->host_no, mb[1])); | 476 | vha->host_no, mb[1])); |
462 | qla_printk(KERN_INFO, ha, | 477 | qla_printk(KERN_INFO, ha, |
463 | "LIP reset occurred (%x).\n", mb[1]); | 478 | "LIP reset occurred (%x).\n", mb[1]); |
464 | 479 | ||
465 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 480 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
466 | atomic_set(&ha->loop_state, LOOP_DOWN); | 481 | atomic_set(&vha->loop_state, LOOP_DOWN); |
467 | atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); | 482 | atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); |
468 | qla2x00_mark_all_devices_lost(ha, 1); | 483 | qla2x00_mark_all_devices_lost(vha, 1); |
469 | } | 484 | } |
470 | 485 | ||
471 | if (ha->parent) { | 486 | if (vha->vp_idx) { |
472 | atomic_set(&ha->vp_state, VP_FAILED); | 487 | atomic_set(&vha->vp_state, VP_FAILED); |
473 | fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED); | 488 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); |
474 | } | 489 | } |
475 | 490 | ||
476 | set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 491 | set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
477 | 492 | ||
478 | ha->operating_mode = LOOP; | 493 | ha->operating_mode = LOOP; |
479 | ha->flags.management_server_logged_in = 0; | 494 | vha->flags.management_server_logged_in = 0; |
480 | qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]); | 495 | qla2x00_post_aen_work(vha, FCH_EVT_LIPRESET, mb[1]); |
481 | break; | 496 | break; |
482 | 497 | ||
483 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 498 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
@@ -485,33 +500,33 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
485 | break; | 500 | break; |
486 | 501 | ||
487 | DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n", | 502 | DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n", |
488 | ha->host_no)); | 503 | vha->host_no)); |
489 | 504 | ||
490 | /* | 505 | /* |
491 | * Until there's a transition from loop down to loop up, treat | 506 | * Until there's a transition from loop down to loop up, treat |
492 | * this as loop down only. | 507 | * this as loop down only. |
493 | */ | 508 | */ |
494 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 509 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
495 | atomic_set(&ha->loop_state, LOOP_DOWN); | 510 | atomic_set(&vha->loop_state, LOOP_DOWN); |
496 | if (!atomic_read(&ha->loop_down_timer)) | 511 | if (!atomic_read(&vha->loop_down_timer)) |
497 | atomic_set(&ha->loop_down_timer, | 512 | atomic_set(&vha->loop_down_timer, |
498 | LOOP_DOWN_TIME); | 513 | LOOP_DOWN_TIME); |
499 | qla2x00_mark_all_devices_lost(ha, 1); | 514 | qla2x00_mark_all_devices_lost(vha, 1); |
500 | } | 515 | } |
501 | 516 | ||
502 | if (ha->parent) { | 517 | if (vha->vp_idx) { |
503 | atomic_set(&ha->vp_state, VP_FAILED); | 518 | atomic_set(&vha->vp_state, VP_FAILED); |
504 | fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED); | 519 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); |
505 | } | 520 | } |
506 | 521 | ||
507 | if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) { | 522 | if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))) |
508 | set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags); | 523 | set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
509 | } | 524 | |
510 | set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags); | 525 | set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); |
511 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 526 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
512 | 527 | ||
513 | ha->flags.gpsc_supported = 1; | 528 | ha->flags.gpsc_supported = 1; |
514 | ha->flags.management_server_logged_in = 0; | 529 | vha->flags.management_server_logged_in = 0; |
515 | break; | 530 | break; |
516 | 531 | ||
517 | case MBA_CHG_IN_CONNECTION: /* Change in connection mode */ | 532 | case MBA_CHG_IN_CONNECTION: /* Change in connection mode */ |
@@ -520,134 +535,137 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
520 | 535 | ||
521 | DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection " | 536 | DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection " |
522 | "received.\n", | 537 | "received.\n", |
523 | ha->host_no)); | 538 | vha->host_no)); |
524 | qla_printk(KERN_INFO, ha, | 539 | qla_printk(KERN_INFO, ha, |
525 | "Configuration change detected: value=%x.\n", mb[1]); | 540 | "Configuration change detected: value=%x.\n", mb[1]); |
526 | 541 | ||
527 | if (atomic_read(&ha->loop_state) != LOOP_DOWN) { | 542 | if (atomic_read(&vha->loop_state) != LOOP_DOWN) { |
528 | atomic_set(&ha->loop_state, LOOP_DOWN); | 543 | atomic_set(&vha->loop_state, LOOP_DOWN); |
529 | if (!atomic_read(&ha->loop_down_timer)) | 544 | if (!atomic_read(&vha->loop_down_timer)) |
530 | atomic_set(&ha->loop_down_timer, | 545 | atomic_set(&vha->loop_down_timer, |
531 | LOOP_DOWN_TIME); | 546 | LOOP_DOWN_TIME); |
532 | qla2x00_mark_all_devices_lost(ha, 1); | 547 | qla2x00_mark_all_devices_lost(vha, 1); |
533 | } | 548 | } |
534 | 549 | ||
535 | if (ha->parent) { | 550 | if (vha->vp_idx) { |
536 | atomic_set(&ha->vp_state, VP_FAILED); | 551 | atomic_set(&vha->vp_state, VP_FAILED); |
537 | fc_vport_set_state(ha->fc_vport, FC_VPORT_FAILED); | 552 | fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); |
538 | } | 553 | } |
539 | 554 | ||
540 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 555 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
541 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 556 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
542 | break; | 557 | break; |
543 | 558 | ||
544 | case MBA_PORT_UPDATE: /* Port database update */ | 559 | case MBA_PORT_UPDATE: /* Port database update */ |
560 | /* Only handle SCNs for our Vport index. */ | ||
561 | if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff)) | ||
562 | break; | ||
563 | |||
545 | /* | 564 | /* |
546 | * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET | 565 | * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET |
547 | * event etc. earlier indicating loop is down) then process | 566 | * event etc. earlier indicating loop is down) then process |
548 | * it. Otherwise ignore it and Wait for RSCN to come in. | 567 | * it. Otherwise ignore it and Wait for RSCN to come in. |
549 | */ | 568 | */ |
550 | atomic_set(&ha->loop_down_timer, 0); | 569 | atomic_set(&vha->loop_down_timer, 0); |
551 | if (atomic_read(&ha->loop_state) != LOOP_DOWN && | 570 | if (atomic_read(&vha->loop_state) != LOOP_DOWN && |
552 | atomic_read(&ha->loop_state) != LOOP_DEAD) { | 571 | atomic_read(&vha->loop_state) != LOOP_DEAD) { |
553 | DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE " | 572 | DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE " |
554 | "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1], | 573 | "ignored %04x/%04x/%04x.\n", vha->host_no, mb[1], |
555 | mb[2], mb[3])); | 574 | mb[2], mb[3])); |
556 | break; | 575 | break; |
557 | } | 576 | } |
558 | 577 | ||
559 | DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n", | 578 | DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n", |
560 | ha->host_no)); | 579 | vha->host_no)); |
561 | DEBUG(printk(KERN_INFO | 580 | DEBUG(printk(KERN_INFO |
562 | "scsi(%ld): Port database changed %04x %04x %04x.\n", | 581 | "scsi(%ld): Port database changed %04x %04x %04x.\n", |
563 | ha->host_no, mb[1], mb[2], mb[3])); | 582 | vha->host_no, mb[1], mb[2], mb[3])); |
564 | 583 | ||
565 | /* | 584 | /* |
566 | * Mark all devices as missing so we will login again. | 585 | * Mark all devices as missing so we will login again. |
567 | */ | 586 | */ |
568 | atomic_set(&ha->loop_state, LOOP_UP); | 587 | atomic_set(&vha->loop_state, LOOP_UP); |
569 | 588 | ||
570 | qla2x00_mark_all_devices_lost(ha, 1); | 589 | qla2x00_mark_all_devices_lost(vha, 1); |
571 | 590 | ||
572 | ha->flags.rscn_queue_overflow = 1; | 591 | vha->flags.rscn_queue_overflow = 1; |
573 | 592 | ||
574 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 593 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
575 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 594 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); |
576 | break; | 595 | break; |
577 | 596 | ||
578 | case MBA_RSCN_UPDATE: /* State Change Registration */ | 597 | case MBA_RSCN_UPDATE: /* State Change Registration */ |
579 | /* Check if the Vport has issued a SCR */ | 598 | /* Check if the Vport has issued a SCR */ |
580 | if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) | 599 | if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags)) |
581 | break; | 600 | break; |
582 | /* Only handle SCNs for our Vport index. */ | 601 | /* Only handle SCNs for our Vport index. */ |
583 | if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) | 602 | if (vha->vp_idx && vha->vp_idx != (mb[3] & 0xff)) |
584 | break; | 603 | break; |
585 | |||
586 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", | 604 | DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", |
587 | ha->host_no)); | 605 | vha->host_no)); |
588 | DEBUG(printk(KERN_INFO | 606 | DEBUG(printk(KERN_INFO |
589 | "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n", | 607 | "scsi(%ld): RSCN database changed -- %04x %04x %04x.\n", |
590 | ha->host_no, mb[1], mb[2], mb[3])); | 608 | vha->host_no, mb[1], mb[2], mb[3])); |
591 | 609 | ||
592 | rscn_entry = ((mb[1] & 0xff) << 16) | mb[2]; | 610 | rscn_entry = ((mb[1] & 0xff) << 16) | mb[2]; |
593 | host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) | | 611 | host_pid = (vha->d_id.b.domain << 16) | (vha->d_id.b.area << 8) |
594 | ha->d_id.b.al_pa; | 612 | | vha->d_id.b.al_pa; |
595 | if (rscn_entry == host_pid) { | 613 | if (rscn_entry == host_pid) { |
596 | DEBUG(printk(KERN_INFO | 614 | DEBUG(printk(KERN_INFO |
597 | "scsi(%ld): Ignoring RSCN update to local host " | 615 | "scsi(%ld): Ignoring RSCN update to local host " |
598 | "port ID (%06x)\n", | 616 | "port ID (%06x)\n", |
599 | ha->host_no, host_pid)); | 617 | vha->host_no, host_pid)); |
600 | break; | 618 | break; |
601 | } | 619 | } |
602 | 620 | ||
603 | /* Ignore reserved bits from RSCN-payload. */ | 621 | /* Ignore reserved bits from RSCN-payload. */ |
604 | rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2]; | 622 | rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2]; |
605 | rscn_queue_index = ha->rscn_in_ptr + 1; | 623 | rscn_queue_index = vha->rscn_in_ptr + 1; |
606 | if (rscn_queue_index == MAX_RSCN_COUNT) | 624 | if (rscn_queue_index == MAX_RSCN_COUNT) |
607 | rscn_queue_index = 0; | 625 | rscn_queue_index = 0; |
608 | if (rscn_queue_index != ha->rscn_out_ptr) { | 626 | if (rscn_queue_index != vha->rscn_out_ptr) { |
609 | ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry; | 627 | vha->rscn_queue[vha->rscn_in_ptr] = rscn_entry; |
610 | ha->rscn_in_ptr = rscn_queue_index; | 628 | vha->rscn_in_ptr = rscn_queue_index; |
611 | } else { | 629 | } else { |
612 | ha->flags.rscn_queue_overflow = 1; | 630 | vha->flags.rscn_queue_overflow = 1; |
613 | } | 631 | } |
614 | 632 | ||
615 | atomic_set(&ha->loop_state, LOOP_UPDATE); | 633 | atomic_set(&vha->loop_state, LOOP_UPDATE); |
616 | atomic_set(&ha->loop_down_timer, 0); | 634 | atomic_set(&vha->loop_down_timer, 0); |
617 | ha->flags.management_server_logged_in = 0; | 635 | vha->flags.management_server_logged_in = 0; |
618 | 636 | ||
619 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 637 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
620 | set_bit(RSCN_UPDATE, &ha->dpc_flags); | 638 | set_bit(RSCN_UPDATE, &vha->dpc_flags); |
621 | qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry); | 639 | qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry); |
622 | break; | 640 | break; |
623 | 641 | ||
624 | /* case MBA_RIO_RESPONSE: */ | 642 | /* case MBA_RIO_RESPONSE: */ |
625 | case MBA_ZIO_RESPONSE: | 643 | case MBA_ZIO_RESPONSE: |
626 | DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n", | 644 | DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n", |
627 | ha->host_no)); | 645 | vha->host_no)); |
628 | DEBUG(printk(KERN_INFO | 646 | DEBUG(printk(KERN_INFO |
629 | "scsi(%ld): [R|Z]IO update completion.\n", | 647 | "scsi(%ld): [R|Z]IO update completion.\n", |
630 | ha->host_no)); | 648 | vha->host_no)); |
631 | 649 | ||
632 | if (IS_FWI2_CAPABLE(ha)) | 650 | if (IS_FWI2_CAPABLE(ha)) |
633 | qla24xx_process_response_queue(ha); | 651 | qla24xx_process_response_queue(rsp); |
634 | else | 652 | else |
635 | qla2x00_process_response_queue(ha); | 653 | qla2x00_process_response_queue(rsp); |
636 | break; | 654 | break; |
637 | 655 | ||
638 | case MBA_DISCARD_RND_FRAME: | 656 | case MBA_DISCARD_RND_FRAME: |
639 | DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x " | 657 | DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x " |
640 | "%04x.\n", ha->host_no, mb[1], mb[2], mb[3])); | 658 | "%04x.\n", vha->host_no, mb[1], mb[2], mb[3])); |
641 | break; | 659 | break; |
642 | 660 | ||
643 | case MBA_TRACE_NOTIFICATION: | 661 | case MBA_TRACE_NOTIFICATION: |
644 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", | 662 | DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n", |
645 | ha->host_no, mb[1], mb[2])); | 663 | vha->host_no, mb[1], mb[2])); |
646 | break; | 664 | break; |
647 | 665 | ||
648 | case MBA_ISP84XX_ALERT: | 666 | case MBA_ISP84XX_ALERT: |
649 | DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " | 667 | DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- " |
650 | "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3])); | 668 | "%04x %04x %04x\n", vha->host_no, mb[1], mb[2], mb[3])); |
651 | 669 | ||
652 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); | 670 | spin_lock_irqsave(&ha->cs84xx->access_lock, flags); |
653 | switch (mb[1]) { | 671 | switch (mb[1]) { |
@@ -682,16 +700,22 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) | |||
682 | break; | 700 | break; |
683 | } | 701 | } |
684 | 702 | ||
685 | if (!ha->parent && ha->num_vhosts) | 703 | if (!vha->vp_idx && ha->num_vhosts) |
686 | qla2x00_alert_all_vps(ha, mb); | 704 | qla2x00_alert_all_vps(rsp, mb); |
687 | } | 705 | } |
688 | 706 | ||
689 | static void | 707 | static void |
690 | qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) | 708 | qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) |
691 | { | 709 | { |
692 | fc_port_t *fcport = data; | 710 | fc_port_t *fcport = data; |
711 | struct scsi_qla_host *vha = fcport->vha; | ||
712 | struct qla_hw_data *ha = vha->hw; | ||
713 | struct req_que *req = NULL; | ||
693 | 714 | ||
694 | if (fcport->ha->max_q_depth <= sdev->queue_depth) | 715 | req = ha->req_q_map[vha->req_ques[0]]; |
716 | if (!req) | ||
717 | return; | ||
718 | if (req->max_q_depth <= sdev->queue_depth) | ||
695 | return; | 719 | return; |
696 | 720 | ||
697 | if (sdev->ordered_tags) | 721 | if (sdev->ordered_tags) |
@@ -703,9 +727,9 @@ qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data) | |||
703 | 727 | ||
704 | fcport->last_ramp_up = jiffies; | 728 | fcport->last_ramp_up = jiffies; |
705 | 729 | ||
706 | DEBUG2(qla_printk(KERN_INFO, fcport->ha, | 730 | DEBUG2(qla_printk(KERN_INFO, ha, |
707 | "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", | 731 | "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n", |
708 | fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, | 732 | fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, |
709 | sdev->queue_depth)); | 733 | sdev->queue_depth)); |
710 | } | 734 | } |
711 | 735 | ||
@@ -717,20 +741,21 @@ qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data) | |||
717 | if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) | 741 | if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1)) |
718 | return; | 742 | return; |
719 | 743 | ||
720 | DEBUG2(qla_printk(KERN_INFO, fcport->ha, | 744 | DEBUG2(qla_printk(KERN_INFO, fcport->vha->hw, |
721 | "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", | 745 | "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n", |
722 | fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun, | 746 | fcport->vha->host_no, sdev->channel, sdev->id, sdev->lun, |
723 | sdev->queue_depth)); | 747 | sdev->queue_depth)); |
724 | } | 748 | } |
725 | 749 | ||
726 | static inline void | 750 | static inline void |
727 | qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) | 751 | qla2x00_ramp_up_queue_depth(scsi_qla_host_t *vha, struct req_que *req, |
752 | srb_t *sp) | ||
728 | { | 753 | { |
729 | fc_port_t *fcport; | 754 | fc_port_t *fcport; |
730 | struct scsi_device *sdev; | 755 | struct scsi_device *sdev; |
731 | 756 | ||
732 | sdev = sp->cmd->device; | 757 | sdev = sp->cmd->device; |
733 | if (sdev->queue_depth >= ha->max_q_depth) | 758 | if (sdev->queue_depth >= req->max_q_depth) |
734 | return; | 759 | return; |
735 | 760 | ||
736 | fcport = sp->fcport; | 761 | fcport = sp->fcport; |
@@ -751,25 +776,27 @@ qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp) | |||
751 | * @index: SRB index | 776 | * @index: SRB index |
752 | */ | 777 | */ |
753 | static void | 778 | static void |
754 | qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index) | 779 | qla2x00_process_completed_request(struct scsi_qla_host *vha, |
780 | struct req_que *req, uint32_t index) | ||
755 | { | 781 | { |
756 | srb_t *sp; | 782 | srb_t *sp; |
783 | struct qla_hw_data *ha = vha->hw; | ||
757 | 784 | ||
758 | /* Validate handle. */ | 785 | /* Validate handle. */ |
759 | if (index >= MAX_OUTSTANDING_COMMANDS) { | 786 | if (index >= MAX_OUTSTANDING_COMMANDS) { |
760 | DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n", | 787 | DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n", |
761 | ha->host_no, index)); | 788 | vha->host_no, index)); |
762 | qla_printk(KERN_WARNING, ha, | 789 | qla_printk(KERN_WARNING, ha, |
763 | "Invalid SCSI completion handle %d.\n", index); | 790 | "Invalid SCSI completion handle %d.\n", index); |
764 | 791 | ||
765 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 792 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
766 | return; | 793 | return; |
767 | } | 794 | } |
768 | 795 | ||
769 | sp = ha->outstanding_cmds[index]; | 796 | sp = req->outstanding_cmds[index]; |
770 | if (sp) { | 797 | if (sp) { |
771 | /* Free outstanding command slot. */ | 798 | /* Free outstanding command slot. */ |
772 | ha->outstanding_cmds[index] = NULL; | 799 | req->outstanding_cmds[index] = NULL; |
773 | 800 | ||
774 | CMD_COMPL_STATUS(sp->cmd) = 0L; | 801 | CMD_COMPL_STATUS(sp->cmd) = 0L; |
775 | CMD_SCSI_STATUS(sp->cmd) = 0L; | 802 | CMD_SCSI_STATUS(sp->cmd) = 0L; |
@@ -777,15 +804,15 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index) | |||
777 | /* Save ISP completion status */ | 804 | /* Save ISP completion status */ |
778 | sp->cmd->result = DID_OK << 16; | 805 | sp->cmd->result = DID_OK << 16; |
779 | 806 | ||
780 | qla2x00_ramp_up_queue_depth(ha, sp); | 807 | qla2x00_ramp_up_queue_depth(vha, req, sp); |
781 | qla2x00_sp_compl(ha, sp); | 808 | qla2x00_sp_compl(ha, sp); |
782 | } else { | 809 | } else { |
783 | DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", | 810 | DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n", |
784 | ha->host_no)); | 811 | vha->host_no)); |
785 | qla_printk(KERN_WARNING, ha, | 812 | qla_printk(KERN_WARNING, ha, |
786 | "Invalid ISP SCSI completion handle\n"); | 813 | "Invalid ISP SCSI completion handle\n"); |
787 | 814 | ||
788 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 815 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
789 | } | 816 | } |
790 | } | 817 | } |
791 | 818 | ||
@@ -794,32 +821,36 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index) | |||
794 | * @ha: SCSI driver HA context | 821 | * @ha: SCSI driver HA context |
795 | */ | 822 | */ |
796 | void | 823 | void |
797 | qla2x00_process_response_queue(struct scsi_qla_host *ha) | 824 | qla2x00_process_response_queue(struct rsp_que *rsp) |
798 | { | 825 | { |
826 | struct scsi_qla_host *vha; | ||
827 | struct qla_hw_data *ha = rsp->hw; | ||
799 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | 828 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; |
800 | sts_entry_t *pkt; | 829 | sts_entry_t *pkt; |
801 | uint16_t handle_cnt; | 830 | uint16_t handle_cnt; |
802 | uint16_t cnt; | 831 | uint16_t cnt; |
803 | 832 | ||
804 | if (!ha->flags.online) | 833 | vha = qla2x00_get_rsp_host(rsp); |
834 | |||
835 | if (!vha->flags.online) | ||
805 | return; | 836 | return; |
806 | 837 | ||
807 | while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { | 838 | while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { |
808 | pkt = (sts_entry_t *)ha->response_ring_ptr; | 839 | pkt = (sts_entry_t *)rsp->ring_ptr; |
809 | 840 | ||
810 | ha->rsp_ring_index++; | 841 | rsp->ring_index++; |
811 | if (ha->rsp_ring_index == ha->response_q_length) { | 842 | if (rsp->ring_index == rsp->length) { |
812 | ha->rsp_ring_index = 0; | 843 | rsp->ring_index = 0; |
813 | ha->response_ring_ptr = ha->response_ring; | 844 | rsp->ring_ptr = rsp->ring; |
814 | } else { | 845 | } else { |
815 | ha->response_ring_ptr++; | 846 | rsp->ring_ptr++; |
816 | } | 847 | } |
817 | 848 | ||
818 | if (pkt->entry_status != 0) { | 849 | if (pkt->entry_status != 0) { |
819 | DEBUG3(printk(KERN_INFO | 850 | DEBUG3(printk(KERN_INFO |
820 | "scsi(%ld): Process error entry.\n", ha->host_no)); | 851 | "scsi(%ld): Process error entry.\n", vha->host_no)); |
821 | 852 | ||
822 | qla2x00_error_entry(ha, pkt); | 853 | qla2x00_error_entry(vha, rsp, pkt); |
823 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; | 854 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
824 | wmb(); | 855 | wmb(); |
825 | continue; | 856 | continue; |
@@ -827,31 +858,31 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
827 | 858 | ||
828 | switch (pkt->entry_type) { | 859 | switch (pkt->entry_type) { |
829 | case STATUS_TYPE: | 860 | case STATUS_TYPE: |
830 | qla2x00_status_entry(ha, pkt); | 861 | qla2x00_status_entry(vha, rsp, pkt); |
831 | break; | 862 | break; |
832 | case STATUS_TYPE_21: | 863 | case STATUS_TYPE_21: |
833 | handle_cnt = ((sts21_entry_t *)pkt)->handle_count; | 864 | handle_cnt = ((sts21_entry_t *)pkt)->handle_count; |
834 | for (cnt = 0; cnt < handle_cnt; cnt++) { | 865 | for (cnt = 0; cnt < handle_cnt; cnt++) { |
835 | qla2x00_process_completed_request(ha, | 866 | qla2x00_process_completed_request(vha, rsp->req, |
836 | ((sts21_entry_t *)pkt)->handle[cnt]); | 867 | ((sts21_entry_t *)pkt)->handle[cnt]); |
837 | } | 868 | } |
838 | break; | 869 | break; |
839 | case STATUS_TYPE_22: | 870 | case STATUS_TYPE_22: |
840 | handle_cnt = ((sts22_entry_t *)pkt)->handle_count; | 871 | handle_cnt = ((sts22_entry_t *)pkt)->handle_count; |
841 | for (cnt = 0; cnt < handle_cnt; cnt++) { | 872 | for (cnt = 0; cnt < handle_cnt; cnt++) { |
842 | qla2x00_process_completed_request(ha, | 873 | qla2x00_process_completed_request(vha, rsp->req, |
843 | ((sts22_entry_t *)pkt)->handle[cnt]); | 874 | ((sts22_entry_t *)pkt)->handle[cnt]); |
844 | } | 875 | } |
845 | break; | 876 | break; |
846 | case STATUS_CONT_TYPE: | 877 | case STATUS_CONT_TYPE: |
847 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 878 | qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt); |
848 | break; | 879 | break; |
849 | default: | 880 | default: |
850 | /* Type Not Supported. */ | 881 | /* Type Not Supported. */ |
851 | DEBUG4(printk(KERN_WARNING | 882 | DEBUG4(printk(KERN_WARNING |
852 | "scsi(%ld): Received unknown response pkt type %x " | 883 | "scsi(%ld): Received unknown response pkt type %x " |
853 | "entry status=%x.\n", | 884 | "entry status=%x.\n", |
854 | ha->host_no, pkt->entry_type, pkt->entry_status)); | 885 | vha->host_no, pkt->entry_type, pkt->entry_status)); |
855 | break; | 886 | break; |
856 | } | 887 | } |
857 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; | 888 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
@@ -859,7 +890,7 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha) | |||
859 | } | 890 | } |
860 | 891 | ||
861 | /* Adjust ring index */ | 892 | /* Adjust ring index */ |
862 | WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index); | 893 | WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), rsp->ring_index); |
863 | } | 894 | } |
864 | 895 | ||
865 | static inline void | 896 | static inline void |
@@ -881,10 +912,10 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len) | |||
881 | sp->request_sense_ptr += sense_len; | 912 | sp->request_sense_ptr += sense_len; |
882 | sp->request_sense_length -= sense_len; | 913 | sp->request_sense_length -= sense_len; |
883 | if (sp->request_sense_length != 0) | 914 | if (sp->request_sense_length != 0) |
884 | sp->fcport->ha->status_srb = sp; | 915 | sp->fcport->vha->status_srb = sp; |
885 | 916 | ||
886 | DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) " | 917 | DEBUG5(printk("%s(): Check condition Sense data, scsi(%ld:%d:%d:%d) " |
887 | "cmd=%p pid=%ld\n", __func__, sp->fcport->ha->host_no, | 918 | "cmd=%p pid=%ld\n", __func__, sp->fcport->vha->host_no, |
888 | cp->device->channel, cp->device->id, cp->device->lun, cp, | 919 | cp->device->channel, cp->device->id, cp->device->lun, cp, |
889 | cp->serial_number)); | 920 | cp->serial_number)); |
890 | if (sense_len) | 921 | if (sense_len) |
@@ -898,7 +929,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len) | |||
898 | * @pkt: Entry pointer | 929 | * @pkt: Entry pointer |
899 | */ | 930 | */ |
900 | static void | 931 | static void |
901 | qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | 932 | qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) |
902 | { | 933 | { |
903 | srb_t *sp; | 934 | srb_t *sp; |
904 | fc_port_t *fcport; | 935 | fc_port_t *fcport; |
@@ -911,6 +942,8 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
911 | int32_t resid; | 942 | int32_t resid; |
912 | uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len; | 943 | uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len; |
913 | uint8_t *rsp_info, *sense_data; | 944 | uint8_t *rsp_info, *sense_data; |
945 | struct qla_hw_data *ha = vha->hw; | ||
946 | struct req_que *req = rsp->req; | ||
914 | 947 | ||
915 | sts = (sts_entry_t *) pkt; | 948 | sts = (sts_entry_t *) pkt; |
916 | sts24 = (struct sts_entry_24xx *) pkt; | 949 | sts24 = (struct sts_entry_24xx *) pkt; |
@@ -924,31 +957,31 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
924 | 957 | ||
925 | /* Fast path completion. */ | 958 | /* Fast path completion. */ |
926 | if (comp_status == CS_COMPLETE && scsi_status == 0) { | 959 | if (comp_status == CS_COMPLETE && scsi_status == 0) { |
927 | qla2x00_process_completed_request(ha, sts->handle); | 960 | qla2x00_process_completed_request(vha, req, sts->handle); |
928 | 961 | ||
929 | return; | 962 | return; |
930 | } | 963 | } |
931 | 964 | ||
932 | /* Validate handle. */ | 965 | /* Validate handle. */ |
933 | if (sts->handle < MAX_OUTSTANDING_COMMANDS) { | 966 | if (sts->handle < MAX_OUTSTANDING_COMMANDS) { |
934 | sp = ha->outstanding_cmds[sts->handle]; | 967 | sp = req->outstanding_cmds[sts->handle]; |
935 | ha->outstanding_cmds[sts->handle] = NULL; | 968 | req->outstanding_cmds[sts->handle] = NULL; |
936 | } else | 969 | } else |
937 | sp = NULL; | 970 | sp = NULL; |
938 | 971 | ||
939 | if (sp == NULL) { | 972 | if (sp == NULL) { |
940 | DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n", | 973 | DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n", |
941 | ha->host_no)); | 974 | vha->host_no)); |
942 | qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n"); | 975 | qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n"); |
943 | 976 | ||
944 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 977 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
945 | qla2xxx_wake_dpc(ha); | 978 | qla2xxx_wake_dpc(vha); |
946 | return; | 979 | return; |
947 | } | 980 | } |
948 | cp = sp->cmd; | 981 | cp = sp->cmd; |
949 | if (cp == NULL) { | 982 | if (cp == NULL) { |
950 | DEBUG2(printk("scsi(%ld): Command already returned back to OS " | 983 | DEBUG2(printk("scsi(%ld): Command already returned back to OS " |
951 | "pkt->handle=%d sp=%p.\n", ha->host_no, sts->handle, sp)); | 984 | "pkt->handle=%d sp=%p.\n", vha->host_no, sts->handle, sp)); |
952 | qla_printk(KERN_WARNING, ha, | 985 | qla_printk(KERN_WARNING, ha, |
953 | "Command is NULL: already returned to OS (sp=%p)\n", sp); | 986 | "Command is NULL: already returned to OS (sp=%p)\n", sp); |
954 | 987 | ||
@@ -987,7 +1020,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
987 | if (rsp_info_len > 3 && rsp_info[3]) { | 1020 | if (rsp_info_len > 3 && rsp_info[3]) { |
988 | DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " | 1021 | DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol " |
989 | "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..." | 1022 | "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..." |
990 | "retrying command\n", ha->host_no, | 1023 | "retrying command\n", vha->host_no, |
991 | cp->device->channel, cp->device->id, | 1024 | cp->device->channel, cp->device->id, |
992 | cp->device->lun, rsp_info_len, rsp_info[0], | 1025 | cp->device->lun, rsp_info_len, rsp_info[0], |
993 | rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4], | 1026 | rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4], |
@@ -1025,7 +1058,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1025 | qla_printk(KERN_INFO, ha, | 1058 | qla_printk(KERN_INFO, ha, |
1026 | "scsi(%ld:%d:%d:%d): Mid-layer underflow " | 1059 | "scsi(%ld:%d:%d:%d): Mid-layer underflow " |
1027 | "detected (%x of %x bytes)...returning " | 1060 | "detected (%x of %x bytes)...returning " |
1028 | "error status.\n", ha->host_no, | 1061 | "error status.\n", vha->host_no, |
1029 | cp->device->channel, cp->device->id, | 1062 | cp->device->channel, cp->device->id, |
1030 | cp->device->lun, resid, | 1063 | cp->device->lun, resid, |
1031 | scsi_bufflen(cp)); | 1064 | scsi_bufflen(cp)); |
@@ -1039,7 +1072,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1039 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { | 1072 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { |
1040 | DEBUG2(printk(KERN_INFO | 1073 | DEBUG2(printk(KERN_INFO |
1041 | "scsi(%ld): QUEUE FULL status detected " | 1074 | "scsi(%ld): QUEUE FULL status detected " |
1042 | "0x%x-0x%x.\n", ha->host_no, comp_status, | 1075 | "0x%x-0x%x.\n", vha->host_no, comp_status, |
1043 | scsi_status)); | 1076 | scsi_status)); |
1044 | 1077 | ||
1045 | /* Adjust queue depth for all luns on the port. */ | 1078 | /* Adjust queue depth for all luns on the port. */ |
@@ -1078,7 +1111,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1078 | DEBUG2(printk(KERN_INFO | 1111 | DEBUG2(printk(KERN_INFO |
1079 | "scsi(%ld:%d:%d) UNDERRUN status detected " | 1112 | "scsi(%ld:%d:%d) UNDERRUN status detected " |
1080 | "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x " | 1113 | "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x " |
1081 | "os_underflow=0x%x\n", ha->host_no, | 1114 | "os_underflow=0x%x\n", vha->host_no, |
1082 | cp->device->id, cp->device->lun, comp_status, | 1115 | cp->device->id, cp->device->lun, comp_status, |
1083 | scsi_status, resid_len, resid, cp->cmnd[0], | 1116 | scsi_status, resid_len, resid, cp->cmnd[0], |
1084 | cp->underflow)); | 1117 | cp->underflow)); |
@@ -1095,7 +1128,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1095 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { | 1128 | if (lscsi_status == SAM_STAT_TASK_SET_FULL) { |
1096 | DEBUG2(printk(KERN_INFO | 1129 | DEBUG2(printk(KERN_INFO |
1097 | "scsi(%ld): QUEUE FULL status detected " | 1130 | "scsi(%ld): QUEUE FULL status detected " |
1098 | "0x%x-0x%x.\n", ha->host_no, comp_status, | 1131 | "0x%x-0x%x.\n", vha->host_no, comp_status, |
1099 | scsi_status)); | 1132 | scsi_status)); |
1100 | 1133 | ||
1101 | /* | 1134 | /* |
@@ -1125,10 +1158,10 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1125 | if (!(scsi_status & SS_RESIDUAL_UNDER)) { | 1158 | if (!(scsi_status & SS_RESIDUAL_UNDER)) { |
1126 | DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped " | 1159 | DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped " |
1127 | "frame(s) detected (%x of %x bytes)..." | 1160 | "frame(s) detected (%x of %x bytes)..." |
1128 | "retrying command.\n", ha->host_no, | 1161 | "retrying command.\n", |
1129 | cp->device->channel, cp->device->id, | 1162 | vha->host_no, cp->device->channel, |
1130 | cp->device->lun, resid, | 1163 | cp->device->id, cp->device->lun, resid, |
1131 | scsi_bufflen(cp))); | 1164 | scsi_bufflen(cp))); |
1132 | 1165 | ||
1133 | cp->result = DID_BUS_BUSY << 16; | 1166 | cp->result = DID_BUS_BUSY << 16; |
1134 | break; | 1167 | break; |
@@ -1140,7 +1173,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1140 | qla_printk(KERN_INFO, ha, | 1173 | qla_printk(KERN_INFO, ha, |
1141 | "scsi(%ld:%d:%d:%d): Mid-layer underflow " | 1174 | "scsi(%ld:%d:%d:%d): Mid-layer underflow " |
1142 | "detected (%x of %x bytes)...returning " | 1175 | "detected (%x of %x bytes)...returning " |
1143 | "error status.\n", ha->host_no, | 1176 | "error status.\n", vha->host_no, |
1144 | cp->device->channel, cp->device->id, | 1177 | cp->device->channel, cp->device->id, |
1145 | cp->device->lun, resid, | 1178 | cp->device->lun, resid, |
1146 | scsi_bufflen(cp)); | 1179 | scsi_bufflen(cp)); |
@@ -1157,7 +1190,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1157 | case CS_DATA_OVERRUN: | 1190 | case CS_DATA_OVERRUN: |
1158 | DEBUG2(printk(KERN_INFO | 1191 | DEBUG2(printk(KERN_INFO |
1159 | "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n", | 1192 | "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n", |
1160 | ha->host_no, cp->device->id, cp->device->lun, comp_status, | 1193 | vha->host_no, cp->device->id, cp->device->lun, comp_status, |
1161 | scsi_status)); | 1194 | scsi_status)); |
1162 | DEBUG2(printk(KERN_INFO | 1195 | DEBUG2(printk(KERN_INFO |
1163 | "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", | 1196 | "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", |
@@ -1183,7 +1216,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1183 | */ | 1216 | */ |
1184 | DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down " | 1217 | DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down " |
1185 | "pid=%ld, compl status=0x%x, port state=0x%x\n", | 1218 | "pid=%ld, compl status=0x%x, port state=0x%x\n", |
1186 | ha->host_no, cp->device->id, cp->device->lun, | 1219 | vha->host_no, cp->device->id, cp->device->lun, |
1187 | cp->serial_number, comp_status, | 1220 | cp->serial_number, comp_status, |
1188 | atomic_read(&fcport->state))); | 1221 | atomic_read(&fcport->state))); |
1189 | 1222 | ||
@@ -1194,13 +1227,13 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1194 | */ | 1227 | */ |
1195 | cp->result = DID_TRANSPORT_DISRUPTED << 16; | 1228 | cp->result = DID_TRANSPORT_DISRUPTED << 16; |
1196 | if (atomic_read(&fcport->state) == FCS_ONLINE) | 1229 | if (atomic_read(&fcport->state) == FCS_ONLINE) |
1197 | qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1); | 1230 | qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); |
1198 | break; | 1231 | break; |
1199 | 1232 | ||
1200 | case CS_RESET: | 1233 | case CS_RESET: |
1201 | DEBUG2(printk(KERN_INFO | 1234 | DEBUG2(printk(KERN_INFO |
1202 | "scsi(%ld): RESET status detected 0x%x-0x%x.\n", | 1235 | "scsi(%ld): RESET status detected 0x%x-0x%x.\n", |
1203 | ha->host_no, comp_status, scsi_status)); | 1236 | vha->host_no, comp_status, scsi_status)); |
1204 | 1237 | ||
1205 | cp->result = DID_RESET << 16; | 1238 | cp->result = DID_RESET << 16; |
1206 | break; | 1239 | break; |
@@ -1213,7 +1246,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1213 | */ | 1246 | */ |
1214 | DEBUG2(printk(KERN_INFO | 1247 | DEBUG2(printk(KERN_INFO |
1215 | "scsi(%ld): ABORT status detected 0x%x-0x%x.\n", | 1248 | "scsi(%ld): ABORT status detected 0x%x-0x%x.\n", |
1216 | ha->host_no, comp_status, scsi_status)); | 1249 | vha->host_no, comp_status, scsi_status)); |
1217 | 1250 | ||
1218 | cp->result = DID_RESET << 16; | 1251 | cp->result = DID_RESET << 16; |
1219 | break; | 1252 | break; |
@@ -1229,25 +1262,25 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1229 | if (IS_FWI2_CAPABLE(ha)) { | 1262 | if (IS_FWI2_CAPABLE(ha)) { |
1230 | DEBUG2(printk(KERN_INFO | 1263 | DEBUG2(printk(KERN_INFO |
1231 | "scsi(%ld:%d:%d:%d): TIMEOUT status detected " | 1264 | "scsi(%ld:%d:%d:%d): TIMEOUT status detected " |
1232 | "0x%x-0x%x\n", ha->host_no, cp->device->channel, | 1265 | "0x%x-0x%x\n", vha->host_no, cp->device->channel, |
1233 | cp->device->id, cp->device->lun, comp_status, | 1266 | cp->device->id, cp->device->lun, comp_status, |
1234 | scsi_status)); | 1267 | scsi_status)); |
1235 | break; | 1268 | break; |
1236 | } | 1269 | } |
1237 | DEBUG2(printk(KERN_INFO | 1270 | DEBUG2(printk(KERN_INFO |
1238 | "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x " | 1271 | "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x " |
1239 | "sflags=%x.\n", ha->host_no, cp->device->channel, | 1272 | "sflags=%x.\n", vha->host_no, cp->device->channel, |
1240 | cp->device->id, cp->device->lun, comp_status, scsi_status, | 1273 | cp->device->id, cp->device->lun, comp_status, scsi_status, |
1241 | le16_to_cpu(sts->status_flags))); | 1274 | le16_to_cpu(sts->status_flags))); |
1242 | 1275 | ||
1243 | /* Check to see if logout occurred. */ | 1276 | /* Check to see if logout occurred. */ |
1244 | if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT)) | 1277 | if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT)) |
1245 | qla2x00_mark_device_lost(fcport->ha, fcport, 1, 1); | 1278 | qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); |
1246 | break; | 1279 | break; |
1247 | 1280 | ||
1248 | default: | 1281 | default: |
1249 | DEBUG3(printk("scsi(%ld): Error detected (unknown status) " | 1282 | DEBUG3(printk("scsi(%ld): Error detected (unknown status) " |
1250 | "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status)); | 1283 | "0x%x-0x%x.\n", vha->host_no, comp_status, scsi_status)); |
1251 | qla_printk(KERN_INFO, ha, | 1284 | qla_printk(KERN_INFO, ha, |
1252 | "Unknown status detected 0x%x-0x%x.\n", | 1285 | "Unknown status detected 0x%x-0x%x.\n", |
1253 | comp_status, scsi_status); | 1286 | comp_status, scsi_status); |
@@ -1257,7 +1290,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1257 | } | 1290 | } |
1258 | 1291 | ||
1259 | /* Place command on done queue. */ | 1292 | /* Place command on done queue. */ |
1260 | if (ha->status_srb == NULL) | 1293 | if (vha->status_srb == NULL) |
1261 | qla2x00_sp_compl(ha, sp); | 1294 | qla2x00_sp_compl(ha, sp); |
1262 | } | 1295 | } |
1263 | 1296 | ||
@@ -1269,10 +1302,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) | |||
1269 | * Extended sense data. | 1302 | * Extended sense data. |
1270 | */ | 1303 | */ |
1271 | static void | 1304 | static void |
1272 | qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) | 1305 | qla2x00_status_cont_entry(scsi_qla_host_t *vha, sts_cont_entry_t *pkt) |
1273 | { | 1306 | { |
1274 | uint8_t sense_sz = 0; | 1307 | uint8_t sense_sz = 0; |
1275 | srb_t *sp = ha->status_srb; | 1308 | struct qla_hw_data *ha = vha->hw; |
1309 | srb_t *sp = vha->status_srb; | ||
1276 | struct scsi_cmnd *cp; | 1310 | struct scsi_cmnd *cp; |
1277 | 1311 | ||
1278 | if (sp != NULL && sp->request_sense_length != 0) { | 1312 | if (sp != NULL && sp->request_sense_length != 0) { |
@@ -1284,7 +1318,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) | |||
1284 | "cmd is NULL: already returned to OS (sp=%p)\n", | 1318 | "cmd is NULL: already returned to OS (sp=%p)\n", |
1285 | sp); | 1319 | sp); |
1286 | 1320 | ||
1287 | ha->status_srb = NULL; | 1321 | vha->status_srb = NULL; |
1288 | return; | 1322 | return; |
1289 | } | 1323 | } |
1290 | 1324 | ||
@@ -1305,7 +1339,7 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) | |||
1305 | 1339 | ||
1306 | /* Place command on done queue. */ | 1340 | /* Place command on done queue. */ |
1307 | if (sp->request_sense_length == 0) { | 1341 | if (sp->request_sense_length == 0) { |
1308 | ha->status_srb = NULL; | 1342 | vha->status_srb = NULL; |
1309 | qla2x00_sp_compl(ha, sp); | 1343 | qla2x00_sp_compl(ha, sp); |
1310 | } | 1344 | } |
1311 | } | 1345 | } |
@@ -1317,10 +1351,11 @@ qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt) | |||
1317 | * @pkt: Entry pointer | 1351 | * @pkt: Entry pointer |
1318 | */ | 1352 | */ |
1319 | static void | 1353 | static void |
1320 | qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | 1354 | qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) |
1321 | { | 1355 | { |
1322 | srb_t *sp; | 1356 | srb_t *sp; |
1323 | 1357 | struct qla_hw_data *ha = vha->hw; | |
1358 | struct req_que *req = rsp->req; | ||
1324 | #if defined(QL_DEBUG_LEVEL_2) | 1359 | #if defined(QL_DEBUG_LEVEL_2) |
1325 | if (pkt->entry_status & RF_INV_E_ORDER) | 1360 | if (pkt->entry_status & RF_INV_E_ORDER) |
1326 | qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__); | 1361 | qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__); |
@@ -1339,13 +1374,13 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1339 | 1374 | ||
1340 | /* Validate handle. */ | 1375 | /* Validate handle. */ |
1341 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) | 1376 | if (pkt->handle < MAX_OUTSTANDING_COMMANDS) |
1342 | sp = ha->outstanding_cmds[pkt->handle]; | 1377 | sp = req->outstanding_cmds[pkt->handle]; |
1343 | else | 1378 | else |
1344 | sp = NULL; | 1379 | sp = NULL; |
1345 | 1380 | ||
1346 | if (sp) { | 1381 | if (sp) { |
1347 | /* Free outstanding command slot. */ | 1382 | /* Free outstanding command slot. */ |
1348 | ha->outstanding_cmds[pkt->handle] = NULL; | 1383 | req->outstanding_cmds[pkt->handle] = NULL; |
1349 | 1384 | ||
1350 | /* Bad payload or header */ | 1385 | /* Bad payload or header */ |
1351 | if (pkt->entry_status & | 1386 | if (pkt->entry_status & |
@@ -1362,12 +1397,12 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1362 | } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type == | 1397 | } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type == |
1363 | COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) { | 1398 | COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) { |
1364 | DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n", | 1399 | DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n", |
1365 | ha->host_no)); | 1400 | vha->host_no)); |
1366 | qla_printk(KERN_WARNING, ha, | 1401 | qla_printk(KERN_WARNING, ha, |
1367 | "Error entry - invalid handle\n"); | 1402 | "Error entry - invalid handle\n"); |
1368 | 1403 | ||
1369 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1404 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
1370 | qla2xxx_wake_dpc(ha); | 1405 | qla2xxx_wake_dpc(vha); |
1371 | } | 1406 | } |
1372 | } | 1407 | } |
1373 | 1408 | ||
@@ -1377,10 +1412,11 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt) | |||
1377 | * @mb0: Mailbox0 register | 1412 | * @mb0: Mailbox0 register |
1378 | */ | 1413 | */ |
1379 | static void | 1414 | static void |
1380 | qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0) | 1415 | qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) |
1381 | { | 1416 | { |
1382 | uint16_t cnt; | 1417 | uint16_t cnt; |
1383 | uint16_t __iomem *wptr; | 1418 | uint16_t __iomem *wptr; |
1419 | struct qla_hw_data *ha = vha->hw; | ||
1384 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1420 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1385 | 1421 | ||
1386 | /* Load return mailbox registers. */ | 1422 | /* Load return mailbox registers. */ |
@@ -1395,10 +1431,10 @@ qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0) | |||
1395 | 1431 | ||
1396 | if (ha->mcp) { | 1432 | if (ha->mcp) { |
1397 | DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n", | 1433 | DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n", |
1398 | __func__, ha->host_no, ha->mcp->mb[0])); | 1434 | __func__, vha->host_no, ha->mcp->mb[0])); |
1399 | } else { | 1435 | } else { |
1400 | DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n", | 1436 | DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n", |
1401 | __func__, ha->host_no)); | 1437 | __func__, vha->host_no)); |
1402 | } | 1438 | } |
1403 | } | 1439 | } |
1404 | 1440 | ||
@@ -1407,30 +1443,33 @@ qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0) | |||
1407 | * @ha: SCSI driver HA context | 1443 | * @ha: SCSI driver HA context |
1408 | */ | 1444 | */ |
1409 | void | 1445 | void |
1410 | qla24xx_process_response_queue(struct scsi_qla_host *ha) | 1446 | qla24xx_process_response_queue(struct rsp_que *rsp) |
1411 | { | 1447 | { |
1412 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1448 | struct qla_hw_data *ha = rsp->hw; |
1413 | struct sts_entry_24xx *pkt; | 1449 | struct sts_entry_24xx *pkt; |
1450 | struct scsi_qla_host *vha; | ||
1451 | |||
1452 | vha = qla2x00_get_rsp_host(rsp); | ||
1414 | 1453 | ||
1415 | if (!ha->flags.online) | 1454 | if (!vha->flags.online) |
1416 | return; | 1455 | return; |
1417 | 1456 | ||
1418 | while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) { | 1457 | while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { |
1419 | pkt = (struct sts_entry_24xx *)ha->response_ring_ptr; | 1458 | pkt = (struct sts_entry_24xx *)rsp->ring_ptr; |
1420 | 1459 | ||
1421 | ha->rsp_ring_index++; | 1460 | rsp->ring_index++; |
1422 | if (ha->rsp_ring_index == ha->response_q_length) { | 1461 | if (rsp->ring_index == rsp->length) { |
1423 | ha->rsp_ring_index = 0; | 1462 | rsp->ring_index = 0; |
1424 | ha->response_ring_ptr = ha->response_ring; | 1463 | rsp->ring_ptr = rsp->ring; |
1425 | } else { | 1464 | } else { |
1426 | ha->response_ring_ptr++; | 1465 | rsp->ring_ptr++; |
1427 | } | 1466 | } |
1428 | 1467 | ||
1429 | if (pkt->entry_status != 0) { | 1468 | if (pkt->entry_status != 0) { |
1430 | DEBUG3(printk(KERN_INFO | 1469 | DEBUG3(printk(KERN_INFO |
1431 | "scsi(%ld): Process error entry.\n", ha->host_no)); | 1470 | "scsi(%ld): Process error entry.\n", vha->host_no)); |
1432 | 1471 | ||
1433 | qla2x00_error_entry(ha, (sts_entry_t *) pkt); | 1472 | qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt); |
1434 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; | 1473 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
1435 | wmb(); | 1474 | wmb(); |
1436 | continue; | 1475 | continue; |
@@ -1438,13 +1477,13 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1438 | 1477 | ||
1439 | switch (pkt->entry_type) { | 1478 | switch (pkt->entry_type) { |
1440 | case STATUS_TYPE: | 1479 | case STATUS_TYPE: |
1441 | qla2x00_status_entry(ha, pkt); | 1480 | qla2x00_status_entry(vha, rsp, pkt); |
1442 | break; | 1481 | break; |
1443 | case STATUS_CONT_TYPE: | 1482 | case STATUS_CONT_TYPE: |
1444 | qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt); | 1483 | qla2x00_status_cont_entry(vha, (sts_cont_entry_t *)pkt); |
1445 | break; | 1484 | break; |
1446 | case VP_RPT_ID_IOCB_TYPE: | 1485 | case VP_RPT_ID_IOCB_TYPE: |
1447 | qla24xx_report_id_acquisition(ha, | 1486 | qla24xx_report_id_acquisition(vha, |
1448 | (struct vp_rpt_id_entry_24xx *)pkt); | 1487 | (struct vp_rpt_id_entry_24xx *)pkt); |
1449 | break; | 1488 | break; |
1450 | default: | 1489 | default: |
@@ -1452,7 +1491,7 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1452 | DEBUG4(printk(KERN_WARNING | 1491 | DEBUG4(printk(KERN_WARNING |
1453 | "scsi(%ld): Received unknown response pkt type %x " | 1492 | "scsi(%ld): Received unknown response pkt type %x " |
1454 | "entry status=%x.\n", | 1493 | "entry status=%x.\n", |
1455 | ha->host_no, pkt->entry_type, pkt->entry_status)); | 1494 | vha->host_no, pkt->entry_type, pkt->entry_status)); |
1456 | break; | 1495 | break; |
1457 | } | 1496 | } |
1458 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; | 1497 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
@@ -1460,14 +1499,15 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1460 | } | 1499 | } |
1461 | 1500 | ||
1462 | /* Adjust ring index */ | 1501 | /* Adjust ring index */ |
1463 | WRT_REG_DWORD(®->rsp_q_out, ha->rsp_ring_index); | 1502 | ha->isp_ops->wrt_rsp_reg(ha, rsp->id, rsp->ring_index); |
1464 | } | 1503 | } |
1465 | 1504 | ||
1466 | static void | 1505 | static void |
1467 | qla2xxx_check_risc_status(scsi_qla_host_t *ha) | 1506 | qla2xxx_check_risc_status(scsi_qla_host_t *vha) |
1468 | { | 1507 | { |
1469 | int rval; | 1508 | int rval; |
1470 | uint32_t cnt; | 1509 | uint32_t cnt; |
1510 | struct qla_hw_data *ha = vha->hw; | ||
1471 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1511 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1472 | 1512 | ||
1473 | if (!IS_QLA25XX(ha)) | 1513 | if (!IS_QLA25XX(ha)) |
@@ -1521,25 +1561,29 @@ done: | |||
1521 | irqreturn_t | 1561 | irqreturn_t |
1522 | qla24xx_intr_handler(int irq, void *dev_id) | 1562 | qla24xx_intr_handler(int irq, void *dev_id) |
1523 | { | 1563 | { |
1524 | scsi_qla_host_t *ha; | 1564 | scsi_qla_host_t *vha; |
1565 | struct qla_hw_data *ha; | ||
1525 | struct device_reg_24xx __iomem *reg; | 1566 | struct device_reg_24xx __iomem *reg; |
1526 | int status; | 1567 | int status; |
1527 | unsigned long iter; | 1568 | unsigned long iter; |
1528 | uint32_t stat; | 1569 | uint32_t stat; |
1529 | uint32_t hccr; | 1570 | uint32_t hccr; |
1530 | uint16_t mb[4]; | 1571 | uint16_t mb[4]; |
1572 | struct rsp_que *rsp; | ||
1531 | 1573 | ||
1532 | ha = (scsi_qla_host_t *) dev_id; | 1574 | rsp = (struct rsp_que *) dev_id; |
1533 | if (!ha) { | 1575 | if (!rsp) { |
1534 | printk(KERN_INFO | 1576 | printk(KERN_INFO |
1535 | "%s(): NULL host pointer\n", __func__); | 1577 | "%s(): NULL response queue pointer\n", __func__); |
1536 | return IRQ_NONE; | 1578 | return IRQ_NONE; |
1537 | } | 1579 | } |
1538 | 1580 | ||
1581 | ha = rsp->hw; | ||
1539 | reg = &ha->iobase->isp24; | 1582 | reg = &ha->iobase->isp24; |
1540 | status = 0; | 1583 | status = 0; |
1541 | 1584 | ||
1542 | spin_lock(&ha->hardware_lock); | 1585 | spin_lock(&ha->hardware_lock); |
1586 | vha = qla2x00_get_rsp_host(rsp); | ||
1543 | for (iter = 50; iter--; ) { | 1587 | for (iter = 50; iter--; ) { |
1544 | stat = RD_REG_DWORD(®->host_status); | 1588 | stat = RD_REG_DWORD(®->host_status); |
1545 | if (stat & HSRX_RISC_PAUSED) { | 1589 | if (stat & HSRX_RISC_PAUSED) { |
@@ -1547,7 +1591,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1547 | break; | 1591 | break; |
1548 | 1592 | ||
1549 | if (ha->hw_event_pause_errors == 0) | 1593 | if (ha->hw_event_pause_errors == 0) |
1550 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | 1594 | qla2x00_post_hwe_work(vha, HW_EVENT_PARITY_ERR, |
1551 | 0, MSW(stat), LSW(stat)); | 1595 | 0, MSW(stat), LSW(stat)); |
1552 | else if (ha->hw_event_pause_errors < 0xffffffff) | 1596 | else if (ha->hw_event_pause_errors < 0xffffffff) |
1553 | ha->hw_event_pause_errors++; | 1597 | ha->hw_event_pause_errors++; |
@@ -1557,10 +1601,10 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1557 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1601 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
1558 | "Dumping firmware!\n", hccr); | 1602 | "Dumping firmware!\n", hccr); |
1559 | 1603 | ||
1560 | qla2xxx_check_risc_status(ha); | 1604 | qla2xxx_check_risc_status(vha); |
1561 | 1605 | ||
1562 | ha->isp_ops->fw_dump(ha, 1); | 1606 | ha->isp_ops->fw_dump(vha, 1); |
1563 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1607 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
1564 | break; | 1608 | break; |
1565 | } else if ((stat & HSRX_RISC_INT) == 0) | 1609 | } else if ((stat & HSRX_RISC_INT) == 0) |
1566 | break; | 1610 | break; |
@@ -1570,7 +1614,7 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1570 | case 0x2: | 1614 | case 0x2: |
1571 | case 0x10: | 1615 | case 0x10: |
1572 | case 0x11: | 1616 | case 0x11: |
1573 | qla24xx_mbx_completion(ha, MSW(stat)); | 1617 | qla24xx_mbx_completion(vha, MSW(stat)); |
1574 | status |= MBX_INTERRUPT; | 1618 | status |= MBX_INTERRUPT; |
1575 | 1619 | ||
1576 | break; | 1620 | break; |
@@ -1579,15 +1623,16 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1579 | mb[1] = RD_REG_WORD(®->mailbox1); | 1623 | mb[1] = RD_REG_WORD(®->mailbox1); |
1580 | mb[2] = RD_REG_WORD(®->mailbox2); | 1624 | mb[2] = RD_REG_WORD(®->mailbox2); |
1581 | mb[3] = RD_REG_WORD(®->mailbox3); | 1625 | mb[3] = RD_REG_WORD(®->mailbox3); |
1582 | qla2x00_async_event(ha, mb); | 1626 | qla2x00_async_event(vha, rsp, mb); |
1583 | break; | 1627 | break; |
1584 | case 0x13: | 1628 | case 0x13: |
1585 | qla24xx_process_response_queue(ha); | 1629 | case 0x14: |
1630 | qla24xx_process_response_queue(rsp); | ||
1586 | break; | 1631 | break; |
1587 | default: | 1632 | default: |
1588 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " | 1633 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " |
1589 | "(%d).\n", | 1634 | "(%d).\n", |
1590 | ha->host_no, stat & 0xff)); | 1635 | vha->host_no, stat & 0xff)); |
1591 | break; | 1636 | break; |
1592 | } | 1637 | } |
1593 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1638 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
@@ -1607,15 +1652,22 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1607 | static irqreturn_t | 1652 | static irqreturn_t |
1608 | qla24xx_msix_rsp_q(int irq, void *dev_id) | 1653 | qla24xx_msix_rsp_q(int irq, void *dev_id) |
1609 | { | 1654 | { |
1610 | scsi_qla_host_t *ha; | 1655 | struct qla_hw_data *ha; |
1656 | struct rsp_que *rsp; | ||
1611 | struct device_reg_24xx __iomem *reg; | 1657 | struct device_reg_24xx __iomem *reg; |
1612 | 1658 | ||
1613 | ha = dev_id; | 1659 | rsp = (struct rsp_que *) dev_id; |
1660 | if (!rsp) { | ||
1661 | printk(KERN_INFO | ||
1662 | "%s(): NULL response queue pointer\n", __func__); | ||
1663 | return IRQ_NONE; | ||
1664 | } | ||
1665 | ha = rsp->hw; | ||
1614 | reg = &ha->iobase->isp24; | 1666 | reg = &ha->iobase->isp24; |
1615 | 1667 | ||
1616 | spin_lock_irq(&ha->hardware_lock); | 1668 | spin_lock_irq(&ha->hardware_lock); |
1617 | 1669 | ||
1618 | qla24xx_process_response_queue(ha); | 1670 | qla24xx_process_response_queue(rsp); |
1619 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1671 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1620 | 1672 | ||
1621 | spin_unlock_irq(&ha->hardware_lock); | 1673 | spin_unlock_irq(&ha->hardware_lock); |
@@ -1624,20 +1676,64 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1624 | } | 1676 | } |
1625 | 1677 | ||
1626 | static irqreturn_t | 1678 | static irqreturn_t |
1679 | qla25xx_msix_rsp_q(int irq, void *dev_id) | ||
1680 | { | ||
1681 | struct qla_hw_data *ha; | ||
1682 | struct rsp_que *rsp; | ||
1683 | struct device_reg_24xx __iomem *reg; | ||
1684 | uint16_t msix_disabled_hccr = 0; | ||
1685 | |||
1686 | rsp = (struct rsp_que *) dev_id; | ||
1687 | if (!rsp) { | ||
1688 | printk(KERN_INFO | ||
1689 | "%s(): NULL response queue pointer\n", __func__); | ||
1690 | return IRQ_NONE; | ||
1691 | } | ||
1692 | ha = rsp->hw; | ||
1693 | reg = &ha->iobase->isp24; | ||
1694 | |||
1695 | spin_lock_irq(&ha->hardware_lock); | ||
1696 | |||
1697 | msix_disabled_hccr = rsp->options; | ||
1698 | if (!rsp->id) | ||
1699 | msix_disabled_hccr &= __constant_cpu_to_le32(BIT_22); | ||
1700 | else | ||
1701 | msix_disabled_hccr &= __constant_cpu_to_le32(BIT_6); | ||
1702 | |||
1703 | qla24xx_process_response_queue(rsp); | ||
1704 | |||
1705 | if (!msix_disabled_hccr) | ||
1706 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | ||
1707 | |||
1708 | spin_unlock_irq(&ha->hardware_lock); | ||
1709 | |||
1710 | return IRQ_HANDLED; | ||
1711 | } | ||
1712 | |||
1713 | static irqreturn_t | ||
1627 | qla24xx_msix_default(int irq, void *dev_id) | 1714 | qla24xx_msix_default(int irq, void *dev_id) |
1628 | { | 1715 | { |
1629 | scsi_qla_host_t *ha; | 1716 | scsi_qla_host_t *vha; |
1717 | struct qla_hw_data *ha; | ||
1718 | struct rsp_que *rsp; | ||
1630 | struct device_reg_24xx __iomem *reg; | 1719 | struct device_reg_24xx __iomem *reg; |
1631 | int status; | 1720 | int status; |
1632 | uint32_t stat; | 1721 | uint32_t stat; |
1633 | uint32_t hccr; | 1722 | uint32_t hccr; |
1634 | uint16_t mb[4]; | 1723 | uint16_t mb[4]; |
1635 | 1724 | ||
1636 | ha = dev_id; | 1725 | rsp = (struct rsp_que *) dev_id; |
1726 | if (!rsp) { | ||
1727 | DEBUG(printk( | ||
1728 | "%s(): NULL response queue pointer\n", __func__)); | ||
1729 | return IRQ_NONE; | ||
1730 | } | ||
1731 | ha = rsp->hw; | ||
1637 | reg = &ha->iobase->isp24; | 1732 | reg = &ha->iobase->isp24; |
1638 | status = 0; | 1733 | status = 0; |
1639 | 1734 | ||
1640 | spin_lock_irq(&ha->hardware_lock); | 1735 | spin_lock_irq(&ha->hardware_lock); |
1736 | vha = qla2x00_get_rsp_host(rsp); | ||
1641 | do { | 1737 | do { |
1642 | stat = RD_REG_DWORD(®->host_status); | 1738 | stat = RD_REG_DWORD(®->host_status); |
1643 | if (stat & HSRX_RISC_PAUSED) { | 1739 | if (stat & HSRX_RISC_PAUSED) { |
@@ -1645,7 +1741,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1645 | break; | 1741 | break; |
1646 | 1742 | ||
1647 | if (ha->hw_event_pause_errors == 0) | 1743 | if (ha->hw_event_pause_errors == 0) |
1648 | qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR, | 1744 | qla2x00_post_hwe_work(vha, HW_EVENT_PARITY_ERR, |
1649 | 0, MSW(stat), LSW(stat)); | 1745 | 0, MSW(stat), LSW(stat)); |
1650 | else if (ha->hw_event_pause_errors < 0xffffffff) | 1746 | else if (ha->hw_event_pause_errors < 0xffffffff) |
1651 | ha->hw_event_pause_errors++; | 1747 | ha->hw_event_pause_errors++; |
@@ -1655,10 +1751,10 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1655 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1751 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
1656 | "Dumping firmware!\n", hccr); | 1752 | "Dumping firmware!\n", hccr); |
1657 | 1753 | ||
1658 | qla2xxx_check_risc_status(ha); | 1754 | qla2xxx_check_risc_status(vha); |
1659 | 1755 | ||
1660 | ha->isp_ops->fw_dump(ha, 1); | 1756 | ha->isp_ops->fw_dump(vha, 1); |
1661 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1757 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
1662 | break; | 1758 | break; |
1663 | } else if ((stat & HSRX_RISC_INT) == 0) | 1759 | } else if ((stat & HSRX_RISC_INT) == 0) |
1664 | break; | 1760 | break; |
@@ -1668,7 +1764,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1668 | case 0x2: | 1764 | case 0x2: |
1669 | case 0x10: | 1765 | case 0x10: |
1670 | case 0x11: | 1766 | case 0x11: |
1671 | qla24xx_mbx_completion(ha, MSW(stat)); | 1767 | qla24xx_mbx_completion(vha, MSW(stat)); |
1672 | status |= MBX_INTERRUPT; | 1768 | status |= MBX_INTERRUPT; |
1673 | 1769 | ||
1674 | break; | 1770 | break; |
@@ -1677,15 +1773,16 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1677 | mb[1] = RD_REG_WORD(®->mailbox1); | 1773 | mb[1] = RD_REG_WORD(®->mailbox1); |
1678 | mb[2] = RD_REG_WORD(®->mailbox2); | 1774 | mb[2] = RD_REG_WORD(®->mailbox2); |
1679 | mb[3] = RD_REG_WORD(®->mailbox3); | 1775 | mb[3] = RD_REG_WORD(®->mailbox3); |
1680 | qla2x00_async_event(ha, mb); | 1776 | qla2x00_async_event(vha, rsp, mb); |
1681 | break; | 1777 | break; |
1682 | case 0x13: | 1778 | case 0x13: |
1683 | qla24xx_process_response_queue(ha); | 1779 | case 0x14: |
1780 | qla24xx_process_response_queue(rsp); | ||
1684 | break; | 1781 | break; |
1685 | default: | 1782 | default: |
1686 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " | 1783 | DEBUG2(printk("scsi(%ld): Unrecognized interrupt type " |
1687 | "(%d).\n", | 1784 | "(%d).\n", |
1688 | ha->host_no, stat & 0xff)); | 1785 | vha->host_no, stat & 0xff)); |
1689 | break; | 1786 | break; |
1690 | } | 1787 | } |
1691 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1788 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
@@ -1710,70 +1807,138 @@ struct qla_init_msix_entry { | |||
1710 | irq_handler_t handler; | 1807 | irq_handler_t handler; |
1711 | }; | 1808 | }; |
1712 | 1809 | ||
1713 | static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = { | 1810 | static struct qla_init_msix_entry base_queue = { |
1714 | { QLA_MSIX_DEFAULT, QLA_MIDX_DEFAULT, | 1811 | .entry = 0, |
1715 | "qla2xxx (default)", qla24xx_msix_default }, | 1812 | .index = 0, |
1813 | .name = "qla2xxx (default)", | ||
1814 | .handler = qla24xx_msix_default, | ||
1815 | }; | ||
1816 | |||
1817 | static struct qla_init_msix_entry base_rsp_queue = { | ||
1818 | .entry = 1, | ||
1819 | .index = 1, | ||
1820 | .name = "qla2xxx (rsp_q)", | ||
1821 | .handler = qla24xx_msix_rsp_q, | ||
1822 | }; | ||
1716 | 1823 | ||
1717 | { QLA_MSIX_RSP_Q, QLA_MIDX_RSP_Q, | 1824 | static struct qla_init_msix_entry multi_rsp_queue = { |
1718 | "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, | 1825 | .entry = 1, |
1826 | .index = 1, | ||
1827 | .name = "qla2xxx (multi_q)", | ||
1828 | .handler = qla25xx_msix_rsp_q, | ||
1719 | }; | 1829 | }; |
1720 | 1830 | ||
1721 | static void | 1831 | static void |
1722 | qla24xx_disable_msix(scsi_qla_host_t *ha) | 1832 | qla24xx_disable_msix(struct qla_hw_data *ha) |
1723 | { | 1833 | { |
1724 | int i; | 1834 | int i; |
1725 | struct qla_msix_entry *qentry; | 1835 | struct qla_msix_entry *qentry; |
1726 | 1836 | ||
1727 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) { | 1837 | for (i = 0; i < ha->msix_count; i++) { |
1728 | qentry = &ha->msix_entries[imsix_entries[i].index]; | 1838 | qentry = &ha->msix_entries[i]; |
1729 | if (qentry->have_irq) | 1839 | if (qentry->have_irq) |
1730 | free_irq(qentry->msix_vector, ha); | 1840 | free_irq(qentry->vector, qentry->rsp); |
1731 | } | 1841 | } |
1732 | pci_disable_msix(ha->pdev); | 1842 | pci_disable_msix(ha->pdev); |
1843 | kfree(ha->msix_entries); | ||
1844 | ha->msix_entries = NULL; | ||
1845 | ha->flags.msix_enabled = 0; | ||
1733 | } | 1846 | } |
1734 | 1847 | ||
1735 | static int | 1848 | static int |
1736 | qla24xx_enable_msix(scsi_qla_host_t *ha) | 1849 | qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) |
1737 | { | 1850 | { |
1738 | int i, ret; | 1851 | int i, ret; |
1739 | struct msix_entry entries[QLA_MSIX_ENTRIES]; | 1852 | struct msix_entry *entries; |
1740 | struct qla_msix_entry *qentry; | 1853 | struct qla_msix_entry *qentry; |
1854 | struct qla_init_msix_entry *msix_queue; | ||
1741 | 1855 | ||
1742 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) | 1856 | entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count, |
1743 | entries[i].entry = imsix_entries[i].entry; | 1857 | GFP_KERNEL); |
1858 | if (!entries) | ||
1859 | return -ENOMEM; | ||
1744 | 1860 | ||
1745 | ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries)); | 1861 | for (i = 0; i < ha->msix_count; i++) |
1862 | entries[i].entry = i; | ||
1863 | |||
1864 | ret = pci_enable_msix(ha->pdev, entries, ha->msix_count); | ||
1746 | if (ret) { | 1865 | if (ret) { |
1747 | qla_printk(KERN_WARNING, ha, | 1866 | qla_printk(KERN_WARNING, ha, |
1748 | "MSI-X: Failed to enable support -- %d/%d\n", | 1867 | "MSI-X: Failed to enable support -- %d/%d\n" |
1749 | QLA_MSIX_ENTRIES, ret); | 1868 | " Retry with %d vectors\n", ha->msix_count, ret, ret); |
1869 | ha->msix_count = ret; | ||
1870 | ret = pci_enable_msix(ha->pdev, entries, ha->msix_count); | ||
1871 | if (ret) { | ||
1872 | qla_printk(KERN_WARNING, ha, "MSI-X: Failed to enable" | ||
1873 | " support, giving up -- %d/%d\n", | ||
1874 | ha->msix_count, ret); | ||
1875 | goto msix_out; | ||
1876 | } | ||
1877 | ha->max_queues = ha->msix_count - 1; | ||
1878 | } | ||
1879 | ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) * | ||
1880 | ha->msix_count, GFP_KERNEL); | ||
1881 | if (!ha->msix_entries) { | ||
1882 | ret = -ENOMEM; | ||
1750 | goto msix_out; | 1883 | goto msix_out; |
1751 | } | 1884 | } |
1752 | ha->flags.msix_enabled = 1; | 1885 | ha->flags.msix_enabled = 1; |
1753 | 1886 | ||
1754 | for (i = 0; i < QLA_MSIX_ENTRIES; i++) { | 1887 | for (i = 0; i < ha->msix_count; i++) { |
1755 | qentry = &ha->msix_entries[imsix_entries[i].index]; | 1888 | qentry = &ha->msix_entries[i]; |
1756 | qentry->msix_vector = entries[i].vector; | 1889 | qentry->vector = entries[i].vector; |
1757 | qentry->msix_entry = entries[i].entry; | 1890 | qentry->entry = entries[i].entry; |
1758 | qentry->have_irq = 0; | 1891 | qentry->have_irq = 0; |
1759 | ret = request_irq(qentry->msix_vector, | 1892 | qentry->rsp = NULL; |
1760 | imsix_entries[i].handler, 0, imsix_entries[i].name, ha); | 1893 | } |
1761 | if (ret) { | 1894 | |
1762 | qla_printk(KERN_WARNING, ha, | 1895 | /* Enable MSI-X for AENs for queue 0 */ |
1763 | "MSI-X: Unable to register handler -- %x/%d.\n", | 1896 | qentry = &ha->msix_entries[0]; |
1764 | imsix_entries[i].index, ret); | 1897 | ret = request_irq(qentry->vector, base_queue.handler, 0, |
1765 | qla24xx_disable_msix(ha); | 1898 | base_queue.name, rsp); |
1766 | goto msix_out; | 1899 | if (ret) { |
1767 | } | 1900 | qla_printk(KERN_WARNING, ha, |
1768 | qentry->have_irq = 1; | 1901 | "MSI-X: Unable to register handler -- %x/%d.\n", |
1902 | qentry->vector, ret); | ||
1903 | qla24xx_disable_msix(ha); | ||
1904 | goto msix_out; | ||
1769 | } | 1905 | } |
1906 | qentry->have_irq = 1; | ||
1907 | qentry->rsp = rsp; | ||
1908 | |||
1909 | /* Enable MSI-X vector for response queue update for queue 0 */ | ||
1910 | if (ha->max_queues > 1 && ha->mqiobase) { | ||
1911 | ha->mqenable = 1; | ||
1912 | msix_queue = &multi_rsp_queue; | ||
1913 | qla_printk(KERN_INFO, ha, | ||
1914 | "MQ enabled, Number of Queue Resources: %d \n", | ||
1915 | ha->max_queues); | ||
1916 | } else { | ||
1917 | ha->mqenable = 0; | ||
1918 | msix_queue = &base_rsp_queue; | ||
1919 | } | ||
1920 | |||
1921 | qentry = &ha->msix_entries[1]; | ||
1922 | ret = request_irq(qentry->vector, msix_queue->handler, 0, | ||
1923 | msix_queue->name, rsp); | ||
1924 | if (ret) { | ||
1925 | qla_printk(KERN_WARNING, ha, | ||
1926 | "MSI-X: Unable to register handler -- %x/%d.\n", | ||
1927 | qentry->vector, ret); | ||
1928 | qla24xx_disable_msix(ha); | ||
1929 | ha->mqenable = 0; | ||
1930 | goto msix_out; | ||
1931 | } | ||
1932 | qentry->have_irq = 1; | ||
1933 | qentry->rsp = rsp; | ||
1770 | 1934 | ||
1771 | msix_out: | 1935 | msix_out: |
1936 | kfree(entries); | ||
1772 | return ret; | 1937 | return ret; |
1773 | } | 1938 | } |
1774 | 1939 | ||
1775 | int | 1940 | int |
1776 | qla2x00_request_irqs(scsi_qla_host_t *ha) | 1941 | qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) |
1777 | { | 1942 | { |
1778 | int ret; | 1943 | int ret; |
1779 | device_reg_t __iomem *reg = ha->iobase; | 1944 | device_reg_t __iomem *reg = ha->iobase; |
@@ -1782,11 +1947,11 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1782 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) | 1947 | if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha)) |
1783 | goto skip_msix; | 1948 | goto skip_msix; |
1784 | 1949 | ||
1785 | if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX || | 1950 | if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX || |
1786 | !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { | 1951 | !QLA_MSIX_FW_MODE_1(ha->fw_attributes))) { |
1787 | DEBUG2(qla_printk(KERN_WARNING, ha, | 1952 | DEBUG2(qla_printk(KERN_WARNING, ha, |
1788 | "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", | 1953 | "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n", |
1789 | ha->chip_revision, ha->fw_attributes)); | 1954 | ha->pdev->revision, ha->fw_attributes)); |
1790 | 1955 | ||
1791 | goto skip_msix; | 1956 | goto skip_msix; |
1792 | } | 1957 | } |
@@ -1803,7 +1968,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha) | |||
1803 | goto skip_msi; | 1968 | goto skip_msi; |
1804 | } | 1969 | } |
1805 | 1970 | ||
1806 | ret = qla24xx_enable_msix(ha); | 1971 | ret = qla24xx_enable_msix(ha, rsp); |
1807 | if (!ret) { | 1972 | if (!ret) { |
1808 | DEBUG2(qla_printk(KERN_INFO, ha, | 1973 | DEBUG2(qla_printk(KERN_INFO, ha, |
1809 | "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision, | 1974 | "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision, |
@@ -1825,7 +1990,7 @@ skip_msix: | |||
1825 | skip_msi: | 1990 | skip_msi: |
1826 | 1991 | ||
1827 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, | 1992 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, |
1828 | IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha); | 1993 | IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp); |
1829 | if (ret) { | 1994 | if (ret) { |
1830 | qla_printk(KERN_WARNING, ha, | 1995 | qla_printk(KERN_WARNING, ha, |
1831 | "Failed to reserve interrupt %d already in use.\n", | 1996 | "Failed to reserve interrupt %d already in use.\n", |
@@ -1833,10 +1998,8 @@ skip_msi: | |||
1833 | goto fail; | 1998 | goto fail; |
1834 | } | 1999 | } |
1835 | ha->flags.inta_enabled = 1; | 2000 | ha->flags.inta_enabled = 1; |
1836 | ha->host->irq = ha->pdev->irq; | ||
1837 | clear_risc_ints: | 2001 | clear_risc_ints: |
1838 | 2002 | ||
1839 | ha->isp_ops->disable_intrs(ha); | ||
1840 | spin_lock_irq(&ha->hardware_lock); | 2003 | spin_lock_irq(&ha->hardware_lock); |
1841 | if (IS_FWI2_CAPABLE(ha)) { | 2004 | if (IS_FWI2_CAPABLE(ha)) { |
1842 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); | 2005 | WRT_REG_DWORD(®->isp24.hccr, HCCRX_CLR_HOST_INT); |
@@ -1853,13 +2016,74 @@ fail: | |||
1853 | } | 2016 | } |
1854 | 2017 | ||
1855 | void | 2018 | void |
1856 | qla2x00_free_irqs(scsi_qla_host_t *ha) | 2019 | qla2x00_free_irqs(scsi_qla_host_t *vha) |
1857 | { | 2020 | { |
2021 | struct qla_hw_data *ha = vha->hw; | ||
2022 | struct rsp_que *rsp = ha->rsp_q_map[0]; | ||
1858 | 2023 | ||
1859 | if (ha->flags.msix_enabled) | 2024 | if (ha->flags.msix_enabled) |
1860 | qla24xx_disable_msix(ha); | 2025 | qla24xx_disable_msix(ha); |
1861 | else if (ha->flags.inta_enabled) { | 2026 | else if (ha->flags.inta_enabled) { |
1862 | free_irq(ha->host->irq, ha); | 2027 | free_irq(ha->pdev->irq, rsp); |
1863 | pci_disable_msi(ha->pdev); | 2028 | pci_disable_msi(ha->pdev); |
1864 | } | 2029 | } |
1865 | } | 2030 | } |
2031 | |||
2032 | static struct scsi_qla_host * | ||
2033 | qla2x00_get_rsp_host(struct rsp_que *rsp) | ||
2034 | { | ||
2035 | srb_t *sp; | ||
2036 | struct qla_hw_data *ha = rsp->hw; | ||
2037 | struct scsi_qla_host *vha = NULL; | ||
2038 | struct sts_entry_24xx *pkt; | ||
2039 | struct req_que *req; | ||
2040 | |||
2041 | if (rsp->id) { | ||
2042 | pkt = (struct sts_entry_24xx *) rsp->ring_ptr; | ||
2043 | req = rsp->req; | ||
2044 | if (pkt && pkt->handle < MAX_OUTSTANDING_COMMANDS) { | ||
2045 | sp = req->outstanding_cmds[pkt->handle]; | ||
2046 | if (sp) | ||
2047 | vha = sp->vha; | ||
2048 | } | ||
2049 | } | ||
2050 | if (!vha) | ||
2051 | /* handle it in base queue */ | ||
2052 | vha = pci_get_drvdata(ha->pdev); | ||
2053 | |||
2054 | return vha; | ||
2055 | } | ||
2056 | |||
2057 | int qla25xx_request_irq(struct rsp_que *rsp) | ||
2058 | { | ||
2059 | struct qla_hw_data *ha = rsp->hw; | ||
2060 | struct qla_init_msix_entry *intr = &multi_rsp_queue; | ||
2061 | struct qla_msix_entry *msix = rsp->msix; | ||
2062 | int ret; | ||
2063 | |||
2064 | ret = request_irq(msix->vector, intr->handler, 0, intr->name, rsp); | ||
2065 | if (ret) { | ||
2066 | qla_printk(KERN_WARNING, ha, | ||
2067 | "MSI-X: Unable to register handler -- %x/%d.\n", | ||
2068 | msix->vector, ret); | ||
2069 | return ret; | ||
2070 | } | ||
2071 | msix->have_irq = 1; | ||
2072 | msix->rsp = rsp; | ||
2073 | return ret; | ||
2074 | } | ||
2075 | |||
2076 | void | ||
2077 | qla25xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index) | ||
2078 | { | ||
2079 | device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id; | ||
2080 | WRT_REG_DWORD(®->isp25mq.rsp_q_out, index); | ||
2081 | } | ||
2082 | |||
2083 | void | ||
2084 | qla24xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index) | ||
2085 | { | ||
2086 | device_reg_t __iomem *reg = (void *) ha->iobase; | ||
2087 | WRT_REG_DWORD(®->isp24.rsp_q_out, index); | ||
2088 | } | ||
2089 | |||