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); |
