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