Changeset 5fd9c30 in mainline for uspace/drv/bus/usb/ohci/ohci_batch.c
- Timestamp:
- 2017-10-21T20:52:56Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 766043c
- Parents:
- 74b852b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci_batch.c
r74b852b r5fd9c30 47 47 #include "ohci_bus.h" 48 48 49 static void (*const batch_setup[])(ohci_transfer_batch_t* , usb_direction_t);49 static void (*const batch_setup[])(ohci_transfer_batch_t*); 50 50 51 51 /** Safely destructs ohci_transfer_batch_t structure … … 53 53 * @param[in] ohci_batch Instance to destroy. 54 54 */ 55 static void ohci_transfer_batch_dispose(ohci_transfer_batch_t *ohci_batch) 56 { 57 if (!ohci_batch) 58 return; 55 void ohci_transfer_batch_destroy(ohci_transfer_batch_t *ohci_batch) 56 { 57 assert(ohci_batch); 59 58 if (ohci_batch->tds) { 60 59 const ohci_endpoint_t *ohci_ep = … … 67 66 free(ohci_batch->tds); 68 67 } 69 usb_transfer_batch_destroy(ohci_batch->usb_batch);70 68 free32(ohci_batch->device_buffer); 71 69 free(ohci_batch); 72 }73 74 /** Finishes usb_transfer_batch and destroys the structure.75 *76 * @param[in] uhci_batch Instance to finish and destroy.77 */78 void ohci_transfer_batch_finish_dispose(ohci_transfer_batch_t *ohci_batch)79 {80 assert(ohci_batch);81 assert(ohci_batch->usb_batch);82 usb_transfer_batch_finish(ohci_batch->usb_batch,83 ohci_batch->device_buffer + ohci_batch->usb_batch->setup_size);84 ohci_transfer_batch_dispose(ohci_batch);85 70 } 86 71 … … 90 75 * @return Valid pointer if all structures were successfully created, 91 76 * NULL otherwise. 92 * 93 * Determines the number of needed transfer descriptors (TDs). 94 * Prepares a transport buffer (that is accessible by the hardware). 95 * Initializes parameters needed for the transfer and callback. 96 */ 97 ohci_transfer_batch_t * ohci_transfer_batch_get(usb_transfer_batch_t *usb_batch) 98 { 99 assert(usb_batch); 77 */ 78 ohci_transfer_batch_t * ohci_transfer_batch_create(endpoint_t *ep) 79 { 80 assert(ep); 100 81 101 82 ohci_transfer_batch_t *ohci_batch = … … 103 84 if (!ohci_batch) { 104 85 usb_log_error("Failed to allocate OHCI batch data."); 105 goto dispose; 106 } 86 return NULL; 87 } 88 89 usb_transfer_batch_init(&ohci_batch->base, ep); 107 90 link_initialize(&ohci_batch->link); 108 ohci_batch->td_count = 109 (usb_batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1) 91 92 return ohci_batch; 93 } 94 95 /** Prepares a batch to be sent. 96 * 97 * Determines the number of needed transfer descriptors (TDs). 98 * Prepares a transport buffer (that is accessible by the hardware). 99 * Initializes parameters needed for the transfer and callback. 100 */ 101 int ohci_transfer_batch_prepare(ohci_transfer_batch_t *ohci_batch) 102 { 103 assert(ohci_batch); 104 105 const size_t setup_size = (ohci_batch->base.ep->transfer_type == USB_TRANSFER_CONTROL) 106 ? USB_SETUP_PACKET_SIZE 107 : 0; 108 109 usb_transfer_batch_t *usb_batch = &ohci_batch->base; 110 111 ohci_batch->td_count = (usb_batch->buffer_size + OHCI_TD_MAX_TRANSFER - 1) 110 112 / OHCI_TD_MAX_TRANSFER; 111 113 /* Control transfer need Setup and Status stage */ … … 118 120 if (!ohci_batch->tds) { 119 121 usb_log_error("Failed to allocate OHCI transfer descriptors."); 120 goto dispose;122 return ENOMEM; 121 123 } 122 124 … … 129 131 if (!ohci_batch->tds[i]) { 130 132 usb_log_error("Failed to allocate TD %d.", i); 131 goto dispose;133 return ENOMEM; 132 134 } 133 135 } 134 135 136 136 137 /* NOTE: OHCI is capable of handling buffer that crosses page boundaries … … 138 139 * than two pages (the first page is computed using start pointer, the 139 140 * other using the end pointer) */ 140 if ( usb_batch->setup_size + usb_batch->buffer_size > 0) {141 if (setup_size + usb_batch->buffer_size > 0) { 141 142 /* Use one buffer for setup and data stage */ 142 143 ohci_batch->device_buffer = 143 malloc32( usb_batch->setup_size + usb_batch->buffer_size);144 malloc32(setup_size + usb_batch->buffer_size); 144 145 if (!ohci_batch->device_buffer) { 145 146 usb_log_error("Failed to allocate device buffer"); 146 goto dispose;147 return ENOMEM; 147 148 } 148 149 /* Copy setup data */ 149 memcpy(ohci_batch->device_buffer, usb_batch->setup_buffer, 150 usb_batch->setup_size); 150 memcpy(ohci_batch->device_buffer, usb_batch->setup.buffer, setup_size); 151 151 /* Copy generic data */ 152 152 if (usb_batch->ep->direction != USB_DIRECTION_IN) 153 153 memcpy( 154 ohci_batch->device_buffer + usb_batch->setup_size,154 ohci_batch->device_buffer + setup_size, 155 155 usb_batch->buffer, usb_batch->buffer_size); 156 156 } 157 ohci_batch->usb_batch = usb_batch; 158 159 const usb_direction_t dir = usb_transfer_batch_direction(usb_batch); 157 160 158 assert(batch_setup[usb_batch->ep->transfer_type]); 161 batch_setup[usb_batch->ep->transfer_type](ohci_batch, dir); 162 163 return ohci_batch; 164 dispose: 165 ohci_transfer_batch_dispose(ohci_batch); 166 return NULL; 159 batch_setup[usb_batch->ep->transfer_type](ohci_batch); 160 161 return EOK; 167 162 } 168 163 … … 176 171 * completes with the last TD. 177 172 */ 178 bool ohci_transfer_batch_is_complete(const ohci_transfer_batch_t *ohci_batch) 179 { 180 assert(ohci_batch); 181 assert(ohci_batch->usb_batch); 173 bool ohci_transfer_batch_check_completed(ohci_transfer_batch_t *ohci_batch) 174 { 175 assert(ohci_batch); 182 176 183 177 usb_log_debug("Batch %p checking %zu td(s) for completion.\n", … … 194 188 195 189 /* Assume all data got through */ 196 ohci_batch->usb_batch->transfered_size = 197 ohci_batch->usb_batch->buffer_size; 190 ohci_batch->base.transfered_size = ohci_batch->base.buffer_size; 198 191 199 192 /* Assume we will leave the last(unused) TD behind */ … … 207 200 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 208 201 209 ohci_batch-> usb_batch->error = td_error(ohci_batch->tds[i]);210 if (ohci_batch-> usb_batch->error == EOK) {202 ohci_batch->base.error = td_error(ohci_batch->tds[i]); 203 if (ohci_batch->base.error == EOK) { 211 204 /* If the TD got all its data through, it will report 212 205 * 0 bytes remain, the sole exception is INPUT with … … 221 214 * we leave the very last(unused) TD behind. 222 215 */ 223 ohci_batch-> usb_batch->transfered_size216 ohci_batch->base.transfered_size 224 217 -= td_remain_size(ohci_batch->tds[i]); 225 218 } else { … … 252 245 } 253 246 } 254 assert(ohci_batch->usb_batch->transfered_size <= 255 ohci_batch->usb_batch->buffer_size); 247 assert(ohci_batch->base.transfered_size <= 248 ohci_batch->base.buffer_size); 249 250 if (ohci_batch->base.dir == USB_DIRECTION_IN) 251 memcpy(ohci_batch->base.buffer, ohci_batch->device_buffer, ohci_batch->base.transfered_size); 256 252 257 253 /* Store the remaining TD */ 258 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch-> usb_batch->ep);254 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->base.ep); 259 255 assert(ohci_ep); 260 256 ohci_ep->td = ohci_batch->tds[leave_td]; … … 286 282 * Status stage with toggle 1 and direction supplied by parameter. 287 283 */ 288 static void batch_control(ohci_transfer_batch_t *ohci_batch, usb_direction_t dir) 289 { 290 assert(ohci_batch); 291 assert(ohci_batch->usb_batch); 284 static void batch_control(ohci_transfer_batch_t *ohci_batch) 285 { 286 assert(ohci_batch); 287 288 usb_direction_t dir = ohci_batch->base.dir; 292 289 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 290 293 291 usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed, 294 292 ohci_batch->ed->status, ohci_batch->ed->td_tail, … … 307 305 td_init( 308 306 ohci_batch->tds[0], ohci_batch->tds[1], USB_DIRECTION_BOTH, 309 buffer, ohci_batch->usb_batch->setup_size, toggle);307 buffer, USB_SETUP_PACKET_SIZE, toggle); 310 308 usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n", 311 309 ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp, 312 310 ohci_batch->tds[0]->next, ohci_batch->tds[0]->be); 313 buffer += ohci_batch->usb_batch->setup_size;311 buffer += USB_SETUP_PACKET_SIZE; 314 312 315 313 /* Data stage */ … … 361 359 * OHCI hw in ED. 362 360 */ 363 static void batch_data(ohci_transfer_batch_t *ohci_batch, usb_direction_t dir) 364 { 365 assert(ohci_batch); 366 assert(ohci_batch->usb_batch); 361 static void batch_data(ohci_transfer_batch_t *ohci_batch) 362 { 363 assert(ohci_batch); 364 365 usb_direction_t dir = ohci_batch->base.dir; 367 366 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 368 367 usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed, … … 401 400 402 401 /** Transfer setup table. */ 403 static void (*const batch_setup[])(ohci_transfer_batch_t* , usb_direction_t) =402 static void (*const batch_setup[])(ohci_transfer_batch_t*) = 404 403 { 405 404 [USB_TRANSFER_CONTROL] = batch_control,
Note:
See TracChangeset
for help on using the changeset viewer.