Changeset f5f0cfb in mainline for uspace/drv/bus/usb/vhc/transfer.c


Ignore:
Timestamp:
2012-12-22T16:24:28Z (12 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.

File:
1 edited

Legend:

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