Changeset 6602e97 in mainline
- Timestamp:
- 2014-01-25T07:06:48Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a752c78c
- Parents:
- 3f2cb17
- Location:
- uspace/drv/bus/usb/ehci
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ehci/Makefile
r3f2cb17 r6602e97 51 51 hc.c \ 52 52 hw_struct/queue_head.c \ 53 hw_struct/transfer_descriptor.c \ 53 54 main.c \ 54 55 res.c -
uspace/drv/bus/usb/ehci/ehci_batch.c
r3f2cb17 r6602e97 46 46 #include "utils/malloc32.h" 47 47 48 /* The buffer pointer list in the qTD is long enough to support a maximum 49 * transfer size of 20K bytes. This case occurs when all five buffer pointers 50 * are used and the first offset is zero. A qTD handles a 16Kbyte buffer 51 * with any starting buffer alignment. EHCI specs p. 87 (pdf p. 97) */ 52 #define EHCI_TD_MAX_TRANSFER (16 * 1024) 53 48 54 static void (*const batch_setup[])(ehci_transfer_batch_t*, usb_direction_t); 49 55 … … 60 66 ehci_endpoint_get(ehci_batch->usb_batch->ep); 61 67 assert(ehci_ep); 62 for ( unsignedi = 0; i < ehci_batch->td_count; ++i) {68 for (size_t i = 0; i < ehci_batch->td_count; ++i) { 63 69 if (ehci_batch->tds[i] != ehci_ep->td) 64 70 free32(ehci_batch->tds[i]); … … 105 111 } 106 112 link_initialize(&ehci_batch->link); 107 // ehci_batch->td_count = 108 // (usb_batch->buffer_size + EHCI_TD_MAX_TRANSFER - 1) 109 // / EHCI_TD_MAX_TRANSFER; 113 ehci_batch->td_count = 114 (usb_batch->buffer_size + EHCI_TD_MAX_TRANSFER - 1) 115 / EHCI_TD_MAX_TRANSFER; 116 110 117 /* Control transfer need Setup and Status stage */ 111 118 if (usb_batch->ep->transfer_type == USB_TRANSFER_CONTROL) { … … 113 120 } 114 121 115 /* We need an extra place for TD that was left at ED */ 116 ehci_batch->tds = calloc(ehci_batch->td_count + 1, sizeof(td_t*)); 122 ehci_batch->tds = calloc(ehci_batch->td_count, sizeof(td_t*)); 117 123 if (!ehci_batch->tds) { 118 124 usb_log_error("Failed to allocate EHCI transfer descriptors."); … … 122 128 /* Add TD left over by the previous transfer */ 123 129 ehci_batch->qh = ehci_endpoint_get(usb_batch->ep)->qh; 124 ehci_batch->tds[0] = ehci_endpoint_get(usb_batch->ep)->td; 125 126 for (unsigned i = 1; i <= ehci_batch->td_count; ++i) { 130 131 for (unsigned i = 0; i < ehci_batch->td_count; ++i) { 127 132 ehci_batch->tds[i] = malloc32(sizeof(td_t)); 128 133 if (!ehci_batch->tds[i]) { … … 133 138 134 139 135 /* NOTE: EHCI is capable of handling buffer that crosses page boundaries 136 * it is, however, not capable of handling buffer that occupies more 137 * than two pages (the first page is computed using start pointer, the 138 * other using the end pointer) */ 140 /* Mix setup stage and data together, we have enough space */ 139 141 if (usb_batch->setup_size + usb_batch->buffer_size > 0) { 140 142 /* Use one buffer for setup and data stage */ … … 182 184 usb_log_debug("Batch %p checking %zu td(s) for completion.\n", 183 185 ehci_batch->usb_batch, ehci_batch->td_count); 184 #if 0 185 usb_log_debug2("ED: %08x:%08x:%08x:%08x.\n", 186 ehci_batch->ed->status, ehci_batch->ed->td_head, 187 ehci_batch->ed->td_tail, ehci_batch->ed->next); 188 189 if (!ed_inactive(ehci_batch->ed) && ed_transfer_pending(ehci_batch->ed)) 186 187 usb_log_debug2("QH: %08x:%08x:%08x:%08x:%08x:%08x.\n", 188 ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap, 189 ehci_batch->qh->status, ehci_batch->qh->current, 190 ehci_batch->qh->next, ehci_batch->qh->alternate); 191 192 if (!qh_halted(ehci_batch->qh) && qh_transfer_pending(ehci_batch->qh)) 190 193 return false; 191 194 … … 197 200 ehci_batch->usb_batch->buffer_size; 198 201 199 /* Assume we will leave the last(unused) TD behind */200 unsigned leave_td = ehci_batch->td_count;201 202 202 /* Check all TDs */ 203 203 for (size_t i = 0; i < ehci_batch->td_count; ++i) { 204 204 assert(ehci_batch->tds[i] != NULL); 205 usb_log_debug("TD %zu: %08x:%08x:%08x :%08x.\n", i,206 ehci_batch->tds[i]->status, ehci_batch->tds[i]-> cbp,207 ehci_batch->tds[i]-> next, ehci_batch->tds[i]->be);208 205 usb_log_debug("TD %zu: %08x:%08x:%08x.", i, 206 ehci_batch->tds[i]->status, ehci_batch->tds[i]->next, 207 ehci_batch->tds[i]->alternate); 208 #if 0 209 209 ehci_batch->usb_batch->error = td_error(ehci_batch->tds[i]); 210 210 if (ehci_batch->usb_batch->error == EOK) { … … 251 251 break; 252 252 } 253 } 253 #endif 254 } 255 254 256 assert(ehci_batch->usb_batch->transfered_size <= 255 257 ehci_batch->usb_batch->buffer_size); 256 258 #if 0 257 259 /* Store the remaining TD */ 258 260 ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ehci_batch->usb_batch->ep); … … 291 293 assert(ehci_batch->usb_batch); 292 294 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 293 #if 0 294 usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ehci_batch->ed, 295 ehci_batch->ed->status, ehci_batch->ed->td_tail, 296 ehci_batch->ed->td_head, ehci_batch->ed->next); 295 296 usb_log_debug2("Control QH: %08x:%08x:%08x:%08x:%08x:%08x", 297 ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap, 298 ehci_batch->qh->status, ehci_batch->qh->current, 299 ehci_batch->qh->next, ehci_batch->qh->alternate); 297 300 static const usb_direction_t reverse_dir[] = { 298 301 [USB_DIRECTION_IN] = USB_DIRECTION_OUT, … … 309 312 ehci_batch->tds[0], ehci_batch->tds[1], USB_DIRECTION_BOTH, 310 313 buffer, ehci_batch->usb_batch->setup_size, toggle); 311 usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x :%08x.\n",312 ehci_batch->tds[0]->status, ehci_batch->tds[0]-> cbp,313 ehci_batch->tds[0]-> next, ehci_batch->tds[0]->be);314 usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x", 315 ehci_batch->tds[0]->status, ehci_batch->tds[0]->next, 316 ehci_batch->tds[0]->alternate); 314 317 buffer += ehci_batch->usb_batch->setup_size; 315 318 … … 325 328 ehci_batch->tds[td_current + 1], 326 329 data_dir, buffer, transfer_size, toggle); 327 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x :%08x.\n",330 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x", 328 331 ehci_batch->tds[td_current]->status, 329 ehci_batch->tds[td_current]->cbp,330 332 ehci_batch->tds[td_current]->next, 331 ehci_batch->tds[td_current]-> be);333 ehci_batch->tds[td_current]->alternate); 332 334 333 335 buffer += transfer_size; … … 341 343 td_init(ehci_batch->tds[td_current], ehci_batch->tds[td_current + 1], 342 344 status_dir, NULL, 0, 1); 343 usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x :%08x.\n",345 usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x", 344 346 ehci_batch->tds[td_current]->status, 345 ehci_batch->tds[td_current]->cbp,346 347 ehci_batch->tds[td_current]->next, 347 ehci_batch->tds[td_current]-> be);348 #endif 348 ehci_batch->tds[td_current]->alternate); 349 349 350 usb_log_debug2( 350 351 "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized.\n", \ … … 368 369 assert(ehci_batch->usb_batch); 369 370 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 370 #if 0 371 usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ehci_batch->ed, 372 ehci_batch->ed->status, ehci_batch->ed->td_tail, 373 ehci_batch->ed->td_head, ehci_batch->ed->next); 371 372 usb_log_debug2("Control QH: %08x:%08x:%08x:%08x:%08x:%08x", 373 ehci_batch->qh->ep_char, ehci_batch->qh->ep_cap, 374 ehci_batch->qh->status, ehci_batch->qh->current, 375 ehci_batch->qh->next, ehci_batch->qh->alternate); 374 376 375 377 size_t td_current = 0; … … 384 386 dir, buffer, transfer_size, -1); 385 387 386 usb_log_debug("Created DATA TD: %08x:%08x:%08x :%08x.\n",388 usb_log_debug("Created DATA TD: %08x:%08x:%08x", 387 389 ehci_batch->tds[td_current]->status, 388 ehci_batch->tds[td_current]->cbp,389 390 ehci_batch->tds[td_current]->next, 390 ehci_batch->tds[td_current]-> be);391 ehci_batch->tds[td_current]->alternate); 391 392 392 393 buffer += transfer_size; … … 395 396 ++td_current; 396 397 } 397 #endif 398 398 399 usb_log_debug2( 399 "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized .\n", \400 "Batch %p %s %s " USB_TRANSFER_BATCH_FMT " initialized", 400 401 ehci_batch->usb_batch, 401 402 usb_str_transfer_type(ehci_batch->usb_batch->ep->transfer_type), -
uspace/drv/bus/usb/ehci/hw_struct/queue_head.h
r3f2cb17 r6602e97 178 178 } 179 179 180 static inline bool qh_halted(const qh_t *qh) 181 { 182 assert(qh); 183 return (EHCI_MEM32_RD(qh->status) & QH_STATUS_HALTED_FLAG); 184 } 185 186 static inline void qh_halt(qh_t *qh) 187 { 188 assert(qh); 189 EHCI_MEM32_SET(qh->status, QH_STATUS_HALTED_FLAG); 190 } 191 192 static inline bool qh_transfer_pending(const qh_t *qh) 193 { 194 assert(qh); 195 return !(EHCI_MEM32_RD(qh->next) & LINK_POINTER_TERMINATE_FLAG); 196 } 197 180 198 181 199 void qh_init(qh_t *instance, const endpoint_t *ep); -
uspace/drv/bus/usb/ehci/hw_struct/transfer_descriptor.h
r3f2cb17 r6602e97 67 67 68 68 volatile uint32_t buffer_pointer[5]; 69 #define SITD_BUFFER_POINTER_MASK 0xfffff00069 #define TD_BUFFER_POINTER_MASK 0xfffff000 70 70 /* Only the first page pointer */ 71 #define SITD_BUFFER_POINTER_CURRENT_MASK 0xfff 72 #define SITD_BUFFER_POINTER_CURRENT_SHIFT 0 71 #define TD_BUFFER_POINTER_OFFSET_MASK 0xfff 73 72 74 73 } td_t; 74 75 void td_init(td_t *td, const td_t *next, usb_direction_t dir, const void * buf, 76 size_t buf_size, int toggle); 77 75 78 #endif 76 79 /**
Note:
See TracChangeset
for help on using the changeset viewer.