12496af39SMoore, Eric Dean /* 22496af39SMoore, Eric Dean * linux/drivers/message/fusion/mptfc.c 32496af39SMoore, Eric Dean * For use with LSI Logic PCI chip/adapter(s) 42496af39SMoore, Eric Dean * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 52496af39SMoore, Eric Dean * 62496af39SMoore, Eric Dean * Copyright (c) 1999-2005 LSI Logic Corporation 72496af39SMoore, Eric Dean * (mailto:mpt_linux_developer@lsil.com) 82496af39SMoore, Eric Dean * 92496af39SMoore, Eric Dean */ 102496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 112496af39SMoore, Eric Dean /* 122496af39SMoore, Eric Dean This program is free software; you can redistribute it and/or modify 132496af39SMoore, Eric Dean it under the terms of the GNU General Public License as published by 142496af39SMoore, Eric Dean the Free Software Foundation; version 2 of the License. 152496af39SMoore, Eric Dean 162496af39SMoore, Eric Dean This program is distributed in the hope that it will be useful, 172496af39SMoore, Eric Dean but WITHOUT ANY WARRANTY; without even the implied warranty of 182496af39SMoore, Eric Dean MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 192496af39SMoore, Eric Dean GNU General Public License for more details. 202496af39SMoore, Eric Dean 212496af39SMoore, Eric Dean NO WARRANTY 222496af39SMoore, Eric Dean THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 232496af39SMoore, Eric Dean CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 242496af39SMoore, Eric Dean LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 252496af39SMoore, Eric Dean MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 262496af39SMoore, Eric Dean solely responsible for determining the appropriateness of using and 272496af39SMoore, Eric Dean distributing the Program and assumes all risks associated with its 282496af39SMoore, Eric Dean exercise of rights under this Agreement, including but not limited to 292496af39SMoore, Eric Dean the risks and costs of program errors, damage to or loss of data, 302496af39SMoore, Eric Dean programs or equipment, and unavailability or interruption of operations. 312496af39SMoore, Eric Dean 322496af39SMoore, Eric Dean DISCLAIMER OF LIABILITY 332496af39SMoore, Eric Dean NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 342496af39SMoore, Eric Dean DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 352496af39SMoore, Eric Dean DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 362496af39SMoore, Eric Dean ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 372496af39SMoore, Eric Dean TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 382496af39SMoore, Eric Dean USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 392496af39SMoore, Eric Dean HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 402496af39SMoore, Eric Dean 412496af39SMoore, Eric Dean You should have received a copy of the GNU General Public License 422496af39SMoore, Eric Dean along with this program; if not, write to the Free Software 432496af39SMoore, Eric Dean Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 442496af39SMoore, Eric Dean */ 452496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 462496af39SMoore, Eric Dean #include "linux_compat.h" /* linux-2.6 tweaks */ 472496af39SMoore, Eric Dean #include <linux/module.h> 482496af39SMoore, Eric Dean #include <linux/kernel.h> 492496af39SMoore, Eric Dean #include <linux/init.h> 502496af39SMoore, Eric Dean #include <linux/errno.h> 512496af39SMoore, Eric Dean #include <linux/kdev_t.h> 522496af39SMoore, Eric Dean #include <linux/blkdev.h> 532496af39SMoore, Eric Dean #include <linux/delay.h> /* for mdelay */ 542496af39SMoore, Eric Dean #include <linux/interrupt.h> /* needed for in_interrupt() proto */ 552496af39SMoore, Eric Dean #include <linux/reboot.h> /* notifier code */ 562496af39SMoore, Eric Dean #include <linux/sched.h> 572496af39SMoore, Eric Dean #include <linux/workqueue.h> 582496af39SMoore, Eric Dean 592496af39SMoore, Eric Dean #include <scsi/scsi.h> 602496af39SMoore, Eric Dean #include <scsi/scsi_cmnd.h> 612496af39SMoore, Eric Dean #include <scsi/scsi_device.h> 622496af39SMoore, Eric Dean #include <scsi/scsi_host.h> 632496af39SMoore, Eric Dean #include <scsi/scsi_tcq.h> 642496af39SMoore, Eric Dean 652496af39SMoore, Eric Dean #include "mptbase.h" 662496af39SMoore, Eric Dean #include "mptscsih.h" 672496af39SMoore, Eric Dean 682496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 692496af39SMoore, Eric Dean #define my_NAME "Fusion MPT FC Host driver" 702496af39SMoore, Eric Dean #define my_VERSION MPT_LINUX_VERSION_COMMON 712496af39SMoore, Eric Dean #define MYNAM "mptfc" 722496af39SMoore, Eric Dean 732496af39SMoore, Eric Dean MODULE_AUTHOR(MODULEAUTHOR); 742496af39SMoore, Eric Dean MODULE_DESCRIPTION(my_NAME); 752496af39SMoore, Eric Dean MODULE_LICENSE("GPL"); 762496af39SMoore, Eric Dean 772496af39SMoore, Eric Dean /* Command line args */ 782496af39SMoore, Eric Dean static int mpt_pq_filter = 0; 792496af39SMoore, Eric Dean module_param(mpt_pq_filter, int, 0); 802496af39SMoore, Eric Dean MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); 812496af39SMoore, Eric Dean 822496af39SMoore, Eric Dean static int mptfcDoneCtx = -1; 832496af39SMoore, Eric Dean static int mptfcTaskCtx = -1; 842496af39SMoore, Eric Dean static int mptfcInternalCtx = -1; /* Used only for internal commands */ 852496af39SMoore, Eric Dean 862496af39SMoore, Eric Dean static struct scsi_host_template mptfc_driver_template = { 87*f78496daSMoore, Eric Dean .module = THIS_MODULE, 882496af39SMoore, Eric Dean .proc_name = "mptfc", 892496af39SMoore, Eric Dean .proc_info = mptscsih_proc_info, 902496af39SMoore, Eric Dean .name = "MPT FC Host", 912496af39SMoore, Eric Dean .info = mptscsih_info, 922496af39SMoore, Eric Dean .queuecommand = mptscsih_qcmd, 932496af39SMoore, Eric Dean .slave_alloc = mptscsih_slave_alloc, 942496af39SMoore, Eric Dean .slave_configure = mptscsih_slave_configure, 952496af39SMoore, Eric Dean .slave_destroy = mptscsih_slave_destroy, 966e3815baSMoore, Eric Dean .change_queue_depth = mptscsih_change_queue_depth, 972496af39SMoore, Eric Dean .eh_abort_handler = mptscsih_abort, 982496af39SMoore, Eric Dean .eh_device_reset_handler = mptscsih_dev_reset, 992496af39SMoore, Eric Dean .eh_bus_reset_handler = mptscsih_bus_reset, 1002496af39SMoore, Eric Dean .eh_host_reset_handler = mptscsih_host_reset, 1012496af39SMoore, Eric Dean .bios_param = mptscsih_bios_param, 1022496af39SMoore, Eric Dean .can_queue = MPT_FC_CAN_QUEUE, 1032496af39SMoore, Eric Dean .this_id = -1, 1042496af39SMoore, Eric Dean .sg_tablesize = MPT_SCSI_SG_DEPTH, 1052496af39SMoore, Eric Dean .max_sectors = 8192, 1062496af39SMoore, Eric Dean .cmd_per_lun = 7, 1072496af39SMoore, Eric Dean .use_clustering = ENABLE_CLUSTERING, 1082496af39SMoore, Eric Dean }; 1092496af39SMoore, Eric Dean 1102496af39SMoore, Eric Dean /**************************************************************************** 1112496af39SMoore, Eric Dean * Supported hardware 1122496af39SMoore, Eric Dean */ 1132496af39SMoore, Eric Dean 1142496af39SMoore, Eric Dean static struct pci_device_id mptfc_pci_table[] = { 1152496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, 1162496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1172496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, 1182496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1192496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, 1202496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1212496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, 1222496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1232496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, 1242496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1253fadc59dSMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X, 1263fadc59dSMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1273fadc59dSMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, 1283fadc59dSMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1292496af39SMoore, Eric Dean {0} /* Terminating entry */ 1302496af39SMoore, Eric Dean }; 1312496af39SMoore, Eric Dean MODULE_DEVICE_TABLE(pci, mptfc_pci_table); 1322496af39SMoore, Eric Dean 1332496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1342496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1352496af39SMoore, Eric Dean /* 1362496af39SMoore, Eric Dean * mptfc_probe - Installs scsi devices per bus. 1372496af39SMoore, Eric Dean * @pdev: Pointer to pci_dev structure 1382496af39SMoore, Eric Dean * 1392496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 1402496af39SMoore, Eric Dean * 1412496af39SMoore, Eric Dean */ 1422496af39SMoore, Eric Dean static int 1432496af39SMoore, Eric Dean mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1442496af39SMoore, Eric Dean { 1452496af39SMoore, Eric Dean struct Scsi_Host *sh; 1462496af39SMoore, Eric Dean MPT_SCSI_HOST *hd; 1472496af39SMoore, Eric Dean MPT_ADAPTER *ioc; 1482496af39SMoore, Eric Dean unsigned long flags; 1492496af39SMoore, Eric Dean int sz, ii; 1502496af39SMoore, Eric Dean int numSGE = 0; 1512496af39SMoore, Eric Dean int scale; 1522496af39SMoore, Eric Dean int ioc_cap; 1532496af39SMoore, Eric Dean u8 *mem; 1542496af39SMoore, Eric Dean int error=0; 1552496af39SMoore, Eric Dean int r; 1562496af39SMoore, Eric Dean 1572496af39SMoore, Eric Dean if ((r = mpt_attach(pdev,id)) != 0) 1582496af39SMoore, Eric Dean return r; 1592496af39SMoore, Eric Dean 1602496af39SMoore, Eric Dean ioc = pci_get_drvdata(pdev); 161d335cc38SMoore, Eric Dean ioc->DoneCtx = mptfcDoneCtx; 162d335cc38SMoore, Eric Dean ioc->TaskCtx = mptfcTaskCtx; 163d335cc38SMoore, Eric Dean ioc->InternalCtx = mptfcInternalCtx; 1642496af39SMoore, Eric Dean 1652496af39SMoore, Eric Dean /* Added sanity check on readiness of the MPT adapter. 1662496af39SMoore, Eric Dean */ 1672496af39SMoore, Eric Dean if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 1682496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 1692496af39SMoore, Eric Dean "Skipping because it's not operational!\n", 1702496af39SMoore, Eric Dean ioc->name); 1712496af39SMoore, Eric Dean return -ENODEV; 1722496af39SMoore, Eric Dean } 1732496af39SMoore, Eric Dean 1742496af39SMoore, Eric Dean if (!ioc->active) { 1752496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", 1762496af39SMoore, Eric Dean ioc->name); 1772496af39SMoore, Eric Dean return -ENODEV; 1782496af39SMoore, Eric Dean } 1792496af39SMoore, Eric Dean 1802496af39SMoore, Eric Dean /* Sanity check - ensure at least 1 port is INITIATOR capable 1812496af39SMoore, Eric Dean */ 1822496af39SMoore, Eric Dean ioc_cap = 0; 1832496af39SMoore, Eric Dean for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 1842496af39SMoore, Eric Dean if (ioc->pfacts[ii].ProtocolFlags & 1852496af39SMoore, Eric Dean MPI_PORTFACTS_PROTOCOL_INITIATOR) 1862496af39SMoore, Eric Dean ioc_cap ++; 1872496af39SMoore, Eric Dean } 1882496af39SMoore, Eric Dean 1892496af39SMoore, Eric Dean if (!ioc_cap) { 1902496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 1912496af39SMoore, Eric Dean "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 1922496af39SMoore, Eric Dean ioc->name, ioc); 193466544d8SMoore, Eric Dean return 0; 1942496af39SMoore, Eric Dean } 1952496af39SMoore, Eric Dean 1962496af39SMoore, Eric Dean sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 1972496af39SMoore, Eric Dean 1982496af39SMoore, Eric Dean if (!sh) { 1992496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 2002496af39SMoore, Eric Dean "Unable to register controller with SCSI subsystem\n", 2012496af39SMoore, Eric Dean ioc->name); 2022496af39SMoore, Eric Dean return -1; 2032496af39SMoore, Eric Dean } 2042496af39SMoore, Eric Dean 2052496af39SMoore, Eric Dean spin_lock_irqsave(&ioc->FreeQlock, flags); 2062496af39SMoore, Eric Dean 2072496af39SMoore, Eric Dean /* Attach the SCSI Host to the IOC structure 2082496af39SMoore, Eric Dean */ 2092496af39SMoore, Eric Dean ioc->sh = sh; 2102496af39SMoore, Eric Dean 2112496af39SMoore, Eric Dean sh->io_port = 0; 2122496af39SMoore, Eric Dean sh->n_io_port = 0; 2132496af39SMoore, Eric Dean sh->irq = 0; 2142496af39SMoore, Eric Dean 2152496af39SMoore, Eric Dean /* set 16 byte cdb's */ 2162496af39SMoore, Eric Dean sh->max_cmd_len = 16; 2172496af39SMoore, Eric Dean 2182496af39SMoore, Eric Dean sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; 2192496af39SMoore, Eric Dean 2202496af39SMoore, Eric Dean sh->max_lun = MPT_LAST_LUN + 1; 2212496af39SMoore, Eric Dean sh->max_channel = 0; 2222496af39SMoore, Eric Dean sh->this_id = ioc->pfacts[0].PortSCSIID; 2232496af39SMoore, Eric Dean 2242496af39SMoore, Eric Dean /* Required entry. 2252496af39SMoore, Eric Dean */ 2262496af39SMoore, Eric Dean sh->unique_id = ioc->id; 2272496af39SMoore, Eric Dean 2282496af39SMoore, Eric Dean /* Verify that we won't exceed the maximum 2292496af39SMoore, Eric Dean * number of chain buffers 2302496af39SMoore, Eric Dean * We can optimize: ZZ = req_sz/sizeof(SGE) 2312496af39SMoore, Eric Dean * For 32bit SGE's: 2322496af39SMoore, Eric Dean * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ 2332496af39SMoore, Eric Dean * + (req_sz - 64)/sizeof(SGE) 2342496af39SMoore, Eric Dean * A slightly different algorithm is required for 2352496af39SMoore, Eric Dean * 64bit SGEs. 2362496af39SMoore, Eric Dean */ 2372496af39SMoore, Eric Dean scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 2382496af39SMoore, Eric Dean if (sizeof(dma_addr_t) == sizeof(u64)) { 2392496af39SMoore, Eric Dean numSGE = (scale - 1) * 2402496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 2412496af39SMoore, Eric Dean (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 2422496af39SMoore, Eric Dean sizeof(u32)); 2432496af39SMoore, Eric Dean } else { 2442496af39SMoore, Eric Dean numSGE = 1 + (scale - 1) * 2452496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 2462496af39SMoore, Eric Dean (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 2472496af39SMoore, Eric Dean sizeof(u32)); 2482496af39SMoore, Eric Dean } 2492496af39SMoore, Eric Dean 2502496af39SMoore, Eric Dean if (numSGE < sh->sg_tablesize) { 2512496af39SMoore, Eric Dean /* Reset this value */ 2522496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT 2532496af39SMoore, Eric Dean "Resetting sg_tablesize to %d from %d\n", 2542496af39SMoore, Eric Dean ioc->name, numSGE, sh->sg_tablesize)); 2552496af39SMoore, Eric Dean sh->sg_tablesize = numSGE; 2562496af39SMoore, Eric Dean } 2572496af39SMoore, Eric Dean 2582496af39SMoore, Eric Dean spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2592496af39SMoore, Eric Dean 2602496af39SMoore, Eric Dean hd = (MPT_SCSI_HOST *) sh->hostdata; 2612496af39SMoore, Eric Dean hd->ioc = ioc; 2622496af39SMoore, Eric Dean 2632496af39SMoore, Eric Dean /* SCSI needs scsi_cmnd lookup table! 2642496af39SMoore, Eric Dean * (with size equal to req_depth*PtrSz!) 2652496af39SMoore, Eric Dean */ 2662496af39SMoore, Eric Dean sz = ioc->req_depth * sizeof(void *); 2672496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 2682496af39SMoore, Eric Dean if (mem == NULL) { 2692496af39SMoore, Eric Dean error = -ENOMEM; 2702496af39SMoore, Eric Dean goto mptfc_probe_failed; 2712496af39SMoore, Eric Dean } 2722496af39SMoore, Eric Dean 2732496af39SMoore, Eric Dean memset(mem, 0, sz); 2742496af39SMoore, Eric Dean hd->ScsiLookup = (struct scsi_cmnd **) mem; 2752496af39SMoore, Eric Dean 2762496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", 2772496af39SMoore, Eric Dean ioc->name, hd->ScsiLookup, sz)); 2782496af39SMoore, Eric Dean 2792496af39SMoore, Eric Dean /* Allocate memory for the device structures. 2802496af39SMoore, Eric Dean * A non-Null pointer at an offset 2812496af39SMoore, Eric Dean * indicates a device exists. 2822496af39SMoore, Eric Dean * max_id = 1 + maximum id (hosts.h) 2832496af39SMoore, Eric Dean */ 2842496af39SMoore, Eric Dean sz = sh->max_id * sizeof(void *); 2852496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 2862496af39SMoore, Eric Dean if (mem == NULL) { 2872496af39SMoore, Eric Dean error = -ENOMEM; 2882496af39SMoore, Eric Dean goto mptfc_probe_failed; 2892496af39SMoore, Eric Dean } 2902496af39SMoore, Eric Dean 2912496af39SMoore, Eric Dean memset(mem, 0, sz); 2922496af39SMoore, Eric Dean hd->Targets = (VirtDevice **) mem; 2932496af39SMoore, Eric Dean 2942496af39SMoore, Eric Dean dprintk((KERN_INFO 2952496af39SMoore, Eric Dean " Targets @ %p, sz=%d\n", hd->Targets, sz)); 2962496af39SMoore, Eric Dean 2972496af39SMoore, Eric Dean /* Clear the TM flags 2982496af39SMoore, Eric Dean */ 2992496af39SMoore, Eric Dean hd->tmPending = 0; 3002496af39SMoore, Eric Dean hd->tmState = TM_STATE_NONE; 3012496af39SMoore, Eric Dean hd->resetPending = 0; 3022496af39SMoore, Eric Dean hd->abortSCpnt = NULL; 3032496af39SMoore, Eric Dean 3042496af39SMoore, Eric Dean /* Clear the pointer used to store 3052496af39SMoore, Eric Dean * single-threaded commands, i.e., those 3062496af39SMoore, Eric Dean * issued during a bus scan, dv and 3072496af39SMoore, Eric Dean * configuration pages. 3082496af39SMoore, Eric Dean */ 3092496af39SMoore, Eric Dean hd->cmdPtr = NULL; 3102496af39SMoore, Eric Dean 3112496af39SMoore, Eric Dean /* Initialize this SCSI Hosts' timers 3122496af39SMoore, Eric Dean * To use, set the timer expires field 3132496af39SMoore, Eric Dean * and add_timer 3142496af39SMoore, Eric Dean */ 3152496af39SMoore, Eric Dean init_timer(&hd->timer); 3162496af39SMoore, Eric Dean hd->timer.data = (unsigned long) hd; 3172496af39SMoore, Eric Dean hd->timer.function = mptscsih_timer_expired; 3182496af39SMoore, Eric Dean 3192496af39SMoore, Eric Dean hd->mpt_pq_filter = mpt_pq_filter; 3202496af39SMoore, Eric Dean 3212496af39SMoore, Eric Dean ddvprintk((MYIOC_s_INFO_FMT 3222496af39SMoore, Eric Dean "mpt_pq_filter %x\n", 3232496af39SMoore, Eric Dean ioc->name, 3242496af39SMoore, Eric Dean mpt_pq_filter)); 3252496af39SMoore, Eric Dean 3262496af39SMoore, Eric Dean init_waitqueue_head(&hd->scandv_waitq); 3272496af39SMoore, Eric Dean hd->scandv_wait_done = 0; 3282496af39SMoore, Eric Dean hd->last_queue_full = 0; 3292496af39SMoore, Eric Dean 3302496af39SMoore, Eric Dean error = scsi_add_host (sh, &ioc->pcidev->dev); 3312496af39SMoore, Eric Dean if(error) { 3322496af39SMoore, Eric Dean dprintk((KERN_ERR MYNAM 3332496af39SMoore, Eric Dean "scsi_add_host failed\n")); 3342496af39SMoore, Eric Dean goto mptfc_probe_failed; 3352496af39SMoore, Eric Dean } 3362496af39SMoore, Eric Dean 3372496af39SMoore, Eric Dean scsi_scan_host(sh); 3382496af39SMoore, Eric Dean return 0; 3392496af39SMoore, Eric Dean 3402496af39SMoore, Eric Dean mptfc_probe_failed: 3412496af39SMoore, Eric Dean 3422496af39SMoore, Eric Dean mptscsih_remove(pdev); 3432496af39SMoore, Eric Dean return error; 3442496af39SMoore, Eric Dean } 3452496af39SMoore, Eric Dean 3462496af39SMoore, Eric Dean static struct pci_driver mptfc_driver = { 3472496af39SMoore, Eric Dean .name = "mptfc", 3482496af39SMoore, Eric Dean .id_table = mptfc_pci_table, 3492496af39SMoore, Eric Dean .probe = mptfc_probe, 3502496af39SMoore, Eric Dean .remove = __devexit_p(mptscsih_remove), 3512496af39SMoore, Eric Dean .shutdown = mptscsih_shutdown, 3522496af39SMoore, Eric Dean #ifdef CONFIG_PM 3532496af39SMoore, Eric Dean .suspend = mptscsih_suspend, 3542496af39SMoore, Eric Dean .resume = mptscsih_resume, 3552496af39SMoore, Eric Dean #endif 3562496af39SMoore, Eric Dean }; 3572496af39SMoore, Eric Dean 3582496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3592496af39SMoore, Eric Dean /** 3602496af39SMoore, Eric Dean * mptfc_init - Register MPT adapter(s) as SCSI host(s) with 3612496af39SMoore, Eric Dean * linux scsi mid-layer. 3622496af39SMoore, Eric Dean * 3632496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 3642496af39SMoore, Eric Dean */ 3652496af39SMoore, Eric Dean static int __init 3662496af39SMoore, Eric Dean mptfc_init(void) 3672496af39SMoore, Eric Dean { 3682496af39SMoore, Eric Dean 3692496af39SMoore, Eric Dean show_mptmod_ver(my_NAME, my_VERSION); 3702496af39SMoore, Eric Dean 3712496af39SMoore, Eric Dean mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); 3722496af39SMoore, Eric Dean mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 3732496af39SMoore, Eric Dean mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 3742496af39SMoore, Eric Dean 3752496af39SMoore, Eric Dean if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { 3762496af39SMoore, Eric Dean devtprintk((KERN_INFO MYNAM 3772496af39SMoore, Eric Dean ": Registered for IOC event notifications\n")); 3782496af39SMoore, Eric Dean } 3792496af39SMoore, Eric Dean 3802496af39SMoore, Eric Dean if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) { 3812496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 3822496af39SMoore, Eric Dean ": Registered for IOC reset notifications\n")); 3832496af39SMoore, Eric Dean } 3842496af39SMoore, Eric Dean 3852496af39SMoore, Eric Dean return pci_register_driver(&mptfc_driver); 3862496af39SMoore, Eric Dean } 3872496af39SMoore, Eric Dean 3882496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3892496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3902496af39SMoore, Eric Dean /** 3912496af39SMoore, Eric Dean * mptfc_exit - Unregisters MPT adapter(s) 3922496af39SMoore, Eric Dean * 3932496af39SMoore, Eric Dean */ 3942496af39SMoore, Eric Dean static void __exit 3952496af39SMoore, Eric Dean mptfc_exit(void) 3962496af39SMoore, Eric Dean { 3972496af39SMoore, Eric Dean pci_unregister_driver(&mptfc_driver); 3982496af39SMoore, Eric Dean 3992496af39SMoore, Eric Dean mpt_reset_deregister(mptfcDoneCtx); 4002496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 4012496af39SMoore, Eric Dean ": Deregistered for IOC reset notifications\n")); 4022496af39SMoore, Eric Dean 4032496af39SMoore, Eric Dean mpt_event_deregister(mptfcDoneCtx); 4042496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 4052496af39SMoore, Eric Dean ": Deregistered for IOC event notifications\n")); 4062496af39SMoore, Eric Dean 4072496af39SMoore, Eric Dean mpt_deregister(mptfcInternalCtx); 4082496af39SMoore, Eric Dean mpt_deregister(mptfcTaskCtx); 4092496af39SMoore, Eric Dean mpt_deregister(mptfcDoneCtx); 4102496af39SMoore, Eric Dean } 4112496af39SMoore, Eric Dean 4122496af39SMoore, Eric Dean module_init(mptfc_init); 4132496af39SMoore, Eric Dean module_exit(mptfc_exit); 414