Changes in uspace/drv/ohci/batch.c [02cacce:4125b7d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/ohci/batch.c
r02cacce r4125b7d 44 44 #include "hw_struct/transfer_descriptor.h" 45 45 46 /** OHCI specific data required for USB transfer */47 46 typedef struct ohci_transfer_batch { 48 /** Endpoint descriptor of the target endpoint. */49 47 ed_t *ed; 50 /** List of TDs needed for the transfer */51 48 td_t **tds; 52 /** Number of TDs used by the transfer */53 49 size_t td_count; 54 /** Dummy TD to be left at the ED and used by the next transfer */55 50 size_t leave_td; 56 /** Data buffer, must be accessible byb the OHCI hw. */ 57 void *device_buffer; 51 char *device_buffer; 58 52 } ohci_transfer_batch_t; 59 /*----------------------------------------------------------------------------*/ 60 static void batch_control(usb_transfer_batch_t *instance, 61 usb_direction_t data_dir, usb_direction_t status_dir); 62 static void batch_data(usb_transfer_batch_t *instance); 63 /*----------------------------------------------------------------------------*/ 64 /** Safely destructs ohci_transfer_batch_t structure 65 * 66 * @param[in] ohci_batch Instance to destroy. 67 */ 53 68 54 static void ohci_transfer_batch_dispose(void *ohci_batch) 69 55 { … … 83 69 } 84 70 /*----------------------------------------------------------------------------*/ 85 /** Allocate memory initialize internal structures 86 * 87 * @param[in] fun DDF function to pass to callback. 88 * @param[in] ep Communication target 89 * @param[in] buffer Data source/destination. 90 * @param[in] buffer_size Size of the buffer. 91 * @param[in] setup_buffer Setup data source (if not NULL) 92 * @param[in] setup_size Size of setup_buffer (should be always 8) 93 * @param[in] func_in function to call on inbound transfer completion 94 * @param[in] func_out function to call on outbound transfer completion 95 * @param[in] arg additional parameter to func_in or func_out 96 * @return Valid pointer if all structures were successfully created, 97 * NULL otherwise. 98 * 99 * Allocates and initializes structures needed by the OHCI hw for the transfer. 100 */ 71 static void batch_control(usb_transfer_batch_t *instance, 72 usb_direction_t data_dir, usb_direction_t status_dir); 73 static void batch_data(usb_transfer_batch_t *instance); 74 /*----------------------------------------------------------------------------*/ 101 75 usb_transfer_batch_t * batch_get(ddf_fun_t *fun, endpoint_t *ep, 102 char *buffer, size_t buffer_size, 103 const char *setup_buffer, size_t setup_size, 76 char *buffer, size_t buffer_size, char* setup_buffer, size_t setup_size, 104 77 usbhc_iface_transfer_in_callback_t func_in, 105 78 usbhc_iface_transfer_out_callback_t func_out, void *arg) … … 121 94 ohci_transfer_batch_dispose); 122 95 123 consthcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep);96 hcd_endpoint_t *hcd_ep = hcd_endpoint_get(ep); 124 97 assert(hcd_ep); 125 98 … … 130 103 data->td_count = 131 104 ((buffer_size + OHCI_TD_MAX_TRANSFER - 1) / OHCI_TD_MAX_TRANSFER); 132 /* Control transfer need Setup and Status stage */133 105 if (ep->transfer_type == USB_TRANSFER_CONTROL) { 134 106 data->td_count += 2; 135 107 } 136 108 137 /* We need an extra place for TDthat is currently assigned to hcd_ep*/109 /* we need one extra place for td that is currently assigned to hcd_ep*/ 138 110 data->tds = calloc(sizeof(td_t*), data->td_count + 1); 139 111 CHECK_NULL_DISPOSE_RETURN(data->tds, 140 112 "Failed to allocate transfer descriptors.\n"); 141 113 142 /* Add TD left over by the previous transfer */143 114 data->tds[0] = hcd_ep->td; 144 115 data->leave_td = 0; … … 152 123 data->ed = hcd_ep->ed; 153 124 154 /* NOTE: OHCI is capable of handling buffer that crosses page boundaries155 * it is, however, not capable of handling buffer that occupies more156 * than two pages (the first page is computed using start pointer, the157 * other using the end pointer) */158 125 if (setup_size + buffer_size > 0) { 159 126 data->device_buffer = malloc32(setup_size + buffer_size); … … 168 135 } 169 136 /*----------------------------------------------------------------------------*/ 170 /** Check batch TDs' status.171 *172 * @param[in] instance Batch structure to use.173 * @return False, if there is an active TD, true otherwise.174 *175 * Walk all TDs (usually there is just one). Stop with false if there is an176 * active TD. Stop with true if an error is found. Return true if the walk177 * completes with the last TD.178 */179 137 bool batch_is_complete(usb_transfer_batch_t *instance) 180 138 { … … 182 140 ohci_transfer_batch_t *data = instance->private_data; 183 141 assert(data); 142 size_t tds = data->td_count; 184 143 usb_log_debug("Batch(%p) checking %zu td(s) for completion.\n", 185 instance, data->td_count);144 instance, tds); 186 145 usb_log_debug("ED: %x:%x:%x:%x.\n", 187 146 data->ed->status, data->ed->td_head, data->ed->td_tail, … … 189 148 size_t i = 0; 190 149 instance->transfered_size = instance->buffer_size; 191 for (; i < data->td_count; ++i) {150 for (; i < tds; ++i) { 192 151 assert(data->tds[i] != NULL); 193 152 usb_log_debug("TD %zu: %x:%x:%x:%x.\n", i, … … 214 173 assert(hcd_ep); 215 174 hcd_ep->td = data->tds[i]; 216 assert(i > 0); 217 for (--i;i < data->td_count; ++i) 218 instance->transfered_size -= td_remain_size(data->tds[i]); 175 if (i > 0) 176 instance->transfered_size -= td_remain_size(data->tds[i - 1]); 219 177 220 178 /* Clear possible ED HALT */ 221 179 data->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 222 constuint32_t pa = addr_to_phys(hcd_ep->td);180 uint32_t pa = addr_to_phys(hcd_ep->td); 223 181 assert(pa == (data->ed->td_head & ED_TDHEAD_PTR_MASK)); 224 182 assert(pa == (data->ed->td_tail & ED_TDTAIL_PTR_MASK)); … … 227 185 } 228 186 /*----------------------------------------------------------------------------*/ 229 /** Starts execution of the TD list230 *231 * @param[in] instance Batch structure to use232 */233 187 void batch_commit(usb_transfer_batch_t *instance) 234 188 { … … 239 193 } 240 194 /*----------------------------------------------------------------------------*/ 241 /** Prepares control write transfer.242 *243 * @param[in] instance Batch structure to use.244 *245 * Uses generic control transfer using direction OUT(data stage) and246 * IN(status stage).247 */248 195 void batch_control_write(usb_transfer_batch_t *instance) 249 196 { … … 256 203 } 257 204 /*----------------------------------------------------------------------------*/ 258 /** Prepares control read transfer.259 *260 * @param[in] instance Batch structure to use.261 *262 * Uses generic control transfer using direction IN(data stage) and263 * OUT(status stage).264 */265 205 void batch_control_read(usb_transfer_batch_t *instance) 266 206 { … … 271 211 } 272 212 /*----------------------------------------------------------------------------*/ 273 /** Prepare interrupt in transfer.274 *275 * @param[in] instance Batch structure to use.276 *277 * Data transfer.278 */279 213 void batch_interrupt_in(usb_transfer_batch_t *instance) 280 214 { … … 285 219 } 286 220 /*----------------------------------------------------------------------------*/ 287 /** Prepare interrupt out transfer.288 *289 * @param[in] instance Batch structure to use.290 *291 * Data transfer.292 */293 221 void batch_interrupt_out(usb_transfer_batch_t *instance) 294 222 { … … 301 229 } 302 230 /*----------------------------------------------------------------------------*/ 303 /** Prepare bulk in transfer.304 *305 * @param[in] instance Batch structure to use.306 *307 * Data transfer.308 */309 231 void batch_bulk_in(usb_transfer_batch_t *instance) 310 232 { … … 315 237 } 316 238 /*----------------------------------------------------------------------------*/ 317 /** Prepare bulk out transfer.318 *319 * @param[in] instance Batch structure to use.320 *321 * Data transfer.322 */323 239 void batch_bulk_out(usb_transfer_batch_t *instance) 324 240 { … … 331 247 } 332 248 /*----------------------------------------------------------------------------*/ 333 /** Prepare generic control transfer 334 * 335 * @param[in] instance Batch structure to use. 336 * @param[in] data_dir Direction to use for data stage. 337 * @param[in] status_dir Direction to use for status stage. 338 * 339 * Setup stage with toggle 0 and direction BOTH(SETUP_PID) 340 * Data stage with alternating toggle and direction supplied by parameter. 341 * Status stage with toggle 1 and direction supplied by parameter. 342 */ 249 ed_t * batch_ed(usb_transfer_batch_t *instance) 250 { 251 assert(instance); 252 ohci_transfer_batch_t *data = instance->private_data; 253 assert(data); 254 return data->ed; 255 } 256 /*----------------------------------------------------------------------------*/ 343 257 void batch_control(usb_transfer_batch_t *instance, 344 258 usb_direction_t data_dir, usb_direction_t status_dir) … … 389 303 } 390 304 /*----------------------------------------------------------------------------*/ 391 /** Prepare generic data transfer392 *393 * @param[in] instance Batch structure to use.394 *395 * Direction is supplied by the associated ep and toggle is maintained by the396 * OHCI hw in ED.397 */398 305 void batch_data(usb_transfer_batch_t *instance) 399 306 { … … 409 316 char *buffer = instance->data_buffer; 410 317 while (remain_size > 0) { 411 const size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER412 ?OHCI_TD_MAX_TRANSFER : remain_size;318 size_t transfer_size = remain_size > OHCI_TD_MAX_TRANSFER ? 319 OHCI_TD_MAX_TRANSFER : remain_size; 413 320 414 321 td_init(data->tds[td_current], instance->ep->direction,
Note:
See TracChangeset
for help on using the changeset viewer.