Changeset a1ce9bd in mainline
- Timestamp:
- 2018-02-01T00:11:23Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1a2227d
- Parents:
- 8bfb163
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/transfers.c
r8bfb163 ra1ce9bd 126 126 } 127 127 128 static int calculate_trb_count(xhci_transfer_t *transfer) 129 { 130 const size_t size = transfer->batch.buffer_size; 131 return (size + PAGE_SIZE - 1 )/ PAGE_SIZE; 132 } 133 134 static void trb_set_buffer(xhci_transfer_t *transfer, xhci_trb_t *trb, 135 size_t i, size_t total) 136 { 137 const uintptr_t ptr = dma_buffer_phys(&transfer->hc_buffer, 138 transfer->hc_buffer.virt + i * PAGE_SIZE); 139 140 trb->parameter = host2xhci(64, ptr); 141 TRB_CTRL_SET_TD_SIZE(*trb, max(31, total - i - 1)); 142 if (i < total - 1) { 143 TRB_CTRL_SET_XFER_LEN(*trb, PAGE_SIZE); 144 } 145 else { 146 const size_t size = ((transfer->batch.buffer_size - 1) % PAGE_SIZE) + 1; 147 TRB_CTRL_SET_XFER_LEN(*trb, size); 148 } 149 } 150 128 151 static int schedule_control(xhci_hc_t* hc, xhci_transfer_t* transfer) 129 152 { … … 197 220 static int schedule_bulk(xhci_hc_t* hc, xhci_transfer_t *transfer) 198 221 { 199 xhci_trb_t trb;200 xhci_trb_clean(&trb);201 trb.parameter = host2xhci(64, transfer->hc_buffer.phys);202 203 // data size (sent for OUT, or buffer size)204 TRB_CTRL_SET_XFER_LEN(trb, transfer->batch.buffer_size);205 206 222 /* The stream-enabled endpoints need to chain ED trb */ 207 223 xhci_endpoint_t *ep = xhci_endpoint_get(transfer->batch.ep); 208 224 if (!ep->primary_stream_data_size) { 209 // FIXME: TD size 4.11.2.4 210 TRB_CTRL_SET_TD_SIZE(trb, 1); 211 212 // we want an interrupt after this td is done 213 TRB_CTRL_SET_IOC(trb, 1); 214 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 215 225 const size_t buffer_count = calculate_trb_count(transfer); 216 226 xhci_trb_ring_t* ring = get_ring(transfer); 217 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 227 xhci_trb_t trbs[buffer_count]; 228 229 for (size_t i = 0; i < buffer_count; ++i) { 230 xhci_trb_clean(&trbs[i]); 231 trb_set_buffer(transfer, &trbs[i], i, buffer_count); 232 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 233 234 if (i == buffer_count - 1) break; 235 236 /* Set the chain bit as this is not the last TRB */ 237 TRB_CTRL_SET_CHAIN(trbs[i], 1); 238 } 239 /* Set the interrupt bit for last TRB */ 240 TRB_CTRL_SET_IOC(trbs[buffer_count - 1], 1); 241 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count, 242 &transfer->interrupt_trb_phys); 218 243 } 219 244 else { 245 xhci_trb_t trb; 246 xhci_trb_clean(&trb); 247 trb.parameter = host2xhci(64, transfer->hc_buffer.phys); 248 249 // data size (sent for OUT, or buffer size) 250 TRB_CTRL_SET_XFER_LEN(trb, transfer->batch.buffer_size); 220 251 TRB_CTRL_SET_TD_SIZE(trb, 2); 221 252 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); … … 245 276 static int schedule_interrupt(xhci_hc_t* hc, xhci_transfer_t* transfer) 246 277 { 247 xhci_trb_t trb; 248 xhci_trb_clean(&trb); 249 trb.parameter = host2xhci(64, transfer->hc_buffer.phys); 250 251 // data size (sent for OUT, or buffer size) 252 TRB_CTRL_SET_XFER_LEN(trb, transfer->batch.buffer_size); 253 // FIXME: TD size 4.11.2.4 254 TRB_CTRL_SET_TD_SIZE(trb, 1); 255 256 // we want an interrupt after this td is done 257 TRB_CTRL_SET_IOC(trb, 1); 258 259 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 260 278 const size_t buffer_count = calculate_trb_count(transfer); 261 279 xhci_trb_ring_t* ring = get_ring(transfer); 262 263 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 280 xhci_trb_t trbs[buffer_count]; 281 282 for (size_t i = 0; i < buffer_count; ++i) { 283 xhci_trb_clean(&trbs[i]); 284 trb_set_buffer(transfer, &trbs[i], i, buffer_count); 285 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 286 287 if (i == buffer_count - 1) break; 288 289 /* Set the chain bit as this is not the last TRB */ 290 TRB_CTRL_SET_CHAIN(trbs[i], 1); 291 } 292 /* Set the interrupt bit for last TRB */ 293 TRB_CTRL_SET_IOC(trbs[buffer_count - 1], 1); 294 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count, 295 &transfer->interrupt_trb_phys); 264 296 } 265 297
Note:
See TracChangeset
for help on using the changeset viewer.