|
@@ -295,27 +295,31 @@ static int API_dev_close(va_list ap)
|
|
|
|
|
|
|
|
|
/*
|
|
|
- * Notice: this is for sending network packets only, as U-Boot does not
|
|
|
- * support writing to storage at the moment (12.2007)
|
|
|
- *
|
|
|
* pseudo signature:
|
|
|
*
|
|
|
* int API_dev_write(
|
|
|
* struct device_info *di,
|
|
|
* void *buf,
|
|
|
- * int *len
|
|
|
+ * int *len,
|
|
|
+ * unsigned long *start
|
|
|
* )
|
|
|
*
|
|
|
* buf: ptr to buffer from where to get the data to send
|
|
|
*
|
|
|
- * len: length of packet to be sent (in bytes)
|
|
|
+ * len: ptr to length to be read
|
|
|
+ * - network: len of packet to be sent (in bytes)
|
|
|
+ * - storage: # of blocks to write (can vary in size depending on define)
|
|
|
*
|
|
|
+ * start: ptr to start block (only used for storage devices, ignored for
|
|
|
+ * network)
|
|
|
*/
|
|
|
static int API_dev_write(va_list ap)
|
|
|
{
|
|
|
struct device_info *di;
|
|
|
void *buf;
|
|
|
- int *len;
|
|
|
+ lbasize_t *len_stor, act_len_stor;
|
|
|
+ lbastart_t *start;
|
|
|
+ int *len_net;
|
|
|
int err = 0;
|
|
|
|
|
|
/* 1. arg is ptr to the device_info struct */
|
|
@@ -333,23 +337,36 @@ static int API_dev_write(va_list ap)
|
|
|
if (buf == NULL)
|
|
|
return API_EINVAL;
|
|
|
|
|
|
- /* 3. arg is length of buffer */
|
|
|
- len = (int *)va_arg(ap, uintptr_t);
|
|
|
- if (len == NULL)
|
|
|
- return API_EINVAL;
|
|
|
- if (*len <= 0)
|
|
|
- return API_EINVAL;
|
|
|
+ if (di->type & DEV_TYP_STOR) {
|
|
|
+ /* 3. arg - ptr to var with # of blocks to write */
|
|
|
+ len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
|
|
|
+ if (!len_stor)
|
|
|
+ return API_EINVAL;
|
|
|
+ if (*len_stor <= 0)
|
|
|
+ return API_EINVAL;
|
|
|
|
|
|
- if (di->type & DEV_TYP_STOR)
|
|
|
- /*
|
|
|
- * write to storage is currently not supported by U-Boot:
|
|
|
- * no storage device implements block_write() method
|
|
|
- */
|
|
|
- return API_ENODEV;
|
|
|
+ /* 4. arg - ptr to var with start block */
|
|
|
+ start = (lbastart_t *)va_arg(ap, uintptr_t);
|
|
|
|
|
|
- else if (di->type & DEV_TYP_NET)
|
|
|
- err = dev_write_net(di->cookie, buf, *len);
|
|
|
- else
|
|
|
+ act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, *start);
|
|
|
+ if (act_len_stor != *len_stor) {
|
|
|
+ debugf("write @ %llu: done %llu out of %llu blocks",
|
|
|
+ (uint64_t)blk, (uint64_t)act_len_stor,
|
|
|
+ (uint64_t)len_stor);
|
|
|
+ return API_EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ } else if (di->type & DEV_TYP_NET) {
|
|
|
+ /* 3. arg points to the var with length of packet to write */
|
|
|
+ len_net = (int *)va_arg(ap, uintptr_t);
|
|
|
+ if (!len_net)
|
|
|
+ return API_EINVAL;
|
|
|
+ if (*len_net <= 0)
|
|
|
+ return API_EINVAL;
|
|
|
+
|
|
|
+ err = dev_write_net(di->cookie, buf, *len_net);
|
|
|
+
|
|
|
+ } else
|
|
|
err = API_ENODEV;
|
|
|
|
|
|
return err;
|