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