aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c8
-rw-r--r--drivers/s390/block/dasd_devmap.c82
-rw-r--r--drivers/s390/block/dasd_eer.c2
-rw-r--r--drivers/s390/block/dasd_int.h1
-rw-r--r--drivers/s390/block/xpram.c2
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 */
635struct dasd_device *
636dasd_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 */
619struct dasd_device * 649struct dasd_device *
620dasd_device_from_cdev(struct ccw_device *cdev) 650dasd_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
730dasd_discipline_show(struct device *dev, struct device_attribute *attr, 755dasd_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
745static DEVICE_ATTR(discipline, 0444, dasd_discipline_show, NULL); 771static 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
681void __exit dasd_eer_exit(void) 681void 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 *);
534void dasd_remove_sysfs_files(struct ccw_device *); 534void dasd_remove_sysfs_files(struct ccw_device *);
535 535
536struct dasd_device *dasd_device_from_cdev(struct ccw_device *); 536struct dasd_device *dasd_device_from_cdev(struct ccw_device *);
537struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *);
537struct dasd_device *dasd_device_from_devindex(int); 538struct dasd_device *dasd_device_from_devindex(int);
538 539
539int dasd_parse(void); 540int 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);