SOURCES (LINUX_2_6_14): linux-2.6-ueagle.patch (NEW) - ueagle driv...
arekm
arekm at pld-linux.org
Mon Jan 16 08:25:35 CET 2006
Author: arekm Date: Mon Jan 16 07:25:34 2006 GMT
Module: SOURCES Tag: LINUX_2_6_14
---- Log message:
- ueagle driver from 2.6.15
---- Files affected:
SOURCES:
linux-2.6-ueagle.patch (NONE -> 1.1.2.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/linux-2.6-ueagle.patch
diff -u /dev/null SOURCES/linux-2.6-ueagle.patch:1.1.2.1
--- /dev/null Mon Jan 16 08:25:34 2006
+++ SOURCES/linux-2.6-ueagle.patch Mon Jan 16 08:25:29 2006
@@ -0,0 +1,1900 @@
+From: matthieu castet <castet.matthieu at free.fr>
+Date: Mon, 7 Nov 2005 22:27:13 +0000 (+0100)
+Subject: [PATCH] USB: Eagle and ADI 930 usb adsl modem driver
+X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=b72458a80c75cab832248f536412f386e20a93a0
+
+[PATCH] USB: Eagle and ADI 930 usb adsl modem driver
+
+A driver for USB ADSL modems based on the ADI eagle chipset using the
+usb_atm infrastructure.
+
+The managing part was taken from bsd ueagle driver, other parts were
+written from scratch.
+
+The driver uses the in-kernel firmware loader :
+- to load a first usb firmware when the modem is in pre-firmware state
+- to load the dsp firmware that are swapped in host memory.
+- to load CMV (configuration and management variables) when the modem
+boot. (We can't use options or sysfs for this as there many possible
+values. See
+https://mail.gna.org/public/eagleusb-dev/2005-04/msg00031.html for a
+description of some)
+- to load fpga code for 930 chipset.
+
+The device had 4 endpoints :
+* 2 for data (use by usbatm). The incoming
+endpoint could be iso or bulk. The modem seems buggy and produce lot's
+of atm errors when using it in bulk mode for speed > 3Mbps, so iso
+endpoint is need for speed > 3Mbps. At the moment iso endpoint need a
+patched usbatm library and for this reason is not included in this patch.
+
+* One bulk endpoint for uploading dsp firmware
+
+* One irq endpoint that notices the driver
+ - if we need to upload a page of the dsp firmware
+ - an ack for read or write CMV and the value (for the read case).
+
+If order to make the driver cleaner, we design synchronous
+(read|write)_cmv :
+-send a synchronous control message to the modem
+-wait for an ack or a timeout
+-return the value if needed.
+
+In order to run these synchronous usb messages we need a kernel thread.
+
+The driver has been tested with sagem fast 800 modems with different
+eagle chipset revision and with ADI 930 since April 2005.
+
+Signed-off-by: Matthieu CASTET <castet.matthieu at free.fr>
+Signed-off-by: Andrew Morton <akpm at osdl.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>
+---
+
+--- a/drivers/usb/atm/Kconfig
++++ b/drivers/usb/atm/Kconfig
+@@ -44,6 +44,19 @@ config USB_CXACRU
+ To compile this driver as a module, choose M here: the
+ module will be called cxacru.
+
++config USB_UEAGLEATM
++ tristate "ADI 930 and eagle USB DSL modem"
++ depends on USB_ATM
++ select FW_LOADER
++ help
++ Say Y here if you have an ADSL USB modem based on the ADI 930
++ or eagle chipset. In order to use your modem you will need to
++ install firmwares and CMV (Command Management Variables); see
++ <https://gna.org/projects/ueagleatm/> for details.
++
++ To compile this driver as a module, choose M here: the
++ module will be called ueagle-atm.
++
+ config USB_XUSBATM
+ tristate "Other USB DSL modem support"
+ depends on USB_ATM
+--- a/drivers/usb/atm/Makefile
++++ b/drivers/usb/atm/Makefile
+@@ -4,6 +4,7 @@
+
+ obj-$(CONFIG_USB_CXACRU) += cxacru.o
+ obj-$(CONFIG_USB_SPEEDTOUCH) += speedtch.o
++obj-$(CONFIG_USB_UEAGLEATM) += ueagle-atm.o
+ obj-$(CONFIG_USB_ATM) += usbatm.o
+ obj-$(CONFIG_USB_XUSBATM) += xusbatm.o
+
+--- /dev/null
++++ b/drivers/usb/atm/ueagle-atm.c
+@@ -0,0 +1,1813 @@
++/*-
++ * Copyright (c) 2003, 2004
++ * Damien Bergamini <damien.bergamini at free.fr>. All rights reserved.
++ *
++ * Copyright (c) 2005 Matthieu Castet <castet.matthieu at free.fr>
++ *
++ * This software is available to you under a choice of one of two
++ * licenses. You may choose to be licensed under the terms of the GNU
++ * General Public License (GPL) Version 2, available from the file
++ * COPYING in the main directory of this source tree, or the
++ * BSD license below:
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ * notice unmodified, this list of conditions, and the following
++ * disclaimer.
++ * 2. 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.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
++ *
++ * GPL license :
++ * 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.
++ *
++ *
++ * HISTORY : some part of the code was base on ueagle 1.3 BSD driver,
++ * Damien Bergamini agree to put his code under a DUAL GPL/BSD license.
++ *
++ * The rest of the code was was rewritten from scratch.
++ */
++
++#include <linux/module.h>
++#include <linux/moduleparam.h>
++#include <linux/init.h>
++#include <linux/crc32.h>
++#include <linux/usb.h>
++#include <linux/firmware.h>
++#include <linux/ctype.h>
++#include <linux/kthread.h>
++#include <linux/version.h>
++#include <asm/unaligned.h>
++
++#include "usbatm.h"
++
++#define EAGLEUSBVERSION "ueagle 1.1"
++
++
++/*
++ * Debug macros
++ */
++#define uea_dbg(usb_dev, format, args...) \
++ do { \
++ if (debug >= 1) \
++ dev_dbg(&(usb_dev)->dev, \
++ "[ueagle-atm dbg] %s: " format, \
++ __FUNCTION__, ##args); \
++ } while (0)
++
++#define uea_vdbg(usb_dev, format, args...) \
++ do { \
++ if (debug >= 2) \
++ dev_dbg(&(usb_dev)->dev, \
++ "[ueagle-atm vdbg] " format, ##args); \
++ } while (0)
++
++#define uea_enters(usb_dev) \
++ uea_vdbg(usb_dev, "entering %s\n", __FUNCTION__)
++
++#define uea_leaves(usb_dev) \
++ uea_vdbg(usb_dev, "leaving %s\n", __FUNCTION__)
++
++#define uea_err(usb_dev, format,args...) \
++ dev_err(&(usb_dev)->dev ,"[UEAGLE-ATM] " format , ##args)
++
++#define uea_warn(usb_dev, format,args...) \
++ dev_warn(&(usb_dev)->dev ,"[Ueagle-atm] " format, ##args)
++
++#define uea_info(usb_dev, format,args...) \
++ dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args)
++
++struct uea_cmvs {
++ u32 address;
++ u16 offset;
++ u32 data;
++} __attribute__ ((packed));
++
++struct uea_softc {
++ struct usb_device *usb_dev;
++ struct usbatm_data *usbatm;
++
++ int modem_index;
++ unsigned int driver_info;
++
++ int booting;
++ int reset;
++
++ wait_queue_head_t sync_q;
++
++ struct task_struct *kthread;
++ u32 data;
++ wait_queue_head_t cmv_ack_wait;
++ int cmv_ack;
++
++ struct work_struct task;
++ u16 pageno;
++ u16 ovl;
++
++ const struct firmware *dsp_firm;
++ struct urb *urb_int;
++
++ u8 cmv_function;
++ u16 cmv_idx;
++ u32 cmv_address;
++ u16 cmv_offset;
++
++ /* keep in sync with eaglectl */
++ struct uea_stats {
++ struct {
++ u32 state;
++ u32 flags;
++ u32 mflags;
++ u32 vidcpe;
++ u32 vidco;
++ u32 dsrate;
++ u32 usrate;
++ u32 dsunc;
++ u32 usunc;
++ u32 dscorr;
++ u32 uscorr;
++ u32 txflow;
++ u32 rxflow;
++ u32 usattenuation;
++ u32 dsattenuation;
++ u32 dsmargin;
++ u32 usmargin;
++ u32 firmid;
++ } phy;
++ } stats;
++};
++
++/*
++ * Elsa IDs
++ */
++#define ELSA_VID 0x05CC
++#define ELSA_PID_PSTFIRM 0x3350
++#define ELSA_PID_PREFIRM 0x3351
++
++/*
++ * Sagem USB IDs
++ */
++#define EAGLE_VID 0x1110
++#define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */
++#define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */
++
++#define EAGLE_IIC_PID_PREFIRM 0x9024 /* Eagle IIC */
++#define EAGLE_IIC_PID_PSTFIRM 0x9023 /* Eagle IIC */
++
++#define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */
++#define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */
++
++/*
++ * Eagle III Pid
++ */
++#define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */
++#define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */
++
++/*
++ * USR USB IDs
++ */
++#define USR_VID 0x0BAF
++#define MILLER_A_PID_PREFIRM 0x00F2
++#define MILLER_A_PID_PSTFIRM 0x00F1
++#define MILLER_B_PID_PREFIRM 0x00FA
++#define MILLER_B_PID_PSTFIRM 0x00F9
++#define HEINEKEN_A_PID_PREFIRM 0x00F6
++#define HEINEKEN_A_PID_PSTFIRM 0x00F5
++#define HEINEKEN_B_PID_PREFIRM 0x00F8
++#define HEINEKEN_B_PID_PSTFIRM 0x00F7
++
++#define PREFIRM 0
++#define PSTFIRM (1<<7)
++enum {
++ ADI930 = 0,
++ EAGLE_I,
++ EAGLE_II,
++ EAGLE_III
++};
++
++/* macros for both struct usb_device_id and struct uea_softc */
++#define UEA_IS_PREFIRM(x) \
++ (!((x)->driver_info & PSTFIRM))
++#define UEA_CHIP_VERSION(x) \
++ ((x)->driver_info & 0xf)
++
++#define IS_ISDN(sc) \
++ (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)
++
++#define INS_TO_USBDEV(ins) ins->usb_dev
++
++#define GET_STATUS(data) \
++ ((data >> 8) & 0xf)
++#define IS_OPERATIONAL(sc) \
++ (GET_STATUS(sc->stats.phy.state) == 2)
++
++/*
++ * Set of macros to handle unaligned data in the firmware blob.
++ * The FW_GET_BYTE() macro is provided only for consistency.
++ */
++
++#define FW_GET_BYTE(p) *((__u8 *) (p))
++#define FW_GET_WORD(p) le16_to_cpu(get_unaligned((__le16 *) (p)))
++#define FW_GET_LONG(p) le32_to_cpu(get_unaligned((__le32 *) (p)))
++
++#define FW_DIR "ueagle-atm/"
++#define NB_MODEM 4
++
++#define BULK_TIMEOUT 300
++#define CTRL_TIMEOUT 1000
++
++#define ACK_TIMEOUT msecs_to_jiffies(1500)
++
++#define UEA_INTR_IFACE_NO 0
++#define UEA_US_IFACE_NO 1
++#define UEA_DS_IFACE_NO 2
++
++#define FASTEST_ISO_INTF 8
++
++#define UEA_BULK_DATA_PIPE 0x02
++#define UEA_IDMA_PIPE 0x04
++#define UEA_INTR_PIPE 0x04
++#define UEA_ISO_DATA_PIPE 0x08
++
++#define UEA_SET_BLOCK 0x0001
++#define UEA_SET_MODE 0x0003
++#define UEA_SET_2183_DATA 0x0004
++#define UEA_SET_TIMEOUT 0x0011
++
++#define UEA_LOOPBACK_OFF 0x0002
++#define UEA_LOOPBACK_ON 0x0003
++#define UEA_BOOT_IDMA 0x0006
++#define UEA_START_RESET 0x0007
++#define UEA_END_RESET 0x0008
++
++#define UEA_SWAP_MAILBOX (0x3fcd | 0x4000)
++#define UEA_MPTX_START (0x3fce | 0x4000)
++#define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000)
++#define UEA_MPRX_MAILBOX (0x3fdf | 0x4000)
++
++/* structure describing a block within a DSP page */
++struct block_info {
++ __le16 wHdr;
++#define UEA_BIHDR 0xabcd
++ __le16 wAddress;
++ __le16 wSize;
++ __le16 wOvlOffset;
++ __le16 wOvl; /* overlay */
++ __le16 wLast;
++} __attribute__ ((packed));
++#define BLOCK_INFO_SIZE 12
++
++/* structure representing a CMV (Configuration and Management Variable) */
++struct cmv {
++ __le16 wPreamble;
++#define PREAMBLE 0x535c
++ __u8 bDirection;
++#define MODEMTOHOST 0x01
++#define HOSTTOMODEM 0x10
++ __u8 bFunction;
++#define FUNCTION_TYPE(f) ((f) >> 4)
++#define MEMACCESS 0x1
++#define ADSLDIRECTIVE 0x7
++
++#define FUNCTION_SUBTYPE(f) ((f) & 0x0f)
++/* for MEMACCESS */
++#define REQUESTREAD 0x0
++#define REQUESTWRITE 0x1
++#define REPLYREAD 0x2
++#define REPLYWRITE 0x3
++/* for ADSLDIRECTIVE */
++#define KERNELREADY 0x0
++#define MODEMREADY 0x1
++
++#define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf))
++ __le16 wIndex;
++ __le32 dwSymbolicAddress;
++#define MAKESA(a, b, c, d) \
++ (((c) & 0xff) << 24 | \
++ ((d) & 0xff) << 16 | \
++ ((a) & 0xff) << 8 | \
++ ((b) & 0xff))
++
++#define SA_CNTL MAKESA('C', 'N', 'T', 'L')
++#define SA_DIAG MAKESA('D', 'I', 'A', 'G')
++#define SA_INFO MAKESA('I', 'N', 'F', 'O')
++#define SA_OPTN MAKESA('O', 'P', 'T', 'N')
++#define SA_RATE MAKESA('R', 'A', 'T', 'E')
++#define SA_STAT MAKESA('S', 'T', 'A', 'T')
++ __le16 wOffsetAddress;
++ __le32 dwData;
++} __attribute__ ((packed));
++#define CMV_SIZE 16
++
++/* structure representing swap information */
++struct swap_info {
++ __u8 bSwapPageNo;
++ __u8 bOvl; /* overlay */
++} __attribute__ ((packed));
++
++/* structure representing interrupt data */
++struct intr_pkt {
++ __u8 bType;
++ __u8 bNotification;
++ __le16 wValue;
++ __le16 wIndex;
++ __le16 wLength;
++ __le16 wInterrupt;
++#define INT_LOADSWAPPAGE 0x0001
++#define INT_INCOMINGCMV 0x0002
++ union {
++ struct {
++ struct swap_info swapinfo;
++ __le16 wDataSize;
++ } __attribute__ ((packed)) s1;
++
++ struct {
++ struct cmv cmv;
++ __le16 wDataSize;
++ } __attribute__ ((packed)) s2;
++ } __attribute__ ((packed)) u;
++#define bSwapPageNo u.s1.swapinfo.bSwapPageNo
++#define bOvl u.s1.swapinfo.bOvl
++} __attribute__ ((packed));
++#define INTR_PKT_SIZE 28
++
++static struct usb_driver uea_driver;
++static DECLARE_MUTEX(uea_semaphore);
++static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};
++
++static int modem_index;
++static unsigned int debug;
++static int sync_wait[NB_MODEM];
++static char *cmv_file[NB_MODEM];
++
++module_param(debug, uint, 0644);
++MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)");
++module_param_array(sync_wait, bool, NULL, 0644);
++MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM");
++module_param_array(cmv_file, charp, NULL, 0644);
++MODULE_PARM_DESC(cmv_file,
++ "file name with configuration and management variables");
++
++#define UPDATE_ATM_STAT(type, val) \
++ do { \
++ if (sc->usbatm->atm_dev) \
++ sc->usbatm->atm_dev->type = val; \
++ } while (0)
++
++/* Firmware loading */
++#define LOAD_INTERNAL 0xA0
++#define F8051_USBCS 0x7f92
++
++/**
++ * uea_send_modem_cmd - Send a command for pre-firmware devices.
++ */
++static int uea_send_modem_cmd(struct usb_device *usb,
++ u16 addr, u16 size, u8 * buff)
++{
++ int ret = -ENOMEM;
++ u8 *xfer_buff;
++
++ xfer_buff = kmalloc(size, GFP_KERNEL);
++ if (xfer_buff) {
++ memcpy(xfer_buff, buff, size);
++ ret = usb_control_msg(usb,
++ usb_sndctrlpipe(usb, 0),
++ LOAD_INTERNAL,
++ USB_DIR_OUT | USB_TYPE_VENDOR |
++ USB_RECIP_DEVICE, addr, 0, xfer_buff,
++ size, CTRL_TIMEOUT);
++ kfree(xfer_buff);
++ }
++
++ if (ret < 0)
++ return ret;
++
++ return (ret == size) ? 0 : -EIO;
++}
++
++static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *context)
++{
++ struct usb_device *usb = context;
++ u8 *pfw, value;
++ u32 crc = 0;
++ int ret, size;
++
++ uea_enters(usb);
++ if (!fw_entry) {
++ uea_err(usb, "firmware is not available\n");
++ goto err;
++ }
++
++ pfw = fw_entry->data;
++ size = fw_entry->size;
++
++ crc = FW_GET_LONG(pfw);
++ pfw += 4;
++ size -= 4;
++ if (crc32_be(0, pfw, size) != crc) {
++ uea_err(usb, "firmware is corrupted\n");
++ goto err;
++ }
++
++ /*
++ * Start to upload formware : send reset
++ */
++ value = 1;
++ ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
++
++ if (ret < 0) {
++ uea_err(usb, "modem reset failed with error %d\n", ret);
++ goto err;
++ }
++
++ while (size > 0) {
++ u8 len = FW_GET_BYTE(pfw);
++ u16 add = FW_GET_WORD(pfw + 1);
++ ret = uea_send_modem_cmd(usb, add, len, pfw + 3);
++ if (ret < 0) {
++ uea_err(usb, "uploading firmware data failed "
++ "with error %d\n", ret);
++ goto err;
++ }
++ pfw += len + 3;
++ size -= len + 3;
++ }
++
++ /*
++ * Tell the modem we finish : de-assert reset
++ */
++ value = 0;
++ ret = uea_send_modem_cmd(usb, F8051_USBCS, 1, &value);
++ if (ret < 0)
++ uea_err(usb, "modem de-assert failed with error %d\n", ret);
++ else
++ uea_info(usb, "firmware uploaded\n");
++
++err:
++ uea_leaves(usb);
++}
++
++/**
++ * uea_load_firmware - Load usb firmware for pre-firmware devices.
++ */
++static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
++{
++ int ret;
++ char *fw_name = FW_DIR "eagle.fw";
++
++ uea_enters(usb);
++ uea_info(usb, "pre-firmware device, uploading firmware\n");
++
++ switch (ver) {
++ case ADI930:
++ fw_name = FW_DIR "adi930.fw";
++ break;
++ case EAGLE_I:
++ fw_name = FW_DIR "eagleI.fw";
++ break;
++ case EAGLE_II:
++ fw_name = FW_DIR "eagleII.fw";
++ break;
++ case EAGLE_III:
++ fw_name = FW_DIR "eagleIII.fw";
++ break;
++ }
++
++ ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware);
++ if (ret)
++ uea_err(usb, "firmware %s is not available\n", fw_name);
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list