xref: /linux/drivers/message/fusion/mptfc.c (revision c537b994505099b7197e7d3125b942ecbcc51eb6)
1 /*
2  *  linux/drivers/message/fusion/mptfc.c
3  *      For use with LSI Logic PCI chip/adapter(s)
4  *      running LSI Logic Fusion MPT (Message Passing Technology) firmware.
5  *
6  *  Copyright (c) 1999-2007 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@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_compat.h"	/* linux-2.6 tweaks */
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h>	/* for mdelay */
54 #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
55 #include <linux/reboot.h>	/* notifier code */
56 #include <linux/workqueue.h>
57 #include <linux/sort.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 int	mptfcDoneCtx = -1;
95 static int	mptfcTaskCtx = -1;
96 static int	mptfcInternalCtx = -1; /* Used only for internal commands */
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_cmnd *SCpnt,
101 		      void (*done)(struct scsi_cmnd *));
102 static void mptfc_target_destroy(struct scsi_target *starget);
103 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
104 static void __devexit mptfc_remove(struct pci_dev *pdev);
105 static int mptfc_abort(struct scsi_cmnd *SCpnt);
106 static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
107 static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
108 static int mptfc_host_reset(struct scsi_cmnd *SCpnt);
109 
110 static struct scsi_host_template mptfc_driver_template = {
111 	.module				= THIS_MODULE,
112 	.proc_name			= "mptfc",
113 	.proc_info			= mptscsih_proc_info,
114 	.name				= "MPT FC Host",
115 	.info				= mptscsih_info,
116 	.queuecommand			= mptfc_qcmd,
117 	.target_alloc			= mptfc_target_alloc,
118 	.slave_alloc			= mptfc_slave_alloc,
119 	.slave_configure		= mptscsih_slave_configure,
120 	.target_destroy			= mptfc_target_destroy,
121 	.slave_destroy			= mptscsih_slave_destroy,
122 	.change_queue_depth 		= mptscsih_change_queue_depth,
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 };
135 
136 /****************************************************************************
137  * Supported hardware
138  */
139 
140 static struct pci_device_id mptfc_pci_table[] = {
141 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC909,
142 		PCI_ANY_ID, PCI_ANY_ID },
143 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919,
144 		PCI_ANY_ID, PCI_ANY_ID },
145 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929,
146 		PCI_ANY_ID, PCI_ANY_ID },
147 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC919X,
148 		PCI_ANY_ID, PCI_ANY_ID },
149 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC929X,
150 		PCI_ANY_ID, PCI_ANY_ID },
151 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC939X,
152 		PCI_ANY_ID, PCI_ANY_ID },
153 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949X,
154 		PCI_ANY_ID, PCI_ANY_ID },
155 	{ PCI_VENDOR_ID_LSI_LOGIC, MPI_MANUFACTPAGE_DEVICEID_FC949E,
156 		PCI_ANY_ID, PCI_ANY_ID },
157 	{0}	/* Terminating entry */
158 };
159 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
160 
161 static struct scsi_transport_template *mptfc_transport_template = NULL;
162 
163 static struct fc_function_template mptfc_transport_functions = {
164 	.dd_fcrport_size = 8,
165 	.show_host_node_name = 1,
166 	.show_host_port_name = 1,
167 	.show_host_supported_classes = 1,
168 	.show_host_port_id = 1,
169 	.show_rport_supported_classes = 1,
170 	.show_starget_node_name = 1,
171 	.show_starget_port_name = 1,
172 	.show_starget_port_id = 1,
173 	.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
174 	.show_rport_dev_loss_tmo = 1,
175 	.show_host_supported_speeds = 1,
176 	.show_host_maxframe_size = 1,
177 	.show_host_speed = 1,
178 	.show_host_fabric_name = 1,
179 	.show_host_port_type = 1,
180 	.show_host_port_state = 1,
181 	.show_host_symbolic_name = 1,
182 };
183 
184 static int
185 mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
186 			  int (*func)(struct scsi_cmnd *SCpnt),
187 			  const char *caller)
188 {
189 	struct scsi_device	*sdev = SCpnt->device;
190 	struct Scsi_Host	*shost = sdev->host;
191 	struct fc_rport		*rport = starget_to_rport(scsi_target(sdev));
192 	unsigned long		flags;
193 	int			ready;
194 
195 	spin_lock_irqsave(shost->host_lock, flags);
196 	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY) {
197 		spin_unlock_irqrestore(shost->host_lock, flags);
198 		dfcprintk ((MYIOC_s_INFO_FMT
199 			"mptfc_block_error_handler.%d: %d:%d, port status is "
200 			"DID_IMM_RETRY, deferring %s recovery.\n",
201 			((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
202 			((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
203 			SCpnt->device->id,SCpnt->device->lun,caller));
204 		msleep(1000);
205 		spin_lock_irqsave(shost->host_lock, flags);
206 	}
207 	spin_unlock_irqrestore(shost->host_lock, flags);
208 
209 	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata) {
210 		dfcprintk ((MYIOC_s_INFO_FMT
211 			"%s.%d: %d:%d, failing recovery, "
212 			"port state %d, vdev %p.\n", caller,
213 			((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
214 			((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
215 			SCpnt->device->id,SCpnt->device->lun,ready,
216 			SCpnt->device->hostdata));
217 		return FAILED;
218 	}
219 	dfcprintk ((MYIOC_s_INFO_FMT
220 		"%s.%d: %d:%d, executing recovery.\n", caller,
221 		((MPT_SCSI_HOST *) shost->hostdata)->ioc->name,
222 		((MPT_SCSI_HOST *) shost->hostdata)->ioc->sh->host_no,
223 		SCpnt->device->id,SCpnt->device->lun));
224 	return (*func)(SCpnt);
225 }
226 
227 static int
228 mptfc_abort(struct scsi_cmnd *SCpnt)
229 {
230 	return
231 	    mptfc_block_error_handler(SCpnt, mptscsih_abort, __FUNCTION__);
232 }
233 
234 static int
235 mptfc_dev_reset(struct scsi_cmnd *SCpnt)
236 {
237 	return
238 	    mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __FUNCTION__);
239 }
240 
241 static int
242 mptfc_bus_reset(struct scsi_cmnd *SCpnt)
243 {
244 	return
245 	    mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __FUNCTION__);
246 }
247 
248 static int
249 mptfc_host_reset(struct scsi_cmnd *SCpnt)
250 {
251 	return
252 	    mptfc_block_error_handler(SCpnt, mptscsih_host_reset, __FUNCTION__);
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 vdev 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 				}
477 			}
478 			*((struct mptfc_rport_info **)rport->dd_data) = ri;
479 			/* scan will be scheduled once rport becomes a target */
480 			fc_remote_port_rolechg(rport,roles);
481 
482 			pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
483 			nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
484 			dfcprintk ((MYIOC_s_INFO_FMT
485 				"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
486 				"rport tid %d, tmo %d\n",
487 					ioc->name,
488 					ioc->sh->host_no,
489 					pg0->PortIdentifier,
490 					(unsigned long long)nn,
491 					(unsigned long long)pn,
492 					pg0->CurrentTargetID,
493 					ri->rport->scsi_target_id,
494 					ri->rport->dev_loss_tmo));
495 		} else {
496 			list_del(&ri->list);
497 			kfree(ri);
498 			ri = NULL;
499 		}
500 	}
501 }
502 
503 /*
504  *	OS entry point to allow for host driver to free allocated memory
505  *	Called if no device present or device being unloaded
506  */
507 static void
508 mptfc_target_destroy(struct scsi_target *starget)
509 {
510 	struct fc_rport		*rport;
511 	struct mptfc_rport_info *ri;
512 
513 	rport = starget_to_rport(starget);
514 	if (rport) {
515 		ri = *((struct mptfc_rport_info **)rport->dd_data);
516 		if (ri)	/* better be! */
517 			ri->starget = NULL;
518 	}
519 	if (starget->hostdata)
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 /*
562  *	OS entry point to allow host driver to alloc memory
563  *	for each scsi device. Called once per device the bus scan.
564  *	Return non-zero if allocation fails.
565  *	Init memory once per LUN.
566  */
567 static int
568 mptfc_slave_alloc(struct scsi_device *sdev)
569 {
570 	MPT_SCSI_HOST		*hd;
571 	VirtTarget		*vtarget;
572 	VirtDevice		*vdev;
573 	struct scsi_target	*starget;
574 	struct fc_rport		*rport;
575 
576 
577 	starget = scsi_target(sdev);
578 	rport = starget_to_rport(starget);
579 
580 	if (!rport || fc_remote_port_chkready(rport))
581 		return -ENXIO;
582 
583 	hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
584 
585 	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
586 	if (!vdev) {
587 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
588 				hd->ioc->name, sizeof(VirtDevice));
589 		return -ENOMEM;
590 	}
591 
592 
593 	sdev->hostdata = vdev;
594 	vtarget = starget->hostdata;
595 
596 	if (vtarget->num_luns == 0) {
597 		vtarget->ioc_id = hd->ioc->id;
598 		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
599 	}
600 
601 	vdev->vtarget = vtarget;
602 	vdev->lun = sdev->lun;
603 
604 	vtarget->num_luns++;
605 
606 
607 #ifdef DMPT_DEBUG_FC
608 	{
609 	u64 nn, pn;
610 	struct mptfc_rport_info *ri;
611 	ri = *((struct mptfc_rport_info **)rport->dd_data);
612 	pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
613 	nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
614 	dfcprintk ((MYIOC_s_INFO_FMT
615 		"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
616 	        "CurrentTargetID %d, %x %llx %llx\n",
617 		hd->ioc->name,
618 		sdev->host->host_no,
619 		vtarget->num_luns,
620 		sdev->id, ri->pg0.CurrentTargetID,
621 		ri->pg0.PortIdentifier,
622 		(unsigned long long)pn,
623 		(unsigned long long)nn));
624 	}
625 #endif
626 
627 	return 0;
628 }
629 
630 static int
631 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
632 {
633 	struct mptfc_rport_info	*ri;
634 	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
635 	int		err;
636 	VirtDevice	*vdev = SCpnt->device->hostdata;
637 
638 	if (!vdev || !vdev->vtarget) {
639 		SCpnt->result = DID_NO_CONNECT << 16;
640 		done(SCpnt);
641 		return 0;
642 	}
643 
644 	err = fc_remote_port_chkready(rport);
645 	if (unlikely(err)) {
646 		SCpnt->result = err;
647 		done(SCpnt);
648 		return 0;
649 	}
650 
651 	/* dd_data is null until finished adding target */
652 	ri = *((struct mptfc_rport_info **)rport->dd_data);
653 	if (unlikely(!ri)) {
654 		dfcprintk ((MYIOC_s_INFO_FMT
655 			"mptfc_qcmd.%d: %d:%d, dd_data is null.\n",
656 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
657 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
658 			SCpnt->device->id,SCpnt->device->lun));
659 		SCpnt->result = DID_IMM_RETRY << 16;
660 		done(SCpnt);
661 		return 0;
662 	}
663 
664 	err = mptscsih_qcmd(SCpnt,done);
665 #ifdef DMPT_DEBUG_FC
666 	if (unlikely(err)) {
667 		dfcprintk ((MYIOC_s_INFO_FMT
668 			"mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero, (%x).\n",
669 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
670 			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
671 			SCpnt->device->id,SCpnt->device->lun,err));
672 	}
673 #endif
674 	return err;
675 }
676 
677 /*
678  *	mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
679  *	@ioc: Pointer to MPT_ADAPTER structure
680  *	@portnum: IOC Port number
681  *
682  *	Return: 0 for success
683  *	-ENOMEM if no memory available
684  *		-EPERM if not allowed due to ISR context
685  *		-EAGAIN if no msg frames currently available
686  *		-EFAULT for non-successful reply or no reply (timeout)
687  *		-EINVAL portnum arg out of range (hardwired to two elements)
688  */
689 static int
690 mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
691 {
692 	ConfigPageHeader_t	 hdr;
693 	CONFIGPARMS		 cfg;
694 	FCPortPage0_t		*ppage0_alloc;
695 	FCPortPage0_t		*pp0dest;
696 	dma_addr_t		 page0_dma;
697 	int			 data_sz;
698 	int			 copy_sz;
699 	int			 rc;
700 	int			 count = 400;
701 
702 	if (portnum > 1)
703 		return -EINVAL;
704 
705 	/* Get FCPort Page 0 header */
706 	hdr.PageVersion = 0;
707 	hdr.PageLength = 0;
708 	hdr.PageNumber = 0;
709 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
710 	cfg.cfghdr.hdr = &hdr;
711 	cfg.physAddr = -1;
712 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
713 	cfg.dir = 0;
714 	cfg.pageAddr = portnum;
715 	cfg.timeout = 0;
716 
717 	if ((rc = mpt_config(ioc, &cfg)) != 0)
718 		return rc;
719 
720 	if (hdr.PageLength == 0)
721 		return 0;
722 
723 	data_sz = hdr.PageLength * 4;
724 	rc = -ENOMEM;
725 	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
726 	if (ppage0_alloc) {
727 
728  try_again:
729 		memset((u8 *)ppage0_alloc, 0, data_sz);
730 		cfg.physAddr = page0_dma;
731 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
732 
733 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
734 			/* save the data */
735 			pp0dest = &ioc->fc_port_page0[portnum];
736 			copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
737 			memcpy(pp0dest, ppage0_alloc, copy_sz);
738 
739 			/*
740 			 *	Normalize endianness of structure data,
741 			 *	by byte-swapping all > 1 byte fields!
742 			 */
743 			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
744 			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
745 			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
746 			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
747 			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
748 			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
749 			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
750 			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
751 			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
752 			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
753 			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
754 			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
755 			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
756 			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
757 			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
758 			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
759 
760 			/*
761 			 * if still doing discovery,
762 			 * hang loose a while until finished
763 			 */
764 			if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
765 			    (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
766 			     (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
767 			      == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
768 				if (count-- > 0) {
769 					msleep(100);
770 					goto try_again;
771 				}
772 				printk(MYIOC_s_INFO_FMT "Firmware discovery not"
773 							" complete.\n",
774 						ioc->name);
775 			}
776 		}
777 
778 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
779 	}
780 
781 	return rc;
782 }
783 
784 static int
785 mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
786 {
787 	ConfigPageHeader_t	 hdr;
788 	CONFIGPARMS		 cfg;
789 	int			 rc;
790 
791 	if (portnum > 1)
792 		return -EINVAL;
793 
794 	if (!(ioc->fc_data.fc_port_page1[portnum].data))
795 		return -EINVAL;
796 
797 	/* get fcport page 1 header */
798 	hdr.PageVersion = 0;
799 	hdr.PageLength = 0;
800 	hdr.PageNumber = 1;
801 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
802 	cfg.cfghdr.hdr = &hdr;
803 	cfg.physAddr = -1;
804 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
805 	cfg.dir = 0;
806 	cfg.pageAddr = portnum;
807 	cfg.timeout = 0;
808 
809 	if ((rc = mpt_config(ioc, &cfg)) != 0)
810 		return rc;
811 
812 	if (hdr.PageLength == 0)
813 		return -ENODEV;
814 
815 	if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
816 		return -EINVAL;
817 
818 	cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
819 	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
820 	cfg.dir = 1;
821 
822 	rc = mpt_config(ioc, &cfg);
823 
824 	return rc;
825 }
826 
827 static int
828 mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
829 {
830 	ConfigPageHeader_t	 hdr;
831 	CONFIGPARMS		 cfg;
832 	FCPortPage1_t		*page1_alloc;
833 	dma_addr_t		 page1_dma;
834 	int			 data_sz;
835 	int			 rc;
836 
837 	if (portnum > 1)
838 		return -EINVAL;
839 
840 	/* get fcport page 1 header */
841 	hdr.PageVersion = 0;
842 	hdr.PageLength = 0;
843 	hdr.PageNumber = 1;
844 	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
845 	cfg.cfghdr.hdr = &hdr;
846 	cfg.physAddr = -1;
847 	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
848 	cfg.dir = 0;
849 	cfg.pageAddr = portnum;
850 	cfg.timeout = 0;
851 
852 	if ((rc = mpt_config(ioc, &cfg)) != 0)
853 		return rc;
854 
855 	if (hdr.PageLength == 0)
856 		return -ENODEV;
857 
858 start_over:
859 
860 	if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
861 		data_sz = hdr.PageLength * 4;
862 		if (data_sz < sizeof(FCPortPage1_t))
863 			data_sz = sizeof(FCPortPage1_t);
864 
865 		page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
866 						data_sz,
867 						&page1_dma);
868 		if (!page1_alloc)
869 			return -ENOMEM;
870 	}
871 	else {
872 		page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
873 		page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
874 		data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
875 		if (hdr.PageLength * 4 > data_sz) {
876 			ioc->fc_data.fc_port_page1[portnum].data = NULL;
877 			pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
878 				page1_alloc, page1_dma);
879 			goto start_over;
880 		}
881 	}
882 
883 	memset(page1_alloc,0,data_sz);
884 
885 	cfg.physAddr = page1_dma;
886 	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
887 
888 	if ((rc = mpt_config(ioc, &cfg)) == 0) {
889 		ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
890 		ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
891 		ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
892 	}
893 	else {
894 		ioc->fc_data.fc_port_page1[portnum].data = NULL;
895 		pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
896 			page1_alloc, page1_dma);
897 	}
898 
899 	return rc;
900 }
901 
902 static void
903 mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
904 {
905 	int		ii;
906 	FCPortPage1_t	*pp1;
907 
908 	#define MPTFC_FW_DEVICE_TIMEOUT	(1)
909 	#define MPTFC_FW_IO_PEND_TIMEOUT (1)
910 	#define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
911 	#define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
912 
913 	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
914 		if (mptfc_GetFcPortPage1(ioc, ii) != 0)
915 			continue;
916 		pp1 = ioc->fc_data.fc_port_page1[ii].data;
917 		if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
918 		 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
919 		 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
920 		 && ((pp1->Flags & OFF_FLAGS) == 0))
921 			continue;
922 		pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
923 		pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
924 		pp1->Flags &= ~OFF_FLAGS;
925 		pp1->Flags |= ON_FLAGS;
926 		mptfc_WriteFcPortPage1(ioc, ii);
927 	}
928 }
929 
930 
931 static void
932 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
933 {
934 	unsigned	class = 0;
935 	unsigned	cos = 0;
936 	unsigned	speed;
937 	unsigned	port_type;
938 	unsigned	port_state;
939 	FCPortPage0_t	*pp0;
940 	struct Scsi_Host *sh;
941 	char		*sn;
942 
943 	/* don't know what to do as only one scsi (fc) host was allocated */
944 	if (portnum != 0)
945 		return;
946 
947 	pp0 = &ioc->fc_port_page0[portnum];
948 	sh = ioc->sh;
949 
950 	sn = fc_host_symbolic_name(sh);
951 	snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
952 	    ioc->prod_name,
953 	    MPT_FW_REV_MAGIC_ID_STRING,
954 	    ioc->facts.FWVersion.Word);
955 
956 	fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
957 
958 	fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
959 
960 	fc_host_node_name(sh) =
961 	    	(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
962 
963 	fc_host_port_name(sh) =
964 	    	(u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
965 
966 	fc_host_port_id(sh) = pp0->PortIdentifier;
967 
968 	class = pp0->SupportedServiceClass;
969 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
970 		cos |= FC_COS_CLASS1;
971 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
972 		cos |= FC_COS_CLASS2;
973 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
974 		cos |= FC_COS_CLASS3;
975 	fc_host_supported_classes(sh) = cos;
976 
977 	if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
978 		speed = FC_PORTSPEED_1GBIT;
979 	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
980 		speed = FC_PORTSPEED_2GBIT;
981 	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
982 		speed = FC_PORTSPEED_4GBIT;
983 	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
984 		speed = FC_PORTSPEED_10GBIT;
985 	else
986 		speed = FC_PORTSPEED_UNKNOWN;
987 	fc_host_speed(sh) = speed;
988 
989 	speed = 0;
990 	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
991 		speed |= FC_PORTSPEED_1GBIT;
992 	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
993 		speed |= FC_PORTSPEED_2GBIT;
994 	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
995 		speed |= FC_PORTSPEED_4GBIT;
996 	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
997 		speed |= FC_PORTSPEED_10GBIT;
998 	fc_host_supported_speeds(sh) = speed;
999 
1000 	port_state = FC_PORTSTATE_UNKNOWN;
1001 	if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1002 		port_state = FC_PORTSTATE_ONLINE;
1003 	else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1004 		port_state = FC_PORTSTATE_LINKDOWN;
1005 	fc_host_port_state(sh) = port_state;
1006 
1007 	port_type = FC_PORTTYPE_UNKNOWN;
1008 	if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1009 		port_type = FC_PORTTYPE_PTP;
1010 	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1011 		port_type = FC_PORTTYPE_LPORT;
1012 	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1013 		port_type = FC_PORTTYPE_NLPORT;
1014 	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1015 		port_type = FC_PORTTYPE_NPORT;
1016 	fc_host_port_type(sh) = port_type;
1017 
1018 	fc_host_fabric_name(sh) =
1019 	    (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1020 		(u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1021 		(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1022 
1023 }
1024 
1025 static void
1026 mptfc_setup_reset(struct work_struct *work)
1027 {
1028 	MPT_ADAPTER		*ioc =
1029 		container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1030 	u64			pn;
1031 	struct mptfc_rport_info *ri;
1032 
1033 	/* reset about to happen, delete (block) all rports */
1034 	list_for_each_entry(ri, &ioc->fc_rports, list) {
1035 		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1036 			ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1037 			fc_remote_port_delete(ri->rport);	/* won't sleep */
1038 			ri->rport = NULL;
1039 
1040 			pn = (u64)ri->pg0.WWPN.High << 32 |
1041 			     (u64)ri->pg0.WWPN.Low;
1042 			dfcprintk ((MYIOC_s_INFO_FMT
1043 				"mptfc_setup_reset.%d: %llx deleted\n",
1044 				ioc->name,
1045 				ioc->sh->host_no,
1046 				(unsigned long long)pn));
1047 		}
1048 	}
1049 }
1050 
1051 static void
1052 mptfc_rescan_devices(struct work_struct *work)
1053 {
1054 	MPT_ADAPTER		*ioc =
1055 		container_of(work, MPT_ADAPTER, fc_rescan_work);
1056 	int			ii;
1057 	u64			pn;
1058 	struct mptfc_rport_info *ri;
1059 
1060 	/* start by tagging all ports as missing */
1061 	list_for_each_entry(ri, &ioc->fc_rports, list) {
1062 		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1063 			ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1064 		}
1065 	}
1066 
1067 	/*
1068 	 * now rescan devices known to adapter,
1069 	 * will reregister existing rports
1070 	 */
1071 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1072 		(void) mptfc_GetFcPortPage0(ioc, ii);
1073 		mptfc_init_host_attr(ioc, ii);	/* refresh */
1074 		mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1075 	}
1076 
1077 	/* delete devices still missing */
1078 	list_for_each_entry(ri, &ioc->fc_rports, list) {
1079 		/* if newly missing, delete it */
1080 		if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1081 
1082 			ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1083 				       MPT_RPORT_INFO_FLAGS_MISSING);
1084 			fc_remote_port_delete(ri->rport);	/* won't sleep */
1085 			ri->rport = NULL;
1086 
1087 			pn = (u64)ri->pg0.WWPN.High << 32 |
1088 			     (u64)ri->pg0.WWPN.Low;
1089 			dfcprintk ((MYIOC_s_INFO_FMT
1090 				"mptfc_rescan.%d: %llx deleted\n",
1091 				ioc->name,
1092 				ioc->sh->host_no,
1093 				(unsigned long long)pn));
1094 		}
1095 	}
1096 }
1097 
1098 static int
1099 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1100 {
1101 	struct Scsi_Host	*sh;
1102 	MPT_SCSI_HOST		*hd;
1103 	MPT_ADAPTER 		*ioc;
1104 	unsigned long		 flags;
1105 	int			 ii;
1106 	int			 numSGE = 0;
1107 	int			 scale;
1108 	int			 ioc_cap;
1109 	int			error=0;
1110 	int			r;
1111 
1112 	if ((r = mpt_attach(pdev,id)) != 0)
1113 		return r;
1114 
1115 	ioc = pci_get_drvdata(pdev);
1116 	ioc->DoneCtx = mptfcDoneCtx;
1117 	ioc->TaskCtx = mptfcTaskCtx;
1118 	ioc->InternalCtx = mptfcInternalCtx;
1119 
1120 	/*  Added sanity check on readiness of the MPT adapter.
1121 	 */
1122 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1123 		printk(MYIOC_s_WARN_FMT
1124 		  "Skipping because it's not operational!\n",
1125 		  ioc->name);
1126 		error = -ENODEV;
1127 		goto out_mptfc_probe;
1128 	}
1129 
1130 	if (!ioc->active) {
1131 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1132 		  ioc->name);
1133 		error = -ENODEV;
1134 		goto out_mptfc_probe;
1135 	}
1136 
1137 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
1138 	 */
1139 	ioc_cap = 0;
1140 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1141 		if (ioc->pfacts[ii].ProtocolFlags &
1142 		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
1143 			ioc_cap ++;
1144 	}
1145 
1146 	if (!ioc_cap) {
1147 		printk(MYIOC_s_WARN_FMT
1148 			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1149 			ioc->name, ioc);
1150 		return 0;
1151 	}
1152 
1153 	sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1154 
1155 	if (!sh) {
1156 		printk(MYIOC_s_WARN_FMT
1157 			"Unable to register controller with SCSI subsystem\n",
1158 			ioc->name);
1159 		error = -1;
1160 		goto out_mptfc_probe;
1161         }
1162 
1163 	spin_lock_init(&ioc->fc_rescan_work_lock);
1164 	INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1165 	INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1166 
1167 	spin_lock_irqsave(&ioc->FreeQlock, flags);
1168 
1169 	/* Attach the SCSI Host to the IOC structure
1170 	 */
1171 	ioc->sh = sh;
1172 
1173 	sh->io_port = 0;
1174 	sh->n_io_port = 0;
1175 	sh->irq = 0;
1176 
1177 	/* set 16 byte cdb's */
1178 	sh->max_cmd_len = 16;
1179 
1180 	sh->max_id = ioc->pfacts->MaxDevices;
1181 	sh->max_lun = max_lun;
1182 
1183 	sh->this_id = ioc->pfacts[0].PortSCSIID;
1184 
1185 	/* Required entry.
1186 	 */
1187 	sh->unique_id = ioc->id;
1188 
1189 	/* Verify that we won't exceed the maximum
1190 	 * number of chain buffers
1191 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
1192 	 * For 32bit SGE's:
1193 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1194 	 *               + (req_sz - 64)/sizeof(SGE)
1195 	 * A slightly different algorithm is required for
1196 	 * 64bit SGEs.
1197 	 */
1198 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1199 	if (sizeof(dma_addr_t) == sizeof(u64)) {
1200 		numSGE = (scale - 1) *
1201 		  (ioc->facts.MaxChainDepth-1) + scale +
1202 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1203 		  sizeof(u32));
1204 	} else {
1205 		numSGE = 1 + (scale - 1) *
1206 		  (ioc->facts.MaxChainDepth-1) + scale +
1207 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1208 		  sizeof(u32));
1209 	}
1210 
1211 	if (numSGE < sh->sg_tablesize) {
1212 		/* Reset this value */
1213 		dprintk((MYIOC_s_INFO_FMT
1214 		  "Resetting sg_tablesize to %d from %d\n",
1215 		  ioc->name, numSGE, sh->sg_tablesize));
1216 		sh->sg_tablesize = numSGE;
1217 	}
1218 
1219 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1220 
1221 	hd = (MPT_SCSI_HOST *) sh->hostdata;
1222 	hd->ioc = ioc;
1223 
1224 	/* SCSI needs scsi_cmnd lookup table!
1225 	 * (with size equal to req_depth*PtrSz!)
1226 	 */
1227 	hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1228 	if (!hd->ScsiLookup) {
1229 		error = -ENOMEM;
1230 		goto out_mptfc_probe;
1231 	}
1232 
1233 	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
1234 		 ioc->name, hd->ScsiLookup));
1235 
1236 	/* Clear the TM flags
1237 	 */
1238 	hd->tmPending = 0;
1239 	hd->tmState = TM_STATE_NONE;
1240 	hd->resetPending = 0;
1241 	hd->abortSCpnt = NULL;
1242 
1243 	/* Clear the pointer used to store
1244 	 * single-threaded commands, i.e., those
1245 	 * issued during a bus scan, dv and
1246 	 * configuration pages.
1247 	 */
1248 	hd->cmdPtr = NULL;
1249 
1250 	/* Initialize this SCSI Hosts' timers
1251 	 * To use, set the timer expires field
1252 	 * and add_timer
1253 	 */
1254 	init_timer(&hd->timer);
1255 	hd->timer.data = (unsigned long) hd;
1256 	hd->timer.function = mptscsih_timer_expired;
1257 
1258 	init_waitqueue_head(&hd->scandv_waitq);
1259 	hd->scandv_wait_done = 0;
1260 	hd->last_queue_full = 0;
1261 
1262 	sh->transportt = mptfc_transport_template;
1263 	error = scsi_add_host (sh, &ioc->pcidev->dev);
1264 	if(error) {
1265 		dprintk((KERN_ERR MYNAM
1266 		  "scsi_add_host failed\n"));
1267 		goto out_mptfc_probe;
1268 	}
1269 
1270 	/* initialize workqueue */
1271 
1272 	snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
1273 		sh->host_no);
1274 	ioc->fc_rescan_work_q =
1275 		create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
1276 	if (!ioc->fc_rescan_work_q)
1277 		goto out_mptfc_probe;
1278 
1279 	/*
1280 	 *  Pre-fetch FC port WWN and stuff...
1281 	 *  (FCPortPage0_t stuff)
1282 	 */
1283 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1284 		(void) mptfc_GetFcPortPage0(ioc, ii);
1285 	}
1286 	mptfc_SetFcPortPage1_defaults(ioc);
1287 
1288 	/*
1289 	 * scan for rports -
1290 	 *	by doing it via the workqueue, some locking is eliminated
1291 	 */
1292 
1293 	queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1294 	flush_workqueue(ioc->fc_rescan_work_q);
1295 
1296 	return 0;
1297 
1298 out_mptfc_probe:
1299 
1300 	mptscsih_remove(pdev);
1301 	return error;
1302 }
1303 
1304 static struct pci_driver mptfc_driver = {
1305 	.name		= "mptfc",
1306 	.id_table	= mptfc_pci_table,
1307 	.probe		= mptfc_probe,
1308 	.remove		= __devexit_p(mptfc_remove),
1309 	.shutdown	= mptscsih_shutdown,
1310 #ifdef CONFIG_PM
1311 	.suspend	= mptscsih_suspend,
1312 	.resume		= mptscsih_resume,
1313 #endif
1314 };
1315 
1316 static int
1317 mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1318 {
1319 	MPT_SCSI_HOST *hd;
1320 	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1321 	unsigned long flags;
1322 	int rc=1;
1323 
1324 	devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1325 			ioc->name, event));
1326 
1327 	if (ioc->sh == NULL ||
1328 		((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
1329 		return 1;
1330 
1331 	switch (event) {
1332 	case MPI_EVENT_RESCAN:
1333 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1334 		if (ioc->fc_rescan_work_q) {
1335 			queue_work(ioc->fc_rescan_work_q,
1336 				   &ioc->fc_rescan_work);
1337 		}
1338 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1339 		break;
1340 	default:
1341 		rc = mptscsih_event_process(ioc,pEvReply);
1342 		break;
1343 	}
1344 	return rc;
1345 }
1346 
1347 static int
1348 mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1349 {
1350 	int		rc;
1351 	unsigned long	flags;
1352 
1353 	rc = mptscsih_ioc_reset(ioc,reset_phase);
1354 	if (rc == 0)
1355 		return rc;
1356 
1357 
1358 	dtmprintk((KERN_WARNING MYNAM
1359 		": IOC %s_reset routed to FC host driver!\n",
1360 		reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1361 		reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1362 
1363 	if (reset_phase == MPT_IOC_SETUP_RESET) {
1364 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1365 		if (ioc->fc_rescan_work_q) {
1366 			queue_work(ioc->fc_rescan_work_q,
1367 				   &ioc->fc_setup_reset_work);
1368 		}
1369 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1370 	}
1371 
1372 	else if (reset_phase == MPT_IOC_PRE_RESET) {
1373 	}
1374 
1375 	else {	/* MPT_IOC_POST_RESET */
1376 		mptfc_SetFcPortPage1_defaults(ioc);
1377 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1378 		if (ioc->fc_rescan_work_q) {
1379 			queue_work(ioc->fc_rescan_work_q,
1380 				   &ioc->fc_rescan_work);
1381 		}
1382 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1383 	}
1384 	return 1;
1385 }
1386 
1387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1388 /**
1389  *	mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1390  *
1391  *	Returns 0 for success, non-zero for failure.
1392  */
1393 static int __init
1394 mptfc_init(void)
1395 {
1396 	int error;
1397 
1398 	show_mptmod_ver(my_NAME, my_VERSION);
1399 
1400 	/* sanity check module parameters */
1401 	if (mptfc_dev_loss_tmo <= 0)
1402 		mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1403 
1404 	mptfc_transport_template =
1405 		fc_attach_transport(&mptfc_transport_functions);
1406 
1407 	if (!mptfc_transport_template)
1408 		return -ENODEV;
1409 
1410 	mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
1411 	mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
1412 	mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
1413 
1414 	if (mpt_event_register(mptfcDoneCtx, mptfc_event_process) == 0) {
1415 		devtverboseprintk((KERN_INFO MYNAM
1416 		  ": Registered for IOC event notifications\n"));
1417 	}
1418 
1419 	if (mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset) == 0) {
1420 		dprintk((KERN_INFO MYNAM
1421 		  ": Registered for IOC reset notifications\n"));
1422 	}
1423 
1424 	error = pci_register_driver(&mptfc_driver);
1425 	if (error)
1426 		fc_release_transport(mptfc_transport_template);
1427 
1428 	return error;
1429 }
1430 
1431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1432 /**
1433  *	mptfc_remove - Remove fc infrastructure for devices
1434  *	@pdev: Pointer to pci_dev structure
1435  *
1436  */
1437 static void __devexit
1438 mptfc_remove(struct pci_dev *pdev)
1439 {
1440 	MPT_ADAPTER		*ioc = pci_get_drvdata(pdev);
1441 	struct mptfc_rport_info	*p, *n;
1442 	struct workqueue_struct *work_q;
1443 	unsigned long		flags;
1444 	int			ii;
1445 
1446 	/* destroy workqueue */
1447 	if ((work_q=ioc->fc_rescan_work_q)) {
1448 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1449 		ioc->fc_rescan_work_q = NULL;
1450 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1451 		destroy_workqueue(work_q);
1452 	}
1453 
1454 	fc_remove_host(ioc->sh);
1455 
1456 	list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1457 		list_del(&p->list);
1458 		kfree(p);
1459 	}
1460 
1461 	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1462 		if (ioc->fc_data.fc_port_page1[ii].data) {
1463 			pci_free_consistent(ioc->pcidev,
1464 				ioc->fc_data.fc_port_page1[ii].pg_sz,
1465 				(u8 *) ioc->fc_data.fc_port_page1[ii].data,
1466 				ioc->fc_data.fc_port_page1[ii].dma);
1467 			ioc->fc_data.fc_port_page1[ii].data = NULL;
1468 		}
1469 	}
1470 
1471 	mptscsih_remove(pdev);
1472 }
1473 
1474 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1476 /**
1477  *	mptfc_exit - Unregisters MPT adapter(s)
1478  *
1479  */
1480 static void __exit
1481 mptfc_exit(void)
1482 {
1483 	pci_unregister_driver(&mptfc_driver);
1484 	fc_release_transport(mptfc_transport_template);
1485 
1486 	mpt_reset_deregister(mptfcDoneCtx);
1487 	dprintk((KERN_INFO MYNAM
1488 	  ": Deregistered for IOC reset notifications\n"));
1489 
1490 	mpt_event_deregister(mptfcDoneCtx);
1491 	dprintk((KERN_INFO MYNAM
1492 	  ": Deregistered for IOC event notifications\n"));
1493 
1494 	mpt_deregister(mptfcInternalCtx);
1495 	mpt_deregister(mptfcTaskCtx);
1496 	mpt_deregister(mptfcDoneCtx);
1497 }
1498 
1499 module_init(mptfc_init);
1500 module_exit(mptfc_exit);
1501