Changes in / [6edc69a:7e7f0f5] in mainline


Ignore:
Location:
uspace
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/iface.c

    r6edc69a r7e7f0f5  
    5454}
    5555/*----------------------------------------------------------------------------*/
    56 static int reserve_default_address(device_t *dev, usb_speed_t speed)
     56static int reserve_default_address(device_t *dev)
    5757{
    5858        assert(dev);
     
    7272}
    7373/*----------------------------------------------------------------------------*/
    74 static int request_address(device_t *dev, usb_speed_t speed,
    75     usb_address_t *address)
     74static int request_address(device_t *dev, usb_address_t *address)
    7675{
    7776        assert(dev);
     
    164163        return EOK;
    165164}
    166 
    167 
     165/*----------------------------------------------------------------------------*/
     166static int control_write_setup(device_t *dev, usb_target_t target,
     167    size_t max_packet_size,
     168    void *data, size_t size,
     169    usbhc_iface_transfer_out_callback_t callback, void *arg)
     170{
     171        dev_speed_t speed = FULL_SPEED;
     172
     173        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     174        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     175            max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
     176        if (!batch)
     177                return ENOMEM;
     178        batch_control_setup_old(batch);
     179        return EOK;
     180}
     181/*----------------------------------------------------------------------------*/
     182static int control_write_data(device_t *dev, usb_target_t target,
     183    size_t max_packet_size,
     184    void *data, size_t size,
     185    usbhc_iface_transfer_out_callback_t callback, void *arg)
     186{
     187        dev_speed_t speed = FULL_SPEED;
     188
     189        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     190        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     191            max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
     192        if (!batch)
     193                return ENOMEM;
     194        batch_control_write_data_old(batch);
     195        return EOK;
     196}
     197/*----------------------------------------------------------------------------*/
     198static int control_write_status(device_t *dev, usb_target_t target,
     199    usbhc_iface_transfer_in_callback_t callback, void *arg)
     200{
     201        size_t max_packet_size = 8;
     202        dev_speed_t speed = FULL_SPEED;
     203
     204        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     205        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     206            max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);
     207        if (!batch)
     208                return ENOMEM;
     209        batch_control_write_status_old(batch);
     210        return EOK;
     211}
     212/*----------------------------------------------------------------------------*/
     213static int control_read_setup(device_t *dev, usb_target_t target,
     214    size_t max_packet_size,
     215    void *data, size_t size,
     216    usbhc_iface_transfer_out_callback_t callback, void *arg)
     217{
     218        dev_speed_t speed = FULL_SPEED;
     219
     220        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     221        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     222            max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
     223        if (!batch)
     224                return ENOMEM;
     225        batch_control_setup_old(batch);
     226        return EOK;
     227}
     228/*----------------------------------------------------------------------------*/
     229static int control_read_data(device_t *dev, usb_target_t target,
     230    size_t max_packet_size,
     231    void *data, size_t size,
     232    usbhc_iface_transfer_in_callback_t callback, void *arg)
     233{
     234        dev_speed_t speed = FULL_SPEED;
     235
     236        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     237        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     238            max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
     239        if (!batch)
     240                return ENOMEM;
     241        batch_control_read_data_old(batch);
     242        return EOK;
     243}
     244/*----------------------------------------------------------------------------*/
     245static int control_read_status(device_t *dev, usb_target_t target,
     246    usbhc_iface_transfer_out_callback_t callback, void *arg)
     247{
     248        size_t max_packet_size = 8;
     249        dev_speed_t speed = FULL_SPEED;
     250
     251        usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
     252        batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
     253            max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg);
     254        if (!batch)
     255                return ENOMEM;
     256        batch_control_read_status_old(batch);
     257        return EOK;
     258}
    168259/*----------------------------------------------------------------------------*/
    169260usbhc_iface_t uhci_iface = {
     
    181272        .control_read = control_read,
    182273        .control_write = control_write,
     274
     275        .control_write_setup = control_write_setup,
     276        .control_write_data = control_write_data,
     277        .control_write_status = control_write_status,
     278
     279        .control_read_setup = control_read_setup,
     280        .control_read_data = control_read_data,
     281        .control_read_status = control_read_status
    183282};
    184283/**
  • uspace/drv/uhci-rhd/port.c

    r6edc69a r7e7f0f5  
    131131        return EOK;
    132132}
    133 
    134 /** Callback for enabling port during adding a new device.
    135  *
    136  * @param portno Port number (unused).
    137  * @param arg Pointer to uhci_port_t of port with the new device.
    138  * @return Error code.
    139  */
    140 static int new_device_enable_port(int portno, void *arg)
    141 {
    142         uhci_port_t *port = (uhci_port_t *) arg;
    143 
    144         usb_log_debug("new_device_enable_port(%d)\n", port->number);
     133/*----------------------------------------------------------------------------*/
     134static int uhci_port_new_device(uhci_port_t *port)
     135{
     136        assert(port);
     137        assert(usb_hc_connection_is_opened(&port->hc_connection));
     138
     139        usb_log_info("Adding new device on port %d.\n", port->number);
     140
     141        /* get address of the future device */
     142        const usb_address_t usb_address = usb_hc_request_address(&port->hc_connection);
     143
     144        if (usb_address <= 0) {
     145                usb_log_error("Recieved invalid address(%d).\n", usb_address);
     146                return usb_address;
     147        }
     148        usb_log_debug("Sucessfully obtained address %d for port %d.\n",
     149            usb_address, port->number);
     150
     151        /* get default address */
     152        int ret = usb_hc_reserve_default_address(&port->hc_connection);
     153        if (ret != EOK) {
     154                usb_log_error("Failed to reserve default address on port %d.\n",
     155                    port->number);
     156                int ret2 = usb_hc_unregister_device(&port->hc_connection,
     157                    usb_address);
     158                if (ret2 != EOK) {
     159                        usb_log_fatal("Failed to return requested address on port %d.\n",
     160                           port->number);
     161                        return ret2;
     162                }
     163                usb_log_debug("Successfully returned reserved address on port %d.\n",
     164                        port->number);
     165                return ret;
     166        }
     167        usb_log_debug("Sucessfully obtained default address for port %d.\n",
     168            port->number);
    145169
    146170        /*
    147          * The host then waits for at least 100 ms to allow completion of
     171         * the host then waits for at least 100 ms to allow completion of
    148172         * an insertion process and for power at the device to become stable.
    149173         */
    150174        async_usleep(100000);
    151175
    152         /* Enable the port. */
     176        /* enable port */
    153177        uhci_port_set_enabled(port, true);
    154178
     
    172196        }
    173197
    174         return EOK;
    175 }
    176 
    177 /*----------------------------------------------------------------------------*/
    178 static int uhci_port_new_device(uhci_port_t *port)
    179 {
    180         assert(port);
    181         assert(usb_hc_connection_is_opened(&port->hc_connection));
    182 
    183         usb_log_info("Detected new device on port %u.\n", port->number);
    184 
    185         usb_address_t dev_addr;
    186         int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    187             USB_SPEED_FULL,
    188             new_device_enable_port, port->number, port,
    189             &dev_addr, &port->attached_device);
    190         if (rc != EOK) {
    191                 usb_log_error("Failed adding new device on port %u: %s.\n",
    192                     port->number, str_error(rc));
     198        /*
     199         * Initialize connection to the device.
     200         */
     201        /* FIXME: check for errors. */
     202        usb_device_connection_t new_dev_connection;
     203        usb_endpoint_pipe_t new_dev_ctrl_pipe;
     204        usb_device_connection_initialize_on_default_address(
     205            &new_dev_connection, &port->hc_connection);
     206        usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
     207            &new_dev_connection);
     208
     209        /*
     210         * Assign new address to the device. This function updates
     211         * the backing connection to still point to the same device.
     212         */
     213        /* FIXME: check for errors. */
     214        usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
     215        ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
     216        usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
     217
     218        if (ret != EOK) { /* address assigning went wrong */
     219                usb_log_error("Failed(%d) to assign address to the device.\n", ret);
    193220                uhci_port_set_enabled(port, false);
    194                 return rc;
    195         }
    196 
    197         usb_log_info("New device on port %u has address %d (handle %zu).\n",
    198             port->number, dev_addr, port->attached_device);
    199 
    200         return EOK;
    201 }
    202 
     221                int release = usb_hc_release_default_address(&port->hc_connection);
     222                if (release != EOK) {
     223                        usb_log_error("Failed to release default address on port %d.\n",
     224                            port->number);
     225                        return release;
     226                }
     227                usb_log_debug("Sucessfully released default address on port %d.\n",
     228                    port->number);
     229                return ret;
     230        }
     231        usb_log_debug("Sucessfully assigned address %d for port %d.\n",
     232            usb_address, port->number);
     233
     234        /* release default address */
     235        ret = usb_hc_release_default_address(&port->hc_connection);
     236        if (ret != EOK) {
     237                usb_log_error("Failed to release default address on port %d.\n",
     238                    port->number);
     239                return ret;
     240        }
     241        usb_log_debug("Sucessfully released default address on port %d.\n",
     242            port->number);
     243
     244        /* communicate and possibly report to devman */
     245        assert(port->attached_device == 0);
     246
     247        ret = usb_device_register_child_in_devman(new_dev_connection.address,
     248            new_dev_connection.hc_handle, port->rh, &port->attached_device);
     249
     250        if (ret != EOK) { /* something went wrong */
     251                usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
     252                uhci_port_set_enabled(port, false);
     253                return ENOMEM;
     254        }
     255        usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
     256                port->number, usb_address, port->attached_device);
     257
     258        /*
     259         * Register the device in the host controller.
     260         */
     261        usb_hc_attached_device_t new_device = {
     262                .address = new_dev_connection.address,
     263                .handle = port->attached_device
     264        };
     265
     266        ret = usb_hc_register_device(&port->hc_connection, &new_device);
     267        // TODO: proper error check here
     268        assert(ret == EOK);
     269
     270        return EOK;
     271}
    203272/*----------------------------------------------------------------------------*/
    204273static int uhci_port_remove_device(uhci_port_t *port)
  • uspace/drv/uhci-rhd/root_hub.c

    r6edc69a r7e7f0f5  
    4747        assert(rh);
    4848        int ret;
    49         ret = usb_hc_find(rh->handle, &instance->hc_handle);
     49        ret = usb_drv_find_hc(rh, &instance->hc_handle);
    5050        usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle);
    5151        if (ret != EOK) {
  • uspace/drv/usbhub/usbhub.c

    r6edc69a r7e7f0f5  
    5050#include "usb/usb.h"
    5151
    52 static int iface_get_hc_handle(device_t *device, devman_handle_t *handle)
    53 {
    54         return usb_hc_find(device->handle, handle);
    55 }
    56 
    5752static usb_iface_t hub_usb_iface = {
    58         .get_hc_handle = iface_get_hc_handle
     53        .get_hc_handle = usb_drv_find_hc
    5954};
    6055
  • uspace/drv/vhc/connhost.c

    r6edc69a r7e7f0f5  
    234234}
    235235
     236static int enqueue_transfer_setup(device_t *dev,
     237    usb_target_t target, usb_transfer_type_t transfer_type,
     238    void *buffer, size_t size,
     239    usbhc_iface_transfer_out_callback_t callback, void *arg)
     240{
     241        usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n",
     242            target.address, target.endpoint,
     243            usb_str_transfer_type(transfer_type),
     244            size);
     245
     246        transfer_info_t *transfer
     247            = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
     248        transfer->out_callback = callback;
     249
     250        hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
     251            universal_callback, transfer);
     252
     253        return EOK;
     254}
     255
    236256static int enqueue_transfer_in(device_t *dev,
    237257    usb_target_t target, usb_transfer_type_t transfer_type,
     
    275295}
    276296
     297static int control_write_setup(device_t *dev, usb_target_t target,
     298    size_t max_packet_size,
     299    void *data, size_t size,
     300    usbhc_iface_transfer_out_callback_t callback, void *arg)
     301{
     302        return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
     303            data, size,
     304            callback, arg);
     305}
     306
     307static int control_write_data(device_t *dev, usb_target_t target,
     308    size_t max_packet_size,
     309    void *data, size_t size,
     310    usbhc_iface_transfer_out_callback_t callback, void *arg)
     311{
     312        return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
     313            data, size,
     314            callback, arg);
     315}
     316
     317static int control_write_status(device_t *dev, usb_target_t target,
     318    usbhc_iface_transfer_in_callback_t callback, void *arg)
     319{
     320        return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
     321            NULL, 0,
     322            callback, arg);
     323}
     324
    277325static int control_write(device_t *dev, usb_target_t target,
    278326    size_t max_packet_size,
     
    293341}
    294342
     343static int control_read_setup(device_t *dev, usb_target_t target,
     344    size_t max_packet_size,
     345    void *data, size_t size,
     346    usbhc_iface_transfer_out_callback_t callback, void *arg)
     347{
     348        return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
     349            data, size,
     350            callback, arg);
     351}
     352
     353static int control_read_data(device_t *dev, usb_target_t target,
     354    size_t max_packet_size,
     355    void *data, size_t size,
     356    usbhc_iface_transfer_in_callback_t callback, void *arg)
     357{
     358        return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
     359            data, size,
     360            callback, arg);
     361}
     362
     363static int control_read_status(device_t *dev, usb_target_t target,
     364    usbhc_iface_transfer_out_callback_t callback, void *arg)
     365{
     366        return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
     367            NULL, 0,
     368            callback, arg);
     369}
     370
    295371static int control_read(device_t *dev, usb_target_t target,
    296372    size_t max_packet_size,
     
    314390
    315391
    316 static int reserve_default_address(device_t *dev, usb_speed_t ignored)
     392static int reserve_default_address(device_t *dev)
    317393{
    318394        usb_address_keeping_reserve_default(&addresses);
     
    326402}
    327403
    328 static int request_address(device_t *dev, usb_speed_t ignored,
    329     usb_address_t *address)
     404static int request_address(device_t *dev, usb_address_t *address)
    330405{
    331406        usb_address_t addr = usb_address_keeping_request(&addresses);
     
    379454        .interrupt_in = interrupt_in,
    380455
     456        .control_write_setup = control_write_setup,
     457        .control_write_data = control_write_data,
     458        .control_write_status = control_write_status,
     459
    381460        .control_write = control_write,
     461
     462        .control_read_setup = control_read_setup,
     463        .control_read_data = control_read_data,
     464        .control_read_status = control_read_status,
     465
    382466        .control_read = control_read
    383467};
  • uspace/lib/c/generic/str_error.c

    r6edc69a r7e7f0f5  
    7373                case EBADCHECKSUM:
    7474                        return "Bad checksum";
    75                 case ESTALL:
    76                         return "Operation stalled";
    7775                case EAGAIN:
    7876                        return "Resource temporarily unavailable";
  • uspace/lib/c/include/errno.h

    r6edc69a r7e7f0f5  
    5959#define EBADCHECKSUM  (-300)
    6060
    61 /** USB: stalled operation. */
    62 #define ESTALL (-301)
    63 
    6461/** An API function is called while another blocking function is in progress. */
    6562#define EINPROGRESS  (-10036)
  • uspace/lib/drv/generic/remote_usbhc.c

    r6edc69a r7e7f0f5  
    4646static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4747static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     48static void remote_usbhc_control_write_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     49static void remote_usbhc_control_write_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     50static void remote_usbhc_control_write_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     51static void remote_usbhc_control_read_setup(device_t *, void *, ipc_callid_t, ipc_call_t *);
     52static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
     53static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4854static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4955static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6975        remote_usbhc_interrupt_in,
    7076
     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,
     84
    7185        remote_usbhc_control_write,
    7286        remote_usbhc_control_read
     
    151165                return;
    152166        }
    153        
    154         usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    155        
    156         int rc = usb_iface->reserve_default_address(device, speed);
     167
     168        int rc = usb_iface->reserve_default_address(device);
    157169
    158170        async_answer_0(callid, rc);
     
    183195                return;
    184196        }
    185        
    186         usb_speed_t speed = DEV_IPC_GET_ARG1(*call);
    187197
    188198        usb_address_t address;
    189         int rc = usb_iface->request_address(device, speed, &address);
     199        int rc = usb_iface->request_address(device, &address);
    190200        if (rc != EOK) {
    191201                async_answer_0(callid, rc);
     
    283293        }
    284294
    285         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
     295        size_t expected_len = DEV_IPC_GET_ARG3(*call);
    286296        usb_target_t target = {
    287297                .address = DEV_IPC_GET_ARG1(*call),
     
    291301        size_t len = 0;
    292302        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;
     303        if (expected_len > 0) {
     304                int rc = async_data_write_accept(&buffer, false,
     305                    1, USB_MAX_PAYLOAD_SIZE,
     306                    0, &len);
     307
     308                if (rc != EOK) {
     309                        async_answer_0(callid, rc);
     310                        return;
     311                }
    301312        }
    302313
     
    313324        trans->size = len;
    314325
    315         rc = transfer_func(device, target, max_packet_size,
     326        int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE,
    316327            buffer, len,
    317328            callback_out, trans);
     
    339350        }
    340351
    341         size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
     352        size_t len = DEV_IPC_GET_ARG3(*call);
    342353        usb_target_t target = {
    343354                .address = DEV_IPC_GET_ARG1(*call),
     
    345356        };
    346357
    347         size_t len;
    348358        ipc_callid_t data_callid;
    349359        if (!async_data_read_receive(&data_callid, &len)) {
     
    361371        trans->size = len;
    362372
    363         int rc = transfer_func(device, target, max_packet_size,
     373        int rc = transfer_func(device, target, HACK_MAX_PACKET_SIZE_INTERRUPT_IN,
    364374            trans->buffer, len,
    365375            callback_in, trans);
     
    371381}
    372382
     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
     450
    373451void remote_usbhc_interrupt_out(device_t *device, void *iface,
    374452    ipc_callid_t callid, ipc_call_t *call)
     
    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, HACK_MAX_PACKET_SIZE,
    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, HACK_MAX_PACKET_SIZE,
    511647            setup_packet, setup_packet_len,
    512648            trans->buffer, trans->size,
  • uspace/lib/drv/include/usbhc_iface.h

    r6edc69a r7e7f0f5  
    4040#include "driver.h"
    4141#include <usb/usb.h>
    42 #include <bool.h>
    4342
    4443
     
    5352 *   - argument #1 is target address
    5453 *   - argument #2 is target endpoint
    55  *   - argument #3 is max packet size of the endpoint
     54 *   - argument #3 is buffer size
    5655 * - this call is immediately followed by IPC data write (from caller)
    5756 * - the initial call (and the whole transaction) is answer after the
     
    6665 *   - argument #1 is target address
    6766 *   - argument #2 is target endpoint
    68  *   - argument #3 is max packet size of the endpoint
     67 *   - argument #3 is buffer size
    6968 * - this call is immediately followed by IPC data read (async version)
    7069 * - the call is not answered until the device returns some data (or until
     
    153152        IPC_M_USBHC_INTERRUPT_IN,
    154153
     154
     155        /** Start WRITE control transfer.
     156         * See explanation at usb_iface_funcs_t (OUT transaction).
     157         */
     158        IPC_M_USBHC_CONTROL_WRITE_SETUP,
     159
     160        /** Send control-transfer data to device.
     161         * See explanation at usb_iface_funcs_t (OUT transaction).
     162         */
     163        IPC_M_USBHC_CONTROL_WRITE_DATA,
     164
     165        /** Terminate WRITE control transfer.
     166         * See explanation at usb_iface_funcs_t (NO-DATA transaction).
     167         */
     168        IPC_M_USBHC_CONTROL_WRITE_STATUS,
     169
     170
     171
     172        /** Start READ control transfer.
     173         * See explanation at usb_iface_funcs_t (OUT transaction).
     174         */
     175        IPC_M_USBHC_CONTROL_READ_SETUP,
     176
     177        /** Get control-transfer data from device.
     178         * See explanation at usb_iface_funcs_t (IN transaction).
     179         */
     180        IPC_M_USBHC_CONTROL_READ_DATA,
     181
     182        /** Terminate READ control transfer.
     183         * See explanation at usb_iface_funcs_t (NO-DATA transaction).
     184         */
     185        IPC_M_USBHC_CONTROL_READ_STATUS,
     186
    155187        /** Issue control WRITE transfer.
    156188         * See explanation at usb_iface_funcs_t (OUT transaction) for
     
    161193        IPC_M_USBHC_CONTROL_WRITE,
    162194
    163         /** Issue control READ transfer.
     195        /** Issue control WRITE transfer.
    164196         * See explanation at usb_iface_funcs_t (IN transaction) for
    165197         * call parameters.
    166          * This call is immediately followed by IPC data write from the caller
    167          * (setup packet) and IPC data read (buffer that was read).
     198         * This call is immediately followed by IPC data read from the caller
     199         * (setup packet).
     200         * Actual data are retrieved through IPC_M_USBHC_GET_BUFFER.
    168201         */
    169202        IPC_M_USBHC_CONTROL_READ,
     
    198231        int (*tell_address)(device_t *, devman_handle_t, usb_address_t *);
    199232
    200         int (*reserve_default_address)(device_t *, usb_speed_t);
     233        int (*reserve_default_address)(device_t *);
    201234        int (*release_default_address)(device_t *);
    202         int (*request_address)(device_t *, usb_speed_t, usb_address_t *);
     235        int (*request_address)(device_t *, usb_address_t *);
    203236        int (*bind_address)(device_t *, usb_address_t, devman_handle_t);
    204237        int (*release_address)(device_t *, usb_address_t);
     
    206239        usbhc_iface_transfer_out_t interrupt_out;
    207240        usbhc_iface_transfer_in_t interrupt_in;
     241
     242        usbhc_iface_transfer_setup_t control_write_setup;
     243        usbhc_iface_transfer_out_t control_write_data;
     244        int (*control_write_status)(device_t *, usb_target_t,
     245            usbhc_iface_transfer_in_callback_t, void *);
     246
     247        usbhc_iface_transfer_setup_t control_read_setup;
     248        usbhc_iface_transfer_in_t control_read_data;
     249        int (*control_read_status)(device_t *, usb_target_t,
     250            usbhc_iface_transfer_out_callback_t, void *);
    208251
    209252        int (*control_write)(device_t *, usb_target_t,
  • uspace/lib/usb/include/usb/hub.h

    r6edc69a r7e7f0f5  
    3939#include <usb/usbdevice.h>
    4040
    41 int usb_hc_new_device_wrapper(device_t *, usb_hc_connection_t *, usb_speed_t,
    42     int (*)(int, void *), int, void *, usb_address_t *, devman_handle_t *);
    43 
    4441/** Info about device attached to host controller.
    4542 *
     
    5552} usb_hc_attached_device_t;
    5653
    57 int usb_hc_reserve_default_address(usb_hc_connection_t *, usb_speed_t);
     54int usb_hc_reserve_default_address(usb_hc_connection_t *);
    5855int usb_hc_release_default_address(usb_hc_connection_t *);
    5956
    60 usb_address_t usb_hc_request_address(usb_hc_connection_t *, usb_speed_t);
     57usb_address_t usb_hc_request_address(usb_hc_connection_t *);
    6158int usb_hc_register_device(usb_hc_connection_t *,
    6259    const usb_hc_attached_device_t *);
  • uspace/lib/usb/include/usb/usb.h

    r6edc69a r7e7f0f5  
    6868        USB_DIRECTION_BOTH
    6969} usb_direction_t;
    70 
    71 /** USB speeds. */
    72 typedef enum {
    73         /** USB 1.1 low speed (1.5Mbits/s). */
    74         USB_SPEED_LOW,
    75         /** USB 1.1 full speed (12Mbits/s). */
    76         USB_SPEED_FULL,
    77         /** USB 2.0 high speed (480Mbits/s). */
    78         USB_SPEED_HIGH
    79 } usb_speed_t;
    8070
    8171/** USB request type target. */
  • uspace/lib/usb/src/hub.c

    r6edc69a r7e7f0f5  
    3434 */
    3535#include <usb/hub.h>
    36 #include <usb/pipes.h>
    37 #include <usb/request.h>
    38 #include <usb/recognise.h>
    3936#include <usbhc_iface.h>
    4037#include <errno.h>
     
    5855 * @return Error code.
    5956 */
    60 int usb_hc_reserve_default_address(usb_hc_connection_t *connection,
    61     usb_speed_t speed)
     57int usb_hc_reserve_default_address(usb_hc_connection_t *connection)
    6258{
    6359        CHECK_CONNECTION(connection);
    6460
    65         return async_req_2_0(connection->hc_phone,
     61        return async_req_1_0(connection->hc_phone,
    6662            DEV_IFACE_ID(USBHC_DEV_IFACE),
    67             IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS, speed);
     63            IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
    6864}
    6965
     
    8783 * @return Assigned USB address or negative error code.
    8884 */
    89 usb_address_t usb_hc_request_address(usb_hc_connection_t *connection,
    90     usb_speed_t speed)
     85usb_address_t usb_hc_request_address(usb_hc_connection_t *connection)
    9186{
    9287        CHECK_CONNECTION(connection);
    9388
    9489        sysarg_t address;
    95         int rc = async_req_2_1(connection->hc_phone,
     90        int rc = async_req_1_1(connection->hc_phone,
    9691            DEV_IFACE_ID(USBHC_DEV_IFACE),
    97             IPC_M_USBHC_REQUEST_ADDRESS, speed,
    98             &address);
     92            IPC_M_USBHC_REQUEST_ADDRESS, &address);
    9993        if (rc != EOK) {
    10094                return (usb_address_t) rc;
     
    141135
    142136
    143 /** Wrapper for registering attached device to the hub.
    144  *
    145  * The @p enable_port function is expected to enable singalling on given
    146  * port.
    147  * The two arguments to it can have arbitrary meaning
    148  * (the @p port_no is only a suggestion)
    149  * and are not touched at all by this function
    150  * (they are passed as is to the @p enable_port function).
    151  *
    152  * If the @p enable_port fails (i.e. does not return EOK), the device
    153  * addition is cancelled.
    154  * The return value is then returned (it is good idea to use different
    155  * error codes than those listed as return codes by this function itself).
    156  *
    157  * @param parent Parent device (i.e. the hub device).
    158  * @param connection Opened connection to host controller.
    159  * @param dev_speed New device speed.
    160  * @param enable_port Function for enabling signalling through the port the
    161  *      device is attached to.
    162  * @param port_no Port number (passed through to @p enable_port).
    163  * @param arg Any data argument to @p enable_port.
    164  * @param[out] assigned_address USB address of the device.
    165  * @param[out] assigned_handle Devman handle of the new device.
    166  * @return Error code.
    167  * @retval ENOENT Connection to HC not opened.
    168  * @retval EADDRNOTAVAIL Failed retrieving free address from host controller.
    169  * @retval EBUSY Failed reserving default USB address.
    170  * @retval ENOTCONN Problem connecting to the host controller via USB pipe.
    171  * @retval ESTALL Problem communication with device (either SET_ADDRESS
    172  *      request or requests for descriptors when creating match ids).
    173  */
    174 int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection,
    175     usb_speed_t dev_speed,
    176     int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
    177     usb_address_t *assigned_address, devman_handle_t *assigned_handle)
    178 {
    179         CHECK_CONNECTION(connection);
    180 
    181         /*
    182          * Request new address.
    183          */
    184         usb_address_t dev_addr = usb_hc_request_address(connection, dev_speed);
    185         if (dev_addr < 0) {
    186                 return EADDRNOTAVAIL;
    187         }
    188 
    189         int rc;
    190 
    191         /*
    192          * Reserve the default address.
    193          */
    194         rc = usb_hc_reserve_default_address(connection, dev_speed);
    195         if (rc != EOK) {
    196                 rc = EBUSY;
    197                 goto leave_release_free_address;
    198         }
    199 
    200         /*
    201          * Enable the port (i.e. allow signalling through this port).
    202          */
    203         rc = enable_port(port_no, arg);
    204         if (rc != EOK) {
    205                 goto leave_release_default_address;
    206         }
    207 
    208         /*
    209          * Change the address from default to the free one.
    210          * We need to create a new control pipe for that.
    211          */
    212         usb_device_connection_t dev_conn;
    213         rc = usb_device_connection_initialize_on_default_address(&dev_conn,
    214             connection);
    215         if (rc != EOK) {
    216                 rc = ENOTCONN;
    217                 goto leave_release_default_address;
    218         }
    219 
    220         usb_endpoint_pipe_t ctrl_pipe;
    221         rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe,
    222             &dev_conn);
    223         if (rc != EOK) {
    224                 rc = ENOTCONN;
    225                 goto leave_release_default_address;
    226         }
    227 
    228         rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
    229         if (rc != EOK) {
    230                 rc = ENOTCONN;
    231                 goto leave_release_default_address;
    232         }
    233 
    234         rc = usb_request_set_address(&ctrl_pipe, dev_addr);
    235         if (rc != EOK) {
    236                 rc = ESTALL;
    237                 goto leave_stop_session;
    238         }
    239 
    240         usb_endpoint_pipe_end_session(&ctrl_pipe);
    241 
    242         /*
    243          * Once the address is changed, we can return the default address.
    244          */
    245         usb_hc_release_default_address(connection);
    246 
    247         /*
    248          * It is time to register the device with devman.
    249          */
    250         /* FIXME: create device_register that will get opened ctrl pipe. */
    251         devman_handle_t child_handle;
    252         rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
    253             parent, &child_handle);
    254         if (rc != EOK) {
    255                 rc = ESTALL;
    256                 goto leave_release_free_address;
    257         }
    258 
    259         /*
    260          * And now inform the host controller about the handle.
    261          */
    262         usb_hc_attached_device_t new_device = {
    263                 .address = dev_addr,
    264                 .handle = child_handle
    265         };
    266         rc = usb_hc_register_device(connection, &new_device);
    267         if (rc != EOK) {
    268                 rc = EDESTADDRREQ;
    269                 goto leave_release_free_address;
    270         }
    271 
    272         /*
    273          * And we are done.
    274          */
    275         if (assigned_address != NULL) {
    276                 *assigned_address = dev_addr;
    277         }
    278         if (assigned_handle != NULL) {
    279                 *assigned_handle = child_handle;
    280         }
    281 
    282         return EOK;
    283 
    284 
    285 
    286         /*
    287          * Error handling (like nested exceptions) starts here.
    288          * Completely ignoring errors here.
    289          */
    290 
    291 leave_stop_session:
    292         usb_endpoint_pipe_end_session(&ctrl_pipe);
    293 
    294 leave_release_default_address:
    295         usb_hc_release_default_address(connection);
    296 
    297 leave_release_free_address:
    298         usb_hc_unregister_device(connection, dev_addr);
    299 
    300         return rc;
    301 }
    302 
    303 
    304137/**
    305138 * @}
  • uspace/lib/usb/src/pipes.c

    r6edc69a r7e7f0f5  
    3535#include <usb/usb.h>
    3636#include <usb/pipes.h>
    37 #include <usbhc_iface.h>
    3837#include <errno.h>
    3938#include <assert.h>
    40 
    41 /** Tell USB address assigned to given device.
    42  *
    43  * @param phone Phone to my HC.
    44  * @param dev Device in question.
    45  * @return USB address or error code.
    46  */
    47 static usb_address_t get_my_address(int phone, device_t *dev)
    48 {
    49         sysarg_t address;
    50         int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
    51             IPC_M_USBHC_GET_ADDRESS,
    52             dev->handle, &address);
    53 
    54         if (rc != EOK) {
    55                 return rc;
    56         }
    57 
    58         return (usb_address_t) address;
    59 }
     39#include <usb/usbdrv.h>
    6040
    6141/** Initialize connection to USB device.
     
    7555        usb_address_t my_address;
    7656
    77         rc = usb_hc_find(device->handle, &hc_handle);
     57        rc = usb_drv_find_hc(device, &hc_handle);
    7858        if (rc != EOK) {
    7959                return rc;
     
    8565        }
    8666
    87         my_address = get_my_address(hc_phone, device);
     67        my_address = usb_drv_get_my_address(hc_phone, device);
    8868        if (my_address < 0) {
    8969                rc = my_address;
  • uspace/lib/usb/src/pipesio.c

    r6edc69a r7e7f0f5  
    7878         * Make call identifying target USB device and type of transfer.
    7979         */
    80         aid_t opening_request = async_send_4(pipe->hc_phone,
     80        aid_t opening_request = async_send_3(pipe->hc_phone,
    8181            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    8282            pipe->wire->address, pipe->endpoint_no,
    83             pipe->max_packet_size,
    8483            NULL);
    8584        if (opening_request == 0) {
     
    202201         * Make call identifying target USB device and type of transfer.
    203202         */
    204         aid_t opening_request = async_send_4(pipe->hc_phone,
     203        aid_t opening_request = async_send_3(pipe->hc_phone,
    205204            DEV_IFACE_ID(USBHC_DEV_IFACE), ipc_method,
    206205            pipe->wire->address, pipe->endpoint_no,
    207             pipe->max_packet_size,
    208206            NULL);
    209207        if (opening_request == 0) {
     
    285283         * Make call identifying target USB device and control transfer type.
    286284         */
    287         aid_t opening_request = async_send_4(pipe->hc_phone,
     285        aid_t opening_request = async_send_3(pipe->hc_phone,
    288286            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_READ,
    289287            pipe->wire->address, pipe->endpoint_no,
    290             pipe->max_packet_size,
    291288            NULL);
    292289        if (opening_request == 0) {
     
    405402         * Make call identifying target USB device and control transfer type.
    406403         */
    407         aid_t opening_request = async_send_5(pipe->hc_phone,
     404        aid_t opening_request = async_send_4(pipe->hc_phone,
    408405            DEV_IFACE_ID(USBHC_DEV_IFACE), IPC_M_USBHC_CONTROL_WRITE,
    409406            pipe->wire->address, pipe->endpoint_no,
    410407            data_buffer_size,
    411             pipe->max_packet_size,
    412408            NULL);
    413409        if (opening_request == 0) {
  • uspace/lib/usb/src/usbdrv.c

    r6edc69a r7e7f0f5  
    3434 */
    3535#include <usb/usbdrv.h>
     36#include <usbhc_iface.h>
     37#include <usb_iface.h>
    3638#include <errno.h>
    37 
     39#include <str_error.h>
     40
     41/** Information about pending transaction on HC. */
     42typedef struct {
     43        /** Phone to host controller driver. */
     44        int phone;
     45        /** Data buffer. */
     46        void *buffer;
     47        /** Buffer size. */
     48        size_t size;
     49        /** Storage for actual number of bytes transferred. */
     50        size_t *size_transferred;
     51        /** Initial call reply data. */
     52        ipc_call_t reply;
     53        /** Initial call identifier. */
     54        aid_t request;
     55        /** Reply data for data read call. */
     56        ipc_call_t read_reply;
     57        /** Data read call identifier. */
     58        aid_t read_request;
     59} transfer_info_t;
    3860
    3961/** Find handle of host controller the device is physically attached to.
     
    4567int usb_drv_find_hc(device_t *dev, devman_handle_t *handle)
    4668{
    47         return ENOTSUP;
     69        if (dev == NULL) {
     70                return EBADMEM;
     71        }
     72        if (handle == NULL) {
     73                return EBADMEM;
     74        }
     75
     76        int parent_phone = devman_parent_device_connect(dev->handle,
     77            IPC_FLAG_BLOCKING);
     78        if (parent_phone < 0) {
     79                return parent_phone;
     80        }
     81
     82        devman_handle_t h;
     83        int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
     84            IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
     85
     86        async_hangup(parent_phone);
     87
     88        if (rc != EOK) {
     89                return rc;
     90        }
     91
     92        *handle = h;
     93
     94        return EOK;
    4895}
    4996
     
    58105    unsigned int flags)
    59106{
    60         return ENOTSUP;
     107        return devman_device_connect(hc_handle, flags);
    61108}
    62109
     
    69116int usb_drv_hc_connect_auto(device_t *dev, unsigned int flags)
    70117{
    71         return ENOTSUP;
     118        int rc;
     119        devman_handle_t hc_handle;
     120
     121        /*
     122         * Call parent hub to obtain device handle of respective HC.
     123         */
     124        rc = usb_drv_find_hc(dev, &hc_handle);
     125        if (rc != EOK) {
     126                return rc;
     127        }
     128       
     129        return usb_drv_hc_connect(dev, hc_handle, flags);
    72130}
    73131
     
    80138usb_address_t usb_drv_get_my_address(int phone, device_t *dev)
    81139{
    82         return ENOTSUP;
     140        sysarg_t address;
     141        int rc = async_req_2_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     142            IPC_M_USBHC_GET_ADDRESS,
     143            dev->handle, &address);
     144
     145        if (rc != EOK) {
     146                return rc;
     147        }
     148
     149        return (usb_address_t) address;
    83150}
    84151
     
    90157int usb_drv_reserve_default_address(int phone)
    91158{
    92         return ENOTSUP;
     159        return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     160            IPC_M_USBHC_RESERVE_DEFAULT_ADDRESS);
    93161}
    94162
     
    100168int usb_drv_release_default_address(int phone)
    101169{
    102         return ENOTSUP;
     170        return async_req_1_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     171            IPC_M_USBHC_RELEASE_DEFAULT_ADDRESS);
    103172}
    104173
     
    110179usb_address_t usb_drv_request_address(int phone)
    111180{
    112         return ENOTSUP;
     181        sysarg_t address;
     182        int rc = async_req_1_1(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     183            IPC_M_USBHC_REQUEST_ADDRESS, &address);
     184        if (rc != EOK) {
     185                return rc;
     186        } else {
     187                return (usb_address_t) address;
     188        }
    113189}
    114190
     
    123199    devman_handle_t handle)
    124200{
    125         return ENOTSUP;
     201        int rc = async_req_3_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     202            IPC_M_USBHC_BIND_ADDRESS,
     203            address, handle);
     204
     205        return rc;
    126206}
    127207
     
    134214int usb_drv_release_address(int phone, usb_address_t address)
    135215{
    136         return ENOTSUP;
    137 }
     216        return async_req_2_0(phone, DEV_IFACE_ID(USBHC_DEV_IFACE),
     217            IPC_M_USBHC_RELEASE_ADDRESS, address);
     218}
     219
     220/** Send data to HCD.
     221 *
     222 * @param phone Phone to HC.
     223 * @param method Method used for calling.
     224 * @param target Targeted device.
     225 * @param buffer Data buffer (NULL to skip data transfer phase).
     226 * @param size Buffer size (must be zero when @p buffer is NULL).
     227 * @param handle Storage for transaction handle (cannot be NULL).
     228 * @return Error status.
     229 * @retval EINVAL Invalid parameter.
     230 * @retval ENOMEM Not enough memory to complete the operation.
     231 */
     232static int async_send_buffer(int phone, int method,
     233    usb_target_t target,
     234    void *buffer, size_t size,
     235    usb_handle_t *handle)
     236{
     237        if (phone < 0) {
     238                return EINVAL;
     239        }
     240
     241        if ((buffer == NULL) && (size > 0)) {
     242                return EINVAL;
     243        }
     244
     245        if (handle == NULL) {
     246                return EINVAL;
     247        }
     248
     249        transfer_info_t *transfer
     250            = (transfer_info_t *) malloc(sizeof(transfer_info_t));
     251        if (transfer == NULL) {
     252                return ENOMEM;
     253        }
     254
     255        transfer->read_request = 0;
     256        transfer->size_transferred = NULL;
     257        transfer->buffer = NULL;
     258        transfer->size = 0;
     259        transfer->phone = phone;
     260
     261        int rc;
     262
     263        transfer->request = async_send_4(phone,
     264            DEV_IFACE_ID(USBHC_DEV_IFACE),
     265            method,
     266            target.address, target.endpoint,
     267            size,
     268            &transfer->reply);
     269
     270        if (size > 0) {
     271                rc = async_data_write_start(phone, buffer, size);
     272                if (rc != EOK) {
     273                        async_wait_for(transfer->request, NULL);
     274                        return rc;
     275                }
     276        }
     277
     278        *handle = (usb_handle_t) transfer;
     279
     280        return EOK;
     281}
     282
     283/** Prepare data retrieval.
     284 *
     285 * @param phone Opened phone to HCD.
     286 * @param method Method used for calling.
     287 * @param target Targeted device.
     288 * @param buffer Buffer where to store retrieved data
     289 *      (NULL to skip data transfer phase).
     290 * @param size Buffer size (must be zero when @p buffer is NULL).
     291 * @param actual_size Storage where actual number of bytes transferred will
     292 *      be stored.
     293 * @param handle Storage for transaction handle (cannot be NULL).
     294 * @return Error status.
     295 * @retval EINVAL Invalid parameter.
     296 * @retval ENOMEM Not enough memory to complete the operation.
     297 */
     298static int async_recv_buffer(int phone, int method,
     299    usb_target_t target,
     300    void *buffer, size_t size, size_t *actual_size,
     301    usb_handle_t *handle)
     302{
     303        if (phone < 0) {
     304                return EINVAL;
     305        }
     306
     307        if ((buffer == NULL) && (size > 0)) {
     308                return EINVAL;
     309        }
     310
     311        if (handle == NULL) {
     312                return EINVAL;
     313        }
     314
     315        transfer_info_t *transfer
     316            = (transfer_info_t *) malloc(sizeof(transfer_info_t));
     317        if (transfer == NULL) {
     318                return ENOMEM;
     319        }
     320
     321        transfer->read_request = 0;
     322        transfer->size_transferred = actual_size;
     323        transfer->buffer = buffer;
     324        transfer->size = size;
     325        transfer->phone = phone;
     326
     327        transfer->request = async_send_4(phone,
     328            DEV_IFACE_ID(USBHC_DEV_IFACE),
     329            method,
     330            target.address, target.endpoint,
     331            size,
     332            &transfer->reply);
     333
     334        if (buffer != NULL) {
     335                transfer->read_request = async_data_read(phone, buffer, size,
     336                    &transfer->read_reply);
     337        }
     338
     339        *handle = (usb_handle_t) transfer;
     340
     341        return EOK;
     342}
     343
    138344
    139345/** Blocks caller until given USB transaction is finished.
     
    149355int usb_drv_async_wait_for(usb_handle_t handle)
    150356{
    151         return ENOTSUP;
     357        if (handle == 0) {
     358                return EBADMEM;
     359        }
     360
     361        int rc = EOK;
     362
     363        transfer_info_t *transfer = (transfer_info_t *) handle;
     364
     365        sysarg_t answer_rc;
     366
     367        /*
     368         * If the buffer is not NULL, we must accept some data.
     369         */
     370        if ((transfer->buffer != NULL) && (transfer->size > 0)) {
     371                async_wait_for(transfer->read_request, &answer_rc);
     372
     373                if (answer_rc != EOK) {
     374                        rc = (int) answer_rc;
     375                        goto leave;
     376                }
     377
     378                if (transfer->size_transferred != NULL) {
     379                        *(transfer->size_transferred)
     380                            = IPC_GET_ARG2(transfer->read_reply);
     381                }
     382        }
     383
     384        async_wait_for(transfer->request, &answer_rc);
     385
     386        if (answer_rc != EOK) {
     387                rc = (int) answer_rc;
     388                goto leave;
     389        }
     390
     391leave:
     392        free(transfer);
     393
     394        return rc;
    152395}
    153396
     
    157400    usb_handle_t *handle)
    158401{
    159         return ENOTSUP;
     402        return async_send_buffer(phone,
     403            IPC_M_USBHC_INTERRUPT_OUT,
     404            target,
     405            buffer, size,
     406            handle);
    160407}
    161408
     
    165412    usb_handle_t *handle)
    166413{
    167         return ENOTSUP;
     414        return async_recv_buffer(phone,
     415            IPC_M_USBHC_INTERRUPT_IN,
     416            target,
     417            buffer, size, actual_size,
     418            handle);
    168419}
    169420
     
    173424    usb_handle_t *handle)
    174425{
    175         return ENOTSUP;
     426        return async_send_buffer(phone,
     427            IPC_M_USBHC_CONTROL_WRITE_SETUP,
     428            target,
     429            buffer, size,
     430            handle);
    176431}
    177432
     
    181436    usb_handle_t *handle)
    182437{
    183         return ENOTSUP;
     438        return async_send_buffer(phone,
     439            IPC_M_USBHC_CONTROL_WRITE_DATA,
     440            target,
     441            buffer, size,
     442            handle);
    184443}
    185444
     
    188447    usb_handle_t *handle)
    189448{
    190         return ENOTSUP;
     449        return async_recv_buffer(phone,
     450            IPC_M_USBHC_CONTROL_WRITE_STATUS,
     451            target,
     452            NULL, 0, NULL,
     453            handle);
    191454}
    192455
     
    197460    usb_handle_t *handle)
    198461{
    199         return ENOTSUP;
     462        // FIXME - check input parameters instead of asserting them
     463        assert(phone > 0);
     464        assert(setup_packet != NULL);
     465        assert(setup_packet_size > 0);
     466        assert(((buffer != NULL) && (buffer_size > 0))
     467            || ((buffer == NULL) && (buffer_size == 0)));
     468        assert(handle != NULL);
     469
     470        transfer_info_t *transfer
     471            = (transfer_info_t *) malloc(sizeof(transfer_info_t));
     472        if (transfer == NULL) {
     473                return ENOMEM;
     474        }
     475
     476        transfer->read_request = 0;
     477        transfer->size_transferred = NULL;
     478        transfer->buffer = NULL;
     479        transfer->size = 0;
     480        transfer->phone = phone;
     481
     482        int rc;
     483
     484        transfer->request = async_send_3(phone,
     485            DEV_IFACE_ID(USBHC_DEV_IFACE),
     486            IPC_M_USBHC_CONTROL_WRITE,
     487            target.address, target.endpoint,
     488            &transfer->reply);
     489
     490        rc = async_data_write_start(phone, setup_packet, setup_packet_size);
     491        if (rc != EOK) {
     492                async_wait_for(transfer->request, NULL);
     493                return rc;
     494        }
     495
     496        if (buffer_size > 0) {
     497                rc = async_data_write_start(phone, buffer, buffer_size);
     498                if (rc != EOK) {
     499                        async_wait_for(transfer->request, NULL);
     500                        return rc;
     501                }
     502        }
     503
     504        *handle = (usb_handle_t) transfer;
     505
     506        return EOK;
    200507}
    201508
     
    205512    usb_handle_t *handle)
    206513{
    207         return ENOTSUP;
     514        return async_send_buffer(phone,
     515            IPC_M_USBHC_CONTROL_READ_SETUP,
     516            target,
     517            buffer, size,
     518            handle);
    208519}
    209520
     
    213524    usb_handle_t *handle)
    214525{
    215         return ENOTSUP;
     526        return async_recv_buffer(phone,
     527            IPC_M_USBHC_CONTROL_READ_DATA,
     528            target,
     529            buffer, size, actual_size,
     530            handle);
    216531}
    217532
     
    220535    usb_handle_t *handle)
    221536{
    222         return ENOTSUP;
     537        return async_send_buffer(phone,
     538            IPC_M_USBHC_CONTROL_READ_STATUS,
     539            target,
     540            NULL, 0,
     541            handle);
    223542}
    224543
     
    229548    usb_handle_t *handle)
    230549{
    231         return ENOTSUP;
     550        // FIXME - check input parameters instead of asserting them
     551        assert(phone > 0);
     552        assert(setup_packet != NULL);
     553        assert(setup_packet_size > 0);
     554        assert(buffer != NULL);
     555        assert(buffer_size > 0);
     556        assert(handle != NULL);
     557
     558        transfer_info_t *transfer
     559            = (transfer_info_t *) malloc(sizeof(transfer_info_t));
     560        if (transfer == NULL) {
     561                return ENOMEM;
     562        }
     563
     564        transfer->size_transferred = actual_size;
     565        transfer->buffer = buffer;
     566        transfer->size = buffer_size;
     567        transfer->phone = phone;
     568
     569        int rc;
     570
     571        transfer->request = async_send_4(phone,
     572            DEV_IFACE_ID(USBHC_DEV_IFACE),
     573            IPC_M_USBHC_CONTROL_READ,
     574            target.address, target.endpoint,
     575            buffer_size,
     576            &transfer->reply);
     577
     578        rc = async_data_write_start(phone, setup_packet, setup_packet_size);
     579        if (rc != EOK) {
     580                async_wait_for(transfer->request, NULL);
     581                return rc;
     582        }
     583
     584        transfer->read_request = async_data_read(phone, buffer, buffer_size,
     585            &transfer->read_reply);
     586
     587        *handle = (usb_handle_t) transfer;
     588
     589        return EOK;
    232590}
    233591
Note: See TracChangeset for help on using the changeset viewer.