Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[pandora-kernel.git] / drivers / scsi / qla4xxx / ql4_isr.c
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c)  2003-2006 QLogic Corporation
4  *
5  * See LICENSE.qla4xxx for copyright and licensing details.
6  */
7
8 #include "ql4_def.h"
9 #include "ql4_glbl.h"
10 #include "ql4_dbg.h"
11 #include "ql4_inline.h"
12
13 /**
14  * qla4xxx_copy_sense - copy sense data into cmd sense buffer
15  * @ha: Pointer to host adapter structure.
16  * @sts_entry: Pointer to status entry structure.
17  * @srb: Pointer to srb structure.
18  **/
19 static void qla4xxx_copy_sense(struct scsi_qla_host *ha,
20                                struct status_entry *sts_entry,
21                                struct srb *srb)
22 {
23         struct scsi_cmnd *cmd = srb->cmd;
24         uint16_t sense_len;
25
26         memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
27         sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
28         if (sense_len == 0)
29                 return;
30
31         /* Save total available sense length,
32          * not to exceed cmd's sense buffer size */
33         sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE);
34         srb->req_sense_ptr = cmd->sense_buffer;
35         srb->req_sense_len = sense_len;
36
37         /* Copy sense from sts_entry pkt */
38         sense_len = min_t(uint16_t, sense_len, IOCB_MAX_SENSEDATA_LEN);
39         memcpy(cmd->sense_buffer, sts_entry->senseData, sense_len);
40
41         DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: %s: sense key = %x, "
42                 "ASL= %02x, ASC/ASCQ = %02x/%02x\n", ha->host_no,
43                 cmd->device->channel, cmd->device->id,
44                 cmd->device->lun, __func__,
45                 sts_entry->senseData[2] & 0x0f,
46                 sts_entry->senseData[7],
47                 sts_entry->senseData[12],
48                 sts_entry->senseData[13]));
49
50         DEBUG5(qla4xxx_dump_buffer(cmd->sense_buffer, sense_len));
51         srb->flags |= SRB_GOT_SENSE;
52
53         /* Update srb, in case a sts_cont pkt follows */
54         srb->req_sense_ptr += sense_len;
55         srb->req_sense_len -= sense_len;
56         if (srb->req_sense_len != 0)
57                 ha->status_srb = srb;
58         else
59                 ha->status_srb = NULL;
60 }
61
62 /**
63  * qla4xxx_status_cont_entry - Process a Status Continuations entry.
64  * @ha: SCSI driver HA context
65  * @sts_cont: Entry pointer
66  *
67  * Extended sense data.
68  */
69 static void
70 qla4xxx_status_cont_entry(struct scsi_qla_host *ha,
71                           struct status_cont_entry *sts_cont)
72 {
73         struct srb *srb = ha->status_srb;
74         struct scsi_cmnd *cmd;
75         uint16_t sense_len;
76
77         if (srb == NULL)
78                 return;
79
80         cmd = srb->cmd;
81         if (cmd == NULL) {
82                 DEBUG2(printk(KERN_INFO "scsi%ld: %s: Cmd already returned "
83                         "back to OS srb=%p srb->state:%d\n", ha->host_no,
84                         __func__, srb, srb->state));
85                 ha->status_srb = NULL;
86                 return;
87         }
88
89         /* Copy sense data. */
90         sense_len = min_t(uint16_t, srb->req_sense_len,
91                           IOCB_MAX_EXT_SENSEDATA_LEN);
92         memcpy(srb->req_sense_ptr, sts_cont->ext_sense_data, sense_len);
93         DEBUG5(qla4xxx_dump_buffer(srb->req_sense_ptr, sense_len));
94
95         srb->req_sense_ptr += sense_len;
96         srb->req_sense_len -= sense_len;
97
98         /* Place command on done queue. */
99         if (srb->req_sense_len == 0) {
100                 kref_put(&srb->srb_ref, qla4xxx_srb_compl);
101                 ha->status_srb = NULL;
102         }
103 }
104
105 /**
106  * qla4xxx_status_entry - processes status IOCBs
107  * @ha: Pointer to host adapter structure.
108  * @sts_entry: Pointer to status entry structure.
109  **/
110 static void qla4xxx_status_entry(struct scsi_qla_host *ha,
111                                  struct status_entry *sts_entry)
112 {
113         uint8_t scsi_status;
114         struct scsi_cmnd *cmd;
115         struct srb *srb;
116         struct ddb_entry *ddb_entry;
117         uint32_t residual;
118
119         srb = qla4xxx_del_from_active_array(ha, le32_to_cpu(sts_entry->handle));
120         if (!srb) {
121                 DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid "
122                               "handle 0x%x, sp=%p. This cmd may have already "
123                               "been completed.\n", ha->host_no, __func__,
124                               le32_to_cpu(sts_entry->handle), srb));
125                 ql4_printk(KERN_WARNING, ha, "%s invalid status entry:"
126                     " handle=0x%0x\n", __func__, sts_entry->handle);
127                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
128                 return;
129         }
130
131         cmd = srb->cmd;
132         if (cmd == NULL) {
133                 DEBUG2(printk("scsi%ld: %s: Command already returned back to "
134                               "OS pkt->handle=%d srb=%p srb->state:%d\n",
135                               ha->host_no, __func__, sts_entry->handle,
136                               srb, srb->state));
137                 ql4_printk(KERN_WARNING, ha, "Command is NULL:"
138                     " already returned to OS (srb=%p)\n", srb);
139                 return;
140         }
141
142         ddb_entry = srb->ddb;
143         if (ddb_entry == NULL) {
144                 cmd->result = DID_NO_CONNECT << 16;
145                 goto status_entry_exit;
146         }
147
148         residual = le32_to_cpu(sts_entry->residualByteCnt);
149
150         /* Translate ISP error to a Linux SCSI error. */
151         scsi_status = sts_entry->scsiStatus;
152         switch (sts_entry->completionStatus) {
153         case SCS_COMPLETE:
154
155                 if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) {
156                         cmd->result = DID_ERROR << 16;
157                         break;
158                 }
159
160                 if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) {
161                         scsi_set_resid(cmd, residual);
162                         if (!scsi_status && ((scsi_bufflen(cmd) - residual) <
163                                 cmd->underflow)) {
164
165                                 cmd->result = DID_ERROR << 16;
166
167                                 DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
168                                         "Mid-layer Data underrun0, "
169                                         "xferlen = 0x%x, "
170                                         "residual = 0x%x\n", ha->host_no,
171                                         cmd->device->channel,
172                                         cmd->device->id,
173                                         cmd->device->lun, __func__,
174                                         scsi_bufflen(cmd), residual));
175                                 break;
176                         }
177                 }
178
179                 cmd->result = DID_OK << 16 | scsi_status;
180
181                 if (scsi_status != SCSI_CHECK_CONDITION)
182                         break;
183
184                 /* Copy Sense Data into sense buffer. */
185                 qla4xxx_copy_sense(ha, sts_entry, srb);
186                 break;
187
188         case SCS_INCOMPLETE:
189                 /* Always set the status to DID_ERROR, since
190                  * all conditions result in that status anyway */
191                 cmd->result = DID_ERROR << 16;
192                 break;
193
194         case SCS_RESET_OCCURRED:
195                 DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n",
196                               ha->host_no, cmd->device->channel,
197                               cmd->device->id, cmd->device->lun, __func__));
198
199                 cmd->result = DID_RESET << 16;
200                 break;
201
202         case SCS_ABORTED:
203                 DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n",
204                               ha->host_no, cmd->device->channel,
205                               cmd->device->id, cmd->device->lun, __func__));
206
207                 cmd->result = DID_RESET << 16;
208                 break;
209
210         case SCS_TIMEOUT:
211                 DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n",
212                               ha->host_no, cmd->device->channel,
213                               cmd->device->id, cmd->device->lun));
214
215                 cmd->result = DID_TRANSPORT_DISRUPTED << 16;
216
217                 /*
218                  * Mark device missing so that we won't continue to send
219                  * I/O to this device.  We should get a ddb state change
220                  * AEN soon.
221                  */
222                 if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
223                         qla4xxx_mark_device_missing(ha, ddb_entry);
224                 break;
225
226         case SCS_DATA_UNDERRUN:
227         case SCS_DATA_OVERRUN:
228                 if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) ||
229                      (sts_entry->completionStatus == SCS_DATA_OVERRUN)) {
230                         DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun\n",
231                                       ha->host_no,
232                                       cmd->device->channel, cmd->device->id,
233                                       cmd->device->lun, __func__));
234
235                         cmd->result = DID_ERROR << 16;
236                         break;
237                 }
238
239                 scsi_set_resid(cmd, residual);
240
241                 /*
242                  * If there is scsi_status, it takes precedense over
243                  * underflow condition.
244                  */
245                 if (scsi_status != 0) {
246                         cmd->result = DID_OK << 16 | scsi_status;
247
248                         if (scsi_status != SCSI_CHECK_CONDITION)
249                                 break;
250
251                         /* Copy Sense Data into sense buffer. */
252                         qla4xxx_copy_sense(ha, sts_entry, srb);
253                 } else {
254                         /*
255                          * If RISC reports underrun and target does not
256                          * report it then we must have a lost frame, so
257                          * tell upper layer to retry it by reporting a
258                          * bus busy.
259                          */
260                         if ((sts_entry->iscsiFlags &
261                              ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
262                                 cmd->result = DID_BUS_BUSY << 16;
263                         } else if ((scsi_bufflen(cmd) - residual) <
264                                    cmd->underflow) {
265                                 /*
266                                  * Handle mid-layer underflow???
267                                  *
268                                  * For kernels less than 2.4, the driver must
269                                  * return an error if an underflow is detected.
270                                  * For kernels equal-to and above 2.4, the
271                                  * mid-layer will appearantly handle the
272                                  * underflow by detecting the residual count --
273                                  * unfortunately, we do not see where this is
274                                  * actually being done.  In the interim, we
275                                  * will return DID_ERROR.
276                                  */
277                                 DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
278                                         "Mid-layer Data underrun1, "
279                                         "xferlen = 0x%x, "
280                                         "residual = 0x%x\n", ha->host_no,
281                                         cmd->device->channel,
282                                         cmd->device->id,
283                                         cmd->device->lun, __func__,
284                                         scsi_bufflen(cmd), residual));
285
286                                 cmd->result = DID_ERROR << 16;
287                         } else {
288                                 cmd->result = DID_OK << 16;
289                         }
290                 }
291                 break;
292
293         case SCS_DEVICE_LOGGED_OUT:
294         case SCS_DEVICE_UNAVAILABLE:
295                 DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: SCS_DEVICE "
296                     "state: 0x%x\n", ha->host_no,
297                     cmd->device->channel, cmd->device->id,
298                     cmd->device->lun, sts_entry->completionStatus));
299                 /*
300                  * Mark device missing so that we won't continue to
301                  * send I/O to this device.  We should get a ddb
302                  * state change AEN soon.
303                  */
304                 if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
305                         qla4xxx_mark_device_missing(ha, ddb_entry);
306
307                 cmd->result = DID_TRANSPORT_DISRUPTED << 16;
308                 break;
309
310         case SCS_QUEUE_FULL:
311                 /*
312                  * SCSI Mid-Layer handles device queue full
313                  */
314                 cmd->result = DID_OK << 16 | sts_entry->scsiStatus;
315                 DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected "
316                               "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x,"
317                               " iResp=%02x\n", ha->host_no, cmd->device->id,
318                               cmd->device->lun, __func__,
319                               sts_entry->completionStatus,
320                               sts_entry->scsiStatus, sts_entry->state_flags,
321                               sts_entry->iscsiFlags,
322                               sts_entry->iscsiResponse));
323                 break;
324
325         default:
326                 cmd->result = DID_ERROR << 16;
327                 break;
328         }
329
330 status_entry_exit:
331
332         /* complete the request, if not waiting for status_continuation pkt */
333         srb->cc_stat = sts_entry->completionStatus;
334         if (ha->status_srb == NULL)
335                 kref_put(&srb->srb_ref, qla4xxx_srb_compl);
336 }
337
338 /**
339  * qla4xxx_process_response_queue - process response queue completions
340  * @ha: Pointer to host adapter structure.
341  *
342  * This routine process response queue completions in interrupt context.
343  * Hardware_lock locked upon entry
344  **/
345 void qla4xxx_process_response_queue(struct scsi_qla_host *ha)
346 {
347         uint32_t count = 0;
348         struct srb *srb = NULL;
349         struct status_entry *sts_entry;
350
351         /* Process all responses from response queue */
352         while ((ha->response_ptr->signature != RESPONSE_PROCESSED)) {
353                 sts_entry = (struct status_entry *) ha->response_ptr;
354                 count++;
355
356                 /* Advance pointers for next entry */
357                 if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) {
358                         ha->response_out = 0;
359                         ha->response_ptr = ha->response_ring;
360                 } else {
361                         ha->response_out++;
362                         ha->response_ptr++;
363                 }
364
365                 /* process entry */
366                 switch (sts_entry->hdr.entryType) {
367                 case ET_STATUS:
368                         /* Common status */
369                         qla4xxx_status_entry(ha, sts_entry);
370                         break;
371
372                 case ET_PASSTHRU_STATUS:
373                         break;
374
375                 case ET_STATUS_CONTINUATION:
376                         qla4xxx_status_cont_entry(ha,
377                                 (struct status_cont_entry *) sts_entry);
378                         break;
379
380                 case ET_COMMAND:
381                         /* ISP device queue is full. Command not
382                          * accepted by ISP.  Queue command for
383                          * later */
384
385                         srb = qla4xxx_del_from_active_array(ha,
386                                                     le32_to_cpu(sts_entry->
387                                                                 handle));
388                         if (srb == NULL)
389                                 goto exit_prq_invalid_handle;
390
391                         DEBUG2(printk("scsi%ld: %s: FW device queue full, "
392                                       "srb %p\n", ha->host_no, __func__, srb));
393
394                         /* ETRY normally by sending it back with
395                          * DID_BUS_BUSY */
396                         srb->cmd->result = DID_BUS_BUSY << 16;
397                         kref_put(&srb->srb_ref, qla4xxx_srb_compl);
398                         break;
399
400                 case ET_CONTINUE:
401                         /* Just throw away the continuation entries */
402                         DEBUG2(printk("scsi%ld: %s: Continuation entry - "
403                                       "ignoring\n", ha->host_no, __func__));
404                         break;
405
406                 default:
407                         /*
408                          * Invalid entry in response queue, reset RISC
409                          * firmware.
410                          */
411                         DEBUG2(printk("scsi%ld: %s: Invalid entry %x in "
412                                       "response queue \n", ha->host_no,
413                                       __func__,
414                                       sts_entry->hdr.entryType));
415                         goto exit_prq_error;
416                 }
417                 ((struct response *)sts_entry)->signature = RESPONSE_PROCESSED;
418                 wmb();
419         }
420
421         /*
422          * Tell ISP we're done with response(s). This also clears the interrupt.
423          */
424         ha->isp_ops->complete_iocb(ha);
425
426         return;
427
428 exit_prq_invalid_handle:
429         DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n",
430                       ha->host_no, __func__, srb, sts_entry->hdr.entryType,
431                       sts_entry->completionStatus));
432
433 exit_prq_error:
434         ha->isp_ops->complete_iocb(ha);
435         set_bit(DPC_RESET_HA, &ha->dpc_flags);
436 }
437
438 /**
439  * qla4xxx_isr_decode_mailbox - decodes mailbox status
440  * @ha: Pointer to host adapter structure.
441  * @mailbox_status: Mailbox status.
442  *
443  * This routine decodes the mailbox status during the ISR.
444  * Hardware_lock locked upon entry. runs in interrupt context.
445  **/
446 static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
447                                        uint32_t mbox_status)
448 {
449         int i;
450         uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
451
452         if ((mbox_status == MBOX_STS_BUSY) ||
453             (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
454             (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) {
455                 ha->mbox_status[0] = mbox_status;
456
457                 if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
458                         /*
459                          * Copy all mailbox registers to a temporary
460                          * location and set mailbox command done flag
461                          */
462                         for (i = 0; i < ha->mbox_status_count; i++)
463                                 ha->mbox_status[i] = is_qla8022(ha)
464                                     ? readl(&ha->qla4_8xxx_reg->mailbox_out[i])
465                                     : readl(&ha->reg->mailbox[i]);
466
467                         set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
468
469                         if (test_bit(AF_MBOX_COMMAND_NOPOLL, &ha->flags))
470                                 complete(&ha->mbx_intr_comp);
471                 }
472         } else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
473                 for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
474                         mbox_sts[i] = is_qla8022(ha)
475                             ? readl(&ha->qla4_8xxx_reg->mailbox_out[i])
476                             : readl(&ha->reg->mailbox[i]);
477
478                 /* Immediately process the AENs that don't require much work.
479                  * Only queue the database_changed AENs */
480                 if (ha->aen_log.count < MAX_AEN_ENTRIES) {
481                         for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
482                                 ha->aen_log.entry[ha->aen_log.count].mbox_sts[i] =
483                                     mbox_sts[i];
484                         ha->aen_log.count++;
485                 }
486                 switch (mbox_status) {
487                 case MBOX_ASTS_SYSTEM_ERROR:
488                         /* Log Mailbox registers */
489                         ql4_printk(KERN_INFO, ha, "%s: System Err\n", __func__);
490                         qla4xxx_dump_registers(ha);
491
492                         if (ql4xdontresethba) {
493                                 DEBUG2(printk("scsi%ld: %s:Don't Reset HBA\n",
494                                     ha->host_no, __func__));
495                         } else {
496                                 set_bit(AF_GET_CRASH_RECORD, &ha->flags);
497                                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
498                         }
499                         break;
500
501                 case MBOX_ASTS_REQUEST_TRANSFER_ERROR:
502                 case MBOX_ASTS_RESPONSE_TRANSFER_ERROR:
503                 case MBOX_ASTS_NVRAM_INVALID:
504                 case MBOX_ASTS_IP_ADDRESS_CHANGED:
505                 case MBOX_ASTS_DHCP_LEASE_EXPIRED:
506                         DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, "
507                                       "Reset HA\n", ha->host_no, mbox_status));
508                         set_bit(DPC_RESET_HA, &ha->dpc_flags);
509                         break;
510
511                 case MBOX_ASTS_LINK_UP:
512                         set_bit(AF_LINK_UP, &ha->flags);
513                         if (test_bit(AF_INIT_DONE, &ha->flags))
514                                 set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
515
516                         ql4_printk(KERN_INFO, ha, "%s: LINK UP\n", __func__);
517                         break;
518
519                 case MBOX_ASTS_LINK_DOWN:
520                         clear_bit(AF_LINK_UP, &ha->flags);
521                         if (test_bit(AF_INIT_DONE, &ha->flags))
522                                 set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
523
524                         ql4_printk(KERN_INFO, ha, "%s: LINK DOWN\n", __func__);
525                         break;
526
527                 case MBOX_ASTS_HEARTBEAT:
528                         ha->seconds_since_last_heartbeat = 0;
529                         break;
530
531                 case MBOX_ASTS_DHCP_LEASE_ACQUIRED:
532                         DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE "
533                                       "ACQUIRED\n", ha->host_no, mbox_status));
534                         set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
535                         break;
536
537                 case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM:
538                 case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target
539                                                            * mode
540                                                            * only */
541                 case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED:  /* Connection mode */
542                 case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR:
543                 case MBOX_ASTS_SUBNET_STATE_CHANGE:
544                         /* No action */
545                         DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no,
546                                       mbox_status));
547                         break;
548
549                 case MBOX_ASTS_IP_ADDR_STATE_CHANGED:
550                         printk("scsi%ld: AEN %04x, mbox_sts[2]=%04x, "
551                             "mbox_sts[3]=%04x\n", ha->host_no, mbox_sts[0],
552                             mbox_sts[2], mbox_sts[3]);
553
554                         /* mbox_sts[2] = Old ACB state
555                          * mbox_sts[3] = new ACB state */
556                         if ((mbox_sts[3] == ACB_STATE_VALID) &&
557                             (mbox_sts[2] == ACB_STATE_TENTATIVE))
558                                 set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
559                         else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
560                             (mbox_sts[2] == ACB_STATE_VALID))
561                                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
562                         break;
563
564                 case MBOX_ASTS_MAC_ADDRESS_CHANGED:
565                 case MBOX_ASTS_DNS:
566                         /* No action */
567                         DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, "
568                                       "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n",
569                                       ha->host_no, mbox_sts[0],
570                                       mbox_sts[1], mbox_sts[2]));
571                         break;
572
573                 case MBOX_ASTS_SELF_TEST_FAILED:
574                 case MBOX_ASTS_LOGIN_FAILED:
575                         /* No action */
576                         DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, "
577                                       "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n",
578                                       ha->host_no, mbox_sts[0], mbox_sts[1],
579                                       mbox_sts[2], mbox_sts[3]));
580                         break;
581
582                 case MBOX_ASTS_DATABASE_CHANGED:
583                         /* Queue AEN information and process it in the DPC
584                          * routine */
585                         if (ha->aen_q_count > 0) {
586
587                                 /* decrement available counter */
588                                 ha->aen_q_count--;
589
590                                 for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
591                                         ha->aen_q[ha->aen_in].mbox_sts[i] =
592                                             mbox_sts[i];
593
594                                 /* print debug message */
595                                 DEBUG2(printk("scsi%ld: AEN[%d] %04x queued"
596                                     " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n",
597                                     ha->host_no, ha->aen_in, mbox_sts[0],
598                                     mbox_sts[1], mbox_sts[2],  mbox_sts[3],
599                                     mbox_sts[4]));
600
601                                 /* advance pointer */
602                                 ha->aen_in++;
603                                 if (ha->aen_in == MAX_AEN_ENTRIES)
604                                         ha->aen_in = 0;
605
606                                 /* The DPC routine will process the aen */
607                                 set_bit(DPC_AEN, &ha->dpc_flags);
608                         } else {
609                                 DEBUG2(printk("scsi%ld: %s: aen %04x, queue "
610                                               "overflowed!  AEN LOST!!\n",
611                                               ha->host_no, __func__,
612                                               mbox_sts[0]));
613
614                                 DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n",
615                                               ha->host_no));
616
617                                 for (i = 0; i < MAX_AEN_ENTRIES; i++) {
618                                         DEBUG2(printk("AEN[%d] %04x %04x %04x "
619                                                       "%04x\n", i, mbox_sts[0],
620                                                       mbox_sts[1], mbox_sts[2],
621                                                       mbox_sts[3]));
622                                 }
623                         }
624                         break;
625
626                 case MBOX_ASTS_TXSCVR_INSERTED:
627                         DEBUG2(printk(KERN_WARNING
628                             "scsi%ld: AEN %04x Transceiver"
629                             " inserted\n",  ha->host_no, mbox_sts[0]));
630                         break;
631
632                 case MBOX_ASTS_TXSCVR_REMOVED:
633                         DEBUG2(printk(KERN_WARNING
634                             "scsi%ld: AEN %04x Transceiver"
635                             " removed\n",  ha->host_no, mbox_sts[0]));
636                         break;
637
638                 default:
639                         DEBUG2(printk(KERN_WARNING
640                                       "scsi%ld: AEN %04x UNKNOWN\n",
641                                       ha->host_no, mbox_sts[0]));
642                         break;
643                 }
644         } else {
645                 DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n",
646                               ha->host_no, mbox_status));
647
648                 ha->mbox_status[0] = mbox_status;
649         }
650 }
651
652 /**
653  * qla4_8xxx_interrupt_service_routine - isr
654  * @ha: pointer to host adapter structure.
655  *
656  * This is the main interrupt service routine.
657  * hardware_lock locked upon entry. runs in interrupt context.
658  **/
659 void qla4_8xxx_interrupt_service_routine(struct scsi_qla_host *ha,
660     uint32_t intr_status)
661 {
662         /* Process response queue interrupt. */
663         if (intr_status & HSRX_RISC_IOCB_INT)
664                 qla4xxx_process_response_queue(ha);
665
666         /* Process mailbox/asynch event interrupt.*/
667         if (intr_status & HSRX_RISC_MB_INT)
668                 qla4xxx_isr_decode_mailbox(ha,
669                     readl(&ha->qla4_8xxx_reg->mailbox_out[0]));
670
671         /* clear the interrupt */
672         writel(0, &ha->qla4_8xxx_reg->host_int);
673         readl(&ha->qla4_8xxx_reg->host_int);
674 }
675
676 /**
677  * qla4xxx_interrupt_service_routine - isr
678  * @ha: pointer to host adapter structure.
679  *
680  * This is the main interrupt service routine.
681  * hardware_lock locked upon entry. runs in interrupt context.
682  **/
683 void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
684                                        uint32_t intr_status)
685 {
686         /* Process response queue interrupt. */
687         if (intr_status & CSR_SCSI_COMPLETION_INTR)
688                 qla4xxx_process_response_queue(ha);
689
690         /* Process mailbox/asynch event  interrupt.*/
691         if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
692                 qla4xxx_isr_decode_mailbox(ha,
693                                            readl(&ha->reg->mailbox[0]));
694
695                 /* Clear Mailbox Interrupt */
696                 writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
697                        &ha->reg->ctrl_status);
698                 readl(&ha->reg->ctrl_status);
699         }
700 }
701
702 /**
703  * qla4_8xxx_spurious_interrupt - processes spurious interrupt
704  * @ha: pointer to host adapter structure.
705  * @reqs_count: .
706  *
707  **/
708 static void qla4_8xxx_spurious_interrupt(struct scsi_qla_host *ha,
709     uint8_t reqs_count)
710 {
711         if (reqs_count)
712                 return;
713
714         DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n"));
715         if (is_qla8022(ha)) {
716                 writel(0, &ha->qla4_8xxx_reg->host_int);
717                 if (test_bit(AF_INTx_ENABLED, &ha->flags))
718                         qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
719                             0xfbff);
720         }
721         ha->spurious_int_count++;
722 }
723
724 /**
725  * qla4xxx_intr_handler - hardware interrupt handler.
726  * @irq: Unused
727  * @dev_id: Pointer to host adapter structure
728  **/
729 irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
730 {
731         struct scsi_qla_host *ha;
732         uint32_t intr_status;
733         unsigned long flags = 0;
734         uint8_t reqs_count = 0;
735
736         ha = (struct scsi_qla_host *) dev_id;
737         if (!ha) {
738                 DEBUG2(printk(KERN_INFO
739                               "qla4xxx: Interrupt with NULL host ptr\n"));
740                 return IRQ_NONE;
741         }
742
743         spin_lock_irqsave(&ha->hardware_lock, flags);
744
745         ha->isr_count++;
746         /*
747          * Repeatedly service interrupts up to a maximum of
748          * MAX_REQS_SERVICED_PER_INTR
749          */
750         while (1) {
751                 /*
752                  * Read interrupt status
753                  */
754                 if (ha->isp_ops->rd_shdw_rsp_q_in(ha) !=
755                     ha->response_out)
756                         intr_status = CSR_SCSI_COMPLETION_INTR;
757                 else
758                         intr_status = readl(&ha->reg->ctrl_status);
759
760                 if ((intr_status &
761                     (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == 0) {
762                         if (reqs_count == 0)
763                                 ha->spurious_int_count++;
764                         break;
765                 }
766
767                 if (intr_status & CSR_FATAL_ERROR) {
768                         DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, "
769                                       "Status 0x%04x\n", ha->host_no,
770                                       readl(isp_port_error_status (ha))));
771
772                         /* Issue Soft Reset to clear this error condition.
773                          * This will prevent the RISC from repeatedly
774                          * interrupting the driver; thus, allowing the DPC to
775                          * get scheduled to continue error recovery.
776                          * NOTE: Disabling RISC interrupts does not work in
777                          * this case, as CSR_FATAL_ERROR overrides
778                          * CSR_SCSI_INTR_ENABLE */
779                         if ((readl(&ha->reg->ctrl_status) &
780                              CSR_SCSI_RESET_INTR) == 0) {
781                                 writel(set_rmask(CSR_SOFT_RESET),
782                                        &ha->reg->ctrl_status);
783                                 readl(&ha->reg->ctrl_status);
784                         }
785
786                         writel(set_rmask(CSR_FATAL_ERROR),
787                                &ha->reg->ctrl_status);
788                         readl(&ha->reg->ctrl_status);
789
790                         __qla4xxx_disable_intrs(ha);
791
792                         set_bit(DPC_RESET_HA, &ha->dpc_flags);
793
794                         break;
795                 } else if (intr_status & CSR_SCSI_RESET_INTR) {
796                         clear_bit(AF_ONLINE, &ha->flags);
797                         __qla4xxx_disable_intrs(ha);
798
799                         writel(set_rmask(CSR_SCSI_RESET_INTR),
800                                &ha->reg->ctrl_status);
801                         readl(&ha->reg->ctrl_status);
802
803                         if (!test_bit(AF_HBA_GOING_AWAY, &ha->flags))
804                                 set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
805
806                         break;
807                 } else if (intr_status & INTR_PENDING) {
808                         ha->isp_ops->interrupt_service_routine(ha, intr_status);
809                         ha->total_io_count++;
810                         if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
811                                 break;
812                 }
813         }
814
815         spin_unlock_irqrestore(&ha->hardware_lock, flags);
816
817         return IRQ_HANDLED;
818 }
819
820 /**
821  * qla4_8xxx_intr_handler - hardware interrupt handler.
822  * @irq: Unused
823  * @dev_id: Pointer to host adapter structure
824  **/
825 irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
826 {
827         struct scsi_qla_host *ha = dev_id;
828         uint32_t intr_status;
829         uint32_t status;
830         unsigned long flags = 0;
831         uint8_t reqs_count = 0;
832
833         if (unlikely(pci_channel_offline(ha->pdev)))
834                 return IRQ_HANDLED;
835
836         ha->isr_count++;
837         status = qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
838         if (!(status & ha->nx_legacy_intr.int_vec_bit))
839                 return IRQ_NONE;
840
841         status = qla4_8xxx_rd_32(ha, ISR_INT_STATE_REG);
842         if (!ISR_IS_LEGACY_INTR_TRIGGERED(status)) {
843                 DEBUG2(ql4_printk(KERN_INFO, ha,
844                     "%s legacy Int not triggered\n", __func__));
845                 return IRQ_NONE;
846         }
847
848         /* clear the interrupt */
849         qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
850
851         /* read twice to ensure write is flushed */
852         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
853         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
854
855         spin_lock_irqsave(&ha->hardware_lock, flags);
856         while (1) {
857                 if (!(readl(&ha->qla4_8xxx_reg->host_int) &
858                     ISRX_82XX_RISC_INT)) {
859                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
860                         break;
861                 }
862                 intr_status =  readl(&ha->qla4_8xxx_reg->host_status);
863                 if ((intr_status &
864                     (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0)  {
865                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
866                         break;
867                 }
868
869                 ha->isp_ops->interrupt_service_routine(ha, intr_status);
870
871                 /* Enable Interrupt */
872                 qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
873
874                 if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
875                         break;
876         }
877
878         spin_unlock_irqrestore(&ha->hardware_lock, flags);
879         return IRQ_HANDLED;
880 }
881
882 irqreturn_t
883 qla4_8xxx_msi_handler(int irq, void *dev_id)
884 {
885         struct scsi_qla_host *ha;
886
887         ha = (struct scsi_qla_host *) dev_id;
888         if (!ha) {
889                 DEBUG2(printk(KERN_INFO
890                     "qla4xxx: MSIX: Interrupt with NULL host ptr\n"));
891                 return IRQ_NONE;
892         }
893
894         ha->isr_count++;
895         /* clear the interrupt */
896         qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
897
898         /* read twice to ensure write is flushed */
899         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
900         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
901
902         return qla4_8xxx_default_intr_handler(irq, dev_id);
903 }
904
905 /**
906  * qla4_8xxx_default_intr_handler - hardware interrupt handler.
907  * @irq: Unused
908  * @dev_id: Pointer to host adapter structure
909  *
910  * This interrupt handler is called directly for MSI-X, and
911  * called indirectly for MSI.
912  **/
913 irqreturn_t
914 qla4_8xxx_default_intr_handler(int irq, void *dev_id)
915 {
916         struct scsi_qla_host *ha = dev_id;
917         unsigned long   flags;
918         uint32_t intr_status;
919         uint8_t reqs_count = 0;
920
921         spin_lock_irqsave(&ha->hardware_lock, flags);
922         while (1) {
923                 if (!(readl(&ha->qla4_8xxx_reg->host_int) &
924                     ISRX_82XX_RISC_INT)) {
925                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
926                         break;
927                 }
928
929                 intr_status =  readl(&ha->qla4_8xxx_reg->host_status);
930                 if ((intr_status &
931                     (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
932                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
933                         break;
934                 }
935
936                 ha->isp_ops->interrupt_service_routine(ha, intr_status);
937
938                 if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
939                         break;
940         }
941
942         ha->isr_count++;
943         spin_unlock_irqrestore(&ha->hardware_lock, flags);
944         return IRQ_HANDLED;
945 }
946
947 irqreturn_t
948 qla4_8xxx_msix_rsp_q(int irq, void *dev_id)
949 {
950         struct scsi_qla_host *ha = dev_id;
951         unsigned long flags;
952
953         spin_lock_irqsave(&ha->hardware_lock, flags);
954         qla4xxx_process_response_queue(ha);
955         writel(0, &ha->qla4_8xxx_reg->host_int);
956         spin_unlock_irqrestore(&ha->hardware_lock, flags);
957
958         ha->isr_count++;
959         return IRQ_HANDLED;
960 }
961
962 /**
963  * qla4xxx_process_aen - processes AENs generated by firmware
964  * @ha: pointer to host adapter structure.
965  * @process_aen: type of AENs to process
966  *
967  * Processes specific types of Asynchronous Events generated by firmware.
968  * The type of AENs to process is specified by process_aen and can be
969  *      PROCESS_ALL_AENS         0
970  *      FLUSH_DDB_CHANGED_AENS   1
971  *      RELOGIN_DDB_CHANGED_AENS 2
972  **/
973 void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
974 {
975         uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
976         struct aen *aen;
977         int i;
978         unsigned long flags;
979
980         spin_lock_irqsave(&ha->hardware_lock, flags);
981         while (ha->aen_out != ha->aen_in) {
982                 aen = &ha->aen_q[ha->aen_out];
983                 /* copy aen information to local structure */
984                 for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
985                         mbox_sts[i] = aen->mbox_sts[i];
986
987                 ha->aen_q_count++;
988                 ha->aen_out++;
989
990                 if (ha->aen_out == MAX_AEN_ENTRIES)
991                         ha->aen_out = 0;
992
993                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
994
995                 DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x"
996                         " mbx3=0x%08x mbx4=0x%08x\n", ha->host_no,
997                         (ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)),
998                         mbox_sts[0], mbox_sts[1], mbox_sts[2],
999                         mbox_sts[3], mbox_sts[4]));
1000
1001                 switch (mbox_sts[0]) {
1002                 case MBOX_ASTS_DATABASE_CHANGED:
1003                         if (process_aen == FLUSH_DDB_CHANGED_AENS) {
1004                                 DEBUG2(printk("scsi%ld: AEN[%d] %04x, index "
1005                                               "[%d] state=%04x FLUSHED!\n",
1006                                               ha->host_no, ha->aen_out,
1007                                               mbox_sts[0], mbox_sts[2],
1008                                               mbox_sts[3]));
1009                                 break;
1010                         } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) {
1011                                 /* for use during init time, we only want to
1012                                  * relogin non-active ddbs */
1013                                 struct ddb_entry *ddb_entry;
1014
1015                                 ddb_entry =
1016                                         /* FIXME: name length? */
1017                                         qla4xxx_lookup_ddb_by_fw_index(ha,
1018                                                                        mbox_sts[2]);
1019                                 if (!ddb_entry)
1020                                         break;
1021
1022                                 ddb_entry->dev_scan_wait_to_complete_relogin =
1023                                         0;
1024                                 ddb_entry->dev_scan_wait_to_start_relogin =
1025                                         jiffies +
1026                                         ((ddb_entry->default_time2wait +
1027                                           4) * HZ);
1028
1029                                 DEBUG2(printk("scsi%ld: ddb [%d] initate"
1030                                               " RELOGIN after %d seconds\n",
1031                                               ha->host_no,
1032                                               ddb_entry->fw_ddb_index,
1033                                               ddb_entry->default_time2wait +
1034                                               4));
1035                                 break;
1036                         }
1037
1038                         if (mbox_sts[1] == 0) { /* Global DB change. */
1039                                 qla4xxx_reinitialize_ddb_list(ha);
1040                         } else if (mbox_sts[1] == 1) {  /* Specific device. */
1041                                 qla4xxx_process_ddb_changed(ha, mbox_sts[2],
1042                                                 mbox_sts[3], mbox_sts[4]);
1043                         }
1044                         break;
1045                 }
1046                 spin_lock_irqsave(&ha->hardware_lock, flags);
1047         }
1048         spin_unlock_irqrestore(&ha->hardware_lock, flags);
1049 }
1050
1051 int qla4xxx_request_irqs(struct scsi_qla_host *ha)
1052 {
1053         int ret;
1054
1055         if (!is_qla8022(ha))
1056                 goto try_intx;
1057
1058         if (ql4xenablemsix == 2)
1059                 goto try_msi;
1060
1061         if (ql4xenablemsix == 0 || ql4xenablemsix != 1)
1062                 goto try_intx;
1063
1064         /* Trying MSI-X */
1065         ret = qla4_8xxx_enable_msix(ha);
1066         if (!ret) {
1067                 DEBUG2(ql4_printk(KERN_INFO, ha,
1068                     "MSI-X: Enabled (0x%X).\n", ha->revision_id));
1069                 goto irq_attached;
1070         }
1071
1072         ql4_printk(KERN_WARNING, ha,
1073             "MSI-X: Falling back-to MSI mode -- %d.\n", ret);
1074
1075 try_msi:
1076         /* Trying MSI */
1077         ret = pci_enable_msi(ha->pdev);
1078         if (!ret) {
1079                 ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler,
1080                         IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha);
1081                 if (!ret) {
1082                         DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
1083                         set_bit(AF_MSI_ENABLED, &ha->flags);
1084                         goto irq_attached;
1085                 } else {
1086                         ql4_printk(KERN_WARNING, ha,
1087                             "MSI: Failed to reserve interrupt %d "
1088                             "already in use.\n", ha->pdev->irq);
1089                         pci_disable_msi(ha->pdev);
1090                 }
1091         }
1092         ql4_printk(KERN_WARNING, ha,
1093             "MSI: Falling back-to INTx mode -- %d.\n", ret);
1094
1095 try_intx:
1096         /* Trying INTx */
1097         ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
1098             IRQF_DISABLED|IRQF_SHARED, DRIVER_NAME, ha);
1099         if (!ret) {
1100                 DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n"));
1101                 set_bit(AF_INTx_ENABLED, &ha->flags);
1102                 goto irq_attached;
1103
1104         } else {
1105                 ql4_printk(KERN_WARNING, ha,
1106                     "INTx: Failed to reserve interrupt %d already in"
1107                     " use.\n", ha->pdev->irq);
1108                 return ret;
1109         }
1110
1111 irq_attached:
1112         set_bit(AF_IRQ_ATTACHED, &ha->flags);
1113         ha->host->irq = ha->pdev->irq;
1114         ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n",
1115             __func__, ha->pdev->irq);
1116         return ret;
1117 }
1118
1119 void qla4xxx_free_irqs(struct scsi_qla_host *ha)
1120 {
1121         if (test_bit(AF_MSIX_ENABLED, &ha->flags))
1122                 qla4_8xxx_disable_msix(ha);
1123         else if (test_and_clear_bit(AF_MSI_ENABLED, &ha->flags)) {
1124                 free_irq(ha->pdev->irq, ha);
1125                 pci_disable_msi(ha->pdev);
1126         } else if (test_and_clear_bit(AF_INTx_ENABLED, &ha->flags))
1127                 free_irq(ha->pdev->irq, ha);
1128 }