diff -ur dev/usb/ugen.c /usr/local/src/mykernelhack/dev/usb/ugen.c --- dev/usb/ugen.c Thu Feb 21 05:30:12 2002 +++ /usr/local/src/mykernelhack/dev/usb/ugen.c Sat Jan 3 21:05:36 2004 @@ -107,6 +107,7 @@ void *dmabuf; u_int16_t sizes[UGEN_NISORFRMS]; } isoreqs[UGEN_NISOREQS]; + int chksum; /* apply checksum to raw packet (isoc) */ }; struct ugen_softc { @@ -119,6 +120,7 @@ #define IN 1 int sc_refcnt; + int sc_chksum; /* checksum setting (for isoc endpoints) */ u_char sc_dying; }; @@ -394,6 +396,7 @@ free(sce->ibuf, M_USBDEV); return (EIO); } + sce->chksum = sc->sc_chksum; for(i = 0; i < UGEN_NISOREQS; ++i) { sce->isoreqs[i].sce = sce; xfer = usbd_alloc_xfer(sc->sc_udev); @@ -867,6 +870,32 @@ u_int32_t actlen = req->sizes[i]; char const *buf = (char const *)req->dmabuf + isize * i; + /* checksum */ + if ( sce->chksum > 0 ) { + if ( actlen > 2 ) { + int j; + u_int32_t checksum, packetsum; + unsigned char const *cbuf; + cbuf = (unsigned char const *)req->dmabuf + isize * i; + packetsum = 0; + for (j = 0; j < actlen-2; ++j) { + packetsum += cbuf[j]; + } + checksum = cbuf[j] + cbuf[j+1]*256u; + if ( (packetsum&0xffff) == checksum ) { + DPRINTFN(4, ("ugen_isoc_rintr: checksum OK\n")); + actlen -= 2; + } else { + DPRINTFN(4, ("ugen_isoc_rintr: checksum NG %x %x\n",packetsum,checksum)); + actlen = 0; + } + } else { + if ( actlen > 0 ) + DPRINTFN(4, ("ugen_isoc_rintr: ignore short data %d\n",actlen)); + actlen = 0; + } + } + /* copy data to buffer */ while (actlen > 0) { n = min(actlen, sce->limit - sce->fill); @@ -1042,6 +1071,13 @@ ) return (EINVAL); sce->timeout = *(int *)addr; + return (0); + case USB_SET_PACKETCHKSUM: + if (endpt != USB_CONTROL_ENDPOINT) + return (EINVAL); + if ( (*(int *)addr > 1) || (*(int *)addr < 0) ) + return (EINVAL); + sc->sc_chksum = *(int *)addr; return (0); default: break; diff -ur dev/usb/usb.h /usr/local/src/mykernelhack/dev/usb/usb.h --- dev/usb/usb.h Tue Feb 26 19:27:49 2002 +++ /usr/local/src/mykernelhack/dev/usb/usb.h Fri Jan 2 12:09:26 2004 @@ -667,6 +667,7 @@ #define USB_GET_DEVICEINFO _IOR ('U', 112, struct usb_device_info) #define USB_SET_SHORT_XFER _IOW ('U', 113, int) #define USB_SET_TIMEOUT _IOW ('U', 114, int) +#define USB_SET_PACKETCHKSUM _IOW ('U', 115, int) /* Modem device */ #define USB_GET_CM_OVER_DATA _IOR ('U', 130, int)