Commit fa4229ad authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 29b49883 0c546aea
......@@ -23,7 +23,7 @@ and /proc/bus/usb/devices, as well as /proc/bus/usb/BBB/DDD files.
to interact with USB devices.
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.
**NOTE**: The filesystem has been renamed from "usbdevfs" to
......
......@@ -27,8 +27,8 @@ config USB_BLUETOOTH_TTY
device that can be used only by specialized Bluetooth HCI software.
Say Y here if you want to use OpenBT Bluetooth stack (available
at <http://developer.axis.com/software/index.shtml>), or other TTY
based Bluetooth stacks, and want to connect a USB Bluetooth device
at <http://developer.axis.com/software>), or other TTY based
Bluetooth stacks, and want to connect a USB Bluetooth device
to your computer's USB port.
Do *not* enable this driver if you want to use generic Linux
......
......@@ -1420,7 +1420,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->number_of_packets = DESCFRAMES;
urb->context = as;
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;
else
u->flags &= ~FLG_RUNNING;
......@@ -1433,7 +1433,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->number_of_packets = DESCFRAMES;
urb->context = as;
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;
else
u->flags &= ~FLG_RUNNING;
......@@ -1448,7 +1448,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->context = as;
urb->complete = usbout_sync_completed;
/* 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;
else
u->flags &= ~FLG_RUNNING;
......@@ -1462,7 +1462,7 @@ static int usbout_start(struct usb_audiodev *as)
urb->context = as;
urb->complete = usbout_sync_completed;
/* 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;
else
u->flags &= ~FLG_RUNNING;
......
......@@ -337,7 +337,8 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
if (status) {
printk(KERN_ERR "usbmidi: Cannot submit urb (%d)\n",status);
ret = -EFAULT;
ret = -EIO;
goto error;
}
add_wait_queue( &ep->wait, &wait );
......@@ -354,6 +355,7 @@ static int usb_write( struct midi_out_endpoint *ep, unsigned char *buf, int len
set_current_state( TASK_RUNNING );
remove_wait_queue( &ep->wait, &wait );
error:
return ret;
}
......@@ -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);
unsigned char *data = urb->transfer_buffer;
int i, j, wake;
unsigned long int flags;
if ( !ep->urbSubmitted ) {
return;
......@@ -377,7 +378,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
if ( (urb->status == 0) && (urb->actual_length > 0) ) {
wake = 0;
spin_lock_irqsave( &ep->lock, flags );
spin_lock( &ep->lock );
for(j = 0; j < urb->actual_length; j += 4) {
int cin = (data[j]>>0)&0xf;
......@@ -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 ) {
wake_up( &ep->wait );
}
......@@ -407,7 +408,7 @@ static void usb_bulk_read(struct urb *urb, struct pt_regs *regs)
urb->dev = ep->usbdev;
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)
add_wait_queue( &open_wait, &wait );
up(&open_sem);
schedule();
__set_current_state(TASK_RUNNING);
remove_wait_queue( &open_wait, &wait );
if ( signal_pending(current) ) {
return -ERESTARTSYS;
......
......@@ -200,8 +200,10 @@ static int xpad_open (struct input_dev *dev)
return 0;
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 0;
}
......
......@@ -57,6 +57,7 @@
#include <asm/uaccess.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
......@@ -87,7 +88,6 @@
#define SPEEDTOUCH_VENDORID 0x06b9
#define SPEEDTOUCH_PRODUCTID 0x4061
#define MAX_UDSL 1
#define UDSL_OBUF_SIZE 32768
#define UDSL_MINOR 48
#define UDSL_NUMBER_RCV_URBS 1
......@@ -137,33 +137,25 @@ struct udsl_usb_send_data_context {
*/
struct udsl_instance_data {
int minor;
struct tasklet_struct recvqueue_tasklet;
/* usb device part */
struct usb_device *usb_dev;
struct udsl_data_ctx *rcvbufs;
struct sk_buff_head sndqueue;
spinlock_t sndqlock;
struct udsl_usb_send_data_context send_ctx[UDSL_NUMBER_SND_URBS];
int data_started;
/* atm device part */
struct atm_dev *atm_dev;
struct sk_buff_head recvqueue;
spinlock_t recvqlock;
struct atmsar_vcc_data *atmsar_vcc_list;
};
struct udsl_instance_data *minor_data[MAX_UDSL];
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 unsigned int datapid;
#ifdef DEBUG_PACKET
int udsl_print_packet (const unsigned char *data, int len);
......@@ -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_send (struct atm_vcc *vcc, struct sk_buff *skb);
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 = {
.open = udsl_atm_open,
......@@ -244,19 +236,15 @@ void udsl_atm_stopdevice (struct udsl_instance_data *instance)
struct atm_vcc *walk;
struct sk_buff *skb;
struct atm_dev *atm_dev;
unsigned long iflags;
if (!instance->atm_dev)
return;
atm_dev = instance->atm_dev;
/* clean queue */
spin_lock_irqsave (&instance->recvqlock, iflags);
while (!skb_queue_empty (&instance->recvqueue)) {
skb = skb_dequeue (&instance->recvqueue);
while ((skb = skb_dequeue (&instance->recvqueue)))
dev_kfree_skb (skb);
};
spin_unlock_irqrestore (&instance->recvqlock, iflags);
atm_dev->signal = ATM_PHY_SIG_LOST;
walk = atm_dev->vccs;
......@@ -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)
{
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;
if (!left--)
return sprintf (page, "Speed Touch USB:%d (%02x:%02x:%02x:%02x:%02x:%02x)\n",
instance->minor, atm_dev->esi[0], atm_dev->esi[1], atm_dev->esi[2],
return sprintf (page, "Speed Touch USB %s-%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
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]);
if (!left--)
......@@ -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)
{
struct udsl_atm_dev_data *dev_data = (struct udsl_atm_dev_data *) vcc->dev_data;
struct udsl_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data;
struct udsl_atm_dev_data *dev_data = vcc->dev_data;
struct udsl_instance_data *instance = vcc->dev->dev_data;
struct sk_buff *new = NULL;
int err;
......@@ -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 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");
while (!skb_queue_empty (&instance->recvqueue)) {
skb = skb_dequeue (&instance->recvqueue);
spin_unlock_irqrestore (&instance->recvqlock, iflags);
while ((skb = skb_dequeue (&instance->recvqueue))) {
PDEBUG ("skb = %p, skb->len = %d\n", skb, skb->len);
PACKETDEBUG (skb->data, skb->len);
......@@ -430,73 +409,11 @@ void udsl_atm_processqueue (struct udsl_instance_data *instance)
}
};
dev_kfree_skb (skb);
spin_lock_irqsave (&instance->recvqlock, iflags);
};
spin_unlock_irqrestore (&instance->recvqlock, iflags);
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)
int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
{
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");
......@@ -515,8 +432,7 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
return -EINVAL;
MOD_INC_USE_COUNT;
dev_data =
(struct udsl_atm_dev_data *) kmalloc (sizeof (struct udsl_atm_dev_data), GFP_KERNEL);
dev_data = kmalloc (sizeof (struct udsl_atm_dev_data), GFP_KERNEL);
if (!dev_data)
return -ENOMEM;
......@@ -544,8 +460,8 @@ int udsl_atm_open (struct atm_vcc *vcc, short vpi, int vci)
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_instance_data *instance = (struct udsl_instance_data *) vcc->dev->dev_data;
struct udsl_atm_dev_data *dev_data = vcc->dev_data;
struct udsl_instance_data *instance = vcc->dev->dev_data;
PDEBUG ("udsl_atm_close called\n");
......@@ -596,7 +512,7 @@ struct udsl_cb {
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;
int err;
......@@ -604,17 +520,12 @@ static void udsl_usb_send_data_complete (struct urb *urb, struct pt_regs *regs)
ctx->skb, urb->status);
ctx->vcc->pop (ctx->vcc, ctx->skb);
ctx->skb = NULL;
spin_lock (&instance->sndqlock);
if (skb_queue_empty (&instance->sndqueue)) {
spin_unlock (&instance->sndqlock);
if (!(ctx->skb = skb_dequeue (&(instance->sndqueue))))
return;
}
/* submit next skb */
ctx->skb = skb_dequeue (&(instance->sndqueue));
ctx->vcc = ((struct udsl_cb *) (ctx->skb->cb))->vcc;
spin_unlock (&instance->sndqlock);
usb_fill_bulk_urb (urb,
instance->usb_dev,
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
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;
/* we are already queueing */
if (!skb_queue_empty (&instance->sndqueue)) {
skb_queue_tail (&instance->sndqueue, skb);
spin_unlock_irqrestore (&instance->sndqlock, flags);
__skb_queue_tail (&instance->sndqueue, skb);
spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
PDEBUG ("udsl_usb_send_data: already queing, skb (0x%p) queued\n", skb);
return 0;
}
......@@ -678,8 +589,8 @@ int udsl_usb_send_data (struct udsl_instance_data *instance, struct atm_vcc *vcc
/* we must start queueing */
if (i == UDSL_NUMBER_SND_URBS) {
skb_queue_tail (&instance->sndqueue, skb);
spin_unlock_irqrestore (&instance->sndqlock, flags);
__skb_queue_tail (&instance->sndqueue, skb);
spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
PDEBUG ("udsl_usb_send_data: skb (0x%p) queued\n", skb);
return 0;
};
......@@ -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].instance = instance;
spin_unlock_irqrestore (&instance->sndqlock, flags);
spin_unlock_irqrestore (&instance->sndqueue.lock, flags);
/* submit packet */
usb_fill_bulk_urb (urb,
......@@ -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,
urb->actual_length, urb->status);
ctx = (struct udsl_data_ctx *) urb->context;
ctx = urb->context;
if (!ctx || !ctx->skb)
return;
......@@ -736,10 +647,8 @@ void udsl_usb_data_receive (struct urb *urb, struct pt_regs *regs)
skb_put (ctx->skb, urb->actual_length);
/* queue the skb for processing and wake the SAR */
spin_lock (&instance->recvqlock);
skb_queue_tail (&instance->recvqueue, ctx->skb);
spin_unlock (&instance->recvqlock);
wake_up (&udsl_wqh);
tasklet_schedule (&instance->recvqueue_tasklet);
/* get a new skb */
ctx->skb = dev_alloc_skb (UDSL_RECEIVE_BUFFER_SIZE);
if (!ctx->skb) {
......@@ -781,9 +690,7 @@ int udsl_usb_data_init (struct udsl_instance_data *instance)
usb_maxpacket (instance->usb_dev,
usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT), 0));
instance->rcvbufs =
(struct udsl_data_ctx *) kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS,
GFP_KERNEL);
instance->rcvbufs = kmalloc (sizeof (struct udsl_data_ctx) * UDSL_NUMBER_RCV_URBS, GFP_KERNEL);
if (!instance->rcvbufs)
return -ENOMEM;
......@@ -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)
{
struct usb_device *dev = interface_to_usbdev (intf);
struct udsl_instance_data *instance;
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];
struct udsl_instance_data *instance = usb_get_intfdata (intf);
int retval;
down(&udsl_usb_ioctl_lock);
switch (code) {
......@@ -950,16 +847,7 @@ static int udsl_usb_probe (struct usb_interface *intf, const struct usb_device_i
MOD_INC_USE_COUNT;
for (i = 0; i < MAX_UDSL; i++)
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);
PDEBUG ("Device Accepted\n");
/* device init */
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
/* initialize structure */
memset (instance, 0, sizeof (struct udsl_instance_data));
instance->minor = i;
instance->usb_dev = dev;
instance->rcvbufs = NULL;
spin_lock_init (&instance->sndqlock);
spin_lock_init (&instance->recvqlock);
tasklet_init (&instance->recvqueue_tasklet, udsl_atm_processqueue, (unsigned long) instance);
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
mac[5]);
udsl_atm_set_mac (instance, mac);
minor_data[instance->minor] = instance;
usb_set_intfdata (intf, instance);
return 0;
}
......@@ -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)
{
struct udsl_instance_data *instance = usb_get_intfdata (intf);
int i;
PDEBUG ("disconnecting\n");
usb_set_intfdata (intf, NULL);
if (instance) {
i = instance->minor;
/* unlinking receive buffers */
udsl_usb_data_exit (instance);
......@@ -1008,10 +892,7 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
if (instance->atm_dev)
udsl_atm_stopdevice (instance);
PDEBUG ("disconnecting minor %d\n", i);
kfree (instance);
minor_data[i] = NULL;
MOD_DEC_USE_COUNT;
}
......@@ -1025,23 +906,13 @@ static void udsl_usb_disconnect (struct usb_interface *intf)
static int __init udsl_usb_init (void)
{
int i;
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);
}
static void __exit udsl_usb_cleanup (void)
{
/* killing threads */
udsl_atm_sar_stop ();
usb_deregister (&udsl_usb_driver);
}
......
......@@ -507,7 +507,8 @@ static struct usb_driver digi_driver = {
static struct usb_serial_device_type digi_acceleport_2_device = {
.owner = THIS_MODULE,
.name = "Digi USB",
.name = "Digi 2 port USB adapter",
.short_name = "digi_2",
.id_table = id_table_2,
.num_interrupt_in = 0,
.num_bulk_in = 4,
......@@ -531,7 +532,8 @@ static struct usb_serial_device_type digi_acceleport_2_device = {
static struct usb_serial_device_type digi_acceleport_4_device = {
.owner = THIS_MODULE,
.name = "Digi USB",
.name = "Digi 4 port USB adapter",
.short_name = "digi_4",
.id_table = id_table_4,
.num_interrupt_in = 0,
.num_bulk_in = 5,
......
......@@ -910,7 +910,7 @@ int usb_serial_probe(struct usb_interface *interface,
kfree (serial);
return -EIO;
}
retval = type->probe (serial, id);
retval = type->probe (serial, id_pattern);
module_put(type->owner);
if (retval < 0) {
......
......@@ -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_int_callback (struct urb *urb, struct pt_regs *regs);
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 [] = {
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_S360_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID),
.driver_info = (unsigned int)&palm_os_3_probe },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_TREO_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M515_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ 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_NX60_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_NX60_ID),
.driver_info = (unsigned int)&palm_os_4_probe },
{ } /* Terminating entry */
};
......@@ -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);
}
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;
int response;
struct visor_connection_info *connection_info;
unsigned char *transfer_buffer;
char *string;
int retval = 0;
int i;
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) {
dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__, 256);
dev_err(dev, "%s - kmalloc(%d) failed.\n", __FUNCTION__,
sizeof(*connection_info));
return -ENOMEM;
}
dbg("%s", __FUNCTION__);
dbg("%s - Set config to 1", __FUNCTION__);
usb_set_configuration (serial->dev, 1);
/* send a get connection info request */
response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_GET_CONNECTION_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 300);
if (response < 0) {
dev_err(dev, "%s - error getting connection information\n", __FUNCTION__);
} else {
struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer;
char *string;
retval = usb_control_msg (serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
VISOR_GET_CONNECTION_INFORMATION,
0xc2, 0x0000, 0x0000, transfer_buffer,
sizeof(*connection_info), 300);
if (retval < 0) {
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);
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) {
switch (connection_info->connections[i].port_function_id) {
case VISOR_FUNCTION_GENERIC:
......@@ -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,
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) &&
(serial->dev->descriptor.idProduct != SONY_CLIE_4_1_ID))) {
/* Palm OS 4.0 Hack */
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 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);
}
}
/*
* save off our num_ports info so that we can use it in the
* calc_num_ports callback
*/
usb_set_serial_data(serial, (void *)(long)num_ports);
/* 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,
0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 300);
if (response < 0) {
dev_err(dev, "%s - error getting bytes available request\n", __FUNCTION__);
}
retval = usb_control_msg (serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
VISOR_REQUEST_BYTES_AVAILABLE,
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);
/* 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;
}
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)
{
int num_ports = (int)(long)(usb_get_serial_data(serial));
......
......@@ -94,7 +94,36 @@ struct visor_connection_info {
* 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.
****************************************************************************/
#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
......@@ -49,6 +49,7 @@
void usb_stor_show_command(Scsi_Cmnd *srb)
{
char *what = NULL;
int i;
switch (srb->cmnd[0]) {
case TEST_UNIT_READY: what = "TEST_UNIT_READY"; break;
......@@ -143,29 +144,25 @@ void usb_stor_show_command(Scsi_Cmnd *srb)
default: what = "(unknown command)"; break;
}
US_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len);
US_DEBUGP("%02x %02x %02x %02x "
"%02x %02x %02x %02x "
"%02x %02x %02x %02x\n",
srb->cmnd[0], srb->cmnd[1], srb->cmnd[2], srb->cmnd[3],
srb->cmnd[4], srb->cmnd[5], srb->cmnd[6], srb->cmnd[7],
srb->cmnd[8], srb->cmnd[9], srb->cmnd[10],
srb->cmnd[11]);
US_DEBUGP("");
for (i = 0; i < srb->cmd_len && i < 16; i++)
US_DEBUGPX(" %02x", srb->cmnd[i]);
US_DEBUGPX("\n");
}
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;
u8* buffer = cmd->request_buffer;
struct scatterlist* sg = (struct scatterlist*)cmd->request_buffer;
u8 *buffer = cmd->request_buffer;
struct scatterlist *sg = (struct scatterlist*)cmd->request_buffer;
US_DEBUGP("Dumping information about %p.\n", cmd );
US_DEBUGP("cmd->cmnd[0] value is %d.\n", cmd->cmnd[0] );
US_DEBUGP("Dumping information about %p.\n", cmd);
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",
MODE_SENSE, MODE_SENSE_10 );
MODE_SENSE, MODE_SENSE_10);
US_DEBUGP("buffer is %p with length %d.\n", buffer, bufferSize );
for ( i=0; i<bufferSize; i+=16 )
{
US_DEBUGP("buffer is %p with length %d.\n", buffer, bufferSize);
for (i=0; i<bufferSize; i+=16) {
US_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x\n"
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
buffer[i],
......@@ -187,8 +184,7 @@ void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd )
}
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]);
US_DEBUGP("Length of scatterlist %d is %d.\n",i,sg[i].length);
......
......@@ -86,7 +86,7 @@ MODULE_DEVICE_TABLE (usb, skel_table);
#define USB_SKEL_MINOR_BASE 0
#else
/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE 200
#define USB_SKEL_MINOR_BASE 192
#endif
/* 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