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