Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel...
[pandora-kernel.git] / drivers / scsi / qla4xxx / ql4_isr.c
1 /*
2  * QLogic iSCSI HBA Driver
3  * Copyright (c)  2003-2010 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                             (mbox_sts[2] == ACB_STATE_ACQUIRING)))
559                                 set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
560                         else if ((mbox_sts[3] == ACB_STATE_ACQUIRING) &&
561                             (mbox_sts[2] == ACB_STATE_VALID))
562                                 set_bit(DPC_RESET_HA, &ha->dpc_flags);
563                         break;
564
565                 case MBOX_ASTS_MAC_ADDRESS_CHANGED:
566                 case MBOX_ASTS_DNS:
567                         /* No action */
568                         DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, "
569                                       "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n",
570                                       ha->host_no, mbox_sts[0],
571                                       mbox_sts[1], mbox_sts[2]));
572                         break;
573
574                 case MBOX_ASTS_SELF_TEST_FAILED:
575                 case MBOX_ASTS_LOGIN_FAILED:
576                         /* No action */
577                         DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, "
578                                       "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n",
579                                       ha->host_no, mbox_sts[0], mbox_sts[1],
580                                       mbox_sts[2], mbox_sts[3]));
581                         break;
582
583                 case MBOX_ASTS_DATABASE_CHANGED:
584                         /* Queue AEN information and process it in the DPC
585                          * routine */
586                         if (ha->aen_q_count > 0) {
587
588                                 /* decrement available counter */
589                                 ha->aen_q_count--;
590
591                                 for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
592                                         ha->aen_q[ha->aen_in].mbox_sts[i] =
593                                             mbox_sts[i];
594
595                                 /* print debug message */
596                                 DEBUG2(printk("scsi%ld: AEN[%d] %04x queued"
597                                     " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n",
598                                     ha->host_no, ha->aen_in, mbox_sts[0],
599                                     mbox_sts[1], mbox_sts[2],  mbox_sts[3],
600                                     mbox_sts[4]));
601
602                                 /* advance pointer */
603                                 ha->aen_in++;
604                                 if (ha->aen_in == MAX_AEN_ENTRIES)
605                                         ha->aen_in = 0;
606
607                                 /* The DPC routine will process the aen */
608                                 set_bit(DPC_AEN, &ha->dpc_flags);
609                         } else {
610                                 DEBUG2(printk("scsi%ld: %s: aen %04x, queue "
611                                               "overflowed!  AEN LOST!!\n",
612                                               ha->host_no, __func__,
613                                               mbox_sts[0]));
614
615                                 DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n",
616                                               ha->host_no));
617
618                                 for (i = 0; i < MAX_AEN_ENTRIES; i++) {
619                                         DEBUG2(printk("AEN[%d] %04x %04x %04x "
620                                                       "%04x\n", i, mbox_sts[0],
621                                                       mbox_sts[1], mbox_sts[2],
622                                                       mbox_sts[3]));
623                                 }
624                         }
625                         break;
626
627                 case MBOX_ASTS_TXSCVR_INSERTED:
628                         DEBUG2(printk(KERN_WARNING
629                             "scsi%ld: AEN %04x Transceiver"
630                             " inserted\n",  ha->host_no, mbox_sts[0]));
631                         break;
632
633                 case MBOX_ASTS_TXSCVR_REMOVED:
634                         DEBUG2(printk(KERN_WARNING
635                             "scsi%ld: AEN %04x Transceiver"
636                             " removed\n",  ha->host_no, mbox_sts[0]));
637                         break;
638
639                 default:
640                         DEBUG2(printk(KERN_WARNING
641                                       "scsi%ld: AEN %04x UNKNOWN\n",
642                                       ha->host_no, mbox_sts[0]));
643                         break;
644                 }
645         } else {
646                 DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n",
647                               ha->host_no, mbox_status));
648
649                 ha->mbox_status[0] = mbox_status;
650         }
651 }
652
653 /**
654  * qla4_8xxx_interrupt_service_routine - isr
655  * @ha: pointer to host adapter structure.
656  *
657  * This is the main interrupt service routine.
658  * hardware_lock locked upon entry. runs in interrupt context.
659  **/
660 void qla4_8xxx_interrupt_service_routine(struct scsi_qla_host *ha,
661     uint32_t intr_status)
662 {
663         /* Process response queue interrupt. */
664         if (intr_status & HSRX_RISC_IOCB_INT)
665                 qla4xxx_process_response_queue(ha);
666
667         /* Process mailbox/asynch event interrupt.*/
668         if (intr_status & HSRX_RISC_MB_INT)
669                 qla4xxx_isr_decode_mailbox(ha,
670                     readl(&ha->qla4_8xxx_reg->mailbox_out[0]));
671
672         /* clear the interrupt */
673         writel(0, &ha->qla4_8xxx_reg->host_int);
674         readl(&ha->qla4_8xxx_reg->host_int);
675 }
676
677 /**
678  * qla4xxx_interrupt_service_routine - isr
679  * @ha: pointer to host adapter structure.
680  *
681  * This is the main interrupt service routine.
682  * hardware_lock locked upon entry. runs in interrupt context.
683  **/
684 void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
685                                        uint32_t intr_status)
686 {
687         /* Process response queue interrupt. */
688         if (intr_status & CSR_SCSI_COMPLETION_INTR)
689                 qla4xxx_process_response_queue(ha);
690
691         /* Process mailbox/asynch event  interrupt.*/
692         if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
693                 qla4xxx_isr_decode_mailbox(ha,
694                                            readl(&ha->reg->mailbox[0]));
695
696                 /* Clear Mailbox Interrupt */
697                 writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
698                        &ha->reg->ctrl_status);
699                 readl(&ha->reg->ctrl_status);
700         }
701 }
702
703 /**
704  * qla4_8xxx_spurious_interrupt - processes spurious interrupt
705  * @ha: pointer to host adapter structure.
706  * @reqs_count: .
707  *
708  **/
709 static void qla4_8xxx_spurious_interrupt(struct scsi_qla_host *ha,
710     uint8_t reqs_count)
711 {
712         if (reqs_count)
713                 return;
714
715         DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n"));
716         if (is_qla8022(ha)) {
717                 writel(0, &ha->qla4_8xxx_reg->host_int);
718                 if (test_bit(AF_INTx_ENABLED, &ha->flags))
719                         qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg,
720                             0xfbff);
721         }
722         ha->spurious_int_count++;
723 }
724
725 /**
726  * qla4xxx_intr_handler - hardware interrupt handler.
727  * @irq: Unused
728  * @dev_id: Pointer to host adapter structure
729  **/
730 irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
731 {
732         struct scsi_qla_host *ha;
733         uint32_t intr_status;
734         unsigned long flags = 0;
735         uint8_t reqs_count = 0;
736
737         ha = (struct scsi_qla_host *) dev_id;
738         if (!ha) {
739                 DEBUG2(printk(KERN_INFO
740                               "qla4xxx: Interrupt with NULL host ptr\n"));
741                 return IRQ_NONE;
742         }
743
744         spin_lock_irqsave(&ha->hardware_lock, flags);
745
746         ha->isr_count++;
747         /*
748          * Repeatedly service interrupts up to a maximum of
749          * MAX_REQS_SERVICED_PER_INTR
750          */
751         while (1) {
752                 /*
753                  * Read interrupt status
754                  */
755                 if (ha->isp_ops->rd_shdw_rsp_q_in(ha) !=
756                     ha->response_out)
757                         intr_status = CSR_SCSI_COMPLETION_INTR;
758                 else
759                         intr_status = readl(&ha->reg->ctrl_status);
760
761                 if ((intr_status &
762                     (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) == 0) {
763                         if (reqs_count == 0)
764                                 ha->spurious_int_count++;
765                         break;
766                 }
767
768                 if (intr_status & CSR_FATAL_ERROR) {
769                         DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, "
770                                       "Status 0x%04x\n", ha->host_no,
771                                       readl(isp_port_error_status (ha))));
772
773                         /* Issue Soft Reset to clear this error condition.
774                          * This will prevent the RISC from repeatedly
775                          * interrupting the driver; thus, allowing the DPC to
776                          * get scheduled to continue error recovery.
777                          * NOTE: Disabling RISC interrupts does not work in
778                          * this case, as CSR_FATAL_ERROR overrides
779                          * CSR_SCSI_INTR_ENABLE */
780                         if ((readl(&ha->reg->ctrl_status) &
781                              CSR_SCSI_RESET_INTR) == 0) {
782                                 writel(set_rmask(CSR_SOFT_RESET),
783                                        &ha->reg->ctrl_status);
784                                 readl(&ha->reg->ctrl_status);
785                         }
786
787                         writel(set_rmask(CSR_FATAL_ERROR),
788                                &ha->reg->ctrl_status);
789                         readl(&ha->reg->ctrl_status);
790
791                         __qla4xxx_disable_intrs(ha);
792
793                         set_bit(DPC_RESET_HA, &ha->dpc_flags);
794
795                         break;
796                 } else if (intr_status & CSR_SCSI_RESET_INTR) {
797                         clear_bit(AF_ONLINE, &ha->flags);
798                         __qla4xxx_disable_intrs(ha);
799
800                         writel(set_rmask(CSR_SCSI_RESET_INTR),
801                                &ha->reg->ctrl_status);
802                         readl(&ha->reg->ctrl_status);
803
804                         if (!test_bit(AF_HBA_GOING_AWAY, &ha->flags))
805                                 set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
806
807                         break;
808                 } else if (intr_status & INTR_PENDING) {
809                         ha->isp_ops->interrupt_service_routine(ha, intr_status);
810                         ha->total_io_count++;
811                         if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
812                                 break;
813                 }
814         }
815
816         spin_unlock_irqrestore(&ha->hardware_lock, flags);
817
818         return IRQ_HANDLED;
819 }
820
821 /**
822  * qla4_8xxx_intr_handler - hardware interrupt handler.
823  * @irq: Unused
824  * @dev_id: Pointer to host adapter structure
825  **/
826 irqreturn_t qla4_8xxx_intr_handler(int irq, void *dev_id)
827 {
828         struct scsi_qla_host *ha = dev_id;
829         uint32_t intr_status;
830         uint32_t status;
831         unsigned long flags = 0;
832         uint8_t reqs_count = 0;
833
834         if (unlikely(pci_channel_offline(ha->pdev)))
835                 return IRQ_HANDLED;
836
837         ha->isr_count++;
838         status = qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
839         if (!(status & ha->nx_legacy_intr.int_vec_bit))
840                 return IRQ_NONE;
841
842         status = qla4_8xxx_rd_32(ha, ISR_INT_STATE_REG);
843         if (!ISR_IS_LEGACY_INTR_TRIGGERED(status)) {
844                 DEBUG2(ql4_printk(KERN_INFO, ha,
845                     "%s legacy Int not triggered\n", __func__));
846                 return IRQ_NONE;
847         }
848
849         /* clear the interrupt */
850         qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
851
852         /* read twice to ensure write is flushed */
853         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
854         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
855
856         spin_lock_irqsave(&ha->hardware_lock, flags);
857         while (1) {
858                 if (!(readl(&ha->qla4_8xxx_reg->host_int) &
859                     ISRX_82XX_RISC_INT)) {
860                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
861                         break;
862                 }
863                 intr_status =  readl(&ha->qla4_8xxx_reg->host_status);
864                 if ((intr_status &
865                     (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0)  {
866                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
867                         break;
868                 }
869
870                 ha->isp_ops->interrupt_service_routine(ha, intr_status);
871
872                 /* Enable Interrupt */
873                 qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff);
874
875                 if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
876                         break;
877         }
878
879         spin_unlock_irqrestore(&ha->hardware_lock, flags);
880         return IRQ_HANDLED;
881 }
882
883 irqreturn_t
884 qla4_8xxx_msi_handler(int irq, void *dev_id)
885 {
886         struct scsi_qla_host *ha;
887
888         ha = (struct scsi_qla_host *) dev_id;
889         if (!ha) {
890                 DEBUG2(printk(KERN_INFO
891                     "qla4xxx: MSIX: Interrupt with NULL host ptr\n"));
892                 return IRQ_NONE;
893         }
894
895         ha->isr_count++;
896         /* clear the interrupt */
897         qla4_8xxx_wr_32(ha, ha->nx_legacy_intr.tgt_status_reg, 0xffffffff);
898
899         /* read twice to ensure write is flushed */
900         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
901         qla4_8xxx_rd_32(ha, ISR_INT_VECTOR);
902
903         return qla4_8xxx_default_intr_handler(irq, dev_id);
904 }
905
906 /**
907  * qla4_8xxx_default_intr_handler - hardware interrupt handler.
908  * @irq: Unused
909  * @dev_id: Pointer to host adapter structure
910  *
911  * This interrupt handler is called directly for MSI-X, and
912  * called indirectly for MSI.
913  **/
914 irqreturn_t
915 qla4_8xxx_default_intr_handler(int irq, void *dev_id)
916 {
917         struct scsi_qla_host *ha = dev_id;
918         unsigned long   flags;
919         uint32_t intr_status;
920         uint8_t reqs_count = 0;
921
922         spin_lock_irqsave(&ha->hardware_lock, flags);
923         while (1) {
924                 if (!(readl(&ha->qla4_8xxx_reg->host_int) &
925                     ISRX_82XX_RISC_INT)) {
926                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
927                         break;
928                 }
929
930                 intr_status =  readl(&ha->qla4_8xxx_reg->host_status);
931                 if ((intr_status &
932                     (HSRX_RISC_MB_INT | HSRX_RISC_IOCB_INT)) == 0) {
933                         qla4_8xxx_spurious_interrupt(ha, reqs_count);
934                         break;
935                 }
936
937                 ha->isp_ops->interrupt_service_routine(ha, intr_status);
938
939                 if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
940                         break;
941         }
942
943         ha->isr_count++;
944         spin_unlock_irqrestore(&ha->hardware_lock, flags);
945         return IRQ_HANDLED;
946 }
947
948 irqreturn_t
949 qla4_8xxx_msix_rsp_q(int irq, void *dev_id)
950 {
951         struct scsi_qla_host *ha = dev_id;
952         unsigned long flags;
953
954         spin_lock_irqsave(&ha->hardware_lock, flags);
955         qla4xxx_process_response_queue(ha);
956         writel(0, &ha->qla4_8xxx_reg->host_int);
957         spin_unlock_irqrestore(&ha->hardware_lock, flags);
958
959         ha->isr_count++;
960         return IRQ_HANDLED;
961 }
962
963 /**
964  * qla4xxx_process_aen - processes AENs generated by firmware
965  * @ha: pointer to host adapter structure.
966  * @process_aen: type of AENs to process
967  *
968  * Processes specific types of Asynchronous Events generated by firmware.
969  * The type of AENs to process is specified by process_aen and can be
970  *      PROCESS_ALL_AENS         0
971  *      FLUSH_DDB_CHANGED_AENS   1
972  *      RELOGIN_DDB_CHANGED_AENS 2
973  **/
974 void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
975 {
976         uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
977         struct aen *aen;
978         int i;
979         unsigned long flags;
980
981         spin_lock_irqsave(&ha->hardware_lock, flags);
982         while (ha->aen_out != ha->aen_in) {
983                 aen = &ha->aen_q[ha->aen_out];
984                 /* copy aen information to local structure */
985                 for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
986                         mbox_sts[i] = aen->mbox_sts[i];
987
988                 ha->aen_q_count++;
989                 ha->aen_out++;
990
991                 if (ha->aen_out == MAX_AEN_ENTRIES)
992                         ha->aen_out = 0;
993
994                 spin_unlock_irqrestore(&ha->hardware_lock, flags);
995
996                 DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x"
997                         " mbx3=0x%08x mbx4=0x%08x\n", ha->host_no,
998                         (ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)),
999                         mbox_sts[0], mbox_sts[1], mbox_sts[2],
1000                         mbox_sts[3], mbox_sts[4]));
1001
1002                 switch (mbox_sts[0]) {
1003                 case MBOX_ASTS_DATABASE_CHANGED:
1004                         if (process_aen == FLUSH_DDB_CHANGED_AENS) {
1005                                 DEBUG2(printk("scsi%ld: AEN[%d] %04x, index "
1006                                               "[%d] state=%04x FLUSHED!\n",
1007                                               ha->host_no, ha->aen_out,
1008                                               mbox_sts[0], mbox_sts[2],
1009                                               mbox_sts[3]));
1010                                 break;
1011                         } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) {
1012                                 /* for use during init time, we only want to
1013                                  * relogin non-active ddbs */
1014                                 struct ddb_entry *ddb_entry;
1015
1016                                 ddb_entry =
1017                                         /* FIXME: name length? */
1018                                         qla4xxx_lookup_ddb_by_fw_index(ha,
1019                                                                        mbox_sts[2]);
1020                                 if (!ddb_entry)
1021                                         break;
1022
1023                                 ddb_entry->dev_scan_wait_to_complete_relogin =
1024                                         0;
1025                                 ddb_entry->dev_scan_wait_to_start_relogin =
1026                                         jiffies +
1027                                         ((ddb_entry->default_time2wait +
1028                                           4) * HZ);
1029
1030                                 DEBUG2(printk("scsi%ld: ddb [%d] initiate"
1031                                               " RELOGIN after %d seconds\n",
1032                                               ha->host_no,
1033                                               ddb_entry->fw_ddb_index,
1034                                               ddb_entry->default_time2wait +
1035                                               4));
1036                                 break;
1037                         }
1038
1039                         if (mbox_sts[1] == 0) { /* Global DB change. */
1040                                 qla4xxx_reinitialize_ddb_list(ha);
1041                         } else if (mbox_sts[1] == 1) {  /* Specific device. */
1042                                 qla4xxx_process_ddb_changed(ha, mbox_sts[2],
1043                                                 mbox_sts[3], mbox_sts[4]);
1044                         }
1045                         break;
1046                 }
1047                 spin_lock_irqsave(&ha->hardware_lock, flags);
1048         }
1049         spin_unlock_irqrestore(&ha->hardware_lock, flags);
1050 }
1051
1052 int qla4xxx_request_irqs(struct scsi_qla_host *ha)
1053 {
1054         int ret;
1055
1056         if (!is_qla8022(ha))
1057                 goto try_intx;
1058
1059         if (ql4xenablemsix == 2)
1060                 goto try_msi;
1061
1062         if (ql4xenablemsix == 0 || ql4xenablemsix != 1)
1063                 goto try_intx;
1064
1065         /* Trying MSI-X */
1066         ret = qla4_8xxx_enable_msix(ha);
1067         if (!ret) {
1068                 DEBUG2(ql4_printk(KERN_INFO, ha,
1069                     "MSI-X: Enabled (0x%X).\n", ha->revision_id));
1070                 goto irq_attached;
1071         }
1072
1073         ql4_printk(KERN_WARNING, ha,
1074             "MSI-X: Falling back-to MSI mode -- %d.\n", ret);
1075
1076 try_msi:
1077         /* Trying MSI */
1078         ret = pci_enable_msi(ha->pdev);
1079         if (!ret) {
1080                 ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler,
1081                         0, DRIVER_NAME, ha);
1082                 if (!ret) {
1083                         DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
1084                         set_bit(AF_MSI_ENABLED, &ha->flags);
1085                         goto irq_attached;
1086                 } else {
1087                         ql4_printk(KERN_WARNING, ha,
1088                             "MSI: Failed to reserve interrupt %d "
1089                             "already in use.\n", ha->pdev->irq);
1090                         pci_disable_msi(ha->pdev);
1091                 }
1092         }
1093         ql4_printk(KERN_WARNING, ha,
1094             "MSI: Falling back-to INTx mode -- %d.\n", ret);
1095
1096 try_intx:
1097         /* Trying INTx */
1098         ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
1099             IRQF_SHARED, DRIVER_NAME, ha);
1100         if (!ret) {
1101                 DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n"));
1102                 set_bit(AF_INTx_ENABLED, &ha->flags);
1103                 goto irq_attached;
1104
1105         } else {
1106                 ql4_printk(KERN_WARNING, ha,
1107                     "INTx: Failed to reserve interrupt %d already in"
1108                     " use.\n", ha->pdev->irq);
1109                 return ret;
1110         }
1111
1112 irq_attached:
1113         set_bit(AF_IRQ_ATTACHED, &ha->flags);
1114         ha->host->irq = ha->pdev->irq;
1115         ql4_printk(KERN_INFO, ha, "%s: irq %d attached\n",
1116             __func__, ha->pdev->irq);
1117         return ret;
1118 }
1119
1120 void qla4xxx_free_irqs(struct scsi_qla_host *ha)
1121 {
1122         if (test_bit(AF_MSIX_ENABLED, &ha->flags))
1123                 qla4_8xxx_disable_msix(ha);
1124         else if (test_and_clear_bit(AF_MSI_ENABLED, &ha->flags)) {
1125                 free_irq(ha->pdev->irq, ha);
1126                 pci_disable_msi(ha->pdev);
1127         } else if (test_and_clear_bit(AF_INTx_ENABLED, &ha->flags))
1128                 free_irq(ha->pdev->irq, ha);
1129 }