xref: /linux/drivers/message/fusion/mptspi.c (revision 60b2737de1b1ddfdb90f3ba622634eb49d6f3603)
1 /*
2  *  linux/drivers/message/fusion/mptspi.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 
47 #include "linux_compat.h"	/* linux-2.6 tweaks */
48 #include <linux/module.h>
49 #include <linux/kernel.h>
50 #include <linux/init.h>
51 #include <linux/errno.h>
52 #include <linux/kdev_t.h>
53 #include <linux/blkdev.h>
54 #include <linux/delay.h>	/* for mdelay */
55 #include <linux/interrupt.h>	/* needed for in_interrupt() proto */
56 #include <linux/reboot.h>	/* notifier code */
57 #include <linux/sched.h>
58 #include <linux/workqueue.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 
66 #include "mptbase.h"
67 #include "mptscsih.h"
68 
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME		"Fusion MPT SPI Host driver"
71 #define my_VERSION	MPT_LINUX_VERSION_COMMON
72 #define MYNAM		"mptspi"
73 
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 
78 /* Command line args */
79 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
80 static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
81 module_param(mpt_dv, int, 0);
82 MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
83 
84 static int mpt_width = MPTSCSIH_MAX_WIDTH;
85 module_param(mpt_width, int, 0);
86 MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
87 
88 static ushort mpt_factor = MPTSCSIH_MIN_SYNC;
89 module_param(mpt_factor, ushort, 0);
90 MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
91 #endif
92 
93 static int mpt_saf_te = MPTSCSIH_SAF_TE;
94 module_param(mpt_saf_te, int, 0);
95 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
96 
97 static int mpt_pq_filter = 0;
98 module_param(mpt_pq_filter, int, 0);
99 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
100 
101 static int	mptspiDoneCtx = -1;
102 static int	mptspiTaskCtx = -1;
103 static int	mptspiInternalCtx = -1; /* Used only for internal commands */
104 
105 static struct device_attribute mptspi_queue_depth_attr = {
106 	.attr = {
107 		.name = 	"queue_depth",
108 		.mode =		S_IWUSR,
109 	},
110 	.store = mptscsih_store_queue_depth,
111 };
112 
113 static struct device_attribute *mptspi_dev_attrs[] = {
114 	&mptspi_queue_depth_attr,
115 	NULL,
116 };
117 
118 static struct scsi_host_template mptspi_driver_template = {
119 	.proc_name			= "mptspi",
120 	.proc_info			= mptscsih_proc_info,
121 	.name				= "MPT SPI Host",
122 	.info				= mptscsih_info,
123 	.queuecommand			= mptscsih_qcmd,
124 	.slave_alloc			= mptscsih_slave_alloc,
125 	.slave_configure		= mptscsih_slave_configure,
126 	.slave_destroy			= mptscsih_slave_destroy,
127 	.eh_abort_handler		= mptscsih_abort,
128 	.eh_device_reset_handler	= mptscsih_dev_reset,
129 	.eh_bus_reset_handler		= mptscsih_bus_reset,
130 	.eh_host_reset_handler		= mptscsih_host_reset,
131 	.bios_param			= mptscsih_bios_param,
132 	.can_queue			= MPT_SCSI_CAN_QUEUE,
133 	.this_id			= -1,
134 	.sg_tablesize			= MPT_SCSI_SG_DEPTH,
135 	.max_sectors			= 8192,
136 	.cmd_per_lun			= 7,
137 	.use_clustering			= ENABLE_CLUSTERING,
138 	.sdev_attrs			= mptspi_dev_attrs,
139 };
140 
141 
142 /****************************************************************************
143  * Supported hardware
144  */
145 
146 static struct pci_device_id mptspi_pci_table[] = {
147 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030,
148 		PCI_ANY_ID, PCI_ANY_ID },
149 	{ PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035,
150 		PCI_ANY_ID, PCI_ANY_ID },
151 	{0}	/* Terminating entry */
152 };
153 MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
154 
155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
157 /*
158  *	mptspi_probe - Installs scsi devices per bus.
159  *	@pdev: Pointer to pci_dev structure
160  *
161  *	Returns 0 for success, non-zero for failure.
162  *
163  */
164 static int
165 mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
166 {
167 	struct Scsi_Host	*sh;
168 	MPT_SCSI_HOST		*hd;
169 	MPT_ADAPTER 		*ioc;
170 	unsigned long		 flags;
171 	int			 sz, ii;
172 	int			 numSGE = 0;
173 	int			 scale;
174 	int			 ioc_cap;
175 	u8			*mem;
176 	int			error=0;
177 	int			r;
178 
179 	if ((r = mpt_attach(pdev,id)) != 0)
180 		return r;
181 
182 	ioc = pci_get_drvdata(pdev);
183 	ioc->DoneCtx = mptspiDoneCtx;
184 	ioc->TaskCtx = mptspiTaskCtx;
185 	ioc->InternalCtx = mptspiInternalCtx;
186 
187 	/*  Added sanity check on readiness of the MPT adapter.
188 	 */
189 	if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
190 		printk(MYIOC_s_WARN_FMT
191 		  "Skipping because it's not operational!\n",
192 		  ioc->name);
193 		return -ENODEV;
194 	}
195 
196 	if (!ioc->active) {
197 		printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
198 		  ioc->name);
199 		return -ENODEV;
200 	}
201 
202 	/*  Sanity check - ensure at least 1 port is INITIATOR capable
203 	 */
204 	ioc_cap = 0;
205 	for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
206 		if (ioc->pfacts[ii].ProtocolFlags &
207 		    MPI_PORTFACTS_PROTOCOL_INITIATOR)
208 			ioc_cap ++;
209 	}
210 
211 	if (!ioc_cap) {
212 		printk(MYIOC_s_WARN_FMT
213 			"Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
214 			ioc->name, ioc);
215 		return -ENODEV;
216 	}
217 
218 	sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
219 
220 	if (!sh) {
221 		printk(MYIOC_s_WARN_FMT
222 			"Unable to register controller with SCSI subsystem\n",
223 			ioc->name);
224                 return -1;
225         }
226 
227 	spin_lock_irqsave(&ioc->FreeQlock, flags);
228 
229 	/* Attach the SCSI Host to the IOC structure
230 	 */
231 	ioc->sh = sh;
232 
233 	sh->io_port = 0;
234 	sh->n_io_port = 0;
235 	sh->irq = 0;
236 
237 	/* set 16 byte cdb's */
238 	sh->max_cmd_len = 16;
239 
240 	/* Yikes!  This is important!
241 	 * Otherwise, by default, linux
242 	 * only scans target IDs 0-7!
243 	 * pfactsN->MaxDevices unreliable
244 	 * (not supported in early
245 	 *	versions of the FW).
246 	 * max_id = 1 + actual max id,
247 	 * max_lun = 1 + actual last lun,
248 	 *	see hosts.h :o(
249 	 */
250 	sh->max_id = MPT_MAX_SCSI_DEVICES;
251 
252 	sh->max_lun = MPT_LAST_LUN + 1;
253 	sh->max_channel = 0;
254 	sh->this_id = ioc->pfacts[0].PortSCSIID;
255 
256 	/* Required entry.
257 	 */
258 	sh->unique_id = ioc->id;
259 
260 	/* Verify that we won't exceed the maximum
261 	 * number of chain buffers
262 	 * We can optimize:  ZZ = req_sz/sizeof(SGE)
263 	 * For 32bit SGE's:
264 	 *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
265 	 *               + (req_sz - 64)/sizeof(SGE)
266 	 * A slightly different algorithm is required for
267 	 * 64bit SGEs.
268 	 */
269 	scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
270 	if (sizeof(dma_addr_t) == sizeof(u64)) {
271 		numSGE = (scale - 1) *
272 		  (ioc->facts.MaxChainDepth-1) + scale +
273 		  (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
274 		  sizeof(u32));
275 	} else {
276 		numSGE = 1 + (scale - 1) *
277 		  (ioc->facts.MaxChainDepth-1) + scale +
278 		  (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
279 		  sizeof(u32));
280 	}
281 
282 	if (numSGE < sh->sg_tablesize) {
283 		/* Reset this value */
284 		dprintk((MYIOC_s_INFO_FMT
285 		  "Resetting sg_tablesize to %d from %d\n",
286 		  ioc->name, numSGE, sh->sg_tablesize));
287 		sh->sg_tablesize = numSGE;
288 	}
289 
290 	/* Set the pci device pointer in Scsi_Host structure.
291 	 */
292 	scsi_set_device(sh, &ioc->pcidev->dev);
293 
294 	spin_unlock_irqrestore(&ioc->FreeQlock, flags);
295 
296 	hd = (MPT_SCSI_HOST *) sh->hostdata;
297 	hd->ioc = ioc;
298 
299 	/* SCSI needs scsi_cmnd lookup table!
300 	 * (with size equal to req_depth*PtrSz!)
301 	 */
302 	sz = ioc->req_depth * sizeof(void *);
303 	mem = kmalloc(sz, GFP_ATOMIC);
304 	if (mem == NULL) {
305 		error = -ENOMEM;
306 		goto mptspi_probe_failed;
307 	}
308 
309 	memset(mem, 0, sz);
310 	hd->ScsiLookup = (struct scsi_cmnd **) mem;
311 
312 	dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
313 		 ioc->name, hd->ScsiLookup, sz));
314 
315 	/* Allocate memory for the device structures.
316 	 * A non-Null pointer at an offset
317 	 * indicates a device exists.
318 	 * max_id = 1 + maximum id (hosts.h)
319 	 */
320 	sz = sh->max_id * sizeof(void *);
321 	mem = kmalloc(sz, GFP_ATOMIC);
322 	if (mem == NULL) {
323 		error = -ENOMEM;
324 		goto mptspi_probe_failed;
325 	}
326 
327 	memset(mem, 0, sz);
328 	hd->Targets = (VirtDevice **) mem;
329 
330 	dprintk((KERN_INFO
331 	  "  Targets @ %p, sz=%d\n", hd->Targets, sz));
332 
333 	/* Clear the TM flags
334 	 */
335 	hd->tmPending = 0;
336 	hd->tmState = TM_STATE_NONE;
337 	hd->resetPending = 0;
338 	hd->abortSCpnt = NULL;
339 
340 	/* Clear the pointer used to store
341 	 * single-threaded commands, i.e., those
342 	 * issued during a bus scan, dv and
343 	 * configuration pages.
344 	 */
345 	hd->cmdPtr = NULL;
346 
347 	/* Initialize this SCSI Hosts' timers
348 	 * To use, set the timer expires field
349 	 * and add_timer
350 	 */
351 	init_timer(&hd->timer);
352 	hd->timer.data = (unsigned long) hd;
353 	hd->timer.function = mptscsih_timer_expired;
354 
355 	ioc->spi_data.Saf_Te = mpt_saf_te;
356 	hd->mpt_pq_filter = mpt_pq_filter;
357 
358 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
359 	if (ioc->spi_data.maxBusWidth > mpt_width)
360 		ioc->spi_data.maxBusWidth = mpt_width;
361 	if (ioc->spi_data.minSyncFactor < mpt_factor)
362 		ioc->spi_data.minSyncFactor = mpt_factor;
363 	if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
364 		ioc->spi_data.maxSyncOffset = 0;
365 	}
366 	ioc->spi_data.mpt_dv = mpt_dv;
367 	hd->negoNvram = 0;
368 
369 	ddvprintk((MYIOC_s_INFO_FMT
370 		"dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
371 		ioc->name,
372 		mpt_dv,
373 		mpt_width,
374 		mpt_factor,
375 		mpt_saf_te,
376 		mpt_pq_filter));
377 #else
378 	hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
379 	ddvprintk((MYIOC_s_INFO_FMT
380 		"saf_te %x mpt_pq_filter %x\n",
381 		ioc->name,
382 		mpt_saf_te,
383 		mpt_pq_filter));
384 #endif
385 
386 	ioc->spi_data.forceDv = 0;
387 	ioc->spi_data.noQas = 0;
388 
389 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
390 		ioc->spi_data.dvStatus[ii] =
391 		  MPT_SCSICFG_NEGOTIATE;
392 
393 	for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
394 		ioc->spi_data.dvStatus[ii] |=
395 		  MPT_SCSICFG_DV_NOT_DONE;
396 
397 	init_waitqueue_head(&hd->scandv_waitq);
398 	hd->scandv_wait_done = 0;
399 	hd->last_queue_full = 0;
400 
401 	error = scsi_add_host (sh, &ioc->pcidev->dev);
402 	if(error) {
403 		dprintk((KERN_ERR MYNAM
404 		  "scsi_add_host failed\n"));
405 		goto mptspi_probe_failed;
406 	}
407 
408 	scsi_scan_host(sh);
409 	return 0;
410 
411 mptspi_probe_failed:
412 
413 	mptscsih_remove(pdev);
414 	return error;
415 }
416 
417 static struct pci_driver mptspi_driver = {
418 	.name		= "mptspi",
419 	.id_table	= mptspi_pci_table,
420 	.probe		= mptspi_probe,
421 	.remove		= __devexit_p(mptscsih_remove),
422 	.driver         = {
423 		.shutdown = mptscsih_shutdown,
424         },
425 #ifdef CONFIG_PM
426 	.suspend	= mptscsih_suspend,
427 	.resume		= mptscsih_resume,
428 #endif
429 };
430 
431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
432 /**
433  *	mptspi_init - Register MPT adapter(s) as SCSI host(s) with
434  *	linux scsi mid-layer.
435  *
436  *	Returns 0 for success, non-zero for failure.
437  */
438 static int __init
439 mptspi_init(void)
440 {
441 
442 	show_mptmod_ver(my_NAME, my_VERSION);
443 
444 	mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER);
445 	mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER);
446 	mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER);
447 
448 	if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) {
449 		devtprintk((KERN_INFO MYNAM
450 		  ": Registered for IOC event notifications\n"));
451 	}
452 
453 	if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) {
454 		dprintk((KERN_INFO MYNAM
455 		  ": Registered for IOC reset notifications\n"));
456 	}
457 
458 	return pci_register_driver(&mptspi_driver);
459 }
460 
461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
463 /**
464  *	mptspi_exit - Unregisters MPT adapter(s)
465  *
466  */
467 static void __exit
468 mptspi_exit(void)
469 {
470 	pci_unregister_driver(&mptspi_driver);
471 
472 	mpt_reset_deregister(mptspiDoneCtx);
473 	dprintk((KERN_INFO MYNAM
474 	  ": Deregistered for IOC reset notifications\n"));
475 
476 	mpt_event_deregister(mptspiDoneCtx);
477 	dprintk((KERN_INFO MYNAM
478 	  ": Deregistered for IOC event notifications\n"));
479 
480 	mpt_deregister(mptspiInternalCtx);
481 	mpt_deregister(mptspiTaskCtx);
482 	mpt_deregister(mptspiDoneCtx);
483 }
484 
485 module_init(mptspi_init);
486 module_exit(mptspi_exit);
487