Skip to content

Commit

Permalink
scsi: Add buffer_aligned check pass-through
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Marek Vasut authored and trini committed Aug 22, 2023
1 parent 75191f7 commit 4f543e8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 0 deletions.
15 changes: 15 additions & 0 deletions drivers/scsi/scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) && \
Expand Down Expand Up @@ -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) = {
Expand Down
19 changes: 19 additions & 0 deletions include/scsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define _SCSI_H

#include <asm/cache.h>
#include <bouncebuf.h>
#include <linux/dma-direction.h>

/* Fix this to the maximum */
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 4f543e8

Please sign in to comment.