diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2010-11-10 04:05:52 -0500 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-11-10 04:05:54 -0500 |
commit | 3b210e7652a0ac638b1a267b6a181c8f742d8462 (patch) | |
tree | 2087121208ca42ecc20726f0ba2e94359c30d1d7 /drivers/s390 | |
parent | 25591b07033663e09f5e60355fc5ec4d4aa53e63 (diff) |
[S390] tape: add medium state notifications
Add uevent notifications for tape cartridge load and tape
cartridge unload events.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-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 | ||