blk: Remove various places that do flush cache after read
[oweals/u-boot.git] / drivers / block / blk_legacy.c
1 /*
2  * Copyright (C) 2016 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <linux/err.h>
10
11 struct blk_driver *blk_driver_lookup_type(int if_type)
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 (if_type == entry->if_type)
19                         return entry;
20         }
21
22         /* Not found */
23         return NULL;
24 }
25
26 static struct blk_driver *blk_driver_lookup_typename(const char *if_typename)
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(if_typename, entry->if_typename))
34                         return entry;
35         }
36
37         /* Not found */
38         return NULL;
39 }
40
41 const char *blk_get_if_type_name(enum if_type if_type)
42 {
43         struct blk_driver *drv = blk_driver_lookup_type(if_type);
44
45         return drv ? drv->if_typename : 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 #ifdef HAVE_BLOCK_DEVICE
73 int blk_list_part(enum if_type if_type)
74 {
75         struct blk_driver *drv;
76         struct blk_desc *desc;
77         int devnum, ok;
78         bool first = true;
79
80         drv = blk_driver_lookup_type(if_type);
81         if (!drv)
82                 return -ENOSYS;
83         for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) {
84                 if (get_desc(drv, devnum, &desc))
85                         continue;
86                 if (desc->part_type != PART_TYPE_UNKNOWN) {
87                         ++ok;
88                         if (!first)
89                                 putc('\n');
90                         part_print(desc);
91                         first = false;
92                 }
93         }
94         if (!ok)
95                 return -ENODEV;
96
97         return 0;
98 }
99
100 int blk_print_part_devnum(enum if_type if_type, int devnum)
101 {
102         struct blk_driver *drv = blk_driver_lookup_type(if_type);
103         struct blk_desc *desc;
104         int ret;
105
106         if (!drv)
107                 return -ENOSYS;
108         ret = get_desc(drv, devnum, &desc);
109         if (ret)
110                 return ret;
111         if (desc->type == DEV_TYPE_UNKNOWN)
112                 return -ENOENT;
113         part_print(desc);
114
115         return 0;
116 }
117
118 void blk_list_devices(enum if_type if_type)
119 {
120         struct blk_driver *drv = blk_driver_lookup_type(if_type);
121         struct blk_desc *desc;
122         int i;
123
124         if (!drv)
125                 return;
126         for (i = 0; i < drv->max_devs; ++i) {
127                 if (get_desc(drv, i, &desc))
128                         continue;
129                 if (desc->type == DEV_TYPE_UNKNOWN)
130                         continue;  /* list only known devices */
131                 printf("Device %d: ", i);
132                 dev_print(desc);
133         }
134 }
135
136 int blk_print_device_num(enum if_type if_type, int devnum)
137 {
138         struct blk_driver *drv = blk_driver_lookup_type(if_type);
139         struct blk_desc *desc;
140         int ret;
141
142         if (!drv)
143                 return -ENOSYS;
144         ret = get_desc(drv, devnum, &desc);
145         if (ret)
146                 return ret;
147         printf("\n%s device %d: ", drv->if_typename, devnum);
148         dev_print(desc);
149
150         return 0;
151 }
152
153 int blk_show_device(enum if_type if_type, int devnum)
154 {
155         struct blk_driver *drv = blk_driver_lookup_type(if_type);
156         struct blk_desc *desc;
157         int ret;
158
159         if (!drv)
160                 return -ENOSYS;
161         printf("\nDevice %d: ", devnum);
162         if (devnum >= drv->max_devs) {
163                 puts("unknown device\n");
164                 return -ENODEV;
165         }
166         ret = get_desc(drv, devnum, &desc);
167         if (ret)
168                 return ret;
169         dev_print(desc);
170
171         if (desc->type == DEV_TYPE_UNKNOWN)
172                 return -ENOENT;
173
174         return 0;
175 }
176 #endif /* HAVE_BLOCK_DEVICE */
177
178 struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum)
179 {
180         struct blk_driver *drv = blk_driver_lookup_type(if_type);
181         struct blk_desc *desc;
182
183         if (!drv)
184                 return NULL;
185
186         if (get_desc(drv, devnum, &desc))
187                 return NULL;
188
189         return desc;
190 }
191
192 int blk_dselect_hwpart(struct blk_desc *desc, int hwpart)
193 {
194         struct blk_driver *drv = blk_driver_lookup_type(desc->if_type);
195
196         if (!drv)
197                 return -ENOSYS;
198         if (drv->select_hwpart)
199                 return drv->select_hwpart(desc, hwpart);
200
201         return 0;
202 }
203
204 struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum)
205 {
206         struct blk_driver *drv = blk_driver_lookup_typename(if_typename);
207         struct blk_desc *desc;
208
209         if (!drv)
210                 return NULL;
211
212         if (get_desc(drv, devnum, &desc))
213                 return NULL;
214
215         return desc;
216 }
217
218 ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start,
219                       lbaint_t blkcnt, void *buffer)
220 {
221         struct blk_driver *drv = blk_driver_lookup_type(if_type);
222         struct blk_desc *desc;
223         ulong n;
224         int ret;
225
226         if (!drv)
227                 return -ENOSYS;
228         ret = get_desc(drv, devnum, &desc);
229         if (ret)
230                 return ret;
231         n = desc->block_read(desc, start, blkcnt, buffer);
232         if (IS_ERR_VALUE(n))
233                 return n;
234
235         return n;
236 }
237
238 ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start,
239                        lbaint_t blkcnt, const void *buffer)
240 {
241         struct blk_driver *drv = blk_driver_lookup_type(if_type);
242         struct blk_desc *desc;
243         int ret;
244
245         if (!drv)
246                 return -ENOSYS;
247         ret = get_desc(drv, devnum, &desc);
248         if (ret)
249                 return ret;
250         return desc->block_write(desc, start, blkcnt, buffer);
251 }
252
253 int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart)
254 {
255         struct blk_driver *drv = blk_driver_lookup_type(if_type);
256         struct blk_desc *desc;
257         int ret;
258
259         if (!drv)
260                 return -ENOSYS;
261         ret = get_desc(drv, devnum, &desc);
262         if (ret)
263                 return ret;
264         return drv->select_hwpart(desc, hwpart);
265 }