summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2009-02-09 21:56:33 +0000
committerthompsa <thompsa@FreeBSD.org>2009-02-09 21:56:33 +0000
commit1267fde951ac97e2a78d4007348e4bbc9a4595dc (patch)
tree2748b1c4373c619a63e26bfd471adb0551de602d
parent1f67e30bafd08e89983cbb3d71482b7ae4c9b628 (diff)
downloadFreeBSD-src-1267fde951ac97e2a78d4007348e4bbc9a4595dc.zip
FreeBSD-src-1267fde951ac97e2a78d4007348e4bbc9a4595dc.tar.gz
MFp4 //depot/projects/usb; 157069, 157429, 157430
- Change "usb2_pause_mtx" so that it takes the timeout value in ticks - Factor out USB ethernet and USB serial driver specific control request. - USB process naming cleanup. Submitted by: Hans Petter Selasky
-rw-r--r--sys/dev/usb2/core/usb2_core.h1
-rw-r--r--sys/dev/usb2/core/usb2_device.c17
-rw-r--r--sys/dev/usb2/core/usb2_hub.c11
-rw-r--r--sys/dev/usb2/core/usb2_msctest.c2
-rw-r--r--sys/dev/usb2/core/usb2_process.c17
-rw-r--r--sys/dev/usb2/core/usb2_process.h6
-rw-r--r--sys/dev/usb2/core/usb2_request.c59
-rw-r--r--sys/dev/usb2/core/usb2_request.h5
-rw-r--r--sys/dev/usb2/core/usb2_transfer.c3
-rw-r--r--sys/dev/usb2/core/usb2_util.c31
-rw-r--r--sys/dev/usb2/core/usb2_util.h2
11 files changed, 111 insertions, 43 deletions
diff --git a/sys/dev/usb2/core/usb2_core.h b/sys/dev/usb2/core/usb2_core.h
index 156ec5d..33b1a27 100644
--- a/sys/dev/usb2/core/usb2_core.h
+++ b/sys/dev/usb2/core/usb2_core.h
@@ -434,6 +434,7 @@ uint8_t usb2_clear_stall_callback(struct usb2_xfer *xfer1,
uint8_t usb2_get_interface_altindex(struct usb2_interface *iface);
usb2_error_t usb2_set_alt_interface_index(struct usb2_device *udev,
uint8_t iface_index, uint8_t alt_index);
+uint8_t usb2_get_mode(struct usb2_device *udev);
uint8_t usb2_get_speed(struct usb2_device *udev);
uint32_t usb2_get_isoc_fps(struct usb2_device *udev);
usb2_error_t usb2_transfer_setup(struct usb2_device *udev,
diff --git a/sys/dev/usb2/core/usb2_device.c b/sys/dev/usb2/core/usb2_device.c
index 6f398bc..41272bb 100644
--- a/sys/dev/usb2/core/usb2_device.c
+++ b/sys/dev/usb2/core/usb2_device.c
@@ -1401,7 +1401,8 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus,
"(ignored)\n", udev->address);
}
/* allow device time to set new address */
- usb2_pause_mtx(&Giant, USB_SET_ADDRESS_SETTLE);
+ usb2_pause_mtx(&Giant,
+ USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
} else {
/* We are not self powered */
udev->flags.self_powered = 0;
@@ -1951,6 +1952,20 @@ usb2_check_strings(struct usb2_device *udev)
}
}
+/*
+ * Returns:
+ * See: USB_MODE_XXX
+ */
+uint8_t
+usb2_get_mode(struct usb2_device *udev)
+{
+ return (udev->flags.usb2_mode);
+}
+
+/*
+ * Returns:
+ * See: USB_SPEED_XXX
+ */
uint8_t
usb2_get_speed(struct usb2_device *udev)
{
diff --git a/sys/dev/usb2/core/usb2_hub.c b/sys/dev/usb2/core/usb2_hub.c
index 47db119..8c2d639 100644
--- a/sys/dev/usb2/core/usb2_hub.c
+++ b/sys/dev/usb2/core/usb2_hub.c
@@ -335,7 +335,8 @@ repeat:
/* wait for maximum device power up time */
- usb2_pause_mtx(&Giant, USB_PORT_POWERUP_DELAY);
+ usb2_pause_mtx(&Giant,
+ USB_MS_TO_TICKS(USB_PORT_POWERUP_DELAY));
/* reset port, which implies enabling it */
@@ -736,7 +737,7 @@ uhub_attach(device_t dev)
goto error;
}
/* wait with power off for a while */
- usb2_pause_mtx(&Giant, USB_POWER_DOWN_TIME);
+ usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_POWER_DOWN_TIME));
/*
* To have the best chance of success we do things in the exact same
@@ -794,7 +795,7 @@ uhub_attach(device_t dev)
portno);
/* wait for stable power */
- usb2_pause_mtx(&Giant, pwrdly);
+ usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(pwrdly));
}
device_printf(dev, "%d port%s with %d "
@@ -1666,7 +1667,7 @@ usb2_dev_resume_peer(struct usb2_device *udev)
return;
}
/* resume settle time */
- usb2_pause_mtx(&Giant, USB_PORT_RESUME_DELAY);
+ usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(USB_PORT_RESUME_DELAY));
if (bus->methods->device_resume != NULL) {
/* resume USB device on the USB controller */
@@ -1802,7 +1803,7 @@ repeat:
/* do DMA delay */
temp = usb2_get_dma_delay(udev->bus);
- usb2_pause_mtx(&Giant, temp);
+ usb2_pause_mtx(&Giant, USB_MS_TO_TICKS(temp));
}
/* suspend current port */
diff --git a/sys/dev/usb2/core/usb2_msctest.c b/sys/dev/usb2/core/usb2_msctest.c
index 452f389..fbd7dbc 100644
--- a/sys/dev/usb2/core/usb2_msctest.c
+++ b/sys/dev/usb2/core/usb2_msctest.c
@@ -562,7 +562,7 @@ repeat_inquiry:
goto done;
}
} else if ((err != 2) && --timeout) {
- usb2_pause_mtx(&sc->mtx, USB_MS_HZ);
+ usb2_pause_mtx(&sc->mtx, hz);
goto repeat_inquiry;
}
err = USB_ERR_INVAL;
diff --git a/sys/dev/usb2/core/usb2_process.c b/sys/dev/usb2/core/usb2_process.c
index facd84e..890d53e 100644
--- a/sys/dev/usb2/core/usb2_process.c
+++ b/sys/dev/usb2/core/usb2_process.c
@@ -164,7 +164,7 @@ usb2_process(void *arg)
}
/*------------------------------------------------------------------------*
- * usb2_proc_setup
+ * usb2_proc_create
*
* This function will create a process using the given "prio" that can
* execute callbacks. The mutex pointed to by "p_mtx" will be applied
@@ -176,8 +176,9 @@ usb2_process(void *arg)
* 0: success
* Else: failure
*------------------------------------------------------------------------*/
-uint8_t
-usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx, uint8_t prio)
+int
+usb2_proc_create(struct usb2_process *up, struct mtx *p_mtx,
+ const char *pmesg, uint8_t prio)
{
up->up_mtx = p_mtx;
up->up_prio = prio;
@@ -188,7 +189,7 @@ usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx, uint8_t prio)
usb2_cv_init(&up->up_drain, "dmsg");
if (USB_THREAD_CREATE(&usb2_process, up,
- &up->up_ptr, "usbproc")) {
+ &up->up_ptr, pmesg)) {
DPRINTFN(0, "Unable to create USB process.");
up->up_ptr = NULL;
goto error;
@@ -196,12 +197,12 @@ usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx, uint8_t prio)
return (0);
error:
- usb2_proc_unsetup(up);
- return (1);
+ usb2_proc_free(up);
+ return (ENOMEM);
}
/*------------------------------------------------------------------------*
- * usb2_proc_unsetup
+ * usb2_proc_free
*
* NOTE: If the structure pointed to by "up" is all zero, this
* function does nothing.
@@ -210,7 +211,7 @@ error:
* removed nor called.
*------------------------------------------------------------------------*/
void
-usb2_proc_unsetup(struct usb2_process *up)
+usb2_proc_free(struct usb2_process *up)
{
if (!(up->up_mtx)) {
/* not initialised */
diff --git a/sys/dev/usb2/core/usb2_process.h b/sys/dev/usb2/core/usb2_process.h
index 17a0248..78fdb3aa 100644
--- a/sys/dev/usb2/core/usb2_process.h
+++ b/sys/dev/usb2/core/usb2_process.h
@@ -79,12 +79,12 @@ struct usb2_process {
uint8_t usb2_proc_cwait(struct usb2_process *up, int timeout);
uint8_t usb2_proc_is_gone(struct usb2_process *up);
-uint8_t usb2_proc_setup(struct usb2_process *up, struct mtx *p_mtx,
- uint8_t prio);
+int usb2_proc_create(struct usb2_process *up, struct mtx *p_mtx,
+ const char *pmesg, uint8_t prio);
void usb2_proc_csignal(struct usb2_process *up);
void usb2_proc_drain(struct usb2_process *up);
void usb2_proc_mwait(struct usb2_process *up, void *pm0, void *pm1);
-void usb2_proc_unsetup(struct usb2_process *up);
+void usb2_proc_free(struct usb2_process *up);
void *usb2_proc_msignal(struct usb2_process *up, void *pm0, void *pm1);
#endif /* _USB2_PROCESS_H_ */
diff --git a/sys/dev/usb2/core/usb2_request.c b/sys/dev/usb2/core/usb2_request.c
index 3e48dc1..75a14ff 100644
--- a/sys/dev/usb2/core/usb2_request.c
+++ b/sys/dev/usb2/core/usb2_request.c
@@ -371,7 +371,7 @@ usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
if (temp > 0) {
usb2_pause_mtx(
xfer->xroot->xfer_mtx,
- temp);
+ USB_MS_TO_TICKS(temp));
}
#endif
xfer->flags.manual_status = 0;
@@ -477,6 +477,49 @@ done:
}
/*------------------------------------------------------------------------*
+ * usb2_do_request_proc - factored out code
+ *
+ * This function is factored out code. It does basically the same like
+ * usb2_do_request_flags, except it will check the status of the
+ * passed process argument before doing the USB request. If the
+ * process is draining the USB_ERR_IOERROR code will be returned. It
+ * is assumed that the mutex associated with the process is locked
+ * when calling this function.
+ *------------------------------------------------------------------------*/
+usb2_error_t
+usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc,
+ struct usb2_device_request *req, void *data, uint32_t flags,
+ uint16_t *actlen, uint32_t timeout)
+{
+ usb2_error_t err;
+ uint16_t len;
+
+ /* get request data length */
+ len = UGETW(req->wLength);
+
+ /* check if the device is being detached */
+ if (usb2_proc_is_gone(pproc)) {
+ err = USB_ERR_IOERROR;
+ goto done;
+ }
+
+ /* forward the USB request */
+ err = usb2_do_request_flags(udev, pproc->up_mtx,
+ req, data, flags, actlen, timeout);
+
+done:
+ /* on failure we zero the data */
+ /* on short packet we zero the unused data */
+ if ((len != 0) && (req->bmRequestType & UE_DIR_IN)) {
+ if (err)
+ memset(data, 0, len);
+ else if (actlen && *actlen != len)
+ memset(((uint8_t *)data) + *actlen, 0, len - *actlen);
+ }
+ return (err);
+}
+
+/*------------------------------------------------------------------------*
* usb2_req_reset_port
*
* This function will instruct an USB HUB to perform a reset sequence
@@ -520,11 +563,11 @@ usb2_req_reset_port(struct usb2_device *udev, struct mtx *mtx, uint8_t port)
while (1) {
#if USB_DEBUG
/* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, pr_poll_delay);
+ usb2_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay));
n += pr_poll_delay;
#else
/* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, USB_PORT_RESET_DELAY);
+ usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY));
n += USB_PORT_RESET_DELAY;
#endif
err = usb2_req_get_port_status(udev, mtx, &ps, port);
@@ -559,10 +602,10 @@ usb2_req_reset_port(struct usb2_device *udev, struct mtx *mtx, uint8_t port)
}
#if USB_DEBUG
/* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, pr_recovery_delay);
+ usb2_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay));
#else
/* wait for the device to recover from reset */
- usb2_pause_mtx(mtx, USB_PORT_RESET_RECOVERY);
+ usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY));
#endif
done:
@@ -624,7 +667,7 @@ usb2_req_get_desc(struct usb2_device *udev, struct mtx *mtx, void *desc,
}
retries--;
- usb2_pause_mtx(mtx, 200);
+ usb2_pause_mtx(mtx, hz / 5);
continue;
}
@@ -1369,7 +1412,7 @@ retry:
udev->address = old_addr;
/* allow device time to set new address */
- usb2_pause_mtx(mtx, USB_SET_ADDRESS_SETTLE);
+ usb2_pause_mtx(mtx, USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE));
/* get the device descriptor */
err = usb2_req_get_desc(udev, mtx, &udev->ddesc,
@@ -1389,7 +1432,7 @@ retry:
done:
if (err && do_retry) {
/* give the USB firmware some time to load */
- usb2_pause_mtx(mtx, 500);
+ usb2_pause_mtx(mtx, hz / 2);
/* no more retries after this retry */
do_retry = 0;
/* try again */
diff --git a/sys/dev/usb2/core/usb2_request.h b/sys/dev/usb2/core/usb2_request.h
index b33e0a1..8a360b7 100644
--- a/sys/dev/usb2/core/usb2_request.h
+++ b/sys/dev/usb2/core/usb2_request.h
@@ -27,9 +27,14 @@
#ifndef _USB2_REQUEST_H_
#define _USB2_REQUEST_H_
+struct usb2_process;
+
usb2_error_t usb2_do_request_flags(struct usb2_device *udev, struct mtx *mtx,
struct usb2_device_request *req, void *data, uint32_t flags,
uint16_t *actlen, uint32_t timeout);
+usb2_error_t usb2_do_request_proc(struct usb2_device *udev, struct usb2_process *pproc,
+ struct usb2_device_request *req, void *data, uint32_t flags,
+ uint16_t *actlen, uint32_t timeout);
usb2_error_t usb2_req_clear_hub_feature(struct usb2_device *udev,
struct mtx *mtx, uint16_t sel);
usb2_error_t usb2_req_clear_port_feature(struct usb2_device *udev,
diff --git a/sys/dev/usb2/core/usb2_transfer.c b/sys/dev/usb2/core/usb2_transfer.c
index d47845e..ef512d3 100644
--- a/sys/dev/usb2/core/usb2_transfer.c
+++ b/sys/dev/usb2/core/usb2_transfer.c
@@ -1066,7 +1066,8 @@ usb2_transfer_unsetup_sub(struct usb2_xfer_root *info, uint8_t needs_delay)
if (needs_delay) {
temp = usb2_get_dma_delay(info->bus);
- usb2_pause_mtx(&info->bus->bus_mtx, temp);
+ usb2_pause_mtx(&info->bus->bus_mtx,
+ USB_MS_TO_TICKS(temp));
}
/* make sure that our done messages are not queued anywhere */
diff --git a/sys/dev/usb2/core/usb2_util.c b/sys/dev/usb2/core/usb2_util.c
index 953997e..5dca332 100644
--- a/sys/dev/usb2/core/usb2_util.c
+++ b/sys/dev/usb2/core/usb2_util.c
@@ -124,36 +124,37 @@ device_set_usb2_desc(device_t dev)
/*------------------------------------------------------------------------*
* usb2_pause_mtx - factored out code
*
- * This function will delay the code by the passed number of
- * milliseconds. The passed mutex "mtx" will be dropped while waiting,
- * if "mtx" is not NULL. The number of milliseconds per second is 1024
- * for sake of optimisation.
+ * This function will delay the code by the passed number of system
+ * ticks. The passed mutex "mtx" will be dropped while waiting, if
+ * "mtx" is not NULL.
*------------------------------------------------------------------------*/
void
-usb2_pause_mtx(struct mtx *mtx, uint32_t ms)
+usb2_pause_mtx(struct mtx *mtx, int _ticks)
{
+ if (mtx != NULL)
+ mtx_unlock(mtx);
+
if (cold) {
- ms = (ms + 1) * 1024;
- DELAY(ms);
+ /* convert to milliseconds */
+ _ticks = (_ticks * 1000) / hz;
+ /* convert to microseconds, rounded up */
+ _ticks = (_ticks + 1) * 1000;
+ DELAY(_ticks);
} else {
- ms = USB_MS_TO_TICKS(ms);
/*
* Add one to the number of ticks so that we don't return
* too early!
*/
- ms++;
-
- if (mtx != NULL)
- mtx_unlock(mtx);
+ _ticks++;
- if (pause("USBWAIT", ms)) {
+ if (pause("USBWAIT", _ticks)) {
/* ignore */
}
- if (mtx != NULL)
- mtx_lock(mtx);
}
+ if (mtx != NULL)
+ mtx_lock(mtx);
}
/*------------------------------------------------------------------------*
diff --git a/sys/dev/usb2/core/usb2_util.h b/sys/dev/usb2/core/usb2_util.h
index 8bbae8c..e081c31 100644
--- a/sys/dev/usb2/core/usb2_util.h
+++ b/sys/dev/usb2/core/usb2_util.h
@@ -31,7 +31,7 @@ int device_delete_all_children(device_t dev);
uint32_t usb2_get_devid(device_t dev);
uint8_t usb2_make_str_desc(void *ptr, uint16_t max_len, const char *s);
void device_set_usb2_desc(device_t dev);
-void usb2_pause_mtx(struct mtx *mtx, uint32_t ms);
+void usb2_pause_mtx(struct mtx *mtx, int _ticks);
void usb2_printBCD(char *p, uint16_t p_len, uint16_t bcd);
void usb2_trim_spaces(char *p);
OpenPOWER on IntegriCloud