Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Jan 2005 02:37:53 -0800
From:      Sandy Rutherford <sandy@krvarr.bc.ca>
To:        Julian Elischer <julian@elischer.org>
Cc:        freebsd-usb@freebsd.org
Subject:   Re: ulpt hangs on offline status
Message-ID:  <16872.62081.209945.743448@szamoca.krvarr.bc.ca>
In-Reply-To: <41E6D483.8050005@elischer.org>
References:  <16870.6275.128262.61361@szamoca.krvarr.bc.ca> <41E6D483.8050005@elischer.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--W0AcZiywTF
Content-Type: text/plain; charset=us-ascii
Content-Description: message body text
Content-Transfer-Encoding: 7bit

Julian,

On Thu, 13 Jan 2005 you wrote:

 > Sandy Rutherford wrote:

 >> 
 >> [root@szamoca:14] usbdevs -v -d
 >> Controller /dev/usb0:
 >> addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), Intel(0x0000), rev 1.00
 >> uhub0
 >> port 1 powered
 >> port 2 addr 2: full speed, power 98 mA, config 1, Centronics connector(0x0006), Entrega(0x1645), rev 1.00
 >> ulpt0
 >> 
 >> I am willing to muck around with the driver to try to fix this myself,
 >> but it would be useful to know if anybody else has seen or worked on
 >> this problem.
 >> 

 > not yet but I'm willing to believe that you may need to poll the device 
 > to see the change in status.
 > That would be handled in the "interrupt" type transfers..
 > We do not support them very well yet.

This evening, I threw a bunch of print statements into ulpt.c to see
what was happening.  This is for /sys/dev/usb/ulpt.c in FreeBSD 4.10.

As expected, it hangs trying to open the connection.

First it runs a tsleep loop:

	for (spin = 0; (ulpt_status(sc) & LPS_SELECT) == 0; spin += STEP) {
		DPRINTF(("ulpt_open: waiting a while\n"));
		if (spin >= TIMEOUT) {
			error = EBUSY;
			sc->sc_state = 0;
			goto done;
		}

		/* wait 1/4 second, give up if we get a signal */
		error = tsleep(sc, LPTPRI | PCATCH, "ulptop", STEP);
		if (error != EWOULDBLOCK) {
			sc->sc_state = 0;
			goto done;
		}

		if (sc->sc_dying) {
			error = ENXIO;
			sc->sc_state = 0;
			goto done;
		}
	}

If the printer is offline, the tsleap returns an EAGAIN (resource
temporarily unavailable) error.  After the loop, it tries to open
input and output pipes.  If any of these fail, `error' is set to one
of EIO or ENOMEM and we `goto done'.

The problem is that if the printer comes back on line during the
tsleep loop, this is not caught and the tsleep loop exits with 
`error == EAGAIN'.  If subsequently, the input and output pipes are
opened successfully, `error' remains set to EAGAIN and this is what
`ulptopen' returns.  It should really return 0, because we have a good
connection and we should start writing data.

Therefore, I stuck the following just before the `done: ' tag:

	/* If we get to here with error == EAGAIN (resource temporarily */
	/* unavailable), it means open out and open in succeeded, even  */
        /* though the tsleep failed.  This probably means that          */
        /* the printer came online during the tsleep loop and we now    */ 
        /* have a connection.  Return 0 to start ulptwrite.             */
        /* --SR sandy@krvarr.bc.ca                                      */
	if (error ==  EAGAIN) {
	  DPRINTF(("error=%d.  Connection established?", error));
	  error = 0;
	}

 done:
	if (--sc->sc_refcnt < 0)
		usb_detach_wakeup(USBDEV(sc->sc_dev));

	DPRINTF(("ulptopen: done, error=%d\n", error));
	return (error);
}


It does the job for me.  ulpt now starts up when the printer comes
back online.

If anybody else has a similar problem, you might try this patch.  I'll
attach a proper patch file below.  If anybody does try this and it messes
something else up, please let me know.  USB devices are notoriously
flakey.

After testing this further for a few days, I'll send in a pr with the
patch.

BTW, I am running FreeBSD on i386 hardware.  The specifics of my USB
setup are:

usbdevs -v
Controller /dev/usb0:
addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), Intel(0x0000), rev 1.00
 port 1 powered
 port 2 addr 2: full speed, power 98 mA, config 1, Centronics connector(0x0006), Entrega(0x1645), rev 1.00

Sandy

 
--W0AcZiywTF
Content-Type: application/octet-stream
Content-Description: ulpt.c patch
Content-Disposition: attachment;
	filename="ulpt.c.patch"
Content-Transfer-Encoding: base64

KioqIHVscHQuYy5vcmlnCVdlZCBKYW4gMTIgMjA6MTM6MTggMjAwNQotLS0gdWxwdC5jCVNhdCBK
YW4gMTUgMDE6NTI6MDAgMjAwNQoqKioqKioqKioqKioqKioKKioqIDYwNyw2MTIgKioqKgotLS0g
NjA3LDYyNCAtLS0tCiAgCiAgCXNjLT5zY19zdGF0ZSA9IFVMUFRfT1BFTjsKICAKKyAKKyAJLyog
SWYgd2UgZ2V0IHRvIGhlcmUgd2l0aCBlcnJvciA9PSBFQUdBSU4gKHJlc291cmNlIHRlbXBvcmFy
aWx5ICovCisgCS8qIHVuYXZhaWxhYmxlKSwgaXQgbWVhbnMgb3BlbiBvdXQgYW5kIG9wZW4gaW4g
c3VjY2VlZGVkLCBldmVuICAqLworICAgICAgICAgLyogdGhvdWdoIHRoZSB0c2xlZXAgZmFpbGVk
LiAgVGhpcyBwcm9iYWJseSBtZWFucyB0aGF0ICAgICAgICAgICovCisgICAgICAgICAvKiB0aGUg
cHJpbnRlciBjYW1lIG9ubGluZSBkdXJpbmcgdGhlIHRzbGVlcCBsb29wIGFuZCB3ZSBub3cgICAg
Ki8gCisgICAgICAgICAvKiBoYXZlIGEgY29ubmVjdGlvbi4gIFJldHVybiAwIHRvIHN0YXJ0IHVs
cHR3cml0ZS4gICAgICAgICAgICAgKi8KKyAgICAgICAgIC8qIC0tU1Igc2FuZHlAa3J2YXJyLmJj
LmNhICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLworIAlpZiAoZXJyb3Ig
PT0gIEVBR0FJTikgeworIAkgIERQUklOVEYoKCJlcnJvcj0lZC4gIENvbm5lY3Rpb24gZXN0YWJs
aXNoZWQ/IiwgZXJyb3IpKTsKKyAJICBlcnJvciA9IDA7CisgCX0KKyAKICAgZG9uZToKICAJaWYg
KC0tc2MtPnNjX3JlZmNudCA8IDApCiAgCQl1c2JfZGV0YWNoX3dha2V1cChVU0JERVYoc2MtPnNj
X2RldikpOwo=
--W0AcZiywTF--



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