aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block
diff options
context:
space:
mode:
authorHorst Hummel <horst.hummel@de.ibm.com>2006-06-29 09:08:18 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-06-29 09:08:18 -0400
commit405455734e1cdec09c37233216f9240cb1a058e5 (patch)
tree36e88909f646b635117041b19a851031fc8ffb41 /drivers/s390/block
parent8f27766a883149926e7c1f69d9f1d8f68efcd65f (diff)
[S390] add PAV support to the dasd driver.
Add support for parallel-access-volumes to the dasd driver. This allows concurrent access to dasd devices with multiple channel programs. Signed-off-by: Horst Hummel <horst.hummel@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block')
-rw-r--r--drivers/s390/block/dasd.c51
-rw-r--r--drivers/s390/block/dasd_devmap.c80
-rw-r--r--drivers/s390/block/dasd_eckd.c140
-rw-r--r--drivers/s390/block/dasd_eckd.h16
-rw-r--r--drivers/s390/block/dasd_fba.c20
-rw-r--r--drivers/s390/block/dasd_int.h2
6 files changed, 222 insertions, 87 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 7e9978ad1445..bafcd2f20ae2 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1855,15 +1855,34 @@ dasd_generic_probe (struct ccw_device *cdev,
1855{ 1855{
1856 int ret; 1856 int ret;
1857 1857
1858 ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
1859 if (ret) {
1860 printk(KERN_WARNING
1861 "dasd_generic_probe: could not set ccw-device options "
1862 "for %s\n", cdev->dev.bus_id);
1863 return ret;
1864 }
1858 ret = dasd_add_sysfs_files(cdev); 1865 ret = dasd_add_sysfs_files(cdev);
1859 if (ret) { 1866 if (ret) {
1860 printk(KERN_WARNING 1867 printk(KERN_WARNING
1861 "dasd_generic_probe: could not add sysfs entries " 1868 "dasd_generic_probe: could not add sysfs entries "
1862 "for %s\n", cdev->dev.bus_id); 1869 "for %s\n", cdev->dev.bus_id);
1863 } else { 1870 return ret;
1864 cdev->handler = &dasd_int_handler;
1865 } 1871 }
1872 cdev->handler = &dasd_int_handler;
1866 1873
1874 /*
1875 * Automatically online either all dasd devices (dasd_autodetect)
1876 * or all devices specified with dasd= parameters during
1877 * initial probe.
1878 */
1879 if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) ||
1880 (dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0))
1881 ret = ccw_device_set_online(cdev);
1882 if (ret)
1883 printk(KERN_WARNING
1884 "dasd_generic_probe: could not initially online "
1885 "ccw-device %s\n", cdev->dev.bus_id);
1867 return ret; 1886 return ret;
1868} 1887}
1869 1888
@@ -1911,6 +1930,8 @@ dasd_generic_set_online (struct ccw_device *cdev,
1911 struct dasd_device *device; 1930 struct dasd_device *device;
1912 int rc; 1931 int rc;
1913 1932
1933 /* first online clears initial online feature flag */
1934 dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0);
1914 device = dasd_create_device(cdev); 1935 device = dasd_create_device(cdev);
1915 if (IS_ERR(device)) 1936 if (IS_ERR(device))
1916 return PTR_ERR(device); 1937 return PTR_ERR(device);
@@ -2065,31 +2086,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event)
2065 return ret; 2086 return ret;
2066} 2087}
2067 2088
2068/*
2069 * Automatically online either all dasd devices (dasd_autodetect) or
2070 * all devices specified with dasd= parameters.
2071 */
2072static int
2073__dasd_auto_online(struct device *dev, void *data)
2074{
2075 struct ccw_device *cdev;
2076
2077 cdev = to_ccwdev(dev);
2078 if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0)
2079 ccw_device_set_online(cdev);
2080 return 0;
2081}
2082
2083void
2084dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver)
2085{
2086 struct device_driver *drv;
2087
2088 drv = get_driver(&dasd_discipline_driver->driver);
2089 driver_for_each_device(drv, NULL, NULL, __dasd_auto_online);
2090 put_driver(drv);
2091}
2092
2093 2089
2094static int __init 2090static int __init
2095dasd_init(void) 2091dasd_init(void)
@@ -2170,5 +2166,4 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove);
2170EXPORT_SYMBOL_GPL(dasd_generic_notify); 2166EXPORT_SYMBOL_GPL(dasd_generic_notify);
2171EXPORT_SYMBOL_GPL(dasd_generic_set_online); 2167EXPORT_SYMBOL_GPL(dasd_generic_set_online);
2172EXPORT_SYMBOL_GPL(dasd_generic_set_offline); 2168EXPORT_SYMBOL_GPL(dasd_generic_set_offline);
2173EXPORT_SYMBOL_GPL(dasd_generic_auto_online);
2174 2169
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 672e50314b12..9e9ae7179602 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -27,7 +27,7 @@
27#include "dasd_int.h" 27#include "dasd_int.h"
28 28
29kmem_cache_t *dasd_page_cache; 29kmem_cache_t *dasd_page_cache;
30EXPORT_SYMBOL(dasd_page_cache); 30EXPORT_SYMBOL_GPL(dasd_page_cache);
31 31
32/* 32/*
33 * dasd_devmap_t is used to store the features and the relation 33 * dasd_devmap_t is used to store the features and the relation
@@ -49,6 +49,20 @@ struct dasd_devmap {
49}; 49};
50 50
51/* 51/*
52 * dasd_servermap is used to store the server_id of all storage servers
53 * accessed by DASD device driver.
54 */
55struct dasd_servermap {
56 struct list_head list;
57 struct server_id {
58 char vendor[4];
59 char serial[15];
60 } sid;
61};
62
63static struct list_head dasd_serverlist;
64
65/*
52 * Parameter parsing functions for dasd= parameter. The syntax is: 66 * Parameter parsing functions for dasd= parameter. The syntax is:
53 * <devno> : (0x)?[0-9a-fA-F]+ 67 * <devno> : (0x)?[0-9a-fA-F]+
54 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+ 68 * <busid> : [0-0a-f]\.[0-9a-f]\.(0x)?[0-9a-fA-F]+
@@ -64,6 +78,8 @@ struct dasd_devmap {
64 78
65int dasd_probeonly = 0; /* is true, when probeonly mode is active */ 79int dasd_probeonly = 0; /* is true, when probeonly mode is active */
66int dasd_autodetect = 0; /* is true, when autodetection is active */ 80int dasd_autodetect = 0; /* is true, when autodetection is active */
81int dasd_nopav = 0; /* is true, when PAV is disabled */
82EXPORT_SYMBOL_GPL(dasd_nopav);
67 83
68/* 84/*
69 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement 85 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
@@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) {
228 length = strlen(parsestring); 244 length = strlen(parsestring);
229 residual_str = parsestring + length; 245 residual_str = parsestring + length;
230 } 246 }
231 if (strncmp ("autodetect", parsestring, length) == 0) { 247 if (strncmp("autodetect", parsestring, length) == 0) {
232 dasd_autodetect = 1; 248 dasd_autodetect = 1;
233 MESSAGE (KERN_INFO, "%s", 249 MESSAGE (KERN_INFO, "%s",
234 "turning to autodetection mode"); 250 "turning to autodetection mode");
235 return residual_str; 251 return residual_str;
236 } 252 }
237 if (strncmp ("probeonly", parsestring, length) == 0) { 253 if (strncmp("probeonly", parsestring, length) == 0) {
238 dasd_probeonly = 1; 254 dasd_probeonly = 1;
239 MESSAGE(KERN_INFO, "%s", 255 MESSAGE(KERN_INFO, "%s",
240 "turning to probeonly mode"); 256 "turning to probeonly mode");
241 return residual_str; 257 return residual_str;
242 } 258 }
243 if (strncmp ("fixedbuffers", parsestring, length) == 0) { 259 if (strncmp("nopav", parsestring, length) == 0) {
260 dasd_nopav = 1;
261 MESSAGE(KERN_INFO, "%s", "disable PAV mode");
262 return residual_str;
263 }
264 if (strncmp("fixedbuffers", parsestring, length) == 0) {
244 if (dasd_page_cache) 265 if (dasd_page_cache)
245 return residual_str; 266 return residual_str;
246 dasd_page_cache = 267 dasd_page_cache =
@@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) {
294 features = dasd_feature_list(str, &str); 315 features = dasd_feature_list(str, &str);
295 if (features < 0) 316 if (features < 0)
296 return ERR_PTR(-EINVAL); 317 return ERR_PTR(-EINVAL);
318 /* each device in dasd= parameter should be set initially online */
319 features |= DASD_FEATURE_INITIAL_ONLINE;
297 while (from <= to) { 320 while (from <= to) {
298 sprintf(bus_id, "%01x.%01x.%04x", 321 sprintf(bus_id, "%01x.%01x.%04x",
299 from_id0, from_id1, from++); 322 from_id0, from_id1, from++);
@@ -836,6 +859,38 @@ static struct attribute_group dasd_attr_group = {
836 .attrs = dasd_attrs, 859 .attrs = dasd_attrs,
837}; 860};
838 861
862/*
863 * Check if the related storage server is already contained in the
864 * dasd_serverlist. If server is not contained, create new entry.
865 * Return 0 if server was already in serverlist,
866 * 1 if the server was added successfully
867 * <0 in case of error.
868 */
869static int
870dasd_add_server(struct dasd_uid *uid)
871{
872 struct dasd_servermap *new, *tmp;
873
874 /* check if server is already contained */
875 list_for_each_entry(tmp, &dasd_serverlist, list)
876 // normale cmp?
877 if (strncmp(tmp->sid.vendor, uid->vendor,
878 sizeof(tmp->sid.vendor)) == 0
879 && strncmp(tmp->sid.serial, uid->serial,
880 sizeof(tmp->sid.serial)) == 0)
881 return 0;
882
883 new = (struct dasd_servermap *)
884 kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL);
885 if (!new)
886 return -ENOMEM;
887
888 strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor));
889 strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial));
890 list_add(&new->list, &dasd_serverlist);
891 return 1;
892}
893
839 894
840/* 895/*
841 * Return copy of the device unique identifier. 896 * Return copy of the device unique identifier.
@@ -856,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
856 911
857/* 912/*
858 * Register the given device unique identifier into devmap struct. 913 * Register the given device unique identifier into devmap struct.
914 * Return 0 if server was already in serverlist,
915 * 1 if the server was added successful
916 * <0 in case of error.
859 */ 917 */
860int 918int
861dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) 919dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid)
862{ 920{
863 struct dasd_devmap *devmap; 921 struct dasd_devmap *devmap;
922 int rc;
864 923
865 devmap = dasd_find_busid(cdev->dev.bus_id); 924 devmap = dasd_find_busid(cdev->dev.bus_id);
866 if (IS_ERR(devmap)) 925 if (IS_ERR(devmap))
867 return PTR_ERR(devmap); 926 return PTR_ERR(devmap);
868 spin_lock(&dasd_devmap_lock); 927 spin_lock(&dasd_devmap_lock);
869 devmap->uid = *uid; 928 devmap->uid = *uid;
929 rc = dasd_add_server(uid);
870 spin_unlock(&dasd_devmap_lock); 930 spin_unlock(&dasd_devmap_lock);
871 return 0; 931 return rc;
872} 932}
873EXPORT_SYMBOL(dasd_set_uid); 933EXPORT_SYMBOL_GPL(dasd_set_uid);
874 934
875/* 935/*
876 * Return value of the specified feature. 936 * Return value of the specified feature.
@@ -882,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature)
882 942
883 devmap = dasd_find_busid(cdev->dev.bus_id); 943 devmap = dasd_find_busid(cdev->dev.bus_id);
884 if (IS_ERR(devmap)) 944 if (IS_ERR(devmap))
885 return (int) PTR_ERR(devmap); 945 return PTR_ERR(devmap);
886 946
887 return ((devmap->features & feature) != 0); 947 return ((devmap->features & feature) != 0);
888} 948}
@@ -898,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag)
898 958
899 devmap = dasd_find_busid(cdev->dev.bus_id); 959 devmap = dasd_find_busid(cdev->dev.bus_id);
900 if (IS_ERR(devmap)) 960 if (IS_ERR(devmap))
901 return (int) PTR_ERR(devmap); 961 return PTR_ERR(devmap);
902 962
903 spin_lock(&dasd_devmap_lock); 963 spin_lock(&dasd_devmap_lock);
904 if (flag) 964 if (flag)
@@ -934,8 +994,10 @@ dasd_devmap_init(void)
934 dasd_max_devindex = 0; 994 dasd_max_devindex = 0;
935 for (i = 0; i < 256; i++) 995 for (i = 0; i < 256; i++)
936 INIT_LIST_HEAD(&dasd_hashlists[i]); 996 INIT_LIST_HEAD(&dasd_hashlists[i]);
937 return 0;
938 997
998 /* Initialize servermap structure. */
999 INIT_LIST_HEAD(&dasd_serverlist);
1000 return 0;
939} 1001}
940 1002
941void 1003void
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 12257776e79b..0dfab30e8089 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -24,6 +24,7 @@
24#include <asm/io.h> 24#include <asm/io.h>
25#include <asm/todclk.h> 25#include <asm/todclk.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/cio.h>
27#include <asm/ccwdev.h> 28#include <asm/ccwdev.h>
28 29
29#include "dasd_int.h" 30#include "dasd_int.h"
@@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev)
89{ 90{
90 int ret; 91 int ret;
91 92
92 ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); 93 /* set ECKD specific ccw-device options */
93 if (ret) 94 ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
95 if (ret) {
96 printk(KERN_WARNING
97 "dasd_eckd_probe: could not set ccw-device options "
98 "for %s\n", cdev->dev.bus_id);
94 return ret; 99 return ret;
95 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); 100 }
96 return 0; 101 ret = dasd_generic_probe(cdev, &dasd_eckd_discipline);
102 return ret;
97} 103}
98 104
99static int 105static int
100dasd_eckd_set_online(struct ccw_device *cdev) 106dasd_eckd_set_online(struct ccw_device *cdev)
101{ 107{
102 return dasd_generic_set_online (cdev, &dasd_eckd_discipline); 108 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
103} 109}
104 110
105static struct ccw_driver dasd_eckd_driver = { 111static struct ccw_driver dasd_eckd_driver = {
@@ -541,6 +547,86 @@ dasd_eckd_read_conf(struct dasd_device *device)
541} 547}
542 548
543/* 549/*
550 * Build CP for Perform Subsystem Function - SSC.
551 */
552struct dasd_ccw_req *
553dasd_eckd_build_psf_ssc(struct dasd_device *device)
554{
555 struct dasd_ccw_req *cqr;
556 struct dasd_psf_ssc_data *psf_ssc_data;
557 struct ccw1 *ccw;
558
559 cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ ,
560 sizeof(struct dasd_psf_ssc_data),
561 device);
562
563 if (IS_ERR(cqr)) {
564 DEV_MESSAGE(KERN_WARNING, device, "%s",
565 "Could not allocate PSF-SSC request");
566 return cqr;
567 }
568 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data;
569 psf_ssc_data->order = PSF_ORDER_SSC;
570 psf_ssc_data->suborder = 0x08;
571
572 ccw = cqr->cpaddr;
573 ccw->cmd_code = DASD_ECKD_CCW_PSF;
574 ccw->cda = (__u32)(addr_t)psf_ssc_data;
575 ccw->count = 66;
576
577 cqr->device = device;
578 cqr->expires = 10*HZ;
579 cqr->buildclk = get_clock();
580 cqr->status = DASD_CQR_FILLED;
581 return cqr;
582}
583
584/*
585 * Perform Subsystem Function.
586 * It is necessary to trigger CIO for channel revalidation since this
587 * call might change behaviour of DASD devices.
588 */
589static int
590dasd_eckd_psf_ssc(struct dasd_device *device)
591{
592 struct dasd_ccw_req *cqr;
593 int rc;
594
595 cqr = dasd_eckd_build_psf_ssc(device);
596 if (IS_ERR(cqr))
597 return PTR_ERR(cqr);
598
599 rc = dasd_sleep_on(cqr);
600 if (!rc)
601 /* trigger CIO to reprobe devices */
602 css_schedule_reprobe();
603 dasd_sfree_request(cqr, cqr->device);
604 return rc;
605}
606
607/*
608 * Valide storage server of current device.
609 */
610static int
611dasd_eckd_validate_server(struct dasd_device *device)
612{
613 int rc;
614
615 /* Currently PAV is the only reason to 'validate' server on LPAR */
616 if (dasd_nopav || MACHINE_IS_VM)
617 return 0;
618
619 rc = dasd_eckd_psf_ssc(device);
620 if (rc)
621 /* may be requested feature is not available on server,
622 * therefore just report error and go ahead */
623 DEV_MESSAGE(KERN_INFO, device,
624 "Perform Subsystem Function returned rc=%d", rc);
625 /* RE-Read Configuration Data */
626 return dasd_eckd_read_conf(device);
627}
628
629/*
544 * Check device characteristics. 630 * Check device characteristics.
545 * If the device is accessible using ECKD discipline, the device is enabled. 631 * If the device is accessible using ECKD discipline, the device is enabled.
546 */ 632 */
@@ -570,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
570 private->attrib.operation = DASD_NORMAL_CACHE; 656 private->attrib.operation = DASD_NORMAL_CACHE;
571 private->attrib.nr_cyl = 0; 657 private->attrib.nr_cyl = 0;
572 658
659 /* Read Configuration Data */
660 rc = dasd_eckd_read_conf(device);
661 if (rc)
662 return rc;
663
664 /* Generate device unique id and register in devmap */
665 rc = dasd_eckd_generate_uid(device, &uid);
666 if (rc)
667 return rc;
668 rc = dasd_set_uid(device->cdev, &uid);
669 if (rc == 1) /* new server found */
670 rc = dasd_eckd_validate_server(device);
671 if (rc)
672 return rc;
673
573 /* Read Device Characteristics */ 674 /* Read Device Characteristics */
574 rdc_data = (void *) &(private->rdc_data); 675 rdc_data = (void *) &(private->rdc_data);
575 memset(rdc_data, 0, sizeof(rdc_data)); 676 memset(rdc_data, 0, sizeof(rdc_data));
576 rc = read_dev_chars(device->cdev, &rdc_data, 64); 677 rc = read_dev_chars(device->cdev, &rdc_data, 64);
577 if (rc) { 678 if (rc)
578 DEV_MESSAGE(KERN_WARNING, device, 679 DEV_MESSAGE(KERN_WARNING, device,
579 "Read device characteristics returned error %d", 680 "Read device characteristics returned "
580 rc); 681 "rc=%d", rc);
581 return rc;
582 }
583 682
584 DEV_MESSAGE(KERN_INFO, device, 683 DEV_MESSAGE(KERN_INFO, device,
585 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", 684 "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d",
@@ -590,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
590 private->rdc_data.no_cyl, 689 private->rdc_data.no_cyl,
591 private->rdc_data.trk_per_cyl, 690 private->rdc_data.trk_per_cyl,
592 private->rdc_data.sec_per_trk); 691 private->rdc_data.sec_per_trk);
593
594 /* Read Configuration Data */
595 rc = dasd_eckd_read_conf (device);
596 if (rc)
597 return rc;
598
599 /* Generate device unique id and register in devmap */
600 rc = dasd_eckd_generate_uid(device, &uid);
601 if (rc)
602 return rc;
603
604 rc = dasd_set_uid(device->cdev, &uid);
605
606 return rc; 692 return rc;
607} 693}
608 694
@@ -1687,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = {
1687static int __init 1773static int __init
1688dasd_eckd_init(void) 1774dasd_eckd_init(void)
1689{ 1775{
1690 int ret;
1691
1692 ASCEBC(dasd_eckd_discipline.ebcname, 4); 1776 ASCEBC(dasd_eckd_discipline.ebcname, 4);
1693 1777 return ccw_driver_register(&dasd_eckd_driver);
1694 ret = ccw_driver_register(&dasd_eckd_driver);
1695 if (!ret)
1696 dasd_generic_auto_online(&dasd_eckd_driver);
1697 return ret;
1698} 1778}
1699 1779
1700static void __exit 1780static void __exit
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h
index 9d91c8632569..712ff1650134 100644
--- a/drivers/s390/block/dasd_eckd.h
+++ b/drivers/s390/block/dasd_eckd.h
@@ -41,9 +41,10 @@
41#define DASD_ECKD_CCW_RESERVE 0xB4 41#define DASD_ECKD_CCW_RESERVE 0xB4
42 42
43/* 43/*
44 *Perform Subsystem Function / Sub-Orders 44 * Perform Subsystem Function / Sub-Orders
45 */ 45 */
46#define PSF_ORDER_PRSSD 0x18 46#define PSF_ORDER_PRSSD 0x18
47#define PSF_ORDER_SSC 0x1D
47 48
48/***************************************************************************** 49/*****************************************************************************
49 * SECTION: Type Definitions 50 * SECTION: Type Definitions
@@ -353,4 +354,15 @@ struct dasd_psf_prssd_data {
353 unsigned char varies[9]; 354 unsigned char varies[9];
354} __attribute__ ((packed)); 355} __attribute__ ((packed));
355 356
357/*
358 * Perform Subsystem Function - Set Subsystem Characteristics
359 */
360struct dasd_psf_ssc_data {
361 unsigned char order;
362 unsigned char flags;
363 unsigned char cu_type[4];
364 unsigned char suborder;
365 unsigned char reserved[59];
366} __attribute__((packed));
367
356#endif /* DASD_ECKD_H */ 368#endif /* DASD_ECKD_H */
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index d331c6e22c59..bb7755b9b19d 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -56,19 +56,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */
56static int 56static int
57dasd_fba_probe(struct ccw_device *cdev) 57dasd_fba_probe(struct ccw_device *cdev)
58{ 58{
59 int ret; 59 return dasd_generic_probe(cdev, &dasd_fba_discipline);
60
61 ret = dasd_generic_probe (cdev, &dasd_fba_discipline);
62 if (ret)
63 return ret;
64 ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
65 return 0;
66} 60}
67 61
68static int 62static int
69dasd_fba_set_online(struct ccw_device *cdev) 63dasd_fba_set_online(struct ccw_device *cdev)
70{ 64{
71 return dasd_generic_set_online (cdev, &dasd_fba_discipline); 65 return dasd_generic_set_online(cdev, &dasd_fba_discipline);
72} 66}
73 67
74static struct ccw_driver dasd_fba_driver = { 68static struct ccw_driver dasd_fba_driver = {
@@ -569,16 +563,8 @@ static struct dasd_discipline dasd_fba_discipline = {
569static int __init 563static int __init
570dasd_fba_init(void) 564dasd_fba_init(void)
571{ 565{
572 int ret;
573
574 ASCEBC(dasd_fba_discipline.ebcname, 4); 566 ASCEBC(dasd_fba_discipline.ebcname, 4);
575 567 return ccw_driver_register(&dasd_fba_driver);
576 ret = ccw_driver_register(&dasd_fba_driver);
577 if (ret)
578 return ret;
579
580 dasd_generic_auto_online(&dasd_fba_driver);
581 return 0;
582} 568}
583 569
584static void __exit 570static void __exit
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 2c1fa85a3dad..03a83efc34c4 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -513,12 +513,12 @@ void dasd_generic_remove (struct ccw_device *cdev);
513int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); 513int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
514int dasd_generic_set_offline (struct ccw_device *cdev); 514int dasd_generic_set_offline (struct ccw_device *cdev);
515int dasd_generic_notify(struct ccw_device *, int); 515int dasd_generic_notify(struct ccw_device *, int);
516void dasd_generic_auto_online (struct ccw_driver *);
517 516
518/* externals in dasd_devmap.c */ 517/* externals in dasd_devmap.c */
519extern int dasd_max_devindex; 518extern int dasd_max_devindex;
520extern int dasd_probeonly; 519extern int dasd_probeonly;
521extern int dasd_autodetect; 520extern int dasd_autodetect;
521extern int dasd_nopav;
522 522
523int dasd_devmap_init(void); 523int dasd_devmap_init(void);
524void dasd_devmap_exit(void); 524void dasd_devmap_exit(void);