Changeset 3038d51 in mainline
- Timestamp:
- 2018-02-01T18:57:17Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 290338b
- Parents:
- 3b5a5e3
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/endpoint.c
r3b5a5e3 r3038d51 88 88 if (dev->speed >= USB_SPEED_SUPER) { 89 89 ep->packets_per_uframe = xhci_ep->max_burst * xhci_ep->mult; 90 ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe; 90 if (ep->transfer_type == USB_TRANSFER_ISOCHRONOUS 91 || ep->transfer_type == USB_TRANSFER_INTERRUPT) { 92 ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe; 93 } 94 else { 95 ep->max_transfer_size = 200 * PAGE_SIZE; 96 } 91 97 } 92 98 -
uspace/drv/bus/usb/xhci/transfers.c
r3b5a5e3 r3038d51 133 133 134 134 static void trb_set_buffer(xhci_transfer_t *transfer, xhci_trb_t *trb, 135 size_t i, size_t total )135 size_t i, size_t total, size_t *remaining) 136 136 { 137 137 const uintptr_t ptr = dma_buffer_phys(&transfer->hc_buffer, … … 140 140 trb->parameter = host2xhci(64, ptr); 141 141 TRB_CTRL_SET_TD_SIZE(*trb, max(31, total - i - 1)); 142 if ( i < total - 1) {142 if (*remaining > PAGE_SIZE) { 143 143 TRB_CTRL_SET_XFER_LEN(*trb, PAGE_SIZE); 144 *remaining -= PAGE_SIZE; 144 145 } 145 146 else { 146 const size_t size = ((transfer->batch.buffer_size - 1) % PAGE_SIZE) + 1;147 TRB_CTRL_SET_XFER_LEN(*trb, size);147 TRB_CTRL_SET_XFER_LEN(*trb, *remaining); 148 *remaining = 0; 148 149 } 149 150 } … … 156 157 usb_device_request_setup_packet_t* setup = &batch->setup.packet; 157 158 158 xhci_trb_t trbs[3]; 159 int trbs_used = 0; 160 161 xhci_trb_t *trb_setup = trbs + trbs_used++; 159 size_t buffer_count = 0; 160 if (setup->length > 0) { 161 buffer_count = calculate_trb_count(transfer); 162 } 163 164 xhci_trb_t trbs[buffer_count + 2]; 165 166 xhci_trb_t *trb_setup = trbs; 162 167 xhci_trb_clean(trb_setup); 163 168 … … 178 183 179 184 /* Data stage */ 180 xhci_trb_t *trb_data = NULL;181 185 if (setup->length > 0) { 182 trb_data = trbs + trbs_used++;183 xhci_trb_clean(trb_data);184 185 trb_data->parameter = host2xhci(64, transfer->hc_buffer.phys);186 187 // data size (sent for OUT, or buffer size)188 TRB_CTRL_SET_XFER_LEN(*trb_data, batch->buffer_size);189 // FIXME: TD size 4.11.2.4190 TRB_CTRL_SET_TD_SIZE(*trb_data, 1);191 192 // Some more fields here, no idea what they mean193 TRB_CTRL_SET_TRB_TYPE(*trb_data, XHCI_TRB_TYPE_DATA_STAGE);194 195 186 int stage_dir = REQUEST_TYPE_IS_DEVICE_TO_HOST(setup->request_type) 196 187 ? STAGE_IN : STAGE_OUT; 197 TRB_CTRL_SET_DIR(*trb_data, stage_dir); 188 size_t remaining = transfer->batch.buffer_size; 189 190 for (size_t i = 0; i < buffer_count; ++i) { 191 xhci_trb_clean(&trbs[i + 1]); 192 trb_set_buffer(transfer, &trbs[i + 1], i, buffer_count, &remaining); 193 194 TRB_CTRL_SET_DIR(trbs[i + 1], stage_dir); 195 TRB_CTRL_SET_TRB_TYPE(trbs[i + 1], XHCI_TRB_TYPE_DATA_STAGE); 196 197 if (i == buffer_count - 1) break; 198 199 /* Set the chain bit as this is not the last TRB */ 200 TRB_CTRL_SET_CHAIN(trbs[i], 1); 201 } 198 202 } 199 203 200 204 /* Status stage */ 201 xhci_trb_t *trb_status = trbs + trbs_used++;205 xhci_trb_t *trb_status = trbs + buffer_count + 1; 202 206 xhci_trb_clean(trb_status); 203 207 … … 215 219 216 220 return xhci_trb_ring_enqueue_multiple(get_ring(transfer), trbs, 217 trbs_used, &transfer->interrupt_trb_phys);221 buffer_count + 2, &transfer->interrupt_trb_phys); 218 222 } 219 223 … … 224 228 if (!ep->primary_stream_data_size) { 225 229 const size_t buffer_count = calculate_trb_count(transfer); 226 xhci_trb_ring_t* ring = get_ring(transfer);227 230 xhci_trb_t trbs[buffer_count]; 231 size_t remaining = transfer->batch.buffer_size; 228 232 229 233 for (size_t i = 0; i < buffer_count; ++i) { 230 234 xhci_trb_clean(&trbs[i]); 231 trb_set_buffer(transfer, &trbs[i], i, buffer_count );235 trb_set_buffer(transfer, &trbs[i], i, buffer_count, &remaining); 232 236 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 233 237 … … 239 243 /* Set the interrupt bit for last TRB */ 240 244 TRB_CTRL_SET_IOC(trbs[buffer_count - 1], 1); 245 246 xhci_trb_ring_t* ring = get_ring(transfer); 241 247 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count, 242 248 &transfer->interrupt_trb_phys); 243 249 } 244 250 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);251 TRB_CTRL_SET_TD_SIZE(trb, 2);252 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL);253 TRB_CTRL_SET_CHAIN(trb, 1);254 TRB_CTRL_SET_ENT(trb, 1);255 256 251 xhci_trb_ring_t* ring = get_ring(transfer); 257 252 if (!ring) { … … 259 254 } 260 255 261 int err = xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 262 263 if (err) { 264 return err; 265 } 266 267 xhci_trb_clean(&trb); 268 trb.parameter = host2xhci(64, (uintptr_t) transfer); 269 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_EVENT_DATA); 270 TRB_CTRL_SET_IOC(trb, 1); 271 272 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 256 const size_t buffer_count = calculate_trb_count(transfer); 257 xhci_trb_t trbs[buffer_count + 1]; 258 size_t remaining = transfer->batch.buffer_size; 259 260 for (size_t i = 0; i < buffer_count; ++i) { 261 xhci_trb_clean(&trbs[i]); 262 trb_set_buffer(transfer, &trbs[i], i, buffer_count + 1, &remaining); 263 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 264 TRB_CTRL_SET_CHAIN(trbs[i], 1); 265 } 266 TRB_CTRL_SET_ENT(trbs[buffer_count - 1], 1); 267 268 xhci_trb_clean(&trbs[buffer_count]); 269 trbs[buffer_count].parameter = host2xhci(64, (uintptr_t) transfer); 270 TRB_CTRL_SET_TRB_TYPE(trbs[buffer_count], XHCI_TRB_TYPE_EVENT_DATA); 271 TRB_CTRL_SET_IOC(trbs[buffer_count], 1); 272 273 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count + 1, 274 &transfer->interrupt_trb_phys); 273 275 } 274 276 } … … 277 279 { 278 280 const size_t buffer_count = calculate_trb_count(transfer); 279 xhci_trb_ring_t* ring = get_ring(transfer);280 281 xhci_trb_t trbs[buffer_count]; 282 size_t remaining = transfer->batch.buffer_size; 281 283 282 284 for (size_t i = 0; i < buffer_count; ++i) { 283 285 xhci_trb_clean(&trbs[i]); 284 trb_set_buffer(transfer, &trbs[i], i, buffer_count );286 trb_set_buffer(transfer, &trbs[i], i, buffer_count, &remaining); 285 287 TRB_CTRL_SET_TRB_TYPE(trbs[i], XHCI_TRB_TYPE_NORMAL); 286 288 … … 292 294 /* Set the interrupt bit for last TRB */ 293 295 TRB_CTRL_SET_IOC(trbs[buffer_count - 1], 1); 296 297 xhci_trb_ring_t* ring = get_ring(transfer); 294 298 return xhci_trb_ring_enqueue_multiple(ring, &trbs[0], buffer_count, 295 299 &transfer->interrupt_trb_phys);
Note:
See TracChangeset
for help on using the changeset viewer.