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