⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ueagle-atm.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*- * Copyright (c) 2003, 2004 *	Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. * * Copyright (c) 2005 Matthieu Castet <castet.matthieu@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 <linux/mutex.h>#include <asm/unaligned.h>#include "usbatm.h"#define EAGLEUSBVERSION "ueagle 1.3"/* * 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(3000)#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 GETSA1(a) ((a >> 8) & 0xff)#define GETSA2(a) (a & 0xff)#define GETSA3(a) ((a >> 24) & 0xff)#define GETSA4(a) ((a >> 16) & 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 28static struct usb_driver uea_driver;static DEFINE_MUTEX(uea_mutex);static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"};static int modem_index;static unsigned int debug;static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1};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(use_iso, bool, NULL, 0644);MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic");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;	if (size < 4)		goto err_fw_corrupted;	crc = FW_GET_LONG(pfw);	pfw += 4;	size -= 4;	if (crc32_be(0, pfw, size) != crc)		goto err_fw_corrupted;	/*	 * 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 > 3) {		u8 len = FW_GET_BYTE(pfw);		u16 add = FW_GET_WORD(pfw + 1);		size -= len + 3;		if (size < 0)			goto err_fw_corrupted;		ret = uea_send_modem_cmd(usb, add, len, pfw + 3);		if (ret < 0) {			uea_err(usb, "uploading firmware data failed "

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -