Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Sep 2004 18:39:04 +0000 (UTC)
From:      Bill Paul <wpaul@FreeBSD.org>
To:        src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org
Subject:   cvs commit: src/sys/dev/usb ugen.c
Message-ID:  <200409281839.i8SId48U003669@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
wpaul       2004-09-28 18:39:04 UTC

  FreeBSD src repository

  Modified files:
    sys/dev/usb          ugen.c 
  Log:
  Arrgh. Recently I tried using ugen(4) in an application that uses
  select(2), and discovered to my horror that ugen(4)'s bulk in/out support
  is horribly lobotomized. Bulk transfers are done using the synchronous
  API instead of the asynchronous one. This causes the following broken
  behavior to occur:
  
  - You open the bulk in/out ugen device and get a descriptor
  - You create some other descriptor (socket, other device, etc...)
  - You select on both the descriptors waiting until either one has
    data ready to read
  - Because of ugen's brokenness, you block in usb_bulk_transfer() inside
    ugen_do_read() instead of blocking in select()
  - The non-USB descriptor becomes ready for reading, but you remain blocked
    on select()
  - The USB descriptor becomes ready for reading
  - Only now are you woken up so that you can ready data from either
    descriptor.
  
  The result is select() can only wake up when there's USB data pending. If
  any other descriptor becomes ready, you lose: until the USB descriptor
  becomes ready, you stay asleep.
  
  The correct approach is to use async bulk transfers, so I changed
  the read code to use the async bulk transfer API. I left the write
  side alone for now since it's less of an issue.
  
  Note that the uscanner driver has the same brokenness in it.
  
  Revision  Changes    Path
  1.91      +122 -26   src/sys/dev/usb/ugen.c



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200409281839.i8SId48U003669>