xref: /linux/drivers/message/fusion/mptfc.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 /*
2  *  linux/drivers/message/fusion/mptfc.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.com)
8  *
9  */
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
11 /*
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; version 2 of the License.
15 
16     This program is distributed in the hope that it will be useful,
17     but WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     GNU General Public License for more details.
20 
21     NO WARRANTY
22     THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
23     CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
24     LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
25     MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
26     solely responsible for determining the appropriateness of using and
27     distributing the Program and assumes all risks associated with its
28     exercise of rights under this Agreement, including but not limited to
29     the risks and costs of program errors, damage to or loss of data,
30     programs or equipment, and unavailability or interruption of operations.
31 
32     DISCLAIMER OF LIABILITY
33     NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
34     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35     DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
36     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
37     TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
38     USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
39     HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
40 
41     You should have received a copy of the GNU General Public License
42     along with this program; if not, write to the Free Software
43     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
44 */
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
46 #include "linux_compat.h"	/* linux-2.6 tweaks */
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h>	/* for mdelay */
54 #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
55 #include <linux/reboot.h>	/* notifier code */
56 #include <linux/sched.h>
57 #include <linux/workqueue.h>
58 #include <linux/sort.h>
59 
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_transport_fc.h>
66 
67 #include "mptbase.h"
68 #include "mptscsih.h"
69 
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME		"Fusion MPT FC Host driver"
72 #define my_VERSION	MPT_LINUX_VERSION_COMMON
73 #define MYNAM		"mptfc"
74 
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78 
79 /* Command line args */
80 static int mpt_pq_filter = 0;
81 module_param(mpt_pq_filter, int, 0);
82 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
83 
84 #define MPTFC_DEV_LOSS_TMO (60)
85 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;	/* reasonable default */
86 module_param(mptfc_dev_loss_tmo, int, 0);
87 MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
88     				     " transport to wait for an rport to "
89 				     " return following a device loss event."
90 				     "  Default=60.");
91 
92 static int	mptfcDoneCtx = -1;
93 static int	mptfcTaskCtx = -1;
94 static int	mptfcInternalCtx = -1; /* Used only for internal commands */
95 
96 static int mptfc_target_alloc(struct scsi_target *starget);
97 static int mptfc_slave_alloc(struct scsi_device *sdev);
98 static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
99 		      void (*done)(struct scsi_cmnd *));
100 static void mptfc_target_destroy(struct scsi_target *starget);
101 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
102 static void __devexit mptfc_remove(struct pci_dev *pdev);
103 
104 static struct scsi_host_template mptfc_driver_template = {
105 	.module				= THIS_MODULE,
106 	.proc_name			= "mptfc",
107 	.proc_info			= mptscsih_proc_info,
108 	.name				= "MPT FC Host",
109 	.info				= mptscsih_info,
110 	.queuecommand			= mptfc_qcmd,
111 	.target_alloc			= mptfc_target_alloc,
112 	.slave_alloc			= mptfc_slave_alloc,
113 	.slave_configure		= mptscsih_slave_configure,
114 	.target_destroy			= mptfc_target_destroy,
115 	.slave_destroy			= mptscsih_slave_destroy,
116 	.change_queue_depth 		= mptscsih_change_queue_depth,
117 	.eh_abort_handler		= mptscsih_abort,
118 	.eh_device_reset_handler	= mptscsih_dev_reset,
119 	.eh_bus_reset_handler		= mptscsih_bus_reset,
120 	.eh_host_reset_handler		= mptscsih_host_reset,
121 	.bios_param			= mptscsih_bios_param,
122 	.can_queue			= MPT_FC_CAN_QUEUE,
123 	.this_id			= -1,
124 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
125 	.max_sectors			= 8192,
126 	.cmd_per_lun			= 7,
127 	.use_clustering			= ENABLE_CLUSTERING,
128 };
129 
130 /****************************************************************************
131  * Supported hardware
132  */
133 
134 static struct pci_device_id mptfc_pci_table[] = {
135 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
136 		PCI_ANY_ID, PCI_ANY_ID },
137 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
138 		PCI_ANY_ID, PCI_ANY_ID },
139 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
140 		PCI_ANY_ID, PCI_ANY_ID },
141 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
142 		PCI_ANY_ID, PCI_ANY_ID },
143 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
144 		PCI_ANY_ID, PCI_ANY_ID },
145 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
146 		PCI_ANY_ID, PCI_ANY_ID },
147 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
148 		PCI_ANY_ID, PCI_ANY_ID },
149 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
150 		PCI_ANY_ID, PCI_ANY_ID },
151 	{0}	/* Terminating entry */
152 };
153 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
154 
155 static struct scsi_transport_template *mptfc_transport_template = NULL;
156 
157 static struct fc_function_template mptfc_transport_functions = {
158 	.dd_fcrport_size = 8,
159 	.show_host_node_name = 1,
160 	.show_host_port_name = 1,
161 	.show_host_supported_classes = 1,
162 	.show_host_port_id = 1,
163 	.show_rport_supported_classes = 1,
164 	.show_starget_node_name = 1,
165 	.show_starget_port_name = 1,
166 	.show_starget_port_id = 1,
167 	.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
168 	.show_rport_dev_loss_tmo = 1,
169 
170 };
171 
172 static void
173 mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
174 {
175 	if (timeout > 0)
176 		rport->dev_loss_tmo = timeout;
177 	else
178 		rport->dev_loss_tmo = mptfc_dev_loss_tmo;
179 }
180 
181 static int
182 mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
183 {
184 	FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
185 	FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
186 
187 	if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
188 		if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
189 			return 0;
190 		if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
191 			return -1;
192 		return 1;
193 	}
194 	if ((*aa)->CurrentBus < (*bb)->CurrentBus)
195 		return -1;
196 	return 1;
197 }
198 
199 static int
200 mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
201 	void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
202 {
203 	ConfigPageHeader_t	 hdr;
204 	CONFIGPARMS		 cfg;
205 	FCDevicePage0_t		*ppage0_alloc, *fc;
206 	dma_addr_t		 page0_dma;
207 	int			 data_sz;
208 	int			 ii;
209 
210 	FCDevicePage0_t		*p0_array=NULL, *p_p0;
211 	FCDevicePage0_t		**pp0_array=NULL, **p_pp0;
212 
213 	int			 rc = -ENOMEM;
214 	U32			 port_id = 0xffffff;
215 	int			 num_targ = 0;
216 	int			 max_bus = ioc->facts.MaxBuses;
217 	int			 max_targ = ioc->facts.MaxDevices;
218 
219 	if (max_bus == 0 || max_targ == 0)
220 		goto out;
221 
222 	data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
223 	p_p0 = p0_array =  kzalloc(data_sz, GFP_KERNEL);
224 	if (!p0_array)
225 		goto out;
226 
227 	data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
228 	p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
229 	if (!pp0_array)
230 		goto out;
231 
232 	do {
233 		/* Get FC Device Page 0 header */
234 		hdr.PageVersion = 0;
235 		hdr.PageLength = 0;
236 		hdr.PageNumber = 0;
237 		hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
238 		cfg.cfghdr.hdr = &hdr;
239 		cfg.physAddr = -1;
240 		cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
241 		cfg.dir = 0;
242 		cfg.pageAddr = port_id;
243 		cfg.timeout = 0;
244 
245 		if ((rc = mpt_config(ioc, &cfg)) != 0)
246 			break;
247 
248 		if (hdr.PageLength <= 0)
249 			break;
250 
251 		data_sz = hdr.PageLength * 4;
252 		ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
253 		    					&page0_dma);
254 		rc = -ENOMEM;
255 		if (!ppage0_alloc)
256 			break;
257 
258 		cfg.physAddr = page0_dma;
259 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
260 
261 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
262 			ppage0_alloc->PortIdentifier =
263 				le32_to_cpu(ppage0_alloc->PortIdentifier);
264 
265 			ppage0_alloc->WWNN.Low =
266 				le32_to_cpu(ppage0_alloc->WWNN.Low);
267 
268 			ppage0_alloc->WWNN.High =
269 				le32_to_cpu(ppage0_alloc->WWNN.High);
270 
271 			ppage0_alloc->WWPN.Low =
272 				le32_to_cpu(ppage0_alloc->WWPN.Low);
273 
274 			ppage0_alloc->WWPN.High =
275 				le32_to_cpu(ppage0_alloc->WWPN.High);
276 
277 			ppage0_alloc->BBCredit =
278 				le16_to_cpu(ppage0_alloc->BBCredit);
279 
280 			ppage0_alloc->MaxRxFrameSize =
281 				le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
282 
283 			port_id = ppage0_alloc->PortIdentifier;
284 			num_targ++;
285 			*p_p0 = *ppage0_alloc;	/* save data */
286 			*p_pp0++ = p_p0++;	/* save addr */
287 		}
288 		pci_free_consistent(ioc->pcidev, data_sz,
289 		    			(u8 *) ppage0_alloc, page0_dma);
290 		if (rc != 0)
291 			break;
292 
293 	} while (port_id <= 0xff0000);
294 
295 	if (num_targ) {
296 		/* sort array */
297 		if (num_targ > 1)
298 			sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
299 				mptfc_FcDevPage0_cmp_func, NULL);
300 		/* call caller's func for each targ */
301 		for (ii = 0; ii < num_targ;  ii++) {
302 			fc = *(pp0_array+ii);
303 			func(ioc, ioc_port, fc);
304 		}
305 	}
306 
307  out:
308 	if (pp0_array)
309 		kfree(pp0_array);
310 	if (p0_array)
311 		kfree(p0_array);
312 	return rc;
313 }
314 
315 static int
316 mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
317 {
318 	/* not currently usable */
319 	if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
320 			  MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
321 		return -1;
322 
323 	if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
324 		return -1;
325 
326 	if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
327 		return -1;
328 
329 	/*
330 	 * board data structure already normalized to platform endianness
331 	 * shifted to avoid unaligned access on 64 bit architecture
332 	 */
333 	rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
334 	rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
335 	rid->port_id =   pg0->PortIdentifier;
336 	rid->roles = FC_RPORT_ROLE_UNKNOWN;
337 
338 	return 0;
339 }
340 
341 static void
342 mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
343 {
344 	struct fc_rport_identifiers rport_ids;
345 	struct fc_rport		*rport;
346 	struct mptfc_rport_info	*ri;
347 	int			new_ri = 1;
348 	u64			pn, nn;
349 	VirtTarget		*vtarget;
350 	u32			roles = FC_RPORT_ROLE_UNKNOWN;
351 
352 	if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
353 		return;
354 
355 	roles |= FC_RPORT_ROLE_FCP_TARGET;
356 	if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
357 		roles |= FC_RPORT_ROLE_FCP_INITIATOR;
358 
359 	/* scan list looking for a match */
360 	list_for_each_entry(ri, &ioc->fc_rports, list) {
361 		pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
362 		if (pn == rport_ids.port_name) {	/* match */
363 			list_move_tail(&ri->list, &ioc->fc_rports);
364 			new_ri = 0;
365 			break;
366 		}
367 	}
368 	if (new_ri) {	/* allocate one */
369 		ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
370 		if (!ri)
371 			return;
372 		list_add_tail(&ri->list, &ioc->fc_rports);
373 	}
374 
375 	ri->pg0 = *pg0;	/* add/update pg0 data */
376 	ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
377 
378 	/* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
379 	if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
380 		ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
381 		rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
382 		if (rport) {
383 			ri->rport = rport;
384 			if (new_ri) /* may have been reset by user */
385 				rport->dev_loss_tmo = mptfc_dev_loss_tmo;
386 			/*
387 			 * if already mapped, remap here.  If not mapped,
388 			 * target_alloc will allocate vtarget and map,
389 			 * slave_alloc will fill in vdev from vtarget.
390 			 */
391 			if (ri->starget) {
392 				vtarget = ri->starget->hostdata;
393 				if (vtarget) {
394 					vtarget->target_id = pg0->CurrentTargetID;
395 					vtarget->bus_id = pg0->CurrentBus;
396 				}
397 			}
398 			*((struct mptfc_rport_info **)rport->dd_data) = ri;
399 			/* scan will be scheduled once rport becomes a target */
400 			fc_remote_port_rolechg(rport,roles);
401 
402 			pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
403 			nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
404 			dfcprintk ((MYIOC_s_INFO_FMT
405 				"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
406 				"rport tid %d, tmo %d\n",
407 					ioc->name,
408 					ioc->sh->host_no,
409 					pg0->PortIdentifier,
410 					(unsigned long long)nn,
411 					(unsigned long long)pn,
412 					pg0->CurrentTargetID,
413 					ri->rport->scsi_target_id,
414 					ri->rport->dev_loss_tmo));
415 		} else {
416 			list_del(&ri->list);
417 			kfree(ri);
418 			ri = NULL;
419 		}
420 	}
421 }
422 
423 /*
424  *	OS entry point to allow for host driver to free allocated memory
425  *	Called if no device present or device being unloaded
426  */
427 static void
428 mptfc_target_destroy(struct scsi_target *starget)
429 {
430 	struct fc_rport		*rport;
431 	struct mptfc_rport_info *ri;
432 
433 	rport = starget_to_rport(starget);
434 	if (rport) {
435 		ri = *((struct mptfc_rport_info **)rport->dd_data);
436 		if (ri)	/* better be! */
437 			ri->starget = NULL;
438 	}
439 	if (starget->hostdata)
440 		kfree(starget->hostdata);
441 	starget->hostdata = NULL;
442 }
443 
444 /*
445  *	OS entry point to allow host driver to alloc memory
446  *	for each scsi target. Called once per device the bus scan.
447  *	Return non-zero if allocation fails.
448  */
449 static int
450 mptfc_target_alloc(struct scsi_target *starget)
451 {
452 	VirtTarget		*vtarget;
453 	struct fc_rport		*rport;
454 	struct mptfc_rport_info *ri;
455 	int			rc;
456 
457 	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
458 	if (!vtarget)
459 		return -ENOMEM;
460 	starget->hostdata = vtarget;
461 
462 	rc = -ENODEV;
463 	rport = starget_to_rport(starget);
464 	if (rport) {
465 		ri = *((struct mptfc_rport_info **)rport->dd_data);
466 		if (ri) {	/* better be! */
467 			vtarget->target_id = ri->pg0.CurrentTargetID;
468 			vtarget->bus_id = ri->pg0.CurrentBus;
469 			ri->starget = starget;
470 			rc = 0;
471 		}
472 	}
473 	if (rc != 0) {
474 		kfree(vtarget);
475 		starget->hostdata = NULL;
476 	}
477 
478 	return rc;
479 }
480 
481 /*
482  *	OS entry point to allow host driver to alloc memory
483  *	for each scsi device. Called once per device the bus scan.
484  *	Return non-zero if allocation fails.
485  *	Init memory once per LUN.
486  */
487 static int
488 mptfc_slave_alloc(struct scsi_device *sdev)
489 {
490 	MPT_SCSI_HOST		*hd;
491 	VirtTarget		*vtarget;
492 	VirtDevice		*vdev;
493 	struct scsi_target	*starget;
494 	struct fc_rport		*rport;
495 
496 
497 	starget = scsi_target(sdev);
498 	rport = starget_to_rport(starget);
499 
500 	if (!rport || fc_remote_port_chkready(rport))
501 		return -ENXIO;
502 
503 	hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
504 
505 	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
506 	if (!vdev) {
507 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
508 				hd->ioc->name, sizeof(VirtDevice));
509 		return -ENOMEM;
510 	}
511 
512 
513 	sdev->hostdata = vdev;
514 	vtarget = starget->hostdata;
515 
516 	if (vtarget->num_luns == 0) {
517 		vtarget->ioc_id = hd->ioc->id;
518 		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
519 		    		  MPT_TARGET_FLAGS_VALID_INQUIRY;
520 		hd->Targets[sdev->id] = vtarget;
521 	}
522 
523 	vdev->vtarget = vtarget;
524 	vdev->lun = sdev->lun;
525 
526 	vtarget->num_luns++;
527 
528 
529 #ifdef DMPT_DEBUG_FC
530 	{
531 	u64 nn, pn;
532 	struct mptfc_rport_info *ri;
533 	ri = *((struct mptfc_rport_info **)rport->dd_data);
534 	pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
535 	nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
536 	dfcprintk ((MYIOC_s_INFO_FMT
537 		"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
538 	        "CurrentTargetID %d, %x %llx %llx\n",
539 		hd->ioc->name,
540 		sdev->host->host_no,
541 		vtarget->num_luns,
542 		sdev->id, ri->pg0.CurrentTargetID,
543 		ri->pg0.PortIdentifier,
544 		(unsigned long long)pn,
545 		(unsigned long long)nn));
546 	}
547 #endif
548 
549 	return 0;
550 }
551 
552 static int
553 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
554 {
555 	struct mptfc_rport_info	*ri;
556 	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
557 	int		err;
558 
559 	err = fc_remote_port_chkready(rport);
560 	if (unlikely(err)) {
561 		SCpnt->result = err;
562 		done(SCpnt);
563 		return 0;
564 	}
565 
566 	/* dd_data is null until finished adding target */
567 	ri = *((struct mptfc_rport_info **)rport->dd_data);
568 	if (unlikely(!ri)) {
569 		dfcprintk ((MYIOC_s_INFO_FMT
570 			"mptfc_qcmd.%d: %d:%d, dd_data is null.\n",
571 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
572 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
573 			SCpnt->device->id,SCpnt->device->lun));
574 		SCpnt->result = DID_IMM_RETRY << 16;
575 		done(SCpnt);
576 		return 0;
577 	}
578 
579 	err = mptscsih_qcmd(SCpnt,done);
580 #ifdef DMPT_DEBUG_FC
581 	if (unlikely(err)) {
582 		dfcprintk ((MYIOC_s_INFO_FMT
583 			"mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero, (%x).\n",
584 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
585 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
586 			SCpnt->device->id,SCpnt->device->lun,err));
587 	}
588 #endif
589 	return err;
590 }
591 
592 /*
593  *	mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
594  *	@ioc: Pointer to MPT_ADAPTER structure
595  *	@portnum: IOC Port number
596  *
597  *	Return: 0 for success
598  *	-ENOMEM if no memory available
599  *		-EPERM if not allowed due to ISR context
600  *		-EAGAIN if no msg frames currently available
601  *		-EFAULT for non-successful reply or no reply (timeout)
602  *		-EINVAL portnum arg out of range (hardwired to two elements)
603  */
604 static int
605 mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
606 {
607 	ConfigPageHeader_t	 hdr;
608 	CONFIGPARMS		 cfg;
609 	FCPortPage0_t		*ppage0_alloc;
610 	FCPortPage0_t		*pp0dest;
611 	dma_addr_t		 page0_dma;
612 	int			 data_sz;
613 	int			 copy_sz;
614 	int			 rc;
615 	int			 count = 400;
616 
617 	if (portnum > 1)
618 		return -EINVAL;
619 
620 	/* Get FCPort Page 0 header */
621 	hdr.PageVersion = 0;
622 	hdr.PageLength = 0;
623 	hdr.PageNumber = 0;
624 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
625 	cfg.cfghdr.hdr = &hdr;
626 	cfg.physAddr = -1;
627 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
628 	cfg.dir = 0;
629 	cfg.pageAddr = portnum;
630 	cfg.timeout = 0;
631 
632 	if ((rc = mpt_config(ioc, &cfg)) != 0)
633 		return rc;
634 
635 	if (hdr.PageLength == 0)
636 		return 0;
637 
638 	data_sz = hdr.PageLength * 4;
639 	rc = -ENOMEM;
640 	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
641 	if (ppage0_alloc) {
642 
643  try_again:
644 		memset((u8 *)ppage0_alloc, 0, data_sz);
645 		cfg.physAddr = page0_dma;
646 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
647 
648 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
649 			/* save the data */
650 			pp0dest = &ioc->fc_port_page0[portnum];
651 			copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
652 			memcpy(pp0dest, ppage0_alloc, copy_sz);
653 
654 			/*
655 			 *	Normalize endianness of structure data,
656 			 *	by byte-swapping all > 1 byte fields!
657 			 */
658 			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
659 			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
660 			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
661 			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
662 			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
663 			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
664 			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
665 			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
666 			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
667 			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
668 			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
669 			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
670 			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
671 			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
672 			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
673 			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
674 
675 			/*
676 			 * if still doing discovery,
677 			 * hang loose a while until finished
678 			 */
679 			if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
680 				if (count-- > 0) {
681 					msleep(100);
682 					goto try_again;
683 				}
684 				printk(MYIOC_s_INFO_FMT "Firmware discovery not"
685 							" complete.\n",
686 						ioc->name);
687 			}
688 		}
689 
690 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
691 	}
692 
693 	return rc;
694 }
695 
696 static int
697 mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
698 {
699 	ConfigPageHeader_t	 hdr;
700 	CONFIGPARMS		 cfg;
701 	int			 rc;
702 
703 	if (portnum > 1)
704 		return -EINVAL;
705 
706 	if (!(ioc->fc_data.fc_port_page1[portnum].data))
707 		return -EINVAL;
708 
709 	/* get fcport page 1 header */
710 	hdr.PageVersion = 0;
711 	hdr.PageLength = 0;
712 	hdr.PageNumber = 1;
713 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
714 	cfg.cfghdr.hdr = &hdr;
715 	cfg.physAddr = -1;
716 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
717 	cfg.dir = 0;
718 	cfg.pageAddr = portnum;
719 	cfg.timeout = 0;
720 
721 	if ((rc = mpt_config(ioc, &cfg)) != 0)
722 		return rc;
723 
724 	if (hdr.PageLength == 0)
725 		return -ENODEV;
726 
727 	if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
728 		return -EINVAL;
729 
730 	cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
731 	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
732 	cfg.dir = 1;
733 
734 	rc = mpt_config(ioc, &cfg);
735 
736 	return rc;
737 }
738 
739 static int
740 mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
741 {
742 	ConfigPageHeader_t	 hdr;
743 	CONFIGPARMS		 cfg;
744 	FCPortPage1_t		*page1_alloc;
745 	dma_addr_t		 page1_dma;
746 	int			 data_sz;
747 	int			 rc;
748 
749 	if (portnum > 1)
750 		return -EINVAL;
751 
752 	/* get fcport page 1 header */
753 	hdr.PageVersion = 0;
754 	hdr.PageLength = 0;
755 	hdr.PageNumber = 1;
756 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
757 	cfg.cfghdr.hdr = &hdr;
758 	cfg.physAddr = -1;
759 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
760 	cfg.dir = 0;
761 	cfg.pageAddr = portnum;
762 	cfg.timeout = 0;
763 
764 	if ((rc = mpt_config(ioc, &cfg)) != 0)
765 		return rc;
766 
767 	if (hdr.PageLength == 0)
768 		return -ENODEV;
769 
770 start_over:
771 
772 	if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
773 		data_sz = hdr.PageLength * 4;
774 		if (data_sz < sizeof(FCPortPage1_t))
775 			data_sz = sizeof(FCPortPage1_t);
776 
777 		page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
778 						data_sz,
779 						&page1_dma);
780 		if (!page1_alloc)
781 			return -ENOMEM;
782 	}
783 	else {
784 		page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
785 		page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
786 		data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
787 		if (hdr.PageLength * 4 > data_sz) {
788 			ioc->fc_data.fc_port_page1[portnum].data = NULL;
789 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
790 				page1_alloc, page1_dma);
791 			goto start_over;
792 		}
793 	}
794 
795 	memset(page1_alloc,0,data_sz);
796 
797 	cfg.physAddr = page1_dma;
798 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
799 
800 	if ((rc = mpt_config(ioc, &cfg)) == 0) {
801 		ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
802 		ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
803 		ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
804 	}
805 	else {
806 		ioc->fc_data.fc_port_page1[portnum].data = NULL;
807 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
808 			page1_alloc, page1_dma);
809 	}
810 
811 	return rc;
812 }
813 
814 static void
815 mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
816 {
817 	int		ii;
818 	FCPortPage1_t	*pp1;
819 
820 	#define MPTFC_FW_DEVICE_TIMEOUT	(1)
821 	#define MPTFC_FW_IO_PEND_TIMEOUT (1)
822 	#define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
823 	#define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
824 
825 	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
826 		if (mptfc_GetFcPortPage1(ioc, ii) != 0)
827 			continue;
828 		pp1 = ioc->fc_data.fc_port_page1[ii].data;
829 		if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
830 		 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
831 		 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
832 		 && ((pp1->Flags & OFF_FLAGS) == 0))
833 			continue;
834 		pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
835 		pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
836 		pp1->Flags &= ~OFF_FLAGS;
837 		pp1->Flags |= ON_FLAGS;
838 		mptfc_WriteFcPortPage1(ioc, ii);
839 	}
840 }
841 
842 
843 static void
844 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
845 {
846 	unsigned class = 0, cos = 0;
847 
848 	/* don't know what to do as only one scsi (fc) host was allocated */
849 	if (portnum != 0)
850 		return;
851 
852 	class = ioc->fc_port_page0[portnum].SupportedServiceClass;
853 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
854 		cos |= FC_COS_CLASS1;
855 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
856 		cos |= FC_COS_CLASS2;
857 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
858 		cos |= FC_COS_CLASS3;
859 
860 	fc_host_node_name(ioc->sh) =
861 	    	(u64)ioc->fc_port_page0[portnum].WWNN.High << 32
862 		    | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
863 
864 	fc_host_port_name(ioc->sh) =
865 	    	(u64)ioc->fc_port_page0[portnum].WWPN.High << 32
866 		    | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
867 
868 	fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
869 
870 	fc_host_supported_classes(ioc->sh) = cos;
871 
872 	fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
873 }
874 
875 static void
876 mptfc_setup_reset(void *arg)
877 {
878 	MPT_ADAPTER		*ioc = (MPT_ADAPTER *)arg;
879 	u64			pn;
880 	struct mptfc_rport_info *ri;
881 
882 	/* reset about to happen, delete (block) all rports */
883 	list_for_each_entry(ri, &ioc->fc_rports, list) {
884 		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
885 			ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
886 			fc_remote_port_delete(ri->rport);	/* won't sleep */
887 			ri->rport = NULL;
888 
889 			pn = (u64)ri->pg0.WWPN.High << 32 |
890 			     (u64)ri->pg0.WWPN.Low;
891 			dfcprintk ((MYIOC_s_INFO_FMT
892 				"mptfc_setup_reset.%d: %llx deleted\n",
893 				ioc->name,
894 				ioc->sh->host_no,
895 				(unsigned long long)pn));
896 		}
897 	}
898 }
899 
900 static void
901 mptfc_rescan_devices(void *arg)
902 {
903 	MPT_ADAPTER		*ioc = (MPT_ADAPTER *)arg;
904 	int			ii;
905 	int			work_to_do;
906 	u64			pn;
907 	unsigned long		flags;
908 	struct mptfc_rport_info *ri;
909 
910 	do {
911 		/* start by tagging all ports as missing */
912 		list_for_each_entry(ri, &ioc->fc_rports, list) {
913 			if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
914 				ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
915 			}
916 		}
917 
918 		/*
919 		 * now rescan devices known to adapter,
920 		 * will reregister existing rports
921 		 */
922 		for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
923 			(void) mptfc_GetFcPortPage0(ioc, ii);
924 			mptfc_init_host_attr(ioc,ii);	/* refresh */
925 			mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
926 		}
927 
928 		/* delete devices still missing */
929 		list_for_each_entry(ri, &ioc->fc_rports, list) {
930 			/* if newly missing, delete it */
931 			if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
932 
933 				ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
934 					       MPT_RPORT_INFO_FLAGS_MISSING);
935 				fc_remote_port_delete(ri->rport);	/* won't sleep */
936 				ri->rport = NULL;
937 
938 				pn = (u64)ri->pg0.WWPN.High << 32 |
939 				     (u64)ri->pg0.WWPN.Low;
940 				dfcprintk ((MYIOC_s_INFO_FMT
941 					"mptfc_rescan.%d: %llx deleted\n",
942 					ioc->name,
943 					ioc->sh->host_no,
944 					(unsigned long long)pn));
945 			}
946 		}
947 
948 		/*
949 		 * allow multiple passes as target state
950 		 * might have changed during scan
951 		 */
952 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
953 		if (ioc->fc_rescan_work_count > 2) 	/* only need one more */
954 			ioc->fc_rescan_work_count = 2;
955 		work_to_do = --ioc->fc_rescan_work_count;
956 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
957 	} while (work_to_do);
958 }
959 
960 static int
961 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
962 {
963 	struct Scsi_Host	*sh;
964 	MPT_SCSI_HOST		*hd;
965 	MPT_ADAPTER 		*ioc;
966 	unsigned long		 flags;
967 	int			 ii;
968 	int			 numSGE = 0;
969 	int			 scale;
970 	int			 ioc_cap;
971 	int			error=0;
972 	int			r;
973 
974 	if ((r = mpt_attach(pdev,id)) != 0)
975 		return r;
976 
977 	ioc = pci_get_drvdata(pdev);
978 	ioc->DoneCtx = mptfcDoneCtx;
979 	ioc->TaskCtx = mptfcTaskCtx;
980 	ioc->InternalCtx = mptfcInternalCtx;
981 
982 	/*  Added sanity check on readiness of the MPT adapter.
983 	 */
984 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
985 		printk(MYIOC_s_WARN_FMT
986 		  "Skipping because it's not operational!\n",
987 		  ioc->name);
988 		error = -ENODEV;
989 		goto out_mptfc_probe;
990 	}
991 
992 	if (!ioc->active) {
993 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
994 		  ioc->name);
995 		error = -ENODEV;
996 		goto out_mptfc_probe;
997 	}
998 
999 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
1000 	 */
1001 	ioc_cap = 0;
1002 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1003 		if (ioc->pfacts[ii].ProtocolFlags &
1004 		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
1005 			ioc_cap ++;
1006 	}
1007 
1008 	if (!ioc_cap) {
1009 		printk(MYIOC_s_WARN_FMT
1010 			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1011 			ioc->name, ioc);
1012 		return -ENODEV;
1013 	}
1014 
1015 	sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1016 
1017 	if (!sh) {
1018 		printk(MYIOC_s_WARN_FMT
1019 			"Unable to register controller with SCSI subsystem\n",
1020 			ioc->name);
1021 		error = -1;
1022 		goto out_mptfc_probe;
1023         }
1024 
1025 	spin_lock_init(&ioc->fc_rescan_work_lock);
1026 	INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
1027 	INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset, (void *)ioc);
1028 
1029 	spin_lock_irqsave(&ioc->FreeQlock, flags);
1030 
1031 	/* Attach the SCSI Host to the IOC structure
1032 	 */
1033 	ioc->sh = sh;
1034 
1035 	sh->io_port = 0;
1036 	sh->n_io_port = 0;
1037 	sh->irq = 0;
1038 
1039 	/* set 16 byte cdb's */
1040 	sh->max_cmd_len = 16;
1041 
1042 	sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1043 
1044 	sh->max_lun = MPT_LAST_LUN + 1;
1045 	sh->max_channel = 0;
1046 	sh->this_id = ioc->pfacts[0].PortSCSIID;
1047 
1048 	/* Required entry.
1049 	 */
1050 	sh->unique_id = ioc->id;
1051 
1052 	/* Verify that we won't exceed the maximum
1053 	 * number of chain buffers
1054 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
1055 	 * For 32bit SGE's:
1056 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1057 	 *               + (req_sz - 64)/sizeof(SGE)
1058 	 * A slightly different algorithm is required for
1059 	 * 64bit SGEs.
1060 	 */
1061 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1062 	if (sizeof(dma_addr_t) == sizeof(u64)) {
1063 		numSGE = (scale - 1) *
1064 		  (ioc->facts.MaxChainDepth-1) + scale +
1065 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1066 		  sizeof(u32));
1067 	} else {
1068 		numSGE = 1 + (scale - 1) *
1069 		  (ioc->facts.MaxChainDepth-1) + scale +
1070 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1071 		  sizeof(u32));
1072 	}
1073 
1074 	if (numSGE < sh->sg_tablesize) {
1075 		/* Reset this value */
1076 		dprintk((MYIOC_s_INFO_FMT
1077 		  "Resetting sg_tablesize to %d from %d\n",
1078 		  ioc->name, numSGE, sh->sg_tablesize));
1079 		sh->sg_tablesize = numSGE;
1080 	}
1081 
1082 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1083 
1084 	hd = (MPT_SCSI_HOST *) sh->hostdata;
1085 	hd->ioc = ioc;
1086 
1087 	/* SCSI needs scsi_cmnd lookup table!
1088 	 * (with size equal to req_depth*PtrSz!)
1089 	 */
1090 	hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1091 	if (!hd->ScsiLookup) {
1092 		error = -ENOMEM;
1093 		goto out_mptfc_probe;
1094 	}
1095 
1096 	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1097 		 ioc->name, hd->ScsiLookup));
1098 
1099 	/* Allocate memory for the device structures.
1100 	 * A non-Null pointer at an offset
1101 	 * indicates a device exists.
1102 	 * max_id = 1 + maximum id (hosts.h)
1103 	 */
1104 	hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
1105 	if (!hd->Targets) {
1106 		error = -ENOMEM;
1107 		goto out_mptfc_probe;
1108 	}
1109 
1110 	dprintk((KERN_INFO "  vdev @ %p\n", hd->Targets));
1111 
1112 	/* Clear the TM flags
1113 	 */
1114 	hd->tmPending = 0;
1115 	hd->tmState = TM_STATE_NONE;
1116 	hd->resetPending = 0;
1117 	hd->abortSCpnt = NULL;
1118 
1119 	/* Clear the pointer used to store
1120 	 * single-threaded commands, i.e., those
1121 	 * issued during a bus scan, dv and
1122 	 * configuration pages.
1123 	 */
1124 	hd->cmdPtr = NULL;
1125 
1126 	/* Initialize this SCSI Hosts' timers
1127 	 * To use, set the timer expires field
1128 	 * and add_timer
1129 	 */
1130 	init_timer(&hd->timer);
1131 	hd->timer.data = (unsigned long) hd;
1132 	hd->timer.function = mptscsih_timer_expired;
1133 
1134 	hd->mpt_pq_filter = mpt_pq_filter;
1135 
1136 	ddvprintk((MYIOC_s_INFO_FMT
1137 		"mpt_pq_filter %x\n",
1138 		ioc->name,
1139 		mpt_pq_filter));
1140 
1141 	init_waitqueue_head(&hd->scandv_waitq);
1142 	hd->scandv_wait_done = 0;
1143 	hd->last_queue_full = 0;
1144 
1145 	sh->transportt = mptfc_transport_template;
1146 	error = scsi_add_host (sh, &ioc->pcidev->dev);
1147 	if(error) {
1148 		dprintk((KERN_ERR MYNAM
1149 		  "scsi_add_host failed\n"));
1150 		goto out_mptfc_probe;
1151 	}
1152 
1153 	/* initialize workqueue */
1154 
1155 	snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
1156 		sh->host_no);
1157 	ioc->fc_rescan_work_q =
1158 		create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
1159 	if (!ioc->fc_rescan_work_q)
1160 		goto out_mptfc_probe;
1161 
1162 	/*
1163 	 *  Pre-fetch FC port WWN and stuff...
1164 	 *  (FCPortPage0_t stuff)
1165 	 */
1166 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1167 		(void) mptfc_GetFcPortPage0(ioc, ii);
1168 	}
1169 	mptfc_SetFcPortPage1_defaults(ioc);
1170 
1171 	/*
1172 	 * scan for rports -
1173 	 *	by doing it via the workqueue, some locking is eliminated
1174 	 */
1175 
1176 	ioc->fc_rescan_work_count = 1;
1177 	queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1178 	flush_workqueue(ioc->fc_rescan_work_q);
1179 
1180 	return 0;
1181 
1182 out_mptfc_probe:
1183 
1184 	mptscsih_remove(pdev);
1185 	return error;
1186 }
1187 
1188 static struct pci_driver mptfc_driver = {
1189 	.name		= "mptfc",
1190 	.id_table	= mptfc_pci_table,
1191 	.probe		= mptfc_probe,
1192 	.remove		= __devexit_p(mptfc_remove),
1193 	.shutdown	= mptscsih_shutdown,
1194 #ifdef CONFIG_PM
1195 	.suspend	= mptscsih_suspend,
1196 	.resume		= mptscsih_resume,
1197 #endif
1198 };
1199 
1200 static int
1201 mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1202 {
1203 	MPT_SCSI_HOST *hd;
1204 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1205 	unsigned long flags;
1206 	int rc=1;
1207 
1208 	devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1209 			ioc->name, event));
1210 
1211 	if (ioc->sh == NULL ||
1212 		((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
1213 		return 1;
1214 
1215 	switch (event) {
1216 	case MPI_EVENT_RESCAN:
1217 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1218 		if (ioc->fc_rescan_work_q) {
1219 			if (ioc->fc_rescan_work_count++ == 0) {
1220 				queue_work(ioc->fc_rescan_work_q,
1221 					   &ioc->fc_rescan_work);
1222 			}
1223 		}
1224 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1225 		break;
1226 	default:
1227 		rc = mptscsih_event_process(ioc,pEvReply);
1228 		break;
1229 	}
1230 	return rc;
1231 }
1232 
1233 static int
1234 mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1235 {
1236 	int		rc;
1237 	unsigned long	flags;
1238 
1239 	rc = mptscsih_ioc_reset(ioc,reset_phase);
1240 	if (rc == 0)
1241 		return rc;
1242 
1243 
1244 	dtmprintk((KERN_WARNING MYNAM
1245 		": IOC %s_reset routed to FC host driver!\n",
1246 		reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1247 		reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1248 
1249 	if (reset_phase == MPT_IOC_SETUP_RESET) {
1250 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1251 		if (ioc->fc_rescan_work_q) {
1252 			queue_work(ioc->fc_rescan_work_q,
1253 				   &ioc->fc_setup_reset_work);
1254 		}
1255 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1256 	}
1257 
1258 	else if (reset_phase == MPT_IOC_PRE_RESET) {
1259 	}
1260 
1261 	else {	/* MPT_IOC_POST_RESET */
1262 		mptfc_SetFcPortPage1_defaults(ioc);
1263 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1264 		if (ioc->fc_rescan_work_q) {
1265 			if (ioc->fc_rescan_work_count++ == 0) {
1266 				queue_work(ioc->fc_rescan_work_q,
1267 					   &ioc->fc_rescan_work);
1268 			}
1269 		}
1270 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1271 	}
1272 	return 1;
1273 }
1274 
1275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1276 /**
1277  *	mptfc_init - Register MPT adapter(s) as SCSI host(s) with
1278  *	linux scsi mid-layer.
1279  *
1280  *	Returns 0 for success, non-zero for failure.
1281  */
1282 static int __init
1283 mptfc_init(void)
1284 {
1285 	int error;
1286 
1287 	show_mptmod_ver(my_NAME, my_VERSION);
1288 
1289 	/* sanity check module parameters */
1290 	if (mptfc_dev_loss_tmo <= 0)
1291 		mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1292 
1293 	mptfc_transport_template =
1294 		fc_attach_transport(&mptfc_transport_functions);
1295 
1296 	if (!mptfc_transport_template)
1297 		return -ENODEV;
1298 
1299 	mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
1300 	mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
1301 	mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
1302 
1303 	if (mpt_event_register(mptfcDoneCtx, mptfc_event_process) == 0) {
1304 		devtverboseprintk((KERN_INFO MYNAM
1305 		  ": Registered for IOC event notifications\n"));
1306 	}
1307 
1308 	if (mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset) == 0) {
1309 		dprintk((KERN_INFO MYNAM
1310 		  ": Registered for IOC reset notifications\n"));
1311 	}
1312 
1313 	error = pci_register_driver(&mptfc_driver);
1314 	if (error)
1315 		fc_release_transport(mptfc_transport_template);
1316 
1317 	return error;
1318 }
1319 
1320 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1321 /**
1322  *	mptfc_remove - Removed fc infrastructure for devices
1323  *	@pdev: Pointer to pci_dev structure
1324  *
1325  */
1326 static void __devexit
1327 mptfc_remove(struct pci_dev *pdev)
1328 {
1329 	MPT_ADAPTER		*ioc = pci_get_drvdata(pdev);
1330 	struct mptfc_rport_info	*p, *n;
1331 	struct workqueue_struct *work_q;
1332 	unsigned long		flags;
1333 	int			ii;
1334 
1335 	/* destroy workqueue */
1336 	if ((work_q=ioc->fc_rescan_work_q)) {
1337 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1338 		ioc->fc_rescan_work_q = NULL;
1339 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1340 		destroy_workqueue(work_q);
1341 	}
1342 
1343 	fc_remove_host(ioc->sh);
1344 
1345 	list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1346 		list_del(&p->list);
1347 		kfree(p);
1348 	}
1349 
1350 	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1351 		if (ioc->fc_data.fc_port_page1[ii].data) {
1352 			pci_free_consistent(ioc->pcidev,
1353 				ioc->fc_data.fc_port_page1[ii].pg_sz,
1354 				(u8 *) ioc->fc_data.fc_port_page1[ii].data,
1355 				ioc->fc_data.fc_port_page1[ii].dma);
1356 			ioc->fc_data.fc_port_page1[ii].data = NULL;
1357 		}
1358 	}
1359 
1360 	mptscsih_remove(pdev);
1361 }
1362 
1363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1364 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1365 /**
1366  *	mptfc_exit - Unregisters MPT adapter(s)
1367  *
1368  */
1369 static void __exit
1370 mptfc_exit(void)
1371 {
1372 	pci_unregister_driver(&mptfc_driver);
1373 	fc_release_transport(mptfc_transport_template);
1374 
1375 	mpt_reset_deregister(mptfcDoneCtx);
1376 	dprintk((KERN_INFO MYNAM
1377 	  ": Deregistered for IOC reset notifications\n"));
1378 
1379 	mpt_event_deregister(mptfcDoneCtx);
1380 	dprintk((KERN_INFO MYNAM
1381 	  ": Deregistered for IOC event notifications\n"));
1382 
1383 	mpt_deregister(mptfcInternalCtx);
1384 	mpt_deregister(mptfcTaskCtx);
1385 	mpt_deregister(mptfcDoneCtx);
1386 }
1387 
1388 module_init(mptfc_init);
1389 module_exit(mptfc_exit);
1390