[SCSI] mptfusion - adding = THIS_MODULE
[safe/jmp/linux-2.6] / drivers / message / fusion / mptfc.c
1 /*
2  *  linux/drivers/message/fusion/mptfc.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 #include "linux_compat.h"       /* linux-2.6 tweaks */
47 #include <linux/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h>        /* for mdelay */
54 #include <linux/interrupt.h>    /* needed for in_interrupt() proto */
55 #include <linux/reboot.h>       /* notifier code */
56 #include <linux/sched.h>
57 #include <linux/workqueue.h>
58
59 #include <scsi/scsi.h>
60 #include <scsi/scsi_cmnd.h>
61 #include <scsi/scsi_device.h>
62 #include <scsi/scsi_host.h>
63 #include <scsi/scsi_tcq.h>
64
65 #include "mptbase.h"
66 #include "mptscsih.h"
67
68 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
69 #define my_NAME         "Fusion MPT FC Host driver"
70 #define my_VERSION      MPT_LINUX_VERSION_COMMON
71 #define MYNAM           "mptfc"
72
73 MODULE_AUTHOR(MODULEAUTHOR);
74 MODULE_DESCRIPTION(my_NAME);
75 MODULE_LICENSE("GPL");
76
77 /* Command line args */
78 static int mpt_pq_filter = 0;
79 module_param(mpt_pq_filter, int, 0);
80 MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
81
82 static int      mptfcDoneCtx = -1;
83 static int      mptfcTaskCtx = -1;
84 static int      mptfcInternalCtx = -1; /* Used only for internal commands */
85
86 static struct scsi_host_template mptfc_driver_template = {
87         .module                         = THIS_MODULE,
88         .proc_name                      = "mptfc",
89         .proc_info                      = mptscsih_proc_info,
90         .name                           = "MPT FC Host",
91         .info                           = mptscsih_info,
92         .queuecommand                   = mptscsih_qcmd,
93         .slave_alloc                    = mptscsih_slave_alloc,
94         .slave_configure                = mptscsih_slave_configure,
95         .slave_destroy                  = mptscsih_slave_destroy,
96         .change_queue_depth             = mptscsih_change_queue_depth,
97         .eh_abort_handler               = mptscsih_abort,
98         .eh_device_reset_handler        = mptscsih_dev_reset,
99         .eh_bus_reset_handler           = mptscsih_bus_reset,
100         .eh_host_reset_handler          = mptscsih_host_reset,
101         .bios_param                     = mptscsih_bios_param,
102         .can_queue                      = MPT_FC_CAN_QUEUE,
103         .this_id                        = -1,
104         .sg_tablesize                   = MPT_SCSI_SG_DEPTH,
105         .max_sectors                    = 8192,
106         .cmd_per_lun                    = 7,
107         .use_clustering                 = ENABLE_CLUSTERING,
108 };
109
110 /****************************************************************************
111  * Supported hardware
112  */
113
114 static struct pci_device_id mptfc_pci_table[] = {
115         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909,
116                 PCI_ANY_ID, PCI_ANY_ID },
117         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919,
118                 PCI_ANY_ID, PCI_ANY_ID },
119         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929,
120                 PCI_ANY_ID, PCI_ANY_ID },
121         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X,
122                 PCI_ANY_ID, PCI_ANY_ID },
123         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X,
124                 PCI_ANY_ID, PCI_ANY_ID },
125         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X,
126                 PCI_ANY_ID, PCI_ANY_ID },
127         { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X,
128                 PCI_ANY_ID, PCI_ANY_ID },
129         {0}     /* Terminating entry */
130 };
131 MODULE_DEVICE_TABLE(pci, mptfc_pci_table);
132
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
135 /*
136  *      mptfc_probe - Installs scsi devices per bus.
137  *      @pdev: Pointer to pci_dev structure
138  *
139  *      Returns 0 for success, non-zero for failure.
140  *
141  */
142 static int
143 mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
144 {
145         struct Scsi_Host        *sh;
146         MPT_SCSI_HOST           *hd;
147         MPT_ADAPTER             *ioc;
148         unsigned long            flags;
149         int                      sz, ii;
150         int                      numSGE = 0;
151         int                      scale;
152         int                      ioc_cap;
153         u8                      *mem;
154         int                     error=0;
155         int                     r;
156                 
157         if ((r = mpt_attach(pdev,id)) != 0)
158                 return r;
159         
160         ioc = pci_get_drvdata(pdev);
161         ioc->DoneCtx = mptfcDoneCtx;
162         ioc->TaskCtx = mptfcTaskCtx;
163         ioc->InternalCtx = mptfcInternalCtx;
164
165         /*  Added sanity check on readiness of the MPT adapter.
166          */
167         if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
168                 printk(MYIOC_s_WARN_FMT
169                   "Skipping because it's not operational!\n",
170                   ioc->name);
171                 return -ENODEV;
172         }
173
174         if (!ioc->active) {
175                 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
176                   ioc->name);
177                 return -ENODEV;
178         }
179
180         /*  Sanity check - ensure at least 1 port is INITIATOR capable
181          */
182         ioc_cap = 0;
183         for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
184                 if (ioc->pfacts[ii].ProtocolFlags &
185                     MPI_PORTFACTS_PROTOCOL_INITIATOR)
186                         ioc_cap ++;
187         }
188
189         if (!ioc_cap) {
190                 printk(MYIOC_s_WARN_FMT
191                         "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
192                         ioc->name, ioc);
193                 return 0;
194         }
195
196         sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST));
197
198         if (!sh) {
199                 printk(MYIOC_s_WARN_FMT
200                         "Unable to register controller with SCSI subsystem\n",
201                         ioc->name);
202                 return -1;
203         }
204
205         spin_lock_irqsave(&ioc->FreeQlock, flags);
206
207         /* Attach the SCSI Host to the IOC structure
208          */
209         ioc->sh = sh;
210
211         sh->io_port = 0;
212         sh->n_io_port = 0;
213         sh->irq = 0;
214
215         /* set 16 byte cdb's */
216         sh->max_cmd_len = 16;
217
218         sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
219
220         sh->max_lun = MPT_LAST_LUN + 1;
221         sh->max_channel = 0;
222         sh->this_id = ioc->pfacts[0].PortSCSIID;
223
224         /* Required entry.
225          */
226         sh->unique_id = ioc->id;
227
228         /* Verify that we won't exceed the maximum
229          * number of chain buffers
230          * We can optimize:  ZZ = req_sz/sizeof(SGE)
231          * For 32bit SGE's:
232          *  numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
233          *               + (req_sz - 64)/sizeof(SGE)
234          * A slightly different algorithm is required for
235          * 64bit SGEs.
236          */
237         scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
238         if (sizeof(dma_addr_t) == sizeof(u64)) {
239                 numSGE = (scale - 1) *
240                   (ioc->facts.MaxChainDepth-1) + scale +
241                   (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
242                   sizeof(u32));
243         } else {
244                 numSGE = 1 + (scale - 1) *
245                   (ioc->facts.MaxChainDepth-1) + scale +
246                   (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
247                   sizeof(u32));
248         }
249
250         if (numSGE < sh->sg_tablesize) {
251                 /* Reset this value */
252                 dprintk((MYIOC_s_INFO_FMT
253                   "Resetting sg_tablesize to %d from %d\n",
254                   ioc->name, numSGE, sh->sg_tablesize));
255                 sh->sg_tablesize = numSGE;
256         }
257
258         spin_unlock_irqrestore(&ioc->FreeQlock, flags);
259
260         hd = (MPT_SCSI_HOST *) sh->hostdata;
261         hd->ioc = ioc;
262
263         /* SCSI needs scsi_cmnd lookup table!
264          * (with size equal to req_depth*PtrSz!)
265          */
266         sz = ioc->req_depth * sizeof(void *);
267         mem = kmalloc(sz, GFP_ATOMIC);
268         if (mem == NULL) {
269                 error = -ENOMEM;
270                 goto mptfc_probe_failed;
271         }
272
273         memset(mem, 0, sz);
274         hd->ScsiLookup = (struct scsi_cmnd **) mem;
275
276         dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
277                  ioc->name, hd->ScsiLookup, sz));
278
279         /* Allocate memory for the device structures.
280          * A non-Null pointer at an offset
281          * indicates a device exists.
282          * max_id = 1 + maximum id (hosts.h)
283          */
284         sz = sh->max_id * sizeof(void *);
285         mem = kmalloc(sz, GFP_ATOMIC);
286         if (mem == NULL) {
287                 error = -ENOMEM;
288                 goto mptfc_probe_failed;
289         }
290
291         memset(mem, 0, sz);
292         hd->Targets = (VirtDevice **) mem;
293
294         dprintk((KERN_INFO
295           "  Targets @ %p, sz=%d\n", hd->Targets, sz));
296
297         /* Clear the TM flags
298          */
299         hd->tmPending = 0;
300         hd->tmState = TM_STATE_NONE;
301         hd->resetPending = 0;
302         hd->abortSCpnt = NULL;
303
304         /* Clear the pointer used to store
305          * single-threaded commands, i.e., those
306          * issued during a bus scan, dv and
307          * configuration pages.
308          */
309         hd->cmdPtr = NULL;
310
311         /* Initialize this SCSI Hosts' timers
312          * To use, set the timer expires field
313          * and add_timer
314          */
315         init_timer(&hd->timer);
316         hd->timer.data = (unsigned long) hd;
317         hd->timer.function = mptscsih_timer_expired;
318
319         hd->mpt_pq_filter = mpt_pq_filter;
320
321         ddvprintk((MYIOC_s_INFO_FMT
322                 "mpt_pq_filter %x\n",
323                 ioc->name, 
324                 mpt_pq_filter));
325
326         init_waitqueue_head(&hd->scandv_waitq);
327         hd->scandv_wait_done = 0;
328         hd->last_queue_full = 0;
329
330         error = scsi_add_host (sh, &ioc->pcidev->dev);
331         if(error) {
332                 dprintk((KERN_ERR MYNAM
333                   "scsi_add_host failed\n"));
334                 goto mptfc_probe_failed;
335         }
336
337         scsi_scan_host(sh);
338         return 0;
339
340 mptfc_probe_failed:
341
342         mptscsih_remove(pdev);
343         return error;
344 }
345
346 static struct pci_driver mptfc_driver = {
347         .name           = "mptfc",
348         .id_table       = mptfc_pci_table,
349         .probe          = mptfc_probe,
350         .remove         = __devexit_p(mptscsih_remove),
351         .shutdown       = mptscsih_shutdown,
352 #ifdef CONFIG_PM
353         .suspend        = mptscsih_suspend,
354         .resume         = mptscsih_resume,
355 #endif
356 };
357
358 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
359 /**
360  *      mptfc_init - Register MPT adapter(s) as SCSI host(s) with
361  *      linux scsi mid-layer.
362  *
363  *      Returns 0 for success, non-zero for failure.
364  */
365 static int __init
366 mptfc_init(void)
367 {
368
369         show_mptmod_ver(my_NAME, my_VERSION);
370
371         mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER);
372         mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER);
373         mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER);
374
375         if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) {
376                 devtprintk((KERN_INFO MYNAM
377                   ": Registered for IOC event notifications\n"));
378         }
379
380         if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) {
381                 dprintk((KERN_INFO MYNAM
382                   ": Registered for IOC reset notifications\n"));
383         }
384
385         return pci_register_driver(&mptfc_driver);
386 }
387
388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
390 /**
391  *      mptfc_exit - Unregisters MPT adapter(s)
392  *
393  */
394 static void __exit
395 mptfc_exit(void)
396 {
397         pci_unregister_driver(&mptfc_driver);
398         
399         mpt_reset_deregister(mptfcDoneCtx);
400         dprintk((KERN_INFO MYNAM
401           ": Deregistered for IOC reset notifications\n"));
402
403         mpt_event_deregister(mptfcDoneCtx);
404         dprintk((KERN_INFO MYNAM
405           ": Deregistered for IOC event notifications\n"));
406
407         mpt_deregister(mptfcInternalCtx);
408         mpt_deregister(mptfcTaskCtx);
409         mpt_deregister(mptfcDoneCtx);
410 }
411
412 module_init(mptfc_init);
413 module_exit(mptfc_exit);