Commit 36644e22 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/linus-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents f6b765c0 8e791974
......@@ -19,9 +19,9 @@ your system. This library is available from
auerswald and shipped as part of the java software.
You may create the devices with:
mknod -m 666 /dev/usb/auer0 c 180 80
mknod -m 666 /dev/usb/auer0 c 180 112
...
mknod -m 666 /dev/usb/auer15 c 180 95
mknod -m 666 /dev/usb/auer15 c 180 127
Future plans
============
......
......@@ -95,12 +95,13 @@ HandSpring Visor, Palm USB, and Cli
Kroah-Hartman at greg@kroah.com
Compaq iPAQ driver
Compaq iPAQ and HP Jornada driver
This driver can be used to connect to Compaq iPAQ PDAs running
Windows CE 3.0 using a USB autosync cable. It has been tested only on
the Compaq H3135. It should work with the H3600 and later models too.
It may work with other CE based handhelds as well.
This driver can be used to connect to Compaq iPAQ and HP Jornada PDAs
running Windows CE 3.0 or PocketPC 2002 using a USB cable/cradle. It
has been tested only on the Compaq H3135, but is rumoured to work on
with the H3600 and later models as well as the Jornada 548 and 568.
With minor modifications, it may work for other CE based handhelds too.
The driver presents a serial interface (usually on /dev/ttyUSB0) over
which one may run ppp and establish a TCP/IP link to the iPAQ. Once this
......@@ -109,11 +110,14 @@ Compaq iPAQ driver
kbytes/sec for download/upload to the iPAQ.
The driver works intermittently with the usb-uhci driver but quite
reliably with the uhci driver. Make sure you have the right driver
loaded - usb-uhci is often the default.
reliably with the uhci driver. However, performance is much better
with usb-uhci. It does not seem to work with ohci at all.
You must setup hotplug to invoke pppd as soon as the iPAQ is connected.
A ppp script like the one below may be used:
A ppp script like the one below should be kept in the file
/etc/hotplug/usb/ipaq Remember to chmod +x. Make sure there are no
options in /etc/ppp/options or ~/.ppprc which conflict with the ones
given below.
#!/bin/bash
......@@ -133,7 +137,7 @@ Compaq iPAQ driver
On connecting the cable, you should see the usual "Device Connected",
"User Authenticated" messages flash by on your iPAQ. Once connected,
you can use Win CE programs like ftpView, Pocket Outlook from the iPAQ
and other synce utilities from the Linux side. Remember to enable IP
and xcerdisp, synce utilities from the Linux side. Remember to enable IP
forwarding.
To use Pocket IE, follow the instructions given at
......
......@@ -124,9 +124,7 @@
* conversions. We never do sample rate conversion; these are too
* expensive to be performed in the kernel.
*
* Current status:
* - Pretty stable on UHCI-Acher/Fliegl/Sailer
* - Does not work on OHCI due to lack of OHCI driver supporting URB's
* Current status: no known HCD-specific issues.
*
* Generally: Due to the brokenness of the Audio Class spec
* it seems generally impossible to write a generic Audio Class driver,
......@@ -298,12 +296,10 @@ struct usb_audio_state;
struct my_data_urb {
struct urb *urb;
struct usb_iso_packet_descriptor isoframe[DESCFRAMES];
};
struct my_sync_urb {
struct urb *urb;
struct usb_iso_packet_descriptor isoframe[SYNCFRAMES];
};
......@@ -2829,14 +2825,14 @@ static void usb_audio_parsestreaming(struct usb_audio_state *s, unsigned char *b
init_waitqueue_head(&as->usbin.dma.wait);
init_waitqueue_head(&as->usbout.dma.wait);
spin_lock_init(&as->lock);
as->usbin.durb[0].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbin.durb[1].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbin.surb[0].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbin.surb[1].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbout.durb[0].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbout.durb[1].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbout.surb[0].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbout.surb[1].urb = usb_alloc_urb(0, GFP_KERNEL);
as->usbin.durb[0].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
as->usbin.durb[1].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
as->usbin.surb[0].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
as->usbin.surb[1].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
as->usbout.durb[0].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
as->usbout.durb[1].urb = usb_alloc_urb (DESCFRAMES, GFP_KERNEL);
as->usbout.surb[0].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
as->usbout.surb[1].urb = usb_alloc_urb (SYNCFRAMES, GFP_KERNEL);
if ((!as->usbin.durb[0].urb) ||
(!as->usbin.durb[1].urb) ||
(!as->usbin.surb[0].urb) ||
......
......@@ -61,7 +61,7 @@ do { \
#define ID_AUERSWALD 0x09BF
#ifndef AUER_MINOR_BASE /* allow external override */
#define AUER_MINOR_BASE 80 /* auerswald driver minor number */
#define AUER_MINOR_BASE 112 /* auerswald driver minor number */
#endif
/* we can have up to this number of device plugged in at once */
......
......@@ -4,8 +4,6 @@
* (C) Copyright 1999,2000 Thomas Sailer <sailer@ife.ee.ethz.ch>. (proc file per device)
* (C) Copyright 1999 Deti Fliegl (new USB architecture)
*
* $id$
*
* 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
......@@ -61,6 +59,8 @@
#include <linux/usbdevice_fs.h>
#include <asm/uaccess.h>
#include "hcd.h"
#define MAX_TOPO_LEVEL 6
/* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
......@@ -429,6 +429,10 @@ static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes
* count = device count at this level
*/
/* If this is the root hub, display the bandwidth information */
/* FIXME high speed reserves 20% frametime for non-periodic,
* while full/low speed reserves only 10% ... so this is wrong
* for high speed busses. also, change how bandwidth is recorded.
*/
if (level == 0)
data_end += sprintf(data_end, format_bandwidth, bus->bandwidth_allocated,
FRAME_TIME_MAX_USECS_ALLOC,
......
This diff is collapsed.
/*
* Copyright (c) 2001 by David Brownell
*
* Copyright (c) 2001-2002 by David Brownell
*
* 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
......@@ -17,6 +17,8 @@
*/
#ifdef __KERNEL__
/*-------------------------------------------------------------------------*/
/*
......@@ -33,8 +35,8 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
/*
* housekeeping
*/
struct usb_bus *bus; /* hcd is-a bus */
struct list_head hcd_list;
struct usb_bus *bus; /* FIXME only use "self" */
struct usb_bus self; /* hcd is-a bus */
const char *bus_name;
......@@ -98,6 +100,19 @@ struct hcd_timeout { /* timeouts we allocate */
/*-------------------------------------------------------------------------*/
/*
* FIXME usb_operations should vanish or become hc_driver,
* when usb_bus and usb_hcd become the same thing.
*/
struct usb_operations {
int (*allocate)(struct usb_device *);
int (*deallocate)(struct usb_device *);
int (*get_frame_number) (struct usb_device *usb_dev);
int (*submit_urb) (struct urb *urb, int mem_flags);
int (*unlink_urb) (struct urb *urb);
};
/* each driver provides one of these, and hardware init support */
struct hc_driver {
......@@ -126,8 +141,6 @@ struct hc_driver {
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
// FIXME: rework generic-to-specific HCD linkage (specific contains generic)
/* memory lifecycle */
struct usb_hcd *(*hcd_alloc) (void);
void (*hcd_free) (struct usb_hcd *hcd);
......@@ -152,7 +165,8 @@ struct hc_driver {
extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb);
#ifdef CONFIG_PCI
struct pci_dev;
struct pci_device_id;
extern int usb_hcd_pci_probe (struct pci_dev *dev,
const struct pci_device_id *id);
extern void usb_hcd_pci_remove (struct pci_dev *dev);
......@@ -204,6 +218,59 @@ extern int usb_hcd_pci_resume (struct pci_dev *dev);
#define SetPortFeature (0x2300 | USB_REQ_SET_FEATURE)
/*-------------------------------------------------------------------------*/
/*
* Generic bandwidth allocation constants/support
*/
#define FRAME_TIME_USECS 1000L
#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
/* Trying not to use worst-case bit-stuffing
of (7/6 * 8 * bytecount) = 9.33 * bytecount */
/* bytecount = data payload byte count */
#define NS_TO_US(ns) ((ns + 500L) / 1000L)
/* convert & round nanoseconds to microseconds */
extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
int bustime, int isoc);
extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
int isoc);
/*
* Full/low speed bandwidth allocation constants/support.
*/
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
/* 4 full-speed bit times (est.) */
#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
/*-------------------------------------------------------------------------*/
extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
extern void usb_free_bus (struct usb_bus *);
extern void usb_register_bus (struct usb_bus *);
extern void usb_deregister_bus (struct usb_bus *);
extern int usb_register_root_hub (struct usb_device *usb_dev,
struct device *parent_dev);
/*-------------------------------------------------------------------------*/
/* exported only within usbcore */
extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock;
extern void usb_bus_get (struct usb_bus *bus);
extern void usb_bus_put (struct usb_bus *bus);
/*-------------------------------------------------------------------------*/
/* hub.h ... DeviceRemovable in 2.4.2-ac11, gone in 2.4.10 */
......@@ -217,3 +284,7 @@ extern int usb_hcd_pci_resume (struct pci_dev *dev);
#define RUN_CONTEXT (in_irq () ? "in_irq" \
: (in_interrupt () ? "in_interrupt" : "can sleep"))
#endif /* __KERNEL__ */
......@@ -44,6 +44,7 @@
#include <linux/usb.h>
#include "../hcd.h"
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
......
......@@ -18,8 +18,6 @@
/* this file is part of ehci-hcd.c */
#include <asm/byteorder.h>
/*-------------------------------------------------------------------------*/
/*
......
......@@ -18,8 +18,6 @@
/* this file is part of ehci-hcd.c */
#include <asm/byteorder.h>
/*-------------------------------------------------------------------------*/
/*
......
......@@ -18,8 +18,6 @@
/* this file is part of ehci-hcd.c */
#include <asm/byteorder.h>
/*-------------------------------------------------------------------------*/
/*
......
......@@ -20,8 +20,6 @@
/*-------------------------------------------------------------------------*/
#include "ehci.h"
/*
* EHCI scheduled transaction support: interrupt, iso, split iso
* These are called "periodic" transactions in the EHCI spec.
......@@ -395,6 +393,9 @@ static int intr_submit (
frame += period;
} while (frame < ehci->periodic_size);
/* update bandwidth utilization records (for usbfs) */
usb_claim_bandwidth (urb->dev, urb, usecs, 0);
/* maybe enable periodic schedule processing */
if (!ehci->periodic_urbs++) {
u32 cmd;
......
......@@ -8,8 +8,6 @@
* $Id: ohci-q.c,v 1.6 2002/01/19 00:23:15 dbrownell Exp $
*/
#include <asm/byteorder.h>
static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv)
{
int last = urb_priv->length - 1;
......
......@@ -1452,7 +1452,8 @@ static void hid_disconnect(struct usb_device *dev, void *ptr)
}
static struct usb_device_id hid_usb_ids [] = {
{ bInterfaceClass: USB_INTERFACE_CLASS_HID },
{ match_flags: USB_DEVICE_ID_MATCH_INT_CLASS,
bInterfaceClass: USB_INTERFACE_CLASS_HID },
{ } /* Terminating entry */
};
......
......@@ -40,9 +40,10 @@ CONFIG_USB_SERIAL_VISOR
module, say M here and read <file:Documentation/modules.txt>.
CONFIG_USB_SERIAL_IPAQ
Say Y here if you want to connect to your Compaq iPAQ running
Windows CE 3.0 using a USB autosync cable. For information on using
the driver, read <file:Documentation/usb/usb-serial.txt>.
Say Y here if you want to connect to your Compaq iPAQ or HP Jornada
548/568 running Windows CE 3.0 or PocketPC 2002 using a USB
cradle/cable. For information on using the driver,
read <file:Documentation/usb/usb-serial.txt>.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
......
......@@ -15,7 +15,7 @@ dep_tristate ' USB Digi International AccelePort USB Serial Driver' CONFIG_USB_
dep_tristate ' USB Empeg empeg-car Mark I/II Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EMPEG $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
dep_tristate ' USB FTDI Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_FTDI_SIO $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
dep_tristate ' USB Handspring Visor / Palm m50x / Sony Clie Driver' CONFIG_USB_SERIAL_VISOR $CONFIG_USB_SERIAL
dep_tristate ' USB Compaq iPAQ Driver' CONFIG_USB_SERIAL_IPAQ $CONFIG_USB_SERIAL
dep_tristate ' USB Compaq iPAQ / HP Jornada Driver' CONFIG_USB_SERIAL_IPAQ $CONFIG_USB_SERIAL
dep_tristate ' USB IR Dongle Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_IR $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
dep_tristate ' USB Inside Out Edgeport Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_EDGEPORT $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
dep_tristate ' USB Keyspan PDA Single Port Serial Driver (EXPERIMENTAL)' CONFIG_USB_SERIAL_KEYSPAN_PDA $CONFIG_USB_SERIAL $CONFIG_EXPERIMENTAL
......
......@@ -207,8 +207,6 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -230,8 +228,6 @@ static int belkin_sa_open (struct usb_serial_port *port, struct file *filp)
}
exit:
up (&port->sem);
return retval;
} /* belkin_sa_open */
......@@ -249,8 +245,6 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number);
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -262,8 +256,6 @@ static void belkin_sa_close (struct usb_serial_port *port, struct file *filp)
}
port->open_count = 0;
}
up (&port->sem);
} /* belkin_sa_close */
......
......@@ -151,8 +151,6 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -179,8 +177,6 @@ static int cyberjack_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - usb_submit_urb(int urb)");
}
up (&port->sem);
return result;
}
......@@ -188,8 +184,6 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
{
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -201,8 +195,6 @@ static void cyberjack_close (struct usb_serial_port *port, struct file *filp)
}
port->open_count = 0;
}
up (&port->sem);
}
static int cyberjack_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
......@@ -225,8 +217,6 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
return (0);
}
down (&port->sem);
if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
/* To much data for buffer. Reset buffer. */
priv->wrfilled=0;
......@@ -235,8 +225,9 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
/* Copy data */
if (from_user) {
if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count))
if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
return -EFAULT;
}
} else {
memcpy (priv->wrbuf+priv->wrfilled, buf, count);
}
......@@ -277,7 +268,6 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
/* Throw away data. No better idea what to do with it. */
priv->wrfilled=0;
priv->wrsent=0;
up (&port->sem);
return 0;
}
......@@ -292,7 +282,6 @@ static int cyberjack_write (struct usb_serial_port *port, int from_user, const u
}
}
up (&port->sem);
return (count);
}
......@@ -432,8 +421,6 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
return;
}
down (&port->sem);
dbg(__FUNCTION__ " - transmitting data (frame n)");
length = ((priv->wrfilled - priv->wrsent) > port->bulk_out_size) ?
......@@ -459,7 +446,6 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
/* Throw away data. No better idea what to do with it. */
priv->wrfilled=0;
priv->wrsent=0;
up (&port->sem);
queue_task(&port->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
return;
......@@ -477,7 +463,6 @@ static void cyberjack_write_bulk_callback (struct urb *urb)
priv->wrsent=0;
}
up (&port->sem);
queue_task(&port->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
return;
......
......@@ -157,8 +157,6 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -189,8 +187,6 @@ static int empeg_open (struct usb_serial_port *port, struct file *filp)
}
up (&port->sem);
return result;
}
......@@ -208,8 +204,6 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
if (!serial)
return;
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -220,8 +214,6 @@ static void empeg_close (struct usb_serial_port *port, struct file * filp)
port->open_count = 0;
}
up (&port->sem);
/* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
}
......@@ -462,15 +454,7 @@ static void empeg_read_bulk_callback (struct urb *urb)
static void empeg_throttle (struct usb_serial_port *port)
{
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
usb_unlink_urb (port->read_urb);
up (&port->sem);
return;
}
......@@ -480,8 +464,6 @@ static void empeg_unthrottle (struct usb_serial_port *port)
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
......@@ -489,10 +471,7 @@ static void empeg_unthrottle (struct usb_serial_port *port)
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
up (&port->sem);
return;
}
......
......@@ -319,8 +319,6 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__);
down (&port->sem);
++port->open_count;
if (port->open_count == 1){
......@@ -361,7 +359,6 @@ static int ftdi_sio_open (struct usb_serial_port *port, struct file *filp)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
}
up (&port->sem);
return result;
} /* ftdi_sio_open */
......@@ -374,7 +371,6 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
dbg( __FUNCTION__);
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -411,9 +407,6 @@ static void ftdi_sio_close (struct usb_serial_port *port, struct file *filp)
tty_hangup(port->tty);
}
}
up (&port->sem);
} /* ftdi_sio_close */
......@@ -447,8 +440,6 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user,
return (0);
}
down(&port->sem);
count += data_offset;
count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
......@@ -456,7 +447,6 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user,
if (from_user) {
if (copy_from_user(port->write_urb->transfer_buffer + data_offset,
buf, count - data_offset )){
up (&port->sem);
return -EFAULT;
}
} else {
......@@ -482,14 +472,11 @@ static int ftdi_sio_write (struct usb_serial_port *port, int from_user,
result = usb_submit_urb(port->write_urb, GFP_KERNEL);
if (result) {
err(__FUNCTION__ " - failed submitting write urb, error %d", result);
up (&port->sem);
return 0;
}
up (&port->sem);
dbg(__FUNCTION__ " write returning: %d", count - data_offset);
return (count - data_offset);
} /* ftdi_sio_write */
static void ftdi_sio_write_bulk_callback (struct urb *urb)
......
/*
* USB Compaq iPAQ driver
*
* Copyright (C) 2001
* Copyright (C) 2001 - 2002
* Ganesh Varadarajan <ganesh@veritas.com>
*
* This program is free software; you can redistribute it and/or modify
......@@ -9,6 +9,9 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* (25/2/2002) ganesh
* Added support for the HP Jornada 548 and 568. Completely untested.
* Thanks to info from Heath Robinson and Arieh Davidoff.
*/
#include <linux/config.h>
......@@ -39,9 +42,9 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.1"
#define DRIVER_VERSION "v0.2"
#define DRIVER_AUTHOR "Ganesh Varadarajan <ganesh@veritas.com>"
#define DRIVER_DESC "USB Compaq iPAQ driver"
#define DRIVER_DESC "USB Compaq iPAQ, HP Jornada driver"
/* Function prototypes for an ipaq */
static int ipaq_open (struct usb_serial_port *port, struct file *filp);
......@@ -61,7 +64,9 @@ static void ipaq_destroy_lists(struct usb_serial_port *port);
static __devinitdata struct usb_device_id ipaq_id_table [] = {
{ USB_DEVICE(IPAQ_VENDOR_ID, IPAQ_PRODUCT_ID) },
{ USB_DEVICE(COMPAQ_VENDOR_ID, COMPAQ_IPAQ_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_548_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_JORNADA_568_ID) },
{ } /* Terminating entry */
};
......@@ -72,7 +77,7 @@ struct usb_serial_device_type ipaq_device = {
owner: THIS_MODULE,
name: "Compaq iPAQ",
id_table: ipaq_id_table,
num_interrupt_in: 0,
num_interrupt_in: NUM_DONT_CARE,
num_bulk_in: 1,
num_bulk_out: 1,
num_ports: 1,
......@@ -104,8 +109,6 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__ " - port %d", port->number);
down(&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -193,8 +196,6 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
}
}
up(&port->sem);
return result;
enomem:
......@@ -219,8 +220,6 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp)
serial = get_usb_serial(port, __FUNCTION__);
if (!serial)
return;
down (&port->sem);
--port->open_count;
......@@ -238,8 +237,6 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp)
port->open_count = 0;
}
up (&port->sem);
/* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
}
......
/*
* USB Compaq iPAQ driver
*
* Copyright (C) 2001
* Copyright (C) 2001 - 2002
* Ganesh Varadarajan <ganesh@veritas.com>
*
* This program is free software; you can redistribute it and/or modify
......@@ -16,8 +16,12 @@
#define __LINUX_USB_SERIAL_IPAQ_H
#define IPAQ_VENDOR_ID 0x049f
#define IPAQ_PRODUCT_ID 0x0003
#define COMPAQ_VENDOR_ID 0x049f
#define COMPAQ_IPAQ_ID 0x0003
#define HP_VENDOR_ID 0x003f
#define HP_JORNADA_548_ID 0x1016
#define HP_JORNADA_568_ID 0x1116
/*
* Since we can't queue our bulk write urbs (don't know why - it just
......
......@@ -252,8 +252,6 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
dbg("%s - port %d", __FUNCTION__, port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -293,9 +291,6 @@ static int ir_open (struct usb_serial_port *port, struct file *filp)
if (result)
err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
}
up (&port->sem);
return result;
}
......@@ -312,8 +307,6 @@ static void ir_close (struct usb_serial_port *port, struct file * filp)
if (!serial)
return;
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -324,7 +317,6 @@ static void ir_close (struct usb_serial_port *port, struct file * filp)
port->open_count = 0;
}
up (&port->sem);
}
static int ir_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
......
......@@ -861,10 +861,8 @@ static int keyspan_open (struct usb_serial_port *port, struct file *filp)
dbg("keyspan_open called for port%d.\n", port->number);
down (&port->sem);
already_active = port->open_count;
++port->open_count;
up (&port->sem);
if (already_active)
return 0;
......@@ -926,8 +924,6 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
p_priv->out_flip = 0;
p_priv->in_flip = 0;
down (&port->sem);
if (--port->open_count <= 0) {
if (serial->dev) {
/* Stop reading/writing urbs */
......@@ -941,7 +937,6 @@ static void keyspan_close(struct usb_serial_port *port, struct file *filp)
port->open_count = 0;
port->tty = 0;
}
up (&port->sem);
}
......
......@@ -662,8 +662,6 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
int rc = 0;
struct keyspan_pda_private *priv;
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -707,12 +705,9 @@ static int keyspan_pda_open (struct usb_serial_port *port, struct file *filp)
}
up (&port->sem);
return rc;
error:
--port->open_count;
up (&port->sem);
return rc;
}
......@@ -721,8 +716,6 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
{
struct usb_serial *serial = port->serial;
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -737,8 +730,6 @@ static void keyspan_pda_close(struct usb_serial_port *port, struct file *filp)
}
port->open_count = 0;
}
up (&port->sem);
}
......
......@@ -358,8 +358,6 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -437,8 +435,6 @@ static int klsi_105_open (struct usb_serial_port *port, struct file *filp)
}
exit:
up (&port->sem);
return retval;
} /* klsi_105_open */
......@@ -455,8 +451,6 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
if(!serial)
return;
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -482,8 +476,6 @@ static void klsi_105_close (struct usb_serial_port *port, struct file *filp)
port->open_count = 0;
info("kl5kusb105 port stats: %ld bytes in, %ld bytes out", priv->bytes_in, priv->bytes_out);
}
up (&port->sem);
} /* klsi_105_close */
......@@ -505,9 +497,6 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user,
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem); /* to lock against someone else trying to
take an URB we just selected from the pool */
while (count > 0) {
/* try to find a free urb (write 0 bytes if none) */
struct urb *urb = NULL;
......@@ -543,7 +532,6 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user,
if (from_user) {
if (copy_from_user(urb->transfer_buffer
+ KLSI_105_DATA_OFFSET, buf, size)) {
up (&port->sem);
return -EFAULT;
}
} else {
......@@ -578,7 +566,6 @@ static int klsi_105_write (struct usb_serial_port *port, int from_user,
count -= size;
}
exit:
up (&port->sem);
priv->bytes_out+=bytes_sent;
return bytes_sent; /* that's how much we wrote */
......@@ -1021,34 +1008,21 @@ static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file,
static void klsi_105_throttle (struct usb_serial_port *port)
{
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
usb_unlink_urb (port->read_urb);
up (&port->sem);
return;
}
static void klsi_105_unthrottle (struct usb_serial_port *port)
{
int result;
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d",
result);
up (&port->sem);
return;
}
......
......@@ -341,8 +341,6 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -398,8 +396,6 @@ static int mct_u232_open (struct usb_serial_port *port, struct file *filp)
}
exit:
up (&port->sem);
return 0;
} /* mct_u232_open */
......@@ -408,8 +404,6 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
{
dbg(__FUNCTION__" port %d", port->number);
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -421,8 +415,6 @@ static void mct_u232_close (struct usb_serial_port *port, struct file *filp)
}
port->open_count = 0;
}
up (&port->sem);
} /* mct_u232_close */
......@@ -454,16 +446,12 @@ static int mct_u232_write (struct usb_serial_port *port, int from_user,
bytes_sent = 0;
while (count > 0) {
down (&port->sem);
size = (count > port->bulk_out_size) ? port->bulk_out_size : count;
usb_serial_debug_data (__FILE__, __FUNCTION__, size, buf);
if (from_user) {
if (copy_from_user(port->write_urb->transfer_buffer, buf, size)) {
up (&port->sem);
return -EFAULT;
}
}
......@@ -486,12 +474,9 @@ static int mct_u232_write (struct usb_serial_port *port, int from_user,
if (result) {
err(__FUNCTION__
" - failed submitting write urb, error %d", result);
up (&port->sem);
return result;
}
up (&port->sem);
bytes_sent += size;
if (write_blocking)
interruptible_sleep_on(&port->write_wait);
......
......@@ -157,8 +157,6 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
if (!serial)
return -ENODEV;
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -166,7 +164,6 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
if( !od ) {
err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
port->open_count = 0;
up (&port->sem);
return -ENOMEM;
}
......@@ -184,8 +181,6 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
}
up (&port->sem);
return result;
}
......@@ -204,8 +199,6 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
if (!serial)
return;
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -220,8 +213,6 @@ static void omninet_close (struct usb_serial_port *port, struct file * filp)
if (od)
kfree(od);
}
up (&port->sem);
}
......
......@@ -367,8 +367,6 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
dbg (__FUNCTION__ " - port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -407,7 +405,6 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
result = usb_submit_urb (port->read_urb, GFP_KERNEL);
if (result) {
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
up (&port->sem);
pl2303_close (port, NULL);
return -EPROTO;
}
......@@ -417,12 +414,10 @@ static int pl2303_open (struct usb_serial_port *port, struct file *filp)
result = usb_submit_urb (port->interrupt_in_urb, GFP_KERNEL);
if (result) {
err(__FUNCTION__ " - failed submitting interrupt urb, error %d", result);
up (&port->sem);
pl2303_close (port, NULL);
return -EPROTO;
}
}
up (&port->sem);
return 0;
}
......@@ -442,8 +437,6 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
dbg (__FUNCTION__ " - port %d", port->number);
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
if (serial->dev) {
......@@ -478,8 +471,6 @@ static void pl2303_close (struct usb_serial_port *port, struct file *filp)
}
port->open_count = 0;
}
up (&port->sem);
}
static int set_modem_info (struct usb_serial_port *port, unsigned int cmd, unsigned int *value)
......
This diff is collapsed.
......@@ -12,6 +12,15 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
* (02/27/2002) gkh
* Reworked the urb handling logic. We have no more pool, but dynamically
* allocate the urb and the transfer buffer on the fly. In testing this
* does not incure any measurable overhead. This also relies on the fact
* that we have proper reference counting logic for urbs.
*
* (02/21/2002) SilaS
* Added initial support for the Palm m515 devices.
*
* (02/14/2002) gkh
* Added support for the Clie S-360 device.
*
......@@ -134,7 +143,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v1.9"
#define DRIVER_VERSION "v2.0"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clié driver"
......@@ -158,6 +167,7 @@ static int clie_3_5_startup (struct usb_serial *serial);
static __devinitdata struct usb_device_id combined_id_table [] = {
{ 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_M125_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
......@@ -174,6 +184,7 @@ static __devinitdata struct usb_device_id id_table [] = {
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_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_M125_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
......@@ -233,12 +244,8 @@ static struct usb_serial_device_type clie_3_5_device = {
};
#define NUM_URBS 24
#define URB_TRANSFER_BUFFER_SIZE 768
static struct urb *write_urb_pool[NUM_URBS];
static spinlock_t write_urb_pool_lock;
static int bytes_in;
static int bytes_out;
static int bytes_in;
static int bytes_out;
/******************************************************************************
......@@ -259,8 +266,6 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
return -ENODEV;
}
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -284,8 +289,6 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
}
up (&port->sem);
return result;
}
......@@ -304,8 +307,6 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
if (!serial)
return;
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -329,8 +330,6 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
}
port->open_count = 0;
}
up (&port->sem);
/* Uncomment the following line if you want to see some statistics in your syslog */
/* info ("Bytes In = %d Bytes Out = %d", bytes_in, bytes_out); */
}
......@@ -340,120 +339,84 @@ static int visor_write (struct usb_serial_port *port, int from_user, const unsig
{
struct usb_serial *serial = port->serial;
struct urb *urb;
const unsigned char *current_position = buf;
unsigned long flags;
unsigned char *buffer;
int status;
int i;
int bytes_sent = 0;
int transfer_size;
dbg(__FUNCTION__ " - port %d", port->number);
while (count > 0) {
/* try to find a free urb in our list of them */
urb = NULL;
spin_lock_irqsave (&write_urb_pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
if (write_urb_pool[i]->status != -EINPROGRESS) {
urb = write_urb_pool[i];
break;
}
}
spin_unlock_irqrestore (&write_urb_pool_lock, flags);
if (urb == NULL) {
dbg (__FUNCTION__ " - no more free urbs");
goto exit;
}
if (urb->transfer_buffer == NULL) {
urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
if (urb->transfer_buffer == NULL) {
err(__FUNCTION__" no more kernel memory...");
goto exit;
}
}
transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
if (from_user) {
if (copy_from_user (urb->transfer_buffer, current_position, transfer_size)) {
bytes_sent = -EFAULT;
break;
}
} else {
memcpy (urb->transfer_buffer, current_position, transfer_size);
}
buffer = kmalloc (count, GFP_KERNEL);
if (!buffer) {
err ("out of memory");
return -ENOMEM;
}
usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, urb->transfer_buffer);
/* build up our urb */
usb_fill_bulk_urb (urb, serial->dev,
usb_sndbulkpipe (serial->dev,
port->bulk_out_endpointAddress),
urb->transfer_buffer, transfer_size,
visor_write_bulk_callback, port);
urb->transfer_flags |= USB_QUEUE_BULK;
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_KERNEL);
if (status) {
err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
bytes_sent = status;
break;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
err ("no more free urbs");
kfree (buffer);
return -ENOMEM;
}
if (from_user) {
if (copy_from_user (buffer, buf, count)) {
kfree (buffer);
usb_free_urb (urb);
return -EFAULT;
}
} else {
memcpy (buffer, buf, count);
}
usb_serial_debug_data (__FILE__, __FUNCTION__, count, buffer);
current_position += transfer_size;
bytes_sent += transfer_size;
count -= transfer_size;
bytes_out += transfer_size;
usb_fill_bulk_urb (urb, serial->dev,
usb_sndbulkpipe (serial->dev,
port->bulk_out_endpointAddress),
buffer, count,
visor_write_bulk_callback, port);
urb->transfer_flags |= USB_QUEUE_BULK;
/* send it down the pipe */
status = usb_submit_urb(urb, GFP_KERNEL);
if (status) {
err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status);
count = status;
} else {
bytes_out += count;
}
exit:
return bytes_sent;
/* we are done with this urb, so let the host driver
* really free it when it is finished with it */
usb_free_urb (urb);
return count;
}
static int visor_write_room (struct usb_serial_port *port)
{
unsigned long flags;
int i;
int room = 0;
dbg(__FUNCTION__ " - port %d", port->number);
spin_lock_irqsave (&write_urb_pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
if (write_urb_pool[i]->status != -EINPROGRESS) {
room += URB_TRANSFER_BUFFER_SIZE;
}
}
spin_unlock_irqrestore (&write_urb_pool_lock, flags);
dbg(__FUNCTION__ " - returns %d", room);
return (room);
/*
* We really can take anything the user throws at us
* but let's pick a nice big number to tell the tty
* layer that we have lots of free space
*/
return 2048;
}
static int visor_chars_in_buffer (struct usb_serial_port *port)
{
unsigned long flags;
int i;
int chars = 0;
dbg(__FUNCTION__ " - port %d", port->number);
spin_lock_irqsave (&write_urb_pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
if (write_urb_pool[i]->status == -EINPROGRESS) {
chars += URB_TRANSFER_BUFFER_SIZE;
}
}
spin_unlock_irqrestore (&write_urb_pool_lock, flags);
dbg (__FUNCTION__ " - returns %d", chars);
return (chars);
/*
* We can't really account for how much data we
* have sent out, but hasn't made it through to the
* device, so just tell the tty layer that everything
* is flushed.
*/
return 0;
}
......@@ -471,9 +434,12 @@ static void visor_write_bulk_callback (struct urb *urb)
return;
}
/* free up the transfer buffer, as usb_free_urb() does not do this */
kfree (urb->transfer_buffer);
queue_task(&port->tqueue, &tq_immediate);
mark_bh(IMMEDIATE_BH);
return;
}
......@@ -534,16 +500,8 @@ static void visor_read_bulk_callback (struct urb *urb)
static void visor_throttle (struct usb_serial_port *port)
{
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
usb_unlink_urb (port->read_urb);
up (&port->sem);
return;
}
......@@ -553,16 +511,10 @@ static void visor_unthrottle (struct usb_serial_port *port)
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
port->read_urb->dev = port->serial->dev;
result = usb_submit_urb(port->read_urb, GFP_KERNEL);
if (result)
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
up (&port->sem);
return;
}
......@@ -783,30 +735,8 @@ static void visor_set_termios (struct usb_serial_port *port, struct termios *old
static int __init visor_init (void)
{
struct urb *urb;
int i;
usb_serial_register (&handspring_device);
usb_serial_register (&clie_3_5_device);
/* create our write urb pool and transfer buffers */
spin_lock_init (&write_urb_pool_lock);
for (i = 0; i < NUM_URBS; ++i) {
urb = usb_alloc_urb(0, GFP_KERNEL);
write_urb_pool[i] = urb;
if (urb == NULL) {
err("No more urbs???");
continue;
}
urb->transfer_buffer = NULL;
urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
if (!urb->transfer_buffer) {
err (__FUNCTION__ " - out of memory for urb buffers.");
continue;
}
}
info(DRIVER_DESC " " DRIVER_VERSION);
return 0;
......@@ -815,27 +745,8 @@ static int __init visor_init (void)
static void __exit visor_exit (void)
{
int i;
unsigned long flags;
usb_serial_deregister (&handspring_device);
usb_serial_deregister (&clie_3_5_device);
spin_lock_irqsave (&write_urb_pool_lock, flags);
for (i = 0; i < NUM_URBS; ++i) {
if (write_urb_pool[i]) {
/* FIXME - uncomment the following usb_unlink_urb call when
* the host controllers get fixed to set urb->dev = NULL after
* the urb is finished. Otherwise this call oopses. */
/* usb_unlink_urb(write_urb_pool[i]); */
if (write_urb_pool[i]->transfer_buffer)
kfree(write_urb_pool[i]->transfer_buffer);
usb_free_urb (write_urb_pool[i]);
}
}
spin_unlock_irqrestore (&write_urb_pool_lock, flags);
}
......
......@@ -23,6 +23,7 @@
#define PALM_VENDOR_ID 0x0830
#define PALM_M500_ID 0x0001
#define PALM_M505_ID 0x0002
#define PALM_M515_ID 0x0003
#define PALM_M125_ID 0x0040
#define SONY_VENDOR_ID 0x054C
......
......@@ -306,8 +306,6 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
dbg(__FUNCTION__" - port %d", port->number);
down (&port->sem);
++port->open_count;
if (port->open_count == 1) {
......@@ -354,16 +352,12 @@ static int whiteheat_open (struct usb_serial_port *port, struct file *filp)
}
dbg(__FUNCTION__ " - exit");
up (&port->sem);
return retval;
error_exit:
--port->open_count;
dbg(__FUNCTION__ " - error_exit");
up (&port->sem);
return retval;
}
......@@ -374,7 +368,6 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
dbg(__FUNCTION__ " - port %d", port->number);
down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
......@@ -391,7 +384,6 @@ static void whiteheat_close(struct usb_serial_port *port, struct file * filp)
usb_unlink_urb (port->read_urb);
port->open_count = 0;
}
up (&port->sem);
}
......@@ -410,8 +402,6 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios
dbg(__FUNCTION__ " -port %d", port->number);
down (&port->sem);
if ((!port->tty) || (!port->tty->termios)) {
dbg(__FUNCTION__" - no tty structures");
goto exit;
......@@ -492,7 +482,6 @@ static void whiteheat_set_termios (struct usb_serial_port *port, struct termios
whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
exit:
up (&port->sem);
return;
}
......
......@@ -53,11 +53,11 @@
#include <asm/irq.h>
#include <asm/system.h>
#include "hcd.h"
#include "uhci.h"
#include <linux/pm.h>
/*
* Version Information
*/
......@@ -65,7 +65,6 @@
#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber"
#define DRIVER_DESC "USB Universal Host Controller Interface driver"
/*
* debug = 0, no debugging messages
* debug = 1, dump failed URB's except for stalls
......@@ -100,6 +99,7 @@ static void wakeup_hc(struct uhci *uhci);
/* If a transfer is still active after this much time, turn off FSBR */
#define IDLE_TIMEOUT (HZ / 20) /* 50 ms */
#define FSBR_DELAY (HZ / 20) /* 50 ms */
#define MAX_URB_LOOP 2048 /* Maximum number of linked URB's */
......@@ -766,7 +766,7 @@ static void uhci_dec_fsbr(struct uhci *uhci, struct urb *urb)
if ((!(urb->transfer_flags & USB_NO_FSBR)) && urbp->fsbr) {
urbp->fsbr = 0;
if (!--uhci->fsbr)
uhci->skel_term_qh->link = UHCI_PTR_TERM;
uhci->fsbrtimeout = jiffies + FSBR_DELAY;
}
spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
......@@ -2031,6 +2031,12 @@ static void rh_int_timer_do(unsigned long ptr)
uhci_unlink_urb(u);
}
/* Really disable FSBR */
if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) {
uhci->fsbrtimeout = 0;
uhci->skel_term_qh->link = UHCI_PTR_TERM;
}
/* enter global suspend if nothing connected */
if (!uhci->is_suspended && !ports_active(uhci))
suspend_hc(uhci);
......
......@@ -309,6 +309,7 @@ struct uhci {
spinlock_t frame_list_lock;
struct uhci_frame_list *fl; /* P: uhci->frame_list_lock */
int fsbr; /* Full speed bandwidth reclamation */
unsigned long fsbrtimeout; /* FSBR delay */
int is_suspended;
/* Main list of URB's currently controlled by this HC */
......
......@@ -73,6 +73,7 @@
#define OHCI_USE_NPS // force NoPowerSwitching mode
// #define OHCI_VERBOSE_DEBUG /* not always helpful */
#include "hcd.h"
#include "usb-ohci.h"
......
......@@ -57,6 +57,7 @@
#define VERSTR "$Revision: 1.275 $ time " __TIME__ " " __DATE__
#include <linux/usb.h>
#include "hcd.h"
#include "usb-uhci.h"
#include "usb-uhci-debug.h"
......
This diff is collapsed.
......@@ -44,8 +44,8 @@
/*
* USB directions
*/
#define USB_DIR_OUT 0
#define USB_DIR_IN 0x80
#define USB_DIR_OUT 0 /* to device */
#define USB_DIR_IN 0x80 /* to host */
/*
* Endpoints
......@@ -148,12 +148,6 @@ struct usb_devmap {
unsigned long devicemap[128 / (8*sizeof(unsigned long))];
};
#define USB_MAXBUS 64
struct usb_busmap {
unsigned long busmap[USB_MAXBUS / (8*sizeof(unsigned long))];
};
struct usb_device;
/*-------------------------------------------------------------------------*/
......@@ -516,7 +510,8 @@ struct usb_device_id {
* work to connect to a device should be done when the device is opened,
* and undone at the last close. The disconnect code needs to address
* concurrency issues with respect to open() and close() methods, as
* well as cancel any I/O requests that are still pending.
* well as forcing all pending I/O requests to complete (by unlinking
* them as necessary, and blocking until the unlinks complete).
*/
struct usb_driver {
struct module *owner;
......@@ -905,13 +900,7 @@ extern int usb_make_path(struct usb_device *dev, char *buf, size_t size);
/* Host Controller Driver (HCD) support */
struct usb_operations {
int (*allocate)(struct usb_device *);
int (*deallocate)(struct usb_device *);
int (*get_frame_number) (struct usb_device *usb_dev);
int (*submit_urb) (struct urb *urb, int mem_flags);
int (*unlink_urb) (struct urb *urb);
};
struct usb_operations;
#define DEVNUM_ROUND_ROBIN /***** OPTION *****/
......@@ -944,40 +933,11 @@ struct usb_bus {
atomic_t refcnt;
};
extern struct usb_bus *usb_alloc_bus(struct usb_operations *);
extern void usb_free_bus(struct usb_bus *);
extern void usb_register_bus(struct usb_bus *);
extern void usb_deregister_bus(struct usb_bus *);
extern int usb_register_root_hub(struct usb_device *usb_dev, struct device *parent_dev);
extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
int bustime, int isoc);
extern void usb_release_bandwidth(struct usb_device *dev, struct urb *urb,
int isoc);
// FIXME: root_hub_string vanishes when "usb_hcd" conversion is done,
// along with pre-hcd versions of the OHCI and UHCI drivers.
extern int usb_root_hub_string(int id, int serial,
char *type, __u8 *data, int len);
/*
* Some USB 1.1 bandwidth allocation constants.
*/
#define BW_HOST_DELAY 1000L /* nanoseconds */
#define BW_HUB_LS_SETUP 333L /* nanoseconds */
/* 4 full-speed bit times (est.) */
#define FRAME_TIME_BITS 12000L /* frame = 1 millisecond */
#define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L)
#define FRAME_TIME_USECS 1000L
#define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L)
#define BitTime(bytecount) (7 * 8 * bytecount / 6) /* with integer truncation */
/* Trying not to use worst-case bit-stuffing
of (7/6 * 8 * bytecount) = 9.33 * bytecount */
/* bytecount = data payload byte count */
#define NS_TO_US(ns) ((ns + 500L) / 1000L)
/* convert & round nanoseconds to microseconds */
/*
* As of USB 2.0, full/low speed devices are segregated into trees.
* One type grows from USB 1.1 host controllers (OHCI, UHCI etc).
......@@ -1209,13 +1169,11 @@ void usb_show_string(struct usb_device *dev, char *id, int index);
/* -------------------------------------------------------------------------- */
/*
* bus and driver list
* driver list
* exported only for usbfs (not visible outside usbcore)
*/
extern struct list_head usb_driver_list;
extern struct list_head usb_bus_list;
extern struct semaphore usb_bus_list_lock;
/*
* USB device fs stuff
......
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