Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-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                      ii;
162         int                      numSGE = 0;
163         int                      scale;
164         int                      ioc_cap;
165         int                     error=0;
166         int                     r;
167
168         if ((r = mpt_attach(pdev,id)) != 0)
169                 return r;
170
171         ioc = pci_get_drvdata(pdev);
172         ioc->DoneCtx = mptspiDoneCtx;
173         ioc->TaskCtx = mptspiTaskCtx;
174         ioc->InternalCtx = mptspiInternalCtx;
175
176         /*  Added sanity check on readiness of the MPT adapter.
177          */
178         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
179                 printk(MYIOC_s_WARN_FMT
180                   "Skipping because it's not operational!\n",
181                   ioc->name);
182                 error = -ENODEV;
183                 goto out_mptspi_probe;
184         }
185
186         if (!ioc->active) {
187                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
188                   ioc->name);
189                 error = -ENODEV;
190                 goto out_mptspi_probe;
191         }
192
193         /*  Sanity check - ensure at least 1 port is INITIATOR capable
194          */
195         ioc_cap = 0;
196         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
197                 if (ioc->pfacts[ii].ProtocolFlags &
198                     MPI_PORTFACTS_PROTOCOL_INITIATOR)
199                         ioc_cap ++;
200         }
201
202         if (!ioc_cap) {
203                 printk(MYIOC_s_WARN_FMT
204                         "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
205                         ioc->name, ioc);
206                 return 0;
207         }
208
209         sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST));
210
211         if (!sh) {
212                 printk(MYIOC_s_WARN_FMT
213                         "Unable to register controller with SCSI subsystem\n",
214                         ioc->name);
215                 error = -1;
216                 goto out_mptspi_probe;
217         }
218
219         spin_lock_irqsave(&ioc->FreeQlock, flags);
220
221         /* Attach the SCSI Host to the IOC structure
222          */
223         ioc->sh = sh;
224
225         sh->io_port = 0;
226         sh->n_io_port = 0;
227         sh->irq = 0;
228
229         /* set 16 byte cdb's */
230         sh->max_cmd_len = 16;
231
232         /* Yikes!  This is important!
233          * Otherwise, by default, linux
234          * only scans target IDs 0-7!
235          * pfactsN->MaxDevices unreliable
236          * (not supported in early
237          *      versions of the FW).
238          * max_id = 1 + actual max id,
239          * max_lun = 1 + actual last lun,
240          *      see hosts.h :o(
241          */
242         sh->max_id = MPT_MAX_SCSI_DEVICES;
243
244         sh->max_lun = MPT_LAST_LUN + 1;
245         sh->max_channel = 0;
246         sh->this_id = ioc->pfacts[0].PortSCSIID;
247
248         /* Required entry.
249          */
250         sh->unique_id = ioc->id;
251
252         /* Verify that we won't exceed the maximum
253          * number of chain buffers
254          * We can optimize:  ZZ = req_sz/sizeof(SGE)
255          * For 32bit SGE's:
256          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
257          *               + (req_sz - 64)/sizeof(SGE)
258          * A slightly different algorithm is required for
259          * 64bit SGEs.
260          */
261         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
262         if (sizeof(dma_addr_t) == sizeof(u64)) {
263                 numSGE = (scale - 1) *
264                   (ioc->facts.MaxChainDepth-1) + scale +
265                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
266                   sizeof(u32));
267         } else {
268                 numSGE = 1 + (scale - 1) *
269                   (ioc->facts.MaxChainDepth-1) + scale +
270                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
271                   sizeof(u32));
272         }
273
274         if (numSGE < sh->sg_tablesize) {
275                 /* Reset this value */
276                 dprintk((MYIOC_s_INFO_FMT
277                   "Resetting sg_tablesize to %d from %d\n",
278                   ioc->name, numSGE, sh->sg_tablesize));
279                 sh->sg_tablesize = numSGE;
280         }
281
282         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
283
284         hd = (MPT_SCSI_HOST *) sh->hostdata;
285         hd->ioc = ioc;
286
287         /* SCSI needs scsi_cmnd lookup table!
288          * (with size equal to req_depth*PtrSz!)
289          */
290         hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC);
291         if (!hd->ScsiLookup) {
292                 error = -ENOMEM;
293                 goto out_mptspi_probe;
294         }
295
296         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n",
297                  ioc->name, hd->ScsiLookup));
298
299         /* Allocate memory for the device structures.
300          * A non-Null pointer at an offset
301          * indicates a device exists.
302          * max_id = 1 + maximum id (hosts.h)
303          */
304         hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC);
305         if (!hd->Targets) {
306                 error = -ENOMEM;
307                 goto out_mptspi_probe;
308         }
309
310         dprintk((KERN_INFO "  vdev @ %p\n", hd->Targets));
311
312         /* Clear the TM flags
313          */
314         hd->tmPending = 0;
315         hd->tmState = TM_STATE_NONE;
316         hd->resetPending = 0;
317         hd->abortSCpnt = NULL;
318
319         /* Clear the pointer used to store
320          * single-threaded commands, i.e., those
321          * issued during a bus scan, dv and
322          * configuration pages.
323          */
324         hd->cmdPtr = NULL;
325
326         /* Initialize this SCSI Hosts' timers
327          * To use, set the timer expires field
328          * and add_timer
329          */
330         init_timer(&hd->timer);
331         hd->timer.data = (unsigned long) hd;
332         hd->timer.function = mptscsih_timer_expired;
333
334         ioc->spi_data.Saf_Te = mpt_saf_te;
335         hd->mpt_pq_filter = mpt_pq_filter;
336
337 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
338         if (ioc->spi_data.maxBusWidth > mpt_width)
339                 ioc->spi_data.maxBusWidth = mpt_width;
340         if (ioc->spi_data.minSyncFactor < mpt_factor)
341                 ioc->spi_data.minSyncFactor = mpt_factor;
342         if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
343                 ioc->spi_data.maxSyncOffset = 0;
344         }
345         ioc->spi_data.mpt_dv = mpt_dv;
346         hd->negoNvram = 0;
347
348         ddvprintk((MYIOC_s_INFO_FMT
349                 "dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n",
350                 ioc->name,
351                 mpt_dv,
352                 mpt_width,
353                 mpt_factor,
354                 mpt_saf_te,
355                 mpt_pq_filter));
356 #else
357         hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
358         ddvprintk((MYIOC_s_INFO_FMT
359                 "saf_te %x mpt_pq_filter %x\n",
360                 ioc->name,
361                 mpt_saf_te,
362                 mpt_pq_filter));
363 #endif
364
365         ioc->spi_data.forceDv = 0;
366         ioc->spi_data.noQas = 0;
367
368         for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
369                 ioc->spi_data.dvStatus[ii] =
370                   MPT_SCSICFG_NEGOTIATE;
371
372         for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
373                 ioc->spi_data.dvStatus[ii] |=
374                   MPT_SCSICFG_DV_NOT_DONE;
375
376         init_waitqueue_head(&hd->scandv_waitq);
377         hd->scandv_wait_done = 0;
378         hd->last_queue_full = 0;
379
380         error = scsi_add_host (sh, &ioc->pcidev->dev);
381         if(error) {
382                 dprintk((KERN_ERR MYNAM
383                   "scsi_add_host failed\n"));
384                 goto out_mptspi_probe;
385         }
386
387         /*
388          * issue internal bus reset
389          */
390         if (ioc->spi_data.bus_reset)
391                 mptscsih_TMHandler(hd,
392                     MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
393                     0, 0, 0, 0, 5);
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);