Changes in / [6edc69a:374552ef] in mainline


Ignore:
Location:
uspace/drv/uhci-hcd
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/batch.c

    r6edc69a r374552ef  
    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 */
    143144        instance->transfered_size = 0;
    144145        size_t i = 0;
     
    156157                    transfer_descriptor_actual_size(&instance->tds[i]);
    157158        }
    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 
    195193        instance->next_step = batch_call_out_and_dispose;
    196194        batch_schedule(instance);
     
    223221        transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT,
    224222            0, 1, false, instance->target, USB_PID_OUT, NULL, NULL);
    225 
    226         instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    227223
    228224        instance->next_step = batch_call_in_and_dispose;
     
    248244        }
    249245
    250         instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    251 
    252246        instance->next_step = batch_call_in_and_dispose;
    253247        batch_schedule(instance);
     
    274268        }
    275269
    276         instance->tds[i - 1].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG;
    277 
    278270        instance->next_step = batch_call_out_and_dispose;
    279271        batch_schedule(instance);
  • uspace/drv/uhci-hcd/main.c

    r6edc69a r374552ef  
    3434#include <driver.h>
    3535#include <usb_iface.h>
    36 #include <ipc/irc.h>
    37 #include <ipc/ns.h>
    38 #include <ipc/services.h>
    39 #include <sysinfo.h>
    4036
    4137#include <errno.h>
     
    5046#define NAME "uhci-hcd"
    5147
    52 static int uhci_add_device(device_t *device);
    53 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle);
    54 /*----------------------------------------------------------------------------*/
    5548static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
    5649{
     
    6154        return EOK;
    6255}
    63 /*----------------------------------------------------------------------------*/
     56
    6457static usb_iface_t hc_usb_iface = {
    6558        .get_hc_handle = usb_iface_get_hc_handle
    6659};
    67 /*----------------------------------------------------------------------------*/
     60
    6861static device_ops_t uhci_ops = {
    6962        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    7063        .interfaces[USBHC_DEV_IFACE] = &uhci_iface
    7164};
    72 /*----------------------------------------------------------------------------*/
    73 static driver_ops_t uhci_driver_ops = {
    74         .add_device = uhci_add_device,
    75 };
    76 /*----------------------------------------------------------------------------*/
    77 static driver_t uhci_driver = {
    78         .name = NAME,
    79         .driver_ops = &uhci_driver_ops
    80 };
    81 /*----------------------------------------------------------------------------*/
    82 static irq_cmd_t uhci_cmds[] = {
    83         {
    84                 .cmd = CMD_PIO_READ_16,
    85                 .addr = (void*)0xc022,
    86                 .dstarg = 1
    87         },
    88         {
    89                 .cmd = CMD_PIO_WRITE_16,
    90                 .addr = (void*)0xc022,
    91                 .value = 0x1f
    92         },
    93         {
    94                 .cmd = CMD_ACCEPT
    95         }
    96 };
    97 /*----------------------------------------------------------------------------*/
    98 static irq_code_t uhci_code = {
    99         sizeof(uhci_cmds) / sizeof(irq_cmd_t),
    100         uhci_cmds
    101 };
    102 /*----------------------------------------------------------------------------*/
    103 static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
    104 {
    105         assert(device);
    106         uhci_t *hc = dev_to_uhci(device);
    107         usb_log_info("LOL HARDWARE INTERRUPT: %p.\n", hc);
    108         uint16_t status = IPC_GET_ARG1(*call);
    109         assert(hc);
    110         uhci_interrupt(hc, status);
    111 }
    112 /*----------------------------------------------------------------------------*/
     65
    11366static int uhci_add_device(device_t *device)
    11467{
     
    12275        int irq;
    12376
    124         int ret =
    125             pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
     77        int rc = pci_get_my_registers(device,
     78            &io_reg_base, &io_reg_size, &irq);
    12679
    127         if (ret != EOK) {
    128                 usb_log_error(
    129                     "Failed(%d) to get I/O registers addresses for device:.\n",
    130                     ret, device->handle);
    131                 return ret;
     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;
    13284        }
    13385
     
    13587            io_reg_base, io_reg_size, irq);
    13688
    137 
    138   sysarg_t apic;
    139   sysarg_t i8259;
    140         int irc_phone = -1;
    141         int irc_service = 0;
    142 
    143   if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
    144     irc_service = SERVICE_APIC;
    145                 usb_log_debug("SERVICE_APIC\n");
    146         } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
    147     irc_service = SERVICE_I8259;
    148                 usb_log_debug("SERVICE_I8259\n");
    149         }
    150 
    151   if (irc_service) {
    152     while (irc_phone < 0)
    153       irc_phone = service_connect_blocking(irc_service, 0, 0);
    154   }
    155         usb_log_debug("Interrupt conttroller phone: %d\n", irc_phone);
    156 
    157         async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
    158         async_hangup(irc_phone);
    159 
    160         ret = register_interrupt_handler(device, irq, irq_handler, &uhci_code);
    161         usb_log_debug("Registered interrupt handler %d.\n", ret);
    162 
    16389        uhci_t *uhci_hc = malloc(sizeof(uhci_t));
    16490        if (!uhci_hc) {
    165                 usb_log_error("Failed to allocate memory for uhci hcd driver.\n");
     91                usb_log_error("Failed to allocaete memory for uhci hcd driver.\n");
    16692                return ENOMEM;
    16793        }
    16894
    169         ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
     95        int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
    17096        if (ret != EOK) {
    17197                usb_log_error("Failed to init uhci-hcd.\n");
     
    174100        device_t *rh;
    175101        ret = setup_root_hub(&rh, device);
     102
    176103        if (ret != EOK) {
    177104                usb_log_error("Failed to setup uhci root hub.\n");
     
    191118        return EOK;
    192119}
    193 /*----------------------------------------------------------------------------*/
     120
     121static driver_ops_t uhci_driver_ops = {
     122        .add_device = uhci_add_device,
     123};
     124
     125static driver_t uhci_driver = {
     126        .name = NAME,
     127        .driver_ops = &uhci_driver_ops
     128};
     129
    194130int main(int argc, char *argv[])
    195131{
    196         sleep(3);
    197         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     132        /*
     133         * Do some global initializations.
     134         */
     135        sleep(5);
     136        usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
    198137
    199138        return driver_main(&uhci_driver);
  • uspace/drv/uhci-hcd/transfer_list.c

    r6edc69a r374552ef  
    111111        /* I'm the first one here */
    112112        if (batch->link.prev == &instance->batch_list) {
    113                 usb_log_debug("Removing batch %p was first, next element %x.\n",
     113                usb_log_debug("Removing tracer %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 batch %p was NOT first, next element %x.\n",
     117                usb_log_debug("Removing tracer %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

    r6edc69a r374552ef  
    1110 pci/ven=8086&dev=7020
    2 10 pci/ven=8086&dev=7112
     2
  • uspace/drv/uhci-hcd/uhci.c

    r6edc69a r374552ef  
    4141
    4242static int uhci_init_transfer_lists(uhci_t *instance);
    43 static int uhci_init_mem_structures(uhci_t *instance);
    44 static void uhci_init_hw(uhci_t *instance);
    45 
    46 static int uhci_interrupt_emulator(void *arg);
     43static int uhci_clean_finished(void *arg);
    4744static int uhci_debug_checker(void *arg);
    48 
    4945static bool allowed_usb_packet(
    5046        bool low_speed, usb_transfer_type_t, size_t size);
    5147
    52 #define CHECK_RET_RETURN(ret, message...) \
     48int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
     49{
     50#define CHECK_RET_RETURN(message...) \
    5351        if (ret != EOK) { \
    5452                usb_log_error(message); \
     
    5654        } else (void) 0
    5755
    58 int uhci_init(uhci_t *instance, void *regs, size_t reg_size)
    59 {
    60         assert(reg_size >= sizeof(regs_t));
     56        /* init address keeper(libusb) */
     57        usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
     58        usb_log_debug("Initialized address manager.\n");
    6159
    6260        /* allow access to hc control registers */
    6361        regs_t *io;
     62        assert(reg_size >= sizeof(regs_t));
    6463        int ret = pio_enable(regs, reg_size, (void**)&io);
    65         CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io);
     64        CHECK_RET_RETURN("Failed to gain access to registers at %p.\n", io);
    6665        instance->registers = io;
    6766        usb_log_debug("Device registers accessible.\n");
    6867
    69         ret = uhci_init_mem_structures(instance);
    70         CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n");
    71 
    72         uhci_init_hw(instance);
    73 
    74         instance->cleaner = fibril_create(uhci_interrupt_emulator, instance);
    75 //      fibril_add_ready(instance->cleaner);
    76 
    77         instance->debug_checker = fibril_create(uhci_debug_checker, instance);
    78         fibril_add_ready(instance->debug_checker);
    79 
    80         return EOK;
    81 }
    82 /*----------------------------------------------------------------------------*/
    83 void uhci_init_hw(uhci_t *instance)
    84 {
    85 
    86         /* set framelist pointer */
    87         const uint32_t pa = addr_to_phys(instance->frame_list);
    88         pio_write_32(&instance->registers->flbaseadd, pa);
    89 
    90         /* enable all interrupts, but resume interrupt */
    91         pio_write_16(&instance->registers->usbintr,
    92                   UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET);
    93 
    94         /* Start the hc with large(64B) packet FSBR */
    95         pio_write_16(&instance->registers->usbcmd,
    96             UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE);
    97         usb_log_debug("Started UHCI HC.\n");
    98 }
    99 /*----------------------------------------------------------------------------*/
    100 int uhci_init_mem_structures(uhci_t *instance)
    101 {
    102         assert(instance);
    10368        /* init transfer lists */
    104         int ret = uhci_init_transfer_lists(instance);
    105         CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n");
    106         usb_log_debug("Initialized transfer lists.\n");
    107 
    108         /* frame list initialization */
     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");
    10975        instance->frame_list = get_page();
    11076        ret = instance ? EOK : ENOMEM;
    111         CHECK_RET_RETURN(ret, "Failed to get frame list page.\n");
    112         usb_log_debug("Initialized frame list.\n");
     77        CHECK_RET_RETURN("Failed to get frame list page.\n");
    11378
    11479        /* initialize all frames to point to the first queue head */
     
    12186        }
    12287
    123         /* init address keeper(libusb) */
    124         usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX);
    125         usb_log_debug("Initialized address manager.\n");
     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);
    126108
    127109        return EOK;
     
    132114        assert(instance);
    133115
    134         /* initialize TODO: check errors */
     116        /* initialize */
    135117        int ret;
    136118        ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL");
     
    164146        instance->transfers[1][USB_TRANSFER_CONTROL] =
    165147          &instance->transfers_control_slow;
    166         instance->transfers[0][USB_TRANSFER_BULK] =
    167           &instance->transfers_bulk_full;
     148        instance->transfers[0][USB_TRANSFER_CONTROL] =
     149          &instance->transfers_control_full;
    168150
    169151        return EOK;
     
    192174}
    193175/*----------------------------------------------------------------------------*/
    194 void uhci_interrupt(uhci_t *instance, uint16_t status)
    195 {
    196         assert(instance);
    197         if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0)
    198                 return;
    199         usb_log_debug("UHCI interrupt: %X.\n", status);
    200         transfer_list_check(&instance->transfers_interrupt);
    201         transfer_list_check(&instance->transfers_control_slow);
    202         transfer_list_check(&instance->transfers_control_full);
    203         transfer_list_check(&instance->transfers_bulk_full);
    204 }
    205 /*----------------------------------------------------------------------------*/
    206 int uhci_interrupt_emulator(void* arg)
    207 {
    208         usb_log_debug("Started interrupt emulator.\n");
     176int uhci_clean_finished(void* arg)
     177{
     178        usb_log_debug("Started cleaning fibril.\n");
    209179        uhci_t *instance = (uhci_t*)arg;
    210180        assert(instance);
    211181
    212182        while(1) {
    213                 uint16_t status = pio_read_16(&instance->registers->usbsts);
    214                 uhci_interrupt(instance, status);
     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);
    215187                async_usleep(UHCI_CLEANER_TIMEOUT);
    216188        }
     
    223195        assert(instance);
    224196        while (1) {
    225                 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd);
    226                 const uint16_t sts = pio_read_16(&instance->registers->usbsts);
    227                 const uint16_t intr = pio_read_16(&instance->registers->usbintr);
    228                 usb_log_debug("Command: %X Status: %X Interrupts: %x\n",
    229                     cmd, sts, intr);
     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);
    230200
    231201                uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd);
    232                 if (frame_list != addr_to_phys(instance->frame_list)) {
     202                if (frame_list != (uintptr_t)addr_to_phys(instance->frame_list)) {
    233203                        usb_log_debug("Framelist address: %p vs. %p.\n",
    234204                                frame_list, addr_to_phys(instance->frame_list));
  • uspace/drv/uhci-hcd/uhci.h

    r6edc69a r374552ef  
    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 
    7368        uint16_t frnum;
    7469        uint32_t flbaseadd;
     
    8580
    8681        link_pointer_t *frame_list;
     82
     83        link_t batch_list;
     84        fibril_mutex_t batch_list_mutex;
    8785
    8886        transfer_list_t transfers_bulk_full;
     
    117115int uhci_schedule(uhci_t *instance, batch_t *batch);
    118116
    119 void uhci_interrupt(uhci_t *instance, uint16_t status);
    120 
    121117static inline uhci_t * dev_to_uhci(device_t *dev)
    122118        { return (uhci_t*)dev->driver_data; }
Note: See TracChangeset for help on using the changeset viewer.