/spare/repo/netdev-2.6 branch 'master'
This commit is contained in:
@@ -20,6 +20,7 @@ config USB_ARCH_HAS_OHCI
|
||||
default y if SA1111
|
||||
default y if ARCH_OMAP
|
||||
default y if ARCH_LH7A404
|
||||
default y if ARCH_S3C2410
|
||||
default y if PXA27x
|
||||
# PPC:
|
||||
default y if STB03xxx
|
||||
|
@@ -980,6 +980,9 @@ static struct usb_device_id acm_ids[] = {
|
||||
{ USB_DEVICE(0x0870, 0x0001), /* Metricom GS Modem */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
{ USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */
|
||||
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
|
||||
},
|
||||
/* control interfaces with various AT-command sets */
|
||||
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
|
||||
USB_CDC_ACM_PROTO_AT_V25TER) },
|
||||
|
@@ -569,8 +569,11 @@ static int proc_control(struct dev_state *ps, void __user *arg)
|
||||
free_page((unsigned long)tbuf);
|
||||
return -EINVAL;
|
||||
}
|
||||
snoop(&dev->dev, "control read: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n",
|
||||
ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex);
|
||||
snoop(&dev->dev, "control read: bRequest=%02x "
|
||||
"bRrequestType=%02x wValue=%04x "
|
||||
"wIndex=%04x wLength=%04x\n",
|
||||
ctrl.bRequest, ctrl.bRequestType, ctrl.wValue,
|
||||
ctrl.wIndex, ctrl.wLength);
|
||||
|
||||
usb_unlock_device(dev);
|
||||
i = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ctrl.bRequest, ctrl.bRequestType,
|
||||
@@ -579,11 +582,11 @@ static int proc_control(struct dev_state *ps, void __user *arg)
|
||||
if ((i > 0) && ctrl.wLength) {
|
||||
if (usbfs_snoop) {
|
||||
dev_info(&dev->dev, "control read: data ");
|
||||
for (j = 0; j < ctrl.wLength; ++j)
|
||||
for (j = 0; j < i; ++j)
|
||||
printk ("%02x ", (unsigned char)(tbuf)[j]);
|
||||
printk("\n");
|
||||
}
|
||||
if (copy_to_user(ctrl.data, tbuf, ctrl.wLength)) {
|
||||
if (copy_to_user(ctrl.data, tbuf, i)) {
|
||||
free_page((unsigned long)tbuf);
|
||||
return -EFAULT;
|
||||
}
|
||||
@@ -595,8 +598,11 @@ static int proc_control(struct dev_state *ps, void __user *arg)
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
snoop(&dev->dev, "control write: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x\n",
|
||||
ctrl.bRequest, ctrl.bRequestType, ctrl.wValue, ctrl.wIndex);
|
||||
snoop(&dev->dev, "control write: bRequest=%02x "
|
||||
"bRrequestType=%02x wValue=%04x "
|
||||
"wIndex=%04x wLength=%04x\n",
|
||||
ctrl.bRequest, ctrl.bRequestType, ctrl.wValue,
|
||||
ctrl.wIndex, ctrl.wLength);
|
||||
if (usbfs_snoop) {
|
||||
dev_info(&dev->dev, "control write: data: ");
|
||||
for (j = 0; j < ctrl.wLength; ++j)
|
||||
|
@@ -939,9 +939,9 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount)
|
||||
case USB_SPEED_HIGH: /* ISOC or INTR */
|
||||
// FIXME adjust for input vs output
|
||||
if (isoc)
|
||||
tmp = HS_USECS (bytecount);
|
||||
tmp = HS_NSECS_ISO (bytecount);
|
||||
else
|
||||
tmp = HS_USECS_ISO (bytecount);
|
||||
tmp = HS_NSECS (bytecount);
|
||||
return tmp;
|
||||
default:
|
||||
pr_debug ("%s: bogus device speed!\n", usbcore_name);
|
||||
|
@@ -334,17 +334,19 @@ extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
|
||||
extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
|
||||
|
||||
/*
|
||||
* Ceiling microseconds (typical) for that many bytes at high speed
|
||||
* Ceiling [nano/micro]seconds (typical) for that many bytes at high speed
|
||||
* ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed
|
||||
* to preallocate bandwidth)
|
||||
*/
|
||||
#define USB2_HOST_DELAY 5 /* nsec, guess */
|
||||
#define HS_USECS(bytes) NS_TO_US ( ((55 * 8 * 2083)/1000) \
|
||||
#define HS_NSECS(bytes) ( ((55 * 8 * 2083)/1000) \
|
||||
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
|
||||
+ USB2_HOST_DELAY)
|
||||
#define HS_USECS_ISO(bytes) NS_TO_US ( ((38 * 8 * 2083)/1000) \
|
||||
#define HS_NSECS_ISO(bytes) ( ((38 * 8 * 2083)/1000) \
|
||||
+ ((2083UL * (3167 + BitTime (bytes)))/1000) \
|
||||
+ USB2_HOST_DELAY)
|
||||
#define HS_USECS(bytes) NS_TO_US (HS_NSECS(bytes))
|
||||
#define HS_USECS_ISO(bytes) NS_TO_US (HS_NSECS_ISO(bytes))
|
||||
|
||||
extern long usb_calc_bus_time (int speed, int is_input,
|
||||
int isoc, int bytecount);
|
||||
|
@@ -985,8 +985,10 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
||||
for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) {
|
||||
struct usb_interface *interface;
|
||||
|
||||
/* remove this interface */
|
||||
/* remove this interface if it has been registered */
|
||||
interface = dev->actconfig->interface[i];
|
||||
if (!klist_node_attached(&interface->dev.knode_bus))
|
||||
continue;
|
||||
dev_dbg (&dev->dev, "unregistering interface %s\n",
|
||||
interface->dev.bus_id);
|
||||
usb_remove_sysfs_intf_files(interface);
|
||||
@@ -1439,7 +1441,7 @@ free_interfaces:
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// synchronous request completion model
|
||||
|
@@ -657,8 +657,8 @@ qh_make (
|
||||
* For control/bulk requests, the HC or TT handles these.
|
||||
*/
|
||||
if (type == PIPE_INTERRUPT) {
|
||||
qh->usecs = usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0,
|
||||
hb_mult (maxp) * max_packet (maxp));
|
||||
qh->usecs = NS_TO_US (usb_calc_bus_time (USB_SPEED_HIGH, is_input, 0,
|
||||
hb_mult (maxp) * max_packet (maxp)));
|
||||
qh->start = NO_FRAME;
|
||||
|
||||
if (urb->dev->speed == USB_SPEED_HIGH) {
|
||||
|
@@ -887,6 +887,10 @@ MODULE_LICENSE ("GPL");
|
||||
#include "ohci-sa1111.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_S3C2410
|
||||
#include "ohci-s3c2410.c"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ARCH_OMAP
|
||||
#include "ohci-omap.c"
|
||||
#endif
|
||||
@@ -909,6 +913,7 @@ MODULE_LICENSE ("GPL");
|
||||
|
||||
#if !(defined(CONFIG_PCI) \
|
||||
|| defined(CONFIG_SA1111) \
|
||||
|| defined(CONFIG_ARCH_S3C2410) \
|
||||
|| defined(CONFIG_ARCH_OMAP) \
|
||||
|| defined (CONFIG_ARCH_LH7A404) \
|
||||
|| defined (CONFIG_PXA27x) \
|
||||
|
496
drivers/usb/host/ohci-s3c2410.c
Normal file
496
drivers/usb/host/ohci-s3c2410.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* OHCI HCD (Host Controller Driver) for USB.
|
||||
*
|
||||
* (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
|
||||
* (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net>
|
||||
* (C) Copyright 2002 Hewlett-Packard Company
|
||||
*
|
||||
* USB Bus Glue for Samsung S3C2410
|
||||
*
|
||||
* Written by Christopher Hoover <ch@hpl.hp.com>
|
||||
* Based on fragments of previous driver by Rusell King et al.
|
||||
*
|
||||
* Modified for S3C2410 from ohci-sa1111.c, ohci-omap.c and ohci-lh7a40.c
|
||||
* by Ben Dooks, <ben@simtec.co.uk>
|
||||
* Copyright (C) 2004 Simtec Electronics
|
||||
*
|
||||
* Thanks to basprog@mail.ru for updates to newer kernels
|
||||
*
|
||||
* This file is licenced under the GPL.
|
||||
*/
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/hardware/clock.h>
|
||||
#include <asm/arch/usb-control.h>
|
||||
|
||||
#define valid_port(idx) ((idx) == 1 || (idx) == 2)
|
||||
|
||||
/* clock device associated with the hcd */
|
||||
|
||||
static struct clk *clk;
|
||||
|
||||
/* forward definitions */
|
||||
|
||||
static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc);
|
||||
|
||||
/* conversion functions */
|
||||
|
||||
struct s3c2410_hcd_info *to_s3c2410_info(struct usb_hcd *hcd)
|
||||
{
|
||||
return hcd->self.controller->platform_data;
|
||||
}
|
||||
|
||||
static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)
|
||||
{
|
||||
struct s3c2410_hcd_info *info = dev->dev.platform_data;
|
||||
|
||||
dev_dbg(&dev->dev, "s3c2410_start_hc:\n");
|
||||
clk_enable(clk);
|
||||
|
||||
if (info != NULL) {
|
||||
info->hcd = hcd;
|
||||
info->report_oc = s3c2410_hcd_oc;
|
||||
|
||||
if (info->enable_oc != NULL) {
|
||||
(info->enable_oc)(info, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void s3c2410_stop_hc(struct platform_device *dev)
|
||||
{
|
||||
struct s3c2410_hcd_info *info = dev->dev.platform_data;
|
||||
|
||||
dev_dbg(&dev->dev, "s3c2410_stop_hc:\n");
|
||||
|
||||
if (info != NULL) {
|
||||
info->report_oc = NULL;
|
||||
info->hcd = NULL;
|
||||
|
||||
if (info->enable_oc != NULL) {
|
||||
(info->enable_oc)(info, 0);
|
||||
}
|
||||
}
|
||||
|
||||
clk_disable(clk);
|
||||
}
|
||||
|
||||
/* ohci_s3c2410_hub_status_data
|
||||
*
|
||||
* update the status data from the hub with anything that
|
||||
* has been detected by our system
|
||||
*/
|
||||
|
||||
static int
|
||||
ohci_s3c2410_hub_status_data (struct usb_hcd *hcd, char *buf)
|
||||
{
|
||||
struct s3c2410_hcd_info *info = to_s3c2410_info(hcd);
|
||||
struct s3c2410_hcd_port *port;
|
||||
int orig;
|
||||
int portno;
|
||||
|
||||
orig = ohci_hub_status_data (hcd, buf);
|
||||
|
||||
if (info == NULL)
|
||||
return orig;
|
||||
|
||||
port = &info->port[0];
|
||||
|
||||
/* mark any changed port as changed */
|
||||
|
||||
for (portno = 0; portno < 2; port++, portno++) {
|
||||
if (port->oc_changed == 1 &&
|
||||
port->flags & S3C_HCDFLG_USED) {
|
||||
dev_dbg(hcd->self.controller,
|
||||
"oc change on port %d\n", portno);
|
||||
|
||||
if (orig < 1)
|
||||
orig = 1;
|
||||
|
||||
buf[0] |= 1<<(portno+1);
|
||||
}
|
||||
}
|
||||
|
||||
return orig;
|
||||
}
|
||||
|
||||
/* s3c2410_usb_set_power
|
||||
*
|
||||
* configure the power on a port, by calling the platform device
|
||||
* routine registered with the platform device
|
||||
*/
|
||||
|
||||
static void s3c2410_usb_set_power(struct s3c2410_hcd_info *info,
|
||||
int port, int to)
|
||||
{
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
if (info->power_control != NULL) {
|
||||
info->port[port-1].power = to;
|
||||
(info->power_control)(port, to);
|
||||
}
|
||||
}
|
||||
|
||||
/* ohci_s3c2410_hub_control
|
||||
*
|
||||
* look at control requests to the hub, and see if we need
|
||||
* to take any action or over-ride the results from the
|
||||
* request.
|
||||
*/
|
||||
|
||||
static int ohci_s3c2410_hub_control (
|
||||
struct usb_hcd *hcd,
|
||||
u16 typeReq,
|
||||
u16 wValue,
|
||||
u16 wIndex,
|
||||
char *buf,
|
||||
u16 wLength)
|
||||
{
|
||||
struct s3c2410_hcd_info *info = to_s3c2410_info(hcd);
|
||||
struct usb_hub_descriptor *desc;
|
||||
int ret = -EINVAL;
|
||||
u32 *data = (u32 *)buf;
|
||||
|
||||
dev_dbg(hcd->self.controller,
|
||||
"s3c2410_hub_control(%p,0x%04x,0x%04x,0x%04x,%p,%04x)\n",
|
||||
hcd, typeReq, wValue, wIndex, buf, wLength);
|
||||
|
||||
/* if we are only an humble host without any special capabilites
|
||||
* process the request straight away and exit */
|
||||
|
||||
if (info == NULL) {
|
||||
ret = ohci_hub_control(hcd, typeReq, wValue,
|
||||
wIndex, buf, wLength);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check the request to see if it needs handling */
|
||||
|
||||
switch (typeReq) {
|
||||
case SetPortFeature:
|
||||
if (wValue == USB_PORT_FEAT_POWER) {
|
||||
dev_dbg(hcd->self.controller, "SetPortFeat: POWER\n");
|
||||
s3c2410_usb_set_power(info, wIndex, 1);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
|
||||
case ClearPortFeature:
|
||||
switch (wValue) {
|
||||
case USB_PORT_FEAT_C_OVER_CURRENT:
|
||||
dev_dbg(hcd->self.controller,
|
||||
"ClearPortFeature: C_OVER_CURRENT\n");
|
||||
|
||||
if (valid_port(wIndex)) {
|
||||
info->port[wIndex-1].oc_changed = 0;
|
||||
info->port[wIndex-1].oc_status = 0;
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
case USB_PORT_FEAT_OVER_CURRENT:
|
||||
dev_dbg(hcd->self.controller,
|
||||
"ClearPortFeature: OVER_CURRENT\n");
|
||||
|
||||
if (valid_port(wIndex)) {
|
||||
info->port[wIndex-1].oc_status = 0;
|
||||
}
|
||||
|
||||
goto out;
|
||||
|
||||
case USB_PORT_FEAT_POWER:
|
||||
dev_dbg(hcd->self.controller,
|
||||
"ClearPortFeature: POWER\n");
|
||||
|
||||
if (valid_port(wIndex)) {
|
||||
s3c2410_usb_set_power(info, wIndex, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ret = ohci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
switch (typeReq) {
|
||||
case GetHubDescriptor:
|
||||
|
||||
/* update the hub's descriptor */
|
||||
|
||||
desc = (struct usb_hub_descriptor *)buf;
|
||||
|
||||
if (info->power_control == NULL)
|
||||
return ret;
|
||||
|
||||
dev_dbg(hcd->self.controller, "wHubCharacteristics 0x%04x\n",
|
||||
desc->wHubCharacteristics);
|
||||
|
||||
/* remove the old configurations for power-switching, and
|
||||
* over-current protection, and insert our new configuration
|
||||
*/
|
||||
|
||||
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_LPSM);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(0x0001);
|
||||
|
||||
if (info->enable_oc) {
|
||||
desc->wHubCharacteristics &= ~cpu_to_le16(HUB_CHAR_OCPM);
|
||||
desc->wHubCharacteristics |= cpu_to_le16(0x0008|0x0001);
|
||||
}
|
||||
|
||||
dev_dbg(hcd->self.controller, "wHubCharacteristics after 0x%04x\n",
|
||||
desc->wHubCharacteristics);
|
||||
|
||||
return ret;
|
||||
|
||||
case GetPortStatus:
|
||||
/* check port status */
|
||||
|
||||
dev_dbg(hcd->self.controller, "GetPortStatus(%d)\n", wIndex);
|
||||
|
||||
if (valid_port(wIndex)) {
|
||||
if (info->port[wIndex-1].oc_changed) {
|
||||
*data |= cpu_to_le32(RH_PS_OCIC);
|
||||
}
|
||||
|
||||
if (info->port[wIndex-1].oc_status) {
|
||||
*data |= cpu_to_le32(RH_PS_POCI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* s3c2410_hcd_oc
|
||||
*
|
||||
* handle an over-current report
|
||||
*/
|
||||
|
||||
static void s3c2410_hcd_oc(struct s3c2410_hcd_info *info, int port_oc)
|
||||
{
|
||||
struct s3c2410_hcd_port *port;
|
||||
struct usb_hcd *hcd;
|
||||
unsigned long flags;
|
||||
int portno;
|
||||
|
||||
if (info == NULL)
|
||||
return;
|
||||
|
||||
port = &info->port[0];
|
||||
hcd = info->hcd;
|
||||
|
||||
local_irq_save(flags);
|
||||
|
||||
for (portno = 0; portno < 2; port++, portno++) {
|
||||
if (port_oc & (1<<portno) &&
|
||||
port->flags & S3C_HCDFLG_USED) {
|
||||
port->oc_status = 1;
|
||||
port->oc_changed = 1;
|
||||
|
||||
/* ok, once over-current is detected,
|
||||
the port needs to be powered down */
|
||||
s3c2410_usb_set_power(info, portno+1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
|
||||
/* may be called without controller electrically present */
|
||||
/* may be called with controller, bus, and devices active */
|
||||
|
||||
/*
|
||||
* usb_hcd_s3c2410_remove - shutdown processing for HCD
|
||||
* @dev: USB Host Controller being removed
|
||||
* Context: !in_interrupt()
|
||||
*
|
||||
* Reverses the effect of usb_hcd_3c2410_probe(), first invoking
|
||||
* the HCD's stop() method. It is always called from a thread
|
||||
* context, normally "rmmod", "apmd", or something similar.
|
||||
*
|
||||
*/
|
||||
|
||||
void usb_hcd_s3c2410_remove (struct usb_hcd *hcd, struct platform_device *dev)
|
||||
{
|
||||
usb_remove_hcd(hcd);
|
||||
s3c2410_stop_hc(dev);
|
||||
iounmap(hcd->regs);
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
usb_put_hcd(hcd);
|
||||
}
|
||||
|
||||
/**
|
||||
* usb_hcd_s3c2410_probe - initialize S3C2410-based HCDs
|
||||
* Context: !in_interrupt()
|
||||
*
|
||||
* Allocates basic resources for this USB host controller, and
|
||||
* then invokes the start() method for the HCD associated with it
|
||||
* through the hotplug entry's driver_data.
|
||||
*
|
||||
*/
|
||||
int usb_hcd_s3c2410_probe (const struct hc_driver *driver,
|
||||
struct platform_device *dev)
|
||||
{
|
||||
struct usb_hcd *hcd = NULL;
|
||||
int retval;
|
||||
|
||||
s3c2410_usb_set_power(dev->dev.platform_data, 0, 1);
|
||||
s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);
|
||||
|
||||
hcd = usb_create_hcd(driver, &dev->dev, "s3c24xx");
|
||||
if (hcd == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
hcd->rsrc_start = dev->resource[0].start;
|
||||
hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
|
||||
|
||||
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
|
||||
dev_err(&dev->dev, "request_mem_region failed");
|
||||
retval = -EBUSY;
|
||||
goto err0;
|
||||
}
|
||||
|
||||
clk = clk_get(NULL, "usb-host");
|
||||
if (IS_ERR(clk)) {
|
||||
dev_err(&dev->dev, "cannot get usb-host clock\n");
|
||||
retval = -ENOENT;
|
||||
goto err1;
|
||||
}
|
||||
|
||||
clk_use(clk);
|
||||
s3c2410_start_hc(dev, hcd);
|
||||
|
||||
hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
|
||||
if (!hcd->regs) {
|
||||
dev_err(&dev->dev, "ioremap failed\n");
|
||||
retval = -ENOMEM;
|
||||
goto err2;
|
||||
}
|
||||
|
||||
ohci_hcd_init(hcd_to_ohci(hcd));
|
||||
|
||||
retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
|
||||
if (retval != 0)
|
||||
goto err2;
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
s3c2410_stop_hc(dev);
|
||||
iounmap(hcd->regs);
|
||||
clk_unuse(clk);
|
||||
clk_put(clk);
|
||||
|
||||
err1:
|
||||
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
|
||||
|
||||
err0:
|
||||
usb_put_hcd(hcd);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
static int
|
||||
ohci_s3c2410_start (struct usb_hcd *hcd)
|
||||
{
|
||||
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
|
||||
int ret;
|
||||
|
||||
if ((ret = ohci_init(ohci)) < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = ohci_run (ohci)) < 0) {
|
||||
err ("can't start %s", hcd->self.bus_name);
|
||||
ohci_stop (hcd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct hc_driver ohci_s3c2410_hc_driver = {
|
||||
.description = hcd_name,
|
||||
.product_desc = "S3C24XX OHCI",
|
||||
.hcd_priv_size = sizeof(struct ohci_hcd),
|
||||
|
||||
/*
|
||||
* generic hardware linkage
|
||||
*/
|
||||
.irq = ohci_irq,
|
||||
.flags = HCD_USB11 | HCD_MEMORY,
|
||||
|
||||
/*
|
||||
* basic lifecycle operations
|
||||
*/
|
||||
.start = ohci_s3c2410_start,
|
||||
.stop = ohci_stop,
|
||||
|
||||
/*
|
||||
* managing i/o requests and associated device resources
|
||||
*/
|
||||
.urb_enqueue = ohci_urb_enqueue,
|
||||
.urb_dequeue = ohci_urb_dequeue,
|
||||
.endpoint_disable = ohci_endpoint_disable,
|
||||
|
||||
/*
|
||||
* scheduling support
|
||||
*/
|
||||
.get_frame_number = ohci_get_frame,
|
||||
|
||||
/*
|
||||
* root hub support
|
||||
*/
|
||||
.hub_status_data = ohci_s3c2410_hub_status_data,
|
||||
.hub_control = ohci_s3c2410_hub_control,
|
||||
|
||||
#if defined(CONFIG_USB_SUSPEND) && 0
|
||||
.hub_suspend = ohci_hub_suspend,
|
||||
.hub_resume = ohci_hub_resume,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* device driver */
|
||||
|
||||
static int ohci_hcd_s3c2410_drv_probe(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
return usb_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);
|
||||
}
|
||||
|
||||
static int ohci_hcd_s3c2410_drv_remove(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
|
||||
usb_hcd_s3c2410_remove(hcd, pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver ohci_hcd_s3c2410_driver = {
|
||||
.name = "s3c2410-ohci",
|
||||
.bus = &platform_bus_type,
|
||||
.probe = ohci_hcd_s3c2410_drv_probe,
|
||||
.remove = ohci_hcd_s3c2410_drv_remove,
|
||||
/*.suspend = ohci_hcd_s3c2410_drv_suspend, */
|
||||
/*.resume = ohci_hcd_s3c2410_drv_resume, */
|
||||
};
|
||||
|
||||
static int __init ohci_hcd_s3c2410_init (void)
|
||||
{
|
||||
return driver_register(&ohci_hcd_s3c2410_driver);
|
||||
}
|
||||
|
||||
static void __exit ohci_hcd_s3c2410_cleanup (void)
|
||||
{
|
||||
driver_unregister(&ohci_hcd_s3c2410_driver);
|
||||
}
|
||||
|
||||
module_init (ohci_hcd_s3c2410_init);
|
||||
module_exit (ohci_hcd_s3c2410_cleanup);
|
@@ -361,8 +361,7 @@ int mts_scsi_queuecommand (Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback );
|
||||
static void mts_transfer_cleanup( struct urb *transfer );
|
||||
static void mts_do_sg(struct urb * transfer, struct pt_regs *regs);
|
||||
|
||||
|
||||
inline static
|
||||
static inline
|
||||
void mts_int_submit_urb (struct urb* transfer,
|
||||
int pipe,
|
||||
void* data,
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
/*
|
||||
* Version Information
|
||||
@@ -87,8 +88,8 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
|
||||
if (prox) {
|
||||
int x = data[1] | (data[2] << 8);
|
||||
int y = data[3] | (data[4] << 8);
|
||||
/*Pressure should compute the same way for flair and 302*/
|
||||
int pressure = data[5] | ((int)data[6] << 8);
|
||||
/* Pressure should compute the same way for flair and 302 */
|
||||
int pressure = data[5] | (data[6] << 8);
|
||||
int touch = data[0] & 0x01;
|
||||
int stylus = (data[0] & 0x10) >> 4;
|
||||
int stylus2 = (data[0] & 0x20) >> 5;
|
||||
@@ -104,9 +105,9 @@ static void usb_acecad_irq(struct urb *urb, struct pt_regs *regs)
|
||||
input_sync(dev);
|
||||
|
||||
resubmit:
|
||||
status = usb_submit_urb (urb, GFP_ATOMIC);
|
||||
status = usb_submit_urb(urb, GFP_ATOMIC);
|
||||
if (status)
|
||||
err ("can't resubmit intr, %s-%s/input0, status %d",
|
||||
err("can't resubmit intr, %s-%s/input0, status %d",
|
||||
acecad->usbdev->bus->bus_name, acecad->usbdev->devpath, status);
|
||||
}
|
||||
|
||||
@@ -212,10 +213,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_
|
||||
|
||||
acecad->dev.name = acecad->name;
|
||||
acecad->dev.phys = acecad->phys;
|
||||
acecad->dev.id.bustype = BUS_USB;
|
||||
acecad->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
acecad->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
acecad->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &acecad->dev.id);
|
||||
acecad->dev.dev = &intf->dev;
|
||||
|
||||
usb_fill_int_urb(acecad->irq, dev, pipe,
|
||||
|
@@ -77,6 +77,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
#include <linux/sched.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/unaligned.h>
|
||||
@@ -2125,10 +2126,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||
aiptek->inputdev.absflat[ABS_WHEEL] = 0;
|
||||
aiptek->inputdev.name = "Aiptek";
|
||||
aiptek->inputdev.phys = aiptek->features.usbPath;
|
||||
aiptek->inputdev.id.bustype = BUS_USB;
|
||||
aiptek->inputdev.id.vendor = le16_to_cpu(usbdev->descriptor.idVendor);
|
||||
aiptek->inputdev.id.product = le16_to_cpu(usbdev->descriptor.idProduct);
|
||||
aiptek->inputdev.id.version = le16_to_cpu(usbdev->descriptor.bcdDevice);
|
||||
usb_to_input_id(usbdev, &aiptek->inputdev.id);
|
||||
aiptek->inputdev.dev = &intf->dev;
|
||||
|
||||
aiptek->usbdev = usbdev;
|
||||
|
@@ -94,6 +94,7 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
/*
|
||||
@@ -635,11 +636,8 @@ static void ati_remote_input_init(struct ati_remote *ati_remote)
|
||||
idev->name = ati_remote->name;
|
||||
idev->phys = ati_remote->phys;
|
||||
|
||||
idev->id.bustype = BUS_USB;
|
||||
idev->id.vendor = le16_to_cpu(ati_remote->udev->descriptor.idVendor);
|
||||
idev->id.product = le16_to_cpu(ati_remote->udev->descriptor.idProduct);
|
||||
idev->id.version = le16_to_cpu(ati_remote->udev->descriptor.bcdDevice);
|
||||
idev->dev = &(ati_remote->udev->dev);
|
||||
usb_to_input_id(ati_remote->udev, &idev->id);
|
||||
idev->dev = &ati_remote->udev->dev;
|
||||
}
|
||||
|
||||
static int ati_remote_initialize(struct ati_remote *ati_remote)
|
||||
|
@@ -789,12 +789,12 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
|
||||
static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt, struct pt_regs *regs)
|
||||
{
|
||||
hid_dump_input(usage, value);
|
||||
if (hid->claimed & HID_CLAIMED_INPUT)
|
||||
hidinput_hid_event(hid, field, usage, value, regs);
|
||||
if (hid->claimed & HID_CLAIMED_HIDDEV)
|
||||
if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt)
|
||||
hiddev_hid_event(hid, field, usage, value, regs);
|
||||
}
|
||||
|
||||
@@ -804,7 +804,7 @@ static void hid_process_event(struct hid_device *hid, struct hid_field *field, s
|
||||
* reporting to the layer).
|
||||
*/
|
||||
|
||||
static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, struct pt_regs *regs)
|
||||
static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt, struct pt_regs *regs)
|
||||
{
|
||||
unsigned n;
|
||||
unsigned count = field->report_count;
|
||||
@@ -831,19 +831,19 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u
|
||||
for (n = 0; n < count; n++) {
|
||||
|
||||
if (HID_MAIN_ITEM_VARIABLE & field->flags) {
|
||||
hid_process_event(hid, field, &field->usage[n], value[n], regs);
|
||||
hid_process_event(hid, field, &field->usage[n], value[n], interrupt, regs);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (field->value[n] >= min && field->value[n] <= max
|
||||
&& field->usage[field->value[n] - min].hid
|
||||
&& search(value, field->value[n], count))
|
||||
hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, regs);
|
||||
hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt, regs);
|
||||
|
||||
if (value[n] >= min && value[n] <= max
|
||||
&& field->usage[value[n] - min].hid
|
||||
&& search(field->value, value[n], count))
|
||||
hid_process_event(hid, field, &field->usage[value[n] - min], 1, regs);
|
||||
hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt, regs);
|
||||
}
|
||||
|
||||
memcpy(field->value, value, count * sizeof(__s32));
|
||||
@@ -851,7 +851,7 @@ exit:
|
||||
kfree(value);
|
||||
}
|
||||
|
||||
static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs)
|
||||
static int hid_input_report(int type, struct urb *urb, int interrupt, struct pt_regs *regs)
|
||||
{
|
||||
struct hid_device *hid = urb->context;
|
||||
struct hid_report_enum *report_enum = hid->report_enum + type;
|
||||
@@ -899,7 +899,7 @@ static int hid_input_report(int type, struct urb *urb, struct pt_regs *regs)
|
||||
hiddev_report_event(hid, report);
|
||||
|
||||
for (n = 0; n < report->maxfield; n++)
|
||||
hid_input_field(hid, report->field[n], data, regs);
|
||||
hid_input_field(hid, report->field[n], data, interrupt, regs);
|
||||
|
||||
if (hid->claimed & HID_CLAIMED_INPUT)
|
||||
hidinput_report_event(hid, report);
|
||||
@@ -918,7 +918,7 @@ static void hid_irq_in(struct urb *urb, struct pt_regs *regs)
|
||||
|
||||
switch (urb->status) {
|
||||
case 0: /* success */
|
||||
hid_input_report(HID_INPUT_REPORT, urb, regs);
|
||||
hid_input_report(HID_INPUT_REPORT, urb, 1, regs);
|
||||
break;
|
||||
case -ECONNRESET: /* unlink */
|
||||
case -ENOENT:
|
||||
@@ -1142,7 +1142,7 @@ static void hid_ctrl(struct urb *urb, struct pt_regs *regs)
|
||||
switch (urb->status) {
|
||||
case 0: /* success */
|
||||
if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN)
|
||||
hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, regs);
|
||||
hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0, regs);
|
||||
case -ESHUTDOWN: /* unplug */
|
||||
case -EILSEQ: /* unplug timectrl on uhci */
|
||||
unplug = 1;
|
||||
@@ -1372,6 +1372,9 @@ void hid_init_reports(struct hid_device *hid)
|
||||
#define USB_VENDOR_ID_A4TECH 0x09da
|
||||
#define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006
|
||||
|
||||
#define USB_VENDOR_ID_AASHIMA 0x06D6
|
||||
#define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025
|
||||
|
||||
#define USB_VENDOR_ID_CYPRESS 0x04b4
|
||||
#define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001
|
||||
#define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500
|
||||
@@ -1548,6 +1551,7 @@ static struct hid_blacklist {
|
||||
{ USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 },
|
||||
{ USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 },
|
||||
|
||||
{ USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD },
|
||||
{ USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT },
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
@@ -397,11 +398,12 @@ ignore:
|
||||
|
||||
void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, struct pt_regs *regs)
|
||||
{
|
||||
struct input_dev *input = &field->hidinput->input;
|
||||
struct input_dev *input;
|
||||
int *quirks = &hid->quirks;
|
||||
|
||||
if (!input)
|
||||
if (!field->hidinput)
|
||||
return;
|
||||
input = &field->hidinput->input;
|
||||
|
||||
input_regs(input, regs);
|
||||
|
||||
@@ -581,10 +583,7 @@ int hidinput_connect(struct hid_device *hid)
|
||||
hidinput->input.name = hid->name;
|
||||
hidinput->input.phys = hid->phys;
|
||||
hidinput->input.uniq = hid->uniq;
|
||||
hidinput->input.id.bustype = BUS_USB;
|
||||
hidinput->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
hidinput->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
hidinput->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &hidinput->input.id);
|
||||
hidinput->input.dev = &hid->intf->dev;
|
||||
}
|
||||
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
/* only an 8 byte buffer necessary for a single packet */
|
||||
#define ITM_BUFSIZE 8
|
||||
@@ -184,10 +185,7 @@ static int itmtouch_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
|
||||
itmtouch->inputdev.name = itmtouch->name;
|
||||
itmtouch->inputdev.phys = itmtouch->phys;
|
||||
itmtouch->inputdev.id.bustype = BUS_USB;
|
||||
itmtouch->inputdev.id.vendor = udev->descriptor.idVendor;
|
||||
itmtouch->inputdev.id.product = udev->descriptor.idProduct;
|
||||
itmtouch->inputdev.id.version = udev->descriptor.bcdDevice;
|
||||
usb_to_input_id(udev, &itmtouch->inputdev.id);
|
||||
itmtouch->inputdev.dev = &intf->dev;
|
||||
|
||||
if (!strlen(itmtouch->name))
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
@@ -167,10 +168,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
|
||||
kbtab->dev.name = "KB Gear Tablet";
|
||||
kbtab->dev.phys = kbtab->phys;
|
||||
kbtab->dev.id.bustype = BUS_USB;
|
||||
kbtab->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
kbtab->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
kbtab->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &kbtab->dev.id);
|
||||
kbtab->dev.dev = &intf->dev;
|
||||
kbtab->usbdev = dev;
|
||||
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
#define MTOUCHUSB_MIN_XC 0x0
|
||||
#define MTOUCHUSB_MAX_RAW_XC 0x4000
|
||||
@@ -232,10 +233,7 @@ static int mtouchusb_probe(struct usb_interface *intf, const struct usb_device_i
|
||||
|
||||
mtouch->input.name = mtouch->name;
|
||||
mtouch->input.phys = mtouch->phys;
|
||||
mtouch->input.id.bustype = BUS_USB;
|
||||
mtouch->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
|
||||
mtouch->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
|
||||
mtouch->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
|
||||
usb_to_input_id(udev, &mtouch->input.id);
|
||||
mtouch->input.dev = &intf->dev;
|
||||
|
||||
mtouch->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
#define POWERMATE_VENDOR 0x077d /* Griffin Technology, Inc. */
|
||||
#define POWERMATE_PRODUCT_NEW 0x0410 /* Griffin PowerMate */
|
||||
@@ -389,10 +390,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
|
||||
pm->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
|
||||
pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
|
||||
pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
|
||||
pm->input.id.bustype = BUS_USB;
|
||||
pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
|
||||
pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
|
||||
pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
|
||||
usb_to_input_id(udev, &pm->input.id);
|
||||
pm->input.event = powermate_input_event;
|
||||
pm->input.dev = &intf->dev;
|
||||
pm->input.phys = pm->phys;
|
||||
|
@@ -35,7 +35,7 @@
|
||||
#define DEBUG
|
||||
#endif
|
||||
#include <linux/usb.h>
|
||||
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
#define TOUCHKIT_MIN_XC 0x0
|
||||
#define TOUCHKIT_MAX_XC 0x07ff
|
||||
@@ -202,10 +202,7 @@ static int touchkit_probe(struct usb_interface *intf,
|
||||
|
||||
touchkit->input.name = touchkit->name;
|
||||
touchkit->input.phys = touchkit->phys;
|
||||
touchkit->input.id.bustype = BUS_USB;
|
||||
touchkit->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
|
||||
touchkit->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
|
||||
touchkit->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
|
||||
usb_to_input_id(udev, &touchkit->input.id);
|
||||
touchkit->input.dev = &intf->dev;
|
||||
|
||||
touchkit->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
/*
|
||||
* Version Information
|
||||
@@ -288,10 +289,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
|
||||
|
||||
kbd->dev.name = kbd->name;
|
||||
kbd->dev.phys = kbd->phys;
|
||||
kbd->dev.id.bustype = BUS_USB;
|
||||
kbd->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
kbd->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
kbd->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &kbd->dev.id);
|
||||
kbd->dev.dev = &iface->dev;
|
||||
|
||||
if (dev->manufacturer)
|
||||
|
@@ -32,6 +32,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
/*
|
||||
* Version Information
|
||||
@@ -171,10 +172,7 @@ static int usb_mouse_probe(struct usb_interface * intf, const struct usb_device_
|
||||
|
||||
mouse->dev.name = mouse->name;
|
||||
mouse->dev.phys = mouse->phys;
|
||||
mouse->dev.id.bustype = BUS_USB;
|
||||
mouse->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
mouse->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
mouse->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &mouse->dev.id);
|
||||
mouse->dev.dev = &intf->dev;
|
||||
|
||||
if (dev->manufacturer)
|
||||
|
@@ -69,6 +69,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
@@ -823,10 +824,7 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
|
||||
|
||||
wacom->dev.name = wacom->features->name;
|
||||
wacom->dev.phys = wacom->phys;
|
||||
wacom->dev.id.bustype = BUS_USB;
|
||||
wacom->dev.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
wacom->dev.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
wacom->dev.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &wacom->dev.id);
|
||||
wacom->dev.dev = &intf->dev;
|
||||
wacom->usbdev = dev;
|
||||
|
||||
|
@@ -62,6 +62,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/usb.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
#define DRIVER_VERSION "v0.0.5"
|
||||
#define DRIVER_AUTHOR "Marko Friedemann <mfr@bmx-chemnitz.de>"
|
||||
@@ -256,10 +257,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
|
||||
|
||||
xpad->udev = udev;
|
||||
|
||||
xpad->dev.id.bustype = BUS_USB;
|
||||
xpad->dev.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
|
||||
xpad->dev.id.product = le16_to_cpu(udev->descriptor.idProduct);
|
||||
xpad->dev.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
|
||||
usb_to_input_id(udev, &xpad->dev.id);
|
||||
xpad->dev.dev = &intf->dev;
|
||||
xpad->dev.private = xpad;
|
||||
xpad->dev.name = xpad_device[i].name;
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/usb_input.h>
|
||||
|
||||
#include "usbvideo.h"
|
||||
|
||||
@@ -845,10 +846,7 @@ static int konicawc_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
cam->input.private = cam;
|
||||
cam->input.evbit[0] = BIT(EV_KEY);
|
||||
cam->input.keybit[LONG(BTN_0)] = BIT(BTN_0);
|
||||
cam->input.id.bustype = BUS_USB;
|
||||
cam->input.id.vendor = le16_to_cpu(dev->descriptor.idVendor);
|
||||
cam->input.id.product = le16_to_cpu(dev->descriptor.idProduct);
|
||||
cam->input.id.version = le16_to_cpu(dev->descriptor.bcdDevice);
|
||||
usb_to_input_id(dev, &cam->input.id);
|
||||
input_register_device(&cam->input);
|
||||
|
||||
usb_make_path(dev, cam->input_physname, 56);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
*
|
||||
* V0.1 (mh) Initial version
|
||||
* V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint)
|
||||
* V0.12 (mh) Added kmalloc check for string buffer
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
@@ -84,7 +85,7 @@ static struct usb_device_id ld_usb_table [] = {
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, ld_usb_table);
|
||||
MODULE_VERSION("V0.11");
|
||||
MODULE_VERSION("V0.12");
|
||||
MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>");
|
||||
MODULE_DESCRIPTION("LD USB Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -635,6 +636,10 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *
|
||||
(le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) &&
|
||||
(le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) {
|
||||
buffer = kmalloc(256, GFP_KERNEL);
|
||||
if (buffer == NULL) {
|
||||
dev_err(&intf->dev, "Couldn't allocate string buffer\n");
|
||||
goto error;
|
||||
}
|
||||
/* usb_string makes SETUP+STALL to leave always ControlReadLoop */
|
||||
usb_string(udev, 255, buffer, 256);
|
||||
kfree(buffer);
|
||||
|
@@ -59,7 +59,6 @@ static const char driver_name[] = "pegasus";
|
||||
|
||||
static int loopback = 0;
|
||||
static int mii_mode = 0;
|
||||
static int multicast_filter_limit = 32;
|
||||
|
||||
static struct usb_eth_dev usb_dev_id[] = {
|
||||
#define PEGASUS_DEV(pn, vid, pid, flags) \
|
||||
|
@@ -167,8 +167,6 @@ struct rtl8150 {
|
||||
|
||||
typedef struct rtl8150 rtl8150_t;
|
||||
|
||||
static unsigned long multicast_filter_limit = 32;
|
||||
|
||||
static void fill_skb_pool(rtl8150_t *);
|
||||
static void free_skb_pool(rtl8150_t *);
|
||||
static inline struct sk_buff *pull_skb(rtl8150_t *);
|
||||
|
@@ -29,6 +29,7 @@ static struct usb_device_id zd1201_table[] = {
|
||||
{USB_DEVICE(0x0ace, 0x1201)}, /* ZyDAS ZD1201 Wireless USB Adapter */
|
||||
{USB_DEVICE(0x050d, 0x6051)}, /* Belkin F5D6051 usb adapter */
|
||||
{USB_DEVICE(0x0db0, 0x6823)}, /* MSI UB11B usb adapter */
|
||||
{USB_DEVICE(0x1044, 0x8005)}, /* GIGABYTE GN-WLBZ201 usb adapter */
|
||||
{}
|
||||
};
|
||||
|
||||
|
@@ -429,6 +429,9 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) },
|
||||
{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y6_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_Y8_PID) },
|
||||
{ USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
@@ -545,6 +548,7 @@ static struct usb_serial_device_type ftdi_sio_device = {
|
||||
|
||||
|
||||
#define WDR_TIMEOUT 5000 /* default urb timeout */
|
||||
#define WDR_SHORT_TIMEOUT 1000 /* shorter urb timeout */
|
||||
|
||||
/* High and low are for DTR, RTS etc etc */
|
||||
#define HIGH 1
|
||||
@@ -593,62 +597,59 @@ static __u32 ftdi_232bm_baud_to_divisor(int baud)
|
||||
return(ftdi_232bm_baud_base_to_divisor(baud, 48000000));
|
||||
}
|
||||
|
||||
static int set_rts(struct usb_serial_port *port, int high_or_low)
|
||||
#define set_mctrl(port, set) update_mctrl((port), (set), 0)
|
||||
#define clear_mctrl(port, clear) update_mctrl((port), 0, (clear))
|
||||
|
||||
static int update_mctrl(struct usb_serial_port *port, unsigned int set, unsigned int clear)
|
||||
{
|
||||
struct ftdi_private *priv = usb_get_serial_port_data(port);
|
||||
char *buf;
|
||||
unsigned ftdi_high_or_low;
|
||||
unsigned urb_value;
|
||||
int rv;
|
||||
|
||||
buf = kmalloc(1, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (high_or_low) {
|
||||
ftdi_high_or_low = FTDI_SIO_SET_RTS_HIGH;
|
||||
priv->last_dtr_rts |= TIOCM_RTS;
|
||||
} else {
|
||||
ftdi_high_or_low = FTDI_SIO_SET_RTS_LOW;
|
||||
priv->last_dtr_rts &= ~TIOCM_RTS;
|
||||
|
||||
if (((set | clear) & (TIOCM_DTR | TIOCM_RTS)) == 0) {
|
||||
dbg("%s - DTR|RTS not being set|cleared", __FUNCTION__);
|
||||
return 0; /* no change */
|
||||
}
|
||||
|
||||
buf = kmalloc(1, GFP_NOIO);
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clear &= ~set; /* 'set' takes precedence over 'clear' */
|
||||
urb_value = 0;
|
||||
if (clear & TIOCM_DTR)
|
||||
urb_value |= FTDI_SIO_SET_DTR_LOW;
|
||||
if (clear & TIOCM_RTS)
|
||||
urb_value |= FTDI_SIO_SET_RTS_LOW;
|
||||
if (set & TIOCM_DTR)
|
||||
urb_value |= FTDI_SIO_SET_DTR_HIGH;
|
||||
if (set & TIOCM_RTS)
|
||||
urb_value |= FTDI_SIO_SET_RTS_HIGH;
|
||||
rv = usb_control_msg(port->serial->dev,
|
||||
usb_sndctrlpipe(port->serial->dev, 0),
|
||||
FTDI_SIO_SET_MODEM_CTRL_REQUEST,
|
||||
FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
|
||||
ftdi_high_or_low, priv->interface,
|
||||
urb_value, priv->interface,
|
||||
buf, 0, WDR_TIMEOUT);
|
||||
|
||||
kfree(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
static int set_dtr(struct usb_serial_port *port, int high_or_low)
|
||||
{
|
||||
struct ftdi_private *priv = usb_get_serial_port_data(port);
|
||||
char *buf;
|
||||
unsigned ftdi_high_or_low;
|
||||
int rv;
|
||||
|
||||
buf = kmalloc(1, GFP_NOIO);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (high_or_low) {
|
||||
ftdi_high_or_low = FTDI_SIO_SET_DTR_HIGH;
|
||||
priv->last_dtr_rts |= TIOCM_DTR;
|
||||
if (rv < 0) {
|
||||
err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
|
||||
__FUNCTION__,
|
||||
(set & TIOCM_DTR) ? "HIGH" :
|
||||
(clear & TIOCM_DTR) ? "LOW" : "unchanged",
|
||||
(set & TIOCM_RTS) ? "HIGH" :
|
||||
(clear & TIOCM_RTS) ? "LOW" : "unchanged");
|
||||
} else {
|
||||
ftdi_high_or_low = FTDI_SIO_SET_DTR_LOW;
|
||||
priv->last_dtr_rts &= ~TIOCM_DTR;
|
||||
dbg("%s - DTR %s, RTS %s", __FUNCTION__,
|
||||
(set & TIOCM_DTR) ? "HIGH" :
|
||||
(clear & TIOCM_DTR) ? "LOW" : "unchanged",
|
||||
(set & TIOCM_RTS) ? "HIGH" :
|
||||
(clear & TIOCM_RTS) ? "LOW" : "unchanged");
|
||||
priv->last_dtr_rts = (priv->last_dtr_rts & ~clear) | set;
|
||||
}
|
||||
rv = usb_control_msg(port->serial->dev,
|
||||
usb_sndctrlpipe(port->serial->dev, 0),
|
||||
FTDI_SIO_SET_MODEM_CTRL_REQUEST,
|
||||
FTDI_SIO_SET_MODEM_CTRL_REQUEST_TYPE,
|
||||
ftdi_high_or_low, priv->interface,
|
||||
buf, 0, WDR_TIMEOUT);
|
||||
|
||||
kfree(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -681,7 +682,7 @@ static int change_speed(struct usb_serial_port *port)
|
||||
FTDI_SIO_SET_BAUDRATE_REQUEST,
|
||||
FTDI_SIO_SET_BAUDRATE_REQUEST_TYPE,
|
||||
urb_value, urb_index,
|
||||
buf, 0, 100);
|
||||
buf, 0, WDR_SHORT_TIMEOUT);
|
||||
|
||||
kfree(buf);
|
||||
return rv;
|
||||
@@ -1219,12 +1220,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp)
|
||||
/* FIXME: Flow control might be enabled, so it should be checked -
|
||||
we have no control of defaults! */
|
||||
/* Turn on RTS and DTR since we are not flow controlling by default */
|
||||
if (set_dtr(port, HIGH) < 0) {
|
||||
err("%s Error from DTR HIGH urb", __FUNCTION__);
|
||||
}
|
||||
if (set_rts(port, HIGH) < 0){
|
||||
err("%s Error from RTS HIGH urb", __FUNCTION__);
|
||||
}
|
||||
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
|
||||
/* Not throttled */
|
||||
spin_lock_irqsave(&priv->rx_lock, flags);
|
||||
@@ -1274,14 +1270,8 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp)
|
||||
err("error from flowcontrol urb");
|
||||
}
|
||||
|
||||
/* drop DTR */
|
||||
if (set_dtr(port, LOW) < 0){
|
||||
err("Error from DTR LOW urb");
|
||||
}
|
||||
/* drop RTS */
|
||||
if (set_rts(port, LOW) < 0) {
|
||||
err("Error from RTS LOW urb");
|
||||
}
|
||||
/* drop RTS and DTR */
|
||||
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
} /* Note change no line if hupcl is off */
|
||||
|
||||
/* cancel any scheduled reading */
|
||||
@@ -1797,7 +1787,7 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
|
||||
FTDI_SIO_SET_DATA_REQUEST,
|
||||
FTDI_SIO_SET_DATA_REQUEST_TYPE,
|
||||
urb_value , priv->interface,
|
||||
buf, 0, 100) < 0) {
|
||||
buf, 0, WDR_SHORT_TIMEOUT) < 0) {
|
||||
err("%s FAILED to set databits/stopbits/parity", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1812,25 +1802,14 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_
|
||||
err("%s error from disable flowcontrol urb", __FUNCTION__);
|
||||
}
|
||||
/* Drop RTS and DTR */
|
||||
if (set_dtr(port, LOW) < 0){
|
||||
err("%s Error from DTR LOW urb", __FUNCTION__);
|
||||
}
|
||||
if (set_rts(port, LOW) < 0){
|
||||
err("%s Error from RTS LOW urb", __FUNCTION__);
|
||||
}
|
||||
|
||||
clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
} else {
|
||||
/* set the baudrate determined before */
|
||||
if (change_speed(port)) {
|
||||
err("%s urb failed to set baurdrate", __FUNCTION__);
|
||||
}
|
||||
/* Ensure RTS and DTR are raised */
|
||||
else if (set_dtr(port, HIGH) < 0){
|
||||
err("%s Error from DTR HIGH urb", __FUNCTION__);
|
||||
}
|
||||
else if (set_rts(port, HIGH) < 0){
|
||||
err("%s Error from RTS HIGH urb", __FUNCTION__);
|
||||
}
|
||||
set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
|
||||
/* Set flow control */
|
||||
@@ -1942,35 +1921,8 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file)
|
||||
|
||||
static int ftdi_tiocmset(struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dbg("%s TIOCMSET", __FUNCTION__);
|
||||
if (set & TIOCM_DTR){
|
||||
if ((ret = set_dtr(port, HIGH)) < 0) {
|
||||
err("Urb to set DTR failed");
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
if (set & TIOCM_RTS) {
|
||||
if ((ret = set_rts(port, HIGH)) < 0){
|
||||
err("Urb to set RTS failed");
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
|
||||
if (clear & TIOCM_DTR){
|
||||
if ((ret = set_dtr(port, LOW)) < 0){
|
||||
err("Urb to unset DTR failed");
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
if (clear & TIOCM_RTS) {
|
||||
if ((ret = set_rts(port, LOW)) < 0){
|
||||
err("Urb to unset RTS failed");
|
||||
return(ret);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
return update_mctrl(port, set, clear);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -264,11 +264,25 @@
|
||||
#define MOBILITY_VID 0x1342
|
||||
#define MOBILITY_USB_SERIAL_PID 0x0202 /* EasiDock USB 200 serial */
|
||||
|
||||
/*
|
||||
* microHAM product IDs (http://www.microham.com).
|
||||
* Submitted by Justin Burket (KL1RL) <zorton@jtan.com>.
|
||||
*/
|
||||
#define FTDI_MHAM_Y6_PID 0xEEEA /* USB-Y6 interface */
|
||||
#define FTDI_MHAM_Y8_PID 0xEEEB /* USB-Y8 interface */
|
||||
|
||||
/*
|
||||
* Active Robots product ids.
|
||||
*/
|
||||
#define FTDI_ACTIVE_ROBOTS_PID 0xE548 /* USB comms board */
|
||||
|
||||
/*
|
||||
* Evolution Robotics products (http://www.evolution.com/).
|
||||
* Submitted by Shawn M. Lavelle.
|
||||
*/
|
||||
#define EVOLUTION_VID 0xDEEE /* Vendor ID */
|
||||
#define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */
|
||||
|
||||
/* Commands */
|
||||
#define FTDI_SIO_RESET 0 /* Reset the port */
|
||||
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
|
||||
|
@@ -12,14 +12,25 @@
|
||||
History:
|
||||
|
||||
2005-05-19 v0.1 Initial version, based on incomplete docs
|
||||
and analysis of misbehavior of the standard driver
|
||||
and analysis of misbehavior with the standard driver
|
||||
2005-05-20 v0.2 Extended the input buffer to avoid losing
|
||||
random 64-byte chunks of data
|
||||
2005-05-21 v0.3 implemented chars_in_buffer()
|
||||
turned on low_latency
|
||||
simplified the code somewhat
|
||||
2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load
|
||||
removed some dead code
|
||||
added sponsor notice
|
||||
coding style clean-up
|
||||
2005-06-20 v0.4.1 add missing braces :-/
|
||||
killed end-of-line whitespace
|
||||
2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
|
||||
|
||||
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
|
||||
|
||||
*/
|
||||
#define DRIVER_VERSION "v0.3"
|
||||
|
||||
#define DRIVER_VERSION "v0.4"
|
||||
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
|
||||
#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
|
||||
|
||||
@@ -44,7 +55,6 @@ static int option_write_room (struct usb_serial_port *port);
|
||||
|
||||
static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
|
||||
|
||||
|
||||
static int option_write (struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count);
|
||||
|
||||
@@ -60,14 +70,17 @@ static int option_tiocmset (struct usb_serial_port *port, struct file *file,
|
||||
static int option_send_setup (struct usb_serial_port *port);
|
||||
|
||||
/* Vendor and product IDs */
|
||||
#define OPTION_VENDOR_ID 0x0AF0
|
||||
#define OPTION_VENDOR_ID 0x0AF0
|
||||
|
||||
#define OPTION_PRODUCT_OLD 0x5000
|
||||
#define OPTION_PRODUCT_FUSION 0x6000
|
||||
#define OPTION_PRODUCT_FUSION2 0x6300
|
||||
|
||||
#define OPTION_PRODUCT_OLD 0x5000
|
||||
#define OPTION_PRODUCT_WLAN 0x6000
|
||||
|
||||
static struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
@@ -85,58 +98,62 @@ static struct usb_driver option_driver = {
|
||||
* recognizes separately, thus num_port=1.
|
||||
*/
|
||||
static struct usb_serial_device_type option_3port_device = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "Option 3-port card",
|
||||
.short_name = "option",
|
||||
.id_table = option_ids,
|
||||
.num_interrupt_in = NUM_DONT_CARE,
|
||||
.num_bulk_in = NUM_DONT_CARE,
|
||||
.num_bulk_out = NUM_DONT_CARE,
|
||||
.num_ports = 1, /* 3 */
|
||||
.open = option_open,
|
||||
.close = option_close,
|
||||
.write = option_write,
|
||||
.write_room = option_write_room,
|
||||
.chars_in_buffer = option_chars_in_buffer,
|
||||
.throttle = option_rx_throttle,
|
||||
.unthrottle = option_rx_unthrottle,
|
||||
.ioctl = option_ioctl,
|
||||
.set_termios = option_set_termios,
|
||||
.break_ctl = option_break_ctl,
|
||||
.tiocmget = option_tiocmget,
|
||||
.tiocmset = option_tiocmset,
|
||||
.attach = option_startup,
|
||||
.shutdown = option_shutdown,
|
||||
.read_int_callback = option_instat_callback,
|
||||
.owner = THIS_MODULE,
|
||||
.name = "Option 3G data card",
|
||||
.short_name = "option",
|
||||
.id_table = option_ids,
|
||||
.num_interrupt_in = NUM_DONT_CARE,
|
||||
.num_bulk_in = NUM_DONT_CARE,
|
||||
.num_bulk_out = NUM_DONT_CARE,
|
||||
.num_ports = 1, /* 3, but the card reports its ports separately */
|
||||
.open = option_open,
|
||||
.close = option_close,
|
||||
.write = option_write,
|
||||
.write_room = option_write_room,
|
||||
.chars_in_buffer = option_chars_in_buffer,
|
||||
.throttle = option_rx_throttle,
|
||||
.unthrottle = option_rx_unthrottle,
|
||||
.ioctl = option_ioctl,
|
||||
.set_termios = option_set_termios,
|
||||
.break_ctl = option_break_ctl,
|
||||
.tiocmget = option_tiocmget,
|
||||
.tiocmset = option_tiocmset,
|
||||
.attach = option_startup,
|
||||
.shutdown = option_shutdown,
|
||||
.read_int_callback = option_instat_callback,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_DEBUG
|
||||
static int debug;
|
||||
#else
|
||||
#define debug 0
|
||||
#endif
|
||||
|
||||
|
||||
/* per port private data */
|
||||
|
||||
#define N_IN_URB 4
|
||||
#define N_OUT_URB 1
|
||||
#define IN_BUFLEN 1024
|
||||
#define OUT_BUFLEN 1024
|
||||
#define N_IN_URB 4
|
||||
#define N_OUT_URB 1
|
||||
#define IN_BUFLEN 1024
|
||||
#define OUT_BUFLEN 128
|
||||
|
||||
struct option_port_private {
|
||||
/* Input endpoints and buffer for this port */
|
||||
struct urb *in_urbs[N_IN_URB];
|
||||
char in_buffer[N_IN_URB][IN_BUFLEN];
|
||||
struct urb *in_urbs[N_IN_URB];
|
||||
char in_buffer[N_IN_URB][IN_BUFLEN];
|
||||
/* Output endpoints and buffer for this port */
|
||||
struct urb *out_urbs[N_OUT_URB];
|
||||
char out_buffer[N_OUT_URB][OUT_BUFLEN];
|
||||
struct urb *out_urbs[N_OUT_URB];
|
||||
char out_buffer[N_OUT_URB][OUT_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;
|
||||
// int break_on;
|
||||
int rts_state; /* Handshaking pins (outputs) */
|
||||
int dtr_state;
|
||||
int cts_state; /* Handshaking pins (inputs) */
|
||||
int dsr_state;
|
||||
int dcd_state;
|
||||
int ri_state;
|
||||
|
||||
unsigned long tx_start_time[N_OUT_URB];
|
||||
unsigned long tx_start_time[N_OUT_URB];
|
||||
};
|
||||
|
||||
|
||||
@@ -190,13 +207,13 @@ static void
|
||||
option_break_ctl (struct usb_serial_port *port, int break_state)
|
||||
{
|
||||
/* Unfortunately, I don't know how to send a break */
|
||||
dbg("%s", __FUNCTION__);
|
||||
dbg("%s", __FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
option_set_termios (struct usb_serial_port *port,
|
||||
struct termios *old_termios)
|
||||
struct termios *old_termios)
|
||||
{
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
@@ -204,10 +221,10 @@ option_set_termios (struct usb_serial_port *port,
|
||||
}
|
||||
|
||||
static int
|
||||
option_tiocmget(struct usb_serial_port *port, struct file *file)
|
||||
option_tiocmget (struct usb_serial_port *port, struct file *file)
|
||||
{
|
||||
unsigned int value;
|
||||
struct option_port_private *portdata;
|
||||
unsigned int value;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
@@ -225,7 +242,7 @@ static int
|
||||
option_tiocmset (struct usb_serial_port *port, struct file *file,
|
||||
unsigned int set, unsigned int clear)
|
||||
{
|
||||
struct option_port_private *portdata;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
@@ -250,71 +267,50 @@ option_ioctl (struct usb_serial_port *port, struct file *file,
|
||||
|
||||
/* Write */
|
||||
static int
|
||||
option_write(struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count)
|
||||
option_write (struct usb_serial_port *port,
|
||||
const unsigned char *buf, int count)
|
||||
{
|
||||
struct option_port_private *portdata;
|
||||
int i;
|
||||
int left, todo;
|
||||
struct urb *this_urb = NULL; /* spurious */
|
||||
int err;
|
||||
struct option_port_private *portdata;
|
||||
int i;
|
||||
int left, todo;
|
||||
struct urb *this_urb = NULL; /* spurious */
|
||||
int err;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
dbg("%s: write (%d chars)", __FUNCTION__, count);
|
||||
|
||||
#if 0
|
||||
spin_lock(&port->lock);
|
||||
if (port->write_urb_busy) {
|
||||
spin_unlock(&port->lock);
|
||||
dbg("%s: already writing", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
port->write_urb_busy = 1;
|
||||
spin_unlock(&port->lock);
|
||||
#endif
|
||||
|
||||
i = 0;
|
||||
left = count;
|
||||
while (left>0) {
|
||||
for (i=0; left > 0 && i < N_OUT_URB; i++) {
|
||||
todo = left;
|
||||
if (todo > OUT_BUFLEN)
|
||||
todo = OUT_BUFLEN;
|
||||
|
||||
for (;i < N_OUT_URB; i++) {
|
||||
/* Check we have a valid urb/endpoint before we use it... */
|
||||
this_urb = portdata->out_urbs[i];
|
||||
if (this_urb->status != -EINPROGRESS)
|
||||
break;
|
||||
this_urb = portdata->out_urbs[i];
|
||||
if (this_urb->status == -EINPROGRESS) {
|
||||
if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
|
||||
continue;
|
||||
if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
|
||||
continue;
|
||||
this_urb->transfer_flags |= URB_ASYNC_UNLINK;
|
||||
usb_unlink_urb(this_urb);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == N_OUT_URB) {
|
||||
/* no bulk out free! */
|
||||
dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
|
||||
#if 0
|
||||
port->write_urb_busy = 0;
|
||||
#endif
|
||||
return count-left;
|
||||
}
|
||||
if (this_urb->status != 0)
|
||||
dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
|
||||
|
||||
dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
|
||||
|
||||
/* send the data */
|
||||
memcpy (this_urb->transfer_buffer, buf, todo);
|
||||
|
||||
/* send the data out the bulk port */
|
||||
this_urb->transfer_buffer_length = todo;
|
||||
|
||||
this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
||||
this_urb->dev = port->serial->dev;
|
||||
err = usb_submit_urb(this_urb, GFP_ATOMIC);
|
||||
if (err) {
|
||||
dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);
|
||||
dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
|
||||
continue;
|
||||
}
|
||||
portdata->tx_start_time[i] = jiffies;
|
||||
@@ -323,9 +319,6 @@ option_write(struct usb_serial_port *port,
|
||||
}
|
||||
|
||||
count -= left;
|
||||
#if 0
|
||||
port->write_urb_busy = 0;
|
||||
#endif
|
||||
dbg("%s: wrote (did %d)", __FUNCTION__, count);
|
||||
return count;
|
||||
}
|
||||
@@ -333,7 +326,7 @@ option_write(struct usb_serial_port *port,
|
||||
static void
|
||||
option_indat_callback (struct urb *urb, struct pt_regs *regs)
|
||||
{
|
||||
int i, err;
|
||||
int i, err;
|
||||
int endpoint;
|
||||
struct usb_serial_port *port;
|
||||
struct tty_struct *tty;
|
||||
@@ -444,10 +437,11 @@ option_write_room (struct usb_serial_port *port)
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
for (i=0; i < N_OUT_URB; i++)
|
||||
for (i=0; i < N_OUT_URB; i++) {
|
||||
this_urb = portdata->out_urbs[i];
|
||||
if (this_urb && this_urb->status != -EINPROGRESS)
|
||||
data_len += OUT_BUFLEN;
|
||||
}
|
||||
|
||||
dbg("%s: %d", __FUNCTION__, data_len);
|
||||
return data_len;
|
||||
@@ -464,11 +458,11 @@ option_chars_in_buffer (struct usb_serial_port *port)
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
for (i=0; i < N_OUT_URB; i++)
|
||||
for (i=0; i < N_OUT_URB; i++) {
|
||||
this_urb = portdata->out_urbs[i];
|
||||
if (this_urb && this_urb->status == -EINPROGRESS)
|
||||
data_len += this_urb->transfer_buffer_length;
|
||||
|
||||
}
|
||||
dbg("%s: %d", __FUNCTION__, data_len);
|
||||
return data_len;
|
||||
}
|
||||
@@ -477,10 +471,10 @@ option_chars_in_buffer (struct usb_serial_port *port)
|
||||
static int
|
||||
option_open (struct usb_serial_port *port, struct file *filp)
|
||||
{
|
||||
struct option_port_private *portdata;
|
||||
struct usb_serial *serial = port->serial;
|
||||
int i, err;
|
||||
struct urb *urb;
|
||||
struct option_port_private *portdata;
|
||||
struct usb_serial *serial = port->serial;
|
||||
int i, err;
|
||||
struct urb *urb;
|
||||
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
@@ -528,7 +522,7 @@ option_open (struct usb_serial_port *port, struct file *filp)
|
||||
}
|
||||
|
||||
static inline void
|
||||
stop_urb(struct urb *urb)
|
||||
stop_urb (struct urb *urb)
|
||||
{
|
||||
if (urb && urb->status == -EINPROGRESS) {
|
||||
urb->transfer_flags &= ~URB_ASYNC_UNLINK;
|
||||
@@ -537,11 +531,11 @@ stop_urb(struct urb *urb)
|
||||
}
|
||||
|
||||
static void
|
||||
option_close(struct usb_serial_port *port, struct file *filp)
|
||||
option_close (struct usb_serial_port *port, struct file *filp)
|
||||
{
|
||||
int i;
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct option_port_private *portdata;
|
||||
int i;
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
@@ -589,11 +583,11 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
|
||||
|
||||
/* Setup urbs */
|
||||
static void
|
||||
option_setup_urbs(struct usb_serial *serial)
|
||||
option_setup_urbs (struct usb_serial *serial)
|
||||
{
|
||||
int j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
int j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
@@ -617,7 +611,7 @@ option_setup_urbs(struct usb_serial *serial)
|
||||
|
||||
|
||||
static int
|
||||
option_send_setup(struct usb_serial_port *port)
|
||||
option_send_setup (struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct option_port_private *portdata;
|
||||
@@ -644,9 +638,9 @@ option_send_setup(struct usb_serial_port *port)
|
||||
static int
|
||||
option_startup (struct usb_serial *serial)
|
||||
{
|
||||
int i, err;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
int i, err;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
@@ -677,9 +671,9 @@ option_startup (struct usb_serial *serial)
|
||||
static void
|
||||
option_shutdown (struct usb_serial *serial)
|
||||
{
|
||||
int i, j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
int i, j;
|
||||
struct usb_serial_port *port;
|
||||
struct option_port_private *portdata;
|
||||
|
||||
dbg("%s", __FUNCTION__);
|
||||
|
||||
@@ -724,6 +718,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
|
||||
MODULE_VERSION(DRIVER_VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#ifdef CONFIG_USB_DEBUG
|
||||
module_param(debug, bool, S_IRUGO | S_IWUSR);
|
||||
MODULE_PARM_DESC(debug, "Debug messages");
|
||||
#endif
|
||||
|
||||
|
@@ -257,7 +257,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
|
||||
endpoint = &iface_desc->endpoint[i].desc;
|
||||
|
||||
if (!dev->bulk_in_endpointAddr &&
|
||||
(endpoint->bEndpointAddress & USB_DIR_IN) &&
|
||||
((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
||||
== USB_DIR_IN) &&
|
||||
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
|
||||
== USB_ENDPOINT_XFER_BULK)) {
|
||||
/* we found a bulk in endpoint */
|
||||
@@ -272,7 +273,8 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i
|
||||
}
|
||||
|
||||
if (!dev->bulk_out_endpointAddr &&
|
||||
!(endpoint->bEndpointAddress & USB_DIR_OUT) &&
|
||||
((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
|
||||
== USB_DIR_OUT) &&
|
||||
((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
|
||||
== USB_ENDPOINT_XFER_BULK)) {
|
||||
/* we found a bulk out endpoint */
|
||||
|
Reference in New Issue
Block a user