Merge branch '2022-04-23-binman-updates'
[platform/kernel/u-boot.git] / drivers / block / blk-uclass.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2016 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6
7 #define LOG_CATEGORY UCLASS_BLK
8
9 #include <common.h>
10 #include <blk.h>
11 #include <dm.h>
12 #include <log.h>
13 #include <malloc.h>
14 #include <part.h>
15 #include <dm/device-internal.h>
16 #include <dm/lists.h>
17 #include <dm/uclass-internal.h>
18 #include <linux/err.h>
19
20 static const char *if_typename_str[IF_TYPE_COUNT] = {
21         [IF_TYPE_IDE]           = "ide",
22         [IF_TYPE_SCSI]          = "scsi",
23         [IF_TYPE_ATAPI]         = "atapi",
24         [IF_TYPE_USB]           = "usb",
25         [IF_TYPE_DOC]           = "doc",
26         [IF_TYPE_MMC]           = "mmc",
27         [IF_TYPE_SD]            = "sd",
28         [IF_TYPE_SATA]          = "sata",
29         [IF_TYPE_HOST]          = "host",
30         [IF_TYPE_NVME]          = "nvme",
31         [IF_TYPE_EFI_MEDIA]     = "efi",
32         [IF_TYPE_EFI_LOADER]    = "efiloader",
33         [IF_TYPE_VIRTIO]        = "virtio",
34         [IF_TYPE_PVBLOCK]       = "pvblock",
35 };
36
37 static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = {
38         [IF_TYPE_IDE]           = UCLASS_IDE,
39         [IF_TYPE_SCSI]          = UCLASS_SCSI,
40         [IF_TYPE_ATAPI]         = UCLASS_INVALID,
41         [IF_TYPE_USB]           = UCLASS_MASS_STORAGE,
42         [IF_TYPE_DOC]           = UCLASS_INVALID,
43         [IF_TYPE_MMC]           = UCLASS_MMC,
44         [IF_TYPE_SD]            = UCLASS_INVALID,
45         [IF_TYPE_SATA]          = UCLASS_AHCI,
46         [IF_TYPE_HOST]          = UCLASS_ROOT,
47         [IF_TYPE_NVME]          = UCLASS_NVME,
48         [IF_TYPE_EFI_MEDIA]     = UCLASS_EFI_MEDIA,
49         [IF_TYPE_EFI_LOADER]    = UCLASS_EFI_LOADER,
50         [IF_TYPE_VIRTIO]        = UCLASS_VIRTIO,
51         [IF_TYPE_PVBLOCK]       = UCLASS_PVBLOCK,
52 };
53
54 static enum if_type if_typename_to_iftype(const char *if_typename)
55 {
56         int i;
57
58         for (i = 0; i < IF_TYPE_COUNT; i++) {
59                 if (if_typename_str[i] &&
60                     !strcmp(if_typename, if_typename_str[i]))
61                         return i;
62         }
63
64         return IF_TYPE_UNKNOWN;
65 }
66
67 static enum uclass_id if_type_to_uclass_id(enum if_type if_type)
68 {
69         return if_type_uclass_id[if_type];
70 }
71
72 const char *blk_get_if_type_name(enum if_type if_type)
73 {
74         return if_typename_str[if_type];
75 }
76
77 struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
78 {
79         struct blk_desc *desc;
80         struct udevice *dev;
81         int ret;
82
83         ret = blk_get_device(if_type, devnum, &dev);
84         if (ret)
85                 return NULL;
86         desc = dev_get_uclass_plat(dev);
87
88         return desc;
89 }
90
91 /*
92  * This function is complicated with driver model. We look up the interface
93  * name in a local table. This gives us an interface type which we can match
94  * against the uclass of the block device's parent.
95  */
96 struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
97 {
98         enum uclass_id uclass_id;
99         enum if_type if_type;
100         struct udevice *dev;
101         struct uclass *uc;
102         int ret;
103
104         if_type = if_typename_to_iftype(if_typename);
105         if (if_type == IF_TYPE_UNKNOWN) {
106                 debug("%s: Unknown interface type '%s'\n", __func__,
107                       if_typename);
108                 return NULL;
109         }
110         uclass_id = if_type_to_uclass_id(if_type);
111         if (uclass_id == UCLASS_INVALID) {
112                 debug("%s: Unknown uclass for interface type'\n",
113                       if_typename_str[if_type]);
114                 return NULL;
115         }
116
117         ret = uclass_get(UCLASS_BLK, &uc);
118         if (ret)
119                 return NULL;
120         uclass_foreach_dev(dev, uc) {
121                 struct blk_desc *desc = dev_get_uclass_plat(dev);
122
123                 debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
124                       if_type, devnum, dev->name, desc->if_type, desc->devnum);
125                 if (desc->devnum != devnum)
126                         continue;
127
128                 /* Find out the parent device uclass */
129                 if (device_get_uclass_id(dev->parent) != uclass_id) {
130                         debug("%s: parent uclass %d, this dev %d\n", __func__,
131                               device_get_uclass_id(dev->parent), uclass_id);
132                         continue;
133                 }
134
135                 if (device_probe(dev))
136                         return NULL;
137
138                 debug("%s: Device desc %p\n", __func__, desc);
139                 return desc;
140         }
141         debug("%s: No device found\n", __func__);
142
143         return NULL;
144 }
145
146 /**
147  * blk_get_by_device() - Get the block device descriptor for the given device
148  * @dev:        Instance of a storage device
149  *
150  * Return: With block device descriptor on success , NULL if there is no such
151  *         block device.
152  */
153 struct blk_desc *blk_get_by_device(struct udevice *dev)
154 {
155         struct udevice *child_dev;
156
157         device_foreach_child(child_dev, dev) {
158                 if (device_get_uclass_id(child_dev) != UCLASS_BLK)
159                         continue;
160
161                 return dev_get_uclass_plat(child_dev);
162         }
163
164         debug("%s: No block device found\n", __func__);
165
166         return NULL;
167 }
168
169 /**
170  * get_desc() - Get the block device descriptor for the given device number
171  *
172  * @if_type:    Interface type
173  * @devnum:     Device number (0 = first)
174  * @descp:      Returns block device descriptor on success
175  * Return: 0 on success, -ENODEV if there is no such device and no device
176  * with a higher device number, -ENOENT if there is no such device but there
177  * is one with a higher number, or other -ve on other error.
178  */
179 static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp)
180 {
181         bool found_more = false;
182         struct udevice *dev;
183         struct uclass *uc;
184         int ret;
185
186         *descp = NULL;
187         ret = uclass_get(UCLASS_BLK, &uc);
188         if (ret)
189                 return ret;
190         uclass_foreach_dev(dev, uc) {
191                 struct blk_desc *desc = dev_get_uclass_plat(dev);
192
193                 debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
194                       if_type, devnum, dev->name, desc->if_type, desc->devnum);
195                 if (desc->if_type == if_type) {
196                         if (desc->devnum == devnum) {
197                                 ret = device_probe(dev);
198                                 if (ret)
199                                         return ret;
200
201                                 *descp = desc;
202                                 return 0;
203                         } else if (desc->devnum > devnum) {
204                                 found_more = true;
205                         }
206                 }
207         }
208
209         return found_more ? -ENOENT : -ENODEV;
210 }
211
212 int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
213 {
214         struct udevice *dev;
215         int ret;
216
217         ret = blk_get_device(if_type, devnum, &dev);
218         if (ret)
219                 return ret;
220
221         return blk_select_hwpart(dev, hwpart);
222 }
223
224 int blk_list_part(enum if_type if_type)
225 {
226         struct blk_desc *desc;
227         int devnum, ok;
228         int ret;
229
230         for (ok = 0, devnum = 0;; ++devnum) {
231                 ret = get_desc(if_type, devnum, &desc);
232                 if (ret == -ENODEV)
233                         break;
234                 else if (ret)
235                         continue;
236                 if (desc->part_type != PART_TYPE_UNKNOWN) {
237                         ++ok;
238                         if (devnum)
239                                 putc('\n');
240                         part_print(desc);
241                 }
242         }
243         if (!ok)
244                 return -ENODEV;
245
246         return 0;
247 }
248
249 int blk_print_part_devnum(enum if_type if_type, int devnum)
250 {
251         struct blk_desc *desc;
252         int ret;
253
254         ret = get_desc(if_type, devnum, &desc);
255         if (ret)
256                 return ret;
257         if (desc->type == DEV_TYPE_UNKNOWN)
258                 return -ENOENT;
259         part_print(desc);
260
261         return 0;
262 }
263
264 void blk_list_devices(enum if_type if_type)
265 {
266         struct blk_desc *desc;
267         int ret;
268         int i;
269
270         for (i = 0;; ++i) {
271                 ret = get_desc(if_type, i, &desc);
272                 if (ret == -ENODEV)
273                         break;
274                 else if (ret)
275                         continue;
276                 if (desc->type == DEV_TYPE_UNKNOWN)
277                         continue;  /* list only known devices */
278                 printf("Device %d: ", i);
279                 dev_print(desc);
280         }
281 }
282
283 int blk_print_device_num(enum if_type if_type, int devnum)
284 {
285         struct blk_desc *desc;
286         int ret;
287
288         ret = get_desc(if_type, devnum, &desc);
289         if (ret)
290                 return ret;
291         printf("\nIDE device %d: ", devnum);
292         dev_print(desc);
293
294         return 0;
295 }
296
297 int blk_show_device(enum if_type if_type, int devnum)
298 {
299         struct blk_desc *desc;
300         int ret;
301
302         printf("\nDevice %d: ", devnum);
303         ret = get_desc(if_type, devnum, &desc);
304         if (ret == -ENODEV || ret == -ENOENT) {
305                 printf("unknown device\n");
306                 return -ENODEV;
307         }
308         if (ret)
309                 return ret;
310         dev_print(desc);
311
312         if (desc->type == DEV_TYPE_UNKNOWN)
313                 return -ENOENT;
314
315         return 0;
316 }
317
318 ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
319                       lbaint_t blkcnt, void *buffer)
320 {
321         struct blk_desc *desc;
322         ulong n;
323         int ret;
324
325         ret = get_desc(if_type, devnum, &desc);
326         if (ret)
327                 return ret;
328         n = blk_dread(desc, start, blkcnt, buffer);
329         if (IS_ERR_VALUE(n))
330                 return n;
331
332         return n;
333 }
334
335 ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
336                        lbaint_t blkcnt, const void *buffer)
337 {
338         struct blk_desc *desc;
339         int ret;
340
341         ret = get_desc(if_type, devnum, &desc);
342         if (ret)
343                 return ret;
344         return blk_dwrite(desc, start, blkcnt, buffer);
345 }
346
347 int blk_select_hwpart(struct udevice *dev, int hwpart)
348 {
349         const struct blk_ops *ops = blk_get_ops(dev);
350
351         if (!ops)
352                 return -ENOSYS;
353         if (!ops->select_hwpart)
354                 return 0;
355
356         return ops->select_hwpart(dev, hwpart);
357 }
358
359 int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
360 {
361         return blk_select_hwpart(desc->bdev, hwpart);
362 }
363
364 int blk_first_device(int if_type, struct udevice **devp)
365 {
366         struct blk_desc *desc;
367         int ret;
368
369         ret = uclass_find_first_device(UCLASS_BLK, devp);
370         if (ret)
371                 return ret;
372         if (!*devp)
373                 return -ENODEV;
374         do {
375                 desc = dev_get_uclass_plat(*devp);
376                 if (desc->if_type == if_type)
377                         return 0;
378                 ret = uclass_find_next_device(devp);
379                 if (ret)
380                         return ret;
381         } while (*devp);
382
383         return -ENODEV;
384 }
385
386 int blk_next_device(struct udevice **devp)
387 {
388         struct blk_desc *desc;
389         int ret, if_type;
390
391         desc = dev_get_uclass_plat(*devp);
392         if_type = desc->if_type;
393         do {
394                 ret = uclass_find_next_device(devp);
395                 if (ret)
396                         return ret;
397                 if (!*devp)
398                         return -ENODEV;
399                 desc = dev_get_uclass_plat(*devp);
400                 if (desc->if_type == if_type)
401                         return 0;
402         } while (1);
403 }
404
405 int blk_find_device(int if_type, int devnum, struct udevice **devp)
406 {
407         struct uclass *uc;
408         struct udevice *dev;
409         int ret;
410
411         ret = uclass_get(UCLASS_BLK, &uc);
412         if (ret)
413                 return ret;
414         uclass_foreach_dev(dev, uc) {
415                 struct blk_desc *desc = dev_get_uclass_plat(dev);
416
417                 debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__,
418                       if_type, devnum, dev->name, desc->if_type, desc->devnum);
419                 if (desc->if_type == if_type && desc->devnum == devnum) {
420                         *devp = dev;
421                         return 0;
422                 }
423         }
424
425         return -ENODEV;
426 }
427
428 int blk_get_device(int if_type, int devnum, struct udevice **devp)
429 {
430         int ret;
431
432         ret = blk_find_device(if_type, devnum, devp);
433         if (ret)
434                 return ret;
435
436         return device_probe(*devp);
437 }
438
439 unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
440                         lbaint_t blkcnt, void *buffer)
441 {
442         struct udevice *dev = block_dev->bdev;
443         const struct blk_ops *ops = blk_get_ops(dev);
444         ulong blks_read;
445
446         if (!ops->read)
447                 return -ENOSYS;
448
449         if (blkcache_read(block_dev->if_type, block_dev->devnum,
450                           start, blkcnt, block_dev->blksz, buffer))
451                 return blkcnt;
452         blks_read = ops->read(dev, start, blkcnt, buffer);
453         if (blks_read == blkcnt)
454                 blkcache_fill(block_dev->if_type, block_dev->devnum,
455                               start, blkcnt, block_dev->blksz, buffer);
456
457         return blks_read;
458 }
459
460 unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
461                          lbaint_t blkcnt, const void *buffer)
462 {
463         struct udevice *dev = block_dev->bdev;
464         const struct blk_ops *ops = blk_get_ops(dev);
465
466         if (!ops->write)
467                 return -ENOSYS;
468
469         blkcache_invalidate(block_dev->if_type, block_dev->devnum);
470         return ops->write(dev, start, blkcnt, buffer);
471 }
472
473 unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
474                          lbaint_t blkcnt)
475 {
476         struct udevice *dev = block_dev->bdev;
477         const struct blk_ops *ops = blk_get_ops(dev);
478
479         if (!ops->erase)
480                 return -ENOSYS;
481
482         blkcache_invalidate(block_dev->if_type, block_dev->devnum);
483         return ops->erase(dev, start, blkcnt);
484 }
485
486 int blk_get_from_parent(struct udevice *parent, struct udevice **devp)
487 {
488         struct udevice *dev;
489         enum uclass_id id;
490         int ret;
491
492         device_find_first_child(parent, &dev);
493         if (!dev) {
494                 debug("%s: No block device found for parent '%s'\n", __func__,
495                       parent->name);
496                 return -ENODEV;
497         }
498         id = device_get_uclass_id(dev);
499         if (id != UCLASS_BLK) {
500                 debug("%s: Incorrect uclass %s for block device '%s'\n",
501                       __func__, uclass_get_name(id), dev->name);
502                 return -ENOTBLK;
503         }
504         ret = device_probe(dev);
505         if (ret)
506                 return ret;
507         *devp = dev;
508
509         return 0;
510 }
511
512 int blk_find_max_devnum(enum if_type if_type)
513 {
514         struct udevice *dev;
515         int max_devnum = -ENODEV;
516         struct uclass *uc;
517         int ret;
518
519         ret = uclass_get(UCLASS_BLK, &uc);
520         if (ret)
521                 return ret;
522         uclass_foreach_dev(dev, uc) {
523                 struct blk_desc *desc = dev_get_uclass_plat(dev);
524
525                 if (desc->if_type == if_type && desc->devnum > max_devnum)
526                         max_devnum = desc->devnum;
527         }
528
529         return max_devnum;
530 }
531
532 int blk_next_free_devnum(enum if_type if_type)
533 {
534         int ret;
535
536         ret = blk_find_max_devnum(if_type);
537         if (ret == -ENODEV)
538                 return 0;
539         if (ret < 0)
540                 return ret;
541
542         return ret + 1;
543 }
544
545 static int blk_flags_check(struct udevice *dev, enum blk_flag_t req_flags)
546 {
547         const struct blk_desc *desc = dev_get_uclass_plat(dev);
548         enum blk_flag_t flags;
549
550         flags = desc->removable ? BLKF_REMOVABLE : BLKF_FIXED;
551
552         return flags & req_flags ? 0 : 1;
553 }
554
555 int blk_find_first(enum blk_flag_t flags, struct udevice **devp)
556 {
557         int ret;
558
559         for (ret = uclass_find_first_device(UCLASS_BLK, devp);
560              *devp && !blk_flags_check(*devp, flags);
561              ret = uclass_find_next_device(devp))
562                 return 0;
563
564         return -ENODEV;
565 }
566
567 int blk_find_next(enum blk_flag_t flags, struct udevice **devp)
568 {
569         int ret;
570
571         for (ret = uclass_find_next_device(devp);
572              *devp && !blk_flags_check(*devp, flags);
573              ret = uclass_find_next_device(devp))
574                 return 0;
575
576         return -ENODEV;
577 }
578
579 int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp)
580 {
581         int ret;
582
583         for (ret = uclass_first_device_err(UCLASS_BLK, devp);
584              !ret;
585              ret = uclass_next_device_err(devp)) {
586                 if (!blk_flags_check(*devp, flags))
587                         return 0;
588         }
589
590         return -ENODEV;
591 }
592
593 int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp)
594 {
595         int ret;
596
597         for (ret = uclass_next_device_err(devp);
598              !ret;
599              ret = uclass_next_device_err(devp)) {
600                 if (!blk_flags_check(*devp, flags))
601                         return 0;
602         }
603
604         return -ENODEV;
605 }
606
607 int blk_count_devices(enum blk_flag_t flag)
608 {
609         struct udevice *dev;
610         int count = 0;
611
612         blk_foreach_probe(flag, dev)
613                 count++;
614
615         return count;
616 }
617
618 static int blk_claim_devnum(enum if_type if_type, int devnum)
619 {
620         struct udevice *dev;
621         struct uclass *uc;
622         int ret;
623
624         ret = uclass_get(UCLASS_BLK, &uc);
625         if (ret)
626                 return ret;
627         uclass_foreach_dev(dev, uc) {
628                 struct blk_desc *desc = dev_get_uclass_plat(dev);
629
630                 if (desc->if_type == if_type && desc->devnum == devnum) {
631                         int next = blk_next_free_devnum(if_type);
632
633                         if (next < 0)
634                                 return next;
635                         desc->devnum = next;
636                         return 0;
637                 }
638         }
639
640         return -ENOENT;
641 }
642
643 int blk_create_device(struct udevice *parent, const char *drv_name,
644                       const char *name, int if_type, int devnum, int blksz,
645                       lbaint_t lba, struct udevice **devp)
646 {
647         struct blk_desc *desc;
648         struct udevice *dev;
649         int ret;
650
651         if (devnum == -1) {
652                 devnum = blk_next_free_devnum(if_type);
653         } else {
654                 ret = blk_claim_devnum(if_type, devnum);
655                 if (ret < 0 && ret != -ENOENT)
656                         return ret;
657         }
658         if (devnum < 0)
659                 return devnum;
660         ret = device_bind_driver(parent, drv_name, name, &dev);
661         if (ret)
662                 return ret;
663         desc = dev_get_uclass_plat(dev);
664         desc->if_type = if_type;
665         desc->blksz = blksz;
666         desc->log2blksz = LOG2(desc->blksz);
667         desc->lba = lba;
668         desc->part_type = PART_TYPE_UNKNOWN;
669         desc->bdev = dev;
670         desc->devnum = devnum;
671         *devp = dev;
672
673         return 0;
674 }
675
676 int blk_create_devicef(struct udevice *parent, const char *drv_name,
677                        const char *name, int if_type, int devnum, int blksz,
678                        lbaint_t lba, struct udevice **devp)
679 {
680         char dev_name[30], *str;
681         int ret;
682
683         snprintf(dev_name, sizeof(dev_name), "%s.%s", parent->name, name);
684         str = strdup(dev_name);
685         if (!str)
686                 return -ENOMEM;
687
688         ret = blk_create_device(parent, drv_name, str, if_type, devnum,
689                                 blksz, lba, devp);
690         if (ret) {
691                 free(str);
692                 return ret;
693         }
694         device_set_name_alloced(*devp);
695
696         return 0;
697 }
698
699 int blk_probe_or_unbind(struct udevice *dev)
700 {
701         int ret;
702
703         ret = device_probe(dev);
704         if (ret) {
705                 log_debug("probing %s failed\n", dev->name);
706                 device_unbind(dev);
707         }
708
709         return ret;
710 }
711
712 int blk_unbind_all(int if_type)
713 {
714         struct uclass *uc;
715         struct udevice *dev, *next;
716         int ret;
717
718         ret = uclass_get(UCLASS_BLK, &uc);
719         if (ret)
720                 return ret;
721         uclass_foreach_dev_safe(dev, next, uc) {
722                 struct blk_desc *desc = dev_get_uclass_plat(dev);
723
724                 if (desc->if_type == if_type) {
725                         ret = device_remove(dev, DM_REMOVE_NORMAL);
726                         if (ret)
727                                 return ret;
728                         ret = device_unbind(dev);
729                         if (ret)
730                                 return ret;
731                 }
732         }
733
734         return 0;
735 }
736
737 static int blk_post_probe(struct udevice *dev)
738 {
739         if (CONFIG_IS_ENABLED(PARTITIONS) &&
740             IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE)) {
741                 struct blk_desc *desc = dev_get_uclass_plat(dev);
742
743                 part_init(desc);
744
745                 if (desc->part_type != PART_TYPE_UNKNOWN &&
746                     part_create_block_devices(dev))
747                         debug("*** creating partitions failed\n");
748         }
749
750         return 0;
751 }
752
753 UCLASS_DRIVER(blk) = {
754         .id             = UCLASS_BLK,
755         .name           = "blk",
756         .post_probe     = blk_post_probe,
757         .per_device_plat_auto   = sizeof(struct blk_desc),
758 };