summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUwe Kleine-König <u.kleine-koenig@baylibre.com>2025-12-19 10:25:31 +0100
committerMartin K. Petersen <martin.petersen@oracle.com>2026-01-11 21:31:58 -0500
commitf7d4f1bf5724e52de049c619beddd53c62206624 (patch)
tree47062a5598c3dab5a676e4d0cb683e9cb7f80412
parent7d42bcea57ae139e2ed754425cc5fc44e260c890 (diff)
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 <u.kleine-koenig@baylibre.com> Reviewed-by: Peter Wang <peter.wang@mediatek.com> Reviewed-by: Bart Van Assche <bvanassche@acm.org> Link: https://patch.msgid.link/a54e363a3fd2054fb924afd7df44bca7f444b5f1.1766133330.git.u.kleine-koenig@baylibre.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/scsi_sysfs.c73
-rw-r--r--include/scsi/scsi_driver.h3
2 files changed, 74 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index db0ba68f2e6e..6b8c5c05f294 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 40aba9a9349a..249cea724abd 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 *);