📄 udc.patch
字号:
diff -Nru linux26-cvs/Documentation/usb/amd5536udc.txt linux26-amd/Documentation/usb/amd5536udc.txt--- linux26-cvs/Documentation/usb/amd5536udc.txt 1970-01-01 01:00:00.000000000 +0100+++ linux26-amd/Documentation/usb/amd5536udc.txt 2005-06-22 13:46:09.755480000 +0200@@ -0,0 +1,183 @@+-------------------------------------------------------------------------------+Howto for Linux device driver for the AMD5536 USB Device Controller (UDC)+for gadget driver stack+-------------------------------------------------------------------------------++Author: Thomas Dahlmann++INTRODUCTION:++The AMD5536 UDC is part of x86 southbridge AMD5536 and MIPS CPU Au1200.+It is a DMA capable usb device controller. The usb port is shared+between host and UDC. The on-chip OTG controller is used to switch the+usb port between host, UDC and neutral. So amd5536otg driver is needed+to get the UDC operating.++-------------------------------------------------------------------------------+WHAT YOU NEED:+-------------------------------------------------------------------------------++copy/replace following files to /usr/src/linux/drivers/usb/gadget+ amd5536udc.c+ amd5536udc.h+ amd5536otg-fsm.c+ amd5536otg.h+ amd5536uoc.c+ amd5536uoc.h+ ether.c+ file_storage.c+ zero.c+ gadget_chips.h+ Makefile+ Kconfig ++-------------------------------------------------------------------------------+HOW TO INSTALL IT:+-------------------------------------------------------------------------------++change to directory /usr/src/linux++configure gadget as module:+ "make menuconfig"+ under "Code maturity level options" choose "Prompt for development ..."+ goto "Device Drivers"+ goto "USB support" -> "USB Gadget support"+ choose "Support for USB Gadgets" as module+ under choice "USB Peripheral Controller" choose "AMD5536-UDC"+ under "USB Gadget Drivers"+ choose "Gadget Zero" as module or+ choose "Ethernet Gagdet" as module or+ choose "File-backed Storage Gadget" as module+ choose "AMD5536 USB portmux control (On-The-Go support)"+ under choice "OTG port functionality" choose "Gadget only"+ exit and save config++compile and install modules:+ "make modules modules_install"++-------------------------------------------------------------------------------+HOW TO USE IT:+-------------------------------------------------------------------------------++*** How to load FILE-BACKED STORAGE gadget driver - mass storage ***+enable USB mass storage support for linux host:+ change to directory /usr/src/linux+ "make menuconfig"+ under "File systems" choose "DOS/FAT/NT filesystems"+ choose "MSDOS fs support"+ under "Device Drivers" under "SCSI device support"+ choose "SCSI device support"+ choose "SCSI generic support"+ under "Device Drivers" under "USB support" in section + "USB Device Class drivers" choose+ "USB Mass Storage support"+ compile new kernel+create disk file:+ "dd bs=1M count=128 if=/dev/zero of=/tmp/disk"+ => creates a 128Mbyte image file /tmp/disk+load modules:+ "modprobe amd5536udc" + "modprobe g_file_storage file=/tmp/disk"+ "modprobe amd5536otg"+create a primary FAT16 disk partition via linux host site:+ "fdisk /dev/sda", make FAT16 prim. partition+ => "n", "p", "1", "<RETURN>", "<RETURN>", "t", "6", "w",+ "mkdosfs /dev/sda1"+ "sync"+create primary disk partition via Windows XP host site:+ right click on "My Computer"+ choose "Manage" => "Disk Management"+ choose usb disk and follow instructions of partition menu+mount usb mass storage device on linux host:+ make directory "/mnt/gadget/"+ "mount -t msdos /dev/sda1 /mnt/gadget"++*** How to access files of disk image on UDC side ***+When files were copied from host to UDC mass storage device then files+are inside the monolitic disk image (see above) on UDC side. This+disk image can be mounted via the loopback device driver to a +directory on UDC side to access these files.+Steps on UDC side:+ enable kernel support for loopback device+ change to directory /usr/src/linux+ "make menuconfig"+ under "Block devices" choose "Loopback device support"+ and recompile the kernel+ determine offset inside disk image:+ "fdisk -l -u disk_image", output is like:+>> You must set cylinders.+>> You can do this from the extra functions menu.+>>+>> Disk /tmp/disk128: 5 heads, 52 sectors, 0 cylinders+>> Units = sectors of 1 * 512 bytes+>>+>> Device Boot Start End Blocks Id System+>> /tmp/disk128p1 52 262079 131014 6 FAT16++ get offset my multiplying start value by sector size:+ 52 * 512 = 26624+ mount disk image:+ "mount -o loop,offset=26624 -t msdos disk_image /mnt"+++*** How to load ZERO gadget driver - simple BULK loop back ***+load modules:+UDC driver:+ (a) Slave/Fifo mode: "modprobe amd5536udc use_dma=0"+ (b) DMA Buffer Fill mode: "modprobe amd5536udc use_dma=1" + default:+ (c) DMA PPBNDU mode: "modprobe amd5536udc" + (d) DMA PPBDU mode: "modprobe amd5536udc use_dma=1 use_dma_ppb=1 use_dma_ppb_du=1" + (e) fullspeed mode: "modprobe amd5536udc use_fullspeed=1", can be combined+ with all dma modes + (f) special higspeed+ tx buffer size: "modprobe amd5536udc hs_tx_buf=<buf_size in dwords>"+ example: "modprobe amd5536udc use_dma=1 hs_tx_buf=128"+ => buffer size = 512 bytes (=bulk max packet)+Gadget Zero driver:+ (a) Bulk loop: "modprobe g_zero"+ (b) Int loop: "modprobe g_zero use_interrupt_traffic=1"+ (c) Source/Sink "modprobe g_zero loopdefault=0"+ OUT data must all be zero's+ (d) Source/Sink count "modprobe g_zero loopdefault=0 pattern=1"+ each OUT packet must count modulo63 (0,1,..,62,0,1,..) +OTG driver: "modprobe amd5536otg"+example:+ "modprobe amd5536udc"+ "modprobe g_zero"+ "modprobe amd5536otg"+ => loads driver for DMA PPBNDU mode and Bulk loop +++*** How to use ETHERNET gadget driver (CDC protocol) ***+ with Linux Host+UDC side bringup: + load gadget modules+ "modprobe amd5536udc" + "modprobe g_ether"+ "modprobe amd5536otg"+ "ifconfig usb0 192.168.0.2" +Host side bringup: + install support for CDC Ethernet:+ change to directory /usr/src/linux+ "make menuconfig"+ under "Device Drivers" under "USB support" under+ "USB Network adapters" choose+ "Multi-purpose USB Networking Framework"+ choose "CDC Ethernet support"+ compile mew kernel+ "modprobe CDCEther"+ "ifconfig eth1 192.168.0.1"+ note: assuming there is one network card assigned to eth0,+ otherwise kernel messages of CDC Ethernet module show+ which interface (ethX) is used +Use network connection: + after bringup of host and UDC side it behaves like a normal+ ethernet connection between host and UDC+ test the connection:+ host side: "ping -I eth1 192.168.0.2"+ UDC side : "ping -I usb0 192.168.0.1"+ note: the "-I" option assures that the USB cable is used, the+ option can be omitted when the routing table is setup to avoid+ using other network interfaces as eth0+diff -Nru linux26-cvs/drivers/usb/core/otg_whitelist.h linux26-amd/drivers/usb/core/otg_whitelist.h--- linux26-cvs/drivers/usb/core/otg_whitelist.h 2005-03-23 13:53:03.000000000 +0100+++ linux26-amd/drivers/usb/core/otg_whitelist.h 2005-06-17 09:52:06.000000000 +0200@@ -22,6 +22,10 @@ { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 0), }, { USB_DEVICE_INFO(USB_CLASS_HUB, 0, 1), }, +#if defined(CONFIG_USB_PORT_AMD5536OTG) && defined(CONFIG_USB_STORAGE)+{ USB_DEVICE(0x0438, 0xdc02) },+#endif+ #ifdef CONFIG_USB_PRINTER /* ignoring nonstatic linkage! */ /* FIXME actually, printers are NOT supposed to use device classes; * they're supposed to use interface classes...@@ -31,6 +35,17 @@ { USB_DEVICE_INFO(7, 1, 3) }, #endif +#ifdef CONFIG_USB_PORT_AMD5536OTG+#if defined(CONFIG_USB_STORAGE) || defined(CONFIG_USB_STORAGE_MODULE)+/* AMD Linux-USB storage gadget */+{ USB_DEVICE(0x0438, 0xdc02) },+#endif+#if defined(CONFIG_USB_CDCETHER) || defined(CONFIG_USB_CDCETHER_MODULE)+/* AMD Linux-USB CDC Ethernet gadget */+{ USB_DEVICE(0x0438, 0xdc01) },+#endif+#endif+ #ifdef CONFIG_USB_CDCETHER /* Linux-USB CDC Ethernet gadget */ { USB_DEVICE(0x0525, 0xa4a1), },diff -Nru linux26-cvs/drivers/usb/gadget/amd5536otg-fsm.c linux26-amd/drivers/usb/gadget/amd5536otg-fsm.c--- linux26-cvs/drivers/usb/gadget/amd5536otg-fsm.c 1970-01-01 01:00:00.000000000 +0100+++ linux26-amd/drivers/usb/gadget/amd5536otg-fsm.c 2005-08-16 16:09:18.000000000 +0200@@ -0,0 +1,1333 @@+/*+ * AMD 5536 USB OTG controller driver state machine+ */++/*+ * Copyright (C) 2005 AMD (http://www.amd.com)+ * Author: Karsten Boge + *+ * 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+ */+++/*****************************************************************************+ * Includes+ *****************************************************************************/++#include <linux/config.h>+#include <linux/module.h>+#include <linux/kernel.h>+#include <linux/version.h>+#include <linux/delay.h>+#include <linux/ioport.h>+#include <linux/sched.h>+#include <linux/slab.h>+#include <linux/smp_lock.h>+#include <linux/errno.h>+#include <linux/init.h>+#include <linux/timer.h>+#include <linux/list.h>++#include <asm/byteorder.h>+#include <asm/io.h>+#include <asm/system.h>+#include <asm/unaligned.h>++/* #define DEBUG */+/* #define VERBOSE */++#ifndef CONFIG_USB_OTG+#define CONFIG_USB_OTG+#endif+#undef CONFIG_USB_OTG_ALWAYS_END_SESSION++#ifdef CONFIG_SOC_AU1X00+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,59)+#include <asm/au1000.h>+#include <asm/au1000_gpio.h>+#else+#include <asm/mach-au1x00/au1000.h>+#include <asm/mach-au1x00/au1000_gpio.h>+#endif+#endif++#define DRIVER_REVISION "01.00.0200 - $Revision: #12 $"+#define DRIVER_NAME_FOR_PRINT OTG_DRIVER_NAME+#include <linux/usb.h>+#include <linux/usb_gadget.h>+#include <linux/usb_otg.h>+#include "amd5536otg.h"+#include "amd5536uoc.h"+++/*****************************************************************************+ * Data+ *****************************************************************************/++extern u32 otg_tmr_high_count;+extern struct usb_otg_gadget_extension otg_gadget_extension;+++/*****************************************************************************+ * Function Definitions+ *****************************************************************************/++/**+ * \brief+ * Process SRP (B-device)+ *+ * Initiate or continue a Session Request+ *+ * \param otg OTG controller info+ * \param state actual HW state+ * \param event actual event state+ * \param pMask + *+ * \return void+ */+inline void process_srp (struct otg *otg, u32 state, u32 event, u32 *pMask)+{+ switch (otg->transceiver.state) {++ case OTG_STATE_B_SRP_INIT :++ if (IS_BIT_RES (OTG_STS_SESSEND, state) ||+ IS_BIT_SET (OTG_STS_LST, state)) {++ /* VBus too high | line state != SE0 => B_IDLE */++ SET_FLAG (otg, OTG_B_SRP_ERROR);+ CHANGE_STATE (otg, OTG_STATE_B_IDLE, pMask);+ }+ else {++ /* start timer => SE0 wait */++ set_srp_conditions (otg);+ SET_OTG_TIMER (otg, SRP_WAIT_SE0);+ CHANGE_STATE (otg, OTG_STATE_B_SRP_WAIT_SE0, pMask);+ }+ break;++ case OTG_STATE_B_SRP_WAIT_SE0 :++ CHECK_STATE (otg, OTG_STATE_B_SRP_WAIT_SE0, pMask);+ if (GOT_EVENT (OTG_INT_TMX, event)) {++ /* timer exp. => D_PULSE */+ /* start timer, set state */++ SET_OTG_TIMER (otg, SRP_WAIT_DP);+ CHANGE_STATE (otg, OTG_STATE_B_SRP_D_PULSE, pMask);+ }+ else if (IS_BIT_RES (OTG_STS_SESSEND, state) ||+ GOT_EVENT (OTG_INT_LSTC, event)) {++ /* VBus too high | line state != SE0 => B_IDLE */+ /* this should not happen here, */+ /* it's just to avoid a deadlock scene */+ /* Stop timer, set state */++ SET_FLAG (otg, OTG_B_SRP_ERROR);+ reset_srp_conditions (otg);+ ERR ("SRP: bus is not idle\n");+ CHANGE_STATE (otg, OTG_STATE_B_IDLE, pMask);++ /* TODO kboge: system notification */+ /* otg->transceiver.state & OTG_STATE_B_SRP_ERROR */+ }+ break;++ case OTG_STATE_B_SRP_D_PULSE :++ CHECK_STATE (otg, OTG_STATE_B_SRP_D_PULSE, pMask);+ if (GOT_EVENT (OTG_INT_TMX, event)) {++ /* D_PULSE done => V_PULSE */+ /* start timer, set state */++ SET_OTG_TIMER_LONG (otg, SRP_WAIT_VP);+ CHANGE_STATE (otg, OTG_STATE_B_SRP_V_PULSE, pMask);+ }+ break;++ case OTG_STATE_B_SRP_V_PULSE :++ CHECK_STATE (otg, OTG_STATE_B_SRP_V_PULSE, pMask);+ if (GOT_EVENT (OTG_INT_TMX, event)) {+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -