Changeset 7a7bfeb3 in mainline for uspace/lib/usbvirt/main.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.