1*2496af39SMoore, Eric Dean /* 2*2496af39SMoore, Eric Dean * linux/drivers/message/fusion/mptfc.c 3*2496af39SMoore, Eric Dean * For use with LSI Logic PCI chip/adapter(s) 4*2496af39SMoore, Eric Dean * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 5*2496af39SMoore, Eric Dean * 6*2496af39SMoore, Eric Dean * Copyright (c) 1999-2005 LSI Logic Corporation 7*2496af39SMoore, Eric Dean * (mailto:mpt_linux_developer@lsil.com) 8*2496af39SMoore, Eric Dean * 9*2496af39SMoore, Eric Dean */ 10*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 11*2496af39SMoore, Eric Dean /* 12*2496af39SMoore, Eric Dean This program is free software; you can redistribute it and/or modify 13*2496af39SMoore, Eric Dean it under the terms of the GNU General Public License as published by 14*2496af39SMoore, Eric Dean the Free Software Foundation; version 2 of the License. 15*2496af39SMoore, Eric Dean 16*2496af39SMoore, Eric Dean This program is distributed in the hope that it will be useful, 17*2496af39SMoore, Eric Dean but WITHOUT ANY WARRANTY; without even the implied warranty of 18*2496af39SMoore, Eric Dean MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19*2496af39SMoore, Eric Dean GNU General Public License for more details. 20*2496af39SMoore, Eric Dean 21*2496af39SMoore, Eric Dean NO WARRANTY 22*2496af39SMoore, Eric Dean THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 23*2496af39SMoore, Eric Dean CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 24*2496af39SMoore, Eric Dean LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 25*2496af39SMoore, Eric Dean MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 26*2496af39SMoore, Eric Dean solely responsible for determining the appropriateness of using and 27*2496af39SMoore, Eric Dean distributing the Program and assumes all risks associated with its 28*2496af39SMoore, Eric Dean exercise of rights under this Agreement, including but not limited to 29*2496af39SMoore, Eric Dean the risks and costs of program errors, damage to or loss of data, 30*2496af39SMoore, Eric Dean programs or equipment, and unavailability or interruption of operations. 31*2496af39SMoore, Eric Dean 32*2496af39SMoore, Eric Dean DISCLAIMER OF LIABILITY 33*2496af39SMoore, Eric Dean NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 34*2496af39SMoore, Eric Dean DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35*2496af39SMoore, Eric Dean DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 36*2496af39SMoore, Eric Dean ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 37*2496af39SMoore, Eric Dean TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 38*2496af39SMoore, Eric Dean USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 39*2496af39SMoore, Eric Dean HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 40*2496af39SMoore, Eric Dean 41*2496af39SMoore, Eric Dean You should have received a copy of the GNU General Public License 42*2496af39SMoore, Eric Dean along with this program; if not, write to the Free Software 43*2496af39SMoore, Eric Dean Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 44*2496af39SMoore, Eric Dean */ 45*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 46*2496af39SMoore, Eric Dean #include "linux_compat.h" /* linux-2.6 tweaks */ 47*2496af39SMoore, Eric Dean #include <linux/module.h> 48*2496af39SMoore, Eric Dean #include <linux/kernel.h> 49*2496af39SMoore, Eric Dean #include <linux/init.h> 50*2496af39SMoore, Eric Dean #include <linux/errno.h> 51*2496af39SMoore, Eric Dean #include <linux/kdev_t.h> 52*2496af39SMoore, Eric Dean #include <linux/blkdev.h> 53*2496af39SMoore, Eric Dean #include <linux/delay.h> /* for mdelay */ 54*2496af39SMoore, Eric Dean #include <linux/interrupt.h> /* needed for in_interrupt() proto */ 55*2496af39SMoore, Eric Dean #include <linux/reboot.h> /* notifier code */ 56*2496af39SMoore, Eric Dean #include <linux/sched.h> 57*2496af39SMoore, Eric Dean #include <linux/workqueue.h> 58*2496af39SMoore, Eric Dean 59*2496af39SMoore, Eric Dean #include <scsi/scsi.h> 60*2496af39SMoore, Eric Dean #include <scsi/scsi_cmnd.h> 61*2496af39SMoore, Eric Dean #include <scsi/scsi_device.h> 62*2496af39SMoore, Eric Dean #include <scsi/scsi_host.h> 63*2496af39SMoore, Eric Dean #include <scsi/scsi_tcq.h> 64*2496af39SMoore, Eric Dean 65*2496af39SMoore, Eric Dean #include "mptbase.h" 66*2496af39SMoore, Eric Dean #include "mptscsih.h" 67*2496af39SMoore, Eric Dean 68*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 69*2496af39SMoore, Eric Dean #define my_NAME "Fusion MPT FC Host driver" 70*2496af39SMoore, Eric Dean #define my_VERSION MPT_LINUX_VERSION_COMMON 71*2496af39SMoore, Eric Dean #define MYNAM "mptfc" 72*2496af39SMoore, Eric Dean 73*2496af39SMoore, Eric Dean MODULE_AUTHOR(MODULEAUTHOR); 74*2496af39SMoore, Eric Dean MODULE_DESCRIPTION(my_NAME); 75*2496af39SMoore, Eric Dean MODULE_LICENSE("GPL"); 76*2496af39SMoore, Eric Dean 77*2496af39SMoore, Eric Dean /* Command line args */ 78*2496af39SMoore, Eric Dean static int mpt_pq_filter = 0; 79*2496af39SMoore, Eric Dean module_param(mpt_pq_filter, int, 0); 80*2496af39SMoore, Eric Dean MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)"); 81*2496af39SMoore, Eric Dean 82*2496af39SMoore, Eric Dean static int mptfcDoneCtx = -1; 83*2496af39SMoore, Eric Dean static int mptfcTaskCtx = -1; 84*2496af39SMoore, Eric Dean static int mptfcInternalCtx = -1; /* Used only for internal commands */ 85*2496af39SMoore, Eric Dean 86*2496af39SMoore, Eric Dean static struct device_attribute mptfc_queue_depth_attr = { 87*2496af39SMoore, Eric Dean .attr = { 88*2496af39SMoore, Eric Dean .name = "queue_depth", 89*2496af39SMoore, Eric Dean .mode = S_IWUSR, 90*2496af39SMoore, Eric Dean }, 91*2496af39SMoore, Eric Dean .store = mptscsih_store_queue_depth, 92*2496af39SMoore, Eric Dean }; 93*2496af39SMoore, Eric Dean 94*2496af39SMoore, Eric Dean static struct device_attribute *mptfc_dev_attrs[] = { 95*2496af39SMoore, Eric Dean &mptfc_queue_depth_attr, 96*2496af39SMoore, Eric Dean NULL, 97*2496af39SMoore, Eric Dean }; 98*2496af39SMoore, Eric Dean 99*2496af39SMoore, Eric Dean static struct scsi_host_template mptfc_driver_template = { 100*2496af39SMoore, Eric Dean .proc_name = "mptfc", 101*2496af39SMoore, Eric Dean .proc_info = mptscsih_proc_info, 102*2496af39SMoore, Eric Dean .name = "MPT FC Host", 103*2496af39SMoore, Eric Dean .info = mptscsih_info, 104*2496af39SMoore, Eric Dean .queuecommand = mptscsih_qcmd, 105*2496af39SMoore, Eric Dean .slave_alloc = mptscsih_slave_alloc, 106*2496af39SMoore, Eric Dean .slave_configure = mptscsih_slave_configure, 107*2496af39SMoore, Eric Dean .slave_destroy = mptscsih_slave_destroy, 108*2496af39SMoore, Eric Dean .eh_abort_handler = mptscsih_abort, 109*2496af39SMoore, Eric Dean .eh_device_reset_handler = mptscsih_dev_reset, 110*2496af39SMoore, Eric Dean .eh_bus_reset_handler = mptscsih_bus_reset, 111*2496af39SMoore, Eric Dean .eh_host_reset_handler = mptscsih_host_reset, 112*2496af39SMoore, Eric Dean .bios_param = mptscsih_bios_param, 113*2496af39SMoore, Eric Dean .can_queue = MPT_FC_CAN_QUEUE, 114*2496af39SMoore, Eric Dean .this_id = -1, 115*2496af39SMoore, Eric Dean .sg_tablesize = MPT_SCSI_SG_DEPTH, 116*2496af39SMoore, Eric Dean .max_sectors = 8192, 117*2496af39SMoore, Eric Dean .cmd_per_lun = 7, 118*2496af39SMoore, Eric Dean .use_clustering = ENABLE_CLUSTERING, 119*2496af39SMoore, Eric Dean .sdev_attrs = mptfc_dev_attrs, 120*2496af39SMoore, Eric Dean }; 121*2496af39SMoore, Eric Dean 122*2496af39SMoore, Eric Dean /**************************************************************************** 123*2496af39SMoore, Eric Dean * Supported hardware 124*2496af39SMoore, Eric Dean */ 125*2496af39SMoore, Eric Dean 126*2496af39SMoore, Eric Dean static struct pci_device_id mptfc_pci_table[] = { 127*2496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC909, 128*2496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 129*2496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919, 130*2496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 131*2496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929, 132*2496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 133*2496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC919X, 134*2496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 135*2496af39SMoore, Eric Dean { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_FC929X, 136*2496af39SMoore, Eric Dean PCI_ANY_ID, PCI_ANY_ID }, 137*2496af39SMoore, Eric Dean {0} /* Terminating entry */ 138*2496af39SMoore, Eric Dean }; 139*2496af39SMoore, Eric Dean MODULE_DEVICE_TABLE(pci, mptfc_pci_table); 140*2496af39SMoore, Eric Dean 141*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 142*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 143*2496af39SMoore, Eric Dean /* 144*2496af39SMoore, Eric Dean * mptfc_probe - Installs scsi devices per bus. 145*2496af39SMoore, Eric Dean * @pdev: Pointer to pci_dev structure 146*2496af39SMoore, Eric Dean * 147*2496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 148*2496af39SMoore, Eric Dean * 149*2496af39SMoore, Eric Dean */ 150*2496af39SMoore, Eric Dean static int 151*2496af39SMoore, Eric Dean mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) 152*2496af39SMoore, Eric Dean { 153*2496af39SMoore, Eric Dean struct Scsi_Host *sh; 154*2496af39SMoore, Eric Dean MPT_SCSI_HOST *hd; 155*2496af39SMoore, Eric Dean MPT_ADAPTER *ioc; 156*2496af39SMoore, Eric Dean unsigned long flags; 157*2496af39SMoore, Eric Dean int sz, ii; 158*2496af39SMoore, Eric Dean int numSGE = 0; 159*2496af39SMoore, Eric Dean int scale; 160*2496af39SMoore, Eric Dean int ioc_cap; 161*2496af39SMoore, Eric Dean u8 *mem; 162*2496af39SMoore, Eric Dean int error=0; 163*2496af39SMoore, Eric Dean int r; 164*2496af39SMoore, Eric Dean 165*2496af39SMoore, Eric Dean if ((r = mpt_attach(pdev,id)) != 0) 166*2496af39SMoore, Eric Dean return r; 167*2496af39SMoore, Eric Dean 168*2496af39SMoore, Eric Dean ioc = pci_get_drvdata(pdev); 169*2496af39SMoore, Eric Dean 170*2496af39SMoore, Eric Dean /* Added sanity check on readiness of the MPT adapter. 171*2496af39SMoore, Eric Dean */ 172*2496af39SMoore, Eric Dean if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 173*2496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 174*2496af39SMoore, Eric Dean "Skipping because it's not operational!\n", 175*2496af39SMoore, Eric Dean ioc->name); 176*2496af39SMoore, Eric Dean return -ENODEV; 177*2496af39SMoore, Eric Dean } 178*2496af39SMoore, Eric Dean 179*2496af39SMoore, Eric Dean if (!ioc->active) { 180*2496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", 181*2496af39SMoore, Eric Dean ioc->name); 182*2496af39SMoore, Eric Dean return -ENODEV; 183*2496af39SMoore, Eric Dean } 184*2496af39SMoore, Eric Dean 185*2496af39SMoore, Eric Dean /* Sanity check - ensure at least 1 port is INITIATOR capable 186*2496af39SMoore, Eric Dean */ 187*2496af39SMoore, Eric Dean ioc_cap = 0; 188*2496af39SMoore, Eric Dean for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 189*2496af39SMoore, Eric Dean if (ioc->pfacts[ii].ProtocolFlags & 190*2496af39SMoore, Eric Dean MPI_PORTFACTS_PROTOCOL_INITIATOR) 191*2496af39SMoore, Eric Dean ioc_cap ++; 192*2496af39SMoore, Eric Dean } 193*2496af39SMoore, Eric Dean 194*2496af39SMoore, Eric Dean if (!ioc_cap) { 195*2496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 196*2496af39SMoore, Eric Dean "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 197*2496af39SMoore, Eric Dean ioc->name, ioc); 198*2496af39SMoore, Eric Dean return -ENODEV; 199*2496af39SMoore, Eric Dean } 200*2496af39SMoore, Eric Dean 201*2496af39SMoore, Eric Dean sh = scsi_host_alloc(&mptfc_driver_template, sizeof(MPT_SCSI_HOST)); 202*2496af39SMoore, Eric Dean 203*2496af39SMoore, Eric Dean if (!sh) { 204*2496af39SMoore, Eric Dean printk(MYIOC_s_WARN_FMT 205*2496af39SMoore, Eric Dean "Unable to register controller with SCSI subsystem\n", 206*2496af39SMoore, Eric Dean ioc->name); 207*2496af39SMoore, Eric Dean return -1; 208*2496af39SMoore, Eric Dean } 209*2496af39SMoore, Eric Dean 210*2496af39SMoore, Eric Dean spin_lock_irqsave(&ioc->FreeQlock, flags); 211*2496af39SMoore, Eric Dean 212*2496af39SMoore, Eric Dean /* Attach the SCSI Host to the IOC structure 213*2496af39SMoore, Eric Dean */ 214*2496af39SMoore, Eric Dean ioc->sh = sh; 215*2496af39SMoore, Eric Dean 216*2496af39SMoore, Eric Dean sh->io_port = 0; 217*2496af39SMoore, Eric Dean sh->n_io_port = 0; 218*2496af39SMoore, Eric Dean sh->irq = 0; 219*2496af39SMoore, Eric Dean 220*2496af39SMoore, Eric Dean /* set 16 byte cdb's */ 221*2496af39SMoore, Eric Dean sh->max_cmd_len = 16; 222*2496af39SMoore, Eric Dean 223*2496af39SMoore, Eric Dean sh->max_id = MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255; 224*2496af39SMoore, Eric Dean 225*2496af39SMoore, Eric Dean sh->max_lun = MPT_LAST_LUN + 1; 226*2496af39SMoore, Eric Dean sh->max_channel = 0; 227*2496af39SMoore, Eric Dean sh->this_id = ioc->pfacts[0].PortSCSIID; 228*2496af39SMoore, Eric Dean 229*2496af39SMoore, Eric Dean /* Required entry. 230*2496af39SMoore, Eric Dean */ 231*2496af39SMoore, Eric Dean sh->unique_id = ioc->id; 232*2496af39SMoore, Eric Dean 233*2496af39SMoore, Eric Dean /* Verify that we won't exceed the maximum 234*2496af39SMoore, Eric Dean * number of chain buffers 235*2496af39SMoore, Eric Dean * We can optimize: ZZ = req_sz/sizeof(SGE) 236*2496af39SMoore, Eric Dean * For 32bit SGE's: 237*2496af39SMoore, Eric Dean * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ 238*2496af39SMoore, Eric Dean * + (req_sz - 64)/sizeof(SGE) 239*2496af39SMoore, Eric Dean * A slightly different algorithm is required for 240*2496af39SMoore, Eric Dean * 64bit SGEs. 241*2496af39SMoore, Eric Dean */ 242*2496af39SMoore, Eric Dean scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 243*2496af39SMoore, Eric Dean if (sizeof(dma_addr_t) == sizeof(u64)) { 244*2496af39SMoore, Eric Dean numSGE = (scale - 1) * 245*2496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 246*2496af39SMoore, Eric Dean (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 247*2496af39SMoore, Eric Dean sizeof(u32)); 248*2496af39SMoore, Eric Dean } else { 249*2496af39SMoore, Eric Dean numSGE = 1 + (scale - 1) * 250*2496af39SMoore, Eric Dean (ioc->facts.MaxChainDepth-1) + scale + 251*2496af39SMoore, Eric Dean (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 252*2496af39SMoore, Eric Dean sizeof(u32)); 253*2496af39SMoore, Eric Dean } 254*2496af39SMoore, Eric Dean 255*2496af39SMoore, Eric Dean if (numSGE < sh->sg_tablesize) { 256*2496af39SMoore, Eric Dean /* Reset this value */ 257*2496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT 258*2496af39SMoore, Eric Dean "Resetting sg_tablesize to %d from %d\n", 259*2496af39SMoore, Eric Dean ioc->name, numSGE, sh->sg_tablesize)); 260*2496af39SMoore, Eric Dean sh->sg_tablesize = numSGE; 261*2496af39SMoore, Eric Dean } 262*2496af39SMoore, Eric Dean 263*2496af39SMoore, Eric Dean /* Set the pci device pointer in Scsi_Host structure. 264*2496af39SMoore, Eric Dean */ 265*2496af39SMoore, Eric Dean scsi_set_device(sh, &ioc->pcidev->dev); 266*2496af39SMoore, Eric Dean 267*2496af39SMoore, Eric Dean spin_unlock_irqrestore(&ioc->FreeQlock, flags); 268*2496af39SMoore, Eric Dean 269*2496af39SMoore, Eric Dean hd = (MPT_SCSI_HOST *) sh->hostdata; 270*2496af39SMoore, Eric Dean hd->ioc = ioc; 271*2496af39SMoore, Eric Dean 272*2496af39SMoore, Eric Dean /* SCSI needs scsi_cmnd lookup table! 273*2496af39SMoore, Eric Dean * (with size equal to req_depth*PtrSz!) 274*2496af39SMoore, Eric Dean */ 275*2496af39SMoore, Eric Dean sz = ioc->req_depth * sizeof(void *); 276*2496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 277*2496af39SMoore, Eric Dean if (mem == NULL) { 278*2496af39SMoore, Eric Dean error = -ENOMEM; 279*2496af39SMoore, Eric Dean goto mptfc_probe_failed; 280*2496af39SMoore, Eric Dean } 281*2496af39SMoore, Eric Dean 282*2496af39SMoore, Eric Dean memset(mem, 0, sz); 283*2496af39SMoore, Eric Dean hd->ScsiLookup = (struct scsi_cmnd **) mem; 284*2496af39SMoore, Eric Dean 285*2496af39SMoore, Eric Dean dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", 286*2496af39SMoore, Eric Dean ioc->name, hd->ScsiLookup, sz)); 287*2496af39SMoore, Eric Dean 288*2496af39SMoore, Eric Dean /* Allocate memory for the device structures. 289*2496af39SMoore, Eric Dean * A non-Null pointer at an offset 290*2496af39SMoore, Eric Dean * indicates a device exists. 291*2496af39SMoore, Eric Dean * max_id = 1 + maximum id (hosts.h) 292*2496af39SMoore, Eric Dean */ 293*2496af39SMoore, Eric Dean sz = sh->max_id * sizeof(void *); 294*2496af39SMoore, Eric Dean mem = kmalloc(sz, GFP_ATOMIC); 295*2496af39SMoore, Eric Dean if (mem == NULL) { 296*2496af39SMoore, Eric Dean error = -ENOMEM; 297*2496af39SMoore, Eric Dean goto mptfc_probe_failed; 298*2496af39SMoore, Eric Dean } 299*2496af39SMoore, Eric Dean 300*2496af39SMoore, Eric Dean memset(mem, 0, sz); 301*2496af39SMoore, Eric Dean hd->Targets = (VirtDevice **) mem; 302*2496af39SMoore, Eric Dean 303*2496af39SMoore, Eric Dean dprintk((KERN_INFO 304*2496af39SMoore, Eric Dean " Targets @ %p, sz=%d\n", hd->Targets, sz)); 305*2496af39SMoore, Eric Dean 306*2496af39SMoore, Eric Dean /* Clear the TM flags 307*2496af39SMoore, Eric Dean */ 308*2496af39SMoore, Eric Dean hd->tmPending = 0; 309*2496af39SMoore, Eric Dean hd->tmState = TM_STATE_NONE; 310*2496af39SMoore, Eric Dean hd->resetPending = 0; 311*2496af39SMoore, Eric Dean hd->abortSCpnt = NULL; 312*2496af39SMoore, Eric Dean 313*2496af39SMoore, Eric Dean /* Clear the pointer used to store 314*2496af39SMoore, Eric Dean * single-threaded commands, i.e., those 315*2496af39SMoore, Eric Dean * issued during a bus scan, dv and 316*2496af39SMoore, Eric Dean * configuration pages. 317*2496af39SMoore, Eric Dean */ 318*2496af39SMoore, Eric Dean hd->cmdPtr = NULL; 319*2496af39SMoore, Eric Dean 320*2496af39SMoore, Eric Dean /* Initialize this SCSI Hosts' timers 321*2496af39SMoore, Eric Dean * To use, set the timer expires field 322*2496af39SMoore, Eric Dean * and add_timer 323*2496af39SMoore, Eric Dean */ 324*2496af39SMoore, Eric Dean init_timer(&hd->timer); 325*2496af39SMoore, Eric Dean hd->timer.data = (unsigned long) hd; 326*2496af39SMoore, Eric Dean hd->timer.function = mptscsih_timer_expired; 327*2496af39SMoore, Eric Dean 328*2496af39SMoore, Eric Dean ioc->DoneCtx = mptfcDoneCtx; 329*2496af39SMoore, Eric Dean ioc->TaskCtx = mptfcTaskCtx; 330*2496af39SMoore, Eric Dean ioc->InternalCtx = mptfcInternalCtx; 331*2496af39SMoore, Eric Dean 332*2496af39SMoore, Eric Dean hd->mpt_pq_filter = mpt_pq_filter; 333*2496af39SMoore, Eric Dean 334*2496af39SMoore, Eric Dean ddvprintk((MYIOC_s_INFO_FMT 335*2496af39SMoore, Eric Dean "mpt_pq_filter %x\n", 336*2496af39SMoore, Eric Dean ioc->name, 337*2496af39SMoore, Eric Dean mpt_pq_filter)); 338*2496af39SMoore, Eric Dean 339*2496af39SMoore, Eric Dean init_waitqueue_head(&hd->scandv_waitq); 340*2496af39SMoore, Eric Dean hd->scandv_wait_done = 0; 341*2496af39SMoore, Eric Dean hd->last_queue_full = 0; 342*2496af39SMoore, Eric Dean 343*2496af39SMoore, Eric Dean error = scsi_add_host (sh, &ioc->pcidev->dev); 344*2496af39SMoore, Eric Dean if(error) { 345*2496af39SMoore, Eric Dean dprintk((KERN_ERR MYNAM 346*2496af39SMoore, Eric Dean "scsi_add_host failed\n")); 347*2496af39SMoore, Eric Dean goto mptfc_probe_failed; 348*2496af39SMoore, Eric Dean } 349*2496af39SMoore, Eric Dean 350*2496af39SMoore, Eric Dean scsi_scan_host(sh); 351*2496af39SMoore, Eric Dean return 0; 352*2496af39SMoore, Eric Dean 353*2496af39SMoore, Eric Dean mptfc_probe_failed: 354*2496af39SMoore, Eric Dean 355*2496af39SMoore, Eric Dean mptscsih_remove(pdev); 356*2496af39SMoore, Eric Dean return error; 357*2496af39SMoore, Eric Dean } 358*2496af39SMoore, Eric Dean 359*2496af39SMoore, Eric Dean static struct pci_driver mptfc_driver = { 360*2496af39SMoore, Eric Dean .name = "mptfc", 361*2496af39SMoore, Eric Dean .id_table = mptfc_pci_table, 362*2496af39SMoore, Eric Dean .probe = mptfc_probe, 363*2496af39SMoore, Eric Dean .remove = __devexit_p(mptscsih_remove), 364*2496af39SMoore, Eric Dean .driver = { 365*2496af39SMoore, Eric Dean .shutdown = mptscsih_shutdown, 366*2496af39SMoore, Eric Dean }, 367*2496af39SMoore, Eric Dean #ifdef CONFIG_PM 368*2496af39SMoore, Eric Dean .suspend = mptscsih_suspend, 369*2496af39SMoore, Eric Dean .resume = mptscsih_resume, 370*2496af39SMoore, Eric Dean #endif 371*2496af39SMoore, Eric Dean }; 372*2496af39SMoore, Eric Dean 373*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 374*2496af39SMoore, Eric Dean /** 375*2496af39SMoore, Eric Dean * mptfc_init - Register MPT adapter(s) as SCSI host(s) with 376*2496af39SMoore, Eric Dean * linux scsi mid-layer. 377*2496af39SMoore, Eric Dean * 378*2496af39SMoore, Eric Dean * Returns 0 for success, non-zero for failure. 379*2496af39SMoore, Eric Dean */ 380*2496af39SMoore, Eric Dean static int __init 381*2496af39SMoore, Eric Dean mptfc_init(void) 382*2496af39SMoore, Eric Dean { 383*2496af39SMoore, Eric Dean 384*2496af39SMoore, Eric Dean show_mptmod_ver(my_NAME, my_VERSION); 385*2496af39SMoore, Eric Dean 386*2496af39SMoore, Eric Dean mptfcDoneCtx = mpt_register(mptscsih_io_done, MPTFC_DRIVER); 387*2496af39SMoore, Eric Dean mptfcTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTFC_DRIVER); 388*2496af39SMoore, Eric Dean mptfcInternalCtx = mpt_register(mptscsih_scandv_complete, MPTFC_DRIVER); 389*2496af39SMoore, Eric Dean 390*2496af39SMoore, Eric Dean if (mpt_event_register(mptfcDoneCtx, mptscsih_event_process) == 0) { 391*2496af39SMoore, Eric Dean devtprintk((KERN_INFO MYNAM 392*2496af39SMoore, Eric Dean ": Registered for IOC event notifications\n")); 393*2496af39SMoore, Eric Dean } 394*2496af39SMoore, Eric Dean 395*2496af39SMoore, Eric Dean if (mpt_reset_register(mptfcDoneCtx, mptscsih_ioc_reset) == 0) { 396*2496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 397*2496af39SMoore, Eric Dean ": Registered for IOC reset notifications\n")); 398*2496af39SMoore, Eric Dean } 399*2496af39SMoore, Eric Dean 400*2496af39SMoore, Eric Dean return pci_register_driver(&mptfc_driver); 401*2496af39SMoore, Eric Dean } 402*2496af39SMoore, Eric Dean 403*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 404*2496af39SMoore, Eric Dean /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 405*2496af39SMoore, Eric Dean /** 406*2496af39SMoore, Eric Dean * mptfc_exit - Unregisters MPT adapter(s) 407*2496af39SMoore, Eric Dean * 408*2496af39SMoore, Eric Dean */ 409*2496af39SMoore, Eric Dean static void __exit 410*2496af39SMoore, Eric Dean mptfc_exit(void) 411*2496af39SMoore, Eric Dean { 412*2496af39SMoore, Eric Dean pci_unregister_driver(&mptfc_driver); 413*2496af39SMoore, Eric Dean 414*2496af39SMoore, Eric Dean mpt_reset_deregister(mptfcDoneCtx); 415*2496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 416*2496af39SMoore, Eric Dean ": Deregistered for IOC reset notifications\n")); 417*2496af39SMoore, Eric Dean 418*2496af39SMoore, Eric Dean mpt_event_deregister(mptfcDoneCtx); 419*2496af39SMoore, Eric Dean dprintk((KERN_INFO MYNAM 420*2496af39SMoore, Eric Dean ": Deregistered for IOC event notifications\n")); 421*2496af39SMoore, Eric Dean 422*2496af39SMoore, Eric Dean mpt_deregister(mptfcInternalCtx); 423*2496af39SMoore, Eric Dean mpt_deregister(mptfcTaskCtx); 424*2496af39SMoore, Eric Dean mpt_deregister(mptfcDoneCtx); 425*2496af39SMoore, Eric Dean } 426*2496af39SMoore, Eric Dean 427*2496af39SMoore, Eric Dean module_init(mptfc_init); 428*2496af39SMoore, Eric Dean module_exit(mptfc_exit); 429