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