PERFORCE change 159241 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sun Mar 15 03:36:29 PDT 2009
http://perforce.freebsd.org/chv.cgi?CH=159241
Change 159241 by hselasky at 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_ */
More information about the p4-projects
mailing list