Changeset beee81a in mainline


Ignore:
Timestamp:
2011-05-07T09:35:15Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bc02b83, d38d830
Parents:
42e2172
Message:

Virtual USB refactoring

Changes include

  • add missing comments
  • add function for virtual device disconnect
  • fix memory leak
  • support for bulks
  • checking of input parameters
Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/vuhid/main.c

    r42e2172 rbeee81a  
    194194        printf("Terminating...\n");
    195195       
     196        usbvirt_device_unplug(&hid_dev);
     197
    196198        return 0;
    197199}
  • uspace/drv/vhc/transfer.c

    r42e2172 rbeee81a  
    135135                if (transfer->direction == USB_DIRECTION_IN) {
    136136                        rc = usbvirt_ipc_send_control_read(phone,
    137                             transfer->endpoint,
    138137                            transfer->setup_buffer, transfer->setup_buffer_size,
    139138                            transfer->data_buffer, transfer->data_buffer_size,
     
    142141                        assert(transfer->direction == USB_DIRECTION_OUT);
    143142                        rc = usbvirt_ipc_send_control_write(phone,
    144                             transfer->endpoint,
    145143                            transfer->setup_buffer, transfer->setup_buffer_size,
    146144                            transfer->data_buffer, transfer->data_buffer_size);
  • uspace/lib/usbvirt/include/usbvirt/device.h

    r42e2172 rbeee81a  
    194194         */
    195195        usbvirt_device_state_t state;
     196        /** Phone to the host controller.
     197         * You shall treat this field as read only in your code.
     198         */
     199        int vhc_phone;
    196200};
    197201
    198202int usbvirt_device_plug(usbvirt_device_t *, const char *);
     203void usbvirt_device_unplug(usbvirt_device_t *);
    199204
    200205void usbvirt_control_reply_helper(const usb_device_request_setup_packet_t *,
  • uspace/lib/usbvirt/include/usbvirt/ipc.h

    r42e2172 rbeee81a  
    4646        IPC_M_USBVIRT_CONTROL_WRITE,
    4747        IPC_M_USBVIRT_INTERRUPT_IN,
    48         IPC_M_USBVIRT_INTERRUPT_OUT
     48        IPC_M_USBVIRT_INTERRUPT_OUT,
     49        IPC_M_USBVIRT_BULK_IN,
     50        IPC_M_USBVIRT_BULK_OUT
    4951} usbvirt_hc_to_device_method_t;
    5052
    51 int usbvirt_ipc_send_control_read(int, usb_endpoint_t, void *, size_t,
     53int usbvirt_ipc_send_control_read(int, void *, size_t,
    5254    void *, size_t, size_t *);
    53 int usbvirt_ipc_send_control_write(int, usb_endpoint_t, void *, size_t,
     55int usbvirt_ipc_send_control_write(int, void *, size_t,
    5456    void *, size_t);
    5557int usbvirt_ipc_send_data_in(int, usb_endpoint_t, usb_transfer_type_t,
  • uspace/lib/usbvirt/src/device.c

    r42e2172 rbeee81a  
    4444#include <usb/debug.h>
    4545
     46/** Current device. */
    4647static usbvirt_device_t *DEV = NULL;
    4748
     49/** Main IPC call handling from virtual host controller.
     50 *
     51 * @param iid Caller identification.
     52 * @param icall Initial incoming call.
     53 */
    4854static void callback_connection(ipc_callid_t iid, ipc_call_t *icall)
    4955{
     
    8288        devman_handle_t handle;
    8389
     90        if (DEV != NULL) {
     91                return ELIMIT;
     92        }
     93
    8494        rc = devman_device_get_handle(vhc_path, &handle, 0);
    8595        if (rc != EOK) {
     
    94104
    95105        DEV = dev;
     106        dev->vhc_phone = hcd_phone;
    96107
    97108        rc = async_connect_to_me(hcd_phone, 0, 0, 0, callback_connection);
    98109        if (rc != EOK) {
    99110                DEV = NULL;
    100                 return rc;
    101111        }
    102112
    103 
    104 
    105         return EOK;
     113        return rc;
    106114}
    107115
     116/** Disconnect the device from virtual host controller.
     117 *
     118 * @param dev Device to be disconnected.
     119 */
     120void usbvirt_device_unplug(usbvirt_device_t *dev)
     121{
     122        async_hangup(dev->vhc_phone);
     123}
    108124
    109125/**
  • uspace/lib/usbvirt/src/ipc_dev.c

    r42e2172 rbeee81a  
    4343#include <usb/debug.h>
    4444
     45/** Handle VHC request for device name.
     46 *
     47 * @param dev Target virtual device.
     48 * @param iid Caller id.
     49 * @param icall The call with the request.
     50 */
    4551static void ipc_get_name(usbvirt_device_t *dev,
    4652    ipc_callid_t iid, ipc_call_t *icall)
     
    6773}
    6874
     75/** Handle VHC request for control read from the device.
     76 *
     77 * @param dev Target virtual device.
     78 * @param iid Caller id.
     79 * @param icall The call with the request.
     80 */
    6981static void ipc_control_read(usbvirt_device_t *dev,
    7082    ipc_callid_t iid, ipc_call_t *icall)
    7183{
    72         //usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
    73 
    7484        int rc;
    7585
     
    118128}
    119129
     130/** Handle VHC request for control write to the device.
     131 *
     132 * @param dev Target virtual device.
     133 * @param iid Caller id.
     134 * @param icall The call with the request.
     135 */
    120136static void ipc_control_write(usbvirt_device_t *dev,
    121137    ipc_callid_t iid, ipc_call_t *icall)
    122138{
    123         size_t data_buffer_len = IPC_GET_ARG2(*icall);
     139        size_t data_buffer_len = IPC_GET_ARG1(*icall);
    124140        int rc;
    125141
     
    129145
    130146        rc = async_data_write_accept(&setup_packet, false,
    131             1, 1024, 0, &setup_packet_len);
     147            1, 0, 0, &setup_packet_len);
    132148        if (rc != EOK) {
    133149                async_answer_0(iid, rc);
     
    137153        if (data_buffer_len > 0) {
    138154                rc = async_data_write_accept(&data_buffer, false,
    139                     1, 1024, 0, &data_buffer_len);
     155                    1, 0, 0, &data_buffer_len);
    140156                if (rc != EOK) {
    141157                        async_answer_0(iid, rc);
     
    149165
    150166        async_answer_0(iid, rc);
    151 }
    152 
    153 static void ipc_interrupt_in(usbvirt_device_t *dev,
     167
     168        free(setup_packet);
     169        if (data_buffer != NULL) {
     170                free(data_buffer);
     171        }
     172}
     173
     174/** Handle VHC request for data read from the device (in transfer).
     175 *
     176 * @param dev Target virtual device.
     177 * @param iid Caller id.
     178 * @param icall The call with the request.
     179 */
     180static void ipc_data_in(usbvirt_device_t *dev,
     181    usb_transfer_type_t transfer_type,
    154182    ipc_callid_t iid, ipc_call_t *icall)
    155183{
    156184        usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
    157         usb_transfer_type_t transfer_type = IPC_GET_ARG2(*icall);
    158185
    159186        int rc;
     
    189216}
    190217
    191 static void ipc_interrupt_out(usbvirt_device_t *dev,
     218/** Handle VHC request for data write to the device (out transfer).
     219 *
     220 * @param dev Target virtual device.
     221 * @param iid Caller id.
     222 * @param icall The call with the request.
     223 */
     224static void ipc_data_out(usbvirt_device_t *dev,
     225    usb_transfer_type_t transfer_type,
    192226    ipc_callid_t iid, ipc_call_t *icall)
    193227{
    194228        usb_endpoint_t endpoint = IPC_GET_ARG1(*icall);
    195         usb_transfer_type_t transfer_type = IPC_GET_ARG2(*icall);
    196229
    197230        void *data_buffer = NULL;
     
    199232
    200233        int rc = async_data_write_accept(&data_buffer, false,
    201             1, 1024, 0, &data_buffer_size);
     234            1, 0, 0, &data_buffer_size);
    202235        if (rc != EOK) {
    203236                async_answer_0(iid, rc);
     
    213246}
    214247
    215 
     248/** Handle incoming IPC call for virtual USB device.
     249 *
     250 * @param dev Target USB device.
     251 * @param callid Caller id.
     252 * @param call Incoming call.
     253 * @return Whether the call was handled.
     254 */
    216255bool usbvirt_ipc_handle_call(usbvirt_device_t *dev,
    217256    ipc_callid_t callid, ipc_call_t *call)
    218257{
    219258        switch (IPC_GET_IMETHOD(*call)) {
    220                 case IPC_M_USBVIRT_GET_NAME:
    221                         ipc_get_name(dev, callid, call);
    222                         break;
    223 
    224                 case IPC_M_USBVIRT_CONTROL_READ:
    225                         ipc_control_read(dev, callid, call);
    226                         break;
    227 
    228                 case IPC_M_USBVIRT_CONTROL_WRITE:
    229                         ipc_control_write(dev, callid, call);
    230                         break;
    231 
    232                 case IPC_M_USBVIRT_INTERRUPT_IN:
    233                         ipc_interrupt_in(dev, callid, call);
    234                         break;
    235 
    236                 case IPC_M_USBVIRT_INTERRUPT_OUT:
    237                         ipc_interrupt_out(dev, callid, call);
    238                         break;
    239 
    240                 default:
    241                         return false;
     259        case IPC_M_USBVIRT_GET_NAME:
     260                ipc_get_name(dev, callid, call);
     261                break;
     262
     263        case IPC_M_USBVIRT_CONTROL_READ:
     264                ipc_control_read(dev, callid, call);
     265                break;
     266
     267        case IPC_M_USBVIRT_CONTROL_WRITE:
     268                ipc_control_write(dev, callid, call);
     269                break;
     270
     271        case IPC_M_USBVIRT_INTERRUPT_IN:
     272                ipc_data_in(dev, USB_TRANSFER_INTERRUPT, callid, call);
     273                break;
     274
     275        case IPC_M_USBVIRT_BULK_IN:
     276                ipc_data_in(dev, USB_TRANSFER_BULK, callid, call);
     277                break;
     278
     279        case IPC_M_USBVIRT_INTERRUPT_OUT:
     280                ipc_data_out(dev, USB_TRANSFER_INTERRUPT, callid, call);
     281                break;
     282
     283        case IPC_M_USBVIRT_BULK_OUT:
     284                ipc_data_out(dev, USB_TRANSFER_BULK, callid, call);
     285                break;
     286
     287
     288        default:
     289                return false;
    242290        }
    243291
  • uspace/lib/usbvirt/src/ipc_hc.c

    r42e2172 rbeee81a  
    5454 * @return Error code.
    5555 */
    56 int usbvirt_ipc_send_control_read(int phone, usb_endpoint_t ep,
     56int usbvirt_ipc_send_control_read(int phone,
    5757    void *setup_buffer, size_t setup_buffer_size,
    5858    void *data_buffer, size_t data_buffer_size, size_t *data_transfered_size)
    5959{
    60         aid_t opening_request = async_send_1(phone,
    61             IPC_M_USBVIRT_CONTROL_READ, ep, NULL);
     60        if (phone < 0) {
     61                return EINVAL;
     62        }
     63        if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
     64                return EINVAL;
     65        }
     66        if ((data_buffer == NULL) || (data_buffer_size == 0)) {
     67                return EINVAL;
     68        }
     69
     70        aid_t opening_request = async_send_0(phone,
     71            IPC_M_USBVIRT_CONTROL_READ, NULL);
    6272        if (opening_request == 0) {
    6373                return ENOMEM;
     
    98108        }
    99109
    100         *data_transfered_size = IPC_GET_ARG2(data_request_call);
     110        if (data_transfered_size != NULL) {
     111                *data_transfered_size = IPC_GET_ARG2(data_request_call);
     112        }
    101113
    102114        return EOK;
     
    113125 * @return Error code.
    114126 */
    115 int usbvirt_ipc_send_control_write(int phone, usb_endpoint_t ep,
     127int usbvirt_ipc_send_control_write(int phone,
    116128    void *setup_buffer, size_t setup_buffer_size,
    117129    void *data_buffer, size_t data_buffer_size)
    118130{
    119         aid_t opening_request = async_send_2(phone,
    120             IPC_M_USBVIRT_CONTROL_WRITE, ep, data_buffer_size,  NULL);
     131        if (phone < 0) {
     132                return EINVAL;
     133        }
     134        if ((setup_buffer == NULL) || (setup_buffer_size == 0)) {
     135                return EINVAL;
     136        }
     137        if ((data_buffer_size > 0) && (data_buffer == NULL)) {
     138                return EINVAL;
     139        }
     140
     141        aid_t opening_request = async_send_1(phone,
     142            IPC_M_USBVIRT_CONTROL_WRITE, data_buffer_size,  NULL);
    121143        if (opening_request == 0) {
    122144                return ENOMEM;
     
    159181    usb_transfer_type_t tr_type, void *data, size_t data_size, size_t *act_size)
    160182{
    161         aid_t opening_request = async_send_2(phone,
    162             IPC_M_USBVIRT_INTERRUPT_IN, ep, tr_type, NULL);
    163         if (opening_request == 0) {
    164                 return ENOMEM;
    165         }
     183        if (phone < 0) {
     184                return EINVAL;
     185        }
     186        usbvirt_hc_to_device_method_t method;
     187        switch (tr_type) {
     188        case USB_TRANSFER_INTERRUPT:
     189                method = IPC_M_USBVIRT_INTERRUPT_IN;
     190                break;
     191        case USB_TRANSFER_BULK:
     192                method = IPC_M_USBVIRT_BULK_IN;
     193                break;
     194        default:
     195                return EINVAL;
     196        }
     197        if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
     198                return EINVAL;
     199        }
     200        if ((data == NULL) || (data_size == 0)) {
     201                return EINVAL;
     202        }
     203
     204
     205        aid_t opening_request = async_send_2(phone, method, ep, tr_type, NULL);
     206        if (opening_request == 0) {
     207                return ENOMEM;
     208        }
     209
    166210
    167211        ipc_call_t data_request_call;
     
    210254    usb_transfer_type_t tr_type, void *data, size_t data_size)
    211255{
    212         aid_t opening_request = async_send_2(phone,
    213             IPC_M_USBVIRT_INTERRUPT_OUT, ep, tr_type, NULL);
     256        if (phone < 0) {
     257                return EINVAL;
     258        }
     259        usbvirt_hc_to_device_method_t method;
     260        switch (tr_type) {
     261        case USB_TRANSFER_INTERRUPT:
     262                method = IPC_M_USBVIRT_INTERRUPT_OUT;
     263                break;
     264        case USB_TRANSFER_BULK:
     265                method = IPC_M_USBVIRT_BULK_OUT;
     266                break;
     267        default:
     268                return EINVAL;
     269        }
     270        if ((ep <= 0) || (ep >= USBVIRT_ENDPOINT_MAX)) {
     271                return EINVAL;
     272        }
     273        if ((data == NULL) || (data_size == 0)) {
     274                return EINVAL;
     275        }
     276
     277        aid_t opening_request = async_send_1(phone, method, ep, NULL);
    214278        if (opening_request == 0) {
    215279                return ENOMEM;
Note: See TracChangeset for help on using the changeset viewer.