mirror of
https://github.com/u-boot/u-boot.git
synced 2024-12-10 13:13:28 +08:00
Merge branch 'master' of git://git.denx.de/u-boot-usb
This commit is contained in:
commit
8a6b088aff
@ -430,6 +430,16 @@ static int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_USB_STORAGE */
|
#endif /* CONFIG_USB_STORAGE */
|
||||||
|
|
||||||
|
static int do_usb_stop_keyboard(int force)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USB_KEYBOARD
|
||||||
|
if (usb_kbd_deregister(force) != 0) {
|
||||||
|
printf("USB not stopped: usbkbd still using USB\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* usb command intepreter
|
* usb command intepreter
|
||||||
@ -450,6 +460,8 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
if ((strncmp(argv[1], "reset", 5) == 0) ||
|
if ((strncmp(argv[1], "reset", 5) == 0) ||
|
||||||
(strncmp(argv[1], "start", 5) == 0)) {
|
(strncmp(argv[1], "start", 5) == 0)) {
|
||||||
bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
|
bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
|
||||||
|
if (do_usb_stop_keyboard(1) != 0)
|
||||||
|
return 1;
|
||||||
usb_stop();
|
usb_stop();
|
||||||
printf("(Re)start USB...\n");
|
printf("(Re)start USB...\n");
|
||||||
if (usb_init() >= 0) {
|
if (usb_init() >= 0) {
|
||||||
@ -468,19 +480,10 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strncmp(argv[1], "stop", 4) == 0) {
|
if (strncmp(argv[1], "stop", 4) == 0) {
|
||||||
#ifdef CONFIG_USB_KEYBOARD
|
if (argc != 2)
|
||||||
if (argc == 2) {
|
|
||||||
if (usb_kbd_deregister() != 0) {
|
|
||||||
printf("USB not stopped: usbkbd still"
|
|
||||||
" using USB\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* forced stop, switch console in to serial */
|
|
||||||
console_assign(stdin, "serial");
|
console_assign(stdin, "serial");
|
||||||
usb_kbd_deregister();
|
if (do_usb_stop_keyboard(0) != 0)
|
||||||
}
|
return 1;
|
||||||
#endif
|
|
||||||
printf("stopping USB..\n");
|
printf("stopping USB..\n");
|
||||||
usb_stop();
|
usb_stop();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -34,6 +34,9 @@ char *stdio_names[MAX_FILES] = { "stdin", "stdout", "stderr" };
|
|||||||
#define CONFIG_SYS_DEVICE_NULLDEV 1
|
#define CONFIG_SYS_DEVICE_NULLDEV 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
||||||
|
#define CONFIG_SYS_DEVICE_NULLDEV 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_DEVICE_NULLDEV
|
#ifdef CONFIG_SYS_DEVICE_NULLDEV
|
||||||
void nulldev_putc(struct stdio_dev *dev, const char c)
|
void nulldev_putc(struct stdio_dev *dev, const char c)
|
||||||
@ -172,7 +175,7 @@ int stdio_register(struct stdio_dev *dev)
|
|||||||
* returns 0 if success, -1 if device is assigned and 1 if devname not found
|
* returns 0 if success, -1 if device is assigned and 1 if devname not found
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
||||||
int stdio_deregister_dev(struct stdio_dev *dev)
|
int stdio_deregister_dev(struct stdio_dev *dev, int force)
|
||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
struct list_head *pos;
|
struct list_head *pos;
|
||||||
@ -181,6 +184,10 @@ int stdio_deregister_dev(struct stdio_dev *dev)
|
|||||||
/* get stdio devices (ListRemoveItem changes the dev list) */
|
/* get stdio devices (ListRemoveItem changes the dev list) */
|
||||||
for (l=0 ; l< MAX_FILES; l++) {
|
for (l=0 ; l< MAX_FILES; l++) {
|
||||||
if (stdio_devices[l] == dev) {
|
if (stdio_devices[l] == dev) {
|
||||||
|
if (force) {
|
||||||
|
strcpy(temp_names[l], "nulldev");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
/* Device is assigned -> report error */
|
/* Device is assigned -> report error */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -202,7 +209,7 @@ int stdio_deregister_dev(struct stdio_dev *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stdio_deregister(const char *devname)
|
int stdio_deregister(const char *devname, int force)
|
||||||
{
|
{
|
||||||
struct stdio_dev *dev;
|
struct stdio_dev *dev;
|
||||||
|
|
||||||
@ -211,7 +218,7 @@ int stdio_deregister(const char *devname)
|
|||||||
if (!dev) /* device not found */
|
if (!dev) /* device not found */
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
return stdio_deregister_dev(dev);
|
return stdio_deregister_dev(dev, force);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_SYS_STDIO_DEREGISTER */
|
#endif /* CONFIG_SYS_STDIO_DEREGISTER */
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio_dev.h>
|
#include <stdio_dev.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
@ -170,11 +171,12 @@ static void usb_kbd_setled(struct usb_device *dev)
|
|||||||
{
|
{
|
||||||
struct usb_interface *iface = &dev->config.if_desc[0];
|
struct usb_interface *iface = &dev->config.if_desc[0];
|
||||||
struct usb_kbd_pdata *data = dev->privptr;
|
struct usb_kbd_pdata *data = dev->privptr;
|
||||||
uint32_t leds = data->flags & USB_KBD_LEDMASK;
|
ALLOC_ALIGN_BUFFER(uint32_t, leds, 1, USB_DMA_MINALIGN);
|
||||||
|
|
||||||
|
*leds = data->flags & USB_KBD_LEDMASK;
|
||||||
usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||||
USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
USB_REQ_SET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||||
0x200, iface->desc.bInterfaceNumber, (void *)&leds, 1, 0);
|
0x200, iface->desc.bInterfaceNumber, leds, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CAPITAL_MASK 0x20
|
#define CAPITAL_MASK 0x20
|
||||||
@ -488,7 +490,7 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
|
|||||||
/* Search for keyboard and register it if found. */
|
/* Search for keyboard and register it if found. */
|
||||||
int drv_usb_kbd_init(void)
|
int drv_usb_kbd_init(void)
|
||||||
{
|
{
|
||||||
struct stdio_dev usb_kbd_dev, *old_dev;
|
struct stdio_dev usb_kbd_dev;
|
||||||
struct usb_device *dev;
|
struct usb_device *dev;
|
||||||
char *stdinname = getenv("stdin");
|
char *stdinname = getenv("stdin");
|
||||||
int error, i;
|
int error, i;
|
||||||
@ -507,16 +509,6 @@ int drv_usb_kbd_init(void)
|
|||||||
if (usb_kbd_probe(dev, 0) != 1)
|
if (usb_kbd_probe(dev, 0) != 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We found a keyboard, check if it is already registered. */
|
|
||||||
debug("USB KBD: found set up device.\n");
|
|
||||||
old_dev = stdio_get_by_name(DEVNAME);
|
|
||||||
if (old_dev) {
|
|
||||||
/* Already registered, just return ok. */
|
|
||||||
debug("USB KBD: is already registered.\n");
|
|
||||||
usb_kbd_deregister();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register the keyboard */
|
/* Register the keyboard */
|
||||||
debug("USB KBD: register.\n");
|
debug("USB KBD: register.\n");
|
||||||
memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
|
memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
|
||||||
@ -555,10 +547,14 @@ int drv_usb_kbd_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Deregister the keyboard. */
|
/* Deregister the keyboard. */
|
||||||
int usb_kbd_deregister(void)
|
int usb_kbd_deregister(int force)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
||||||
return stdio_deregister(DEVNAME);
|
int ret = stdio_deregister(DEVNAME, force);
|
||||||
|
if (ret && ret != -ENODEV)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -198,7 +198,7 @@ static int serial_pre_remove(struct udevice *dev)
|
|||||||
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
||||||
struct serial_dev_priv *upriv = dev->uclass_priv;
|
struct serial_dev_priv *upriv = dev->uclass_priv;
|
||||||
|
|
||||||
if (stdio_deregister_dev(upriv->sdev))
|
if (stdio_deregister_dev(upriv->sdev), 0)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -777,6 +777,11 @@ static int ci_pullup(struct usb_gadget *gadget, int is_on)
|
|||||||
/* select DEVICE mode */
|
/* select DEVICE mode */
|
||||||
writel(USBMODE_DEVICE, &udc->usbmode);
|
writel(USBMODE_DEVICE, &udc->usbmode);
|
||||||
|
|
||||||
|
#if !defined(CONFIG_USB_GADGET_DUALSPEED)
|
||||||
|
/* Port force Full-Speed Connect */
|
||||||
|
setbits_le32(&udc->portsc, PFSC);
|
||||||
|
#endif
|
||||||
|
|
||||||
writel(0xffffffff, &udc->epflush);
|
writel(0xffffffff, &udc->epflush);
|
||||||
|
|
||||||
/* Turn on the USB connection by enabling the pullup resistor */
|
/* Turn on the USB connection by enabling the pullup resistor */
|
||||||
|
@ -81,14 +81,6 @@ static struct usb_descriptor_header *dfu_runtime_descs[] = {
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct usb_qualifier_descriptor dev_qualifier = {
|
|
||||||
.bLength = sizeof dev_qualifier,
|
|
||||||
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
|
|
||||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
|
||||||
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
|
|
||||||
.bNumConfigurations = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char dfu_name[] = "Device Firmware Upgrade";
|
static const char dfu_name[] = "Device Firmware Upgrade";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -237,6 +229,7 @@ static inline void to_dfu_mode(struct f_dfu *f_dfu)
|
|||||||
{
|
{
|
||||||
f_dfu->usb_function.strings = dfu_strings;
|
f_dfu->usb_function.strings = dfu_strings;
|
||||||
f_dfu->usb_function.hs_descriptors = f_dfu->function;
|
f_dfu->usb_function.hs_descriptors = f_dfu->function;
|
||||||
|
f_dfu->usb_function.descriptors = f_dfu->function;
|
||||||
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
|
f_dfu->dfu_state = DFU_STATE_dfuIDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,6 +237,7 @@ static inline void to_runtime_mode(struct f_dfu *f_dfu)
|
|||||||
{
|
{
|
||||||
f_dfu->usb_function.strings = NULL;
|
f_dfu->usb_function.strings = NULL;
|
||||||
f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
|
f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
|
||||||
|
f_dfu->usb_function.descriptors = dfu_runtime_descs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_upload(struct usb_request *req, u16 len)
|
static int handle_upload(struct usb_request *req, u16 len)
|
||||||
@ -808,6 +802,7 @@ static int dfu_bind_config(struct usb_configuration *c)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
f_dfu->usb_function.name = "dfu";
|
f_dfu->usb_function.name = "dfu";
|
||||||
f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
|
f_dfu->usb_function.hs_descriptors = dfu_runtime_descs;
|
||||||
|
f_dfu->usb_function.descriptors = dfu_runtime_descs;
|
||||||
f_dfu->usb_function.bind = dfu_bind;
|
f_dfu->usb_function.bind = dfu_bind;
|
||||||
f_dfu->usb_function.unbind = dfu_unbind;
|
f_dfu->usb_function.unbind = dfu_unbind;
|
||||||
f_dfu->usb_function.set_alt = dfu_set_alt;
|
f_dfu->usb_function.set_alt = dfu_set_alt;
|
||||||
|
@ -351,10 +351,11 @@ static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
|
|||||||
strncat(response, FASTBOOT_VERSION, chars_left);
|
strncat(response, FASTBOOT_VERSION, chars_left);
|
||||||
} else if (!strcmp_l1("bootloader-version", cmd)) {
|
} else if (!strcmp_l1("bootloader-version", cmd)) {
|
||||||
strncat(response, U_BOOT_VERSION, chars_left);
|
strncat(response, U_BOOT_VERSION, chars_left);
|
||||||
} else if (!strcmp_l1("downloadsize", cmd)) {
|
} else if (!strcmp_l1("downloadsize", cmd) ||
|
||||||
|
!strcmp_l1("max-download-size", cmd)) {
|
||||||
char str_num[12];
|
char str_num[12];
|
||||||
|
|
||||||
sprintf(str_num, "%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
|
sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
|
||||||
strncat(response, str_num, chars_left);
|
strncat(response, str_num, chars_left);
|
||||||
} else if (!strcmp_l1("serialno", cmd)) {
|
} else if (!strcmp_l1("serialno", cmd)) {
|
||||||
s = getenv("serial#");
|
s = getenv("serial#");
|
||||||
@ -386,6 +387,7 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
|
|||||||
unsigned int transfer_size = download_size - download_bytes;
|
unsigned int transfer_size = download_size - download_bytes;
|
||||||
const unsigned char *buffer = req->buf;
|
const unsigned char *buffer = req->buf;
|
||||||
unsigned int buffer_size = req->actual;
|
unsigned int buffer_size = req->actual;
|
||||||
|
unsigned int pre_dot_num, now_dot_num;
|
||||||
|
|
||||||
if (req->status != 0) {
|
if (req->status != 0) {
|
||||||
printf("Bad status: %d\n", req->status);
|
printf("Bad status: %d\n", req->status);
|
||||||
@ -398,7 +400,15 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
|
|||||||
memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
|
memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
|
||||||
buffer, transfer_size);
|
buffer, transfer_size);
|
||||||
|
|
||||||
|
pre_dot_num = download_bytes / BYTES_PER_DOT;
|
||||||
download_bytes += transfer_size;
|
download_bytes += transfer_size;
|
||||||
|
now_dot_num = download_bytes / BYTES_PER_DOT;
|
||||||
|
|
||||||
|
if (pre_dot_num != now_dot_num) {
|
||||||
|
putc('.');
|
||||||
|
if (!(now_dot_num % 74))
|
||||||
|
putc('\n');
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if transfer is done */
|
/* Check if transfer is done */
|
||||||
if (download_bytes >= download_size) {
|
if (download_bytes >= download_size) {
|
||||||
@ -420,11 +430,6 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
|
|||||||
req->length = ep->maxpacket;
|
req->length = ep->maxpacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (download_bytes && !(download_bytes % BYTES_PER_DOT)) {
|
|
||||||
putc('.');
|
|
||||||
if (!(download_bytes % (74 * BYTES_PER_DOT)))
|
|
||||||
putc('\n');
|
|
||||||
}
|
|
||||||
req->actual = 0;
|
req->actual = 0;
|
||||||
usb_ep_queue(ep, req, 0);
|
usb_ep_queue(ep, req, 0);
|
||||||
}
|
}
|
||||||
@ -541,7 +546,14 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
|
|||||||
error("unknown command: %s\n", cmdbuf);
|
error("unknown command: %s\n", cmdbuf);
|
||||||
fastboot_tx_write_str("FAILunknown command");
|
fastboot_tx_write_str("FAILunknown command");
|
||||||
} else {
|
} else {
|
||||||
|
if (req->actual < req->length) {
|
||||||
|
u8 *buf = (u8 *)req->buf;
|
||||||
|
buf[req->actual] = 0;
|
||||||
func_cb(ep, req);
|
func_cb(ep, req);
|
||||||
|
} else {
|
||||||
|
error("buffer overflow\n");
|
||||||
|
fastboot_tx_write_str("FAILbuffer overflow");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (req->status == 0) {
|
if (req->status == 0) {
|
||||||
|
@ -1110,6 +1110,7 @@ static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
|
|||||||
|
|
||||||
memset(buf, 0, 8);
|
memset(buf, 0, 8);
|
||||||
buf[0] = TYPE_DISK;
|
buf[0] = TYPE_DISK;
|
||||||
|
buf[1] = curlun->removable ? 0x80 : 0;
|
||||||
buf[2] = 2; /* ANSI SCSI level 2 */
|
buf[2] = 2; /* ANSI SCSI level 2 */
|
||||||
buf[3] = 2; /* SCSI-2 INQUIRY data format */
|
buf[3] = 2; /* SCSI-2 INQUIRY data format */
|
||||||
buf[4] = 31; /* Additional length */
|
buf[4] = 31; /* Additional length */
|
||||||
|
@ -458,16 +458,6 @@ static struct usb_endpoint_descriptor hs_int_desc = {
|
|||||||
.bInterval = 0x9,
|
.bInterval = 0x9,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct usb_qualifier_descriptor dev_qualifier = {
|
|
||||||
.bLength = sizeof(dev_qualifier),
|
|
||||||
.bDescriptorType = USB_DT_DEVICE_QUALIFIER,
|
|
||||||
|
|
||||||
.bcdUSB = __constant_cpu_to_le16(0x0200),
|
|
||||||
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
|
|
||||||
|
|
||||||
.bNumConfigurations = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This attribute vendor descriptor is necessary for correct operation with
|
* This attribute vendor descriptor is necessary for correct operation with
|
||||||
* Windows version of THOR download program
|
* Windows version of THOR download program
|
||||||
|
@ -273,6 +273,29 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed)
|
|||||||
return QH_FULL_SPEED;
|
return QH_FULL_SPEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
|
||||||
|
struct QH *qh)
|
||||||
|
{
|
||||||
|
struct usb_device *ttdev;
|
||||||
|
|
||||||
|
if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For full / low speed devices we need to get the devnum and portnr of
|
||||||
|
* the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
|
||||||
|
* in the tree before that one!
|
||||||
|
*/
|
||||||
|
ttdev = dev;
|
||||||
|
while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
|
||||||
|
ttdev = ttdev->parent;
|
||||||
|
if (!ttdev->parent)
|
||||||
|
return;
|
||||||
|
|
||||||
|
qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
|
||||||
|
QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
||||||
int length, struct devrequest *req)
|
int length, struct devrequest *req)
|
||||||
@ -390,10 +413,9 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
|
|||||||
QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
|
QH_ENDPT1_ENDPT(usb_pipeendpoint(pipe)) | QH_ENDPT1_I(0) |
|
||||||
QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
|
QH_ENDPT1_DEVADDR(usb_pipedevice(pipe));
|
||||||
qh->qh_endpt1 = cpu_to_hc32(endpt);
|
qh->qh_endpt1 = cpu_to_hc32(endpt);
|
||||||
endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_PORTNUM(dev->portnr) |
|
endpt = QH_ENDPT2_MULT(1) | QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
|
||||||
QH_ENDPT2_HUBADDR(dev->parent->devnum) |
|
|
||||||
QH_ENDPT2_UFCMASK(0) | QH_ENDPT2_UFSMASK(0);
|
|
||||||
qh->qh_endpt2 = cpu_to_hc32(endpt);
|
qh->qh_endpt2 = cpu_to_hc32(endpt);
|
||||||
|
ehci_update_endpt2_dev_n_port(dev, qh);
|
||||||
qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
|
qh->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
|
||||||
qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
|
qh->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
|
||||||
|
|
||||||
@ -974,6 +996,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
|
|||||||
* Set up periodic list
|
* Set up periodic list
|
||||||
* Step 1: Parent QH for all periodic transfers.
|
* Step 1: Parent QH for all periodic transfers.
|
||||||
*/
|
*/
|
||||||
|
ehcic[index].periodic_schedules = 0;
|
||||||
periodic = &ehcic[index].periodic_queue;
|
periodic = &ehcic[index].periodic_queue;
|
||||||
memset(periodic, 0, sizeof(*periodic));
|
memset(periodic, 0, sizeof(*periodic));
|
||||||
periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
|
periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
|
||||||
@ -1132,8 +1155,6 @@ disable_periodic(struct ehci_ctrl *ctrl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int periodic_schedules;
|
|
||||||
|
|
||||||
struct int_queue *
|
struct int_queue *
|
||||||
create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
|
create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
|
||||||
int elementsize, void *buffer)
|
int elementsize, void *buffer)
|
||||||
@ -1201,12 +1222,10 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
|
|||||||
(1 << 0)); /* S-mask: microframe 0 */
|
(1 << 0)); /* S-mask: microframe 0 */
|
||||||
if (dev->speed == USB_SPEED_LOW ||
|
if (dev->speed == USB_SPEED_LOW ||
|
||||||
dev->speed == USB_SPEED_FULL) {
|
dev->speed == USB_SPEED_FULL) {
|
||||||
debug("TT: port: %d, hub address: %d\n",
|
/* C-mask: microframes 2-4 */
|
||||||
dev->portnr, dev->parent->devnum);
|
qh->qh_endpt2 |= cpu_to_hc32((0x1c << 8));
|
||||||
qh->qh_endpt2 |= cpu_to_hc32((dev->portnr << 23) |
|
|
||||||
(dev->parent->devnum << 16) |
|
|
||||||
(0x1c << 8)); /* C-mask: microframes 2-4 */
|
|
||||||
}
|
}
|
||||||
|
ehci_update_endpt2_dev_n_port(dev, qh);
|
||||||
|
|
||||||
td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
|
td->qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
|
||||||
td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
|
td->qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE);
|
||||||
@ -1258,7 +1277,7 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
|
|||||||
debug("FATAL: periodic should never fail, but did");
|
debug("FATAL: periodic should never fail, but did");
|
||||||
goto fail3;
|
goto fail3;
|
||||||
}
|
}
|
||||||
periodic_schedules++;
|
ctrl->periodic_schedules++;
|
||||||
|
|
||||||
debug("Exit create_int_queue\n");
|
debug("Exit create_int_queue\n");
|
||||||
return result;
|
return result;
|
||||||
@ -1277,6 +1296,7 @@ fail1:
|
|||||||
void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
|
void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
|
||||||
{
|
{
|
||||||
struct QH *cur = queue->current;
|
struct QH *cur = queue->current;
|
||||||
|
struct qTD *cur_td;
|
||||||
|
|
||||||
/* depleted queue */
|
/* depleted queue */
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
@ -1284,20 +1304,21 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* still active */
|
/* still active */
|
||||||
invalidate_dcache_range((uint32_t)cur,
|
cur_td = &queue->tds[queue->current - queue->first];
|
||||||
ALIGN_END_ADDR(struct QH, cur, 1));
|
invalidate_dcache_range((uint32_t)cur_td,
|
||||||
if (cur->qh_overlay.qt_token & cpu_to_hc32(0x80)) {
|
ALIGN_END_ADDR(struct qTD, cur_td, 1));
|
||||||
debug("Exit poll_int_queue with no completed intr transfer. "
|
if (QT_TOKEN_GET_STATUS(hc32_to_cpu(cur_td->qt_token)) &
|
||||||
"token is %x\n", cur->qh_overlay.qt_token);
|
QT_TOKEN_STATUS_ACTIVE) {
|
||||||
|
debug("Exit poll_int_queue with no completed intr transfer. token is %x\n",
|
||||||
|
hc32_to_cpu(cur_td->qt_token));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(cur->qh_link & QH_LINK_TERMINATE))
|
if (!(cur->qh_link & QH_LINK_TERMINATE))
|
||||||
queue->current++;
|
queue->current++;
|
||||||
else
|
else
|
||||||
queue->current = NULL;
|
queue->current = NULL;
|
||||||
debug("Exit poll_int_queue with completed intr transfer. "
|
debug("Exit poll_int_queue with completed intr transfer. token is %x at %p (first at %p)\n",
|
||||||
"token is %x at %p (first at %p)\n", cur->qh_overlay.qt_token,
|
hc32_to_cpu(cur_td->qt_token), cur, queue->first);
|
||||||
&cur->qh_overlay.qt_token, queue->first);
|
|
||||||
return cur->buffer;
|
return cur->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1313,7 +1334,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
|
|||||||
debug("FATAL: periodic should never fail, but did");
|
debug("FATAL: periodic should never fail, but did");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
periodic_schedules--;
|
ctrl->periodic_schedules--;
|
||||||
|
|
||||||
struct QH *cur = &ctrl->periodic_queue;
|
struct QH *cur = &ctrl->periodic_queue;
|
||||||
timeout = get_timer(0) + 500; /* abort after 500ms */
|
timeout = get_timer(0) + 500; /* abort after 500ms */
|
||||||
@ -1322,6 +1343,8 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
|
|||||||
if (NEXT_QH(cur) == queue->first) {
|
if (NEXT_QH(cur) == queue->first) {
|
||||||
debug("found candidate. removing from chain\n");
|
debug("found candidate. removing from chain\n");
|
||||||
cur->qh_link = queue->last->qh_link;
|
cur->qh_link = queue->last->qh_link;
|
||||||
|
flush_dcache_range((uint32_t)cur,
|
||||||
|
ALIGN_END_ADDR(struct QH, cur, 1));
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1333,7 +1356,7 @@ destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (periodic_schedules > 0) {
|
if (ctrl->periodic_schedules > 0) {
|
||||||
result = enable_periodic(ctrl);
|
result = enable_periodic(ctrl);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
debug("FATAL: periodic should never fail, but did");
|
debug("FATAL: periodic should never fail, but did");
|
||||||
|
@ -305,11 +305,11 @@ static void init_phy_mux(struct fdt_usb *config, uint pts,
|
|||||||
#if defined(CONFIG_TEGRA20)
|
#if defined(CONFIG_TEGRA20)
|
||||||
if (config->periph_id == PERIPH_ID_USBD) {
|
if (config->periph_id == PERIPH_ID_USBD) {
|
||||||
clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
|
clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK,
|
||||||
PTS_UTMI << PTS1_SHIFT);
|
pts << PTS1_SHIFT);
|
||||||
clrbits_le32(&usbctlr->port_sc1, STS1);
|
clrbits_le32(&usbctlr->port_sc1, STS1);
|
||||||
} else {
|
} else {
|
||||||
clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
|
clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
|
||||||
PTS_UTMI << PTS_SHIFT);
|
pts << PTS_SHIFT);
|
||||||
clrbits_le32(&usbctlr->port_sc1, STS);
|
clrbits_le32(&usbctlr->port_sc1, STS);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -246,6 +246,7 @@ struct ehci_ctrl {
|
|||||||
struct QH qh_list __aligned(USB_DMA_MINALIGN);
|
struct QH qh_list __aligned(USB_DMA_MINALIGN);
|
||||||
struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
|
struct QH periodic_queue __aligned(USB_DMA_MINALIGN);
|
||||||
uint32_t *periodic_list;
|
uint32_t *periodic_list;
|
||||||
|
int periodic_schedules;
|
||||||
int ntds;
|
int ntds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -942,9 +942,7 @@ void musb_start(struct musb *musb)
|
|||||||
|
|
||||||
/* put into basic highspeed mode and start session */
|
/* put into basic highspeed mode and start session */
|
||||||
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
|
musb_writeb(regs, MUSB_POWER, MUSB_POWER_ISOUPDATE
|
||||||
#ifdef CONFIG_USB_GADGET_DUALSPEED
|
|
||||||
| MUSB_POWER_HSENAB
|
| MUSB_POWER_HSENAB
|
||||||
#endif
|
|
||||||
/* ENSUSPEND wedges tusb */
|
/* ENSUSPEND wedges tusb */
|
||||||
/* | MUSB_POWER_ENSUSPEND */
|
/* | MUSB_POWER_ENSUSPEND */
|
||||||
);
|
);
|
||||||
|
@ -231,7 +231,7 @@
|
|||||||
#define CONFIG_MUSB_GADGET
|
#define CONFIG_MUSB_GADGET
|
||||||
#define CONFIG_MUSB_PIO_ONLY
|
#define CONFIG_MUSB_PIO_ONLY
|
||||||
#define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
|
#define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
|
||||||
#define CONFIG_USB_GADGET_DUALSPEED
|
#undef CONFIG_USB_GADGET_DUALSPEED
|
||||||
#define CONFIG_USB_GADGET_VBUS_DRAW 2
|
#define CONFIG_USB_GADGET_VBUS_DRAW 2
|
||||||
#define CONFIG_MUSB_HOST
|
#define CONFIG_MUSB_HOST
|
||||||
|
|
||||||
|
@ -103,8 +103,8 @@ int stdio_init(void);
|
|||||||
|
|
||||||
void stdio_print_current_devices(void);
|
void stdio_print_current_devices(void);
|
||||||
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
#ifdef CONFIG_SYS_STDIO_DEREGISTER
|
||||||
int stdio_deregister(const char *devname);
|
int stdio_deregister(const char *devname, int force);
|
||||||
int stdio_deregister_dev(struct stdio_dev *dev);
|
int stdio_deregister_dev(struct stdio_dev *dev, int force);
|
||||||
#endif
|
#endif
|
||||||
struct list_head* stdio_get_list(void);
|
struct list_head* stdio_get_list(void);
|
||||||
struct stdio_dev* stdio_get_by_name(const char* name);
|
struct stdio_dev* stdio_get_by_name(const char* name);
|
||||||
|
@ -216,7 +216,7 @@ int usb_host_eth_scan(int mode);
|
|||||||
#ifdef CONFIG_USB_KEYBOARD
|
#ifdef CONFIG_USB_KEYBOARD
|
||||||
|
|
||||||
int drv_usb_kbd_init(void);
|
int drv_usb_kbd_init(void);
|
||||||
int usb_kbd_deregister(void);
|
int usb_kbd_deregister(int force);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/* routines */
|
/* routines */
|
||||||
|
Loading…
Reference in New Issue
Block a user