Changes in / [81c508c:299d53e] in mainline


Ignore:
Location:
uspace/drv
Files:
2 added
1 deleted
21 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/pciintel/pci.c

    r81c508c r299d53e  
    320320        /* Get the value of the BAR. */
    321321        val = pci_conf_read_32(fun, addr);
     322
     323#define IO_MASK  (~0x3)
     324#define MEM_MASK (~0xf)
    322325       
    323326        io = (bool) (val & 1);
    324327        if (io) {
    325328                addrw64 = false;
     329                mask = IO_MASK;
    326330        } else {
     331                mask = MEM_MASK;
    327332                switch ((val >> 1) & 3) {
    328333                case 0:
     
    340345        /* Get the address mask. */
    341346        pci_conf_write_32(fun, addr, 0xffffffff);
    342         mask = pci_conf_read_32(fun, addr);
     347        mask &= pci_conf_read_32(fun, addr);
    343348       
    344349        /* Restore the original value. */
     
    659664size_t pci_bar_mask_to_size(uint32_t mask)
    660665{
    661         return ((mask & 0xfffffff0) ^ 0xffffffff) + 1;
     666        size_t size = mask & ~(mask - 1);
     667        return size;
    662668}
    663669
  • uspace/drv/uhci-hcd/Makefile

    r81c508c r299d53e  
    3939        uhci.c \
    4040        uhci_struct/transfer_descriptor.c \
     41        utils/device_keeper.c \
    4142        pci.c \
    4243        batch.c
  • uspace/drv/uhci-hcd/batch.c

    r81c508c r299d53e  
    3333 */
    3434#include <errno.h>
     35#include <str_error.h>
    3536
    3637#include <usb/debug.h>
     
    5354batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    5455    usb_transfer_type_t transfer_type, size_t max_packet_size,
    55     dev_speed_t speed, char *buffer, size_t size,
     56    usb_speed_t speed, char *buffer, size_t size,
    5657    char* setup_buffer, size_t setup_size,
    5758    usbhc_iface_transfer_in_callback_t func_in,
     
    139140{
    140141        assert(instance);
    141         usb_log_debug("Checking(%p) %d packet for completion.\n",
     142        usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",
    142143            instance, instance->packets);
    143144        instance->transfered_size = 0;
     
    151152                        if (i > 0)
    152153                                instance->transfered_size -= instance->setup_size;
     154                        usb_log_debug("Batch(%p) found error TD(%d):%x.\n",
     155                          instance, i, instance->tds[i].status);
    153156                        return true;
    154157                }
     
    156159                    transfer_descriptor_actual_size(&instance->tds[i]);
    157160        }
    158         /* This is just an ugly trick to support the old API */
    159161        instance->transfered_size -= instance->setup_size;
    160162        return true;
     
    168170        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    169171
     172        const bool low_speed = instance->speed == USB_SPEED_LOW;
    170173        int toggle = 0;
    171174        /* setup stage */
    172175        transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    173             instance->setup_size, toggle, false, instance->target,
    174             USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
     176            instance->setup_size, toggle, false, low_speed,
     177            instance->target, USB_PID_SETUP, instance->setup_buffer,
     178            &instance->tds[1]);
    175179
    176180        /* data stage */
     
    182186
    183187                transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    184                     instance->max_packet_size, toggle++, false, instance->target,
    185                     USB_PID_OUT, data, &instance->tds[i + 1]);
     188                    instance->max_packet_size, toggle++, false, low_speed,
     189                    instance->target, USB_PID_OUT, data, &instance->tds[i + 1]);
    186190        }
    187191
     
    189193        i = instance->packets - 1;
    190194        transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    191             0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
     195            0, 1, false, low_speed, instance->target, USB_PID_IN, NULL, NULL);
    192196
    193197        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     198        usb_log_debug("Control write last TD status: %x.\n",
     199                instance->tds[i].status);
    194200
    195201        instance->next_step = batch_call_out_and_dispose;
     
    201207        assert(instance);
    202208
     209        const bool low_speed = instance->speed == USB_SPEED_LOW;
    203210        int toggle = 0;
    204211        /* setup stage */
    205212        transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    206             instance->setup_size, toggle, false, instance->target,
     213            instance->setup_size, toggle, false, low_speed, instance->target,
    207214            USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]);
    208215
     
    215222
    216223                transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    217                     instance->max_packet_size, toggle, false, instance->target,
    218                     USB_PID_IN, data, &instance->tds[i + 1]);
     224                    instance->max_packet_size, toggle, false, low_speed,
     225                                instance->target, USB_PID_IN, data, &instance->tds[i + 1]);
    219226        }
    220227
     
    222229        i = instance->packets - 1;
    223230        transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    224             0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
     231            0, 1, false, low_speed, instance->target, USB_PID_OUT, NULL, NULL);
    225232
    226233        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     234        usb_log_debug("Control read last TD status: %x.\n",
     235                instance->tds[i].status);
    227236
    228237        instance->next_step = batch_call_in_and_dispose;
     
    234243        assert(instance);
    235244
     245        const bool low_speed = instance->speed == USB_SPEED_LOW;
    236246        int toggle = 1;
    237247        size_t i = 0;
     
    244254
    245255                transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    246                     instance->max_packet_size, toggle, false, instance->target,
    247                     USB_PID_IN, data, next);
     256                    instance->max_packet_size, toggle, false, low_speed,
     257                    instance->target, USB_PID_IN, data, next);
    248258        }
    249259
     
    260270        memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size);
    261271
     272        const bool low_speed = instance->speed == USB_SPEED_LOW;
    262273        int toggle = 1;
    263274        size_t i = 0;
     
    270281
    271282                transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    272                     instance->max_packet_size, toggle++, false, instance->target,
    273                     USB_PID_OUT, data, next);
     283                    instance->max_packet_size, toggle++, false, low_speed,
     284                    instance->target, USB_PID_OUT, data, next);
    274285        }
    275286
     
    288299
    289300        int err = instance->error;
    290         usb_log_info("Callback IN(%d): %d, %zu.\n", instance->transfer_type,
    291             err, instance->transfered_size);
     301        usb_log_info("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n",
     302            instance, instance->transfer_type, str_error(err), err,
     303            instance->transfered_size);
    292304
    293305        instance->callback_in(instance->fun,
     
    302314
    303315        int err = instance->error;
    304         usb_log_info("Callback OUT(%d): %d.\n", instance->transfer_type, err);
     316        usb_log_info("Batch(%p) callback OUT(type:%d): %s(%d).\n",
     317            instance, instance->transfer_type, str_error(err), err);
    305318        instance->callback_out(instance->fun,
    306319            err, instance->arg);
     
    311324        assert(instance);
    312325        batch_call_in(instance);
    313         usb_log_debug("Disposing batch: %p.\n", instance);
     326        usb_log_debug("Batch(%p) disposing.\n", instance);
    314327        free32(instance->tds);
    315328        free32(instance->qh);
     
    323336        assert(instance);
    324337        batch_call_out(instance);
    325         usb_log_debug("Disposing batch: %p.\n", instance);
     338        usb_log_debug("Batch(%p) disposing.\n", instance);
    326339        free32(instance->tds);
    327340        free32(instance->qh);
     
    338351        return uhci_schedule(hc, instance);
    339352}
    340 /*----------------------------------------------------------------------------*/
    341 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */
    342 void batch_control_setup_old(batch_t *instance)
    343 {
    344         assert(instance);
    345         instance->packets = 1;
    346 
    347         /* setup stage */
    348         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    349             instance->setup_size, 0, false, instance->target,
    350             USB_PID_SETUP, instance->setup_buffer, NULL);
    351 
    352         instance->next_step = batch_call_out_and_dispose;
    353         batch_schedule(instance);
    354 }
    355 /*----------------------------------------------------------------------------*/
    356 void batch_control_write_data_old(batch_t *instance)
    357 {
    358         assert(instance);
    359         instance->packets -= 2;
    360         batch_interrupt_out(instance);
    361 }
    362 /*----------------------------------------------------------------------------*/
    363 void batch_control_read_data_old(batch_t *instance)
    364 {
    365         assert(instance);
    366         instance->packets -= 2;
    367         batch_interrupt_in(instance);
    368 }
    369 /*----------------------------------------------------------------------------*/
    370 void batch_control_write_status_old(batch_t *instance)
    371 {
    372         assert(instance);
    373         instance->packets = 1;
    374         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    375             0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
    376         instance->next_step = batch_call_in_and_dispose;
    377         batch_schedule(instance);
    378 }
    379 /*----------------------------------------------------------------------------*/
    380 void batch_control_read_status_old(batch_t *instance)
    381 {
    382         assert(instance);
    383         instance->packets = 1;
    384         transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT,
    385             0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
    386         instance->next_step = batch_call_out_and_dispose;
    387         batch_schedule(instance);
    388 }
    389353/**
    390354 * @}
  • uspace/drv/uhci-hcd/batch.h

    r81c508c r299d53e  
    4343#include "uhci_struct/queue_head.h"
    4444
    45 typedef enum {
    46         LOW_SPEED,
    47         FULL_SPEED,
    48 } dev_speed_t;
    49 
    5045typedef struct batch
    5146{
    5247        link_t link;
    53         dev_speed_t speed;
     48        usb_speed_t speed;
    5449        usb_target_t target;
    5550        usb_transfer_type_t transfer_type;
     
    7671batch_t * batch_get(ddf_fun_t *fun, usb_target_t target,
    7772    usb_transfer_type_t transfer_type, size_t max_packet_size,
    78     dev_speed_t speed, char *buffer, size_t size,
     73    usb_speed_t speed, char *buffer, size_t size,
    7974                char *setup_buffer, size_t setup_size,
    8075    usbhc_iface_transfer_in_callback_t func_in,
  • uspace/drv/uhci-hcd/iface.c

    r81c508c r299d53e  
    4141#include "iface.h"
    4242#include "uhci.h"
     43#include "utils/device_keeper.h"
    4344
    4445/*----------------------------------------------------------------------------*/
     
    4849        uhci_t *hc = fun_to_uhci(fun);
    4950        assert(hc);
    50         usb_address_keeping_reserve_default(&hc->address_manager);
     51        usb_log_debug("Default address request with speed %d.\n", speed);
     52        device_keeper_reserve_default(&hc->device_manager, speed);
    5153        return EOK;
    5254}
     
    5759        uhci_t *hc = fun_to_uhci(fun);
    5860        assert(hc);
    59         usb_address_keeping_release_default(&hc->address_manager);
     61        usb_log_debug("Default address release.\n");
     62        device_keeper_release_default(&hc->device_manager);
    6063        return EOK;
    6164}
     
    6770        uhci_t *hc = fun_to_uhci(fun);
    6871        assert(hc);
    69         *address = usb_address_keeping_request(&hc->address_manager);
     72        assert(address);
     73
     74        usb_log_debug("Address request with speed %d.\n", speed);
     75        *address = device_keeper_request(&hc->device_manager, speed);
     76        usb_log_debug("Address request with result: %d.\n", *address);
    7077        if (*address <= 0)
    7178          return *address;
     
    7986        uhci_t *hc = fun_to_uhci(fun);
    8087        assert(hc);
    81         usb_address_keeping_devman_bind(&hc->address_manager, address, handle);
     88        usb_log_debug("Address bind %d-%d.\n", address, handle);
     89        device_keeper_bind(&hc->device_manager, address, handle);
    8290        return EOK;
    8391}
     
    8896        uhci_t *hc = fun_to_uhci(fun);
    8997        assert(hc);
    90         usb_address_keeping_release_default(&hc->address_manager);
     98        usb_log_debug("Address release %d.\n", address);
     99        device_keeper_release(&hc->device_manager, address);
    91100        return EOK;
    92101}
    93102/*----------------------------------------------------------------------------*/
    94103static int interrupt_out(ddf_fun_t *fun, usb_target_t target,
    95     size_t max_packet_size,
    96     void *data, size_t size,
     104    size_t max_packet_size, void *data, size_t size,
    97105    usbhc_iface_transfer_out_callback_t callback, void *arg)
    98106{
    99         dev_speed_t speed = FULL_SPEED;
     107        assert(fun);
     108        uhci_t *hc = fun_to_uhci(fun);
     109        assert(hc);
     110        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     111
     112        usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n",
     113            target.address, target.endpoint, size, max_packet_size);
    100114
    101115        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
     
    108122/*----------------------------------------------------------------------------*/
    109123static int interrupt_in(ddf_fun_t *fun, usb_target_t target,
    110     size_t max_packet_size,
    111     void *data, size_t size,
     124    size_t max_packet_size, void *data, size_t size,
    112125    usbhc_iface_transfer_in_callback_t callback, void *arg)
    113126{
    114         dev_speed_t speed = FULL_SPEED;
     127        assert(fun);
     128        uhci_t *hc = fun_to_uhci(fun);
     129        assert(hc);
     130        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     131        usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n",
     132            target.address, target.endpoint, size, max_packet_size);
    115133
    116134        batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,
     
    127145    usbhc_iface_transfer_out_callback_t callback, void *arg)
    128146{
    129         dev_speed_t speed = FULL_SPEED;
     147        assert(fun);
     148        uhci_t *hc = fun_to_uhci(fun);
     149        assert(hc);
     150        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     151        usb_log_debug("Control WRITE %d:%d %zu(%zu).\n",
     152            target.address, target.endpoint, size, max_packet_size);
    130153
    131154        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
     
    143166    usbhc_iface_transfer_in_callback_t callback, void *arg)
    144167{
    145         dev_speed_t speed = FULL_SPEED;
    146 
     168        assert(fun);
     169        uhci_t *hc = fun_to_uhci(fun);
     170        assert(hc);
     171        usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address);
     172
     173        usb_log_debug("Control READ %d:%d %zu(%zu).\n",
     174            target.address, target.endpoint, size, max_packet_size);
    147175        batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL,
    148176            max_packet_size, speed, data, size, setup_data, setup_size, callback,
  • uspace/drv/uhci-hcd/main.c

    r81c508c r299d53e  
    8282        usb_log_info("uhci_add_device() called\n");
    8383
    84 
    85         uintptr_t io_reg_base;
    86         size_t io_reg_size;
    87         int irq;
     84        uintptr_t io_reg_base = 0;
     85        size_t io_reg_size = 0;
     86        int irq = 0;
    8887
    8988        int ret =
     
    9594            io_reg_base, io_reg_size, irq);
    9695
    97         ret = pci_enable_interrupts(device);
    98         CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
     96//      ret = pci_enable_interrupts(device);
     97//      CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
    9998
    10099        uhci_t *uhci_hc = malloc(sizeof(uhci_t));
     
    114113         */
    115114        device->driver_data = uhci_hc;
    116 
    117115        ret = register_interrupt_handler(device, irq, irq_handler,
    118116            &uhci_hc->interrupt_code);
     
    149147{
    150148        sleep(3);
    151         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     149        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    152150
    153151        return ddf_driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/pci.c

    r81c508c r299d53e  
    3838#include <devman.h>
    3939#include <device/hw_res.h>
     40
     41#include <usb/debug.h>
    4042
    4143#include "pci.h"
     
    8385                                irq = res->res.interrupt.irq;
    8486                                irq_found = true;
     87                                usb_log_debug("Found interrupt: %d.\n", irq);
    8588                                break;
    8689                        case IO_RANGE:
    87                                 io_address = (uintptr_t)
    88                                     res->res.io_range.address;
     90                                io_address = res->res.io_range.address;
    8991                                io_size = res->res.io_range.size;
     92                                usb_log_debug("Found io: %llx %zu %zu.\n",
     93                                    res->res.io_range.address, res->res.io_range.size, io_size);
    9094                                io_found = true;
    9195                                break;
     
    105109        }
    106110
    107         if (io_reg_address != NULL) {
    108                 *io_reg_address = io_address;
    109         }
    110         if (io_reg_size != NULL) {
    111                 *io_reg_size = io_size;
    112         }
    113         if (irq_no != NULL) {
    114                 *irq_no = irq;
    115         }
     111        *io_reg_address = io_address;
     112        *io_reg_size = io_size;
     113        *irq_no = irq;
    116114
    117115        rc = EOK;
     
    127125            IPC_FLAG_BLOCKING);
    128126        bool enabled = hw_res_enable_interrupt(parent_phone);
     127        async_hangup(parent_phone);
    129128        return enabled ? EOK : EIO;
    130129}
  • uspace/drv/uhci-hcd/root_hub.c

    r81c508c r299d53e  
    3535#include <errno.h>
    3636#include <stdio.h>
     37#include <ops/hw_res.h>
     38
    3739#include <usb_iface.h>
    3840#include <usb/debug.h>
     
    4143#include "uhci.h"
    4244
     45/*----------------------------------------------------------------------------*/
    4346static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun,
    4447    devman_handle_t *handle)
     
    5154        return EOK;
    5255}
    53 
     56/*----------------------------------------------------------------------------*/
    5457static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle,
    5558    usb_address_t *address)
     
    6164        assert(hc);
    6265
    63         usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
     66        usb_address_t addr = device_keeper_find(&hc->device_manager,
    6467            handle);
    6568        if (addr < 0) {
     
    7376        return EOK;
    7477}
    75 
     78/*----------------------------------------------------------------------------*/
    7679usb_iface_t usb_iface_root_hub_fun_impl = {
    7780        .get_hc_handle = usb_iface_get_hc_handle_rh_impl,
    7881        .get_address = usb_iface_get_address_rh_impl
    7982};
     83/*----------------------------------------------------------------------------*/
     84static hw_resource_list_t *get_resource_list(ddf_fun_t *dev)
     85{
     86        assert(dev);
     87        ddf_fun_t *hc_ddf_instance = dev->driver_data;
     88        assert(hc_ddf_instance);
     89        uhci_t *hc = hc_ddf_instance->driver_data;
     90        assert(hc);
    8091
     92        //TODO: fix memory leak
     93        hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t));
     94        assert(resource_list);
     95        resource_list->count = 1;
     96        resource_list->resources = malloc(sizeof(hw_resource_t));
     97        assert(resource_list->resources);
     98        resource_list->resources[0].type = IO_RANGE;
     99        resource_list->resources[0].res.io_range.address =
     100            ((uintptr_t)hc->registers) + 0x10; // see UHCI design guide
     101        resource_list->resources[0].res.io_range.size = 4;
     102        resource_list->resources[0].res.io_range.endianness = LITTLE_ENDIAN;
     103
     104        return resource_list;
     105}
     106/*----------------------------------------------------------------------------*/
     107static hw_res_ops_t hw_res_iface = {
     108        .get_resource_list = get_resource_list,
     109        .enable_interrupt = NULL
     110};
     111/*----------------------------------------------------------------------------*/
    81112static ddf_dev_ops_t root_hub_ops = {
    82         .interfaces[USB_DEV_IFACE] = &usb_iface_root_hub_fun_impl
     113        .interfaces[USB_DEV_IFACE] = &usb_iface_root_hub_fun_impl,
     114        .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface
    83115};
    84 
    85116/*----------------------------------------------------------------------------*/
    86117int setup_root_hub(ddf_fun_t **fun, ddf_dev_t *hc)
  • uspace/drv/uhci-hcd/transfer_list.c

    r81c508c r299d53e  
    7070        assert(instance);
    7171        assert(batch);
     72        usb_log_debug("Adding batch(%p) to queue %s.\n", batch, instance->name);
    7273
    7374        uint32_t pa = (uintptr_t)addr_to_phys(batch->qh);
     
    123124}
    124125/*----------------------------------------------------------------------------*/
    125 void transfer_list_check(transfer_list_t *instance)
     126void transfer_list_remove_finished(transfer_list_t *instance)
    126127{
    127128        assert(instance);
     129
     130        LIST_INITIALIZE(done);
     131
    128132        fibril_mutex_lock(&instance->guard);
    129133        link_t *current = instance->batch_list.next;
     
    134138                if (batch_is_complete(batch)) {
    135139                        transfer_list_remove_batch(instance, batch);
    136                         batch->next_step(batch);
     140                        list_append(current, &done);
    137141                }
    138142                current = next;
    139143        }
    140144        fibril_mutex_unlock(&instance->guard);
     145
     146        while (!list_empty(&done)) {
     147                link_t *item = done.next;
     148                list_remove(item);
     149                batch_t *batch = list_get_instance(item, batch_t, link);
     150                batch->next_step(batch);
     151        }
    141152}
    142153/**
  • uspace/drv/uhci-hcd/transfer_list.h

    r81c508c r299d53e  
    6060        queue_head_dispose(instance->queue_head);
    6161}
    62 void transfer_list_check(transfer_list_t *instance);
     62void transfer_list_remove_finished(transfer_list_t *instance);
    6363
    6464void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch);
  • uspace/drv/uhci-hcd/uhci.c

    r81c508c r299d53e  
    4848        {
    4949                .cmd = CMD_PIO_READ_16,
    50                 .addr = (void*)0xc022,
     50                .addr = NULL, /* patched for every instance */
    5151                .dstarg = 1
    5252        },
    5353        {
    5454                .cmd = CMD_PIO_WRITE_16,
    55                 .addr = (void*)0xc022,
     55                .addr = NULL, /* pathed for every instance */
    5656                .value = 0x1f
    5757        },
     
    6868        assert(hc);
    6969
    70         usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
     70        usb_address_t addr = device_keeper_find(&hc->device_manager,
    7171            handle);
    7272        if (addr < 0) {
     
    8080        return EOK;
    8181}
    82 
    83 
     82/*----------------------------------------------------------------------------*/
    8483static usb_iface_t hc_usb_iface = {
    8584        .get_hc_handle = usb_iface_get_hc_handle_hc_impl,
     
    8988static ddf_dev_ops_t uhci_ops = {
    9089        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    91         .interfaces[USBHC_DEV_IFACE] = &uhci_iface
     90        .interfaces[USBHC_DEV_IFACE] = &uhci_iface,
    9291};
    9392
     
    141140
    142141        instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
    143 //      fibril_add_ready(instance->cleaner);
     142        fibril_add_ready(instance->cleaner);
    144143
    145144        instance->debug_checker = fibril_create(uhci_debug_checker, instance);
     
    151150void uhci_init_hw(uhci_t *instance)
    152151{
     152        /* reset everything, who knows what touched it before us */
     153        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET);
     154        async_usleep(10000); /* 10ms according to USB spec */
     155        pio_write_16(&instance->registers->usbcmd, 0);
     156
     157        /* reset hc, all states and counters */
     158        pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);
     159        while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)
     160                { async_usleep(10); }
    153161
    154162        /* set framelist pointer */
     
    203211
    204212        /* init address keeper(libusb) */
    205         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    206         usb_log_debug("Initialized address manager.\n");
     213        device_keeper_init(&instance->device_manager);
     214        usb_log_debug("Initialized device manager.\n");
    207215
    208216        return EOK;
     
    255263        assert(instance);
    256264        assert(batch);
    257         const int low_speed = (batch->speed == LOW_SPEED);
     265        const int low_speed = (batch->speed == USB_SPEED_LOW);
    258266        if (!allowed_usb_packet(
    259267            low_speed, batch->transfer_type, batch->max_packet_size)) {
     
    276284{
    277285        assert(instance);
    278         if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
    279                 return;
    280         usb_log_debug("UHCI interrupt: %X.\n", status);
    281         transfer_list_check(&instance->transfers_interrupt);
    282         transfer_list_check(&instance->transfers_control_slow);
    283         transfer_list_check(&instance->transfers_control_full);
    284         transfer_list_check(&instance->transfers_bulk_full);
     286//      if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
     287//              return;
     288//      usb_log_debug2("UHCI interrupt: %X.\n", status);
     289        transfer_list_remove_finished(&instance->transfers_interrupt);
     290        transfer_list_remove_finished(&instance->transfers_control_slow);
     291        transfer_list_remove_finished(&instance->transfers_control_full);
     292        transfer_list_remove_finished(&instance->transfers_bulk_full);
    285293}
    286294/*----------------------------------------------------------------------------*/
     
    291299        assert(instance);
    292300
    293         while(1) {
     301        while (1) {
    294302                uint16_t status = pio_read_16(&instance->registers->usbsts);
     303                if (status != 0)
     304                        usb_log_debug2("UHCI status: %x.\n", status);
     305                status |= 1;
    295306                uhci_interrupt(instance, status);
    296                 async_usleep(UHCI_CLEANER_TIMEOUT);
     307                pio_write_16(&instance->registers->usbsts, 0x1f);
     308                async_usleep(UHCI_CLEANER_TIMEOUT * 5);
    297309        }
    298310        return EOK;
     
    307319                const uint16_t sts = pio_read_16(&instance->registers->usbsts);
    308320                const uint16_t intr = pio_read_16(&instance->registers->usbintr);
    309                 usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
    310                     cmd, sts, intr);
    311 
    312                 uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
     321                if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) {
     322                        usb_log_debug2("Command: %X Status: %X Intr: %x\n",
     323                            cmd, sts, intr);
     324                }
     325
     326                uintptr_t frame_list =
     327                    pio_read_32(&instance->registers->flbaseadd) & ~0xfff;
    313328                if (frame_list != addr_to_phys(instance->frame_list)) {
    314329                        usb_log_debug("Framelist address: %p vs. %p.\n",
  • uspace/drv/uhci-hcd/uhci.h

    r81c508c r299d53e  
    4141#include <ddi.h>
    4242
    43 #include <usb/addrkeep.h>
    4443#include <usbhc_iface.h>
    4544
     45#include "batch.h"
    4646#include "transfer_list.h"
    47 #include "batch.h"
     47#include "utils/device_keeper.h"
    4848
    4949typedef struct uhci_regs {
     
    8282
    8383typedef struct uhci {
    84         usb_address_keeping_t address_manager;
     84        device_keeper_t device_manager;
     85
    8586        volatile regs_t *registers;
    8687
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c

    r81c508c r299d53e  
    3939
    4040void transfer_descriptor_init(transfer_descriptor_t *instance,
    41     int error_count, size_t size, bool toggle, bool isochronous,
     41    int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,
    4242    usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next)
    4343{
     
    5050        instance->status = 0
    5151          | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS)
     52                | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)
    5253          | TD_STATUS_ERROR_ACTIVE;
    5354
     
    6970                instance->next, instance->status, instance->device,
    7071          instance->buffer_ptr, buffer);
    71 #if 0
    72         if (size) {
    73                 unsigned char * buff = buffer;
    74                 uhci_print_verbose("TD Buffer dump(%p-%dB): ", buffer, size);
    75                 unsigned i = 0;
    76                 /* TODO: Verbose? */
    77                 for (; i < size; ++i) {
    78                         printf((i & 1) ? "%x " : "%x", buff[i]);
    79                 }
    80                 printf("\n");
    81         }
    82 #endif
    8372}
    8473/*----------------------------------------------------------------------------*/
     
    8877
    8978        if ((instance->status & TD_STATUS_ERROR_STALLED) != 0)
    90                 return EIO;
     79                return ESTALL;
    9180
    9281        if ((instance->status & TD_STATUS_ERROR_CRC) != 0)
    93                 return EAGAIN;
     82                return EBADCHECKSUM;
    9483
    9584        if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0)
  • uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h

    r81c508c r299d53e  
    9292
    9393void transfer_descriptor_init(transfer_descriptor_t *instance,
    94     int error_count, size_t size, bool toggle, bool isochronous,
     94    int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,
    9595    usb_target_t target, int pid, void *buffer, transfer_descriptor_t * next);
    9696
  • uspace/drv/uhci-rhd/main.c

    r81c508c r299d53e  
    3333 */
    3434#include <ddf/driver.h>
     35#include <devman.h>
     36#include <device/hw_res.h>
    3537#include <usb_iface.h>
    3638#include <usb/ddfiface.h>
     
    4345
    4446#define NAME "uhci-rhd"
     47static int hc_get_my_registers(ddf_dev_t *dev,
     48    uintptr_t *io_reg_address, size_t *io_reg_size);
    4549
    4650static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
     
    8084        }
    8185
    82         /* TODO: get register values from hc */
    83         int ret = uhci_root_hub_init(rh, (void*)0xc030, 4, device);
     86        uintptr_t io_regs = 0;
     87        size_t io_size = 0;
     88
     89        int ret = hc_get_my_registers(device, &io_regs, &io_size);
     90        assert(ret == EOK);
     91
     92        /* TODO: verify values from hc */
     93        usb_log_info("I/O regs at 0x%X (size %zu).\n", io_regs, io_size);
     94        ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device);
    8495        if (ret != EOK) {
    8596                usb_log_error("Failed(%d) to initialize driver instance.\n", ret);
     
    102113        .driver_ops = &uhci_rh_driver_ops
    103114};
    104 
     115/*----------------------------------------------------------------------------*/
    105116int main(int argc, char *argv[])
    106117{
     
    108119        return ddf_driver_main(&uhci_rh_driver);
    109120}
     121/*----------------------------------------------------------------------------*/
     122int hc_get_my_registers(ddf_dev_t *dev,
     123    uintptr_t *io_reg_address, size_t *io_reg_size)
     124{
     125        assert(dev != NULL);
     126
     127        int parent_phone = devman_parent_device_connect(dev->handle,
     128            IPC_FLAG_BLOCKING);
     129        if (parent_phone < 0) {
     130                return parent_phone;
     131        }
     132
     133        int rc;
     134
     135        hw_resource_list_t hw_resources;
     136        rc = hw_res_get_resource_list(parent_phone, &hw_resources);
     137        if (rc != EOK) {
     138                goto leave;
     139        }
     140
     141        uintptr_t io_address = 0;
     142        size_t io_size = 0;
     143        bool io_found = false;
     144
     145        size_t i;
     146        for (i = 0; i < hw_resources.count; i++) {
     147                hw_resource_t *res = &hw_resources.resources[i];
     148                switch (res->type) {
     149                        case IO_RANGE:
     150                                io_address = (uintptr_t)
     151                                    res->res.io_range.address;
     152                                io_size = res->res.io_range.size;
     153                                io_found = true;
     154                                break;
     155                        default:
     156                                break;
     157                }
     158        }
     159
     160        if (!io_found) {
     161                rc = ENOENT;
     162                goto leave;
     163        }
     164
     165        if (io_reg_address != NULL) {
     166                *io_reg_address = io_address;
     167        }
     168        if (io_reg_size != NULL) {
     169                *io_reg_size = io_size;
     170        }
     171        rc = EOK;
     172leave:
     173        async_hangup(parent_phone);
     174
     175        return rc;
     176}
    110177/**
    111178 * @}
  • uspace/drv/uhci-rhd/port.c

    r81c508c r299d53e  
    3434#include <errno.h>
    3535#include <str_error.h>
     36#include <fibril_synch.h>
    3637
    3738#include <usb/usb.h>    /* usb_address_t */
     
    4546#include "port_status.h"
    4647
    47 static int uhci_port_new_device(uhci_port_t *port);
     48static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
    4849static int uhci_port_remove_device(uhci_port_t *port);
    4950static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
    5051static int uhci_port_check(void *port);
     52static int new_device_enable_port(int portno, void *arg);
    5153
    5254int uhci_port_init(
    5355  uhci_port_t *port, port_status_t *address, unsigned number,
    54   unsigned usec, ddf_dev_t *rh, int parent_phone)
     56  unsigned usec, ddf_dev_t *rh)
    5557{
    5658        assert(port);
     
    9092        uhci_port_t *port_instance = port;
    9193        assert(port_instance);
     94        port_status_write(port_instance->address, 0);
     95
     96        uint64_t count = 0;
    9297
    9398        while (1) {
     99                async_usleep(port_instance->wait_period_usec);
     100
    94101                /* read register value */
    95102                port_status_t port_status =
     
    97104
    98105                /* debug print */
    99                 usb_log_debug("Port %d status at %p: 0x%04x.\n",
    100                   port_instance->number, port_instance->address, port_status);
    101                 print_port_status(port_status);
    102 
    103                 if (port_status & STATUS_CONNECTED_CHANGED) {
     106                static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
     107                fibril_mutex_lock(&dbg_mtx);
     108                usb_log_debug("Port %d status at %p: 0x%04x. === %llu\n",
     109                  port_instance->number, port_instance->address, port_status, count++);
     110//              print_port_status(port_status);
     111                fibril_mutex_unlock(&dbg_mtx);
     112
     113                if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
     114                        usb_log_debug("Change detected on port %d: %x.\n",
     115                            port_instance->number, port_status);
     116
     117
    104118                        int rc = usb_hc_connection_open(
    105119                            &port_instance->hc_connection);
    106120                        if (rc != EOK) {
    107121                                usb_log_error("Failed to connect to HC.");
    108                                 goto next;
    109                         }
    110 
    111                         if (port_status & STATUS_CONNECTED) {
     122                                continue;
     123                        }
     124
     125                        /* remove any old device */
     126                        if (port_instance->attached_device) {
     127                                usb_log_debug("Removing device on port %d.\n",
     128                                    port_instance->number);
     129                                uhci_port_remove_device(port_instance);
     130                        }
     131
     132                        if ((port_status & STATUS_CONNECTED) != 0) {
    112133                                /* new device */
    113                                 uhci_port_new_device(port_instance);
     134                                uhci_port_new_device(port_instance, port_status);
    114135                        } else {
    115                                 uhci_port_remove_device(port_instance);
     136                                /* ack changes by writing one to WC bits */
     137                                port_status_write(port_instance->address, port_status);
     138                                usb_log_debug("Change status ack on port %d.\n",
     139                                                port_instance->number);
    116140                        }
    117141
     
    120144                        if (rc != EOK) {
    121145                                usb_log_error("Failed to disconnect from HC.");
    122                                 goto next;
    123146                        }
    124147                }
    125         next:
    126                 async_usleep(port_instance->wait_period_usec);
    127148        }
    128149        return EOK;
     
    147168        async_usleep(100000);
    148169
    149         /* Enable the port. */
    150         uhci_port_set_enabled(port, true);
    151170
    152171        /* The hub maintains the reset signal to that port for 10 ms
     
    169188        }
    170189
    171         return EOK;
    172 }
    173 
    174 /*----------------------------------------------------------------------------*/
    175 static int uhci_port_new_device(uhci_port_t *port)
     190        /* Enable the port. */
     191        uhci_port_set_enabled(port, true);
     192
     193        return EOK;
     194}
     195
     196/*----------------------------------------------------------------------------*/
     197static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
    176198{
    177199        assert(port);
     
    182204        usb_address_t dev_addr;
    183205        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
    184             USB_SPEED_FULL,
     206            ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
    185207            new_device_enable_port, port->number, port,
    186208            &dev_addr, &port->attached_device, NULL, NULL, NULL);
     209
    187210        if (rc != EOK) {
    188211                usb_log_error("Failed adding new device on port %u: %s.\n",
  • uspace/drv/uhci-rhd/port.h

    r81c508c r299d53e  
    5555int uhci_port_init(
    5656  uhci_port_t *port, port_status_t *address, unsigned number,
    57   unsigned usec, ddf_dev_t *rh, int parent_phone);
     57  unsigned usec, ddf_dev_t *rh);
    5858
    5959void uhci_port_fini(uhci_port_t *port);
  • uspace/drv/uhci-rhd/port_status.c

    r81c508c r299d53e  
    4141struct flag_name
    4242{
    43         unsigned flag;
     43        uint16_t flag;
    4444        const char *name;
    4545};
     
    6565        for (;i < sizeof(flags)/sizeof(struct flag_name); ++i) {
    6666                usb_log_debug2("\t%s status: %s.\n", flags[i].name,
    67                   value & flags[i].flag ? "YES" : "NO");
     67                  ((value & flags[i].flag) != 0) ? "YES" : "NO");
    6868        }
    6969}
  • uspace/drv/uhci-rhd/port_status.h

    r81c508c r299d53e  
    4141typedef uint16_t port_status_t;
    4242
    43 enum {
    44         STATUS_CONNECTED         = 1 << 0,
    45         STATUS_CONNECTED_CHANGED = 1 << 1,
    46         STATUS_ENABLED           = 1 << 2,
    47         STATUS_ENABLED_CHANGED   = 1 << 3,
    48         STATUS_LINE_D_PLUS       = 1 << 4,
    49         STATUS_LINE_D_MINUS      = 1 << 5,
    50         STATUS_RESUME            = 1 << 6,
    51         STATUS_ALWAYS_ONE        = 1 << 7,
     43#define STATUS_CONNECTED         (1 << 0)
     44#define STATUS_CONNECTED_CHANGED (1 << 1)
     45#define STATUS_ENABLED           (1 << 2)
     46#define STATUS_ENABLED_CHANGED   (1 << 3)
     47#define STATUS_LINE_D_PLUS       (1 << 4)
     48#define STATUS_LINE_D_MINUS      (1 << 5)
     49#define STATUS_RESUME            (1 << 6)
     50#define STATUS_ALWAYS_ONE        (1 << 7)
    5251
    53         STATUS_LOW_SPEED = 1 <<  8,
    54         STATUS_IN_RESET  = 1 <<  9,
    55         STATUS_SUSPEND   = 1 << 12,
    56 };
     52#define STATUS_LOW_SPEED (1 <<  8)
     53#define STATUS_IN_RESET  (1 <<  9)
     54#define STATUS_SUSPEND   (1 << 12)
    5755
    5856static inline port_status_t port_status_read(port_status_t * address)
  • uspace/drv/uhci-rhd/root_hub.c

    r81c508c r299d53e  
    4040#include "root_hub.h"
    4141
    42 
    4342int uhci_root_hub_init(
    4443  uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh)
     
    6766        unsigned i = 0;
    6867        for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) {
    69                 /* connect to the parent device (HC) */
    70                 int parent_phone = devman_device_connect(instance->hc_handle, 0);
    71                 //usb_drv_hc_connect(rh, instance->hc_handle, 0);
    72                 if (parent_phone < 0) {
    73                         usb_log_error("Failed to connect to the HC device port %d.\n", i);
    74                         return parent_phone;
    75                 }
    7668                /* mind pointer arithmetics */
    7769                int ret = uhci_port_init(
    78                   &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh, parent_phone);
     70                  &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh);
    7971                if (ret != EOK) {
    8072                        unsigned j = 0;
  • uspace/drv/uhci-rhd/root_hub.h

    r81c508c r299d53e  
    4141
    4242#define UHCI_ROOT_HUB_PORT_COUNT 2
    43 #define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10
    44 #define ROOT_HUB_WAIT_USEC 10000000 /* 10 seconds */
     43#define ROOT_HUB_WAIT_USEC 5000000 /* 5 seconds */
    4544
    4645typedef struct root_hub {
Note: See TracChangeset for help on using the changeset viewer.