Changeset 3e200736 in mainline
- Timestamp:
- 2014-01-18T21:34:32Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a5361fb
- Parents:
- e26a9d95
- Location:
- uspace
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/hc.c
re26a9d95 r3e200736 92 92 static void hc_start(hc_t *instance); 93 93 static int hc_init_memory(hc_t *instance); 94 static int interrupt_emulator(hc_t *instance);95 94 96 95 /** Generate IRQ code. … … 191 190 hc_gain_control(instance); 192 191 193 if (!interrupts) {194 instance->interrupt_emulator =195 fibril_create((int(*)(void*))interrupt_emulator, instance);196 fibril_add_ready(instance->interrupt_emulator);197 }198 199 192 ehci_rh_init( 200 193 &instance->rh, instance->caps, instance->registers, "ehci rh"); … … 256 249 } 257 250 258 /** Check status register regularly259 *260 * @param[in] instance EHCI hc driver structure.261 * @return Error code262 */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 276 251 /** Turn off any (BIOS)driver that might be in control of the device. 277 252 * -
uspace/drv/bus/usb/ehci/hc.h
re26a9d95 r3e200736 64 64 list_t pending_batches; 65 65 66 /** Fibril for periodic checks if interrupts can't be used */67 fid_t interrupt_emulator;68 69 66 /** Guards schedule and endpoint manipulation */ 70 67 fibril_mutex_t guard; -
uspace/drv/bus/usb/ohci/hc.c
re26a9d95 r3e200736 93 93 static int hc_init_transfer_lists(hc_t *instance); 94 94 static int hc_init_memory(hc_t *instance); 95 static int interrupt_emulator(hc_t *instance);96 95 97 96 /** Generate IRQ code. … … 182 181 183 182 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 }190 183 191 184 ohci_rh_init(&instance->rh, instance->registers, "ohci rh"); … … 280 273 assert(instance); 281 274 282 async_usleep(10000);283 275 if (instance->registers){ 284 276 *status = OHCI_RD(instance->registers->interrupt_status); … … 373 365 } 374 366 375 }376 377 /** Check status register regularly378 *379 * @param[in] instance OHCI hc driver structure.380 * @return Error code381 */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;393 367 } 394 368 -
uspace/drv/bus/usb/uhci/hc.c
re26a9d95 r3e200736 96 96 static int hc_init_transfer_lists(hc_t *instance); 97 97 98 static int hc_interrupt_emulator(void *arg);99 98 static int hc_debug_checker(void *arg); 100 99 … … 245 244 246 245 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 }252 246 (void)hc_debug_checker; 253 247 … … 460 454 } 461 455 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 485 456 /** Debug function, checks consistency of memory structures. 486 457 * -
uspace/drv/bus/usb/uhci/hc.h
re26a9d95 r3e200736 93 93 94 94 #define UHCI_FRAME_LIST_COUNT 1024 95 #define UHCI_INT_EMULATOR_TIMEOUT 1000096 95 #define UHCI_DEBUGER_TIMEOUT 5000000 97 96 #define UHCI_ALLOWED_HW_FAIL 5 98 #define UHCI_NEEDED_IRQ_COMMANDS 599 97 100 98 /** Main UHCI driver structure */ … … 118 116 /** Pointer table to the above lists, helps during scheduling */ 119 117 transfer_list_t *transfers[2][4]; 120 /** Fibril periodically checking status register*/121 fid_t interrupt_emulator;122 118 /** Indicator of hw interrupts availability */ 123 119 bool hw_interrupts; -
uspace/lib/usbhost/include/usb/host/hcd.h
re26a9d95 r3e200736 76 76 /** Driver implementation */ 77 77 hc_driver_t driver; 78 79 /** Interrupt replacement fibril */ 80 fid_t polling_fibril; 78 81 }; 79 82 -
uspace/lib/usbhost/src/ddf_helpers.c
re26a9d95 r3e200736 717 717 718 718 assert(device); 719 assert(hw_res); 720 assert(handler); 721 assert(gen_irq_code); 719 if (!handler || !gen_irq_code) 720 return ENOTSUP; 722 721 723 722 irq_code_t irq_code = {0}; … … 768 767 hcd->driver.irq_hook(hcd, status); 769 768 } 769 770 static 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 770 788 /** Initialize hc and rh DDF structures and their respective drivers. 771 789 * … … 816 834 const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler, 817 835 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); 819 858 usb_log_warning("Failed to enable interrupts: %s." 820 859 " 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;831 860 } 832 861
Note:
See TracChangeset
for help on using the changeset viewer.