[SCSI] qla2xxx: Remove unnecessary spinlock primitive - mbx_reg_lock.
[linux-2.6/verdex.git] / drivers / scsi / qla2xxx / qla_isr.c
blobc948a8ce723299f5d4a28d9981323c1707ac3d03
1 /*
2 * QLogic Fibre Channel HBA Driver
3 * Copyright (c) 2003-2005 QLogic Corporation
5 * See LICENSE.qla2xxx for copyright and licensing details.
6 */
7 #include "qla_def.h"
9 #include <scsi/scsi_tcq.h>
11 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
12 static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
13 static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
14 static void qla2x00_status_entry(scsi_qla_host_t *, void *);
15 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_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
19 static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
21 /**
22 * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
23 * @irq:
24 * @dev_id: SCSI driver HA context
26 * Called by system whenever the host adapter generates an interrupt.
28 * Returns handled flag.
30 irqreturn_t
31 qla2100_intr_handler(int irq, void *dev_id)
33 scsi_qla_host_t *ha;
34 struct device_reg_2xxx __iomem *reg;
35 int status;
36 unsigned long flags;
37 unsigned long iter;
38 uint16_t mb[4];
40 ha = (scsi_qla_host_t *) dev_id;
41 if (!ha) {
42 printk(KERN_INFO
43 "%s(): NULL host pointer\n", __func__);
44 return (IRQ_NONE);
47 reg = &ha->iobase->isp;
48 status = 0;
50 spin_lock_irqsave(&ha->hardware_lock, flags);
51 for (iter = 50; iter--; ) {
52 if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
53 break;
55 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
56 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
57 RD_REG_WORD(&reg->hccr);
59 /* Get mailbox data. */
60 mb[0] = RD_MAILBOX_REG(ha, reg, 0);
61 if (mb[0] > 0x3fff && mb[0] < 0x8000) {
62 qla2x00_mbx_completion(ha, mb[0]);
63 status |= MBX_INTERRUPT;
64 } else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
65 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
66 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
67 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
68 qla2x00_async_event(ha, mb);
69 } else {
70 /*EMPTY*/
71 DEBUG2(printk("scsi(%ld): Unrecognized "
72 "interrupt type (%d).\n",
73 ha->host_no, mb[0]));
75 /* Release mailbox registers. */
76 WRT_REG_WORD(&reg->semaphore, 0);
77 RD_REG_WORD(&reg->semaphore);
78 } else {
79 qla2x00_process_response_queue(ha);
81 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
82 RD_REG_WORD(&reg->hccr);
85 spin_unlock_irqrestore(&ha->hardware_lock, flags);
87 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
88 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
89 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
90 up(&ha->mbx_intr_sem);
93 return (IRQ_HANDLED);
96 /**
97 * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
98 * @irq:
99 * @dev_id: SCSI driver HA context
101 * Called by system whenever the host adapter generates an interrupt.
103 * Returns handled flag.
105 irqreturn_t
106 qla2300_intr_handler(int irq, void *dev_id)
108 scsi_qla_host_t *ha;
109 struct device_reg_2xxx __iomem *reg;
110 int status;
111 unsigned long flags;
112 unsigned long iter;
113 uint32_t stat;
114 uint16_t hccr;
115 uint16_t mb[4];
117 ha = (scsi_qla_host_t *) dev_id;
118 if (!ha) {
119 printk(KERN_INFO
120 "%s(): NULL host pointer\n", __func__);
121 return (IRQ_NONE);
124 reg = &ha->iobase->isp;
125 status = 0;
127 spin_lock_irqsave(&ha->hardware_lock, flags);
128 for (iter = 50; iter--; ) {
129 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
130 if (stat & HSR_RISC_PAUSED) {
131 hccr = RD_REG_WORD(&reg->hccr);
132 if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
133 qla_printk(KERN_INFO, ha,
134 "Parity error -- HCCR=%x.\n", hccr);
135 else
136 qla_printk(KERN_INFO, ha,
137 "RISC paused -- HCCR=%x.\n", hccr);
140 * Issue a "HARD" reset in order for the RISC
141 * interrupt bit to be cleared. Schedule a big
142 * hammmer to get out of the RISC PAUSED state.
144 WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
145 RD_REG_WORD(&reg->hccr);
146 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
147 break;
148 } else if ((stat & HSR_RISC_INT) == 0)
149 break;
151 switch (stat & 0xff) {
152 case 0x1:
153 case 0x2:
154 case 0x10:
155 case 0x11:
156 qla2x00_mbx_completion(ha, MSW(stat));
157 status |= MBX_INTERRUPT;
159 /* Release mailbox registers. */
160 WRT_REG_WORD(&reg->semaphore, 0);
161 break;
162 case 0x12:
163 mb[0] = MSW(stat);
164 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
165 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
166 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
167 qla2x00_async_event(ha, mb);
168 break;
169 case 0x13:
170 qla2x00_process_response_queue(ha);
171 break;
172 case 0x15:
173 mb[0] = MBA_CMPLT_1_16BIT;
174 mb[1] = MSW(stat);
175 qla2x00_async_event(ha, mb);
176 break;
177 case 0x16:
178 mb[0] = MBA_SCSI_COMPLETION;
179 mb[1] = MSW(stat);
180 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
181 qla2x00_async_event(ha, mb);
182 break;
183 default:
184 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
185 "(%d).\n",
186 ha->host_no, stat & 0xff));
187 break;
189 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
190 RD_REG_WORD_RELAXED(&reg->hccr);
192 spin_unlock_irqrestore(&ha->hardware_lock, flags);
194 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
195 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
196 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
197 up(&ha->mbx_intr_sem);
200 return (IRQ_HANDLED);
204 * qla2x00_mbx_completion() - Process mailbox command completions.
205 * @ha: SCSI driver HA context
206 * @mb0: Mailbox0 register
208 static void
209 qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
211 uint16_t cnt;
212 uint16_t __iomem *wptr;
213 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
215 /* Load return mailbox registers. */
216 ha->flags.mbox_int = 1;
217 ha->mailbox_out[0] = mb0;
218 wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
220 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
221 if (IS_QLA2200(ha) && cnt == 8)
222 wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
223 if (cnt == 4 || cnt == 5)
224 ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
225 else
226 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
228 wptr++;
231 if (ha->mcp) {
232 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
233 __func__, ha->host_no, ha->mcp->mb[0]));
234 } else {
235 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
236 __func__, ha->host_no));
241 * qla2x00_async_event() - Process aynchronous events.
242 * @ha: SCSI driver HA context
243 * @mb: Mailbox registers (0 - 3)
245 static void
246 qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
248 #define LS_UNKNOWN 2
249 static char *link_speeds[5] = { "1", "2", "?", "4", "10" };
250 char *link_speed;
251 uint16_t handle_cnt;
252 uint16_t cnt;
253 uint32_t handles[5];
254 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
255 uint32_t rscn_entry, host_pid;
256 uint8_t rscn_queue_index;
258 /* Setup to process RIO completion. */
259 handle_cnt = 0;
260 switch (mb[0]) {
261 case MBA_SCSI_COMPLETION:
262 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
263 handle_cnt = 1;
264 break;
265 case MBA_CMPLT_1_16BIT:
266 handles[0] = mb[1];
267 handle_cnt = 1;
268 mb[0] = MBA_SCSI_COMPLETION;
269 break;
270 case MBA_CMPLT_2_16BIT:
271 handles[0] = mb[1];
272 handles[1] = mb[2];
273 handle_cnt = 2;
274 mb[0] = MBA_SCSI_COMPLETION;
275 break;
276 case MBA_CMPLT_3_16BIT:
277 handles[0] = mb[1];
278 handles[1] = mb[2];
279 handles[2] = mb[3];
280 handle_cnt = 3;
281 mb[0] = MBA_SCSI_COMPLETION;
282 break;
283 case MBA_CMPLT_4_16BIT:
284 handles[0] = mb[1];
285 handles[1] = mb[2];
286 handles[2] = mb[3];
287 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
288 handle_cnt = 4;
289 mb[0] = MBA_SCSI_COMPLETION;
290 break;
291 case MBA_CMPLT_5_16BIT:
292 handles[0] = mb[1];
293 handles[1] = mb[2];
294 handles[2] = mb[3];
295 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
296 handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
297 handle_cnt = 5;
298 mb[0] = MBA_SCSI_COMPLETION;
299 break;
300 case MBA_CMPLT_2_32BIT:
301 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
302 handles[1] = le32_to_cpu(
303 ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
304 RD_MAILBOX_REG(ha, reg, 6));
305 handle_cnt = 2;
306 mb[0] = MBA_SCSI_COMPLETION;
307 break;
308 default:
309 break;
312 switch (mb[0]) {
313 case MBA_SCSI_COMPLETION: /* Fast Post */
314 if (!ha->flags.online)
315 break;
317 for (cnt = 0; cnt < handle_cnt; cnt++)
318 qla2x00_process_completed_request(ha, handles[cnt]);
319 break;
321 case MBA_RESET: /* Reset */
322 DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no));
324 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
325 break;
327 case MBA_SYSTEM_ERR: /* System Error */
328 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
329 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
330 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
332 qla_printk(KERN_INFO, ha,
333 "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
334 mb[1], mb[2], mb[3]);
336 ha->isp_ops.fw_dump(ha, 1);
338 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
339 if (mb[1] == 0 && mb[2] == 0) {
340 qla_printk(KERN_ERR, ha,
341 "Unrecoverable Hardware Error: adapter "
342 "marked OFFLINE!\n");
343 ha->flags.online = 0;
344 } else
345 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
346 } else if (mb[1] == 0) {
347 qla_printk(KERN_INFO, ha,
348 "Unrecoverable Hardware Error: adapter marked "
349 "OFFLINE!\n");
350 ha->flags.online = 0;
351 } else
352 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
353 break;
355 case MBA_REQ_TRANSFER_ERR: /* Request Transfer Error */
356 DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
357 ha->host_no));
358 qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
360 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
361 break;
363 case MBA_RSP_TRANSFER_ERR: /* Response Transfer Error */
364 DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n",
365 ha->host_no));
366 qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
368 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
369 break;
371 case MBA_WAKEUP_THRES: /* Request Queue Wake-up */
372 DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
373 ha->host_no));
374 break;
376 case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */
377 DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
378 mb[1]));
379 qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
381 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
382 atomic_set(&ha->loop_state, LOOP_DOWN);
383 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
384 qla2x00_mark_all_devices_lost(ha, 1);
387 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
389 ha->flags.management_server_logged_in = 0;
390 break;
392 case MBA_LOOP_UP: /* Loop Up Event */
393 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
394 link_speed = link_speeds[0];
395 ha->link_data_rate = PORT_SPEED_1GB;
396 } else {
397 link_speed = link_speeds[LS_UNKNOWN];
398 if (mb[1] < 5)
399 link_speed = link_speeds[mb[1]];
400 ha->link_data_rate = mb[1];
403 DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n",
404 ha->host_no, link_speed));
405 qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n",
406 link_speed);
408 ha->flags.management_server_logged_in = 0;
409 break;
411 case MBA_LOOP_DOWN: /* Loop Down Event */
412 DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
413 ha->host_no, mb[1]));
414 qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
416 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
417 atomic_set(&ha->loop_state, LOOP_DOWN);
418 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
419 ha->device_flags |= DFLG_NO_CABLE;
420 qla2x00_mark_all_devices_lost(ha, 1);
423 ha->flags.management_server_logged_in = 0;
424 ha->link_data_rate = PORT_SPEED_UNKNOWN;
425 if (ql2xfdmienable)
426 set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
427 break;
429 case MBA_LIP_RESET: /* LIP reset occurred */
430 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
431 ha->host_no, mb[1]));
432 qla_printk(KERN_INFO, ha,
433 "LIP reset occured (%x).\n", mb[1]);
435 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
436 atomic_set(&ha->loop_state, LOOP_DOWN);
437 atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
438 qla2x00_mark_all_devices_lost(ha, 1);
441 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
443 ha->operating_mode = LOOP;
444 ha->flags.management_server_logged_in = 0;
445 break;
447 case MBA_POINT_TO_POINT: /* Point-to-Point */
448 if (IS_QLA2100(ha))
449 break;
451 DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n",
452 ha->host_no));
455 * Until there's a transition from loop down to loop up, treat
456 * this as loop down only.
458 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
459 atomic_set(&ha->loop_state, LOOP_DOWN);
460 if (!atomic_read(&ha->loop_down_timer))
461 atomic_set(&ha->loop_down_timer,
462 LOOP_DOWN_TIME);
463 qla2x00_mark_all_devices_lost(ha, 1);
466 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
467 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
469 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
470 break;
472 case MBA_CHG_IN_CONNECTION: /* Change in connection mode */
473 if (IS_QLA2100(ha))
474 break;
476 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
477 "received.\n",
478 ha->host_no));
479 qla_printk(KERN_INFO, ha,
480 "Configuration change detected: value=%x.\n", mb[1]);
482 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
483 atomic_set(&ha->loop_state, LOOP_DOWN);
484 if (!atomic_read(&ha->loop_down_timer))
485 atomic_set(&ha->loop_down_timer,
486 LOOP_DOWN_TIME);
487 qla2x00_mark_all_devices_lost(ha, 1);
490 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
491 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
492 break;
494 case MBA_PORT_UPDATE: /* Port database update */
496 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
497 * event etc. earlier indicating loop is down) then process
498 * it. Otherwise ignore it and Wait for RSCN to come in.
500 atomic_set(&ha->loop_down_timer, 0);
501 if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
502 atomic_read(&ha->loop_state) != LOOP_DEAD) {
503 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
504 "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
505 mb[2], mb[3]));
506 break;
509 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
510 ha->host_no));
511 DEBUG(printk(KERN_INFO
512 "scsi(%ld): Port database changed %04x %04x %04x.\n",
513 ha->host_no, mb[1], mb[2], mb[3]));
516 * Mark all devices as missing so we will login again.
518 atomic_set(&ha->loop_state, LOOP_UP);
520 qla2x00_mark_all_devices_lost(ha, 1);
522 ha->flags.rscn_queue_overflow = 1;
524 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
525 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
526 break;
528 case MBA_RSCN_UPDATE: /* State Change Registration */
529 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
530 ha->host_no));
531 DEBUG(printk(KERN_INFO
532 "scsi(%ld): RSCN database changed -- %04x %04x.\n",
533 ha->host_no, mb[1], mb[2]));
535 rscn_entry = (mb[1] << 16) | mb[2];
536 host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
537 ha->d_id.b.al_pa;
538 if (rscn_entry == host_pid) {
539 DEBUG(printk(KERN_INFO
540 "scsi(%ld): Ignoring RSCN update to local host "
541 "port ID (%06x)\n",
542 ha->host_no, host_pid));
543 break;
546 rscn_queue_index = ha->rscn_in_ptr + 1;
547 if (rscn_queue_index == MAX_RSCN_COUNT)
548 rscn_queue_index = 0;
549 if (rscn_queue_index != ha->rscn_out_ptr) {
550 ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry;
551 ha->rscn_in_ptr = rscn_queue_index;
552 } else {
553 ha->flags.rscn_queue_overflow = 1;
556 atomic_set(&ha->loop_state, LOOP_UPDATE);
557 atomic_set(&ha->loop_down_timer, 0);
558 ha->flags.management_server_logged_in = 0;
560 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
561 set_bit(RSCN_UPDATE, &ha->dpc_flags);
562 break;
564 /* case MBA_RIO_RESPONSE: */
565 case MBA_ZIO_RESPONSE:
566 DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n",
567 ha->host_no));
568 DEBUG(printk(KERN_INFO
569 "scsi(%ld): [R|Z]IO update completion.\n",
570 ha->host_no));
572 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
573 qla24xx_process_response_queue(ha);
574 else
575 qla2x00_process_response_queue(ha);
576 break;
578 case MBA_DISCARD_RND_FRAME:
579 DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
580 "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
581 break;
583 case MBA_TRACE_NOTIFICATION:
584 DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
585 ha->host_no, mb[1], mb[2]));
586 break;
590 static void
591 qla2x00_adjust_sdev_qdepth_up(struct scsi_device *sdev, void *data)
593 fc_port_t *fcport = data;
595 if (fcport->ha->max_q_depth <= sdev->queue_depth)
596 return;
598 if (sdev->ordered_tags)
599 scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG,
600 sdev->queue_depth + 1);
601 else
602 scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG,
603 sdev->queue_depth + 1);
605 fcport->last_ramp_up = jiffies;
607 DEBUG2(qla_printk(KERN_INFO, fcport->ha,
608 "scsi(%ld:%d:%d:%d): Queue depth adjusted-up to %d.\n",
609 fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
610 sdev->queue_depth));
613 static void
614 qla2x00_adjust_sdev_qdepth_down(struct scsi_device *sdev, void *data)
616 fc_port_t *fcport = data;
618 if (!scsi_track_queue_full(sdev, sdev->queue_depth - 1))
619 return;
621 DEBUG2(qla_printk(KERN_INFO, fcport->ha,
622 "scsi(%ld:%d:%d:%d): Queue depth adjusted-down to %d.\n",
623 fcport->ha->host_no, sdev->channel, sdev->id, sdev->lun,
624 sdev->queue_depth));
627 static inline void
628 qla2x00_ramp_up_queue_depth(scsi_qla_host_t *ha, srb_t *sp)
630 fc_port_t *fcport;
631 struct scsi_device *sdev;
633 sdev = sp->cmd->device;
634 if (sdev->queue_depth >= ha->max_q_depth)
635 return;
637 fcport = sp->fcport;
638 if (time_before(jiffies,
639 fcport->last_ramp_up + ql2xqfullrampup * HZ))
640 return;
641 if (time_before(jiffies,
642 fcport->last_queue_full + ql2xqfullrampup * HZ))
643 return;
645 starget_for_each_device(sdev->sdev_target, fcport,
646 qla2x00_adjust_sdev_qdepth_up);
650 * qla2x00_process_completed_request() - Process a Fast Post response.
651 * @ha: SCSI driver HA context
652 * @index: SRB index
654 static void
655 qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
657 srb_t *sp;
659 /* Validate handle. */
660 if (index >= MAX_OUTSTANDING_COMMANDS) {
661 DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
662 ha->host_no, index));
663 qla_printk(KERN_WARNING, ha,
664 "Invalid SCSI completion handle %d.\n", index);
666 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
667 return;
670 sp = ha->outstanding_cmds[index];
671 if (sp) {
672 /* Free outstanding command slot. */
673 ha->outstanding_cmds[index] = NULL;
675 CMD_COMPL_STATUS(sp->cmd) = 0L;
676 CMD_SCSI_STATUS(sp->cmd) = 0L;
678 /* Save ISP completion status */
679 sp->cmd->result = DID_OK << 16;
681 qla2x00_ramp_up_queue_depth(ha, sp);
682 qla2x00_sp_compl(ha, sp);
683 } else {
684 DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
685 ha->host_no));
686 qla_printk(KERN_WARNING, ha,
687 "Invalid ISP SCSI completion handle\n");
689 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
694 * qla2x00_process_response_queue() - Process response queue entries.
695 * @ha: SCSI driver HA context
697 void
698 qla2x00_process_response_queue(struct scsi_qla_host *ha)
700 struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
701 sts_entry_t *pkt;
702 uint16_t handle_cnt;
703 uint16_t cnt;
705 if (!ha->flags.online)
706 return;
708 while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
709 pkt = (sts_entry_t *)ha->response_ring_ptr;
711 ha->rsp_ring_index++;
712 if (ha->rsp_ring_index == ha->response_q_length) {
713 ha->rsp_ring_index = 0;
714 ha->response_ring_ptr = ha->response_ring;
715 } else {
716 ha->response_ring_ptr++;
719 if (pkt->entry_status != 0) {
720 DEBUG3(printk(KERN_INFO
721 "scsi(%ld): Process error entry.\n", ha->host_no));
723 qla2x00_error_entry(ha, pkt);
724 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
725 wmb();
726 continue;
729 switch (pkt->entry_type) {
730 case STATUS_TYPE:
731 qla2x00_status_entry(ha, pkt);
732 break;
733 case STATUS_TYPE_21:
734 handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
735 for (cnt = 0; cnt < handle_cnt; cnt++) {
736 qla2x00_process_completed_request(ha,
737 ((sts21_entry_t *)pkt)->handle[cnt]);
739 break;
740 case STATUS_TYPE_22:
741 handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
742 for (cnt = 0; cnt < handle_cnt; cnt++) {
743 qla2x00_process_completed_request(ha,
744 ((sts22_entry_t *)pkt)->handle[cnt]);
746 break;
747 case STATUS_CONT_TYPE:
748 qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
749 break;
750 case MS_IOCB_TYPE:
751 qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
752 break;
753 default:
754 /* Type Not Supported. */
755 DEBUG4(printk(KERN_WARNING
756 "scsi(%ld): Received unknown response pkt type %x "
757 "entry status=%x.\n",
758 ha->host_no, pkt->entry_type, pkt->entry_status));
759 break;
761 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
762 wmb();
765 /* Adjust ring index */
766 WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index);
770 * qla2x00_status_entry() - Process a Status IOCB entry.
771 * @ha: SCSI driver HA context
772 * @pkt: Entry pointer
774 static void
775 qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
777 srb_t *sp;
778 fc_port_t *fcport;
779 struct scsi_cmnd *cp;
780 sts_entry_t *sts;
781 struct sts_entry_24xx *sts24;
782 uint16_t comp_status;
783 uint16_t scsi_status;
784 uint8_t lscsi_status;
785 int32_t resid;
786 uint32_t sense_len, rsp_info_len, resid_len, fw_resid_len;
787 uint8_t *rsp_info, *sense_data;
789 sts = (sts_entry_t *) pkt;
790 sts24 = (struct sts_entry_24xx *) pkt;
791 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
792 comp_status = le16_to_cpu(sts24->comp_status);
793 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
794 } else {
795 comp_status = le16_to_cpu(sts->comp_status);
796 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
799 /* Fast path completion. */
800 if (comp_status == CS_COMPLETE && scsi_status == 0) {
801 qla2x00_process_completed_request(ha, sts->handle);
803 return;
806 /* Validate handle. */
807 if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
808 sp = ha->outstanding_cmds[sts->handle];
809 ha->outstanding_cmds[sts->handle] = NULL;
810 } else
811 sp = NULL;
813 if (sp == NULL) {
814 DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
815 ha->host_no));
816 qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
818 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
819 qla2xxx_wake_dpc(ha);
820 return;
822 cp = sp->cmd;
823 if (cp == NULL) {
824 DEBUG2(printk("scsi(%ld): Command already returned back to OS "
825 "pkt->handle=%d sp=%p.\n", ha->host_no, sts->handle, sp));
826 qla_printk(KERN_WARNING, ha,
827 "Command is NULL: already returned to OS (sp=%p)\n", sp);
829 return;
832 lscsi_status = scsi_status & STATUS_MASK;
833 CMD_ENTRY_STATUS(cp) = sts->entry_status;
834 CMD_COMPL_STATUS(cp) = comp_status;
835 CMD_SCSI_STATUS(cp) = scsi_status;
837 fcport = sp->fcport;
839 sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
840 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
841 sense_len = le32_to_cpu(sts24->sense_len);
842 rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
843 resid_len = le32_to_cpu(sts24->rsp_residual_count);
844 fw_resid_len = le32_to_cpu(sts24->residual_len);
845 rsp_info = sts24->data;
846 sense_data = sts24->data;
847 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
848 } else {
849 sense_len = le16_to_cpu(sts->req_sense_length);
850 rsp_info_len = le16_to_cpu(sts->rsp_info_len);
851 resid_len = le32_to_cpu(sts->residual_length);
852 rsp_info = sts->rsp_info;
853 sense_data = sts->req_sense_data;
856 /* Check for any FCP transport errors. */
857 if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
858 /* Sense data lies beyond any FCP RESPONSE data. */
859 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
860 sense_data += rsp_info_len;
861 if (rsp_info_len > 3 && rsp_info[3]) {
862 DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
863 "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
864 "retrying command\n", ha->host_no,
865 cp->device->channel, cp->device->id,
866 cp->device->lun, rsp_info_len, rsp_info[0],
867 rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
868 rsp_info[5], rsp_info[6], rsp_info[7]));
870 cp->result = DID_BUS_BUSY << 16;
871 qla2x00_sp_compl(ha, sp);
872 return;
877 * Based on Host and scsi status generate status code for Linux
879 switch (comp_status) {
880 case CS_COMPLETE:
881 case CS_QUEUE_FULL:
882 if (scsi_status == 0) {
883 cp->result = DID_OK << 16;
884 break;
886 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
887 resid = resid_len;
888 cp->resid = resid;
889 CMD_RESID_LEN(cp) = resid;
891 if (!lscsi_status &&
892 ((unsigned)(cp->request_bufflen - resid) <
893 cp->underflow)) {
894 qla_printk(KERN_INFO, ha,
895 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
896 "detected (%x of %x bytes)...returning "
897 "error status.\n", ha->host_no,
898 cp->device->channel, cp->device->id,
899 cp->device->lun, resid,
900 cp->request_bufflen);
902 cp->result = DID_ERROR << 16;
903 break;
906 cp->result = DID_OK << 16 | lscsi_status;
908 if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
909 DEBUG2(printk(KERN_INFO
910 "scsi(%ld): QUEUE FULL status detected "
911 "0x%x-0x%x.\n", ha->host_no, comp_status,
912 scsi_status));
914 /* Adjust queue depth for all luns on the port. */
915 fcport->last_queue_full = jiffies;
916 starget_for_each_device(cp->device->sdev_target,
917 fcport, qla2x00_adjust_sdev_qdepth_down);
918 break;
920 if (lscsi_status != SS_CHECK_CONDITION)
921 break;
923 /* Copy Sense Data into sense buffer. */
924 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
926 if (!(scsi_status & SS_SENSE_LEN_VALID))
927 break;
929 if (sense_len >= sizeof(cp->sense_buffer))
930 sense_len = sizeof(cp->sense_buffer);
932 CMD_ACTUAL_SNSLEN(cp) = sense_len;
933 sp->request_sense_length = sense_len;
934 sp->request_sense_ptr = cp->sense_buffer;
936 if (sp->request_sense_length > 32)
937 sense_len = 32;
939 memcpy(cp->sense_buffer, sense_data, sense_len);
941 sp->request_sense_ptr += sense_len;
942 sp->request_sense_length -= sense_len;
943 if (sp->request_sense_length != 0)
944 ha->status_srb = sp;
946 DEBUG5(printk("%s(): Check condition Sense data, "
947 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__,
948 ha->host_no, cp->device->channel, cp->device->id,
949 cp->device->lun, cp, cp->serial_number));
950 if (sense_len)
951 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
952 CMD_ACTUAL_SNSLEN(cp)));
953 break;
955 case CS_DATA_UNDERRUN:
956 resid = resid_len;
957 /* Use F/W calculated residual length. */
958 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
959 resid = fw_resid_len;
961 if (scsi_status & SS_RESIDUAL_UNDER) {
962 cp->resid = resid;
963 CMD_RESID_LEN(cp) = resid;
964 } else {
965 DEBUG2(printk(KERN_INFO
966 "scsi(%ld:%d:%d) UNDERRUN status detected "
967 "0x%x-0x%x. resid=0x%x fw_resid=0x%x cdb=0x%x "
968 "os_underflow=0x%x\n", ha->host_no,
969 cp->device->id, cp->device->lun, comp_status,
970 scsi_status, resid_len, resid, cp->cmnd[0],
971 cp->underflow));
976 * Check to see if SCSI Status is non zero. If so report SCSI
977 * Status.
979 if (lscsi_status != 0) {
980 cp->result = DID_OK << 16 | lscsi_status;
982 if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
983 DEBUG2(printk(KERN_INFO
984 "scsi(%ld): QUEUE FULL status detected "
985 "0x%x-0x%x.\n", ha->host_no, comp_status,
986 scsi_status));
989 * Adjust queue depth for all luns on the
990 * port.
992 fcport->last_queue_full = jiffies;
993 starget_for_each_device(
994 cp->device->sdev_target, fcport,
995 qla2x00_adjust_sdev_qdepth_down);
996 break;
998 if (lscsi_status != SS_CHECK_CONDITION)
999 break;
1001 /* Copy Sense Data into sense buffer */
1002 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
1004 if (!(scsi_status & SS_SENSE_LEN_VALID))
1005 break;
1007 if (sense_len >= sizeof(cp->sense_buffer))
1008 sense_len = sizeof(cp->sense_buffer);
1010 CMD_ACTUAL_SNSLEN(cp) = sense_len;
1011 sp->request_sense_length = sense_len;
1012 sp->request_sense_ptr = cp->sense_buffer;
1014 if (sp->request_sense_length > 32)
1015 sense_len = 32;
1017 memcpy(cp->sense_buffer, sense_data, sense_len);
1019 sp->request_sense_ptr += sense_len;
1020 sp->request_sense_length -= sense_len;
1021 if (sp->request_sense_length != 0)
1022 ha->status_srb = sp;
1024 DEBUG5(printk("%s(): Check condition Sense data, "
1025 "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
1026 __func__, ha->host_no, cp->device->channel,
1027 cp->device->id, cp->device->lun, cp,
1028 cp->serial_number));
1030 if (sense_len)
1031 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1032 CMD_ACTUAL_SNSLEN(cp)));
1033 } else {
1035 * If RISC reports underrun and target does not report
1036 * it then we must have a lost frame, so tell upper
1037 * layer to retry it by reporting a bus busy.
1039 if (!(scsi_status & SS_RESIDUAL_UNDER)) {
1040 DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
1041 "frame(s) detected (%x of %x bytes)..."
1042 "retrying command.\n", ha->host_no,
1043 cp->device->channel, cp->device->id,
1044 cp->device->lun, resid,
1045 cp->request_bufflen));
1047 cp->result = DID_BUS_BUSY << 16;
1048 break;
1051 /* Handle mid-layer underflow */
1052 if ((unsigned)(cp->request_bufflen - resid) <
1053 cp->underflow) {
1054 qla_printk(KERN_INFO, ha,
1055 "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1056 "detected (%x of %x bytes)...returning "
1057 "error status.\n", ha->host_no,
1058 cp->device->channel, cp->device->id,
1059 cp->device->lun, resid,
1060 cp->request_bufflen);
1062 cp->result = DID_ERROR << 16;
1063 break;
1066 /* Everybody online, looking good... */
1067 cp->result = DID_OK << 16;
1069 break;
1071 case CS_DATA_OVERRUN:
1072 DEBUG2(printk(KERN_INFO
1073 "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
1074 ha->host_no, cp->device->id, cp->device->lun, comp_status,
1075 scsi_status));
1076 DEBUG2(printk(KERN_INFO
1077 "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1078 cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
1079 cp->cmnd[4], cp->cmnd[5]));
1080 DEBUG2(printk(KERN_INFO
1081 "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1082 "status!\n",
1083 cp->serial_number, cp->request_bufflen, resid_len));
1085 cp->result = DID_ERROR << 16;
1086 break;
1088 case CS_PORT_LOGGED_OUT:
1089 case CS_PORT_CONFIG_CHG:
1090 case CS_PORT_BUSY:
1091 case CS_INCOMPLETE:
1092 case CS_PORT_UNAVAILABLE:
1094 * If the port is in Target Down state, return all IOs for this
1095 * Target with DID_NO_CONNECT ELSE Queue the IOs in the
1096 * retry_queue.
1098 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1099 "pid=%ld, compl status=0x%x, port state=0x%x\n",
1100 ha->host_no, cp->device->id, cp->device->lun,
1101 cp->serial_number, comp_status,
1102 atomic_read(&fcport->state)));
1104 cp->result = DID_BUS_BUSY << 16;
1105 if (atomic_read(&fcport->state) == FCS_ONLINE) {
1106 qla2x00_mark_device_lost(ha, fcport, 1, 1);
1108 break;
1110 case CS_RESET:
1111 DEBUG2(printk(KERN_INFO
1112 "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
1113 ha->host_no, comp_status, scsi_status));
1115 cp->result = DID_RESET << 16;
1116 break;
1118 case CS_ABORTED:
1120 * hv2.19.12 - DID_ABORT does not retry the request if we
1121 * aborted this request then abort otherwise it must be a
1122 * reset.
1124 DEBUG2(printk(KERN_INFO
1125 "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
1126 ha->host_no, comp_status, scsi_status));
1128 cp->result = DID_RESET << 16;
1129 break;
1131 case CS_TIMEOUT:
1132 cp->result = DID_BUS_BUSY << 16;
1134 if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
1135 DEBUG2(printk(KERN_INFO
1136 "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
1137 "0x%x-0x%x\n", ha->host_no, cp->device->channel,
1138 cp->device->id, cp->device->lun, comp_status,
1139 scsi_status));
1140 break;
1142 DEBUG2(printk(KERN_INFO
1143 "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
1144 "sflags=%x.\n", ha->host_no, cp->device->channel,
1145 cp->device->id, cp->device->lun, comp_status, scsi_status,
1146 le16_to_cpu(sts->status_flags)));
1148 /* Check to see if logout occurred. */
1149 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
1150 qla2x00_mark_device_lost(ha, fcport, 1, 1);
1151 break;
1153 default:
1154 DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
1155 "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
1156 qla_printk(KERN_INFO, ha,
1157 "Unknown status detected 0x%x-0x%x.\n",
1158 comp_status, scsi_status);
1160 cp->result = DID_ERROR << 16;
1161 break;
1164 /* Place command on done queue. */
1165 if (ha->status_srb == NULL)
1166 qla2x00_sp_compl(ha, sp);
1170 * qla2x00_status_cont_entry() - Process a Status Continuations entry.
1171 * @ha: SCSI driver HA context
1172 * @pkt: Entry pointer
1174 * Extended sense data.
1176 static void
1177 qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1179 uint8_t sense_sz = 0;
1180 srb_t *sp = ha->status_srb;
1181 struct scsi_cmnd *cp;
1183 if (sp != NULL && sp->request_sense_length != 0) {
1184 cp = sp->cmd;
1185 if (cp == NULL) {
1186 DEBUG2(printk("%s(): Cmd already returned back to OS "
1187 "sp=%p.\n", __func__, sp));
1188 qla_printk(KERN_INFO, ha,
1189 "cmd is NULL: already returned to OS (sp=%p)\n",
1190 sp);
1192 ha->status_srb = NULL;
1193 return;
1196 if (sp->request_sense_length > sizeof(pkt->data)) {
1197 sense_sz = sizeof(pkt->data);
1198 } else {
1199 sense_sz = sp->request_sense_length;
1202 /* Move sense data. */
1203 if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
1204 host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1205 memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1206 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1208 sp->request_sense_ptr += sense_sz;
1209 sp->request_sense_length -= sense_sz;
1211 /* Place command on done queue. */
1212 if (sp->request_sense_length == 0) {
1213 ha->status_srb = NULL;
1214 qla2x00_sp_compl(ha, sp);
1220 * qla2x00_error_entry() - Process an error entry.
1221 * @ha: SCSI driver HA context
1222 * @pkt: Entry pointer
1224 static void
1225 qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1227 srb_t *sp;
1229 #if defined(QL_DEBUG_LEVEL_2)
1230 if (pkt->entry_status & RF_INV_E_ORDER)
1231 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
1232 else if (pkt->entry_status & RF_INV_E_COUNT)
1233 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
1234 else if (pkt->entry_status & RF_INV_E_PARAM)
1235 qla_printk(KERN_ERR, ha,
1236 "%s: Invalid Entry Parameter\n", __func__);
1237 else if (pkt->entry_status & RF_INV_E_TYPE)
1238 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
1239 else if (pkt->entry_status & RF_BUSY)
1240 qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);
1241 else
1242 qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);
1243 #endif
1245 /* Validate handle. */
1246 if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1247 sp = ha->outstanding_cmds[pkt->handle];
1248 else
1249 sp = NULL;
1251 if (sp) {
1252 /* Free outstanding command slot. */
1253 ha->outstanding_cmds[pkt->handle] = NULL;
1255 /* Bad payload or header */
1256 if (pkt->entry_status &
1257 (RF_INV_E_ORDER | RF_INV_E_COUNT |
1258 RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1259 sp->cmd->result = DID_ERROR << 16;
1260 } else if (pkt->entry_status & RF_BUSY) {
1261 sp->cmd->result = DID_BUS_BUSY << 16;
1262 } else {
1263 sp->cmd->result = DID_ERROR << 16;
1265 qla2x00_sp_compl(ha, sp);
1267 } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1268 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
1269 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
1270 ha->host_no));
1271 qla_printk(KERN_WARNING, ha,
1272 "Error entry - invalid handle\n");
1274 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1275 qla2xxx_wake_dpc(ha);
1280 * qla2x00_ms_entry() - Process a Management Server entry.
1281 * @ha: SCSI driver HA context
1282 * @index: Response queue out pointer
1284 static void
1285 qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
1287 srb_t *sp;
1289 DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1290 __func__, ha->host_no, pkt, pkt->handle1));
1292 /* Validate handle. */
1293 if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
1294 sp = ha->outstanding_cmds[pkt->handle1];
1295 else
1296 sp = NULL;
1298 if (sp == NULL) {
1299 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1300 ha->host_no));
1301 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
1303 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1304 return;
1307 CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
1308 CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1310 /* Free outstanding command slot. */
1311 ha->outstanding_cmds[pkt->handle1] = NULL;
1313 qla2x00_sp_compl(ha, sp);
1318 * qla24xx_mbx_completion() - Process mailbox command completions.
1319 * @ha: SCSI driver HA context
1320 * @mb0: Mailbox0 register
1322 static void
1323 qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
1325 uint16_t cnt;
1326 uint16_t __iomem *wptr;
1327 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1329 /* Load return mailbox registers. */
1330 ha->flags.mbox_int = 1;
1331 ha->mailbox_out[0] = mb0;
1332 wptr = (uint16_t __iomem *)&reg->mailbox1;
1334 for (cnt = 1; cnt < ha->mbx_count; cnt++) {
1335 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
1336 wptr++;
1339 if (ha->mcp) {
1340 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
1341 __func__, ha->host_no, ha->mcp->mb[0]));
1342 } else {
1343 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
1344 __func__, ha->host_no));
1349 * qla24xx_process_response_queue() - Process response queue entries.
1350 * @ha: SCSI driver HA context
1352 void
1353 qla24xx_process_response_queue(struct scsi_qla_host *ha)
1355 struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1356 struct sts_entry_24xx *pkt;
1358 if (!ha->flags.online)
1359 return;
1361 while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
1362 pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
1364 ha->rsp_ring_index++;
1365 if (ha->rsp_ring_index == ha->response_q_length) {
1366 ha->rsp_ring_index = 0;
1367 ha->response_ring_ptr = ha->response_ring;
1368 } else {
1369 ha->response_ring_ptr++;
1372 if (pkt->entry_status != 0) {
1373 DEBUG3(printk(KERN_INFO
1374 "scsi(%ld): Process error entry.\n", ha->host_no));
1376 qla2x00_error_entry(ha, (sts_entry_t *) pkt);
1377 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1378 wmb();
1379 continue;
1382 switch (pkt->entry_type) {
1383 case STATUS_TYPE:
1384 qla2x00_status_entry(ha, pkt);
1385 break;
1386 case STATUS_CONT_TYPE:
1387 qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
1388 break;
1389 case MS_IOCB_TYPE:
1390 qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
1391 break;
1392 default:
1393 /* Type Not Supported. */
1394 DEBUG4(printk(KERN_WARNING
1395 "scsi(%ld): Received unknown response pkt type %x "
1396 "entry status=%x.\n",
1397 ha->host_no, pkt->entry_type, pkt->entry_status));
1398 break;
1400 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1401 wmb();
1404 /* Adjust ring index */
1405 WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
1409 * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
1410 * @irq:
1411 * @dev_id: SCSI driver HA context
1413 * Called by system whenever the host adapter generates an interrupt.
1415 * Returns handled flag.
1417 irqreturn_t
1418 qla24xx_intr_handler(int irq, void *dev_id)
1420 scsi_qla_host_t *ha;
1421 struct device_reg_24xx __iomem *reg;
1422 int status;
1423 unsigned long flags;
1424 unsigned long iter;
1425 uint32_t stat;
1426 uint32_t hccr;
1427 uint16_t mb[4];
1429 ha = (scsi_qla_host_t *) dev_id;
1430 if (!ha) {
1431 printk(KERN_INFO
1432 "%s(): NULL host pointer\n", __func__);
1433 return IRQ_NONE;
1436 reg = &ha->iobase->isp24;
1437 status = 0;
1439 spin_lock_irqsave(&ha->hardware_lock, flags);
1440 for (iter = 50; iter--; ) {
1441 stat = RD_REG_DWORD(&reg->host_status);
1442 if (stat & HSRX_RISC_PAUSED) {
1443 hccr = RD_REG_DWORD(&reg->hccr);
1445 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1446 "Dumping firmware!\n", hccr);
1447 qla24xx_fw_dump(ha, 1);
1449 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1450 break;
1451 } else if ((stat & HSRX_RISC_INT) == 0)
1452 break;
1454 switch (stat & 0xff) {
1455 case 0x1:
1456 case 0x2:
1457 case 0x10:
1458 case 0x11:
1459 qla24xx_mbx_completion(ha, MSW(stat));
1460 status |= MBX_INTERRUPT;
1462 break;
1463 case 0x12:
1464 mb[0] = MSW(stat);
1465 mb[1] = RD_REG_WORD(&reg->mailbox1);
1466 mb[2] = RD_REG_WORD(&reg->mailbox2);
1467 mb[3] = RD_REG_WORD(&reg->mailbox3);
1468 qla2x00_async_event(ha, mb);
1469 break;
1470 case 0x13:
1471 qla24xx_process_response_queue(ha);
1472 break;
1473 default:
1474 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1475 "(%d).\n",
1476 ha->host_no, stat & 0xff));
1477 break;
1479 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1480 RD_REG_DWORD_RELAXED(&reg->hccr);
1482 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1484 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1485 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1486 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1487 up(&ha->mbx_intr_sem);
1490 return IRQ_HANDLED;
1494 * qla24xx_ms_entry() - Process a Management Server entry.
1495 * @ha: SCSI driver HA context
1496 * @index: Response queue out pointer
1498 static void
1499 qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
1501 srb_t *sp;
1503 DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1504 __func__, ha->host_no, pkt, pkt->handle));
1506 DEBUG9(printk("%s: ct pkt dump:\n", __func__));
1507 DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx)));
1509 /* Validate handle. */
1510 if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1511 sp = ha->outstanding_cmds[pkt->handle];
1512 else
1513 sp = NULL;
1515 if (sp == NULL) {
1516 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1517 ha->host_no));
1518 DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
1519 ha->host_no));
1520 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
1521 pkt->handle);
1523 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1524 return;
1527 CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
1528 CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1530 /* Free outstanding command slot. */
1531 ha->outstanding_cmds[pkt->handle] = NULL;
1533 qla2x00_sp_compl(ha, sp);
1536 static irqreturn_t
1537 qla24xx_msix_rsp_q(int irq, void *dev_id)
1539 scsi_qla_host_t *ha;
1540 struct device_reg_24xx __iomem *reg;
1541 unsigned long flags;
1543 ha = dev_id;
1544 reg = &ha->iobase->isp24;
1546 spin_lock_irqsave(&ha->hardware_lock, flags);
1548 qla24xx_process_response_queue(ha);
1550 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1551 RD_REG_DWORD_RELAXED(&reg->hccr);
1553 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1555 return IRQ_HANDLED;
1558 static irqreturn_t
1559 qla24xx_msix_default(int irq, void *dev_id)
1561 scsi_qla_host_t *ha;
1562 struct device_reg_24xx __iomem *reg;
1563 int status;
1564 unsigned long flags;
1565 unsigned long iter;
1566 uint32_t stat;
1567 uint32_t hccr;
1568 uint16_t mb[4];
1570 ha = dev_id;
1571 reg = &ha->iobase->isp24;
1572 status = 0;
1574 spin_lock_irqsave(&ha->hardware_lock, flags);
1575 for (iter = 50; iter--; ) {
1576 stat = RD_REG_DWORD(&reg->host_status);
1577 if (stat & HSRX_RISC_PAUSED) {
1578 hccr = RD_REG_DWORD(&reg->hccr);
1580 qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1581 "Dumping firmware!\n", hccr);
1582 ha->isp_ops.fw_dump(ha, 1);
1583 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1584 break;
1585 } else if ((stat & HSRX_RISC_INT) == 0)
1586 break;
1588 switch (stat & 0xff) {
1589 case 0x1:
1590 case 0x2:
1591 case 0x10:
1592 case 0x11:
1593 qla24xx_mbx_completion(ha, MSW(stat));
1594 status |= MBX_INTERRUPT;
1596 break;
1597 case 0x12:
1598 mb[0] = MSW(stat);
1599 mb[1] = RD_REG_WORD(&reg->mailbox1);
1600 mb[2] = RD_REG_WORD(&reg->mailbox2);
1601 mb[3] = RD_REG_WORD(&reg->mailbox3);
1602 qla2x00_async_event(ha, mb);
1603 break;
1604 case 0x13:
1605 qla24xx_process_response_queue(ha);
1606 break;
1607 default:
1608 DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1609 "(%d).\n",
1610 ha->host_no, stat & 0xff));
1611 break;
1613 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1614 RD_REG_DWORD_RELAXED(&reg->hccr);
1616 spin_unlock_irqrestore(&ha->hardware_lock, flags);
1618 if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1619 (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1620 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1621 up(&ha->mbx_intr_sem);
1624 return IRQ_HANDLED;
1627 /* Interrupt handling helpers. */
1629 struct qla_init_msix_entry {
1630 uint16_t entry;
1631 uint16_t index;
1632 const char *name;
1633 irqreturn_t (*handler)(int, void *);
1636 static struct qla_init_msix_entry imsix_entries[QLA_MSIX_ENTRIES] = {
1637 { QLA_MSIX_DEFAULT, QLA_MIDX_DEFAULT,
1638 "qla2xxx (default)", qla24xx_msix_default },
1640 { QLA_MSIX_RSP_Q, QLA_MIDX_RSP_Q,
1641 "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
1644 static void
1645 qla24xx_disable_msix(scsi_qla_host_t *ha)
1647 int i;
1648 struct qla_msix_entry *qentry;
1650 for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
1651 qentry = &ha->msix_entries[imsix_entries[i].index];
1652 if (qentry->have_irq)
1653 free_irq(qentry->msix_vector, ha);
1655 pci_disable_msix(ha->pdev);
1658 static int
1659 qla24xx_enable_msix(scsi_qla_host_t *ha)
1661 int i, ret;
1662 struct msix_entry entries[QLA_MSIX_ENTRIES];
1663 struct qla_msix_entry *qentry;
1665 for (i = 0; i < QLA_MSIX_ENTRIES; i++)
1666 entries[i].entry = imsix_entries[i].entry;
1668 ret = pci_enable_msix(ha->pdev, entries, ARRAY_SIZE(entries));
1669 if (ret) {
1670 qla_printk(KERN_WARNING, ha,
1671 "MSI-X: Failed to enable support -- %d/%d\n",
1672 QLA_MSIX_ENTRIES, ret);
1673 goto msix_out;
1675 ha->flags.msix_enabled = 1;
1677 for (i = 0; i < QLA_MSIX_ENTRIES; i++) {
1678 qentry = &ha->msix_entries[imsix_entries[i].index];
1679 qentry->msix_vector = entries[i].vector;
1680 qentry->msix_entry = entries[i].entry;
1681 qentry->have_irq = 0;
1682 ret = request_irq(qentry->msix_vector,
1683 imsix_entries[i].handler, 0, imsix_entries[i].name, ha);
1684 if (ret) {
1685 qla_printk(KERN_WARNING, ha,
1686 "MSI-X: Unable to register handler -- %x/%d.\n",
1687 imsix_entries[i].index, ret);
1688 qla24xx_disable_msix(ha);
1689 goto msix_out;
1691 qentry->have_irq = 1;
1694 msix_out:
1695 return ret;
1699 qla2x00_request_irqs(scsi_qla_host_t *ha)
1701 int ret;
1703 /* If possible, enable MSI-X. */
1704 if (!IS_QLA2432(ha))
1705 goto skip_msix;
1707 if (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
1708 !QLA_MSIX_FW_MODE_1(ha->fw_attributes)) {
1709 DEBUG2(qla_printk(KERN_WARNING, ha,
1710 "MSI-X: Unsupported ISP2432 (0x%X, 0x%X).\n",
1711 ha->chip_revision, ha->fw_attributes));
1713 goto skip_msix;
1716 ret = qla24xx_enable_msix(ha);
1717 if (!ret) {
1718 DEBUG2(qla_printk(KERN_INFO, ha,
1719 "MSI-X: Enabled (0x%X, 0x%X).\n", ha->chip_revision,
1720 ha->fw_attributes));
1721 return ret;
1723 qla_printk(KERN_WARNING, ha,
1724 "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
1725 skip_msix:
1726 ret = request_irq(ha->pdev->irq, ha->isp_ops.intr_handler,
1727 IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, ha);
1728 if (!ret) {
1729 ha->flags.inta_enabled = 1;
1730 ha->host->irq = ha->pdev->irq;
1731 } else {
1732 qla_printk(KERN_WARNING, ha,
1733 "Failed to reserve interrupt %d already in use.\n",
1734 ha->pdev->irq);
1737 return ret;
1740 void
1741 qla2x00_free_irqs(scsi_qla_host_t *ha)
1744 if (ha->flags.msix_enabled)
1745 qla24xx_disable_msix(ha);
1746 else if (ha->flags.inta_enabled)
1747 free_irq(ha->host->irq, ha);