blob: 76bd5baf99594fd90aa67de4335d22540692fe28 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Simon Glassac8162f2016-02-29 15:25:39 -07002/*
3 * (C) Copyright 2000-2004
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
Simon Glassac8162f2016-02-29 15:25:39 -07005 */
6
7#ifndef BLK_H
8#define BLK_H
9
Marek Vasut847e24f2023-08-14 01:49:59 +020010#include <bouncebuf.h>
Simon Glassdbfa32c2022-08-11 19:34:59 -060011#include <dm/uclass-id.h>
Peter Jonesc27e1c12017-09-13 18:05:25 -040012#include <efi.h>
13
Simon Glassac8162f2016-02-29 15:25:39 -070014#ifdef CONFIG_SYS_64BIT_LBA
15typedef uint64_t lbaint_t;
16#define LBAFlength "ll"
17#else
18typedef ulong lbaint_t;
19#define LBAFlength "l"
20#endif
21#define LBAF "%" LBAFlength "x"
22#define LBAFU "%" LBAFlength "u"
23
Bin Meng2294ecb2023-09-26 16:43:31 +080024#define DEFAULT_BLKSZ 512
25
Simon Glassfc7a7442021-07-05 16:32:59 -060026struct udevice;
27
Simon Glassf5ac3032022-08-11 19:34:45 -060028static inline bool blk_enabled(void)
29{
Simon Glass3bf7d7a2022-08-11 19:34:48 -060030 return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_SPL_LEGACY_BLOCK);
Simon Glassf5ac3032022-08-11 19:34:45 -060031}
32
Bin Mengcf406d22017-09-10 05:12:50 -070033#define BLK_VEN_SIZE 40
34#define BLK_PRD_SIZE 20
35#define BLK_REV_SIZE 8
36
Masahisa Kojima6460c3e2021-10-26 17:27:25 +090037#define PART_FORMAT_PCAT 0x1
38#define PART_FORMAT_GPT 0x2
39
Simon Glasscceee552016-02-29 15:25:55 -070040/*
Peter Jonesc27e1c12017-09-13 18:05:25 -040041 * Identifies the partition table type (ie. MBR vs GPT GUID) signature
42 */
43enum sig_type {
44 SIG_TYPE_NONE,
45 SIG_TYPE_MBR,
46 SIG_TYPE_GUID,
47
48 SIG_TYPE_COUNT /* Number of signature types */
49};
50
51/*
Simon Glasscceee552016-02-29 15:25:55 -070052 * With driver model (CONFIG_BLK) this is uclass platform data, accessible
Simon Glass71fa5b42020-12-03 16:55:18 -070053 * with dev_get_uclass_plat(dev)
Simon Glasscceee552016-02-29 15:25:55 -070054 */
Simon Glassac8162f2016-02-29 15:25:39 -070055struct blk_desc {
Simon Glasscceee552016-02-29 15:25:55 -070056 /*
57 * TODO: With driver model we should be able to use the parent
58 * device's uclass instead.
59 */
Simon Glassfada3f92022-09-17 09:00:09 -060060 enum uclass_id uclass_id; /* type of the interface */
Simon Glass2f26fff2016-02-29 15:25:51 -070061 int devnum; /* device number */
Simon Glassac8162f2016-02-29 15:25:39 -070062 unsigned char part_type; /* partition type */
63 unsigned char target; /* target SCSI ID */
64 unsigned char lun; /* target LUN */
65 unsigned char hwpart; /* HW partition, e.g. for eMMC */
66 unsigned char type; /* device type */
67 unsigned char removable; /* removable device */
Simon Glassac8162f2016-02-29 15:25:39 -070068 /* device can use 48bit addr (ATA/ATAPI v7) */
Simon Glass61317282023-04-25 10:54:41 -060069 bool lba48;
Simon Glass631db662023-04-25 10:54:35 -060070 unsigned char atapi; /* Use ATAPI protocol */
Simon Glassac8162f2016-02-29 15:25:39 -070071 lbaint_t lba; /* number of blocks */
72 unsigned long blksz; /* block size */
73 int log2blksz; /* for convenience: log2(blksz) */
Bin Mengcf406d22017-09-10 05:12:50 -070074 char vendor[BLK_VEN_SIZE + 1]; /* device vendor string */
75 char product[BLK_PRD_SIZE + 1]; /* device product number */
76 char revision[BLK_REV_SIZE + 1]; /* firmware revision */
Peter Jonesc27e1c12017-09-13 18:05:25 -040077 enum sig_type sig_type; /* Partition table signature type */
78 union {
79 uint32_t mbr_sig; /* MBR integer signature */
80 efi_guid_t guid_sig; /* GPT GUID Signature */
81 };
Simon Glass5f4bd8c2017-07-04 13:31:19 -060082#if CONFIG_IS_ENABLED(BLK)
Simon Glass8f5f7222016-05-01 13:52:33 -060083 /*
84 * For now we have a few functions which take struct blk_desc as a
85 * parameter. This field allows them to look up the associated
86 * device. Once these functions are removed we can drop this field.
87 */
Simon Glasscceee552016-02-29 15:25:55 -070088 struct udevice *bdev;
89#else
Simon Glassac8162f2016-02-29 15:25:39 -070090 unsigned long (*block_read)(struct blk_desc *block_dev,
91 lbaint_t start,
92 lbaint_t blkcnt,
93 void *buffer);
94 unsigned long (*block_write)(struct blk_desc *block_dev,
95 lbaint_t start,
96 lbaint_t blkcnt,
97 const void *buffer);
98 unsigned long (*block_erase)(struct blk_desc *block_dev,
99 lbaint_t start,
100 lbaint_t blkcnt);
101 void *priv; /* driver private struct pointer */
Simon Glasscceee552016-02-29 15:25:55 -0700102#endif
Simon Glassac8162f2016-02-29 15:25:39 -0700103};
104
105#define BLOCK_CNT(size, blk_desc) (PAD_COUNT(size, blk_desc->blksz))
106#define PAD_TO_BLOCKSIZE(size, blk_desc) \
107 (PAD_SIZE(size, blk_desc->blksz))
108
Adam Fordd693fb92018-06-11 17:17:48 -0500109#if CONFIG_IS_ENABLED(BLOCK_CACHE)
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700110/**
111 * blkcache_read() - attempt to read a set of blocks from cache
112 *
Simon Glassfada3f92022-09-17 09:00:09 -0600113 * @param iftype - uclass_id_x for type of device
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700114 * @param dev - device index of particular type
115 * @param start - starting block number
116 * @param blkcnt - number of blocks to read
117 * @param blksz - size in bytes of each block
Mattijs Korpershoek3cc71a02022-10-17 09:35:04 +0200118 * @param buffer - buffer to contain cached data
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700119 *
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100120 * Return: - 1 if block returned from cache, 0 otherwise.
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700121 */
Eric Nelsonf201f232016-04-02 07:37:14 -0700122int blkcache_read(int iftype, int dev,
123 lbaint_t start, lbaint_t blkcnt,
124 unsigned long blksz, void *buffer);
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700125
126/**
127 * blkcache_fill() - make data read from a block device available
128 * to the block cache
129 *
Simon Glassfada3f92022-09-17 09:00:09 -0600130 * @param iftype - uclass_id_x for type of device
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700131 * @param dev - device index of particular type
132 * @param start - starting block number
133 * @param blkcnt - number of blocks available
134 * @param blksz - size in bytes of each block
Mattijs Korpershoek3cc71a02022-10-17 09:35:04 +0200135 * @param buffer - buffer containing data to cache
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700136 *
137 */
Eric Nelsonf201f232016-04-02 07:37:14 -0700138void blkcache_fill(int iftype, int dev,
139 lbaint_t start, lbaint_t blkcnt,
140 unsigned long blksz, void const *buffer);
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700141
142/**
143 * blkcache_invalidate() - discard the cache for a set of blocks
144 * because of a write or device (re)initialization.
145 *
Simon Glass76c62692022-10-29 19:47:08 -0600146 * @iftype - UCLASS_ID_ for type of device, or -1 for any
147 * @dev - device index of particular type, if @iftype is not -1
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700148 */
Eric Nelsonf201f232016-04-02 07:37:14 -0700149void blkcache_invalidate(int iftype, int dev);
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700150
151/**
152 * blkcache_configure() - configure block cache
153 *
154 * @param blocks - maximum blocks per entry
155 * @param entries - maximum entries in cache
156 */
157void blkcache_configure(unsigned blocks, unsigned entries);
158
159/*
160 * statistics of the block cache
161 */
162struct block_cache_stats {
163 unsigned hits;
164 unsigned misses;
165 unsigned entries; /* current entry count */
166 unsigned max_blocks_per_entry;
167 unsigned max_entries;
168};
169
170/**
171 * get_blkcache_stats() - return statistics and reset
172 *
173 * @param stats - statistics are copied here
174 */
175void blkcache_stats(struct block_cache_stats *stats);
176
Simon Glass76c62692022-10-29 19:47:08 -0600177/** blkcache_free() - free all memory allocated to the block cache */
178void blkcache_free(void);
179
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700180#else
181
Eric Nelsonf201f232016-04-02 07:37:14 -0700182static inline int blkcache_read(int iftype, int dev,
183 lbaint_t start, lbaint_t blkcnt,
184 unsigned long blksz, void *buffer)
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700185{
186 return 0;
187}
188
Eric Nelsonf201f232016-04-02 07:37:14 -0700189static inline void blkcache_fill(int iftype, int dev,
190 lbaint_t start, lbaint_t blkcnt,
191 unsigned long blksz, void const *buffer) {}
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700192
Eric Nelsonf201f232016-04-02 07:37:14 -0700193static inline void blkcache_invalidate(int iftype, int dev) {}
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700194
Simon Glass76c62692022-10-29 19:47:08 -0600195static inline void blkcache_free(void) {}
196
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700197#endif
198
Simon Glass5f4bd8c2017-07-04 13:31:19 -0600199#if CONFIG_IS_ENABLED(BLK)
Simon Glasscceee552016-02-29 15:25:55 -0700200struct udevice;
201
202/* Operations on block devices */
203struct blk_ops {
204 /**
205 * read() - read from a block device
206 *
207 * @dev: Device to read from
208 * @start: Start block number to read (0=first)
209 * @blkcnt: Number of blocks to read
210 * @buffer: Destination buffer for data read
211 * @return number of blocks read, or -ve error number (see the
212 * IS_ERR_VALUE() macro
213 */
214 unsigned long (*read)(struct udevice *dev, lbaint_t start,
215 lbaint_t blkcnt, void *buffer);
216
217 /**
218 * write() - write to a block device
219 *
220 * @dev: Device to write to
221 * @start: Start block number to write (0=first)
222 * @blkcnt: Number of blocks to write
223 * @buffer: Source buffer for data to write
224 * @return number of blocks written, or -ve error number (see the
225 * IS_ERR_VALUE() macro
226 */
227 unsigned long (*write)(struct udevice *dev, lbaint_t start,
228 lbaint_t blkcnt, const void *buffer);
229
230 /**
231 * erase() - erase a section of a block device
232 *
233 * @dev: Device to (partially) erase
234 * @start: Start block number to erase (0=first)
235 * @blkcnt: Number of blocks to erase
236 * @return number of blocks erased, or -ve error number (see the
237 * IS_ERR_VALUE() macro
238 */
239 unsigned long (*erase)(struct udevice *dev, lbaint_t start,
240 lbaint_t blkcnt);
Simon Glass13c2c292016-05-01 13:52:30 -0600241
242 /**
243 * select_hwpart() - select a particular hardware partition
244 *
245 * Some devices (e.g. MMC) can support partitioning at the hardware
246 * level. This is quite separate from the normal idea of
247 * software-based partitions. MMC hardware partitions must be
248 * explicitly selected. Once selected only the region of the device
249 * covered by that partition is accessible.
250 *
251 * The MMC standard provides for two boot partitions (numbered 1 and 2),
252 * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
253 *
Mattijs Korpershoek3cc71a02022-10-17 09:35:04 +0200254 * @dev: Block device to update
Simon Glass13c2c292016-05-01 13:52:30 -0600255 * @hwpart: Hardware partition number to select. 0 means the raw
256 * device, 1 is the first partition, 2 is the second, etc.
257 * @return 0 if OK, -ve on error
258 */
259 int (*select_hwpart)(struct udevice *dev, int hwpart);
Marek Vasut847e24f2023-08-14 01:49:59 +0200260
261#if IS_ENABLED(CONFIG_BOUNCE_BUFFER)
262 /**
263 * buffer_aligned() - test memory alignment of block operation buffer
264 *
265 * Some devices have limited DMA capabilities and require that the
266 * buffers passed to them fit specific properties. This optional
267 * callback can be used to indicate whether a buffer alignment is
268 * suitable for the device DMA or not, and trigger use of generic
269 * bounce buffer implementation to help use of unsuitable buffers
270 * at the expense of performance degradation.
271 *
272 * @dev: Block device associated with the request
273 * @state: Bounce buffer state
274 * @return 1 if OK, 0 if unaligned
275 */
276 int (*buffer_aligned)(struct udevice *dev, struct bounce_buffer *state);
277#endif /* CONFIG_BOUNCE_BUFFER */
Simon Glasscceee552016-02-29 15:25:55 -0700278};
279
Simon Glasscceee552016-02-29 15:25:55 -0700280/*
281 * These functions should take struct udevice instead of struct blk_desc,
282 * but this is convenient for migration to driver model. Add a 'd' prefix
283 * to the function operations, so that blk_read(), etc. can be reserved for
284 * functions with the correct arguments.
285 */
286unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
287 lbaint_t blkcnt, void *buffer);
288unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
289 lbaint_t blkcnt, const void *buffer);
290unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
291 lbaint_t blkcnt);
292
293/**
Simon Glass18861002022-10-20 18:22:54 -0600294 * blk_read() - Read from a block device
295 *
296 * @dev: Device to read from
297 * @start: Start block for the read
298 * @blkcnt: Number of blocks to read
299 * @buf: Place to put the data
300 * @return number of blocks read (which may be less than @blkcnt),
301 * or -ve on error. This never returns 0 unless @blkcnt is 0
302 */
303long blk_read(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
304 void *buffer);
305
306/**
307 * blk_write() - Write to a block device
308 *
309 * @dev: Device to write to
310 * @start: Start block for the write
311 * @blkcnt: Number of blocks to write
312 * @buf: Data to write
313 * @return number of blocks written (which may be less than @blkcnt),
314 * or -ve on error. This never returns 0 unless @blkcnt is 0
315 */
316long blk_write(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
317 const void *buffer);
318
319/**
320 * blk_erase() - Erase part of a block device
321 *
322 * @dev: Device to erase
323 * @start: Start block for the erase
324 * @blkcnt: Number of blocks to erase
325 * @return number of blocks erased (which may be less than @blkcnt),
326 * or -ve on error. This never returns 0 unless @blkcnt is 0
327 */
328long blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt);
329
330/**
Simon Glassd5d4c102017-04-23 20:02:05 -0600331 * blk_find_device() - Find a block device
332 *
333 * This function does not activate the device. The device will be returned
334 * whether or not it is activated.
335 *
Simon Glassfada3f92022-09-17 09:00:09 -0600336 * @uclass_id: Interface type (enum uclass_id_t)
Simon Glassd5d4c102017-04-23 20:02:05 -0600337 * @devnum: Device number (specific to each interface type)
338 * @devp: the device, if found
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100339 * Return: 0 if found, -ENODEV if no device found, or other -ve error value
Simon Glassd5d4c102017-04-23 20:02:05 -0600340 */
Simon Glassfada3f92022-09-17 09:00:09 -0600341int blk_find_device(int uclass_id, int devnum, struct udevice **devp);
Simon Glassd5d4c102017-04-23 20:02:05 -0600342
343/**
Simon Glasscceee552016-02-29 15:25:55 -0700344 * blk_get_device() - Find and probe a block device ready for use
345 *
Simon Glassfada3f92022-09-17 09:00:09 -0600346 * @uclass_id: Interface type (enum uclass_id_t)
Simon Glasscceee552016-02-29 15:25:55 -0700347 * @devnum: Device number (specific to each interface type)
348 * @devp: the device, if found
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100349 * Return: 0 if found, -ENODEV if no device found, or other -ve error value
Simon Glasscceee552016-02-29 15:25:55 -0700350 */
Simon Glassfada3f92022-09-17 09:00:09 -0600351int blk_get_device(int uclass_id, int devnum, struct udevice **devp);
Simon Glasscceee552016-02-29 15:25:55 -0700352
353/**
354 * blk_first_device() - Find the first device for a given interface
355 *
356 * The device is probed ready for use
357 *
358 * @devnum: Device number (specific to each interface type)
359 * @devp: the device, if found
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100360 * Return: 0 if found, -ENODEV if no device, or other -ve error value
Simon Glasscceee552016-02-29 15:25:55 -0700361 */
Simon Glassfada3f92022-09-17 09:00:09 -0600362int blk_first_device(int uclass_id, struct udevice **devp);
Simon Glasscceee552016-02-29 15:25:55 -0700363
364/**
365 * blk_next_device() - Find the next device for a given interface
366 *
367 * This can be called repeatedly after blk_first_device() to iterate through
368 * all devices of the given interface type.
369 *
370 * The device is probed ready for use
371 *
372 * @devp: On entry, the previous device returned. On exit, the next
373 * device, if found
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100374 * Return: 0 if found, -ENODEV if no device, or other -ve error value
Simon Glasscceee552016-02-29 15:25:55 -0700375 */
376int blk_next_device(struct udevice **devp);
377
378/**
379 * blk_create_device() - Create a new block device
380 *
381 * @parent: Parent of the new device
382 * @drv_name: Driver name to use for the block device
383 * @name: Name for the device
Simon Glassfada3f92022-09-17 09:00:09 -0600384 * @uclass_id: Interface type (enum uclass_id_t)
Simon Glassd089ba32016-05-01 11:36:28 -0600385 * @devnum: Device number, specific to the interface type, or -1 to
386 * allocate the next available number
Simon Glasscceee552016-02-29 15:25:55 -0700387 * @blksz: Block size of the device in bytes (typically 512)
Jean-Jacques Hiblot99b324a2017-06-09 16:45:18 +0200388 * @lba: Total number of blocks of the device
Simon Glasscceee552016-02-29 15:25:55 -0700389 * @devp: the new device (which has not been probed)
390 */
391int blk_create_device(struct udevice *parent, const char *drv_name,
Simon Glassfada3f92022-09-17 09:00:09 -0600392 const char *name, int uclass_id, int devnum, int blksz,
Jean-Jacques Hiblot99b324a2017-06-09 16:45:18 +0200393 lbaint_t lba, struct udevice **devp);
Simon Glasscceee552016-02-29 15:25:55 -0700394
395/**
Simon Glass966b6952016-05-01 11:36:29 -0600396 * blk_create_devicef() - Create a new named block device
397 *
398 * @parent: Parent of the new device
399 * @drv_name: Driver name to use for the block device
400 * @name: Name for the device (parent name is prepended)
Simon Glassfada3f92022-09-17 09:00:09 -0600401 * @uclass_id: Interface type (enum uclass_id_t)
Simon Glass966b6952016-05-01 11:36:29 -0600402 * @devnum: Device number, specific to the interface type, or -1 to
403 * allocate the next available number
404 * @blksz: Block size of the device in bytes (typically 512)
Jean-Jacques Hiblot99b324a2017-06-09 16:45:18 +0200405 * @lba: Total number of blocks of the device
Simon Glass966b6952016-05-01 11:36:29 -0600406 * @devp: the new device (which has not been probed)
407 */
408int blk_create_devicef(struct udevice *parent, const char *drv_name,
Simon Glassfada3f92022-09-17 09:00:09 -0600409 const char *name, int uclass_id, int devnum, int blksz,
Jean-Jacques Hiblot99b324a2017-06-09 16:45:18 +0200410 lbaint_t lba, struct udevice **devp);
Simon Glass966b6952016-05-01 11:36:29 -0600411
412/**
AKASHI Takahiro3e32dbe2021-12-10 15:49:29 +0900413 * blk_probe_or_unbind() - Try to probe
414 *
415 * Try to probe the device, primarily for enumerating partitions.
416 * If it fails, the device itself is unbound since it means that it won't
417 * work any more.
418 *
419 * @dev: The device to probe
420 * Return: 0 if OK, -ve on error
421 */
422int blk_probe_or_unbind(struct udevice *dev);
423
424/**
Simon Glasscceee552016-02-29 15:25:55 -0700425 * blk_unbind_all() - Unbind all device of the given interface type
426 *
427 * The devices are removed and then unbound.
428 *
Simon Glassfada3f92022-09-17 09:00:09 -0600429 * @uclass_id: Interface type to unbind
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100430 * Return: 0 if OK, -ve on error
Simon Glasscceee552016-02-29 15:25:55 -0700431 */
Simon Glassfada3f92022-09-17 09:00:09 -0600432int blk_unbind_all(int uclass_id);
Simon Glasscceee552016-02-29 15:25:55 -0700433
Simon Glassd089ba32016-05-01 11:36:28 -0600434/**
435 * blk_find_max_devnum() - find the maximum device number for an interface type
436 *
Simon Glassfada3f92022-09-17 09:00:09 -0600437 * Finds the last allocated device number for an interface type @uclass_id. The
Simon Glassd089ba32016-05-01 11:36:28 -0600438 * next number is safe to use for a newly allocated device.
439 *
Simon Glassfada3f92022-09-17 09:00:09 -0600440 * @uclass_id: Interface type to scan
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100441 * Return: maximum device number found, or -ENODEV if none, or other -ve on
Simon Glassd089ba32016-05-01 11:36:28 -0600442 * error
443 */
Simon Glassfada3f92022-09-17 09:00:09 -0600444int blk_find_max_devnum(enum uclass_id uclass_id);
Simon Glassd089ba32016-05-01 11:36:28 -0600445
Simon Glass13c2c292016-05-01 13:52:30 -0600446/**
Bin Mengfd5eda72018-10-15 02:21:09 -0700447 * blk_next_free_devnum() - get the next device number for an interface type
448 *
449 * Finds the next number that is safe to use for a newly allocated device for
Simon Glassfada3f92022-09-17 09:00:09 -0600450 * an interface type @uclass_id.
Bin Mengfd5eda72018-10-15 02:21:09 -0700451 *
Simon Glassfada3f92022-09-17 09:00:09 -0600452 * @uclass_id: Interface type to scan
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100453 * Return: next device number safe to use, or -ve on error
Bin Mengfd5eda72018-10-15 02:21:09 -0700454 */
Simon Glassfada3f92022-09-17 09:00:09 -0600455int blk_next_free_devnum(enum uclass_id uclass_id);
Bin Mengfd5eda72018-10-15 02:21:09 -0700456
457/**
Simon Glass13c2c292016-05-01 13:52:30 -0600458 * blk_select_hwpart() - select a hardware partition
459 *
460 * Select a hardware partition if the device supports it (typically MMC does)
461 *
462 * @dev: Device to update
463 * @hwpart: Partition number to select
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100464 * Return: 0 if OK, -ve on error
Simon Glass13c2c292016-05-01 13:52:30 -0600465 */
466int blk_select_hwpart(struct udevice *dev, int hwpart);
467
Tom Rini7c41d142017-06-10 10:01:05 -0400468/**
Simon Glassc0bcaaf2022-10-29 19:47:14 -0600469 * blk_find_from_parent() - find a block device by looking up its parent
470 *
471 * All block devices have a parent 'media' device which provides the block
472 * driver for the block device, ensuring that access to the underlying medium
473 * is available.
474 *
475 * The block device is not activated by this function. See
476 * blk_get_from_parent() for that.
477 *
478 * @parent: Media device
479 * @devp: Returns the associated block device, if any
480 * Returns: 0 if OK, -ENODEV if @parent is not a media device and has no
481 * UCLASS_BLK child
482 */
483int blk_find_from_parent(struct udevice *parent, struct udevice **devp);
484
485/**
Tom Rini7c41d142017-06-10 10:01:05 -0400486 * blk_get_from_parent() - obtain a block device by looking up its parent
487 *
Simon Glassc0bcaaf2022-10-29 19:47:14 -0600488 * All block devices have a parent 'media' device which provides the block
489 * driver for the block device, ensuring that access to the underlying medium
490 * is available.
491 *
492 * The block device is probed and ready for use.
493 *
494 * @parent: Media device
495 * @devp: Returns the associated block device, if any
496 * Returns: 0 if OK, -ENODEV if @parent is not a media device and has no
497 * UCLASS_BLK child
Tom Rini7c41d142017-06-10 10:01:05 -0400498 */
499int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
500
Tien Fong Chee10378522018-07-06 16:26:36 +0800501/**
Simon Glassf3086cf2022-04-24 23:31:03 -0600502 * blk_get_devtype() - Get the device type of a block device
503 *
504 * @dev: Block device to check
505 * Return: device tree, i.e. the uclass name of its parent, e.g. "mmc"
506 */
507const char *blk_get_devtype(struct udevice *dev);
508
509/**
Tien Fong Chee10378522018-07-06 16:26:36 +0800510 * blk_get_by_device() - Get the block device descriptor for the given device
Simon Glass18861002022-10-20 18:22:54 -0600511 * @dev: Instance of a storage device (the parent of the block device)
Tien Fong Chee10378522018-07-06 16:26:36 +0800512 *
513 * Return: With block device descriptor on success , NULL if there is no such
514 * block device.
515 */
516struct blk_desc *blk_get_by_device(struct udevice *dev);
517
Bin Meng9efc2452023-09-26 16:43:41 +0800518/**
519 * blk_get_desc() - Get the block device descriptor for the given device number
520 *
521 * @uclass_id: Interface type
522 * @devnum: Device number (0 = first)
523 * @descp: Returns block device descriptor on success
524 * Return: 0 on success, -ENODEV if there is no such device and no device
525 * with a higher device number, -ENOENT if there is no such device but there
526 * is one with a higher number, or other -ve on other error.
527 */
528int blk_get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp);
529
Simon Glasscceee552016-02-29 15:25:55 -0700530#else
531#include <errno.h>
Simon Glass2ee8ada2016-02-29 15:25:52 -0700532/*
533 * These functions should take struct udevice instead of struct blk_desc,
534 * but this is convenient for migration to driver model. Add a 'd' prefix
535 * to the function operations, so that blk_read(), etc. can be reserved for
536 * functions with the correct arguments.
537 */
538static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start,
539 lbaint_t blkcnt, void *buffer)
540{
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700541 ulong blks_read;
Simon Glassfada3f92022-09-17 09:00:09 -0600542 if (blkcache_read(block_dev->uclass_id, block_dev->devnum,
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700543 start, blkcnt, block_dev->blksz, buffer))
544 return blkcnt;
545
Simon Glass2ee8ada2016-02-29 15:25:52 -0700546 /*
547 * We could check if block_read is NULL and return -ENOSYS. But this
548 * bloats the code slightly (cause some board to fail to build), and
549 * it would be an error to try an operation that does not exist.
550 */
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700551 blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer);
552 if (blks_read == blkcnt)
Simon Glassfada3f92022-09-17 09:00:09 -0600553 blkcache_fill(block_dev->uclass_id, block_dev->devnum,
Eric Nelsonfaf4f052016-03-28 10:05:44 -0700554 start, blkcnt, block_dev->blksz, buffer);
555
556 return blks_read;
Simon Glass2ee8ada2016-02-29 15:25:52 -0700557}
558
559static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
560 lbaint_t blkcnt, const void *buffer)
561{
Simon Glassfada3f92022-09-17 09:00:09 -0600562 blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
Simon Glass2ee8ada2016-02-29 15:25:52 -0700563 return block_dev->block_write(block_dev, start, blkcnt, buffer);
564}
565
566static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
567 lbaint_t blkcnt)
568{
Simon Glassfada3f92022-09-17 09:00:09 -0600569 blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
Simon Glass2ee8ada2016-02-29 15:25:52 -0700570 return block_dev->block_erase(block_dev, start, blkcnt);
571}
Simon Glass3bf2ab92016-05-01 11:36:03 -0600572
573/**
574 * struct blk_driver - Driver for block interface types
575 *
576 * This provides access to the block devices for each interface type. One
577 * driver should be provided using U_BOOT_LEGACY_BLK() for each interface
578 * type that is to be supported.
579 *
Simon Glassfada3f92022-09-17 09:00:09 -0600580 * @uclass_idname: Interface type name
581 * @uclass_id: Interface type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600582 * @max_devs: Maximum number of devices supported
583 * @desc: Pointer to list of devices for this interface type,
584 * or NULL to use @get_dev() instead
585 */
586struct blk_driver {
Simon Glassfada3f92022-09-17 09:00:09 -0600587 const char *uclass_idname;
588 enum uclass_id uclass_id;
Simon Glass3bf2ab92016-05-01 11:36:03 -0600589 int max_devs;
590 struct blk_desc *desc;
591 /**
592 * get_dev() - get a pointer to a block device given its number
593 *
594 * Each interface allocates its own devices and typically
595 * struct blk_desc is contained with the interface's data structure.
596 * There is no global numbering for block devices. This method allows
597 * the device for an interface type to be obtained when @desc is NULL.
598 *
599 * @devnum: Device number (0 for first device on that interface,
600 * 1 for second, etc.
601 * @descp: Returns pointer to the block device on success
602 * @return 0 if OK, -ve on error
603 */
604 int (*get_dev)(int devnum, struct blk_desc **descp);
605
606 /**
607 * select_hwpart() - Select a hardware partition
608 *
609 * Some devices (e.g. MMC) can support partitioning at the hardware
610 * level. This is quite separate from the normal idea of
611 * software-based partitions. MMC hardware partitions must be
612 * explicitly selected. Once selected only the region of the device
613 * covered by that partition is accessible.
614 *
615 * The MMC standard provides for two boot partitions (numbered 1 and 2),
616 * rpmb (3), and up to 4 addition general-purpose partitions (4-7).
617 * Partition 0 is the main user-data partition.
618 *
619 * @desc: Block device descriptor
620 * @hwpart: Hardware partition number to select. 0 means the main
621 * user-data partition, 1 is the first partition, 2 is
622 * the second, etc.
623 * @return 0 if OK, other value for an error
624 */
625 int (*select_hwpart)(struct blk_desc *desc, int hwpart);
626};
627
628/*
629 * Declare a new U-Boot legacy block driver. New drivers should use driver
630 * model (UCLASS_BLK).
631 */
632#define U_BOOT_LEGACY_BLK(__name) \
633 ll_entry_declare(struct blk_driver, __name, blk_driver)
634
Simon Glassfada3f92022-09-17 09:00:09 -0600635struct blk_driver *blk_driver_lookup_type(int uclass_id);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600636
Simon Glasscceee552016-02-29 15:25:55 -0700637#endif /* !CONFIG_BLK */
Simon Glass2ee8ada2016-02-29 15:25:52 -0700638
Simon Glass3bf2ab92016-05-01 11:36:03 -0600639/**
Simon Glassfada3f92022-09-17 09:00:09 -0600640 * blk_get_devnum_by_uclass_idname() - Get a block device by type and number
Simon Glass3bf2ab92016-05-01 11:36:03 -0600641 *
642 * This looks through the available block devices of the given type, returning
643 * the one with the given @devnum.
644 *
Simon Glassfada3f92022-09-17 09:00:09 -0600645 * @uclass_id: Block device type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600646 * @devnum: Device number
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100647 * Return: point to block device descriptor, or NULL if not found
Simon Glass3bf2ab92016-05-01 11:36:03 -0600648 */
Simon Glassfada3f92022-09-17 09:00:09 -0600649struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600650
651/**
Simon Glassfada3f92022-09-17 09:00:09 -0600652 * blk_get_devnum_by_uclass_id() - Get a block device by type name, and number
Simon Glass3bf2ab92016-05-01 11:36:03 -0600653 *
Simon Glassfada3f92022-09-17 09:00:09 -0600654 * This looks up the block device type based on @uclass_idname, then calls
655 * blk_get_devnum_by_uclass_id().
Simon Glass3bf2ab92016-05-01 11:36:03 -0600656 *
Simon Glassfada3f92022-09-17 09:00:09 -0600657 * @uclass_idname: Block device type name
Simon Glass3bf2ab92016-05-01 11:36:03 -0600658 * @devnum: Device number
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100659 * Return: point to block device descriptor, or NULL if not found
Simon Glass3bf2ab92016-05-01 11:36:03 -0600660 */
Simon Glassfada3f92022-09-17 09:00:09 -0600661struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname,
Simon Glass3bf2ab92016-05-01 11:36:03 -0600662 int devnum);
663
664/**
665 * blk_dselect_hwpart() - select a hardware partition
666 *
667 * This selects a hardware partition (such as is supported by MMC). The block
668 * device size may change as this effectively points the block device to a
669 * partition at the hardware level. See the select_hwpart() method above.
670 *
671 * @desc: Block device descriptor for the device to select
672 * @hwpart: Partition number to select
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100673 * Return: 0 if OK, -ve on error
Simon Glass3bf2ab92016-05-01 11:36:03 -0600674 */
675int blk_dselect_hwpart(struct blk_desc *desc, int hwpart);
676
677/**
678 * blk_list_part() - list the partitions for block devices of a given type
679 *
Simon Glassfada3f92022-09-17 09:00:09 -0600680 * This looks up the partition type for each block device of type @uclass_id,
Simon Glass3bf2ab92016-05-01 11:36:03 -0600681 * then displays a list of partitions.
682 *
Simon Glassfada3f92022-09-17 09:00:09 -0600683 * @uclass_id: Block device type
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100684 * Return: 0 if OK, -ENODEV if there is none of that type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600685 */
Simon Glassfada3f92022-09-17 09:00:09 -0600686int blk_list_part(enum uclass_id uclass_id);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600687
688/**
689 * blk_list_devices() - list the block devices of a given type
690 *
Simon Glassfada3f92022-09-17 09:00:09 -0600691 * This lists each block device of the type @uclass_id, showing the capacity
Simon Glass3bf2ab92016-05-01 11:36:03 -0600692 * as well as type-specific information.
693 *
Simon Glassfada3f92022-09-17 09:00:09 -0600694 * @uclass_id: Block device type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600695 */
Simon Glassfada3f92022-09-17 09:00:09 -0600696void blk_list_devices(enum uclass_id uclass_id);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600697
698/**
699 * blk_show_device() - show information about a given block device
700 *
701 * This shows the block device capacity as well as type-specific information.
702 *
Simon Glassfada3f92022-09-17 09:00:09 -0600703 * @uclass_id: Block device type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600704 * @devnum: Device number
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100705 * Return: 0 if OK, -ENODEV for invalid device number
Simon Glass3bf2ab92016-05-01 11:36:03 -0600706 */
Simon Glassfada3f92022-09-17 09:00:09 -0600707int blk_show_device(enum uclass_id uclass_id, int devnum);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600708
709/**
710 * blk_print_device_num() - show information about a given block device
711 *
712 * This is similar to blk_show_device() but returns an error if the block
713 * device type is unknown.
714 *
Simon Glassfada3f92022-09-17 09:00:09 -0600715 * @uclass_id: Block device type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600716 * @devnum: Device number
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100717 * Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
Simon Glass3bf2ab92016-05-01 11:36:03 -0600718 * device is not connected
719 */
Simon Glassfada3f92022-09-17 09:00:09 -0600720int blk_print_device_num(enum uclass_id uclass_id, int devnum);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600721
722/**
723 * blk_print_part_devnum() - print the partition information for a device
724 *
Simon Glassfada3f92022-09-17 09:00:09 -0600725 * @uclass_id: Block device type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600726 * @devnum: Device number
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100727 * Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
Simon Glass3bf2ab92016-05-01 11:36:03 -0600728 * the interface type is not supported, other -ve on other error
729 */
Simon Glassfada3f92022-09-17 09:00:09 -0600730int blk_print_part_devnum(enum uclass_id uclass_id, int devnum);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600731
732/**
Simon Glass3bf2ab92016-05-01 11:36:03 -0600733 * blk_select_hwpart_devnum() - select a hardware partition
734 *
735 * This is similar to blk_dselect_hwpart() but it looks up the interface and
736 * device number.
737 *
Simon Glassfada3f92022-09-17 09:00:09 -0600738 * @uclass_id: Block device type
Simon Glass3bf2ab92016-05-01 11:36:03 -0600739 * @devnum: Device number
740 * @hwpart: Partition number to select
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100741 * Return: 0 if OK, -ve on error
Simon Glass3bf2ab92016-05-01 11:36:03 -0600742 */
Simon Glassfada3f92022-09-17 09:00:09 -0600743int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart);
Simon Glass3bf2ab92016-05-01 11:36:03 -0600744
Simon Glass85af5a42017-07-29 11:34:53 -0600745/**
Simon Glassfada3f92022-09-17 09:00:09 -0600746 * blk_get_uclass_name() - Get the name of an interface type
Simon Glass85af5a42017-07-29 11:34:53 -0600747 *
Simon Glassfada3f92022-09-17 09:00:09 -0600748 * @uclass_id: Interface type to check
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100749 * Return: name of interface, or NULL if none
Simon Glass85af5a42017-07-29 11:34:53 -0600750 */
Simon Glassfada3f92022-09-17 09:00:09 -0600751const char *blk_get_uclass_name(enum uclass_id uclass_id);
Simon Glass85af5a42017-07-29 11:34:53 -0600752
Simon Glassbf2e7952017-07-29 11:34:54 -0600753/**
754 * blk_common_cmd() - handle common commands with block devices
755 *
756 * @args: Number of arguments to the command (argv[0] is the command itself)
757 * @argv: Command arguments
Simon Glassfada3f92022-09-17 09:00:09 -0600758 * @uclass_id: Interface type
Simon Glassbf2e7952017-07-29 11:34:54 -0600759 * @cur_devnump: Current device number for this interface type
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100760 * Return: 0 if OK, CMD_RET_ERROR on error
Simon Glassbf2e7952017-07-29 11:34:54 -0600761 */
Simon Glassfada3f92022-09-17 09:00:09 -0600762int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
Simon Glassbf2e7952017-07-29 11:34:54 -0600763 int *cur_devnump);
764
Simon Glassfc7a7442021-07-05 16:32:59 -0600765enum blk_flag_t {
766 BLKF_FIXED = 1 << 0,
767 BLKF_REMOVABLE = 1 << 1,
768 BLKF_BOTH = BLKF_FIXED | BLKF_REMOVABLE,
769};
770
771/**
772 * blk_first_device_err() - Get the first block device
773 *
774 * The device returned is probed if necessary, and ready for use
775 *
776 * @flags: Indicates type of device to return
777 * @devp: Returns pointer to the first device in that uclass, or NULL if none
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100778 * Return: 0 if found, -ENODEV if not found, other -ve on error
Simon Glassfc7a7442021-07-05 16:32:59 -0600779 */
780int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp);
781
782/**
783 * blk_next_device_err() - Get the next block device
784 *
785 * The device returned is probed if necessary, and ready for use
786 *
787 * @flags: Indicates type of device to return
788 * @devp: On entry, pointer to device to lookup. On exit, returns pointer
789 * to the next device in the uclass if no error occurred, or -ENODEV if
790 * there is no next device.
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100791 * Return: 0 if found, -ENODEV if not found, other -ve on error
Simon Glassfc7a7442021-07-05 16:32:59 -0600792 */
793int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp);
794
795/**
Simon Glass8e61f932022-02-28 12:08:35 -0700796 * blk_find_first() - Return the first matching block device
797 * @flags: Indicates type of device to return
798 * @devp: Returns pointer to device, or NULL on error
799 *
800 * The device is not prepared for use - this is an internal function.
801 * The function uclass_get_device_tail() can be used to probe the device.
802 *
803 * Note that some devices are considered removable until they have been probed
804 *
805 * @return 0 if found, -ENODEV if not found
806 */
807int blk_find_first(enum blk_flag_t flags, struct udevice **devp);
808
809/**
810 * blk_find_next() - Return the next matching block device
811 * @flags: Indicates type of device to return
812 * @devp: On entry, pointer to device to lookup. On exit, returns pointer
813 * to the next device in the same uclass, or NULL if none
814 *
815 * The device is not prepared for use - this is an internal function.
816 * The function uclass_get_device_tail() can be used to probe the device.
817 *
818 * Note that some devices are considered removable until they have been probed
819 *
820 * @return 0 if found, -ENODEV if not found
821 */
822int blk_find_next(enum blk_flag_t flags, struct udevice **devp);
823
824/**
825 * blk_foreach() - iterate through block devices
826 *
827 * This creates a for() loop which works through the available block devices in
828 * order from start to end.
829 *
830 * If for some reason the uclass cannot be found, this does nothing.
831 *
832 * @_flags: Indicates type of device to return
833 * @_pos: struct udevice * to hold the current device. Set to NULL when there
834 * are no more devices.
835 */
836#define blk_foreach(_flags, _pos) \
837 for (int _ret = blk_find_first(_flags, &_pos); !_ret && _pos; \
838 _ret = blk_find_next(_flags, &_pos))
839
840/**
Simon Glassfc7a7442021-07-05 16:32:59 -0600841 * blk_foreach_probe() - Helper function to iteration through block devices
842 *
843 * This creates a for() loop which works through the available devices in
844 * a uclass in order from start to end. Devices are probed if necessary,
845 * and ready for use.
846 *
847 * @flags: Indicates type of device to return
848 * @dev: struct udevice * to hold the current device. Set to NULL when there
849 * are no more devices.
850 */
851#define blk_foreach_probe(flags, pos) \
852 for (int _ret = blk_first_device_err(flags, &(pos)); \
853 !_ret && pos; \
854 _ret = blk_next_device_err(flags, &(pos)))
855
856/**
857 * blk_count_devices() - count the number of devices of a particular type
858 *
859 * @flags: Indicates type of device to find
Heinrich Schuchardt47b4c022022-01-19 18:05:50 +0100860 * Return: number of devices matching those flags
Simon Glassfc7a7442021-07-05 16:32:59 -0600861 */
862int blk_count_devices(enum blk_flag_t flag);
863
Simon Glassac8162f2016-02-29 15:25:39 -0700864#endif