Changes in uspace/drv/ohci/hc.c [53f1c87:049eb87] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/hc.c
r53f1c87 r049eb87 45 45 46 46 static int interrupt_emulator(hc_t *instance); 47 static void hc_gain_control(hc_t *instance); 48 static void hc_init_hw(hc_t *instance); 47 49 /*----------------------------------------------------------------------------*/ 48 50 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) … … 58 60 59 61 char *match_str = NULL; 60 int ret = asprintf(&match_str, "usb& mid");62 int ret = asprintf(&match_str, "usb&class=hub"); 61 63 ret = (match_str == NULL) ? ret : EOK; 62 64 if (ret < 0) { … … 77 79 assert(instance); 78 80 int ret = EOK; 81 #define CHECK_RET_RETURN(ret, message...) \ 82 if (ret != EOK) { \ 83 usb_log_error(message); \ 84 return ret; \ 85 } else (void)0 79 86 80 87 ret = pio_enable((void*)regs, reg_size, (void**)&instance->registers); 81 if (ret != EOK) {82 usb_log_error("Failed to gain access to device registers.\n");83 return ret;84 } 88 CHECK_RET_RETURN(ret, 89 "Failed(%d) to gain access to device registers: %s.\n", 90 ret, str_error(ret)); 91 85 92 instance->ddf_instance = fun; 86 93 usb_device_keeper_init(&instance->manager); 94 ret = usb_endpoint_manager_init(&instance->ep_manager, 95 BANDWIDTH_AVAILABLE_USB11); 96 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 97 ret, str_error(ret)); 87 98 88 99 if (!interrupts) { … … 92 103 } 93 104 105 hc_gain_control(instance); 106 94 107 rh_init(&instance->rh, dev, instance->registers); 108 109 hc_init_hw(instance); 95 110 96 111 /* TODO: implement */ … … 117 132 rh_interrupt(&instance->rh); 118 133 134 usb_log_info("OHCI interrupt: %x.\n", status); 135 119 136 /* TODO: Check for further interrupt causes */ 120 137 /* TODO: implement */ … … 126 143 usb_log_info("Started interrupt emulator.\n"); 127 144 while (1) { 128 uint32_t status = instance->registers->interrupt_status;145 const uint32_t status = instance->registers->interrupt_status; 129 146 instance->registers->interrupt_status = status; 130 147 hc_interrupt(instance, status); … … 133 150 return EOK; 134 151 } 152 /*----------------------------------------------------------------------------*/ 153 void hc_gain_control(hc_t *instance) 154 { 155 assert(instance); 156 /* Interrupt routing enabled => smm driver is active */ 157 if (instance->registers->control & C_IR) { 158 usb_log_info("Found SMM driver requesting ownership change.\n"); 159 instance->registers->command_status |= CS_OCR; 160 while (instance->registers->control & C_IR) { 161 async_usleep(1000); 162 } 163 usb_log_info("Ownership taken from SMM driver.\n"); 164 return; 165 } 166 167 const unsigned hc_status = 168 (instance->registers->control >> C_HCFS_SHIFT) & C_HCFS_MASK; 169 /* Interrupt routing disabled && status != USB_RESET => BIOS active */ 170 if (hc_status != C_HCFS_RESET) { 171 usb_log_info("Found BIOS driver.\n"); 172 if (hc_status == C_HCFS_OPERATIONAL) { 173 usb_log_info("HC operational(BIOS).\n"); 174 return; 175 } 176 /* HC is suspended assert resume for 20ms */ 177 instance->registers->control &= (C_HCFS_RESUME << C_HCFS_SHIFT); 178 async_usleep(20000); 179 return; 180 } 181 182 /* HC is in reset (hw startup) => no other driver 183 * maintain reset for at least the time specified in USB spec (50 ms)*/ 184 async_usleep(50000); 185 186 /* turn off legacy emulation */ 187 volatile uint32_t *ohci_emulation_reg = 188 (uint32_t*)((char*)instance->registers + 0x100); 189 usb_log_info("OHCI legacy register status %p: %x.\n", 190 ohci_emulation_reg, *ohci_emulation_reg); 191 *ohci_emulation_reg = 0; 192 193 } 194 /*----------------------------------------------------------------------------*/ 195 void hc_init_hw(hc_t *instance) 196 { 197 assert(instance); 198 const uint32_t fm_interval = instance->registers->fm_interval; 199 instance->registers->command_status = CS_HCR; 200 async_usleep(10); 201 instance->registers->fm_interval = fm_interval; 202 assert((instance->registers->command_status & CS_HCR) == 0); 203 /* hc is now in suspend state */ 204 /* TODO: init HCCA block */ 205 /* TODO: init queues */ 206 /* TODO: enable queues */ 207 /* TODO: enable interrupts */ 208 /* TODO: set periodic start to 90% */ 209 210 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT); 211 usb_log_info("OHCI HC up and running.\n"); 212 } 135 213 /** 136 214 * @}
Note:
See TracChangeset
for help on using the changeset viewer.