I'm having a problem where the kernel is freezing when the function 
sohci_unlink_urb is attempting to shedule_timeout(timeout). The exact point 
in the kerneL where it freezes is in add_timer(&timer) after the spinlock is 
locked.

I attempted to fix this problem by setting the USB_ASYNC_UNLINK flag when the 
urbs are created in the probe function. This stops the freezing of the 
kernel, but my computer starts making a continuous humming noise after the 
calls to sohci_unlink_urb. I'm not sure why my computer is humming. It's 
almost as if the usb driver were constantly working even after all the urbs 
were unlinked.

The driver code is attached.

Any explanations for this strange behaviour?
-- 
Camotion
Software Development
/***************************************************************************
                          RasidDriver.c  -  description
                             -------------------
    begin                : Fri Jan 12 2001
    copyright            : (C) 2001 by CAMotion
    email                : [EMAIL PROTECTED]
 ***************************************************************************/

/*  TODO
 *
 * on read, if count == 2*TRANSFER_PACKET_SIZE, then also send contents of last_sent buffer
 * 
 */ 

//  Proprietary intellectual property,  (c) 2000 CAMotion, Inc.
//  Source and listing must be protected.

/* /////////////////////////////////////////////////////////////////////////////

  Module Name: modRasidDriver.c
  Date: January 2002
  Description: RASID Linux device driver
  Module Function:
  Notes:   By default, all functions will return a negative integer under
           error conditions.

           This program can be compiled to the module RasidDriver.o with
           the following command:

           gcc -I/usr/src/linux/include
           -Wall -O2 -o modRasidDriver.o -c modRasidDriver.c

           This module can then be inserted into the Kernel:
                        insmod modRasidDriver.o

           Caution!!!  This program compiles to a device driver (as a Kernel
           loadable module). Therefore, this code is intended to run in Kernel
           space as a priveleged process.  It has the power to do anything
           on the system including crashing the Kernel.

  Owner:         CAMotion, Inc.
                 Atlanta, GA 30318
                 404.874.0090


  Copyright (c) 2002 CAMotion, Inc.  All rights reserved.



  06-13-02 Added call to devfs_register in probe to avoid use of "mknod" call
           Added a member in the rasid context struct for the devfs handle

  Rewritten: Andrew M. Henshaw    2/1/01
  Original: Jerry Volcy
  

///////////////////////////////////////////////////////////////////////////// */


/* =======================================================================
 This section contains include files and certain preprocessing options
 required to program in Kernel space.
======================================================================= */
#ifndef __KERNEL__
#  define __KERNEL__
#endif

#ifndef MODULE
#  define MODULE
#endif

#define __NO_VERSION__ //no kernel version
#include   <linux/module.h>
//#include   <linux/modversions.h>

#if defined (CONFIG_SMP)
	#define __SMP__
#endif

#if defined (CONFIG_MODVERSIONS)
	//#define MODVERSIONS
	//#include <linux/modversions.h>
#endif

//#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/usb.h>
//#include <linux/time.h>
#include <linux/errno.h>    //definition of error symbols EPIPE, ENOENT, etc...
                            //also includes asm/errno.h
//#include <linux/sched.h>
//#include <linux/devfs_fs_kernel.h>

/* =======================================================================
  Kernel version definition

  =======================================================================*/

char kernel_version [] = UTS_RELEASE;
extern wait_queue_head_t log_wait;

/* =======================================================================
 Selection of Major#
 The following Major numbers are reserved for local (user defined) devices:
 42, 120-127. No standard production device should use these numbers.
 Usually, we are free to pick any one of these numbers for our driver.

 But, since RASID is a USB device, by convention it should have major #180.
======================================================================= */
#define RASID_MAJOR 180


/* =======================================================================
 Minor number for the RASID USB driver:  This number must be a multiple
 of 16. The specified minor number and the 15 following numbers are assigned
 to the driver.  This makes it possible to serve up to 16 similar USB devices
 with a single driver.  Here are the minor numbers currently assigned on
 this computer (by inspection of /dev/usb):

 BASE MNR#  RANGE       DEVICE
 0 (0*16)   0-15        lp
 32 (2*16)  32-47       mdc800
 48 (3*16)  48-63       scanner
 64 (4*16)  64-79       rio50
 80 (5*16)  80-95       dc2xx
 240(15*16) 240-255     dabusb

 It's probably safe to assume that these are standard assignments.
 Presumably, base minor# 16, 96-224 ((1, 6-14)*16 )are available.
 Since the assignment seems to start from the lower numbers
 to the higher, let's use a relatively large minor number to
 avoid conflicts in the near future.  Use #13*16=208 until wisdom
 to the contrary is found.
======================================================================= */
#define RASID_BASE_MINOR    208     /* we can handle 16 RASIDs with minor
                                    numbers that will range from 208 - 223)*/


/* =======================================================================
 Selection of IOCTL base address.
 It will also be necessary to pick a base number for ioctl calls made to the
 driver.  Standard ioctl base number assignments can be found in
 /usr/src/linux/Documentation/ioctl-number.txt.  Again we are free to pick any
 base address that is not assigned.  0xbb is probably a good choice:  it is far
 away from anything else out there.
======================================================================= */
#define RASID_IOCTL_BASE    0xbb


/* =======================================================================
 IOCTL calls
 These are the IOCTL calls for the RASID driver.
======================================================================= */
#define RASID_READ_DATA _IO(RASID_BASE, 0);
#define RASID_SEND_COMMAND _IOWR(RASID_BASE, 1);
//etc...

/* ==================Init_H=====================================================
 Maximum number of RASIDS
 Currently, the Linux USB core driver allows each loaded driver to control
 a maximum of 16 devices.  This will limit the number of RASIDS attached to
 any system to 16.
======================================================================= */
#define MAX_NUM_RASIDS  16

/* =======================================================================
 Axes per RASID
 The number of Axes each RASID can currently control
======================================================================= */
#define AXES_PER_RASID  1

/* =======================================================================
 Maximum number of Axes
======================================================================= */
#define MAX_NUM_AXES    MAX_NUM_RASIDS*AXES_PER_RASID

/* =======================================================================
USB transfer buffer length
======================================================================= */
#define NUMBER_OF_PACKETS       1
#define TRANSFER_PACKET_SIZE    64      //this is the max packet size
#define TRANSFER_BUFFER_LENGTH  NUMBER_OF_PACKETS*TRANSFER_PACKET_SIZE

/* =======================================================================
RASID USB options
======================================================================= */
#define RCV_ENDPOINT            0x02    //receive endpoint
#define SND_ENDPOINT            0x82    //send endpoint
#define RCV_TIMEOUT             10000   //timeout in jiffies
#define SND_TIMEOUT             10000   //timeout in jiffies
#define ISOC_RCV_INTERVAL       1       //isochronous interval (milliseconds)
#define ISOC_SND_INTERVAL       1       //isochronous interval (millisecodns)
#define RASID_VENDOR_ID         0x0471  //Vendor ID#
#define RASID_PRODUCT_ID        0x0222  //Product ID#
#define RASID_IFNUM             0       //interface # this driver handles
#define RASID_CONF              1       //configuration # this driver handles

#define SND_URB_POOL_SIZE       2
#define RCV_URB_POOL_SIZE       2
#define URB_POOL_SIZE           (SND_URB_POOL_SIZE + RCV_URB_POOL_SIZE)
#define IDLE_SIZE               1
#define MAX_BUFFER_INDEX        2

/* =======================================================================
DevFS file name length

Length of the string holding the filename of a rasid in /dev/
Enough to hold "Rasid" + RasidNum_ + \n
======================================================================= */

//#define FILE_NAME_LENGTH        8

/* =======================================================================
 Debugging option

 Define the symbol DEGUG to enable verbose status logging into /proc/kmsg
 use the dmesg command to read the messages.
======================================================================= */
#define DEBUG

/* =======================================================================
 This macro logs messages to /proc/kmsg if DEBUG is defined.
 The macro "MSG(...)" is simply a shorthand for "printk(KERN_DEBUG ...)"
 when the symbol DEBUG is defined. When DEBUG is not defined,  the
 macro evaluates to NULL (no action taken).
======================================================================= */
#ifdef DEBUG
    #define MSG(string, args...) printk(KERN_INFO string, ##args)
#else
    #define MSG(string, args...)
#endif      //#ifdef DEBUG

/* =======================================================================
min macro
======================================================================= */
#define min(x, y) ((x <= y) ? x : y)

/* =======================================================================
    table of devices that work with the RASID driver
======================================================================= */

static struct usb_device_id rasid_table[] = 
{
    {USB_DEVICE(RASID_VENDOR_ID, RASID_PRODUCT_ID)},
    {}
};
MODULE_DEVICE_TABLE(usb, rasid_table);


/* =======================================================================
Forward declarations
======================================================================= */
struct rasid_dev_context;

static struct usb_driver RasidDriver;
void rasid_rcv_complete(struct urb *purb);
void rasid_snd_complete(struct urb *purb);
void show_urb(purb_t urb);


/* =======================================================================
Forward declarations for _fops
======================================================================= */
ssize_t rasid_read   (struct file *file, char *buf, size_t count, loff_t *offset);
ssize_t rasid_write  (struct file *file, const char *buf, size_t count, loff_t *offset);
int     rasid_ioctl  (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
int     rasid_open   (struct inode *inode, struct file *file);
int     rasid_release(struct inode *inode, struct file *file);
loff_t  rasid_lseek  (struct file *file, loff_t offset, int orig) ;
static struct file_operations rasid_fops;

/* =======================================================================
Global declarations
======================================================================= */
/*this is a global array of rasid device context pointers.  The array is
static, its elements will therefore be initialized to NULL;*/
static struct rasid_dev_context *p_rasid_dev_context[MAX_NUM_RASIDS]={NULL, /*...*/};
static int nNumRasids = 0;        //the number of attached RASID devices;


int write_try = 0;
int slept = 0;
int interrupted = 0;

/* =======================================================================
This is our new custom driver context structure.  It will contain:
pointers to the send and receive URBs and misc. device specific members.
======================================================================= */
struct rasid_dev_context
{
    struct usb_device *rasid_dev;

    __u16 RasidNum; //RaisdNum stores the position of
    //the pointer to the current device context
    //in the global RASID device context pointer array.

    //Example: there exists a global array of pointers
    //to RASID type device context structures:
    //p_rasid_dev_context.  If p_rasid_dev_context[5]
    //points to the current driver context, then
    //RasidNum = 5;

    //This is needed for deallocation purposes in disconnect_rasid();

    purb_t urbs[URB_POOL_SIZE] ;   //urbs for ping-ponging sends and receives
    char    latest_data[TRANSFER_PACKET_SIZE] ;  //buffer for isochronously-read data
    char    latest_sent[TRANSFER_PACKET_SIZE];

    spinlock_t read_lock;
    int        open_ctr;
    char       write_buffer[MAX_BUFFER_INDEX + 1][TRANSFER_PACKET_SIZE];
    int        write_buffer_length[MAX_BUFFER_INDEX + 1];
    int        put_index ;
    int        get_index ; 
    int        accepted;
    int        idle_run;
    int        idle;
    struct semaphore slots;
    //devfs_handle_t devfs;     //handle for node in dev file system
    //char fileName[FILE_NAME_LENGTH];         //file name in dev

    //struct wait_queue * wait;
    /////

    __u32 rcv_pipe;                //receive pipe
    __u32 snd_pipe;                //send pipe
};


/* =======================================================================
int init_module(void)
Non-static declaration here.  This function must be exported to Kernel
space.
======================================================================= */
int init_module(void)
{
    __s16 res;

    res = usb_register(&RasidDriver);
    if (res)
    {
        MSG("RASID driver failed to register.\n");
        return res;
    }
    MSG("RASID driver registered.\n");
    return 0;
}


/* =======================================================================
void cleanup_module(void)
Non static declaration here.  This function must be exported to Kernel
space.
======================================================================= */
void cleanup_module(void)
{
    MSG("Closing RASID driver.\n");
    usb_deregister(&RasidDriver);
}


static void unlink_open_urbs(struct rasid_dev_context *context)
{
    purb_t purb ;
    int    i    ;
    int    status ;

    if (context)
    {
        for (i = 0; i < URB_POOL_SIZE; i++)
        {
            purb = context->urbs[i];
            show_urb(purb);
            if (purb->status)
            {
                status = usb_unlink_urb(purb);
            }
        }
    }
}

/* =======================================================================
static void disconnect_rasid(struct usb_device*, void *)

In the function, we must de-allocate all resources previously allocated
in probe_rasid
======================================================================= */
static void disconnect_rasid(struct usb_device *dev, void *drv_context)
{
    struct rasid_dev_context *context = (struct rasid_dev_context*)drv_context;
    purb_t purb ;
    int i;

    if (context)
    {
        unlink_open_urbs(context);

        //free the URB pool
        for (i = 0; i < URB_POOL_SIZE; i++)
        {
            purb = context->urbs[i];
            kfree(purb->transfer_buffer) ;
            usb_free_urb(purb);
        }

        //free the appropriate slot in the global context pointer array
        //NULL implies the slot is available
        if (p_rasid_dev_context[context->RasidNum])
            p_rasid_dev_context[context->RasidNum] = NULL;

	//unregister with devFS
	//devfs_unregister(context->devfs);
	

        MSG("Disconnecting device with Major# %d and Minor# %d...\n", RASID_MAJOR, context->RasidNum + RASID_BASE_MINOR);
        //de-allocate space for the device context
        kfree(context);

        nNumRasids--;
        MSG("Number of RASIDs in system: %d\n", nNumRasids);
    }
    return;
}


/* =======================================================================
ssize_t rasid_read(struct file *file, char *buf, size_t count, loff_t *offset)

All inputs from RASID to the driver is through endpoint #82 which is
setup for 64-byte isochronous transfers (IN)
======================================================================= */
ssize_t rasid_read(struct file *file, char *buf, size_t count, loff_t *offset)
{
    struct rasid_dev_context *context = (struct rasid_dev_context *)file->private_data;
    unsigned long irqflags;

    //DANGER - should not use spinlocks copying to user space
    spin_lock_irqsave(&(context->read_lock), irqflags);
    count = min(count, TRANSFER_PACKET_SIZE);
    //DANGER - memcopy assumes program code is not paged out aka  enough memory
    memcpy(buf, context->latest_data, count);

    spin_unlock_irqrestore(&(context->read_lock), irqflags);
    return count;

    return 0 ;
}

/* =======================================================================
RASID URB transfer callback routine
======================================================================= */
void rasid_rcv_complete(purb_t purb)
{
    struct rasid_dev_context *context = (struct rasid_dev_context*)(purb->context);

   //  MSG("recieved a message at %ul .\n", jiffies);
    memcpy(context->latest_data, purb->transfer_buffer, TRANSFER_PACKET_SIZE);
}

/* =======================================================================
ssize_t rasid_write(struct file *file, const char *buf, size_t count, loff_t *offset)

All outputs from the driver to RASID is through endpoint #02 which is
setup for 64-byte isochronous transfers (OUT)
======================================================================= */
ssize_t rasid_write(struct file *file, const char *buf, size_t count, loff_t *offset)
{
    struct rasid_dev_context *context = (struct rasid_dev_context*) file->private_data ;
    int writecount = 0 ;
    int next_index ;
    int sem_return ;

    write_try++;

/*    if( sem_return = down_trylock(&context->slots))
	{
	slept++;
 	sem_return = down_interruptible(&context->slots) ;
 	}
*/

sem_return = down_interruptible(&context->slots) ;

    if (sem_return < 0) 
	{
	  interrupted ++;
	  return sem_return;  // Interrupted by a signal

        }
    
    next_index = (context->put_index + 1) % MAX_BUFFER_INDEX ;

    if ( next_index != context->get_index)  
    {
        writecount = min(count, TRANSFER_PACKET_SIZE) ;
        memcpy(context->write_buffer[context->put_index], buf, writecount);
        context->write_buffer_length[context->put_index] = writecount;
        context->put_index = next_index ;
    }
    else
    	MSG("Inconceivable! Reached end of buffer\n");
    return writecount;
}


/* =======================================================================
RASID URB transfer callback routine
======================================================================= */
void rasid_snd_complete(struct urb *purb)
{

    unsigned long irqflags;
    struct rasid_dev_context *context = (struct rasid_dev_context*)(purb->context);
    struct timeval tv; //ANTON CHANGE


    // save the last non-idle message sent (for monitoring purposes)
    if (*(char *)purb->transfer_buffer != (char)0xff)
    {
        spin_lock_irqsave(&(context->read_lock), irqflags);
        memcpy(context->latest_sent, 
               purb->transfer_buffer, 
               TRANSFER_PACKET_SIZE);
        spin_unlock_irqrestore(&(context->read_lock), irqflags);
    }
        
 
    if (context->get_index != context->put_index)
    {
       // move the data from the queue into the packet
        memcpy(purb->transfer_buffer, 
               context->write_buffer[context->get_index], 
               context->write_buffer_length[context->get_index]);

        context->accepted++;
        context->get_index = (context->get_index + 1) % MAX_BUFFER_INDEX ;
	do_gettimeofday(&tv);
	printk(KERN_DEBUG "INT %d\n", tv.tv_usec); //ANTON CHANGE
	up(&context->slots);
    }
    else
    {
        context->idle++;
        *(char *)purb->transfer_buffer = (char)0xff;
    }


    // display some statistics every 1000 packets


    if ((context->idle + context->accepted) == 100)
    {
        if(context->idle) 
        {
            /*MSG ("Idle %d packets out of 100  (After run of %d)\n", 
                context->idle, context->idle_run);
	    MSG("Wrote %d times\nSlept %d times\nInterrupted %d times\n\n", 
		write_try, slept, interrupted);*/
            context->idle_run = 0;
        }
        else
        {
            context->idle_run++;
        }
        context->idle     = 0;
        context->accepted = 0;
    }

	
    return;
}

/* =======================================================================
int rasid_open(struct inode *inode, struct file *file)

======================================================================= */

int rasid_open(struct inode *inode, struct file *file)
{
    int i;
    int ret_code ;
    int rcv_start ;
    unsigned long irqflags;

    int rasidNum = MINOR(inode->i_rdev) - RASID_BASE_MINOR;

    struct rasid_dev_context *context = p_rasid_dev_context[rasidNum] ;

    MSG("Opening rasid num: %d\n", rasidNum);
    file->private_data = (void *) context;

    spin_lock_irqsave(&(context->read_lock), irqflags);
    if (!context->open_ctr)    
    {
        // this is the only(first) app to open this device
        
        ///// set the free buffer to the first one
        context->put_index = 0 ;
        context->get_index = 0 ;

        // init statistics
        context->accepted  = 0;
        context->idle      = 0;
        context->idle_run  = 0;

        //context->wait      = NULL ;
        sema_init(&context->slots, MAX_BUFFER_INDEX - 1);

        // set up the ping-pong urbs for empty sends
        for (i = 0; i < SND_URB_POOL_SIZE; i++)
        {
            context->urbs[i]->iso_frame_desc[0].length = TRANSFER_PACKET_SIZE;  
            context->urbs[i]->transfer_buffer_length   = TRANSFER_PACKET_SIZE;
            *(char *)context->urbs[i]->transfer_buffer = (char) 0xff;  // idle packet
            context->urbs[i]->next = context->urbs[(i+1) % SND_URB_POOL_SIZE] ;
        }

        // set up the ping-pong urbs for isochronous receives
        rcv_start = SND_URB_POOL_SIZE ;
        for (i = 0; i < RCV_URB_POOL_SIZE; i++)
        {
            context->urbs[i+rcv_start]->iso_frame_desc[0].length = TRANSFER_PACKET_SIZE;  
            context->urbs[i+rcv_start]->transfer_buffer_length   = TRANSFER_PACKET_SIZE;
            context->urbs[i+rcv_start]->next = 
            context->urbs[((i+1) % RCV_URB_POOL_SIZE) + rcv_start] ;
        }



        for (i = 0; i < URB_POOL_SIZE; i++)
        {
            context->urbs[i]->dev = context->rasid_dev;
            ret_code = usb_submit_urb(context->urbs[i]);
            show_urb(context->urbs[i]);
            if (ret_code)
            {
                MSG("Rasid open: urb submit failed: %d\n", ret_code);
                return ret_code;
            }
            //MSG("usb_submit_urb\n");
        }



    }
    context->open_ctr++;
    spin_unlock_irqrestore(&(context->read_lock), irqflags);

    MOD_INC_USE_COUNT;
    return 0;
}

/* =======================================================================
======================================================================= */
int rasid_release(struct inode *inode, struct file *file)
{
    int RasidNum ;
    unsigned long irqflags;
    struct rasid_dev_context *context ;
    RasidNum = MINOR(inode->i_rdev) - RASID_BASE_MINOR;

    MSG("Releasing rasid num: %d\n", RasidNum);
    context  = p_rasid_dev_context[RasidNum] ;
    //MSG("Idle run: %d\n", context->idle_run);   
    MSG("RASID closing\n");
    
    spin_lock_irqsave(&(context->read_lock), irqflags);
    context->open_ctr--;
    if (!context->open_ctr)
    {
        unlink_open_urbs(context) ;
    }
    spin_unlock_irqrestore(&(context->read_lock), irqflags);

    MOD_DEC_USE_COUNT;
    return 0;
}


/* =======================================================================
int rasid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
======================================================================= */
int rasid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
    return 0;
}


/* =======================================================================
loff_t     rasid_lseek(struct inode *inode, struct file *file, off_t offset, int orig) ;
======================================================================= */
loff_t rasid_lseek(struct file *file, loff_t offset, int orig)
{
    return 0;
}


/* =======================================================================

======================================================================= */
static void *probe_rasid(struct usb_device *dev, 
                         unsigned int ifnum,
                         const struct usb_device_id *id_table)
{

    int i, j;
    struct rasid_dev_context *context ;
    purb_t purb ;
    //devfs_handle_t oldNode = NULL;

    //__s16 x;
    __u16 RasidNum_;    //If the probing device is a RASID, RasidNum_
                        //will be its position in the global driver
                        //context array. This is needed for
                        //de-allocation in disconnect_rasid();

    //besides the Vendor ID and the Product ID, we should check the
    //interface number
    if (dev->descriptor.idVendor  == RASID_VENDOR_ID &&
        dev->descriptor.idProduct == RASID_PRODUCT_ID)
    {
        //may want to check the configuration # also
        MSG("A CAMotion RASID device has been connected!\n");
        if( ifnum != RASID_IFNUM) goto p0;  //no match
    }
    else goto p0;        //no match

    if (nNumRasids == MAX_NUM_RASIDS)
    {
        MSG("All minor numbers are assigned.\n");
        goto p0;        //no more minor devices remaining
    }

    //find the next available minor number
    for (RasidNum_ = 0; RasidNum_ < MAX_NUM_RASIDS; RasidNum_++)
    {
        if (!p_rasid_dev_context[RasidNum_]) break;  //found an un-allocated driver context
    }

    //allocate space for the device context
    if (!(p_rasid_dev_context[RasidNum_] = kmalloc(sizeof(struct rasid_dev_context), GFP_KERNEL)) )
    {
        MSG("Out of memory while allocating space for the device context.\n");
        goto p0;
    }
    context = p_rasid_dev_context[RasidNum_] ;
    memset(context, 0, sizeof(struct rasid_dev_context));

    context->RasidNum  = RasidNum_;  //store the position w/in the global table permanently
    context->rasid_dev = dev;        //store the usb part of the driver context
    spin_lock_init(&(context->read_lock));

    usb_set_configuration(context->rasid_dev, RASID_CONF);
    usb_set_interface    (context->rasid_dev, RASID_IFNUM, 0);

    //
    //next, create the input and output pipes
    //
    context->rcv_pipe = usb_rcvisocpipe(context->rasid_dev, RCV_ENDPOINT );
    context->snd_pipe = usb_sndisocpipe(context->rasid_dev, SND_ENDPOINT );

    //
    // Create a pool of URBs for later usage
    //
    for (i = 0; i < URB_POOL_SIZE; i++)
    {
        //first, allocate the URBs
        if( (purb = (purb_t)usb_alloc_urb(NUMBER_OF_PACKETS)) == NULL )
        {
            MSG("Error allocating URB.\n");
            goto p1;    //de-allocate buffer
        }

        context->urbs[i] = purb ;
        memset(purb, 0, sizeof(urb_t));

        //
        //fill in the URB
        //
        purb->dev                    = context->rasid_dev;
        purb->transfer_flags         = USB_ISO_ASAP | USB_ASYNC_UNLINK;
        purb->number_of_packets      = NUMBER_OF_PACKETS;   //iso only
        purb->context                = context;             //pointer to the URB's parent device context
        purb->transfer_buffer_length = TRANSFER_BUFFER_LENGTH;
        if (i < SND_URB_POOL_SIZE)                          //setup a send URB
        {
            purb->pipe     = context->snd_pipe;
            purb->interval = ISOC_SND_INTERVAL;
            purb->timeout  = SND_TIMEOUT;
            purb->complete = rasid_snd_complete;
        }
        else                                               //setup a receive URB
        {
            purb->pipe     = context->rcv_pipe;
            purb->interval = ISOC_RCV_INTERVAL;
            purb->timeout  = RCV_TIMEOUT;
            purb->complete = rasid_rcv_complete;
        }
        for (j = 0; j < NUMBER_OF_PACKETS; j++)
        {
            purb->iso_frame_desc[j].offset = (TRANSFER_PACKET_SIZE) * j ;
            purb->iso_frame_desc[j].length = TRANSFER_PACKET_SIZE ;
        }

        if(!(purb->transfer_buffer = (char*)kmalloc(TRANSFER_BUFFER_LENGTH, GFP_KERNEL)) )
        {
            MSG("Out of memory while allocating I/O buffer.\n");
            goto p1;        //de-allocate entire driver context
        }
    }


    //
    //all is well, increment the number of RASIDS attached by one
    //


    nNumRasids++;
    MSG("Number of RASIDs in system: %d\n", nNumRasids);
    MSG("Current device has major# %u and Minor# %u.\n", RASID_MAJOR, RasidNum_ + RASID_BASE_MINOR);

    //
    // make the file in the dev filesystem
    //

/*===========================Unused DevFS Code==================================
    sprintf(context->fileName, "rasid%d", RasidNum_);
    oldNode = (devfs_handle_t) get_root_entry();
    if(oldNode)
	{
	   MSG("found root entry\n");
	}
    oldNode =  devfs_find_handle (NULL, 
				  "rasid1", 
				  (unsigned int) NULL, 
				  (unsigned int) NULL, 
				  DEVFS_SPECIAL_CHR, 
				  1);   
    if( oldNode )
     {
	MSG("Removing old node from /dev/%s", context->fileName);
	devfs_unregister(oldNode);
     }

    context->devfs =  devfs_register (NULL, 
				      context->fileName,
				      DEVFS_FL_DEFAULT,
				      RASID_MAJOR, 
				      RasidNum_ + RASID_BASE_MINOR,
				      S_IFCHR | S_IRUSR | S_IWUSR |
				      S_IRGRP | S_IWGRP | S_IROTH, 
				      &rasid_fops, 
				      NULL);

    if( !context->devfs )
      {
	MSG("Unable to create rasid file in /dev/.\n");
 	MSG("name: %s %d\n", context->fileName, context->devfs);
      }

==========================================================================*/


    return context;                 //return the driver context structure

p1: kfree(context);                 //Free Device context
    MSG("Device context freed.\n");
p0: return NULL;                    //Call failed
}


/* =======================================================================
static struct file_operations rasid_fops
======================================================================= */
static struct file_operations rasid_fops=
{
    owner:   THIS_MODULE,
    llseek:  rasid_lseek,
    read:    rasid_read,
    write:   rasid_write,
    ioctl:   rasid_ioctl,
    open:    rasid_open,
    release: rasid_release

};

void show_urb(purb_t purb)
{
    return;   //  Short circuit
    
    MSG("Status      : %10d    Actual length: %8d\n", purb->status, purb->actual_length);
    MSG("Address     : %10p             Next: %p\n", purb, purb->next);
    MSG("Start frame : %10d      Error count: %8d   Frame length: %d\n", 
            purb->start_frame, purb->error_count, purb->iso_frame_desc[0].length);
    MSG("Dev     : %10p\n\n", purb->dev);

}
/* =======================================================================
static struct usb_driver RasidDriver
======================================================================= */
static struct usb_driver RasidDriver=
{
    name:       "rasid",
    probe:      probe_rasid,
    disconnect: disconnect_rasid,
    fops:       &rasid_fops,
    minor:      RASID_BASE_MINOR,
    id_table:   rasid_table,
};


/* =======================================================================
Signal Values.

The values of a few signals are listed here only as an aid in debugging.
These can be found in usr/include/asm/errno.h and usr/include/linux/errno.h.

ENOMEM    =  12
ENXIO     =   6
EINVAL    =  22   //Log off and go home
EAGAIN    =  11
EFBIG     =  27
EPIPE     =  32
EMSGSIZE  =  90
ENOENT    =   2
EILSEQ    =  84   //illegal byte sequence
ETIMEDOUT = 110   //connection timed out
======================================================================= */




Reply via email to