Changeset df6ded8 in mainline for uspace/drv/bus/usb/ehci/ehci_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/ehci/ehci_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 * … … 100 101 */ 101 102 errno_t ehci_rh_init(ehci_rh_t *instance, ehci_caps_regs_t *caps, ehci_regs_t *regs, 102 const char *name)103 fibril_mutex_t *guard, const char *name) 103 104 { 104 105 assert(instance); … … 107 108 (EHCI_RD(caps->hcsparams) >> EHCI_CAPS_HCS_N_PORTS_SHIFT) & 108 109 EHCI_CAPS_HCS_N_PORTS_MASK; 109 usb_log_debug2("RH(%p): hcsparams: %x. \n", instance,110 usb_log_debug2("RH(%p): hcsparams: %x.", instance, 110 111 EHCI_RD(caps->hcsparams)); 111 usb_log_info("RH(%p): Found %u ports. \n", instance,112 usb_log_info("RH(%p): Found %u ports.", instance, 112 113 instance->port_count); 113 114 … … 127 128 128 129 ehci_rh_hub_desc_init(instance, EHCI_RD(caps->hcsparams)); 129 instance->unfinished_interrupt_transfer = NULL; 130 instance->guard = guard; 131 instance->status_change_endpoint = NULL; 130 132 131 133 return virthub_base_init(&instance->base, name, &ops, instance, … … 144 146 assert(instance); 145 147 assert(batch); 146 const usb_target_t target = {{ 147 .address = batch->ep->address, 148 .endpoint = batch->ep->endpoint, 149 }}; 150 batch->error = virthub_base_request(&instance->base, target, 151 usb_transfer_batch_direction(batch), (void*)batch->setup_buffer, 152 batch->buffer, batch->buffer_size, &batch->transfered_size); 148 batch->error = virthub_base_request(&instance->base, batch->target, 149 batch->dir, (void*) batch->setup.buffer, 150 batch->dma_buffer.virt, batch->size, 151 &batch->transferred_size); 153 152 if (batch->error == ENAK) { 154 153 usb_log_debug("RH(%p): BATCH(%p) adding as unfinished", 155 154 instance, batch); 156 /* This is safe because only status change interrupt transfers 157 * return NAK. The assertion holds true because the batch 158 * existence prevents communication with that ep */ 159 assert(instance->unfinished_interrupt_transfer == NULL); 160 instance->unfinished_interrupt_transfer = batch; 155 156 /* Lock the HC guard */ 157 fibril_mutex_lock(instance->guard); 158 const int err = endpoint_activate_locked(batch->ep, batch); 159 if (err) { 160 fibril_mutex_unlock(batch->ep->guard); 161 return err; 162 } 163 164 /* 165 * Asserting that the HC do not run two instances of the status 166 * change endpoint - shall be true. 167 */ 168 assert(!instance->status_change_endpoint); 169 170 endpoint_add_ref(batch->ep); 171 instance->status_change_endpoint = batch->ep; 172 fibril_mutex_unlock(instance->guard); 161 173 } else { 162 usb_transfer_batch_finish(batch, NULL);163 usb_transfer_batch_destroy(batch);164 174 usb_log_debug("RH(%p): BATCH(%p) virtual request complete: %s", 165 175 instance, batch, str_error(batch->error)); 176 usb_transfer_batch_finish(batch); 166 177 } 167 178 return EOK; … … 177 188 errno_t ehci_rh_interrupt(ehci_rh_t *instance) 178 189 { 179 //TODO atomic swap needed 180 usb_transfer_batch_t *batch = instance->unfinished_interrupt_transfer; 181 instance->unfinished_interrupt_transfer = NULL; 182 usb_log_debug2("RH(%p): Interrupt. Processing batch: %p", 183 instance, batch); 190 fibril_mutex_lock(instance->guard); 191 endpoint_t *ep = instance->status_change_endpoint; 192 if (!ep) { 193 fibril_mutex_unlock(instance->guard); 194 return EOK; 195 } 196 197 usb_transfer_batch_t * const batch = ep->active_batch; 198 endpoint_deactivate_locked(ep); 199 instance->status_change_endpoint = NULL; 200 fibril_mutex_unlock(instance->guard); 201 202 endpoint_del_ref(ep); 203 184 204 if (batch) { 185 const usb_target_t target = {{ 186 .address = batch->ep->address, 187 .endpoint = batch->ep->endpoint, 188 }}; 189 batch->error = virthub_base_request(&instance->base, target, 190 usb_transfer_batch_direction(batch), 191 (void*)batch->setup_buffer, 192 batch->buffer, batch->buffer_size, &batch->transfered_size); 193 usb_transfer_batch_finish(batch, NULL); 194 usb_transfer_batch_destroy(batch); 205 usb_log_debug2("RH(%p): Interrupt. Processing batch: %p", 206 instance, batch); 207 batch->error = virthub_base_request(&instance->base, batch->target, 208 batch->dir, (void*) batch->setup.buffer, 209 batch->dma_buffer.virt, batch->size, 210 &batch->transferred_size); 211 usb_transfer_batch_finish(batch); 195 212 } 196 213 return EOK; … … 258 275 259 276 #define BIT_VAL(val, bit) ((val & bit) ? 1 : 0) 260 #define EHCI2USB(val, bit, feat) (BIT_VAL(val, bit) << feat)277 #define EHCI2USB(val, bit, mask) (BIT_VAL(val, bit) ? mask : 0) 261 278 262 279 /** Port status request handler. … … 280 297 const uint32_t reg = EHCI_RD(hub->registers->portsc[port]); 281 298 const uint32_t status = uint32_host2usb( 282 EHCI2USB(reg, USB_PORTSC_CONNECT_FLAG, USB_HUB_ FEATURE_PORT_CONNECTION) |283 EHCI2USB(reg, USB_PORTSC_ENABLED_FLAG, USB_HUB_ FEATURE_PORT_ENABLE) |284 EHCI2USB(reg, USB_PORTSC_SUSPEND_FLAG, USB _HUB_FEATURE_PORT_SUSPEND) |285 EHCI2USB(reg, USB_PORTSC_OC_ACTIVE_FLAG, USB_HUB_ FEATURE_PORT_OVER_CURRENT) |286 EHCI2USB(reg, USB_PORTSC_PORT_RESET_FLAG, USB_HUB_ FEATURE_PORT_RESET) |287 EHCI2USB(reg, USB_PORTSC_PORT_POWER_FLAG, USB _HUB_FEATURE_PORT_POWER) |299 EHCI2USB(reg, USB_PORTSC_CONNECT_FLAG, USB_HUB_PORT_STATUS_CONNECTION) | 300 EHCI2USB(reg, USB_PORTSC_ENABLED_FLAG, USB_HUB_PORT_STATUS_ENABLE) | 301 EHCI2USB(reg, USB_PORTSC_SUSPEND_FLAG, USB2_HUB_PORT_STATUS_SUSPEND) | 302 EHCI2USB(reg, USB_PORTSC_OC_ACTIVE_FLAG, USB_HUB_PORT_STATUS_OC) | 303 EHCI2USB(reg, USB_PORTSC_PORT_RESET_FLAG, USB_HUB_PORT_STATUS_RESET) | 304 EHCI2USB(reg, USB_PORTSC_PORT_POWER_FLAG, USB2_HUB_PORT_STATUS_POWER) | 288 305 (((reg & USB_PORTSC_LINE_STATUS_MASK) == USB_PORTSC_LINE_STATUS_K) ? 289 ( 1 << USB_HUB_FEATURE_PORT_LOW_SPEED) : 0) |290 ((reg & USB_PORTSC_PORT_OWNER_FLAG) ? 0 : (1 << USB_HUB_FEATURE_PORT_HIGH_SPEED)) |291 EHCI2USB(reg, USB_PORTSC_PORT_TEST_MASK, 11) |292 EHCI2USB(reg, USB_PORTSC_INDICATOR_MASK, 12) |293 EHCI2USB(reg, USB_PORTSC_CONNECT_CH_FLAG, USB_HUB_ FEATURE_C_PORT_CONNECTION) |294 EHCI2USB(reg, USB_PORTSC_EN_CHANGE_FLAG, USB _HUB_FEATURE_C_PORT_ENABLE) |295 (hub->resume_flag[port] ? (1 << USB_HUB_FEATURE_C_PORT_SUSPEND): 0) |296 EHCI2USB(reg, USB_PORTSC_OC_CHANGE_FLAG, USB_HUB_ FEATURE_C_PORT_OVER_CURRENT) |297 (hub->reset_flag[port] ? (1 << USB_HUB_FEATURE_C_PORT_RESET): 0)306 (USB2_HUB_PORT_STATUS_LOW_SPEED) : 0) | 307 ((reg & USB_PORTSC_PORT_OWNER_FLAG) ? 0 : USB2_HUB_PORT_STATUS_HIGH_SPEED) | 308 EHCI2USB(reg, USB_PORTSC_PORT_TEST_MASK, USB2_HUB_PORT_STATUS_TEST) | 309 EHCI2USB(reg, USB_PORTSC_INDICATOR_MASK, USB2_HUB_PORT_STATUS_INDICATOR) | 310 EHCI2USB(reg, USB_PORTSC_CONNECT_CH_FLAG, USB_HUB_PORT_STATUS_C_CONNECTION) | 311 EHCI2USB(reg, USB_PORTSC_EN_CHANGE_FLAG, USB2_HUB_PORT_STATUS_C_ENABLE) | 312 (hub->resume_flag[port] ? USB2_HUB_PORT_STATUS_C_SUSPEND : 0) | 313 EHCI2USB(reg, USB_PORTSC_OC_CHANGE_FLAG, USB_HUB_PORT_STATUS_C_OC) | 314 (hub->reset_flag[port] ? USB_HUB_PORT_STATUS_C_RESET: 0) 298 315 ); 299 316 /* Note feature numbers for test and indicator feature do not … … 396 413 return EOK; 397 414 398 case USB _HUB_FEATURE_PORT_ENABLE: /*1*/415 case USB2_HUB_FEATURE_PORT_ENABLE: /*1*/ 399 416 usb_log_debug2("RH(%p-%u): Clear port enable.", hub, port); 400 417 EHCI_CLR(hub->registers->portsc[port], … … 402 419 return EOK; 403 420 404 case USB _HUB_FEATURE_PORT_SUSPEND: /*2*/421 case USB2_HUB_FEATURE_PORT_SUSPEND: /*2*/ 405 422 usb_log_debug2("RH(%p-%u): Clear port suspend.", hub, port); 406 423 /* If not in suspend it's noop */ … … 420 437 USB_PORTSC_CONNECT_CH_FLAG); 421 438 return EOK; 422 case USB _HUB_FEATURE_C_PORT_ENABLE: /*17*/439 case USB2_HUB_FEATURE_C_PORT_ENABLE: /*17*/ 423 440 usb_log_debug2("RH(%p-%u): Clear port enable change.", 424 441 hub, port); … … 432 449 USB_PORTSC_OC_CHANGE_FLAG); 433 450 return EOK; 434 case USB _HUB_FEATURE_C_PORT_SUSPEND: /*18*/451 case USB2_HUB_FEATURE_C_PORT_SUSPEND: /*18*/ 435 452 usb_log_debug2("RH(%p-%u): Clear port suspend change.", 436 453 hub, port); … … 467 484 const unsigned feature = uint16_usb2host(setup_packet->value); 468 485 switch (feature) { 469 case USB _HUB_FEATURE_PORT_ENABLE: /*1*/486 case USB2_HUB_FEATURE_PORT_ENABLE: /*1*/ 470 487 usb_log_debug2("RH(%p-%u): Set port enable.", hub, port); 471 488 EHCI_SET(hub->registers->portsc[port], 472 489 USB_PORTSC_ENABLED_FLAG); 473 490 return EOK; 474 case USB _HUB_FEATURE_PORT_SUSPEND: /*2*/491 case USB2_HUB_FEATURE_PORT_SUSPEND: /*2*/ 475 492 usb_log_debug2("RH(%p-%u): Set port suspend.", hub, port); 476 493 EHCI_SET(hub->registers->portsc[port],
Note:
See TracChangeset
for help on using the changeset viewer.