Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[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         .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);