diff options
| -rw-r--r-- | drivers/s390/char/tape_core.c | 68 |
1 files changed, 59 insertions, 9 deletions
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index 6c408670e08d..b3a3e8e8656e 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
| @@ -209,29 +209,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate) | |||
| 209 | wake_up(&device->state_change_wq); | 209 | wake_up(&device->state_change_wq); |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | struct tape_med_state_work_data { | ||
| 213 | struct tape_device *device; | ||
| 214 | enum tape_medium_state state; | ||
| 215 | struct work_struct work; | ||
| 216 | }; | ||
| 217 | |||
| 218 | static void | ||
| 219 | tape_med_state_work_handler(struct work_struct *work) | ||
| 220 | { | ||
| 221 | static char env_state_loaded[] = "MEDIUM_STATE=LOADED"; | ||
| 222 | static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED"; | ||
| 223 | struct tape_med_state_work_data *p = | ||
| 224 | container_of(work, struct tape_med_state_work_data, work); | ||
| 225 | struct tape_device *device = p->device; | ||
| 226 | char *envp[] = { NULL, NULL }; | ||
| 227 | |||
| 228 | switch (p->state) { | ||
| 229 | case MS_UNLOADED: | ||
| 230 | pr_info("%s: The tape cartridge has been successfully " | ||
| 231 | "unloaded\n", dev_name(&device->cdev->dev)); | ||
| 232 | envp[0] = env_state_unloaded; | ||
| 233 | kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp); | ||
| 234 | break; | ||
| 235 | case MS_LOADED: | ||
| 236 | pr_info("%s: A tape cartridge has been mounted\n", | ||
| 237 | dev_name(&device->cdev->dev)); | ||
| 238 | envp[0] = env_state_loaded; | ||
| 239 | kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp); | ||
| 240 | break; | ||
| 241 | default: | ||
| 242 | break; | ||
| 243 | } | ||
| 244 | tape_put_device(device); | ||
| 245 | kfree(p); | ||
| 246 | } | ||
| 247 | |||
| 248 | static void | ||
| 249 | tape_med_state_work(struct tape_device *device, enum tape_medium_state state) | ||
| 250 | { | ||
| 251 | struct tape_med_state_work_data *p; | ||
| 252 | |||
| 253 | p = kzalloc(sizeof(*p), GFP_ATOMIC); | ||
| 254 | if (p) { | ||
| 255 | INIT_WORK(&p->work, tape_med_state_work_handler); | ||
| 256 | p->device = tape_get_device(device); | ||
| 257 | p->state = state; | ||
| 258 | schedule_work(&p->work); | ||
| 259 | } | ||
| 260 | } | ||
| 261 | |||
| 212 | void | 262 | void |
| 213 | tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate) | 263 | tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate) |
| 214 | { | 264 | { |
| 215 | if (device->medium_state == newstate) | 265 | enum tape_medium_state oldstate; |
| 266 | |||
| 267 | oldstate = device->medium_state; | ||
| 268 | if (oldstate == newstate) | ||
| 216 | return; | 269 | return; |
| 270 | device->medium_state = newstate; | ||
| 217 | switch(newstate){ | 271 | switch(newstate){ |
| 218 | case MS_UNLOADED: | 272 | case MS_UNLOADED: |
| 219 | device->tape_generic_status |= GMT_DR_OPEN(~0); | 273 | device->tape_generic_status |= GMT_DR_OPEN(~0); |
| 220 | if (device->medium_state == MS_LOADED) | 274 | if (oldstate == MS_LOADED) |
| 221 | pr_info("%s: The tape cartridge has been successfully " | 275 | tape_med_state_work(device, MS_UNLOADED); |
| 222 | "unloaded\n", dev_name(&device->cdev->dev)); | ||
| 223 | break; | 276 | break; |
| 224 | case MS_LOADED: | 277 | case MS_LOADED: |
| 225 | device->tape_generic_status &= ~GMT_DR_OPEN(~0); | 278 | device->tape_generic_status &= ~GMT_DR_OPEN(~0); |
| 226 | if (device->medium_state == MS_UNLOADED) | 279 | if (oldstate == MS_UNLOADED) |
| 227 | pr_info("%s: A tape cartridge has been mounted\n", | 280 | tape_med_state_work(device, MS_LOADED); |
| 228 | dev_name(&device->cdev->dev)); | ||
| 229 | break; | 281 | break; |
| 230 | default: | 282 | default: |
| 231 | // print nothing | ||
| 232 | break; | 283 | break; |
| 233 | } | 284 | } |
| 234 | device->medium_state = newstate; | ||
| 235 | wake_up(&device->state_change_wq); | 285 | wake_up(&device->state_change_wq); |
| 236 | } | 286 | } |
| 237 | 287 | ||
