diff options
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r-- | drivers/message/fusion/Makefile | 2 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.c | 299 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 18 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.c | 241 | ||||
-rw-r--r-- | drivers/message/fusion/mptctl.h | 4 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 203 | ||||
-rw-r--r-- | drivers/message/fusion/mptsas.c | 241 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 118 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.h | 1 | ||||
-rw-r--r-- | drivers/message/fusion/mptspi.c | 10 |
10 files changed, 843 insertions, 294 deletions
diff --git a/drivers/message/fusion/Makefile b/drivers/message/fusion/Makefile index 8a2e2657f4c2..33ace373241c 100644 --- a/drivers/message/fusion/Makefile +++ b/drivers/message/fusion/Makefile | |||
@@ -29,6 +29,8 @@ | |||
29 | # For mptctl: | 29 | # For mptctl: |
30 | #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL | 30 | #CFLAGS_mptctl.o += -DMPT_DEBUG_IOCTL |
31 | # | 31 | # |
32 | # For mptfc: | ||
33 | #CFLAGS_mptfc.o += -DMPT_DEBUG_FC | ||
32 | 34 | ||
33 | #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC | 35 | #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-} LSI_LOGIC |
34 | 36 | ||
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index d890b2b8a93e..642a61b6d0a4 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -81,6 +81,10 @@ MODULE_LICENSE("GPL"); | |||
81 | /* | 81 | /* |
82 | * cmd line parameters | 82 | * cmd line parameters |
83 | */ | 83 | */ |
84 | static int mpt_msi_enable; | ||
85 | module_param(mpt_msi_enable, int, 0); | ||
86 | MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); | ||
87 | |||
84 | #ifdef MFCNT | 88 | #ifdef MFCNT |
85 | static int mfcounter = 0; | 89 | static int mfcounter = 0; |
86 | #define PRINT_MF_COUNT 20000 | 90 | #define PRINT_MF_COUNT 20000 |
@@ -174,7 +178,7 @@ static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); | |||
174 | static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); | 178 | static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); |
175 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); | 179 | static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); |
176 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); | 180 | static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); |
177 | static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info); | 181 | static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); |
178 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); | 182 | static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); |
179 | 183 | ||
180 | /* module entry point */ | 184 | /* module entry point */ |
@@ -313,7 +317,7 @@ mpt_reply(MPT_ADAPTER *ioc, u32 pa) | |||
313 | if (ioc->bus_type == FC) | 317 | if (ioc->bus_type == FC) |
314 | mpt_fc_log_info(ioc, log_info); | 318 | mpt_fc_log_info(ioc, log_info); |
315 | else if (ioc->bus_type == SPI) | 319 | else if (ioc->bus_type == SPI) |
316 | mpt_sp_log_info(ioc, log_info); | 320 | mpt_spi_log_info(ioc, log_info); |
317 | else if (ioc->bus_type == SAS) | 321 | else if (ioc->bus_type == SAS) |
318 | mpt_sas_log_info(ioc, log_info); | 322 | mpt_sas_log_info(ioc, log_info); |
319 | } | 323 | } |
@@ -448,8 +452,7 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) | |||
448 | } else if (func == MPI_FUNCTION_EVENT_ACK) { | 452 | } else if (func == MPI_FUNCTION_EVENT_ACK) { |
449 | dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", | 453 | dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n", |
450 | ioc->name)); | 454 | ioc->name)); |
451 | } else if (func == MPI_FUNCTION_CONFIG || | 455 | } else if (func == MPI_FUNCTION_CONFIG) { |
452 | func == MPI_FUNCTION_TOOLBOX) { | ||
453 | CONFIGPARMS *pCfg; | 456 | CONFIGPARMS *pCfg; |
454 | unsigned long flags; | 457 | unsigned long flags; |
455 | 458 | ||
@@ -1444,6 +1447,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1444 | 1447 | ||
1445 | ioc->pci_irq = -1; | 1448 | ioc->pci_irq = -1; |
1446 | if (pdev->irq) { | 1449 | if (pdev->irq) { |
1450 | if (mpt_msi_enable && !pci_enable_msi(pdev)) | ||
1451 | printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name); | ||
1452 | |||
1447 | r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); | 1453 | r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); |
1448 | 1454 | ||
1449 | if (r < 0) { | 1455 | if (r < 0) { |
@@ -1483,6 +1489,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1483 | 1489 | ||
1484 | list_del(&ioc->list); | 1490 | list_del(&ioc->list); |
1485 | free_irq(ioc->pci_irq, ioc); | 1491 | free_irq(ioc->pci_irq, ioc); |
1492 | if (mpt_msi_enable) | ||
1493 | pci_disable_msi(pdev); | ||
1494 | if (ioc->alt_ioc) | ||
1495 | ioc->alt_ioc->alt_ioc = NULL; | ||
1486 | iounmap(mem); | 1496 | iounmap(mem); |
1487 | kfree(ioc); | 1497 | kfree(ioc); |
1488 | pci_set_drvdata(pdev, NULL); | 1498 | pci_set_drvdata(pdev, NULL); |
@@ -2136,6 +2146,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2136 | 2146 | ||
2137 | if (ioc->pci_irq != -1) { | 2147 | if (ioc->pci_irq != -1) { |
2138 | free_irq(ioc->pci_irq, ioc); | 2148 | free_irq(ioc->pci_irq, ioc); |
2149 | if (mpt_msi_enable) | ||
2150 | pci_disable_msi(ioc->pcidev); | ||
2139 | ioc->pci_irq = -1; | 2151 | ioc->pci_irq = -1; |
2140 | } | 2152 | } |
2141 | 2153 | ||
@@ -2157,6 +2169,10 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2157 | sz_last = ioc->alloc_total; | 2169 | sz_last = ioc->alloc_total; |
2158 | dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", | 2170 | dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", |
2159 | ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); | 2171 | ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); |
2172 | |||
2173 | if (ioc->alt_ioc) | ||
2174 | ioc->alt_ioc->alt_ioc = NULL; | ||
2175 | |||
2160 | kfree(ioc); | 2176 | kfree(ioc); |
2161 | } | 2177 | } |
2162 | 2178 | ||
@@ -2770,13 +2786,16 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
2770 | 2786 | ||
2771 | /* RAID FW may take a long time to enable | 2787 | /* RAID FW may take a long time to enable |
2772 | */ | 2788 | */ |
2773 | if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) | 2789 | if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) |
2774 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) { | 2790 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) || |
2775 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, | 2791 | (ioc->bus_type == SAS)) { |
2776 | reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); | 2792 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
2793 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, | ||
2794 | 300 /*seconds*/, sleepFlag); | ||
2777 | } else { | 2795 | } else { |
2778 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, | 2796 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
2779 | reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag); | 2797 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, |
2798 | 30 /*seconds*/, sleepFlag); | ||
2780 | } | 2799 | } |
2781 | return rc; | 2800 | return rc; |
2782 | } | 2801 | } |
@@ -4387,6 +4406,138 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
4387 | } | 4406 | } |
4388 | 4407 | ||
4389 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 4408 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
4409 | |||
4410 | static void | ||
4411 | mptbase_raid_process_event_data(MPT_ADAPTER *ioc, | ||
4412 | MpiEventDataRaid_t * pRaidEventData) | ||
4413 | { | ||
4414 | int volume; | ||
4415 | int reason; | ||
4416 | int disk; | ||
4417 | int status; | ||
4418 | int flags; | ||
4419 | int state; | ||
4420 | |||
4421 | volume = pRaidEventData->VolumeID; | ||
4422 | reason = pRaidEventData->ReasonCode; | ||
4423 | disk = pRaidEventData->PhysDiskNum; | ||
4424 | status = le32_to_cpu(pRaidEventData->SettingsStatus); | ||
4425 | flags = (status >> 0) & 0xff; | ||
4426 | state = (status >> 8) & 0xff; | ||
4427 | |||
4428 | if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { | ||
4429 | return; | ||
4430 | } | ||
4431 | |||
4432 | if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && | ||
4433 | reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || | ||
4434 | (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { | ||
4435 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", | ||
4436 | ioc->name, disk); | ||
4437 | } else { | ||
4438 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", | ||
4439 | ioc->name, volume); | ||
4440 | } | ||
4441 | |||
4442 | switch(reason) { | ||
4443 | case MPI_EVENT_RAID_RC_VOLUME_CREATED: | ||
4444 | printk(MYIOC_s_INFO_FMT " volume has been created\n", | ||
4445 | ioc->name); | ||
4446 | break; | ||
4447 | |||
4448 | case MPI_EVENT_RAID_RC_VOLUME_DELETED: | ||
4449 | |||
4450 | printk(MYIOC_s_INFO_FMT " volume has been deleted\n", | ||
4451 | ioc->name); | ||
4452 | break; | ||
4453 | |||
4454 | case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: | ||
4455 | printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", | ||
4456 | ioc->name); | ||
4457 | break; | ||
4458 | |||
4459 | case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: | ||
4460 | printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", | ||
4461 | ioc->name, | ||
4462 | state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL | ||
4463 | ? "optimal" | ||
4464 | : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED | ||
4465 | ? "degraded" | ||
4466 | : state == MPI_RAIDVOL0_STATUS_STATE_FAILED | ||
4467 | ? "failed" | ||
4468 | : "state unknown", | ||
4469 | flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED | ||
4470 | ? ", enabled" : "", | ||
4471 | flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED | ||
4472 | ? ", quiesced" : "", | ||
4473 | flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS | ||
4474 | ? ", resync in progress" : "" ); | ||
4475 | break; | ||
4476 | |||
4477 | case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: | ||
4478 | printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", | ||
4479 | ioc->name, disk); | ||
4480 | break; | ||
4481 | |||
4482 | case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: | ||
4483 | printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", | ||
4484 | ioc->name); | ||
4485 | break; | ||
4486 | |||
4487 | case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: | ||
4488 | printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", | ||
4489 | ioc->name); | ||
4490 | break; | ||
4491 | |||
4492 | case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: | ||
4493 | printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", | ||
4494 | ioc->name); | ||
4495 | break; | ||
4496 | |||
4497 | case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: | ||
4498 | printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", | ||
4499 | ioc->name, | ||
4500 | state == MPI_PHYSDISK0_STATUS_ONLINE | ||
4501 | ? "online" | ||
4502 | : state == MPI_PHYSDISK0_STATUS_MISSING | ||
4503 | ? "missing" | ||
4504 | : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE | ||
4505 | ? "not compatible" | ||
4506 | : state == MPI_PHYSDISK0_STATUS_FAILED | ||
4507 | ? "failed" | ||
4508 | : state == MPI_PHYSDISK0_STATUS_INITIALIZING | ||
4509 | ? "initializing" | ||
4510 | : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED | ||
4511 | ? "offline requested" | ||
4512 | : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED | ||
4513 | ? "failed requested" | ||
4514 | : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE | ||
4515 | ? "offline" | ||
4516 | : "state unknown", | ||
4517 | flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC | ||
4518 | ? ", out of sync" : "", | ||
4519 | flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED | ||
4520 | ? ", quiesced" : "" ); | ||
4521 | break; | ||
4522 | |||
4523 | case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: | ||
4524 | printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", | ||
4525 | ioc->name, disk); | ||
4526 | break; | ||
4527 | |||
4528 | case MPI_EVENT_RAID_RC_SMART_DATA: | ||
4529 | printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", | ||
4530 | ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); | ||
4531 | break; | ||
4532 | |||
4533 | case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: | ||
4534 | printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", | ||
4535 | ioc->name, disk); | ||
4536 | break; | ||
4537 | } | ||
4538 | } | ||
4539 | |||
4540 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
4390 | /* | 4541 | /* |
4391 | * GetIoUnitPage2 - Retrieve BIOS version and boot order information. | 4542 | * GetIoUnitPage2 - Retrieve BIOS version and boot order information. |
4392 | * @ioc: Pointer to MPT_ADAPTER structure | 4543 | * @ioc: Pointer to MPT_ADAPTER structure |
@@ -4598,6 +4749,14 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) | |||
4598 | SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; | 4749 | SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; |
4599 | MpiDeviceInfo_t *pdevice = NULL; | 4750 | MpiDeviceInfo_t *pdevice = NULL; |
4600 | 4751 | ||
4752 | /* | ||
4753 | * Save "Set to Avoid SCSI Bus Resets" flag | ||
4754 | */ | ||
4755 | ioc->spi_data.bus_reset = | ||
4756 | (le32_to_cpu(pPP2->PortFlags) & | ||
4757 | MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? | ||
4758 | 0 : 1 ; | ||
4759 | |||
4601 | /* Save the Port Page 2 data | 4760 | /* Save the Port Page 2 data |
4602 | * (reformat into a 32bit quantity) | 4761 | * (reformat into a 32bit quantity) |
4603 | */ | 4762 | */ |
@@ -5167,115 +5326,6 @@ mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) | |||
5167 | } | 5326 | } |
5168 | 5327 | ||
5169 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 5328 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
5170 | /** | ||
5171 | * mpt_toolbox - Generic function to issue toolbox message | ||
5172 | * @ioc - Pointer to an adapter structure | ||
5173 | * @cfg - Pointer to a toolbox structure. Struct contains | ||
5174 | * action, page address, direction, physical address | ||
5175 | * and pointer to a configuration page header | ||
5176 | * Page header is updated. | ||
5177 | * | ||
5178 | * Returns 0 for success | ||
5179 | * -EPERM if not allowed due to ISR context | ||
5180 | * -EAGAIN if no msg frames currently available | ||
5181 | * -EFAULT for non-successful reply or no reply (timeout) | ||
5182 | */ | ||
5183 | int | ||
5184 | mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) | ||
5185 | { | ||
5186 | ToolboxIstwiReadWriteRequest_t *pReq; | ||
5187 | MPT_FRAME_HDR *mf; | ||
5188 | struct pci_dev *pdev; | ||
5189 | unsigned long flags; | ||
5190 | int rc; | ||
5191 | u32 flagsLength; | ||
5192 | int in_isr; | ||
5193 | |||
5194 | /* Prevent calling wait_event() (below), if caller happens | ||
5195 | * to be in ISR context, because that is fatal! | ||
5196 | */ | ||
5197 | in_isr = in_interrupt(); | ||
5198 | if (in_isr) { | ||
5199 | dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n", | ||
5200 | ioc->name)); | ||
5201 | return -EPERM; | ||
5202 | } | ||
5203 | |||
5204 | /* Get and Populate a free Frame | ||
5205 | */ | ||
5206 | if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { | ||
5207 | dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n", | ||
5208 | ioc->name)); | ||
5209 | return -EAGAIN; | ||
5210 | } | ||
5211 | pReq = (ToolboxIstwiReadWriteRequest_t *)mf; | ||
5212 | pReq->Tool = pCfg->action; | ||
5213 | pReq->Reserved = 0; | ||
5214 | pReq->ChainOffset = 0; | ||
5215 | pReq->Function = MPI_FUNCTION_TOOLBOX; | ||
5216 | pReq->Reserved1 = 0; | ||
5217 | pReq->Reserved2 = 0; | ||
5218 | pReq->MsgFlags = 0; | ||
5219 | pReq->Flags = pCfg->dir; | ||
5220 | pReq->BusNum = 0; | ||
5221 | pReq->Reserved3 = 0; | ||
5222 | pReq->NumAddressBytes = 0x01; | ||
5223 | pReq->Reserved4 = 0; | ||
5224 | pReq->DataLength = cpu_to_le16(0x04); | ||
5225 | pdev = ioc->pcidev; | ||
5226 | if (pdev->devfn & 1) | ||
5227 | pReq->DeviceAddr = 0xB2; | ||
5228 | else | ||
5229 | pReq->DeviceAddr = 0xB0; | ||
5230 | pReq->Addr1 = 0; | ||
5231 | pReq->Addr2 = 0; | ||
5232 | pReq->Addr3 = 0; | ||
5233 | pReq->Reserved5 = 0; | ||
5234 | |||
5235 | /* Add a SGE to the config request. | ||
5236 | */ | ||
5237 | |||
5238 | flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4; | ||
5239 | |||
5240 | mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr); | ||
5241 | |||
5242 | dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n", | ||
5243 | ioc->name, pReq->Tool)); | ||
5244 | |||
5245 | /* Append pCfg pointer to end of mf | ||
5246 | */ | ||
5247 | *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg; | ||
5248 | |||
5249 | /* Initalize the timer | ||
5250 | */ | ||
5251 | init_timer(&pCfg->timer); | ||
5252 | pCfg->timer.data = (unsigned long) ioc; | ||
5253 | pCfg->timer.function = mpt_timer_expired; | ||
5254 | pCfg->wait_done = 0; | ||
5255 | |||
5256 | /* Set the timer; ensure 10 second minimum */ | ||
5257 | if (pCfg->timeout < 10) | ||
5258 | pCfg->timer.expires = jiffies + HZ*10; | ||
5259 | else | ||
5260 | pCfg->timer.expires = jiffies + HZ*pCfg->timeout; | ||
5261 | |||
5262 | /* Add to end of Q, set timer and then issue this command */ | ||
5263 | spin_lock_irqsave(&ioc->FreeQlock, flags); | ||
5264 | list_add_tail(&pCfg->linkage, &ioc->configQ); | ||
5265 | spin_unlock_irqrestore(&ioc->FreeQlock, flags); | ||
5266 | |||
5267 | add_timer(&pCfg->timer); | ||
5268 | mpt_put_msg_frame(mpt_base_index, ioc, mf); | ||
5269 | wait_event(mpt_waitq, pCfg->wait_done); | ||
5270 | |||
5271 | /* mf has been freed - do not access */ | ||
5272 | |||
5273 | rc = pCfg->status; | ||
5274 | |||
5275 | return rc; | ||
5276 | } | ||
5277 | |||
5278 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
5279 | /* | 5329 | /* |
5280 | * mpt_timer_expired - Call back for timer process. | 5330 | * mpt_timer_expired - Call back for timer process. |
5281 | * Used only internal config functionality. | 5331 | * Used only internal config functionality. |
@@ -5967,6 +6017,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply | |||
5967 | } | 6017 | } |
5968 | } | 6018 | } |
5969 | break; | 6019 | break; |
6020 | case MPI_EVENT_INTEGRATED_RAID: | ||
6021 | mptbase_raid_process_event_data(ioc, | ||
6022 | (MpiEventDataRaid_t *)pEventReply->Data); | ||
6023 | break; | ||
5970 | default: | 6024 | default: |
5971 | break; | 6025 | break; |
5972 | } | 6026 | } |
@@ -5978,7 +6032,7 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply | |||
5978 | if (ioc->events && (ioc->eventTypes & ( 1 << event))) { | 6032 | if (ioc->events && (ioc->eventTypes & ( 1 << event))) { |
5979 | int idx; | 6033 | int idx; |
5980 | 6034 | ||
5981 | idx = ioc->eventContext % ioc->eventLogSize; | 6035 | idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; |
5982 | 6036 | ||
5983 | ioc->events[idx].event = event; | 6037 | ioc->events[idx].event = event; |
5984 | ioc->events[idx].eventContext = ioc->eventContext; | 6038 | ioc->events[idx].eventContext = ioc->eventContext; |
@@ -6046,7 +6100,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6046 | 6100 | ||
6047 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6101 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
6048 | /* | 6102 | /* |
6049 | * mpt_sp_log_info - Log information returned from SCSI Parallel IOC. | 6103 | * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. |
6050 | * @ioc: Pointer to MPT_ADAPTER structure | 6104 | * @ioc: Pointer to MPT_ADAPTER structure |
6051 | * @mr: Pointer to MPT reply frame | 6105 | * @mr: Pointer to MPT reply frame |
6052 | * @log_info: U32 LogInfo word from the IOC | 6106 | * @log_info: U32 LogInfo word from the IOC |
@@ -6054,7 +6108,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
6054 | * Refer to lsi/sp_log.h. | 6108 | * Refer to lsi/sp_log.h. |
6055 | */ | 6109 | */ |
6056 | static void | 6110 | static void |
6057 | mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) | 6111 | mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) |
6058 | { | 6112 | { |
6059 | u32 info = log_info & 0x00FF0000; | 6113 | u32 info = log_info & 0x00FF0000; |
6060 | char *desc = "unknown"; | 6114 | char *desc = "unknown"; |
@@ -6376,7 +6430,6 @@ EXPORT_SYMBOL(mpt_lan_index); | |||
6376 | EXPORT_SYMBOL(mpt_stm_index); | 6430 | EXPORT_SYMBOL(mpt_stm_index); |
6377 | EXPORT_SYMBOL(mpt_HardResetHandler); | 6431 | EXPORT_SYMBOL(mpt_HardResetHandler); |
6378 | EXPORT_SYMBOL(mpt_config); | 6432 | EXPORT_SYMBOL(mpt_config); |
6379 | EXPORT_SYMBOL(mpt_toolbox); | ||
6380 | EXPORT_SYMBOL(mpt_findImVolumes); | 6433 | EXPORT_SYMBOL(mpt_findImVolumes); |
6381 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); | 6434 | EXPORT_SYMBOL(mpt_read_ioc_pg_3); |
6382 | EXPORT_SYMBOL(mpt_alloc_fw_memory); | 6435 | EXPORT_SYMBOL(mpt_alloc_fw_memory); |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 47053ac65068..723d54300953 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -76,8 +76,8 @@ | |||
76 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR | 76 | #define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR |
77 | #endif | 77 | #endif |
78 | 78 | ||
79 | #define MPT_LINUX_VERSION_COMMON "3.03.06" | 79 | #define MPT_LINUX_VERSION_COMMON "3.03.07" |
80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.06" | 80 | #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.07" |
81 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" | 81 | #define WHAT_MAGIC_STRING "@" "(" "#" ")" |
82 | 82 | ||
83 | #define show_mptmod_ver(s,ver) \ | 83 | #define show_mptmod_ver(s,ver) \ |
@@ -123,7 +123,7 @@ | |||
123 | #define MPT_MAX_FRAME_SIZE 128 | 123 | #define MPT_MAX_FRAME_SIZE 128 |
124 | #define MPT_DEFAULT_FRAME_SIZE 128 | 124 | #define MPT_DEFAULT_FRAME_SIZE 128 |
125 | 125 | ||
126 | #define MPT_REPLY_FRAME_SIZE 0x40 /* Must be a multiple of 8 */ | 126 | #define MPT_REPLY_FRAME_SIZE 0x50 /* Must be a multiple of 8 */ |
127 | 127 | ||
128 | #define MPT_SG_REQ_128_SCALE 1 | 128 | #define MPT_SG_REQ_128_SCALE 1 |
129 | #define MPT_SG_REQ_96_SCALE 2 | 129 | #define MPT_SG_REQ_96_SCALE 2 |
@@ -510,9 +510,10 @@ struct mptfc_rport_info | |||
510 | { | 510 | { |
511 | struct list_head list; | 511 | struct list_head list; |
512 | struct fc_rport *rport; | 512 | struct fc_rport *rport; |
513 | VirtDevice *vdev; | 513 | struct scsi_target *starget; |
514 | FCDevicePage0_t pg0; | 514 | FCDevicePage0_t pg0; |
515 | u8 flags; | 515 | u8 flags; |
516 | u8 remap_needed; | ||
516 | }; | 517 | }; |
517 | 518 | ||
518 | /* | 519 | /* |
@@ -615,6 +616,7 @@ typedef struct _MPT_ADAPTER | |||
615 | * increments by 32 bytes | 616 | * increments by 32 bytes |
616 | */ | 617 | */ |
617 | int errata_flag_1064; | 618 | int errata_flag_1064; |
619 | int aen_event_read_flag; /* flag to indicate event log was read*/ | ||
618 | u8 FirstWhoInit; | 620 | u8 FirstWhoInit; |
619 | u8 upload_fw; /* If set, do a fw upload */ | 621 | u8 upload_fw; /* If set, do a fw upload */ |
620 | u8 reload_fw; /* Force a FW Reload on next reset */ | 622 | u8 reload_fw; /* Force a FW Reload on next reset */ |
@@ -631,6 +633,7 @@ typedef struct _MPT_ADAPTER | |||
631 | struct mutex sas_topology_mutex; | 633 | struct mutex sas_topology_mutex; |
632 | MPT_SAS_MGMT sas_mgmt; | 634 | MPT_SAS_MGMT sas_mgmt; |
633 | int num_ports; | 635 | int num_ports; |
636 | struct work_struct mptscsih_persistTask; | ||
634 | 637 | ||
635 | struct list_head fc_rports; | 638 | struct list_head fc_rports; |
636 | spinlock_t fc_rport_lock; /* list and ri flags */ | 639 | spinlock_t fc_rport_lock; /* list and ri flags */ |
@@ -803,6 +806,12 @@ typedef struct _mpt_sge { | |||
803 | #define dreplyprintk(x) | 806 | #define dreplyprintk(x) |
804 | #endif | 807 | #endif |
805 | 808 | ||
809 | #ifdef DMPT_DEBUG_FC | ||
810 | #define dfcprintk(x) printk x | ||
811 | #else | ||
812 | #define dfcprintk(x) | ||
813 | #endif | ||
814 | |||
806 | #ifdef MPT_DEBUG_TM | 815 | #ifdef MPT_DEBUG_TM |
807 | #define dtmprintk(x) printk x | 816 | #define dtmprintk(x) printk x |
808 | #define DBG_DUMP_TM_REQUEST_FRAME(mfp) \ | 817 | #define DBG_DUMP_TM_REQUEST_FRAME(mfp) \ |
@@ -1018,7 +1027,6 @@ extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); | |||
1018 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); | 1027 | extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); |
1019 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); | 1028 | extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); |
1020 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | 1029 | extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); |
1021 | extern int mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); | ||
1022 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); | 1030 | extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); |
1023 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); | 1031 | extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); |
1024 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); | 1032 | extern int mpt_findImVolumes(MPT_ADAPTER *ioc); |
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c index bdf709987982..9b64e07400da 100644 --- a/drivers/message/fusion/mptctl.c +++ b/drivers/message/fusion/mptctl.c | |||
@@ -136,6 +136,12 @@ static void mptctl_free_tm_flags(MPT_ADAPTER *ioc); | |||
136 | */ | 136 | */ |
137 | static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); | 137 | static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); |
138 | 138 | ||
139 | /* | ||
140 | * Event Handler function | ||
141 | */ | ||
142 | static int mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); | ||
143 | struct fasync_struct *async_queue=NULL; | ||
144 | |||
139 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 145 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
140 | /* | 146 | /* |
141 | * Scatter gather list (SGL) sizes and limits... | 147 | * Scatter gather list (SGL) sizes and limits... |
@@ -385,18 +391,18 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) | |||
385 | } | 391 | } |
386 | 392 | ||
387 | /* Now wait for the command to complete */ | 393 | /* Now wait for the command to complete */ |
388 | ii = wait_event_interruptible_timeout(mptctl_wait, | 394 | ii = wait_event_timeout(mptctl_wait, |
389 | ioctl->wait_done == 1, | 395 | ioctl->wait_done == 1, |
390 | HZ*5 /* 5 second timeout */); | 396 | HZ*5 /* 5 second timeout */); |
391 | 397 | ||
392 | if(ii <=0 && (ioctl->wait_done != 1 )) { | 398 | if(ii <=0 && (ioctl->wait_done != 1 )) { |
399 | mpt_free_msg_frame(hd->ioc, mf); | ||
393 | ioctl->wait_done = 0; | 400 | ioctl->wait_done = 0; |
394 | retval = -1; /* return failure */ | 401 | retval = -1; /* return failure */ |
395 | } | 402 | } |
396 | 403 | ||
397 | mptctl_bus_reset_done: | 404 | mptctl_bus_reset_done: |
398 | 405 | ||
399 | mpt_free_msg_frame(hd->ioc, mf); | ||
400 | mptctl_free_tm_flags(ioctl->ioc); | 406 | mptctl_free_tm_flags(ioctl->ioc); |
401 | return retval; | 407 | return retval; |
402 | } | 408 | } |
@@ -472,6 +478,69 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
472 | } | 478 | } |
473 | 479 | ||
474 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 480 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
481 | /* ASYNC Event Notification Support */ | ||
482 | static int | ||
483 | mptctl_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | ||
484 | { | ||
485 | u8 event; | ||
486 | |||
487 | event = le32_to_cpu(pEvReply->Event) & 0xFF; | ||
488 | |||
489 | dctlprintk(("%s() called\n", __FUNCTION__)); | ||
490 | if(async_queue == NULL) | ||
491 | return 1; | ||
492 | |||
493 | /* Raise SIGIO for persistent events. | ||
494 | * TODO - this define is not in MPI spec yet, | ||
495 | * but they plan to set it to 0x21 | ||
496 | */ | ||
497 | if (event == 0x21 ) { | ||
498 | ioc->aen_event_read_flag=1; | ||
499 | dctlprintk(("Raised SIGIO to application\n")); | ||
500 | devtprintk(("Raised SIGIO to application\n")); | ||
501 | kill_fasync(&async_queue, SIGIO, POLL_IN); | ||
502 | return 1; | ||
503 | } | ||
504 | |||
505 | /* This flag is set after SIGIO was raised, and | ||
506 | * remains set until the application has read | ||
507 | * the event log via ioctl=MPTEVENTREPORT | ||
508 | */ | ||
509 | if(ioc->aen_event_read_flag) | ||
510 | return 1; | ||
511 | |||
512 | /* Signal only for the events that are | ||
513 | * requested for by the application | ||
514 | */ | ||
515 | if (ioc->events && (ioc->eventTypes & ( 1 << event))) { | ||
516 | ioc->aen_event_read_flag=1; | ||
517 | dctlprintk(("Raised SIGIO to application\n")); | ||
518 | devtprintk(("Raised SIGIO to application\n")); | ||
519 | kill_fasync(&async_queue, SIGIO, POLL_IN); | ||
520 | } | ||
521 | return 1; | ||
522 | } | ||
523 | |||
524 | static int | ||
525 | mptctl_fasync(int fd, struct file *filep, int mode) | ||
526 | { | ||
527 | MPT_ADAPTER *ioc; | ||
528 | |||
529 | list_for_each_entry(ioc, &ioc_list, list) | ||
530 | ioc->aen_event_read_flag=0; | ||
531 | |||
532 | dctlprintk(("%s() called\n", __FUNCTION__)); | ||
533 | return fasync_helper(fd, filep, mode, &async_queue); | ||
534 | } | ||
535 | |||
536 | static int | ||
537 | mptctl_release(struct inode *inode, struct file *filep) | ||
538 | { | ||
539 | dctlprintk(("%s() called\n", __FUNCTION__)); | ||
540 | return fasync_helper(-1, filep, 0, &async_queue); | ||
541 | } | ||
542 | |||
543 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
475 | /* | 544 | /* |
476 | * MPT ioctl handler | 545 | * MPT ioctl handler |
477 | * cmd - specify the particular IOCTL command to be issued | 546 | * cmd - specify the particular IOCTL command to be issued |
@@ -674,22 +743,23 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
674 | u16 iocstat; | 743 | u16 iocstat; |
675 | pFWDownloadReply_t ReplyMsg = NULL; | 744 | pFWDownloadReply_t ReplyMsg = NULL; |
676 | 745 | ||
677 | dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); | 746 | dctlprintk(("mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); |
678 | 747 | ||
679 | dctlprintk((KERN_INFO "DbG: kfwdl.bufp = %p\n", ufwbuf)); | 748 | dctlprintk(("DbG: kfwdl.bufp = %p\n", ufwbuf)); |
680 | dctlprintk((KERN_INFO "DbG: kfwdl.fwlen = %d\n", (int)fwlen)); | 749 | dctlprintk(("DbG: kfwdl.fwlen = %d\n", (int)fwlen)); |
681 | dctlprintk((KERN_INFO "DbG: kfwdl.ioc = %04xh\n", ioc)); | 750 | dctlprintk(("DbG: kfwdl.ioc = %04xh\n", ioc)); |
682 | 751 | ||
683 | if ((ioc = mpt_verify_adapter(ioc, &iocp)) < 0) { | 752 | if (mpt_verify_adapter(ioc, &iocp) < 0) { |
684 | dctlprintk(("%s@%d::_ioctl_fwdl - ioc%d not found!\n", | 753 | dctlprintk(("ioctl_fwdl - ioc%d not found!\n", |
685 | __FILE__, __LINE__, ioc)); | 754 | ioc)); |
686 | return -ENODEV; /* (-6) No such device or address */ | 755 | return -ENODEV; /* (-6) No such device or address */ |
687 | } | 756 | } else { |
688 | 757 | ||
689 | /* Valid device. Get a message frame and construct the FW download message. | 758 | /* Valid device. Get a message frame and construct the FW download message. |
690 | */ | 759 | */ |
691 | if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) | 760 | if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL) |
692 | return -EAGAIN; | 761 | return -EAGAIN; |
762 | } | ||
693 | dlmsg = (FWDownload_t*) mf; | 763 | dlmsg = (FWDownload_t*) mf; |
694 | ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; | 764 | ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL; |
695 | sgOut = (char *) (ptsge + 1); | 765 | sgOut = (char *) (ptsge + 1); |
@@ -702,7 +772,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
702 | dlmsg->ChainOffset = 0; | 772 | dlmsg->ChainOffset = 0; |
703 | dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; | 773 | dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD; |
704 | dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; | 774 | dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0; |
705 | dlmsg->MsgFlags = 0; | 775 | if (iocp->facts.MsgVersion >= MPI_VERSION_01_05) |
776 | dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT; | ||
777 | else | ||
778 | dlmsg->MsgFlags = 0; | ||
779 | |||
706 | 780 | ||
707 | /* Set up the Transaction SGE. | 781 | /* Set up the Transaction SGE. |
708 | */ | 782 | */ |
@@ -754,7 +828,7 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
754 | goto fwdl_out; | 828 | goto fwdl_out; |
755 | } | 829 | } |
756 | 830 | ||
757 | dctlprintk((KERN_INFO "DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); | 831 | dctlprintk(("DbG: sgl buffer = %p, sgfrags = %d\n", sgl, numfrags)); |
758 | 832 | ||
759 | /* | 833 | /* |
760 | * Parse SG list, copying sgl itself, | 834 | * Parse SG list, copying sgl itself, |
@@ -803,11 +877,11 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) | |||
803 | /* | 877 | /* |
804 | * Finally, perform firmware download. | 878 | * Finally, perform firmware download. |
805 | */ | 879 | */ |
806 | iocp->ioctl->wait_done = 0; | 880 | ReplyMsg = NULL; |
807 | mpt_put_msg_frame(mptctl_id, iocp, mf); | 881 | mpt_put_msg_frame(mptctl_id, iocp, mf); |
808 | 882 | ||
809 | /* Now wait for the command to complete */ | 883 | /* Now wait for the command to complete */ |
810 | ret = wait_event_interruptible_timeout(mptctl_wait, | 884 | ret = wait_event_timeout(mptctl_wait, |
811 | iocp->ioctl->wait_done == 1, | 885 | iocp->ioctl->wait_done == 1, |
812 | HZ*60); | 886 | HZ*60); |
813 | 887 | ||
@@ -1145,7 +1219,9 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1145 | /* Fill in the data and return the structure to the calling | 1219 | /* Fill in the data and return the structure to the calling |
1146 | * program | 1220 | * program |
1147 | */ | 1221 | */ |
1148 | if (ioc->bus_type == FC) | 1222 | if (ioc->bus_type == SAS) |
1223 | karg->adapterType = MPT_IOCTL_INTERFACE_SAS; | ||
1224 | else if (ioc->bus_type == FC) | ||
1149 | karg->adapterType = MPT_IOCTL_INTERFACE_FC; | 1225 | karg->adapterType = MPT_IOCTL_INTERFACE_FC; |
1150 | else | 1226 | else |
1151 | karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; | 1227 | karg->adapterType = MPT_IOCTL_INTERFACE_SCSI; |
@@ -1170,12 +1246,11 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) | |||
1170 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); | 1246 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); |
1171 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); | 1247 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); |
1172 | } else if (cim_rev == 2) { | 1248 | } else if (cim_rev == 2) { |
1173 | /* Get the PCI bus, device, function and segment ID numbers | 1249 | /* Get the PCI bus, device, function and segment ID numbers |
1174 | for the IOC */ | 1250 | for the IOC */ |
1175 | karg->pciInfo.u.bits.busNumber = pdev->bus->number; | 1251 | karg->pciInfo.u.bits.busNumber = pdev->bus->number; |
1176 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); | 1252 | karg->pciInfo.u.bits.deviceNumber = PCI_SLOT( pdev->devfn ); |
1177 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); | 1253 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); |
1178 | karg->pciInfo.u.bits.functionNumber = PCI_FUNC( pdev->devfn ); | ||
1179 | karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); | 1254 | karg->pciInfo.segmentID = pci_domain_nr(pdev->bus); |
1180 | } | 1255 | } |
1181 | 1256 | ||
@@ -1500,7 +1575,7 @@ mptctl_eventquery (unsigned long arg) | |||
1500 | return -ENODEV; | 1575 | return -ENODEV; |
1501 | } | 1576 | } |
1502 | 1577 | ||
1503 | karg.eventEntries = ioc->eventLogSize; | 1578 | karg.eventEntries = MPTCTL_EVENT_LOG_SIZE; |
1504 | karg.eventTypes = ioc->eventTypes; | 1579 | karg.eventTypes = ioc->eventTypes; |
1505 | 1580 | ||
1506 | /* Copy the data from kernel memory to user memory | 1581 | /* Copy the data from kernel memory to user memory |
@@ -1550,7 +1625,6 @@ mptctl_eventenable (unsigned long arg) | |||
1550 | memset(ioc->events, 0, sz); | 1625 | memset(ioc->events, 0, sz); |
1551 | ioc->alloc_total += sz; | 1626 | ioc->alloc_total += sz; |
1552 | 1627 | ||
1553 | ioc->eventLogSize = MPTCTL_EVENT_LOG_SIZE; | ||
1554 | ioc->eventContext = 0; | 1628 | ioc->eventContext = 0; |
1555 | } | 1629 | } |
1556 | 1630 | ||
@@ -1590,7 +1664,7 @@ mptctl_eventreport (unsigned long arg) | |||
1590 | maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); | 1664 | maxEvents = numBytes/sizeof(MPT_IOCTL_EVENTS); |
1591 | 1665 | ||
1592 | 1666 | ||
1593 | max = ioc->eventLogSize < maxEvents ? ioc->eventLogSize : maxEvents; | 1667 | max = MPTCTL_EVENT_LOG_SIZE < maxEvents ? MPTCTL_EVENT_LOG_SIZE : maxEvents; |
1594 | 1668 | ||
1595 | /* If fewer than 1 event is requested, there must have | 1669 | /* If fewer than 1 event is requested, there must have |
1596 | * been some type of error. | 1670 | * been some type of error. |
@@ -1598,6 +1672,9 @@ mptctl_eventreport (unsigned long arg) | |||
1598 | if ((max < 1) || !ioc->events) | 1672 | if ((max < 1) || !ioc->events) |
1599 | return -ENODATA; | 1673 | return -ENODATA; |
1600 | 1674 | ||
1675 | /* reset this flag so SIGIO can restart */ | ||
1676 | ioc->aen_event_read_flag=0; | ||
1677 | |||
1601 | /* Copy the data from kernel memory to user memory | 1678 | /* Copy the data from kernel memory to user memory |
1602 | */ | 1679 | */ |
1603 | numBytes = max * sizeof(MPT_IOCTL_EVENTS); | 1680 | numBytes = max * sizeof(MPT_IOCTL_EVENTS); |
@@ -1817,6 +1894,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1817 | case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: | 1894 | case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR: |
1818 | case MPI_FUNCTION_FW_DOWNLOAD: | 1895 | case MPI_FUNCTION_FW_DOWNLOAD: |
1819 | case MPI_FUNCTION_FC_PRIMITIVE_SEND: | 1896 | case MPI_FUNCTION_FC_PRIMITIVE_SEND: |
1897 | case MPI_FUNCTION_TOOLBOX: | ||
1898 | case MPI_FUNCTION_SAS_IO_UNIT_CONTROL: | ||
1820 | break; | 1899 | break; |
1821 | 1900 | ||
1822 | case MPI_FUNCTION_SCSI_IO_REQUEST: | 1901 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
@@ -1837,7 +1916,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1837 | goto done_free_mem; | 1916 | goto done_free_mem; |
1838 | } | 1917 | } |
1839 | 1918 | ||
1840 | pScsiReq->MsgFlags = mpt_msg_flags(); | 1919 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; |
1920 | pScsiReq->MsgFlags |= mpt_msg_flags(); | ||
1921 | |||
1841 | 1922 | ||
1842 | /* verify that app has not requested | 1923 | /* verify that app has not requested |
1843 | * more sense data than driver | 1924 | * more sense data than driver |
@@ -1888,6 +1969,25 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1888 | } | 1969 | } |
1889 | break; | 1970 | break; |
1890 | 1971 | ||
1972 | case MPI_FUNCTION_SMP_PASSTHROUGH: | ||
1973 | /* Check mf->PassthruFlags to determine if | ||
1974 | * transfer is ImmediateMode or not. | ||
1975 | * Immediate mode returns data in the ReplyFrame. | ||
1976 | * Else, we are sending request and response data | ||
1977 | * in two SGLs at the end of the mf. | ||
1978 | */ | ||
1979 | break; | ||
1980 | |||
1981 | case MPI_FUNCTION_SATA_PASSTHROUGH: | ||
1982 | if (!ioc->sh) { | ||
1983 | printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " | ||
1984 | "SCSI driver is not loaded. \n", | ||
1985 | __FILE__, __LINE__); | ||
1986 | rc = -EFAULT; | ||
1987 | goto done_free_mem; | ||
1988 | } | ||
1989 | break; | ||
1990 | |||
1891 | case MPI_FUNCTION_RAID_ACTION: | 1991 | case MPI_FUNCTION_RAID_ACTION: |
1892 | /* Just add a SGE | 1992 | /* Just add a SGE |
1893 | */ | 1993 | */ |
@@ -1900,7 +2000,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
1900 | int scsidir = MPI_SCSIIO_CONTROL_READ; | 2000 | int scsidir = MPI_SCSIIO_CONTROL_READ; |
1901 | int dataSize; | 2001 | int dataSize; |
1902 | 2002 | ||
1903 | pScsiReq->MsgFlags = mpt_msg_flags(); | 2003 | pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH; |
2004 | pScsiReq->MsgFlags |= mpt_msg_flags(); | ||
2005 | |||
1904 | 2006 | ||
1905 | /* verify that app has not requested | 2007 | /* verify that app has not requested |
1906 | * more sense data than driver | 2008 | * more sense data than driver |
@@ -2130,7 +2232,7 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) | |||
2130 | 2232 | ||
2131 | /* Now wait for the command to complete */ | 2233 | /* Now wait for the command to complete */ |
2132 | timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; | 2234 | timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT; |
2133 | timeout = wait_event_interruptible_timeout(mptctl_wait, | 2235 | timeout = wait_event_timeout(mptctl_wait, |
2134 | ioc->ioctl->wait_done == 1, | 2236 | ioc->ioctl->wait_done == 1, |
2135 | HZ*timeout); | 2237 | HZ*timeout); |
2136 | 2238 | ||
@@ -2246,13 +2348,16 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2246 | hp_host_info_t __user *uarg = (void __user *) arg; | 2348 | hp_host_info_t __user *uarg = (void __user *) arg; |
2247 | MPT_ADAPTER *ioc; | 2349 | MPT_ADAPTER *ioc; |
2248 | struct pci_dev *pdev; | 2350 | struct pci_dev *pdev; |
2249 | char *pbuf; | 2351 | char *pbuf=NULL; |
2250 | dma_addr_t buf_dma; | 2352 | dma_addr_t buf_dma; |
2251 | hp_host_info_t karg; | 2353 | hp_host_info_t karg; |
2252 | CONFIGPARMS cfg; | 2354 | CONFIGPARMS cfg; |
2253 | ConfigPageHeader_t hdr; | 2355 | ConfigPageHeader_t hdr; |
2254 | int iocnum; | 2356 | int iocnum; |
2255 | int rc, cim_rev; | 2357 | int rc, cim_rev; |
2358 | ToolboxIstwiReadWriteRequest_t *IstwiRWRequest; | ||
2359 | MPT_FRAME_HDR *mf = NULL; | ||
2360 | MPIHeader_t *mpi_hdr; | ||
2256 | 2361 | ||
2257 | dctlprintk((": mptctl_hp_hostinfo called.\n")); | 2362 | dctlprintk((": mptctl_hp_hostinfo called.\n")); |
2258 | /* Reset long to int. Should affect IA64 and SPARC only | 2363 | /* Reset long to int. Should affect IA64 and SPARC only |
@@ -2370,7 +2475,7 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2370 | 2475 | ||
2371 | karg.base_io_addr = pci_resource_start(pdev, 0); | 2476 | karg.base_io_addr = pci_resource_start(pdev, 0); |
2372 | 2477 | ||
2373 | if (ioc->bus_type == FC) | 2478 | if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) |
2374 | karg.bus_phys_width = HP_BUS_WIDTH_UNK; | 2479 | karg.bus_phys_width = HP_BUS_WIDTH_UNK; |
2375 | else | 2480 | else |
2376 | karg.bus_phys_width = HP_BUS_WIDTH_16; | 2481 | karg.bus_phys_width = HP_BUS_WIDTH_16; |
@@ -2388,20 +2493,67 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size) | |||
2388 | } | 2493 | } |
2389 | } | 2494 | } |
2390 | 2495 | ||
2391 | cfg.pageAddr = 0; | 2496 | /* |
2392 | cfg.action = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; | 2497 | * Gather ISTWI(Industry Standard Two Wire Interface) Data |
2393 | cfg.dir = MPI_TB_ISTWI_FLAGS_READ; | 2498 | */ |
2394 | cfg.timeout = 10; | 2499 | if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) { |
2500 | dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n", | ||
2501 | ioc->name,__FUNCTION__)); | ||
2502 | goto out; | ||
2503 | } | ||
2504 | |||
2505 | IstwiRWRequest = (ToolboxIstwiReadWriteRequest_t *)mf; | ||
2506 | mpi_hdr = (MPIHeader_t *) mf; | ||
2507 | memset(IstwiRWRequest,0,sizeof(ToolboxIstwiReadWriteRequest_t)); | ||
2508 | IstwiRWRequest->Function = MPI_FUNCTION_TOOLBOX; | ||
2509 | IstwiRWRequest->Tool = MPI_TOOLBOX_ISTWI_READ_WRITE_TOOL; | ||
2510 | IstwiRWRequest->MsgContext = mpi_hdr->MsgContext; | ||
2511 | IstwiRWRequest->Flags = MPI_TB_ISTWI_FLAGS_READ; | ||
2512 | IstwiRWRequest->NumAddressBytes = 0x01; | ||
2513 | IstwiRWRequest->DataLength = cpu_to_le16(0x04); | ||
2514 | if (pdev->devfn & 1) | ||
2515 | IstwiRWRequest->DeviceAddr = 0xB2; | ||
2516 | else | ||
2517 | IstwiRWRequest->DeviceAddr = 0xB0; | ||
2518 | |||
2395 | pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); | 2519 | pbuf = pci_alloc_consistent(ioc->pcidev, 4, &buf_dma); |
2396 | if (pbuf) { | 2520 | if (!pbuf) |
2397 | cfg.physAddr = buf_dma; | 2521 | goto out; |
2398 | if ((mpt_toolbox(ioc, &cfg)) == 0) { | 2522 | mpt_add_sge((char *)&IstwiRWRequest->SGL, |
2399 | karg.rsvd = *(u32 *)pbuf; | 2523 | (MPT_SGE_FLAGS_SSIMPLE_READ|4), buf_dma); |
2400 | } | 2524 | |
2401 | pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); | 2525 | ioc->ioctl->wait_done = 0; |
2402 | pbuf = NULL; | 2526 | mpt_put_msg_frame(mptctl_id, ioc, mf); |
2527 | |||
2528 | rc = wait_event_timeout(mptctl_wait, | ||
2529 | ioc->ioctl->wait_done == 1, | ||
2530 | HZ*MPT_IOCTL_DEFAULT_TIMEOUT /* 10 sec */); | ||
2531 | |||
2532 | if(rc <=0 && (ioc->ioctl->wait_done != 1 )) { | ||
2533 | /* | ||
2534 | * Now we need to reset the board | ||
2535 | */ | ||
2536 | mpt_free_msg_frame(ioc, mf); | ||
2537 | mptctl_timeout_expired(ioc->ioctl); | ||
2538 | goto out; | ||
2403 | } | 2539 | } |
2404 | 2540 | ||
2541 | /* | ||
2542 | *ISTWI Data Definition | ||
2543 | * pbuf[0] = FW_VERSION = 0x4 | ||
2544 | * pbuf[1] = Bay Count = 6 or 4 or 2, depending on | ||
2545 | * the config, you should be seeing one out of these three values | ||
2546 | * pbuf[2] = Drive Installed Map = bit pattern depend on which | ||
2547 | * bays have drives in them | ||
2548 | * pbuf[3] = Checksum (0x100 = (byte0 + byte2 + byte3) | ||
2549 | */ | ||
2550 | if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) | ||
2551 | karg.rsvd = *(u32 *)pbuf; | ||
2552 | |||
2553 | out: | ||
2554 | if (pbuf) | ||
2555 | pci_free_consistent(ioc->pcidev, 4, pbuf, buf_dma); | ||
2556 | |||
2405 | /* Copy the data from kernel memory to user memory | 2557 | /* Copy the data from kernel memory to user memory |
2406 | */ | 2558 | */ |
2407 | if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { | 2559 | if (copy_to_user((char __user *)arg, &karg, sizeof(hp_host_info_t))) { |
@@ -2459,7 +2611,7 @@ mptctl_hp_targetinfo(unsigned long arg) | |||
2459 | 2611 | ||
2460 | /* There is nothing to do for FCP parts. | 2612 | /* There is nothing to do for FCP parts. |
2461 | */ | 2613 | */ |
2462 | if (ioc->bus_type == FC) | 2614 | if ((ioc->bus_type == SAS) || (ioc->bus_type == FC)) |
2463 | return 0; | 2615 | return 0; |
2464 | 2616 | ||
2465 | if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) | 2617 | if ((ioc->spi_data.sdp0length == 0) || (ioc->sh == NULL)) |
@@ -2569,6 +2721,8 @@ mptctl_hp_targetinfo(unsigned long arg) | |||
2569 | static struct file_operations mptctl_fops = { | 2721 | static struct file_operations mptctl_fops = { |
2570 | .owner = THIS_MODULE, | 2722 | .owner = THIS_MODULE, |
2571 | .llseek = no_llseek, | 2723 | .llseek = no_llseek, |
2724 | .release = mptctl_release, | ||
2725 | .fasync = mptctl_fasync, | ||
2572 | .unlocked_ioctl = mptctl_ioctl, | 2726 | .unlocked_ioctl = mptctl_ioctl, |
2573 | #ifdef CONFIG_COMPAT | 2727 | #ifdef CONFIG_COMPAT |
2574 | .compat_ioctl = compat_mpctl_ioctl, | 2728 | .compat_ioctl = compat_mpctl_ioctl, |
@@ -2813,6 +2967,11 @@ static int __init mptctl_init(void) | |||
2813 | /* FIXME! */ | 2967 | /* FIXME! */ |
2814 | } | 2968 | } |
2815 | 2969 | ||
2970 | if (mpt_event_register(mptctl_id, mptctl_event_process) == 0) { | ||
2971 | devtprintk((KERN_INFO MYNAM | ||
2972 | ": Registered for IOC event notifications\n")); | ||
2973 | } | ||
2974 | |||
2816 | return 0; | 2975 | return 0; |
2817 | 2976 | ||
2818 | out_fail: | 2977 | out_fail: |
diff --git a/drivers/message/fusion/mptctl.h b/drivers/message/fusion/mptctl.h index 518996e03481..a2f8a97992e6 100644 --- a/drivers/message/fusion/mptctl.h +++ b/drivers/message/fusion/mptctl.h | |||
@@ -169,8 +169,10 @@ struct mpt_ioctl_pci_info2 { | |||
169 | * Read only. | 169 | * Read only. |
170 | * Data starts at offset 0xC | 170 | * Data starts at offset 0xC |
171 | */ | 171 | */ |
172 | #define MPT_IOCTL_INTERFACE_FC (0x01) | ||
173 | #define MPT_IOCTL_INTERFACE_SCSI (0x00) | 172 | #define MPT_IOCTL_INTERFACE_SCSI (0x00) |
173 | #define MPT_IOCTL_INTERFACE_FC (0x01) | ||
174 | #define MPT_IOCTL_INTERFACE_FC_IP (0x02) | ||
175 | #define MPT_IOCTL_INTERFACE_SAS (0x03) | ||
174 | #define MPT_IOCTL_VERSION_LENGTH (32) | 176 | #define MPT_IOCTL_VERSION_LENGTH (32) |
175 | 177 | ||
176 | struct mpt_ioctl_iocinfo { | 178 | struct mpt_ioctl_iocinfo { |
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index b102c7666d0e..c3a3499bce2a 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c | |||
@@ -93,10 +93,11 @@ static int mptfcDoneCtx = -1; | |||
93 | static int mptfcTaskCtx = -1; | 93 | static int mptfcTaskCtx = -1; |
94 | static int mptfcInternalCtx = -1; /* Used only for internal commands */ | 94 | static int mptfcInternalCtx = -1; /* Used only for internal commands */ |
95 | 95 | ||
96 | int mptfc_slave_alloc(struct scsi_device *device); | 96 | static int mptfc_target_alloc(struct scsi_target *starget); |
97 | static int mptfc_slave_alloc(struct scsi_device *sdev); | ||
97 | static int mptfc_qcmd(struct scsi_cmnd *SCpnt, | 98 | static int mptfc_qcmd(struct scsi_cmnd *SCpnt, |
98 | void (*done)(struct scsi_cmnd *)); | 99 | void (*done)(struct scsi_cmnd *)); |
99 | 100 | static void mptfc_target_destroy(struct scsi_target *starget); | |
100 | static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); | 101 | static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout); |
101 | static void __devexit mptfc_remove(struct pci_dev *pdev); | 102 | static void __devexit mptfc_remove(struct pci_dev *pdev); |
102 | 103 | ||
@@ -107,10 +108,10 @@ static struct scsi_host_template mptfc_driver_template = { | |||
107 | .name = "MPT FC Host", | 108 | .name = "MPT FC Host", |
108 | .info = mptscsih_info, | 109 | .info = mptscsih_info, |
109 | .queuecommand = mptfc_qcmd, | 110 | .queuecommand = mptfc_qcmd, |
110 | .target_alloc = mptscsih_target_alloc, | 111 | .target_alloc = mptfc_target_alloc, |
111 | .slave_alloc = mptfc_slave_alloc, | 112 | .slave_alloc = mptfc_slave_alloc, |
112 | .slave_configure = mptscsih_slave_configure, | 113 | .slave_configure = mptscsih_slave_configure, |
113 | .target_destroy = mptscsih_target_destroy, | 114 | .target_destroy = mptfc_target_destroy, |
114 | .slave_destroy = mptscsih_slave_destroy, | 115 | .slave_destroy = mptscsih_slave_destroy, |
115 | .change_queue_depth = mptscsih_change_queue_depth, | 116 | .change_queue_depth = mptscsih_change_queue_depth, |
116 | .eh_abort_handler = mptscsih_abort, | 117 | .eh_abort_handler = mptscsih_abort, |
@@ -348,14 +349,33 @@ mptfc_generate_rport_ids(FCDevicePage0_t *pg0, struct fc_rport_identifiers *rid) | |||
348 | } | 349 | } |
349 | 350 | ||
350 | static void | 351 | static void |
352 | mptfc_remap_sdev(struct scsi_device *sdev, void *arg) | ||
353 | { | ||
354 | VirtDevice *vdev; | ||
355 | VirtTarget *vtarget; | ||
356 | struct scsi_target *starget; | ||
357 | |||
358 | starget = scsi_target(sdev); | ||
359 | if (starget->hostdata == arg) { | ||
360 | vtarget = arg; | ||
361 | vdev = sdev->hostdata; | ||
362 | if (vdev) { | ||
363 | vdev->bus_id = vtarget->bus_id; | ||
364 | vdev->target_id = vtarget->target_id; | ||
365 | } | ||
366 | } | ||
367 | } | ||
368 | |||
369 | static void | ||
351 | mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | 370 | mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) |
352 | { | 371 | { |
353 | struct fc_rport_identifiers rport_ids; | 372 | struct fc_rport_identifiers rport_ids; |
354 | struct fc_rport *rport; | 373 | struct fc_rport *rport; |
355 | struct mptfc_rport_info *ri; | 374 | struct mptfc_rport_info *ri; |
356 | int match = 0; | 375 | int new_ri = 1; |
357 | u64 port_name; | 376 | u64 pn; |
358 | unsigned long flags; | 377 | unsigned long flags; |
378 | VirtTarget *vtarget; | ||
359 | 379 | ||
360 | if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) | 380 | if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) |
361 | return; | 381 | return; |
@@ -363,14 +383,14 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | |||
363 | /* scan list looking for a match */ | 383 | /* scan list looking for a match */ |
364 | spin_lock_irqsave(&ioc->fc_rport_lock, flags); | 384 | spin_lock_irqsave(&ioc->fc_rport_lock, flags); |
365 | list_for_each_entry(ri, &ioc->fc_rports, list) { | 385 | list_for_each_entry(ri, &ioc->fc_rports, list) { |
366 | port_name = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; | 386 | pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; |
367 | if (port_name == rport_ids.port_name) { /* match */ | 387 | if (pn == rport_ids.port_name) { /* match */ |
368 | list_move_tail(&ri->list, &ioc->fc_rports); | 388 | list_move_tail(&ri->list, &ioc->fc_rports); |
369 | match = 1; | 389 | new_ri = 0; |
370 | break; | 390 | break; |
371 | } | 391 | } |
372 | } | 392 | } |
373 | if (!match) { /* allocate one */ | 393 | if (new_ri) { /* allocate one */ |
374 | spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); | 394 | spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); |
375 | ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); | 395 | ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); |
376 | if (!ri) | 396 | if (!ri) |
@@ -382,40 +402,43 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | |||
382 | ri->pg0 = *pg0; /* add/update pg0 data */ | 402 | ri->pg0 = *pg0; /* add/update pg0 data */ |
383 | ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING; | 403 | ri->flags &= ~MPT_RPORT_INFO_FLAGS_MISSING; |
384 | 404 | ||
405 | /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */ | ||
385 | if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { | 406 | if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { |
386 | ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; | 407 | ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; |
387 | spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); | 408 | spin_unlock_irqrestore(&ioc->fc_rport_lock, flags); |
388 | rport = fc_remote_port_add(ioc->sh,channel, &rport_ids); | 409 | rport = fc_remote_port_add(ioc->sh, channel, &rport_ids); |
389 | spin_lock_irqsave(&ioc->fc_rport_lock, flags); | 410 | spin_lock_irqsave(&ioc->fc_rport_lock, flags); |
390 | if (rport) { | 411 | if (rport) { |
391 | if (*((struct mptfc_rport_info **)rport->dd_data) != ri) { | 412 | ri->rport = rport; |
392 | ri->flags &= ~MPT_RPORT_INFO_FLAGS_MAPPED_VDEV; | 413 | if (new_ri) /* may have been reset by user */ |
393 | ri->vdev = NULL; | 414 | rport->dev_loss_tmo = mptfc_dev_loss_tmo; |
394 | ri->rport = rport; | 415 | *((struct mptfc_rport_info **)rport->dd_data) = ri; |
395 | *((struct mptfc_rport_info **)rport->dd_data) = ri; | ||
396 | } | ||
397 | rport->dev_loss_tmo = mptfc_dev_loss_tmo; | ||
398 | /* | 416 | /* |
399 | * if already mapped, remap here. If not mapped, | 417 | * if already mapped, remap here. If not mapped, |
400 | * slave_alloc will allocate vdev and map | 418 | * target_alloc will allocate vtarget and map, |
419 | * slave_alloc will fill in vdev from vtarget. | ||
401 | */ | 420 | */ |
402 | if (ri->flags & MPT_RPORT_INFO_FLAGS_MAPPED_VDEV) { | 421 | if (ri->starget) { |
403 | ri->vdev->target_id = ri->pg0.CurrentTargetID; | 422 | vtarget = ri->starget->hostdata; |
404 | ri->vdev->bus_id = ri->pg0.CurrentBus; | 423 | if (vtarget) { |
405 | ri->vdev->vtarget->target_id = ri->vdev->target_id; | 424 | vtarget->target_id = pg0->CurrentTargetID; |
406 | ri->vdev->vtarget->bus_id = ri->vdev->bus_id; | 425 | vtarget->bus_id = pg0->CurrentBus; |
426 | starget_for_each_device(ri->starget, | ||
427 | vtarget,mptfc_remap_sdev); | ||
428 | } | ||
429 | ri->remap_needed = 0; | ||
407 | } | 430 | } |
408 | #ifdef MPT_DEBUG | 431 | dfcprintk ((MYIOC_s_INFO_FMT |
409 | printk ("mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " | 432 | "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " |
410 | "rport tid %d, tmo %d\n", | 433 | "rport tid %d, tmo %d\n", |
411 | ioc->sh->host_no, | 434 | ioc->name, |
435 | oc->sh->host_no, | ||
412 | pg0->PortIdentifier, | 436 | pg0->PortIdentifier, |
413 | pg0->WWNN, | 437 | pg0->WWNN, |
414 | pg0->WWPN, | 438 | pg0->WWPN, |
415 | pg0->CurrentTargetID, | 439 | pg0->CurrentTargetID, |
416 | ri->rport->scsi_target_id, | 440 | ri->rport->scsi_target_id, |
417 | ri->rport->dev_loss_tmo); | 441 | ri->rport->dev_loss_tmo)); |
418 | #endif | ||
419 | } else { | 442 | } else { |
420 | list_del(&ri->list); | 443 | list_del(&ri->list); |
421 | kfree(ri); | 444 | kfree(ri); |
@@ -427,6 +450,65 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) | |||
427 | } | 450 | } |
428 | 451 | ||
429 | /* | 452 | /* |
453 | * OS entry point to allow for host driver to free allocated memory | ||
454 | * Called if no device present or device being unloaded | ||
455 | */ | ||
456 | static void | ||
457 | mptfc_target_destroy(struct scsi_target *starget) | ||
458 | { | ||
459 | struct fc_rport *rport; | ||
460 | struct mptfc_rport_info *ri; | ||
461 | |||
462 | rport = starget_to_rport(starget); | ||
463 | if (rport) { | ||
464 | ri = *((struct mptfc_rport_info **)rport->dd_data); | ||
465 | if (ri) /* better be! */ | ||
466 | ri->starget = NULL; | ||
467 | } | ||
468 | if (starget->hostdata) | ||
469 | kfree(starget->hostdata); | ||
470 | starget->hostdata = NULL; | ||
471 | } | ||
472 | |||
473 | /* | ||
474 | * OS entry point to allow host driver to alloc memory | ||
475 | * for each scsi target. Called once per device the bus scan. | ||
476 | * Return non-zero if allocation fails. | ||
477 | */ | ||
478 | static int | ||
479 | mptfc_target_alloc(struct scsi_target *starget) | ||
480 | { | ||
481 | VirtTarget *vtarget; | ||
482 | struct fc_rport *rport; | ||
483 | struct mptfc_rport_info *ri; | ||
484 | int rc; | ||
485 | |||
486 | vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); | ||
487 | if (!vtarget) | ||
488 | return -ENOMEM; | ||
489 | starget->hostdata = vtarget; | ||
490 | |||
491 | rc = -ENODEV; | ||
492 | rport = starget_to_rport(starget); | ||
493 | if (rport) { | ||
494 | ri = *((struct mptfc_rport_info **)rport->dd_data); | ||
495 | if (ri) { /* better be! */ | ||
496 | vtarget->target_id = ri->pg0.CurrentTargetID; | ||
497 | vtarget->bus_id = ri->pg0.CurrentBus; | ||
498 | ri->starget = starget; | ||
499 | ri->remap_needed = 0; | ||
500 | rc = 0; | ||
501 | } | ||
502 | } | ||
503 | if (rc != 0) { | ||
504 | kfree(vtarget); | ||
505 | starget->hostdata = NULL; | ||
506 | } | ||
507 | |||
508 | return rc; | ||
509 | } | ||
510 | |||
511 | /* | ||
430 | * OS entry point to allow host driver to alloc memory | 512 | * OS entry point to allow host driver to alloc memory |
431 | * for each scsi device. Called once per device the bus scan. | 513 | * for each scsi device. Called once per device the bus scan. |
432 | * Return non-zero if allocation fails. | 514 | * Return non-zero if allocation fails. |
@@ -440,7 +522,6 @@ mptfc_slave_alloc(struct scsi_device *sdev) | |||
440 | VirtDevice *vdev; | 522 | VirtDevice *vdev; |
441 | struct scsi_target *starget; | 523 | struct scsi_target *starget; |
442 | struct fc_rport *rport; | 524 | struct fc_rport *rport; |
443 | struct mptfc_rport_info *ri; | ||
444 | unsigned long flags; | 525 | unsigned long flags; |
445 | 526 | ||
446 | 527 | ||
@@ -451,55 +532,44 @@ mptfc_slave_alloc(struct scsi_device *sdev) | |||
451 | 532 | ||
452 | hd = (MPT_SCSI_HOST *)sdev->host->hostdata; | 533 | hd = (MPT_SCSI_HOST *)sdev->host->hostdata; |
453 | 534 | ||
454 | vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); | 535 | vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL); |
455 | if (!vdev) { | 536 | if (!vdev) { |
456 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", | 537 | printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", |
457 | hd->ioc->name, sizeof(VirtDevice)); | 538 | hd->ioc->name, sizeof(VirtDevice)); |
458 | return -ENOMEM; | 539 | return -ENOMEM; |
459 | } | 540 | } |
460 | memset(vdev, 0, sizeof(VirtDevice)); | ||
461 | 541 | ||
462 | spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags); | 542 | spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags); |
463 | 543 | ||
464 | if (!(ri = *((struct mptfc_rport_info **)rport->dd_data))) { | ||
465 | spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); | ||
466 | kfree(vdev); | ||
467 | return -ENODEV; | ||
468 | } | ||
469 | |||
470 | sdev->hostdata = vdev; | 544 | sdev->hostdata = vdev; |
471 | starget = scsi_target(sdev); | 545 | starget = scsi_target(sdev); |
472 | vtarget = starget->hostdata; | 546 | vtarget = starget->hostdata; |
547 | |||
473 | if (vtarget->num_luns == 0) { | 548 | if (vtarget->num_luns == 0) { |
549 | vtarget->ioc_id = hd->ioc->id; | ||
474 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | | 550 | vtarget->tflags = MPT_TARGET_FLAGS_Q_YES | |
475 | MPT_TARGET_FLAGS_VALID_INQUIRY; | 551 | MPT_TARGET_FLAGS_VALID_INQUIRY; |
476 | hd->Targets[sdev->id] = vtarget; | 552 | hd->Targets[sdev->id] = vtarget; |
477 | } | 553 | } |
478 | 554 | ||
479 | vtarget->target_id = vdev->target_id; | ||
480 | vtarget->bus_id = vdev->bus_id; | ||
481 | |||
482 | vdev->vtarget = vtarget; | 555 | vdev->vtarget = vtarget; |
483 | vdev->ioc_id = hd->ioc->id; | 556 | vdev->ioc_id = hd->ioc->id; |
484 | vdev->lun = sdev->lun; | 557 | vdev->lun = sdev->lun; |
485 | vdev->target_id = ri->pg0.CurrentTargetID; | 558 | vdev->target_id = vtarget->target_id; |
486 | vdev->bus_id = ri->pg0.CurrentBus; | 559 | vdev->bus_id = vtarget->bus_id; |
487 | |||
488 | ri->flags |= MPT_RPORT_INFO_FLAGS_MAPPED_VDEV; | ||
489 | ri->vdev = vdev; | ||
490 | 560 | ||
491 | spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); | 561 | spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags); |
492 | 562 | ||
493 | vtarget->num_luns++; | 563 | vtarget->num_luns++; |
494 | 564 | ||
495 | #ifdef MPT_DEBUG | 565 | dfcprintk ((MYIOC_s_INFO_FMT |
496 | printk ("mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " | 566 | "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " |
497 | "CurrentTargetID %d, %x %llx %llx\n", | 567 | "CurrentTargetID %d, %x %llx %llx\n", |
498 | sdev->host->host_no, | 568 | ioc->name, |
499 | vtarget->num_luns, | 569 | sdev->host->host_no, |
500 | sdev->id, ri->pg0.CurrentTargetID, | 570 | vtarget->num_luns, |
501 | ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN); | 571 | sdev->id, ri->pg0.CurrentTargetID, |
502 | #endif | 572 | ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); |
503 | 573 | ||
504 | return 0; | 574 | return 0; |
505 | } | 575 | } |
@@ -507,6 +577,7 @@ mptfc_slave_alloc(struct scsi_device *sdev) | |||
507 | static int | 577 | static int |
508 | mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | 578 | mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) |
509 | { | 579 | { |
580 | struct mptfc_rport_info *ri; | ||
510 | struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); | 581 | struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device)); |
511 | int err; | 582 | int err; |
512 | 583 | ||
@@ -516,6 +587,10 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) | |||
516 | done(SCpnt); | 587 | done(SCpnt); |
517 | return 0; | 588 | return 0; |
518 | } | 589 | } |
590 | ri = *((struct mptfc_rport_info **)rport->dd_data); | ||
591 | if (unlikely(ri->remap_needed)) | ||
592 | return SCSI_MLQUEUE_HOST_BUSY; | ||
593 | |||
519 | return mptscsih_qcmd(SCpnt,done); | 594 | return mptscsih_qcmd(SCpnt,done); |
520 | } | 595 | } |
521 | 596 | ||
@@ -591,16 +666,20 @@ mptfc_rescan_devices(void *arg) | |||
591 | 666 | ||
592 | ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| | 667 | ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| |
593 | MPT_RPORT_INFO_FLAGS_MISSING); | 668 | MPT_RPORT_INFO_FLAGS_MISSING); |
669 | ri->remap_needed = 1; | ||
594 | fc_remote_port_delete(ri->rport); | 670 | fc_remote_port_delete(ri->rport); |
595 | /* | 671 | /* |
596 | * remote port not really deleted 'cause | 672 | * remote port not really deleted 'cause |
597 | * binding is by WWPN and driver only | 673 | * binding is by WWPN and driver only |
598 | * registers FCP_TARGETs | 674 | * registers FCP_TARGETs but cannot trust |
675 | * data structures. | ||
599 | */ | 676 | */ |
600 | #ifdef MPT_DEBUG | 677 | ri->rport = NULL; |
601 | printk ("mptfc_rescan.%d: %llx deleted\n", | 678 | dfcprintk ((MYIOC_s_INFO_FMT |
602 | ioc->sh->host_no, ri->pg0.WWPN); | 679 | "mptfc_rescan.%d: %llx deleted\n", |
603 | #endif | 680 | ioc->name, |
681 | ioc->sh->host_no, | ||
682 | ri->pg0.WWPN)); | ||
604 | } | 683 | } |
605 | } | 684 | } |
606 | spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); | 685 | spin_unlock_irqrestore(&ioc->fc_rport_lock,flags); |
@@ -872,9 +951,8 @@ mptfc_init(void) | |||
872 | } | 951 | } |
873 | 952 | ||
874 | error = pci_register_driver(&mptfc_driver); | 953 | error = pci_register_driver(&mptfc_driver); |
875 | if (error) { | 954 | if (error) |
876 | fc_release_transport(mptfc_transport_template); | 955 | fc_release_transport(mptfc_transport_template); |
877 | } | ||
878 | 956 | ||
879 | return error; | 957 | return error; |
880 | } | 958 | } |
@@ -885,7 +963,8 @@ mptfc_init(void) | |||
885 | * @pdev: Pointer to pci_dev structure | 963 | * @pdev: Pointer to pci_dev structure |
886 | * | 964 | * |
887 | */ | 965 | */ |
888 | static void __devexit mptfc_remove(struct pci_dev *pdev) | 966 | static void __devexit |
967 | mptfc_remove(struct pci_dev *pdev) | ||
889 | { | 968 | { |
890 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 969 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
891 | struct mptfc_rport_info *p, *n; | 970 | struct mptfc_rport_info *p, *n; |
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 5a06d8d8694e..2512d0e6155e 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -89,6 +89,8 @@ static int mptsasMgmtCtx = -1; | |||
89 | enum mptsas_hotplug_action { | 89 | enum mptsas_hotplug_action { |
90 | MPTSAS_ADD_DEVICE, | 90 | MPTSAS_ADD_DEVICE, |
91 | MPTSAS_DEL_DEVICE, | 91 | MPTSAS_DEL_DEVICE, |
92 | MPTSAS_ADD_RAID, | ||
93 | MPTSAS_DEL_RAID, | ||
92 | }; | 94 | }; |
93 | 95 | ||
94 | struct mptsas_hotplug_event { | 96 | struct mptsas_hotplug_event { |
@@ -114,6 +116,7 @@ struct mptsas_hotplug_event { | |||
114 | 116 | ||
115 | struct mptsas_devinfo { | 117 | struct mptsas_devinfo { |
116 | u16 handle; /* unique id to address this device */ | 118 | u16 handle; /* unique id to address this device */ |
119 | u16 handle_parent; /* unique id to address parent device */ | ||
117 | u8 phy_id; /* phy number of parent device */ | 120 | u8 phy_id; /* phy number of parent device */ |
118 | u8 port_id; /* sas physical port this device | 121 | u8 port_id; /* sas physical port this device |
119 | is assoc'd with */ | 122 | is assoc'd with */ |
@@ -301,9 +304,8 @@ mptsas_slave_alloc(struct scsi_device *sdev) | |||
301 | } | 304 | } |
302 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 305 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
303 | 306 | ||
304 | printk("No matching SAS device found!!\n"); | ||
305 | kfree(vdev); | 307 | kfree(vdev); |
306 | return -ENODEV; | 308 | return -ENXIO; |
307 | 309 | ||
308 | out: | 310 | out: |
309 | vtarget->ioc_id = vdev->ioc_id; | 311 | vtarget->ioc_id = vdev->ioc_id; |
@@ -321,6 +323,7 @@ mptsas_slave_destroy(struct scsi_device *sdev) | |||
321 | struct sas_rphy *rphy; | 323 | struct sas_rphy *rphy; |
322 | struct mptsas_portinfo *p; | 324 | struct mptsas_portinfo *p; |
323 | int i; | 325 | int i; |
326 | VirtDevice *vdev; | ||
324 | 327 | ||
325 | /* | 328 | /* |
326 | * Handle hotplug removal case. | 329 | * Handle hotplug removal case. |
@@ -344,8 +347,29 @@ mptsas_slave_destroy(struct scsi_device *sdev) | |||
344 | out: | 347 | out: |
345 | mutex_unlock(&hd->ioc->sas_topology_mutex); | 348 | mutex_unlock(&hd->ioc->sas_topology_mutex); |
346 | /* | 349 | /* |
347 | * TODO: Issue target reset to flush firmware outstanding commands. | 350 | * Issue target reset to flush firmware outstanding commands. |
348 | */ | 351 | */ |
352 | vdev = sdev->hostdata; | ||
353 | if (vdev->configured_lun){ | ||
354 | if (mptscsih_TMHandler(hd, | ||
355 | MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | ||
356 | vdev->bus_id, | ||
357 | vdev->target_id, | ||
358 | 0, 0, 5 /* 5 second timeout */) | ||
359 | < 0){ | ||
360 | |||
361 | /* The TM request failed! | ||
362 | * Fatal error case. | ||
363 | */ | ||
364 | printk(MYIOC_s_WARN_FMT | ||
365 | "Error processing TaskMgmt id=%d TARGET_RESET\n", | ||
366 | hd->ioc->name, | ||
367 | vdev->target_id); | ||
368 | |||
369 | hd->tmPending = 0; | ||
370 | hd->tmState = TM_STATE_NONE; | ||
371 | } | ||
372 | } | ||
349 | mptscsih_slave_destroy(sdev); | 373 | mptscsih_slave_destroy(sdev); |
350 | } | 374 | } |
351 | 375 | ||
@@ -714,6 +738,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, | |||
714 | mptsas_print_device_pg0(buffer); | 738 | mptsas_print_device_pg0(buffer); |
715 | 739 | ||
716 | device_info->handle = le16_to_cpu(buffer->DevHandle); | 740 | device_info->handle = le16_to_cpu(buffer->DevHandle); |
741 | device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); | ||
717 | device_info->phy_id = buffer->PhyNum; | 742 | device_info->phy_id = buffer->PhyNum; |
718 | device_info->port_id = buffer->PhysicalPort; | 743 | device_info->port_id = buffer->PhysicalPort; |
719 | device_info->id = buffer->TargetID; | 744 | device_info->id = buffer->TargetID; |
@@ -863,6 +888,26 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, | |||
863 | return error; | 888 | return error; |
864 | } | 889 | } |
865 | 890 | ||
891 | /* | ||
892 | * Returns true if there is a scsi end device | ||
893 | */ | ||
894 | static inline int | ||
895 | mptsas_is_end_device(struct mptsas_devinfo * attached) | ||
896 | { | ||
897 | if ((attached->handle) && | ||
898 | (attached->device_info & | ||
899 | MPI_SAS_DEVICE_INFO_END_DEVICE) && | ||
900 | ((attached->device_info & | ||
901 | MPI_SAS_DEVICE_INFO_SSP_TARGET) | | ||
902 | (attached->device_info & | ||
903 | MPI_SAS_DEVICE_INFO_STP_TARGET) | | ||
904 | (attached->device_info & | ||
905 | MPI_SAS_DEVICE_INFO_SATA_DEVICE))) | ||
906 | return 1; | ||
907 | else | ||
908 | return 0; | ||
909 | } | ||
910 | |||
866 | static void | 911 | static void |
867 | mptsas_parse_device_info(struct sas_identify *identify, | 912 | mptsas_parse_device_info(struct sas_identify *identify, |
868 | struct mptsas_devinfo *device_info) | 913 | struct mptsas_devinfo *device_info) |
@@ -1227,7 +1272,7 @@ mptsas_find_phyinfo_by_parent(MPT_ADAPTER *ioc, u16 parent_handle, u8 phy_id) | |||
1227 | } | 1272 | } |
1228 | 1273 | ||
1229 | static struct mptsas_phyinfo * | 1274 | static struct mptsas_phyinfo * |
1230 | mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) | 1275 | mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) |
1231 | { | 1276 | { |
1232 | struct mptsas_portinfo *port_info; | 1277 | struct mptsas_portinfo *port_info; |
1233 | struct mptsas_phyinfo *phy_info = NULL; | 1278 | struct mptsas_phyinfo *phy_info = NULL; |
@@ -1239,12 +1284,12 @@ mptsas_find_phyinfo_by_handle(MPT_ADAPTER *ioc, u16 handle) | |||
1239 | */ | 1284 | */ |
1240 | mutex_lock(&ioc->sas_topology_mutex); | 1285 | mutex_lock(&ioc->sas_topology_mutex); |
1241 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 1286 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
1242 | for (i = 0; i < port_info->num_phys; i++) { | 1287 | for (i = 0; i < port_info->num_phys; i++) |
1243 | if (port_info->phy_info[i].attached.handle == handle) { | 1288 | if (mptsas_is_end_device(&port_info->phy_info[i].attached)) |
1244 | phy_info = &port_info->phy_info[i]; | 1289 | if (port_info->phy_info[i].attached.id == id) { |
1245 | break; | 1290 | phy_info = &port_info->phy_info[i]; |
1246 | } | 1291 | break; |
1247 | } | 1292 | } |
1248 | } | 1293 | } |
1249 | mutex_unlock(&ioc->sas_topology_mutex); | 1294 | mutex_unlock(&ioc->sas_topology_mutex); |
1250 | 1295 | ||
@@ -1258,36 +1303,58 @@ mptsas_hotplug_work(void *arg) | |||
1258 | MPT_ADAPTER *ioc = ev->ioc; | 1303 | MPT_ADAPTER *ioc = ev->ioc; |
1259 | struct mptsas_phyinfo *phy_info; | 1304 | struct mptsas_phyinfo *phy_info; |
1260 | struct sas_rphy *rphy; | 1305 | struct sas_rphy *rphy; |
1306 | struct scsi_device *sdev; | ||
1261 | char *ds = NULL; | 1307 | char *ds = NULL; |
1262 | 1308 | struct mptsas_devinfo sas_device; | |
1263 | if (ev->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | ||
1264 | ds = "ssp"; | ||
1265 | if (ev->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) | ||
1266 | ds = "stp"; | ||
1267 | if (ev->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) | ||
1268 | ds = "sata"; | ||
1269 | 1309 | ||
1270 | switch (ev->event_type) { | 1310 | switch (ev->event_type) { |
1271 | case MPTSAS_DEL_DEVICE: | 1311 | case MPTSAS_DEL_DEVICE: |
1272 | printk(MYIOC_s_INFO_FMT | ||
1273 | "removing %s device, channel %d, id %d, phy %d\n", | ||
1274 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); | ||
1275 | 1312 | ||
1276 | phy_info = mptsas_find_phyinfo_by_handle(ioc, ev->handle); | 1313 | phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); |
1277 | if (!phy_info) { | 1314 | if (!phy_info) { |
1278 | printk("mptsas: remove event for non-existant PHY.\n"); | 1315 | printk("mptsas: remove event for non-existant PHY.\n"); |
1279 | break; | 1316 | break; |
1280 | } | 1317 | } |
1281 | 1318 | ||
1319 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | ||
1320 | ds = "ssp"; | ||
1321 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) | ||
1322 | ds = "stp"; | ||
1323 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) | ||
1324 | ds = "sata"; | ||
1325 | |||
1326 | printk(MYIOC_s_INFO_FMT | ||
1327 | "removing %s device, channel %d, id %d, phy %d\n", | ||
1328 | ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); | ||
1329 | |||
1282 | if (phy_info->rphy) { | 1330 | if (phy_info->rphy) { |
1283 | sas_rphy_delete(phy_info->rphy); | 1331 | sas_rphy_delete(phy_info->rphy); |
1284 | phy_info->rphy = NULL; | 1332 | phy_info->rphy = NULL; |
1285 | } | 1333 | } |
1286 | break; | 1334 | break; |
1287 | case MPTSAS_ADD_DEVICE: | 1335 | case MPTSAS_ADD_DEVICE: |
1288 | printk(MYIOC_s_INFO_FMT | 1336 | |
1289 | "attaching %s device, channel %d, id %d, phy %d\n", | 1337 | /* |
1290 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); | 1338 | * When there is no sas address, |
1339 | * RAID volumes are being deleted, | ||
1340 | * and hidden phy disk are being added. | ||
1341 | * We don't know the SAS data yet, | ||
1342 | * so lookup sas device page to get | ||
1343 | * pertaining info | ||
1344 | */ | ||
1345 | if (!ev->sas_address) { | ||
1346 | if (mptsas_sas_device_pg0(ioc, | ||
1347 | &sas_device, ev->id, | ||
1348 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << | ||
1349 | MPI_SAS_DEVICE_PGAD_FORM_SHIFT))) | ||
1350 | break; | ||
1351 | ev->handle = sas_device.handle; | ||
1352 | ev->parent_handle = sas_device.handle_parent; | ||
1353 | ev->channel = sas_device.channel; | ||
1354 | ev->phy_id = sas_device.phy_id; | ||
1355 | ev->sas_address = sas_device.sas_address; | ||
1356 | ev->device_info = sas_device.device_info; | ||
1357 | } | ||
1291 | 1358 | ||
1292 | phy_info = mptsas_find_phyinfo_by_parent(ioc, | 1359 | phy_info = mptsas_find_phyinfo_by_parent(ioc, |
1293 | ev->parent_handle, ev->phy_id); | 1360 | ev->parent_handle, ev->phy_id); |
@@ -1310,10 +1377,23 @@ mptsas_hotplug_work(void *arg) | |||
1310 | phy_info->attached.sas_address = ev->sas_address; | 1377 | phy_info->attached.sas_address = ev->sas_address; |
1311 | phy_info->attached.device_info = ev->device_info; | 1378 | phy_info->attached.device_info = ev->device_info; |
1312 | 1379 | ||
1380 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | ||
1381 | ds = "ssp"; | ||
1382 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) | ||
1383 | ds = "stp"; | ||
1384 | if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) | ||
1385 | ds = "sata"; | ||
1386 | |||
1387 | printk(MYIOC_s_INFO_FMT | ||
1388 | "attaching %s device, channel %d, id %d, phy %d\n", | ||
1389 | ioc->name, ds, ev->channel, ev->id, ev->phy_id); | ||
1390 | |||
1391 | |||
1313 | rphy = sas_rphy_alloc(phy_info->phy); | 1392 | rphy = sas_rphy_alloc(phy_info->phy); |
1314 | if (!rphy) | 1393 | if (!rphy) |
1315 | break; /* non-fatal: an rphy can be added later */ | 1394 | break; /* non-fatal: an rphy can be added later */ |
1316 | 1395 | ||
1396 | rphy->scsi_target_id = phy_info->attached.id; | ||
1317 | mptsas_parse_device_info(&rphy->identify, &phy_info->attached); | 1397 | mptsas_parse_device_info(&rphy->identify, &phy_info->attached); |
1318 | if (sas_rphy_add(rphy)) { | 1398 | if (sas_rphy_add(rphy)) { |
1319 | sas_rphy_free(rphy); | 1399 | sas_rphy_free(rphy); |
@@ -1322,6 +1402,40 @@ mptsas_hotplug_work(void *arg) | |||
1322 | 1402 | ||
1323 | phy_info->rphy = rphy; | 1403 | phy_info->rphy = rphy; |
1324 | break; | 1404 | break; |
1405 | case MPTSAS_ADD_RAID: | ||
1406 | sdev = scsi_device_lookup( | ||
1407 | ioc->sh, | ||
1408 | ioc->num_ports, | ||
1409 | ev->id, | ||
1410 | 0); | ||
1411 | if (sdev) { | ||
1412 | scsi_device_put(sdev); | ||
1413 | break; | ||
1414 | } | ||
1415 | printk(MYIOC_s_INFO_FMT | ||
1416 | "attaching device, channel %d, id %d\n", | ||
1417 | ioc->name, ioc->num_ports, ev->id); | ||
1418 | scsi_add_device(ioc->sh, | ||
1419 | ioc->num_ports, | ||
1420 | ev->id, | ||
1421 | 0); | ||
1422 | mpt_findImVolumes(ioc); | ||
1423 | break; | ||
1424 | case MPTSAS_DEL_RAID: | ||
1425 | sdev = scsi_device_lookup( | ||
1426 | ioc->sh, | ||
1427 | ioc->num_ports, | ||
1428 | ev->id, | ||
1429 | 0); | ||
1430 | if (!sdev) | ||
1431 | break; | ||
1432 | printk(MYIOC_s_INFO_FMT | ||
1433 | "removing device, channel %d, id %d\n", | ||
1434 | ioc->name, ioc->num_ports, ev->id); | ||
1435 | scsi_remove_device(sdev); | ||
1436 | scsi_device_put(sdev); | ||
1437 | mpt_findImVolumes(ioc); | ||
1438 | break; | ||
1325 | } | 1439 | } |
1326 | 1440 | ||
1327 | kfree(ev); | 1441 | kfree(ev); |
@@ -1372,23 +1486,94 @@ mptscsih_send_sas_event(MPT_ADAPTER *ioc, | |||
1372 | schedule_work(&ev->work); | 1486 | schedule_work(&ev->work); |
1373 | } | 1487 | } |
1374 | 1488 | ||
1489 | static void | ||
1490 | mptscsih_send_raid_event(MPT_ADAPTER *ioc, | ||
1491 | EVENT_DATA_RAID *raid_event_data) | ||
1492 | { | ||
1493 | struct mptsas_hotplug_event *ev; | ||
1494 | RAID_VOL0_STATUS * volumeStatus; | ||
1495 | |||
1496 | if (ioc->bus_type != SAS) | ||
1497 | return; | ||
1498 | |||
1499 | ev = kmalloc(sizeof(*ev), GFP_ATOMIC); | ||
1500 | if (!ev) { | ||
1501 | printk(KERN_WARNING "mptsas: lost hotplug event\n"); | ||
1502 | return; | ||
1503 | } | ||
1504 | |||
1505 | memset(ev,0,sizeof(struct mptsas_hotplug_event)); | ||
1506 | INIT_WORK(&ev->work, mptsas_hotplug_work, ev); | ||
1507 | ev->ioc = ioc; | ||
1508 | ev->id = raid_event_data->VolumeID; | ||
1509 | |||
1510 | switch (raid_event_data->ReasonCode) { | ||
1511 | case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: | ||
1512 | ev->event_type = MPTSAS_ADD_DEVICE; | ||
1513 | break; | ||
1514 | case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: | ||
1515 | ev->event_type = MPTSAS_DEL_DEVICE; | ||
1516 | break; | ||
1517 | case MPI_EVENT_RAID_RC_VOLUME_DELETED: | ||
1518 | ev->event_type = MPTSAS_DEL_RAID; | ||
1519 | break; | ||
1520 | case MPI_EVENT_RAID_RC_VOLUME_CREATED: | ||
1521 | ev->event_type = MPTSAS_ADD_RAID; | ||
1522 | break; | ||
1523 | case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: | ||
1524 | volumeStatus = (RAID_VOL0_STATUS *) & | ||
1525 | raid_event_data->SettingsStatus; | ||
1526 | ev->event_type = (volumeStatus->State == | ||
1527 | MPI_RAIDVOL0_STATUS_STATE_FAILED) ? | ||
1528 | MPTSAS_DEL_RAID : MPTSAS_ADD_RAID; | ||
1529 | break; | ||
1530 | default: | ||
1531 | break; | ||
1532 | } | ||
1533 | schedule_work(&ev->work); | ||
1534 | } | ||
1535 | |||
1536 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
1537 | /* work queue thread to clear the persitency table */ | ||
1538 | static void | ||
1539 | mptscsih_sas_persist_clear_table(void * arg) | ||
1540 | { | ||
1541 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | ||
1542 | |||
1543 | mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); | ||
1544 | } | ||
1545 | |||
1375 | static int | 1546 | static int |
1376 | mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | 1547 | mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) |
1377 | { | 1548 | { |
1549 | int rc=1; | ||
1378 | u8 event = le32_to_cpu(reply->Event) & 0xFF; | 1550 | u8 event = le32_to_cpu(reply->Event) & 0xFF; |
1379 | 1551 | ||
1380 | if (!ioc->sh) | 1552 | if (!ioc->sh) |
1381 | return 1; | 1553 | goto out; |
1382 | 1554 | ||
1383 | switch (event) { | 1555 | switch (event) { |
1384 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: | 1556 | case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: |
1385 | mptscsih_send_sas_event(ioc, | 1557 | mptscsih_send_sas_event(ioc, |
1386 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); | 1558 | (EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)reply->Data); |
1387 | return 1; /* currently means nothing really */ | 1559 | break; |
1388 | 1560 | case MPI_EVENT_INTEGRATED_RAID: | |
1561 | mptscsih_send_raid_event(ioc, | ||
1562 | (EVENT_DATA_RAID *)reply->Data); | ||
1563 | break; | ||
1564 | case MPI_EVENT_PERSISTENT_TABLE_FULL: | ||
1565 | INIT_WORK(&ioc->mptscsih_persistTask, | ||
1566 | mptscsih_sas_persist_clear_table, | ||
1567 | (void *)ioc); | ||
1568 | schedule_work(&ioc->mptscsih_persistTask); | ||
1569 | break; | ||
1389 | default: | 1570 | default: |
1390 | return mptscsih_event_process(ioc, reply); | 1571 | rc = mptscsih_event_process(ioc, reply); |
1572 | break; | ||
1391 | } | 1573 | } |
1574 | out: | ||
1575 | |||
1576 | return rc; | ||
1392 | } | 1577 | } |
1393 | 1578 | ||
1394 | static int | 1579 | static int |
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index cdac5578fdf2..4fee6befc93d 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c | |||
@@ -144,7 +144,6 @@ static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); | |||
144 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); | 144 | static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); |
145 | static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); | 145 | static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); |
146 | 146 | ||
147 | static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | ||
148 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | 147 | static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); |
149 | 148 | ||
150 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 149 | int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
@@ -159,11 +158,9 @@ static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); | |||
159 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); | 158 | int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); |
160 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); | 159 | static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); |
161 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); | 160 | static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
162 | static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget); | 161 | static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice); |
163 | static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); | 162 | static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); |
164 | 163 | ||
165 | static struct work_struct mptscsih_persistTask; | ||
166 | |||
167 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION | 164 | #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION |
168 | static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); | 165 | static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); |
169 | static void mptscsih_domainValidation(void *hd); | 166 | static void mptscsih_domainValidation(void *hd); |
@@ -563,11 +560,24 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
563 | MPT_SCSI_HOST *hd; | 560 | MPT_SCSI_HOST *hd; |
564 | SCSIIORequest_t *pScsiReq; | 561 | SCSIIORequest_t *pScsiReq; |
565 | SCSIIOReply_t *pScsiReply; | 562 | SCSIIOReply_t *pScsiReply; |
566 | u16 req_idx; | 563 | u16 req_idx, req_idx_MR; |
567 | 564 | ||
568 | hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; | 565 | hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; |
569 | 566 | ||
570 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); | 567 | req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); |
568 | req_idx_MR = (mr != NULL) ? | ||
569 | le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx; | ||
570 | if ((req_idx != req_idx_MR) || | ||
571 | (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) { | ||
572 | printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n", | ||
573 | ioc->name); | ||
574 | printk (MYIOC_s_ERR_FMT | ||
575 | "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n", | ||
576 | ioc->name, req_idx, req_idx_MR, mf, mr, | ||
577 | hd->ScsiLookup[req_idx_MR]); | ||
578 | return 0; | ||
579 | } | ||
580 | |||
571 | sc = hd->ScsiLookup[req_idx]; | 581 | sc = hd->ScsiLookup[req_idx]; |
572 | if (sc == NULL) { | 582 | if (sc == NULL) { |
573 | MPIHeader_t *hdr = (MPIHeader_t *)mf; | 583 | MPIHeader_t *hdr = (MPIHeader_t *)mf; |
@@ -730,6 +740,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
730 | 740 | ||
731 | break; | 741 | break; |
732 | 742 | ||
743 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | ||
744 | sc->resid=0; | ||
733 | case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ | 745 | case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ |
734 | case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ | 746 | case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ |
735 | if (scsi_status == MPI_SCSI_STATUS_BUSY) | 747 | if (scsi_status == MPI_SCSI_STATUS_BUSY) |
@@ -789,7 +801,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) | |||
789 | case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ | 801 | case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ |
790 | case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ | 802 | case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ |
791 | case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ | 803 | case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ |
792 | case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ | ||
793 | case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ | 804 | case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ |
794 | case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ | 805 | case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ |
795 | default: | 806 | default: |
@@ -1530,7 +1541,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) | |||
1530 | * | 1541 | * |
1531 | * Returns 0 for SUCCESS or -1 if FAILED. | 1542 | * Returns 0 for SUCCESS or -1 if FAILED. |
1532 | */ | 1543 | */ |
1533 | static int | 1544 | int |
1534 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) | 1545 | mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) |
1535 | { | 1546 | { |
1536 | MPT_ADAPTER *ioc; | 1547 | MPT_ADAPTER *ioc; |
@@ -1721,6 +1732,20 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun | |||
1721 | return retval; | 1732 | return retval; |
1722 | } | 1733 | } |
1723 | 1734 | ||
1735 | static int | ||
1736 | mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) | ||
1737 | { | ||
1738 | switch (ioc->bus_type) { | ||
1739 | case FC: | ||
1740 | return 40; | ||
1741 | case SAS: | ||
1742 | return 10; | ||
1743 | case SPI: | ||
1744 | default: | ||
1745 | return 2; | ||
1746 | } | ||
1747 | } | ||
1748 | |||
1724 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 1749 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
1725 | /** | 1750 | /** |
1726 | * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant | 1751 | * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant |
@@ -1792,7 +1817,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) | |||
1792 | vdev = SCpnt->device->hostdata; | 1817 | vdev = SCpnt->device->hostdata; |
1793 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, | 1818 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, |
1794 | vdev->bus_id, vdev->target_id, vdev->lun, | 1819 | vdev->bus_id, vdev->target_id, vdev->lun, |
1795 | ctx2abort, 2 /* 2 second timeout */); | 1820 | ctx2abort, mptscsih_get_tm_timeout(ioc)); |
1796 | 1821 | ||
1797 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", | 1822 | printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", |
1798 | hd->ioc->name, | 1823 | hd->ioc->name, |
@@ -1843,7 +1868,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) | |||
1843 | vdev = SCpnt->device->hostdata; | 1868 | vdev = SCpnt->device->hostdata; |
1844 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, | 1869 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, |
1845 | vdev->bus_id, vdev->target_id, | 1870 | vdev->bus_id, vdev->target_id, |
1846 | 0, 0, 5 /* 5 second timeout */); | 1871 | 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1847 | 1872 | ||
1848 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", | 1873 | printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", |
1849 | hd->ioc->name, | 1874 | hd->ioc->name, |
@@ -1893,7 +1918,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) | |||
1893 | 1918 | ||
1894 | vdev = SCpnt->device->hostdata; | 1919 | vdev = SCpnt->device->hostdata; |
1895 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, | 1920 | retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, |
1896 | vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */); | 1921 | vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc)); |
1897 | 1922 | ||
1898 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", | 1923 | printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", |
1899 | hd->ioc->name, | 1924 | hd->ioc->name, |
@@ -2016,6 +2041,42 @@ mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ) | |||
2016 | } | 2041 | } |
2017 | 2042 | ||
2018 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2043 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2044 | static void | ||
2045 | mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code) | ||
2046 | { | ||
2047 | char *desc; | ||
2048 | |||
2049 | switch (response_code) { | ||
2050 | case MPI_SCSITASKMGMT_RSP_TM_COMPLETE: | ||
2051 | desc = "The task completed."; | ||
2052 | break; | ||
2053 | case MPI_SCSITASKMGMT_RSP_INVALID_FRAME: | ||
2054 | desc = "The IOC received an invalid frame status."; | ||
2055 | break; | ||
2056 | case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED: | ||
2057 | desc = "The task type is not supported."; | ||
2058 | break; | ||
2059 | case MPI_SCSITASKMGMT_RSP_TM_FAILED: | ||
2060 | desc = "The requested task failed."; | ||
2061 | break; | ||
2062 | case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED: | ||
2063 | desc = "The task completed successfully."; | ||
2064 | break; | ||
2065 | case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN: | ||
2066 | desc = "The LUN request is invalid."; | ||
2067 | break; | ||
2068 | case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC: | ||
2069 | desc = "The task is in the IOC queue and has not been sent to target."; | ||
2070 | break; | ||
2071 | default: | ||
2072 | desc = "unknown"; | ||
2073 | break; | ||
2074 | } | ||
2075 | printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n", | ||
2076 | ioc->name, response_code, desc); | ||
2077 | } | ||
2078 | |||
2079 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2019 | /** | 2080 | /** |
2020 | * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver | 2081 | * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver |
2021 | * @ioc: Pointer to MPT_ADAPTER structure | 2082 | * @ioc: Pointer to MPT_ADAPTER structure |
@@ -2064,6 +2125,11 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m | |||
2064 | /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ | 2125 | /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ |
2065 | tmType = pScsiTmReq->TaskType; | 2126 | tmType = pScsiTmReq->TaskType; |
2066 | 2127 | ||
2128 | if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 && | ||
2129 | pScsiTmReply->ResponseCode) | ||
2130 | mptscsih_taskmgmt_response_code(ioc, | ||
2131 | pScsiTmReply->ResponseCode); | ||
2132 | |||
2067 | dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", | 2133 | dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", |
2068 | ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); | 2134 | ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); |
2069 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); | 2135 | DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); |
@@ -2255,7 +2321,7 @@ mptscsih_slave_destroy(struct scsi_device *sdev) | |||
2255 | vtarget->luns[0] &= ~(1 << vdevice->lun); | 2321 | vtarget->luns[0] &= ~(1 << vdevice->lun); |
2256 | vtarget->num_luns--; | 2322 | vtarget->num_luns--; |
2257 | if (vtarget->num_luns == 0) { | 2323 | if (vtarget->num_luns == 0) { |
2258 | mptscsih_negotiate_to_asyn_narrow(hd, vtarget); | 2324 | mptscsih_negotiate_to_asyn_narrow(hd, vdevice); |
2259 | if (hd->ioc->bus_type == SPI) { | 2325 | if (hd->ioc->bus_type == SPI) { |
2260 | if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { | 2326 | if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) { |
2261 | hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; | 2327 | hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; |
@@ -2423,7 +2489,7 @@ mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR | |||
2423 | int idx; | 2489 | int idx; |
2424 | MPT_ADAPTER *ioc = hd->ioc; | 2490 | MPT_ADAPTER *ioc = hd->ioc; |
2425 | 2491 | ||
2426 | idx = ioc->eventContext % ioc->eventLogSize; | 2492 | idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; |
2427 | ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; | 2493 | ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; |
2428 | ioc->events[idx].eventContext = ioc->eventContext; | 2494 | ioc->events[idx].eventContext = ioc->eventContext; |
2429 | 2495 | ||
@@ -2585,16 +2651,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) | |||
2585 | } | 2651 | } |
2586 | 2652 | ||
2587 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 2653 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
2588 | /* work queue thread to clear the persitency table */ | ||
2589 | static void | ||
2590 | mptscsih_sas_persist_clear_table(void * arg) | ||
2591 | { | ||
2592 | MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; | ||
2593 | |||
2594 | mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); | ||
2595 | } | ||
2596 | |||
2597 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
2598 | int | 2654 | int |
2599 | mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | 2655 | mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) |
2600 | { | 2656 | { |
@@ -2656,13 +2712,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) | |||
2656 | break; | 2712 | break; |
2657 | } | 2713 | } |
2658 | 2714 | ||
2659 | /* Persistent table is full. */ | ||
2660 | case MPI_EVENT_PERSISTENT_TABLE_FULL: | ||
2661 | INIT_WORK(&mptscsih_persistTask, | ||
2662 | mptscsih_sas_persist_clear_table,(void *)ioc); | ||
2663 | schedule_work(&mptscsih_persistTask); | ||
2664 | break; | ||
2665 | |||
2666 | case MPI_EVENT_NONE: /* 00 */ | 2715 | case MPI_EVENT_NONE: /* 00 */ |
2667 | case MPI_EVENT_LOG_DATA: /* 01 */ | 2716 | case MPI_EVENT_LOG_DATA: /* 01 */ |
2668 | case MPI_EVENT_STATE_CHANGE: /* 02 */ | 2717 | case MPI_EVENT_STATE_CHANGE: /* 02 */ |
@@ -3863,8 +3912,9 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) | |||
3863 | * | 3912 | * |
3864 | */ | 3913 | */ |
3865 | static void | 3914 | static void |
3866 | mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) | 3915 | mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice) |
3867 | { | 3916 | { |
3917 | VirtTarget *vtarget = vdevice->vtarget; | ||
3868 | MPT_ADAPTER *ioc= hd->ioc; | 3918 | MPT_ADAPTER *ioc= hd->ioc; |
3869 | SCSIDevicePage1_t *pcfg1Data; | 3919 | SCSIDevicePage1_t *pcfg1Data; |
3870 | CONFIGPARMS cfg; | 3920 | CONFIGPARMS cfg; |
@@ -3874,7 +3924,8 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) | |||
3874 | int requested, configuration, data,i; | 3924 | int requested, configuration, data,i; |
3875 | u8 flags, factor; | 3925 | u8 flags, factor; |
3876 | 3926 | ||
3877 | if (ioc->bus_type != SPI) | 3927 | if ((ioc->bus_type != SPI) || |
3928 | (!vdevice->configured_lun)) | ||
3878 | return; | 3929 | return; |
3879 | 3930 | ||
3880 | if (!ioc->spi_data.sdp1length) | 3931 | if (!ioc->spi_data.sdp1length) |
@@ -3910,7 +3961,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) | |||
3910 | } | 3961 | } |
3911 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, | 3962 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, |
3912 | &configuration, flags); | 3963 | &configuration, flags); |
3913 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " | 3964 | dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC " |
3914 | "offset=0 negoFlags=%x request=%x config=%x\n", | 3965 | "offset=0 negoFlags=%x request=%x config=%x\n", |
3915 | id, flags, requested, configuration)); | 3966 | id, flags, requested, configuration)); |
3916 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); | 3967 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); |
@@ -3923,7 +3974,7 @@ mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget) | |||
3923 | flags = vtarget->negoFlags; | 3974 | flags = vtarget->negoFlags; |
3924 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, | 3975 | mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, |
3925 | &configuration, flags); | 3976 | &configuration, flags); |
3926 | dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " | 3977 | dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC " |
3927 | "offset=0 negoFlags=%x request=%x config=%x\n", | 3978 | "offset=0 negoFlags=%x request=%x config=%x\n", |
3928 | vtarget->target_id, flags, requested, configuration)); | 3979 | vtarget->target_id, flags, requested, configuration)); |
3929 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); | 3980 | pcfg1Data->RequestedParameters = cpu_to_le32(requested); |
@@ -5620,5 +5671,6 @@ EXPORT_SYMBOL(mptscsih_event_process); | |||
5620 | EXPORT_SYMBOL(mptscsih_ioc_reset); | 5671 | EXPORT_SYMBOL(mptscsih_ioc_reset); |
5621 | EXPORT_SYMBOL(mptscsih_change_queue_depth); | 5672 | EXPORT_SYMBOL(mptscsih_change_queue_depth); |
5622 | EXPORT_SYMBOL(mptscsih_timer_expired); | 5673 | EXPORT_SYMBOL(mptscsih_timer_expired); |
5674 | EXPORT_SYMBOL(mptscsih_TMHandler); | ||
5623 | 5675 | ||
5624 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 5676 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index d3cba12f4bd9..44b248d51ea3 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h | |||
@@ -108,3 +108,4 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pE | |||
108 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); | 108 | extern int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); |
109 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); | 109 | extern int mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth); |
110 | extern void mptscsih_timer_expired(unsigned long data); | 110 | extern void mptscsih_timer_expired(unsigned long data); |
111 | extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); | ||
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 7dce29277cb7..f148dfa39117 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c | |||
@@ -384,6 +384,14 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
384 | goto out_mptspi_probe; | 384 | goto out_mptspi_probe; |
385 | } | 385 | } |
386 | 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 | |||
387 | scsi_scan_host(sh); | 395 | scsi_scan_host(sh); |
388 | return 0; | 396 | return 0; |
389 | 397 | ||
@@ -445,7 +453,7 @@ static void __exit | |||
445 | mptspi_exit(void) | 453 | mptspi_exit(void) |
446 | { | 454 | { |
447 | pci_unregister_driver(&mptspi_driver); | 455 | pci_unregister_driver(&mptspi_driver); |
448 | 456 | ||
449 | mpt_reset_deregister(mptspiDoneCtx); | 457 | mpt_reset_deregister(mptspiDoneCtx); |
450 | dprintk((KERN_INFO MYNAM | 458 | dprintk((KERN_INFO MYNAM |
451 | ": Deregistered for IOC reset notifications\n")); | 459 | ": Deregistered for IOC reset notifications\n")); |