blk-uclass.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Google, Inc
  4. * Written by Simon Glass <sjg@chromium.org>
  5. */
  6. #include <common.h>
  7. #include <blk.h>
  8. #include <dm.h>
  9. #include <dm/device-internal.h>
  10. #include <dm/lists.h>
  11. #include <dm/uclass-internal.h>
  12. #include <linux/err.h>
  13. static const char *if_typename_str[IF_TYPE_COUNT] = {
  14. [IF_TYPE_IDE] = "ide",
  15. [IF_TYPE_SCSI] = "scsi",
  16. [IF_TYPE_ATAPI] = "atapi",
  17. [IF_TYPE_USB] = "usb",
  18. [IF_TYPE_DOC] = "doc",
  19. [IF_TYPE_MMC] = "mmc",
  20. [IF_TYPE_SD] = "sd",
  21. [IF_TYPE_SATA] = "sata",
  22. [IF_TYPE_HOST] = "host",
  23. [IF_TYPE_NVME] = "nvme",
  24. [IF_TYPE_EFI] = "efi",
  25. [IF_TYPE_VIRTIO] = "virtio",
  26. };
  27. static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
  28. [IF_TYPE_IDE] = UCLASS_IDE,
  29. [IF_TYPE_SCSI] = UCLASS_SCSI,
  30. [IF_TYPE_ATAPI] = UCLASS_INVALID,
  31. [IF_TYPE_USB] = UCLASS_MASS_STORAGE,
  32. [IF_TYPE_DOC] = UCLASS_INVALID,
  33. [IF_TYPE_MMC] = UCLASS_MMC,
  34. [IF_TYPE_SD] = UCLASS_INVALID,
  35. [IF_TYPE_SATA] = UCLASS_AHCI,
  36. [IF_TYPE_HOST] = UCLASS_ROOT,
  37. [IF_TYPE_NVME] = UCLASS_NVME,
  38. [IF_TYPE_EFI] = UCLASS_EFI,
  39. [IF_TYPE_VIRTIO] = UCLASS_VIRTIO,
  40. };
  41. static enum if_type if_typename_to_iftype(const char *if_typename)
  42. {
  43. int i;
  44. for (i = 0; i < IF_TYPE_COUNT; i++) {
  45. if (if_typename_str[i] &&
  46. !strcmp(if_typename, if_typename_str[i]))
  47. return i;
  48. }
  49. return IF_TYPE_UNKNOWN;
  50. }
  51. static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
  52. {
  53. return if_type_uclass_id[if_type];
  54. }
  55. const char *blk_get_if_type_name(enum if_type if_type)
  56. {
  57. return if_typename_str[if_type];
  58. }
  59. struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
  60. {
  61. struct blk_desc *desc;
  62. struct udevice *dev;
  63. int ret;
  64. ret = blk_get_device(if_type, devnum, &dev);
  65. if (ret)
  66. return NULL;
  67. desc = dev_get_uclass_platdata(dev);
  68. return desc;
  69. }
  70. /*
  71. * This function is complicated with driver model. We look up the interface
  72. * name in a local table. This gives us an interface type which we can match
  73. * against the uclass of the block device's parent.
  74. */
  75. struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
  76. {
  77. enum uclass_id uclass_id;
  78. enum if_type if_type;
  79. struct udevice *dev;
  80. struct uclass *uc;
  81. int ret;
  82. if_type = if_typename_to_iftype(if_typename);
  83. if (if_type == IF_TYPE_UNKNOWN) {
  84. debug("%s: Unknown interface type '%s'\n", __func__,
  85. if_typename);
  86. return NULL;
  87. }
  88. uclass_id = if_type_to_uclass_id(if_type);
  89. if (uclass_id == UCLASS_INVALID) {
  90. debug("%s: Unknown uclass for interface type'\n",
  91. if_typename_str[if_type]);
  92. return NULL;
  93. }
  94. ret = uclass_get(UCLASS_BLK, &uc);
  95. if (ret)
  96. return NULL;
  97. uclass_foreach_dev(dev, uc) {
  98. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  99. debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
  100. if_type, devnum, dev->name, desc->if_type, desc->devnum);
  101. if (desc->devnum != devnum)
  102. continue;
  103. /* Find out the parent device uclass */
  104. if (device_get_uclass_id(dev->parent) != uclass_id) {
  105. debug("%s: parent uclass %d, this dev %d\n", __func__,
  106. device_get_uclass_id(dev->parent), uclass_id);
  107. continue;
  108. }
  109. if (device_probe(dev))
  110. return NULL;
  111. debug("%s: Device desc %p\n", __func__, desc);
  112. return desc;
  113. }
  114. debug("%s: No device found\n", __func__);
  115. return NULL;
  116. }
  117. /**
  118. * blk_get_by_device() - Get the block device descriptor for the given device
  119. * @dev: Instance of a storage device
  120. *
  121. * Return: With block device descriptor on success , NULL if there is no such
  122. * block device.
  123. */
  124. struct blk_desc *blk_get_by_device(struct udevice *dev)
  125. {
  126. struct udevice *child_dev;
  127. device_foreach_child(child_dev, dev) {
  128. if (device_get_uclass_id(child_dev) != UCLASS_BLK)
  129. continue;
  130. return dev_get_uclass_platdata(child_dev);
  131. }
  132. debug("%s: No block device found\n", __func__);
  133. return NULL;
  134. }
  135. /**
  136. * get_desc() - Get the block device descriptor for the given device number
  137. *
  138. * @if_type: Interface type
  139. * @devnum: Device number (0 = first)
  140. * @descp: Returns block device descriptor on success
  141. * @return 0 on success, -ENODEV if there is no such device and no device
  142. * with a higher device number, -ENOENT if there is no such device but there
  143. * is one with a higher number, or other -ve on other error.
  144. */
  145. static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
  146. {
  147. bool found_more = false;
  148. struct udevice *dev;
  149. struct uclass *uc;
  150. int ret;
  151. *descp = NULL;
  152. ret = uclass_get(UCLASS_BLK, &uc);
  153. if (ret)
  154. return ret;
  155. uclass_foreach_dev(dev, uc) {
  156. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  157. debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
  158. if_type, devnum, dev->name, desc->if_type, desc->devnum);
  159. if (desc->if_type == if_type) {
  160. if (desc->devnum == devnum) {
  161. ret = device_probe(dev);
  162. if (ret)
  163. return ret;
  164. *descp = desc;
  165. return 0;
  166. } else if (desc->devnum > devnum) {
  167. found_more = true;
  168. }
  169. }
  170. }
  171. return found_more ? -ENOENT : -ENODEV;
  172. }
  173. int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
  174. {
  175. struct udevice *dev;
  176. int ret;
  177. ret = blk_get_device(if_type, devnum, &dev);
  178. if (ret)
  179. return ret;
  180. return blk_select_hwpart(dev, hwpart);
  181. }
  182. int blk_list_part(enum if_type if_type)
  183. {
  184. struct blk_desc *desc;
  185. int devnum, ok;
  186. int ret;
  187. for (ok = 0, devnum = 0;; ++devnum) {
  188. ret = get_desc(if_type, devnum, &desc);
  189. if (ret == -ENODEV)
  190. break;
  191. else if (ret)
  192. continue;
  193. if (desc->part_type != PART_TYPE_UNKNOWN) {
  194. ++ok;
  195. if (devnum)
  196. putc('\n');
  197. part_print(desc);
  198. }
  199. }
  200. if (!ok)
  201. return -ENODEV;
  202. return 0;
  203. }
  204. int blk_print_part_devnum(enum if_type if_type, int devnum)
  205. {
  206. struct blk_desc *desc;
  207. int ret;
  208. ret = get_desc(if_type, devnum, &desc);
  209. if (ret)
  210. return ret;
  211. if (desc->type == DEV_TYPE_UNKNOWN)
  212. return -ENOENT;
  213. part_print(desc);
  214. return 0;
  215. }
  216. void blk_list_devices(enum if_type if_type)
  217. {
  218. struct blk_desc *desc;
  219. int ret;
  220. int i;
  221. for (i = 0;; ++i) {
  222. ret = get_desc(if_type, i, &desc);
  223. if (ret == -ENODEV)
  224. break;
  225. else if (ret)
  226. continue;
  227. if (desc->type == DEV_TYPE_UNKNOWN)
  228. continue; /* list only known devices */
  229. printf("Device %d: ", i);
  230. dev_print(desc);
  231. }
  232. }
  233. int blk_print_device_num(enum if_type if_type, int devnum)
  234. {
  235. struct blk_desc *desc;
  236. int ret;
  237. ret = get_desc(if_type, devnum, &desc);
  238. if (ret)
  239. return ret;
  240. printf("\nIDE device %d: ", devnum);
  241. dev_print(desc);
  242. return 0;
  243. }
  244. int blk_show_device(enum if_type if_type, int devnum)
  245. {
  246. struct blk_desc *desc;
  247. int ret;
  248. printf("\nDevice %d: ", devnum);
  249. ret = get_desc(if_type, devnum, &desc);
  250. if (ret == -ENODEV || ret == -ENOENT) {
  251. printf("unknown device\n");
  252. return -ENODEV;
  253. }
  254. if (ret)
  255. return ret;
  256. dev_print(desc);
  257. if (desc->type == DEV_TYPE_UNKNOWN)
  258. return -ENOENT;
  259. return 0;
  260. }
  261. ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
  262. lbaint_t blkcnt, void *buffer)
  263. {
  264. struct blk_desc *desc;
  265. ulong n;
  266. int ret;
  267. ret = get_desc(if_type, devnum, &desc);
  268. if (ret)
  269. return ret;
  270. n = blk_dread(desc, start, blkcnt, buffer);
  271. if (IS_ERR_VALUE(n))
  272. return n;
  273. return n;
  274. }
  275. ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
  276. lbaint_t blkcnt, const void *buffer)
  277. {
  278. struct blk_desc *desc;
  279. int ret;
  280. ret = get_desc(if_type, devnum, &desc);
  281. if (ret)
  282. return ret;
  283. return blk_dwrite(desc, start, blkcnt, buffer);
  284. }
  285. int blk_select_hwpart(struct udevice *dev, int hwpart)
  286. {
  287. const struct blk_ops *ops = blk_get_ops(dev);
  288. if (!ops)
  289. return -ENOSYS;
  290. if (!ops->select_hwpart)
  291. return 0;
  292. return ops->select_hwpart(dev, hwpart);
  293. }
  294. int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
  295. {
  296. return blk_select_hwpart(desc->bdev, hwpart);
  297. }
  298. int blk_first_device(int if_type, struct udevice **devp)
  299. {
  300. struct blk_desc *desc;
  301. int ret;
  302. ret = uclass_find_first_device(UCLASS_BLK, devp);
  303. if (ret)
  304. return ret;
  305. if (!*devp)
  306. return -ENODEV;
  307. do {
  308. desc = dev_get_uclass_platdata(*devp);
  309. if (desc->if_type == if_type)
  310. return 0;
  311. ret = uclass_find_next_device(devp);
  312. if (ret)
  313. return ret;
  314. } while (*devp);
  315. return -ENODEV;
  316. }
  317. int blk_next_device(struct udevice **devp)
  318. {
  319. struct blk_desc *desc;
  320. int ret, if_type;
  321. desc = dev_get_uclass_platdata(*devp);
  322. if_type = desc->if_type;
  323. do {
  324. ret = uclass_find_next_device(devp);
  325. if (ret)
  326. return ret;
  327. if (!*devp)
  328. return -ENODEV;
  329. desc = dev_get_uclass_platdata(*devp);
  330. if (desc->if_type == if_type)
  331. return 0;
  332. } while (1);
  333. }
  334. int blk_find_device(int if_type, int devnum, struct udevice **devp)
  335. {
  336. struct uclass *uc;
  337. struct udevice *dev;
  338. int ret;
  339. ret = uclass_get(UCLASS_BLK, &uc);
  340. if (ret)
  341. return ret;
  342. uclass_foreach_dev(dev, uc) {
  343. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  344. debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
  345. if_type, devnum, dev->name, desc->if_type, desc->devnum);
  346. if (desc->if_type == if_type && desc->devnum == devnum) {
  347. *devp = dev;
  348. return 0;
  349. }
  350. }
  351. return -ENODEV;
  352. }
  353. int blk_get_device(int if_type, int devnum, struct udevice **devp)
  354. {
  355. int ret;
  356. ret = blk_find_device(if_type, devnum, devp);
  357. if (ret)
  358. return ret;
  359. return device_probe(*devp);
  360. }
  361. unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
  362. lbaint_t blkcnt, void *buffer)
  363. {
  364. struct udevice *dev = block_dev->bdev;
  365. const struct blk_ops *ops = blk_get_ops(dev);
  366. ulong blks_read;
  367. if (!ops->read)
  368. return -ENOSYS;
  369. if (blkcache_read(block_dev->if_type, block_dev->devnum,
  370. start, blkcnt, block_dev->blksz, buffer))
  371. return blkcnt;
  372. blks_read = ops->read(dev, start, blkcnt, buffer);
  373. if (blks_read == blkcnt)
  374. blkcache_fill(block_dev->if_type, block_dev->devnum,
  375. start, blkcnt, block_dev->blksz, buffer);
  376. return blks_read;
  377. }
  378. unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
  379. lbaint_t blkcnt, const void *buffer)
  380. {
  381. struct udevice *dev = block_dev->bdev;
  382. const struct blk_ops *ops = blk_get_ops(dev);
  383. if (!ops->write)
  384. return -ENOSYS;
  385. blkcache_invalidate(block_dev->if_type, block_dev->devnum);
  386. return ops->write(dev, start, blkcnt, buffer);
  387. }
  388. unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
  389. lbaint_t blkcnt)
  390. {
  391. struct udevice *dev = block_dev->bdev;
  392. const struct blk_ops *ops = blk_get_ops(dev);
  393. if (!ops->erase)
  394. return -ENOSYS;
  395. blkcache_invalidate(block_dev->if_type, block_dev->devnum);
  396. return ops->erase(dev, start, blkcnt);
  397. }
  398. int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
  399. {
  400. struct udevice *dev;
  401. enum uclass_id id;
  402. int ret;
  403. device_find_first_child(parent, &dev);
  404. if (!dev) {
  405. debug("%s: No block device found for parent '%s'\n", __func__,
  406. parent->name);
  407. return -ENODEV;
  408. }
  409. id = device_get_uclass_id(dev);
  410. if (id != UCLASS_BLK) {
  411. debug("%s: Incorrect uclass %s for block device '%s'\n",
  412. __func__, uclass_get_name(id), dev->name);
  413. return -ENOTBLK;
  414. }
  415. ret = device_probe(dev);
  416. if (ret)
  417. return ret;
  418. *devp = dev;
  419. return 0;
  420. }
  421. int blk_find_max_devnum(enum if_type if_type)
  422. {
  423. struct udevice *dev;
  424. int max_devnum = -ENODEV;
  425. struct uclass *uc;
  426. int ret;
  427. ret = uclass_get(UCLASS_BLK, &uc);
  428. if (ret)
  429. return ret;
  430. uclass_foreach_dev(dev, uc) {
  431. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  432. if (desc->if_type == if_type && desc->devnum > max_devnum)
  433. max_devnum = desc->devnum;
  434. }
  435. return max_devnum;
  436. }
  437. int blk_next_free_devnum(enum if_type if_type)
  438. {
  439. int ret;
  440. ret = blk_find_max_devnum(if_type);
  441. if (ret == -ENODEV)
  442. return 0;
  443. if (ret < 0)
  444. return ret;
  445. return ret + 1;
  446. }
  447. static int blk_claim_devnum(enum if_type if_type, int devnum)
  448. {
  449. struct udevice *dev;
  450. struct uclass *uc;
  451. int ret;
  452. ret = uclass_get(UCLASS_BLK, &uc);
  453. if (ret)
  454. return ret;
  455. uclass_foreach_dev(dev, uc) {
  456. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  457. if (desc->if_type == if_type && desc->devnum == devnum) {
  458. int next = blk_next_free_devnum(if_type);
  459. if (next < 0)
  460. return next;
  461. desc->devnum = next;
  462. return 0;
  463. }
  464. }
  465. return -ENOENT;
  466. }
  467. int blk_create_device(struct udevice *parent, const char *drv_name,
  468. const char *name, int if_type, int devnum, int blksz,
  469. lbaint_t lba, struct udevice **devp)
  470. {
  471. struct blk_desc *desc;
  472. struct udevice *dev;
  473. int ret;
  474. if (devnum == -1) {
  475. devnum = blk_next_free_devnum(if_type);
  476. } else {
  477. ret = blk_claim_devnum(if_type, devnum);
  478. if (ret < 0 && ret != -ENOENT)
  479. return ret;
  480. }
  481. if (devnum < 0)
  482. return devnum;
  483. ret = device_bind_driver(parent, drv_name, name, &dev);
  484. if (ret)
  485. return ret;
  486. desc = dev_get_uclass_platdata(dev);
  487. desc->if_type = if_type;
  488. desc->blksz = blksz;
  489. desc->log2blksz = LOG2(desc->blksz);
  490. desc->lba = lba;
  491. desc->part_type = PART_TYPE_UNKNOWN;
  492. desc->bdev = dev;
  493. desc->devnum = devnum;
  494. *devp = dev;
  495. return 0;
  496. }
  497. int blk_create_devicef(struct udevice *parent, const char *drv_name,
  498. const char *name, int if_type, int devnum, int blksz,
  499. lbaint_t lba, struct udevice **devp)
  500. {
  501. char dev_name[30], *str;
  502. int ret;
  503. snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
  504. str = strdup(dev_name);
  505. if (!str)
  506. return -ENOMEM;
  507. ret = blk_create_device(parent, drv_name, str, if_type, devnum,
  508. blksz, lba, devp);
  509. if (ret) {
  510. free(str);
  511. return ret;
  512. }
  513. device_set_name_alloced(*devp);
  514. return 0;
  515. }
  516. int blk_unbind_all(int if_type)
  517. {
  518. struct uclass *uc;
  519. struct udevice *dev, *next;
  520. int ret;
  521. ret = uclass_get(UCLASS_BLK, &uc);
  522. if (ret)
  523. return ret;
  524. uclass_foreach_dev_safe(dev, next, uc) {
  525. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  526. if (desc->if_type == if_type) {
  527. ret = device_remove(dev, DM_REMOVE_NORMAL);
  528. if (ret)
  529. return ret;
  530. ret = device_unbind(dev);
  531. if (ret)
  532. return ret;
  533. }
  534. }
  535. return 0;
  536. }
  537. static int blk_post_probe(struct udevice *dev)
  538. {
  539. #if defined(CONFIG_PARTITIONS) && defined(CONFIG_HAVE_BLOCK_DEVICE)
  540. struct blk_desc *desc = dev_get_uclass_platdata(dev);
  541. part_init(desc);
  542. #endif
  543. return 0;
  544. }
  545. UCLASS_DRIVER(blk) = {
  546. .id = UCLASS_BLK,
  547. .name = "blk",
  548. .post_probe = blk_post_probe,
  549. .per_device_platdata_auto_alloc_size = sizeof(struct blk_desc),
  550. };