s390/ccwgroup: tie a ccwgroup driver to its ccw driver
authorJulian Wiedmann <jwi@linux.vnet.ibm.com>
Thu, 14 Sep 2017 07:52:32 +0000 (09:52 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 29 Sep 2017 13:51:30 +0000 (15:51 +0200)
When grouping devices, the ccwgroup core only checks whether all of the
devices are bound to the same ccw_driver. It has no means of checking
if the requesting ccwgroup driver actually supports this device type.
qeth implements its own device matching in qeth_core_probe_device(),
while ctcm and lcs currently have no sanity-checking at all.

Enable ccwgroup drivers to optionally defer the device type checking to
the ccwgroup core, by specifying their supported ccw_driver.
This allows us drop the device type matching from qeth, and improves
the robustness of ctcm and lcs.

Signed-off-by: Julian Wiedmann <jwi@linux.vnet.ibm.com>
Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/ccwgroup.h
drivers/s390/cio/ccwgroup.c
drivers/s390/net/ctcm_main.c
drivers/s390/net/lcs.c
drivers/s390/net/qeth_core_main.c

index 057ce0ca6377dc3b28b775c3c1ca1797a8cbbf2c..6d50e86dd0e837c0c2a3d9588229f691b1b56983 100644 (file)
@@ -41,6 +41,7 @@ struct ccwgroup_device {
  * @thaw: undo work done in @freeze
  * @restore: callback for restoring after hibernation
  * @driver: embedded driver structure
+ * @ccw_driver: supported ccw_driver (optional)
  */
 struct ccwgroup_driver {
        int (*setup) (struct ccwgroup_device *);
@@ -55,6 +56,7 @@ struct ccwgroup_driver {
        int (*restore)(struct ccwgroup_device *);
 
        struct device_driver driver;
+       struct ccw_driver *ccw_driver;
 };
 
 extern int  ccwgroup_driver_register   (struct ccwgroup_driver *cdriver);
index 34b9ad6b31438fb8864a9068d7f72294722da169..e2f7b6e93efddf85dd45457d70ce3c3bc3602ba3 100644 (file)
@@ -373,6 +373,12 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv,
                rc = -EINVAL;
                goto error;
        }
+       /* Check if the devices are bound to the required ccw driver. */
+       if (gdev->count && gdrv && gdrv->ccw_driver &&
+           gdev->cdev[0]->drv != gdrv->ccw_driver) {
+               rc = -EINVAL;
+               goto error;
+       }
 
        dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev));
        gdev->dev.groups = ccwgroup_attr_groups;
index 26363e0816fe4ac4c3ffa6aa5cdb03a285d7f9b8..be9f172185310ac081d6a44f0e061868bc5885d3 100644 (file)
@@ -1761,6 +1761,7 @@ static struct ccwgroup_driver ctcm_group_driver = {
                .owner  = THIS_MODULE,
                .name   = CTC_DRIVER_NAME,
        },
+       .ccw_driver  = &ctcm_ccw_driver,
        .setup       = ctcm_probe_device,
        .remove      = ctcm_remove_device,
        .set_online  = ctcm_new_device,
index d01b5c2a77600e4d21ce7f74bc00baf5fde29184..0bf7b7356f10224579015676b08f52bee8e84772 100644 (file)
@@ -2396,6 +2396,7 @@ static struct ccwgroup_driver lcs_group_driver = {
                .owner  = THIS_MODULE,
                .name   = "lcs",
        },
+       .ccw_driver  = &lcs_ccw_driver,
        .setup       = lcs_probe_device,
        .remove      = lcs_remove_device,
        .set_online  = lcs_new_device,
index bae7440abc01e3560a987b39db440c375488a979..61cf3e9c0acb80683d60e27802b259a568b0a6ac 100644 (file)
@@ -5875,6 +5875,7 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
                .owner = THIS_MODULE,
                .name = "qeth",
        },
+       .ccw_driver = &qeth_ccw_driver,
        .setup = qeth_core_probe_device,
        .remove = qeth_core_remove_device,
        .set_online = qeth_core_set_online,