diff options
-rw-r--r-- | drivers/scsi/scsi.c | 15 | ||||
-rw-r--r-- | include/scsi.h | 19 |
2 files changed, 34 insertions, 0 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 6498f998ad6..7411660d465 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -274,6 +274,18 @@ static ulong scsi_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, __func__, start, smallblks, buf_addr); return blkcnt; } + +#if IS_ENABLED(CONFIG_BOUNCE_BUFFER) +static int scsi_buffer_aligned(struct udevice *dev, struct bounce_buffer *state) +{ + struct scsi_ops *ops = scsi_get_ops(dev->parent); + + if (ops->buffer_aligned) + return ops->buffer_aligned(dev->parent, state); + + return 1; +} +#endif /* CONFIG_BOUNCE_BUFFER */ #endif #if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) && \ @@ -720,6 +732,9 @@ int scsi_scan(bool verbose) static const struct blk_ops scsi_blk_ops = { .read = scsi_read, .write = scsi_write, +#if IS_ENABLED(CONFIG_BOUNCE_BUFFER) + .buffer_aligned = scsi_buffer_aligned, +#endif /* CONFIG_BOUNCE_BUFFER */ }; U_BOOT_DRIVER(scsi_blk) = { diff --git a/include/scsi.h b/include/scsi.h index 9efefea99bb..ee9d622680d 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -7,6 +7,7 @@ #define _SCSI_H #include <asm/cache.h> +#include <bouncebuf.h> #include <linux/dma-direction.h> /* Fix this to the maximum */ @@ -298,6 +299,24 @@ struct scsi_ops { * @return 0 if OK, -ve on error */ int (*bus_reset)(struct udevice *dev); + +#if IS_ENABLED(CONFIG_BOUNCE_BUFFER) + /** + * buffer_aligned() - test memory alignment of block operation buffer + * + * Some devices have limited DMA capabilities and require that the + * buffers passed to them fit specific properties. This optional + * callback can be used to indicate whether a buffer alignment is + * suitable for the device DMA or not, and trigger use of generic + * bounce buffer implementation to help use of unsuitable buffers + * at the expense of performance degradation. + * + * @dev: Block device associated with the request + * @state: Bounce buffer state + * @return 1 if OK, 0 if unaligned + */ + int (*buffer_aligned)(struct udevice *dev, struct bounce_buffer *state); +#endif /* CONFIG_BOUNCE_BUFFER */ }; #define scsi_get_ops(dev) ((struct scsi_ops *)(dev)->driver->ops) |