*/
#include <common.h>
+#include <blk.h>
#include <command.h>
+#include <env.h>
#include <errno.h>
#include <ide.h>
+#include <log.h>
#include <malloc.h>
#include <part.h>
#include <ubifs_uboot.h>
#endif
/*
- * Overflowless variant of (block_count * mul_by / 2**div_by)
- * when div_by > mul_by
+ * Overflowless variant of (block_count * mul_by / 2**right_shift)
+ * when 2**right_shift > mul_by
*/
-static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, int div_by)
+static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by,
+ int right_shift)
{
lba512_t bc_quot, bc_rem;
/* x * m / d == x / d * m + (x % d) * m / d */
- bc_quot = block_count >> div_by;
- bc_rem = block_count - (bc_quot << div_by);
- return bc_quot * mul_by + ((bc_rem * mul_by) >> div_by);
+ bc_quot = block_count >> right_shift;
+ bc_rem = block_count - (bc_quot << right_shift);
+ return bc_quot * mul_by + ((bc_rem * mul_by) >> right_shift);
}
void dev_print (struct blk_desc *dev_desc)
case IF_TYPE_MMC:
case IF_TYPE_USB:
case IF_TYPE_NVME:
+ case IF_TYPE_PVBLOCK:
+ case IF_TYPE_HOST:
printf ("Vendor: %s Rev: %s Prod: %s\n",
dev_desc->vendor,
dev_desc->revision,
case IF_TYPE_NVME:
puts ("NVMe");
break;
+ case IF_TYPE_PVBLOCK:
+ puts("PV BLOCK");
+ break;
case IF_TYPE_VIRTIO:
puts("VirtIO");
break;
#endif /* CONFIG_HAVE_BLOCK_DEVICE */
int part_get_info(struct blk_desc *dev_desc, int part,
- disk_partition_t *info)
+ struct disk_partition *info)
{
#ifdef CONFIG_HAVE_BLOCK_DEVICE
struct part_driver *drv;
}
#endif /* CONFIG_HAVE_BLOCK_DEVICE */
- return -1;
+ return -ENOENT;
}
-int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
+int part_get_info_whole_disk(struct blk_desc *dev_desc,
+ struct disk_partition *info)
{
info->start = 0;
info->size = dev_desc->lba;
hwpart = 0;
}
- dev = simple_strtoul(dev_str, &ep, 16);
+ dev = hextoul(dev_str, &ep);
if (*ep) {
printf("** Bad device specification %s %s **\n",
ifname, dev_str);
}
if (hwpart_str) {
- hwpart = simple_strtoul(hwpart_str, &ep, 16);
+ hwpart = hextoul(hwpart_str, &ep);
if (*ep) {
printf("** Bad HW partition specification %s %s **\n",
ifname, hwpart_str);
*dev_desc = get_dev_hwpart(ifname, dev, hwpart);
if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
debug("** Bad device %s %s **\n", ifname, dev_hwpart_str);
- dev = -ENOENT;
+ dev = -ENODEV;
goto cleanup;
}
#define PART_AUTO -1
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)
+ struct disk_partition *info, int allow_whole_dev)
{
- int ret = -1;
+ int ret;
const char *part_str;
char *dup_str = NULL;
const char *dev_str;
char *ep;
int p;
int part;
- disk_partition_t tmpinfo;
+ struct disk_partition tmpinfo;
#ifdef CONFIG_SANDBOX
/*
if (0 == strcmp(ifname, "ubi")) {
if (!ubifs_is_mounted()) {
printf("UBIFS not mounted, use ubifsmount to mount volume first!\n");
- return -1;
+ return -EINVAL;
}
*dev_desc = NULL;
/* If still no dev_part_str, it's an error */
if (!dev_part_str) {
printf("** No device specified **\n");
+ ret = -ENODEV;
goto cleanup;
}
/* Look up the device */
dev = blk_get_device_by_str(ifname, dev_str, dev_desc);
- if (dev < 0)
+ if (dev < 0) {
+ ret = dev;
goto cleanup;
+ }
/* Convert partition ID string to number */
if (!part_str || !*part_str) {
part = PART_AUTO;
} else {
/* Something specified -> use exactly that */
- part = (int)simple_strtoul(part_str, &ep, 16);
+ part = (int)hextoul(part_str, &ep);
/*
* 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);
+ ret = -ENOENT;
goto cleanup;
}
}
if (!(*dev_desc)->lba) {
printf("** Bad device size - %s %s **\n", ifname,
dev_str);
+ ret = -EINVAL;
goto cleanup;
}
if ((part > 0) || (!allow_whole_dev)) {
printf("** No partition table - %s %s **\n", ifname,
dev_str);
+ ret = -EPROTONOSUPPORT;
goto cleanup;
}
*info = tmpinfo;
} else {
printf("** No valid partitions found **\n");
- ret = -1;
goto cleanup;
}
}
printf("** Invalid partition type \"%.32s\""
" (expect \"" BOOT_PART_TYPE "\")\n",
info->type);
- ret = -1;
+ ret = -EINVAL;
goto cleanup;
}
}
int part_get_info_by_name_type(struct blk_desc *dev_desc, const char *name,
- disk_partition_t *info, int part_type)
+ struct disk_partition *info, int part_type)
{
struct part_driver *part_drv;
int ret;
}
}
- return -1;
+ return -ENOENT;
}
int part_get_info_by_name(struct blk_desc *dev_desc, const char *name,
- disk_partition_t *info)
+ struct disk_partition *info)
{
return part_get_info_by_name_type(dev_desc, name, info, PART_TYPE_ALL);
}
* Get partition info from device number and partition name.
*
* Parse a device number and partition name string in the form of
- * "device_num#partition_name", for example "0#misc". If the partition
- * is found, sets dev_desc and part_info accordingly with the information
- * of the partition with the given partition_name.
+ * "devicenum.hwpartnum#partition_name", for example "0.1#misc". devicenum and
+ * hwpartnum are both optional, defaulting to 0. If the partition is found,
+ * sets dev_desc and part_info accordingly with the information of the
+ * partition with the given partition_name.
*
* @param[in] dev_iface Device interface
- * @param[in] dev_part_str Input string argument, like "0#misc"
+ * @param[in] dev_part_str Input string argument, like "0.1#misc"
* @param[out] dev_desc Place to store the device description pointer
* @param[out] part_info Place to store the partition information
* @return 0 on success, or a negative on error
static int part_get_info_by_dev_and_name(const char *dev_iface,
const char *dev_part_str,
struct blk_desc **dev_desc,
- disk_partition_t *part_info)
+ struct disk_partition *part_info)
{
- char *ep;
- const char *part_str;
- int dev_num;
+ char *dup_str = NULL;
+ const char *dev_str, *part_str;
+ int ret;
- part_str = strchr(dev_part_str, '#');
- if (!part_str || part_str == dev_part_str)
- return -EINVAL;
+ /* Separate device and partition name specification */
+ if (dev_part_str)
+ part_str = strchr(dev_part_str, '#');
+ else
+ part_str = NULL;
- dev_num = simple_strtoul(dev_part_str, &ep, 16);
- if (ep != part_str) {
- /* Not all the first part before the # was parsed. */
+ if (part_str) {
+ dup_str = strdup(dev_part_str);
+ dup_str[part_str - dev_part_str] = 0;
+ dev_str = dup_str;
+ part_str++;
+ } else {
return -EINVAL;
}
- part_str++;
- *dev_desc = blk_get_dev(dev_iface, dev_num);
- if (!*dev_desc) {
- printf("Could not find %s %d\n", dev_iface, dev_num);
- return -EINVAL;
- }
- if (part_get_info_by_name(*dev_desc, part_str, part_info) < 0) {
+ ret = blk_get_device_by_str(dev_iface, dev_str, dev_desc);
+ if (ret < 0)
+ goto cleanup;
+
+ ret = part_get_info_by_name(*dev_desc, part_str, part_info);
+ if (ret < 0)
printf("Could not find \"%s\" partition\n", part_str);
- return -EINVAL;
- }
- return 0;
+
+cleanup:
+ free(dup_str);
+ return ret;
}
int part_get_info_by_dev_and_name_or_num(const char *dev_iface,
const char *dev_part_str,
struct blk_desc **dev_desc,
- disk_partition_t *part_info)
+ struct disk_partition *part_info,
+ int allow_whole_dev)
{
+ int ret;
+
/* Split the part_name if passed as "$dev_num#part_name". */
- if (!part_get_info_by_dev_and_name(dev_iface, dev_part_str,
- dev_desc, part_info))
- return 0;
+ ret = part_get_info_by_dev_and_name(dev_iface, dev_part_str,
+ dev_desc, part_info);
+ if (ret >= 0)
+ return ret;
/*
* Couldn't lookup by name, try looking up the partition description
* directly.
*/
- if (blk_get_device_part_str(dev_iface, dev_part_str,
- dev_desc, part_info, 1) < 0) {
+ ret = blk_get_device_part_str(dev_iface, dev_part_str,
+ dev_desc, part_info, allow_whole_dev);
+ if (ret < 0)
printf("Couldn't find partition %s %s\n",
dev_iface, dev_part_str);
- return -EINVAL;
- }
- return 0;
+ return ret;
}
void part_set_generic_name(const struct blk_desc *dev_desc,