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 = { 87f78496daSMoore, 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); 171*7acec1e7SMoore, Eric Dean error = -ENODEV; 172*7acec1e7SMoore, Eric Dean goto out_mptfc_probe; 1732496af39SMoore, Eric Dean } 1742496af39SMoore, Eric Dean 1752496af39SMoore, Eric Dean if (!ioc->active) { 1762496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", 1772496af39SMoore, Eric Dean ioc->name); 178*7acec1e7SMoore, Eric Dean error = -ENODEV; 179*7acec1e7SMoore, Eric Dean goto out_mptfc_probe; 1802496af39SMoore, Eric Dean } 1812496af39SMoore, Eric Dean 1822496af39SMoore, Eric Dean /* Sanity check - ensure at least 1 port is INITIATOR capable 1832496af39SMoore, Eric Dean */ 1842496af39SMoore, Eric Dean ioc_cap = 0; 1852496af39SMoore, Eric Dean for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 1862496af39SMoore, Eric Dean if (ioc->pfacts[ii].ProtocolFlags & 1872496af39SMoore, Eric Dean MPI_PORTFACTS_PROTOCOL_INITIATOR) 1882496af39SMoore, Eric Dean ioc_cap ++; 1892496af39SMoore, Eric Dean } 1902496af39SMoore, Eric Dean 1912496af39SMoore, Eric Dean if (!ioc_cap) { 1922496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 1932496af39SMoore, Eric Dean "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 1942496af39SMoore, Eric Dean ioc->name, ioc); 195466544d8SMoore, Eric Dean return 0; 1962496af39SMoore, Eric Dean } 1972496af39SMoore, Eric Dean 1982496af39SMoore, Eric Dean sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 1992496af39SMoore, Eric Dean 2002496af39SMoore, Eric Dean if (!sh) { 2012496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 2022496af39SMoore, Eric Dean "Unable to register controller with SCSI subsystem\n", 2032496af39SMoore, Eric Dean ioc->name); 204*7acec1e7SMoore, Eric Dean error = -1; 205*7acec1e7SMoore, Eric Dean goto out_mptfc_probe; 2062496af39SMoore, Eric Dean } 2072496af39SMoore, Eric Dean 2082496af39SMoore, Eric Dean spin_lock_irqsave(&ioc->FreeQlock, flags); 2092496af39SMoore, Eric Dean 2102496af39SMoore, Eric Dean /* Attach the SCSI Host to the IOC structure 2112496af39SMoore, Eric Dean */ 2122496af39SMoore, Eric Dean ioc->sh = sh; 2132496af39SMoore, Eric Dean 2142496af39SMoore, Eric Dean sh->io_port = 0; 2152496af39SMoore, Eric Dean sh->n_io_port = 0; 2162496af39SMoore, Eric Dean sh->irq = 0; 2172496af39SMoore, Eric Dean 2182496af39SMoore, Eric Dean /* set 16 byte cdb's */ 2192496af39SMoore, Eric Dean sh->max_cmd_len = 16; 2202496af39SMoore, Eric Dean 2212496af39SMoore, Eric Dean sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; 2222496af39SMoore, Eric Dean 2232496af39SMoore, Eric Dean sh->max_lun = MPT_LAST_LUN + 1; 2242496af39SMoore, Eric Dean sh->max_channel = 0; 2252496af39SMoore, Eric Dean sh->this_id = ioc->pfacts[0].PortSCSIID; 2262496af39SMoore, Eric Dean 2272496af39SMoore, Eric Dean /* Required entry. 2282496af39SMoore, Eric Dean */ 2292496af39SMoore, Eric Dean sh->unique_id = ioc->id; 2302496af39SMoore, Eric Dean 2312496af39SMoore, Eric Dean /* Verify that we won't exceed the maximum 2322496af39SMoore, Eric Dean * number of chain buffers 2332496af39SMoore, Eric Dean * We can optimize: ZZ = req_sz/sizeof(SGE) 2342496af39SMoore, Eric Dean * For 32bit SGE's: 2352496af39SMoore, Eric Dean * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ 2362496af39SMoore, Eric Dean * + (req_sz - 64)/sizeof(SGE) 2372496af39SMoore, Eric Dean * A slightly different algorithm is required for 2382496af39SMoore, Eric Dean * 64bit SGEs. 2392496af39SMoore, Eric Dean */ 2402496af39SMoore, Eric Dean scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 2412496af39SMoore, Eric Dean if (sizeof(dma_addr_t) == sizeof(u64)) { 2422496af39SMoore, Eric Dean numSGE = (scale - 1) * 2432496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 2442496af39SMoore, Eric Dean (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 2452496af39SMoore, Eric Dean sizeof(u32)); 2462496af39SMoore, Eric Dean } else { 2472496af39SMoore, Eric Dean numSGE = 1 + (scale - 1) * 2482496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 2492496af39SMoore, Eric Dean (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 2502496af39SMoore, Eric Dean sizeof(u32)); 2512496af39SMoore, Eric Dean } 2522496af39SMoore, Eric Dean 2532496af39SMoore, Eric Dean if (numSGE < sh->sg_tablesize) { 2542496af39SMoore, Eric Dean /* Reset this value */ 2552496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT 2562496af39SMoore, Eric Dean "Resetting sg_tablesize to %d from %d\n", 2572496af39SMoore, Eric Dean ioc->name, numSGE, sh->sg_tablesize)); 2582496af39SMoore, Eric Dean sh->sg_tablesize = numSGE; 2592496af39SMoore, Eric Dean } 2602496af39SMoore, Eric Dean 2612496af39SMoore, Eric Dean spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2622496af39SMoore, Eric Dean 2632496af39SMoore, Eric Dean hd = (MPT_SCSI_HOST *) sh->hostdata; 2642496af39SMoore, Eric Dean hd->ioc = ioc; 2652496af39SMoore, Eric Dean 2662496af39SMoore, Eric Dean /* SCSI needs scsi_cmnd lookup table! 2672496af39SMoore, Eric Dean * (with size equal to req_depth*PtrSz!) 2682496af39SMoore, Eric Dean */ 2692496af39SMoore, Eric Dean sz = ioc->req_depth * sizeof(void *); 2702496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 2712496af39SMoore, Eric Dean if (mem == NULL) { 2722496af39SMoore, Eric Dean error = -ENOMEM; 273*7acec1e7SMoore, Eric Dean goto out_mptfc_probe; 2742496af39SMoore, Eric Dean } 2752496af39SMoore, Eric Dean 2762496af39SMoore, Eric Dean memset(mem, 0, sz); 2772496af39SMoore, Eric Dean hd->ScsiLookup = (struct scsi_cmnd **) mem; 2782496af39SMoore, Eric Dean 2792496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", 2802496af39SMoore, Eric Dean ioc->name, hd->ScsiLookup, sz)); 2812496af39SMoore, Eric Dean 2822496af39SMoore, Eric Dean /* Allocate memory for the device structures. 2832496af39SMoore, Eric Dean * A non-Null pointer at an offset 2842496af39SMoore, Eric Dean * indicates a device exists. 2852496af39SMoore, Eric Dean * max_id = 1 + maximum id (hosts.h) 2862496af39SMoore, Eric Dean */ 2872496af39SMoore, Eric Dean sz = sh->max_id * sizeof(void *); 2882496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 2892496af39SMoore, Eric Dean if (mem == NULL) { 2902496af39SMoore, Eric Dean error = -ENOMEM; 291*7acec1e7SMoore, Eric Dean goto out_mptfc_probe; 2922496af39SMoore, Eric Dean } 2932496af39SMoore, Eric Dean 2942496af39SMoore, Eric Dean memset(mem, 0, sz); 2952496af39SMoore, Eric Dean hd->Targets = (VirtDevice **) mem; 2962496af39SMoore, Eric Dean 2972496af39SMoore, Eric Dean dprintk((KERN_INFO 2982496af39SMoore, Eric Dean " Targets @ %p, sz=%d\n", hd->Targets, sz)); 2992496af39SMoore, Eric Dean 3002496af39SMoore, Eric Dean /* Clear the TM flags 3012496af39SMoore, Eric Dean */ 3022496af39SMoore, Eric Dean hd->tmPending = 0; 3032496af39SMoore, Eric Dean hd->tmState = TM_STATE_NONE; 3042496af39SMoore, Eric Dean hd->resetPending = 0; 3052496af39SMoore, Eric Dean hd->abortSCpnt = NULL; 3062496af39SMoore, Eric Dean 3072496af39SMoore, Eric Dean /* Clear the pointer used to store 3082496af39SMoore, Eric Dean * single-threaded commands, i.e., those 3092496af39SMoore, Eric Dean * issued during a bus scan, dv and 3102496af39SMoore, Eric Dean * configuration pages. 3112496af39SMoore, Eric Dean */ 3122496af39SMoore, Eric Dean hd->cmdPtr = NULL; 3132496af39SMoore, Eric Dean 3142496af39SMoore, Eric Dean /* Initialize this SCSI Hosts' timers 3152496af39SMoore, Eric Dean * To use, set the timer expires field 3162496af39SMoore, Eric Dean * and add_timer 3172496af39SMoore, Eric Dean */ 3182496af39SMoore, Eric Dean init_timer(&hd->timer); 3192496af39SMoore, Eric Dean hd->timer.data = (unsigned long) hd; 3202496af39SMoore, Eric Dean hd->timer.function = mptscsih_timer_expired; 3212496af39SMoore, Eric Dean 3222496af39SMoore, Eric Dean hd->mpt_pq_filter = mpt_pq_filter; 3232496af39SMoore, Eric Dean 3242496af39SMoore, Eric Dean ddvprintk((MYIOC_s_INFO_FMT 3252496af39SMoore, Eric Dean "mpt_pq_filter %x\n", 3262496af39SMoore, Eric Dean ioc->name, 3272496af39SMoore, Eric Dean mpt_pq_filter)); 3282496af39SMoore, Eric Dean 3292496af39SMoore, Eric Dean init_waitqueue_head(&hd->scandv_waitq); 3302496af39SMoore, Eric Dean hd->scandv_wait_done = 0; 3312496af39SMoore, Eric Dean hd->last_queue_full = 0; 3322496af39SMoore, Eric Dean 3332496af39SMoore, Eric Dean error = scsi_add_host (sh, &ioc->pcidev->dev); 3342496af39SMoore, Eric Dean if(error) { 3352496af39SMoore, Eric Dean dprintk((KERN_ERR MYNAM 3362496af39SMoore, Eric Dean "scsi_add_host failed\n")); 337*7acec1e7SMoore, Eric Dean goto out_mptfc_probe; 3382496af39SMoore, Eric Dean } 3392496af39SMoore, Eric Dean 3402496af39SMoore, Eric Dean scsi_scan_host(sh); 3412496af39SMoore, Eric Dean return 0; 3422496af39SMoore, Eric Dean 343*7acec1e7SMoore, Eric Dean out_mptfc_probe: 3442496af39SMoore, Eric Dean 3452496af39SMoore, Eric Dean mptscsih_remove(pdev); 3462496af39SMoore, Eric Dean return error; 3472496af39SMoore, Eric Dean } 3482496af39SMoore, Eric Dean 3492496af39SMoore, Eric Dean static struct pci_driver mptfc_driver = { 3502496af39SMoore, Eric Dean .name = "mptfc", 3512496af39SMoore, Eric Dean .id_table = mptfc_pci_table, 3522496af39SMoore, Eric Dean .probe = mptfc_probe, 3532496af39SMoore, Eric Dean .remove = __devexit_p(mptscsih_remove), 3542496af39SMoore, Eric Dean .shutdown = mptscsih_shutdown, 3552496af39SMoore, Eric Dean #ifdef CONFIG_PM 3562496af39SMoore, Eric Dean .suspend = mptscsih_suspend, 3572496af39SMoore, Eric Dean .resume = mptscsih_resume, 3582496af39SMoore, Eric Dean #endif 3592496af39SMoore, Eric Dean }; 3602496af39SMoore, Eric Dean 3612496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3622496af39SMoore, Eric Dean /** 3632496af39SMoore, Eric Dean * mptfc_init - Register MPT adapter(s) as SCSI host(s) with 3642496af39SMoore, Eric Dean * linux scsi mid-layer. 3652496af39SMoore, Eric Dean * 3662496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 3672496af39SMoore, Eric Dean */ 3682496af39SMoore, Eric Dean static int __init 3692496af39SMoore, Eric Dean mptfc_init(void) 3702496af39SMoore, Eric Dean { 3712496af39SMoore, Eric Dean 3722496af39SMoore, Eric Dean show_mptmod_ver(my_NAME, my_VERSION); 3732496af39SMoore, Eric Dean 3742496af39SMoore, Eric Dean mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); 3752496af39SMoore, Eric Dean mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 3762496af39SMoore, Eric Dean mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 3772496af39SMoore, Eric Dean 3782496af39SMoore, Eric Dean if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { 3792496af39SMoore, Eric Dean devtprintk((KERN_INFO MYNAM 3802496af39SMoore, Eric Dean ": Registered for IOC event notifications\n")); 3812496af39SMoore, Eric Dean } 3822496af39SMoore, Eric Dean 3832496af39SMoore, Eric Dean if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) { 3842496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 3852496af39SMoore, Eric Dean ": Registered for IOC reset notifications\n")); 3862496af39SMoore, Eric Dean } 3872496af39SMoore, Eric Dean 3882496af39SMoore, Eric Dean return pci_register_driver(&mptfc_driver); 3892496af39SMoore, Eric Dean } 3902496af39SMoore, Eric Dean 3912496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3922496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3932496af39SMoore, Eric Dean /** 3942496af39SMoore, Eric Dean * mptfc_exit - Unregisters MPT adapter(s) 3952496af39SMoore, Eric Dean * 3962496af39SMoore, Eric Dean */ 3972496af39SMoore, Eric Dean static void __exit 3982496af39SMoore, Eric Dean mptfc_exit(void) 3992496af39SMoore, Eric Dean { 4002496af39SMoore, Eric Dean pci_unregister_driver(&mptfc_driver); 4012496af39SMoore, Eric Dean 4022496af39SMoore, Eric Dean mpt_reset_deregister(mptfcDoneCtx); 4032496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 4042496af39SMoore, Eric Dean ": Deregistered for IOC reset notifications\n")); 4052496af39SMoore, Eric Dean 4062496af39SMoore, Eric Dean mpt_event_deregister(mptfcDoneCtx); 4072496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 4082496af39SMoore, Eric Dean ": Deregistered for IOC event notifications\n")); 4092496af39SMoore, Eric Dean 4102496af39SMoore, Eric Dean mpt_deregister(mptfcInternalCtx); 4112496af39SMoore, Eric Dean mpt_deregister(mptfcTaskCtx); 4122496af39SMoore, Eric Dean mpt_deregister(mptfcDoneCtx); 4132496af39SMoore, Eric Dean } 4142496af39SMoore, Eric Dean 4152496af39SMoore, Eric Dean module_init(mptfc_init); 4162496af39SMoore, Eric Dean module_exit(mptfc_exit); 417