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.
6 * Copyright (c) 1999-2005 LSI Logic Corporation
7 * (mailto:mpt_linux_developer@lsil.com)
10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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>
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>
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT SPI Host driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptspi"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
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)");
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)");
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)");
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)");
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)");
101 static int mptspiDoneCtx = -1;
102 static int mptspiTaskCtx = -1;
103 static int mptspiInternalCtx = -1; /* Used only for internal commands */
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,
125 .sg_tablesize = MPT_SCSI_SG_DEPTH,
128 .use_clustering = ENABLE_CLUSTERING,
132 /****************************************************************************
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 */
143 MODULE_DEVICE_TABLE(pci, mptspi_pci_table);
145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
148 * mptspi_probe - Installs scsi devices per bus.
149 * @pdev: Pointer to pci_dev structure
151 * Returns 0 for success, non-zero for failure.
155 mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
157 struct Scsi_Host *sh;
169 if ((r = mpt_attach(pdev,id)) != 0)
172 ioc = pci_get_drvdata(pdev);
173 ioc->DoneCtx = mptspiDoneCtx;
174 ioc->TaskCtx = mptspiTaskCtx;
175 ioc->InternalCtx = mptspiInternalCtx;
177 /* Added sanity check on readiness of the MPT adapter.
179 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
180 printk(MYIOC_s_WARN_FMT
181 "Skipping because it's not operational!\n",
184 goto out_mptspi_probe;
188 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
191 goto out_mptspi_probe;
194 /* Sanity check - ensure at least 1 port is INITIATOR capable
197 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
198 if (ioc->pfacts[ii].ProtocolFlags &
199 MPI_PORTFACTS_PROTOCOL_INITIATOR)
204 printk(MYIOC_s_WARN_FMT
205 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
210 sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
213 printk(MYIOC_s_WARN_FMT
214 "Unable to register controller with SCSI subsystem\n",
217 goto out_mptspi_probe;
220 spin_lock_irqsave(&ioc->FreeQlock, flags);
222 /* Attach the SCSI Host to the IOC structure
230 /* set 16 byte cdb's */
231 sh->max_cmd_len = 16;
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,
243 sh->max_id = MPT_MAX_SCSI_DEVICES;
245 sh->max_lun = MPT_LAST_LUN + 1;
247 sh->this_id = ioc->pfacts[0].PortSCSIID;
251 sh->unique_id = ioc->id;
253 /* Verify that we won't exceed the maximum
254 * number of chain buffers
255 * We can optimize: ZZ = req_sz/sizeof(SGE)
257 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
258 * + (req_sz - 64)/sizeof(SGE)
259 * A slightly different algorithm is required for
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) +
269 numSGE = 1 + (scale - 1) *
270 (ioc->facts.MaxChainDepth-1) + scale +
271 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
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;
283 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
285 hd = (MPT_SCSI_HOST *) sh->hostdata;
288 /* SCSI needs scsi_cmnd lookup table!
289 * (with size equal to req_depth*PtrSz!)
291 sz = ioc->req_depth * sizeof(void *);
292 mem = kmalloc(sz, GFP_ATOMIC);
295 goto out_mptspi_probe;
299 hd->ScsiLookup = (struct scsi_cmnd **) mem;
301 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
302 ioc->name, hd->ScsiLookup, sz));
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)
309 sz = sh->max_id * sizeof(void *);
310 mem = kmalloc(sz, GFP_ATOMIC);
313 goto out_mptspi_probe;
317 hd->Targets = (VirtTarget **) mem;
320 " vdev @ %p, sz=%d\n", hd->Targets, sz));
322 /* Clear the TM flags
325 hd->tmState = TM_STATE_NONE;
326 hd->resetPending = 0;
327 hd->abortSCpnt = NULL;
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.
336 /* Initialize this SCSI Hosts' timers
337 * To use, set the timer expires field
340 init_timer(&hd->timer);
341 hd->timer.data = (unsigned long) hd;
342 hd->timer.function = mptscsih_timer_expired;
344 ioc->spi_data.Saf_Te = mpt_saf_te;
345 hd->mpt_pq_filter = mpt_pq_filter;
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;
355 ioc->spi_data.mpt_dv = mpt_dv;
358 ddvprintk((MYIOC_s_INFO_FMT
359 "dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
367 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
368 ddvprintk((MYIOC_s_INFO_FMT
369 "saf_te %x mpt_pq_filter %x\n",
375 ioc->spi_data.forceDv = 0;
376 ioc->spi_data.noQas = 0;
378 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
379 ioc->spi_data.dvStatus[ii] =
380 MPT_SCSICFG_NEGOTIATE;
382 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
383 ioc->spi_data.dvStatus[ii] |=
384 MPT_SCSICFG_DV_NOT_DONE;
386 init_waitqueue_head(&hd->scandv_waitq);
387 hd->scandv_wait_done = 0;
388 hd->last_queue_full = 0;
390 error = scsi_add_host (sh, &ioc->pcidev->dev);
392 dprintk((KERN_ERR MYNAM
393 "scsi_add_host failed\n"));
394 goto out_mptspi_probe;
402 mptscsih_remove(pdev);
406 static struct pci_driver mptspi_driver = {
408 .id_table = mptspi_pci_table,
409 .probe = mptspi_probe,
410 .remove = __devexit_p(mptscsih_remove),
411 .shutdown = mptscsih_shutdown,
413 .suspend = mptscsih_suspend,
414 .resume = mptscsih_resume,
418 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
420 * mptspi_init - Register MPT adapter(s) as SCSI host(s) with
421 * linux scsi mid-layer.
423 * Returns 0 for success, non-zero for failure.
429 show_mptmod_ver(my_NAME, my_VERSION);
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);
435 if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) {
436 devtprintk((KERN_INFO MYNAM
437 ": Registered for IOC event notifications\n"));
440 if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) {
441 dprintk((KERN_INFO MYNAM
442 ": Registered for IOC reset notifications\n"));
445 return pci_register_driver(&mptspi_driver);
448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
451 * mptspi_exit - Unregisters MPT adapter(s)
457 pci_unregister_driver(&mptspi_driver);
459 mpt_reset_deregister(mptspiDoneCtx);
460 dprintk((KERN_INFO MYNAM
461 ": Deregistered for IOC reset notifications\n"));
463 mpt_event_deregister(mptspiDoneCtx);
464 dprintk((KERN_INFO MYNAM
465 ": Deregistered for IOC event notifications\n"));
467 mpt_deregister(mptspiInternalCtx);
468 mpt_deregister(mptspiTaskCtx);
469 mpt_deregister(mptspiDoneCtx);
472 module_init(mptspi_init);
473 module_exit(mptspi_exit);