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