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