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 .module = THIS_MODULE, 107 .proc_name = "mptspi", 108 .proc_info = mptscsih_proc_info, 109 .name = "MPT SPI Host", 110 .info = mptscsih_info, 111 .queuecommand = mptscsih_qcmd, 112 .target_alloc = mptscsih_target_alloc, 113 .slave_alloc = mptscsih_slave_alloc, 114 .slave_configure = mptscsih_slave_configure, 115 .target_destroy = mptscsih_target_destroy, 116 .slave_destroy = mptscsih_slave_destroy, 117 .change_queue_depth = mptscsih_change_queue_depth, 118 .eh_abort_handler = mptscsih_abort, 119 .eh_device_reset_handler = mptscsih_dev_reset, 120 .eh_bus_reset_handler = mptscsih_bus_reset, 121 .eh_host_reset_handler = mptscsih_host_reset, 122 .bios_param = mptscsih_bios_param, 123 .can_queue = MPT_SCSI_CAN_QUEUE, 124 .this_id = -1, 125 .sg_tablesize = MPT_SCSI_SG_DEPTH, 126 .max_sectors = 8192, 127 .cmd_per_lun = 7, 128 .use_clustering = ENABLE_CLUSTERING, 129 }; 130 131 132 /**************************************************************************** 133 * Supported hardware 134 */ 135 136 static struct pci_device_id mptspi_pci_table[] = { 137 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_53C1030, 138 PCI_ANY_ID, PCI_ANY_ID }, 139 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_1030_53C1035, 140 PCI_ANY_ID, PCI_ANY_ID }, 141 {0} /* Terminating entry */ 142 }; 143 MODULE_DEVICE_TABLE(pci, mptspi_pci_table); 144 145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 147 /* 148 * mptspi_probe - Installs scsi devices per bus. 149 * @pdev: Pointer to pci_dev structure 150 * 151 * Returns 0 for success, non-zero for failure. 152 * 153 */ 154 static int 155 mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) 156 { 157 struct Scsi_Host *sh; 158 MPT_SCSI_HOST *hd; 159 MPT_ADAPTER *ioc; 160 unsigned long flags; 161 int ii; 162 int numSGE = 0; 163 int scale; 164 int ioc_cap; 165 int error=0; 166 int r; 167 168 if ((r = mpt_attach(pdev,id)) != 0) 169 return r; 170 171 ioc = pci_get_drvdata(pdev); 172 ioc->DoneCtx = mptspiDoneCtx; 173 ioc->TaskCtx = mptspiTaskCtx; 174 ioc->InternalCtx = mptspiInternalCtx; 175 176 /* Added sanity check on readiness of the MPT adapter. 177 */ 178 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 179 printk(MYIOC_s_WARN_FMT 180 "Skipping because it's not operational!\n", 181 ioc->name); 182 error = -ENODEV; 183 goto out_mptspi_probe; 184 } 185 186 if (!ioc->active) { 187 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", 188 ioc->name); 189 error = -ENODEV; 190 goto out_mptspi_probe; 191 } 192 193 /* Sanity check - ensure at least 1 port is INITIATOR capable 194 */ 195 ioc_cap = 0; 196 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 197 if (ioc->pfacts[ii].ProtocolFlags & 198 MPI_PORTFACTS_PROTOCOL_INITIATOR) 199 ioc_cap ++; 200 } 201 202 if (!ioc_cap) { 203 printk(MYIOC_s_WARN_FMT 204 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n", 205 ioc->name, ioc); 206 return 0; 207 } 208 209 sh = scsi_host_alloc(&mptspi_driver_template, sizeof(MPT_SCSI_HOST)); 210 211 if (!sh) { 212 printk(MYIOC_s_WARN_FMT 213 "Unable to register controller with SCSI subsystem\n", 214 ioc->name); 215 error = -1; 216 goto out_mptspi_probe; 217 } 218 219 spin_lock_irqsave(&ioc->FreeQlock, flags); 220 221 /* Attach the SCSI Host to the IOC structure 222 */ 223 ioc->sh = sh; 224 225 sh->io_port = 0; 226 sh->n_io_port = 0; 227 sh->irq = 0; 228 229 /* set 16 byte cdb's */ 230 sh->max_cmd_len = 16; 231 232 /* Yikes! This is important! 233 * Otherwise, by default, linux 234 * only scans target IDs 0-7! 235 * pfactsN->MaxDevices unreliable 236 * (not supported in early 237 * versions of the FW). 238 * max_id = 1 + actual max id, 239 * max_lun = 1 + actual last lun, 240 * see hosts.h :o( 241 */ 242 sh->max_id = MPT_MAX_SCSI_DEVICES; 243 244 sh->max_lun = MPT_LAST_LUN + 1; 245 sh->max_channel = 0; 246 sh->this_id = ioc->pfacts[0].PortSCSIID; 247 248 /* Required entry. 249 */ 250 sh->unique_id = ioc->id; 251 252 /* Verify that we won't exceed the maximum 253 * number of chain buffers 254 * We can optimize: ZZ = req_sz/sizeof(SGE) 255 * For 32bit SGE's: 256 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ 257 * + (req_sz - 64)/sizeof(SGE) 258 * A slightly different algorithm is required for 259 * 64bit SGEs. 260 */ 261 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 262 if (sizeof(dma_addr_t) == sizeof(u64)) { 263 numSGE = (scale - 1) * 264 (ioc->facts.MaxChainDepth-1) + scale + 265 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 266 sizeof(u32)); 267 } else { 268 numSGE = 1 + (scale - 1) * 269 (ioc->facts.MaxChainDepth-1) + scale + 270 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 271 sizeof(u32)); 272 } 273 274 if (numSGE < sh->sg_tablesize) { 275 /* Reset this value */ 276 dprintk((MYIOC_s_INFO_FMT 277 "Resetting sg_tablesize to %d from %d\n", 278 ioc->name, numSGE, sh->sg_tablesize)); 279 sh->sg_tablesize = numSGE; 280 } 281 282 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 283 284 hd = (MPT_SCSI_HOST *) sh->hostdata; 285 hd->ioc = ioc; 286 287 /* SCSI needs scsi_cmnd lookup table! 288 * (with size equal to req_depth*PtrSz!) 289 */ 290 hd->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); 291 if (!hd->ScsiLookup) { 292 error = -ENOMEM; 293 goto out_mptspi_probe; 294 } 295 296 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p\n", 297 ioc->name, hd->ScsiLookup)); 298 299 /* Allocate memory for the device structures. 300 * A non-Null pointer at an offset 301 * indicates a device exists. 302 * max_id = 1 + maximum id (hosts.h) 303 */ 304 hd->Targets = kcalloc(sh->max_id, sizeof(void *), GFP_ATOMIC); 305 if (!hd->Targets) { 306 error = -ENOMEM; 307 goto out_mptspi_probe; 308 } 309 310 dprintk((KERN_INFO " vdev @ %p\n", hd->Targets)); 311 312 /* Clear the TM flags 313 */ 314 hd->tmPending = 0; 315 hd->tmState = TM_STATE_NONE; 316 hd->resetPending = 0; 317 hd->abortSCpnt = NULL; 318 319 /* Clear the pointer used to store 320 * single-threaded commands, i.e., those 321 * issued during a bus scan, dv and 322 * configuration pages. 323 */ 324 hd->cmdPtr = NULL; 325 326 /* Initialize this SCSI Hosts' timers 327 * To use, set the timer expires field 328 * and add_timer 329 */ 330 init_timer(&hd->timer); 331 hd->timer.data = (unsigned long) hd; 332 hd->timer.function = mptscsih_timer_expired; 333 334 ioc->spi_data.Saf_Te = mpt_saf_te; 335 hd->mpt_pq_filter = mpt_pq_filter; 336 337 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 338 if (ioc->spi_data.maxBusWidth > mpt_width) 339 ioc->spi_data.maxBusWidth = mpt_width; 340 if (ioc->spi_data.minSyncFactor < mpt_factor) 341 ioc->spi_data.minSyncFactor = mpt_factor; 342 if (ioc->spi_data.minSyncFactor == MPT_ASYNC) { 343 ioc->spi_data.maxSyncOffset = 0; 344 } 345 ioc->spi_data.mpt_dv = mpt_dv; 346 hd->negoNvram = 0; 347 348 ddvprintk((MYIOC_s_INFO_FMT 349 "dv %x width %x factor %x saf_te %x mpt_pq_filter %x\n", 350 ioc->name, 351 mpt_dv, 352 mpt_width, 353 mpt_factor, 354 mpt_saf_te, 355 mpt_pq_filter)); 356 #else 357 hd->negoNvram = MPT_SCSICFG_USE_NVRAM; 358 ddvprintk((MYIOC_s_INFO_FMT 359 "saf_te %x mpt_pq_filter %x\n", 360 ioc->name, 361 mpt_saf_te, 362 mpt_pq_filter)); 363 #endif 364 365 ioc->spi_data.forceDv = 0; 366 ioc->spi_data.noQas = 0; 367 368 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) 369 ioc->spi_data.dvStatus[ii] = 370 MPT_SCSICFG_NEGOTIATE; 371 372 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) 373 ioc->spi_data.dvStatus[ii] |= 374 MPT_SCSICFG_DV_NOT_DONE; 375 376 init_waitqueue_head(&hd->scandv_waitq); 377 hd->scandv_wait_done = 0; 378 hd->last_queue_full = 0; 379 380 error = scsi_add_host (sh, &ioc->pcidev->dev); 381 if(error) { 382 dprintk((KERN_ERR MYNAM 383 "scsi_add_host failed\n")); 384 goto out_mptspi_probe; 385 } 386 387 /* 388 * issue internal bus reset 389 */ 390 if (ioc->spi_data.bus_reset) 391 mptscsih_TMHandler(hd, 392 MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 393 0, 0, 0, 0, 5); 394 395 scsi_scan_host(sh); 396 return 0; 397 398 out_mptspi_probe: 399 400 mptscsih_remove(pdev); 401 return error; 402 } 403 404 static struct pci_driver mptspi_driver = { 405 .name = "mptspi", 406 .id_table = mptspi_pci_table, 407 .probe = mptspi_probe, 408 .remove = __devexit_p(mptscsih_remove), 409 .shutdown = mptscsih_shutdown, 410 #ifdef CONFIG_PM 411 .suspend = mptscsih_suspend, 412 .resume = mptscsih_resume, 413 #endif 414 }; 415 416 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 417 /** 418 * mptspi_init - Register MPT adapter(s) as SCSI host(s) with 419 * linux scsi mid-layer. 420 * 421 * Returns 0 for success, non-zero for failure. 422 */ 423 static int __init 424 mptspi_init(void) 425 { 426 427 show_mptmod_ver(my_NAME, my_VERSION); 428 429 mptspiDoneCtx = mpt_register(mptscsih_io_done, MPTSPI_DRIVER); 430 mptspiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSPI_DRIVER); 431 mptspiInternalCtx = mpt_register(mptscsih_scandv_complete, MPTSPI_DRIVER); 432 433 if (mpt_event_register(mptspiDoneCtx, mptscsih_event_process) == 0) { 434 devtprintk((KERN_INFO MYNAM 435 ": Registered for IOC event notifications\n")); 436 } 437 438 if (mpt_reset_register(mptspiDoneCtx, mptscsih_ioc_reset) == 0) { 439 dprintk((KERN_INFO MYNAM 440 ": Registered for IOC reset notifications\n")); 441 } 442 443 return pci_register_driver(&mptspi_driver); 444 } 445 446 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 448 /** 449 * mptspi_exit - Unregisters MPT adapter(s) 450 * 451 */ 452 static void __exit 453 mptspi_exit(void) 454 { 455 pci_unregister_driver(&mptspi_driver); 456 457 mpt_reset_deregister(mptspiDoneCtx); 458 dprintk((KERN_INFO MYNAM 459 ": Deregistered for IOC reset notifications\n")); 460 461 mpt_event_deregister(mptspiDoneCtx); 462 dprintk((KERN_INFO MYNAM 463 ": Deregistered for IOC event notifications\n")); 464 465 mpt_deregister(mptspiInternalCtx); 466 mpt_deregister(mptspiTaskCtx); 467 mpt_deregister(mptspiDoneCtx); 468 } 469 470 module_init(mptspi_init); 471 module_exit(mptspi_exit); 472