Changes in / [79d2987:25971d2] in mainline


Ignore:
Location:
uspace
Files:
2 added
2 deleted
18 edited

Legend:

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

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

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

    r79d2987 r25971d2  
    106106    usbhc_iface_transfer_out_callback_t callback, void *arg)
    107107{
    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;
     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);
    117113}
    118114/*----------------------------------------------------------------------------*/
     
    121117    usbhc_iface_transfer_in_callback_t callback, void *arg)
    122118{
    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 /*----------------------------------------------------------------------------*/
    134 static 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 /*----------------------------------------------------------------------------*/
    149 static 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;
     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);
    162124}
    163125/*----------------------------------------------------------------------------*/
     
    166128    usbhc_iface_transfer_out_callback_t callback, void *arg)
    167129{
    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;
     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);
    175135}
    176136/*----------------------------------------------------------------------------*/
     
    179139    usbhc_iface_transfer_out_callback_t callback, void *arg)
    180140{
    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;
     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);
    187146}
    188147/*----------------------------------------------------------------------------*/
     
    190149    usbhc_iface_transfer_in_callback_t callback, void *arg)
    191150{
    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;
     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);
    198156}
    199157/*----------------------------------------------------------------------------*/
     
    202160    usbhc_iface_transfer_out_callback_t callback, void *arg)
    203161{
    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;
     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);
    211167}
    212168/*----------------------------------------------------------------------------*/
     
    215171    usbhc_iface_transfer_in_callback_t callback, void *arg)
    216172{
    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;
     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);
    223178}
    224179/*----------------------------------------------------------------------------*/
     
    226181    usbhc_iface_transfer_out_callback_t callback, void *arg)
    227182{
    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 /*----------------------------------------------------------------------------*/
     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
    236191usbhc_iface_t uhci_iface = {
    237192        .tell_address = get_address,
     
    245200        .interrupt_out = interrupt_out,
    246201        .interrupt_in = interrupt_in,
    247 
    248         .control_read = control_read,
    249         .control_write = control_write,
    250202
    251203        .control_write_setup = control_write_setup,
  • uspace/drv/uhci-hcd/transfer_list.c

    r79d2987 r25971d2  
    4141{
    4242        assert(instance);
     43        instance->first = NULL;
     44        instance->last = NULL;
    4345        instance->next = NULL;
    4446        instance->name = name;
     
    6466}
    6567/*----------------------------------------------------------------------------*/
    66 void transfer_list_add_tracker(transfer_list_t *instance, tracker_t *tracker)
     68int transfer_list_append(
     69  transfer_list_t *instance, transfer_descriptor_t *transfer)
    6770{
    6871        assert(instance);
    69         assert(tracker);
     72        assert(transfer);
    7073
    71         uint32_t pa = (uintptr_t)addr_to_phys(tracker->td);
     74        uint32_t pa = (uintptr_t)addr_to_phys(transfer);
    7275        assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);
    7376
     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;
    7484
     85                assert(instance->last->next & LINK_POINTER_TERMINATE_FLAG);
     86                instance->last->next = (pa & LINK_POINTER_ADDRESS_MASK);
     87                instance->last = transfer;
     88        }
     89
     90        assert(instance->queue_head);
    7591        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;
     92                instance->queue_head->element = (pa & LINK_POINTER_ADDRESS_MASK);
    8493        }
    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;
    91 
    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 */
    96         if (instance->queue_head->element & LINK_POINTER_TERMINATE_FLAG) {
    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);
    100         }
     94        usb_log_debug("Successfully added transfer to the hc queue %s.\n",
     95          instance->name);
     96        return EOK;
    10197}
    10298/**
  • uspace/drv/uhci-hcd/transfer_list.h

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

    r79d2987 r25971d2  
    3333 */
    3434#include <errno.h>
    35 #include <adt/list.h>
    3635
    3736#include <usb/debug.h>
     
    4342static int uhci_clean_finished(void *arg);
    4443static int uhci_debug_checker(void *arg);
    45 static bool allowed_usb_packet(
    46         bool low_speed, usb_transfer_type_t, size_t size);
    4744
    4845int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     
    8784
    8885        const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
     86
    8987        pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
    90 
    91         list_initialize(&instance->tracker_list);
    92         fibril_mutex_initialize(&instance->tracker_list_mutex);
    9388
    9489        instance->cleaner = fibril_create(uhci_clean_finished, instance);
     
    9893        fibril_add_ready(instance->debug_checker);
    9994
    100         /* Start the hc with large(64B) packet FSBR */
     95        /* Start the hc with large(64b) packet FSBR */
    10196        pio_write_16(&instance->registers->usbcmd,
    10297            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
     
    152147}
    153148/*----------------------------------------------------------------------------*/
    154 int 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);
     149int 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");
    164165                return ENOTSUP;
    165166        }
    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());
     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");
    185214
    186215        return EOK;
    187216}
    188 /*----------------------------------------------------------------------------*/
     217/*---------------------------------------------------------------------------*/
    189218int uhci_clean_finished(void* arg)
    190219{
     
    194223
    195224        while(1) {
    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);
     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) );
    222241                        }
    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);
     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;
    237255                }
    238256                async_usleep(UHCI_CLEANER_TIMEOUT);
     
    293311        return 0;
    294312}
    295 /*----------------------------------------------------------------------------*/
    296 bool 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 }
    312313/**
    313314 * @}
  • uspace/drv/uhci-hcd/uhci.h

    r79d2987 r25971d2  
    3737
    3838#include <fibril.h>
    39 #include <fibril_synch.h>
    40 #include <adt/list.h>
    4139
    4240#include <usb/addrkeep.h>
     
    4442
    4543#include "transfer_list.h"
    46 #include "tracker.h"
    4744
    4845typedef struct uhci_regs {
     
    7168} regs_t;
    7269
     70#define TRANSFER_QUEUES 4
    7371#define UHCI_FRAME_LIST_COUNT 1024
    7472#define UHCI_CLEANER_TIMEOUT 10000
    75 #define UHCI_DEBUGER_TIMEOUT 5000000
     73#define UHCI_DEBUGER_TIMEOUT 500000
    7674
    7775typedef struct uhci {
     
    8078
    8179        link_pointer_t *frame_list;
    82 
    83         link_t tracker_list;
    84         fibril_mutex_t tracker_list_mutex;
    8580
    8681        transfer_list_t transfers_bulk_full;
     
    113108  void *arg );
    114109
    115 int uhci_schedule(uhci_t *instance, tracker_t *tracker);
    116 
    117110static inline uhci_t * dev_to_uhci(device_t *dev)
    118111        { return (uhci_t*)dev->driver_data; }
  • uspace/drv/uhci-hcd/uhci_struct/queue_head.h

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

    r79d2987 r25971d2  
    3232 * @brief UHCI driver
    3333 */
    34 #include <errno.h>
    3534#include <usb/debug.h>
    3635
    3736#include "transfer_descriptor.h"
    38 #include "utils/malloc32.h"
    3937
    4038void transfer_descriptor_init(transfer_descriptor_t *instance,
    41     int error_count, size_t size, bool toggle, bool isochronous,
    42     usb_target_t target, int pid, void *buffer)
     39  int error_count, size_t size, bool isochronous, usb_target_t target,
     40        int pid, void *buffer)
    4341{
    4442        assert(instance);
    4543
    46         instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;
     44        instance->next =
     45          0 | LINK_POINTER_TERMINATE_FLAG;
    4746
     47
     48        assert(size < 1024);
    4849        instance->status = 0
    4950          | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
    5051          | TD_STATUS_ERROR_ACTIVE;
    5152
    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)
    5655                | ((target.address & TD_DEVICE_ADDRESS_MASK) << TD_DEVICE_ADDRESS_POS)
    5756                | ((target.endpoint & TD_DEVICE_ENDPOINT_MASK) << TD_DEVICE_ENDPOINT_POS)
     
    5958
    6059        instance->buffer_ptr = 0;
     60
     61        instance->next_va = NULL;
     62        instance->callback = NULL;
    6163
    6264        if (size) {
     
    104106                return USB_OUTCOME_CRCERROR;
    105107
    106 //      assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
    107 //      | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
     108        assert((((status >> TD_STATUS_ERROR_POS) & TD_STATUS_ERROR_MASK)
     109        | TD_STATUS_ERROR_RESERVED) == TD_STATUS_ERROR_RESERVED);
    108110        return USB_OUTCOME_OK;
    109111}
    110 /*----------------------------------------------------------------------------*/
    111 int transfer_descriptor_status(transfer_descriptor_t *instance)
     112
     113void transfer_descriptor_fini(transfer_descriptor_t *instance)
    112114{
    113115        assert(instance);
    114         if (convert_outcome(instance->status))
    115                 return EINVAL; //TODO: use sane error value here
    116         return EOK;
     116        callback_run(instance->callback,
     117                convert_outcome(instance->status),
     118                ((instance->status >> TD_STATUS_ACTLEN_POS) + 1) & TD_STATUS_ACTLEN_MASK
     119        );
    117120}
    118121/**
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r79d2987 r25971d2  
    3838#include <usb/usb.h>
    3939
     40#include "utils/malloc32.h"
     41#include "callback.h"
    4042#include "link_pointer.h"
    4143
     
    8486        volatile uint32_t buffer_ptr;
    8587
    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
     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.
    8992         */
     93        struct transfer_descriptor *next_va;
     94        callback_t *callback;
    9095} __attribute__((packed)) transfer_descriptor_t;
    9196
    9297
    9398void transfer_descriptor_init(transfer_descriptor_t *instance,
    94     int error_count, size_t size, bool toggle, bool isochronous,
    95     usb_target_t target, int pid, void *buffer);
     99  int error_count, size_t size, bool isochronous, usb_target_t target,
     100        int pid, void *buffer);
    96101
    97 int transfer_descriptor_status(transfer_descriptor_t *instance);
     102static 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));
    98108
    99 static inline bool transfer_descriptor_is_active(
    100     transfer_descriptor_t *instance)
     109        if (instance)
     110                transfer_descriptor_init(
     111                  instance, error_count, size, isochronous, target, pid, buffer);
     112        return instance;
     113}
     114
     115void transfer_descriptor_fini(transfer_descriptor_t *instance);
     116
     117static inline void transfer_descriptor_dispose(transfer_descriptor_t *instance)
    101118{
    102119        assert(instance);
    103         return (instance->status & TD_STATUS_ERROR_ACTIVE) != 0;
     120        transfer_descriptor_fini(instance);
     121        free32(instance);
     122}
     123
     124static 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;
    104130}
    105131#endif
  • uspace/drv/uhci-rhd/main.c

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

    r79d2987 r25971d2  
    6969        device_t *device;
    7070        usb_hid_configuration_t *conf;
     71        usb_address_t address;
    7172        usb_hid_report_parser_t *parser;
    7273
    7374        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

    r79d2987 r25971d2  
    4747#include <usb/classes/hid.h>
    4848#include <usb/classes/hidparser.h>
    49 #include <usb/request.h>
     49#include <usb/devreq.h>
    5050#include <usb/descriptor.h>
    5151#include <io/console.h>
     
    262262}
    263263
     264# if 0
    264265/*
    265266 * Kbd functions
     
    280281               
    281282                // get the descriptor from the device
    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,
     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,
    286286                    &actual_size);
    287287
     
    303303        usb_standard_configuration_descriptor_t config_desc;
    304304       
    305         int rc;
    306         rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe,
    307             0, &config_desc);
     305        int rc = usb_drv_req_get_bare_configuration_descriptor(
     306            kbd_dev->device->parent_phone, kbd_dev->address, 0, &config_desc);
    308307       
    309308        if (rc != EOK) {
     
    319318        size_t transferred = 0;
    320319        // get full configuration descriptor
    321         rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe,
    322             0, descriptors,
     320        rc = usb_drv_req_get_full_configuration_descriptor(
     321            kbd_dev->device->parent_phone, kbd_dev->address, 0, descriptors,
    323322            config_desc.total_length, &transferred);
    324323       
     
    364363        return EOK;
    365364}
    366 
     365#endif
    367366static usb_hid_dev_kbd_t *usbkbd_init_device(device_t *dev)
    368367{
    369         int rc;
    370 
    371368        usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1,
    372369            sizeof(usb_hid_dev_kbd_t));
     
    379376        kbd_dev->device = dev;
    380377
     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
    381414        /*
    382415         * Initialize the backing connection to the host controller.
     
    392425         * Initialize device pipes.
    393426         */
    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 
    402427        rc = usb_endpoint_pipe_initialize(&kbd_dev->poll_pipe, &kbd_dev->wire,
    403428            GUESSED_POLL_ENDPOINT, USB_TRANSFER_INTERRUPT, 8, USB_DIRECTION_IN);
     
    408433        }
    409434
    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);
    422435
    423436        return kbd_dev;
  • uspace/lib/c/generic/async.c

    r79d2987 r25971d2  
    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  */
    1577 aid_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 
    15831569/** Wrapper for IPC_M_DATA_READ calls using the async framework.
    15841570 *
  • uspace/lib/c/include/async.h

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

    r79d2987 r25971d2  
    4242
    4343static void remote_usbhc_get_address(device_t *, void *, ipc_callid_t, ipc_call_t *);
     44static void remote_usbhc_get_buffer(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4445static void remote_usbhc_interrupt_out(device_t *, void *, ipc_callid_t, ipc_call_t *);
    4546static void remote_usbhc_interrupt_in(device_t *, void *, ipc_callid_t, ipc_call_t *);
     
    6364        remote_usbhc_get_address,
    6465
     66        remote_usbhc_get_buffer,
     67
    6568        remote_usbhc_reserve_default_address,
    6669        remote_usbhc_release_default_address,
     
    9598typedef struct {
    9699        ipc_callid_t caller;
    97         ipc_callid_t data_caller;
    98100        void *buffer;
    99101        void *setup_packet;
     
    125127
    126128        trans->caller = caller;
    127         trans->data_caller = 0;
    128129        trans->buffer = NULL;
    129130        trans->setup_packet = NULL;
     
    154155}
    155156
     157void 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
    156190void remote_usbhc_reserve_default_address(device_t *device, void *iface,
    157191    ipc_callid_t callid, ipc_call_t *call)
     
    256290        if (outcome != USB_OUTCOME_OK) {
    257291                async_answer_0(trans->caller, outcome);
    258                 if (trans->data_caller) {
    259                         async_answer_0(trans->data_caller, EINTR);
    260                 }
    261292                async_transaction_destroy(trans);
    262293                return;
     
    264295
    265296        trans->size = actual_size;
    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);
     297        async_answer_1(trans->caller, USB_OUTCOME_OK, (sysarg_t)trans);
    275298}
    276299
     
    353376        };
    354377
    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 
    361378        async_transaction_t *trans = async_transaction_create(callid);
    362379        if (trans == NULL) {
     
    364381                return;
    365382        }
    366         trans->data_caller = data_callid;
    367383        trans->buffer = malloc(len);
    368384        trans->size = len;
     
    614630        }
    615631
    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 
    623632        async_transaction_t *trans = async_transaction_create(callid);
    624633        if (trans == NULL) {
     
    627636                return;
    628637        }
    629         trans->data_caller = data_callid;
    630638        trans->setup_packet = setup_packet;
    631639        trans->size = data_len;
  • uspace/lib/drv/include/usbhc_iface.h

    r79d2987 r25971d2  
    6666 *   - argument #2 is target endpoint
    6767 *   - argument #3 is buffer size
    68  * - this call is immediately followed by IPC data read (async version)
    6968 * - the call is not answered until the device returns some data (or until
    7069 *   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
    7172 *
    7273 * Some special methods (NO-DATA transactions) do not send any data. These
    7374 * might behave as both OUT or IN transactions because communication parts
    7475 * where actual buffers are exchanged are omitted.
    75  **
     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 *
    7685 * For all these methods, wrap functions exists. Important rule: functions
    7786 * for IN transactions have (as parameters) buffers where retrieved data
     
    95104        IPC_M_USBHC_GET_ADDRESS,
    96105
     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
    97113
    98114        /** Reserve usage of default address.
  • uspace/lib/usb/src/usbdrv.c

    r79d2987 r25971d2  
    4949        /** Storage for actual number of bytes transferred. */
    5050        size_t *size_transferred;
    51         /** Initial call reply data. */
     51        /** Initial call replay 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;
    5955} transfer_info_t;
    6056
     
    144140
    145141        if (rc != EOK) {
     142                printf("usb_drv_get_my_address over %d failed: %s\n", phone, str_error(rc));
    146143                return rc;
    147144        }
     
    253250        }
    254251
    255         transfer->read_request = 0;
    256252        transfer->size_transferred = NULL;
    257253        transfer->buffer = NULL;
     
    319315        }
    320316
    321         transfer->read_request = 0;
    322317        transfer->size_transferred = actual_size;
    323318        transfer->buffer = buffer;
     
    332327            &transfer->reply);
    333328
    334         if (buffer != NULL) {
    335                 transfer->read_request = async_data_read(phone, buffer, size,
    336                     &transfer->read_reply);
    337         }
    338 
    339329        *handle = (usb_handle_t) transfer;
    340330
     
    342332}
    343333
     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 */
     344static 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}
    344375
    345376/** Blocks caller until given USB transaction is finished.
     
    364395
    365396        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        }
    366403
    367404        /*
     
    369406         */
    370407        if ((transfer->buffer != NULL) && (transfer->size > 0)) {
    371                 async_wait_for(transfer->read_request, &answer_rc);
    372 
    373                 if (answer_rc != EOK) {
    374                         rc = (int) answer_rc;
     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;
    375416                        goto leave;
    376417                }
    377418
    378                 if (transfer->size_transferred != NULL) {
    379                         *(transfer->size_transferred)
    380                             = IPC_GET_ARG2(transfer->read_reply);
     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;
    381425                }
    382         }
    383 
    384         async_wait_for(transfer->request, &answer_rc);
    385 
    386         if (answer_rc != EOK) {
    387                 rc = (int) answer_rc;
    388                 goto leave;
     426
     427                if (transfer->size_transferred) {
     428                        *(transfer->size_transferred) = actual_size;
     429                }
    389430        }
    390431
     
    474515        }
    475516
    476         transfer->read_request = 0;
    477517        transfer->size_transferred = NULL;
    478518        transfer->buffer = NULL;
     
    580620        }
    581621
    582         transfer->read_request = async_data_read(phone, buffer, buffer_size,
    583             &transfer->read_reply);
    584 
    585622        *handle = (usb_handle_t) transfer;
    586623
Note: See TracChangeset for help on using the changeset viewer.