xref: /linux/drivers/message/fusion/mptfc.c (revision de2fe5e07d58424bc286fff3fd3c1b0bf933cd58)
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-2005 LSI Logic Corporation
7  *  (mailto:mpt_linux_developer@lsil.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/sched.h>
57 #include <linux/workqueue.h>
58 #include <linux/sort.h>
59 
60 #include <scsi/scsi.h>
61 #include <scsi/scsi_cmnd.h>
62 #include <scsi/scsi_device.h>
63 #include <scsi/scsi_host.h>
64 #include <scsi/scsi_tcq.h>
65 #include <scsi/scsi_transport_fc.h>
66 
67 #include "mptbase.h"
68 #include "mptscsih.h"
69 
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME		"Fusion MPT FC Host driver"
72 #define my_VERSION	MPT_LINUX_VERSION_COMMON
73 #define MYNAM		"mptfc"
74 
75 MODULE_AUTHOR(MODULEAUTHOR);
76 MODULE_DESCRIPTION(my_NAME);
77 MODULE_LICENSE("GPL");
78 
79 /* Command line args */
80 static int mpt_pq_filter = 0;
81 module_param(mpt_pq_filter, int, 0);
82 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
83 
84 #define MPTFC_DEV_LOSS_TMO (60)
85 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;	/* reasonable default */
86 module_param(mptfc_dev_loss_tmo, int, 0);
87 MODULE_PARM_DESC(mptfc_dev_loss_tmo, " Initial time the driver programs the "
88     				     " transport to wait for an rport to "
89 				     " return following a device loss event."
90 				     "  Default=60.");
91 
92 static int	mptfcDoneCtx = -1;
93 static int	mptfcTaskCtx = -1;
94 static int	mptfcInternalCtx = -1; /* Used only for internal commands */
95 
96 static int mptfc_target_alloc(struct scsi_target *starget);
97 static int mptfc_slave_alloc(struct scsi_device *sdev);
98 static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
99 		      void (*done)(struct scsi_cmnd *));
100 static void mptfc_target_destroy(struct scsi_target *starget);
101 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
102 static void __devexit mptfc_remove(struct pci_dev *pdev);
103 
104 static struct scsi_host_template mptfc_driver_template = {
105 	.module				= THIS_MODULE,
106 	.proc_name			= "mptfc",
107 	.proc_info			= mptscsih_proc_info,
108 	.name				= "MPT FC Host",
109 	.info				= mptscsih_info,
110 	.queuecommand			= mptfc_qcmd,
111 	.target_alloc			= mptfc_target_alloc,
112 	.slave_alloc			= mptfc_slave_alloc,
113 	.slave_configure		= mptscsih_slave_configure,
114 	.target_destroy			= mptfc_target_destroy,
115 	.slave_destroy			= mptscsih_slave_destroy,
116 	.change_queue_depth 		= mptscsih_change_queue_depth,
117 	.eh_abort_handler		= mptscsih_abort,
118 	.eh_device_reset_handler	= mptscsih_dev_reset,
119 	.eh_bus_reset_handler		= mptscsih_bus_reset,
120 	.eh_host_reset_handler		= mptscsih_host_reset,
121 	.bios_param			= mptscsih_bios_param,
122 	.can_queue			= MPT_FC_CAN_QUEUE,
123 	.this_id			= -1,
124 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
125 	.max_sectors			= 8192,
126 	.cmd_per_lun			= 7,
127 	.use_clustering			= ENABLE_CLUSTERING,
128 };
129 
130 /****************************************************************************
131  * Supported hardware
132  */
133 
134 static struct pci_device_id mptfc_pci_table[] = {
135 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
136 		PCI_ANY_ID, PCI_ANY_ID },
137 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
138 		PCI_ANY_ID, PCI_ANY_ID },
139 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
140 		PCI_ANY_ID, PCI_ANY_ID },
141 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
142 		PCI_ANY_ID, PCI_ANY_ID },
143 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
144 		PCI_ANY_ID, PCI_ANY_ID },
145 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
146 		PCI_ANY_ID, PCI_ANY_ID },
147 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
148 		PCI_ANY_ID, PCI_ANY_ID },
149 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949ES,
150 		PCI_ANY_ID, PCI_ANY_ID },
151 	{0}	/* Terminating entry */
152 };
153 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
154 
155 static struct scsi_transport_template *mptfc_transport_template = NULL;
156 
157 static struct fc_function_template mptfc_transport_functions = {
158 	.dd_fcrport_size = 8,
159 	.show_host_node_name = 1,
160 	.show_host_port_name = 1,
161 	.show_host_supported_classes = 1,
162 	.show_host_port_id = 1,
163 	.show_rport_supported_classes = 1,
164 	.show_starget_node_name = 1,
165 	.show_starget_port_name = 1,
166 	.show_starget_port_id = 1,
167 	.set_rport_dev_loss_tmo = mptfc_set_rport_loss_tmo,
168 	.show_rport_dev_loss_tmo = 1,
169 
170 };
171 
172 /* FIXME! values controlling firmware RESCAN event
173  * need to be set low to allow dev_loss_tmo to
174  * work as expected.  Currently, firmware doesn't
175  * notify driver of RESCAN event until some number
176  * of seconds elapse.  This value can be set via
177  * lsiutil.
178  */
179 static void
180 mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
181 {
182 	if (timeout > 0)
183 		rport->dev_loss_tmo = timeout;
184 	else
185 		rport->dev_loss_tmo = mptfc_dev_loss_tmo;
186 }
187 
188 static int
189 mptfc_FcDevPage0_cmp_func(const void *a, const void *b)
190 {
191 	FCDevicePage0_t **aa = (FCDevicePage0_t **)a;
192 	FCDevicePage0_t **bb = (FCDevicePage0_t **)b;
193 
194 	if ((*aa)->CurrentBus == (*bb)->CurrentBus) {
195 		if ((*aa)->CurrentTargetID == (*bb)->CurrentTargetID)
196 			return 0;
197 		if ((*aa)->CurrentTargetID < (*bb)->CurrentTargetID)
198 			return -1;
199 		return 1;
200 	}
201 	if ((*aa)->CurrentBus < (*bb)->CurrentBus)
202 		return -1;
203 	return 1;
204 }
205 
206 static int
207 mptfc_GetFcDevPage0(MPT_ADAPTER *ioc, int ioc_port,
208 	void(*func)(MPT_ADAPTER *ioc,int channel, FCDevicePage0_t *arg))
209 {
210 	ConfigPageHeader_t	 hdr;
211 	CONFIGPARMS		 cfg;
212 	FCDevicePage0_t		*ppage0_alloc, *fc;
213 	dma_addr_t		 page0_dma;
214 	int			 data_sz;
215 	int			 ii;
216 
217 	FCDevicePage0_t		*p0_array=NULL, *p_p0;
218 	FCDevicePage0_t		**pp0_array=NULL, **p_pp0;
219 
220 	int			 rc = -ENOMEM;
221 	U32			 port_id = 0xffffff;
222 	int			 num_targ = 0;
223 	int			 max_bus = ioc->facts.MaxBuses;
224 	int			 max_targ = ioc->facts.MaxDevices;
225 
226 	if (max_bus == 0 || max_targ == 0)
227 		goto out;
228 
229 	data_sz = sizeof(FCDevicePage0_t) * max_bus * max_targ;
230 	p_p0 = p0_array =  kzalloc(data_sz, GFP_KERNEL);
231 	if (!p0_array)
232 		goto out;
233 
234 	data_sz = sizeof(FCDevicePage0_t *) * max_bus * max_targ;
235 	p_pp0 = pp0_array = kzalloc(data_sz, GFP_KERNEL);
236 	if (!pp0_array)
237 		goto out;
238 
239 	do {
240 		/* Get FC Device Page 0 header */
241 		hdr.PageVersion = 0;
242 		hdr.PageLength = 0;
243 		hdr.PageNumber = 0;
244 		hdr.PageType = MPI_CONFIG_PAGETYPE_FC_DEVICE;
245 		cfg.cfghdr.hdr = &hdr;
246 		cfg.physAddr = -1;
247 		cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
248 		cfg.dir = 0;
249 		cfg.pageAddr = port_id;
250 		cfg.timeout = 0;
251 
252 		if ((rc = mpt_config(ioc, &cfg)) != 0)
253 			break;
254 
255 		if (hdr.PageLength <= 0)
256 			break;
257 
258 		data_sz = hdr.PageLength * 4;
259 		ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz,
260 		    					&page0_dma);
261 		rc = -ENOMEM;
262 		if (!ppage0_alloc)
263 			break;
264 
265 		cfg.physAddr = page0_dma;
266 		cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
267 
268 		if ((rc = mpt_config(ioc, &cfg)) == 0) {
269 			ppage0_alloc->PortIdentifier =
270 				le32_to_cpu(ppage0_alloc->PortIdentifier);
271 
272 			ppage0_alloc->WWNN.Low =
273 				le32_to_cpu(ppage0_alloc->WWNN.Low);
274 
275 			ppage0_alloc->WWNN.High =
276 				le32_to_cpu(ppage0_alloc->WWNN.High);
277 
278 			ppage0_alloc->WWPN.Low =
279 				le32_to_cpu(ppage0_alloc->WWPN.Low);
280 
281 			ppage0_alloc->WWPN.High =
282 				le32_to_cpu(ppage0_alloc->WWPN.High);
283 
284 			ppage0_alloc->BBCredit =
285 				le16_to_cpu(ppage0_alloc->BBCredit);
286 
287 			ppage0_alloc->MaxRxFrameSize =
288 				le16_to_cpu(ppage0_alloc->MaxRxFrameSize);
289 
290 			port_id = ppage0_alloc->PortIdentifier;
291 			num_targ++;
292 			*p_p0 = *ppage0_alloc;	/* save data */
293 			*p_pp0++ = p_p0++;	/* save addr */
294 		}
295 		pci_free_consistent(ioc->pcidev, data_sz,
296 		    			(u8 *) ppage0_alloc, page0_dma);
297 		if (rc != 0)
298 			break;
299 
300 	} while (port_id <= 0xff0000);
301 
302 	if (num_targ) {
303 		/* sort array */
304 		if (num_targ > 1)
305 			sort (pp0_array, num_targ, sizeof(FCDevicePage0_t *),
306 				mptfc_FcDevPage0_cmp_func, NULL);
307 		/* call caller's func for each targ */
308 		for (ii = 0; ii < num_targ;  ii++) {
309 			fc = *(pp0_array+ii);
310 			func(ioc, ioc_port, fc);
311 		}
312 	}
313 
314  out:
315 	if (pp0_array)
316 		kfree(pp0_array);
317 	if (p0_array)
318 		kfree(p0_array);
319 	return rc;
320 }
321 
322 static int
323 mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid)
324 {
325 	/* not currently usable */
326 	if (pg0->Flags & (MPI_FC_DEVICE_PAGE0_FLAGS_PLOGI_INVALID |
327 			  MPI_FC_DEVICE_PAGE0_FLAGS_PRLI_INVALID))
328 		return -1;
329 
330 	if (!(pg0->Flags & MPI_FC_DEVICE_PAGE0_FLAGS_TARGETID_BUS_VALID))
331 		return -1;
332 
333 	if (!(pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_TARGET))
334 		return -1;
335 
336 	/*
337 	 * board data structure already normalized to platform endianness
338 	 * shifted to avoid unaligned access on 64 bit architecture
339 	 */
340 	rid->node_name = ((u64)pg0->WWNN.High) << 32 | (u64)pg0->WWNN.Low;
341 	rid->port_name = ((u64)pg0->WWPN.High) << 32 | (u64)pg0->WWPN.Low;
342 	rid->port_id =   pg0->PortIdentifier;
343 	rid->roles = FC_RPORT_ROLE_UNKNOWN;
344 	rid->roles |= FC_RPORT_ROLE_FCP_TARGET;
345 	if (pg0->Protocol & MPI_FC_DEVICE_PAGE0_PROT_FCP_INITIATOR)
346 		rid->roles |= FC_RPORT_ROLE_FCP_INITIATOR;
347 
348 	return 0;
349 }
350 
351 static void
352 mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
353 {
354 	struct fc_rport_identifiers rport_ids;
355 	struct fc_rport		*rport;
356 	struct mptfc_rport_info	*ri;
357 	int			new_ri = 1;
358 	u64			pn;
359 	unsigned long		flags;
360 	VirtTarget		*vtarget;
361 
362 	if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
363 		return;
364 
365 	/* scan list looking for a match */
366 	spin_lock_irqsave(&ioc->fc_rport_lock, flags);
367 	list_for_each_entry(ri, &ioc->fc_rports, list) {
368 		pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
369 		if (pn == rport_ids.port_name) {	/* match */
370 			list_move_tail(&ri->list, &ioc->fc_rports);
371 			new_ri = 0;
372 			break;
373 		}
374 	}
375 	if (new_ri) {	/* allocate one */
376 		spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
377 		ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
378 		if (!ri)
379 			return;
380 		spin_lock_irqsave(&ioc->fc_rport_lock, flags);
381 		list_add_tail(&ri->list, &ioc->fc_rports);
382 	}
383 
384 	ri->pg0 = *pg0;	/* add/update pg0 data */
385 	ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING;
386 
387 	/* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
388 	if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
389 		ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
390 		spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
391 		rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
392 		spin_lock_irqsave(&ioc->fc_rport_lock, flags);
393 		if (rport) {
394 			ri->rport = rport;
395 			if (new_ri) /* may have been reset by user */
396 				rport->dev_loss_tmo = mptfc_dev_loss_tmo;
397 			*((struct mptfc_rport_info **)rport->dd_data) = ri;
398 			/*
399 			 * if already mapped, remap here.  If not mapped,
400 			 * target_alloc will allocate vtarget and map,
401 			 * slave_alloc will fill in vdev from vtarget.
402 			 */
403 			if (ri->starget) {
404 				vtarget = ri->starget->hostdata;
405 				if (vtarget) {
406 					vtarget->target_id = pg0->CurrentTargetID;
407 					vtarget->bus_id = pg0->CurrentBus;
408 				}
409 				ri->remap_needed = 0;
410 			}
411 			dfcprintk ((MYIOC_s_INFO_FMT
412 				"mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
413 				"rport tid %d, tmo %d\n",
414 					ioc->name,
415 					ioc->sh->host_no,
416 					pg0->PortIdentifier,
417 					pg0->WWNN,
418 					pg0->WWPN,
419 					pg0->CurrentTargetID,
420 					ri->rport->scsi_target_id,
421 					ri->rport->dev_loss_tmo));
422 		} else {
423 			list_del(&ri->list);
424 			kfree(ri);
425 			ri = NULL;
426 		}
427 	}
428 	spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
429 
430 }
431 
432 /*
433  *	OS entry point to allow for host driver to free allocated memory
434  *	Called if no device present or device being unloaded
435  */
436 static void
437 mptfc_target_destroy(struct scsi_target *starget)
438 {
439 	struct fc_rport		*rport;
440 	struct mptfc_rport_info *ri;
441 
442 	rport = starget_to_rport(starget);
443 	if (rport) {
444 		ri = *((struct mptfc_rport_info **)rport->dd_data);
445 		if (ri)	/* better be! */
446 			ri->starget = NULL;
447 	}
448 	if (starget->hostdata)
449 		kfree(starget->hostdata);
450 	starget->hostdata = NULL;
451 }
452 
453 /*
454  *	OS entry point to allow host driver to alloc memory
455  *	for each scsi target. Called once per device the bus scan.
456  *	Return non-zero if allocation fails.
457  */
458 static int
459 mptfc_target_alloc(struct scsi_target *starget)
460 {
461 	VirtTarget		*vtarget;
462 	struct fc_rport		*rport;
463 	struct mptfc_rport_info *ri;
464 	int			rc;
465 
466 	vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
467 	if (!vtarget)
468 		return -ENOMEM;
469 	starget->hostdata = vtarget;
470 
471 	rc = -ENODEV;
472 	rport = starget_to_rport(starget);
473 	if (rport) {
474 		ri = *((struct mptfc_rport_info **)rport->dd_data);
475 		if (ri) {	/* better be! */
476 			vtarget->target_id = ri->pg0.CurrentTargetID;
477 			vtarget->bus_id = ri->pg0.CurrentBus;
478 			ri->starget = starget;
479 			ri->remap_needed = 0;
480 			rc = 0;
481 		}
482 	}
483 	if (rc != 0) {
484 		kfree(vtarget);
485 		starget->hostdata = NULL;
486 	}
487 
488 	return rc;
489 }
490 
491 /*
492  *	OS entry point to allow host driver to alloc memory
493  *	for each scsi device. Called once per device the bus scan.
494  *	Return non-zero if allocation fails.
495  *	Init memory once per LUN.
496  */
497 static int
498 mptfc_slave_alloc(struct scsi_device *sdev)
499 {
500 	MPT_SCSI_HOST		*hd;
501 	VirtTarget		*vtarget;
502 	VirtDevice		*vdev;
503 	struct scsi_target	*starget;
504 	struct fc_rport		*rport;
505 	unsigned long		flags;
506 
507 
508 	rport = starget_to_rport(scsi_target(sdev));
509 
510 	if (!rport || fc_remote_port_chkready(rport))
511 		return -ENXIO;
512 
513 	hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
514 
515 	vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
516 	if (!vdev) {
517 		printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
518 				hd->ioc->name, sizeof(VirtDevice));
519 		return -ENOMEM;
520 	}
521 
522 	spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
523 
524 	sdev->hostdata = vdev;
525 	starget = scsi_target(sdev);
526 	vtarget = starget->hostdata;
527 
528 	if (vtarget->num_luns == 0) {
529 		vtarget->ioc_id = hd->ioc->id;
530 		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
531 		    		  MPT_TARGET_FLAGS_VALID_INQUIRY;
532 		hd->Targets[sdev->id] = vtarget;
533 	}
534 
535 	vdev->vtarget = vtarget;
536 	vdev->lun = sdev->lun;
537 
538 	spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
539 
540 	vtarget->num_luns++;
541 
542 #ifdef DMPT_DEBUG_FC
543 	 {
544 	struct mptfc_rport_info *ri;
545 	ri = *((struct mptfc_rport_info **)rport->dd_data);
546 	dfcprintk ((MYIOC_s_INFO_FMT
547 		"mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
548 	        "CurrentTargetID %d, %x %llx %llx\n",
549 		hd->ioc->name,
550 		sdev->host->host_no,
551 		vtarget->num_luns,
552 		sdev->id, ri->pg0.CurrentTargetID,
553 		ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN));
554 	}
555 #endif
556 
557 	return 0;
558 }
559 
560 static int
561 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
562 {
563 	struct mptfc_rport_info	*ri;
564 	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
565 	int		err;
566 
567 	err = fc_remote_port_chkready(rport);
568 	if (unlikely(err)) {
569 		SCpnt->result = err;
570 		done(SCpnt);
571 		return 0;
572 	}
573 	ri = *((struct mptfc_rport_info **)rport->dd_data);
574 	if (unlikely(ri->remap_needed))
575 		return SCSI_MLQUEUE_HOST_BUSY;
576 
577 	return mptscsih_qcmd(SCpnt,done);
578 }
579 
580 static void
581 mptfc_init_host_attr(MPT_ADAPTER *ioc,int portnum)
582 {
583 	unsigned class = 0, cos = 0;
584 
585 	/* don't know what to do as only one scsi (fc) host was allocated */
586 	if (portnum != 0)
587 		return;
588 
589 	class = ioc->fc_port_page0[portnum].SupportedServiceClass;
590 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_1)
591 		cos |= FC_COS_CLASS1;
592 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_2)
593 		cos |= FC_COS_CLASS2;
594 	if (class & MPI_FCPORTPAGE0_SUPPORT_CLASS_3)
595 		cos |= FC_COS_CLASS3;
596 
597 	fc_host_node_name(ioc->sh) =
598 	    	(u64)ioc->fc_port_page0[portnum].WWNN.High << 32
599 		    | (u64)ioc->fc_port_page0[portnum].WWNN.Low;
600 
601 	fc_host_port_name(ioc->sh) =
602 	    	(u64)ioc->fc_port_page0[portnum].WWPN.High << 32
603 		    | (u64)ioc->fc_port_page0[portnum].WWPN.Low;
604 
605 	fc_host_port_id(ioc->sh) = ioc->fc_port_page0[portnum].PortIdentifier;
606 
607 	fc_host_supported_classes(ioc->sh) = cos;
608 
609 	fc_host_tgtid_bind_type(ioc->sh) = FC_TGTID_BIND_BY_WWPN;
610 }
611 
612 static void
613 mptfc_rescan_devices(void *arg)
614 {
615 	MPT_ADAPTER		*ioc = (MPT_ADAPTER *)arg;
616 	int			ii;
617 	int			work_to_do;
618 	unsigned long		flags;
619 	struct mptfc_rport_info *ri;
620 
621 	do {
622 		/* start by tagging all ports as missing */
623 		spin_lock_irqsave(&ioc->fc_rport_lock,flags);
624 		list_for_each_entry(ri, &ioc->fc_rports, list) {
625 			if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
626 				ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
627 			}
628 		}
629 		spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
630 
631 		/*
632 		 * now rescan devices known to adapter,
633 		 * will reregister existing rports
634 		 */
635 		for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
636 			(void) mptbase_GetFcPortPage0(ioc, ii);
637 			mptfc_init_host_attr(ioc,ii);	/* refresh */
638 			mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
639 		}
640 
641 		/* delete devices still missing */
642 		spin_lock_irqsave(&ioc->fc_rport_lock, flags);
643 		list_for_each_entry(ri, &ioc->fc_rports, list) {
644 			/* if newly missing, delete it */
645 			if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED |
646 					  MPT_RPORT_INFO_FLAGS_MISSING))
647 			  == (MPT_RPORT_INFO_FLAGS_REGISTERED |
648 			      MPT_RPORT_INFO_FLAGS_MISSING)) {
649 
650 				ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
651 					       MPT_RPORT_INFO_FLAGS_MISSING);
652 				ri->remap_needed = 1;
653 				fc_remote_port_delete(ri->rport);
654 				/*
655 				 * remote port not really deleted 'cause
656 				 * binding is by WWPN and driver only
657 				 * registers FCP_TARGETs but cannot trust
658 				 * data structures.
659 				 */
660 				ri->rport = NULL;
661 				dfcprintk ((MYIOC_s_INFO_FMT
662 					"mptfc_rescan.%d: %llx deleted\n",
663 					ioc->name,
664 					ioc->sh->host_no,
665 					ri->pg0.WWPN));
666 			}
667 		}
668 		spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
669 
670 		/*
671 		 * allow multiple passes as target state
672 		 * might have changed during scan
673 		 */
674 		spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
675 		if (ioc->fc_rescan_work_count > 2) 	/* only need one more */
676 			ioc->fc_rescan_work_count = 2;
677 		work_to_do = --ioc->fc_rescan_work_count;
678 		spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
679 	} while (work_to_do);
680 }
681 
682 static int
683 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
684 {
685 	struct Scsi_Host	*sh;
686 	MPT_SCSI_HOST		*hd;
687 	MPT_ADAPTER 		*ioc;
688 	unsigned long		 flags;
689 	int			 ii;
690 	int			 numSGE = 0;
691 	int			 scale;
692 	int			 ioc_cap;
693 	int			error=0;
694 	int			r;
695 
696 	if ((r = mpt_attach(pdev,id)) != 0)
697 		return r;
698 
699 	ioc = pci_get_drvdata(pdev);
700 	ioc->DoneCtx = mptfcDoneCtx;
701 	ioc->TaskCtx = mptfcTaskCtx;
702 	ioc->InternalCtx = mptfcInternalCtx;
703 
704 	/*  Added sanity check on readiness of the MPT adapter.
705 	 */
706 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
707 		printk(MYIOC_s_WARN_FMT
708 		  "Skipping because it's not operational!\n",
709 		  ioc->name);
710 		error = -ENODEV;
711 		goto out_mptfc_probe;
712 	}
713 
714 	if (!ioc->active) {
715 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
716 		  ioc->name);
717 		error = -ENODEV;
718 		goto out_mptfc_probe;
719 	}
720 
721 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
722 	 */
723 	ioc_cap = 0;
724 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
725 		if (ioc->pfacts[ii].ProtocolFlags &
726 		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
727 			ioc_cap ++;
728 	}
729 
730 	if (!ioc_cap) {
731 		printk(MYIOC_s_WARN_FMT
732 			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
733 			ioc->name, ioc);
734 		return -ENODEV;
735 	}
736 
737 	sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
738 
739 	if (!sh) {
740 		printk(MYIOC_s_WARN_FMT
741 			"Unable to register controller with SCSI subsystem\n",
742 			ioc->name);
743 		error = -1;
744 		goto out_mptfc_probe;
745         }
746 
747 	INIT_WORK(&ioc->fc_rescan_work, mptfc_rescan_devices,(void *)ioc);
748 
749 	spin_lock_irqsave(&ioc->FreeQlock, flags);
750 
751 	/* Attach the SCSI Host to the IOC structure
752 	 */
753 	ioc->sh = sh;
754 
755 	sh->io_port = 0;
756 	sh->n_io_port = 0;
757 	sh->irq = 0;
758 
759 	/* set 16 byte cdb's */
760 	sh->max_cmd_len = 16;
761 
762 	sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
763 
764 	sh->max_lun = MPT_LAST_LUN + 1;
765 	sh->max_channel = 0;
766 	sh->this_id = ioc->pfacts[0].PortSCSIID;
767 
768 	/* Required entry.
769 	 */
770 	sh->unique_id = ioc->id;
771 
772 	/* Verify that we won't exceed the maximum
773 	 * number of chain buffers
774 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
775 	 * For 32bit SGE's:
776 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
777 	 *               + (req_sz - 64)/sizeof(SGE)
778 	 * A slightly different algorithm is required for
779 	 * 64bit SGEs.
780 	 */
781 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
782 	if (sizeof(dma_addr_t) == sizeof(u64)) {
783 		numSGE = (scale - 1) *
784 		  (ioc->facts.MaxChainDepth-1) + scale +
785 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
786 		  sizeof(u32));
787 	} else {
788 		numSGE = 1 + (scale - 1) *
789 		  (ioc->facts.MaxChainDepth-1) + scale +
790 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
791 		  sizeof(u32));
792 	}
793 
794 	if (numSGE < sh->sg_tablesize) {
795 		/* Reset this value */
796 		dprintk((MYIOC_s_INFO_FMT
797 		  "Resetting sg_tablesize to %d from %d\n",
798 		  ioc->name, numSGE, sh->sg_tablesize));
799 		sh->sg_tablesize = numSGE;
800 	}
801 
802 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
803 
804 	hd = (MPT_SCSI_HOST *) sh->hostdata;
805 	hd->ioc = ioc;
806 
807 	/* SCSI needs scsi_cmnd lookup table!
808 	 * (with size equal to req_depth*PtrSz!)
809 	 */
810 	hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
811 	if (!hd->ScsiLookup) {
812 		error = -ENOMEM;
813 		goto out_mptfc_probe;
814 	}
815 
816 	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
817 		 ioc->name, hd->ScsiLookup));
818 
819 	/* Allocate memory for the device structures.
820 	 * A non-Null pointer at an offset
821 	 * indicates a device exists.
822 	 * max_id = 1 + maximum id (hosts.h)
823 	 */
824 	hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
825 	if (!hd->Targets) {
826 		error = -ENOMEM;
827 		goto out_mptfc_probe;
828 	}
829 
830 	dprintk((KERN_INFO "  vdev @ %p\n", hd->Targets));
831 
832 	/* Clear the TM flags
833 	 */
834 	hd->tmPending = 0;
835 	hd->tmState = TM_STATE_NONE;
836 	hd->resetPending = 0;
837 	hd->abortSCpnt = NULL;
838 
839 	/* Clear the pointer used to store
840 	 * single-threaded commands, i.e., those
841 	 * issued during a bus scan, dv and
842 	 * configuration pages.
843 	 */
844 	hd->cmdPtr = NULL;
845 
846 	/* Initialize this SCSI Hosts' timers
847 	 * To use, set the timer expires field
848 	 * and add_timer
849 	 */
850 	init_timer(&hd->timer);
851 	hd->timer.data = (unsigned long) hd;
852 	hd->timer.function = mptscsih_timer_expired;
853 
854 	hd->mpt_pq_filter = mpt_pq_filter;
855 
856 	ddvprintk((MYIOC_s_INFO_FMT
857 		"mpt_pq_filter %x\n",
858 		ioc->name,
859 		mpt_pq_filter));
860 
861 	init_waitqueue_head(&hd->scandv_waitq);
862 	hd->scandv_wait_done = 0;
863 	hd->last_queue_full = 0;
864 
865 	sh->transportt = mptfc_transport_template;
866 	error = scsi_add_host (sh, &ioc->pcidev->dev);
867 	if(error) {
868 		dprintk((KERN_ERR MYNAM
869 		  "scsi_add_host failed\n"));
870 		goto out_mptfc_probe;
871 	}
872 
873 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
874 		mptfc_init_host_attr(ioc,ii);
875 		mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev);
876 	}
877 
878 	return 0;
879 
880 out_mptfc_probe:
881 
882 	mptscsih_remove(pdev);
883 	return error;
884 }
885 
886 static struct pci_driver mptfc_driver = {
887 	.name		= "mptfc",
888 	.id_table	= mptfc_pci_table,
889 	.probe		= mptfc_probe,
890 	.remove		= __devexit_p(mptfc_remove),
891 	.shutdown	= mptscsih_shutdown,
892 #ifdef CONFIG_PM
893 	.suspend	= mptscsih_suspend,
894 	.resume		= mptscsih_resume,
895 #endif
896 };
897 
898 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
899 /**
900  *	mptfc_init - Register MPT adapter(s) as SCSI host(s) with
901  *	linux scsi mid-layer.
902  *
903  *	Returns 0 for success, non-zero for failure.
904  */
905 static int __init
906 mptfc_init(void)
907 {
908 	int error;
909 
910 	show_mptmod_ver(my_NAME, my_VERSION);
911 
912 	/* sanity check module parameter */
913 	if (mptfc_dev_loss_tmo == 0)
914 		mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;
915 
916 	mptfc_transport_template =
917 		fc_attach_transport(&mptfc_transport_functions);
918 
919 	if (!mptfc_transport_template)
920 		return -ENODEV;
921 
922 	mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
923 	mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
924 	mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
925 
926 	if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
927 		devtverboseprintk((KERN_INFO MYNAM
928 		  ": Registered for IOC event notifications\n"));
929 	}
930 
931 	if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
932 		dprintk((KERN_INFO MYNAM
933 		  ": Registered for IOC reset notifications\n"));
934 	}
935 
936 	error = pci_register_driver(&mptfc_driver);
937 	if (error)
938 		fc_release_transport(mptfc_transport_template);
939 
940 	return error;
941 }
942 
943 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
944 /**
945  *	mptfc_remove - Removed fc infrastructure for devices
946  *	@pdev: Pointer to pci_dev structure
947  *
948  */
949 static void __devexit
950 mptfc_remove(struct pci_dev *pdev)
951 {
952 	MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
953 	struct mptfc_rport_info *p, *n;
954 
955 	fc_remove_host(ioc->sh);
956 
957 	list_for_each_entry_safe(p, n, &ioc->fc_rports, list) {
958 		list_del(&p->list);
959 		kfree(p);
960 	}
961 
962 	mptscsih_remove(pdev);
963 }
964 
965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
966 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
967 /**
968  *	mptfc_exit - Unregisters MPT adapter(s)
969  *
970  */
971 static void __exit
972 mptfc_exit(void)
973 {
974 	pci_unregister_driver(&mptfc_driver);
975 	fc_release_transport(mptfc_transport_template);
976 
977 	mpt_reset_deregister(mptfcDoneCtx);
978 	dprintk((KERN_INFO MYNAM
979 	  ": Deregistered for IOC reset notifications\n"));
980 
981 	mpt_event_deregister(mptfcDoneCtx);
982 	dprintk((KERN_INFO MYNAM
983 	  ": Deregistered for IOC event notifications\n"));
984 
985 	mpt_deregister(mptfcInternalCtx);
986 	mpt_deregister(mptfcTaskCtx);
987 	mpt_deregister(mptfcDoneCtx);
988 }
989 
990 module_init(mptfc_init);
991 module_exit(mptfc_exit);
992