uboot/disk/part.c
<<
>>
Prefs
   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 <part.h>
  28
  29#undef  PART_DEBUG
  30
  31#ifdef  PART_DEBUG
  32#define PRINTF(fmt,args...)     printf (fmt ,##args)
  33#else
  34#define PRINTF(fmt,args...)
  35#endif
  36
  37#if (defined(CONFIG_CMD_IDE) || \
  38     defined(CONFIG_CMD_MG_DISK) || \
  39     defined(CONFIG_CMD_SATA) || \
  40     defined(CONFIG_CMD_SCSI) || \
  41     defined(CONFIG_CMD_USB) || \
  42     defined(CONFIG_MMC) || \
  43     defined(CONFIG_SYSTEMACE) )
  44
  45struct block_drvr {
  46        char *name;
  47        block_dev_desc_t* (*get_dev)(int dev);
  48};
  49
  50static const struct block_drvr block_drvr[] = {
  51#if defined(CONFIG_CMD_IDE)
  52        { .name = "ide", .get_dev = ide_get_dev, },
  53#endif
  54#if defined(CONFIG_CMD_SATA)
  55        {.name = "sata", .get_dev = sata_get_dev, },
  56#endif
  57#if defined(CONFIG_CMD_SCSI)
  58        { .name = "scsi", .get_dev = scsi_get_dev, },
  59#endif
  60#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE)
  61        { .name = "usb", .get_dev = usb_stor_get_dev, },
  62#endif
  63#if defined(CONFIG_MMC)
  64        { .name = "mmc", .get_dev = mmc_get_dev, },
  65#endif
  66#if defined(CONFIG_SYSTEMACE)
  67        { .name = "ace", .get_dev = systemace_get_dev, },
  68#endif
  69#if defined(CONFIG_CMD_MG_DISK)
  70        { .name = "mgd", .get_dev = mg_disk_get_dev, },
  71#endif
  72        { },
  73};
  74
  75DECLARE_GLOBAL_DATA_PTR;
  76
  77block_dev_desc_t *get_dev(char* ifname, int dev)
  78{
  79        const struct block_drvr *drvr = block_drvr;
  80        block_dev_desc_t* (*reloc_get_dev)(int dev);
  81        char *name;
  82
  83        name = drvr->name;
  84#ifdef CONFIG_NEEDS_MANUAL_RELOC
  85        name += gd->reloc_off;
  86#endif
  87        while (name) {
  88                name = drvr->name;
  89                reloc_get_dev = drvr->get_dev;
  90#ifdef CONFIG_NEEDS_MANUAL_RELOC
  91                name += gd->reloc_off;
  92                reloc_get_dev += gd->reloc_off;
  93#endif
  94                if (strncmp(ifname, name, strlen(name)) == 0)
  95                        return reloc_get_dev(dev);
  96                drvr++;
  97        }
  98        return NULL;
  99}
 100#else
 101block_dev_desc_t *get_dev(char* ifname, int dev)
 102{
 103        return NULL;
 104}
 105#endif
 106
 107#if (defined(CONFIG_CMD_IDE) || \
 108     defined(CONFIG_CMD_MG_DISK) || \
 109     defined(CONFIG_CMD_SATA) || \
 110     defined(CONFIG_CMD_SCSI) || \
 111     defined(CONFIG_CMD_USB) || \
 112     defined(CONFIG_MMC) || \
 113     defined(CONFIG_SYSTEMACE) )
 114
 115/* ------------------------------------------------------------------------- */
 116/*
 117 * reports device info to the user
 118 */
 119
 120#ifdef CONFIG_LBA48
 121typedef uint64_t lba512_t;
 122#else
 123typedef lbaint_t lba512_t;
 124#endif
 125
 126/*
 127 * Overflowless variant of (block_count * mul_by / div_by)
 128 * when div_by > mul_by
 129 */
 130static lba512_t lba512_muldiv (lba512_t block_count, lba512_t mul_by, lba512_t div_by)
 131{
 132        lba512_t bc_quot, bc_rem;
 133
 134        /* x * m / d == x / d * m + (x % d) * m / d */
 135        bc_quot = block_count / div_by;
 136        bc_rem  = block_count - div_by * bc_quot;
 137        return bc_quot * mul_by + (bc_rem * mul_by) / div_by;
 138}
 139
 140void dev_print (block_dev_desc_t *dev_desc)
 141{
 142        lba512_t lba512; /* number of blocks if 512bytes block size */
 143
 144        if (dev_desc->type == DEV_TYPE_UNKNOWN) {
 145                puts ("not available\n");
 146                return;
 147        }
 148
 149        switch (dev_desc->if_type) {
 150        case IF_TYPE_SCSI:
 151                printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n",
 152                        dev_desc->target,dev_desc->lun,
 153                        dev_desc->vendor,
 154                        dev_desc->product,
 155                        dev_desc->revision);
 156                break;
 157        case IF_TYPE_ATAPI:
 158        case IF_TYPE_IDE:
 159        case IF_TYPE_SATA:
 160                printf ("Model: %s Firm: %s Ser#: %s\n",
 161                        dev_desc->vendor,
 162                        dev_desc->revision,
 163                        dev_desc->product);
 164                break;
 165        case IF_TYPE_SD:
 166        case IF_TYPE_MMC:
 167        case IF_TYPE_USB:
 168                printf ("Vendor: %s Rev: %s Prod: %s\n",
 169                        dev_desc->vendor,
 170                        dev_desc->revision,
 171                        dev_desc->product);
 172                break;
 173        case IF_TYPE_DOC:
 174                puts("device type DOC\n");
 175                return;
 176        case IF_TYPE_UNKNOWN:
 177                puts("device type unknown\n");
 178                return;
 179        default:
 180                printf("Unhandled device type: %i\n", dev_desc->if_type);
 181                return;
 182        }
 183        puts ("            Type: ");
 184        if (dev_desc->removable)
 185                puts ("Removable ");
 186        switch (dev_desc->type & 0x1F) {
 187        case DEV_TYPE_HARDDISK:
 188                puts ("Hard Disk");
 189                break;
 190        case DEV_TYPE_CDROM:
 191                puts ("CD ROM");
 192                break;
 193        case DEV_TYPE_OPDISK:
 194                puts ("Optical Device");
 195                break;
 196        case DEV_TYPE_TAPE:
 197                puts ("Tape");
 198                break;
 199        default:
 200                printf ("# %02X #", dev_desc->type & 0x1F);
 201                break;
 202        }
 203        puts ("\n");
 204        if ((dev_desc->lba * dev_desc->blksz)>0L) {
 205                ulong mb, mb_quot, mb_rem, gb, gb_quot, gb_rem;
 206                lbaint_t lba;
 207
 208                lba = dev_desc->lba;
 209
 210                lba512 = (lba * (dev_desc->blksz/512));
 211                /* round to 1 digit */
 212                mb = lba512_muldiv(lba512, 10, 2048);   /* 2048 = (1024 * 1024) / 512 MB */
 213
 214                mb_quot = mb / 10;
 215                mb_rem  = mb - (10 * mb_quot);
 216
 217                gb = mb / 1024;
 218                gb_quot = gb / 10;
 219                gb_rem  = gb - (10 * gb_quot);
 220#ifdef CONFIG_LBA48
 221                if (dev_desc->lba48)
 222                        printf ("            Supports 48-bit addressing\n");
 223#endif
 224#if defined(CONFIG_SYS_64BIT_LBA)
 225                printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%Ld x %ld)\n",
 226                        mb_quot, mb_rem,
 227                        gb_quot, gb_rem,
 228                        lba,
 229                        dev_desc->blksz);
 230#else
 231                printf ("            Capacity: %ld.%ld MB = %ld.%ld GB (%ld x %ld)\n",
 232                        mb_quot, mb_rem,
 233                        gb_quot, gb_rem,
 234                        (ulong)lba,
 235                        dev_desc->blksz);
 236#endif
 237        } else {
 238                puts ("            Capacity: not available\n");
 239        }
 240}
 241#endif
 242
 243#if (defined(CONFIG_CMD_IDE) || \
 244     defined(CONFIG_CMD_MG_DISK) || \
 245     defined(CONFIG_CMD_SATA) || \
 246     defined(CONFIG_CMD_SCSI) || \
 247     defined(CONFIG_CMD_USB) || \
 248     defined(CONFIG_MMC)                || \
 249     defined(CONFIG_SYSTEMACE) )
 250
 251#if defined(CONFIG_MAC_PARTITION) || \
 252    defined(CONFIG_DOS_PARTITION) || \
 253    defined(CONFIG_ISO_PARTITION) || \
 254    defined(CONFIG_AMIGA_PARTITION) || \
 255    defined(CONFIG_EFI_PARTITION)
 256
 257void init_part (block_dev_desc_t * dev_desc)
 258{
 259#ifdef CONFIG_ISO_PARTITION
 260        if (test_part_iso(dev_desc) == 0) {
 261                dev_desc->part_type = PART_TYPE_ISO;
 262                return;
 263        }
 264#endif
 265
 266#ifdef CONFIG_MAC_PARTITION
 267        if (test_part_mac(dev_desc) == 0) {
 268                dev_desc->part_type = PART_TYPE_MAC;
 269                return;
 270        }
 271#endif
 272
 273/* must be placed before DOS partition detection */
 274#ifdef CONFIG_EFI_PARTITION
 275        if (test_part_efi(dev_desc) == 0) {
 276                dev_desc->part_type = PART_TYPE_EFI;
 277                return;
 278        }
 279#endif
 280
 281#ifdef CONFIG_DOS_PARTITION
 282        if (test_part_dos(dev_desc) == 0) {
 283                dev_desc->part_type = PART_TYPE_DOS;
 284                return;
 285        }
 286#endif
 287
 288#ifdef CONFIG_AMIGA_PARTITION
 289        if (test_part_amiga(dev_desc) == 0) {
 290            dev_desc->part_type = PART_TYPE_AMIGA;
 291            return;
 292        }
 293#endif
 294}
 295
 296
 297int get_partition_info (block_dev_desc_t *dev_desc, int part
 298                                        , disk_partition_t *info)
 299{
 300        switch (dev_desc->part_type) {
 301#ifdef CONFIG_MAC_PARTITION
 302        case PART_TYPE_MAC:
 303                if (get_partition_info_mac(dev_desc,part,info) == 0) {
 304                        PRINTF ("## Valid MAC partition found ##\n");
 305                        return (0);
 306                }
 307                break;
 308#endif
 309
 310#ifdef CONFIG_DOS_PARTITION
 311        case PART_TYPE_DOS:
 312                if (get_partition_info_dos(dev_desc,part,info) == 0) {
 313                        PRINTF ("## Valid DOS partition found ##\n");
 314                        return (0);
 315                }
 316                break;
 317#endif
 318
 319#ifdef CONFIG_ISO_PARTITION
 320        case PART_TYPE_ISO:
 321                if (get_partition_info_iso(dev_desc,part,info) == 0) {
 322                        PRINTF ("## Valid ISO boot partition found ##\n");
 323                        return (0);
 324                }
 325                break;
 326#endif
 327
 328#ifdef CONFIG_AMIGA_PARTITION
 329        case PART_TYPE_AMIGA:
 330            if (get_partition_info_amiga(dev_desc, part, info) == 0)
 331            {
 332                PRINTF ("## Valid Amiga partition found ##\n");
 333                return (0);
 334            }
 335            break;
 336#endif
 337
 338#ifdef CONFIG_EFI_PARTITION
 339        case PART_TYPE_EFI:
 340                if (get_partition_info_efi(dev_desc,part,info) == 0) {
 341                        PRINTF ("## Valid EFI partition found ##\n");
 342                        return (0);
 343                }
 344                break;
 345#endif
 346        default:
 347                break;
 348        }
 349        return (-1);
 350}
 351
 352static void print_part_header (const char *type, block_dev_desc_t * dev_desc)
 353{
 354        puts ("\nPartition Map for ");
 355        switch (dev_desc->if_type) {
 356        case IF_TYPE_IDE:
 357                puts ("IDE");
 358                break;
 359        case IF_TYPE_SATA:
 360                puts ("SATA");
 361                break;
 362        case IF_TYPE_SCSI:
 363                puts ("SCSI");
 364                break;
 365        case IF_TYPE_ATAPI:
 366                puts ("ATAPI");
 367                break;
 368        case IF_TYPE_USB:
 369                puts ("USB");
 370                break;
 371        case IF_TYPE_DOC:
 372                puts ("DOC");
 373                break;
 374        case IF_TYPE_MMC:
 375                puts ("MMC");
 376                break;
 377        default:
 378                puts ("UNKNOWN");
 379                break;
 380        }
 381        printf (" device %d  --   Partition Type: %s\n\n",
 382                        dev_desc->dev, type);
 383}
 384
 385void print_part (block_dev_desc_t * dev_desc)
 386{
 387
 388                switch (dev_desc->part_type) {
 389#ifdef CONFIG_MAC_PARTITION
 390        case PART_TYPE_MAC:
 391                PRINTF ("## Testing for valid MAC partition ##\n");
 392                print_part_header ("MAC", dev_desc);
 393                print_part_mac (dev_desc);
 394                return;
 395#endif
 396#ifdef CONFIG_DOS_PARTITION
 397        case PART_TYPE_DOS:
 398                PRINTF ("## Testing for valid DOS partition ##\n");
 399                print_part_header ("DOS", dev_desc);
 400                print_part_dos (dev_desc);
 401                return;
 402#endif
 403
 404#ifdef CONFIG_ISO_PARTITION
 405        case PART_TYPE_ISO:
 406                PRINTF ("## Testing for valid ISO Boot partition ##\n");
 407                print_part_header ("ISO", dev_desc);
 408                print_part_iso (dev_desc);
 409                return;
 410#endif
 411
 412#ifdef CONFIG_AMIGA_PARTITION
 413        case PART_TYPE_AMIGA:
 414            PRINTF ("## Testing for a valid Amiga partition ##\n");
 415            print_part_header ("AMIGA", dev_desc);
 416            print_part_amiga (dev_desc);
 417            return;
 418#endif
 419
 420#ifdef CONFIG_EFI_PARTITION
 421        case PART_TYPE_EFI:
 422                PRINTF ("## Testing for valid EFI partition ##\n");
 423                print_part_header ("EFI", dev_desc);
 424                print_part_efi (dev_desc);
 425                return;
 426#endif
 427        }
 428        puts ("## Unknown partition table\n");
 429}
 430
 431
 432#else   /* neither MAC nor DOS nor ISO nor AMIGA nor EFI partition configured */
 433# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION
 434# error nor CONFIG_ISO_PARTITION nor CONFIG_AMIGA_PARTITION
 435# error nor CONFIG_EFI_PARTITION configured!
 436#endif
 437
 438#endif
 439