Blame view
api/api_storage.c
8.14 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
500856eb1 API for external ... |
2 |
/* |
f2302d443 Fix merge problems |
3 |
* (C) Copyright 2007-2008 Semihalf |
500856eb1 API for external ... |
4 5 |
* * Written by: Rafal Jaworowski <raj@semihalf.com> |
500856eb1 API for external ... |
6 7 8 |
*/ #include <config.h> |
500856eb1 API for external ... |
9 10 |
#include <common.h> #include <api_public.h> |
3d0ea3110 api: Fix building... |
11 12 13 |
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) #include <usb.h> #endif |
500856eb1 API for external ... |
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
#define DEBUG #undef DEBUG #ifdef DEBUG #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0) #else #define debugf(fmt, args...) #endif #define errf(fmt, args...) do { printf("ERROR @ %s(): ", __func__); printf(fmt, ##args); } while (0) #define ENUM_IDE 0 #define ENUM_USB 1 #define ENUM_SCSI 2 #define ENUM_MMC 3 |
f2302d443 Fix merge problems |
30 31 |
#define ENUM_SATA 4 #define ENUM_MAX 5 |
500856eb1 API for external ... |
32 33 34 35 36 |
struct stor_spec { int max_dev; int enum_started; int enum_ended; |
e3d7675ac Cosmetic api: api... |
37 |
int type; /* "external" type: DT_STOR_{IDE,USB,etc} */ |
f2302d443 Fix merge problems |
38 |
char *name; |
500856eb1 API for external ... |
39 |
}; |
5d81c6df3 api: storage: Avo... |
40 |
static struct stor_spec specs[ENUM_MAX] = { { 0, 0, 0, 0, NULL }, }; |
500856eb1 API for external ... |
41 |
|
6d7a57076 api: Define a def... |
42 43 44 |
#ifndef CONFIG_SYS_MMC_MAX_DEVICE #define CONFIG_SYS_MMC_MAX_DEVICE 1 #endif |
500856eb1 API for external ... |
45 46 47 |
void dev_stor_init(void) { |
fc843a02a Kconfig: Add a CO... |
48 |
#if defined(CONFIG_IDE) |
6d0f6bcf3 rename CFG_ macro... |
49 |
specs[ENUM_IDE].max_dev = CONFIG_SYS_IDE_MAXDEVICE; |
500856eb1 API for external ... |
50 51 52 53 54 |
specs[ENUM_IDE].enum_started = 0; specs[ENUM_IDE].enum_ended = 0; specs[ENUM_IDE].type = DEV_TYP_STOR | DT_STOR_IDE; specs[ENUM_IDE].name = "ide"; #endif |
f2302d443 Fix merge problems |
55 |
#if defined(CONFIG_CMD_MMC) |
6d0f6bcf3 rename CFG_ macro... |
56 |
specs[ENUM_MMC].max_dev = CONFIG_SYS_MMC_MAX_DEVICE; |
f2302d443 Fix merge problems |
57 58 59 60 61 |
specs[ENUM_MMC].enum_started = 0; specs[ENUM_MMC].enum_ended = 0; specs[ENUM_MMC].type = DEV_TYP_STOR | DT_STOR_MMC; specs[ENUM_MMC].name = "mmc"; #endif |
10e40d54b Kconfig: Add CONF... |
62 |
#if defined(CONFIG_SATA) |
6d0f6bcf3 rename CFG_ macro... |
63 |
specs[ENUM_SATA].max_dev = CONFIG_SYS_SATA_MAX_DEVICE; |
f2302d443 Fix merge problems |
64 65 66 67 |
specs[ENUM_SATA].enum_started = 0; specs[ENUM_SATA].enum_ended = 0; specs[ENUM_SATA].type = DEV_TYP_STOR | DT_STOR_SATA; specs[ENUM_SATA].name = "sata"; |
500856eb1 API for external ... |
68 |
#endif |
c649e3c91 dm: scsi: Rename ... |
69 |
#if defined(CONFIG_SCSI) |
6d0f6bcf3 rename CFG_ macro... |
70 |
specs[ENUM_SCSI].max_dev = CONFIG_SYS_SCSI_MAX_DEVICE; |
500856eb1 API for external ... |
71 72 73 74 75 |
specs[ENUM_SCSI].enum_started = 0; specs[ENUM_SCSI].enum_ended = 0; specs[ENUM_SCSI].type = DEV_TYP_STOR | DT_STOR_SCSI; specs[ENUM_SCSI].name = "scsi"; #endif |
f2302d443 Fix merge problems |
76 77 78 79 80 81 82 |
#if defined(CONFIG_CMD_USB) && defined(CONFIG_USB_STORAGE) specs[ENUM_USB].max_dev = USB_MAX_STOR_DEV; specs[ENUM_USB].enum_started = 0; specs[ENUM_USB].enum_ended = 0; specs[ENUM_USB].type = DEV_TYP_STOR | DT_STOR_USB; specs[ENUM_USB].name = "usb"; #endif |
500856eb1 API for external ... |
83 84 85 86 87 88 89 |
} /* * Finds next available device in the storage group * * type: storage group type - ENUM_IDE, ENUM_SCSI etc. * |
500856eb1 API for external ... |
90 91 92 93 94 |
* more: returns 0/1 depending if there are more devices in this group * available (for future iterations) * * returns: 0/1 depending if device found in this iteration */ |
d3e8f6302 api: storage: Tes... |
95 |
static int dev_stor_get(int type, int *more, struct device_info *di) |
500856eb1 API for external ... |
96 |
{ |
4101f6879 dm: Drop the bloc... |
97 |
struct blk_desc *dd; |
d3e8f6302 api: storage: Tes... |
98 |
int found = 0; |
8efae021d api: storage: Fix... |
99 |
int found_last = 0; |
d3e8f6302 api: storage: Tes... |
100 |
int i = 0; |
500856eb1 API for external ... |
101 |
|
5d81c6df3 api: storage: Avo... |
102 103 104 |
/* Wasn't configured for this type, return 0 directly */ if (specs[type].name == NULL) return 0; |
d3e8f6302 api: storage: Tes... |
105 106 107 |
if (di->cookie != NULL) { /* Find the last device we've returned */ for (i = 0; i < specs[type].max_dev; i++) { |
db1d9e78e dm: blk: Rename g... |
108 109 |
if (di->cookie == (void *)blk_get_dev(specs[type].name, i)) { |
d3e8f6302 api: storage: Tes... |
110 |
i += 1; |
8efae021d api: storage: Fix... |
111 |
found_last = 1; |
500856eb1 API for external ... |
112 113 |
break; } |
d3e8f6302 api: storage: Tes... |
114 |
} |
8efae021d api: storage: Fix... |
115 116 117 |
if (!found_last) i = 0; |
500856eb1 API for external ... |
118 |
} |
d3e8f6302 api: storage: Tes... |
119 120 |
for (; i < specs[type].max_dev; i++) { di->cookie = (void *)blk_get_dev(specs[type].name, i); |
500856eb1 API for external ... |
121 122 |
if (di->cookie != NULL) { |
d3e8f6302 api: storage: Tes... |
123 124 |
found = 1; break; |
500856eb1 API for external ... |
125 |
} |
d3e8f6302 api: storage: Tes... |
126 127 128 129 130 131 |
} if (i == specs[type].max_dev) *more = 0; else *more = 1; |
500856eb1 API for external ... |
132 |
|
d3e8f6302 api: storage: Tes... |
133 134 135 136 137 138 139 140 141 142 143 144 |
if (found) { di->type = specs[type].type; dd = (struct blk_desc *)di->cookie; if (dd->type == DEV_TYPE_UNKNOWN) { debugf("device instance exists, but is not active.."); found = 0; } else { di->di_stor.block_count = dd->lba; di->di_stor.block_size = dd->blksz; } } else { |
500856eb1 API for external ... |
145 |
di->cookie = NULL; |
d3e8f6302 api: storage: Tes... |
146 |
} |
500856eb1 API for external ... |
147 148 149 |
return found; } |
c9db75a06 Cosmetic api: api... |
150 |
/* returns: ENUM_IDE, ENUM_USB etc. based on struct blk_desc */ |
4101f6879 dm: Drop the bloc... |
151 |
static int dev_stor_type(struct blk_desc *dd) |
500856eb1 API for external ... |
152 153 154 155 156 |
{ int i, j; for (i = ENUM_IDE; i < ENUM_MAX; i++) for (j = 0; j < specs[i].max_dev; j++) |
db1d9e78e dm: blk: Rename g... |
157 |
if (dd == blk_get_dev(specs[i].name, j)) |
500856eb1 API for external ... |
158 159 160 161 |
return i; return ENUM_MAX; } |
c9db75a06 Cosmetic api: api... |
162 |
/* returns: 0/1 whether cookie points to some device in this group */ |
500856eb1 API for external ... |
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
static int dev_is_stor(int type, struct device_info *di) { return (dev_stor_type(di->cookie) == type) ? 1 : 0; } static int dev_enum_stor(int type, struct device_info *di) { int found = 0, more = 0; debugf("called, type %d ", type); /* * Formulae for enumerating storage devices: * 1. if cookie (hint from previous enum call) is NULL we start again * with enumeration, so return the first available device, done. * * 2. if cookie is not NULL, check if it identifies some device in * this group: * * 2a. if cookie is a storage device from our group (IDE, USB etc.), * return next available (if exists) in this group * * 2b. if it isn't device from our group, check if such devices were * ever enumerated before: * - if not, return the first available device from this group * - else return 0 */ if (di->cookie == NULL) { |
500856eb1 API for external ... |
194 195 196 197 198 199 200 |
debugf("group%d - enum restart ", type); /* * 1. Enumeration (re-)started: take the first available * device, if exists */ |
d3e8f6302 api: storage: Tes... |
201 |
found = dev_stor_get(type, &more, di); |
500856eb1 API for external ... |
202 203 204 |
specs[type].enum_started = 1; } else if (dev_is_stor(type, di)) { |
500856eb1 API for external ... |
205 206 207 208 209 210 211 212 213 214 |
debugf("group%d - enum continued for the next device ", type); if (specs[type].enum_ended) { debugf("group%d - nothing more to enum! ", type); return 0; } /* 2a. Attempt to take a next available device in the group */ |
d3e8f6302 api: storage: Tes... |
215 |
found = dev_stor_get(type, &more, di); |
500856eb1 API for external ... |
216 217 |
} else { |
500856eb1 API for external ... |
218 219 220 221 222 223 224 225 226 227 228 229 230 |
if (specs[type].enum_ended) { debugf("group %d - already enumerated, skipping ", type); return 0; } debugf("group%d - first time enum ", type); if (specs[type].enum_started == 0) { /* * 2b. If enumerating devices in this group did not * happen before, it means the cookie pointed to a |
83f9ecbe2 Cosmetic api: api... |
231 |
* device from some other group (another storage |
500856eb1 API for external ... |
232 233 234 235 236 237 238 239 240 |
* group, or network); in this case try to take the * first available device from our group */ specs[type].enum_started = 1; /* * Attempt to take the first device in this group: *'first element' flag is set */ |
d3e8f6302 api: storage: Tes... |
241 |
found = dev_stor_get(type, &more, di); |
500856eb1 API for external ... |
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
} else { errf("group%d - out of order iteration ", type); found = 0; more = 0; } } /* * If there are no more devices in this group, consider its * enumeration finished */ specs[type].enum_ended = (!more) ? 1 : 0; if (found) debugf("device found, returning cookie 0x%08x ", |
e5fbf2a73 Cosmetic api: api... |
260 |
(u_int32_t)di->cookie); |
500856eb1 API for external ... |
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 |
else debugf("no device found "); return found; } void dev_enum_reset(void) { int i; for (i = 0; i < ENUM_MAX; i ++) { specs[i].enum_started = 0; specs[i].enum_ended = 0; } } int dev_enum_storage(struct device_info *di) { int i; |
c9db75a06 Cosmetic api: api... |
281 |
/* check: ide, usb, scsi, mmc */ |
500856eb1 API for external ... |
282 283 284 285 286 287 288 |
for (i = ENUM_IDE; i < ENUM_MAX; i ++) { if (dev_enum_stor(i, di)) return 1; } return 0; } |
4101f6879 dm: Drop the bloc... |
289 |
static int dev_stor_is_valid(int type, struct blk_desc *dd) |
500856eb1 API for external ... |
290 291 292 293 |
{ int i; for (i = 0; i < specs[type].max_dev; i++) |
db1d9e78e dm: blk: Rename g... |
294 |
if (dd == blk_get_dev(specs[type].name, i)) |
500856eb1 API for external ... |
295 296 297 298 299 300 301 302 303 304 305 306 307 |
if (dd->type != DEV_TYPE_UNKNOWN) return 1; return 0; } int dev_open_stor(void *cookie) { int type = dev_stor_type(cookie); if (type == ENUM_MAX) return API_ENODEV; |
4101f6879 dm: Drop the bloc... |
308 |
if (dev_stor_is_valid(type, (struct blk_desc *)cookie)) |
500856eb1 API for external ... |
309 310 311 312 313 314 315 316 317 318 319 320 321 322 |
return 0; return API_ENODEV; } int dev_close_stor(void *cookie) { /* * Not much to do as we actually do not alter storage devices upon * close */ return 0; } |
500856eb1 API for external ... |
323 324 325 |
lbasize_t dev_read_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start) { int type; |
4101f6879 dm: Drop the bloc... |
326 |
struct blk_desc *dd = (struct blk_desc *)cookie; |
500856eb1 API for external ... |
327 328 329 330 331 332 |
if ((type = dev_stor_type(dd)) == ENUM_MAX) return 0; if (!dev_stor_is_valid(type, dd)) return 0; |
f2288c5a5 Apparent conflict... |
333 334 335 |
#ifdef CONFIG_BLK return blk_dread(dd, start, len, buf); #else |
500856eb1 API for external ... |
336 |
if ((dd->block_read) == NULL) { |
f2302d443 Fix merge problems |
337 338 |
debugf("no block_read() for device 0x%08x ", cookie); |
500856eb1 API for external ... |
339 340 |
return 0; } |
7c4213f6a block: pass block... |
341 |
return dd->block_read(dd, start, len, buf); |
f2288c5a5 Apparent conflict... |
342 |
#endif /* defined(CONFIG_BLK) */ |
500856eb1 API for external ... |
343 |
} |
036218a67 api: storage: Add... |
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
lbasize_t dev_write_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start) { struct blk_desc *dd = (struct blk_desc *)cookie; int type = dev_stor_type(dd); if (type == ENUM_MAX) return 0; if (!dev_stor_is_valid(type, dd)) return 0; #ifdef CONFIG_BLK return blk_dwrite(dd, start, len, buf); #else if (dd->block_write == NULL) { debugf("no block_write() for device 0x%08x ", cookie); return 0; } return dd->block_write(dd, start, len, buf); #endif /* defined(CONFIG_BLK) */ } |