Changeset a94cbfa in mainline
- Timestamp:
- 2018-01-26T00:55:38Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 77733a9
- Parents:
- 047fbc8
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-26 00:15:17)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-26 00:55:38)
- Location:
- uspace/drv/bus/usb
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_rh.c
r047fbc8 ra94cbfa 127 127 128 128 ehci_rh_hub_desc_init(instance, EHCI_RD(caps->hcsparams)); 129 instance-> unfinished_interrupt_transfer= NULL;129 instance->status_change_endpoint = NULL; 130 130 131 131 return virthub_base_init(&instance->base, name, &ops, instance, … … 150 150 usb_log_debug("RH(%p): BATCH(%p) adding as unfinished", 151 151 instance, batch); 152 /* This is safe because only status change interrupt transfers 153 * return NAK. The assertion holds true because the batch 154 * existence prevents communication with that ep */ 155 assert(instance->unfinished_interrupt_transfer == NULL); 156 instance->unfinished_interrupt_transfer = batch; 152 153 /* Lock the HC guard */ 154 fibril_mutex_lock(batch->ep->guard); 155 const int err = endpoint_activate_locked(batch->ep, batch); 156 if (err) { 157 fibril_mutex_unlock(batch->ep->guard); 158 return err; 159 } 160 161 /* 162 * Asserting that the HC do not run two instances of the status 163 * change endpoint - shall be true. 164 */ 165 assert(!instance->status_change_endpoint); 166 167 endpoint_add_ref(batch->ep); 168 instance->status_change_endpoint = batch->ep; 169 fibril_mutex_unlock(batch->ep->guard); 157 170 } else { 158 171 usb_log_debug("RH(%p): BATCH(%p) virtual request complete: %s", … … 172 185 int ehci_rh_interrupt(ehci_rh_t *instance) 173 186 { 174 //TODO atomic swap needed 175 usb_transfer_batch_t *batch = instance->unfinished_interrupt_transfer; 176 instance->unfinished_interrupt_transfer = NULL; 177 usb_log_debug2("RH(%p): Interrupt. Processing batch: %p", 178 instance, batch); 187 endpoint_t *ep = instance->status_change_endpoint; 188 if (!ep) 189 return EOK; 190 191 fibril_mutex_lock(ep->guard); 192 usb_transfer_batch_t * const batch = ep->active_batch; 193 endpoint_deactivate_locked(ep); 194 instance->status_change_endpoint = NULL; 195 fibril_mutex_unlock(ep->guard); 196 197 endpoint_del_ref(ep); 198 179 199 if (batch) { 200 usb_log_debug2("RH(%p): Interrupt. Processing batch: %p", 201 instance, batch); 180 202 batch->error = virthub_base_request(&instance->base, batch->target, 181 203 batch->dir, (void*) batch->setup.buffer, -
uspace/drv/bus/usb/ehci/ehci_rh.h
r047fbc8 ra94cbfa 61 61 uint8_t rempow[STATUS_BYTES(EHCI_MAX_PORTS) * 2]; 62 62 } __attribute__((packed)) hub_descriptor; 63 /** interrupt transfer waiting for an actual interrupt to occur */64 usb_transfer_batch_t *unfinished_interrupt_transfer;65 63 bool reset_flag[EHCI_MAX_PORTS]; 66 64 bool resume_flag[EHCI_MAX_PORTS]; 65 66 /* 67 * This is sort of hacky, but better than duplicating functionality. 68 * We cannot simply store a pointer to a transfer in-progress, in order 69 * to allow it to be aborted. We can however store a reference to the 70 * Status Change Endpoint. Note that this is mixing two worlds together 71 * - otherwise, the RH is "a device" and have no clue about HC, apart 72 * from accessing its registers. 73 */ 74 endpoint_t *status_change_endpoint; 75 67 76 } ehci_rh_t; 68 77 -
uspace/drv/bus/usb/ohci/ohci_rh.c
r047fbc8 ra94cbfa 162 162 163 163 ohci_rh_hub_desc_init(instance); 164 instance-> unfinished_interrupt_transfer= NULL;164 instance->status_change_endpoint = NULL; 165 165 return virthub_base_init(&instance->base, name, &ops, instance, 166 166 NULL, &instance->hub_descriptor.header, HUB_STATUS_CHANGE_PIPE); … … 182 182 batch->buffer, batch->buffer_size, &batch->transferred_size); 183 183 if (batch->error == ENAK) { 184 /* This is safe because only status change interrupt transfers 185 * return NAK. The assertion holds true because the batch 186 * existence prevents communication with that ep */ 187 assert(instance->unfinished_interrupt_transfer == NULL); 188 instance->unfinished_interrupt_transfer = batch; 184 /* Lock the HC guard */ 185 fibril_mutex_lock(batch->ep->guard); 186 const int err = endpoint_activate_locked(batch->ep, batch); 187 if (err) { 188 fibril_mutex_unlock(batch->ep->guard); 189 return err; 190 } 191 192 /* 193 * Asserting that the HC do not run two instances of the status 194 * change endpoint - shall be true. 195 */ 196 assert(!instance->status_change_endpoint); 197 198 endpoint_add_ref(batch->ep); 199 instance->status_change_endpoint = batch->ep; 200 fibril_mutex_unlock(batch->ep->guard); 189 201 } else { 190 202 usb_transfer_batch_finish(batch); … … 202 214 int ohci_rh_interrupt(ohci_rh_t *instance) 203 215 { 204 //TODO atomic swap needed 205 usb_transfer_batch_t *batch = instance->unfinished_interrupt_transfer; 206 instance->unfinished_interrupt_transfer = NULL; 216 endpoint_t *ep = instance->status_change_endpoint; 217 if (!ep) 218 return EOK; 219 220 fibril_mutex_lock(ep->guard); 221 usb_transfer_batch_t * const batch = ep->active_batch; 222 endpoint_deactivate_locked(ep); 223 instance->status_change_endpoint = NULL; 224 fibril_mutex_unlock(ep->guard); 225 226 endpoint_del_ref(ep); 227 207 228 if (batch) { 208 229 batch->error = virthub_base_request(&instance->base, batch->target, -
uspace/drv/bus/usb/ohci/ohci_rh.h
r047fbc8 ra94cbfa 61 61 uint8_t rempow[STATUS_BYTES(OHCI_MAX_PORTS) * 2]; 62 62 } __attribute__((packed)) hub_descriptor; 63 /** interrupt transfer waiting for an actual interrupt to occur*/64 usb_transfer_batch_t *unfinished_interrupt_transfer;63 /** A hacky way to emulate interrupts over polling. See ehci_rh. */ 64 endpoint_t *status_change_endpoint; 65 65 } ohci_rh_t; 66 66
Note:
See TracChangeset
for help on using the changeset viewer.