Changeset 22ceff3a in mainline for uspace/drv/bus/usb/ohci/ohci_batch.c
- Timestamp:
- 2011-10-17T07:29:44Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 12f55220
- Parents:
- 25696fea (diff), 1f131fb9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/ohci/ohci_batch.c
r25696fea r22ceff3a 163 163 ohci_batch->ed->td_tail, ohci_batch->ed->next); 164 164 165 size_t i = 0; 166 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) { 167 180 assert(ohci_batch->tds[i] != NULL); 168 181 usb_log_debug("TD %zu: %08x:%08x:%08x:%08x.\n", i, 169 182 ohci_batch->tds[i]->status, ohci_batch->tds[i]->cbp, 170 183 ohci_batch->tds[i]->next, ohci_batch->tds[i]->be); 171 if (!td_is_finished(ohci_batch->tds[i])) { 172 return false; 173 } 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 174 199 ohci_batch->usb_batch->error = td_error(ohci_batch->tds[i]); 175 200 if (ohci_batch->usb_batch->error != EOK) { … … 177 202 ohci_batch->usb_batch, i, 178 203 ohci_batch->tds[i]->status); 179 /* Make sure TD queue is empty (one TD), 180 * ED should be marked as halted */ 181 ohci_batch->ed->td_tail = 182 (ohci_batch->ed->td_head & ED_TDTAIL_PTR_MASK); 183 ++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; 184 227 break; 185 228 } 186 229 } 187 188 assert(i <= ohci_batch->td_count);189 ohci_batch->leave_td = i; 190 230 assert(ohci_batch->usb_batch->transfered_size <= 231 ohci_batch->usb_batch->buffer_size); 232 233 /* Store the remaining TD */ 191 234 ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ohci_batch->usb_batch->ep); 192 235 assert(ohci_ep); 193 236 ohci_ep->td = ohci_batch->tds[ohci_batch->leave_td]; 194 assert(i > 0); 195 ohci_batch->usb_batch->transfered_size = 196 ohci_batch->usb_batch->buffer_size; 197 for (--i;i < ohci_batch->td_count; ++i) { 198 ohci_batch->usb_batch->transfered_size 199 -= td_remain_size(ohci_batch->tds[i]); 200 } 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 /*----------------------------------------------------------------------------*/ … … 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]);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); 253 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, … … 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]); 301 td_init(ohci_batch->tds[td_current], 302 ohci_batch->tds[td_current + 1], 303 data_dir, buffer, transfer_size, toggle); 271 304 usb_log_debug("Created CONTROL DATA TD: %08x:%08x:%08x:%08x.\n", 272 305 ohci_batch->tds[td_current]->status, … … 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]); 318 td_init(ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 319 status_dir, NULL, 0, 1); 288 320 usb_log_debug("Created CONTROL STATUS TD: %08x:%08x:%08x:%08x.\n", 289 321 ohci_batch->tds[td_current]->status, … … 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]); 357 td_init( 358 ohci_batch->tds[td_current], ohci_batch->tds[td_current + 1], 359 dir, buffer, transfer_size, -1); 329 360 330 361 usb_log_debug("Created DATA TD: %08x:%08x:%08x:%08x.\n",
Note:
See TracChangeset
for help on using the changeset viewer.