cvs commit: src/sys/dev/usb ohci.c ohcivar.h

Ian Dowse iedowse at FreeBSD.org
Sun Nov 27 09:05:42 GMT 2005


iedowse     2005-11-27 09:05:37 UTC

  FreeBSD src repository

  Modified files:
    sys/dev/usb          ohci.c ohcivar.h 
  Log:
  The ohci driver's processing of completed transfer descriptors (TDs)
  appeared to rely on all kinds of non-guaranteed behaviours: the
  transfer abort code assumed that TDs with no interrupt timeout
  configured would end up on the done queue within 20ms, the done
  queue processing assumed that all TDs from a transfer would appear
  at the same time, and there were access-after-free bugs triggered
  on failed transfers.
  
  Attempt to fix these problems by the following changes:
   - Use a maximum (6-frame) interrupt delay instead of no interrupt
     delay to ensure that the 20ms wait in ohci_abort_xfer() is enough
     for the TDs to have been taken off the hardware done queue.
   - Defer cancellation of timeouts and freeing of TDs until we either
     hit an error or reach the final TD.
   - Remove TDs from the done queue before freeing them so that it
     is safe to continue traversing the done queue.
  
  This appears to fix a hang that was reproducable with revision 1.67
  or 1.68 of ulpt.c (earlier revisions had a different transfer
  pattern). With certain HP printers, the command "true > /dev/ulpt0"
  would cause ohci_add_done() to spin because the done queue had a
  loop. The list corruption was caused by a 3-TD transfer where the
  first TD completed but remained on the internal host controller
  done queue because it had no interrupt timeout. When the transfer
  timed out, the TD got freed and reused, so it caused a loop in the
  done queue when it was inserted a second time from a different
  transfer.
  
  Reported by:    Alex Pivovarov
  MFC after:      1 week
  
  Revision  Changes    Path
  1.155     +38 -30    src/sys/dev/usb/ohci.c
  1.41      +0 -1      src/sys/dev/usb/ohcivar.h


More information about the cvs-src mailing list