Changeset 35c37fc in mainline for uspace/drv/bus/usb/ehci/ehci_batch.c
- Timestamp:
- 2018-01-05T20:15:08Z (6 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9e5b162
- Parents:
- b60944b
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-05 16:11:04)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-05 20:15:08)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/ehci_batch.c
rb60944b r35c37fc 42 42 #include <usb/usb.h> 43 43 #include <usb/debug.h> 44 #include <usb/host/utils/malloc32.h>45 44 46 45 #include "ehci_batch.h" … … 62 61 { 63 62 assert(ehci_batch); 64 if (ehci_batch->tds) { 65 for (size_t i = 0; i < ehci_batch->td_count; ++i) { 66 free32(ehci_batch->tds[i]); 67 } 68 free(ehci_batch->tds); 69 } 70 free32(ehci_batch->device_buffer); 63 dma_buffer_free(&ehci_batch->dma_buffer); 71 64 free(ehci_batch); 72 65 usb_log_debug2("Batch(%p): disposed", ehci_batch); … … 112 105 const size_t size = ehci_batch->base.buffer_size; 113 106 114 /* Mix setup stage and data together, we have enough space */ 115 if (size + setup_size > 0) { 116 /* Use one buffer for setup and data stage */ 117 ehci_batch->device_buffer = malloc32(size + setup_size); 118 if (!ehci_batch->device_buffer) { 107 /* Add TD left over by the previous transfer */ 108 ehci_batch->qh = ehci_endpoint_get(ehci_batch->base.ep)->qh; 109 110 /* Determine number of TDs needed */ 111 ehci_batch->td_count = (size + EHCI_TD_MAX_TRANSFER - 1) 112 / EHCI_TD_MAX_TRANSFER; 113 114 /* Control transfer need Setup and Status stage */ 115 if (ehci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) { 116 ehci_batch->td_count += 2; 117 } 118 119 const size_t tds_size = ehci_batch->td_count * sizeof(td_t); 120 121 /* Mix setup stage, data and TDs together, we have enough space */ 122 if (size + setup_size + tds_size > 0) { 123 if (dma_buffer_alloc(&ehci_batch->dma_buffer, tds_size + setup_size + size)) { 119 124 usb_log_error("Batch %p: Failed to allocate device " 120 125 "buffer", ehci_batch); 121 126 return ENOMEM; 122 127 } 128 /* Clean TDs */ 129 ehci_batch->tds = ehci_batch->dma_buffer.virt; 130 memset(ehci_batch->tds, 0, tds_size); 123 131 /* Copy setup data */ 124 memcpy(ehci_batch->device_buffer, ehci_batch->base.setup.buffer, 125 132 ehci_batch->setup_buffer = ehci_batch->dma_buffer.virt + tds_size; 133 memcpy(ehci_batch->setup_buffer, ehci_batch->base.setup.buffer, setup_size); 126 134 /* Copy generic data */ 135 ehci_batch->data_buffer = ehci_batch->setup_buffer + setup_size; 127 136 if (ehci_batch->base.dir != USB_DIRECTION_IN) 128 memcpy(ehci_batch->device_buffer + setup_size, 129 ehci_batch->base.buffer, ehci_batch->base.buffer_size); 130 } 131 132 /* Add TD left over by the previous transfer */ 133 ehci_batch->qh = ehci_endpoint_get(ehci_batch->base.ep)->qh; 134 135 /* Determine number of TDs needed */ 136 ehci_batch->td_count = (size + EHCI_TD_MAX_TRANSFER - 1) 137 / EHCI_TD_MAX_TRANSFER; 138 139 /* Control transfer need Setup and Status stage */ 140 if (ehci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) { 141 ehci_batch->td_count += 2; 142 } 143 144 ehci_batch->tds = calloc(ehci_batch->td_count, sizeof(td_t*)); 145 if (!ehci_batch->tds) { 146 usb_log_error("Batch %p: Failed to allocate EHCI transfer " 147 "descriptors.", ehci_batch); 148 return ENOMEM; 149 } 150 151 for (unsigned i = 0; i < ehci_batch->td_count; ++i) { 152 ehci_batch->tds[i] = malloc32(sizeof(td_t)); 153 if (!ehci_batch->tds[i]) { 154 usb_log_error("Batch %p: Failed to allocate TD %d.", 155 ehci_batch, i); 156 return ENOMEM; 157 } 158 memset(ehci_batch->tds[i], 0, sizeof(td_t)); 137 memcpy(ehci_batch->data_buffer, 138 ehci_batch->base.buffer, 139 ehci_batch->base.buffer_size); 159 140 } 160 141 … … 203 184 /* Check all TDs */ 204 185 for (size_t i = 0; i < ehci_batch->td_count; ++i) { 205 assert(ehci_batch->tds[i] != NULL);206 186 usb_log_debug("Batch %p: TD %zu: %08x:%08x:%08x.", 207 187 ehci_batch, i, 208 ehci_batch->tds[i] ->status, ehci_batch->tds[i]->next,209 ehci_batch->tds[i] ->alternate);210 211 ehci_batch->base.error = td_error( ehci_batch->tds[i]);188 ehci_batch->tds[i].status, ehci_batch->tds[i].next, 189 ehci_batch->tds[i].alternate); 190 191 ehci_batch->base.error = td_error(&ehci_batch->tds[i]); 212 192 if (ehci_batch->base.error == EOK) { 213 193 /* If the TD got all its data through, it will report … … 224 204 */ 225 205 ehci_batch->base.transfered_size 226 -= td_remain_size( ehci_batch->tds[i]);206 -= td_remain_size(&ehci_batch->tds[i]); 227 207 } else { 228 208 usb_log_debug("Batch %p found error TD(%zu):%08x (%d).", 229 209 ehci_batch, i, 230 ehci_batch->tds[i] ->status,210 ehci_batch->tds[i].status, 231 211 ehci_batch->base.error); 232 212 /* Clear possible ED HALT */ … … 238 218 assert(ehci_batch->base.transfered_size <= ehci_batch->base.buffer_size); 239 219 240 const size_t setup_size = (ehci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL)241 ? USB_SETUP_PACKET_SIZE242 : 0;243 244 220 if (ehci_batch->base.dir == USB_DIRECTION_IN) 245 221 memcpy(ehci_batch->base.buffer, 246 ehci_batch->d evice_buffer + setup_size,222 ehci_batch->data_buffer, 247 223 ehci_batch->base.transfered_size); 248 224 … … 263 239 { 264 240 assert(ehci_batch); 265 qh_set_next_td(ehci_batch->qh, ehci_batch->tds[0]);241 qh_set_next_td(ehci_batch->qh, dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[0])); 266 242 } 267 243 … … 281 257 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 282 258 283 usb_log_debug2("Batch %p: Control QH(% "PRIxn"): "259 usb_log_debug2("Batch %p: Control QH(%p): " 284 260 "%08x:%08x:%08x:%08x:%08x:%08x", ehci_batch, 285 addr_to_phys(ehci_batch->qh),261 ehci_batch->qh, 286 262 ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap, 287 263 ehci_batch->qh->status, ehci_batch->qh->current, … … 293 269 294 270 int toggle = 0; 295 const char* buffer = ehci_batch->device_buffer;296 271 const usb_direction_t data_dir = dir; 297 272 const usb_direction_t status_dir = reverse_dir[dir]; 298 273 299 274 /* Setup stage */ 300 td_init(ehci_batch->tds[0], ehci_batch->tds[1], USB_DIRECTION_BOTH, 301 buffer, USB_SETUP_PACKET_SIZE, toggle, false); 275 td_init(&ehci_batch->tds[0], 276 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[1]), 277 dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->setup_buffer), 278 USB_DIRECTION_BOTH, USB_SETUP_PACKET_SIZE, toggle, false); 302 279 usb_log_debug2("Batch %p: Created CONTROL SETUP TD(%"PRIxn"): " 303 280 "%08x:%08x:%08x", ehci_batch, 304 addr_to_phys(ehci_batch->tds[0]), 305 ehci_batch->tds[0]->status, ehci_batch->tds[0]->next, 306 ehci_batch->tds[0]->alternate); 307 buffer += USB_SETUP_PACKET_SIZE; 281 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[0]), 282 ehci_batch->tds[0].status, ehci_batch->tds[0].next, 283 ehci_batch->tds[0].alternate); 308 284 309 285 /* Data stage */ 310 size_ttd_current = 1;286 unsigned td_current = 1; 311 287 size_t remain_size = ehci_batch->base.buffer_size; 288 uintptr_t buffer = dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->data_buffer); 312 289 while (remain_size > 0) { 313 const size_t transfer_size = 314 min(remain_size, EHCI_TD_MAX_TRANSFER); 290 const size_t transfer_size = min(remain_size, EHCI_TD_MAX_TRANSFER); 315 291 toggle = 1 - toggle; 316 292 317 td_init( ehci_batch->tds[td_current],318 ehci_batch->tds[td_current + 1], data_dir, buffer,319 transfer_size, toggle, false);293 td_init(&ehci_batch->tds[td_current], 294 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current + 1]), 295 buffer, data_dir, transfer_size, toggle, false); 320 296 usb_log_debug2("Batch %p: Created CONTROL DATA TD(%"PRIxn"): " 321 297 "%08x:%08x:%08x", ehci_batch, 322 addr_to_phys(ehci_batch->tds[td_current]),323 ehci_batch->tds[td_current] ->status,324 ehci_batch->tds[td_current] ->next,325 ehci_batch->tds[td_current] ->alternate);298 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]), 299 ehci_batch->tds[td_current].status, 300 ehci_batch->tds[td_current].next, 301 ehci_batch->tds[td_current].alternate); 326 302 327 303 buffer += transfer_size; … … 333 309 /* Status stage */ 334 310 assert(td_current == ehci_batch->td_count - 1); 335 td_init( ehci_batch->tds[td_current], NULL, status_dir, NULL, 0, 1, true);336 usb_log_debug2("Batch %p: Created CONTROL STATUS TD (%"PRIxn"): "337 "%08x:%08x:%08x", ehci_batch, 338 addr_to_phys(ehci_batch->tds[td_current]),339 ehci_batch->tds[td_current] ->status,340 ehci_batch->tds[td_current] ->next,341 ehci_batch->tds[td_current] ->alternate);311 td_init(&ehci_batch->tds[td_current], 0, 0, status_dir, 0, 1, true); 312 usb_log_debug2("Batch %p: Created CONTROL STATUS TD %d(%"PRIxn"): " 313 "%08x:%08x:%08x", ehci_batch, td_current, 314 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]), 315 ehci_batch->tds[td_current].status, 316 ehci_batch->tds[td_current].next, 317 ehci_batch->tds[td_current].alternate); 342 318 } 343 319 … … 354 330 assert(ehci_batch); 355 331 356 usb_log_debug2("Batch %p: Data QH(% "PRIxn"): "332 usb_log_debug2("Batch %p: Data QH(%p): " 357 333 "%08x:%08x:%08x:%08x:%08x:%08x", ehci_batch, 358 addr_to_phys(ehci_batch->qh),334 ehci_batch->qh, 359 335 ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap, 360 336 ehci_batch->qh->status, ehci_batch->qh->current, … … 363 339 size_t td_current = 0; 364 340 size_t remain_size = ehci_batch->base.buffer_size; 365 char *buffer = ehci_batch->device_buffer;341 uintptr_t buffer = dma_buffer_phys(&ehci_batch->dma_buffer, ehci_batch->data_buffer); 366 342 while (remain_size > 0) { 367 343 const size_t transfer_size = remain_size > EHCI_TD_MAX_TRANSFER … … 369 345 370 346 const bool last = (remain_size == transfer_size); 371 td_init( 372 ehci_batch->tds[td_current], 373 last ? NULL : ehci_batch->tds[td_current + 1], 374 ehci_batch->base.dir, buffer, transfer_size, -1, last); 347 td_init(&ehci_batch->tds[td_current], 348 last ? 0 : dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current + 1]), 349 buffer, ehci_batch->base.dir, transfer_size, -1, last); 375 350 376 351 usb_log_debug2("Batch %p: DATA TD(%"PRIxn": %08x:%08x:%08x", 377 352 ehci_batch, 378 addr_to_phys(ehci_batch->tds[td_current]),379 ehci_batch->tds[td_current] ->status,380 ehci_batch->tds[td_current] ->next,381 ehci_batch->tds[td_current] ->alternate);353 dma_buffer_phys(&ehci_batch->dma_buffer, &ehci_batch->tds[td_current]), 354 ehci_batch->tds[td_current].status, 355 ehci_batch->tds[td_current].next, 356 ehci_batch->tds[td_current].alternate); 382 357 383 358 buffer += transfer_size;
Note:
See TracChangeset
for help on using the changeset viewer.