Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/thunderbolt/nhi.c
| Show First 20 Lines • Show All 1,023 Lines • ▼ Show 20 Lines | |||||
| /* | /* | ||||
| * The CI and PI indexes are not read from the hardware. We track them in | * The CI and PI indexes are not read from the hardware. We track them in | ||||
| * software, so we know where in the ring to start a scan on an interrupt. | * software, so we know where in the ring to start a scan on an interrupt. | ||||
| * All we have to do is check for the appropriate Done bit in the next | * All we have to do is check for the appropriate Done bit in the next | ||||
| * descriptor, and we know if we have reached the last descriptor that the | * descriptor, and we know if we have reached the last descriptor that the | ||||
| * hardware touched. This technique saves at least 2 MEMIO reads per | * hardware touched. This technique saves at least 2 MEMIO reads per | ||||
| * interrupt. | * interrupt. | ||||
| * | |||||
| * TODO Is this actually okay? What if we fail to get a completion interrupts | |||||
| * but hardware updated CI anyway? I know this can happen, but is this an | |||||
| * issue? | |||||
| */ | */ | ||||
| void | void | ||||
| nhi_intr(void *data) | nhi_intr(void *data) | ||||
| { | { | ||||
| union nhi_ring_desc *rxd; | union nhi_ring_desc *rxd; | ||||
| struct nhi_cmd_frame *cmd; | struct nhi_cmd_frame *cmd; | ||||
| struct nhi_intr_tracker *trkr = data; | struct nhi_intr_tracker *trkr = data; | ||||
| struct nhi_softc *sc; | struct nhi_softc *sc; | ||||
| struct nhi_ring_pair *r; | struct nhi_ring_pair *r; | ||||
| struct nhi_tx_buffer_desc *txd; | struct nhi_tx_buffer_desc *txd; | ||||
| uint32_t val, old_ci; | uint32_t val, old_ci; | ||||
| u_int count; | u_int count; | ||||
| sc = trkr->sc; | sc = trkr->sc; | ||||
| tb_debug(sc, DBG_INTR|DBG_FULL, "Interrupt @ vector %d\n", | tb_debug(sc, DBG_INTR|DBG_FULL, "Interrupt @ vector %d\n", | ||||
| trkr->vector); | trkr->vector); | ||||
| if ((r = trkr->ring) == NULL) | if ((r = trkr->ring) == NULL) | ||||
| return; | return; | ||||
| /* | |||||
| * Need to read this necessarily to clear it; see 12.6.3.4.1. Disable | |||||
obiwac: See comment in D49451 about specifying where this reference is from. Though maybe I should do a… | |||||
emasteUnsubmitted Not Done Inline ActionsYeah, I'd just go ahead and make that change for any existing references first. emaste: Yeah, I'd just go ahead and make that change for any existing references first. | |||||
| * ISR Auto-Clear must be set to 0. | |||||
| * | |||||
| * XXX This might not be necessary on all platforms. It is on Pink | |||||
| * Sardine, but this was not being done previously so it might have | |||||
| * been working without this on whatever Scott was testing on. | |||||
| */ | |||||
| nhi_read_reg(sc, NHI_ISR0); | |||||
| /* | /* | ||||
| * Process TX completions from the adapter. Only go through | * Process TX completions from the adapter. Only go through | ||||
| * the ring once to prevent unbounded looping. | * the ring once to prevent unbounded looping. | ||||
| */ | */ | ||||
| count = r->tx_ring_depth; | count = r->tx_ring_depth; | ||||
| while (count-- > 0) { | while (count-- > 0) { | ||||
| txd = &r->tx_ring[r->tx_ci].tx; | txd = &r->tx_ring[r->tx_ci].tx; | ||||
| ▲ Show 20 Lines • Show All 112 Lines • Show Last 20 Lines | |||||
See comment in D49451 about specifying where this reference is from. Though maybe I should do a separate commit with this change to all existing references in the USB4 code.