X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=disk%2Fpart.c;h=f0afd89553345b974c828bde34425da61c9ee9ef;hb=99d2c205d4a151faf5f9a406316b9dd960f43475;hp=61e6579d459c21b770ca3ba392588ef406eb65b1;hpb=3e3b956906eba9e4ad7931581ecedaad10eccce8;p=u-boot diff --git a/disk/part.c b/disk/part.c old mode 100755 new mode 100644 index 61e6579d45..f0afd89553 --- a/disk/part.c +++ b/disk/part.c @@ -34,9 +34,10 @@ #define PRINTF(fmt,args...) #endif -#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ - (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ - (CONFIG_COMMANDS & CFG_CMD_USB) || \ +#if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ defined(CONFIG_SYSTEMACE) ) @@ -46,13 +47,16 @@ struct block_drvr { }; static const struct block_drvr block_drvr[] = { -#if (CONFIG_COMMANDS & CFG_CMD_IDE) +#if defined(CONFIG_CMD_IDE) { .name = "ide", .get_dev = ide_get_dev, }, #endif -#if (CONFIG_COMMANDS & CFG_CMD_SCSI) +#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 ((CONFIG_COMMANDS & CFG_CMD_USB) && defined(CONFIG_USB_STORAGE)) +#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) { .name = "usb", .get_dev = usb_stor_get_dev, }, #endif #if defined(CONFIG_MMC) @@ -66,29 +70,43 @@ static const struct block_drvr block_drvr[] = { DECLARE_GLOBAL_DATA_PTR; -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { const struct block_drvr *drvr = block_drvr; block_dev_desc_t* (*reloc_get_dev)(int dev); + char *name; + + if (!ifname) + return NULL; + name = drvr->name; +#ifdef CONFIG_NEEDS_MANUAL_RELOC + name += gd->reloc_off; +#endif while (drvr->name) { - reloc_get_dev = drvr->get_dev + gd->reloc_off; - if (strncmp(ifname, drvr->name, strlen(drvr->name)) == 0) + name = drvr->name; + reloc_get_dev = drvr->get_dev; +#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); drvr++; } return NULL; } #else -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { return NULL; } #endif -#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ - (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ - (CONFIG_COMMANDS & CFG_CMD_USB) || \ +#if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ defined(CONFIG_SYSTEMACE) ) @@ -96,46 +114,89 @@ block_dev_desc_t *get_dev(char* ifname, int dev) /* * 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 - if (dev_desc->type==DEV_TYPE_UNKNOWN) { +/* + * 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 (block_dev_desc_t *dev_desc) +{ + lba512_t lba512; /* number of blocks if 512bytes block size */ + + if (dev_desc->type == DEV_TYPE_UNKNOWN) { puts ("not available\n"); return; } - if (dev_desc->if_type==IF_TYPE_SCSI) { - printf ("(%d:%d) ", dev_desc->target,dev_desc->lun); - } - if (dev_desc->if_type==IF_TYPE_IDE) { + + switch (dev_desc->if_type) { + case IF_TYPE_SCSI: + printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", + dev_desc->target,dev_desc->lun, + dev_desc->vendor, + dev_desc->product, + dev_desc->revision); + break; + case IF_TYPE_ATAPI: + case IF_TYPE_IDE: + case IF_TYPE_SATA: printf ("Model: %s Firm: %s Ser#: %s\n", dev_desc->vendor, dev_desc->revision, dev_desc->product); - } else { - printf ("Vendor: %s Prod.: %s Rev: %s\n", + break; + case IF_TYPE_SD: + case IF_TYPE_MMC: + case IF_TYPE_USB: + printf ("Vendor: %s Rev: %s Prod: %s\n", dev_desc->vendor, - dev_desc->product, - dev_desc->revision); + dev_desc->revision, + dev_desc->product); + break; + case IF_TYPE_DOC: + puts("device type DOC\n"); + return; + case IF_TYPE_UNKNOWN: + puts("device type unknown\n"); + return; + default: + printf("Unhandled device type: %i\n", dev_desc->if_type); + return; } puts (" Type: "); if (dev_desc->removable) puts ("Removable "); switch (dev_desc->type & 0x1F) { - case DEV_TYPE_HARDDISK: puts ("Hard Disk"); - break; - case DEV_TYPE_CDROM: puts ("CD ROM"); - break; - case DEV_TYPE_OPDISK: puts ("Optical Device"); - break; - case DEV_TYPE_TAPE: puts ("Tape"); - break; - default: printf ("# %02X #", dev_desc->type & 0x1F); - break; + case DEV_TYPE_HARDDISK: + puts ("Hard Disk"); + break; + case DEV_TYPE_CDROM: + puts ("CD ROM"); + break; + case DEV_TYPE_OPDISK: + puts ("Optical Device"); + break; + case DEV_TYPE_TAPE: + puts ("Tape"); + break; + default: + printf ("# %02X #", dev_desc->type & 0x1F); + break; } puts ("\n"); if ((dev_desc->lba * dev_desc->blksz)>0L) { @@ -145,8 +206,9 @@ void dev_print (block_dev_desc_t *dev_desc) lba = dev_desc->lba; lba512 = (lba * (dev_desc->blksz/512)); - mb = (10 * lba512) / 2048; /* 2048 = (1024 * 1024) / 512 MB */ /* round to 1 digit */ + mb = lba512_muldiv(lba512, 10, 2048); /* 2048 = (1024 * 1024) / 512 MB */ + mb_quot = mb / 10; mb_rem = mb - (10 * mb_quot); @@ -157,8 +219,8 @@ void dev_print (block_dev_desc_t *dev_desc) if (dev_desc->lba48) printf (" Supports 48-bit addressing\n"); #endif -#if defined(CFG_64BIT_LBA) && defined(CFG_64BIT_VSPRINTF) - printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%qd x %ld)\n", +#if defined(CONFIG_SYS_64BIT_LBA) + printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n", mb_quot, mb_rem, gb_quot, gb_rem, lba, @@ -174,19 +236,20 @@ void dev_print (block_dev_desc_t *dev_desc) puts (" Capacity: not available\n"); } } -#endif /* CFG_CMD_IDE || CFG_CMD_SCSI || CFG_CMD_USB || CONFIG_MMC */ +#endif -#if ((CONFIG_COMMANDS & CFG_CMD_IDE) || \ - (CONFIG_COMMANDS & CFG_CMD_SCSI) || \ - (CONFIG_COMMANDS & CFG_CMD_USB) || \ +#if (defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ - (defined(CONFIG_MMC) && defined(CONFIG_LPC2292)) || \ - defined(CONFIG_SYSTEMACE) ) + defined(CONFIG_SYSTEMACE) ) #if defined(CONFIG_MAC_PARTITION) || \ defined(CONFIG_DOS_PARTITION) || \ defined(CONFIG_ISO_PARTITION) || \ - defined(CONFIG_AMIGA_PARTITION) + defined(CONFIG_AMIGA_PARTITION) || \ + defined(CONFIG_EFI_PARTITION) void init_part (block_dev_desc_t * dev_desc) { @@ -204,6 +267,14 @@ void init_part (block_dev_desc_t * dev_desc) } #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; @@ -217,72 +288,39 @@ void init_part (block_dev_desc_t * dev_desc) return; } #endif + dev_desc->part_type = PART_TYPE_UNKNOWN; } -int get_partition_info (block_dev_desc_t *dev_desc, int part - , disk_partition_t *info) +static void print_part_header (const char *type, block_dev_desc_t * 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); - } + puts ("\nPartition Map for "); + switch (dev_desc->if_type) { + case IF_TYPE_IDE: + puts ("IDE"); 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); - } + case IF_TYPE_SATA: + puts ("SATA"); 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); - } + case IF_TYPE_SCSI: + puts ("SCSI"); + break; + case IF_TYPE_ATAPI: + puts ("ATAPI"); + break; + case IF_TYPE_USB: + puts ("USB"); + break; + case IF_TYPE_DOC: + puts ("DOC"); + break; + case IF_TYPE_MMC: + puts ("MMC"); 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 default: + puts ("UNKNOWN"); break; } - return (-1); -} - -static void print_part_header (const char *type, block_dev_desc_t * dev_desc) -{ - puts ("\nPartition Map for "); - switch (dev_desc->if_type) { - case IF_TYPE_IDE: puts ("IDE"); - break; - case IF_TYPE_SCSI: puts ("SCSI"); - break; - case IF_TYPE_ATAPI: puts ("ATAPI"); - break; - case IF_TYPE_USB: puts ("USB"); - break; - case IF_TYPE_DOC: puts ("DOC"); - break; - default: puts ("UNKNOWN"); - break; - } printf (" device %d -- Partition Type: %s\n\n", dev_desc->dev, type); } @@ -321,14 +359,150 @@ void print_part (block_dev_desc_t * dev_desc) print_part_amiga (dev_desc); return; #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; +#endif } puts ("## Unknown partition table\n"); } -#else /* neither MAC nor DOS nor ISO partition configured */ -# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION -# error nor CONFIG_ISO_PARTITION configured! +#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! +#endif + +#endif + +int get_partition_info(block_dev_desc_t *dev_desc, int part + , disk_partition_t *info) +{ +#if defined(CONFIG_CMD_IDE) || \ + defined(CONFIG_CMD_SATA) || \ + defined(CONFIG_CMD_SCSI) || \ + defined(CONFIG_CMD_USB) || \ + defined(CONFIG_MMC) || \ + defined(CONFIG_SYSTEMACE) + + 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; + } + 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; + } #endif -#endif /* (CONFIG_COMMANDS & CFG_CMD_IDE) || CONFIG_COMMANDS & CFG_CMD_SCSI) */ + return -1; +} + +int get_device_and_partition(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info) +{ + int ret; + char *ep; + int dev; + block_dev_desc_t *desc; + int part = 0; + char *part_str; + + if (dev_str) + dev = simple_strtoul(dev_str, &ep, 16); + + if (!dev_str || (dev_str == ep)) { + dev_str = getenv("bootdevice"); + if (dev_str) + dev = simple_strtoul(dev_str, &ep, 16); + if (!dev_str || (dev_str == ep)) + goto err; + } + + desc = get_dev(ifname, dev); + if (!desc || (desc->type == DEV_TYPE_UNKNOWN)) + goto err; + + if (desc->part_type == PART_TYPE_UNKNOWN) { + /* disk doesn't use partition table */ + if (!desc->lba) { + printf("**Bad disk size - %s %d:0 **\n", ifname, dev); + return -1; + } + info->start = 0; + info->size = desc->lba; + info->blksz = desc->blksz; + + *dev_desc = desc; + return 0; + } + + part_str = strchr(dev_str, ':'); + if (part_str) + part = (int)simple_strtoul(++part_str, NULL, 16); + + ret = get_partition_info(desc, part, info); + if (ret) { + printf("** Invalid partition %d, use `dev[:part]' **\n", part); + return -1; + } + if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { + printf("** Invalid partition type \"%.32s\"" + " (expect \"" BOOT_PART_TYPE "\")\n", + info->type); + return -1; + } + + *dev_desc = desc; + return part; + +err: + puts("** Invalid boot device, use `dev[:part]' **\n"); + return -1; +}