public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
@ 2008-06-23 11:24 Tor Krill
  2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
  To: u-boot

Add high speed support to USB code. Extracted from Juniper Networks patch.

I know that the mergewindow is closed but wanted to get feedback on these
patches if possible.

Signed-off-by: Tor Krill <tor@excito.com>
---
 common/cmd_usb.c   |    3 ++-
 common/usb.c       |   30 +++++++++++++++++++++++++-----
 include/usb.h      |   16 +++++++++-------
 include/usb_defs.h |   10 ++++++++++
 4 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 9be86b8..03282f6 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -276,7 +276,8 @@ void usb_show_tree_graph(struct usb_device *dev,char *pre)
 	pre[index++]= has_child ? '|' : ' ';
 	pre[index]=0;
 	printf(" %s (%s, %dmA)\n",usb_get_class_desc(dev->config.if_desc[0].bInterfaceClass),
-		dev->slow ? "1.5MBit/s" : "12MBit/s",dev->config.MaxPower * 2);
+		(dev->speed == USB_SPEED_LOW) ? "1.5MBit/s" : (dev->speed == USB_SPEED_FULL)
+		? "12MBit/s" : "480MBit/s", dev->config.MaxPower * 2);
 	if (strlen(dev->mf) ||
 	   strlen(dev->prod) ||
 	   strlen(dev->serial))
diff --git a/common/usb.c b/common/usb.c
index a0107dc..44f35bc 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -793,6 +793,11 @@ int usb_new_device(struct usb_device *dev)
 		case 16: dev->maxpacketsize = 1; break;
 		case 32: dev->maxpacketsize = 2; break;
 		case 64: dev->maxpacketsize = 3; break;
+		case 512: dev->maxpacketsize = 6; break;
+		default:
+			printf("XXX bMaxPacketSize0 unsupported (%u)\n",
+			    dev->descriptor.bMaxPacketSize0);
+			break;
 	}
 	dev->devnum = addr;
 
@@ -981,8 +986,10 @@ static int hub_port_reset(struct usb_device *dev, int port,
 		}
 		portstatus = le16_to_cpu(portsts.wPortStatus);
 		portchange = le16_to_cpu(portsts.wPortChange);
-		USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus ,portchange,
-			portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+		USB_HUB_PRINTF("portstatus %x, change %x, %s Speed\n", portstatus ,portchange,
+			portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low" :
+			portstatus&(1<<USB_PORT_FEAT_HIGHSPEED) ?  "High" :
+			"Full");
 		USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d  USB_PORT_STAT_ENABLE %d\n",
 			(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0,
 			(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0,
@@ -1026,8 +1033,10 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 
 	portstatus = le16_to_cpu(portsts.wPortStatus);
 	portchange = le16_to_cpu(portsts.wPortChange);
-	USB_HUB_PRINTF("portstatus %x, change %x, %s\n", portstatus, portchange,
-		portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low Speed" : "High Speed");
+	USB_HUB_PRINTF("portstatus %x, change %x, %s Speed\n", portstatus, portchange,
+		portstatus&(1<<USB_PORT_FEAT_LOWSPEED) ? "Low" :
+		portstatus&(1<<USB_PORT_FEAT_HIGHSPEED) ?  "High" :
+		"Full");
 
 	/* Clear the connection change status */
 	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION);
@@ -1052,10 +1061,21 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 
 	/* Allocate a new device struct for it */
 	usb=usb_alloc_new_device();
-	usb->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ? 1 : 0;
+	switch (portstatus & USB_PORT_STAT_SPEED) {
+	case 0:
+		usb->speed = USB_SPEED_FULL;
+		break;
+	case USB_PORT_STAT_LOW_SPEED:
+		usb->speed = USB_SPEED_LOW;
+		break;
+	case USB_PORT_STAT_HIGH_SPEED:
+		usb->speed = USB_SPEED_HIGH;
+		break;
+	}
 
 	dev->children[port] = usb;
 	usb->parent=dev;
+	usb->portnr = port + 1;
 	/* Run it through the hoops (find a driver, etc) */
 	if (usb_new_device(usb)) {
 		/* Woops, disable the port */
diff --git a/include/usb.h b/include/usb.h
index 5a6ffdd..410f9cf 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -132,7 +132,7 @@ struct usb_config_descriptor {
 
 struct usb_device {
 	int devnum;			/* Device number on USB bus */
-	int slow;			/* Slow device? */
+	int speed;			/* full/low/high */
 	char mf[32];			/* manufacturer */
 	char prod[32];			/* product */
 	char serial[32];		/* serial number */
@@ -161,6 +161,7 @@ struct usb_device {
 	unsigned long status;
 	int act_len;			/* transfered bytes */
 	int maxchild;			/* Number of ports if hub */
+	int portnr;
 	struct usb_device *parent;
 	struct usb_device *children[USB_MAXCHILDREN];
 };
@@ -171,7 +172,7 @@ struct usb_device {
 
 #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || \
 	defined(CONFIG_USB_OHCI_NEW) || defined (CONFIG_USB_SL811HS) || \
-	defined(CONFIG_USB_ISP116X_HCD)
+	defined(CONFIG_USB_ISP116X_HCD) || defined (CONFIG_USB_EHCI)
 
 int usb_lowlevel_init(void);
 int usb_lowlevel_stop(void);
@@ -264,7 +265,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  *  - endpoint number (4 bits)
  *  - current Data0/1 state (1 bit)
  *  - direction (1 bit)
- *  - speed (1 bit)
+ *  - speed (2 bits)
  *  - max packet size (2 bits: 8, 16, 32 or 64)
  *  - pipe type (2 bits: control, interrupt, bulk, isochronous)
  *
@@ -280,7 +281,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  *  - device:		bits 8-14
  *  - endpoint:		bits 15-18
  *  - Data0/1:		bit 19
- *  - speed:		bit 26		(0 = Full, 1 = Low Speed)
+ *  - speed:		bits 26-27	(0 = Full, 1 = Low, 2 = High)
  *  - pipe type:	bits 30-31	(00 = isochronous, 01 = interrupt, 10 = control, 11 = bulk)
  *
  * Why? Because it's arbitrary, and whatever encoding we select is really
@@ -290,8 +291,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
  */
 /* Create various pipes... */
 #define create_pipe(dev,endpoint) \
-		(((dev)->devnum << 8) | (endpoint << 15) | ((dev)->slow << 26) | (dev)->maxpacketsize)
-#define default_pipe(dev) ((dev)->slow <<26)
+		(((dev)->devnum << 8) | (endpoint << 15) | ((dev)->speed << 26) | (dev)->maxpacketsize)
+#define default_pipe(dev) ((dev)->speed << 26)
 
 #define usb_sndctrlpipe(dev,endpoint)	((PIPE_CONTROL << 30) | create_pipe(dev,endpoint))
 #define usb_rcvctrlpipe(dev,endpoint)	((PIPE_CONTROL << 30) | create_pipe(dev,endpoint) | USB_DIR_IN)
@@ -323,7 +324,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
 #define usb_pipe_endpdev(pipe)	(((pipe) >> 8) & 0x7ff)
 #define usb_pipeendpoint(pipe)	(((pipe) >> 15) & 0xf)
 #define usb_pipedata(pipe)	(((pipe) >> 19) & 1)
-#define usb_pipeslow(pipe)	(((pipe) >> 26) & 1)
+#define usb_pipespeed(pipe)	(((pipe) >> 26) & 3)
+#define usb_pipeslow(pipe)	(usb_pipespeed(pipe) == USB_SPEED_LOW)
 #define usb_pipetype(pipe)	(((pipe) >> 30) & 3)
 #define usb_pipeisoc(pipe)	(usb_pipetype((pipe)) == PIPE_ISOCHRONOUS)
 #define usb_pipeint(pipe)	(usb_pipetype((pipe)) == PIPE_INTERRUPT)
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 353019f..8032e57 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -80,6 +80,12 @@
 #define USB_DIR_OUT           0
 #define USB_DIR_IN            0x80
 
+/* USB device speeds */
+#define USB_SPEED_FULL		0x0	/* 12Mbps */
+#define USB_SPEED_LOW		0x1	/* 1.5Mbps */
+#define USB_SPEED_HIGH		0x2	/* 480Mbps */
+#define USB_SPEED_RESERVED	0x3
+
 /* Descriptor types */
 #define USB_DT_DEVICE        0x01
 #define USB_DT_CONFIG        0x02
@@ -202,6 +208,7 @@
 #define USB_PORT_FEAT_RESET          4
 #define USB_PORT_FEAT_POWER          8
 #define USB_PORT_FEAT_LOWSPEED       9
+#define USB_PORT_FEAT_HIGHSPEED      10
 #define USB_PORT_FEAT_C_CONNECTION   16
 #define USB_PORT_FEAT_C_ENABLE       17
 #define USB_PORT_FEAT_C_SUSPEND      18
@@ -216,6 +223,9 @@
 #define USB_PORT_STAT_RESET         0x0010
 #define USB_PORT_STAT_POWER         0x0100
 #define USB_PORT_STAT_LOW_SPEED     0x0200
+#define USB_PORT_STAT_HIGH_SPEED    0x0400	/* support for EHCI */
+#define USB_PORT_STAT_SPEED	\
+	(USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED)
 
 /* wPortChange bits */
 #define USB_PORT_STAT_C_CONNECTION  0x0001
-- 
1.5.6

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality
  2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
@ 2008-06-23 11:24 ` Tor Krill
  2008-06-23 11:24   ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
                     ` (2 more replies)
  2008-07-07  7:21 ` [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Markus Klotzbücher
  2008-07-10 15:00 ` Markus Klotzbücher
  2 siblings, 3 replies; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
  To: u-boot

Add basic functionality for ehci bulk and control messages

Signed-off-by: Tor Krill <tor@excito.com>
---
 drivers/usb/Makefile        |    3 +
 drivers/usb/usb_ehci.h      |  106 +++++++
 drivers/usb/usb_ehci_core.c |  633 +++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/usb_ehci_core.h |   29 ++
 4 files changed, 771 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/usb_ehci.h
 create mode 100644 drivers/usb/usb_ehci_core.c
 create mode 100644 drivers/usb/usb_ehci_core.h

diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 252b00e..838c52c 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -32,6 +32,9 @@ COBJS-y += usbdcore.o
 COBJS-y += usbdcore_ep0.o
 COBJS-y += usbdcore_mpc8xx.o
 COBJS-y += usbdcore_omap1510.o
+COBJS-$(CONFIG_USB_EHCI) += usb_ehci_core.o
+COBJS-$(CONFIG_USB_EHCI_FSL) += usb_ehci_fsl.o
+COBJS-$(CONFIG_USB_EHCI_PCI) += usb_ehci_pci.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/usb/usb_ehci.h b/drivers/usb/usb_ehci.h
new file mode 100644
index 0000000..0695038
--- /dev/null
+++ b/drivers/usb/usb_ehci.h
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef USB_EHCI_H
+#define USB_EHCI_H
+
+/*
+ * Register Space.
+ */
+struct ehci_hccr {
+	uint8_t cr_caplength;
+	uint16_t cr_hciversion;
+	uint32_t cr_hcsparams;
+	uint32_t cr_hccparams;
+	uint8_t cr_hcsp_portrt[8];
+};
+
+struct ehci_hcor {
+	uint32_t or_usbcmd;
+	uint32_t or_usbsts;
+	uint32_t or_usbintr;
+	uint32_t or_frindex;
+	uint32_t or_ctrldssegment;
+	uint32_t or_periodiclistbase;
+	uint32_t or_asynclistaddr;
+	uint32_t _reserved_[9];
+	uint32_t or_configflag;
+	uint32_t or_portsc[2];
+	uint32_t or_systune;
+};
+
+#define EHCI_PS_WKOC_E		0x00400000	/* RW wake on over current */
+#define EHCI_PS_WKDSCNNT_E	0x00200000	/* RW wake on disconnect */
+#define EHCI_PS_WKCNNT_E	0x00100000	/* RW wake on connect */
+#define EHCI_PS_PTC		0x000f0000	/* RW port test control */
+#define EHCI_PS_PIC		0x0000c000	/* RW port indicator control */
+#define EHCI_PS_PO		0x00002000	/* RW port owner */
+#define EHCI_PS_PP		0x00001000	/* RW,RO port power */
+#define EHCI_PS_LS		0x00000c00	/* RO line status */
+#define EHCI_PS_IS_LOWSPEED(x) (((x) & EHCI_PS_LS) == 0x00000400)
+#define EHCI_PS_PR		0x00000100	/* RW port reset */
+#define EHCI_PS_SUSP		0x00000080	/* RW suspend */
+#define EHCI_PS_FPR		0x00000040	/* RW force port resume */
+#define EHCI_PS_OCC		0x00000020	/* RWC over current change */
+#define EHCI_PS_OCA		0x00000010	/* RO over current active */
+#define EHCI_PS_PEC		0x00000008	/* RWC port enable change */
+#define EHCI_PS_PE		0x00000004	/* RW port enable */
+#define EHCI_PS_CSC		0x00000002	/* RWC connect status change */
+#define EHCI_PS_CS		0x00000001	/* RO connect status */
+#define EHCI_PS_CLEAR		(EHCI_PS_OCC|EHCI_PS_PEC|EHCI_PS_CSC)
+
+/*
+ * Schedule Interface Space.
+ *
+ * IMPORTANT: Software must ensure that no interface data structure
+ * reachable by the EHCI host controller spans a 4K page boundary!
+ *
+ * Periodic transfers (i.e. isochronous and interrupt transfers) are
+ * not supported.
+ */
+
+/* Queue Element Transfer Descriptor (qTD). */
+struct qTD {
+	uint32_t qt_next;
+#define	QT_NEXT_TERMINATE	1
+	uint32_t qt_altnext;
+	uint32_t qt_token;
+	uint32_t qt_buffer[5];
+};
+
+/* Queue Head (QH). */
+struct QH {
+	uint32_t qh_link;
+#define	QH_LINK_TERMINATE	1
+#define	QH_LINK_TYPE_ITD	0
+#define	QH_LINK_TYPE_QH		2
+#define	QH_LINK_TYPE_SITD	4
+#define	QH_LINK_TYPE_FSTN	6
+	uint32_t qh_endpt1;
+	uint32_t qh_endpt2;
+	uint32_t qh_curtd;
+	struct qTD qh_overlay;
+};
+
+/* Low level intit functions */
+
+int ehci_hcd_init (void);
+int ehci_hcd_stop (void);
+#endif /* USB_EHCI_H */
diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c
new file mode 100644
index 0000000..dfffb01
--- /dev/null
+++ b/drivers/usb/usb_ehci_core.c
@@ -0,0 +1,633 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * Copyright (c) 2008, Excito Elektronik i Sk?ne AB
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <usb.h>
+#include <asm/io.h>
+#include "usb_ehci.h"
+
+int rootdev;
+struct ehci_hccr *hccr;		/* R/O registers, not need for volatile */
+volatile struct ehci_hcor *hcor;
+
+static uint16_t portreset;
+static struct QH qh_list __attribute__ ((aligned (32)));
+
+static struct {
+	uint8_t hub[8];
+	uint8_t device[18];
+	uint8_t config[9];
+	uint8_t interface[9];
+	uint8_t endpoint[7];
+} descr = {
+	{			/* HUB */
+		sizeof (descr.hub),	/* bDescLength */
+		    0x29,	/* bDescriptorType: hub descriptor */
+		    2,		/* bNrPorts -- runtime modified */
+		    0, 0,	/* wHubCharacteristics -- runtime modified */
+		    0xff,	/* bPwrOn2PwrGood */
+		    0,		/* bHubCntrCurrent */
+		    0		/* DeviceRemovable XXX at most 7 ports! XXX */
+	}
+	, {			/* DEVICE */
+		sizeof (descr.device),	/* bLength */
+		    1,		/* bDescriptorType: UDESC_DEVICE */
+		    0x00, 0x02,	/* bcdUSB: v2.0 */
+		    9,		/* bDeviceClass: UDCLASS_HUB */
+		    0,		/* bDeviceSubClass: UDSUBCLASS_HUB */
+		    1,		/* bDeviceProtocol: UDPROTO_HSHUBSTT */
+		    64,		/* bMaxPacketSize: 64 bytes */
+		    0x00, 0x00,	/* idVendor */
+		    0x00, 0x00,	/* idProduct */
+		    0x00, 0x01,	/* bcdDevice */
+		    1,		/* iManufacturer */
+		    2,		/* iProduct */
+		    0,		/* iSerialNumber */
+		    1		/* bNumConfigurations: 1 */
+	}
+	, {			/* CONFIG */
+		sizeof (descr.config),	/* bLength */
+		    2,		/* bDescriptorType: UDESC_CONFIG */
+		    sizeof (descr.config) + sizeof (descr.interface) +
+		    sizeof (descr.endpoint), 0,
+		    /* wTotalLength */
+		    1,		/* bNumInterface */
+		    1,		/* bConfigurationValue */
+		    0,		/* iConfiguration */
+		    0x40,	/* bmAttributes: UC_SELF_POWERED */
+		    0		/* bMaxPower */
+	}
+	, {			/* INTERFACE */
+		sizeof (descr.interface),	/* bLength */
+		    4,		/* bDescriptorType: UDESC_INTERFACE */
+		    0,		/* bInterfaceNumber */
+		    0,		/* bAlternateSetting */
+		    1,		/* bNumEndpoints */
+		    9,		/* bInterfaceClass: UICLASS_HUB */
+		    0,		/* bInterfaceSubClass: UISUBCLASS_HUB */
+		    0,		/* bInterfaceProtocol: UIPROTO_HSHUBSTT */
+		    0		/* iInterface */
+	}
+	, {			/* ENDPOINT */
+		sizeof (descr.endpoint),	/* bLength */
+		    5,		/* bDescriptorType: UDESC_ENDPOINT */
+		    0x81,	/* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
+		    3,		/* bmAttributes: UE_INTERRUPT */
+		    8, 0,	/* wMaxPacketSize */
+		    255		/* bInterval */
+	}
+};
+
+static void *ehci_alloc (size_t sz, size_t align)
+{
+	static struct QH qh __attribute__ ((aligned (32)));
+	static struct qTD td[3] __attribute__ ((aligned (32)));
+	static int ntds = 0;
+	void *p;
+
+	switch (sz) {
+	case sizeof (struct QH):
+		p = &qh;
+		ntds = 0;
+		break;
+	case sizeof (struct qTD):
+		if (ntds == 3) {
+			debug ("out of TDs");
+			return (NULL);
+		}
+		p = &td[ntds];
+		ntds++;
+		break;
+	default:
+		debug ("unknown allocation size");
+		return (NULL);
+	}
+
+	memset (p, sz, 0);
+	return (p);
+}
+
+static void ehci_free (void *p, size_t sz)
+{
+}
+
+static int ehci_td_buffer (struct qTD *td, void *buf, size_t sz)
+{
+	uint32_t addr, delta, next;
+	int idx;
+
+	addr = (uint32_t) buf;
+	idx = 0;
+	while (idx < 5) {
+		td->qt_buffer[idx] = cpu_to_le32 (addr);
+		next = (addr + 4096) & ~4095;
+		delta = next - addr;
+		if (delta >= sz)
+			break;
+		sz -= delta;
+		addr = next;
+		idx++;
+	}
+
+	if (idx == 5) {
+		debug ("out of buffer pointers (%u bytes left)", sz);
+		return (-1);
+	}
+
+	return (0);
+}
+
+static int
+ehci_submit_async (struct usb_device *dev, unsigned long pipe, void *buffer,
+		   int length, struct devrequest *req)
+{
+	struct QH *qh;
+	struct qTD *td;
+	volatile struct qTD *vtd;
+	unsigned long ts;
+	uint32_t *tdp;
+	uint32_t endpt, token, usbsts;
+	uint32_t c, toggle;
+
+	debug ("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p", dev, pipe,
+	       buffer, length, req);
+	if (req != NULL)
+		debug ("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u",
+		       req->request, req->request,
+		       req->requesttype, req->requesttype,
+		       le16_to_cpu (req->value), le16_to_cpu (req->value),
+		       le16_to_cpu (req->index), le16_to_cpu (req->index));
+
+	qh = ehci_alloc (sizeof (struct QH), 32);
+	if (qh == NULL) {
+		debug ("unable to allocate QH");
+		return (-1);
+	}
+	qh->qh_link = cpu_to_le32 ((uint32_t) & qh_list | QH_LINK_TYPE_QH);
+	c = (usb_pipespeed (pipe) != USB_SPEED_HIGH &&
+	     usb_pipeendpoint (pipe) == 0) ? 1 : 0;
+	endpt = (8 << 28) |
+	    (c << 27) |
+	    (usb_maxpacket (dev, pipe) << 16) |
+	    (0 << 15) |
+	    (1 << 14) |
+	    (usb_pipespeed (pipe) << 12) |
+	    (usb_pipeendpoint (pipe) << 8) |
+	    (0 << 7) | (usb_pipedevice (pipe) << 0);
+	qh->qh_endpt1 = cpu_to_le32 (endpt);
+	endpt = (1 << 30) |
+	    (dev->portnr << 23) |
+	    (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
+	qh->qh_endpt2 = cpu_to_le32 (endpt);
+	qh->qh_overlay.qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+	qh->qh_overlay.qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+
+	td = NULL;
+	tdp = &qh->qh_overlay.qt_next;
+
+	toggle =
+	    usb_gettoggle (dev, usb_pipeendpoint (pipe), usb_pipeout (pipe));
+
+	if (req != NULL) {
+		td = ehci_alloc (sizeof (struct qTD), 32);
+		if (td == NULL) {
+			debug ("unable to allocate SETUP td");
+			goto fail;
+		}
+		td->qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+		td->qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+		token = (0 << 31) |
+		    (sizeof (*req) << 16) |
+		    (0 << 15) | (0 << 12) | (3 << 10) | (2 << 8) | (0x80 << 0);
+		td->qt_token = cpu_to_le32 (token);
+		if (ehci_td_buffer (td, req, sizeof (*req)) != 0) {
+			debug ("unable construct SETUP td");
+			ehci_free (td, sizeof (*td));
+			goto fail;
+		}
+		*tdp = cpu_to_le32 ((uint32_t) td);
+		tdp = &td->qt_next;
+		toggle = 1;
+	}
+
+	if (length > 0 || req == NULL) {
+		td = ehci_alloc (sizeof (struct qTD), 32);
+		if (td == NULL) {
+			debug ("unable to allocate DATA td");
+			goto fail;
+		}
+		td->qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+		td->qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+		token = (toggle << 31) |
+		    (length << 16) |
+		    ((req == NULL ? 1 : 0) << 15) |
+		    (0 << 12) |
+		    (3 << 10) |
+		    ((usb_pipein (pipe) ? 1 : 0) << 8) | (0x80 << 0);
+		td->qt_token = cpu_to_le32 (token);
+		if (ehci_td_buffer (td, buffer, length) != 0) {
+			debug ("unable construct DATA td");
+			ehci_free (td, sizeof (*td));
+			goto fail;
+		}
+		*tdp = cpu_to_le32 ((uint32_t) td);
+		tdp = &td->qt_next;
+	}
+
+	if (req != NULL) {
+		td = ehci_alloc (sizeof (struct qTD), 32);
+		if (td == NULL) {
+			debug ("unable to allocate ACK td");
+			goto fail;
+		}
+		td->qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+		td->qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+		token = (toggle << 31) |
+		    (0 << 16) |
+		    (1 << 15) |
+		    (0 << 12) |
+		    (3 << 10) |
+		    ((usb_pipein (pipe) ? 0 : 1) << 8) | (0x80 << 0);
+		td->qt_token = cpu_to_le32 (token);
+		*tdp = cpu_to_le32 ((uint32_t) td);
+		tdp = &td->qt_next;
+	}
+
+	qh_list.qh_link = cpu_to_le32 ((uint32_t) qh | QH_LINK_TYPE_QH);
+
+	usbsts = le32_to_cpu (hcor->or_usbsts);
+	hcor->or_usbsts = cpu_to_le32 (usbsts & 0x3f);
+
+	/* Enable async. schedule. */
+	hcor->or_usbcmd |= cpu_to_le32 (0x20);
+	while ((hcor->or_usbsts & cpu_to_le32 (0x8000)) == 0)
+		udelay (1);
+
+	/* Wait for TDs to be processed. */
+	ts = get_timer (0);
+	vtd = td;
+	do {
+		token = le32_to_cpu (vtd->qt_token);
+		if (!(token & 0x80))
+			break;
+	} while (get_timer (ts) < CFG_HZ);
+
+	/* Disable async schedule. */
+	hcor->or_usbcmd &= ~cpu_to_le32 (0x20);
+	while ((hcor->or_usbsts & cpu_to_le32 (0x8000)) != 0)
+		udelay (1);
+
+	qh_list.qh_link = cpu_to_le32 ((uint32_t) & qh_list | QH_LINK_TYPE_QH);
+
+	token = le32_to_cpu (qh->qh_overlay.qt_token);
+	if (!(token & 0x80)) {
+		// debug ("TOKEN=%#x", token);
+		switch (token & 0xfc) {
+		case 0:
+			toggle = token >> 31;
+			usb_settoggle (dev, usb_pipeendpoint (pipe),
+				       usb_pipeout (pipe), toggle);
+			dev->status = 0;
+			break;
+		case 0x40:
+			dev->status = USB_ST_STALLED;
+			break;
+		case 0xa0:
+		case 0x20:
+			dev->status = USB_ST_BUF_ERR;
+			break;
+		case 0x50:
+		case 0x10:
+			dev->status = USB_ST_BABBLE_DET;
+			break;
+		default:
+			dev->status = USB_ST_CRC_ERR;
+			break;
+		}
+		dev->act_len = length - ((token >> 16) & 0x7fff);
+	} else {
+		dev->act_len = 0;
+		debug ("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x",
+		       dev->devnum, le32_to_cpu (hcor->or_usbsts),
+		       le32_to_cpu (hcor->or_portsc[0]),
+		       le32_to_cpu (hcor->or_portsc[1]));
+	}
+
+	return ((dev->status != USB_ST_NOT_PROC) ? 0 : -1);
+
+      fail:
+	td = (void *)le32_to_cpu (qh->qh_overlay.qt_next);
+	while (td != (void *)QT_NEXT_TERMINATE) {
+		qh->qh_overlay.qt_next = td->qt_next;
+		ehci_free (td, sizeof (*td));
+		td = (void *)le32_to_cpu (qh->qh_overlay.qt_next);
+	}
+	ehci_free (qh, sizeof (*qh));
+	return (-1);
+}
+
+static __inline int min3 (int a, int b, int c)
+{
+
+	if (b < a)
+		a = b;
+	if (c < a)
+		a = c;
+	return (a);
+}
+
+static int
+ehci_submit_root (struct usb_device *dev, unsigned long pipe, void *buffer,
+		  int length, struct devrequest *req)
+{
+	uint8_t tmpbuf[4];
+	void *srcptr;
+	int len, srclen;
+	uint32_t reg;
+
+	srclen = 0;
+	srcptr = NULL;
+
+	debug ("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
+	       req->request, req->request,
+	       req->requesttype, req->requesttype,
+	       le16_to_cpu (req->value), le16_to_cpu (req->index));
+
+#define C(a,b)	(((b) << 8) | (a))
+
+	switch (C (req->request, req->requesttype)) {
+	case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE):
+		switch (le16_to_cpu (req->value) >> 8) {
+		case USB_DT_DEVICE:
+			srcptr = descr.device;
+			srclen = sizeof (descr.device);
+			break;
+		case USB_DT_CONFIG:
+			srcptr = descr.config;
+			srclen = sizeof (descr.config) +
+			    sizeof (descr.interface) + sizeof (descr.endpoint);
+			break;
+		case USB_DT_STRING:
+			switch (le16_to_cpu (req->value) & 0xff) {
+			case 0:	/* Language */
+				srcptr = "\4\3\1\0";
+				srclen = 4;
+				break;
+			case 1:	/* Vendor */
+				srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
+				srclen = 14;
+				break;
+			case 2:	/* Product */
+				srcptr = "\52\3E\0H\0C\0I\0 \0H\0o\0s\0t\0 \0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
+				srclen = 42;
+				break;
+			default:
+				goto unknown;
+			}
+			break;
+		default:
+			debug ("unknown value %x", le16_to_cpu (req->value));
+			goto unknown;
+		}
+		break;
+	case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB):
+		switch (le16_to_cpu (req->value) >> 8) {
+		case USB_DT_HUB:
+			srcptr = descr.hub;
+			srclen = sizeof (descr.hub);
+			break;
+		default:
+			debug ("unknown value %x", le16_to_cpu (req->value));
+			goto unknown;
+		}
+		break;
+	case C (USB_REQ_SET_ADDRESS, USB_RECIP_DEVICE):
+		rootdev = le16_to_cpu (req->value);
+		break;
+	case C (USB_REQ_SET_CONFIGURATION, USB_RECIP_DEVICE):
+		/* Nothing to do */
+		break;
+	case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB):
+		tmpbuf[0] = 1;	/* USB_STATUS_SELFPOWERED */
+		tmpbuf[1] = 0;
+		srcptr = tmpbuf;
+		srclen = 2;
+		break;
+	case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT):
+		memset (tmpbuf, 0, 4);
+		reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+		if (reg & EHCI_PS_CS)
+			tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
+		if (reg & EHCI_PS_PE)
+			tmpbuf[0] |= USB_PORT_STAT_ENABLE;
+		if (reg & EHCI_PS_SUSP)
+			tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
+		if (reg & EHCI_PS_OCA)
+			tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
+		if (reg & EHCI_PS_PR)
+			tmpbuf[0] |= USB_PORT_STAT_RESET;
+		if (reg & EHCI_PS_PP)
+			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
+		tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
+
+		if (reg & EHCI_PS_CSC)
+			tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
+		if (reg & EHCI_PS_PEC)
+			tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
+		if (reg & EHCI_PS_OCC)
+			tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
+		if (portreset & (1 << le16_to_cpu (req->index)))
+			tmpbuf[2] |= USB_PORT_STAT_C_RESET;
+		srcptr = tmpbuf;
+		srclen = 4;
+		break;
+	case C (USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_RT_PORT):
+		reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+		reg &= ~EHCI_PS_CLEAR;
+		switch (le16_to_cpu (req->value)) {
+		case USB_PORT_FEAT_POWER:
+			reg |= EHCI_PS_PP;
+			break;
+		case USB_PORT_FEAT_RESET:
+			if (EHCI_PS_IS_LOWSPEED (reg)) {
+				/* Low speed device, give up ownership. */
+				reg |= EHCI_PS_PO;
+				break;
+			}
+			/* Start reset sequence. */
+			reg &= ~EHCI_PS_PE;
+			reg |= EHCI_PS_PR;
+			hcor->or_portsc[le16_to_cpu (req->index) - 1] =
+			    cpu_to_le32 (reg);
+			/* Wait for reset to complete. */
+			udelay (500000);
+			/* Terminate reset sequence. */
+			reg &= ~EHCI_PS_PR;
+			/* TODO: is it only fsl chip that requires this
+			 * manual setting of port enable?
+			 */
+			reg |= EHCI_PS_PE;
+			hcor->or_portsc[le16_to_cpu (req->index) - 1] =
+			    cpu_to_le32 (reg);
+			/* Wait for HC to complete reset. */
+			udelay (2000);
+			reg =
+			    le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+			reg &= ~EHCI_PS_CLEAR;
+			if ((reg & EHCI_PS_PE) == 0) {
+				/* Not a high speed device, give up ownership. */
+				reg |= EHCI_PS_PO;
+				break;
+			}
+			portreset |= 1 << le16_to_cpu (req->index);
+			break;
+		default:
+			debug ("unknown feature %x", le16_to_cpu (req->value));
+			goto unknown;
+		}
+		hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
+		break;
+	case C (USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RT_PORT):
+		reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
+		reg &= ~EHCI_PS_CLEAR;
+		switch (le16_to_cpu (req->value)) {
+		case USB_PORT_FEAT_ENABLE:
+			reg &= ~EHCI_PS_PE;
+			break;
+		case USB_PORT_FEAT_C_CONNECTION:
+			reg |= EHCI_PS_CSC;
+			break;
+		case USB_PORT_FEAT_C_RESET:
+			portreset &= ~(1 << le16_to_cpu (req->index));
+			break;
+		default:
+			debug ("unknown feature %x", le16_to_cpu (req->value));
+			goto unknown;
+		}
+		hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
+		break;
+	default:
+		debug ("Unknown request %x",
+		       C (req->request, req->requesttype));
+		goto unknown;
+	}
+
+#undef C
+
+	len = min3 (srclen, le16_to_cpu (req->length), length);
+	if (srcptr != NULL && len > 0)
+		memcpy (buffer, srcptr, len);
+	dev->act_len = len;
+	dev->status = 0;
+	return (0);
+
+      unknown:
+	debug ("requesttype=%x, request=%x, value=%x, index=%x, length=%x",
+	       req->requesttype, req->request, le16_to_cpu (req->value),
+	       le16_to_cpu (req->index), le16_to_cpu (req->length));
+
+	dev->act_len = 0;
+	dev->status = USB_ST_STALLED;
+	return (-1);
+}
+
+int usb_lowlevel_stop (void)
+{
+	return ehci_hcd_stop ();
+}
+
+int usb_lowlevel_init (void)
+{
+	uint32_t reg;
+
+	if (ehci_hcd_init () != 0) {
+		return -1;
+	}
+
+	/* Set head of reclaim list */
+	memset (&qh_list, 0, sizeof (qh_list));
+	qh_list.qh_link = cpu_to_le32 ((uint32_t) & qh_list | QH_LINK_TYPE_QH);
+	qh_list.qh_endpt1 = cpu_to_le32 ((1 << 15) | (USB_SPEED_HIGH << 12));
+	qh_list.qh_curtd = cpu_to_le32 (QT_NEXT_TERMINATE);
+	qh_list.qh_overlay.qt_next = cpu_to_le32 (QT_NEXT_TERMINATE);
+	qh_list.qh_overlay.qt_altnext = cpu_to_le32 (QT_NEXT_TERMINATE);
+	qh_list.qh_overlay.qt_token = cpu_to_le32 (0x40);
+
+	/* Set async. queue head pointer. */
+	hcor->or_asynclistaddr = cpu_to_le32 ((uint32_t) & qh_list);
+
+	reg = le32_to_cpu (hccr->cr_hcsparams);
+	descr.hub[2] = reg & 0xf;
+	if (reg & 0x10000)	/* Port Indicators */
+		descr.hub[3] |= 0x80;
+	if (reg & 0x10)		/* Port Power Control */
+		descr.hub[3] |= 0x01;
+
+	/* take control over the ports */
+	hcor->or_configflag |= cpu_to_le32 (1);
+
+	/* Start the host controller. */
+	hcor->or_usbcmd |= cpu_to_le32 (1);
+
+	rootdev = 0;
+
+	return 0;
+}
+
+int
+submit_bulk_msg (struct usb_device *dev, unsigned long pipe, void *buffer,
+		 int length)
+{
+
+	if (usb_pipetype (pipe) != PIPE_BULK) {
+		debug ("non-bulk pipe (type=%lu)", usb_pipetype (pipe));
+		return (-1);
+	}
+	return (ehci_submit_async (dev, pipe, buffer, length, NULL));
+}
+
+int
+submit_control_msg (struct usb_device *dev, unsigned long pipe, void *buffer,
+		    int length, struct devrequest *setup)
+{
+
+	if (usb_pipetype (pipe) != PIPE_CONTROL) {
+		debug ("non-control pipe (type=%lu)", usb_pipetype (pipe));
+		return (-1);
+	}
+
+	if (usb_pipedevice (pipe) == rootdev) {
+		if (rootdev == 0)
+			dev->speed = USB_SPEED_HIGH;
+		return (ehci_submit_root (dev, pipe, buffer, length, setup));
+	}
+	return (ehci_submit_async (dev, pipe, buffer, length, setup));
+}
+
+int
+submit_int_msg (struct usb_device *dev, unsigned long pipe, void *buffer,
+		int length, int interval)
+{
+
+	debug ("dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe,
+	       buffer, length, interval);
+	return (-1);
+}
diff --git a/drivers/usb/usb_ehci_core.h b/drivers/usb/usb_ehci_core.h
new file mode 100644
index 0000000..88e91b9
--- /dev/null
+++ b/drivers/usb/usb_ehci_core.h
@@ -0,0 +1,29 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * Copyright (c) 2008, Excito Elektronik i Sk?ne AB
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef USB_EHCI_CORE_H
+#define USB_EHCI_CORE_H
+
+extern int rootdev;
+extern struct ehci_hccr *hccr;
+extern volatile struct ehci_hcor *hcor;
+
+#endif
-- 
1.5.6

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx
  2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
@ 2008-06-23 11:24   ` Tor Krill
  2008-06-23 11:24     ` [U-Boot-Users] [PATCH 4/4][RFC] ReAdd extracted Juniper Networks PCI hcd driver Tor Krill
  2008-06-23 12:59   ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality michael
       [not found]   ` <49267DEB.5020903@gandalf.sssup.it>
  2 siblings, 1 reply; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
  To: u-boot

Add hcd driver for Freescale 8313 and possibly others. Supports
built in UTMI PHY and has a hardcoded clock setting.

Signed-off-by: Tor Krill <tor@excito.com>
---
 drivers/usb/usb_ehci_fsl.c |   99 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/usb_ehci_fsl.h |   82 ++++++++++++++++++++++++++++++++++++
 2 files changed, 181 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/usb_ehci_fsl.c
 create mode 100644 drivers/usb/usb_ehci_fsl.h

diff --git a/drivers/usb/usb_ehci_fsl.c b/drivers/usb/usb_ehci_fsl.c
new file mode 100644
index 0000000..6c03773
--- /dev/null
+++ b/drivers/usb/usb_ehci_fsl.c
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2008, Excito Elektronik i Sk?ne AB
+ *
+ * Author: Tor Krill tor at excito.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <usb.h>
+#include <mpc83xx.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#include "usb_ehci.h"
+#include "usb_ehci_fsl.h"
+#include "usb_ehci_core.h"
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ *
+ * Excerpts from linux ehci fsl driver.
+ */
+int ehci_hcd_init (void)
+{
+	volatile immap_t *im = (immap_t *) CFG_IMMR;
+	uint32_t addr, temp;
+
+	addr = (uint32_t) & (im->usb[0]);
+	hccr = (struct ehci_hccr *)(addr + FSL_SKIP_PCI);
+	hcor = (struct ehci_hcor *)((uint32_t) hccr + hccr->cr_caplength);
+
+	/* Configure clock */
+	clrsetbits_be32 (&(im->clk.sccr), MPC83XX_SCCR_USB_MASK,
+			 MPC83XX_SCCR_USB_DRCM_11);
+
+	/* Confgure interface. */
+	temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+	out_be32 ((void *)(addr + FSL_SOC_USB_CTRL), temp
+		  | REFSEL_16MHZ | UTMI_PHY_EN);
+
+	/* Wait for clock to stabilize */
+	do {
+		temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+		udelay (1000);
+	} while (!(temp & PHY_CLK_VALID));
+
+	/* Set to Host mode */
+	temp = in_le32 ((void *)(addr + FSL_SOC_USB_USBMODE));
+	out_le32 ((void *)(addr + FSL_SOC_USB_USBMODE), temp | CM_HOST);
+
+	out_be32 ((void *)(addr + FSL_SOC_USB_SNOOP1), SNOOP_SIZE_2GB);
+	out_be32 ((void *)(addr + FSL_SOC_USB_SNOOP2),
+		  0x80000000 | SNOOP_SIZE_2GB);
+
+	/* Init phy */
+	/* TODO: handle different phys? */
+	out_le32 (&(hcor->or_portsc[0]), PORT_PTS_UTMI);
+
+	/* Enable interface. */
+	temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+	out_be32 ((void *)(addr + FSL_SOC_USB_CTRL), temp | USB_EN);
+
+	out_be32 ((void *)(addr + FSL_SOC_USB_PRICTRL), 0x0000000c);
+	out_be32 ((void *)(addr + FSL_SOC_USB_AGECNTTHRSH), 0x00000040);
+	out_be32 ((void *)(addr + FSL_SOC_USB_SICTRL), 0x00000001);
+
+	/* Enable interface. */
+	temp = in_be32 ((void *)(addr + FSL_SOC_USB_CTRL));
+	out_be32 ((void *)(addr + FSL_SOC_USB_CTRL), temp | USB_EN);
+
+	temp = in_le32 ((void *)(addr + FSL_SOC_USB_USBMODE));
+
+	return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop (void)
+{
+	return 0;
+}
diff --git a/drivers/usb/usb_ehci_fsl.h b/drivers/usb/usb_ehci_fsl.h
new file mode 100644
index 0000000..dd7ee2e
--- /dev/null
+++ b/drivers/usb/usb_ehci_fsl.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 2005 freescale semiconductor
+ * Copyright (c) 2005 MontaVista Software
+ * Copyright (c) 2008 Excito Elektronik i Sk?ne AB
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the  GNU General Public License along
+ * with this program; if not, write  to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _EHCI_FSL_H
+#define _EHCI_FSL_H
+/* Global offsets */
+#define FSL_SKIP_PCI 0x100
+
+/* offsets for the non-ehci registers in the FSL SOC USB controller */
+#define FSL_SOC_USB_ULPIVP	0x170
+#define FSL_SOC_USB_PORTSC1	0x184
+#define PORT_PTS_MSK		(3<<30)
+#define PORT_PTS_UTMI		(0<<30)
+#define PORT_PTS_ULPI		(2<<30)
+#define	PORT_PTS_SERIAL		(3<<30)
+#define PORT_PTS_PTW		(1<<28)
+
+/* USBMODE Register bits */
+#define CM_IDLE				(0<<0)
+#define CM_RESERVED			(1<<0)
+#define CM_DEVICE			(2<<0)
+#define CM_HOST				(3<<0)
+#define USBMODE_RESERVED_2	(0<<2)
+#define SLOM				(1<<3)
+#define SDIS				(1<<4)
+
+/* CONTROL Register bits */
+#define ULPI_INT_EN			(1<<0)
+#define WU_INT_EN			(1<<1)
+#define USB_EN				(1<<2)
+#define LSF_EN				(1<<3)
+#define KEEP_OTG_ON			(1<<4)
+#define OTG_PORT			(1<<5)
+#define REFSEL_12MHZ		(0<<6)
+#define REFSEL_16MHZ		(1<<6)
+#define REFSEL_48MHZ		(2<<6)
+#define PLL_RESET			(1<<8)
+#define UTMI_PHY_EN			(1<<9)
+#define PHY_CLK_SEL_UTMI	(0<<10)
+#define PHY_CLK_SEL_ULPI	(1<<10)
+#define CLKIN_SEL_USB_CLK	(0<<11)
+#define CLKIN_SEL_USB_CLK2	(1<<11)
+#define CLKIN_SEL_SYS_CLK	(2<<11)
+#define CLKIN_SEL_SYS_CLK2	(3<<11)
+#define RESERVED_18			(0<<13)
+#define RESERVED_17			(0<<14)
+#define RESERVED_16			(0<<15)
+#define WU_INT				(1<<16)
+#define PHY_CLK_VALID		(1<<17)
+
+#define FSL_SOC_USB_PORTSC2	0x188
+#define FSL_SOC_USB_USBMODE	0x1a8
+#define FSL_SOC_USB_SNOOP1	0x400	/* NOTE: big-endian */
+#define FSL_SOC_USB_SNOOP2	0x404	/* NOTE: big-endian */
+#define FSL_SOC_USB_AGECNTTHRSH	0x408	/* NOTE: big-endian */
+#define FSL_SOC_USB_PRICTRL	0x40c	/* NOTE: big-endian */
+#define FSL_SOC_USB_SICTRL	0x410	/* NOTE: big-endian */
+#define FSL_SOC_USB_CTRL	0x500	/* NOTE: big-endian */
+#define SNOOP_SIZE_2GB		0x1e
+
+/* System Clock Control Register */
+#define MPC83XX_SCCR_USB_MASK		0x00f00000
+#define MPC83XX_SCCR_USB_DRCM_11	0x00300000
+#define MPC83XX_SCCR_USB_DRCM_01	0x00100000
+#define MPC83XX_SCCR_USB_DRCM_10	0x00200000
+
+#endif /* _EHCI_FSL_H */
-- 
1.5.6

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 4/4][RFC] ReAdd extracted Juniper Networks PCI hcd driver
  2008-06-23 11:24   ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
@ 2008-06-23 11:24     ` Tor Krill
  0 siblings, 0 replies; 12+ messages in thread
From: Tor Krill @ 2008-06-23 11:24 UTC (permalink / raw)
  To: u-boot

Readds Juniper Networks original Philips PCI driver. (Untested)

Signed-off-by: Tor Krill <tor@excito.com>
---
 drivers/usb/usb_ehci_pci.c |  135 ++++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/usb_ehci_pci.h |   37 ++++++++++++
 2 files changed, 172 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/usb_ehci_pci.c
 create mode 100644 drivers/usb/usb_ehci_pci.h

diff --git a/drivers/usb/usb_ehci_pci.c b/drivers/usb/usb_ehci_pci.c
new file mode 100644
index 0000000..d652122
--- /dev/null
+++ b/drivers/usb/usb_ehci_pci.c
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <usb.h>
+#include "usb_ehci.h"
+#include "usb_ehci_pci.h"
+#include "usb_ehci_core.h"
+
+#ifdef EHCI_DEBUG
+static void dump_pci_reg (pci_dev_t dev, int ofs)
+{
+	uint32_t reg;
+
+	pci_read_config_dword (dev, ofs, &reg);
+	printf ("\t0x%02x: %08x\n", ofs, reg);
+}
+
+static void dump_pci (int enh, pci_dev_t dev)
+{
+	int ofs;
+
+	debug ("\n%s", (enh) ? "EHCI" : "OHCI");
+	for (ofs = 0; ofs < 0x44; ofs += 4)
+		dump_pci_reg (dev, ofs);
+	if (enh)
+		dump_pci_reg (dev, 0x60);
+	dump_pci_reg (dev, 0xdc);
+	dump_pci_reg (dev, 0xe0);
+	if (enh) {
+		dump_pci_reg (dev, 0xe4);
+		dump_pci_reg (dev, 0xe8);
+	}
+}
+
+static void dump_regs (void)
+{
+
+	debug ("usbcmd=%#x, usbsts=%#x, usbintr=%#x,\n\tfrindex=%#x, "
+	       "ctrldssegment=%#x, periodiclistbase=%#x,\n\tasynclistaddr=%#x, "
+	       "configflag=%#x,\n\tportsc[1]=%#x, portsc[2]=%#x, systune=%#x",
+	       swap_32 (hcor->or_usbcmd), swap_32 (hcor->or_usbsts),
+	       swap_32 (hcor->or_usbintr), swap_32 (hcor->or_frindex),
+	       swap_32 (hcor->or_ctrldssegment),
+	       swap_32 (hcor->or_periodiclistbase),
+	       swap_32 (hcor->or_asynclistaddr), swap_32 (hcor->or_configflag),
+	       swap_32 (hcor->or_portsc[0]), swap_32 (hcor->or_portsc[1]),
+	       swap_32 (hcor->or_systune));
+}
+
+static void dump_TD (struct qTD *td)
+{
+
+	debug ("%p: qt_next=%#x, qt_altnext=%#x, qt_token=%#x, "
+	       "qt_buffer={%#x,%#x,%#x,%#x,%#x}", td, swap_32 (td->qt_next),
+	       swap_32 (td->qt_altnext), swap_32 (td->qt_token),
+	       swap_32 (td->qt_buffer[0]), swap_32 (td->qt_buffer[1]),
+	       swap_32 (td->qt_buffer[2]), swap_32 (td->qt_buffer[3]),
+	       swap_32 (td->qt_buffer[4]));
+}
+
+static void dump_QH (struct QH *qh)
+{
+
+	debug ("%p: qh_link=%#x, qh_endpt1=%#x, qh_endpt2=%#x, qh_curtd=%#x",
+	       qh, swap_32 (qh->qh_link), swap_32 (qh->qh_endpt1),
+	       swap_32 (qh->qh_endpt2), swap_32 (qh->qh_curtd));
+	dump_TD (&qh->qh_overlay);
+}
+#endif
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init (void)
+{
+	pci_dev_t dev;
+	uint32_t addr;
+
+	dev = pci_find_device (0x1131, 0x1561, 0);
+	if (dev != -1) {
+		volatile uint32_t *hcreg;
+
+		pci_read_config_dword (dev, PCI_BASE_ADDRESS_0, &addr);
+		hcreg = (uint32_t *) (addr + 8);
+		*hcreg = swap_32 (1);
+		udelay (100);
+	}
+
+	dev = pci_find_device (0x1131, 0x1562, 0);
+	if (dev == -1) {
+		printf ("EHCI host controller not found\n");
+		return (-1);
+	}
+
+	pci_read_config_dword (dev, EHCI_PCICS_USBBASE, &addr);
+	hccr = (void *)addr;
+
+	addr += hccr->cr_caplength;
+	hcor = (void *)addr;
+
+	/* Latte/Espresso USB hardware bug workaround */
+	hcor->or_systune |= swap_32 (3);
+
+	return (0);
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop (void)
+{
+
+	return (0);
+}
diff --git a/drivers/usb/usb_ehci_pci.h b/drivers/usb/usb_ehci_pci.h
new file mode 100644
index 0000000..6a4d16e
--- /dev/null
+++ b/drivers/usb/usb_ehci_pci.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2007-2008, Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * PCI Configuration Space.
+ */
+#define	EHCI_PCICS_BASEC		PCI_CLASS_CODE
+#define	EHCI_PCICS_SCC			PCI_CLASS_SUB_CODE
+#define	EHCI_PCICS_PI			PCI_CLASS_PROG
+#define	EHCI_PCICS_USBBASE		PCI_BASE_ADDRESS_0
+#define	EHCI_PCICS_SBRN			0x60
+#define	EHCI_PCICS_FLADJ		0x61
+#define	EHCI_PCICS_PORTWAKECAP		0x62
+
+#define	EHCI_PCICS_USBLEGSUP
+#define	EHCI_PCICS_USBLEGCTLSTS
+
+#define	EHCI_PCI_BASEC			0x0c	/* Serial Bus Controller. */
+#define	EHCI_PCI_SCC			0x03	/* USB Host Controller. */
+#define	EHCI_PCI_PI			0x20	/* USB 2.0 Host Controller. */
-- 
1.5.6

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality
  2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
  2008-06-23 11:24   ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
@ 2008-06-23 12:59   ` michael
       [not found]   ` <49267DEB.5020903@gandalf.sssup.it>
  2 siblings, 0 replies; 12+ messages in thread
From: michael @ 2008-06-23 12:59 UTC (permalink / raw)
  To: u-boot

Hi,
Tor Krill wrote:
> +static uint16_t portreset;
> +static struct QH qh_list __attribute__ ((aligned (32)));
> +
> +static struct {
> +	uint8_t hub[8];
> +	uint8_t device[18];
> +	uint8_t config[9];
> +	uint8_t interface[9];
> +	uint8_t endpoint[7];
> +} descr = {
> +	{			/* HUB */
> +		sizeof (descr.hub),	/* bDescLength */
> +		    0x29,	/* bDescriptorType: hub descriptor */
> +		    2,		/* bNrPorts -- runtime modified */
> +		    0, 0,	/* wHubCharacteristics -- runtime modified */
> +		    0xff,	/* bPwrOn2PwrGood */
> +		    0,		/* bHubCntrCurrent */
> +		    0		/* DeviceRemovable XXX at most 7 ports! XXX */
> +	}
> +	, {			/* DEVICE */
> +		sizeof (descr.device),	/* bLength */
> +		    1,		/* bDescriptorType: UDESC_DEVICE */
> +		    0x00, 0x02,	/* bcdUSB: v2.0 */
> +		    9,		/* bDeviceClass: UDCLASS_HUB */
> +		    0,		/* bDeviceSubClass: UDSUBCLASS_HUB */
> +		    1,		/* bDeviceProtocol: UDPROTO_HSHUBSTT */
> +		    64,		/* bMaxPacketSize: 64 bytes */
> +		    0x00, 0x00,	/* idVendor */
> +		    0x00, 0x00,	/* idProduct */
> +		    0x00, 0x01,	/* bcdDevice */
> +		    1,		/* iManufacturer */
> +		    2,		/* iProduct */
> +		    0,		/* iSerialNumber */
> +		    1		/* bNumConfigurations: 1 */
> +	}
> +	, {			/* CONFIG */
> +		sizeof (descr.config),	/* bLength */
> +		    2,		/* bDescriptorType: UDESC_CONFIG */
> +		    sizeof (descr.config) + sizeof (descr.interface) +
> +		    sizeof (descr.endpoint), 0,
> +		    /* wTotalLength */
> +		    1,		/* bNumInterface */
> +		    1,		/* bConfigurationValue */
> +		    0,		/* iConfiguration */
> +		    0x40,	/* bmAttributes: UC_SELF_POWERED */
> +		    0		/* bMaxPower */
> +	}
> +	, {			/* INTERFACE */
> +		sizeof (descr.interface),	/* bLength */
> +		    4,		/* bDescriptorType: UDESC_INTERFACE */
> +		    0,		/* bInterfaceNumber */
> +		    0,		/* bAlternateSetting */
> +		    1,		/* bNumEndpoints */
> +		    9,		/* bInterfaceClass: UICLASS_HUB */
> +		    0,		/* bInterfaceSubClass: UISUBCLASS_HUB */
> +		    0,		/* bInterfaceProtocol: UIPROTO_HSHUBSTT */
> +		    0		/* iInterface */
> +	}
> +	, {			/* ENDPOINT */
> +		sizeof (descr.endpoint),	/* bLength */
> +		    5,		/* bDescriptorType: UDESC_ENDPOINT */
> +		    0x81,	/* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
> +		    3,		/* bmAttributes: UE_INTERRUPT */
> +		    8, 0,	/* wMaxPacketSize */
> +		    255		/* bInterval */
> +	}
> +};
> +
>   
I prefer using:

struct usb_device_descriptor device = {
        sizeof(struct usb_device_descriptor),   /* bLength */
        1,              /* bDescriptorType: UDESC_DEVICE */
        0x0002,         /* bcdUSB: v2.0 */
        9,              /* bDeviceClass: UDCLASS_HUB */
        0,              /* bDeviceSubClass: UDSUBCLASS_HUB */
        1,              /* bDeviceProtocol: UDPROTO_HSHUBSTT */
        64,             /* bMaxPacketSize: 64 bytes */
        0x0000,         /* idVendor */
        0x0000,         /* idProduct */
        0x0001,         /* bcdDevice */
        1,              /* iManufacturer */
        2,              /* iProduct */
        0,              /* iSerialNumber */
        1               /* bNumConfigurations: 1 */
};

struct usb_interface_descriptor interface = {
        sizeof(struct usb_interface_descriptor),        /* bLength */
        4,              /* bDescriptorType: UDESC_INTERFACE */
        0,              /* bInterfaceNumber */
        0,              /* bAlternateSetting */
        1,              /* bNumEndpoints */
        9,              /* bInterfaceClass: UICLASS_HUB */
        0,              /* bInterfaceSubClass: UISUBCLASS_HUB */
        0,              /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
        0               /* iInterface */
};

struct usb_endpoint_descriptor endpoint = {
        sizeof(struct usb_endpoint_descriptor),         /* bLength */
        5,              /* bDescriptorType: UDESC_ENDPOINT */
        0x81,           /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
        3,              /* bmAttributes: UE_INTERRUPT */
        8, 0,           /* wMaxPacketSize */
        255             /* bInterval */

};

struct usb_hub_descriptor hub = {
        sizeof(struct usb_hub_descriptor),      /* bDescLength */
        0x29,                           /* bDescriptorType: hub 
descriptor */
        2,                              /* bNrPorts -- runtime modified */
        0, 0,                           /* wHubCharacteristics */
        0xff,                           /* bPwrOn2PwrGood */
        {},                             /* bHubCntrCurrent */
        {}                              /* at most 7 ports! XXX */
};

Why don't use somenthing like this? (see up)

> +static int
> +ehci_submit_root (struct usb_device *dev, unsigned long pipe, void *buffer,
> +		  int length, struct devrequest *req)
> +{
> +	uint8_t tmpbuf[4];
> +	void *srcptr;
> +	int len, srclen;
> +	uint32_t reg;
> +
> +	srclen = 0;
> +	srcptr = NULL;
> +
> +	debug ("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
> +	       req->request, req->request,
> +	       req->requesttype, req->requesttype,
> +	       le16_to_cpu (req->value), le16_to_cpu (req->index));
> +
> +#define C(a,b)	(((b) << 8) | (a))
> +
> +	switch (C (req->request, req->requesttype)) {
> +	case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE):
> +		switch (le16_to_cpu (req->value) >> 8) {
> +		case USB_DT_DEVICE:
> +			srcptr = descr.device;
> +			srclen = sizeof (descr.device);
> +			break;
> +		case USB_DT_CONFIG:
> +			srcptr = descr.config;
> +			srclen = sizeof (descr.config) +
> +			    sizeof (descr.interface) + sizeof (descr.endpoint);
> +			break;
> +		case USB_DT_STRING:
> +			switch (le16_to_cpu (req->value) & 0xff) {
> +			case 0:	/* Language */
> +				srcptr = "\4\3\1\0";
> +				srclen = 4;
> +				break;
> +			case 1:	/* Vendor */
> +				srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
> +				srclen = 14;
> +				break;
> +			case 2:	/* Product */
> +				srcptr = "\52\3E\0H\0C\0I\0 \0H\0o\0s\0t\0 \0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
> +				srclen = 42;
> +				break;
> +			default:
> +				goto unknown;
> +			}
> +			break;
> +		default:
> +			debug ("unknown value %x", le16_to_cpu (req->value));
> +			goto unknown;
> +		}
> +		break;
> +	case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB):
> +		switch (le16_to_cpu (req->value) >> 8) {
> +		case USB_DT_HUB:
> +			srcptr = descr.hub;
> +			srclen = sizeof (descr.hub);
> +			break;
> +		default:
> +			debug ("unknown value %x", le16_to_cpu (req->value));
> +			goto unknown;
> +		}
> +		break;
> +	case C (USB_REQ_SET_ADDRESS, USB_RECIP_DEVICE):
> +		rootdev = le16_to_cpu (req->value);
> +		break;
> +	case C (USB_REQ_SET_CONFIGURATION, USB_RECIP_DEVICE):
> +		/* Nothing to do */
> +		break;
> +	case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB):
> +		tmpbuf[0] = 1;	/* USB_STATUS_SELFPOWERED */
> +		tmpbuf[1] = 0;
> +		srcptr = tmpbuf;
> +		srclen = 2;
> +		break;
> +	case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT):
> +		memset (tmpbuf, 0, 4);
> +		reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> +		if (reg & EHCI_PS_CS)
> +			tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
> +		if (reg & EHCI_PS_PE)
> +			tmpbuf[0] |= USB_PORT_STAT_ENABLE;
> +		if (reg & EHCI_PS_SUSP)
> +			tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
> +		if (reg & EHCI_PS_OCA)
> +			tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
> +		if (reg & EHCI_PS_PR)
> +			tmpbuf[0] |= USB_PORT_STAT_RESET;
> +		if (reg & EHCI_PS_PP)
> +			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
> +		tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
> +
> +		if (reg & EHCI_PS_CSC)
> +			tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
> +		if (reg & EHCI_PS_PEC)
> +			tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
> +		if (reg & EHCI_PS_OCC)
> +			tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
> +		if (portreset & (1 << le16_to_cpu (req->index)))
> +			tmpbuf[2] |= USB_PORT_STAT_C_RESET;
> +		srcptr = tmpbuf;
> +		srclen = 4;
> +		break;
> +	case C (USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_RT_PORT):
> +		reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> +		reg &= ~EHCI_PS_CLEAR;
> +		switch (le16_to_cpu (req->value)) {
> +		case USB_PORT_FEAT_POWER:
> +			reg |= EHCI_PS_PP;
> +			break;
> +		case USB_PORT_FEAT_RESET:
> +			if (EHCI_PS_IS_LOWSPEED (reg)) {
> +				/* Low speed device, give up ownership. */
> +				reg |= EHCI_PS_PO;
> +				break;
> +			}
> +			/* Start reset sequence. */
> +			reg &= ~EHCI_PS_PE;
> +			reg |= EHCI_PS_PR;
> +			hcor->or_portsc[le16_to_cpu (req->index) - 1] =
> +			    cpu_to_le32 (reg);
> +			/* Wait for reset to complete. */
> +			udelay (500000);
> +			/* Terminate reset sequence. */
> +			reg &= ~EHCI_PS_PR;
> +			/* TODO: is it only fsl chip that requires this
> +			 * manual setting of port enable?
> +			 */
> +			reg |= EHCI_PS_PE;
> +			hcor->or_portsc[le16_to_cpu (req->index) - 1] =
> +			    cpu_to_le32 (reg);
> +			/* Wait for HC to complete reset. */
> +			udelay (2000);
> +			reg =
> +			    le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> +			reg &= ~EHCI_PS_CLEAR;
> +			if ((reg & EHCI_PS_PE) == 0) {
> +				/* Not a high speed device, give up ownership. */
> +				reg |= EHCI_PS_PO;
> +				break;
> +			}
> +			portreset |= 1 << le16_to_cpu (req->index);
> +			break;
> +		default:
> +			debug ("unknown feature %x", le16_to_cpu (req->value));
> +			goto unknown;
> +		}
> +		hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
> +		break;
> +	case C (USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RT_PORT):
> +		reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 1]);
> +		reg &= ~EHCI_PS_CLEAR;
> +		switch (le16_to_cpu (req->value)) {
> +		case USB_PORT_FEAT_ENABLE:
> +			reg &= ~EHCI_PS_PE;
> +			break;
> +		case USB_PORT_FEAT_C_CONNECTION:
> +			reg |= EHCI_PS_CSC;
> +			break;
> +		case USB_PORT_FEAT_C_RESET:
> +			portreset &= ~(1 << le16_to_cpu (req->index));
> +			break;
> +		default:
> +			debug ("unknown feature %x", le16_to_cpu (req->value));
> +			goto unknown;
> +		}
> +		hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 (reg);
> +		break;
> +	default:
> +		debug ("Unknown request %x",
> +		       C (req->request, req->requesttype));
> +		goto unknown;
> +	}
> +
> +#undef C
> +
> +	len = min3 (srclen, le16_to_cpu (req->length), length);
> +	if (srcptr != NULL && len > 0)
> +		memcpy (buffer, srcptr, len);
> +	dev->act_len = len;
> +	dev->status = 0;
> +	return (0);
> +
> +      unknown:
> +	debug ("requesttype=%x, request=%x, value=%x, index=%x, length=%x",
> +	       req->requesttype, req->request, le16_to_cpu (req->value),
> +	       le16_to_cpu (req->index), le16_to_cpu (req->length));
> +
> +	dev->act_len = 0;
> +	dev->status = USB_ST_STALLED;
> +	return (-1);
> +}
> +
>   
This code can be change according with this one.

static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
                            void *buffer, int length, struct devrequest 
*req)
{
        uint8_t tmpbuf[4];
        u16 typeReq;
        void *srcptr;
        int len, srclen;
        uint32_t reg;

        srclen = 0;
        srcptr = NULL;

        DBG("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
            req->request, req->request,
            req->requesttype, req->requesttype,
            swap_16(req->value), swap_16(req->index));

        typeReq = req->request << 8 | req->requesttype;

        switch (typeReq) {

        case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
                switch(swap_16(req->value) >> 8) {
                case USB_DT_DEVICE:
                        srcptr = &device;
                        srclen = sizeof(struct usb_device_descriptor);
                        break;
                case USB_DT_CONFIG:
                        srcptr = &config;
                        srclen = sizeof(config) +
                                sizeof(struct usb_interface_descriptor) +
                                sizeof(struct usb_hub_descriptor);
                        break;
                case USB_DT_STRING:
                        switch (swap_16(req->value) & 0xff) {
                        case 0:         /* Language */
                                srcptr = "\4\3\1\0";
                                srclen = 4;
                                break;
                        case 1:         /* Vendor */
                                srcptr = "\20\3P\0h\0i\0l\0i\0p\0s\0";
                                srclen = 16;
                                break;
                        case 2:         /* Product */
                                srcptr = "\12\3E\0H\0C\0I\0";
                                srclen = 10;
                                break;
                        default:
                                goto unknown;
                        }
                        break;
                default:
                        DBG("unknown value %x", swap_16(req->value));
                        goto unknown;
                }
                break;
        case USB_REQ_GET_DESCRIPTOR | (( USB_DIR_IN | USB_RT_HUB) << 8):
                switch (swap_16(req->value) >> 8) {
                case USB_DT_HUB:
                        srcptr = &hub;
                        srclen = sizeof(hub);
                        break;
                default:
                        DBG("unknown value %x", swap_16(req->value));
                        goto unknown;
                }
                break;
        case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
                rootdev = swap_16(req->value);
                break;
        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
                /* Nothing to do */
                break;
        case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
                tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
                tmpbuf[1] = 0;
                srcptr = tmpbuf;
                srclen = 2;
                break;
        case DeviceRequest | USB_REQ_GET_STATUS:
                memset(tmpbuf, 0, 4);
                reg = swap_32(hcor->or_portsc[swap_16(req->index) - 1]);
                if (reg & EHCI_PS_CS)
                        tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
                if (reg & EHCI_PS_PE)
                        tmpbuf[0] |= USB_PORT_STAT_ENABLE;
                if (reg & EHCI_PS_SUSP)
                        tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
                if (reg & EHCI_PS_OCA)
                        tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
                if (reg & EHCI_PS_PR)
                        tmpbuf[0] |= USB_PORT_STAT_RESET;
                if (reg & EHCI_PS_PP)
...

All the struct are defined in u-boot and you can reuse that one, I think.

Regards Michael

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
  2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
  2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
@ 2008-07-07  7:21 ` Markus Klotzbücher
  2008-07-10 15:00 ` Markus Klotzbücher
  2 siblings, 0 replies; 12+ messages in thread
From: Markus Klotzbücher @ 2008-07-07  7:21 UTC (permalink / raw)
  To: u-boot

Hi Tor,

Tor Krill <tor@excito.com> writes:

> Add high speed support to USB code. Extracted from Juniper Networks patch.
>
> I know that the mergewindow is closed but wanted to get feedback on these
> patches if possible.

Thanks for the patches! I just got back from holiday, so it'll take a
couple of days for reviewing.

Thank you for your patience.

Viele Gr??e / Best regards

Markus Klotzb?cher

--
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
  2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
  2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
  2008-07-07  7:21 ` [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Markus Klotzbücher
@ 2008-07-10 15:00 ` Markus Klotzbücher
  2008-07-10 15:22   ` Tor Krill
  2 siblings, 1 reply; 12+ messages in thread
From: Markus Klotzbücher @ 2008-07-10 15:00 UTC (permalink / raw)
  To: u-boot

Hi Tor,

Tor Krill <tor@excito.com> writes:

> Add high speed support to USB code. Extracted from Juniper Networks patch.
>
> I know that the mergewindow is closed but wanted to get feedback on these
> patches if possible.

Thanks again for fixing this up. AFAIK patches look fine, only two
 things:

- please address the issues pointed out by Michael, especially removal
  of the "C" macro.

- Secondly it would be nice if we could have a short README.ehci or
  similar which explains what works and what not, and what needs to be
  done to add further board/HC support.

Thank you in advance.

Best regards

Markus Klotzb?cher

--
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
  2008-07-10 15:00 ` Markus Klotzbücher
@ 2008-07-10 15:22   ` Tor Krill
  2008-09-03  7:02     ` [U-Boot] " Markus Klotzbücher
  0 siblings, 1 reply; 12+ messages in thread
From: Tor Krill @ 2008-07-10 15:22 UTC (permalink / raw)
  To: u-boot




On 7/10/2008, "Markus Klotzb?cher" <mk@denx.de> wrote:

>Hi Tor,

Hi Markus,

>Tor Krill <tor@excito.com> writes:
>
>> Add high speed support to USB code. Extracted from Juniper Networks patch.
>>
>> I know that the mergewindow is closed but wanted to get feedback on these
>> patches if possible.
>
>Thanks again for fixing this up. AFAIK patches look fine, only two
> things:
>
>- please address the issues pointed out by Michael, especially removal
>  of the "C" macro.
>
>- Secondly it would be nice if we could have a short README.ehci or
>  similar which explains what works and what not, and what needs to be
>  done to add further board/HC support.
>
>Thank you in advance.

Thank you for reviewing. I will try fix things up and resubmit later.

Best Regards,

/Tor

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code.
  2008-07-10 15:22   ` Tor Krill
@ 2008-09-03  7:02     ` Markus Klotzbücher
  0 siblings, 0 replies; 12+ messages in thread
From: Markus Klotzbücher @ 2008-09-03  7:02 UTC (permalink / raw)
  To: u-boot

Hi Tor,

On Thu, Jul 10, 2008 at 05:22:18PM +0200, Tor Krill wrote:
> On 7/10/2008, "Markus Klotzb?cher" <mk@denx.de> wrote:
> >Tor Krill <tor@excito.com> writes:
> >
> >> Add high speed support to USB code. Extracted from Juniper Networks patch.
> >>
> >> I know that the mergewindow is closed but wanted to get feedback on these
> >> patches if possible.
> >
> >Thanks again for fixing this up. AFAIK patches look fine, only two
> > things:
> >
> >- please address the issues pointed out by Michael, especially removal
> >  of the "C" macro.
> >
> >- Secondly it would be nice if we could have a short README.ehci or
> >  similar which explains what works and what not, and what needs to be
> >  done to add further board/HC support.
> >
> >Thank you in advance.
> 
> Thank you for reviewing. I will try fix things up and resubmit
> later.

Any news about this? I'd very much like to get your patches merged...

Best regards
Markus Klotzb?cher

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de")

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality
       [not found]   ` <49267DEB.5020903@gandalf.sssup.it>
@ 2008-11-25  8:20     ` Remy Bohmer
       [not found]     ` <20081125083937.GA10745@x61.spaceport9>
  1 sibling, 0 replies; 12+ messages in thread
From: Remy Bohmer @ 2008-11-25  8:20 UTC (permalink / raw)
  To: u-boot

Hello Michael,

> I have redone the patch. What do you think?
> I can't test them. They compile.

Besides the not-tested part I replied to you about yesterday, can you
please post these patches in the proper format. (inlined, signed-off
etc)
See http://www.denx.de/wiki/U-Boot/Patches

Kind Regards,

Remy

>
> Regards Michael
>
>
> -------------------------------------------------------------------------
> This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
> Build the coolest Linux based applications with Moblin SDK & win great
> prizes
> Grand prize is a trip for two to an Open Source event anywhere in the world
> http://moblin-contest.org/redirect.php?banner_id=100&url=/
> _______________________________________________
> U-Boot-Users mailing list
> U-Boot-Users at lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/u-boot-users
>
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 2/4][RFC] Add ehci core functionality
       [not found]       ` <492BE407.7030309@gandalf.sssup.it>
@ 2008-11-25 12:12         ` Wolfgang Denk
  2008-11-25 12:22           ` michael
  0 siblings, 1 reply; 12+ messages in thread
From: Wolfgang Denk @ 2008-11-25 12:12 UTC (permalink / raw)
  To: u-boot

Dear michael,

In message <492BE407.7030309@gandalf.sssup.it> you wrote:
> SGksCgpNYXJrdXMgS2xvdHpiw7xjaGVyIHdyb3RlOgo+IE9uIEZyaSwgTm92IDIxLCAyMDA4IGF0
> IDEwOjIyOjUxQU0gKzAxMDAsIG1pY2hhZWwgd3JvdGU6Cj4gICAKPj4gSGksCj4+Cj4+IEkgaGF2
> ZSByZWRvbmUgdGhlIHBhdGNoLiBXaGF0IGRvIHlvdSB0aGluaz8KPj4KPj4gSSBjYW4ndCB0ZXN0
> IHRoZW0uIFRoZXkgY29tcGlsZS4KPj4gICAgIAo+Cj4gTm90IGZvciBtZSAoYm9hcmQgaXMgc2Vx
> dW9pYSk6Cj4KPiBtYWtlIC1DIGNvbW1vbi8KPiBtYWtlWzFdOiBFbnRlcmluZyBkaXJlY3Rvcnkg
> YC9ob21lL21rL3NyYy9naXQvdS1ib290L2NvbW1vbicKPiBwcGNfNHh4RlAtZ2NjIC1nICAtT3Mg
> ICAtZlBJQyAtZmZpeGVkLXIxNCAtbWVhYmkgLWZuby1zdHJpY3QtYWxpYXNpbmcgLURfX0tFUk5F
> TF9fIC1EVEVYVF9CQVNFPTB4RkZGQTAwMDAgLUkvaG9tZS9tay9zcmMvZ2l0L3UtYm9vdC9pbmNs
> dWRlIC1mbm8tYnVpbHRpbiAtZmZyZWVzdGFuZGluZyAtbm9zdGRpbmMgLWlzeXN0ZW0gL2hvbWUv
> bWsvZWxka3MvZWxkay00LjIvdXNyL2Jpbi8uLi9saWIvZ2NjL3Bvd2VycGMtbGludXgvNC4yLjIv
> aW5jbHVkZSAtcGlwZSAgLURDT05GSUdfUFBDIC1EX19wb3dlcnBjX18gLURDT05GSUdfNHh4IC1m
> Zml4ZWQtcjIgLW1zdHJpbmcgLW1zb2Z0LWZsb2F0IC1XYSwtbTQ0MCAtbWNwdT00NDAgLURDT05G
> SUdfNDQwPTEgLVdhbGwgLVdzdHJpY3QtcHJvdG90eXBlcyAtZm5vLXN0YWNrLXByb3RlY3RvciAt
> YyAtbyB1c2IubyB1c2IuYwo+IHVzYi5jOiBJbiBmdW5jdGlvbiAndXNiX2h1Yl9wb3J0X2Nvbm5l
> Y3RfY2hhbmdlJzoKPiB1c2IuYzoxMTI5OiBlcnJvcjogJ3N0cnVjdCB1c2JfZGV2aWNlJyBoYXMg
> bm8gbWVtYmVyIG5hbWVkICdzbG93Jwo+IG1ha2VbMV06ICoqKiBbdXNiLm9dIEVycm9yIDEKPiBt
> YWtlWzFdOiBUYXJnZXQgYGFsbCcgbm90IHJlbWFkZSBiZWNhdXNlIG9mIGVycm9ycy4KPgo+IEJl
> c3QgcmVnYXJkcwo+IE1hcmt1cwo+Cj4gICAKCkNhbiB5b3UgcGxlYXNlIHNlbmQgeW91ciBjb25m
> aWd1cmF0aW9uPwoKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
> LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KVGhpcyBTRi5OZXQgZW1haWwgaXMgc3BvbnNv
> cmVkIGJ5IHRoZSBNb2JsaW4gWW91ciBNb3ZlIERldmVsb3BlcidzIGNoYWxsZW5nZQpCdWlsZCB0
> aGUgY29vbGVzdCBMaW51eCBiYXNlZCBhcHBsaWNhdGlvbnMgd2l0aCBNb2JsaW4gU0RLICYgd2lu
> IGdyZWF0IHByaXplcwpHcmFuZCBwcml6ZSBpcyBhIHRyaXAgZm9yIHR3byB0byBhbiBPcGVuIFNv
> dXJjZSBldmVudCBhbnl3aGVyZSBpbiB0aGUgd29ybGQKaHR0cDovL21vYmxpbi1jb250ZXN0Lm9y
> Zy9yZWRpcmVjdC5waHA/YmFubmVyX2lkPTEwMCZ1cmw9LwpfX19fX19fX19fX19fX19fX19fX19f
> X19fX19fX19fX19fX19fX19fX19fX19fXwpVLUJvb3QtVXNlcnMgbWFpbGluZyBsaXN0ClUtQm9v
> dC1Vc2Vyc0BsaXN0cy5zb3VyY2Vmb3JnZS5uZXQKaHR0cHM6Ly9saXN0cy5zb3VyY2Vmb3JnZS5u
> ZXQvbGlzdHMvbGlzdGluZm8vdS1ib290LXVzZXJzCg==

Please stop posting base64 encoded stuff. Send plain text only.

And please stop sending to the old sourceforge list. The mailing list
address is u-boot at lists.denx.de

> Markus Klotzb?cher wrote:
...
> > Not for me (board is sequoia):
...
>Can you please send your configuration?

Markus explicitely mentioned that he was using the "sequoia" board
configuration. What else would you need?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
You don't need a weatherman to know which way the wind blows.
                                                          - Bob Dylan

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [U-Boot] [PATCH 2/4][RFC] Add ehci core functionality
  2008-11-25 12:12         ` [U-Boot] " Wolfgang Denk
@ 2008-11-25 12:22           ` michael
  0 siblings, 0 replies; 12+ messages in thread
From: michael @ 2008-11-25 12:22 UTC (permalink / raw)
  To: u-boot

Wolfgang Denk wrote:
> Dear michael,
>
>> Can you please send your configuration?
>   
> Markus explicitely mentioned that he was using the "sequoia" board
> configuration. What else would you need?
>
>   
Ok, I read a lot of mail, and I'm preparing a clean patch set. I'm sorry 
Markus.

> Best regards,
>
> Wolfgang Denk
>
>   
Regards Michael

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2008-11-25 12:22 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-06-23 11:24 [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Tor Krill
2008-06-23 11:24 ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality Tor Krill
2008-06-23 11:24   ` [U-Boot-Users] [PATCH 3/4][RFC] Add ehci support for Freescale 83xx Tor Krill
2008-06-23 11:24     ` [U-Boot-Users] [PATCH 4/4][RFC] ReAdd extracted Juniper Networks PCI hcd driver Tor Krill
2008-06-23 12:59   ` [U-Boot-Users] [PATCH 2/4][RFC] Add ehci core functionality michael
     [not found]   ` <49267DEB.5020903@gandalf.sssup.it>
2008-11-25  8:20     ` [U-Boot] " Remy Bohmer
     [not found]     ` <20081125083937.GA10745@x61.spaceport9>
     [not found]       ` <492BE407.7030309@gandalf.sssup.it>
2008-11-25 12:12         ` [U-Boot] " Wolfgang Denk
2008-11-25 12:22           ` michael
2008-07-07  7:21 ` [U-Boot-Users] [PATCH 1/4][RFC] Add initial high speed support to USB code Markus Klotzbücher
2008-07-10 15:00 ` Markus Klotzbücher
2008-07-10 15:22   ` Tor Krill
2008-09-03  7:02     ` [U-Boot] " Markus Klotzbücher

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox