View difference between Paste ID: JirJw9NX and WgUt04Ah
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