aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptsas.c
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/mptsas.c
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/mptsas.c')
-rw-r--r--drivers/message/fusion/mptsas.c272
1 files changed, 237 insertions, 35 deletions
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);