sandbox SCSI conversion to driver model

final patch for blk improvements
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCgAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmMws50RHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIreYM4ggAk6Zljtm3UfpW5RFdUGQ+hsy5dAAAJIpp
 nXGXCCtpS055XE3FkWGX6huO+/5awsr1HiB2hoTQc5/ySg147CRqETulaDqMkaBZ
 0ybqYko2o9kWmlCV7DSPFDyMr4rf/vD8FOblQnLVjkimcMBEufJba+bYhUcfA5Tg
 BM+l9QX1OXjCht6apKPRM+WuKgsxd+qthdAZigjQ0KEVS3SblEbJLDXoYJPhkW8g
 5gLBs8IMPfrgfIeuSN5s0t+wLnhxrQWqdSr59zjh/cR2FmYC+0+woK3peCZJULmS
 KkKQWuhlWrj12n1RHFwZ8hCNpIaiEOvGR2Urk7GplnZvda/+4Dg/gA==
 =AcpT
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Tom Rini 2022-09-25 17:20:11 -04:00
commit 9114b7cee8
48 changed files with 766 additions and 405 deletions

View file

@ -166,7 +166,6 @@ config SANDBOX
imply CMD_IO
imply CMD_IOTRACE
imply CMD_LZMADEC
imply CMD_SATA
imply CMD_SF
imply CMD_SF_TEST
imply CRC32_VERIFY

View file

@ -1017,8 +1017,24 @@ void *os_find_text_base(void)
return base;
}
/**
* os_unblock_signals() - unblock all signals
*
* If we are relaunching the sandbox in a signal handler, we have to unblock
* the respective signal before calling execv(). See signal(7) man-page.
*/
static void os_unblock_signals(void)
{
sigset_t sigs;
sigfillset(&sigs);
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
}
void os_relaunch(char *argv[])
{
os_unblock_signals();
execv(argv[0], argv);
os_exit(1);
}

View file

@ -245,6 +245,10 @@
compatible = "sandbox,sandbox-rng";
};
scsi {
compatible = "sandbox,scsi";
};
sound {
compatible = "sandbox,sound";
cpu {

View file

@ -1158,6 +1158,11 @@
backlight = <&backlight 0 100>;
};
scsi {
compatible = "sandbox,scsi";
sandbox,filepath = "scsi.img";
};
smem@0 {
compatible = "sandbox,smem";
};

View file

@ -37,7 +37,7 @@ static void board_get_alt_info_mmc(struct udevice *dev, char *buf)
if (!desc)
return;
name = blk_get_if_type_name(desc->if_type);
name = blk_get_uclass_name(desc->uclass_id);
devnum = desc->devnum;
len = strlen(buf);

View file

@ -122,7 +122,7 @@ static int __bcb_load(int devnum, const char *partp)
char *endp;
int part, ret;
desc = blk_get_devnum_by_type(UCLASS_MMC, devnum);
desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, devnum);
if (!desc) {
ret = -ENODEV;
goto err_read_fail;
@ -287,7 +287,7 @@ static int __bcb_store(void)
u64 cnt;
int ret;
desc = blk_get_devnum_by_type(UCLASS_MMC, bcb_dev);
desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, bcb_dev);
if (!desc) {
ret = -ENODEV;
goto err;

View file

@ -12,10 +12,10 @@
#include <blk.h>
#include <command.h>
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)
{
const char *if_name = blk_get_if_type_name(if_type);
const char *if_name = blk_get_uclass_name(uclass_id);
switch (argc) {
case 0:
@ -23,16 +23,16 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
return CMD_RET_USAGE;
case 2:
if (strncmp(argv[1], "inf", 3) == 0) {
blk_list_devices(if_type);
blk_list_devices(uclass_id);
return 0;
} else if (strncmp(argv[1], "dev", 3) == 0) {
if (blk_print_device_num(if_type, *cur_devnump)) {
if (blk_print_device_num(uclass_id, *cur_devnump)) {
printf("\nno %s devices available\n", if_name);
return CMD_RET_FAILURE;
}
return 0;
} else if (strncmp(argv[1], "part", 4) == 0) {
if (blk_list_part(if_type))
if (blk_list_part(uclass_id))
printf("\nno %s partition table available\n",
if_name);
return 0;
@ -42,7 +42,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
if (strncmp(argv[1], "dev", 3) == 0) {
int dev = (int)dectoul(argv[2], NULL);
if (!blk_show_device(if_type, dev)) {
if (!blk_show_device(uclass_id, dev)) {
*cur_devnump = dev;
printf("... is now current device\n");
} else {
@ -52,7 +52,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
} else if (strncmp(argv[1], "part", 4) == 0) {
int dev = (int)dectoul(argv[2], NULL);
if (blk_print_part_devnum(if_type, dev)) {
if (blk_print_part_devnum(uclass_id, dev)) {
printf("\n%s device %d not available\n",
if_name, dev);
return CMD_RET_FAILURE;
@ -71,7 +71,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
printf("\n%s read: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
n = blk_read_devnum(if_type, *cur_devnump, blk, cnt,
n = blk_read_devnum(uclass_id, *cur_devnump, blk, cnt,
(ulong *)addr);
printf("%ld blocks read: %s\n", n,
@ -86,7 +86,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type,
printf("\n%s write: device %d block # "LBAFU", count %lu ... ",
if_name, *cur_devnump, blk, cnt);
n = blk_write_devnum(if_type, *cur_devnump, blk, cnt,
n = blk_write_devnum(uclass_id, *cur_devnump, blk, cnt,
(ulong *)addr);
printf("%ld blocks written: %s\n", n,

View file

@ -36,7 +36,7 @@ static int do_lsblk(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv
continue;
desc = dev_get_uclass_plat(udev);
printf("%c %s %u", i ? ',' : ':',
blk_get_if_type_name(desc->if_type),
blk_get_uclass_name(desc->uclass_id),
desc->devnum);
i++;
}

View file

@ -154,7 +154,7 @@ static struct mmc *__init_mmc_device(int dev, bool force_init,
#ifdef CONFIG_BLOCK_CACHE
struct blk_desc *bd = mmc_get_blk_desc(mmc);
blkcache_invalidate(bd->if_type, bd->devnum);
blkcache_invalidate(bd->uclass_id, bd->devnum);
#endif
return mmc;
@ -530,7 +530,7 @@ static int do_mmc_part(struct cmd_tbl *cmdtp, int flag,
if (!mmc)
return CMD_RET_FAILURE;
mmc_dev = blk_get_devnum_by_type(UCLASS_MMC, curr_device);
mmc_dev = blk_get_devnum_by_uclass_id(UCLASS_MMC, curr_device);
if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) {
part_print(mmc_dev);
return CMD_RET_SUCCESS;

View file

@ -71,7 +71,7 @@ static int spl_sata_load_image(struct spl_image_info *spl_image,
/* try to recognize storage devices immediately */
scsi_scan(false);
stor_dev = blk_get_devnum_by_type(UCLASS_SCSI, 0);
stor_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0);
if (!stor_dev)
return -ENODEV;

View file

@ -41,7 +41,7 @@ int spl_usb_load(struct spl_image_info *spl_image,
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
stor_dev = blk_get_devnum_by_type(UCLASS_USB, usb_stor_curr_dev);
stor_dev = blk_get_devnum_by_uclass_id(UCLASS_USB, usb_stor_curr_dev);
if (!stor_dev)
return -ENODEV;

View file

@ -279,7 +279,7 @@ static int usb_stor_probe_device(struct usb_device *udev)
blkdev = &usb_dev_desc[usb_max_devs];
memset(blkdev, '\0', sizeof(struct blk_desc));
blkdev->if_type = UCLASS_USB;
blkdev->uclass_id = UCLASS_USB;
blkdev->devnum = usb_max_devs;
blkdev->part_type = PART_TYPE_UNKNOWN;
blkdev->target = 0xff;
@ -1577,8 +1577,8 @@ U_BOOT_DRIVER(usb_storage_blk) = {
};
#else
U_BOOT_LEGACY_BLK(usb) = {
.if_typename = "usb",
.if_type = UCLASS_USB,
.uclass_idname = "usb",
.uclass_id = UCLASS_USB,
.max_devs = USB_MAX_STOR_DEV,
.desc = usb_dev_desc,
};

View file

@ -104,7 +104,6 @@ CONFIG_DEVRES=y
CONFIG_DEBUG_DEVRES=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@ -203,6 +202,8 @@ CONFIG_DM_RESET=y
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_RTC_RV8803=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SMEM=y
CONFIG_SANDBOX_SMEM=y

View file

@ -137,7 +137,6 @@ CONFIG_DEBUG_DEVRES=y
CONFIG_SIMPLE_PM_BUS=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@ -264,9 +263,7 @@ CONFIG_RESET_SCMI=y
CONFIG_DM_RTC=y
CONFIG_RTC_RV8803=y
CONFIG_SCSI=y
CONFIG_SCSI_AHCI_PLAT=y
CONFIG_SYS_SCSI_MAX_SCSI_ID=8
CONFIG_SYS_SCSI_MAX_LUN=4
CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SMEM=y
CONFIG_SANDBOX_SMEM=y

View file

@ -85,7 +85,6 @@ CONFIG_DEVRES=y
CONFIG_DEBUG_DEVRES=y
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_CLK=y
@ -174,6 +173,8 @@ CONFIG_REMOTEPROC_SANDBOX=y
CONFIG_DM_RESET=y
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y

View file

@ -108,7 +108,6 @@ CONFIG_DEBUG_DEVRES=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@ -200,6 +199,8 @@ CONFIG_DM_RESET=y
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_SPL_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y

View file

@ -109,7 +109,6 @@ CONFIG_DEBUG_DEVRES=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SYS_IDE_MAXBUS=1
@ -203,6 +202,8 @@ CONFIG_DM_RESET=y
CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_SPL_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y

View file

@ -124,7 +124,6 @@ CONFIG_DEBUG_DEVRES=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_ADC=y
CONFIG_ADC_SANDBOX=y
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_CLK=y
@ -209,6 +208,8 @@ CONFIG_SANDBOX_RESET=y
CONFIG_DM_RTC=y
CONFIG_SPL_DM_RTC=y
CONFIG_TPL_DM_RTC=y
CONFIG_SCSI=y
CONFIG_DM_SCSI=y
CONFIG_SANDBOX_SERIAL=y
CONFIG_SOUND=y
CONFIG_SOUND_SANDBOX=y

View file

@ -18,7 +18,6 @@ CONFIG_OF_CONTROL=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
# CONFIG_NET is not set
# CONFIG_ACPIGEN is not set
CONFIG_SYS_SATA_MAX_DEVICE=2
CONFIG_AXI=y
CONFIG_AXI_SANDBOX=y
CONFIG_SANDBOX_GPIO=y

View file

@ -191,12 +191,12 @@ unsigned long dev_read(struct udevice *dev, lbaint_t start,
start_in_disk += part->gpt_part_info.start;
}
if (blkcache_read(block_dev->if_type, block_dev->devnum,
if (blkcache_read(block_dev->uclass_id, block_dev->devnum,
start_in_disk, blkcnt, block_dev->blksz, buffer))
return blkcnt;
blks_read = ops->read(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_in_disk, blkcnt, block_dev->blksz, buffer);
return blks_read;
@ -216,7 +216,7 @@ unsigned long dev_write(struct udevice *dev, lbaint_t start,
if (!ops->write)
return -ENOSYS;
blkcache_invalidate(block_dev->if_type, block_dev->devnum);
blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->write(dev, start, blkcnt, buffer);
}
@ -235,7 +235,7 @@ unsigned long dev_erase(struct udevice *dev, lbaint_t start,
if (!ops->erase)
return -ENOSYS;
blkcache_invalidate(block_dev->if_type, block_dev->devnum);
blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->erase(dev, start, blkcnt);
}

View file

@ -61,7 +61,7 @@ static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
if (!blk_enabled())
return NULL;
dev_desc = blk_get_devnum_by_typename(ifname, dev);
dev_desc = blk_get_devnum_by_uclass_idname(ifname, dev);
if (!dev_desc) {
debug("%s: No device for iface '%s', dev %d\n", __func__,
ifname, dev);
@ -120,7 +120,7 @@ void dev_print(struct blk_desc *dev_desc)
return;
}
switch (dev_desc->if_type) {
switch (dev_desc->uclass_id) {
case UCLASS_SCSI:
printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
dev_desc->target,dev_desc->lun,
@ -155,7 +155,7 @@ void dev_print(struct blk_desc *dev_desc)
puts("device type unknown\n");
return;
default:
printf("Unhandled device type: %i\n", dev_desc->if_type);
printf("Unhandled device type: %i\n", dev_desc->uclass_id);
return;
}
puts (" Type: ");
@ -225,7 +225,7 @@ void part_init(struct blk_desc *dev_desc)
const int n_ents = ll_entry_count(struct part_driver, part_driver);
struct part_driver *entry;
blkcache_invalidate(dev_desc->if_type, dev_desc->devnum);
blkcache_invalidate(dev_desc->uclass_id, dev_desc->devnum);
dev_desc->part_type = PART_TYPE_UNKNOWN;
for (entry = drv; entry != drv + n_ents; entry++) {
@ -248,7 +248,7 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc)
CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
CONFIG_IS_ENABLED(EFI_PARTITION)
puts ("\nPartition Map for ");
switch (dev_desc->if_type) {
switch (dev_desc->uclass_id) {
case UCLASS_IDE:
puts ("IDE");
break;
@ -408,7 +408,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
* Always should be done, otherwise hw partition 0 will return
* stale data after displaying a non-zero hw partition.
*/
if ((*dev_desc)->if_type == UCLASS_MMC)
if ((*dev_desc)->uclass_id == UCLASS_MMC)
part_init(*dev_desc);
}
@ -762,7 +762,7 @@ void part_set_generic_name(const struct blk_desc *dev_desc,
{
char *devtype;
switch (dev_desc->if_type) {
switch (dev_desc->uclass_id) {
case UCLASS_IDE:
case UCLASS_AHCI:
devtype = "hd";

View file

@ -20,7 +20,7 @@ generic syntax.
interface
The interface used to access the partition's device, like ``mmc`` or
``scsi``. For a full list of supported interfaces, consult the
``if_typename_str`` array in ``drivers/block/blk-uclass.c``
``uclass_idname_str`` array in ``drivers/block/blk-uclass.c``
devnum
The device number. This defaults to 0.

View file

@ -79,7 +79,7 @@ int __sata_initialize(void)
for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) {
memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc));
sata_dev_desc[i].if_type = UCLASS_AHCI;
sata_dev_desc[i].uclass_id = UCLASS_AHCI;
sata_dev_desc[i].devnum = i;
sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
sata_dev_desc[i].type = DEV_TYPE_HARDDISK;

View file

@ -20,7 +20,7 @@
static struct {
enum uclass_id id;
const char *name;
} if_typename_str[] = {
} uclass_idname_str[] = {
{ UCLASS_IDE, "ide" },
{ UCLASS_SCSI, "scsi" },
{ UCLASS_USB, "usb" },
@ -34,19 +34,19 @@ static struct {
{ UCLASS_PVBLOCK, "pvblock" },
};
static enum uclass_id if_typename_to_iftype(const char *if_typename)
static enum uclass_id uclass_name_to_iftype(const char *uclass_idname)
{
int i;
for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) {
if (!strcmp(if_typename, if_typename_str[i].name))
return if_typename_str[i].id;
for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) {
if (!strcmp(uclass_idname, uclass_idname_str[i].name))
return uclass_idname_str[i].id;
}
return UCLASS_INVALID;
}
static enum uclass_id if_type_to_uclass_id(enum uclass_id if_type)
static enum uclass_id conv_uclass_id(enum uclass_id uclass_id)
{
/*
* This strange adjustment is used because we use UCLASS_MASS_STORAGE
@ -65,31 +65,30 @@ static enum uclass_id if_type_to_uclass_id(enum uclass_id if_type)
* - rename UCLASS_USB name to "usb_ctlr"
* - use UCLASS_MASS_STORAGE instead of UCLASS_USB in if_typename_str
*/
if (if_type == UCLASS_USB)
if (uclass_id == UCLASS_USB)
return UCLASS_MASS_STORAGE;
return if_type;
return uclass_id;
}
const char *blk_get_if_type_name(enum uclass_id if_type)
const char *blk_get_uclass_name(enum uclass_id uclass_id)
{
int i;
for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) {
if (if_typename_str[i].id == if_type)
return if_typename_str[i].name;
for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) {
if (uclass_idname_str[i].id == uclass_id)
return uclass_idname_str[i].name;
}
return "(none)";
}
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)
{
struct blk_desc *desc;
struct udevice *dev;
int ret;
ret = blk_get_device(if_type, devnum, &dev);
ret = blk_get_device(uclass_id, devnum, &dev);
if (ret)
return NULL;
desc = dev_get_uclass_plat(dev);
@ -102,7 +101,7 @@ struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum)
* name in a local table. This gives us an interface type which we can match
* against the uclass of the block device's parent.
*/
struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum)
{
enum uclass_id uclass_id;
enum uclass_id type;
@ -110,16 +109,16 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
struct uclass *uc;
int ret;
type = if_typename_to_iftype(if_typename);
type = uclass_name_to_iftype(uclass_idname);
if (type == UCLASS_INVALID) {
debug("%s: Unknown interface type '%s'\n", __func__,
if_typename);
uclass_idname);
return NULL;
}
uclass_id = if_type_to_uclass_id(type);
uclass_id = conv_uclass_id(type);
if (uclass_id == UCLASS_INVALID) {
debug("%s: Unknown uclass for interface type'\n",
blk_get_if_type_name(type));
blk_get_uclass_name(type));
return NULL;
}
@ -129,8 +128,8 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
type, devnum, dev->name, desc->if_type, desc->devnum);
debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__,
type, devnum, dev->name, desc->uclass_id, desc->devnum);
if (desc->devnum != devnum)
continue;
@ -178,14 +177,14 @@ struct blk_desc *blk_get_by_device(struct udevice *dev)
/**
* get_desc() - Get the block device descriptor for the given device number
*
* @if_type: Interface type
* @uclass_id: Interface type
* @devnum: Device number (0 = first)
* @descp: Returns block device descriptor on success
* Return: 0 on success, -ENODEV if there is no such device and no device
* with a higher device number, -ENOENT if there is no such device but there
* is one with a higher number, or other -ve on other error.
*/
static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp)
static int get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp)
{
bool found_more = false;
struct udevice *dev;
@ -199,9 +198,9 @@ static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp)
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
if_type, devnum, dev->name, desc->if_type, desc->devnum);
if (desc->if_type == if_type) {
debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__,
uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum);
if (desc->uclass_id == uclass_id) {
if (desc->devnum == devnum) {
ret = device_probe(dev);
if (ret)
@ -218,26 +217,26 @@ static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp)
return found_more ? -ENOENT : -ENODEV;
}
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)
{
struct udevice *dev;
int ret;
ret = blk_get_device(if_type, devnum, &dev);
ret = blk_get_device(uclass_id, devnum, &dev);
if (ret)
return ret;
return blk_select_hwpart(dev, hwpart);
}
int blk_list_part(enum uclass_id if_type)
int blk_list_part(enum uclass_id uclass_id)
{
struct blk_desc *desc;
int devnum, ok;
int ret;
for (ok = 0, devnum = 0;; ++devnum) {
ret = get_desc(if_type, devnum, &desc);
ret = get_desc(uclass_id, devnum, &desc);
if (ret == -ENODEV)
break;
else if (ret)
@ -255,12 +254,12 @@ int blk_list_part(enum uclass_id if_type)
return 0;
}
int blk_print_part_devnum(enum uclass_id if_type, int devnum)
int blk_print_part_devnum(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
int ret;
ret = get_desc(if_type, devnum, &desc);
ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
if (desc->type == DEV_TYPE_UNKNOWN)
@ -270,14 +269,14 @@ int blk_print_part_devnum(enum uclass_id if_type, int devnum)
return 0;
}
void blk_list_devices(enum uclass_id if_type)
void blk_list_devices(enum uclass_id uclass_id)
{
struct blk_desc *desc;
int ret;
int i;
for (i = 0;; ++i) {
ret = get_desc(if_type, i, &desc);
ret = get_desc(uclass_id, i, &desc);
if (ret == -ENODEV)
break;
else if (ret)
@ -289,12 +288,12 @@ void blk_list_devices(enum uclass_id if_type)
}
}
int blk_print_device_num(enum uclass_id if_type, int devnum)
int blk_print_device_num(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
int ret;
ret = get_desc(if_type, devnum, &desc);
ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
printf("\nIDE device %d: ", devnum);
@ -303,13 +302,13 @@ int blk_print_device_num(enum uclass_id if_type, int devnum)
return 0;
}
int blk_show_device(enum uclass_id if_type, int devnum)
int blk_show_device(enum uclass_id uclass_id, int devnum)
{
struct blk_desc *desc;
int ret;
printf("\nDevice %d: ", devnum);
ret = get_desc(if_type, devnum, &desc);
ret = get_desc(uclass_id, devnum, &desc);
if (ret == -ENODEV || ret == -ENOENT) {
printf("unknown device\n");
return -ENODEV;
@ -324,14 +323,14 @@ int blk_show_device(enum uclass_id if_type, int devnum)
return 0;
}
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)
{
struct blk_desc *desc;
ulong n;
int ret;
ret = get_desc(if_type, devnum, &desc);
ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
n = blk_dread(desc, start, blkcnt, buffer);
@ -341,13 +340,13 @@ ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
return n;
}
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)
{
struct blk_desc *desc;
int ret;
ret = get_desc(if_type, devnum, &desc);
ret = get_desc(uclass_id, devnum, &desc);
if (ret)
return ret;
return blk_dwrite(desc, start, blkcnt, buffer);
@ -370,7 +369,7 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
return blk_select_hwpart(desc->bdev, hwpart);
}
int blk_first_device(int if_type, struct udevice **devp)
int blk_first_device(int uclass_id, struct udevice **devp)
{
struct blk_desc *desc;
int ret;
@ -382,7 +381,7 @@ int blk_first_device(int if_type, struct udevice **devp)
return -ENODEV;
do {
desc = dev_get_uclass_plat(*devp);
if (desc->if_type == if_type)
if (desc->uclass_id == uclass_id)
return 0;
ret = uclass_find_next_device(devp);
if (ret)
@ -395,10 +394,10 @@ int blk_first_device(int if_type, struct udevice **devp)
int blk_next_device(struct udevice **devp)
{
struct blk_desc *desc;
int ret, if_type;
int ret, uclass_id;
desc = dev_get_uclass_plat(*devp);
if_type = desc->if_type;
uclass_id = desc->uclass_id;
do {
ret = uclass_find_next_device(devp);
if (ret)
@ -406,12 +405,12 @@ int blk_next_device(struct udevice **devp)
if (!*devp)
return -ENODEV;
desc = dev_get_uclass_plat(*devp);
if (desc->if_type == if_type)
if (desc->uclass_id == uclass_id)
return 0;
} while (1);
}
int blk_find_device(int if_type, int devnum, struct udevice **devp)
int blk_find_device(int uclass_id, int devnum, struct udevice **devp)
{
struct uclass *uc;
struct udevice *dev;
@ -423,9 +422,9 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp)
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
if_type, devnum, dev->name, desc->if_type, desc->devnum);
if (desc->if_type == if_type && desc->devnum == devnum) {
debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__,
uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum);
if (desc->uclass_id == uclass_id && desc->devnum == devnum) {
*devp = dev;
return 0;
}
@ -434,11 +433,11 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp)
return -ENODEV;
}
int blk_get_device(int if_type, int devnum, struct udevice **devp)
int blk_get_device(int uclass_id, int devnum, struct udevice **devp)
{
int ret;
ret = blk_find_device(if_type, devnum, devp);
ret = blk_find_device(uclass_id, devnum, devp);
if (ret)
return ret;
@ -455,12 +454,12 @@ unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
if (!ops->read)
return -ENOSYS;
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;
blks_read = ops->read(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;
@ -475,7 +474,7 @@ unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
if (!ops->write)
return -ENOSYS;
blkcache_invalidate(block_dev->if_type, block_dev->devnum);
blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->write(dev, start, blkcnt, buffer);
}
@ -488,7 +487,7 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
if (!ops->erase)
return -ENOSYS;
blkcache_invalidate(block_dev->if_type, block_dev->devnum);
blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return ops->erase(dev, start, blkcnt);
}
@ -525,7 +524,7 @@ const char *blk_get_devtype(struct udevice *dev)
return uclass_get_name(device_get_uclass_id(parent));
};
int blk_find_max_devnum(enum uclass_id if_type)
int blk_find_max_devnum(enum uclass_id uclass_id)
{
struct udevice *dev;
int max_devnum = -ENODEV;
@ -538,18 +537,18 @@ int blk_find_max_devnum(enum uclass_id if_type)
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
if (desc->if_type == if_type && desc->devnum > max_devnum)
if (desc->uclass_id == uclass_id && desc->devnum > max_devnum)
max_devnum = desc->devnum;
}
return max_devnum;
}
int blk_next_free_devnum(enum uclass_id if_type)
int blk_next_free_devnum(enum uclass_id uclass_id)
{
int ret;
ret = blk_find_max_devnum(if_type);
ret = blk_find_max_devnum(uclass_id);
if (ret == -ENODEV)
return 0;
if (ret < 0)
@ -631,7 +630,7 @@ int blk_count_devices(enum blk_flag_t flag)
return count;
}
static int blk_claim_devnum(enum uclass_id if_type, int devnum)
static int blk_claim_devnum(enum uclass_id uclass_id, int devnum)
{
struct udevice *dev;
struct uclass *uc;
@ -643,8 +642,8 @@ static int blk_claim_devnum(enum uclass_id if_type, int devnum)
uclass_foreach_dev(dev, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
if (desc->if_type == if_type && desc->devnum == devnum) {
int next = blk_next_free_devnum(if_type);
if (desc->uclass_id == uclass_id && desc->devnum == devnum) {
int next = blk_next_free_devnum(uclass_id);
if (next < 0)
return next;
@ -657,7 +656,7 @@ static int blk_claim_devnum(enum uclass_id if_type, int devnum)
}
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)
{
struct blk_desc *desc;
@ -665,9 +664,9 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
int ret;
if (devnum == -1) {
devnum = blk_next_free_devnum(if_type);
devnum = blk_next_free_devnum(uclass_id);
} else {
ret = blk_claim_devnum(if_type, devnum);
ret = blk_claim_devnum(uclass_id, devnum);
if (ret < 0 && ret != -ENOENT)
return ret;
}
@ -677,7 +676,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
if (ret)
return ret;
desc = dev_get_uclass_plat(dev);
desc->if_type = if_type;
desc->uclass_id = uclass_id;
desc->blksz = blksz;
desc->log2blksz = LOG2(desc->blksz);
desc->lba = lba;
@ -690,7 +689,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name,
}
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)
{
char dev_name[30], *str;
@ -701,7 +700,7 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name,
if (!str)
return -ENOMEM;
ret = blk_create_device(parent, drv_name, str, if_type, devnum,
ret = blk_create_device(parent, drv_name, str, uclass_id, devnum,
blksz, lba, devp);
if (ret) {
free(str);
@ -725,7 +724,7 @@ int blk_probe_or_unbind(struct udevice *dev)
return ret;
}
int blk_unbind_all(int if_type)
int blk_unbind_all(int uclass_id)
{
struct uclass *uc;
struct udevice *dev, *next;
@ -737,7 +736,7 @@ int blk_unbind_all(int if_type)
uclass_foreach_dev_safe(dev, next, uc) {
struct blk_desc *desc = dev_get_uclass_plat(dev);
if (desc->if_type == if_type) {
if (desc->uclass_id == uclass_id) {
ret = device_remove(dev, DM_REMOVE_NORMAL);
if (ret)
return ret;

View file

@ -9,14 +9,14 @@
#include <part.h>
#include <linux/err.h>
struct blk_driver *blk_driver_lookup_type(int if_type)
struct blk_driver *blk_driver_lookup_type(int uclass_id)
{
struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
struct blk_driver *entry;
for (entry = drv; entry != drv + n_ents; entry++) {
if (if_type == entry->if_type)
if (uclass_id == entry->uclass_id)
return entry;
}
@ -24,14 +24,14 @@ struct blk_driver *blk_driver_lookup_type(int if_type)
return NULL;
}
static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
static struct blk_driver *blk_driver_lookup_typename(const char *uclass_idname)
{
struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
struct blk_driver *entry;
for (entry = drv; entry != drv + n_ents; entry++) {
if (!strcmp(if_typename, entry->if_typename))
if (!strcmp(uclass_idname, entry->uclass_idname))
return entry;
}
@ -39,11 +39,11 @@ static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
return NULL;
}
const char *blk_get_if_type_name(enum uclass_id if_type)
const char *blk_get_uclass_name(enum uclass_id uclass_id)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
return drv ? drv->if_typename : NULL;
return drv ? drv->uclass_idname : NULL;
}
/**
@ -70,14 +70,14 @@ static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp)
return drv->get_dev(devnum, descp);
}
int blk_list_part(enum uclass_id if_type)
int blk_list_part(enum uclass_id uclass_id)
{
struct blk_driver *drv;
struct blk_desc *desc;
int devnum, ok;
bool first = true;
drv = blk_driver_lookup_type(if_type);
drv = blk_driver_lookup_type(uclass_id);
if (!drv)
return -ENOSYS;
for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
@ -97,9 +97,9 @@ int blk_list_part(enum uclass_id if_type)
return 0;
}
int blk_print_part_devnum(enum uclass_id if_type, int devnum)
int blk_print_part_devnum(enum uclass_id uclass_id, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@ -115,9 +115,9 @@ int blk_print_part_devnum(enum uclass_id if_type, int devnum)
return 0;
}
void blk_list_devices(enum uclass_id if_type)
void blk_list_devices(enum uclass_id uclass_id)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int i;
@ -133,9 +133,9 @@ void blk_list_devices(enum uclass_id if_type)
}
}
int blk_print_device_num(enum uclass_id if_type, int devnum)
int blk_print_device_num(enum uclass_id uclass_id, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@ -144,15 +144,15 @@ int blk_print_device_num(enum uclass_id if_type, int devnum)
ret = get_desc(drv, devnum, &desc);
if (ret)
return ret;
printf("\n%s device %d: ", drv->if_typename, devnum);
printf("\n%s device %d: ", drv->uclass_idname, devnum);
dev_print(desc);
return 0;
}
int blk_show_device(enum uclass_id if_type, int devnum)
int blk_show_device(enum uclass_id uclass_id, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@ -174,9 +174,9 @@ int blk_show_device(enum uclass_id if_type, int devnum)
return 0;
}
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)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
if (!drv)
@ -190,7 +190,7 @@ struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum)
int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
{
struct blk_driver *drv = blk_driver_lookup_type(desc->if_type);
struct blk_driver *drv = blk_driver_lookup_type(desc->uclass_id);
if (!drv)
return -ENOSYS;
@ -200,9 +200,9 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
return 0;
}
struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum)
{
struct blk_driver *drv = blk_driver_lookup_typename(if_typename);
struct blk_driver *drv = blk_driver_lookup_typename(uclass_idname);
struct blk_desc *desc;
if (!drv)
@ -214,10 +214,10 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
return desc;
}
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)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
ulong n;
int ret;
@ -234,10 +234,10 @@ ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
return n;
}
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)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;
@ -249,9 +249,9 @@ ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start,
return desc->block_write(desc, start, blkcnt, buffer);
}
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)
{
struct blk_driver *drv = blk_driver_lookup_type(if_type);
struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
struct blk_desc *desc;
int ret;

View file

@ -537,7 +537,7 @@ static void ide_ident(struct blk_desc *dev_desc)
/* Select device
*/
ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device));
dev_desc->if_type = UCLASS_IDE;
dev_desc->uclass_id = UCLASS_IDE;
#ifdef CONFIG_ATAPI
retries = 0;
@ -752,7 +752,7 @@ void ide_init(void)
for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) {
ide_dev_desc[i].type = DEV_TYPE_UNKNOWN;
ide_dev_desc[i].if_type = UCLASS_IDE;
ide_dev_desc[i].uclass_id = UCLASS_IDE;
ide_dev_desc[i].devnum = i;
ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
ide_dev_desc[i].blksz = 0;
@ -1143,8 +1143,8 @@ UCLASS_DRIVER(ide) = {
};
#else
U_BOOT_LEGACY_BLK(ide) = {
.if_typename = "ide",
.if_type = UCLASS_IDE,
.uclass_idname = "ide",
.uclass_id = UCLASS_IDE,
.max_devs = CONFIG_SYS_IDE_MAXDEVICE,
.desc = ide_dev_desc,
};

View file

@ -150,7 +150,7 @@ int host_dev_bind(int devnum, char *filename, bool removable)
goto err_file;
}
desc = blk_get_devnum_by_type(UCLASS_ROOT, devnum);
desc = blk_get_devnum_by_uclass_id(UCLASS_ROOT, devnum);
desc->removable = removable;
snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
@ -192,7 +192,7 @@ int host_dev_bind(int dev, char *filename, bool removable)
}
struct blk_desc *blk_dev = &host_dev->blk_dev;
blk_dev->if_type = UCLASS_ROOT;
blk_dev->uclass_id = UCLASS_ROOT;
blk_dev->priv = host_dev;
blk_dev->blksz = 512;
blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz;
@ -262,8 +262,8 @@ U_BOOT_DRIVER(sandbox_host_blk) = {
};
#else
U_BOOT_LEGACY_BLK(sandbox_host) = {
.if_typename = "host",
.if_type = UCLASS_ROOT,
.uclass_idname = "host",
.uclass_id = UCLASS_ROOT,
.max_devs = SANDBOX_HOST_MAX_DEVICES,
.get_dev = host_get_dev_err,
};

View file

@ -472,7 +472,7 @@ static int mmc_select_hwpart(struct udevice *bdev, int hwpart)
ret = mmc_switch_part(mmc, hwpart);
if (!ret)
blkcache_invalidate(desc->if_type, desc->devnum);
blkcache_invalidate(desc->uclass_id, desc->devnum);
return ret;
}

View file

@ -132,7 +132,7 @@ static struct mmc mmc_static = {
.dsr_imp = 0,
.dsr = 0xffffffff,
.block_dev = {
.if_type = UCLASS_MMC,
.uclass_id = UCLASS_MMC,
.removable = 1,
.devnum = 0,
.block_read = mmc_bread,
@ -194,7 +194,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv)
mmc->dsr = 0xffffffff;
/* Setup the universal parts of the block interface just once */
bdesc = mmc_get_blk_desc(mmc);
bdesc->if_type = UCLASS_MMC;
bdesc->uclass_id = UCLASS_MMC;
bdesc->removable = 1;
bdesc->devnum = mmc_get_next_devnum();
bdesc->block_read = mmc_bread;
@ -253,8 +253,8 @@ static int mmc_get_dev(int dev, struct blk_desc **descp)
}
U_BOOT_LEGACY_BLK(mmc) = {
.if_typename = "mmc",
.if_type = UCLASS_MMC,
.uclass_idname = "mmc",
.uclass_id = UCLASS_MMC,
.max_devs = -1,
.get_dev = mmc_get_dev,
.select_hwpart = mmc_select_hwpartp,

View file

@ -146,7 +146,7 @@ static int enetc_init_sgmii(struct udevice *dev)
if (!enetc_has_imdio(dev))
return 0;
if (priv->if_type == PHY_INTERFACE_MODE_2500BASEX)
if (priv->uclass_id == PHY_INTERFACE_MODE_2500BASEX)
is2500 = true;
/*
@ -221,7 +221,7 @@ static void enetc_setup_mac_iface(struct udevice *dev,
struct enetc_priv *priv = dev_get_priv(dev);
u32 if_mode;
switch (priv->if_type) {
switch (priv->uclass_id) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_RGMII_RXID:
@ -278,14 +278,14 @@ static void enetc_start_pcs(struct udevice *dev)
return;
}
priv->if_type = dev_read_phy_mode(dev);
if (priv->if_type == PHY_INTERFACE_MODE_NA) {
priv->uclass_id = dev_read_phy_mode(dev);
if (priv->uclass_id == PHY_INTERFACE_MODE_NA) {
enetc_dbg(dev,
"phy-mode property not found, defaulting to SGMII\n");
priv->if_type = PHY_INTERFACE_MODE_SGMII;
priv->uclass_id = PHY_INTERFACE_MODE_SGMII;
}
switch (priv->if_type) {
switch (priv->uclass_id) {
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_2500BASEX:
enetc_init_sgmii(dev);

View file

@ -158,7 +158,7 @@ struct enetc_priv {
struct bd_ring tx_bdr;
struct bd_ring rx_bdr;
int if_type;
int uclass_id;
struct mii_dev imdio;
struct phy_device *phy;
};

View file

@ -17,4 +17,5 @@ endif
ifdef CONFIG_SCSI
obj-$(CONFIG_SANDBOX) += sandbox_scsi.o
obj-$(CONFIG_SANDBOX) += scsi_emul.o
endif

View file

@ -7,19 +7,145 @@
* that CONFIG_SCSI can be enabled for sandbox.
*/
#define LOG_CATEGORY UCLASS_SCSI
#include <common.h>
#include <dm.h>
#include <os.h>
#include <malloc.h>
#include <scsi.h>
#include <scsi_emul.h>
int scsi_bus_reset(struct udevice *dev)
enum {
SANDBOX_SCSI_BLOCK_LEN = 512,
SANDBOX_SCSI_BUF_SIZE = 512,
};
/**
* struct sandbox_scsi_priv
*
* @eminfo: emulator state
* @pathanme: Path to the backing file, e.g. 'scsi.img'
* @fd: File descriptor of backing file
*/
struct sandbox_scsi_priv {
struct scsi_emul_info eminfo;
const char *pathname;
int fd;
};
static int sandbox_scsi_exec(struct udevice *dev, struct scsi_cmd *req)
{
struct sandbox_scsi_priv *priv = dev_get_priv(dev);
struct scsi_emul_info *info = &priv->eminfo;
int ret;
if (req->lun || req->target)
return -EIO;
ret = sb_scsi_emul_command(info, req, req->cmdlen);
if (ret < 0) {
log_debug("SCSI command 0x%02x ret errno %d\n", req->cmd[0],
ret);
return ret;
} else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) {
long bytes_read;
log_debug("read %x %x\n", info->seek_block, info->read_len);
os_lseek(priv->fd, info->seek_block * info->block_size,
OS_SEEK_SET);
bytes_read = os_read(priv->fd, req->pdata, info->buff_used);
if (bytes_read < 0)
return bytes_read;
if (bytes_read != info->buff_used)
return -EIO;
} else if (!ret) {
req->pdata = info->buff;
info->phase = SCSIPH_STATUS;
log_debug("sending buf\n");
} else {
log_debug("error\n");
return -EIO;
}
return 0;
}
void scsi_init(void)
static int sandbox_scsi_bus_reset(struct udevice *dev)
{
}
/* Not implemented */
int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb)
{
return 0;
}
static int sandbox_scsi_of_to_plat(struct udevice *dev)
{
struct sandbox_scsi_priv *priv = dev_get_priv(dev);
priv->pathname = dev_read_string(dev, "sandbox,filepath");
return 0;
}
static int sandbox_scsi_probe(struct udevice *dev)
{
struct scsi_plat *scsi_plat = dev_get_uclass_plat(dev);
struct sandbox_scsi_priv *priv = dev_get_priv(dev);
struct scsi_emul_info *info = &priv->eminfo;
int ret;
scsi_plat->max_id = 2;
scsi_plat->max_lun = 3;
scsi_plat->max_bytes_per_req = 1 << 20;
info->vendor = "SANDBOX";
info->product = "FAKE DISK";
info->buff = malloc(SANDBOX_SCSI_BUF_SIZE);
if (!info->buff)
return log_ret(-ENOMEM);
info->block_size = SANDBOX_SCSI_BLOCK_LEN;
if (priv->pathname) {
priv->fd = os_open(priv->pathname, OS_O_RDONLY);
if (priv->fd != -1) {
ret = os_get_filesize(priv->pathname, &info->file_size);
if (ret)
return log_msg_ret("sz", ret);
}
} else {
priv->fd = -1;
}
log_debug("filename: %s, fd %d\n", priv->pathname, priv->fd);
return 0;
}
static int sandbox_scsi_remove(struct udevice *dev)
{
struct sandbox_scsi_priv *priv = dev_get_priv(dev);
struct scsi_emul_info *info = &priv->eminfo;
free(info->buff);
return 0;
}
struct scsi_ops sandbox_scsi_ops = {
.exec = sandbox_scsi_exec,
.bus_reset = sandbox_scsi_bus_reset,
};
static const struct udevice_id sanbox_scsi_ids[] = {
{ .compatible = "sandbox,scsi" },
{ }
};
U_BOOT_DRIVER(sandbox_scsi) = {
.name = "sandbox_scsi",
.id = UCLASS_SCSI,
.ops = &sandbox_scsi_ops,
.of_match = sanbox_scsi_ids,
.of_to_plat = sandbox_scsi_of_to_plat,
.probe = sandbox_scsi_probe,
.remove = sandbox_scsi_remove,
.priv_auto = sizeof(struct sandbox_scsi_priv),
};

View file

@ -456,7 +456,7 @@ static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum)
{
dev_desc->lba = 0;
dev_desc->blksz = 0;
dev_desc->if_type = UCLASS_SCSI;
dev_desc->uclass_id = UCLASS_SCSI;
dev_desc->devnum = devnum;
dev_desc->part_type = PART_TYPE_UNKNOWN;
@ -706,8 +706,8 @@ U_BOOT_DRIVER(scsi_blk) = {
};
#else
U_BOOT_LEGACY_BLK(scsi) = {
.if_typename = "scsi",
.if_type = UCLASS_SCSI,
.uclass_idname = "scsi",
.uclass_id = UCLASS_SCSI,
.max_devs = SCSI_MAX_DEVICE,
.desc = scsi_dev_desc,
};

74
drivers/scsi/scsi_emul.c Normal file
View file

@ -0,0 +1,74 @@
// 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 <sjg@chromium.org>
*
* implementation of SCSI functions required so that CONFIG_SCSI can be enabled
* for sandbox.
*/
#define LOG_CATEGORY UCLASS_SCSI
#include <common.h>
#include <dm.h>
#include <log.h>
#include <scsi.h>
#include <scsi_emul.h>
int sb_scsi_emul_command(struct scsi_emul_info *info,
const struct scsi_cmd *req, int len)
{
int ret = 0;
info->buff_used = 0;
log_debug("emul %x\n", *req->cmd);
switch (*req->cmd) {
case SCSI_INQUIRY: {
struct scsi_inquiry_resp *resp = (void *)info->buff;
info->alloc_len = req->cmd[4];
memset(resp, '\0', sizeof(*resp));
resp->data_format = 1;
resp->additional_len = 0x1f;
strncpy(resp->vendor, info->vendor, sizeof(resp->vendor));
strncpy(resp->product, info->product, sizeof(resp->product));
strncpy(resp->revision, "1.0", sizeof(resp->revision));
info->buff_used = sizeof(*resp);
break;
}
case SCSI_TST_U_RDY:
break;
case SCSI_RD_CAPAC: {
struct scsi_read_capacity_resp *resp = (void *)info->buff;
uint blocks;
if (info->file_size)
blocks = info->file_size / info->block_size - 1;
else
blocks = 0;
resp->last_block_addr = cpu_to_be32(blocks);
resp->block_len = cpu_to_be32(info->block_size);
info->buff_used = sizeof(*resp);
break;
}
case SCSI_READ10: {
const struct scsi_read10_req *read_req = (void *)req;
info->seek_block = be32_to_cpu(read_req->lba);
info->read_len = be16_to_cpu(read_req->xfer_len);
info->buff_used = info->read_len * info->block_size;
ret = SCSI_EMUL_DO_READ;
break;
}
default:
debug("Command not supported: %x\n", req->cmd[0]);
ret = -EPROTONOSUPPORT;
}
if (ret >= 0)
info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS;
log_debug(" - done %x: ret=%d\n", *req->cmd, ret);
return ret;
}

View file

@ -7,8 +7,10 @@
#include <common.h>
#include <dm.h>
#include <log.h>
#include <malloc.h>
#include <os.h>
#include <scsi.h>
#include <scsi_emul.h>
#include <usb.h>
/*
@ -21,12 +23,7 @@ enum {
SANDBOX_FLASH_EP_OUT = 1, /* endpoints */
SANDBOX_FLASH_EP_IN = 2,
SANDBOX_FLASH_BLOCK_LEN = 512,
};
enum cmd_phase {
PHASE_START,
PHASE_DATA,
PHASE_STATUS,
SANDBOX_FLASH_BUF_SIZE = 512,
};
enum {
@ -40,29 +37,19 @@ enum {
/**
* struct sandbox_flash_priv - private state for this driver
*
* @eminfo: emulator state
* @error: true if there is an error condition
* @alloc_len: Allocation length from the last incoming command
* @transfer_len: Transfer length from CBW header
* @read_len: Number of blocks of data left in the current read command
* @tag: Tag value from last command
* @fd: File descriptor of backing file
* @file_size: Size of file in bytes
* @status_buff: Data buffer for outgoing status
* @buff_used: Number of bytes ready to transfer back to host
* @buff: Data buffer for outgoing data
*/
struct sandbox_flash_priv {
struct scsi_emul_info eminfo;
bool error;
int alloc_len;
int transfer_len;
int read_len;
enum cmd_phase phase;
u32 tag;
int fd;
loff_t file_size;
struct umass_bbb_csw status;
int buff_used;
u8 buff[512];
};
struct sandbox_flash_plat {
@ -70,32 +57,6 @@ struct sandbox_flash_plat {
struct usb_string flash_strings[STRINGID_COUNT];
};
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 {
u32 last_block_addr;
u32 block_len;
};
struct __packed scsi_read10_req {
u8 cmd;
u8 lun_flags;
u32 lba;
u8 spare;
u16 transfer_len;
u8 spare2[3];
};
static struct usb_device_descriptor flash_device_desc = {
.bLength = sizeof(flash_device_desc),
.bDescriptorType = USB_DT_DEVICE,
@ -200,7 +161,6 @@ static void setup_fail_response(struct sandbox_flash_priv *priv)
csw->dCSWTag = priv->tag;
csw->dCSWDataResidue = 0;
csw->bCSWStatus = CSWSTATUS_FAILED;
priv->buff_used = 0;
}
/**
@ -210,8 +170,7 @@ static void setup_fail_response(struct sandbox_flash_priv *priv)
* @resp: Response to send, or NULL if none
* @size: Size of response
*/
static void setup_response(struct sandbox_flash_priv *priv, void *resp,
int size)
static void setup_response(struct sandbox_flash_priv *priv)
{
struct umass_bbb_csw *csw = &priv->status;
@ -219,97 +178,45 @@ static void setup_response(struct sandbox_flash_priv *priv, void *resp,
csw->dCSWTag = priv->tag;
csw->dCSWDataResidue = 0;
csw->bCSWStatus = CSWSTATUS_GOOD;
assert(!resp || resp == priv->buff);
priv->buff_used = size;
}
static void handle_read(struct sandbox_flash_priv *priv, ulong lba,
ulong transfer_len)
static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,
int len)
{
debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len);
priv->read_len = transfer_len;
if (priv->fd != -1) {
os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET);
setup_response(priv, priv->buff,
transfer_len * SANDBOX_FLASH_BLOCK_LEN);
struct scsi_emul_info *info = &priv->eminfo;
const struct scsi_cmd *req = buff;
int ret;
ret = sb_scsi_emul_command(info, req, len);
if (!ret) {
setup_response(priv);
} else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) {
os_lseek(priv->fd, info->seek_block * info->block_size,
OS_SEEK_SET);
setup_response(priv);
} else {
setup_fail_response(priv);
}
}
static int handle_ufi_command(struct sandbox_flash_plat *plat,
struct sandbox_flash_priv *priv, const void *buff,
int len)
{
const struct scsi_cmd *req = buff;
switch (*req->cmd) {
case SCSI_INQUIRY: {
struct scsi_inquiry_resp *resp = (void *)priv->buff;
priv->alloc_len = req->cmd[4];
memset(resp, '\0', sizeof(*resp));
resp->data_format = 1;
resp->additional_len = 0x1f;
strncpy(resp->vendor,
plat->flash_strings[STRINGID_MANUFACTURER - 1].s,
sizeof(resp->vendor));
strncpy(resp->product,
plat->flash_strings[STRINGID_PRODUCT - 1].s,
sizeof(resp->product));
strncpy(resp->revision, "1.0", sizeof(resp->revision));
setup_response(priv, resp, sizeof(*resp));
break;
}
case SCSI_TST_U_RDY:
setup_response(priv, NULL, 0);
break;
case SCSI_RD_CAPAC: {
struct scsi_read_capacity_resp *resp = (void *)priv->buff;
uint blocks;
if (priv->file_size)
blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1;
else
blocks = 0;
resp->last_block_addr = cpu_to_be32(blocks);
resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN);
setup_response(priv, resp, sizeof(*resp));
break;
}
case SCSI_READ10: {
struct scsi_read10_req *req = (void *)buff;
handle_read(priv, be32_to_cpu(req->lba),
be16_to_cpu(req->transfer_len));
break;
}
default:
debug("Command not supported: %x\n", req->cmd[0]);
return -EPROTONOSUPPORT;
}
priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS;
return 0;
}
static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buff, int len)
{
struct sandbox_flash_plat *plat = dev_get_plat(dev);
struct sandbox_flash_priv *priv = dev_get_priv(dev);
struct scsi_emul_info *info = &priv->eminfo;
int ep = usb_pipeendpoint(pipe);
struct umass_bbb_cbw *cbw = buff;
debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__,
dev->name, pipe, ep, len, priv->phase);
dev->name, pipe, ep, len, info->phase);
switch (ep) {
case SANDBOX_FLASH_EP_OUT:
switch (priv->phase) {
case PHASE_START:
priv->alloc_len = 0;
priv->read_len = 0;
switch (info->phase) {
case SCSIPH_START:
info->alloc_len = 0;
info->read_len = 0;
if (priv->error || len != UMASS_BBB_CBW_SIZE ||
cbw->dCBWSignature != CBWSIGNATURE)
goto err;
@ -318,22 +225,22 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
goto err;
if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10)
goto err;
priv->transfer_len = cbw->dCBWDataTransferLength;
info->transfer_len = cbw->dCBWDataTransferLength;
priv->tag = cbw->dCBWTag;
return handle_ufi_command(plat, priv, cbw->CBWCDB,
return handle_ufi_command(priv, cbw->CBWCDB,
cbw->bCDBLength);
case PHASE_DATA:
case SCSIPH_DATA:
debug("data out\n");
break;
default:
break;
}
case SANDBOX_FLASH_EP_IN:
switch (priv->phase) {
case PHASE_DATA:
debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n",
len, priv->alloc_len, priv->read_len);
if (priv->read_len) {
switch (info->phase) {
case SCSIPH_DATA:
debug("data in, len=%x, alloc_len=%x, info->read_len=%x\n",
len, info->alloc_len, info->read_len);
if (info->read_len) {
ulong bytes_read;
if (priv->fd == -1)
@ -342,24 +249,24 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
bytes_read = os_read(priv->fd, buff, len);
if (bytes_read != len)
return -EIO;
priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN;
if (!priv->read_len)
priv->phase = PHASE_STATUS;
info->read_len -= len / info->block_size;
if (!info->read_len)
info->phase = SCSIPH_STATUS;
} else {
if (priv->alloc_len && len > priv->alloc_len)
len = priv->alloc_len;
if (len > sizeof(priv->buff))
len = sizeof(priv->buff);
memcpy(buff, priv->buff, len);
priv->phase = PHASE_STATUS;
if (info->alloc_len && len > info->alloc_len)
len = info->alloc_len;
if (len > SANDBOX_FLASH_BUF_SIZE)
len = SANDBOX_FLASH_BUF_SIZE;
memcpy(buff, info->buff, len);
info->phase = SCSIPH_STATUS;
}
return len;
case PHASE_STATUS:
case SCSIPH_STATUS:
debug("status in, len=%x\n", len);
if (len > sizeof(priv->status))
len = sizeof(priv->status);
memcpy(buff, &priv->status, len);
priv->phase = PHASE_START;
info->phase = SCSIPH_START;
return len;
default:
break;
@ -400,10 +307,31 @@ static int sandbox_flash_probe(struct udevice *dev)
{
struct sandbox_flash_plat *plat = dev_get_plat(dev);
struct sandbox_flash_priv *priv = dev_get_priv(dev);
struct scsi_emul_info *info = &priv->eminfo;
int ret;
priv->fd = os_open(plat->pathname, OS_O_RDONLY);
if (priv->fd != -1)
return os_get_filesize(plat->pathname, &priv->file_size);
if (priv->fd != -1) {
ret = os_get_filesize(plat->pathname, &info->file_size);
if (ret)
return log_msg_ret("sz", ret);
}
info->buff = malloc(SANDBOX_FLASH_BUF_SIZE);
if (!info->buff)
return log_ret(-ENOMEM);
info->vendor = plat->flash_strings[STRINGID_MANUFACTURER - 1].s;
info->product = plat->flash_strings[STRINGID_PRODUCT - 1].s;
info->block_size = SANDBOX_FLASH_BLOCK_LEN;
return 0;
}
static int sandbox_flash_remove(struct udevice *dev)
{
struct sandbox_flash_priv *priv = dev_get_priv(dev);
struct scsi_emul_info *info = &priv->eminfo;
free(info->buff);
return 0;
}
@ -424,6 +352,7 @@ U_BOOT_DRIVER(usb_sandbox_flash) = {
.of_match = sandbox_usb_flash_ids,
.bind = sandbox_flash_bind,
.probe = sandbox_flash_probe,
.remove = sandbox_flash_remove,
.of_to_plat = sandbox_flash_of_to_plat,
.ops = &sandbox_usb_flash_ops,
.priv_auto = sizeof(struct sandbox_flash_priv),

View file

@ -75,7 +75,7 @@ static int virtio_blk_bind(struct udevice *dev)
struct blk_desc *desc = dev_get_uclass_plat(dev);
int devnum;
desc->if_type = UCLASS_VIRTIO;
desc->uclass_id = UCLASS_VIRTIO;
/*
* Initialize the devnum to -ENODEV. This is to make sure that
* blk_next_free_devnum() works as expected, since the default

View file

@ -665,7 +665,7 @@ static int pvblock_blk_bind(struct udevice *udev)
struct blk_desc *desc = dev_get_uclass_plat(udev);
int devnum;
desc->if_type = UCLASS_PVBLOCK;
desc->uclass_id = UCLASS_PVBLOCK;
/*
* Initialize the devnum to -ENODEV. This is to make sure that
* blk_next_free_devnum() works as expected, since the default

View file

@ -1145,7 +1145,7 @@ int file_fat_detectfs(void)
}
if (blk_enabled()) {
printf("Interface: %s\n", blk_get_if_type_name(cur_dev->if_type));
printf("Interface: %s\n", blk_get_uclass_name(cur_dev->uclass_id));
printf(" Device %d: ", cur_dev->devnum);
dev_print(cur_dev);
}

View file

@ -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 {

View file

@ -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);

View file

@ -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 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;
unsigned int priv;
enum dma_data_direction dma_dir;
};
/*-----------------------------------------------------------
@ -167,6 +187,74 @@ struct scsi_cmd {
#define SCSI_WRITE_LONG 0x3F /* Write Long (O) */
#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
*

70
include/scsi_emul.h Normal file
View file

@ -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 <sjg@chromium.org>
*
* 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

View file

@ -498,13 +498,13 @@ static efi_status_t efi_disk_add_dev(
diskobj->media.last_block);
/* Store first EFI system partition */
if (part && !efi_system_partition.if_type) {
if (part && !efi_system_partition.uclass_id) {
if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
efi_system_partition.if_type = desc->if_type;
efi_system_partition.uclass_id = desc->uclass_id;
efi_system_partition.devnum = desc->devnum;
efi_system_partition.part = part;
EFI_PRINT("EFI system partition: %s %x:%x\n",
blk_get_if_type_name(desc->if_type),
blk_get_uclass_name(desc->uclass_id),
desc->devnum, part);
}
}
@ -640,7 +640,7 @@ static int efi_disk_probe(void *ctx, struct event *event)
* has already created an efi_disk at this moment.
*/
desc = dev_get_uclass_plat(dev);
if (desc->if_type != UCLASS_EFI_LOADER) {
if (desc->uclass_id != UCLASS_EFI_LOADER) {
ret = efi_disk_create_raw(dev);
if (ret)
return -1;
@ -675,7 +675,7 @@ static int efi_disk_delete_raw(struct udevice *dev)
return -1;
desc = dev_get_uclass_plat(dev);
if (desc->if_type != UCLASS_EFI_LOADER) {
if (desc->uclass_id != UCLASS_EFI_LOADER) {
diskobj = container_of(handle, struct efi_disk_obj, header);
efi_free_pool(diskobj->dp);
}
@ -794,7 +794,7 @@ efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int
} else {
return EFI_INVALID_PARAMETER;
}
if_typename = blk_get_if_type_name(desc->if_type);
if_typename = blk_get_uclass_name(desc->uclass_id);
diskid = desc->devnum;
if (is_partition) {

View file

@ -38,13 +38,13 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void)
char part_str[PART_STR_LEN];
int r;
if (efi_system_partition.if_type == UCLASS_INVALID) {
if (efi_system_partition.uclass_id == UCLASS_INVALID) {
log_err("No EFI system partition\n");
return EFI_DEVICE_ERROR;
}
snprintf(part_str, PART_STR_LEN, "%x:%x",
efi_system_partition.devnum, efi_system_partition.part);
r = fs_set_blk_dev(blk_get_if_type_name(efi_system_partition.if_type),
r = fs_set_blk_dev(blk_get_uclass_name(efi_system_partition.uclass_id),
part_str, FS_TYPE_ANY);
if (r) {
log_err("Cannot read EFI system partition\n");

View file

@ -91,6 +91,7 @@ obj-$(CONFIG_DM_REGULATOR) += regulator.o
obj-$(CONFIG_DM_RNG) += rng.o
obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o
obj-$(CONFIG_SCSI) += scsi.o
obj-$(CONFIG_DM_SERIAL) += serial.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_SIMPLE_BUS) += simple-bus.o

39
test/dm/scsi.c Normal file
View file

@ -0,0 +1,39 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2015 Google, Inc
*/
#include <common.h>
#include <dm.h>
#include <part.h>
#include <scsi.h>
#include <dm/test.h>
#include <test/test.h>
#include <test/ut.h>
/* Test that sandbox SCSI works correctly */
static int dm_test_scsi_base(struct unit_test_state *uts)
{
const struct disk_partition *info;
const struct disk_part *part;
struct udevice *dev;
ut_assertok(scsi_scan(false));
/*
* We expect some sort of partition on the disk image, created by
* test_ut_dm_init()
*/
ut_assertok(uclass_first_device_err(UCLASS_PARTITION, &dev));
part = dev_get_uclass_plat(dev);
ut_asserteq(1, part->partnum);
info = &part->gpt_part_info;
ut_asserteq_str("sda1", info->name);
ut_asserteq_str("U-Boot", info->type);
ut_asserteq(0x83 /* linux */, info->sys_ind);
return 0;
}
DM_TEST(dm_test_scsi_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);

View file

@ -114,6 +114,15 @@ def test_ut_dm_init(u_boot_console):
with open(fn, 'wb') as fh:
fh.write(data)
# Create a file with a single partition
fn = u_boot_console.config.source_dir + '/scsi.img'
if not os.path.exists(fn):
data = b'\x00' * (2 * 1024 * 1024)
with open(fn, 'wb') as fh:
fh.write(data)
u_boot_utils.run_and_log(
u_boot_console, f'sfdisk {fn}', stdin=b'type=83')
@pytest.mark.buildconfigspec('cmd_bootflow')
def test_ut_dm_init_bootstd(u_boot_console):
"""Initialise data for bootflow tests"""