Linux-2.4.0-test22.4.0-test2
authorLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:56 +0000 (23 15:35 -0500)
committerLinus Torvalds<torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:56 +0000 (23 15:35 -0500)
There's a "test2" kernel out there now, integrating most of the -ac
patches, and some code that wasn't in -ac.

Normally, when you integrate almost 5MB of patches, bad things happen.
This time, a miracle occurred. As I uploaded the resultant kernel, a
specter of the holy penguin appeared before me, and said "It is Good. It
is Bugfree".

As if wanting to re-assure me that yes, it really =was= the holy penguin,
it finally added "Do you have any Herring?" before fading out in a puff of
holy penguin-smoke. Only a faint whiff of rancid fish remains as I type in
these words..

In short, not only are most of Alan's patches integrated, I have it on
higher authority that the result is perfect.

So if it doesn't compile for you, you must be doing something wrong.

Linus

50 files changed:
Documentation/cpqarray.txt
MAINTAINERS
arch/ia64/kernel/mca.c
arch/ia64/kernel/ptrace.c
arch/sparc64/kernel/binfmt_aout32.c
arch/sparc64/kernel/sys_sparc32.c
drivers/block/cpqarray.c
drivers/block/ida_cmd.h
drivers/block/smart1,2.h
drivers/net/Config.in
drivers/usb/Config.in
drivers/usb/devio.c
drivers/usb/evdev.c
drivers/usb/joydev.c
drivers/usb/mousedev.c
drivers/usb/pegasus.c
drivers/usb/serial/usbserial.c
drivers/usb/serial/visor.c
drivers/usb/usb-storage.c
drivers/usb/usb-storage.h
drivers/video/Config.in
drivers/video/sisfb.c
fs/binfmt_elf.c
fs/exec.c
fs/lockd/svc.c
fs/lockd/svcsubs.c
fs/lockd/xdr.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/nfs3proc.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfsd/export.c
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfscache.c
fs/nfsd/nfsfh.c
fs/nfsd/nfsxdr.c
fs/nfsd/vfs.c
include/asm-i386/bugs.h
include/asm-i386/io_apic.h
include/asm-ia64/pgtable.h
include/linux/capability.h
include/linux/fb.h
include/linux/pci_ids.h
init/main.c
kernel/capability.c
kernel/kmod.c
kernel/sysctl.c

index 45a5321..67db480 100644 (file)
@@ -1,11+1,5 @@
 This driver is for Compaq's SMART2 Intellegent Disk Array Controllers.
 
-WARNING:
---------
-
-This driver comes with NO WARRANTY.  It is not officially supported by
-Compaq.  Do not call technical support.  Use at your own risk.
-
 Supported Cards:
 ----------------
 
@@ -22,6+16,7 @@ This driver is known to work with the following cards:
        * Integrated Smart Array Controller
        * SA 4200
        * SA 4250ES
+       * SA 431
 
 It should also work with some really old Disk array adapters, but I am
 unable to test against these cards:
index 634e370..6ce7ccf 100644 (file)
@@ -199,8+199,9 @@ S:  Maintained
 COMPAQ SMART2 RAID DRIVER
 P:     Charles White   
 M:     Charles White <arrays@compaq.com>
-L:     compaqandlinux@yps.org  
-S:     Maintained
+L:     compaqandlinux@cpqlin.van-dijk.net
+W:     ftp.compaq.com/pub/products/drivers/linux
+S:     Supported       
 
 COMPUTONE INTELLIPORT MULTIPORT CARD
 P:     Doug McNash
index e6daa58..003b8dd 100644 (file)
@@ -9,9+9,11 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) Vijay Chander(vijay@engr.sgi.com)
  *
- * 00/03/29 C. Fleckenstein  Fixed PAL/SAL update issues, began MCA bug fixes, logging issues, 
+ * 00/03/29 C. Fleckenstein  Fixed PAL/SAL update issues, began MCA bug fixes,
+ *                           logging issues, 
  *                           added min save state dump, added INIT handler. 
  */
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/sched.h>
index b050603..0efd42b 100644 (file)
@@ -7,6+7,7 @@
  * Derived from the x86 and Alpha versions.  Most of the code in here
  * could actually be factored into a common set of routines.
  */
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/mm.h>
index 9cc2402..4460729 100644 (file)
@@ -277,20+277,24 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                        goto beyond_if;
                }
 
+               down(&current->mm->mmap_sem);
                error = do_mmap(bprm->file, N_TXTADDR(ex), ex.a_text,
                        PROT_READ | PROT_EXEC,
                        MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
                        fd_offset);
+               up(&current->mm->mmap_sem);
 
                if (error != N_TXTADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
                }
 
+               down(&current->mm->mmap_sem);
                error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data,
                                PROT_READ | PROT_WRITE | PROT_EXEC,
                                MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE,
                                fd_offset + ex.a_text);
+               up(&current->mm->mmap_sem);
                if (error != N_DATADDR(ex)) {
                        send_sig(SIGKILL, current, 0);
                        return error;
index 3e3e391..26c5fae 100644 (file)
@@ -1,4+1,4 @@
-/* $Id: sys_sparc32.c,v 1.151 2000/06/22 11:42:25 davem Exp $
+/* $Id: sys_sparc32.c,v 1.152 2000/06/22 17:44:47 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -3778,8+3778,6 @@ static int nfs_getfh32_res_trans(union nfsctl_res *kres, union nfsctl_res32 *res
        return copy_to_user(res32, kres, sizeof(*res32));
 }
 
-extern asmlinkage int sys_nfsservctl(int cmd, void *arg, void *resp);
-
 int asmlinkage sys32_nfsservctl(int cmd, struct nfsctl_arg32 *arg32, union nfsctl_res32 *res32)
 {
        struct nfsctl_arg *karg = NULL;
index 40e6398..9bbe505 100644 (file)
  *    driver, you'll probably need the Compaq Array Controller Interface
  *    Specificiation (Document number ECG086/1198)
  */
-#include <linux/config.h>
+#include <linux/config.h>      /* CONFIG_PROC_FS */
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/types.h>
 
 #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 1.0.4)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(1,0,4)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 2.4.0)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(2,4,0)
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
 #include <linux/blk.h>
 #include <linux/blkdev.h>
@@ -73,7+73,7 @@ static int eisa[8] = { 0, 0 ,0 ,0, 0, 0 ,0 ,0 };
  *  product = Marketing Name for the board
  *  access = Address of the struct of function pointers 
  */
-struct board_type products[] = {
+static struct board_type products[] = {
        { 0x0040110E, "IDA",                    &smart1_access },
        { 0x0140110E, "IDA-2",                  &smart1_access },
        { 0x1040110E, "IAES",                   &smart1_access },
@@ -87,6+87,7 @@ struct board_type products[] = {
        { 0x40400E11, "Integrated Array",       &smart4_access },
        { 0x40500E11, "Smart Array 4200",       &smart4_access },
        { 0x40510E11, "Smart Array 4250ES",     &smart4_access },
+       { 0x40580E11, "Smart Array 431",        &smart4_access },
 };
 
 static struct hd_struct * ida;
@@ -95,7+96,7 @@ static int * ida_blocksizes;
 static int * ida_hardsizes;
 static struct gendisk ida_gendisk[MAX_CTLR];
 
-struct proc_dir_entry *proc_array = NULL;
+static struct proc_dir_entry *proc_array = NULL;
 
 /* Debug... */
 #define DBG(s) do { s } while(0)
@@ -106,7+107,7 @@ struct proc_dir_entry *proc_array = NULL;
 /* Debug Extra Paranoid... */
 #define DBGPX(s) do { } while(0)
 
-void cpqarray_init(void);
+int cpqarray_init(void);
 static int cpqarray_pci_detect(void);
 static int cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn);
 static ulong remap_pci_mem(ulong base, ulong size);
@@ -312,9+313,8 @@ EXPORT_NO_SYMBOLS;
 /* This is a bit of a hack... */
 int __init init_module(void)
 {
-       cpqarray_init();
-       if (nr_ctlr == 0)
-               return -EIO;
+       if (cpqarray_init() == 0) /* all the block dev numbers already used */
+               return -EIO;      /* or no controllers were found */
        return 0;
 }
 
@@ -357,8+357,9 @@ void cleanup_module(void)
 /*
  *  This is it.  Find all the controllers and register them.  I really hate
  *  stealing all these major device numbers.
+ *  returns the number of block devices registered.
  */
-void __init cpqarray_init(void)
+int __init cpqarray_init(void)
 {
        void (*request_fns[MAX_CTLR])(request_queue_t *) = {
                do_ida_request0, do_ida_request1,
@@ -367,31+368,52 @@ void __init cpqarray_init(void)
                do_ida_request6, do_ida_request7,
        };
        int i,j;
+       int num_cntlrs_reg = 0;
 
        /* detect controllers */
        cpqarray_pci_detect();
        cpqarray_eisa_detect();
        
        if (nr_ctlr == 0)
-               return;
+               return(num_cntlrs_reg);
 
        printk(DRIVER_NAME "\n");
        printk("Found %d controller(s)\n", nr_ctlr);
 
        /* allocate space for disk structs */
        ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
-       
        if(ida==NULL)
-               goto bail;
-       ida_sizes =      kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
+       {
+               printk( KERN_ERR "cpqarray: out of memory");
+               return(num_cntlrs_reg);
+       }
+       
+       ida_sizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
        if(ida_sizes==NULL)
-               goto bail2;
+       {
+               kfree(ida); 
+               printk( KERN_ERR "cpqarray: out of memory");
+               return(num_cntlrs_reg);
+       }
+
        ida_blocksizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
        if(ida_blocksizes==NULL)
-               goto bail3;
-       ida_hardsizes =  kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
+       {
+               kfree(ida);
+               kfree(ida_sizes); 
+               printk( KERN_ERR "cpqarray: out of memory");
+               return(num_cntlrs_reg);
+       }
+
+       ida_hardsizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
        if(ida_hardsizes==NULL)
-               goto bail4;
+       {
+               kfree(ida);
+               kfree(ida_sizes); 
+               kfree(ida_blocksizes);
+               printk( KERN_ERR "cpqarray: out of memory");
+               return(num_cntlrs_reg);
+       }
 
        memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
        memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16);
@@ -399,74+421,90 @@ void __init cpqarray_init(void)
        memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16);
        memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);
 
-       /* 
+               /* 
         * register block devices
         * Find disks and fill in structs
         * Get an interrupt, set the Q depth and get into /proc
         */
        for(i=0; i< nr_ctlr; i++) {
+               /* If this successful it should insure that we are the only */
+               /* instance of the driver */    
+               if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
+                        printk(KERN_ERR "cpqarray: Unable to get major number %d for ida\n",
+                                MAJOR_NR+i);
+                        continue;
+                }
+
+       
                hba[i]->access.set_intr_mask(hba[i], 0);
                if (request_irq(hba[i]->intr, do_ida_intr,
                        SA_INTERRUPT|SA_SHIRQ, hba[i]->devname, hba[i])) {
 
-                       printk("Unable to get irq %d for %s\n", 
+                       printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n", 
                                hba[i]->intr, hba[i]->devname);
+                       unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
                        continue;
                }
-               if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
-                       printk("Unable to get major number %d for ida\n",
-                               MAJOR_NR+i);
-                       continue;
-               }
-
+               num_cntlrs_reg++;
                hba[i]->cmd_pool = (cmdlist_t *)kmalloc(
                                NR_CMDS * sizeof(cmdlist_t), GFP_KERNEL);
                hba[i]->cmd_pool_bits = (__u32*)kmalloc(
                                ((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
                
-               if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
+       if(hba[i]->cmd_pool_bits == NULL || hba[i]->cmd_pool == NULL)
                {
-                       int j;
+                       nr_ctlr = i; 
                        if(hba[i]->cmd_pool_bits)
                                kfree(hba[i]->cmd_pool_bits);
                        if(hba[i]->cmd_pool)
                                kfree(hba[i]->cmd_pool);
-                       for(j=0;i<i;j++)
-                       {
-                               free_irq(hba[j]->intr, hba[j]);
-                               unregister_blkdev(MAJOR_NR+j, hba[j]->devname);
-                               kfree(hba[j]->cmd_pool_bits);
-                               kfree(hba[j]->cmd_pool);
-                       }
                        free_irq(hba[i]->intr, hba[i]);
                        unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
-                       goto bail5;
+                       num_cntlrs_reg--;
+                       printk( KERN_ERR "cpqarray: out of memory");
+
+                       /* If num_cntlrs_reg == 0, no controllers worked. 
+                        *      init_module will fail, so clean up global 
+                        *      memory that clean_module would do.
+                       */      
+       
+                       if (num_cntlrs_reg == 0) 
+                       {
+                               kfree(ida);
+                               kfree(ida_sizes);
+                               kfree(ida_hardsizes);
+                               kfree(ida_blocksizes);
+                       }
+                       return(num_cntlrs_reg);
+       
                }
                memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
                memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));
-               printk("Finding drives on %s", hba[i]->devname);
+               printk(KERN_INFO "cpqarray: Finding drives on %s", 
+                       hba[i]->devname);
                getgeometry(i);
                start_fwbk(i); 
 
                hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);
 
+
                ida_procinit(i);
-       
-               blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i), request_fns[i]);
-               blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 0);
 
+               blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 
+                       request_fns[i]);                
+               blk_queue_headactive(BLK_DEFAULT_QUEUE(MAJOR_NR + i), 0);
                blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
                hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
-
                read_ahead[MAJOR_NR+i] = READ_AHEAD;
+
                ida_gendisk[i].major = MAJOR_NR + i;
                ida_gendisk[i].major_name = "ida";
                ida_gendisk[i].minor_shift = NWD_SHIFT;
                ida_gendisk[i].max_p = 16;
                ida_gendisk[i].part = ida + (i*256);
                ida_gendisk[i].sizes = ida_sizes + (i*256);
-               /* ida_gendisk[i].nr_real is handled by getgeometry */
-
+               ida_gendisk[i].nr_real = 0; 
+       
                /* Get on the disk list */
                ida_gendisk[i].next = gendisk_head;
                gendisk_head = &ida_gendisk[i];
@@ -479,21+517,13 @@ void __init cpqarray_init(void)
 
                ida_geninit(i);
                for(j=0; j<NWD; j++)    
-                       register_disk(&ida_gendisk[i], MKDEV(MAJOR_NR+i,j<<4),
-                                       16, &ida_fops, hba[i]->drv[j].nr_blks);
+                       register_disk(&ida_gendisk[i], 
+                               MKDEV(MAJOR_NR+i,j<<4),
+                               16, &ida_fops, hba[i]->drv[j].nr_blks);
+
        }
        /* done ! */
-       return;
-bail5:
-       kfree(ida_hardsizes);
-bail4:
-       kfree(ida_blocksizes);
-bail3:
-       kfree(ida_sizes);
-bail2:
-       kfree(ida);
-bail:
-       printk(KERN_ERR "cpqarray: out of memory.\n");
+       return(num_cntlrs_reg);
 }
 
 /*
@@ -506,103+536,68 @@ static int cpqarray_pci_detect(void)
 {
        int index;
        unchar bus=0, dev_fn=0;
-       
-       /* This seems dumb, surely we could use an array of types to match ?? */
-
-       for(index=0; ; index++) {
-               if (pcibios_find_device(PCI_VENDOR_ID_DEC,
-                        PCI_DEVICE_ID_COMPAQ_42XX, index, &bus, &dev_fn))
-                       break;
-               printk(KERN_DEBUG "42XX Device has been found at %x %x\n",
-                               bus, dev_fn);
-               if (index == 1000000) break;
-               if (nr_ctlr == 8) {
-                       printk("This driver supports a maximum of "
-                               "8 controllers.\n");
-                       break;
-               }
-               
-               hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-               if(hba[nr_ctlr]==NULL)
-               {
-                       printk(KERN_ERR "cpqarray: out of memory.\n");
-                       continue;
-               }
-               memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-               if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
-                       continue;
-               sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-               hba[nr_ctlr]->ctlr = nr_ctlr;
-               nr_ctlr++;
-       }
-
-       for(index=0; ; index++) {
-               unsigned short subvendor=0;
 
-                if (pcibios_find_device(PCI_VENDOR_ID_NCR,
-                         PCI_DEVICE_ID_NCR_53C1510, index, &bus, &dev_fn))
-                        break;
-                printk(KERN_DEBUG "Integrated RAID Chip has been found at %x %x\n",
-                                bus, dev_fn);
-               if(pcibios_read_config_word(bus, dev_fn, 
-                       PCI_SUBSYSTEM_VENDOR_ID, &subvendor))   
-               {
-                       printk(KERN_DEBUG "cpqarray failed to read subvendor\n");
-                       break;
-               }
-               if(subvendor !=  PCI_VENDOR_ID_COMPAQ)
-                       break;
-               printk(KERN_DEBUG "Its a compaq RAID Chip\n");
-                if (index == 1000000) break;
-                if (nr_ctlr == 8) {
-                        printk("This driver supports a maximum of "
-                                "8 controllers.\n");
-                        break;
-                }
+#define IDA_BOARD_TYPES 3
+       static int ida_vendor_id[IDA_BOARD_TYPES] = { PCI_VENDOR_ID_DEC, 
+               PCI_VENDOR_ID_NCR, PCI_VENDOR_ID_COMPAQ };
+       static int ida_device_id[IDA_BOARD_TYPES] = { PCI_DEVICE_ID_COMPAQ_42XX,                PCI_DEVICE_ID_NCR_53C1510, PCI_DEVICE_ID_COMPAQ_SMART2P };
+       int brdtype;
+       
+       /* search for all PCI board types that could be for this driver */
+       for(brdtype=0; brdtype<IDA_BOARD_TYPES; brdtype++)
+       {
+               for(index=0; ; index++) {
+                       if (pcibios_find_device(ida_vendor_id[brdtype],
+                               ida_device_id[brdtype], index, &bus, &dev_fn))
+                               break;
+                       printk(KERN_DEBUG "cpqarray: Device %x has been found at %x %x\n",
+                               ida_vendor_id[brdtype], bus, dev_fn);
+                       if (index == 1000000) break;
+                       if (nr_ctlr == 8) {
+                               printk(KERN_WARNING "cpqarray: This driver"
+                               " supports a maximum of 8 controllers.\n");
+                               break;
+                       }
 
-                hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-                if(hba[nr_ctlr]==NULL)
-                {
-                       printk(KERN_ERR "cpqarray: out of memory.\n");
-                       continue;
-                }
-                memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-                /* DOESNT THIS LEAK MEMORY ?????? - AC */
-                if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
-                        continue;
-                sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-                hba[nr_ctlr]->ctlr = nr_ctlr;
-                nr_ctlr++;
-        }
+/* if it is a PCI_DEVICE_ID_NCR_53C1510, make sure it's                                the Compaq version of the chip */ 
+
+                       if (ida_device_id[brdtype] == PCI_DEVICE_ID_NCR_53C1510)                        {       
+                               unsigned short subvendor=0;
+                               if(pcibios_read_config_word(bus, dev_fn, 
+                                       PCI_SUBSYSTEM_VENDOR_ID, &subvendor))
+                               {
+                                       printk(KERN_DEBUG "cpqarray: failed to read subvendor\n");
+                                       continue;
+                               }
+                               if(subvendor !=  PCI_VENDOR_ID_COMPAQ)
+                               {
+                                       printk(KERN_DEBUG 
+                                               "cpqarray: not a Compaq integrated array controller\n");
+                                       continue;
+                               }
+                       }
 
-       for(index=0; ; index++) {
-               if (pcibios_find_device(PCI_VENDOR_ID_COMPAQ,
-                       PCI_DEVICE_ID_COMPAQ_SMART2P, index, &bus, &dev_fn))
-                       break;
+                       hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);                        if(hba[nr_ctlr]==NULL)
+                       {
+                               printk(KERN_ERR "cpqarray: out of memory.\n");
+                               continue;
+                       }
+                       memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
+                       if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
+                       {
+                               kfree(hba[nr_ctlr]);
+                               continue;
+                       }
+                       sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
+                       hba[nr_ctlr]->ctlr = nr_ctlr;
+                       nr_ctlr++;
 
-               if (index == 1000000) break;
-               if (nr_ctlr == 8) {
-                       printk("This driver supports a maximum of "
-                               "8 controllers.\n");
-                       break;
                }
-               
-               hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
-               if(hba[nr_ctlr]==NULL)
-                {
-                       printk(KERN_ERR "cpqarray: out of memory.\n");
-                       continue;
-                }
-               memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
-               if (cpqarray_pci_init(hba[nr_ctlr], bus, dev_fn) != 0)
-                       continue;
-               sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
-               hba[nr_ctlr]->ctlr = nr_ctlr;
-               nr_ctlr++;
        }
 
        return nr_ctlr;
 }
+
 /*
  * Find the IO address of the controller, its IRQ and so forth.  Fill
  * in some basic stuff into the ctlr_info_t structure.
@@ -671,8+666,9 @@ DBGINFO(
                }
        }
        if (i == NR_PRODUCTS) {
-               printk("Sorry, I don't know how to access the SMART Array"
-                       " controller %08lx\n", (unsigned long)board_id);
+               printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
+                       " to access the SMART Array controller %08lx\n", 
+                               (unsigned long)board_id);
                return -1;
        }
 
@@ -734,8+730,8 @@ static int cpqarray_eisa_detect(void)
 
        while(i<8 && eisa[i]) {
                if (nr_ctlr == 8) {
-                       printk("This driver supports a maximum of "
-                               "8 controllers.\n");
+                       printk(KERN_WARNING "cpqarray: This driver supports"
+                               " a maximum of 8 controllers.\n");
                        break;
                }
                board_id = inl(eisa[i]+0xC80);
@@ -744,11+740,11 @@ static int cpqarray_eisa_detect(void)
                                break;
 
                if (j == NR_PRODUCTS) {
-                       printk("Sorry, I don't know how to access the SMART"
-                         " Array controller %08lx\n", (unsigned long)board_id);
+                       printk(KERN_WARNING "cpqarray: Sorry, I don't know how"
+                               " to access the SMART Array controller %08lx\n",                                 (unsigned long)board_id);
                        continue;
                }
-               hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+               hba[nr_ctlr] = (ctlr_info_t *) kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
                if(hba[nr_ctlr]==NULL)
                {
                        printk(KERN_ERR "cpqarray: out of memory.\n");
@@ -885,21+881,34 @@ static void do_ida_request(int ctlr)
        queue_head = &blk_dev[MAJOR_NR+ctlr].request_queue.queue_head;
 
        if (list_empty(queue_head))
-               goto doreq_done;
+       {
+               start_io(h);
+               return;
+       }
+
        creq = blkdev_entry_next_request(queue_head);
        if (creq->rq_status == RQ_INACTIVE)
-               goto doreq_done;
+       {       
+                start_io(h);
+                return;
+        }
+
 
        if (ctlr != MAJOR(creq->rq_dev)-MAJOR_NR ||
-               ctlr > nr_ctlr || h == NULL) {
+               ctlr > nr_ctlr || h == NULL) 
+       {
                printk("doreq cmd for %d, %x at %p\n",
                                ctlr, creq->rq_dev, creq);
                complete_buffers(creq->bh, 0);
-               goto doreq_done;
+               start_io(h);
+                return;
        }
 
        if ((c = cmd_alloc(h)) == NULL)
-               goto doreq_done;
+       {
+                start_io(h);
+                return;
+        }
 
        bh = creq->bh;
 
@@ -972,9+981,9 @@ DBGPX(              printk("Done with %p\n", creq); );
        /* Put the request on the tail of the request queue */
        addQ(&h->reqQ, c);
        h->Qdepth++;
-       if (h->Qdepth > h->maxQsinceinit) h->maxQsinceinit = h->Qdepth;
+       if (h->Qdepth > h->maxQsinceinit) 
+               h->maxQsinceinit = h->Qdepth;
 
-doreq_done:
        start_io(h);
 }
 
@@ -1022,28+1031,24 @@ static inline void complete_buffers(struct buffer_head *bh, int ok)
  */
 static inline void complete_command(cmdlist_t *cmd, int timeout)
 {
-       char buf[80];
        int ok=1;
 
        if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
           (hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) {
-               sprintf(buf, "Non Fatal error on ida/c%dd%d\n",
+               printk(KERN_WARNING "Non Fatal error on ida/c%dd%d\n",
                                cmd->ctlr, cmd->hdr.unit);
-               console_print(buf);
                hba[cmd->ctlr]->misc_tflags |= MISC_NONFATAL_WARN;
        }
        if (cmd->req.hdr.rcode & RCODE_FATAL) {
-               sprintf(buf, "Fatal error on ida/c%dd%d\n",
+               printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
                                cmd->ctlr, cmd->hdr.unit);
-               console_print(buf);
                ok = 0;
        }
        if (cmd->req.hdr.rcode & RCODE_INVREQ) {
-                               sprintf(buf, "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
+                               printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
                                cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
                                cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
                                cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
-               console_print(buf);
                ok = 0; 
        }
        if (timeout) ok = 0;
@@ -1077,10+1082,15 @@ static void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
        if (istat & FIFO_NOT_EMPTY) {
                while((a = h->access.command_completed(h))) {
                        a1 = a; a &= ~3;
-                       if ((c = h->cmpQ) == NULL) goto bad_completion;
+                       if ((c = h->cmpQ) == NULL)
+                       {  
+                               printk(KERN_WARNING "cpqarray: Completion of %08lx ignored\n", (unsigned long)a1);
+                               continue;       
+                       } 
                        while(c->busaddr != a) {
                                c = c->next;
-                               if (c == h->cmpQ) break;
+                               if (c == h->cmpQ) 
+                                       break;
                        }
                        /*
                         * If we've found the command, take it off the
@@ -1096,8+1106,6 @@ static void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
                                }
                                continue;
                        }
-bad_completion:
-                       printk("Completion of %08lx ignored\n", (unsigned long)a1);
                }
        }
 
@@ -1227,16+1235,27 @@ static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io)
        switch(io->cmd) {
        case PASSTHRU_A:
                p = kmalloc(io->sg[0].size, GFP_KERNEL);
-               if (!p) { error = -ENOMEM; goto ioctl_err_exit; }
+               if (!p) 
+               { 
+                       error = -ENOMEM; 
+                       cmd_free(NULL, c); 
+                       return(error);
+               }
                copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size);
-               c->req.bp = virt_to_bus(&(io->c));
+               c->req.hdr.blk = virt_to_bus(&(io->c));
                c->req.sg[0].size = io->sg[0].size;
                c->req.sg[0].addr = virt_to_bus(p);
                c->req.hdr.sg_cnt = 1;
                break;
        case IDA_READ:
                p = kmalloc(io->sg[0].size, GFP_KERNEL);
-               if (!p) { error = -ENOMEM; goto ioctl_err_exit; }
+               if (!p) 
+               { 
+                        error = -ENOMEM; 
+                        cmd_free(NULL, c);
+                        return(error);
+                }
+
                c->req.sg[0].size = io->sg[0].size;
                c->req.sg[0].addr = virt_to_bus(p);
                c->req.hdr.sg_cnt = 1;
@@ -1245,7+1264,12 @@ static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io)
        case IDA_WRITE_MEDIA:
        case DIAG_PASS_THRU:
                p = kmalloc(io->sg[0].size, GFP_KERNEL);
-               if (!p) { error = -ENOMEM; goto ioctl_err_exit; }
+               if (!p) 
+               { 
+                        error = -ENOMEM; 
+                        cmd_free(NULL, c);
+                        return(error);
+                }
                copy_from_user(p, (void*)io->sg[0].addr, io->sg[0].size);
                c->req.sg[0].size = io->sg[0].size;
                c->req.sg[0].addr = virt_to_bus(p);
@@ -1284,10+1308,8 @@ static int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io)
        }
 
        io->rcode = c->req.hdr.rcode;
-       error = 0;
-ioctl_err_exit:
        cmd_free(NULL, c);
-       return error;
+       return(0);
 }
 
 /*
@@ -1390,8+1412,8 @@ static int sendcmd(
                }
                udelay(10);
 DBG(
-               printk("ida%d: idaSendPciCmd FIFO full, waiting!\n",
-                      ctlr);
+               printk(KERN_WARNING "cpqarray ida%d: idaSendPciCmd FIFO full,"
+                       " waiting!\n", ctlr);
 );
        } 
        /*
@@ -1401,16+1423,16 @@ DBG(
        complete = pollcomplete(ctlr);
        if (complete != 1) {
                if (complete != c->busaddr) {
-                       printk(
-                       "ida%d: idaSendPciCmd "
+                       printk( KERN_WARNING
+                       "cpqarray ida%d: idaSendPciCmd "
                      "Invalid command list address returned! (%08lx)\n",
                                ctlr, (unsigned long)complete);
                        cmd_free(info_p, c);
                        return (IO_ERROR);
                }
        } else {
-               printk(
-                       "ida%d: idaSendPciCmd Timeout out, "
+               printk( KERN_WARNING
+                       "cpqarray ida%d: idaSendPciCmd Timeout out, "
                        "No command list address returned!\n",
                        ctlr);
                cmd_free(info_p, c);
@@ -1419,9+1441,9 @@ DBG(
 
        if (c->req.hdr.rcode & 0x00FE) {
                if (!(c->req.hdr.rcode & BIG_PROBLEM)) {
-                       printk(
-                       "ida%d: idaSendPciCmd, error: Controller failed "
-                               "at init time "
+                       printk( KERN_WARNING
+                       "cpqarray ida%d: idaSendPciCmd, error: "
+                               "Controller failed at init time "
                                "cmd: 0x%x, return code = 0x%x\n",
                                ctlr, c->req.hdr.cmd, c->req.hdr.rcode);
 
@@ -1461,8+1483,8 @@ static int revalidate_allvol(kdev_t dev)
        spin_lock_irqsave(&io_request_lock, flags);
        if (hba[ctlr]->usage_count > 1) {
                spin_unlock_irqrestore(&io_request_lock, flags);
-               printk("Device busy for volume revalidation (usage=%d)\n",
-                                       hba[ctlr]->usage_count);
+               printk(KERN_WARNING "cpqarray: Device busy for volume"
+                       " revalidation (usage=%d)\n", hba[ctlr]->usage_count);
                return -EBUSY;
        }
        spin_unlock_irqrestore(&io_request_lock, flags);
@@ -1514,8+1536,9 @@ static int revalidate_logvol(kdev_t dev, int maxusage)
        spin_lock_irqsave(&io_request_lock, flags);
        if (hba[ctlr]->drv[target].usage_count > maxusage) {
                spin_unlock_irqrestore(&io_request_lock, flags);
-               printk("Device busy for revalidation (usage=%d)\n",
-                                       hba[ctlr]->drv[target].usage_count);
+               printk(KERN_WARNING "cpqarray: Device busy for "
+                       "revalidation (usage=%d)\n",
+                       hba[ctlr]->drv[target].usage_count);
                return -EBUSY;
        }
 
@@ -1581,22+1604,28 @@ static void start_fwbk(int ctlr)
                id_ctlr_t *id_ctlr_buf; 
        int ret_code;
 
-       if(     hba[ctlr]->board_id != 0x40400E11)
+       if(     (hba[ctlr]->board_id != 0x40400E11)
+               && (hba[ctlr]->board_id != 0x40480E11) )
+
        /* Not a Integrated Raid, so there is nothing for us to do */
                return;
-       printk(KERN_DEBUG "Starting firmware's background processing\n");
+       printk(KERN_DEBUG "cpqarray: Starting firmware's background"
+               " processing\n");
        /* Command does not return anything, but idasend command needs a 
                buffer */
        id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
        if(id_ctlr_buf==NULL)
        {
-               printk(KERN_WARNING "Out of memory. Unable to start background processing.\n");
+               printk(KERN_WARNING "cpqarray: Out of memory. "
+                       "Unable to start background processing.\n");
                return;
        }               
        ret_code = sendcmd(RESUME_BACKGROUND_ACTIVITY, ctlr, 
                id_ctlr_buf, 0, 0, 0, 0);
        if(ret_code != IO_OK)
-               printk(KERN_WARNING "Unable to start background processing\n");
+               printk(KERN_WARNING "cpqarray: Unable to start"
+                       " background processing\n");
+
        kfree(id_ctlr_buf);
 }
 /*****************************************************************
@@ -1620,16+1649,38 @@ static void getgeometry(int ctlr)
        
        id_ldrive = (id_log_drv_t *)kmalloc(sizeof(id_log_drv_t), GFP_KERNEL);
        if(id_ldrive == NULL)
+       {
+               printk( KERN_ERR "cpqarray:  out of memory.\n");
                return;
+       }
+
        id_ctlr_buf = (id_ctlr_t *)kmalloc(sizeof(id_ctlr_t), GFP_KERNEL);
        if(id_ctlr_buf == NULL)
-               goto bail2;
+       {
+               kfree(id_ldrive);
+               printk( KERN_ERR "cpqarray:  out of memory.\n");
+               return;
+       }
+
        id_lstatus_buf = (sense_log_drv_stat_t *)kmalloc(sizeof(sense_log_drv_stat_t), GFP_KERNEL);
        if(id_lstatus_buf == NULL)
-               goto bail3;
+       {
+               kfree(id_ctlr_buf);
+               kfree(id_ldrive);
+               printk( KERN_ERR "cpqarray:  out of memory.\n");
+               return;
+       }
+
        sense_config_buf = (config_t *)kmalloc(sizeof(config_t), GFP_KERNEL);
        if(sense_config_buf == NULL)
-               goto bail4;
+       {
+               kfree(id_lstatus_buf);
+               kfree(id_ctlr_buf);
+               kfree(id_ldrive);
+               printk( KERN_ERR "cpqarray:  out of memory.\n");
+               return;
+       }
+
        memset(id_ldrive, 0, sizeof(id_log_drv_t));
        memset(id_ctlr_buf, 0, sizeof(id_ctlr_t));
        memset(id_lstatus_buf, 0, sizeof(sense_log_drv_stat_t));
@@ -1648,8+1699,15 @@ static void getgeometry(int ctlr)
                 * so the idastubopen will fail on all logical drives
                 * on the controller.
                 */
-               goto geo_ret;   /* release the buf and return */
-       }
+                /* Free all the buffers and return */ 
+               printk(KERN_ERR "cpqarray: error sending ID controller\n");
+               kfree(sense_config_buf);
+                kfree(id_lstatus_buf);
+                kfree(id_ctlr_buf);
+                kfree(id_ldrive);
+                return;
+        }
+
        info_p->log_drives = id_ctlr_buf->nr_drvs;;
        *(__u32*)(info_p->firm_rev) = *(__u32*)(id_ctlr_buf->firm_rev);
        info_p->ctlr_sig = id_ctlr_buf->cfg_sig;
@@ -1663,8+1721,9 @@ static void getgeometry(int ctlr)
         * Get drive geometry for all logical drives
         */
        if (id_ctlr_buf->nr_drvs > 16)
-               printk("ida%d:  This driver supports 16 logical drives "
-                       "per controller.\n.  Additional drives will not be "
+               printk(KERN_WARNING "cpqarray ida%d:  This driver supports "
+                       "16 logical drives per controller.\n.  "
+                       " Additional drives will not be "
                        "detected\n", ctlr);
 
        for (log_unit = 0;
@@ -1687,13+1746,17 @@ static void getgeometry(int ctlr)
                           on the controller. 
                         */
                        info_p->log_drv_map = 0;        
-                       printk(
-                            "ida%d: idaGetGeometry - Controller failed "
-                               "to report status of logical drive %d\n"
+                       printk( KERN_WARNING
+                            "cpqarray ida%d: idaGetGeometry - Controller"
+                               " failed to report status of logical drive %d\n"
                         "Access to this controller has been disabled\n",
                                ctlr, log_unit);
-                       goto geo_ret;   /* release the buf and return */
-
+                       /* Free all the buffers and return */
+                       kfree(sense_config_buf);
+                       kfree(id_lstatus_buf);
+                       kfree(id_ctlr_buf);
+                       kfree(id_ldrive);
+                       return;
                }
                /*
                   Make sure the logical drive is configured
@@ -1715,14+1778,21 @@ static void getgeometry(int ctlr)
                                drv->sectors = id_ldrive->drv.sect_per_track;
                                info_p->log_drv_map |=  (1 << log_unit);
 
-       printk("ida/c%dd%d: blksz=%d nr_blks=%d\n",
+       printk(KERN_INFO "cpqarray ida/c%dd%d: blksz=%d nr_blks=%d\n",
                ctlr, log_unit, drv->blk_size, drv->nr_blks);
                                ret_code = sendcmd(SENSE_CONFIG,
                                                  ctlr, sense_config_buf,
                                 sizeof(config_t), 0, 0, log_unit);
                                if (ret_code == IO_ERROR) {
                                        info_p->log_drv_map = 0;
-                                       goto geo_ret;   /* release the buf and return */
+                                       /* Free all the buffers and return */
+                                       printk(KERN_ERR "cpqarray: error sending sense config\n");
+                                       kfree(sense_config_buf);
+                                       kfree(id_lstatus_buf);
+                                       kfree(id_ctlr_buf);
+                                       kfree(id_ldrive);
+                                       return;
+
                                }
                                info_p->phys_drives =
                                    sense_config_buf->ctlr_phys_drv;
@@ -1736,12+1806,10 @@ static void getgeometry(int ctlr)
                        log_index = log_index + 1;
                }               /* end of if logical drive configured */
        }                       /* end of for log_unit */
-geo_ret:
        kfree(sense_config_buf);
-bail4: 
-       kfree(id_ldrive);
-bail3:
-       kfree(id_lstatus_buf);
-bail2: 
+       kfree(id_ldrive);
+       kfree(id_lstatus_buf);
        kfree(id_ctlr_buf);
+       return;
+
 }
index 056863b..6d57a85 100644 (file)
@@ -191,7+191,7 @@ typedef struct {
        __u8    expn_fail;
        __u8    unit_flags;
        __u16   big_fail_map[8];
-       __u16   big_remap_map[8];
+       __u16   big_remap_map[128];
        __u16   big_repl_map[8];
        __u16   big_act_spare_map[8];
        __u8    big_spar_repl_map[128];
@@ -336,7+336,7 @@ typedef struct {
        __u32   sense_info;
        __u8    sense_code;
        __u8    sense_qual;
-       __u   residual;
+       __u32   residual;
        __u8    reserved[4];
        __u8    cdb[12];        
 } scsi_param_t;
index 221e4a5..0159800 100644 (file)
@@ -62,13+62,14 @@ static void smart4_intr_mask(ctlr_info_t *h, unsigned long val)
 }
 
 /*
- *  For this card fifo is full if reading this port returns 0! 
+ *  For older cards FIFO Full = 0. 
+ *  On this card 0 means there is room, anything else FIFO Full. 
  * 
  */ 
 static unsigned long smart4_fifo_full(ctlr_info_t *h)
 {
        
-        return (~readl(h->vaddr + S42XX_REQUEST_PORT_OFFSET));
+        return (!readl(h->vaddr + S42XX_REQUEST_PORT_OFFSET));
 }
 
 /* This type of controller returns -1 if the fifo is empty, 
@@ -81,7+82,7 @@ static unsigned long smart4_completed(ctlr_info_t *h)
                = readl(h->vaddr + S42XX_REPLY_PORT_OFFSET);
 
        /* Fifo is empty */
-       if( register_value == -1)
+       if( register_value == 0xffffffff)
                return 0;       
 
        /* Need to let it know we got the reply */
index 7592e0b..5084ea7 100644 (file)
@@ -197,7+197,7 @@ endmenu
 
 bool 'FDDI driver support' CONFIG_FDDI
 if [ "$CONFIG_FDDI" = "y" ]; then
-   dep_tristate '  Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX $CONFIG_FDDI
+   tristate '  Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
    tristate '  SysKonnect FDDI PCI support' CONFIG_SKFP
 fi
 
index 2975a51..5032a9b 100644 (file)
@@ -74,14+74,14 @@ comment 'USB HID'
       if [ "$CONFIG_INPUT_IFORCE_USB" != "n" ];  then
          define_tristate CONFIG_INPUT_IFORCE $CONFIG_INPUT_IFORCE_USB
       fi
-   dep_tristate '  Keyboard support' CONFIG_INPUT_KEYBDEV
-   dep_tristate '  Mouse support' CONFIG_INPUT_MOUSEDEV
+   dep_tristate '  Keyboard support' CONFIG_INPUT_KEYBDEV $CONFIG_USB
+   dep_tristate '  Mouse support' CONFIG_INPUT_MOUSEDEV $CONFIG_USB
    if [ "$CONFIG_INPUT_MOUSEDEV" != "n" ]; then
       int '   Horizontal screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
       int '   Vertical screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_Y 768
    fi
-   dep_tristate '  Joystick support' CONFIG_INPUT_JOYDEV
-   dep_tristate '  Event interface support' CONFIG_INPUT_EVDEV
+   dep_tristate '  Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_USB
+   dep_tristate '  Event interface support' CONFIG_INPUT_EVDEV $CONFIG_USB
 fi
 
 endmenu
index 2353855..d6cedee 100644 (file)
@@ -1044,7+1044,7 @@ static int proc_ioctl (struct dev_state *ps, void *arg)
                        kfree (buf);
                        return -EFAULT;
                } else
-                       memset (arg, size, 0);
+                       memset (arg, 0, size);
        }
 
        /* ioctl to device */
index 3e21f6c..7eca5e3 100644 (file)
@@ -1,5+1,5 @@
 /*
- * $Id: evdev.c,v 1.8 2000/05/29 09:01:52 vojtech Exp $
+ * $Id: evdev.c,v 1.10 2000/06/23 09:23:00 vojtech Exp $
  *
  *  Copyright (c) 1999-2000 Vojtech Pavlik
  *
 #include <linux/input.h>
 
 struct evdev {
-       int used;
+       int exist;
        int open;
        int minor;
        struct input_handle handle;
@@ -99,13+99,14 @@ static int evdev_release(struct inode * inode, struct file * file)
                listptr = &((*listptr)->next);
        *listptr = (*listptr)->next;
 
-       if (!--list->evdev->open)
-               input_close_device(&list->evdev->handle);       
-       
-       if (!--list->evdev->used) {
-               input_unregister_minor(list->evdev->devfs);
-               evdev_table[list->evdev->minor] = NULL;
-               kfree(list->evdev);
+       if (!--list->evdev->open) {
+               if (list->evdev->exist) {
+                       input_close_device(&list->evdev->handle);       
+               } else {
+                       input_unregister_minor(list->evdev->devfs);
+                       evdev_table[list->evdev->minor] = NULL;
+                       kfree(list->evdev);
+               }
        }
 
        kfree(list);
@@ -121,9+122,8 @@ static int evdev_open(struct inode * inode, struct file * file)
        if (i > EVDEV_MINORS || !evdev_table[i])
                return -ENODEV;
 
-       if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) {
+       if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL)))
                return -ENOMEM;
-       }
        memset(list, 0, sizeof(struct evdev_list));
 
        list->evdev = evdev_table[i];
@@ -132,10+132,9 @@ static int evdev_open(struct inode * inode, struct file * file)
 
        file->private_data = list;
 
-       list->evdev->used++;
-
        if (!list->evdev->open++)
-               input_open_device(&list->evdev->handle);        
+               if (list->evdev->exist)
+                       input_open_device(&list->evdev->handle);        
 
        return 0;
 }
@@ -303,7+302,7 @@ static struct input_handle *evdev_connect(struct input_handler *handler, struct
        evdev->handle.handler = handler;
        evdev->handle.private = evdev;
 
-       evdev->used = 1;
+       evdev->exist = 1;
 
        evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE);
 
@@ -316,10+315,11 @@ static void evdev_disconnect(struct input_handle *handle)
 {
        struct evdev *evdev = handle->private;
 
-       if (evdev->open)
-               input_close_device(handle);
+       evdev->exist = 0;
 
-       if (!--evdev->used) {
+       if (evdev->open) {
+               input_close_device(handle);
+       } else {
                input_unregister_minor(evdev->devfs);
                evdev_table[evdev->minor] = NULL;
                kfree(evdev);
index 0f0bb27..5349d51 100644 (file)
@@ -1,7+1,7 @@
 /*
- * $Id: joydev.c,v 1.7 2000/05/29 09:01:52 vojtech Exp $
+ * $Id: joydev.c,v 1.11 2000/06/23 09:23:00 vojtech Exp $
  *
- *  Copyright (c) 1999-2000 Vojtech Pavlik
+ *  Copyright (c) 1999-2000 Vojtech Pavlik 
  *  Copyright (c) 1999 Colin Van Dyke 
  *
  *  Joystick device driver for the input driver suite.
 #define JOYDEV_BUFFER_SIZE     64
 
 struct joydev {
-       int used;
+       int exist;
        int open;
        int minor;
        struct input_handle handle;
@@ -66,6+66,7 @@ struct joydev {
        __u16 keypam[KEY_MAX - BTN_MISC];
        __u8 absmap[ABS_MAX];
        __u8 abspam[ABS_MAX];
+       __s16 abs[ABS_MAX];
 };
 
 struct joydev_list {
@@ -121,7+122,9 @@ static void joydev_event(struct input_handle *handle, unsigned int type, unsigne
                case EV_ABS:
                        event.type = JS_EVENT_AXIS;
                        event.number = joydev->absmap[code];
-                       event.value = joydev_correct(value, &joydev->corr[event.number]);
+                       event.value = joydev_correct(value, joydev->corr + event.number);
+                       if (event.value == joydev->abs[event.number]) return;
+                       joydev->abs[event.number] = event.value;
                        break;
 
                default:
@@ -165,13+168,14 @@ static int joydev_release(struct inode * inode, struct file * file)
                listptr = &((*listptr)->next);
        *listptr = (*listptr)->next;
 
-       if (!--list->joydev->open)
-               input_close_device(&list->joydev->handle);
-       
-       if (!--list->joydev->used) {
-               input_unregister_minor(list->joydev->devfs);
-               joydev_table[list->joydev->minor] = NULL;
-               kfree(list->joydev);
+       if (!--list->joydev->open) {
+               if (list->joydev->exist) {
+                       input_close_device(&list->joydev->handle);
+               } else {
+                       input_unregister_minor(list->joydev->devfs);
+                       joydev_table[list->joydev->minor] = NULL;
+                       kfree(list->joydev);
+               }
        }
 
        kfree(list);
@@ -187,9+191,8 @@ static int joydev_open(struct inode *inode, struct file *file)
        if (i > JOYDEV_MINORS || !joydev_table[i])
                return -ENODEV;
 
-       if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL))) {
+       if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL)))
                return -ENOMEM;
-       }
        memset(list, 0, sizeof(struct joydev_list));
 
        list->joydev = joydev_table[i];
@@ -198,10+201,9 @@ static int joydev_open(struct inode *inode, struct file *file)
 
        file->private_data = list;
 
-       list->joydev->used++;
-
        if (!list->joydev->open++)
-               input_open_device(&list->joydev->handle);
+               if (list->joydev->exist)
+                       input_open_device(&list->joydev->handle);
 
        return 0;
 }
@@ -228,8+230,8 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p
 
                data.buttons =  ((joydev->nkey > 0 && test_bit(joydev->keypam[0], input->key)) ? 1 : 0) |
                                ((joydev->nkey > 1 && test_bit(joydev->keypam[1], input->key)) ? 2 : 0);
-               data.x = ((joydev_correct(input->abs[ABS_X], &joydev->corr[0]) / 256) + 128) >> joydev->glue.JS_CORR.x;
-               data.y = ((joydev_correct(input->abs[ABS_Y], &joydev->corr[1]) / 256) + 128) >> joydev->glue.JS_CORR.y;
+               data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x;
+               data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y;
 
                if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
                        return -EFAULT;
@@ -274,13+276,12 @@ static ssize_t joydev_read(struct file *file, char *buf, size_t count, loff_t *p
 
                if (list->startup < joydev->nkey) {
                        event.type = JS_EVENT_BUTTON | JS_EVENT_INIT;
-                       event.value = !!test_bit(joydev->keypam[list->startup], input->key);
                        event.number = list->startup;
+                       event.value = !!test_bit(joydev->keypam[event.number], input->key);
                } else {
                        event.type = JS_EVENT_AXIS | JS_EVENT_INIT;
-                       event.value = joydev_correct(input->abs[joydev->abspam[list->startup - joydev->nkey]],
-                                                       &joydev->corr[list->startup - joydev->nkey]);
                        event.number = list->startup - joydev->nkey;
+                       event.value = joydev->abs[event.number];
                }
 
                if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
@@ -407,7+408,7 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
        joydev->handle.handler = handler;
        joydev->handle.private = joydev;
 
-       joydev->used = 1;
+       joydev->exist = 1;
 
        for (i = 0; i < ABS_MAX; i++)
                if (test_bit(i, dev->absbit)) {
@@ -442,6+443,8 @@ static struct input_handle *joydev_connect(struct input_handler *handler, struct
                joydev->corr[i].coef[1] = (dev->absmax[j] + dev->absmin[j]) / 2 + dev->absflat[j];
                joydev->corr[i].coef[2] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
                joydev->corr[i].coef[3] = (1 << 29) / ((dev->absmax[j] - dev->absmin[j]) / 2 - 2 * dev->absflat[j]);
+
+               joydev->abs[i] = joydev_correct(dev->abs[j], joydev->corr + i);
        }
 
        joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE);
@@ -455,10+458,11 @@ static void joydev_disconnect(struct input_handle *handle)
 {
        struct joydev *joydev = handle->private;
 
-       if (joydev->open)
-               input_close_device(handle);     
+       joydev->exist = 0;
 
-       if (!--joydev->used) {
+       if (joydev->open) {
+               input_close_device(handle);     
+       } else {
                input_unregister_minor(joydev->devfs);
                joydev_table[joydev->minor] = NULL;
                kfree(joydev);
index 399d2a0..5c871a8 100644 (file)
@@ -1,5+1,5 @@
 /*
- * $Id: mousedev.c,v 1.8 2000/05/28 17:31:36 vojtech Exp $
+ * $Id: mousedev.c,v 1.10 2000/06/23 09:23:00 vojtech Exp $
  *
  *  Copyright (c) 1999-2000 Vojtech Pavlik
  *
 #endif
 
 struct mousedev {
-       int used;
+       int exist;
        int open;
        int minor;
        wait_queue_head_t wait;
@@ -172,22+172,30 @@ static int mousedev_release(struct inode * inode, struct file * file)
                        struct input_handle *handle = mousedev_handler.handle;
                        while (handle) {
                                struct mousedev *mousedev = handle->private;
-                               if (!mousedev->open)
-                                       input_close_device(handle);
+                               if (!mousedev->open) {
+                                       if (mousedev->exist) {
+                                               input_close_device(&mousedev->handle);
+                                       } else {
+                                               input_unregister_minor(mousedev->devfs);
+                                               mousedev_table[mousedev->minor] = NULL;
+                                               kfree(mousedev);
+                                       }
+                               }
                                handle = handle->hnext;
                        }
                } else {
-                       if (!mousedev_mix.open) 
-                               input_close_device(&list->mousedev->handle);
+                       if (!mousedev_mix.open) {
+                               if (list->mousedev->exist) {
+                                       input_close_device(&list->mousedev->handle);
+                               } else {
+                                       input_unregister_minor(list->mousedev->devfs);
+                                       mousedev_table[list->mousedev->minor] = NULL;
+                                       kfree(list->mousedev);
+                               }
+                       }
                }
        }
        
-       if (!--list->mousedev->used) {
-               input_unregister_minor(list->mousedev->devfs);
-               mousedev_table[list->mousedev->minor] = NULL;
-               kfree(list->mousedev);
-       }
-
        kfree(list);
 
        return 0;
@@ -210,20+218,20 @@ static int mousedev_open(struct inode * inode, struct file * file)
        mousedev_table[i]->list = list;
        file->private_data = list;
 
-       list->mousedev->used++;
-
        if (!list->mousedev->open++) {
                if (list->mousedev->minor == MOUSEDEV_MIX) {
                        struct input_handle *handle = mousedev_handler.handle;
                        while (handle) {
                                struct mousedev *mousedev = handle->private;
                                if (!mousedev->open)
-                                       input_open_device(handle);
+                                       if (mousedev->exist)    
+                                               input_open_device(handle);
                                handle = handle->hnext;
                        }
                } else {
-                       if (!mousedev_mix.open) 
-                               input_open_device(&list->mousedev->handle);
+                       if (!mousedev_mix.open)
+                               if (list->mousedev->exist)      
+                                       input_open_device(&list->mousedev->handle);
                }
        }
 
@@ -402,7+410,7 @@ static struct input_handle *mousedev_connect(struct input_handler *handler, stru
        memset(mousedev, 0, sizeof(struct mousedev));
        init_waitqueue_head(&mousedev->wait);
 
-       mousedev->used = 1;
+       mousedev->exist = 1;
        mousedev->minor = minor;
        mousedev_table[minor] = mousedev;
 
@@ -424,10+432,13 @@ static void mousedev_disconnect(struct input_handle *handle)
 {
        struct mousedev *mousedev = handle->private;
 
-       if (mousedev->open || mousedev_mix.open)
-               input_close_device(handle);
+       mousedev->exist = 0;
 
-       if (!--mousedev->used) {
+       if (mousedev->open) {
+               input_close_device(handle);
+       } else {
+               if (mousedev_mix.open)
+                       input_close_device(handle);
                input_unregister_minor(mousedev->devfs);
                mousedev_table[mousedev->minor] = NULL;
                kfree(mousedev);
@@ -449,7+460,7 @@ static int __init mousedev_init(void)
        memset(&mousedev_mix, 0, sizeof(struct mousedev));
        init_waitqueue_head(&mousedev_mix.wait);
        mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
-       mousedev_mix.used = 1;
+       mousedev_mix.exist = 1;
        mousedev_mix.minor = MOUSEDEV_MIX;
        mousedev_mix.devfs = input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);
 
index 80b82bb..8c588f7 100644 (file)
 /*
 **     Pegasus: USB 10/100Mbps/HomePNA (1Mbps) Controller
 **
-**     Copyright (R) 1999,2000 Petko Manolov - Petkan (petkan@spct.net)
+**     Copyright (c) 1999,2000 Petko Manolov - Petkan (petkan@spct.net)
+**     
 **
-**     Distribute under GPL version 2 or later.
+**     ChangeLog:
+**             ....    Most of the time spend reading sources & docs.
+**             v0.2.x  First official release for the Linux kernel.
+**             v0.3.0  Beutified and structured, some bugs fixed.
+**             v0.3.x  URBifying bulk requests and bugfixing. First relatively
+**                     stable release. Still can touch device's registers only
+**                     from top-halves.
+**             v0.4.0  Control messages remained unurbified are now URBs.
+**                     Now we can touch the HW at any time.
 */
 
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
 #include <linux/module.h>
 #include <linux/sched.h>
 #include <linux/malloc.h>
 #include <linux/usb.h>
 
 
-static const char *version = __FILE__ ": v0.3.14 2000/06/09 (C) 1999-2000 Petko Manolov (petkan@spct.net)\n";
+static const char *version = __FILE__ ": v0.4.0 2000/06/15 (C) 1999-2000 Petko Manolov (petkan@spct.net)\n";
 
 
 #define        PEGASUS_MTU             1500
@@ -24,17+50,39 @@ static const char *version = __FILE__ ": v0.3.14 2000/06/09 (C) 1999-2000 Petko
 #define        SROM_WRITE              0x01
 #define        SROM_READ               0x02
 #define        PEGASUS_TX_TIMEOUT      (HZ*5)
+#define        PEGASUS_CTRL_TIMEOUT    1000
 #define        PEGASUS_RESET           1
 #define        ALIGN(x)                x __attribute__((aligned(L1_CACHE_BYTES)))
 
 
+enum pegasus_registers {
+       EthCtrl0 = 0,
+       EthCtrl1 = 1,
+       EthCtrl2 = 2,
+       EthID = 0x10,
+       EpromOffset = 0x20,
+       EpromData = 0x21,       /* 0x21 low, 0x22 high byte */
+       EpromCtrl = 0x23,
+       PhyAddr = 0x25,
+       PhyData = 0x26,         /* 0x26 low, 0x27 high byte */
+       PhyCtrl = 0x28,
+       UsbStst = 0x2a,
+       EthTxStat0 = 0x2b,
+       EthTxStat1 = 0x2c,
+       EthRxStat = 0x2d,
+       Gpio0 = 0x7e,
+       Gpio1 = 0x7f,
+};
+
+
 struct pegasus {
        struct usb_device       *usb;
        struct net_device       *net;
        struct net_device_stats stats;
        int                     flags;
-       spinlock_t              pegasus_lock;
-       struct urb              rx_urb, tx_urb, intr_urb;
+       spinlock_t              pegasus_lock, ctrl_lock;
+       struct urb              rx_urb, tx_urb, intr_urb, ctrl_urb;
+       devrequest              dr;
        unsigned char           ALIGN(rx_buff[PEGASUS_MAX_MTU]); 
        unsigned char           ALIGN(tx_buff[PEGASUS_MAX_MTU]); 
        unsigned char           ALIGN(intr_buff[8]);
@@ -64,7+112,7 @@ static struct usb_eth_dev usb_dev_id[] = {
        {"D-Link DSB-650TX", 0x2001, 0x4001, NULL},
        {"D-Link DSB-650TX", 0x2001, 0x4002, NULL},
        {"D-Link DSB-650TX(PNA)", 0x2001, 0x4003, NULL},
-       {"D-Link DU-10", 0x07b8, 0xabc1, NULL},
+       {"D-Link DU-E10", 0x07b8, 0xabc1, NULL},
        {"D-Link DU-E100", 0x07b8, 0x4002, NULL},
        {"Linksys USB100TX", 0x066b, 0x2203, NULL},
        {"Linksys USB100TX", 0x066b, 0x2204, NULL},
@@ -78,23+126,120 @@ static struct usb_eth_dev usb_dev_id[] = {
 };
 
 
-#define pegasus_get_registers(dev, indx, size, data)\
-       usb_control_msg(dev, usb_rcvctrlpipe(dev,0), 0xf0, 0xc0, 0, indx, data, size, HZ);
-#define pegasus_set_registers(dev, indx, size, data)\
-       usb_control_msg(dev, usb_sndctrlpipe(dev,0), 0xf1, 0x40, 0, indx, data, size, HZ);
-#define pegasus_set_register(dev, indx, value) \
-       { __u8  __data = value;                 \
-       usb_control_msg(dev, usb_sndctrlpipe(dev,0), 0xf1, 0x40, __data, indx, &__data, 1, HZ);}
+
+static void pegasus_ctrl_end( urb_t *urb )
+{
+       if ( urb->status )
+               warn("ctrl_urb end status %d", urb->status);
+}
 
 
-static int pegasus_read_phy_word(struct usb_device *dev, __u8 index, __u16 *regdata)
+static int pegasus_ctrl_timeout( urb_t *ctrl_urb )
+{
+       int     timeout=0;
+       
+       while ( ctrl_urb->status == -EINPROGRESS ) {
+               if ( timeout++ < PEGASUS_CTRL_TIMEOUT ) {
+                       udelay(100);
+                       continue;
+               }
+               err("ctrl urb busy %d", ctrl_urb->status);
+               usb_unlink_urb( ctrl_urb );
+               return  ctrl_urb->status;
+       }
+       return  0;
+}
+
+
+static int pegasus_get_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
+{
+       int     ret;
+
+
+       spin_lock( &pegasus->ctrl_lock );
+       pegasus->dr.requesttype = 0xc0;
+       pegasus->dr.request = 0xf0;
+       pegasus->dr.value = 0x0;
+       pegasus->dr.index = indx;
+       pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = size;
+
+       FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+                         usb_rcvctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
+                         data, size, pegasus_ctrl_end, pegasus );
+
+       if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) ) 
+               err("BAD CTRLs %d", ret);
+       else
+               ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
+
+       spin_unlock( &pegasus->ctrl_lock );
+
+       return  ret;
+}
+
+
+static int pegasus_set_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
+{
+       int     ret;
+
+
+       spin_lock( &pegasus->ctrl_lock );
+       pegasus->dr.requesttype = 0x40;
+       pegasus->dr.request = 0xf1;
+       pegasus->dr.value = 0x0;
+       pegasus->dr.index = indx;
+       pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = size;
+
+       FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+                         usb_sndctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
+                         data, size, pegasus_ctrl_end, pegasus );
+
+       if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
+               err("BAD CTRL %d", ret);
+       else
+               ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
+
+       spin_unlock( &pegasus->ctrl_lock );
+
+       return  ret;
+}
+
+
+static int pegasus_set_register( struct pegasus *pegasus, __u16 indx,__u8 data )
+{
+       int     ret;
+
+
+       spin_lock( &pegasus->ctrl_lock );
+       pegasus->dr.requesttype = 0x40;
+       pegasus->dr.request = 0xf1;
+       pegasus->dr.value = data;
+       pegasus->dr.index = indx;
+       pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = 1;
+
+       FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
+                         usb_sndctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
+                         &data, 1, pegasus_ctrl_end, pegasus );
+                         
+       if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
+               err("BAD CTRL %d", ret);
+       else
+               ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
+
+       spin_unlock( &pegasus->ctrl_lock );
+
+       return  ret;
+}
+
+
+static int pegasus_read_phy_word(struct pegasus *pegasus, __u8 index, __u16 *regdata)
 {
        int i;
        __u8 data[4] = { 1, 0, 0, 0x40 + index };
 
-       pegasus_set_registers(dev, 0x25, 4, data);
+       pegasus_set_registers(pegasus, PhyAddr, 4, data);
        for (i = 0; i < 100; i++) {
-               pegasus_get_registers(dev, 0x26, 3, data);
+               pegasus_get_registers(pegasus, PhyData, 3, data);
                if (data[2] & 0x80) {
                        *regdata = *(__u16 *)(data);
                        return 0;
@@ -107,14+252,14 @@ static int pegasus_read_phy_word(struct usb_device *dev, __u8 index, __u16 *regd
 }
 
 
-static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regdata)
+static int pegasus_write_phy_word(struct pegasus *pegasus, __u8 index, __u16 regdata)
 {
        int i;
        __u8 data[4] = { 1, regdata, regdata >> 8, 0x20 + index };
 
-       pegasus_set_registers(dev, 0x25, 4, data);
+       pegasus_set_registers(pegasus, PhyAddr, 4, data);
        for (i = 0; i < 100; i++) {
-               pegasus_get_registers(dev, 0x28, 1, data);
+               pegasus_get_registers(pegasus, PhyCtrl, 1, data);
                if (data[0] & 0x80)
                        return 0;
                udelay(100);
@@ -125,51+270,51 @@ static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regd
 }
 
 
-static int pegasus_rw_srom_word(struct usb_device *dev, __u8 index, __u16 *retdata, __u8 direction)
+static int pegasus_rw_eprom_word(struct pegasus *pegasus, __u8 index, __u16 *retdata, __u8 direction)
 {
        int i;
        __u8 data[4] = { index, 0, 0, direction };
 
-       pegasus_set_registers(dev, 0x20, 4, data);
+       pegasus_set_registers(pegasus, EpromOffset, 4, data);
        for (i = 0; i < 100; i++) {
-               pegasus_get_registers(dev, 0x23, 1, data);
+               pegasus_get_registers(pegasus, EpromCtrl, 1, data);
                if (data[0] & 4) {
-                       pegasus_get_registers(dev, 0x21, 2, data);
+                       pegasus_get_registers(pegasus, EpromData, 2, data);
                        *retdata = *(__u16 *)data;
                        return 0;
                }
        }
 
-       warn("pegasus_rw_srom_word() failed");
+       warn("pegasus_rw_eprom_word() failed");
        return 1;
 }
 
 
-static int pegasus_get_node_id(struct usb_device *dev, __u8 *id)
+static int pegasus_get_node_id(struct pegasus *pegasus, __u8 *id)
 {
        int i;
        for (i = 0; i < 3; i++)
-               if (pegasus_rw_srom_word(dev,i,(__u16 *)&id[i * 2],SROM_READ))
+               if (pegasus_rw_eprom_word(pegasus,i,(__u16 *)&id[i*2],SROM_READ))
                        return 1;
        return 0;
 }
 
 
-static int pegasus_reset_mac(struct usb_device *dev)
+static int pegasus_reset_mac(struct pegasus *pegasus)
 {
        __u8 data = 0x8;
        int i;
 
-       pegasus_set_register(dev, 1, data);
+       pegasus_set_register(pegasus, EthCtrl1, data);
        for (i = 0; i < 100; i++) {
-               pegasus_get_registers(dev, 1, 1, &data);
+               pegasus_get_registers(pegasus, EthCtrl1, 1, &data);
                if (~data & 0x08) {
                        if (loopback & 1) 
                                return 0;
                        if (loopback & 2) 
-                               pegasus_write_phy_word(dev, 0, 0x4000);
-                       pegasus_set_register(dev, 0x7e, 0x24);
-                       pegasus_set_register(dev, 0x7e, 0x27);
+                               pegasus_write_phy_word(pegasus, 0, 0x4000);
+                       pegasus_set_register(pegasus, Gpio0, 0x24);
+                       pegasus_set_register(pegasus, Gpio0, 0x27);
                        return 0;
                }
        }
@@ -183,22+328,22 @@ static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
        __u16 partmedia, temp;
        __u8 node_id[6];
        __u8 data[4];
+       struct pegasus *pegasus = dev->priv;
 
-       if (pegasus_get_node_id(usb, node_id)) 
+       if (pegasus_get_node_id(pegasus, node_id)) 
                return 1;
 
-       pegasus_set_registers(usb, 0x10, 6, node_id);
+       pegasus_set_registers(pegasus, EthID, 6, node_id);
        memcpy(dev->dev_addr, node_id, 6);
-       if (pegasus_read_phy_word(usb, 1, &temp)) 
+       if (pegasus_read_phy_word(pegasus, 1, &temp)) 
                return 2;
 
        if ((~temp & 4) && !loopback) {
-               warn("%s: link NOT established (0x%x), check the cable.",
+               warn("%s: link NOT established (0x%x) - check the cable.",
                        dev->name, temp);
-               /* return 3; FIXME */
        }
 
-       if (pegasus_read_phy_word(usb, 5, &partmedia))
+       if (pegasus_read_phy_word(pegasus, 5, &partmedia))
                return 4;
 
        if ((partmedia & 0x1f) != 1) {
@@ -210,7+355,7 @@ static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
        data[1] = (partmedia & 0x100) ? 0x30 : ((partmedia & 0x80) ? 0x10 : 0);
        data[2] = (loopback & 1) ? 0x09 : 0x01;
 
-       pegasus_set_registers(usb, 0, 3, data);
+       pegasus_set_registers(pegasus, EthCtrl0, 3, data);
 
        return 0;
 }
@@ -281,24+426,26 @@ static void pegasus_write_bulk(struct urb *urb)
 {
        struct pegasus *pegasus = urb->context;
 
-       spin_lock(&pegasus->pegasus_lock);
 
        if (urb->status)
                info("%s: TX status %d", pegasus->net->name, urb->status);
+#if 1  /* Should be fixed */
+       if (urb->status == -ETIMEDOUT)
+               pegasus_reset_mac(pegasus);
+#endif
        netif_wake_queue(pegasus->net);
-
-       spin_unlock(&pegasus->pegasus_lock);
 }
 
 static void pegasus_tx_timeout(struct net_device *net)
 {
        struct pegasus *pegasus = net->priv;
 
-       warn("%s: Tx timed out. Reseting...", net->name);
+       
        usb_unlink_urb(&pegasus->tx_urb);
+       warn("%s: Tx timed out. Reseting...", net->name);
+       pegasus_reset_mac( pegasus );
        pegasus->stats.tx_errors++;
        net->trans_start = jiffies;
-       pegasus->flags |= PEGASUS_RESET;
 
        netif_wake_queue(net);
 }
@@ -372,6+519,8 @@ static int pegasus_close(struct net_device *net)
 
        netif_stop_queue(net);
 
+       if ( pegasus->ctrl_urb.status == -EINPROGRESS )
+               usb_unlink_urb(&pegasus->ctrl_urb);
        if ( pegasus->rx_urb.status == -EINPROGRESS )
                usb_unlink_urb(&pegasus->rx_urb);
        if ( pegasus->tx_urb.status == -EINPROGRESS )   
@@ -394,12+543,12 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
                case SIOCDEVPRIVATE:
                        data[0] = 1;
                case SIOCDEVPRIVATE+1:
-                       pegasus_read_phy_word(pegasus->usb, data[1] & 0x1f, &data[3]);
+                       pegasus_read_phy_word(pegasus, data[1] & 0x1f, &data[3]);
                        return 0;
                case SIOCDEVPRIVATE+2:
                        if (!capable(CAP_NET_ADMIN))
                                return -EPERM;
-                       pegasus_write_phy_word(pegasus->usb, data[1] & 0x1f, data[2]);
+                       pegasus_write_phy_word(pegasus, data[1] & 0x1f, data[2]);
                        return 0;
                default:
                        return -EOPNOTSUPP;
@@ -410,19+559,23 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 static void pegasus_set_rx_mode(struct net_device *net)
 {
        struct pegasus *pegasus = net->priv;
+       __u8    tmp;
 
        netif_stop_queue(net);
 
        if (net->flags & IFF_PROMISC) {
                info("%s: Promiscuous mode enabled", net->name);
-/*             pegasus_set_register(pegasus->usb, 2, 0x04); FIXME */
+               pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
+               pegasus_set_register(pegasus, EthCtrl2, tmp | 4);
        } else if ((net->mc_count > multicast_filter_limit) ||
                        (net->flags & IFF_ALLMULTI)) {
-               pegasus_set_register(pegasus->usb, 0, 0xfa);
-               pegasus_set_register(pegasus->usb, 2, 0);
+               pegasus_set_register(pegasus, EthCtrl0, 0xfa);
+               pegasus_set_register(pegasus, EthCtrl2, 0);
                info("%s set allmulti", net->name);
        } else {
                info("%s: set Rx mode", net->name);
+               pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
+               pegasus_set_register(pegasus, EthCtrl2, tmp & ~4);      
        }
 
        netif_wake_queue(net);
@@ -464,12+617,6 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
        }
        memset(pegasus, 0, sizeof(struct pegasus));
 
-       if (pegasus_reset_mac(dev)) {
-               err("can't reset MAC");
-               kfree(pegasus);
-               return NULL;
-       }
-       
        net = init_etherdev(0, 0);
        net->priv = pegasus;
        net->open = pegasus_open;
@@ -485,6+632,7 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
        pegasus->usb = dev;
        pegasus->net = net;
        pegasus->pegasus_lock = SPIN_LOCK_UNLOCKED;
+       pegasus->ctrl_lock = SPIN_LOCK_UNLOCKED;
 
        FILL_BULK_URB(&pegasus->rx_urb, dev, usb_rcvbulkpipe(dev, 1),
                        pegasus->rx_buff, PEGASUS_MAX_MTU, pegasus_read_bulk, 
@@ -495,7+643,12 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
        FILL_INT_URB(&pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
                        pegasus->intr_buff, 8, pegasus_irq, pegasus, 500);
 
-
+       if (pegasus_reset_mac(pegasus)) {
+               err("can't reset MAC");
+               kfree(pegasus);
+               return NULL;
+       }
+       
        printk(KERN_INFO "%s: %s\n", net->name, usb_dev_id[dev_indx].name);
 
        return pegasus;
@@ -515,7+668,9 @@ static void pegasus_disconnect(struct usb_device *dev, void *ptr)
                dev_close(pegasus->net);
 
        unregister_netdev(pegasus->net);
-
+       
+       if ( pegasus->ctrl_urb.status == -EINPROGRESS )
+               usb_unlink_urb(&pegasus->ctrl_urb);
        if ( pegasus->rx_urb.status == -EINPROGRESS )
                usb_unlink_urb(&pegasus->rx_urb);
        if ( pegasus->tx_urb.status == -EINPROGRESS )
index b2e18bd..d60fd8e 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (06/23/2000) gkh
+ *     Cleaned up debugging statements in a quest to find UHCI timeout bug.
+ *
  * (05/22/2000) gkh
  *     Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be 
  *     removed from the individual device source files.
@@ -358,7+361,7 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor)
        int i, j;
        int good_spot;
 
-       dbg("get_free_serial %d", num_ports);
+       dbg(__FUNCTION__ " %d", num_ports);
 
        *minor = 0;
        for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
@@ -373,14+376,14 @@ static struct usb_serial *get_free_serial (int num_ports, int *minor)
                        continue;
                        
                if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL))) {
-                       err("Out of memory");
+                       err(__FUNCTION__ " - Out of memory");
                        return NULL;
                }
                memset(serial, 0, sizeof(struct usb_serial));
                serial->magic = USB_SERIAL_MAGIC;
                serial_table[i] = serial;
                *minor = i;
-               dbg("minor base = %d", *minor);
+               dbg(__FUNCTION__ " - minor base = %d", *minor);
                for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
                        serial_table[i] = serial;
                return serial;
@@ -393,7+396,7 @@ static void return_serial (struct usb_serial *serial)
 {
        int i;
 
-       dbg("return_serial");
+       dbg(__FUNCTION__);
 
        if (serial == NULL)
                return;
@@ -418,7+421,7 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da
 //     dbg("ezusb_writememory %x, %d", address, length);
 
        if (!transfer_buffer) {
-               err("ezusb_writememory: kmalloc(%d) failed.", length);
+               err(__FUNCTION__ " - kmalloc(%d) failed.", length);
                return -ENOMEM;
        }
        memcpy (transfer_buffer, data, length);
@@ -431,10+434,10 @@ int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *da
 int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
 {
        int     response;
-       dbg("ezusb_set_reset: %d", reset_bit);
+       dbg(__FUNCTION__ " - %d", reset_bit);
        response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0);
        if (response < 0) {
-               err("ezusb_set_reset %d failed", reset_bit);
+               err(__FUNCTION__ "- %d failed", reset_bit);
        }
        return response;
 }
@@ -451,7+454,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
        struct usb_serial_port *port;
        int portNumber;
        
-       dbg("serial_open");
+       dbg(__FUNCTION__);
 
        /* initialize the pointer incase something fails */
        tty->driver_data = NULL;
@@ -459,7+462,7 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
        /* get the serial object associated with this tty pointer */
        serial = get_serial_by_minor (MINOR(tty->device));
 
-       if (serial_paranoia_check (serial, "serial_open")) {
+       if (serial_paranoia_check (serial, __FUNCTION__)) {
                return -ENODEV;
        }
 
@@ -481,16+484,16 @@ static int serial_open (struct tty_struct *tty, struct file * filp)
 static void serial_close(struct tty_struct *tty, struct file * filp)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_close");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return;
        }
 
-       dbg("serial_close port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
        
        if (!port->active) {
-               dbg ("port not opened");
+               dbg (__FUNCTION__ " - port not opened");
                return;
        }
 
@@ -506,16+509,16 @@ static void serial_close(struct tty_struct *tty, struct file * filp)
 static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_write");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
        
        if (!serial) {
                return -ENODEV;
        }
        
-       dbg("serial_write port %d, %d byte(s)", port->number, count);
+       dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count);
 
        if (!port->active) {
-               dbg ("port not opened");
+               dbg (__FUNCTION__ " - port not opened");
                return -EINVAL;
        }
        
@@ -531,16+534,16 @@ static int serial_write (struct tty_struct * tty, int from_user, const unsigned
 static int serial_write_room (struct tty_struct *tty) 
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_write_room");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return -ENODEV;
        }
 
-       dbg("serial_write_room port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
        
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return -EINVAL;
        }
 
@@ -556,14+559,14 @@ static int serial_write_room (struct tty_struct *tty)
 static int serial_chars_in_buffer (struct tty_struct *tty) 
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_chars_in_buffer");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return -ENODEV;
        }
 
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return -EINVAL;
        }
 
@@ -579,16+582,16 @@ static int serial_chars_in_buffer (struct tty_struct *tty)
 static void serial_throttle (struct tty_struct * tty)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_throttle");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return;
        }
 
-       dbg("serial_throttle port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return;
        }
 
@@ -604,16+607,16 @@ static void serial_throttle (struct tty_struct * tty)
 static void serial_unthrottle (struct tty_struct * tty)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_unthrottle");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return;
        }
 
-       dbg("serial_unthrottle port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return;
        }
 
@@ -629,16+632,16 @@ static void serial_unthrottle (struct tty_struct * tty)
 static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_ioctl");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return -ENODEV;
        }
 
-       dbg("serial_ioctl port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return -ENODEV;
        }
 
@@ -654,16+657,16 @@ static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned in
 static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_set_termios");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return;
        }
 
-       dbg("serial_set_termios port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return;
        }
 
@@ -679,16+682,16 @@ static void serial_set_termios (struct tty_struct *tty, struct termios * old)
 static void serial_break (struct tty_struct *tty, int break_state)
 {
        struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data;
-       struct usb_serial *serial = get_usb_serial (port, "serial_break");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
 
        if (!serial) {
                return;
        }
 
-       dbg("serial_break port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (!port->active) {
-               dbg ("port not open");
+               dbg (__FUNCTION__ " - port not open");
                return;
        }
 
@@ -708,10+711,10 @@ static int generic_open (struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
 
-       dbg("generic_open port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (port->active) {
-               dbg ("device already open");
+               dbg (__FUNCTION__ " - device already open");
                return -EINVAL;
        }
        port->active = 1;
@@ -720,7+723,7 @@ static int generic_open (struct usb_serial_port *port, struct file *filp)
        if (serial->num_bulk_in) {
                /*Start reading from the device*/
                if (usb_submit_urb(port->read_urb))
-                       dbg("usb_submit_urb(read bulk) failed");
+                       dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed");
        }
 
        return (0);
@@ -731,7+734,7 @@ static void generic_close (struct usb_serial_port *port, struct file * filp)
 {
        struct usb_serial *serial = port->serial;
 
-       dbg("generic_close port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
        
        /* shutdown any bulk reads that might be going on */
        if (serial->num_bulk_out) {
@@ -749,22+752,33 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns
 {
        struct usb_serial *serial = port->serial;
 
-       dbg("generic_serial_write port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (count == 0) {
-               dbg("write request of 0 bytes");
+               dbg(__FUNCTION__ " - write request of 0 bytes");
                return (0);
        }
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
                if (port->write_urb->status == -EINPROGRESS) {
-                       dbg ("already writing");
+                       dbg (__FUNCTION__ " - already writing");
                        return (0);
                }
 
                count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
+#ifdef DEBUG
+               {
+                       int i;
+                       printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", count);
+                       for (i = 0; i < count; ++i) {
+                               printk ("%.2x ", buf[i]);
+                       }
+                       printk ("\n");
+               }
+#endif
+
                if (from_user) {
                        copy_from_user(port->write_urb->transfer_buffer, buf, count);
                }
@@ -776,7+790,7 @@ static int generic_write (struct usb_serial_port *port, int from_user, const uns
                port->write_urb->transfer_buffer_length = count;
 
                if (usb_submit_urb(port->write_urb))
-                       dbg("usb_submit_urb(write bulk) failed");
+                       dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed");
 
                return (count);
        }
@@ -791,14+805,14 @@ static int generic_write_room (struct usb_serial_port *port)
        struct usb_serial *serial = port->serial;
        int room;
 
-       dbg("generic_write_room port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
        
        if (serial->num_bulk_out) {
                if (port->write_urb->status == -EINPROGRESS)
                        room = 0;
                else
                        room = port->bulk_out_size;
-               dbg("generic_write_room returns %d", room);
+               dbg(__FUNCTION__ " returns %d", room);
                return (room);
        }
        
@@ -810,7+824,7 @@ static int generic_chars_in_buffer (struct usb_serial_port *port)
 {
        struct usb_serial *serial = port->serial;
 
-       dbg("generic_chars_in_buffer port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
        
        if (serial->num_bulk_out) {
                if (port->write_urb->status == -EINPROGRESS) {
@@ -825,23+839,25 @@ static int generic_chars_in_buffer (struct usb_serial_port *port)
 static void generic_read_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-       struct usb_serial *serial = get_usb_serial (port, "generic_read_bulk_callback");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
        struct tty_struct *tty;
        unsigned char *data = urb->transfer_buffer;
        int i;
 
+       dbg (__FUNCTION__ " - enter");
+       
        if (!serial) {
                return;
        }
 
        if (urb->status) {
-               dbg("nonzero read bulk status received: %d", urb->status);
+               dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
                return;
        }
 
 #ifdef DEBUG
        if (urb->actual_length) {
-               printk (KERN_DEBUG __FILE__ ": data read - length = %d, data = ", urb->actual_length);
+               printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ "- length = %d, data = ", urb->actual_length);
                for (i = 0; i < urb->actual_length; ++i) {
                        printk ("%.2x ", data[i]);
                }
@@ -859,8+875,10 @@ static void generic_read_bulk_callback (struct urb *urb)
 
        /* Continue trying to always read  */
        if (usb_submit_urb(urb))
-               dbg("failed resubmitting read urb");
+               dbg(__FUNCTION__ " - failed resubmitting read urb");
 
+       dbg (__FUNCTION__ " - exit");
+       
        return;
 }
 
@@ -868,15+886,17 @@ static void generic_read_bulk_callback (struct urb *urb)
 static void generic_write_bulk_callback (struct urb *urb)
 {
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-       struct usb_serial *serial = get_usb_serial (port, "generic_write_bulk_callback");
+       struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
        struct tty_struct *tty;
 
+       dbg (__FUNCTION__ " - enter");
+       
        if (!serial) {
                return;
        }
 
        if (urb->status) {
-               dbg("nonzero write bulk status received: %d", urb->status);
+               dbg(__FUNCTION__ " - nonzero write bulk status received: %d", urb->status);
                return;
        }
 
@@ -886,6+906,8 @@ static void generic_write_bulk_callback (struct urb *urb)
 
        wake_up_interruptible(&tty->write_wait);
        
+       dbg (__FUNCTION__ " - exit");
+       
        return;
 }
 
@@ -1255,7+1277,7 @@ int usb_serial_init(void)
        serial_tty_driver.init_termios          = tty_std_termios;
        serial_tty_driver.init_termios.c_cflag  = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
        if (tty_register_driver (&serial_tty_driver)) {
-               err("failed to register tty driver");
+               err(__FUNCTION__ " - failed to register tty driver");
                return -1;
        }
 
index 5cfb4c4..8be2dd3 100644 (file)
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (06/23/2000) gkh
+ *     Cleaned up debugging statements in a quest to find UHCI timeout bug.
+ *
  * (04/27/2000) Ryan VanderBijl
  *     Fixed memory leak in visor_close
  *
@@ -80,10+83,10 @@ struct usb_serial_device_type handspring_device = {
  ******************************************************************************/
 static int visor_open (struct usb_serial_port *port, struct file *filp)
 {
-       dbg("visor_open port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (port->active) {
-               dbg ("device already open");
+               dbg (__FUNCTION__ " - device already open");
                return -EINVAL;
        }
 
@@ -91,7+94,7 @@ static int visor_open (struct usb_serial_port *port, struct file *filp)
 
        /*Start reading from the device*/
        if (usb_submit_urb(port->read_urb))
-               dbg("usb_submit_urb(read bulk) failed");
+               dbg(__FUNCTION__  " - usb_submit_urb(read bulk) failed");
 
        return (0);
 }
@@ -102,10+105,10 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
        struct usb_serial *serial = port->serial;
        unsigned char *transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
        
-       dbg("visor_close port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
                         
        if (!transfer_buffer) {
-               err("visor_close: kmalloc(%d) failed.", 0x12);
+               err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
        } else {
                /* send a shutdown message to the device */
                usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), VISOR_CLOSE_NOTIFICATION,
@@ -122,7+125,7 @@ static void visor_close (struct usb_serial_port *port, struct file * filp)
 
 static void visor_throttle (struct usb_serial_port *port)
 {
-       dbg("visor_throttle port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        usb_unlink_urb (port->read_urb);
 
@@ -132,10+135,10 @@ static void visor_throttle (struct usb_serial_port *port)
 
 static void visor_unthrottle (struct usb_serial_port *port)
 {
-       dbg("visor_unthrottle port %d", port->number);
+       dbg(__FUNCTION__ " - port %d", port->number);
 
        if (usb_unlink_urb (port->read_urb))
-               dbg("usb_submit_urb(read bulk) failed");
+               dbg(__FUNCTION__ " - usb_submit_urb(read bulk) failed");
 
        return;
 }
@@ -148,20+151,20 @@ static int  visor_startup (struct usb_serial *serial)
        unsigned char *transfer_buffer =  kmalloc (256, GFP_KERNEL);
 
        if (!transfer_buffer) {
-               err("visor_startup: kmalloc(%d) failed.", 256);
+               err(__FUNCTION__ " - kmalloc(%d) failed.", 256);
                return -ENOMEM;
        }
 
-       dbg("visor_startup");
+       dbg(__FUNCTION__);
 
-       dbg("visor_setup: Set config to 1");
+       dbg(__FUNCTION__ " - Set config to 1");
        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) {
-               err("visor_startup: error getting connection information");
+               err(__FUNCTION__ " - error getting connection information");
        } else {
                struct visor_connection_info *connection_info = (struct visor_connection_info *)transfer_buffer;
                char *string;
@@ -195,7+198,7 @@ static int  visor_startup (struct usb_serial *serial)
        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) {
-               err("visor_startup: error getting bytes available request");
+               err(__FUNCTION__ " - error getting bytes available request");
        }
 
        kfree (transfer_buffer);
index b9cead4..6d88d36 100644 (file)
 /* Driver for USB Mass Storage compliant devices
  *
- * Initial work by:
- *   (c) 1999 Michael Gee (michael@linuxspecific.com)
+ * $Id: usb-storage.c,v 1.11 2000/06/20 03:19:31 mdharm Exp $
  *
  * Current development and maintainance by:
  *   (c) 1999, 2000 Matthew Dharm (mdharm-usb@one-eyed-alien.net)
  *
+ * Developed with the assistance of:
+ *   (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org)
+ *
+ * Initial work by:
+ *   (c) 1999 Michael Gee (michael@linuxspecific.com)
+ *
  * This driver is based on the 'USB Mass Storage Class' document. This
  * describes in detail the protocol used to communicate with such
  * devices.  Clearly, the designers had SCSI and ATAPI commands in
  *
  * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more
  * information about this driver.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
 #include <linux/module.h>
@@ -88,6+107,7 @@ struct us_data {
        char                    *protocol_name;
        u8                      subclass;
        u8                      protocol;
+       u8                      max_lun;
 
        /* information about the device -- only good if device is attached */
        u8                      ifnum;           /* interface number   */
@@ -536,8+556,9 @@ static void invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
                /* save the old command */
                memcpy(old_cmnd, srb->cmnd, MAX_COMMAND_SIZE);
 
+               /* set the command and the LUN */
                srb->cmnd[0] = REQUEST_SENSE;
-               srb->cmnd[1] = 0;
+               srb->cmnd[1] = old_cmnd[1] & 0xE0;
                srb->cmnd[2] = 0;
                srb->cmnd[3] = 0;
                srb->cmnd[4] = 18;
@@ -791,7+812,7 @@ static int Bulk_max_lun(struct us_data *us)
                  result, data);
 
        /* if we have a successful request, return the result */
-       if (!result)
+       if (result == 1)
                return data;
 
        /* if we get a STALL, clear the stall */
@@ -839,6+860,9 @@ static int Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
        if (result == -EPIPE) {
                US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
                usb_clear_halt(us->pusb_dev, pipe);
+       } else if (result) {
+               /* unknown error -- we've got a problem */
+               return USB_STOR_TRANSPORT_ERROR;
        }
        
        /* if the command transfered well, then we go to the data stage */
@@ -976,25+1000,17 @@ static void ATAPI_command(Scsi_Cmnd *srb, struct us_data *us)
                srb->cmnd[0] = srb->cmnd[0] | 0x20;
                break;
        } /* end switch on cmnd[0] */
+       
+       /* convert MODE_SELECT data here */
+       if (old_cmnd == MODE_SELECT)
+               usb_stor_scsiSense6to10(srb);
 
        /* send the command to the transport layer */
        invoke_transport(srb, us);
 
-       /* Fix the MODE_SENSE data if we translated the command
-        */
-       if (old_cmnd == MODE_SENSE) {
-               unsigned char *dta = (unsigned char *)us->srb->request_buffer;
-
-               /* FIXME: we need to compress the entire data structure here
-                */
-               dta[0] = dta[1];        /* data len */
-               dta[1] = dta[2];        /* med type */
-               dta[2] = dta[3];        /* dev-spec prm */
-               dta[3] = dta[7];        /* block desc len */
-               printk (KERN_DEBUG USB_STORAGE
-                       "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n",
-                       dta[0], dta[1], dta[2], dta[3]);
-       }
+       /* Fix the MODE_SENSE data if we translated the command */
+       if ((old_cmnd == MODE_SENSE) && (srb->result == GOOD))
+               usb_stor_scsiSense10to6(srb);
 
        /* Fix-up the return data from an INQUIRY command to show 
         * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us
@@ -1084,24+1100,16 @@ static void ufi_command(Scsi_Cmnd *srb, struct us_data *us)
                break;
        } /* end switch on cmnd[0] */
 
+       /* convert MODE_SELECT data here */
+       if (old_cmnd == MODE_SELECT)
+               usb_stor_scsiSense6to10(srb);
+
        /* send the command to the transport layer */
        invoke_transport(srb, us);
        
-       /* Fix the MODE_SENSE data here if we had to translate the command
-        */
-       if (old_cmnd == MODE_SENSE) {
-               unsigned char *dta = (unsigned char *)us->srb->request_buffer;
-
-               /* FIXME: we need to compress the entire data structure here
-                */
-               dta[0] = dta[1];        /* data len */
-               dta[1] = dta[2];        /* med type */
-               dta[2] = dta[3];        /* dev-spec prm */
-               dta[3] = dta[7];        /* block desc len */
-               printk (KERN_DEBUG USB_STORAGE
-                       "new MODE_SENSE_6 data = %.2X %.2X %.2X %.2X\n",
-                       dta[0], dta[1], dta[2], dta[3]);
-       }
+       /* Fix the MODE_SENSE data if we translated the command */
+       if ((old_cmnd == MODE_SENSE) && (srb->result == GOOD))
+               usb_stor_scsiSense10to6(srb);
 
        /* Fix-up the return data from an INQUIRY command to show 
         * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us
@@ -1310,9+1318,8 @@ static int us_release(struct Scsi_Host *psh)
        down(&(us->notify));
        
        /* free the data structure we were using */
-       US_DEBUGP("-- freeing private host data structure\n");
+       US_DEBUGP("-- freeing URB\n");
        kfree(us->current_urb);
-       kfree(us);
        (struct us_data*)psh->hostdata[0] = NULL;
 
        /* we always have a successful release */
@@ -1536,11+1543,10 @@ static int usb_stor_control_thread(void * __us)
 
                switch (action) {
                case US_ACT_COMMAND:
-                       /* reject if target != 0 or if single-lun device
-                        * and LUN != 0
+                       /* reject if target != 0 or if LUN is higher than
+                        * the maximum known LUN
                         */
-                       if (us->srb->target ||
-                           ((us->flags & US_FL_SINGLE_LUN) && us->srb->lun)) {
+                       if (us->srb->target || (us->srb->lun > us->max_lun)) {
                                US_DEBUGP("Bad device number (%d/%d)\n",
                                          us->srb->target, us->srb->lun);
 
@@ -1623,32+1629,37 @@ static int usb_stor_control_thread(void * __us)
 
 /* This is the list of devices we recognize, along with their flag data */
 static struct us_unusual_dev us_unusual_dev_list[] = {
-       { 0x03f0, 0x0107, 0x0200,
-         "HP USB CD-Writer Plus", US_SC_8070, US_PR_CB, 0}, 
-       { 0x04e6, 0x0001, 0x0200,
-         "Matshita LS-120", US_SC_8020, US_PR_CB, US_FL_SINGLE_LUN},
-       { 0x04e6, 0x0002, 0x0100,
-         "Shuttle eUSCSI Bridge", US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
-       { 0x04e6, 0x0006, 0x0100,
-         "Shuttle eUSB MMC Adapter", US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN}, 
-       { 0x057b, 0x0000, 0x0114,
-         "Y-E Data Flashbuster-U", US_SC_UFI, US_PR_CB, US_FL_SINGLE_LUN},
-       { 0x059b, 0x0030, 0x0100,
-         "Iomega Zip 250", US_SC_SCSI, US_PR_BULK, US_FL_SINGLE_LUN},
-       { 0x0693, 0x0002, 0x0100,
-         "Hagiwara FlashGate SmartMedia", US_SC_SCSI, US_PR_BULK,
-         US_FL_ALT_LENGTH},
-       { 0x0781, 0x0001, 0x0200,
-         "Sandisk ImageMate (SDDR-01)", US_SC_SCSI, US_PR_CB, 
-         US_FL_SINGLE_LUN | US_FL_START_STOP},
-       { 0x0781, 0x0002, 0x0009,
-         "Sandisk Imagemate (SDDR-31)", US_SC_SCSI, US_PR_BULK, 
-         US_FL_SINGLE_LUN | US_FL_IGNORE_SER},
-       { 0x07af, 0x0005, 0x0100,
-         "Microtech USB-SCSI-HD50", US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
-       { 0x0000, 0x0000, 0x0,
-         "", 0, 0, 0}
-};
+       { 0x03f0, 0x0107, 0x0200, 0x0200, "HP USB CD-Writer Plus",
+               US_SC_8070, US_PR_CB, 0}, 
+       { 0x04e6, 0x0001, 0x0200, 0x0200, "Matshita LS-120",
+               US_SC_8020, US_PR_CB, US_FL_SINGLE_LUN},
+       { 0x04e6, 0x0002, 0x0100, 0x0100, "Shuttle eUSCSI Bridge",
+               US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
+       { 0x04e6, 0x0006, 0x0100, 0x0100, "Shuttle eUSB MMC Adapter",
+               US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN}, 
+       { 0x054c, 0x0010, 0x0210, 0x0210, "Sony DSC-S30", 
+               US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP |
+               US_FL_MODE_XLATE | US_FL_ALT_LENGTH},
+       { 0x054c, 0x002d, 0x0100, 0x0100, "Sony Memorystick MSAC-US1",
+               US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP |
+               US_FL_MODE_XLATE | US_FL_ALT_LENGTH},
+       { 0x057b, 0x0000, 0x0000, 0x0299, "Y-E Data Flashbuster-U",
+               US_SC_UFI,  US_PR_CB, US_FL_SINGLE_LUN},
+       { 0x057b, 0x0000, 0x0300, 0x9999, "Y-E Data Flashbuster-U",
+               US_SC_UFI,  US_PR_CBI, US_FL_SINGLE_LUN},
+       { 0x0693, 0x0002, 0x0100, 0x0100, "Hagiwara FlashGate SmartMedia",
+               US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH},
+       { 0x0781, 0x0001, 0x0200, 0x0200, "Sandisk ImageMate (SDDR-01)",
+               US_SC_SCSI, US_PR_CB, US_FL_SINGLE_LUN | US_FL_START_STOP},
+       { 0x0781, 0x0002, 0x0009, 0x0009, "Sandisk Imagemate (SDDR-31)",
+               US_SC_SCSI, US_PR_BULK, US_FL_IGNORE_SER},
+       { 0x07af, 0x0005, 0x0100, 0x0100, "Microtech USB-SCSI-HD50",
+               US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
+       { 0x05ab, 0x0031, 0x0100, 0x0100, "In-System USB/IDE Bridge",
+               US_SC_8070, US_PR_BULK, US_FL_ALT_LENGTH}, 
+       { 0x0693, 0x0005, 0x0100, 0x0100, "Hagiwara Flashgate",
+               US_SC_SCSI, US_PR_BULK, US_FL_ALT_LENGTH}, 
+       { 0 }};
 
 /* Search our ususual device list, based on vendor/product combinations
  * to see if we can support this device.  Returns a pointer to a structure
@@ -1667,7+1678,8 @@ static struct us_unusual_dev* us_find_dev(u16 idVendor, u16 idProduct,
        while ((ptr->idVendor != 0x0000) && 
               !((ptr->idVendor == idVendor) && 
                 (ptr->idProduct == idProduct) &&
-                (ptr->bcdDevice == bcdDevice)))
+                (ptr->bcdDeviceMin <= bcdDevice) &&
+                (ptr->bcdDeviceMax >= bcdDevice)))
                ptr++;
        
        /* if the search ended because we hit the end record, we failed */
@@ -1968,20+1980,21 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                        ss->transport_name = "Control/Bulk";
                        ss->transport = CB_transport;
                        ss->transport_reset = CB_reset;
+                       ss->max_lun = 7;
                        break;
                        
                case US_PR_CBI:
                        ss->transport_name = "Control/Bulk/Interrupt";
                        ss->transport = CBI_transport;
                        ss->transport_reset = CB_reset;
+                       ss->max_lun = 7;
                        break;
                        
                case US_PR_BULK:
                        ss->transport_name = "Bulk";
                        ss->transport = Bulk_transport;
                        ss->transport_reset = Bulk_reset;
-                       /* FIXME: for testing purposes only */
-                       Bulk_max_lun(ss);
+                       ss->max_lun = Bulk_max_lun(ss);
                        break;
                        
                default:
@@ -1994,6+2007,10 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
                }
                US_DEBUGP("Transport: %s\n", ss->transport_name);
 
+               /* fix for single-lun devices */
+               if (ss->flags & US_FL_SINGLE_LUN)
+                       ss->max_lun = 0;
+
                switch (ss->subclass) {
                case US_SC_RBC:
                        ss->protocol_name = "Reduced Block Commands (RBC)";
@@ -2134,6+2151,576 @@ static void storage_disconnect(struct usb_device *dev, void *ptr)
        up(&(ss->dev_semaphore));
 }
 
+/**************************************************************
+ **************************************************************/
+
+#define USB_STOR_SCSI_SENSE_HDRSZ 4
+#define USB_STOR_SCSI_SENSE_10_HDRSZ 8
+
+struct usb_stor_scsi_sense_hdr
+{
+  __u8* dataLength;
+  __u8* mediumType;
+  __u8* devSpecParms;
+  __u8* blkDescLength;
+};
+
+typedef struct usb_stor_scsi_sense_hdr Usb_Stor_Scsi_Sense_Hdr;
+
+union usb_stor_scsi_sense_hdr_u
+{
+  Usb_Stor_Scsi_Sense_Hdr hdr;
+  __u8* array[USB_STOR_SCSI_SENSE_HDRSZ];
+};
+
+typedef union usb_stor_scsi_sense_hdr_u Usb_Stor_Scsi_Sense_Hdr_u;
+
+struct usb_stor_scsi_sense_hdr_10
+{
+  __u8* dataLengthMSB;
+  __u8* dataLengthLSB;
+  __u8* mediumType;
+  __u8* devSpecParms;
+  __u8* reserved1;
+  __u8* reserved2;
+  __u8* blkDescLengthMSB;
+  __u8* blkDescLengthLSB;
+};
+
+typedef struct usb_stor_scsi_sense_hdr_10 Usb_Stor_Scsi_Sense_Hdr_10;
+
+union usb_stor_scsi_sense_hdr_10_u
+{
+  Usb_Stor_Scsi_Sense_Hdr_10 hdr;
+  __u8* array[USB_STOR_SCSI_SENSE_10_HDRSZ];
+};
+
+typedef union usb_stor_scsi_sense_hdr_10_u Usb_Stor_Scsi_Sense_Hdr_10_u;
+
+void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* , Usb_Stor_Scsi_Sense_Hdr_u*,
+                                   Usb_Stor_Scsi_Sense_Hdr_10_u*, int* );
+void usb_stor_print_Scsi_Cmnd( Scsi_Cmnd* cmd );
+
+int
+usb_stor_scsiSense10to6( Scsi_Cmnd* the10 )
+{
+  __u8 *buffer=0;
+  int outputBufferSize = 0;
+  int length=0;
+  struct scatterlist *sg = 0;
+  int i=0, j=0, element=0;
+  Usb_Stor_Scsi_Sense_Hdr_u the6Locations;
+  Usb_Stor_Scsi_Sense_Hdr_10_u the10Locations;
+  int sb=0,si=0,db=0,di=0;
+  int sgLength=0;
+
+#if 0
+  /* Make sure we get a MODE_SENSE_10 command */
+  if ( the10->cmnd[0] != MODE_SENSE_10 )
+    {
+      printk( KERN_ERR USB_STORAGE 
+             "Scsi_Cmnd was not a MODE_SENSE_10.\n" );
+      return -1;
+    }
+
+  /* Now start to format the output */
+  the10->cmnd[0] = MODE_SENSE;
+#endif
+  US_DEBUGP("-- converting 10 byte sense data to 6 byte\n");
+  the10->cmnd[0] = the10->cmnd[0] & 0xBF;
+
+  /* Determine buffer locations */
+  usb_stor_scsiSenseParseBuffer( the10, &the6Locations, &the10Locations,
+                                &length );
+
+  /* Work out minimum buffer to output */
+  outputBufferSize = *the10Locations.hdr.dataLengthLSB;
+  outputBufferSize += USB_STOR_SCSI_SENSE_HDRSZ;
+
+  /* Check to see if we need to truncate the output */
+  if ( outputBufferSize > length )
+    {
+      printk( KERN_WARNING USB_STORAGE 
+             "Had to truncate MODE_SENSE_10 buffer into MODE_SENSE.\n" );
+      printk( KERN_WARNING USB_STORAGE
+             "outputBufferSize is %d and length is %d.\n",
+             outputBufferSize, length );
+    }
+  outputBufferSize = length;
+
+  /* Data length */
+  if ( *the10Locations.hdr.dataLengthMSB != 0 ) /* MSB must be zero */
+    {
+      printk( KERN_WARNING USB_STORAGE 
+             "Command will be truncated to fit in SENSE6 buffer.\n" );
+      *the6Locations.hdr.dataLength = 0xff;
+    }
+  else
+    {
+      *the6Locations.hdr.dataLength = *the10Locations.hdr.dataLengthLSB;
+    }
+
+  /* Medium type and DevSpecific parms */
+  *the6Locations.hdr.mediumType = *the10Locations.hdr.mediumType;
+  *the6Locations.hdr.devSpecParms = *the10Locations.hdr.devSpecParms;
+
+  /* Block descriptor length */
+  if ( *the10Locations.hdr.blkDescLengthMSB != 0 ) /* MSB must be zero */
+    {
+      printk( KERN_WARNING USB_STORAGE 
+             "Command will be truncated to fit in SENSE6 buffer.\n" );
+      *the6Locations.hdr.blkDescLength = 0xff;
+    }
+  else
+    {
+      *the6Locations.hdr.blkDescLength = *the10Locations.hdr.blkDescLengthLSB;
+    }
+
+  if ( the10->use_sg == 0 )
+    {
+      buffer = the10->request_buffer;
+      /* Copy the rest of the data */
+      memmove( &(buffer[USB_STOR_SCSI_SENSE_HDRSZ]),
+              &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]),
+              outputBufferSize - USB_STOR_SCSI_SENSE_HDRSZ );
+      /* initialise last bytes left in buffer due to smaller header */
+      memset( &(buffer[outputBufferSize
+           -(USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ)]),
+             0,
+             USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ );
+    }
+  else
+    {
+      sg = (struct scatterlist *) the10->request_buffer;
+      /* scan through this scatterlist and figure out starting positions */
+      for ( i=0; i < the10->use_sg; i++)
+       {
+         sgLength = sg[i].length;
+         for ( j=0; j<sgLength; j++ )
+           {
+             /* get to end of header */
+             if ( element == USB_STOR_SCSI_SENSE_HDRSZ )
+               {
+                 db=i;
+                 di=j;
+               }
+             if ( element == USB_STOR_SCSI_SENSE_10_HDRSZ )
+               {
+                 sb=i;
+                 si=j;
+                 /* we've found both sets now, exit loops */
+                 j=sgLength;
+                 i=the10->use_sg;
+               }
+             element++;
+           }
+       }
+
+      /* Now we know where to start the copy from */
+      element = USB_STOR_SCSI_SENSE_HDRSZ;
+      while ( element < outputBufferSize
+             -(USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ) )
+       {
+         /* check limits */
+         if ( sb >= the10->use_sg ||
+              si >= sg[sb].length ||
+              db >= the10->use_sg ||
+              di >= sg[db].length )
+           {
+             printk( KERN_ERR USB_STORAGE
+                     "Buffer overrun averted, this shouldn't happen!\n" );
+             break;
+           }
+
+         /* copy one byte */
+         sg[db].address[di] = sg[sb].address[si];
+
+         /* get next destination */
+         if ( sg[db].length-1 == di )
+           {
+             db++;
+             di=0;
+           }
+         else
+           {
+             di++;
+           }
+
+         /* get next source */
+         if ( sg[sb].length-1 == si )
+           {
+             sb++;
+             si=0;
+           }
+         else
+           {
+             si++;
+           }
+
+         element++;
+       }
+      /* zero the remaining bytes */
+      while ( element < outputBufferSize )
+       {
+         /* check limits */
+         if ( db >= the10->use_sg ||
+              di >= sg[db].length )
+           {
+             printk( KERN_ERR USB_STORAGE
+                     "Buffer overrun averted, this shouldn't happen!\n" );
+             break;
+           }
+
+         sg[db].address[di] = 0;
+
+         /* get next destination */
+         if ( sg[db].length-1 == di )
+           {
+             db++;
+             di=0;
+           }
+         else
+           {
+             di++;
+           }
+         element++;
+       }
+    }
+
+  /* All done any everything was fine */
+  return 0;
+}
+
+int
+usb_stor_scsiSense6to10( Scsi_Cmnd* the6 )
+{
+  /* will be used to store part of buffer */  
+  __u8 tempBuffer[USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ],
+    *buffer=0;
+  int outputBufferSize = 0;
+  int length=0;
+  struct scatterlist *sg = 0;
+  int i=0, j=0, element=0;
+  Usb_Stor_Scsi_Sense_Hdr_u the6Locations;
+  Usb_Stor_Scsi_Sense_Hdr_10_u the10Locations;
+  int sb=0,si=0,db=0,di=0;
+  int lsb=0,lsi=0,ldb=0,ldi=0;
+
+#if 0
+  /* Make sure we get a MODE_SENSE command */
+  if ( the6->cmnd[0] != MODE_SENSE )
+    {
+      printk( KERN_ERR USB_STORAGE 
+             "Scsi_Cmnd was not MODE_SENSE.\n" );
+      return -1;
+    }
+
+  /* Now start to format the output */
+  the6->cmnd[0] = MODE_SENSE_10;
+#endif
+  US_DEBUGP("-- converting 6 byte sense data to 10 byte\n");
+  the6->cmnd[0] = the6->cmnd[0] | 0x40;
+
+  /* Determine buffer locations */
+  usb_stor_scsiSenseParseBuffer( the6, &the6Locations, &the10Locations,
+                                &length );
+
+  /* Work out minimum buffer to output */
+  outputBufferSize = *the6Locations.hdr.dataLength;
+  outputBufferSize += USB_STOR_SCSI_SENSE_10_HDRSZ;
+
+  /* Check to see if we need to trucate the output */
+  if ( outputBufferSize > length )
+    {
+      printk( KERN_WARNING USB_STORAGE 
+             "Had to truncate MODE_SENSE into MODE_SENSE_10 buffer.\n" );
+      printk( KERN_WARNING USB_STORAGE
+             "outputBufferSize is %d and length is %d.\n",
+             outputBufferSize, length );
+    }
+  outputBufferSize = length;
+
+  /* Block descriptor length - save these before overwriting */
+  tempBuffer[2] = *the10Locations.hdr.blkDescLengthMSB;
+  tempBuffer[3] = *the10Locations.hdr.blkDescLengthLSB;
+  *the10Locations.hdr.blkDescLengthLSB = *the6Locations.hdr.blkDescLength;
+  *the10Locations.hdr.blkDescLengthMSB = 0;
+
+  /* reserved - save these before overwriting */
+  tempBuffer[0] = *the10Locations.hdr.reserved1;
+  tempBuffer[1] = *the10Locations.hdr.reserved2;
+  *the10Locations.hdr.reserved1 = *the10Locations.hdr.reserved2 = 0;
+
+  /* Medium type and DevSpecific parms */
+  *the10Locations.hdr.devSpecParms = *the6Locations.hdr.devSpecParms;
+  *the10Locations.hdr.mediumType = *the6Locations.hdr.mediumType;
+
+  /* Data length */
+  *the10Locations.hdr.dataLengthLSB = *the6Locations.hdr.dataLength;
+  *the10Locations.hdr.dataLengthMSB = 0;
+
+  if ( !the6->use_sg )
+    {
+      buffer = the6->request_buffer;
+      /* Copy the rest of the data */
+      memmove( &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]),
+             &(buffer[USB_STOR_SCSI_SENSE_HDRSZ]),
+             outputBufferSize-USB_STOR_SCSI_SENSE_10_HDRSZ );
+      /* Put the first four bytes (after header) in place */
+      memcpy( &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]),
+             tempBuffer,
+             USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ );
+    }
+  else
+    {
+      sg = (struct scatterlist *) the6->request_buffer;
+      /* scan through this scatterlist and figure out ending positions */
+      for ( i=0; i < the6->use_sg; i++)
+       {
+         for ( j=0; j<sg[i].length; j++ )
+           {
+             /* get to end of header */
+             if ( element == USB_STOR_SCSI_SENSE_HDRSZ )
+               {
+                 ldb=i;
+                 ldi=j;
+               }
+             if ( element == USB_STOR_SCSI_SENSE_10_HDRSZ )
+               {
+                 lsb=i;
+                 lsi=j;
+                 /* we've found both sets now, exit loops */
+                 j=sg[i].length;
+                 i=the6->use_sg;
+                 break;
+               }
+             element++;
+           }
+       }
+      /* scan through this scatterlist and figure out starting positions */
+      element = length-1;
+      /* destination is the last element */
+      db=the6->use_sg-1;
+      di=sg[db].length-1;
+      for ( i=the6->use_sg-1; i >= 0; i--)
+       {
+         for ( j=sg[i].length-1; j>=0; j-- )
+           {
+             /* get to end of header and find source for copy */
+             if ( element == length - 1
+                  - (USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ) )
+               {
+                 sb=i;
+                 si=j;
+                 /* we've found both sets now, exit loops */
+                 j=-1;
+                 i=-1;
+               }
+             element--;
+           }
+       }
+      /* Now we know where to start the copy from */
+      element = length-1
+       - (USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ);
+      while ( element >= USB_STOR_SCSI_SENSE_10_HDRSZ )
+       {
+         /* check limits */
+         if ( ( sb <= lsb && si < lsi ) ||
+              ( db <= ldb && di < ldi ) )
+           {
+             printk( KERN_ERR USB_STORAGE
+                     "Buffer overrun averted, this shouldn't happen!\n" );
+             break;
+           }
+
+         /* copy one byte */
+         sg[db].address[di] = sg[sb].address[si];
+
+         /* get next destination */
+         if ( di == 0 )
+           {
+             db--;
+             di=sg[db].length-1;
+           }
+         else
+           {
+             di--;
+           }
+
+         /* get next source */
+         if ( si == 0 )
+           {
+             sb--;
+             si=sg[sb].length-1;
+           }
+         else
+           {
+             si--;
+           }
+
+         element--;
+       }
+      /* copy the remaining four bytes */
+      while ( element >= USB_STOR_SCSI_SENSE_HDRSZ )
+       {
+         /* check limits */
+         if ( db <= ldb && di < ldi )
+           {
+             printk( KERN_ERR USB_STORAGE
+                     "Buffer overrun averted, this shouldn't happen!\n" );
+             break;
+           }
+
+         sg[db].address[di] = tempBuffer[element-USB_STOR_SCSI_SENSE_HDRSZ];
+
+         /* get next destination */
+         if ( di == 0 )
+           {
+             db--;
+             di=sg[db].length-1;
+           }
+         else
+           {
+             di--;
+           }
+         element--;
+       }
+    }
+
+  /* All done and everything was fine */
+  return 0;
+}
+
+void
+usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* the6,
+                              Usb_Stor_Scsi_Sense_Hdr_10_u* the10,
+                              int* length_p )
+
+{
+  int i = 0, j=0, element=0;
+  struct scatterlist *sg = 0;
+  int length = 0;
+  __u8* buffer=0;
+
+  /* are we scatter-gathering? */
+  if ( srb->use_sg != 0 )
+    {
+      /* loop over all the scatter gather structures and 
+       * get pointer to the data members in the headers
+       * (also work out the length while we're here)
+       */
+      sg = (struct scatterlist *) srb->request_buffer;
+      for (i = 0; i < srb->use_sg; i++)
+       {
+         length += sg[i].length;
+         /* We only do the inner loop for the headers */
+         if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ )
+           {
+             /* scan through this scatterlist */
+             for ( j=0; j<sg[i].length; j++ )
+               {
+                 if ( element < USB_STOR_SCSI_SENSE_HDRSZ )
+                   {
+                     /* fill in the pointers for both header types */
+                     the6->array[element] = &(sg[i].address[j]);
+                     the10->array[element] = &(sg[i].address[j]);
+                   }
+                 else if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ )
+                   {
+                     /* only the longer headers still cares now */
+                     the10->array[element] = &(sg[i].address[j]);
+                   }
+                 /* increase element counter */
+                 element++;
+               }
+           }
+       }
+    }
+  else
+    {
+      length = srb->request_bufflen;
+      buffer = srb->request_buffer;
+      if ( length < USB_STOR_SCSI_SENSE_10_HDRSZ )
+       printk( KERN_ERR USB_STORAGE
+               "Buffer length smaller than header!!" );
+      for( i=0; i<USB_STOR_SCSI_SENSE_10_HDRSZ; i++ )
+       {
+         if ( i < USB_STOR_SCSI_SENSE_HDRSZ )
+           {
+             the6->array[i] = &(buffer[i]);
+             the10->array[i] = &(buffer[i]);
+           }
+         else
+           {
+             the10->array[i] = &(buffer[i]);
+           }
+       }
+    }
+
+  /* Set value of length passed in */
+  *length_p = length;
+}
+
+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;
+
+  printk( KERN_ERR "Dumping information about %p.\n", cmd );
+  printk( KERN_ERR "cmd->cmnd[0] value is %d.\n", cmd->cmnd[0] );
+  printk( KERN_ERR "(MODE_SENSE is %d and MODE_SENSE_10 is %d)\n",
+         MODE_SENSE, MODE_SENSE_10 );
+
+  printk( KERN_ERR "buffer is %p with length %d.\n", buffer, bufferSize );
+  for ( i=0; i<bufferSize; i+=16 )
+    {
+      printk( KERN_ERR "%2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",
+             buffer[i],
+             buffer[i+1],
+             buffer[i+2],
+             buffer[i+3],
+             buffer[i+4],
+             buffer[i+5],
+             buffer[i+6],
+             buffer[i+7],
+             buffer[i+8],
+             buffer[i+9],
+             buffer[i+10],
+             buffer[i+11],
+             buffer[i+12],
+             buffer[i+13],
+             buffer[i+14],
+             buffer[i+15] );
+    }
+
+  printk( KERN_ERR "Buffer has %d scatterlists.\n", cmd->use_sg );
+  for ( i=0; i<cmd->use_sg; i++ )
+    {
+      printk( KERN_ERR "Length of scatterlist %d is %d.\n", i, sg[i].length );
+      printk( KERN_ERR "%2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",
+             sg[i].address[0],
+             sg[i].address[1],
+             sg[i].address[2],
+             sg[i].address[3],
+             sg[i].address[4],
+             sg[i].address[5],
+             sg[i].address[6],
+             sg[i].address[7],
+             sg[i].address[8],
+             sg[i].address[9],
+             sg[i].address[10],
+             sg[i].address[11],
+             sg[i].address[12],
+             sg[i].address[13],
+             sg[i].address[14],
+             sg[i].address[15] );
+    }
+}
+
+/**************************************************************
+ **************************************************************/
 
 /***********************************************************************
  * Initialization and registration
@@ -2183,6+2770,11 @@ void __exit usb_stor_exit(void)
                US_DEBUGP("-- calling scsi_unregister_module()\n");
                scsi_unregister_module(MODULE_SCSI_HA, &(us_list->htmplt));
 
+                /* Now that scsi_unregister_module is done with the host
+                 * template, we can free the us_data structure (the host
+                 * template is inline in this structure). */
+                kfree (us_list);
+
                /* advance the list pointer */
                us_list = next;
        }
index 6e54b05..82475f0 100644 (file)
@@ -139,7+139,8 @@ struct us_unusual_dev {
        /* we search the list based on these parameters */
        __u16 idVendor;
        __u16 idProduct;
-       __u16 bcdDevice;
+       __u16 bcdDeviceMin;
+       __u16 bcdDeviceMax;
 
        /* the list specifies these parameters */
        const char* name;
index 83e5dac..6529b53 100644 (file)
@@ -120,6+120,7 @@ if [ "$CONFIG_FB" = "y" ]; then
         tristate '  ATI Mach64 display support (EXPERIMENTAL)' CONFIG_FB_ATY
         tristate '  ATI Rage 128 display support (EXPERIMENTAL)' CONFIG_FB_ATY128
         bool '  3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
+        tristate '  SIS 630/540 display support (EXPERIMENTAL)' CONFIG_FB_SIS
       fi
    fi
    if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
index 7b83f69..d42448f 100644 (file)
 #define FALSE   0
 #define TRUE    1
 
-/* Draw Function */
+/* Draw Function 
 #define FBIOGET_GLYPH        0x4620
 #define FBIOGET_HWCINFO      0x4621
+*/
 #define BR(x)   (0x8200 | (x) << 2)
 
 #define BITBLT               0x00000000
 #define MMIO_SIZE                 0x20000      /* 128K MMIO capability */
 #define MAX_ROM_SCAN              0x10000
 
-#define RESERVED_MEM_SIZE         0x400000     /* 4M */
+#define RESERVED_MEM_SIZE_4M      0x400000     /* 4M */
+#define RESERVED_MEM_SIZE_8M      0x800000     /* 8M */
 
 /* Mode set stuff */
 #define DEFAULT_MODE      0
@@ -173,9+175,9 @@ static struct board {
        const char *name;
 } dev_list[] = {
        {
-       PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_300, "SIS 300"}, {
-       PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_540, "SIS 540"}, {
-       PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS_630, "SIS 630"}, {
+       PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_300, "SIS 300"}, {
+       PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_540, "SIS 540"}, {
+       PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_630, "SIS 630"}, {
        0, 0, NULL}
 };
 
@@ -1020,8+1022,11 @@ static int sisfb_heap_init(void)
        struct OH *poh;
        u8 jTemp, tq_state;
 
-       heap_start = (unsigned long) ivideo.video_vbase + RESERVED_MEM_SIZE;
-       //heap_start = (unsigned long)ivideo.video_vbase + (video_size - RESERVED_MEM_SIZE);
+       if(ivideo.video_size > 0x800000)   /* video ram is large than 8M */
+               heap_start = (unsigned long) ivideo.video_vbase + RESERVED_MEM_SIZE_8M;
+       else
+               heap_start = (unsigned long) ivideo.video_vbase + RESERVED_MEM_SIZE_4M;
+
        heap_end = (unsigned long) ivideo.video_vbase + ivideo.video_size;
        heap_size = heap_end - heap_start;
 
@@ -1398,6+1403,7 @@ static u32 get_reg3(u16 port)
 
 static u16 get_modeID_length(unsigned long ROMAddr, u16 ModeNo)
 {
+#if 0
        unsigned char ModeID;
        u16 modeidlength;
        u16 usModeIDOffset;
@@ -1411,6+1417,8 @@ static u16 get_modeID_length(unsigned long ROMAddr, u16 ModeNo)
                ModeID = *((unsigned char *) (ROMAddr + usModeIDOffset));
        }
        return (modeidlength);
+#endif
+       return(10);
 }
 
 static int search_modeID(unsigned long ROMAddr, u16 ModeNo)
@@ -2467,7+2475,11 @@ static int sisfb_get_fix(struct fb_fix_screeninfo *fix, int con,
        strcpy(fix->id, fb_info.modename);
 
        fix->smem_start = ivideo.video_base;
-       fix->smem_len = RESERVED_MEM_SIZE;      /* reserved for Xserver */
+       if(ivideo.video_size > 0x800000)
+               fix->smem_len = RESERVED_MEM_SIZE_8M;   /* reserved for Xserver */
+       else
+               fix->smem_len = RESERVED_MEM_SIZE_4M;   /* reserved for Xserver */
+
        fix->type = video_type;
        fix->type_aux = 0;
        if (ivideo.video_bpp == 8)
index 9f00506..5e49df1 100644 (file)
@@ -450,7+450,7 @@ static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs)
                if (elf_ppnt->p_type == PT_INTERP) {
                        retval = -EINVAL;
                        if (elf_interpreter)
-                               goto out_free_interp;
+                               goto out_free_dentry;
 
                        /* This is the program interpreter used for
                         * shared libraries - for now assume that this
index a1401b4..2ab3373 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -484,6+484,8 @@ int flush_old_exec(struct linux_binprm * bprm)
        /* This is the point of no return */
        release_old_signals(oldsig);
 
+       current->sas_ss_sp = current->sas_ss_size = 0;
+
        if (current->euid == current->uid && current->egid == current->gid)
                current->dumpable = 1;
        name = bprm->filename;
@@ -585,21+587,18 @@ int prepare_binprm(struct linux_binprm *bprm)
        cap_clear(bprm->cap_effective);
 
        /*  To support inheritance of root-permissions and suid-root
-         *  executables under compatibility mode, we raise the
-         *  effective and inherited bitmasks of the executable file
-         *  (translation: we set the executable "capability dumb" and
-         *  set the allowed set to maximum). We don't set any forced
-         *  bits.
+         *  executables under compatibility mode, we raise all three
+         *  capability sets for the file.
          *
          *  If only the real uid is 0, we only raise the inheritable
-         *  bitmask of the executable file (translation: we set the
-         *  allowed set to maximum and the application to "capability
-         *  smart"). 
+         *  and permitted sets of the executable file.
          */
 
        if (!issecure(SECURE_NOROOT)) {
-               if (bprm->e_uid == 0 || current->uid == 0)
+               if (bprm->e_uid == 0 || current->uid == 0) {
                        cap_set_full(bprm->cap_inheritable);
+                       cap_set_full(bprm->cap_permitted);
+               }
                if (bprm->e_uid == 0) 
                        cap_set_full(bprm->cap_effective);
        }
@@ -610,10+609,12 @@ int prepare_binprm(struct linux_binprm *bprm)
          * privilege does not go against other system constraints.
          * The new Permitted set is defined below -- see (***). */
        {
-               kernel_cap_t working =
-                       cap_combine(bprm->cap_permitted,
-                                   cap_intersect(bprm->cap_inheritable,
-                                                 current->cap_inheritable));
+               kernel_cap_t permitted, working;
+
+               permitted = cap_intersect(bprm->cap_permitted, cap_bset);
+               working = cap_intersect(bprm->cap_inheritable,
+                                       current->cap_inheritable);
+               working = cap_combine(permitted, working);
                if (!cap_issubset(working, current->cap_permitted)) {
                        cap_raised = 1;
                }
@@ -646,26+647,29 @@ int prepare_binprm(struct linux_binprm *bprm)
  * The formula used for evolving capabilities is:
  *
  *       pI' = pI
- * (***) pP' = fP | (fI & pI)
+ * (***) pP' = (fP & X) | (fI & pI)
  *       pE' = pP' & fE          [NB. fE is 0 or ~0]
  *
  * I=Inheritable, P=Permitted, E=Effective // p=process, f=file
- * ' indicates post-exec().
+ * ' indicates post-exec(), and X is the global 'cap_bset'.
  */
 
 void compute_creds(struct linux_binprm *bprm) 
 {
-       int new_permitted = cap_t(bprm->cap_permitted) |
-               (cap_t(bprm->cap_inheritable) & 
-                cap_t(current->cap_inheritable));
+       kernel_cap_t new_permitted, working;
+
+       new_permitted = cap_intersect(bprm->cap_permitted, cap_bset);
+       working = cap_intersect(bprm->cap_inheritable,
+                               current->cap_inheritable);
+       new_permitted = cap_combine(new_permitted, working);
 
        /* For init, we want to retain the capabilities set
          * in the init_task struct. Thus we skip the usual
          * capability rules */
        if (current->pid != 1) {
-               cap_t(current->cap_permitted) = new_permitted;
-               cap_t(current->cap_effective) = new_permitted & 
-                                               cap_t(bprm->cap_effective);
+               current->cap_permitted = new_permitted;
+               current->cap_effective =
+                       cap_intersect(new_permitted, bprm->cap_effective);
        }
        
         /* AUD: Audit candidate if current->cap_effective is set */
index 264c19c..c9e4b4b 100644 (file)
@@ -235,7+235,10 @@ lockd_up(void)
        }
 
        if ((error = svc_makesock(serv, IPPROTO_UDP, 0)) < 0 
-        || (error = svc_makesock(serv, IPPROTO_TCP, 0)) < 0) {
+#ifdef CONFIG_NFSD_TCP
+        || (error = svc_makesock(serv, IPPROTO_TCP, 0)) < 0
+#endif
+               ) {
                if (warned++ == 0) 
                        printk(KERN_WARNING
                                "lockd_up: makesock failed, error=%d\n", error);
index 1d5b538..9bcc192 100644 (file)
@@ -79,7+79,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result,
                goto out_unlock;
 
        memset(file, 0, sizeof(*file));
-       file->f_handle = *f;
+       memcpy(&file->f_handle, f, sizeof(struct nfs_fh));
        file->f_hash = hash;
        init_MUTEX(&file->f_sema);
 
index 41c2038..9a179d5 100644 (file)
@@ -86,7+86,7 @@ nlm_decode_fh(u32 *p, struct nfs_fh *f)
 
        if ((len = ntohl(*p++)) != NFS2_FHSIZE) {
                printk(KERN_NOTICE
-                       "lockd: bad fhandle size %x (should be %u)\n",
+                       "lockd: bad fhandle size %x (should be %Zu)\n",
                        len, NFS2_FHSIZE);
                return NULL;
        }
index f35ef3b..2d6365c 100644 (file)
 #include <linux/nfs_mount.h>
 #include <linux/pagemap.h>
 
-#include <asm/segment.h>       /* for fs functions */
-
 #define NFS_PARANOIA 1
 /* #define NFS_DEBUG_VERBOSE 1 */
 
index 44e7171..62b37c8 100644 (file)
 #include <linux/smp_lock.h>
 
 #include <asm/uaccess.h>
-#include <asm/segment.h>
 #include <asm/system.h>
 
 #define NFSDBG_FACILITY                NFSDBG_FILE
index 31b9705..aedda1e 100644 (file)
@@ -705,7+705,7 @@ nfs_fhget(struct dentry *dentry, struct nfs_fh *fhandle,
                (long long)fattr->fileid);
 
        /* Install the file handle in the dentry */
-       *((struct nfs_fh *) dentry->d_fsdata) = *fhandle;
+       memcpy(dentry->d_fsdata, fhandle, sizeof(struct nfs_fh));
 
 #ifdef CONFIG_NFS_SNAPSHOT
        /*
index 921841b..4219141 100644 (file)
 #include <linux/nfs3.h>
 #include <linux/nfs_fs.h>
 
-#include <asm/segment.h>
-
 #define NFSDBG_FACILITY                NFSDBG_PROC
 
 /*
index 0abf65a..373d729 100644 (file)
 #include <linux/nfs2.h>
 #include <linux/nfs_fs.h>
 
-#include <asm/segment.h>
-
 #define NFSDBG_FACILITY                NFSDBG_PROC
 
 /*
@@ -203,7+201,7 @@ nfs_proc_mknod(struct dentry *dir, struct qstr *name, struct iattr *sattr,
        if (S_ISFIFO(mode)) {
                sattr->ia_mode = (mode & ~S_IFMT) | S_IFCHR;
                sattr->ia_valid &= ~ATTR_SIZE;
-       } else if (S_ISCHR(rdev) || S_ISBLK(rdev)) {
+       } else if (S_ISCHR(mode) || S_ISBLK(mode)) {
                sattr->ia_valid |= ATTR_SIZE;
                sattr->ia_size   = rdev;        /* get out your barf bag */
        }
index b15f50e..e51adbd 100644 (file)
 #include <linux/nfs_flushd.h>
 #include <linux/smp_lock.h>
 
-#include <asm/segment.h>
 #include <asm/system.h>
 
 #define NFSDBG_FACILITY                NFSDBG_PAGECACHE
index b674d1e..dee52dd 100644 (file)
@@ -430,13+430,12 @@ exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino,
         * fh must be initialized before calling fh_compose
         */
        fh_init(&fh, maxsize);
-       if (fh_compose(&fh, exp, nd.dentry))
+       if (fh_compose(&fh, exp, dget(nd.dentry)))
                err = -EINVAL;
        else
                err = 0;
        memcpy(f, &fh.fh_handle, sizeof(struct knfsd_fh));
        fh_put(&fh);
-       return err;
 
 out:
        path_release(&nd);
index 8f69cb5..e6118a9 100644 (file)
@@ -658,7+658,7 @@ struct svc_procedure                nfsd_procedures3[22] = {
   PROC(mknod,   mknod,         create,         fhandle2, RC_REPLBUFF),
   PROC(remove,  dirop,         wccstat,        fhandle,  RC_REPLBUFF),
   PROC(rmdir,   dirop,         wccstat,        fhandle,  RC_REPLBUFF),
-  PROC(rename,  rename,        rename,         fhandle RC_REPLBUFF),
+  PROC(rename,  rename,        rename,         fhandle2, RC_REPLBUFF),
   PROC(link,    link,          link,           fhandle2, RC_REPLBUFF),
   PROC(readdir,         readdir,       readdir,        fhandle,  RC_NOCACHE),
   PROC(readdirplus,readdirplus,        readdir,        fhandle,  RC_NOCACHE),
index 97acf31..948566a 100644 (file)
@@ -698,17+698,9 @@ encode_entry(struct readdir_cd *cd, const char *name,
                cd->eob = 1;
                return -EINVAL;
        }
-       *p++ = xdr_one;                            /* mark entry present */
-       p    = xdr_encode_hyper(p, ino);                           /* file id */
-       p[slen - 1] = 0;                /* don't leak kernel data */
-#ifdef XDR_ENCODE_STRING_TAKES_LENGTH
-       p    = xdr_encode_string(p, name, namlen); /* name length & name */
-#else
-       /* just like nfsproc.c */
-       *p++ = htonl((u32) namlen);
-       memcpy(p, name, namlen);
-       p += slen;
-#endif
+       *p++ = xdr_one;                          /* mark entry present */
+       p    = xdr_encode_hyper(p, ino);         /* file id */
+       p    = xdr_encode_array(p, name, namlen);/* name length & name */
 
        cd->offset = p;                 /* remember pointer */
        p = xdr_encode_hyper(p, NFS_OFFSET_MAX);        /* offset of next entry */
index fa9cc60..357a297 100644 (file)
@@ -60,7+60,7 @@ nfsd_cache_init(void)
        nfscache = (struct svc_cacherep *)
                __get_free_pages(GFP_KERNEL, order);
        if (!nfscache) {
-               printk (KERN_ERR "nfsd: cannot allocate %Zu bytes for reply cache\n", i);
+               printk (KERN_ERR "nfsd: cannot allocate %d bytes for reply cache\n", i);
                return;
        }
        memset(nfscache, 0, i);
@@ -70,7+70,7 @@ nfsd_cache_init(void)
        if (!hash_list) {
                free_pages ((unsigned long)nfscache, order);
                nfscache = NULL;
-               printk (KERN_ERR "nfsd: cannot allocate %Zu bytes for hash list\n", i);
+               printk (KERN_ERR "nfsd: cannot allocate %d bytes for hash list\n", i);
                return;
        }
 
index 84ec4e3..85a98c8 100644 (file)
@@ -367,7+367,7 @@ find_fh_dentry(struct super_block *sb, ino_t ino, int generation, ino_t dirino,
        /* It's a directory, or we are required to confirm the file's
         * location in the tree.
         */
-       dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,(long) ino);
+       dprintk("nfs_fh: need to look harder for %d/%ld\n",sb->s_dev,ino);
        down(&sb->s_nfsd_free_path_sem);
 
        /* claiming the semaphore might have allowed things to get fixed up */
index 2984f03..7b9546d 100644 (file)
@@ -412,11+412,9 @@ nfssvc_encode_entry(struct readdir_cd *cd, const char *name,
                cd->eob = 1;
                return -EINVAL;
        }
-       *p++ = xdr_one;                 /* mark entry present */
-       *p++ = htonl((u32) ino);        /* file id */
-       *p++ = htonl((u32) namlen);     /* name length & name */
-       memcpy(p, name, namlen);
-       p += slen;
+       *p++ = xdr_one;                         /* mark entry present */
+       *p++ = htonl((u32) ino);                /* file id */
+       p    = xdr_encode_array(p, name, namlen);/* name length & name */
        cd->offset = p;                 /* remember pointer */
        *p++ = ~(u32) 0;                /* offset of next entry */
 
index 3bdeb2c..40f1ab8 100644 (file)
 #include <linux/unistd.h>
 #include <linux/malloc.h>
 #include <linux/in.h>
+#define __NO_VERSION__
+#include <linux/module.h>
 
 #include <linux/sunrpc/svc.h>
 #include <linux/nfsd/nfsd.h>
@@ -451,7+453,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
                goto out_nfserr;
 
        memset(filp, 0, sizeof(*filp));
-       filp->f_op    = inode->i_fop;
+       filp->f_op    = fops_get(inode->i_fop);
        atomic_set(&filp->f_count, 1);
        filp->f_dentry = dentry;
        if (access & MAY_WRITE) {
@@ -467,6+469,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
        if (filp->f_op && filp->f_op->open) {
                err = filp->f_op->open(inode, filp);
                if (err) {
+                       fops_put(filp->f_op);
                        if (access & MAY_WRITE)
                                put_write_access(inode);
 
@@ -494,6+497,7 @@ nfsd_close(struct file *filp)
 
        if (filp->f_op && filp->f_op->release)
                filp->f_op->release(inode, filp);
+       fops_put(filp->f_op);
        if (filp->f_mode & FMODE_WRITE)
                put_write_access(inode);
 }
index 37915c8..23460fc 100644 (file)
@@ -66,8+66,10 @@ static void __init copro_timeout(void)
 static double __initdata x = 4195835.0;
 static double __initdata y = 3145727.0;
 
+#ifdef CONFIG_X86_XMM
 static float __initdata zero[4] = { 0.0, 0.0, 0.0, 0.0 };
 static float __initdata one[4] = { 1.0, 1.0, 1.0, 1.0 };
+#endif
 
 static void __init check_fpu(void)
 {
index 9835842..9ac8df6 100644 (file)
@@ -1,6+1,7 @@
 #ifndef __ASM_IO_APIC_H
 #define __ASM_IO_APIC_H
 
+#include <linux/config.h>
 #include <asm/types.h>
 
 /*
index 41a3e2a..ce0dea3 100644 (file)
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
-#include <linux/config.h>
-
 #include <asm/mman.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 
 #include <asm/bitops.h>
 #include <asm/mmu_context.h>
-#include <asm/processor.h>
 #include <asm/system.h>
 
 /*
index 394c96b..a1e9dc3 100644 (file)
@@ -4,6+4,10 @@
  * Andrew G. Morgan <morgan@transmeta.com>
  * Alexander Kjeldaas <astor@guardian.no>
  * with help from Aleph1, Roland Buresund and Andrew Main.
+ *
+ * See here for the libcap library ("POSIX draft" compliance):
+ *
+ * ftp://linux.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/
  */ 
 
 #ifndef _LINUX_CAPABILITY_H
@@ -170,8+174,8 @@ typedef __u32 kernel_cap_t;
 
 #define CAP_IPC_OWNER        15
 
-/* Insert and remove kernel modules */
-
+/* Insert and remove kernel modules - modify kernel without limit */
+/* Modify cap_bset */
 #define CAP_SYS_MODULE       16
 
 /* Allow ioperm/iopl access */
@@ -294,12+298,12 @@ extern kernel_cap_t cap_bset;
 #define CAP_EMPTY_SET       to_cap_t(0)
 #define CAP_FULL_SET        to_cap_t(~0)
 #define CAP_INIT_EFF_SET    to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
-#define CAP_INIT_INH_SET    to_cap_t(~0 & ~CAP_TO_MASK(CAP_SETPCAP))
+#define CAP_INIT_INH_SET    to_cap_t(0)
 
 #define CAP_TO_MASK(x) (1 << (x))
 #define cap_raise(c, flag)   (cap_t(c) |=  CAP_TO_MASK(flag))
 #define cap_lower(c, flag)   (cap_t(c) &= ~CAP_TO_MASK(flag))
-#define cap_raised(c, flag)  (cap_t(c) & CAP_TO_MASK(flag) & cap_bset)
+#define cap_raised(c, flag)  (cap_t(c) & CAP_TO_MASK(flag))
 
 static inline kernel_cap_t cap_combine(kernel_cap_t a, kernel_cap_t b)
 {
index 4147f05..896dade 100644 (file)
 #define FBIOGET_VBLANK         _IOR('F', 0x12, struct fb_vblank)
 #define FBIO_ALLOC              0x4613
 #define FBIO_FREE               0x4614
+#define FBIOGET_GLYPH           0x4615
+#define FBIOGET_HWCINFO         0x4616
 
 #define FB_TYPE_PACKED_PIXELS          0       /* Packed Pixels        */
 #define FB_TYPE_PLANES                 1       /* Non interleaved planes */
index a5bc92e..61ac59d 100644 (file)
 #define PCI_DEVICE_ID_SI_6205          0x0205
 #define PCI_DEVICE_ID_SI_501           0x0406
 #define PCI_DEVICE_ID_SI_496           0x0496
+#define PCI_DEVICE_ID_SI_300        0x0300
 #define PCI_DEVICE_ID_SI_530           0x0530
-#define PCI_DEVICE_ID_SI_540           0x0540
+#define PCI_DEVICE_ID_SI_540        0x5300
 #define PCI_DEVICE_ID_SI_601           0x0601
 #define PCI_DEVICE_ID_SI_620           0x0620
-#define PCI_DEVICE_ID_SI_630           0x0630
+#define PCI_DEVICE_ID_SI_630        0x6300
 #define PCI_DEVICE_ID_SI_5107          0x5107
 #define PCI_DEVICE_ID_SI_5511          0x5511
 #define PCI_DEVICE_ID_SI_5513          0x5513
 #define PCI_DEVICE_ID_ARK_STING                0xa091
 #define PCI_DEVICE_ID_ARK_STINGARK     0xa099
 #define PCI_DEVICE_ID_ARK_2000MT       0xa0a1
-
-#define PCI_VENDOR_ID_SIS               0x1039
-#define PCI_DEVICE_ID_SIS_300           0x0300
-#define PCI_DEVICE_ID_SIS_540           0x5300
-#define PCI_DEVICE_ID_SIS_630           0x6300
index 88de7a2..42cf879 100644 (file)
@@ -233,6+233,25 @@ static struct dev_name_struct {
        { "dasdg", (DASD_MAJOR << MINORBITS) + (6 << 2) },
        { "dasdh", (DASD_MAJOR << MINORBITS) + (7 << 2) },
 #endif
+#if defined(CONFIG_BLK_CPQ_DA) || defined(CONFIG_BLK_CPQ_DA_MODULE)
+       { "ida/c0d0p",0x4800 },
+       { "ida/c0d1p",0x4810 },
+       { "ida/c0d2p",0x4820 },
+       { "ida/c0d3p",0x4830 },
+       { "ida/c0d4p",0x4840 },
+       { "ida/c0d5p",0x4850 },
+       { "ida/c0d6p",0x4860 },
+       { "ida/c0d7p",0x4870 },
+       { "ida/c0d8p",0x4880 },
+       { "ida/c0d9p",0x4890 },
+       { "ida/c0d10p",0x48A0 },
+       { "ida/c0d11p",0x48B0 },
+       { "ida/c0d12p",0x48C0 },
+       { "ida/c0d13p",0x48D0 },
+       { "ida/c0d14p",0x48E0 },
+       { "ida/c0d15p",0x48F0 },
+#endif
+
        { NULL, 0 }
 };
 
index 7c5f6df..7aaf1a4 100644 (file)
@@ -8,6+8,8 @@
 #include <linux/mm.h>
 #include <asm/uaccess.h>
 
+kernel_cap_t cap_bset = CAP_INIT_EFF_SET;
+
 /* Note: never hold tasklist_lock while spinning for this one */
 spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED;
 
@@ -17,8+19,6 @@ spinlock_t task_capability_lock = SPIN_LOCK_UNLOCKED;
  * uninteresting and/or not to be changed.
  */
 
-kernel_cap_t cap_bset = CAP_FULL_SET;
-
 asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
 {
      int error, pid;
index bbfaf29..5e8d825 100644 (file)
@@ -95,9+95,8 @@ int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
        /* Drop the "current user" thing */
        free_uid(current);
 
-       /* Give kmod all privileges.. */
+       /* Give kmod all effective privileges.. */
        current->uid = current->euid = current->fsuid = 0;
-       cap_set_full(current->cap_inheritable);
        cap_set_full(current->cap_effective);
 
        /* Allow execve args to be in kernel space. */
index 4dd6839..5fc0418 100644 (file)
@@ -803,8+803,11 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp,
 int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
                        void *buffer, size_t *lenp)
 {
+       if (!capable(CAP_SYS_MODULE)) {
+               return -EPERM;
+       }
        return do_proc_dointvec(table,write,filp,buffer,lenp,1,
-               (current->pid == 1) ? OP_SET : OP_AND);
+                               (current->pid == 1) ? OP_SET : OP_AND);
 }
 
 int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
close