From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vivek Gautam Date: Tue, 24 Jun 2014 19:40:22 +0530 Subject: [U-Boot] [PATCH 2/2] RFC: usb: host: Introduce host translational layer In-Reply-To: <1403619022-15662-1-git-send-email-gautam.vivek@samsung.com> References: <1403619022-15662-1-git-send-email-gautam.vivek@samsung.com> Message-ID: <1403619022-15662-3-git-send-email-gautam.vivek@samsung.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Introduce a wrapper layer to translate submit_**_msg() APIs as well as usb_lowlevel_**() APIs so as to enable using mutiple controller types viz. OHCI/EHCI/XHCI. This is still WIP, with support for APIs translation for EHCI and XHCI only. Signed-off-by: Vivek Gautam --- common/usb.c | 8 ++-- drivers/usb/host/Makefile | 2 + drivers/usb/host/ehci-hcd.c | 15 +++--- drivers/usb/host/host_trans.c | 102 +++++++++++++++++++++++++++++++++++++++++ drivers/usb/host/host_trans.h | 42 +++++++++++++++++ drivers/usb/host/xhci.c | 11 +++-- include/usb.h | 15 +++--- 7 files changed, 174 insertions(+), 21 deletions(-) create mode 100644 drivers/usb/host/host_trans.c create mode 100644 drivers/usb/host/host_trans.h diff --git a/common/usb.c b/common/usb.c index 5dd09aa..ae483d0 100644 --- a/common/usb.c +++ b/common/usb.c @@ -58,6 +58,7 @@ char usb_started; /* flag for the started/stopped USB status */ int usb_init(void) { void *ctrl; + int ctrl_type; struct usb_device *dev; int i, start_index = 0; @@ -75,7 +76,7 @@ int usb_init(void) for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { /* init low_level USB */ printf("USB%d: ", i); - if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) { + if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl, &ctrl_type)) { puts("lowlevel init failed\n"); continue; } @@ -86,6 +87,7 @@ int usb_init(void) start_index = dev_index; printf("scanning bus %d for devices... ", i); dev = usb_alloc_new_device(ctrl); + dev->ctrl_type = ctrl_type; /* * device 0 is always present * (root hub, so let it analyze) @@ -193,7 +195,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, request, requesttype, value, index, size); dev->status = USB_ST_NOT_PROC; /*not yet processed */ - if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0) + if (usb_submit_control_msg(dev, pipe, data, size, setup_packet) < 0) return -1; if (timeout == 0) return (int)size; @@ -226,7 +228,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, if (len < 0) return -1; dev->status = USB_ST_NOT_PROC; /*not yet processed */ - if (submit_bulk_msg(dev, pipe, data, len) < 0) + if (usb_submit_bulk_msg(dev, pipe, data, len) < 0) return -1; while (timeout--) { if (!((volatile unsigned long)dev->status & USB_ST_NOT_PROC)) diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 7211c6a..9c6eb84 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -43,3 +43,5 @@ obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o + +obj-$(CONFIG_USB_HOST_TRANS) += host_trans.o diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index eaf5913..460c509 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -31,6 +31,7 @@ #include #include "ehci.h" +#include "host_trans.h" #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 @@ -917,13 +918,13 @@ unknown: return -1; } -int usb_lowlevel_stop(int index) +int ehci_lowlevel_stop(int index) { ehci_shutdown(&ehcic[index]); return ehci_hcd_stop(index); } -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +int ehci_lowlevel_init(int index, enum usb_init_type init, void **controller) { uint32_t reg; uint32_t cmd; @@ -1052,8 +1053,8 @@ done: } int -submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int length) +ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length) { if (usb_pipetype(pipe) != PIPE_BULK) { @@ -1064,8 +1065,8 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, } int -submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int length, struct devrequest *setup) +ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, struct devrequest *setup) { struct ehci_ctrl *ctrl = dev->controller; @@ -1348,7 +1349,7 @@ out: } int -submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, +ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int length, int interval) { void *backbuffer; diff --git a/drivers/usb/host/host_trans.c b/drivers/usb/host/host_trans.c new file mode 100644 index 0000000..701faa2 --- /dev/null +++ b/drivers/usb/host/host_trans.c @@ -0,0 +1,102 @@ +/* + * USB HOST Controller translation layer + * + * Provides a smooth translation from usb_*() APIs from + * core usb drivers to controller drivers, enabling simultaneous + * use of different types of controller at once. + * + * Copyright (C) 2014 Samsung Electronics Co.Ltd + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "host_trans.h" + +static int ehci_count; +static int xhci_count; + +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller, + int *ctrl_type) +{ + if (index >= CONFIG_USB_MAX_CONTROLLER_COUNT) + return 0; + + /* first enumerate available EHCI controllers */ + if (ehci_count < CONFIG_USB_MAX_EHCI_COUNT) { + if (ehci_lowlevel_init) { + ehci_count++; + *ctrl_type = USB_HOST_EHCI; + /* init max number of ehci controllers */ + return ehci_lowlevel_init(ehci_count, init, controller); + } + } + + if (xhci_count < CONFIG_USB_MAX_XHCI_COUNT) { + if (xhci_lowlevel_init) { + xhci_count++; + *ctrl_type = USB_HOST_XHCI; + /* init max number of xhci controllers */ + return xhci_lowlevel_init(index, init, controller); + } + } + + return -1; +} + +int usb_lowlevel_stop(int index) +{ + if (index >= CONFIG_USB_MAX_CONTROLLER_COUNT) + return 0; + + ehci_count = xhci_count = 0; + + if (ehci_count < CONFIG_USB_MAX_EHCI_COUNT) { + if (ehci_lowlevel_init) { + ehci_count++; + return ehci_lowlevel_stop(index); + } + } + + if (xhci_count < CONFIG_USB_MAX_XHCI_COUNT) { + if (xhci_lowlevel_init) { + xhci_count++; + return xhci_lowlevel_stop(index); + } + } + + return -1; +} + +int usb_submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len) +{ + if (dev->ctrl_type == USB_HOST_EHCI) + return ehci_submit_bulk_msg(dev, pipe, buffer, transfer_len); + + if (dev->ctrl_type == USB_HOST_XHCI) + return xhci_submit_bulk_msg(dev, pipe, buffer, transfer_len); +} + +int usb_submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, struct devrequest *setup) +{ + if (dev->ctrl_type == USB_HOST_EHCI) + return ehci_submit_control_msg(dev, pipe, buffer, + transfer_len, setup); + + if (dev->ctrl_type == USB_HOST_EHCI) + return xhci_submit_control_msg(dev, pipe, buffer, + transfer_len, setup); +} + +int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int transfer_len, int interval) +{ + if (dev->ctrl_type == USB_HOST_EHCI) + return ehci_submit_int_msg(dev, pipe, buffer, + transfer_len, interval); + + if (dev->ctrl_type == USB_HOST_XHCI) + return xhci_submit_int_msg(dev, pipe, buffer, + transfer_len, interval); +} diff --git a/drivers/usb/host/host_trans.h b/drivers/usb/host/host_trans.h new file mode 100644 index 0000000..90bcc92 --- /dev/null +++ b/drivers/usb/host/host_trans.h @@ -0,0 +1,42 @@ + +#ifndef _HOST_TRANS_H_ +#define _HOST_TRANS_H_ + +#include +#include +#include + +#ifndef CONFIG_USB_MAX_EHCI_COUNT +#define CONFIG_USB_MAX_EHCI_COUNT 1 +#endif + +#ifndef CONFIG_USB_MAX_XHCI_COUNT +#define CONFIG_USB_MAX_XHCI_COUNT 1 +#endif + +enum usb_ctrl_type { + USB_HOST_OHCI, + USB_HOST_UHCI, + USB_HOST_EHCI, + USB_HOST_XHCI, +}; + +int ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, int interval); +int ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length); +int ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int length, struct devrequest *setup); +int ehci_lowlevel_init(int index, enum usb_init_type init, void **controller); +int ehci_lowlevel_stop(int index); + +int xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length, int interval); +int xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length); +int xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, + void *buffer, int length, struct devrequest *setup); +int xhci_lowlevel_init(int index, enum usb_init_type init, void **controller); +int xhci_lowlevel_stop(int index); + +#endif /* _HOST_TRANS_H_ */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d1c2e5c..2e7e3f0 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -29,6 +29,7 @@ #include #include #include "xhci.h" +#include "host_trans.h" #ifndef CONFIG_USB_MAX_CONTROLLER_COUNT #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 @@ -859,7 +860,7 @@ unknown: * @return 0 */ int -submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, +xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length, int interval) { /* @@ -879,7 +880,7 @@ submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer, * @return returns 0 if successful else -1 on failure */ int -submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, +xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length) { if (usb_pipetype(pipe) != PIPE_BULK) { @@ -901,7 +902,7 @@ submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer, * @return returns 0 if successful else -1 on failure */ int -submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, +xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, int length, struct devrequest *setup) { struct xhci_ctrl *ctrl = udev->controller; @@ -936,7 +937,7 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer, * @param index index to the host controller data structure * @return pointer to the intialised controller */ -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) +int xhci_lowlevel_init(int index, enum usb_init_type init, void **controller) { uint32_t val; uint32_t val2; @@ -1009,7 +1010,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) * @param index index to the host controller data structure * @return none */ -int usb_lowlevel_stop(int index) +int xhci_lowlevel_stop(int index) { struct xhci_ctrl *ctrl = (xhcic + index); u32 temp; diff --git a/include/usb.h b/include/usb.h index 30fc890..212a34d 100644 --- a/include/usb.h +++ b/include/usb.h @@ -125,6 +125,7 @@ struct usb_device { struct usb_device *children[USB_MAXCHILDREN]; void *controller; /* hardware controller private data */ + int ctrl_type; /* controller type - OHCI/EHCI/XHCI */ /* slot_id - for xHCI enabled devices */ unsigned int slot_id; }; @@ -152,15 +153,17 @@ enum usb_init_type { defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \ defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) -int usb_lowlevel_init(int index, enum usb_init_type init, void **controller); +int usb_lowlevel_init(int index, enum usb_init_type init, void **controller, + int *ctrl_type); int usb_lowlevel_stop(int index); -int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, +int usb_submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len); -int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, struct devrequest *setup); -int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, - int transfer_len, int interval); +int usb_submit_control_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, + struct devrequest *setup); +int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, + void *buffer, int transfer_len, int interval); /* Defines */ #define USB_UHCI_VEND_ID 0x8086 -- 1.7.10.4