Commit f812d833 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/usb-2.6

into ppc970.osdl.org:/home/torvalds/v2.6/linux
parents ca6f8809 4965c6f6
Linux Gadget Serial Driver v2.0
11/20/2004
License and Disclaimer
----------------------
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.
This document and the the gadget serial driver itself are
Copyright (C) 2004 by Al Borchers (alborchers@steinerpoint.com).
If you have questions, problems, or suggestions for this driver
please contact Al Borchers at alborchers@steinerpoint.com.
Prerequisites
-------------
Versions of the gadget serial driver are available for the
2.4 Linux kernels, but this document assumes you are using
version 2.0 or later of the gadget serial driver in a 2.6
Linux kernel.
This document assumes that you are familiar with Linux and
Windows and know how to configure and build Linux kernels, run
standard utilities, use minicom and HyperTerminal, and work with
USB and serial devices. It also assumes you configure the Linux
gadget and usb drivers as modules.
Overview
--------
The gadget serial driver is a Linux USB gadget driver, a USB device
side driver. It runs on a Linux system that has USB device side
hardware; for example, a PDA, an embedded Linux system, or a PC
with a USB development card.
The gadget serial driver talks over USB to either a CDC ACM driver
or a generic USB serial driver running on a host PC.
Host
--------------------------------------
| Host-Side CDC ACM USB Host |
| Operating | or | Controller | USB
| System | Generic USB | Driver |--------
| (Linux or | Serial | and | |
| Windows) Driver USB Stack | |
-------------------------------------- |
|
|
|
Gadget |
-------------------------------------- |
| Gadget USB Periph. | |
| Device-Side | Gadget | Controller | |
| Linux | Serial | Driver |--------
| Operating | Driver | and |
| System USB Stack |
--------------------------------------
On the device-side Linux system, the gadget serial driver looks
like a serial device.
On the host-side system, the gadget serial device looks like a
CDC ACM compliant class device or a simple vendor specific device
with bulk in and bulk out endpoints, and it is treated similarly
to other serial devices.
The host side driver can potentially be any ACM compliant driver
or any driver that can talk to a device with a simple bulk in/out
interface. Gadget serial has been tested with the Linux ACM driver,
the Windows usbser.sys ACM driver, and the Linux USB generic serial
driver.
With the gadget serial driver and the host side ACM or generic
serial driver running, you should be able to communicate between
the host and the gadget side systems as if they were connected by a
serial cable.
The gadget serial driver only provides simple unreliable data
communication. It does not yet handle flow control or many other
features of normal serial devices.
Installing the Gadget Serial Driver
-----------------------------------
To use the gadget serial driver you must configure the Linux gadget
side kernel for "Support for USB Gadgets", for a "USB Peripheral
Controller" (for example, net2280), and for the "Serial Gadget"
driver. All this are listed under "USB Gadget Support" when
configuring the kernel. Then rebuild and install the kernel or
modules.
The gadget serial driver uses major number 127, for now. So you
will need to create a device node for it, like this:
mknod /dev/ttygserial c 127 0
You only need to do this once.
Then you must load the gadget serial driver. To load it as an
ACM device, do this:
modprobe g_serial use_acm=1
To load it as a vendor specific bulk in/out device, do this:
modprobe g_serial
This will also automatically load the underlying gadget peripheral
controller driver. This must be done each time you reboot the gadget
side Linux system. You can add this to the start up scripts, if
desired.
If gadget serial is loaded as an ACM device you will want to use
either the Windows or Linux ACM driver on the host side. If gadget
serial is loaded as a bulk in/out device, you will want to use the
Linux generic serial driver on the host side. Follow the appropriate
instructions below to install the host side driver.
Installing the Windows Host ACM Driver
--------------------------------------
To use the Windows ACM driver you must have the files "gserial.inf"
and "usbser.sys" together in a folder on the Windows machine.
The "gserial.inf" file is given here.
-------------------- CUT HERE --------------------
[Version]
Signature="$Windows NT$"
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Provider=%LINUX%
DriverVer=08/17/2004,0.0.2.0
; Copyright (C) 2004 Al Borchers (alborchers@steinerpoint.com)
[Manufacturer]
%LINUX%=GSerialDeviceList
[GSerialDeviceList]
%GSERIAL%=GSerialInstall, USB\VID_0525&PID_A4A7
[DestinationDirs]
DefaultDestDir=10,System32\Drivers
[GSerialInstall]
CopyFiles=GSerialCopyFiles
AddReg=GSerialAddReg
[GSerialCopyFiles]
usbser.sys
[GSerialAddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[GSerialInstall.Services]
AddService = usbser,0x0002,GSerialService
[GSerialService]
DisplayName = %GSERIAL_DISPLAY_NAME%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\usbser.sys
LoadOrderGroup = Base
[Strings]
LINUX = "Linux"
GSERIAL = "Gadget Serial"
GSERIAL_DISPLAY_NAME = "USB Gadget Serial Driver"
-------------------- CUT HERE --------------------
The "usbser.sys" file comes with various versions of Windows.
For example, it can be found on Windows XP typically in
C:\WINDOWS\Driver Cache\i386\driver.cab
Or it can be found on the Windows 98SE CD in the "win98" folder
in the "DRIVER11.CAB" through "DRIVER20.CAB" cab files. You will
need the DOS "expand" program, the Cygwin "cabextract" program, or
a similar program to unpack these cab files and extract "usbser.sys".
For example, to extract "usbser.sys" into the current directory
on Windows XP, open a DOS window and run a command like
expand C:\WINDOWS\Driver~1\i386\driver.cab -F:usbser.sys .
(Thanks to Nishant Kamat for pointing out this DOS command.)
When the gadget serial driver is loaded and the USB device connected
to the Windows host with a USB cable, Windows should recognize the
gadget serial device and ask for a driver. Tell Windows to find the
driver in the folder that contains "gserial.inf" and "usbser.sys".
For example, on Windows XP, when the gadget serial device is first
plugged in, the "Found New Hardware Wizard" starts up. Select
"Install from a list or specific location (Advanced)", then on
the next screen select "Include this location in the search" and
enter the path or browse to the folder containing "gserial.inf" and
"usbser.sys". Windows will complain that the Gadget Serial driver
has not passed Windows Logo testing, but select "Continue anyway"
and finish the driver installation.
On Windows XP, in the "Device Manager" (under "Control Panel",
"System", "Hardware") expand the "Ports (COM & LPT)" entry and you
should see "Gadget Serial" listed as the driver for one of the COM
ports.
To uninstall the Windows XP driver for "Gadget Serial", right click
on the "Gadget Serial" entry in the "Device Manager" and select
"Uninstall".
Installing the Linux Host ACM Driver
------------------------------------
To use the Linux ACM driver you must configure the Linux host side
kernel for "Support for Host-side USB" and for "USB Modem (CDC ACM)
support".
Once the gadget serial driver is loaded and the USB device connected
to the Linux host with a USB cable, the host system should recognize
the gadget serial device. For example, the command
cat /proc/bus/usb/devices
should show something like this:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 5 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=02(comm.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0525 ProdID=a4a7 Rev= 2.01
S: Manufacturer=Linux 2.6.8.1 with net2280
S: Product=Gadget Serial
S: SerialNumber=0
C:* #Ifs= 2 Cfg#= 2 Atr=c0 MxPwr= 2mA
I: If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=01 Driver=acm
E: Ad=83(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
I: If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=acm
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
If the host side Linux system is configured properly, the ACM driver
should be loaded automatically. The command "lsmod" should show the
"acm" module is loaded.
Installing the Linux Host Generic USB Serial Driver
---------------------------------------------------
To use the Linux generic USB serial driver you must configure the
Linux host side kernel for "Support for Host-side USB", for "USB
Serial Converter support", and for the "USB Generic Serial Driver".
Once the gadget serial driver is loaded and the USB device connected
to the Linux host with a USB cable, the host system should recognize
the gadget serial device. For example, the command
cat /proc/bus/usb/devices
should show something like this:
T: Bus=01 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 6 Spd=480 MxCh= 0
D: Ver= 2.00 Cls=ff(vend.) Sub=00 Prot=00 MxPS=64 #Cfgs= 1
P: Vendor=0525 ProdID=a4a6 Rev= 2.01
S: Manufacturer=Linux 2.6.8.1 with net2280
S: Product=Gadget Serial
S: SerialNumber=0
C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr= 2mA
I: If#= 0 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=serial
E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
You must explicitly load the usbserial driver with parameters to
configure it to recognize the gadget serial device, like this:
modprobe usbserial vendor=0x0525 product=0xA4A6
If everything is working, usbserial will print a message in the
system log saying something like "Gadget Serial converter now
attached to ttyUSB0".
Testing with Minicom or HyperTerminal
-------------------------------------
Once the gadget serial driver and the host driver are both installed,
and a USB cable connects the gadget device to the host, you should
be able to communicate over USB between the gadget and host systems.
You can use minicom or HyperTerminal to try this out.
On the gadget side run "minicom -s" to configure a new minicom
session. Under "Serial port setup" set "/dev/ttygserial" as the
"Serial Device". Set baud rate, data bits, parity, and stop bits,
to 9600, 8, none, and 1--these settings mostly do not matter.
Under "Modem and dialing" erase all the modem and dialing strings.
On a Linux host running the ACM driver, configure minicom similarly
but use "/dev/ttyACM0" as the "Serial Device". (If you have other
ACM devices connected, change the device name appropriately.)
On a Linux host running the USB generic serial driver, configure
minicom similarly, but use "/dev/ttyUSB0" as the "Serial Device".
(If you have other USB serial devices connected, change the device
name appropriately.)
On a Windows host configure a new HyperTerminal session to use the
COM port assigned to Gadget Serial. The "Port Settings" will be
set automatically when HyperTerminal connects to the gadget serial
device, so you can leave them set to the default values--these
settings mostly do not matter.
With minicom configured and running on the gadget side and with
minicom or HyperTerminal configured and running on the host side,
you should be able to send data back and forth between the gadget
side and host side systems. Anything you type on the terminal
window on the gadget side should appear in the terminal window on
the host side and vice versa.
......@@ -103,7 +103,7 @@ firmware_class_hotplug(struct class_device *class_dev, char **envp,
"FIRMWARE=%s", fw_priv->fw_id))
return -ENOMEM;
envp[i++] = NULL;
envp[i] = NULL;
return 0;
}
......
......@@ -36,7 +36,7 @@
#define DRV_NAME "ub"
#define DEVFS_NAME DRV_NAME
#define UB_MAJOR 125 /* Stolen from Experimental range for a week - XXX */
#define UB_MAJOR 180
/*
* Definitions which have to be scattered once we understand the layout better.
......@@ -1535,8 +1535,11 @@ static int ub_bd_revalidate(struct gendisk *disk)
ub_revalidate(sc);
/* This is pretty much a long term P3 */
if (!atomic_read(&sc->poison)) { /* Cover sc->dev */
printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n",
sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize);
sc->name, sc->dev->devnum,
sc->capacity.nsec, sc->capacity.bsize);
}
/* XXX Support sector size switching like in sr.c */
blk_queue_hardsect_size(disk->queue, sc->capacity.bsize);
......
......@@ -38,6 +38,7 @@ obj-$(CONFIG_USB_KONICAWC) += media/
obj-$(CONFIG_USB_OV511) += media/
obj-$(CONFIG_USB_PWC) += media/
obj-$(CONFIG_USB_SE401) += media/
obj-$(CONFIG_USB_SN9C102) += media/
obj-$(CONFIG_USB_STV680) += media/
obj-$(CONFIG_USB_VICAM) += media/
obj-$(CONFIG_USB_W9968CF) += media/
......
......@@ -243,14 +243,16 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs)
// BUG ();
}
if (urb->status && urb->status != -ECONNRESET) {
if (io->status == 0 && urb->status && urb->status != -ECONNRESET) {
int i, found, status;
io->status = urb->status;
/* the previous urbs, and this one, completed already.
* unlink pending urbs so they won't rx/tx bad data.
* careful: unlink can sometimes be synchronous...
*/
spin_unlock (&io->lock);
for (i = 0, found = 0; i < io->entries; i++) {
if (!io->urbs [i] || !io->urbs [i]->dev)
continue;
......@@ -263,6 +265,7 @@ static void sg_complete (struct urb *urb, struct pt_regs *regs)
} else if (urb == io->urbs [i])
found = 1;
}
spin_lock (&io->lock);
}
urb->dev = NULL;
......@@ -524,6 +527,7 @@ void usb_sg_cancel (struct usb_sg_request *io)
int i;
io->status = -ECONNRESET;
spin_unlock (&io->lock);
for (i = 0; i < io->entries; i++) {
int retval;
......@@ -534,6 +538,7 @@ void usb_sg_cancel (struct usb_sg_request *io)
dev_warn (&io->dev->dev, "%s, unlink --> %d\n",
__FUNCTION__, retval);
}
spin_lock (&io->lock);
}
spin_unlock_irqrestore (&io->lock, flags);
}
......
......@@ -451,9 +451,11 @@ int usb_unlink_urb(struct urb *urb)
return -EINVAL;
if (!(urb->transfer_flags & URB_ASYNC_UNLINK)) {
#ifdef CONFIG_DEBUG_KERNEL
if (printk_ratelimit()) {
printk(KERN_NOTICE "usb_unlink_urb() is deprecated for "
"synchronous unlinks. Use usb_kill_urb() instead.\n");
WARN_ON(1);
}
#endif
usb_kill_urb(urb);
return 0;
......
......@@ -656,7 +656,7 @@ static int usb_hotplug (struct device *dev, char **envp, int num_envp,
return -ENOMEM;
}
envp[i++] = NULL;
envp[i] = NULL;
return 0;
}
......
......@@ -33,3 +33,18 @@ extern struct usb_driver usbfs_driver;
extern struct file_operations usbfs_devices_fops;
extern struct file_operations usbfs_device_file_operations;
extern void usbfs_conn_disc_event(void);
struct dev_state {
struct list_head list; /* state list */
struct usb_device *dev;
struct file *file;
spinlock_t lock; /* protects the async urb lists */
struct list_head async_pending;
struct list_head async_completed;
wait_queue_head_t wait; /* wake up if a request completed */
unsigned int discsignr;
struct task_struct *disctask;
void __user *disccontext;
unsigned long ifclaimed;
};
......@@ -223,6 +223,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
#define DEV_CONFIG_CDC
#endif
#ifdef CONFIG_USB_GADGET_LH7A40X
#define DEV_CONFIG_CDC
#endif
#ifdef CONFIG_USB_GADGET_MQ11XX
#define DEV_CONFIG_CDC
#endif
......@@ -235,6 +239,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
#define DEV_CONFIG_CDC
#endif
#ifdef CONFIG_USB_GADGET_PXA27X
#define DEV_CONFIG_CDC
#endif
/* For CDC-incapable hardware, choose the simple cdc subset.
* Anything that talks bulk (without notable bugs) can do this.
......@@ -247,10 +255,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address");
#define DEV_CONFIG_SUBSET
#endif
#ifdef CONFIG_USB_GADGET_LH7A40X
#define DEV_CONFIG_CDC
#endif
#ifdef CONFIG_USB_GADGET_SA1100
/* use non-CDC for backwards compatibility */
#define DEV_CONFIG_SUBSET
......@@ -2321,6 +2325,8 @@ eth_bind (struct usb_gadget *gadget)
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
} else if (gadget_is_n9604(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
} else if (gadget_is_pxa27x(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
} else {
/* can't assume CDC works. don't want to default to
* anything less functional on CDC-capable hardware,
......
......@@ -3739,6 +3739,8 @@ static int __init check_parameters(struct fsg_dev *fsg)
mod_data.release = 0x0309;
else if (gadget_is_n9604(fsg->gadget))
mod_data.release = 0x0310;
else if (gadget_is_pxa27x(fsg->gadget))
mod_data.release = 0x0311;
else {
WARN(fsg, "controller '%s' not recognized\n",
fsg->gadget->name);
......
......@@ -68,6 +68,12 @@
#define gadget_is_n9604(g) 0
#endif
#ifdef CONFIG_USB_GADGET_PXA27X
#define gadget_is_pxa27x(g) !strcmp("pxa27x_udc", (g)->name)
#else
#define gadget_is_pxa27x(g) 0
#endif
// CONFIG_USB_GADGET_AT91RM9200
// CONFIG_USB_GADGET_SX2
// CONFIG_USB_GADGET_AU1X00
......
......@@ -1529,6 +1529,9 @@ static int gs_bind(struct usb_gadget *gadget)
} else if (gadget_is_n9604(gadget)) {
gs_device_desc.bcdDevice =
__constant_cpu_to_le16(GS_VERSION_NUM|0x0009);
} else if (gadget_is_pxa27x(gadget)) {
gs_device_desc.bcdDevice =
__constant_cpu_to_le16(GS_VERSION_NUM|0x0011);
} else {
printk(KERN_WARNING "gs_bind: controller '%s' not recognized\n",
gadget->name);
......
......@@ -1190,6 +1190,8 @@ zero_bind (struct usb_gadget *gadget)
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0209);
} else if (gadget_is_n9604(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210);
} else if (gadget_is_pxa27x(gadget)) {
device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211);
} else {
/* gadget zero is so simple (for now, no altsettings) that
* it SHOULD NOT have problems with bulk-capable hardware.
......
......@@ -379,6 +379,14 @@ static int ehci_hc_reset (struct usb_hcd *hcd)
/* cache this readonly data; minimize PCI reads */
ehci->hcs_params = readl (&ehci->caps->hcs_params);
/* at least the Genesys GL880S needs fixup here */
temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params);
temp &= 0x0f;
if (temp && HCS_N_PORTS(ehci->hcs_params) > temp) {
temp |= (ehci->hcs_params & ~0xf);
ehci->hcs_params = temp;
}
/* force HC to halt state */
return ehci_halt (ehci);
}
......
......@@ -281,8 +281,11 @@ ehci_hub_descriptor (
temp = 0x0008; /* per-port overcurrent reporting */
if (HCS_PPC (ehci->hcs_params))
temp |= 0x0001; /* per-port power control */
#if 0
// re-enable when we support USB_PORT_FEAT_INDICATOR below.
if (HCS_INDICATOR (ehci->hcs_params))
temp |= 0x0080; /* per-port indicators (LEDs) */
#endif
desc->wHubCharacteristics = cpu_to_le16 (temp);
}
......
......@@ -175,6 +175,8 @@ static void qtd_copy_status (
static void
ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
__releases(ehci->lock)
__acquires(ehci->lock)
{
if (likely (urb->hcpriv != 0)) {
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
......
......@@ -35,6 +35,8 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
*/
static void
finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs)
__releases(ohci->lock)
__acquires(ohci->lock)
{
// ASSERT (urb->hcpriv != 0);
......
......@@ -1602,7 +1602,10 @@ static void uhci_free_pending_tds(struct uhci_hcd *uhci)
}
}
static void uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
static void
uhci_finish_urb(struct usb_hcd *hcd, struct urb *urb, struct pt_regs *regs)
__releases(uhci->schedule_lock)
__acquires(uhci->schedule_lock)
{
struct uhci_hcd *uhci = hcd_to_uhci(hcd);
......
......@@ -102,6 +102,7 @@
#define ATI_REMOTE_VENDOR_ID 0x0bc7
#define ATI_REMOTE_PRODUCT_ID 0x004
#define LOLA_REMOTE_PRODUCT_ID 0x002
#define MEDION_REMOTE_PRODUCT_ID 0x006
#define DRIVER_VERSION "2.2.1"
#define DRIVER_AUTHOR "Torrey Hoffman <thoffman@arnor.net>"
......@@ -126,6 +127,7 @@ MODULE_PARM_DESC(debug, "Enable extra debug messages and information");
static struct usb_device_id ati_remote_table[] = {
{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, ATI_REMOTE_PRODUCT_ID) },
{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, LOLA_REMOTE_PRODUCT_ID) },
{ USB_DEVICE(ATI_REMOTE_VENDOR_ID, MEDION_REMOTE_PRODUCT_ID) },
{} /* Terminating entry */
};
......@@ -730,7 +732,8 @@ static int ati_remote_probe(struct usb_interface *interface, const struct usb_de
/* See if the offered device matches what we can accept */
if ((udev->descriptor.idVendor != ATI_REMOTE_VENDOR_ID) ||
( (udev->descriptor.idProduct != ATI_REMOTE_PRODUCT_ID) &&
(udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) ))
(udev->descriptor.idProduct != LOLA_REMOTE_PRODUCT_ID) &&
(udev->descriptor.idProduct != MEDION_REMOTE_PRODUCT_ID) ))
return -ENODEV;
/* Allocate and clear an ati_remote struct */
......
......@@ -94,7 +94,8 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned
memset(field, 0, sizeof(struct hid_field) + usages * sizeof(struct hid_usage)
+ values * sizeof(unsigned));
report->field[report->maxfield++] = field;
field->index = report->maxfield++;
report->field[field->index] = field;
field->usage = (struct hid_usage *)(field + 1);
field->value = (unsigned *)(field->usage + usages);
field->report = report;
......
......@@ -59,6 +59,10 @@
#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
#define DRIVER_DESC "eGalax TouchKit USB HID Touchscreen Driver"
static int swap_xy;
module_param(swap_xy, bool, 0644);
MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
struct touchkit_usb {
unsigned char *data;
dma_addr_t data_dma;
......@@ -80,6 +84,7 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
{
struct touchkit_usb *touchkit = urb->context;
int retval;
int x, y;
switch (urb->status) {
case 0:
......@@ -103,13 +108,19 @@ static void touchkit_irq(struct urb *urb, struct pt_regs *regs)
goto exit;
}
if (swap_xy) {
y = TOUCHKIT_GET_X(touchkit->data);
x = TOUCHKIT_GET_Y(touchkit->data);
} else {
x = TOUCHKIT_GET_X(touchkit->data);
y = TOUCHKIT_GET_Y(touchkit->data);
}
input_regs(&touchkit->input, regs);
input_report_key(&touchkit->input, BTN_TOUCH,
TOUCHKIT_GET_TOUCHED(touchkit->data));
input_report_abs(&touchkit->input, ABS_X,
TOUCHKIT_GET_X(touchkit->data));
input_report_abs(&touchkit->input, ABS_Y,
TOUCHKIT_GET_Y(touchkit->data));
input_report_abs(&touchkit->input, ABS_X, x);
input_report_abs(&touchkit->input, ABS_Y, y);
input_sync(&touchkit->input);
exit:
......
......@@ -527,7 +527,7 @@ static void ax8817x_interrupt_complete(struct urb *urb, struct pt_regs *regs)
devdbg(dev, "ax8817x - Link Status is: %d", link);
}
}
usb_submit_urb(data->int_urb, GFP_KERNEL);
usb_submit_urb(data->int_urb, GFP_ATOMIC);
}
}
......
......@@ -2797,9 +2797,12 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio
static void unicode_to_ascii (char *string, __le16 *unicode, int unicode_size)
{
int i;
for (i = 0; i < unicode_size; ++i) {
if (unicode_size <= 0)
return;
for (i = 0; i < unicode_size; ++i)
string[i] = (char)(le16_to_cpu(unicode[i]));
}
string[unicode_size] = 0x00;
}
......
......@@ -494,10 +494,9 @@ static int visor_write (struct usb_serial_port *port, const unsigned char *buf,
spin_lock_irqsave(&priv->lock, flags);
if (priv->outstanding_urbs > URB_UPPER_LIMIT) {
spin_unlock_irqrestore(&priv->lock, flags);
dev_dbg(&port->dev, "write limit hit\n");
dbg("%s - write limit hit\n", __FUNCTION__);
return 0;
}
++priv->outstanding_urbs;
spin_unlock_irqrestore(&priv->lock, flags);
buffer = kmalloc (count, GFP_ATOMIC);
......
......@@ -2,16 +2,23 @@
# USB Storage driver configuration
#
comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information"
config USB_STORAGE
tristate "USB Mass Storage support"
depends on USB
select SCSI
---help---
Say Y here if you want to connect USB mass storage devices to your
computer's USB port. This is the driver you need for USB floppy drives,
USB hard disks, USB tape drives and USB CD-ROMs, along with
similar devices. This driver may also be used for some cameras and
card readers.
computer's USB port. This is the driver you need for USB
floppy drives, USB hard disks, USB tape drives, USB CD-ROMs,
USB flash devices, and memory sticks, along with
similar devices. This driver may also be used for some cameras
and card readers.
This option 'selects' (turns on, enables) 'SCSI', but you
probably also need 'SCSI device support: SCSI disk support'
(BLK_DEV_SD) for most USB storage devices.
To compile this driver as a module, choose M here: the
module will be called usb-storage.
......
......@@ -274,6 +274,14 @@ UNUSUAL_DEV( 0x052b, 0x1801, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Another Yakumo camera.
* Reported by Michele Alzetta <michele.alzetta@aliceposta.it> */
UNUSUAL_DEV( 0x052b, 0x1804, 0x0100, 0x0100,
"Tekom Technologies, Inc",
"300_CAMERA",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ),
/* Reported by Iacopo Spalletti <avvisi@spalletti.it> */
UNUSUAL_DEV( 0x052b, 0x1807, 0x0100, 0x0100,
"Tekom Technologies, Inc",
......
......@@ -144,29 +144,4 @@ struct usbdevfs_hub_portinfo {
#define USBDEVFS_DISCONNECT _IO('U', 22)
#define USBDEVFS_CONNECT _IO('U', 23)
/* --------------------------------------------------------------------- */
#ifdef __KERNEL__
#include <linux/list.h>
#include <asm/semaphore.h>
struct dev_state {
struct list_head list; /* state list */
struct usb_device *dev;
struct file *file;
spinlock_t lock; /* protects the async urb lists */
struct list_head async_pending;
struct list_head async_completed;
wait_queue_head_t wait; /* wake up if a request completed */
unsigned int discsignr;
struct task_struct *disctask;
void __user *disccontext;
unsigned long ifclaimed;
};
#endif /* __KERNEL__ */
/* --------------------------------------------------------------------- */
#endif /* _LINUX_USBDEVICE_FS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment