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

📄 visor.c

📁 usb driver for 2.6.17
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * USB HandSpring Visor, Palm m50x, and Sony Clie driver * (supports all of the Palm OS USB devices) * *	Copyright (C) 1999 - 2004 *	    Greg Kroah-Hartman (greg@kroah.com) * *	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. * * See Documentation/usb/usb-serial.txt for more information on using this driver * */#include <linux/config.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/slab.h>#include <linux/tty.h>#include <linux/tty_driver.h>#include <linux/tty_flip.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/spinlock.h>#include <asm/uaccess.h>#include <linux/usb.h>#include "usb-serial.h"#include "visor.h"/* * Version Information */#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"#define DRIVER_DESC "USB HandSpring Visor / Palm OS driver"/* function prototypes for a handspring visor */static int  visor_open		(struct usb_serial_port *port, struct file *filp);static void visor_close		(struct usb_serial_port *port, struct file *filp);static int  visor_write		(struct usb_serial_port *port, const unsigned char *buf, int count);static int  visor_write_room		(struct usb_serial_port *port);static int  visor_chars_in_buffer	(struct usb_serial_port *port);static void visor_throttle	(struct usb_serial_port *port);static void visor_unthrottle	(struct usb_serial_port *port);static int  visor_probe		(struct usb_serial *serial, const struct usb_device_id *id);static int  visor_calc_num_ports(struct usb_serial *serial);static void visor_shutdown	(struct usb_serial *serial);static int  visor_ioctl		(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg);static void visor_set_termios	(struct usb_serial_port *port, struct termios *old_termios);static void visor_write_bulk_callback	(struct urb *urb, struct pt_regs *regs);static void visor_read_bulk_callback	(struct urb *urb, struct pt_regs *regs);static void visor_read_int_callback	(struct urb *urb, struct pt_regs *regs);static int  clie_3_5_startup	(struct usb_serial *serial);static int  treo_attach		(struct usb_serial *serial);static int clie_5_attach (struct usb_serial *serial);static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id);static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id);/* Parameters that may be passed into the module. */static int debug;static __u16 vendor;static __u16 product;static struct usb_device_id id_table [] = {	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),		.driver_info = (kernel_ulong_t)&palm_os_3_probe },	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), 		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ },					/* optional parameter entry */	{ }					/* Terminating entry */};static struct usb_device_id clie_id_5_table [] = {	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID),		.driver_info = (kernel_ulong_t)&palm_os_4_probe },	{ },					/* optional parameter entry */	{ }					/* Terminating entry */};static struct usb_device_id clie_id_3_5_table [] = {	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },	{ }					/* Terminating entry */};static struct usb_device_id id_table_combined [] = {	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },	{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO600_ID) },	{ USB_DEVICE(GSPDA_VENDOR_ID, GSPDA_XPLORE_M68_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M100_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID) },	{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NZ90V_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_UX50_ID) },	{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) },	{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) },	{ USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) },	{ USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) },	{ USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) },	{ USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) },	{ USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) },	{ USB_DEVICE(FOSSIL_VENDOR_ID, FOSSIL_ABACUS_ID) },	{ },					/* optional parameter entry */	{ }					/* Terminating entry */};MODULE_DEVICE_TABLE (usb, id_table_combined);static struct usb_driver visor_driver = {	.name =		"visor",	.probe =	usb_serial_probe,	.disconnect =	usb_serial_disconnect,	.id_table =	id_table_combined,	.no_dynamic_id = 	1,};/* All of the device info needed for the Handspring Visor, and Palm 4.0 devices */static struct usb_serial_driver handspring_device = {	.driver = {		.owner =	THIS_MODULE,		.name =		"visor",	},	.description =		"Handspring Visor / Palm OS",	.id_table =		id_table,	.num_interrupt_in =	NUM_DONT_CARE,	.num_bulk_in =		2,	.num_bulk_out =		2,	.num_ports =		2,	.open =			visor_open,	.close =		visor_close,	.throttle =		visor_throttle,	.unthrottle =		visor_unthrottle,	.attach =		treo_attach,	.probe =		visor_probe,	.calc_num_ports =	visor_calc_num_ports,	.shutdown =		visor_shutdown,	.ioctl =		visor_ioctl,	.set_termios =		visor_set_termios,	.write =		visor_write,	.write_room =		visor_write_room,	.chars_in_buffer =	visor_chars_in_buffer,	.write_bulk_callback =	visor_write_bulk_callback,	.read_bulk_callback =	visor_read_bulk_callback,	.read_int_callback =	visor_read_int_callback,};/* All of the device info needed for the Clie UX50, TH55 Palm 5.0 devices */static struct usb_serial_driver clie_5_device = {	.driver = {		.owner =	THIS_MODULE,		.name =		"clie_5",	},	.description =		"Sony Clie 5.0",	.id_table =		clie_id_5_table,	.num_interrupt_in =	NUM_DONT_CARE,	.num_bulk_in =		2,	.num_bulk_out =		2,	.num_ports =		2,	.open =			visor_open,	.close =		visor_close,	.throttle =		visor_throttle,	.unthrottle =		visor_unthrottle,	.attach =		clie_5_attach,	.probe =		visor_probe,	.calc_num_ports =	visor_calc_num_ports,	.shutdown =		visor_shutdown,	.ioctl =		visor_ioctl,	.set_termios =		visor_set_termios,	.write =		visor_write,	.write_room =		visor_write_room,	.chars_in_buffer =	visor_chars_in_buffer,	.write_bulk_callback =	visor_write_bulk_callback,	.read_bulk_callback =	visor_read_bulk_callback,	.read_int_callback =	visor_read_int_callback,};/* device info for the Sony Clie OS version 3.5 */static struct usb_serial_driver clie_3_5_device = {	.driver = {		.owner =	THIS_MODULE,		.name =		"clie_3.5",	},	.description =		"Sony Clie 3.5",	.id_table =		clie_id_3_5_table,	.num_interrupt_in =	0,	.num_bulk_in =		1,	.num_bulk_out =		1,	.num_ports =		1,	.open =			visor_open,	.close =		visor_close,	.throttle =		visor_throttle,	.unthrottle =		visor_unthrottle,	.attach =		clie_3_5_startup,	.ioctl =		visor_ioctl,	.set_termios =		visor_set_termios,	.write =		visor_write,	.write_room =		visor_write_room,	.chars_in_buffer =	visor_chars_in_buffer,	.write_bulk_callback =	visor_write_bulk_callback,	.read_bulk_callback =	visor_read_bulk_callback,};struct visor_private {	spinlock_t lock;	int bytes_in;	int bytes_out;	int outstanding_urbs;	int throttled;};/* number of outstanding urbs to prevent userspace DoS from happening */#define URB_UPPER_LIMIT	42static int stats;/****************************************************************************** * Handspring Visor specific driver functions ******************************************************************************/static int visor_open (struct usb_serial_port *port, struct file *filp){	struct usb_serial *serial = port->serial;	struct visor_private *priv = usb_get_serial_port_data(port);	unsigned long flags;	int result = 0;	dbg("%s - port %d", __FUNCTION__, port->number);	if (!port->read_urb) {		/* this is needed for some brain dead Sony devices */		dev_err(&port->dev, "Device lied about number of ports, please use a lower one.\n");		return -ENODEV;	}	spin_lock_irqsave(&priv->lock, flags);	priv->bytes_in = 0;	priv->bytes_out = 0;	priv->outstanding_urbs = 0;	priv->throttled = 0;	spin_unlock_irqrestore(&priv->lock, flags);	/*	 * Force low_latency on so that our tty_push actually forces the data	 * through, otherwise it is scheduled, and with high data rates (like	 * with OHCI) data can get lost.	 */	if (port->tty)		port->tty->low_latency = 1;	/* Start reading from the device */	usb_fill_bulk_urb (port->read_urb, serial->dev,			   usb_rcvbulkpipe (serial->dev, 					    port->bulk_in_endpointAddress),			   port->read_urb->transfer_buffer,			   port->read_urb->transfer_buffer_length,			   visor_read_bulk_callback, port);	result = usb_submit_urb(port->read_urb, GFP_KERNEL);	if (result) {		dev_err(&port->dev, "%s - failed submitting read urb, error %d\n",			__FUNCTION__, result);		goto exit;	}		if (port->interrupt_in_urb) {		dbg("%s - adding interrupt input for treo", __FUNCTION__);		result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);		if (result)			dev_err(&port->dev, "%s - failed submitting interrupt urb, error %d\n",				__FUNCTION__, result);	}exit:		return result;}static void visor_close (struct usb_serial_port *port, struct file * filp){	struct visor_private *priv = usb_get_serial_port_data(port);	unsigned char *transfer_buffer;

⌨️ 快捷键说明

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