From f6ab5a92acc78371fc088075b64bd394d1f0d45f Mon Sep 17 00:00:00 2001 From: Simon Glass <sjg@chromium.org> Date: Wed, 14 Jun 2017 21:28:43 -0600 Subject: [PATCH] dm: scsi: Add operations for SCSI devices The SCSI uclass currently has no operations. It just uses the global SCSI functions. Fix this by adding operations to the only two drivers that use the uclass, and replacing the global functions with those defined locally in the SCSI code. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> --- drivers/ata/ahci.c | 7 +++++++ drivers/ata/dwc_ahci.c | 1 + drivers/ata/sata_ceva.c | 1 + drivers/scsi/scsi-uclass.c | 20 ++++++++++++++++++++ include/scsi.h | 28 +++++++++++++++++++++++----- 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 9c7b043aa2b..5a20b97c4b8 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1141,6 +1141,12 @@ static int ahci_scsi_bus_reset(struct udevice *dev) return 0; } +#ifdef CONFIG_DM_SCSI +struct scsi_ops scsi_ops = { + .exec = ahci_scsi_exec, + .bus_reset = ahci_scsi_bus_reset, +}; +#else int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) { return ahci_scsi_exec(dev, pccb); @@ -1152,3 +1158,4 @@ __weak int scsi_bus_reset(struct udevice *dev) return 0; } +#endif diff --git a/drivers/ata/dwc_ahci.c b/drivers/ata/dwc_ahci.c index 401201717f8..f6147989b1c 100644 --- a/drivers/ata/dwc_ahci.c +++ b/drivers/ata/dwc_ahci.c @@ -98,6 +98,7 @@ U_BOOT_DRIVER(dwc_ahci) = { .id = UCLASS_SCSI, .of_match = dwc_ahci_ids, .ofdata_to_platdata = dwc_ahci_ofdata_to_platdata, + .ops = &scsi_ops, .probe = dwc_ahci_probe, .priv_auto_alloc_size = sizeof(struct dwc_ahci_priv), .flags = DM_FLAG_ALLOC_PRIV_DMA, diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c index 7d61a546d75..d582e5ba80f 100644 --- a/drivers/ata/sata_ceva.c +++ b/drivers/ata/sata_ceva.c @@ -144,6 +144,7 @@ U_BOOT_DRIVER(ceva_host_blk) = { .name = "ceva_sata", .id = UCLASS_SCSI, .of_match = sata_ceva_ids, + .ops = &scsi_ops, .probe = sata_ceva_probe, .ofdata_to_platdata = sata_ceva_ofdata_to_platdata, }; diff --git a/drivers/scsi/scsi-uclass.c b/drivers/scsi/scsi-uclass.c index 40c5044f093..31e89992971 100644 --- a/drivers/scsi/scsi-uclass.c +++ b/drivers/scsi/scsi-uclass.c @@ -13,6 +13,26 @@ #include <dm.h> #include <scsi.h> +int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) +{ + struct scsi_ops *ops = scsi_get_ops(dev); + + if (!ops->exec) + return -ENOSYS; + + return ops->exec(dev, pccb); +} + +int scsi_bus_reset(struct udevice *dev) +{ + struct scsi_ops *ops = scsi_get_ops(dev); + + if (!ops->bus_reset) + return -ENOSYS; + + return ops->bus_reset(dev); +} + UCLASS_DRIVER(scsi) = { .id = UCLASS_SCSI, .name = "scsi", diff --git a/include/scsi.h b/include/scsi.h index 20f6932602b..9cdd13c795d 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -191,12 +191,25 @@ struct scsi_ops { int (*bus_reset)(struct udevice *dev); }; -#ifndef CONFIG_DM_SCSI -void scsi_low_level_init(int busdevfunc); -void scsi_init(void); -#endif +#define scsi_get_ops(dev) ((struct scsi_ops *)(dev)->driver->ops) + +extern struct scsi_ops scsi_ops; + +/** + * scsi_exec() - execute a command + * + * @dev: SCSI bus + * @cmd: Command to execute + * @return 0 if OK, -ve on error + */ +int scsi_exec(struct udevice *dev, struct scsi_cmd *cmd); -int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb); +/** + * scsi_bus_reset() - reset the bus + * + * @dev: SCSI bus to reset + * @return 0 if OK, -ve on error + */ int scsi_bus_reset(struct udevice *dev); /** @@ -206,6 +219,11 @@ int scsi_bus_reset(struct udevice *dev); */ int scsi_scan(bool verbose); +#ifndef CONFIG_DM_SCSI +void scsi_low_level_init(int busdevfunc); +void scsi_init(void); +#endif + #define SCSI_IDENTIFY 0xC0 /* not used */ /* Hardware errors */ -- GitLab