diff options
author | Eric Moore <eric.moore@lsi.com> | 2007-01-29 11:45:37 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-02-02 22:01:28 -0500 |
commit | b506ade9f3c309ac2ce3ffc4039f731097506038 (patch) | |
tree | 26ffb22dd5859977e92ca57f01033da69a6265f5 /drivers/message/fusion/mptsas.c | |
parent | c6c727a1a0ff90c80425b7226557b2354e00cf7b (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.c | 272 |
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; | |||
94 | static int mptsasInternalCtx = -1; /* Used only for internal commands */ | 94 | static int mptsasInternalCtx = -1; /* Used only for internal commands */ |
95 | static int mptsasMgmtCtx = -1; | 95 | static int mptsasMgmtCtx = -1; |
96 | 96 | ||
97 | static void mptsas_hotplug_work(struct work_struct *work); | ||
97 | 98 | ||
98 | enum mptsas_hotplug_action { | 99 | enum 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 | ||
121 | struct mptsas_discovery_event { | 124 | struct 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 | |||
2066 | static struct mptsas_phyinfo * | ||
2067 | mptsas_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 | ||
2058 | static struct mptsas_phyinfo * | 2091 | static struct mptsas_phyinfo * |
2059 | mptsas_find_phyinfo_by_target(MPT_ADAPTER *ioc, u32 id) | 2092 | mptsas_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 | ||
2145 | static void | ||
2146 | mptsas_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 | ||
2338 | static void | 2497 | static 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 | |||
2398 | static void | 2562 | static void |
2399 | mptsas_send_raid_event(MPT_ADAPTER *ioc, | 2563 | mptsas_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 | */ | ||
2676 | static void | ||
2677 | mptsas_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 | ||
2500 | static int | 2698 | static int |
2501 | mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | 2699 | mptsas_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); |