aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2009-05-29 07:23:56 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-06-09 18:44:11 -0400
commita7938b0bb3b458fe0723608be3db6c4ed8d79a8c (patch)
tree6654a67ee51d52e1447ed970801b2fb9106f3867 /drivers/message/fusion/mptscsih.c
parent71278192a887d7da3e768809c6fe9979d172ff23 (diff)
[SCSI] mpt fusion: RAID device handling and Dual port Raid support is added
1. Handle integrated Raid device(Add/Delete) and error condition and check related to Raid device. is_logical_volume will represent logical volume device. 2. Raid device dual port support is added. Main functions to support this feature are mpt_raid_phys_disk_get_num_paths and mpt_raid_phys_disk_pg1. Signed-off-by: Kashyap Desai <kadesai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c85
1 files changed, 83 insertions, 2 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 6424dcbd5908..cf1aba18a09f 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2087,8 +2087,10 @@ int
2087mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id) 2087mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2088{ 2088{
2089 struct inactive_raid_component_info *component_info; 2089 struct inactive_raid_component_info *component_info;
2090 int i; 2090 int i, j;
2091 RaidPhysDiskPage1_t *phys_disk;
2091 int rc = 0; 2092 int rc = 0;
2093 int num_paths;
2092 2094
2093 if (!ioc->raid_data.pIocPg3) 2095 if (!ioc->raid_data.pIocPg3)
2094 goto out; 2096 goto out;
@@ -2100,6 +2102,45 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2100 } 2102 }
2101 } 2103 }
2102 2104
2105 if (ioc->bus_type != SAS)
2106 goto out;
2107
2108 /*
2109 * Check if dual path
2110 */
2111 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2112 num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2113 ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2114 if (num_paths < 2)
2115 continue;
2116 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2117 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2118 if (!phys_disk)
2119 continue;
2120 if ((mpt_raid_phys_disk_pg1(ioc,
2121 ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2122 phys_disk))) {
2123 kfree(phys_disk);
2124 continue;
2125 }
2126 for (j = 0; j < num_paths; j++) {
2127 if ((phys_disk->Path[j].Flags &
2128 MPI_RAID_PHYSDISK1_FLAG_INVALID))
2129 continue;
2130 if ((phys_disk->Path[j].Flags &
2131 MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2132 continue;
2133 if ((id == phys_disk->Path[j].PhysDiskID) &&
2134 (channel == phys_disk->Path[j].PhysDiskBus)) {
2135 rc = 1;
2136 kfree(phys_disk);
2137 goto out;
2138 }
2139 }
2140 kfree(phys_disk);
2141 }
2142
2143
2103 /* 2144 /*
2104 * Check inactive list for matching phys disks 2145 * Check inactive list for matching phys disks
2105 */ 2146 */
@@ -2124,8 +2165,10 @@ u8
2124mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id) 2165mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2125{ 2166{
2126 struct inactive_raid_component_info *component_info; 2167 struct inactive_raid_component_info *component_info;
2127 int i; 2168 int i, j;
2169 RaidPhysDiskPage1_t *phys_disk;
2128 int rc = -ENXIO; 2170 int rc = -ENXIO;
2171 int num_paths;
2129 2172
2130 if (!ioc->raid_data.pIocPg3) 2173 if (!ioc->raid_data.pIocPg3)
2131 goto out; 2174 goto out;
@@ -2137,6 +2180,44 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2137 } 2180 }
2138 } 2181 }
2139 2182
2183 if (ioc->bus_type != SAS)
2184 goto out;
2185
2186 /*
2187 * Check if dual path
2188 */
2189 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2190 num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
2191 ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
2192 if (num_paths < 2)
2193 continue;
2194 phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
2195 (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
2196 if (!phys_disk)
2197 continue;
2198 if ((mpt_raid_phys_disk_pg1(ioc,
2199 ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
2200 phys_disk))) {
2201 kfree(phys_disk);
2202 continue;
2203 }
2204 for (j = 0; j < num_paths; j++) {
2205 if ((phys_disk->Path[j].Flags &
2206 MPI_RAID_PHYSDISK1_FLAG_INVALID))
2207 continue;
2208 if ((phys_disk->Path[j].Flags &
2209 MPI_RAID_PHYSDISK1_FLAG_BROKEN))
2210 continue;
2211 if ((id == phys_disk->Path[j].PhysDiskID) &&
2212 (channel == phys_disk->Path[j].PhysDiskBus)) {
2213 rc = phys_disk->PhysDiskNum;
2214 kfree(phys_disk);
2215 goto out;
2216 }
2217 }
2218 kfree(phys_disk);
2219 }
2220
2140 /* 2221 /*
2141 * Check inactive list for matching phys disks 2222 * Check inactive list for matching phys disks
2142 */ 2223 */