Changeset 3e200736 in mainline


Ignore:
Timestamp:
2014-01-18T21:34:32Z (10 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a5361fb
Parents:
e26a9d95
Message:

uhci,ohci, ehci: Move interrupt replacement fibril to libusbhost

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/hc.c

    re26a9d95 r3e200736  
    9292static void hc_start(hc_t *instance);
    9393static int hc_init_memory(hc_t *instance);
    94 static int interrupt_emulator(hc_t *instance);
    9594
    9695/** Generate IRQ code.
     
    191190        hc_gain_control(instance);
    192191
    193         if (!interrupts) {
    194                 instance->interrupt_emulator =
    195                     fibril_create((int(*)(void*))interrupt_emulator, instance);
    196                 fibril_add_ready(instance->interrupt_emulator);
    197         }
    198 
    199192        ehci_rh_init(
    200193            &instance->rh, instance->caps, instance->registers, "ehci rh");
     
    256249}
    257250
    258 /** Check status register regularly
    259  *
    260  * @param[in] instance EHCI hc driver structure.
    261  * @return Error code
    262  */
    263 int interrupt_emulator(hc_t *instance)
    264 {
    265         assert(instance);
    266         usb_log_info("Started interrupt emulator.\n");
    267         while (1) {
    268 //              const uint32_t status = instance->registers->interrupt_status;
    269 //              instance->registers->interrupt_status = status;
    270 //              hc_interrupt(instance, status);
    271                 async_usleep(10000);
    272         }
    273         return EOK;
    274 }
    275 
    276251/** Turn off any (BIOS)driver that might be in control of the device.
    277252 *
  • uspace/drv/bus/usb/ehci/hc.h

    re26a9d95 r3e200736  
    6464        list_t pending_batches;
    6565
    66         /** Fibril for periodic checks if interrupts can't be used */
    67         fid_t interrupt_emulator;
    68 
    6966        /** Guards schedule and endpoint manipulation */
    7067        fibril_mutex_t guard;
  • uspace/drv/bus/usb/ohci/hc.c

    re26a9d95 r3e200736  
    9393static int hc_init_transfer_lists(hc_t *instance);
    9494static int hc_init_memory(hc_t *instance);
    95 static int interrupt_emulator(hc_t *instance);
    9695
    9796/** Generate IRQ code.
     
    182181
    183182        hc_gain_control(instance);
    184 
    185         if (!interrupts) {
    186                 instance->interrupt_emulator =
    187                     fibril_create((int(*)(void*))interrupt_emulator, instance);
    188                 fibril_add_ready(instance->interrupt_emulator);
    189         }
    190183
    191184        ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
     
    280273        assert(instance);
    281274
    282         async_usleep(10000);
    283275        if (instance->registers){
    284276                *status = OHCI_RD(instance->registers->interrupt_status);
     
    373365        }
    374366
    375 }
    376 
    377 /** Check status register regularly
    378  *
    379  * @param[in] instance OHCI hc driver structure.
    380  * @return Error code
    381  */
    382 int interrupt_emulator(hc_t *instance)
    383 {
    384         assert(instance);
    385         usb_log_info("Started interrupt emulator.\n");
    386         while (1) {
    387                 const uint32_t status = instance->registers->interrupt_status;
    388                 instance->registers->interrupt_status = status;
    389                 hc_interrupt(instance, status);
    390                 async_usleep(10000);
    391         }
    392         return EOK;
    393367}
    394368
  • uspace/drv/bus/usb/uhci/hc.c

    re26a9d95 r3e200736  
    9696static int hc_init_transfer_lists(hc_t *instance);
    9797
    98 static int hc_interrupt_emulator(void *arg);
    9998static int hc_debug_checker(void *arg);
    10099
     
    245244
    246245        hc_init_hw(instance);
    247         if (!interrupts) {
    248                 instance->interrupt_emulator =
    249                     fibril_create(hc_interrupt_emulator, instance);
    250                 fibril_add_ready(instance->interrupt_emulator);
    251         }
    252246        (void)hc_debug_checker;
    253247
     
    460454}
    461455
    462 /** Polling function, emulates interrupts.
    463  *
    464  * @param[in] arg UHCI hc structure to use.
    465  * @return EOK (should never return)
    466  */
    467 int hc_interrupt_emulator(void* arg)
    468 {
    469         usb_log_debug("Started interrupt emulator.\n");
    470         hc_t *instance = arg;
    471         assert(instance);
    472 
    473         while (1) {
    474                 /* Read and clear status register */
    475                 uint16_t status = pio_read_16(&instance->registers->usbsts);
    476                 pio_write_16(&instance->registers->usbsts, status);
    477                 if (status != 0)
    478                         usb_log_debug2("UHCI status: %x.\n", status);
    479                 hc_interrupt(instance, status);
    480                 async_usleep(UHCI_INT_EMULATOR_TIMEOUT);
    481         }
    482         return EOK;
    483 }
    484 
    485456/** Debug function, checks consistency of memory structures.
    486457 *
  • uspace/drv/bus/usb/uhci/hc.h

    re26a9d95 r3e200736  
    9393
    9494#define UHCI_FRAME_LIST_COUNT 1024
    95 #define UHCI_INT_EMULATOR_TIMEOUT 10000
    9695#define UHCI_DEBUGER_TIMEOUT 5000000
    9796#define UHCI_ALLOWED_HW_FAIL 5
    98 #define UHCI_NEEDED_IRQ_COMMANDS 5
    9997
    10098/** Main UHCI driver structure */
     
    118116        /** Pointer table to the above lists, helps during scheduling */
    119117        transfer_list_t *transfers[2][4];
    120         /** Fibril periodically checking status register*/
    121         fid_t interrupt_emulator;
    122118        /** Indicator of hw interrupts availability */
    123119        bool hw_interrupts;
  • uspace/lib/usbhost/include/usb/host/hcd.h

    re26a9d95 r3e200736  
    7676        /** Driver implementation */
    7777        hc_driver_t driver;
     78
     79        /** Interrupt replacement fibril */
     80        fid_t polling_fibril;
    7881};
    7982
  • uspace/lib/usbhost/src/ddf_helpers.c

    re26a9d95 r3e200736  
    717717
    718718        assert(device);
    719         assert(hw_res);
    720         assert(handler);
    721         assert(gen_irq_code);
     719        if (!handler || !gen_irq_code)
     720                return ENOTSUP;
    722721
    723722        irq_code_t irq_code = {0};
     
    768767        hcd->driver.irq_hook(hcd, status);
    769768}
     769
     770static int interrupt_polling(void *arg)
     771{
     772        hcd_t *hcd = arg;
     773        assert(hcd);
     774        if (!hcd->driver.status_hook || !hcd->driver.irq_hook)
     775                return ENOTSUP;
     776        uint32_t status = 0;
     777        while (hcd->driver.status_hook(hcd, &status) == EOK) {
     778                hcd->driver.irq_hook(hcd, status);
     779                status = 0;
     780                /* We should wait 1 frame - 1ms here, but this polling is a
     781                 * lame crutch anyway so don't hog the system. 10ms is still
     782                 * good enough for emergency mode */
     783                async_usleep(10000);
     784        }
     785        return EOK;
     786}
     787
    770788/** Initialize hc and rh DDF structures and their respective drivers.
    771789 *
     
    816834        const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler,
    817835            gen_irq_code);
    818         if (irq < 0) {
     836        if (!(irq < 0)) {
     837                usb_log_debug("Hw interrupts enabled.\n");
     838        }
     839
     840        /* Init hw driver */
     841        hcd_t *hcd = dev_to_hcd(device);
     842        ret = driver_init(hcd, &hw_res, !(irq < 0));
     843        hw_res_list_parsed_clean(&hw_res);
     844        if (ret != EOK) {
     845                usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(ret));
     846                goto irq_unregister;
     847        }
     848
     849        /* Need working irq replacement to setup root hub */
     850        if ((irq < 0) && hcd->driver.status_hook) {
     851                hcd->polling_fibril = fibril_create(interrupt_polling, hcd);
     852                if (hcd->polling_fibril == 0) {
     853                        usb_log_error("Failed to create polling fibril\n");
     854                        ret = ENOMEM;
     855                        goto irq_unregister;
     856                }
     857                fibril_add_ready(hcd->polling_fibril);
    819858                usb_log_warning("Failed to enable interrupts: %s."
    820859                    " Falling back to polling.\n", str_error(irq));
    821         } else {
    822                 usb_log_debug("Hw interrupts enabled.\n");
    823         }
    824 
    825         /* Init hw driver */
    826         ret = driver_init(dev_to_hcd(device), &hw_res, !(irq < 0));
    827         hw_res_list_parsed_clean(&hw_res);
    828         if (ret != EOK) {
    829                 usb_log_error("Failed to init uhci_hcd: %s.\n", str_error(ret));
    830                 goto irq_unregister;
    831860        }
    832861
Note: See TracChangeset for help on using the changeset viewer.