On Fri, Sep 19, 2003 at 11:30:32AM -0500, Kirk Strauser
wrote:> When I bought my Laserjet 1200SE about a year ago, FreeBSD wasn't
capable of
> using its USB interface. I see no indication that this has changed. Is
> anybody working on this as a personal project? Is there any general
> progress on it?
>
> Basically, parallel printing 50MB Postscript files is killing me. I think
> I'm going to have to give in and move the Printer onto a Linux
workstation
> unless somebody knows something I don't.
-stable stumbles over 1284 mode if the printer lists it as the first
alternative.
For -current this is not a problem.
I have a patch for -stable to switch to a working alternative somewhere
around - I hope that the attached is the right one...
--
B.Walter BWCT http://www.bwct.de
ticso@bwct.de info@bwct.de
-------------- next part --------------
--- ulpt.c.orig Fri May 2 15:50:58 2003
+++ ulpt.c Fri May 2 15:56:40 2003
@@ -174,7 +174,8 @@
id->bInterfaceClass == UICLASS_PRINTER &&
id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
(id->bInterfaceProtocol == UIPROTO_PRINTER_UNI ||
- id->bInterfaceProtocol == UIPROTO_PRINTER_BI))
+ id->bInterfaceProtocol == UIPROTO_PRINTER_BI ||
+ id->bInterfaceProtocol == UIPROTO_PRINTER_1284))
return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO);
return (UMATCH_NONE);
}
@@ -183,79 +184,63 @@
{
USB_ATTACH_START(ulpt, sc, uaa);
usbd_device_handle dev = uaa->device;
+
+ usb_config_descriptor_t *cdesc;
+
usbd_interface_handle iface = uaa->iface;
- usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
+ usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface);
+ usb_interface_descriptor_t *id, *iend;
char devinfo[1024];
usb_endpoint_descriptor_t *ed;
usbd_status err;
+ u_int8_t epcount;
+ int i, altno;
DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
usbd_devinfo(dev, 0, devinfo);
USB_ATTACH_SETUP;
- printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
- devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
- /* Figure out which endpoint is the bulk out endpoint. */
- ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == NULL)
- goto nobulk;
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_BULK) {
- /* In case we are using a bidir protocol... */
- ed = usbd_interface2endpoint_descriptor(iface, 1);
- if (ed == NULL)
- goto nobulk;
- if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
- (ed->bmAttributes & UE_XFERTYPE) != UE_BULK)
- goto nobulk;
- }
- sc->sc_bulk = ed->bEndpointAddress;
- DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_bulk));
-
- sc->sc_iface = iface;
- err = usbd_interface2device_handle(iface, &sc->sc_udev);
- if (err) {
- sc->sc_dying = 1;
- USB_ATTACH_ERROR_RETURN;
- }
- sc->sc_ifaceno = id->bInterfaceNumber;
-
-#if 0
-/*
- * This code is disabled because for some mysterious reason it causes
- * printing not to work. But only sometimes, and mostly with
- * UHCI and less often with OHCI. *sigh*
- */
- {
- usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
- usb_device_request_t req;
- int len, alen;
-
- req.bmRequestType = UT_READ_CLASS_INTERFACE;
- req.bRequest = UR_GET_DEVICE_ID;
- USETW(req.wValue, cd->bConfigurationValue);
- USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting);
- USETW(req.wLength, sizeof devinfo - 1);
- err = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
- &alen);
- if (err) {
- printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev));
- } else if (alen <= 2) {
- printf("%s: empty device id, no printer connected?\n",
- USBDEVNAME(sc->sc_dev));
- } else {
- /* devinfo now contains an IEEE-1284 device ID */
- len = ((devinfo[0] & 0xff) << 8) | (devinfo[1] & 0xff);
- if (len > sizeof devinfo - 3)
- len = sizeof devinfo - 3;
- devinfo[len] = 0;
- printf("%s: device id <", USBDEVNAME(sc->sc_dev));
- ieee1284_print_id(devinfo+2);
- printf(">\n");
- }
- }
+ cdesc = usbd_get_config_descriptor(dev);
+ if (cdesc == NULL) {
+ printf("%s: failed to get configuration descriptor\n",
+ USBDEVNAME(sc->sc_dev));
+ USB_ATTACH_ERROR_RETURN;
+ }
+ iend = (usb_interface_descriptor_t *)
+ ((char *)cdesc + UGETW(cdesc->wTotalLength));
+#ifdef DIAGNOSTIC
+ if (ifcd < (usb_interface_descriptor_t *)cdesc ||
+ ifcd >= iend)
+ panic("ulpt: iface desc out of range\n");
#endif
-
+ /* Step through all the descriptors looking for bidir mode */
+ for (id = ifcd, altno = 0;
+ id < iend;
+ id = (void *)((char *)id + id->bLength)) {
+ if (id->bDescriptorType == UDESC_INTERFACE &&
+ id->bInterfaceNumber == ifcd->bInterfaceNumber) {
+ if (id->bInterfaceClass == UICLASS_PRINTER &&
+ id->bInterfaceSubClass == UISUBCLASS_PRINTER &&
+ id->bInterfaceProtocol == UIPROTO_PRINTER_BI) {
+ DPRINTF(("ulpt_attach: set altno = %d\n", altno));
+ err = usbd_set_interface(iface, altno);
+ if (err == 0) {
+ printf("%s: %s, iclass %d/%d-%d(%d)\n",
USBDEVNAME(sc->sc_dev),
+ devinfo, id->bInterfaceClass, id->bInterfaceSubClass,
+ id->bInterfaceNumber+id->bAlternateSetting,
id->bInterfaceProtocol);
+ epcount = 0;
+ (void)usbd_endpoint_count(iface, &epcount);
+ for (i = 0; i < epcount; i++) {
+ ed = usbd_interface2endpoint_descriptor(iface, i);
+ if (ed != NULL) {
+ if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
+ (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
+ sc->sc_bulk = ed->bEndpointAddress;
+ DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_bulk));
+ sc->sc_iface = iface;
+ err = usbd_interface2device_handle(iface, &sc->sc_udev);
+ if (err == 0) {
+ sc->sc_ifaceno = id->bInterfaceNumber;
#if defined(__FreeBSD__)
sc->dev = make_dev(&ulpt_cdevsw, device_get_unit(self),
UID_ROOT, GID_OPERATOR, 0644, "ulpt%d", device_get_unit(self));
@@ -263,10 +248,17 @@
device_get_unit(self)|ULPT_NOPRIME,
UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self));
#endif
-
USB_ATTACH_SUCCESS_RETURN;
-
- nobulk:
+ }
+ }
+ }
+ }
+ }
+ }
+ altno++;
+ }
+ }
+ id = ifcd; /* not found, use original */
printf("%s: could not find bulk endpoint\n",
USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;