Blame view

drivers/scsi/qla2xxx/qla_os.c 159 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
fa90c54f6   Andrew Vasquez   [SCSI] qla2xxx: U...
2
   * QLogic Fibre Channel HBA Driver
bd21eaf92   Armen Baloyan   qla2xxx: Change c...
3
   * Copyright (c)  2003-2014 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
8
9
10
   */
  #include "qla_def.h"
  
  #include <linux/moduleparam.h>
  #include <linux/vmalloc.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
  #include <linux/delay.h>
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
12
  #include <linux/kthread.h>
e1e82b6f0   Daniel Walker   [SCSI] qla2xxx: f...
13
  #include <linux/mutex.h>
3420d36ca   Andrew Vasquez   [SCSI] qla2xxx: A...
14
  #include <linux/kobject.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
15
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
  #include <scsi/scsi_tcq.h>
  #include <scsi/scsicam.h>
  #include <scsi/scsi_transport.h>
  #include <scsi/scsi_transport_fc.h>
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
20
  #include "qla_target.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
  /*
   * Driver version
   */
  char qla2x00_version_str[40];
6a03b4cd7   Harish Zunjarrao   [SCSI] qla2xxx: A...
25
  static int apidev_major;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
  /*
   * SRB allocation cache
   */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
29
  static struct kmem_cache *srb_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30

a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
31
32
33
34
  /*
   * CT6 CTX allocation cache
   */
  static struct kmem_cache *ctx_cachep;
3ce8866ce   Saurav Kashyap   [SCSI] qla2xxx: B...
35
36
37
38
  /*
   * error level for logging
   */
  int ql_errlev = ql_log_all;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
39

fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
40
  static int ql2xenableclass2;
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
41
42
43
44
  module_param(ql2xenableclass2, int, S_IRUGO|S_IRUSR);
  MODULE_PARM_DESC(ql2xenableclass2,
  		"Specify if Class 2 operations are supported from the very "
  		"beginning. Default is 0 - class 2 not supported.");
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
45

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  int ql2xlogintimeout = 20;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
47
  module_param(ql2xlogintimeout, int, S_IRUGO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
49
  MODULE_PARM_DESC(ql2xlogintimeout,
  		"Login timeout value in seconds.");
a7b618422   Andrew Vasquez   [SCSI] qla2xxx: H...
50
  int qlport_down_retry;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
51
  module_param(qlport_down_retry, int, S_IRUGO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
  MODULE_PARM_DESC(qlport_down_retry,
900d9f987   Jesper Juhl   [SCSI] small whit...
53
  		"Maximum number of command retries to a port that returns "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  		"a PORT-DOWN status.");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
  int ql2xplogiabsentdevice;
  module_param(ql2xplogiabsentdevice, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(ql2xplogiabsentdevice,
  		"Option to enable PLOGI to devices that are not present after "
900d9f987   Jesper Juhl   [SCSI] small whit...
59
  		"a Fabric scan.  This is needed for several broken switches. "
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
60
  		"Default is 0 - no PLOGI. 1 - perfom PLOGI.");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  int ql2xloginretrycount = 0;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
62
  module_param(ql2xloginretrycount, int, S_IRUGO);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
  MODULE_PARM_DESC(ql2xloginretrycount,
  		"Specify an alternate value for the NVRAM login retry count.");
a7a167bf7   Andrew Vasquez   [SCSI] qla2xxx: R...
65
  int ql2xallocfwdump = 1;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
66
  module_param(ql2xallocfwdump, int, S_IRUGO);
a7a167bf7   Andrew Vasquez   [SCSI] qla2xxx: R...
67
68
69
70
  MODULE_PARM_DESC(ql2xallocfwdump,
  		"Option to enable allocation of memory for a firmware dump "
  		"during HBA initialization.  Memory allocation requirements "
  		"vary by ISP type.  Default is 1 - allocate memory.");
11010fecd   Andrew Vasquez   [SCSI] Maintain m...
71
  int ql2xextended_error_logging;
27d940352   Andrew Vasquez   [SCSI] qla2xxx: A...
72
  module_param(ql2xextended_error_logging, int, S_IRUGO|S_IWUSR);
11010fecd   Andrew Vasquez   [SCSI] Maintain m...
73
  MODULE_PARM_DESC(ql2xextended_error_logging,
3ce8866ce   Saurav Kashyap   [SCSI] qla2xxx: B...
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  		"Option to enable extended error logging,
  "
  		"\t\tDefault is 0 - no logging.  0x40000000 - Module Init & Probe.
  "
  		"\t\t0x20000000 - Mailbox Cmnds. 0x10000000 - Device Discovery.
  "
  		"\t\t0x08000000 - IO tracing.    0x04000000 - DPC Thread.
  "
  		"\t\t0x02000000 - Async events.  0x01000000 - Timer routines.
  "
  		"\t\t0x00800000 - User space.    0x00400000 - Task Management.
  "
  		"\t\t0x00200000 - AER/EEH.       0x00100000 - Multi Q.
  "
  		"\t\t0x00080000 - P3P Specific.  0x00040000 - Virtual Port.
  "
  		"\t\t0x00020000 - Buffer Dump.   0x00010000 - Misc.
  "
29f9f90ce   Chad Dupuis   [SCSI] qla2xxx: U...
92
93
94
95
  		"\t\t0x00008000 - Verbose.       0x00004000 - Target.
  "
  		"\t\t0x00002000 - Target Mgmt.   0x00001000 - Target TMF.
  "
3ce8866ce   Saurav Kashyap   [SCSI] qla2xxx: B...
96
97
  		"\t\t0x7fffffff - For enabling all logs, can be too many logs.
  "
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
98
99
100
101
  		"\t\t0x1e400000 - Preferred value for capturing essential "
  		"debug information (equivalent to old "
  		"ql2xextended_error_logging=1).
  "
3ce8866ce   Saurav Kashyap   [SCSI] qla2xxx: B...
102
  		"\t\tDo LOGICAL OR of the value to enable more than one level");
0181944fe   Andrew Vasquez   [SCSI] qla2xxx: A...
103

a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
104
  int ql2xshiftctondsd = 6;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
105
  module_param(ql2xshiftctondsd, int, S_IRUGO);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
106
107
108
  MODULE_PARM_DESC(ql2xshiftctondsd,
  		"Set to control shifting of command type processing "
  		"based on total number of SG elements.");
7e47e5ca1   Andrew Vasquez   [SCSI] qla2xxx: R...
109
  int ql2xfdmienable=1;
de187df86   Himanshu Madhani   qla2xxx: Allow us...
110
  module_param(ql2xfdmienable, int, S_IRUGO|S_IWUSR);
cca5335ca   Andrew Vasquez   [SCSI] qla2xxx: A...
111
  MODULE_PARM_DESC(ql2xfdmienable,
7794a5af6   Ferenc Wagner   [SCSI] qla2xxx: F...
112
113
  		"Enables FDMI registrations. "
  		"0 - no FDMI. Default is 1 - perform FDMI.");
cca5335ca   Andrew Vasquez   [SCSI] qla2xxx: A...
114

50280c014   Chad Dupuis   [SCSI] Revert "ql...
115
116
  #define MAX_Q_DEPTH	32
  static int ql2xmaxqdepth = MAX_Q_DEPTH;
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
117
118
  module_param(ql2xmaxqdepth, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(ql2xmaxqdepth,
e92e4a8f0   Chad Dupuis   [SCSI] qla2xxx: F...
119
120
  		"Maximum queue depth to set for each LUN. "
  		"Default is 32.");
df7baa506   Andrew Vasquez   [SCSI] qla2xxx: C...
121

9e522cd8f   Arun Easi   [SCSI] qla2xxx: T...
122
123
  int ql2xenabledif = 2;
  module_param(ql2xenabledif, int, S_IRUGO);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
124
  MODULE_PARM_DESC(ql2xenabledif,
b97f5d0b0   Steven J. Magnani   [SCSI] qla2xxx: R...
125
126
127
128
129
130
131
132
133
134
  		" Enable T10-CRC-DIF:
  "
  		" Default is 2.
  "
  		"  0 -- No DIF Support
  "
  		"  1 -- Enable DIF for all types
  "
  		"  2 -- Enable DIF for all types, except Type 0.
  ");
bad750028   Arun Easi   [SCSI] qla2xxx: T...
135

8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
136
  int ql2xenablehba_err_chk = 2;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
137
138
  module_param(ql2xenablehba_err_chk, int, S_IRUGO|S_IWUSR);
  MODULE_PARM_DESC(ql2xenablehba_err_chk,
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
139
140
  		" Enable T10-CRC-DIF Error isolation by HBA:
  "
b97f5d0b0   Steven J. Magnani   [SCSI] qla2xxx: R...
141
142
  		" Default is 2.
  "
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
143
144
145
146
147
148
  		"  0 -- Error isolation disabled
  "
  		"  1 -- Error isolation enabled only for DIX Type 0
  "
  		"  2 -- Error isolation enabled for all Types
  ");
bad750028   Arun Easi   [SCSI] qla2xxx: T...
149

e5896bd5d   Andrew Vasquez   [SCSI] qla2xxx: A...
150
  int ql2xiidmaenable=1;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
151
  module_param(ql2xiidmaenable, int, S_IRUGO);
e5896bd5d   Andrew Vasquez   [SCSI] qla2xxx: A...
152
153
154
  MODULE_PARM_DESC(ql2xiidmaenable,
  		"Enables iIDMA settings "
  		"Default is 1 - perform iIDMA. 0 - no iIDMA.");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
155
  int ql2xmaxqueues = 1;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
156
  module_param(ql2xmaxqueues, int, S_IRUGO);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
157
158
  MODULE_PARM_DESC(ql2xmaxqueues,
  		"Enables MQ settings "
ae68230c2   Joe Perches   drivers/scsi/qla2...
159
160
  		"Default is 1 for single queue. Set it to number "
  		"of queues in MQ mode.");
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
161
162
  
  int ql2xmultique_tag;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
163
  module_param(ql2xmultique_tag, int, S_IRUGO);
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
164
165
166
167
  MODULE_PARM_DESC(ql2xmultique_tag,
  		"Enables CPU affinity settings for the driver "
  		"Default is 0 for no affinity of request and response IO. "
  		"Set it to 1 to turn on the cpu affinity.");
e337d9070   Andrew Vasquez   [SCSI] qla2xxx: A...
168
169
  
  int ql2xfwloadbin;
86e45bf66   Chad Dupuis   [SCSI] qla2xxx: E...
170
  module_param(ql2xfwloadbin, int, S_IRUGO|S_IWUSR);
e337d9070   Andrew Vasquez   [SCSI] qla2xxx: A...
171
  MODULE_PARM_DESC(ql2xfwloadbin,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
172
173
174
175
  		"Option to specify location from which to load ISP firmware:.
  "
  		" 2 -- load firmware via the request_firmware() (hotplug).
  "
e337d9070   Andrew Vasquez   [SCSI] qla2xxx: A...
176
177
178
179
180
181
  		"      interface.
  "
  		" 1 -- load firmware from flash.
  "
  		" 0 -- use default semantics.
  ");
ae97c91eb   Andrew Vasquez   [SCSI] qla2xxx: A...
182
  int ql2xetsenable;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
183
  module_param(ql2xetsenable, int, S_IRUGO);
ae97c91eb   Andrew Vasquez   [SCSI] qla2xxx: A...
184
185
186
  MODULE_PARM_DESC(ql2xetsenable,
  		"Enables firmware ETS burst."
  		"Default is 0 - skip ETS enablement.");
6907869d7   Giridhar Malavali   [SCSI] qla2xxx: E...
187
  int ql2xdbwr = 1;
86e45bf66   Chad Dupuis   [SCSI] qla2xxx: E...
188
  module_param(ql2xdbwr, int, S_IRUGO|S_IWUSR);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
189
  MODULE_PARM_DESC(ql2xdbwr,
08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
190
191
192
193
194
195
  		"Option to specify scheme for request queue posting.
  "
  		" 0 -- Regular doorbell.
  "
  		" 1 -- CAMRAM doorbell (faster).
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
196

f4c496c1f   Giridhar Malavali   [SCSI] qla2xxx: O...
197
  int ql2xtargetreset = 1;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
198
  module_param(ql2xtargetreset, int, S_IRUGO);
f4c496c1f   Giridhar Malavali   [SCSI] qla2xxx: O...
199
200
201
  MODULE_PARM_DESC(ql2xtargetreset,
  		 "Enable target reset."
  		 "Default is 1 - use hw defaults.");
4da26e162   Chad Dupuis   [SCSI] qla2xxx: A...
202
  int ql2xgffidenable;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
203
  module_param(ql2xgffidenable, int, S_IRUGO);
4da26e162   Chad Dupuis   [SCSI] qla2xxx: A...
204
205
206
  MODULE_PARM_DESC(ql2xgffidenable,
  		"Enables GFF_ID checks of port type. "
  		"Default is 0 - Do not use GFF_ID information.");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
207

3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
208
  int ql2xasynctmfenable;
f2019cb11   Joe Carnuccio   [SCSI] qla2xxx: R...
209
  module_param(ql2xasynctmfenable, int, S_IRUGO);
3822263eb   Madhuranath Iyengar   [SCSI] qla2xxx: S...
210
211
212
  MODULE_PARM_DESC(ql2xasynctmfenable,
  		"Enables issue of TM IOCBs asynchronously via IOCB mechanism"
  		"Default is 0 - Issue TM IOCBs via mailbox mechanism.");
ed0de87ce   Giridhar Malavali   [SCSI] qla2xxx: A...
213
214
  
  int ql2xdontresethba;
86e45bf66   Chad Dupuis   [SCSI] qla2xxx: E...
215
  module_param(ql2xdontresethba, int, S_IRUGO|S_IWUSR);
ed0de87ce   Giridhar Malavali   [SCSI] qla2xxx: A...
216
  MODULE_PARM_DESC(ql2xdontresethba,
08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
217
218
219
220
221
222
  		"Option to specify reset behaviour.
  "
  		" 0 (Default) -- Reset on failure.
  "
  		" 1 -- Do not reset on failure.
  ");
ed0de87ce   Giridhar Malavali   [SCSI] qla2xxx: A...
223

1abf635d2   Hannes Reinecke   scsi: use 64-bit ...
224
225
  uint64_t ql2xmaxlun = MAX_LUNS;
  module_param(ql2xmaxlun, ullong, S_IRUGO);
82515920b   Andrew Vasquez   [SCSI] qla2xxx: A...
226
227
228
  MODULE_PARM_DESC(ql2xmaxlun,
  		"Defines the maximum LU number to register with the SCSI "
  		"midlayer. Default is 65535.");
08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
229
230
231
232
  int ql2xmdcapmask = 0x1F;
  module_param(ql2xmdcapmask, int, S_IRUGO);
  MODULE_PARM_DESC(ql2xmdcapmask,
  		"Set the Minidump driver capture mask level. "
6e96fa7b8   Giridhar Malavali   [SCSI] qla2xxx: C...
233
  		"Default is 0x1F - Can be set to 0x3, 0x7, 0xF, 0x1F, 0x7F.");
08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
234

3aadff356   Giridhar Malavali   [SCSI] qla2xxx: E...
235
  int ql2xmdenable = 1;
08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
236
237
238
  module_param(ql2xmdenable, int, S_IRUGO);
  MODULE_PARM_DESC(ql2xmdenable,
  		"Enable/disable MiniDump. "
3aadff356   Giridhar Malavali   [SCSI] qla2xxx: E...
239
240
  		"0 - MiniDump disabled. "
  		"1 (Default) - MiniDump enabled.");
08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
241

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
  /*
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
243
   * SCSI host template entry points
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
   */
  static int qla2xxx_slave_configure(struct scsi_device * device);
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
246
  static int qla2xxx_slave_alloc(struct scsi_device *);
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
247
248
  static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
  static void qla2xxx_scan_start(struct Scsi_Host *);
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
249
  static void qla2xxx_slave_destroy(struct scsi_device *);
f281233d3   Jeff Garzik   SCSI host lock pu...
250
  static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
  static int qla2xxx_eh_abort(struct scsi_cmnd *);
  static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
253
  static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
  static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
  static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256

1a2fbf185   Joe Lawrence   qla2xxx: Use qla2...
257
  static void qla2x00_clear_drv_active(struct qla_hw_data *);
3491255e1   Saurav Kashyap   [SCSI] qla2xxx: M...
258
  static void qla2x00_free_device(scsi_qla_host_t *);
2d5a4c344   Himanshu Madhani   qla2xxx: Disable ...
259
  static void qla83xx_disable_laser(scsi_qla_host_t *vha);
ce7e4af7f   Andrew Vasquez   [SCSI] qla2xxx: A...
260

a5326f86e   Giridhar Malavali   [SCSI] qla2xxx: C...
261
  struct scsi_host_template qla2xxx_driver_template = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
  	.module			= THIS_MODULE,
cb63067a7   Andrew Vasquez   [SCSI] qla2xxx: C...
263
  	.name			= QLA2XXX_DRIVER_NAME,
a5326f86e   Giridhar Malavali   [SCSI] qla2xxx: C...
264
  	.queuecommand		= qla2xxx_queuecommand,
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
265
266
267
  
  	.eh_abort_handler	= qla2xxx_eh_abort,
  	.eh_device_reset_handler = qla2xxx_eh_device_reset,
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
268
  	.eh_target_reset_handler = qla2xxx_eh_target_reset,
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
269
270
271
272
273
274
275
  	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
  	.eh_host_reset_handler	= qla2xxx_eh_host_reset,
  
  	.slave_configure	= qla2xxx_slave_configure,
  
  	.slave_alloc		= qla2xxx_slave_alloc,
  	.slave_destroy		= qla2xxx_slave_destroy,
ed6770863   Andrew Vasquez   [SCSI] qla2xxx: A...
276
277
  	.scan_finished		= qla2xxx_scan_finished,
  	.scan_start		= qla2xxx_scan_start,
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
278
  	.change_queue_depth	= scsi_change_queue_depth,
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
279
280
281
282
283
284
  	.this_id		= -1,
  	.cmd_per_lun		= 3,
  	.use_clustering		= ENABLE_CLUSTERING,
  	.sg_tablesize		= SG_ALL,
  
  	.max_sectors		= 0xFFFF,
afb046e2b   Andrew Vasquez   [SCSI] qla2xxx: A...
285
  	.shost_attrs		= qla2x00_host_attrs,
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
286
287
  
  	.supported_mode		= MODE_INITIATOR,
2ecb204d0   Christoph Hellwig   scsi: always assi...
288
  	.use_blk_tags		= 1,
c40ecc12c   Christoph Hellwig   scsi: avoid ->cha...
289
  	.track_queue_depth	= 1,
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
290
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
  static struct scsi_transport_template *qla2xxx_transport_template = NULL;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
292
  struct scsi_transport_template *qla2xxx_transport_vport_template = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
297
  /* TODO Convert to inlines
   *
   * Timer routines
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298

2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
299
  __inline__ void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
300
  qla2x00_start_timer(scsi_qla_host_t *vha, void *func, unsigned long interval)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
302
303
304
305
306
307
  	init_timer(&vha->timer);
  	vha->timer.expires = jiffies + interval * HZ;
  	vha->timer.data = (unsigned long)vha;
  	vha->timer.function = (void (*)(unsigned long))func;
  	add_timer(&vha->timer);
  	vha->timer_active = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
309
310
  }
  
  static inline void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
311
  qla2x00_restart_timer(scsi_qla_host_t *vha, unsigned long interval)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
313
  	/* Currently used for 82XX only. */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
314
315
316
317
  	if (vha->device_flags & DFLG_DEV_FAILED) {
  		ql_dbg(ql_dbg_timer, vha, 0x600d,
  		    "Device in a failed state, returning.
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
318
  		return;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
319
  	}
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
320

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
321
  	mod_timer(&vha->timer, jiffies + interval * HZ);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
  }
a824ebb37   Adrian Bunk   [SCSI] qla2xxx: C...
323
  static __inline__ void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
324
  qla2x00_stop_timer(scsi_qla_host_t *vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
325
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
326
327
  	del_timer_sync(&vha->timer);
  	vha->timer_active = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
328
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
331
  static int qla2x00_do_dpc(void *data);
  
  static void qla2x00_rst_aen(scsi_qla_host_t *);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
332
333
  static int qla2x00_mem_alloc(struct qla_hw_data *, uint16_t, uint16_t,
  	struct req_que **, struct rsp_que **);
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
334
  static void qla2x00_free_fw_dump(struct qla_hw_data *);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
335
  static void qla2x00_mem_free(struct qla_hw_data *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  /* -------------------------------------------------------------------------- */
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
338
339
  static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
  				struct rsp_que *rsp)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
340
  {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
341
  	scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
342
  	ha->req_q_map = kzalloc(sizeof(struct req_que *) * ha->max_req_queues,
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
343
344
  				GFP_KERNEL);
  	if (!ha->req_q_map) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
345
346
347
  		ql_log(ql_log_fatal, vha, 0x003b,
  		    "Unable to allocate memory for request queue ptrs.
  ");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
348
349
  		goto fail_req_map;
  	}
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
350
  	ha->rsp_q_map = kzalloc(sizeof(struct rsp_que *) * ha->max_rsp_queues,
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
351
352
  				GFP_KERNEL);
  	if (!ha->rsp_q_map) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
353
354
355
  		ql_log(ql_log_fatal, vha, 0x003c,
  		    "Unable to allocate memory for response queue ptrs.
  ");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
356
357
  		goto fail_rsp_map;
  	}
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
358
359
360
361
362
363
  	/*
  	 * Make sure we record at least the request and response queue zero in
  	 * case we need to free them if part of the probe fails.
  	 */
  	ha->rsp_q_map[0] = rsp;
  	ha->req_q_map[0] = req;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
364
365
366
367
368
369
370
371
372
373
  	set_bit(0, ha->rsp_qid_map);
  	set_bit(0, ha->req_qid_map);
  	return 1;
  
  fail_rsp_map:
  	kfree(ha->req_q_map);
  	ha->req_q_map = NULL;
  fail_req_map:
  	return -ENOMEM;
  }
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
374
  static void qla2x00_free_req_que(struct qla_hw_data *ha, struct req_que *req)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
375
  {
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
376
377
378
379
380
381
  	if (IS_QLAFX00(ha)) {
  		if (req && req->ring_fx00)
  			dma_free_coherent(&ha->pdev->dev,
  			    (req->length_fx00 + 1) * sizeof(request_t),
  			    req->ring_fx00, req->dma_fx00);
  	} else if (req && req->ring)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
382
383
384
  		dma_free_coherent(&ha->pdev->dev,
  		(req->length + 1) * sizeof(request_t),
  		req->ring, req->dma);
8d93f5502   Chad Dupuis   [SCSI] qla2xxx: D...
385
386
  	if (req)
  		kfree(req->outstanding_cmds);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
387
388
389
  	kfree(req);
  	req = NULL;
  }
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
390
391
  static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp)
  {
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
392
393
394
395
396
397
  	if (IS_QLAFX00(ha)) {
  		if (rsp && rsp->ring)
  			dma_free_coherent(&ha->pdev->dev,
  			    (rsp->length_fx00 + 1) * sizeof(request_t),
  			    rsp->ring_fx00, rsp->dma_fx00);
  	} else if (rsp && rsp->ring) {
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
398
399
400
  		dma_free_coherent(&ha->pdev->dev,
  		(rsp->length + 1) * sizeof(response_t),
  		rsp->ring, rsp->dma);
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
401
  	}
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
402
403
404
  	kfree(rsp);
  	rsp = NULL;
  }
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
405
406
407
408
409
  static void qla2x00_free_queues(struct qla_hw_data *ha)
  {
  	struct req_que *req;
  	struct rsp_que *rsp;
  	int cnt;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
410
  	for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
411
  		req = ha->req_q_map[cnt];
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
412
  		qla2x00_free_req_que(ha, req);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
413
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
414
415
  	kfree(ha->req_q_map);
  	ha->req_q_map = NULL;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
416
417
418
419
420
421
422
  
  	for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
  		rsp = ha->rsp_q_map[cnt];
  		qla2x00_free_rsp_que(ha, rsp);
  	}
  	kfree(ha->rsp_q_map);
  	ha->rsp_q_map = NULL;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
423
  }
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
424
425
426
427
428
  static int qla25xx_setup_mode(struct scsi_qla_host *vha)
  {
  	uint16_t options = 0;
  	int ques, req, ret;
  	struct qla_hw_data *ha = vha->hw;
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
429
  	if (!(ha->fw_attributes & BIT_6)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
430
431
432
  		ql_log(ql_log_warn, vha, 0x00d8,
  		    "Firmware is not multi-queue capable.
  ");
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
433
434
  		goto fail;
  	}
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
435
  	if (ql2xmultique_tag) {
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
436
437
438
439
440
  		/* create a request queue for IO */
  		options |= BIT_7;
  		req = qla25xx_create_req_que(ha, options, 0, 0, -1,
  			QLA_DEFAULT_QUE_QOS);
  		if (!req) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
441
442
443
  			ql_log(ql_log_warn, vha, 0x00e0,
  			    "Failed to create request queue.
  ");
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
444
445
  			goto fail;
  		}
278274d54   Tejun Heo   scsi/be2iscsi,qla...
446
  		ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1);
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
447
448
449
450
451
  		vha->req = ha->req_q_map[req];
  		options |= BIT_1;
  		for (ques = 1; ques < ha->max_rsp_queues; ques++) {
  			ret = qla25xx_create_rsp_que(ha, options, 0, 0, req);
  			if (!ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
452
453
454
  				ql_log(ql_log_warn, vha, 0x00e8,
  				    "Failed to create response queue.
  ");
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
455
456
457
  				goto fail2;
  			}
  		}
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
458
  		ha->flags.cpu_affinity_enabled = 1;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
459
460
461
462
463
464
465
466
467
468
  		ql_dbg(ql_dbg_multiq, vha, 0xc007,
  		    "CPU affinity mode enalbed, "
  		    "no. of response queues:%d no. of request queues:%d.
  ",
  		    ha->max_rsp_queues, ha->max_req_queues);
  		ql_dbg(ql_dbg_init, vha, 0x00e9,
  		    "CPU affinity mode enalbed, "
  		    "no. of response queues:%d no. of request queues:%d.
  ",
  		    ha->max_rsp_queues, ha->max_req_queues);
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
469
470
471
472
  	}
  	return 0;
  fail2:
  	qla25xx_delete_queues(vha);
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
473
474
  	destroy_workqueue(ha->wq);
  	ha->wq = NULL;
0cd33fcfb   Giridhar Malavali   [SCSI] qla2xxx: R...
475
  	vha->req = ha->req_q_map[0];
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
476
477
  fail:
  	ha->mqenable = 0;
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
478
479
480
  	kfree(ha->req_q_map);
  	kfree(ha->rsp_q_map);
  	ha->max_req_queues = ha->max_rsp_queues = 1;
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
481
482
  	return 1;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  static char *
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
484
  qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
486
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
  	static char *pci_bus_modes[] = {
  		"33", "66", "100", "133",
  	};
  	uint16_t pci_bus;
  
  	strcpy(str, "PCI");
  	pci_bus = (ha->pci_attr & (BIT_9 | BIT_10)) >> 9;
  	if (pci_bus) {
  		strcat(str, "-X (");
  		strcat(str, pci_bus_modes[pci_bus]);
  	} else {
  		pci_bus = (ha->pci_attr & BIT_8) >> 8;
  		strcat(str, " (");
  		strcat(str, pci_bus_modes[pci_bus]);
  	}
  	strcat(str, " MHz)");
  
  	return (str);
  }
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
506
  static char *
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
507
  qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str)
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
508
509
  {
  	static char *pci_bus_modes[] = { "33", "66", "100", "133", };
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
510
  	struct qla_hw_data *ha = vha->hw;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
511
  	uint32_t pci_bus;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
512

62a276f81   Bjorn Helgaas   [SCSI] qla2xxx: U...
513
  	if (pci_is_pcie(ha->pdev)) {
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
514
  		char lwstr[6];
62a276f81   Bjorn Helgaas   [SCSI] qla2xxx: U...
515
  		uint32_t lstat, lspeed, lwidth;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
516

62a276f81   Bjorn Helgaas   [SCSI] qla2xxx: U...
517
518
519
  		pcie_capability_read_dword(ha->pdev, PCI_EXP_LNKCAP, &lstat);
  		lspeed = lstat & PCI_EXP_LNKCAP_SLS;
  		lwidth = (lstat & PCI_EXP_LNKCAP_MLW) >> 4;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
520
521
  
  		strcpy(str, "PCIe (");
49300af72   Saurav Kashyap   [SCSI] qla2xxx: A...
522
523
  		switch (lspeed) {
  		case 1:
c87a0d8c8   Andrew Vasquez   [SCSI] qla2xxx: U...
524
  			strcat(str, "2.5GT/s ");
49300af72   Saurav Kashyap   [SCSI] qla2xxx: A...
525
526
  			break;
  		case 2:
c87a0d8c8   Andrew Vasquez   [SCSI] qla2xxx: U...
527
  			strcat(str, "5.0GT/s ");
49300af72   Saurav Kashyap   [SCSI] qla2xxx: A...
528
529
530
531
532
  			break;
  		case 3:
  			strcat(str, "8.0GT/s ");
  			break;
  		default:
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
533
  			strcat(str, "<unknown> ");
49300af72   Saurav Kashyap   [SCSI] qla2xxx: A...
534
535
  			break;
  		}
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
  		snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
  		strcat(str, lwstr);
  
  		return str;
  	}
  
  	strcpy(str, "PCI");
  	pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8;
  	if (pci_bus == 0 || pci_bus == 8) {
  		strcat(str, " (");
  		strcat(str, pci_bus_modes[pci_bus >> 3]);
  	} else {
  		strcat(str, "-X ");
  		if (pci_bus & BIT_2)
  			strcat(str, "Mode 2");
  		else
  			strcat(str, "Mode 1");
  		strcat(str, " (");
  		strcat(str, pci_bus_modes[pci_bus & ~BIT_2]);
  	}
  	strcat(str, " MHz)");
  
  	return str;
  }
e5f82ab83   Adrian Bunk   [SCSI] qla2xxx: m...
560
  static char *
df57cabac   Himanshu Madhani   qla2xxx: Add FDMI...
561
  qla2x00_fw_version_str(struct scsi_qla_host *vha, char *str, size_t size)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
563
  {
  	char un_str[10];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
564
  	struct qla_hw_data *ha = vha->hw;
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
565

df57cabac   Himanshu Madhani   qla2xxx: Add FDMI...
566
567
  	snprintf(str, size, "%d.%02d.%02d ", ha->fw_major_version,
  	    ha->fw_minor_version, ha->fw_subminor_version);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
  
  	if (ha->fw_attributes & BIT_9) {
  		strcat(str, "FLX");
  		return (str);
  	}
  
  	switch (ha->fw_attributes & 0xFF) {
  	case 0x7:
  		strcat(str, "EF");
  		break;
  	case 0x17:
  		strcat(str, "TP");
  		break;
  	case 0x37:
  		strcat(str, "IP");
  		break;
  	case 0x77:
  		strcat(str, "VI");
  		break;
  	default:
  		sprintf(un_str, "(%x)", ha->fw_attributes);
  		strcat(str, un_str);
  		break;
  	}
  	if (ha->fw_attributes & 0x100)
  		strcat(str, "X");
  
  	return (str);
  }
e5f82ab83   Adrian Bunk   [SCSI] qla2xxx: m...
597
  static char *
df57cabac   Himanshu Madhani   qla2xxx: Add FDMI...
598
  qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str, size_t size)
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
599
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
600
  	struct qla_hw_data *ha = vha->hw;
f0883ac6a   Andrew Vasquez   [SCSI] qla2xxx: A...
601

df57cabac   Himanshu Madhani   qla2xxx: Add FDMI...
602
  	snprintf(str, size, "%d.%02d.%02d (%x)", ha->fw_major_version,
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
603
  	    ha->fw_minor_version, ha->fw_subminor_version, ha->fw_attributes);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
604
  	return str;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
605
  }
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
606
607
  void
  qla2x00_sp_free_dma(void *vha, void *ptr)
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
608
  {
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
609
610
611
612
  	srb_t *sp = (srb_t *)ptr;
  	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
  	struct qla_hw_data *ha = sp->fcport->vha->hw;
  	void *ctx = GET_CMD_CTX_SP(sp);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
613

9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
614
615
616
  	if (sp->flags & SRB_DMA_VALID) {
  		scsi_dma_unmap(cmd);
  		sp->flags &= ~SRB_DMA_VALID;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
617
  	}
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
618

9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
619
620
621
622
623
624
625
626
  	if (sp->flags & SRB_CRC_PROT_DMA_VALID) {
  		dma_unmap_sg(&ha->pdev->dev, scsi_prot_sglist(cmd),
  		    scsi_prot_sg_count(cmd), cmd->sc_data_direction);
  		sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
  	}
  
  	if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
  		/* List assured to be having elements */
f83adb617   Quinn Tran   qla2xxx: T10-Dif:...
627
  		qla2x00_clean_dsd_pool(ha, sp, NULL);
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
628
629
630
631
632
633
634
635
636
637
638
  		sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
  	}
  
  	if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
  		dma_pool_free(ha->dl_dma_pool, ctx,
  		    ((struct crc_context *)ctx)->crc_ctx_dma);
  		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
  	}
  
  	if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
  		struct ct6_dsd *ctx1 = (struct ct6_dsd *)ctx;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
639

9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
640
641
642
643
644
645
646
647
648
649
  		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
  			ctx1->fcp_cmnd_dma);
  		list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
  		ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
  		ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
  		mempool_free(ctx1, ha->ctx_mempool);
  		ctx1 = NULL;
  	}
  
  	CMD_SP(cmd) = NULL;
b00ee7d77   Chad Dupuis   [SCSI] qla2xxx: U...
650
  	qla2x00_rel_sp(sp->fcport->vha, sp);
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
651
  }
14b06808d   Fengguang Wu   [SCSI] qla2xxx: q...
652
  static void
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  qla2x00_sp_compl(void *data, void *ptr, int res)
  {
  	struct qla_hw_data *ha = (struct qla_hw_data *)data;
  	srb_t *sp = (srb_t *)ptr;
  	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
  
  	cmd->result = res;
  
  	if (atomic_read(&sp->ref_count) == 0) {
  		ql_dbg(ql_dbg_io, sp->fcport->vha, 0x3015,
  		    "SP reference-count to ZERO -- sp=%p cmd=%p.
  ",
  		    sp, GET_CMD_SP(sp));
  		if (ql2xextended_error_logging & ql_dbg_io)
  			BUG();
  		return;
  	}
  	if (!atomic_dec_and_test(&sp->ref_count))
  		return;
  
  	qla2x00_sp_free_dma(ha, sp);
  	cmd->scsi_done(cmd);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
675
  }
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
676
677
678
  /* If we are SP1 here, we need to still take and release the host_lock as SP1
   * does not have the changes necessary to avoid taking host->host_lock.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
679
  static int
f5e3e40b3   Madhuranath Iyengar   [SCSI] qla2xxx: R...
680
  qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
681
  {
134ae0785   Madhuranath Iyengar   [SCSI] qla2xxx: U...
682
  	scsi_qla_host_t *vha = shost_priv(host);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
683
  	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
19a7b4aeb   James.Smart@Emulex.Com   [SCSI] update fc_...
684
  	struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
685
686
  	struct qla_hw_data *ha = vha->hw;
  	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
687
688
  	srb_t *sp;
  	int rval;
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
689
  	if (ha->flags.eeh_busy) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
690
  		if (ha->flags.pci_channel_io_perm_failure) {
5f28d2d7c   Saurav Kashyap   [SCSI] qla2xxx: A...
691
  			ql_dbg(ql_dbg_aer, vha, 0x9010,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
692
693
694
  			    "PCI Channel IO permanent failure, exiting "
  			    "cmd=%p.
  ", cmd);
b9b12f73d   Seokmann Ju   [SCSI] qla2xxx: C...
695
  			cmd->result = DID_NO_CONNECT << 16;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
696
  		} else {
5f28d2d7c   Saurav Kashyap   [SCSI] qla2xxx: A...
697
  			ql_dbg(ql_dbg_aer, vha, 0x9011,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
698
699
  			    "EEH_Busy, Requeuing the cmd=%p.
  ", cmd);
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
700
  			cmd->result = DID_REQUEUE << 16;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
701
  		}
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
702
703
  		goto qc24_fail_command;
  	}
19a7b4aeb   James.Smart@Emulex.Com   [SCSI] update fc_...
704
705
706
  	rval = fc_remote_port_chkready(rport);
  	if (rval) {
  		cmd->result = rval;
5f28d2d7c   Saurav Kashyap   [SCSI] qla2xxx: A...
707
  		ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3003,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
708
709
710
  		    "fc_remote_port_chkready failed for cmd=%p, rval=0x%x.
  ",
  		    cmd, rval);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
711
712
  		goto qc24_fail_command;
  	}
bad750028   Arun Easi   [SCSI] qla2xxx: T...
713
714
  	if (!vha->flags.difdix_supported &&
  		scsi_get_prot_op(cmd) != SCSI_PROT_NORMAL) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
715
716
717
718
  			ql_dbg(ql_dbg_io, vha, 0x3004,
  			    "DIF Cap not reg, fail DIF capable cmd's:%p.
  ",
  			    cmd);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
719
720
721
  			cmd->result = DID_NO_CONNECT << 16;
  			goto qc24_fail_command;
  	}
aa651be83   Chad Dupuis   [SCSI] qla2xxx: A...
722
723
724
725
726
  
  	if (!fcport) {
  		cmd->result = DID_NO_CONNECT << 16;
  		goto qc24_fail_command;
  	}
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
727
728
  	if (atomic_read(&fcport->state) != FCS_ONLINE) {
  		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
38170fa8e   Giridhar Malavali   [SCSI] qla2xxx: A...
729
  			atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
730
731
732
733
734
  			ql_dbg(ql_dbg_io, vha, 0x3005,
  			    "Returning DNC, fcport_state=%d loop_state=%d.
  ",
  			    atomic_read(&fcport->state),
  			    atomic_read(&base_vha->loop_state));
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
735
736
737
  			cmd->result = DID_NO_CONNECT << 16;
  			goto qc24_fail_command;
  		}
7b594131c   Mike Christie   [SCSI] qla2xxx: r...
738
  		goto qc24_target_busy;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
739
  	}
e05fe2924   Chad Dupuis   qla2xxx: Honor FC...
740
741
742
743
  	/*
  	 * Return target busy if we've received a non-zero retry_delay_timer
  	 * in a FCP_RSP.
  	 */
975f7d467   Bruno Prémont   qla2xxx: fix busy...
744
745
746
  	if (fcport->retry_delay_timestamp == 0) {
  		/* retry delay not set */
  	} else if (time_after(jiffies, fcport->retry_delay_timestamp))
e05fe2924   Chad Dupuis   qla2xxx: Honor FC...
747
748
749
  		fcport->retry_delay_timestamp = 0;
  	else
  		goto qc24_target_busy;
b00ee7d77   Chad Dupuis   [SCSI] qla2xxx: U...
750
  	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
50280c014   Chad Dupuis   [SCSI] Revert "ql...
751
  	if (!sp)
f5e3e40b3   Madhuranath Iyengar   [SCSI] qla2xxx: R...
752
  		goto qc24_host_busy;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
753

9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
754
755
756
757
758
759
  	sp->u.scmd.cmd = cmd;
  	sp->type = SRB_SCSI_CMD;
  	atomic_set(&sp->ref_count, 1);
  	CMD_SP(cmd) = (void *)sp;
  	sp->free = qla2x00_sp_free_dma;
  	sp->done = qla2x00_sp_compl;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
760
  	rval = ha->isp_ops->start_scsi(sp);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
761
  	if (rval != QLA_SUCCESS) {
53016ed32   Chad Dupuis   [SCSI] qla2xxx: M...
762
  		ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3013,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
763
764
  		    "Start scsi failed rval=%d for cmd=%p.
  ", rval, cmd);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
765
  		goto qc24_host_busy_free_sp;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
766
  	}
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
767

fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
768
769
770
  	return 0;
  
  qc24_host_busy_free_sp:
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
771
  	qla2x00_sp_free_dma(ha, sp);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
772

f5e3e40b3   Madhuranath Iyengar   [SCSI] qla2xxx: R...
773
  qc24_host_busy:
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
774
  	return SCSI_MLQUEUE_HOST_BUSY;
7b594131c   Mike Christie   [SCSI] qla2xxx: r...
775
776
  qc24_target_busy:
  	return SCSI_MLQUEUE_TARGET_BUSY;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
777
  qc24_fail_command:
f5e3e40b3   Madhuranath Iyengar   [SCSI] qla2xxx: R...
778
  	cmd->scsi_done(cmd);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
779
780
781
  
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
783
784
785
786
787
  /*
   * qla2x00_eh_wait_on_command
   *    Waits for the command to be returned by the Firmware for some
   *    max time.
   *
   * Input:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
788
   *    cmd = Scsi Command to wait on.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
789
790
791
792
793
794
   *
   * Return:
   *    Not Found : 0
   *    Found : 1
   */
  static int
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
795
  qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  {
fe74c71f6   Andrew Vasquez   [SCSI] qla2xxx: R...
797
  #define ABORT_POLLING_PERIOD	1000
478c3b03c   Chad Dupuis   qla2xxx: Reduce t...
798
  #define ABORT_WAIT_ITER		((2 * 1000) / (ABORT_POLLING_PERIOD))
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
799
  	unsigned long wait_iter = ABORT_WAIT_ITER;
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
800
801
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
  	struct qla_hw_data *ha = vha->hw;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
802
  	int ret = QLA_SUCCESS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
803

858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
804
  	if (unlikely(pci_channel_offline(ha->pdev)) || ha->flags.eeh_busy) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
805
806
807
  		ql_dbg(ql_dbg_taskm, vha, 0x8005,
  		    "Return:eh_wait.
  ");
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
808
809
  		return ret;
  	}
d970432c4   Lalit Chandivade   [SCSI] qla2xxx: C...
810
  	while (CMD_SP(cmd) && wait_iter--) {
fe74c71f6   Andrew Vasquez   [SCSI] qla2xxx: R...
811
  		msleep(ABORT_POLLING_PERIOD);
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
812
813
814
  	}
  	if (CMD_SP(cmd))
  		ret = QLA_FUNCTION_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
816
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
817
818
819
820
  }
  
  /*
   * qla2x00_wait_for_hba_online
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
821
   *    Wait till the HBA is online after going through
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
824
825
826
   *    <= MAX_RETRIES_OF_ISP_ABORT  or
   *    finally HBA is disabled ie marked offline
   *
   * Input:
   *     ha - pointer to host adapter structure
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
827
828
   *
   * Note:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
831
832
833
834
835
   *    Does context switching-Release SPIN_LOCK
   *    (if any) before calling this routine.
   *
   * Return:
   *    Success (Adapter is online) : 0
   *    Failed  (Adapter is offline/disabled) : 1
   */
854165f42   Andrew Vasquez   [SCSI] qla2xxx: A...
836
  int
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
837
  qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
838
  {
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
839
840
  	int		return_status;
  	unsigned long	wait_online;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
841
842
  	struct qla_hw_data *ha = vha->hw;
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
843

fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
844
  	wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
845
846
847
848
  	while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
  	    test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
  	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
  	    ha->dpc_active) && time_before(jiffies, wait_online)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
850
851
  
  		msleep(1000);
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
852
  	if (base_vha->flags.online)
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
853
  		return_status = QLA_SUCCESS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
  	else
  		return_status = QLA_FUNCTION_FAILED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
857
  	return (return_status);
  }
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
858
  /*
638a1a01d   Sawan Chandak   qla2xxx: Delay dr...
859
860
   * qla2x00_wait_for_hba_ready
   * Wait till the HBA is ready before doing driver unload
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
861
862
863
864
865
866
867
868
   *
   * Input:
   *     ha - pointer to host adapter structure
   *
   * Note:
   *    Does context switching-Release SPIN_LOCK
   *    (if any) before calling this routine.
   *
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
869
   */
638a1a01d   Sawan Chandak   qla2xxx: Delay dr...
870
871
  static void
  qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha)
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
872
  {
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
873
  	struct qla_hw_data *ha = vha->hw;
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
874

9d35894d3   Sawan Chandak   qla2xxx: Add fix ...
875
876
877
878
  	while (((qla2x00_reset_active(vha)) || ha->dpc_active ||
  	    ha->flags.mbox_busy) ||
  		test_bit(FX00_RESET_RECOVERY, &vha->dpc_flags) ||
  		test_bit(FX00_TARGET_SCAN, &vha->dpc_flags))
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
879
  		msleep(1000);
86fbee86e   Lalit Chandivade   [SCSI] qla2xxx: e...
880
  }
2533cf671   Lalit Chandivade   [SCSI] qla2xxx: C...
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
  int
  qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
  {
  	int		return_status;
  	unsigned long	wait_reset;
  	struct qla_hw_data *ha = vha->hw;
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
  
  	wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
  	while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
  	    test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
  	    test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
  	    ha->dpc_active) && time_before(jiffies, wait_reset)) {
  
  		msleep(1000);
  
  		if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
  		    ha->flags.chip_reset_done)
  			break;
  	}
  	if (ha->flags.chip_reset_done)
  		return_status = QLA_SUCCESS;
  	else
  		return_status = QLA_FUNCTION_FAILED;
  
  	return return_status;
  }
083a469db   Giridhar Malavali   [SCSI] qla2xxx: C...
908
909
910
911
912
  static void
  sp_get(struct srb *sp)
  {
  	atomic_inc(&sp->ref_count);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
914
915
916
917
918
919
920
921
922
923
924
925
  /**************************************************************************
  * qla2xxx_eh_abort
  *
  * Description:
  *    The abort function will abort the specified command.
  *
  * Input:
  *    cmd = Linux SCSI command packet to be aborted.
  *
  * Returns:
  *    Either SUCCESS or FAILED.
  *
  * Note:
2ea002025   Michael Reed   [SCSI] qla2xxx: C...
926
  *    Only return FAILED if command not returned by firmware.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
927
  **************************************************************************/
e5f82ab83   Adrian Bunk   [SCSI] qla2xxx: m...
928
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
930
  qla2xxx_eh_abort(struct scsi_cmnd *cmd)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
931
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
932
  	srb_t *sp;
4e98d3b8a   Andrew Vasquez   [SCSI] qla2xxx: C...
933
  	int ret;
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
934
935
  	unsigned int id;
  	uint64_t lun;
18e144d32   Andrew Vasquez   [SCSI] qla2xxx: f...
936
  	unsigned long flags;
f934c9d08   Chad Dupuis   qla2xxx: Avoid es...
937
  	int rval, wait = 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
938
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
940
  	if (!CMD_SP(cmd))
2ea002025   Michael Reed   [SCSI] qla2xxx: C...
941
  		return SUCCESS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942

4e98d3b8a   Andrew Vasquez   [SCSI] qla2xxx: C...
943
944
945
946
  	ret = fc_block_scsi_eh(cmd);
  	if (ret != 0)
  		return ret;
  	ret = SUCCESS;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
947
948
  	id = cmd->device->id;
  	lun = cmd->device->lun;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
949

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
950
  	spin_lock_irqsave(&ha->hardware_lock, flags);
170babc37   Mike Christie   [SCSI] qla2xxx: D...
951
952
953
954
955
  	sp = (srb_t *) CMD_SP(cmd);
  	if (!sp) {
  		spin_unlock_irqrestore(&ha->hardware_lock, flags);
  		return SUCCESS;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
956

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
957
  	ql_dbg(ql_dbg_taskm, vha, 0x8002,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
958
959
  	    "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
960
  	    vha->host_no, id, lun, sp, cmd);
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
961

170babc37   Mike Christie   [SCSI] qla2xxx: D...
962
963
  	/* Get a reference to the sp and drop the lock.*/
  	sp_get(sp);
083a469db   Giridhar Malavali   [SCSI] qla2xxx: C...
964

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
965
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
f934c9d08   Chad Dupuis   qla2xxx: Avoid es...
966
967
968
969
970
971
972
973
974
975
976
  	rval = ha->isp_ops->abort_command(sp);
  	if (rval) {
  		if (rval == QLA_FUNCTION_PARAMETER_ERROR) {
  			/*
  			 * Decrement the ref_count since we can't find the
  			 * command
  			 */
  			atomic_dec(&sp->ref_count);
  			ret = SUCCESS;
  		} else
  			ret = FAILED;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
977
  		ql_dbg(ql_dbg_taskm, vha, 0x8003,
f934c9d08   Chad Dupuis   qla2xxx: Avoid es...
978
979
  		    "Abort command mbx failed cmd=%p, rval=%x.
  ", cmd, rval);
170babc37   Mike Christie   [SCSI] qla2xxx: D...
980
  	} else {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
981
  		ql_dbg(ql_dbg_taskm, vha, 0x8004,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
982
983
  		    "Abort command mbx success cmd=%p.
  ", cmd);
170babc37   Mike Christie   [SCSI] qla2xxx: D...
984
985
  		wait = 1;
  	}
759420649   Saurav Kashyap   [SCSI] qla2xxx: A...
986
987
  
  	spin_lock_irqsave(&ha->hardware_lock, flags);
f934c9d08   Chad Dupuis   qla2xxx: Avoid es...
988
989
990
991
992
993
  	/*
  	 * Clear the slot in the oustanding_cmds array if we can't find the
  	 * command to reclaim the resources.
  	 */
  	if (rval == QLA_FUNCTION_PARAMETER_ERROR)
  		vha->req->outstanding_cmds[sp->handle] = NULL;
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
994
  	sp->done(ha, sp, 0);
759420649   Saurav Kashyap   [SCSI] qla2xxx: A...
995
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
996

bc91ade9b   Chad Dupuis   [SCSI] qla2xxx: D...
997
998
999
  	/* Did the command return during mailbox execution? */
  	if (ret == FAILED && !CMD_SP(cmd))
  		ret = SUCCESS;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1000
  	/* Wait for the command to be returned. */
2ea002025   Michael Reed   [SCSI] qla2xxx: C...
1001
  	if (wait) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1002
  		if (qla2x00_eh_wait_on_command(cmd) != QLA_SUCCESS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1003
  			ql_log(ql_log_warn, vha, 0x8006,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1004
1005
  			    "Abort handler timed out cmd=%p.
  ", cmd);
2ea002025   Michael Reed   [SCSI] qla2xxx: C...
1006
  			ret = FAILED;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1007
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1008
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1010
  	ql_log(ql_log_info, vha, 0x801c,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1011
1012
  	    "Abort command issued nexus=%ld:%d:%llu --  %d %x.
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1013
  	    vha->host_no, id, lun, wait, ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1015
1016
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017

4d78c973e   Giridhar Malavali   [SCSI] qla2xxx: R...
1018
  int
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1019
  qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1020
  	uint64_t l, enum nexus_wait_type type)
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1021
  {
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1022
  	int cnt, match, status;
18e144d32   Andrew Vasquez   [SCSI] qla2xxx: f...
1023
  	unsigned long flags;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1024
  	struct qla_hw_data *ha = vha->hw;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1025
  	struct req_que *req;
4d78c973e   Giridhar Malavali   [SCSI] qla2xxx: R...
1026
  	srb_t *sp;
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1027
  	struct scsi_cmnd *cmd;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1028

523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1029
  	status = QLA_SUCCESS;
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1030

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1031
  	spin_lock_irqsave(&ha->hardware_lock, flags);
67c2e93ae   Anirban Chakraborty   [SCSI] qla2xxx: R...
1032
  	req = vha->req;
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1033
  	for (cnt = 1; status == QLA_SUCCESS &&
8d93f5502   Chad Dupuis   [SCSI] qla2xxx: D...
1034
  		cnt < req->num_outstanding_cmds; cnt++) {
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1035
1036
  		sp = req->outstanding_cmds[cnt];
  		if (!sp)
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1037
  			continue;
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1038
  		if (sp->type != SRB_SCSI_CMD)
cf53b069f   Andrew Vasquez   [SCSI] qla2xxx: G...
1039
  			continue;
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1040
1041
1042
  		if (vha->vp_idx != sp->fcport->vha->vp_idx)
  			continue;
  		match = 0;
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1043
  		cmd = GET_CMD_SP(sp);
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1044
1045
1046
1047
1048
  		switch (type) {
  		case WAIT_HOST:
  			match = 1;
  			break;
  		case WAIT_TARGET:
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1049
  			match = cmd->device->id == t;
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1050
1051
  			break;
  		case WAIT_LUN:
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1052
1053
  			match = (cmd->device->id == t &&
  				cmd->device->lun == l);
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1054
  			break;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1055
  		}
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1056
1057
1058
1059
  		if (!match)
  			continue;
  
  		spin_unlock_irqrestore(&ha->hardware_lock, flags);
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1060
  		status = qla2x00_eh_wait_on_command(cmd);
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
1061
  		spin_lock_irqsave(&ha->hardware_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1062
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1063
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1064
1065
  
  	return status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1066
  }
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1067
1068
1069
1070
1071
1072
  static char *reset_errors[] = {
  	"HBA not online",
  	"HBA not ready",
  	"Task management failed",
  	"Waiting for command completions",
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1073

e5f82ab83   Adrian Bunk   [SCSI] qla2xxx: m...
1074
  static int
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1075
  __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1076
      struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, uint64_t, int))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1077
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1078
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
1079
  	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1080
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1081

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1082
  	if (!fcport) {
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1083
  		return FAILED;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1084
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1085

4e98d3b8a   Andrew Vasquez   [SCSI] qla2xxx: C...
1086
1087
1088
  	err = fc_block_scsi_eh(cmd);
  	if (err != 0)
  		return err;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1089
  	ql_log(ql_log_info, vha, 0x8009,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1090
1091
  	    "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.
  ", name, vha->host_no,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1092
  	    cmd->device->id, cmd->device->lun, cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093

523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1094
  	err = 0;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1095
1096
1097
1098
  	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
  		ql_log(ql_log_warn, vha, 0x800a,
  		    "Wait for hba online failed for cmd=%p.
  ", cmd);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1099
  		goto eh_reset_failed;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1100
  	}
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1101
  	err = 2;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1102
  	if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1103
1104
1105
1106
  		!= QLA_SUCCESS) {
  		ql_log(ql_log_warn, vha, 0x800c,
  		    "do_reset failed for cmd=%p.
  ", cmd);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1107
  		goto eh_reset_failed;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1108
  	}
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1109
  	err = 3;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1110
  	if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1111
1112
  	    cmd->device->lun, type) != QLA_SUCCESS) {
  		ql_log(ql_log_warn, vha, 0x800d,
d6a03581a   Masanari Iida   [SCSI] qla2xxx: F...
1113
1114
  		    "wait for pending cmds failed for cmd=%p.
  ", cmd);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1115
  		goto eh_reset_failed;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1116
  	}
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1117

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1118
  	ql_log(ql_log_info, vha, 0x800e,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1119
1120
  	    "%s RESET SUCCEEDED nexus:%ld:%d:%llu cmd=%p.
  ", name,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1121
  	    vha->host_no, cmd->device->id, cmd->device->lun, cmd);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1122
1123
  
  	return SUCCESS;
4d78c973e   Giridhar Malavali   [SCSI] qla2xxx: R...
1124
  eh_reset_failed:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1125
  	ql_log(ql_log_info, vha, 0x800f,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1126
1127
  	    "%s RESET FAILED: %s nexus=%ld:%d:%llu cmd=%p.
  ", name,
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1128
1129
  	    reset_errors[err], vha->host_no, cmd->device->id, cmd->device->lun,
  	    cmd);
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1130
1131
  	return FAILED;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1132

523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1133
1134
1135
  static int
  qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1136
1137
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138

523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1139
1140
  	return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
  	    ha->isp_ops->lun_reset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1141
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1142
  static int
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1143
  qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1144
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1145
1146
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1147

523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1148
1149
  	return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
  	    ha->isp_ops->target_reset);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1150
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  /**************************************************************************
  * qla2xxx_eh_bus_reset
  *
  * Description:
  *    The bus reset function will reset the bus and abort any executing
  *    commands.
  *
  * Input:
  *    cmd = Linux SCSI command packet of the command that cause the
  *          bus reset.
  *
  * Returns:
  *    SUCCESS/FAILURE (defined as macro in scsi.h).
  *
  **************************************************************************/
e5f82ab83   Adrian Bunk   [SCSI] qla2xxx: m...
1166
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1167
1168
  qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1169
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
1170
  	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
1171
  	int ret = FAILED;
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1172
1173
  	unsigned int id;
  	uint64_t lun;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1174

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1175
1176
  	id = cmd->device->id;
  	lun = cmd->device->lun;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1177

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1178
  	if (!fcport) {
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1179
  		return ret;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1180
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1181

4e98d3b8a   Andrew Vasquez   [SCSI] qla2xxx: C...
1182
1183
1184
1185
  	ret = fc_block_scsi_eh(cmd);
  	if (ret != 0)
  		return ret;
  	ret = FAILED;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1186
  	ql_log(ql_log_info, vha, 0x8012,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1187
1188
  	    "BUS RESET ISSUED nexus=%ld:%d:%llu.
  ", vha->host_no, id, lun);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1189

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1190
  	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1191
1192
1193
  		ql_log(ql_log_fatal, vha, 0x8013,
  		    "Wait for hba online failed board disabled.
  ");
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1194
  		goto eh_bus_reset_done;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1195
  	}
ad537689c   Saurav Kashyap   [SCSI] qla2xxx: R...
1196
1197
  	if (qla2x00_loop_reset(vha) == QLA_SUCCESS)
  		ret = SUCCESS;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1198
1199
  	if (ret == FAILED)
  		goto eh_bus_reset_done;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1200

9a41a62b7   Andrew Vasquez   [SCSI] qla2xxx: r...
1201
  	/* Flush outstanding commands. */
4d78c973e   Giridhar Malavali   [SCSI] qla2xxx: R...
1202
  	if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) !=
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1203
1204
1205
1206
  	    QLA_SUCCESS) {
  		ql_log(ql_log_warn, vha, 0x8014,
  		    "Wait for pending commands failed.
  ");
9a41a62b7   Andrew Vasquez   [SCSI] qla2xxx: r...
1207
  		ret = FAILED;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1208
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1209

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1210
  eh_bus_reset_done:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1211
  	ql_log(ql_log_warn, vha, 0x802b,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1212
1213
  	    "BUS RESET %s nexus=%ld:%d:%llu.
  ",
d6a03581a   Masanari Iida   [SCSI] qla2xxx: F...
1214
  	    (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1215

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1216
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
  }
  
  /**************************************************************************
  * qla2xxx_eh_host_reset
  *
  * Description:
  *    The reset function will reset the Adapter.
  *
  * Input:
  *      cmd = Linux SCSI command packet of the command that cause the
  *            adapter reset.
  *
  * Returns:
  *      Either SUCCESS or FAILED.
  *
  * Note:
  **************************************************************************/
e5f82ab83   Adrian Bunk   [SCSI] qla2xxx: m...
1234
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1235
1236
  qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1237
  	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1238
  	struct qla_hw_data *ha = vha->hw;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
1239
  	int ret = FAILED;
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1240
1241
  	unsigned int id;
  	uint64_t lun;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1242
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1243

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1244
1245
  	id = cmd->device->id;
  	lun = cmd->device->lun;
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1246

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1247
  	ql_log(ql_log_info, vha, 0x8018,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1248
1249
  	    "ADAPTER RESET ISSUED nexus=%ld:%d:%llu.
  ", vha->host_no, id, lun);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1250

63ee7072b   Chad Dupuis   qla2xxx: Remove w...
1251
1252
1253
1254
1255
  	/*
  	 * No point in issuing another reset if one is active.  Also do not
  	 * attempt a reset if we are updating flash.
  	 */
  	if (qla2x00_reset_active(vha) || ha->optrom_state != QLA_SWAITING)
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1256
  		goto eh_host_reset_lock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1258
1259
  	if (vha != base_vha) {
  		if (qla2x00_vp_abort_isp(vha))
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1260
  			goto eh_host_reset_lock;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1261
  	} else {
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1262
  		if (IS_P3P_TYPE(vha->hw)) {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1263
1264
1265
1266
1267
1268
1269
  			if (!qla82xx_fcoe_ctx_reset(vha)) {
  				/* Ctx reset success */
  				ret = SUCCESS;
  				goto eh_host_reset_lock;
  			}
  			/* fall thru if ctx reset failed */
  		}
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
1270
1271
  		if (ha->wq)
  			flush_workqueue(ha->wq);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1272
  		set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1273
  		if (ha->isp_ops->abort_isp(base_vha)) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1274
1275
1276
  			clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
  			/* failed. schedule dpc to try */
  			set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1277
1278
1279
1280
  			if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
  				ql_log(ql_log_warn, vha, 0x802a,
  				    "wait for hba online failed.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1281
  				goto eh_host_reset_lock;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1282
  			}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1283
1284
  		}
  		clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
1285
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1286

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1287
  	/* Waiting for command to be returned to OS.*/
4d78c973e   Giridhar Malavali   [SCSI] qla2xxx: R...
1288
  	if (qla2x00_eh_wait_for_pending_commands(vha, 0, 0, WAIT_HOST) ==
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1289
  		QLA_SUCCESS)
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1290
  		ret = SUCCESS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1291

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1292
  eh_host_reset_lock:
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1293
  	ql_log(ql_log_info, vha, 0x8017,
9cb78c16f   Hannes Reinecke   scsi: use 64-bit ...
1294
1295
  	    "ADAPTER RESET %s nexus=%ld:%d:%llu.
  ",
cfb0919c1   Chad Dupuis   [SCSI] qla2xxx: U...
1296
  	    (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1297

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1298
1299
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
  
  /*
  * qla2x00_loop_reset
  *      Issue loop reset.
  *
  * Input:
  *      ha = adapter block pointer.
  *
  * Returns:
  *      0 = success
  */
a4722cf24   Andrew Vasquez   [SCSI] qla2xxx: D...
1311
  int
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1312
  qla2x00_loop_reset(scsi_qla_host_t *vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1313
  {
0c8c39af1   Andrew Vasquez   [SCSI] qla2xxx: C...
1314
  	int ret;
bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
1315
  	struct fc_port *fcport;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1316
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1317

5854771e3   Armen Baloyan   [SCSI] qla2xxx: A...
1318
1319
1320
  	if (IS_QLAFX00(ha)) {
  		return qlafx00_loop_reset(vha);
  	}
f4c496c1f   Giridhar Malavali   [SCSI] qla2xxx: O...
1321
  	if (ql2xtargetreset == 1 && ha->flags.enable_target_reset) {
55e5ed273   Andrew Vasquez   [SCSI] qla2xxx: C...
1322
1323
1324
1325
1326
1327
  		list_for_each_entry(fcport, &vha->vp_fcports, list) {
  			if (fcport->port_type != FCT_TARGET)
  				continue;
  
  			ret = ha->isp_ops->target_reset(fcport, 0, 0);
  			if (ret != QLA_SUCCESS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1328
  				ql_dbg(ql_dbg_taskm, vha, 0x802c,
5854771e3   Armen Baloyan   [SCSI] qla2xxx: A...
1329
  				    "Bus Reset failed: Reset=%d "
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1330
1331
  				    "d_id=%x.
  ", ret, fcport->d_id.b24);
55e5ed273   Andrew Vasquez   [SCSI] qla2xxx: C...
1332
1333
1334
  			}
  		}
  	}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1335

6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
1336
  	if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) {
0b7e7c533   Andrew Vasquez   [SCSI] qla2xxx: C...
1337
1338
1339
  		atomic_set(&vha->loop_state, LOOP_DOWN);
  		atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
  		qla2x00_mark_all_devices_lost(vha, 0);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1340
  		ret = qla2x00_full_login_lip(vha);
0c8c39af1   Andrew Vasquez   [SCSI] qla2xxx: C...
1341
  		if (ret != QLA_SUCCESS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1342
1343
1344
  			ql_dbg(ql_dbg_taskm, vha, 0x802d,
  			    "full_login_lip=%d.
  ", ret);
749af3d54   Anirban Chakraborty   [SCSI] qla2xxx: C...
1345
  		}
0c8c39af1   Andrew Vasquez   [SCSI] qla2xxx: C...
1346
  	}
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
1347
  	if (ha->flags.enable_lip_reset) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1348
  		ret = qla2x00_lip_reset(vha);
ad537689c   Saurav Kashyap   [SCSI] qla2xxx: R...
1349
  		if (ret != QLA_SUCCESS)
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
1350
1351
1352
  			ql_dbg(ql_dbg_taskm, vha, 0x802e,
  			    "lip_reset failed (%d).
  ", ret);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1353
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1354
  	/* Issue marker command only when we are going to start the I/O */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1355
  	vha->marker_needed = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1356

0c8c39af1   Andrew Vasquez   [SCSI] qla2xxx: C...
1357
  	return QLA_SUCCESS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1358
  }
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
1359
  void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1360
  qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
1361
  {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1362
  	int que, cnt;
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
1363
1364
  	unsigned long flags;
  	srb_t *sp;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1365
  	struct qla_hw_data *ha = vha->hw;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1366
  	struct req_que *req;
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
1367

c0cb44967   Arun Easi   qla2xxx: Add Host...
1368
  	qlt_host_reset_handler(ha);
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
1369
  	spin_lock_irqsave(&ha->hardware_lock, flags);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1370
  	for (que = 0; que < ha->max_req_queues; que++) {
29bdccbee   Anirban Chakraborty   [SCSI] qla2xxx: F...
1371
  		req = ha->req_q_map[que];
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1372
1373
  		if (!req)
  			continue;
8d93f5502   Chad Dupuis   [SCSI] qla2xxx: D...
1374
1375
1376
  		if (!req->outstanding_cmds)
  			continue;
  		for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1377
  			sp = req->outstanding_cmds[cnt];
e612d4659   Andrew Vasquez   [SCSI] qla2xxx: C...
1378
  			if (sp) {
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1379
  				req->outstanding_cmds[cnt] = NULL;
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
1380
  				sp->done(vha, sp, res);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
1381
  			}
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
1382
1383
1384
1385
  		}
  	}
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
  }
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1386
1387
  static int
  qla2xxx_slave_alloc(struct scsi_device *sdev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1388
  {
bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
1389
  	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390

19a7b4aeb   James.Smart@Emulex.Com   [SCSI] update fc_...
1391
  	if (!rport || fc_remote_port_chkready(rport))
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1392
  		return -ENXIO;
bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
1393

19a7b4aeb   James.Smart@Emulex.Com   [SCSI] update fc_...
1394
  	sdev->hostdata = *(fc_port_t **)rport->dd_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1395

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1396
1397
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1398

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1399
1400
1401
  static int
  qla2xxx_slave_configure(struct scsi_device *sdev)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1402
  	scsi_qla_host_t *vha = shost_priv(sdev->host);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
1403
  	struct req_que *req = vha->req;
8482e118a   Andrew Vasquez   [PATCH] qla2xxx: ...
1404

9e522cd8f   Arun Easi   [SCSI] qla2xxx: T...
1405
1406
  	if (IS_T10_PI_CAPABLE(vha->hw))
  		blk_queue_update_dma_alignment(sdev->request_queue, 0x7);
db5ed4dfd   Christoph Hellwig   scsi: drop reason...
1407
  	scsi_change_queue_depth(sdev, req->max_q_depth);
f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1408
1409
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1410

f4f051ebb   Andrew Vasquez   [PATCH] qla2xxx: ...
1411
1412
1413
1414
  static void
  qla2xxx_slave_destroy(struct scsi_device *sdev)
  {
  	sdev->hostdata = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
  }
  
  /**
   * qla2x00_config_dma_addressing() - Configure OS DMA addressing method.
   * @ha: HA context
   *
   * At exit, the @ha's flags.enable_64bit_addressing set to indicated
   * supported addressing method.
   */
  static void
53303c42d   Andrew Vasquez   [SCSI] qla2xxx: C...
1425
  qla2x00_config_dma_addressing(struct qla_hw_data *ha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1426
  {
7524f9b9e   Andrew Vasquez   [SCSI] qla2xxx: U...
1427
  	/* Assume a 32bit DMA mask. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
  	ha->flags.enable_64bit_addressing = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1429

6a35528a8   Yang Hongyang   dma-mapping: repl...
1430
  	if (!dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(64))) {
7524f9b9e   Andrew Vasquez   [SCSI] qla2xxx: U...
1431
1432
  		/* Any upper-dword bits set? */
  		if (MSD(dma_get_required_mask(&ha->pdev->dev)) &&
6a35528a8   Yang Hongyang   dma-mapping: repl...
1433
  		    !pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(64))) {
7524f9b9e   Andrew Vasquez   [SCSI] qla2xxx: U...
1434
  			/* Ok, a 64bit DMA mask is applicable. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1435
  			ha->flags.enable_64bit_addressing = 1;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1436
1437
  			ha->isp_ops->calc_req_entries = qla2x00_calc_iocbs_64;
  			ha->isp_ops->build_iocbs = qla2x00_build_scsi_iocbs_64;
7524f9b9e   Andrew Vasquez   [SCSI] qla2xxx: U...
1438
  			return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1439
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1440
  	}
7524f9b9e   Andrew Vasquez   [SCSI] qla2xxx: U...
1441

284901a90   Yang Hongyang   dma-mapping: repl...
1442
1443
  	dma_set_mask(&ha->pdev->dev, DMA_BIT_MASK(32));
  	pci_set_consistent_dma_mask(ha->pdev, DMA_BIT_MASK(32));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1444
  }
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1445
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1446
  qla2x00_enable_intrs(struct qla_hw_data *ha)
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
  {
  	unsigned long flags = 0;
  	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
  
  	spin_lock_irqsave(&ha->hardware_lock, flags);
  	ha->interrupts_on = 1;
  	/* enable risc and host interrupts */
  	WRT_REG_WORD(&reg->ictrl, ICR_EN_INT | ICR_EN_RISC);
  	RD_REG_WORD(&reg->ictrl);
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
  
  }
  
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1461
  qla2x00_disable_intrs(struct qla_hw_data *ha)
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
  {
  	unsigned long flags = 0;
  	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
  
  	spin_lock_irqsave(&ha->hardware_lock, flags);
  	ha->interrupts_on = 0;
  	/* disable risc and host interrupts */
  	WRT_REG_WORD(&reg->ictrl, 0);
  	RD_REG_WORD(&reg->ictrl);
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
  }
  
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1475
  qla24xx_enable_intrs(struct qla_hw_data *ha)
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
  {
  	unsigned long flags = 0;
  	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
  
  	spin_lock_irqsave(&ha->hardware_lock, flags);
  	ha->interrupts_on = 1;
  	WRT_REG_DWORD(&reg->ictrl, ICRX_EN_RISC_INT);
  	RD_REG_DWORD(&reg->ictrl);
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
  }
  
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1488
  qla24xx_disable_intrs(struct qla_hw_data *ha)
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1489
1490
1491
  {
  	unsigned long flags = 0;
  	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
124f85e6c   Andrew Vasquez   [SCSI] qla2xxx: D...
1492
1493
  	if (IS_NOPOLLING_TYPE(ha))
  		return;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1494
1495
1496
1497
1498
1499
  	spin_lock_irqsave(&ha->hardware_lock, flags);
  	ha->interrupts_on = 0;
  	WRT_REG_DWORD(&reg->ictrl, 0);
  	RD_REG_DWORD(&reg->ictrl);
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
  }
706f457d0   Giridhar Malavali   [SCSI] qla2xxx: A...
1500
1501
1502
1503
1504
1505
  static int
  qla2x00_iospace_config(struct qla_hw_data *ha)
  {
  	resource_size_t pio;
  	uint16_t msix;
  	int cpus;
706f457d0   Giridhar Malavali   [SCSI] qla2xxx: A...
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
  	if (pci_request_selected_regions(ha->pdev, ha->bars,
  	    QLA2XXX_DRIVER_NAME)) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0011,
  		    "Failed to reserve PIO/MMIO regions (%s), aborting.
  ",
  		    pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  	if (!(ha->bars & 1))
  		goto skip_pio;
  
  	/* We only need PIO for Flash operations on ISP2312 v2 chips. */
  	pio = pci_resource_start(ha->pdev, 0);
  	if (pci_resource_flags(ha->pdev, 0) & IORESOURCE_IO) {
  		if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
  			ql_log_pci(ql_log_warn, ha->pdev, 0x0012,
  			    "Invalid pci I/O region size (%s).
  ",
  			    pci_name(ha->pdev));
  			pio = 0;
  		}
  	} else {
  		ql_log_pci(ql_log_warn, ha->pdev, 0x0013,
  		    "Region #0 no a PIO resource (%s).
  ",
  		    pci_name(ha->pdev));
  		pio = 0;
  	}
  	ha->pio_address = pio;
  	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0014,
  	    "PIO address=%llu.
  ",
  	    (unsigned long long)ha->pio_address);
  
  skip_pio:
  	/* Use MMIO operations for all accesses. */
  	if (!(pci_resource_flags(ha->pdev, 1) & IORESOURCE_MEM)) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0015,
  		    "Region #1 not an MMIO resource (%s), aborting.
  ",
  		    pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  	if (pci_resource_len(ha->pdev, 1) < MIN_IOBASE_LEN) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0016,
  		    "Invalid PCI mem region size (%s), aborting.
  ",
  		    pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  
  	ha->iobase = ioremap(pci_resource_start(ha->pdev, 1), MIN_IOBASE_LEN);
  	if (!ha->iobase) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0017,
  		    "Cannot remap MMIO (%s), aborting.
  ",
  		    pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  
  	/* Determine queue resources */
  	ha->max_req_queues = ha->max_rsp_queues = 1;
  	if ((ql2xmaxqueues <= 1 && !ql2xmultique_tag) ||
  		(ql2xmaxqueues > 1 && ql2xmultique_tag) ||
  		(!IS_QLA25XX(ha) && !IS_QLA81XX(ha)))
  		goto mqiobase_exit;
  
  	ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 3),
  			pci_resource_len(ha->pdev, 3));
  	if (ha->mqiobase) {
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0018,
  		    "MQIO Base=%p.
  ", ha->mqiobase);
  		/* Read MSIX vector size of the board */
  		pci_read_config_word(ha->pdev, QLA_PCI_MSIX_CONTROL, &msix);
  		ha->msix_count = msix;
  		/* Max queues are bounded by available msix vectors */
  		/* queue 0 uses two msix vectors */
  		if (ql2xmultique_tag) {
  			cpus = num_online_cpus();
  			ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
  				(cpus + 1) : (ha->msix_count - 1);
  			ha->max_req_queues = 2;
  		} else if (ql2xmaxqueues > 1) {
  			ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
  			    QLA_MQ_SIZE : ql2xmaxqueues;
  			ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc008,
  			    "QoS mode set, max no of request queues:%d.
  ",
  			    ha->max_req_queues);
  			ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0019,
  			    "QoS mode set, max no of request queues:%d.
  ",
  			    ha->max_req_queues);
  		}
  		ql_log_pci(ql_log_info, ha->pdev, 0x001a,
  		    "MSI-X vector count: %d.
  ", msix);
  	} else
  		ql_log_pci(ql_log_info, ha->pdev, 0x001b,
  		    "BAR 3 not enabled.
  ");
  
  mqiobase_exit:
  	ha->msix_count = ha->max_rsp_queues + 1;
  	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x001c,
  	    "MSIX Count:%d.
  ", ha->msix_count);
  	return (0);
  
  iospace_error_exit:
  	return (-ENOMEM);
  }
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
  static int
  qla83xx_iospace_config(struct qla_hw_data *ha)
  {
  	uint16_t msix;
  	int cpus;
  
  	if (pci_request_selected_regions(ha->pdev, ha->bars,
  	    QLA2XXX_DRIVER_NAME)) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0117,
  		    "Failed to reserve PIO/MMIO regions (%s), aborting.
  ",
  		    pci_name(ha->pdev));
  
  		goto iospace_error_exit;
  	}
  
  	/* Use MMIO operations for all accesses. */
  	if (!(pci_resource_flags(ha->pdev, 0) & IORESOURCE_MEM)) {
  		ql_log_pci(ql_log_warn, ha->pdev, 0x0118,
  		    "Invalid pci I/O region size (%s).
  ",
  		    pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  	if (pci_resource_len(ha->pdev, 0) < MIN_IOBASE_LEN) {
  		ql_log_pci(ql_log_warn, ha->pdev, 0x0119,
  		    "Invalid PCI mem region size (%s), aborting
  ",
  			pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  
  	ha->iobase = ioremap(pci_resource_start(ha->pdev, 0), MIN_IOBASE_LEN);
  	if (!ha->iobase) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x011a,
  		    "Cannot remap MMIO (%s), aborting.
  ",
  		    pci_name(ha->pdev));
  		goto iospace_error_exit;
  	}
  
  	/* 64bit PCI BAR - BAR2 will correspoond to region 4 */
  	/* 83XX 26XX always use MQ type access for queues
  	 * - mbar 2, a.k.a region 4 */
  	ha->max_req_queues = ha->max_rsp_queues = 1;
  	ha->mqiobase = ioremap(pci_resource_start(ha->pdev, 4),
  			pci_resource_len(ha->pdev, 4));
  
  	if (!ha->mqiobase) {
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x011d,
  		    "BAR2/region4 not enabled
  ");
  		goto mqiobase_exit;
  	}
  
  	ha->msixbase = ioremap(pci_resource_start(ha->pdev, 2),
  			pci_resource_len(ha->pdev, 2));
  	if (ha->msixbase) {
  		/* Read MSIX vector size of the board */
  		pci_read_config_word(ha->pdev,
  		    QLA_83XX_PCI_MSIX_CONTROL, &msix);
  		ha->msix_count = msix;
  		/* Max queues are bounded by available msix vectors */
  		/* queue 0 uses two msix vectors */
  		if (ql2xmultique_tag) {
  			cpus = num_online_cpus();
  			ha->max_rsp_queues = (ha->msix_count - 1 > cpus) ?
  				(cpus + 1) : (ha->msix_count - 1);
  			ha->max_req_queues = 2;
  		} else if (ql2xmaxqueues > 1) {
  			ha->max_req_queues = ql2xmaxqueues > QLA_MQ_SIZE ?
  						QLA_MQ_SIZE : ql2xmaxqueues;
  			ql_dbg_pci(ql_dbg_multiq, ha->pdev, 0xc00c,
  			    "QoS mode set, max no of request queues:%d.
  ",
  			    ha->max_req_queues);
  			ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011b,
  			    "QoS mode set, max no of request queues:%d.
  ",
  			    ha->max_req_queues);
  		}
  		ql_log_pci(ql_log_info, ha->pdev, 0x011c,
  		    "MSI-X vector count: %d.
  ", msix);
  	} else
  		ql_log_pci(ql_log_info, ha->pdev, 0x011e,
  		    "BAR 1 not enabled.
  ");
  
  mqiobase_exit:
  	ha->msix_count = ha->max_rsp_queues + 1;
aa230bc55   Arun Easi   [SCSI] qla2xxx: E...
1710
1711
  
  	qlt_83xx_iospace_config(ha);
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
1712
1713
1714
1715
1716
1717
1718
1719
  	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x011f,
  	    "MSIX Count:%d.
  ", ha->msix_count);
  	return 0;
  
  iospace_error_exit:
  	return -ENOMEM;
  }
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
  static struct isp_operations qla2100_isp_ops = {
  	.pci_config		= qla2100_pci_config,
  	.reset_chip		= qla2x00_reset_chip,
  	.chip_diag		= qla2x00_chip_diag,
  	.config_rings		= qla2x00_config_rings,
  	.reset_adapter		= qla2x00_reset_adapter,
  	.nvram_config		= qla2x00_nvram_config,
  	.update_fw_options	= qla2x00_update_fw_options,
  	.load_risc		= qla2x00_load_risc,
  	.pci_info_str		= qla2x00_pci_info_str,
  	.fw_version_str		= qla2x00_fw_version_str,
  	.intr_handler		= qla2100_intr_handler,
  	.enable_intrs		= qla2x00_enable_intrs,
  	.disable_intrs		= qla2x00_disable_intrs,
  	.abort_command		= qla2x00_abort_command,
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1735
1736
  	.target_reset		= qla2x00_abort_target,
  	.lun_reset		= qla2x00_lun_reset,
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
  	.fabric_login		= qla2x00_login_fabric,
  	.fabric_logout		= qla2x00_fabric_logout,
  	.calc_req_entries	= qla2x00_calc_iocbs_32,
  	.build_iocbs		= qla2x00_build_scsi_iocbs_32,
  	.prep_ms_iocb		= qla2x00_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla2x00_prep_ms_fdmi_iocb,
  	.read_nvram		= qla2x00_read_nvram_data,
  	.write_nvram		= qla2x00_write_nvram_data,
  	.fw_dump		= qla2100_fw_dump,
  	.beacon_on		= NULL,
  	.beacon_off		= NULL,
  	.beacon_blink		= NULL,
  	.read_optrom		= qla2x00_read_optrom_data,
  	.write_optrom		= qla2x00_write_optrom_data,
  	.get_flash_version	= qla2x00_get_flash_version,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1752
  	.start_scsi		= qla2x00_start_scsi,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1753
  	.abort_isp		= qla2x00_abort_isp,
706f457d0   Giridhar Malavali   [SCSI] qla2xxx: A...
1754
  	.iospace_config     	= qla2x00_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1755
  	.initialize_adapter	= qla2x00_initialize_adapter,
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
  };
  
  static struct isp_operations qla2300_isp_ops = {
  	.pci_config		= qla2300_pci_config,
  	.reset_chip		= qla2x00_reset_chip,
  	.chip_diag		= qla2x00_chip_diag,
  	.config_rings		= qla2x00_config_rings,
  	.reset_adapter		= qla2x00_reset_adapter,
  	.nvram_config		= qla2x00_nvram_config,
  	.update_fw_options	= qla2x00_update_fw_options,
  	.load_risc		= qla2x00_load_risc,
  	.pci_info_str		= qla2x00_pci_info_str,
  	.fw_version_str		= qla2x00_fw_version_str,
  	.intr_handler		= qla2300_intr_handler,
  	.enable_intrs		= qla2x00_enable_intrs,
  	.disable_intrs		= qla2x00_disable_intrs,
  	.abort_command		= qla2x00_abort_command,
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1773
1774
  	.target_reset		= qla2x00_abort_target,
  	.lun_reset		= qla2x00_lun_reset,
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
  	.fabric_login		= qla2x00_login_fabric,
  	.fabric_logout		= qla2x00_fabric_logout,
  	.calc_req_entries	= qla2x00_calc_iocbs_32,
  	.build_iocbs		= qla2x00_build_scsi_iocbs_32,
  	.prep_ms_iocb		= qla2x00_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla2x00_prep_ms_fdmi_iocb,
  	.read_nvram		= qla2x00_read_nvram_data,
  	.write_nvram		= qla2x00_write_nvram_data,
  	.fw_dump		= qla2300_fw_dump,
  	.beacon_on		= qla2x00_beacon_on,
  	.beacon_off		= qla2x00_beacon_off,
  	.beacon_blink		= qla2x00_beacon_blink,
  	.read_optrom		= qla2x00_read_optrom_data,
  	.write_optrom		= qla2x00_write_optrom_data,
  	.get_flash_version	= qla2x00_get_flash_version,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1790
  	.start_scsi		= qla2x00_start_scsi,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1791
  	.abort_isp		= qla2x00_abort_isp,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1792
  	.iospace_config		= qla2x00_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1793
  	.initialize_adapter	= qla2x00_initialize_adapter,
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
  };
  
  static struct isp_operations qla24xx_isp_ops = {
  	.pci_config		= qla24xx_pci_config,
  	.reset_chip		= qla24xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla24xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla24xx_nvram_config,
  	.update_fw_options	= qla24xx_update_fw_options,
  	.load_risc		= qla24xx_load_risc,
  	.pci_info_str		= qla24xx_pci_info_str,
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla24xx_intr_handler,
  	.enable_intrs		= qla24xx_enable_intrs,
  	.disable_intrs		= qla24xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1811
1812
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= qla24xx_read_nvram_data,
  	.write_nvram		= qla24xx_write_nvram_data,
  	.fw_dump		= qla24xx_fw_dump,
  	.beacon_on		= qla24xx_beacon_on,
  	.beacon_off		= qla24xx_beacon_off,
  	.beacon_blink		= qla24xx_beacon_blink,
  	.read_optrom		= qla24xx_read_optrom_data,
  	.write_optrom		= qla24xx_write_optrom_data,
  	.get_flash_version	= qla24xx_get_flash_version,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
1828
  	.start_scsi		= qla24xx_start_scsi,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1829
  	.abort_isp		= qla2x00_abort_isp,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1830
  	.iospace_config		= qla2x00_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1831
  	.initialize_adapter	= qla2x00_initialize_adapter,
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
1832
  };
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
  static struct isp_operations qla25xx_isp_ops = {
  	.pci_config		= qla25xx_pci_config,
  	.reset_chip		= qla24xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla24xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla24xx_nvram_config,
  	.update_fw_options	= qla24xx_update_fw_options,
  	.load_risc		= qla24xx_load_risc,
  	.pci_info_str		= qla24xx_pci_info_str,
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla24xx_intr_handler,
  	.enable_intrs		= qla24xx_enable_intrs,
  	.disable_intrs		= qla24xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
523ec773b   Andrew Vasquez   [SCSI] qla2xxx: A...
1848
1849
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= qla25xx_read_nvram_data,
  	.write_nvram		= qla25xx_write_nvram_data,
  	.fw_dump		= qla25xx_fw_dump,
  	.beacon_on		= qla24xx_beacon_on,
  	.beacon_off		= qla24xx_beacon_off,
  	.beacon_blink		= qla24xx_beacon_blink,
338c9161e   Andrew Vasquez   [SCSI] qla2xxx: A...
1862
  	.read_optrom		= qla25xx_read_optrom_data,
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
1863
1864
  	.write_optrom		= qla24xx_write_optrom_data,
  	.get_flash_version	= qla24xx_get_flash_version,
bad750028   Arun Easi   [SCSI] qla2xxx: T...
1865
  	.start_scsi		= qla24xx_dif_start_scsi,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1866
  	.abort_isp		= qla2x00_abort_isp,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1867
  	.iospace_config		= qla2x00_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1868
  	.initialize_adapter	= qla2x00_initialize_adapter,
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
1869
  };
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
1870
1871
1872
1873
1874
1875
1876
1877
  static struct isp_operations qla81xx_isp_ops = {
  	.pci_config		= qla25xx_pci_config,
  	.reset_chip		= qla24xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla24xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla81xx_nvram_config,
  	.update_fw_options	= qla81xx_update_fw_options,
eaac30be2   Andrew Vasquez   [SCSI] qla2xxx: M...
1878
  	.load_risc		= qla81xx_load_risc,
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
  	.pci_info_str		= qla24xx_pci_info_str,
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla24xx_intr_handler,
  	.enable_intrs		= qla24xx_enable_intrs,
  	.disable_intrs		= qla24xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
3d79038f9   Andrew Vasquez   [SCSI] qla2xxx: A...
1893
1894
  	.read_nvram		= NULL,
  	.write_nvram		= NULL,
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
1895
1896
1897
  	.fw_dump		= qla81xx_fw_dump,
  	.beacon_on		= qla24xx_beacon_on,
  	.beacon_off		= qla24xx_beacon_off,
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
1898
  	.beacon_blink		= qla83xx_beacon_blink,
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
1899
1900
1901
  	.read_optrom		= qla25xx_read_optrom_data,
  	.write_optrom		= qla24xx_write_optrom_data,
  	.get_flash_version	= qla24xx_get_flash_version,
ba77ef535   Arun Easi   [SCSI] qla2xxx: T...
1902
  	.start_scsi		= qla24xx_dif_start_scsi,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1903
  	.abort_isp		= qla2x00_abort_isp,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1904
  	.iospace_config		= qla2x00_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1905
  	.initialize_adapter	= qla2x00_initialize_adapter,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
  };
  
  static struct isp_operations qla82xx_isp_ops = {
  	.pci_config		= qla82xx_pci_config,
  	.reset_chip		= qla82xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla82xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla81xx_nvram_config,
  	.update_fw_options	= qla24xx_update_fw_options,
  	.load_risc		= qla82xx_load_risc,
9d55ca660   Atul Deshmukh   [SCSI] qla2xxx: W...
1917
  	.pci_info_str		= qla24xx_pci_info_str,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla82xx_intr_handler,
  	.enable_intrs		= qla82xx_enable_intrs,
  	.disable_intrs		= qla82xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= qla24xx_read_nvram_data,
  	.write_nvram		= qla24xx_write_nvram_data,
a1b23c5a1   Chad Dupuis   [SCSI] qla2xxx: R...
1933
  	.fw_dump		= qla82xx_fw_dump,
999916dc5   Saurav Kashyap   [SCSI] qla2xxx: I...
1934
1935
1936
  	.beacon_on		= qla82xx_beacon_on,
  	.beacon_off		= qla82xx_beacon_off,
  	.beacon_blink		= NULL,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1937
1938
  	.read_optrom		= qla82xx_read_optrom_data,
  	.write_optrom		= qla82xx_write_optrom_data,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1939
  	.get_flash_version	= qla82xx_get_flash_version,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
1940
1941
  	.start_scsi             = qla82xx_start_scsi,
  	.abort_isp		= qla82xx_abort_isp,
706f457d0   Giridhar Malavali   [SCSI] qla2xxx: A...
1942
  	.iospace_config     	= qla82xx_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
1943
  	.initialize_adapter	= qla2x00_initialize_adapter,
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
1944
  };
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
  static struct isp_operations qla8044_isp_ops = {
  	.pci_config		= qla82xx_pci_config,
  	.reset_chip		= qla82xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla82xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla81xx_nvram_config,
  	.update_fw_options	= qla24xx_update_fw_options,
  	.load_risc		= qla82xx_load_risc,
  	.pci_info_str		= qla24xx_pci_info_str,
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla8044_intr_handler,
  	.enable_intrs		= qla82xx_enable_intrs,
  	.disable_intrs		= qla82xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= NULL,
  	.write_nvram		= NULL,
a1b23c5a1   Chad Dupuis   [SCSI] qla2xxx: R...
1970
  	.fw_dump		= qla8044_fw_dump,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1971
1972
1973
  	.beacon_on		= qla82xx_beacon_on,
  	.beacon_off		= qla82xx_beacon_off,
  	.beacon_blink		= NULL,
888e639d6   Saurav Kashyap   [SCSI] qla2xxx: C...
1974
  	.read_optrom		= qla8044_read_optrom_data,
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
1975
1976
1977
1978
1979
1980
1981
  	.write_optrom		= qla8044_write_optrom_data,
  	.get_flash_version	= qla82xx_get_flash_version,
  	.start_scsi             = qla82xx_start_scsi,
  	.abort_isp		= qla8044_abort_isp,
  	.iospace_config		= qla82xx_iospace_config,
  	.initialize_adapter	= qla2x00_initialize_adapter,
  };
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
  static struct isp_operations qla83xx_isp_ops = {
  	.pci_config		= qla25xx_pci_config,
  	.reset_chip		= qla24xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla24xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla81xx_nvram_config,
  	.update_fw_options	= qla81xx_update_fw_options,
  	.load_risc		= qla81xx_load_risc,
  	.pci_info_str		= qla24xx_pci_info_str,
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla24xx_intr_handler,
  	.enable_intrs		= qla24xx_enable_intrs,
  	.disable_intrs		= qla24xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= NULL,
  	.write_nvram		= NULL,
  	.fw_dump		= qla83xx_fw_dump,
  	.beacon_on		= qla24xx_beacon_on,
  	.beacon_off		= qla24xx_beacon_off,
  	.beacon_blink		= qla83xx_beacon_blink,
  	.read_optrom		= qla25xx_read_optrom_data,
  	.write_optrom		= qla24xx_write_optrom_data,
  	.get_flash_version	= qla24xx_get_flash_version,
  	.start_scsi		= qla24xx_dif_start_scsi,
  	.abort_isp		= qla2x00_abort_isp,
  	.iospace_config		= qla83xx_iospace_config,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
  	.initialize_adapter	= qla2x00_initialize_adapter,
  };
  
  static struct isp_operations qlafx00_isp_ops = {
  	.pci_config		= qlafx00_pci_config,
  	.reset_chip		= qlafx00_soft_reset,
  	.chip_diag		= qlafx00_chip_diag,
  	.config_rings		= qlafx00_config_rings,
  	.reset_adapter		= qlafx00_soft_reset,
  	.nvram_config		= NULL,
  	.update_fw_options	= NULL,
  	.load_risc		= NULL,
  	.pci_info_str		= qlafx00_pci_info_str,
  	.fw_version_str		= qlafx00_fw_version_str,
  	.intr_handler		= qlafx00_intr_handler,
  	.enable_intrs		= qlafx00_enable_intrs,
  	.disable_intrs		= qlafx00_disable_intrs,
4440e46d5   Armen Baloyan   [SCSI] qla2xxx: A...
2034
  	.abort_command		= qla24xx_async_abort_command,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
  	.target_reset		= qlafx00_abort_target,
  	.lun_reset		= qlafx00_lun_reset,
  	.fabric_login		= NULL,
  	.fabric_logout		= NULL,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= qla24xx_read_nvram_data,
  	.write_nvram		= qla24xx_write_nvram_data,
  	.fw_dump		= NULL,
  	.beacon_on		= qla24xx_beacon_on,
  	.beacon_off		= qla24xx_beacon_off,
  	.beacon_blink		= NULL,
  	.read_optrom		= qla24xx_read_optrom_data,
  	.write_optrom		= qla24xx_write_optrom_data,
  	.get_flash_version	= qla24xx_get_flash_version,
  	.start_scsi		= qlafx00_start_scsi,
  	.abort_isp		= qlafx00_abort_isp,
  	.iospace_config		= qlafx00_iospace_config,
  	.initialize_adapter	= qlafx00_initialize_adapter,
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2056
  };
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
  static struct isp_operations qla27xx_isp_ops = {
  	.pci_config		= qla25xx_pci_config,
  	.reset_chip		= qla24xx_reset_chip,
  	.chip_diag		= qla24xx_chip_diag,
  	.config_rings		= qla24xx_config_rings,
  	.reset_adapter		= qla24xx_reset_adapter,
  	.nvram_config		= qla81xx_nvram_config,
  	.update_fw_options	= qla81xx_update_fw_options,
  	.load_risc		= qla81xx_load_risc,
  	.pci_info_str		= qla24xx_pci_info_str,
  	.fw_version_str		= qla24xx_fw_version_str,
  	.intr_handler		= qla24xx_intr_handler,
  	.enable_intrs		= qla24xx_enable_intrs,
  	.disable_intrs		= qla24xx_disable_intrs,
  	.abort_command		= qla24xx_abort_command,
  	.target_reset		= qla24xx_abort_target,
  	.lun_reset		= qla24xx_lun_reset,
  	.fabric_login		= qla24xx_login_fabric,
  	.fabric_logout		= qla24xx_fabric_logout,
  	.calc_req_entries	= NULL,
  	.build_iocbs		= NULL,
  	.prep_ms_iocb		= qla24xx_prep_ms_iocb,
  	.prep_ms_fdmi_iocb	= qla24xx_prep_ms_fdmi_iocb,
  	.read_nvram		= NULL,
  	.write_nvram		= NULL,
  	.fw_dump		= qla27xx_fwdump,
  	.beacon_on		= qla24xx_beacon_on,
  	.beacon_off		= qla24xx_beacon_off,
  	.beacon_blink		= qla83xx_beacon_blink,
  	.read_optrom		= qla25xx_read_optrom_data,
  	.write_optrom		= qla24xx_write_optrom_data,
  	.get_flash_version	= qla24xx_get_flash_version,
  	.start_scsi		= qla24xx_dif_start_scsi,
  	.abort_isp		= qla2x00_abort_isp,
  	.iospace_config		= qla83xx_iospace_config,
  	.initialize_adapter	= qla2x00_initialize_adapter,
  };
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2094
  static inline void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2095
  qla2x00_set_isp_flags(struct qla_hw_data *ha)
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2096
2097
2098
2099
2100
2101
  {
  	ha->device_type = DT_EXTENDED_IDS;
  	switch (ha->pdev->device) {
  	case PCI_DEVICE_ID_QLOGIC_ISP2100:
  		ha->device_type |= DT_ISP2100;
  		ha->device_type &= ~DT_EXTENDED_IDS;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2102
  		ha->fw_srisc_address = RISC_START_ADDRESS_2100;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2103
2104
2105
2106
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP2200:
  		ha->device_type |= DT_ISP2200;
  		ha->device_type &= ~DT_EXTENDED_IDS;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2107
  		ha->fw_srisc_address = RISC_START_ADDRESS_2100;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2108
2109
2110
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP2300:
  		ha->device_type |= DT_ISP2300;
4a59f71d7   Andrew Vasquez   [SCSI] qla2xxx: F...
2111
  		ha->device_type |= DT_ZIO_SUPPORTED;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2112
  		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2113
2114
2115
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP2312:
  		ha->device_type |= DT_ISP2312;
4a59f71d7   Andrew Vasquez   [SCSI] qla2xxx: F...
2116
  		ha->device_type |= DT_ZIO_SUPPORTED;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2117
  		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2118
2119
2120
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP2322:
  		ha->device_type |= DT_ISP2322;
4a59f71d7   Andrew Vasquez   [SCSI] qla2xxx: F...
2121
  		ha->device_type |= DT_ZIO_SUPPORTED;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2122
2123
2124
  		if (ha->pdev->subsystem_vendor == 0x1028 &&
  		    ha->pdev->subsystem_device == 0x0170)
  			ha->device_type |= DT_OEM_001;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2125
  		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2126
2127
2128
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP6312:
  		ha->device_type |= DT_ISP6312;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2129
  		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2130
2131
2132
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP6322:
  		ha->device_type |= DT_ISP6322;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2133
  		ha->fw_srisc_address = RISC_START_ADDRESS_2300;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2134
2135
2136
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP2422:
  		ha->device_type |= DT_ISP2422;
4a59f71d7   Andrew Vasquez   [SCSI] qla2xxx: F...
2137
  		ha->device_type |= DT_ZIO_SUPPORTED;
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
2138
  		ha->device_type |= DT_FWI2;
c76f2c013   Andrew Vasquez   [SCSI] qla2xxx: G...
2139
  		ha->device_type |= DT_IIDMA;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2140
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2141
2142
2143
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP2432:
  		ha->device_type |= DT_ISP2432;
4a59f71d7   Andrew Vasquez   [SCSI] qla2xxx: F...
2144
  		ha->device_type |= DT_ZIO_SUPPORTED;
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
2145
  		ha->device_type |= DT_FWI2;
c76f2c013   Andrew Vasquez   [SCSI] qla2xxx: G...
2146
  		ha->device_type |= DT_IIDMA;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2147
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2148
  		break;
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
2149
2150
2151
2152
2153
2154
2155
  	case PCI_DEVICE_ID_QLOGIC_ISP8432:
  		ha->device_type |= DT_ISP8432;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		break;
044cc6c8e   Andrew Vasquez   [SCSI] qla2xxx: A...
2156
2157
  	case PCI_DEVICE_ID_QLOGIC_ISP5422:
  		ha->device_type |= DT_ISP5422;
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
2158
  		ha->device_type |= DT_FWI2;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2159
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2160
  		break;
044cc6c8e   Andrew Vasquez   [SCSI] qla2xxx: A...
2161
2162
  	case PCI_DEVICE_ID_QLOGIC_ISP5432:
  		ha->device_type |= DT_ISP5432;
e428924cc   Andrew Vasquez   [SCSI] qla2xxx: G...
2163
  		ha->device_type |= DT_FWI2;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2164
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2165
  		break;
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2166
2167
2168
2169
2170
  	case PCI_DEVICE_ID_QLOGIC_ISP2532:
  		ha->device_type |= DT_ISP2532;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
441d10720   Andrew Vasquez   [SCSI] qla2xxx: R...
2171
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2172
  		break;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2173
2174
2175
2176
2177
2178
2179
  	case PCI_DEVICE_ID_QLOGIC_ISP8001:
  		ha->device_type |= DT_ISP8001;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		break;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2180
2181
2182
2183
2184
2185
2186
2187
  	case PCI_DEVICE_ID_QLOGIC_ISP8021:
  		ha->device_type |= DT_ISP8021;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		/* Initialize 82XX ISP flags */
  		qla82xx_init_flags(ha);
  		break;
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
2188
2189
2190
2191
2192
2193
2194
2195
  	 case PCI_DEVICE_ID_QLOGIC_ISP8044:
  		ha->device_type |= DT_ISP8044;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		/* Initialize 82XX ISP flags */
  		qla82xx_init_flags(ha);
  		break;
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
  	case PCI_DEVICE_ID_QLOGIC_ISP2031:
  		ha->device_type |= DT_ISP2031;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
  		ha->device_type |= DT_T10_PI;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		break;
  	case PCI_DEVICE_ID_QLOGIC_ISP8031:
  		ha->device_type |= DT_ISP8031;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
  		ha->device_type |= DT_T10_PI;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		break;
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2212
2213
2214
  	case PCI_DEVICE_ID_QLOGIC_ISPF001:
  		ha->device_type |= DT_ISPFX00;
  		break;
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2215
2216
2217
2218
2219
2220
2221
  	case PCI_DEVICE_ID_QLOGIC_ISP2071:
  		ha->device_type |= DT_ISP2071;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		break;
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
2222
2223
2224
2225
2226
2227
2228
  	case PCI_DEVICE_ID_QLOGIC_ISP2271:
  		ha->device_type |= DT_ISP2271;
  		ha->device_type |= DT_ZIO_SUPPORTED;
  		ha->device_type |= DT_FWI2;
  		ha->device_type |= DT_IIDMA;
  		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
  		break;
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2229
  	}
e5b68a61e   Anirban Chakraborty   [SCSI] qla2xxx: U...
2230

a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2231
  	if (IS_QLA82XX(ha))
43a9c38bf   Saurav Kashyap   [SCSI] qla2xxx: C...
2232
  		ha->port_no = ha->portnum & 1;
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2233
  	else {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2234
2235
  		/* Get adapter physical port no from interrupt pin register. */
  		pci_read_config_byte(ha->pdev, PCI_INTERRUPT_PIN, &ha->port_no);
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2236
2237
2238
2239
2240
  		if (IS_QLA27XX(ha))
  			ha->port_no--;
  		else
  			ha->port_no = !(ha->port_no & 1);
  	}
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2241

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2242
  	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x000b,
d8424f68c   Joe Perches   [SCSI] qla2xxx: M...
2243
2244
  	    "device_type=0x%x port=%d fw_srisc_address=0x%x.
  ",
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2245
  	    ha->device_type, ha->port_no, ha->fw_srisc_address);
ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2246
  }
abbd8870b   Andrew Vasquez   [SCSI] qla2xxx: F...
2247
  static void
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2248
2249
  qla2xxx_scan_start(struct Scsi_Host *shost)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2250
  	scsi_qla_host_t *vha = shost_priv(shost);
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2251

cbc8eb67d   Andrew Vasquez   [SCSI] qla2xxx: F...
2252
2253
  	if (vha->hw->flags.running_gold_fw)
  		return;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2254
2255
2256
2257
  	set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
  	set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
  	set_bit(RSCN_UPDATE, &vha->dpc_flags);
  	set_bit(NPIV_CONFIG_NEEDED, &vha->dpc_flags);
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2258
2259
2260
2261
2262
  }
  
  static int
  qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2263
  	scsi_qla_host_t *vha = shost_priv(shost);
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2264

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2265
  	if (!vha->host)
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2266
  		return 1;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2267
  	if (time > vha->hw->loop_reset_delay * HZ)
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2268
  		return 1;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2269
  	return atomic_read(&vha->loop_state) == LOOP_READY;
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2270
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2271
2272
2273
  /*
   * PCI driver interface
   */
6f0397905   Greg Kroah-Hartman   Drivers: scsi: re...
2274
  static int
7ee613970   Andrew Vasquez   [SCSI] qla2xxx: C...
2275
  qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2276
  {
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2277
  	int	ret = -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2278
  	struct Scsi_Host *host;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2279
2280
  	scsi_qla_host_t *base_vha = NULL;
  	struct qla_hw_data *ha;
29856e284   Andrew Vasquez   [SCSI] qla2xxx: A...
2281
  	char pci_info[30];
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
2282
  	char fw_str[30], wq_name[30];
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
2283
  	struct scsi_host_template *sht;
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2284
  	int bars, mem_only = 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2285
  	uint16_t req_length = 0, rsp_length = 0;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2286
2287
  	struct req_que *req = NULL;
  	struct rsp_que *rsp = NULL;
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2288
  	bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
a5326f86e   Giridhar Malavali   [SCSI] qla2xxx: C...
2289
  	sht = &qla2xxx_driver_template;
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
2290
  	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
8bc69e7dc   Andrew Vasquez   [SCSI] qla2xxx: C...
2291
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
2292
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
8bc69e7dc   Andrew Vasquez   [SCSI] qla2xxx: C...
2293
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2294
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2295
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 ||
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2296
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001 ||
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2297
2298
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8021 ||
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2031 ||
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2299
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 ||
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
2300
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 ||
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2301
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 ||
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
2302
2303
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 ||
  	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271) {
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2304
  		bars = pci_select_bars(pdev, IORESOURCE_MEM);
094839164   Benjamin Herrenschmidt   PCI: Remove users...
2305
  		mem_only = 1;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2306
2307
2308
  		ql_dbg_pci(ql_dbg_init, pdev, 0x0007,
  		    "Mem only adapter.
  ");
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2309
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2310
2311
2312
  	ql_dbg_pci(ql_dbg_init, pdev, 0x0008,
  	    "Bars=%d.
  ", bars);
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2313

094839164   Benjamin Herrenschmidt   PCI: Remove users...
2314
2315
2316
2317
2318
2319
2320
  	if (mem_only) {
  		if (pci_enable_device_mem(pdev))
  			goto probe_out;
  	} else {
  		if (pci_enable_device(pdev))
  			goto probe_out;
  	}
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2321

0927678f5   Jesse Barnes   PCI: use pci_find...
2322
2323
  	/* This may fail but that's ok */
  	pci_enable_pcie_error_reporting(pdev);
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2324

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2325
2326
  	ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL);
  	if (!ha) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2327
2328
2329
  		ql_log_pci(ql_log_fatal, pdev, 0x0009,
  		    "Unable to allocate memory for ha.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2330
  		goto probe_out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2331
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2332
2333
2334
  	ql_dbg_pci(ql_dbg_init, pdev, 0x000a,
  	    "Memory allocated for ha=%p.
  ", ha);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2335
  	ha->pdev = pdev;
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2336
  	ha->tgt.enable_class_2 = ql2xenableclass2;
33e799775   Quinn Tran   qla2xxx: Add supp...
2337
2338
  	INIT_LIST_HEAD(&ha->tgt.q_full_list);
  	spin_lock_init(&ha->tgt.q_full_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2339
2340
  
  	/* Clear our data area */
285d0321d   Andrew Vasquez   [SCSI] qla2xxx: M...
2341
  	ha->bars = bars;
094839164   Benjamin Herrenschmidt   PCI: Remove users...
2342
  	ha->mem_only = mem_only;
df4bf0bb5   Andrew Vasquez   [SCSI] qla2xxx: C...
2343
  	spin_lock_init(&ha->hardware_lock);
339aa70ec   Andrew Vasquez   [SCSI] qla2xxx: I...
2344
  	spin_lock_init(&ha->vport_slock);
a9b6f722f   Saurav Kashyap   [SCSI] qla2xxx: I...
2345
  	mutex_init(&ha->selflogin_lock);
7a8ab9c84   Chad Dupuis   [SCSI] qla2xxx: A...
2346
  	mutex_init(&ha->optrom_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2347

ea5b6382f   Andrew Vasquez   [SCSI] qla2xxx: C...
2348
2349
  	/* Set ISP-type information. */
  	qla2x00_set_isp_flags(ha);
ca79cf664   Duane Grigsby   [SCSI] qla2xxx: A...
2350
2351
  
  	/* Set EEH reset type to fundamental if required by hba */
956761121   Joe Carnuccio   [SCSI] qla2xxx: D...
2352
  	if (IS_QLA24XX(ha) || IS_QLA25XX(ha) || IS_QLA81XX(ha) ||
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2353
  	    IS_QLA83XX(ha) || IS_QLA27XX(ha))
ca79cf664   Duane Grigsby   [SCSI] qla2xxx: A...
2354
  		pdev->needs_freset = 1;
ca79cf664   Duane Grigsby   [SCSI] qla2xxx: A...
2355

cba1e47f4   Chad Dupuis   [SCSI] qla2xxx: M...
2356
2357
2358
2359
  	ha->prev_topology = 0;
  	ha->init_cb_size = sizeof(init_cb_t);
  	ha->link_data_rate = PORT_SPEED_UNKNOWN;
  	ha->optrom_size = OPTROM_SIZE_2300;
abbd8870b   Andrew Vasquez   [SCSI] qla2xxx: F...
2360
  	/* Assign ISP specific operations. */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2361
  	if (IS_QLA2100(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2362
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2100;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2363
  		ha->mbx_count = MAILBOX_REGISTER_COUNT_2100;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2364
2365
2366
  		req_length = REQUEST_ENTRY_CNT_2100;
  		rsp_length = RESPONSE_ENTRY_CNT_2100;
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
abbd8870b   Andrew Vasquez   [SCSI] qla2xxx: F...
2367
  		ha->gid_list_info_size = 4;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2368
2369
2370
2371
  		ha->flash_conf_off = ~0;
  		ha->flash_data_off = ~0;
  		ha->nvram_conf_off = ~0;
  		ha->nvram_data_off = ~0;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
2372
  		ha->isp_ops = &qla2100_isp_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2373
  	} else if (IS_QLA2200(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2374
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2100;
67ddda353   Andrew Vasquez   [SCSI] qla2xxx: C...
2375
  		ha->mbx_count = MAILBOX_REGISTER_COUNT_2200;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2376
2377
2378
  		req_length = REQUEST_ENTRY_CNT_2200;
  		rsp_length = RESPONSE_ENTRY_CNT_2100;
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
abbd8870b   Andrew Vasquez   [SCSI] qla2xxx: F...
2379
  		ha->gid_list_info_size = 4;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2380
2381
2382
2383
  		ha->flash_conf_off = ~0;
  		ha->flash_data_off = ~0;
  		ha->nvram_conf_off = ~0;
  		ha->nvram_data_off = ~0;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
2384
  		ha->isp_ops = &qla2100_isp_ops;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
2385
  	} else if (IS_QLA23XX(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2386
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2100;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2387
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2388
2389
2390
  		req_length = REQUEST_ENTRY_CNT_2200;
  		rsp_length = RESPONSE_ENTRY_CNT_2300;
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
abbd8870b   Andrew Vasquez   [SCSI] qla2xxx: F...
2391
  		ha->gid_list_info_size = 6;
854165f42   Andrew Vasquez   [SCSI] qla2xxx: A...
2392
2393
  		if (IS_QLA2322(ha) || IS_QLA6322(ha))
  			ha->optrom_size = OPTROM_SIZE_2322;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2394
2395
2396
2397
  		ha->flash_conf_off = ~0;
  		ha->flash_data_off = ~0;
  		ha->nvram_conf_off = ~0;
  		ha->nvram_data_off = ~0;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
2398
  		ha->isp_ops = &qla2300_isp_ops;
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
2399
  	} else if (IS_QLA24XX_TYPE(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2400
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
2401
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2402
2403
  		req_length = REQUEST_ENTRY_CNT_24XX;
  		rsp_length = RESPONSE_ENTRY_CNT_2300;
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2404
  		ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2405
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
2406
  		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
2407
  		ha->gid_list_info_size = 8;
854165f42   Andrew Vasquez   [SCSI] qla2xxx: A...
2408
  		ha->optrom_size = OPTROM_SIZE_24XX;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2409
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA24XX;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
2410
  		ha->isp_ops = &qla24xx_isp_ops;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2411
2412
2413
2414
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
  		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
  		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2415
  	} else if (IS_QLA25XX(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2416
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2417
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2418
2419
  		req_length = REQUEST_ENTRY_CNT_24XX;
  		rsp_length = RESPONSE_ENTRY_CNT_2300;
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2420
  		ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2421
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2422
  		ha->init_cb_size = sizeof(struct mid_init_cb_24xx);
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2423
2424
  		ha->gid_list_info_size = 8;
  		ha->optrom_size = OPTROM_SIZE_25XX;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2425
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
2426
  		ha->isp_ops = &qla25xx_isp_ops;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2427
2428
2429
2430
2431
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
  		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
  		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
  	} else if (IS_QLA81XX(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2432
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2433
2434
2435
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
  		req_length = REQUEST_ENTRY_CNT_24XX;
  		rsp_length = RESPONSE_ENTRY_CNT_2300;
aa230bc55   Arun Easi   [SCSI] qla2xxx: E...
2436
  		ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2437
2438
2439
2440
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
  		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
  		ha->gid_list_info_size = 8;
  		ha->optrom_size = OPTROM_SIZE_81XX;
40859ae5f   Anirban Chakraborty   [SCSI] qla2xxx: C...
2441
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
2442
2443
2444
2445
2446
  		ha->isp_ops = &qla81xx_isp_ops;
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX;
  		ha->nvram_conf_off = ~0;
  		ha->nvram_data_off = ~0;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2447
  	} else if (IS_QLA82XX(ha)) {
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2448
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2449
2450
2451
2452
2453
2454
2455
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
  		req_length = REQUEST_ENTRY_CNT_82XX;
  		rsp_length = RESPONSE_ENTRY_CNT_82XX;
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
  		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
  		ha->gid_list_info_size = 8;
  		ha->optrom_size = OPTROM_SIZE_82XX;
087c621e2   Andrew Vasquez   [SCSI] qla2xxx: C...
2456
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2457
2458
2459
2460
2461
  		ha->isp_ops = &qla82xx_isp_ops;
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
  		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
  		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
  	} else if (IS_QLA8044(ha)) {
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
  		req_length = REQUEST_ENTRY_CNT_82XX;
  		rsp_length = RESPONSE_ENTRY_CNT_82XX;
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
  		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
  		ha->gid_list_info_size = 8;
  		ha->optrom_size = OPTROM_SIZE_83XX;
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
  		ha->isp_ops = &qla8044_isp_ops;
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA;
  		ha->nvram_conf_off = FARX_ACCESS_NVRAM_CONF;
  		ha->nvram_data_off = FARX_ACCESS_NVRAM_DATA;
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2477
  	} else if (IS_QLA83XX(ha)) {
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
2478
  		ha->portnum = PCI_FUNC(ha->pdev->devfn);
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2479
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2480
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
f2ea653fd   Saurav Kashyap   qla2xxx: Increase...
2481
  		req_length = REQUEST_ENTRY_CNT_83XX;
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2482
  		rsp_length = RESPONSE_ENTRY_CNT_2300;
b8aa4bdfe   Arun Easi   [SCSI] qla2xxx: A...
2483
  		ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX;
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
  		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
  		ha->gid_list_info_size = 8;
  		ha->optrom_size = OPTROM_SIZE_83XX;
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
  		ha->isp_ops = &qla83xx_isp_ops;
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX;
  		ha->nvram_conf_off = ~0;
  		ha->nvram_data_off = ~0;
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2494
2495
2496
2497
2498
2499
  	}  else if (IS_QLAFX00(ha)) {
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_FX00;
  		ha->mbx_count = MAILBOX_REGISTER_COUNT_FX00;
  		ha->aen_mbx_count = AEN_MAILBOX_REGISTER_COUNT_FX00;
  		req_length = REQUEST_ENTRY_CNT_FX00;
  		rsp_length = RESPONSE_ENTRY_CNT_FX00;
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2500
2501
2502
2503
  		ha->isp_ops = &qlafx00_isp_ops;
  		ha->port_down_retry_count = 30; /* default value */
  		ha->mr.fw_hbt_cnt = QLAFX00_HEARTBEAT_INTERVAL;
  		ha->mr.fw_reset_timer_tick = QLAFX00_RESET_INTERVAL;
71e560036   Armen Baloyan   [SCSI] qla2xxx: A...
2504
  		ha->mr.fw_critemp_timer_tick = QLAFX00_CRITEMP_INTERVAL;
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2505
  		ha->mr.fw_hbt_en = 1;
e8f5e95d5   Armen Baloyan   [SCSI] qla2xxx: F...
2506
2507
  		ha->mr.host_info_resend = false;
  		ha->mr.hinfo_resend_timer_tick = QLAFX00_HINFO_RESEND_INTERVAL;
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
  	} else if (IS_QLA27XX(ha)) {
  		ha->portnum = PCI_FUNC(ha->pdev->devfn);
  		ha->max_fibre_devices = MAX_FIBRE_DEVICES_2400;
  		ha->mbx_count = MAILBOX_REGISTER_COUNT;
  		req_length = REQUEST_ENTRY_CNT_24XX;
  		rsp_length = RESPONSE_ENTRY_CNT_2300;
  		ha->max_loop_id = SNS_LAST_LOOP_ID_2300;
  		ha->init_cb_size = sizeof(struct mid_init_cb_81xx);
  		ha->gid_list_info_size = 8;
  		ha->optrom_size = OPTROM_SIZE_83XX;
  		ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX;
  		ha->isp_ops = &qla27xx_isp_ops;
  		ha->flash_conf_off = FARX_ACCESS_FLASH_CONF_81XX;
  		ha->flash_data_off = FARX_ACCESS_FLASH_DATA_81XX;
  		ha->nvram_conf_off = ~0;
  		ha->nvram_data_off = ~0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2524
  	}
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
2525

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2526
2527
2528
  	ql_dbg_pci(ql_dbg_init, pdev, 0x001e,
  	    "mbx_count=%d, req_length=%d, "
  	    "rsp_length=%d, max_loop_id=%d, init_cb_size=%d, "
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2529
2530
2531
  	    "gid_list_info_size=%d, optrom_size=%d, nvram_npiv_size=%d, "
  	    "max_fibre_devices=%d.
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2532
2533
  	    ha->mbx_count, req_length, rsp_length, ha->max_loop_id,
  	    ha->init_cb_size, ha->gid_list_info_size, ha->optrom_size,
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2534
  	    ha->nvram_npiv_size, ha->max_fibre_devices);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2535
2536
2537
2538
2539
2540
  	ql_dbg_pci(ql_dbg_init, pdev, 0x001f,
  	    "isp_ops=%p, flash_conf_off=%d, "
  	    "flash_data_off=%d, nvram_conf_off=%d, nvram_data_off=%d.
  ",
  	    ha->isp_ops, ha->flash_conf_off, ha->flash_data_off,
  	    ha->nvram_conf_off, ha->nvram_data_off);
706f457d0   Giridhar Malavali   [SCSI] qla2xxx: A...
2541
2542
2543
2544
  
  	/* Configure PCI I/O space */
  	ret = ha->isp_ops->iospace_config(ha);
  	if (ret)
0a63ad12e   Saurav Kashyap   [SCSI] qla2xxx: D...
2545
  		goto iospace_config_failed;
706f457d0   Giridhar Malavali   [SCSI] qla2xxx: A...
2546
2547
2548
2549
2550
  
  	ql_log_pci(ql_log_info, pdev, 0x001d,
  	    "Found an ISP%04X irq %d iobase 0x%p.
  ",
  	    pdev->device, pdev->irq, ha->iobase);
6c2f527cb   matthias@kaehlcke.net   [SCSI] qla2xxx: C...
2551
  	mutex_init(&ha->vport_lock);
0b05a1f0d   Marcus Barrow   [SCSI] qla2xxx: U...
2552
2553
2554
  	init_completion(&ha->mbx_cmd_comp);
  	complete(&ha->mbx_cmd_comp);
  	init_completion(&ha->mbx_intr_comp);
23f2ebd17   Sarang Radke   [SCSI] qla2xxx: A...
2555
  	init_completion(&ha->dcbx_comp);
f356bef13   Chad Dupuis   [SCSI] qla2xxx: W...
2556
  	init_completion(&ha->lb_portup_comp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2557

2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
2558
  	set_bit(0, (unsigned long *) ha->vp_idx_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2559

53303c42d   Andrew Vasquez   [SCSI] qla2xxx: C...
2560
  	qla2x00_config_dma_addressing(ha);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2561
2562
2563
2564
2565
  	ql_dbg_pci(ql_dbg_init, pdev, 0x0020,
  	    "64 Bit addressing is %s.
  ",
  	    ha->flags.enable_64bit_addressing ? "enable" :
  	    "disable");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2566
  	ret = qla2x00_mem_alloc(ha, req_length, rsp_length, &req, &rsp);
b2a72ec32   Dan Carpenter   [SCSI] qla2xxx: f...
2567
  	if (ret) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2568
2569
2570
  		ql_log_pci(ql_log_fatal, pdev, 0x0031,
  		    "Failed to allocate memory for adapter, aborting.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2571

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2572
2573
  		goto probe_hw_failed;
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2574
  	req->max_q_depth = MAX_Q_DEPTH;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2575
  	if (ql2xmaxqdepth != 0 && ql2xmaxqdepth <= 0xffffU)
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2576
  		req->max_q_depth = ql2xmaxqdepth;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2577
2578
2579
  
  	base_vha = qla2x00_create_host(sht, ha);
  	if (!base_vha) {
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2580
  		ret = -ENOMEM;
6e9f21f3d   Anirban Chakraborty   [SCSI] qla2xxx: F...
2581
  		qla2x00_mem_free(ha);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2582
2583
  		qla2x00_free_req_que(ha, req);
  		qla2x00_free_rsp_que(ha, rsp);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2584
  		goto probe_hw_failed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2585
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2586
  	pci_set_drvdata(pdev, base_vha);
6b3839790   Joe Lawrence   qla2xxx: Prevent ...
2587
  	set_bit(PFLG_DRIVER_PROBING, &base_vha->pci_flags);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2588

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2589
  	host = base_vha->host;
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2590
  	base_vha->req = req;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2591
  	if (IS_QLA2XXX_MIDTYPE(ha))
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2592
  		base_vha->mgmt_svr_loop_id = 10 + base_vha->vp_idx;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2593
  	else
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2594
2595
  		base_vha->mgmt_svr_loop_id = MANAGEMENT_SERVER +
  						base_vha->vp_idx;
58548cb51   Giridhar Malavali   [SCSI] qla2xxx: I...
2596

8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2597
2598
2599
2600
2601
2602
2603
  	/* Setup fcport template structure. */
  	ha->mr.fcport.vha = base_vha;
  	ha->mr.fcport.port_type = FCT_UNKNOWN;
  	ha->mr.fcport.loop_id = FC_NO_LOOP_ID;
  	qla2x00_set_fcport_state(&ha->mr.fcport, FCS_UNCONFIGURED);
  	ha->mr.fcport.supported_classes = FC_COS_UNSPECIFIED;
  	ha->mr.fcport.scan_state = 1;
58548cb51   Giridhar Malavali   [SCSI] qla2xxx: I...
2604
2605
2606
2607
2608
2609
2610
2611
  	/* Set the SG table size based on ISP type */
  	if (!IS_FWI2_CAPABLE(ha)) {
  		if (IS_QLA2100(ha))
  			host->sg_tablesize = 32;
  	} else {
  		if (!IS_QLA82XX(ha))
  			host->sg_tablesize = QLA_SG_ALL;
  	}
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
2612
  	host->max_id = ha->max_fibre_devices;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2613
2614
  	host->cmd_per_lun = 3;
  	host->unique_id = host->host_no;
e02587d77   Arun Easi   [SCSI] qla2xxx: T...
2615
  	if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif)
0c4708748   Arun Easi   [SCSI] qla2xxx: T...
2616
2617
2618
  		host->max_cmd_len = 32;
  	else
  		host->max_cmd_len = MAX_CMDSZ;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2619
  	host->max_channel = MAX_BUSES - 1;
755f516bb   Hannes Reinecke   qla2xxx: Restrict...
2620
2621
2622
2623
2624
2625
  	/* Older HBAs support only 16-bit LUNs */
  	if (!IS_QLAFX00(ha) && !IS_FWI2_CAPABLE(ha) &&
  	    ql2xmaxlun > 0xffff)
  		host->max_lun = 0xffff;
  	else
  		host->max_lun = ql2xmaxlun;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2626
  	host->transportt = qla2xxx_transport_template;
9a069e196   Giridhar Malavali   [SCSI] qla2xxx: A...
2627
  	sht->vendor_id = (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2628

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2629
2630
2631
  	ql_dbg(ql_dbg_init, base_vha, 0x0033,
  	    "max_id=%d this_id=%d "
  	    "cmd_per_len=%d unique_id=%d max_cmd_len=%d max_channel=%d "
1abf635d2   Hannes Reinecke   scsi: use 64-bit ...
2632
2633
  	    "max_lun=%llu transportt=%p, vendor_id=%llu.
  ", host->max_id,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2634
2635
2636
  	    host->this_id, host->cmd_per_lun, host->unique_id,
  	    host->max_cmd_len, host->max_channel, host->max_lun,
  	    host->transportt, sht->vendor_id);
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
2637
2638
2639
2640
2641
2642
2643
2644
2645
  que_init:
  	/* Alloc arrays of request and response ring ptrs */
  	if (!qla2x00_alloc_queues(ha, req, rsp)) {
  		ql_log(ql_log_fatal, base_vha, 0x003d,
  		    "Failed to allocate memory for queue pointers..."
  		    "aborting.
  ");
  		goto probe_init_failed;
  	}
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2646
  	qlt_probe_one_stage1(base_vha, ha);
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
2647

73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
2648
2649
2650
  	/* Set up the irqs */
  	ret = qla2x00_request_irqs(ha, rsp);
  	if (ret)
6e9f21f3d   Anirban Chakraborty   [SCSI] qla2xxx: F...
2651
  		goto probe_init_failed;
90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
2652
2653
  
  	pci_save_state(pdev);
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
2654
  	/* Assign back pointers */
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2655
2656
  	rsp->req = req;
  	req->rsp = rsp;
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
2657

8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2658
2659
2660
2661
2662
2663
  	if (IS_QLAFX00(ha)) {
  		ha->rsp_q_map[0] = rsp;
  		ha->req_q_map[0] = req;
  		set_bit(0, ha->req_qid_map);
  		set_bit(0, ha->rsp_qid_map);
  	}
08029990b   Andrew Vasquez   [SCSI] qla2xxx: R...
2664
2665
2666
2667
2668
  	/* FWI2-capable only. */
  	req->req_q_in = &ha->iobase->isp24.req_q_in;
  	req->req_q_out = &ha->iobase->isp24.req_q_out;
  	rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in;
  	rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out;
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2669
  	if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) {
08029990b   Andrew Vasquez   [SCSI] qla2xxx: R...
2670
2671
2672
2673
  		req->req_q_in = &ha->mqiobase->isp25mq.req_q_in;
  		req->req_q_out = &ha->mqiobase->isp25mq.req_q_out;
  		rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in;
  		rsp->rsp_q_out =  &ha->mqiobase->isp25mq.rsp_q_out;
17d98630a   Anirban Chakraborty   [SCSI] qla2xxx: c...
2674
  	}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2675
2676
2677
2678
2679
2680
  	if (IS_QLAFX00(ha)) {
  		req->req_q_in = &ha->iobase->ispfx00.req_q_in;
  		req->req_q_out = &ha->iobase->ispfx00.req_q_out;
  		rsp->rsp_q_in = &ha->iobase->ispfx00.rsp_q_in;
  		rsp->rsp_q_out = &ha->iobase->ispfx00.rsp_q_out;
  	}
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
2681
  	if (IS_P3P_TYPE(ha)) {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2682
2683
2684
2685
  		req->req_q_out = &ha->iobase->isp82.req_q_out[0];
  		rsp->rsp_q_in = &ha->iobase->isp82.rsp_q_in[0];
  		rsp->rsp_q_out = &ha->iobase->isp82.rsp_q_out[0];
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
  	ql_dbg(ql_dbg_multiq, base_vha, 0xc009,
  	    "rsp_q_map=%p req_q_map=%p rsp->req=%p req->rsp=%p.
  ",
  	    ha->rsp_q_map, ha->req_q_map, rsp->req, req->rsp);
  	ql_dbg(ql_dbg_multiq, base_vha, 0xc00a,
  	    "req->req_q_in=%p req->req_q_out=%p "
  	    "rsp->rsp_q_in=%p rsp->rsp_q_out=%p.
  ",
  	    req->req_q_in, req->req_q_out,
  	    rsp->rsp_q_in, rsp->rsp_q_out);
  	ql_dbg(ql_dbg_init, base_vha, 0x003e,
  	    "rsp_q_map=%p req_q_map=%p rsp->req=%p req->rsp=%p.
  ",
  	    ha->rsp_q_map, ha->req_q_map, rsp->req, req->rsp);
  	ql_dbg(ql_dbg_init, base_vha, 0x003f,
  	    "req->req_q_in=%p req->req_q_out=%p rsp->rsp_q_in=%p rsp->rsp_q_out=%p.
  ",
  	    req->req_q_in, req->req_q_out, rsp->rsp_q_in, rsp->rsp_q_out);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2704

8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2705
  	if (ha->isp_ops->initialize_adapter(base_vha)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2706
2707
2708
2709
  		ql_log(ql_log_fatal, base_vha, 0x00d6,
  		    "Failed to initialize adapter - Adapter flags %x.
  ",
  		    base_vha->device_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2710

a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2711
2712
2713
  		if (IS_QLA82XX(ha)) {
  			qla82xx_idc_lock(ha);
  			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
2714
  				QLA8XXX_DEV_FAILED);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2715
  			qla82xx_idc_unlock(ha);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2716
2717
2718
  			ql_log(ql_log_fatal, base_vha, 0x00d7,
  			    "HW State: FAILED.
  ");
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
2719
2720
2721
2722
2723
2724
2725
2726
2727
  		} else if (IS_QLA8044(ha)) {
  			qla8044_idc_lock(ha);
  			qla8044_wr_direct(base_vha,
  				QLA8044_CRB_DEV_STATE_INDEX,
  				QLA8XXX_DEV_FAILED);
  			qla8044_idc_unlock(ha);
  			ql_log(ql_log_fatal, base_vha, 0x0150,
  			    "HW State: FAILED.
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2728
  		}
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2729
  		ret = -ENODEV;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2730
2731
  		goto probe_failed;
  	}
3b1bef644   Chad Dupuis   [SCSI] qla2xxx: S...
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
  	if (IS_QLAFX00(ha))
  		host->can_queue = QLAFX00_MAX_CANQUEUE;
  	else
  		host->can_queue = req->num_outstanding_cmds - 10;
  
  	ql_dbg(ql_dbg_init, base_vha, 0x0032,
  	    "can_queue=%d, req=%p, mgmt_svr_loop_id=%d, sg_tablesize=%d.
  ",
  	    host->can_queue, base_vha->req,
  	    base_vha->mgmt_svr_loop_id, host->sg_tablesize);
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
2742
2743
  	if (ha->mqenable) {
  		if (qla25xx_setup_mode(base_vha)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2744
2745
2746
  			ql_log(ql_log_warn, base_vha, 0x00ec,
  			    "Failed to create queues, falling back to single queue mode.
  ");
7163ea815   Anirban Chakraborty   [SCSI] qla2xxx: F...
2747
2748
2749
  			goto que_init;
  		}
  	}
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
2750

cbc8eb67d   Andrew Vasquez   [SCSI] qla2xxx: F...
2751
2752
  	if (ha->flags.running_gold_fw)
  		goto skip_dpc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2753
2754
2755
  	/*
  	 * Startup the kernel thread for this host adapter
  	 */
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
2756
  	ha->dpc_thread = kthread_create(qla2x00_do_dpc, ha,
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2757
  	    "%s_dpc", base_vha->host_str);
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
2758
  	if (IS_ERR(ha->dpc_thread)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2759
2760
2761
  		ql_log(ql_log_fatal, base_vha, 0x00ed,
  		    "Failed to start DPC thread.
  ");
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
2762
  		ret = PTR_ERR(ha->dpc_thread);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2763
2764
  		goto probe_failed;
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2765
2766
2767
  	ql_dbg(ql_dbg_init, base_vha, 0x00ee,
  	    "DPC thread started successfully.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2768

2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2769
2770
2771
2772
2773
2774
2775
  	/*
  	 * If we're not coming up in initiator mode, we might sit for
  	 * a while without waking up the dpc thread, which leads to a
  	 * stuck process warning.  So just kick the dpc once here and
  	 * let the kthread start (and go back to sleep in qla2x00_do_dpc).
  	 */
  	qla2xxx_wake_dpc(base_vha);
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
2776
  	INIT_WORK(&ha->board_disable, qla2x00_disable_board_on_pci_error);
81178772b   Saurav Kashyap   [SCSI] qla2xxx: I...
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
  	if (IS_QLA8031(ha) || IS_MCTP_CAPABLE(ha)) {
  		sprintf(wq_name, "qla2xxx_%lu_dpc_lp_wq", base_vha->host_no);
  		ha->dpc_lp_wq = create_singlethread_workqueue(wq_name);
  		INIT_WORK(&ha->idc_aen, qla83xx_service_idc_aen);
  
  		sprintf(wq_name, "qla2xxx_%lu_dpc_hp_wq", base_vha->host_no);
  		ha->dpc_hp_wq = create_singlethread_workqueue(wq_name);
  		INIT_WORK(&ha->nic_core_reset, qla83xx_nic_core_reset_work);
  		INIT_WORK(&ha->idc_state_handler,
  		    qla83xx_idc_state_handler_work);
  		INIT_WORK(&ha->nic_core_unrecoverable,
  		    qla83xx_nic_core_unrecoverable_work);
  	}
cbc8eb67d   Andrew Vasquez   [SCSI] qla2xxx: F...
2790
  skip_dpc:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2791
2792
  	list_add_tail(&base_vha->list, &ha->vp_list);
  	base_vha->host->irq = ha->pdev->irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2793
2794
  
  	/* Initialized the timer */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2795
  	qla2x00_start_timer(base_vha, qla2x00_timer, WATCH_INTERVAL);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2796
2797
2798
2799
2800
2801
2802
2803
  	ql_dbg(ql_dbg_init, base_vha, 0x00ef,
  	    "Started qla2x00_timer with "
  	    "interval=%d.
  ", WATCH_INTERVAL);
  	ql_dbg(ql_dbg_init, base_vha, 0x00f0,
  	    "Detected hba at address=%p.
  ",
  	    ha);
d19044c32   Andrew Vasquez   [SCSI] qla2xxx: d...
2804

e02587d77   Arun Easi   [SCSI] qla2xxx: T...
2805
  	if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
bad750028   Arun Easi   [SCSI] qla2xxx: T...
2806
  		if (ha->fw_attributes & BIT_4) {
9e522cd8f   Arun Easi   [SCSI] qla2xxx: T...
2807
  			int prot = 0, guard;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
2808
  			base_vha->flags.difdix_supported = 1;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2809
2810
2811
  			ql_dbg(ql_dbg_init, base_vha, 0x00f1,
  			    "Registering for DIF/DIX type 1 and 3 protection.
  ");
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
2812
2813
  			if (ql2xenabledif == 1)
  				prot = SHOST_DIX_TYPE0_PROTECTION;
bad750028   Arun Easi   [SCSI] qla2xxx: T...
2814
  			scsi_host_set_prot(host,
8cb2049c7   Arun Easi   [SCSI] qla2xxx: T...
2815
  			    prot | SHOST_DIF_TYPE1_PROTECTION
0c4708748   Arun Easi   [SCSI] qla2xxx: T...
2816
  			    | SHOST_DIF_TYPE2_PROTECTION
bad750028   Arun Easi   [SCSI] qla2xxx: T...
2817
2818
  			    | SHOST_DIF_TYPE3_PROTECTION
  			    | SHOST_DIX_TYPE1_PROTECTION
0c4708748   Arun Easi   [SCSI] qla2xxx: T...
2819
  			    | SHOST_DIX_TYPE2_PROTECTION
bad750028   Arun Easi   [SCSI] qla2xxx: T...
2820
  			    | SHOST_DIX_TYPE3_PROTECTION);
9e522cd8f   Arun Easi   [SCSI] qla2xxx: T...
2821
2822
2823
2824
2825
2826
2827
2828
  
  			guard = SHOST_DIX_GUARD_CRC;
  
  			if (IS_PI_IPGUARD_CAPABLE(ha) &&
  			    (ql2xenabledif > 1 || IS_PI_DIFB_DIX0_CAPABLE(ha)))
  				guard |= SHOST_DIX_GUARD_IP;
  
  			scsi_host_set_guard(host, guard);
bad750028   Arun Easi   [SCSI] qla2xxx: T...
2829
2830
2831
  		} else
  			base_vha->flags.difdix_supported = 0;
  	}
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2832
  	ha->isp_ops->enable_intrs(ha);
1fe19ee48   Armen Baloyan   [SCSI] qla2xxx: A...
2833
2834
2835
2836
2837
2838
  	if (IS_QLAFX00(ha)) {
  		ret = qlafx00_fx_disc(base_vha,
  			&base_vha->hw->mr.fcport, FXDISC_GET_CONFIG_INFO);
  		host->sg_tablesize = (ha->mr.extended_io_enabled) ?
  		    QLA_SG_ALL : 128;
  	}
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2839
2840
2841
  	ret = scsi_add_host(host, &pdev->dev);
  	if (ret)
  		goto probe_failed;
1486400f7   Michael Reed   [SCSI] qla2xxx: d...
2842
2843
  	base_vha->flags.init_done = 1;
  	base_vha->flags.online = 1;
edaa5c741   Saurav Kashyap   qla2xxx: Allow th...
2844
  	ha->prev_minidump_failed = 0;
1486400f7   Michael Reed   [SCSI] qla2xxx: d...
2845

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2846
2847
2848
  	ql_dbg(ql_dbg_init, base_vha, 0x00f2,
  	    "Init done and hba is online.
  ");
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2849
2850
2851
2852
2853
2854
  	if (qla_ini_mode_enabled(base_vha))
  		scsi_scan_host(host);
  	else
  		ql_dbg(ql_dbg_init, base_vha, 0x0122,
  			"skipping scsi_scan_host() for non-initiator port
  ");
1e99e33ad   Andrew Vasquez   [SCSI] qla2xxx: a...
2855

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2856
  	qla2x00_alloc_sysfs_attr(base_vha);
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2857

8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2858
2859
  	if (IS_QLAFX00(ha)) {
  		ret = qlafx00_fx_disc(base_vha,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2860
2861
2862
2863
2864
2865
  			&base_vha->hw->mr.fcport, FXDISC_GET_PORT_INFO);
  
  		/* Register system information */
  		ret =  qlafx00_fx_disc(base_vha,
  			&base_vha->hw->mr.fcport, FXDISC_REG_HOST_INFO);
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2866
  	qla2x00_init_host_attr(base_vha);
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2867

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2868
  	qla2x00_dfs_setup(base_vha);
df613b960   Andrew Vasquez   [SCSI] qla2xxx: A...
2869

03eb912a4   Armen Baloyan   [SCSI] qla2xxx: A...
2870
2871
2872
  	ql_log(ql_log_info, base_vha, 0x00fb,
  	    "QLogic %s - %s.
  ", ha->model_number, ha->model_desc);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
2873
2874
2875
2876
2877
2878
  	ql_log(ql_log_info, base_vha, 0x00fc,
  	    "ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.
  ",
  	    pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info),
  	    pci_name(pdev), ha->flags.enable_64bit_addressing ? '+' : '-',
  	    base_vha->host_no,
df57cabac   Himanshu Madhani   qla2xxx: Add FDMI...
2879
  	    ha->isp_ops->fw_version_str(base_vha, fw_str, sizeof(fw_str)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2880

2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
2881
  	qlt_add_target(ha, base_vha);
6b3839790   Joe Lawrence   qla2xxx: Prevent ...
2882
  	clear_bit(PFLG_DRIVER_PROBING, &base_vha->pci_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2883
  	return 0;
6e9f21f3d   Anirban Chakraborty   [SCSI] qla2xxx: F...
2884
  probe_init_failed:
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2885
  	qla2x00_free_req_que(ha, req);
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
2886
2887
  	ha->req_q_map[0] = NULL;
  	clear_bit(0, ha->req_qid_map);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2888
  	qla2x00_free_rsp_que(ha, rsp);
9a347ff40   Chad Dupuis   [SCSI] qla2xxx: H...
2889
2890
  	ha->rsp_q_map[0] = NULL;
  	clear_bit(0, ha->rsp_qid_map);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
2891
  	ha->max_req_queues = ha->max_rsp_queues = 0;
6e9f21f3d   Anirban Chakraborty   [SCSI] qla2xxx: F...
2892

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2893
  probe_failed:
b99787698   Andrew Vasquez   [SCSI] qla2xxx: E...
2894
2895
2896
2897
2898
2899
2900
2901
2902
  	if (base_vha->timer_active)
  		qla2x00_stop_timer(base_vha);
  	base_vha->flags.online = 0;
  	if (ha->dpc_thread) {
  		struct task_struct *t = ha->dpc_thread;
  
  		ha->dpc_thread = NULL;
  		kthread_stop(t);
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2903
  	qla2x00_free_device(base_vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2904

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2905
  	scsi_host_put(base_vha->host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2906

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2907
  probe_hw_failed:
1a2fbf185   Joe Lawrence   qla2xxx: Use qla2...
2908
  	qla2x00_clear_drv_active(ha);
0a63ad12e   Saurav Kashyap   [SCSI] qla2xxx: D...
2909
  iospace_config_failed:
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
2910
  	if (IS_P3P_TYPE(ha)) {
0a63ad12e   Saurav Kashyap   [SCSI] qla2xxx: D...
2911
  		if (!ha->nx_pcibase)
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2912
  			iounmap((device_reg_t *)ha->nx_pcibase);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2913
  		if (!ql2xdbwr)
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
2914
  			iounmap((device_reg_t *)ha->nxdb_wr_ptr);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2915
2916
2917
  	} else {
  		if (ha->iobase)
  			iounmap(ha->iobase);
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
2918
2919
  		if (ha->cregbase)
  			iounmap(ha->cregbase);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
2920
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2921
2922
2923
  	pci_release_selected_regions(ha->pdev, ha->bars);
  	kfree(ha);
  	ha = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2924

a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2925
  probe_out:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2926
  	pci_disable_device(pdev);
a1541d5af   Andrew Vasquez   [SCSI] qla2xxx: P...
2927
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2928
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2929

4c993f766   Adrian Bunk   scsi/qla2xxx/qla_...
2930
  static void
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
2931
2932
2933
2934
  qla2x00_shutdown(struct pci_dev *pdev)
  {
  	scsi_qla_host_t *vha;
  	struct qla_hw_data  *ha;
552f3f9ac   Masanari Iida   [SCSI] qla2xxx: A...
2935
2936
  	if (!atomic_read(&pdev->enable_cnt))
  		return;
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
2937
2938
  	vha = pci_get_drvdata(pdev);
  	ha = vha->hw;
424793439   Armen Baloyan   [SCSI] qla2xxx: N...
2939
2940
2941
  	/* Notify ISPFX00 firmware */
  	if (IS_QLAFX00(ha))
  		qlafx00_driver_shutdown(vha, 20);
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
  	/* Turn-off FCE trace */
  	if (ha->flags.fce_enabled) {
  		qla2x00_disable_fce_trace(vha, NULL, NULL);
  		ha->flags.fce_enabled = 0;
  	}
  
  	/* Turn-off EFT trace */
  	if (ha->eft)
  		qla2x00_disable_eft_trace(vha);
  
  	/* Stop currently executing firmware. */
  	qla2x00_try_to_stop_firmware(vha);
  
  	/* Turn adapter off line */
  	vha->flags.online = 0;
  
  	/* turn-off interrupts on the card */
  	if (ha->interrupts_on) {
  		vha->flags.init_done = 0;
  		ha->isp_ops->disable_intrs(ha);
  	}
  
  	qla2x00_free_irqs(vha);
  
  	qla2x00_free_fw_dump(ha);
61d41f610   Chad Dupuis   qla2xxx: Disable ...
2967
2968
2969
  
  	pci_disable_pcie_error_reporting(pdev);
  	pci_disable_device(pdev);
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
2970
  }
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
2971
  /* Deletes all the virtual ports for a given ha */
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
2972
  static void
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
2973
  qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2974
  {
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
2975
2976
  	struct Scsi_Host *scsi_host;
  	scsi_qla_host_t *vha;
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
2977
  	unsigned long flags;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2978

43ebf16d7   Arun Easi   [SCSI] qla2xxx: F...
2979
2980
  	mutex_lock(&ha->vport_lock);
  	while (ha->cur_vport_count) {
43ebf16d7   Arun Easi   [SCSI] qla2xxx: F...
2981
  		spin_lock_irqsave(&ha->vport_slock, flags);
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
2982

43ebf16d7   Arun Easi   [SCSI] qla2xxx: F...
2983
2984
2985
  		BUG_ON(base_vha->list.next == &ha->vp_list);
  		/* This assumes first entry in ha->vp_list is always base vha */
  		vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
2986
  		scsi_host = scsi_host_get(vha->host);
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
2987

43ebf16d7   Arun Easi   [SCSI] qla2xxx: F...
2988
2989
2990
2991
2992
  		spin_unlock_irqrestore(&ha->vport_slock, flags);
  		mutex_unlock(&ha->vport_lock);
  
  		fc_vport_terminate(vha->fc_vport);
  		scsi_host_put(vha->host);
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
2993

43ebf16d7   Arun Easi   [SCSI] qla2xxx: F...
2994
  		mutex_lock(&ha->vport_lock);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
2995
  	}
43ebf16d7   Arun Easi   [SCSI] qla2xxx: F...
2996
  	mutex_unlock(&ha->vport_lock);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
2997
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2998

fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
2999
3000
3001
3002
  /* Stops all deferred work threads */
  static void
  qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
  {
68ca949cd   Anirban Chakraborty   [SCSI] qla2xxx: A...
3003
3004
3005
3006
3007
3008
  	/* Flush the work queue and remove it */
  	if (ha->wq) {
  		flush_workqueue(ha->wq);
  		destroy_workqueue(ha->wq);
  		ha->wq = NULL;
  	}
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
  	/* Cancel all work and destroy DPC workqueues */
  	if (ha->dpc_lp_wq) {
  		cancel_work_sync(&ha->idc_aen);
  		destroy_workqueue(ha->dpc_lp_wq);
  		ha->dpc_lp_wq = NULL;
  	}
  
  	if (ha->dpc_hp_wq) {
  		cancel_work_sync(&ha->nic_core_reset);
  		cancel_work_sync(&ha->idc_state_handler);
  		cancel_work_sync(&ha->nic_core_unrecoverable);
  		destroy_workqueue(ha->dpc_hp_wq);
  		ha->dpc_hp_wq = NULL;
  	}
b99787698   Andrew Vasquez   [SCSI] qla2xxx: E...
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
  	/* Kill the kernel thread for this host */
  	if (ha->dpc_thread) {
  		struct task_struct *t = ha->dpc_thread;
  
  		/*
  		 * qla2xxx_wake_dpc checks for ->dpc_thread
  		 * so we need to zero it out.
  		 */
  		ha->dpc_thread = NULL;
  		kthread_stop(t);
  	}
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3034
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3035

fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3036
3037
3038
  static void
  qla2x00_unmap_iobases(struct qla_hw_data *ha)
  {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3039
  	if (IS_QLA82XX(ha)) {
b963752f4   Giridhar Malavali   [SCSI] qla2xxx: C...
3040

f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3041
  		iounmap((device_reg_t *)ha->nx_pcibase);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3042
  		if (!ql2xdbwr)
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3043
  			iounmap((device_reg_t *)ha->nxdb_wr_ptr);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3044
3045
3046
  	} else {
  		if (ha->iobase)
  			iounmap(ha->iobase);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3047

8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
3048
3049
  		if (ha->cregbase)
  			iounmap(ha->cregbase);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3050
3051
  		if (ha->mqiobase)
  			iounmap(ha->mqiobase);
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
3052

f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3053
  		if ((IS_QLA83XX(ha) || IS_QLA27XX(ha)) && ha->msixbase)
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
3054
  			iounmap(ha->msixbase);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3055
  	}
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3056
3057
3058
  }
  
  static void
db7157d4c   Joe Lawrence   qla2xxx: Fix shos...
3059
  qla2x00_clear_drv_active(struct qla_hw_data *ha)
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3060
  {
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3061
3062
  	if (IS_QLA8044(ha)) {
  		qla8044_idc_lock(ha);
c41afc9a7   Saurav Kashyap   [SCSI] qla2xxx: F...
3063
  		qla8044_clear_drv_active(ha);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
  		qla8044_idc_unlock(ha);
  	} else if (IS_QLA82XX(ha)) {
  		qla82xx_idc_lock(ha);
  		qla82xx_clear_drv_active(ha);
  		qla82xx_idc_unlock(ha);
  	}
  }
  
  static void
  qla2x00_remove_one(struct pci_dev *pdev)
  {
  	scsi_qla_host_t *base_vha;
  	struct qla_hw_data  *ha;
beb9e315e   Joe Lawrence   qla2xxx: Prevent ...
3077
3078
3079
3080
3081
3082
3083
  	base_vha = pci_get_drvdata(pdev);
  	ha = base_vha->hw;
  
  	/* Indicate device removal to prevent future board_disable and wait
  	 * until any pending board_disable has completed. */
  	set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags);
  	cancel_work_sync(&ha->board_disable);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3084
  	/*
beb9e315e   Joe Lawrence   qla2xxx: Prevent ...
3085
3086
3087
  	 * If the PCI device is disabled then there was a PCI-disconnect and
  	 * qla2x00_disable_board_on_pci_error has taken care of most of the
  	 * resources.
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3088
  	 */
beb9e315e   Joe Lawrence   qla2xxx: Prevent ...
3089
3090
3091
3092
  	if (!atomic_read(&pdev->enable_cnt)) {
  		scsi_host_put(base_vha->host);
  		kfree(ha);
  		pci_set_drvdata(pdev, NULL);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3093
  		return;
beb9e315e   Joe Lawrence   qla2xxx: Prevent ...
3094
  	}
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3095

638a1a01d   Sawan Chandak   qla2xxx: Delay dr...
3096
  	qla2x00_wait_for_hba_ready(base_vha);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
  	set_bit(UNLOADING, &base_vha->dpc_flags);
  
  	if (IS_QLAFX00(ha))
  		qlafx00_driver_shutdown(base_vha, 20);
  
  	qla2x00_delete_all_vps(ha, base_vha);
  
  	if (IS_QLA8031(ha)) {
  		ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
  		    "Clearing fcoe driver presence.
  ");
  		if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
  			    "Error while clearing DRV-Presence.
  ");
  	}
  
  	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
  
  	qla2x00_dfs_remove(base_vha);
  
  	qla84xx_put_chip(base_vha);
2d5a4c344   Himanshu Madhani   qla2xxx: Disable ...
3119
3120
3121
  	/* Laser should be disabled only for ISP2031 */
  	if (IS_QLA2031(ha))
  		qla83xx_disable_laser(base_vha);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
  	/* Disable timer */
  	if (base_vha->timer_active)
  		qla2x00_stop_timer(base_vha);
  
  	base_vha->flags.online = 0;
  
  	qla2x00_destroy_deferred_work(ha);
  
  	qlt_remove_target(ha, base_vha);
  
  	qla2x00_free_sysfs_attr(base_vha, true);
  
  	fc_remove_host(base_vha->host);
  
  	scsi_remove_host(base_vha->host);
  
  	qla2x00_free_device(base_vha);
db7157d4c   Joe Lawrence   qla2xxx: Fix shos...
3139
  	qla2x00_clear_drv_active(ha);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3140

d2749ffad   Arun Easi   qla2xxx: Unload o...
3141
  	scsi_host_put(base_vha->host);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3142
  	qla2x00_unmap_iobases(ha);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3143

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3144
3145
3146
  	pci_release_selected_regions(ha->pdev, ha->bars);
  	kfree(ha);
  	ha = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3147

90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
3148
  	pci_disable_pcie_error_reporting(pdev);
665db93b8   Bernhard Walle   [SCSI] qla2xxx: R...
3149
  	pci_disable_device(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3150
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3151
3152
  
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3153
  qla2x00_free_device(scsi_qla_host_t *vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3154
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3155
  	struct qla_hw_data *ha = vha->hw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3156

858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
3157
3158
3159
3160
3161
  	qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
  
  	/* Disable timer */
  	if (vha->timer_active)
  		qla2x00_stop_timer(vha);
2afa19a93   Anirban Chakraborty   [SCSI] qla2xxx: A...
3162
  	qla25xx_delete_queues(vha);
fe1b806f4   Chad Dupuis   [SCSI] qla2xxx: R...
3163

df613b960   Andrew Vasquez   [SCSI] qla2xxx: A...
3164
  	if (ha->flags.fce_enabled)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3165
  		qla2x00_disable_fce_trace(vha, NULL, NULL);
df613b960   Andrew Vasquez   [SCSI] qla2xxx: A...
3166

a7a167bf7   Andrew Vasquez   [SCSI] qla2xxx: R...
3167
  	if (ha->eft)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3168
  		qla2x00_disable_eft_trace(vha);
a7a167bf7   Andrew Vasquez   [SCSI] qla2xxx: R...
3169

f6ef3b187   Andrew Vasquez   [SCSI] qla2xxx: S...
3170
  	/* Stop currently executing firmware. */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3171
  	qla2x00_try_to_stop_firmware(vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3172

858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
3173
  	vha->flags.online = 0;
f6ef3b187   Andrew Vasquez   [SCSI] qla2xxx: S...
3174
  	/* turn-off interrupts on the card */
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3175
3176
  	if (ha->interrupts_on) {
  		vha->flags.init_done = 0;
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
3177
  		ha->isp_ops->disable_intrs(ha);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3178
  	}
f6ef3b187   Andrew Vasquez   [SCSI] qla2xxx: S...
3179

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3180
  	qla2x00_free_irqs(vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3181

8867048b4   Chad Dupuis   [SCSI] qla2xxx: A...
3182
  	qla2x00_free_fcports(vha);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3183
  	qla2x00_mem_free(ha);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3184

08de2844c   Giridhar Malavali   [SCSI] qla2xxx: A...
3185
  	qla82xx_md_free(vha);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3186
  	qla2x00_free_queues(ha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3187
  }
8867048b4   Chad Dupuis   [SCSI] qla2xxx: A...
3188
3189
3190
3191
3192
3193
  void qla2x00_free_fcports(struct scsi_qla_host *vha)
  {
  	fc_port_t *fcport, *tfcport;
  
  	list_for_each_entry_safe(fcport, tfcport, &vha->vp_fcports, list) {
  		list_del(&fcport->list);
5f16b331d   Chad Dupuis   [SCSI] qla2xxx: U...
3194
  		qla2x00_clear_loop_id(fcport);
8867048b4   Chad Dupuis   [SCSI] qla2xxx: A...
3195
3196
3197
3198
  		kfree(fcport);
  		fcport = NULL;
  	}
  }
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3199
  static inline void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3200
  qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3201
3202
      int defer)
  {
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3203
  	struct fc_rport *rport;
67becc004   Andrew Vasquez   [SCSI] qla2xxx: P...
3204
  	scsi_qla_host_t *base_vha;
044d78e1a   Madhuranath Iyengar   [SCSI] qla2xxx: C...
3205
  	unsigned long flags;
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3206
3207
3208
3209
3210
3211
  
  	if (!fcport->rport)
  		return;
  
  	rport = fcport->rport;
  	if (defer) {
67becc004   Andrew Vasquez   [SCSI] qla2xxx: P...
3212
  		base_vha = pci_get_drvdata(vha->hw->pdev);
044d78e1a   Madhuranath Iyengar   [SCSI] qla2xxx: C...
3213
  		spin_lock_irqsave(vha->host->host_lock, flags);
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3214
  		fcport->drport = rport;
044d78e1a   Madhuranath Iyengar   [SCSI] qla2xxx: C...
3215
  		spin_unlock_irqrestore(vha->host->host_lock, flags);
67becc004   Andrew Vasquez   [SCSI] qla2xxx: P...
3216
3217
  		set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
  		qla2xxx_wake_dpc(base_vha);
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3218
  	} else {
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3219
  		fc_remote_port_delete(rport);
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3220
3221
  		qlt_fc_port_deleted(vha, fcport);
  	}
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3222
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3223
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3224
3225
3226
3227
3228
3229
3230
3231
   * qla2x00_mark_device_lost Updates fcport state when device goes offline.
   *
   * Input: ha = adapter block pointer.  fcport = port structure pointer.
   *
   * Return: None.
   *
   * Context:
   */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3232
  void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
3233
      int do_login, int defer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3234
  {
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
3235
3236
3237
3238
3239
  	if (IS_QLAFX00(vha->hw)) {
  		qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
  		qla2x00_schedule_rport_del(vha, fcport, defer);
  		return;
  	}
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
3240
  	if (atomic_read(&fcport->state) == FCS_ONLINE &&
c6d39e23d   Joe Carnuccio   [SCSI] qla2xxx: R...
3241
  	    vha->vp_idx == fcport->vha->vp_idx) {
ec426e106   Chad Dupuis   [SCSI] qla2xxx: L...
3242
  		qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3243
3244
  		qla2x00_schedule_rport_del(vha, fcport, defer);
  	}
fa2a1ce53   Andrew Vasquez   [SCSI] qla2xxx: C...
3245
  	/*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3246
3247
3248
3249
  	 * We may need to retry the login, so don't change the state of the
  	 * port but do the retries.
  	 */
  	if (atomic_read(&fcport->state) != FCS_DEVICE_DEAD)
ec426e106   Chad Dupuis   [SCSI] qla2xxx: L...
3250
  		qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3251
3252
3253
3254
3255
  
  	if (!do_login)
  		return;
  
  	if (fcport->login_retry == 0) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3256
3257
  		fcport->login_retry = vha->hw->login_retry_count;
  		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3258

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3259
  		ql_dbg(ql_dbg_disc, vha, 0x2067,
7b8335589   Oleksandr Khoshaba   [SCSI] qla2xxx: P...
3260
3261
3262
  		    "Port login retry %8phN, id = 0x%04x retry cnt=%d.
  ",
  		    fcport->port_name, fcport->loop_id, fcport->login_retry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
  	}
  }
  
  /*
   * qla2x00_mark_all_devices_lost
   *	Updates fcport state when device goes offline.
   *
   * Input:
   *	ha = adapter block pointer.
   *	fcport = port structure pointer.
   *
   * Return:
   *	None.
   *
   * Context:
   */
  void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3280
  qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3281
3282
  {
  	fc_port_t *fcport;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3283
  	list_for_each_entry(fcport, &vha->vp_fcports, list) {
c6d39e23d   Joe Carnuccio   [SCSI] qla2xxx: R...
3284
  		if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3285
  			continue;
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
3286

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3287
3288
3289
3290
3291
3292
  		/*
  		 * No point in marking the device as lost, if the device is
  		 * already DEAD.
  		 */
  		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
  			continue;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3293
  		if (atomic_read(&fcport->state) == FCS_ONLINE) {
ec426e106   Chad Dupuis   [SCSI] qla2xxx: L...
3294
  			qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
3295
3296
  			if (defer)
  				qla2x00_schedule_rport_del(vha, fcport, defer);
c6d39e23d   Joe Carnuccio   [SCSI] qla2xxx: R...
3297
  			else if (vha->vp_idx == fcport->vha->vp_idx)
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
3298
3299
  				qla2x00_schedule_rport_del(vha, fcport, defer);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3300
3301
3302
3303
3304
3305
3306
3307
3308
  	}
  }
  
  /*
  * qla2x00_mem_alloc
  *      Allocates adapter memory.
  *
  * Returns:
  *      0  = success.
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3309
  *      !0  = failure.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3310
  */
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3311
  static int
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3312
3313
  qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
  	struct req_que **req, struct rsp_que **rsp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3314
3315
  {
  	char	name[16];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3316

e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3317
  	ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3318
  		&ha->init_cb_dma, GFP_KERNEL);
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3319
  	if (!ha->init_cb)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3320
  		goto fail;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3321

2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3322
3323
  	if (qlt_mem_alloc(ha) < 0)
  		goto fail_free_init_cb;
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
3324
3325
  	ha->gid_list = dma_alloc_coherent(&ha->pdev->dev,
  		qla2x00_gid_list_size(ha), &ha->gid_list_dma, GFP_KERNEL);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3326
  	if (!ha->gid_list)
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3327
  		goto fail_free_tgt_mem;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3328

e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3329
3330
  	ha->srb_mempool = mempool_create_slab_pool(SRB_MIN_REQ, srb_cachep);
  	if (!ha->srb_mempool)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3331
  		goto fail_free_gid_list;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3332

7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
3333
  	if (IS_P3P_TYPE(ha)) {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
  		/* Allocate cache for CT6 Ctx. */
  		if (!ctx_cachep) {
  			ctx_cachep = kmem_cache_create("qla2xxx_ctx",
  				sizeof(struct ct6_dsd), 0,
  				SLAB_HWCACHE_ALIGN, NULL);
  			if (!ctx_cachep)
  				goto fail_free_gid_list;
  		}
  		ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ,
  			ctx_cachep);
  		if (!ha->ctx_mempool)
  			goto fail_free_srb_mempool;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3346
3347
3348
3349
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0021,
  		    "ctx_cachep=%p ctx_mempool=%p.
  ",
  		    ctx_cachep, ha->ctx_mempool);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3350
  	}
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3351
3352
3353
  	/* Get memory for cached NVRAM */
  	ha->nvram = kzalloc(MAX_NVRAM_SIZE, GFP_KERNEL);
  	if (!ha->nvram)
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3354
  		goto fail_free_ctx_mempool;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3355

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3356
3357
3358
3359
3360
3361
  	snprintf(name, sizeof(name), "%s_%d", QLA2XXX_DRIVER_NAME,
  		ha->pdev->device);
  	ha->s_dma_pool = dma_pool_create(name, &ha->pdev->dev,
  		DMA_POOL_SIZE, 8, 0);
  	if (!ha->s_dma_pool)
  		goto fail_free_nvram;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3362
3363
3364
3365
  	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0022,
  	    "init_cb=%p gid_list=%p, srb_mempool=%p s_dma_pool=%p.
  ",
  	    ha->init_cb, ha->gid_list, ha->srb_mempool, ha->s_dma_pool);
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
3366
  	if (IS_P3P_TYPE(ha) || ql2xenabledif) {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3367
3368
3369
  		ha->dl_dma_pool = dma_pool_create(name, &ha->pdev->dev,
  			DSD_LIST_DMA_POOL_SIZE, 8, 0);
  		if (!ha->dl_dma_pool) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3370
3371
3372
  			ql_log_pci(ql_log_fatal, ha->pdev, 0x0023,
  			    "Failed to allocate memory for dl_dma_pool.
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3373
3374
3375
3376
3377
3378
  			goto fail_s_dma_pool;
  		}
  
  		ha->fcp_cmnd_dma_pool = dma_pool_create(name, &ha->pdev->dev,
  			FCP_CMND_DMA_POOL_SIZE, 8, 0);
  		if (!ha->fcp_cmnd_dma_pool) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3379
3380
3381
  			ql_log_pci(ql_log_fatal, ha->pdev, 0x0024,
  			    "Failed to allocate memory for fcp_cmnd_dma_pool.
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3382
3383
  			goto fail_dl_dma_pool;
  		}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3384
3385
3386
3387
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0025,
  		    "dl_dma_pool=%p fcp_cmnd_dma_pool=%p.
  ",
  		    ha->dl_dma_pool, ha->fcp_cmnd_dma_pool);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3388
  	}
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3389
3390
  	/* Allocate memory for SNS commands */
  	if (IS_QLA2100(ha) || IS_QLA2200(ha)) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3391
  	/* Get consistent memory allocated for SNS commands */
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3392
  		ha->sns_cmd = dma_alloc_coherent(&ha->pdev->dev,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3393
  		sizeof(struct sns_cmd_pkt), &ha->sns_cmd_dma, GFP_KERNEL);
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3394
  		if (!ha->sns_cmd)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3395
  			goto fail_dma_pool;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3396
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0026,
d8424f68c   Joe Perches   [SCSI] qla2xxx: M...
3397
3398
  		    "sns_cmd: %p.
  ", ha->sns_cmd);
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3399
  	} else {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3400
  	/* Get consistent memory allocated for MS IOCB */
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3401
  		ha->ms_iocb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3402
  			&ha->ms_iocb_dma);
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3403
  		if (!ha->ms_iocb)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3404
3405
  			goto fail_dma_pool;
  	/* Get consistent memory allocated for CT SNS commands */
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3406
  		ha->ct_sns = dma_alloc_coherent(&ha->pdev->dev,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3407
  			sizeof(struct ct_sns_pkt), &ha->ct_sns_dma, GFP_KERNEL);
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3408
3409
  		if (!ha->ct_sns)
  			goto fail_free_ms_iocb;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3410
3411
3412
3413
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0027,
  		    "ms_iocb=%p ct_sns=%p.
  ",
  		    ha->ms_iocb, ha->ct_sns);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3414
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3415
  	/* Allocate memory for request ring */
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3416
3417
  	*req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
  	if (!*req) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3418
3419
3420
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0028,
  		    "Failed to allocate memory for req.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3421
3422
  		goto fail_req;
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3423
3424
3425
3426
3427
  	(*req)->length = req_len;
  	(*req)->ring = dma_alloc_coherent(&ha->pdev->dev,
  		((*req)->length + 1) * sizeof(request_t),
  		&(*req)->dma, GFP_KERNEL);
  	if (!(*req)->ring) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3428
3429
3430
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0029,
  		    "Failed to allocate memory for req_ring.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3431
3432
3433
  		goto fail_req_ring;
  	}
  	/* Allocate memory for response ring */
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3434
3435
  	*rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
  	if (!*rsp) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3436
3437
3438
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x002a,
  		    "Failed to allocate memory for rsp.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3439
3440
  		goto fail_rsp;
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3441
3442
3443
3444
3445
3446
  	(*rsp)->hw = ha;
  	(*rsp)->length = rsp_len;
  	(*rsp)->ring = dma_alloc_coherent(&ha->pdev->dev,
  		((*rsp)->length + 1) * sizeof(response_t),
  		&(*rsp)->dma, GFP_KERNEL);
  	if (!(*rsp)->ring) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3447
3448
3449
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x002b,
  		    "Failed to allocate memory for rsp_ring.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3450
3451
  		goto fail_rsp_ring;
  	}
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3452
3453
  	(*req)->rsp = *rsp;
  	(*rsp)->req = *req;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3454
3455
3456
3457
3458
3459
  	ql_dbg_pci(ql_dbg_init, ha->pdev, 0x002c,
  	    "req=%p req->length=%d req->ring=%p rsp=%p "
  	    "rsp->length=%d rsp->ring=%p.
  ",
  	    *req, (*req)->length, (*req)->ring, *rsp, (*rsp)->length,
  	    (*rsp)->ring);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3460
3461
3462
  	/* Allocate memory for NVRAM data for vports */
  	if (ha->nvram_npiv_size) {
  		ha->npiv_info = kzalloc(sizeof(struct qla_npiv_entry) *
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3463
  		    ha->nvram_npiv_size, GFP_KERNEL);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3464
  		if (!ha->npiv_info) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3465
3466
3467
  			ql_log_pci(ql_log_fatal, ha->pdev, 0x002d,
  			    "Failed to allocate memory for npiv_info.
  ");
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3468
3469
3470
3471
  			goto fail_npiv_info;
  		}
  	} else
  		ha->npiv_info = NULL;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3472

b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3473
  	/* Get consistent memory allocated for EX-INIT-CB. */
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3474
  	if (IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha)) {
b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3475
3476
3477
3478
  		ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
  		    &ha->ex_init_cb_dma);
  		if (!ha->ex_init_cb)
  			goto fail_ex_init_cb;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3479
3480
3481
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x002e,
  		    "ex_init_cb=%p.
  ", ha->ex_init_cb);
b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3482
  	}
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3483
  	INIT_LIST_HEAD(&ha->gbl_dsd_list);
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3484
3485
3486
3487
3488
3489
  	/* Get consistent memory allocated for Async Port-Database. */
  	if (!IS_FWI2_CAPABLE(ha)) {
  		ha->async_pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
  			&ha->async_pd_dma);
  		if (!ha->async_pd)
  			goto fail_async_pd;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3490
3491
3492
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x002f,
  		    "async_pd=%p.
  ", ha->async_pd);
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3493
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3494
  	INIT_LIST_HEAD(&ha->vp_list);
5f16b331d   Chad Dupuis   [SCSI] qla2xxx: U...
3495
3496
3497
3498
3499
3500
3501
3502
3503
  
  	/* Allocate memory for our loop_id bitmap */
  	ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long),
  	    GFP_KERNEL);
  	if (!ha->loop_id_map)
  		goto fail_async_pd;
  	else {
  		qla2x00_set_reserved_loop_ids(ha);
  		ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123,
b2a72ec32   Dan Carpenter   [SCSI] qla2xxx: f...
3504
3505
  		    "loop_id_map=%p.
  ", ha->loop_id_map);
5f16b331d   Chad Dupuis   [SCSI] qla2xxx: U...
3506
  	}
b2a72ec32   Dan Carpenter   [SCSI] qla2xxx: f...
3507
  	return 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3508

5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3509
3510
  fail_async_pd:
  	dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3511
3512
  fail_ex_init_cb:
  	kfree(ha->npiv_info);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3513
3514
3515
3516
3517
  fail_npiv_info:
  	dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
  		sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
  	(*rsp)->ring = NULL;
  	(*rsp)->dma = 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3518
  fail_rsp_ring:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3519
  	kfree(*rsp);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3520
  fail_rsp:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3521
3522
3523
3524
  	dma_free_coherent(&ha->pdev->dev, ((*req)->length + 1) *
  		sizeof(request_t), (*req)->ring, (*req)->dma);
  	(*req)->ring = NULL;
  	(*req)->dma = 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3525
  fail_req_ring:
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3526
  	kfree(*req);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3527
3528
3529
3530
3531
  fail_req:
  	dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
  		ha->ct_sns, ha->ct_sns_dma);
  	ha->ct_sns = NULL;
  	ha->ct_sns_dma = 0;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3532
3533
3534
3535
  fail_free_ms_iocb:
  	dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
  	ha->ms_iocb = NULL;
  	ha->ms_iocb_dma = 0;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3536
  fail_dma_pool:
bad750028   Arun Easi   [SCSI] qla2xxx: T...
3537
  	if (IS_QLA82XX(ha) || ql2xenabledif) {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3538
3539
3540
3541
  		dma_pool_destroy(ha->fcp_cmnd_dma_pool);
  		ha->fcp_cmnd_dma_pool = NULL;
  	}
  fail_dl_dma_pool:
bad750028   Arun Easi   [SCSI] qla2xxx: T...
3542
  	if (IS_QLA82XX(ha) || ql2xenabledif) {
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3543
3544
3545
3546
  		dma_pool_destroy(ha->dl_dma_pool);
  		ha->dl_dma_pool = NULL;
  	}
  fail_s_dma_pool:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3547
3548
  	dma_pool_destroy(ha->s_dma_pool);
  	ha->s_dma_pool = NULL;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3549
3550
3551
  fail_free_nvram:
  	kfree(ha->nvram);
  	ha->nvram = NULL;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3552
3553
3554
  fail_free_ctx_mempool:
  	mempool_destroy(ha->ctx_mempool);
  	ha->ctx_mempool = NULL;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3555
3556
3557
  fail_free_srb_mempool:
  	mempool_destroy(ha->srb_mempool);
  	ha->srb_mempool = NULL;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3558
  fail_free_gid_list:
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
3559
3560
  	dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
  	ha->gid_list,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3561
  	ha->gid_list_dma);
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3562
3563
  	ha->gid_list = NULL;
  	ha->gid_list_dma = 0;
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3564
3565
  fail_free_tgt_mem:
  	qlt_mem_free(ha);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3566
3567
3568
3569
3570
  fail_free_init_cb:
  	dma_free_coherent(&ha->pdev->dev, ha->init_cb_size, ha->init_cb,
  	ha->init_cb_dma);
  	ha->init_cb = NULL;
  	ha->init_cb_dma = 0;
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3571
  fail:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3572
3573
3574
  	ql_log(ql_log_fatal, NULL, 0x0030,
  	    "Memory allocation failure.
  ");
e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3575
  	return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3576
3577
3578
  }
  
  /*
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3579
3580
  * qla2x00_free_fw_dump
  *	Frees fw dump stuff.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3581
3582
  *
  * Input:
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
3583
  *	ha = adapter block pointer
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3584
  */
a824ebb37   Adrian Bunk   [SCSI] qla2xxx: C...
3585
  static void
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3586
  qla2x00_free_fw_dump(struct qla_hw_data *ha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3587
  {
df613b960   Andrew Vasquez   [SCSI] qla2xxx: A...
3588
  	if (ha->fce)
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3589
3590
  		dma_free_coherent(&ha->pdev->dev,
  		    FCE_SIZE, ha->fce, ha->fce_dma);
df613b960   Andrew Vasquez   [SCSI] qla2xxx: A...
3591

f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3592
3593
3594
3595
3596
  	if (ha->eft)
  		dma_free_coherent(&ha->pdev->dev,
  		    EFT_SIZE, ha->eft, ha->eft_dma);
  
  	if (ha->fw_dump)
a7a167bf7   Andrew Vasquez   [SCSI] qla2xxx: R...
3597
  		vfree(ha->fw_dump);
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3598
3599
  	if (ha->fw_dump_template)
  		vfree(ha->fw_dump_template);
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3600
3601
3602
3603
  	ha->fce = NULL;
  	ha->fce_dma = 0;
  	ha->eft = NULL;
  	ha->eft_dma = 0;
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3604
  	ha->fw_dumped = 0;
61f098dde   Hiral Patel   qla2xxx: Introduc...
3605
  	ha->fw_dump_cap_flags = 0;
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3606
  	ha->fw_dump_reading = 0;
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
3607
3608
3609
3610
  	ha->fw_dump = NULL;
  	ha->fw_dump_len = 0;
  	ha->fw_dump_template = NULL;
  	ha->fw_dump_template_len = 0;
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
  }
  
  /*
  * qla2x00_mem_free
  *      Frees all adapter allocated memory.
  *
  * Input:
  *      ha = adapter block pointer.
  */
  static void
  qla2x00_mem_free(struct qla_hw_data *ha)
  {
  	qla2x00_free_fw_dump(ha);
81178772b   Saurav Kashyap   [SCSI] qla2xxx: I...
3624
3625
3626
  	if (ha->mctp_dump)
  		dma_free_coherent(&ha->pdev->dev, MCTP_DUMP_SIZE, ha->mctp_dump,
  		    ha->mctp_dump_dma);
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
3627
3628
  	if (ha->srb_mempool)
  		mempool_destroy(ha->srb_mempool);
a7a167bf7   Andrew Vasquez   [SCSI] qla2xxx: R...
3629

11bbc1d89   Andrew Vasquez   [SCSI] qla2xxx: E...
3630
3631
3632
  	if (ha->dcbx_tlv)
  		dma_free_coherent(&ha->pdev->dev, DCBX_TLV_DATA_SIZE,
  		    ha->dcbx_tlv, ha->dcbx_tlv_dma);
ce0423f4a   Andrew Vasquez   [SCSI] qla2xxx: E...
3633
3634
3635
  	if (ha->xgmac_data)
  		dma_free_coherent(&ha->pdev->dev, XGMAC_DATA_SIZE,
  		    ha->xgmac_data, ha->xgmac_data_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3636
3637
  	if (ha->sns_cmd)
  		dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3638
  		ha->sns_cmd, ha->sns_cmd_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3639
3640
3641
  
  	if (ha->ct_sns)
  		dma_free_coherent(&ha->pdev->dev, sizeof(struct ct_sns_pkt),
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3642
  		ha->ct_sns, ha->ct_sns_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3643

88729e53a   Andrew Vasquez   [SCSI] qla2xxx: A...
3644
3645
  	if (ha->sfp_data)
  		dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3646
3647
  	if (ha->ms_iocb)
  		dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3648
  	if (ha->ex_init_cb)
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3649
3650
  		dma_pool_free(ha->s_dma_pool,
  			ha->ex_init_cb, ha->ex_init_cb_dma);
b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3651

5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3652
3653
  	if (ha->async_pd)
  		dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3654
3655
  	if (ha->s_dma_pool)
  		dma_pool_destroy(ha->s_dma_pool);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3656
  	if (ha->gid_list)
642ef9838   Chad Dupuis   [SCSI] qla2xxx: A...
3657
3658
  		dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha),
  		ha->gid_list, ha->gid_list_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3659

a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
  	if (IS_QLA82XX(ha)) {
  		if (!list_empty(&ha->gbl_dsd_list)) {
  			struct dsd_dma *dsd_ptr, *tdsd_ptr;
  
  			/* clean up allocated prev pool */
  			list_for_each_entry_safe(dsd_ptr,
  				tdsd_ptr, &ha->gbl_dsd_list, list) {
  				dma_pool_free(ha->dl_dma_pool,
  				dsd_ptr->dsd_addr, dsd_ptr->dsd_list_dma);
  				list_del(&dsd_ptr->list);
  				kfree(dsd_ptr);
  			}
  		}
  	}
  
  	if (ha->dl_dma_pool)
  		dma_pool_destroy(ha->dl_dma_pool);
  
  	if (ha->fcp_cmnd_dma_pool)
  		dma_pool_destroy(ha->fcp_cmnd_dma_pool);
  
  	if (ha->ctx_mempool)
  		mempool_destroy(ha->ctx_mempool);
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3683
  	qlt_mem_free(ha);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3684
3685
  	if (ha->init_cb)
  		dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3686
  			ha->init_cb, ha->init_cb_dma);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3687
3688
  	vfree(ha->optrom_buffer);
  	kfree(ha->nvram);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
3689
  	kfree(ha->npiv_info);
7a67735b0   Andrew Vasquez   [SCSI] qla2xxx: C...
3690
  	kfree(ha->swl);
5f16b331d   Chad Dupuis   [SCSI] qla2xxx: U...
3691
  	kfree(ha->loop_id_map);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3692

e87110852   Andrew Vasquez   [SCSI] qla2xxx: C...
3693
  	ha->srb_mempool = NULL;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3694
  	ha->ctx_mempool = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3695
3696
3697
3698
3699
3700
  	ha->sns_cmd = NULL;
  	ha->sns_cmd_dma = 0;
  	ha->ct_sns = NULL;
  	ha->ct_sns_dma = 0;
  	ha->ms_iocb = NULL;
  	ha->ms_iocb_dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3701
3702
  	ha->init_cb = NULL;
  	ha->init_cb_dma = 0;
b64b0e8fd   Andrew Vasquez   [SCSI] qla2xxx: P...
3703
3704
  	ha->ex_init_cb = NULL;
  	ha->ex_init_cb_dma = 0;
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3705
3706
  	ha->async_pd = NULL;
  	ha->async_pd_dma = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3707
3708
  
  	ha->s_dma_pool = NULL;
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
3709
3710
  	ha->dl_dma_pool = NULL;
  	ha->fcp_cmnd_dma_pool = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3711

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3712
3713
  	ha->gid_list = NULL;
  	ha->gid_list_dma = 0;
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
3714
3715
3716
3717
  
  	ha->tgt.atio_ring = NULL;
  	ha->tgt.atio_dma = 0;
  	ha->tgt.tgt_vp_map = NULL;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3718
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3719

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3720
3721
3722
3723
3724
  struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
  						struct qla_hw_data *ha)
  {
  	struct Scsi_Host *host;
  	struct scsi_qla_host *vha = NULL;
854165f42   Andrew Vasquez   [SCSI] qla2xxx: A...
3725

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3726
3727
  	host = scsi_host_alloc(sht, sizeof(scsi_qla_host_t));
  	if (host == NULL) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3728
3729
3730
  		ql_log_pci(ql_log_fatal, ha->pdev, 0x0107,
  		    "Failed to allocate host from the scsi layer, aborting.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
  		goto fail;
  	}
  
  	/* Clear our data area */
  	vha = shost_priv(host);
  	memset(vha, 0, sizeof(scsi_qla_host_t));
  
  	vha->host = host;
  	vha->host_no = host->host_no;
  	vha->hw = ha;
  
  	INIT_LIST_HEAD(&vha->vp_fcports);
  	INIT_LIST_HEAD(&vha->work_list);
  	INIT_LIST_HEAD(&vha->list);
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3745
  	spin_lock_init(&vha->work_lock);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3746
  	sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
3747
3748
3749
3750
  	ql_dbg(ql_dbg_init, vha, 0x0041,
  	    "Allocated the host=%p hw=%p vha=%p dev_name=%s",
  	    vha->host, vha->hw, vha,
  	    dev_name(&(ha->pdev->dev)));
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3751
3752
3753
3754
  	return vha;
  
  fail:
  	return vha;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
3755
  }
01ef66bbb   Adrian Bunk   [SCSI] qla2xxx: q...
3756
  static struct qla_work_evt *
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3757
  qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type)
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3758
3759
  {
  	struct qla_work_evt *e;
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
3760
3761
3762
3763
3764
  	uint8_t bail;
  
  	QLA_VHA_MARK_BUSY(vha, bail);
  	if (bail)
  		return NULL;
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3765

f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3766
  	e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC);
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
3767
3768
  	if (!e) {
  		QLA_VHA_MARK_NOT_BUSY(vha);
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3769
  		return NULL;
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
3770
  	}
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3771
3772
3773
3774
3775
3776
  
  	INIT_LIST_HEAD(&e->list);
  	e->type = type;
  	e->flags = QLA_EVT_FLAG_FREE;
  	return e;
  }
01ef66bbb   Adrian Bunk   [SCSI] qla2xxx: q...
3777
  static int
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3778
  qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3779
  {
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3780
  	unsigned long flags;
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3781

f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3782
  	spin_lock_irqsave(&vha->work_lock, flags);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3783
  	list_add_tail(&e->list, &vha->work_list);
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3784
  	spin_unlock_irqrestore(&vha->work_lock, flags);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3785
  	qla2xxx_wake_dpc(vha);
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3786

0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3787
3788
3789
3790
  	return QLA_SUCCESS;
  }
  
  int
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3791
  qla2x00_post_aen_work(struct scsi_qla_host *vha, enum fc_host_event_code code,
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3792
3793
3794
      u32 data)
  {
  	struct qla_work_evt *e;
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3795
  	e = qla2x00_alloc_work(vha, QLA_EVT_AEN);
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3796
3797
3798
3799
3800
  	if (!e)
  		return QLA_FUNCTION_FAILED;
  
  	e->u.aen.code = code;
  	e->u.aen.data = data;
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3801
  	return qla2x00_post_work(vha, e);
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3802
  }
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
3803
3804
3805
3806
  int
  qla2x00_post_idc_ack_work(struct scsi_qla_host *vha, uint16_t *mb)
  {
  	struct qla_work_evt *e;
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3807
  	e = qla2x00_alloc_work(vha, QLA_EVT_IDC_ACK);
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
3808
3809
3810
3811
  	if (!e)
  		return QLA_FUNCTION_FAILED;
  
  	memcpy(e->u.idc_ack.mb, mb, QLA_IDC_ACK_REGS * sizeof(uint16_t));
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3812
  	return qla2x00_post_work(vha, e);
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
3813
  }
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
  #define qla2x00_post_async_work(name, type)	\
  int qla2x00_post_async_##name##_work(		\
      struct scsi_qla_host *vha,			\
      fc_port_t *fcport, uint16_t *data)		\
  {						\
  	struct qla_work_evt *e;			\
  						\
  	e = qla2x00_alloc_work(vha, type);	\
  	if (!e)					\
  		return QLA_FUNCTION_FAILED;	\
  						\
  	e->u.logio.fcport = fcport;		\
  	if (data) {				\
  		e->u.logio.data[0] = data[0];	\
  		e->u.logio.data[1] = data[1];	\
  	}					\
  	return qla2x00_post_work(vha, e);	\
  }
  
  qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN);
  qla2x00_post_async_work(login_done, QLA_EVT_ASYNC_LOGIN_DONE);
  qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
  qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3837
3838
  qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC);
  qla2x00_post_async_work(adisc_done, QLA_EVT_ASYNC_ADISC_DONE);
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3839

3420d36ca   Andrew Vasquez   [SCSI] qla2xxx: A...
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
  int
  qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
  {
  	struct qla_work_evt *e;
  
  	e = qla2x00_alloc_work(vha, QLA_EVT_UEVENT);
  	if (!e)
  		return QLA_FUNCTION_FAILED;
  
  	e->u.uevent.code = code;
  	return qla2x00_post_work(vha, e);
  }
  
  static void
  qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code)
  {
  	char event_string[40];
  	char *envp[] = { event_string, NULL };
  
  	switch (code) {
  	case QLA_UEVENT_CODE_FW_DUMP:
  		snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld",
  		    vha->host_no);
  		break;
  	default:
  		/* do nothing */
  		break;
  	}
  	kobject_uevent_env(&vha->hw->pdev->dev.kobj, KOBJ_CHANGE, envp);
  }
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
  int
  qlafx00_post_aenfx_work(struct scsi_qla_host *vha,  uint32_t evtcode,
  			uint32_t *data, int cnt)
  {
  	struct qla_work_evt *e;
  
  	e = qla2x00_alloc_work(vha, QLA_EVT_AENFX);
  	if (!e)
  		return QLA_FUNCTION_FAILED;
  
  	e->u.aenfx.evtcode = evtcode;
  	e->u.aenfx.count = cnt;
  	memcpy(e->u.aenfx.mbx, data, sizeof(*data) * cnt);
  	return qla2x00_post_work(vha, e);
  }
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3885
  void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3886
  qla2x00_do_work(struct scsi_qla_host *vha)
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3887
  {
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3888
3889
3890
  	struct qla_work_evt *e, *tmp;
  	unsigned long flags;
  	LIST_HEAD(work);
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3891

f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3892
3893
3894
3895
3896
  	spin_lock_irqsave(&vha->work_lock, flags);
  	list_splice_init(&vha->work_list, &work);
  	spin_unlock_irqrestore(&vha->work_lock, flags);
  
  	list_for_each_entry_safe(e, tmp, &work, list) {
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3897
  		list_del_init(&e->list);
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3898
3899
3900
  
  		switch (e->type) {
  		case QLA_EVT_AEN:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3901
  			fc_host_post_event(vha->host, fc_get_event_number(),
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3902
3903
  			    e->u.aen.code, e->u.aen.data);
  			break;
8a659571e   Andrew Vasquez   [SCSI] qla2xxx: P...
3904
3905
3906
  		case QLA_EVT_IDC_ACK:
  			qla81xx_idc_ack(vha, e->u.idc_ack.mb);
  			break;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
  		case QLA_EVT_ASYNC_LOGIN:
  			qla2x00_async_login(vha, e->u.logio.fcport,
  			    e->u.logio.data);
  			break;
  		case QLA_EVT_ASYNC_LOGIN_DONE:
  			qla2x00_async_login_done(vha, e->u.logio.fcport,
  			    e->u.logio.data);
  			break;
  		case QLA_EVT_ASYNC_LOGOUT:
  			qla2x00_async_logout(vha, e->u.logio.fcport);
  			break;
  		case QLA_EVT_ASYNC_LOGOUT_DONE:
  			qla2x00_async_logout_done(vha, e->u.logio.fcport,
  			    e->u.logio.data);
  			break;
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3922
3923
3924
3925
3926
3927
3928
3929
  		case QLA_EVT_ASYNC_ADISC:
  			qla2x00_async_adisc(vha, e->u.logio.fcport,
  			    e->u.logio.data);
  			break;
  		case QLA_EVT_ASYNC_ADISC_DONE:
  			qla2x00_async_adisc_done(vha, e->u.logio.fcport,
  			    e->u.logio.data);
  			break;
3420d36ca   Andrew Vasquez   [SCSI] qla2xxx: A...
3930
3931
3932
  		case QLA_EVT_UEVENT:
  			qla2x00_uevent_emit(vha, e->u.uevent.code);
  			break;
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
3933
3934
3935
  		case QLA_EVT_AENFX:
  			qlafx00_process_aen(vha, e);
  			break;
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
3936
3937
3938
  		}
  		if (e->flags & QLA_EVT_FLAG_FREE)
  			kfree(e);
feafb7b17   Arun Easi   [SCSI] qla2xxx: F...
3939
3940
3941
  
  		/* For each work completed decrement vha ref count */
  		QLA_VHA_MARK_NOT_BUSY(vha);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3942
  	}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3943
  }
f999f4c19   Andrew Vasquez   [SCSI] qla2xxx: R...
3944

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3945
3946
3947
3948
3949
3950
  /* Relogins all the fcports of a vport
   * Context: dpc thread
   */
  void qla2x00_relogin(struct scsi_qla_host *vha)
  {
  	fc_port_t       *fcport;
c6b2fca82   Andrew Vasquez   [SCSI] qla2xxx: C...
3951
  	int status;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3952
3953
  	uint16_t        next_loopid = 0;
  	struct qla_hw_data *ha = vha->hw;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3954
  	uint16_t data[2];
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3955
3956
3957
3958
3959
3960
  
  	list_for_each_entry(fcport, &vha->vp_fcports, list) {
  	/*
  	 * If the port is not ONLINE then try to login
  	 * to it if we haven't run out of retries.
  	 */
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3961
3962
  		if (atomic_read(&fcport->state) != FCS_ONLINE &&
  		    fcport->login_retry && !(fcport->flags & FCF_ASYNC_SENT)) {
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3963
  			fcport->login_retry--;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3964
  			if (fcport->flags & FCF_FABRIC_DEVICE) {
f08b7251c   Andrew Vasquez   [SCSI] qla2xxx: C...
3965
  				if (fcport->flags & FCF_FCP2_DEVICE)
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
3966
3967
3968
3969
3970
  					ha->isp_ops->fabric_logout(vha,
  							fcport->loop_id,
  							fcport->d_id.b.domain,
  							fcport->d_id.b.area,
  							fcport->d_id.b.al_pa);
03bcfb57c   Joe Carnuccio   [SCSI] qla2xxx: A...
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
  				if (fcport->loop_id == FC_NO_LOOP_ID) {
  					fcport->loop_id = next_loopid =
  					    ha->min_external_loopid;
  					status = qla2x00_find_new_loop_id(
  					    vha, fcport);
  					if (status != QLA_SUCCESS) {
  						/* Ran out of IDs to use */
  						break;
  					}
  				}
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3981
  				if (IS_ALOGIO_CAPABLE(ha)) {
5ff1d5841   Andrew Vasquez   [SCSI] qla2xxx: L...
3982
  					fcport->flags |= FCF_ASYNC_SENT;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3983
3984
3985
3986
3987
3988
3989
3990
  					data[0] = 0;
  					data[1] = QLA_LOGIO_LOGIN_RETRIED;
  					status = qla2x00_post_async_login_work(
  					    vha, fcport, data);
  					if (status == QLA_SUCCESS)
  						continue;
  					/* Attempt a retry. */
  					status = 1;
aaf4d3e2c   Saurav Kashyap   [SCSI] qla2xxx: P...
3991
  				} else {
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
3992
3993
  					status = qla2x00_fabric_login(vha,
  					    fcport, &next_loopid);
aaf4d3e2c   Saurav Kashyap   [SCSI] qla2xxx: P...
3994
3995
3996
3997
3998
3999
4000
4001
  					if (status ==  QLA_SUCCESS) {
  						int status2;
  						uint8_t opts;
  
  						opts = 0;
  						if (fcport->flags &
  						    FCF_FCP2_DEVICE)
  							opts |= BIT_1;
03003960a   Saurav Kashyap   [SCSI] qla2xxx: F...
4002
4003
4004
  						status2 =
  						    qla2x00_get_port_database(
  							vha, fcport, opts);
aaf4d3e2c   Saurav Kashyap   [SCSI] qla2xxx: P...
4005
4006
4007
4008
  						if (status2 != QLA_SUCCESS)
  							status = 1;
  					}
  				}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4009
4010
4011
  			} else
  				status = qla2x00_local_device_login(vha,
  								fcport);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4012
4013
  			if (status == QLA_SUCCESS) {
  				fcport->old_loop_id = fcport->loop_id;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4014
4015
4016
4017
  				ql_dbg(ql_dbg_disc, vha, 0x2003,
  				    "Port login OK: logged in ID 0x%x.
  ",
  				    fcport->loop_id);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4018
4019
4020
4021
4022
4023
  
  				qla2x00_update_fcport(vha, fcport);
  
  			} else if (status == 1) {
  				set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
  				/* retry the login again */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4024
4025
4026
4027
  				ql_dbg(ql_dbg_disc, vha, 0x2007,
  				    "Retrying %d login again loop_id 0x%x.
  ",
  				    fcport->login_retry, fcport->loop_id);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4028
4029
4030
4031
4032
  			} else {
  				fcport->login_retry = 0;
  			}
  
  			if (fcport->login_retry == 0 && status != QLA_SUCCESS)
5f16b331d   Chad Dupuis   [SCSI] qla2xxx: U...
4033
  				qla2x00_clear_loop_id(fcport);
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4034
4035
4036
  		}
  		if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))
  			break;
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
4037
  	}
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
4038
  }
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
  /* Schedule work on any of the dpc-workqueues */
  void
  qla83xx_schedule_work(scsi_qla_host_t *base_vha, int work_code)
  {
  	struct qla_hw_data *ha = base_vha->hw;
  
  	switch (work_code) {
  	case MBA_IDC_AEN: /* 0x8200 */
  		if (ha->dpc_lp_wq)
  			queue_work(ha->dpc_lp_wq, &ha->idc_aen);
  		break;
  
  	case QLA83XX_NIC_CORE_RESET: /* 0x1 */
  		if (!ha->flags.nic_core_reset_hdlr_active) {
  			if (ha->dpc_hp_wq)
  				queue_work(ha->dpc_hp_wq, &ha->nic_core_reset);
  		} else
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb05e,
  			    "NIC Core reset is already active. Skip "
  			    "scheduling it again.
  ");
  		break;
  	case QLA83XX_IDC_STATE_HANDLER: /* 0x2 */
  		if (ha->dpc_hp_wq)
  			queue_work(ha->dpc_hp_wq, &ha->idc_state_handler);
  		break;
  	case QLA83XX_NIC_CORE_UNRECOVERABLE: /* 0x3 */
  		if (ha->dpc_hp_wq)
  			queue_work(ha->dpc_hp_wq, &ha->nic_core_unrecoverable);
  		break;
  	default:
  		ql_log(ql_log_warn, base_vha, 0xb05f,
  		    "Unknow work-code=0x%x.
  ", work_code);
  	}
  
  	return;
  }
  
  /* Work: Perform NIC Core Unrecoverable state handling */
  void
  qla83xx_nic_core_unrecoverable_work(struct work_struct *work)
  {
  	struct qla_hw_data *ha =
2ad1b67c5   Arun Easi   [SCSI] qla2xxx: U...
4083
  		container_of(work, struct qla_hw_data, nic_core_unrecoverable);
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
  	uint32_t dev_state = 0;
  
  	qla83xx_idc_lock(base_vha, 0);
  	qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
  	qla83xx_reset_ownership(base_vha);
  	if (ha->flags.nic_core_reset_owner) {
  		ha->flags.nic_core_reset_owner = 0;
  		qla83xx_wr_reg(base_vha, QLA83XX_IDC_DEV_STATE,
  		    QLA8XXX_DEV_FAILED);
  		ql_log(ql_log_info, base_vha, 0xb060, "HW State: FAILED.
  ");
  		qla83xx_schedule_work(base_vha, QLA83XX_IDC_STATE_HANDLER);
  	}
  	qla83xx_idc_unlock(base_vha, 0);
  }
  
  /* Work: Execute IDC state handler */
  void
  qla83xx_idc_state_handler_work(struct work_struct *work)
  {
  	struct qla_hw_data *ha =
2ad1b67c5   Arun Easi   [SCSI] qla2xxx: U...
4106
  		container_of(work, struct qla_hw_data, idc_state_handler);
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
  	uint32_t dev_state = 0;
  
  	qla83xx_idc_lock(base_vha, 0);
  	qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
  	if (dev_state == QLA8XXX_DEV_FAILED ||
  			dev_state == QLA8XXX_DEV_NEED_QUIESCENT)
  		qla83xx_idc_state_handler(base_vha);
  	qla83xx_idc_unlock(base_vha, 0);
  }
fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
4117
  static int
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
  qla83xx_check_nic_core_fw_alive(scsi_qla_host_t *base_vha)
  {
  	int rval = QLA_SUCCESS;
  	unsigned long heart_beat_wait = jiffies + (1 * HZ);
  	uint32_t heart_beat_counter1, heart_beat_counter2;
  
  	do {
  		if (time_after(jiffies, heart_beat_wait)) {
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb07c,
  			    "Nic Core f/w is not alive.
  ");
  			rval = QLA_FUNCTION_FAILED;
  			break;
  		}
  
  		qla83xx_idc_lock(base_vha, 0);
  		qla83xx_rd_reg(base_vha, QLA83XX_FW_HEARTBEAT,
  		    &heart_beat_counter1);
  		qla83xx_idc_unlock(base_vha, 0);
  		msleep(100);
  		qla83xx_idc_lock(base_vha, 0);
  		qla83xx_rd_reg(base_vha, QLA83XX_FW_HEARTBEAT,
  		    &heart_beat_counter2);
  		qla83xx_idc_unlock(base_vha, 0);
  	} while (heart_beat_counter1 == heart_beat_counter2);
  
  	return rval;
  }
  
  /* Work: Perform NIC Core Reset handling */
  void
  qla83xx_nic_core_reset_work(struct work_struct *work)
  {
  	struct qla_hw_data *ha =
  		container_of(work, struct qla_hw_data, nic_core_reset);
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
  	uint32_t dev_state = 0;
81178772b   Saurav Kashyap   [SCSI] qla2xxx: I...
4155
4156
4157
4158
4159
4160
4161
  	if (IS_QLA2031(ha)) {
  		if (qla2xxx_mctp_dump(base_vha) != QLA_SUCCESS)
  			ql_log(ql_log_warn, base_vha, 0xb081,
  			    "Failed to dump mctp
  ");
  		return;
  	}
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
  	if (!ha->flags.nic_core_reset_hdlr_active) {
  		if (qla83xx_check_nic_core_fw_alive(base_vha) == QLA_SUCCESS) {
  			qla83xx_idc_lock(base_vha, 0);
  			qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE,
  			    &dev_state);
  			qla83xx_idc_unlock(base_vha, 0);
  			if (dev_state != QLA8XXX_DEV_NEED_RESET) {
  				ql_dbg(ql_dbg_p3p, base_vha, 0xb07a,
  				    "Nic Core f/w is alive.
  ");
  				return;
  			}
  		}
  
  		ha->flags.nic_core_reset_hdlr_active = 1;
  		if (qla83xx_nic_core_reset(base_vha)) {
  			/* NIC Core reset failed. */
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb061,
  			    "NIC Core reset failed.
  ");
  		}
  		ha->flags.nic_core_reset_hdlr_active = 0;
  	}
  }
  
  /* Work: Handle 8200 IDC aens */
  void
  qla83xx_service_idc_aen(struct work_struct *work)
  {
  	struct qla_hw_data *ha =
  		container_of(work, struct qla_hw_data, idc_aen);
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
  	uint32_t dev_state, idc_control;
  
  	qla83xx_idc_lock(base_vha, 0);
  	qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
  	qla83xx_rd_reg(base_vha, QLA83XX_IDC_CONTROL, &idc_control);
  	qla83xx_idc_unlock(base_vha, 0);
  	if (dev_state == QLA8XXX_DEV_NEED_RESET) {
  		if (idc_control & QLA83XX_IDC_GRACEFUL_RESET) {
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb062,
  			    "Application requested NIC Core Reset.
  ");
  			qla83xx_schedule_work(base_vha, QLA83XX_NIC_CORE_RESET);
  		} else if (qla83xx_check_nic_core_fw_alive(base_vha) ==
  		    QLA_SUCCESS) {
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb07b,
  			    "Other protocol driver requested NIC Core Reset.
  ");
  			qla83xx_schedule_work(base_vha, QLA83XX_NIC_CORE_RESET);
  		}
  	} else if (dev_state == QLA8XXX_DEV_FAILED ||
  			dev_state == QLA8XXX_DEV_NEED_QUIESCENT) {
  		qla83xx_schedule_work(base_vha, QLA83XX_IDC_STATE_HANDLER);
  	}
  }
  
  static void
  qla83xx_wait_logic(void)
  {
  	int i;
  
  	/* Yield CPU */
  	if (!in_interrupt()) {
  		/*
  		 * Wait about 200ms before retrying again.
  		 * This controls the number of retries for single
  		 * lock operation.
  		 */
  		msleep(100);
  		schedule();
  	} else {
  		for (i = 0; i < 20; i++)
  			cpu_relax(); /* This a nop instr on i386 */
  	}
  }
fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
4238
  static int
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4239
4240
4241
4242
4243
4244
4245
  qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha)
  {
  	int rval;
  	uint32_t data;
  	uint32_t idc_lck_rcvry_stage_mask = 0x3;
  	uint32_t idc_lck_rcvry_owner_mask = 0x3c;
  	struct qla_hw_data *ha = base_vha->hw;
6c3155532   Saurav Kashyap   [SCSI] qla2xxx: D...
4246
4247
4248
  	ql_dbg(ql_dbg_p3p, base_vha, 0xb086,
  	    "Trying force recovery of the IDC lock.
  ");
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
  
  	rval = qla83xx_rd_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY, &data);
  	if (rval)
  		return rval;
  
  	if ((data & idc_lck_rcvry_stage_mask) > 0) {
  		return QLA_SUCCESS;
  	} else {
  		data = (IDC_LOCK_RECOVERY_STAGE1) | (ha->portnum << 2);
  		rval = qla83xx_wr_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY,
  		    data);
  		if (rval)
  			return rval;
  
  		msleep(200);
  
  		rval = qla83xx_rd_reg(base_vha, QLA83XX_IDC_LOCK_RECOVERY,
  		    &data);
  		if (rval)
  			return rval;
  
  		if (((data & idc_lck_rcvry_owner_mask) >> 2) == ha->portnum) {
  			data &= (IDC_LOCK_RECOVERY_STAGE2 |
  					~(idc_lck_rcvry_stage_mask));
  			rval = qla83xx_wr_reg(base_vha,
  			    QLA83XX_IDC_LOCK_RECOVERY, data);
  			if (rval)
  				return rval;
  
  			/* Forcefully perform IDC UnLock */
  			rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_UNLOCK,
  			    &data);
  			if (rval)
  				return rval;
  			/* Clear lock-id by setting 0xff */
  			rval = qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID,
  			    0xff);
  			if (rval)
  				return rval;
  			/* Clear lock-recovery by setting 0x0 */
  			rval = qla83xx_wr_reg(base_vha,
  			    QLA83XX_IDC_LOCK_RECOVERY, 0x0);
  			if (rval)
  				return rval;
  		} else
  			return QLA_SUCCESS;
  	}
  
  	return rval;
  }
fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
4299
  static int
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
  qla83xx_idc_lock_recovery(scsi_qla_host_t *base_vha)
  {
  	int rval = QLA_SUCCESS;
  	uint32_t o_drv_lockid, n_drv_lockid;
  	unsigned long lock_recovery_timeout;
  
  	lock_recovery_timeout = jiffies + QLA83XX_MAX_LOCK_RECOVERY_WAIT;
  retry_lockid:
  	rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &o_drv_lockid);
  	if (rval)
  		goto exit;
  
  	/* MAX wait time before forcing IDC Lock recovery = 2 secs */
  	if (time_after_eq(jiffies, lock_recovery_timeout)) {
  		if (qla83xx_force_lock_recovery(base_vha) == QLA_SUCCESS)
  			return QLA_SUCCESS;
  		else
  			return QLA_FUNCTION_FAILED;
  	}
  
  	rval = qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &n_drv_lockid);
  	if (rval)
  		goto exit;
  
  	if (o_drv_lockid == n_drv_lockid) {
  		qla83xx_wait_logic();
  		goto retry_lockid;
  	} else
  		return QLA_SUCCESS;
  
  exit:
  	return rval;
  }
  
  void
  qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id)
  {
  	uint16_t options = (requester_id << 15) | BIT_6;
  	uint32_t data;
6c3155532   Saurav Kashyap   [SCSI] qla2xxx: D...
4339
  	uint32_t lock_owner;
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
  	struct qla_hw_data *ha = base_vha->hw;
  
  	/* IDC-lock implementation using driver-lock/lock-id remote registers */
  retry_lock:
  	if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCK, &data)
  	    == QLA_SUCCESS) {
  		if (data) {
  			/* Setting lock-id to our function-number */
  			qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID,
  			    ha->portnum);
  		} else {
6c3155532   Saurav Kashyap   [SCSI] qla2xxx: D...
4351
4352
  			qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID,
  			    &lock_owner);
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4353
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb063,
6c3155532   Saurav Kashyap   [SCSI] qla2xxx: D...
4354
4355
4356
  			    "Failed to acquire IDC lock, acquired by %d, "
  			    "retrying...
  ", lock_owner);
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
  
  			/* Retry/Perform IDC-Lock recovery */
  			if (qla83xx_idc_lock_recovery(base_vha)
  			    == QLA_SUCCESS) {
  				qla83xx_wait_logic();
  				goto retry_lock;
  			} else
  				ql_log(ql_log_warn, base_vha, 0xb075,
  				    "IDC Lock recovery FAILED.
  ");
  		}
  
  	}
  
  	return;
  
  	/* XXX: IDC-lock implementation using access-control mbx */
  retry_lock2:
  	if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
  		ql_dbg(ql_dbg_p3p, base_vha, 0xb072,
  		    "Failed to acquire IDC lock. retrying...
  ");
  		/* Retry/Perform IDC-Lock recovery */
  		if (qla83xx_idc_lock_recovery(base_vha) == QLA_SUCCESS) {
  			qla83xx_wait_logic();
  			goto retry_lock2;
  		} else
  			ql_log(ql_log_warn, base_vha, 0xb076,
  			    "IDC Lock recovery FAILED.
  ");
  	}
  
  	return;
  }
  
  void
  qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id)
  {
  	uint16_t options = (requester_id << 15) | BIT_7, retry;
  	uint32_t data;
  	struct qla_hw_data *ha = base_vha->hw;
  
  	/* IDC-unlock implementation using driver-unlock/lock-id
  	 * remote registers
  	 */
  	retry = 0;
  retry_unlock:
  	if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCKID, &data)
  	    == QLA_SUCCESS) {
  		if (data == ha->portnum) {
  			qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_UNLOCK, &data);
  			/* Clearing lock-id by setting 0xff */
  			qla83xx_wr_reg(base_vha, QLA83XX_DRIVER_LOCKID, 0xff);
  		} else if (retry < 10) {
  			/* SV: XXX: IDC unlock retrying needed here? */
  
  			/* Retry for IDC-unlock */
  			qla83xx_wait_logic();
  			retry++;
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb064,
  			    "Failed to release IDC lock, retyring=%d
  ", retry);
  			goto retry_unlock;
  		}
  	} else if (retry < 10) {
  		/* Retry for IDC-unlock */
  		qla83xx_wait_logic();
  		retry++;
  		ql_dbg(ql_dbg_p3p, base_vha, 0xb065,
  		    "Failed to read drv-lockid, retyring=%d
  ", retry);
  		goto retry_unlock;
  	}
  
  	return;
  
  	/* XXX: IDC-unlock implementation using access-control mbx */
  	retry = 0;
  retry_unlock2:
  	if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) {
  		if (retry < 10) {
  			/* Retry for IDC-unlock */
  			qla83xx_wait_logic();
  			retry++;
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb066,
  			    "Failed to release IDC lock, retyring=%d
  ", retry);
  			goto retry_unlock2;
  		}
  	}
  
  	return;
  }
  
  int
  __qla83xx_set_drv_presence(scsi_qla_host_t *vha)
  {
  	int rval = QLA_SUCCESS;
  	struct qla_hw_data *ha = vha->hw;
  	uint32_t drv_presence;
  
  	rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
  	if (rval == QLA_SUCCESS) {
  		drv_presence |= (1 << ha->portnum);
  		rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
  		    drv_presence);
  	}
  
  	return rval;
  }
  
  int
  qla83xx_set_drv_presence(scsi_qla_host_t *vha)
  {
  	int rval = QLA_SUCCESS;
  
  	qla83xx_idc_lock(vha, 0);
  	rval = __qla83xx_set_drv_presence(vha);
  	qla83xx_idc_unlock(vha, 0);
  
  	return rval;
  }
  
  int
  __qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
  {
  	int rval = QLA_SUCCESS;
  	struct qla_hw_data *ha = vha->hw;
  	uint32_t drv_presence;
  
  	rval = qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
  	if (rval == QLA_SUCCESS) {
  		drv_presence &= ~(1 << ha->portnum);
  		rval = qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
  		    drv_presence);
  	}
  
  	return rval;
  }
  
  int
  qla83xx_clear_drv_presence(scsi_qla_host_t *vha)
  {
  	int rval = QLA_SUCCESS;
  
  	qla83xx_idc_lock(vha, 0);
  	rval = __qla83xx_clear_drv_presence(vha);
  	qla83xx_idc_unlock(vha, 0);
  
  	return rval;
  }
fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
4508
  static void
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
  qla83xx_need_reset_handler(scsi_qla_host_t *vha)
  {
  	struct qla_hw_data *ha = vha->hw;
  	uint32_t drv_ack, drv_presence;
  	unsigned long ack_timeout;
  
  	/* Wait for IDC ACK from all functions (DRV-ACK == DRV-PRESENCE) */
  	ack_timeout = jiffies + (ha->fcoe_reset_timeout * HZ);
  	while (1) {
  		qla83xx_rd_reg(vha, QLA83XX_IDC_DRIVER_ACK, &drv_ack);
  		qla83xx_rd_reg(vha, QLA83XX_IDC_DRV_PRESENCE, &drv_presence);
807fb6d8a   Saurav Kashyap   [SCSI] qla2xxx: I...
4520
  		if ((drv_ack & drv_presence) == drv_presence)
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
  			break;
  
  		if (time_after_eq(jiffies, ack_timeout)) {
  			ql_log(ql_log_warn, vha, 0xb067,
  			    "RESET ACK TIMEOUT! drv_presence=0x%x "
  			    "drv_ack=0x%x
  ", drv_presence, drv_ack);
  			/*
  			 * The function(s) which did not ack in time are forced
  			 * to withdraw any further participation in the IDC
  			 * reset.
  			 */
  			if (drv_ack != drv_presence)
  				qla83xx_wr_reg(vha, QLA83XX_IDC_DRV_PRESENCE,
  				    drv_ack);
  			break;
  		}
  
  		qla83xx_idc_unlock(vha, 0);
  		msleep(1000);
  		qla83xx_idc_lock(vha, 0);
  	}
  
  	qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_COLD);
  	ql_log(ql_log_info, vha, 0xb068, "HW State: COLD/RE-INIT.
  ");
  }
fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
4548
  static int
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
  qla83xx_device_bootstrap(scsi_qla_host_t *vha)
  {
  	int rval = QLA_SUCCESS;
  	uint32_t idc_control;
  
  	qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_INITIALIZING);
  	ql_log(ql_log_info, vha, 0xb069, "HW State: INITIALIZING.
  ");
  
  	/* Clearing IDC-Control Graceful-Reset Bit before resetting f/w */
  	__qla83xx_get_idc_control(vha, &idc_control);
  	idc_control &= ~QLA83XX_IDC_GRACEFUL_RESET;
  	__qla83xx_set_idc_control(vha, 0);
  
  	qla83xx_idc_unlock(vha, 0);
  	rval = qla83xx_restart_nic_firmware(vha);
  	qla83xx_idc_lock(vha, 0);
  
  	if (rval != QLA_SUCCESS) {
  		ql_log(ql_log_fatal, vha, 0xb06a,
  		    "Failed to restart NIC f/w.
  ");
  		qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_FAILED);
  		ql_log(ql_log_info, vha, 0xb06b, "HW State: FAILED.
  ");
  	} else {
  		ql_dbg(ql_dbg_p3p, vha, 0xb06c,
  		    "Success in restarting nic f/w.
  ");
  		qla83xx_wr_reg(vha, QLA83XX_IDC_DEV_STATE, QLA8XXX_DEV_READY);
  		ql_log(ql_log_info, vha, 0xb06d, "HW State: READY.
  ");
  	}
  
  	return rval;
  }
  
  /* Assumes idc_lock always held on entry */
  int
  qla83xx_idc_state_handler(scsi_qla_host_t *base_vha)
  {
  	struct qla_hw_data *ha = base_vha->hw;
  	int rval = QLA_SUCCESS;
  	unsigned long dev_init_timeout;
  	uint32_t dev_state;
  
  	/* Wait for MAX-INIT-TIMEOUT for the device to go ready */
  	dev_init_timeout = jiffies + (ha->fcoe_dev_init_timeout * HZ);
  
  	while (1) {
  
  		if (time_after_eq(jiffies, dev_init_timeout)) {
  			ql_log(ql_log_warn, base_vha, 0xb06e,
  			    "Initialization TIMEOUT!
  ");
  			/* Init timeout. Disable further NIC Core
  			 * communication.
  			 */
  			qla83xx_wr_reg(base_vha, QLA83XX_IDC_DEV_STATE,
  				QLA8XXX_DEV_FAILED);
  			ql_log(ql_log_info, base_vha, 0xb06f,
  			    "HW State: FAILED.
  ");
  		}
  
  		qla83xx_rd_reg(base_vha, QLA83XX_IDC_DEV_STATE, &dev_state);
  		switch (dev_state) {
  		case QLA8XXX_DEV_READY:
  			if (ha->flags.nic_core_reset_owner)
  				qla83xx_idc_audit(base_vha,
  				    IDC_AUDIT_COMPLETION);
  			ha->flags.nic_core_reset_owner = 0;
  			ql_dbg(ql_dbg_p3p, base_vha, 0xb070,
  			    "Reset_owner reset by 0x%x.
  ",
  			    ha->portnum);
  			goto exit;
  		case QLA8XXX_DEV_COLD:
  			if (ha->flags.nic_core_reset_owner)
  				rval = qla83xx_device_bootstrap(base_vha);
  			else {
  			/* Wait for AEN to change device-state */
  				qla83xx_idc_unlock(base_vha, 0);
  				msleep(1000);
  				qla83xx_idc_lock(base_vha, 0);
  			}
  			break;
  		case QLA8XXX_DEV_INITIALIZING:
  			/* Wait for AEN to change device-state */
  			qla83xx_idc_unlock(base_vha, 0);
  			msleep(1000);
  			qla83xx_idc_lock(base_vha, 0);
  			break;
  		case QLA8XXX_DEV_NEED_RESET:
  			if (!ql2xdontresethba && ha->flags.nic_core_reset_owner)
  				qla83xx_need_reset_handler(base_vha);
  			else {
  				/* Wait for AEN to change device-state */
  				qla83xx_idc_unlock(base_vha, 0);
  				msleep(1000);
  				qla83xx_idc_lock(base_vha, 0);
  			}
  			/* reset timeout value after need reset handler */
  			dev_init_timeout = jiffies +
  			    (ha->fcoe_dev_init_timeout * HZ);
  			break;
  		case QLA8XXX_DEV_NEED_QUIESCENT:
  			/* XXX: DEBUG for now */
  			qla83xx_idc_unlock(base_vha, 0);
  			msleep(1000);
  			qla83xx_idc_lock(base_vha, 0);
  			break;
  		case QLA8XXX_DEV_QUIESCENT:
  			/* XXX: DEBUG for now */
  			if (ha->flags.quiesce_owner)
  				goto exit;
  
  			qla83xx_idc_unlock(base_vha, 0);
  			msleep(1000);
  			qla83xx_idc_lock(base_vha, 0);
  			dev_init_timeout = jiffies +
  			    (ha->fcoe_dev_init_timeout * HZ);
  			break;
  		case QLA8XXX_DEV_FAILED:
  			if (ha->flags.nic_core_reset_owner)
  				qla83xx_idc_audit(base_vha,
  				    IDC_AUDIT_COMPLETION);
  			ha->flags.nic_core_reset_owner = 0;
  			__qla83xx_clear_drv_presence(base_vha);
  			qla83xx_idc_unlock(base_vha, 0);
  			qla8xxx_dev_failed_handler(base_vha);
  			rval = QLA_FUNCTION_FAILED;
  			qla83xx_idc_lock(base_vha, 0);
  			goto exit;
  		case QLA8XXX_BAD_VALUE:
  			qla83xx_idc_unlock(base_vha, 0);
  			msleep(1000);
  			qla83xx_idc_lock(base_vha, 0);
  			break;
  		default:
  			ql_log(ql_log_warn, base_vha, 0xb071,
  			    "Unknow Device State: %x.
  ", dev_state);
  			qla83xx_idc_unlock(base_vha, 0);
  			qla8xxx_dev_failed_handler(base_vha);
  			rval = QLA_FUNCTION_FAILED;
  			qla83xx_idc_lock(base_vha, 0);
  			goto exit;
  		}
  	}
  
  exit:
  	return rval;
  }
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
  void
  qla2x00_disable_board_on_pci_error(struct work_struct *work)
  {
  	struct qla_hw_data *ha = container_of(work, struct qla_hw_data,
  	    board_disable);
  	struct pci_dev *pdev = ha->pdev;
  	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
  
  	ql_log(ql_log_warn, base_vha, 0x015b,
  	    "Disabling adapter.
  ");
  
  	set_bit(UNLOADING, &base_vha->dpc_flags);
  
  	qla2x00_delete_all_vps(ha, base_vha);
  
  	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
  
  	qla2x00_dfs_remove(base_vha);
  
  	qla84xx_put_chip(base_vha);
  
  	if (base_vha->timer_active)
  		qla2x00_stop_timer(base_vha);
  
  	base_vha->flags.online = 0;
  
  	qla2x00_destroy_deferred_work(ha);
  
  	/*
  	 * Do not try to stop beacon blink as it will issue a mailbox
  	 * command.
  	 */
  	qla2x00_free_sysfs_attr(base_vha, false);
  
  	fc_remove_host(base_vha->host);
  
  	scsi_remove_host(base_vha->host);
  
  	base_vha->flags.init_done = 0;
  	qla25xx_delete_queues(base_vha);
  	qla2x00_free_irqs(base_vha);
  	qla2x00_free_fcports(base_vha);
  	qla2x00_mem_free(ha);
  	qla82xx_md_free(base_vha);
  	qla2x00_free_queues(ha);
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
4749
4750
4751
  	qla2x00_unmap_iobases(ha);
  
  	pci_release_selected_regions(ha->pdev, ha->bars);
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
4752
4753
  	pci_disable_pcie_error_reporting(pdev);
  	pci_disable_device(pdev);
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
4754

beb9e315e   Joe Lawrence   qla2xxx: Prevent ...
4755
4756
4757
  	/*
  	 * Let qla2x00_remove_one cleanup qla_hw_data on device removal.
  	 */
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
4758
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
  /**************************************************************************
  * qla2x00_do_dpc
  *   This kernel thread is a task that is schedule by the interrupt handler
  *   to perform the background processing for interrupts.
  *
  * Notes:
  * This task always run in the context of a kernel thread.  It
  * is kick-off by the driver's detect code and starts up
  * up one per adapter. It immediately goes to sleep and waits for
  * some fibre event.  When either the interrupt handler or
  * the timer routine detects a event it will one of the task
  * bits then wake us up.
  **************************************************************************/
  static int
  qla2x00_do_dpc(void *data)
  {
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
4775
  	int		rval;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4776
4777
  	scsi_qla_host_t *base_vha;
  	struct qla_hw_data *ha;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4778

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4779
4780
  	ha = (struct qla_hw_data *)data;
  	base_vha = pci_get_drvdata(ha->pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4781

8698a745d   Dongsheng Yang   sched, treewide: ...
4782
  	set_user_nice(current, MIN_NICE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4783

563585ec4   James Bottomley   [SCSI] qla2xxx: F...
4784
  	set_current_state(TASK_INTERRUPTIBLE);
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
4785
  	while (!kthread_should_stop()) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4786
4787
4788
  		ql_dbg(ql_dbg_dpc, base_vha, 0x4000,
  		    "DPC handler sleeping.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4789

39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
4790
  		schedule();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4791

c142caf0a   Andrew Vasquez   [SCSI] qla2xxx: L...
4792
4793
  		if (!base_vha->flags.init_done || ha->flags.mbox_busy)
  			goto end_loop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4794

858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
4795
  		if (ha->flags.eeh_busy) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4796
4797
4798
  			ql_dbg(ql_dbg_dpc, base_vha, 0x4003,
  			    "eeh_busy=%d.
  ", ha->flags.eeh_busy);
c142caf0a   Andrew Vasquez   [SCSI] qla2xxx: L...
4799
  			goto end_loop;
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
4800
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4801
  		ha->dpc_active = 1;
5f28d2d7c   Saurav Kashyap   [SCSI] qla2xxx: A...
4802
4803
4804
4805
  		ql_dbg(ql_dbg_dpc + ql_dbg_verbose, base_vha, 0x4001,
  		    "DPC handler waking up, dpc_flags=0x%lx.
  ",
  		    base_vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4806

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4807
  		qla2x00_do_work(base_vha);
0971de7f5   Andrew Vasquez   [SCSI] qla2xxx: A...
4808

7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
  		if (IS_P3P_TYPE(ha)) {
  			if (IS_QLA8044(ha)) {
  				if (test_and_clear_bit(ISP_UNRECOVERABLE,
  					&base_vha->dpc_flags)) {
  					qla8044_idc_lock(ha);
  					qla8044_wr_direct(base_vha,
  						QLA8044_CRB_DEV_STATE_INDEX,
  						QLA8XXX_DEV_FAILED);
  					qla8044_idc_unlock(ha);
  					ql_log(ql_log_info, base_vha, 0x4004,
  						"HW State: FAILED.
  ");
  					qla8044_device_state_handler(base_vha);
  					continue;
  				}
  
  			} else {
  				if (test_and_clear_bit(ISP_UNRECOVERABLE,
  					&base_vha->dpc_flags)) {
  					qla82xx_idc_lock(ha);
  					qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
  						QLA8XXX_DEV_FAILED);
  					qla82xx_idc_unlock(ha);
  					ql_log(ql_log_info, base_vha, 0x0151,
  						"HW State: FAILED.
  ");
  					qla82xx_device_state_handler(base_vha);
  					continue;
  				}
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
4838
4839
4840
4841
  			}
  
  			if (test_and_clear_bit(FCOE_CTX_RESET_NEEDED,
  				&base_vha->dpc_flags)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4842
4843
4844
  				ql_dbg(ql_dbg_dpc, base_vha, 0x4005,
  				    "FCoE context reset scheduled.
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
  				if (!(test_and_set_bit(ABORT_ISP_ACTIVE,
  					&base_vha->dpc_flags))) {
  					if (qla82xx_fcoe_ctx_reset(base_vha)) {
  						/* FCoE-ctx reset failed.
  						 * Escalate to chip-reset
  						 */
  						set_bit(ISP_ABORT_NEEDED,
  							&base_vha->dpc_flags);
  					}
  					clear_bit(ABORT_ISP_ACTIVE,
  						&base_vha->dpc_flags);
  				}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4857
4858
4859
  				ql_dbg(ql_dbg_dpc, base_vha, 0x4006,
  				    "FCoE context reset end.
  ");
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
4860
  			}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
4861
4862
4863
4864
4865
4866
4867
4868
4869
  		} else if (IS_QLAFX00(ha)) {
  			if (test_and_clear_bit(ISP_UNRECOVERABLE,
  				&base_vha->dpc_flags)) {
  				ql_dbg(ql_dbg_dpc, base_vha, 0x4020,
  				    "Firmware Reset Recovery
  ");
  				if (qlafx00_reset_initialize(base_vha)) {
  					/* Failed. Abort isp later. */
  					if (!test_bit(UNLOADING,
f92f82d67   Dan Carpenter   qla2xxx: fix inco...
4870
  					    &base_vha->dpc_flags)) {
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
4871
4872
4873
4874
4875
4876
  						set_bit(ISP_UNRECOVERABLE,
  						    &base_vha->dpc_flags);
  						ql_dbg(ql_dbg_dpc, base_vha,
  						    0x4021,
  						    "Reset Recovery Failed
  ");
f92f82d67   Dan Carpenter   qla2xxx: fix inco...
4877
  					}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
  				}
  			}
  
  			if (test_and_clear_bit(FX00_TARGET_SCAN,
  				&base_vha->dpc_flags)) {
  				ql_dbg(ql_dbg_dpc, base_vha, 0x4022,
  				    "ISPFx00 Target Scan scheduled
  ");
  				if (qlafx00_rescan_isp(base_vha)) {
  					if (!test_bit(UNLOADING,
  					    &base_vha->dpc_flags))
  						set_bit(ISP_UNRECOVERABLE,
  						    &base_vha->dpc_flags);
  					ql_dbg(ql_dbg_dpc, base_vha, 0x401e,
  					    "ISPFx00 Target Scan Failed
  ");
  				}
  				ql_dbg(ql_dbg_dpc, base_vha, 0x401f,
  				    "ISPFx00 Target Scan End
  ");
  			}
e8f5e95d5   Armen Baloyan   [SCSI] qla2xxx: F...
4899
4900
4901
4902
4903
4904
4905
4906
4907
  			if (test_and_clear_bit(FX00_HOST_INFO_RESEND,
  				&base_vha->dpc_flags)) {
  				ql_dbg(ql_dbg_dpc, base_vha, 0x4023,
  				    "ISPFx00 Host Info resend scheduled
  ");
  				qlafx00_fx_disc(base_vha,
  				    &base_vha->hw->mr.fcport,
  				    FXDISC_REG_HOST_INFO);
  			}
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
4908
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4909
4910
  		if (test_and_clear_bit(ISP_ABORT_NEEDED,
  						&base_vha->dpc_flags)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4911

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4912
4913
4914
  			ql_dbg(ql_dbg_dpc, base_vha, 0x4007,
  			    "ISP abort scheduled.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4915
  			if (!(test_and_set_bit(ABORT_ISP_ACTIVE,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4916
  			    &base_vha->dpc_flags))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4917

a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
4918
  				if (ha->isp_ops->abort_isp(base_vha)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4919
4920
  					/* failed. retry later */
  					set_bit(ISP_ABORT_NEEDED,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4921
  					    &base_vha->dpc_flags);
99363ef81   Seokmann Ju   [SCSI] qla2xxx: C...
4922
  				}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4923
4924
  				clear_bit(ABORT_ISP_ACTIVE,
  						&base_vha->dpc_flags);
99363ef81   Seokmann Ju   [SCSI] qla2xxx: C...
4925
  			}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4926
4927
4928
  			ql_dbg(ql_dbg_dpc, base_vha, 0x4008,
  			    "ISP abort end.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4929
  		}
a394aac88   David Jeffery   [SCSI] qla2xxx: T...
4930
4931
  		if (test_and_clear_bit(FCPORT_UPDATE_NEEDED,
  		    &base_vha->dpc_flags)) {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4932
  			qla2x00_update_fcports(base_vha);
c9c5ced90   Andrew Vasquez   [SCSI] qla2xxx: A...
4933
  		}
d97994dc1   Andrew Vasquez   [SCSI] qla2xxx: C...
4934

2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
  		if (test_bit(SCR_PENDING, &base_vha->dpc_flags)) {
  			int ret;
  			ret = qla2x00_send_change_request(base_vha, 0x3, 0);
  			if (ret != QLA_SUCCESS)
  				ql_log(ql_log_warn, base_vha, 0x121,
  				    "Failed to enable receiving of RSCN "
  				    "requests: 0x%x.
  ", ret);
  			clear_bit(SCR_PENDING, &base_vha->dpc_flags);
  		}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
4945
4946
  		if (IS_QLAFX00(ha))
  			goto loop_resync_check;
579d12b58   Saurav Kashyap   [SCSI] qla2xxx: A...
4947
  		if (test_bit(ISP_QUIESCE_NEEDED, &base_vha->dpc_flags)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4948
4949
4950
  			ql_dbg(ql_dbg_dpc, base_vha, 0x4009,
  			    "Quiescence mode scheduled.
  ");
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
4951
4952
4953
4954
4955
  			if (IS_P3P_TYPE(ha)) {
  				if (IS_QLA82XX(ha))
  					qla82xx_device_state_handler(base_vha);
  				if (IS_QLA8044(ha))
  					qla8044_device_state_handler(base_vha);
8fcd6b8b0   Chad Dupuis   [SCSI] qla2xxx: C...
4956
4957
4958
4959
  				clear_bit(ISP_QUIESCE_NEEDED,
  				    &base_vha->dpc_flags);
  				if (!ha->flags.quiesce_owner) {
  					qla2x00_perform_loop_resync(base_vha);
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
  					if (IS_QLA82XX(ha)) {
  						qla82xx_idc_lock(ha);
  						qla82xx_clear_qsnt_ready(
  						    base_vha);
  						qla82xx_idc_unlock(ha);
  					} else if (IS_QLA8044(ha)) {
  						qla8044_idc_lock(ha);
  						qla8044_clear_qsnt_ready(
  						    base_vha);
  						qla8044_idc_unlock(ha);
  					}
8fcd6b8b0   Chad Dupuis   [SCSI] qla2xxx: C...
4971
4972
4973
4974
4975
  				}
  			} else {
  				clear_bit(ISP_QUIESCE_NEEDED,
  				    &base_vha->dpc_flags);
  				qla2x00_quiesce_io(base_vha);
579d12b58   Saurav Kashyap   [SCSI] qla2xxx: A...
4976
  			}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4977
4978
4979
  			ql_dbg(ql_dbg_dpc, base_vha, 0x400a,
  			    "Quiescence mode end.
  ");
579d12b58   Saurav Kashyap   [SCSI] qla2xxx: A...
4980
  		}
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4981
  		if (test_and_clear_bit(RESET_MARKER_NEEDED,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
4982
  				&base_vha->dpc_flags) &&
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4983
  		    (!(test_and_set_bit(RESET_ACTIVE, &base_vha->dpc_flags)))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4984

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4985
4986
4987
  			ql_dbg(ql_dbg_dpc, base_vha, 0x400b,
  			    "Reset marker scheduled.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4988
4989
  			qla2x00_rst_aen(base_vha);
  			clear_bit(RESET_ACTIVE, &base_vha->dpc_flags);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
4990
4991
4992
  			ql_dbg(ql_dbg_dpc, base_vha, 0x400c,
  			    "Reset marker end.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4993
4994
4995
  		}
  
  		/* Retry each device up to login retry count */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
4996
4997
4998
4999
  		if ((test_and_clear_bit(RELOGIN_NEEDED,
  						&base_vha->dpc_flags)) &&
  		    !test_bit(LOOP_RESYNC_NEEDED, &base_vha->dpc_flags) &&
  		    atomic_read(&base_vha->loop_state) != LOOP_DOWN) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5000

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5001
5002
5003
  			ql_dbg(ql_dbg_dpc, base_vha, 0x400d,
  			    "Relogin scheduled.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5004
  			qla2x00_relogin(base_vha);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5005
5006
5007
  			ql_dbg(ql_dbg_dpc, base_vha, 0x400e,
  			    "Relogin end.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5008
  		}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5009
  loop_resync_check:
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5010
  		if (test_and_clear_bit(LOOP_RESYNC_NEEDED,
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5011
  		    &base_vha->dpc_flags)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5012

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5013
5014
5015
  			ql_dbg(ql_dbg_dpc, base_vha, 0x400f,
  			    "Loop resync scheduled.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5016
5017
  
  			if (!(test_and_set_bit(LOOP_RESYNC_ACTIVE,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5018
  			    &base_vha->dpc_flags))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5019

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5020
  				rval = qla2x00_loop_resync(base_vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5021

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5022
5023
  				clear_bit(LOOP_RESYNC_ACTIVE,
  						&base_vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5024
  			}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5025
5026
5027
  			ql_dbg(ql_dbg_dpc, base_vha, 0x4010,
  			    "Loop resync end.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5028
  		}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5029
5030
  		if (IS_QLAFX00(ha))
  			goto intr_on_check;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5031
5032
5033
5034
  		if (test_bit(NPIV_CONFIG_NEEDED, &base_vha->dpc_flags) &&
  		    atomic_read(&base_vha->loop_state) == LOOP_READY) {
  			clear_bit(NPIV_CONFIG_NEEDED, &base_vha->dpc_flags);
  			qla2xxx_flash_npiv_conf(base_vha);
272976ca1   Andrew Vasquez   [SCSI] qla2xxx: A...
5035
  		}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5036
  intr_on_check:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5037
  		if (!ha->interrupts_on)
fd34f5569   Andrew Vasquez   [SCSI] qla2xxx: R...
5038
  			ha->isp_ops->enable_intrs(ha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5039

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5040
  		if (test_and_clear_bit(BEACON_BLINK_NEEDED,
90b604f26   Himanshu Madani   qla2xxx: Fix beac...
5041
5042
5043
5044
  					&base_vha->dpc_flags)) {
  			if (ha->beacon_blink_led == 1)
  				ha->isp_ops->beacon_blink(base_vha);
  		}
f6df144cc   Andrew Vasquez   [SCSI] qla2xxx: A...
5045

8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5046
5047
  		if (!IS_QLAFX00(ha))
  			qla2x00_do_dpc_all_vps(base_vha);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5048

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5049
  		ha->dpc_active = 0;
c142caf0a   Andrew Vasquez   [SCSI] qla2xxx: L...
5050
  end_loop:
563585ec4   James Bottomley   [SCSI] qla2xxx: F...
5051
  		set_current_state(TASK_INTERRUPTIBLE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5052
  	} /* End of while(1) */
563585ec4   James Bottomley   [SCSI] qla2xxx: F...
5053
  	__set_current_state(TASK_RUNNING);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5054

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5055
5056
5057
  	ql_dbg(ql_dbg_dpc, base_vha, 0x4011,
  	    "DPC handler exiting.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5058
5059
5060
5061
  
  	/*
  	 * Make sure that nobody tries to wake us up again.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5062
  	ha->dpc_active = 0;
ac280b670   Andrew Vasquez   [SCSI] qla2xxx: A...
5063
5064
  	/* Cleanup any residual CTX SRBs. */
  	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
5065
5066
5067
5068
  	return 0;
  }
  
  void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5069
  qla2xxx_wake_dpc(struct scsi_qla_host *vha)
39a112403   Christoph Hellwig   [SCSI] qla2xxx: u...
5070
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5071
  	struct qla_hw_data *ha = vha->hw;
c795c1e4b   Andrew Vasquez   [SCSI] qla2xxx: E...
5072
  	struct task_struct *t = ha->dpc_thread;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5073
  	if (!test_bit(UNLOADING, &vha->dpc_flags) && t)
c795c1e4b   Andrew Vasquez   [SCSI] qla2xxx: E...
5074
  		wake_up_process(t);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5075
5076
5077
  }
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5078
5079
5080
5081
5082
5083
5084
  *  qla2x00_rst_aen
  *      Processes asynchronous reset.
  *
  * Input:
  *      ha  = adapter block pointer.
  */
  static void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5085
  qla2x00_rst_aen(scsi_qla_host_t *vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5086
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5087
5088
5089
  	if (vha->flags.online && !vha->flags.reset_active &&
  	    !atomic_read(&vha->loop_down_timer) &&
  	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5090
  		do {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5091
  			clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5092
5093
5094
5095
5096
  
  			/*
  			 * Issue marker command only when we are going to start
  			 * the I/O.
  			 */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5097
5098
5099
  			vha->marker_needed = 1;
  		} while (!atomic_read(&vha->loop_down_timer) &&
  		    (test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags)));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5100
5101
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5102
5103
5104
5105
5106
5107
5108
5109
  /**************************************************************************
  *   qla2x00_timer
  *
  * Description:
  *   One second timer
  *
  * Context: Interrupt
  ***************************************************************************/
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5110
  void
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5111
  qla2x00_timer(scsi_qla_host_t *vha)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5112
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5113
  	unsigned long	cpu_flags = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5114
5115
5116
  	int		start_dpc = 0;
  	int		index;
  	srb_t		*sp;
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5117
  	uint16_t        w;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5118
  	struct qla_hw_data *ha = vha->hw;
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
5119
  	struct req_que *req;
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5120

a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5121
  	if (ha->flags.eeh_busy) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5122
5123
5124
5125
  		ql_dbg(ql_dbg_timer, vha, 0x6000,
  		    "EEH = %d, restarting timer.
  ",
  		    ha->flags.eeh_busy);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5126
5127
5128
  		qla2x00_restart_timer(vha, WATCH_INTERVAL);
  		return;
  	}
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
5129
5130
5131
5132
5133
  	/*
  	 * Hardware read to raise pending EEH errors during mailbox waits. If
  	 * the read returns -1 then disable the board.
  	 */
  	if (!pci_channel_offline(ha->pdev)) {
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5134
  		pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
c821e0d5b   Joe Lawrence   qla2xxx: Collect ...
5135
  		qla2x00_check_reg16_for_disconnect(vha, w);
f3ddac191   Chad Dupuis   [SCSI] qla2xxx: D...
5136
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5137

cefcaba67   Saurav Kashyap   [SCSI] qla2xxx: F...
5138
  	/* Make sure qla82xx_watchdog is run only for physical port */
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
5139
  	if (!vha->vp_idx && IS_P3P_TYPE(ha)) {
579d12b58   Saurav Kashyap   [SCSI] qla2xxx: A...
5140
5141
  		if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags))
  			start_dpc++;
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
5142
5143
5144
5145
  		if (IS_QLA82XX(ha))
  			qla82xx_watchdog(vha);
  		else if (IS_QLA8044(ha))
  			qla8044_watchdog(vha);
579d12b58   Saurav Kashyap   [SCSI] qla2xxx: A...
5146
  	}
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5147
5148
  	if (!vha->vp_idx && IS_QLAFX00(ha))
  		qlafx00_timer_routine(vha);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5149
  	/* Loop down handler. */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5150
  	if (atomic_read(&vha->loop_down_timer) > 0 &&
8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
5151
5152
  	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) &&
  	    !(test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5153
  		&& vha->flags.online) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5154

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5155
5156
  		if (atomic_read(&vha->loop_down_timer) ==
  		    vha->loop_down_abort_time) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5157

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5158
5159
5160
  			ql_log(ql_log_info, vha, 0x6008,
  			    "Loop down - aborting the queues before time expires.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5161

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5162
5163
  			if (!IS_QLA2100(ha) && vha->link_down_timeout)
  				atomic_set(&vha->loop_state, LOOP_DEAD);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5164

f08b7251c   Andrew Vasquez   [SCSI] qla2xxx: C...
5165
5166
5167
5168
  			/*
  			 * Schedule an ISP abort to return any FCP2-device
  			 * commands.
  			 */
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5169
  			/* NPIV - scan physical port only */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5170
  			if (!vha->vp_idx) {
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5171
5172
  				spin_lock_irqsave(&ha->hardware_lock,
  				    cpu_flags);
73208dfd7   Anirban Chakraborty   [SCSI] qla2xxx: a...
5173
  				req = ha->req_q_map[0];
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5174
  				for (index = 1;
8d93f5502   Chad Dupuis   [SCSI] qla2xxx: D...
5175
  				    index < req->num_outstanding_cmds;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5176
5177
  				    index++) {
  					fc_port_t *sfcp;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5178
  					sp = req->outstanding_cmds[index];
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5179
5180
  					if (!sp)
  						continue;
9ba56b95a   Giridhar Malavali   [SCSI] qla2xxx: C...
5181
  					if (sp->type != SRB_SCSI_CMD)
cf53b069f   Andrew Vasquez   [SCSI] qla2xxx: G...
5182
  						continue;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5183
  					sfcp = sp->fcport;
f08b7251c   Andrew Vasquez   [SCSI] qla2xxx: C...
5184
  					if (!(sfcp->flags & FCF_FCP2_DEVICE))
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5185
  						continue;
bdf796210   Andrew Vasquez   [PATCH] qla2xxx: ...
5186

8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
5187
5188
5189
5190
5191
  					if (IS_QLA82XX(ha))
  						set_bit(FCOE_CTX_RESET_NEEDED,
  							&vha->dpc_flags);
  					else
  						set_bit(ISP_ABORT_NEEDED,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5192
  							&vha->dpc_flags);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5193
5194
5195
  					break;
  				}
  				spin_unlock_irqrestore(&ha->hardware_lock,
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5196
  								cpu_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5197
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5198
5199
5200
5201
  			start_dpc++;
  		}
  
  		/* if the loop has been down for 4 minutes, reinit adapter */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5202
  		if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
0d6e61bc6   Andrew Vasquez   [SCSI] qla2xxx: C...
5203
  			if (!(vha->device_flags & DFLG_NO_CABLE)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5204
  				ql_log(ql_log_warn, vha, 0x6009,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5205
5206
  				    "Loop down - aborting ISP.
  ");
8f7daead3   Giridhar Malavali   [SCSI] qla2xxx: P...
5207
5208
5209
5210
5211
5212
  				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
5213
5214
  			}
  		}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5215
5216
5217
5218
  		ql_dbg(ql_dbg_timer, vha, 0x600a,
  		    "Loop down - seconds remaining %d.
  ",
  		    atomic_read(&vha->loop_down_timer));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5219
  	}
cefcaba67   Saurav Kashyap   [SCSI] qla2xxx: F...
5220
5221
  	/* Check if beacon LED needs to be blinked for physical host only */
  	if (!vha->vp_idx && (ha->beacon_blink_led == 1)) {
999916dc5   Saurav Kashyap   [SCSI] qla2xxx: I...
5222
  		/* There is no beacon_blink function for ISP82xx */
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
5223
  		if (!IS_P3P_TYPE(ha)) {
999916dc5   Saurav Kashyap   [SCSI] qla2xxx: I...
5224
5225
5226
  			set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags);
  			start_dpc++;
  		}
f6df144cc   Andrew Vasquez   [SCSI] qla2xxx: A...
5227
  	}
550bf57df   Andrew Vasquez   [SCSI] qla2xxx: W...
5228
  	/* Process any deferred work. */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5229
  	if (!list_empty(&vha->work_list))
550bf57df   Andrew Vasquez   [SCSI] qla2xxx: W...
5230
  		start_dpc++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5231
  	/* Schedule the DPC routine if needed */
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5232
5233
5234
  	if ((test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
  	    test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) ||
  	    test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags) ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5235
  	    start_dpc ||
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5236
5237
  	    test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) ||
  	    test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags) ||
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5238
5239
  	    test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags) ||
  	    test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags) ||
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5240
  	    test_bit(VP_DPC_NEEDED, &vha->dpc_flags) ||
50280c014   Chad Dupuis   [SCSI] Revert "ql...
5241
  	    test_bit(RELOGIN_NEEDED, &vha->dpc_flags))) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
  		ql_dbg(ql_dbg_timer, vha, 0x600b,
  		    "isp_abort_needed=%d loop_resync_needed=%d "
  		    "fcport_update_needed=%d start_dpc=%d "
  		    "reset_marker_needed=%d",
  		    test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags),
  		    test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags),
  		    test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags),
  		    start_dpc,
  		    test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags));
  		ql_dbg(ql_dbg_timer, vha, 0x600c,
  		    "beacon_blink_needed=%d isp_unrecoverable=%d "
  		    "fcoe_ctx_reset_needed=%d vp_dpc_needed=%d "
50280c014   Chad Dupuis   [SCSI] Revert "ql...
5254
5255
  		    "relogin_needed=%d.
  ",
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5256
5257
5258
5259
  		    test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags),
  		    test_bit(ISP_UNRECOVERABLE, &vha->dpc_flags),
  		    test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags),
  		    test_bit(VP_DPC_NEEDED, &vha->dpc_flags),
50280c014   Chad Dupuis   [SCSI] Revert "ql...
5260
  		    test_bit(RELOGIN_NEEDED, &vha->dpc_flags));
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5261
  		qla2xxx_wake_dpc(vha);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5262
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5263

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5264
  	qla2x00_restart_timer(vha, WATCH_INTERVAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5265
  }
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5266
  /* Firmware interface routines. */
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
5267
  #define FW_BLOBS	11
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5268
5269
5270
5271
  #define FW_ISP21XX	0
  #define FW_ISP22XX	1
  #define FW_ISP2300	2
  #define FW_ISP2322	3
48c02fde9   Andrew Vasquez   [SCSI] qla2xxx: C...
5272
  #define FW_ISP24XX	4
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
5273
  #define FW_ISP25XX	5
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
5274
  #define FW_ISP81XX	6
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5275
  #define FW_ISP82XX	7
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
5276
5277
  #define FW_ISP2031	8
  #define FW_ISP8031	9
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
5278
  #define FW_ISP27XX	10
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5279

bb8ee4998   Andrew Vasquez   [SCSI] qla2xxx: A...
5280
5281
5282
5283
5284
  #define FW_FILE_ISP21XX	"ql2100_fw.bin"
  #define FW_FILE_ISP22XX	"ql2200_fw.bin"
  #define FW_FILE_ISP2300	"ql2300_fw.bin"
  #define FW_FILE_ISP2322	"ql2322_fw.bin"
  #define FW_FILE_ISP24XX	"ql2400_fw.bin"
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
5285
  #define FW_FILE_ISP25XX	"ql2500_fw.bin"
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
5286
  #define FW_FILE_ISP81XX	"ql8100_fw.bin"
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5287
  #define FW_FILE_ISP82XX	"ql8200_fw.bin"
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
5288
5289
  #define FW_FILE_ISP2031	"ql2600_fw.bin"
  #define FW_FILE_ISP8031	"ql8300_fw.bin"
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
5290
  #define FW_FILE_ISP27XX	"ql2700_fw.bin"
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
5291

bb8ee4998   Andrew Vasquez   [SCSI] qla2xxx: A...
5292

e1e82b6f0   Daniel Walker   [SCSI] qla2xxx: f...
5293
  static DEFINE_MUTEX(qla_fw_lock);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5294
5295
  
  static struct fw_blob qla_fw_blobs[FW_BLOBS] = {
bb8ee4998   Andrew Vasquez   [SCSI] qla2xxx: A...
5296
5297
5298
5299
5300
  	{ .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, },
  	{ .name = FW_FILE_ISP22XX, .segs = { 0x1000, 0 }, },
  	{ .name = FW_FILE_ISP2300, .segs = { 0x800, 0 }, },
  	{ .name = FW_FILE_ISP2322, .segs = { 0x800, 0x1c000, 0x1e000, 0 }, },
  	{ .name = FW_FILE_ISP24XX, },
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
5301
  	{ .name = FW_FILE_ISP25XX, },
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
5302
  	{ .name = FW_FILE_ISP81XX, },
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5303
  	{ .name = FW_FILE_ISP82XX, },
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
5304
5305
  	{ .name = FW_FILE_ISP2031, },
  	{ .name = FW_FILE_ISP8031, },
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
5306
  	{ .name = FW_FILE_ISP27XX, },
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5307
5308
5309
  };
  
  struct fw_blob *
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5310
  qla2x00_request_firmware(scsi_qla_host_t *vha)
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5311
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5312
  	struct qla_hw_data *ha = vha->hw;
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5313
  	struct fw_blob *blob;
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5314
5315
5316
5317
  	if (IS_QLA2100(ha)) {
  		blob = &qla_fw_blobs[FW_ISP21XX];
  	} else if (IS_QLA2200(ha)) {
  		blob = &qla_fw_blobs[FW_ISP22XX];
48c02fde9   Andrew Vasquez   [SCSI] qla2xxx: C...
5318
  	} else if (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA6312(ha)) {
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5319
  		blob = &qla_fw_blobs[FW_ISP2300];
48c02fde9   Andrew Vasquez   [SCSI] qla2xxx: C...
5320
  	} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5321
  		blob = &qla_fw_blobs[FW_ISP2322];
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
5322
  	} else if (IS_QLA24XX_TYPE(ha)) {
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5323
  		blob = &qla_fw_blobs[FW_ISP24XX];
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
5324
5325
  	} else if (IS_QLA25XX(ha)) {
  		blob = &qla_fw_blobs[FW_ISP25XX];
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
5326
5327
  	} else if (IS_QLA81XX(ha)) {
  		blob = &qla_fw_blobs[FW_ISP81XX];
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5328
5329
  	} else if (IS_QLA82XX(ha)) {
  		blob = &qla_fw_blobs[FW_ISP82XX];
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
5330
5331
5332
5333
  	} else if (IS_QLA2031(ha)) {
  		blob = &qla_fw_blobs[FW_ISP2031];
  	} else if (IS_QLA8031(ha)) {
  		blob = &qla_fw_blobs[FW_ISP8031];
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
5334
5335
  	} else if (IS_QLA27XX(ha)) {
  		blob = &qla_fw_blobs[FW_ISP27XX];
8a6552299   Dan Carpenter   [SCSI] qla2xxx: h...
5336
5337
  	} else {
  		return NULL;
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5338
  	}
e1e82b6f0   Daniel Walker   [SCSI] qla2xxx: f...
5339
  	mutex_lock(&qla_fw_lock);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5340
5341
5342
5343
  	if (blob->fw)
  		goto out;
  
  	if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5344
5345
5346
  		ql_log(ql_log_warn, vha, 0x0063,
  		    "Failed to load firmware image (%s).
  ", blob->name);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5347
5348
5349
5350
5351
5352
  		blob->fw = NULL;
  		blob = NULL;
  		goto out;
  	}
  
  out:
e1e82b6f0   Daniel Walker   [SCSI] qla2xxx: f...
5353
  	mutex_unlock(&qla_fw_lock);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5354
5355
5356
5357
5358
5359
5360
  	return blob;
  }
  
  static void
  qla2x00_release_firmware(void)
  {
  	int idx;
e1e82b6f0   Daniel Walker   [SCSI] qla2xxx: f...
5361
  	mutex_lock(&qla_fw_lock);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5362
  	for (idx = 0; idx < FW_BLOBS; idx++)
cf92549f1   Jesper Juhl   qla2xxx: Remove r...
5363
  		release_firmware(qla_fw_blobs[idx].fw);
e1e82b6f0   Daniel Walker   [SCSI] qla2xxx: f...
5364
  	mutex_unlock(&qla_fw_lock);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5365
  }
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5366
5367
5368
  static pci_ers_result_t
  qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
  {
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5369
5370
  	scsi_qla_host_t *vha = pci_get_drvdata(pdev);
  	struct qla_hw_data *ha = vha->hw;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5371
5372
5373
  	ql_dbg(ql_dbg_aer, vha, 0x9000,
  	    "PCI error detected, state %x.
  ", state);
b9b12f73d   Seokmann Ju   [SCSI] qla2xxx: C...
5374

14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5375
5376
  	switch (state) {
  	case pci_channel_io_normal:
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5377
  		ha->flags.eeh_busy = 0;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5378
5379
  		return PCI_ERS_RESULT_CAN_RECOVER;
  	case pci_channel_io_frozen:
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5380
  		ha->flags.eeh_busy = 1;
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5381
5382
  		/* For ISP82XX complete any pending mailbox cmd */
  		if (IS_QLA82XX(ha)) {
7190575f7   Giridhar Malavali   [SCSI] qla2xxx: A...
5383
  			ha->flags.isp82xx_fw_hung = 1;
c8f6544e6   Chad Dupuis   [SCSI] qla2xxx: E...
5384
5385
5386
  			ql_dbg(ql_dbg_aer, vha, 0x9001, "Pci channel io frozen
  ");
  			qla82xx_clear_pending_mbx(vha);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5387
  		}
90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5388
  		qla2x00_free_irqs(vha);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5389
  		pci_disable_device(pdev);
bddd2d65a   Lalit Chandivade   [SCSI] qla2xxx: U...
5390
5391
  		/* Return back all IOs */
  		qla2x00_abort_all_cmds(vha, DID_RESET << 16);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5392
5393
  		return PCI_ERS_RESULT_NEED_RESET;
  	case pci_channel_io_perm_failure:
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5394
5395
  		ha->flags.pci_channel_io_perm_failure = 1;
  		qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
  		return PCI_ERS_RESULT_DISCONNECT;
  	}
  	return PCI_ERS_RESULT_NEED_RESET;
  }
  
  static pci_ers_result_t
  qla2xxx_pci_mmio_enabled(struct pci_dev *pdev)
  {
  	int risc_paused = 0;
  	uint32_t stat;
  	unsigned long flags;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5407
5408
  	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
  	struct qla_hw_data *ha = base_vha->hw;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5409
5410
  	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
  	struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24;
bcc5b6d32   Saurav Kashyap   [SCSI] qla2xxx: A...
5411
5412
  	if (IS_QLA82XX(ha))
  		return PCI_ERS_RESULT_RECOVERED;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
  	spin_lock_irqsave(&ha->hardware_lock, flags);
  	if (IS_QLA2100(ha) || IS_QLA2200(ha)){
  		stat = RD_REG_DWORD(&reg->hccr);
  		if (stat & HCCR_RISC_PAUSE)
  			risc_paused = 1;
  	} else if (IS_QLA23XX(ha)) {
  		stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
  		if (stat & HSR_RISC_PAUSED)
  			risc_paused = 1;
  	} else if (IS_FWI2_CAPABLE(ha)) {
  		stat = RD_REG_DWORD(&reg24->host_status);
  		if (stat & HSRX_RISC_PAUSED)
  			risc_paused = 1;
  	}
  	spin_unlock_irqrestore(&ha->hardware_lock, flags);
  
  	if (risc_paused) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5430
5431
5432
  		ql_log(ql_log_info, base_vha, 0x9003,
  		    "RISC paused -- mmio_enabled, Dumping firmware.
  ");
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5433
  		ha->isp_ops->fw_dump(base_vha, 0);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5434
5435
5436
5437
5438
  
  		return PCI_ERS_RESULT_NEED_RESET;
  	} else
  		return PCI_ERS_RESULT_RECOVERED;
  }
fa4926306   Saurav Kashyap   [SCSI] qla2xxx: F...
5439
5440
  static uint32_t
  qla82xx_error_recovery(scsi_qla_host_t *base_vha)
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5441
5442
5443
5444
5445
5446
  {
  	uint32_t rval = QLA_FUNCTION_FAILED;
  	uint32_t drv_active = 0;
  	struct qla_hw_data *ha = base_vha->hw;
  	int fn;
  	struct pci_dev *other_pdev = NULL;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5447
5448
5449
  	ql_dbg(ql_dbg_aer, base_vha, 0x9006,
  	    "Entered %s.
  ", __func__);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
  
  	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
  
  	if (base_vha->flags.online) {
  		/* Abort all outstanding commands,
  		 * so as to be requeued later */
  		qla2x00_abort_isp_cleanup(base_vha);
  	}
  
  
  	fn = PCI_FUNC(ha->pdev->devfn);
  	while (fn > 0) {
  		fn--;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5463
5464
5465
  		ql_dbg(ql_dbg_aer, base_vha, 0x9007,
  		    "Finding pci device at function = 0x%x.
  ", fn);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5466
5467
5468
5469
5470
5471
5472
5473
  		other_pdev =
  		    pci_get_domain_bus_and_slot(pci_domain_nr(ha->pdev->bus),
  		    ha->pdev->bus->number, PCI_DEVFN(PCI_SLOT(ha->pdev->devfn),
  		    fn));
  
  		if (!other_pdev)
  			continue;
  		if (atomic_read(&other_pdev->enable_cnt)) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5474
5475
5476
5477
  			ql_dbg(ql_dbg_aer, base_vha, 0x9008,
  			    "Found PCI func available and enable at 0x%x.
  ",
  			    fn);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5478
5479
5480
5481
5482
5483
5484
5485
  			pci_dev_put(other_pdev);
  			break;
  		}
  		pci_dev_put(other_pdev);
  	}
  
  	if (!fn) {
  		/* Reset owner */
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5486
5487
5488
5489
  		ql_dbg(ql_dbg_aer, base_vha, 0x9009,
  		    "This devfn is reset owner = 0x%x.
  ",
  		    ha->pdev->devfn);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5490
5491
5492
  		qla82xx_idc_lock(ha);
  
  		qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
5493
  		    QLA8XXX_DEV_INITIALIZING);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5494
5495
5496
5497
5498
  
  		qla82xx_wr_32(ha, QLA82XX_CRB_DRV_IDC_VERSION,
  		    QLA82XX_IDC_VERSION);
  
  		drv_active = qla82xx_rd_32(ha, QLA82XX_CRB_DRV_ACTIVE);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5499
5500
5501
  		ql_dbg(ql_dbg_aer, base_vha, 0x900a,
  		    "drv_active = 0x%x.
  ", drv_active);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
  
  		qla82xx_idc_unlock(ha);
  		/* Reset if device is not already reset
  		 * drv_active would be 0 if a reset has already been done
  		 */
  		if (drv_active)
  			rval = qla82xx_start_firmware(base_vha);
  		else
  			rval = QLA_SUCCESS;
  		qla82xx_idc_lock(ha);
  
  		if (rval != QLA_SUCCESS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5514
5515
5516
  			ql_log(ql_log_info, base_vha, 0x900b,
  			    "HW State: FAILED.
  ");
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5517
5518
  			qla82xx_clear_drv_active(ha);
  			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
5519
  			    QLA8XXX_DEV_FAILED);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5520
  		} else {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5521
5522
5523
  			ql_log(ql_log_info, base_vha, 0x900c,
  			    "HW State: READY.
  ");
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5524
  			qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE,
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
5525
  			    QLA8XXX_DEV_READY);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5526
  			qla82xx_idc_unlock(ha);
7190575f7   Giridhar Malavali   [SCSI] qla2xxx: A...
5527
  			ha->flags.isp82xx_fw_hung = 0;
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5528
5529
5530
5531
5532
5533
5534
5535
  			rval = qla82xx_restart_isp(base_vha);
  			qla82xx_idc_lock(ha);
  			/* Clear driver state register */
  			qla82xx_wr_32(ha, QLA82XX_CRB_DRV_STATE, 0);
  			qla82xx_set_drv_active(base_vha);
  		}
  		qla82xx_idc_unlock(ha);
  	} else {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5536
5537
5538
5539
  		ql_dbg(ql_dbg_aer, base_vha, 0x900d,
  		    "This devfn is not reset owner = 0x%x.
  ",
  		    ha->pdev->devfn);
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5540
  		if ((qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
7d613ac6a   Santosh Vernekar   [SCSI] qla2xxx: I...
5541
  		    QLA8XXX_DEV_READY)) {
7190575f7   Giridhar Malavali   [SCSI] qla2xxx: A...
5542
  			ha->flags.isp82xx_fw_hung = 0;
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
  			rval = qla82xx_restart_isp(base_vha);
  			qla82xx_idc_lock(ha);
  			qla82xx_set_drv_active(base_vha);
  			qla82xx_idc_unlock(ha);
  		}
  	}
  	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
  
  	return rval;
  }
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5553
5554
5555
5556
  static pci_ers_result_t
  qla2xxx_pci_slot_reset(struct pci_dev *pdev)
  {
  	pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5557
5558
  	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
  	struct qla_hw_data *ha = base_vha->hw;
90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5559
5560
  	struct rsp_que *rsp;
  	int rc, retries = 10;
094839164   Benjamin Herrenschmidt   PCI: Remove users...
5561

7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5562
5563
5564
  	ql_dbg(ql_dbg_aer, base_vha, 0x9004,
  	    "Slot Reset.
  ");
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5565

90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5566
5567
5568
5569
5570
5571
5572
  	/* Workaround: qla2xxx driver which access hardware earlier
  	 * needs error state to be pci_channel_io_online.
  	 * Otherwise mailbox command timesout.
  	 */
  	pdev->error_state = pci_channel_io_normal;
  
  	pci_restore_state(pdev);
8c1496bda   Richard Lary   [SCSI] qla2xxx: E...
5573
5574
5575
5576
  	/* pci_restore_state() clears the saved_state flag of the device
  	 * save restored state which resets saved_state flag
  	 */
  	pci_save_state(pdev);
094839164   Benjamin Herrenschmidt   PCI: Remove users...
5577
5578
5579
5580
  	if (ha->mem_only)
  		rc = pci_enable_device_mem(pdev);
  	else
  		rc = pci_enable_device(pdev);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5581

094839164   Benjamin Herrenschmidt   PCI: Remove users...
5582
  	if (rc) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5583
  		ql_log(ql_log_warn, base_vha, 0x9005,
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5584
5585
  		    "Can't re-enable PCI device after reset.
  ");
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5586
  		goto exit_slot_reset;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5587
  	}
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5588

90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5589
5590
  	rsp = ha->rsp_q_map[0];
  	if (qla2x00_request_irqs(ha, rsp))
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5591
  		goto exit_slot_reset;
90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5592

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5593
  	if (ha->isp_ops->pci_config(base_vha))
a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5594
5595
5596
5597
5598
5599
5600
5601
5602
  		goto exit_slot_reset;
  
  	if (IS_QLA82XX(ha)) {
  		if (qla82xx_error_recovery(base_vha) == QLA_SUCCESS) {
  			ret = PCI_ERS_RESULT_RECOVERED;
  			goto exit_slot_reset;
  		} else
  			goto exit_slot_reset;
  	}
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5603

90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5604
5605
  	while (ha->flags.mbox_busy && retries--)
  		msleep(1000);
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5606

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5607
  	set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5608
  	if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS)
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5609
  		ret =  PCI_ERS_RESULT_RECOVERED;
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5610
  	clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5611

90a86fc05   Joe Carnuccio   [SCSI] qla2xxx: E...
5612

a5b363219   Lalit Chandivade   [SCSI] qla2xxx: A...
5613
  exit_slot_reset:
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5614
5615
5616
  	ql_dbg(ql_dbg_aer, base_vha, 0x900e,
  	    "slot_reset return %x.
  ", ret);
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5617

14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5618
5619
5620
5621
5622
5623
  	return ret;
  }
  
  static void
  qla2xxx_pci_resume(struct pci_dev *pdev)
  {
e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5624
5625
  	scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
  	struct qla_hw_data *ha = base_vha->hw;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5626
  	int ret;
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5627
5628
5629
  	ql_dbg(ql_dbg_aer, base_vha, 0x900f,
  	    "pci_resume.
  ");
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5630

e315cd28b   Anirban Chakraborty   [SCSI] qla2xxx: C...
5631
  	ret = qla2x00_wait_for_hba_online(base_vha);
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5632
  	if (ret != QLA_SUCCESS) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5633
5634
5635
  		ql_log(ql_log_fatal, base_vha, 0x9002,
  		    "The device failed to resume I/O from slot/link_reset.
  ");
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5636
  	}
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5637

3e46f0313   Lalit Chandivade   [SCSI] qla2xxx: C...
5638
  	pci_cleanup_aer_uncorrect_error_status(pdev);
858808019   Andrew Vasquez   [SCSI] qla2xxx: E...
5639
  	ha->flags.eeh_busy = 0;
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5640
  }
2d5a4c344   Himanshu Madhani   qla2xxx: Disable ...
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
  static void
  qla83xx_disable_laser(scsi_qla_host_t *vha)
  {
  	uint32_t reg, data, fn;
  	struct qla_hw_data *ha = vha->hw;
  	struct device_reg_24xx __iomem *isp_reg = &ha->iobase->isp24;
  
  	/* pci func #/port # */
  	ql_dbg(ql_dbg_init, vha, 0x004b,
  	    "Disabling Laser for hba: %p
  ", vha);
  
  	fn = (RD_REG_DWORD(&isp_reg->ctrl_status) &
  		(BIT_15|BIT_14|BIT_13|BIT_12));
  
  	fn = (fn >> 12);
  
  	if (fn & 1)
  		reg = PORT_1_2031;
  	else
  		reg = PORT_0_2031;
  
  	data = LASER_OFF_2031;
  
  	qla83xx_wr_reg(vha, reg, data);
  }
a55b2d21e   Stephen Hemminger   scsi: make pci er...
5667
  static const struct pci_error_handlers qla2xxx_err_handler = {
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5668
5669
5670
5671
5672
  	.error_detected = qla2xxx_pci_error_detected,
  	.mmio_enabled = qla2xxx_pci_mmio_enabled,
  	.slot_reset = qla2xxx_pci_slot_reset,
  	.resume = qla2xxx_pci_resume,
  };
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5673
  static struct pci_device_id qla2xxx_pci_tbl[] = {
47f5e069e   Andrew Vasquez   [SCSI] qla2xxx: U...
5674
5675
5676
5677
5678
5679
5680
5681
5682
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2300) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2312) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2322) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6312) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
4d4df1932   Harihara Kadayam   [SCSI] qla2xxx: A...
5683
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) },
47f5e069e   Andrew Vasquez   [SCSI] qla2xxx: U...
5684
5685
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
c3a2f0dfe   Andrew Vasquez   [SCSI] qla2xxx: A...
5686
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
6246b8a1d   Giridhar Malavali   [SCSI] qla2xxx: E...
5687
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2031) },
3a03eb797   Andrew Vasquez   [SCSI] qla2xxx: A...
5688
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8001) },
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5689
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8021) },
650f528f3   Chad Dupuis   [SCSI] qla2xxx: B...
5690
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8031) },
8ae6d9c7e   Giridhar Malavali   [SCSI] qla2xxx: E...
5691
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) },
7ec0effd3   Atul Deshmukh   [SCSI] qla2xxx: A...
5692
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) },
f73cb695d   Chad Dupuis   [SCSI] qla2xxx: A...
5693
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) },
2c5bbbb25   Joe Carnuccio   qla2xxx: Add pci ...
5694
  	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) },
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5695
5696
5697
  	{ 0 },
  };
  MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5698
  static struct pci_driver qla2xxx_pci_driver = {
cb63067a7   Andrew Vasquez   [SCSI] qla2xxx: C...
5699
  	.name		= QLA2XXX_DRIVER_NAME,
0a21ef1e6   James Bottomley   [SCSI] qla2xxx: f...
5700
5701
5702
  	.driver		= {
  		.owner		= THIS_MODULE,
  	},
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5703
  	.id_table	= qla2xxx_pci_tbl,
7ee613970   Andrew Vasquez   [SCSI] qla2xxx: C...
5704
  	.probe		= qla2x00_probe_one,
4c993f766   Adrian Bunk   scsi/qla2xxx/qla_...
5705
  	.remove		= qla2x00_remove_one,
e30d17564   Madhuranath Iyengar   [SCSI] qla2xxx: A...
5706
  	.shutdown	= qla2x00_shutdown,
14e660e67   Seokmann Ju   [SCSI] qla2xxx: A...
5707
  	.err_handler	= &qla2xxx_err_handler,
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5708
  };
75ef9de12   Al Viro   constify a bunch ...
5709
  static const struct file_operations apidev_fops = {
6a03b4cd7   Harish Zunjarrao   [SCSI] qla2xxx: A...
5710
  	.owner = THIS_MODULE,
6038f373a   Arnd Bergmann   llseek: automatic...
5711
  	.llseek = noop_llseek,
6a03b4cd7   Harish Zunjarrao   [SCSI] qla2xxx: A...
5712
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5713
5714
5715
5716
5717
5718
  /**
   * qla2x00_module_init - Module initialization.
   **/
  static int __init
  qla2x00_module_init(void)
  {
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5719
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5720
  	/* Allocate cache for SRBs. */
354d6b219   Andrew Vasquez   [SCSI] remove som...
5721
  	srb_cachep = kmem_cache_create("qla2xxx_srbs", sizeof(srb_t), 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
5722
  	    SLAB_HWCACHE_ALIGN, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5723
  	if (srb_cachep == NULL) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5724
5725
5726
  		ql_log(ql_log_fatal, NULL, 0x0001,
  		    "Unable to allocate SRB cache...Failing load!.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5727
5728
  		return -ENOMEM;
  	}
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
  	/* Initialize target kmem_cache and mem_pools */
  	ret = qlt_init();
  	if (ret < 0) {
  		kmem_cache_destroy(srb_cachep);
  		return ret;
  	} else if (ret > 0) {
  		/*
  		 * If initiator mode is explictly disabled by qlt_init(),
  		 * prevent scsi_transport_fc.c:fc_scsi_scan_rport() from
  		 * performing scsi_scan_target() during LOOP UP event.
  		 */
  		qla2xxx_transport_functions.disable_target_scan = 1;
  		qla2xxx_transport_vport_functions.disable_target_scan = 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5743
5744
  	/* Derive version string. */
  	strcpy(qla2x00_version_str, QLA2XXX_VERSION);
11010fecd   Andrew Vasquez   [SCSI] Maintain m...
5745
  	if (ql2xextended_error_logging)
0181944fe   Andrew Vasquez   [SCSI] qla2xxx: A...
5746
  		strcat(qla2x00_version_str, "-debug");
1c97a12a2   Andrew Vasquez   [SCSI] qla2xxx: r...
5747
5748
  	qla2xxx_transport_template =
  	    fc_attach_transport(&qla2xxx_transport_functions);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5749
5750
  	if (!qla2xxx_transport_template) {
  		kmem_cache_destroy(srb_cachep);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5751
5752
5753
  		ql_log(ql_log_fatal, NULL, 0x0002,
  		    "fc_attach_transport failed...Failing load!.
  ");
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
5754
  		qlt_exit();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5755
  		return -ENODEV;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5756
  	}
6a03b4cd7   Harish Zunjarrao   [SCSI] qla2xxx: A...
5757
5758
5759
  
  	apidev_major = register_chrdev(0, QLA2XXX_APIDEV, &apidev_fops);
  	if (apidev_major < 0) {
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5760
5761
5762
  		ql_log(ql_log_fatal, NULL, 0x0003,
  		    "Unable to register char device %s.
  ", QLA2XXX_APIDEV);
6a03b4cd7   Harish Zunjarrao   [SCSI] qla2xxx: A...
5763
  	}
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5764
5765
5766
5767
  	qla2xxx_transport_vport_template =
  	    fc_attach_transport(&qla2xxx_transport_vport_functions);
  	if (!qla2xxx_transport_vport_template) {
  		kmem_cache_destroy(srb_cachep);
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
5768
  		qlt_exit();
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5769
  		fc_release_transport(qla2xxx_transport_template);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5770
5771
5772
  		ql_log(ql_log_fatal, NULL, 0x0004,
  		    "fc_attach_transport vport failed...Failing load!.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5773
  		return -ENODEV;
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5774
  	}
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5775
5776
5777
  	ql_log(ql_log_info, NULL, 0x0005,
  	    "QLogic Fibre Channel HBA Driver: %s.
  ",
fd9a29f03   Andrew Vasquez   [SCSI] qla2xxx: D...
5778
  	    qla2x00_version_str);
7ee613970   Andrew Vasquez   [SCSI] qla2xxx: C...
5779
  	ret = pci_register_driver(&qla2xxx_pci_driver);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5780
5781
  	if (ret) {
  		kmem_cache_destroy(srb_cachep);
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
5782
  		qlt_exit();
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5783
  		fc_release_transport(qla2xxx_transport_template);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5784
  		fc_release_transport(qla2xxx_transport_vport_template);
7c3df1320   Saurav Kashyap   [SCSI] qla2xxx: C...
5785
5786
5787
5788
  		ql_log(ql_log_fatal, NULL, 0x0006,
  		    "pci_register_driver failed...ret=%d Failing load!.
  ",
  		    ret);
fca297037   Andrew Vasquez   [SCSI] qla2xxx: A...
5789
5790
  	}
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5791
5792
5793
5794
5795
5796
5797
5798
  }
  
  /**
   * qla2x00_module_exit - Module cleanup.
   **/
  static void __exit
  qla2x00_module_exit(void)
  {
6a03b4cd7   Harish Zunjarrao   [SCSI] qla2xxx: A...
5799
  	unregister_chrdev(apidev_major, QLA2XXX_APIDEV);
7ee613970   Andrew Vasquez   [SCSI] qla2xxx: C...
5800
  	pci_unregister_driver(&qla2xxx_pci_driver);
5433383ef   Andrew Vasquez   [SCSI] qla2xxx: A...
5801
  	qla2x00_release_firmware();
354d6b219   Andrew Vasquez   [SCSI] remove som...
5802
  	kmem_cache_destroy(srb_cachep);
2d70c103f   Nicholas Bellinger   [SCSI] qla2xxx: A...
5803
  	qlt_exit();
a9083016a   Giridhar Malavali   [SCSI] qla2xxx: A...
5804
5805
  	if (ctx_cachep)
  		kmem_cache_destroy(ctx_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5806
  	fc_release_transport(qla2xxx_transport_template);
2c3dfe3f6   Seokmann Ju   [SCSI] qla2xxx: a...
5807
  	fc_release_transport(qla2xxx_transport_vport_template);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5808
5809
5810
5811
5812
5813
5814
5815
5816
  }
  
  module_init(qla2x00_module_init);
  module_exit(qla2x00_module_exit);
  
  MODULE_AUTHOR("QLogic Corporation");
  MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver");
  MODULE_LICENSE("GPL");
  MODULE_VERSION(QLA2XXX_VERSION);
bb8ee4998   Andrew Vasquez   [SCSI] qla2xxx: A...
5817
5818
5819
5820
5821
  MODULE_FIRMWARE(FW_FILE_ISP21XX);
  MODULE_FIRMWARE(FW_FILE_ISP22XX);
  MODULE_FIRMWARE(FW_FILE_ISP2300);
  MODULE_FIRMWARE(FW_FILE_ISP2322);
  MODULE_FIRMWARE(FW_FILE_ISP24XX);
61623fc34   Andrew Vasquez   [SCSI] qla2xxx: A...
5822
  MODULE_FIRMWARE(FW_FILE_ISP25XX);