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	kfree(starget->hostdata);
529	starget->hostdata = NULL;
530}
531
532/*
533 *	OS entry point to allow host driver to alloc memory
534 *	for each scsi target. Called once per device the bus scan.
535 *	Return non-zero if allocation fails.
536 */
537static int
538mptfc_target_alloc(struct scsi_target *starget)
539{
540	VirtTarget		*vtarget;
541	struct fc_rport		*rport;
542	struct mptfc_rport_info *ri;
543	int			rc;
544
545	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
546	if (!vtarget)
547		return -ENOMEM;
548	starget->hostdata = vtarget;
549
550	rc = -ENODEV;
551	rport = starget_to_rport(starget);
552	if (rport) {
553		ri = *((struct mptfc_rport_info **)rport->dd_data);
554		if (ri) {	/* better be! */
555			vtarget->id = ri->pg0.CurrentTargetID;
556			vtarget->channel = ri->pg0.CurrentBus;
557			ri->starget = starget;
558			rc = 0;
559		}
560	}
561	if (rc != 0) {
562		kfree(vtarget);
563		starget->hostdata = NULL;
564	}
565
566	return rc;
567}
568/*
569 *	mptfc_dump_lun_info
570 *	@ioc
571 *	@rport
572 *	@sdev
573 *
574 */
575static void
576mptfc_dump_lun_info(MPT_ADAPTER *ioc, struct fc_rport *rport, struct scsi_device *sdev,
577		VirtTarget *vtarget)
578{
579	u64 nn, pn;
580	struct mptfc_rport_info *ri;
581
582	ri = *((struct mptfc_rport_info **)rport->dd_data);
583	pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
584	nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
585	dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
586		"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
587		"CurrentTargetID %d, %x %llx %llx\n",
588		ioc->name,
589		sdev->host->host_no,
590		vtarget->num_luns,
591		sdev->id, ri->pg0.CurrentTargetID,
592		ri->pg0.PortIdentifier,
593		(unsigned long long)pn,
594		(unsigned long long)nn));
595}
596
597
598/*
599 *	OS entry point to allow host driver to alloc memory
600 *	for each scsi device. Called once per device the bus scan.
601 *	Return non-zero if allocation fails.
602 *	Init memory once per LUN.
603 */
604static int
605mptfc_slave_alloc(struct scsi_device *sdev)
606{
607	MPT_SCSI_HOST		*hd;
608	VirtTarget		*vtarget;
609	VirtDevice		*vdevice;
610	struct scsi_target	*starget;
611	struct fc_rport		*rport;
612	MPT_ADAPTER 		*ioc;
613
614	starget = scsi_target(sdev);
615	rport = starget_to_rport(starget);
616
617	if (!rport || fc_remote_port_chkready(rport))
618		return -ENXIO;
619
620	hd = shost_priv(sdev->host);
621	ioc = hd->ioc;
622
623	vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
624	if (!vdevice) {
625		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
626				ioc->name, sizeof(VirtDevice));
627		return -ENOMEM;
628	}
629
630
631	sdev->hostdata = vdevice;
632	vtarget = starget->hostdata;
633
634	if (vtarget->num_luns == 0) {
635		vtarget->ioc_id = ioc->id;
636		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
637	}
638
639	vdevice->vtarget = vtarget;
640	vdevice->lun = sdev->lun;
641
642	vtarget->num_luns++;
643
644
645	mptfc_dump_lun_info(ioc, rport, sdev, vtarget);
646
647	return 0;
648}
649
650static int
651mptfc_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *SCpnt)
652{
653	struct mptfc_rport_info	*ri;
654	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
655	int		err;
656	VirtDevice	*vdevice = SCpnt->device->hostdata;
657
658	if (!vdevice || !vdevice->vtarget) {
659		SCpnt->result = DID_NO_CONNECT << 16;
660		SCpnt->scsi_done(SCpnt);
661		return 0;
662	}
663
664	err = fc_remote_port_chkready(rport);
665	if (unlikely(err)) {
666		SCpnt->result = err;
667		SCpnt->scsi_done(SCpnt);
668		return 0;
669	}
670
671	/* dd_data is null until finished adding target */
672	ri = *((struct mptfc_rport_info **)rport->dd_data);
673	if (unlikely(!ri)) {
674		SCpnt->result = DID_IMM_RETRY << 16;
675		SCpnt->scsi_done(SCpnt);
676		return 0;
677	}
678
679	return mptscsih_qcmd(SCpnt);
680}
681
682/*
683 *	mptfc_display_port_link_speed - displaying link speed
684 *	@ioc: Pointer to MPT_ADAPTER structure
685 *	@portnum: IOC Port number
686 *	@pp0dest: port page0 data payload
687 *
688 */
689static void
690mptfc_display_port_link_speed(MPT_ADAPTER *ioc, int portnum, FCPortPage0_t *pp0dest)
691{
692	u8	old_speed, new_speed, state;
693	char	*old, *new;
694
695	if (portnum >= 2)
696		return;
697
698	old_speed = ioc->fc_link_speed[portnum];
699	new_speed = pp0dest->CurrentSpeed;
700	state = pp0dest->PortState;
701
702	if (state != MPI_FCPORTPAGE0_PORTSTATE_OFFLINE &&
703	    new_speed != MPI_FCPORTPAGE0_CURRENT_SPEED_UKNOWN) {
704
705		old = old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
706		       old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
707			old_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
708			 "Unknown";
709		new = new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT ? "1 Gbps" :
710		       new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT ? "2 Gbps" :
711			new_speed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT ? "4 Gbps" :
712			 "Unknown";
713		if (old_speed == 0)
714			printk(MYIOC_s_NOTE_FMT
715				"FC Link Established, Speed = %s\n",
716				ioc->name, new);
717		else if (old_speed != new_speed)
718			printk(MYIOC_s_WARN_FMT
719				"FC Link Speed Change, Old Speed = %s, New Speed = %s\n",
720				ioc->name, old, new);
721
722		ioc->fc_link_speed[portnum] = new_speed;
723	}
724}
725
726/*
727 *	mptfc_GetFcPortPage0 - Fetch FCPort config Page0.
728 *	@ioc: Pointer to MPT_ADAPTER structure
729 *	@portnum: IOC Port number
730 *
731 *	Return: 0 for success
732 *	-ENOMEM if no memory available
733 *		-EPERM if not allowed due to ISR context
734 *		-EAGAIN if no msg frames currently available
735 *		-EFAULT for non-successful reply or no reply (timeout)
736 *		-EINVAL portnum arg out of range (hardwired to two elements)
737 */
738static int
739mptfc_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
740{
741	ConfigPageHeader_t	 hdr;
742	CONFIGPARMS		 cfg;
743	FCPortPage0_t		*ppage0_alloc;
744	FCPortPage0_t		*pp0dest;
745	dma_addr_t		 page0_dma;
746	int			 data_sz;
747	int			 copy_sz;
748	int			 rc;
749	int			 count = 400;
750
751	if (portnum > 1)
752		return -EINVAL;
753
754	/* Get FCPort Page 0 header */
755	hdr.PageVersion = 0;
756	hdr.PageLength = 0;
757	hdr.PageNumber = 0;
758	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
759	cfg.cfghdr.hdr = &hdr;
760	cfg.physAddr = -1;
761	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
762	cfg.dir = 0;
763	cfg.pageAddr = portnum;
764	cfg.timeout = 0;
765
766	if ((rc = mpt_config(ioc, &cfg)) != 0)
767		return rc;
768
769	if (hdr.PageLength == 0)
770		return 0;
771
772	data_sz = hdr.PageLength * 4;
773	rc = -ENOMEM;
774	ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
775	if (ppage0_alloc) {
776
777 try_again:
778		memset((u8 *)ppage0_alloc, 0, data_sz);
779		cfg.physAddr = page0_dma;
780		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
781
782		if ((rc = mpt_config(ioc, &cfg)) == 0) {
783			/* save the data */
784			pp0dest = &ioc->fc_port_page0[portnum];
785			copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
786			memcpy(pp0dest, ppage0_alloc, copy_sz);
787
788			/*
789			 *	Normalize endianness of structure data,
790			 *	by byte-swapping all > 1 byte fields!
791			 */
792			pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
793			pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
794			pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
795			pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
796			pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
797			pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
798			pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
799			pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
800			pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
801			pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
802			pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
803			pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
804			pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
805			pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
806			pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
807			pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
808
809			/*
810			 * if still doing discovery,
811			 * hang loose a while until finished
812			 */
813			if ((pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) ||
814			    (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE &&
815			     (pp0dest->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_TYPE_MASK)
816			      == MPI_FCPORTPAGE0_FLAGS_ATTACH_NO_INIT)) {
817				if (count-- > 0) {
818					msleep(100);
819					goto try_again;
820				}
821				printk(MYIOC_s_INFO_FMT "Firmware discovery not"
822							" complete.\n",
823						ioc->name);
824			}
825			mptfc_display_port_link_speed(ioc, portnum, pp0dest);
826		}
827
828		pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
829	}
830
831	return rc;
832}
833
834static int
835mptfc_WriteFcPortPage1(MPT_ADAPTER *ioc, int portnum)
836{
837	ConfigPageHeader_t	 hdr;
838	CONFIGPARMS		 cfg;
839	int			 rc;
840
841	if (portnum > 1)
842		return -EINVAL;
843
844	if (!(ioc->fc_data.fc_port_page1[portnum].data))
845		return -EINVAL;
846
847	/* get fcport page 1 header */
848	hdr.PageVersion = 0;
849	hdr.PageLength = 0;
850	hdr.PageNumber = 1;
851	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
852	cfg.cfghdr.hdr = &hdr;
853	cfg.physAddr = -1;
854	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
855	cfg.dir = 0;
856	cfg.pageAddr = portnum;
857	cfg.timeout = 0;
858
859	if ((rc = mpt_config(ioc, &cfg)) != 0)
860		return rc;
861
862	if (hdr.PageLength == 0)
863		return -ENODEV;
864
865	if (hdr.PageLength*4 != ioc->fc_data.fc_port_page1[portnum].pg_sz)
866		return -EINVAL;
867
868	cfg.physAddr = ioc->fc_data.fc_port_page1[portnum].dma;
869	cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
870	cfg.dir = 1;
871
872	rc = mpt_config(ioc, &cfg);
873
874	return rc;
875}
876
877static int
878mptfc_GetFcPortPage1(MPT_ADAPTER *ioc, int portnum)
879{
880	ConfigPageHeader_t	 hdr;
881	CONFIGPARMS		 cfg;
882	FCPortPage1_t		*page1_alloc;
883	dma_addr_t		 page1_dma;
884	int			 data_sz;
885	int			 rc;
886
887	if (portnum > 1)
888		return -EINVAL;
889
890	/* get fcport page 1 header */
891	hdr.PageVersion = 0;
892	hdr.PageLength = 0;
893	hdr.PageNumber = 1;
894	hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
895	cfg.cfghdr.hdr = &hdr;
896	cfg.physAddr = -1;
897	cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
898	cfg.dir = 0;
899	cfg.pageAddr = portnum;
900	cfg.timeout = 0;
901
902	if ((rc = mpt_config(ioc, &cfg)) != 0)
903		return rc;
904
905	if (hdr.PageLength == 0)
906		return -ENODEV;
907
908start_over:
909
910	if (ioc->fc_data.fc_port_page1[portnum].data == NULL) {
911		data_sz = hdr.PageLength * 4;
912		if (data_sz < sizeof(FCPortPage1_t))
913			data_sz = sizeof(FCPortPage1_t);
914
915		page1_alloc = (FCPortPage1_t *) pci_alloc_consistent(ioc->pcidev,
916						data_sz,
917						&page1_dma);
918		if (!page1_alloc)
919			return -ENOMEM;
920	}
921	else {
922		page1_alloc = ioc->fc_data.fc_port_page1[portnum].data;
923		page1_dma = ioc->fc_data.fc_port_page1[portnum].dma;
924		data_sz = ioc->fc_data.fc_port_page1[portnum].pg_sz;
925		if (hdr.PageLength * 4 > data_sz) {
926			ioc->fc_data.fc_port_page1[portnum].data = NULL;
927			pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
928				page1_alloc, page1_dma);
929			goto start_over;
930		}
931	}
932
933	memset(page1_alloc,0,data_sz);
934
935	cfg.physAddr = page1_dma;
936	cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
937
938	if ((rc = mpt_config(ioc, &cfg)) == 0) {
939		ioc->fc_data.fc_port_page1[portnum].data = page1_alloc;
940		ioc->fc_data.fc_port_page1[portnum].pg_sz = data_sz;
941		ioc->fc_data.fc_port_page1[portnum].dma = page1_dma;
942	}
943	else {
944		ioc->fc_data.fc_port_page1[portnum].data = NULL;
945		pci_free_consistent(ioc->pcidev, data_sz, (u8 *)
946			page1_alloc, page1_dma);
947	}
948
949	return rc;
950}
951
952static void
953mptfc_SetFcPortPage1_defaults(MPT_ADAPTER *ioc)
954{
955	int		ii;
956	FCPortPage1_t	*pp1;
957
958	#define MPTFC_FW_DEVICE_TIMEOUT	(1)
959	#define MPTFC_FW_IO_PEND_TIMEOUT (1)
960	#define ON_FLAGS  (MPI_FCPORTPAGE1_FLAGS_IMMEDIATE_ERROR_REPLY)
961	#define OFF_FLAGS (MPI_FCPORTPAGE1_FLAGS_VERBOSE_RESCAN_EVENTS)
962
963	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
964		if (mptfc_GetFcPortPage1(ioc, ii) != 0)
965			continue;
966		pp1 = ioc->fc_data.fc_port_page1[ii].data;
967		if ((pp1->InitiatorDeviceTimeout == MPTFC_FW_DEVICE_TIMEOUT)
968		 && (pp1->InitiatorIoPendTimeout == MPTFC_FW_IO_PEND_TIMEOUT)
969		 && ((pp1->Flags & ON_FLAGS) == ON_FLAGS)
970		 && ((pp1->Flags & OFF_FLAGS) == 0))
971			continue;
972		pp1->InitiatorDeviceTimeout = MPTFC_FW_DEVICE_TIMEOUT;
973		pp1->InitiatorIoPendTimeout = MPTFC_FW_IO_PEND_TIMEOUT;
974		pp1->Flags &= ~OFF_FLAGS;
975		pp1->Flags |= ON_FLAGS;
976		mptfc_WriteFcPortPage1(ioc, ii);
977	}
978}
979
980
981static void
982mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
983{
984	unsigned	class = 0;
985	unsigned	cos = 0;
986	unsigned	speed;
987	unsigned	port_type;
988	unsigned	port_state;
989	FCPortPage0_t	*pp0;
990	struct Scsi_Host *sh;
991	char		*sn;
992
993	/* don't know what to do as only one scsi (fc) host was allocated */
994	if (portnum != 0)
995		return;
996
997	pp0 = &ioc->fc_port_page0[portnum];
998	sh = ioc->sh;
999
1000	sn = fc_host_symbolic_name(sh);
1001	snprintf(sn, FC_SYMBOLIC_NAME_SIZE, "%s %s%08xh",
1002	    ioc->prod_name,
1003	    MPT_FW_REV_MAGIC_ID_STRING,
1004	    ioc->facts.FWVersion.Word);
1005
1006	fc_host_tgtid_bind_type(sh) = FC_TGTID_BIND_BY_WWPN;
1007
1008	fc_host_maxframe_size(sh) = pp0->MaxFrameSize;
1009
1010	fc_host_node_name(sh) =
1011	    	(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1012
1013	fc_host_port_name(sh) =
1014	    	(u64)pp0->WWPN.High << 32 | (u64)pp0->WWPN.Low;
1015
1016	fc_host_port_id(sh) = pp0->PortIdentifier;
1017
1018	class = pp0->SupportedServiceClass;
1019	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
1020		cos |= FC_COS_CLASS1;
1021	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
1022		cos |= FC_COS_CLASS2;
1023	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
1024		cos |= FC_COS_CLASS3;
1025	fc_host_supported_classes(sh) = cos;
1026
1027	if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_1GBIT)
1028		speed = FC_PORTSPEED_1GBIT;
1029	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_2GBIT)
1030		speed = FC_PORTSPEED_2GBIT;
1031	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_4GBIT)
1032		speed = FC_PORTSPEED_4GBIT;
1033	else if (pp0->CurrentSpeed == MPI_FCPORTPAGE0_CURRENT_SPEED_10GBIT)
1034		speed = FC_PORTSPEED_10GBIT;
1035	else
1036		speed = FC_PORTSPEED_UNKNOWN;
1037	fc_host_speed(sh) = speed;
1038
1039	speed = 0;
1040	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_1GBIT_SPEED)
1041		speed |= FC_PORTSPEED_1GBIT;
1042	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_2GBIT_SPEED)
1043		speed |= FC_PORTSPEED_2GBIT;
1044	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_4GBIT_SPEED)
1045		speed |= FC_PORTSPEED_4GBIT;
1046	if (pp0->SupportedSpeeds & MPI_FCPORTPAGE0_SUPPORT_10GBIT_SPEED)
1047		speed |= FC_PORTSPEED_10GBIT;
1048	fc_host_supported_speeds(sh) = speed;
1049
1050	port_state = FC_PORTSTATE_UNKNOWN;
1051	if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_ONLINE)
1052		port_state = FC_PORTSTATE_ONLINE;
1053	else if (pp0->PortState == MPI_FCPORTPAGE0_PORTSTATE_OFFLINE)
1054		port_state = FC_PORTSTATE_LINKDOWN;
1055	fc_host_port_state(sh) = port_state;
1056
1057	port_type = FC_PORTTYPE_UNKNOWN;
1058	if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_POINT_TO_POINT)
1059		port_type = FC_PORTTYPE_PTP;
1060	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PRIVATE_LOOP)
1061		port_type = FC_PORTTYPE_LPORT;
1062	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_PUBLIC_LOOP)
1063		port_type = FC_PORTTYPE_NLPORT;
1064	else if (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_ATTACH_FABRIC_DIRECT)
1065		port_type = FC_PORTTYPE_NPORT;
1066	fc_host_port_type(sh) = port_type;
1067
1068	fc_host_fabric_name(sh) =
1069	    (pp0->Flags & MPI_FCPORTPAGE0_FLAGS_FABRIC_WWN_VALID) ?
1070		(u64) pp0->FabricWWNN.High << 32 | (u64) pp0->FabricWWPN.Low :
1071		(u64)pp0->WWNN.High << 32 | (u64)pp0->WWNN.Low;
1072
1073}
1074
1075static void
1076mptfc_link_status_change(struct work_struct *work)
1077{
1078	MPT_ADAPTER             *ioc =
1079		container_of(work, MPT_ADAPTER, fc_rescan_work);
1080	int ii;
1081
1082	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++)
1083		(void) mptfc_GetFcPortPage0(ioc, ii);
1084
1085}
1086
1087static void
1088mptfc_setup_reset(struct work_struct *work)
1089{
1090	MPT_ADAPTER		*ioc =
1091		container_of(work, MPT_ADAPTER, fc_setup_reset_work);
1092	u64			pn;
1093	struct mptfc_rport_info *ri;
1094	struct scsi_target      *starget;
1095	VirtTarget              *vtarget;
1096
1097	/* reset about to happen, delete (block) all rports */
1098	list_for_each_entry(ri, &ioc->fc_rports, list) {
1099		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1100			ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
1101			fc_remote_port_delete(ri->rport);	/* won't sleep */
1102			ri->rport = NULL;
1103			starget = ri->starget;
1104			if (starget) {
1105				vtarget = starget->hostdata;
1106				if (vtarget)
1107					vtarget->deleted = 1;
1108			}
1109
1110			pn = (u64)ri->pg0.WWPN.High << 32 |
1111			     (u64)ri->pg0.WWPN.Low;
1112			dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1113				"mptfc_setup_reset.%d: %llx deleted\n",
1114				ioc->name,
1115				ioc->sh->host_no,
1116				(unsigned long long)pn));
1117		}
1118	}
1119}
1120
1121static void
1122mptfc_rescan_devices(struct work_struct *work)
1123{
1124	MPT_ADAPTER		*ioc =
1125		container_of(work, MPT_ADAPTER, fc_rescan_work);
1126	int			ii;
1127	u64			pn;
1128	struct mptfc_rport_info *ri;
1129	struct scsi_target      *starget;
1130	VirtTarget              *vtarget;
1131
1132	/* start by tagging all ports as missing */
1133	list_for_each_entry(ri, &ioc->fc_rports, list) {
1134		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
1135			ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
1136		}
1137	}
1138
1139	/*
1140	 * now rescan devices known to adapter,
1141	 * will reregister existing rports
1142	 */
1143	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1144		(void) mptfc_GetFcPortPage0(ioc, ii);
1145		mptfc_init_host_attr(ioc, ii);	/* refresh */
1146		mptfc_GetFcDevPage0(ioc, ii, mptfc_register_dev);
1147	}
1148
1149	/* delete devices still missing */
1150	list_for_each_entry(ri, &ioc->fc_rports, list) {
1151		/* if newly missing, delete it */
1152		if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
1153
1154			ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
1155				       MPT_RPORT_INFO_FLAGS_MISSING);
1156			fc_remote_port_delete(ri->rport);	/* won't sleep */
1157			ri->rport = NULL;
1158			starget = ri->starget;
1159			if (starget) {
1160				vtarget = starget->hostdata;
1161				if (vtarget)
1162					vtarget->deleted = 1;
1163			}
1164
1165			pn = (u64)ri->pg0.WWPN.High << 32 |
1166			     (u64)ri->pg0.WWPN.Low;
1167			dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
1168				"mptfc_rescan.%d: %llx deleted\n",
1169				ioc->name,
1170				ioc->sh->host_no,
1171				(unsigned long long)pn));
1172		}
1173	}
1174}
1175
1176static int
1177mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1178{
1179	struct Scsi_Host	*sh;
1180	MPT_SCSI_HOST		*hd;
1181	MPT_ADAPTER 		*ioc;
1182	unsigned long		 flags;
1183	int			 ii;
1184	int			 numSGE = 0;
1185	int			 scale;
1186	int			 ioc_cap;
1187	int			error=0;
1188	int			r;
1189
1190	if ((r = mpt_attach(pdev,id)) != 0)
1191		return r;
1192
1193	ioc = pci_get_drvdata(pdev);
1194	ioc->DoneCtx = mptfcDoneCtx;
1195	ioc->TaskCtx = mptfcTaskCtx;
1196	ioc->InternalCtx = mptfcInternalCtx;
1197
1198	/*  Added sanity check on readiness of the MPT adapter.
1199	 */
1200	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1201		printk(MYIOC_s_WARN_FMT
1202		  "Skipping because it's not operational!\n",
1203		  ioc->name);
1204		error = -ENODEV;
1205		goto out_mptfc_probe;
1206	}
1207
1208	if (!ioc->active) {
1209		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1210		  ioc->name);
1211		error = -ENODEV;
1212		goto out_mptfc_probe;
1213	}
1214
1215	/*  Sanity check - ensure at least 1 port is INITIATOR capable
1216	 */
1217	ioc_cap = 0;
1218	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1219		if (ioc->pfacts[ii].ProtocolFlags &
1220		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
1221			ioc_cap ++;
1222	}
1223
1224	if (!ioc_cap) {
1225		printk(MYIOC_s_WARN_FMT
1226			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1227			ioc->name, ioc);
1228		return 0;
1229	}
1230
1231	sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
1232
1233	if (!sh) {
1234		printk(MYIOC_s_WARN_FMT
1235			"Unable to register controller with SCSI subsystem\n",
1236			ioc->name);
1237		error = -1;
1238		goto out_mptfc_probe;
1239        }
1240
1241	spin_lock_init(&ioc->fc_rescan_work_lock);
1242	INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices);
1243	INIT_WORK(&ioc->fc_setup_reset_work, mptfc_setup_reset);
1244	INIT_WORK(&ioc->fc_lsc_work, mptfc_link_status_change);
1245
1246	spin_lock_irqsave(&ioc->FreeQlock, flags);
1247
1248	/* Attach the SCSI Host to the IOC structure
1249	 */
1250	ioc->sh = sh;
1251
1252	sh->io_port = 0;
1253	sh->n_io_port = 0;
1254	sh->irq = 0;
1255
1256	/* set 16 byte cdb's */
1257	sh->max_cmd_len = 16;
1258
1259	sh->max_id = ioc->pfacts->MaxDevices;
1260	sh->max_lun = max_lun;
1261
1262	/* Required entry.
1263	 */
1264	sh->unique_id = ioc->id;
1265
1266	/* Verify that we won't exceed the maximum
1267	 * number of chain buffers
1268	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
1269	 * For 32bit SGE's:
1270	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1271	 *               + (req_sz - 64)/sizeof(SGE)
1272	 * A slightly different algorithm is required for
1273	 * 64bit SGEs.
1274	 */
1275	scale = ioc->req_sz/ioc->SGE_size;
1276	if (ioc->sg_addr_size == sizeof(u64)) {
1277		numSGE = (scale - 1) *
1278		  (ioc->facts.MaxChainDepth-1) + scale +
1279		  (ioc->req_sz - 60) / ioc->SGE_size;
1280	} else {
1281		numSGE = 1 + (scale - 1) *
1282		  (ioc->facts.MaxChainDepth-1) + scale +
1283		  (ioc->req_sz - 64) / ioc->SGE_size;
1284	}
1285
1286	if (numSGE < sh->sg_tablesize) {
1287		/* Reset this value */
1288		dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1289		  "Resetting sg_tablesize to %d from %d\n",
1290		  ioc->name, numSGE, sh->sg_tablesize));
1291		sh->sg_tablesize = numSGE;
1292	}
1293
1294	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1295
1296	hd = shost_priv(sh);
1297	hd->ioc = ioc;
1298
1299	/* SCSI needs scsi_cmnd lookup table!
1300	 * (with size equal to req_depth*PtrSz!)
1301	 */
1302	ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
1303	if (!ioc->ScsiLookup) {
1304		error = -ENOMEM;
1305		goto out_mptfc_probe;
1306	}
1307	spin_lock_init(&ioc->scsi_lookup_lock);
1308
1309	dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScsiLookup @ %p\n",
1310		 ioc->name, ioc->ScsiLookup));
1311
1312	hd->last_queue_full = 0;
1313
1314	sh->transportt = mptfc_transport_template;
1315	error = scsi_add_host (sh, &ioc->pcidev->dev);
1316	if(error) {
1317		dprintk(ioc, printk(MYIOC_s_ERR_FMT
1318		  "scsi_add_host failed\n", ioc->name));
1319		goto out_mptfc_probe;
1320	}
1321
1322	/* initialize workqueue */
1323
1324	snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
1325		 "mptfc_wq_%d", sh->host_no);
1326	ioc->fc_rescan_work_q =
1327		create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
1328	if (!ioc->fc_rescan_work_q)
1329		goto out_mptfc_probe;
1330
1331	/*
1332	 *  Pre-fetch FC port WWN and stuff...
1333	 *  (FCPortPage0_t stuff)
1334	 */
1335	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1336		(void) mptfc_GetFcPortPage0(ioc, ii);
1337	}
1338	mptfc_SetFcPortPage1_defaults(ioc);
1339
1340	/*
1341	 * scan for rports -
1342	 *	by doing it via the workqueue, some locking is eliminated
1343	 */
1344
1345	queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
1346	flush_workqueue(ioc->fc_rescan_work_q);
1347
1348	return 0;
1349
1350out_mptfc_probe:
1351
1352	mptscsih_remove(pdev);
1353	return error;
1354}
1355
1356static struct pci_driver mptfc_driver = {
1357	.name		= "mptfc",
1358	.id_table	= mptfc_pci_table,
1359	.probe		= mptfc_probe,
1360	.remove		= mptfc_remove,
1361	.shutdown	= mptscsih_shutdown,
1362#ifdef CONFIG_PM
1363	.suspend	= mptscsih_suspend,
1364	.resume		= mptscsih_resume,
1365#endif
1366};
1367
1368static int
1369mptfc_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
1370{
1371	MPT_SCSI_HOST *hd;
1372	u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
1373	unsigned long flags;
1374	int rc=1;
1375
1376	if (ioc->bus_type != FC)
1377		return 0;
1378
1379	devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
1380			ioc->name, event));
1381
1382	if (ioc->sh == NULL ||
1383		((hd = shost_priv(ioc->sh)) == NULL))
1384		return 1;
1385
1386	switch (event) {
1387	case MPI_EVENT_RESCAN:
1388		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1389		if (ioc->fc_rescan_work_q) {
1390			queue_work(ioc->fc_rescan_work_q,
1391				   &ioc->fc_rescan_work);
1392		}
1393		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1394		break;
1395	case MPI_EVENT_LINK_STATUS_CHANGE:
1396		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1397		if (ioc->fc_rescan_work_q) {
1398			queue_work(ioc->fc_rescan_work_q,
1399				   &ioc->fc_lsc_work);
1400		}
1401		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1402		break;
1403	default:
1404		rc = mptscsih_event_process(ioc,pEvReply);
1405		break;
1406	}
1407	return rc;
1408}
1409
1410static int
1411mptfc_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
1412{
1413	int		rc;
1414	unsigned long	flags;
1415
1416	rc = mptscsih_ioc_reset(ioc,reset_phase);
1417	if ((ioc->bus_type != FC) || (!rc))
1418		return rc;
1419
1420
1421	dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1422		": IOC %s_reset routed to FC host driver!\n",ioc->name,
1423		reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
1424		reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
1425
1426	if (reset_phase == MPT_IOC_SETUP_RESET) {
1427		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1428		if (ioc->fc_rescan_work_q) {
1429			queue_work(ioc->fc_rescan_work_q,
1430				   &ioc->fc_setup_reset_work);
1431		}
1432		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1433	}
1434
1435	else if (reset_phase == MPT_IOC_PRE_RESET) {
1436	}
1437
1438	else {	/* MPT_IOC_POST_RESET */
1439		mptfc_SetFcPortPage1_defaults(ioc);
1440		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1441		if (ioc->fc_rescan_work_q) {
1442			queue_work(ioc->fc_rescan_work_q,
1443				   &ioc->fc_rescan_work);
1444		}
1445		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1446	}
1447	return 1;
1448}
1449
1450/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1451/**
1452 *	mptfc_init - Register MPT adapter(s) as SCSI host(s) with SCSI mid-layer.
1453 *
1454 *	Returns 0 for success, non-zero for failure.
1455 */
1456static int __init
1457mptfc_init(void)
1458{
1459	int error;
1460
1461	show_mptmod_ver(my_NAME, my_VERSION);
1462
1463	/* sanity check module parameters */
1464	if (mptfc_dev_loss_tmo <= 0)
1465		mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
1466
1467	mptfc_transport_template =
1468		fc_attach_transport(&mptfc_transport_functions);
1469
1470	if (!mptfc_transport_template)
1471		return -ENODEV;
1472
1473	mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER,
1474	    "mptscsih_scandv_complete");
1475	mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER,
1476	    "mptscsih_scandv_complete");
1477	mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER,
1478	    "mptscsih_scandv_complete");
1479
1480	mpt_event_register(mptfcDoneCtx, mptfc_event_process);
1481	mpt_reset_register(mptfcDoneCtx, mptfc_ioc_reset);
1482
1483	error = pci_register_driver(&mptfc_driver);
1484	if (error)
1485		fc_release_transport(mptfc_transport_template);
1486
1487	return error;
1488}
1489
1490/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1491/**
1492 *	mptfc_remove - Remove fc infrastructure for devices
1493 *	@pdev: Pointer to pci_dev structure
1494 *
1495 */
1496static void mptfc_remove(struct pci_dev *pdev)
1497{
1498	MPT_ADAPTER		*ioc = pci_get_drvdata(pdev);
1499	struct mptfc_rport_info	*p, *n;
1500	struct workqueue_struct *work_q;
1501	unsigned long		flags;
1502	int			ii;
1503
1504	/* destroy workqueue */
1505	if ((work_q=ioc->fc_rescan_work_q)) {
1506		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
1507		ioc->fc_rescan_work_q = NULL;
1508		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
1509		destroy_workqueue(work_q);
1510	}
1511
1512	fc_remove_host(ioc->sh);
1513
1514	list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
1515		list_del(&p->list);
1516		kfree(p);
1517	}
1518
1519	for (ii=0; ii<ioc->facts.NumberOfPorts; ii++) {
1520		if (ioc->fc_data.fc_port_page1[ii].data) {
1521			pci_free_consistent(ioc->pcidev,
1522				ioc->fc_data.fc_port_page1[ii].pg_sz,
1523				(u8 *) ioc->fc_data.fc_port_page1[ii].data,
1524				ioc->fc_data.fc_port_page1[ii].dma);
1525			ioc->fc_data.fc_port_page1[ii].data = NULL;
1526		}
1527	}
1528
1529	mptscsih_remove(pdev);
1530}
1531
1532/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1533/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1534/**
1535 *	mptfc_exit - Unregisters MPT adapter(s)
1536 *
1537 */
1538static void __exit
1539mptfc_exit(void)
1540{
1541	pci_unregister_driver(&mptfc_driver);
1542	fc_release_transport(mptfc_transport_template);
1543
1544	mpt_reset_deregister(mptfcDoneCtx);
1545	mpt_event_deregister(mptfcDoneCtx);
1546
1547	mpt_deregister(mptfcInternalCtx);
1548	mpt_deregister(mptfcTaskCtx);
1549	mpt_deregister(mptfcDoneCtx);
1550}
1551
1552module_init(mptfc_init);
1553module_exit(mptfc_exit);
1554