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

📄 sierra.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  USB Driver for Sierra Wireless  Copyright (C) 2006, 2007  Kevin Lloyd <linux@sierrawireless.com>  IMPORTANT DISCLAIMER: This driver is not commercially supported by  Sierra Wireless. Use at your own risk.  This driver is free software; you can redistribute it and/or modify  it under the terms of Version 2 of the GNU General Public License as  published by the Free Software Foundation.  Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de>  Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>*/#define DRIVER_VERSION "v.1.2.5b"#define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>"#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"#include <linux/kernel.h>#include <linux/jiffies.h>#include <linux/errno.h>#include <linux/tty.h>#include <linux/tty_flip.h>#include <linux/module.h>#include <linux/usb.h>#include <linux/usb/serial.h>#define SWIMS_USB_REQUEST_SetMode	0x0B#define SWIMS_USB_REQUEST_TYPE_SetMode	0x40#define SWIMS_USB_INDEX_SetMode		0x0000#define SWIMS_SET_MODE_Modem		0x0001/* per port private data */#define N_IN_URB	4#define N_OUT_URB	4#define IN_BUFLEN	4096static int debug;enum devicetype {	DEVICE_3_PORT =		0,	DEVICE_1_PORT =		1,	DEVICE_INSTALLER =	2,};static int sierra_set_power_state(struct usb_device *udev, __u16 swiState){	int result;	dev_dbg(&udev->dev, "%s", "SET POWER STATE\n");	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),			0x00,			/* __u8 request      */			0x40,			/* __u8 request type */			swiState,		/* __u16 value       */			0,			/* __u16 index       */			NULL,			/* void *data        */			0,			/* __u16 size 	     */			USB_CTRL_SET_TIMEOUT);	/* int timeout 	     */	return result;}static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode){	int result;	dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH\n");	result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),			SWIMS_USB_REQUEST_SetMode,	/* __u8 request      */			SWIMS_USB_REQUEST_TYPE_SetMode,	/* __u8 request type */			eSocMode,			/* __u16 value       */			SWIMS_USB_INDEX_SetMode,	/* __u16 index       */			NULL,				/* void *data        */			0,				/* __u16 size 	     */			USB_CTRL_SET_TIMEOUT);		/* int timeout       */	return result;}static int sierra_probe(struct usb_interface *iface,			const struct usb_device_id *id){	int result;	struct usb_device *udev;	udev = usb_get_dev(interface_to_usbdev(iface));	/* Check if in installer mode */	if (id->driver_info == DEVICE_INSTALLER) {		dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n");		result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem);		/*We do not want to bind to the device when in installer mode*/		return -EIO;	}	return usb_serial_probe(iface, id);}static struct usb_device_id id_table [] = {	{ USB_DEVICE(0x1199, 0x0017) },	/* Sierra Wireless EM5625 */	{ USB_DEVICE(0x1199, 0x0018) },	/* Sierra Wireless MC5720 */	{ USB_DEVICE(0x1199, 0x0218) },	/* Sierra Wireless MC5720 */	{ USB_DEVICE(0x0f30, 0x1b1d) },	/* Sierra Wireless MC5720 */	{ USB_DEVICE(0x1199, 0x0020) },	/* Sierra Wireless MC5725 */	{ USB_DEVICE(0x1199, 0x0220) },	/* Sierra Wireless MC5725 */	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */	{ USB_DEVICE(0x1199, 0x0021) },	/* Sierra Wireless AirCard 597E */	{ USB_DEVICE(0x1199, 0x0120) },	/* Sierra Wireless USB Dongle 595U */	{ USB_DEVICE(0x1199, 0x0023) },	/* Sierra Wireless AirCard */	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */	{ USB_DEVICE(0x1199, 0x6804) },	/* Sierra Wireless MC8755 */	{ USB_DEVICE(0x1199, 0x6803) },	/* Sierra Wireless MC8765 */	{ USB_DEVICE(0x1199, 0x6812) },	/* Sierra Wireless MC8775 & AC 875U */	{ USB_DEVICE(0x1199, 0x6813) },	/* Sierra Wireless MC8775 (Thinkpad internal) */	{ USB_DEVICE(0x1199, 0x6820) },	/* Sierra Wireless AirCard 875 */	{ USB_DEVICE(0x1199, 0x6832) },	/* Sierra Wireless MC8780*/	{ USB_DEVICE(0x1199, 0x6833) },	/* Sierra Wireless MC8781*/	{ USB_DEVICE(0x1199, 0x6850) },	/* Sierra Wireless AirCard 880 */	{ USB_DEVICE(0x1199, 0x6851) },	/* Sierra Wireless AirCard 881 */	{ USB_DEVICE(0x1199, 0x6852) },	/* Sierra Wireless AirCard 880 E */	{ USB_DEVICE(0x1199, 0x6853) },	/* Sierra Wireless AirCard 881 E */	{ USB_DEVICE(0x1199, 0x6855) },	/* Sierra Wireless AirCard 880 U */	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */	{ USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */	{ USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */	{ USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */	{ USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */	{ USB_DEVICE(0x05C6, 0x6613), .driver_info = DEVICE_1_PORT }, /* Onda H600/ZTE MF330 */	{ USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER},	{ }};MODULE_DEVICE_TABLE(usb, id_table);static struct usb_device_id id_table_1port [] = {	{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */	{ USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */	{ USB_DEVICE(0x05C6, 0x6613) }, /* Onda H600/ZTE MF330 */	{ }};static struct usb_device_id id_table_3port [] = {	{ USB_DEVICE(0x1199, 0x0017) },	/* Sierra Wireless EM5625 */	{ USB_DEVICE(0x1199, 0x0018) },	/* Sierra Wireless MC5720 */	{ USB_DEVICE(0x0f30, 0x1b1d) },	/* Sierra Wireless MC5720 */	{ USB_DEVICE(0x1199, 0x0218) },	/* Sierra Wireless MC5720 */	{ USB_DEVICE(0x1199, 0x0020) },	/* Sierra Wireless MC5725 */	{ USB_DEVICE(0x1199, 0x0220) },	/* Sierra Wireless MC5725 */	{ USB_DEVICE(0x1199, 0x0019) },	/* Sierra Wireless AirCard 595 */	{ USB_DEVICE(0x1199, 0x0021) },	/* Sierra Wireless AirCard 597E */	{ USB_DEVICE(0x1199, 0x0120) },	/* Sierra Wireless USB Dongle 595U*/	{ USB_DEVICE(0x1199, 0x0023) },	/* Sierra Wireless AirCard */	{ USB_DEVICE(0x1199, 0x6802) },	/* Sierra Wireless MC8755 */	{ USB_DEVICE(0x1199, 0x6804) },	/* Sierra Wireless MC8755 */	{ USB_DEVICE(0x1199, 0x6803) },	/* Sierra Wireless MC8765 */	{ USB_DEVICE(0x1199, 0x6812) },	/* Sierra Wireless MC8775 & AC 875U */	{ USB_DEVICE(0x1199, 0x6813) },	/* Sierra Wireless MC8775 (Thinkpad internal) */	{ USB_DEVICE(0x1199, 0x6820) },	/* Sierra Wireless AirCard 875 */	{ USB_DEVICE(0x1199, 0x6832) },	/* Sierra Wireless MC8780*/	{ USB_DEVICE(0x1199, 0x6833) },	/* Sierra Wireless MC8781*/	{ USB_DEVICE(0x1199, 0x6850) },	/* Sierra Wireless AirCard 880 */	{ USB_DEVICE(0x1199, 0x6851) },	/* Sierra Wireless AirCard 881 */	{ USB_DEVICE(0x1199, 0x6852) },	/* Sierra Wireless AirCard 880E */	{ USB_DEVICE(0x1199, 0x6853) },	/* Sierra Wireless AirCard 881E */	{ USB_DEVICE(0x1199, 0x6855) },	/* Sierra Wireless AirCard 880 U */	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881U */	{ USB_DEVICE(0x1199, 0x6468) }, /* Sierra Wireless MP3G - EVDO */	{ USB_DEVICE(0x1199, 0x6469) }, /* Sierra Wireless MP3G - UMTS/HSPA */	{ }};static struct usb_driver sierra_driver = {	.name       = "sierra",	.probe      = sierra_probe,	.disconnect = usb_serial_disconnect,	.id_table   = id_table,	.no_dynamic_id = 	1,};struct sierra_port_private {	spinlock_t lock;	/* lock the structure */	int outstanding_urbs;	/* number of out urbs in flight */	/* Input endpoints and buffer for this port */	struct urb *in_urbs[N_IN_URB];	char in_buffer[N_IN_URB][IN_BUFLEN];	/* Settings for the port */	int rts_state;	/* Handshaking pins (outputs) */	int dtr_state;	int cts_state;	/* Handshaking pins (inputs) */	int dsr_state;	int dcd_state;	int ri_state;};static int sierra_send_setup(struct usb_serial_port *port){	struct usb_serial *serial = port->serial;	struct sierra_port_private *portdata;	dbg("%s", __FUNCTION__);	portdata = usb_get_serial_port_data(port);	if (port->tty) {		int val = 0;		if (portdata->dtr_state)			val |= 0x01;		if (portdata->rts_state)			val |= 0x02;		return usb_control_msg(serial->dev,				usb_rcvctrlpipe(serial->dev, 0),				0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);	}	return 0;}static void sierra_rx_throttle(struct usb_serial_port *port){	dbg("%s", __FUNCTION__);}static void sierra_rx_unthrottle(struct usb_serial_port *port){	dbg("%s", __FUNCTION__);}static void sierra_break_ctl(struct usb_serial_port *port, int break_state){	/* Unfortunately, I don't know how to send a break */	dbg("%s", __FUNCTION__);}static void sierra_set_termios(struct usb_serial_port *port,			struct ktermios *old_termios){	dbg("%s", __FUNCTION__);	tty_termios_copy_hw(port->tty->termios, old_termios);	sierra_send_setup(port);}static int sierra_tiocmget(struct usb_serial_port *port, struct file *file){	unsigned int value;	struct sierra_port_private *portdata;	portdata = usb_get_serial_port_data(port);	value = ((portdata->rts_state) ? TIOCM_RTS : 0) |		((portdata->dtr_state) ? TIOCM_DTR : 0) |		((portdata->cts_state) ? TIOCM_CTS : 0) |		((portdata->dsr_state) ? TIOCM_DSR : 0) |		((portdata->dcd_state) ? TIOCM_CAR : 0) |		((portdata->ri_state) ? TIOCM_RNG : 0);	return value;}static int sierra_tiocmset(struct usb_serial_port *port, struct file *file,			unsigned int set, unsigned int clear){	struct sierra_port_private *portdata;	portdata = usb_get_serial_port_data(port);	if (set & TIOCM_RTS)		portdata->rts_state = 1;	if (set & TIOCM_DTR)		portdata->dtr_state = 1;	if (clear & TIOCM_RTS)		portdata->rts_state = 0;	if (clear & TIOCM_DTR)		portdata->dtr_state = 0;	return sierra_send_setup(port);}static int sierra_ioctl(struct usb_serial_port *port, struct file *file,			unsigned int cmd, unsigned long arg){	return -ENOIOCTLCMD;}static void sierra_outdat_callback(struct urb *urb){	struct usb_serial_port *port = urb->context;	struct sierra_port_private *portdata = usb_get_serial_port_data(port);	int status = urb->status;	unsigned long flags;	dbg("%s - port %d", __FUNCTION__, port->number);	/* free up the transfer buffer, as usb_free_urb() does not do this */	kfree(urb->transfer_buffer);	if (status)		dbg("%s - nonzero write bulk status received: %d",		    __FUNCTION__, status);	spin_lock_irqsave(&portdata->lock, flags);	--portdata->outstanding_urbs;	spin_unlock_irqrestore(&portdata->lock, flags);	usb_serial_port_softint(port);}/* Write */static int sierra_write(struct usb_serial_port *port,			const unsigned char *buf, int count){	struct sierra_port_private *portdata = usb_get_serial_port_data(port);	struct usb_serial *serial = port->serial;	unsigned long flags;	unsigned char *buffer;	struct urb *urb;	int status;	portdata = usb_get_serial_port_data(port);	dbg("%s: write (%d chars)", __FUNCTION__, count);	spin_lock_irqsave(&portdata->lock, flags);	if (portdata->outstanding_urbs > N_OUT_URB) {		spin_unlock_irqrestore(&portdata->lock, flags);		dbg("%s - write limit hit\n", __FUNCTION__);		return 0;	}	portdata->outstanding_urbs++;	spin_unlock_irqrestore(&portdata->lock, flags);	buffer = kmalloc(count, GFP_ATOMIC);	if (!buffer) {		dev_err(&port->dev, "out of memory\n");		count = -ENOMEM;		goto error_no_buffer;	}	urb = usb_alloc_urb(0, GFP_ATOMIC);	if (!urb) {		dev_err(&port->dev, "no more free urbs\n");		count = -ENOMEM;		goto error_no_urb;	}	memcpy(buffer, buf, count);	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);	usb_fill_bulk_urb(urb, serial->dev,			  usb_sndbulkpipe(serial->dev,					  port->bulk_out_endpointAddress),			  buffer, count, sierra_outdat_callback, port);	/* send it down the pipe */	status = usb_submit_urb(urb, GFP_ATOMIC);	if (status) {		dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed "			"with status = %d\n", __FUNCTION__, status);		count = status;		goto error;	}	/* we are done with this urb, so let the host driver	 * really free it when it is finished with it */	usb_free_urb(urb);	return count;error:	usb_free_urb(urb);error_no_urb:	kfree(buffer);error_no_buffer:	spin_lock_irqsave(&portdata->lock, flags);	--portdata->outstanding_urbs;	spin_unlock_irqrestore(&portdata->lock, flags);	return count;}

⌨️ 快捷键说明

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