diff options
| author | Tom Rini <[email protected]> | 2022-09-25 17:20:11 -0400 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2022-09-25 17:20:11 -0400 |
| commit | 9114b7cee817789ad59e0fb6d5cd57f50668b4e1 (patch) | |
| tree | a6bd3d83314fee80b1b1a2e9a39df39d96a2dcc8 /include | |
| parent | 81da5042e514bfd27516d3530dde4d62a6708ca4 (diff) | |
| parent | 22c80d5603ac4c58debc8c776b8f138e76cf5f7c (diff) | |
Merge tag 'dm-next-25sep22' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm into next
sandbox SCSI conversion to driver model
final patch for blk improvements
Diffstat (limited to 'include')
| -rw-r--r-- | include/blk.h | 122 | ||||
| -rw-r--r-- | include/efi_loader.h | 4 | ||||
| -rw-r--r-- | include/scsi.h | 126 | ||||
| -rw-r--r-- | include/scsi_emul.h | 70 |
4 files changed, 240 insertions, 82 deletions
diff --git a/include/blk.h b/include/blk.h index 279f9ea4a9d..8806c382d4e 100644 --- a/include/blk.h +++ b/include/blk.h @@ -54,7 +54,7 @@ struct blk_desc { * TODO: With driver model we should be able to use the parent * device's uclass instead. */ - enum uclass_id if_type; /* type of the interface */ + enum uclass_id uclass_id; /* type of the interface */ int devnum; /* device number */ unsigned char part_type; /* partition type */ unsigned char target; /* target SCSI ID */ @@ -114,7 +114,7 @@ int blkcache_init(void); /** * blkcache_read() - attempt to read a set of blocks from cache * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type * @param start - starting block number * @param blkcnt - number of blocks to read @@ -131,7 +131,7 @@ int blkcache_read(int iftype, int dev, * blkcache_fill() - make data read from a block device available * to the block cache * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type * @param start - starting block number * @param blkcnt - number of blocks available @@ -147,7 +147,7 @@ void blkcache_fill(int iftype, int dev, * blkcache_invalidate() - discard the cache for a set of blocks * because of a write or device (re)initialization. * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type */ void blkcache_invalidate(int iftype, int dev); @@ -279,22 +279,22 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, * This function does not activate the device. The device will be returned * whether or not it is activated. * - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value */ -int blk_find_device(int if_type, int devnum, struct udevice **devp); +int blk_find_device(int uclass_id, int devnum, struct udevice **devp); /** * blk_get_device() - Find and probe a block device ready for use * - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value */ -int blk_get_device(int if_type, int devnum, struct udevice **devp); +int blk_get_device(int uclass_id, int devnum, struct udevice **devp); /** * blk_first_device() - Find the first device for a given interface @@ -305,7 +305,7 @@ int blk_get_device(int if_type, int devnum, struct udevice **devp); * @devp: the device, if found * Return: 0 if found, -ENODEV if no device, or other -ve error value */ -int blk_first_device(int if_type, struct udevice **devp); +int blk_first_device(int uclass_id, struct udevice **devp); /** * blk_next_device() - Find the next device for a given interface @@ -327,7 +327,7 @@ int blk_next_device(struct udevice **devp); * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -335,7 +335,7 @@ int blk_next_device(struct udevice **devp); * @devp: the new device (which has not been probed) */ int blk_create_device(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp); /** @@ -344,7 +344,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device (parent name is prepended) - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -352,7 +352,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @devp: the new device (which has not been probed) */ int blk_create_devicef(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp); /** @@ -372,33 +372,33 @@ int blk_probe_or_unbind(struct udevice *dev); * * The devices are removed and then unbound. * - * @if_type: Interface type to unbind + * @uclass_id: Interface type to unbind * Return: 0 if OK, -ve on error */ -int blk_unbind_all(int if_type); +int blk_unbind_all(int uclass_id); /** * blk_find_max_devnum() - find the maximum device number for an interface type * - * Finds the last allocated device number for an interface type @if_type. The + * Finds the last allocated device number for an interface type @uclass_id. The * next number is safe to use for a newly allocated device. * - * @if_type: Interface type to scan + * @uclass_id: Interface type to scan * Return: maximum device number found, or -ENODEV if none, or other -ve on * error */ -int blk_find_max_devnum(enum uclass_id if_type); +int blk_find_max_devnum(enum uclass_id uclass_id); /** * blk_next_free_devnum() - get the next device number for an interface type * * Finds the next number that is safe to use for a newly allocated device for - * an interface type @if_type. + * an interface type @uclass_id. * - * @if_type: Interface type to scan + * @uclass_id: Interface type to scan * Return: next device number safe to use, or -ve on error */ -int blk_next_free_devnum(enum uclass_id if_type); +int blk_next_free_devnum(enum uclass_id uclass_id); /** * blk_select_hwpart() - select a hardware partition @@ -447,7 +447,7 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, void *buffer) { ulong blks_read; - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer)) return blkcnt; @@ -458,7 +458,7 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, */ blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -467,14 +467,14 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *buffer) { - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return block_dev->block_write(block_dev, start, blkcnt, buffer); } static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) { - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return block_dev->block_erase(block_dev, start, blkcnt); } @@ -485,15 +485,15 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, * driver should be provided using U_BOOT_LEGACY_BLK() for each interface * type that is to be supported. * - * @if_typename: Interface type name - * @if_type: Interface type + * @uclass_idname: Interface type name + * @uclass_id: Interface type * @max_devs: Maximum number of devices supported * @desc: Pointer to list of devices for this interface type, * or NULL to use @get_dev() instead */ struct blk_driver { - const char *if_typename; - enum uclass_id if_type; + const char *uclass_idname; + enum uclass_id uclass_id; int max_devs; struct blk_desc *desc; /** @@ -540,33 +540,33 @@ struct blk_driver { #define U_BOOT_LEGACY_BLK(__name) \ ll_entry_declare(struct blk_driver, __name, blk_driver) -struct blk_driver *blk_driver_lookup_type(int if_type); +struct blk_driver *blk_driver_lookup_type(int uclass_id); #endif /* !CONFIG_BLK */ /** - * blk_get_devnum_by_typename() - Get a block device by type and number + * blk_get_devnum_by_uclass_idname() - Get a block device by type and number * * This looks through the available block devices of the given type, returning * the one with the given @devnum. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum); +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum); /** - * blk_get_devnum_by_type() - Get a block device by type name, and number + * blk_get_devnum_by_uclass_id() - Get a block device by type name, and number * - * This looks up the block device type based on @if_typename, then calls - * blk_get_devnum_by_type(). + * This looks up the block device type based on @uclass_idname, then calls + * blk_get_devnum_by_uclass_id(). * - * @if_typename: Block device type name + * @uclass_idname: Block device type name * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum); /** @@ -585,34 +585,34 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart); /** * blk_list_part() - list the partitions for block devices of a given type * - * This looks up the partition type for each block device of type @if_type, + * This looks up the partition type for each block device of type @uclass_id, * then displays a list of partitions. * - * @if_type: Block device type + * @uclass_id: Block device type * Return: 0 if OK, -ENODEV if there is none of that type */ -int blk_list_part(enum uclass_id if_type); +int blk_list_part(enum uclass_id uclass_id); /** * blk_list_devices() - list the block devices of a given type * - * This lists each block device of the type @if_type, showing the capacity + * This lists each block device of the type @uclass_id, showing the capacity * as well as type-specific information. * - * @if_type: Block device type + * @uclass_id: Block device type */ -void blk_list_devices(enum uclass_id if_type); +void blk_list_devices(enum uclass_id uclass_id); /** * blk_show_device() - show information about a given block device * * This shows the block device capacity as well as type-specific information. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number */ -int blk_show_device(enum uclass_id if_type, int devnum); +int blk_show_device(enum uclass_id uclass_id, int devnum); /** * blk_print_device_num() - show information about a given block device @@ -620,45 +620,45 @@ int blk_show_device(enum uclass_id if_type, int devnum); * This is similar to blk_show_device() but returns an error if the block * device type is unknown. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block * device is not connected */ -int blk_print_device_num(enum uclass_id if_type, int devnum); +int blk_print_device_num(enum uclass_id uclass_id, int devnum); /** * blk_print_part_devnum() - print the partition information for a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if * the interface type is not supported, other -ve on other error */ -int blk_print_part_devnum(enum uclass_id if_type, int devnum); +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum); /** * blk_read_devnum() - read blocks from a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @blkcnt: Number of blocks to read * @buffer: Address to write data to * Return: number of blocks read, or -ve error number on error */ -ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer); /** * blk_write_devnum() - write blocks to a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @blkcnt: Number of blocks to write * @buffer: Address to read data from * Return: number of blocks written, or -ve error number on error */ -ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer); /** @@ -667,31 +667,31 @@ ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, * This is similar to blk_dselect_hwpart() but it looks up the interface and * device number. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @hwpart: Partition number to select * Return: 0 if OK, -ve on error */ -int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart); +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart); /** - * blk_get_if_type_name() - Get the name of an interface type + * blk_get_uclass_name() - Get the name of an interface type * - * @if_type: Interface type to check + * @uclass_id: Interface type to check * Return: name of interface, or NULL if none */ -const char *blk_get_if_type_name(enum uclass_id if_type); +const char *blk_get_uclass_name(enum uclass_id uclass_id); /** * blk_common_cmd() - handle common commands with block devices * * @args: Number of arguments to the command (argv[0] is the command itself) * @argv: Command arguments - * @if_type: Interface type + * @uclass_id: Interface type * @cur_devnump: Current device number for this interface type * Return: 0 if OK, CMD_RET_ERROR on error */ -int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id, int *cur_devnump); enum blk_flag_t { diff --git a/include/efi_loader.h b/include/efi_loader.h index 7554f3b7dbc..ad01395b39c 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -161,7 +161,7 @@ extern bool efi_st_keep_devices; /* EFI system partition */ extern struct efi_system_partition { - enum uclass_id if_type; + enum uclass_id uclass_id; int devnum; u8 part; } efi_system_partition; @@ -562,7 +562,7 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, struct efi_loaded_image *loaded_image_info); /* Create handles and protocols for the partitions of a block device */ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, - const char *if_typename, int diskid, + const char *uclass_idname, int diskid, const char *pdevname); /* Called by bootefi to make GOP (graphical) interface available */ efi_status_t efi_gop_register(void); diff --git a/include/scsi.h b/include/scsi.h index b47c7463c1d..94e1d8ccb28 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -15,27 +15,47 @@ struct udevice; +/** + * struct scsi_cmd - information about a SCSI command to be processed + * + * @cmd: command + * @sense_buf: for request sense + * @status: SCSI Status + * @target: Target ID + * @lun: Target LUN + * @cmdlen: command len + * @datalen: Total data length + * @pdata: pointer to data + * @msgout: Messge out buffer (NOT USED) + * @msgin: Message in buffer + * @sensecmdlen: Sense command len + * @sensedatalen: Sense data len + * @sensecmd: Sense command + * @contr_stat: Controller Status + * @trans_bytes: tranfered bytes + * @priv: Private value + * @dma_dir: Direction of data structure + */ struct scsi_cmd { - unsigned char cmd[16]; /* command */ - /* for request sense */ - unsigned char sense_buf[64] + unsigned char cmd[16]; + unsigned char sense_buf[64] __attribute__((aligned(ARCH_DMA_MINALIGN))); - unsigned char status; /* SCSI Status */ - unsigned char target; /* Target ID */ - unsigned char lun; /* Target LUN */ - unsigned char cmdlen; /* command len */ - unsigned long datalen; /* Total data length */ - unsigned char * pdata; /* pointer to data */ - unsigned char msgout[12]; /* Messge out buffer (NOT USED) */ - unsigned char msgin[12]; /* Message in buffer */ - unsigned char sensecmdlen; /* Sense command len */ - unsigned long sensedatalen; /* Sense data len */ - unsigned char sensecmd[6]; /* Sense command */ - unsigned long contr_stat; /* Controller Status */ - unsigned long trans_bytes; /* tranfered bytes */ - - unsigned int priv; - enum dma_data_direction dma_dir; + unsigned char status; + unsigned char target; + unsigned char lun; + unsigned char cmdlen; + unsigned long datalen; + unsigned char *pdata; + unsigned char msgout[12]; + unsigned char msgin[12]; + unsigned char sensecmdlen; + unsigned long sensedatalen; + unsigned char sensecmd[6]; + unsigned long contr_stat; + unsigned long trans_bytes; + + unsigned int priv; + enum dma_data_direction dma_dir; }; /*----------------------------------------------------------- @@ -168,6 +188,74 @@ struct scsi_cmd { #define SCSI_WRITE_SAME 0x41 /* Write Same (O) */ /** + * enum scsi_cmd_phase - current phase of the SCSI protocol + * + * @SCSIPH_START: Start phase + * @SCSIPH_DATA: Data phase + * @SCSIPH_STATUS: Status phase + */ +enum scsi_cmd_phase { + SCSIPH_START, + SCSIPH_DATA, + SCSIPH_STATUS, +}; + +/** + * struct scsi_inquiry_resp - holds a SCSI inquiry command + * + * @type; command type + * @flags; command flags + * @version; command version + * @data_format; data format + * @additional_len; additional data length + * @spare[3]; spare bytes + * @vendor[8]; vendor information + * @product[16]; production information + * @revision[4]; revision information + */ +struct scsi_inquiry_resp { + u8 type; + u8 flags; + u8 version; + u8 data_format; + u8 additional_len; + u8 spare[3]; + char vendor[8]; + char product[16]; + char revision[4]; +}; + +/** + * struct scsi_read_capacity_resp - holds the response to a read-capacity cmd + * + * @last_block_addr: Logical block address of last block + * @block_len: Length of each block in bytes + */ +struct scsi_read_capacity_resp { + u32 last_block_addr; + u32 block_len; +}; + +/** + * struct scsi_read10_req - holds a SCSI READ10 request + * + * @cmd; command type + * @lun_flags; LUN flags + * @lba; Logical block address to start reading from + * @spare; spare bytes + * @xfer_len: number of blocks to read + * @spare2: more spare bytes + */ +struct __packed scsi_read10_req { + u8 cmd; + u8 lun_flags; + u32 lba; + u8 spare; + u16 xfer_len; + u8 spare2[3]; +}; + +/** * struct scsi_plat - stores information about SCSI controller * * @base: Controller base address diff --git a/include/scsi_emul.h b/include/scsi_emul.h new file mode 100644 index 00000000000..13c3f860b40 --- /dev/null +++ b/include/scsi_emul.h @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Emulation of enough SCSI commands to find and read from a unit + * + * Copyright 2022 Google LLC + * Written by Simon Glass <[email protected]> + * + * implementations of SCSI functions required so that CONFIG_SCSI can be enabled + * for sandbox + */ + +#ifndef __scsi_emul_h +#define __scsi_emul_h + +/** + * struct scsi_emul_info - information for emulating a SCSI device + * + * @vendor: Vendor name + * @product: Product name + * @block_size: Block size of device in bytes (normally 512) + * @file_size: Size of the backing file for this emulator, in bytes + * @seek_block: Seek position for file (block number) + * + * @phase: Current SCSI phase + * @buff_used: Number of bytes ready to transfer back to host + * @read_len: Number of bytes of data left in the current read command + * @alloc_len: Allocation length from the last incoming command + * @transfer_len: Transfer length from CBW header + * @buff: Data buffer for outgoing data + */ +struct scsi_emul_info { + /* provided by the caller: */ + void *buff; + const char *vendor; + const char *product; + int block_size; + loff_t file_size; + int seek_block; + + /* state maintained by the emulator: */ + enum scsi_cmd_phase phase; + int buff_used; + int read_len; + uint seek_pos; + int alloc_len; + uint transfer_len; +}; + +/* Indicates that a read is being started */ +#define SCSI_EMUL_DO_READ 1 + +/** + * sb_scsi_emul_command() - Process a SCSI command + * + * This sets up the response in info->buff and updates various other values + * in info. + * + * If SCSI_EMUL_DO_READ is returned then the caller should set up so that the + * backing file can be read, or return an error status if there is no file. + * + * @info: Emulation information + * @req: Request to process + * @len: Length of request in bytes + * @return SCSI_EMUL_DO_READ if a read has started, 0 if some other operation + * has started, -ve if there was an error + */ +int sb_scsi_emul_command(struct scsi_emul_info *info, + const struct scsi_cmd *req, int len); + +#endif |
