Changeset 1d758fc in mainline for uspace/lib/usbhost/src/usb_transfer_batch.c
- Timestamp:
- 2018-02-12T10:11:47Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5fe3f954
- Parents:
- 2f762a7
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-02-05 03:28:50)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-02-12 10:11:47)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/usbhost/src/usb_transfer_batch.c
r2f762a7 r1d758fc 103 103 } 104 104 105 bool usb_transfer_batch_bounce_required(usb_transfer_batch_t *batch) 106 { 107 if (!batch->size) 108 return false; 109 110 unsigned flags = batch->dma_buffer.policy & DMA_POLICY_FLAGS_MASK; 111 unsigned required_flags = 112 batch->ep->required_transfer_buffer_policy & DMA_POLICY_FLAGS_MASK; 113 114 if (required_flags & ~flags) 115 return true; 116 117 size_t chunk_mask = dma_policy_chunk_mask(batch->dma_buffer.policy); 118 size_t required_chunk_mask = 119 dma_policy_chunk_mask(batch->ep->required_transfer_buffer_policy); 120 121 /* If the chunks are at least as large as required, we're good */ 122 if ((required_chunk_mask & ~chunk_mask) == 0) 123 return false; 124 125 size_t start_chunk = batch->offset & ~chunk_mask; 126 size_t end_chunk = (batch->offset + batch->size - 1) & ~chunk_mask; 127 128 /* The requested area crosses a chunk boundary */ 129 if (start_chunk != end_chunk) 130 return true; 131 132 return false; 133 } 134 105 135 errno_t usb_transfer_batch_bounce(usb_transfer_batch_t *batch) 106 136 { … … 108 138 assert(!batch->is_bounced); 109 139 110 if (dma_buffer_is_set(&batch->dma_buffer)) 111 dma_buffer_unlock(&batch->dma_buffer, batch->buffer_size); 140 dma_buffer_release(&batch->dma_buffer); 141 142 batch->original_buffer = batch->dma_buffer.virt + batch->offset; 112 143 113 144 usb_log_debug("Batch(%p): Buffer cannot be used directly, " … … 115 146 116 147 const errno_t err = dma_buffer_alloc_policy(&batch->dma_buffer, 117 batch-> buffer_size, batch->ep->transfer_buffer_policy);148 batch->size, batch->ep->transfer_buffer_policy); 118 149 if (err) 119 150 return err; … … 121 152 /* Copy the data out */ 122 153 if (batch->dir == USB_DIRECTION_OUT) 123 memcpy(batch->dma_buffer.virt, batch->buffer, batch->buffer_size); 154 memcpy(batch->dma_buffer.virt, 155 batch->original_buffer, 156 batch->size); 124 157 125 158 batch->is_bounced = true; 159 batch->offset = 0; 160 126 161 return err; 127 }128 129 /**130 * Prepare a DMA buffer according to endpoint policy.131 *132 * If the buffer is suitable to be used directly, it is. Otherwise, a bounce133 * buffer is created.134 */135 errno_t usb_transfer_batch_prepare_buffer(usb_transfer_batch_t *batch, char *buf)136 {137 /* Empty transfers do not need a buffer */138 if (batch->buffer_size == 0)139 return EOK;140 141 batch->buffer = buf;142 143 const dma_policy_t policy = batch->ep->transfer_buffer_policy;144 145 /*146 * We don't have enough information (yet, WIP) to know if we can skip147 * the bounce, so check the conditions carefully.148 */149 if (!dma_buffer_check_policy(buf, batch->buffer_size, policy))150 return usb_transfer_batch_bounce(batch);151 152 /* Fill the buffer with virtual address and lock it for DMA */153 return dma_buffer_lock(&batch->dma_buffer, buf, batch->buffer_size);154 162 } 155 163 … … 167 175 batch, USB_TRANSFER_BATCH_ARGS(*batch)); 168 176 169 if (batch->error == EOK && batch->buffer_size > 0) { 170 if (!batch->is_bounced) { 171 /* Unlock the buffer for DMA */ 172 dma_buffer_unlock(&batch->dma_buffer, 173 batch->buffer_size); 177 if (batch->error == EOK && batch->size > 0) { 178 if (batch->is_bounced) { 179 /* We we're forced to use bounce buffer, copy it back */ 180 if (batch->dir == USB_DIRECTION_IN) 181 memcpy(batch->original_buffer, 182 batch->dma_buffer.virt, 183 batch->transferred_size); 184 185 dma_buffer_free(&batch->dma_buffer); 174 186 } 175 187 else { 176 /* We we're forced to use bounce buffer, copy it back */ 177 if (batch->dir == USB_DIRECTION_IN) 178 memcpy(batch->buffer, 179 batch->dma_buffer.virt, 180 batch->transferred_size); 181 182 dma_buffer_free(&batch->dma_buffer); 188 dma_buffer_release(&batch->dma_buffer); 183 189 } 184 190 }
Note:
See TracChangeset
for help on using the changeset viewer.