aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
authorEric Moore <eric.moore@lsi.com>2007-01-29 11:45:37 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-02-02 22:01:28 -0500
commitb506ade9f3c309ac2ce3ffc4039f731097506038 (patch)
tree26ffb22dd5859977e92ca57f01033da69a6265f5 /drivers/message/fusion
parentc6c727a1a0ff90c80425b7226557b2354e00cf7b (diff)
[SCSI] fusion - inactive raid support, and raid event bug fix's
inactive raid support, e.g. exposing hidden raid components belonging to a volume that are inactive. Also misc bug fix's for various raid asyn events. Signed-off-by: Eric Moore <Eric.Moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/message/fusion')
-rw-r--r--drivers/message/fusion/mptbase.c278
-rw-r--r--drivers/message/fusion/mptbase.h19
-rw-r--r--drivers/message/fusion/mptsas.c272
-rw-r--r--drivers/message/fusion/mptscsih.c32
-rw-r--r--drivers/message/fusion/mptspi.c3
5 files changed, 510 insertions, 94 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 5d4faa4dd4ea..e7aec3478a30 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -184,6 +184,7 @@ static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
184static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 184static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
185static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 185static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
186static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 186static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
187static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
187 188
188/* module entry point */ 189/* module entry point */
189static int __init fusion_init (void); 190static int __init fusion_init (void);
@@ -1815,6 +1816,13 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1815 * and we try GetLanConfigPages again... 1816 * and we try GetLanConfigPages again...
1816 */ 1817 */
1817 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 1818 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1819
1820 /*
1821 * Initalize link list for inactive raid volumes.
1822 */
1823 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
1824 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
1825
1818 if (ioc->bus_type == SAS) { 1826 if (ioc->bus_type == SAS) {
1819 1827
1820 /* clear persistency table */ 1828 /* clear persistency table */
@@ -2021,6 +2029,8 @@ mpt_adapter_disable(MPT_ADAPTER *ioc)
2021 } 2029 }
2022 2030
2023 kfree(ioc->spi_data.nvram); 2031 kfree(ioc->spi_data.nvram);
2032 mpt_inactive_raid_list_free(ioc);
2033 kfree(ioc->raid_data.pIocPg2);
2024 kfree(ioc->raid_data.pIocPg3); 2034 kfree(ioc->raid_data.pIocPg3);
2025 ioc->spi_data.nvram = NULL; 2035 ioc->spi_data.nvram = NULL;
2026 ioc->raid_data.pIocPg3 = NULL; 2036 ioc->raid_data.pIocPg3 = NULL;
@@ -2417,6 +2427,9 @@ GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2417 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 2427 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2418 2428
2419 facts->ProductID = le16_to_cpu(facts->ProductID); 2429 facts->ProductID = le16_to_cpu(facts->ProductID);
2430 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2431 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2432 ioc->ir_firmware = 1;
2420 facts->CurrentHostMfaHighAddr = 2433 facts->CurrentHostMfaHighAddr =
2421 le32_to_cpu(facts->CurrentHostMfaHighAddr); 2434 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2422 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 2435 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
@@ -2735,9 +2748,7 @@ SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2735 2748
2736 /* RAID FW may take a long time to enable 2749 /* RAID FW may take a long time to enable
2737 */ 2750 */
2738 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 2751 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2739 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2740 (ioc->bus_type == SAS)) {
2741 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 2752 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2742 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 2753 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2743 300 /*seconds*/, sleepFlag); 2754 300 /*seconds*/, sleepFlag);
@@ -4325,8 +4336,8 @@ mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4325 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && 4336 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4326 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || 4337 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4327 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { 4338 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4328 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n", 4339 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4329 ioc->name, disk); 4340 ioc->name, disk, volume);
4330 } else { 4341 } else {
4331 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", 4342 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4332 ioc->name, volume); 4343 ioc->name, volume);
@@ -4727,7 +4738,187 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4727 return 0; 4738 return 0;
4728} 4739}
4729 4740
4730/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4741/**
4742 * mpt_inactive_raid_list_free
4743 *
4744 * This clears this link list.
4745 *
4746 * @ioc - pointer to per adapter structure
4747 *
4748 **/
4749static void
4750mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4751{
4752 struct inactive_raid_component_info *component_info, *pNext;
4753
4754 if (list_empty(&ioc->raid_data.inactive_list))
4755 return;
4756
4757 down(&ioc->raid_data.inactive_list_mutex);
4758 list_for_each_entry_safe(component_info, pNext,
4759 &ioc->raid_data.inactive_list, list) {
4760 list_del(&component_info->list);
4761 kfree(component_info);
4762 }
4763 up(&ioc->raid_data.inactive_list_mutex);
4764}
4765
4766/**
4767 * mpt_inactive_raid_volumes
4768 *
4769 * This sets up link list of phy_disk_nums for devices belonging in an inactive volume
4770 *
4771 * @ioc - pointer to per adapter structure
4772 * @channel - volume channel
4773 * @id - volume target id
4774 *
4775 *
4776 **/
4777static void
4778mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4779{
4780 CONFIGPARMS cfg;
4781 ConfigPageHeader_t hdr;
4782 dma_addr_t dma_handle;
4783 pRaidVolumePage0_t buffer = NULL;
4784 int i;
4785 RaidPhysDiskPage0_t phys_disk;
4786 struct inactive_raid_component_info *component_info;
4787 int handle_inactive_volumes;
4788
4789 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4790 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4791 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4792 cfg.pageAddr = (channel << 8) + id;
4793 cfg.cfghdr.hdr = &hdr;
4794 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4795
4796 if (mpt_config(ioc, &cfg) != 0)
4797 goto out;
4798
4799 if (!hdr.PageLength)
4800 goto out;
4801
4802 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4803 &dma_handle);
4804
4805 if (!buffer)
4806 goto out;
4807
4808 cfg.physAddr = dma_handle;
4809 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4810
4811 if (mpt_config(ioc, &cfg) != 0)
4812 goto out;
4813
4814 if (!buffer->NumPhysDisks)
4815 goto out;
4816
4817 handle_inactive_volumes =
4818 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
4819 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
4820 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
4821 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
4822
4823 if (!handle_inactive_volumes)
4824 goto out;
4825
4826 down(&ioc->raid_data.inactive_list_mutex);
4827 for (i = 0; i < buffer->NumPhysDisks; i++) {
4828 if(mpt_raid_phys_disk_pg0(ioc,
4829 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4830 continue;
4831
4832 if ((component_info = kmalloc(sizeof (*component_info),
4833 GFP_KERNEL)) == NULL)
4834 continue;
4835
4836 component_info->volumeID = id;
4837 component_info->volumeBus = channel;
4838 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
4839 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
4840 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
4841 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
4842
4843 list_add_tail(&component_info->list,
4844 &ioc->raid_data.inactive_list);
4845 }
4846 up(&ioc->raid_data.inactive_list_mutex);
4847
4848 out:
4849 if (buffer)
4850 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4851 dma_handle);
4852}
4853
4854/**
4855 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
4856 * @ioc: Pointer to a Adapter Structure
4857 * @phys_disk_num: io unit unique phys disk num generated by the ioc
4858 * @phys_disk: requested payload data returned
4859 *
4860 * Return:
4861 * 0 on success
4862 * -EFAULT if read of config page header fails or data pointer not NULL
4863 * -ENOMEM if pci_alloc failed
4864 **/
4865int
4866mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
4867{
4868 CONFIGPARMS cfg;
4869 ConfigPageHeader_t hdr;
4870 dma_addr_t dma_handle;
4871 pRaidPhysDiskPage0_t buffer = NULL;
4872 int rc;
4873
4874 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4875 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4876
4877 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
4878 cfg.cfghdr.hdr = &hdr;
4879 cfg.physAddr = -1;
4880 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4881
4882 if (mpt_config(ioc, &cfg) != 0) {
4883 rc = -EFAULT;
4884 goto out;
4885 }
4886
4887 if (!hdr.PageLength) {
4888 rc = -EFAULT;
4889 goto out;
4890 }
4891
4892 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4893 &dma_handle);
4894
4895 if (!buffer) {
4896 rc = -ENOMEM;
4897 goto out;
4898 }
4899
4900 cfg.physAddr = dma_handle;
4901 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4902 cfg.pageAddr = phys_disk_num;
4903
4904 if (mpt_config(ioc, &cfg) != 0) {
4905 rc = -EFAULT;
4906 goto out;
4907 }
4908
4909 rc = 0;
4910 memcpy(phys_disk, buffer, sizeof(*buffer));
4911 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
4912
4913 out:
4914
4915 if (buffer)
4916 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4917 dma_handle);
4918
4919 return rc;
4920}
4921
4731/** 4922/**
4732 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 4923 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4733 * @ioc: Pointer to a Adapter Strucutre 4924 * @ioc: Pointer to a Adapter Strucutre
@@ -4737,21 +4928,27 @@ mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4737 * 0 on success 4928 * 0 on success
4738 * -EFAULT if read of config page header fails or data pointer not NULL 4929 * -EFAULT if read of config page header fails or data pointer not NULL
4739 * -ENOMEM if pci_alloc failed 4930 * -ENOMEM if pci_alloc failed
4740 */ 4931 **/
4741int 4932int
4742mpt_findImVolumes(MPT_ADAPTER *ioc) 4933mpt_findImVolumes(MPT_ADAPTER *ioc)
4743{ 4934{
4744 IOCPage2_t *pIoc2; 4935 IOCPage2_t *pIoc2;
4745 u8 *mem; 4936 u8 *mem;
4746 ConfigPageIoc2RaidVol_t *pIocRv;
4747 dma_addr_t ioc2_dma; 4937 dma_addr_t ioc2_dma;
4748 CONFIGPARMS cfg; 4938 CONFIGPARMS cfg;
4749 ConfigPageHeader_t header; 4939 ConfigPageHeader_t header;
4750 int jj;
4751 int rc = 0; 4940 int rc = 0;
4752 int iocpage2sz; 4941 int iocpage2sz;
4753 u8 nVols, nPhys; 4942 int i;
4754 u8 vid, vbus, vioc; 4943
4944 if (!ioc->ir_firmware)
4945 return 0;
4946
4947 /* Free the old page
4948 */
4949 kfree(ioc->raid_data.pIocPg2);
4950 ioc->raid_data.pIocPg2 = NULL;
4951 mpt_inactive_raid_list_free(ioc);
4755 4952
4756 /* Read IOCP2 header then the page. 4953 /* Read IOCP2 header then the page.
4757 */ 4954 */
@@ -4779,55 +4976,23 @@ mpt_findImVolumes(MPT_ADAPTER *ioc)
4779 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4976 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4780 cfg.physAddr = ioc2_dma; 4977 cfg.physAddr = ioc2_dma;
4781 if (mpt_config(ioc, &cfg) != 0) 4978 if (mpt_config(ioc, &cfg) != 0)
4782 goto done_and_free; 4979 goto out;
4980
4981 mem = kmalloc(iocpage2sz, GFP_KERNEL);
4982 if (!mem)
4983 goto out;
4783 4984
4784 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4785 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4786 if (mem) {
4787 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4788 } else {
4789 goto done_and_free;
4790 }
4791 }
4792 memcpy(mem, (u8 *)pIoc2, iocpage2sz); 4985 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4986 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4793 4987
4794 /* Identify RAID Volume Id's */ 4988 mpt_read_ioc_pg_3(ioc);
4795 nVols = pIoc2->NumActiveVolumes;
4796 if ( nVols == 0) {
4797 /* No RAID Volume.
4798 */
4799 goto done_and_free;
4800 } else {
4801 /* At least 1 RAID Volume
4802 */
4803 pIocRv = pIoc2->RaidVolume;
4804 ioc->raid_data.isRaid = 0;
4805 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4806 vid = pIocRv->VolumeID;
4807 vbus = pIocRv->VolumeBus;
4808 vioc = pIocRv->VolumeIOC;
4809
4810 /* find the match
4811 */
4812 if (vbus == 0) {
4813 ioc->raid_data.isRaid |= (1 << vid);
4814 } else {
4815 /* Error! Always bus 0
4816 */
4817 }
4818 }
4819 }
4820 4989
4821 /* Identify Hidden Physical Disk Id's */ 4990 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
4822 nPhys = pIoc2->NumActivePhysDisks; 4991 mpt_inactive_raid_volumes(ioc,
4823 if (nPhys == 0) { 4992 pIoc2->RaidVolume[i].VolumeBus,
4824 /* No physical disks. 4993 pIoc2->RaidVolume[i].VolumeID);
4825 */
4826 } else {
4827 mpt_read_ioc_pg_3(ioc);
4828 }
4829 4994
4830done_and_free: 4995 out:
4831 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); 4996 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4832 4997
4833 return rc; 4998 return rc;
@@ -4880,7 +5045,7 @@ mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4880 cfg.physAddr = ioc3_dma; 5045 cfg.physAddr = ioc3_dma;
4881 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5046 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4882 if (mpt_config(ioc, &cfg) == 0) { 5047 if (mpt_config(ioc, &cfg) == 0) {
4883 mem = kmalloc(iocpage3sz, GFP_ATOMIC); 5048 mem = kmalloc(iocpage3sz, GFP_KERNEL);
4884 if (mem) { 5049 if (mem) {
4885 memcpy(mem, (u8 *)pIoc3, iocpage3sz); 5050 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4886 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; 5051 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
@@ -6833,6 +6998,7 @@ EXPORT_SYMBOL(mpt_findImVolumes);
6833EXPORT_SYMBOL(mpt_alloc_fw_memory); 6998EXPORT_SYMBOL(mpt_alloc_fw_memory);
6834EXPORT_SYMBOL(mpt_free_fw_memory); 6999EXPORT_SYMBOL(mpt_free_fw_memory);
6835EXPORT_SYMBOL(mptbase_sas_persist_operation); 7000EXPORT_SYMBOL(mptbase_sas_persist_operation);
7001EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
6836 7002
6837/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7003/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6838/** 7004/**
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 3d613c4f93d9..07830d28e58d 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -485,10 +485,24 @@ typedef struct _SasCfgData {
485 */ 485 */
486}SasCfgData; 486}SasCfgData;
487 487
488/*
489 * Inactive volume link list of raid component data
490 * @inactive_list
491 */
492struct inactive_raid_component_info {
493 struct list_head list;
494 u8 volumeID; /* volume target id */
495 u8 volumeBus; /* volume channel */
496 IOC_3_PHYS_DISK d; /* phys disk info */
497};
498
488typedef struct _RaidCfgData { 499typedef struct _RaidCfgData {
489 IOCPage2_t *pIocPg2; /* table of Raid Volumes */ 500 IOCPage2_t *pIocPg2; /* table of Raid Volumes */
490 IOCPage3_t *pIocPg3; /* table of physical disks */ 501 IOCPage3_t *pIocPg3; /* table of physical disks */
491 int isRaid; /* bit field, 1 if RAID */ 502 struct semaphore inactive_list_mutex;
503 struct list_head inactive_list; /* link list for physical
504 disk that belong in
505 inactive volumes */
492}RaidCfgData; 506}RaidCfgData;
493 507
494typedef struct _FcCfgData { 508typedef struct _FcCfgData {
@@ -611,6 +625,8 @@ typedef struct _MPT_ADAPTER
611 u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */ 625 u8 persist_reply_frame[MPT_DEFAULT_FRAME_SIZE]; /* persist reply */
612 LANPage0_t lan_cnfg_page0; 626 LANPage0_t lan_cnfg_page0;
613 LANPage1_t lan_cnfg_page1; 627 LANPage1_t lan_cnfg_page1;
628
629 u8 ir_firmware; /* =1 if IR firmware detected */
614 /* 630 /*
615 * Description: errata_flag_1064 631 * Description: errata_flag_1064
616 * If a PCIX read occurs within 1 or 2 cycles after the chip receives 632 * If a PCIX read occurs within 1 or 2 cycles after the chip receives
@@ -1043,6 +1059,7 @@ extern void mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
1043extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 1059extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
1044extern int mpt_findImVolumes(MPT_ADAPTER *ioc); 1060extern int mpt_findImVolumes(MPT_ADAPTER *ioc);
1045extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 1061extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
1062extern int mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk);
1046 1063
1047/* 1064/*
1048 * Public data decl's... 1065 * Public data decl's...
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index f7c5e0d97890..a8df06c422bd 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -94,12 +94,14 @@ static int mptsasTaskCtx = -1;
94static int mptsasInternalCtx = -1; /* Used only for internal commands */ 94static int mptsasInternalCtx = -1; /* Used only for internal commands */
95static int mptsasMgmtCtx = -1; 95static int mptsasMgmtCtx = -1;
96 96
97static void mptsas_hotplug_work(struct work_struct *work);
97 98
98enum mptsas_hotplug_action { 99enum mptsas_hotplug_action {
99 MPTSAS_ADD_DEVICE, 100 MPTSAS_ADD_DEVICE,
100 MPTSAS_DEL_DEVICE, 101 MPTSAS_DEL_DEVICE,
101 MPTSAS_ADD_RAID, 102 MPTSAS_ADD_RAID,
102 MPTSAS_DEL_RAID, 103 MPTSAS_DEL_RAID,
104 MPTSAS_ADD_INACTIVE_VOLUME,
103 MPTSAS_IGNORE_EVENT, 105 MPTSAS_IGNORE_EVENT,
104}; 106};
105 107
@@ -108,14 +110,15 @@ struct mptsas_hotplug_event {
108 MPT_ADAPTER *ioc; 110 MPT_ADAPTER *ioc;
109 enum mptsas_hotplug_action event_type; 111 enum mptsas_hotplug_action event_type;
110 u64 sas_address; 112 u64 sas_address;
111 u32 channel; 113 u8 channel;
112 u32 id; 114 u8 id;
113 u32 device_info; 115 u32 device_info;
114 u16 handle; 116 u16 handle;
115 u16 parent_handle; 117 u16 parent_handle;
116 u8 phy_id; 118 u8 phy_id;
117 u8 phys_disk_num; 119 u8 phys_disk_num_valid; /* hrc (hidden raid component) */
118 u8 phys_disk_num_valid; 120 u8 phys_disk_num; /* hrc - unique index*/
121 u8 hidden_raid_component; /* hrc - don't expose*/
119}; 122};
120 123
121struct mptsas_discovery_event { 124struct mptsas_discovery_event {
@@ -140,6 +143,7 @@ struct mptsas_devinfo {
140 u8 port_id; /* sas physical port this device 143 u8 port_id; /* sas physical port this device
141 is assoc'd with */ 144 is assoc'd with */
142 u8 id; /* logical target id of this device */ 145 u8 id; /* logical target id of this device */
146 u32 phys_disk_num; /* phys disk id, for csmi-ioctls */
143 u8 channel; /* logical bus number of this device */ 147 u8 channel; /* logical bus number of this device */
144 u64 sas_address; /* WWN of this device, 148 u64 sas_address; /* WWN of this device,
145 SATA is assigned by HBA,expander */ 149 SATA is assigned by HBA,expander */
@@ -711,6 +715,7 @@ mptsas_target_alloc(struct scsi_target *starget)
711 channel, id); 715 channel, id);
712 vtarget->tflags |= 716 vtarget->tflags |=
713 MPT_TARGET_FLAGS_RAID_COMPONENT; 717 MPT_TARGET_FLAGS_RAID_COMPONENT;
718 p->phy_info[i].attached.phys_disk_num = id;
714 } 719 }
715 mutex_unlock(&hd->ioc->sas_topology_mutex); 720 mutex_unlock(&hd->ioc->sas_topology_mutex);
716 goto out; 721 goto out;
@@ -1272,6 +1277,7 @@ mptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info,
1272 device_info->phy_id = buffer->PhyNum; 1277 device_info->phy_id = buffer->PhyNum;
1273 device_info->port_id = buffer->PhysicalPort; 1278 device_info->port_id = buffer->PhysicalPort;
1274 device_info->id = buffer->TargetID; 1279 device_info->id = buffer->TargetID;
1280 device_info->phys_disk_num = ~0;
1275 device_info->channel = buffer->Bus; 1281 device_info->channel = buffer->Bus;
1276 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); 1282 memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64));
1277 device_info->sas_address = le64_to_cpu(sas_address); 1283 device_info->sas_address = le64_to_cpu(sas_address);
@@ -1983,6 +1989,8 @@ mptsas_scan_sas_topology(MPT_ADAPTER *ioc)
1983 /* 1989 /*
1984 Reporting RAID volumes. 1990 Reporting RAID volumes.
1985 */ 1991 */
1992 if (!ioc->ir_firmware)
1993 goto out;
1986 if (!ioc->raid_data.pIocPg2) 1994 if (!ioc->raid_data.pIocPg2)
1987 goto out; 1995 goto out;
1988 if (!ioc->raid_data.pIocPg2->NumActiveVolumes) 1996 if (!ioc->raid_data.pIocPg2->NumActiveVolumes)
@@ -2041,12 +2049,37 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2041 mutex_lock(&ioc->sas_topology_mutex); 2049 mutex_lock(&ioc->sas_topology_mutex);
2042 list_for_each_entry(port_info, &ioc->sas_topology, list) { 2050 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2043 for (i = 0; i < port_info->num_phys; i++) { 2051 for (i = 0; i < port_info->num_phys; i++) {
2052 if (!mptsas_is_end_device(
2053 &port_info->phy_info[i].attached))
2054 continue;
2044 if (port_info->phy_info[i].attached.sas_address 2055 if (port_info->phy_info[i].attached.sas_address
2045 != sas_address) 2056 != sas_address)
2046 continue; 2057 continue;
2058 phy_info = &port_info->phy_info[i];
2059 break;
2060 }
2061 }
2062 mutex_unlock(&ioc->sas_topology_mutex);
2063 return phy_info;
2064}
2065
2066static struct mptsas_phyinfo *
2067mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u8 channel, u8 id)
2068{
2069 struct mptsas_portinfo *port_info;
2070 struct mptsas_phyinfo *phy_info = NULL;
2071 int i;
2072
2073 mutex_lock(&ioc->sas_topology_mutex);
2074 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2075 for (i = 0; i < port_info->num_phys; i++) {
2047 if (!mptsas_is_end_device( 2076 if (!mptsas_is_end_device(
2048 &port_info->phy_info[i].attached)) 2077 &port_info->phy_info[i].attached))
2049 continue; 2078 continue;
2079 if (port_info->phy_info[i].attached.id != id)
2080 continue;
2081 if (port_info->phy_info[i].attached.channel != channel)
2082 continue;
2050 phy_info = &port_info->phy_info[i]; 2083 phy_info = &port_info->phy_info[i];
2051 break; 2084 break;
2052 } 2085 }
@@ -2056,7 +2089,7 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address)
2056} 2089}
2057 2090
2058static struct mptsas_phyinfo * 2091static struct mptsas_phyinfo *
2059mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) 2092mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2060{ 2093{
2061 struct mptsas_portinfo *port_info; 2094 struct mptsas_portinfo *port_info;
2062 struct mptsas_phyinfo *phy_info = NULL; 2095 struct mptsas_phyinfo *phy_info = NULL;
@@ -2065,11 +2098,15 @@ mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id)
2065 mutex_lock(&ioc->sas_topology_mutex); 2098 mutex_lock(&ioc->sas_topology_mutex);
2066 list_for_each_entry(port_info, &ioc->sas_topology, list) { 2099 list_for_each_entry(port_info, &ioc->sas_topology, list) {
2067 for (i = 0; i < port_info->num_phys; i++) { 2100 for (i = 0; i < port_info->num_phys; i++) {
2068 if (port_info->phy_info[i].attached.id != id)
2069 continue;
2070 if (!mptsas_is_end_device( 2101 if (!mptsas_is_end_device(
2071 &port_info->phy_info[i].attached)) 2102 &port_info->phy_info[i].attached))
2072 continue; 2103 continue;
2104 if (port_info->phy_info[i].attached.phys_disk_num == ~0)
2105 continue;
2106 if (port_info->phy_info[i].attached.phys_disk_num != id)
2107 continue;
2108 if (port_info->phy_info[i].attached.channel != channel)
2109 continue;
2073 phy_info = &port_info->phy_info[i]; 2110 phy_info = &port_info->phy_info[i];
2074 break; 2111 break;
2075 } 2112 }
@@ -2105,6 +2142,76 @@ mptsas_reprobe_target(struct scsi_target *starget, int uld_attach)
2105 mptsas_reprobe_lun); 2142 mptsas_reprobe_lun);
2106} 2143}
2107 2144
2145static void
2146mptsas_adding_inactive_raid_components(MPT_ADAPTER *ioc, u8 channel, u8 id)
2147{
2148 CONFIGPARMS cfg;
2149 ConfigPageHeader_t hdr;
2150 dma_addr_t dma_handle;
2151 pRaidVolumePage0_t buffer = NULL;
2152 RaidPhysDiskPage0_t phys_disk;
2153 int i;
2154 struct mptsas_hotplug_event *ev;
2155
2156 memset(&cfg, 0 , sizeof(CONFIGPARMS));
2157 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
2158 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
2159 cfg.pageAddr = (channel << 8) + id;
2160 cfg.cfghdr.hdr = &hdr;
2161 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
2162
2163 if (mpt_config(ioc, &cfg) != 0)
2164 goto out;
2165
2166 if (!hdr.PageLength)
2167 goto out;
2168
2169 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
2170 &dma_handle);
2171
2172 if (!buffer)
2173 goto out;
2174
2175 cfg.physAddr = dma_handle;
2176 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
2177
2178 if (mpt_config(ioc, &cfg) != 0)
2179 goto out;
2180
2181 if (!(buffer->VolumeStatus.Flags &
2182 MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE))
2183 goto out;
2184
2185 if (!buffer->NumPhysDisks)
2186 goto out;
2187
2188 for (i = 0; i < buffer->NumPhysDisks; i++) {
2189
2190 if (mpt_raid_phys_disk_pg0(ioc,
2191 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
2192 continue;
2193
2194 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2195 if (!ev) {
2196 printk(KERN_WARNING "mptsas: lost hotplug event\n");
2197 goto out;
2198 }
2199
2200 INIT_WORK(&ev->work, mptsas_hotplug_work);
2201 ev->ioc = ioc;
2202 ev->id = phys_disk.PhysDiskID;
2203 ev->channel = phys_disk.PhysDiskBus;
2204 ev->phys_disk_num_valid = 1;
2205 ev->phys_disk_num = phys_disk.PhysDiskNum;
2206 ev->event_type = MPTSAS_ADD_DEVICE;
2207 schedule_work(&ev->work);
2208 }
2209
2210 out:
2211 if (buffer)
2212 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
2213 dma_handle);
2214}
2108/* 2215/*
2109 * Work queue thread to handle SAS hotplug events 2216 * Work queue thread to handle SAS hotplug events
2110 */ 2217 */
@@ -2113,6 +2220,7 @@ mptsas_hotplug_work(struct work_struct *work)
2113{ 2220{
2114 struct mptsas_hotplug_event *ev = 2221 struct mptsas_hotplug_event *ev =
2115 container_of(work, struct mptsas_hotplug_event, work); 2222 container_of(work, struct mptsas_hotplug_event, work);
2223
2116 MPT_ADAPTER *ioc = ev->ioc; 2224 MPT_ADAPTER *ioc = ev->ioc;
2117 struct mptsas_phyinfo *phy_info; 2225 struct mptsas_phyinfo *phy_info;
2118 struct sas_rphy *rphy; 2226 struct sas_rphy *rphy;
@@ -2125,17 +2233,43 @@ mptsas_hotplug_work(struct work_struct *work)
2125 VirtTarget *vtarget; 2233 VirtTarget *vtarget;
2126 VirtDevice *vdevice; 2234 VirtDevice *vdevice;
2127 2235
2128
2129 mutex_lock(&ioc->sas_discovery_mutex); 2236 mutex_lock(&ioc->sas_discovery_mutex);
2130 switch (ev->event_type) { 2237 switch (ev->event_type) {
2131 case MPTSAS_DEL_DEVICE: 2238 case MPTSAS_DEL_DEVICE:
2132 2239
2133 phy_info = mptsas_find_phyinfo_by_target(ioc, ev->id); 2240 phy_info = NULL;
2241 if (ev->phys_disk_num_valid) {
2242 if (ev->hidden_raid_component){
2243 if (mptsas_sas_device_pg0(ioc, &sas_device,
2244 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2245 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2246 (ev->channel << 8) + ev->id)) {
2247 dfailprintk((MYIOC_s_ERR_FMT
2248 "%s: exit at line=%d\n", ioc->name,
2249 __FUNCTION__, __LINE__));
2250 break;
2251 }
2252 phy_info = mptsas_find_phyinfo_by_sas_address(
2253 ioc, sas_device.sas_address);
2254 }else
2255 phy_info = mptsas_find_phyinfo_by_phys_disk_num(
2256 ioc, ev->channel, ev->phys_disk_num);
2257 }
2258
2259 if (!phy_info)
2260 phy_info = mptsas_find_phyinfo_by_target(ioc,
2261 ev->channel, ev->id);
2134 2262
2135 /* 2263 /*
2136 * Sanity checks, for non-existing phys and remote rphys. 2264 * Sanity checks, for non-existing phys and remote rphys.
2137 */ 2265 */
2138 if (!phy_info || !phy_info->port_details) { 2266 if (!phy_info){
2267 dfailprintk((MYIOC_s_ERR_FMT
2268 "%s: exit at line=%d\n", ioc->name,
2269 __FUNCTION__, __LINE__));
2270 break;
2271 }
2272 if (!phy_info->port_details) {
2139 dfailprintk((MYIOC_s_ERR_FMT 2273 dfailprintk((MYIOC_s_ERR_FMT
2140 "%s: exit at line=%d\n", ioc->name, 2274 "%s: exit at line=%d\n", ioc->name,
2141 __FUNCTION__, __LINE__)); 2275 __FUNCTION__, __LINE__));
@@ -2148,6 +2282,7 @@ mptsas_hotplug_work(struct work_struct *work)
2148 __FUNCTION__, __LINE__)); 2282 __FUNCTION__, __LINE__));
2149 break; 2283 break;
2150 } 2284 }
2285
2151 port = mptsas_get_port(phy_info); 2286 port = mptsas_get_port(phy_info);
2152 if (!port) { 2287 if (!port) {
2153 dfailprintk((MYIOC_s_ERR_FMT 2288 dfailprintk((MYIOC_s_ERR_FMT
@@ -2170,28 +2305,38 @@ mptsas_hotplug_work(struct work_struct *work)
2170 /* 2305 /*
2171 * Handling RAID components 2306 * Handling RAID components
2172 */ 2307 */
2173 if (ev->phys_disk_num_valid) { 2308 if (ev->phys_disk_num_valid &&
2309 ev->hidden_raid_component) {
2310 printk(MYIOC_s_INFO_FMT
2311 "RAID Hidding: channel=%d, id=%d, "
2312 "physdsk %d \n", ioc->name, ev->channel,
2313 ev->id, ev->phys_disk_num);
2174 vtarget->id = ev->phys_disk_num; 2314 vtarget->id = ev->phys_disk_num;
2175 vtarget->tflags |= MPT_TARGET_FLAGS_RAID_COMPONENT; 2315 vtarget->tflags |=
2316 MPT_TARGET_FLAGS_RAID_COMPONENT;
2176 mptsas_reprobe_target(starget, 1); 2317 mptsas_reprobe_target(starget, 1);
2177 break; 2318 phy_info->attached.phys_disk_num =
2319 ev->phys_disk_num;
2320 break;
2178 } 2321 }
2179 2322
2180 vtarget->deleted = 1; 2323 vtarget->deleted = 1;
2181 mptsas_target_reset(ioc, vtarget); 2324 mptsas_target_reset(ioc, vtarget);
2182 } 2325 }
2183 2326
2184 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 2327 if (phy_info->attached.device_info &
2328 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2185 ds = "ssp"; 2329 ds = "ssp";
2186 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) 2330 if (phy_info->attached.device_info &
2331 MPI_SAS_DEVICE_INFO_STP_TARGET)
2187 ds = "stp"; 2332 ds = "stp";
2188 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) 2333 if (phy_info->attached.device_info &
2334 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2189 ds = "sata"; 2335 ds = "sata";
2190 2336
2191 printk(MYIOC_s_INFO_FMT 2337 printk(MYIOC_s_INFO_FMT
2192 "removing %s device, channel %d, id %d, phy %d\n", 2338 "removing %s device, channel %d, id %d, phy %d\n",
2193 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id); 2339 ioc->name, ds, ev->channel, ev->id, phy_info->phy_id);
2194
2195#ifdef MPT_DEBUG_SAS_WIDE 2340#ifdef MPT_DEBUG_SAS_WIDE
2196 dev_printk(KERN_DEBUG, &port->dev, 2341 dev_printk(KERN_DEBUG, &port->dev,
2197 "delete port (%d)\n", port->port_identifier); 2342 "delete port (%d)\n", port->port_identifier);
@@ -2209,14 +2354,14 @@ mptsas_hotplug_work(struct work_struct *work)
2209 */ 2354 */
2210 if (mptsas_sas_device_pg0(ioc, &sas_device, 2355 if (mptsas_sas_device_pg0(ioc, &sas_device,
2211 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID << 2356 (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID <<
2212 MPI_SAS_DEVICE_PGAD_FORM_SHIFT), ev->id)) { 2357 MPI_SAS_DEVICE_PGAD_FORM_SHIFT),
2358 (ev->channel << 8) + ev->id)) {
2213 dfailprintk((MYIOC_s_ERR_FMT 2359 dfailprintk((MYIOC_s_ERR_FMT
2214 "%s: exit at line=%d\n", ioc->name, 2360 "%s: exit at line=%d\n", ioc->name,
2215 __FUNCTION__, __LINE__)); 2361 __FUNCTION__, __LINE__));
2216 break; 2362 break;
2217 } 2363 }
2218 2364
2219 ssleep(2);
2220 __mptsas_discovery_work(ioc); 2365 __mptsas_discovery_work(ioc);
2221 2366
2222 phy_info = mptsas_find_phyinfo_by_sas_address(ioc, 2367 phy_info = mptsas_find_phyinfo_by_sas_address(ioc,
@@ -2230,7 +2375,8 @@ mptsas_hotplug_work(struct work_struct *work)
2230 } 2375 }
2231 2376
2232 starget = mptsas_get_starget(phy_info); 2377 starget = mptsas_get_starget(phy_info);
2233 if (starget) { 2378 if (starget && (!ev->hidden_raid_component)){
2379
2234 vtarget = starget->hostdata; 2380 vtarget = starget->hostdata;
2235 2381
2236 if (!vtarget) { 2382 if (!vtarget) {
@@ -2243,9 +2389,15 @@ mptsas_hotplug_work(struct work_struct *work)
2243 * Handling RAID components 2389 * Handling RAID components
2244 */ 2390 */
2245 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) { 2391 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
2246 vtarget->tflags &= ~MPT_TARGET_FLAGS_RAID_COMPONENT; 2392 printk(MYIOC_s_INFO_FMT
2393 "RAID Exposing: channel=%d, id=%d, "
2394 "physdsk %d \n", ioc->name, ev->channel,
2395 ev->id, ev->phys_disk_num);
2396 vtarget->tflags &=
2397 ~MPT_TARGET_FLAGS_RAID_COMPONENT;
2247 vtarget->id = ev->id; 2398 vtarget->id = ev->id;
2248 mptsas_reprobe_target(starget, 0); 2399 mptsas_reprobe_target(starget, 0);
2400 phy_info->attached.phys_disk_num = ~0;
2249 } 2401 }
2250 break; 2402 break;
2251 } 2403 }
@@ -2254,8 +2406,10 @@ mptsas_hotplug_work(struct work_struct *work)
2254 dfailprintk((MYIOC_s_ERR_FMT 2406 dfailprintk((MYIOC_s_ERR_FMT
2255 "%s: exit at line=%d\n", ioc->name, 2407 "%s: exit at line=%d\n", ioc->name,
2256 __FUNCTION__, __LINE__)); 2408 __FUNCTION__, __LINE__));
2409 if (ev->channel) printk("%d\n", __LINE__);
2257 break; 2410 break;
2258 } 2411 }
2412
2259 port = mptsas_get_port(phy_info); 2413 port = mptsas_get_port(phy_info);
2260 if (!port) { 2414 if (!port) {
2261 dfailprintk((MYIOC_s_ERR_FMT 2415 dfailprintk((MYIOC_s_ERR_FMT
@@ -2263,15 +2417,17 @@ mptsas_hotplug_work(struct work_struct *work)
2263 __FUNCTION__, __LINE__)); 2417 __FUNCTION__, __LINE__));
2264 break; 2418 break;
2265 } 2419 }
2266
2267 memcpy(&phy_info->attached, &sas_device, 2420 memcpy(&phy_info->attached, &sas_device,
2268 sizeof(struct mptsas_devinfo)); 2421 sizeof(struct mptsas_devinfo));
2269 2422
2270 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) 2423 if (phy_info->attached.device_info &
2424 MPI_SAS_DEVICE_INFO_SSP_TARGET)
2271 ds = "ssp"; 2425 ds = "ssp";
2272 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) 2426 if (phy_info->attached.device_info &
2427 MPI_SAS_DEVICE_INFO_STP_TARGET)
2273 ds = "stp"; 2428 ds = "stp";
2274 if (phy_info->attached.device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE) 2429 if (phy_info->attached.device_info &
2430 MPI_SAS_DEVICE_INFO_SATA_DEVICE)
2275 ds = "sata"; 2431 ds = "sata";
2276 2432
2277 printk(MYIOC_s_INFO_FMT 2433 printk(MYIOC_s_INFO_FMT
@@ -2312,19 +2468,23 @@ mptsas_hotplug_work(struct work_struct *work)
2312 break; 2468 break;
2313 case MPTSAS_DEL_RAID: 2469 case MPTSAS_DEL_RAID:
2314 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, 2470 sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL,
2315 ev->id, 0); 2471 ev->id, 0);
2316 if (!sdev) 2472 if (!sdev)
2317 break; 2473 break;
2318 printk(MYIOC_s_INFO_FMT 2474 printk(MYIOC_s_INFO_FMT
2319 "removing raid volume, channel %d, id %d\n", 2475 "removing raid volume, channel %d, id %d\n",
2320 ioc->name, MPTSAS_RAID_CHANNEL, ev->id); 2476 ioc->name, MPTSAS_RAID_CHANNEL, ev->id);
2321 vdevice = sdev->hostdata;
2322 vdevice->vtarget->deleted = 1; 2477 vdevice->vtarget->deleted = 1;
2323 mptsas_target_reset(ioc, vdevice->vtarget); 2478 mptsas_target_reset(ioc, vdevice->vtarget);
2479 vdevice = sdev->hostdata;
2324 scsi_remove_device(sdev); 2480 scsi_remove_device(sdev);
2325 scsi_device_put(sdev); 2481 scsi_device_put(sdev);
2326 mpt_findImVolumes(ioc); 2482 mpt_findImVolumes(ioc);
2327 break; 2483 break;
2484 case MPTSAS_ADD_INACTIVE_VOLUME:
2485 mptsas_adding_inactive_raid_components(ioc,
2486 ev->channel, ev->id);
2487 break;
2328 case MPTSAS_IGNORE_EVENT: 2488 case MPTSAS_IGNORE_EVENT:
2329 default: 2489 default:
2330 break; 2490 break;
@@ -2332,7 +2492,6 @@ mptsas_hotplug_work(struct work_struct *work)
2332 2492
2333 mutex_unlock(&ioc->sas_discovery_mutex); 2493 mutex_unlock(&ioc->sas_discovery_mutex);
2334 kfree(ev); 2494 kfree(ev);
2335
2336} 2495}
2337 2496
2338static void 2497static void
@@ -2386,15 +2545,20 @@ mptsas_send_sas_event(MPT_ADAPTER *ioc,
2386 mptsas_persist_clear_table); 2545 mptsas_persist_clear_table);
2387 schedule_work(&ioc->sas_persist_task); 2546 schedule_work(&ioc->sas_persist_task);
2388 break; 2547 break;
2548 /*
2549 * TODO, handle other events
2550 */
2389 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 2551 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
2390 /* TODO */ 2552 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
2391 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 2553 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
2392 /* TODO */ 2554 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
2555 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
2556 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
2557 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
2393 default: 2558 default:
2394 break; 2559 break;
2395 } 2560 }
2396} 2561}
2397
2398static void 2562static void
2399mptsas_send_raid_event(MPT_ADAPTER *ioc, 2563mptsas_send_raid_event(MPT_ADAPTER *ioc,
2400 EVENT_DATA_RAID *raid_event_data) 2564 EVENT_DATA_RAID *raid_event_data)
@@ -2415,31 +2579,36 @@ mptsas_send_raid_event(MPT_ADAPTER *ioc,
2415 INIT_WORK(&ev->work, mptsas_hotplug_work); 2579 INIT_WORK(&ev->work, mptsas_hotplug_work);
2416 ev->ioc = ioc; 2580 ev->ioc = ioc;
2417 ev->id = raid_event_data->VolumeID; 2581 ev->id = raid_event_data->VolumeID;
2582 ev->channel = raid_event_data->VolumeBus;
2418 ev->event_type = MPTSAS_IGNORE_EVENT; 2583 ev->event_type = MPTSAS_IGNORE_EVENT;
2419 2584
2420 switch (raid_event_data->ReasonCode) { 2585 switch (raid_event_data->ReasonCode) {
2421 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: 2586 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
2587 ev->phys_disk_num_valid = 1;
2588 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2422 ev->event_type = MPTSAS_ADD_DEVICE; 2589 ev->event_type = MPTSAS_ADD_DEVICE;
2423 break; 2590 break;
2424 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 2591 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
2425 ioc->raid_data.isRaid = 1;
2426 ev->phys_disk_num_valid = 1; 2592 ev->phys_disk_num_valid = 1;
2427 ev->phys_disk_num = raid_event_data->PhysDiskNum; 2593 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2594 ev->hidden_raid_component = 1;
2428 ev->event_type = MPTSAS_DEL_DEVICE; 2595 ev->event_type = MPTSAS_DEL_DEVICE;
2429 break; 2596 break;
2430 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: 2597 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
2431 switch (state) { 2598 switch (state) {
2432 case MPI_PD_STATE_ONLINE: 2599 case MPI_PD_STATE_ONLINE:
2433 ioc->raid_data.isRaid = 1; 2600 case MPI_PD_STATE_NOT_COMPATIBLE:
2434 ev->phys_disk_num_valid = 1; 2601 ev->phys_disk_num_valid = 1;
2435 ev->phys_disk_num = raid_event_data->PhysDiskNum; 2602 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2603 ev->hidden_raid_component = 1;
2436 ev->event_type = MPTSAS_ADD_DEVICE; 2604 ev->event_type = MPTSAS_ADD_DEVICE;
2437 break; 2605 break;
2438 case MPI_PD_STATE_MISSING: 2606 case MPI_PD_STATE_MISSING:
2439 case MPI_PD_STATE_NOT_COMPATIBLE:
2440 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST: 2607 case MPI_PD_STATE_OFFLINE_AT_HOST_REQUEST:
2441 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST: 2608 case MPI_PD_STATE_FAILED_AT_HOST_REQUEST:
2442 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON: 2609 case MPI_PD_STATE_OFFLINE_FOR_ANOTHER_REASON:
2610 ev->phys_disk_num_valid = 1;
2611 ev->phys_disk_num = raid_event_data->PhysDiskNum;
2443 ev->event_type = MPTSAS_DEL_DEVICE; 2612 ev->event_type = MPTSAS_DEL_DEVICE;
2444 break; 2613 break;
2445 default: 2614 default:
@@ -2496,6 +2665,35 @@ mptsas_send_discovery_event(MPT_ADAPTER *ioc,
2496 schedule_work(&ev->work); 2665 schedule_work(&ev->work);
2497}; 2666};
2498 2667
2668/*
2669 * mptsas_send_ir2_event - handle exposing hidden disk when
2670 * an inactive raid volume is added
2671 *
2672 * @ioc: Pointer to MPT_ADAPTER structure
2673 * @ir2_data
2674 *
2675 */
2676static void
2677mptsas_send_ir2_event(MPT_ADAPTER *ioc, PTR_MPI_EVENT_DATA_IR2 ir2_data)
2678{
2679 struct mptsas_hotplug_event *ev;
2680
2681 if (ir2_data->ReasonCode !=
2682 MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED)
2683 return;
2684
2685 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
2686 if (!ev)
2687 return;
2688
2689 INIT_WORK(&ev->work, mptsas_hotplug_work);
2690 ev->ioc = ioc;
2691 ev->id = ir2_data->TargetID;
2692 ev->channel = ir2_data->Bus;
2693 ev->event_type = MPTSAS_ADD_INACTIVE_VOLUME;
2694
2695 schedule_work(&ev->work);
2696};
2499 2697
2500static int 2698static int
2501mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) 2699mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
@@ -2535,6 +2733,10 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply)
2535 mptsas_send_discovery_event(ioc, 2733 mptsas_send_discovery_event(ioc,
2536 (EVENT_DATA_SAS_DISCOVERY *)reply->Data); 2734 (EVENT_DATA_SAS_DISCOVERY *)reply->Data);
2537 break; 2735 break;
2736 case MPI_EVENT_IR2:
2737 mptsas_send_ir2_event(ioc,
2738 (PTR_MPI_EVENT_DATA_IR2)reply->Data);
2739 break;
2538 default: 2740 default:
2539 rc = mptscsih_event_process(ioc, reply); 2741 rc = mptscsih_event_process(ioc, reply);
2540 break; 2742 break;
@@ -2742,7 +2944,7 @@ static void __devexit mptsas_remove(struct pci_dev *pdev)
2742 struct mptsas_portinfo *p, *n; 2944 struct mptsas_portinfo *p, *n;
2743 int i; 2945 int i;
2744 2946
2745 ioc->sas_discovery_ignore_events=1; 2947 ioc->sas_discovery_ignore_events = 1;
2746 sas_remove_host(ioc->sh); 2948 sas_remove_host(ioc->sh);
2747 2949
2748 mutex_lock(&ioc->sas_topology_mutex); 2950 mutex_lock(&ioc->sas_topology_mutex);
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 507aa08611d5..f9e11c8db462 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2244,6 +2244,7 @@ mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2244int 2244int
2245mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id) 2245mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2246{ 2246{
2247 struct inactive_raid_component_info *component_info;
2247 int i; 2248 int i;
2248 int rc = 0; 2249 int rc = 0;
2249 2250
@@ -2257,6 +2258,21 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2257 } 2258 }
2258 } 2259 }
2259 2260
2261 /*
2262 * Check inactive list for matching phys disks
2263 */
2264 if (list_empty(&ioc->raid_data.inactive_list))
2265 goto out;
2266
2267 down(&ioc->raid_data.inactive_list_mutex);
2268 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2269 list) {
2270 if ((component_info->d.PhysDiskID == id) &&
2271 (component_info->d.PhysDiskBus == channel))
2272 rc = 1;
2273 }
2274 up(&ioc->raid_data.inactive_list_mutex);
2275
2260 out: 2276 out:
2261 return rc; 2277 return rc;
2262} 2278}
@@ -2265,6 +2281,7 @@ EXPORT_SYMBOL(mptscsih_is_phys_disk);
2265u8 2281u8
2266mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) 2282mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2267{ 2283{
2284 struct inactive_raid_component_info *component_info;
2268 int i; 2285 int i;
2269 int rc = -ENXIO; 2286 int rc = -ENXIO;
2270 2287
@@ -2278,6 +2295,21 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2278 } 2295 }
2279 } 2296 }
2280 2297
2298 /*
2299 * Check inactive list for matching phys disks
2300 */
2301 if (list_empty(&ioc->raid_data.inactive_list))
2302 goto out;
2303
2304 down(&ioc->raid_data.inactive_list_mutex);
2305 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2306 list) {
2307 if ((component_info->d.PhysDiskID == id) &&
2308 (component_info->d.PhysDiskBus == channel))
2309 rc = component_info->d.PhysDiskNum;
2310 }
2311 up(&ioc->raid_data.inactive_list_mutex);
2312
2281 out: 2313 out:
2282 return rc; 2314 return rc;
2283} 2315}
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 06a7b86f5f23..5398aeab191d 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -1363,8 +1363,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1363 /* 1363 /*
1364 * If RAID Firmware Detected, setup virtual channel 1364 * If RAID Firmware Detected, setup virtual channel
1365 */ 1365 */
1366 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 1366 if (ioc->ir_firmware)
1367 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
1368 sh->max_channel = 1; 1367 sh->max_channel = 1;
1369 else 1368 else
1370 sh->max_channel = 0; 1369 sh->max_channel = 0;