extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long);
 extern int ccw_device_set_options(struct ccw_device *, unsigned long);
 extern void ccw_device_clear_options(struct ccw_device *, unsigned long);
+int ccw_device_is_pathgroup(struct ccw_device *cdev);
+int ccw_device_is_multipath(struct ccw_device *cdev);
 
 /* Allow for i/o completion notification after primary interrupt status. */
 #define CCWDEV_EARLY_NOTIFICATION      0x0001
 #define CCWDEV_DO_PATHGROUP             0x0004
 /* Allow forced onlining of boxed devices. */
 #define CCWDEV_ALLOW_FORCE              0x0008
+/* Try to use multipath mode. */
+#define CCWDEV_DO_MULTIPATH            0x0010
 
 extern int ccw_device_start(struct ccw_device *, struct ccw1 *,
                            unsigned long, __u8, unsigned long);
 
 {
        int ret;
 
-       ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
-       if (ret) {
-               DBF_EVENT(DBF_WARNING,
-                      "dasd_generic_probe: could not set ccw-device options "
-                      "for %s\n", dev_name(&cdev->dev));
-               return ret;
-       }
        ret = dasd_add_sysfs_files(cdev);
        if (ret) {
                DBF_EVENT(DBF_WARNING,
 
        int ret;
 
        /* set ECKD specific ccw-device options */
-       ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE);
+       ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE |
+                                    CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH);
        if (ret) {
                DBF_EVENT(DBF_WARNING,
                       "dasd_eckd_probe: could not set ccw-device options "
        struct dasd_block *block;
        int is_known, rc;
 
+       if (!ccw_device_is_pathgroup(device->cdev)) {
+               dev_warn(&device->cdev->dev,
+                        "A channel path group could not be established\n");
+               return -EIO;
+       }
+       if (!ccw_device_is_multipath(device->cdev)) {
+               dev_info(&device->cdev->dev,
+                        "The DASD is not operating in multipath mode\n");
+       }
        private = (struct dasd_eckd_private *) device->private;
        if (!private) {
                private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA);
 
        device = tape_alloc_device();
        if (IS_ERR(device))
                return -ENODEV;
-       ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
+       ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP |
+                                    CCWDEV_DO_MULTIPATH);
        ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
        if (ret) {
                tape_put_device(device);
 
        if (cdev->private->state != DEV_STATE_ONLINE)
                return -EINVAL;
        /* Are we doing path grouping? */
-       if (!cdev->private->options.pgroup) {
+       if (!cdev->private->flags.pgroup) {
                /* No, set state offline immediately. */
                ccw_device_done(cdev, DEV_STATE_OFFLINE);
                return 0;
 
        cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0;
        cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0;
        cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0;
+       cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0;
        return 0;
 }
 
        cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0;
        cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0;
        cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0;
+       cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0;
        return 0;
 }
 
        cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0;
        cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0;
        cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0;
+       cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0;
 }
 
+/**
+ * ccw_device_is_pathgroup - determine if paths to this device are grouped
+ * @cdev: ccw device
+ *
+ * Return non-zero if there is a path group, zero otherwise.
+ */
+int ccw_device_is_pathgroup(struct ccw_device *cdev)
+{
+       return cdev->private->flags.pgroup;
+}
+EXPORT_SYMBOL(ccw_device_is_pathgroup);
+
+/**
+ * ccw_device_is_multipath - determine if device is operating in multipath mode
+ * @cdev: ccw device
+ *
+ * Return non-zero if device is operating in multipath mode, zero otherwise.
+ */
+int ccw_device_is_multipath(struct ccw_device *cdev)
+{
+       return cdev->private->flags.mpath;
+}
+EXPORT_SYMBOL(ccw_device_is_multipath);
+
 /**
  * ccw_device_clear() - terminate I/O request processing
  * @cdev: target ccw device
 
 {
        struct subchannel *sch = to_subchannel(cdev->dev.parent);
        struct ccw_dev_id *id = &cdev->private->dev_id;
-       int mpath = !cdev->private->flags.pgid_single;
-       int pgroup = cdev->private->options.pgroup;
+       int mpath = cdev->private->flags.mpath;
+       int pgroup = cdev->private->flags.pgroup;
 
        if (rc)
                goto out;
                fn = SPID_FUNC_ESTABLISH;
        else
                fn = SPID_FUNC_RESIGN;
-       if (!cdev->private->flags.pgid_single)
+       if (cdev->private->flags.mpath)
                fn |= SPID_FUNC_MULTI_PATH;
        spid_build_cp(cdev, fn);
        ccw_request_start(cdev);
        case -EACCES:
                break;
        case -EOPNOTSUPP:
-               if (!cdev->private->flags.pgid_single) {
+               if (cdev->private->flags.mpath) {
                        /* Try without multipathing. */
-                       cdev->private->flags.pgid_single = 1;
+                       cdev->private->flags.mpath = 0;
                        goto out_restart;
                }
                /* Try without pathgrouping. */
-               cdev->private->options.pgroup = 0;
+               cdev->private->flags.pgroup = 0;
                goto out_restart;
        default:
                goto err;
        req->timeout    = PGID_TIMEOUT;
        req->maxretries = PGID_RETRIES;
        req->lpm        = 0x80;
-       if (cdev->private->options.pgroup) {
+       if (cdev->private->flags.pgroup) {
                req->callback   = spid_callback;
                spid_do(cdev);
        } else {
        CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id));
        if (!cdev->private->flags.pgid_rdy) {
                /* No pathgrouping possible. */
-               cdev->private->options.pgroup = 0;
-               cdev->private->flags.pgid_single = 1;
-       } else
-               cdev->private->flags.pgid_single = 0;
+               cdev->private->flags.pgroup = 0;
+               cdev->private->flags.mpath = 0;
+       } else {
+               /*
+                * Initialize pathgroup and multipath state with target values.
+                * They may change in the course of path verification.
+                */
+               cdev->private->flags.pgroup = cdev->private->options.pgroup;
+               cdev->private->flags.mpath = cdev->private->options.mpath;
+
+       }
        cdev->private->flags.doverify = 0;
        verify_start(cdev);
 }
        if (rc)
                goto out;
        /* Ensure consistent multipathing state at device and channel. */
-       cdev->private->flags.pgid_single = 1;
+       cdev->private->flags.mpath = 0;
        if (sch->config.mp) {
                sch->config.mp = 0;
                rc = cio_commit_config(sch);
        req->lpm        = sch->schib.pmcw.pam & sch->opm;
        req->callback   = disband_callback;
        fn = SPID_FUNC_DISBAND;
-       if (!cdev->private->flags.pgid_single)
+       if (cdev->private->flags.mpath)
                fn |= SPID_FUNC_MULTI_PATH;
        spid_build_cp(cdev, fn);
        ccw_request_start(cdev);
 
                unsigned int repall:1;  /* report every interrupt status */
                unsigned int pgroup:1;  /* do path grouping */
                unsigned int force:1;   /* allow forced online */
+               unsigned int mpath:1;   /* do multipathing */
        } __attribute__ ((packed)) options;
        struct {
-               unsigned int pgid_single:1; /* use single path for Set PGID */
                unsigned int esid:1;        /* Ext. SenseID supported by HW */
                unsigned int dosense:1;     /* delayed SENSE required */
                unsigned int doverify:1;    /* delayed path verification */
                unsigned int fake_irb:1;    /* deliver faked irb */
                unsigned int resuming:1;    /* recognition while resume */
                unsigned int pgid_rdy:1;    /* pgids are ready */
+               unsigned int pgroup:1;      /* pathgroup is set up */
+               unsigned int mpath:1;       /* multipathing is set up */
        } __attribute__((packed)) flags;
        unsigned long intparm;  /* user interruption parameter */
        struct qdio_irq *qdio_data;