Blame view

drivers/scsi/qla2xxx/qla_isr.c 70.2 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
fa90c54f6   Andrew Vasquez   [SCSI] qla2xxx: U...
2
   * QLogic Fibre Channel HBA Driver
07e264b76   Andrew Vasquez   [SCSI] qla2xxx: U...
3
   * Copyright (c)  2003-2011 QLogic Corporation
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
   *
fa90c54f6   Andrew Vasquez   [SCSI] qla2xxx: U...
5
   * See LICENSE.qla2xxx for copyright and licensing details.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
   */
  #include "qla_def.h"
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
8
  #include <linux/delay.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
9
  #include <linux/slab.h>
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
10
  #include <scsi/scsi_tcq.h>
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
11
  #include <scsi/scsi_bsg_fc.h>
bad750028   Arun Easi   [SCSI] qla2xxx: T...
12
  #include <scsi/scsi_eh.h>
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
13

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
  static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
15
16
17
  static void qla2x00_process_completed_request(struct scsi_qla_host *,
  	struct req_que *, uint32_t);
  static void qla2x00_status_entry(scsi_qla_host_t *, struct rsp_que *, void *);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
18
  static void qla2x00_status_cont_entry(struct rsp_que *, sts_cont_entry_t *);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
19
20
  static void qla2x00_error_entry(scsi_qla_host_t *, struct rsp_que *,
  	sts_entry_t *);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
21

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
25
  /**
   * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
   * @irq:
   * @dev_id: SCSI driver HA context
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
31
   *
   * Called by system whenever the host adapter generates an interrupt.
   *
   * Returns handled flag.
   */
  irqreturn_t
7d12e780e   David Howells   IRQ: Maintain reg...
32
  qla2100_intr_handler(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
34
35
  	scsi_qla_host_t	*vha;
  	struct qla_hw_data *ha;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
36
  	struct device_reg_2xxx __iomem *reg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
  	int		status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
  	unsigned long	iter;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
39
  	uint16_t	hccr;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
40
  	uint16_t	mb[4];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
41
  	struct rsp_que *rsp;
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
42
  	unsigned long	flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
44
45
  	rsp = (struct rsp_que *) dev_id;
  	if (!rsp) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  		printk(KERN_INFO
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
47
48
  		    "%s(): NULL response queue pointer.
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
  		return (IRQ_NONE);
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
51
  	ha = rsp->hw;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
52
  	reg = &ha->iobase->isp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53
  	status = 0;
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
54
  	spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
55
  	vha = pci_get_drvdata(ha->pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  	for (iter = 50; iter--; ) {
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
57
58
59
60
61
62
63
  		hccr = RD_REG_WORD(&reg->hccr);
  		if (hccr & HCCR_RISC_PAUSE) {
  			if (pci_channel_offline(ha->pdev))
  				break;
  
  			/*
  			 * Issue a "HARD" reset in order for the RISC interrupt
a06a0f8e3   Justin P. Mattock   scsi: qla_isr.c: ...
64
  			 * bit to be cleared.  Schedule a big hammer to get
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
65
66
67
68
  			 * out of the RISC PAUSED state.
  			 */
  			WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
  			RD_REG_WORD(&reg->hccr);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
69
70
  			ha->isp_ops->fw_dump(vha, 1);
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
71
72
  			break;
  		} else if ((RD_REG_WORD(&reg->istatus) & ISR_RISC_INT) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
74
75
76
77
78
79
  			break;
  
  		if (RD_REG_WORD(&reg->semaphore) & BIT_0) {
  			WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
  			RD_REG_WORD(&reg->hccr);
  
  			/* Get mailbox data. */
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
80
81
  			mb[0] = RD_MAILBOX_REG(ha, reg, 0);
  			if (mb[0] > 0x3fff && mb[0] < 0x8000) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
82
  				qla2x00_mbx_completion(vha, mb[0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
  				status |= MBX_INTERRUPT;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
84
85
86
87
  			} else if (mb[0] > 0x7fff && mb[0] < 0xc000) {
  				mb[1] = RD_MAILBOX_REG(ha, reg, 1);
  				mb[2] = RD_MAILBOX_REG(ha, reg, 2);
  				mb[3] = RD_MAILBOX_REG(ha, reg, 3);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
88
  				qla2x00_async_event(vha, rsp, mb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89
90
  			} else {
  				/*EMPTY*/
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
91
92
93
94
  				ql_dbg(ql_dbg_async, vha, 0x5025,
  				    "Unrecognized interrupt type (%d).
  ",
  				    mb[0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
95
96
97
98
99
  			}
  			/* Release mailbox registers. */
  			WRT_REG_WORD(&reg->semaphore, 0);
  			RD_REG_WORD(&reg->semaphore);
  		} else {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
100
  			qla2x00_process_response_queue(rsp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
  
  			WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
  			RD_REG_WORD(&reg->hccr);
  		}
  	}
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
106
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
107

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
  	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
  	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
110
  		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0d   Marcus Barrow   [SCSI] qla2xxx: U...
111
  		complete(&ha->mbx_intr_comp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113
114
115
116
117
118
119
  	return (IRQ_HANDLED);
  }
  
  /**
   * qla2300_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
   * @irq:
   * @dev_id: SCSI driver HA context
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
122
123
124
125
   *
   * Called by system whenever the host adapter generates an interrupt.
   *
   * Returns handled flag.
   */
  irqreturn_t
7d12e780e   David Howells   IRQ: Maintain reg...
126
  qla2300_intr_handler(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
128
  	scsi_qla_host_t	*vha;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
129
  	struct device_reg_2xxx __iomem *reg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  	int		status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
132
  	unsigned long	iter;
  	uint32_t	stat;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  	uint16_t	hccr;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
134
  	uint16_t	mb[4];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
135
136
  	struct rsp_que *rsp;
  	struct qla_hw_data *ha;
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
137
  	unsigned long	flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
139
140
  	rsp = (struct rsp_que *) dev_id;
  	if (!rsp) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
  		printk(KERN_INFO
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
142
143
  		    "%s(): NULL response queue pointer.
  ", __func__);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
144
145
  		return (IRQ_NONE);
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
146
  	ha = rsp->hw;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
147
  	reg = &ha->iobase->isp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  	status = 0;
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
149
  	spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
150
  	vha = pci_get_drvdata(ha->pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
  	for (iter = 50; iter--; ) {
  		stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
  		if (stat & HSR_RISC_PAUSED) {
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
154
  			if (unlikely(pci_channel_offline(ha->pdev)))
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
155
  				break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
157
  			hccr = RD_REG_WORD(&reg->hccr);
  			if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
158
159
160
161
  				ql_log(ql_log_warn, vha, 0x5026,
  				    "Parity error -- HCCR=%x, Dumping "
  				    "firmware.
  ", hccr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
  			else
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
163
164
165
166
  				ql_log(ql_log_warn, vha, 0x5027,
  				    "RISC paused -- HCCR=%x, Dumping "
  				    "firmware.
  ", hccr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
168
169
170
  
  			/*
  			 * Issue a "HARD" reset in order for the RISC
  			 * interrupt bit to be cleared.  Schedule a big
a06a0f8e3   Justin P. Mattock   scsi: qla_isr.c: ...
171
  			 * hammer to get out of the RISC PAUSED state.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172
173
174
  			 */
  			WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
  			RD_REG_WORD(&reg->hccr);
07f31805e   Andrew Vasquez   [SCSI] qla2xxx: P...
175

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
176
177
  			ha->isp_ops->fw_dump(vha, 1);
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
  			break;
  		} else if ((stat & HSR_RISC_INT) == 0)
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  		switch (stat & 0xff) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
184
185
  		case 0x1:
  		case 0x2:
  		case 0x10:
  		case 0x11:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
186
  			qla2x00_mbx_completion(vha, MSW(stat));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
187
188
189
190
191
192
  			status |= MBX_INTERRUPT;
  
  			/* Release mailbox registers. */
  			WRT_REG_WORD(&reg->semaphore, 0);
  			break;
  		case 0x12:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
193
194
195
196
  			mb[0] = MSW(stat);
  			mb[1] = RD_MAILBOX_REG(ha, reg, 1);
  			mb[2] = RD_MAILBOX_REG(ha, reg, 2);
  			mb[3] = RD_MAILBOX_REG(ha, reg, 3);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
197
  			qla2x00_async_event(vha, rsp, mb);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
198
199
  			break;
  		case 0x13:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
200
  			qla2x00_process_response_queue(rsp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
  			break;
  		case 0x15:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
203
204
  			mb[0] = MBA_CMPLT_1_16BIT;
  			mb[1] = MSW(stat);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
205
  			qla2x00_async_event(vha, rsp, mb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
  			break;
  		case 0x16:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
208
209
210
  			mb[0] = MBA_SCSI_COMPLETION;
  			mb[1] = MSW(stat);
  			mb[2] = RD_MAILBOX_REG(ha, reg, 2);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
211
  			qla2x00_async_event(vha, rsp, mb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
213
  			break;
  		default:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
214
215
216
  			ql_dbg(ql_dbg_async, vha, 0x5028,
  			    "Unrecognized interrupt type (%d).
  ", stat & 0xff);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
220
221
  			break;
  		}
  		WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
  		RD_REG_WORD_RELAXED(&reg->hccr);
  	}
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
222
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
225
  	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
  	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
  		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0d   Marcus Barrow   [SCSI] qla2xxx: U...
227
  		complete(&ha->mbx_intr_comp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
234
235
236
237
  	return (IRQ_HANDLED);
  }
  
  /**
   * qla2x00_mbx_completion() - Process mailbox command completions.
   * @ha: SCSI driver HA context
   * @mb0: Mailbox0 register
   */
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
238
  qla2x00_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
  {
  	uint16_t	cnt;
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
241
  	uint32_t	mboxes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
  	uint16_t __iomem *wptr;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
243
  	struct qla_hw_data *ha = vha->hw;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
244
  	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245

4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
246
247
248
249
250
251
252
  	/* Read all mbox registers? */
  	mboxes = (1 << ha->mbx_count) - 1;
  	if (!ha->mcp)
  		ql_dbg(ql_dbg_async, vha, 0x5001, "MBX pointer ERRROR.
  ");
  	else
  		mboxes = ha->mcp->in_mb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
255
  	/* Load return mailbox registers. */
  	ha->flags.mbox_int = 1;
  	ha->mailbox_out[0] = mb0;
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
256
  	mboxes >>= 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
  	wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 1);
  
  	for (cnt = 1; cnt < ha->mbx_count; cnt++) {
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
260
  		if (IS_QLA2200(ha) && cnt == 8)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
  			wptr = (uint16_t __iomem *)MAILBOX_REG(ha, reg, 8);
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
262
  		if ((cnt == 4 || cnt == 5) && (mboxes & BIT_0))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  			ha->mailbox_out[cnt] = qla2x00_debounce_register(wptr);
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
264
  		else if (mboxes & BIT_0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  			ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
266

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
  		wptr++;
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
268
  		mboxes >>= 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  }
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
  static void
  qla81xx_idc_event(scsi_qla_host_t *vha, uint16_t aen, uint16_t descr)
  {
  	static char *event[] =
  		{ "Complete", "Request Notification", "Time Extension" };
  	int rval;
  	struct device_reg_24xx __iomem *reg24 = &vha->hw->iobase->isp24;
  	uint16_t __iomem *wptr;
  	uint16_t cnt, timeout, mb[QLA_IDC_ACK_REGS];
  
  	/* Seed data -- mailbox1 -> mailbox7. */
  	wptr = (uint16_t __iomem *)&reg24->mailbox1;
  	for (cnt = 0; cnt < QLA_IDC_ACK_REGS; cnt++, wptr++)
  		mb[cnt] = RD_REG_WORD(wptr);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
285
286
287
288
289
290
  	ql_dbg(ql_dbg_async, vha, 0x5021,
  	    "Inter-Driver Commucation %s -- "
  	    "%04x %04x %04x %04x %04x %04x %04x.
  ",
  	    event[aen & 0xff], mb[0], mb[1], mb[2], mb[3],
  	    mb[4], mb[5], mb[6]);
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
291
292
293
294
295
  
  	/* Acknowledgement needed? [Notify && non-zero timeout]. */
  	timeout = (descr >> 8) & 0xf;
  	if (aen != MBA_IDC_NOTIFY || !timeout)
  		return;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
296
  	ql_dbg(ql_dbg_async, vha, 0x5022,
d8424f68c   Joe Perches   [SCSI] qla2xxx: M...
297
298
  	    "%lu Inter-Driver Communication %s -- ACK timeout=%d.
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
299
  	    vha->host_no, event[aen & 0xff], timeout);
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
300
301
302
  
  	rval = qla2x00_post_idc_ack_work(vha, mb);
  	if (rval != QLA_SUCCESS)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
303
  		ql_log(ql_log_warn, vha, 0x5023,
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
304
305
306
  		    "IDC failed to post ACK.
  ");
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
  /**
   * qla2x00_async_event() - Process aynchronous events.
   * @ha: SCSI driver HA context
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
310
   * @mb: Mailbox registers (0 - 3)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
311
   */
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
312
  void
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
313
  qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
  {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
315
  #define LS_UNKNOWN	2
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
316
  	static char	*link_speeds[] = { "1", "2", "?", "4", "8", "10" };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  	char		*link_speed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
  	uint16_t	handle_cnt;
bdab23da7   Andrew Vasquez   [SCSI] qla2xxx: D...
319
  	uint16_t	cnt, mbx;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
320
  	uint32_t	handles[5];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
321
  	struct qla_hw_data *ha = vha->hw;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
322
  	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
bdab23da7   Andrew Vasquez   [SCSI] qla2xxx: D...
323
  	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
bc5c2aad1   Andrew Vasquez   [SCSI] qla2xxx: D...
324
  	struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
326
  	uint32_t	rscn_entry, host_pid;
  	uint8_t		rscn_queue_index;
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
327
  	unsigned long	flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
329
330
  
  	/* Setup to process RIO completion. */
  	handle_cnt = 0;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
331
  	if (IS_QLA8XXX_TYPE(ha))
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
332
  		goto skip_rio;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
333
334
  	switch (mb[0]) {
  	case MBA_SCSI_COMPLETION:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
335
  		handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
338
  		handle_cnt = 1;
  		break;
  	case MBA_CMPLT_1_16BIT:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
339
  		handles[0] = mb[1];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
341
342
343
  		handle_cnt = 1;
  		mb[0] = MBA_SCSI_COMPLETION;
  		break;
  	case MBA_CMPLT_2_16BIT:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
344
345
  		handles[0] = mb[1];
  		handles[1] = mb[2];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
347
348
349
  		handle_cnt = 2;
  		mb[0] = MBA_SCSI_COMPLETION;
  		break;
  	case MBA_CMPLT_3_16BIT:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
350
351
352
  		handles[0] = mb[1];
  		handles[1] = mb[2];
  		handles[2] = mb[3];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
356
  		handle_cnt = 3;
  		mb[0] = MBA_SCSI_COMPLETION;
  		break;
  	case MBA_CMPLT_4_16BIT:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
357
358
359
  		handles[0] = mb[1];
  		handles[1] = mb[2];
  		handles[2] = mb[3];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
361
362
363
364
  		handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
  		handle_cnt = 4;
  		mb[0] = MBA_SCSI_COMPLETION;
  		break;
  	case MBA_CMPLT_5_16BIT:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
365
366
367
  		handles[0] = mb[1];
  		handles[1] = mb[2];
  		handles[2] = mb[3];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
368
369
370
371
372
373
  		handles[3] = (uint32_t)RD_MAILBOX_REG(ha, reg, 6);
  		handles[4] = (uint32_t)RD_MAILBOX_REG(ha, reg, 7);
  		handle_cnt = 5;
  		mb[0] = MBA_SCSI_COMPLETION;
  		break;
  	case MBA_CMPLT_2_32BIT:
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
374
  		handles[0] = le32_to_cpu((uint32_t)((mb[2] << 16) | mb[1]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
375
376
377
378
379
380
381
382
383
  		handles[1] = le32_to_cpu(
  		    ((uint32_t)(RD_MAILBOX_REG(ha, reg, 7) << 16)) |
  		    RD_MAILBOX_REG(ha, reg, 6));
  		handle_cnt = 2;
  		mb[0] = MBA_SCSI_COMPLETION;
  		break;
  	default:
  		break;
  	}
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
384
  skip_rio:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
386
  	switch (mb[0]) {
  	case MBA_SCSI_COMPLETION:	/* Fast Post */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
387
  		if (!vha->flags.online)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
389
390
  			break;
  
  		for (cnt = 0; cnt < handle_cnt; cnt++)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
391
392
  			qla2x00_process_completed_request(vha, rsp->req,
  				handles[cnt]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
  		break;
  
  	case MBA_RESET:			/* Reset */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
396
397
398
  		ql_dbg(ql_dbg_async, vha, 0x5002,
  		    "Asynchronous RESET.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
400
  		set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
  		break;
  
  	case MBA_SYSTEM_ERR:		/* System Error */
bdab23da7   Andrew Vasquez   [SCSI] qla2xxx: D...
404
  		mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox7) : 0;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
405
  		ql_log(ql_log_warn, vha, 0x5003,
bdab23da7   Andrew Vasquez   [SCSI] qla2xxx: D...
406
407
408
  		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh "
  		    "mbx7=%xh.
  ", mb[1], mb[2], mb[3], mbx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
409

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
410
  		ha->isp_ops->fw_dump(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411

e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
412
  		if (IS_FWI2_CAPABLE(ha)) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
413
  			if (mb[1] == 0 && mb[2] == 0) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
414
  				ql_log(ql_log_fatal, vha, 0x5004,
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
415
416
417
  				    "Unrecoverable Hardware Error: adapter "
  				    "marked OFFLINE!
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
418
  				vha->flags.online = 0;
b1d46989c   Madhuranath Iyengar   [SCSI] qla2xxx: H...
419
  			} else {
25985edce   Lucas De Marchi   Fix common misspe...
420
  				/* Check to see if MPI timeout occurred */
b1d46989c   Madhuranath Iyengar   [SCSI] qla2xxx: H...
421
422
423
  				if ((mbx & MBX_3) && (ha->flags.port0))
  					set_bit(MPI_RESET_NEEDED,
  					    &vha->dpc_flags);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
424
  				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
b1d46989c   Madhuranath Iyengar   [SCSI] qla2xxx: H...
425
  			}
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
426
  		} else if (mb[1] == 0) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
427
  			ql_log(ql_log_fatal, vha, 0x5005,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
429
430
  			    "Unrecoverable Hardware Error: adapter marked "
  			    "OFFLINE!
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
431
  			vha->flags.online = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
432
  		} else
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
433
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434
435
436
  		break;
  
  	case MBA_REQ_TRANSFER_ERR:	/* Request Transfer Error */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
437
438
439
  		ql_log(ql_log_warn, vha, 0x5006,
  		    "ISP Request Transfer Error (%x).
  ",  mb[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
441
  		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
444
  		break;
  
  	case MBA_RSP_TRANSFER_ERR:	/* Response Transfer Error */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
445
446
447
  		ql_log(ql_log_warn, vha, 0x5007,
  		    "ISP Response Transfer Error.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
449
  		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
451
452
  		break;
  
  	case MBA_WAKEUP_THRES:		/* Request Queue Wake-up */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
453
454
455
  		ql_dbg(ql_dbg_async, vha, 0x5008,
  		    "Asynchronous WAKEUP_THRES.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
457
458
  		break;
  
  	case MBA_LIP_OCCURRED:		/* Loop Initialization Procedure */
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
459
  		ql_dbg(ql_dbg_async, vha, 0x5009,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
460
461
  		    "LIP occurred (%x).
  ", mb[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
463
464
465
466
  		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
  			atomic_set(&vha->loop_state, LOOP_DOWN);
  			atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
  			qla2x00_mark_all_devices_lost(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
468
469
470
  		if (vha->vp_idx) {
  			atomic_set(&vha->vp_state, VP_FAILED);
  			fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
471
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
472
473
  		set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
  		set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
475
476
  		vha->flags.management_server_logged_in = 0;
  		qla2x00_post_aen_work(vha, FCH_EVT_LIP, mb[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
478
479
  		break;
  
  	case MBA_LOOP_UP:		/* Loop Up Event */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
481
  		if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
  			link_speed = link_speeds[0];
d8b452134   Andrew Vasquez   [SCSI] qla2xxx: A...
482
  			ha->link_data_rate = PORT_SPEED_1GB;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  		} else {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
484
  			link_speed = link_speeds[LS_UNKNOWN];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
  			if (mb[1] < 5)
  				link_speed = link_speeds[mb[1]];
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
487
488
  			else if (mb[1] == 0x13)
  				link_speed = link_speeds[5];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
490
  			ha->link_data_rate = mb[1];
  		}
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
491
  		ql_dbg(ql_dbg_async, vha, 0x500a,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
492
493
  		    "LOOP UP detected (%s Gbps).
  ", link_speed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
495
496
  		vha->flags.management_server_logged_in = 0;
  		qla2x00_post_aen_work(vha, FCH_EVT_LINKUP, ha->link_data_rate);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
497
498
499
  		break;
  
  	case MBA_LOOP_DOWN:		/* Loop Down Event */
bdab23da7   Andrew Vasquez   [SCSI] qla2xxx: D...
500
  		mbx = IS_QLA81XX(ha) ? RD_REG_WORD(&reg24->mailbox4) : 0;
bc5c2aad1   Andrew Vasquez   [SCSI] qla2xxx: D...
501
  		mbx = IS_QLA82XX(ha) ? RD_REG_WORD(&reg82->mailbox_out[4]) : mbx;
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
502
  		ql_dbg(ql_dbg_async, vha, 0x500b,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
503
504
505
  		    "LOOP DOWN detected (%x %x %x %x).
  ",
  		    mb[1], mb[2], mb[3], mbx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
507
508
509
510
511
  		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
  			atomic_set(&vha->loop_state, LOOP_DOWN);
  			atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
  			vha->device_flags |= DFLG_NO_CABLE;
  			qla2x00_mark_all_devices_lost(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
513
514
515
  		if (vha->vp_idx) {
  			atomic_set(&vha->vp_state, VP_FAILED);
  			fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
516
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
517
  		vha->flags.management_server_logged_in = 0;
d8b452134   Andrew Vasquez   [SCSI] qla2xxx: A...
518
  		ha->link_data_rate = PORT_SPEED_UNKNOWN;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
519
  		qla2x00_post_aen_work(vha, FCH_EVT_LINKDOWN, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
522
  		break;
  
  	case MBA_LIP_RESET:		/* LIP reset occurred */
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
523
  		ql_dbg(ql_dbg_async, vha, 0x500c,
cc3ef7bc4   Bjorn Helgaas   [SCSI] qla2xxx: F...
524
525
  		    "LIP reset occurred (%x).
  ", mb[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
526

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
527
528
529
530
  		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
  			atomic_set(&vha->loop_state, LOOP_DOWN);
  			atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
  			qla2x00_mark_all_devices_lost(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
532
533
534
  		if (vha->vp_idx) {
  			atomic_set(&vha->vp_state, VP_FAILED);
  			fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
535
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
536
  		set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
537
538
  
  		ha->operating_mode = LOOP;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
539
540
  		vha->flags.management_server_logged_in = 0;
  		qla2x00_post_aen_work(vha, FCH_EVT_LIPRESET, mb[1]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  		break;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
542
  	/* case MBA_DCBX_COMPLETE: */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
543
544
545
  	case MBA_POINT_TO_POINT:	/* Point-to-Point */
  		if (IS_QLA2100(ha))
  			break;
23f2ebd17   Sarang Radke   [SCSI] qla2xxx: A...
546
  		if (IS_QLA8XXX_TYPE(ha)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
547
548
549
550
  			ql_dbg(ql_dbg_async, vha, 0x500d,
  			    "DCBX Completed -- %04x %04x %04x.
  ",
  			    mb[1], mb[2], mb[3]);
23f2ebd17   Sarang Radke   [SCSI] qla2xxx: A...
551
552
553
554
  			if (ha->notify_dcbx_comp)
  				complete(&ha->dcbx_comp);
  
  		} else
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
555
556
557
  			ql_dbg(ql_dbg_async, vha, 0x500e,
  			    "Asynchronous P2P MODE received.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
559
560
561
562
  
  		/*
  		 * Until there's a transition from loop down to loop up, treat
  		 * this as loop down only.
  		 */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
563
564
565
566
  		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
  			atomic_set(&vha->loop_state, LOOP_DOWN);
  			if (!atomic_read(&vha->loop_down_timer))
  				atomic_set(&vha->loop_down_timer,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
  				    LOOP_DOWN_TIME);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
568
  			qla2x00_mark_all_devices_lost(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
570
571
572
  		if (vha->vp_idx) {
  			atomic_set(&vha->vp_state, VP_FAILED);
  			fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
573
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
574
575
576
577
578
  		if (!(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)))
  			set_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
  
  		set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
  		set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
4346b1494   Andrew Vasquez   [SCSI] qla2xxx: D...
579
580
  
  		ha->flags.gpsc_supported = 1;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
581
  		vha->flags.management_server_logged_in = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
583
584
585
586
  		break;
  
  	case MBA_CHG_IN_CONNECTION:	/* Change in connection mode */
  		if (IS_QLA2100(ha))
  			break;
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
587
  		ql_dbg(ql_dbg_async, vha, 0x500f,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
588
589
  		    "Configuration change detected: value=%x.
  ", mb[1]);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
590
591
592
593
  		if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
  			atomic_set(&vha->loop_state, LOOP_DOWN);
  			if (!atomic_read(&vha->loop_down_timer))
  				atomic_set(&vha->loop_down_timer,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
  				    LOOP_DOWN_TIME);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
595
  			qla2x00_mark_all_devices_lost(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
596
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
597
598
599
  		if (vha->vp_idx) {
  			atomic_set(&vha->vp_state, VP_FAILED);
  			fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
600
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
601
602
  		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
604
605
  		break;
  
  	case MBA_PORT_UPDATE:		/* Port database update */
55903b9d1   Santosh Vernekar   [SCSI] qla2xxx: S...
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
  		/*
  		 * Handle only global and vn-port update events
  		 *
  		 * Relevant inputs:
  		 * mb[1] = N_Port handle of changed port
  		 * OR 0xffff for global event
  		 * mb[2] = New login state
  		 * 7 = Port logged out
  		 * mb[3] = LSB is vp_idx, 0xff = all vps
  		 *
  		 * Skip processing if:
  		 *       Event is global, vp_idx is NOT all vps,
  		 *           vp_idx does not match
  		 *       Event is not global, vp_idx does not match
  		 */
12cec63e4   Andrew Vasquez   [SCSI] qla2xxx: C...
621
622
623
624
  		if (IS_QLA2XXX_MIDTYPE(ha) &&
  		    ((mb[1] == 0xffff && (mb[3] & 0xff) != 0xff) ||
  			(mb[1] != 0xffff)) && vha->vp_idx != (mb[3] & 0xff))
  			break;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
625

9764ff880   Andrew Vasquez   [SCSI] qla2xxx: C...
626
627
  		/* Global event -- port logout or port unavailable. */
  		if (mb[1] == 0xffff && mb[2] == 0x7) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
628
629
630
631
  			ql_dbg(ql_dbg_async, vha, 0x5010,
  			    "Port unavailable %04x %04x %04x.
  ",
  			    mb[1], mb[2], mb[3]);
9764ff880   Andrew Vasquez   [SCSI] qla2xxx: C...
632
633
634
635
636
637
638
639
640
641
642
643
644
  
  			if (atomic_read(&vha->loop_state) != LOOP_DOWN) {
  				atomic_set(&vha->loop_state, LOOP_DOWN);
  				atomic_set(&vha->loop_down_timer,
  				    LOOP_DOWN_TIME);
  				vha->device_flags |= DFLG_NO_CABLE;
  				qla2x00_mark_all_devices_lost(vha, 1);
  			}
  
  			if (vha->vp_idx) {
  				atomic_set(&vha->vp_state, VP_FAILED);
  				fc_vport_set_state(vha->fc_vport,
  				    FC_VPORT_FAILED);
faadc5e71   Santosh Vernekar   [SCSI] qla2xxx: M...
645
  				qla2x00_mark_all_devices_lost(vha, 1);
9764ff880   Andrew Vasquez   [SCSI] qla2xxx: C...
646
647
648
649
650
651
  			}
  
  			vha->flags.management_server_logged_in = 0;
  			ha->link_data_rate = PORT_SPEED_UNKNOWN;
  			break;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
  		/*
cc3ef7bc4   Bjorn Helgaas   [SCSI] qla2xxx: F...
653
  		 * If PORT UPDATE is global (received LIP_OCCURRED/LIP_RESET
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654
655
656
  		 * event etc. earlier indicating loop is down) then process
  		 * it.  Otherwise ignore it and Wait for RSCN to come in.
  		 */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
657
658
659
  		atomic_set(&vha->loop_down_timer, 0);
  		if (atomic_read(&vha->loop_state) != LOOP_DOWN &&
  		    atomic_read(&vha->loop_state) != LOOP_DEAD) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
660
661
662
663
  			ql_dbg(ql_dbg_async, vha, 0x5011,
  			    "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.
  ",
  			    mb[1], mb[2], mb[3]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664
665
  			break;
  		}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
666
667
668
669
  		ql_dbg(ql_dbg_async, vha, 0x5012,
  		    "Port database changed %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
671
672
673
  
  		/*
  		 * Mark all devices as missing so we will login again.
  		 */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
674
  		atomic_set(&vha->loop_state, LOOP_UP);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
675

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
676
  		qla2x00_mark_all_devices_lost(vha, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
678
  		vha->flags.rscn_queue_overflow = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
680
681
  		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  		set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
683
684
  		break;
  
  	case MBA_RSCN_UPDATE:		/* State Change Registration */
3c3974007   Seokmann Ju   [SCSI] qla2xxx: R...
685
  		/* Check if the Vport has issued a SCR */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
686
  		if (vha->vp_idx && test_bit(VP_SCR_NEEDED, &vha->vp_flags))
3c3974007   Seokmann Ju   [SCSI] qla2xxx: R...
687
688
  			break;
  		/* Only handle SCNs for our Vport index. */
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
689
  		if (ha->flags.npiv_supported && vha->vp_idx != (mb[3] & 0xff))
3c3974007   Seokmann Ju   [SCSI] qla2xxx: R...
690
  			break;
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
691

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
692
693
694
695
  		ql_dbg(ql_dbg_async, vha, 0x5013,
  		    "RSCN database changed -- %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696

59d72d873   Ravi Anand   [SCSI] qla2xxx: I...
697
  		rscn_entry = ((mb[1] & 0xff) << 16) | mb[2];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
698
699
  		host_pid = (vha->d_id.b.domain << 16) | (vha->d_id.b.area << 8)
  				| vha->d_id.b.al_pa;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700
  		if (rscn_entry == host_pid) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
701
702
703
704
  			ql_dbg(ql_dbg_async, vha, 0x5014,
  			    "Ignoring RSCN update to local host "
  			    "port ID (%06x).
  ", host_pid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
706
  			break;
  		}
59d72d873   Ravi Anand   [SCSI] qla2xxx: I...
707
708
  		/* Ignore reserved bits from RSCN-payload. */
  		rscn_entry = ((mb[1] & 0x3ff) << 16) | mb[2];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
709
  		rscn_queue_index = vha->rscn_in_ptr + 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
711
  		if (rscn_queue_index == MAX_RSCN_COUNT)
  			rscn_queue_index = 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
712
713
714
  		if (rscn_queue_index != vha->rscn_out_ptr) {
  			vha->rscn_queue[vha->rscn_in_ptr] = rscn_entry;
  			vha->rscn_in_ptr = rscn_queue_index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
715
  		} else {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
716
  			vha->flags.rscn_queue_overflow = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
717
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
718
719
  		atomic_set(&vha->loop_down_timer, 0);
  		vha->flags.management_server_logged_in = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
720

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
721
722
723
  		set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  		set_bit(RSCN_UPDATE, &vha->dpc_flags);
  		qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724
725
726
727
  		break;
  
  	/* case MBA_RIO_RESPONSE: */
  	case MBA_ZIO_RESPONSE:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
728
729
730
  		ql_dbg(ql_dbg_async, vha, 0x5015,
  		    "[R|Z]IO update completion.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731

e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
732
  		if (IS_FWI2_CAPABLE(ha))
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
733
  			qla24xx_process_response_queue(vha, rsp);
4fdfefe52   Andrew Vasquez   [SCSI] qla2xxx: A...
734
  		else
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
735
  			qla2x00_process_response_queue(rsp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
736
  		break;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
737
738
  
  	case MBA_DISCARD_RND_FRAME:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
739
740
741
742
  		ql_dbg(ql_dbg_async, vha, 0x5016,
  		    "Discard RND Frame -- %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
743
  		break;
45ebeb560   Andrew Vasquez   [SCSI] qla2xxx: L...
744
745
  
  	case MBA_TRACE_NOTIFICATION:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
746
747
748
  		ql_dbg(ql_dbg_async, vha, 0x5017,
  		    "Trace Notification -- %04x %04x.
  ", mb[1], mb[2]);
45ebeb560   Andrew Vasquez   [SCSI] qla2xxx: L...
749
  		break;
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
750
751
  
  	case MBA_ISP84XX_ALERT:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
752
753
754
755
  		ql_dbg(ql_dbg_async, vha, 0x5018,
  		    "ISP84XX Alert Notification -- %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
756
757
758
759
  
  		spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
  		switch (mb[1]) {
  		case A84_PANIC_RECOVERY:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
760
761
762
763
  			ql_log(ql_log_info, vha, 0x5019,
  			    "Alert 84XX: panic recovery %04x %04x.
  ",
  			    mb[2], mb[3]);
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
764
765
766
  			break;
  		case A84_OP_LOGIN_COMPLETE:
  			ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2];
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
767
768
769
770
  			ql_log(ql_log_info, vha, 0x501a,
  			    "Alert 84XX: firmware version %x.
  ",
  			    ha->cs84xx->op_fw_version);
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
771
772
773
  			break;
  		case A84_DIAG_LOGIN_COMPLETE:
  			ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
774
775
776
777
  			ql_log(ql_log_info, vha, 0x501b,
  			    "Alert 84XX: diagnostic firmware version %x.
  ",
  			    ha->cs84xx->diag_fw_version);
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
778
779
780
781
  			break;
  		case A84_GOLD_LOGIN_COMPLETE:
  			ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
  			ha->cs84xx->fw_update = 1;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
782
783
784
785
  			ql_log(ql_log_info, vha, 0x501c,
  			    "Alert 84XX: gold firmware version %x.
  ",
  			    ha->cs84xx->gold_fw_version);
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
786
787
  			break;
  		default:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
788
789
790
  			ql_log(ql_log_warn, vha, 0x501d,
  			    "Alert 84xx: Invalid Alert %04x %04x %04x.
  ",
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
791
792
793
794
  			    mb[1], mb[2], mb[3]);
  		}
  		spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags);
  		break;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
795
  	case MBA_DCBX_START:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
796
797
798
799
  		ql_dbg(ql_dbg_async, vha, 0x501e,
  		    "DCBX Started -- %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
800
801
  		break;
  	case MBA_DCBX_PARAM_UPDATE:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
802
803
804
805
  		ql_dbg(ql_dbg_async, vha, 0x501f,
  		    "DCBX Parameters Updated -- %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
806
807
  		break;
  	case MBA_FCF_CONF_ERR:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
808
809
810
811
  		ql_dbg(ql_dbg_async, vha, 0x5020,
  		    "FCF Configuration Error -- %04x %04x %04x.
  ",
  		    mb[1], mb[2], mb[3]);
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
812
813
  		break;
  	case MBA_IDC_COMPLETE:
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
814
  	case MBA_IDC_NOTIFY:
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
815
  	case MBA_IDC_TIME_EXT:
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
816
  		qla81xx_idc_event(vha, mb[0], mb[1]);
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
817
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
  	}
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
819

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
820
  	if (!vha->vp_idx && ha->num_vhosts)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
821
  		qla2x00_alert_all_vps(rsp, mb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
824
825
826
827
828
829
  }
  
  /**
   * qla2x00_process_completed_request() - Process a Fast Post response.
   * @ha: SCSI driver HA context
   * @index: SRB index
   */
  static void
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
830
831
  qla2x00_process_completed_request(struct scsi_qla_host *vha,
  				struct req_que *req, uint32_t index)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
833
  {
  	srb_t *sp;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
834
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
836
837
  
  	/* Validate handle. */
  	if (index >= MAX_OUTSTANDING_COMMANDS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
838
839
840
  		ql_log(ql_log_warn, vha, 0x3014,
  		    "Invalid SCSI command index (%x).
  ", index);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
841

8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
842
843
844
845
  		if (IS_QLA82XX(ha))
  			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
  		else
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
846
847
  		return;
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
848
  	sp = req->outstanding_cmds[index];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
850
  	if (sp) {
  		/* Free outstanding command slot. */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
851
  		req->outstanding_cmds[index] = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
854
  		/* Save ISP completion status */
  		sp->cmd->result = DID_OK << 16;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
855
  		qla2x00_sp_compl(ha, sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  	} else {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
857
858
  		ql_log(ql_log_warn, vha, 0x3016, "Invalid SCSI SRB.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859

8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
860
861
862
863
  		if (IS_QLA82XX(ha))
  			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
  		else
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
865
  	}
  }
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
866
867
868
869
870
871
872
873
874
875
876
  static srb_t *
  qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
      struct req_que *req, void *iocb)
  {
  	struct qla_hw_data *ha = vha->hw;
  	sts_entry_t *pkt = iocb;
  	srb_t *sp = NULL;
  	uint16_t index;
  
  	index = LSW(pkt->handle);
  	if (index >= MAX_OUTSTANDING_COMMANDS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
877
878
879
  		ql_log(ql_log_warn, vha, 0x5031,
  		    "Invalid command index (%x).
  ", index);
8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
880
881
882
883
  		if (IS_QLA82XX(ha))
  			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
  		else
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
884
885
886
887
  		goto done;
  	}
  	sp = req->outstanding_cmds[index];
  	if (!sp) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
888
889
890
  		ql_log(ql_log_warn, vha, 0x5032,
  		    "Invalid completion handle (%x) -- timed-out.
  ", index);
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
891
892
893
  		return sp;
  	}
  	if (sp->handle != index) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
894
895
896
  		ql_log(ql_log_warn, vha, 0x5033,
  		    "SRB handle (%x) mismatch %x.
  ", sp->handle, index);
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
897
898
  		return NULL;
  	}
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
899

ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
900
  	req->outstanding_cmds[index] = NULL;
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
901

ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
902
903
904
905
906
907
908
909
910
911
  done:
  	return sp;
  }
  
  static void
  qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
      struct mbx_entry *mbx)
  {
  	const char func[] = "MBX-IOCB";
  	const char *type;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
912
913
  	fc_port_t *fcport;
  	srb_t *sp;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
914
915
  	struct srb_iocb *lio;
  	struct srb_ctx *ctx;
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
916
  	uint16_t *data;
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
917
  	uint16_t status;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
918
919
920
921
  
  	sp = qla2x00_get_sp_from_handle(vha, func, req, mbx);
  	if (!sp)
  		return;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
922
923
924
  	ctx = sp->ctx;
  	lio = ctx->u.iocb_cmd;
  	type = ctx->name;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
925
  	fcport = sp->fcport;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
926
  	data = lio->u.logio.data;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
927

5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
928
  	data[0] = MBS_COMMAND_ERROR;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
929
  	data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
930
  	    QLA_LOGIO_LOGIN_RETRIED : 0;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
931
  	if (mbx->entry_status) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
932
  		ql_dbg(ql_dbg_async, vha, 0x5043,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
933
  		    "Async-%s error entry - hdl=%x portid=%02x%02x%02x "
d3fa9e7d2   Andrew Vasquez   [SCSI] qla2xxx: A...
934
  		    "entry-status=%x status=%x state-flag=%x "
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
935
936
937
  		    "status-flags=%x.
  ", type, sp->handle,
  		    fcport->d_id.b.domain, fcport->d_id.b.area,
d3fa9e7d2   Andrew Vasquez   [SCSI] qla2xxx: A...
938
939
  		    fcport->d_id.b.al_pa, mbx->entry_status,
  		    le16_to_cpu(mbx->status), le16_to_cpu(mbx->state_flags),
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
940
  		    le16_to_cpu(mbx->status_flags));
d3fa9e7d2   Andrew Vasquez   [SCSI] qla2xxx: A...
941

cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
942
  		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5029,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
943
  		    (uint8_t *)mbx, sizeof(*mbx));
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
944

99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
945
  		goto logio_done;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
946
  	}
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
947
  	status = le16_to_cpu(mbx->status);
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
948
  	if (status == 0x30 && ctx->type == SRB_LOGIN_CMD &&
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
949
950
951
  	    le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE)
  		status = 0;
  	if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
952
  		ql_dbg(ql_dbg_async, vha, 0x5045,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
953
954
955
956
957
  		    "Async-%s complete - hdl=%x portid=%02x%02x%02x mbx1=%x.
  ",
  		    type, sp->handle, fcport->d_id.b.domain,
  		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
  		    le16_to_cpu(mbx->mb1));
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
958
959
  
  		data[0] = MBS_COMMAND_COMPLETE;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
960
  		if (ctx->type == SRB_LOGIN_CMD) {
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
961
962
963
  			fcport->port_type = FCT_TARGET;
  			if (le16_to_cpu(mbx->mb1) & BIT_0)
  				fcport->port_type = FCT_INITIATOR;
6ac526085   Andrew Vasquez   [SCSI] qla2xxx: C...
964
  			else if (le16_to_cpu(mbx->mb1) & BIT_1)
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
965
  				fcport->flags |= FCF_FCP2_DEVICE;
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
966
  		}
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
967
  		goto logio_done;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
968
969
970
971
972
973
974
975
976
977
978
  	}
  
  	data[0] = le16_to_cpu(mbx->mb0);
  	switch (data[0]) {
  	case MBS_PORT_ID_USED:
  		data[1] = le16_to_cpu(mbx->mb1);
  		break;
  	case MBS_LOOP_ID_USED:
  		break;
  	default:
  		data[0] = MBS_COMMAND_ERROR;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
979
980
  		break;
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
981
  	ql_log(ql_log_warn, vha, 0x5046,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
982
983
984
985
986
  	    "Async-%s failed - hdl=%x portid=%02x%02x%02x status=%x "
  	    "mb0=%x mb1=%x mb2=%x mb6=%x mb7=%x.
  ", type, sp->handle,
  	    fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa,
  	    status, le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1),
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
987
  	    le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6),
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
988
  	    le16_to_cpu(mbx->mb7));
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
989

99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
990
  logio_done:
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
991
  	lio->done(sp);
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
992
993
994
  }
  
  static void
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
  qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
      sts_entry_t *pkt, int iocb_type)
  {
  	const char func[] = "CT_IOCB";
  	const char *type;
  	struct qla_hw_data *ha = vha->hw;
  	srb_t *sp;
  	struct srb_ctx *sp_bsg;
  	struct fc_bsg_job *bsg_job;
  	uint16_t comp_status;
  
  	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
  	if (!sp)
  		return;
  
  	sp_bsg = sp->ctx;
  	bsg_job = sp_bsg->u.bsg_job;
  
  	type = NULL;
  	switch (sp_bsg->type) {
  	case SRB_CT_CMD:
  		type = "ct pass-through";
  		break;
  	default:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1019
1020
1021
  		ql_log(ql_log_warn, vha, 0x5047,
  		    "Unrecognized SRB: (%p) type=%d.
  ", sp, sp_bsg->type);
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
  		return;
  	}
  
  	comp_status = le16_to_cpu(pkt->comp_status);
  
  	/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
  	 * fc payload  to the caller
  	 */
  	bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
  	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
  
  	if (comp_status != CS_COMPLETE) {
  		if (comp_status == CS_DATA_UNDERRUN) {
  			bsg_job->reply->result = DID_OK << 16;
  			bsg_job->reply->reply_payload_rcv_len =
  			    le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1038
1039
  			ql_log(ql_log_warn, vha, 0x5048,
  			    "CT pass-through-%s error "
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1040
1041
  			    "comp_status-status=0x%x total_byte = 0x%x.
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1042
1043
  			    type, comp_status,
  			    bsg_job->reply->reply_payload_rcv_len);
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1044
  		} else {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1045
1046
1047
1048
  			ql_log(ql_log_warn, vha, 0x5049,
  			    "CT pass-through-%s error "
  			    "comp_status-status=0x%x.
  ", type, comp_status);
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1049
1050
1051
  			bsg_job->reply->result = DID_ERROR << 16;
  			bsg_job->reply->reply_payload_rcv_len = 0;
  		}
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1052
  		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5035,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1053
  		    (uint8_t *)pkt, sizeof(*pkt));
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1054
  	} else {
6eab04a87   Justin P. Mattock   treewide: remove ...
1055
  		bsg_job->reply->result =  DID_OK << 16;
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
  		bsg_job->reply->reply_payload_rcv_len =
  		    bsg_job->reply_payload.payload_len;
  		bsg_job->reply_len = 0;
  	}
  
  	dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
  	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
  
  	dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
  	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
  
  	if (sp_bsg->type == SRB_ELS_CMD_HST || sp_bsg->type == SRB_CT_CMD)
  		kfree(sp->fcport);
  
  	kfree(sp->ctx);
  	mempool_free(sp, ha->srb_mempool);
  	bsg_job->job_done(bsg_job);
  }
  
  static void
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1076
1077
1078
1079
1080
1081
1082
  qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
      struct sts_entry_24xx *pkt, int iocb_type)
  {
  	const char func[] = "ELS_CT_IOCB";
  	const char *type;
  	struct qla_hw_data *ha = vha->hw;
  	srb_t *sp;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1083
  	struct srb_ctx *sp_bsg;
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1084
1085
1086
1087
1088
1089
1090
1091
  	struct fc_bsg_job *bsg_job;
  	uint16_t comp_status;
  	uint32_t fw_status[3];
  	uint8_t* fw_sts_ptr;
  
  	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
  	if (!sp)
  		return;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1092
1093
  	sp_bsg = sp->ctx;
  	bsg_job = sp_bsg->u.bsg_job;
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1094
1095
  
  	type = NULL;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1096
  	switch (sp_bsg->type) {
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1097
1098
1099
1100
1101
1102
1103
1104
  	case SRB_ELS_CMD_RPT:
  	case SRB_ELS_CMD_HST:
  		type = "els";
  		break;
  	case SRB_CT_CMD:
  		type = "ct pass-through";
  		break;
  	default:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1105
1106
1107
  		ql_log(ql_log_warn, vha, 0x503e,
  		    "Unrecognized SRB: (%p) type=%d.
  ", sp, sp_bsg->type);
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
  		return;
  	}
  
  	comp_status = fw_status[0] = le16_to_cpu(pkt->comp_status);
  	fw_status[1] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_1);
  	fw_status[2] = le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->error_subcode_2);
  
  	/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
  	 * fc payload  to the caller
  	 */
  	bsg_job->reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
  	bsg_job->reply_len = sizeof(struct fc_bsg_reply) + sizeof(fw_status);
  
  	if (comp_status != CS_COMPLETE) {
  		if (comp_status == CS_DATA_UNDERRUN) {
  			bsg_job->reply->result = DID_OK << 16;
  			bsg_job->reply->reply_payload_rcv_len =
  				le16_to_cpu(((struct els_sts_entry_24xx*)pkt)->total_byte_count);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1126
  			ql_log(ql_log_info, vha, 0x503f,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1127
  			    "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1128
1129
  			    "error subcode 1=0x%x error subcode 2=0x%x total_byte = 0x%x.
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1130
  			    type, sp->handle, comp_status, fw_status[1], fw_status[2],
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1131
1132
  			    le16_to_cpu(((struct els_sts_entry_24xx *)
  				pkt)->total_byte_count));
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1133
1134
1135
1136
  			fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
  			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
  		}
  		else {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1137
  			ql_log(ql_log_info, vha, 0x5040,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1138
  			    "ELS-CT pass-through-%s error hdl=%x comp_status-status=0x%x "
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1139
1140
  			    "error subcode 1=0x%x error subcode 2=0x%x.
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1141
  			    type, sp->handle, comp_status,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1142
1143
1144
1145
  			    le16_to_cpu(((struct els_sts_entry_24xx *)
  				pkt)->error_subcode_1),
  			    le16_to_cpu(((struct els_sts_entry_24xx *)
  				    pkt)->error_subcode_2));
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1146
1147
1148
1149
1150
  			bsg_job->reply->result = DID_ERROR << 16;
  			bsg_job->reply->reply_payload_rcv_len = 0;
  			fw_sts_ptr = ((uint8_t*)bsg_job->req->sense) + sizeof(struct fc_bsg_reply);
  			memcpy( fw_sts_ptr, fw_status, sizeof(fw_status));
  		}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1151
1152
  		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5056,
  				(uint8_t *)pkt, sizeof(*pkt));
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1153
1154
  	}
  	else {
6eab04a87   Justin P. Mattock   treewide: remove ...
1155
  		bsg_job->reply->result =  DID_OK << 16;
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  		bsg_job->reply->reply_payload_rcv_len = bsg_job->reply_payload.payload_len;
  		bsg_job->reply_len = 0;
  	}
  
  	dma_unmap_sg(&ha->pdev->dev,
  	    bsg_job->request_payload.sg_list,
  	    bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
  	dma_unmap_sg(&ha->pdev->dev,
  	    bsg_job->reply_payload.sg_list,
  	    bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1166
1167
  	if ((sp_bsg->type == SRB_ELS_CMD_HST) ||
  	    (sp_bsg->type == SRB_CT_CMD))
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
1168
1169
1170
1171
1172
1173
1174
  		kfree(sp->fcport);
  	kfree(sp->ctx);
  	mempool_free(sp, ha->srb_mempool);
  	bsg_job->job_done(bsg_job);
  }
  
  static void
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1175
1176
1177
1178
1179
  qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
      struct logio_entry_24xx *logio)
  {
  	const char func[] = "LOGIO-IOCB";
  	const char *type;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1180
1181
  	fc_port_t *fcport;
  	srb_t *sp;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1182
1183
  	struct srb_iocb *lio;
  	struct srb_ctx *ctx;
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
1184
  	uint16_t *data;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1185
1186
1187
1188
1189
  	uint32_t iop[2];
  
  	sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
  	if (!sp)
  		return;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1190
1191
1192
  	ctx = sp->ctx;
  	lio = ctx->u.iocb_cmd;
  	type = ctx->name;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1193
  	fcport = sp->fcport;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1194
  	data = lio->u.logio.data;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1195

5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
1196
  	data[0] = MBS_COMMAND_ERROR;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1197
  	data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
1198
  		QLA_LOGIO_LOGIN_RETRIED : 0;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1199
  	if (logio->entry_status) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1200
  		ql_log(ql_log_warn, vha, 0x5034,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1201
  		    "Async-%s error entry - hdl=%x"
d3fa9e7d2   Andrew Vasquez   [SCSI] qla2xxx: A...
1202
1203
  		    "portid=%02x%02x%02x entry-status=%x.
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1204
1205
1206
1207
  		    type, sp->handle, fcport->d_id.b.domain,
  		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
  		    logio->entry_status);
  		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1208
  		    (uint8_t *)logio, sizeof(*logio));
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1209

99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
1210
  		goto logio_done;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1211
1212
1213
  	}
  
  	if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1214
  		ql_dbg(ql_dbg_async, vha, 0x5036,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1215
1216
1217
1218
  		    "Async-%s complete - hdl=%x portid=%02x%02x%02x "
  		    "iop0=%x.
  ", type, sp->handle, fcport->d_id.b.domain,
  		    fcport->d_id.b.area, fcport->d_id.b.al_pa,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1219
  		    le32_to_cpu(logio->io_parameter[0]));
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1220
1221
  
  		data[0] = MBS_COMMAND_COMPLETE;
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1222
  		if (ctx->type != SRB_LOGIN_CMD)
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
1223
  			goto logio_done;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1224
1225
1226
1227
1228
  
  		iop[0] = le32_to_cpu(logio->io_parameter[0]);
  		if (iop[0] & BIT_4) {
  			fcport->port_type = FCT_TARGET;
  			if (iop[0] & BIT_8)
8474f3a02   Santosh Vernekar   [SCSI] qla2xxx: C...
1229
  				fcport->flags |= FCF_FCP2_DEVICE;
b0cd579cd   Andrew Vasquez   [SCSI] qla2xxx: M...
1230
  		} else if (iop[0] & BIT_5)
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1231
  			fcport->port_type = FCT_INITIATOR;
b0cd579cd   Andrew Vasquez   [SCSI] qla2xxx: M...
1232

ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1233
1234
1235
1236
  		if (logio->io_parameter[7] || logio->io_parameter[8])
  			fcport->supported_classes |= FC_COS_CLASS2;
  		if (logio->io_parameter[9] || logio->io_parameter[10])
  			fcport->supported_classes |= FC_COS_CLASS3;
99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
1237
  		goto logio_done;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
  	}
  
  	iop[0] = le32_to_cpu(logio->io_parameter[0]);
  	iop[1] = le32_to_cpu(logio->io_parameter[1]);
  	switch (iop[0]) {
  	case LSC_SCODE_PORTID_USED:
  		data[0] = MBS_PORT_ID_USED;
  		data[1] = LSW(iop[1]);
  		break;
  	case LSC_SCODE_NPORT_USED:
  		data[0] = MBS_LOOP_ID_USED;
  		break;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1250
1251
  	default:
  		data[0] = MBS_COMMAND_ERROR;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1252
1253
  		break;
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1254
  	ql_dbg(ql_dbg_async, vha, 0x5037,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1255
1256
1257
  	    "Async-%s failed - hdl=%x portid=%02x%02x%02x comp=%x "
  	    "iop0=%x iop1=%x.
  ", type, sp->handle, fcport->d_id.b.domain,
d3fa9e7d2   Andrew Vasquez   [SCSI] qla2xxx: A...
1258
  	    fcport->d_id.b.area, fcport->d_id.b.al_pa,
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1259
1260
  	    le16_to_cpu(logio->comp_status),
  	    le32_to_cpu(logio->io_parameter[0]),
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1261
  	    le32_to_cpu(logio->io_parameter[1]));
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1262

99b0bec7b   Andrew Vasquez   [SCSI] qla2xxx: F...
1263
  logio_done:
4916392b5   Madhuranath Iyengar   [SCSI] qla2xxx: P...
1264
  	lio->done(sp);
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1265
  }
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
  static void
  qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
      struct tsk_mgmt_entry *tsk)
  {
  	const char func[] = "TMF-IOCB";
  	const char *type;
  	fc_port_t *fcport;
  	srb_t *sp;
  	struct srb_iocb *iocb;
  	struct srb_ctx *ctx;
  	struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
  	int error = 1;
  
  	sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
  	if (!sp)
  		return;
  
  	ctx = sp->ctx;
  	iocb = ctx->u.iocb_cmd;
  	type = ctx->name;
  	fcport = sp->fcport;
  
  	if (sts->entry_status) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1289
  		ql_log(ql_log_warn, vha, 0x5038,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1290
1291
1292
  		    "Async-%s error - hdl=%x entry-status(%x).
  ",
  		    type, sp->handle, sts->entry_status);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1293
  	} else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1294
  		ql_log(ql_log_warn, vha, 0x5039,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1295
1296
1297
  		    "Async-%s error - hdl=%x completion status(%x).
  ",
  		    type, sp->handle, sts->comp_status);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1298
1299
  	} else if (!(le16_to_cpu(sts->scsi_status) &
  	    SS_RESPONSE_INFO_LEN_VALID)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1300
  		ql_log(ql_log_warn, vha, 0x503a,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1301
1302
1303
  		    "Async-%s error - hdl=%x no response info(%x).
  ",
  		    type, sp->handle, sts->scsi_status);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1304
  	} else if (le32_to_cpu(sts->rsp_data_len) < 4) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1305
  		ql_log(ql_log_warn, vha, 0x503b,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1306
1307
1308
  		    "Async-%s error - hdl=%x not enough response(%d).
  ",
  		    type, sp->handle, sts->rsp_data_len);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1309
  	} else if (sts->data[3]) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1310
  		ql_log(ql_log_warn, vha, 0x503c,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1311
1312
1313
  		    "Async-%s error - hdl=%x response(%x).
  ",
  		    type, sp->handle, sts->data[3]);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1314
1315
1316
1317
1318
1319
  	} else {
  		error = 0;
  	}
  
  	if (error) {
  		iocb->u.tmf.data = error;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1320
1321
  		ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x5055,
  		    (uint8_t *)sts, sizeof(*sts));
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1322
1323
1324
1325
  	}
  
  	iocb->done(sp);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1326
1327
1328
1329
1330
  /**
   * qla2x00_process_response_queue() - Process response queue entries.
   * @ha: SCSI driver HA context
   */
  void
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1331
  qla2x00_process_response_queue(struct rsp_que *rsp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1332
  {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1333
1334
  	struct scsi_qla_host *vha;
  	struct qla_hw_data *ha = rsp->hw;
3d71644cf   Andrew Vasquez   [SCSI] qla2xxx: A...
1335
  	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1336
1337
1338
  	sts_entry_t	*pkt;
  	uint16_t        handle_cnt;
  	uint16_t        cnt;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1339

2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1340
  	vha = pci_get_drvdata(ha->pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1341

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1342
  	if (!vha->flags.online)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1343
  		return;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1344
1345
  	while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
  		pkt = (sts_entry_t *)rsp->ring_ptr;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1346

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1347
1348
1349
1350
  		rsp->ring_index++;
  		if (rsp->ring_index == rsp->length) {
  			rsp->ring_index = 0;
  			rsp->ring_ptr = rsp->ring;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1351
  		} else {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1352
  			rsp->ring_ptr++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
1354
1355
  		}
  
  		if (pkt->entry_status != 0) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1356
  			qla2x00_error_entry(vha, rsp, pkt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1357
1358
1359
1360
1361
1362
1363
  			((response_t *)pkt)->signature = RESPONSE_PROCESSED;
  			wmb();
  			continue;
  		}
  
  		switch (pkt->entry_type) {
  		case STATUS_TYPE:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1364
  			qla2x00_status_entry(vha, rsp, pkt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1365
1366
1367
1368
  			break;
  		case STATUS_TYPE_21:
  			handle_cnt = ((sts21_entry_t *)pkt)->handle_count;
  			for (cnt = 0; cnt < handle_cnt; cnt++) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1369
  				qla2x00_process_completed_request(vha, rsp->req,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1370
1371
1372
1373
1374
1375
  				    ((sts21_entry_t *)pkt)->handle[cnt]);
  			}
  			break;
  		case STATUS_TYPE_22:
  			handle_cnt = ((sts22_entry_t *)pkt)->handle_count;
  			for (cnt = 0; cnt < handle_cnt; cnt++) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1376
  				qla2x00_process_completed_request(vha, rsp->req,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1377
1378
1379
1380
  				    ((sts22_entry_t *)pkt)->handle[cnt]);
  			}
  			break;
  		case STATUS_CONT_TYPE:
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1381
  			qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
  			break;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
1383
1384
1385
  		case MBX_IOCB_TYPE:
  			qla2x00_mbx_iocb_entry(vha, rsp->req,
  			    (struct mbx_entry *)pkt);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
1386
  			break;
9bc4f4fb4   Harish Zunjarrao   [SCSI] qla2xxx: A...
1387
1388
1389
  		case CT_IOCB_TYPE:
  			qla2x00_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390
1391
  		default:
  			/* Type Not Supported. */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1392
1393
  			ql_log(ql_log_warn, vha, 0x504a,
  			    "Received unknown response pkt type %x "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1394
1395
  			    "entry status=%x.
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1396
  			    pkt->entry_type, pkt->entry_status);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1397
1398
1399
1400
1401
1402
1403
  			break;
  		}
  		((response_t *)pkt)->signature = RESPONSE_PROCESSED;
  		wmb();
  	}
  
  	/* Adjust ring index */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1404
  	WRT_REG_WORD(ISP_RSP_Q_OUT(ha, reg), rsp->ring_index);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1405
  }
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1406
  static inline void
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1407
1408
  qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t par_sense_len,
      uint32_t sense_len, struct rsp_que *rsp)
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1409
  {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1410
  	struct scsi_qla_host *vha = sp->fcport->vha;
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1411
1412
1413
1414
  	struct scsi_cmnd *cp = sp->cmd;
  
  	if (sense_len >= SCSI_SENSE_BUFFERSIZE)
  		sense_len = SCSI_SENSE_BUFFERSIZE;
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1415
1416
  	sp->request_sense_length = sense_len;
  	sp->request_sense_ptr = cp->sense_buffer;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1417
1418
  	if (sp->request_sense_length > par_sense_len)
  		sense_len = par_sense_len;
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1419
1420
1421
1422
1423
1424
  
  	memcpy(cp->sense_buffer, sense_data, sense_len);
  
  	sp->request_sense_ptr += sense_len;
  	sp->request_sense_length -= sense_len;
  	if (sp->request_sense_length != 0)
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1425
  		rsp->status_srb = sp;
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1426

cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1427
1428
1429
1430
1431
1432
  	if (sense_len) {
  		ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x301c,
  		    "Check condition Sense data, nexus%ld:%d:%d cmd=%p.
  ",
  		    sp->fcport->vha->host_no, cp->device->id, cp->device->lun,
  		    cp);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1433
1434
  		ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302b,
  		    cp->sense_buffer, sense_len);
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1435
  	}
4733fcb1f   Andrew Vasquez   [SCSI] qla2xxx: C...
1436
  }
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
  struct scsi_dif_tuple {
  	__be16 guard;       /* Checksum */
  	__be16 app_tag;         /* APPL identifer */
  	__be32 ref_tag;         /* Target LBA or indirect LBA */
  };
  
  /*
   * Checks the guard or meta-data for the type of error
   * detected by the HBA. In case of errors, we set the
   * ASC/ASCQ fields in the sense buffer with ILLEGAL_REQUEST
   * to indicate to the kernel that the HBA detected error.
   */
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1449
  static inline int
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1450
1451
  qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
  {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1452
  	struct scsi_qla_host *vha = sp->fcport->vha;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1453
  	struct scsi_cmnd *cmd = sp->cmd;
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1454
1455
  	uint8_t		*ap = &sts24->data[12];
  	uint8_t		*ep = &sts24->data[20];
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1456
1457
1458
  	uint32_t	e_ref_tag, a_ref_tag;
  	uint16_t	e_app_tag, a_app_tag;
  	uint16_t	e_guard, a_guard;
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
  	/*
  	 * swab32 of the "data" field in the beginning of qla2x00_status_entry()
  	 * would make guard field appear at offset 2
  	 */
  	a_guard   = le16_to_cpu(*(uint16_t *)(ap + 2));
  	a_app_tag = le16_to_cpu(*(uint16_t *)(ap + 0));
  	a_ref_tag = le32_to_cpu(*(uint32_t *)(ap + 4));
  	e_guard   = le16_to_cpu(*(uint16_t *)(ep + 2));
  	e_app_tag = le16_to_cpu(*(uint16_t *)(ep + 0));
  	e_ref_tag = le32_to_cpu(*(uint32_t *)(ep + 4));
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1469

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1470
1471
1472
  	ql_dbg(ql_dbg_io, vha, 0x3023,
  	    "iocb(s) %p Returned STATUS.
  ", sts24);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1473

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1474
1475
  	ql_dbg(ql_dbg_io, vha, 0x3024,
  	    "DIF ERROR in cmd 0x%x lba 0x%llx act ref"
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1476
  	    " tag=0x%x, exp ref_tag=0x%x, act app tag=0x%x, exp app"
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1477
1478
  	    " tag=0x%x, act guard=0x%x, exp guard=0x%x.
  ",
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1479
  	    cmd->cmnd[0], (u64)scsi_get_lba(cmd), a_ref_tag, e_ref_tag,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1480
  	    a_app_tag, e_app_tag, a_guard, e_guard);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1481

8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
  	/*
  	 * Ignore sector if:
  	 * For type     3: ref & app tag is all 'f's
  	 * For type 0,1,2: app tag is all 'f's
  	 */
  	if ((a_app_tag == 0xffff) &&
  	    ((scsi_get_prot_type(cmd) != SCSI_PROT_DIF_TYPE3) ||
  	     (a_ref_tag == 0xffffffff))) {
  		uint32_t blocks_done, resid;
  		sector_t lba_s = scsi_get_lba(cmd);
  
  		/* 2TB boundary case covered automatically with this */
  		blocks_done = e_ref_tag - (uint32_t)lba_s + 1;
  
  		resid = scsi_bufflen(cmd) - (blocks_done *
  		    cmd->device->sector_size);
  
  		scsi_set_resid(cmd, resid);
  		cmd->result = DID_OK << 16;
  
  		/* Update protection tag */
  		if (scsi_prot_sg_count(cmd)) {
  			uint32_t i, j = 0, k = 0, num_ent;
  			struct scatterlist *sg;
  			struct sd_dif_tuple *spt;
  
  			/* Patch the corresponding protection tags */
  			scsi_for_each_prot_sg(cmd, sg,
  			    scsi_prot_sg_count(cmd), i) {
  				num_ent = sg_dma_len(sg) / 8;
  				if (k + num_ent < blocks_done) {
  					k += num_ent;
  					continue;
  				}
  				j = blocks_done - k - 1;
  				k = blocks_done;
  				break;
  			}
  
  			if (k != blocks_done) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1522
  				ql_log(ql_log_warn, vha, 0x302f,
8ec9c7fb1   Randy Dunlap   scsi: fix qla2xxx...
1523
1524
1525
  				    "unexpected tag values tag:lba=%x:%llx)
  ",
  				    e_ref_tag, (unsigned long long)lba_s);
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
  				return 1;
  			}
  
  			spt = page_address(sg_page(sg)) + sg->offset;
  			spt += j;
  
  			spt->app_tag = 0xffff;
  			if (scsi_get_prot_type(cmd) == SCSI_PROT_DIF_TYPE3)
  				spt->ref_tag = 0xffffffff;
  		}
  
  		return 0;
  	}
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1539
1540
1541
1542
1543
1544
1545
  	/* check guard */
  	if (e_guard != a_guard) {
  		scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
  		    0x10, 0x1);
  		set_driver_byte(cmd, DRIVER_SENSE);
  		set_host_byte(cmd, DID_ABORT);
  		cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1546
  		return 1;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1547
  	}
e02587d77   Arun Easi   [SCSI] qla2xxx: T...
1548
1549
  	/* check ref tag */
  	if (e_ref_tag != a_ref_tag) {
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1550
  		scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
e02587d77   Arun Easi   [SCSI] qla2xxx: T...
1551
  		    0x10, 0x3);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1552
1553
1554
  		set_driver_byte(cmd, DRIVER_SENSE);
  		set_host_byte(cmd, DID_ABORT);
  		cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1555
  		return 1;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1556
  	}
e02587d77   Arun Easi   [SCSI] qla2xxx: T...
1557
1558
  	/* check appl tag */
  	if (e_app_tag != a_app_tag) {
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1559
  		scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
e02587d77   Arun Easi   [SCSI] qla2xxx: T...
1560
  		    0x10, 0x2);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1561
1562
1563
  		set_driver_byte(cmd, DRIVER_SENSE);
  		set_host_byte(cmd, DID_ABORT);
  		cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1564
  		return 1;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1565
  	}
e02587d77   Arun Easi   [SCSI] qla2xxx: T...
1566

8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1567
  	return 1;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1568
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1569
1570
1571
1572
1573
1574
  /**
   * qla2x00_status_entry() - Process a Status IOCB entry.
   * @ha: SCSI driver HA context
   * @pkt: Entry pointer
   */
  static void
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1575
  qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1576
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
  	srb_t		*sp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1578
1579
  	fc_port_t	*fcport;
  	struct scsi_cmnd *cp;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1580
1581
  	sts_entry_t *sts;
  	struct sts_entry_24xx *sts24;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1582
1583
  	uint16_t	comp_status;
  	uint16_t	scsi_status;
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1584
  	uint16_t	ox_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1585
1586
  	uint8_t		lscsi_status;
  	int32_t		resid;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1587
1588
  	uint32_t sense_len, par_sense_len, rsp_info_len, resid_len,
  	    fw_resid_len;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1589
  	uint8_t		*rsp_info, *sense_data;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1590
  	struct qla_hw_data *ha = vha->hw;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1591
1592
1593
  	uint32_t handle;
  	uint16_t que;
  	struct req_que *req;
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1594
  	int logit = 1;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1595
1596
1597
  
  	sts = (sts_entry_t *) pkt;
  	sts24 = (struct sts_entry_24xx *) pkt;
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
1598
  	if (IS_FWI2_CAPABLE(ha)) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1599
1600
1601
1602
1603
1604
  		comp_status = le16_to_cpu(sts24->comp_status);
  		scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
  	} else {
  		comp_status = le16_to_cpu(sts->comp_status);
  		scsi_status = le16_to_cpu(sts->scsi_status) & SS_MASK;
  	}
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1605
1606
1607
  	handle = (uint32_t) LSW(sts->handle);
  	que = MSW(sts->handle);
  	req = ha->req_q_map[que];
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1608

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1609
  	/* Fast path completion. */
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1610
  	if (comp_status == CS_COMPLETE && scsi_status == 0) {
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1611
  		qla2x00_process_completed_request(vha, req, handle);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612
1613
1614
1615
1616
  
  		return;
  	}
  
  	/* Validate handle. */
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1617
1618
1619
  	if (handle < MAX_OUTSTANDING_COMMANDS) {
  		sp = req->outstanding_cmds[handle];
  		req->outstanding_cmds[handle] = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1620
1621
1622
1623
  	} else
  		sp = NULL;
  
  	if (sp == NULL) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1624
  		ql_dbg(ql_dbg_io, vha, 0x3017,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1625
1626
  		    "Invalid status handle (0x%x).
  ", sts->handle);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1627

8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
1628
1629
1630
1631
  		if (IS_QLA82XX(ha))
  			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
  		else
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1632
  		qla2xxx_wake_dpc(vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1633
1634
1635
1636
  		return;
  	}
  	cp = sp->cmd;
  	if (cp == NULL) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1637
  		ql_dbg(ql_dbg_io, vha, 0x3018,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1638
1639
1640
  		    "Command already returned (0x%x/%p).
  ",
  		    sts->handle, sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1641
1642
1643
  
  		return;
  	}
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1644
    	lscsi_status = scsi_status & STATUS_MASK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1645

bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
1646
  	fcport = sp->fcport;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1647

b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1648
  	ox_id = 0;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1649
1650
  	sense_len = par_sense_len = rsp_info_len = resid_len =
  	    fw_resid_len = 0;
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
1651
  	if (IS_FWI2_CAPABLE(ha)) {
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1652
1653
1654
1655
1656
1657
1658
1659
  		if (scsi_status & SS_SENSE_LEN_VALID)
  			sense_len = le32_to_cpu(sts24->sense_len);
  		if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
  			rsp_info_len = le32_to_cpu(sts24->rsp_data_len);
  		if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER))
  			resid_len = le32_to_cpu(sts24->rsp_residual_count);
  		if (comp_status == CS_DATA_UNDERRUN)
  			fw_resid_len = le32_to_cpu(sts24->residual_len);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1660
1661
1662
  		rsp_info = sts24->data;
  		sense_data = sts24->data;
  		host_to_fcp_swap(sts24->data, sizeof(sts24->data));
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1663
  		ox_id = le16_to_cpu(sts24->ox_id);
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1664
  		par_sense_len = sizeof(sts24->data);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1665
  	} else {
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1666
1667
1668
1669
  		if (scsi_status & SS_SENSE_LEN_VALID)
  			sense_len = le16_to_cpu(sts->req_sense_length);
  		if (scsi_status & SS_RESPONSE_INFO_LEN_VALID)
  			rsp_info_len = le16_to_cpu(sts->rsp_info_len);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1670
1671
1672
  		resid_len = le32_to_cpu(sts->residual_length);
  		rsp_info = sts->rsp_info;
  		sense_data = sts->req_sense_data;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1673
  		par_sense_len = sizeof(sts->req_sense_data);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1674
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1675
1676
  	/* Check for any FCP transport errors. */
  	if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1677
  		/* Sense data lies beyond any FCP RESPONSE data. */
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1678
  		if (IS_FWI2_CAPABLE(ha)) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1679
  			sense_data += rsp_info_len;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1680
1681
  			par_sense_len -= rsp_info_len;
  		}
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1682
  		if (rsp_info_len > 3 && rsp_info[3]) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1683
  			ql_dbg(ql_dbg_io, vha, 0x3019,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1684
1685
1686
  			    "FCP I/O protocol failure (0x%x/0x%x).
  ",
  			    rsp_info_len, rsp_info[3]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
1688
  
  			cp->result = DID_BUS_BUSY << 16;
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1689
  			goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1690
1691
  		}
  	}
3e8ce320c   Andrew Vasquez   [SCSI] qla2xxx: C...
1692
1693
1694
1695
  	/* Check for overrun. */
  	if (IS_FWI2_CAPABLE(ha) && comp_status == CS_COMPLETE &&
  	    scsi_status & SS_RESIDUAL_OVER)
  		comp_status = CS_DATA_OVERRUN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1696
1697
1698
1699
1700
  	/*
  	 * Based on Host and scsi status generate status code for Linux
  	 */
  	switch (comp_status) {
  	case CS_COMPLETE:
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
1701
  	case CS_QUEUE_FULL:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1702
1703
1704
1705
1706
  		if (scsi_status == 0) {
  			cp->result = DID_OK << 16;
  			break;
  		}
  		if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1707
  			resid = resid_len;
385d70b4e   FUJITA Tomonori   [SCSI] qla2xxx: c...
1708
  			scsi_set_resid(cp, resid);
0da69df1e   Andrew Vasquez   [SCSI] qla2xxx: C...
1709
1710
  
  			if (!lscsi_status &&
385d70b4e   FUJITA Tomonori   [SCSI] qla2xxx: c...
1711
  			    ((unsigned)(scsi_bufflen(cp) - resid) <
0da69df1e   Andrew Vasquez   [SCSI] qla2xxx: C...
1712
  			     cp->underflow)) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1713
  				ql_dbg(ql_dbg_io, vha, 0x301a,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1714
  				    "Mid-layer underflow "
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1715
1716
  				    "detected (0x%x of 0x%x bytes).
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1717
  				    resid, scsi_bufflen(cp));
0da69df1e   Andrew Vasquez   [SCSI] qla2xxx: C...
1718
1719
1720
1721
  
  				cp->result = DID_ERROR << 16;
  				break;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1722
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1723
  		cp->result = DID_OK << 16 | lscsi_status;
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
1724
  		if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1725
  			ql_dbg(ql_dbg_io, vha, 0x301b,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1726
1727
  			    "QUEUE FULL detected.
  ");
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
1728
1729
  			break;
  		}
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1730
  		logit = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1731
1732
  		if (lscsi_status != SS_CHECK_CONDITION)
  			break;
b80ca4f7e   FUJITA Tomonori   [SCSI] replace si...
1733
  		memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1734
1735
  		if (!(scsi_status & SS_SENSE_LEN_VALID))
  			break;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1736
1737
  		qla2x00_handle_sense(sp, sense_data, par_sense_len, sense_len,
  		    rsp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1738
1739
1740
  		break;
  
  	case CS_DATA_UNDERRUN:
ed17c71b5   Ravi Anand   [SCSI] qla2xxx: U...
1741
  		/* Use F/W calculated residual length. */
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1742
1743
1744
1745
  		resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len;
  		scsi_set_resid(cp, resid);
  		if (scsi_status & SS_RESIDUAL_UNDER) {
  			if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1746
  				ql_dbg(ql_dbg_io, vha, 0x301d,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1747
1748
1749
1750
  				    "Dropped frame(s) detected "
  				    "(0x%x of 0x%x bytes).
  ",
  				    resid, scsi_bufflen(cp));
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1751
1752
  
  				cp->result = DID_ERROR << 16 | lscsi_status;
4e85e3d92   Arun Easi   [SCSI] qla2xxx: C...
1753
  				goto check_scsi_status;
6acf81900   Andrew Vasquez   [SCSI] qla2xxx: C...
1754
  			}
ed17c71b5   Ravi Anand   [SCSI] qla2xxx: U...
1755

0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1756
1757
1758
  			if (!lscsi_status &&
  			    ((unsigned)(scsi_bufflen(cp) - resid) <
  			    cp->underflow)) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1759
  				ql_dbg(ql_dbg_io, vha, 0x301e,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1760
  				    "Mid-layer underflow "
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1761
1762
  				    "detected (0x%x of 0x%x bytes).
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1763
  				    resid, scsi_bufflen(cp));
e038a1be2   Andrew Vasquez   [SCSI] qla2xxx: D...
1764

0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1765
1766
1767
  				cp->result = DID_ERROR << 16;
  				break;
  			}
0374f55ed   Lalit Chandivade   [SCSI] qla2xxx: C...
1768
  		} else {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1769
  			ql_dbg(ql_dbg_io, vha, 0x301f,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1770
1771
1772
  			    "Dropped frame(s) detected (0x%x "
  			    "of 0x%x bytes).
  ", resid, scsi_bufflen(cp));
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1773

0374f55ed   Lalit Chandivade   [SCSI] qla2xxx: C...
1774
1775
  			cp->result = DID_ERROR << 16 | lscsi_status;
  			goto check_scsi_status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1776
  		}
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1777
  		cp->result = DID_OK << 16 | lscsi_status;
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1778
  		logit = 0;
0f00a206c   Lalit Chandivade   [SCSI] qla2xxx: P...
1779

0374f55ed   Lalit Chandivade   [SCSI] qla2xxx: C...
1780
  check_scsi_status:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1781
  		/*
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
1782
  		 * Check to see if SCSI Status is non zero. If so report SCSI
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783
1784
1785
  		 * Status.
  		 */
  		if (lscsi_status != 0) {
ffec28a3e   Andrew Vasquez   [SCSI] qla2xxx: E...
1786
  			if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1787
  				ql_dbg(ql_dbg_io, vha, 0x3020,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1788
1789
  				    "QUEUE FULL detected.
  ");
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1790
  				logit = 1;
ffec28a3e   Andrew Vasquez   [SCSI] qla2xxx: E...
1791
1792
  				break;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1793
1794
  			if (lscsi_status != SS_CHECK_CONDITION)
  				break;
b80ca4f7e   FUJITA Tomonori   [SCSI] replace si...
1795
  			memset(cp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1796
1797
  			if (!(scsi_status & SS_SENSE_LEN_VALID))
  				break;
5544213be   Andrew Vasquez   [SCSI] qla2xxx: C...
1798
1799
  			qla2x00_handle_sense(sp, sense_data, par_sense_len,
  			    sense_len, rsp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1800
1801
  		}
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1802
1803
1804
1805
1806
  	case CS_PORT_LOGGED_OUT:
  	case CS_PORT_CONFIG_CHG:
  	case CS_PORT_BUSY:
  	case CS_INCOMPLETE:
  	case CS_PORT_UNAVAILABLE:
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1807
  	case CS_TIMEOUT:
ff454b01b   Chad Dupuis   [SCSI] qla2xxx: G...
1808
  	case CS_RESET:
056a44834   Mike Christie   [SCSI] qla2xxx: u...
1809
1810
1811
1812
1813
1814
  		/*
  		 * We are going to have the fc class block the rport
  		 * while we try to recover so instruct the mid layer
  		 * to requeue until the class decides how to handle this.
  		 */
  		cp->result = DID_TRANSPORT_DISRUPTED << 16;
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1815
1816
1817
1818
1819
1820
1821
1822
  
  		if (comp_status == CS_TIMEOUT) {
  			if (IS_FWI2_CAPABLE(ha))
  				break;
  			else if ((le16_to_cpu(sts->status_flags) &
  			    SF_LOGOUT_SENT) == 0)
  				break;
  		}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1823
1824
1825
1826
  		ql_dbg(ql_dbg_io, vha, 0x3021,
  		    "Port down status: port-state=0x%x.
  ",
  		    atomic_read(&fcport->state));
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1827

a7a28504b   Andrew Vasquez   [SCSI] qla2xxx: C...
1828
  		if (atomic_read(&fcport->state) == FCS_ONLINE)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1829
  			qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1830
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1831
  	case CS_ABORTED:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1832
1833
  		cp->result = DID_RESET << 16;
  		break;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1834
1835
  
  	case CS_DIF_ERROR:
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
1836
  		logit = qla2x00_handle_dif_error(sp, sts24);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1837
  		break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1838
  	default:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1839
1840
1841
  		cp->result = DID_ERROR << 16;
  		break;
  	}
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1842
1843
  out:
  	if (logit)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1844
1845
  		ql_dbg(ql_dbg_io, vha, 0x3022,
  		    "FCP command status: 0x%x-0x%x (0x%x) "
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1846
1847
  		    "nexus=%ld:%d:%d portid=%02x%02x%02x oxid=0x%x "
  		    "cdb=%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x len=0x%x "
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1848
1849
  		    "rsp_info=0x%x resid=0x%x fw_resid=0x%x.
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1850
1851
1852
1853
1854
1855
  		    comp_status, scsi_status, cp->result, vha->host_no,
  		    cp->device->id, cp->device->lun, fcport->d_id.b.domain,
  		    fcport->d_id.b.area, fcport->d_id.b.al_pa, ox_id,
  		    cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
  		    cp->cmnd[4], cp->cmnd[5], cp->cmnd[6], cp->cmnd[7],
  		    cp->cmnd[8], cp->cmnd[9], scsi_bufflen(cp), rsp_info_len,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1856
  		    resid_len, fw_resid_len);
b7d2280c1   Andrew Vasquez   [SCSI] qla2xxx: C...
1857

2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1858
  	if (rsp->status_srb == NULL)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1859
  		qla2x00_sp_compl(ha, sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
  }
  
  /**
   * qla2x00_status_cont_entry() - Process a Status Continuations entry.
   * @ha: SCSI driver HA context
   * @pkt: Entry pointer
   *
   * Extended sense data.
   */
  static void
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1870
  qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1871
1872
  {
  	uint8_t		sense_sz = 0;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1873
  	struct qla_hw_data *ha = rsp->hw;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1874
  	struct scsi_qla_host *vha = pci_get_drvdata(ha->pdev);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1875
  	srb_t		*sp = rsp->status_srb;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1876
1877
1878
1879
1880
  	struct scsi_cmnd *cp;
  
  	if (sp != NULL && sp->request_sense_length != 0) {
  		cp = sp->cmd;
  		if (cp == NULL) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1881
1882
1883
  			ql_log(ql_log_warn, vha, 0x3025,
  			    "cmd is NULL: already returned to OS (sp=%p).
  ",
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
1884
  			    sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1885

2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1886
  			rsp->status_srb = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
  			return;
  		}
  
  		if (sp->request_sense_length > sizeof(pkt->data)) {
  			sense_sz = sizeof(pkt->data);
  		} else {
  			sense_sz = sp->request_sense_length;
  		}
  
  		/* Move sense data. */
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
1897
  		if (IS_FWI2_CAPABLE(ha))
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
1898
  			host_to_fcp_swap(pkt->data, sizeof(pkt->data));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1899
  		memcpy(sp->request_sense_ptr, pkt->data, sense_sz);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1900
1901
  		ql_dump_buffer(ql_dbg_io + ql_dbg_buffer, vha, 0x302c,
  			sp->request_sense_ptr, sense_sz);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1902
1903
1904
1905
1906
1907
  
  		sp->request_sense_ptr += sense_sz;
  		sp->request_sense_length -= sense_sz;
  
  		/* Place command on done queue. */
  		if (sp->request_sense_length == 0) {
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1908
  			rsp->status_srb = NULL;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1909
  			qla2x00_sp_compl(ha, sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1910
1911
1912
  		}
  	}
  }
c4631191c   Giridhar Malavali   [SCSI] qla2xxx: P...
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
  static int
  qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp)
  {
  	struct qla_hw_data *ha = vha->hw;
  	struct srb_ctx *ctx;
  
  	if (!sp->ctx)
  		return 1;
  
  	ctx = sp->ctx;
  
  	if (ctx->type == SRB_LOGIN_CMD ||
  	    ctx->type == SRB_LOGOUT_CMD ||
  	    ctx->type == SRB_TM_CMD) {
  		ctx->u.iocb_cmd->done(sp);
  		return 0;
  	} else if (ctx->type == SRB_ADISC_CMD) {
  		ctx->u.iocb_cmd->free(sp);
  		return 0;
  	} else {
  		struct fc_bsg_job *bsg_job;
  
  		bsg_job = ctx->u.bsg_job;
  		if (ctx->type == SRB_ELS_CMD_HST ||
  		    ctx->type == SRB_CT_CMD)
  			kfree(sp->fcport);
  
  		bsg_job->reply->reply_data.ctels_reply.status =
  		    FC_CTELS_STATUS_OK;
  		bsg_job->reply->result = DID_ERROR << 16;
  		bsg_job->reply->reply_payload_rcv_len = 0;
  		kfree(sp->ctx);
  		mempool_free(sp, ha->srb_mempool);
  		bsg_job->job_done(bsg_job);
  		return 0;
  	}
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1951
1952
1953
1954
1955
1956
  /**
   * qla2x00_error_entry() - Process an error entry.
   * @ha: SCSI driver HA context
   * @pkt: Entry pointer
   */
  static void
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1957
  qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1958
1959
  {
  	srb_t *sp;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1960
  	struct qla_hw_data *ha = vha->hw;
c4631191c   Giridhar Malavali   [SCSI] qla2xxx: P...
1961
  	const char func[] = "ERROR-IOCB";
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1962
1963
  	uint16_t que = MSW(pkt->handle);
  	struct req_que *req = ha->req_q_map[que];
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1964

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1965
  	if (pkt->entry_status & RF_INV_E_ORDER)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1966
1967
1968
  		ql_dbg(ql_dbg_async, vha, 0x502a,
  		    "Invalid Entry Order.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1969
  	else if (pkt->entry_status & RF_INV_E_COUNT)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1970
1971
1972
  		ql_dbg(ql_dbg_async, vha, 0x502b,
  		    "Invalid Entry Count.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
  	else if (pkt->entry_status & RF_INV_E_PARAM)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1974
1975
1976
  		ql_dbg(ql_dbg_async, vha, 0x502c,
  		    "Invalid Entry Parameter.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1977
  	else if (pkt->entry_status & RF_INV_E_TYPE)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1978
1979
1980
  		ql_dbg(ql_dbg_async, vha, 0x502d,
  		    "Invalid Entry Type.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1981
  	else if (pkt->entry_status & RF_BUSY)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1982
1983
1984
  		ql_dbg(ql_dbg_async, vha, 0x502e,
  		    "Busy.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1985
  	else
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1986
1987
1988
  		ql_dbg(ql_dbg_async, vha, 0x502f,
  		    "UNKNOWN flag error.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1989

c4631191c   Giridhar Malavali   [SCSI] qla2xxx: P...
1990
  	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1991
  	if (sp) {
c4631191c   Giridhar Malavali   [SCSI] qla2xxx: P...
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
  		if (qla2x00_free_sp_ctx(vha, sp)) {
  			if (pkt->entry_status &
  			    (RF_INV_E_ORDER | RF_INV_E_COUNT |
  			     RF_INV_E_PARAM | RF_INV_E_TYPE)) {
  				sp->cmd->result = DID_ERROR << 16;
  			} else if (pkt->entry_status & RF_BUSY) {
  				sp->cmd->result = DID_BUS_BUSY << 16;
  			} else {
  				sp->cmd->result = DID_ERROR << 16;
  			}
  			qla2x00_sp_compl(ha, sp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2003
  		}
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2004
  	} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
2005
2006
  		COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
  		|| pkt->entry_type == COMMAND_TYPE_6) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2007
2008
2009
  		ql_log(ql_log_warn, vha, 0x5030,
  		    "Error entry - invalid handle.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2010

8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
2011
2012
2013
2014
  		if (IS_QLA82XX(ha))
  			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
  		else
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2015
  		qla2xxx_wake_dpc(vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2016
2017
2018
2019
  	}
  }
  
  /**
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2020
2021
2022
2023
2024
   * qla24xx_mbx_completion() - Process mailbox command completions.
   * @ha: SCSI driver HA context
   * @mb0: Mailbox0 register
   */
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2025
  qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2026
2027
  {
  	uint16_t	cnt;
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
2028
  	uint32_t	mboxes;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2029
  	uint16_t __iomem *wptr;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2030
  	struct qla_hw_data *ha = vha->hw;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2031
  	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
2032
2033
2034
2035
2036
2037
2038
  	/* Read all mbox registers? */
  	mboxes = (1 << ha->mbx_count) - 1;
  	if (!ha->mcp)
  		ql_dbg(ql_dbg_async, vha, 0x504e, "MBX pointer ERRROR.
  ");
  	else
  		mboxes = ha->mcp->in_mb;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2039
2040
2041
  	/* Load return mailbox registers. */
  	ha->flags.mbox_int = 1;
  	ha->mailbox_out[0] = mb0;
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
2042
  	mboxes >>= 1;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2043
2044
2045
  	wptr = (uint16_t __iomem *)&reg->mailbox1;
  
  	for (cnt = 1; cnt < ha->mbx_count; cnt++) {
4fa94f83f   Andrew Vasquez   [SCSI] qla2xxx: O...
2046
2047
2048
2049
  		if (mboxes & BIT_0)
  			ha->mailbox_out[cnt] = RD_REG_WORD(wptr);
  
  		mboxes >>= 1;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2050
2051
  		wptr++;
  	}
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2052
2053
2054
2055
2056
2057
  }
  
  /**
   * qla24xx_process_response_queue() - Process response queue entries.
   * @ha: SCSI driver HA context
   */
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2058
2059
  void qla24xx_process_response_queue(struct scsi_qla_host *vha,
  	struct rsp_que *rsp)
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2060
  {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2061
  	struct sts_entry_24xx *pkt;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2062
  	struct qla_hw_data *ha = vha->hw;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2063

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2064
  	if (!vha->flags.online)
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2065
  		return;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2066
2067
  	while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) {
  		pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2068

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2069
2070
2071
2072
  		rsp->ring_index++;
  		if (rsp->ring_index == rsp->length) {
  			rsp->ring_index = 0;
  			rsp->ring_ptr = rsp->ring;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2073
  		} else {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2074
  			rsp->ring_ptr++;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2075
2076
2077
  		}
  
  		if (pkt->entry_status != 0) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2078
  			qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2079
2080
2081
2082
2083
2084
2085
  			((response_t *)pkt)->signature = RESPONSE_PROCESSED;
  			wmb();
  			continue;
  		}
  
  		switch (pkt->entry_type) {
  		case STATUS_TYPE:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2086
  			qla2x00_status_entry(vha, rsp, pkt);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2087
2088
  			break;
  		case STATUS_CONT_TYPE:
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2089
  			qla2x00_status_cont_entry(rsp, (sts_cont_entry_t *)pkt);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2090
  			break;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
2091
  		case VP_RPT_ID_IOCB_TYPE:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2092
  			qla24xx_report_id_acquisition(vha,
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
2093
2094
  			    (struct vp_rpt_id_entry_24xx *)pkt);
  			break;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
2095
2096
2097
2098
  		case LOGINOUT_PORT_IOCB_TYPE:
  			qla24xx_logio_entry(vha, rsp->req,
  			    (struct logio_entry_24xx *)pkt);
  			break;
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
2099
2100
2101
2102
  		case TSK_MGMT_IOCB_TYPE:
  			qla24xx_tm_iocb_entry(vha, rsp->req,
  			    (struct tsk_mgmt_entry *)pkt);
  			break;
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
2103
2104
2105
2106
2107
2108
2109
                  case CT_IOCB_TYPE:
  			qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
  			clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
  			break;
                  case ELS_IOCB_TYPE:
  			qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
  			break;
54883291f   Saurav Kashyap   [SCSI] qla2xxx: c...
2110
2111
2112
2113
2114
  		case MARKER_TYPE:
  			/* Do nothing in this case, this check is to prevent it
  			 * from falling into default case
  			 */
  			break;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2115
2116
  		default:
  			/* Type Not Supported. */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2117
2118
  			ql_dbg(ql_dbg_async, vha, 0x5042,
  			    "Received unknown response pkt type %x "
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2119
2120
  			    "entry status=%x.
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2121
  			    pkt->entry_type, pkt->entry_status);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2122
2123
2124
2125
2126
2127
2128
  			break;
  		}
  		((response_t *)pkt)->signature = RESPONSE_PROCESSED;
  		wmb();
  	}
  
  	/* Adjust ring index */
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2129
2130
2131
2132
2133
  	if (IS_QLA82XX(ha)) {
  		struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
  		WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index);
  	} else
  		WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2134
  }
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2135
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2136
  qla2xxx_check_risc_status(scsi_qla_host_t *vha)
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2137
2138
2139
  {
  	int rval;
  	uint32_t cnt;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2140
  	struct qla_hw_data *ha = vha->hw;
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2141
  	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2142
  	if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha))
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
  		return;
  
  	rval = QLA_SUCCESS;
  	WRT_REG_DWORD(&reg->iobase_addr, 0x7C00);
  	RD_REG_DWORD(&reg->iobase_addr);
  	WRT_REG_DWORD(&reg->iobase_window, 0x0001);
  	for (cnt = 10000; (RD_REG_DWORD(&reg->iobase_window) & BIT_0) == 0 &&
  	    rval == QLA_SUCCESS; cnt--) {
  		if (cnt) {
  			WRT_REG_DWORD(&reg->iobase_window, 0x0001);
  			udelay(10);
  		} else
  			rval = QLA_FUNCTION_TIMEOUT;
  	}
  	if (rval == QLA_SUCCESS)
  		goto next_test;
  
  	WRT_REG_DWORD(&reg->iobase_window, 0x0003);
  	for (cnt = 100; (RD_REG_DWORD(&reg->iobase_window) & BIT_0) == 0 &&
  	    rval == QLA_SUCCESS; cnt--) {
  		if (cnt) {
  			WRT_REG_DWORD(&reg->iobase_window, 0x0003);
  			udelay(10);
  		} else
  			rval = QLA_FUNCTION_TIMEOUT;
  	}
  	if (rval != QLA_SUCCESS)
  		goto done;
  
  next_test:
  	if (RD_REG_DWORD(&reg->iobase_c8) & BIT_3)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2174
2175
2176
  		ql_log(ql_log_info, vha, 0x504c,
  		    "Additional code -- 0x55AA.
  ");
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2177
2178
2179
2180
2181
  
  done:
  	WRT_REG_DWORD(&reg->iobase_window, 0x0000);
  	RD_REG_DWORD(&reg->iobase_window);
  }
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2182
2183
2184
2185
  /**
   * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx.
   * @irq:
   * @dev_id: SCSI driver HA context
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2186
2187
2188
2189
2190
2191
   *
   * Called by system whenever the host adapter generates an interrupt.
   *
   * Returns handled flag.
   */
  irqreturn_t
7d12e780e   David Howells   IRQ: Maintain reg...
2192
  qla24xx_intr_handler(int irq, void *dev_id)
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2193
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2194
2195
  	scsi_qla_host_t	*vha;
  	struct qla_hw_data *ha;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2196
2197
  	struct device_reg_24xx __iomem *reg;
  	int		status;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2198
2199
2200
2201
  	unsigned long	iter;
  	uint32_t	stat;
  	uint32_t	hccr;
  	uint16_t	mb[4];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2202
  	struct rsp_que *rsp;
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
2203
  	unsigned long	flags;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2204

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2205
2206
  	rsp = (struct rsp_que *) dev_id;
  	if (!rsp) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2207
  		printk(KERN_INFO
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2208
2209
  		    "%s(): NULL response queue pointer.
  ", __func__);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2210
2211
  		return IRQ_NONE;
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2212
  	ha = rsp->hw;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2213
2214
  	reg = &ha->iobase->isp24;
  	status = 0;
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
2215
2216
  	if (unlikely(pci_channel_offline(ha->pdev)))
  		return IRQ_HANDLED;
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
2217
  	spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2218
  	vha = pci_get_drvdata(ha->pdev);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2219
2220
2221
  	for (iter = 50; iter--; ) {
  		stat = RD_REG_DWORD(&reg->host_status);
  		if (stat & HSRX_RISC_PAUSED) {
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
2222
  			if (unlikely(pci_channel_offline(ha->pdev)))
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
2223
  				break;
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2224
  			hccr = RD_REG_DWORD(&reg->hccr);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2225
2226
2227
2228
  			ql_log(ql_log_warn, vha, 0x504b,
  			    "RISC paused -- HCCR=%x, Dumping firmware.
  ",
  			    hccr);
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2229

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2230
  			qla2xxx_check_risc_status(vha);
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2231

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2232
2233
  			ha->isp_ops->fw_dump(vha, 1);
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2234
2235
2236
2237
2238
2239
2240
2241
2242
  			break;
  		} else if ((stat & HSRX_RISC_INT) == 0)
  			break;
  
  		switch (stat & 0xff) {
  		case 0x1:
  		case 0x2:
  		case 0x10:
  		case 0x11:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2243
  			qla24xx_mbx_completion(vha, MSW(stat));
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2244
2245
2246
2247
2248
2249
2250
2251
  			status |= MBX_INTERRUPT;
  
  			break;
  		case 0x12:
  			mb[0] = MSW(stat);
  			mb[1] = RD_REG_WORD(&reg->mailbox1);
  			mb[2] = RD_REG_WORD(&reg->mailbox2);
  			mb[3] = RD_REG_WORD(&reg->mailbox3);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2252
  			qla2x00_async_event(vha, rsp, mb);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2253
2254
  			break;
  		case 0x13:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2255
  		case 0x14:
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2256
  			qla24xx_process_response_queue(vha, rsp);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2257
2258
  			break;
  		default:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2259
2260
2261
  			ql_dbg(ql_dbg_async, vha, 0x504f,
  			    "Unrecognized interrupt type (%d).
  ", stat * 0xff);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2262
2263
2264
2265
2266
  			break;
  		}
  		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
  		RD_REG_DWORD_RELAXED(&reg->hccr);
  	}
43fac4d97   Anirban Chakraborty   [SCSI] qla2xxx: R...
2267
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2268
2269
2270
  
  	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
  	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2271
  		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0d   Marcus Barrow   [SCSI] qla2xxx: U...
2272
  		complete(&ha->mbx_intr_comp);
9a853f718   Andrew Vasquez   [SCSI] qla2xxx: A...
2273
2274
2275
2276
  	}
  
  	return IRQ_HANDLED;
  }
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2277
2278
2279
  static irqreturn_t
  qla24xx_msix_rsp_q(int irq, void *dev_id)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2280
2281
  	struct qla_hw_data *ha;
  	struct rsp_que *rsp;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2282
  	struct device_reg_24xx __iomem *reg;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2283
  	struct scsi_qla_host *vha;
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2284
  	unsigned long flags;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2285

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2286
2287
2288
  	rsp = (struct rsp_que *) dev_id;
  	if (!rsp) {
  		printk(KERN_INFO
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2289
2290
  		"%s(): NULL response queue pointer.
  ", __func__);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2291
2292
2293
  		return IRQ_NONE;
  	}
  	ha = rsp->hw;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2294
  	reg = &ha->iobase->isp24;
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2295
  	spin_lock_irqsave(&ha->hardware_lock, flags);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2296

a67093d46   Anirban Chakraborty   [SCSI] qla2xxx: O...
2297
  	vha = pci_get_drvdata(ha->pdev);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2298
  	qla24xx_process_response_queue(vha, rsp);
3155754a6   Anirban Chakraborty   [SCSI] qla2xxx: f...
2299
  	if (!ha->flags.disable_msix_handshake) {
eb94114bf   Anirban Chakraborty   [SCSI] qla2xxx: F...
2300
2301
2302
  		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
  		RD_REG_DWORD_RELAXED(&reg->hccr);
  	}
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2303
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2304
2305
2306
2307
2308
  
  	return IRQ_HANDLED;
  }
  
  static irqreturn_t
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2309
2310
2311
2312
  qla25xx_msix_rsp_q(int irq, void *dev_id)
  {
  	struct qla_hw_data *ha;
  	struct rsp_que *rsp;
3155754a6   Anirban Chakraborty   [SCSI] qla2xxx: f...
2313
  	struct device_reg_24xx __iomem *reg;
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2314
  	unsigned long flags;
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2315
2316
2317
2318
  
  	rsp = (struct rsp_que *) dev_id;
  	if (!rsp) {
  		printk(KERN_INFO
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2319
2320
  			"%s(): NULL response queue pointer.
  ", __func__);
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2321
2322
2323
  		return IRQ_NONE;
  	}
  	ha = rsp->hw;
3155754a6   Anirban Chakraborty   [SCSI] qla2xxx: f...
2324
  	/* Clear the interrupt, if enabled, for this response queue */
d424754cb   Andrew Vasquez   [SCSI] qla2xxx: C...
2325
  	if (!ha->flags.disable_msix_handshake) {
3155754a6   Anirban Chakraborty   [SCSI] qla2xxx: f...
2326
  		reg = &ha->iobase->isp24;
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2327
  		spin_lock_irqsave(&ha->hardware_lock, flags);
3155754a6   Anirban Chakraborty   [SCSI] qla2xxx: f...
2328
2329
  		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
  		RD_REG_DWORD_RELAXED(&reg->hccr);
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2330
  		spin_unlock_irqrestore(&ha->hardware_lock, flags);
3155754a6   Anirban Chakraborty   [SCSI] qla2xxx: f...
2331
  	}
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2332
2333
2334
2335
2336
2337
  	queue_work_on((int) (rsp->id - 1), ha->wq, &rsp->q_work);
  
  	return IRQ_HANDLED;
  }
  
  static irqreturn_t
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2338
2339
  qla24xx_msix_default(int irq, void *dev_id)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2340
2341
2342
  	scsi_qla_host_t	*vha;
  	struct qla_hw_data *ha;
  	struct rsp_que *rsp;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2343
2344
  	struct device_reg_24xx __iomem *reg;
  	int		status;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2345
2346
2347
  	uint32_t	stat;
  	uint32_t	hccr;
  	uint16_t	mb[4];
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2348
  	unsigned long flags;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2349

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2350
2351
  	rsp = (struct rsp_que *) dev_id;
  	if (!rsp) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2352
2353
2354
  		printk(KERN_INFO
  			"%s(): NULL response queue pointer.
  ", __func__);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2355
2356
2357
  		return IRQ_NONE;
  	}
  	ha = rsp->hw;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2358
2359
  	reg = &ha->iobase->isp24;
  	status = 0;
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2360
  	spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2361
  	vha = pci_get_drvdata(ha->pdev);
87f27015b   Andrew Vasquez   [SCSI] qla2xxx: R...
2362
  	do {
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2363
2364
  		stat = RD_REG_DWORD(&reg->host_status);
  		if (stat & HSRX_RISC_PAUSED) {
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
2365
  			if (unlikely(pci_channel_offline(ha->pdev)))
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
2366
  				break;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2367
  			hccr = RD_REG_DWORD(&reg->hccr);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2368
2369
2370
2371
  			ql_log(ql_log_info, vha, 0x5050,
  			    "RISC paused -- HCCR=%x, Dumping firmware.
  ",
  			    hccr);
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2372

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2373
  			qla2xxx_check_risc_status(vha);
05236a050   Andrew Vasquez   [SCSI] qla2xxx: Q...
2374

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2375
2376
  			ha->isp_ops->fw_dump(vha, 1);
  			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2377
2378
2379
2380
2381
2382
2383
2384
2385
  			break;
  		} else if ((stat & HSRX_RISC_INT) == 0)
  			break;
  
  		switch (stat & 0xff) {
  		case 0x1:
  		case 0x2:
  		case 0x10:
  		case 0x11:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2386
  			qla24xx_mbx_completion(vha, MSW(stat));
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2387
2388
2389
2390
2391
2392
2393
2394
  			status |= MBX_INTERRUPT;
  
  			break;
  		case 0x12:
  			mb[0] = MSW(stat);
  			mb[1] = RD_REG_WORD(&reg->mailbox1);
  			mb[2] = RD_REG_WORD(&reg->mailbox2);
  			mb[3] = RD_REG_WORD(&reg->mailbox3);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2395
  			qla2x00_async_event(vha, rsp, mb);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2396
2397
  			break;
  		case 0x13:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2398
  		case 0x14:
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2399
  			qla24xx_process_response_queue(vha, rsp);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2400
2401
  			break;
  		default:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2402
2403
2404
  			ql_dbg(ql_dbg_async, vha, 0x5051,
  			    "Unrecognized interrupt type (%d).
  ", stat & 0xff);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2405
2406
2407
  			break;
  		}
  		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
87f27015b   Andrew Vasquez   [SCSI] qla2xxx: R...
2408
  	} while (0);
0f19bc681   Xiaotian Feng   [SCSI] qla2xxx: m...
2409
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2410
2411
2412
  
  	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
  	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2413
  		set_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
0b05a1f0d   Marcus Barrow   [SCSI] qla2xxx: U...
2414
  		complete(&ha->mbx_intr_comp);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2415
  	}
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2416
2417
2418
2419
2420
2421
  	return IRQ_HANDLED;
  }
  
  /* Interrupt handling helpers. */
  
  struct qla_init_msix_entry {
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2422
  	const char *name;
476834c25   Jeff Garzik   [SCSI] aacraid,ql...
2423
  	irq_handler_t handler;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2424
  };
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2425
  static struct qla_init_msix_entry msix_entries[3] = {
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2426
2427
  	{ "qla2xxx (default)", qla24xx_msix_default },
  	{ "qla2xxx (rsp_q)", qla24xx_msix_rsp_q },
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2428
  	{ "qla2xxx (multiq)", qla25xx_msix_rsp_q },
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2429
  };
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2430
2431
2432
2433
  static struct qla_init_msix_entry qla82xx_msix_entries[2] = {
  	{ "qla2xxx (default)", qla82xx_msix_default },
  	{ "qla2xxx (rsp_q)", qla82xx_msix_rsp_q },
  };
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2434
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2435
  qla24xx_disable_msix(struct qla_hw_data *ha)
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2436
2437
2438
  {
  	int i;
  	struct qla_msix_entry *qentry;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2439
  	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2440

73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2441
2442
  	for (i = 0; i < ha->msix_count; i++) {
  		qentry = &ha->msix_entries[i];
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2443
  		if (qentry->have_irq)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2444
  			free_irq(qentry->vector, qentry->rsp);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2445
2446
  	}
  	pci_disable_msix(ha->pdev);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2447
2448
2449
  	kfree(ha->msix_entries);
  	ha->msix_entries = NULL;
  	ha->flags.msix_enabled = 0;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2450
2451
2452
  	ql_dbg(ql_dbg_init, vha, 0x0042,
  	    "Disabled the MSI.
  ");
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2453
2454
2455
  }
  
  static int
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2456
  qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2457
  {
ad038fa82   Lalit Chandivade   [SCSI] qla2xxx: C...
2458
  #define MIN_MSIX_COUNT	2
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2459
  	int i, ret;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2460
  	struct msix_entry *entries;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2461
  	struct qla_msix_entry *qentry;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2462
  	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2463
2464
  
  	entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2465
  			GFP_KERNEL);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2466
2467
2468
2469
  	if (!entries) {
  		ql_log(ql_log_warn, vha, 0x00bc,
  		    "Failed to allocate memory for msix_entry.
  ");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2470
  		return -ENOMEM;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2471
  	}
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2472

73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2473
2474
  	for (i = 0; i < ha->msix_count; i++)
  		entries[i].entry = i;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2475

73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2476
  	ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2477
  	if (ret) {
ad038fa82   Lalit Chandivade   [SCSI] qla2xxx: C...
2478
2479
  		if (ret < MIN_MSIX_COUNT)
  			goto msix_failed;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2480
2481
2482
2483
2484
2485
  		ql_log(ql_log_warn, vha, 0x00c6,
  		    "MSI-X: Failed to enable support "
  		    "-- %d/%d
   Retry with %d vectors.
  ",
  		    ha->msix_count, ret, ret);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2486
2487
2488
  		ha->msix_count = ret;
  		ret = pci_enable_msix(ha->pdev, entries, ha->msix_count);
  		if (ret) {
ad038fa82   Lalit Chandivade   [SCSI] qla2xxx: C...
2489
  msix_failed:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2490
2491
2492
2493
2494
  			ql_log(ql_log_fatal, vha, 0x00c7,
  			    "MSI-X: Failed to enable support, "
  			    "giving   up -- %d/%d.
  ",
  			    ha->msix_count, ret);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2495
2496
  			goto msix_out;
  		}
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2497
  		ha->max_rsp_queues = ha->msix_count - 1;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2498
2499
2500
2501
  	}
  	ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
  				ha->msix_count, GFP_KERNEL);
  	if (!ha->msix_entries) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2502
2503
2504
  		ql_log(ql_log_fatal, vha, 0x00c8,
  		    "Failed to allocate memory for ha->msix_entries.
  ");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2505
  		ret = -ENOMEM;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2506
2507
2508
  		goto msix_out;
  	}
  	ha->flags.msix_enabled = 1;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2509
2510
2511
2512
  	for (i = 0; i < ha->msix_count; i++) {
  		qentry = &ha->msix_entries[i];
  		qentry->vector = entries[i].vector;
  		qentry->entry = entries[i].entry;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2513
  		qentry->have_irq = 0;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2514
  		qentry->rsp = NULL;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2515
  	}
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2516
2517
2518
  	/* Enable MSI-X vectors for the base queue */
  	for (i = 0; i < 2; i++) {
  		qentry = &ha->msix_entries[i];
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2519
2520
2521
2522
2523
2524
2525
2526
2527
  		if (IS_QLA82XX(ha)) {
  			ret = request_irq(qentry->vector,
  				qla82xx_msix_entries[i].handler,
  				0, qla82xx_msix_entries[i].name, rsp);
  		} else {
  			ret = request_irq(qentry->vector,
  				msix_entries[i].handler,
  				0, msix_entries[i].name, rsp);
  		}
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2528
  		if (ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2529
2530
2531
2532
  			ql_log(ql_log_fatal, vha, 0x00cb,
  			    "MSI-X: unable to register handler -- %x/%d.
  ",
  			    qentry->vector, ret);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2533
2534
2535
2536
2537
2538
2539
  			qla24xx_disable_msix(ha);
  			ha->mqenable = 0;
  			goto msix_out;
  		}
  		qentry->have_irq = 1;
  		qentry->rsp = rsp;
  		rsp->msix = qentry;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2540
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2541
2542
  
  	/* Enable MSI-X vector for response queue update for queue 0 */
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2543
  	if (ha->mqiobase &&  (ha->max_rsp_queues > 1 || ha->max_req_queues > 1))
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2544
  		ha->mqenable = 1;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2545
2546
2547
2548
2549
2550
2551
2552
  	ql_dbg(ql_dbg_multiq, vha, 0xc005,
  	    "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.
  ",
  	    ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues);
  	ql_dbg(ql_dbg_init, vha, 0x0055,
  	    "mqiobase=%p, max_rsp_queues=%d, max_req_queues=%d.
  ",
  	    ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2553

a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2554
  msix_out:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2555
  	kfree(entries);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2556
2557
2558
2559
  	return ret;
  }
  
  int
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2560
  qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2561
2562
  {
  	int ret;
963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2563
  	device_reg_t __iomem *reg = ha->iobase;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2564
  	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2565
2566
  
  	/* If possible, enable MSI-X. */
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2567
  	if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2568
  		!IS_QLA8432(ha) && !IS_QLA8XXX_TYPE(ha))
6377a7ae1   Ben Hutchings   [SCSI] qla2xxx: D...
2569
2570
2571
2572
2573
2574
  		goto skip_msi;
  
  	if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
  		(ha->pdev->subsystem_device == 0x7040 ||
  		ha->pdev->subsystem_device == 0x7041 ||
  		ha->pdev->subsystem_device == 0x1705)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2575
2576
2577
  		ql_log(ql_log_warn, vha, 0x0034,
  		    "MSI-X: Unsupported ISP 2432 SSVID/SSDID (0x%X,0x%X).
  ",
6377a7ae1   Ben Hutchings   [SCSI] qla2xxx: D...
2578
  			ha->pdev->subsystem_vendor,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2579
  			ha->pdev->subsystem_device);
6377a7ae1   Ben Hutchings   [SCSI] qla2xxx: D...
2580
2581
  		goto skip_msi;
  	}
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2582

42cd4f5dc   Chad Dupuis   [SCSI] qla2xxx: F...
2583
  	if (IS_QLA2432(ha) && (ha->pdev->revision < QLA_MSIX_CHIP_REV_24XX)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2584
2585
2586
  		ql_log(ql_log_warn, vha, 0x0035,
  		    "MSI-X; Unsupported ISP2432 (0x%X, 0x%X).
  ",
42cd4f5dc   Chad Dupuis   [SCSI] qla2xxx: F...
2587
  		    ha->pdev->revision, QLA_MSIX_CHIP_REV_24XX);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2588
2589
  		goto skip_msix;
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2590
  	ret = qla24xx_enable_msix(ha, rsp);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2591
  	if (!ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2592
2593
2594
2595
  		ql_dbg(ql_dbg_init, vha, 0x0036,
  		    "MSI-X: Enabled (0x%X, 0x%X).
  ",
  		    ha->chip_revision, ha->fw_attributes);
963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2596
  		goto clear_risc_ints;
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2597
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2598
2599
2600
  	ql_log(ql_log_info, vha, 0x0037,
  	    "MSI-X Falling back-to MSI mode -%d.
  ", ret);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2601
  skip_msix:
cbedb6018   Andrew Vasquez   [SCSI] qla2xxx: A...
2602

3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2603
2604
  	if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
  	    !IS_QLA8001(ha))
cbedb6018   Andrew Vasquez   [SCSI] qla2xxx: A...
2605
2606
2607
2608
  		goto skip_msi;
  
  	ret = pci_enable_msi(ha->pdev);
  	if (!ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2609
2610
2611
  		ql_dbg(ql_dbg_init, vha, 0x0038,
  		    "MSI: Enabled.
  ");
cbedb6018   Andrew Vasquez   [SCSI] qla2xxx: A...
2612
  		ha->flags.msi_enabled = 1;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2613
  	} else
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2614
2615
2616
  		ql_log(ql_log_warn, vha, 0x0039,
  		    "MSI-X; Falling back-to INTa mode -- %d.
  ", ret);
cbedb6018   Andrew Vasquez   [SCSI] qla2xxx: A...
2617
  skip_msi:
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
2618
  	ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
7992abfc8   Mike Hernandez   [SCSI] qla2xxx: C...
2619
2620
  	    ha->flags.msi_enabled ? 0 : IRQF_SHARED,
  	    QLA2XXX_DRIVER_NAME, rsp);
963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2621
  	if (ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2622
  		ql_log(ql_log_warn, vha, 0x003a,
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2623
2624
2625
  		    "Failed to reserve interrupt %d already in use.
  ",
  		    ha->pdev->irq);
963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2626
2627
  		goto fail;
  	}
7992abfc8   Mike Hernandez   [SCSI] qla2xxx: C...
2628

963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2629
  clear_risc_ints:
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2630
2631
2632
2633
  	/*
  	 * FIXME: Noted that 8014s were being dropped during NK testing.
  	 * Timing deltas during MSI-X/INTa transitions?
  	 */
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2634
  	if (IS_QLA81XX(ha) || IS_QLA82XX(ha))
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2635
  		goto fail;
c6952483b   Andrew Vasquez   [SCSI] qla2xxx: S...
2636
  	spin_lock_irq(&ha->hardware_lock);
963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2637
2638
2639
2640
2641
2642
2643
  	if (IS_FWI2_CAPABLE(ha)) {
  		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
  		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
  	} else {
  		WRT_REG_WORD(&reg->isp.semaphore, 0);
  		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
  		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2644
  	}
c6952483b   Andrew Vasquez   [SCSI] qla2xxx: S...
2645
  	spin_unlock_irq(&ha->hardware_lock);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2646

963b0fdd3   Andrew Vasquez   [SCSI] qla2xxx: M...
2647
  fail:
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2648
2649
2650
2651
  	return ret;
  }
  
  void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2652
  qla2x00_free_irqs(scsi_qla_host_t *vha)
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2653
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2654
  	struct qla_hw_data *ha = vha->hw;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2655
  	struct rsp_que *rsp = ha->rsp_q_map[0];
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2656
2657
2658
  
  	if (ha->flags.msix_enabled)
  		qla24xx_disable_msix(ha);
90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
2659
  	else if (ha->flags.msi_enabled) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2660
  		free_irq(ha->pdev->irq, rsp);
cbedb6018   Andrew Vasquez   [SCSI] qla2xxx: A...
2661
  		pci_disable_msi(ha->pdev);
90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
2662
2663
  	} else
  		free_irq(ha->pdev->irq, rsp);
a8488abef   Andrew Vasquez   [SCSI] qla2xxx: A...
2664
  }
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2665

73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2666
2667
2668
2669
  
  int qla25xx_request_irq(struct rsp_que *rsp)
  {
  	struct qla_hw_data *ha = rsp->hw;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2670
  	struct qla_init_msix_entry *intr = &msix_entries[2];
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2671
  	struct qla_msix_entry *msix = rsp->msix;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2672
  	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2673
2674
2675
2676
  	int ret;
  
  	ret = request_irq(msix->vector, intr->handler, 0, intr->name, rsp);
  	if (ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2677
2678
2679
2680
  		ql_log(ql_log_fatal, vha, 0x00e6,
  		    "MSI-X: Unable to register handler -- %x/%d.
  ",
  		    msix->vector, ret);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2681
2682
2683
2684
2685
2686
  		return ret;
  	}
  	msix->have_irq = 1;
  	msix->rsp = rsp;
  	return ret;
  }