Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/drv/generic/remote_usbhc.c

    r4689d40 rcb59f787  
    4242#define USB_MAX_PAYLOAD_SIZE 1020
    4343
    44 static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4544static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4645static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4746static 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_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    55 static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    56 static void remote_usbhc_request_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    57 static void remote_usbhc_bind_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    58 static void remote_usbhc_release_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    59 //static void remote_usbhc(device_t *, void *, ipc_callid_t, ipc_call_t *);
     47//static void remote_usb(device_t *, void *, ipc_callid_t, ipc_call_t *);
    6048
    6149/** Remote USB interface operations. */
    6250static remote_iface_func_ptr_t remote_usbhc_iface_ops [] = {
    63         remote_usbhc_get_address,
    64 
    65         remote_usbhc_get_buffer,
    66 
    67         remote_usbhc_reserve_default_address,
    68         remote_usbhc_release_default_address,
    69 
    70         remote_usbhc_request_address,
    71         remote_usbhc_bind_address,
    72         remote_usbhc_release_address,
    73 
    74         remote_usbhc_interrupt_out,
    75         remote_usbhc_interrupt_in,
    76 
    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
     51        &remote_usbhc_get_buffer,
     52        &remote_usbhc_interrupt_out,
     53        &remote_usbhc_interrupt_in
    8454};
    8555
     
    9868} async_transaction_t;
    9969
    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 = IPC_GET_ARG1(*call);
    111 
    112         usb_address_t address;
    113         int rc = usb_iface->tell_address(device, handle, &address);
    114         if (rc != EOK) {
    115                 ipc_answer_0(callid, rc);
    116         } else {
    117                 ipc_answer_1(callid, EOK, address);
    118         }
    119 }
    12070
    12171void remote_usbhc_get_buffer(device_t *device, void *iface,
     
    152102}
    153103
    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, (ipcarg_t) address);
    200         }
    201 }
    202 
    203 void remote_usbhc_bind_address(device_t *device, void *iface,
    204     ipc_callid_t callid, ipc_call_t *call)
    205 {
    206         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    207 
    208         if (!usb_iface->bind_address) {
    209                 ipc_answer_0(callid, ENOTSUP);
    210                 return;
    211         }
    212 
    213         usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
    214         devman_handle_t handle = (devman_handle_t) IPC_GET_ARG2(*call);
    215 
    216         int rc = usb_iface->bind_address(device, address, handle);
    217 
    218         ipc_answer_0(callid, rc);
    219 }
    220 
    221 void remote_usbhc_release_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->release_address) {
    227                 ipc_answer_0(callid, ENOTSUP);
    228                 return;
    229         }
    230 
    231         usb_address_t address = (usb_address_t) IPC_GET_ARG1(*call);
    232 
    233         int rc = usb_iface->release_address(device, address);
    234 
    235         ipc_answer_0(callid, rc);
    236 }
    237 
    238104
    239105static void callback_out(device_t *device,
     
    259125}
    260126
    261 /** Process an outgoing transfer (both OUT and SETUP).
    262  *
    263  * @param device Target device.
    264  * @param callid Initiating caller.
    265  * @param call Initiating call.
    266  * @param transfer_func Transfer function (might be NULL).
    267  */
    268 static void remote_usbhc_out_transfer(device_t *device,
    269     ipc_callid_t callid, ipc_call_t *call,
    270     usbhc_iface_transfer_out_t transfer_func)
    271 {
    272         if (!transfer_func) {
    273                 ipc_answer_0(callid, ENOTSUP);
    274                 return;
    275         }
     127void remote_usbhc_interrupt_out(device_t *device, void *iface,
     128            ipc_callid_t callid, ipc_call_t *call)
     129{
     130        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    276131
    277132        size_t expected_len = IPC_GET_ARG3(*call);
     
    294149        }
    295150
     151        if (!usb_iface->interrupt_out) {
     152                ipc_answer_0(callid, ENOTSUP);
     153                return;
     154        }
     155
    296156        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    297157        trans->caller = callid;
    298         trans->buffer = buffer;
    299         trans->size = len;
    300 
    301         int rc = transfer_func(device, target, buffer, len,
     158        trans->buffer = NULL;
     159        trans->size = 0;
     160
     161        int rc = usb_iface->interrupt_out(device, target, buffer, len,
    302162            callback_out, trans);
    303163
    304164        if (rc != EOK) {
    305165                ipc_answer_0(callid, rc);
    306                 if (buffer != NULL) {
    307                         free(buffer);
    308                 }
    309166                free(trans);
    310167        }
    311168}
    312169
    313 /** Process an incoming transfer.
    314  *
    315  * @param device Target device.
    316  * @param callid Initiating caller.
    317  * @param call Initiating call.
    318  * @param transfer_func Transfer function (might be NULL).
    319  */
    320 static void remote_usbhc_in_transfer(device_t *device,
    321     ipc_callid_t callid, ipc_call_t *call,
    322     usbhc_iface_transfer_in_t transfer_func)
    323 {
    324         if (!transfer_func) {
    325                 ipc_answer_0(callid, ENOTSUP);
    326                 return;
    327         }
     170void remote_usbhc_interrupt_in(device_t *device, void *iface,
     171            ipc_callid_t callid, ipc_call_t *call)
     172{
     173        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    328174
    329175        size_t len = IPC_GET_ARG3(*call);
     
    333179        };
    334180
     181        if (!usb_iface->interrupt_in) {
     182                ipc_answer_0(callid, ENOTSUP);
     183                return;
     184        }
     185
    335186        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    336187        trans->caller = callid;
     
    338189        trans->size = len;
    339190
    340         int rc = transfer_func(device, target, trans->buffer, len,
     191        int rc = usb_iface->interrupt_in(device, target, trans->buffer, len,
    341192            callback_in, trans);
    342193
     
    348199}
    349200
    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;
    383         }
    384 
    385         usb_target_t target = {
    386                 .address = IPC_GET_ARG1(*call),
    387                 .endpoint = IPC_GET_ARG2(*call)
    388         };
    389 
    390         async_transaction_t *trans = malloc(sizeof(async_transaction_t));
    391         trans->caller = callid;
    392         trans->buffer = NULL;
    393         trans->size = 0;
    394 
    395         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)
    420 {
    421         usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
    422         assert(usb_iface != NULL);
    423 
    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);
    496 }
    497 
    498 
    499201
    500202/**
Note: See TracChangeset for help on using the changeset viewer.