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