Changeset 79d2987 in mainline


Ignore:
Timestamp:
2011-02-11T17:16:36Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4e8e1f5
Parents:
25971d2 (diff), 608afb9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge development/ changes

Location:
uspace
Files:
1 added
1 deleted
18 edited
1 moved

Legend:

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

    r25971d2 r79d2987  
    8181{
    8282        int rc;
     83
     84        if (str_cmp(path, "uhci") == 0) {
     85                path = "/hw/pci0/00:01.2";
     86        }
    8387
    8488        devman_handle_t handle;
  • uspace/drv/uhci-hcd/Makefile

    r25971d2 r79d2987  
    3333
    3434SOURCES = \
    35         callback.c \
    3635        iface.c \
    3736        main.c \
     
    4039        uhci.c \
    4140        uhci_struct/transfer_descriptor.c \
    42         pci.c
     41        pci.c \
     42        tracker.c
    4343
    4444include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/uhci-hcd/iface.c

    r25971d2 r79d2987  
    106106    usbhc_iface_transfer_out_callback_t callback, void *arg)
    107107{
    108         assert(dev);
    109         uhci_t *hc = dev_to_uhci(dev);
    110         assert(hc);
    111         return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_OUT,
    112                 false, data, size, callback, NULL, arg);
     108        size_t max_packet_size = 8;
     109        dev_speed_t speed = FULL_SPEED;
     110
     111        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT,
     112            max_packet_size, speed, data, size, NULL, callback, arg);
     113        if (!tracker)
     114                return ENOMEM;
     115        tracker_interrupt_out(tracker);
     116        return EOK;
    113117}
    114118/*----------------------------------------------------------------------------*/
     
    117121    usbhc_iface_transfer_in_callback_t callback, void *arg)
    118122{
    119         assert(dev);
    120         uhci_t *hc = dev_to_uhci(dev);
    121         assert(hc);
    122         return uhci_transfer(hc, dev, target, USB_TRANSFER_INTERRUPT, 0, USB_PID_IN,
    123                 false, data, size, NULL, callback, arg);
     123        size_t max_packet_size = 4;
     124        dev_speed_t speed = FULL_SPEED;
     125
     126        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_INTERRUPT,
     127            max_packet_size, speed, data, size, callback, NULL, arg);
     128        if (!tracker)
     129                return ENOMEM;
     130        tracker_interrupt_in(tracker);
     131        return EOK;
     132}
     133/*----------------------------------------------------------------------------*/
     134static int control_write(device_t *dev, usb_target_t target,
     135    void *setup_data, size_t setup_size, void *data, size_t size,
     136    usbhc_iface_transfer_out_callback_t callback, void *arg)
     137{
     138        size_t max_packet_size = 8;
     139        dev_speed_t speed = FULL_SPEED;
     140
     141        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     142            max_packet_size, speed, data, size, NULL, callback, arg);
     143        if (!tracker)
     144                return ENOMEM;
     145        tracker_control_write(tracker, setup_data, setup_size);
     146        return EOK;
     147}
     148/*----------------------------------------------------------------------------*/
     149static int control_read(device_t *dev, usb_target_t target,
     150    void *setup_data, size_t setup_size, void *data, size_t size,
     151    usbhc_iface_transfer_in_callback_t callback, void *arg)
     152{
     153        size_t max_packet_size = 8;
     154        dev_speed_t speed = FULL_SPEED;
     155
     156        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     157            max_packet_size, speed, data, size, callback, NULL, arg);
     158        if (!tracker)
     159                return ENOMEM;
     160        tracker_control_read(tracker, setup_data, setup_size);
     161        return EOK;
    124162}
    125163/*----------------------------------------------------------------------------*/
     
    128166    usbhc_iface_transfer_out_callback_t callback, void *arg)
    129167{
    130         assert(dev);
    131         uhci_t *hc = dev_to_uhci(dev);
    132         assert(hc);
    133         return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP,
    134                 false, data, size, callback, NULL, arg);
     168        usb_log_warning("Using deprecated API control write setup.\n");
     169        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     170            8, FULL_SPEED, data, size, NULL, callback, arg);
     171        if (!tracker)
     172                return ENOMEM;
     173        tracker_control_setup_old(tracker);
     174        return EOK;
    135175}
    136176/*----------------------------------------------------------------------------*/
     
    139179    usbhc_iface_transfer_out_callback_t callback, void *arg)
    140180{
    141         assert(dev);
    142         uhci_t *hc = dev_to_uhci(dev);
    143         assert(hc);
    144         return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_OUT,
    145                 false, data, size, callback, NULL, arg);
     181        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     182            size, FULL_SPEED, data, size, NULL, callback, arg);
     183        if (!tracker)
     184                return ENOMEM;
     185        tracker_control_write_data_old(tracker);
     186        return EOK;
    146187}
    147188/*----------------------------------------------------------------------------*/
     
    149190    usbhc_iface_transfer_in_callback_t callback, void *arg)
    150191{
    151         assert(dev);
    152         uhci_t *hc = dev_to_uhci(dev);
    153         assert(hc);
    154         return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_IN,
    155                 false, NULL, 0, NULL, callback, arg);
     192        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     193            0, FULL_SPEED, NULL, 0, callback, NULL, arg);
     194        if (!tracker)
     195                return ENOMEM;
     196        tracker_control_write_status_old(tracker);
     197        return EOK;
    156198}
    157199/*----------------------------------------------------------------------------*/
     
    160202    usbhc_iface_transfer_out_callback_t callback, void *arg)
    161203{
    162         assert(dev);
    163         uhci_t *hc = dev_to_uhci(dev);
    164         assert(hc);
    165         return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_SETUP,
    166                 false, data, size, callback, NULL, arg);
     204        usb_log_warning("Using deprecated API control read setup.\n");
     205        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     206            8, FULL_SPEED, data, size, NULL, callback, arg);
     207        if (!tracker)
     208                return ENOMEM;
     209        tracker_control_setup_old(tracker);
     210        return EOK;
    167211}
    168212/*----------------------------------------------------------------------------*/
     
    171215    usbhc_iface_transfer_in_callback_t callback, void *arg)
    172216{
    173         assert(dev);
    174         uhci_t *hc = dev_to_uhci(dev);
    175         assert(hc);
    176         return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 1, USB_PID_IN,
    177                 false, data, size, NULL, callback, arg);
     217        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     218            size, FULL_SPEED, data, size, callback, NULL, arg);
     219        if (!tracker)
     220                return ENOMEM;
     221        tracker_control_read_data_old(tracker);
     222        return EOK;
    178223}
    179224/*----------------------------------------------------------------------------*/
     
    181226    usbhc_iface_transfer_out_callback_t callback, void *arg)
    182227{
    183         assert(dev);
    184         uhci_t *hc = dev_to_uhci(dev);
    185         assert(hc);
    186         return uhci_transfer(hc, dev, target, USB_TRANSFER_CONTROL, 0, USB_PID_OUT,
    187                 false, NULL, 0, callback, NULL, arg);
    188 }
    189 
    190 
     228        tracker_t *tracker = tracker_get(dev, target, USB_TRANSFER_CONTROL,
     229            0, FULL_SPEED, NULL, 0, NULL, callback, arg);
     230        if (!tracker)
     231                return ENOMEM;
     232        tracker_control_read_status_old(tracker);
     233        return EOK;
     234}
     235/*----------------------------------------------------------------------------*/
    191236usbhc_iface_t uhci_iface = {
    192237        .tell_address = get_address,
     
    200245        .interrupt_out = interrupt_out,
    201246        .interrupt_in = interrupt_in,
     247
     248        .control_read = control_read,
     249        .control_write = control_write,
    202250
    203251        .control_write_setup = control_write_setup,
  • uspace/drv/uhci-hcd/tracker.h

    r25971d2 r79d2987  
    11/*
    2  * Copyright (c) 2010 Jan Vesely
     2 * Copyright (c) 2011 Jan Vesely
    33 * All rights reserved.
    44 *
     
    3232 * @brief UHCI driver
    3333 */
    34 #ifndef DRV_UHCI_CALLBACK_H
    35 #define DRV_UHCI_CALLBACK_H
     34#ifndef DRV_UHCI_TRACKER_H
     35#define DRV_UHCI_TRACKER_H
     36
     37#include <adt/list.h>
    3638
    3739#include <usbhc_iface.h>
    3840#include <usb/usb.h>
    3941
    40 #include "utils/malloc32.h"
     42#include "uhci_struct/transfer_descriptor.h"
    4143
    42 typedef struct callback
     44typedef enum {
     45        LOW_SPEED,
     46        FULL_SPEED,
     47} dev_speed_t;
     48
     49typedef struct tracker
    4350{
    44         usbhc_iface_transfer_in_callback_t callback_in;
    45         usbhc_iface_transfer_out_callback_t callback_out;
    46         void *old_buffer;
    47         void *new_buffer;
     51        link_t link;
     52        usb_target_t target;
     53        usb_transfer_type_t transfer_type;
     54        union {
     55                usbhc_iface_transfer_in_callback_t callback_in;
     56                usbhc_iface_transfer_out_callback_t callback_out;
     57        };
    4858        void *arg;
     59        char *buffer;
     60        char *packet;
    4961        size_t buffer_size;
    50         size_t actual_size;
     62        size_t max_packet_size;
     63        size_t packet_size;
     64        size_t buffer_offset;
     65        dev_speed_t speed;
    5166        device_t *dev;
    52 } callback_t;
     67        transfer_descriptor_t *td;
     68        void (*next_step)(struct tracker*);
     69        unsigned toggle:1;
     70} tracker_t;
    5371
    5472
    55 int callback_init(callback_t *instance, device_t *dev,
    56   void *buffer, size_t size, usbhc_iface_transfer_in_callback_t func_in,
    57   usbhc_iface_transfer_out_callback_t func_out, void *arg);
     73tracker_t * tracker_get(device_t *dev, usb_target_t target,
     74    usb_transfer_type_t transfer_type, size_t max_packet_size,
     75    dev_speed_t speed, char *buffer, size_t size,
     76    usbhc_iface_transfer_in_callback_t func_in,
     77    usbhc_iface_transfer_out_callback_t func_out, void *arg);
    5878
    59 #define callback_in_init(instance, dev, buffer, size, func, arg) \
    60         callback_init(instance, dev, buffer, size, func, NULL, arg)
     79void tracker_control_write(
     80    tracker_t *instance, char* setup_buffer, size_t setup_size);
    6181
    62 #define callback_out_init(instance, dev, buffer, size, func, arg) \
    63         callback_init(instance, dev, buffer, size, func, NULL, arg)
     82void tracker_control_read(
     83    tracker_t *instance, char* setup_buffer, size_t setup_size);
    6484
    65 static inline callback_t *callback_get(device_t *dev,
    66   void *buffer, size_t size, usbhc_iface_transfer_in_callback_t func_in,
    67   usbhc_iface_transfer_out_callback_t func_out, void *arg)
    68 {
    69         callback_t *instance = malloc(sizeof(callback_t));
    70         if (callback_init(instance, dev, buffer, size, func_in, func_out, arg)) {
    71                 free(instance);
    72                 instance = NULL;
    73         }
    74         return instance;
    75 }
     85void tracker_interrupt_in(tracker_t *instance);
    7686
    77 static inline void callback_fini(callback_t *instance)
    78 {
    79         assert(instance);
    80         if (instance->new_buffer)
    81                 free32(instance->new_buffer);
    82 }
     87void tracker_interrupt_out(tracker_t *instance);
    8388
    84 static inline void callback_dispose(callback_t *instance)
    85 {
    86         callback_fini(instance);
    87         free(instance);
    88 }
     89/* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */
     90void tracker_control_setup_old(tracker_t *instance);
    8991
    90 void callback_run(
    91   callback_t *instance, usb_transaction_outcome_t outcome, size_t act_size);
     92void tracker_control_write_data_old(tracker_t *instance);
     93
     94void tracker_control_read_data_old(tracker_t *instance);
     95
     96void tracker_control_write_status_old(tracker_t *instance);
     97
     98void tracker_control_read_status_old(tracker_t *instance);
    9299#endif
    93100/**
  • uspace/drv/uhci-hcd/transfer_list.c

    r25971d2 r79d2987  
    4141{
    4242        assert(instance);
    43         instance->first = NULL;
    44         instance->last = NULL;
    4543        instance->next = NULL;
    4644        instance->name = name;
     
    6664}
    6765/*----------------------------------------------------------------------------*/
    68 int transfer_list_append(
    69   transfer_list_t *instance, transfer_descriptor_t *transfer)
     66void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker)
    7067{
    7168        assert(instance);
    72         assert(transfer);
     69        assert(tracker);
    7370
    74         uint32_t pa = (uintptr_t)addr_to_phys(transfer);
     71        uint32_t pa = (uintptr_t)addr_to_phys(tracker->td);
    7572        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    7673
    77         /* empty list */
    78         if (instance->first == NULL) {
    79                 assert(instance->last == NULL);
    80                 instance->first = instance->last = transfer;
    81         } else {
    82                 assert(instance->last);
    83                 instance->last->next_va = transfer;
    8474
    85                 assert(instance->last->next & LINK_POINTER_TERMINATE_FLAG);
    86                 instance->last->next = (pa & LINK_POINTER_ADDRESS_MASK);
    87                 instance->last = transfer;
     75        if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
     76                usb_log_debug2("Adding td(%X:%X) to queue %s first.\n",
     77                        tracker->td->status, tracker->td->device, instance->name);
     78                /* there is nothing scheduled */
     79                instance->last_tracker = tracker;
     80                instance->queue_head->element = pa;
     81                usb_log_debug2("Added td(%X:%X) to queue %s first.\n",
     82                        tracker->td->status, tracker->td->device, instance->name);
     83                return;
    8884        }
     85        usb_log_debug2("Adding td(%X:%X) to queue %s last.%p\n",
     86            tracker->td->status, tracker->td->device, instance->name,
     87            instance->last_tracker);
     88        /* now we can be sure that last_tracker is a valid pointer */
     89        instance->last_tracker->td->next = pa;
     90        instance->last_tracker = tracker;
    8991
    90         assert(instance->queue_head);
     92        usb_log_debug2("Added td(%X:%X) to queue %s last.\n",
     93                tracker->td->status, tracker->td->device, instance->name);
     94
     95        /* check again, may be use atomic compare and swap */
    9196        if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
    92                 instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK);
     97                instance->queue_head->element = pa;
     98                usb_log_debug2("Added td(%X:%X) to queue first2 %s.\n",
     99                        tracker->td->status, tracker->td->device, instance->name);
    93100        }
    94         usb_log_debug("Successfully added transfer to the hc queue %s.\n",
    95           instance->name);
    96         return EOK;
    97101}
    98102/**
  • uspace/drv/uhci-hcd/transfer_list.h

    r25971d2 r79d2987  
    3636
    3737#include "uhci_struct/queue_head.h"
    38 #include "uhci_struct/transfer_descriptor.h"
     38#include "tracker.h"
    3939
    4040typedef struct transfer_list
    4141{
    42         transfer_descriptor_t *first;
    43         transfer_descriptor_t *last;
     42        tracker_t *last_tracker;
     43
    4444        queue_head_t *queue_head;
    4545        uint32_t queue_head_pa;
     
    5858}
    5959
    60 int transfer_list_append(
    61   transfer_list_t *instance, transfer_descriptor_t *transfer);
     60
     61void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker);
    6262
    6363#endif
  • uspace/drv/uhci-hcd/uhci.c

    r25971d2 r79d2987  
    3333 */
    3434#include <errno.h>
     35#include <adt/list.h>
    3536
    3637#include <usb/debug.h>
     
    4243static int uhci_clean_finished(void *arg);
    4344static int uhci_debug_checker(void *arg);
     45static bool allowed_usb_packet(
     46        bool low_speed, usb_transfer_type_t, size_t size);
    4447
    4548int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     
    8487
    8588        const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
    86 
    8789        pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
     90
     91        list_initialize(&instance->tracker_list);
     92        fibril_mutex_initialize(&instance->tracker_list_mutex);
    8893
    8994        instance->cleaner = fibril_create(uhci_clean_finished, instance);
     
    9398        fibril_add_ready(instance->debug_checker);
    9499
    95         /* Start the hc with large(64b) packet FSBR */
     100        /* Start the hc with large(64B) packet FSBR */
    96101        pio_write_16(&instance->registers->usbcmd,
    97102            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
     
    147152}
    148153/*----------------------------------------------------------------------------*/
    149 int uhci_transfer(
    150   uhci_t *instance,
    151   device_t *dev,
    152   usb_target_t target,
    153   usb_transfer_type_t transfer_type,
    154         bool toggle,
    155   usb_packet_id pid,
    156         bool low_speed,
    157   void *buffer, size_t size,
    158   usbhc_iface_transfer_out_callback_t callback_out,
    159   usbhc_iface_transfer_in_callback_t callback_in,
    160   void *arg)
    161 {
    162         // TODO: Add support for isochronous transfers
    163         if (transfer_type == USB_TRANSFER_ISOCHRONOUS) {
    164                 usb_log_warning("ISO transfer not supported.\n");
     154int uhci_schedule(uhci_t *instance, tracker_t *tracker)
     155{
     156        assert(instance);
     157        assert(tracker);
     158        const int low_speed = (tracker->speed == LOW_SPEED);
     159        if (!allowed_usb_packet(
     160            low_speed, tracker->transfer_type, tracker->packet_size)) {
     161                usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n",
     162                          low_speed ? "LOW" : "FULL" , tracker->transfer_type,
     163                    tracker->packet_size);
    165164                return ENOTSUP;
    166165        }
    167 
    168         if (transfer_type == USB_TRANSFER_INTERRUPT
    169           && size >= 64) {
    170                 usb_log_warning("Interrupt transfer too big %zu.\n", size);
    171                 return ENOTSUP;
    172         }
    173 
    174         if (size >= 1024) {
    175                 usb_log_warning("Transfer too big.\n");
    176                 return ENOTSUP;
    177         }
    178         transfer_list_t *list = instance->transfers[low_speed][transfer_type];
    179         if (!list) {
    180                 usb_log_warning("UNSUPPORTED transfer %d-%d.\n", low_speed, transfer_type);
    181                 return ENOTSUP;
    182         }
    183 
    184         transfer_descriptor_t *td = NULL;
    185         callback_t *job = NULL;
    186         int ret = EOK;
    187         assert(dev);
    188 
    189 #define CHECK_RET_TRANS_FREE_JOB_TD(message) \
    190         if (ret != EOK) { \
    191                 usb_log_error(message); \
    192                 if (job) { \
    193                         callback_dispose(job); \
    194                 } \
    195                 if (td) { free32(td); } \
    196                 return ret; \
    197         } else (void) 0
    198 
    199         job = callback_get(dev, buffer, size, callback_in, callback_out, arg);
    200         ret = job ? EOK : ENOMEM;
    201         CHECK_RET_TRANS_FREE_JOB_TD("Failed to allocate callback structure.\n");
    202 
    203         td = transfer_descriptor_get(3, size, false, target, pid, job->new_buffer);
    204         ret = td ? EOK : ENOMEM;
    205         CHECK_RET_TRANS_FREE_JOB_TD("Failed to setup transfer descriptor.\n");
    206 
    207         td->callback = job;
    208 
    209 
    210         usb_log_debug("Appending a new transfer to queue %s.\n", list->name);
    211 
    212         ret = transfer_list_append(list, td);
    213         CHECK_RET_TRANS_FREE_JOB_TD("Failed to append transfer descriptor.\n");
     166        /* TODO: check available bandwith here */
     167
     168        usb_log_debug2("Scheduler(%d) acquiring tracker list mutex.\n",
     169            fibril_get_id());
     170        fibril_mutex_lock(&instance->tracker_list_mutex);
     171        usb_log_debug2("Scheduler(%d) acquired tracker list mutex.\n",
     172            fibril_get_id());
     173
     174        transfer_list_t *list =
     175            instance->transfers[low_speed][tracker->transfer_type];
     176        assert(list);
     177        transfer_list_add_tracker(list, tracker);
     178        list_append(&tracker->link, &instance->tracker_list);
     179
     180        usb_log_debug2("Scheduler(%d) releasing tracker list mutex.\n",
     181            fibril_get_id());
     182        fibril_mutex_unlock(&instance->tracker_list_mutex);
     183        usb_log_debug2("Scheduler(%d) released tracker list mutex.\n",
     184            fibril_get_id());
    214185
    215186        return EOK;
    216187}
    217 /*---------------------------------------------------------------------------*/
     188/*----------------------------------------------------------------------------*/
    218189int uhci_clean_finished(void* arg)
    219190{
     
    223194
    224195        while(1) {
    225                 usb_log_debug("Running cleaning fibril on: %p.\n", instance);
    226                 /* iterate all transfer queues */
    227                 transfer_list_t *current_list = &instance->transfers_interrupt;
    228                 while (current_list) {
    229                         /* Remove inactive transfers from the top of the queue
    230                          * TODO: should I reach queue head or is this enough? */
    231                         volatile transfer_descriptor_t * it =
    232                                 current_list->first;
    233                         usb_log_debug("Running cleaning fibril on queue: %s (%s).\n",
    234                                 current_list->name, it ? "SOMETHING" : "EMPTY");
    235 
    236                         if (it) {
    237                                 usb_log_debug("First in queue: %p (%x) PA:%x.\n",
    238                                         it, it->status, addr_to_phys((void*)it) );
    239                                 usb_log_debug("First to send: %x\n",
    240                                         (current_list->queue_head->element) );
     196                LIST_INITIALIZE(done_trackers);
     197                /* tracker iteration */
     198
     199                usb_log_debug2("Cleaner(%d) acquiring tracker list mutex.\n",
     200                    fibril_get_id());
     201                fibril_mutex_lock(&instance->tracker_list_mutex);
     202                usb_log_debug2("Cleaner(%d) acquired tracker list mutex.\n",
     203                    fibril_get_id());
     204
     205                link_t *current = instance->tracker_list.next;
     206                while (current != &instance->tracker_list)
     207                {
     208
     209                        link_t *next = current->next;
     210                        tracker_t *tracker = list_get_instance(current, tracker_t, link);
     211
     212                        assert(current == &tracker->link);
     213                        assert(tracker);
     214                        assert(tracker->next_step);
     215                        assert(tracker->td);
     216
     217                        if (!transfer_descriptor_is_active(tracker->td)) {
     218                                usb_log_info("Found inactive tracker with status: %x:%x.\n",
     219                                    tracker->td->status, tracker->td->device);
     220                                list_remove(current);
     221                                list_append(current, &done_trackers);
    241222                        }
    242 
    243                         while (current_list->first &&
    244                          !(current_list->first->status & TD_STATUS_ERROR_ACTIVE)) {
    245                                 transfer_descriptor_t *transfer = current_list->first;
    246                                 usb_log_info("Inactive transfer calling callback with status %x.\n",
    247                                   transfer->status);
    248                                 current_list->first = transfer->next_va;
    249                                 transfer_descriptor_dispose(transfer);
    250                         }
    251                         if (!current_list->first)
    252                                 current_list->last = current_list->first;
    253 
    254                         current_list = current_list->next;
     223                        current = next;
     224                }
     225
     226                usb_log_debug2("Cleaner(%d) releasing tracker list mutex.\n",
     227                    fibril_get_id());
     228                fibril_mutex_unlock(&instance->tracker_list_mutex);
     229                usb_log_debug2("Cleaner(%d) released tracker list mutex.\n",
     230                    fibril_get_id());
     231
     232                while (!list_empty(&done_trackers)) {
     233                        tracker_t *tracker = list_get_instance(
     234                          done_trackers.next, tracker_t, link);
     235                        list_remove(&tracker->link);
     236                        tracker->next_step(tracker);
    255237                }
    256238                async_usleep(UHCI_CLEANER_TIMEOUT);
     
    311293        return 0;
    312294}
     295/*----------------------------------------------------------------------------*/
     296bool allowed_usb_packet(
     297        bool low_speed, usb_transfer_type_t transfer, size_t size)
     298{
     299        /* see USB specification chapter 5.5-5.8 for magic numbers used here */
     300        switch(transfer) {
     301                case USB_TRANSFER_ISOCHRONOUS:
     302                        return (!low_speed && size < 1024);
     303                case USB_TRANSFER_INTERRUPT:
     304                        return size <= (low_speed ? 8 : 64);
     305                case USB_TRANSFER_CONTROL: /* device specifies its own max size */
     306                        return (size <= (low_speed ? 8 : 64));
     307                case USB_TRANSFER_BULK: /* device specifies its own max size */
     308                        return (!low_speed && size <= 64);
     309        }
     310        return false;
     311}
    313312/**
    314313 * @}
  • uspace/drv/uhci-hcd/uhci.h

    r25971d2 r79d2987  
    3737
    3838#include <fibril.h>
     39#include <fibril_synch.h>
     40#include <adt/list.h>
    3941
    4042#include <usb/addrkeep.h>
     
    4244
    4345#include "transfer_list.h"
     46#include "tracker.h"
    4447
    4548typedef struct uhci_regs {
     
    6871} regs_t;
    6972
    70 #define TRANSFER_QUEUES 4
    7173#define UHCI_FRAME_LIST_COUNT 1024
    7274#define UHCI_CLEANER_TIMEOUT 10000
    73 #define UHCI_DEBUGER_TIMEOUT 500000
     75#define UHCI_DEBUGER_TIMEOUT 5000000
    7476
    7577typedef struct uhci {
     
    7880
    7981        link_pointer_t *frame_list;
     82
     83        link_t tracker_list;
     84        fibril_mutex_t tracker_list_mutex;
    8085
    8186        transfer_list_t transfers_bulk_full;
     
    108113  void *arg );
    109114
     115int uhci_schedule(uhci_t *instance, tracker_t *tracker);
     116
    110117static inline uhci_t * dev_to_uhci(device_t *dev)
    111118        { return (uhci_t*)dev->driver_data; }
  • uspace/drv/uhci-hcd/uhci_struct/queue_head.h

    r25971d2 r79d2987  
    4343
    4444typedef struct queue_head {
    45         link_pointer_t next_queue;
    46         link_pointer_t element;
     45        volatile link_pointer_t next_queue;
     46        volatile link_pointer_t element;
    4747} __attribute__((packed)) queue_head_t;
    4848
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    r25971d2 r79d2987  
    3232 * @brief UHCI driver
    3333 */
     34#include <errno.h>
    3435#include <usb/debug.h>
    3536
    3637#include "transfer_descriptor.h"
     38#include "utils/malloc32.h"
    3739
    3840void transfer_descriptor_init(transfer_descriptor_t *instance,
    39   int error_count, size_t size, bool isochronous, usb_target_t target,
    40         int pid, void *buffer)
     41    int error_count, size_t size, bool toggle, bool isochronous,
     42    usb_target_t target, int pid, void *buffer)
    4143{
    4244        assert(instance);
    4345
    44         instance->next =
    45           0 | LINK_POINTER_TERMINATE_FLAG;
     46        instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
    4647
    47 
    48         assert(size < 1024);
    4948        instance->status = 0
    5049          | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
    5150          | TD_STATUS_ERROR_ACTIVE;
    5251
     52        assert(size < 1024);
    5353        instance->device = 0
    5454                | (((size - 1) & TD_DEVICE_MAXLEN_MASK) << TD_DEVICE_MAXLEN_POS)
     55                | (toggle ? TD_DEVICE_DATA_TOGGLE_ONE_FLAG : 0)
    5556                | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
    5657                | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
     
    5859
    5960        instance->buffer_ptr = 0;
    60 
    61         instance->next_va = NULL;
    62         instance->callback = NULL;
    6361
    6462        if (size) {
     
    106104                return USB_OUTCOME_CRCERROR;
    107105
    108         assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
    109         | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
     106//      assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
     107//      | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
    110108        return USB_OUTCOME_OK;
    111109}
    112 
    113 void transfer_descriptor_fini(transfer_descriptor_t *instance)
     110/*----------------------------------------------------------------------------*/
     111int transfer_descriptor_status(transfer_descriptor_t *instance)
    114112{
    115113        assert(instance);
    116         callback_run(instance->callback,
    117                 convert_outcome(instance->status),
    118                 ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK
    119         );
     114        if (convert_outcome(instance->status))
     115                return EINVAL; //TODO: use sane error value here
     116        return EOK;
    120117}
    121118/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r25971d2 r79d2987  
    3838#include <usb/usb.h>
    3939
    40 #include "utils/malloc32.h"
    41 #include "callback.h"
    4240#include "link_pointer.h"
    4341
     
    8684        volatile uint32_t buffer_ptr;
    8785
    88         /* there is 16 bytes of data available here
    89          * those are used to store callback pointer
    90          * and next pointer. Thus, there is some free space
    91          * on 32bits systems.
     86        /* there is 16 bytes of data available here, according to UHCI
     87         * Design guide, according to linux kernel the hardware does not care
     88         * we don't use it anyway
    9289         */
    93         struct transfer_descriptor *next_va;
    94         callback_t *callback;
    9590} __attribute__((packed)) transfer_descriptor_t;
    9691
    9792
    9893void transfer_descriptor_init(transfer_descriptor_t *instance,
    99   int error_count, size_t size, bool isochronous, usb_target_t target,
    100         int pid, void *buffer);
     94    int error_count, size_t size, bool toggle, bool isochronous,
     95    usb_target_t target, int pid, void *buffer);
    10196
    102 static inline transfer_descriptor_t * transfer_descriptor_get(
    103   int error_count, size_t size, bool isochronous, usb_target_t target,
    104   int pid, void *buffer)
    105 {
    106         transfer_descriptor_t * instance =
    107           malloc32(sizeof(transfer_descriptor_t));
     97int transfer_descriptor_status(transfer_descriptor_t *instance);
    10898
    109         if (instance)
    110                 transfer_descriptor_init(
    111                   instance, error_count, size, isochronous, target, pid, buffer);
    112         return instance;
    113 }
    114 
    115 void transfer_descriptor_fini(transfer_descriptor_t *instance);
    116 
    117 static inline void transfer_descriptor_dispose(transfer_descriptor_t *instance)
     99static inline bool transfer_descriptor_is_active(
     100    transfer_descriptor_t *instance)
    118101{
    119102        assert(instance);
    120         transfer_descriptor_fini(instance);
    121         free32(instance);
    122 }
    123 
    124 static inline void transfer_descriptor_append(
    125   transfer_descriptor_t *instance, transfer_descriptor_t *item)
    126 {
    127         assert(instance);
    128         instance->next_va = item;
    129         instance->next = (uintptr_t)addr_to_phys( item ) & LINK_POINTER_ADDRESS_MASK;
     103        return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0;
    130104}
    131105#endif
  • uspace/drv/uhci-rhd/main.c

    r25971d2 r79d2987  
    102102int main(int argc, char *argv[])
    103103{
    104         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     104        usb_log_enable(USB_LOG_LEVEL_ERROR, NAME);
    105105        return driver_main(&uhci_rh_driver);
    106106}
  • uspace/drv/usbhid/hid.h

    r25971d2 r79d2987  
    6969        device_t *device;
    7070        usb_hid_configuration_t *conf;
    71         usb_address_t address;
    7271        usb_hid_report_parser_t *parser;
    7372
    7473        usb_device_connection_t wire;
     74        usb_endpoint_pipe_t ctrl_pipe;
    7575        usb_endpoint_pipe_t poll_pipe;
    7676} usb_hid_dev_kbd_t;
  • uspace/drv/usbhid/main.c

    r25971d2 r79d2987  
    4747#include <usb/classes/hid.h>
    4848#include <usb/classes/hidparser.h>
    49 #include <usb/devreq.h>
     49#include <usb/request.h>
    5050#include <usb/descriptor.h>
    5151#include <io/console.h>
     
    262262}
    263263
    264 # if 0
    265264/*
    266265 * Kbd functions
     
    281280               
    282281                // get the descriptor from the device
    283                 int rc = usb_drv_req_get_descriptor(kbd_dev->device->parent_phone,
    284                     kbd_dev->address, USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
    285                     0, i, kbd_dev->conf->interfaces[i].report_desc, length,
     282                int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe,
     283                    USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT,
     284                    i, 0,
     285                    kbd_dev->conf->interfaces[i].report_desc, length,
    286286                    &actual_size);
    287287
     
    303303        usb_standard_configuration_descriptor_t config_desc;
    304304       
    305         int rc = usb_drv_req_get_bare_configuration_descriptor(
    306             kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
     305        int rc;
     306        rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
     307            0, &config_desc);
    307308       
    308309        if (rc != EOK) {
     
    318319        size_t transferred = 0;
    319320        // get full configuration descriptor
    320         rc = usb_drv_req_get_full_configuration_descriptor(
    321             kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
     321        rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
     322            0, descriptors,
    322323            config_desc.total_length, &transferred);
    323324       
     
    363364        return EOK;
    364365}
    365 #endif
     366
    366367static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
    367368{
     369        int rc;
     370
    368371        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1,
    369372            sizeof(usb_hid_dev_kbd_t));
     
    376379        kbd_dev->device = dev;
    377380
    378         // get phone to my HC and save it as my parent's phone
    379         // TODO: maybe not a good idea if DDF will use parent_phone
    380         int rc = kbd_dev->device->parent_phone = usb_drv_hc_connect_auto(dev, 0);
    381         if (rc < 0) {
    382                 printf("Problem setting phone to HC.\n");
    383                 goto error_leave;
    384         }
    385 
    386         rc = kbd_dev->address = usb_drv_get_my_address(dev->parent_phone, dev);
    387         if (rc < 0) {
    388                 printf("Problem getting address of the device.\n");
    389                 goto error_leave;
    390         }
    391 
    392         // doesn't matter now that we have no address
    393 //      if (kbd_dev->address < 0) {
    394 //              fprintf(stderr, NAME ": No device address!\n");
    395 //              free(kbd_dev);
    396 //              return NULL;
    397 //      }
    398 
    399         /*
    400          * will need all descriptors:
    401          * 1) choose one configuration from configuration descriptors
    402          *    (set it to the device)
    403          * 2) set endpoints from endpoint descriptors
    404          */
    405 
    406 
    407         // TODO: get descriptors, parse descriptors and save endpoints
    408         //usbkbd_process_descriptors(kbd_dev);
    409         usb_drv_req_set_configuration(
    410           kbd_dev->device->parent_phone, kbd_dev->address, 1);
    411 
    412 
    413 
    414381        /*
    415382         * Initialize the backing connection to the host controller.
     
    425392         * Initialize device pipes.
    426393         */
     394        rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe,
     395            &kbd_dev->wire);
     396        if (rc != EOK) {
     397                printf("Failed to initialize default control pipe: %s.\n",
     398                    str_error(rc));
     399                goto error_leave;
     400        }
     401
    427402        rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire,
    428403            GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, 8, USB_DIRECTION_IN);
     
    433408        }
    434409
     410        /*
     411         * will need all descriptors:
     412         * 1) choose one configuration from configuration descriptors
     413         *    (set it to the device)
     414         * 2) set endpoints from endpoint descriptors
     415         */
     416
     417        // TODO: get descriptors, parse descriptors and save endpoints
     418        usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe);
     419        //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1);
     420        usbkbd_process_descriptors(kbd_dev);
     421        usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe);
    435422
    436423        return kbd_dev;
  • uspace/lib/c/generic/async.c

    r25971d2 r79d2987  
    15671567}
    15681568
     1569/** Start IPC_M_DATA_READ using the async framework.
     1570 *
     1571 * @param phoneid Phone that will be used to contact the receiving side.
     1572 * @param dst Address of the beginning of the destination buffer.
     1573 * @param size Size of the destination buffer (in bytes).
     1574 * @param dataptr Storage of call data (arg 2 holds actual data size).
     1575 * @return Hash of the sent message or 0 on error.
     1576 */
     1577aid_t async_data_read(int phoneid, void *dst, size_t size, ipc_call_t *dataptr)
     1578{
     1579        return async_send_2(phoneid, IPC_M_DATA_READ, (sysarg_t) dst,
     1580            (sysarg_t) size, dataptr);
     1581}
     1582
    15691583/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15701584 *
  • uspace/lib/c/include/async.h

    r25971d2 r79d2987  
    340340            (arg4), (answer))
    341341
     342extern aid_t async_data_read(int, void *, size_t, ipc_call_t *);
    342343extern int async_data_read_start(int, void *, size_t);
    343344extern bool async_data_read_receive(ipc_callid_t *, size_t *);
  • uspace/lib/drv/generic/remote_usbhc.c

    r25971d2 r79d2987  
    4242
    4343static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
    44 static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4544static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4645static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6463        remote_usbhc_get_address,
    6564
    66         remote_usbhc_get_buffer,
    67 
    6865        remote_usbhc_reserve_default_address,
    6966        remote_usbhc_release_default_address,
     
    9895typedef struct {
    9996        ipc_callid_t caller;
     97        ipc_callid_t data_caller;
    10098        void *buffer;
    10199        void *setup_packet;
     
    127125
    128126        trans->caller = caller;
     127        trans->data_caller = 0;
    129128        trans->buffer = NULL;
    130129        trans->setup_packet = NULL;
     
    155154}
    156155
    157 void remote_usbhc_get_buffer(device_t *device, void *iface,
    158     ipc_callid_t callid, ipc_call_t *call)
    159 {
    160         sysarg_t buffer_hash = DEV_IPC_GET_ARG1(*call);
    161         async_transaction_t * trans = (async_transaction_t *)buffer_hash;
    162         if (trans == NULL) {
    163                 async_answer_0(callid, ENOENT);
    164                 return;
    165         }
    166         if (trans->buffer == NULL) {
    167                 async_answer_0(callid, EINVAL);
    168                 async_transaction_destroy(trans);
    169                 return;
    170         }
    171 
    172         ipc_callid_t cid;
    173         size_t accepted_size;
    174         if (!async_data_read_receive(&cid, &accepted_size)) {
    175                 async_answer_0(callid, EINVAL);
    176                 async_transaction_destroy(trans);
    177                 return;
    178         }
    179 
    180         if (accepted_size > trans->size) {
    181                 accepted_size = trans->size;
    182         }
    183         async_data_read_finalize(cid, trans->buffer, accepted_size);
    184 
    185         async_answer_1(callid, EOK, accepted_size);
    186 
    187         async_transaction_destroy(trans);
    188 }
    189 
    190156void remote_usbhc_reserve_default_address(device_t *device, void *iface,
    191157    ipc_callid_t callid, ipc_call_t *call)
     
    290256        if (outcome != USB_OUTCOME_OK) {
    291257                async_answer_0(trans->caller, outcome);
     258                if (trans->data_caller) {
     259                        async_answer_0(trans->data_caller, EINTR);
     260                }
    292261                async_transaction_destroy(trans);
    293262                return;
     
    295264
    296265        trans->size = actual_size;
    297         async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
     266
     267        if (trans->data_caller) {
     268                async_data_read_finalize(trans->data_caller,
     269                    trans->buffer, actual_size);
     270        }
     271
     272        async_answer_0(trans->caller, USB_OUTCOME_OK);
     273
     274        async_transaction_destroy(trans);
    298275}
    299276
     
    376353        };
    377354
     355        ipc_callid_t data_callid;
     356        if (!async_data_read_receive(&data_callid, &len)) {
     357                async_answer_0(callid, EPARTY);
     358                return;
     359        }
     360
    378361        async_transaction_t *trans = async_transaction_create(callid);
    379362        if (trans == NULL) {
     
    381364                return;
    382365        }
     366        trans->data_caller = data_callid;
    383367        trans->buffer = malloc(len);
    384368        trans->size = len;
     
    630614        }
    631615
     616        ipc_callid_t data_callid;
     617        if (!async_data_read_receive(&data_callid, &data_len)) {
     618                async_answer_0(callid, EPARTY);
     619                free(setup_packet);
     620                return;
     621        }
     622
    632623        async_transaction_t *trans = async_transaction_create(callid);
    633624        if (trans == NULL) {
     
    636627                return;
    637628        }
     629        trans->data_caller = data_callid;
    638630        trans->setup_packet = setup_packet;
    639631        trans->size = data_len;
  • uspace/lib/drv/include/usbhc_iface.h

    r25971d2 r79d2987  
    6666 *   - argument #2 is target endpoint
    6767 *   - argument #3 is buffer size
     68 * - this call is immediately followed by IPC data read (async version)
    6869 * - the call is not answered until the device returns some data (or until
    6970 *   error occurs)
    70  * - if the call is answered with EOK, first argument of the answer is buffer
    71  *   hash that could be used to retrieve the actual data
    7271 *
    7372 * Some special methods (NO-DATA transactions) do not send any data. These
    7473 * might behave as both OUT or IN transactions because communication parts
    7574 * where actual buffers are exchanged are omitted.
    76  *
    77  * The mentioned data retrieval can be done any time after receiving EOK
    78  * answer to IN method.
    79  * This retrieval is done using the IPC_M_USBHC_GET_BUFFER where
    80  * the first argument is buffer hash from call answer.
    81  * This call must be immediately followed by data read-in and after the
    82  * data are transferred, the initial call (IPC_M_USBHC_GET_BUFFER)
    83  * is answered. Each buffer can be retrieved only once.
    84  *
     75 **
    8576 * For all these methods, wrap functions exists. Important rule: functions
    8677 * for IN transactions have (as parameters) buffers where retrieved data
     
    10495        IPC_M_USBHC_GET_ADDRESS,
    10596
    106         /** Asks for data buffer.
    107          * See explanation at usb_iface_funcs_t.
    108          * This function does not have counter part in functional interface
    109          * as it is handled by the remote part itself.
    110          */
    111         IPC_M_USBHC_GET_BUFFER,
    112 
    11397
    11498        /** Reserve usage of default address.
  • uspace/lib/usb/src/usbdrv.c

    r25971d2 r79d2987  
    4949        /** Storage for actual number of bytes transferred. */
    5050        size_t *size_transferred;
    51         /** Initial call replay data. */
     51        /** Initial call reply data. */
    5252        ipc_call_t reply;
    5353        /** Initial call identifier. */
    5454        aid_t request;
     55        /** Reply data for data read call. */
     56        ipc_call_t read_reply;
     57        /** Data read call identifier. */
     58        aid_t read_request;
    5559} transfer_info_t;
    5660
     
    140144
    141145        if (rc != EOK) {
    142                 printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));
    143146                return rc;
    144147        }
     
    250253        }
    251254
     255        transfer->read_request = 0;
    252256        transfer->size_transferred = NULL;
    253257        transfer->buffer = NULL;
     
    315319        }
    316320
     321        transfer->read_request = 0;
    317322        transfer->size_transferred = actual_size;
    318323        transfer->buffer = buffer;
     
    327332            &transfer->reply);
    328333
     334        if (buffer != NULL) {
     335                transfer->read_request = async_data_read(phone, buffer, size,
     336                    &transfer->read_reply);
     337        }
     338
    329339        *handle = (usb_handle_t) transfer;
    330340
     
    332342}
    333343
    334 /** Read buffer from HCD.
    335  *
    336  * @param phone Opened phone to HCD.
    337  * @param hash Buffer hash (obtained after completing IN transaction).
    338  * @param buffer Buffer where to store data data.
    339  * @param size Buffer size.
    340  * @param actual_size Storage where actual number of bytes transferred will
    341  *      be stored.
    342  * @return Error status.
    343  */
    344 static int read_buffer_in(int phone, sysarg_t hash,
    345     void *buffer, size_t size, size_t *actual_size)
    346 {
    347         ipc_call_t answer_data;
    348         sysarg_t answer_rc;
    349         aid_t req;
    350         int rc;
    351 
    352         req = async_send_2(phone,
    353             DEV_IFACE_ID(USBHC_DEV_IFACE),
    354             IPC_M_USBHC_GET_BUFFER,
    355             hash,
    356             &answer_data);
    357 
    358         rc = async_data_read_start(phone, buffer, size);
    359         if (rc != EOK) {
    360                 async_wait_for(req, NULL);
    361                 return EINVAL;
    362         }
    363 
    364         async_wait_for(req, &answer_rc);
    365         rc = (int)answer_rc;
    366 
    367         if (rc != EOK) {
    368                 return rc;
    369         }
    370 
    371         *actual_size = IPC_GET_ARG1(answer_data);
    372 
    373         return EOK;
    374 }
    375344
    376345/** Blocks caller until given USB transaction is finished.
     
    395364
    396365        sysarg_t answer_rc;
    397         async_wait_for(transfer->request, &answer_rc);
    398 
    399         if (answer_rc != EOK) {
    400                 rc = (int) answer_rc;
    401                 goto leave;
    402         }
    403366
    404367        /*
     
    406369         */
    407370        if ((transfer->buffer != NULL) && (transfer->size > 0)) {
    408                 /*
    409                  * The buffer hash identifies the data on the server
    410                  * side.
    411                  * We will use it when actually reading-in the data.
    412                  */
    413                 sysarg_t buffer_hash = IPC_GET_ARG1(transfer->reply);
    414                 if (buffer_hash == 0) {
    415                         rc = ENOENT;
     371                async_wait_for(transfer->read_request, &answer_rc);
     372
     373                if (answer_rc != EOK) {
     374                        rc = (int) answer_rc;
    416375                        goto leave;
    417376                }
    418377
    419                 size_t actual_size;
    420                 rc = read_buffer_in(transfer->phone, buffer_hash,
    421                     transfer->buffer, transfer->size, &actual_size);
    422 
    423                 if (rc != EOK) {
    424                         goto leave;
     378                if (transfer->size_transferred != NULL) {
     379                        *(transfer->size_transferred)
     380                            = IPC_GET_ARG2(transfer->read_reply);
    425381                }
    426 
    427                 if (transfer->size_transferred) {
    428                         *(transfer->size_transferred) = actual_size;
    429                 }
     382        }
     383
     384        async_wait_for(transfer->request, &answer_rc);
     385
     386        if (answer_rc != EOK) {
     387                rc = (int) answer_rc;
     388                goto leave;
    430389        }
    431390
     
    515474        }
    516475
     476        transfer->read_request = 0;
    517477        transfer->size_transferred = NULL;
    518478        transfer->buffer = NULL;
     
    620580        }
    621581
     582        transfer->read_request = async_data_read(phone, buffer, buffer_size,
     583            &transfer->read_reply);
     584
    622585        *handle = (usb_handle_t) transfer;
    623586
Note: See TracChangeset for help on using the changeset viewer.