Changes in uspace/drv/ohci/hc.c [8148ee3a:d6522dd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/hc.c
r8148ee3a rd6522dd 43 43 44 44 #include "hc.h" 45 #include "hcd_endpoint.h" 45 46 46 47 static int interrupt_emulator(hc_t *instance); … … 67 68 &instance->manager, hub_address, hub_fun->handle); 68 69 69 ret = usb_endpoint_manager_add_ep(&instance->ep_manager, 70 hub_address, 0, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL, 71 USB_SPEED_FULL, 64, 0); 70 ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 71 USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0); 72 72 if (ret != EOK) { 73 73 usb_log_error("Failed to add OHCI rh endpoint 0.\n"); … … 109 109 ret, str_error(ret)); 110 110 111 instance->ddf_instance = fun;112 111 usb_device_keeper_init(&instance->manager); 113 112 ret = usb_endpoint_manager_init(&instance->ep_manager, … … 131 130 } 132 131 133 return EOK; 132 list_initialize(&instance->pending_batches); 133 #undef CHECK_RET_RETURN 134 return EOK; 135 } 136 /*----------------------------------------------------------------------------*/ 137 int hc_add_endpoint( 138 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint, 139 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 140 size_t mps, size_t size, unsigned interval) 141 { 142 endpoint_t *ep = malloc(sizeof(endpoint_t)); 143 if (ep == NULL) 144 return ENOMEM; 145 int ret = 146 endpoint_init(ep, address, endpoint, direction, type, speed, mps); 147 if (ret != EOK) { 148 free(ep); 149 return ret; 150 } 151 152 hcd_endpoint_t *hcd_ep = hcd_endpoint_assign(ep); 153 if (hcd_ep == NULL) { 154 endpoint_destroy(ep); 155 return ENOMEM; 156 } 157 158 ret = usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size); 159 if (ret != EOK) { 160 hcd_endpoint_clear(ep); 161 endpoint_destroy(ep); 162 return ret; 163 } 164 165 /* Enqueue hcd_ep */ 166 switch (ep->transfer_type) { 167 case USB_TRANSFER_CONTROL: 168 instance->registers->control &= ~C_CLE; 169 endpoint_list_add_ep( 170 &instance->lists[ep->transfer_type], hcd_ep); 171 instance->registers->control_current = 0; 172 instance->registers->control |= C_CLE; 173 break; 174 case USB_TRANSFER_BULK: 175 instance->registers->control &= ~C_BLE; 176 endpoint_list_add_ep( 177 &instance->lists[ep->transfer_type], hcd_ep); 178 instance->registers->control |= C_BLE; 179 break; 180 case USB_TRANSFER_ISOCHRONOUS: 181 case USB_TRANSFER_INTERRUPT: 182 instance->registers->control &= (~C_PLE & ~C_IE); 183 endpoint_list_add_ep( 184 &instance->lists[ep->transfer_type], hcd_ep); 185 instance->registers->control |= C_PLE | C_IE; 186 break; 187 default: 188 break; 189 } 190 191 return EOK; 192 } 193 /*----------------------------------------------------------------------------*/ 194 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 195 usb_endpoint_t endpoint, usb_direction_t direction) 196 { 197 assert(instance); 198 fibril_mutex_lock(&instance->guard); 199 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 200 address, endpoint, direction, NULL); 201 if (ep == NULL) { 202 usb_log_error("Endpoint unregister failed: No such EP.\n"); 203 fibril_mutex_unlock(&instance->guard); 204 return ENOENT; 205 } 206 207 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 208 if (hcd_ep) { 209 /* Dequeue hcd_ep */ 210 switch (ep->transfer_type) { 211 case USB_TRANSFER_CONTROL: 212 instance->registers->control &= ~C_CLE; 213 endpoint_list_remove_ep( 214 &instance->lists[ep->transfer_type], hcd_ep); 215 instance->registers->control_current = 0; 216 instance->registers->control |= C_CLE; 217 break; 218 case USB_TRANSFER_BULK: 219 instance->registers->control &= ~C_BLE; 220 endpoint_list_remove_ep( 221 &instance->lists[ep->transfer_type], hcd_ep); 222 instance->registers->control |= C_BLE; 223 break; 224 case USB_TRANSFER_ISOCHRONOUS: 225 case USB_TRANSFER_INTERRUPT: 226 instance->registers->control &= (~C_PLE & ~C_IE); 227 endpoint_list_remove_ep( 228 &instance->lists[ep->transfer_type], hcd_ep); 229 instance->registers->control |= C_PLE | C_IE; 230 break; 231 default: 232 break; 233 } 234 hcd_endpoint_clear(ep); 235 } else { 236 usb_log_warning("Endpoint without hcd equivalent structure.\n"); 237 } 238 int ret = usb_endpoint_manager_unregister_ep(&instance->ep_manager, 239 address, endpoint, direction); 240 fibril_mutex_unlock(&instance->guard); 241 return ret; 242 } 243 /*----------------------------------------------------------------------------*/ 244 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 245 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw) 246 { 247 assert(instance); 248 fibril_mutex_lock(&instance->guard); 249 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 250 address, endpoint, direction, bw); 251 fibril_mutex_unlock(&instance->guard); 252 return ep; 134 253 } 135 254 /*----------------------------------------------------------------------------*/ … … 146 265 147 266 fibril_mutex_lock(&instance->guard); 267 list_append(&batch->link, &instance->pending_batches); 268 batch_commit(batch); 148 269 switch (batch->ep->transfer_type) { 149 270 case USB_TRANSFER_CONTROL: 150 instance->registers->control &= ~C_CLE;151 transfer_list_add_batch(152 instance->transfers[batch->ep->transfer_type], batch);153 271 instance->registers->command_status |= CS_CLF; 154 usb_log_debug2("Set CS control transfer filled: %x.\n",155 instance->registers->command_status);156 instance->registers->control_current = 0;157 instance->registers->control |= C_CLE;158 272 break; 159 273 case USB_TRANSFER_BULK: 160 instance->registers->control &= ~C_BLE;161 transfer_list_add_batch(162 instance->transfers[batch->ep->transfer_type], batch);163 274 instance->registers->command_status |= CS_BLF; 164 usb_log_debug2("Set bulk transfer filled: %x.\n",165 instance->registers->command_status);166 instance->registers->control |= C_BLE;167 break;168 case USB_TRANSFER_INTERRUPT:169 case USB_TRANSFER_ISOCHRONOUS:170 instance->registers->control &= (~C_PLE & ~C_IE);171 transfer_list_add_batch(172 instance->transfers[batch->ep->transfer_type], batch);173 instance->registers->control |= C_PLE | C_IE;174 usb_log_debug2("Added periodic transfer: %x.\n",175 instance->registers->periodic_current);176 275 break; 177 276 default: 178 277 break; 179 278 } 279 180 280 fibril_mutex_unlock(&instance->guard); 181 281 return EOK; … … 198 298 usb_log_debug2("Periodic current: %p.\n", 199 299 instance->registers->periodic_current); 200 LIST_INITIALIZE(done); 201 transfer_list_remove_finished( 202 &instance->transfers_interrupt, &done); 203 transfer_list_remove_finished( 204 &instance->transfers_isochronous, &done); 205 transfer_list_remove_finished( 206 &instance->transfers_control, &done); 207 transfer_list_remove_finished( 208 &instance->transfers_bulk, &done); 209 210 while (!list_empty(&done)) { 211 link_t *item = done.next; 212 list_remove(item); 300 301 link_t *current = instance->pending_batches.next; 302 while (current != &instance->pending_batches) { 303 link_t *next = current->next; 213 304 usb_transfer_batch_t *batch = 214 list_get_instance(item, usb_transfer_batch_t, link); 215 usb_transfer_batch_finish(batch); 305 usb_transfer_batch_from_link(current); 306 307 if (batch_is_complete(batch)) { 308 list_remove(current); 309 usb_transfer_batch_finish(batch); 310 } 311 current = next; 216 312 } 217 313 fibril_mutex_unlock(&instance->guard); … … 307 403 308 404 /* Use queues */ 309 instance->registers->bulk_head = instance->transfers_bulk.list_head_pa; 405 instance->registers->bulk_head = 406 instance->lists[USB_TRANSFER_BULK].list_head_pa; 310 407 usb_log_debug2("Bulk HEAD set to: %p(%p).\n", 311 instance-> transfers_bulk.list_head,312 instance-> transfers_bulk.list_head_pa);408 instance->lists[USB_TRANSFER_BULK].list_head, 409 instance->lists[USB_TRANSFER_BULK].list_head_pa); 313 410 314 411 instance->registers->control_head = 315 instance-> transfers_control.list_head_pa;412 instance->lists[USB_TRANSFER_CONTROL].list_head_pa; 316 413 usb_log_debug2("Control HEAD set to: %p(%p).\n", 317 instance-> transfers_control.list_head,318 instance-> transfers_control.list_head_pa);414 instance->lists[USB_TRANSFER_CONTROL].list_head, 415 instance->lists[USB_TRANSFER_CONTROL].list_head_pa); 319 416 320 417 /* Enable queues */ … … 347 444 assert(instance); 348 445 349 #define SETUP_ TRANSFER_LIST(type, name) \446 #define SETUP_ENDPOINT_LIST(type) \ 350 447 do { \ 351 int ret = transfer_list_init(&instance->type, name); \ 448 const char *name = usb_str_transfer_type(type); \ 449 int ret = endpoint_list_init(&instance->lists[type], name); \ 352 450 if (ret != EOK) { \ 353 usb_log_error("Failed(%d) to setup %s transferlist.\n", \451 usb_log_error("Failed(%d) to setup %s endpoint list.\n", \ 354 452 ret, name); \ 355 transfer_list_fini(&instance->transfers_isochronous); \356 transfer_list_fini(&instance->transfers_interrupt); \357 transfer_list_fini(&instance->transfers_control); \358 transfer_list_fini(&instance->transfers_bulk); \453 endpoint_list_fini(&instance->lists[USB_TRANSFER_ISOCHRONOUS]); \ 454 endpoint_list_fini(&instance->lists[USB_TRANSFER_INTERRUPT]); \ 455 endpoint_list_fini(&instance->lists[USB_TRANSFER_CONTROL]); \ 456 endpoint_list_fini(&instance->lists[USB_TRANSFER_BULK]); \ 359 457 } \ 360 458 } while (0) 361 459 362 SETUP_TRANSFER_LIST(transfers_isochronous, "ISOCHRONOUS"); 363 SETUP_TRANSFER_LIST(transfers_interrupt, "INTERRUPT"); 364 SETUP_TRANSFER_LIST(transfers_control, "CONTROL"); 365 SETUP_TRANSFER_LIST(transfers_bulk, "BULK"); 366 #undef SETUP_TRANSFER_LIST 367 transfer_list_set_next(&instance->transfers_interrupt, 368 &instance->transfers_isochronous); 369 370 /* Assign pointers to be used during scheduling */ 371 instance->transfers[USB_TRANSFER_INTERRUPT] = 372 &instance->transfers_interrupt; 373 instance->transfers[USB_TRANSFER_ISOCHRONOUS] = 374 &instance->transfers_interrupt; 375 instance->transfers[USB_TRANSFER_CONTROL] = 376 &instance->transfers_control; 377 instance->transfers[USB_TRANSFER_BULK] = 378 &instance->transfers_bulk; 460 SETUP_ENDPOINT_LIST(USB_TRANSFER_ISOCHRONOUS); 461 SETUP_ENDPOINT_LIST(USB_TRANSFER_INTERRUPT); 462 SETUP_ENDPOINT_LIST(USB_TRANSFER_CONTROL); 463 SETUP_ENDPOINT_LIST(USB_TRANSFER_BULK); 464 #undef SETUP_ENDPOINT_LIST 465 endpoint_list_set_next(&instance->lists[USB_TRANSFER_INTERRUPT], 466 &instance->lists[USB_TRANSFER_ISOCHRONOUS]); 379 467 380 468 return EOK; … … 397 485 for (; i < 32; ++i) { 398 486 instance->hcca->int_ep[i] = 399 instance-> transfers_interrupt.list_head_pa;487 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa; 400 488 } 401 489 usb_log_debug2("Interrupt HEADs set to: %p(%p).\n", 402 instance-> transfers_interrupt.list_head,403 instance-> transfers_interrupt.list_head_pa);490 instance->lists[USB_TRANSFER_INTERRUPT].list_head, 491 instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa); 404 492 405 493 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.