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, 93*c7c82987SMoore, Eric Dean .target_alloc = mptscsih_target_alloc, 942496af39SMoore, Eric Dean .slave_alloc = mptscsih_slave_alloc, 952496af39SMoore, Eric Dean .slave_configure = mptscsih_slave_configure, 96*c7c82987SMoore, Eric Dean .target_destroy = mptscsih_target_destroy, 972496af39SMoore, Eric Dean .slave_destroy = mptscsih_slave_destroy, 986e3815baSMoore, Eric Dean .change_queue_depth = mptscsih_change_queue_depth, 992496af39SMoore, Eric Dean .eh_abort_handler = mptscsih_abort, 1002496af39SMoore, Eric Dean .eh_device_reset_handler = mptscsih_dev_reset, 1012496af39SMoore, Eric Dean .eh_bus_reset_handler = mptscsih_bus_reset, 1022496af39SMoore, Eric Dean .eh_host_reset_handler = mptscsih_host_reset, 1032496af39SMoore, Eric Dean .bios_param = mptscsih_bios_param, 1042496af39SMoore, Eric Dean .can_queue = MPT_FC_CAN_QUEUE, 1052496af39SMoore, Eric Dean .this_id = -1, 1062496af39SMoore, Eric Dean .sg_tablesize = MPT_SCSI_SG_DEPTH, 1072496af39SMoore, Eric Dean .max_sectors = 8192, 1082496af39SMoore, Eric Dean .cmd_per_lun = 7, 1092496af39SMoore, Eric Dean .use_clustering = ENABLE_CLUSTERING, 1102496af39SMoore, Eric Dean }; 1112496af39SMoore, Eric Dean 1122496af39SMoore, Eric Dean /**************************************************************************** 1132496af39SMoore, Eric Dean * Supported hardware 1142496af39SMoore, Eric Dean */ 1152496af39SMoore, Eric Dean 1162496af39SMoore, Eric Dean static struct pci_device_id mptfc_pci_table[] = { 1172496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, 1182496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1192496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, 1202496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1212496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, 1222496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1232496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, 1242496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1252496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, 1262496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1273fadc59dSMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC939X, 1283fadc59dSMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1293fadc59dSMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC949X, 1303fadc59dSMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 1312496af39SMoore, Eric Dean {0} /* Terminating entry */ 1322496af39SMoore, Eric Dean }; 1332496af39SMoore, Eric Dean MODULE_DEVICE_TABLE(pci, mptfc_pci_table); 1342496af39SMoore, Eric Dean 1352496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1362496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1372496af39SMoore, Eric Dean /* 1382496af39SMoore, Eric Dean * mptfc_probe - Installs scsi devices per bus. 1392496af39SMoore, Eric Dean * @pdev: Pointer to pci_dev structure 1402496af39SMoore, Eric Dean * 1412496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 1422496af39SMoore, Eric Dean * 1432496af39SMoore, Eric Dean */ 1442496af39SMoore, Eric Dean static int 1452496af39SMoore, Eric Dean mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1462496af39SMoore, Eric Dean { 1472496af39SMoore, Eric Dean struct Scsi_Host *sh; 1482496af39SMoore, Eric Dean MPT_SCSI_HOST *hd; 1492496af39SMoore, Eric Dean MPT_ADAPTER *ioc; 1502496af39SMoore, Eric Dean unsigned long flags; 1512496af39SMoore, Eric Dean int sz, ii; 1522496af39SMoore, Eric Dean int numSGE = 0; 1532496af39SMoore, Eric Dean int scale; 1542496af39SMoore, Eric Dean int ioc_cap; 1552496af39SMoore, Eric Dean u8 *mem; 1562496af39SMoore, Eric Dean int error=0; 1572496af39SMoore, Eric Dean int r; 1582496af39SMoore, Eric Dean 1592496af39SMoore, Eric Dean if ((r = mpt_attach(pdev,id)) != 0) 1602496af39SMoore, Eric Dean return r; 1612496af39SMoore, Eric Dean 1622496af39SMoore, Eric Dean ioc = pci_get_drvdata(pdev); 163d335cc38SMoore, Eric Dean ioc->DoneCtx = mptfcDoneCtx; 164d335cc38SMoore, Eric Dean ioc->TaskCtx = mptfcTaskCtx; 165d335cc38SMoore, Eric Dean ioc->InternalCtx = mptfcInternalCtx; 1662496af39SMoore, Eric Dean 1672496af39SMoore, Eric Dean /* Added sanity check on readiness of the MPT adapter. 1682496af39SMoore, Eric Dean */ 1692496af39SMoore, Eric Dean if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 1702496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 1712496af39SMoore, Eric Dean "Skipping because it's not operational!\n", 1722496af39SMoore, Eric Dean ioc->name); 1737acec1e7SMoore, Eric Dean error = -ENODEV; 1747acec1e7SMoore, Eric Dean goto out_mptfc_probe; 1752496af39SMoore, Eric Dean } 1762496af39SMoore, Eric Dean 1772496af39SMoore, Eric Dean if (!ioc->active) { 1782496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", 1792496af39SMoore, Eric Dean ioc->name); 1807acec1e7SMoore, Eric Dean error = -ENODEV; 1817acec1e7SMoore, Eric Dean goto out_mptfc_probe; 1822496af39SMoore, Eric Dean } 1832496af39SMoore, Eric Dean 1842496af39SMoore, Eric Dean /* Sanity check - ensure at least 1 port is INITIATOR capable 1852496af39SMoore, Eric Dean */ 1862496af39SMoore, Eric Dean ioc_cap = 0; 1872496af39SMoore, Eric Dean for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 1882496af39SMoore, Eric Dean if (ioc->pfacts[ii].ProtocolFlags & 1892496af39SMoore, Eric Dean MPI_PORTFACTS_PROTOCOL_INITIATOR) 1902496af39SMoore, Eric Dean ioc_cap ++; 1912496af39SMoore, Eric Dean } 1922496af39SMoore, Eric Dean 1932496af39SMoore, Eric Dean if (!ioc_cap) { 1942496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 1952496af39SMoore, Eric Dean "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 1962496af39SMoore, Eric Dean ioc->name, ioc); 197466544d8SMoore, Eric Dean return 0; 1982496af39SMoore, Eric Dean } 1992496af39SMoore, Eric Dean 2002496af39SMoore, Eric Dean sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 2012496af39SMoore, Eric Dean 2022496af39SMoore, Eric Dean if (!sh) { 2032496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 2042496af39SMoore, Eric Dean "Unable to register controller with SCSI subsystem\n", 2052496af39SMoore, Eric Dean ioc->name); 2067acec1e7SMoore, Eric Dean error = -1; 2077acec1e7SMoore, Eric Dean goto out_mptfc_probe; 2082496af39SMoore, Eric Dean } 2092496af39SMoore, Eric Dean 2102496af39SMoore, Eric Dean spin_lock_irqsave(&ioc->FreeQlock, flags); 2112496af39SMoore, Eric Dean 2122496af39SMoore, Eric Dean /* Attach the SCSI Host to the IOC structure 2132496af39SMoore, Eric Dean */ 2142496af39SMoore, Eric Dean ioc->sh = sh; 2152496af39SMoore, Eric Dean 2162496af39SMoore, Eric Dean sh->io_port = 0; 2172496af39SMoore, Eric Dean sh->n_io_port = 0; 2182496af39SMoore, Eric Dean sh->irq = 0; 2192496af39SMoore, Eric Dean 2202496af39SMoore, Eric Dean /* set 16 byte cdb's */ 2212496af39SMoore, Eric Dean sh->max_cmd_len = 16; 2222496af39SMoore, Eric Dean 2232496af39SMoore, Eric Dean sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; 2242496af39SMoore, Eric Dean 2252496af39SMoore, Eric Dean sh->max_lun = MPT_LAST_LUN + 1; 2262496af39SMoore, Eric Dean sh->max_channel = 0; 2272496af39SMoore, Eric Dean sh->this_id = ioc->pfacts[0].PortSCSIID; 2282496af39SMoore, Eric Dean 2292496af39SMoore, Eric Dean /* Required entry. 2302496af39SMoore, Eric Dean */ 2312496af39SMoore, Eric Dean sh->unique_id = ioc->id; 2322496af39SMoore, Eric Dean 2332496af39SMoore, Eric Dean /* Verify that we won't exceed the maximum 2342496af39SMoore, Eric Dean * number of chain buffers 2352496af39SMoore, Eric Dean * We can optimize: ZZ = req_sz/sizeof(SGE) 2362496af39SMoore, Eric Dean * For 32bit SGE's: 2372496af39SMoore, Eric Dean * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ 2382496af39SMoore, Eric Dean * + (req_sz - 64)/sizeof(SGE) 2392496af39SMoore, Eric Dean * A slightly different algorithm is required for 2402496af39SMoore, Eric Dean * 64bit SGEs. 2412496af39SMoore, Eric Dean */ 2422496af39SMoore, Eric Dean scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 2432496af39SMoore, Eric Dean if (sizeof(dma_addr_t) == sizeof(u64)) { 2442496af39SMoore, Eric Dean numSGE = (scale - 1) * 2452496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 2462496af39SMoore, Eric Dean (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 2472496af39SMoore, Eric Dean sizeof(u32)); 2482496af39SMoore, Eric Dean } else { 2492496af39SMoore, Eric Dean numSGE = 1 + (scale - 1) * 2502496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 2512496af39SMoore, Eric Dean (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 2522496af39SMoore, Eric Dean sizeof(u32)); 2532496af39SMoore, Eric Dean } 2542496af39SMoore, Eric Dean 2552496af39SMoore, Eric Dean if (numSGE < sh->sg_tablesize) { 2562496af39SMoore, Eric Dean /* Reset this value */ 2572496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT 2582496af39SMoore, Eric Dean "Resetting sg_tablesize to %d from %d\n", 2592496af39SMoore, Eric Dean ioc->name, numSGE, sh->sg_tablesize)); 2602496af39SMoore, Eric Dean sh->sg_tablesize = numSGE; 2612496af39SMoore, Eric Dean } 2622496af39SMoore, Eric Dean 2632496af39SMoore, Eric Dean spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2642496af39SMoore, Eric Dean 2652496af39SMoore, Eric Dean hd = (MPT_SCSI_HOST *) sh->hostdata; 2662496af39SMoore, Eric Dean hd->ioc = ioc; 2672496af39SMoore, Eric Dean 2682496af39SMoore, Eric Dean /* SCSI needs scsi_cmnd lookup table! 2692496af39SMoore, Eric Dean * (with size equal to req_depth*PtrSz!) 2702496af39SMoore, Eric Dean */ 2712496af39SMoore, Eric Dean sz = ioc->req_depth * sizeof(void *); 2722496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 2732496af39SMoore, Eric Dean if (mem == NULL) { 2742496af39SMoore, Eric Dean error = -ENOMEM; 2757acec1e7SMoore, Eric Dean goto out_mptfc_probe; 2762496af39SMoore, Eric Dean } 2772496af39SMoore, Eric Dean 2782496af39SMoore, Eric Dean memset(mem, 0, sz); 2792496af39SMoore, Eric Dean hd->ScsiLookup = (struct scsi_cmnd **) mem; 2802496af39SMoore, Eric Dean 2812496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", 2822496af39SMoore, Eric Dean ioc->name, hd->ScsiLookup, sz)); 2832496af39SMoore, Eric Dean 2842496af39SMoore, Eric Dean /* Allocate memory for the device structures. 2852496af39SMoore, Eric Dean * A non-Null pointer at an offset 2862496af39SMoore, Eric Dean * indicates a device exists. 2872496af39SMoore, Eric Dean * max_id = 1 + maximum id (hosts.h) 2882496af39SMoore, Eric Dean */ 2892496af39SMoore, Eric Dean sz = sh->max_id * sizeof(void *); 2902496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 2912496af39SMoore, Eric Dean if (mem == NULL) { 2922496af39SMoore, Eric Dean error = -ENOMEM; 2937acec1e7SMoore, Eric Dean goto out_mptfc_probe; 2942496af39SMoore, Eric Dean } 2952496af39SMoore, Eric Dean 2962496af39SMoore, Eric Dean memset(mem, 0, sz); 297*c7c82987SMoore, Eric Dean hd->Targets = (VirtTarget **) mem; 2982496af39SMoore, Eric Dean 2992496af39SMoore, Eric Dean dprintk((KERN_INFO 300*c7c82987SMoore, Eric Dean " vdev @ %p, sz=%d\n", hd->Targets, sz)); 3012496af39SMoore, Eric Dean 3022496af39SMoore, Eric Dean /* Clear the TM flags 3032496af39SMoore, Eric Dean */ 3042496af39SMoore, Eric Dean hd->tmPending = 0; 3052496af39SMoore, Eric Dean hd->tmState = TM_STATE_NONE; 3062496af39SMoore, Eric Dean hd->resetPending = 0; 3072496af39SMoore, Eric Dean hd->abortSCpnt = NULL; 3082496af39SMoore, Eric Dean 3092496af39SMoore, Eric Dean /* Clear the pointer used to store 3102496af39SMoore, Eric Dean * single-threaded commands, i.e., those 3112496af39SMoore, Eric Dean * issued during a bus scan, dv and 3122496af39SMoore, Eric Dean * configuration pages. 3132496af39SMoore, Eric Dean */ 3142496af39SMoore, Eric Dean hd->cmdPtr = NULL; 3152496af39SMoore, Eric Dean 3162496af39SMoore, Eric Dean /* Initialize this SCSI Hosts' timers 3172496af39SMoore, Eric Dean * To use, set the timer expires field 3182496af39SMoore, Eric Dean * and add_timer 3192496af39SMoore, Eric Dean */ 3202496af39SMoore, Eric Dean init_timer(&hd->timer); 3212496af39SMoore, Eric Dean hd->timer.data = (unsigned long) hd; 3222496af39SMoore, Eric Dean hd->timer.function = mptscsih_timer_expired; 3232496af39SMoore, Eric Dean 3242496af39SMoore, Eric Dean hd->mpt_pq_filter = mpt_pq_filter; 3252496af39SMoore, Eric Dean 3262496af39SMoore, Eric Dean ddvprintk((MYIOC_s_INFO_FMT 3272496af39SMoore, Eric Dean "mpt_pq_filter %x\n", 3282496af39SMoore, Eric Dean ioc->name, 3292496af39SMoore, Eric Dean mpt_pq_filter)); 3302496af39SMoore, Eric Dean 3312496af39SMoore, Eric Dean init_waitqueue_head(&hd->scandv_waitq); 3322496af39SMoore, Eric Dean hd->scandv_wait_done = 0; 3332496af39SMoore, Eric Dean hd->last_queue_full = 0; 3342496af39SMoore, Eric Dean 3352496af39SMoore, Eric Dean error = scsi_add_host (sh, &ioc->pcidev->dev); 3362496af39SMoore, Eric Dean if(error) { 3372496af39SMoore, Eric Dean dprintk((KERN_ERR MYNAM 3382496af39SMoore, Eric Dean "scsi_add_host failed\n")); 3397acec1e7SMoore, Eric Dean goto out_mptfc_probe; 3402496af39SMoore, Eric Dean } 3412496af39SMoore, Eric Dean 3422496af39SMoore, Eric Dean scsi_scan_host(sh); 3432496af39SMoore, Eric Dean return 0; 3442496af39SMoore, Eric Dean 3457acec1e7SMoore, Eric Dean out_mptfc_probe: 3462496af39SMoore, Eric Dean 3472496af39SMoore, Eric Dean mptscsih_remove(pdev); 3482496af39SMoore, Eric Dean return error; 3492496af39SMoore, Eric Dean } 3502496af39SMoore, Eric Dean 3512496af39SMoore, Eric Dean static struct pci_driver mptfc_driver = { 3522496af39SMoore, Eric Dean .name = "mptfc", 3532496af39SMoore, Eric Dean .id_table = mptfc_pci_table, 3542496af39SMoore, Eric Dean .probe = mptfc_probe, 3552496af39SMoore, Eric Dean .remove = __devexit_p(mptscsih_remove), 3562496af39SMoore, Eric Dean .shutdown = mptscsih_shutdown, 3572496af39SMoore, Eric Dean #ifdef CONFIG_PM 3582496af39SMoore, Eric Dean .suspend = mptscsih_suspend, 3592496af39SMoore, Eric Dean .resume = mptscsih_resume, 3602496af39SMoore, Eric Dean #endif 3612496af39SMoore, Eric Dean }; 3622496af39SMoore, Eric Dean 3632496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3642496af39SMoore, Eric Dean /** 3652496af39SMoore, Eric Dean * mptfc_init - Register MPT adapter(s) as SCSI host(s) with 3662496af39SMoore, Eric Dean * linux scsi mid-layer. 3672496af39SMoore, Eric Dean * 3682496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 3692496af39SMoore, Eric Dean */ 3702496af39SMoore, Eric Dean static int __init 3712496af39SMoore, Eric Dean mptfc_init(void) 3722496af39SMoore, Eric Dean { 3732496af39SMoore, Eric Dean 3742496af39SMoore, Eric Dean show_mptmod_ver(my_NAME, my_VERSION); 3752496af39SMoore, Eric Dean 3762496af39SMoore, Eric Dean mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); 3772496af39SMoore, Eric Dean mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 3782496af39SMoore, Eric Dean mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 3792496af39SMoore, Eric Dean 3802496af39SMoore, Eric Dean if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { 3812496af39SMoore, Eric Dean devtprintk((KERN_INFO MYNAM 3822496af39SMoore, Eric Dean ": Registered for IOC event notifications\n")); 3832496af39SMoore, Eric Dean } 3842496af39SMoore, Eric Dean 3852496af39SMoore, Eric Dean if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) { 3862496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 3872496af39SMoore, Eric Dean ": Registered for IOC reset notifications\n")); 3882496af39SMoore, Eric Dean } 3892496af39SMoore, Eric Dean 3902496af39SMoore, Eric Dean return pci_register_driver(&mptfc_driver); 3912496af39SMoore, Eric Dean } 3922496af39SMoore, Eric Dean 3932496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3942496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3952496af39SMoore, Eric Dean /** 3962496af39SMoore, Eric Dean * mptfc_exit - Unregisters MPT adapter(s) 3972496af39SMoore, Eric Dean * 3982496af39SMoore, Eric Dean */ 3992496af39SMoore, Eric Dean static void __exit 4002496af39SMoore, Eric Dean mptfc_exit(void) 4012496af39SMoore, Eric Dean { 4022496af39SMoore, Eric Dean pci_unregister_driver(&mptfc_driver); 4032496af39SMoore, Eric Dean 4042496af39SMoore, Eric Dean mpt_reset_deregister(mptfcDoneCtx); 4052496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 4062496af39SMoore, Eric Dean ": Deregistered for IOC reset notifications\n")); 4072496af39SMoore, Eric Dean 4082496af39SMoore, Eric Dean mpt_event_deregister(mptfcDoneCtx); 4092496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 4102496af39SMoore, Eric Dean ": Deregistered for IOC event notifications\n")); 4112496af39SMoore, Eric Dean 4122496af39SMoore, Eric Dean mpt_deregister(mptfcInternalCtx); 4132496af39SMoore, Eric Dean mpt_deregister(mptfcTaskCtx); 4142496af39SMoore, Eric Dean mpt_deregister(mptfcDoneCtx); 4152496af39SMoore, Eric Dean } 4162496af39SMoore, Eric Dean 4172496af39SMoore, Eric Dean module_init(mptfc_init); 4182496af39SMoore, Eric Dean module_exit(mptfc_exit); 419