first adaption of 'usbport' by Benedikt Sauter
authorBernhard Urban <lewurm@gmx.net>
Wed, 16 Sep 2009 00:29:08 +0000 (02:29 +0200)
committerBernhard Urban <lewurm@gmx.net>
Wed, 16 Sep 2009 00:29:08 +0000 (02:29 +0200)
see http://www.embedded-projects.net/index.php?page_id=186

35 files changed:
Makefile
irq.c
main.c
ohci.c [deleted file]
ohci.h [deleted file]
usb/AUTHORS [new file with mode: 0644]
usb/COPYING [new file with mode: 0644]
usb/Makefile [new file with mode: 0644]
usb/README [new file with mode: 0644]
usb/core/README [new file with mode: 0644]
usb/core/core.c [new file with mode: 0644]
usb/core/core.h [new file with mode: 0644]
usb/core/usb.c [new file with mode: 0644]
usb/core/usb.h [new file with mode: 0644]
usb/drivers/class/hub.c [new file with mode: 0644]
usb/drivers/class/hub.h [new file with mode: 0644]
usb/drivers/class/storage.c [new file with mode: 0644]
usb/drivers/class/storage.h [new file with mode: 0644]
usb/drivers/mon/mon.c [new file with mode: 0644]
usb/drivers/mon/mon.h [new file with mode: 0644]
usb/drivers/skeleton.c [new file with mode: 0644]
usb/host/at90usb1287-hcd.c [new file with mode: 0644]
usb/host/at90usb1287.h [new file with mode: 0644]
usb/host/host.h [new file with mode: 0644]
usb/host/ohci.c [new file with mode: 0644]
usb/host/ohci.h [new file with mode: 0644]
usb/host/sl811hs-hcd.c [new file with mode: 0644]
usb/host/sl811hs.h [new file with mode: 0644]
usb/lib/list.c [new file with mode: 0644]
usb/lib/list.h [new file with mode: 0644]
usb/uclibusb/ft232.c [new file with mode: 0644]
usb/uclibusb/ft232.h [new file with mode: 0644]
usb/usbspec/request.c [new file with mode: 0644]
usb/usbspec/request.h [new file with mode: 0644]
usb/usbspec/usb11spec.h [new file with mode: 0644]

index ef1414ae3eae34b82a91897ec657b625fc6cec25..98118622caf38de90946a189b7d06aef8f676451 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,9 @@ TARGET = ppcboot.elf
 OBJS = realmode.o crt0.o main.o string.o sync.o time.o printf.o input.o \
        exception.o exception_2200.o malloc.o gecko.o video_low.o \
        ipc.o mini_ipc.o nandfs.o ff.o diskio.o fat.o font.o console.o \
-       ohci.o irq.o
+       irq.o
+
+include usb/Makefile
 
 include common.mk
 
diff --git a/irq.c b/irq.c
index c37240c1fa401107ef5717fa021056b0cca0527a..4f15bb8b9f4e63e5f8114954125f3f043bf1c5f7 100644 (file)
--- a/irq.c
+++ b/irq.c
@@ -14,7 +14,7 @@ Copyright (C) 2009                    Andre Heider "dhewg" <dhewg@wiibrew.org>
 #include "hollywood.h"
 #include "ipc.h"
 #include "bootmii_ppc.h"
-#include "ohci.h"
+#include "usb/host/host.h"
 
 void irq_initialize(void)
 {
@@ -111,7 +111,7 @@ void irq_handler(void)
                        //sdhc_irq();
                }
                if (hw_flags & IRQF_OHCI0) {
-                       ohci0_irq();
+                       hcdi_irq();
                        write32(HW_PPCIRQFLAG, IRQF_OHCI0);
                }
                if (hw_flags & IRQF_OHCI1) {
diff --git a/main.c b/main.c
index c8193f4b874b9e33252975a505b19357808f848d..bbb7d39c9c81b72da7091708cbcdac569cb1a92f 100644 (file)
--- a/main.c
+++ b/main.c
@@ -24,8 +24,8 @@ Copyright (C) 2009              John Kelley <wiidev@kelley.ca>
 #include "video_low.h"
 #include "input.h"
 #include "console.h"
-#include "ohci.h"
 #include "irq.h"
+#include "usb/core/core.h"
 
 #define MINIMUM_MINI_VERSION 0x00010001
 
@@ -100,7 +100,7 @@ int main(void)
        VIDEO_SetFrameBuffer(get_xfb());
        VISetupEncoder();
 
-       ohci_init();
+       usb_init();
 
        u32 version = ipc_getvers();
        u16 mini_version_major = version >> 16 & 0xFFFF;
diff --git a/ohci.c b/ohci.c
deleted file mode 100644 (file)
index 7e61a8f..0000000
--- a/ohci.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-       ppcskel - a Free Software replacement for the Nintendo/BroadOn bootloader.
-       ohci hardware support
-
-Copyright (C) 2009     Bernhard Urban <lewurm@gmx.net>
-Copyright (C) 2009     Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
-
-# This code is licensed to you under the terms of the GNU GPL, version 2;
-# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
-*/
-
-#include "bootmii_ppc.h"
-#include "hollywood.h"
-#include "ohci.h"
-#include "irq.h"
-#include "string.h"
-
-static struct ohci_hcca hcca_oh0;
-
-static void dbg_op_state() 
-{
-       switch (read32(OHCI0_HC_CONTROL) & OHCI_CTRL_HCFS) {
-               case OHCI_USB_SUSPEND:
-                       printf("ohci-- OHCI_USB_SUSPEND\n");
-                       break;
-               case OHCI_USB_RESET:
-                       printf("ohci-- OHCI_USB_RESET\n");
-                       break;
-               case OHCI_USB_OPER:
-                       printf("ohci-- OHCI_USB_OPER\n");
-                       break;
-               case OHCI_USB_RESUME:
-                       printf("ohci-- OHCI_USB_RESUME\n");
-                       break;
-       }
-}
-
-void ohci_init() 
-{
-       printf("ohci-- init\n");
-       dbg_op_state();
-
-       /* disable hc interrupts */
-       set32(OHCI0_HC_INT_DISABLE, OHCI_INTR_MIE);
-
-       /* save fmInterval and calculate FSMPS */
-#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7))
-#define FI 0x2edf /* 12000 bits per frame (-1) */
-       u32 fmint = read32(OHCI0_HC_FM_INTERVAL) & 0x3fff;
-       if(fmint != FI)
-               printf("ohci-- fminterval delta: %d\n", fmint - FI);
-       fmint |= FSMP (fmint) << 16;
-
-       /* enable interrupts of both usb host controllers */
-       set32(EHCI_CTL, EHCI_CTL_OH0INTE | EHCI_CTL_OH1INTE | 0xe0000);
-
-       /* reset HC */
-       write32(OHCI0_HC_COMMAND_STATUS, OHCI_HCR);
-
-       /* wait max. 30us */
-       u32 ts = 30;
-       while ((read32(OHCI0_HC_COMMAND_STATUS) & OHCI_HCR) != 0) {
-                if(--ts == 0) {
-                       printf("ohci-- FAILED");
-                       return;
-                }
-                udelay(1);
-       }
-
-       /* disable interrupts; 2ms timelimit here! 
-          now we're in the SUSPEND state ... must go OPERATIONAL
-          within 2msec else HC enters RESUME */
-
-       u32 cookie = irq_kill();
-
-       /* Tell the controller where the control and bulk lists are
-        * The lists are empty now. */
-       write32(OHCI0_HC_CTRL_HEAD_ED, 0);
-       write32(OHCI0_HC_BULK_HEAD_ED, 0);
-
-       /* set hcca adress */
-       sync_after_write(&hcca_oh0, 256);
-       write32(OHCI0_HC_HCCA, virt_to_phys(&hcca_oh0));
-
-       /* set periodicstart */
-#define FIT (1<<31)
-       u32 fmInterval = read32(OHCI0_HC_FM_INTERVAL) &0x3fff;
-       u32 fit = read32(OHCI0_HC_FM_INTERVAL) & FIT;
-
-       write32(OHCI0_HC_FM_INTERVAL, fmint | (fit ^ FIT));
-       write32(OHCI0_HC_PERIODIC_START, ((9*fmInterval)/10)&0x3fff);
-
-       /* testing bla */
-       if ((read32(OHCI0_HC_FM_INTERVAL) & 0x3fff0000) == 0 || !read32(OHCI0_HC_PERIODIC_START)) {
-               printf("ohci-- w00t, fail!! see ohci-hcd.c:669\n");
-       }
-       
-       /* start HC operations */
-       write32(OHCI0_HC_CONTROL, OHCI_CONTROL_INIT | OHCI_USB_OPER);
-
-       /* wake on ConnectStatusChange, matching external hubs */
-       set32(OHCI0_HC_RH_STATUS, RH_HS_DRWE);
-
-       /* Choose the interrupts we care about now, others later on demand */
-       write32(OHCI0_HC_INT_STATUS, ~0);
-       write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_INIT);
-
-       irq_restore(cookie);
-
-       dbg_op_state();
-}
-
-void ohci0_irq() 
-{
-       /* read interrupt status */
-       u32 flags = read32(OHCI0_HC_INT_STATUS);
-
-       /* when all bits are set to 1 some problem occured */
-       if (flags == 0xffffffff) {
-               printf("ohci-- Houston, we have a serious problem! :(\n");
-               return;
-       }
-
-       /* only care about interrupts that are enabled */
-       flags &= read32(OHCI0_HC_INT_ENABLE);
-
-       /* nothing to do? */
-       if (flags == 0)
-               return;
-
-       printf("OHCI Interrupt occured: ");
-       /* UnrecoverableError */
-       if (flags & OHCI_INTR_UE) {
-               printf("UnrecoverableError\n");
-               /* TODO: well, I don't know... nothing,
-                *       because it won't happen anyway? ;-) */
-       }
-
-       /* RootHubStatusChange */
-       if (flags & OHCI_INTR_RHSC) {
-               printf("RootHubStatusChange\n");
-               /* TODO: set some next_statechange variable... */
-               write32(OHCI0_HC_INT_STATUS, OHCI_INTR_RD | OHCI_INTR_RHSC);
-       }
-       /* ResumeDetected */
-       else if (flags & OHCI_INTR_RD) {
-               printf("ResumeDetected\n");
-               write32(OHCI0_HC_INT_STATUS, OHCI_INTR_RD);
-               /* TODO: figure out what the linux kernel does here... */
-       }
-
-       /* WritebackDoneHead */
-       if (flags & OHCI_INTR_WDH) {
-               printf("WritebackDoneHead\n");
-               /* TODO: figure out what the linux kernel does here... */
-       }
-
-       /* TODO: handle any pending URB/ED unlinks... */
-
-#define HC_IS_RUNNING() 1 /* dirty, i know... just a temporary solution */
-       if (HC_IS_RUNNING()) {
-               write32(OHCI0_HC_INT_STATUS, flags);
-               write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_MIE);
-       }
-}
-
diff --git a/ohci.h b/ohci.h
deleted file mode 100644 (file)
index e528d58..0000000
--- a/ohci.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
-       ppcskel - a Free Software replacement for the Nintendo/BroadOn bootloader.
-       ohci hardware support
-
-Copyright (C) 2009     Bernhard Urban <lewurm@gmx.net>
-Copyright (C) 2009     Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
-
-# This code is licensed to you under the terms of the GNU GPL, version 2;
-# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
-*/
-
-#ifndef __OHCI_H__
-#define __OHCI_H__
-
-#include "types.h"
-
-/* stolen from drivers/usb/host/ohci.h (linux-kernel) :) */
-
-/* OHCI CONTROL AND STATUS REGISTER MASKS */
-
-/*
- * HcControl (control) register masks
- */
-#define OHCI_CTRL_CBSR (3 << 0)        /* control/bulk service ratio */
-#define OHCI_CTRL_PLE  (1 << 2)        /* periodic list enable */
-#define OHCI_CTRL_IE   (1 << 3)        /* isochronous enable */
-#define OHCI_CTRL_CLE  (1 << 4)        /* control list enable */
-#define OHCI_CTRL_BLE  (1 << 5)        /* bulk list enable */
-#define OHCI_CTRL_HCFS (3 << 6)        /* host controller functional state */
-#define OHCI_CTRL_IR   (1 << 8)        /* interrupt routing */
-#define OHCI_CTRL_RWC  (1 << 9)        /* remote wakeup connected */
-#define OHCI_CTRL_RWE  (1 << 10)       /* remote wakeup enable */
-
-/* pre-shifted values for HCFS */
-#define OHCI_USB_RESET (0 << 6)
-#define OHCI_USB_RESUME        (1 << 6)
-#define OHCI_USB_OPER  (2 << 6)
-#define OHCI_USB_SUSPEND       (3 << 6)
-
-/*
- * HcCommandStatus (cmdstatus) register masks
- */
-#define OHCI_HCR       (1 << 0)        /* host controller reset */
-#define OHCI_CLF       (1 << 1)        /* control list filled */
-#define OHCI_BLF       (1 << 2)        /* bulk list filled */
-#define OHCI_OCR       (1 << 3)        /* ownership change request */
-#define OHCI_SOC       (3 << 16)       /* scheduling overrun count */
-
-/*
- * masks used with interrupt registers:
- * HcInterruptStatus (intrstatus)
- * HcInterruptEnable (intrenable)
- * HcInterruptDisable (intrdisable)
- */
-#define OHCI_INTR_SO   (1 << 0)        /* scheduling overrun */
-#define OHCI_INTR_WDH  (1 << 1)        /* writeback of done_head */
-#define OHCI_INTR_SF   (1 << 2)        /* start frame */
-#define OHCI_INTR_RD   (1 << 3)        /* resume detect */
-#define OHCI_INTR_UE   (1 << 4)        /* unrecoverable error */
-#define OHCI_INTR_FNO  (1 << 5)        /* frame number overflow */
-#define OHCI_INTR_RHSC (1 << 6)        /* root hub status change */
-#define OHCI_INTR_OC   (1 << 30)       /* ownership change */
-#define OHCI_INTR_MIE  (1 << 31)       /* master interrupt enable */
-
-/*
- * masks used with interrupt registers:
- * HcInterruptStatus (intrstatus)
- * HcInterruptEnable (intrenable)
- * HcInterruptDisable (intrdisable)
- */
-#define OHCI_INTR_SO   (1 << 0)        /* scheduling overrun */
-#define OHCI_INTR_WDH  (1 << 1)        /* writeback of done_head */
-#define OHCI_INTR_SF   (1 << 2)        /* start frame */
-#define OHCI_INTR_RD   (1 << 3)        /* resume detect */
-#define OHCI_INTR_UE   (1 << 4)        /* unrecoverable error */
-#define OHCI_INTR_FNO  (1 << 5)        /* frame number overflow */
-#define OHCI_INTR_RHSC (1 << 6)        /* root hub status change */
-#define OHCI_INTR_OC   (1 << 30)       /* ownership change */
-#define OHCI_INTR_MIE  (1 << 31)       /* master interrupt enable */
-
-
-/* For initializing controller (mask in an HCFS mode too) */
-#define OHCI_CONTROL_INIT      (3 << 0)
-#define        OHCI_INTR_INIT \
-               (OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE \
-               | OHCI_INTR_RD | OHCI_INTR_WDH)
-
-/* OHCI ROOT HUB REGISTER MASKS */
-
-/* roothub.portstatus [i] bits */
-#define RH_PS_CCS            0x00000001                /* current connect status */
-#define RH_PS_PES            0x00000002                /* port enable status*/
-#define RH_PS_PSS            0x00000004                /* port suspend status */
-#define RH_PS_POCI           0x00000008                /* port over current indicator */
-#define RH_PS_PRS            0x00000010                /* port reset status */
-#define RH_PS_PPS            0x00000100                /* port power status */
-#define RH_PS_LSDA           0x00000200                /* low speed device attached */
-#define RH_PS_CSC            0x00010000                /* connect status change */
-#define RH_PS_PESC           0x00020000                /* port enable status change */
-#define RH_PS_PSSC           0x00040000                /* port suspend status change */
-#define RH_PS_OCIC           0x00080000                /* over current indicator change */
-#define RH_PS_PRSC           0x00100000                /* port reset status change */
-
-/* roothub.status bits */
-#define RH_HS_LPS           0x00000001         /* local power status */
-#define RH_HS_OCI           0x00000002         /* over current indicator */
-#define RH_HS_DRWE          0x00008000         /* device remote wakeup enable */
-#define RH_HS_LPSC          0x00010000         /* local power status change */
-#define RH_HS_OCIC          0x00020000         /* over current indicator change */
-#define RH_HS_CRWE          0x80000000         /* clear remote wakeup enable */
-
-/* roothub.b masks */
-#define RH_B_DR                0x0000ffff              /* device removable flags */
-#define RH_B_PPCM      0xffff0000              /* port power control mask */
-
-/* roothub.a masks */
-#define        RH_A_NDP        (0xff << 0)             /* number of downstream ports */
-#define        RH_A_PSM        (1 << 8)                /* power switching mode */
-#define        RH_A_NPS        (1 << 9)                /* no power switching */
-#define        RH_A_DT         (1 << 10)               /* device type (mbz) */
-#define        RH_A_OCPM       (1 << 11)               /* over current protection mode */
-#define        RH_A_NOCP       (1 << 12)               /* no over current protection */
-#define        RH_A_POTPGT     (0xff << 24)            /* power on to power good time */
-
-struct ohci_hcca {
-#define NUM_INITS 32
-       u32 int_table[NUM_INITS]; /* periodic schedule */
-       /*
-        * OHCI defines u16 frame_no, followed by u16 zero pad.
-        * Since some processors can't do 16 bit bus accesses,
-        * portable access must be a 32 bits wide.
-        */
-       u32     frame_no;               /* current frame number */
-       u32     done_head;              /* info returned for an interrupt */
-       u8 reserved_for_hc [116];
-       u8 what [4];            /* spec only identifies 252 bytes :) */
-} ALIGNED(256);
-
-void ohci_init(void);
-void ohci0_irq(void);
-
-#endif
diff --git a/usb/AUTHORS b/usb/AUTHORS
new file mode 100644 (file)
index 0000000..e166255
--- /dev/null
@@ -0,0 +1 @@
+Benedikt Sauter, sauter@ixbat.de
diff --git a/usb/COPYING b/usb/COPYING
new file mode 100644 (file)
index 0000000..b04f484
--- /dev/null
@@ -0,0 +1,28 @@
+Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions 
+are met:
+
+    * Redistributions of source code must retain the above copyright 
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above 
+      copyright notice, this list of conditions and the following 
+      disclaimer in the documentation and/or other materials provided 
+      with the distribution.
+    * Neither the name of the FH Augsburg nor the names of its 
+      contributors may be used to endorse or promote products derived 
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/usb/Makefile b/usb/Makefile
new file mode 100644 (file)
index 0000000..4ee16a6
--- /dev/null
@@ -0,0 +1,7 @@
+#tmp...
+CFLAGS += -Wno-unused-parameter 
+
+OBJS += usb/host/ohci.o usb/core/core.o usb/core/usb.o \
+               usb/lib/list.o usb/usbspec/request.o \
+               usb/drivers/class/hub.o \
+               usb/drivers/class/storage.o
diff --git a/usb/README b/usb/README
new file mode 100644 (file)
index 0000000..0e0304d
--- /dev/null
@@ -0,0 +1,33 @@
+usbport host is an open source, highly portable USB-Stack
+for memory- and cpu-constrained embedded systems written
+by Benedikt Sauter in his thesis at FH Augsburg University
+for Applied Science.
+
+usbport host is designed for embedded systems with small amounts of
+memory. A typical USBene configuration is 200 kilobytes of RAM and 
+4 kilobytes of Code-Memory. USBene consists provides
+own layers for the different USB parts. Drivers can be load
+dynamically and unloaded at runtime.
+
+usbport host runs on a variety of platform ranging from embedded
+microcontrollers such as ARM7/9 derivates and the AVR to old
+homecomputers. Code footprint is on the order of kilobytes and memory
+usage can be configured to be as low as tens of bytes.
+
+usbport host is written in the C programming language and is freely
+available as open source under a BSD-style license. More information
+about USBene can be found at the usbport host home page:
+http://www.usb-projects.de/opus
+
+Directory:
+
+arch         Beispielimplementierungen für verschiedene Mikrocontroller 
+boards       Schaltplan, Platinenlayout, etc. für die Testplatine
+core         USB-Kern-Funktionen
+doc          Diplomarbeit als Beschreibung 
+drivers              USB-Treiber (Geräte und Klassen) 
+host         Host-Controller-Treiber 
+lib          Zusatzfunktionen, Typendefinitionen, etc. 
+uclibusb      USB-Bibliotheken für USB-Geräte 
+usbspec              Datentypen und -formate der USB-Spezifikation
+
diff --git a/usb/core/README b/usb/core/README
new file mode 100644 (file)
index 0000000..6f4df70
--- /dev/null
@@ -0,0 +1,5 @@
+USB Subsystem
+
+
+
+
diff --git a/usb/core/core.c b/usb/core/core.c
new file mode 100644 (file)
index 0000000..a66df30
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#include <stdlib.h>
+#include "core.h"
+#include "../host/host.h"
+#include "usb.h"
+#include "../usbspec/usb11spec.h"
+#include "../lib/list.h"
+#include "../../malloc.h"
+
+/**
+ * Initialize USB stack.
+ */
+void usb_init()
+{
+  core.drivers = list_create();
+  core.devices = list_create();
+  core.nextaddress = 1;
+  hcdi_init();
+}
+
+/**
+ * Get next free usb device address.
+ */
+u8 usb_next_address()
+{
+  u8 addr = core.nextaddress;
+  core.nextaddress++;
+  return addr;
+}
+
+
+/**
+ * Call this function periodically for 
+ * control and transfer management.
+ */
+void usb_periodic()
+{
+  // call ever registered driver  
+  usb_driver *drv;
+  element *iterator = core.drivers->head;
+  while (iterator != NULL) {
+    drv = (usb_driver *) iterator->data;
+    drv->check();
+    iterator = iterator->next;
+  }
+}
+
+
+/** 
+ * Enumerate new device and create data structures 
+ * for the core. usb_add_device expected that
+ * the device answers to address zero.
+ */
+usb_device *usb_add_device()
+{
+  usb_device *dev = (usb_device *) malloc(sizeof(usb_device));
+  dev->address = 0;
+  dev->bMaxPacketSize0 = 8;     /* send at first time only 8 bytes */
+
+  dev->epSize[0] = 64;
+  dev->epSize[1] = 64;
+  dev->epSize[2] = 64;
+
+  dev->epTogl[0] = 0;
+  dev->epTogl[1] = 0;
+  dev->epTogl[2] = 0;
+
+  char buf[64];
+  u8 devdescr_size;
+  u8 address = usb_next_address();
+
+  /* ask first 8 bytes of device descriptor with this special 
+   * GET Descriptor Request, when device address = 0
+   */
+  usb_control_msg(dev, 0x80, GET_DESCRIPTOR, 1, 0, 64, buf, 8, 0);
+
+  dev->bMaxPacketSize0 = (u8) buf[7];   /* setup real ep0 fifo size */
+  devdescr_size = (u8) buf[0];  /* save real length of device descriptor */
+
+  /* define new adress */
+  usb_control_msg(dev, 0x00, SET_ADDRESS, address << 8, 0, 0, buf, 8, 0);
+  dev->address = address;
+
+  /* get complete device descriptor */
+  usb_control_msg(dev, 0x80, GET_DESCRIPTOR, 1, 0, devdescr_size, buf, 8,
+                  0);
+
+  /* save only really neccessary values for this small usbstack */
+  dev->bDeviceClass = (u8) buf[4];
+  dev->bDeviceSubClass = (u8) buf[5];
+  dev->bDeviceProtocoll = (u8) buf[6];
+  dev->idVendor = (u16) (buf[9] << 8) | (buf[8]);
+  dev->idProduct = (u16) (buf[11] << 8) | (buf[10]);
+  dev->bcdDevice = (u16) (buf[13] << 8) | (buf[12]);
+
+  // string descriptoren werden nicht im arbeitsspeicher gehalten -> on demand mit 
+  // entprechenden funktionen
+  // hier muss man noch mehr abholen, konfigurationene, interfaces und endpunkte
+
+  /* add device to device list */
+  element *tmp = (element *) malloc(sizeof(element));
+  tmp->data = (void *) dev;
+  list_add_tail(core.devices, tmp);
+
+  usb_probe_driver();
+
+  return dev;
+}
+
+/**
+ * Find currently detached device and remove
+ * data structures
+ */
+u8 usb_remove_device(usb_device * dev)
+{
+  // FIXME!!!! dieser quatsch ist nur temporaer
+  free(core.devices->head);
+  free(core.devices);
+  core.devices = list_create();
+  return 1;
+}
+
+/**
+ * Register new driver at usb stack.
+ */
+u8 usb_register_driver(usb_driver * dev)
+{
+  /* add driver to driver list */
+  element *tmp = (element *) malloc(sizeof(element));
+  tmp->data = (void *) dev;
+  tmp->next = NULL;
+  list_add_tail(core.drivers, tmp);
+
+
+  /** 
+   * first check to find a suitable device 
+   * (root hub drivers need this call here)
+   */
+  dev->probe();
+
+  return 1;
+}
+
+
+/**
+ * Call every probe function from every registered
+ * driver, to check if there is a valid driver
+ * for the new device.  
+ */
+void usb_probe_driver()
+{
+  // call ever registered driver  
+  usb_driver *drv;
+  element *iterator = core.drivers->head;
+  while (iterator != NULL) {
+    drv = (usb_driver *) iterator->data;
+    drv->probe();
+    iterator = iterator->next;
+  }
+}
+
+/**
+ * Not implemented.
+ */
+usb_irp *usb_get_irp()
+{
+  return 0;
+}
+
+/**
+ * Not implemented.
+ */
+u8 usb_remove_irp(usb_irp * irp)
+{
+
+  return 1;
+}
+
+/**
+ * Takes usb_irp and split it into
+ * several usb packeges (SETUP,IN,OUT)
+ * In the usbstack they are transported with the
+ * usb_transfer_descriptor data structure.
+ */
+u16 usb_submit_irp(usb_irp * irp)
+{
+  usb_transfer_descriptor *td;
+  u8 runloop = 1;
+  u16 restlength = irp->len;
+  char *td_buf_ptr = irp->buffer;
+
+  //u8 togl=irp->dev->epTogl[(irp->endpoint & 0x7F)];
+  u8 togl = irp->dev->epTogl[(irp->endpoint & 0x7F)];
+  //u8 togl=0;
+
+  switch (irp->type) {
+  case USB_CTRL:
+
+    /* alle requests mit dem gleichen algorithmus zerteilen
+     * das einzige ist der spezielle get_Device_descriptor request
+     * bei dem eine laenge von 64 angegeben ist.
+     * wenn man an adresse 0 einen get_device_desciptor schickt
+     * dann reichen die ersten 8 byte.
+     */
+
+      /***************** Setup Stage ***********************/
+    td = usb_create_transfer_descriptor(irp);
+    td->pid = USB_PID_SETUP;
+    td->buffer = irp->buffer;
+    td->actlen = 8;             /* control message are always 8 bytes */
+
+    togl = 0;
+    td->togl = togl;            /* start with data0 */
+    if (togl == 0)
+      togl = 1;
+    else
+      togl = 0;
+      /**** send token ****/
+    hcdi_enqueue(td);
+
+      /***************** Data Stage ***********************/
+      /**
+       * You can see at bit 7 of bmRequestType if this stage is used,
+       * default requests are always 8 byte greate, from
+       * host to device. Stage 3 is only neccessary if the request
+       * expected datas from the device.
+       * bit7 - 1 = from device to host -> yes we need data stage
+       * bit7 - 0 = from host to device -> no send zero packet
+       *
+       * nach einem setup token kann nur ein IN token in stage 3 folgen
+       * nie aber ein OUT. Ein Zero OUT wird nur als Bestaetigung benoetigt.
+       *
+       *
+       * bit7 = 1
+       *  Device to Host
+       *  - es kommen noch Daten mit PID_IN an
+       *  - host beendet mit PID_OUT DATA1 Zero
+       * bit7 - 0
+       *  Host zu Device (wie set address)
+       *  - device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
+       */
+    usb_device_request *setup = (usb_device_request *) irp->buffer;
+    u8 bmRequestType = setup->bmRequestType;
+
+    if (bmRequestType & 0x80) { /* check bit 7 of bmRequestType */
+
+      /* schleife die die tds generiert */
+      while (runloop) {
+        td = usb_create_transfer_descriptor(irp);
+        td->actlen = irp->epsize;
+        /* stop loop if all bytes are send */
+        if (restlength <= irp->epsize) {
+          runloop = 0;
+          td->actlen = restlength;
+        }
+
+        td->buffer = td_buf_ptr;
+        /* move pointer for next packet */
+        td_buf_ptr = td_buf_ptr + irp->epsize;
+
+        td->pid = USB_PID_IN;
+        td->togl = togl;
+        if (togl == 0)
+          togl = 1;
+        else
+          togl = 0;
+
+        /* wenn device descriptor von adresse 0 angefragt wird werden nur
+         * die ersten 8 byte abgefragt
+         */
+        if (setup->bRequest == GET_DESCRIPTOR && (setup->wValue >> 8) == 1
+            && td->devaddress == 0) {
+          runloop = 0;          /* stop loop */
+        }
+
+          /**** send token ****/
+        hcdi_enqueue(td);
+
+        /* pruefe ob noch weitere Pakete vom Device abgeholt werden muessen */
+        restlength = restlength - irp->epsize;
+      }
+    }
+
+
+
+
+      /***************** Status Stage ***********************/
+    /* Zero packet for end */
+    td = usb_create_transfer_descriptor(irp);
+    td->togl = 1;               /* zero data packet = always DATA1 packet */
+    td->actlen = 0;
+    td->buffer = NULL;
+
+      /**
+       * bit7 = 1, host beendet mit PID_OUT DATA1 Zero
+       * bit7 = 0, device sendet ein PID_IN DATA1 Zero Packet als bestaetigung
+       */
+    if (bmRequestType & 0x80) { /* check bit 7 of bmRequestType */
+      td->pid = USB_PID_OUT;
+    } else {
+      td->pid = USB_PID_IN;
+    }
+      /**** send token ****/
+    hcdi_enqueue(td);
+    free(td);
+
+
+    break;
+  case USB_BULK:
+
+    core.stdout("bulk\r\n");
+    //u8 runloop=1;
+    //u16 restlength = irp->len;
+    //char * td_buf_ptr=irp->buffer;
+
+    /* schleife die die tds generiert */
+    while (runloop) {
+
+      td = usb_create_transfer_descriptor(irp);
+      td->endpoint = td->endpoint & 0x7F;       /* clear direction bit */
+
+      /* max packet size for given endpoint */
+      td->actlen = irp->epsize;
+
+      /* Generate In Packet  */
+      if (irp->endpoint & 0x80)
+        td->pid = USB_PID_IN;
+      else
+        /* Generate Out Packet */
+        td->pid = USB_PID_OUT;
+
+      /* stop loop if all bytes are send */
+      if (restlength <= irp->epsize) {
+        runloop = 0;
+        td->actlen = restlength;
+      }
+
+      td->buffer = td_buf_ptr;
+      /* move pointer for next packet */
+      td_buf_ptr = td_buf_ptr + irp->epsize;
+
+      td->togl = togl;
+      if (togl == 0)
+        togl = 1;
+      else
+        togl = 0;
+        /**** send token ****/
+      hcdi_enqueue(td);
+      free(td);
+    }
+    /* next togl */
+    //if(td->pid == USB_PID_OUT) {
+    //if(togl==0) togl=1; else togl=0;
+    //}
+    irp->dev->epTogl[(irp->endpoint & 0x7F)] = togl;
+
+    break;
+  }
+
+  return 1;
+}
+
+
+
+/** 
+ * Create a transfer descriptor with an parent irp.
+ */
+usb_transfer_descriptor *usb_create_transfer_descriptor(usb_irp * irp)
+{
+  usb_transfer_descriptor *td =
+      (usb_transfer_descriptor *) malloc(sizeof(usb_transfer_descriptor));
+
+  td->devaddress = irp->dev->address;
+  td->endpoint = irp->endpoint;
+  td->iso = 0;
+  td->state = USB_TRANSFER_DESCR_NONE;
+
+  return td;
+}
diff --git a/usb/core/core.h b/usb/core/core.h
new file mode 100644 (file)
index 0000000..143be33
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _CORE_H_
+#define _CORE_H_
+
+#include "../../types.h"
+#include "../lib/list.h"
+
+
+#include "../../bootmii_ppc.h"
+inline static void wait_ms(int ms)
+{
+       int i=0;
+       for(;i<ms;i++)
+               udelay(1000);
+}
+
+/**
+ * Main datastructure of the usbstack, which have to be instanced
+ * in the main application.
+ */
+
+typedef struct usb_device_t usb_device;
+struct usb_device_t {
+  u8  address;
+  u8  fullspeed;
+  u8  bMaxPacketSize0;
+  u8  bDeviceClass;
+  u8  bDeviceSubClass;
+  u8  bDeviceProtocoll;
+  u32 idVendor;
+  u32 idProduct;
+  u32 bcdDevice;
+  u8  bNumConfigurations;
+
+  u8 epSize[16];
+  u8 epTogl[16];
+
+  usb_device *next;
+};
+
+
+typedef struct usb_endpoint_t usb_endpoint;
+struct usb_endpoint_t {
+  u8 type;
+  u8 size;
+  u8 togl;
+  usb_endpoint *next;
+};
+
+
+
+
+typedef struct usb_transfer_descriptor_ep_t usb_transfer_descriptor_ep;
+struct usb_transfer_descriptor_ep_t {
+  usb_transfer_descriptor_ep *next;
+  u8 device_address;
+  u8 endpoint;
+  struct usb_transfer_descriptor_t *start;
+};
+
+/**
+ * USB Driver data structure
+ */
+typedef struct usb_driver_t usb_driver;
+struct usb_driver_t {
+  char* name;
+  void (*probe)(void);
+  void (*check)(void);
+  void * data;
+  usb_driver *next;
+};
+
+
+/**
+ * I/O Request Block
+ */
+
+typedef struct usb_irp_t usb_irp;
+struct usb_irp_t {
+  //u8 devaddress;
+  usb_device * dev;
+  u8 endpoint;             /* ep -> bit 7 is for direction 1=from  dev to host */
+  u8 epsize;
+  u8 type;                 /* control, interrupt, bulk or isochron */
+
+  char * buffer;
+  u16 len;
+
+  //list * td_list;
+  u16 timeout;
+};
+
+
+/**
+ * usb transfer descriptor
+ */
+typedef struct usb_transfer_descriptor_t usb_transfer_descriptor;
+struct usb_transfer_descriptor_t {
+  u8 devaddress;
+  u8 endpoint;
+  
+  // TODO: zusammenfassen!
+  u8 pid;
+  u8 iso;
+  u8 togl;  
+  
+  char * buffer;
+  u16 actlen;
+  
+  u8 state;
+  usb_transfer_descriptor *next;
+};
+
+//typedef struct usb_core_t usb_core;
+struct usb_core_t {
+  u8 nextaddress;
+  void (*stdout)(char * arg); 
+  // driver list
+  list * drivers;
+  list * devices;
+} core;
+
+void usb_init();
+void usb_periodic();
+u8 usb_next_address();
+
+
+usb_device * usb_add_device();
+u8 usb_remove_device(usb_device *dev);
+u8 usb_register_driver(usb_driver *driver);
+void usb_probe_driver();
+
+
+
+usb_irp * usb_get_irp();
+u8 usb_remove_irp(usb_irp *irp);
+u16 usb_submit_irp(usb_irp *irp);
+
+
+usb_transfer_descriptor * usb_create_transfer_descriptor(usb_irp *irp);
+
+
+#define USB_IRP_WAITING          1
+
+
+#define USB_TRANSFER_DESCR_NONE 1
+#define USB_TRANSFER_DESCR_SEND 2
+
+#endif //_CORE_H_
diff --git a/usb/core/usb.c b/usb/core/usb.c
new file mode 100644 (file)
index 0000000..c99ba09
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ * I take the function names and parameters mainly from
+ * libusb.sf.net.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//wtf??!
+//#ifndef _USB_H_
+//#define _USB_H_
+
+//#include <stdlib.h>
+
+#include "usb.h"
+#include "core.h"
+#include "../host/host.h"
+#include "../usbspec/usb11spec.h"
+#include "../../malloc.h"
+
+
+/******************* Device Operations **********************/
+
+/**
+ * Open a device with verndor- and product-id for a communication.
+ */
+usb_device * usb_open(u32 vendor_id, u32 product_id)
+{
+  usb_device* dev;
+  element * iterator = core.devices->head;
+  while(iterator != NULL) {
+    dev = (usb_device*)iterator->data;
+    
+    if(dev->idVendor==vendor_id&&dev->idProduct==product_id)
+      return dev;
+
+    iterator=iterator->next;
+  }
+
+  return NULL;
+}
+
+
+/**
+ * Open a device with an class code for a communication.
+ */
+usb_device * usb_open_class(u8 class)
+{
+  usb_device* dev;
+  element * iterator = core.devices->head;
+  while(iterator != NULL) {
+    dev = (usb_device*)iterator->data;
+    
+    if(dev->bDeviceClass==class)
+      return dev;
+
+    iterator=iterator->next;
+  }
+  return NULL;
+}
+
+/**
+ * Close device after a communication.
+ */
+u8 usb_close(usb_device *dev)
+{
+
+  return 0;
+}
+
+u8 usb_get_device_descriptor(usb_device *dev, char *buf,u8 size)
+{
+
+  return 0;
+}
+
+u8 usb_set_address(usb_device *dev, u8 address)
+{
+
+  return 0;
+}
+
+u8 usb_set_configuration(usb_device *dev, u8 configuration)
+{
+
+  return 0;
+}
+
+u8 usb_set_altinterface(usb_device *dev, u8 alternate)
+{
+
+  return 0;
+}
+
+u8 usb_reset(usb_device *dev)
+{
+
+
+  return 0;
+}
+
+
+/******************* Control Transfer **********************/
+
+/**
+ * Create a control transfer.
+ */
+u8 usb_control_msg(usb_device *dev, u8 requesttype, u8 request, u16 value, u16 index, u16 length,char *buf, u16 size, u16 timeout)
+{
+  usb_irp * irp = (usb_irp*)malloc(sizeof(usb_irp));
+  irp->dev = dev;
+  //irp->devaddress = dev->address;
+  irp->endpoint = 0;
+  
+  irp->epsize = dev->bMaxPacketSize0;
+  irp->type = USB_CTRL;
+
+  buf[0]=(char)requesttype;
+  buf[1]=(char)request;           
+  buf[2]=(char)(value >> 8);
+  buf[3]=(char)(value);          
+  buf[4]=(char)(index >> 8);
+  buf[5]=(char)(index);        
+  // lenght buf are the only where the order is inverted
+  buf[6]=(char)(length);
+  buf[7]=(char)(length >> 8);
+
+  irp->buffer = buf;
+  irp->len = length;
+  irp->timeout = timeout;
+
+  usb_submit_irp(irp);
+  free(irp);
+
+  return 0;
+}
+
+
+u8 usb_get_string(usb_device *dev, u8 index, u8 langid, char *buf, u8 buflen)
+{
+
+  return 0;
+}
+
+
+u8 usb_get_string_simple(usb_device *dev, u8 index, char *buf, u8 buflen)
+{
+
+  return 0;
+}
+
+u8 usb_get_descriptor(usb_device *dev, unsigned char type, unsigned char index, void *buf, u8 size)
+{
+
+  return 0;
+}
+
+
+/******************* Bulk Transfer **********************/
+
+/**
+ * Write to an a bulk endpoint.
+ */
+u8 usb_bulk_write(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout)
+{
+  usb_irp * irp = (usb_irp*)malloc(sizeof(usb_irp));
+  irp->dev = dev;
+  //irp->devaddress = dev->address;
+  
+  irp->endpoint = ep;
+  irp->epsize = dev->epSize[ep]; // ermitteln
+  irp->type = USB_BULK;
+
+  irp->buffer = buf;
+  irp->len = size;
+  irp->timeout = timeout;
+
+  usb_submit_irp(irp);
+  free(irp);
+
+  return 0;
+}
+
+/**
+ * Read from an bulk endpoint.
+ */
+u8 usb_bulk_read(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout)
+{
+  usb_irp * irp = (usb_irp*)malloc(sizeof(usb_irp));
+  //irp->devaddress = dev->address;
+  irp->dev = dev;
+  
+  irp->endpoint = ep | 0x80;  // from device to host
+  irp->epsize = dev->epSize[ep]; // ermitteln
+  irp->type = USB_BULK;
+
+  irp->buffer = buf;
+  irp->len = size;
+  irp->timeout = timeout;
+
+  usb_submit_irp(irp);
+  free(irp);
+
+  return 0;
+}
+
+
+/******************* Interrupt Transfer **********************/
+/**
+ * Write to an interrupt endpoint.
+ */
+u8 usb_interrupt_write(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout)
+{
+
+  return 0;
+}
+
+/**
+ * Read from an interrupt endpoint.
+ */
+u8 usb_interrupt_read(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout)
+{
+
+  return 0;
+}
+
+
+/******************* Isochron Transfer **********************/
+
+/**
+ * Write to an isochron endpoint.
+ */
+u8 usb_isochron_write(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout)
+{
+
+  return 0;
+}
+
+/**
+ * Read from an isochron endpoint.
+ */
+u8 usb_isochron_read(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout)
+{
+
+
+  return 0;
+}
+
+
+//#endif       //_USB_H_
diff --git a/usb/core/usb.h b/usb/core/usb.h
new file mode 100644 (file)
index 0000000..6579b72
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ * I take the function names and parameters mainly from
+ * libusb.sf.net.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _USB_H_
+#define _USB_H_
+
+#include "../../types.h"
+#include "core.h"
+
+
+/******************* Device Operations **********************/
+
+// use an own usb device
+usb_device * usb_open(u32 vendor_id, u32 product_id);
+usb_device * usb_open_class(u8 class);
+
+u8 usb_close(usb_device *dev);
+
+
+
+u8 usb_get_device_descriptor(usb_device *dev, char *buf,u8 size);
+u8 usb_set_address(usb_device *dev, u8 address);
+u8 usb_set_configuration(usb_device *dev, u8 configuration);
+u8 usb_set_altinterface(usb_device *dev, u8 alternate);
+
+
+/**
+ * usb_reset resets the specified device by sending a RESET down the port 
+ * it is connected to. Returns 0 on success or < 0 on error.
+ */
+
+u8 usb_reset(usb_device *dev);
+
+
+/******************* Control Transfer **********************/
+
+
+u8 usb_control_msg(usb_device *dev, u8 requesttype, u8 request, u16 value, u16 index, u16 length, char *buf, u16 size, u16 timeout);
+u8 usb_get_string(usb_device *dev, u8 index, u8 langid, char *buf, u8 buflen);
+u8 usb_get_string_simple(usb_device *dev, u8 index, char *buf, u8 buflen);
+u8 usb_get_descriptor(usb_device *dev, unsigned char type, unsigned char index, void *buf, u8 size);
+
+
+/******************* Bulk Transfer **********************/
+
+u8 usb_bulk_write(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout);
+u8 usb_bulk_read(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout);
+
+
+/******************* Interrupt Transfer **********************/
+u8 usb_u8errupt_write(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout);
+u8 usb_u8errupt_read(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout);
+
+
+/******************* Isochron Transfer **********************/
+u8 usb_isochron_write(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout);
+u8 usb_isochron_read(usb_device *dev, u8 ep, char *buf, u8 size, u8 timeout);
+
+
+
+#endif //_USB_H_
diff --git a/usb/drivers/class/hub.c b/usb/drivers/class/hub.c
new file mode 100644 (file)
index 0000000..722624c
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#include <wait.h>
+//#include <stdlib.h>
+
+#include "../../core/core.h"
+#include "../../core/usb.h"
+#include "../../usbspec/usb11spec.h"
+
+
+void usb_hub_probe();
+void usb_hub_check();
+
+
+usb_driver hub = {
+  .name          = "hub",
+  .probe  = usb_hub_probe,
+  .check  = usb_hub_check,
+  .data          = NULL
+};
+
+void usb_hub_init()
+{
+  usb_register_driver(&hub);  
+}
+
+
+void usb_hub_probe()
+{
+  // schaue ob aktuell enumeriertes geraet ein hub ist
+  #if DEBUG
+  core.stdout("Probe: Hub\r\n");
+  #endif
+  wait_ms(1000);
+  
+  usb_device * dev;
+  dev = usb_open_class(HUB_CLASSCODE);
+  if(dev != NULL){
+    hub.data = (void*)dev;    /* save handle */
+    #if DEBUG
+    core.stdout("Hub: Found Hub Device\r\n");
+    #endif 
+   
+    /* install int in EP */
+
+  }
+
+
+
+}
+
+
+void usb_hub_check()
+{
+  // usb_read_interrupt(handle,1,buf); 
+  // ah neue geraet gefunden
+  // mit request den port geziel reseten, damit device adresse 0 hat
+  // enumeration start
+  // usb_add_device()
+  //
+  //
+  // ah geraet entfernt
+  // usb_remove_device(h1);
+
+}
+
+
+u8 usb_hub_get_hub_descriptor(usb_device *dev, char * buf)
+{
+  return 0;  
+}
+
+u8 usb_hub_get_hub_status(usb_device *dev, char *buf)
+{
+
+
+  return 0;  
+}
+
+
+u8 usb_hub_get_port_status(usb_device *dev, char *buf)
+{
+
+
+  return 0;  
+}
+
+u8 usb_hub_clear_port_feature(usb_device *dev)
+{
+
+  return 0;  
+}
+
+u8 usb_hub_set_port_feature(usb_device *dev, u8 value)
+{
+
+  return 0;  
+}
+
+u8 usb_hub_clear_hub_feature(usb_device *dev)
+{
+
+  return 0;  
+}
+
+u8 usb_hub_set_hub_feature(usb_device *dev)
+{
+
+  return 0;  
+}
+
+u8 usb_hub_set_hub_descriptor(usb_device *dev)
+{
+
+  return 0;  
+}
+
diff --git a/usb/drivers/class/hub.h b/usb/drivers/class/hub.h
new file mode 100644 (file)
index 0000000..7e157b3
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _HUB_H
+#define _HUB_H
+
+void usb_hub_init();
+void usb_hub_probe();
+
+void usb_hub_check();
+u8 usb_hub_get_hub_descriptor(usb_device *dev, char * buf);
+u8 usb_hub_get_hub_status(usb_device *dev, char *buf);
+u8 usb_hub_get_port_status(usb_device *dev, char *buf);
+u8 usb_hub_clear_port_feature(usb_device *dev);
+u8 usb_hub_set_port_feature(usb_device *dev, u8 value);
+u8 usb_hub_clear_hub_feature(usb_device *dev);
+u8 usb_hub_set_hub_feature(usb_device *dev);
+
+u8 usb_hub_set_hub_descriptor(usb_device *dev);
+#endif /* _HUB_H */
+
diff --git a/usb/drivers/class/storage.c b/usb/drivers/class/storage.c
new file mode 100644 (file)
index 0000000..ff503f7
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+//#include <wait.h>
+//#include <stdlib.h>
+
+#include "../../core/core.h"
+#include "../../core/usb.h"
+#include "../../usbspec/usb11spec.h"
+#include "../../../malloc.h"
+
+#include "storage.h"
+
+
+#define MAX_DEVICES 2
+
+void usb_storage_probe();
+void usb_storage_check();
+
+usb_device * massstorage[MAX_DEVICES];
+u16 sectorsize[MAX_DEVICES];
+u8 massstorage_in_use;
+
+usb_driver storage = {
+  .name          = "storage",
+  .probe  = usb_storage_probe,
+  .check  = usb_storage_check,
+  .data          = NULL
+};
+
+void usb_storage_init()
+{
+  massstorage_in_use = 0;
+  usb_register_driver(&storage);  
+}
+
+
+void usb_storage_probe()
+{
+  // schaue ob aktuell enumeriertes geraet ein storage ist
+  #if DEBUG
+  core.stdout("Probe: Storage\r\n");
+  #endif
+  /* read interface descriptor for class code */
+  char buf[32];
+  
+  usb_device* dev;
+  element * iterator = core.devices->head;
+  
+  while(iterator != NULL) {
+    dev = (usb_device*)iterator->data;
+
+    /* get interface descriptor */
+    usb_control_msg(dev, 0x80, GET_DESCRIPTOR,2, 0,  32,buf, 8, 0);
+
+    if(buf[14]==MASS_STORAGE_CLASSCODE){
+      massstorage[massstorage_in_use] = dev;
+      massstorage_in_use++;
+      #if DEBUG
+      core.stdout("Storage: Found Storage Device\r\n");
+      #endif 
+
+      /* here is only my lib driver test */
+      usb_storage_open(0);
+      usb_storage_inquiry(0);
+      usb_storage_read_capacity(0);
+
+      //char * buf = (char*)malloc(512);
+      //free(buf);
+      //char buf[512];
+      //usb_storage_read_sector(0,1,buf);
+
+      /* end of driver test */
+    }
+
+    iterator=iterator->next;
+  }
+}
+
+
+void usb_storage_check()
+{
+  // wird periodisch augerufen
+  // da ein mass storage aber keinen interrupt oder isochronen endpunkt
+  // hat passiert hier nichts
+}
+
+
+
+/**
+ * open connection to an storage device
+ */
+u8 usb_storage_open(u8 device)
+{
+  /* set configuration */
+  char tmp[8];
+  usb_control_msg(massstorage[device], 0x00,SET_CONFIGURATION,0x0100, 0, 0,tmp, 8, 0);
+
+
+  /* class request */
+  usb_control_msg(massstorage[device], 0xA1,0xFE,0, 0, 1,tmp, 8, 0);
+
+  /* wait until the stick is complete ready */
+  wait_ms(10);
+  
+  //FIXME and all other return values!!!
+  return 1;
+}
+
+u8 usb_storage_inquiry(u8 device)
+{
+  /* send cwb "usbc" */
+  
+  usb_storage_cbw *cbw = (usb_storage_cbw*)malloc(sizeof(usb_storage_cbw));
+  cbw->dCBWSignature= 0x43425355;
+  cbw->dCBWTag=0x826A6008;
+  cbw->dCBWDataTransferLength=0x00000024;
+  cbw->bCWDFlags=0x80;
+  cbw->bCBWLun=0x00;
+  cbw->bCBWCBLength=0x01;
+
+  u8 i;
+  for(i=0;i<16;i++)
+    cbw->CBWCB[i]=0x00;
+
+  cbw->CBWCB[0]=0x12; // 0x12 = INQUIRY
+
+  usb_bulk_write(massstorage[device], 2, (char*)cbw, 31, 0); 
+  usb_bulk_read(massstorage[device], 1, (char*)cbw, 36, 0); 
+  usb_bulk_read(massstorage[device], 1, (char*)cbw, 13, 0); 
+
+  free(cbw);
+
+  return 0;
+}
+
+
+u8 usb_storage_read_capacity(u8 device)
+{
+  /* send cwb "usbc" */
+
+  char tmp[8];
+  u8 i;
+  usb_storage_cbw  * cbw = (usb_storage_cbw*)malloc(sizeof(usb_storage_cbw));
+
+  usb_control_msg(massstorage[device], 0x02,1,0, 0x8100, 0,tmp, 8, 0); // 
+
+  cbw->dCBWSignature= 0x43425355;
+  cbw->dCBWTag=0x826A6008;
+  cbw->dCBWDataTransferLength=0x00000008;
+  cbw->bCWDFlags=0x80;
+  cbw->bCBWLun=0x00;
+  cbw->bCBWCBLength=0x0A;
+
+  for(i=0;i<16;i++)
+    cbw->CBWCB[i]=0x00;
+
+  cbw->CBWCB[0]=0x25; // 0x12 = INQUIRY
+
+  usb_bulk_write(massstorage[device], 2, (char*)cbw, 31, 0); 
+  usb_bulk_read(massstorage[device], 1, (char*)cbw, 8, 0); 
+  usb_bulk_read(massstorage[device], 1, (char*)cbw, 13, 0); 
+
+  free(cbw);
+
+  return 0;
+}
+
+
+u8 usb_storage_read_sector(u8 device, u32 sector, char * buf)
+{
+  /* send cwb "usbc" */
+  char tmpbuf[] = {0x55,0x53,0x42,0x43,0x08,
+               0xE0,0x63,0x82,0x00,0x02,
+               0x00,0x00,0x80,0x00,0x0A,
+               0x28,0x00,0x00,0x00,0x00,
+               0x00,0x00,0x00,0x01,0x00,
+               0x00,0x00,0x00,0x00,0x00,
+               0x00,
+               0x00,0x00,0x00,0x00,0x00};
+
+  usb_bulk_write(massstorage[device], 2, tmpbuf, 31, 0);
+  //usb_bulk_read(massstorage[device], 1, buf,64,0);
+  //usb_bulk_read(massstorage[device], 1, buf, 13, 0); 
+
+  
+  return 0;
+}
+
+
+u8 usb_storage_write_sector(u8 device, u32 sector, char * buf)
+{
+
+  return 0;
+}
diff --git a/usb/drivers/class/storage.h b/usb/drivers/class/storage.h
new file mode 100644 (file)
index 0000000..3b5b4c0
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __STORAGE_H
+#define __STORAGE_H
+void usb_storage_probe();
+void usb_storage_check();
+
+/* CSW Status Definitions */
+#define CSW_CMD_PASSED                  0x00
+#define CSW_CMD_FAILED                  0x01
+#define CSW_PHASE_ERROR                 0x02
+
+
+/* SCSI Commands */
+#define SCSI_TEST_UNIT_READY            0x00
+#define SCSI_REQUEST_SENSE              0x03
+#define SCSI_FORMAT_UNIT                0x04
+#define SCSI_INQUIRY                    0x12
+#define SCSI_MODE_SELECT6               0x15
+#define SCSI_MODE_SENSE6                0x1A
+#define SCSI_START_STOP_UNIT            0x1B
+#define SCSI_MEDIA_REMOVAL              0x1E
+#define SCSI_READ_FORMAT_CAPACITIES     0x23
+#define SCSI_READ_CAPACITY              0x25
+#define SCSI_READ10                     0x28
+#define SCSI_WRITE10                    0x2A
+#define SCSI_VERIFY10                   0x2F
+#define SCSI_MODE_SELECT10              0x55
+#define SCSI_MODE_SENSE10               0x5A
+
+
+typedef struct usb_storage_cbw_t usb_storage_cbw;
+struct usb_storage_cbw_t {
+  u32 dCBWSignature;
+  u32 dCBWTag;
+  u32 dCBWDataTransferLength;
+  u8  bCWDFlags;
+  u8  bCBWLun;
+  u8  bCBWCBLength;
+  u8  CBWCB[16];
+};
+
+typedef struct usb_storage_csw_t usb_storage_csw;
+struct usb_storage_csw_t {
+  u32 dCSWSignature;
+  u32 dCSWTag;
+  u32 dCSWDataResidue;
+  u8  bCSWStatus;
+};
+
+
+void usb_storage_init();
+
+u8 usb_storage_open(u8 device);
+
+u8 usb_storage_read_capacity(u8 device);
+u8 usb_storage_inquiry(u8 device);
+u8 usb_storage_read_sector(u8 device, u32 sector, char * buf);
+u8 usb_storage_write_sector(u8 device, u32 sector, char * buf);
+#endif /* __STORAGE_H */
+
diff --git a/usb/drivers/mon/mon.c b/usb/drivers/mon/mon.c
new file mode 100644 (file)
index 0000000..bd7a324
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#if USBMON
+
+#include <string.h>
+
+#include "mon.h"
+#include <core/core.h>
+#include <uart.h>
+
+void usb_mon_stdout(void *output)
+{
+  core.stdout = output;
+  usbmon_index=0;
+  usbmon_loop=0;
+}
+
+void usb_mon_stdin(unsigned char input)
+{
+  char send[3]={input,0,0};
+  usbmon_buffer[usbmon_index++]=input;
+  // if enter is pressed
+  if(input==0xD){
+    usbmon_buffer[--usbmon_index]=0;
+    usb_mon_command();
+    usbmon_index=0;
+  } else {
+    core.stdout(send);
+  }
+  if((usbmon_loop==0 && input==0xD)){ 
+    send[0]='\n';
+    send[1]='\r';
+    core.stdout(send);
+    core.stdout("usbmon> ");
+  } 
+
+  if((usbmon_loop==1 && input==0xD)){
+    usbmon_loop=0;
+  }
+}
+
+void usb_mon_command()
+{
+  if(strcmp("list",(char*)usbmon_buffer)==0){
+    core.stdout("\r\nDevice list:\r\n");
+  } else if (strcmp("mon",(char*)usbmon_buffer)==0) {
+    core.stdout("\r\n0:02:Bo 00 93 04");
+    core.stdout("\r\n0:02:Bo 00 93 04");
+    usbmon_loop=1;
+  } else if (strcmp("help",(char*)usbmon_buffer)==0) {
+    usb_mon_usage();
+  } else if (strcmp(".",(char*)usbmon_buffer)==0) {
+    usbmon_loop=0;
+  }
+  else {
+    if(usbmon_index>0)
+      core.stdout("\r\nunkown command (type help)");
+  }
+
+}
+
+void usb_mon_usage()
+{
+  core.stdout("\r\nUsage:\r\n");
+  core.stdout("\tlist\t Print device list\r\n");
+  core.stdout("\tmon\t View online traffic\r\n");
+}
+
+
+
+#endif
diff --git a/usb/drivers/mon/mon.h b/usb/drivers/mon/mon.h
new file mode 100644 (file)
index 0000000..3c7c3dc
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * Aufgabefunktion fuer Debugmeldung angeben
+ */
+#if USBMON
+#ifndef _MON_H_
+#define _MON_H_
+
+unsigned char usbmon_buffer[20];
+int usbmon_index;
+int usbmon_loop;
+
+void usb_mon_stdout(void *output);
+void usb_mon_stdin(unsigned char input);
+
+void usb_mon_command();
+void usb_mon_usage();
+
+#endif //_MON_H_
+#endif
diff --git a/usb/drivers/skeleton.c b/usb/drivers/skeleton.c
new file mode 100644 (file)
index 0000000..3c0e0ba
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <core/core.h>
+#include <core/usb.h>
+#include <usbspec/usb11spec.h>
+
+#define MAX_DEVICES;
+
+usb_device * devices[MAX_DEVICES];
+u8 devices_in_use;
+
+usb_driver skeleton = {
+  .name    = "skeleton",
+  .probe   = usb_skeleton_probe,
+  .unprobe = usb_skeleton_unprobe,
+  .check   = usb_skeleton_check,
+  .data    = NULL
+};
+
+/* Zum Treiber initialisieren und anmelden am Stack */
+void usb_skeleton_init()
+{
+  devices_in_use = 0;
+  usb_register_driver(&skeleton);
+}
+
+/* Prüfen ob neues Gerät vom Treiber aus angesteuert werden kann */
+void usb_skeleton_probe()
+{
+  usb_device * tmp;
+  tmp = usb_open(0x1234,0x9876);
+  if(tmp!=NULL) {
+    /* neues Gerät gefunden */
+
+    /* wenn Gerät noch nicht in interner Datenstruktur */
+    if(devices_in_use<MAX_DEVICES)
+      devices[devices_in_use++] = tmp;
+  }
+
+}
+
+/* Entferntes Gerät aus Treiberstrukturen löschen */
+void usb_skeleton_unprobe(usb_device * dev)
+{
+  u8 i;
+  for(i=0;i<MAX_DEVICES;i++) {
+    if(devices[i]==dev)
+      usb_close(dev);
+  }
+}
+
+/* Für periodische Endpunkte, Verwaltungs- und Steuerungsaufgaben */
+void usb_skeleton_check(){
+
diff --git a/usb/host/at90usb1287-hcd.c b/usb/host/at90usb1287-hcd.c
new file mode 100644 (file)
index 0000000..2ba0cae
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+  //
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file: at90usb1287-hcdi.c
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "host.h"
+#include <wait.h>
+#include <stdlib.h>
+
+#include "at90usb1287.h"
+#include <avr/io.h>
+
+#include "uart.h"
+#include "wait.h"
+
+#include <core/core.h>
+#include <usbspec/usb11spec.h>
+
+void at90usb1287_roothub_probe();
+void at90usb1287_roothub_check();
+
+void at90usb1287_start_transfer();
+
+usb_device * device_on_downstream;
+
+
+/* cuurent transferdescriptor on port a and port b */
+usb_transfer_descriptor * td_usba;
+usb_transfer_descriptor * td_usbb;
+
+usb_driver at90usb1287_roothub = {
+  .name          = "at90usb1287_roothub",
+  .probe  = at90usb1287_roothub_probe,
+  .check  = at90usb1287_roothub_check,
+  .data          = NULL,
+};
+
+usb_device * device_on_downstream;
+
+/**
+ * Find and initial root hub
+ */
+void at90usb1287_roothub_probe()
+{
+  // called on n every new enumeration and at usb_register_driver  
+  // der sollte nach dem ersten aufruf igonriert werden
+  #if DEBUG
+  core.stdout("Probe: AT90USB1287 Root Hub\r\n");
+  #endif
+}
+
+/**
+ * This function is called periodical, to notice
+ * port changes after an hub
+ */
+void at90usb1287_roothub_check()
+{
+  //USART_WriteHex(UHINT);
+  //UHINT = 0x00;
+  // disconnect 
+  if(UHINT & 0x02) {
+    device_on_downstream=NULL;
+    #if DEBUG
+    core.stdout("Device: Removed!\r\n");
+    #endif
+    //UHINT &= ~(1<<DDISCI);
+  } else {
+    // if connect 
+    if(device_on_downstream!=NULL) {
+      // normal transfer check for interrupt and isochonous endpoints
+      //USART_WriteHex(0x88);
+    } 
+    // check if device is connected 
+    else {
+      if(UHINT & 0x01) {
+       // found new device
+       #if DEBUG
+       core.stdout("Device: Found new one!\r\n");
+       #endif
+
+       if((USBSTA &   (1<<SPEED)) &&(USBSTA &   (1<<SPEED))){
+         // fullspeed
+         #if DEBUG
+         core.stdout("FS\r\n");
+         #endif
+       } else {
+         //lowspeed
+         #if DEBUG
+         core.stdout("LS\r\n");
+         #endif
+         // mark device as low speed
+       }
+       
+       //UHCON = (1<<SOFEN); /* host generate for FS SOF, and for LS keep-alive! */
+       //UHCON = (1<<RESET);
+
+       // SOF on etx
+       device_on_downstream = 1;       
+       //device_on_downstream = usb_add_device();      
+       //UHINT &= ~(1<<DCONNI);
+      }
+      else {
+       // wenn geraet nicht aktiviert ist das immer aufrufen! 
+      //USART_WriteHex(0x55);
+      }
+    }
+  }
+  UHINT = 0x00;
+       /* Usb_disable */
+       USBCON &= ~(1<<USBE);
+       /* Usb_enable */
+       USBCON |= (1<<USBE);
+       /* unfreeze clock */
+       UsbEnableClock();
+       /* usb attach */
+       UDCON   &= ~(1<<DETACH);
+       /* select host */
+       USBCON  |=  (1<<HOST);
+       /* disable vbus hw control */
+       OTGCON  |=  (1<<VBUSHWC);
+       /* enable vbus */
+       OTGCON  |=  (1<<VBUSREQ);
+
+ }
+
+
+void hcdi_init()
+{ 
+ /* register virtual root hub driver */
+  usb_register_driver(&at90usb1287_roothub);
+
+  /* enable regulator */
+  UHWCON |= (1<<UVREGE); 
+  /* force host mode */
+  UHWCON &= ~(1<<UIDE);
+  UHWCON &= ~(1<<UIMOD);
+
+  /* pll sart */
+  UsbSetPLL_CPU_Frequency();
+  UsbEnablePLL();
+  UsbWaitPLL_Locked();
+
+  /* Usb_disable */
+  USBCON &= ~(1<<USBE);
+  
+  /* Usb_enable */
+  USBCON |= (1<<USBE);
+  
+  /* unfreeze clock */
+  UsbEnableClock();
+
+  /* usb attach */
+  UDCON   &= ~(1<<DETACH);
+
+  /* enable uconv pin */
+  UsbDisableUVCON_PinControl();
+  UsbEnableUID_ModeSelection();
+
+  /* select host */
+  USBCON  |=  (1<<HOST);
+
+  /* disable vbus hw control */
+  OTGCON  |=  (1<<VBUSHWC);
+
+  // 4
+  /* enable vbus */
+  OTGCON  |=  (1<<VBUSREQ);
+  
+  UHIEN |= (1<<DDISCE);
+  UHIEN |= (1<<DCONNE);
+
+  UHIEN = 0xff;
+ }
+
+/**
+ * hcdi_enqueue takes usb_irp and split it into
+ * several usb packeges (SETUP,IN,OUT)
+ * In the usbstack they are transported with the
+ * usb_transfer_descriptor data structure.
+ */
+
+u8 hcdi_enqueue(usb_transfer_descriptor *td)
+{
+  #if LIBMODE
+  td_usba = td;
+  at90usb1287_start_transfer();
+  #endif
+  return 1;
+}
+
+
+u8 hcdi_dequeue(usb_transfer_descriptor *td)
+{
+  return 1;
+}
+
+
+
+void hcdi_irq()
+{
+}
+
+
+
+void at90usb1287_start_transfer()
+{
+  usb_transfer_descriptor * td;
+  //core.stdout("Transfer: Start!\r\n");
+
+  #if LIBMODE
+  /* choose next free port */
+  td = td_usba;
+  #endif
+
+  switch(td->pid) {
+    case USB_PID_SETUP:
+    break;
+    
+    case USB_PID_IN:
+    break;
+    
+    case USB_PID_OUT:
+    break;
+  }
+
+
+}
+
+
diff --git a/usb/host/at90usb1287.h b/usb/host/at90usb1287.h
new file mode 100644 (file)
index 0000000..eb2ed07
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef _AT90USB_H
+#define _AT90USB_H
+// AT90USB/usb_drv.h
+// Macros for access to USB registers of Atmels AT90USB microcontrollers
+// This file contains low level register stuff as described in
+// Atmels AT90USB datasheet 7593D-AVR-07/06
+// S. Salewski 21-MAR-2007
+// B. Sauter (modified for usb host stack) 2007
+
+
+// A few macros for bit fiddling
+#define SetBit(adr, bit)                        (adr |=  (1<<bit))
+#define ClearBit(adr, bit)                      (adr &= ~(1<<bit))
+#define BitIsSet(adr, bit)                      (adr & (1<<bit))
+#define BitIsClear(adr, bit)                    (!(adr & (1<<bit)))
+
+
+
+// PLL clock for USB interface, section 6.11, page 50
+// PLLCSR (PLL Control and Status Register)
+// set PLL prescaler according to XTAL crystal frequency
+//#define UsbXTALFrequencyIs2MHz()              PLLCSR = (PLLCSR & ~(15<<1))
+//#define UsbXTALFrequencyIs4MHz()              PLLCSR = (PLLCSR & ~(15<<1)) | (1<<2)
+//#define UsbXTALFrequencyIs6MHz()              PLLCSR = (PLLCSR & ~(15<<1)) | (2<<2)
+//#define UsbXTALFrequencyIs8MHz()              PLLCSR = (PLLCSR & ~(15<<1)) | (3<<2)
+//#define UsbXTALFrequencyIs12MHz()             PLLCSR = (PLLCSR & ~(15<<1)) | (4<<2)
+//#define UsbXTALFrequencyIs16MHz()             PLLCSR = (PLLCSR & ~(15<<1)) | (5<<2)
+#if (F_CPU == 2000000)
+#define _pre_ 0
+#elif (F_CPU == 4000000)
+#define _pre_ 1
+#elif (F_CPU == 6000000)
+#define _pre_ 2
+#elif (F_CPU == 8000000)
+#define _pre_ 3
+#elif (F_CPU == 12000000)
+#define _pre_ 4
+#elif (F_CPU == 16000000)
+#define _pre_ 5
+#else
+  #error "XTAL-Frequency has to be 2, 4, 6, 8, 12 or 16 MHz for USB devices!"
+#endif
+#define UsbSetPLL_CPU_Frequency()              PLLCSR = (_pre_<<2)
+#define UsbEnablePLL()                          SetBit(PLLCSR, PLLE)
+#define UsbDisablePLL()                         ClearBit(PLLCSR, PLLE)
+#define UsbIsPLL_Locked()                       BitIsSet(PLLCSR, PLOCK)
+#define UsbWaitPLL_Locked()                     while (!(PLLCSR & (1<<PLOCK)));
+#define UsbEnableClock()                        ClearBit(USBCON, FRZCLK)
+
+//USB general registers, section 21.12.1, page 263 of datasheet
+// UHWCON (UsbHardWareCONfiguration)
+#define UsbSetDeviceMode()                SetBit(UHWCON, UIMOD)           // select host or device mode manually
+#define UsbSetHostMode()                  ClearBit(UHWCON, UIMOD)
+#define UsbEnableUID_ModeSelection()      SetBit(UHWCON, UIDE)            // enable mode selection by UID pin
+#define UsbDisableUID_ModeSelection()     ClearBit(UHWCON, UIDE)
+#define UsbEnableUVCON_PinControl()       SetBit(UHWCON, UVCONE)          // enable UVCON pin control, figure 21-7
+#define UsbDisableUVCON_PinControl()      ClearBit(UHWCON, UVCONE)
+#define UsbEnablePadsRegulator()          SetBit(UHWCON, UVREGE)          // USB pads (D+, D-) supply
+#define UsbDisablePadsRegulator()         ClearBit(UHWCON, UVREGE)
+
+// USBCON (USB CONfiguration)
+#define UsbEnableController()             SetBit(USBCON, USBE)            // USB controller enable
+#define UsbDisableController()            ClearBit(USBCON, USBE)          // reset and disable controller
+#define UsbIsControllerEnabled()          BitIsSet(USBCON, USBE)
+#define UsbSetHostModeReg()               SetBit(USBCON, HOST)            // select multiplexed controller registers
+#define UsbSetDeviceModeReg()             ClearBit(USBCON, HOST)          //
+#define UsbFreezeClock()                  SetBit(USBCON, FRZCLK)          // reduce power consumption
+#define UsbEnableClock()                  ClearBit(USBCON, FRZCLK)
+#define UsbIsClockFreezed()               BitIsSet(USBCON, FRZCLK)
+#define UsbEnableOTG_Pad()                SetBit(USBCON, OTGPADE)         // ??? is this the UID pad?
+#define UsbDisableOTG_Pad()               ClearBit(USBCON, OTGPADE)
+#define UsbEnableID_TransitionInt()       SetBit(USBCON, IDTE)            // enable ID transition interrupt generation
+#define UsbDisableID_TransitionInt()      ClearBit(USBCON, IDTE)
+#define UsbEnableVBUS_TransitionInt()     SetBit(USBCON, VBUSTE)          // enable VBUS transition interrupt
+#define UsbDisableVBUS_TransitionInt()    ClearBit(USBCON, VBUSTE)
+
+// USBSTA (USBSTAtus, read only)
+#define UsbIsFullSpeedMode()              BitIsSet(USBSTA, SPEED)         // set by hardware if controller is in fullspeed mode,
+#define UsbIsLowSpeedMode()               BitIsClear(USBSTA, SPEED)       // use in host mode only, indeterminate in device mode
+#define UsbIsUID_PinHigh()               BitIsSet(USBSTA, ID)            // query UID pad/pin
+#define UsbIsVBUS_PinHigh()              BitIsSet(USBSTA, VBUS)          // query VBUS pad/pin
+
+// USBINT (USBINTerrupt)
+#define UsbIsIDTI_FlagSet()              BitIsSet(USBINT, IDTI)          // set by hardware if ID pin transition detected
+#define UsbClearIDTI_Flag()              ClearBit(USBINT, IDTI)          // shall be cleared by software
+#define UsbIsVBUSTI_FlagSet()            BitIsSet(USBINT, VBUSTI)        // set by hardware if transition on VBUS pad is detected
+#define UsbClearVBUSTI_Flag()            ClearBit(USBINT, VBUSTI)        // shall be cleared by software
+
+#endif /* _AT90USB_H */
diff --git a/usb/host/host.h b/usb/host/host.h
new file mode 100644 (file)
index 0000000..9aa6a77
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __HOST_H
+#define __HOST_H
+
+#include "../core/core.h"
+
+/**
+ * IRQ from host controller.
+ */
+void hcdi_irq();
+
+
+/**
+ * Intial host controller and necessary software structures.
+ */
+void hcdi_init();
+/**
+ * Enqueue a transfer descriptor.
+ */
+u8 hcdi_enqueue(usb_transfer_descriptor *td);
+/**
+ * Remove an transfer descriptor from transfer queue.
+ */
+u8 hcdi_dequeue(usb_transfer_descriptor *td);
+
+#endif /* __HOST_H */
diff --git a/usb/host/ohci.c b/usb/host/ohci.c
new file mode 100644 (file)
index 0000000..35fb456
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+       ppcskel - a Free Software replacement for the Nintendo/BroadOn bootloader.
+       ohci hardware support
+
+Copyright (C) 2009     Bernhard Urban <lewurm@gmx.net>
+Copyright (C) 2009     Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
+
+# This code is licensed to you under the terms of the GNU GPL, version 2;
+# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+*/
+
+#include "../../bootmii_ppc.h"
+#include "../../hollywood.h"
+#include "../../irq.h"
+#include "../../string.h"
+#include "ohci.h"
+#include "host.h"
+
+static struct ohci_hcca hcca_oh0;
+
+static void dbg_op_state() 
+{
+       switch (read32(OHCI0_HC_CONTROL) & OHCI_CTRL_HCFS) {
+               case OHCI_USB_SUSPEND:
+                       printf("ohci-- OHCI_USB_SUSPEND\n");
+                       break;
+               case OHCI_USB_RESET:
+                       printf("ohci-- OHCI_USB_RESET\n");
+                       break;
+               case OHCI_USB_OPER:
+                       printf("ohci-- OHCI_USB_OPER\n");
+                       break;
+               case OHCI_USB_RESUME:
+                       printf("ohci-- OHCI_USB_RESUME\n");
+                       break;
+       }
+}
+
+
+/**
+ * Enqueue a transfer descriptor.
+ */
+u8 hcdi_enqueue(usb_transfer_descriptor *td) {
+       return 0;
+}
+
+/**
+ * Remove an transfer descriptor from transfer queue.
+ */
+u8 hcdi_dequeue(usb_transfer_descriptor *td) {
+       return 0;
+}
+
+void hcdi_init() 
+{
+       printf("ohci-- init\n");
+       dbg_op_state();
+
+       /* disable hc interrupts */
+       set32(OHCI0_HC_INT_DISABLE, OHCI_INTR_MIE);
+
+       /* save fmInterval and calculate FSMPS */
+#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7))
+#define FI 0x2edf /* 12000 bits per frame (-1) */
+       u32 fmint = read32(OHCI0_HC_FM_INTERVAL) & 0x3fff;
+       if(fmint != FI)
+               printf("ohci-- fminterval delta: %d\n", fmint - FI);
+       fmint |= FSMP (fmint) << 16;
+
+       /* enable interrupts of both usb host controllers */
+       set32(EHCI_CTL, EHCI_CTL_OH0INTE | EHCI_CTL_OH1INTE | 0xe0000);
+
+       /* reset HC */
+       write32(OHCI0_HC_COMMAND_STATUS, OHCI_HCR);
+
+       /* wait max. 30us */
+       u32 ts = 30;
+       while ((read32(OHCI0_HC_COMMAND_STATUS) & OHCI_HCR) != 0) {
+                if(--ts == 0) {
+                       printf("ohci-- FAILED");
+                       return;
+                }
+                udelay(1);
+       }
+
+       /* disable interrupts; 2ms timelimit here! 
+          now we're in the SUSPEND state ... must go OPERATIONAL
+          within 2msec else HC enters RESUME */
+
+       u32 cookie = irq_kill();
+
+       /* Tell the controller where the control and bulk lists are
+        * The lists are empty now. */
+       write32(OHCI0_HC_CTRL_HEAD_ED, 0);
+       write32(OHCI0_HC_BULK_HEAD_ED, 0);
+
+       /* set hcca adress */
+       sync_after_write(&hcca_oh0, 256);
+       write32(OHCI0_HC_HCCA, virt_to_phys(&hcca_oh0));
+
+       /* set periodicstart */
+#define FIT (1<<31)
+       u32 fmInterval = read32(OHCI0_HC_FM_INTERVAL) &0x3fff;
+       u32 fit = read32(OHCI0_HC_FM_INTERVAL) & FIT;
+
+       write32(OHCI0_HC_FM_INTERVAL, fmint | (fit ^ FIT));
+       write32(OHCI0_HC_PERIODIC_START, ((9*fmInterval)/10)&0x3fff);
+
+       /* testing bla */
+       if ((read32(OHCI0_HC_FM_INTERVAL) & 0x3fff0000) == 0 || !read32(OHCI0_HC_PERIODIC_START)) {
+               printf("ohci-- w00t, fail!! see ohci-hcd.c:669\n");
+       }
+       
+       /* start HC operations */
+       write32(OHCI0_HC_CONTROL, OHCI_CONTROL_INIT | OHCI_USB_OPER);
+
+       /* wake on ConnectStatusChange, matching external hubs */
+       set32(OHCI0_HC_RH_STATUS, RH_HS_DRWE);
+
+       /* Choose the interrupts we care about now, others later on demand */
+       write32(OHCI0_HC_INT_STATUS, ~0);
+       write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_INIT);
+
+       irq_restore(cookie);
+
+       dbg_op_state();
+}
+
+void hcdi_irq()
+{
+       /* read interrupt status */
+       u32 flags = read32(OHCI0_HC_INT_STATUS);
+
+       /* when all bits are set to 1 some problem occured */
+       if (flags == 0xffffffff) {
+               printf("ohci-- Houston, we have a serious problem! :(\n");
+               return;
+       }
+
+       /* only care about interrupts that are enabled */
+       flags &= read32(OHCI0_HC_INT_ENABLE);
+
+       /* nothing to do? */
+       if (flags == 0)
+               return;
+
+       printf("OHCI Interrupt occured: ");
+       /* UnrecoverableError */
+       if (flags & OHCI_INTR_UE) {
+               printf("UnrecoverableError\n");
+               /* TODO: well, I don't know... nothing,
+                *       because it won't happen anyway? ;-) */
+       }
+
+       /* RootHubStatusChange */
+       if (flags & OHCI_INTR_RHSC) {
+               printf("RootHubStatusChange\n");
+               /* TODO: set some next_statechange variable... */
+               write32(OHCI0_HC_INT_STATUS, OHCI_INTR_RD | OHCI_INTR_RHSC);
+       }
+       /* ResumeDetected */
+       else if (flags & OHCI_INTR_RD) {
+               printf("ResumeDetected\n");
+               write32(OHCI0_HC_INT_STATUS, OHCI_INTR_RD);
+               /* TODO: figure out what the linux kernel does here... */
+       }
+
+       /* WritebackDoneHead */
+       if (flags & OHCI_INTR_WDH) {
+               printf("WritebackDoneHead\n");
+               /* TODO: figure out what the linux kernel does here... */
+       }
+
+       /* TODO: handle any pending URB/ED unlinks... */
+
+#define HC_IS_RUNNING() 1 /* dirty, i know... just a temporary solution */
+       if (HC_IS_RUNNING()) {
+               write32(OHCI0_HC_INT_STATUS, flags);
+               write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_MIE);
+       }
+}
+
diff --git a/usb/host/ohci.h b/usb/host/ohci.h
new file mode 100644 (file)
index 0000000..224872f
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+       ppcskel - a Free Software replacement for the Nintendo/BroadOn bootloader.
+       ohci hardware support
+
+Copyright (C) 2009     Bernhard Urban <lewurm@gmx.net>
+Copyright (C) 2009     Sebastian Falbesoner <sebastian.falbesoner@gmail.com>
+
+# This code is licensed to you under the terms of the GNU GPL, version 2;
+# see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+*/
+
+#ifndef __OHCI_H__
+#define __OHCI_H__
+
+#include "../../types.h"
+
+/* stolen from drivers/usb/host/ohci.h (linux-kernel) :) */
+
+/* OHCI CONTROL AND STATUS REGISTER MASKS */
+
+/*
+ * HcControl (control) register masks
+ */
+#define OHCI_CTRL_CBSR (3 << 0)        /* control/bulk service ratio */
+#define OHCI_CTRL_PLE  (1 << 2)        /* periodic list enable */
+#define OHCI_CTRL_IE   (1 << 3)        /* isochronous enable */
+#define OHCI_CTRL_CLE  (1 << 4)        /* control list enable */
+#define OHCI_CTRL_BLE  (1 << 5)        /* bulk list enable */
+#define OHCI_CTRL_HCFS (3 << 6)        /* host controller functional state */
+#define OHCI_CTRL_IR   (1 << 8)        /* interrupt routing */
+#define OHCI_CTRL_RWC  (1 << 9)        /* remote wakeup connected */
+#define OHCI_CTRL_RWE  (1 << 10)       /* remote wakeup enable */
+
+/* pre-shifted values for HCFS */
+#define OHCI_USB_RESET (0 << 6)
+#define OHCI_USB_RESUME        (1 << 6)
+#define OHCI_USB_OPER  (2 << 6)
+#define OHCI_USB_SUSPEND       (3 << 6)
+
+/*
+ * HcCommandStatus (cmdstatus) register masks
+ */
+#define OHCI_HCR       (1 << 0)        /* host controller reset */
+#define OHCI_CLF       (1 << 1)        /* control list filled */
+#define OHCI_BLF       (1 << 2)        /* bulk list filled */
+#define OHCI_OCR       (1 << 3)        /* ownership change request */
+#define OHCI_SOC       (3 << 16)       /* scheduling overrun count */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO   (1 << 0)        /* scheduling overrun */
+#define OHCI_INTR_WDH  (1 << 1)        /* writeback of done_head */
+#define OHCI_INTR_SF   (1 << 2)        /* start frame */
+#define OHCI_INTR_RD   (1 << 3)        /* resume detect */
+#define OHCI_INTR_UE   (1 << 4)        /* unrecoverable error */
+#define OHCI_INTR_FNO  (1 << 5)        /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6)        /* root hub status change */
+#define OHCI_INTR_OC   (1 << 30)       /* ownership change */
+#define OHCI_INTR_MIE  (1 << 31)       /* master interrupt enable */
+
+/*
+ * masks used with interrupt registers:
+ * HcInterruptStatus (intrstatus)
+ * HcInterruptEnable (intrenable)
+ * HcInterruptDisable (intrdisable)
+ */
+#define OHCI_INTR_SO   (1 << 0)        /* scheduling overrun */
+#define OHCI_INTR_WDH  (1 << 1)        /* writeback of done_head */
+#define OHCI_INTR_SF   (1 << 2)        /* start frame */
+#define OHCI_INTR_RD   (1 << 3)        /* resume detect */
+#define OHCI_INTR_UE   (1 << 4)        /* unrecoverable error */
+#define OHCI_INTR_FNO  (1 << 5)        /* frame number overflow */
+#define OHCI_INTR_RHSC (1 << 6)        /* root hub status change */
+#define OHCI_INTR_OC   (1 << 30)       /* ownership change */
+#define OHCI_INTR_MIE  (1 << 31)       /* master interrupt enable */
+
+
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT      (3 << 0)
+#define        OHCI_INTR_INIT \
+               (OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE \
+               | OHCI_INTR_RD | OHCI_INTR_WDH)
+
+/* OHCI ROOT HUB REGISTER MASKS */
+
+/* roothub.portstatus [i] bits */
+#define RH_PS_CCS            0x00000001                /* current connect status */
+#define RH_PS_PES            0x00000002                /* port enable status*/
+#define RH_PS_PSS            0x00000004                /* port suspend status */
+#define RH_PS_POCI           0x00000008                /* port over current indicator */
+#define RH_PS_PRS            0x00000010                /* port reset status */
+#define RH_PS_PPS            0x00000100                /* port power status */
+#define RH_PS_LSDA           0x00000200                /* low speed device attached */
+#define RH_PS_CSC            0x00010000                /* connect status change */
+#define RH_PS_PESC           0x00020000                /* port enable status change */
+#define RH_PS_PSSC           0x00040000                /* port suspend status change */
+#define RH_PS_OCIC           0x00080000                /* over current indicator change */
+#define RH_PS_PRSC           0x00100000                /* port reset status change */
+
+/* roothub.status bits */
+#define RH_HS_LPS           0x00000001         /* local power status */
+#define RH_HS_OCI           0x00000002         /* over current indicator */
+#define RH_HS_DRWE          0x00008000         /* device remote wakeup enable */
+#define RH_HS_LPSC          0x00010000         /* local power status change */
+#define RH_HS_OCIC          0x00020000         /* over current indicator change */
+#define RH_HS_CRWE          0x80000000         /* clear remote wakeup enable */
+
+/* roothub.b masks */
+#define RH_B_DR                0x0000ffff              /* device removable flags */
+#define RH_B_PPCM      0xffff0000              /* port power control mask */
+
+/* roothub.a masks */
+#define        RH_A_NDP        (0xff << 0)             /* number of downstream ports */
+#define        RH_A_PSM        (1 << 8)                /* power switching mode */
+#define        RH_A_NPS        (1 << 9)                /* no power switching */
+#define        RH_A_DT         (1 << 10)               /* device type (mbz) */
+#define        RH_A_OCPM       (1 << 11)               /* over current protection mode */
+#define        RH_A_NOCP       (1 << 12)               /* no over current protection */
+#define        RH_A_POTPGT     (0xff << 24)            /* power on to power good time */
+
+struct ohci_hcca {
+#define NUM_INITS 32
+       u32 int_table[NUM_INITS]; /* periodic schedule */
+       /*
+        * OHCI defines u16 frame_no, followed by u16 zero pad.
+        * Since some processors can't do 16 bit bus accesses,
+        * portable access must be a 32 bits wide.
+        */
+       u32     frame_no;               /* current frame number */
+       u32     done_head;              /* info returned for an interrupt */
+       u8 reserved_for_hc [116];
+       u8 what [4];            /* spec only identifies 252 bytes :) */
+} ALIGNED(256);
+
+#endif
+
diff --git a/usb/host/sl811hs-hcd.c b/usb/host/sl811hs-hcd.c
new file mode 100644 (file)
index 0000000..2270384
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file: sl811hs-hcdi.c
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "host.h"
+#include "sl811hs.h"
+#include <wait.h>
+#include <stdlib.h>
+
+#include "uart.h"
+#include "wait.h"
+
+#include <core/core.h>
+//#include <class/hub.h>
+#include <usbspec/usb11spec.h>
+
+void sl811_roothub_probe();
+void sl811_roothub_check();
+
+void sl811_start_transfer();
+
+usb_device * device_on_downstream;
+
+
+/* cuurent transferdescriptor on port a and port b */
+usb_transfer_descriptor * td_usba;
+usb_transfer_descriptor * td_usbb;
+
+usb_driver sl811_roothub = {
+  .name          = "sl811_roothub",
+  .probe  = sl811_roothub_probe,
+  .check  = sl811_roothub_check,
+  .data          = NULL,
+};
+
+/**
+ * Find and initial root hub
+ */
+void sl811_roothub_probe()
+{
+  // called on n every new enumeration and at usb_register_driver  
+  // der sollte nach dem ersten aufruf igonriert werden
+  // oder diese funktion bleibt einfach leer
+  #if DEBUG
+  core.stdout("Probe: SL811 Root Hub\r\n");
+  #endif
+}
+
+
+/**
+ * This function is called periodical, to notice
+ * port changes after an hub
+ */
+void sl811_roothub_check()
+{
+  /* hier muss man nur dafuer sorgen wenn ein geaert angesteckt
+   * wird, dass der entsprechende port auf reset gesetzt wird
+   * damit das device die adresse 0 annimmt
+   * und dann muss man usb_add_device aufrufen
+   *
+   * wenn ein geraet entfernt wird muss man nur usb_remove_device aufrufen
+   * und es muss dabei das richtige geraet angegeben werden.
+   * dieses muss man sich wahrscheinlich intern im treiber
+   * merken...
+   */
+  // check for new device 
+  u16 *port_change = (u16*)sl811_roothub.data;
+  
+  u8 status = sl811_read(SL811_ISR);
+  sl811_write(SL811_ISR,SL811_ISR_DATA | SL811_ISR_SOFTIMER);
+
+  #define HUB_PORTSTATUS_C_PORT_CONNECTION 1
+  if((status & SL811_ISR_RESET)) {  // TODO und bit x von CTRL
+    // remove device if neccessary
+    if(device_on_downstream!=NULL){
+      #if USBMON
+      core.stdout("Remove Device!\r\n");
+      #endif
+      usb_remove_device(device_on_downstream);
+      device_on_downstream=NULL;
+    }
+    
+    sl811_write(SL811_ISR,SL811_ISR_RESET);
+  } else {
+    if((port_change[0] & HUB_PORTSTATUS_C_PORT_CONNECTION)){
+      #if USBMON
+      core.stdout("Find new Device!\r\n");
+      #endif
+      
+      /* init sof currently for fullspeed  (datasheet page 11)*/
+      sl811_write(SL811_CSOF,0xAE);
+      sl811_write(SL811_DATA,0xE0);
+
+      /* reset device that function can answer to address 0 */
+      sl811_write(SL811_IER,0x00);
+      sl811_write(SL811_CTRL,SL811_CTRL_ENABLESOF|SL811_CTRL_RESETENGINE);
+      sl811_write(SL811_ISR,0xff);
+      wait_ms(20);
+
+      /* start SOF generation */
+      sl811_write(SL811_CTRL,SL811_CTRL_ENABLESOF);
+      sl811_write(SL811_ISR,0xff);
+      sl811_write(SL811_E0BASE,SL811_EPCTRL_ARM);
+      wait_ms(50);
+      
+      device_on_downstream = usb_add_device();
+
+      /* set internate port state 1=device is online */
+      port_change[0]=0x00;
+
+    }
+  }
+
+  if((status & SL811_ISR_INSERT)){
+    port_change[0] |= HUB_PORTSTATUS_C_PORT_CONNECTION;
+    sl811_write(SL811_ISR,SL811_ISR_INSERT);
+  }
+
+}
+
+
+void hcdi_init()
+{
+  /* find and initial host controller */
+  sl811_init();
+  u8 rev = sl811_read(SL811_REV)>>4;
+
+  switch(rev) {
+    case 1:
+      #if USBMON
+      core.stdout("Host: SL811HS v1.2 found\r\n");
+      #endif
+    break;
+    case 2:
+      #if USBMON
+      core.stdout("Host: SL811HS v1.5 found\r\n");
+      #endif
+    break;
+    default:
+      #if USBMON 
+      core.stdout("Can't find SL811!\r\n"); 
+      #endif
+      return;
+  }
+  /* Disable interrupt, then wait 40 ms */
+  sl811_write(SL811_IER,0x00);
+
+  /* Initialize controller */
+  //sl811_write(SL811_CSOF,0xae);
+  sl811_write(SL811_CSOF,SL811_CSOF_MASTER);
+
+  /* clear interrupt status register with one read operation */
+  sl811_write(SL811_ISR,0xff);
+
+  /* data = hub flags */
+  u16 *port_change = (u16*)malloc(sizeof(u16));
+  port_change[0] = 0x00;
+  port_change[1] = 0x00;
+  sl811_roothub.data = (void*)port_change;
+  device_on_downstream = NULL;
+
+
+  /* register virtual root hub driver */
+  usb_register_driver(&sl811_roothub);
+
+  
+  /* activate interrupts */
+  sl811_write(SL811_IER,SL811_IER_USBA);
+}
+
+/**
+ * hcdi_enqueue takes usb_irp and split it into
+ * several usb packeges (SETUP,IN,OUT)
+ * In the usbstack they are transported with the
+ * usb_transfer_descriptor data structure.
+ */
+
+u8 hcdi_enqueue(usb_transfer_descriptor *td)
+{
+  #if LIBMODE
+  td_usba = td;
+  sl811_start_transfer();
+  #endif
+  return 1;
+}
+
+
+u8 hcdi_dequeue(usb_transfer_descriptor *td)
+{
+  return 1;
+}
+
+
+
+void hcdi_irq()
+{
+  core.stdout("interrupt\r\n");
+  u8 state;
+  state = sl811_read(SL811_ISR);
+  if(state & SL811_ISR_USBA) {
+    core.stdout("a done\r\n");
+  }
+  if(state & SL811_ISR_USBB) {
+    core.stdout("b done\r\n");
+  }
+  if(state & SL811_ISR_RESET) {
+    core.stdout("reset\r\n");
+  }
+  
+  if(state & SL811_ISR_INSERT) {
+    core.stdout("insert\r\n");
+  }
+
+  sl811_write(SL811_ISR,0xFF);
+}
+
+
+
+void sl811_start_transfer()
+{
+  usb_transfer_descriptor * td;
+
+  #if LIBMODE
+  /* choose next free port */
+  td = td_usba;
+  /* disable a done interrupt */
+  sl811_write(SL811_IER,0x00); 
+  #endif
+
+  #if USBMON
+    //core.stdout("");
+  #endif
+
+  sl811_write(SL811_E0CONT,td->devaddress);    /* device address */
+  sl811_write(SL811_E0LEN,td->actlen);         /* number of bytes to transfer */
+  sl811_write(SL811_E0ADDR,cMemStart);         /* set address to buffer in sl811 ram */
+
+  switch(td->pid) {
+    case USB_PID_SETUP:
+      //core.stdout("*setup\r\n");
+      /* copy data into ram of sl811 */
+      sl811_write_buf(cMemStart,(unsigned char *)td->buffer,td->actlen);
+      
+      sl811_write(SL811_E0STAT,PID_SETUP|td->endpoint); /* set pid and ep */
+      sl811_write(SL811_E0CTRL,DATA0_WR);              /* send setup packet with DATA0 */
+      td->state = USB_TRANSFER_DESCR_SEND;
+
+      /* wait ack */
+      #if LIBMODE
+      while((sl811_read(SL811_ISR)&SL811_ISR_USBA)==0);
+      //wait_ms(1);
+      #endif
+
+    break;
+    
+    case USB_PID_IN:
+      //core.stdout("*in\r\n");
+      #if LIBMODE
+      wait_ms(2);
+      #endif
+      
+      sl811_write(SL811_E0STAT,PID_IN|td->endpoint); /* set pid and ep */
+      sl811_write(SL811_ISR,0xff);
+     
+      /* choose data0 or data1 */
+      if(td->togl)
+       sl811_write(SL811_E0CTRL,DATA1_RD);             /* send setup packet with DATA0 */
+      else
+       sl811_write(SL811_E0CTRL,DATA0_RD);             /* send setup packet with DATA0 */
+
+      td->state = USB_TRANSFER_DESCR_SEND;
+  
+      /* wait ack */
+      #if LIBMODE
+      while((sl811_read(SL811_ISR)&SL811_ISR_USBA)==0);
+      //wait_ms(1);
+      
+      /* copy received data from internal sl811 ram */
+      sl811_read_buf(cMemStart,(unsigned char *)td->buffer,td->actlen);
+      
+      #endif
+
+    break;
+    
+    case USB_PID_OUT:
+      //core.stdout("*out\r\n");
+      #if LIBMODE
+      wait_ms(2);
+      #endif
+
+      /* copy data into ram of sl811 */
+      if(td->actlen>0)
+       sl811_write_buf(cMemStart,(unsigned char *)td->buffer,td->actlen);
+
+      sl811_write(SL811_E0STAT,PID_OUT|td->endpoint); /* set pid and ep */
+  
+      /* choose data0 or data1 */
+      if(td->togl)
+       sl811_write(SL811_E0CTRL,DATA1_WR);             /* send setup packet with DATA0 */
+      else
+       sl811_write(SL811_E0CTRL,DATA0_WR);             /* send setup packet with DATA0 */
+
+      td->state = USB_TRANSFER_DESCR_SEND;
+
+      /* wait ack */
+      #if LIBMODE
+      while((sl811_read(SL811_ISR)&SL811_ISR_USBA)==0);
+      //wait_ms(1);
+      #endif
+
+    break;
+
+
+  }
+
+
+}
+
+
diff --git a/usb/host/sl811hs.h b/usb/host/sl811hs.h
new file mode 100644 (file)
index 0000000..b5d8ab4
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file (sl811hs.h):
+ * Register definitions of SL811, created from the datasheet
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SL811HS_H
+#define _SL811HS_H
+
+/* prototypes for communication functions */
+void sl811_init();
+void sl811_reset();
+void sl811_write(u8 addr, u8 data);
+u8 sl811_read(u8 addr);
+
+void sl811_write_burst(u8 data);
+u8 sl811_read_burst();
+
+void sl811_write_buf(u8 addr, unsigned char *buffer,u8 size);
+void sl811_read_buf(u8 addr, unsigned char *buffer,u8 size);
+
+/*
+ *  * ScanLogic SL811HS/T USB Host Controller
+ *   */
+
+#define SL811_IDX_ADDR (0x00)
+#define SL811_IDX_DATA (0x01)
+#define SL811_PORTSIZE (0x02)
+
+#define SL811_E0BASE (0x00)    /* Base of Control0 */
+#define SL811_E0CTRL (0x00)    /* Host Control Register */
+#define SL811_E0ADDR (0x01)    /* Host Base Address */
+#define SL811_E0LEN  (0x02)    /* Host Base Length */
+#define SL811_E0STAT (0x03)    /* USB Status (Read) */
+#define SL811_E0PID  SL811_E0STAT      /* Host PID, Device Endpoint (Write) */
+#define SL811_E0CONT (0x04)    /* Transfer Count (Read) */
+#define SL811_E0DEV  SL811_E0CONT      /* Host Device Address (Write) */
+
+#define SL811_E1BASE (0x08)    /* Base of Control1 */
+#define SL811_E1CTRL (SL811_E1BASE + SL811_E0CTRL)
+#define SL811_E1ADDR (SL811_E1BASE + SL811_E0ADDR)
+#define SL811_E1LEN  (SL811_E1BASE + SL811_E0LEN)
+#define SL811_E1STAT (SL811_E1BASE + SL811_E0STAT)
+#define SL811_E1PID  (SL811_E1BASE + SL811_E0PID)
+#define SL811_E1CONT (SL811_E1BASE + SL811_E0CONT)
+#define SL811_E1DEV  (SL811_E1BASE + SL811_E0DEV)
+
+#define SL811_CTRL (0x05)    /* Control Register1 */
+#define SL811_IER  (0x06)    /* Interrupt Enable Register */
+#define SL811_ISR  (0x0d)    /* Interrupt Status Register */
+#define SL811_DATA (0x0e)    /* SOF Counter Low (Write) */
+#define SL811_REV  SL811_DATA /* HW Revision Register (Read) */
+#define SL811_CSOF  (0x0f)    /* SOF Counter High(R), Control2(W) */
+#define SL811_MEM  (0x10)    /* Memory Buffer (0x10 - 0xff) */
+
+#define SL811_EPCTRL_ARM         (0x01)
+#define SL811_EPCTRL_ENABLE  (0x02)
+#define SL811_EPCTRL_DIRECTION (0x04)
+#define SL811_EPCTRL_ISO         (0x10)
+#define SL811_EPCTRL_SOF         (0x20)
+#define SL811_EPCTRL_DATATOGGLE        (0x40)
+#define SL811_EPCTRL_PREAMBLE  (0x80)
+
+#define SL811_EPPID_PIDMASK  (0xf0)
+#define SL811_EPPID_EPMASK (0x0f)
+
+#define SL811_EPSTAT_ACK         (0x01)
+#define SL811_EPSTAT_ERROR (0x02)
+#define SL811_EPSTAT_TIMEOUT (0x04)
+#define SL811_EPSTAT_SEQUENCE  (0x08)
+#define SL811_EPSTAT_SETUP (0x10)
+#define SL811_EPSTAT_OVERFLOW  (0x20)
+#define SL811_EPSTAT_NAK         (0x40)
+#define SL811_EPSTAT_STALL (0x80)
+
+#define SL811_CTRL_ENABLESOF (0x01)
+#define SL811_CTRL_EOF2          (0x04)
+#define SL811_CTRL_RESETENGINE (0x08)
+#define SL811_CTRL_JKSTATE (0x10)
+#define SL811_CTRL_LOWSPEED  (0x20)
+#define SL811_CTRL_SUSPEND (0x40)
+
+#define SL811_IER_USBA (0x01)  /* USB-A done */
+#define SL811_IER_USBB (0x02)  /* USB-B done */
+#define SL811_IER_BABBLE         (0x04)  /* Babble detection */
+#define SL811_IER_SOFTIMER (0x10)  /* 1ms SOF timer */
+#define SL811_IER_INSERT         (0x20)  /* Slave Insert/Remove detection */
+#define SL811_IER_RESET          (0x40)  /* USB Reset/Resume */
+
+#define SL811_ISR_USBA (0x01)  /* USB-A done */
+#define SL811_ISR_USBB (0x02)  /* USB-B done */
+#define SL811_ISR_BABBLE         (0x04)  /* Babble detection */
+#define SL811_ISR_SOFTIMER (0x10)  /* 1ms SOF timer */
+#define SL811_ISR_INSERT         (0x20)  /* Slave Insert/Remove detection */
+#define SL811_ISR_RESET          (0x40)  /* USB Reset/Resume */
+#define SL811_ISR_DATA (0x80)  /* Value of the Data+ pin */
+
+#define SL811_REV_USBA (0x01)  /* USB-A */
+#define SL811_REV_USBB (0x02)  /* USB-B */
+#define SL811_REV_REVMASK  (0xf0)  /* HW Revision */
+#define SL811_REV_REVSL811H (0x00)  /* HW is SL811H */
+#define SL811_REV_REVSL811HS (0x10)  /* HW is SL811HS */
+
+#define SL811_CSOF_SOFMASK  (0x3f)  /* SOF High Counter */
+#define SL811_CSOF_POLARITY (0x40)  /* Change polarity */
+#define SL811_CSOF_MASTER (0x80)  /* Master/Slave selection */
+
+
+#define cMemStart 0x10
+#define ubufA    0x80
+#define ubufB    0xc0
+#define        uxferLen  0x40
+#define sMemSize  0xc0
+#define        cMemEnd   256
+
+
+#define EP0Buf 0x40
+#define EP0Len 0x40
+
+#define DATA0_WR  0x07
+#define DATA1_WR  0x47
+
+#define ZDATA0_WR 0x05
+#define ZDATA1_WR 0x45
+
+#define DATA0_RD  0x03
+#define DATA1_RD  0x43
+
+#define PID_SOF          0x50
+#define PID_SETUP 0xd0
+#define PID_IN   0x90
+#define PID_OUT          0x10
+#define PID_PRE          0xc0
+#define PID_NAK          0xa0
+#define PID_STALL 0xe0
+#define PID_DATA0 0x30
+#define PID_DATA1 0xb0
+
+
+#endif /* _SL811HS_H */
+
diff --git a/usb/lib/list.c b/usb/lib/list.c
new file mode 100644 (file)
index 0000000..05ffc07
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+//#include <stdlib.h>
+#include "list.h"
+#include "../../malloc.h"
+
+list* list_create()
+{
+  list *l = (list*)malloc(sizeof(list));
+  l->head = NULL;
+  return l;
+}
+
+u8 list_add_tail(list *l, element *e)
+{
+  e->next = NULL;
+
+  /* if head is empty put first element here */
+  if(l->head==NULL){
+    l->head = e;
+    return 1;
+  }
+
+  /* find last element */
+  element * iterator;
+  iterator = l->head;
+
+  while(iterator->next!=NULL) {
+    iterator = iterator->next;
+  } 
+  iterator->next = e;
+
+  return 1;
+}
+
+
+
+// FIXME: untested and unused!! 
+u8 list_delete_element(list *l, element *e)
+{
+  return 1;
+}
+
+// FIXME: untested and unused!! 
+u8 list_is_element_last(list *l, element *e)
+{
+  if(e->next==NULL)
+    return 1;
+  else
+    return 0;
+}
+
+
+
+// FIXME: untested and unused!! 
+element * list_find_next_element(list *l, element *e)
+{
+  element * iterator;
+  iterator = l->head;
+
+  while(iterator!=NULL){
+    if(iterator == e)
+      return iterator->next;
+    iterator = iterator->next;
+  }
+  return NULL;
+}
+
diff --git a/usb/lib/list.h b/usb/lib/list.h
new file mode 100644 (file)
index 0000000..392f28b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _LIST_H_
+#define _LIST_H_
+
+#include "../../types.h"
+
+
+typedef struct element_t element;
+struct element_t {
+  void * data;
+  element * next;
+};
+
+
+typedef struct list_t list;
+struct list_t {
+  element * head;
+};
+
+
+
+list* list_create();
+
+u8 list_add_tail(list *l, element *e);
+u8 list_delete_element(list *l, element *e);
+
+u8 list_is_element_last(list *l, element *e);
+
+element * list_find_next_element(list *l, element *e);
+
+
+#endif // _LIST_H_
diff --git a/usb/uclibusb/ft232.c b/usb/uclibusb/ft232.c
new file mode 100644 (file)
index 0000000..73380eb
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <lib/types.h>
+
+#include <core/usb.h>
+#include <usbspec/usb11spec.h>
+
+#include "ft232.h"
+
+/** 
+ * Find and open an FT232 on bus.
+ */
+usb_device * usb_ft232_open()
+{
+  usb_device * dev = usb_open(0x0403,0x6001);
+  char tmp[8];
+
+  if(dev!=NULL) {
+    usb_control_msg(dev, 0x00,SET_CONFIGURATION,0x0100, 0, 0,tmp, 8, 0);
+
+    usb_control_msg(dev, 0x40, 0,0, 0,  0,tmp, 8, 0);
+    usb_control_msg(dev, 0x40, 4,8, 0,  0,tmp, 8, 0);
+    usb_control_msg(dev, 0x40, 3,0x4138, 0,  0,tmp, 8, 0);
+    usb_control_msg(dev, 0x40, 1,0x0303, 0,  0,tmp, 8, 0);
+    usb_control_msg(dev, 0x40, 2,0, 0,  0,tmp, 8, 0);
+    usb_control_msg(dev, 0x40, 1,0x0303, 0,  0,tmp, 8, 0);
+  } else {
+    dev = NULL;
+  }
+  return dev;
+}
+
+/**
+ * Close the opened FT232.
+ */
+void usb_ft232_close(usb_device *dev)
+{
+  return;
+}
+
+/**
+ * Send a buffer.
+ */
+u8 usb_ft232_send(usb_device *dev,char *bytes, u8 length)
+{
+  char tmp[8];
+  usb_bulk_write(dev, 2, bytes, length, 0);
+  usb_control_msg(dev, 0x40, 2,0, 0,  0,tmp, 8, 0);
+  usb_control_msg(dev, 0x40, 1,0x0300, 0,  0,tmp, 8, 0);
+  return 1;
+}
+
+/**
+ * Receive some values.
+ */
+u8 usb_ft232_receive(usb_device *dev,char *bytes, u8 length)
+{
+  usb_bulk_read(dev, 1,  bytes, length,0);
+  return 1;
+}
diff --git a/usb/uclibusb/ft232.h b/usb/uclibusb/ft232.h
new file mode 100644 (file)
index 0000000..dfff678
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __FT232_H
+#define __FT232_H
+#include "../../types.h"
+
+usb_device * usb_ft232_open();
+void usb_ft232_close(usb_device *dev);
+u8 usb_ft232_send(usb_device *dev,char *bytes, u8 length);
+u8 usb_ft232_receive(usb_device *dev,char *bytes, u8 length);
+
+#endif /* __FT232_H */
diff --git a/usb/usbspec/request.c b/usb/usbspec/request.c
new file mode 100644 (file)
index 0000000..555fb6e
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "usb11spec.h"
+#include "request.h"
+
+void request_usb_get_device_descriptor(char *buf, u8 len)
+{
+       //struct usb_device_request * req = (struct usb_device_request*)buf;
+       // 0x80,0x06,0x00,0x01, 0x00,0x00,0x40,0x00
+       buf[0] = 0x80;
+       buf[1] = 0x06;
+       buf[2] = 0x00;
+       buf[3] = 0x01;
+       buf[4] = 0x00;
+       buf[5] = 0x00;
+       buf[6] = len;
+       buf[7] = 0x00;
+       /*
+       req->bmRequestType=0x80;
+       req->bRequest=GET_DESCRIPTOR;
+       req->wValue=DEVICE;
+       req->wIndex=0x0000;
+       req->wLength=len<<8;
+       */
+}
+
+
+void request_usb_set_address(char *buf, u8 addr)
+{
+       buf[0] = 0x00;
+       buf[1] = 0x05;
+       buf[2] = addr;
+       buf[3] = 0x00;
+       buf[4] = 0x00;
+       buf[5] = 0x00;
+       buf[6] = 0x00;
+       buf[7] = 0x00;
+}
+
diff --git a/usb/usbspec/request.h b/usb/usbspec/request.h
new file mode 100644 (file)
index 0000000..c31f6d7
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2006, Benedikt Sauter <sauter@ixbat.de>
+ * All rights reserved.
+ *
+ * Short descripton of file:
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright 
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the following 
+ *     disclaimer in the documentation and/or other materials provided 
+ *     with the distribution.
+ *   * Neither the name of the FH Augsburg nor the names of its 
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __REQUEST_H
+#define __REQUEST_H
+#include "../../types.h"
+
+void request_usb_get_device_descriptor(char *buf, u8 len);
+
+void request_usb_set_address(char *buf, u8 addr);
+
+#endif /*__REQUEST_H */
diff --git a/usb/usbspec/usb11spec.h b/usb/usbspec/usb11spec.h
new file mode 100644 (file)
index 0000000..7958fb3
--- /dev/null
@@ -0,0 +1,191 @@
+/* usb11spec.h
+* Copyright (C) 2005  Benedikt Sauter
+*
+* 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
+*/
+#ifndef _USB11PSEC_H
+#define _USB11SPEC_H
+
+/*-------------------------------------------
+ * device descriptor 
+ * ------------------------------------------*/
+struct usb_device_descriptor 
+{
+       unsigned char   bLength;
+       unsigned char   bDescriptorType;
+       unsigned short  bcdUSB;
+       unsigned char   bDeviceClass;
+       unsigned char   bDeviceSubClass;
+       unsigned char   bDeviceProtocol;
+       unsigned char   bMaxPacketSize0;
+       unsigned short  idVendor;
+       unsigned short  idProduct;
+       unsigned short  bcdDevice;
+       unsigned char   iManufacturer;
+       unsigned char   iProduct;
+       unsigned char   iSerialNumber;
+       unsigned char   bNumConfigurations;
+};
+
+/*-------------------------------------------
+ * configuration descriptor 
+ * ------------------------------------------*/
+
+struct usb_configuration_descriptor 
+{
+       unsigned char   bLength;
+       unsigned char   bDescriptorType;
+       unsigned short  wTotalLength;
+       unsigned char   bNumInterfaces;
+       unsigned char   bConfigurationValue;
+       unsigned char   iConfiguration;
+       unsigned char   bmAttributes;
+       unsigned char   MaxPower;
+};
+
+/*-------------------------------------------
+ * interface descriptor 
+ * ------------------------------------------*/
+
+struct usb_interface_descriptor 
+{
+       unsigned char   bLength;
+       unsigned char   bDescriptorType;
+       unsigned char   bInterfaceNumber;
+       unsigned char   bAlternateSetting;
+       unsigned char   bNumEndpoints;
+       unsigned char   bInterfaceClass;
+       unsigned char   bInterfaceSubClass;
+       unsigned char   bInterfaceProtocol;
+       unsigned char   iInterface;
+};
+
+
+/*-------------------------------------------
+ * endpoint descriptor 
+ * ------------------------------------------*/
+struct usb_endpoint_descriptor 
+{
+       unsigned char   bLength;
+       unsigned char   bDescriptorType;
+       unsigned char   bEndpointAddress;
+       unsigned char   bmAttributes;
+       unsigned short  wMaxPacketSize;
+       unsigned char   bIntervall;
+};
+
+
+
+/*-------------------------------------------
+ * string descriptor 
+ * ------------------------------------------*/
+struct usb_string_descriptor 
+{
+       unsigned char   bLength;
+       unsigned char   bDescriptorType;
+       unsigned char*  String;
+};
+
+
+
+
+/*-------------------------------------------
+ * USB Device Request
+ * ------------------------------------------*/
+typedef struct usb_device_request_t usb_device_request;
+struct usb_device_request_t
+{
+       unsigned char bmRequestType;
+       unsigned char bRequest;
+       unsigned short wValue;
+       unsigned short wIndex;  
+       unsigned short wLength;
+};
+
+/*-------------------------------------------
+ * Get Device Descriptor Request
+ * ------------------------------------------*/
+//char GetDeviceDescriptor[] {0x80,GET_DESCRIPTOR, DEVICE,0x00, 0x00,0x00,0x00,0x40};
+//char GetDeviceDescriptor[] {0x80,GET_DESCRIPTOR, DEVICE,0x00, 0x00,0x00,0x00,0x40};
+//char SetAddress[] {0x00,SET_ADDRESS, 0x00, address, 0x00,0x00,0x00,0x40};
+//char SetAddress[] {0x00,SET_ADDRESS, 0x00, 0x00, 0x00,0x00,0x00,0x00};
+
+
+/*------------------------------------------
+ * transfer types 
+ * ------------------------------------------*/
+
+#define USB_CTRL               0x00
+#define USB_ISOC               0x01
+#define USB_BULK               0x02
+#define USB_INTR               0x03
+
+/*-------------------------------------------
+ * device descriptor types 
+ * ------------------------------------------*/
+#define DO_STANDARD   0x00
+#define DO_CLASS      0x20
+#define DO_VENDOR     0x40
+
+/*-------------------------------------------
+ * standard requests for ep0 
+ * ------------------------------------------*/
+
+#define GET_STATUS             0x00 
+#define CLR_FEATURE            0x01
+#define SET_FEATURE            0x03
+#define SET_ADDRESS            0x05
+#define GET_DESCRIPTOR         0x06
+#define SET_DESCRIPTOR         0x07
+#define GET_CONFIGURATION      0x08
+#define SET_CONFIGURATION      0x09
+#define GET_INTERFACE          0x0A
+#define SET_INTERFACE          0x0B
+
+/*-------------------------------------------
+ * descriptor types 
+ * ------------------------------------------*/
+
+#define DEVICE                 0x01
+#define CONFIGURATION          0x02
+#define STRING                 0x03
+#define INTERFACE              0x04
+#define ENDPOINT               0x05
+#define DEVICEQUALIFIER                0x06 // only usb2.0
+#define OTHERSPEEDCONFIGURATION 0x07 // only usb2.0
+
+
+/*-------------------------------------------
+ * pid fields 
+ * ------------------------------------------*/
+
+#define USB_PID_SOF     0x05
+#define USB_PID_SETUP   0x0D
+#define USB_PID_IN      0x09
+#define USB_PID_OUT     0x01
+#define USB_PID_DATA0   0x03
+#define USB_PID_DATA1   0x0B
+#define USB_PID_ACK     0x02
+#define USB_PID_NACK    0x0A
+#define USB_PID_STALL   0x0E
+#define USB_PID_PRE     0x0C
+
+
+#define MASS_STORAGE_CLASSCODE 0x08
+#define HUB_CLASSCODE          0x09
+
+
+
+#endif /* __USB11SPEC_H__ */