Changeset f5f0cfb in mainline


Ignore:
Timestamp:
2012-12-22T16:24:28Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1e2af6a9
Parents:
f6577d9
Message:

vhc: Remove single instance limitation.

Embed hub vitrul device instead of using global instance.

Location:
uspace/drv/bus/usb/vhc
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/vhc/devconn.c

    rf6577d9 rf5f0cfb  
    7979        if (connect) {
    8080                // FIXME: check status
    81                 (void) virthub_connect_device(vhc->hub, dev);
     81                (void) virthub_connect_device(&vhc->hub, dev);
    8282        }
    8383
     
    105105
    106106        // FIXME: check status
    107         (void) virthub_disconnect_device(vhc->hub, dev);
     107        (void) virthub_disconnect_device(&vhc->hub, dev);
    108108
    109109        fibril_mutex_lock(&vhc->guard);
  • uspace/drv/bus/usb/vhc/hub/virthub.c

    rf6577d9 rf5f0cfb  
    146146 * @return Error code.
    147147 */
    148 int virthub_init(usbvirt_device_t *dev)
     148int virthub_init(usbvirt_device_t *dev, const char* name)
    149149{
    150150        if (dev == NULL) {
     
    153153        dev->ops = &hub_ops;
    154154        dev->descriptors = &descriptors;
     155        dev->address = 0;
     156        dev->name = str_dup(name);
     157        if (!name)
     158                return ENOMEM;
    155159
    156160        hub_t *hub = malloc(sizeof(hub_t));
    157161        if (hub == NULL) {
     162                free(dev->name);
    158163                return ENOMEM;
    159164        }
  • uspace/drv/bus/usb/vhc/hub/virthub.h

    rf6577d9 rf5f0cfb  
    7979extern hub_descriptor_t hub_descriptor;
    8080
    81 int virthub_init(usbvirt_device_t *);
     81int virthub_init(usbvirt_device_t *, const char *name);
    8282int virthub_connect_device(usbvirt_device_t *, vhc_virtdev_t *);
    8383int virthub_disconnect_device(usbvirt_device_t *, vhc_virtdev_t *);
  • uspace/drv/bus/usb/vhc/main.c

    rf6577d9 rf5f0cfb  
    4444#include <usb/debug.h>
    4545#include "vhcd.h"
    46 #include "hub/hub.h"
    47 #include "hub/virthub.h"
    4846
    49 static usbvirt_device_t virtual_hub_device = {
    50         .name = "root hub",
    51         .ops = &hub_ops,
    52         .address = 0
    53 };
    5447
    5548static ddf_dev_ops_t vhc_ops = {
     
    5750        .default_handler = default_connection_handler
    5851};
     52
    5953
    6054static int vhc_control_node(ddf_dev_t *dev, ddf_fun_t **fun)
     
    7872                return ret;
    7973        }
    80         vhc_data_init(vhc);
    81         // TODO: This limits us to single vhc instance.
    82         virthub_init(&virtual_hub_device);
    83         vhc->hub = &virtual_hub_device;
     74        vhc_init(vhc);
    8475        return EOK;
    8576}
    86 
    8777
    8878static int vhc_dev_add(ddf_dev_t *dev)
     
    111101        /* Add virtual hub device */
    112102        usb_address_t address = 1;
    113         ret = vhc_virtdev_plug_hub(data, data->hub, NULL, address);
     103        ret = vhc_virtdev_plug_hub(data, &data->hub, NULL, address);
    114104        if (ret != EOK) {
    115105                usb_log_error("Failed to plug root hub: %s.\n", str_error(ret));
  • uspace/drv/bus/usb/vhc/transfer.c

    rf6577d9 rf5f0cfb  
    3333#include <usbvirt/ipc.h>
    3434#include "vhcd.h"
     35#include "hub/virthub.h"
     36
     37static bool is_set_address_transfer(vhc_transfer_t *transfer)
     38{
     39        if (transfer->batch->ep->endpoint != 0) {
     40                return false;
     41        }
     42        if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
     43                return false;
     44        }
     45        if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) {
     46                return false;
     47        }
     48        const usb_device_request_setup_packet_t *setup =
     49            (void*)transfer->batch->setup_buffer;
     50        if (setup->request_type != 0) {
     51                return false;
     52        }
     53        if (setup->request != USB_DEVREQ_SET_ADDRESS) {
     54                return false;
     55        }
     56
     57        return true;
     58}
     59
     60static int process_transfer_local(usb_transfer_batch_t *batch,
     61    usbvirt_device_t *dev, size_t *actual_data_size)
     62{
     63        int rc;
     64       
     65        const usb_direction_t dir = usb_transfer_batch_direction(batch);
     66
     67        if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     68                if (dir == USB_DIRECTION_IN) {
     69                        rc = usbvirt_control_read(dev,
     70                            batch->setup_buffer, batch->setup_size,
     71                            batch->buffer, batch->buffer_size,
     72                            actual_data_size);
     73                } else {
     74                        assert(dir == USB_DIRECTION_OUT);
     75                        rc = usbvirt_control_write(dev,
     76                            batch->setup_buffer, batch->setup_size,
     77                            batch->buffer, batch->buffer_size);
     78                }
     79        } else {
     80                if (dir == USB_DIRECTION_IN) {
     81                        rc = usbvirt_data_in(dev, batch->ep->transfer_type,
     82                            batch->ep->endpoint,
     83                            batch->buffer, batch->buffer_size,
     84                            actual_data_size);
     85                } else {
     86                        assert(dir == USB_DIRECTION_OUT);
     87                        rc = usbvirt_data_out(dev, batch->ep->transfer_type,
     88                            batch->ep->endpoint,
     89                            batch->buffer, batch->buffer_size);
     90                }
     91        }
     92
     93        return rc;
     94}
     95
     96static int process_transfer_remote(usb_transfer_batch_t *batch,
     97    async_sess_t *sess, size_t *actual_data_size)
     98{
     99        int rc;
     100
     101        const usb_direction_t dir = usb_transfer_batch_direction(batch);
     102
     103        if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
     104                if (dir == USB_DIRECTION_IN) {
     105                        rc = usbvirt_ipc_send_control_read(sess,
     106                            batch->setup_buffer, batch->setup_size,
     107                            batch->buffer, batch->buffer_size,
     108                            actual_data_size);
     109                } else {
     110                        assert(dir == USB_DIRECTION_OUT);
     111                        rc = usbvirt_ipc_send_control_write(sess,
     112                            batch->setup_buffer, batch->setup_size,
     113                            batch->buffer, batch->buffer_size);
     114                }
     115        } else {
     116                if (dir == USB_DIRECTION_IN) {
     117                        rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
     118                            batch->ep->transfer_type,
     119                            batch->buffer, batch->buffer_size,
     120                            actual_data_size);
     121                } else {
     122                        assert(dir == USB_DIRECTION_OUT);
     123                        rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
     124                            batch->ep->transfer_type,
     125                            batch->buffer, batch->buffer_size);
     126                }
     127        }
     128
     129        return rc;
     130}
     131
     132static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev)
     133{
     134        assert(fibril_mutex_is_locked(&dev->guard));
     135        assert(!list_empty(&dev->transfer_queue));
     136
     137        vhc_transfer_t *transfer = list_get_instance(
     138            list_first(&dev->transfer_queue), vhc_transfer_t, link);
     139        list_remove(&transfer->link);
     140
     141        return transfer;
     142}
     143
     144static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
     145    size_t data_transfer_size, int outcome)
     146{
     147        assert(outcome != ENAK);
     148        assert(transfer);
     149        assert(transfer->batch);
     150        usb_transfer_batch_finish_error(transfer->batch, NULL,
     151            data_transfer_size, outcome);
     152        usb_transfer_batch_destroy(transfer->batch);
     153        free(transfer);
     154}
     155
     156int vhc_init(vhc_data_t *instance)
     157{
     158        assert(instance);
     159        list_initialize(&instance->devices);
     160        fibril_mutex_initialize(&instance->guard);
     161        instance->magic = 0xDEADBEEF;
     162        return virthub_init(&instance->hub, "root hub");
     163}
    35164
    36165int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
     
    69198
    70199        return targets ? EOK : ENOENT;
    71 }
    72 
    73 static bool is_set_address_transfer(vhc_transfer_t *transfer)
    74 {
    75         if (transfer->batch->ep->endpoint != 0) {
    76                 return false;
    77         }
    78         if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
    79                 return false;
    80         }
    81         if (usb_transfer_batch_direction(transfer->batch) != USB_DIRECTION_OUT) {
    82                 return false;
    83         }
    84         const usb_device_request_setup_packet_t *setup =
    85             (void*)transfer->batch->setup_buffer;
    86         if (setup->request_type != 0) {
    87                 return false;
    88         }
    89         if (setup->request != USB_DEVREQ_SET_ADDRESS) {
    90                 return false;
    91         }
    92 
    93         return true;
    94 }
    95 
    96 static int process_transfer_local(usb_transfer_batch_t *batch,
    97     usbvirt_device_t *dev, size_t *actual_data_size)
    98 {
    99         int rc;
    100        
    101         const usb_direction_t dir = usb_transfer_batch_direction(batch);
    102 
    103         if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    104                 if (dir == USB_DIRECTION_IN) {
    105                         rc = usbvirt_control_read(dev,
    106                             batch->setup_buffer, batch->setup_size,
    107                             batch->buffer, batch->buffer_size,
    108                             actual_data_size);
    109                 } else {
    110                         assert(dir == USB_DIRECTION_OUT);
    111                         rc = usbvirt_control_write(dev,
    112                             batch->setup_buffer, batch->setup_size,
    113                             batch->buffer, batch->buffer_size);
    114                 }
    115         } else {
    116                 if (dir == USB_DIRECTION_IN) {
    117                         rc = usbvirt_data_in(dev, batch->ep->transfer_type,
    118                             batch->ep->endpoint,
    119                             batch->buffer, batch->buffer_size,
    120                             actual_data_size);
    121                 } else {
    122                         assert(dir == USB_DIRECTION_OUT);
    123                         rc = usbvirt_data_out(dev, batch->ep->transfer_type,
    124                             batch->ep->endpoint,
    125                             batch->buffer, batch->buffer_size);
    126                 }
    127         }
    128 
    129         return rc;
    130 }
    131 
    132 static int process_transfer_remote(usb_transfer_batch_t *batch,
    133     async_sess_t *sess, size_t *actual_data_size)
    134 {
    135         int rc;
    136 
    137         const usb_direction_t dir = usb_transfer_batch_direction(batch);
    138 
    139         if (batch->ep->transfer_type == USB_TRANSFER_CONTROL) {
    140                 if (dir == USB_DIRECTION_IN) {
    141                         rc = usbvirt_ipc_send_control_read(sess,
    142                             batch->setup_buffer, batch->setup_size,
    143                             batch->buffer, batch->buffer_size,
    144                             actual_data_size);
    145                 } else {
    146                         assert(dir == USB_DIRECTION_OUT);
    147                         rc = usbvirt_ipc_send_control_write(sess,
    148                             batch->setup_buffer, batch->setup_size,
    149                             batch->buffer, batch->buffer_size);
    150                 }
    151         } else {
    152                 if (dir == USB_DIRECTION_IN) {
    153                         rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
    154                             batch->ep->transfer_type,
    155                             batch->buffer, batch->buffer_size,
    156                             actual_data_size);
    157                 } else {
    158                         assert(dir == USB_DIRECTION_OUT);
    159                         rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
    160                             batch->ep->transfer_type,
    161                             batch->buffer, batch->buffer_size);
    162                 }
    163         }
    164 
    165         return rc;
    166 }
    167 
    168 static vhc_transfer_t *dequeue_first_transfer(vhc_virtdev_t *dev)
    169 {
    170         assert(fibril_mutex_is_locked(&dev->guard));
    171         assert(!list_empty(&dev->transfer_queue));
    172 
    173         vhc_transfer_t *transfer = list_get_instance(
    174             list_first(&dev->transfer_queue), vhc_transfer_t, link);
    175         list_remove(&transfer->link);
    176 
    177         return transfer;
    178 }
    179 
    180 static void execute_transfer_callback_and_free(vhc_transfer_t *transfer,
    181     size_t data_transfer_size, int outcome)
    182 {
    183         assert(outcome != ENAK);
    184         assert(transfer);
    185         assert(transfer->batch);
    186         usb_transfer_batch_finish_error(transfer->batch, NULL,
    187             data_transfer_size, outcome);
    188         usb_transfer_batch_destroy(transfer->batch);
    189         free(transfer);
    190200}
    191201
  • uspace/drv/bus/usb/vhc/vhcd.h

    rf6577d9 rf5f0cfb  
    5959        list_t devices;
    6060        fibril_mutex_t guard;
    61         usbvirt_device_t *hub;
    62         ddf_fun_t *hc_fun;
     61        usbvirt_device_t hub;
    6362} vhc_data_t;
    6463
     
    6867} vhc_transfer_t;
    6968
    70 static inline void vhc_data_init(vhc_data_t *instance)
    71 {
    72         assert(instance);
    73         list_initialize(&instance->devices);
    74         fibril_mutex_initialize(&instance->guard);
    75         instance->magic = 0xDEADBEEF;
    76 }
    7769
    7870void on_client_close(ddf_fun_t *fun);
     
    8577void vhc_virtdev_unplug(vhc_data_t *, uintptr_t);
    8678
    87 
     79int vhc_init(vhc_data_t *instance);
    8880int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    8981int vhc_transfer_queue_processor(void *arg);
Note: See TracChangeset for help on using the changeset viewer.