1 /* 2 * linux/drivers/message/fusion/mptsas.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 * Copyright (c) 2005 Dell 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/module.h> 48 #include <linux/kernel.h> 49 #include <linux/init.h> 50 #include <linux/errno.h> 51 #include <linux/sched.h> 52 #include <linux/workqueue.h> 53 54 #include <scsi/scsi_cmnd.h> 55 #include <scsi/scsi_device.h> 56 #include <scsi/scsi_host.h> 57 #include <scsi/scsi_transport_sas.h> 58 59 #include "mptbase.h" 60 #include "mptscsih.h" 61 62 63 #define my_NAME "Fusion MPT SAS Host driver" 64 #define my_VERSION MPT_LINUX_VERSION_COMMON 65 #define MYNAM "mptsas" 66 67 MODULE_AUTHOR(MODULEAUTHOR); 68 MODULE_DESCRIPTION(my_NAME); 69 MODULE_LICENSE("GPL"); 70 71 static int mpt_pq_filter; 72 module_param(mpt_pq_filter, int, 0); 73 MODULE_PARM_DESC(mpt_pq_filter, 74 "Enable peripheral qualifier filter: enable=1 " 75 "(default=0)"); 76 77 static int mpt_pt_clear; 78 module_param(mpt_pt_clear, int, 0); 79 MODULE_PARM_DESC(mpt_pt_clear, 80 "Clear persistency table: enable=1 " 81 "(default=MPTSCSIH_PT_CLEAR=0)"); 82 83 static int mptsasDoneCtx = -1; 84 static int mptsasTaskCtx = -1; 85 static int mptsasInternalCtx = -1; /* Used only for internal commands */ 86 87 88 /* 89 * SAS topology structures 90 * 91 * The MPT Fusion firmware interface spreads information about the 92 * SAS topology over many manufacture pages, thus we need some data 93 * structure to collect it and process it for the SAS transport class. 94 */ 95 96 struct mptsas_devinfo { 97 u16 handle; /* unique id to address this device */ 98 u8 phy_id; /* phy number of parent device */ 99 u8 port_id; /* sas physical port this device 100 is assoc'd with */ 101 u8 target; /* logical target id of this device */ 102 u8 bus; /* logical bus number of this device */ 103 u64 sas_address; /* WWN of this device, 104 SATA is assigned by HBA,expander */ 105 u32 device_info; /* bitfield detailed info about this device */ 106 }; 107 108 struct mptsas_phyinfo { 109 u8 phy_id; /* phy index */ 110 u8 port_id; /* port number this phy is part of */ 111 u8 negotiated_link_rate; /* nego'd link rate for this phy */ 112 u8 hw_link_rate; /* hardware max/min phys link rate */ 113 u8 programmed_link_rate; /* programmed max/min phy link rate */ 114 struct mptsas_devinfo identify; /* point to phy device info */ 115 struct mptsas_devinfo attached; /* point to attached device info */ 116 struct sas_rphy *rphy; 117 }; 118 119 struct mptsas_portinfo { 120 struct list_head list; 121 u16 handle; /* unique id to address this */ 122 u8 num_phys; /* number of phys */ 123 struct mptsas_phyinfo *phy_info; 124 }; 125 126 /* 127 * This is pretty ugly. We will be able to seriously clean it up 128 * once the DV code in mptscsih goes away and we can properly 129 * implement ->target_alloc. 130 */ 131 static int 132 mptsas_slave_alloc(struct scsi_device *device) 133 { 134 struct Scsi_Host *host = device->host; 135 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 136 struct sas_rphy *rphy; 137 struct mptsas_portinfo *p; 138 VirtDevice *vdev; 139 uint target = device->id; 140 int i; 141 142 if ((vdev = hd->Targets[target]) != NULL) 143 goto out; 144 145 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); 146 if (!vdev) { 147 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 148 hd->ioc->name, sizeof(VirtDevice)); 149 return -ENOMEM; 150 } 151 152 memset(vdev, 0, sizeof(VirtDevice)); 153 vdev->tflags = MPT_TARGET_FLAGS_Q_YES|MPT_TARGET_FLAGS_VALID_INQUIRY; 154 vdev->ioc_id = hd->ioc->id; 155 156 rphy = dev_to_rphy(device->sdev_target->dev.parent); 157 list_for_each_entry(p, &hd->ioc->sas_topology, list) { 158 for (i = 0; i < p->num_phys; i++) { 159 if (p->phy_info[i].attached.sas_address == 160 rphy->identify.sas_address) { 161 vdev->target_id = 162 p->phy_info[i].attached.target; 163 vdev->bus_id = p->phy_info[i].attached.bus; 164 hd->Targets[device->id] = vdev; 165 goto out; 166 } 167 } 168 } 169 170 printk("No matching SAS device found!!\n"); 171 kfree(vdev); 172 return -ENODEV; 173 174 out: 175 vdev->num_luns++; 176 device->hostdata = vdev; 177 return 0; 178 } 179 180 static struct scsi_host_template mptsas_driver_template = { 181 .proc_name = "mptsas", 182 .proc_info = mptscsih_proc_info, 183 .name = "MPT SPI Host", 184 .info = mptscsih_info, 185 .queuecommand = mptscsih_qcmd, 186 .slave_alloc = mptsas_slave_alloc, 187 .slave_configure = mptscsih_slave_configure, 188 .slave_destroy = mptscsih_slave_destroy, 189 .change_queue_depth = mptscsih_change_queue_depth, 190 .eh_abort_handler = mptscsih_abort, 191 .eh_device_reset_handler = mptscsih_dev_reset, 192 .eh_bus_reset_handler = mptscsih_bus_reset, 193 .eh_host_reset_handler = mptscsih_host_reset, 194 .bios_param = mptscsih_bios_param, 195 .can_queue = MPT_FC_CAN_QUEUE, 196 .this_id = -1, 197 .sg_tablesize = MPT_SCSI_SG_DEPTH, 198 .max_sectors = 8192, 199 .cmd_per_lun = 7, 200 .use_clustering = ENABLE_CLUSTERING, 201 }; 202 203 static struct sas_function_template mptsas_transport_functions = { 204 }; 205 206 static struct scsi_transport_template *mptsas_transport_template; 207 208 #ifdef SASDEBUG 209 static void mptsas_print_phy_data(MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) 210 { 211 printk("---- IO UNIT PAGE 0 ------------\n"); 212 printk("Handle=0x%X\n", 213 le16_to_cpu(phy_data->AttachedDeviceHandle)); 214 printk("Controller Handle=0x%X\n", 215 le16_to_cpu(phy_data->ControllerDevHandle)); 216 printk("Port=0x%X\n", phy_data->Port); 217 printk("Port Flags=0x%X\n", phy_data->PortFlags); 218 printk("PHY Flags=0x%X\n", phy_data->PhyFlags); 219 printk("Negotiated Link Rate=0x%X\n", phy_data->NegotiatedLinkRate); 220 printk("Controller PHY Device Info=0x%X\n", 221 le32_to_cpu(phy_data->ControllerPhyDeviceInfo)); 222 printk("DiscoveryStatus=0x%X\n", 223 le32_to_cpu(phy_data->DiscoveryStatus)); 224 printk("\n"); 225 } 226 227 static void mptsas_print_phy_pg0(SasPhyPage0_t *pg0) 228 { 229 __le64 sas_address; 230 231 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); 232 233 printk("---- SAS PHY PAGE 0 ------------\n"); 234 printk("Attached Device Handle=0x%X\n", 235 le16_to_cpu(pg0->AttachedDevHandle)); 236 printk("SAS Address=0x%llX\n", 237 (unsigned long long)le64_to_cpu(sas_address)); 238 printk("Attached PHY Identifier=0x%X\n", pg0->AttachedPhyIdentifier); 239 printk("Attached Device Info=0x%X\n", 240 le32_to_cpu(pg0->AttachedDeviceInfo)); 241 printk("Programmed Link Rate=0x%X\n", pg0->ProgrammedLinkRate); 242 printk("Change Count=0x%X\n", pg0->ChangeCount); 243 printk("PHY Info=0x%X\n", le32_to_cpu(pg0->PhyInfo)); 244 printk("\n"); 245 } 246 247 static void mptsas_print_device_pg0(SasDevicePage0_t *pg0) 248 { 249 __le64 sas_address; 250 251 memcpy(&sas_address, &pg0->SASAddress, sizeof(__le64)); 252 253 printk("---- SAS DEVICE PAGE 0 ---------\n"); 254 printk("Handle=0x%X\n" ,le16_to_cpu(pg0->DevHandle)); 255 printk("Enclosure Handle=0x%X\n", le16_to_cpu(pg0->EnclosureHandle)); 256 printk("Slot=0x%X\n", le16_to_cpu(pg0->Slot)); 257 printk("SAS Address=0x%llX\n", le64_to_cpu(sas_address)); 258 printk("Target ID=0x%X\n", pg0->TargetID); 259 printk("Bus=0x%X\n", pg0->Bus); 260 printk("PhyNum=0x%X\n", pg0->PhyNum); 261 printk("AccessStatus=0x%X\n", le16_to_cpu(pg0->AccessStatus)); 262 printk("Device Info=0x%X\n", le32_to_cpu(pg0->DeviceInfo)); 263 printk("Flags=0x%X\n", le16_to_cpu(pg0->Flags)); 264 printk("Physical Port=0x%X\n", pg0->PhysicalPort); 265 printk("\n"); 266 } 267 268 static void mptsas_print_expander_pg1(SasExpanderPage1_t *pg1) 269 { 270 printk("---- SAS EXPANDER PAGE 1 ------------\n"); 271 272 printk("Physical Port=0x%X\n", pg1->PhysicalPort); 273 printk("PHY Identifier=0x%X\n", pg1->Phy); 274 printk("Negotiated Link Rate=0x%X\n", pg1->NegotiatedLinkRate); 275 printk("Programmed Link Rate=0x%X\n", pg1->ProgrammedLinkRate); 276 printk("Hardware Link Rate=0x%X\n", pg1->HwLinkRate); 277 printk("Owner Device Handle=0x%X\n", 278 le16_to_cpu(pg1->OwnerDevHandle)); 279 printk("Attached Device Handle=0x%X\n", 280 le16_to_cpu(pg1->AttachedDevHandle)); 281 } 282 #else 283 #define mptsas_print_phy_data(phy_data) do { } while (0) 284 #define mptsas_print_phy_pg0(pg0) do { } while (0) 285 #define mptsas_print_device_pg0(pg0) do { } while (0) 286 #define mptsas_print_expander_pg1(pg1) do { } while (0) 287 #endif 288 289 static int 290 mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) 291 { 292 ConfigExtendedPageHeader_t hdr; 293 CONFIGPARMS cfg; 294 SasIOUnitPage0_t *buffer; 295 dma_addr_t dma_handle; 296 int error, i; 297 298 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION; 299 hdr.ExtPageLength = 0; 300 hdr.PageNumber = 0; 301 hdr.Reserved1 = 0; 302 hdr.Reserved2 = 0; 303 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 304 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; 305 306 cfg.cfghdr.ehdr = &hdr; 307 cfg.physAddr = -1; 308 cfg.pageAddr = 0; 309 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 310 cfg.dir = 0; /* read */ 311 cfg.timeout = 10; 312 313 error = mpt_config(ioc, &cfg); 314 if (error) 315 goto out; 316 if (!hdr.ExtPageLength) { 317 error = -ENXIO; 318 goto out; 319 } 320 321 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 322 &dma_handle); 323 if (!buffer) { 324 error = -ENOMEM; 325 goto out; 326 } 327 328 cfg.physAddr = dma_handle; 329 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 330 331 error = mpt_config(ioc, &cfg); 332 if (error) 333 goto out_free_consistent; 334 335 port_info->num_phys = buffer->NumPhys; 336 port_info->phy_info = kcalloc(port_info->num_phys, 337 sizeof(struct mptsas_phyinfo),GFP_KERNEL); 338 if (!port_info->phy_info) { 339 error = -ENOMEM; 340 goto out_free_consistent; 341 } 342 343 for (i = 0; i < port_info->num_phys; i++) { 344 mptsas_print_phy_data(&buffer->PhyData[i]); 345 port_info->phy_info[i].phy_id = i; 346 port_info->phy_info[i].port_id = 347 buffer->PhyData[i].Port; 348 port_info->phy_info[i].negotiated_link_rate = 349 buffer->PhyData[i].NegotiatedLinkRate; 350 } 351 352 out_free_consistent: 353 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 354 buffer, dma_handle); 355 out: 356 return error; 357 } 358 359 static int 360 mptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, 361 u32 form, u32 form_specific) 362 { 363 ConfigExtendedPageHeader_t hdr; 364 CONFIGPARMS cfg; 365 SasPhyPage0_t *buffer; 366 dma_addr_t dma_handle; 367 int error; 368 369 hdr.PageVersion = MPI_SASPHY0_PAGEVERSION; 370 hdr.ExtPageLength = 0; 371 hdr.PageNumber = 0; 372 hdr.Reserved1 = 0; 373 hdr.Reserved2 = 0; 374 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 375 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY; 376 377 cfg.cfghdr.ehdr = &hdr; 378 cfg.dir = 0; /* read */ 379 cfg.timeout = 10; 380 381 /* Get Phy Pg 0 for each Phy. */ 382 cfg.physAddr = -1; 383 cfg.pageAddr = form + form_specific; 384 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 385 386 error = mpt_config(ioc, &cfg); 387 if (error) 388 goto out; 389 390 if (!hdr.ExtPageLength) { 391 error = -ENXIO; 392 goto out; 393 } 394 395 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 396 &dma_handle); 397 if (!buffer) { 398 error = -ENOMEM; 399 goto out; 400 } 401 402 cfg.physAddr = dma_handle; 403 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 404 405 error = mpt_config(ioc, &cfg); 406 if (error) 407 goto out_free_consistent; 408 409 mptsas_print_phy_pg0(buffer); 410 411 phy_info->hw_link_rate = buffer->HwLinkRate; 412 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate; 413 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); 414 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); 415 416 out_free_consistent: 417 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 418 buffer, dma_handle); 419 out: 420 return error; 421 } 422 423 static int 424 mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, 425 u32 form, u32 form_specific) 426 { 427 ConfigExtendedPageHeader_t hdr; 428 CONFIGPARMS cfg; 429 SasDevicePage0_t *buffer; 430 dma_addr_t dma_handle; 431 __le64 sas_address; 432 int error; 433 434 hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION; 435 hdr.ExtPageLength = 0; 436 hdr.PageNumber = 0; 437 hdr.Reserved1 = 0; 438 hdr.Reserved2 = 0; 439 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 440 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE; 441 442 cfg.cfghdr.ehdr = &hdr; 443 cfg.pageAddr = form + form_specific; 444 cfg.physAddr = -1; 445 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 446 cfg.dir = 0; /* read */ 447 cfg.timeout = 10; 448 449 error = mpt_config(ioc, &cfg); 450 if (error) 451 goto out; 452 if (!hdr.ExtPageLength) { 453 error = -ENXIO; 454 goto out; 455 } 456 457 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 458 &dma_handle); 459 if (!buffer) { 460 error = -ENOMEM; 461 goto out; 462 } 463 464 cfg.physAddr = dma_handle; 465 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 466 467 error = mpt_config(ioc, &cfg); 468 if (error) 469 goto out_free_consistent; 470 471 mptsas_print_device_pg0(buffer); 472 473 device_info->handle = le16_to_cpu(buffer->DevHandle); 474 device_info->phy_id = buffer->PhyNum; 475 device_info->port_id = buffer->PhysicalPort; 476 device_info->target = buffer->TargetID; 477 device_info->bus = buffer->Bus; 478 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); 479 device_info->sas_address = le64_to_cpu(sas_address); 480 device_info->device_info = 481 le32_to_cpu(buffer->DeviceInfo); 482 483 out_free_consistent: 484 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 485 buffer, dma_handle); 486 out: 487 return error; 488 } 489 490 static int 491 mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, 492 u32 form, u32 form_specific) 493 { 494 ConfigExtendedPageHeader_t hdr; 495 CONFIGPARMS cfg; 496 SasExpanderPage0_t *buffer; 497 dma_addr_t dma_handle; 498 int error; 499 500 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; 501 hdr.ExtPageLength = 0; 502 hdr.PageNumber = 0; 503 hdr.Reserved1 = 0; 504 hdr.Reserved2 = 0; 505 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 506 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 507 508 cfg.cfghdr.ehdr = &hdr; 509 cfg.physAddr = -1; 510 cfg.pageAddr = form + form_specific; 511 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 512 cfg.dir = 0; /* read */ 513 cfg.timeout = 10; 514 515 error = mpt_config(ioc, &cfg); 516 if (error) 517 goto out; 518 519 if (!hdr.ExtPageLength) { 520 error = -ENXIO; 521 goto out; 522 } 523 524 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 525 &dma_handle); 526 if (!buffer) { 527 error = -ENOMEM; 528 goto out; 529 } 530 531 cfg.physAddr = dma_handle; 532 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 533 534 error = mpt_config(ioc, &cfg); 535 if (error) 536 goto out_free_consistent; 537 538 /* save config data */ 539 port_info->num_phys = buffer->NumPhys; 540 port_info->handle = le16_to_cpu(buffer->DevHandle); 541 port_info->phy_info = kcalloc(port_info->num_phys, 542 sizeof(struct mptsas_phyinfo),GFP_KERNEL); 543 if (!port_info->phy_info) { 544 error = -ENOMEM; 545 goto out_free_consistent; 546 } 547 548 out_free_consistent: 549 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 550 buffer, dma_handle); 551 out: 552 return error; 553 } 554 555 static int 556 mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, 557 u32 form, u32 form_specific) 558 { 559 ConfigExtendedPageHeader_t hdr; 560 CONFIGPARMS cfg; 561 SasExpanderPage1_t *buffer; 562 dma_addr_t dma_handle; 563 int error; 564 565 hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; 566 hdr.ExtPageLength = 0; 567 hdr.PageNumber = 1; 568 hdr.Reserved1 = 0; 569 hdr.Reserved2 = 0; 570 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 571 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER; 572 573 cfg.cfghdr.ehdr = &hdr; 574 cfg.physAddr = -1; 575 cfg.pageAddr = form + form_specific; 576 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 577 cfg.dir = 0; /* read */ 578 cfg.timeout = 10; 579 580 error = mpt_config(ioc, &cfg); 581 if (error) 582 goto out; 583 584 if (!hdr.ExtPageLength) { 585 error = -ENXIO; 586 goto out; 587 } 588 589 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 590 &dma_handle); 591 if (!buffer) { 592 error = -ENOMEM; 593 goto out; 594 } 595 596 cfg.physAddr = dma_handle; 597 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 598 599 error = mpt_config(ioc, &cfg); 600 if (error) 601 goto out_free_consistent; 602 603 604 mptsas_print_expander_pg1(buffer); 605 606 /* save config data */ 607 phy_info->phy_id = buffer->Phy; 608 phy_info->port_id = buffer->PhysicalPort; 609 phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate; 610 phy_info->programmed_link_rate = buffer->ProgrammedLinkRate; 611 phy_info->hw_link_rate = buffer->HwLinkRate; 612 phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); 613 phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); 614 615 616 out_free_consistent: 617 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, 618 buffer, dma_handle); 619 out: 620 return error; 621 } 622 623 static void 624 mptsas_parse_device_info(struct sas_identify *identify, 625 struct mptsas_devinfo *device_info) 626 { 627 u16 protocols; 628 629 identify->sas_address = device_info->sas_address; 630 identify->phy_identifier = device_info->phy_id; 631 632 /* 633 * Fill in Phy Initiator Port Protocol. 634 * Bits 6:3, more than one bit can be set, fall through cases. 635 */ 636 protocols = device_info->device_info & 0x78; 637 identify->initiator_port_protocols = 0; 638 if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR) 639 identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; 640 if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR) 641 identify->initiator_port_protocols |= SAS_PROTOCOL_STP; 642 if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR) 643 identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; 644 if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST) 645 identify->initiator_port_protocols |= SAS_PROTOCOL_SATA; 646 647 /* 648 * Fill in Phy Target Port Protocol. 649 * Bits 10:7, more than one bit can be set, fall through cases. 650 */ 651 protocols = device_info->device_info & 0x780; 652 identify->target_port_protocols = 0; 653 if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET) 654 identify->target_port_protocols |= SAS_PROTOCOL_SSP; 655 if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET) 656 identify->target_port_protocols |= SAS_PROTOCOL_STP; 657 if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET) 658 identify->target_port_protocols |= SAS_PROTOCOL_SMP; 659 if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE) 660 identify->target_port_protocols |= SAS_PROTOCOL_SATA; 661 662 /* 663 * Fill in Attached device type. 664 */ 665 switch (device_info->device_info & 666 MPI_SAS_DEVICE_INFO_MASK_DEVICE_TYPE) { 667 case MPI_SAS_DEVICE_INFO_NO_DEVICE: 668 identify->device_type = SAS_PHY_UNUSED; 669 break; 670 case MPI_SAS_DEVICE_INFO_END_DEVICE: 671 identify->device_type = SAS_END_DEVICE; 672 break; 673 case MPI_SAS_DEVICE_INFO_EDGE_EXPANDER: 674 identify->device_type = SAS_EDGE_EXPANDER_DEVICE; 675 break; 676 case MPI_SAS_DEVICE_INFO_FANOUT_EXPANDER: 677 identify->device_type = SAS_FANOUT_EXPANDER_DEVICE; 678 break; 679 } 680 } 681 682 static int mptsas_probe_one_phy(struct device *dev, 683 struct mptsas_phyinfo *phy_info, int index) 684 { 685 struct sas_phy *port; 686 int error; 687 688 port = sas_phy_alloc(dev, index); 689 if (!port) 690 return -ENOMEM; 691 692 port->port_identifier = phy_info->port_id; 693 mptsas_parse_device_info(&port->identify, &phy_info->identify); 694 695 /* 696 * Set Negotiated link rate. 697 */ 698 switch (phy_info->negotiated_link_rate) { 699 case MPI_SAS_IOUNIT0_RATE_PHY_DISABLED: 700 port->negotiated_linkrate = SAS_PHY_DISABLED; 701 break; 702 case MPI_SAS_IOUNIT0_RATE_FAILED_SPEED_NEGOTIATION: 703 port->negotiated_linkrate = SAS_LINK_RATE_FAILED; 704 break; 705 case MPI_SAS_IOUNIT0_RATE_1_5: 706 port->negotiated_linkrate = SAS_LINK_RATE_1_5_GBPS; 707 break; 708 case MPI_SAS_IOUNIT0_RATE_3_0: 709 port->negotiated_linkrate = SAS_LINK_RATE_3_0_GBPS; 710 break; 711 case MPI_SAS_IOUNIT0_RATE_SATA_OOB_COMPLETE: 712 case MPI_SAS_IOUNIT0_RATE_UNKNOWN: 713 default: 714 port->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN; 715 break; 716 } 717 718 /* 719 * Set Max hardware link rate. 720 */ 721 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) { 722 case MPI_SAS_PHY0_HWRATE_MAX_RATE_1_5: 723 port->maximum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; 724 break; 725 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0: 726 port->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; 727 break; 728 default: 729 break; 730 } 731 732 /* 733 * Set Max programmed link rate. 734 */ 735 switch (phy_info->programmed_link_rate & 736 MPI_SAS_PHY0_PRATE_MAX_RATE_MASK) { 737 case MPI_SAS_PHY0_PRATE_MAX_RATE_1_5: 738 port->maximum_linkrate = SAS_LINK_RATE_1_5_GBPS; 739 break; 740 case MPI_SAS_PHY0_PRATE_MAX_RATE_3_0: 741 port->maximum_linkrate = SAS_LINK_RATE_3_0_GBPS; 742 break; 743 default: 744 break; 745 } 746 747 /* 748 * Set Min hardware link rate. 749 */ 750 switch (phy_info->hw_link_rate & MPI_SAS_PHY0_HWRATE_MIN_RATE_MASK) { 751 case MPI_SAS_PHY0_HWRATE_MIN_RATE_1_5: 752 port->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; 753 break; 754 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0: 755 port->minimum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; 756 break; 757 default: 758 break; 759 } 760 761 /* 762 * Set Min programmed link rate. 763 */ 764 switch (phy_info->programmed_link_rate & 765 MPI_SAS_PHY0_PRATE_MIN_RATE_MASK) { 766 case MPI_SAS_PHY0_PRATE_MIN_RATE_1_5: 767 port->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS; 768 break; 769 case MPI_SAS_PHY0_PRATE_MIN_RATE_3_0: 770 port->minimum_linkrate = SAS_LINK_RATE_3_0_GBPS; 771 break; 772 default: 773 break; 774 } 775 776 error = sas_phy_add(port); 777 if (error) { 778 sas_phy_free(port); 779 return error; 780 } 781 782 if (phy_info->attached.handle) { 783 struct sas_rphy *rphy; 784 785 rphy = sas_rphy_alloc(port); 786 if (!rphy) 787 return 0; /* non-fatal: an rphy can be added later */ 788 789 mptsas_parse_device_info(&rphy->identify, &phy_info->attached); 790 error = sas_rphy_add(rphy); 791 if (error) { 792 sas_rphy_free(rphy); 793 return error; 794 } 795 796 phy_info->rphy = rphy; 797 } 798 799 return 0; 800 } 801 802 static int 803 mptsas_probe_hba_phys(MPT_ADAPTER *ioc, int *index) 804 { 805 struct mptsas_portinfo *port_info; 806 u32 handle = 0xFFFF; 807 int error = -ENOMEM, i; 808 809 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL); 810 if (!port_info) 811 goto out; 812 memset(port_info, 0, sizeof(*port_info)); 813 814 error = mptsas_sas_io_unit_pg0(ioc, port_info); 815 if (error) 816 goto out_free_port_info; 817 818 list_add_tail(&port_info->list, &ioc->sas_topology); 819 820 for (i = 0; i < port_info->num_phys; i++) { 821 mptsas_sas_phy_pg0(ioc, &port_info->phy_info[i], 822 (MPI_SAS_PHY_PGAD_FORM_PHY_NUMBER << 823 MPI_SAS_PHY_PGAD_FORM_SHIFT), i); 824 825 mptsas_sas_device_pg0(ioc, &port_info->phy_info[i].identify, 826 (MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE << 827 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), handle); 828 handle = port_info->phy_info[i].identify.handle; 829 830 if (port_info->phy_info[i].attached.handle) { 831 mptsas_sas_device_pg0(ioc, 832 &port_info->phy_info[i].attached, 833 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 834 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 835 port_info->phy_info[i].attached.handle); 836 } 837 838 mptsas_probe_one_phy(&ioc->sh->shost_gendev, 839 &port_info->phy_info[i], *index); 840 (*index)++; 841 } 842 843 return 0; 844 845 out_free_port_info: 846 kfree(port_info); 847 out: 848 return error; 849 } 850 851 static int 852 mptsas_probe_expander_phys(MPT_ADAPTER *ioc, u32 *handle, int *index) 853 { 854 struct mptsas_portinfo *port_info, *p; 855 int error = -ENOMEM, i, j; 856 857 port_info = kmalloc(sizeof(*port_info), GFP_KERNEL); 858 if (!port_info) 859 goto out; 860 memset(port_info, 0, sizeof(*port_info)); 861 862 error = mptsas_sas_expander_pg0(ioc, port_info, 863 (MPI_SAS_EXPAND_PGAD_FORM_GET_NEXT_HANDLE << 864 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), *handle); 865 if (error) 866 goto out_free_port_info; 867 868 *handle = port_info->handle; 869 870 list_add_tail(&port_info->list, &ioc->sas_topology); 871 for (i = 0; i < port_info->num_phys; i++) { 872 struct device *parent; 873 874 mptsas_sas_expander_pg1(ioc, &port_info->phy_info[i], 875 (MPI_SAS_EXPAND_PGAD_FORM_HANDLE_PHY_NUM << 876 MPI_SAS_EXPAND_PGAD_FORM_SHIFT), (i << 16) + *handle); 877 878 if (port_info->phy_info[i].identify.handle) { 879 mptsas_sas_device_pg0(ioc, 880 &port_info->phy_info[i].identify, 881 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 882 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 883 port_info->phy_info[i].identify.handle); 884 } 885 886 if (port_info->phy_info[i].attached.handle) { 887 mptsas_sas_device_pg0(ioc, 888 &port_info->phy_info[i].attached, 889 (MPI_SAS_DEVICE_PGAD_FORM_HANDLE << 890 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), 891 port_info->phy_info[i].attached.handle); 892 } 893 894 /* 895 * If we find a parent port handle this expander is 896 * attached to another expander, else it hangs of the 897 * HBA phys. 898 */ 899 parent = &ioc->sh->shost_gendev; 900 list_for_each_entry(p, &ioc->sas_topology, list) { 901 for (j = 0; j < p->num_phys; j++) { 902 if (port_info->phy_info[i].identify.handle == 903 p->phy_info[j].attached.handle) 904 parent = &p->phy_info[j].rphy->dev; 905 } 906 } 907 908 mptsas_probe_one_phy(parent, &port_info->phy_info[i], *index); 909 (*index)++; 910 } 911 912 return 0; 913 914 out_free_port_info: 915 kfree(port_info); 916 out: 917 return error; 918 } 919 920 static void 921 mptsas_scan_sas_topology(MPT_ADAPTER *ioc) 922 { 923 u32 handle = 0xFFFF; 924 int index = 0; 925 926 mptsas_probe_hba_phys(ioc, &index); 927 while (!mptsas_probe_expander_phys(ioc, &handle, &index)) 928 ; 929 } 930 931 static int 932 mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) 933 { 934 struct Scsi_Host *sh; 935 MPT_SCSI_HOST *hd; 936 MPT_ADAPTER *ioc; 937 unsigned long flags; 938 int sz, ii; 939 int numSGE = 0; 940 int scale; 941 int ioc_cap; 942 u8 *mem; 943 int error=0; 944 int r; 945 946 r = mpt_attach(pdev,id); 947 if (r) 948 return r; 949 950 ioc = pci_get_drvdata(pdev); 951 ioc->DoneCtx = mptsasDoneCtx; 952 ioc->TaskCtx = mptsasTaskCtx; 953 ioc->InternalCtx = mptsasInternalCtx; 954 955 /* Added sanity check on readiness of the MPT adapter. 956 */ 957 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 958 printk(MYIOC_s_WARN_FMT 959 "Skipping because it's not operational!\n", 960 ioc->name); 961 return -ENODEV; 962 } 963 964 if (!ioc->active) { 965 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n", 966 ioc->name); 967 return -ENODEV; 968 } 969 970 /* Sanity check - ensure at least 1 port is INITIATOR capable 971 */ 972 ioc_cap = 0; 973 for (ii = 0; ii < ioc->facts.NumberOfPorts; ii++) { 974 if (ioc->pfacts[ii].ProtocolFlags & 975 MPI_PORTFACTS_PROTOCOL_INITIATOR) 976 ioc_cap++; 977 } 978 979 if (!ioc_cap) { 980 printk(MYIOC_s_WARN_FMT 981 "Skipping ioc=%p because SCSI Initiator mode " 982 "is NOT enabled!\n", ioc->name, ioc); 983 return 0; 984 } 985 986 sh = scsi_host_alloc(&mptsas_driver_template, sizeof(MPT_SCSI_HOST)); 987 if (!sh) { 988 printk(MYIOC_s_WARN_FMT 989 "Unable to register controller with SCSI subsystem\n", 990 ioc->name); 991 return -1; 992 } 993 994 spin_lock_irqsave(&ioc->FreeQlock, flags); 995 996 /* Attach the SCSI Host to the IOC structure 997 */ 998 ioc->sh = sh; 999 1000 sh->io_port = 0; 1001 sh->n_io_port = 0; 1002 sh->irq = 0; 1003 1004 /* set 16 byte cdb's */ 1005 sh->max_cmd_len = 16; 1006 1007 sh->max_id = ioc->pfacts->MaxDevices + 1; 1008 1009 sh->transportt = mptsas_transport_template; 1010 1011 sh->max_lun = MPT_LAST_LUN + 1; 1012 sh->max_channel = 0; 1013 sh->this_id = ioc->pfacts[0].PortSCSIID; 1014 1015 /* Required entry. 1016 */ 1017 sh->unique_id = ioc->id; 1018 1019 INIT_LIST_HEAD(&ioc->sas_topology); 1020 1021 /* Verify that we won't exceed the maximum 1022 * number of chain buffers 1023 * We can optimize: ZZ = req_sz/sizeof(SGE) 1024 * For 32bit SGE's: 1025 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ 1026 * + (req_sz - 64)/sizeof(SGE) 1027 * A slightly different algorithm is required for 1028 * 64bit SGEs. 1029 */ 1030 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 1031 if (sizeof(dma_addr_t) == sizeof(u64)) { 1032 numSGE = (scale - 1) * 1033 (ioc->facts.MaxChainDepth-1) + scale + 1034 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + 1035 sizeof(u32)); 1036 } else { 1037 numSGE = 1 + (scale - 1) * 1038 (ioc->facts.MaxChainDepth-1) + scale + 1039 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + 1040 sizeof(u32)); 1041 } 1042 1043 if (numSGE < sh->sg_tablesize) { 1044 /* Reset this value */ 1045 dprintk((MYIOC_s_INFO_FMT 1046 "Resetting sg_tablesize to %d from %d\n", 1047 ioc->name, numSGE, sh->sg_tablesize)); 1048 sh->sg_tablesize = numSGE; 1049 } 1050 1051 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 1052 1053 hd = (MPT_SCSI_HOST *) sh->hostdata; 1054 hd->ioc = ioc; 1055 1056 /* SCSI needs scsi_cmnd lookup table! 1057 * (with size equal to req_depth*PtrSz!) 1058 */ 1059 sz = ioc->req_depth * sizeof(void *); 1060 mem = kmalloc(sz, GFP_ATOMIC); 1061 if (mem == NULL) { 1062 error = -ENOMEM; 1063 goto mptsas_probe_failed; 1064 } 1065 1066 memset(mem, 0, sz); 1067 hd->ScsiLookup = (struct scsi_cmnd **) mem; 1068 1069 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n", 1070 ioc->name, hd->ScsiLookup, sz)); 1071 1072 /* Allocate memory for the device structures. 1073 * A non-Null pointer at an offset 1074 * indicates a device exists. 1075 * max_id = 1 + maximum id (hosts.h) 1076 */ 1077 sz = sh->max_id * sizeof(void *); 1078 mem = kmalloc(sz, GFP_ATOMIC); 1079 if (mem == NULL) { 1080 error = -ENOMEM; 1081 goto mptsas_probe_failed; 1082 } 1083 1084 memset(mem, 0, sz); 1085 hd->Targets = (VirtDevice **) mem; 1086 1087 dprintk((KERN_INFO 1088 " Targets @ %p, sz=%d\n", hd->Targets, sz)); 1089 1090 /* Clear the TM flags 1091 */ 1092 hd->tmPending = 0; 1093 hd->tmState = TM_STATE_NONE; 1094 hd->resetPending = 0; 1095 hd->abortSCpnt = NULL; 1096 1097 /* Clear the pointer used to store 1098 * single-threaded commands, i.e., those 1099 * issued during a bus scan, dv and 1100 * configuration pages. 1101 */ 1102 hd->cmdPtr = NULL; 1103 1104 /* Initialize this SCSI Hosts' timers 1105 * To use, set the timer expires field 1106 * and add_timer 1107 */ 1108 init_timer(&hd->timer); 1109 hd->timer.data = (unsigned long) hd; 1110 hd->timer.function = mptscsih_timer_expired; 1111 1112 hd->mpt_pq_filter = mpt_pq_filter; 1113 ioc->sas_data.ptClear = mpt_pt_clear; 1114 1115 if (ioc->sas_data.ptClear==1) { 1116 mptbase_sas_persist_operation( 1117 ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT); 1118 } 1119 1120 ddvprintk((MYIOC_s_INFO_FMT 1121 "mpt_pq_filter %x mpt_pq_filter %x\n", 1122 ioc->name, 1123 mpt_pq_filter, 1124 mpt_pq_filter)); 1125 1126 init_waitqueue_head(&hd->scandv_waitq); 1127 hd->scandv_wait_done = 0; 1128 hd->last_queue_full = 0; 1129 1130 error = scsi_add_host(sh, &ioc->pcidev->dev); 1131 if (error) { 1132 dprintk((KERN_ERR MYNAM 1133 "scsi_add_host failed\n")); 1134 goto mptsas_probe_failed; 1135 } 1136 1137 mptsas_scan_sas_topology(ioc); 1138 1139 return 0; 1140 1141 mptsas_probe_failed: 1142 1143 mptscsih_remove(pdev); 1144 return error; 1145 } 1146 1147 static void __devexit mptsas_remove(struct pci_dev *pdev) 1148 { 1149 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1150 struct mptsas_portinfo *p, *n; 1151 1152 sas_remove_host(ioc->sh); 1153 1154 list_for_each_entry_safe(p, n, &ioc->sas_topology, list) { 1155 list_del(&p->list); 1156 kfree(p); 1157 } 1158 1159 mptscsih_remove(pdev); 1160 } 1161 1162 static struct pci_device_id mptsas_pci_table[] = { 1163 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064, 1164 PCI_ANY_ID, PCI_ANY_ID }, 1165 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066, 1166 PCI_ANY_ID, PCI_ANY_ID }, 1167 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068, 1168 PCI_ANY_ID, PCI_ANY_ID }, 1169 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1064E, 1170 PCI_ANY_ID, PCI_ANY_ID }, 1171 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1066E, 1172 PCI_ANY_ID, PCI_ANY_ID }, 1173 { PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1068E, 1174 PCI_ANY_ID, PCI_ANY_ID }, 1175 {0} /* Terminating entry */ 1176 }; 1177 MODULE_DEVICE_TABLE(pci, mptsas_pci_table); 1178 1179 1180 static struct pci_driver mptsas_driver = { 1181 .name = "mptsas", 1182 .id_table = mptsas_pci_table, 1183 .probe = mptsas_probe, 1184 .remove = __devexit_p(mptsas_remove), 1185 .shutdown = mptscsih_shutdown, 1186 #ifdef CONFIG_PM 1187 .suspend = mptscsih_suspend, 1188 .resume = mptscsih_resume, 1189 #endif 1190 }; 1191 1192 static int __init 1193 mptsas_init(void) 1194 { 1195 show_mptmod_ver(my_NAME, my_VERSION); 1196 1197 mptsas_transport_template = 1198 sas_attach_transport(&mptsas_transport_functions); 1199 if (!mptsas_transport_template) 1200 return -ENODEV; 1201 1202 mptsasDoneCtx = mpt_register(mptscsih_io_done, MPTSAS_DRIVER); 1203 mptsasTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSAS_DRIVER); 1204 mptsasInternalCtx = 1205 mpt_register(mptscsih_scandv_complete, MPTSAS_DRIVER); 1206 1207 if (mpt_event_register(mptsasDoneCtx, mptscsih_event_process) == 0) { 1208 devtprintk((KERN_INFO MYNAM 1209 ": Registered for IOC event notifications\n")); 1210 } 1211 1212 if (mpt_reset_register(mptsasDoneCtx, mptscsih_ioc_reset) == 0) { 1213 dprintk((KERN_INFO MYNAM 1214 ": Registered for IOC reset notifications\n")); 1215 } 1216 1217 return pci_register_driver(&mptsas_driver); 1218 } 1219 1220 static void __exit 1221 mptsas_exit(void) 1222 { 1223 pci_unregister_driver(&mptsas_driver); 1224 sas_release_transport(mptsas_transport_template); 1225 1226 mpt_reset_deregister(mptsasDoneCtx); 1227 mpt_event_deregister(mptsasDoneCtx); 1228 1229 mpt_deregister(mptsasInternalCtx); 1230 mpt_deregister(mptsasTaskCtx); 1231 mpt_deregister(mptsasDoneCtx); 1232 } 1233 1234 module_init(mptsas_init); 1235 module_exit(mptsas_exit); 1236