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