Changeset 62066b4 in mainline for uspace/drv


Ignore:
Timestamp:
2011-02-20T21:47:23Z (15 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ace12560
Parents:
6bb83c7 (diff), 423e8c81 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge with usb/development

Location:
uspace/drv
Files:
14 edited

Legend:

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

    r6bb83c7 r62066b4  
    4949#include <ipc/devman.h>
    5050#include <ipc/dev_iface.h>
     51#include <ipc/irc.h>
     52#include <ipc/ns.h>
     53#include <ipc/services.h>
     54#include <sysinfo.h>
    5155#include <ops/hw_res.h>
    5256#include <device/hw_res.h>
     
    7276static bool pciintel_enable_child_interrupt(device_t *dev)
    7377{
    74         /* TODO */
    75        
    76         return false;
     78        /* This is an old ugly way, copied from ne2000 driver */
     79        assert(dev);
     80        pci_dev_data_t *dev_data = (pci_dev_data_t *) dev->driver_data;
     81
     82  sysarg_t apic;
     83  sysarg_t i8259;
     84        int irc_phone = -1;
     85        int irc_service = 0;
     86
     87  if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
     88    irc_service = SERVICE_APIC;
     89        } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
     90    irc_service = SERVICE_I8259;
     91        }
     92
     93  if (irc_service) {
     94    while (irc_phone < 0)
     95      irc_phone = service_connect_blocking(irc_service, 0, 0);
     96  } else {
     97                return false;
     98        }
     99
     100        size_t i;
     101  for (i = 0; i < dev_data->hw_resources.count; i++) {
     102                if (dev_data->hw_resources.resources[i].type == INTERRUPT) {
     103                        int irq = dev_data->hw_resources.resources[i].res.interrupt.irq;
     104                        async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
     105                }
     106        }
     107
     108        async_hangup(irc_phone);
     109        return true;
    77110}
    78111
  • uspace/drv/uhci-hcd/batch.c

    r6bb83c7 r62066b4  
    141141        usb_log_debug("Checking(%p) %d packet for completion.\n",
    142142            instance, instance->packets);
    143         /* This is just an ugly trick to support the old API */
    144143        instance->transfered_size = 0;
    145144        size_t i = 0;
     
    157156                    transfer_descriptor_actual_size(&instance->tds[i]);
    158157        }
     158        /* This is just an ugly trick to support the old API */
    159159        instance->transfered_size -= instance->setup_size;
    160160        return true;
     
    191191            0, 1, false, instance->target, USB_PID_IN, NULL, NULL);
    192192
     193        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     194
    193195        instance->next_step = batch_call_out_and_dispose;
    194196        batch_schedule(instance);
     
    221223        transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    222224            0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
     225
     226        instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    223227
    224228        instance->next_step = batch_call_in_and_dispose;
     
    244248        }
    245249
     250        instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     251
    246252        instance->next_step = batch_call_in_and_dispose;
    247253        batch_schedule(instance);
     
    268274        }
    269275
     276        instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
     277
    270278        instance->next_step = batch_call_out_and_dispose;
    271279        batch_schedule(instance);
  • uspace/drv/uhci-hcd/iface.c

    r6bb83c7 r62066b4  
    5454}
    5555/*----------------------------------------------------------------------------*/
    56 static int reserve_default_address(device_t *dev, bool full_speed)
     56static int reserve_default_address(device_t *dev, usb_speed_t speed)
    5757{
    5858        assert(dev);
     
    7272}
    7373/*----------------------------------------------------------------------------*/
    74 static int request_address(device_t *dev, bool full_speed,
     74static int request_address(device_t *dev, usb_speed_t speed,
    7575    usb_address_t *address)
    7676{
     
    164164        return EOK;
    165165}
    166 /*----------------------------------------------------------------------------*/
    167 static int control_write_setup(device_t *dev, usb_target_t target,
    168     size_t max_packet_size,
    169     void *data, size_t size,
    170     usbhc_iface_transfer_out_callback_t callback, void *arg)
    171 {
    172         dev_speed_t speed = FULL_SPEED;
    173166
    174         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    175         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    176             max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
    177         if (!batch)
    178                 return ENOMEM;
    179         batch_control_setup_old(batch);
    180         return EOK;
    181 }
    182 /*----------------------------------------------------------------------------*/
    183 static int control_write_data(device_t *dev, usb_target_t target,
    184     size_t max_packet_size,
    185     void *data, size_t size,
    186     usbhc_iface_transfer_out_callback_t callback, void *arg)
    187 {
    188         dev_speed_t speed = FULL_SPEED;
    189167
    190         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    191         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    192             max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg);
    193         if (!batch)
    194                 return ENOMEM;
    195         batch_control_write_data_old(batch);
    196         return EOK;
    197 }
    198 /*----------------------------------------------------------------------------*/
    199 static int control_write_status(device_t *dev, usb_target_t target,
    200     usbhc_iface_transfer_in_callback_t callback, void *arg)
    201 {
    202         size_t max_packet_size = 8;
    203         dev_speed_t speed = FULL_SPEED;
    204 
    205         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    206         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    207             max_packet_size, speed, NULL, 0, NULL, 0, callback, NULL, arg);
    208         if (!batch)
    209                 return ENOMEM;
    210         batch_control_write_status_old(batch);
    211         return EOK;
    212 }
    213 /*----------------------------------------------------------------------------*/
    214 static int control_read_setup(device_t *dev, usb_target_t target,
    215     size_t max_packet_size,
    216     void *data, size_t size,
    217     usbhc_iface_transfer_out_callback_t callback, void *arg)
    218 {
    219         dev_speed_t speed = FULL_SPEED;
    220 
    221         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    222         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    223             max_packet_size, speed, NULL, 0, data, size, NULL, callback, arg);
    224         if (!batch)
    225                 return ENOMEM;
    226         batch_control_setup_old(batch);
    227         return EOK;
    228 }
    229 /*----------------------------------------------------------------------------*/
    230 static int control_read_data(device_t *dev, usb_target_t target,
    231     size_t max_packet_size,
    232     void *data, size_t size,
    233     usbhc_iface_transfer_in_callback_t callback, void *arg)
    234 {
    235         dev_speed_t speed = FULL_SPEED;
    236 
    237         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    238         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    239             max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg);
    240         if (!batch)
    241                 return ENOMEM;
    242         batch_control_read_data_old(batch);
    243         return EOK;
    244 }
    245 /*----------------------------------------------------------------------------*/
    246 static int control_read_status(device_t *dev, usb_target_t target,
    247     usbhc_iface_transfer_out_callback_t callback, void *arg)
    248 {
    249         size_t max_packet_size = 8;
    250         dev_speed_t speed = FULL_SPEED;
    251 
    252         usb_log_warning("Using deprecated API %s.\n", __FUNCTION__);
    253         batch_t *batch = batch_get(dev, target, USB_TRANSFER_CONTROL,
    254             max_packet_size, speed, NULL, 0, NULL, 0, NULL, callback, arg);
    255         if (!batch)
    256                 return ENOMEM;
    257         batch_control_read_status_old(batch);
    258         return EOK;
    259 }
    260168/*----------------------------------------------------------------------------*/
    261169usbhc_iface_t uhci_iface = {
     
    273181        .control_read = control_read,
    274182        .control_write = control_write,
    275 
    276         .control_write_setup = control_write_setup,
    277         .control_write_data = control_write_data,
    278         .control_write_status = control_write_status,
    279 
    280         .control_read_setup = control_read_setup,
    281         .control_read_data = control_read_data,
    282         .control_read_status = control_read_status
    283183};
    284184/**
  • uspace/drv/uhci-hcd/main.c

    r6bb83c7 r62066b4  
    3434#include <driver.h>
    3535#include <usb_iface.h>
     36#include <device/hw_res.h>
    3637
    3738#include <errno.h>
     
    4647#define NAME "uhci-hcd"
    4748
     49static int uhci_add_device(device_t *device);
     50static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle);
     51/*----------------------------------------------------------------------------*/
    4852static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
    4953{
     
    5458        return EOK;
    5559}
    56 
     60/*----------------------------------------------------------------------------*/
    5761static usb_iface_t hc_usb_iface = {
    5862        .get_hc_handle = usb_iface_get_hc_handle
    5963};
    60 
     64/*----------------------------------------------------------------------------*/
    6165static device_ops_t uhci_ops = {
    6266        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    6367        .interfaces[USBHC_DEV_IFACE] = &uhci_iface
    6468};
     69/*----------------------------------------------------------------------------*/
     70static driver_ops_t uhci_driver_ops = {
     71        .add_device = uhci_add_device,
     72};
     73/*----------------------------------------------------------------------------*/
     74static driver_t uhci_driver = {
     75        .name = NAME,
     76        .driver_ops = &uhci_driver_ops
     77};
     78/*----------------------------------------------------------------------------*/
     79static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
     80{
     81        assert(device);
     82        uhci_t *hc = dev_to_uhci(device);
     83        uint16_t status = IPC_GET_ARG1(*call);
     84        assert(hc);
     85        uhci_interrupt(hc, status);
     86}
     87/*----------------------------------------------------------------------------*/
     88#define CHECK_RET_RETURN(ret, message...) \
     89if (ret != EOK) { \
     90        usb_log_error(message); \
     91        return ret; \
     92}
    6593
    6694static int uhci_add_device(device_t *device)
     
    75103        int irq;
    76104
    77         int rc = pci_get_my_registers(device,
    78             &io_reg_base, &io_reg_size, &irq);
     105        int ret =
     106            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
    79107
    80         if (rc != EOK) {
    81                 usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n",
    82                     rc, device->handle);
    83                 return rc;
    84         }
    85 
     108        CHECK_RET_RETURN(ret,
     109            "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
    86110        usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
    87111            io_reg_base, io_reg_size, irq);
    88112
     113        ret = pci_enable_interrupts(device);
     114        CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
     115
    89116        uhci_t *uhci_hc = malloc(sizeof(uhci_t));
    90         if (!uhci_hc) {
    91                 usb_log_error("Failed to allocaete memory for uhci hcd driver.\n");
    92                 return ENOMEM;
     117        ret = (uhci_hc != NULL) ? EOK : ENOMEM;
     118        CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
     119
     120        ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
     121        if (ret != EOK) {
     122                usb_log_error("Failed to init uhci-hcd.\n");
     123                free(uhci_hc);
     124                return ret;
    93125        }
    94126
    95         int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
     127        ret = register_interrupt_handler(device, irq, irq_handler,
     128            &uhci_hc->interrupt_code);
    96129        if (ret != EOK) {
    97                 usb_log_error("Failed to init uhci-hcd.\n");
     130                usb_log_error("Failed to register interrupt handler.\n");
     131                uhci_fini(uhci_hc);
     132                free(uhci_hc);
    98133                return ret;
    99134        }
     135
    100136        device_t *rh;
    101137        ret = setup_root_hub(&rh, device);
    102 
    103138        if (ret != EOK) {
    104139                usb_log_error("Failed to setup uhci root hub.\n");
    105                 /* TODO: destroy uhci here */
     140                uhci_fini(uhci_hc);
     141                free(uhci_hc);
    106142                return ret;
    107143        }
     
    110146        if (ret != EOK) {
    111147                usb_log_error("Failed to register root hub.\n");
    112                 /* TODO: destroy uhci here */
     148                uhci_fini(uhci_hc);
     149                free(uhci_hc);
     150                free(rh);
    113151                return ret;
    114152        }
    115153
    116154        device->driver_data = uhci_hc;
    117 
    118155        return EOK;
    119156}
    120 
    121 static driver_ops_t uhci_driver_ops = {
    122         .add_device = uhci_add_device,
    123 };
    124 
    125 static driver_t uhci_driver = {
    126         .name = NAME,
    127         .driver_ops = &uhci_driver_ops
    128 };
    129 
     157/*----------------------------------------------------------------------------*/
    130158int main(int argc, char *argv[])
    131159{
    132         /*
    133          * Do some global initializations.
    134          */
    135         sleep(5);
    136         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     160        sleep(3);
     161        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    137162
    138163        return driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/pci.c

    r6bb83c7 r62066b4  
    121121        return rc;
    122122}
    123 
     123/*----------------------------------------------------------------------------*/
     124int pci_enable_interrupts(device_t *device)
     125{
     126        int parent_phone = devman_parent_device_connect(device->handle,
     127            IPC_FLAG_BLOCKING);
     128        bool enabled = hw_res_enable_interrupt(parent_phone);
     129        return enabled ? EOK : EIO;
     130}
    124131/**
    125132 * @}
  • uspace/drv/uhci-hcd/pci.h

    r6bb83c7 r62066b4  
    3939
    4040int pci_get_my_registers(device_t *, uintptr_t *, size_t *, int *);
     41int pci_enable_interrupts(device_t *device);
    4142
    4243#endif
  • uspace/drv/uhci-hcd/transfer_list.c

    r6bb83c7 r62066b4  
    111111        /* I'm the first one here */
    112112        if (batch->link.prev == &instance->batch_list) {
    113                 usb_log_debug("Removing tracer %p was first, next element %x.\n",
     113                usb_log_debug("Removing batch %p was first, next element %x.\n",
    114114                        batch, batch->qh->next_queue);
    115115                instance->queue_head->element = batch->qh->next_queue;
    116116        } else {
    117                 usb_log_debug("Removing tracer %p was NOT first, next element %x.\n",
     117                usb_log_debug("Removing batch %p was NOT first, next element %x.\n",
    118118                        batch, batch->qh->next_queue);
    119119                batch_t *prev = list_get_instance(batch->link.prev, batch_t, link);
  • uspace/drv/uhci-hcd/uhci-hcd.ma

    r6bb83c7 r62066b4  
    1110 pci/ven=8086&dev=7020
    2 
     210 pci/ven=8086&dev=7112
  • uspace/drv/uhci-hcd/uhci.c

    r6bb83c7 r62066b4  
    3939
    4040#include "uhci.h"
     41static irq_cmd_t uhci_cmds[] = {
     42        {
     43                .cmd = CMD_PIO_READ_16,
     44                .addr = (void*)0xc022,
     45                .dstarg = 1
     46        },
     47        {
     48                .cmd = CMD_PIO_WRITE_16,
     49                .addr = (void*)0xc022,
     50                .value = 0x1f
     51        },
     52        {
     53                .cmd = CMD_ACCEPT
     54        }
     55};
    4156
    4257static int uhci_init_transfer_lists(uhci_t *instance);
    43 static int uhci_clean_finished(void *arg);
     58static int uhci_init_mem_structures(uhci_t *instance);
     59static void uhci_init_hw(uhci_t *instance);
     60
     61static int uhci_interrupt_emulator(void *arg);
    4462static int uhci_debug_checker(void *arg);
     63
    4564static bool allowed_usb_packet(
    4665        bool low_speed, usb_transfer_type_t, size_t size);
    4766
    48 int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
    49 {
    50 #define CHECK_RET_RETURN(message...) \
     67#define CHECK_RET_RETURN(ret, message...) \
    5168        if (ret != EOK) { \
    5269                usb_log_error(message); \
     
    5471        } else (void) 0
    5572
    56         /* init address keeper(libusb) */
    57         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    58         usb_log_debug("Initialized address manager.\n");
     73int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     74{
     75        assert(reg_size >= sizeof(regs_t));
    5976
    6077        /* allow access to hc control registers */
    6178        regs_t *io;
    62         assert(reg_size >= sizeof(regs_t));
    6379        int ret = pio_enable(regs, reg_size, (void**)&io);
    64         CHECK_RET_RETURN("Failed to gain access to registers at %p.\n", io);
     80        CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
    6581        instance->registers = io;
    6682        usb_log_debug("Device registers accessible.\n");
    6783
     84        ret = uhci_init_mem_structures(instance);
     85        CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
     86
     87        uhci_init_hw(instance);
     88
     89        instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
     90//      fibril_add_ready(instance->cleaner);
     91
     92        instance->debug_checker = fibril_create(uhci_debug_checker, instance);
     93        fibril_add_ready(instance->debug_checker);
     94
     95        return EOK;
     96}
     97/*----------------------------------------------------------------------------*/
     98void uhci_init_hw(uhci_t *instance)
     99{
     100
     101        /* set framelist pointer */
     102        const uint32_t pa = addr_to_phys(instance->frame_list);
     103        pio_write_32(&instance->registers->flbaseadd, pa);
     104
     105        /* enable all interrupts, but resume interrupt */
     106        pio_write_16(&instance->registers->usbintr,
     107                  UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
     108
     109        /* Start the hc with large(64B) packet FSBR */
     110        pio_write_16(&instance->registers->usbcmd,
     111            UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
     112        usb_log_debug("Started UHCI HC.\n");
     113}
     114/*----------------------------------------------------------------------------*/
     115int uhci_init_mem_structures(uhci_t *instance)
     116{
     117        assert(instance);
     118
     119        /* init interrupt code */
     120        irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds));
     121        if (interrupt_commands == NULL) {
     122                return ENOMEM;
     123        }
     124        memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds));
     125        interrupt_commands[0].addr = (void*)&instance->registers->usbsts;
     126        interrupt_commands[1].addr = (void*)&instance->registers->usbsts;
     127        instance->interrupt_code.cmds = interrupt_commands;
     128        instance->interrupt_code.cmdcount =
     129            sizeof(uhci_cmds) / sizeof(irq_cmd_t);
     130
    68131        /* init transfer lists */
    69         ret = uhci_init_transfer_lists(instance);
    70         CHECK_RET_RETURN("Failed to initialize transfer lists.\n");
    71         usb_log_debug("Transfer lists initialized.\n");
    72 
    73 
    74         usb_log_debug("Initializing frame list.\n");
     132        int ret = uhci_init_transfer_lists(instance);
     133        CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
     134        usb_log_debug("Initialized transfer lists.\n");
     135
     136        /* frame list initialization */
    75137        instance->frame_list = get_page();
    76138        ret = instance ? EOK : ENOMEM;
    77         CHECK_RET_RETURN("Failed to get frame list page.\n");
     139        CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
     140        usb_log_debug("Initialized frame list.\n");
    78141
    79142        /* initialize all frames to point to the first queue head */
     
    86149        }
    87150
    88         const uintptr_t pa = (uintptr_t)addr_to_phys(instance->frame_list);
    89         pio_write_32(&instance->registers->flbaseadd, (uint32_t)pa);
    90 
    91         list_initialize(&instance->batch_list);
    92         fibril_mutex_initialize(&instance->batch_list_mutex);
    93 
    94         instance->cleaner = fibril_create(uhci_clean_finished, instance);
    95         fibril_add_ready(instance->cleaner);
    96 
    97         instance->debug_checker = fibril_create(uhci_debug_checker, instance);
    98         fibril_add_ready(instance->debug_checker);
    99 
    100         /* Start the hc with large(64B) packet FSBR */
    101         pio_write_16(&instance->registers->usbcmd,
    102             UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET);
    103         usb_log_debug("Started UHCI HC.\n");
    104 
    105         uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    106         cmd |= UHCI_CMD_DEBUG;
    107         pio_write_16(&instance->registers->usbcmd, cmd);
     151        /* init address keeper(libusb) */
     152        usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
     153        usb_log_debug("Initialized address manager.\n");
    108154
    109155        return EOK;
     
    114160        assert(instance);
    115161
    116         /* initialize */
     162        /* initialize TODO: check errors */
    117163        int ret;
    118164        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     
    146192        instance->transfers[1][USB_TRANSFER_CONTROL] =
    147193          &instance->transfers_control_slow;
    148         instance->transfers[0][USB_TRANSFER_CONTROL] =
    149           &instance->transfers_control_full;
     194        instance->transfers[0][USB_TRANSFER_BULK] =
     195          &instance->transfers_bulk_full;
    150196
    151197        return EOK;
     
    174220}
    175221/*----------------------------------------------------------------------------*/
    176 int uhci_clean_finished(void* arg)
    177 {
    178         usb_log_debug("Started cleaning fibril.\n");
     222void uhci_interrupt(uhci_t *instance, uint16_t status)
     223{
     224        assert(instance);
     225        if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
     226                return;
     227        usb_log_debug("UHCI interrupt: %X.\n", status);
     228        transfer_list_check(&instance->transfers_interrupt);
     229        transfer_list_check(&instance->transfers_control_slow);
     230        transfer_list_check(&instance->transfers_control_full);
     231        transfer_list_check(&instance->transfers_bulk_full);
     232}
     233/*----------------------------------------------------------------------------*/
     234int uhci_interrupt_emulator(void* arg)
     235{
     236        usb_log_debug("Started interrupt emulator.\n");
    179237        uhci_t *instance = (uhci_t*)arg;
    180238        assert(instance);
    181239
    182240        while(1) {
    183                 transfer_list_check(&instance->transfers_interrupt);
    184                 transfer_list_check(&instance->transfers_control_slow);
    185                 transfer_list_check(&instance->transfers_control_full);
    186                 transfer_list_check(&instance->transfers_bulk_full);
     241                uint16_t status = pio_read_16(&instance->registers->usbsts);
     242                uhci_interrupt(instance, status);
    187243                async_usleep(UHCI_CLEANER_TIMEOUT);
    188244        }
     
    195251        assert(instance);
    196252        while (1) {
    197                 uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    198                 uint16_t sts = pio_read_16(&instance->registers->usbsts);
    199                 usb_log_debug("Command register: %X Status register: %X\n", cmd, sts);
     253                const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
     254                const uint16_t sts = pio_read_16(&instance->registers->usbsts);
     255                const uint16_t intr = pio_read_16(&instance->registers->usbintr);
     256                usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
     257                    cmd, sts, intr);
    200258
    201259                uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
    202                 if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {
     260                if (frame_list != addr_to_phys(instance->frame_list)) {
    203261                        usb_log_debug("Framelist address: %p vs. %p.\n",
    204262                                frame_list, addr_to_phys(instance->frame_list));
  • uspace/drv/uhci-hcd/uhci.h

    r6bb83c7 r62066b4  
    6666
    6767        uint16_t usbintr;
     68#define UHCI_INTR_SHORT_PACKET (1 << 3)
     69#define UHCI_INTR_COMPLETE (1 << 2)
     70#define UHCI_INTR_RESUME (1 << 1)
     71#define UHCI_INTR_CRC (1 << 0)
     72
    6873        uint16_t frnum;
    6974        uint32_t flbaseadd;
     
    8186        link_pointer_t *frame_list;
    8287
    83         link_t batch_list;
    84         fibril_mutex_t batch_list_mutex;
    85 
    8688        transfer_list_t transfers_bulk_full;
    8789        transfer_list_t transfers_control_full;
     
    9092
    9193        transfer_list_t *transfers[2][4];
     94
     95        irq_code_t interrupt_code;
    9296
    9397        fid_t cleaner;
     
    98102int uhci_init(uhci_t *instance, void *regs, size_t reg_size);
    99103
    100 int uhci_fini(uhci_t *device);
    101 
    102 int uhci_transfer(
    103   uhci_t *instance,
    104   device_t *dev,
    105   usb_target_t target,
    106   usb_transfer_type_t transfer_type,
    107         bool toggle,
    108   usb_packet_id pid,
    109         bool low_speed,
    110   void *buffer, size_t size,
    111   usbhc_iface_transfer_out_callback_t callback_out,
    112   usbhc_iface_transfer_in_callback_t callback_in,
    113   void *arg );
     104static inline void uhci_fini(uhci_t *instance) {};
    114105
    115106int uhci_schedule(uhci_t *instance, batch_t *batch);
    116107
     108void uhci_interrupt(uhci_t *instance, uint16_t status);
     109
    117110static inline uhci_t * dev_to_uhci(device_t *dev)
    118111        { return (uhci_t*)dev->driver_data; }
     112
    119113
    120114#endif
  • uspace/drv/uhci-rhd/port.c

    r6bb83c7 r62066b4  
    131131        return EOK;
    132132}
    133 /*----------------------------------------------------------------------------*/
    134 static int uhci_port_new_device(uhci_port_t *port)
    135 {
    136         assert(port);
    137         assert(usb_hc_connection_is_opened(&port->hc_connection));
    138 
    139         usb_log_info("Adding new device on port %d.\n", port->number);
    140 
    141         /* get address of the future device */
    142         const usb_address_t usb_address = usb_hc_request_address(
    143             &port->hc_connection, true);
    144 
    145         if (usb_address <= 0) {
    146                 usb_log_error("Recieved invalid address(%d).\n", usb_address);
    147                 return usb_address;
    148         }
    149         usb_log_debug("Sucessfully obtained address %d for port %d.\n",
    150             usb_address, port->number);
    151 
    152         /* get default address */
    153         int ret = usb_hc_reserve_default_address(&port->hc_connection, true);
    154         if (ret != EOK) {
    155                 usb_log_error("Failed to reserve default address on port %d.\n",
    156                     port->number);
    157                 int ret2 = usb_hc_unregister_device(&port->hc_connection,
    158                     usb_address);
    159                 if (ret2 != EOK) {
    160                         usb_log_fatal("Failed to return requested address on port %d.\n",
    161                            port->number);
    162                         return ret2;
    163                 }
    164                 usb_log_debug("Successfully returned reserved address on port %d.\n",
    165                         port->number);
    166                 return ret;
    167         }
    168         usb_log_debug("Sucessfully obtained default address for port %d.\n",
    169             port->number);
     133
     134/** Callback for enabling port during adding a new device.
     135 *
     136 * @param portno Port number (unused).
     137 * @param arg Pointer to uhci_port_t of port with the new device.
     138 * @return Error code.
     139 */
     140static int new_device_enable_port(int portno, void *arg)
     141{
     142        uhci_port_t *port = (uhci_port_t *) arg;
     143
     144        usb_log_debug("new_device_enable_port(%d)\n", port->number);
    170145
    171146        /*
    172          * the host then waits for at least 100 ms to allow completion of
     147         * The host then waits for at least 100 ms to allow completion of
    173148         * an insertion process and for power at the device to become stable.
    174149         */
    175150        async_usleep(100000);
    176151
    177         /* enable port */
     152        /* Enable the port. */
    178153        uhci_port_set_enabled(port, true);
    179154
     
    197172        }
    198173
    199         /*
    200          * Initialize connection to the device.
    201          */
    202         /* FIXME: check for errors. */
    203         usb_device_connection_t new_dev_connection;
    204         usb_endpoint_pipe_t new_dev_ctrl_pipe;
    205         usb_device_connection_initialize_on_default_address(
    206             &new_dev_connection, &port->hc_connection);
    207         usb_endpoint_pipe_initialize_default_control(&new_dev_ctrl_pipe,
    208             &new_dev_connection);
    209 
    210         /*
    211          * Assign new address to the device. This function updates
    212          * the backing connection to still point to the same device.
    213          */
    214         /* FIXME: check for errors. */
    215         usb_endpoint_pipe_start_session(&new_dev_ctrl_pipe);
    216         ret = usb_request_set_address(&new_dev_ctrl_pipe, usb_address);
    217         usb_endpoint_pipe_end_session(&new_dev_ctrl_pipe);
    218 
    219         if (ret != EOK) { /* address assigning went wrong */
    220                 usb_log_error("Failed(%d) to assign address to the device.\n", ret);
     174        return EOK;
     175}
     176
     177/*----------------------------------------------------------------------------*/
     178static int uhci_port_new_device(uhci_port_t *port)
     179{
     180        assert(port);
     181        assert(usb_hc_connection_is_opened(&port->hc_connection));
     182
     183        usb_log_info("Detected new device on port %u.\n", port->number);
     184
     185        usb_address_t dev_addr;
     186        int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
     187            USB_SPEED_FULL,
     188            new_device_enable_port, port->number, port,
     189            &dev_addr, &port->attached_device);
     190        if (rc != EOK) {
     191                usb_log_error("Failed adding new device on port %u: %s.\n",
     192                    port->number, str_error(rc));
    221193                uhci_port_set_enabled(port, false);
    222                 int release = usb_hc_release_default_address(&port->hc_connection);
    223                 if (release != EOK) {
    224                         usb_log_error("Failed to release default address on port %d.\n",
    225                             port->number);
    226                         return release;
    227                 }
    228                 usb_log_debug("Sucessfully released default address on port %d.\n",
    229                     port->number);
    230                 return ret;
    231         }
    232         usb_log_debug("Sucessfully assigned address %d for port %d.\n",
    233             usb_address, port->number);
    234 
    235         /* release default address */
    236         ret = usb_hc_release_default_address(&port->hc_connection);
    237         if (ret != EOK) {
    238                 usb_log_error("Failed to release default address on port %d.\n",
    239                     port->number);
    240                 return ret;
    241         }
    242         usb_log_debug("Sucessfully released default address on port %d.\n",
    243             port->number);
    244 
    245         /* communicate and possibly report to devman */
    246         assert(port->attached_device == 0);
    247 
    248         ret = usb_device_register_child_in_devman(new_dev_connection.address,
    249             new_dev_connection.hc_handle, port->rh, &port->attached_device);
    250 
    251         if (ret != EOK) { /* something went wrong */
    252                 usb_log_error("Failed(%d) in usb_drv_register_child.\n", ret);
    253                 uhci_port_set_enabled(port, false);
    254                 return ENOMEM;
    255         }
    256         usb_log_info("Sucessfully added device on port(%d) address(%d) handle %d.\n",
    257                 port->number, usb_address, port->attached_device);
    258 
    259         /*
    260          * Register the device in the host controller.
    261          */
    262         usb_hc_attached_device_t new_device = {
    263                 .address = new_dev_connection.address,
    264                 .handle = port->attached_device
    265         };
    266 
    267         ret = usb_hc_register_device(&port->hc_connection, &new_device);
    268         // TODO: proper error check here
    269         assert(ret == EOK);
    270 
    271         return EOK;
    272 }
     194                return rc;
     195        }
     196
     197        usb_log_info("New device on port %u has address %d (handle %zu).\n",
     198            port->number, dev_addr, port->attached_device);
     199
     200        return EOK;
     201}
     202
    273203/*----------------------------------------------------------------------------*/
    274204static int uhci_port_remove_device(uhci_port_t *port)
  • uspace/drv/uhci-rhd/root_hub.c

    r6bb83c7 r62066b4  
    4747        assert(rh);
    4848        int ret;
    49         ret = usb_drv_find_hc(rh, &instance->hc_handle);
     49        ret = usb_hc_find(rh->handle, &instance->hc_handle);
    5050        usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle);
    5151        if (ret != EOK) {
  • uspace/drv/usbhub/usbhub.c

    r6bb83c7 r62066b4  
    5252#include "usb/pipes.h"
    5353
     54static int iface_get_hc_handle(device_t *device, devman_handle_t *handle)
     55{
     56        return usb_hc_find(device->handle, handle);
     57}
     58
    5459static usb_iface_t hub_usb_iface = {
    55         .get_hc_handle = usb_drv_find_hc
     60        .get_hc_handle = iface_get_hc_handle
    5661};
    5762
     
    263268        //get default address
    264269        //opResult = usb_drv_reserve_default_address(hc);
    265         opResult = usb_hc_reserve_default_address(&hub->connection, false);
     270        opResult = usb_hc_reserve_default_address(&hub->connection, USB_SPEED_LOW);
    266271        if (opResult != EOK) {
    267272                dprintf(USB_LOG_LEVEL_WARNING, "cannot assign default address, it is probably used");
     
    320325        usb_address_t new_device_address = usb_hc_request_address(
    321326                        &hub->connection,
    322                         false/// \TODO fullspeed??
     327                        USB_SPEED_LOW/// \TODO fullspeed??
    323328                        );
    324329        if (new_device_address < 0) {
  • uspace/drv/vhc/connhost.c

    r6bb83c7 r62066b4  
    234234}
    235235
    236 static int enqueue_transfer_setup(device_t *dev,
    237     usb_target_t target, usb_transfer_type_t transfer_type,
    238     void *buffer, size_t size,
    239     usbhc_iface_transfer_out_callback_t callback, void *arg)
    240 {
    241         usb_log_debug2("Transfer SETUP [%d.%d (%s); %zu].\n",
    242             target.address, target.endpoint,
    243             usb_str_transfer_type(transfer_type),
    244             size);
    245 
    246         transfer_info_t *transfer
    247             = create_transfer_info(dev, USB_DIRECTION_OUT, arg);
    248         transfer->out_callback = callback;
    249 
    250         hc_add_transaction_to_device(true, target, transfer_type, buffer, size,
    251             universal_callback, transfer);
    252 
    253         return EOK;
    254 }
    255 
    256236static int enqueue_transfer_in(device_t *dev,
    257237    usb_target_t target, usb_transfer_type_t transfer_type,
     
    292272        return enqueue_transfer_in(dev, target, USB_TRANSFER_INTERRUPT,
    293273            data, size,
    294             callback, arg);
    295 }
    296 
    297 static int control_write_setup(device_t *dev, usb_target_t target,
    298     size_t max_packet_size,
    299     void *data, size_t size,
    300     usbhc_iface_transfer_out_callback_t callback, void *arg)
    301 {
    302         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    303             data, size,
    304             callback, arg);
    305 }
    306 
    307 static int control_write_data(device_t *dev, usb_target_t target,
    308     size_t max_packet_size,
    309     void *data, size_t size,
    310     usbhc_iface_transfer_out_callback_t callback, void *arg)
    311 {
    312         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    313             data, size,
    314             callback, arg);
    315 }
    316 
    317 static int control_write_status(device_t *dev, usb_target_t target,
    318     usbhc_iface_transfer_in_callback_t callback, void *arg)
    319 {
    320         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    321             NULL, 0,
    322274            callback, arg);
    323275}
     
    341293}
    342294
    343 static int control_read_setup(device_t *dev, usb_target_t target,
    344     size_t max_packet_size,
    345     void *data, size_t size,
    346     usbhc_iface_transfer_out_callback_t callback, void *arg)
    347 {
    348         return enqueue_transfer_setup(dev, target, USB_TRANSFER_CONTROL,
    349             data, size,
    350             callback, arg);
    351 }
    352 
    353 static int control_read_data(device_t *dev, usb_target_t target,
    354     size_t max_packet_size,
    355     void *data, size_t size,
    356     usbhc_iface_transfer_in_callback_t callback, void *arg)
    357 {
    358         return enqueue_transfer_in(dev, target, USB_TRANSFER_CONTROL,
    359             data, size,
    360             callback, arg);
    361 }
    362 
    363 static int control_read_status(device_t *dev, usb_target_t target,
    364     usbhc_iface_transfer_out_callback_t callback, void *arg)
    365 {
    366         return enqueue_transfer_out(dev, target, USB_TRANSFER_CONTROL,
    367             NULL, 0,
    368             callback, arg);
    369 }
    370 
    371295static int control_read(device_t *dev, usb_target_t target,
    372296    size_t max_packet_size,
     
    390314
    391315
    392 static int reserve_default_address(device_t *dev, bool ignored)
     316static int reserve_default_address(device_t *dev, usb_speed_t ignored)
    393317{
    394318        usb_address_keeping_reserve_default(&addresses);
     
    402326}
    403327
    404 static int request_address(device_t *dev, bool ignored, usb_address_t *address)
     328static int request_address(device_t *dev, usb_speed_t ignored,
     329    usb_address_t *address)
    405330{
    406331        usb_address_t addr = usb_address_keeping_request(&addresses);
     
    454379        .interrupt_in = interrupt_in,
    455380
    456         .control_write_setup = control_write_setup,
    457         .control_write_data = control_write_data,
    458         .control_write_status = control_write_status,
    459 
    460381        .control_write = control_write,
    461 
    462         .control_read_setup = control_read_setup,
    463         .control_read_data = control_read_data,
    464         .control_read_status = control_read_status,
    465 
    466382        .control_read = control_read
    467383};
Note: See TracChangeset for help on using the changeset viewer.