PERFORCE change 155936 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Jan 10 12:50:10 PST 2009
http://perforce.freebsd.org/chv.cgi?CH=155936
Change 155936 by hselasky at hselasky_laptop001 on 2009/01/10 20:49:20
Save an USB transfer in UHUB driver by using
the builtin clear-stall mechanism.
Affected files ...
.. //depot/projects/usb/src/sys/dev/usb2/core/usb2_hub.c#31 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/usb2/core/usb2_hub.c#31 (text+ko) ====
@@ -53,6 +53,7 @@
#include <dev/usb2/controller/usb2_bus.h>
#define UHUB_INTR_INTERVAL 250 /* ms */
+#define UHUB_N_TRANSFER 1
#if USB_DEBUG
static int uhub_debug = 0;
@@ -76,10 +77,9 @@
struct uhub_current_state sc_st;/* current state */
device_t sc_dev; /* base device */
struct usb2_device *sc_udev; /* USB device */
- struct usb2_xfer *sc_xfer[2]; /* interrupt xfer */
+ struct usb2_xfer *sc_xfer[UHUB_N_TRANSFER]; /* interrupt xfer */
uint8_t sc_flags;
#define UHUB_FLAG_DID_EXPLORE 0x01
-#define UHUB_FLAG_INTR_STALL 0x02
char sc_name[32];
};
@@ -100,12 +100,11 @@
static bus_child_pnpinfo_str_t uhub_child_pnpinfo_string;
static usb2_callback_t uhub_intr_callback;
-static usb2_callback_t uhub_intr_clear_stall_callback;
static void usb2_dev_resume_peer(struct usb2_device *udev);
static void usb2_dev_suspend_peer(struct usb2_device *udev);
-static const struct usb2_config uhub_config[2] = {
+static const struct usb2_config uhub_config[UHUB_N_TRANSFER] = {
[0] = {
.type = UE_INTERRUPT,
@@ -117,17 +116,6 @@
.mh.callback = &uhub_intr_callback,
.mh.interval = UHUB_INTR_INTERVAL,
},
-
- [1] = {
- .type = UE_CONTROL,
- .endpoint = 0,
- .direction = UE_DIR_ANY,
- .mh.timeout = 1000, /* 1 second */
- .mh.interval = 50, /* 50ms */
- .mh.flags = {},
- .mh.bufsize = sizeof(struct usb2_device_request),
- .mh.callback = &uhub_intr_clear_stall_callback,
- },
};
/*
@@ -160,19 +148,6 @@
DRIVER_MODULE(ushub, ushub, uhub_driver, uhub_devclass, NULL, 0);
static void
-uhub_intr_clear_stall_callback(struct usb2_xfer *xfer)
-{
- struct uhub_softc *sc = xfer->priv_sc;
- struct usb2_xfer *xfer_other = sc->sc_xfer[0];
-
- if (usb2_clear_stall_callback(xfer, xfer_other)) {
- DPRINTF("stall cleared\n");
- sc->sc_flags &= ~UHUB_FLAG_INTR_STALL;
- usb2_transfer_start(xfer_other);
- }
-}
-
-static void
uhub_intr_callback(struct usb2_xfer *xfer)
{
struct uhub_softc *sc = xfer->priv_sc;
@@ -189,21 +164,22 @@
usb2_needs_explore(sc->sc_udev->bus, 0);
case USB_ST_SETUP:
- if (sc->sc_flags & UHUB_FLAG_INTR_STALL) {
- usb2_transfer_start(sc->sc_xfer[1]);
- } else {
- xfer->frlengths[0] = xfer->max_data_length;
- usb2_start_hardware(xfer);
- }
- return;
+ xfer->frlengths[0] = xfer->max_data_length;
+ usb2_start_hardware(xfer);
+ break;
default: /* Error */
if (xfer->error != USB_ERR_CANCELLED) {
- /* start clear stall */
- sc->sc_flags |= UHUB_FLAG_INTR_STALL;
- usb2_transfer_start(sc->sc_xfer[1]);
+ /*
+ * Do a clear-stall. The "stall_pipe" flag
+ * will get cleared before next callback by
+ * the USB stack.
+ */
+ xfer->flags.stall_pipe = 1;
+ xfer->frlengths[0] = xfer->max_data_length;
+ usb2_start_hardware(xfer);
}
- return;
+ break;
}
}
@@ -736,7 +712,7 @@
/* set up interrupt pipe */
iface_index = 0;
err = usb2_transfer_setup(udev, &iface_index, sc->sc_xfer,
- uhub_config, 2, sc, &Giant);
+ uhub_config, UHUB_N_TRANSFER, sc, &Giant);
if (err) {
DPRINTFN(0, "cannot setup interrupt transfer, "
"errstr=%s!\n", usb2_errstr(err));
@@ -821,7 +797,7 @@
return (0);
error:
- usb2_transfer_unsetup(sc->sc_xfer, 2);
+ usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
if (udev->hub) {
free(udev->hub, M_USBDEV);
@@ -864,7 +840,7 @@
child = NULL;
}
- usb2_transfer_unsetup(sc->sc_xfer, 2);
+ usb2_transfer_unsetup(sc->sc_xfer, UHUB_N_TRANSFER);
free(hub, M_USBDEV);
sc->sc_udev->hub = NULL;
More information about the p4-projects
mailing list