xref: /openbmc/linux/drivers/scsi/qla4xxx/ql4_isr.c (revision 5d4a2e29)
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 	uint8_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 		/* FIXMEdg: Don't we need to reset ISP in this case??? */
122 		DEBUG2(printk(KERN_WARNING "scsi%ld: %s: Status Entry invalid "
123 			      "handle 0x%x, sp=%p. This cmd may have already "
124 			      "been completed.\n", ha->host_no, __func__,
125 			      le32_to_cpu(sts_entry->handle), srb));
126 		dev_warn(&ha->pdev->dev, "%s invalid status entry:"
127 			" handle=0x%0x\n", __func__, sts_entry->handle);
128 		set_bit(DPC_RESET_HA, &ha->dpc_flags);
129 		return;
130 	}
131 
132 	cmd = srb->cmd;
133 	if (cmd == NULL) {
134 		DEBUG2(printk("scsi%ld: %s: Command already returned back to "
135 			      "OS pkt->handle=%d srb=%p srb->state:%d\n",
136 			      ha->host_no, __func__, sts_entry->handle,
137 			      srb, srb->state));
138 		dev_warn(&ha->pdev->dev, "Command is NULL:"
139 			" already returned to OS (srb=%p)\n", srb);
140 		return;
141 	}
142 
143 	ddb_entry = srb->ddb;
144 	if (ddb_entry == NULL) {
145 		cmd->result = DID_NO_CONNECT << 16;
146 		goto status_entry_exit;
147 	}
148 
149 	residual = le32_to_cpu(sts_entry->residualByteCnt);
150 
151 	/* Translate ISP error to a Linux SCSI error. */
152 	scsi_status = sts_entry->scsiStatus;
153 	switch (sts_entry->completionStatus) {
154 	case SCS_COMPLETE:
155 
156 		if (sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) {
157 			cmd->result = DID_ERROR << 16;
158 			break;
159 		}
160 
161 		if (sts_entry->iscsiFlags &ISCSI_FLAG_RESIDUAL_UNDER) {
162 			scsi_set_resid(cmd, residual);
163 			if (!scsi_status && ((scsi_bufflen(cmd) - residual) <
164 				cmd->underflow)) {
165 
166 				cmd->result = DID_ERROR << 16;
167 
168 				DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
169 					"Mid-layer Data underrun0, "
170 					"xferlen = 0x%x, "
171 					"residual = 0x%x\n", ha->host_no,
172 					cmd->device->channel,
173 					cmd->device->id,
174 					cmd->device->lun, __func__,
175 					scsi_bufflen(cmd), residual));
176 				break;
177 			}
178 		}
179 
180 		cmd->result = DID_OK << 16 | scsi_status;
181 
182 		if (scsi_status != SCSI_CHECK_CONDITION)
183 			break;
184 
185 		/* Copy Sense Data into sense buffer. */
186 		qla4xxx_copy_sense(ha, sts_entry, srb);
187 		break;
188 
189 	case SCS_INCOMPLETE:
190 		/* Always set the status to DID_ERROR, since
191 		 * all conditions result in that status anyway */
192 		cmd->result = DID_ERROR << 16;
193 		break;
194 
195 	case SCS_RESET_OCCURRED:
196 		DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Device RESET occurred\n",
197 			      ha->host_no, cmd->device->channel,
198 			      cmd->device->id, cmd->device->lun, __func__));
199 
200 		cmd->result = DID_RESET << 16;
201 		break;
202 
203 	case SCS_ABORTED:
204 		DEBUG2(printk("scsi%ld:%d:%d:%d: %s: Abort occurred\n",
205 			      ha->host_no, cmd->device->channel,
206 			      cmd->device->id, cmd->device->lun, __func__));
207 
208 		cmd->result = DID_RESET << 16;
209 		break;
210 
211 	case SCS_TIMEOUT:
212 		DEBUG2(printk(KERN_INFO "scsi%ld:%d:%d:%d: Timeout\n",
213 			      ha->host_no, cmd->device->channel,
214 			      cmd->device->id, cmd->device->lun));
215 
216 		cmd->result = DID_TRANSPORT_DISRUPTED << 16;
217 
218 		/*
219 		 * Mark device missing so that we won't continue to send
220 		 * I/O to this device.	We should get a ddb state change
221 		 * AEN soon.
222 		 */
223 		if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
224 			qla4xxx_mark_device_missing(ha, ddb_entry);
225 		break;
226 
227 	case SCS_DATA_UNDERRUN:
228 	case SCS_DATA_OVERRUN:
229 		if ((sts_entry->iscsiFlags & ISCSI_FLAG_RESIDUAL_OVER) ||
230 		     (sts_entry->completionStatus == SCS_DATA_OVERRUN)) {
231 			DEBUG2(printk("scsi%ld:%d:%d:%d: %s: " "Data overrun\n",
232 				      ha->host_no,
233 				      cmd->device->channel, cmd->device->id,
234 				      cmd->device->lun, __func__));
235 
236 			cmd->result = DID_ERROR << 16;
237 			break;
238 		}
239 
240 		scsi_set_resid(cmd, residual);
241 
242 		/*
243 		 * If there is scsi_status, it takes precedense over
244 		 * underflow condition.
245 		 */
246 		if (scsi_status != 0) {
247 			cmd->result = DID_OK << 16 | scsi_status;
248 
249 			if (scsi_status != SCSI_CHECK_CONDITION)
250 				break;
251 
252 			/* Copy Sense Data into sense buffer. */
253 			qla4xxx_copy_sense(ha, sts_entry, srb);
254 		} else {
255 			/*
256 			 * If RISC reports underrun and target does not
257 			 * report it then we must have a lost frame, so
258 			 * tell upper layer to retry it by reporting a
259 			 * bus busy.
260 			 */
261 			if ((sts_entry->iscsiFlags &
262 			     ISCSI_FLAG_RESIDUAL_UNDER) == 0) {
263 				cmd->result = DID_BUS_BUSY << 16;
264 			} else if ((scsi_bufflen(cmd) - residual) <
265 				   cmd->underflow) {
266 				/*
267 				 * Handle mid-layer underflow???
268 				 *
269 				 * For kernels less than 2.4, the driver must
270 				 * return an error if an underflow is detected.
271 				 * For kernels equal-to and above 2.4, the
272 				 * mid-layer will appearantly handle the
273 				 * underflow by detecting the residual count --
274 				 * unfortunately, we do not see where this is
275 				 * actually being done.	 In the interim, we
276 				 * will return DID_ERROR.
277 				 */
278 				DEBUG2(printk("scsi%ld:%d:%d:%d: %s: "
279 					"Mid-layer Data underrun1, "
280 					"xferlen = 0x%x, "
281 					"residual = 0x%x\n", ha->host_no,
282 					cmd->device->channel,
283 					cmd->device->id,
284 					cmd->device->lun, __func__,
285 					scsi_bufflen(cmd), residual));
286 
287 				cmd->result = DID_ERROR << 16;
288 			} else {
289 				cmd->result = DID_OK << 16;
290 			}
291 		}
292 		break;
293 
294 	case SCS_DEVICE_LOGGED_OUT:
295 	case SCS_DEVICE_UNAVAILABLE:
296 		/*
297 		 * Mark device missing so that we won't continue to
298 		 * send I/O to this device.  We should get a ddb
299 		 * state change AEN soon.
300 		 */
301 		if (atomic_read(&ddb_entry->state) == DDB_STATE_ONLINE)
302 			qla4xxx_mark_device_missing(ha, ddb_entry);
303 
304 		cmd->result = DID_TRANSPORT_DISRUPTED << 16;
305 		break;
306 
307 	case SCS_QUEUE_FULL:
308 		/*
309 		 * SCSI Mid-Layer handles device queue full
310 		 */
311 		cmd->result = DID_OK << 16 | sts_entry->scsiStatus;
312 		DEBUG2(printk("scsi%ld:%d:%d: %s: QUEUE FULL detected "
313 			      "compl=%02x, scsi=%02x, state=%02x, iFlags=%02x,"
314 			      " iResp=%02x\n", ha->host_no, cmd->device->id,
315 			      cmd->device->lun, __func__,
316 			      sts_entry->completionStatus,
317 			      sts_entry->scsiStatus, sts_entry->state_flags,
318 			      sts_entry->iscsiFlags,
319 			      sts_entry->iscsiResponse));
320 		break;
321 
322 	default:
323 		cmd->result = DID_ERROR << 16;
324 		break;
325 	}
326 
327 status_entry_exit:
328 
329 	/* complete the request, if not waiting for status_continuation pkt */
330 	srb->cc_stat = sts_entry->completionStatus;
331 	if (ha->status_srb == NULL)
332 		kref_put(&srb->srb_ref, qla4xxx_srb_compl);
333 }
334 
335 /**
336  * qla4xxx_process_response_queue - process response queue completions
337  * @ha: Pointer to host adapter structure.
338  *
339  * This routine process response queue completions in interrupt context.
340  * Hardware_lock locked upon entry
341  **/
342 static void qla4xxx_process_response_queue(struct scsi_qla_host * ha)
343 {
344 	uint32_t count = 0;
345 	struct srb *srb = NULL;
346 	struct status_entry *sts_entry;
347 
348 	/* Process all responses from response queue */
349 	while ((ha->response_in =
350 		(uint16_t)le32_to_cpu(ha->shadow_regs->rsp_q_in)) !=
351 	       ha->response_out) {
352 		sts_entry = (struct status_entry *) ha->response_ptr;
353 		count++;
354 
355 		/* Advance pointers for next entry */
356 		if (ha->response_out == (RESPONSE_QUEUE_DEPTH - 1)) {
357 			ha->response_out = 0;
358 			ha->response_ptr = ha->response_ring;
359 		} else {
360 			ha->response_out++;
361 			ha->response_ptr++;
362 		}
363 
364 		/* process entry */
365 		switch (sts_entry->hdr.entryType) {
366 		case ET_STATUS:
367 			/* Common status */
368 			qla4xxx_status_entry(ha, sts_entry);
369 			break;
370 
371 		case ET_PASSTHRU_STATUS:
372 			break;
373 
374 		case ET_STATUS_CONTINUATION:
375 			qla4xxx_status_cont_entry(ha,
376 				(struct status_cont_entry *) sts_entry);
377 			break;
378 
379 		case ET_COMMAND:
380 			/* ISP device queue is full. Command not
381 			 * accepted by ISP.  Queue command for
382 			 * later */
383 
384 			srb = qla4xxx_del_from_active_array(ha,
385 						    le32_to_cpu(sts_entry->
386 								handle));
387 			if (srb == NULL)
388 				goto exit_prq_invalid_handle;
389 
390 			DEBUG2(printk("scsi%ld: %s: FW device queue full, "
391 				      "srb %p\n", ha->host_no, __func__, srb));
392 
393 			/* ETRY normally by sending it back with
394 			 * DID_BUS_BUSY */
395 			srb->cmd->result = DID_BUS_BUSY << 16;
396 			kref_put(&srb->srb_ref, qla4xxx_srb_compl);
397 			break;
398 
399 		case ET_CONTINUE:
400 			/* Just throw away the continuation entries */
401 			DEBUG2(printk("scsi%ld: %s: Continuation entry - "
402 				      "ignoring\n", ha->host_no, __func__));
403 			break;
404 
405 		default:
406 			/*
407 			 * Invalid entry in response queue, reset RISC
408 			 * firmware.
409 			 */
410 			DEBUG2(printk("scsi%ld: %s: Invalid entry %x in "
411 				      "response queue \n", ha->host_no,
412 				      __func__,
413 				      sts_entry->hdr.entryType));
414 			goto exit_prq_error;
415 		}
416 	}
417 
418 	/*
419 	 * Done with responses, update the ISP For QLA4010, this also clears
420 	 * the interrupt.
421 	 */
422 	writel(ha->response_out, &ha->reg->rsp_q_out);
423 	readl(&ha->reg->rsp_q_out);
424 
425 	return;
426 
427 exit_prq_invalid_handle:
428 	DEBUG2(printk("scsi%ld: %s: Invalid handle(srb)=%p type=%x IOCS=%x\n",
429 		      ha->host_no, __func__, srb, sts_entry->hdr.entryType,
430 		      sts_entry->completionStatus));
431 
432 exit_prq_error:
433 	writel(ha->response_out, &ha->reg->rsp_q_out);
434 	readl(&ha->reg->rsp_q_out);
435 
436 	set_bit(DPC_RESET_HA, &ha->dpc_flags);
437 }
438 
439 /**
440  * qla4xxx_isr_decode_mailbox - decodes mailbox status
441  * @ha: Pointer to host adapter structure.
442  * @mailbox_status: Mailbox status.
443  *
444  * This routine decodes the mailbox status during the ISR.
445  * Hardware_lock locked upon entry. runs in interrupt context.
446  **/
447 static void qla4xxx_isr_decode_mailbox(struct scsi_qla_host * ha,
448 				       uint32_t mbox_status)
449 {
450 	int i;
451 	uint32_t mbox_stat2, mbox_stat3;
452 
453 	if ((mbox_status == MBOX_STS_BUSY) ||
454 	    (mbox_status == MBOX_STS_INTERMEDIATE_COMPLETION) ||
455 	    (mbox_status >> 12 == MBOX_COMPLETION_STATUS)) {
456 		ha->mbox_status[0] = mbox_status;
457 
458 		if (test_bit(AF_MBOX_COMMAND, &ha->flags)) {
459 			/*
460 			 * Copy all mailbox registers to a temporary
461 			 * location and set mailbox command done flag
462 			 */
463 			for (i = 1; i < ha->mbox_status_count; i++)
464 				ha->mbox_status[i] =
465 					readl(&ha->reg->mailbox[i]);
466 
467 			set_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
468 		}
469 	} else if (mbox_status >> 12 == MBOX_ASYNC_EVENT_STATUS) {
470 		/* Immediately process the AENs that don't require much work.
471 		 * Only queue the database_changed AENs */
472 		if (ha->aen_log.count < MAX_AEN_ENTRIES) {
473 			for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
474 				ha->aen_log.entry[ha->aen_log.count].mbox_sts[i] =
475 					readl(&ha->reg->mailbox[i]);
476 			ha->aen_log.count++;
477 		}
478 		switch (mbox_status) {
479 		case MBOX_ASTS_SYSTEM_ERROR:
480 			/* Log Mailbox registers */
481 			if (ql4xdontresethba) {
482 				DEBUG2(printk("%s:Dont Reset HBA\n",
483 					      __func__));
484 			} else {
485 				set_bit(AF_GET_CRASH_RECORD, &ha->flags);
486 				set_bit(DPC_RESET_HA, &ha->dpc_flags);
487 			}
488 			break;
489 
490 		case MBOX_ASTS_REQUEST_TRANSFER_ERROR:
491 		case MBOX_ASTS_RESPONSE_TRANSFER_ERROR:
492 		case MBOX_ASTS_NVRAM_INVALID:
493 		case MBOX_ASTS_IP_ADDRESS_CHANGED:
494 		case MBOX_ASTS_DHCP_LEASE_EXPIRED:
495 			DEBUG2(printk("scsi%ld: AEN %04x, ERROR Status, "
496 				      "Reset HA\n", ha->host_no, mbox_status));
497 			set_bit(DPC_RESET_HA, &ha->dpc_flags);
498 			break;
499 
500 		case MBOX_ASTS_LINK_UP:
501 			set_bit(AF_LINK_UP, &ha->flags);
502 			if (test_bit(AF_INIT_DONE, &ha->flags))
503 				set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
504 
505 			DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x Adapter"
506 					" LINK UP\n", ha->host_no,
507 					mbox_status));
508 			break;
509 
510 		case MBOX_ASTS_LINK_DOWN:
511 			clear_bit(AF_LINK_UP, &ha->flags);
512 			set_bit(DPC_LINK_CHANGED, &ha->dpc_flags);
513 
514 			DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x Adapter"
515 					" LINK DOWN\n", ha->host_no,
516 					mbox_status));
517 			break;
518 
519 		case MBOX_ASTS_HEARTBEAT:
520 			ha->seconds_since_last_heartbeat = 0;
521 			break;
522 
523 		case MBOX_ASTS_DHCP_LEASE_ACQUIRED:
524 			DEBUG2(printk("scsi%ld: AEN %04x DHCP LEASE "
525 				      "ACQUIRED\n", ha->host_no, mbox_status));
526 			set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
527 			break;
528 
529 		case MBOX_ASTS_PROTOCOL_STATISTIC_ALARM:
530 		case MBOX_ASTS_SCSI_COMMAND_PDU_REJECTED: /* Target
531 							   * mode
532 							   * only */
533 		case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED:  /* Connection mode */
534 		case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR:
535 		case MBOX_ASTS_SUBNET_STATE_CHANGE:
536 			/* No action */
537 			DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no,
538 				      mbox_status));
539 			break;
540 
541 		case MBOX_ASTS_IP_ADDR_STATE_CHANGED:
542 			mbox_stat2 = readl(&ha->reg->mailbox[2]);
543 			mbox_stat3 = readl(&ha->reg->mailbox[3]);
544 
545 			if ((mbox_stat3 == 5) && (mbox_stat2 == 3))
546 				set_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags);
547 			else if ((mbox_stat3 == 2) && (mbox_stat2 == 5))
548 				set_bit(DPC_RESET_HA, &ha->dpc_flags);
549 			break;
550 
551 		case MBOX_ASTS_MAC_ADDRESS_CHANGED:
552 		case MBOX_ASTS_DNS:
553 			/* No action */
554 			DEBUG2(printk(KERN_INFO "scsi%ld: AEN %04x, "
555 				      "mbox_sts[1]=%04x, mbox_sts[2]=%04x\n",
556 				      ha->host_no, mbox_status,
557 				      readl(&ha->reg->mailbox[1]),
558 				      readl(&ha->reg->mailbox[2])));
559 			break;
560 
561 		case MBOX_ASTS_SELF_TEST_FAILED:
562 		case MBOX_ASTS_LOGIN_FAILED:
563 			/* No action */
564 			DEBUG2(printk("scsi%ld: AEN %04x, mbox_sts[1]=%04x, "
565 				      "mbox_sts[2]=%04x, mbox_sts[3]=%04x\n",
566 				      ha->host_no, mbox_status,
567 				      readl(&ha->reg->mailbox[1]),
568 				      readl(&ha->reg->mailbox[2]),
569 				      readl(&ha->reg->mailbox[3])));
570 			break;
571 
572 		case MBOX_ASTS_DATABASE_CHANGED:
573 			/* Queue AEN information and process it in the DPC
574 			 * routine */
575 			if (ha->aen_q_count > 0) {
576 
577 				/* decrement available counter */
578 				ha->aen_q_count--;
579 
580 				for (i = 1; i < MBOX_AEN_REG_COUNT; i++)
581 					ha->aen_q[ha->aen_in].mbox_sts[i] =
582 						readl(&ha->reg->mailbox[i]);
583 
584 				ha->aen_q[ha->aen_in].mbox_sts[0] = mbox_status;
585 
586 				/* print debug message */
587 				DEBUG2(printk("scsi%ld: AEN[%d] %04x queued"
588 					      " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n",
589 					      ha->host_no, ha->aen_in,
590 					      mbox_status,
591 					      ha->aen_q[ha->aen_in].mbox_sts[1],
592 					      ha->aen_q[ha->aen_in].mbox_sts[2],
593 					      ha->aen_q[ha->aen_in].mbox_sts[3],
594 					      ha->aen_q[ha->aen_in].  mbox_sts[4]));
595 				/* advance pointer */
596 				ha->aen_in++;
597 				if (ha->aen_in == MAX_AEN_ENTRIES)
598 					ha->aen_in = 0;
599 
600 				/* The DPC routine will process the aen */
601 				set_bit(DPC_AEN, &ha->dpc_flags);
602 			} else {
603 				DEBUG2(printk("scsi%ld: %s: aen %04x, queue "
604 					      "overflowed!  AEN LOST!!\n",
605 					      ha->host_no, __func__,
606 					      mbox_status));
607 
608 				DEBUG2(printk("scsi%ld: DUMP AEN QUEUE\n",
609 					      ha->host_no));
610 
611 				for (i = 0; i < MAX_AEN_ENTRIES; i++) {
612 					DEBUG2(printk("AEN[%d] %04x %04x %04x "
613 						      "%04x\n", i,
614 						      ha->aen_q[i].mbox_sts[0],
615 						      ha->aen_q[i].mbox_sts[1],
616 						      ha->aen_q[i].mbox_sts[2],
617 						      ha->aen_q[i].mbox_sts[3]));
618 				}
619 			}
620 			break;
621 
622 		default:
623 			DEBUG2(printk(KERN_WARNING
624 				      "scsi%ld: AEN %04x UNKNOWN\n",
625 				      ha->host_no, mbox_status));
626 			break;
627 		}
628 	} else {
629 		DEBUG2(printk("scsi%ld: Unknown mailbox status %08X\n",
630 			      ha->host_no, mbox_status));
631 
632 		ha->mbox_status[0] = mbox_status;
633 	}
634 }
635 
636 /**
637  * qla4xxx_interrupt_service_routine - isr
638  * @ha: pointer to host adapter structure.
639  *
640  * This is the main interrupt service routine.
641  * hardware_lock locked upon entry. runs in interrupt context.
642  **/
643 void qla4xxx_interrupt_service_routine(struct scsi_qla_host * ha,
644 				       uint32_t intr_status)
645 {
646 	/* Process response queue interrupt. */
647 	if (intr_status & CSR_SCSI_COMPLETION_INTR)
648 		qla4xxx_process_response_queue(ha);
649 
650 	/* Process mailbox/asynch event	 interrupt.*/
651 	if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
652 		qla4xxx_isr_decode_mailbox(ha,
653 					   readl(&ha->reg->mailbox[0]));
654 
655 		/* Clear Mailbox Interrupt */
656 		writel(set_rmask(CSR_SCSI_PROCESSOR_INTR),
657 		       &ha->reg->ctrl_status);
658 		readl(&ha->reg->ctrl_status);
659 	}
660 }
661 
662 /**
663  * qla4xxx_intr_handler - hardware interrupt handler.
664  * @irq: Unused
665  * @dev_id: Pointer to host adapter structure
666  **/
667 irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id)
668 {
669 	struct scsi_qla_host *ha;
670 	uint32_t intr_status;
671 	unsigned long flags = 0;
672 	uint8_t reqs_count = 0;
673 
674 	ha = (struct scsi_qla_host *) dev_id;
675 	if (!ha) {
676 		DEBUG2(printk(KERN_INFO
677 			      "qla4xxx: Interrupt with NULL host ptr\n"));
678 		return IRQ_NONE;
679 	}
680 
681 	spin_lock_irqsave(&ha->hardware_lock, flags);
682 
683 	ha->isr_count++;
684 	/*
685 	 * Repeatedly service interrupts up to a maximum of
686 	 * MAX_REQS_SERVICED_PER_INTR
687 	 */
688 	while (1) {
689 		/*
690 		 * Read interrupt status
691 		 */
692 		if (le32_to_cpu(ha->shadow_regs->rsp_q_in) !=
693 		    ha->response_out)
694 			intr_status = CSR_SCSI_COMPLETION_INTR;
695 		else
696 			intr_status = readl(&ha->reg->ctrl_status);
697 
698 		if ((intr_status &
699 		     (CSR_SCSI_RESET_INTR|CSR_FATAL_ERROR|INTR_PENDING)) ==
700 		    0) {
701 			if (reqs_count == 0)
702 				ha->spurious_int_count++;
703 			break;
704 		}
705 
706 		if (intr_status & CSR_FATAL_ERROR) {
707 			DEBUG2(printk(KERN_INFO "scsi%ld: Fatal Error, "
708 				      "Status 0x%04x\n", ha->host_no,
709 				      readl(isp_port_error_status (ha))));
710 
711 			/* Issue Soft Reset to clear this error condition.
712 			 * This will prevent the RISC from repeatedly
713 			 * interrupting the driver; thus, allowing the DPC to
714 			 * get scheduled to continue error recovery.
715 			 * NOTE: Disabling RISC interrupts does not work in
716 			 * this case, as CSR_FATAL_ERROR overrides
717 			 * CSR_SCSI_INTR_ENABLE */
718 			if ((readl(&ha->reg->ctrl_status) &
719 			     CSR_SCSI_RESET_INTR) == 0) {
720 				writel(set_rmask(CSR_SOFT_RESET),
721 				       &ha->reg->ctrl_status);
722 				readl(&ha->reg->ctrl_status);
723 			}
724 
725 			writel(set_rmask(CSR_FATAL_ERROR),
726 			       &ha->reg->ctrl_status);
727 			readl(&ha->reg->ctrl_status);
728 
729 			__qla4xxx_disable_intrs(ha);
730 
731 			set_bit(DPC_RESET_HA, &ha->dpc_flags);
732 
733 			break;
734 		} else if (intr_status & CSR_SCSI_RESET_INTR) {
735 			clear_bit(AF_ONLINE, &ha->flags);
736 			__qla4xxx_disable_intrs(ha);
737 
738 			writel(set_rmask(CSR_SCSI_RESET_INTR),
739 			       &ha->reg->ctrl_status);
740 			readl(&ha->reg->ctrl_status);
741 
742 			if (!ql4_mod_unload)
743 				set_bit(DPC_RESET_HA_INTR, &ha->dpc_flags);
744 
745 			break;
746 		} else if (intr_status & INTR_PENDING) {
747 			qla4xxx_interrupt_service_routine(ha, intr_status);
748 			ha->total_io_count++;
749 			if (++reqs_count == MAX_REQS_SERVICED_PER_INTR)
750 				break;
751 
752 			intr_status = 0;
753 		}
754 	}
755 
756 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
757 
758 	return IRQ_HANDLED;
759 }
760 
761 /**
762  * qla4xxx_process_aen - processes AENs generated by firmware
763  * @ha: pointer to host adapter structure.
764  * @process_aen: type of AENs to process
765  *
766  * Processes specific types of Asynchronous Events generated by firmware.
767  * The type of AENs to process is specified by process_aen and can be
768  *	PROCESS_ALL_AENS	 0
769  *	FLUSH_DDB_CHANGED_AENS	 1
770  *	RELOGIN_DDB_CHANGED_AENS 2
771  **/
772 void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
773 {
774 	uint32_t mbox_sts[MBOX_AEN_REG_COUNT];
775 	struct aen *aen;
776 	int i;
777 	unsigned long flags;
778 
779 	spin_lock_irqsave(&ha->hardware_lock, flags);
780 	while (ha->aen_out != ha->aen_in) {
781 		aen = &ha->aen_q[ha->aen_out];
782 		/* copy aen information to local structure */
783 		for (i = 0; i < MBOX_AEN_REG_COUNT; i++)
784 			mbox_sts[i] = aen->mbox_sts[i];
785 
786 		ha->aen_q_count++;
787 		ha->aen_out++;
788 
789 		if (ha->aen_out == MAX_AEN_ENTRIES)
790 			ha->aen_out = 0;
791 
792 		spin_unlock_irqrestore(&ha->hardware_lock, flags);
793 
794 		DEBUG2(printk("qla4xxx(%ld): AEN[%d]=0x%08x, mbx1=0x%08x mbx2=0x%08x"
795 			" mbx3=0x%08x mbx4=0x%08x\n", ha->host_no,
796 			(ha->aen_out ? (ha->aen_out-1): (MAX_AEN_ENTRIES-1)),
797 			mbox_sts[0], mbox_sts[1], mbox_sts[2],
798 			mbox_sts[3], mbox_sts[4]));
799 
800 		switch (mbox_sts[0]) {
801 		case MBOX_ASTS_DATABASE_CHANGED:
802 			if (process_aen == FLUSH_DDB_CHANGED_AENS) {
803 				DEBUG2(printk("scsi%ld: AEN[%d] %04x, index "
804 					      "[%d] state=%04x FLUSHED!\n",
805 					      ha->host_no, ha->aen_out,
806 					      mbox_sts[0], mbox_sts[2],
807 					      mbox_sts[3]));
808 				break;
809 			} else if (process_aen == RELOGIN_DDB_CHANGED_AENS) {
810 				/* for use during init time, we only want to
811 				 * relogin non-active ddbs */
812 				struct ddb_entry *ddb_entry;
813 
814 				ddb_entry =
815 					/* FIXME: name length? */
816 					qla4xxx_lookup_ddb_by_fw_index(ha,
817 								       mbox_sts[2]);
818 				if (!ddb_entry)
819 					break;
820 
821 				ddb_entry->dev_scan_wait_to_complete_relogin =
822 					0;
823 				ddb_entry->dev_scan_wait_to_start_relogin =
824 					jiffies +
825 					((ddb_entry->default_time2wait +
826 					  4) * HZ);
827 
828 				DEBUG2(printk("scsi%ld: ddb index [%d] initate"
829 					      " RELOGIN after %d seconds\n",
830 					      ha->host_no,
831 					      ddb_entry->fw_ddb_index,
832 					      ddb_entry->default_time2wait +
833 					      4));
834 				break;
835 			}
836 
837 			if (mbox_sts[1] == 0) {	/* Global DB change. */
838 				qla4xxx_reinitialize_ddb_list(ha);
839 			} else if (mbox_sts[1] == 1) {	/* Specific device. */
840 				qla4xxx_process_ddb_changed(ha, mbox_sts[2],
841 						mbox_sts[3], mbox_sts[4]);
842 			}
843 			break;
844 		}
845 		spin_lock_irqsave(&ha->hardware_lock, flags);
846 	}
847 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
848 }
849 
850