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