SHOW:
|
|
- or go back to the newest paste.
1 | From 8d05ccdea2fa533d6427acfe5b78300984344d5e Mon Sep 17 00:00:00 2001 | |
2 | From: Ihar Filipau <[email protected]> | |
3 | Date: Tue, 12 Jul 2016 13:27:02 +0200 | |
4 | Subject: [PATCH] storage device support for ub_dev_write | |
5 | ||
6 | I have stumbled upon the lack of support for storage devices in API's | |
7 | ub_dev_write()/API_dev_write() functions. Currently the function | |
8 | supports only the network devices. | |
9 | ||
10 | I have implemented the support for the storage by adapting the code | |
11 | from API_dev_read() function, and added the ub_dev_write() to the | |
12 | glue.c. Interface for the network devices is unchanged. | |
13 | ||
14 | - | I could only test the ub_dev_write() for storage, but my application |
14 | + | |
15 | - | doesn't use the ub_dev_send() thus I can't test it (but 99% sure that |
15 | + | |
16 | - | it still works). |
16 | + | |
17 | api/api.c | 90 +++++++++++++++++++++++++++++++++++------------------ | |
18 | - | P.S. Do not blame me for the formatting inconsistent with the rest of |
18 | + | |
19 | - | the file - patman has insisted. |
19 | + | |
20 | examples/api/glue.c | 20 ++++++++++++ | |
21 | 4 files changed, 102 insertions(+), 30 deletions(-) | |
22 | ||
23 | diff --git a/api/api.c b/api/api.c | |
24 | index 8a1433a..2ce5d07 100644 | |
25 | --- a/api/api.c | |
26 | +++ b/api/api.c | |
27 | @@ -295,28 +295,44 @@ static int API_dev_close(va_list ap) | |
28 | ||
29 | ||
30 | /* | |
31 | - * Notice: this is for sending network packets only, as U-Boot does not | |
32 | - * support writing to storage at the moment (12.2007) | |
33 | + * pseudo signature, storage: | |
34 | * | |
35 | - * pseudo signature: | |
36 | + * int API_dev_write( | |
37 | + * struct device_info *di, | |
38 | + * void *buf, | |
39 | + * lbasize_t *len, | |
40 | + * lbastart_t *start, | |
41 | + * lbasize_t *act_len | |
42 | + * ) | |
43 | * | |
44 | - * int API_dev_write( | |
45 | - * struct device_info *di, | |
46 | - * void *buf, | |
47 | - * int *len | |
48 | - * ) | |
49 | + * pseudo signature, net: | |
50 | + * | |
51 | + * int API_dev_write( | |
52 | + * struct device_info *di, | |
53 | + * void *buf, | |
54 | + * int *len | |
55 | + * ) | |
56 | + * | |
57 | + * buf: ptr to buffer with data to write | |
58 | * | |
59 | - * buf: ptr to buffer from where to get the data to send | |
60 | + * len: length to be written | |
61 | + * - network: len of packet to write (in bytes) | |
62 | + * - storage: # of blocks to write (can vary in size depending on define) | |
63 | * | |
64 | - * len: length of packet to be sent (in bytes) | |
65 | + * start: start block (only used for storage devices, ignored for | |
66 | + * network) | |
67 | + * | |
68 | + * act_len: ptr to where to put the len actually written | |
69 | * | |
70 | */ | |
71 | static int API_dev_write(va_list ap) | |
72 | { | |
73 | struct device_info *di; | |
74 | void *buf; | |
75 | - int *len; | |
76 | - int err = 0; | |
77 | + lbasize_t *len_stor, *act_len_stor; | |
78 | + lbastart_t *start; | |
79 | + int *len_net; | |
80 | + int ret = 0; | |
81 | ||
82 | /* 1. arg is ptr to the device_info struct */ | |
83 | di = (struct device_info *)va_arg(ap, uintptr_t); | |
84 | @@ -328,31 +344,45 @@ static int API_dev_write(va_list ap) | |
85 | if (di->cookie == NULL) | |
86 | return API_ENODEV; | |
87 | ||
88 | - /* 2. arg is ptr to buffer from where to get data to write */ | |
89 | + /* 2. arg is ptr to buffer from where to put the read data */ | |
90 | buf = (void *)va_arg(ap, uintptr_t); | |
91 | if (buf == NULL) | |
92 | return API_EINVAL; | |
93 | ||
94 | - /* 3. arg is length of buffer */ | |
95 | - len = (int *)va_arg(ap, uintptr_t); | |
96 | - if (len == NULL) | |
97 | - return API_EINVAL; | |
98 | - if (*len <= 0) | |
99 | - return API_EINVAL; | |
100 | + if (di->type & DEV_TYP_STOR) { | |
101 | + /* 3. arg - ptr to var with # of blocks to read */ | |
102 | + len_stor = (lbasize_t *)va_arg(ap, uintptr_t); | |
103 | + if (!len_stor) | |
104 | + return API_EINVAL; | |
105 | + if (*len_stor <= 0) | |
106 | + return API_EINVAL; | |
107 | ||
108 | - if (di->type & DEV_TYP_STOR) | |
109 | - /* | |
110 | - * write to storage is currently not supported by U-Boot: | |
111 | - * no storage device implements block_write() method | |
112 | - */ | |
113 | - return API_ENODEV; | |
114 | + /* 4. arg - ptr to var with start block */ | |
115 | + start = (lbastart_t *)va_arg(ap, uintptr_t); | |
116 | ||
117 | - else if (di->type & DEV_TYP_NET) | |
118 | - err = dev_write_net(di->cookie, buf, *len); | |
119 | - else | |
120 | - err = API_ENODEV; | |
121 | + /* 5. arg - ptr to var where to put the len actually read */ | |
122 | + act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t); | |
123 | + if (!act_len_stor) | |
124 | + return API_EINVAL; | |
125 | ||
126 | - return err; | |
127 | + *act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, | |
128 | + *start); | |
129 | + | |
130 | + } else if (di->type & DEV_TYP_NET) { | |
131 | + /* 3. arg points to the var with length of packet to read */ | |
132 | + len_net = (int *)va_arg(ap, uintptr_t); | |
133 | + if (!len_net) | |
134 | + return API_EINVAL; | |
135 | + if (*len_net <= 0) | |
136 | + return API_EINVAL; | |
137 | + | |
138 | + ret = dev_write_net(di->cookie, buf, *len_net); | |
139 | + | |
140 | + } else { | |
141 | + return API_ENODEV; | |
142 | + } | |
143 | + | |
144 | + return ret; | |
145 | } | |
146 | ||
147 | ||
148 | diff --git a/api/api_private.h b/api/api_private.h | |
149 | index a8866ef..86d45bc 100644 | |
150 | --- a/api/api_private.h | |
151 | +++ b/api/api_private.h | |
152 | @@ -23,6 +23,7 @@ int dev_close_stor(void *); | |
153 | int dev_close_net(void *); | |
154 | ||
155 | lbasize_t dev_read_stor(void *, void *, lbasize_t, lbastart_t); | |
156 | +lbasize_t dev_write_stor(void *, void *, lbasize_t, lbastart_t); | |
157 | int dev_read_net(void *, void *, int); | |
158 | int dev_write_net(void *, void *, int); | |
159 | ||
160 | diff --git a/api/api_storage.c b/api/api_storage.c | |
161 | index d425a9a..efb23c1 100644 | |
162 | --- a/api/api_storage.c | |
163 | +++ b/api/api_storage.c | |
164 | @@ -365,3 +365,24 @@ lbasize_t dev_read_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start | |
165 | ||
166 | return dd->block_read(dd, start, len, buf); | |
167 | } | |
168 | + | |
169 | +lbasize_t dev_write_stor(void *cookie, void *buf, lbasize_t len, | |
170 | + lbastart_t start) | |
171 | +{ | |
172 | + int type; | |
173 | + block_dev_desc_t *dd = (block_dev_desc_t *)cookie; | |
174 | + | |
175 | + type = dev_stor_type(dd); | |
176 | + if (type == ENUM_MAX) | |
177 | + return 0; | |
178 | + | |
179 | + if (!dev_stor_is_valid(type, dd)) | |
180 | + return 0; | |
181 | + | |
182 | + if ((dd->block_write) == NULL) { | |
183 | + debugf("no block_write() for device 0x%08x\n", cookie); | |
184 | + return 0; | |
185 | + } | |
186 | + | |
187 | + return dd->block_write(dev_stor_index(dd), start, len, buf); | |
188 | +} | |
189 | diff --git a/examples/api/glue.c b/examples/api/glue.c | |
190 | index 8aabf32..1a1b69b 100644 | |
191 | --- a/examples/api/glue.c | |
192 | +++ b/examples/api/glue.c | |
193 | @@ -290,6 +290,26 @@ int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start, | |
194 | return err; | |
195 | } | |
196 | ||
197 | +int ub_dev_write(int handle, void *buf, lbasize_t len, lbastart_t start, | |
198 | + lbasize_t *rlen) | |
199 | +{ | |
200 | + struct device_info *di; | |
201 | + lbasize_t act_len; | |
202 | + int err = 0; | |
203 | + | |
204 | + if (!dev_stor_valid(handle)) | |
205 | + return API_ENODEV; | |
206 | + | |
207 | + di = &devices[handle]; | |
208 | + if (!syscall(API_DEV_WRITE, &err, di, buf, &len, &start, &act_len)) | |
209 | + return API_ESYSC; | |
210 | + | |
211 | + if (!err && rlen) | |
212 | + *rlen = act_len; | |
213 | + | |
214 | + return err; | |
215 | +} | |
216 | + | |
217 | static int dev_net_valid(int handle) | |
218 | { | |
219 | if (!dev_valid(handle)) | |
220 | -- | |
221 | 1.9.1 |