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