Home | History | Annotate | Download | only in disk
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2001
      4  * Wolfgang Denk, DENX Software Engineering, wd (at) denx.de.
      5  */
      6 
      7 #include <common.h>
      8 #include <command.h>
      9 #include <errno.h>
     10 #include <ide.h>
     11 #include <malloc.h>
     12 #include <part.h>
     13 #include <ubifs_uboot.h>
     14 
     15 #undef	PART_DEBUG
     16 
     17 #ifdef	PART_DEBUG
     18 #define	PRINTF(fmt,args...)	printf (fmt ,##args)
     19 #else
     20 #define PRINTF(fmt,args...)
     21 #endif
     22 
     23 /* Check all partition types */
     24 #define PART_TYPE_ALL		-1
     25 
     26 static struct part_driver *part_driver_lookup_type(struct blk_desc *dev_desc)
     27 {
     28 	struct part_driver *drv =
     29 		ll_entry_start(struct part_driver, part_driver);
     30 	const int n_ents = ll_entry_count(struct part_driver, part_driver);
     31 	struct part_driver *entry;
     32 
     33 	if (dev_desc->part_type == PART_TYPE_UNKNOWN) {
     34 		for (entry = drv; entry != drv + n_ents; entry++) {
     35 			int ret;
     36 
     37 			ret = entry->test(dev_desc);
     38 			if (!ret) {
     39 				dev_desc->part_type = entry->part_type;
     40 				return entry;
     41 			}
     42 		}
     43 	} else {
     44 		for (entry = drv; entry != drv + n_ents; entry++) {
     45 			if (dev_desc->part_type == entry->part_type)
     46 				return entry;
     47 		}
     48 	}
     49 
     50 	/* Not found */
     51 	return NULL;
     52 }
     53 
     54 #ifdef CONFIG_HAVE_BLOCK_DEVICE
     55 static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
     56 {
     57 	struct blk_desc *dev_desc;
     58 	int ret;
     59 
     60 	dev_desc = blk_get_devnum_by_typename(ifname, dev);
     61 	if (!dev_desc) {
     62 		debug("%s: No device for iface '%s', dev %d\n", __func__,
     63 		      ifname, dev);
     64 		return NULL;
     65 	}
     66 	ret = blk_dselect_hwpart(dev_desc, hwpart);
     67 	if (ret) {
     68 		debug("%s: Failed to select h/w partition: err-%d\n", __func__,
     69 		      ret);
     70 		return NULL;
     71 	}
     72 
     73 	return dev_desc;
     74 }
     75 
     76 struct blk_desc *blk_get_dev(const char *ifname, int dev)
     77 {
     78 	return get_dev_hwpart(ifname, dev, 0);
     79 }
     80 #else
     81 struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart)
     82 {
     83 	return NULL;
     84 }
     85 
     86 struct blk_desc *blk_get_dev(const char *ifname, int dev)
     87 {
     88 	return NULL;
     89 }
     90 #endif
     91 
     92 #ifdef CONFIG_HAVE_BLOCK_DEVICE
     93 
     94 /* ------------------------------------------------------------------------- */
     95 /*
     96  * reports device info to the user
     97  */
     98 
     99 #ifdef CONFIG_LBA48
    100 typedef uint64_t lba512_t;
    101 #else
    102 typedef lbaint_t lba512_t;
    103 #endif
    104 
    105 /*
    106  * Overflowless variant of (block_count * mul_by / div_by)
    107  * when div_by > mul_by
    108  */
    109 static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, lba512_t div_by)
    110 {
    111 	lba512_t bc_quot, bc_rem;
    112 
    113 	/* x * m / d == x / d * m + (x % d) * m / d */
    114 	bc_quot = block_count / div_by;
    115 	bc_rem  = block_count - div_by * bc_quot;
    116 	return bc_quot * mul_by + (bc_rem * mul_by) / div_by;
    117 }
    118 
    119 void dev_print (struct blk_desc *dev_desc)
    120 {
    121 	lba512_t lba512; /* number of blocks if 512bytes block size */
    122 
    123 	if (dev_desc->type == DEV_TYPE_UNKNOWN) {
    124 		puts ("not available\n");
    125 		return;
    126 	}
    127 
    128 	switch (dev_desc->if_type) {
    129 	case IF_TYPE_SCSI:
    130 		printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
    131 			dev_desc->target,dev_desc->lun,
    132 			dev_desc->vendor,
    133 			dev_desc->product,
    134 			dev_desc->revision);
    135 		break;
    136 	case IF_TYPE_ATAPI:
    137 	case IF_TYPE_IDE:
    138 	case IF_TYPE_SATA:
    139 		printf ("Model: %s Firm: %s Ser#: %s\n",
    140 			dev_desc->vendor,
    141 			dev_desc->revision,
    142 			dev_desc->product);
    143 		break;
    144 	case IF_TYPE_SD:
    145 	case IF_TYPE_MMC:
    146 	case IF_TYPE_USB:
    147 	case IF_TYPE_NVME:
    148 		printf ("Vendor: %s Rev: %s Prod: %s\n",
    149 			dev_desc->vendor,
    150 			dev_desc->revision,
    151 			dev_desc->product);
    152 		break;
    153 	case IF_TYPE_DOC:
    154 		puts("device type DOC\n");
    155 		return;
    156 	case IF_TYPE_UNKNOWN:
    157 		puts("device type unknown\n");
    158 		return;
    159 	default:
    160 		printf("Unhandled device type: %i\n", dev_desc->if_type);
    161 		return;
    162 	}
    163 	puts ("            Type: ");
    164 	if (dev_desc->removable)
    165 		puts ("Removable ");
    166 	switch (dev_desc->type & 0x1F) {
    167 	case DEV_TYPE_HARDDISK:
    168 		puts ("Hard Disk");
    169 		break;
    170 	case DEV_TYPE_CDROM:
    171 		puts ("CD ROM");
    172 		break;
    173 	case DEV_TYPE_OPDISK:
    174 		puts ("Optical Device");
    175 		break;
    176 	case DEV_TYPE_TAPE:
    177 		puts ("Tape");
    178 		break;
    179 	default:
    180 		printf ("# %02X #", dev_desc->type & 0x1F);
    181 		break;
    182 	}
    183 	puts ("\n");
    184 	if (dev_desc->lba > 0L && dev_desc->blksz > 0L) {
    185 		ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
    186 		lbaint_t lba;
    187 
    188 		lba = dev_desc->lba;
    189 
    190 		lba512 = (lba * (dev_desc->blksz/512));
    191 		/* round to 1 digit */
    192 		/* 2048 = (1024 * 1024) / 512 MB */
    193 		mb = lba512_muldiv(lba512, 10, 2048);
    194 
    195 		mb_quot	= mb / 10;
    196 		mb_rem	= mb - (10 * mb_quot);
    197 
    198 		gb = mb / 1024;
    199 		gb_quot	= gb / 10;
    200 		gb_rem	= gb - (10 * gb_quot);
    201 #ifdef CONFIG_LBA48
    202 		if (dev_desc->lba48)
    203 			printf ("            Supports 48-bit addressing\n");
    204 #endif
    205 #if defined(CONFIG_SYS_64BIT_LBA)
    206 		printf ("            Capacity: %lu.%lu MB = %lu.%lu GB (%llu x %lu)\n",
    207 			mb_quot, mb_rem,
    208 			gb_quot, gb_rem,
    209 			lba,
    210 			dev_desc->blksz);
    211 #else
    212 		printf ("            Capacity: %lu.%lu MB = %lu.%lu GB (%lu x %lu)\n",
    213 			mb_quot, mb_rem,
    214 			gb_quot, gb_rem,
    215 			(ulong)lba,
    216 			dev_desc->blksz);
    217 #endif
    218 	} else {
    219 		puts ("            Capacity: not available\n");
    220 	}
    221 }
    222 #endif
    223 
    224 #ifdef CONFIG_HAVE_BLOCK_DEVICE
    225 
    226 void part_init(struct blk_desc *dev_desc)
    227 {
    228 	struct part_driver *drv =
    229 		ll_entry_start(struct part_driver, part_driver);
    230 	const int n_ents = ll_entry_count(struct part_driver, part_driver);
    231 	struct part_driver *entry;
    232 
    233 	blkcache_invalidate(dev_desc->if_type, dev_desc->devnum);
    234 
    235 	dev_desc->part_type = PART_TYPE_UNKNOWN;
    236 	for (entry = drv; entry != drv + n_ents; entry++) {
    237 		int ret;
    238 
    239 		ret = entry->test(dev_desc);
    240 		debug("%s: try '%s': ret=%d\n", __func__, entry->name, ret);
    241 		if (!ret) {
    242 			dev_desc->part_type = entry->part_type;
    243 			break;
    244 		}
    245 	}
    246 }
    247 
    248 static void print_part_header(const char *type, struct blk_desc *dev_desc)
    249 {
    250 #if CONFIG_IS_ENABLED(MAC_PARTITION) || \
    251 	CONFIG_IS_ENABLED(DOS_PARTITION) || \
    252 	CONFIG_IS_ENABLED(ISO_PARTITION) || \
    253 	CONFIG_IS_ENABLED(AMIGA_PARTITION) || \
    254 	CONFIG_IS_ENABLED(EFI_PARTITION)
    255 	puts ("\nPartition Map for ");
    256 	switch (dev_desc->if_type) {
    257 	case IF_TYPE_IDE:
    258 		puts ("IDE");
    259 		break;
    260 	case IF_TYPE_SATA:
    261 		puts ("SATA");
    262 		break;
    263 	case IF_TYPE_SCSI:
    264 		puts ("SCSI");
    265 		break;
    266 	case IF_TYPE_ATAPI:
    267 		puts ("ATAPI");
    268 		break;
    269 	case IF_TYPE_USB:
    270 		puts ("USB");
    271 		break;
    272 	case IF_TYPE_DOC:
    273 		puts ("DOC");
    274 		break;
    275 	case IF_TYPE_MMC:
    276 		puts ("MMC");
    277 		break;
    278 	case IF_TYPE_HOST:
    279 		puts ("HOST");
    280 		break;
    281 	case IF_TYPE_NVME:
    282 		puts ("NVMe");
    283 		break;
    284 	default:
    285 		puts ("UNKNOWN");
    286 		break;
    287 	}
    288 	printf (" device %d  --   Partition Type: %s\n\n",
    289 			dev_desc->devnum, type);
    290 #endif /* any CONFIG_..._PARTITION */
    291 }
    292 
    293 void part_print(struct blk_desc *dev_desc)
    294 {
    295 	struct part_driver *drv;
    296 
    297 	drv = part_driver_lookup_type(dev_desc);
    298 	if (!drv) {
    299 		printf("## Unknown partition table type %x\n",
    300 		       dev_desc->part_type);
    301 		return;
    302 	}
    303 
    304 	PRINTF("## Testing for valid %s partition ##\n", drv->name);
    305 	print_part_header(drv->name, dev_desc);
    306 	if (drv->print)
    307 		drv->print(dev_desc);
    308 }
    309 
    310 #endif /* CONFIG_HAVE_BLOCK_DEVICE */
    311 
    312 int part_get_info(struct blk_desc *dev_desc, int part,
    313 		       disk_partition_t *info)
    314 {
    315 #ifdef CONFIG_HAVE_BLOCK_DEVICE
    316 	struct part_driver *drv;
    317 
    318 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
    319 	/* The common case is no UUID support */
    320 	info->uuid[0] = 0;
    321 #endif
    322 #ifdef CONFIG_PARTITION_TYPE_GUID
    323 	info->type_guid[0] = 0;
    324 #endif
    325 
    326 	drv = part_driver_lookup_type(dev_desc);
    327 	if (!drv) {
    328 		debug("## Unknown partition table type %x\n",
    329 		      dev_desc->part_type);
    330 		return -EPROTONOSUPPORT;
    331 	}
    332 	if (!drv->get_info) {
    333 		PRINTF("## Driver %s does not have the get_info() method\n",
    334 		       drv->name);
    335 		return -ENOSYS;
    336 	}
    337 	if (drv->get_info(dev_desc, part, info) == 0) {
    338 		PRINTF("## Valid %s partition found ##\n", drv->name);
    339 		return 0;
    340 	}
    341 #endif /* CONFIG_HAVE_BLOCK_DEVICE */
    342 
    343 	return -1;
    344 }
    345 
    346 int part_get_info_whole_disk(struct blk_desc *dev_desc, disk_partition_t *info)
    347 {
    348 	info->start = 0;
    349 	info->size = dev_desc->lba;
    350 	info->blksz = dev_desc->blksz;
    351 	info->bootable = 0;
    352 	strcpy((char *)info->type, BOOT_PART_TYPE);
    353 	strcpy((char *)info->name, "Whole Disk");
    354 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
    355 	info->uuid[0] = 0;
    356 #endif
    357 #ifdef CONFIG_PARTITION_TYPE_GUID
    358 	info->type_guid[0] = 0;
    359 #endif
    360 
    361 	return 0;
    362 }
    363 
    364 int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str,
    365 			  struct blk_desc **dev_desc)
    366 {
    367 	char *ep;
    368 	char *dup_str = NULL;
    369 	const char *dev_str, *hwpart_str;
    370 	int dev, hwpart;
    371 
    372 	hwpart_str = strchr(dev_hwpart_str, '.');
    373 	if (hwpart_str) {
    374 		dup_str = strdup(dev_hwpart_str);
    375 		dup_str[hwpart_str - dev_hwpart_str] = 0;
    376 		dev_str = dup_str;
    377 		hwpart_str++;
    378 	} else {
    379 		dev_str = dev_hwpart_str;
    380 		hwpart = 0;
    381 	}
    382 
    383 	dev = simple_strtoul(dev_str, &ep, 16);
    384 	if (*ep) {
    385 		printf("** Bad device specification %s %s **\n",
    386 		       ifname, dev_str);
    387 		dev = -EINVAL;
    388 		goto cleanup;
    389 	}
    390 
    391 	if (hwpart_str) {
    392 		hwpart = simple_strtoul(hwpart_str, &ep, 16);
    393 		if (*ep) {
    394 			printf("** Bad HW partition specification %s %s **\n",
    395 			    ifname, hwpart_str);
    396 			dev = -EINVAL;
    397 			goto cleanup;
    398 		}
    399 	}
    400 
    401 	*dev_desc = get_dev_hwpart(ifname, dev, hwpart);
    402 	if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) {
    403 		printf("** Bad device %s %s **\n", ifname, dev_hwpart_str);
    404 		dev = -ENOENT;
    405 		goto cleanup;
    406 	}
    407 
    408 #ifdef CONFIG_HAVE_BLOCK_DEVICE
    409 	/*
    410 	 * Updates the partition table for the specified hw partition.
    411 	 * Does not need to be done for hwpart 0 since it is default and
    412 	 * already loaded.
    413 	 */
    414 	if(hwpart != 0)
    415 		part_init(*dev_desc);
    416 #endif
    417 
    418 cleanup:
    419 	free(dup_str);
    420 	return dev;
    421 }
    422 
    423 #define PART_UNSPECIFIED -2
    424 #define PART_AUTO -1
    425 int blk_get_device_part_str(const char *ifname, const char *dev_part_str,
    426 			     struct blk_desc **dev_desc,
    427 			     disk_partition_t *info, int allow_whole_dev)
    428 {
    429 	int ret = -1;
    430 	const char *part_str;
    431 	char *dup_str = NULL;
    432 	const char *dev_str;
    433 	int dev;
    434 	char *ep;
    435 	int p;
    436 	int part;
    437 	disk_partition_t tmpinfo;
    438 
    439 #ifdef CONFIG_SANDBOX
    440 	/*
    441 	 * Special-case a pseudo block device "hostfs", to allow access to the
    442 	 * host's own filesystem.
    443 	 */
    444 	if (0 == strcmp(ifname, "hostfs")) {
    445 		*dev_desc = NULL;
    446 		info->start = 0;
    447 		info->size = 0;
    448 		info->blksz = 0;
    449 		info->bootable = 0;
    450 		strcpy((char *)info->type, BOOT_PART_TYPE);
    451 		strcpy((char *)info->name, "Sandbox host");
    452 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
    453 		info->uuid[0] = 0;
    454 #endif
    455 #ifdef CONFIG_PARTITION_TYPE_GUID
    456 		info->type_guid[0] = 0;
    457 #endif
    458 
    459 		return 0;
    460 	}
    461 #endif
    462 
    463 #ifdef CONFIG_CMD_UBIFS
    464 	/*
    465 	 * Special-case ubi, ubi goes through a mtd, rathen then through
    466 	 * a regular block device.
    467 	 */
    468 	if (0 == strcmp(ifname, "ubi")) {
    469 		if (!ubifs_is_mounted()) {
    470 			printf("UBIFS not mounted, use ubifsmount to mount volume first!\n");
    471 			return -1;
    472 		}
    473 
    474 		*dev_desc = NULL;
    475 		memset(info, 0, sizeof(*info));
    476 		strcpy((char *)info->type, BOOT_PART_TYPE);
    477 		strcpy((char *)info->name, "UBI");
    478 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
    479 		info->uuid[0] = 0;
    480 #endif
    481 		return 0;
    482 	}
    483 #endif
    484 
    485 	/* If no dev_part_str, use bootdevice environment variable */
    486 	if (!dev_part_str || !strlen(dev_part_str) ||
    487 	    !strcmp(dev_part_str, "-"))
    488 		dev_part_str = env_get("bootdevice");
    489 
    490 	/* If still no dev_part_str, it's an error */
    491 	if (!dev_part_str) {
    492 		printf("** No device specified **\n");
    493 		goto cleanup;
    494 	}
    495 
    496 	/* Separate device and partition ID specification */
    497 	part_str = strchr(dev_part_str, ':');
    498 	if (part_str) {
    499 		dup_str = strdup(dev_part_str);
    500 		dup_str[part_str - dev_part_str] = 0;
    501 		dev_str = dup_str;
    502 		part_str++;
    503 	} else {
    504 		dev_str = dev_part_str;
    505 	}
    506 
    507 	/* Look up the device */
    508 	dev = blk_get_device_by_str(ifname, dev_str, dev_desc);
    509 	if (dev < 0)
    510 		goto cleanup;
    511 
    512 	/* Convert partition ID string to number */
    513 	if (!part_str || !*part_str) {
    514 		part = PART_UNSPECIFIED;
    515 	} else if (!strcmp(part_str, "auto")) {
    516 		part = PART_AUTO;
    517 	} else {
    518 		/* Something specified -> use exactly that */
    519 		part = (int)simple_strtoul(part_str, &ep, 16);
    520 		/*
    521 		 * Less than whole string converted,
    522 		 * or request for whole device, but caller requires partition.
    523 		 */
    524 		if (*ep || (part == 0 && !allow_whole_dev)) {
    525 			printf("** Bad partition specification %s %s **\n",
    526 			    ifname, dev_part_str);
    527 			goto cleanup;
    528 		}
    529 	}
    530 
    531 	/*
    532 	 * No partition table on device,
    533 	 * or user requested partition 0 (entire device).
    534 	 */
    535 	if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) ||
    536 	    (part == 0)) {
    537 		if (!(*dev_desc)->lba) {
    538 			printf("** Bad device size - %s %s **\n", ifname,
    539 			       dev_str);
    540 			goto cleanup;
    541 		}
    542 
    543 		/*
    544 		 * If user specified a partition ID other than 0,
    545 		 * or the calling command only accepts partitions,
    546 		 * it's an error.
    547 		 */
    548 		if ((part > 0) || (!allow_whole_dev)) {
    549 			printf("** No partition table - %s %s **\n", ifname,
    550 			       dev_str);
    551 			goto cleanup;
    552 		}
    553 
    554 		(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
    555 
    556 		part_get_info_whole_disk(*dev_desc, info);
    557 
    558 		ret = 0;
    559 		goto cleanup;
    560 	}
    561 
    562 	/*
    563 	 * Now there's known to be a partition table,
    564 	 * not specifying a partition means to pick partition 1.
    565 	 */
    566 	if (part == PART_UNSPECIFIED)
    567 		part = 1;
    568 
    569 	/*
    570 	 * If user didn't specify a partition number, or did specify something
    571 	 * other than "auto", use that partition number directly.
    572 	 */
    573 	if (part != PART_AUTO) {
    574 		ret = part_get_info(*dev_desc, part, info);
    575 		if (ret) {
    576 			printf("** Invalid partition %d **\n", part);
    577 			goto cleanup;
    578 		}
    579 	} else {
    580 		/*
    581 		 * Find the first bootable partition.
    582 		 * If none are bootable, fall back to the first valid partition.
    583 		 */
    584 		part = 0;
    585 		for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
    586 			ret = part_get_info(*dev_desc, p, info);
    587 			if (ret)
    588 				continue;
    589 
    590 			/*
    591 			 * First valid partition, or new better partition?
    592 			 * If so, save partition ID.
    593 			 */
    594 			if (!part || info->bootable)
    595 				part = p;
    596 
    597 			/* Best possible partition? Stop searching. */
    598 			if (info->bootable)
    599 				break;
    600 
    601 			/*
    602 			 * We now need to search further for best possible.
    603 			 * If we what we just queried was the best so far,
    604 			 * save the info since we over-write it next loop.
    605 			 */
    606 			if (part == p)
    607 				tmpinfo = *info;
    608 		}
    609 		/* If we found any acceptable partition */
    610 		if (part) {
    611 			/*
    612 			 * If we searched all possible partition IDs,
    613 			 * return the first valid partition we found.
    614 			 */
    615 			if (p == MAX_SEARCH_PARTITIONS + 1)
    616 				*info = tmpinfo;
    617 		} else {
    618 			printf("** No valid partitions found **\n");
    619 			ret = -1;
    620 			goto cleanup;
    621 		}
    622 	}
    623 	if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) {
    624 		printf("** Invalid partition type \"%.32s\""
    625 			" (expect \"" BOOT_PART_TYPE "\")\n",
    626 			info->type);
    627 		ret  = -1;
    628 		goto cleanup;
    629 	}
    630 
    631 	(*dev_desc)->log2blksz = LOG2((*dev_desc)->blksz);
    632 
    633 	ret = part;
    634 	goto cleanup;
    635 
    636 cleanup:
    637 	free(dup_str);
    638 	return ret;
    639 }
    640 
    641 int part_get_info_by_name_type(struct blk_desc *dev_desc, const char *name,
    642 			       disk_partition_t *info, int part_type)
    643 {
    644 	struct part_driver *part_drv;
    645 	int ret;
    646 	int i;
    647 
    648 	part_drv = part_driver_lookup_type(dev_desc);
    649 	if (!part_drv)
    650 		return -1;
    651 	for (i = 1; i < part_drv->max_entries; i++) {
    652 		ret = part_drv->get_info(dev_desc, i, info);
    653 		if (ret != 0) {
    654 			/* no more entries in table */
    655 			break;
    656 		}
    657 		if (strcmp(name, (const char *)info->name) == 0) {
    658 			/* matched */
    659 			return i;
    660 		}
    661 	}
    662 
    663 	return -1;
    664 }
    665 
    666 int part_get_info_by_name(struct blk_desc *dev_desc, const char *name,
    667 			  disk_partition_t *info)
    668 {
    669 	return part_get_info_by_name_type(dev_desc, name, info, PART_TYPE_ALL);
    670 }
    671 
    672 void part_set_generic_name(const struct blk_desc *dev_desc,
    673 	int part_num, char *name)
    674 {
    675 	char *devtype;
    676 
    677 	switch (dev_desc->if_type) {
    678 	case IF_TYPE_IDE:
    679 	case IF_TYPE_SATA:
    680 	case IF_TYPE_ATAPI:
    681 		devtype = "hd";
    682 		break;
    683 	case IF_TYPE_SCSI:
    684 		devtype = "sd";
    685 		break;
    686 	case IF_TYPE_USB:
    687 		devtype = "usbd";
    688 		break;
    689 	case IF_TYPE_DOC:
    690 		devtype = "docd";
    691 		break;
    692 	case IF_TYPE_MMC:
    693 	case IF_TYPE_SD:
    694 		devtype = "mmcsd";
    695 		break;
    696 	default:
    697 		devtype = "xx";
    698 		break;
    699 	}
    700 
    701 	sprintf(name, "%s%c%d", devtype, 'a' + dev_desc->devnum, part_num);
    702 }
    703