Changes in uspace/lib/drv/generic/remote_usbhc.c [6edd494:357a302] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
r6edd494 r357a302 1 1 /* 2 * Copyright (c) 2010 Vojtech Horky2 * Copyright (c) 2010-2011 Vojtech Horky 3 3 * All rights reserved. 4 4 * … … 33 33 */ 34 34 35 #include <ipc/ipc.h>36 35 #include <async.h> 37 36 #include <errno.h> … … 41 40 42 41 #define USB_MAX_PAYLOAD_SIZE 1020 43 44 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 45 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *); 42 #define HACK_MAX_PACKET_SIZE 8 43 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4 44 46 45 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 46 static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 51 static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *); 52 static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *); 53 static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 static void remote_usbhc_bulk_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_bulk_in(device_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *); 54 51 static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 55 52 static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); … … 61 58 /** Remote USB host controller interface operations. */ 62 59 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 63 remote_usbhc_get_address,64 65 remote_usbhc_get_buffer,66 67 60 remote_usbhc_reserve_default_address, 68 61 remote_usbhc_release_default_address, … … 75 68 remote_usbhc_interrupt_in, 76 69 77 remote_usbhc_control_write_setup, 78 remote_usbhc_control_write_data, 79 remote_usbhc_control_write_status, 80 81 remote_usbhc_control_read_setup, 82 remote_usbhc_control_read_data, 83 remote_usbhc_control_read_status 70 remote_usbhc_bulk_out, 71 remote_usbhc_bulk_in, 72 73 remote_usbhc_control_write, 74 remote_usbhc_control_read 84 75 }; 85 76 … … 94 85 typedef struct { 95 86 ipc_callid_t caller; 87 ipc_callid_t data_caller; 96 88 void *buffer; 89 void *setup_packet; 97 90 size_t size; 98 91 } async_transaction_t; 99 92 100 void remote_usbhc_get_address(device_t *device, void *iface, 101 ipc_callid_t callid, ipc_call_t *call) 102 { 103 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 104 105 if (!usb_iface->tell_address) { 106 ipc_answer_0(callid, ENOTSUP); 107 return; 108 } 109 110 devman_handle_t handle = DEV_IPC_GET_ARG1(*call); 93 static void async_transaction_destroy(async_transaction_t *trans) 94 { 95 if (trans == NULL) { 96 return; 97 } 98 99 if (trans->setup_packet != NULL) { 100 free(trans->setup_packet); 101 } 102 if (trans->buffer != NULL) { 103 free(trans->buffer); 104 } 105 106 free(trans); 107 } 108 109 static async_transaction_t *async_transaction_create(ipc_callid_t caller) 110 { 111 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 112 if (trans == NULL) { 113 return NULL; 114 } 115 116 trans->caller = caller; 117 trans->data_caller = 0; 118 trans->buffer = NULL; 119 trans->setup_packet = NULL; 120 trans->size = 0; 121 122 return trans; 123 } 124 125 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 126 ipc_callid_t callid, ipc_call_t *call) 127 { 128 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 129 130 if (!usb_iface->reserve_default_address) { 131 async_answer_0(callid, ENOTSUP); 132 return; 133 } 134 135 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 136 137 int rc = usb_iface->reserve_default_address(device, speed); 138 139 async_answer_0(callid, rc); 140 } 141 142 void remote_usbhc_release_default_address(device_t *device, void *iface, 143 ipc_callid_t callid, ipc_call_t *call) 144 { 145 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 146 147 if (!usb_iface->release_default_address) { 148 async_answer_0(callid, ENOTSUP); 149 return; 150 } 151 152 int rc = usb_iface->release_default_address(device); 153 154 async_answer_0(callid, rc); 155 } 156 157 void remote_usbhc_request_address(device_t *device, void *iface, 158 ipc_callid_t callid, ipc_call_t *call) 159 { 160 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 161 162 if (!usb_iface->request_address) { 163 async_answer_0(callid, ENOTSUP); 164 return; 165 } 166 167 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 111 168 112 169 usb_address_t address; 113 int rc = usb_iface-> tell_address(device, handle, &address);114 if (rc != EOK) { 115 ipc_answer_0(callid, rc);170 int rc = usb_iface->request_address(device, speed, &address); 171 if (rc != EOK) { 172 async_answer_0(callid, rc); 116 173 } else { 117 ipc_answer_1(callid, EOK, address); 118 } 119 } 120 121 void remote_usbhc_get_buffer(device_t *device, void *iface, 122 ipc_callid_t callid, ipc_call_t *call) 123 { 124 sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call); 125 async_transaction_t * trans = (async_transaction_t *)buffer_hash; 126 if (trans == NULL) { 127 ipc_answer_0(callid, ENOENT); 128 return; 129 } 130 if (trans->buffer == NULL) { 131 ipc_answer_0(callid, EINVAL); 132 free(trans); 133 return; 134 } 135 136 ipc_callid_t cid; 137 size_t accepted_size; 138 if (!async_data_read_receive(&cid, &accepted_size)) { 139 ipc_answer_0(callid, EINVAL); 140 return; 141 } 142 143 if (accepted_size > trans->size) { 144 accepted_size = trans->size; 145 } 146 async_data_read_finalize(cid, trans->buffer, accepted_size); 147 148 ipc_answer_1(callid, EOK, accepted_size); 149 150 free(trans->buffer); 151 free(trans); 152 } 153 154 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 155 ipc_callid_t callid, ipc_call_t *call) 156 { 157 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 158 159 if (!usb_iface->reserve_default_address) { 160 ipc_answer_0(callid, ENOTSUP); 161 return; 162 } 163 164 int rc = usb_iface->reserve_default_address(device); 165 166 ipc_answer_0(callid, rc); 167 } 168 169 void remote_usbhc_release_default_address(device_t *device, void *iface, 170 ipc_callid_t callid, ipc_call_t *call) 171 { 172 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 173 174 if (!usb_iface->release_default_address) { 175 ipc_answer_0(callid, ENOTSUP); 176 return; 177 } 178 179 int rc = usb_iface->release_default_address(device); 180 181 ipc_answer_0(callid, rc); 182 } 183 184 void remote_usbhc_request_address(device_t *device, void *iface, 185 ipc_callid_t callid, ipc_call_t *call) 186 { 187 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 188 189 if (!usb_iface->request_address) { 190 ipc_answer_0(callid, ENOTSUP); 191 return; 192 } 193 194 usb_address_t address; 195 int rc = usb_iface->request_address(device, &address); 196 if (rc != EOK) { 197 ipc_answer_0(callid, rc); 198 } else { 199 ipc_answer_1(callid, EOK, (sysarg_t) address); 174 async_answer_1(callid, EOK, (sysarg_t) address); 200 175 } 201 176 } … … 207 182 208 183 if (!usb_iface->bind_address) { 209 ipc_answer_0(callid, ENOTSUP);184 async_answer_0(callid, ENOTSUP); 210 185 return; 211 186 } … … 216 191 int rc = usb_iface->bind_address(device, address, handle); 217 192 218 ipc_answer_0(callid, rc);193 async_answer_0(callid, rc); 219 194 } 220 195 … … 225 200 226 201 if (!usb_iface->release_address) { 227 ipc_answer_0(callid, ENOTSUP);202 async_answer_0(callid, ENOTSUP); 228 203 return; 229 204 } … … 233 208 int rc = usb_iface->release_address(device, address); 234 209 235 ipc_answer_0(callid, rc);210 async_answer_0(callid, rc); 236 211 } 237 212 238 213 239 214 static void callback_out(device_t *device, 240 usb_transaction_outcome_t outcome, void *arg)215 int outcome, void *arg) 241 216 { 242 217 async_transaction_t *trans = (async_transaction_t *)arg; 243 218 244 // FIXME - answer according to outcome 245 ipc_answer_0(trans->caller, EOK); 246 247 free(trans); 219 async_answer_0(trans->caller, outcome); 220 221 async_transaction_destroy(trans); 248 222 } 249 223 250 224 static void callback_in(device_t *device, 251 usb_transaction_outcome_t outcome, size_t actual_size, void *arg)225 int outcome, size_t actual_size, void *arg) 252 226 { 253 227 async_transaction_t *trans = (async_transaction_t *)arg; 254 228 255 // FIXME - answer according to outcome 256 ipc_answer_1(trans->caller, EOK, (sysarg_t)trans); 229 if (outcome != EOK) { 230 async_answer_0(trans->caller, outcome); 231 if (trans->data_caller) { 232 async_answer_0(trans->data_caller, EINTR); 233 } 234 async_transaction_destroy(trans); 235 return; 236 } 257 237 258 238 trans->size = actual_size; 239 240 if (trans->data_caller) { 241 async_data_read_finalize(trans->data_caller, 242 trans->buffer, actual_size); 243 } 244 245 async_answer_0(trans->caller, EOK); 246 247 async_transaction_destroy(trans); 259 248 } 260 249 … … 271 260 { 272 261 if (!transfer_func) { 273 ipc_answer_0(callid, ENOTSUP);274 return; 275 } 276 277 size_t expected_len= DEV_IPC_GET_ARG3(*call);262 async_answer_0(callid, ENOTSUP); 263 return; 264 } 265 266 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 278 267 usb_target_t target = { 279 268 .address = DEV_IPC_GET_ARG1(*call), … … 283 272 size_t len = 0; 284 273 void *buffer = NULL; 285 if (expected_len > 0) { 286 int rc = async_data_write_accept(&buffer, false, 287 1, USB_MAX_PAYLOAD_SIZE, 288 0, &len); 289 290 if (rc != EOK) { 291 ipc_answer_0(callid, rc); 292 return; 293 } 294 } 295 296 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 297 trans->caller = callid; 298 trans->buffer = buffer; 299 trans->size = len; 300 301 int rc = transfer_func(device, target, buffer, len, 302 callback_out, trans); 303 304 if (rc != EOK) { 305 ipc_answer_0(callid, rc); 274 275 int rc = async_data_write_accept(&buffer, false, 276 1, USB_MAX_PAYLOAD_SIZE, 277 0, &len); 278 279 if (rc != EOK) { 280 async_answer_0(callid, rc); 281 return; 282 } 283 284 async_transaction_t *trans = async_transaction_create(callid); 285 if (trans == NULL) { 306 286 if (buffer != NULL) { 307 287 free(buffer); 308 288 } 309 free(trans); 289 async_answer_0(callid, ENOMEM); 290 return; 291 } 292 293 trans->buffer = buffer; 294 trans->size = len; 295 296 rc = transfer_func(device, target, max_packet_size, 297 buffer, len, 298 callback_out, trans); 299 300 if (rc != EOK) { 301 async_answer_0(callid, rc); 302 async_transaction_destroy(trans); 310 303 } 311 304 } … … 323 316 { 324 317 if (!transfer_func) { 325 ipc_answer_0(callid, ENOTSUP);326 return; 327 } 328 329 size_t len= DEV_IPC_GET_ARG3(*call);318 async_answer_0(callid, ENOTSUP); 319 return; 320 } 321 322 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 330 323 usb_target_t target = { 331 324 .address = DEV_IPC_GET_ARG1(*call), … … 333 326 }; 334 327 335 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 336 trans->caller = callid; 328 size_t len; 329 ipc_callid_t data_callid; 330 if (!async_data_read_receive(&data_callid, &len)) { 331 async_answer_0(callid, EPARTY); 332 return; 333 } 334 335 async_transaction_t *trans = async_transaction_create(callid); 336 if (trans == NULL) { 337 async_answer_0(callid, ENOMEM); 338 return; 339 } 340 trans->data_caller = data_callid; 337 341 trans->buffer = malloc(len); 338 342 trans->size = len; 339 343 340 int rc = transfer_func(device, target, trans->buffer, len, 344 int rc = transfer_func(device, target, max_packet_size, 345 trans->buffer, len, 341 346 callback_in, trans); 342 347 343 348 if (rc != EOK) { 344 ipc_answer_0(callid, rc); 345 free(trans->buffer); 346 free(trans); 347 } 348 } 349 350 /** Process status part of control transfer. 351 * 352 * @param device Target device. 353 * @param callid Initiating caller. 354 * @param call Initiating call. 355 * @param direction Transfer direction (read ~ in, write ~ out). 356 * @param transfer_in_func Transfer function for control read (might be NULL). 357 * @param transfer_out_func Transfer function for control write (might be NULL). 358 */ 359 static void remote_usbhc_status_transfer(device_t *device, 360 ipc_callid_t callid, ipc_call_t *call, 361 usb_direction_t direction, 362 int (*transfer_in_func)(device_t *, usb_target_t, 363 usbhc_iface_transfer_in_callback_t, void *), 364 int (*transfer_out_func)(device_t *, usb_target_t, 365 usbhc_iface_transfer_out_callback_t, void *)) 366 { 367 switch (direction) { 368 case USB_DIRECTION_IN: 369 if (!transfer_in_func) { 370 ipc_answer_0(callid, ENOTSUP); 371 return; 372 } 373 break; 374 case USB_DIRECTION_OUT: 375 if (!transfer_out_func) { 376 ipc_answer_0(callid, ENOTSUP); 377 return; 378 } 379 break; 380 default: 381 assert(false && "unreachable code"); 382 break; 349 async_answer_0(callid, rc); 350 async_transaction_destroy(trans); 351 } 352 } 353 354 void remote_usbhc_interrupt_out(device_t *device, void *iface, 355 ipc_callid_t callid, ipc_call_t *call) 356 { 357 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 358 assert(usb_iface != NULL); 359 360 return remote_usbhc_out_transfer(device, callid, call, 361 usb_iface->interrupt_out); 362 } 363 364 void remote_usbhc_interrupt_in(device_t *device, void *iface, 365 ipc_callid_t callid, ipc_call_t *call) 366 { 367 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 368 assert(usb_iface != NULL); 369 370 return remote_usbhc_in_transfer(device, callid, call, 371 usb_iface->interrupt_in); 372 } 373 374 void remote_usbhc_bulk_out(device_t *device, void *iface, 375 ipc_callid_t callid, ipc_call_t *call) 376 { 377 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 378 assert(usb_iface != NULL); 379 380 return remote_usbhc_out_transfer(device, callid, call, 381 usb_iface->bulk_out); 382 } 383 384 void remote_usbhc_bulk_in(device_t *device, void *iface, 385 ipc_callid_t callid, ipc_call_t *call) 386 { 387 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 388 assert(usb_iface != NULL); 389 390 return remote_usbhc_in_transfer(device, callid, call, 391 usb_iface->bulk_in); 392 } 393 394 void remote_usbhc_control_write(device_t *device, void *iface, 395 ipc_callid_t callid, ipc_call_t *call) 396 { 397 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 398 assert(usb_iface != NULL); 399 400 if (!usb_iface->control_write) { 401 async_answer_0(callid, ENOTSUP); 402 return; 383 403 } 384 404 … … 387 407 .endpoint = DEV_IPC_GET_ARG2(*call) 388 408 }; 389 390 async_transaction_t *trans = malloc(sizeof(async_transaction_t)); 391 trans->caller = callid; 392 trans->buffer = NULL; 393 trans->size = 0; 409 size_t data_buffer_len = DEV_IPC_GET_ARG3(*call); 410 size_t max_packet_size = DEV_IPC_GET_ARG4(*call); 394 411 395 412 int rc; 396 switch (direction) { 397 case USB_DIRECTION_IN: 398 rc = transfer_in_func(device, target, 399 callback_in, trans); 400 break; 401 case USB_DIRECTION_OUT: 402 rc = transfer_out_func(device, target, 403 callback_out, trans); 404 break; 405 default: 406 assert(false && "unreachable code"); 407 break; 408 } 409 410 if (rc != EOK) { 411 ipc_answer_0(callid, rc); 412 free(trans); 413 } 414 return; 415 } 416 417 418 void remote_usbhc_interrupt_out(device_t *device, void *iface, 419 ipc_callid_t callid, ipc_call_t *call) 413 414 void *setup_packet = NULL; 415 void *data_buffer = NULL; 416 size_t setup_packet_len = 0; 417 418 rc = async_data_write_accept(&setup_packet, false, 419 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 420 if (rc != EOK) { 421 async_answer_0(callid, rc); 422 return; 423 } 424 425 if (data_buffer_len > 0) { 426 rc = async_data_write_accept(&data_buffer, false, 427 1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len); 428 if (rc != EOK) { 429 async_answer_0(callid, rc); 430 free(setup_packet); 431 return; 432 } 433 } 434 435 async_transaction_t *trans = async_transaction_create(callid); 436 if (trans == NULL) { 437 async_answer_0(callid, ENOMEM); 438 free(setup_packet); 439 free(data_buffer); 440 return; 441 } 442 trans->setup_packet = setup_packet; 443 trans->buffer = data_buffer; 444 trans->size = data_buffer_len; 445 446 rc = usb_iface->control_write(device, target, max_packet_size, 447 setup_packet, setup_packet_len, 448 data_buffer, data_buffer_len, 449 callback_out, trans); 450 451 if (rc != EOK) { 452 async_answer_0(callid, rc); 453 async_transaction_destroy(trans); 454 } 455 } 456 457 458 void remote_usbhc_control_read(device_t *device, void *iface, 459 ipc_callid_t callid, ipc_call_t *call) 420 460 { 421 461 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 422 462 assert(usb_iface != NULL); 423 463 424 return remote_usbhc_out_transfer(device, callid, call, 425 usb_iface->interrupt_out); 426 } 427 428 void remote_usbhc_interrupt_in(device_t *device, void *iface, 429 ipc_callid_t callid, ipc_call_t *call) 430 { 431 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 432 assert(usb_iface != NULL); 433 434 return remote_usbhc_in_transfer(device, callid, call, 435 usb_iface->interrupt_in); 436 } 437 438 void remote_usbhc_control_write_setup(device_t *device, void *iface, 439 ipc_callid_t callid, ipc_call_t *call) 440 { 441 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 442 assert(usb_iface != NULL); 443 444 return remote_usbhc_out_transfer(device, callid, call, 445 usb_iface->control_write_setup); 446 } 447 448 void remote_usbhc_control_write_data(device_t *device, void *iface, 449 ipc_callid_t callid, ipc_call_t *call) 450 { 451 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 452 assert(usb_iface != NULL); 453 454 return remote_usbhc_out_transfer(device, callid, call, 455 usb_iface->control_write_data); 456 } 457 458 void remote_usbhc_control_write_status(device_t *device, void *iface, 459 ipc_callid_t callid, ipc_call_t *call) 460 { 461 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 462 assert(usb_iface != NULL); 463 464 return remote_usbhc_status_transfer(device, callid, call, 465 USB_DIRECTION_IN, usb_iface->control_write_status, NULL); 466 } 467 468 void remote_usbhc_control_read_setup(device_t *device, void *iface, 469 ipc_callid_t callid, ipc_call_t *call) 470 { 471 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 472 assert(usb_iface != NULL); 473 474 return remote_usbhc_out_transfer(device, callid, call, 475 usb_iface->control_read_setup); 476 } 477 478 void remote_usbhc_control_read_data(device_t *device, void *iface, 479 ipc_callid_t callid, ipc_call_t *call) 480 { 481 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 482 assert(usb_iface != NULL); 483 484 return remote_usbhc_in_transfer(device, callid, call, 485 usb_iface->control_read_data); 486 } 487 488 void remote_usbhc_control_read_status(device_t *device, void *iface, 489 ipc_callid_t callid, ipc_call_t *call) 490 { 491 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 492 assert(usb_iface != NULL); 493 494 return remote_usbhc_status_transfer(device, callid, call, 495 USB_DIRECTION_OUT, NULL, usb_iface->control_read_status); 464 if (!usb_iface->control_read) { 465 async_answer_0(callid, ENOTSUP); 466 return; 467 } 468 469 usb_target_t target = { 470 .address = DEV_IPC_GET_ARG1(*call), 471 .endpoint = DEV_IPC_GET_ARG2(*call) 472 }; 473 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 474 475 int rc; 476 477 void *setup_packet = NULL; 478 size_t setup_packet_len = 0; 479 size_t data_len = 0; 480 481 rc = async_data_write_accept(&setup_packet, false, 482 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 483 if (rc != EOK) { 484 async_answer_0(callid, rc); 485 return; 486 } 487 488 ipc_callid_t data_callid; 489 if (!async_data_read_receive(&data_callid, &data_len)) { 490 async_answer_0(callid, EPARTY); 491 free(setup_packet); 492 return; 493 } 494 495 async_transaction_t *trans = async_transaction_create(callid); 496 if (trans == NULL) { 497 async_answer_0(callid, ENOMEM); 498 free(setup_packet); 499 return; 500 } 501 trans->data_caller = data_callid; 502 trans->setup_packet = setup_packet; 503 trans->size = data_len; 504 trans->buffer = malloc(data_len); 505 if (trans->buffer == NULL) { 506 async_answer_0(callid, ENOMEM); 507 async_transaction_destroy(trans); 508 return; 509 } 510 511 rc = usb_iface->control_read(device, target, max_packet_size, 512 setup_packet, setup_packet_len, 513 trans->buffer, trans->size, 514 callback_in, trans); 515 516 if (rc != EOK) { 517 async_answer_0(callid, rc); 518 async_transaction_destroy(trans); 519 } 496 520 } 497 521
Note:
See TracChangeset
for help on using the changeset viewer.