Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[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                 if (ql2xfdmienable)
455                         set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
456
457                 /* Update AEN queue. */
458                 qla2x00_enqueue_aen(ha, MBA_LOOP_DOWN, NULL);
459                 break;
460
461         case MBA_LIP_RESET:             /* LIP reset occurred */
462                 DEBUG2(printk("scsi(%ld): Asynchronous LIP RESET (%x).\n",
463                     ha->host_no, mb[1]));
464                 qla_printk(KERN_INFO, ha,
465                     "LIP reset occured (%x).\n", mb[1]);
466
467                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
468                         atomic_set(&ha->loop_state, LOOP_DOWN);
469                         atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME);
470                         qla2x00_mark_all_devices_lost(ha);
471                 }
472
473                 set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
474
475                 ha->operating_mode = LOOP;
476                 ha->flags.management_server_logged_in = 0;
477
478                 /* Update AEN queue. */
479                 qla2x00_enqueue_aen(ha, MBA_LIP_RESET, NULL);
480
481                 break;
482
483         case MBA_POINT_TO_POINT:        /* Point-to-Point */
484                 if (IS_QLA2100(ha))
485                         break;
486
487                 DEBUG2(printk("scsi(%ld): Asynchronous P2P MODE received.\n",
488                     ha->host_no));
489
490                 /*
491                  * Until there's a transition from loop down to loop up, treat
492                  * this as loop down only.
493                  */
494                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
495                         atomic_set(&ha->loop_state, LOOP_DOWN);
496                         if (!atomic_read(&ha->loop_down_timer))
497                                 atomic_set(&ha->loop_down_timer,
498                                     LOOP_DOWN_TIME);
499                         qla2x00_mark_all_devices_lost(ha);
500                 }
501
502                 if (!(test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags))) {
503                         set_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
504                 }
505                 set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
506                 break;
507
508         case MBA_CHG_IN_CONNECTION:     /* Change in connection mode */
509                 if (IS_QLA2100(ha))
510                         break;
511
512                 DEBUG2(printk("scsi(%ld): Asynchronous Change In Connection "
513                     "received.\n",
514                     ha->host_no));
515                 qla_printk(KERN_INFO, ha,
516                     "Configuration change detected: value=%x.\n", mb[1]);
517
518                 if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
519                         atomic_set(&ha->loop_state, LOOP_DOWN);
520                         if (!atomic_read(&ha->loop_down_timer))
521                                 atomic_set(&ha->loop_down_timer,
522                                     LOOP_DOWN_TIME);
523                         qla2x00_mark_all_devices_lost(ha);
524                 }
525
526                 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
527                 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
528                 break;
529
530         case MBA_PORT_UPDATE:           /* Port database update */
531                 /*
532                  * If a single remote port just logged into (or logged out of)
533                  * us, create a new entry in our rscn fcports list and handle
534                  * the event like an RSCN.
535                  */
536                 if (!IS_QLA2100(ha) && !IS_QLA2200(ha) && !IS_QLA6312(ha) &&
537                     !IS_QLA6322(ha) && !IS_QLA24XX(ha) && !IS_QLA25XX(ha) &&
538                     ha->flags.init_done && mb[1] != 0xffff &&
539                     ((ha->operating_mode == P2P && mb[1] != 0) ||
540                     (ha->operating_mode != P2P && mb[1] !=
541                         SNS_FIRST_LOOP_ID)) && (mb[2] == 6 || mb[2] == 7)) {
542                         int rval;
543                         fc_port_t *rscn_fcport;
544
545                         /* Create new fcport for login. */
546                         rscn_fcport = qla2x00_alloc_rscn_fcport(ha, GFP_ATOMIC);
547                         if (rscn_fcport) {
548                                 DEBUG14(printk("scsi(%ld): Port Update -- "
549                                     "creating RSCN fcport %p for %x/%x/%x.\n",
550                                     ha->host_no, rscn_fcport, mb[1], mb[2],
551                                     mb[3]));
552
553                                 rscn_fcport->loop_id = mb[1];
554                                 rscn_fcport->d_id.b24 = INVALID_PORT_ID;
555                                 atomic_set(&rscn_fcport->state,
556                                     FCS_DEVICE_LOST);
557                                 list_add_tail(&rscn_fcport->list,
558                                     &ha->rscn_fcports);
559
560                                 rval = qla2x00_handle_port_rscn(ha, 0,
561                                     rscn_fcport, 1);
562                                 if (rval == QLA_SUCCESS)
563                                         break;
564                         } else {
565                                 DEBUG14(printk("scsi(%ld): Port Update -- "
566                                     "-- unable to allocate RSCN fcport "
567                                     "login.\n", ha->host_no));
568                         }
569                 }
570
571                 /*
572                  * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
573                  * event etc. earlier indicating loop is down) then process
574                  * it.  Otherwise ignore it and Wait for RSCN to come in.
575                  */
576                 atomic_set(&ha->loop_down_timer, 0);
577                 if (atomic_read(&ha->loop_state) != LOOP_DOWN &&
578                     atomic_read(&ha->loop_state) != LOOP_DEAD) {
579                         DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE "
580                             "ignored %04x/%04x/%04x.\n", ha->host_no, mb[1],
581                             mb[2], mb[3]));
582                         break;
583                 }
584
585                 DEBUG2(printk("scsi(%ld): Asynchronous PORT UPDATE.\n",
586                     ha->host_no));
587                 DEBUG(printk(KERN_INFO
588                     "scsi(%ld): Port database changed %04x %04x %04x.\n",
589                     ha->host_no, mb[1], mb[2], mb[3]));
590
591                 /*
592                  * Mark all devices as missing so we will login again.
593                  */
594                 atomic_set(&ha->loop_state, LOOP_UP);
595
596                 qla2x00_mark_all_devices_lost(ha);
597
598                 ha->flags.rscn_queue_overflow = 1;
599
600                 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
601                 set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
602
603                 /* Update AEN queue. */
604                 qla2x00_enqueue_aen(ha, MBA_PORT_UPDATE, NULL);
605                 break;
606
607         case MBA_RSCN_UPDATE:           /* State Change Registration */
608                 DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
609                     ha->host_no));
610                 DEBUG(printk(KERN_INFO
611                     "scsi(%ld): RSCN database changed -- %04x %04x.\n",
612                     ha->host_no, mb[1], mb[2]));
613
614                 rscn_entry = (mb[1] << 16) | mb[2];
615                 host_pid = (ha->d_id.b.domain << 16) | (ha->d_id.b.area << 8) |
616                     ha->d_id.b.al_pa;
617                 if (rscn_entry == host_pid) {
618                         DEBUG(printk(KERN_INFO
619                             "scsi(%ld): Ignoring RSCN update to local host "
620                             "port ID (%06x)\n",
621                             ha->host_no, host_pid));
622                         break;
623                 }
624
625                 rscn_queue_index = ha->rscn_in_ptr + 1;
626                 if (rscn_queue_index == MAX_RSCN_COUNT)
627                         rscn_queue_index = 0;
628                 if (rscn_queue_index != ha->rscn_out_ptr) {
629                         ha->rscn_queue[ha->rscn_in_ptr] = rscn_entry;
630                         ha->rscn_in_ptr = rscn_queue_index;
631                 } else {
632                         ha->flags.rscn_queue_overflow = 1;
633                 }
634
635                 atomic_set(&ha->loop_state, LOOP_UPDATE);
636                 atomic_set(&ha->loop_down_timer, 0);
637                 ha->flags.management_server_logged_in = 0;
638
639                 set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
640                 set_bit(RSCN_UPDATE, &ha->dpc_flags);
641
642                 /* Update AEN queue. */
643                 qla2x00_enqueue_aen(ha, MBA_RSCN_UPDATE, &mb[0]);
644                 break;
645
646         /* case MBA_RIO_RESPONSE: */
647         case MBA_ZIO_RESPONSE:
648                 DEBUG2(printk("scsi(%ld): [R|Z]IO update completion.\n",
649                     ha->host_no));
650                 DEBUG(printk(KERN_INFO
651                     "scsi(%ld): [R|Z]IO update completion.\n",
652                     ha->host_no));
653
654                 qla2x00_process_response_queue(ha);
655                 break;
656
657         case MBA_DISCARD_RND_FRAME:
658                 DEBUG2(printk("scsi(%ld): Discard RND Frame -- %04x %04x "
659                     "%04x.\n", ha->host_no, mb[1], mb[2], mb[3]));
660                 break;
661         }
662 }
663
664 /**
665  * qla2x00_process_completed_request() - Process a Fast Post response.
666  * @ha: SCSI driver HA context
667  * @index: SRB index
668  */
669 static void
670 qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
671 {
672         srb_t *sp;
673
674         /* Validate handle. */
675         if (index >= MAX_OUTSTANDING_COMMANDS) {
676                 DEBUG2(printk("scsi(%ld): Invalid SCSI completion handle %d.\n",
677                     ha->host_no, index));
678                 qla_printk(KERN_WARNING, ha,
679                     "Invalid SCSI completion handle %d.\n", index);
680
681                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
682                 return;
683         }
684
685         sp = ha->outstanding_cmds[index];
686         if (sp) {
687                 /* Free outstanding command slot. */
688                 ha->outstanding_cmds[index] = NULL;
689
690                 CMD_COMPL_STATUS(sp->cmd) = 0L;
691                 CMD_SCSI_STATUS(sp->cmd) = 0L;
692
693                 /* Save ISP completion status */
694                 sp->cmd->result = DID_OK << 16;
695                 qla2x00_sp_compl(ha, sp);
696         } else {
697                 DEBUG2(printk("scsi(%ld): Invalid ISP SCSI completion handle\n",
698                     ha->host_no));
699                 qla_printk(KERN_WARNING, ha,
700                     "Invalid ISP SCSI completion handle\n");
701
702                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
703         }
704 }
705
706 /**
707  * qla2x00_process_response_queue() - Process response queue entries.
708  * @ha: SCSI driver HA context
709  */
710 void
711 qla2x00_process_response_queue(struct scsi_qla_host *ha)
712 {
713         struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
714         sts_entry_t     *pkt;
715         uint16_t        handle_cnt;
716         uint16_t        cnt;
717
718         if (!ha->flags.online)
719                 return;
720
721         while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
722                 pkt = (sts_entry_t *)ha->response_ring_ptr;
723
724                 ha->rsp_ring_index++;
725                 if (ha->rsp_ring_index == ha->response_q_length) {
726                         ha->rsp_ring_index = 0;
727                         ha->response_ring_ptr = ha->response_ring;
728                 } else {
729                         ha->response_ring_ptr++;
730                 }
731
732                 if (pkt->entry_status != 0) {
733                         DEBUG3(printk(KERN_INFO
734                             "scsi(%ld): Process error entry.\n", ha->host_no));
735
736                         qla2x00_error_entry(ha, pkt);
737                         ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
738                         wmb();
739                         continue;
740                 }
741
742                 switch (pkt->entry_type) {
743                 case STATUS_TYPE:
744                         qla2x00_status_entry(ha, pkt);
745                         break;
746                 case STATUS_TYPE_21:
747                         handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
748                         for (cnt = 0; cnt < handle_cnt; cnt++) {
749                                 qla2x00_process_completed_request(ha,
750                                     ((sts21_entry_t *)pkt)->handle[cnt]);
751                         }
752                         break;
753                 case STATUS_TYPE_22:
754                         handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
755                         for (cnt = 0; cnt < handle_cnt; cnt++) {
756                                 qla2x00_process_completed_request(ha,
757                                     ((sts22_entry_t *)pkt)->handle[cnt]);
758                         }
759                         break;
760                 case STATUS_CONT_TYPE:
761                         qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
762                         break;
763                 case MS_IOCB_TYPE:
764                         qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
765                         break;
766                 case MBX_IOCB_TYPE:
767                         if (!IS_QLA2100(ha) && !IS_QLA2200(ha) &&
768                             !IS_QLA6312(ha) && !IS_QLA6322(ha)) {
769                                 if (pkt->sys_define == SOURCE_ASYNC_IOCB) {
770                                         qla2x00_process_iodesc(ha,
771                                             (struct mbx_entry *)pkt);
772                                 } else {
773                                         /* MBX IOCB Type Not Supported. */
774                                         DEBUG4(printk(KERN_WARNING
775                                             "scsi(%ld): Received unknown MBX "
776                                             "IOCB response pkt type=%x "
777                                             "source=%x entry status=%x.\n",
778                                             ha->host_no, pkt->entry_type,
779                                             pkt->sys_define,
780                                             pkt->entry_status));
781                                 }
782                                 break;
783                         }
784                         /* Fallthrough. */
785                 default:
786                         /* Type Not Supported. */
787                         DEBUG4(printk(KERN_WARNING
788                             "scsi(%ld): Received unknown response pkt type %x "
789                             "entry status=%x.\n",
790                             ha->host_no, pkt->entry_type, pkt->entry_status));
791                         break;
792                 }
793                 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
794                 wmb();
795         }
796
797         /* Adjust ring index */
798         WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), ha->rsp_ring_index);
799 }
800
801 /**
802  * qla2x00_status_entry() - Process a Status IOCB entry.
803  * @ha: SCSI driver HA context
804  * @pkt: Entry pointer
805  */
806 static void
807 qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt)
808 {
809         srb_t           *sp;
810         fc_port_t       *fcport;
811         struct scsi_cmnd *cp;
812         sts_entry_t *sts;
813         struct sts_entry_24xx *sts24;
814         uint16_t        comp_status;
815         uint16_t        scsi_status;
816         uint8_t         lscsi_status;
817         int32_t         resid;
818         uint32_t        sense_len, rsp_info_len, resid_len;
819         uint8_t         *rsp_info, *sense_data;
820
821         sts = (sts_entry_t *) pkt;
822         sts24 = (struct sts_entry_24xx *) pkt;
823         if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
824                 comp_status = le16_to_cpu(sts24->comp_status);
825                 scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
826         } else {
827                 comp_status = le16_to_cpu(sts->comp_status);
828                 scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
829         }
830
831         /* Fast path completion. */
832         if (comp_status == CS_COMPLETE && scsi_status == 0) {
833                 qla2x00_process_completed_request(ha, sts->handle);
834
835                 return;
836         }
837
838         /* Validate handle. */
839         if (sts->handle < MAX_OUTSTANDING_COMMANDS) {
840                 sp = ha->outstanding_cmds[sts->handle];
841                 ha->outstanding_cmds[sts->handle] = NULL;
842         } else
843                 sp = NULL;
844
845         if (sp == NULL) {
846                 DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
847                     ha->host_no));
848                 qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
849
850                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
851                 if (ha->dpc_wait && !ha->dpc_active)
852                         up(ha->dpc_wait);
853
854                 return;
855         }
856         cp = sp->cmd;
857         if (cp == NULL) {
858                 DEBUG2(printk("scsi(%ld): Command already returned back to OS "
859                     "pkt->handle=%d sp=%p sp->state:%d\n",
860                     ha->host_no, sts->handle, sp, sp->state));
861                 qla_printk(KERN_WARNING, ha,
862                     "Command is NULL: already returned to OS (sp=%p)\n", sp);
863
864                 return;
865         }
866
867         lscsi_status = scsi_status & STATUS_MASK;
868         CMD_ENTRY_STATUS(cp) = sts->entry_status;
869         CMD_COMPL_STATUS(cp) = comp_status;
870         CMD_SCSI_STATUS(cp) = scsi_status;
871
872         fcport = sp->fcport;
873
874         sense_len = rsp_info_len = resid_len = 0;
875         if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
876                 sense_len = le32_to_cpu(sts24->sense_len);
877                 rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
878                 resid_len = le32_to_cpu(sts24->rsp_residual_count);
879                 rsp_info = sts24->data;
880                 sense_data = sts24->data;
881                 host_to_fcp_swap(sts24->data, sizeof(sts24->data));
882         } else {
883                 sense_len = le16_to_cpu(sts->req_sense_length);
884                 rsp_info_len = le16_to_cpu(sts->rsp_info_len);
885                 resid_len = le32_to_cpu(sts->residual_length);
886                 rsp_info = sts->rsp_info;
887                 sense_data = sts->req_sense_data;
888         }
889
890         /* Check for any FCP transport errors. */
891         if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
892                 /* Sense data lies beyond any FCP RESPONSE data. */
893                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
894                         sense_data += rsp_info_len;
895                 if (rsp_info_len > 3 && rsp_info[3]) {
896                         DEBUG2(printk("scsi(%ld:%d:%d:%d) FCP I/O protocol "
897                             "failure (%x/%02x%02x%02x%02x%02x%02x%02x%02x)..."
898                             "retrying command\n", ha->host_no,
899                             cp->device->channel, cp->device->id,
900                             cp->device->lun, rsp_info_len, rsp_info[0],
901                             rsp_info[1], rsp_info[2], rsp_info[3], rsp_info[4],
902                             rsp_info[5], rsp_info[6], rsp_info[7]));
903
904                         cp->result = DID_BUS_BUSY << 16;
905                         qla2x00_sp_compl(ha, sp);
906                         return;
907                 }
908         }
909
910         /*
911          * Based on Host and scsi status generate status code for Linux
912          */
913         switch (comp_status) {
914         case CS_COMPLETE:
915                 if (scsi_status == 0) {
916                         cp->result = DID_OK << 16;
917                         break;
918                 }
919                 if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
920                         resid = resid_len;
921                         cp->resid = resid;
922                         CMD_RESID_LEN(cp) = resid;
923                 }
924                 cp->result = DID_OK << 16 | lscsi_status;
925
926                 if (lscsi_status != SS_CHECK_CONDITION)
927                         break;
928
929                 /* Copy Sense Data into sense buffer. */
930                 memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
931
932                 if (!(scsi_status & SS_SENSE_LEN_VALID))
933                         break;
934
935                 if (sense_len >= sizeof(cp->sense_buffer))
936                         sense_len = sizeof(cp->sense_buffer);
937
938                 CMD_ACTUAL_SNSLEN(cp) = sense_len;
939                 sp->request_sense_length = sense_len;
940                 sp->request_sense_ptr = cp->sense_buffer;
941
942                 if (sp->request_sense_length > 32)
943                         sense_len = 32;
944
945                 memcpy(cp->sense_buffer, sense_data, sense_len);
946
947                 sp->request_sense_ptr += sense_len;
948                 sp->request_sense_length -= sense_len;
949                 if (sp->request_sense_length != 0)
950                         ha->status_srb = sp;
951
952                 DEBUG5(printk("%s(): Check condition Sense data, "
953                     "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n", __func__,
954                     ha->host_no, cp->device->channel, cp->device->id,
955                     cp->device->lun, cp, cp->serial_number));
956                 if (sense_len)
957                         DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
958                             CMD_ACTUAL_SNSLEN(cp)));
959                 break;
960
961         case CS_DATA_UNDERRUN:
962                 DEBUG2(printk(KERN_INFO
963                     "scsi(%ld:%d:%d) UNDERRUN status detected 0x%x-0x%x.\n",
964                     ha->host_no, cp->device->id, cp->device->lun, comp_status,
965                     scsi_status));
966
967                 resid = resid_len;
968                 if (scsi_status & SS_RESIDUAL_UNDER) {
969                         cp->resid = resid;
970                         CMD_RESID_LEN(cp) = resid;
971                 }
972
973                 /*
974                  * Check to see if SCSI Status is non zero. If so report SCSI
975                  * Status.
976                  */
977                 if (lscsi_status != 0) {
978                         cp->result = DID_OK << 16 | lscsi_status;
979
980                         if (lscsi_status != SS_CHECK_CONDITION)
981                                 break;
982
983                         /* Copy Sense Data into sense buffer */
984                         memset(cp->sense_buffer, 0, sizeof(cp->sense_buffer));
985
986                         if (!(scsi_status & SS_SENSE_LEN_VALID))
987                                 break;
988
989                         if (sense_len >= sizeof(cp->sense_buffer))
990                                 sense_len = sizeof(cp->sense_buffer);
991
992                         CMD_ACTUAL_SNSLEN(cp) = sense_len;
993                         sp->request_sense_length = sense_len;
994                         sp->request_sense_ptr = cp->sense_buffer;
995
996                         if (sp->request_sense_length > 32)
997                                 sense_len = 32;
998
999                         memcpy(cp->sense_buffer, sense_data, sense_len);
1000
1001                         sp->request_sense_ptr += sense_len;
1002                         sp->request_sense_length -= sense_len;
1003                         if (sp->request_sense_length != 0)
1004                                 ha->status_srb = sp;
1005
1006                         DEBUG5(printk("%s(): Check condition Sense data, "
1007                             "scsi(%ld:%d:%d:%d) cmd=%p pid=%ld\n",
1008                             __func__, ha->host_no, cp->device->channel,
1009                             cp->device->id, cp->device->lun, cp,
1010                             cp->serial_number));
1011
1012                         if (sense_len)
1013                                 DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
1014                                     CMD_ACTUAL_SNSLEN(cp)));
1015                 } else {
1016                         /*
1017                          * If RISC reports underrun and target does not report
1018                          * it then we must have a lost frame, so tell upper
1019                          * layer to retry it by reporting a bus busy.
1020                          */
1021                         if (!(scsi_status & SS_RESIDUAL_UNDER)) {
1022                                 DEBUG2(printk("scsi(%ld:%d:%d:%d) Dropped "
1023                                     "frame(s) detected (%x of %x bytes)..."
1024                                     "retrying command.\n", ha->host_no,
1025                                     cp->device->channel, cp->device->id,
1026                                     cp->device->lun, resid,
1027                                     cp->request_bufflen));
1028
1029                                 cp->result = DID_BUS_BUSY << 16;
1030                                 break;
1031                         }
1032
1033                         /* Handle mid-layer underflow */
1034                         if ((unsigned)(cp->request_bufflen - resid) <
1035                             cp->underflow) {
1036                                 qla_printk(KERN_INFO, ha,
1037                                     "scsi(%ld:%d:%d:%d): Mid-layer underflow "
1038                                     "detected (%x of %x bytes)...returning "
1039                                     "error status.\n", ha->host_no,
1040                                     cp->device->channel, cp->device->id,
1041                                     cp->device->lun, resid,
1042                                     cp->request_bufflen);
1043
1044                                 cp->result = DID_ERROR << 16;
1045                                 break;
1046                         }
1047
1048                         /* Everybody online, looking good... */
1049                         cp->result = DID_OK << 16;
1050                 }
1051                 break;
1052
1053         case CS_DATA_OVERRUN:
1054                 DEBUG2(printk(KERN_INFO
1055                     "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
1056                     ha->host_no, cp->device->id, cp->device->lun, comp_status,
1057                     scsi_status));
1058                 DEBUG2(printk(KERN_INFO
1059                     "CDB: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
1060                     cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
1061                     cp->cmnd[4], cp->cmnd[5]));
1062                 DEBUG2(printk(KERN_INFO
1063                     "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
1064                     "status!\n",
1065                     cp->serial_number, cp->request_bufflen, resid_len));
1066
1067                 cp->result = DID_ERROR << 16;
1068                 break;
1069
1070         case CS_PORT_LOGGED_OUT:
1071         case CS_PORT_CONFIG_CHG:
1072         case CS_PORT_BUSY:
1073         case CS_INCOMPLETE:
1074         case CS_PORT_UNAVAILABLE:
1075                 /*
1076                  * If the port is in Target Down state, return all IOs for this
1077                  * Target with DID_NO_CONNECT ELSE Queue the IOs in the
1078                  * retry_queue.
1079                  */
1080                 DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
1081                     "pid=%ld, compl status=0x%x, port state=0x%x\n",
1082                     ha->host_no, cp->device->id, cp->device->lun,
1083                     cp->serial_number, comp_status,
1084                     atomic_read(&fcport->state)));
1085
1086                 cp->result = DID_BUS_BUSY << 16;
1087                 if (atomic_read(&fcport->state) == FCS_ONLINE) {
1088                         qla2x00_mark_device_lost(ha, fcport, 1);
1089                 }
1090                 break;
1091
1092         case CS_RESET:
1093                 DEBUG2(printk(KERN_INFO
1094                     "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
1095                     ha->host_no, comp_status, scsi_status));
1096
1097                 cp->result = DID_RESET << 16;
1098                 break;
1099
1100         case CS_ABORTED:
1101                 /*
1102                  * hv2.19.12 - DID_ABORT does not retry the request if we
1103                  * aborted this request then abort otherwise it must be a
1104                  * reset.
1105                  */
1106                 DEBUG2(printk(KERN_INFO
1107                     "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
1108                     ha->host_no, comp_status, scsi_status));
1109
1110                 cp->result = DID_RESET << 16;
1111                 break;
1112
1113         case CS_TIMEOUT:
1114                 cp->result = DID_BUS_BUSY << 16;
1115
1116                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) {
1117                         DEBUG2(printk(KERN_INFO
1118                             "scsi(%ld:%d:%d:%d): TIMEOUT status detected "
1119                             "0x%x-0x%x\n", ha->host_no, cp->device->channel,
1120                             cp->device->id, cp->device->lun, comp_status,
1121                             scsi_status));
1122                         break;
1123                 }
1124                 DEBUG2(printk(KERN_INFO
1125                     "scsi(%ld:%d:%d:%d): TIMEOUT status detected 0x%x-0x%x "
1126                     "sflags=%x.\n", ha->host_no, cp->device->channel,
1127                     cp->device->id, cp->device->lun, comp_status, scsi_status,
1128                     le16_to_cpu(sts->status_flags)));
1129
1130                 /* Check to see if logout occurred. */
1131                 if ((le16_to_cpu(sts->status_flags) & SF_LOGOUT_SENT))
1132                         qla2x00_mark_device_lost(ha, fcport, 1);
1133                 break;
1134
1135         case CS_QUEUE_FULL:
1136                 DEBUG2(printk(KERN_INFO
1137                     "scsi(%ld): QUEUE FULL status detected 0x%x-0x%x.\n",
1138                     ha->host_no, comp_status, scsi_status));
1139
1140                 /* SCSI Mid-Layer handles device queue full */
1141
1142                 cp->result = DID_OK << 16 | lscsi_status;
1143
1144                 break;
1145
1146         default:
1147                 DEBUG3(printk("scsi(%ld): Error detected (unknown status) "
1148                     "0x%x-0x%x.\n", ha->host_no, comp_status, scsi_status));
1149                 qla_printk(KERN_INFO, ha,
1150                     "Unknown status detected 0x%x-0x%x.\n",
1151                     comp_status, scsi_status);
1152
1153                 cp->result = DID_ERROR << 16;
1154                 break;
1155         }
1156
1157         /* Place command on done queue. */
1158         if (ha->status_srb == NULL)
1159                 qla2x00_sp_compl(ha, sp);
1160 }
1161
1162 /**
1163  * qla2x00_status_cont_entry() - Process a Status Continuations entry.
1164  * @ha: SCSI driver HA context
1165  * @pkt: Entry pointer
1166  *
1167  * Extended sense data.
1168  */
1169 static void
1170 qla2x00_status_cont_entry(scsi_qla_host_t *ha, sts_cont_entry_t *pkt)
1171 {
1172         uint8_t         sense_sz = 0;
1173         srb_t           *sp = ha->status_srb;
1174         struct scsi_cmnd *cp;
1175
1176         if (sp != NULL && sp->request_sense_length != 0) {
1177                 cp = sp->cmd;
1178                 if (cp == NULL) {
1179                         DEBUG2(printk("%s(): Cmd already returned back to OS "
1180                             "sp=%p sp->state:%d\n", __func__, sp, sp->state));
1181                         qla_printk(KERN_INFO, ha,
1182                             "cmd is NULL: already returned to OS (sp=%p)\n",
1183                             sp);
1184
1185                         ha->status_srb = NULL;
1186                         return;
1187                 }
1188
1189                 if (sp->request_sense_length > sizeof(pkt->data)) {
1190                         sense_sz = sizeof(pkt->data);
1191                 } else {
1192                         sense_sz = sp->request_sense_length;
1193                 }
1194
1195                 /* Move sense data. */
1196                 if (IS_QLA24XX(ha) || IS_QLA25XX(ha))
1197                         host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1198                 memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
1199                 DEBUG5(qla2x00_dump_buffer(sp->request_sense_ptr, sense_sz));
1200
1201                 sp->request_sense_ptr += sense_sz;
1202                 sp->request_sense_length -= sense_sz;
1203
1204                 /* Place command on done queue. */
1205                 if (sp->request_sense_length == 0) {
1206                         ha->status_srb = NULL;
1207                         qla2x00_sp_compl(ha, sp);
1208                 }
1209         }
1210 }
1211
1212 /**
1213  * qla2x00_error_entry() - Process an error entry.
1214  * @ha: SCSI driver HA context
1215  * @pkt: Entry pointer
1216  */
1217 static void
1218 qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
1219 {
1220         srb_t *sp;
1221
1222 #if defined(QL_DEBUG_LEVEL_2)
1223         if (pkt->entry_status & RF_INV_E_ORDER)
1224                 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Order\n", __func__);
1225         else if (pkt->entry_status & RF_INV_E_COUNT)
1226                 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Count\n", __func__);
1227         else if (pkt->entry_status & RF_INV_E_PARAM)
1228                 qla_printk(KERN_ERR, ha,
1229                     "%s: Invalid Entry Parameter\n", __func__);
1230         else if (pkt->entry_status & RF_INV_E_TYPE)
1231                 qla_printk(KERN_ERR, ha, "%s: Invalid Entry Type\n", __func__);
1232         else if (pkt->entry_status & RF_BUSY)
1233                 qla_printk(KERN_ERR, ha, "%s: Busy\n", __func__);
1234         else
1235                 qla_printk(KERN_ERR, ha, "%s: UNKNOWN flag error\n", __func__);
1236 #endif
1237
1238         /* Validate handle. */
1239         if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1240                 sp = ha->outstanding_cmds[pkt->handle];
1241         else
1242                 sp = NULL;
1243
1244         if (sp) {
1245                 /* Free outstanding command slot. */
1246                 ha->outstanding_cmds[pkt->handle] = NULL;
1247
1248                 /* Bad payload or header */
1249                 if (pkt->entry_status &
1250                     (RF_INV_E_ORDER | RF_INV_E_COUNT |
1251                      RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1252                         sp->cmd->result = DID_ERROR << 16;
1253                 } else if (pkt->entry_status & RF_BUSY) {
1254                         sp->cmd->result = DID_BUS_BUSY << 16;
1255                 } else {
1256                         sp->cmd->result = DID_ERROR << 16;
1257                 }
1258                 qla2x00_sp_compl(ha, sp);
1259
1260         } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1261             COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
1262                 DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
1263                     ha->host_no));
1264                 qla_printk(KERN_WARNING, ha,
1265                     "Error entry - invalid handle\n");
1266
1267                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1268                 if (ha->dpc_wait && !ha->dpc_active)
1269                         up(ha->dpc_wait);
1270         }
1271 }
1272
1273 /**
1274  * qla2x00_ms_entry() - Process a Management Server entry.
1275  * @ha: SCSI driver HA context
1276  * @index: Response queue out pointer
1277  */
1278 static void
1279 qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
1280 {
1281         srb_t          *sp;
1282
1283         DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1284             __func__, ha->host_no, pkt, pkt->handle1));
1285
1286         /* Validate handle. */
1287         if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
1288                 sp = ha->outstanding_cmds[pkt->handle1];
1289         else
1290                 sp = NULL;
1291
1292         if (sp == NULL) {
1293                 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1294                     ha->host_no));
1295                 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
1296
1297                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1298                 return;
1299         }
1300
1301         CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
1302         CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1303
1304         /* Free outstanding command slot. */
1305         ha->outstanding_cmds[pkt->handle1] = NULL;
1306
1307         qla2x00_sp_compl(ha, sp);
1308 }
1309
1310
1311 /**
1312  * qla24xx_mbx_completion() - Process mailbox command completions.
1313  * @ha: SCSI driver HA context
1314  * @mb0: Mailbox0 register
1315  */
1316 static void
1317 qla24xx_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
1318 {
1319         uint16_t        cnt;
1320         uint16_t __iomem *wptr;
1321         struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1322
1323         /* Load return mailbox registers. */
1324         ha->flags.mbox_int = 1;
1325         ha->mailbox_out[0] = mb0;
1326         wptr = (uint16_t __iomem *)&reg->mailbox1;
1327
1328         for (cnt = 1; cnt < ha->mbx_count; cnt++) {
1329                 ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
1330                 wptr++;
1331         }
1332
1333         if (ha->mcp) {
1334                 DEBUG3(printk("%s(%ld): Got mailbox completion. cmd=%x.\n",
1335                     __func__, ha->host_no, ha->mcp->mb[0]));
1336         } else {
1337                 DEBUG2_3(printk("%s(%ld): MBX pointer ERROR!\n",
1338                     __func__, ha->host_no));
1339         }
1340 }
1341
1342 /**
1343  * qla24xx_process_response_queue() - Process response queue entries.
1344  * @ha: SCSI driver HA context
1345  */
1346 void
1347 qla24xx_process_response_queue(struct scsi_qla_host *ha)
1348 {
1349         struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
1350         struct sts_entry_24xx *pkt;
1351
1352         if (!ha->flags.online)
1353                 return;
1354
1355         while (ha->response_ring_ptr->signature != RESPONSE_PROCESSED) {
1356                 pkt = (struct sts_entry_24xx *)ha->response_ring_ptr;
1357
1358                 ha->rsp_ring_index++;
1359                 if (ha->rsp_ring_index == ha->response_q_length) {
1360                         ha->rsp_ring_index = 0;
1361                         ha->response_ring_ptr = ha->response_ring;
1362                 } else {
1363                         ha->response_ring_ptr++;
1364                 }
1365
1366                 if (pkt->entry_status != 0) {
1367                         DEBUG3(printk(KERN_INFO
1368                             "scsi(%ld): Process error entry.\n", ha->host_no));
1369
1370                         qla2x00_error_entry(ha, (sts_entry_t *) pkt);
1371                         ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1372                         wmb();
1373                         continue;
1374                 }
1375
1376                 switch (pkt->entry_type) {
1377                 case STATUS_TYPE:
1378                         qla2x00_status_entry(ha, pkt);
1379                         break;
1380                 case STATUS_CONT_TYPE:
1381                         qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
1382                         break;
1383                 case MS_IOCB_TYPE:
1384                         qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
1385                         break;
1386                 default:
1387                         /* Type Not Supported. */
1388                         DEBUG4(printk(KERN_WARNING
1389                             "scsi(%ld): Received unknown response pkt type %x "
1390                             "entry status=%x.\n",
1391                             ha->host_no, pkt->entry_type, pkt->entry_status));
1392                         break;
1393                 }
1394                 ((response_t *)pkt)->signature = RESPONSE_PROCESSED;
1395                 wmb();
1396         }
1397
1398         /* Adjust ring index */
1399         WRT_REG_DWORD(&reg->rsp_q_out, ha->rsp_ring_index);
1400 }
1401
1402 /**
1403  * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
1404  * @irq:
1405  * @dev_id: SCSI driver HA context
1406  * @regs:
1407  *
1408  * Called by system whenever the host adapter generates an interrupt.
1409  *
1410  * Returns handled flag.
1411  */
1412 irqreturn_t
1413 qla24xx_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
1414 {
1415         scsi_qla_host_t *ha;
1416         struct device_reg_24xx __iomem *reg;
1417         int             status;
1418         unsigned long   flags;
1419         unsigned long   iter;
1420         uint32_t        stat;
1421         uint32_t        hccr;
1422         uint16_t        mb[4];
1423
1424         ha = (scsi_qla_host_t *) dev_id;
1425         if (!ha) {
1426                 printk(KERN_INFO
1427                     "%s(): NULL host pointer\n", __func__);
1428                 return IRQ_NONE;
1429         }
1430
1431         reg = &ha->iobase->isp24;
1432         status = 0;
1433
1434         spin_lock_irqsave(&ha->hardware_lock, flags);
1435         for (iter = 50; iter--; ) {
1436                 stat = RD_REG_DWORD(&reg->host_status);
1437                 if (stat & HSRX_RISC_PAUSED) {
1438                         hccr = RD_REG_DWORD(&reg->hccr);
1439
1440                         qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
1441                             "Dumping firmware!\n", hccr);
1442                         qla24xx_fw_dump(ha, 1);
1443
1444                         set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1445                         break;
1446                 } else if ((stat & HSRX_RISC_INT) == 0)
1447                         break;
1448
1449                 switch (stat & 0xff) {
1450                 case 0x1:
1451                 case 0x2:
1452                 case 0x10:
1453                 case 0x11:
1454                         qla24xx_mbx_completion(ha, MSW(stat));
1455                         status |= MBX_INTERRUPT;
1456
1457                         break;
1458                 case 0x12:
1459                         mb[0] = MSW(stat);
1460                         mb[1] = RD_REG_WORD(&reg->mailbox1);
1461                         mb[2] = RD_REG_WORD(&reg->mailbox2);
1462                         mb[3] = RD_REG_WORD(&reg->mailbox3);
1463                         qla2x00_async_event(ha, mb);
1464                         break;
1465                 case 0x13:
1466                         qla24xx_process_response_queue(ha);
1467                         break;
1468                 default:
1469                         DEBUG2(printk("scsi(%ld): Unrecognized interrupt type "
1470                             "(%d).\n",
1471                             ha->host_no, stat & 0xff));
1472                         break;
1473                 }
1474                 WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
1475                 RD_REG_DWORD_RELAXED(&reg->hccr);
1476         }
1477         spin_unlock_irqrestore(&ha->hardware_lock, flags);
1478
1479         if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
1480             (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1481                 spin_lock_irqsave(&ha->mbx_reg_lock, flags);
1482
1483                 set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
1484                 up(&ha->mbx_intr_sem);
1485
1486                 spin_unlock_irqrestore(&ha->mbx_reg_lock, flags);
1487         }
1488
1489         return IRQ_HANDLED;
1490 }
1491
1492 /**
1493  * qla24xx_ms_entry() - Process a Management Server entry.
1494  * @ha: SCSI driver HA context
1495  * @index: Response queue out pointer
1496  */
1497 static void
1498 qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
1499 {
1500         srb_t          *sp;
1501
1502         DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
1503             __func__, ha->host_no, pkt, pkt->handle));
1504
1505         DEBUG9(printk("%s: ct pkt dump:\n", __func__);)
1506         DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx));)
1507
1508         /* Validate handle. */
1509         if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
1510                 sp = ha->outstanding_cmds[pkt->handle];
1511         else
1512                 sp = NULL;
1513
1514         if (sp == NULL) {
1515                 DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
1516                     ha->host_no));
1517                 DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
1518                     ha->host_no));
1519                 qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
1520                     pkt->handle);
1521
1522                 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
1523                 return;
1524         }
1525
1526         CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
1527         CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
1528
1529         /* Free outstanding command slot. */
1530         ha->outstanding_cmds[pkt->handle] = NULL;
1531
1532         qla2x00_sp_compl(ha, sp);
1533 }
1534