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