uboot/include/blk.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * (C) Copyright 2000-2004
   4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   5 */
   6
   7#ifndef BLK_H
   8#define BLK_H
   9
  10#include <efi.h>
  11
  12#ifdef CONFIG_SYS_64BIT_LBA
  13typedef uint64_t lbaint_t;
  14#define LBAFlength "ll"
  15#else
  16typedef ulong lbaint_t;
  17#define LBAFlength "l"
  18#endif
  19#define LBAF "%" LBAFlength "x"
  20#define LBAFU "%" LBAFlength "u"
  21
  22struct udevice;
  23
  24/* Interface types: */
  25enum if_type {
  26        IF_TYPE_UNKNOWN = 0,
  27        IF_TYPE_IDE,
  28        IF_TYPE_SCSI,
  29        IF_TYPE_ATAPI,
  30        IF_TYPE_USB,
  31        IF_TYPE_DOC,
  32        IF_TYPE_MMC,
  33        IF_TYPE_SD,
  34        IF_TYPE_SATA,
  35        IF_TYPE_HOST,
  36        IF_TYPE_NVME,
  37        IF_TYPE_EFI,
  38        IF_TYPE_PVBLOCK,
  39        IF_TYPE_VIRTIO,
  40
  41        IF_TYPE_COUNT,                  /* Number of interface types */
  42};
  43
  44#define BLK_VEN_SIZE            40
  45#define BLK_PRD_SIZE            20
  46#define BLK_REV_SIZE            8
  47
  48/*
  49 * Identifies the partition table type (ie. MBR vs GPT GUID) signature
  50 */
  51enum sig_type {
  52        SIG_TYPE_NONE,
  53        SIG_TYPE_MBR,
  54        SIG_TYPE_GUID,
  55
  56        SIG_TYPE_COUNT                  /* Number of signature types */
  57};
  58
  59/*
  60 * With driver model (CONFIG_BLK) this is uclass platform data, accessible
  61 * with dev_get_uclass_plat(dev)
  62 */
  63struct blk_desc {
  64        /*
  65         * TODO: With driver model we should be able to use the parent
  66         * device's uclass instead.
  67         */
  68        enum if_type    if_type;        /* type of the interface */
  69        int             devnum;         /* device number */
  70        unsigned char   part_type;      /* partition type */
  71        unsigned char   target;         /* target SCSI ID */
  72        unsigned char   lun;            /* target LUN */
  73        unsigned char   hwpart;         /* HW partition, e.g. for eMMC */
  74        unsigned char   type;           /* device type */
  75        unsigned char   removable;      /* removable device */
  76#ifdef CONFIG_LBA48
  77        /* device can use 48bit addr (ATA/ATAPI v7) */
  78        unsigned char   lba48;
  79#endif
  80        lbaint_t        lba;            /* number of blocks */
  81        unsigned long   blksz;          /* block size */
  82        int             log2blksz;      /* for convenience: log2(blksz) */
  83        char            vendor[BLK_VEN_SIZE + 1]; /* device vendor string */
  84        char            product[BLK_PRD_SIZE + 1]; /* device product number */
  85        char            revision[BLK_REV_SIZE + 1]; /* firmware revision */
  86        enum sig_type   sig_type;       /* Partition table signature type */
  87        union {
  88                uint32_t mbr_sig;       /* MBR integer signature */
  89                efi_guid_t guid_sig;    /* GPT GUID Signature */
  90        };
  91#if CONFIG_IS_ENABLED(BLK)
  92        /*
  93         * For now we have a few functions which take struct blk_desc as a
  94         * parameter. This field allows them to look up the associated
  95         * device. Once these functions are removed we can drop this field.
  96         */
  97        struct udevice *bdev;
  98#else
  99        unsigned long   (*block_read)(struct blk_desc *block_dev,
 100                                      lbaint_t start,
 101                                      lbaint_t blkcnt,
 102                                      void *buffer);
 103        unsigned long   (*block_write)(struct blk_desc *block_dev,
 104                                       lbaint_t start,
 105                                       lbaint_t blkcnt,
 106                                       const void *buffer);
 107        unsigned long   (*block_erase)(struct blk_desc *block_dev,
 108                                       lbaint_t start,
 109                                       lbaint_t blkcnt);
 110        void            *priv;          /* driver private struct pointer */
 111#endif
 112};
 113
 114#define BLOCK_CNT(size, blk_desc) (PAD_COUNT(size, blk_desc->blksz))
 115#define PAD_TO_BLOCKSIZE(size, blk_desc) \
 116        (PAD_SIZE(size, blk_desc->blksz))
 117
 118#if CONFIG_IS_ENABLED(BLOCK_CACHE)
 119
 120/**
 121 * blkcache_init() - initialize the block cache list pointers
 122 */
 123int blkcache_init(void);
 124
 125/**
 126 * blkcache_read() - attempt to read a set of blocks from cache
 127 *
 128 * @param iftype - IF_TYPE_x for type of device
 129 * @param dev - device index of particular type
 130 * @param start - starting block number
 131 * @param blkcnt - number of blocks to read
 132 * @param blksz - size in bytes of each block
 133 * @param buf - buffer to contain cached data
 134 *
 135 * @return - 1 if block returned from cache, 0 otherwise.
 136 */
 137int blkcache_read(int iftype, int dev,
 138                  lbaint_t start, lbaint_t blkcnt,
 139                  unsigned long blksz, void *buffer);
 140
 141/**
 142 * blkcache_fill() - make data read from a block device available
 143 * to the block cache
 144 *
 145 * @param iftype - IF_TYPE_x for type of device
 146 * @param dev - device index of particular type
 147 * @param start - starting block number
 148 * @param blkcnt - number of blocks available
 149 * @param blksz - size in bytes of each block
 150 * @param buf - buffer containing data to cache
 151 *
 152 */
 153void blkcache_fill(int iftype, int dev,
 154                   lbaint_t start, lbaint_t blkcnt,
 155                   unsigned long blksz, void const *buffer);
 156
 157/**
 158 * blkcache_invalidate() - discard the cache for a set of blocks
 159 * because of a write or device (re)initialization.
 160 *
 161 * @param iftype - IF_TYPE_x for type of device
 162 * @param dev - device index of particular type
 163 */
 164void blkcache_invalidate(int iftype, int dev);
 165
 166/**
 167 * blkcache_configure() - configure block cache
 168 *
 169 * @param blocks - maximum blocks per entry
 170 * @param entries - maximum entries in cache
 171 */
 172void blkcache_configure(unsigned blocks, unsigned entries);
 173
 174/*
 175 * statistics of the block cache
 176 */
 177struct block_cache_stats {
 178        unsigned hits;
 179        unsigned misses;
 180        unsigned entries; /* current entry count */
 181        unsigned max_blocks_per_entry;
 182        unsigned max_entries;
 183};
 184
 185/**
 186 * get_blkcache_stats() - return statistics and reset
 187 *
 188 * @param stats - statistics are copied here
 189 */
 190void blkcache_stats(struct block_cache_stats *stats);
 191
 192#else
 193
 194static inline int blkcache_read(int iftype, int dev,
 195                                lbaint_t start, lbaint_t blkcnt,
 196                                unsigned long blksz, void *buffer)
 197{
 198        return 0;
 199}
 200
 201static inline void blkcache_fill(int iftype, int dev,
 202                                 lbaint_t start, lbaint_t blkcnt,
 203                                 unsigned long blksz, void const *buffer) {}
 204
 205static inline void blkcache_invalidate(int iftype, int dev) {}
 206
 207#endif
 208
 209#if CONFIG_IS_ENABLED(BLK)
 210struct udevice;
 211
 212/* Operations on block devices */
 213struct blk_ops {
 214        /**
 215         * read() - read from a block device
 216         *
 217         * @dev:        Device to read from
 218         * @start:      Start block number to read (0=first)
 219         * @blkcnt:     Number of blocks to read
 220         * @buffer:     Destination buffer for data read
 221         * @return number of blocks read, or -ve error number (see the
 222         * IS_ERR_VALUE() macro
 223         */
 224        unsigned long (*read)(struct udevice *dev, lbaint_t start,
 225                              lbaint_t blkcnt, void *buffer);
 226
 227        /**
 228         * write() - write to a block device
 229         *
 230         * @dev:        Device to write to
 231         * @start:      Start block number to write (0=first)
 232         * @blkcnt:     Number of blocks to write
 233         * @buffer:     Source buffer for data to write
 234         * @return number of blocks written, or -ve error number (see the
 235         * IS_ERR_VALUE() macro
 236         */
 237        unsigned long (*write)(struct udevice *dev, lbaint_t start,
 238                               lbaint_t blkcnt, const void *buffer);
 239
 240        /**
 241         * erase() - erase a section of a block device
 242         *
 243         * @dev:        Device to (partially) erase
 244         * @start:      Start block number to erase (0=first)
 245         * @blkcnt:     Number of blocks to erase
 246         * @return number of blocks erased, or -ve error number (see the
 247         * IS_ERR_VALUE() macro
 248         */
 249        unsigned long (*erase)(struct udevice *dev, lbaint_t start,
 250                               lbaint_t blkcnt);
 251
 252        /**
 253         * select_hwpart() - select a particular hardware partition
 254         *
 255         * Some devices (e.g. MMC) can support partitioning at the hardware
 256         * level. This is quite separate from the normal idea of
 257         * software-based partitions. MMC hardware partitions must be
 258         * explicitly selected. Once selected only the region of the device
 259         * covered by that partition is accessible.
 260         *
 261         * The MMC standard provides for two boot partitions (numbered 1 and 2),
 262         * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
 263         *
 264         * @desc:       Block device to update
 265         * @hwpart:     Hardware partition number to select. 0 means the raw
 266         *              device, 1 is the first partition, 2 is the second, etc.
 267         * @return 0 if OK, -ve on error
 268         */
 269        int (*select_hwpart)(struct udevice *dev, int hwpart);
 270};
 271
 272#define blk_get_ops(dev)        ((struct blk_ops *)(dev)->driver->ops)
 273
 274/*
 275 * These functions should take struct udevice instead of struct blk_desc,
 276 * but this is convenient for migration to driver model. Add a 'd' prefix
 277 * to the function operations, so that blk_read(), etc. can be reserved for
 278 * functions with the correct arguments.
 279 */
 280unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
 281                        lbaint_t blkcnt, void *buffer);
 282unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
 283                         lbaint_t blkcnt, const void *buffer);
 284unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
 285                         lbaint_t blkcnt);
 286
 287/**
 288 * blk_find_device() - Find a block device
 289 *
 290 * This function does not activate the device. The device will be returned
 291 * whether or not it is activated.
 292 *
 293 * @if_type:    Interface type (enum if_type_t)
 294 * @devnum:     Device number (specific to each interface type)
 295 * @devp:       the device, if found
 296 * @return 0 if found, -ENODEV if no device found, or other -ve error value
 297 */
 298int blk_find_device(int if_type, int devnum, struct udevice **devp);
 299
 300/**
 301 * blk_get_device() - Find and probe a block device ready for use
 302 *
 303 * @if_type:    Interface type (enum if_type_t)
 304 * @devnum:     Device number (specific to each interface type)
 305 * @devp:       the device, if found
 306 * @return 0 if found, -ENODEV if no device found, or other -ve error value
 307 */
 308int blk_get_device(int if_type, int devnum, struct udevice **devp);
 309
 310/**
 311 * blk_first_device() - Find the first device for a given interface
 312 *
 313 * The device is probed ready for use
 314 *
 315 * @devnum:     Device number (specific to each interface type)
 316 * @devp:       the device, if found
 317 * @return 0 if found, -ENODEV if no device, or other -ve error value
 318 */
 319int blk_first_device(int if_type, struct udevice **devp);
 320
 321/**
 322 * blk_next_device() - Find the next device for a given interface
 323 *
 324 * This can be called repeatedly after blk_first_device() to iterate through
 325 * all devices of the given interface type.
 326 *
 327 * The device is probed ready for use
 328 *
 329 * @devp:       On entry, the previous device returned. On exit, the next
 330 *              device, if found
 331 * @return 0 if found, -ENODEV if no device, or other -ve error value
 332 */
 333int blk_next_device(struct udevice **devp);
 334
 335/**
 336 * blk_create_device() - Create a new block device
 337 *
 338 * @parent:     Parent of the new device
 339 * @drv_name:   Driver name to use for the block device
 340 * @name:       Name for the device
 341 * @if_type:    Interface type (enum if_type_t)
 342 * @devnum:     Device number, specific to the interface type, or -1 to
 343 *              allocate the next available number
 344 * @blksz:      Block size of the device in bytes (typically 512)
 345 * @lba:        Total number of blocks of the device
 346 * @devp:       the new device (which has not been probed)
 347 */
 348int blk_create_device(struct udevice *parent, const char *drv_name,
 349                      const char *name, int if_type, int devnum, int blksz,
 350                      lbaint_t lba, struct udevice **devp);
 351
 352/**
 353 * blk_create_devicef() - Create a new named block device
 354 *
 355 * @parent:     Parent of the new device
 356 * @drv_name:   Driver name to use for the block device
 357 * @name:       Name for the device (parent name is prepended)
 358 * @if_type:    Interface type (enum if_type_t)
 359 * @devnum:     Device number, specific to the interface type, or -1 to
 360 *              allocate the next available number
 361 * @blksz:      Block size of the device in bytes (typically 512)
 362 * @lba:        Total number of blocks of the device
 363 * @devp:       the new device (which has not been probed)
 364 */
 365int blk_create_devicef(struct udevice *parent, const char *drv_name,
 366                       const char *name, int if_type, int devnum, int blksz,
 367                       lbaint_t lba, struct udevice **devp);
 368
 369/**
 370 * blk_unbind_all() - Unbind all device of the given interface type
 371 *
 372 * The devices are removed and then unbound.
 373 *
 374 * @if_type:    Interface type to unbind
 375 * @return 0 if OK, -ve on error
 376 */
 377int blk_unbind_all(int if_type);
 378
 379/**
 380 * blk_find_max_devnum() - find the maximum device number for an interface type
 381 *
 382 * Finds the last allocated device number for an interface type @if_type. The
 383 * next number is safe to use for a newly allocated device.
 384 *
 385 * @if_type:    Interface type to scan
 386 * @return maximum device number found, or -ENODEV if none, or other -ve on
 387 * error
 388 */
 389int blk_find_max_devnum(enum if_type if_type);
 390
 391/**
 392 * blk_next_free_devnum() - get the next device number for an interface type
 393 *
 394 * Finds the next number that is safe to use for a newly allocated device for
 395 * an interface type @if_type.
 396 *
 397 * @if_type:    Interface type to scan
 398 * @return next device number safe to use, or -ve on error
 399 */
 400int blk_next_free_devnum(enum if_type if_type);
 401
 402/**
 403 * blk_select_hwpart() - select a hardware partition
 404 *
 405 * Select a hardware partition if the device supports it (typically MMC does)
 406 *
 407 * @dev:        Device to update
 408 * @hwpart:     Partition number to select
 409 * @return 0 if OK, -ve on error
 410 */
 411int blk_select_hwpart(struct udevice *dev, int hwpart);
 412
 413/**
 414 * blk_get_from_parent() - obtain a block device by looking up its parent
 415 *
 416 * All devices with
 417 */
 418int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
 419
 420/**
 421 * blk_get_by_device() - Get the block device descriptor for the given device
 422 * @dev:        Instance of a storage device
 423 *
 424 * Return: With block device descriptor on success , NULL if there is no such
 425 *         block device.
 426 */
 427struct blk_desc *blk_get_by_device(struct udevice *dev);
 428
 429#else
 430#include <errno.h>
 431/*
 432 * These functions should take struct udevice instead of struct blk_desc,
 433 * but this is convenient for migration to driver model. Add a 'd' prefix
 434 * to the function operations, so that blk_read(), etc. can be reserved for
 435 * functions with the correct arguments.
 436 */
 437static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start,
 438                              lbaint_t blkcnt, void *buffer)
 439{
 440        ulong blks_read;
 441        if (blkcache_read(block_dev->if_type, block_dev->devnum,
 442                          start, blkcnt, block_dev->blksz, buffer))
 443                return blkcnt;
 444
 445        /*
 446         * We could check if block_read is NULL and return -ENOSYS. But this
 447         * bloats the code slightly (cause some board to fail to build), and
 448         * it would be an error to try an operation that does not exist.
 449         */
 450        blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer);
 451        if (blks_read == blkcnt)
 452                blkcache_fill(block_dev->if_type, block_dev->devnum,
 453                              start, blkcnt, block_dev->blksz, buffer);
 454
 455        return blks_read;
 456}
 457
 458static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
 459                               lbaint_t blkcnt, const void *buffer)
 460{
 461        blkcache_invalidate(block_dev->if_type, block_dev->devnum);
 462        return block_dev->block_write(block_dev, start, blkcnt, buffer);
 463}
 464
 465static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
 466                               lbaint_t blkcnt)
 467{
 468        blkcache_invalidate(block_dev->if_type, block_dev->devnum);
 469        return block_dev->block_erase(block_dev, start, blkcnt);
 470}
 471
 472/**
 473 * struct blk_driver - Driver for block interface types
 474 *
 475 * This provides access to the block devices for each interface type. One
 476 * driver should be provided using U_BOOT_LEGACY_BLK() for each interface
 477 * type that is to be supported.
 478 *
 479 * @if_typename:        Interface type name
 480 * @if_type:            Interface type
 481 * @max_devs:           Maximum number of devices supported
 482 * @desc:               Pointer to list of devices for this interface type,
 483 *                      or NULL to use @get_dev() instead
 484 */
 485struct blk_driver {
 486        const char *if_typename;
 487        enum if_type if_type;
 488        int max_devs;
 489        struct blk_desc *desc;
 490        /**
 491         * get_dev() - get a pointer to a block device given its number
 492         *
 493         * Each interface allocates its own devices and typically
 494         * struct blk_desc is contained with the interface's data structure.
 495         * There is no global numbering for block devices. This method allows
 496         * the device for an interface type to be obtained when @desc is NULL.
 497         *
 498         * @devnum:     Device number (0 for first device on that interface,
 499         *              1 for second, etc.
 500         * @descp:      Returns pointer to the block device on success
 501         * @return 0 if OK, -ve on error
 502         */
 503        int (*get_dev)(int devnum, struct blk_desc **descp);
 504
 505        /**
 506         * select_hwpart() - Select a hardware partition
 507         *
 508         * Some devices (e.g. MMC) can support partitioning at the hardware
 509         * level. This is quite separate from the normal idea of
 510         * software-based partitions. MMC hardware partitions must be
 511         * explicitly selected. Once selected only the region of the device
 512         * covered by that partition is accessible.
 513         *
 514         * The MMC standard provides for two boot partitions (numbered 1 and 2),
 515         * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
 516         * Partition 0 is the main user-data partition.
 517         *
 518         * @desc:       Block device descriptor
 519         * @hwpart:     Hardware partition number to select. 0 means the main
 520         *              user-data partition, 1 is the first partition, 2 is
 521         *              the second, etc.
 522         * @return 0 if OK, other value for an error
 523         */
 524        int (*select_hwpart)(struct blk_desc *desc, int hwpart);
 525};
 526
 527/*
 528 * Declare a new U-Boot legacy block driver. New drivers should use driver
 529 * model (UCLASS_BLK).
 530 */
 531#define U_BOOT_LEGACY_BLK(__name)                                       \
 532        ll_entry_declare(struct blk_driver, __name, blk_driver)
 533
 534struct blk_driver *blk_driver_lookup_type(int if_type);
 535
 536#endif /* !CONFIG_BLK */
 537
 538/**
 539 * blk_get_devnum_by_typename() - Get a block device by type and number
 540 *
 541 * This looks through the available block devices of the given type, returning
 542 * the one with the given @devnum.
 543 *
 544 * @if_type:    Block device type
 545 * @devnum:     Device number
 546 * @return point to block device descriptor, or NULL if not found
 547 */
 548struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum);
 549
 550/**
 551 * blk_get_devnum_by_type() - Get a block device by type name, and number
 552 *
 553 * This looks up the block device type based on @if_typename, then calls
 554 * blk_get_devnum_by_type().
 555 *
 556 * @if_typename:        Block device type name
 557 * @devnum:             Device number
 558 * @return point to block device descriptor, or NULL if not found
 559 */
 560struct blk_desc *blk_get_devnum_by_typename(const char *if_typename,
 561                                            int devnum);
 562
 563/**
 564 * blk_dselect_hwpart() - select a hardware partition
 565 *
 566 * This selects a hardware partition (such as is supported by MMC). The block
 567 * device size may change as this effectively points the block device to a
 568 * partition at the hardware level. See the select_hwpart() method above.
 569 *
 570 * @desc:       Block device descriptor for the device to select
 571 * @hwpart:     Partition number to select
 572 * @return 0 if OK, -ve on error
 573 */
 574int blk_dselect_hwpart(struct blk_desc *desc, int hwpart);
 575
 576/**
 577 * blk_list_part() - list the partitions for block devices of a given type
 578 *
 579 * This looks up the partition type for each block device of type @if_type,
 580 * then displays a list of partitions.
 581 *
 582 * @if_type:    Block device type
 583 * @return 0 if OK, -ENODEV if there is none of that type
 584 */
 585int blk_list_part(enum if_type if_type);
 586
 587/**
 588 * blk_list_devices() - list the block devices of a given type
 589 *
 590 * This lists each block device of the type @if_type, showing the capacity
 591 * as well as type-specific information.
 592 *
 593 * @if_type:    Block device type
 594 */
 595void blk_list_devices(enum if_type if_type);
 596
 597/**
 598 * blk_show_device() - show information about a given block device
 599 *
 600 * This shows the block device capacity as well as type-specific information.
 601 *
 602 * @if_type:    Block device type
 603 * @devnum:     Device number
 604 * @return 0 if OK, -ENODEV for invalid device number
 605 */
 606int blk_show_device(enum if_type if_type, int devnum);
 607
 608/**
 609 * blk_print_device_num() - show information about a given block device
 610 *
 611 * This is similar to blk_show_device() but returns an error if the block
 612 * device type is unknown.
 613 *
 614 * @if_type:    Block device type
 615 * @devnum:     Device number
 616 * @return 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
 617 * device is not connected
 618 */
 619int blk_print_device_num(enum if_type if_type, int devnum);
 620
 621/**
 622 * blk_print_part_devnum() - print the partition information for a device
 623 *
 624 * @if_type:    Block device type
 625 * @devnum:     Device number
 626 * @return 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
 627 * the interface type is not supported, other -ve on other error
 628 */
 629int blk_print_part_devnum(enum if_type if_type, int devnum);
 630
 631/**
 632 * blk_read_devnum() - read blocks from a device
 633 *
 634 * @if_type:    Block device type
 635 * @devnum:     Device number
 636 * @blkcnt:     Number of blocks to read
 637 * @buffer:     Address to write data to
 638 * @return number of blocks read, or -ve error number on error
 639 */
 640ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
 641                      lbaint_t blkcnt, void *buffer);
 642
 643/**
 644 * blk_write_devnum() - write blocks to a device
 645 *
 646 * @if_type:    Block device type
 647 * @devnum:     Device number
 648 * @blkcnt:     Number of blocks to write
 649 * @buffer:     Address to read data from
 650 * @return number of blocks written, or -ve error number on error
 651 */
 652ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
 653                       lbaint_t blkcnt, const void *buffer);
 654
 655/**
 656 * blk_select_hwpart_devnum() - select a hardware partition
 657 *
 658 * This is similar to blk_dselect_hwpart() but it looks up the interface and
 659 * device number.
 660 *
 661 * @if_type:    Block device type
 662 * @devnum:     Device number
 663 * @hwpart:     Partition number to select
 664 * @return 0 if OK, -ve on error
 665 */
 666int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart);
 667
 668/**
 669 * blk_get_if_type_name() - Get the name of an interface type
 670 *
 671 * @if_type: Interface type to check
 672 * @return name of interface, or NULL if none
 673 */
 674const char *blk_get_if_type_name(enum if_type if_type);
 675
 676/**
 677 * blk_common_cmd() - handle common commands with block devices
 678 *
 679 * @args: Number of arguments to the command (argv[0] is the command itself)
 680 * @argv: Command arguments
 681 * @if_type: Interface type
 682 * @cur_devnump: Current device number for this interface type
 683 * @return 0 if OK, CMD_RET_ERROR on error
 684 */
 685int blk_common_cmd(int argc, char *const argv[], enum if_type if_type,
 686                   int *cur_devnump);
 687
 688enum blk_flag_t {
 689        BLKF_FIXED      = 1 << 0,
 690        BLKF_REMOVABLE  = 1 << 1,
 691        BLKF_BOTH       = BLKF_FIXED | BLKF_REMOVABLE,
 692};
 693
 694/**
 695 * blk_first_device_err() - Get the first block device
 696 *
 697 * The device returned is probed if necessary, and ready for use
 698 *
 699 * @flags: Indicates type of device to return
 700 * @devp: Returns pointer to the first device in that uclass, or NULL if none
 701 * @return 0 if found, -ENODEV if not found, other -ve on error
 702 */
 703int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp);
 704
 705/**
 706 * blk_next_device_err() - Get the next block device
 707 *
 708 * The device returned is probed if necessary, and ready for use
 709 *
 710 * @flags: Indicates type of device to return
 711 * @devp: On entry, pointer to device to lookup. On exit, returns pointer
 712 * to the next device in the uclass if no error occurred, or -ENODEV if
 713 * there is no next device.
 714 * @return 0 if found, -ENODEV if not found, other -ve on error
 715 */
 716int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp);
 717
 718/**
 719 * blk_foreach_probe() - Helper function to iteration through block devices
 720 *
 721 * This creates a for() loop which works through the available devices in
 722 * a uclass in order from start to end. Devices are probed if necessary,
 723 * and ready for use.
 724 *
 725 * @flags: Indicates type of device to return
 726 * @dev: struct udevice * to hold the current device. Set to NULL when there
 727 * are no more devices.
 728 */
 729#define blk_foreach_probe(flags, pos)   \
 730        for (int _ret = blk_first_device_err(flags, &(pos)); \
 731             !_ret && pos; \
 732             _ret = blk_next_device_err(flags, &(pos)))
 733
 734/**
 735 * blk_count_devices() - count the number of devices of a particular type
 736 *
 737 * @flags: Indicates type of device to find
 738 * @return number of devices matching those flags
 739 */
 740int blk_count_devices(enum blk_flag_t flag);
 741
 742#endif
 743