]> Git Repo - J-u-boot.git/blob - drivers/block/blk_legacy.c
net: mediatek: fix gmac2 usability for mt7629
[J-u-boot.git] / drivers / block / blk_legacy.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2016 Google, Inc
4  * Written by Simon Glass <[email protected]>
5  */
6
7 #include <blk.h>
8 #include <part.h>
9 #include <linux/err.h>
10
11 struct blk_driver *blk_driver_lookup_type(int uclass_id)
12 {
13         struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
14         const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
15         struct blk_driver *entry;
16
17         for (entry = drv; entry != drv + n_ents; entry++) {
18                 if (uclass_id == entry->uclass_id)
19                         return entry;
20         }
21
22         /* Not found */
23         return NULL;
24 }
25
26 static struct blk_driver *blk_driver_lookup_typename(const char *uclass_idname)
27 {
28         struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver);
29         const int n_ents = ll_entry_count(struct blk_driver, blk_driver);
30         struct blk_driver *entry;
31
32         for (entry = drv; entry != drv + n_ents; entry++) {
33                 if (!strcmp(uclass_idname, entry->uclass_idname))
34                         return entry;
35         }
36
37         /* Not found */
38         return NULL;
39 }
40
41 const char *blk_get_uclass_name(enum uclass_id uclass_id)
42 {
43         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
44
45         return drv ? drv->uclass_idname : NULL;
46 }
47
48 /**
49  * get_desc() - Get the block device descriptor for the given device number
50  *
51  * @drv:        Legacy block driver
52  * @devnum:     Device number (0 = first)
53  * @descp:      Returns block device descriptor on success
54  * Return: 0 on success, -ENODEV if there is no such device, -ENOSYS if the
55  * driver does not provide a way to find a device, or other -ve on other
56  * error.
57  */
58 static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp)
59 {
60         if (drv->desc) {
61                 if (devnum < 0 || devnum >= drv->max_devs)
62                         return -ENODEV;
63                 *descp = &drv->desc[devnum];
64                 return 0;
65         }
66         if (!drv->get_dev)
67                 return -ENOSYS;
68
69         return drv->get_dev(devnum, descp);
70 }
71
72 int blk_list_part(enum uclass_id uclass_id)
73 {
74         struct blk_driver *drv;
75         struct blk_desc *desc;
76         int devnum, ok;
77         bool first = true;
78
79         drv = blk_driver_lookup_type(uclass_id);
80         if (!drv)
81                 return -ENOSYS;
82         for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
83                 if (get_desc(drv, devnum, &desc))
84                         continue;
85                 if (desc->part_type != PART_TYPE_UNKNOWN) {
86                         ++ok;
87                         if (!first)
88                                 putc('\n');
89                         part_print(desc);
90                         first = false;
91                 }
92         }
93         if (!ok)
94                 return -ENODEV;
95
96         return 0;
97 }
98
99 int blk_print_part_devnum(enum uclass_id uclass_id, int devnum)
100 {
101         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
102         struct blk_desc *desc;
103         int ret;
104
105         if (!drv)
106                 return -ENOSYS;
107         ret = get_desc(drv, devnum, &desc);
108         if (ret)
109                 return ret;
110         if (desc->type == DEV_TYPE_UNKNOWN)
111                 return -ENOENT;
112         part_print(desc);
113
114         return 0;
115 }
116
117 void blk_list_devices(enum uclass_id uclass_id)
118 {
119         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
120         struct blk_desc *desc;
121         int i;
122
123         if (!drv)
124                 return;
125         for (i = 0; i < drv->max_devs; ++i) {
126                 if (get_desc(drv, i, &desc))
127                         continue;
128                 if (desc->type == DEV_TYPE_UNKNOWN)
129                         continue;  /* list only known devices */
130                 printf("Device %d: ", i);
131                 dev_print(desc);
132         }
133 }
134
135 int blk_print_device_num(enum uclass_id uclass_id, int devnum)
136 {
137         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
138         struct blk_desc *desc;
139         int ret;
140
141         if (!drv)
142                 return -ENOSYS;
143         ret = get_desc(drv, devnum, &desc);
144         if (ret)
145                 return ret;
146         printf("\n%s device %d: ", drv->uclass_idname, devnum);
147         dev_print(desc);
148
149         return 0;
150 }
151
152 int blk_show_device(enum uclass_id uclass_id, int devnum)
153 {
154         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
155         struct blk_desc *desc;
156         int ret;
157
158         if (!drv)
159                 return -ENOSYS;
160         printf("\nDevice %d: ", devnum);
161         if (devnum >= drv->max_devs) {
162                 puts("unknown device\n");
163                 return -ENODEV;
164         }
165         ret = get_desc(drv, devnum, &desc);
166         if (ret)
167                 return ret;
168         dev_print(desc);
169
170         if (desc->type == DEV_TYPE_UNKNOWN)
171                 return -ENOENT;
172
173         return 0;
174 }
175
176 struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum)
177 {
178         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
179         struct blk_desc *desc;
180
181         if (!drv)
182                 return NULL;
183
184         if (get_desc(drv, devnum, &desc))
185                 return NULL;
186
187         return desc;
188 }
189
190 int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
191 {
192         struct blk_driver *drv = blk_driver_lookup_type(desc->uclass_id);
193
194         if (!drv)
195                 return -ENOSYS;
196         if (drv->select_hwpart)
197                 return drv->select_hwpart(desc, hwpart);
198
199         return 0;
200 }
201
202 struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum)
203 {
204         struct blk_driver *drv = blk_driver_lookup_typename(uclass_idname);
205         struct blk_desc *desc;
206
207         if (!drv)
208                 return NULL;
209
210         if (get_desc(drv, devnum, &desc))
211                 return NULL;
212
213         return desc;
214 }
215
216 ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
217                       lbaint_t blkcnt, void *buffer)
218 {
219         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
220         struct blk_desc *desc;
221         ulong n;
222         int ret;
223
224         if (!drv)
225                 return -ENOSYS;
226         ret = get_desc(drv, devnum, &desc);
227         if (ret)
228                 return ret;
229         n = desc->block_read(desc, start, blkcnt, buffer);
230         if (IS_ERR_VALUE(n))
231                 return n;
232
233         return n;
234 }
235
236 ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start,
237                        lbaint_t blkcnt, const void *buffer)
238 {
239         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
240         struct blk_desc *desc;
241         int ret;
242
243         if (!drv)
244                 return -ENOSYS;
245         ret = get_desc(drv, devnum, &desc);
246         if (ret)
247                 return ret;
248         return desc->block_write(desc, start, blkcnt, buffer);
249 }
250
251 int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart)
252 {
253         struct blk_driver *drv = blk_driver_lookup_type(uclass_id);
254         struct blk_desc *desc;
255         int ret;
256
257         if (!drv)
258                 return -ENOSYS;
259         ret = get_desc(drv, devnum, &desc);
260         if (ret)
261                 return ret;
262         return drv->select_hwpart(desc, hwpart);
263 }
This page took 0.038866 seconds and 4 git commands to generate.