Hi All! I have stumbled upon the lack of support for storage devices in API's ub_dev_write()/API_dev_write() functions. Currently the function supports only the network devices.
I have implemented the support for the storage by adapting the code from API_dev_read() function, and added the ub_dev_write() to the glue.c. Interface for the network devices is unchanged. I could only test the ub_dev_write() for storage, but my application doesn't use the ub_dev_send() thus I can't test it (but 99% sure that it still works). The patch is attached (should apply cleanly to the current git master git.denx.de/u-boot.git). Comments are welcome. Applying it to the git master is even more so. -- Pink Panther's To Do list: - To do - To do - To do, to do, to do, to do, to doooo
From 4c6a2222c1f902a5ff185bad992ac1e420e53c7d Mon Sep 17 00:00:00 2001 From: Ihar Filipau <[email protected]> Date: Wed, 6 Jul 2016 15:35:19 +0200 Subject: [PATCH] storage device support for ub_dev_write --- api/api.c | 89 +++++++++++++++++++++++++++++++++++------------------ api/api_private.h | 1 + api/api_storage.c | 19 ++++++++++++ examples/api/glue.c | 20 ++++++++++++ 4 files changed, 99 insertions(+), 30 deletions(-) diff --git a/api/api.c b/api/api.c index 8a1433a..19c24b1 100644 --- a/api/api.c +++ b/api/api.c @@ -295,28 +295,44 @@ 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, storage: * - * pseudo signature: + * int API_dev_write( + * struct device_info *di, + * void *buf, + * lbasize_t *len, + * lbastart_t *start, + * lbasize_t *act_len + * ) * - * int API_dev_write( - * struct device_info *di, - * void *buf, - * int *len - * ) + * pseudo signature, net: * - * buf: ptr to buffer from where to get the data to send + * int API_dev_write( + * struct device_info *di, + * void *buf, + * int *len + * ) * - * len: length of packet to be sent (in bytes) + * buf: ptr to buffer with data to write + * + * len: length to be written + * - network: len of packet to write (in bytes) + * - storage: # of blocks to write (can vary in size depending on define) + * + * start: start block (only used for storage devices, ignored for + * network) + * + * act_len: ptr to where to put the len actually written * */ static int API_dev_write(va_list ap) { struct device_info *di; void *buf; - int *len; - int err = 0; + lbasize_t *len_stor, *act_len_stor; + lbastart_t *start; + int *len_net; + int ret = 0; /* 1. arg is ptr to the device_info struct */ di = (struct device_info *)va_arg(ap, uintptr_t); @@ -328,31 +344,44 @@ static int API_dev_write(va_list ap) if (di->cookie == NULL) return API_ENODEV; - /* 2. arg is ptr to buffer from where to get data to write */ + /* 2. arg is ptr to buffer from where to put the read data */ buf = (void *)va_arg(ap, uintptr_t); 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 read */ + 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 - err = API_ENODEV; + /* 5. arg - ptr to var where to put the len actually read */ + act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t); + if (!act_len_stor) + return API_EINVAL; - return err; + *act_len_stor = dev_write_stor(di->cookie, buf, *len_stor, *start); + + } else if (di->type & DEV_TYP_NET) { + + /* 3. arg points to the var with length of packet to read */ + len_net = (int *)va_arg(ap, uintptr_t); + if (!len_net) + return API_EINVAL; + if (*len_net <= 0) + return API_EINVAL; + + ret = dev_write_net(di->cookie, buf, *len_net); + + } else + return API_ENODEV; + + return ret; } diff --git a/api/api_private.h b/api/api_private.h index a8866ef..86d45bc 100644 --- a/api/api_private.h +++ b/api/api_private.h @@ -23,6 +23,7 @@ int dev_close_stor(void *); int dev_close_net(void *); lbasize_t dev_read_stor(void *, void *, lbasize_t, lbastart_t); +lbasize_t dev_write_stor(void *, void *, lbasize_t, lbastart_t); int dev_read_net(void *, void *, int); int dev_write_net(void *, void *, int); diff --git a/api/api_storage.c b/api/api_storage.c index d425a9a..967f0da 100644 --- a/api/api_storage.c +++ b/api/api_storage.c @@ -365,3 +365,22 @@ lbasize_t dev_read_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start return dd->block_read(dd, start, len, buf); } + +lbasize_t dev_write_stor(void *cookie, void *buf, lbasize_t len, lbastart_t start) +{ + int type; + block_dev_desc_t *dd = (block_dev_desc_t *)cookie; + + if ((type = dev_stor_type(dd)) == ENUM_MAX) + return 0; + + if (!dev_stor_is_valid(type, dd)) + return 0; + + if ((dd->block_write) == NULL) { + debugf("no block_write() for device 0x%08x\n", cookie); + return 0; + } + + return (dd->block_write(dev_stor_index(dd), start, len, buf)); +} diff --git a/examples/api/glue.c b/examples/api/glue.c index 8aabf32..1a1b69b 100644 --- a/examples/api/glue.c +++ b/examples/api/glue.c @@ -290,6 +290,26 @@ int ub_dev_read(int handle, void *buf, lbasize_t len, lbastart_t start, return err; } +int ub_dev_write(int handle, void *buf, lbasize_t len, lbastart_t start, + lbasize_t *rlen) +{ + struct device_info *di; + lbasize_t act_len; + int err = 0; + + if (!dev_stor_valid(handle)) + return API_ENODEV; + + di = &devices[handle]; + if (!syscall(API_DEV_WRITE, &err, di, buf, &len, &start, &act_len)) + return API_ESYSC; + + if (!err && rlen) + *rlen = act_len; + + return err; +} + static int dev_net_valid(int handle) { if (!dev_valid(handle)) -- 1.9.1
_______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

