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