/* Test that block devices work correctly with USB */ static int dm_test_blk_usb(struct unit_test_state *uts) { struct udevice *usb_dev, *dev; struct blk_desc *dev_desc; /* Get a flash device */ state_set_skip_delays(true); ut_assertok(usb_init()); ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &usb_dev)); ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc)); /* The parent should be a block device */ ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev)); ut_asserteq_ptr(usb_dev, dev_get_parent(dev)); /* Check we have one block device for each mass storage device */ ut_asserteq(6, count_blk_devices()); /* Now go around again, making sure the old devices were unbound */ ut_assertok(usb_stop()); ut_assertok(usb_init()); ut_asserteq(6, count_blk_devices()); ut_assertok(usb_stop()); return 0; }
static inline int mmc_offset_try_partition(const char *str, s64 *val) { disk_partition_t info; struct blk_desc *desc; int len, i, ret; ret = blk_get_device_by_str("mmc", STR(CONFIG_SYS_MMC_ENV_DEV), &desc); if (ret < 0) return (ret); for (i = 1;;i++) { ret = part_get_info(desc, i, &info); if (ret < 0) return ret; if (!strncmp((const char *)info.name, str, sizeof(str))) break; } /* round up to info.blksz */ len = (CONFIG_ENV_SIZE + info.blksz - 1) & ~(info.blksz - 1); /* use the top of the partion for the environment */ *val = (info.start + info.size - 1) - len / info.blksz; return 0; }
static int dm_test_mmc_blk(struct unit_test_state *uts) { struct udevice *dev; struct blk_desc *dev_desc; char cmp[1024]; ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev)); ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc)); /* Read a few blocks and look for the string we expect */ ut_asserteq(512, dev_desc->blksz); memset(cmp, '\0', sizeof(cmp)); ut_asserteq(2, blk_dread(dev_desc, 0, 2, cmp)); ut_assertok(strcmp(cmp, "this is a test")); return 0; }
int blk_get_device_part_str(const char *ifname, const char *dev_part_str, struct blk_desc **dev_desc, disk_partition_t *info, int allow_whole_dev) { int ret = -1; const char *part_str; char *dup_str = NULL; const char *dev_str; int dev; char *ep; int p; int part; disk_partition_t tmpinfo; #ifdef CONFIG_SANDBOX /* * Special-case a pseudo block device "hostfs", to allow access to the * host's own filesystem. */ if (0 == strcmp(ifname, "hostfs")) { *dev_desc = NULL; info->start = 0; info->size = 0; info->blksz = 0; info->bootable = 0; strcpy((char *)info->type, BOOT_PART_TYPE); strcpy((char *)info->name, "Sandbox host"); #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif #ifdef CONFIG_PARTITION_TYPE_GUID info->type_guid[0] = 0; #endif return 0; } #endif #ifdef CONFIG_CMD_UBIFS /* * Special-case ubi, ubi goes through a mtd, rathen then through * a regular block device. */ if (0 == strcmp(ifname, "ubi")) { if (!ubifs_is_mounted()) { printf("UBIFS not mounted, use ubifsmount to mount volume first!\n"); return -1; } *dev_desc = NULL; memset(info, 0, sizeof(*info)); strcpy((char *)info->type, BOOT_PART_TYPE); strcpy((char *)info->name, "UBI"); #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif return 0; } #endif /* If no dev_part_str, use bootdevice environment variable */ if (!dev_part_str || !strlen(dev_part_str) || !strcmp(dev_part_str, "-")) dev_part_str = getenv("bootdevice"); /* If still no dev_part_str, it's an error */ if (!dev_part_str) { printf("** No device specified **\n"); goto cleanup; } /* Separate device and partition ID specification */ part_str = strchr(dev_part_str, ':'); if (part_str) { dup_str = strdup(dev_part_str); dup_str[part_str - dev_part_str] = 0; dev_str = dup_str; part_str++; } else { dev_str = dev_part_str; } /* Look up the device */ dev = blk_get_device_by_str(ifname, dev_str, dev_desc); if (dev < 0) goto cleanup; /* Convert partition ID string to number */ if (!part_str || !*part_str) { part = PART_UNSPECIFIED; } else if (!strcmp(part_str, "auto")) { part = PART_AUTO; } else { /* Something specified -> use exactly that */ part = (int)simple_strtoul(part_str, &ep, 16); /* * Less than whole string converted, * or request for whole device, but caller requires partition. */ if (*ep || (part == 0 && !allow_whole_dev)) { printf("** Bad partition specification %s %s **\n", ifname, dev_part_str); goto cleanup; } } /* * No partition table on device, * or user requested partition 0 (entire device). */ if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || (part == 0)) { if (!(*dev_desc)->lba) { printf("** Bad device size - %s %s **\n", ifname, dev_str); goto cleanup; } /* * If user specified a partition ID other than 0, * or the calling command only accepts partitions, * it's an error. */ if ((part > 0) || (!allow_whole_dev)) { printf("** No partition table - %s %s **\n", ifname, dev_str); goto cleanup; } (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); info->start = 0; info->size = (*dev_desc)->lba; info->blksz = (*dev_desc)->blksz; info->bootable = 0; strcpy((char *)info->type, BOOT_PART_TYPE); strcpy((char *)info->name, "Whole Disk"); #ifdef CONFIG_PARTITION_UUIDS info->uuid[0] = 0; #endif #ifdef CONFIG_PARTITION_TYPE_GUID info->type_guid[0] = 0; #endif ret = 0; goto cleanup; } /* * Now there's known to be a partition table, * not specifying a partition means to pick partition 1. */ if (part == PART_UNSPECIFIED) part = 1; /* * If user didn't specify a partition number, or did specify something * other than "auto", use that partition number directly. */ if (part != PART_AUTO) { ret = part_get_info(*dev_desc, part, info); if (ret) { printf("** Invalid partition %d **\n", part); goto cleanup; } } else { /* * Find the first bootable partition. * If none are bootable, fall back to the first valid partition. */ part = 0; for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { ret = part_get_info(*dev_desc, p, info); if (ret) continue; /* * First valid partition, or new better partition? * If so, save partition ID. */ if (!part || info->bootable) part = p; /* Best possible partition? Stop searching. */ if (info->bootable) break; /* * We now need to search further for best possible. * If we what we just queried was the best so far, * save the info since we over-write it next loop. */ if (part == p) tmpinfo = *info; } /* If we found any acceptable partition */ if (part) { /* * If we searched all possible partition IDs, * return the first valid partition we found. */ if (p == MAX_SEARCH_PARTITIONS + 1) *info = tmpinfo; } else { printf("** No valid partitions found **\n"); ret = -1; goto cleanup; } } if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { printf("** Invalid partition type \"%.32s\"" " (expect \"" BOOT_PART_TYPE "\")\n", info->type); ret = -1; goto cleanup; } (*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz); ret = part; goto cleanup; cleanup: free(dup_str); return ret; }