ChangeSet 1.1276.1.46, 2003/08/27 15:18:12-07:00, [EMAIL PROTECTED]

[PATCH] USB: Cyberjack patch

Mahlzeit

I attached you the diff for 2.6.0-test4. It does there also one program run
without any error, but not more. I hope this issue will be resolved soon,
but I do not know yet how.


 drivers/usb/serial/cyberjack.c |   66 +++++++++++++++++++++++++++++++----------
 1 files changed, 50 insertions(+), 16 deletions(-)


diff -Nru a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
--- a/drivers/usb/serial/cyberjack.c    Tue Sep  2 12:43:43 2003
+++ b/drivers/usb/serial/cyberjack.c    Tue Sep  2 12:43:43 2003
@@ -101,10 +101,11 @@
 };
 
 struct cyberjack_private {
-       short   rdtodo;         /* Bytes still to read */
+       spinlock_t      lock;           /* Lock for SMP */
+       short           rdtodo;         /* Bytes still to read */
        unsigned char   wrbuf[5*64];    /* Buffer for collecting data to write */
-       short   wrfilled;       /* Overall data size we already got */
-       short   wrsent;         /* Data akready sent */
+       short           wrfilled;       /* Overall data size we already got */
+       short           wrsent;         /* Data akready sent */
 };
 
 /* do some startup allocations not currently performed by usb_serial_probe() */
@@ -120,6 +121,7 @@
                return -ENOMEM;
 
        /* set initial values */
+       spin_lock_init(&priv->lock);
        priv->rdtodo = 0;
        priv->wrfilled = 0;
        priv->wrsent = 0;
@@ -146,6 +148,7 @@
 static int  cyberjack_open (struct usb_serial_port *port, struct file *filp)
 {
        struct cyberjack_private *priv;
+       unsigned long flags;
        int result = 0;
 
        if (port_paranoia_check (port, __FUNCTION__))
@@ -160,9 +163,11 @@
        port->tty->low_latency = 1;
 
        priv = usb_get_serial_port_data(port);
+       spin_lock_irqsave(&priv->lock, flags);
        priv->rdtodo = 0;
        priv->wrfilled = 0;
        priv->wrsent = 0;
+       spin_unlock_irqrestore(&priv->lock, flags);
 
        /* shutdown any bulk reads that might be going on */
        usb_unlink_urb (port->write_urb);
@@ -194,6 +199,7 @@
 {
        struct usb_serial *serial = port->serial;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
        int result;
        int wrexpected;
 
@@ -210,15 +216,19 @@
                return (0);
        }
 
+       spin_lock_irqsave(&priv->lock, flags);
+
        if( (count+priv->wrfilled)>sizeof(priv->wrbuf) ) {
                /* To much data  for buffer. Reset buffer. */
                priv->wrfilled=0;
+               spin_unlock_irqrestore(&priv->lock, flags);
                return (0);
        }
 
        /* Copy data */
        if (from_user) {
                if (copy_from_user(priv->wrbuf+priv->wrfilled, buf, count)) {
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        return -EFAULT;
                }
        } else {
@@ -261,6 +271,7 @@
                        /* Throw away data. No better idea what to do with it. */
                        priv->wrfilled=0;
                        priv->wrsent=0;
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        return 0;
                }
 
@@ -275,6 +286,8 @@
                }
        }
 
+       spin_unlock_irqrestore(&priv->lock, flags);
+
        return (count);
 } 
 
@@ -282,8 +295,10 @@
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
        struct usb_serial *serial;
        unsigned char *data = urb->transfer_buffer;
+       int result;
 
        if (port_paranoia_check (port, __FUNCTION__))
                return;
@@ -302,21 +317,20 @@
 
        /* React only to interrupts signaling a bulk_in transfer */
        if( (urb->actual_length==4) && (data[0]==0x01) ) {
-               short old_rdtodo = priv->rdtodo;
+               short old_rdtodo;
                int result;
 
                /* This is a announcement of coming bulk_ins. */
                unsigned short size = ((unsigned short)data[3]<<8)+data[2]+3;
 
-               if( (size>259) || (size==0) ) {
-                       dbg( "Bad announced bulk_in data length: %d", size );
-                       /* Dunno what is most reliable to do here. */
-                       /* return; */
-               }
+               spin_lock_irqsave(&priv->lock, flags);
+
+               old_rdtodo = priv->rdtodo;
 
                if( (old_rdtodo+size)<(old_rdtodo) ) {
                        dbg( "To many bulk_in urbs to do." );
-                       return;
+                       spin_unlock_irqrestore(&priv->lock, flags);
+                       goto resubmit;
                }
 
                /* "+=" is probably more fault tollerant than "=" */
@@ -324,23 +338,34 @@
 
                dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo);
 
+               spin_unlock_irqrestore(&priv->lock, flags);
+
                if( !old_rdtodo ) {
                        port->read_urb->dev = port->serial->dev;
-                       result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+                       result = usb_submit_urb(port->read_urb, GFP_KERNEL);
                        if( result )
                                err("%s - failed resubmitting read urb, error %d", 
__FUNCTION__, result);
                        dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
                }
        }
+
+resubmit:
+       port->interrupt_in_urb->dev = port->serial->dev;
+       result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
+       if (result)
+               err(" usb_submit_urb(read int) failed");
+       dbg("%s - usb_submit_urb(int urb)", __FUNCTION__);
 }
 
 static void cyberjack_read_bulk_callback (struct urb *urb, struct pt_regs *regs)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
        struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
+       short todo;
        int i;
        int result;
 
@@ -372,18 +397,22 @@
                tty_flip_buffer_push(tty);
        }
 
+       spin_lock_irqsave(&priv->lock, flags);
+
        /* Reduce urbs to do by one. */
        priv->rdtodo-=urb->actual_length;
        /* Just to be sure */
-       if ( priv->rdtodo<0 )
-               priv->rdtodo = 0;
+       if ( priv->rdtodo<0 ) priv->rdtodo = 0;
+       todo = priv->rdtodo;
 
-       dbg("%s - rdtodo: %d", __FUNCTION__, priv->rdtodo);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       dbg("%s - rdtodo: %d", __FUNCTION__, todo);
 
        /* Continue to read if we have still urbs to do. */
-       if( priv->rdtodo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) 
{
+       if( todo /* || (urb->actual_length==port->bulk_in_endpointAddress)*/ ) {
                port->read_urb->dev = port->serial->dev;
-               result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+               result = usb_submit_urb(port->read_urb, GFP_KERNEL);
                if (result)
                        err("%s - failed resubmitting read urb, error %d", 
__FUNCTION__, result);
                dbg("%s - usb_submit_urb(read urb)", __FUNCTION__);
@@ -394,6 +423,7 @@
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
        struct cyberjack_private *priv = usb_get_serial_port_data(port);
+       unsigned long flags;
        struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
@@ -408,12 +438,15 @@
                return;
        }
 
+       spin_lock_irqsave(&priv->lock, flags);
+
        /* only do something if we have more data to send */
        if( priv->wrfilled ) {
                int length, blksize, result;
 
                if (port->write_urb->status == -EINPROGRESS) {
                        dbg("%s - already writing", __FUNCTION__);
+                       spin_unlock_irqrestore(&priv->lock, flags);
                        return;
                }
 
@@ -459,6 +492,7 @@
        }
 
 exit:
+       spin_unlock_irqrestore(&priv->lock, flags);
        schedule_work(&port->work);
 }
 



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to