Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/vhc/devices.c

    r774afaae rdaec5e04  
    2727 */
    2828
    29 /** @addtogroup usb
     29/** @addtogroup drvusbvhc
    3030 * @{
    3131 */
     
    3434 */
    3535
    36 #include <ipc/ipc.h>
    3736#include <adt/list.h>
    3837#include <bool.h>
     
    5857/** Create virtual device.
    5958 *
    60  * @param address USB address.
    6159 * @param phone Callback phone.
     60 * @param id Device id.
    6261 * @return New device.
    63  * @retval NULL Out of memory or address already occupied.
    64  */
    65 virtdev_connection_t *virtdev_add_device(int phone)
     62 * @retval NULL Out of memory.
     63 */
     64virtdev_connection_t *virtdev_add_device(int phone, sysarg_t id)
    6665{
    6766        virtdev_connection_t *dev = (virtdev_connection_t *)
    6867            malloc(sizeof(virtdev_connection_t));
     68        if (dev == NULL) {
     69                return NULL;
     70        }
     71
    6972        dev->phone = phone;
     73        dev->id = id;
    7074        list_append(&dev->link, &devices);
    7175       
     
    7579}
    7680
    77 /** Destroy virtual device.
    78  */
    79 void virtdev_destroy_device(virtdev_connection_t *dev)
    80 {
    81         virthub_disconnect_device(&virtual_hub_device, dev);
    82         list_remove(&dev->link);
    83         free(dev);
    84 }
    85 
    86 /** Send data to all connected devices.
    87  *
    88  * @param transaction Transaction to be sent over the bus.
    89  */
    90 usb_transaction_outcome_t virtdev_send_to_all(transaction_t *transaction)
     81/** Find virtual device by id.
     82 *
     83 * @param id Device id.
     84 * @return Device with given id.
     85 * @retval NULL No such device.
     86 */
     87virtdev_connection_t *virtdev_find(sysarg_t id)
    9188{
    9289        link_t *pos;
     
    9491                virtdev_connection_t *dev
    9592                    = list_get_instance(pos, virtdev_connection_t, link);
     93                if (dev->id == id) {
     94                        return dev;
     95                }
     96        }
     97
     98        return NULL;
     99}
     100
     101/** Destroy virtual device.
     102 */
     103void virtdev_destroy_device(virtdev_connection_t *dev)
     104{
     105        virthub_disconnect_device(&virtual_hub_device, dev);
     106        list_remove(&dev->link);
     107        free(dev);
     108}
     109
     110/** Send data to all connected devices.
     111 *
     112 * @param transaction Transaction to be sent over the bus.
     113 */
     114int virtdev_send_to_all(transaction_t *transaction)
     115{
     116        /* For easier debugging. */
     117        switch (transaction->type) {
     118                case USBVIRT_TRANSACTION_SETUP:
     119                case USBVIRT_TRANSACTION_OUT:
     120                        transaction->actual_len = transaction->len;
     121                        break;
     122                case USBVIRT_TRANSACTION_IN:
     123                        transaction->actual_len = 0;
     124                        break;
     125                default:
     126                        assert(false && "unreachable branch in switch()");
     127        }
     128        int outcome = EBADCHECKSUM;
     129
     130        link_t *pos;
     131        list_foreach(pos, &devices) {
     132                virtdev_connection_t *dev
     133                    = list_get_instance(pos, virtdev_connection_t, link);
    96134               
    97135                if (!virthub_is_device_enabled(&virtual_hub_device, dev)) {
     
    100138               
    101139                ipc_call_t answer_data;
    102                 ipcarg_t answer_rc;
     140                sysarg_t answer_rc;
    103141                aid_t req;
    104142                int rc = EOK;
     
    138176                } else {
    139177                        async_wait_for(req, &answer_rc);
     178                        transaction->actual_len = IPC_GET_ARG1(answer_data);
    140179                        rc = (int)answer_rc;
     180                }
     181
     182                /*
     183                 * If at least one device was able to accept this
     184                 * transaction and process it, we can announce success.
     185                 */
     186                if (rc == EOK) {
     187                        outcome = EOK;
    141188                }
    142189        }
     
    148195        if (virtual_hub_device.address == transaction->target.address) {
    149196                size_t tmp;
    150                 dprintf(1, "sending `%s' transaction to hub",
     197                usb_log_debug2("Sending `%s' transaction to hub.\n",
    151198                    usbvirt_str_transaction_type(transaction->type));
    152199                switch (transaction->type) {
     
    164211                                    transaction->buffer, transaction->len,
    165212                                    &tmp);
    166                                 if (tmp < transaction->len) {
    167                                         transaction->len = tmp;
    168                                 }
     213                                transaction->actual_len = tmp;
    169214                                break;
    170215                               
     
    176221                                break;
    177222                }
    178                 dprintf(4, "transaction on hub processed...");
     223                outcome = EOK;
    179224        }
    180225       
     
    183228         * real-life image.
    184229         */
    185         return USB_OUTCOME_OK;
     230        return outcome;
    186231}
    187232
Note: See TracChangeset for help on using the changeset viewer.