diff options
Diffstat (limited to 'drivers/s390/block')
-rw-r--r-- | drivers/s390/block/dasd.c | 8 | ||||
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 82 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eer.c | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 1 | ||||
-rw-r--r-- | drivers/s390/block/xpram.c | 2 |
5 files changed, 61 insertions, 34 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 25c1ef6dfd44..d0647d116eaa 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -184,7 +184,7 @@ dasd_state_known_to_basic(struct dasd_device * device) | |||
184 | device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2, | 184 | device->debug_area = debug_register(device->cdev->dev.bus_id, 1, 2, |
185 | 8 * sizeof (long)); | 185 | 8 * sizeof (long)); |
186 | debug_register_view(device->debug_area, &debug_sprintf_view); | 186 | debug_register_view(device->debug_area, &debug_sprintf_view); |
187 | debug_set_level(device->debug_area, DBF_EMERG); | 187 | debug_set_level(device->debug_area, DBF_WARNING); |
188 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); | 188 | DBF_DEV_EVENT(DBF_EMERG, device, "%s", "debug area created"); |
189 | 189 | ||
190 | device->state = DASD_STATE_BASIC; | 190 | device->state = DASD_STATE_BASIC; |
@@ -893,7 +893,7 @@ dasd_handle_killed_request(struct ccw_device *cdev, unsigned long intparm) | |||
893 | 893 | ||
894 | device = (struct dasd_device *) cqr->device; | 894 | device = (struct dasd_device *) cqr->device; |
895 | if (device == NULL || | 895 | if (device == NULL || |
896 | device != dasd_device_from_cdev(cdev) || | 896 | device != dasd_device_from_cdev_locked(cdev) || |
897 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { | 897 | strncmp(device->discipline->ebcname, (char *) &cqr->magic, 4)) { |
898 | MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", | 898 | MESSAGE(KERN_DEBUG, "invalid device in request: bus_id %s", |
899 | cdev->dev.bus_id); | 899 | cdev->dev.bus_id); |
@@ -970,7 +970,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
970 | /* first of all check for state change pending interrupt */ | 970 | /* first of all check for state change pending interrupt */ |
971 | mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; | 971 | mask = DEV_STAT_ATTENTION | DEV_STAT_DEV_END | DEV_STAT_UNIT_EXCEP; |
972 | if ((irb->scsw.dstat & mask) == mask) { | 972 | if ((irb->scsw.dstat & mask) == mask) { |
973 | device = dasd_device_from_cdev(cdev); | 973 | device = dasd_device_from_cdev_locked(cdev); |
974 | if (!IS_ERR(device)) { | 974 | if (!IS_ERR(device)) { |
975 | dasd_handle_state_change_pending(device); | 975 | dasd_handle_state_change_pending(device); |
976 | dasd_put_device(device); | 976 | dasd_put_device(device); |
@@ -2169,7 +2169,7 @@ dasd_init(void) | |||
2169 | goto failed; | 2169 | goto failed; |
2170 | } | 2170 | } |
2171 | debug_register_view(dasd_debug_area, &debug_sprintf_view); | 2171 | debug_register_view(dasd_debug_area, &debug_sprintf_view); |
2172 | debug_set_level(dasd_debug_area, DBF_EMERG); | 2172 | debug_set_level(dasd_debug_area, DBF_WARNING); |
2173 | 2173 | ||
2174 | DBF_EVENT(DBF_EMERG, "%s", "debug area created"); | 2174 | DBF_EVENT(DBF_EMERG, "%s", "debug area created"); |
2175 | 2175 | ||
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 9af02c79ce8a..91cf971f0652 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -258,8 +258,12 @@ dasd_parse_keyword( char *parsestring ) { | |||
258 | return residual_str; | 258 | return residual_str; |
259 | } | 259 | } |
260 | if (strncmp("nopav", parsestring, length) == 0) { | 260 | if (strncmp("nopav", parsestring, length) == 0) { |
261 | dasd_nopav = 1; | 261 | if (MACHINE_IS_VM) |
262 | MESSAGE(KERN_INFO, "%s", "disable PAV mode"); | 262 | MESSAGE(KERN_INFO, "%s", "'nopav' not supported on VM"); |
263 | else { | ||
264 | dasd_nopav = 1; | ||
265 | MESSAGE(KERN_INFO, "%s", "disable PAV mode"); | ||
266 | } | ||
263 | return residual_str; | 267 | return residual_str; |
264 | } | 268 | } |
265 | if (strncmp("fixedbuffers", parsestring, length) == 0) { | 269 | if (strncmp("fixedbuffers", parsestring, length) == 0) { |
@@ -523,17 +527,17 @@ dasd_create_device(struct ccw_device *cdev) | |||
523 | { | 527 | { |
524 | struct dasd_devmap *devmap; | 528 | struct dasd_devmap *devmap; |
525 | struct dasd_device *device; | 529 | struct dasd_device *device; |
530 | unsigned long flags; | ||
526 | int rc; | 531 | int rc; |
527 | 532 | ||
528 | devmap = dasd_devmap_from_cdev(cdev); | 533 | devmap = dasd_devmap_from_cdev(cdev); |
529 | if (IS_ERR(devmap)) | 534 | if (IS_ERR(devmap)) |
530 | return (void *) devmap; | 535 | return (void *) devmap; |
531 | cdev->dev.driver_data = devmap; | ||
532 | 536 | ||
533 | device = dasd_alloc_device(); | 537 | device = dasd_alloc_device(); |
534 | if (IS_ERR(device)) | 538 | if (IS_ERR(device)) |
535 | return device; | 539 | return device; |
536 | atomic_set(&device->ref_count, 2); | 540 | atomic_set(&device->ref_count, 3); |
537 | 541 | ||
538 | spin_lock(&dasd_devmap_lock); | 542 | spin_lock(&dasd_devmap_lock); |
539 | if (!devmap->device) { | 543 | if (!devmap->device) { |
@@ -552,6 +556,11 @@ dasd_create_device(struct ccw_device *cdev) | |||
552 | dasd_free_device(device); | 556 | dasd_free_device(device); |
553 | return ERR_PTR(rc); | 557 | return ERR_PTR(rc); |
554 | } | 558 | } |
559 | |||
560 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); | ||
561 | cdev->dev.driver_data = device; | ||
562 | spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); | ||
563 | |||
555 | return device; | 564 | return device; |
556 | } | 565 | } |
557 | 566 | ||
@@ -569,6 +578,7 @@ dasd_delete_device(struct dasd_device *device) | |||
569 | { | 578 | { |
570 | struct ccw_device *cdev; | 579 | struct ccw_device *cdev; |
571 | struct dasd_devmap *devmap; | 580 | struct dasd_devmap *devmap; |
581 | unsigned long flags; | ||
572 | 582 | ||
573 | /* First remove device pointer from devmap. */ | 583 | /* First remove device pointer from devmap. */ |
574 | devmap = dasd_find_busid(device->cdev->dev.bus_id); | 584 | devmap = dasd_find_busid(device->cdev->dev.bus_id); |
@@ -582,9 +592,16 @@ dasd_delete_device(struct dasd_device *device) | |||
582 | devmap->device = NULL; | 592 | devmap->device = NULL; |
583 | spin_unlock(&dasd_devmap_lock); | 593 | spin_unlock(&dasd_devmap_lock); |
584 | 594 | ||
585 | /* Drop ref_count by 2, one for the devmap reference and | 595 | /* Disconnect dasd_device structure from ccw_device structure. */ |
586 | * one for the passed reference. */ | 596 | spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); |
587 | atomic_sub(2, &device->ref_count); | 597 | device->cdev->dev.driver_data = NULL; |
598 | spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); | ||
599 | |||
600 | /* | ||
601 | * Drop ref_count by 3, one for the devmap reference, one for | ||
602 | * the cdev reference and one for the passed reference. | ||
603 | */ | ||
604 | atomic_sub(3, &device->ref_count); | ||
588 | 605 | ||
589 | /* Wait for reference counter to drop to zero. */ | 606 | /* Wait for reference counter to drop to zero. */ |
590 | wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); | 607 | wait_event(dasd_delete_wq, atomic_read(&device->ref_count) == 0); |
@@ -593,9 +610,6 @@ dasd_delete_device(struct dasd_device *device) | |||
593 | cdev = device->cdev; | 610 | cdev = device->cdev; |
594 | device->cdev = NULL; | 611 | device->cdev = NULL; |
595 | 612 | ||
596 | /* Disconnect dasd_devmap structure from ccw_device structure. */ | ||
597 | cdev->dev.driver_data = NULL; | ||
598 | |||
599 | /* Put ccw_device structure. */ | 613 | /* Put ccw_device structure. */ |
600 | put_device(&cdev->dev); | 614 | put_device(&cdev->dev); |
601 | 615 | ||
@@ -615,21 +629,32 @@ dasd_put_device_wake(struct dasd_device *device) | |||
615 | 629 | ||
616 | /* | 630 | /* |
617 | * Return dasd_device structure associated with cdev. | 631 | * Return dasd_device structure associated with cdev. |
632 | * This function needs to be called with the ccw device | ||
633 | * lock held. It can be used from interrupt context. | ||
634 | */ | ||
635 | struct dasd_device * | ||
636 | dasd_device_from_cdev_locked(struct ccw_device *cdev) | ||
637 | { | ||
638 | struct dasd_device *device = cdev->dev.driver_data; | ||
639 | |||
640 | if (!device) | ||
641 | return ERR_PTR(-ENODEV); | ||
642 | dasd_get_device(device); | ||
643 | return device; | ||
644 | } | ||
645 | |||
646 | /* | ||
647 | * Return dasd_device structure associated with cdev. | ||
618 | */ | 648 | */ |
619 | struct dasd_device * | 649 | struct dasd_device * |
620 | dasd_device_from_cdev(struct ccw_device *cdev) | 650 | dasd_device_from_cdev(struct ccw_device *cdev) |
621 | { | 651 | { |
622 | struct dasd_devmap *devmap; | ||
623 | struct dasd_device *device; | 652 | struct dasd_device *device; |
653 | unsigned long flags; | ||
624 | 654 | ||
625 | device = ERR_PTR(-ENODEV); | 655 | spin_lock_irqsave(get_ccwdev_lock(cdev), flags); |
626 | spin_lock(&dasd_devmap_lock); | 656 | device = dasd_device_from_cdev_locked(cdev); |
627 | devmap = cdev->dev.driver_data; | 657 | spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); |
628 | if (devmap && devmap->device) { | ||
629 | device = devmap->device; | ||
630 | dasd_get_device(device); | ||
631 | } | ||
632 | spin_unlock(&dasd_devmap_lock); | ||
633 | return device; | 658 | return device; |
634 | } | 659 | } |
635 | 660 | ||
@@ -730,16 +755,17 @@ static ssize_t | |||
730 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, | 755 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, |
731 | char *buf) | 756 | char *buf) |
732 | { | 757 | { |
733 | struct dasd_devmap *devmap; | 758 | struct dasd_device *device; |
734 | char *dname; | 759 | ssize_t len; |
735 | 760 | ||
736 | spin_lock(&dasd_devmap_lock); | 761 | device = dasd_device_from_cdev(to_ccwdev(dev)); |
737 | dname = "none"; | 762 | if (!IS_ERR(device) && device->discipline) { |
738 | devmap = dev->driver_data; | 763 | len = snprintf(buf, PAGE_SIZE, "%s\n", |
739 | if (devmap && devmap->device && devmap->device->discipline) | 764 | device->discipline->name); |
740 | dname = devmap->device->discipline->name; | 765 | dasd_put_device(device); |
741 | spin_unlock(&dasd_devmap_lock); | 766 | } else |
742 | return snprintf(buf, PAGE_SIZE, "%s\n", dname); | 767 | len = snprintf(buf, PAGE_SIZE, "none\n"); |
768 | return len; | ||
743 | } | 769 | } |
744 | 770 | ||
745 | static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); | 771 | static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index da65f1b032f5..e0bf30ebb215 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c | |||
@@ -678,7 +678,7 @@ int __init dasd_eer_init(void) | |||
678 | return 0; | 678 | return 0; |
679 | } | 679 | } |
680 | 680 | ||
681 | void __exit dasd_eer_exit(void) | 681 | void dasd_eer_exit(void) |
682 | { | 682 | { |
683 | WARN_ON(misc_deregister(&dasd_eer_dev) != 0); | 683 | WARN_ON(misc_deregister(&dasd_eer_dev) != 0); |
684 | } | 684 | } |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 3ccf06d28ba1..9f52004f6fc2 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -534,6 +534,7 @@ int dasd_add_sysfs_files(struct ccw_device *); | |||
534 | void dasd_remove_sysfs_files(struct ccw_device *); | 534 | void dasd_remove_sysfs_files(struct ccw_device *); |
535 | 535 | ||
536 | struct dasd_device *dasd_device_from_cdev(struct ccw_device *); | 536 | struct dasd_device *dasd_device_from_cdev(struct ccw_device *); |
537 | struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); | ||
537 | struct dasd_device *dasd_device_from_devindex(int); | 538 | struct dasd_device *dasd_device_from_devindex(int); |
538 | 539 | ||
539 | int dasd_parse(void); | 540 | int dasd_parse(void); |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index ca7d51f7eccc..cab2c736683a 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -453,7 +453,7 @@ static int __init xpram_init(void) | |||
453 | PRINT_WARN("No expanded memory available\n"); | 453 | PRINT_WARN("No expanded memory available\n"); |
454 | return -ENODEV; | 454 | return -ENODEV; |
455 | } | 455 | } |
456 | xpram_pages = xpram_highest_page_index(); | 456 | xpram_pages = xpram_highest_page_index() + 1; |
457 | PRINT_INFO(" %u pages expanded memory found (%lu KB).\n", | 457 | PRINT_INFO(" %u pages expanded memory found (%lu KB).\n", |
458 | xpram_pages, (unsigned long) xpram_pages*4); | 458 | xpram_pages, (unsigned long) xpram_pages*4); |
459 | rc = xpram_setup_sizes(xpram_pages); | 459 | rc = xpram_setup_sizes(xpram_pages); |