Subject: Re: uscanner* and 2.0
To: Matthias Scheler <tron@zhadum.de>
From: enami tsugutomo <enami@but-b.or.jp>
List: current-users
Date: 04/01/2004 11:06:25
> > Any instance of this is either a bug in SANE or a bug in ugen(4). Do you
> > still have that scanner?
> 
> Yes, but I need to reconnect it before I can try it. Do you have a
> configuration example how to use a scanner with ugen(4) and SANE?

I tried last nigtht with my scanner (epson GT-9700F), and ugen needs
following modification in order to work with scanimage.  Though, I'm
not sure if ugen.c is really the right place to fix.

enami.

Index: ugen.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/ugen.c,v
retrieving revision 1.66
diff -c -r1.66 ugen.c
*** ugen.c	4 Sep 2003 03:47:03 -0000	1.66
--- ugen.c	1 Apr 2004 01:45:05 -0000
***************
*** 306,311 ****
--- 306,325 ----
  			sce->sc = sc;
  			sce->edesc = ed;
  			sce->iface = iface;
+ 			/*
+ 			 * For some device, the order to open pipe is
+ 			 * importatnt.
+ 			 */
+ 			if (1 &&
+ 			    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
+ 				DPRINTFN(5, ("ugen_set_config: "
+ 				    "open_pipe (endpoint 0x%x)\n",
+ 				    ed->bEndpointAddress));
+ 				err = usbd_open_pipe(sce->iface,
+ 				    ed->bEndpointAddress, 0, &sce->pipeh);
+ 				DPRINTFN(5, ("ugen_set_config: endpoint 0x%x: "
+ 				    "err = %d\n", ed->bEndpointAddress, err));
+ 			}
  		}
  	}
  	return (USBD_NORMAL_COMPLETION);
***************
*** 384,393 ****
  			DPRINTFN(5, ("ugenopen: interrupt open done\n"));
  			break;
  		case UE_BULK:
! 			err = usbd_open_pipe(sce->iface,
! 				  edesc->bEndpointAddress, 0, &sce->pipeh);
! 			if (err)
! 				return (EIO);
  			break;
  		case UE_ISOCHRONOUS:
  			if (dir == OUT)
--- 398,411 ----
  			DPRINTFN(5, ("ugenopen: interrupt open done\n"));
  			break;
  		case UE_BULK:
! 			if (sce->pipeh == NULL) {
! 				DPRINTFN(5, ("ugenopen: endpoint 0x%x\n",
! 				    edesc->bEndpointAddress));
! 				err = usbd_open_pipe(sce->iface,
! 				    edesc->bEndpointAddress, 0, &sce->pipeh);
! 				if (err)
! 					return (EIO);
! 			}
  			break;
  		case UE_ISOCHRONOUS:
  			if (dir == OUT)
***************
*** 480,488 ****
  		DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
  			     endpt, dir, sce));
  
! 		usbd_abort_pipe(sce->pipeh);
! 		usbd_close_pipe(sce->pipeh);
! 		sce->pipeh = NULL;
  
  		switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
  		case UE_INTERRUPT:
--- 498,511 ----
  		DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
  			     endpt, dir, sce));
  
! 		/*
! 		 * For some device, we need to keep pipe open.
! 		 */
! 		if (0) {
! 			usbd_abort_pipe(sce->pipeh);
! 			usbd_close_pipe(sce->pipeh);
! 			sce->pipeh = NULL;
! 		}
  
  		switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
  		case UE_INTERRUPT:
***************
*** 582,588 ****
  		if (xfer == 0)
  			return (ENOMEM);
  		while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
! 			DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
  			tn = n;
  			err = usbd_bulk_transfer(
  				  xfer, sce->pipeh,
--- 605,614 ----
  		if (xfer == 0)
  			return (ENOMEM);
  		while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
! 			DPRINTFN(1, ("ugenread: start transfer %d bytes%s, "
! 			    "timeout %x\n",
! 			    n, sce->state & UGEN_SHORT_OK ? " (short ok)" : "",
! 			    sce->timeout));
  			tn = n;
  			err = usbd_bulk_transfer(
  				  xfer, sce->pipeh,