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