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