Changeset b00849e in mainline


Ignore:
Timestamp:
2011-02-02T00:57:32Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1537ba6, 3597dab
Parents:
2cea1045 (diff), 2f4438f5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merged pipe API

The pipe API shall eventually replace USB device drivers API explicitly
using phones. This API uses extra abstraction level by introducing
device connection (the wire) and endpoint pipe.

The USB HID driver uses the new API, hub driver does not.

Location:
uspace
Files:
5 added
15 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/usbinfo/dump.c

    r2cea1045 rb00849e  
    9696void dump_usb_descriptor(uint8_t *descriptor, size_t size)
    9797{
     98        printf("Device descriptor:\n");
    9899        usb_dump_standard_descriptor(stdout, get_indent(0), "\n",
    99100            descriptor, size);
  • uspace/app/usbinfo/info.c

    r2cea1045 rb00849e  
    3838#include <errno.h>
    3939#include <usb/usbdrv.h>
     40#include <usb/pipes.h>
     41#include <usb/request.h>
    4042#include "usbinfo.h"
    4143
    42 int dump_device(int hc_phone, usb_address_t address)
     44int dump_device(devman_handle_t hc_handle, usb_address_t address)
    4345{
     46        int rc;
     47        usb_device_connection_t wire;
     48        usb_endpoint_pipe_t ctrl_pipe;
     49        ctrl_pipe.hc_phone = -1;
     50
     51        int hc_phone = devman_device_connect(hc_handle, 0);
     52        if (hc_phone < 0) {
     53                fprintf(stderr,
     54                    NAME ": failed to connect to host controller (%zu): %s.\n",
     55                        (size_t) hc_handle, str_error(hc_phone));
     56                return hc_phone;
     57        }
     58
    4459        /*
    4560         * Dump information about possible match ids.
     
    4762        match_id_list_t match_id_list;
    4863        init_match_ids(&match_id_list);
    49         int rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);
     64        rc = usb_drv_create_device_match_ids(hc_phone, &match_id_list, address);
    5065        if (rc != EOK) {
    5166                fprintf(stderr,
    5267                    NAME ": failed to fetch match ids of the device: %s.\n",
    5368                    str_error(rc));
    54                 return rc;
     69                goto leave;
    5570        }
    5671        dump_match_ids(&match_id_list);
     72
     73        /*
     74         * Initialize pipes.
     75         */
     76        rc = usb_device_connection_initialize(&wire, hc_handle, address);
     77        if (rc != EOK) {
     78                fprintf(stderr,
     79                    NAME ": failed to create connection to the device: %s.\n",
     80                    str_error(rc));
     81                goto leave;
     82        }
     83        rc = usb_endpoint_pipe_initialize_default_control(&ctrl_pipe, &wire);
     84        if (rc != EOK) {
     85                fprintf(stderr,
     86                    NAME ": failed to create default control pipe: %s.\n",
     87                    str_error(rc));
     88                goto leave;
     89        }
     90        rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
     91        if (rc != EOK) {
     92                fprintf(stderr,
     93                    NAME ": failed to start session on control pipe: %s.\n",
     94                    str_error(rc));
     95                goto leave;
     96        }
    5797
    5898        /*
     
    60100         */
    61101        usb_standard_device_descriptor_t device_descriptor;
    62         usb_dprintf(NAME, 1,
    63             "usb_drv_req_get_device_descriptor(%d, %d, %p)\n",
    64             hc_phone, (int) address, &device_descriptor);
    65 
    66         rc = usb_drv_req_get_device_descriptor(hc_phone, address,
    67             &device_descriptor);
     102        rc = usb_request_get_device_descriptor(&ctrl_pipe, &device_descriptor);
    68103        if (rc != EOK) {
    69104                fprintf(stderr,
    70105                    NAME ": failed to fetch standard device descriptor: %s.\n",
    71106                    str_error(rc));
    72                 return rc;
     107                goto leave;
    73108        }
    74109        dump_usb_descriptor((uint8_t *)&device_descriptor, sizeof(device_descriptor));
     
    79114        usb_standard_configuration_descriptor_t config_descriptor;
    80115        int config_index = 0;
    81         usb_dprintf(NAME, 1,
    82             "usb_drv_req_get_bare_configuration_descriptor(%d, %d, %d, %p)\n",
    83             hc_phone, (int) address, config_index, &config_descriptor);
    84 
    85         rc = usb_drv_req_get_bare_configuration_descriptor(hc_phone, address,
    86             config_index, &config_descriptor );
     116        rc = usb_request_get_bare_configuration_descriptor(&ctrl_pipe,
     117            config_index, &config_descriptor);
    87118        if (rc != EOK) {
    88119                fprintf(stderr,
    89120                    NAME ": failed to fetch standard configuration descriptor: %s.\n",
    90121                    str_error(rc));
    91                 return rc;
     122                goto leave;
    92123        }
    93124        //dump_standard_configuration_descriptor(config_index, &config_descriptor);
    94125
    95126        void *full_config_descriptor = malloc(config_descriptor.total_length);
    96         usb_dprintf(NAME, 1,
    97             "usb_drv_req_get_full_configuration_descriptor(%d, %d, %d, %p, %zu)\n",
    98             hc_phone, (int) address, config_index,
    99             full_config_descriptor, config_descriptor.total_length);
    100 
    101         rc = usb_drv_req_get_full_configuration_descriptor(hc_phone, address,
     127        rc = usb_request_get_full_configuration_descriptor(&ctrl_pipe,
    102128            config_index,
    103129            full_config_descriptor, config_descriptor.total_length, NULL);
     
    106132                    NAME ": failed to fetch full configuration descriptor: %s.\n",
    107133                    str_error(rc));
    108                 return rc;
     134                goto leave;
    109135        }
    110136
     
    112138            config_descriptor.total_length);
    113139
    114         return EOK;
     140        rc = EOK;
     141leave:
     142        /* Ignoring errors here. */
     143        ipc_hangup(hc_phone);
     144        usb_endpoint_pipe_end_session(&ctrl_pipe);
     145
     146        return rc;
    115147}
    116148
  • uspace/app/usbinfo/main.c

    r2cea1045 rb00849e  
    7777}
    7878
    79 static int set_new_host_controller(int *phone, const char *path)
     79static int get_host_controller_handle(const char *path,
     80    devman_handle_t *hc_handle)
    8081{
    8182        int rc;
    82         int tmp_phone;
    8383
    84         if (path[0] != '/') {
    85                 int hc_class_index = (int) strtol(path, NULL, 10);
    86                 char *dev_path;
    87                 rc = asprintf(&dev_path, "class/usbhc\\%d", hc_class_index);
    88                 if (rc < 0) {
    89                         internal_error(rc);
    90                         return rc;
    91                 }
    92                 devmap_handle_t handle;
    93                 rc = devmap_device_get_handle(dev_path, &handle, 0);
    94                 if (rc < 0) {
    95                         fprintf(stderr,
    96                             NAME ": failed getting handle of `devman://%s'.\n",
    97                             dev_path);
    98                         free(dev_path);
    99                         return rc;
    100                 }
    101                 tmp_phone = devmap_device_connect(handle, 0);
    102                 if (tmp_phone < 0) {
    103                         fprintf(stderr,
    104                             NAME ": could not connect to `%s'.\n",
    105                             dev_path);
    106                         free(dev_path);
    107                         return tmp_phone;
    108                 }
    109                 free(dev_path);
    110         } else {
    111                 devman_handle_t handle;
    112                 rc = devman_device_get_handle(path, &handle, 0);
    113                 if (rc != EOK) {
    114                         fprintf(stderr,
    115                             NAME ": failed getting handle of `devmap::/%s'.\n",
    116                             path);
    117                         return rc;
    118                 }
    119                 tmp_phone = devman_device_connect(handle, 0);
    120                 if (tmp_phone < 0) {
    121                         fprintf(stderr,
    122                             NAME ": could not connect to `%s'.\n",
    123                             path);
    124                         return tmp_phone;
    125                 }
     84        devman_handle_t handle;
     85        rc = devman_device_get_handle(path, &handle, 0);
     86        if (rc != EOK) {
     87                fprintf(stderr,
     88                    NAME ": failed getting handle of `devman::/%s'.\n",
     89                    path);
     90                return rc;
    12691        }
    127 
    128         *phone = tmp_phone;
     92        *hc_handle = handle;
    12993
    13094        return EOK;
    13195}
    13296
    133 static int connect_with_address(int hc_phone, const char *str_address)
     97static int get_device_address(const char *str_address, usb_address_t *address)
    13498{
    135         usb_address_t address = (usb_address_t) strtol(str_address, NULL, 0);
    136         if ((address < 0) || (address >= USB11_ADDRESS_MAX)) {
     99        usb_address_t addr = (usb_address_t) strtol(str_address, NULL, 0);
     100        if ((addr < 0) || (addr >= USB11_ADDRESS_MAX)) {
    137101                fprintf(stderr, NAME ": USB address out of range.\n");
    138102                return ERANGE;
    139103        }
    140104
    141         if (hc_phone < 0) {
    142                 fprintf(stderr, NAME ": no active host controller.\n");
    143                 return ENOENT;
    144         }
    145 
    146         return dump_device(hc_phone, address);
     105        *address = addr;
     106        return EOK;
    147107}
    148108
     
    150110int main(int argc, char *argv[])
    151111{
    152         int hc_phone = -1;
     112        devman_handle_t hc_handle = (devman_handle_t) -1;
     113        usb_address_t device_address = (usb_address_t) -1;
    153114
    154115        if (argc <= 1) {
     
    175136                        case 'a':
    176137                        case ACTION_DEVICE_ADDRESS: {
    177                                 int rc = connect_with_address(hc_phone, optarg);
     138                                int rc = get_device_address(optarg,
     139                                    &device_address);
    178140                                if (rc != EOK) {
    179141                                        return rc;
     
    184146                        case 't':
    185147                        case ACTION_HOST_CONTROLLER: {
    186                                 int rc = set_new_host_controller(&hc_phone,
    187                                     optarg);
     148                                int rc = get_host_controller_handle(optarg,
     149                                   &hc_handle);
    188150                                if (rc != EOK) {
    189151                                        return rc;
     
    202164        } while (i != -1);
    203165
     166        if ((hc_handle == (devman_handle_t) -1)
     167            || (device_address == (usb_address_t) -1)) {
     168                fprintf(stderr, NAME ": no target specified.\n");
     169                return EINVAL;
     170        }
     171
     172        dump_device(hc_handle, device_address);
     173
    204174        return 0;
    205175}
  • uspace/app/usbinfo/usbinfo.h

    r2cea1045 rb00849e  
    4747void dump_match_ids(match_id_list_t *matches);
    4848void dump_usb_descriptor(uint8_t *, size_t);
    49 int dump_device(int, usb_address_t);
     49int dump_device(devman_handle_t, usb_address_t);
    5050void dump_descriptor_tree(uint8_t *, size_t);
    5151
  • uspace/drv/usbhid/descdump.h

    r2cea1045 rb00849e  
    3737#define USBHID_DESCDUMP_H_
    3838
    39 #include <usb/classes/hid.h>
     39#include "hid.h"
    4040
    4141void dump_standard_configuration_descriptor(
  • uspace/drv/usbhid/descparser.h

    r2cea1045 rb00849e  
    3737#define USBHID_DESCPARSER_H_
    3838
    39 #include <usb/classes/hid.h>
     39#include "hid.h"
    4040
    4141int usbkbd_parse_descriptors(const uint8_t *data, size_t size,
  • uspace/drv/usbhid/main.c

    r2cea1045 rb00849e  
    4343#include <io/console.h>
    4444#include <errno.h>
     45#include <str_error.h>
    4546#include <fibril.h>
    4647#include <usb/classes/hid.h>
    4748#include <usb/classes/hidparser.h>
    48 #include <usb/devreq.h>
     49#include <usb/request.h>
    4950#include <usb/descriptor.h>
    5051#include <io/console.h>
     52#include "hid.h"
    5153#include "descparser.h"
    5254#include "descdump.h"
     
    278280               
    279281                // get the descriptor from the device
    280                 int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone,
    281                     kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    282                     0, i, kbd_dev->conf->interfaces[i].report_desc, length,
     282                int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     283                    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
     284                    i, 0,
     285                    kbd_dev->conf->interfaces[i].report_desc, length,
    283286                    &actual_size);
    284287
     
    301304        usb_standard_configuration_descriptor_t config_desc;
    302305       
    303         int rc = usb_drv_req_get_bare_configuration_descriptor(
    304             kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
     306        int rc;
     307        rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
     308            0, &config_desc);
    305309       
    306310        if (rc != EOK) {
     
    316320        size_t transferred = 0;
    317321        // get full configuration descriptor
    318         rc = usb_drv_req_get_full_configuration_descriptor(
    319             kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
     322        rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
     323            0, descriptors,
    320324            config_desc.total_length, &transferred);
    321325       
     
    364368static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
    365369{
     370        int rc;
     371
    366372        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1,
    367373            sizeof(usb_hid_dev_kbd_t));
     
    374380        kbd_dev->device = dev;
    375381
    376         // get phone to my HC and save it as my parent's phone
    377         // TODO: maybe not a good idea if DDF will use parent_phone
    378         int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
    379         if (rc < 0) {
    380                 printf("Problem setting phone to HC.\n");
    381                 free(kbd_dev);
    382                 return NULL;
    383         }
    384 
    385         rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev);
    386         if (rc < 0) {
    387                 printf("Problem getting address of the device.\n");
    388                 free(kbd_dev);
    389                 return NULL;
    390         }
    391 
    392         // doesn't matter now that we have no address
    393 //      if (kbd_dev->address < 0) {
    394 //              fprintf(stderr, NAME ": No device address!\n");
    395 //              free(kbd_dev);
    396 //              return NULL;
    397 //      }
    398 
    399         // default endpoint
    400         kbd_dev->poll_endpoint = GUESSED_POLL_ENDPOINT;
    401        
     382        /*
     383         * Initialize the backing connection to the host controller.
     384         */
     385        rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev);
     386        if (rc != EOK) {
     387                printf("Problem initializing connection to device: %s.\n",
     388                    str_error(rc));
     389                goto error_leave;
     390        }
     391
     392        /*
     393         * Initialize device pipes.
     394         */
     395        rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,
     396            &kbd_dev->wire);
     397        if (rc != EOK) {
     398                printf("Failed to initialize default control pipe: %s.\n",
     399                    str_error(rc));
     400                goto error_leave;
     401        }
     402
     403        rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire,
     404            GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, USB_DIRECTION_IN);
     405        if (rc != EOK) {
     406                printf("Failed to initialize interrupt in pipe: %s.\n",
     407                    str_error(rc));
     408                goto error_leave;
     409        }
     410
    402411        /*
    403412         * will need all descriptors:
    404          * 1) choose one configuration from configuration descriptors 
     413         * 1) choose one configuration from configuration descriptors
    405414         *    (set it to the device)
    406415         * 2) set endpoints from endpoint descriptors
     
    408417
    409418        // TODO: get descriptors, parse descriptors and save endpoints
     419        usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
    410420        usbkbd_process_descriptors(kbd_dev);
     421        usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
    411422
    412423        return kbd_dev;
     424
     425error_leave:
     426        free(kbd_dev);
     427        return NULL;
    413428}
    414429
     
    435450static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev)
    436451{
    437         int rc;
    438         usb_handle_t handle;
     452        int rc, sess_rc;
    439453        uint8_t buffer[BUFFER_SIZE];
    440454        size_t actual_size;
    441         //usb_endpoint_t poll_endpoint = 1;
    442 
    443 //      usb_address_t my_address = usb_drv_get_my_address(dev->parent_phone,
    444 //          dev);
    445 //      if (my_address < 0) {
    446 //              return;
    447 //      }
    448 
    449         usb_target_t poll_target = {
    450                 .address = kbd_dev->address,
    451                 .endpoint = kbd_dev->poll_endpoint
    452         };
    453455
    454456        printf("Polling keyboard...\n");
     
    456458        while (true) {
    457459                async_usleep(1000 * 1000 * 2);
    458                 rc = usb_drv_async_interrupt_in(kbd_dev->device->parent_phone,
    459                     poll_target, buffer, BUFFER_SIZE, &actual_size, &handle);
     460
     461                sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe);
     462                if (sess_rc != EOK) {
     463                        printf("Failed to start a session: %s.\n",
     464                            str_error(sess_rc));
     465                        continue;
     466                }
     467
     468                rc = usb_endpoint_pipe_read(&kbd_dev->poll_pipe, buffer,
     469                    BUFFER_SIZE, &actual_size);
     470                sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->poll_pipe);
    460471
    461472                if (rc != EOK) {
    462                         printf("Error in usb_drv_async_interrupt_in(): %d\n", rc);
     473                        printf("Error polling the keyboard: %s.\n",
     474                            str_error(rc));
    463475                        continue;
    464476                }
    465477
    466                 rc = usb_drv_async_wait_for(handle);
    467                 if (rc != EOK) {
    468                         printf("Error in usb_drv_async_wait_for(): %d\n", rc);
     478                if (sess_rc != EOK) {
     479                        printf("Error closing session: %s.\n",
     480                            str_error(sess_rc));
    469481                        continue;
    470482                }
  • uspace/drv/vhc/connhost.c

    r2cea1045 rb00849e  
    4242#include "hc.h"
    4343
     44
    4445typedef struct {
    4546        usb_direction_t direction;
     
    4748        usbhc_iface_transfer_in_callback_t in_callback;
    4849        device_t *dev;
     50        size_t reported_size;
    4951        void *arg;
    5052} transfer_info_t;
    5153
     54typedef struct {
     55        usb_direction_t direction;
     56        usb_target_t target;
     57        usbhc_iface_transfer_out_callback_t out_callback;
     58        usbhc_iface_transfer_in_callback_t in_callback;
     59        device_t *dev;
     60        void *arg;
     61        void *data_buffer;
     62        size_t data_buffer_size;
     63} control_transfer_info_t;
     64
    5265static void universal_callback(void *buffer, size_t size,
    5366    usb_transaction_outcome_t outcome, void *arg)
    5467{
    5568        transfer_info_t *transfer = (transfer_info_t *) arg;
     69
     70        if (transfer->reported_size != (size_t) -1) {
     71                size = transfer->reported_size;
     72        }
    5673
    5774        switch (transfer->direction) {
     
    84101        transfer->arg = arg;
    85102        transfer->dev = dev;
     103        transfer->reported_size = (size_t) -1;
     104
     105        return transfer;
     106}
     107
     108static void control_abort_prematurely(control_transfer_info_t *transfer,
     109    size_t size, usb_transaction_outcome_t outcome)
     110{
     111        switch (transfer->direction) {
     112                case USB_DIRECTION_IN:
     113                        transfer->in_callback(transfer->dev,
     114                            outcome, size,
     115                            transfer->arg);
     116                        break;
     117                case USB_DIRECTION_OUT:
     118                        transfer->out_callback(transfer->dev,
     119                            outcome,
     120                            transfer->arg);
     121                        break;
     122                default:
     123                        assert(false && "unreachable");
     124                        break;
     125        }
     126}
     127
     128static void control_callback_two(void *buffer, size_t size,
     129    usb_transaction_outcome_t outcome, void *arg)
     130{
     131        control_transfer_info_t *ctrl_transfer = (control_transfer_info_t *) arg;
     132
     133        if (outcome != USB_OUTCOME_OK) {
     134                control_abort_prematurely(ctrl_transfer, outcome, size);
     135                free(ctrl_transfer);
     136                return;
     137        }
     138
     139        transfer_info_t *transfer  = create_transfer_info(ctrl_transfer->dev,
     140            ctrl_transfer->direction, ctrl_transfer->arg);
     141        transfer->out_callback = ctrl_transfer->out_callback;
     142        transfer->in_callback = ctrl_transfer->in_callback;
     143        transfer->reported_size = size;
     144
     145        switch (ctrl_transfer->direction) {
     146                case USB_DIRECTION_IN:
     147                        hc_add_transaction_to_device(false, ctrl_transfer->target,
     148                            USB_TRANSFER_CONTROL,
     149                            NULL, 0,
     150                            universal_callback, transfer);
     151                        break;
     152                case USB_DIRECTION_OUT:
     153                        hc_add_transaction_from_device(ctrl_transfer->target,
     154                            USB_TRANSFER_CONTROL,
     155                            NULL, 0,
     156                            universal_callback, transfer);
     157                        break;
     158                default:
     159                        assert(false && "unreachable");
     160                        break;
     161        }
     162
     163        free(ctrl_transfer);
     164}
     165
     166static void control_callback_one(void *buffer, size_t size,
     167    usb_transaction_outcome_t outcome, void *arg)
     168{
     169        control_transfer_info_t *transfer = (control_transfer_info_t *) arg;
     170
     171        if (outcome != USB_OUTCOME_OK) {
     172                control_abort_prematurely(transfer, outcome, size);
     173                free(transfer);
     174                return;
     175        }
     176
     177        switch (transfer->direction) {
     178                case USB_DIRECTION_IN:
     179                        hc_add_transaction_from_device(transfer->target,
     180                            USB_TRANSFER_CONTROL,
     181                            transfer->data_buffer, transfer->data_buffer_size,
     182                            control_callback_two, transfer);
     183                        break;
     184                case USB_DIRECTION_OUT:
     185                        hc_add_transaction_to_device(false, transfer->target,
     186                            USB_TRANSFER_CONTROL,
     187                            transfer->data_buffer, transfer->data_buffer_size,
     188                            control_callback_two, transfer);
     189                        break;
     190                default:
     191                        assert(false && "unreachable");
     192                        break;
     193        }
     194}
     195
     196static control_transfer_info_t *create_control_transfer_info(device_t *dev,
     197    usb_direction_t direction, usb_target_t target,
     198    void *data_buffer, size_t data_buffer_size,
     199    void *arg)
     200{
     201        control_transfer_info_t *transfer
     202            = malloc(sizeof(control_transfer_info_t));
     203
     204        transfer->direction = direction;
     205        transfer->target = target;
     206        transfer->in_callback = NULL;
     207        transfer->out_callback = NULL;
     208        transfer->arg = arg;
     209        transfer->dev = dev;
     210        transfer->data_buffer = data_buffer;
     211        transfer->data_buffer_size = data_buffer_size;
    86212
    87213        return transfer;
     
    193319}
    194320
     321static int control_write(device_t *dev, usb_target_t target,
     322    void *setup_packet, size_t setup_packet_size,
     323    void *data, size_t data_size,
     324    usbhc_iface_transfer_out_callback_t callback, void *arg)
     325{
     326        control_transfer_info_t *transfer
     327            = create_control_transfer_info(dev, USB_DIRECTION_OUT, target,
     328            data, data_size, arg);
     329        transfer->out_callback = callback;
     330
     331        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     332            setup_packet, setup_packet_size,
     333            control_callback_one, transfer);
     334
     335        return EOK;
     336}
     337
    195338static int control_read_setup(device_t *dev, usb_target_t target,
    196339    void *data, size_t size,
     
    217360            NULL, 0,
    218361            callback, arg);
     362}
     363
     364static int control_read(device_t *dev, usb_target_t target,
     365    void *setup_packet, size_t setup_packet_size,
     366    void *data, size_t data_size,
     367    usbhc_iface_transfer_in_callback_t callback, void *arg)
     368{
     369        control_transfer_info_t *transfer
     370            = create_control_transfer_info(dev, USB_DIRECTION_IN, target,
     371            data, data_size, arg);
     372        transfer->in_callback = callback;
     373
     374        hc_add_transaction_to_device(true, target, USB_TRANSFER_CONTROL,
     375            setup_packet, setup_packet_size,
     376            control_callback_one, transfer);
     377
     378        return EOK;
    219379}
    220380
     
    290450        .control_write_status = control_write_status,
    291451
     452        .control_write = control_write,
     453
    292454        .control_read_setup = control_read_setup,
    293455        .control_read_data = control_read_data,
    294         .control_read_status = control_read_status
     456        .control_read_status = control_read_status,
     457
     458        .control_read = control_read
    295459};
    296460
  • uspace/lib/drv/generic/remote_usbhc.c

    r2cea1045 rb00849e  
    11/*
    2  * Copyright (c) 2010 Vojtech Horky
     2 * Copyright (c) 2010-2011 Vojtech Horky
    33 * All rights reserved.
    44 *
     
    5252static void remote_usbhc_control_read_data(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5353static void remote_usbhc_control_read_status(device_t *, void *, ipc_callid_t, ipc_call_t *);
     54static void remote_usbhc_control_write(device_t *, void *, ipc_callid_t, ipc_call_t *);
     55static void remote_usbhc_control_read(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5456static void remote_usbhc_reserve_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    5557static void remote_usbhc_release_default_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    8183        remote_usbhc_control_read_setup,
    8284        remote_usbhc_control_read_data,
    83         remote_usbhc_control_read_status
     85        remote_usbhc_control_read_status,
     86
     87        remote_usbhc_control_write,
     88        remote_usbhc_control_read
    8489};
    8590
     
    95100        ipc_callid_t caller;
    96101        void *buffer;
     102        void *setup_packet;
    97103        size_t size;
    98104} async_transaction_t;
     
    297303        trans->caller = callid;
    298304        trans->buffer = buffer;
     305        trans->setup_packet = NULL;
    299306        trans->size = len;
    300307
     
    336343        trans->caller = callid;
    337344        trans->buffer = malloc(len);
     345        trans->setup_packet = NULL;
    338346        trans->size = len;
    339347
     
    391399        trans->caller = callid;
    392400        trans->buffer = NULL;
     401        trans->setup_packet = NULL;
    393402        trans->size = 0;
    394403
     
    496505}
    497506
     507void remote_usbhc_control_write(device_t *device, void *iface,
     508ipc_callid_t callid, ipc_call_t *call)
     509{
     510        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     511        assert(usb_iface != NULL);
     512
     513        if (!usb_iface->control_write) {
     514                ipc_answer_0(callid, ENOTSUP);
     515                return;
     516        }
     517
     518        usb_target_t target = {
     519                .address = DEV_IPC_GET_ARG1(*call),
     520                .endpoint = DEV_IPC_GET_ARG2(*call)
     521        };
     522
     523        int rc;
     524
     525        void *setup_packet = NULL;
     526        void *data_buffer = NULL;
     527        size_t setup_packet_len = 0;
     528        size_t data_buffer_len = 0;
     529
     530        rc = async_data_write_accept(&setup_packet, false,
     531            1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
     532        if (rc != EOK) {
     533                ipc_answer_0(callid, rc);
     534                return;
     535        }
     536        rc = async_data_write_accept(&data_buffer, false,
     537            1, USB_MAX_PAYLOAD_SIZE, 0, &data_buffer_len);
     538        if (rc != EOK) {
     539                free(setup_packet);
     540                ipc_answer_0(callid, rc);
     541                return;
     542        }
     543
     544        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     545        trans->caller = callid;
     546        trans->setup_packet = setup_packet;
     547        trans->buffer = data_buffer;
     548        trans->size = data_buffer_len;
     549
     550        rc = usb_iface->control_write(device, target,
     551            setup_packet, setup_packet_len,
     552            data_buffer, data_buffer_len,
     553            callback_out, trans);
     554
     555        if (rc != EOK) {
     556                ipc_answer_0(callid, rc);
     557                free(setup_packet);
     558                free(data_buffer);
     559                free(trans);
     560        }
     561}
     562
     563
     564void remote_usbhc_control_read(device_t *device, void *iface,
     565ipc_callid_t callid, ipc_call_t *call)
     566{
     567        usbhc_iface_t *usb_iface = (usbhc_iface_t *) iface;
     568        assert(usb_iface != NULL);
     569
     570        if (!usb_iface->control_read) {
     571                ipc_answer_0(callid, ENOTSUP);
     572                return;
     573        }
     574
     575        size_t data_len = DEV_IPC_GET_ARG3(*call);
     576        usb_target_t target = {
     577                .address = DEV_IPC_GET_ARG1(*call),
     578                .endpoint = DEV_IPC_GET_ARG2(*call)
     579        };
     580
     581        int rc;
     582
     583        void *setup_packet = NULL;
     584        size_t setup_packet_len = 0;
     585
     586        rc = async_data_write_accept(&setup_packet, false,
     587            1, USB_MAX_PAYLOAD_SIZE, 0, &setup_packet_len);
     588        if (rc != EOK) {
     589                ipc_answer_0(callid, rc);
     590                return;
     591        }
     592
     593        async_transaction_t *trans = malloc(sizeof(async_transaction_t));
     594        trans->caller = callid;
     595        trans->setup_packet = setup_packet;
     596        trans->buffer = malloc(data_len);
     597        trans->size = data_len;
     598
     599        rc = usb_iface->control_read(device, target,
     600            setup_packet, setup_packet_len,
     601            trans->buffer, trans->size,
     602            callback_in, trans);
     603
     604        if (rc != EOK) {
     605                ipc_answer_0(callid, rc);
     606                free(setup_packet);
     607                free(trans->buffer);
     608                free(trans);
     609        }
     610}
     611
    498612
    499613
  • uspace/lib/drv/include/usbhc_iface.h

    r2cea1045 rb00849e  
    201201        IPC_M_USBHC_CONTROL_READ_STATUS,
    202202
     203        /** Issue control WRITE transfer.
     204         * See explanation at usb_iface_funcs_t (OUT transaction) for
     205         * call parameters.
     206         * This call is immediately followed by two IPC data writes
     207         * from the caller (setup packet and actual data).
     208         */
     209        IPC_M_USBHC_CONTROL_WRITE,
     210
     211        /** Issue control WRITE transfer.
     212         * See explanation at usb_iface_funcs_t (IN transaction) for
     213         * call parameters.
     214         * This call is immediately followed by IPC data read from the caller
     215         * (setup packet).
     216         * Actual data are retrieved through IPC_M_USBHC_GET_BUFFER.
     217         */
     218        IPC_M_USBHC_CONTROL_READ,
    203219
    204220        /* IPC_M_USB_ */
     
    249265        int (*control_read_status)(device_t *, usb_target_t,
    250266            usbhc_iface_transfer_out_callback_t, void *);
     267
     268        int (*control_write)(device_t *, usb_target_t,
     269            void *, size_t, void *, size_t,
     270            usbhc_iface_transfer_out_callback_t, void *);
     271
     272        int (*control_read)(device_t *, usb_target_t,
     273            void *, size_t, void *, size_t,
     274            usbhc_iface_transfer_in_callback_t, void *);
    251275} usbhc_iface_t;
    252276
  • uspace/lib/usb/Makefile

    r2cea1045 rb00849e  
    4343        src/hidparser.c \
    4444        src/localdrv.c \
     45        src/pipes.c \
    4546        src/recognise.c \
    4647        src/remotedrv.c \
     48        src/request.c \
    4749        src/usb.c \
    4850        src/usbdrvreq.c \
  • uspace/lib/usb/include/usb/classes/hid.h

    r2cea1045 rb00849e  
    3737
    3838#include <usb/usb.h>
    39 #include <driver.h>
    4039#include <usb/classes/hidparser.h>
    4140#include <usb/descriptor.h>
     
    101100} __attribute__ ((packed)) usb_standard_hid_descriptor_t;
    102101
    103 /**
    104  *
    105  */
    106 typedef struct {
    107         usb_standard_interface_descriptor_t iface_desc;
    108         usb_standard_endpoint_descriptor_t *endpoints;
    109         usb_standard_hid_descriptor_t hid_desc;
    110         uint8_t *report_desc;
    111         //usb_standard_hid_class_descriptor_info_t *class_desc_info;
    112         //uint8_t **class_descs;
    113 } usb_hid_iface_t;
    114 
    115 /**
    116  *
    117  */
    118 typedef struct {
    119         usb_standard_configuration_descriptor_t config_descriptor;
    120         usb_hid_iface_t *interfaces;
    121 } usb_hid_configuration_t;
    122 
    123 /**
    124  * @brief USB/HID keyboard device type.
    125  *
    126  * Quite dummy right now.
    127  */
    128 typedef struct {
    129         device_t *device;
    130         usb_hid_configuration_t *conf;
    131         usb_address_t address;
    132         usb_endpoint_t poll_endpoint;
    133         usb_hid_report_parser_t *parser;
    134 } usb_hid_dev_kbd_t;
    135 
    136 // TODO: more configurations!
    137102
    138103#endif
  • uspace/lib/usb/include/usb/usb.h

    r2cea1045 rb00849e  
    6666typedef enum {
    6767        USB_DIRECTION_IN,
    68         USB_DIRECTION_OUT
     68        USB_DIRECTION_OUT,
     69        USB_DIRECTION_BOTH
    6970} usb_direction_t;
    7071
  • uspace/lib/usb/include/usb/usbdrv.h

    r2cea1045 rb00849e  
    7070    usb_handle_t *);
    7171
     72int usb_drv_async_control_write(int, usb_target_t,
     73    void *, size_t, void *, size_t, usb_handle_t *);
     74
    7275int usb_drv_psync_control_write_setup(int, usb_target_t, void *, size_t);
    7376int usb_drv_psync_control_write_data(int, usb_target_t, void *, size_t);
     
    7780    void *, size_t, void *, size_t);
    7881
    79 
    8082int usb_drv_async_control_read_setup(int, usb_target_t,
    8183    void *, size_t, usb_handle_t *);
     
    8486int usb_drv_async_control_read_status(int, usb_target_t,
    8587    usb_handle_t *);
     88
     89int usb_drv_async_control_read(int, usb_target_t,
     90    void *, size_t, void *, size_t, size_t *, usb_handle_t *);
    8691
    8792int usb_drv_psync_control_read_setup(int, usb_target_t, void *, size_t);
  • uspace/lib/usb/src/usbdrv.c

    r2cea1045 rb00849e  
    495495}
    496496
     497/** Issue whole control write transfer. */
     498int usb_drv_async_control_write(int phone, usb_target_t target,
     499    void *setup_packet, size_t setup_packet_size,
     500    void *buffer, size_t buffer_size,
     501    usb_handle_t *handle)
     502{
     503        // FIXME - check input parameters instead of asserting them
     504        assert(phone > 0);
     505        assert(setup_packet != NULL);
     506        assert(setup_packet_size > 0);
     507        assert(buffer != NULL);
     508        assert(buffer_size > 0);
     509        assert(handle != NULL);
     510
     511        transfer_info_t *transfer
     512            = (transfer_info_t *) malloc(sizeof(transfer_info_t));
     513        if (transfer == NULL) {
     514                return ENOMEM;
     515        }
     516
     517        transfer->size_transferred = NULL;
     518        transfer->buffer = NULL;
     519        transfer->size = 0;
     520        transfer->phone = phone;
     521
     522        int rc;
     523
     524        transfer->request = async_send_3(phone,
     525            DEV_IFACE_ID(USBHC_DEV_IFACE),
     526            IPC_M_USBHC_CONTROL_WRITE,
     527            target.address, target.endpoint,
     528            &transfer->reply);
     529
     530        rc = async_data_write_start(phone, setup_packet, setup_packet_size);
     531        if (rc != EOK) {
     532                async_wait_for(transfer->request, NULL);
     533                return rc;
     534        }
     535
     536        rc = async_data_write_start(phone, buffer, buffer_size);
     537        if (rc != EOK) {
     538                async_wait_for(transfer->request, NULL);
     539                return rc;
     540        }
     541
     542        *handle = (usb_handle_t) transfer;
     543
     544        return EOK;
     545}
     546
    497547/** Start control read transfer. */
    498548int usb_drv_async_control_read_setup(int phone, usb_target_t target,
     
    530580}
    531581
     582/** Issue whole control read transfer. */
     583int usb_drv_async_control_read(int phone, usb_target_t target,
     584    void *setup_packet, size_t setup_packet_size,
     585    void *buffer, size_t buffer_size, size_t *actual_size,
     586    usb_handle_t *handle)
     587{
     588        // FIXME - check input parameters instead of asserting them
     589        assert(phone > 0);
     590        assert(setup_packet != NULL);
     591        assert(setup_packet_size > 0);
     592        assert(buffer != NULL);
     593        assert(buffer_size > 0);
     594        assert(handle != NULL);
     595
     596        transfer_info_t *transfer
     597            = (transfer_info_t *) malloc(sizeof(transfer_info_t));
     598        if (transfer == NULL) {
     599                return ENOMEM;
     600        }
     601
     602        transfer->size_transferred = actual_size;
     603        transfer->buffer = buffer;
     604        transfer->size = buffer_size;
     605        transfer->phone = phone;
     606
     607        int rc;
     608
     609        transfer->request = async_send_4(phone,
     610            DEV_IFACE_ID(USBHC_DEV_IFACE),
     611            IPC_M_USBHC_CONTROL_READ,
     612            target.address, target.endpoint,
     613            buffer_size,
     614            &transfer->reply);
     615
     616        rc = async_data_write_start(phone, setup_packet, setup_packet_size);
     617        if (rc != EOK) {
     618                async_wait_for(transfer->request, NULL);
     619                return rc;
     620        }
     621
     622        *handle = (usb_handle_t) transfer;
     623
     624        return EOK;
     625}
     626
    532627/**
    533628 * @}
Note: See TracChangeset for help on using the changeset viewer.