diff options
Diffstat (limited to 'drivers/message')
| -rw-r--r-- | drivers/message/fusion/Makefile | 2 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.c | 184 | ||||
| -rw-r--r-- | drivers/message/fusion/mptbase.h | 16 | ||||
| -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 | 116 | ||||
| -rw-r--r-- | drivers/message/fusion/mptscsih.h | 1 | ||||
| -rw-r--r-- | drivers/message/fusion/mptspi.c | 10 |
8 files changed, 636 insertions, 137 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..9a2c7605d49c 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 | } |
| @@ -1444,6 +1448,9 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1444 | 1448 | ||
| 1445 | ioc->pci_irq = -1; | 1449 | ioc->pci_irq = -1; |
| 1446 | if (pdev->irq) { | 1450 | if (pdev->irq) { |
| 1451 | if (mpt_msi_enable && !pci_enable_msi(pdev)) | ||
| 1452 | printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name); | ||
| 1453 | |||
| 1447 | r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); | 1454 | r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc); |
| 1448 | 1455 | ||
| 1449 | if (r < 0) { | 1456 | if (r < 0) { |
| @@ -1483,6 +1490,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 1483 | 1490 | ||
| 1484 | list_del(&ioc->list); | 1491 | list_del(&ioc->list); |
| 1485 | free_irq(ioc->pci_irq, ioc); | 1492 | free_irq(ioc->pci_irq, ioc); |
| 1493 | if (mpt_msi_enable) | ||
| 1494 | pci_disable_msi(pdev); | ||
| 1495 | if (ioc->alt_ioc) | ||
| 1496 | ioc->alt_ioc->alt_ioc = NULL; | ||
| 1486 | iounmap(mem); | 1497 | iounmap(mem); |
| 1487 | kfree(ioc); | 1498 | kfree(ioc); |
| 1488 | pci_set_drvdata(pdev, NULL); | 1499 | pci_set_drvdata(pdev, NULL); |
| @@ -2136,6 +2147,8 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
| 2136 | 2147 | ||
| 2137 | if (ioc->pci_irq != -1) { | 2148 | if (ioc->pci_irq != -1) { |
| 2138 | free_irq(ioc->pci_irq, ioc); | 2149 | free_irq(ioc->pci_irq, ioc); |
| 2150 | if (mpt_msi_enable) | ||
| 2151 | pci_disable_msi(ioc->pcidev); | ||
| 2139 | ioc->pci_irq = -1; | 2152 | ioc->pci_irq = -1; |
| 2140 | } | 2153 | } |
| 2141 | 2154 | ||
| @@ -2157,6 +2170,10 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
| 2157 | sz_last = ioc->alloc_total; | 2170 | sz_last = ioc->alloc_total; |
| 2158 | dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", | 2171 | dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n", |
| 2159 | ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); | 2172 | ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); |
| 2173 | |||
| 2174 | if (ioc->alt_ioc) | ||
| 2175 | ioc->alt_ioc->alt_ioc = NULL; | ||
| 2176 | |||
| 2160 | kfree(ioc); | 2177 | kfree(ioc); |
| 2161 | } | 2178 | } |
| 2162 | 2179 | ||
| @@ -2770,13 +2787,16 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) | |||
| 2770 | 2787 | ||
| 2771 | /* RAID FW may take a long time to enable | 2788 | /* RAID FW may take a long time to enable |
| 2772 | */ | 2789 | */ |
| 2773 | if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) | 2790 | if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) |
| 2774 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) { | 2791 | > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) || |
| 2775 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, | 2792 | (ioc->bus_type == SAS)) { |
| 2776 | reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag); | 2793 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
| 2794 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, | ||
| 2795 | 300 /*seconds*/, sleepFlag); | ||
| 2777 | } else { | 2796 | } else { |
| 2778 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable, | 2797 | rc = mpt_handshake_req_reply_wait(ioc, req_sz, |
| 2779 | reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag); | 2798 | (u32*)&port_enable, reply_sz, (u16*)&reply_buf, |
| 2799 | 30 /*seconds*/, sleepFlag); | ||
| 2780 | } | 2800 | } |
| 2781 | return rc; | 2801 | return rc; |
| 2782 | } | 2802 | } |
| @@ -4387,6 +4407,138 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) | |||
| 4387 | } | 4407 | } |
| 4388 | 4408 | ||
| 4389 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 4409 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 4410 | |||
| 4411 | static void | ||
| 4412 | mptbase_raid_process_event_data(MPT_ADAPTER *ioc, | ||
| 4413 | MpiEventDataRaid_t * pRaidEventData) | ||
| 4414 | { | ||
| 4415 | int volume; | ||
| 4416 | int reason; | ||
| 4417 | int disk; | ||
| 4418 | int status; | ||
| 4419 | int flags; | ||
| 4420 | int state; | ||
| 4421 | |||
| 4422 | volume = pRaidEventData->VolumeID; | ||
| 4423 | reason = pRaidEventData->ReasonCode; | ||
| 4424 | disk = pRaidEventData->PhysDiskNum; | ||
| 4425 | status = le32_to_cpu(pRaidEventData->SettingsStatus); | ||
| 4426 | flags = (status >> 0) & 0xff; | ||
| 4427 | state = (status >> 8) & 0xff; | ||
| 4428 | |||
| 4429 | if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { | ||
| 4430 | return; | ||
| 4431 | } | ||
| 4432 | |||
| 4433 | if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && | ||
| 4434 | reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || | ||
| 4435 | (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { | ||
| 4436 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", | ||
| 4437 | ioc->name, disk); | ||
| 4438 | } else { | ||
| 4439 | printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", | ||
| 4440 | ioc->name, volume); | ||
| 4441 | } | ||
| 4442 | |||
| 4443 | switch(reason) { | ||
| 4444 | case MPI_EVENT_RAID_RC_VOLUME_CREATED: | ||
| 4445 | printk(MYIOC_s_INFO_FMT " volume has been created\n", | ||
| 4446 | ioc->name); | ||
| 4447 | break; | ||
| 4448 | |||
| 4449 | case MPI_EVENT_RAID_RC_VOLUME_DELETED: | ||
| 4450 | |||
| 4451 | printk(MYIOC_s_INFO_FMT " volume has been deleted\n", | ||
| 4452 | ioc->name); | ||
| 4453 | break; | ||
| 4454 | |||
| 4455 | case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: | ||
| 4456 | printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", | ||
| 4457 | ioc->name); | ||
| 4458 | break; | ||
| 4459 | |||
| 4460 | case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: | ||
| 4461 | printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", | ||
| 4462 | ioc->name, | ||
| 4463 | state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL | ||
| 4464 | ? "optimal" | ||
| 4465 | : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED | ||
| 4466 | ? "degraded" | ||
| 4467 | : state == MPI_RAIDVOL0_STATUS_STATE_FAILED | ||
| 4468 | ? "failed" | ||
| 4469 | : "state unknown", | ||
| 4470 | flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED | ||
| 4471 | ? ", enabled" : "", | ||
| 4472 | flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED | ||
| 4473 | ? ", quiesced" : "", | ||
| 4474 | flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS | ||
| 4475 | ? ", resync in progress" : "" ); | ||
| 4476 | break; | ||
| 4477 | |||
| 4478 | case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: | ||
| 4479 | printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", | ||
| 4480 | ioc->name, disk); | ||
| 4481 | break; | ||
| 4482 | |||
| 4483 | case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: | ||
| 4484 | printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", | ||
| 4485 | ioc->name); | ||
| 4486 | break; | ||
| 4487 | |||
| 4488 | case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: | ||
| 4489 | printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", | ||
| 4490 | ioc->name); | ||
| 4491 | break; | ||
| 4492 | |||
| 4493 | case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: | ||
| 4494 | printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", | ||
| 4495 | ioc->name); | ||
| 4496 | break; | ||
| 4497 | |||
| 4498 | case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: | ||
| 4499 | printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", | ||
| 4500 | ioc->name, | ||
| 4501 | state == MPI_PHYSDISK0_STATUS_ONLINE | ||
| 4502 | ? "online" | ||
| 4503 | : state == MPI_PHYSDISK0_STATUS_MISSING | ||
| 4504 | ? "missing" | ||
| 4505 | : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE | ||
| 4506 | ? "not compatible" | ||
| 4507 | : state == MPI_PHYSDISK0_STATUS_FAILED | ||
| 4508 | ? "failed" | ||
| 4509 | : state == MPI_PHYSDISK0_STATUS_INITIALIZING | ||
| 4510 | ? "initializing" | ||
| 4511 | : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED | ||
| 4512 | ? "offline requested" | ||
| 4513 | : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED | ||
| 4514 | ? "failed requested" | ||
| 4515 | : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE | ||
| 4516 | ? "offline" | ||
| 4517 | : "state unknown", | ||
| 4518 | flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC | ||
| 4519 | ? ", out of sync" : "", | ||
| 4520 | flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED | ||
| 4521 | ? ", quiesced" : "" ); | ||
| 4522 | break; | ||
| 4523 | |||
| 4524 | case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: | ||
| 4525 | printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", | ||
| 4526 | ioc->name, disk); | ||
| 4527 | break; | ||
| 4528 | |||
| 4529 | case MPI_EVENT_RAID_RC_SMART_DATA: | ||
| 4530 | printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", | ||
| 4531 | ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); | ||
| 4532 | break; | ||
| 4533 | |||
| 4534 | case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: | ||
| 4535 | printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", | ||
| 4536 | ioc->name, disk); | ||
| 4537 | break; | ||
| 4538 | } | ||
| 4539 | } | ||
| 4540 | |||
| 4541 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | ||
| 4390 | /* | 4542 | /* |
| 4391 | * GetIoUnitPage2 - Retrieve BIOS version and boot order information. | 4543 | * GetIoUnitPage2 - Retrieve BIOS version and boot order information. |
| 4392 | * @ioc: Pointer to MPT_ADAPTER structure | 4544 | * @ioc: Pointer to MPT_ADAPTER structure |
| @@ -4598,6 +4750,14 @@ mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) | |||
| 4598 | SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; | 4750 | SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; |
| 4599 | MpiDeviceInfo_t *pdevice = NULL; | 4751 | MpiDeviceInfo_t *pdevice = NULL; |
| 4600 | 4752 | ||
| 4753 | /* | ||
| 4754 | * Save "Set to Avoid SCSI Bus Resets" flag | ||
| 4755 | */ | ||
| 4756 | ioc->spi_data.bus_reset = | ||
| 4757 | (le32_to_cpu(pPP2->PortFlags) & | ||
| 4758 | MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? | ||
| 4759 | 0 : 1 ; | ||
| 4760 | |||
| 4601 | /* Save the Port Page 2 data | 4761 | /* Save the Port Page 2 data |
| 4602 | * (reformat into a 32bit quantity) | 4762 | * (reformat into a 32bit quantity) |
| 4603 | */ | 4763 | */ |
| @@ -5967,6 +6127,10 @@ ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply | |||
| 5967 | } | 6127 | } |
| 5968 | } | 6128 | } |
| 5969 | break; | 6129 | break; |
| 6130 | case MPI_EVENT_INTEGRATED_RAID: | ||
| 6131 | mptbase_raid_process_event_data(ioc, | ||
| 6132 | (MpiEventDataRaid_t *)pEventReply->Data); | ||
| 6133 | break; | ||
| 5970 | default: | 6134 | default: |
| 5971 | break; | 6135 | break; |
| 5972 | } | 6136 | } |
| @@ -6046,7 +6210,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
| 6046 | 6210 | ||
| 6047 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ | 6211 | /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ |
| 6048 | /* | 6212 | /* |
| 6049 | * mpt_sp_log_info - Log information returned from SCSI Parallel IOC. | 6213 | * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. |
| 6050 | * @ioc: Pointer to MPT_ADAPTER structure | 6214 | * @ioc: Pointer to MPT_ADAPTER structure |
| 6051 | * @mr: Pointer to MPT reply frame | 6215 | * @mr: Pointer to MPT reply frame |
| 6052 | * @log_info: U32 LogInfo word from the IOC | 6216 | * @log_info: U32 LogInfo word from the IOC |
| @@ -6054,7 +6218,7 @@ mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) | |||
| 6054 | * Refer to lsi/sp_log.h. | 6218 | * Refer to lsi/sp_log.h. |
| 6055 | */ | 6219 | */ |
| 6056 | static void | 6220 | static void |
| 6057 | mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info) | 6221 | mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) |
| 6058 | { | 6222 | { |
| 6059 | u32 info = log_info & 0x00FF0000; | 6223 | u32 info = log_info & 0x00FF0000; |
| 6060 | char *desc = "unknown"; | 6224 | char *desc = "unknown"; |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 47053ac65068..ea2649ecad1f 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 | /* |
| @@ -631,6 +632,7 @@ typedef struct _MPT_ADAPTER | |||
| 631 | struct mutex sas_topology_mutex; | 632 | struct mutex sas_topology_mutex; |
| 632 | MPT_SAS_MGMT sas_mgmt; | 633 | MPT_SAS_MGMT sas_mgmt; |
| 633 | int num_ports; | 634 | int num_ports; |
| 635 | struct work_struct mptscsih_persistTask; | ||
| 634 | 636 | ||
| 635 | struct list_head fc_rports; | 637 | struct list_head fc_rports; |
| 636 | spinlock_t fc_rport_lock; /* list and ri flags */ | 638 | spinlock_t fc_rport_lock; /* list and ri flags */ |
| @@ -803,6 +805,12 @@ typedef struct _mpt_sge { | |||
| 803 | #define dreplyprintk(x) | 805 | #define dreplyprintk(x) |
| 804 | #endif | 806 | #endif |
| 805 | 807 | ||
| 808 | #ifdef DMPT_DEBUG_FC | ||
| 809 | #define dfcprintk(x) printk x | ||
| 810 | #else | ||
| 811 | #define dfcprintk(x) | ||
| 812 | #endif | ||
| 813 | |||
| 806 | #ifdef MPT_DEBUG_TM | 814 | #ifdef MPT_DEBUG_TM |
| 807 | #define dtmprintk(x) printk x | 815 | #define dtmprintk(x) printk x |
| 808 | #define DBG_DUMP_TM_REQUEST_FRAME(mfp) \ | 816 | #define DBG_DUMP_TM_REQUEST_FRAME(mfp) \ |
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..05789e505464 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; |
| @@ -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")); |
