Changeset d14688d in mainline
- Timestamp:
- 2018-02-05T00:54:08Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 65c059f
- Parents:
- fdc2253b
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-02-02 14:46:29)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-02-05 00:54:08)
- Location:
- uspace
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/usbinfo/Makefile
rfdc2253b rd14688d 30 30 BINARY = usbinfo 31 31 32 LIBS = usb usbhid usbdevdrv32 LIBS = usbhid usbdev usb drv 33 33 34 34 SOURCES = \ -
uspace/lib/usbdev/src/pipes.c
rfdc2253b rd14688d 61 61 } 62 62 63 typedef struct { 64 usb_pipe_t *pipe; 65 usb_direction_t dir; 66 bool is_control; 67 uint64_t setup; 68 void *buffer; 69 size_t buffer_size; 70 size_t transferred_size; 71 } transfer_t; 72 73 /** 74 * Issue a transfer in a separate exchange. 75 */ 76 static errno_t transfer_common(transfer_t *t) 77 { 78 async_exch_t *exch = async_exchange_begin(t->pipe->bus_session); 79 if (!exch) 80 return ENOMEM; 81 82 const errno_t rc = usbhc_transfer(exch, t->pipe->desc.endpoint_no, 83 t->dir, t->setup, t->buffer, t->buffer_size, &t->transferred_size); 84 85 async_exchange_end(exch); 86 87 if (rc == ESTALL) 88 clear_self_endpoint_halt(t->pipe); 89 90 return rc; 91 } 92 93 /** 94 * Compatibility wrapper for reads/writes without preallocated buffer. 95 */ 96 static errno_t transfer_wrap_dma(transfer_t *t) 97 { 98 void *orig_buffer = t->buffer; 99 t->buffer = usb_pipe_alloc_buffer(t->pipe, t->buffer_size); 100 101 if (t->dir == USB_DIRECTION_OUT) 102 memcpy(t->buffer, orig_buffer, t->buffer_size); 103 104 const errno_t err = transfer_common(t); 105 106 if (!err && t->dir == USB_DIRECTION_IN) 107 memcpy(orig_buffer, t->buffer, t->transferred_size); 108 109 usb_pipe_free_buffer(t->pipe, t->buffer); 110 t->buffer = orig_buffer; 111 return err; 112 } 113 114 static errno_t transfer_check(const transfer_t *t) 115 { 116 if (!t->pipe) 117 return EBADMEM; 118 119 /* Only control writes make sense without buffer */ 120 if ((t->dir != USB_DIRECTION_OUT || !t->is_control) 121 && (t->buffer == NULL || t->buffer_size == 0)) 122 return EINVAL; 123 124 /* Nonzero size requires buffer */ 125 if (t->buffer == NULL && t->buffer_size != 0) 126 return EINVAL; 127 128 /* Check expected direction */ 129 if (t->pipe->desc.direction != USB_DIRECTION_BOTH && 130 t->pipe->desc.direction != t->dir) 131 return EBADF; 132 133 /* Check expected transfer type */ 134 if ((t->pipe->desc.transfer_type == USB_TRANSFER_CONTROL) != t->is_control) 135 return EBADF; 136 137 return EOK; 138 } 139 140 static errno_t prepare_control(transfer_t *t, const void *setup, size_t setup_size) 141 { 142 if ((setup == NULL) || (setup_size != 8)) 143 return EINVAL; 144 145 memcpy(&t->setup, setup, 8); 146 return EOK; 147 } 148 63 149 /** Request a control read transfer on an endpoint pipe. 64 150 * … … 78 164 void *buffer, size_t buffer_size, size_t *transferred_size) 79 165 { 80 assert(pipe); 81 82 if ((setup_buffer == NULL) || (setup_buffer_size != 8)) { 83 return EINVAL; 84 } 85 86 if ((buffer == NULL) || (buffer_size == 0)) { 87 return EINVAL; 88 } 89 90 if ((pipe->desc.direction != USB_DIRECTION_BOTH) 91 || (pipe->desc.transfer_type != USB_TRANSFER_CONTROL)) { 92 return EBADF; 93 } 94 95 uint64_t setup_packet; 96 memcpy(&setup_packet, setup_buffer, 8); 97 98 async_exch_t *exch = async_exchange_begin(pipe->bus_session); 99 size_t act_size = 0; 100 const errno_t rc = usbhc_read(exch, pipe->desc.endpoint_no, setup_packet, buffer, 101 buffer_size, &act_size); 102 async_exchange_end(exch); 103 104 if (rc == ESTALL) { 105 clear_self_endpoint_halt(pipe); 106 } 107 108 if (rc == EOK && transferred_size != NULL) { 109 *transferred_size = act_size; 110 } 111 112 return rc; 166 errno_t err; 167 transfer_t transfer = { 168 .pipe = pipe, 169 .dir = USB_DIRECTION_IN, 170 .is_control = true, 171 .buffer = buffer, 172 .buffer_size = buffer_size 173 }; 174 175 if ((err = transfer_check(&transfer))) 176 return err; 177 178 if ((err = prepare_control(&transfer, setup_buffer, setup_buffer_size))) 179 return err; 180 181 if ((err = transfer_wrap_dma(&transfer))) 182 return err; 183 184 if (transferred_size) 185 *transferred_size = transfer.transferred_size; 186 187 return EOK; 113 188 } 114 189 … … 129 204 { 130 205 assert(pipe); 131 132 if ((setup_buffer == NULL) || (setup_buffer_size != 8)) { 133 return EINVAL; 134 } 135 136 if ((buffer == NULL) && (buffer_size > 0)) { 137 return EINVAL; 138 } 139 140 if ((buffer != NULL) && (buffer_size == 0)) { 141 return EINVAL; 142 } 143 144 if ((pipe->desc.direction != USB_DIRECTION_BOTH) 145 || (pipe->desc.transfer_type != USB_TRANSFER_CONTROL)) { 146 return EBADF; 147 } 148 149 uint64_t setup_packet; 150 memcpy(&setup_packet, setup_buffer, 8); 151 152 async_exch_t *exch = async_exchange_begin(pipe->bus_session); 153 const errno_t rc = usbhc_write(exch, 154 pipe->desc.endpoint_no, setup_packet, buffer, buffer_size); 155 async_exchange_end(exch); 156 157 if (rc == ESTALL) { 158 clear_self_endpoint_halt(pipe); 159 } 160 161 return rc; 206 errno_t err; 207 transfer_t transfer = { 208 .pipe = pipe, 209 .dir = USB_DIRECTION_OUT, 210 .is_control = true, 211 .buffer = (void *) buffer, 212 .buffer_size = buffer_size 213 }; 214 215 if ((err = transfer_check(&transfer))) 216 return err; 217 218 if ((err = prepare_control(&transfer, setup_buffer, setup_buffer_size))) 219 return err; 220 221 return transfer_wrap_dma(&transfer); 162 222 } 163 223 … … 197 257 { 198 258 assert(pipe); 199 200 if (buffer == NULL) { 201 return EINVAL; 202 } 203 204 if (size == 0) { 205 return EINVAL; 206 } 207 208 if (pipe->desc.direction != USB_DIRECTION_IN) { 209 return EBADF; 210 } 211 212 if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) { 213 return EBADF; 214 } 215 216 async_exch_t *exch = async_exchange_begin(pipe->bus_session); 217 size_t act_size = 0; 218 const errno_t rc = 219 usbhc_read(exch, pipe->desc.endpoint_no, 0, buffer, size, &act_size); 220 async_exchange_end(exch); 221 222 if (rc == EOK && size_transferred != NULL) { 223 *size_transferred = act_size; 224 } 225 226 return rc; 259 errno_t err; 260 transfer_t transfer = { 261 .pipe = pipe, 262 .dir = USB_DIRECTION_IN, 263 .buffer = buffer, 264 .buffer_size = size, 265 }; 266 267 if ((err = transfer_check(&transfer))) 268 return err; 269 270 if ((err = transfer_wrap_dma(&transfer))) 271 return err; 272 273 if (size_transferred) 274 *size_transferred = transfer.transferred_size; 275 276 return EOK; 227 277 } 228 278 … … 237 287 { 238 288 assert(pipe); 239 240 if (buffer == NULL || size == 0) { 241 return EINVAL; 242 } 243 244 if (pipe->desc.direction != USB_DIRECTION_OUT) { 245 return EBADF; 246 } 247 248 if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) { 249 return EBADF; 250 } 251 252 async_exch_t *exch = async_exchange_begin(pipe->bus_session); 253 const errno_t rc = usbhc_write(exch, pipe->desc.endpoint_no, 0, buffer, size); 254 async_exchange_end(exch); 255 return rc; 289 errno_t err; 290 transfer_t transfer = { 291 .pipe = pipe, 292 .dir = USB_DIRECTION_OUT, 293 .buffer = (void *) buffer, 294 .buffer_size = size 295 }; 296 297 if ((err = transfer_check(&transfer))) 298 return err; 299 300 if ((err = transfer_wrap_dma(&transfer))) 301 return err; 302 303 return EOK; 256 304 } 257 305 … … 270 318 { 271 319 assert(pipe); 272 273 if (buffer == NULL || size == 0) 274 return EINVAL; 275 276 if (pipe->desc.direction != USB_DIRECTION_IN 277 || pipe->desc.transfer_type == USB_TRANSFER_CONTROL) 278 return EBADF; 279 280 async_exch_t *exch = async_exchange_begin(pipe->bus_session); 281 if (!exch) 282 return ENOMEM; 283 284 const errno_t rc = usbhc_transfer(exch, pipe->desc.endpoint_no, 285 USB_DIRECTION_IN, 0, buffer, size, size_transferred); 286 async_exchange_end(exch); 287 return rc; 320 errno_t err; 321 transfer_t transfer = { 322 .pipe = pipe, 323 .dir = USB_DIRECTION_IN, 324 .buffer = buffer, 325 .buffer_size = size 326 }; 327 328 if ((err = transfer_check(&transfer))) 329 return err; 330 331 if ((err = transfer_common(&transfer))) 332 return err; 333 334 if (size_transferred) 335 *size_transferred = transfer.transferred_size; 336 337 return EOK; 288 338 } 289 339 … … 300 350 { 301 351 assert(pipe); 302 303 if (buffer == NULL || size == 0) { 304 return EINVAL; 305 } 306 307 if (pipe->desc.direction != USB_DIRECTION_OUT 308 || pipe->desc.transfer_type == USB_TRANSFER_CONTROL) 309 return EBADF; 310 311 async_exch_t *exch = async_exchange_begin(pipe->bus_session); 312 if (!exch) 313 return ENOMEM; 314 315 const errno_t rc = usbhc_transfer(exch, pipe->desc.endpoint_no, USB_DIRECTION_OUT, 0, buffer, size, NULL); 316 async_exchange_end(exch); 317 return rc; 352 errno_t err; 353 transfer_t transfer = { 354 .pipe = pipe, 355 .dir = USB_DIRECTION_OUT, 356 .buffer = buffer, 357 .buffer_size = size 358 }; 359 360 if ((err = transfer_check(&transfer))) 361 return err; 362 363 if ((err = transfer_common(&transfer))) 364 return err; 365 366 return EOK; 318 367 } 319 368
Note:
See TracChangeset
for help on using the changeset viewer.