Changeset c6394aa in mainline for uspace/drv/ohci/hc.c
- Timestamp:
- 2011-04-09T16:56:51Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 77223f8
- Parents:
- b6c9e1e (diff), 5410c04 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/hc.c
rb6c9e1e rc6394aa 47 47 static void hc_gain_control(hc_t *instance); 48 48 static void hc_init_hw(hc_t *instance); 49 static int hc_init_transfer_lists(hc_t *instance); 50 static int hc_init_memory(hc_t *instance); 49 51 /*----------------------------------------------------------------------------*/ 50 52 int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun) … … 59 61 &instance->manager, hub_address, hub_fun->handle); 60 62 63 endpoint_t *ep = malloc(sizeof(endpoint_t)); 64 assert(ep); 65 int ret = endpoint_init(ep, hub_address, 0, USB_DIRECTION_BOTH, 66 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64); 67 assert(ret == EOK); 68 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, 0); 69 assert(ret == EOK); 70 61 71 char *match_str = NULL; 62 intret = asprintf(&match_str, "usb&class=hub");63 ret = (match_str == NULL) ? ret : EOK;72 ret = asprintf(&match_str, "usb&class=hub"); 73 // ret = (match_str == NULL) ? ret : EOK; 64 74 if (ret < 0) { 65 usb_log_error("Failed to create root hub match-id string.\n"); 75 usb_log_error( 76 "Failed(%d) to create root hub match-id string.\n", ret); 66 77 return ret; 67 78 } … … 107 118 rh_init(&instance->rh, dev, instance->registers); 108 119 120 hc_init_memory(instance); 109 121 hc_init_hw(instance); 110 122 … … 117 129 assert(instance); 118 130 assert(batch); 131 132 /* check for root hub communication */ 119 133 if (batch->target.address == instance->rh.address) { 120 134 return rh_request(&instance->rh, batch); 121 135 } 122 /* TODO: implement */ 123 return ENOTSUP; 136 137 transfer_list_add_batch( 138 instance->transfers[batch->transfer_type], batch); 139 140 switch (batch->transfer_type) { 141 case USB_TRANSFER_CONTROL: 142 instance->registers->command_status |= CS_CLF; 143 break; 144 case USB_TRANSFER_BULK: 145 instance->registers->command_status |= CS_BLF; 146 break; 147 default: 148 break; 149 } 150 return EOK; 124 151 } 125 152 /*----------------------------------------------------------------------------*/ … … 134 161 usb_log_info("OHCI interrupt: %x.\n", status); 135 162 136 /* TODO: Check for further interrupt causes */ 137 /* TODO: implement */ 163 LIST_INITIALIZE(done); 164 transfer_list_remove_finished(&instance->transfers_interrupt, &done); 165 transfer_list_remove_finished(&instance->transfers_isochronous, &done); 166 transfer_list_remove_finished(&instance->transfers_control, &done); 167 transfer_list_remove_finished(&instance->transfers_bulk, &done); 168 169 while (!list_empty(&done)) { 170 link_t *item = done.next; 171 list_remove(item); 172 usb_transfer_batch_t *batch = 173 list_get_instance(item, usb_transfer_batch_t, link); 174 usb_transfer_batch_finish(batch); 175 } 138 176 } 139 177 /*----------------------------------------------------------------------------*/ … … 197 235 assert(instance); 198 236 const uint32_t fm_interval = instance->registers->fm_interval; 237 238 /* reset hc */ 199 239 instance->registers->command_status = CS_HCR; 200 240 async_usleep(10); 241 242 /* restore fm_interval */ 201 243 instance->registers->fm_interval = fm_interval; 202 244 assert((instance->registers->command_status & CS_HCR) == 0); 245 203 246 /* hc is now in suspend state */ 204 /* TODO: init HCCA block */ 205 /* TODO: initqueues */206 /* TODO: enable queues */247 248 /* enable queues */ 249 instance->registers->control |= (C_PLE | C_IE | C_CLE | C_BLE); 207 250 /* TODO: enable interrupts */ 208 /* TODO: set periodic start to 90% */ 251 /* set periodic start to 90% */ 252 instance->registers->periodic_start = (fm_interval / 10) * 9; 209 253 210 254 instance->registers->control &= (C_HCFS_OPERATIONAL << C_HCFS_SHIFT); 211 255 usb_log_info("OHCI HC up and running.\n"); 256 } 257 /*----------------------------------------------------------------------------*/ 258 int hc_init_transfer_lists(hc_t *instance) 259 { 260 assert(instance); 261 262 #define SETUP_TRANSFER_LIST(type, name) \ 263 do { \ 264 int ret = transfer_list_init(&instance->type, name); \ 265 if (ret != EOK) { \ 266 usb_log_error("Failed(%d) to setup %s transfer list.\n", \ 267 ret, name); \ 268 transfer_list_fini(&instance->transfers_isochronous); \ 269 transfer_list_fini(&instance->transfers_interrupt); \ 270 transfer_list_fini(&instance->transfers_control); \ 271 transfer_list_fini(&instance->transfers_bulk); \ 272 } \ 273 } while (0) 274 275 SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS"); 276 SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT"); 277 SETUP_TRANSFER_LIST(transfers_control, "CONTROL"); 278 SETUP_TRANSFER_LIST(transfers_bulk, "BULK"); 279 280 transfer_list_set_next(&instance->transfers_interrupt, 281 &instance->transfers_isochronous); 282 283 /* Assign pointers to be used during scheduling */ 284 instance->transfers[USB_TRANSFER_INTERRUPT] = 285 &instance->transfers_interrupt; 286 instance->transfers[USB_TRANSFER_ISOCHRONOUS] = 287 &instance->transfers_interrupt; 288 instance->transfers[USB_TRANSFER_CONTROL] = 289 &instance->transfers_control; 290 instance->transfers[USB_TRANSFER_BULK] = 291 &instance->transfers_bulk; 292 293 return EOK; 294 #undef CHECK_RET_CLEAR_RETURN 295 } 296 /*----------------------------------------------------------------------------*/ 297 int hc_init_memory(hc_t *instance) 298 { 299 assert(instance); 300 /* init queues */ 301 hc_init_transfer_lists(instance); 302 303 /* init HCCA */ 304 instance->hcca = malloc32(sizeof(hcca_t)); 305 if (instance->hcca == NULL) 306 return ENOMEM; 307 bzero(instance->hcca, sizeof(hcca_t)); 308 instance->registers->hcca = addr_to_phys(instance->hcca); 309 310 /* use queues */ 311 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 312 instance->registers->control_head = 313 instance->transfers_control.list_head_pa; 314 315 unsigned i = 0; 316 for (; i < 32; ++i) { 317 instance->hcca->int_ep[i] = 318 instance->transfers_interrupt.list_head_pa; 319 } 320 321 return EOK; 212 322 } 213 323 /**
Note:
See TracChangeset
for help on using the changeset viewer.