From owner-p4-projects@FreeBSD.ORG Sun Mar 15 10:36:29 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 20D201065672; Sun, 15 Mar 2009 10:36:29 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D414B106564A for ; Sun, 15 Mar 2009 10:36:28 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B776F8FC21 for ; Sun, 15 Mar 2009 10:36:28 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n2FAaSOb088026 for ; Sun, 15 Mar 2009 10:36:28 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n2FAaS9m088024 for perforce@freebsd.org; Sun, 15 Mar 2009 10:36:28 GMT (envelope-from hselasky@FreeBSD.org) Date: Sun, 15 Mar 2009 10:36:28 GMT Message-Id: <200903151036.n2FAaS9m088024@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 159241 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 15 Mar 2009 10:36:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=159241 Change 159241 by hselasky@hselasky_laptop001 on 2009/03/15 10:35:49 USB ulpt+uscanner fix: - Only send a ZLP before close. Some printers and scanners appear to be choking on force_short_xfer ! - Cleanup usage of dev_ep_index variable. - Make sure that fifo_index does not contain any direction specific bits. Reported by: Alexander Best Affected files ... .. //depot/projects/usb/src/sys/dev/usb/image/uscanner.c#4 edit .. //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#4 edit .. //depot/projects/usb/src/sys/dev/usb/usb_dev.c#9 edit .. //depot/projects/usb/src/sys/dev/usb/usb_dev.h#6 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb/image/uscanner.c#4 (text+ko) ==== @@ -149,7 +149,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .mh.bufsize = USCANNER_BSIZE, - .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1,.force_short_xfer = 1,}, + .mh.flags = {.pipe_bof = 1,.proxy_buffer = 1,}, .mh.callback = &uscanner_write_callback, }, @@ -578,6 +578,7 @@ USCANNER_IFQ_MAXLEN)) { return (ENOMEM); } + usb2_fifo_set_close_zlp(fifo, 1); } return (0); } ==== //depot/projects/usb/src/sys/dev/usb/serial/ulpt.c#4 (text+ko) ==== @@ -200,7 +200,8 @@ DPRINTF("no FIFO\n"); return; } - DPRINTF("state=0x%x\n", USB_GET_STATE(xfer)); + DPRINTF("state=0x%x actlen=%u\n", + USB_GET_STATE(xfer), xfer->actlen); switch (USB_GET_STATE(xfer)) { case USB_ST_TRANSFERRED: @@ -208,7 +209,6 @@ tr_setup: if (usb2_fifo_get_data(f, xfer->frbuffers, 0, xfer->max_data_length, &actlen, 0)) { - xfer->frlengths[0] = actlen; usb2_start_hardware(xfer); } @@ -339,7 +339,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .mh.bufsize = ULPT_BSIZE, - .mh.flags = {.pipe_bof = 1,.force_short_xfer = 1,.proxy_buffer = 1}, + .mh.flags = {.pipe_bof = 1,.proxy_buffer = 1}, .mh.callback = &ulpt_write_callback, }, @@ -440,6 +440,7 @@ } /* set which FIFO is opened */ sc->sc_fifo_open[USB_FIFO_TX] = fifo; + usb2_fifo_set_close_zlp(fifo, 1); } sc->sc_fflags |= fflags & (FREAD | FWRITE); return (0); ==== //depot/projects/usb/src/sys/dev/usb/usb_dev.c#9 (text+ko) ==== @@ -161,7 +161,6 @@ { struct usb2_fifo **ppf; struct usb2_fifo *f; - int dev_ep_index; DPRINTFN(2, "usb2_ref_device, cpd=%p need uref=%d\n", cpd, need_uref); @@ -181,7 +180,6 @@ goto error; } /* check if we are doing an open */ - dev_ep_index = cpd->ep_addr; if (cpd->fflags == 0) { /* set defaults */ cpd->txfifo = NULL; @@ -207,11 +205,6 @@ if (f->fs_ep_max != 0) { cpd->is_usbfs = 1; } - /* - * Get real endpoint index associated with - * this FIFO: - */ - dev_ep_index = f->dev_ep_index; } else { cpd->txfifo = NULL; cpd->is_write = 0; /* no ref */ @@ -231,11 +224,6 @@ if (f->fs_ep_max != 0) { cpd->is_usbfs = 1; } - /* - * Get real endpoint index associated with - * this FIFO: - */ - dev_ep_index = f->dev_ep_index; } else { cpd->rxfifo = NULL; cpd->is_read = 0; /* no ref */ @@ -471,7 +459,7 @@ if (no_null == 0) { if (ep >= (USB_EP_MAX / 2)) { /* we don't create any endpoints in this range */ - DPRINTFN(5, "dev_ep_index out of range\n"); + DPRINTFN(5, "ep out of range\n"); return (is_busy ? EBUSY : EINVAL); } } @@ -681,6 +669,9 @@ goto done; } + /* reset short flag before open */ + f->flag_short = 0; + /* call open method */ err = (f->methods->f_open) (f, fflags); if (err) { @@ -893,18 +884,15 @@ usb2_close(void *arg) { struct usb2_cdev_privdata *cpd = arg; - struct usb2_device *udev; int err; - DPRINTFN(2, "usb2_close, cpd=%p\n", cpd); + DPRINTFN(2, "cpd=%p\n", cpd); err = usb2_ref_device(cpd, 1); if (err) { free(cpd, M_USBDEV); return; } - - udev = cpd->udev; if (cpd->fflags & FREAD) { usb2_fifo_close(cpd->rxfifo, cpd->fflags); } @@ -1618,7 +1606,6 @@ /* initialise FIFO structures */ f_tx->fifo_index = n + USB_FIFO_TX; - f_tx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2); f_tx->priv_mtx = priv_mtx; f_tx->priv_sc0 = priv_sc; f_tx->methods = pm; @@ -1626,7 +1613,6 @@ f_tx->udev = udev; f_rx->fifo_index = n + USB_FIFO_RX; - f_rx->dev_ep_index = (n / 2) + (USB_EP_MAX / 2); f_rx->priv_mtx = priv_mtx; f_rx->priv_sc0 = priv_sc; f_rx->methods = pm; @@ -1681,12 +1667,13 @@ pd->bus_index = device_get_unit(udev->bus->bdev); pd->dev_index = udev->device_index; pd->ep_addr = -1; /* not an endpoint */ - pd->fifo_index = f_tx->fifo_index; + pd->fifo_index = f_tx->fifo_index & f_rx->fifo_index; pd->mode = FREAD|FWRITE; /* Now, create the device itself */ f_sc->dev = make_dev(&usb2_devsw, 0, uid, gid, mode, devname); + /* XXX setting si_drv1 and creating the device is not atomic! */ f_sc->dev->si_drv1 = pd; } @@ -1948,6 +1935,13 @@ break; } if (f->flag_flushing) { + /* check if we should send a short packet */ + if (f->flag_short != 0) { + f->flag_short = 0; + tr_data = 1; + break; + } + /* flushing complete */ f->flag_flushing = 0; usb2_fifo_wakeup(f); } @@ -2006,6 +2000,13 @@ break; } if (f->flag_flushing) { + /* check if we should send a short packet */ + if (f->flag_short != 0) { + f->flag_short = 0; + tr_data = 1; + break; + } + /* flushing complete */ f->flag_flushing = 0; usb2_fifo_wakeup(f); } @@ -2185,3 +2186,13 @@ sx_unlock(&usb2_sym_lock); return (error); } + +void +usb2_fifo_set_close_zlp(struct usb2_fifo *f, uint8_t onoff) +{ + if (f == NULL) + return; + + /* send a Zero Length Packet, ZLP, before close */ + f->flag_short = onoff; +} ==== //depot/projects/usb/src/sys/dev/usb/usb_dev.h#6 (text+ko) ==== @@ -195,5 +195,6 @@ void usb2_free_symlink(struct usb2_symlink *ps); int usb2_read_symlink(uint8_t *user_ptr, uint32_t startentry, uint32_t user_len); +void usb2_fifo_set_close_zlp(struct usb2_fifo *, uint8_t); #endif /* _USB2_DEV_H_ */