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