From: Uwe Kleine-König Date: Fri, 19 Dec 2025 09:25:31 +0000 (+0100) Subject: scsi: core: sysfs: Make use of bus callbacks X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f7d4f1bf5724e52de049c619beddd53c62206624;p=thirdparty%2Fkernel%2Flinux.git scsi: core: sysfs: Make use of bus callbacks Introduce a bus-specific probe, remove and shutdown function. For now this only allows to get rid of a cast of the generic device to a SCSI device in the drivers and changes the remove prototype to return void---a non-zero return value is ignored anyhow. The objective is to get rid of users of struct device_driver callbacks .probe(), .remove() and .shutdown() to eventually remove these. Until all SCSI drivers are converted, this results in a runtime warning about the drivers needing an update because there is a bus probe function and a driver probe function. The in-tree drivers are fixed by the following commits. Signed-off-by: Uwe Kleine-König Reviewed-by: Peter Wang Reviewed-by: Bart Van Assche Link: https://patch.msgid.link/a54e363a3fd2054fb924afd7df44bca7f444b5f1.1766133330.git.u.kleine-koenig@baylibre.com Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index db0ba68f2e6e5..6b8c5c05f2944 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -554,10 +554,48 @@ static int scsi_bus_uevent(const struct device *dev, struct kobj_uevent_env *env return 0; } +static int scsi_bus_probe(struct device *dev) +{ + struct scsi_device *sdp = to_scsi_device(dev); + struct scsi_driver *drv = to_scsi_driver(dev->driver); + + if (drv->probe) + return drv->probe(sdp); + else + return 0; +} + +static void scsi_bus_remove(struct device *dev) +{ + struct scsi_device *sdp = to_scsi_device(dev); + struct scsi_driver *drv = to_scsi_driver(dev->driver); + + if (drv->remove) + drv->remove(sdp); +} + +static void scsi_bus_shutdown(struct device *dev) +{ + struct scsi_device *sdp = to_scsi_device(dev); + struct scsi_driver *drv; + + if (!dev->driver) + return; + + drv = to_scsi_driver(dev->driver); + + if (drv->shutdown) + drv->shutdown(sdp); +} + + const struct bus_type scsi_bus_type = { - .name = "scsi", - .match = scsi_bus_match, + .name = "scsi", + .match = scsi_bus_match, .uevent = scsi_bus_uevent, + .probe = scsi_bus_probe, + .remove = scsi_bus_remove, + .shutdown = scsi_bus_shutdown, #ifdef CONFIG_PM .pm = &scsi_bus_pm_ops, #endif @@ -1554,6 +1592,30 @@ restart: } EXPORT_SYMBOL(scsi_remove_target); +static int scsi_legacy_probe(struct scsi_device *sdp) +{ + struct device *dev = &sdp->sdev_gendev; + struct device_driver *driver = dev->driver; + + return driver->probe(dev); +} + +static void scsi_legacy_remove(struct scsi_device *sdp) +{ + struct device *dev = &sdp->sdev_gendev; + struct device_driver *driver = dev->driver; + + driver->remove(dev); +} + +static void scsi_legacy_shutdown(struct scsi_device *sdp) +{ + struct device *dev = &sdp->sdev_gendev; + struct device_driver *driver = dev->driver; + + driver->shutdown(dev); +} + int __scsi_register_driver(struct scsi_driver *sdrv, struct module *owner) { struct device_driver *drv = &sdrv->gendrv; @@ -1561,6 +1623,13 @@ int __scsi_register_driver(struct scsi_driver *sdrv, struct module *owner) drv->bus = &scsi_bus_type; drv->owner = owner; + if (!sdrv->probe && drv->probe) + sdrv->probe = scsi_legacy_probe; + if (!sdrv->remove && drv->remove) + sdrv->remove = scsi_legacy_remove; + if (!sdrv->shutdown && drv->shutdown) + sdrv->shutdown = scsi_legacy_shutdown; + return driver_register(drv); } EXPORT_SYMBOL(__scsi_register_driver); diff --git a/include/scsi/scsi_driver.h b/include/scsi/scsi_driver.h index 40aba9a9349a6..249cea724abd1 100644 --- a/include/scsi/scsi_driver.h +++ b/include/scsi/scsi_driver.h @@ -12,6 +12,9 @@ struct request; struct scsi_driver { struct device_driver gendrv; + int (*probe)(struct scsi_device *); + void (*remove)(struct scsi_device *); + void (*shutdown)(struct scsi_device *); int (*resume)(struct device *); void (*rescan)(struct device *); blk_status_t (*init_command)(struct scsi_cmnd *);