Commit a68d5b4c 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 4de460b9 023c5be4
...@@ -23,7 +23,7 @@ and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files. ...@@ -23,7 +23,7 @@ and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files.
to interact with USB devices. to interact with USB devices.
There are a number of mount options supported by usbfs. There are a number of mount options supported by usbfs.
Consult the source code (linux/drivers/usb/inode.c) for Consult the source code (linux/drivers/usb/core/inode.c) for
information about those options. information about those options.
**NOTE**: The filesystem has been renamed from "usbdevfs" to **NOTE**: The filesystem has been renamed from "usbdevfs" to
......
...@@ -27,8 +27,8 @@ config USB_BLUETOOTH_TTY ...@@ -27,8 +27,8 @@ config USB_BLUETOOTH_TTY
device that can be used only by specialized Bluetooth HCI software. device that can be used only by specialized Bluetooth HCI software.
Say Y here if you want to use OpenBT Bluetooth stack (available Say Y here if you want to use OpenBT Bluetooth stack (available
at <http://developer.axis.com/software/index.shtml>), or other TTY at <http://developer.axis.com/software>), or other TTY based
based Bluetooth stacks, and want to connect a USB Bluetooth device Bluetooth stacks, and want to connect a USB Bluetooth device
to your computer's USB port. to your computer's USB port.
Do *not* enable this driver if you want to use generic Linux Do *not* enable this driver if you want to use generic Linux
......
...@@ -1420,7 +1420,7 @@ static int usbout_start(struct usb_audiodev *as) ...@@ -1420,7 +1420,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->number_of_packets = DESCFRAMES; urb->number_of_packets = DESCFRAMES;
urb->context = as; urb->context = as;
urb->complete = usbout_completed; urb->complete = usbout_completed;
if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
u->flags |= FLG_URB0RUNNING; u->flags |= FLG_URB0RUNNING;
else else
u->flags &= ~FLG_RUNNING; u->flags &= ~FLG_RUNNING;
...@@ -1433,7 +1433,7 @@ static int usbout_start(struct usb_audiodev *as) ...@@ -1433,7 +1433,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->number_of_packets = DESCFRAMES; urb->number_of_packets = DESCFRAMES;
urb->context = as; urb->context = as;
urb->complete = usbout_completed; urb->complete = usbout_completed;
if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) if (!usbout_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
u->flags |= FLG_URB1RUNNING; u->flags |= FLG_URB1RUNNING;
else else
u->flags &= ~FLG_RUNNING; u->flags &= ~FLG_RUNNING;
...@@ -1448,7 +1448,7 @@ static int usbout_start(struct usb_audiodev *as) ...@@ -1448,7 +1448,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->context = as; urb->context = as;
urb->complete = usbout_sync_completed; urb->complete = usbout_sync_completed;
/* stride: u->syncinterval */ /* stride: u->syncinterval */
if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
u->flags |= FLG_SYNC0RUNNING; u->flags |= FLG_SYNC0RUNNING;
else else
u->flags &= ~FLG_RUNNING; u->flags &= ~FLG_RUNNING;
...@@ -1462,7 +1462,7 @@ static int usbout_start(struct usb_audiodev *as) ...@@ -1462,7 +1462,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->context = as; urb->context = as;
urb->complete = usbout_sync_completed; urb->complete = usbout_sync_completed;
/* stride: u->syncinterval */ /* stride: u->syncinterval */
if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_KERNEL)) if (!usbout_sync_prepare_desc(u, urb) && !usb_submit_urb(urb, GFP_ATOMIC))
u->flags |= FLG_SYNC1RUNNING; u->flags |= FLG_SYNC1RUNNING;
else else
u->flags &= ~FLG_RUNNING; u->flags &= ~FLG_RUNNING;
......
...@@ -337,7 +337,8 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len ...@@ -337,7 +337,8 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
if (status) { if (status) {
printk(KERN_ERR "usbmidi: Cannot submit urb (%d)\n",status); printk(KERN_ERR "usbmidi: Cannot submit urb (%d)\n",status);
ret = -EFAULT; ret = -EIO;
goto error;
} }
add_wait_queue( &ep->wait, &wait ); add_wait_queue( &ep->wait, &wait );
...@@ -354,6 +355,7 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len ...@@ -354,6 +355,7 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
set_current_state( TASK_RUNNING ); set_current_state( TASK_RUNNING );
remove_wait_queue( &ep->wait, &wait ); remove_wait_queue( &ep->wait, &wait );
error:
return ret; return ret;
} }
...@@ -369,7 +371,6 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs) ...@@ -369,7 +371,6 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
struct midi_in_endpoint *ep = (struct midi_in_endpoint *)(urb->context); struct midi_in_endpoint *ep = (struct midi_in_endpoint *)(urb->context);
unsigned char *data = urb->transfer_buffer; unsigned char *data = urb->transfer_buffer;
int i, j, wake; int i, j, wake;
unsigned long int flags;
if ( !ep->urbSubmitted ) { if ( !ep->urbSubmitted ) {
return; return;
...@@ -377,7 +378,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs) ...@@ -377,7 +378,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
if ( (urb->status == 0) && (urb->actual_length > 0) ) { if ( (urb->status == 0) && (urb->actual_length > 0) ) {
wake = 0; wake = 0;
spin_lock_irqsave( &ep->lock, flags ); spin_lock( &ep->lock );
for(j = 0; j < urb->actual_length; j += 4) { for(j = 0; j < urb->actual_length; j += 4) {
int cin = (data[j]>>0)&0xf; int cin = (data[j]>>0)&0xf;
...@@ -397,7 +398,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs) ...@@ -397,7 +398,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
} }
} }
spin_unlock_irqrestore( &ep->lock, flags ); spin_unlock ( &ep->lock );
if ( wake ) { if ( wake ) {
wake_up( &ep->wait ); wake_up( &ep->wait );
} }
...@@ -407,7 +408,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs) ...@@ -407,7 +408,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
urb->dev = ep->usbdev; urb->dev = ep->usbdev;
urb->actual_length = 0; urb->actual_length = 0;
usb_submit_urb(urb, GFP_KERNEL); usb_submit_urb(urb, GFP_ATOMIC);
} }
...@@ -855,7 +856,6 @@ static int usb_midi_open(struct inode *inode, struct file *file) ...@@ -855,7 +856,6 @@ static int usb_midi_open(struct inode *inode, struct file *file)
add_wait_queue( &open_wait, &wait ); add_wait_queue( &open_wait, &wait );
up(&open_sem); up(&open_sem);
schedule(); schedule();
__set_current_state(TASK_RUNNING);
remove_wait_queue( &open_wait, &wait ); remove_wait_queue( &open_wait, &wait );
if ( signal_pending(current) ) { if ( signal_pending(current) ) {
return -ERESTARTSYS; return -ERESTARTSYS;
......
...@@ -325,7 +325,7 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep) ...@@ -325,7 +325,7 @@ static void qh_lines (struct ehci_qh *qh, char **nextp, unsigned *sizep)
} }
static ssize_t static ssize_t
show_async (struct device *dev, char *buf, size_t count, loff_t off) show_async (struct device *dev, char *buf)
{ {
struct pci_dev *pdev; struct pci_dev *pdev;
struct ehci_hcd *ehci; struct ehci_hcd *ehci;
...@@ -334,13 +334,10 @@ show_async (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -334,13 +334,10 @@ show_async (struct device *dev, char *buf, size_t count, loff_t off)
char *next; char *next;
struct ehci_qh *qh; struct ehci_qh *qh;
if (off != 0)
return 0;
pdev = container_of (dev, struct pci_dev, dev); pdev = container_of (dev, struct pci_dev, dev);
ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
next = buf; next = buf;
size = count; size = PAGE_SIZE;
/* dumps a snapshot of the async schedule. /* dumps a snapshot of the async schedule.
* usually empty except for long-term bulk reads, or head. * usually empty except for long-term bulk reads, or head.
...@@ -358,14 +355,14 @@ show_async (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -358,14 +355,14 @@ show_async (struct device *dev, char *buf, size_t count, loff_t off)
} }
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
return count - size; return PAGE_SIZE - size;
} }
static DEVICE_ATTR (async, S_IRUGO, show_async, NULL); static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
#define DBG_SCHED_LIMIT 64 #define DBG_SCHED_LIMIT 64
static ssize_t static ssize_t
show_periodic (struct device *dev, char *buf, size_t count, loff_t off) show_periodic (struct device *dev, char *buf)
{ {
struct pci_dev *pdev; struct pci_dev *pdev;
struct ehci_hcd *ehci; struct ehci_hcd *ehci;
...@@ -375,8 +372,6 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -375,8 +372,6 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
char *next; char *next;
unsigned i, tag; unsigned i, tag;
if (off != 0)
return 0;
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC))) if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
return 0; return 0;
seen_count = 0; seen_count = 0;
...@@ -384,7 +379,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -384,7 +379,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
pdev = container_of (dev, struct pci_dev, dev); pdev = container_of (dev, struct pci_dev, dev);
ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
next = buf; next = buf;
size = count; size = PAGE_SIZE;
temp = snprintf (next, size, "size = %d\n", ehci->periodic_size); temp = snprintf (next, size, "size = %d\n", ehci->periodic_size);
size -= temp; size -= temp;
...@@ -468,14 +463,14 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -468,14 +463,14 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
kfree (seen); kfree (seen);
return count - size; return PAGE_SIZE - size;
} }
static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL); static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
#undef DBG_SCHED_LIMIT #undef DBG_SCHED_LIMIT
static ssize_t static ssize_t
show_registers (struct device *dev, char *buf, size_t count, loff_t off) show_registers (struct device *dev, char *buf)
{ {
struct pci_dev *pdev; struct pci_dev *pdev;
struct ehci_hcd *ehci; struct ehci_hcd *ehci;
...@@ -485,14 +480,11 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -485,14 +480,11 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off)
static char fmt [] = "%*s\n"; static char fmt [] = "%*s\n";
static char label [] = ""; static char label [] = "";
if (off != 0)
return 0;
pdev = container_of (dev, struct pci_dev, dev); pdev = container_of (dev, struct pci_dev, dev);
ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd); ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
next = buf; next = buf;
size = count; size = PAGE_SIZE;
spin_lock_irqsave (&ehci->lock, flags); spin_lock_irqsave (&ehci->lock, flags);
...@@ -568,7 +560,7 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -568,7 +560,7 @@ show_registers (struct device *dev, char *buf, size_t count, loff_t off)
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
return count - size; return PAGE_SIZE - size;
} }
static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
......
...@@ -396,24 +396,21 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) ...@@ -396,24 +396,21 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
} }
static ssize_t static ssize_t
show_async (struct device *dev, char *buf, size_t count, loff_t off) show_async (struct device *dev, char *buf)
{ {
struct ohci_hcd *ohci; struct ohci_hcd *ohci;
size_t temp; size_t temp;
unsigned long flags; unsigned long flags;
if (off != 0)
return 0;
ohci = dev_to_ohci(dev); ohci = dev_to_ohci(dev);
/* display control and bulk lists together, for simplicity */ /* display control and bulk lists together, for simplicity */
spin_lock_irqsave (&ohci->lock, flags); spin_lock_irqsave (&ohci->lock, flags);
temp = show_list (ohci, buf, count, ohci->ed_controltail); temp = show_list (ohci, buf, PAGE_SIZE, ohci->ed_controltail);
count = show_list (ohci, buf + temp, count - temp, ohci->ed_bulktail); temp += show_list (ohci, buf + temp, PAGE_SIZE - temp, ohci->ed_bulktail);
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irqrestore (&ohci->lock, flags);
return temp + count; return temp;
} }
static DEVICE_ATTR (async, S_IRUGO, show_async, NULL); static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
...@@ -421,7 +418,7 @@ static DEVICE_ATTR (async, S_IRUGO, show_async, NULL); ...@@ -421,7 +418,7 @@ static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
#define DBG_SCHED_LIMIT 64 #define DBG_SCHED_LIMIT 64
static ssize_t static ssize_t
show_periodic (struct device *dev, char *buf, size_t count, loff_t off) show_periodic (struct device *dev, char *buf)
{ {
struct ohci_hcd *ohci; struct ohci_hcd *ohci;
struct ed **seen, *ed; struct ed **seen, *ed;
...@@ -430,15 +427,13 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -430,15 +427,13 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
char *next; char *next;
unsigned i; unsigned i;
if (off != 0)
return 0;
if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC))) if (!(seen = kmalloc (DBG_SCHED_LIMIT * sizeof *seen, SLAB_ATOMIC)))
return 0; return 0;
seen_count = 0; seen_count = 0;
ohci = dev_to_ohci(dev); ohci = dev_to_ohci(dev);
next = buf; next = buf;
size = count; size = PAGE_SIZE;
temp = snprintf (next, size, "size = %d\n", NUM_INTS); temp = snprintf (next, size, "size = %d\n", NUM_INTS);
size -= temp; size -= temp;
...@@ -506,10 +501,11 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -506,10 +501,11 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
spin_unlock_irqrestore (&ohci->lock, flags); spin_unlock_irqrestore (&ohci->lock, flags);
kfree (seen); kfree (seen);
return count - size; return PAGE_SIZE - size;
} }
static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL); static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
#undef DBG_SCHED_LIMIT #undef DBG_SCHED_LIMIT
static inline void create_debug_files (struct ohci_hcd *bus) static inline void create_debug_files (struct ohci_hcd *bus)
......
...@@ -200,8 +200,10 @@ static int xpad_open (struct input_dev *dev) ...@@ -200,8 +200,10 @@ static int xpad_open (struct input_dev *dev)
return 0; return 0;
xpad->irq_in->dev = xpad->udev; xpad->irq_in->dev = xpad->udev;
if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) if (usb_submit_urb(xpad->irq_in, GFP_KERNEL)) {
xpad->open_count--;
return -EIO; return -EIO;
}
return 0; return 0;
} }
......
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/atm.h> #include <linux/atm.h>
#include <linux/atmdev.h> #include <linux/atmdev.h>
...@@ -87,7 +88,6 @@ ...@@ -87,7 +88,6 @@
#define SPEEDTOUCH_VENDORID 0x06b9 #define SPEEDTOUCH_VENDORID 0x06b9
#define SPEEDTOUCH_PRODUCTID 0x4061 #define SPEEDTOUCH_PRODUCTID 0x4061
#define MAX_UDSL 1
#define UDSL_OBUF_SIZE 32768 #define UDSL_OBUF_SIZE 32768
#define UDSL_MINOR 48 #define UDSL_MINOR 48
#define UDSL_NUMBER_RCV_URBS 1 #define UDSL_NUMBER_RCV_URBS 1
...@@ -137,33 +137,25 @@ struct udsl_usb_send_data_context { ...@@ -137,33 +137,25 @@ struct udsl_usb_send_data_context {
*/ */
struct udsl_instance_data { struct udsl_instance_data {
int minor; struct tasklet_struct recvqueue_tasklet;
/* usb device part */ /* usb device part */
struct usb_device *usb_dev; struct usb_device *usb_dev;
struct udsl_data_ctx *rcvbufs; struct udsl_data_ctx *rcvbufs;
struct sk_buff_head sndqueue; struct sk_buff_head sndqueue;
spinlock_t sndqlock;
struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS]; struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS];
int data_started; int data_started;
/* atm device part */ /* atm device part */
struct atm_dev *atm_dev; struct atm_dev *atm_dev;
struct sk_buff_head recvqueue; struct sk_buff_head recvqueue;
spinlock_t recvqlock;
struct atmsar_vcc_data *atmsar_vcc_list; struct atmsar_vcc_data *atmsar_vcc_list;
}; };
struct udsl_instance_data *minor_data[MAX_UDSL];
static const char udsl_driver_name[] = "Alcatel SpeedTouch USB"; static const char udsl_driver_name[] = "Alcatel SpeedTouch USB";
/* data thread */
DECLARE_WAIT_QUEUE_HEAD (udsl_wqh);
static DECLARE_COMPLETION(thread_grave);
static DECLARE_MUTEX(udsl_usb_ioctl_lock); static DECLARE_MUTEX(udsl_usb_ioctl_lock);
static unsigned int datapid;
#ifdef DEBUG_PACKET #ifdef DEBUG_PACKET
int udsl_print_packet (const unsigned char *data, int len); int udsl_print_packet (const unsigned char *data, int len);
...@@ -178,7 +170,7 @@ static void udsl_atm_close (struct atm_vcc *vcc); ...@@ -178,7 +170,7 @@ static void udsl_atm_close (struct atm_vcc *vcc);
static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg); static int udsl_atm_ioctl (struct atm_dev *dev, unsigned int cmd, void *arg);
static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb); static int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb);
int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page); int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page);
void udsl_atm_processqueue (struct udsl_instance_data *instance); void udsl_atm_processqueue (unsigned long data);
static struct atmdev_ops udsl_atm_devops = { static struct atmdev_ops udsl_atm_devops = {
.open = udsl_atm_open, .open = udsl_atm_open,
...@@ -244,19 +236,15 @@ void udsl_atm_stopdevice (struct udsl_instance_data *instance) ...@@ -244,19 +236,15 @@ void udsl_atm_stopdevice (struct udsl_instance_data *instance)
struct atm_vcc *walk; struct atm_vcc *walk;
struct sk_buff *skb; struct sk_buff *skb;
struct atm_dev *atm_dev; struct atm_dev *atm_dev;
unsigned long iflags;
if (!instance->atm_dev) if (!instance->atm_dev)
return; return;
atm_dev = instance->atm_dev; atm_dev = instance->atm_dev;
/* clean queue */ /* clean queue */
spin_lock_irqsave (&instance->recvqlock, iflags); while ((skb = skb_dequeue (&instance->recvqueue)))
while (!skb_queue_empty (&instance->recvqueue)) {
skb = skb_dequeue (&instance->recvqueue);
dev_kfree_skb (skb); dev_kfree_skb (skb);
};
spin_unlock_irqrestore (&instance->recvqlock, iflags);
atm_dev->signal = ATM_PHY_SIG_LOST; atm_dev->signal = ATM_PHY_SIG_LOST;
walk = atm_dev->vccs; walk = atm_dev->vccs;
...@@ -296,12 +284,13 @@ struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size) ...@@ -296,12 +284,13 @@ struct sk_buff *udsl_atm_alloc_tx (struct atm_vcc *vcc, unsigned int size)
int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page) int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
{ {
struct udsl_instance_data *instance = (struct udsl_instance_data *) atm_dev->dev_data; struct udsl_instance_data *instance = atm_dev->dev_data;
int left = *pos; int left = *pos;
if (!left--) if (!left--)
return sprintf (page, "Speed Touch USB:%d (%02x:%02x:%02x:%02x:%02x:%02x)\n", return sprintf (page, "Speed Touch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
instance->minor, atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2], instance->usb_dev->bus->bus_name, instance->usb_dev->devpath,
atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]); atm_dev->esi[3], atm_dev->esi[4], atm_dev->esi[5]);
if (!left--) if (!left--)
...@@ -330,8 +319,8 @@ int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page) ...@@ -330,8 +319,8 @@ int udsl_atm_proc_read (struct atm_dev *atm_dev, loff_t * pos, char *page)
****************************************************************************/ ****************************************************************************/
int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
{ {
struct udsl_atm_dev_data *dev_data = (struct udsl_atm_dev_data *) vcc->dev_data; struct udsl_atm_dev_data *dev_data = vcc->dev_data;
struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
struct sk_buff *new = NULL; struct sk_buff *new = NULL;
int err; int err;
...@@ -372,25 +361,15 @@ int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb) ...@@ -372,25 +361,15 @@ int udsl_atm_send (struct atm_vcc *vcc, struct sk_buff *skb)
}; };
void udsl_atm_processqueue (struct udsl_instance_data *instance) void udsl_atm_processqueue (unsigned long data)
{ {
struct udsl_instance_data *instance = (struct udsl_instance_data *) data;
struct atmsar_vcc_data *atmsar_vcc = NULL; struct atmsar_vcc_data *atmsar_vcc = NULL;
struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL; struct sk_buff *new = NULL, *skb = NULL, *tmp = NULL;
unsigned long iflags;
/* quick check */
spin_lock_irqsave (&instance->recvqlock, iflags);
if (skb_queue_empty (&instance->recvqueue)) {
spin_unlock_irqrestore (&instance->recvqlock, iflags);
return;
}
PDEBUG ("udsl_atm_processqueue entered\n"); PDEBUG ("udsl_atm_processqueue entered\n");
while (!skb_queue_empty (&instance->recvqueue)) { while ((skb = skb_dequeue (&instance->recvqueue))) {
skb = skb_dequeue (&instance->recvqueue);
spin_unlock_irqrestore (&instance->recvqlock, iflags);
PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len); PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len);
PACKETDEBUG (skb->data, skb->len); PACKETDEBUG (skb->data, skb->len);
...@@ -430,73 +409,11 @@ void udsl_atm_processqueue (struct udsl_instance_data *instance) ...@@ -430,73 +409,11 @@ void udsl_atm_processqueue (struct udsl_instance_data *instance)
} }
}; };
dev_kfree_skb (skb); dev_kfree_skb (skb);
spin_lock_irqsave (&instance->recvqlock, iflags);
}; };
spin_unlock_irqrestore (&instance->recvqlock, iflags);
PDEBUG ("udsl_atm_processqueue successfull\n"); PDEBUG ("udsl_atm_processqueue successfull\n");
} }
int udsl_atm_processqueue_thread (void *data)
{
int i = 0;
DECLARE_WAITQUEUE (wait, current);
lock_kernel ();
daemonize ();
/* Setup a nice name */
strcpy (current->comm, "kSpeedSARd");
add_wait_queue (&udsl_wqh, &wait);
set_current_state(TASK_INTERRUPTIBLE);
for (;;) {
schedule();
if (signal_pending (current))
break;
PDEBUG ("SpeedSARd awoke\n");
retry:
for (i = 0; i < MAX_UDSL; i++)
if (minor_data[i])
udsl_atm_processqueue (minor_data[i]);
set_current_state(TASK_INTERRUPTIBLE);
/* we must check for data recieved and restart processing if there's any */
for (i = 0; i < MAX_UDSL; i++) {
spin_lock_irq(&minor_data[i]->recvqlock);
if (!skb_queue_empty(&minor_data[i]->recvqueue)) {
spin_unlock_irq(&minor_data[i]->recvqlock);
set_current_state(TASK_RUNNING);
goto retry;
} else {
spin_unlock_irq(&minor_data[i]->recvqlock);
}
}
};
set_current_state(TASK_RUNNING);
remove_wait_queue (&udsl_wqh, &wait);
PDEBUG ("SpeedSARd is exiting\n");
complete_and_exit(&thread_grave, 0);
return 0; //never reached
}
void udsl_atm_sar_start (void)
{
datapid = kernel_thread (udsl_atm_processqueue_thread, (void *) NULL,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
}
void udsl_atm_sar_stop (void)
{
int ret;
/* Kill the thread */
ret = kill_proc (datapid, SIGTERM, 1);
if (!ret) {
wait_for_completion(&thread_grave);
}
}
/*************************************************************************** /***************************************************************************
* *
...@@ -506,7 +423,7 @@ void udsl_atm_sar_stop (void) ...@@ -506,7 +423,7 @@ void udsl_atm_sar_stop (void)
int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
{ {
struct udsl_atm_dev_data *dev_data; struct udsl_atm_dev_data *dev_data;
struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
PDEBUG ("udsl_atm_open called\n"); PDEBUG ("udsl_atm_open called\n");
...@@ -515,8 +432,7 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -515,8 +432,7 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -EINVAL; return -EINVAL;
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
dev_data = dev_data = kmalloc (sizeof (struct udsl_atm_dev_data), GFP_KERNEL);
(struct udsl_atm_dev_data *) kmalloc (sizeof (struct udsl_atm_dev_data), GFP_KERNEL);
if (!dev_data) if (!dev_data)
return -ENOMEM; return -ENOMEM;
...@@ -544,8 +460,8 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci) ...@@ -544,8 +460,8 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
void udsl_atm_close (struct atm_vcc *vcc) void udsl_atm_close (struct atm_vcc *vcc)
{ {
struct udsl_atm_dev_data *dev_data = (struct udsl_atm_dev_data *) vcc->dev_data; struct udsl_atm_dev_data *dev_data = vcc->dev_data;
struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data; struct udsl_instance_data *instance = vcc->dev->dev_data;
PDEBUG ("udsl_atm_close called\n"); PDEBUG ("udsl_atm_close called\n");
...@@ -596,7 +512,7 @@ struct udsl_cb { ...@@ -596,7 +512,7 @@ struct udsl_cb {
static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs) static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
{ {
struct udsl_usb_send_data_context *ctx = (struct udsl_usb_send_data_context *) urb->context; struct udsl_usb_send_data_context *ctx = urb->context;
struct udsl_instance_data *instance = ctx->instance; struct udsl_instance_data *instance = ctx->instance;
int err; int err;
...@@ -604,17 +520,12 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs) ...@@ -604,17 +520,12 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
ctx->skb, urb->status); ctx->skb, urb->status);
ctx->vcc->pop (ctx->vcc, ctx->skb); ctx->vcc->pop (ctx->vcc, ctx->skb);
ctx->skb = NULL;
spin_lock (&instance->sndqlock); if (!(ctx->skb = skb_dequeue (&(instance->sndqueue))))
if (skb_queue_empty (&instance->sndqueue)) {
spin_unlock (&instance->sndqlock);
return; return;
}
/* submit next skb */ /* submit next skb */
ctx->skb = skb_dequeue (&(instance->sndqueue));
ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc; ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc;
spin_unlock (&instance->sndqlock);
usb_fill_bulk_urb (urb, usb_fill_bulk_urb (urb,
instance->usb_dev, instance->usb_dev,
usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
...@@ -661,13 +572,13 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc ...@@ -661,13 +572,13 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
PACKETDEBUG (skb->data, skb->len); PACKETDEBUG (skb->data, skb->len);
spin_lock_irqsave (&instance->sndqlock, flags); spin_lock_irqsave (&instance->sndqueue.lock, flags);
((struct udsl_cb *) skb->cb)->vcc = vcc; ((struct udsl_cb *) skb->cb)->vcc = vcc;
/* we are already queueing */ /* we are already queueing */
if (!skb_queue_empty (&instance->sndqueue)) { if (!skb_queue_empty (&instance->sndqueue)) {
skb_queue_tail (&instance->sndqueue, skb); __skb_queue_tail (&instance->sndqueue, skb);
spin_unlock_irqrestore (&instance->sndqlock, flags); spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
PDEBUG ("udsl_usb_send_data: already queing, skb (0x%p) queued\n", skb); PDEBUG ("udsl_usb_send_data: already queing, skb (0x%p) queued\n", skb);
return 0; return 0;
} }
...@@ -678,8 +589,8 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc ...@@ -678,8 +589,8 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
/* we must start queueing */ /* we must start queueing */
if (i == UDSL_NUMBER_SND_URBS) { if (i == UDSL_NUMBER_SND_URBS) {
skb_queue_tail (&instance->sndqueue, skb); __skb_queue_tail (&instance->sndqueue, skb);
spin_unlock_irqrestore (&instance->sndqlock, flags); spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb); PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb);
return 0; return 0;
}; };
...@@ -690,7 +601,7 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc ...@@ -690,7 +601,7 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
instance->send_ctx[i].vcc = vcc; instance->send_ctx[i].vcc = vcc;
instance->send_ctx[i].instance = instance; instance->send_ctx[i].instance = instance;
spin_unlock_irqrestore (&instance->sndqlock, flags); spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
/* submit packet */ /* submit packet */
usb_fill_bulk_urb (urb, usb_fill_bulk_urb (urb,
...@@ -722,7 +633,7 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) ...@@ -722,7 +633,7 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
PDEBUG ("udsl_usb_receive_data entered, got packet %p with length %d an status %d\n", urb, PDEBUG ("udsl_usb_receive_data entered, got packet %p with length %d an status %d\n", urb,
urb->actual_length, urb->status); urb->actual_length, urb->status);
ctx = (struct udsl_data_ctx *) urb->context; ctx = urb->context;
if (!ctx || !ctx->skb) if (!ctx || !ctx->skb)
return; return;
...@@ -736,10 +647,8 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs) ...@@ -736,10 +647,8 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
skb_put (ctx->skb, urb->actual_length); skb_put (ctx->skb, urb->actual_length);
/* queue the skb for processing and wake the SAR */ /* queue the skb for processing and wake the SAR */
spin_lock (&instance->recvqlock);
skb_queue_tail (&instance->recvqueue, ctx->skb); skb_queue_tail (&instance->recvqueue, ctx->skb);
spin_unlock (&instance->recvqlock); tasklet_schedule (&instance->recvqueue_tasklet);
wake_up (&udsl_wqh);
/* get a new skb */ /* get a new skb */
ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE); ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
if (!ctx->skb) { if (!ctx->skb) {
...@@ -781,9 +690,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance) ...@@ -781,9 +690,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance)
usb_maxpacket (instance->usb_dev, usb_maxpacket (instance->usb_dev,
usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0)); usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0));
instance->rcvbufs = instance->rcvbufs = kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS, GFP_KERNEL);
(struct udsl_data_ctx *) kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS,
GFP_KERNEL);
if (!instance->rcvbufs) if (!instance->rcvbufs)
return -ENOMEM; return -ENOMEM;
...@@ -902,18 +809,8 @@ static int udsl_usb_data_exit (struct udsl_instance_data *instance) ...@@ -902,18 +809,8 @@ static int udsl_usb_data_exit (struct udsl_instance_data *instance)
static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data) static int udsl_usb_ioctl (struct usb_interface *intf, unsigned int code, void *user_data)
{ {
struct usb_device *dev = interface_to_usbdev (intf); struct udsl_instance_data *instance = usb_get_intfdata (intf);
struct udsl_instance_data *instance; int retval;
int i,retval;
for (i = 0; i < MAX_UDSL; i++)
if (minor_data[i] && (minor_data[i]->usb_dev == dev))
break;
if (i == MAX_UDSL)
return -EINVAL;
instance = minor_data[i];
down(&udsl_usb_ioctl_lock); down(&udsl_usb_ioctl_lock);
switch (code) { switch (code) {
...@@ -950,16 +847,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -950,16 +847,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
for (i = 0; i < MAX_UDSL; i++) PDEBUG ("Device Accepted\n");
if (minor_data[i] == NULL)
break;
if (i >= MAX_UDSL) {
printk (KERN_INFO "No minor table space available for SpeedTouch USB\n");
return -ENOMEM;
};
PDEBUG ("Device Accepted, assigning minor %d\n", i);
/* device init */ /* device init */
instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL); instance = kmalloc (sizeof (struct udsl_instance_data), GFP_KERNEL);
...@@ -970,11 +858,9 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -970,11 +858,9 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
/* initialize structure */ /* initialize structure */
memset (instance, 0, sizeof (struct udsl_instance_data)); memset (instance, 0, sizeof (struct udsl_instance_data));
instance->minor = i;
instance->usb_dev = dev; instance->usb_dev = dev;
instance->rcvbufs = NULL; instance->rcvbufs = NULL;
spin_lock_init (&instance->sndqlock); tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance);
spin_lock_init (&instance->recvqlock);
udsl_atm_startdevice (instance, &udsl_atm_devops); udsl_atm_startdevice (instance, &udsl_atm_devops);
...@@ -987,8 +873,6 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -987,8 +873,6 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
mac[5]); mac[5]);
udsl_atm_set_mac (instance, mac); udsl_atm_set_mac (instance, mac);
minor_data[instance->minor] = instance;
usb_set_intfdata (intf, instance); usb_set_intfdata (intf, instance);
return 0; return 0;
} }
...@@ -996,11 +880,11 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i ...@@ -996,11 +880,11 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
static void udsl_usb_disconnect (struct usb_interface *intf) static void udsl_usb_disconnect (struct usb_interface *intf)
{ {
struct udsl_instance_data *instance = usb_get_intfdata (intf); struct udsl_instance_data *instance = usb_get_intfdata (intf);
int i;
PDEBUG ("disconnecting\n");
usb_set_intfdata (intf, NULL); usb_set_intfdata (intf, NULL);
if (instance) { if (instance) {
i = instance->minor;
/* unlinking receive buffers */ /* unlinking receive buffers */
udsl_usb_data_exit (instance); udsl_usb_data_exit (instance);
...@@ -1008,10 +892,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1008,10 +892,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
if (instance->atm_dev) if (instance->atm_dev)
udsl_atm_stopdevice (instance); udsl_atm_stopdevice (instance);
PDEBUG ("disconnecting minor %d\n", i);
kfree (instance); kfree (instance);
minor_data[i] = NULL;
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
...@@ -1025,23 +906,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf) ...@@ -1025,23 +906,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
static int __init udsl_usb_init (void) static int __init udsl_usb_init (void)
{ {
int i;
PDEBUG ("Initializing SpeedTouch Driver Version " DRIVER_VERSION "\n"); PDEBUG ("Initializing SpeedTouch Driver Version " DRIVER_VERSION "\n");
for (i = 0; i < MAX_UDSL; i++)
minor_data[i] = NULL;
init_waitqueue_head (&udsl_wqh);
udsl_atm_sar_start ();
return usb_register (&udsl_usb_driver); return usb_register (&udsl_usb_driver);
} }
static void __exit udsl_usb_cleanup (void) static void __exit udsl_usb_cleanup (void)
{ {
/* killing threads */
udsl_atm_sar_stop ();
usb_deregister (&udsl_usb_driver); usb_deregister (&udsl_usb_driver);
} }
......
...@@ -507,7 +507,8 @@ static struct usb_driver digi_driver = { ...@@ -507,7 +507,8 @@ static struct usb_driver digi_driver = {
static struct usb_serial_device_type digi_acceleport_2_device = { static struct usb_serial_device_type digi_acceleport_2_device = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "Digi USB", .name = "Digi 2 port USB adapter",
.short_name = "digi_2",
.id_table = id_table_2, .id_table = id_table_2,
.num_interrupt_in = 0, .num_interrupt_in = 0,
.num_bulk_in = 4, .num_bulk_in = 4,
...@@ -531,7 +532,8 @@ static struct usb_serial_device_type digi_acceleport_2_device = { ...@@ -531,7 +532,8 @@ static struct usb_serial_device_type digi_acceleport_2_device = {
static struct usb_serial_device_type digi_acceleport_4_device = { static struct usb_serial_device_type digi_acceleport_4_device = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "Digi USB", .name = "Digi 4 port USB adapter",
.short_name = "digi_4",
.id_table = id_table_4, .id_table = id_table_4,
.num_interrupt_in = 0, .num_interrupt_in = 0,
.num_bulk_in = 5, .num_bulk_in = 5,
......
...@@ -910,7 +910,7 @@ int usb_serial_probe(struct usb_interface *interface, ...@@ -910,7 +910,7 @@ int usb_serial_probe(struct usb_interface *interface,
kfree (serial); kfree (serial);
return -EIO; return -EIO;
} }
retval = type->probe (serial, id); retval = type->probe (serial, id_pattern);
module_put(type->owner); module_put(type->owner);
if (retval < 0) { if (retval < 0) {
......
...@@ -177,24 +177,40 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs); ...@@ -177,24 +177,40 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs);
static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs); static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs); static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs);
static int clie_3_5_startup (struct usb_serial *serial); static int clie_3_5_startup (struct usb_serial *serial);
static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id);
static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id);
static struct usb_device_id id_table [] = { static struct usb_device_id id_table [] = {
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) }, { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) }, .driver_info = (unsigned int)&palm_os_3_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) }, { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),
{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) }, .driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) }, .driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),
{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, .driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, .driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, .driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_1_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -600,36 +616,47 @@ static void visor_unthrottle (struct usb_serial_port *port) ...@@ -600,36 +616,47 @@ static void visor_unthrottle (struct usb_serial_port *port)
dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result); dev_err(&port->dev, "%s - failed submitting read urb, error %d\n", __FUNCTION__, result);
} }
static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id) static int palm_os_3_probe (struct usb_serial *serial, const struct usb_device_id *id)
{ {
struct device *dev = &serial->dev->dev; struct device *dev = &serial->dev->dev;
int response; struct visor_connection_info *connection_info;
unsigned char *transfer_buffer;
char *string;
int retval = 0;
int i; int i;
int num_ports; int num_ports;
unsigned char *transfer_buffer = kmalloc (256, GFP_KERNEL);
dbg("%s", __FUNCTION__);
transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);
if (!transfer_buffer) { if (!transfer_buffer) {
dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 256); dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__,
sizeof(*connection_info));
return -ENOMEM; return -ENOMEM;
} }
dbg("%s", __FUNCTION__);
dbg("%s - Set config to 1", __FUNCTION__);
usb_set_configuration (serial->dev, 1);
/* send a get connection info request */ /* send a get connection info request */
response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION, retval = usb_control_msg (serial->dev,
0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300); usb_rcvctrlpipe(serial->dev, 0),
if (response < 0) { VISOR_GET_CONNECTION_INFORMATION,
dev_err(dev, "%s - error getting connection information\n", __FUNCTION__); 0xc2, 0x0000, 0x0000, transfer_buffer,
} else { sizeof(*connection_info), 300);
struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer; if (retval < 0) {
char *string; dev_err(dev, "%s - error %d getting connection information\n",
__FUNCTION__, retval);
goto exit;
}
connection_info = (struct visor_connection_info *)transfer_buffer;
le16_to_cpus(&connection_info->num_ports); le16_to_cpus(&connection_info->num_ports);
num_ports = connection_info->num_ports; num_ports = connection_info->num_ports;
dev_info(dev, "%s: Number of ports: %d\n", serial->type->name, connection_info->num_ports); /* handle devices that report invalid stuff here */
if (num_ports > 2)
num_ports = 2;
dev_info(dev, "%s: Number of ports: %d\n", serial->type->name,
connection_info->num_ports);
for (i = 0; i < num_ports; ++i) { for (i = 0; i < num_ports; ++i) {
switch (connection_info->connections[i].port_function_id) { switch (connection_info->connections[i].port_function_id) {
case VISOR_FUNCTION_GENERIC: case VISOR_FUNCTION_GENERIC:
...@@ -653,48 +680,81 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i ...@@ -653,48 +680,81 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id *i
} }
dev_info(dev, "%s: port %d, is for %s use\n", serial->type->name, dev_info(dev, "%s: port %d, is for %s use\n", serial->type->name,
connection_info->connections[i].port, string); connection_info->connections[i].port, string);
/* save off our num_ports info so that we can use it in the calc_num_ports call */
usb_set_serial_data(serial, (void *)(long)num_ports);
}
} }
if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) || /*
((serial->dev->descriptor.idVendor == SONY_VENDOR_ID) && * save off our num_ports info so that we can use it in the
(serial->dev->descriptor.idProduct != SONY_CLIE_4_1_ID))) { * calc_num_ports callback
/* Palm OS 4.0 Hack */ */
response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), usb_set_serial_data(serial, (void *)(long)num_ports);
PALM_GET_SOME_UNKNOWN_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
0x14, 300);
if (response < 0) {
dev_err(dev, "%s - error getting first unknown palm command\n", __FUNCTION__);
} else {
usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
}
response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0),
PALM_GET_SOME_UNKNOWN_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
0x14, 300);
if (response < 0) {
dev_err(dev, "%s - error getting second unknown palm command\n", __FUNCTION__);
} else {
usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
}
}
/* ask for the number of bytes available, but ignore the response as it is broken */ /* ask for the number of bytes available, but ignore the response as it is broken */
response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_REQUEST_BYTES_AVAILABLE, retval = usb_control_msg (serial->dev,
0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300); usb_rcvctrlpipe(serial->dev, 0),
if (response < 0) { VISOR_REQUEST_BYTES_AVAILABLE,
dev_err(dev, "%s - error getting bytes available request\n", __FUNCTION__); 0xc2, 0x0000, 0x0005, transfer_buffer,
} 0x02, 300);
if (retval < 0)
dev_err(dev, "%s - error %d getting bytes available request\n",
__FUNCTION__, retval);
retval = 0;
exit:
kfree (transfer_buffer); kfree (transfer_buffer);
/* continue on with initialization */ return retval;
}
static int palm_os_4_probe (struct usb_serial *serial, const struct usb_device_id *id)
{
struct device *dev = &serial->dev->dev;
struct palm_ext_connection_info *connection_info;
unsigned char *transfer_buffer;
int retval;
dbg("%s", __FUNCTION__);
transfer_buffer = kmalloc (sizeof (*connection_info), GFP_KERNEL);
if (!transfer_buffer) {
dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__,
sizeof(*connection_info));
return -ENOMEM;
}
retval = usb_control_msg (serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
PALM_GET_EXT_CONNECTION_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
sizeof (*connection_info), 300);
if (retval < 0)
dev_err(dev, "%s - error %d getting connection info\n",
__FUNCTION__, retval);
else
usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, transfer_buffer);
kfree (transfer_buffer);
return 0; return 0;
} }
static int visor_probe (struct usb_serial *serial, const struct usb_device_id *id)
{
int retval = 0;
int (*startup) (struct usb_serial *serial, const struct usb_device_id *id);
dbg("%s", __FUNCTION__);
dbg("%s - Set config to 1", __FUNCTION__);
usb_set_configuration (serial->dev, 1);
if (id->driver_info) {
startup = (void *)id->driver_info;
retval = startup(serial, id);
}
return retval;
}
static int visor_calc_num_ports (struct usb_serial *serial) static int visor_calc_num_ports (struct usb_serial *serial)
{ {
int num_ports = (int)(long)(usb_get_serial_data(serial)); int num_ports = (int)(long)(usb_get_serial_data(serial));
......
...@@ -94,7 +94,36 @@ struct visor_connection_info { ...@@ -94,7 +94,36 @@ struct visor_connection_info {
* PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to * PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to
* get some information from the M series devices, that is currently unknown. * get some information from the M series devices, that is currently unknown.
****************************************************************************/ ****************************************************************************/
#define PALM_GET_SOME_UNKNOWN_INFORMATION 0x04 #define PALM_GET_EXT_CONNECTION_INFORMATION 0x04
/**
* struct palm_ext_connection_info - return data from a PALM_GET_EXT_CONNECTION_INFORMATION request
* @num_ports: maximum number of functions/connections in use
* @endpoint_numbers_different: will be 1 if in and out endpoints numbers are
* different, otherwise it is 0. If value is 1, then
* connections.end_point_info is non-zero. If value is 0, then
* connections.port contains the endpoint number, which is the same for in
* and out.
* @port_function_id: contains the creator id of the applicaton that opened
* this connection.
* @port: contains the in/out endpoint number. Is 0 if in and out endpoint
* numbers are different.
* @end_point_info: high nubbe is in endpoint and low nibble will indicate out
* endpoint. Is 0 if in and out endpoints are the same.
*
* The maximum number of connections currently supported is 2
*/
struct palm_ext_connection_info {
__u8 num_ports;
__u8 endpoint_numbers_different;
__u16 reserved1;
struct {
__u32 port_function_id;
__u8 port;
__u8 end_point_info;
__u16 reserved;
} connections[2];
};
#endif #endif
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
void usb_stor_show_command(Scsi_Cmnd *srb) void usb_stor_show_command(Scsi_Cmnd *srb)
{ {
char *what = NULL; char *what = NULL;
int i;
switch (srb->cmnd[0]) { switch (srb->cmnd[0]) {
case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break; case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
...@@ -143,29 +144,25 @@ void usb_stor_show_command(Scsi_Cmnd *srb) ...@@ -143,29 +144,25 @@ void usb_stor_show_command(Scsi_Cmnd *srb)
default: what = "(unknown command)"; break; default: what = "(unknown command)"; break;
} }
US_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); US_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len);
US_DEBUGP("%02x %02x %02x %02x " US_DEBUGP("");
"%02x %02x %02x %02x " for (i = 0; i < srb->cmd_len && i < 16; i++)
"%02x %02x %02x %02x\n", US_DEBUGPX(" %02x", srb->cmnd[i]);
srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3], US_DEBUGPX("\n");
srb->cmnd[4], srb->cmnd[5], srb->cmnd[6], srb->cmnd[7],
srb->cmnd[8], srb->cmnd[9], srb->cmnd[10],
srb->cmnd[11]);
} }
void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd ) void usb_stor_print_Scsi_Cmnd(Scsi_Cmnd *cmd)
{ {
int i=0, bufferSize = cmd->request_bufflen; int i=0, bufferSize = cmd->request_bufflen;
u8* buffer = cmd->request_buffer; u8 *buffer = cmd->request_buffer;
struct scatterlist* sg = (struct scatterlist*)cmd->request_buffer; struct scatterlist *sg = (struct scatterlist*)cmd->request_buffer;
US_DEBUGP("Dumping information about %p.\n", cmd ); US_DEBUGP("Dumping information about %p.\n", cmd);
US_DEBUGP("cmd->cmnd[0] value is %d.\n", cmd->cmnd[0] ); US_DEBUGP("cmd->cmnd[0] value is %d.\n", cmd->cmnd[0]);
US_DEBUGP("(MODE_SENSE is %d and MODE_SENSE_10 is %d)\n", US_DEBUGP("(MODE_SENSE is %d and MODE_SENSE_10 is %d)\n",
MODE_SENSE, MODE_SENSE_10 ); MODE_SENSE, MODE_SENSE_10);
US_DEBUGP("buffer is %p with length %d.\n", buffer, bufferSize ); US_DEBUGP("buffer is %p with length %d.\n", buffer, bufferSize);
for ( i=0; i<bufferSize; i+=16 ) for (i=0; i<bufferSize; i+=16) {
{
US_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x\n" US_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x\n"
"%02x %02x %02x %02x %02x %02x %02x %02x\n", "%02x %02x %02x %02x %02x %02x %02x %02x\n",
buffer[i], buffer[i],
...@@ -187,8 +184,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd ) ...@@ -187,8 +184,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd )
} }
US_DEBUGP("Buffer has %d scatterlists.\n", cmd->use_sg ); US_DEBUGP("Buffer has %d scatterlists.\n", cmd->use_sg );
for ( i=0; i<cmd->use_sg; i++ ) for (i=0; i<cmd->use_sg; i++) {
{
char *adr = sg_address(sg[i]); char *adr = sg_address(sg[i]);
US_DEBUGP("Length of scatterlist %d is %d.\n",i,sg[i].length); US_DEBUGP("Length of scatterlist %d is %d.\n",i,sg[i].length);
......
...@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE (usb, skel_table); ...@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE (usb, skel_table);
#define USB_SKEL_MINOR_BASE 0 #define USB_SKEL_MINOR_BASE 0
#else #else
/* Get a minor range for your devices from the usb maintainer */ /* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE 200 #define USB_SKEL_MINOR_BASE 192
#endif #endif
/* Structure to hold all of our device specific stuff */ /* Structure to hold all of our device specific 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