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