Changeset 92574f4 in mainline for uspace/lib/drv/generic/remote_usbhc.c
- Timestamp:
- 2011-02-24T12:03:27Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e7b7ebd5
- Parents:
- 4837092 (diff), a80849c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/drv/generic/remote_usbhc.c
r4837092 r92574f4 33 33 */ 34 34 35 #include <ipc/ipc.h>36 35 #include <async.h> 37 36 #include <errno.h> 37 #include <assert.h> 38 38 39 39 #include "usbhc_iface.h" 40 #include "d river.h"40 #include "ddf/driver.h" 41 41 42 42 #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 *); 46 static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *); 47 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 *); 54 static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *); 55 static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *); 56 static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 57 static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 58 static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 59 static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 60 static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *); 61 //static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *); 43 #define HACK_MAX_PACKET_SIZE 8 44 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4 45 46 static void remote_usbhc_interrupt_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 47 static void remote_usbhc_interrupt_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 48 static void remote_usbhc_bulk_out(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 49 static void remote_usbhc_bulk_in(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 50 static void remote_usbhc_control_write(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 51 static void remote_usbhc_control_read(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 52 static void remote_usbhc_reserve_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 53 static void remote_usbhc_release_default_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 54 static void remote_usbhc_request_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 55 static void remote_usbhc_bind_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 56 static void remote_usbhc_release_address(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 57 //static void remote_usbhc(ddf_fun_t *, void *, ipc_callid_t, ipc_call_t *); 62 58 63 59 /** Remote USB host controller interface operations. */ 64 60 static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = { 65 remote_usbhc_get_address,66 67 remote_usbhc_get_buffer,68 69 61 remote_usbhc_reserve_default_address, 70 62 remote_usbhc_release_default_address, … … 77 69 remote_usbhc_interrupt_in, 78 70 79 remote_usbhc_control_write_setup, 80 remote_usbhc_control_write_data, 81 remote_usbhc_control_write_status, 82 83 remote_usbhc_control_read_setup, 84 remote_usbhc_control_read_data, 85 remote_usbhc_control_read_status, 71 remote_usbhc_bulk_out, 72 remote_usbhc_bulk_in, 86 73 87 74 remote_usbhc_control_write, … … 99 86 typedef struct { 100 87 ipc_callid_t caller; 88 ipc_callid_t data_caller; 101 89 void *buffer; 102 90 void *setup_packet; … … 128 116 129 117 trans->caller = caller; 118 trans->data_caller = 0; 130 119 trans->buffer = NULL; 131 120 trans->setup_packet = NULL; … … 135 124 } 136 125 137 void remote_usbhc_get_address(device_t *device, void *iface, 138 ipc_callid_t callid, ipc_call_t *call) 139 { 140 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 141 142 if (!usb_iface->tell_address) { 143 ipc_answer_0(callid, ENOTSUP); 144 return; 145 } 146 147 devman_handle_t handle = DEV_IPC_GET_ARG1(*call); 126 void remote_usbhc_reserve_default_address(ddf_fun_t *fun, void *iface, 127 ipc_callid_t callid, ipc_call_t *call) 128 { 129 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 130 131 if (!usb_iface->reserve_default_address) { 132 async_answer_0(callid, ENOTSUP); 133 return; 134 } 135 136 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 137 138 int rc = usb_iface->reserve_default_address(fun, speed); 139 140 async_answer_0(callid, rc); 141 } 142 143 void remote_usbhc_release_default_address(ddf_fun_t *fun, void *iface, 144 ipc_callid_t callid, ipc_call_t *call) 145 { 146 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 147 148 if (!usb_iface->release_default_address) { 149 async_answer_0(callid, ENOTSUP); 150 return; 151 } 152 153 int rc = usb_iface->release_default_address(fun); 154 155 async_answer_0(callid, rc); 156 } 157 158 void remote_usbhc_request_address(ddf_fun_t *fun, void *iface, 159 ipc_callid_t callid, ipc_call_t *call) 160 { 161 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 162 163 if (!usb_iface->request_address) { 164 async_answer_0(callid, ENOTSUP); 165 return; 166 } 167 168 usb_speed_t speed = DEV_IPC_GET_ARG1(*call); 148 169 149 170 usb_address_t address; 150 int rc = usb_iface-> tell_address(device, handle, &address);151 if (rc != EOK) { 152 ipc_answer_0(callid, rc);171 int rc = usb_iface->request_address(fun, speed, &address); 172 if (rc != EOK) { 173 async_answer_0(callid, rc); 153 174 } else { 154 ipc_answer_1(callid, EOK, address); 155 } 156 } 157 158 void remote_usbhc_get_buffer(device_t *device, void *iface, 159 ipc_callid_t callid, ipc_call_t *call) 160 { 161 sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call); 162 async_transaction_t * trans = (async_transaction_t *)buffer_hash; 163 if (trans == NULL) { 164 ipc_answer_0(callid, ENOENT); 165 return; 166 } 167 if (trans->buffer == NULL) { 168 ipc_answer_0(callid, EINVAL); 169 async_transaction_destroy(trans); 170 return; 171 } 172 173 ipc_callid_t cid; 174 size_t accepted_size; 175 if (!async_data_read_receive(&cid, &accepted_size)) { 176 ipc_answer_0(callid, EINVAL); 177 async_transaction_destroy(trans); 178 return; 179 } 180 181 if (accepted_size > trans->size) { 182 accepted_size = trans->size; 183 } 184 async_data_read_finalize(cid, trans->buffer, accepted_size); 185 186 ipc_answer_1(callid, EOK, accepted_size); 187 188 async_transaction_destroy(trans); 189 } 190 191 void remote_usbhc_reserve_default_address(device_t *device, void *iface, 192 ipc_callid_t callid, ipc_call_t *call) 193 { 194 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 195 196 if (!usb_iface->reserve_default_address) { 197 ipc_answer_0(callid, ENOTSUP); 198 return; 199 } 200 201 int rc = usb_iface->reserve_default_address(device); 202 203 ipc_answer_0(callid, rc); 204 } 205 206 void remote_usbhc_release_default_address(device_t *device, void *iface, 207 ipc_callid_t callid, ipc_call_t *call) 208 { 209 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 210 211 if (!usb_iface->release_default_address) { 212 ipc_answer_0(callid, ENOTSUP); 213 return; 214 } 215 216 int rc = usb_iface->release_default_address(device); 217 218 ipc_answer_0(callid, rc); 219 } 220 221 void remote_usbhc_request_address(device_t *device, void *iface, 222 ipc_callid_t callid, ipc_call_t *call) 223 { 224 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 225 226 if (!usb_iface->request_address) { 227 ipc_answer_0(callid, ENOTSUP); 228 return; 229 } 230 231 usb_address_t address; 232 int rc = usb_iface->request_address(device, &address); 233 if (rc != EOK) { 234 ipc_answer_0(callid, rc); 235 } else { 236 ipc_answer_1(callid, EOK, (sysarg_t) address); 237 } 238 } 239 240 void remote_usbhc_bind_address(device_t *device, void *iface, 175 async_answer_1(callid, EOK, (sysarg_t) address); 176 } 177 } 178 179 void remote_usbhc_bind_address(ddf_fun_t *fun, void *iface, 241 180 ipc_callid_t callid, ipc_call_t *call) 242 181 { … … 244 183 245 184 if (!usb_iface->bind_address) { 246 ipc_answer_0(callid, ENOTSUP);185 async_answer_0(callid, ENOTSUP); 247 186 return; 248 187 } … … 251 190 devman_handle_t handle = (devman_handle_t) DEV_IPC_GET_ARG2(*call); 252 191 253 int rc = usb_iface->bind_address( device, address, handle);254 255 ipc_answer_0(callid, rc);256 } 257 258 void remote_usbhc_release_address(d evice_t *device, void *iface,192 int rc = usb_iface->bind_address(fun, address, handle); 193 194 async_answer_0(callid, rc); 195 } 196 197 void remote_usbhc_release_address(ddf_fun_t *fun, void *iface, 259 198 ipc_callid_t callid, ipc_call_t *call) 260 199 { … … 262 201 263 202 if (!usb_iface->release_address) { 264 ipc_answer_0(callid, ENOTSUP);203 async_answer_0(callid, ENOTSUP); 265 204 return; 266 205 } … … 268 207 usb_address_t address = (usb_address_t) DEV_IPC_GET_ARG1(*call); 269 208 270 int rc = usb_iface->release_address( device, address);271 272 ipc_answer_0(callid, rc);273 } 274 275 276 static void callback_out(d evice_t *device,277 usb_transaction_outcome_t outcome, void *arg)209 int rc = usb_iface->release_address(fun, address); 210 211 async_answer_0(callid, rc); 212 } 213 214 215 static void callback_out(ddf_fun_t *fun, 216 int outcome, void *arg) 278 217 { 279 218 async_transaction_t *trans = (async_transaction_t *)arg; 280 219 281 ipc_answer_0(trans->caller, outcome);220 async_answer_0(trans->caller, outcome); 282 221 283 222 async_transaction_destroy(trans); 284 223 } 285 224 286 static void callback_in(d evice_t *device,287 usb_transaction_outcome_t outcome, size_t actual_size, void *arg)225 static void callback_in(ddf_fun_t *fun, 226 int outcome, size_t actual_size, void *arg) 288 227 { 289 228 async_transaction_t *trans = (async_transaction_t *)arg; 290 229 291 if (outcome != USB_OUTCOME_OK) { 292 ipc_answer_0(trans->caller, outcome); 230 if (outcome != EOK) { 231 async_answer_0(trans->caller, outcome); 232 if (trans->data_caller) { 233 async_answer_0(trans->data_caller, EINTR); 234 } 293 235 async_transaction_destroy(trans); 294 236 return; … … 296 238 297 239 trans->size = actual_size; 298 ipc_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans); 240 241 if (trans->data_caller) { 242 async_data_read_finalize(trans->data_caller, 243 trans->buffer, actual_size); 244 } 245 246 async_answer_0(trans->caller, EOK); 247 248 async_transaction_destroy(trans); 299 249 } 300 250 … … 306 256 * @param transfer_func Transfer function (might be NULL). 307 257 */ 308 static void remote_usbhc_out_transfer(d evice_t *device,258 static void remote_usbhc_out_transfer(ddf_fun_t *fun, 309 259 ipc_callid_t callid, ipc_call_t *call, 310 260 usbhc_iface_transfer_out_t transfer_func) 311 261 { 312 262 if (!transfer_func) { 313 ipc_answer_0(callid, ENOTSUP);314 return; 315 } 316 317 size_t expected_len= DEV_IPC_GET_ARG3(*call);263 async_answer_0(callid, ENOTSUP); 264 return; 265 } 266 267 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 318 268 usb_target_t target = { 319 269 .address = DEV_IPC_GET_ARG1(*call), … … 323 273 size_t len = 0; 324 274 void *buffer = NULL; 325 if (expected_len > 0) { 326 int rc = async_data_write_accept(&buffer, false, 327 1, USB_MAX_PAYLOAD_SIZE, 328 0, &len); 329 330 if (rc != EOK) { 331 ipc_answer_0(callid, rc); 332 return; 333 } 275 276 int rc = async_data_write_accept(&buffer, false, 277 1, USB_MAX_PAYLOAD_SIZE, 278 0, &len); 279 280 if (rc != EOK) { 281 async_answer_0(callid, rc); 282 return; 334 283 } 335 284 … … 339 288 free(buffer); 340 289 } 341 ipc_answer_0(callid, ENOMEM);290 async_answer_0(callid, ENOMEM); 342 291 return; 343 292 } … … 346 295 trans->size = len; 347 296 348 int rc = transfer_func(device, target, buffer, len, 297 rc = transfer_func(fun, target, max_packet_size, 298 buffer, len, 349 299 callback_out, trans); 350 300 351 301 if (rc != EOK) { 352 ipc_answer_0(callid, rc);302 async_answer_0(callid, rc); 353 303 async_transaction_destroy(trans); 354 304 } … … 362 312 * @param transfer_func Transfer function (might be NULL). 363 313 */ 364 static void remote_usbhc_in_transfer(d evice_t *device,314 static void remote_usbhc_in_transfer(ddf_fun_t *fun, 365 315 ipc_callid_t callid, ipc_call_t *call, 366 316 usbhc_iface_transfer_in_t transfer_func) 367 317 { 368 318 if (!transfer_func) { 369 ipc_answer_0(callid, ENOTSUP);370 return; 371 } 372 373 size_t len= DEV_IPC_GET_ARG3(*call);319 async_answer_0(callid, ENOTSUP); 320 return; 321 } 322 323 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 374 324 usb_target_t target = { 375 325 .address = DEV_IPC_GET_ARG1(*call), … … 377 327 }; 378 328 329 size_t len; 330 ipc_callid_t data_callid; 331 if (!async_data_read_receive(&data_callid, &len)) { 332 async_answer_0(callid, EPARTY); 333 return; 334 } 335 379 336 async_transaction_t *trans = async_transaction_create(callid); 380 337 if (trans == NULL) { 381 ipc_answer_0(callid, ENOMEM); 382 return; 383 } 338 async_answer_0(callid, ENOMEM); 339 return; 340 } 341 trans->data_caller = data_callid; 384 342 trans->buffer = malloc(len); 385 343 trans->size = len; 386 344 387 int rc = transfer_func(device, target, trans->buffer, len, 345 int rc = transfer_func(fun, target, max_packet_size, 346 trans->buffer, len, 388 347 callback_in, trans); 389 348 390 349 if (rc != EOK) { 391 ipc_answer_0(callid, rc);350 async_answer_0(callid, rc); 392 351 async_transaction_destroy(trans); 393 352 } 394 353 } 395 354 396 /** Process status part of control transfer. 397 * 398 * @param device Target device. 399 * @param callid Initiating caller. 400 * @param call Initiating call. 401 * @param direction Transfer direction (read ~ in, write ~ out). 402 * @param transfer_in_func Transfer function for control read (might be NULL). 403 * @param transfer_out_func Transfer function for control write (might be NULL). 404 */ 405 static void remote_usbhc_status_transfer(device_t *device, 406 ipc_callid_t callid, ipc_call_t *call, 407 usb_direction_t direction, 408 int (*transfer_in_func)(device_t *, usb_target_t, 409 usbhc_iface_transfer_in_callback_t, void *), 410 int (*transfer_out_func)(device_t *, usb_target_t, 411 usbhc_iface_transfer_out_callback_t, void *)) 412 { 413 switch (direction) { 414 case USB_DIRECTION_IN: 415 if (!transfer_in_func) { 416 ipc_answer_0(callid, ENOTSUP); 417 return; 418 } 419 break; 420 case USB_DIRECTION_OUT: 421 if (!transfer_out_func) { 422 ipc_answer_0(callid, ENOTSUP); 423 return; 424 } 425 break; 426 default: 427 assert(false && "unreachable code"); 428 break; 355 void remote_usbhc_interrupt_out(ddf_fun_t *fun, void *iface, 356 ipc_callid_t callid, ipc_call_t *call) 357 { 358 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 359 assert(usb_iface != NULL); 360 361 return remote_usbhc_out_transfer(fun, callid, call, 362 usb_iface->interrupt_out); 363 } 364 365 void remote_usbhc_interrupt_in(ddf_fun_t *fun, void *iface, 366 ipc_callid_t callid, ipc_call_t *call) 367 { 368 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 369 assert(usb_iface != NULL); 370 371 return remote_usbhc_in_transfer(fun, callid, call, 372 usb_iface->interrupt_in); 373 } 374 375 void remote_usbhc_bulk_out(ddf_fun_t *fun, void *iface, 376 ipc_callid_t callid, ipc_call_t *call) 377 { 378 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 379 assert(usb_iface != NULL); 380 381 return remote_usbhc_out_transfer(fun, callid, call, 382 usb_iface->bulk_out); 383 } 384 385 void remote_usbhc_bulk_in(ddf_fun_t *fun, void *iface, 386 ipc_callid_t callid, ipc_call_t *call) 387 { 388 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 389 assert(usb_iface != NULL); 390 391 return remote_usbhc_in_transfer(fun, callid, call, 392 usb_iface->bulk_in); 393 } 394 395 void remote_usbhc_control_write(ddf_fun_t *fun, void *iface, 396 ipc_callid_t callid, ipc_call_t *call) 397 { 398 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 399 assert(usb_iface != NULL); 400 401 if (!usb_iface->control_write) { 402 async_answer_0(callid, ENOTSUP); 403 return; 429 404 } 430 405 … … 433 408 .endpoint = DEV_IPC_GET_ARG2(*call) 434 409 }; 410 size_t data_buffer_len = DEV_IPC_GET_ARG3(*call); 411 size_t max_packet_size = DEV_IPC_GET_ARG4(*call); 412 413 int rc; 414 415 void *setup_packet = NULL; 416 void *data_buffer = NULL; 417 size_t setup_packet_len = 0; 418 419 rc = async_data_write_accept(&setup_packet, false, 420 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 421 if (rc != EOK) { 422 async_answer_0(callid, rc); 423 return; 424 } 425 426 if (data_buffer_len > 0) { 427 rc = async_data_write_accept(&data_buffer, false, 428 1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len); 429 if (rc != EOK) { 430 async_answer_0(callid, rc); 431 free(setup_packet); 432 return; 433 } 434 } 435 435 436 436 async_transaction_t *trans = async_transaction_create(callid); 437 437 if (trans == NULL) { 438 ipc_answer_0(callid, ENOMEM); 439 return; 440 } 441 442 int rc; 443 switch (direction) { 444 case USB_DIRECTION_IN: 445 rc = transfer_in_func(device, target, 446 callback_in, trans); 447 break; 448 case USB_DIRECTION_OUT: 449 rc = transfer_out_func(device, target, 450 callback_out, trans); 451 break; 452 default: 453 assert(false && "unreachable code"); 454 break; 455 } 456 457 if (rc != EOK) { 458 ipc_answer_0(callid, rc); 438 async_answer_0(callid, ENOMEM); 439 free(setup_packet); 440 free(data_buffer); 441 return; 442 } 443 trans->setup_packet = setup_packet; 444 trans->buffer = data_buffer; 445 trans->size = data_buffer_len; 446 447 rc = usb_iface->control_write(fun, target, max_packet_size, 448 setup_packet, setup_packet_len, 449 data_buffer, data_buffer_len, 450 callback_out, trans); 451 452 if (rc != EOK) { 453 async_answer_0(callid, rc); 459 454 async_transaction_destroy(trans); 460 455 } … … 462 457 463 458 464 void remote_usbhc_ interrupt_out(device_t *device, void *iface,465 459 void remote_usbhc_control_read(ddf_fun_t *fun, void *iface, 460 ipc_callid_t callid, ipc_call_t *call) 466 461 { 467 462 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 468 463 assert(usb_iface != NULL); 469 464 470 return remote_usbhc_out_transfer(device, callid, call, 471 usb_iface->interrupt_out); 472 } 473 474 void remote_usbhc_interrupt_in(device_t *device, void *iface, 475 ipc_callid_t callid, ipc_call_t *call) 476 { 477 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 478 assert(usb_iface != NULL); 479 480 return remote_usbhc_in_transfer(device, callid, call, 481 usb_iface->interrupt_in); 482 } 483 484 void remote_usbhc_control_write_setup(device_t *device, void *iface, 485 ipc_callid_t callid, ipc_call_t *call) 486 { 487 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 488 assert(usb_iface != NULL); 489 490 return remote_usbhc_out_transfer(device, callid, call, 491 usb_iface->control_write_setup); 492 } 493 494 void remote_usbhc_control_write_data(device_t *device, void *iface, 495 ipc_callid_t callid, ipc_call_t *call) 496 { 497 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 498 assert(usb_iface != NULL); 499 500 return remote_usbhc_out_transfer(device, callid, call, 501 usb_iface->control_write_data); 502 } 503 504 void remote_usbhc_control_write_status(device_t *device, void *iface, 505 ipc_callid_t callid, ipc_call_t *call) 506 { 507 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 508 assert(usb_iface != NULL); 509 510 return remote_usbhc_status_transfer(device, callid, call, 511 USB_DIRECTION_IN, usb_iface->control_write_status, NULL); 512 } 513 514 void remote_usbhc_control_read_setup(device_t *device, void *iface, 515 ipc_callid_t callid, ipc_call_t *call) 516 { 517 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 518 assert(usb_iface != NULL); 519 520 return remote_usbhc_out_transfer(device, callid, call, 521 usb_iface->control_read_setup); 522 } 523 524 void remote_usbhc_control_read_data(device_t *device, void *iface, 525 ipc_callid_t callid, ipc_call_t *call) 526 { 527 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 528 assert(usb_iface != NULL); 529 530 return remote_usbhc_in_transfer(device, callid, call, 531 usb_iface->control_read_data); 532 } 533 534 void remote_usbhc_control_read_status(device_t *device, void *iface, 535 ipc_callid_t callid, ipc_call_t *call) 536 { 537 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 538 assert(usb_iface != NULL); 539 540 return remote_usbhc_status_transfer(device, callid, call, 541 USB_DIRECTION_OUT, NULL, usb_iface->control_read_status); 542 } 543 544 void remote_usbhc_control_write(device_t *device, void *iface, 545 ipc_callid_t callid, ipc_call_t *call) 546 { 547 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 548 assert(usb_iface != NULL); 549 550 if (!usb_iface->control_write) { 551 ipc_answer_0(callid, ENOTSUP); 465 if (!usb_iface->control_read) { 466 async_answer_0(callid, ENOTSUP); 552 467 return; 553 468 } … … 557 472 .endpoint = DEV_IPC_GET_ARG2(*call) 558 473 }; 474 size_t max_packet_size = DEV_IPC_GET_ARG3(*call); 559 475 560 476 int rc; 561 477 562 478 void *setup_packet = NULL; 563 void *data_buffer = NULL;564 479 size_t setup_packet_len = 0; 565 size_t data_ buffer_len = 0;480 size_t data_len = 0; 566 481 567 482 rc = async_data_write_accept(&setup_packet, false, 568 483 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 569 484 if (rc != EOK) { 570 ipc_answer_0(callid, rc);571 return; 572 } 573 rc = async_data_write_accept(&data_buffer, false, 574 1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len);575 if ( rc != EOK) {576 ipc_answer_0(callid, rc);485 async_answer_0(callid, rc); 486 return; 487 } 488 489 ipc_callid_t data_callid; 490 if (!async_data_read_receive(&data_callid, &data_len)) { 491 async_answer_0(callid, EPARTY); 577 492 free(setup_packet); 578 493 return; … … 581 496 async_transaction_t *trans = async_transaction_create(callid); 582 497 if (trans == NULL) { 583 ipc_answer_0(callid, ENOMEM);498 async_answer_0(callid, ENOMEM); 584 499 free(setup_packet); 585 free(data_buffer); 586 return; 587 } 588 trans->setup_packet = setup_packet; 589 trans->buffer = data_buffer; 590 trans->size = data_buffer_len; 591 592 rc = usb_iface->control_write(device, target, 593 setup_packet, setup_packet_len, 594 data_buffer, data_buffer_len, 595 callback_out, trans); 596 597 if (rc != EOK) { 598 ipc_answer_0(callid, rc); 599 async_transaction_destroy(trans); 600 } 601 } 602 603 604 void remote_usbhc_control_read(device_t *device, void *iface, 605 ipc_callid_t callid, ipc_call_t *call) 606 { 607 usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface; 608 assert(usb_iface != NULL); 609 610 if (!usb_iface->control_read) { 611 ipc_answer_0(callid, ENOTSUP); 612 return; 613 } 614 615 size_t data_len = DEV_IPC_GET_ARG3(*call); 616 usb_target_t target = { 617 .address = DEV_IPC_GET_ARG1(*call), 618 .endpoint = DEV_IPC_GET_ARG2(*call) 619 }; 620 621 int rc; 622 623 void *setup_packet = NULL; 624 size_t setup_packet_len = 0; 625 626 rc = async_data_write_accept(&setup_packet, false, 627 1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len); 628 if (rc != EOK) { 629 ipc_answer_0(callid, rc); 630 return; 631 } 632 633 async_transaction_t *trans = async_transaction_create(callid); 634 if (trans == NULL) { 635 ipc_answer_0(callid, ENOMEM); 636 free(setup_packet); 637 return; 638 } 500 return; 501 } 502 trans->data_caller = data_callid; 639 503 trans->setup_packet = setup_packet; 640 504 trans->size = data_len; 641 505 trans->buffer = malloc(data_len); 642 506 if (trans->buffer == NULL) { 643 ipc_answer_0(callid, ENOMEM);507 async_answer_0(callid, ENOMEM); 644 508 async_transaction_destroy(trans); 645 509 return; 646 510 } 647 511 648 rc = usb_iface->control_read( device, target,512 rc = usb_iface->control_read(fun, target, max_packet_size, 649 513 setup_packet, setup_packet_len, 650 514 trans->buffer, trans->size, … … 652 516 653 517 if (rc != EOK) { 654 ipc_answer_0(callid, rc);518 async_answer_0(callid, rc); 655 519 async_transaction_destroy(trans); 656 520 }
Note:
See TracChangeset
for help on using the changeset viewer.