Changeset df6ded8 in mainline for uspace/drv/bus/usb/ohci/ohci_rh.c
- Timestamp:
- 2018-02-28T16:37:50Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1b20da0
- Parents:
- f5e5f73 (diff), b2dca8de (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. - git-author:
- Jakub Jermar <jakub@…> (2018-02-28 16:06:42)
- git-committer:
- Jakub Jermar <jakub@…> (2018-02-28 16:37:50)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci_rh.c
rf5e5f73 rdf6ded8 1 1 /* 2 2 * Copyright (c) 2013 Jan Vesely 3 * Copyright (c) 2018 Ondrej Hlavaty 3 4 * All rights reserved. 4 5 * … … 109 110 * initializes internal virtual hub. 110 111 */ 111 errno_t ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs, const char *name) 112 errno_t ohci_rh_init(ohci_rh_t *instance, ohci_regs_t *regs, 113 fibril_mutex_t *guard, const char *name) 112 114 { 113 115 assert(instance); 114 116 instance->registers = regs; 115 117 instance->port_count = OHCI_RD(regs->rh_desc_a) & RHDA_NDS_MASK; 116 usb_log_debug2("rh_desc_a: %x. \n", OHCI_RD(regs->rh_desc_a));118 usb_log_debug2("rh_desc_a: %x.", OHCI_RD(regs->rh_desc_a)); 117 119 if (instance->port_count > OHCI_MAX_PORTS) { 118 120 usb_log_warning("OHCI specification does not allow %d ports. " 119 "Max %d ports will be used. \n", instance->port_count,121 "Max %d ports will be used.", instance->port_count, 120 122 OHCI_MAX_PORTS); 121 123 instance->port_count = OHCI_MAX_PORTS; 122 124 } 123 usb_log_info("%s: Found %u ports. \n", name, instance->port_count);125 usb_log_info("%s: Found %u ports.", name, instance->port_count); 124 126 125 127 #if defined OHCI_POWER_SWITCH_no 126 usb_log_info("%s: Set power mode to no power switching. \n", name);128 usb_log_info("%s: Set power mode to no power switching.", name); 127 129 /* Set port power mode to no power-switching. (always on) */ 128 130 OHCI_SET(regs->rh_desc_a, RHDA_NPS_FLAG); … … 132 134 133 135 #elif defined OHCI_POWER_SWITCH_ganged 134 usb_log_info("%s: Set power mode to ganged power switching. \n", name);136 usb_log_info("%s: Set power mode to ganged power switching.", name); 135 137 /* Set port power mode to ganged power-switching. */ 136 138 OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG); … … 144 146 OHCI_CLR(regs->rh_desc_a, RHDA_OCPM_FLAG); 145 147 #else 146 usb_log_info("%s: Set power mode to per-port power switching. \n", name);148 usb_log_info("%s: Set power mode to per-port power switching.", name); 147 149 /* Set port power mode to per port power-switching. */ 148 150 OHCI_CLR(regs->rh_desc_a, RHDA_NPS_FLAG); … … 162 164 163 165 ohci_rh_hub_desc_init(instance); 164 instance->unfinished_interrupt_transfer = NULL; 166 instance->status_change_endpoint = NULL; 167 instance->guard = guard; 165 168 return virthub_base_init(&instance->base, name, &ops, instance, 166 169 NULL, &instance->hub_descriptor.header, HUB_STATUS_CHANGE_PIPE); … … 178 181 assert(instance); 179 182 assert(batch); 180 const usb_target_t target = {{ 181 .address = batch->ep->address, 182 .endpoint = batch->ep->endpoint, 183 }}; 184 batch->error = virthub_base_request(&instance->base, target, 185 usb_transfer_batch_direction(batch), (void*)batch->setup_buffer, 186 batch->buffer, batch->buffer_size, &batch->transfered_size); 183 batch->error = virthub_base_request(&instance->base, batch->target, 184 batch->dir, &batch->setup.packet, 185 batch->dma_buffer.virt, batch->size, &batch->transferred_size); 187 186 if (batch->error == ENAK) { 188 /* This is safe because only status change interrupt transfers 189 * return NAK. The assertion holds true because the batch 190 * existence prevents communication with that ep */ 191 assert(instance->unfinished_interrupt_transfer == NULL); 192 instance->unfinished_interrupt_transfer = batch; 187 /* Lock the HC guard */ 188 fibril_mutex_lock(instance->guard); 189 const int err = endpoint_activate_locked(batch->ep, batch); 190 if (err) { 191 fibril_mutex_unlock(batch->ep->guard); 192 return err; 193 } 194 195 /* 196 * Asserting that the HC do not run two instances of the status 197 * change endpoint - shall be true. 198 */ 199 assert(!instance->status_change_endpoint); 200 201 endpoint_add_ref(batch->ep); 202 instance->status_change_endpoint = batch->ep; 203 fibril_mutex_unlock(instance->guard); 193 204 } else { 194 usb_transfer_batch_finish(batch, NULL); 195 usb_transfer_batch_destroy(batch); 205 usb_transfer_batch_finish(batch); 196 206 } 197 207 return EOK; … … 207 217 errno_t ohci_rh_interrupt(ohci_rh_t *instance) 208 218 { 209 //TODO atomic swap needed 210 usb_transfer_batch_t *batch = instance->unfinished_interrupt_transfer; 211 instance->unfinished_interrupt_transfer = NULL; 219 fibril_mutex_lock(instance->guard); 220 endpoint_t *ep = instance->status_change_endpoint; 221 if (!ep) { 222 fibril_mutex_unlock(instance->guard); 223 return EOK; 224 } 225 226 usb_transfer_batch_t * const batch = ep->active_batch; 227 endpoint_deactivate_locked(ep); 228 instance->status_change_endpoint = NULL; 229 fibril_mutex_unlock(instance->guard); 230 231 endpoint_del_ref(ep); 232 212 233 if (batch) { 213 const usb_target_t target = {{ 214 .address = batch->ep->address, 215 .endpoint = batch->ep->endpoint, 216 }}; 217 batch->error = virthub_base_request(&instance->base, target, 218 usb_transfer_batch_direction(batch), 219 (void*)batch->setup_buffer, 220 batch->buffer, batch->buffer_size, &batch->transfered_size); 221 usb_transfer_batch_finish(batch, NULL); 222 usb_transfer_batch_destroy(batch); 234 batch->error = virthub_base_request(&instance->base, batch->target, 235 batch->dir, &batch->setup.packet, 236 batch->dma_buffer.virt, batch->size, &batch->transferred_size); 237 usb_transfer_batch_finish(batch); 223 238 } 224 239 return EOK; … … 351 366 } 352 367 353 case USB _HUB_FEATURE_PORT_ENABLE: /*1*/368 case USB2_HUB_FEATURE_PORT_ENABLE: /*1*/ 354 369 OHCI_WR(hub->registers->rh_port_status[port], 355 370 RHPS_CLEAR_PORT_ENABLE); 356 371 return EOK; 357 372 358 case USB _HUB_FEATURE_PORT_SUSPEND: /*2*/373 case USB2_HUB_FEATURE_PORT_SUSPEND: /*2*/ 359 374 OHCI_WR(hub->registers->rh_port_status[port], 360 375 RHPS_CLEAR_PORT_SUSPEND); … … 362 377 363 378 case USB_HUB_FEATURE_C_PORT_CONNECTION: /*16*/ 364 case USB _HUB_FEATURE_C_PORT_ENABLE: /*17*/365 case USB _HUB_FEATURE_C_PORT_SUSPEND: /*18*/379 case USB2_HUB_FEATURE_C_PORT_ENABLE: /*17*/ 380 case USB2_HUB_FEATURE_C_PORT_SUSPEND: /*18*/ 366 381 case USB_HUB_FEATURE_C_PORT_OVER_CURRENT: /*19*/ 367 382 case USB_HUB_FEATURE_C_PORT_RESET: /*20*/ 368 383 usb_log_debug2("Clearing port C_CONNECTION, C_ENABLE, " 369 "C_SUSPEND, C_OC or C_RESET on port %u. \n", port);384 "C_SUSPEND, C_OC or C_RESET on port %u.", port); 370 385 /* Bit offsets correspond to the feature number */ 371 386 OHCI_WR(hub->registers->rh_port_status[port], … … 412 427 /* Fall through, for per port power */ 413 428 /* Fallthrough */ 414 case USB _HUB_FEATURE_PORT_ENABLE: /*1*/415 case USB _HUB_FEATURE_PORT_SUSPEND: /*2*/429 case USB2_HUB_FEATURE_PORT_ENABLE: /*1*/ 430 case USB2_HUB_FEATURE_PORT_SUSPEND: /*2*/ 416 431 case USB_HUB_FEATURE_PORT_RESET: /*4*/ 417 432 usb_log_debug2("Setting port POWER, ENABLE, SUSPEND or RESET " 418 "on port %u. \n", port);433 "on port %u.", port); 419 434 /* Bit offsets correspond to the feature number */ 420 435 OHCI_WR(hub->registers->rh_port_status[port], 1 << feature); … … 462 477 } 463 478 464 usb_log_debug2("OHCI root hub interrupt mask: %hx. \n", mask);479 usb_log_debug2("OHCI root hub interrupt mask: %hx.", mask); 465 480 466 481 if (mask == 0)
Note:
See TracChangeset
for help on using the changeset viewer.