Changeset c21e6a5 in mainline
- Timestamp:
- 2018-02-05T00:54:08Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- af16ebe
- Parents:
- 65c059f
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-02-05 00:27:40)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-02-05 00:54:08)
- Location:
- uspace
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_batch.c
r65c059f rc21e6a5 61 61 { 62 62 assert(ehci_batch); 63 dma_buffer_free(&ehci_batch-> dma_buffer);63 dma_buffer_free(&ehci_batch->ehci_dma_buffer); 64 64 usb_log_debug2("Batch(%p): disposed", ehci_batch); 65 65 free(ehci_batch); … … 116 116 } 117 117 118 assert(ehci_batch->td_count > 0); 119 118 120 const size_t tds_size = ehci_batch->td_count * sizeof(td_t); 119 121 120 /* Mix setup stage, data and TDs together, we have enough space */ 121 if (size + setup_size + tds_size > 0) { 122 if (dma_buffer_alloc(&ehci_batch->dma_buffer, tds_size + setup_size + size)) { 123 usb_log_error("Batch %p: Failed to allocate device " 124 "buffer", ehci_batch); 125 return ENOMEM; 126 } 127 /* Clean TDs */ 128 ehci_batch->tds = ehci_batch->dma_buffer.virt; 129 memset(ehci_batch->tds, 0, tds_size); 130 /* Copy setup data */ 131 ehci_batch->setup_buffer = ehci_batch->dma_buffer.virt + tds_size; 132 memcpy(ehci_batch->setup_buffer, ehci_batch->base.setup.buffer, setup_size); 133 /* Copy generic data */ 134 ehci_batch->data_buffer = ehci_batch->setup_buffer + setup_size; 135 if (ehci_batch->base.dir != USB_DIRECTION_IN) 136 memcpy(ehci_batch->data_buffer, 137 ehci_batch->base.buffer, 138 ehci_batch->base.buffer_size); 139 } 122 /* Mix setup stage and TDs together, we have enough space */ 123 if (dma_buffer_alloc(&ehci_batch->ehci_dma_buffer, tds_size + setup_size)) { 124 usb_log_error("Batch %p: Failed to allocate device buffer", 125 ehci_batch); 126 return ENOMEM; 127 } 128 129 /* Clean TDs */ 130 ehci_batch->tds = ehci_batch->ehci_dma_buffer.virt; 131 memset(ehci_batch->tds, 0, tds_size); 132 133 /* Copy setup data */ 134 ehci_batch->setup_buffer = ehci_batch->ehci_dma_buffer.virt + tds_size; 135 memcpy(ehci_batch->setup_buffer, ehci_batch->base.setup.buffer, setup_size); 136 137 /* Generic data already prepared*/ 138 ehci_batch->data_buffer = ehci_batch->base.dma_buffer.virt; 140 139 141 140 if (!batch_setup[ehci_batch->base.ep->transfer_type]) … … 219 218 assert(ehci_batch->base.transferred_size <= ehci_batch->base.buffer_size); 220 219 221 if (ehci_batch->base.dir == USB_DIRECTION_IN)222 memcpy(ehci_batch->base.buffer,223 ehci_batch->data_buffer,224 ehci_batch->base.transferred_size);225 226 220 /* Clear TD pointers */ 227 221 ehci_batch->qh->next = LINK_POINTER_TERM; … … 240 234 { 241 235 assert(ehci_batch); 242 qh_set_next_td(ehci_batch->qh, dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[0])); 236 qh_set_next_td(ehci_batch->qh, 237 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, &ehci_batch->tds[0])); 243 238 } 244 239 … … 275 270 /* Setup stage */ 276 271 td_init(&ehci_batch->tds[0], 277 dma_buffer_phys(&ehci_batch-> dma_buffer, &ehci_batch->tds[1]),278 dma_buffer_phys(&ehci_batch-> dma_buffer, ehci_batch->setup_buffer),272 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, &ehci_batch->tds[1]), 273 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, ehci_batch->setup_buffer), 279 274 USB_DIRECTION_BOTH, USB_SETUP_PACKET_SIZE, toggle, false); 280 275 usb_log_debug2("Batch %p: Created CONTROL SETUP TD(%"PRIxn"): " 281 276 "%08x:%08x:%08x", ehci_batch, 282 dma_buffer_phys(&ehci_batch-> dma_buffer, &ehci_batch->tds[0]),277 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, &ehci_batch->tds[0]), 283 278 ehci_batch->tds[0].status, ehci_batch->tds[0].next, 284 279 ehci_batch->tds[0].alternate); … … 287 282 unsigned td_current = 1; 288 283 size_t remain_size = ehci_batch->base.buffer_size; 289 uintptr_t buffer = dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->data_buffer); 284 uintptr_t buffer = dma_buffer_phys(&ehci_batch->base.dma_buffer, 285 ehci_batch->data_buffer); 290 286 while (remain_size > 0) { 291 287 const size_t transfer_size = min(remain_size, EHCI_TD_MAX_TRANSFER); … … 293 289 294 290 td_init(&ehci_batch->tds[td_current], 295 dma_buffer_phys(&ehci_batch-> dma_buffer, &ehci_batch->tds[td_current + 1]),291 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, &ehci_batch->tds[td_current + 1]), 296 292 buffer, data_dir, transfer_size, toggle, false); 297 293 usb_log_debug2("Batch %p: Created CONTROL DATA TD(%"PRIxn"): " 298 294 "%08x:%08x:%08x", ehci_batch, 299 dma_buffer_phys(&ehci_batch-> dma_buffer, &ehci_batch->tds[td_current]),295 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, &ehci_batch->tds[td_current]), 300 296 ehci_batch->tds[td_current].status, 301 297 ehci_batch->tds[td_current].next, … … 313 309 usb_log_debug2("Batch %p: Created CONTROL STATUS TD %d(%"PRIxn"): " 314 310 "%08x:%08x:%08x", ehci_batch, td_current, 315 dma_buffer_phys(&ehci_batch-> dma_buffer, &ehci_batch->tds[td_current]),311 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, &ehci_batch->tds[td_current]), 316 312 ehci_batch->tds[td_current].status, 317 313 ehci_batch->tds[td_current].next, … … 340 336 size_t td_current = 0; 341 337 size_t remain_size = ehci_batch->base.buffer_size; 342 uintptr_t buffer = dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->data_buffer); 338 uintptr_t buffer = dma_buffer_phys(&ehci_batch->base.dma_buffer, 339 ehci_batch->data_buffer); 343 340 while (remain_size > 0) { 344 341 const size_t transfer_size = remain_size > EHCI_TD_MAX_TRANSFER … … 347 344 const bool last = (remain_size == transfer_size); 348 345 td_init(&ehci_batch->tds[td_current], 349 last ? 0 : dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current + 1]), 346 last ? 0 : dma_buffer_phys(&ehci_batch->ehci_dma_buffer, 347 &ehci_batch->tds[td_current + 1]), 350 348 buffer, ehci_batch->base.dir, transfer_size, -1, last); 351 349 352 350 usb_log_debug2("Batch %p: DATA TD(%"PRIxn": %08x:%08x:%08x", 353 351 ehci_batch, 354 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]), 352 dma_buffer_phys(&ehci_batch->ehci_dma_buffer, 353 &ehci_batch->tds[td_current]), 355 354 ehci_batch->tds[td_current].status, 356 355 ehci_batch->tds[td_current].next, -
uspace/drv/bus/usb/ehci/ehci_batch.h
r65c059f rc21e6a5 51 51 /** Endpoint descriptor of the target endpoint. */ 52 52 qh_t *qh; 53 /** Data buffer, must be accessible by the EHCI hw. */54 dma_buffer_t dma_buffer;53 /** Backend for TDs and setup data. */ 54 dma_buffer_t ehci_dma_buffer; 55 55 /** List of TDs needed for the transfer - backed by dma_buffer */ 56 56 td_t *tds; -
uspace/drv/bus/usb/ehci/ehci_rh.c
r65c059f rc21e6a5 147 147 batch->error = virthub_base_request(&instance->base, batch->target, 148 148 batch->dir, (void*) batch->setup.buffer, 149 batch->buffer, batch->buffer_size, &batch->transferred_size); 149 batch->dma_buffer.virt, batch->buffer_size, 150 &batch->transferred_size); 150 151 if (batch->error == ENAK) { 151 152 usb_log_debug("RH(%p): BATCH(%p) adding as unfinished", … … 205 206 batch->error = virthub_base_request(&instance->base, batch->target, 206 207 batch->dir, (void*) batch->setup.buffer, 207 batch->buffer, batch->buffer_size, &batch->transferred_size); 208 batch->dma_buffer.virt, batch->buffer_size, 209 &batch->transferred_size); 208 210 usb_transfer_batch_finish(batch); 209 211 } -
uspace/drv/bus/usb/ohci/ohci_batch.c
r65c059f rc21e6a5 113 113 : 0; 114 114 115 if (dma_buffer_alloc(&ohci_batch->ohci_dma_buffer, td_size + setup_size + usb_batch->buffer_size)) {115 if (dma_buffer_alloc(&ohci_batch->ohci_dma_buffer, td_size + setup_size)) { 116 116 usb_log_error("Failed to allocate OHCI DMA buffer."); 117 117 return ENOMEM; … … 129 129 memcpy(ohci_batch->setup_buffer, usb_batch->setup.buffer, setup_size); 130 130 131 ohci_batch->data_buffer = ohci_batch->setup_buffer + setup_size; 132 if (usb_batch->dir == USB_DIRECTION_OUT) 133 memcpy(ohci_batch->data_buffer, usb_batch->buffer, usb_batch->buffer_size); 131 ohci_batch->data_buffer = usb_batch->dma_buffer.virt; 134 132 135 133 batch_setup[usb_batch->ep->transfer_type](ohci_batch); … … 151 149 assert(ohci_batch); 152 150 153 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->base.ep); 151 usb_transfer_batch_t *usb_batch = &ohci_batch->base; 152 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(usb_batch->ep); 154 153 assert(ohci_ep); 155 154 156 155 usb_log_debug("Batch %p checking %zu td(s) for completion.", 157 &ohci_batch->base, ohci_batch->td_count);156 ohci_batch, ohci_batch->td_count); 158 157 usb_log_debug2("ED: %08x:%08x:%08x:%08x.", 159 158 ohci_ep->ed->status, ohci_ep->ed->td_head, … … 167 166 168 167 /* Assume all data got through */ 169 ohci_batch->base.transferred_size = ohci_batch->base.buffer_size;168 usb_batch->transferred_size = usb_batch->buffer_size; 170 169 171 170 /* Check all TDs */ … … 176 175 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 177 176 178 ohci_batch->base.error = td_error(ohci_batch->tds[i]);179 if ( ohci_batch->base.error == EOK) {177 usb_batch->error = td_error(ohci_batch->tds[i]); 178 if (usb_batch->error == EOK) { 180 179 /* If the TD got all its data through, it will report 181 180 * 0 bytes remain, the sole exception is INPUT with … … 190 189 * we leave the very last(unused) TD behind. 191 190 */ 192 ohci_batch->base.transferred_size191 usb_batch->transferred_size 193 192 -= td_remain_size(ohci_batch->tds[i]); 194 193 } else { 195 194 usb_log_debug("Batch %p found error TD(%zu):%08x.", 196 &ohci_batch->base, i, ohci_batch->tds[i]->status);195 ohci_batch, i, ohci_batch->tds[i]->status); 197 196 198 197 /* ED should be stopped because of errors */ … … 213 212 } 214 213 } 215 assert(ohci_batch->base.transferred_size <= 216 ohci_batch->base.buffer_size); 217 218 if (ohci_batch->base.dir == USB_DIRECTION_IN) 219 memcpy(ohci_batch->base.buffer, 220 ohci_batch->data_buffer, 221 ohci_batch->base.transferred_size); 214 assert(usb_batch->transferred_size <= usb_batch->buffer_size); 222 215 223 216 /* Make sure that we are leaving the right TD behind */ -
uspace/drv/bus/usb/ohci/ohci_rh.c
r65c059f rc21e6a5 182 182 batch->error = virthub_base_request(&instance->base, batch->target, 183 183 batch->dir, &batch->setup.packet, 184 batch-> buffer, batch->buffer_size, &batch->transferred_size);184 batch->dma_buffer.virt, batch->buffer_size, &batch->transferred_size); 185 185 if (batch->error == ENAK) { 186 186 /* Lock the HC guard */ … … 233 233 batch->error = virthub_base_request(&instance->base, batch->target, 234 234 batch->dir, &batch->setup.packet, 235 batch-> buffer, batch->buffer_size, &batch->transferred_size);235 batch->dma_buffer.virt, batch->buffer_size, &batch->transferred_size); 236 236 usb_transfer_batch_finish(batch); 237 237 } -
uspace/drv/bus/usb/uhci/uhci_batch.c
r65c059f rc21e6a5 61 61 { 62 62 assert(uhci_batch); 63 free32(uhci_batch->device_buffer);63 dma_buffer_free(&uhci_batch->uhci_dma_buffer); 64 64 free(uhci_batch); 65 65 } … … 110 110 111 111 const size_t total_size = (sizeof(td_t) * uhci_batch->td_count) 112 + sizeof(qh_t) + setup_size + usb_batch->buffer_size;113 uhci_batch->device_buffer = malloc32(total_size); 114 if ( !uhci_batch->device_buffer) {112 + sizeof(qh_t) + setup_size; 113 114 if (dma_buffer_alloc(&uhci_batch->uhci_dma_buffer, total_size)) { 115 115 usb_log_error("Failed to allocate UHCI buffer."); 116 116 return ENOMEM; 117 117 } 118 memset(uhci_batch->device_buffer, 0, total_size); 119 120 uhci_batch->tds = uhci_batch->device_buffer; 121 uhci_batch->qh = 122 (uhci_batch->device_buffer + (sizeof(td_t) * uhci_batch->td_count)); 118 memset(uhci_batch->uhci_dma_buffer.virt, 0, total_size); 119 120 uhci_batch->tds = uhci_batch->uhci_dma_buffer.virt; 121 uhci_batch->qh = (qh_t *) &uhci_batch->tds[uhci_batch->td_count]; 123 122 124 123 qh_init(uhci_batch->qh); 125 124 qh_set_element_td(uhci_batch->qh, &uhci_batch->tds[0]); 126 125 127 void *dest = 128 uhci_batch->device_buffer + (sizeof(td_t) * uhci_batch->td_count) 129 + sizeof(qh_t); 126 void *setup_buffer = uhci_transfer_batch_setup_buffer(uhci_batch); 127 assert(setup_buffer == (void *) (uhci_batch->qh + 1)); 130 128 /* Copy SETUP packet data to the device buffer */ 131 memcpy(dest, usb_batch->setup.buffer, setup_size); 132 dest += setup_size; 133 /* Copy generic data unless they are provided by the device */ 134 if (usb_batch->dir != USB_DIRECTION_IN) { 135 memcpy(dest, usb_batch->buffer, usb_batch->buffer_size); 136 } 129 memcpy(setup_buffer, usb_batch->setup.buffer, setup_size); 130 137 131 usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT 138 132 " memory structures ready.", usb_batch, … … 196 190 } 197 191 198 if (batch->dir == USB_DIRECTION_IN) { 199 assert(batch->transferred_size <= batch->buffer_size); 200 memcpy(batch->buffer, 201 uhci_transfer_batch_data_buffer(uhci_batch), 202 batch->transferred_size); 203 } 192 assert(batch->transferred_size <= batch->buffer_size); 204 193 205 194 return true; -
uspace/drv/bus/usb/uhci/uhci_batch.h
r65c059f rc21e6a5 61 61 /** Number of TDs used by the transfer */ 62 62 size_t td_count; 63 /** Data buffer, must be accessible by the UHCI hw */ 64 void *device_buffer; 63 /* Setup data */ 64 char *setup_buffer; 65 /** Backing TDs + setup_buffer */ 66 dma_buffer_t uhci_dma_buffer; 65 67 /** List element */ 66 68 link_t link; … … 80 82 { 81 83 assert(uhci_batch); 82 assert(uhci_batch->device_buffer); 83 return uhci_batch->device_buffer + sizeof(qh_t) + 84 return uhci_batch->uhci_dma_buffer.virt + sizeof(qh_t) + 84 85 uhci_batch->td_count * sizeof(td_t); 85 86 } … … 93 94 { 94 95 assert(uhci_batch); 95 return uhci_transfer_batch_setup_buffer(uhci_batch) + 96 (uhci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL ? USB_SETUP_PACKET_SIZE : 0); 96 return uhci_batch->base.dma_buffer.virt; 97 97 } 98 98 -
uspace/drv/bus/usb/uhci/uhci_rh.c
r65c059f rc21e6a5 107 107 batch->error = virthub_base_request(&instance->base, batch->target, 108 108 batch->dir, (void*) batch->setup.buffer, 109 batch-> buffer, batch->buffer_size, &batch->transferred_size);109 batch->dma_buffer.virt, batch->buffer_size, &batch->transferred_size); 110 110 if (batch->error == ENAK) 111 111 async_usleep(instance->base.endpoint_descriptor.poll_interval * 1000); -
uspace/drv/bus/usb/vhc/transfer.c
r65c059f rc21e6a5 72 72 rc = usbvirt_control_read(dev, 73 73 batch->setup.buffer, USB_SETUP_PACKET_SIZE, 74 batch-> buffer, batch->buffer_size,74 batch->dma_buffer.virt, batch->buffer_size, 75 75 actual_data_size); 76 76 } else { … … 78 78 rc = usbvirt_control_write(dev, 79 79 batch->setup.buffer, USB_SETUP_PACKET_SIZE, 80 batch-> buffer, batch->buffer_size);80 batch->dma_buffer.virt, batch->buffer_size); 81 81 } 82 82 } else { … … 84 84 rc = usbvirt_data_in(dev, batch->ep->transfer_type, 85 85 batch->ep->endpoint, 86 batch-> buffer, batch->buffer_size,86 batch->dma_buffer.virt, batch->buffer_size, 87 87 actual_data_size); 88 88 } else { … … 90 90 rc = usbvirt_data_out(dev, batch->ep->transfer_type, 91 91 batch->ep->endpoint, 92 batch-> buffer, batch->buffer_size);92 batch->dma_buffer.virt, batch->buffer_size); 93 93 } 94 94 } … … 108 108 rc = usbvirt_ipc_send_control_read(sess, 109 109 batch->setup.buffer, USB_SETUP_PACKET_SIZE, 110 batch-> buffer, batch->buffer_size,110 batch->dma_buffer.virt, batch->buffer_size, 111 111 actual_data_size); 112 112 } else { … … 114 114 rc = usbvirt_ipc_send_control_write(sess, 115 115 batch->setup.buffer, USB_SETUP_PACKET_SIZE, 116 batch-> buffer, batch->buffer_size);116 batch->dma_buffer.virt, batch->buffer_size); 117 117 } 118 118 } else { … … 120 120 rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint, 121 121 batch->ep->transfer_type, 122 batch-> buffer, batch->buffer_size,122 batch->dma_buffer.virt, batch->buffer_size, 123 123 actual_data_size); 124 124 } else { … … 126 126 rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint, 127 127 batch->ep->transfer_type, 128 batch-> buffer, batch->buffer_size);128 batch->dma_buffer.virt, batch->buffer_size); 129 129 } 130 130 } -
uspace/drv/bus/usb/xhci/commands.c
r65c059f rc21e6a5 260 260 // Prevent others from starting CR again. 261 261 cr_set_state(cr, XHCI_CR_STATE_CLOSED); 262 263 XHCI_REG_SET(hc->op_regs, XHCI_OP_CS, 1); 262 264 fibril_mutex_unlock(&cr->guard); 263 265 } -
uspace/drv/bus/usb/xhci/hc.c
r65c059f rc21e6a5 476 476 return ETIMEOUT; 477 477 478 uint64_t dcbaaptr = hc->dcbaa_dma.phys; 479 XHCI_REG_WR(hc->op_regs, XHCI_OP_DCBAAP, dcbaaptr); 478 XHCI_REG_WR(hc->op_regs, XHCI_OP_DCBAAP, hc->dcbaa_dma.phys); 480 479 XHCI_REG_WR(hc->op_regs, XHCI_OP_MAX_SLOTS_EN, hc->max_slots); 481 480 -
uspace/drv/bus/usb/xhci/isoch.c
r65c059f rc21e6a5 480 480 xhci_isoch_t * const isoch = ep->isoch; 481 481 482 if (transfer->batch.buffer_size > ep->base.max_transfer_size) { 483 usb_log_error("Cannot schedule an oversized isochronous transfer."); 484 return ELIMIT; 485 } 482 /* This shall be already checked by endpoint */ 483 assert(transfer->batch.buffer_size <= ep->base.max_transfer_size); 486 484 487 485 fibril_mutex_lock(&isoch->guard); … … 524 522 /* Prepare the transfer. */ 525 523 it->size = transfer->batch.buffer_size; 526 memcpy(it->data.virt, transfer->batch. buffer, it->size);524 memcpy(it->data.virt, transfer->batch.dma_buffer.virt, it->size); 527 525 it->state = ISOCH_FILLED; 528 526 … … 573 571 /* Withdraw results from previous transfer. */ 574 572 if (!it->error) { 575 memcpy(transfer->batch. buffer, it->data.virt, it->size);573 memcpy(transfer->batch.dma_buffer.virt, it->data.virt, it->size); 576 574 transfer->batch.transferred_size = it->size; 577 575 transfer->batch.error = it->error; -
uspace/drv/bus/usb/xhci/transfers.c
r65c059f rc21e6a5 115 115 { 116 116 xhci_transfer_t *transfer = xhci_transfer_from_batch(batch); 117 118 dma_buffer_free(&transfer->hc_buffer);119 117 free(transfer); 120 118 } … … 135 133 size_t i, size_t total, size_t *remaining) 136 134 { 137 const uintptr_t ptr = dma_buffer_phys(&transfer-> hc_buffer,138 transfer-> hc_buffer.virt + i * PAGE_SIZE);135 const uintptr_t ptr = dma_buffer_phys(&transfer->batch.dma_buffer, 136 transfer->batch.dma_buffer.virt + i * PAGE_SIZE); 139 137 140 138 trb->parameter = host2xhci(64, ptr); … … 418 416 } 419 417 420 if (batch->dir == USB_DIRECTION_IN) { 421 assert(batch->buffer); 422 assert(batch->transferred_size <= batch->buffer_size); 423 memcpy(batch->buffer, transfer->hc_buffer.virt, batch->transferred_size); 424 } 418 assert(batch->transferred_size <= batch->buffer_size); 425 419 426 420 usb_transfer_batch_finish(batch); … … 472 466 const usb_transfer_type_t type = batch->ep->transfer_type; 473 467 assert(transfer_handlers[type]); 474 475 if (batch->buffer_size > 0) {476 if (dma_buffer_alloc(&transfer->hc_buffer, batch->buffer_size))477 return ENOMEM;478 }479 480 if (batch->dir != USB_DIRECTION_IN) {481 // Sending stuff from host to device, we need to copy the actual data.482 memcpy(transfer->hc_buffer.virt, batch->buffer, batch->buffer_size);483 }484 468 485 469 /* -
uspace/drv/bus/usb/xhci/transfers.h
r65c059f rc21e6a5 50 50 uint8_t direction; 51 51 52 dma_buffer_t hc_buffer;53 54 52 uintptr_t interrupt_trb_phys; 55 53 } xhci_transfer_t; -
uspace/lib/drv/generic/remote_usbhc.c
r65c059f rc21e6a5 428 428 return err; 429 429 430 /* 431 * As we're going to check the mapping, we must make sure the memory is 432 * actually mapped. We must do it right now, because the area might be 433 * read-only or write-only, and we may be unsure later. 434 */ 435 if (flags & AS_AREA_READ) { 436 char foo = 0; 437 volatile const char *buf = trans->buffer; 438 for (size_t i = 0; i < size; i += PAGE_SIZE) 439 foo += buf[i]; 440 } else { 441 volatile char *buf = trans->buffer; 442 for (size_t i = 0; i < size; i += PAGE_SIZE) 443 buf[i] = 0xff; 444 } 445 430 446 return EOK; 431 447 } -
uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h
r65c059f rc21e6a5 41 41 #include <stddef.h> 42 42 #include <stdint.h> 43 #include <usb/dma_buffer.h> 43 44 #include <usb/request.h> 44 45 #include <usb/usb.h> … … 56 57 /** Target for communication */ 57 58 usb_target_t target; 59 /** Direction of the transfer */ 60 usb_direction_t dir; 58 61 59 62 /** Endpoint used for communication */ 60 63 endpoint_t *ep; 61 62 /** Direction of the transfer */63 usb_direction_t dir;64 65 /** Function called on completion */66 usbhc_iface_transfer_callback_t on_complete;67 /** Arbitrary data for the handler */68 void *on_complete_data;69 64 70 65 /** Place to store SETUP data needed by control transfers */ … … 75 70 } setup; 76 71 77 /** Place for data to send/receive*/78 char *buffer;79 /** Size of memory pointed to by buffer member */72 /** DMA buffer with enforced policy */ 73 dma_buffer_t dma_buffer; 74 /** Size of memory buffer */ 80 75 size_t buffer_size; 76 77 /** 78 * In case the DMA buffer is allocated, the original buffer must to be 79 * stored to be filled after the IN transaction is finished. 80 */ 81 char *original_buffer; 82 83 /** Indicates success/failure of the communication */ 84 errno_t error; 81 85 /** Actually used portion of the buffer */ 82 86 size_t transferred_size; 83 87 84 /** Indicates success/failure of the communication */ 85 errno_t error; 88 /** Function called on completion */ 89 usbhc_iface_transfer_callback_t on_complete; 90 /** Arbitrary data for the handler */ 91 void *on_complete_data; 86 92 } usb_transfer_batch_t; 87 93 … … 108 114 void usb_transfer_batch_init(usb_transfer_batch_t *, endpoint_t *); 109 115 116 /** Buffer preparation */ 117 errno_t usb_transfer_batch_prepare_buffer(usb_transfer_batch_t *, char *); 118 110 119 /** Batch finalization. */ 111 120 void usb_transfer_batch_finish(usb_transfer_batch_t *); -
uspace/lib/usbhost/src/endpoint.c
r65c059f rc21e6a5 74 74 75 75 ep->max_transfer_size = ep->max_packet_size * ep->packets_per_uframe; 76 ep->transfer_buffer_policy = DMA_POLICY_STRICT; 76 77 } 77 78 … … 215 216 * @param name Communication identifier (for nicer output). 216 217 */ 217 int endpoint_send_batch(endpoint_t *ep, usb_target_t target,218 errno_t endpoint_send_batch(endpoint_t *ep, usb_target_t target, 218 219 usb_direction_t direction, char *data, size_t size, uint64_t setup_data, 219 220 usbhc_iface_transfer_callback_t on_complete, void *arg, const char *name) … … 258 259 259 260 batch->target = target; 260 batch->buffer = data;261 batch->buffer_size = size;262 261 batch->setup.packed = setup_data; 263 262 batch->dir = direction; 263 batch->buffer_size = size; 264 265 errno_t err; 266 if ((err = usb_transfer_batch_prepare_buffer(batch, data))) { 267 usb_log_warning("Failed to prepare buffer for batch: %s", str_error(err)); 268 usb_transfer_batch_destroy(batch); 269 return err; 270 } 271 264 272 batch->on_complete = on_complete; 265 273 batch->on_complete_data = arg; -
uspace/lib/usbhost/src/usb_transfer_batch.c
r65c059f rc21e6a5 104 104 105 105 /** 106 * Prepare a DMA buffer according to endpoint policy. 107 * 108 * If the buffer is suitable to be used directly, it is. Otherwise, a bounce 109 * buffer is created. 110 */ 111 errno_t usb_transfer_batch_prepare_buffer( 112 usb_transfer_batch_t *batch, char *buf) 113 { 114 const dma_policy_t policy = batch->ep->transfer_buffer_policy; 115 116 /* Empty transfers do not need a buffer */ 117 if (batch->buffer_size == 0) 118 return EOK; 119 120 if (dma_buffer_check_policy(buf, batch->buffer_size, policy)) { 121 /* Mark this case with invalid address */ 122 batch->original_buffer = NULL; 123 124 /* Fill the buffer with virtual address and lock it for DMA */ 125 return dma_buffer_lock(&batch->dma_buffer, buf, batch->buffer_size); 126 } 127 else { 128 usb_log_debug("Batch(%p): Buffer cannot be used directly, " 129 "falling back to bounce buffer!", batch); 130 const errno_t err = dma_buffer_alloc_policy(&batch->dma_buffer, 131 batch->buffer_size, policy); 132 133 /* Copy the data out */ 134 if (!err && batch->dir == USB_DIRECTION_OUT) 135 memcpy(batch->dma_buffer.virt, buf, batch->buffer_size); 136 137 /* Store the buffer to store the data back before finishing */ 138 batch->original_buffer = buf; 139 140 return err; 141 } 142 } 143 144 /** 106 145 * Finish a transfer batch: call handler, destroy batch, release endpoint. 107 146 * … … 116 155 batch, USB_TRANSFER_BATCH_ARGS(*batch)); 117 156 157 if (batch->error == EOK && batch->buffer_size > 0) { 158 if (batch->original_buffer == NULL) { 159 /* Unlock the buffer for DMA */ 160 dma_buffer_unlock(&batch->dma_buffer, 161 batch->buffer_size); 162 } 163 else { 164 /* We we're forced to use bounce buffer, copy it back */ 165 if (batch->dir == USB_DIRECTION_IN) 166 memcpy(batch->original_buffer, 167 batch->dma_buffer.virt, 168 batch->transferred_size); 169 170 dma_buffer_free(&batch->dma_buffer); 171 } 172 } 173 118 174 if (batch->on_complete) { 119 175 const int err = batch->on_complete(batch->on_complete_data, batch->error, batch->transferred_size); 120 176 if (err) 121 usb_log_warning(" batch %p failed to complete: %s",177 usb_log_warning("Batch %p failed to complete: %s", 122 178 batch, str_error(err)); 123 179 }
Note:
See TracChangeset
for help on using the changeset viewer.