Ignore:
File:
1 edited

Legend:

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

    rb36e5de2 r6427cf67  
    4040
    4141#define USB_MAX_PAYLOAD_SIZE 1020
    42 #define HACK_MAX_PACKET_SIZE 8
    43 #define HACK_MAX_PACKET_SIZE_INTERRUPT_IN 4
    4442
    4543static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4644static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4745static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     46static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     47static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     48static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     49static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     50static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     51static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4852static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4953static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6973        remote_usbhc_interrupt_in,
    7074
     75        remote_usbhc_control_write_setup,
     76        remote_usbhc_control_write_data,
     77        remote_usbhc_control_write_status,
     78
     79        remote_usbhc_control_read_setup,
     80        remote_usbhc_control_read_data,
     81        remote_usbhc_control_read_status,
     82
    7183        remote_usbhc_control_write,
    7284        remote_usbhc_control_read
     
    152164        }
    153165       
    154         usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
     166        bool full_speed = DEV_IPC_GET_ARG1(*call);
    155167       
    156         int rc = usb_iface->reserve_default_address(device, speed);
     168        int rc = usb_iface->reserve_default_address(device, full_speed);
    157169
    158170        async_answer_0(callid, rc);
     
    184196        }
    185197       
    186         usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
     198        bool full_speed = DEV_IPC_GET_ARG1(*call);
    187199
    188200        usb_address_t address;
    189         int rc = usb_iface->request_address(device, speed, &address);
     201        int rc = usb_iface->request_address(device, full_speed, &address);
    190202        if (rc != EOK) {
    191203                async_answer_0(callid, rc);
     
    283295        }
    284296
    285         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
     297        size_t expected_len = DEV_IPC_GET_ARG3(*call);
    286298        usb_target_t target = {
    287299                .address = DEV_IPC_GET_ARG1(*call),
     
    291303        size_t len = 0;
    292304        void *buffer = NULL;
    293 
    294         int rc = async_data_write_accept(&buffer, false,
    295             1, USB_MAX_PAYLOAD_SIZE,
    296             0, &len);
    297 
    298         if (rc != EOK) {
    299                 async_answer_0(callid, rc);
    300                 return;
     305        if (expected_len > 0) {
     306                int rc = async_data_write_accept(&buffer, false,
     307                    1, USB_MAX_PAYLOAD_SIZE,
     308                    0, &len);
     309
     310                if (rc != EOK) {
     311                        async_answer_0(callid, rc);
     312                        return;
     313                }
    301314        }
    302315
     
    313326        trans->size = len;
    314327
    315         rc = transfer_func(device, target, max_packet_size,
    316             buffer, len,
     328        int rc = transfer_func(device, target, buffer, len,
    317329            callback_out, trans);
    318330
     
    339351        }
    340352
    341         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
     353        size_t len = DEV_IPC_GET_ARG3(*call);
    342354        usb_target_t target = {
    343355                .address = DEV_IPC_GET_ARG1(*call),
     
    345357        };
    346358
    347         size_t len;
    348359        ipc_callid_t data_callid;
    349360        if (!async_data_read_receive(&data_callid, &len)) {
     
    361372        trans->size = len;
    362373
    363         int rc = transfer_func(device, target, max_packet_size,
    364             trans->buffer, len,
     374        int rc = transfer_func(device, target, trans->buffer, len,
    365375            callback_in, trans);
    366376
     
    370380        }
    371381}
     382
     383/** Process status part of control transfer.
     384 *
     385 * @param device Target device.
     386 * @param callid Initiating caller.
     387 * @param call Initiating call.
     388 * @param direction Transfer direction (read ~ in, write ~ out).
     389 * @param transfer_in_func Transfer function for control read (might be NULL).
     390 * @param transfer_out_func Transfer function for control write (might be NULL).
     391 */
     392static void remote_usbhc_status_transfer(device_t *device,
     393    ipc_callid_t callid, ipc_call_t *call,
     394    usb_direction_t direction,
     395    int (*transfer_in_func)(device_t *, usb_target_t,
     396        usbhc_iface_transfer_in_callback_t, void *),
     397    int (*transfer_out_func)(device_t *, usb_target_t,
     398        usbhc_iface_transfer_out_callback_t, void *))
     399{
     400        switch (direction) {
     401                case USB_DIRECTION_IN:
     402                        if (!transfer_in_func) {
     403                                async_answer_0(callid, ENOTSUP);
     404                                return;
     405                        }
     406                        break;
     407                case USB_DIRECTION_OUT:
     408                        if (!transfer_out_func) {
     409                                async_answer_0(callid, ENOTSUP);
     410                                return;
     411                        }
     412                        break;
     413                default:
     414                        assert(false && "unreachable code");
     415                        break;
     416        }
     417
     418        usb_target_t target = {
     419                .address = DEV_IPC_GET_ARG1(*call),
     420                .endpoint = DEV_IPC_GET_ARG2(*call)
     421        };
     422
     423        async_transaction_t *trans = async_transaction_create(callid);
     424        if (trans == NULL) {
     425                async_answer_0(callid, ENOMEM);
     426                return;
     427        }
     428
     429        int rc;
     430        switch (direction) {
     431                case USB_DIRECTION_IN:
     432                        rc = transfer_in_func(device, target,
     433                            callback_in, trans);
     434                        break;
     435                case USB_DIRECTION_OUT:
     436                        rc = transfer_out_func(device, target,
     437                            callback_out, trans);
     438                        break;
     439                default:
     440                        assert(false && "unreachable code");
     441                        break;
     442        }
     443
     444        if (rc != EOK) {
     445                async_answer_0(callid, rc);
     446                async_transaction_destroy(trans);
     447        }
     448}
     449
    372450
    373451void remote_usbhc_interrupt_out(device_t *device, void *iface,
     
    389467        return remote_usbhc_in_transfer(device, callid, call,
    390468            usb_iface->interrupt_in);
     469}
     470
     471void remote_usbhc_control_write_setup(device_t *device, void *iface,
     472    ipc_callid_t callid, ipc_call_t *call)
     473{
     474        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     475        assert(usb_iface != NULL);
     476
     477        return remote_usbhc_out_transfer(device, callid, call,
     478            usb_iface->control_write_setup);
     479}
     480
     481void remote_usbhc_control_write_data(device_t *device, void *iface,
     482    ipc_callid_t callid, ipc_call_t *call)
     483{
     484        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     485        assert(usb_iface != NULL);
     486
     487        return remote_usbhc_out_transfer(device, callid, call,
     488            usb_iface->control_write_data);
     489}
     490
     491void remote_usbhc_control_write_status(device_t *device, void *iface,
     492    ipc_callid_t callid, ipc_call_t *call)
     493{
     494        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     495        assert(usb_iface != NULL);
     496
     497        return remote_usbhc_status_transfer(device, callid, call,
     498            USB_DIRECTION_IN, usb_iface->control_write_status, NULL);
     499}
     500
     501void remote_usbhc_control_read_setup(device_t *device, void *iface,
     502    ipc_callid_t callid, ipc_call_t *call)
     503{
     504        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     505        assert(usb_iface != NULL);
     506
     507        return remote_usbhc_out_transfer(device, callid, call,
     508            usb_iface->control_read_setup);
     509}
     510
     511void remote_usbhc_control_read_data(device_t *device, void *iface,
     512            ipc_callid_t callid, ipc_call_t *call)
     513{
     514        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     515        assert(usb_iface != NULL);
     516
     517        return remote_usbhc_in_transfer(device, callid, call,
     518            usb_iface->control_read_data);
     519}
     520
     521void remote_usbhc_control_read_status(device_t *device, void *iface,
     522            ipc_callid_t callid, ipc_call_t *call)
     523{
     524        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     525        assert(usb_iface != NULL);
     526
     527        return remote_usbhc_status_transfer(device, callid, call,
     528            USB_DIRECTION_OUT, NULL, usb_iface->control_read_status);
    391529}
    392530
     
    407545        };
    408546        size_t data_buffer_len = DEV_IPC_GET_ARG3(*call);
    409         size_t max_packet_size = DEV_IPC_GET_ARG4(*call);
    410547
    411548        int rc;
     
    443580        trans->size = data_buffer_len;
    444581
    445         rc = usb_iface->control_write(device, target, max_packet_size,
     582        rc = usb_iface->control_write(device, target,
    446583            setup_packet, setup_packet_len,
    447584            data_buffer, data_buffer_len,
     
    470607                .endpoint = DEV_IPC_GET_ARG2(*call)
    471608        };
    472         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
    473609
    474610        int rc;
     
    508644        }
    509645
    510         rc = usb_iface->control_read(device, target, max_packet_size,
     646        rc = usb_iface->control_read(device, target,
    511647            setup_packet, setup_packet_len,
    512648            trans->buffer, trans->size,
Note: See TracChangeset for help on using the changeset viewer.