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