Changeset 7a7bfeb3 in mainline for uspace/srv


Ignore:
Timestamp:
2010-10-24T16:43:40Z (15 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/srv/hw/bus/usb/hcd/virtual
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • 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.