Date: Wed, 17 Apr 2002 00:54:46 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Peter Haight <peterh@sapros.com> Cc: Nick Hibma <n_hibma@van-laarhoven.org>, <hardware@FreeBSD.ORG> Subject: Re: Reading from the USB ugen device. Message-ID: <20020417003939.B8131-100000@gamplex.bde.org> In-Reply-To: <200204151747.g3FHlPRg037046@wartch.sapros.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 15 Apr 2002, Peter Haight wrote: > >> From what you told me and a brief look at the USB spec, I'm guessing it > >> isn't a coincidence that it is failing on that read where I'm expecting 64 > >> bytes (the max size of a USB packet payload). I'm guessing that in short > >> read mode, the driver gets a full length packet and is expecting another > >> data packet but it never comes because that's the end of the data, so it > >> doesn't return from the read until it gets a timeout. > > > >No. If you read 64 byes in 64 bytes with short_XFER switched on you will > >be reading 64 bytes and then 0 bytes. > > Ok. But why does this happen: > > read(3, 0x8091800, 1024) > read -1 bytes > > At that same point in the protocol if I do: > read(3, 0x8091800, 64) > read 64 bytes > > I would expect: > read(3, 0x8091800, 1024) > read 64 bytes This might be caused by longstanding brokenness in sys_generic.c. E.g., in dofileread(): cnt = nbyte; if ((error = fo_read(fp, &auio, fp->f_cred, flags, td))) { if (auio.uio_resid != cnt && (error == ERESTART || ^^^^^^^^^^^^^^^^^^^^ error == EINTR || error == EWOULDBLOCK)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error = 0; } cnt -= auio.uio_resid; The underlined code arranges for the correct i/o count for non-null i/o to actually be returned to the application if the next lowest level of read() returned ERESTART, EINTR or EWOULDBLOCK. All other cases are broken -- both POSIX and POLA specify that if any i/o was done, then read()/write() shall return a count of the amount done (usually but not necessarily a short count). Try removing this and all other similar "&&" clauses in sys_generic.c. There are surprisingly few files where this actually matters. For regular files on most filesystems, the filesystem unwinds the i/o, so the auio.uio_resid != cnt case is not even seen here. But i/o is normally unwindable for devices. Here the problem may be the more immediate one that usb returns EIO instead of EWOULDBLOCK when it can't proceed. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hardware" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020417003939.B8131-100000>