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