|
@@ -22,6 +22,7 @@
|
|
|
struct block_drvr {
|
|
|
char *name;
|
|
|
block_dev_desc_t* (*get_dev)(int dev);
|
|
|
+ int (*select_hwpart)(int dev_num, int hwpart);
|
|
|
};
|
|
|
|
|
|
static const struct block_drvr block_drvr[] = {
|
|
@@ -52,11 +53,13 @@ static const struct block_drvr block_drvr[] = {
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
|
#ifdef HAVE_BLOCK_DEVICE
|
|
|
-block_dev_desc_t *get_dev(const char *ifname, int dev)
|
|
|
+block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
|
|
|
{
|
|
|
const struct block_drvr *drvr = block_drvr;
|
|
|
block_dev_desc_t* (*reloc_get_dev)(int dev);
|
|
|
+ int (*select_hwpart)(int dev_num, int hwpart);
|
|
|
char *name;
|
|
|
+ int ret;
|
|
|
|
|
|
if (!ifname)
|
|
|
return NULL;
|
|
@@ -68,17 +71,41 @@ block_dev_desc_t *get_dev(const char *ifname, int dev)
|
|
|
while (drvr->name) {
|
|
|
name = drvr->name;
|
|
|
reloc_get_dev = drvr->get_dev;
|
|
|
+ select_hwpart = drvr->select_hwpart;
|
|
|
#ifdef CONFIG_NEEDS_MANUAL_RELOC
|
|
|
name += gd->reloc_off;
|
|
|
reloc_get_dev += gd->reloc_off;
|
|
|
-#endif
|
|
|
- if (strncmp(ifname, name, strlen(name)) == 0)
|
|
|
- return reloc_get_dev(dev);
|
|
|
+ if (select_hwpart)
|
|
|
+ select_hwpart += gd->reloc_off;
|
|
|
+#endif
|
|
|
+ if (strncmp(ifname, name, strlen(name)) == 0) {
|
|
|
+ block_dev_desc_t *dev_desc = reloc_get_dev(dev);
|
|
|
+ if (!dev_desc)
|
|
|
+ return NULL;
|
|
|
+ if (hwpart == -1)
|
|
|
+ return dev_desc;
|
|
|
+ if (!select_hwpart)
|
|
|
+ return NULL;
|
|
|
+ ret = select_hwpart(dev_desc->dev, hwpart);
|
|
|
+ if (ret < 0)
|
|
|
+ return NULL;
|
|
|
+ return dev_desc;
|
|
|
+ }
|
|
|
drvr++;
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
+
|
|
|
+block_dev_desc_t *get_dev(const char *ifname, int dev)
|
|
|
+{
|
|
|
+ return get_dev_hwpart(ifname, dev, -1);
|
|
|
+}
|
|
|
#else
|
|
|
+block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart)
|
|
|
+{
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
block_dev_desc_t *get_dev(const char *ifname, int dev)
|
|
|
{
|
|
|
return NULL;
|
|
@@ -413,25 +440,52 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
-int get_device(const char *ifname, const char *dev_str,
|
|
|
+int get_device(const char *ifname, const char *dev_hwpart_str,
|
|
|
block_dev_desc_t **dev_desc)
|
|
|
{
|
|
|
char *ep;
|
|
|
- int dev;
|
|
|
+ char *dup_str = NULL;
|
|
|
+ const char *dev_str, *hwpart_str;
|
|
|
+ int dev, hwpart;
|
|
|
+
|
|
|
+ hwpart_str = strchr(dev_hwpart_str, '.');
|
|
|
+ if (hwpart_str) {
|
|
|
+ dup_str = strdup(dev_hwpart_str);
|
|
|
+ dup_str[hwpart_str - dev_hwpart_str] = 0;
|
|
|
+ dev_str = dup_str;
|
|
|
+ hwpart_str++;
|
|
|
+ } else {
|
|
|
+ dev_str = dev_hwpart_str;
|
|
|
+ hwpart = -1;
|
|
|
+ }
|
|
|
|
|
|
dev = simple_strtoul(dev_str, &ep, 16);
|
|
|
if (*ep) {
|
|
|
printf("** Bad device specification %s %s **\n",
|
|
|
ifname, dev_str);
|
|
|
- return -1;
|
|
|
+ dev = -1;
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (hwpart_str) {
|
|
|
+ hwpart = simple_strtoul(hwpart_str, &ep, 16);
|
|
|
+ if (*ep) {
|
|
|
+ printf("** Bad HW partition specification %s %s **\n",
|
|
|
+ ifname, hwpart_str);
|
|
|
+ dev = -1;
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- *dev_desc = get_dev(ifname, dev);
|
|
|
+ *dev_desc = get_dev_hwpart(ifname, dev, hwpart);
|
|
|
if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
|
|
|
- printf("** Bad device %s %s **\n", ifname, dev_str);
|
|
|
- return -1;
|
|
|
+ printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
|
|
|
+ dev = -1;
|
|
|
+ goto cleanup;
|
|
|
}
|
|
|
|
|
|
+cleanup:
|
|
|
+ free(dup_str);
|
|
|
return dev;
|
|
|
}
|
|
|
|