X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=disk%2Fpart.c;h=d2e34cfcfa985409c2307608ede51276653ea3be;hb=f18fa31cdcfeecaf56e61224eb18d2f2b6d39d85;hp=e353cee991d522a572a87c0de62c611231f5cd4f;hpb=50bd0057ba8fceeb48533f8b1a652ccd0e170838;p=platform%2Fkernel%2Fu-boot.git diff --git a/disk/part.c b/disk/part.c index e353cee..cb9b861 100644 --- a/disk/part.c +++ b/disk/part.c @@ -2,29 +2,16 @@ * (C) Copyright 2001 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include #include +#include #include +#include #include +#include #undef PART_DEBUG @@ -34,81 +21,98 @@ #define PRINTF(fmt,args...) #endif -#if (defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_SATA) || \ - defined(CONFIG_CMD_SCSI) || \ - defined(CONFIG_CMD_USB) || \ - defined(CONFIG_MMC) || \ - defined(CONFIG_SYSTEMACE) ) - -struct block_drvr { - char *name; - block_dev_desc_t* (*get_dev)(int dev); -}; - -static const struct block_drvr block_drvr[] = { -#if defined(CONFIG_CMD_IDE) - { .name = "ide", .get_dev = ide_get_dev, }, -#endif -#if defined(CONFIG_CMD_SATA) - {.name = "sata", .get_dev = sata_get_dev, }, -#endif -#if defined(CONFIG_CMD_SCSI) - { .name = "scsi", .get_dev = scsi_get_dev, }, -#endif -#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) - { .name = "usb", .get_dev = usb_stor_get_dev, }, -#endif -#if defined(CONFIG_MMC) - { .name = "mmc", .get_dev = mmc_get_dev, }, -#endif -#if defined(CONFIG_SYSTEMACE) - { .name = "ace", .get_dev = systemace_get_dev, }, -#endif - { }, -}; - DECLARE_GLOBAL_DATA_PTR; -block_dev_desc_t *get_dev(char* ifname, int dev) +#ifdef HAVE_BLOCK_DEVICE +static struct part_driver *part_driver_lookup_type(int part_type) { - const struct block_drvr *drvr = block_drvr; - block_dev_desc_t* (*reloc_get_dev)(int dev); - - while (drvr->name) { - reloc_get_dev = drvr->get_dev + gd->reloc_off; - if (strncmp(ifname, drvr->name, strlen(drvr->name)) == 0) - return reloc_get_dev(dev); - drvr++; + struct part_driver *drv = + ll_entry_start(struct part_driver, part_driver); + const int n_ents = ll_entry_count(struct part_driver, part_driver); + struct part_driver *entry; + + for (entry = drv; entry != drv + n_ents; entry++) { + if (part_type == entry->part_type) + return entry; } + + /* Not found */ return NULL; } + +static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) +{ + struct blk_desc *dev_desc; + int ret; + + dev_desc = blk_get_devnum_by_typename(ifname, dev); + if (!dev_desc) { + debug("%s: No device for iface '%s', dev %d\n", __func__, + ifname, dev); + return NULL; + } + ret = blk_dselect_hwpart(dev_desc, hwpart); + if (ret) { + debug("%s: Failed to select h/w partition: err-%d\n", __func__, + ret); + return NULL; + } + + return dev_desc; +} + +struct blk_desc *blk_get_dev(const char *ifname, int dev) +{ + return get_dev_hwpart(ifname, dev, 0); +} #else -block_dev_desc_t *get_dev(char* ifname, int dev) +struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) +{ + return NULL; +} + +struct blk_desc *blk_get_dev(const char *ifname, int dev) { return NULL; } #endif -#if (defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_SATA) || \ - defined(CONFIG_CMD_SCSI) || \ - defined(CONFIG_CMD_USB) || \ - defined(CONFIG_MMC) || \ - defined(CONFIG_SYSTEMACE) ) +#ifdef HAVE_BLOCK_DEVICE /* ------------------------------------------------------------------------- */ /* * reports device info to the user */ -void dev_print (block_dev_desc_t *dev_desc) -{ + #ifdef CONFIG_LBA48 - uint64_t lba512; /* number of blocks if 512bytes block size */ +typedef uint64_t lba512_t; #else - lbaint_t lba512; +typedef lbaint_t lba512_t; #endif +/* + * Overflowless variant of (block_count * mul_by / div_by) + * when div_by > mul_by + */ +static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, lba512_t div_by) +{ + 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 - div_by * bc_quot; + return bc_quot * mul_by + (bc_rem * mul_by) / div_by; +} + +void dev_print (struct blk_desc *dev_desc) +{ + lba512_t lba512; /* number of blocks if 512bytes block size */ + + if (dev_desc->type == DEV_TYPE_UNKNOWN) { + puts ("not available\n"); + return; + } + switch (dev_desc->if_type) { case IF_TYPE_SCSI: printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", @@ -164,15 +168,17 @@ void dev_print (block_dev_desc_t *dev_desc) break; } puts ("\n"); - if ((dev_desc->lba * dev_desc->blksz)>0L) { + if (dev_desc->lba > 0L && dev_desc->blksz > 0L) { ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem; lbaint_t lba; lba = dev_desc->lba; lba512 = (lba * (dev_desc->blksz/512)); - mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */ /* round to 1 digit */ + /* 2048 = (1024 * 1024) / 512 MB */ + mb = lba512_muldiv(lba512, 10, 2048); + mb_quot = mb / 10; mb_rem = mb - (10 * mb_quot); @@ -183,14 +189,14 @@ void dev_print (block_dev_desc_t *dev_desc) if (dev_desc->lba48) printf (" Supports 48-bit addressing\n"); #endif -#if defined(CONFIG_SYS_64BIT_LBA) && defined(CONFIG_SYS_64BIT_VSPRINTF) - printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%qd x %ld)\n", +#if defined(CONFIG_SYS_64BIT_LBA) + printf (" Capacity: %lu.%lu MB = %lu.%lu GB (%llu x %lu)\n", mb_quot, mb_rem, gb_quot, gb_rem, lba, dev_desc->blksz); #else - printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n", + printf (" Capacity: %lu.%lu MB = %lu.%lu GB (%lu x %lu)\n", mb_quot, mb_rem, gb_quot, gb_rem, (ulong)lba, @@ -202,116 +208,37 @@ void dev_print (block_dev_desc_t *dev_desc) } #endif -#if (defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_SATA) || \ - defined(CONFIG_CMD_SCSI) || \ - defined(CONFIG_CMD_USB) || \ - defined(CONFIG_MMC) || \ - defined(CONFIG_SYSTEMACE) ) - -#if defined(CONFIG_MAC_PARTITION) || \ - defined(CONFIG_DOS_PARTITION) || \ - defined(CONFIG_ISO_PARTITION) || \ - defined(CONFIG_AMIGA_PARTITION) || \ - defined(CONFIG_EFI_PARTITION) - -void init_part (block_dev_desc_t * dev_desc) -{ -#ifdef CONFIG_ISO_PARTITION - if (test_part_iso(dev_desc) == 0) { - dev_desc->part_type = PART_TYPE_ISO; - return; - } -#endif - -#ifdef CONFIG_MAC_PARTITION - if (test_part_mac(dev_desc) == 0) { - dev_desc->part_type = PART_TYPE_MAC; - return; - } -#endif - -/* must be placed before DOS partition detection */ -#ifdef CONFIG_EFI_PARTITION - if (test_part_efi(dev_desc) == 0) { - dev_desc->part_type = PART_TYPE_EFI; - return; - } -#endif - -#ifdef CONFIG_DOS_PARTITION - if (test_part_dos(dev_desc) == 0) { - dev_desc->part_type = PART_TYPE_DOS; - return; - } -#endif - -#ifdef CONFIG_AMIGA_PARTITION - if (test_part_amiga(dev_desc) == 0) { - dev_desc->part_type = PART_TYPE_AMIGA; - return; - } -#endif -} - +#ifdef HAVE_BLOCK_DEVICE -int get_partition_info (block_dev_desc_t *dev_desc, int part - , disk_partition_t *info) +void part_init(struct blk_desc *dev_desc) { - switch (dev_desc->part_type) { -#ifdef CONFIG_MAC_PARTITION - case PART_TYPE_MAC: - if (get_partition_info_mac(dev_desc,part,info) == 0) { - PRINTF ("## Valid MAC partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_DOS_PARTITION - case PART_TYPE_DOS: - if (get_partition_info_dos(dev_desc,part,info) == 0) { - PRINTF ("## Valid DOS partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_ISO_PARTITION - case PART_TYPE_ISO: - if (get_partition_info_iso(dev_desc,part,info) == 0) { - PRINTF ("## Valid ISO boot partition found ##\n"); - return (0); + struct part_driver *drv = + ll_entry_start(struct part_driver, part_driver); + 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); + + dev_desc->part_type = PART_TYPE_UNKNOWN; + for (entry = drv; entry != drv + n_ents; entry++) { + int ret; + + ret = entry->test(dev_desc); + debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret); + if (!ret) { + dev_desc->part_type = entry->part_type; + break; } - break; -#endif - -#ifdef CONFIG_AMIGA_PARTITION - case PART_TYPE_AMIGA: - if (get_partition_info_amiga(dev_desc, part, info) == 0) - { - PRINTF ("## Valid Amiga partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_EFI_PARTITION - case PART_TYPE_EFI: - if (get_partition_info_efi(dev_desc,part,info) == 0) { - PRINTF ("## Valid EFI partition found ##\n"); - return (0); - } - break; -#endif - default: - break; } - return (-1); } -static void print_part_header (const char *type, block_dev_desc_t * dev_desc) +static void print_part_header(const char *type, struct blk_desc *dev_desc) { +#if CONFIG_IS_ENABLED(MAC_PARTITION) || \ + defined(CONFIG_DOS_PARTITION) || \ + defined(CONFIG_ISO_PARTITION) || \ + defined(CONFIG_AMIGA_PARTITION) || \ + defined(CONFIG_EFI_PARTITION) puts ("\nPartition Map for "); switch (dev_desc->if_type) { case IF_TYPE_IDE: @@ -332,65 +259,417 @@ static void print_part_header (const char *type, block_dev_desc_t * dev_desc) case IF_TYPE_DOC: puts ("DOC"); break; + case IF_TYPE_MMC: + puts ("MMC"); + break; + case IF_TYPE_HOST: + puts("HOST"); + break; default: puts ("UNKNOWN"); break; } printf (" device %d -- Partition Type: %s\n\n", - dev_desc->dev, type); + dev_desc->devnum, type); +#endif /* any CONFIG_..._PARTITION */ } -void print_part (block_dev_desc_t * dev_desc) +void part_print(struct blk_desc *dev_desc) { + struct part_driver *drv; - switch (dev_desc->part_type) { -#ifdef CONFIG_MAC_PARTITION - case PART_TYPE_MAC: - PRINTF ("## Testing for valid MAC partition ##\n"); - print_part_header ("MAC", dev_desc); - print_part_mac (dev_desc); + drv = part_driver_lookup_type(dev_desc->part_type); + if (!drv) { + printf("## Unknown partition table type %x\n", + dev_desc->part_type); return; + } + + PRINTF("## Testing for valid %s partition ##\n", drv->name); + print_part_header(drv->name, dev_desc); + if (drv->print) + drv->print(dev_desc); +} + +#endif /* HAVE_BLOCK_DEVICE */ + +int part_get_info(struct blk_desc *dev_desc, int part, + disk_partition_t *info) +{ +#ifdef HAVE_BLOCK_DEVICE + struct part_driver *drv; + +#ifdef CONFIG_PARTITION_UUIDS + /* The common case is no UUID support */ + info->uuid[0] = 0; #endif -#ifdef CONFIG_DOS_PARTITION - case PART_TYPE_DOS: - PRINTF ("## Testing for valid DOS partition ##\n"); - print_part_header ("DOS", dev_desc); - print_part_dos (dev_desc); - return; +#ifdef CONFIG_PARTITION_TYPE_GUID + info->type_guid[0] = 0; #endif -#ifdef CONFIG_ISO_PARTITION - case PART_TYPE_ISO: - PRINTF ("## Testing for valid ISO Boot partition ##\n"); - print_part_header ("ISO", dev_desc); - print_part_iso (dev_desc); - return; -#endif + drv = part_driver_lookup_type(dev_desc->part_type); + if (!drv) { + debug("## Unknown partition table type %x\n", + dev_desc->part_type); + return -EPROTONOSUPPORT; + } + if (!drv->get_info) { + PRINTF("## Driver %s does not have the get_info() method\n", + drv->name); + return -ENOSYS; + } + if (drv->get_info(dev_desc, part, info) == 0) { + PRINTF("## Valid %s partition found ##\n", drv->name); + return 0; + } +#endif /* HAVE_BLOCK_DEVICE */ + + return -1; +} + +int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, + struct blk_desc **dev_desc) +{ + char *ep; + 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 = 0; + } + + dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s %s **\n", + ifname, dev_str); + dev = -EINVAL; + goto cleanup; + } -#ifdef CONFIG_AMIGA_PARTITION - case PART_TYPE_AMIGA: - PRINTF ("## Testing for a valid Amiga partition ##\n"); - print_part_header ("AMIGA", dev_desc); - print_part_amiga (dev_desc); - return; + if (hwpart_str) { + hwpart = simple_strtoul(hwpart_str, &ep, 16); + if (*ep) { + printf("** Bad HW partition specification %s %s **\n", + ifname, hwpart_str); + dev = -EINVAL; + goto cleanup; + } + } + + *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_hwpart_str); + dev = -ENOENT; + goto cleanup; + } + +#ifdef HAVE_BLOCK_DEVICE + /* + * Updates the partition table for the specified hw partition. + * Does not need to be done for hwpart 0 since it is default and + * already loaded. + */ + if(hwpart != 0) + part_init(*dev_desc); #endif -#ifdef CONFIG_EFI_PARTITION - case PART_TYPE_EFI: - PRINTF ("## Testing for valid EFI partition ##\n"); - print_part_header ("EFI", dev_desc); - print_part_efi (dev_desc); - return; +cleanup: + free(dup_str); + return dev; +} + +#define PART_UNSPECIFIED -2 +#define PART_AUTO -1 +#define MAX_SEARCH_PARTITIONS 16 +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; } - puts ("## Unknown partition table\n"); -} +#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; + } -#else /* neither MAC nor DOS nor ISO nor AMIGA nor EFI partition configured */ -# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION -# error nor CONFIG_ISO_PARTITION nor CONFIG_AMIGA_PARTITION -# error nor CONFIG_EFI_PARTITION configured! + *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; +} + +int part_get_info_by_name(struct blk_desc *dev_desc, const char *name, + disk_partition_t *info) +{ + struct part_driver *first_drv = + ll_entry_start(struct part_driver, part_driver); + const int n_drvs = ll_entry_count(struct part_driver, part_driver); + struct part_driver *part_drv; + + for (part_drv = first_drv; part_drv != first_drv + n_drvs; part_drv++) { + int ret; + int i; + for (i = 1; i < part_drv->max_entries; i++) { + ret = part_drv->get_info(dev_desc, i, info); + if (ret != 0) { + /* no more entries in table */ + break; + } + if (strcmp(name, (const char *)info->name) == 0) { + /* matched */ + return 0; + } + } + } + return -1; +} + +void part_set_generic_name(const struct blk_desc *dev_desc, + int part_num, char *name) +{ + char *devtype; + + switch (dev_desc->if_type) { + case IF_TYPE_IDE: + case IF_TYPE_SATA: + case IF_TYPE_ATAPI: + devtype = "hd"; + break; + case IF_TYPE_SCSI: + devtype = "sd"; + break; + case IF_TYPE_USB: + devtype = "usbd"; + break; + case IF_TYPE_DOC: + devtype = "docd"; + break; + case IF_TYPE_MMC: + case IF_TYPE_SD: + devtype = "mmcsd"; + break; + default: + devtype = "xx"; + break; + } + + sprintf(name, "%s%c%d", devtype, 'a' + dev_desc->devnum, part_num); +}