1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef BLK_H
#define BLK_H
#ifdef CONFIG_SYS_64BIT_LBA
typedef uint64_t lbaint_t;
#define LBAFlength "ll"
#else
typedef ulong lbaint_t;
#define LBAFlength "l"
#endif
#define LBAF "%" LBAFlength "x"
#define LBAFU "%" LBAFlength "u"
/* Interface types: */
enum if_type {
IF_TYPE_UNKNOWN = 0,
IF_TYPE_IDE,
IF_TYPE_SCSI,
IF_TYPE_ATAPI,
IF_TYPE_USB,
IF_TYPE_DOC,
IF_TYPE_MMC,
IF_TYPE_SD,
IF_TYPE_SATA,
IF_TYPE_HOST,
IF_TYPE_COUNT, /* Number of interface types */
};
struct blk_desc {
enum if_type if_type; /* type of the interface */
int devnum; /* device number */
unsigned char part_type; /* partition type */
unsigned char target; /* target SCSI ID */
unsigned char lun; /* target LUN */
unsigned char hwpart; /* HW partition, e.g. for eMMC */
unsigned char type; /* device type */
unsigned char removable; /* removable device */
#ifdef CONFIG_LBA48
/* device can use 48bit addr (ATA/ATAPI v7) */
unsigned char lba48;
#endif
lbaint_t lba; /* number of blocks */
unsigned long blksz; /* block size */
int log2blksz; /* for convenience: log2(blksz) */
char vendor[40+1]; /* IDE model, SCSI Vendor */
char product[20+1]; /* IDE Serial no, SCSI product */
char revision[8+1]; /* firmware revision */
unsigned long (*block_read)(struct blk_desc *block_dev,
lbaint_t start,
lbaint_t blkcnt,
void *buffer);
unsigned long (*block_write)(struct blk_desc *block_dev,
lbaint_t start,
lbaint_t blkcnt,
const void *buffer);
unsigned long (*block_erase)(struct blk_desc *block_dev,
lbaint_t start,
lbaint_t blkcnt);
void *priv; /* driver private struct pointer */
};
#define BLOCK_CNT(size, blk_desc) (PAD_COUNT(size, blk_desc->blksz))
#define PAD_TO_BLOCKSIZE(size, blk_desc) \
(PAD_SIZE(size, blk_desc->blksz))
/*
* These functions should take struct udevice instead of struct blk_desc,
* but this is convenient for migration to driver model. Add a 'd' prefix
* to the function operations, so that blk_read(), etc. can be reserved for
* functions with the correct arguments.
*/
static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
/*
* We could check if block_read is NULL and return -ENOSYS. But this
* bloats the code slightly (cause some board to fail to build), and
* it would be an error to try an operation that does not exist.
*/
return block_dev->block_read(block_dev, start, blkcnt, buffer);
}
static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
return block_dev->block_write(block_dev, start, blkcnt, buffer);
}
static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt)
{
return block_dev->block_erase(block_dev, start, blkcnt);
}
#endif
|