Changeset f1d6866 in mainline for uspace/drv/bus/usb/ohci/hc.c
- Timestamp:
- 2011-09-18T21:22:59Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- dcc44ca1
- Parents:
- 85ff862 (diff), 45a9cf4 (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/bus/usb/ohci/hc.c
r85ff862 rf1d6866 42 42 43 43 #include "hc.h" 44 #include " hcd_endpoint.h"44 #include "ohci_endpoint.h" 45 45 46 46 #define OHCI_USED_INTERRUPTS \ … … 61 61 static int hc_init_memory(hc_t *instance); 62 62 static int interrupt_emulator(hc_t *instance); 63 63 static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch); 64 64 /*----------------------------------------------------------------------------*/ 65 65 /** Get number of commands used in IRQ code. … … 128 128 129 129 const usb_address_t hub_address = 130 device_keeper_get_free_address(&instance->manager, USB_SPEED_FULL); 130 usb_device_manager_get_free_address( 131 &instance->generic.dev_manager, USB_SPEED_FULL); 131 132 if (hub_address <= 0) { 132 133 usb_log_error("Failed to get OHCI root hub address: %s\n", … … 135 136 } 136 137 instance->rh.address = hub_address; 137 usb_device_ keeper_bind(138 &instance-> manager, hub_address, hub_fun->handle);139 140 #define CHECK_RET_ RELEASE(ret, message...) \138 usb_device_manager_bind( 139 &instance->generic.dev_manager, hub_address, hub_fun->handle); 140 141 #define CHECK_RET_UNREG_RETURN(ret, message...) \ 141 142 if (ret != EOK) { \ 142 143 usb_log_error(message); \ 143 hc_remove_endpoint(instance, hub_address, 0, USB_DIRECTION_BOTH); \ 144 usb_device_keeper_release(&instance->manager, hub_address); \ 144 usb_endpoint_manager_unregister_ep( \ 145 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH);\ 146 usb_device_manager_release( \ 147 &instance->generic.dev_manager, hub_address); \ 145 148 return ret; \ 146 149 } else (void)0 147 148 int ret = hc_add_endpoint(instance, hub_address, 0, USB_SPEED_FULL, 149 USB_TRANSFER_CONTROL, USB_DIRECTION_BOTH, 64, 0, 0); 150 CHECK_RET_RELEASE(ret, 151 "Failed to add OHCI root hub endpoint 0: %s.\n", str_error(ret)); 150 int ret = usb_endpoint_manager_add_ep( 151 &instance->generic.ep_manager, hub_address, 0, USB_DIRECTION_BOTH, 152 USB_TRANSFER_CONTROL, USB_SPEED_FULL, 64, 0); 153 CHECK_RET_UNREG_RETURN(ret, 154 "Failed to register root hub control endpoint: %s.\n", 155 str_error(ret)); 152 156 153 157 ret = ddf_fun_add_match_id(hub_fun, "usb&class=hub", 100); 154 CHECK_RET_ RELEASE(ret,158 CHECK_RET_UNREG_RETURN(ret, 155 159 "Failed to add root hub match-id: %s.\n", str_error(ret)); 156 160 157 161 ret = ddf_fun_bind(hub_fun); 158 CHECK_RET_ RELEASE(ret,162 CHECK_RET_UNREG_RETURN(ret, 159 163 "Failed to bind root hub function: %s.\n", str_error(ret)); 160 164 … … 187 191 188 192 list_initialize(&instance->pending_batches); 189 usb_device_keeper_init(&instance->manager); 190 191 ret = usb_endpoint_manager_init(&instance->ep_manager, 192 BANDWIDTH_AVAILABLE_USB11); 193 CHECK_RET_RETURN(ret, "Failed to initialize endpoint manager: %s.\n", 193 194 ret = hcd_init(&instance->generic, BANDWIDTH_AVAILABLE_USB11, 195 bandwidth_count_usb11); 196 CHECK_RET_RETURN(ret, "Failed to initialize generic driver: %s.\n", 194 197 str_error(ret)); 198 instance->generic.private_data = instance; 199 instance->generic.schedule = hc_schedule; 200 instance->generic.ep_add_hook = ohci_endpoint_init; 195 201 196 202 ret = hc_init_memory(instance); … … 215 221 } 216 222 /*----------------------------------------------------------------------------*/ 217 /** Create and register endpoint structures. 218 * 219 * @param[in] instance OHCI driver structure. 220 * @param[in] address USB address of the device. 221 * @param[in] endpoint USB endpoint number. 222 * @param[in] speed Communication speeed of the device. 223 * @param[in] type Endpoint's transfer type. 224 * @param[in] direction Endpoint's direction. 225 * @param[in] mps Maximum packet size the endpoint accepts. 226 * @param[in] size Maximum allowed buffer size. 227 * @param[in] interval Time between transfers(interrupt transfers only). 228 * @return Error code 229 */ 230 int hc_add_endpoint( 231 hc_t *instance, usb_address_t address, usb_endpoint_t endpoint, 232 usb_speed_t speed, usb_transfer_type_t type, usb_direction_t direction, 233 size_t mps, size_t size, unsigned interval) 234 { 235 endpoint_t *ep = 236 endpoint_get(address, endpoint, direction, type, speed, mps); 237 if (ep == NULL) 238 return ENOMEM; 239 240 hcd_endpoint_t *hcd_ep = hcd_endpoint_assign(ep); 241 if (hcd_ep == NULL) { 242 endpoint_destroy(ep); 243 return ENOMEM; 244 } 245 246 int ret = 247 usb_endpoint_manager_register_ep(&instance->ep_manager, ep, size); 248 if (ret != EOK) { 249 hcd_endpoint_clear(ep); 250 endpoint_destroy(ep); 251 return ret; 252 } 253 254 /* Enqueue hcd_ep */ 223 void hc_enqueue_endpoint(hc_t *instance, endpoint_t *ep) 224 { 225 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 226 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 227 /* Enqueue ep */ 255 228 switch (ep->transfer_type) { 256 229 case USB_TRANSFER_CONTROL: 257 230 instance->registers->control &= ~C_CLE; 258 endpoint_list_add_ep( 259 &instance->lists[ep->transfer_type], hcd_ep); 231 endpoint_list_add_ep(list, ohci_ep); 260 232 instance->registers->control_current = 0; 261 233 instance->registers->control |= C_CLE; … … 263 235 case USB_TRANSFER_BULK: 264 236 instance->registers->control &= ~C_BLE; 265 endpoint_list_add_ep( 266 &instance->lists[ep->transfer_type], hcd_ep); 237 endpoint_list_add_ep(list, ohci_ep); 267 238 instance->registers->control |= C_BLE; 268 239 break; … … 270 241 case USB_TRANSFER_INTERRUPT: 271 242 instance->registers->control &= (~C_PLE & ~C_IE); 272 endpoint_list_add_ep( 273 &instance->lists[ep->transfer_type], hcd_ep); 243 endpoint_list_add_ep(list, ohci_ep); 274 244 instance->registers->control |= C_PLE | C_IE; 275 245 break; 276 246 } 277 278 return EOK; 279 } 280 /*----------------------------------------------------------------------------*/ 281 /** Dequeue and delete endpoint structures 282 * 283 * @param[in] instance OHCI hc driver structure. 284 * @param[in] address USB address of the device. 285 * @param[in] endpoint USB endpoint number. 286 * @param[in] direction Direction of the endpoint. 287 * @return Error code 288 */ 289 int hc_remove_endpoint(hc_t *instance, usb_address_t address, 290 usb_endpoint_t endpoint, usb_direction_t direction) 291 { 292 assert(instance); 293 fibril_mutex_lock(&instance->guard); 294 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 295 address, endpoint, direction, NULL); 296 if (ep == NULL) { 297 usb_log_error("Endpoint unregister failed: No such EP.\n"); 298 fibril_mutex_unlock(&instance->guard); 299 return ENOENT; 300 } 301 302 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 303 if (hcd_ep) { 304 /* Dequeue hcd_ep */ 305 switch (ep->transfer_type) { 306 case USB_TRANSFER_CONTROL: 307 instance->registers->control &= ~C_CLE; 308 endpoint_list_remove_ep( 309 &instance->lists[ep->transfer_type], hcd_ep); 310 instance->registers->control_current = 0; 311 instance->registers->control |= C_CLE; 312 break; 313 case USB_TRANSFER_BULK: 314 instance->registers->control &= ~C_BLE; 315 endpoint_list_remove_ep( 316 &instance->lists[ep->transfer_type], hcd_ep); 317 instance->registers->control |= C_BLE; 318 break; 319 case USB_TRANSFER_ISOCHRONOUS: 320 case USB_TRANSFER_INTERRUPT: 321 instance->registers->control &= (~C_PLE & ~C_IE); 322 endpoint_list_remove_ep( 323 &instance->lists[ep->transfer_type], hcd_ep); 324 instance->registers->control |= C_PLE | C_IE; 325 break; 326 default: 327 break; 328 } 329 hcd_endpoint_clear(ep); 330 } else { 331 usb_log_warning("Endpoint without hcd equivalent structure.\n"); 332 } 333 int ret = usb_endpoint_manager_unregister_ep(&instance->ep_manager, 334 address, endpoint, direction); 335 fibril_mutex_unlock(&instance->guard); 336 return ret; 337 } 338 /*----------------------------------------------------------------------------*/ 339 /** Get access to endpoint structures 340 * 341 * @param[in] instance OHCI hc driver structure. 342 * @param[in] address USB address of the device. 343 * @param[in] endpoint USB endpoint number. 344 * @param[in] direction Direction of the endpoint. 345 * @param[out] bw Reserved bandwidth. 346 * @return Error code 347 */ 348 endpoint_t * hc_get_endpoint(hc_t *instance, usb_address_t address, 349 usb_endpoint_t endpoint, usb_direction_t direction, size_t *bw) 350 { 351 assert(instance); 352 fibril_mutex_lock(&instance->guard); 353 endpoint_t *ep = usb_endpoint_manager_get_ep(&instance->ep_manager, 354 address, endpoint, direction, bw); 355 fibril_mutex_unlock(&instance->guard); 356 return ep; 247 } 248 /*----------------------------------------------------------------------------*/ 249 void hc_dequeue_endpoint(hc_t *instance, endpoint_t *ep) 250 { 251 /* Dequeue ep */ 252 endpoint_list_t *list = &instance->lists[ep->transfer_type]; 253 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep); 254 switch (ep->transfer_type) { 255 case USB_TRANSFER_CONTROL: 256 instance->registers->control &= ~C_CLE; 257 endpoint_list_remove_ep(list, ohci_ep); 258 instance->registers->control_current = 0; 259 instance->registers->control |= C_CLE; 260 break; 261 case USB_TRANSFER_BULK: 262 instance->registers->control &= ~C_BLE; 263 endpoint_list_remove_ep(list, ohci_ep); 264 instance->registers->control |= C_BLE; 265 break; 266 case USB_TRANSFER_ISOCHRONOUS: 267 case USB_TRANSFER_INTERRUPT: 268 instance->registers->control &= (~C_PLE & ~C_IE); 269 endpoint_list_remove_ep(list, ohci_ep); 270 instance->registers->control |= C_PLE | C_IE; 271 break; 272 default: 273 break; 274 } 357 275 } 358 276 /*----------------------------------------------------------------------------*/ … … 363 281 * @return Error code. 364 282 */ 365 int hc_schedule(hc _t *instance, usb_transfer_batch_t *batch)366 { 367 assert( instance);368 assert(batch);369 assert( batch->ep);283 int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch) 284 { 285 assert(hcd); 286 hc_t *instance = hcd->private_data; 287 assert(instance); 370 288 371 289 /* Check for root hub communication */ … … 374 292 return EOK; 375 293 } 294 ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch); 295 if (!ohci_batch) 296 return ENOMEM; 376 297 377 298 fibril_mutex_lock(&instance->guard); 378 list_append(& batch->link, &instance->pending_batches);379 batch_commit(batch);299 list_append(&ohci_batch->link, &instance->pending_batches); 300 ohci_transfer_batch_commit(ohci_batch); 380 301 381 302 /* Control and bulk schedules need a kick to start working */ … … 417 338 instance->registers->periodic_current); 418 339 419 link_t *current = instance->pending_batches.head.next;420 while (current != &instance->pending_batches.head) {340 link_t *current = list_first(&instance->pending_batches); 341 while (current && current != &instance->pending_batches.head) { 421 342 link_t *next = current->next; 422 usb_transfer_batch_t *batch =423 usb_transfer_batch_from_link(current);424 425 if ( batch_is_complete(batch)) {343 ohci_transfer_batch_t *batch = 344 ohci_transfer_batch_from_link(current); 345 346 if (ohci_transfer_batch_is_complete(batch)) { 426 347 list_remove(current); 427 usb_transfer_batch_finish(batch);348 ohci_transfer_batch_finish_dispose(batch); 428 349 } 429 350 … … 434 355 435 356 if (status & I_UE) { 357 usb_log_fatal("Error like no other!\n"); 436 358 hc_start(instance); 437 359 }
Note:
See TracChangeset
for help on using the changeset viewer.