1 /* 2 * (C) Copyright 2001 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 24 #include <common.h> 25 #include <command.h> 26 #include <ide.h> 27 #include <malloc.h> 28 #include <part.h> 29 30 #undef PART_DEBUG 31 32 #ifdef PART_DEBUG 33 #define PRINTF(fmt,args...) printf (fmt ,##args) 34 #else 35 #define PRINTF(fmt,args...) 36 #endif 37 38 /* Rather than repeat this expression each time, add a define for it */ 39 #if (defined(CONFIG_CMD_IDE) || \ 40 defined(CONFIG_CMD_SATA) || \ 41 defined(CONFIG_CMD_SCSI) || \ 42 defined(CONFIG_CMD_USB) || \ 43 defined(CONFIG_MMC) || \ 44 defined(CONFIG_SYSTEMACE) ) 45 #define HAVE_BLOCK_DEVICE 46 #endif 47 48 struct block_drvr { 49 char *name; 50 block_dev_desc_t* (*get_dev)(int dev); 51 }; 52 53 static const struct block_drvr block_drvr[] = { 54 #if defined(CONFIG_CMD_IDE) 55 { .name = "ide", .get_dev = ide_get_dev, }, 56 #endif 57 #if defined(CONFIG_CMD_SATA) 58 {.name = "sata", .get_dev = sata_get_dev, }, 59 #endif 60 #if defined(CONFIG_CMD_SCSI) 61 { .name = "scsi", .get_dev = scsi_get_dev, }, 62 #endif 63 #if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) 64 { .name = "usb", .get_dev = usb_stor_get_dev, }, 65 #endif 66 #if defined(CONFIG_MMC) 67 { .name = "mmc", .get_dev = mmc_get_dev, }, 68 #endif 69 #if defined(CONFIG_SYSTEMACE) 70 { .name = "ace", .get_dev = systemace_get_dev, }, 71 #endif 72 { }, 73 }; 74 75 DECLARE_GLOBAL_DATA_PTR; 76 77 #ifdef HAVE_BLOCK_DEVICE 78 block_dev_desc_t *get_dev(const char *ifname, int dev) 79 { 80 const struct block_drvr *drvr = block_drvr; 81 block_dev_desc_t* (*reloc_get_dev)(int dev); 82 char *name; 83 84 if (!ifname) 85 return NULL; 86 87 name = drvr->name; 88 #ifdef CONFIG_NEEDS_MANUAL_RELOC 89 name += gd->reloc_off; 90 #endif 91 while (drvr->name) { 92 name = drvr->name; 93 reloc_get_dev = drvr->get_dev; 94 #ifdef CONFIG_NEEDS_MANUAL_RELOC 95 name += gd->reloc_off; 96 reloc_get_dev += gd->reloc_off; 97 #endif 98 if (strncmp(ifname, name, strlen(name)) == 0) 99 return reloc_get_dev(dev); 100 drvr++; 101 } 102 return NULL; 103 } 104 #else 105 block_dev_desc_t *get_dev(const char *ifname, int dev) 106 { 107 return NULL; 108 } 109 #endif 110 111 #ifdef HAVE_BLOCK_DEVICE 112 113 /* ------------------------------------------------------------------------- */ 114 /* 115 * reports device info to the user 116 */ 117 118 #ifdef CONFIG_LBA48 119 typedef uint64_t lba512_t; 120 #else 121 typedef lbaint_t lba512_t; 122 #endif 123 124 /* 125 * Overflowless variant of (block_count * mul_by / div_by) 126 * when div_by > mul_by 127 */ 128 static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by) 129 { 130 lba512_t bc_quot, bc_rem; 131 132 /* x * m / d == x / d * m + (x % d) * m / d */ 133 bc_quot = block_count / div_by; 134 bc_rem = block_count - div_by * bc_quot; 135 return bc_quot * mul_by + (bc_rem * mul_by) / div_by; 136 } 137 138 void dev_print (block_dev_desc_t *dev_desc) 139 { 140 lba512_t lba512; /* number of blocks if 512bytes block size */ 141 142 if (dev_desc->type == DEV_TYPE_UNKNOWN) { 143 puts ("not available\n"); 144 return; 145 } 146 147 switch (dev_desc->if_type) { 148 case IF_TYPE_SCSI: 149 printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", 150 dev_desc->target,dev_desc->lun, 151 dev_desc->vendor, 152 dev_desc->product, 153 dev_desc->revision); 154 break; 155 case IF_TYPE_ATAPI: 156 case IF_TYPE_IDE: 157 case IF_TYPE_SATA: 158 printf ("Model: %s Firm: %s Ser#: %s\n", 159 dev_desc->vendor, 160 dev_desc->revision, 161 dev_desc->product); 162 break; 163 case IF_TYPE_SD: 164 case IF_TYPE_MMC: 165 case IF_TYPE_USB: 166 printf ("Vendor: %s Rev: %s Prod: %s\n", 167 dev_desc->vendor, 168 dev_desc->revision, 169 dev_desc->product); 170 break; 171 case IF_TYPE_DOC: 172 puts("device type DOC\n"); 173 return; 174 case IF_TYPE_UNKNOWN: 175 puts("device type unknown\n"); 176 return; 177 default: 178 printf("Unhandled device type: %i\n", dev_desc->if_type); 179 return; 180 } 181 puts (" Type: "); 182 if (dev_desc->removable) 183 puts ("Removable "); 184 switch (dev_desc->type & 0x1F) { 185 case DEV_TYPE_HARDDISK: 186 puts ("Hard Disk"); 187 break; 188 case DEV_TYPE_CDROM: 189 puts ("CD ROM"); 190 break; 191 case DEV_TYPE_OPDISK: 192 puts ("Optical Device"); 193 break; 194 case DEV_TYPE_TAPE: 195 puts ("Tape"); 196 break; 197 default: 198 printf ("# %02X #", dev_desc->type & 0x1F); 199 break; 200 } 201 puts ("\n"); 202 if (dev_desc->lba > 0L && dev_desc->blksz > 0L) { 203 ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem; 204 lbaint_t lba; 205 206 lba = dev_desc->lba; 207 208 lba512 = (lba * (dev_desc->blksz/512)); 209 /* round to 1 digit */ 210 mb = lba512_muldiv(lba512, 10, 2048); /* 2048 = (1024 * 1024) / 512 MB */ 211 212 mb_quot = mb / 10; 213 mb_rem = mb - (10 * mb_quot); 214 215 gb = mb / 1024; 216 gb_quot = gb / 10; 217 gb_rem = gb - (10 * gb_quot); 218 #ifdef CONFIG_LBA48 219 if (dev_desc->lba48) 220 printf (" Supports 48-bit addressing\n"); 221 #endif 222 #if defined(CONFIG_SYS_64BIT_LBA) 223 printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n", 224 mb_quot, mb_rem, 225 gb_quot, gb_rem, 226 lba, 227 dev_desc->blksz); 228 #else 229 printf (" Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n", 230 mb_quot, mb_rem, 231 gb_quot, gb_rem, 232 (ulong)lba, 233 dev_desc->blksz); 234 #endif 235 } else { 236 puts (" Capacity: not available\n"); 237 } 238 } 239 #endif 240 241 #ifdef HAVE_BLOCK_DEVICE 242 243 void init_part (block_dev_desc_t * dev_desc) 244 { 245 #ifdef CONFIG_ISO_PARTITION 246 if (test_part_iso(dev_desc) == 0) { 247 dev_desc->part_type = PART_TYPE_ISO; 248 return; 249 } 250 #endif 251 252 #ifdef CONFIG_MAC_PARTITION 253 if (test_part_mac(dev_desc) == 0) { 254 dev_desc->part_type = PART_TYPE_MAC; 255 return; 256 } 257 #endif 258 259 /* must be placed before DOS partition detection */ 260 #ifdef CONFIG_EFI_PARTITION 261 if (test_part_efi(dev_desc) == 0) { 262 dev_desc->part_type = PART_TYPE_EFI; 263 return; 264 } 265 #endif 266 267 #ifdef CONFIG_DOS_PARTITION 268 if (test_part_dos(dev_desc) == 0) { 269 dev_desc->part_type = PART_TYPE_DOS; 270 return; 271 } 272 #endif 273 274 #ifdef CONFIG_AMIGA_PARTITION 275 if (test_part_amiga(dev_desc) == 0) { 276 dev_desc->part_type = PART_TYPE_AMIGA; 277 return; 278 } 279 #endif 280 dev_desc->part_type = PART_TYPE_UNKNOWN; 281 } 282 283 284 #if defined(CONFIG_MAC_PARTITION) || \ 285 defined(CONFIG_DOS_PARTITION) || \ 286 defined(CONFIG_ISO_PARTITION) || \ 287 defined(CONFIG_AMIGA_PARTITION) || \ 288 defined(CONFIG_EFI_PARTITION) 289 290 static void print_part_header (const char *type, block_dev_desc_t * dev_desc) 291 { 292 puts ("\nPartition Map for "); 293 switch (dev_desc->if_type) { 294 case IF_TYPE_IDE: 295 puts ("IDE"); 296 break; 297 case IF_TYPE_SATA: 298 puts ("SATA"); 299 break; 300 case IF_TYPE_SCSI: 301 puts ("SCSI"); 302 break; 303 case IF_TYPE_ATAPI: 304 puts ("ATAPI"); 305 break; 306 case IF_TYPE_USB: 307 puts ("USB"); 308 break; 309 case IF_TYPE_DOC: 310 puts ("DOC"); 311 break; 312 case IF_TYPE_MMC: 313 puts ("MMC"); 314 break; 315 default: 316 puts ("UNKNOWN"); 317 break; 318 } 319 printf (" device %d -- Partition Type: %s\n\n", 320 dev_desc->dev, type); 321 } 322 323 #endif /* any CONFIG_..._PARTITION */ 324 325 void print_part (block_dev_desc_t * dev_desc) 326 { 327 328 switch (dev_desc->part_type) { 329 #ifdef CONFIG_MAC_PARTITION 330 case PART_TYPE_MAC: 331 PRINTF ("## Testing for valid MAC partition ##\n"); 332 print_part_header ("MAC", dev_desc); 333 print_part_mac (dev_desc); 334 return; 335 #endif 336 #ifdef CONFIG_DOS_PARTITION 337 case PART_TYPE_DOS: 338 PRINTF ("## Testing for valid DOS partition ##\n"); 339 print_part_header ("DOS", dev_desc); 340 print_part_dos (dev_desc); 341 return; 342 #endif 343 344 #ifdef CONFIG_ISO_PARTITION 345 case PART_TYPE_ISO: 346 PRINTF ("## Testing for valid ISO Boot partition ##\n"); 347 print_part_header ("ISO", dev_desc); 348 print_part_iso (dev_desc); 349 return; 350 #endif 351 352 #ifdef CONFIG_AMIGA_PARTITION 353 case PART_TYPE_AMIGA: 354 PRINTF ("## Testing for a valid Amiga partition ##\n"); 355 print_part_header ("AMIGA", dev_desc); 356 print_part_amiga (dev_desc); 357 return; 358 #endif 359 360 #ifdef CONFIG_EFI_PARTITION 361 case PART_TYPE_EFI: 362 PRINTF ("## Testing for valid EFI partition ##\n"); 363 print_part_header ("EFI", dev_desc); 364 print_part_efi (dev_desc); 365 return; 366 #endif 367 } 368 puts ("## Unknown partition table\n"); 369 } 370 371 #endif /* HAVE_BLOCK_DEVICE */ 372 373 int get_partition_info(block_dev_desc_t *dev_desc, int part 374 , disk_partition_t *info) 375 { 376 #ifdef HAVE_BLOCK_DEVICE 377 378 #ifdef CONFIG_PARTITION_UUIDS 379 /* The common case is no UUID support */ 380 info->uuid[0] = 0; 381 #endif 382 383 switch (dev_desc->part_type) { 384 #ifdef CONFIG_MAC_PARTITION 385 case PART_TYPE_MAC: 386 if (get_partition_info_mac(dev_desc, part, info) == 0) { 387 PRINTF("## Valid MAC partition found ##\n"); 388 return 0; 389 } 390 break; 391 #endif 392 393 #ifdef CONFIG_DOS_PARTITION 394 case PART_TYPE_DOS: 395 if (get_partition_info_dos(dev_desc, part, info) == 0) { 396 PRINTF("## Valid DOS partition found ##\n"); 397 return 0; 398 } 399 break; 400 #endif 401 402 #ifdef CONFIG_ISO_PARTITION 403 case PART_TYPE_ISO: 404 if (get_partition_info_iso(dev_desc, part, info) == 0) { 405 PRINTF("## Valid ISO boot partition found ##\n"); 406 return 0; 407 } 408 break; 409 #endif 410 411 #ifdef CONFIG_AMIGA_PARTITION 412 case PART_TYPE_AMIGA: 413 if (get_partition_info_amiga(dev_desc, part, info) == 0) { 414 PRINTF("## Valid Amiga partition found ##\n"); 415 return 0; 416 } 417 break; 418 #endif 419 420 #ifdef CONFIG_EFI_PARTITION 421 case PART_TYPE_EFI: 422 if (get_partition_info_efi(dev_desc, part, info) == 0) { 423 PRINTF("## Valid EFI partition found ##\n"); 424 return 0; 425 } 426 break; 427 #endif 428 default: 429 break; 430 } 431 #endif /* HAVE_BLOCK_DEVICE */ 432 433 return -1; 434 } 435 436 int get_device(const char *ifname, const char *dev_str, 437 block_dev_desc_t **dev_desc) 438 { 439 char *ep; 440 int dev; 441 442 dev = simple_strtoul(dev_str, &ep, 16); 443 if (*ep) { 444 printf("** Bad device specification %s %s **\n", 445 ifname, dev_str); 446 return -1; 447 } 448 449 *dev_desc = get_dev(ifname, dev); 450 if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { 451 printf("** Bad device %s %s **\n", ifname, dev_str); 452 return -1; 453 } 454 455 return dev; 456 } 457 458 #define PART_UNSPECIFIED -2 459 #define PART_AUTO -1 460 #define MAX_SEARCH_PARTITIONS 16 461 int get_device_and_partition(const char *ifname, const char *dev_part_str, 462 block_dev_desc_t **dev_desc, 463 disk_partition_t *info, int allow_whole_dev) 464 { 465 int ret = -1; 466 const char *part_str; 467 char *dup_str = NULL; 468 const char *dev_str; 469 int dev; 470 char *ep; 471 int p; 472 int part; 473 disk_partition_t tmpinfo; 474 475 /* If no dev_part_str, use bootdevice environment variable */ 476 if (!dev_part_str || !strlen(dev_part_str) || 477 !strcmp(dev_part_str, "-")) 478 dev_part_str = getenv("bootdevice"); 479 480 /* If still no dev_part_str, it's an error */ 481 if (!dev_part_str) { 482 printf("** No device specified **\n"); 483 goto cleanup; 484 } 485 486 /* Separate device and partition ID specification */ 487 part_str = strchr(dev_part_str, ':'); 488 if (part_str) { 489 dup_str = strdup(dev_part_str); 490 dup_str[part_str - dev_part_str] = 0; 491 dev_str = dup_str; 492 part_str++; 493 } else { 494 dev_str = dev_part_str; 495 } 496 497 /* Look up the device */ 498 dev = get_device(ifname, dev_str, dev_desc); 499 if (dev < 0) 500 goto cleanup; 501 502 /* Convert partition ID string to number */ 503 if (!part_str || !*part_str) { 504 part = PART_UNSPECIFIED; 505 } else if (!strcmp(part_str, "auto")) { 506 part = PART_AUTO; 507 } else { 508 /* Something specified -> use exactly that */ 509 part = (int)simple_strtoul(part_str, &ep, 16); 510 /* 511 * Less than whole string converted, 512 * or request for whole device, but caller requires partition. 513 */ 514 if (*ep || (part == 0 && !allow_whole_dev)) { 515 printf("** Bad partition specification %s %s **\n", 516 ifname, dev_part_str); 517 goto cleanup; 518 } 519 } 520 521 /* 522 * No partition table on device, 523 * or user requested partition 0 (entire device). 524 */ 525 if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || 526 (part == 0)) { 527 if (!(*dev_desc)->lba) { 528 printf("** Bad device size - %s %s **\n", ifname, 529 dev_str); 530 goto cleanup; 531 } 532 533 /* 534 * If user specified a partition ID other than 0, 535 * or the calling command only accepts partitions, 536 * it's an error. 537 */ 538 if ((part > 0) || (!allow_whole_dev)) { 539 printf("** No partition table - %s %s **\n", ifname, 540 dev_str); 541 goto cleanup; 542 } 543 544 info->start = 0; 545 info->size = (*dev_desc)->lba; 546 info->blksz = (*dev_desc)->blksz; 547 info->bootable = 0; 548 strcpy((char *)info->type, BOOT_PART_TYPE); 549 strcpy((char *)info->name, "Whole Disk"); 550 #ifdef CONFIG_PARTITION_UUIDS 551 info->uuid[0] = 0; 552 #endif 553 554 ret = 0; 555 goto cleanup; 556 } 557 558 /* 559 * Now there's known to be a partition table, 560 * not specifying a partition means to pick partition 1. 561 */ 562 if (part == PART_UNSPECIFIED) 563 part = 1; 564 565 /* 566 * If user didn't specify a partition number, or did specify something 567 * other than "auto", use that partition number directly. 568 */ 569 if (part != PART_AUTO) { 570 ret = get_partition_info(*dev_desc, part, info); 571 if (ret) { 572 printf("** Invalid partition %d **\n", part); 573 goto cleanup; 574 } 575 } else { 576 /* 577 * Find the first bootable partition. 578 * If none are bootable, fall back to the first valid partition. 579 */ 580 part = 0; 581 for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { 582 ret = get_partition_info(*dev_desc, p, info); 583 if (ret) 584 continue; 585 586 /* 587 * First valid partition, or new better partition? 588 * If so, save partition ID. 589 */ 590 if (!part || info->bootable) 591 part = p; 592 593 /* Best possible partition? Stop searching. */ 594 if (info->bootable) 595 break; 596 597 /* 598 * We now need to search further for best possible. 599 * If we what we just queried was the best so far, 600 * save the info since we over-write it next loop. 601 */ 602 if (part == p) 603 tmpinfo = *info; 604 } 605 /* If we found any acceptable partition */ 606 if (part) { 607 /* 608 * If we searched all possible partition IDs, 609 * return the first valid partition we found. 610 */ 611 if (p == MAX_SEARCH_PARTITIONS + 1) 612 *info = tmpinfo; 613 } else { 614 printf("** No valid partitions found **\n"); 615 ret = -1; 616 goto cleanup; 617 } 618 } 619 if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { 620 printf("** Invalid partition type \"%.32s\"" 621 " (expect \"" BOOT_PART_TYPE "\")\n", 622 info->type); 623 ret = -1; 624 goto cleanup; 625 } 626 627 ret = part; 628 goto cleanup; 629 630 cleanup: 631 free(dup_str); 632 return ret; 633 } 634