Changeset 19ea61d in mainline
- Timestamp:
- 2017-11-20T20:01:24Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 677cad5
- Parents:
- c657bd7
- Location:
- uspace/lib/c/generic/io
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/io/chardev.c
rc657bd7 r19ea61d 96 96 int chardev_read(chardev_t *chardev, void *buf, size_t size, size_t *nread) 97 97 { 98 if (size > 4 * sizeof(sysarg_t))99 return ELIMIT;100 101 98 async_exch_t *exch = async_exchange_begin(chardev->sess); 102 sysarg_t message[4] = { 0 }; 103 const ssize_t ret = async_req_1_4(exch, CHARDEV_READ, size, 104 &message[0], &message[1], &message[2], &message[3]); 99 100 if (size > DATA_XFER_LIMIT) { 101 /* This should not hurt anything. */ 102 size = DATA_XFER_LIMIT; 103 } 104 105 ipc_call_t answer; 106 aid_t req = async_send_0(exch, CHARDEV_READ, &answer); 107 int rc = async_data_read_start(exch, buf, size); 105 108 async_exchange_end(exch); 106 if (ret > 0 && (size_t)ret <= size) 107 memcpy(buf, message, size); 108 109 if (ret < 0) { 109 110 if (rc != EOK) { 111 async_forget(req); 110 112 *nread = 0; 111 return ret; 112 } 113 114 *nread = ret; 115 return EOK; 116 } 117 118 /** Write to character device. 119 * 120 * Write @a size bytes from @a data to character device. On success EOK 121 * is returned, all bytes were written and @a *nwritten is set to @a size. 113 return rc; 114 } 115 116 sysarg_t retval; 117 async_wait_for(req, &retval); 118 119 if (retval != EOK) { 120 *nread = 0; 121 return retval; 122 } 123 124 *nread = IPC_GET_ARG2(answer); 125 /* In case of partial success, ARG1 contains the error code */ 126 return IPC_GET_ARG1(answer); 127 128 } 129 130 /** Write up to DATA_XFER_LIMIT bytes to character device. 131 * 132 * Write up to @a size or DATA_XFER_LIMIT bytes from @a data to character 133 * device. On success EOK is returned, bytes were written and @a *nwritten 134 * is set to min(@a size, DATA_XFER_LIMIT) 122 135 * 123 136 * On error a non-zero error code is returned and @a *nwritten is filled with … … 131 144 * @return EOK on success or non-zero error code 132 145 */ 146 static int chardev_write_once(chardev_t *chardev, const void *data, 147 size_t size, size_t *nwritten) 148 { 149 async_exch_t *exch = async_exchange_begin(chardev->sess); 150 ipc_call_t answer; 151 aid_t req; 152 int rc; 153 154 /* Break down large transfers */ 155 if (size > DATA_XFER_LIMIT) 156 size = DATA_XFER_LIMIT; 157 158 req = async_send_0(exch, CHARDEV_WRITE, &answer); 159 rc = async_data_write_start(exch, data, size); 160 async_exchange_end(exch); 161 162 if (rc != EOK) { 163 async_forget(req); 164 *nwritten = 0; 165 return rc; 166 } 167 168 sysarg_t retval; 169 async_wait_for(req, &retval); 170 if (retval != EOK) { 171 *nwritten = 0; 172 return retval; 173 } 174 175 *nwritten = IPC_GET_ARG2(answer); 176 /* In case of partial success, ARG1 contains the error code */ 177 return IPC_GET_ARG1(answer); 178 } 179 180 /** Write to character device. 181 * 182 * Write @a size bytes from @a data to character device. On success EOK 183 * is returned, all bytes were written and @a *nwritten is set to @a size. 184 * 185 * On error a non-zero error code is returned and @a *nwritten is filled with 186 * the number of bytes that were successfully transferred. 187 * 188 * @param chardev Character device 189 * @param buf Destination buffer 190 * @param size Maximum number of bytes to read 191 * @param nwritten Place to store actual number of bytes written 192 * 193 * @return EOK on success or non-zero error code 194 */ 133 195 int chardev_write(chardev_t *chardev, const void *data, size_t size, 134 196 size_t *nwritten) 135 197 { 136 int ret;137 138 i f (size > 3 * sizeof(sysarg_t))139 return ELIMIT; 140 141 async_exch_t *exch = async_exchange_begin(chardev->sess);142 sysarg_t message[3] = { 0 };143 memcpy(message, data, size);144 ret = async_req_4_0(exch, CHARDEV_WRITE, size,145 message[0], message[1], message[2]); 146 async_exchange_end(exch);147 148 if (ret < 0) {149 *nwritten = 0;150 return ret;151 } 152 153 *nwritten = ret;198 size_t nw; 199 size_t p; 200 int rc; 201 202 p = 0; 203 while (p < size) { 204 rc = chardev_write_once(chardev, data + p, size - p, &nw); 205 /* nw is always valid, we can have partial success */ 206 p += nw; 207 208 if (rc != EOK) { 209 /* We can return partial success */ 210 *nwritten = p; 211 return rc; 212 } 213 } 214 215 *nwritten = p; 154 216 return EOK; 155 217 } -
uspace/lib/c/generic/io/chardev_srv.c
rc657bd7 r19ea61d 46 46 ipc_call_t *call) 47 47 { 48 size_t size = IPC_GET_ARG1(*call); 48 void *buf; 49 size_t size; 49 50 int rc; 51 ipc_callid_t rcallid; 50 52 51 if ( srv->srvs->ops->read == NULL) {52 async_answer_0(callid, E NOTSUP);53 if (!async_data_read_receive(&rcallid, &size)) { 54 async_answer_0(callid, EINVAL); 53 55 return; 54 56 } 55 57 56 if (size <= 4 * sizeof(sysarg_t)) { 57 sysarg_t message[4] = {}; 58 buf = malloc(size); 59 if (buf == NULL) { 60 async_answer_0(rcallid, ENOMEM); 61 async_answer_0(callid, ENOMEM); 62 return; 63 } 58 64 59 rc = srv->srvs->ops->read(srv, (char *)message, size);60 async_answer_ 4(callid, rc, message[0], message[1],61 message[2], message[3]);62 } else {63 async_answer_0(callid, ELIMIT);65 if (srv->srvs->ops->read == NULL) { 66 async_answer_0(rcallid, ENOTSUP); 67 async_answer_0(callid, ENOTSUP); 68 free(buf); 69 return; 64 70 } 71 72 rc = srv->srvs->ops->read(srv, buf, size); 73 if (rc < 0) { 74 async_answer_0(rcallid, rc); 75 async_answer_0(callid, rc); 76 free(buf); 77 return; 78 } 79 80 async_data_read_finalize(rcallid, buf, size); 81 82 free(buf); 83 async_answer_2(callid, EOK, EOK, rc /* nread */); 65 84 } 66 85 … … 68 87 ipc_call_t *call) 69 88 { 70 size_t size = IPC_GET_ARG1(*call); 89 void *data; 90 size_t size; 71 91 int rc; 92 93 rc = async_data_write_accept(&data, false, 0, 0, 0, &size); 94 if (rc != EOK) { 95 async_answer_0(callid, rc); 96 return; 97 } 72 98 73 99 if (srv->srvs->ops->write == NULL) { … … 76 102 } 77 103 78 if (size <= 3 * sizeof(sysarg_t)) { 79 const sysarg_t message[3] = { 80 IPC_GET_ARG2(*call), 81 IPC_GET_ARG3(*call), 82 IPC_GET_ARG4(*call) 83 }; 104 rc = srv->srvs->ops->write(srv, data, size); 105 free(data); 106 if (rc < 0) 107 async_answer_0(callid, rc); 84 108 85 rc = srv->srvs->ops->write(srv, (char *)message, size); 86 async_answer_0(callid, rc); 87 } else { 88 async_answer_0(callid, ELIMIT); 89 } 109 async_answer_2(callid, EOK, EOK, rc /* nwritten */); 90 110 } 91 111
Note:
See TracChangeset
for help on using the changeset viewer.