Changes in uspace/drv/bus/usb/ohci/ohci_batch.c [790318e:549ff23] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci_batch.c
r790318e r549ff23 52 52 if (!ohci_batch) 53 53 return; 54 unsigned i = 0;55 54 if (ohci_batch->tds) { 56 for ( ; i< ohci_batch->td_count; ++i) {55 for (unsigned i = 0; i < ohci_batch->td_count; ++i) { 57 56 if (i != ohci_batch->leave_td) 58 57 free32(ohci_batch->tds[i]); … … 60 59 free(ohci_batch->tds); 61 60 } 62 usb_transfer_batch_d ispose(ohci_batch->usb_batch);61 usb_transfer_batch_destroy(ohci_batch->usb_batch); 63 62 free32(ohci_batch->device_buffer); 64 63 free(ohci_batch); … … 107 106 ohci_batch->tds[0] = ohci_endpoint_get(usb_batch->ep)->td; 108 107 ohci_batch->leave_td = 0; 109 unsigned i = 1; 110 for ( ; i <= ohci_batch->td_count; ++i) {108 109 for (unsigned i = 1; i <= ohci_batch->td_count; ++i) { 111 110 ohci_batch->tds[i] = malloc32(sizeof(td_t)); 112 111 CHECK_NULL_DISPOSE_RET(ohci_batch->tds[i], … … 160 159 usb_log_debug("Batch %p checking %zu td(s) for completion.\n", 161 160 ohci_batch->usb_batch, ohci_batch->td_count); 162 usb_log_debug2("ED: % x:%x:%x:%x.\n",161 usb_log_debug2("ED: %08x:%08x:%08x:%08x.\n", 163 162 ohci_batch->ed->status, ohci_batch->ed->td_head, 164 163 ohci_batch->ed->td_tail, ohci_batch->ed->next); 165 164 166 size_t i = 0; 167 for (; i < ohci_batch->td_count; ++i) { 165 if (!ed_inactive(ohci_batch->ed) && ed_transfer_pending(ohci_batch->ed)) 166 return false; 167 168 /* Now we may be sure that either the ED is inactive because of errors 169 * or all transfer descriptors completed successfully */ 170 171 /* Assume all data got through */ 172 ohci_batch->usb_batch->transfered_size = 173 ohci_batch->usb_batch->buffer_size; 174 175 /* Assume we will leave the last(unused) TD behind */ 176 ohci_batch->leave_td = ohci_batch->td_count; 177 178 /* Check all TDs */ 179 for (size_t i = 0; i < ohci_batch->td_count; ++i) { 168 180 assert(ohci_batch->tds[i] != NULL); 169 usb_log_debug("TD %zu: % x:%x:%x:%x.\n", i,181 usb_log_debug("TD %zu: %08x:%08x:%08x:%08x.\n", i, 170 182 ohci_batch->tds[i]->status, ohci_batch->tds[i]->cbp, 171 183 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 172 if (!td_is_finished(ohci_batch->tds[i])) { 173 return false; 174 } 184 185 /* If the TD got all its data through, it will report 0 bytes 186 * remain, the sole exception is INPUT with data rounding flag 187 * (short), i.e. every INPUT. Nice thing is that short packets 188 * will correctly report remaining data, thus making 189 * this computation correct (short packets need to be produced 190 * by the last TD) 191 * NOTE: This also works for CONTROL transfer as 192 * the first TD will return 0 remain. 193 * NOTE: Short packets don't break the assumption that 194 * we leave the very last(unused) TD behind. 195 */ 196 ohci_batch->usb_batch->transfered_size 197 -= td_remain_size(ohci_batch->tds[i]); 198 175 199 ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]); 176 200 if (ohci_batch->usb_batch->error != EOK) { 177 usb_log_debug("Batch %p found error TD(%zu):% x.\n",201 usb_log_debug("Batch %p found error TD(%zu):%08x.\n", 178 202 ohci_batch->usb_batch, i, 179 203 ohci_batch->tds[i]->status); 180 /* Make sure TD queue is empty (one TD), 181 * ED should be marked as halted */ 182 ohci_batch->ed->td_tail = 183 (ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK); 184 ++i; 204 205 /* ED should be stopped because of errors */ 206 assert((ohci_batch->ed->td_head & ED_TDHEAD_HALTED_FLAG) != 0); 207 208 /* Now we have a problem: we don't know what TD 209 * the head pointer points to, the retiring rules 210 * described in specs say it should be the one after 211 * the failed one so set the tail pointer accordingly. 212 * It will be the one TD we leave behind. 213 */ 214 ohci_batch->leave_td = i + 1; 215 216 /* Check TD assumption */ 217 const uint32_t pa = addr_to_phys( 218 ohci_batch->tds[ohci_batch->leave_td]); 219 assert((ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK) 220 == pa); 221 222 ed_set_tail_td(ohci_batch->ed, 223 ohci_batch->tds[ohci_batch->leave_td]); 224 225 /* Clear possible ED HALT */ 226 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 185 227 break; 186 228 } 187 229 } 188 189 assert(i <= ohci_batch->td_count);190 ohci_batch->leave_td = i; 191 230 assert(ohci_batch->usb_batch->transfered_size <= 231 ohci_batch->usb_batch->buffer_size); 232 233 /* Store the remaining TD */ 192 234 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->usb_batch->ep); 193 235 assert(ohci_ep); 194 236 ohci_ep->td = ohci_batch->tds[ohci_batch->leave_td]; 195 assert(i > 0); 196 ohci_batch->usb_batch->transfered_size = 197 ohci_batch->usb_batch->buffer_size; 198 for (--i;i < ohci_batch->td_count; ++i) 199 ohci_batch->usb_batch->transfered_size 200 -= td_remain_size(ohci_batch->tds[i]); 201 202 /* Clear possible ED HALT */ 203 ohci_batch->ed->td_head &= ~ED_TDHEAD_HALTED_FLAG; 204 /* just make sure that we are leaving the right TD behind */ 237 238 /* Make sure that we are leaving the right TD behind */ 205 239 const uint32_t pa = addr_to_phys(ohci_ep->td); 206 240 assert(pa == (ohci_batch->ed->td_head & ED_TDHEAD_PTR_MASK)); … … 217 251 { 218 252 assert(ohci_batch); 219 ed_set_ end_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]);253 ed_set_tail_td(ohci_batch->ed, ohci_batch->tds[ohci_batch->td_count]); 220 254 } 221 255 /*----------------------------------------------------------------------------*/ … … 234 268 assert(ohci_batch->usb_batch); 235 269 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 236 usb_log_debug("Using ED(%p): % x:%x:%x:%x.\n", ohci_batch->ed,270 usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed, 237 271 ohci_batch->ed->status, ohci_batch->ed->td_tail, 238 272 ohci_batch->ed->td_head, ohci_batch->ed->next); … … 247 281 const usb_direction_t status_dir = reverse_dir[dir]; 248 282 249 /* setup stage */250 td_init( ohci_batch->tds[0], USB_DIRECTION_BOTH, buffer,251 ohci_batch->usb_batch->setup_size, toggle);252 td_set_next(ohci_batch->tds[0], ohci_batch->tds[1]);253 usb_log_debug("Created CONTROL SETUP TD: % x:%x:%x:%x.\n",283 /* Setup stage */ 284 td_init( 285 ohci_batch->tds[0], ohci_batch->tds[1], USB_DIRECTION_BOTH, 286 buffer, ohci_batch->usb_batch->setup_size, toggle); 287 usb_log_debug("Created CONTROL SETUP TD: %08x:%08x:%08x:%08x.\n", 254 288 ohci_batch->tds[0]->status, ohci_batch->tds[0]->cbp, 255 289 ohci_batch->tds[0]->next, ohci_batch->tds[0]->be); 256 290 buffer += ohci_batch->usb_batch->setup_size; 257 291 258 /* data stage */292 /* Data stage */ 259 293 size_t td_current = 1; 260 294 size_t remain_size = ohci_batch->usb_batch->buffer_size; … … 265 299 toggle = 1 - toggle; 266 300 267 td_init(ohci_batch->tds[td_current], data_dir, buffer, 268 transfer_size, toggle); 269 td_set_next(ohci_batch->tds[td_current], 270 ohci_batch->tds[td_current + 1]); 271 usb_log_debug("Created CONTROL DATA TD: %x:%x:%x:%x.\n", 301 td_init(ohci_batch->tds[td_current], 302 ohci_batch->tds[td_current + 1], 303 data_dir, buffer, transfer_size, toggle); 304 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x:%08x.\n", 272 305 ohci_batch->tds[td_current]->status, 273 306 ohci_batch->tds[td_current]->cbp, … … 281 314 } 282 315 283 /* status stage */316 /* Status stage */ 284 317 assert(td_current == ohci_batch->td_count - 1); 285 td_init(ohci_batch->tds[td_current], status_dir, NULL, 0, 1); 286 td_set_next(ohci_batch->tds[td_current], 287 ohci_batch->tds[td_current + 1]); 288 usb_log_debug("Created CONTROL STATUS TD: %x:%x:%x:%x.\n", 318 td_init(ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 319 status_dir, NULL, 0, 1); 320 usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x:%08x.\n", 289 321 ohci_batch->tds[td_current]->status, 290 322 ohci_batch->tds[td_current]->cbp, … … 312 344 assert(ohci_batch->usb_batch); 313 345 assert(dir == USB_DIRECTION_IN || dir == USB_DIRECTION_OUT); 314 usb_log_debug("Using ED(%p): % x:%x:%x:%x.\n", ohci_batch->ed,346 usb_log_debug("Using ED(%p): %08x:%08x:%08x:%08x.\n", ohci_batch->ed, 315 347 ohci_batch->ed->status, ohci_batch->ed->td_tail, 316 348 ohci_batch->ed->td_head, ohci_batch->ed->next); … … 323 355 ? OHCI_TD_MAX_TRANSFER : remain_size; 324 356 325 td_init(ohci_batch->tds[td_current], dir, buffer, 326 transfer_size, -1); 327 td_set_next(ohci_batch->tds[td_current], 328 ohci_batch->tds[td_current + 1]); 329 330 usb_log_debug("Created DATA TD: %x:%x:%x:%x.\n", 357 td_init( 358 ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 359 dir, buffer, transfer_size, -1); 360 361 usb_log_debug("Created DATA TD: %08x:%08x:%08x:%08x.\n", 331 362 ohci_batch->tds[td_current]->status, 332 363 ohci_batch->tds[td_current]->cbp,
Note:
See TracChangeset
for help on using the changeset viewer.