diff options
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/ipr.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 1d440f2763ca..eae61d994b90 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
@@ -2180,6 +2180,74 @@ static struct class_device_attribute ipr_diagnostics_attr = { | |||
2180 | }; | 2180 | }; |
2181 | 2181 | ||
2182 | /** | 2182 | /** |
2183 | * ipr_show_adapter_state - Show the adapter's state | ||
2184 | * @class_dev: class device struct | ||
2185 | * @buf: buffer | ||
2186 | * | ||
2187 | * Return value: | ||
2188 | * number of bytes printed to buffer | ||
2189 | **/ | ||
2190 | static ssize_t ipr_show_adapter_state(struct class_device *class_dev, char *buf) | ||
2191 | { | ||
2192 | struct Scsi_Host *shost = class_to_shost(class_dev); | ||
2193 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; | ||
2194 | unsigned long lock_flags = 0; | ||
2195 | int len; | ||
2196 | |||
2197 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
2198 | if (ioa_cfg->ioa_is_dead) | ||
2199 | len = snprintf(buf, PAGE_SIZE, "offline\n"); | ||
2200 | else | ||
2201 | len = snprintf(buf, PAGE_SIZE, "online\n"); | ||
2202 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2203 | return len; | ||
2204 | } | ||
2205 | |||
2206 | /** | ||
2207 | * ipr_store_adapter_state - Change adapter state | ||
2208 | * @class_dev: class_device struct | ||
2209 | * @buf: buffer | ||
2210 | * @count: buffer size | ||
2211 | * | ||
2212 | * This function will change the adapter's state. | ||
2213 | * | ||
2214 | * Return value: | ||
2215 | * count on success / other on failure | ||
2216 | **/ | ||
2217 | static ssize_t ipr_store_adapter_state(struct class_device *class_dev, | ||
2218 | const char *buf, size_t count) | ||
2219 | { | ||
2220 | struct Scsi_Host *shost = class_to_shost(class_dev); | ||
2221 | struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; | ||
2222 | unsigned long lock_flags; | ||
2223 | int result = count; | ||
2224 | |||
2225 | if (!capable(CAP_SYS_ADMIN)) | ||
2226 | return -EACCES; | ||
2227 | |||
2228 | spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); | ||
2229 | if (ioa_cfg->ioa_is_dead && !strncmp(buf, "online", 6)) { | ||
2230 | ioa_cfg->ioa_is_dead = 0; | ||
2231 | ioa_cfg->reset_retries = 0; | ||
2232 | ioa_cfg->in_ioa_bringdown = 0; | ||
2233 | ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); | ||
2234 | } | ||
2235 | spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); | ||
2236 | wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); | ||
2237 | |||
2238 | return result; | ||
2239 | } | ||
2240 | |||
2241 | static struct class_device_attribute ipr_ioa_state_attr = { | ||
2242 | .attr = { | ||
2243 | .name = "state", | ||
2244 | .mode = S_IRUGO | S_IWUSR, | ||
2245 | }, | ||
2246 | .show = ipr_show_adapter_state, | ||
2247 | .store = ipr_store_adapter_state | ||
2248 | }; | ||
2249 | |||
2250 | /** | ||
2183 | * ipr_store_reset_adapter - Reset the adapter | 2251 | * ipr_store_reset_adapter - Reset the adapter |
2184 | * @class_dev: class_device struct | 2252 | * @class_dev: class_device struct |
2185 | * @buf: buffer | 2253 | * @buf: buffer |
@@ -2515,6 +2583,7 @@ static struct class_device_attribute *ipr_ioa_attrs[] = { | |||
2515 | &ipr_fw_version_attr, | 2583 | &ipr_fw_version_attr, |
2516 | &ipr_log_level_attr, | 2584 | &ipr_log_level_attr, |
2517 | &ipr_diagnostics_attr, | 2585 | &ipr_diagnostics_attr, |
2586 | &ipr_ioa_state_attr, | ||
2518 | &ipr_ioa_reset_attr, | 2587 | &ipr_ioa_reset_attr, |
2519 | &ipr_update_fw_attr, | 2588 | &ipr_update_fw_attr, |
2520 | &ipr_ioa_cache_attr, | 2589 | &ipr_ioa_cache_attr, |