aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/cio/device.c109
1 files changed, 62 insertions, 47 deletions
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index e322111fb369..c3fc205e3bc0 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -413,11 +413,60 @@ ccw_device_set_online(struct ccw_device *cdev)
413 return (ret == 0) ? -ENODEV : ret; 413 return (ret == 0) ? -ENODEV : ret;
414} 414}
415 415
416static ssize_t 416static void online_store_handle_offline(struct ccw_device *cdev)
417online_store (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 417{
418 if (cdev->private->state == DEV_STATE_DISCONNECTED)
419 ccw_device_remove_disconnected(cdev);
420 else if (cdev->drv && cdev->drv->set_offline)
421 ccw_device_set_offline(cdev);
422}
423
424static int online_store_recog_and_online(struct ccw_device *cdev)
425{
426 int ret;
427
428 /* Do device recognition, if needed. */
429 if (cdev->id.cu_type == 0) {
430 ret = ccw_device_recognition(cdev);
431 if (ret) {
432 printk(KERN_WARNING"Couldn't start recognition "
433 "for device %s (ret=%d)\n",
434 cdev->dev.bus_id, ret);
435 return ret;
436 }
437 wait_event(cdev->private->wait_q,
438 cdev->private->flags.recog_done);
439 }
440 if (cdev->drv && cdev->drv->set_online)
441 ccw_device_set_online(cdev);
442 return 0;
443}
444static void online_store_handle_online(struct ccw_device *cdev, int force)
445{
446 int ret;
447
448 ret = online_store_recog_and_online(cdev);
449 if (ret)
450 return;
451 if (force && cdev->private->state == DEV_STATE_BOXED) {
452 ret = ccw_device_stlck(cdev);
453 if (ret) {
454 printk(KERN_WARNING"ccw_device_stlck for device %s "
455 "returned %d!\n", cdev->dev.bus_id, ret);
456 return;
457 }
458 if (cdev->id.cu_type == 0)
459 cdev->private->state = DEV_STATE_NOT_OPER;
460 online_store_recog_and_online(cdev);
461 }
462
463}
464
465static ssize_t online_store (struct device *dev, struct device_attribute *attr,
466 const char *buf, size_t count)
418{ 467{
419 struct ccw_device *cdev = to_ccwdev(dev); 468 struct ccw_device *cdev = to_ccwdev(dev);
420 int i, force, ret; 469 int i, force;
421 char *tmp; 470 char *tmp;
422 471
423 if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) 472 if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
@@ -434,51 +483,17 @@ online_store (struct device *dev, struct device_attribute *attr, const char *buf
434 force = 0; 483 force = 0;
435 i = simple_strtoul(buf, &tmp, 16); 484 i = simple_strtoul(buf, &tmp, 16);
436 } 485 }
437 if (i == 1) { 486
438 /* Do device recognition, if needed. */ 487 switch (i) {
439 if (cdev->id.cu_type == 0) { 488 case 0:
440 ret = ccw_device_recognition(cdev); 489 online_store_handle_offline(cdev);
441 if (ret) { 490 break;
442 printk(KERN_WARNING"Couldn't start recognition " 491 case 1:
443 "for device %s (ret=%d)\n", 492 online_store_handle_online(cdev, force);
444 cdev->dev.bus_id, ret); 493 break;
445 goto out; 494 default:
446 } 495 count = -EINVAL;
447 wait_event(cdev->private->wait_q,
448 cdev->private->flags.recog_done);
449 }
450 if (cdev->drv && cdev->drv->set_online)
451 ccw_device_set_online(cdev);
452 } else if (i == 0) {
453 if (cdev->private->state == DEV_STATE_DISCONNECTED)
454 ccw_device_remove_disconnected(cdev);
455 else if (cdev->drv && cdev->drv->set_offline)
456 ccw_device_set_offline(cdev);
457 }
458 if (force && cdev->private->state == DEV_STATE_BOXED) {
459 ret = ccw_device_stlck(cdev);
460 if (ret) {
461 printk(KERN_WARNING"ccw_device_stlck for device %s "
462 "returned %d!\n", cdev->dev.bus_id, ret);
463 goto out;
464 }
465 /* Do device recognition, if needed. */
466 if (cdev->id.cu_type == 0) {
467 cdev->private->state = DEV_STATE_NOT_OPER;
468 ret = ccw_device_recognition(cdev);
469 if (ret) {
470 printk(KERN_WARNING"Couldn't start recognition "
471 "for device %s (ret=%d)\n",
472 cdev->dev.bus_id, ret);
473 goto out;
474 }
475 wait_event(cdev->private->wait_q,
476 cdev->private->flags.recog_done);
477 }
478 if (cdev->drv && cdev->drv->set_online)
479 ccw_device_set_online(cdev);
480 } 496 }
481 out:
482 if (cdev->drv) 497 if (cdev->drv)
483 module_put(cdev->drv->owner); 498 module_put(cdev->drv->owner);
484 atomic_set(&cdev->private->onoff, 0); 499 atomic_set(&cdev->private->onoff, 0);