Merge with /shiny/git/linux-2.6/.git
[linux-2.6] / drivers / scsi / qla2xxx / qla_isr.c
1 /*
2  *                  QLOGIC LINUX SOFTWARE
3  *
4  * QLogic ISP2x00 device driver for Linux 2.6.x
5  * Copyright (C) 2003-2005 QLogic Corporation
6  * (www.qlogic.com)
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2, or (at your option) any
11  * later version.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  */
19 #include "qla_def.h"
20
21 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
22 static void qla2x00_async_event(scsi_qla_host_t *, uint16_t *);
23 static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
24 void qla2x00_process_response_queue(struct scsi_qla_host *);
25 static void qla2x00_status_entry(scsi_qla_host_t *, void *);
26 static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
27 static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
28 static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
29
30 void qla24xx_process_response_queue(scsi_qla_host_t *);
31 static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
32
33 /**
34  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
35  * @irq:
36  * @dev_id: SCSI driver HA context
37  * @regs:
38  *
39  * Called by system whenever the host adapter generates an interrupt.
40  *
41  * Returns handled flag.
42  */
43 irqreturn_t
44 qla2100_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
45 {
46         scsi_qla_host_t *ha;
47         struct device_reg_2xxx __iomem *reg;
48         int             status;
49         unsigned long   flags;
50         unsigned long   iter;
51         uint16_t        mb[4];
52
53         ha = (scsi_qla_host_t *) dev_id;
54         if (!ha) {
55                 printk(KERN_INFO
56                     "%s(): NULL host pointer\n", __func__);
57                 return (IRQ_NONE);
58         }
59
60         reg = &ha->iobase->isp;
61         status = 0;
62
63         spin_lock_irqsave(&ha->hardware_lock, flags);
64         for (iter = 50; iter--; ) {
65                 if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
66                         break;
67
68                 if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
69                         WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
70                         RD_REG_WORD(&reg->hccr);
71
72                         /* Get mailbox data. */
73                         mb[0] = RD_MAILBOX_REG(ha, reg, 0);
74                         if (mb[0] > 0x3fff && mb[0] < 0x8000) {
75                                 qla2x00_mbx_completion(ha, mb[0]);
76                                 status |= MBX_INTERRUPT;
77                         } else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
78                                 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
79                                 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
80                                 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
81                                 qla2x00_async_event(ha, mb);
82                         } else {
83                                 /*EMPTY*/
84                                 DEBUG2(printk("scsi(%ld): Unrecognized "
85                                     "interrupt type (%d).\n",
86                                     ha->host_no, mb[0]));
87                         }
88                         /* Release mailbox registers. */
89                         WRT_REG_WORD(&reg->semaphore, 0);
90                         RD_REG_WORD(&reg->semaphore);
91                 } else {
92                         qla2x00_process_response_queue(ha);
93
94                         WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
95                         RD_REG_WORD(&reg->hccr);
96                 }
97         }
98         spin_unlock_irqrestore(&ha->hardware_lock, flags);
99
100         if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
101             (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
102                 spin_lock_irqsave(&ha->mbx_reg_lock, flags);
103
104                 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
105                 up(&ha->mbx_intr_sem);
106
107                 spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
108         }
109
110         return (IRQ_HANDLED);
111 }
112
113 /**
114  * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
115  * @irq:
116  * @dev_id: SCSI driver HA context
117  * @regs:
118  *
119  * Called by system whenever the host adapter generates an interrupt.
120  *
121  * Returns handled flag.
122  */
123 irqreturn_t
124 qla2300_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
125 {
126         scsi_qla_host_t *ha;
127         struct device_reg_2xxx __iomem *reg;
128         int             status;
129         unsigned long   flags;
130         unsigned long   iter;
131         uint32_t        stat;
132         uint16_t        hccr;
133         uint16_t        mb[4];
134
135         ha = (scsi_qla_host_t *) dev_id;
136         if (!ha) {
137                 printk(KERN_INFO
138                     "%s(): NULL host pointer\n", __func__);
139                 return (IRQ_NONE);
140         }
141
142         reg = &ha->iobase->isp;
143         status = 0;
144
145         spin_lock_irqsave(&ha->hardware_lock, flags);
146         for (iter = 50; iter--; ) {
147                 stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
148                 if (stat & HSR_RISC_PAUSED) {
149                         hccr = RD_REG_WORD(&reg->hccr);
150                         if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
151                                 qla_printk(KERN_INFO, ha,
152                                     "Parity error -- HCCR=%x.\n", hccr);
153                         else
154                                 qla_printk(KERN_INFO, ha,
155                                     "RISC paused -- HCCR=%x.\n", hccr);
156
157                         /*
158                          * Issue a "HARD" reset in order for the RISC
159                          * interrupt bit to be cleared.  Schedule a big
160                          * hammmer to get out of the RISC PAUSED state.
161                          */
162                         WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
163                         RD_REG_WORD(&reg->hccr);
164                         set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
165                         break;
166                 } else if ((stat & HSR_RISC_INT) == 0)
167                         break;
168
169                 switch (stat & 0xff) {
170                 case 0x1:
171                 case 0x2:
172                 case 0x10:
173                 case 0x11:
174                         qla2x00_mbx_completion(ha, MSW(stat));
175                         status |= MBX_INTERRUPT;
176
177                         /* Release mailbox registers. */
178                         WRT_REG_WORD(&reg->semaphore, 0);
179                         break;
180                 case 0x12:
181                         mb[0] = MSW(stat);
182                         mb[1] = RD_MAILBOX_REG(ha, reg, 1);
183                         mb[2] = RD_MAILBOX_REG(ha, reg, 2);
184                         mb[3] = RD_MAILBOX_REG(ha, reg, 3);
185                         qla2x00_async_event(ha, mb);
186                         break;
187                 case 0x13:
188                         qla2x00_process_response_queue(ha);
189                         break;
190                 case 0x15:
191                         mb[0] = MBA_CMPLT_1_16BIT;
192                         mb[1] = MSW(stat);
193                         qla2x00_async_event(ha, mb);
194                         break;
195                 case 0x16:
196                         mb[0] = MBA_SCSI_COMPLETION;
197                         mb[1] = MSW(stat);
198                         mb[2] = RD_MAILBOX_REG(ha, reg, 2);
199                         qla2x00_async_event(ha, mb);
200                         break;
201                 default:
202                         DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
203                             "(%d).\n",
204                             ha->host_no, stat & 0xff));
205                         break;
206                 }
207                 WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
208                 RD_REG_WORD_RELAXED(&reg->hccr);
209         }
210         spin_unlock_irqrestore(&ha->hardware_lock, flags);
211
212         if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
213             (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
214                 spin_lock_irqsave(&ha->mbx_reg_lock, flags);
215
216                 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
217                 up(&ha->mbx_intr_sem);
218
219                 spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
220         }
221
222         return (IRQ_HANDLED);
223 }
224
225 /**
226  * qla2x00_mbx_completion() - Process mailbox command completions.
227  * @ha: SCSI driver HA context
228  * @mb0: Mailbox0 register
229  */
230 static void
231 qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
232 {
233         uint16_t        cnt;
234         uint16_t __iomem *wptr;
235         struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
236
237         /* Load return mailbox registers. */
238         ha->flags.mbox_int = 1;
239         ha->mailbox_out[0] = mb0;
240         wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
241
242         for (cnt = 1; cnt < ha->mbx_count; cnt++) {
243                 if (IS_QLA2200(ha) && cnt == 8)
244                         wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
245                 if (cnt == 4 || cnt == 5)
246                         ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
247                 else
248                         ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
249
250                 wptr++;
251         }
252
253         if (ha->mcp) {
254                 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
255                     __func__, ha->host_no, ha->mcp->mb[0]));
256         } else {
257                 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
258                     __func__, ha->host_no));
259         }
260 }
261
262 /**
263  * qla2x00_async_event() - Process aynchronous events.
264  * @ha: SCSI driver HA context
265  * @mb: Mailbox registers (0 - 3)
266  */
267 static void
268 qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
269 {
270 #define LS_UNKNOWN      2
271         static char     *link_speeds[5] = { "1", "2", "?", "4", "10" };
272         char            *link_speed;
273         uint16_t        handle_cnt;
274         uint16_t        cnt;
275         uint32_t        handles[5];
276         struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
277         uint32_t        rscn_entry, host_pid;
278         uint8_t         rscn_queue_index;
279
280         /* Setup to process RIO completion. */
281         handle_cnt = 0;
282         switch (mb[0]) {
283         case MBA_SCSI_COMPLETION:
284                 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
285                 handle_cnt = 1;
286                 break;
287         case MBA_CMPLT_1_16BIT:
288                 handles[0] = mb[1];
289                 handle_cnt = 1;
290                 mb[0] = MBA_SCSI_COMPLETION;
291                 break;
292         case MBA_CMPLT_2_16BIT:
293                 handles[0] = mb[1];
294                 handles[1] = mb[2];
295                 handle_cnt = 2;
296                 mb[0] = MBA_SCSI_COMPLETION;
297                 break;
298         case MBA_CMPLT_3_16BIT:
299                 handles[0] = mb[1];
300                 handles[1] = mb[2];
301                 handles[2] = mb[3];
302                 handle_cnt = 3;
303                 mb[0] = MBA_SCSI_COMPLETION;
304                 break;
305         case MBA_CMPLT_4_16BIT:
306                 handles[0] = mb[1];
307                 handles[1] = mb[2];
308                 handles[2] = mb[3];
309                 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
310                 handle_cnt = 4;
311                 mb[0] = MBA_SCSI_COMPLETION;
312                 break;
313         case MBA_CMPLT_5_16BIT:
314                 handles[0] = mb[1];
315                 handles[1] = mb[2];
316                 handles[2] = mb[3];
317                 handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
318                 handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
319                 handle_cnt = 5;
320                 mb[0] = MBA_SCSI_COMPLETION;
321                 break;
322         case MBA_CMPLT_2_32BIT:
323                 handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
324                 handles[1] = le32_to_cpu(
325                     ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
326                     RD_MAILBOX_REG(ha, reg, 6));
327                 handle_cnt = 2;
328                 mb[0] = MBA_SCSI_COMPLETION;
329                 break;
330         default:
331                 break;
332         }
333
334         switch (mb[0]) {
335         case MBA_SCSI_COMPLETION:       /* Fast Post */
336                 if (!ha->flags.online)
337                         break;
338
339                 for (cnt = 0; cnt < handle_cnt; cnt++)
340                         qla2x00_process_completed_request(ha, handles[cnt]);
341                 break;
342
343         case MBA_RESET:                 /* Reset */
344                 DEBUG2(printk("scsi(%ld): Asynchronous RESET.\n", ha->host_no));
345
346                 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
347                 break;
348
349         case MBA_SYSTEM_ERR:            /* System Error */
350                 mb[1] = RD_MAILBOX_REG(ha, reg, 1);
351                 mb[2] = RD_MAILBOX_REG(ha, reg, 2);
352                 mb[3] = RD_MAILBOX_REG(ha, reg, 3);
353
354                 qla_printk(KERN_INFO, ha,
355                     "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
356                     mb[1], mb[2], mb[3]);
357
358                 ha->isp_ops.fw_dump(ha, 1);
359
360                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
361                         if (mb[1] == 0 && mb[2] == 0) {
362                                 qla_printk(KERN_ERR, ha,
363                                     "Unrecoverable Hardware Error: adapter "
364                                     "marked OFFLINE!\n");
365                                 ha->flags.online = 0;
366                         } else
367                                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
368                 } else if (mb[1] == 0) {
369                         qla_printk(KERN_INFO, ha,
370                             "Unrecoverable Hardware Error: adapter marked "
371                             "OFFLINE!\n");
372                         ha->flags.online = 0;
373                 } else
374                         set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
375                 break;
376
377         case MBA_REQ_TRANSFER_ERR:      /* Request Transfer Error */
378                 DEBUG2(printk("scsi(%ld): ISP Request Transfer Error.\n",
379                     ha->host_no));
380                 qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
381
382                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
383                 break;
384
385         case MBA_RSP_TRANSFER_ERR:      /* Response Transfer Error */
386                 DEBUG2(printk("scsi(%ld): ISP Response Transfer Error.\n",
387                     ha->host_no));
388                 qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
389
390                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
391                 break;
392
393         case MBA_WAKEUP_THRES:          /* Request Queue Wake-up */
394                 DEBUG2(printk("scsi(%ld): Asynchronous WAKEUP_THRES.\n",
395                     ha->host_no));
396                 break;
397
398         case MBA_LIP_OCCURRED:          /* Loop Initialization Procedure */
399                 DEBUG2(printk("scsi(%ld): LIP occured (%x).\n", ha->host_no,
400                     mb[1]));
401                 qla_printk(KERN_INFO, ha, "LIP occured (%x).\n", mb[1]);
402
403                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
404                         atomic_set(&ha->loop_state, LOOP_DOWN);
405                         atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
406                         qla2x00_mark_all_devices_lost(ha);
407                 }
408
409                 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
410
411                 ha->flags.management_server_logged_in = 0;
412
413                 /* Update AEN queue. */
414                 qla2x00_enqueue_aen(ha, MBA_LIP_OCCURRED, NULL);
415
416                 break;
417
418         case MBA_LOOP_UP:               /* Loop Up Event */
419                 ha->link_data_rate = 0;
420                 if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
421                         link_speed = link_speeds[0];
422                 } else {
423                         link_speed = link_speeds[LS_UNKNOWN];
424                         if (mb[1] < 5)
425                                 link_speed = link_speeds[mb[1]];
426                         ha->link_data_rate = mb[1];
427                 }
428
429                 DEBUG2(printk("scsi(%ld): Asynchronous LOOP UP (%s Gbps).\n",
430                     ha->host_no, link_speed));
431                 qla_printk(KERN_INFO, ha, "LOOP UP detected (%s Gbps).\n",
432                     link_speed);
433
434                 ha->flags.management_server_logged_in = 0;
435
436                 /* Update AEN queue. */
437                 qla2x00_enqueue_aen(ha, MBA_LOOP_UP, NULL);
438                 break;
439
440         case MBA_LOOP_DOWN:             /* Loop Down Event */
441                 DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
442                     ha->host_no, mb[1]));
443                 qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
444
445                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
446                         atomic_set(&ha->loop_state, LOOP_DOWN);
447                         atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
448                         ha->device_flags |= DFLG_NO_CABLE;
449                         qla2x00_mark_all_devices_lost(ha);
450                 }
451
452                 ha->flags.management_server_logged_in = 0;
453                 ha->link_data_rate = 0;
454
455                 /* Update AEN queue. */
456                 qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL);
457                 break;
458
459         case MBA_LIP_RESET:             /* LIP reset occurred */
460                 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
461                     ha->host_no, mb[1]));
462                 qla_printk(KERN_INFO, ha,
463                     "LIP reset occured (%x).\n", mb[1]);
464
465                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
466                         atomic_set(&ha->loop_state, LOOP_DOWN);
467                         atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
468                         qla2x00_mark_all_devices_lost(ha);
469                 }
470
471                 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
472
473                 ha->operating_mode = LOOP;
474                 ha->flags.management_server_logged_in = 0;
475
476                 /* Update AEN queue. */
477                 qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
478
479                 break;
480
481         case MBA_POINT_TO_POINT:        /* Point-to-Point */
482                 if (IS_QLA2100(ha))
483                         break;
484
485                 DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n",
486                     ha->host_no));
487
488                 /*
489                  * Until there's a transition from loop down to loop up, treat
490                  * this as loop down only.
491                  */
492                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
493                         atomic_set(&ha->loop_state, LOOP_DOWN);
494                         if (!atomic_read(&ha->loop_down_timer))
495                                 atomic_set(&ha->loop_down_timer,
496                                     LOOP_DOWN_TIME);
497                         qla2x00_mark_all_devices_lost(ha);
498                 }
499
500                 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
501                         set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
502                 }
503                 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
504                 break;
505
506         case MBA_CHG_IN_CONNECTION:     /* Change in connection mode */
507                 if (IS_QLA2100(ha))
508                         break;
509
510                 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
511                     "received.\n",
512                     ha->host_no));
513                 qla_printk(KERN_INFO, ha,
514                     "Configuration change detected: value=%x.\n", mb[1]);
515
516                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
517                         atomic_set(&ha->loop_state, LOOP_DOWN);
518                         if (!atomic_read(&ha->loop_down_timer))
519                                 atomic_set(&ha->loop_down_timer,
520                                     LOOP_DOWN_TIME);
521                         qla2x00_mark_all_devices_lost(ha);
522                 }
523
524                 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
525                 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
526                 break;
527
528         case MBA_PORT_UPDATE:           /* Port database update */
529                 /*
530                  * If a single remote port just logged into (or logged out of)
531                  * us, create a new entry in our rscn fcports list and handle
532                  * the event like an RSCN.
533                  */
534                 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
535                     !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
536                     ha->flags.init_done && mb[1] != 0xffff &&
537                     ((ha->operating_mode == P2P && mb[1] != 0) ||
538                     (ha->operating_mode != P2P && mb[1] !=
539                         SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) {
540                         int rval;
541                         fc_port_t *rscn_fcport;
542
543                         /* Create new fcport for login. */
544                         rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC);
545                         if (rscn_fcport) {
546                                 DEBUG14(printk("scsi(%ld): Port Update -- "
547                                     "creating RSCN fcport %p for %x/%x/%x.\n",
548                                     ha->host_no, rscn_fcport, mb[1], mb[2],
549                                     mb[3]));
550
551                                 rscn_fcport->loop_id = mb[1];
552                                 rscn_fcport->d_id.b24 = INVALID_PORT_ID;
553                                 atomic_set(&rscn_fcport->state,
554                                     FCS_DEVICE_LOST);
555                                 list_add_tail(&rscn_fcport->list,
556                                     &ha->rscn_fcports);
557
558                                 rval = qla2x00_handle_port_rscn(ha, 0,
559                                     rscn_fcport, 1);
560                                 if (rval == QLA_SUCCESS)
561                                         break;
562                         } else {
563                                 DEBUG14(printk("scsi(%ld): Port Update -- "
564                                     "-- unable to allocate RSCN fcport "
565                                     "login.\n", ha->host_no));
566                         }
567                 }
568
569                 /*
570                  * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
571                  * event etc. earlier indicating loop is down) then process
572                  * it.  Otherwise ignore it and Wait for RSCN to come in.
573                  */
574                 atomic_set(&ha->loop_down_timer, 0);
575                 if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
576                     atomic_read(&ha->loop_state) != LOOP_DEAD) {
577                         DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
578                             "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
579                             mb[2], mb[3]));
580                         break;
581                 }
582
583                 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
584                     ha->host_no));
585                 DEBUG(printk(KERN_INFO
586                     "scsi(%ld): Port database changed %04x %04x %04x.\n",
587                     ha->host_no, mb[1], mb[2], mb[3]));
588
589                 /*
590                  * Mark all devices as missing so we will login again.
591                  */
592                 atomic_set(&ha->loop_state, LOOP_UP);
593
594                 qla2x00_mark_all_devices_lost(ha);
595
596                 ha->flags.rscn_queue_overflow = 1;
597
598                 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
599                 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
600
601                 /* Update AEN queue. */
602                 qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL);
603                 break;
604
605         case MBA_RSCN_UPDATE:           /* State Change Registration */
606                 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
607                     ha->host_no));
608                 DEBUG(printk(KERN_INFO
609                     "scsi(%ld): RSCN database changed -- %04x %04x.\n",
610                     ha->host_no, mb[1], mb[2]));
611
612                 rscn_entry = (mb[1] << 16) | mb[2];
613                 host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
614                     ha->d_id.b.al_pa;
615                 if (rscn_entry == host_pid) {
616                         DEBUG(printk(KERN_INFO
617                             "scsi(%ld): Ignoring RSCN update to local host "
618                             "port ID (%06x)\n",
619                             ha->host_no, host_pid));
620                         break;
621                 }
622
623                 rscn_queue_index = ha->rscn_in_ptr + 1;
624                 if (rscn_queue_index == MAX_RSCN_COUNT)
625                         rscn_queue_index = 0;
626                 if (rscn_queue_index != ha->rscn_out_ptr) {
627                         ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry;
628                         ha->rscn_in_ptr = rscn_queue_index;
629                 } else {
630                         ha->flags.rscn_queue_overflow = 1;
631                 }
632
633                 atomic_set(&ha->loop_state, LOOP_UPDATE);
634                 atomic_set(&ha->loop_down_timer, 0);
635                 ha->flags.management_server_logged_in = 0;
636
637                 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
638                 set_bit(RSCN_UPDATE, &ha->dpc_flags);
639
640                 /* Update AEN queue. */
641                 qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]);
642                 break;
643
644         /* case MBA_RIO_RESPONSE: */
645         case MBA_ZIO_RESPONSE:
646                 DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n",
647                     ha->host_no));
648                 DEBUG(printk(KERN_INFO
649                     "scsi(%ld): [R|Z]IO update completion.\n",
650                     ha->host_no));
651
652                 qla2x00_process_response_queue(ha);
653                 break;
654
655         case MBA_DISCARD_RND_FRAME:
656                 DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
657                     "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
658                 break;
659         }
660 }
661
662 /**
663  * qla2x00_process_completed_request() - Process a Fast Post response.
664  * @ha: SCSI driver HA context
665  * @index: SRB index
666  */
667 static void
668 qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
669 {
670         srb_t *sp;
671
672         /* Validate handle. */
673         if (index >= MAX_OUTSTANDING_COMMANDS) {
674                 DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
675                     ha->host_no, index));
676                 qla_printk(KERN_WARNING, ha,
677                     "Invalid SCSI completion handle %d.\n", index);
678
679                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
680                 return;
681         }
682
683         sp = ha->outstanding_cmds[index];
684         if (sp) {
685                 /* Free outstanding command slot. */
686                 ha->outstanding_cmds[index] = NULL;
687
688                 CMD_COMPL_STATUS(sp->cmd) = 0L;
689                 CMD_SCSI_STATUS(sp->cmd) = 0L;
690
691                 /* Save ISP completion status */
692                 sp->cmd->result = DID_OK << 16;
693                 qla2x00_sp_compl(ha, sp);
694         } else {
695                 DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
696                     ha->host_no));
697                 qla_printk(KERN_WARNING, ha,
698                     "Invalid ISP SCSI completion handle\n");
699
700                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
701         }
702 }
703
704 /**
705  * qla2x00_process_response_queue() - Process response queue entries.
706  * @ha: SCSI driver HA context
707  */
708 void
709 qla2x00_process_response_queue(struct scsi_qla_host *ha)
710 {
711         struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
712         sts_entry_t     *pkt;
713         uint16_t        handle_cnt;
714         uint16_t        cnt;
715
716         if (!ha->flags.online)
717                 return;
718
719         while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
720                 pkt = (sts_entry_t *)ha->response_ring_ptr;
721
722                 ha->rsp_ring_index++;
723                 if (ha->rsp_ring_index == ha->response_q_length) {
724                         ha->rsp_ring_index = 0;
725                         ha->response_ring_ptr = ha->response_ring;
726                 } else {
727                         ha->response_ring_ptr++;
728                 }
729
730                 if (pkt->entry_status != 0) {
731                         DEBUG3(printk(KERN_INFO
732                             "scsi(%ld): Process error entry.\n", ha->host_no));
733
734                         qla2x00_error_entry(ha, pkt);
735                         ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
736                         wmb();
737                         continue;
738                 }
739
740                 switch (pkt->entry_type) {
741                 case STATUS_TYPE:
742                         qla2x00_status_entry(ha, pkt);
743                         break;
744                 case STATUS_TYPE_21:
745                         handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
746                         for (cnt = 0; cnt < handle_cnt; cnt++) {
747                                 qla2x00_process_completed_request(ha,
748                                     ((sts21_entry_t *)pkt)->handle[cnt]);
749                         }
750                         break;
751                 case STATUS_TYPE_22:
752                         handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
753                         for (cnt = 0; cnt < handle_cnt; cnt++) {
754                                 qla2x00_process_completed_request(ha,
755                                     ((sts22_entry_t *)pkt)->handle[cnt]);
756                         }
757                         break;
758                 case STATUS_CONT_TYPE:
759                         qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
760                         break;
761                 case MS_IOCB_TYPE:
762                         qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
763                         break;
764                 case MBX_IOCB_TYPE:
765                         if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
766                             !IS_QLA6312(ha) && !IS_QLA6322(ha)) {
767                                 if (pkt->sys_define == SOURCE_ASYNC_IOCB) {
768                                         qla2x00_process_iodesc(ha,
769                                             (struct mbx_entry *)pkt);
770                                 } else {
771                                         /* MBX IOCB Type Not Supported. */
772                                         DEBUG4(printk(KERN_WARNING
773                                             "scsi(%ld): Received unknown MBX "
774                                             "IOCB response pkt type=%x "
775                                             "source=%x entry status=%x.\n",
776                                             ha->host_no, pkt->entry_type,
777                                             pkt->sys_define,
778                                             pkt->entry_status));
779                                 }
780                                 break;
781                         }
782                         /* Fallthrough. */
783                 default:
784                         /* Type Not Supported. */
785                         DEBUG4(printk(KERN_WARNING
786                             "scsi(%ld): Received unknown response pkt type %x "
787                             "entry status=%x.\n",
788                             ha->host_no, pkt->entry_type, pkt->entry_status));
789                         break;
790                 }
791                 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
792                 wmb();
793         }
794
795         /* Adjust ring index */
796         WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index);
797 }
798
799 /**
800  * qla2x00_status_entry() - Process a Status IOCB entry.
801  * @ha: SCSI driver HA context
802  * @pkt: Entry pointer
803  */
804 static void
805 qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
806 {
807         srb_t           *sp;
808         fc_port_t       *fcport;
809         struct scsi_cmnd *cp;
810         sts_entry_t *sts;
811         struct sts_entry_24xx *sts24;
812         uint16_t        comp_status;
813         uint16_t        scsi_status;
814         uint8_t         lscsi_status;
815         int32_t         resid;
816         uint32_t        sense_len, rsp_info_len, resid_len;
817         uint8_t         *rsp_info, *sense_data;
818
819         sts = (sts_entry_t *) pkt;
820         sts24 = (struct sts_entry_24xx *) pkt;
821         if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
822                 comp_status = le16_to_cpu(sts24->comp_status);
823                 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
824         } else {
825                 comp_status = le16_to_cpu(sts->comp_status);
826                 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
827         }
828
829         /* Fast path completion. */
830         if (comp_status == CS_COMPLETE && scsi_status == 0) {
831                 qla2x00_process_completed_request(ha, sts->handle);
832
833                 return;
834         }
835
836         /* Validate handle. */
837         if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
838                 sp = ha->outstanding_cmds[sts->handle];
839                 ha->outstanding_cmds[sts->handle] = NULL;
840         } else
841                 sp = NULL;
842
843         if (sp == NULL) {
844                 DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
845                     ha->host_no));
846                 qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
847
848                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
849                 if (ha->dpc_wait && !ha->dpc_active)
850                         up(ha->dpc_wait);
851
852                 return;
853         }
854         cp = sp->cmd;
855         if (cp == NULL) {
856                 DEBUG2(printk("scsi(%ld): Command already returned back to OS "
857                     "pkt->handle=%d sp=%p sp->state:%d\n",
858                     ha->host_no, sts->handle, sp, sp->state));
859                 qla_printk(KERN_WARNING, ha,
860                     "Command is NULL: already returned to OS (sp=%p)\n", sp);
861
862                 return;
863         }
864
865         lscsi_status = scsi_status & STATUS_MASK;
866         CMD_ENTRY_STATUS(cp) = sts->entry_status;
867         CMD_COMPL_STATUS(cp) = comp_status;
868         CMD_SCSI_STATUS(cp) = scsi_status;
869
870         fcport = sp->fcport;
871
872         sense_len = rsp_info_len = resid_len = 0;
873         if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
874                 sense_len = le32_to_cpu(sts24->sense_len);
875                 rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
876                 resid_len = le32_to_cpu(sts24->rsp_residual_count);
877                 rsp_info = sts24->data;
878                 sense_data = sts24->data;
879                 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
880         } else {
881                 sense_len = le16_to_cpu(sts->req_sense_length);
882                 rsp_info_len = le16_to_cpu(sts->rsp_info_len);
883                 resid_len = le32_to_cpu(sts->residual_length);
884                 rsp_info = sts->rsp_info;
885                 sense_data = sts->req_sense_data;
886         }
887
888         /* Check for any FCP transport errors. */
889         if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
890                 /* Sense data lies beyond any FCP RESPONSE data. */
891                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
892                         sense_data += rsp_info_len;
893                 if (rsp_info_len > 3 && rsp_info[3]) {
894                         DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
895                             "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
896                             "retrying command\n", ha->host_no,
897                             cp->device->channel, cp->device->id,
898                             cp->device->lun, rsp_info_len, rsp_info[0],
899                             rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
900                             rsp_info[5], rsp_info[6], rsp_info[7]));
901
902                         cp->result = DID_BUS_BUSY << 16;
903                         qla2x00_sp_compl(ha, sp);
904                         return;
905                 }
906         }
907
908         /*
909          * Based on Host and scsi status generate status code for Linux
910          */
911         switch (comp_status) {
912         case CS_COMPLETE:
913                 if (scsi_status == 0) {
914                         cp->result = DID_OK << 16;
915                         break;
916                 }
917                 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
918                         resid = resid_len;
919                         cp->resid = resid;
920                         CMD_RESID_LEN(cp) = resid;
921                 }
922                 cp->result = DID_OK << 16 | lscsi_status;
923
924                 if (lscsi_status != SS_CHECK_CONDITION)
925                         break;
926
927                 /* Copy Sense Data into sense buffer. */
928                 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
929
930                 if (!(scsi_status & SS_SENSE_LEN_VALID))
931                         break;
932
933                 if (sense_len >= sizeof(cp->sense_buffer))
934                         sense_len = sizeof(cp->sense_buffer);
935
936                 CMD_ACTUAL_SNSLEN(cp) = sense_len;
937                 sp->request_sense_length = sense_len;
938                 sp->request_sense_ptr = cp->sense_buffer;
939
940                 if (sp->request_sense_length > 32)
941                         sense_len = 32;
942
943                 memcpy(cp->sense_buffer, sense_data, sense_len);
944
945                 sp->request_sense_ptr += sense_len;
946                 sp->request_sense_length -= sense_len;
947                 if (sp->request_sense_length != 0)
948                         ha->status_srb = sp;
949
950                 DEBUG5(printk("%s(): Check condition Sense data, "
951                     "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__,
952                     ha->host_no, cp->device->channel, cp->device->id,
953                     cp->device->lun, cp, cp->serial_number));
954                 if (sense_len)
955                         DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
956                             CMD_ACTUAL_SNSLEN(cp)));
957                 break;
958
959         case CS_DATA_UNDERRUN:
960                 DEBUG2(printk(KERN_INFO
961                     "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",
962                     ha->host_no, cp->device->id, cp->device->lun, comp_status,
963                     scsi_status));
964
965                 resid = resid_len;
966                 if (scsi_status & SS_RESIDUAL_UNDER) {
967                         cp->resid = resid;
968                         CMD_RESID_LEN(cp) = resid;
969                 }
970
971                 /*
972                  * Check to see if SCSI Status is non zero. If so report SCSI
973                  * Status.
974                  */
975                 if (lscsi_status != 0) {
976                         cp->result = DID_OK << 16 | lscsi_status;
977
978                         if (lscsi_status != SS_CHECK_CONDITION)
979                                 break;
980
981                         /* Copy Sense Data into sense buffer */
982                         memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
983
984                         if (!(scsi_status & SS_SENSE_LEN_VALID))
985                                 break;
986
987                         if (sense_len >= sizeof(cp->sense_buffer))
988                                 sense_len = sizeof(cp->sense_buffer);
989
990                         CMD_ACTUAL_SNSLEN(cp) = sense_len;
991                         sp->request_sense_length = sense_len;
992                         sp->request_sense_ptr = cp->sense_buffer;
993
994                         if (sp->request_sense_length > 32)
995                                 sense_len = 32;
996
997                         memcpy(cp->sense_buffer, sense_data, sense_len);
998
999                         sp->request_sense_ptr += sense_len;
1000                         sp->request_sense_length -= sense_len;
1001                         if (sp->request_sense_length != 0)
1002                                 ha->status_srb = sp;
1003
1004                         DEBUG5(printk("%s(): Check condition Sense data, "
1005                             "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
1006                             __func__, ha->host_no, cp->device->channel,
1007                             cp->device->id, cp->device->lun, cp,
1008                             cp->serial_number));
1009
1010                         if (sense_len)
1011                                 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1012                                     CMD_ACTUAL_SNSLEN(cp)));
1013                 } else {
1014                         /*
1015                          * If RISC reports underrun and target does not report
1016                          * it then we must have a lost frame, so tell upper
1017                          * layer to retry it by reporting a bus busy.
1018                          */
1019                         if (!(scsi_status & SS_RESIDUAL_UNDER)) {
1020                                 DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
1021                                     "frame(s) detected (%x of %x bytes)..."
1022                                     "retrying command.\n", ha->host_no,
1023                                     cp->device->channel, cp->device->id,
1024                                     cp->device->lun, resid,
1025                                     cp->request_bufflen));
1026
1027                                 cp->result = DID_BUS_BUSY << 16;
1028                                 break;
1029                         }
1030
1031                         /* Handle mid-layer underflow */
1032                         if ((unsigned)(cp->request_bufflen - resid) <
1033                             cp->underflow) {
1034                                 qla_printk(KERN_INFO, ha,
1035                                     "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1036                                     "detected (%x of %x bytes)...returning "
1037                                     "error status.\n", ha->host_no,
1038                                     cp->device->channel, cp->device->id,
1039                                     cp->device->lun, resid,
1040                                     cp->request_bufflen);
1041
1042                                 cp->result = DID_ERROR << 16;
1043                                 break;
1044                         }
1045
1046                         /* Everybody online, looking good... */
1047                         cp->result = DID_OK << 16;
1048                 }
1049                 break;
1050
1051         case CS_DATA_OVERRUN:
1052                 DEBUG2(printk(KERN_INFO
1053                     "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
1054                     ha->host_no, cp->device->id, cp->device->lun, comp_status,
1055                     scsi_status));
1056                 DEBUG2(printk(KERN_INFO
1057                     "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1058                     cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
1059                     cp->cmnd[4], cp->cmnd[5]));
1060                 DEBUG2(printk(KERN_INFO
1061                     "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1062                     "status!\n",
1063                     cp->serial_number, cp->request_bufflen, resid_len));
1064
1065                 cp->result = DID_ERROR << 16;
1066                 break;
1067
1068         case CS_PORT_LOGGED_OUT:
1069         case CS_PORT_CONFIG_CHG:
1070         case CS_PORT_BUSY:
1071         case CS_INCOMPLETE:
1072         case CS_PORT_UNAVAILABLE:
1073                 /*
1074                  * If the port is in Target Down state, return all IOs for this
1075                  * Target with DID_NO_CONNECT ELSE Queue the IOs in the
1076                  * retry_queue.
1077                  */
1078                 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1079                     "pid=%ld, compl status=0x%x, port state=0x%x\n",
1080                     ha->host_no, cp->device->id, cp->device->lun,
1081                     cp->serial_number, comp_status,
1082                     atomic_read(&fcport->state)));
1083
1084                 cp->result = DID_BUS_BUSY << 16;
1085                 if (atomic_read(&fcport->state) == FCS_ONLINE) {
1086                         qla2x00_mark_device_lost(ha, fcport, 1);
1087                 }
1088                 break;
1089
1090         case CS_RESET:
1091                 DEBUG2(printk(KERN_INFO
1092                     "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
1093                     ha->host_no, comp_status, scsi_status));
1094
1095                 cp->result = DID_RESET << 16;
1096                 break;
1097
1098         case CS_ABORTED:
1099                 /*
1100                  * hv2.19.12 - DID_ABORT does not retry the request if we
1101                  * aborted this request then abort otherwise it must be a
1102                  * reset.
1103                  */
1104                 DEBUG2(printk(KERN_INFO
1105                     "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
1106                     ha->host_no, comp_status, scsi_status));
1107
1108                 cp->result = DID_RESET << 16;
1109                 break;
1110
1111         case CS_TIMEOUT:
1112                 cp->result = DID_BUS_BUSY << 16;
1113
1114                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
1115                         DEBUG2(printk(KERN_INFO
1116                             "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
1117                             "0x%x-0x%x\n", ha->host_no, cp->device->channel,
1118                             cp->device->id, cp->device->lun, comp_status,
1119                             scsi_status));
1120                         break;
1121                 }
1122                 DEBUG2(printk(KERN_INFO
1123                     "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
1124                     "sflags=%x.\n", ha->host_no, cp->device->channel,
1125                     cp->device->id, cp->device->lun, comp_status, scsi_status,
1126                     le16_to_cpu(sts->status_flags)));
1127
1128                 /* Check to see if logout occurred. */
1129                 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
1130                         qla2x00_mark_device_lost(ha, fcport, 1);
1131                 break;
1132
1133         case CS_QUEUE_FULL:
1134                 DEBUG2(printk(KERN_INFO
1135                     "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n",
1136                     ha->host_no, comp_status, scsi_status));
1137
1138                 /* SCSI Mid-Layer handles device queue full */
1139
1140                 cp->result = DID_OK << 16 | lscsi_status;
1141
1142                 break;
1143
1144         default:
1145                 DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
1146                     "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
1147                 qla_printk(KERN_INFO, ha,
1148                     "Unknown status detected 0x%x-0x%x.\n",
1149                     comp_status, scsi_status);
1150
1151                 cp->result = DID_ERROR << 16;
1152                 break;
1153         }
1154
1155         /* Place command on done queue. */
1156         if (ha->status_srb == NULL)
1157                 qla2x00_sp_compl(ha, sp);
1158 }
1159
1160 /**
1161  * qla2x00_status_cont_entry() - Process a Status Continuations entry.
1162  * @ha: SCSI driver HA context
1163  * @pkt: Entry pointer
1164  *
1165  * Extended sense data.
1166  */
1167 static void
1168 qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1169 {
1170         uint8_t         sense_sz = 0;
1171         srb_t           *sp = ha->status_srb;
1172         struct scsi_cmnd *cp;
1173
1174         if (sp != NULL && sp->request_sense_length != 0) {
1175                 cp = sp->cmd;
1176                 if (cp == NULL) {
1177                         DEBUG2(printk("%s(): Cmd already returned back to OS "
1178                             "sp=%p sp->state:%d\n", __func__, sp, sp->state));
1179                         qla_printk(KERN_INFO, ha,
1180                             "cmd is NULL: already returned to OS (sp=%p)\n",
1181                             sp);
1182
1183                         ha->status_srb = NULL;
1184                         return;
1185                 }
1186
1187                 if (sp->request_sense_length > sizeof(pkt->data)) {
1188                         sense_sz = sizeof(pkt->data);
1189                 } else {
1190                         sense_sz = sp->request_sense_length;
1191                 }
1192
1193                 /* Move sense data. */
1194                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
1195                         host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1196                 memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1197                 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1198
1199                 sp->request_sense_ptr += sense_sz;
1200                 sp->request_sense_length -= sense_sz;
1201
1202                 /* Place command on done queue. */
1203                 if (sp->request_sense_length == 0) {
1204                         ha->status_srb = NULL;
1205                         qla2x00_sp_compl(ha, sp);
1206                 }
1207         }
1208 }
1209
1210 /**
1211  * qla2x00_error_entry() - Process an error entry.
1212  * @ha: SCSI driver HA context
1213  * @pkt: Entry pointer
1214  */
1215 static void
1216 qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1217 {
1218         srb_t *sp;
1219
1220 #if defined(QL_DEBUG_LEVEL_2)
1221         if (pkt->entry_status & RF_INV_E_ORDER)
1222                 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
1223         else if (pkt->entry_status & RF_INV_E_COUNT)
1224                 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
1225         else if (pkt->entry_status & RF_INV_E_PARAM)
1226                 qla_printk(KERN_ERR, ha,
1227                     "%s: Invalid Entry Parameter\n", __func__);
1228         else if (pkt->entry_status & RF_INV_E_TYPE)
1229                 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
1230         else if (pkt->entry_status & RF_BUSY)
1231                 qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);
1232         else
1233                 qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);
1234 #endif
1235
1236         /* Validate handle. */
1237         if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1238                 sp = ha->outstanding_cmds[pkt->handle];
1239         else
1240                 sp = NULL;
1241
1242         if (sp) {
1243                 /* Free outstanding command slot. */
1244                 ha->outstanding_cmds[pkt->handle] = NULL;
1245
1246                 /* Bad payload or header */
1247                 if (pkt->entry_status &
1248                     (RF_INV_E_ORDER | RF_INV_E_COUNT |
1249                      RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1250                         sp->cmd->result = DID_ERROR << 16;
1251                 } else if (pkt->entry_status & RF_BUSY) {
1252                         sp->cmd->result = DID_BUS_BUSY << 16;
1253                 } else {
1254                         sp->cmd->result = DID_ERROR << 16;
1255                 }
1256                 qla2x00_sp_compl(ha, sp);
1257
1258         } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1259             COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
1260                 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
1261                     ha->host_no));
1262                 qla_printk(KERN_WARNING, ha,
1263                     "Error entry - invalid handle\n");
1264
1265                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1266                 if (ha->dpc_wait && !ha->dpc_active)
1267                         up(ha->dpc_wait);
1268         }
1269 }
1270
1271 /**
1272  * qla2x00_ms_entry() - Process a Management Server entry.
1273  * @ha: SCSI driver HA context
1274  * @index: Response queue out pointer
1275  */
1276 static void
1277 qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
1278 {
1279         srb_t          *sp;
1280
1281         DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1282             __func__, ha->host_no, pkt, pkt->handle1));
1283
1284         /* Validate handle. */
1285         if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
1286                 sp = ha->outstanding_cmds[pkt->handle1];
1287         else
1288                 sp = NULL;
1289
1290         if (sp == NULL) {
1291                 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1292                     ha->host_no));
1293                 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
1294
1295                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1296                 return;
1297         }
1298
1299         CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
1300         CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1301
1302         /* Free outstanding command slot. */
1303         ha->outstanding_cmds[pkt->handle1] = NULL;
1304
1305         qla2x00_sp_compl(ha, sp);
1306 }
1307
1308
1309 /**
1310  * qla24xx_mbx_completion() - Process mailbox command completions.
1311  * @ha: SCSI driver HA context
1312  * @mb0: Mailbox0 register
1313  */
1314 static void
1315 qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
1316 {
1317         uint16_t        cnt;
1318         uint16_t __iomem *wptr;
1319         struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1320
1321         /* Load return mailbox registers. */
1322         ha->flags.mbox_int = 1;
1323         ha->mailbox_out[0] = mb0;
1324         wptr = (uint16_t __iomem *)&reg->mailbox1;
1325
1326         for (cnt = 1; cnt < ha->mbx_count; cnt++) {
1327                 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
1328                 wptr++;
1329         }
1330
1331         if (ha->mcp) {
1332                 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
1333                     __func__, ha->host_no, ha->mcp->mb[0]));
1334         } else {
1335                 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
1336                     __func__, ha->host_no));
1337         }
1338 }
1339
1340 /**
1341  * qla24xx_process_response_queue() - Process response queue entries.
1342  * @ha: SCSI driver HA context
1343  */
1344 void
1345 qla24xx_process_response_queue(struct scsi_qla_host *ha)
1346 {
1347         struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1348         struct sts_entry_24xx *pkt;
1349
1350         if (!ha->flags.online)
1351                 return;
1352
1353         while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
1354                 pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
1355
1356                 ha->rsp_ring_index++;
1357                 if (ha->rsp_ring_index == ha->response_q_length) {
1358                         ha->rsp_ring_index = 0;
1359                         ha->response_ring_ptr = ha->response_ring;
1360                 } else {
1361                         ha->response_ring_ptr++;
1362                 }
1363
1364                 if (pkt->entry_status != 0) {
1365                         DEBUG3(printk(KERN_INFO
1366                             "scsi(%ld): Process error entry.\n", ha->host_no));
1367
1368                         qla2x00_error_entry(ha, (sts_entry_t *) pkt);
1369                         ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1370                         wmb();
1371                         continue;
1372                 }
1373
1374                 switch (pkt->entry_type) {
1375                 case STATUS_TYPE:
1376                         qla2x00_status_entry(ha, pkt);
1377                         break;
1378                 case STATUS_CONT_TYPE:
1379                         qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
1380                         break;
1381                 case MS_IOCB_TYPE:
1382                         qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
1383                         break;
1384                 default:
1385                         /* Type Not Supported. */
1386                         DEBUG4(printk(KERN_WARNING
1387                             "scsi(%ld): Received unknown response pkt type %x "
1388                             "entry status=%x.\n",
1389                             ha->host_no, pkt->entry_type, pkt->entry_status));
1390                         break;
1391                 }
1392                 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1393                 wmb();
1394         }
1395
1396         /* Adjust ring index */
1397         WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
1398 }
1399
1400 /**
1401  * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
1402  * @irq:
1403  * @dev_id: SCSI driver HA context
1404  * @regs:
1405  *
1406  * Called by system whenever the host adapter generates an interrupt.
1407  *
1408  * Returns handled flag.
1409  */
1410 irqreturn_t
1411 qla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
1412 {
1413         scsi_qla_host_t *ha;
1414         struct device_reg_24xx __iomem *reg;
1415         int             status;
1416         unsigned long   flags;
1417         unsigned long   iter;
1418         uint32_t        stat;
1419         uint32_t        hccr;
1420         uint16_t        mb[4];
1421
1422         ha = (scsi_qla_host_t *) dev_id;
1423         if (!ha) {
1424                 printk(KERN_INFO
1425                     "%s(): NULL host pointer\n", __func__);
1426                 return IRQ_NONE;
1427         }
1428
1429         reg = &ha->iobase->isp24;
1430         status = 0;
1431
1432         spin_lock_irqsave(&ha->hardware_lock, flags);
1433         for (iter = 50; iter--; ) {
1434                 stat = RD_REG_DWORD(&reg->host_status);
1435                 if (stat & HSRX_RISC_PAUSED) {
1436                         hccr = RD_REG_DWORD(&reg->hccr);
1437
1438                         qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1439                             "Dumping firmware!\n", hccr);
1440                         qla24xx_fw_dump(ha, 1);
1441
1442                         set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1443                         break;
1444                 } else if ((stat & HSRX_RISC_INT) == 0)
1445                         break;
1446
1447                 switch (stat & 0xff) {
1448                 case 0x1:
1449                 case 0x2:
1450                 case 0x10:
1451                 case 0x11:
1452                         qla24xx_mbx_completion(ha, MSW(stat));
1453                         status |= MBX_INTERRUPT;
1454
1455                         break;
1456                 case 0x12:
1457                         mb[0] = MSW(stat);
1458                         mb[1] = RD_REG_WORD(&reg->mailbox1);
1459                         mb[2] = RD_REG_WORD(&reg->mailbox2);
1460                         mb[3] = RD_REG_WORD(&reg->mailbox3);
1461                         qla2x00_async_event(ha, mb);
1462                         break;
1463                 case 0x13:
1464                         qla24xx_process_response_queue(ha);
1465                         break;
1466                 default:
1467                         DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1468                             "(%d).\n",
1469                             ha->host_no, stat & 0xff));
1470                         break;
1471                 }
1472                 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1473                 RD_REG_DWORD_RELAXED(&reg->hccr);
1474         }
1475         spin_unlock_irqrestore(&ha->hardware_lock, flags);
1476
1477         if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1478             (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1479                 spin_lock_irqsave(&ha->mbx_reg_lock, flags);
1480
1481                 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1482                 up(&ha->mbx_intr_sem);
1483
1484                 spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
1485         }
1486
1487         return IRQ_HANDLED;
1488 }
1489
1490 /**
1491  * qla24xx_ms_entry() - Process a Management Server entry.
1492  * @ha: SCSI driver HA context
1493  * @index: Response queue out pointer
1494  */
1495 static void
1496 qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
1497 {
1498         srb_t          *sp;
1499
1500         DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1501             __func__, ha->host_no, pkt, pkt->handle));
1502
1503         DEBUG9(printk("%s: ct pkt dump:\n", __func__);)
1504         DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));)
1505
1506         /* Validate handle. */
1507         if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1508                 sp = ha->outstanding_cmds[pkt->handle];
1509         else
1510                 sp = NULL;
1511
1512         if (sp == NULL) {
1513                 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1514                     ha->host_no));
1515                 DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
1516                     ha->host_no));
1517                 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
1518                     pkt->handle);
1519
1520                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1521                 return;
1522         }
1523
1524         CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
1525         CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1526
1527         /* Free outstanding command slot. */
1528         ha->outstanding_cmds[pkt->handle] = NULL;
1529
1530         qla2x00_sp_compl(ha, sp);
1531 }
1532