Hi Carlos,

> I've noticed every time OpenCT polls the file descriptor returned by
> ifd_sysdep_usb_open the message "/bsd: ugenpoll: no edesc" is written to
> the system log. According to:
> 
> http://archive.netbsd.se/?ml=freebsd-hackers&a=2005-05&t=934813
> 
> the control endpoint does not support polling. Could another endpoint be
> used for that purpose?

In fact, the device ugen0 does not even exist. Thus referring to
ugen0 without any endpoint specification, communication is
(normally) implicitely forwarded to endpoint 0. This endpoint 
doesn't want to be polled though. Any other endpoints can be
polled, as long as their transfer channels. 

FreeBSD has this lines, which also cares for stopping OpenCT
filling up your logs with "no edesc" messages in OpenBSD (see 
the attached patch).

+       /* Do not allow to poll a control endpoint */
+       if ( UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT )
+               return (EIO);

I also attached the OpenBSD port I wrote some time ago with my
patches I used for testing OpenCT there. I reworked your patch
so it applies as a patch for the port. Just move it into the
"patches" directory and delete the old one. 

One other thing: Please don't modify #define sections without a 
reason: the BSD people have a rather strict idea how source files 
have to look. 

I will test the patched version as soon as possible, but as I
just moved appartment, this could take some days. Your
modifications compile clean, though.

All the best,
/Markus


Attachments:    ports archive for OpenCT 0.6.8
                patch for /usr/src/sys/dev/ugen.c
                your patch, reworked


Attachment: openct.tgz
Description: application/tar-gz

--- ugen.c.orig Sun Jul 16 19:24:10 2006
+++ ugen.c      Sun Jul 16 18:46:42 2006
@@ -675,6 +675,9 @@
 
        USB_GET_SC(ugen, UGENUNIT(dev), sc);
 
+       if(sc->sc_dying)
+               return (EIO);
+       
        sc->sc_refcnt++;
        error = ugen_do_read(sc, endpt, uio, flag);
        if (--sc->sc_refcnt < 0)
@@ -774,6 +777,9 @@
 
        USB_GET_SC(ugen, UGENUNIT(dev), sc);
 
+       if (sc->sc_dying)
+               return (EIO);
+       
        sc->sc_refcnt++;
        error = ugen_do_write(sc, endpt, uio, flag);
        if (--sc->sc_refcnt < 0)
@@ -1329,6 +1336,9 @@
 
        USB_GET_SC(ugen, UGENUNIT(dev), sc);
 
+       if (sc->sc_dying)
+               return(EIO);
+       
        sc->sc_refcnt++;
        error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
        if (--sc->sc_refcnt < 0)
@@ -1344,16 +1354,33 @@
        int revents = 0;
        int s;
 
+       /* Do not allow to poll a control endpoint */
+       if ( UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT )
+               return (EIO);
+       
        USB_GET_SC(ugen, UGENUNIT(dev), sc);
 
        if (sc->sc_dying)
                return (EIO);
 
-       /* XXX always IN */
-       sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
+       if((events & POLLIN) && (events & POLLOUT)) {
+               printf("ugenpoll: POLLIN and POLLOUT? We're not \
+                   handling it, so bail.\n");
+               return (EIO);
+       }
+       
+       if(events & (POLLIN | POLLRDNORM))
+               sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
+       else if(events & (POLLOUT | POLLWRNORM))
+               sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT];
+       else {
+               printf("ugenpoll: unhandled input event\n");
+               return (EIO);
+       }
+
        if (sce == NULL)
-               return (EINVAL);
-#ifdef DIAGNOSTIC
+               return (EIO);
+       
        if (!sce->edesc) {
                printf("ugenpoll: no edesc\n");
                return (EIO);
@@ -1362,23 +1389,27 @@
                printf("ugenpoll: no pipe\n");
                return (EIO);
        }
-#endif
+
        s = splusb();
        switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
        case UE_INTERRUPT:
-               if (events & (POLLIN | POLLRDNORM)) {
-                       if (sce->q.c_cc > 0)
+               if (sce->q.c_cc > 0) {
+                       if (events & (POLLIN | POLLRDNORM))
                                revents |= events & (POLLIN | POLLRDNORM);
-                       else
-                               selrecord(p, &sce->rsel);
+                       else if (events & (POLLOUT | POLLWRNORM))
+                               revents |= events & (POLLOUT | POLLWRNORM);
+               } else {
+                       selrecord(p, &sce->rsel);
                }
                break;
        case UE_ISOCHRONOUS:
-               if (events & (POLLIN | POLLRDNORM)) {
-                       if (sce->cur != sce->fill)
+               if (sce->cur != sce->fill) {
+                       if (events & (POLLIN | POLLRDNORM))
                                revents |= events & (POLLIN | POLLRDNORM);
-                       else
-                               selrecord(p, &sce->rsel);
+                       else if (events & (POLLOUT | POLLWRNORM))
+                               revents |= events & (POLLOUT | POLLWRNORM);
+               } else {
+                       selrecord(p, &sce->rsel);
                }
                break;
        case UE_BULK:
--- src/ifd/sys-bsd.c.orig      Sun Jul 30 04:38:14 2006
+++ src/ifd/sys-bsd.c   Sun Jul 30 04:59:20 2006
@@ -37,9 +37,20 @@
                return -1;
 
        if (!strncmp(name, "/dev/ugen", 9)) {
-               ifd_debug(1, "BSD: returning IFD_DEVICE_TYPE_USB");
+
+#ifdef __OpenBSD__
+               char real_device[256];
+
+               snprintf(real_device, sizeof(real_device),
+                   "%s.00", name);
+               
+               if (stat(real_device, &stb) < 0)
+                       return -1;
+#else
                if (stat(name, &stb) < 0)
                        return -1;
+#endif
+               ifd_debug(1, "BSD: returning IFD_DEVICE_TYPE_USB");
                return IFD_DEVICE_TYPE_USB;
        }
 
@@ -79,10 +90,15 @@
                ifd_debug(6, "open_ep: endpoint already opened");
                return 0;
        }
-
+#ifdef __OpenBSD__
+       sprintf((char *)&filename, "%s.%02d", name, endpoint);
+#else
        sprintf((char *)&filename, "%s.%d", name, endpoint);
-
-       if ((interfaces[interface][endpoint].ep_fd = open(filename, flags)) < 
0) {
+#endif /* __OpenBSD__ */
+       
+       ifd_debug (1, "opening endpoint %s", filename);
+       
+       if ((interfaces[interface][endpoint].ep_fd = open(filename, flags, 0)) 
< 0) {
                ifd_debug(6, "open_ep: error opening \"%s\": %s", filename,
                          strerror(errno));
                interfaces[interface][endpoint].ep_fd = 0;
@@ -91,7 +107,7 @@
        return 0;
 }
 
-close_ep(int interface, int endpoint)
+void close_ep(int interface, int endpoint)
 {
        if (interfaces[interface][endpoint].ep_fd) {
                close(interfaces[interface][endpoint].ep_fd);
@@ -107,12 +123,20 @@
        int direction =
            (ep & IFD_USB_ENDPOINT_DIR_MASK) == IFD_USB_ENDPOINT_IN ? 1 : 0;
        int endpoint = (ep & ~IFD_USB_ENDPOINT_DIR_MASK);
-
+       int one = 1;
+       
        ct_debug("ifd_sysdep_usb_bulk: endpoint=%d direction=%d", endpoint,
                 direction);
        if (open_ep(dev->name, 0, endpoint, O_RDWR | O_NONBLOCK)) {
                ct_debug("ifd_sysdep_usb_bulk: opening endpoint failed");
                return -1;
+       }       
+       if (ioctl(interfaces[0][endpoint].ep_fd,
+           USB_SET_SHORT_XFER, &one) < 0 ) {
+               ifd_debug(6, "ifd_sysdep_usb_bulk: USB_SET_SHORT_XFER failed: 
%s",
+                   strerror(errno));
+               ct_error("usb_bulk read failed: %s", strerror(errno));
+               return IFD_ERROR_COMM_ERROR;
        }
        if (direction) {
                if ((bytes_to_process =
@@ -155,8 +179,6 @@
                                 size_t maxpacket, ifd_usb_capture_t ** capret)
 {
        ifd_usb_capture_t *cap;
-       int direction =
-           (ep & IFD_USB_ENDPOINT_DIR_MASK) == IFD_USB_ENDPOINT_IN ? 1 : 0;
        int endpoint = (ep & ~IFD_USB_ENDPOINT_DIR_MASK);
 
        if (!(cap = (ifd_usb_capture_t *) calloc(1, sizeof(*cap) + maxpacket))) 
{
@@ -183,9 +205,6 @@
 {
        struct timeval begin;
        int bytes_to_process = 0;
-       int direction =
-           (cap->endpoint & IFD_USB_ENDPOINT_DIR_MASK) ==
-           IFD_USB_ENDPOINT_IN ? 1 : 0;
        int endpoint = (cap->endpoint & ~IFD_USB_ENDPOINT_DIR_MASK);
 
        gettimeofday(&begin, NULL);
@@ -216,9 +235,6 @@
 
 int ifd_sysdep_usb_end_capture(ifd_device_t * dev, ifd_usb_capture_t * cap)
 {
-       int direction =
-           (cap->endpoint & IFD_USB_ENDPOINT_DIR_MASK) ==
-           IFD_USB_ENDPOINT_IN ? 1 : 0;
        int endpoint = (cap->endpoint & ~IFD_USB_ENDPOINT_DIR_MASK);
        close_ep(0, endpoint);
        if (cap)
@@ -330,7 +346,18 @@
 
 int ifd_sysdep_usb_open(const char *device)
 {
-        return open(device, O_RDWR);
+#ifdef __OpenBSD__
+       char real_device[256];
+
+       snprintf(real_device, sizeof(real_device),
+           "%s.00", device);
+       ifd_debug(1, "opening %s", real_device);
+       return open(real_device, O_RDWR);
+#else
+       ifd_debug(1, "ifd_sysdep_usb_open: opening %s", 
+           device);
+       return open(device, O_RDWR);
+#endif
 }
 
 /*
_______________________________________________
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Reply via email to