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