]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
scsi: Add buffer_aligned check pass-through
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Sun, 13 Aug 2023 23:50:00 +0000 (01:50 +0200)
committerTom Rini <trini@konsulko.com>
Tue, 22 Aug 2023 19:17:53 +0000 (15:17 -0400)
Some devices have limited DMA capabilities and require that the
buffers passed to them fit specific properties. Add new optional
callback which can be used at driver level to indicate whether a
buffer alignment is suitable for the device DMA or not. This is
a pass-through callback from block uclass to drivers.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
drivers/scsi/scsi.c
include/scsi.h

index 6498f998ad6e48cb0d5984e8fd927ce50b6f6ec8..7411660d465eb188b749a2d2b940bc77b5a995aa 100644 (file)
@@ -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) = {
index 9efefea99bb90b5fc7e5c24d3fa0a6d45389c494..ee9d622680d60a2541cc8152c5f006eebc86ae17 100644 (file)
@@ -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)