Changeset 7a7bfeb3 in mainline


Ignore:
Timestamp:
2010-10-24T16:43:40Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
355f7c2
Parents:
b8a3cda
Message:

Virtual USB overhaul almost complete

The virtual HC, hub and keyboard are rewritten after changes to HCD API.
Comments will be added later.

Location:
uspace
Files:
1 added
1 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/virtusbkbd/stdreq.c

    rb8a3cda r7a7bfeb3  
    6565                 * report descriptor.
    6666                 */
    67                 int rc = dev->send_data(dev, 0,
     67                int rc = dev->control_transfer_reply(dev, 0,
    6868                    report_descriptor, report_descriptor_size);
    6969               
  • uspace/app/virtusbkbd/virtusbkbd.c

    rb8a3cda r7a7bfeb3  
    6767        (printf("%s: %s" fmt "\n", NAME, _QUOTEME(cmd), __VA_ARGS__), cmd(__VA_ARGS__))
    6868
     69kb_status_t status;
     70
    6971static int on_incoming_data(struct usbvirt_device *dev,
    7072    usb_endpoint_t endpoint, void *buffer, size_t size)
     
    8385}
    8486
     87static int on_request_for_data(struct usbvirt_device *dev,
     88    usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size)
     89{
     90        if (size < 2 + KB_MAX_KEYS_AT_ONCE) {
     91                return EINVAL;
     92        }
     93       
     94        *actual_size = 2 + KB_MAX_KEYS_AT_ONCE;
     95       
     96        uint8_t data[2 + KB_MAX_KEYS_AT_ONCE];
     97        data[0] = status.modifiers;
     98        data[1] = 0;
     99       
     100        size_t i;
     101        for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {
     102                data[2 + i] = status.pressed_keys[i];
     103        }
     104       
     105        memcpy(buffer, &data, *actual_size);
     106       
     107        return EOK;
     108}
     109
     110
    85111/** Keyboard callbacks.
    86112 * We abuse the fact that static variables are zero-filled.
     
    89115        .standard_request_ops = &standard_request_ops,
    90116        .on_class_device_request = on_class_request,
    91         .on_data = on_incoming_data
     117        .on_data = on_incoming_data,
     118        .on_data_request = on_request_for_data
    92119};
    93120
     
    151178        }
    152179        printf("\n");
    153        
    154         uint8_t data[3 + KB_MAX_KEYS_AT_ONCE];
    155         data[0] = status->modifiers;
    156         data[1] = 0;
    157         data[2] = 0;
    158         for (i = 0; i < KB_MAX_KEYS_AT_ONCE; i++) {
    159                 data[3 + i] = status->pressed_keys[i];
    160         }
    161        
    162         int rc = keyboard_dev.send_data(&keyboard_dev, 0, data, sizeof(data));
    163         printf("%s:   Sent to VHCD (%s).\n", NAME, str_error(rc));
    164180       
    165181        fibril_sleep(1);
     
    198214        }
    199215       
     216        kb_init(&status);
     217       
    200218       
    201219        int rc = usbvirt_connect(&keyboard_dev, DEV_HCD_NAME);
     
    206224        }
    207225       
    208         kb_status_t status;
    209         kb_init(&status);
    210        
    211226        printf("%s: Simulating keyboard events...\n", NAME);
    212227        kb_process_events(&status, keyboard_events, keyboard_events_count,
  • uspace/lib/usb/usb.h

    rb8a3cda r7a7bfeb3  
    6464typedef int usb_endpoint_t;
    6565
     66/** Maximum endpoint number in USB 1.1.
     67 */
     68#define USB11_ENDPOINT_MAX 16
     69
     70
    6671/** USB complete address type.
    6772 * Pair address + endpoint is identification of transaction recipient.
  • uspace/lib/usbvirt/Makefile

    rb8a3cda r7a7bfeb3  
    3535SOURCES = \
    3636        ctrlpipe.c \
    37         incoming.c \
    3837        main.c \
    39         stdreq.c
     38        stdreq.c \
     39        transaction.c
    4040
    4141include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/usbvirt/ctrlpipe.c

    rb8a3cda r7a7bfeb3  
    5353
    5454
    55 
    56 int control_pipe(void *buffer, size_t size)
     55int control_pipe(usbvirt_control_transfer_t *transfer)
    5756{
    58         if (size < sizeof(usb_device_request_setup_packet_t)) {
     57        if (transfer->request_size < sizeof(usb_device_request_setup_packet_t)) {
    5958                return ENOMEM;
    6059        }
    6160       
    62         usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) buffer;
    63         uint8_t *remaining_data = ((uint8_t *) request) + sizeof(usb_device_request_setup_packet_t);
     61        usb_device_request_setup_packet_t *request = (usb_device_request_setup_packet_t *) transfer->request;
     62        uint8_t *remaining_data = transfer->data;
    6463       
    6564        int type = request_get_type(request->request_type);
     
    8079                        break;
    8180        }
    82        
    83         device->send_data(device, 0, NULL, 0);
    8481       
    8582        if (dev_new_address != -1) {
  • uspace/lib/usbvirt/device.h

    rb8a3cda r7a7bfeb3  
    4141
    4242struct usbvirt_device;
     43struct usbvirt_control_transfer;
    4344
    4445typedef int (*usbvirt_on_device_request_t)(struct usbvirt_device *dev,
     
    7071        /** Callback for class-specific USB request. */
    7172        usbvirt_on_device_request_t on_class_device_request;
     73       
     74        int (*on_control_transfer)(struct usbvirt_device *dev,
     75            usb_endpoint_t endpoint, struct usbvirt_control_transfer *transfer);
     76       
    7277        /** Callback for all other incoming data. */
    7378        int (*on_data)(struct usbvirt_device *dev,
     79            usb_endpoint_t endpoint, void *buffer, size_t size);
     80       
     81        /** Callback for host request for data. */
     82        int (*on_data_request)(struct usbvirt_device *dev,
     83            usb_endpoint_t endpoint, void *buffer, size_t size, size_t *actual_size);
     84       
     85        /** Decides direction of control transfer. */
     86        usb_direction_t (*decide_control_transfer_direction)(
    7487            usb_endpoint_t endpoint, void *buffer, size_t size);
    7588} usbvirt_device_ops_t;
     
    117130} usbvirt_device_state_t;
    118131
     132/** Information about on-going control transfer.
     133 */
     134typedef struct usbvirt_control_transfer {
     135        usb_direction_t direction;
     136        void *request;
     137        size_t request_size;
     138        void *data;
     139        size_t data_size;
     140} usbvirt_control_transfer_t;
     141
    119142/** Virtual USB device. */
    120143typedef struct usbvirt_device {
     
    122145        usbvirt_device_ops_t *ops;
    123146       
    124         /** Send data to HC.
    125          * @warning Do not change after initializing with
    126          * usbvirt_device_init().
    127          * This function is here merely to make the interface more OOP.
     147       
     148        /** Reply onto control transfer.
    128149         */
    129         int (*send_data)(struct usbvirt_device *dev,
     150        int (*control_transfer_reply)(struct usbvirt_device *dev,
    130151            usb_endpoint_t endpoint, void *buffer, size_t size);
    131152       
     
    153174        int device_id_;
    154175       
    155         /** Main routine called when data is received from HC.
    156          * @warning Do not change after initializing with
    157          * usbvirt_device_init().
    158          * This function is here merely to make the interface more OOP.
    159          */
    160         int (*receive_data)(struct usbvirt_device *dev,
     176        int (*transaction_out)(struct usbvirt_device *dev,
    161177            usb_endpoint_t endpoint, void *buffer, size_t size);
     178        int (*transaction_setup)(struct usbvirt_device *dev,
     179            usb_endpoint_t endpoint, void *buffer, size_t size);
     180        int (*transaction_in)(struct usbvirt_device *dev,
     181            usb_endpoint_t endpoint, void *buffer, size_t size, size_t *data_size);
    162182       
     183        usbvirt_control_transfer_t current_control_transfers[USB11_ENDPOINT_MAX];
    163184} usbvirt_device_t;
    164185
  • uspace/lib/usbvirt/hub.h

    rb8a3cda r7a7bfeb3  
    4141typedef enum {
    4242        IPC_M_USBVIRT_DATA_TO_DEVICE = IPC_FIRST_USER_METHOD,
    43         IPC_M_USBVIRT_DATA_FROM_DEVICE
     43        IPC_M_USBVIRT_DATA_FROM_DEVICE,
     44        IPC_M_USBVIRT_TRANSACTION_SETUP,
     45        IPC_M_USBVIRT_TRANSACTION_OUT,
     46        IPC_M_USBVIRT_TRANSACTION_IN,
    4447} usbvirt_device_method_t;
    4548
  • uspace/lib/usbvirt/main.c

    rb8a3cda r7a7bfeb3  
    3838#include <errno.h>
    3939#include <stdlib.h>
     40#include <mem.h>
    4041
    4142#include "hub.h"
     
    4748usbvirt_device_t *device = NULL;
    4849
    49 
    50 static void handle_data_to_device(ipc_callid_t iid, ipc_call_t icall)
     50static void handle_setup_transaction(ipc_callid_t iid, ipc_call_t icall)
    5151{
    5252        usb_address_t address = IPC_GET_ARG1(icall);
    5353        usb_endpoint_t endpoint = IPC_GET_ARG2(icall);
    54         size_t expected_len = IPC_GET_ARG5(icall);
     54        size_t expected_len = IPC_GET_ARG3(icall);
    5555       
    5656        if (address != device->address) {
     
    5959        }
    6060       
     61        if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) {
     62                ipc_answer_0(iid, EINVAL);
     63                return;
     64        }
     65       
     66        if (expected_len == 0) {
     67                ipc_answer_0(iid, EINVAL);
     68                return;
     69        }
     70       
    6171        size_t len = 0;
    6272        void * buffer = NULL;
     73        int rc = async_data_write_accept(&buffer, false,
     74            1, USB_MAX_PAYLOAD_SIZE, 0, &len);
     75               
     76        if (rc != EOK) {
     77                ipc_answer_0(iid, rc);
     78                return;
     79        }
     80       
     81        rc = device->transaction_setup(device, endpoint, buffer, len);
     82       
     83        ipc_answer_0(iid, rc);
     84}
     85
     86
     87static void handle_out_transaction(ipc_callid_t iid, ipc_call_t icall)
     88{
     89        usb_address_t address = IPC_GET_ARG1(icall);
     90        usb_endpoint_t endpoint = IPC_GET_ARG2(icall);
     91        size_t expected_len = IPC_GET_ARG3(icall);
     92       
     93        if (address != device->address) {
     94                ipc_answer_0(iid, EADDRNOTAVAIL);
     95                return;
     96        }
     97       
     98        if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) {
     99                ipc_answer_0(iid, EINVAL);
     100                return;
     101        }
     102       
     103        int rc = EOK;
     104       
     105        size_t len = 0;
     106        void *buffer = NULL;
     107       
    63108        if (expected_len > 0) {
    64                 int rc = async_data_write_accept(&buffer, false,
    65                     1, USB_MAX_PAYLOAD_SIZE,
    66                     0, &len);
    67                
     109                rc = async_data_write_accept(&buffer, false,
     110                    1, USB_MAX_PAYLOAD_SIZE, 0, &len);
     111                       
    68112                if (rc != EOK) {
    69113                        ipc_answer_0(iid, rc);
     
    72116        }
    73117       
    74         device->receive_data(device, endpoint, buffer, len);
     118        rc = device->transaction_out(device, endpoint, buffer, len);
    75119       
    76120        if (buffer != NULL) {
     
    78122        }
    79123       
    80         ipc_answer_0(iid, EOK);
    81 }
     124        ipc_answer_0(iid, rc);
     125}
     126
     127
     128
     129static void handle_in_transaction(ipc_callid_t iid, ipc_call_t icall)
     130{
     131        usb_address_t address = IPC_GET_ARG1(icall);
     132        usb_endpoint_t endpoint = IPC_GET_ARG2(icall);
     133        size_t expected_len = IPC_GET_ARG3(icall);
     134       
     135        if (address != device->address) {
     136                ipc_answer_0(iid, EADDRNOTAVAIL);
     137                return;
     138        }
     139       
     140        if ((endpoint < 0) || (endpoint >= USB11_ENDPOINT_MAX)) {
     141                ipc_answer_0(iid, EINVAL);
     142                return;
     143        }
     144       
     145        int rc = EOK;
     146       
     147        void *buffer = expected_len > 0 ? malloc(expected_len) : NULL;
     148        size_t len;
     149       
     150        rc = device->transaction_in(device, endpoint, buffer, expected_len, &len);
     151        /*
     152         * If the request was processed, we will send data back.
     153         */
     154        if (rc == EOK) {
     155                size_t receive_len;
     156                if (!async_data_read_receive(&iid, &receive_len)) {
     157                        ipc_answer_0(iid, EINVAL);
     158                        return;
     159                }
     160                async_data_read_finalize(iid, buffer, receive_len);
     161        }
     162       
     163        ipc_answer_0(iid, rc);
     164}
     165
     166
    82167
    83168static void callback_connection(ipc_callid_t iid, ipc_call_t *icall)
     
    95180                                return;
    96181                       
    97                         case IPC_M_USBVIRT_DATA_TO_DEVICE:
    98                                 handle_data_to_device(callid, call);
     182                        case IPC_M_USBVIRT_TRANSACTION_SETUP:
     183                                handle_setup_transaction(callid, call);
     184                                break;
     185                       
     186                        case IPC_M_USBVIRT_TRANSACTION_OUT:
     187                                handle_out_transaction(callid, call);
     188                                break;
     189                               
     190                        case IPC_M_USBVIRT_TRANSACTION_IN:
     191                                handle_in_transaction(callid, call);
    99192                                break;
    100193                       
     
    106199}
    107200
     201static int control_transfer_reply(struct usbvirt_device *device,
     202            usb_endpoint_t endpoint, void *buffer, size_t size)
     203{
     204        usbvirt_control_transfer_t *transfer = &device->current_control_transfers[endpoint];
     205        if (transfer->data != NULL) {
     206                free(transfer->data);
     207        }
     208        transfer->data = malloc(size);
     209        memcpy(transfer->data, buffer, size);
     210        transfer->data_size = size;
     211       
     212        return EOK;
     213}
     214
    108215static void device_init(usbvirt_device_t *dev)
    109216{
    110         dev->send_data = usbvirt_data_to_host;
    111         dev->receive_data = handle_incoming_data;
     217        dev->transaction_out = transaction_out;
     218        dev->transaction_setup = transaction_setup;
     219        dev->transaction_in = transaction_in;
     220       
     221        dev->control_transfer_reply = control_transfer_reply;
     222       
    112223        dev->state = USBVIRT_STATE_DEFAULT;
    113224        dev->address = 0;
    114 }
    115 
    116 int usbvirt_data_to_host(struct usbvirt_device *dev,
    117     usb_endpoint_t endpoint, void *buffer, size_t size)
    118 {
    119         int phone = dev->vhcd_phone_;
    120        
    121         if (phone < 0) {
    122                 return EINVAL;
    123         }
    124         if ((buffer == NULL) && (size != 0)) {
    125                 return EINVAL;
    126         }
    127 
    128         ipc_call_t answer_data;
    129         ipcarg_t answer_rc;
    130         aid_t req;
    131         int rc;
    132        
    133         req = async_send_3(phone,
    134             IPC_M_USBVIRT_DATA_FROM_DEVICE,
    135             dev->address,
    136             endpoint,
    137             size,
    138             &answer_data);
    139        
    140         if (size > 0) {
    141                 rc = async_data_write_start(phone, buffer, size);
    142                 if (rc != EOK) {
    143                         async_wait_for(req, NULL);
    144                         return rc;
    145                 }
    146         }
    147        
    148         async_wait_for(req, &answer_rc);
    149         rc = (int)answer_rc;
    150         if (rc != EOK) {
    151                 return rc;
    152         }
    153        
    154         return EOK;
     225       
     226        size_t i;
     227        for (i = 0; i < USB11_ENDPOINT_MAX; i++) {
     228                usbvirt_control_transfer_t *transfer = &dev->current_control_transfers[i];
     229                transfer->direction = 0;
     230                transfer->request = NULL;
     231                transfer->request_size = 0;
     232                transfer->data = NULL;
     233                transfer->data_size = 0;
     234        }
    155235}
    156236
  • uspace/lib/usbvirt/private.h

    rb8a3cda r7a7bfeb3  
    5454    usb_endpoint_t endpoint, void *buffer, size_t size);
    5555
    56 int control_pipe(void *buffer, size_t size);
     56int control_pipe(usbvirt_control_transfer_t *transfer);
    5757
    5858int handle_std_request(usb_device_request_setup_packet_t *request, uint8_t *data);
     
    6060extern usb_address_t dev_new_address;
    6161
     62int transaction_setup(usbvirt_device_t *device, usb_endpoint_t endpoint,
     63    void *buffer, size_t size);
     64int transaction_out(usbvirt_device_t *device, usb_endpoint_t endpoint,
     65    void *buffer, size_t size);
     66int transaction_in(usbvirt_device_t *device, usb_endpoint_t endpoint,
     67    void *buffer, size_t size, size_t *data_size);
     68
    6269#endif
    6370/**
  • uspace/lib/usbvirt/stdreq.c

    rb8a3cda r7a7bfeb3  
    5757        if ((type == USB_DESCTYPE_DEVICE) && (index == 0)) {
    5858                if (device->descriptors && device->descriptors->device) {
    59                         return device->send_data(device, 0,
     59                        return device->control_transfer_reply(device, 0,
    6060                            device->descriptors->device,
    6161                            device->descriptors->device->length);
     
    9595                }
    9696               
    97                 int rc = device->send_data(device, 0, all_data,
    98                     config->descriptor->total_length);
     97                int rc = device->control_transfer_reply(device, 0,
     98                    all_data, config->descriptor->total_length);
    9999               
    100100                free(all_data);
  • uspace/srv/hw/bus/usb/hcd/virtual/conndev.c

    rb8a3cda r7a7bfeb3  
    4242#include "hub.h"
    4343
    44 /** Handle data from device to host.
    45  */
    46 static void handle_data_from_device(ipc_callid_t iid, ipc_call_t icall,
    47     virtdev_connection_t *dev)
    48 {
    49         usb_target_t target = {
    50                 .address = IPC_GET_ARG1(icall),
    51                 .endpoint = IPC_GET_ARG2(icall)
    52         };
    53         size_t len = IPC_GET_ARG3(icall);
    54        
    55         if (!hub_can_device_signal(dev)) {
    56                 ipc_answer_0(iid, EREFUSED);
    57                 return;
    58         }
    59        
    60         dprintf("data from device %d [%d.%d]", dev->id,
    61             target.address, target.endpoint);
    62        
    63         int rc;
    64        
    65         void * buffer = NULL;
    66         if (len > 0) {
    67                 rc = async_data_write_accept(&buffer, false,
    68                     1, USB_MAX_PAYLOAD_SIZE,
    69                     0, &len);
    70                
    71                 if (rc != EOK) {
    72                         ipc_answer_0(iid, rc);
    73                         return;
    74                 }
    75         }
    76        
    77         rc = hc_fillin_transaction_from_device(target, buffer, len);
    78        
    79         ipc_answer_0(iid, rc);
    80 }
    81 
    8244/** Connection handler for communcation with virtual device.
    8345 *
     
    11072                                break;
    11173                       
    112                         case IPC_M_USBVIRT_DATA_FROM_DEVICE:
    113                                 handle_data_from_device(callid, call, dev);
    114                                 break;
    115                        
    11674                        default:
    11775                                ipc_answer_0(callid, EINVAL);
  • uspace/srv/hw/bus/usb/hcd/virtual/devices.c

    rb8a3cda r7a7bfeb3  
    126126                aid_t req;
    127127                int rc = EOK;
    128                
    129                 req = async_send_4(dev->phone,
    130                     IPC_M_USBVIRT_DATA_TO_DEVICE,
     128                int method = IPC_M_USBVIRT_TRANSACTION_SETUP;
     129               
     130                switch (transaction->type) {
     131                        case USBVIRT_TRANSACTION_SETUP:
     132                                method = IPC_M_USBVIRT_TRANSACTION_SETUP;
     133                                break;
     134                        case USBVIRT_TRANSACTION_IN:
     135                                method = IPC_M_USBVIRT_TRANSACTION_IN;
     136                                break;
     137                        case USBVIRT_TRANSACTION_OUT:
     138                                method = IPC_M_USBVIRT_TRANSACTION_OUT;
     139                                break;
     140                }
     141               
     142                req = async_send_3(dev->phone,
     143                    method,
    131144                    transaction->target.address,
    132145                    transaction->target.endpoint,
    133                     transaction->type,
    134146                    transaction->len,
    135147                    &answer_data);
    136148               
    137149                if (transaction->len > 0) {
    138                         rc = async_data_write_start(dev->phone,
    139                             transaction->buffer, transaction->len);
    140                 }
     150                        if (transaction->type == USBVIRT_TRANSACTION_IN) {
     151                                rc = async_data_read_start(dev->phone,
     152                                    transaction->buffer, transaction->len);
     153                        } else {
     154                                rc = async_data_write_start(dev->phone,
     155                                    transaction->buffer, transaction->len);
     156                        }
     157                }
     158               
    141159                if (rc != EOK) {
    142160                        async_wait_for(req, NULL);
     
    152170         */
    153171        if (virthub_dev.address == transaction->target.address) {
    154                 virthub_dev.receive_data(&virthub_dev, transaction->target.endpoint,
    155                     transaction->buffer, transaction->len);
     172                size_t tmp;
     173                switch (transaction->type) {
     174                        case USBVIRT_TRANSACTION_SETUP:
     175                                virthub_dev.transaction_setup(&virthub_dev,
     176                                    transaction->target.endpoint,
     177                                    transaction->buffer, transaction->len);
     178                                break;
     179                               
     180                        case USBVIRT_TRANSACTION_IN:
     181                                virthub_dev.transaction_in(&virthub_dev,
     182                                    transaction->target.endpoint,
     183                                    transaction->buffer, transaction->len,
     184                                    &tmp);
     185                                if (tmp < transaction->len) {
     186                                        transaction->len = tmp;
     187                                }
     188                                break;
     189                               
     190                        case USBVIRT_TRANSACTION_OUT:
     191                                virthub_dev.transaction_out(&virthub_dev,
     192                                    transaction->target.endpoint,
     193                                    transaction->buffer, transaction->len);
     194                                break;
     195                }
    156196        }
    157197       
  • uspace/srv/hw/bus/usb/hcd/virtual/hc.c

    rb8a3cda r7a7bfeb3  
    4848#include "hc.h"
    4949#include "devices.h"
     50#include "hub.h"
    5051
    5152#define USLEEP_BASE (500 * 1000)
     
    6566        } while (0)
    6667
    67 static link_t transaction_to_device_list;
    68 static link_t transaction_from_device_list;
     68static link_t transaction_list;
    6969
    70 #define TRANSACTION_FORMAT "T[%d:%d (%d)]"
     70#define TRANSACTION_FORMAT "T[%d:%d (%d) %d]"
    7171#define TRANSACTION_PRINTF(t) \
    7272        (t).target.address, (t).target.endpoint, \
    73         (int)(t).len
     73        (int)(t).len, (int)(t).type
    7474
    7575#define transaction_get_instance(lnk) \
     
    100100void hc_manager(void)
    101101{
    102         list_initialize(&transaction_to_device_list);
    103         list_initialize(&transaction_from_device_list);
     102        list_initialize(&transaction_list);
    104103       
    105104        static unsigned int seed = 4573;
     
    110109                async_usleep(USLEEP_BASE + (pseudo_random(&seed) % USLEEP_VAR));
    111110               
    112                 if (list_empty(&transaction_to_device_list)) {
     111                if (list_empty(&transaction_list)) {
    113112                        continue;
    114113                }
    115114               
    116                 link_t *first_transaction_link = transaction_to_device_list.next;
     115                dprintf("virtual hub has address %d:*.", virthub_dev.address);
     116               
     117                link_t *first_transaction_link = transaction_list.next;
    117118                transaction_t *transaction
    118119                    = transaction_get_instance(first_transaction_link);
    119120                list_remove(first_transaction_link);
     121               
     122                dprintf("processing transaction " TRANSACTION_FORMAT "",
     123                    TRANSACTION_PRINTF(*transaction));
    120124               
    121125                usb_transaction_outcome_t outcome;
     
    157161            setup ? USBVIRT_TRANSACTION_SETUP : USBVIRT_TRANSACTION_OUT, target,
    158162            buffer, len, callback, arg);
    159         list_append(&transaction->link, &transaction_to_device_list);
     163        list_append(&transaction->link, &transaction_list);
    160164}
    161165
     
    168172        transaction_t *transaction = transaction_create(USBVIRT_TRANSACTION_IN,
    169173            target, buffer, len, callback, arg);
    170         list_append(&transaction->link, &transaction_from_device_list);
    171 }
    172 
    173 /** Fill data to existing transaction from device.
    174  */
    175 int hc_fillin_transaction_from_device(usb_target_t target,
    176     void * buffer, size_t len)
    177 {
    178         dprintf("finding transaction to fill data in (%d:%d)...",
    179             target.address, target.endpoint);
    180         int rc;
    181        
    182         /*
    183          * Find correct transaction envelope in the list.
    184          */
    185         if (list_empty(&transaction_from_device_list)) {
    186                 rc = ENOENT;
    187                 goto leave;
    188         }
    189        
    190         transaction_t *transaction = NULL;
    191         link_t *pos = transaction_from_device_list.next;
    192        
    193         while (pos != &transaction_from_device_list) {
    194                 transaction_t *t = transaction_get_instance(pos);
    195                 if (usb_target_same(t->target, target)) {
    196                         transaction = t;
    197                         break;
    198                 }
    199                 pos = pos->next;
    200         }
    201         if (transaction == NULL) {
    202                 rc = ENOENT;
    203                 goto leave;
    204         }
    205        
    206         /*
    207          * Remove the transaction from the list as it will be processed now.
    208          */
    209         list_remove(&transaction->link);
    210        
    211         if (transaction->len < len) {
    212                 process_transaction_with_outcome(transaction, USB_OUTCOME_BABBLE);
    213                 rc = ENOMEM;
    214                 goto leave;
    215         }
    216        
    217         /*
    218          * Copy the data and finish processing the transaction.
    219          */
    220         transaction->len = len;
    221         memcpy(transaction->buffer, buffer, len);
    222        
    223         process_transaction_with_outcome(transaction, USB_OUTCOME_OK);
    224        
    225         dprintf("  ...transaction " TRANSACTION_FORMAT " sent back",
    226             TRANSACTION_PRINTF(*transaction));
    227        
    228        
    229         free(transaction);
    230         rc = EOK;
    231        
    232 leave:
    233         dprintf("  ...fill-in transaction: %s", str_error(rc));
    234        
    235         return rc;
     174        list_append(&transaction->link, &transaction_list);
    236175}
    237176
  • uspace/srv/hw/bus/usb/hcd/virtual/hub.c

    rb8a3cda r7a7bfeb3  
    144144hub_device_t hub_dev;
    145145
    146 static int send_data(struct usbvirt_device *dev,
    147             usb_endpoint_t endpoint, void *buffer, size_t size)
    148 {
    149         usb_target_t target = { dev->address, endpoint };
    150         void *my_buffer = NULL;
    151         if (size > 0) {
    152                 my_buffer = malloc(size);
    153                 memcpy(my_buffer, buffer, size);
    154         }
    155         hc_fillin_transaction_from_device(target, my_buffer, size);
    156        
    157         return EOK;
    158 }
    159 
    160146void hub_init(void)
    161147{
     
    170156       
    171157        usbvirt_connect_local(&virthub_dev);
    172         virthub_dev.send_data = send_data;
     158        //virthub_dev.send_data = send_data;
    173159       
    174160        printf("%s: virtual hub (%d ports) created.\n", NAME, HUB_PORT_COUNT);
     
    235221}
    236222
    237 void hub_check_port_changes(void)
    238 {
    239         /* FIXME - what if HUB_PORT_COUNT is greater than 8. */
    240         uint8_t change_map = 0;
    241        
    242         size_t i;
    243         for (i = 0; i < HUB_PORT_COUNT; i++) {
    244                 hub_port_t *port = &hub_dev.ports[i];
    245                
    246                 if (port->status_change != 0) {
    247                         change_map |= (1 << (i + 1));
    248                 }
    249         }
    250        
    251         /* FIXME - do not send when it has not changed since previous run. */
    252         if (change_map != 0) {
    253                 virthub_dev.send_data(&virthub_dev, HUB_STATUS_CHANGE_PIPE,
    254                     &change_map, 1);
    255         }
    256 }
    257223
    258224/**
  • uspace/srv/hw/bus/usb/hcd/virtual/hub.h

    rb8a3cda r7a7bfeb3  
    5151void hub_remove_device(virtdev_connection_t *);
    5252bool hub_can_device_signal(virtdev_connection_t *);
    53 void hub_check_port_changes(void);
    5453
    5554#endif
  • uspace/srv/hw/bus/usb/hcd/virtual/hubops.c

    rb8a3cda r7a7bfeb3  
    5959static int on_class_request(struct usbvirt_device *dev,
    6060    usb_device_request_setup_packet_t *request, uint8_t *data);
     61static int on_data_request(struct usbvirt_device *dev,
     62    usb_endpoint_t endpoint,
     63    void *buffer, size_t size, size_t *actual_size);
     64
    6165
    6266static usbvirt_standard_device_request_ops_t standard_request_ops = {
     
    7882        .standard_request_ops = &standard_request_ops,
    7983        .on_class_device_request = on_class_request,
    80         .on_data = NULL
     84        .on_data = NULL,
     85        .on_data_request = on_data_request
    8186};
    8287
     
    8590{
    8691        if (request->value_high == USB_DESCTYPE_HUB) {
    87                 int rc = dev->send_data(dev, 0,
     92                int rc = dev->control_transfer_reply(dev, 0,
    8893                    &hub_descriptor, hub_descriptor.length);
    8994               
     
    196201        uint32_t hub_status = 0;
    197202       
    198         return virthub_dev.send_data(&virthub_dev, 0, &hub_status, 4);
     203        return virthub_dev.control_transfer_reply(&virthub_dev, 0,
     204            &hub_status, 4);
    199205}
    200206
     
    230236        status |= (port->status_change << 16);
    231237       
    232         return virthub_dev.send_data(&virthub_dev, 0, &status, 4);
     238        return virthub_dev.control_transfer_reply(&virthub_dev, 0, &status, 4);
    233239}
    234240
     
    334340{
    335341        port->status_change &= (~change);
    336         hub_check_port_changes();
    337342}
    338343
     
    341346        port->status_change |= change;
    342347}
     348
     349static int on_data_request(struct usbvirt_device *dev,
     350    usb_endpoint_t endpoint,
     351    void *buffer, size_t size, size_t *actual_size)
     352{
     353        uint8_t change_map = 0;
     354       
     355        size_t i;
     356        for (i = 0; i < HUB_PORT_COUNT; i++) {
     357                hub_port_t *port = &hub_dev.ports[i];
     358               
     359                if (port->status_change != 0) {
     360                        change_map |= (1 << (i + 1));
     361                }
     362        }
     363       
     364        uint8_t *b = (uint8_t *) buffer;
     365        if (size > 0) {
     366                *b = change_map;
     367                *actual_size = 1;
     368        }
     369       
     370        return EOK;
     371}
     372
    343373
    344374/**
Note: See TracChangeset for help on using the changeset viewer.