]> git.neil.brown.name Git - history.git/commitdiff
2.0.37pre5 2.0.37pre5
authorAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:12:11 +0000 (15:12 -0500)
committerAlan Cox <alan@lxorguk.ukuu.org.uk>
Fri, 23 Nov 2007 20:12:11 +0000 (15:12 -0500)
o Configuration tool fixes (Alan Cox)
o MegaRAID update (AMI)
o ioctl thread fix (Alan Cox)
o RCPCI update (Red Creek)
o IDE OOps fix (from 2.2)
o Symbios 53c416 driver (Lieven Willems)
o PARIDE enhancements (Grant)
o SMART2 update (Compaq)
o Cyclades PCI update (Cyclades)
o ISO 8859-15  (From 2.2)
o DAC960 update (Leonard Zubkoff)

48 files changed:
Documentation/Configure.help
arch/i386/config.in
drivers/block/Config.in
drivers/block/DAC960.c
drivers/block/README.smart2
drivers/block/cpqarray.c
drivers/block/cpqarray.h
drivers/block/ide.c
drivers/block/paride/friq.c
drivers/block/paride/on26.c
drivers/char/cyclades.c
drivers/char/random.c
drivers/net/Makefile
drivers/net/README.rcpci [new file with mode: 0644]
drivers/net/de4x5.c
drivers/net/de4x5.h
drivers/net/dummy.c
drivers/net/rcif.h
drivers/net/rclanmtl.c [new file with mode: 0644]
drivers/net/rclanmtl.h [new file with mode: 0644]
drivers/net/rcmtl.c [deleted file]
drivers/net/rcmtl.h [deleted file]
drivers/net/rcpci45.c
drivers/pci/pci.c
drivers/scsi/Config.in
drivers/scsi/Makefile
drivers/scsi/hosts.c
drivers/scsi/megaraid.c
drivers/scsi/megaraid.h
drivers/scsi/sym53c416.c [new file with mode: 0644]
drivers/scsi/sym53c416.h [new file with mode: 0644]
drivers/sound/.defines [new file with mode: 0644]
drivers/sound/Config.in
drivers/sound/local.h [new file with mode: 0644]
fs/Config.in
fs/Makefile
fs/ioctl.c
fs/nls.c
fs/nls_iso8859-15.c [new file with mode: 0644]
include/asm-alpha/ioctls.h
include/linux/cyclades.h
include/linux/pci.h
include/linux/proc_fs.h
init/main.c
scripts/Menuconfig
scripts/tkgen.c
scripts/tkparse.c
scripts/tkparse.h

index 75db1ff151b16bb8e36fb06949c01da07f2ec596..f349b4b13627df1cb0c408c39ba7a181441a9b14 100644 (file)
@@ -2116,6 +2116,22 @@ CONFIG_SCSI_DC390T_NOGENSUPP
   some reason, you want to drive with the other AM53C974 driver.
   If unsure, say N.
 
+Symbios Logic sym53c416 support
+CONFIG_SCSI_SYM53C416
+  This is support for the sym53c416 SCSI host adapter. This is the 
+  SCSI adapter that comes with some hp scanners. This driver requires that
+  the sym53c416 is configured first using some sort of pnp configuration
+  program (e.g. isapnp). After doing so it should be loaded as a module
+  using insmod. The parameters of the configured card(s) should be passed
+  to the driver. The format is:
+  
+    insmod sym53c416 sym53c416=<base>,<irq> [sym53c416_1=<base>,<irq>]
+
+  There is support for up to four adapters. If you want to compile this
+  driver as a module ( = code which can be inserted in and removed from
+  the running kernel whenever you want), say M here and read
+  Documentation/modules.txt.                                      
+
 AM53/79C974 PCI SCSI support
 CONFIG_SCSI_AM53C974
   This is support for the AM53/79C974 SCSI host adapters. Please read
index 52ea7df77e297f9c1822d03364865515d3ccd074..b6cb215f2a6e2435ddf514c30dc87fb7b7936a3d 100644 (file)
@@ -27,7 +27,7 @@ choice 'Nemory configuration' \
         Enterprise     CONFIG_MEM_ENT  \
         Custom         CONFIG_MEM_SPECIAL" Standard
 
-if [ "CONFIG_MEM_SPECIAL" = "y" ]; then
+if [ "$CONFIG_MEM_SPECIAL" = "y" ]; then
        int ' Max physical memory in MB' CONFIG_MAX_MEMSIZE 1024
 fi
 if [ "$CONFIG_MEM_ENT" = "y" ]; then
index 5c70f0ad4d478056b245c21c7aaac79b2bcc3604..502cbb4efd10d15c17ff0879a109c5f3778d4b0a 100644 (file)
@@ -60,7 +60,11 @@ if [ "$CONFIG_PCI" = "y" ]; then
   bool 'Mylex DAC960 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960
 fi
 
-tristate 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA
+bool 'Compaq SMART2 support' CONFIG_BLK_CPQ_DA
+if [ "$CONFIG_BLK_CPQ_DA" = "y" -o "$CONFIG_BLK_CPQ_DA" = "m" ]; then
+  bool '   Support for PCI SMART-2 Controllers' CONFIG_BLK_CPQ_DA_PCI
+  bool '   Support for EISA SMART-2 Controllers' CONFIG_BLK_CPQ_DA_EISA
+fi
 
 tristate 'Parallel port IDE device support' CONFIG_PARIDE 
 if [ "$CONFIG_PARIDE" = "y" -o "$CONFIG_PARIDE" = "m" ]; then
index 1dcf660e468067495f4e754f92aba8ba5444827d..28b0014596fc354321274ea379ca62b3b8e0fd19 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/bios32.h>
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/segment.h>
 #include "DAC960.h"
 
 
index 78fd159fde6ae42337dde7f8d617a9f1cabed00f..053451754549792006dde3acc18f2f74c5047270 100644 (file)
@@ -31,6 +31,23 @@ Create device nodes for the diskarray device:
 Where ctlrs is the number of controllers you have (defaults to 1 if not
 specified).
 
+EISA Controllers:
+-----------------
+
+If you want to use an EISA controller you'll have to turn on EISA support
+and supply some insmod/lilo paramaters.  If the driver is compiled into the
+kernel, must give it port/irq data at boot time.  For example, if you had
+two SMART-2/E controllers, in EISA slots 1 and 2, on irqs 15 and 5 respectively
+you'd give it a boot argument like this:
+
+       smart2=0x1000,0xf,0x2000,0x5
+
+If you were loading the driver as a module, you'd give load it like this:
+
+       insmod cpqarray.o eisa=0x1000,0xf,0x2000,0x5
+
+You can use EISA and PCI adapters at the same time.
+
 Booting:
 --------
 
index 08313f5ecd85dbe290968c5a0ac8001132d52ece..c04a72bc6bee1d68d53e54e7477c88e6e294bfd1 100644 (file)
 #else
 #define MOD_INC_USE_COUNT
 #define MOD_DEC_USE_COUNT
-#endif
 extern struct inode_operations proc_diskarray_inode_operations;
+#endif
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 0.9.5)"
+#define DRIVER_NAME "Compaq SMART2 Driver (v 0.9.7)"
 
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
 #include <linux/blk.h>
@@ -64,6 +64,13 @@ extern struct inode_operations proc_diskarray_inode_operations;
 static int nr_ctlr = 0;
 static ctlr_info_t *hba[MAX_CTLR] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 
+#ifdef CONFIG_BLK_CPQ_DA_EISA
+#ifndef MODULE
+static
+#endif
+int eisa[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+#endif
+
 static struct hd_struct * ida;
 static int * ida_sizes;
 static int * ida_blocksizes;
@@ -88,22 +95,21 @@ static struct gendisk ida_gendisk[MAX_CTLR];
 #endif /* PROFILE_REQUESTS */
 
 
-#define PROFILE_MEMUSAGE
-#ifdef PROFILE_MEMUSAGE
-unsigned int nr_allocs = 0;
-unsigned int nr_frees = 0;
-#endif
-
 void cpqarray_init(void);
+#ifdef CONFIG_BLK_CPQ_DA_PCI
 static int cpqarray_pci_detect(void);
 static void cpqarray_pci_init(ctlr_info_t *c, unchar bus, unchar device_fn);
 static ulong remap_pci_mem(ulong base, ulong size);
+#endif
+#ifdef CONFIG_BLK_CPQ_DA_EISA
+static int cpqarray_eisa_detect(void);
+#endif
 static void flushcomplete(int ctlr);
 static int pollcomplete(int ctlr);
 static void getgeometry(int ctlr);
 
-static cmdlist_t * cmd_alloc(int intr);
-static void cmd_free(cmdlist_t *c);
+static cmdlist_t * cmd_alloc(ctlr_info_t *h, int intr);
+static void cmd_free(ctlr_info_t *h, cmdlist_t *c);
 
 static int sendcmd(
        __u8    cmd,
@@ -154,6 +160,32 @@ static int revalidate_allvol(kdev_t dev);
 static void ida_procinit(int i);
 static int ida_proc_get_info(char *buffer, char **start, off_t offset, int length, int dp);
 
+/*
+ * These macros control what happens when the driver tries to write to or
+ * read from a card.  If the driver is configured for EISA only or PCI only,
+ * the macros expand to inl/outl or readl/writel.  If the drive is configured
+ * for both EISA and PCI, the macro expands to a conditional which uses
+ * memory mapped IO if the card has it (PCI) or io ports if it doesn't (EISA).
+ */
+#ifdef CONFIG_BLK_CPQ_DA_PCI
+#      ifdef CONFIG_BLK_CPQ_DA_EISA
+#              warning "SMART2: EISA+PCI"
+#              define smart2_read(h, offset)  ( ((h)->vaddr) ? readl((h)->vaddr+(offset)) : inl((h)->ioaddr+(offset)) )
+#              define smart2_write(p, h, offset) ( ((h)->vaddr) ? writel((p), (h)->vaddr+(offset)) : outl((p), (h)->ioaddr+(offset)) )
+#      else
+#              warning "SMART2: PCI"
+#              define smart2_read(h, offset)  readl((h)->vaddr+(offset))
+#              define smart2_write(p, h, offset) writel((p), (h)->vaddr+(offset))
+#      endif
+#else
+#      ifdef CONFIG_BLK_CPQ_DA_EISA
+#              warning "SMART2: EISA"
+#              define smart2_read(h, offset)  inl((h)->vaddr+(offset))
+#              define smart2_write(p, h, offset) outl((p), (h)->vaddr+(offset))
+#      else
+#              error "You must enable either SMART2 PCI support or SMART2 EISA support or both!"
+#      endif
+#endif
 
 void ida_geninit(struct gendisk *g)
 {
@@ -324,11 +356,9 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
                        h->nr_requests);
        pos += size; len += size;
 #endif /* PROFILE_REQUESTS */
-#ifdef PROFILE_MEMUSAGE
        size = sprintf(buffer+len,"nr_allocs = %d\nnr_frees = %d\n",
-                       nr_allocs, nr_frees);
+                       h->nr_allocs, h->nr_frees);
        pos += size; len += size;
-#endif /* PROFILE_MEMUSAGE */
 
        *start = buffer+offset;
        len -= offset;
@@ -340,6 +370,7 @@ static int ida_proc_get_info(char *buffer, char **start, off_t offset, int lengt
 #ifdef MODULE
 /* This is a hack... */
 #include "proc_array.c"
+
 int init_module(void)
 {
        int i, j;
@@ -361,7 +392,7 @@ void cleanup_module(void)
        struct gendisk *g;
 
        for(i=0; i<nr_ctlr; i++) {
-               writel(0, hba[i]->vaddr + INTR_MASK);
+               smart2_write(0, hba[i], INTR_MASK);
                free_irq(hba[i]->intr, hba[i]);
                vfree((void*)hba[i]->vaddr);
                unregister_blkdev(MAJOR_NR+i, hba[i]->devname);
@@ -413,7 +444,14 @@ void cpqarray_init(void)
        int i;
 
        /* detect controllers */
-       if (cpqarray_pci_detect() == 0)
+#ifdef CONFIG_BLK_CPQ_DA_PCI
+       cpqarray_pci_detect();
+#endif
+#ifdef CONFIG_BLK_CPQ_DA_EISA
+       cpqarray_eisa_detect();
+#endif
+
+       if (nr_ctlr == 0)
                return;
 
        printk(DRIVER_NAME "\n");
@@ -446,7 +484,7 @@ void cpqarray_init(void)
         * Get an interrupt, set the Q depth and get into /proc
         */
        for(i=0; i< nr_ctlr; i++) {
-               writel(0, hba[i]->vaddr + INTR_MASK);  /* No interrupts */
+               smart2_write(0, hba[i], INTR_MASK);  /* No interrupts */
                if (request_irq(hba[i]->intr, do_ida_intr,
                        SA_INTERRUPT | SA_SHIRQ, hba[i]->devname, hba[i])) {
 
@@ -463,7 +501,7 @@ void cpqarray_init(void)
                printk("Finding drives on %s\n", hba[i]->devname);
                getgeometry(i);
 
-               writel(FIFO_NOT_EMPTY, hba[i]->vaddr + INTR_MASK);
+               smart2_write(FIFO_NOT_EMPTY, hba[i], INTR_MASK);
 
                hba[i]->maxQ = 32;
 #ifdef PROFILE_REQUESTS
@@ -502,6 +540,7 @@ void cpqarray_init(void)
        /* done ! */
 }
 
+#ifdef CONFIG_BLK_CPQ_DA_PCI
 /*
  * Find the controller and initialize it
  */
@@ -597,6 +636,49 @@ static ulong remap_pci_mem(ulong base, ulong size)
 
         return (ulong) (page_remapped ? (page_remapped + page_offs) : 0UL);
 }
+#endif /* CONFIG_BLK_CPQ_DA_PCI */
+
+#ifdef CONFIG_BLK_CPQ_DA_EISA
+/*
+ * Copy the contents of the ints[] array passed to us by init.
+ */
+void cpqarray_setup(char *str, int *ints)
+{
+       int i;
+       if (ints[0] & 1) {
+               printk( "SMART2 Parameter Usage:\n"
+                       "     smart2=io,irq,io,irq,...\n");
+               return;
+       }
+       for(i=0; i<ints[0]; i++) {
+               eisa[i] = ints[i+1];
+       }
+}
+
+/*
+ * Find an EISA controller's signature.  Set up an hba if we find it.
+ */
+static int cpqarray_eisa_detect(void)
+{
+       int i=0;
+
+       while(i<16 && eisa[i]) {
+               if (inl(eisa[i]+0xC80) == 0x3040110e) {
+                       hba[nr_ctlr] = kmalloc(sizeof(ctlr_info_t), GFP_KERNEL);
+                       memset(hba[nr_ctlr], 0, sizeof(ctlr_info_t));
+                       hba[nr_ctlr]->ioaddr = eisa[i];
+                       hba[nr_ctlr]->intr = eisa[i+1];
+                       sprintf(hba[nr_ctlr]->devname, "ida%d", nr_ctlr);
+                       hba[nr_ctlr]->ctlr = nr_ctlr;
+                       nr_ctlr++;
+               } else {
+                       printk("SMART2:  Could not find a controller at io=0x%04x irq=0x%x\n", eisa[i], eisa[i+1]);
+               }
+               i+=2;
+       }
+       return nr_ctlr;
+}
+#endif /* CONFIG_BLK_CPQ_DA_EISA */
 
 /*
  * Open.  Make sure the device is really there.
@@ -706,7 +788,7 @@ void do_ida_request(int ctlr)
        if (h->Qdepth >= h->maxQ)
                goto doreq_done;
 
-       if ((c = cmd_alloc(1)) == NULL)
+       if ((c = cmd_alloc(h, 1)) == NULL)
                goto doreq_done;
 
        blk_dev[MAJOR_NR+ctlr].current_request = creq->next;
@@ -774,7 +856,7 @@ static void start_io(ctlr_info_t *h)
 
        while((c = h->reqQ) != NULL) {
                /* Can't do anything if we're busy */
-               if (readl(h->vaddr + COMMAND_FIFO) == 0)
+               if (smart2_read(h, COMMAND_FIFO) == 0)
                        return;
 
                /* Get the first entry from the request Q */
@@ -782,7 +864,7 @@ static void start_io(ctlr_info_t *h)
                h->Qdepth--;
        
                /* Tell the controller to do our bidding */
-               writel(c->busaddr, h->vaddr + COMMAND_FIFO);
+               smart2_write(c->busaddr, h, COMMAND_FIFO);
 
                /* Get onto the completion Q */
                addQ(&h->cmpQ, c);
@@ -852,7 +934,7 @@ void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
        unsigned long istat;
        __u32 a,a1;
 
-       istat = readl(h->vaddr + INTR_PENDING);
+       istat = smart2_read(h, INTR_PENDING);
        /* Is this interrupt for us? */
        if (istat == 0)
                return;
@@ -862,7 +944,7 @@ void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
         * we had better do something about it.
         */
        if (istat & FIFO_NOT_EMPTY) {
-               while((a = readl(h->vaddr + COMMAND_COMPLETE_FIFO))) {
+               while((a = smart2_read(h, COMMAND_COMPLETE_FIFO))) {
                        a1 = a; a &= ~3;
                        if ((c = h->cmpQ) == NULL) goto bad_completion;
                        while(c->busaddr != a) {
@@ -884,7 +966,7 @@ void do_ida_intr(int irq, void *dev_id, struct pt_regs *regs)
                                ++h->nr_requests;
 #endif /* PROFILE_REQUESTS */
                                        complete_command(c, 0);
-                                       cmd_free(c);
+                                       cmd_free(h, c);
                                } else if (c->type == CMD_IOCTL_PEND) {
                                        c->type = CMD_IOCTL_DONE;
                                }
@@ -947,13 +1029,19 @@ int ida_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigne
                put_user(diskinfo[0], &geo->heads);
                put_user(diskinfo[1], &geo->sectors);
                put_user(diskinfo[2], &geo->cylinders);
-               put_user(ida[MINOR(inode->i_rdev)].start_sect, &geo->start);
+               put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].start_sect, &geo->start);
                return 0;
        case IDAGETDRVINFO:
                error = verify_area(VERIFY_WRITE, io, sizeof(*io));
                if (error) return error;
                memcpy_tofs(&io->c.drv,&hba[ctlr]->drv[dsk],sizeof(drv_info_t));
                return 0;
+       case BLKGETSIZE:
+               if (!arg) return -EINVAL;
+               error = verify_area(VERIFY_WRITE, (long*)arg, sizeof(long));
+               if (error) return error;
+               put_user(ida[(ctlr<<CTLR_SHIFT)+MINOR(inode->i_rdev)].nr_sects, (long*)arg);
+               return 0;
        case BLKRASET:
                if (!suser()) return -EACCES;
                if (!(inode->i_rdev)) return -EINVAL;
@@ -1012,7 +1100,7 @@ int ida_ctlr_ioctl(int ctlr, int dsk, ida_ioctl_t *io)
        int error;
 
        DBGINFO(printk("ida_ctlr_ioctl %d %x %p\n", ctlr, dsk, io));
-       if ((c = cmd_alloc(0)) == NULL)
+       if ((c = cmd_alloc(h, 0)) == NULL)
                return -ENOMEM;
        c->ctlr = ctlr;
        c->hdr.unit = (io->unit & UNITVALID) ? io->unit &0x7f : dsk;
@@ -1102,7 +1190,7 @@ 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(c);
+       cmd_free(h, c);
        return error;
 }
 
@@ -1110,24 +1198,25 @@ ioctl_err_exit:
  * Sooner or later we'll want to maintain our own cache of
  * commands.  For now, just use kmalloc to get them
  */
-cmdlist_t * cmd_alloc(int intr)
+cmdlist_t * cmd_alloc(ctlr_info_t *h, int intr)
 {
        cmdlist_t * c;
 
+       if (h->nr_allocs - h->nr_frees > 128)
+               return NULL;
+
        c = kmalloc(sizeof(cmdlist_t), (intr) ? GFP_ATOMIC : GFP_KERNEL);
+       if (c == NULL)
+               return NULL;
        memset(c, 0, sizeof(cmdlist_t));
        c->busaddr = virt_to_bus(c);
-#ifdef PROFILE_MEMUSAGE
-       nr_allocs++;
-#endif
+       h->nr_allocs++;
        return c;
 }
 
-void cmd_free(cmdlist_t *c)
+void cmd_free(ctlr_info_t *h, cmdlist_t *c)
 {
-#ifdef PROFILE_MEMUSAGE
-       nr_frees++;
-#endif
+       h->nr_frees++;
        kfree(c);
 }
 
@@ -1153,7 +1242,7 @@ int sendcmd(
        unsigned long i;
        ctlr_info_t *info_p = hba[ctlr];
 
-       c = cmd_alloc(0);
+       c = cmd_alloc(info_p, 0);
        c->ctlr = ctlr;
        c->hdr.unit = log_unit;
        c->hdr.prio = 0;
@@ -1181,11 +1270,11 @@ int sendcmd(
         * Disable interrupt
         */
        base_ptr = info_p->vaddr;
-       writel(0, base_ptr + INTR_MASK);
+       smart2_write(0, info_p, INTR_MASK);
        /* Make sure there is room in the command FIFO */
        /* Actually it should be completely empty at this time. */
        for (i = 200000; i > 0; i--) {
-               temp = readl(base_ptr + COMMAND_FIFO);
+               temp = smart2_read(info_p, COMMAND_FIFO);
                if (temp != 0) {
                        break;
                }
@@ -1198,7 +1287,7 @@ DBG(
        /*
         * Send the cmd
         */
-       writel(c->busaddr, base_ptr + COMMAND_FIFO);
+       smart2_write(c->busaddr, info_p, COMMAND_FIFO);
        complete = pollcomplete(ctlr);
        if (complete != 1) {
                if (complete != c->busaddr) {
@@ -1206,7 +1295,7 @@ DBG(
                        "ida%d: idaSendPciCmd "
                      "Invalid command list address returned! (%08lx)\n",
                                ctlr, (unsigned long)complete);
-                       cmd_free(c);
+                       cmd_free(info_p, c);
                        return (IO_ERROR);
                }
        } else {
@@ -1214,7 +1303,7 @@ DBG(
                        "ida%d: idaSendPciCmd Timeout out, "
                        "No command list address returned!\n",
                        ctlr);
-               cmd_free(c);
+               cmd_free(info_p, c);
                return (IO_ERROR);
        }
 
@@ -1226,11 +1315,11 @@ DBG(
                                "cmd: 0x%x, return code = 0x%x\n",
                                ctlr, c->req.hdr.cmd, c->req.hdr.rcode);
 
-                       cmd_free(c);
+                       cmd_free(info_p, c);
                        return (IO_ERROR);
                }
        }
-       cmd_free(c);
+       cmd_free(info_p, c);
        return (IO_OK);
 }
 
@@ -1286,9 +1375,9 @@ static int revalidate_allvol(kdev_t dev)
         * we check the new geometry.  Then turn interrupts back on when
         * we're done.
         */
-       writel(0, hba[ctlr]->vaddr + INTR_MASK);
+       smart2_write(0, hba[ctlr], INTR_MASK);
        getgeometry(ctlr);
-       writel(FIFO_NOT_EMPTY, hba[ctlr]->vaddr + INTR_MASK);
+       smart2_write(FIFO_NOT_EMPTY, hba[ctlr], INTR_MASK);
 
        ida_geninit(&ida_gendisk[ctlr]);
        for(i=0; i<NWD; i++)
@@ -1358,12 +1447,11 @@ int pollcomplete(int ctlr)
 {
        int done;
        int i;
-       unsigned long base_ptr = hba[ctlr]->vaddr;
 
        /* Wait (up to 2 seconds) for a command to complete */
 
        for (i = 200000; i > 0; i--) {
-               done = readl(base_ptr + COMMAND_COMPLETE_FIFO);
+               done = smart2_read(hba[ctlr], COMMAND_COMPLETE_FIFO);
                if (done == 0) {
                        udelay(10);     /* a short fixed delay */
                } else
@@ -1388,13 +1476,11 @@ int pollcomplete(int ctlr)
  */
 void flushcomplete(int ctlr)
 {
-
-       unsigned long base_ptr = hba[ctlr]->vaddr;
        unsigned long ret_addr;
        unsigned int i;
 
        for (i = 200000; i > 0; i--) {
-               ret_addr = readl(base_ptr + COMMAND_COMPLETE_FIFO);
+               ret_addr = smart2_read(hba[ctlr], COMMAND_COMPLETE_FIFO);
                if (ret_addr == 0) {
                        break;
                }
index 144eca4edfc5d72d5502f11759c4f900961cc93d..f913569f11bac83d8cd329862aa47fafefd5645b 100644 (file)
@@ -88,6 +88,8 @@ typedef struct {
        unsigned int avg_latency;
        unsigned int max_latency;
        unsigned int nr_requests;
+       unsigned int nr_allocs;
+       unsigned int nr_frees;
        struct timer_list timer;
        unsigned int misc_tflags;
 } ctlr_info_t;
index d6ff11d35d5403b38095add0f84626d7a797ed5c..27bec67185f9130369596d5370ef6c0b6a3a51b4 100644 (file)
@@ -618,7 +618,7 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
         * This is a split test for drives 8 Gig and Bigger only.
         */
        if ((id->lba_capacity >= 16514064) && (id->cyls == 0x3fff) &&
-           (id->heads == 16) && (id->sectors = 63)) {
+           (id->heads == 16) && (id->sectors == 63)) {
                id->cyls = lba_sects / (16 * 63); /* correct cyls */
                return 1;       /* lba_capacity is our only option */
        }
@@ -627,7 +627,7 @@ static int lba_capacity_is_ok (struct hd_driveid *id)
         * This is a split test for drives less than 8 Gig only.
         */
        if ((id->lba_capacity < 16514064) && (lba_sects > chs_sects) &&
-           (id->heads == 16) && (id->sectors = 63)) {
+           (id->heads == 16) && (id->sectors == 63)) {
                id->cyls = lba_sects / (16 * 63); /* correct cyls */
                return 1;       /* lba_capacity is our only option */
        }       
@@ -3402,7 +3402,11 @@ int ide_xlate_1024 (kdev_t i_rdev, int xparm, const char *msg)
        const byte *heads = head_vals;
        unsigned long tracks;
 
-       if ((drive = get_info_ptr(i_rdev)) == NULL || drive->forced_geom) {
+       drive = get_info_ptr(i_rdev);
+       if (!drive)
+               return 0;
+
+       if (drive->forced_geom) {
                /*
                 * Update the current 3D drive values.
                 */
index 9b7e98501a541c5706df3573fb2d54703f70ae26..37ebaa04797616dc06022814c995cb3210cbd4f2 100644 (file)
@@ -3,11 +3,29 @@
                            Under the terms of the GNU public license
 
        friq.c is a low-level protocol driver for the Freecom "IQ"
-       parallel port IDE adapter. 
+       parallel port IDE adapter.   Early versions of this adapter
+       use the 'frpw' protocol.
        
+       Freecom uses this adapter in a battery powered external 
+       CD-ROM drive.  It is also used in LS-120 drives by
+       Maxell and Panasonic, and other devices.
+
+       The battery powered drive requires software support to
+       control the power to the drive.  This module enables the
+       drive power when the high level driver (pcd) is loaded
+       and disables it when the module is unloaded.  Note, if
+       the friq module is built in to the kernel, the power
+       will never be switched off, so other means should be
+       used to conserve battery power.
+
+*/
+
+/* Changes:
+
+       1.01    GRG 1998.12.20   Added support for soft power switch
 */
 
-#define        FRIQ_VERSION    "1.00
+#define        FRIQ_VERSION    "1.01
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -165,6 +183,11 @@ static int friq_test_proto( PIA *pi, char * scratch, int verbose )
 {       int     j, k, r;
        int     e[2] = {0,0};
 
+       pi->saved_r0 = r0();    
+       w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
+       udelay(500);
+       w0(pi->saved_r0);
+
        friq_connect(pi);
        for (j=0;j<2;j++) {
                 friq_write_regr(pi,0,6,0xa0+j*0x10);
@@ -201,16 +224,29 @@ static void friq_log_adapter( PIA *pi, char * scratch, int verbose )
         printk("mode %d (%s), delay %d\n",pi->mode,
                mode_string[pi->mode],pi->delay);
 
+       pi->private = 1;
+       friq_connect(pi);
+       CMD(0x9e);              /* disable sleep timer */
+       friq_disconnect(pi);
+
 }
 
 static void friq_init_proto( PIA *pi)
 
 {       MOD_INC_USE_COUNT;
+       pi->private = 0;
 }
 
 static void friq_release_proto( PIA *pi)
 
-{       MOD_DEC_USE_COUNT;
+{       if (pi->private) {             /* turn off the power */
+               friq_connect(pi);
+               CMD(0x1d); CMD(0x1e);
+               friq_disconnect(pi);
+               pi->private = 0;
+       }
+
+       MOD_DEC_USE_COUNT;
 }
 
 struct pi_protocol friq = {"friq",0,5,2,1,1,
index 231e01c0a477d6169312166f022b6b2fd3ea2b22..d1e85cd28edb0f4cd8c08f4fd885ae942172927b 100644 (file)
         1.01    GRG 1998.05.06 init_proto, release_proto
        1.02    GRG 1998.09.23 updates for the -E rev chip
        1.03    GRG 1998.12.14 fix for slave drives
+       1.04    GRG 1998.12.20 yet another bug fix
 
 */
 
-#define ON26_VERSION      "1.03"
+#define ON26_VERSION      "1.04"
 
 #include <linux/module.h>
 #include <linux/delay.h>
@@ -159,7 +160,7 @@ static int on26_test_port( PIA *pi)  /* hard reset */
                 x = on26_read_regr(pi,0,7);
                 on26_write_regr(pi,0,6,0xb0);
                 y = on26_read_regr(pi,0,7);
-                if ((x&0x80)||(y&0x80)) break;
+                if (!((x&0x80)||(y&0x80))) break;
                 udelay(100000);
             }
 
index 8b7695ff54b9e34f1a8b6deae956005d726c60de..5d30a41ff23eac8382da2ba69d247244d0b68b6a 100644 (file)
@@ -1,7 +1,7 @@
 #define BLOCKMOVE
 #define        Z_WAKE
 static char rcsid[] =
-"$Revision: 2.1.1.10 $$Date: 1998/11/12 16:08:23 $";
+"$Revision: 2.1.1.11 $$Date: 1998/12/30 18:58:47 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -31,7 +31,11 @@ static char rcsid[] =
  *   void cleanup_module(void);
  *
  * $Log: cyclades.c,v $
- * Revision: 2.1.1.10  1998/11/12 16:08:23 ivan
+ * Revision 2.1.1.11  1998/12/30 18:58:47 ivan
+ * Changed access to PLX PCI bridge registers from I/O to MMIO, in
+ * order to make PLX9050-based boards work with certain motherboards.
+ *
+ * Revision 2.1.1.10  1998/11/12 16:08:23 ivan
  * cy_close function now resets (correctly) the tty->closing flag;
  * JIFFIES_DIFF macro fixed.
  *
@@ -4707,7 +4711,6 @@ cy_detect_pci(void))
 {
 #ifdef CONFIG_PCI
   unsigned char         cyy_bus, cyy_dev_fn, cyy_rev_id;
-  unsigned long         pci_intr_ctrl;
   unsigned char         cy_pci_irq;
   uclong                cy_pci_addr0, cy_pci_addr1, cy_pci_addr2;
   unsigned short        i,j,cy_pci_nchan, plx_ver;
@@ -4761,7 +4764,7 @@ cy_detect_pci(void))
             printk("Cyclom-Y/PCI:found  winaddr=0x%lx ioaddr=0x%lx\n",
                (ulong)cy_pci_addr2, (ulong)cy_pci_addr1);
 #endif
-                cy_pci_addr1  &= PCI_BASE_ADDRESS_IO_MASK;
+                cy_pci_addr0  &= PCI_BASE_ADDRESS_MEM_MASK;
                 cy_pci_addr2  &= PCI_BASE_ADDRESS_MEM_MASK;
 
 #if defined(__alpha__)
@@ -4778,6 +4781,7 @@ cy_detect_pci(void))
                    continue;
                 }
 #else
+               cy_pci_addr0  = (ulong) ioremap(cy_pci_addr0, CyPCI_Yctl);
                 if ((ulong)cy_pci_addr2 >= 0x100000)  /* above 1M? */
                     cy_pci_addr2 = (ulong) ioremap(cy_pci_addr2, CyPCI_Ywin);
 #endif
@@ -4827,7 +4831,7 @@ cy_detect_pci(void))
 
                 /* set cy_card */
                 cy_card[j].base_addr = (ulong)cy_pci_addr2;
-                cy_card[j].ctl_addr = 0;
+               cy_card[j].ctl_addr = (ulong)cy_pci_addr0;
                 cy_card[j].irq = (int) cy_pci_irq;
                 cy_card[j].bus_index = 1;
                 cy_card[j].first_line = cy_next_channel;
@@ -4839,20 +4843,16 @@ cy_detect_pci(void))
                 switch (plx_ver) {
                    case PLX_9050:
 
-                   outw(inw(cy_pci_addr1+0x4c)|0x0040,cy_pci_addr1+0x4c);
-                   pci_intr_ctrl = (unsigned long)
-                               (inw(cy_pci_addr1+0x4c)
-                               | inw(cy_pci_addr1+0x4e)<<16);
+                   cy_writew(cy_pci_addr0+0x4c,
+                       cy_readw(cy_pci_addr0+0x4c)|0x0040);
                    break;
 
                    case PLX_9060:
                    case PLX_9080:
                    default: /* Old boards, use PLX_9060 */
 
-                   outw(inw(cy_pci_addr1+0x68)|0x0900,cy_pci_addr1+0x68);
-                   pci_intr_ctrl = (unsigned long)
-                               (inw(cy_pci_addr1+0x68)
-                               | inw(cy_pci_addr1+0x6a)<<16);
+                   cy_writew(cy_pci_addr0+0x68,
+                       cy_readw(cy_pci_addr0+0x68)|0x0900);
                    break;
                 }
 
index 3e8d21d55036427e25b15e7d311052e7766addd5..28de370b901db8ed09607e6c913c12b4d16ff630 100644 (file)
@@ -1004,7 +1004,17 @@ static int extract_entropy(struct random_bucket *r, char * buf,
                buf += i;
                add_timer_randomness(r, &extract_timer_state, nbytes);
                if (to_user && need_resched)
+               {
+                       if(current->signal & ~current->blocked)
+                       {
+                               if(nbytes==0)
+                                       ret = -ERESTARTSYS;
+                               else
+                                       ret -= nbytes;
+                               break;
+                       }
                        schedule();
+               }
        }
 
        /* Wipe data from memory */
index a084af63f6edb13604b0179fb0177059bcb4e50c..e7e06d9b37d318f1732c6608419f9b9d147d4498 100644 (file)
@@ -682,8 +682,8 @@ include $(TOPDIR)/Rules.make
 clean:
        rm -f core *.o *.a *.s
 
-rcpci.o: rcpci45.o rcmtl.o
-       $(LD) -r -o rcpci.o rcpci45.o rcmtl.o
+rcpci.o: rcpci45.o rclanmtl.o
+       $(LD) -r -o rcpci.o rcpci45.o rclanmtl.o
 
 wd.o:  wd.c CONFIG
        $(CC) $(CPPFLAGS) $(CFLAGS) $(WD_OPTS) -c $<
diff --git a/drivers/net/README.rcpci b/drivers/net/README.rcpci
new file mode 100644 (file)
index 0000000..e3710f0
--- /dev/null
@@ -0,0 +1,79 @@
+
+Application Information
+
+
+The included application, called "rcc" (for RedCreek Control), is an 
+example of a user-space application (i.e., not running within kernel
+space).  It issues ioctl commands to communicate with the PCI driver.  
+It can currently report any of the following information:
+
+   - PCI driver information ("getinfo")
+   - card statistics ("getstats")
+   - card's ip address & netmask ("getipnmask")
+   - card's mac address ("getmac")
+   - current speed ("getspeed")
+   - firmware version string ("getfirmware")
+   - status of the link (up or down) ("getstatus")
+
+Also, it can "set" the following parameters:
+
+   - IP and mask
+   - mac address
+   - link speed
+   - promiscuous mode
+
+Example:  rcc eth1 setipnmask="192.168.254.254 255.255.255.0"
+
+Note: rcc's command line parser is very basic. If you type the
+command incorrectly, it might result in a core dump.
+
+This program needs to run as root, to avoid encountering permission 
+problems.  An alternative is to change the permission and ownership
+so that it runs as a setuid root process (for example, "chown 
+root.root rcc; chmod u+s rcc").
+
+
+
+Quick PCI driver background
+
+
+The adapter has its own IP and mac addresses which you have to
+assign using the RedCreek manager (assuming the adapter is
+running 3.X firmware).  Your linux box will not know anything 
+about the adapter's IP address -- ie, the adapter will show up 
+as a regular nic.  You will assign the linux box IP address using 
+the "ifconfig" command, as mentioned below.
+
+
+To compile the driver, simply type "make".
+This, of course, assumes that you have GNU compiler environment
+already setup on a linux box.  The .c and .h files were copied 
+to a dos filesystem (the floppy), so you may have to use "dos2unix" to 
+convert it back to a unix text file.  Keep in mind that the driver
+currently works with kernels 2.0.X only.  Furthermore, it was only
+tested with kernel 2.0.34.
+
+To load the driver:
+
+"insmod rcpci"
+
+The adapter will show up as a regular nic.  Thus, if you have only
+one nic (the pci card) in your box, you would at this point configure
+it with the following commands:
+
+mandatory:
+"ifconfig eth0 <your linux box IP address (NOT the IP address of the 
+                adapter!>"
+"route add -net <your network address> eth0"
+
+optional (if you want to be able to access other networks):
+"route add default gw <your default gateway IP address> eth0"
+
+Done.  Type "ifconfig" to see "eth0" and the packet count, as well
+as the IP address, net mask, etc.
+
+To unload the driver, you first have to shutdown the interface:
+
+"ifconfig eth0 down"
+
+Then you unload the driver with "rmmod rcpci".
index b6364cd6c30bda76a27eb8f273f531a215354251..510aeea13e0a5cc49a119c91cb467843775c3f6f 100644 (file)
                           alignment for Alpha's and avoid their unaligned
                           access traps. This flag is merely for log messages:
                           should do something more definitive though...
+      0.5352 30-Dec-98    Fix driver recognition of the newer DECchips.
 
     =========================================================================
 */
 
-static const char *version = "de4x5.c:V0.5351 1998/10/4 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.5352 1998/12/30 davies@maniac.ultranet.com\n";
 
 #include <linux/module.h>
 
@@ -769,7 +770,7 @@ struct de4x5_private {
     int tx_new, tx_old;                     /* TX descriptor ring pointers  */
     char setup_frame[SETUP_FRAME_LEN];      /* Holds MCA and PA info.       */
     char frame[64];                         /* Min sized packet for loopback*/
-    struct net_device_stats stats;           /* Public stats                 */
+    struct net_device_stats stats;          /* Public stats                 */
     struct {
        u_int bins[DE4X5_PKT_STAT_SZ];      /* Private stats counters       */
        u_int unicast;
@@ -1356,7 +1357,6 @@ de4x5_open(struct device *dev)
     ** Re-initialize the DE4X5... 
     */
     status = de4x5_init(dev);
-    
     lp->state = OPEN;
     de4x5_dbg_open(dev);
     
@@ -1599,7 +1599,7 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     DISABLE_IRQs;                        /* Ensure non re-entrancy */
 
     if (test_and_set_bit(MASK_INTERRUPTS, (void*) &lp->interrupt))
-       printk("%s: Re-entering the interrupt handler.\n", dev->name);
+        printk("%s: Re-entering the interrupt handler.\n", dev->name);
 
 #if    LINUX_VERSION_CODE >= ((2 << 16) | (1 << 8))
     synchronize_irq();
@@ -2075,7 +2075,9 @@ eisa_probe(struct device *dev, u_long ioaddr))
            irq = inb(EISA_REG0);
            irq = de4x5_irq[(irq >> 1) & 0x03];
 
-           if (is_DC2114x) device |= (cfrv & CFRV_RN);
+           if (is_DC2114x) {
+               device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+           }
            lp->chipset = device;
 
            /* Write the PCI Configuration Registers */
@@ -2180,7 +2182,9 @@ pci_probe(struct device *dev, u_long ioaddr))
            lp->bus_num = pb;
            
            /* Set the chipset information */
-           if (is_DC2114x) device |= (cfrv & CFRV_RN);
+           if (is_DC2114x) {
+               device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+           }
            lp->chipset = device;
 
            /* Get the board I/O address (64 bits on sparc64) */
@@ -2291,7 +2295,9 @@ srom_search(int index))
        lp->bus_num = pb;
            
        /* Set the chipset information */
-       if (is_DC2114x) device |= (cfrv & CFRV_RN);
+       if (is_DC2114x) {
+           device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+       }
        lp->chipset = device;
 
        /* Get the board I/O address (64 bits on sparc64) */
@@ -5657,7 +5663,7 @@ de4x5_ioctl(struct device *dev, struct ifreq *rq, int cmd)
        cli();
        copy_to_user(ioc->data, &lp->pktStats, ioc->len); 
        sti();
-       
+
        break;
     case DE4X5_CLR_STATS:            /* Zero out the driver statistics */
        if (suser()) {
@@ -5830,6 +5836,12 @@ init_module(void)
        if (!mdev) mdev = p;
 
        if (register_netdev(p) != 0) {
+           struct de4x5_private *lp = (struct de4x5_private *)p->priv;
+           if (lp) {
+               release_region(p->base_addr, (lp->bus == PCI ? 
+                                             DE4X5_PCI_TOTAL_SIZE :
+                                             DE4X5_EISA_TOTAL_SIZE));
+           }
            kfree(p);
        } else {
            status = 0;                 /* At least one adapter will work */
index c0c58ccf4beb3dc15aa9b90f1031b62934e5f801..0a83efa91418298926d7280e826e3139fe124974 100644 (file)
 #define DC2114x     DC2114x_DID
 #define DC21142     (DC2114x_DID | 0x0010)
 #define DC21143     (DC2114x_DID | 0x0030)
+#define DC2114x_BRK 0x0020           /* CFRV break between DC21142 & DC21143 */
 
 #define is_DC21040 ((vendor == DC21040_VID) && (device == DC21040_DID))
 #define is_DC21041 ((vendor == DC21041_VID) && (device == DC21041_DID))
index 6f360b9680325d04b1c2535663e5f5dceba93e49..a8426bf4d64de49507e56f8b7f562f6968cdf45a 100644 (file)
@@ -70,6 +70,10 @@ static int dummy_close(struct device *dev)
        return 0;
 }
 
+static int dummy_rebuild(void *eth, struct device *dev, unsigned long raddr, struct sk_buff *skb)
+{
+       return 0;
+}
 
 int dummy_init(struct device *dev)
 {
@@ -94,6 +98,7 @@ int dummy_init(struct device *dev)
        /* Fill in the fields of the device structure with ethernet-generic values. */
        ether_setup(dev);
        dev->flags |= IFF_NOARP;
+       dev->rebuild_header = dummy_rebuild;
 
        return 0;
 }
index 4996b01daba535b9576512c220bb36723d394efc..a41f05aac20d5ca84c8a830d2585cec9ac899432 100644 (file)
@@ -8,7 +8,7 @@
 **  RedCreek InterFace include file.
 **
 **  ---------------------------------------------------------------------
-**  ---     Copyright (c) 1998, RedCreek Communications Inc.          ---
+**  ---     Copyright (c) 1998-1999, RedCreek Communications Inc.     ---
 **  ---                   All rights reserved.                        ---
 **  ---------------------------------------------------------------------
 **
@@ -38,7 +38,7 @@
 
 /* The following protocol revision # should be incremented every time
    a new protocol or new structures are used in this file. */
-int USER_PROTOCOL_REV = 1;     /* used to track different protocol revisions */
+int USER_PROTOCOL_REV = 2;     /* used to track different protocol revisions */
 
 /* define a single TCB & buffer */
 typedef struct                  /* a single buffer */
@@ -124,6 +124,31 @@ struct RC_user_tag
             U32 LinkSpeedCode;
         } RCgetspeed;                   /* <---- RCgetspeed */
   
+        /* SETSPEED structure */
+        struct RCsetspeed_tag {
+            U16 LinkSpeedCode;
+        } RCsetspeed;                   /* <---- RCsetspeed */
+
+        /* GETPROM structure */
+        struct  RCgetprom_tag {
+            U32 PromMode;
+        } RCgetprom;                   /* <---- RCgetprom */
+  
+        /* SETPROM structure */
+        struct RCsetprom_tag {
+            U16 PromMode;
+        } RCsetprom;                   /* <---- RCsetprom */
+
+        /* GETBROADCAST structure */
+        struct  RCgetbroadcast_tag {
+            U32 BroadcastMode;
+        } RCgetbroadcast;                   /* <---- RCgetbroadcast */
+  
+        /* SETBROADCAST structure */
+        struct RCsetbroadcast_tag {
+            U16 BroadcastMode;
+        } RCsetbroadcast;                   /* <---- RCsetbroadcast */
+
         /* GETFIRMWAREVER structure */
         #define FirmStringLen 80
         struct RCgetfwver_tag {
@@ -136,12 +161,23 @@ struct RC_user_tag
             U32 NetMask;
         } RCgetipandmask;               /* <---- RCgetipandmask */
 
+        /* SETIPANDMASK structure */
+        struct RCsetipnmask_tag {
+            U32 IpAddr;
+            U32 NetMask;
+        } RCsetipandmask;               /* <---- RCsetipandmask */
+
         /* GETMAC structure */
         #define MAC_SIZE 10
         struct RCgetmac_tag {
             U8 mac[MAC_SIZE];
         } RCgetmac;                     /* <---- RCgetmac */
 
+        /* SETMAC structure */
+        struct RCsetmac_tag {
+            U8 mac[MAC_SIZE];
+        } RCsetmac;                     /* <---- RCsetmac */
+
         /* GETLINKSTATUS structure */
         struct RCgetlnkstatus_tag {
             U32 ReturnStatus;
@@ -166,35 +202,56 @@ struct RC_user_tag
 union RC_user_data_tag {        /* structure tags used are taken from RC_user_tag structure above */
     struct RCgetinfo_tag      *getinfo;
     struct RCgetspeed_tag     *getspeed;
+    struct RCgetprom_tag *getprom;
+    struct RCgetbroadcast_tag   *getbroadcast;
     struct RCgetfwver_tag     *getfwver;
     struct RCgetipnmask_tag   *getipandmask;
     struct RCgetmac_tag       *getmac;
     struct RCgetlnkstatus_tag *getlinkstatus;
     struct RCgetlinkstats_tag *getlinkstatistics;
     struct RCdefault_tag      *rcdefault;
+    struct RCsetspeed_tag     *setspeed;
+    struct RCsetprom_tag     *setprom;
+    struct RCsetbroadcast_tag     *setbroadcast;
+    struct RCsetipnmask_tag   *setipandmask;
+    struct RCsetmac_tag       *setmac;
 } _RC_user_data;  /* declare as a global, so the defines below will work */
 
 /* 3) Structure short-cut entry */
 /* define structure short-cuts */   /* structure names are taken from RC_user_tag structure above */
 #define RCUS_GETINFO           data.RCgetinfo;
 #define RCUS_GETSPEED          data.RCgetspeed;
+#define RCUS_GETPROM           data.RCgetprom;
+#define RCUS_GETBROADCAST      data.RCgetbroadcast;
 #define RCUS_GETFWVER          data.RCgetfwver;
 #define RCUS_GETIPANDMASK      data.RCgetipandmask;
 #define RCUS_GETMAC            data.RCgetmac;
 #define RCUS_GETLINKSTATUS     data.RCgetlnkstatus;
 #define RCUS_GETLINKSTATISTICS data.RCgetlinkstats;
 #define RCUS_DEFAULT           data.RCdefault;
+#define RCUS_SETSPEED          data.RCsetspeed;
+#define RCUS_SETPROM           data.RCsetprom;
+#define RCUS_SETBROADCAST      data.RCsetbroadcast;
+#define RCUS_SETIPANDMASK      data.RCsetipandmask;
+#define RCUS_SETMAC            data.RCsetmac;
 
 /* 4) Data short-cut entry */
 /* define data short-cuts */    /* pointer names are from RC_user_data_tag union (just below RC_user_tag) */
 #define RCUD_GETINFO           _RC_user_data.getinfo
 #define RCUD_GETSPEED          _RC_user_data.getspeed
+#define RCUD_GETPROM           _RC_user_data.getprom
+#define RCUD_GETBROADCAST      _RC_user_data.getbroadcast
 #define RCUD_GETFWVER          _RC_user_data.getfwver
 #define RCUD_GETIPANDMASK      _RC_user_data.getipandmask
 #define RCUD_GETMAC            _RC_user_data.getmac
 #define RCUD_GETLINKSTATUS     _RC_user_data.getlinkstatus
 #define RCUD_GETLINKSTATISTICS _RC_user_data.getlinkstatistics
 #define RCUD_DEFAULT           _RC_user_data.rcdefault
+#define RCUD_SETSPEED          _RC_user_data.setspeed
+#define RCUD_SETPROM           _RC_user_data.setprom
+#define RCUD_SETBROADCAST      _RC_user_data.setbroadcast
+#define RCUD_SETIPANDMASK      _RC_user_data.setipandmask
+#define RCUD_SETMAC            _RC_user_data.setmac
 
 /* 5) Command identifier entry */
 /* define command identifiers */
@@ -205,7 +262,14 @@ union RC_user_data_tag {        /* structure tags used are taken from RC_user_ta
 #define RCUC_GETMAC             0x05
 #define RCUC_GETLINKSTATUS      0x06
 #define RCUC_GETLINKSTATISTICS  0x07
+#define RCUC_GETPROM            0x14
+#define RCUC_GETBROADCAST       0x15
 #define RCUC_DEFAULT            0xff
+#define RCUC_SETSPEED           0x08
+#define RCUC_SETIPANDMASK       0x09
+#define RCUC_SETMAC             0x0a
+#define RCUC_SETPROM            0x16
+#define RCUC_SETBROADCAST       0x17
 
 /* define ioctl commands to use, when talking to RC 45/PCI driver */
 #define RCU_PROTOCOL_REV         SIOCDEVPRIVATE
diff --git a/drivers/net/rclanmtl.c b/drivers/net/rclanmtl.c
new file mode 100644 (file)
index 0000000..971fb49
--- /dev/null
@@ -0,0 +1,2307 @@
+/*
+** *************************************************************************
+**
+**
+**     R C L A N M T L . C             $Revision: 5 $
+**
+**
+**  RedCreek I2O LAN Message Transport Layer program module.
+**
+**  ---------------------------------------------------------------------
+**  ---     Copyright (c) 1997-1999, RedCreek Communications Inc.     ---
+**  ---                   All rights reserved.                        ---
+**  ---------------------------------------------------------------------
+**
+**  File Description:
+**
+**  Host side I2O (Intelligent I/O) LAN message transport layer.
+**
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+** *************************************************************************
+*/
+
+#undef DEBUG
+
+#define RC_LINUX_MODULE
+#include "rclanmtl.h"
+
+#define dprintf kprintf
+
+extern int printk(const char * fmt, ...);
+
+ /* RedCreek LAN device Target ID */
+#define RC_LAN_TARGET_ID  0x10 
+ /* RedCreek's OSM default LAN receive Initiator */
+#define DEFAULT_RECV_INIT_CONTEXT  0xA17  
+
+
+/*
+** I2O message structures
+*/
+
+#define    I2O_TID_SZ                                  12
+#define    I2O_FUNCTION_SZ                             8
+
+/* Transaction Reply Lists (TRL) Control Word structure */
+
+#define    I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH           0x00
+#define    I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH        0x40
+#define    I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH         0x80
+
+/* LAN Class specific functions */
+
+#define    I2O_LAN_PACKET_SEND                         0x3B
+#define    I2O_LAN_SDU_SEND                            0x3D
+#define    I2O_LAN_RECEIVE_POST                        0x3E
+#define    I2O_LAN_RESET                               0x35
+#define    I2O_LAN_SHUTDOWN                            0x37
+
+/* Private Class specfic function */
+#define    I2O_PRIVATE                                 0xFF
+
+/*  I2O Executive Function Codes.  */
+
+#define    I2O_EXEC_ADAPTER_ASSIGN                     0xB3
+#define    I2O_EXEC_ADAPTER_READ                       0xB2
+#define    I2O_EXEC_ADAPTER_RELEASE                    0xB5
+#define    I2O_EXEC_BIOS_INFO_SET                      0xA5
+#define    I2O_EXEC_BOOT_DEVICE_SET                    0xA7
+#define    I2O_EXEC_CONFIG_VALIDATE                    0xBB
+#define    I2O_EXEC_CONN_SETUP                         0xCA
+#define    I2O_EXEC_DEVICE_ASSIGN                      0xB7
+#define    I2O_EXEC_DEVICE_RELEASE                     0xB9
+#define    I2O_EXEC_HRT_GET                            0xA8
+#define    I2O_EXEC_IOP_CLEAR                          0xBE
+#define    I2O_EXEC_IOP_CONNECT                        0xC9
+#define    I2O_EXEC_IOP_RESET                          0xBD
+#define    I2O_EXEC_LCT_NOTIFY                         0xA2
+#define    I2O_EXEC_OUTBOUND_INIT                      0xA1
+#define    I2O_EXEC_PATH_ENABLE                        0xD3
+#define    I2O_EXEC_PATH_QUIESCE                       0xC5
+#define    I2O_EXEC_PATH_RESET                         0xD7
+#define    I2O_EXEC_STATIC_MF_CREATE                   0xDD
+#define    I2O_EXEC_STATIC_MF_RELEASE                  0xDF
+#define    I2O_EXEC_STATUS_GET                         0xA0
+#define    I2O_EXEC_SW_DOWNLOAD                        0xA9
+#define    I2O_EXEC_SW_UPLOAD                          0xAB
+#define    I2O_EXEC_SW_REMOVE                          0xAD
+#define    I2O_EXEC_SYS_ENABLE                         0xD1
+#define    I2O_EXEC_SYS_MODIFY                         0xC1
+#define    I2O_EXEC_SYS_QUIESCE                        0xC3
+#define    I2O_EXEC_SYS_TAB_SET                        0xA3
+
+
+ /* Init Outbound Q status */
+#define    I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS          0x01
+#define    I2O_EXEC_OUTBOUND_INIT_REJECTED             0x02
+#define    I2O_EXEC_OUTBOUND_INIT_FAILED               0x03
+#define    I2O_EXEC_OUTBOUND_INIT_COMPLETE             0x04
+
+
+#define    I2O_UTIL_NOP                                0x00
+
+
+/* I2O Get Status State values */
+
+#define    I2O_IOP_STATE_INITIALIZING                  0x01
+#define    I2O_IOP_STATE_RESET                         0x02
+#define    I2O_IOP_STATE_HOLD                          0x04
+#define    I2O_IOP_STATE_READY                         0x05
+#define    I2O_IOP_STATE_OPERATIONAL                   0x08
+#define    I2O_IOP_STATE_FAILED                        0x10
+#define    I2O_IOP_STATE_FAULTED                       0x11
+
+
+/* Defines for Request Status Codes:  Table 3-1 Reply Status Codes.  */
+
+#define    I2O_REPLY_STATUS_SUCCESS                    0x00
+#define    I2O_REPLY_STATUS_ABORT_DIRTY                0x01
+#define    I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     0x02
+#define    I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER     0x03
+#define    I2O_REPLY_STATUS_ERROR_DIRTY                0x04
+#define    I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER     0x05
+#define    I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER     0x06
+#define    I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY        0x07
+#define    I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER   0x08
+#define    I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER   0x09
+#define    I2O_REPLY_STATUS_TRANSACTION_ERROR          0x0A
+#define    I2O_REPLY_STATUS_PROGRESS_REPORT            0x80
+
+
+/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/
+
+#define    I2O_DETAIL_STATUS_SUCCESS                        0x0000
+#define    I2O_DETAIL_STATUS_BAD_KEY                        0x0001
+#define    I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE         0x0002
+#define    I2O_DETAIL_STATUS_DEVICE_BUSY                    0x0003
+#define    I2O_DETAIL_STATUS_DEVICE_LOCKED                  0x0004
+#define    I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE           0x0005
+#define    I2O_DETAIL_STATUS_DEVICE_RESET                   0x0006
+#define    I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION         0x0007
+#define    I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD     0x0008
+#define    I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT     0x0009
+#define    I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS      0x000A
+#define    I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS          0x000B
+#define    I2O_DETAIL_STATUS_INVALID_OFFSET                 0x000C
+#define    I2O_DETAIL_STATUS_INVALID_PARAMETER              0x000D
+#define    I2O_DETAIL_STATUS_INVALID_REQUEST                0x000E
+#define    I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS         0x000F
+#define    I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE              0x0010
+#define    I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL              0x0011
+#define    I2O_DETAIL_STATUS_MISSING_PARAMETER              0x0012
+#define    I2O_DETAIL_STATUS_NO_SUCH_PAGE                   0x0013
+#define    I2O_DETAIL_STATUS_REPLY_BUFFER_FULL              0x0014
+#define    I2O_DETAIL_STATUS_TCL_ERROR                      0x0015
+#define    I2O_DETAIL_STATUS_TIMEOUT                        0x0016
+#define    I2O_DETAIL_STATUS_UNKNOWN_ERROR                  0x0017
+#define    I2O_DETAIL_STATUS_UNKNOWN_FUNCTION               0x0018
+#define    I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION           0x0019
+#define    I2O_DETAIL_STATUS_UNSUPPORTED_VERSION            0x001A
+
+ /* I2O msg header defines for VersionOffset */
+#define I2OMSGVER_1_5   0x0001
+#define SGL_OFFSET_0    I2OMSGVER_1_5
+#define SGL_OFFSET_4    (0x0040 | I2OMSGVER_1_5)
+#define TRL_OFFSET_5    (0x0050 | I2OMSGVER_1_5)
+#define TRL_OFFSET_6    (0x0060 | I2OMSGVER_1_5)
+
+ /* I2O msg header defines for MsgFlags */
+#define MSG_STATIC      0x0100
+#define MSG_64BIT_CNTXT 0x0200
+#define MSG_MULTI_TRANS 0x1000
+#define MSG_FAIL        0x2000
+#define MSG_LAST        0x4000
+#define MSG_REPLY       0x8000
+
+  /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
+#define LAN_MSG_REQST  (MSG_MULTI_TRANS | SGL_OFFSET_4)
+
+ /* minimum size msg */
+#define THREE_WORD_MSG_SIZE 0x00030000
+#define FOUR_WORD_MSG_SIZE  0x00040000
+#define FIVE_WORD_MSG_SIZE  0x00050000
+#define SIX_WORD_MSG_SIZE   0x00060000
+#define SEVEN_WORD_MSG_SIZE 0x00070000
+#define EIGHT_WORD_MSG_SIZE 0x00080000
+#define NINE_WORD_MSG_SIZE  0x00090000
+
+/* Special TID Assignments */
+
+#define I2O_IOP_TID   0
+#define I2O_HOST_TID  1
+
+ /* RedCreek I2O private message codes */
+#define RC_PRIVATE_GET_MAC_ADDR     0x0001/**/ /* OBSOLETE */
+#define RC_PRIVATE_SET_MAC_ADDR     0x0002
+#define RC_PRIVATE_GET_NIC_STATS    0x0003
+#define RC_PRIVATE_GET_LINK_STATUS  0x0004
+#define RC_PRIVATE_SET_LINK_SPEED   0x0005
+#define RC_PRIVATE_SET_IP_AND_MASK  0x0006
+/* #define RC_PRIVATE_GET_IP_AND_MASK  0x0007 */ /* OBSOLETE */
+#define RC_PRIVATE_GET_LINK_SPEED   0x0008
+#define RC_PRIVATE_GET_FIRMWARE_REV 0x0009
+/* #define RC_PRIVATE_GET_MAC_ADDR     0x000A *//**/
+#define RC_PRIVATE_GET_IP_AND_MASK  0x000B /**/
+#define RC_PRIVATE_DEBUG_MSG        0x000C
+#define RC_PRIVATE_REPORT_DRIVER_CAPABILITY  0x000D
+#define RC_PRIVATE_SET_PROMISCUOUS_MODE  0x000e
+#define RC_PRIVATE_GET_PROMISCUOUS_MODE  0x000f
+#define RC_PRIVATE_SET_BROADCAST_MODE    0x0010
+#define RC_PRIVATE_GET_BROADCAST_MODE    0x0011
+
+#define RC_PRIVATE_REBOOT           0x00FF
+
+
+/* I2O message header */
+typedef struct _I2O_MESSAGE_FRAME 
+{
+    U8                          VersionOffset;
+    U8                          MsgFlags;
+    U16                         MessageSize;
+    BF                          TargetAddress:I2O_TID_SZ;
+    BF                          InitiatorAddress:I2O_TID_SZ;
+    BF                          Function:I2O_FUNCTION_SZ;
+    U32                         InitiatorContext;
+    /* SGL[] */ 
+}
+I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
+
+
+ /* assumed a 16K minus 256 byte space for outbound queue message frames */
+#define MSG_FRAME_SIZE  512
+#define NMBR_MSG_FRAMES 30
+
+/*
+**  Message Unit CSR definitions for RedCreek PCI45 board
+*/
+typedef struct tag_rcatu 
+{
+    volatile unsigned long APICRegSel;  /* APIC Register Select */
+    volatile unsigned long reserved0;
+    volatile unsigned long APICWinReg;  /* APIC Window Register */
+    volatile unsigned long reserved1;
+    volatile unsigned long InMsgReg0;   /* inbound message register 0 */
+    volatile unsigned long InMsgReg1;   /* inbound message register 1 */
+    volatile unsigned long OutMsgReg0;  /* outbound message register 0 */
+    volatile unsigned long OutMsgReg1;  /* outbound message register 1 */
+    volatile unsigned long InDoorReg;   /* inbound doorbell register */
+    volatile unsigned long InIntStat;   /* inbound interrupt status register */
+    volatile unsigned long InIntMask;   /* inbound interrupt mask register */
+    volatile unsigned long OutDoorReg;  /* outbound doorbell register */
+    volatile unsigned long OutIntStat;  /* outbound interrupt status register */
+    volatile unsigned long OutIntMask;  /* outbound interrupt mask register */
+    volatile unsigned long reserved2;
+    volatile unsigned long reserved3;
+    volatile unsigned long InQueue;     /* inbound queue port */
+    volatile unsigned long OutQueue;    /* outbound queue port */
+    volatile unsigned long reserved4;
+    volatile unsigned long reserver5;
+    /* RedCreek extension */
+    volatile unsigned long EtherMacLow;
+    volatile unsigned long EtherMacHi;
+    volatile unsigned long IPaddr;
+    volatile unsigned long IPmask;
+}
+ATU, *PATU;
+
+ /* 
+ ** typedef PAB
+ **
+ ** PCI Adapter Block - holds instance specific information and is located
+ ** in a reserved space at the start of the message buffer allocated by user.
+ */
+typedef struct
+{
+    PATU             p_atu;                /* ptr to  ATU register block */
+    PU8              pPci45LinBaseAddr;
+    PU8              pLinOutMsgBlock;
+    U32              outMsgBlockPhyAddr; 
+    PFNTXCALLBACK    pTransCallbackFunc;
+    PFNRXCALLBACK    pRecvCallbackFunc;
+    PFNCALLBACK      pRebootCallbackFunc;
+    PFNCALLBACK      pCallbackFunc;
+    U16              IOPState;
+    U16              InboundMFrameSize;
+}
+PAB, *PPAB;
+
+ /* 
+ ** in reserved space right after PAB in host memory is area for returning
+ ** values from card 
+ */
+
+ /* 
+ ** Array of pointers to PCI Adapter Blocks.
+ ** Indexed by a zero based (0-31) interface number.
+ */ 
+#define MAX_ADAPTERS 32
+static PPAB  PCIAdapterBlock[MAX_ADAPTERS] = 
+{
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+
+/*
+** typedef NICSTAT
+**
+** Data structure for NIC statistics retruned from PCI card.  Data copied from
+** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.
+*/
+typedef struct tag_NicStat 
+{
+    unsigned long   TX_good; 
+    unsigned long   TX_maxcol;
+    unsigned long   TX_latecol;
+    unsigned long   TX_urun;
+    unsigned long   TX_crs;         /* lost carrier sense */
+    unsigned long   TX_def;         /* transmit deferred */
+    unsigned long   TX_singlecol;   /* single collisions */
+    unsigned long   TX_multcol;
+    unsigned long   TX_totcol;
+    unsigned long   Rcv_good;
+    unsigned long   Rcv_CRCerr;
+    unsigned long   Rcv_alignerr;
+    unsigned long   Rcv_reserr;     /* rnr'd pkts */
+    unsigned long   Rcv_orun;
+    unsigned long   Rcv_cdt;
+    unsigned long   Rcv_runt;
+    unsigned long   dump_status;    /* last field directly from the chip */
+} 
+NICSTAT, *P_NICSTAT;
+
+#define DUMP_DONE   0x0000A005      /* completed statistical dump */
+#define DUMP_CLEAR  0x0000A007      /* completed stat dump and clear counters */
+
+
+static volatile int msgFlag;
+
+
+/* local function prototypes */
+static void ProcessOutboundI2OMsg(PPAB pPab, U32 phyMsgAddr);
+static int FillI2OMsgSGLFromTCB(PU32 pMsg, PRCTCB pXmitCntrlBlock);
+static int GetI2OStatus(PPAB pPab);
+static int SendI2OOutboundQInitMsg(PPAB pPab);
+static int SendEnableSysMsg(PPAB pPab);
+
+
+/* 1st 100h bytes of message block is reserved for messenger instance */
+#define ADAPTER_BLOCK_RESERVED_SPACE 0x100
+
+/*
+** =========================================================================
+** RCInitI2OMsgLayer()
+**
+** Initialize the RedCreek I2O Module and adapter.
+**
+** Inputs:  AdapterID - interface number from 0 to 15
+**          pciBaseAddr - virual base address of PCI (set by BIOS)
+**          p_msgbuf - virual address to private message block (min. 16K)
+**          p_phymsgbuf - physical address of private message block
+**          TransmitCallbackFunction - address of transmit callback function
+**          ReceiveCallbackFunction  - address of receive  callback function
+**
+** private message block is allocated by user.  It must be in locked pages.
+** p_msgbuf and p_phymsgbuf point to the same location.  Must be contigous
+** memory block of a minimum of 16K byte and long word aligned.
+** =========================================================================
+*/
+RC_RETURN
+RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr, 
+                  PU8 p_msgbuf,  PU8 p_phymsgbuf,
+                  PFNTXCALLBACK  TransmitCallbackFunction,
+                  PFNRXCALLBACK  ReceiveCallbackFunction,
+                  PFNCALLBACK    RebootCallbackFunction)
+{
+    int result;
+    PPAB pPab; 
+    
+#ifdef DEBUG
+    kprintf("InitI2O: Adapter:0x%04.4ux ATU:0x%08.8ulx msgbuf:0x%08.8ulx phymsgbuf:0x%08.8ulx\n"
+            "TransmitCallbackFunction:0x%08.8ulx  ReceiveCallbackFunction:0x%08.8ulx\n",
+            AdapterID, pciBaseAddr, p_msgbuf, p_phymsgbuf, TransmitCallbackFunction, ReceiveCallbackFunction);
+#endif /* DEBUG */
+
+    
+    /* Check if this interface already initialized - if so, shut it down */
+    if (PCIAdapterBlock[AdapterID] != NULL)
+    {
+        printk("PCIAdapterBlock[%d]!=NULL\n", AdapterID);
+//        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
+        PCIAdapterBlock[AdapterID] = NULL;
+    }
+
+    /* 
+    ** store adapter instance values in adapter block.
+    ** Adapter block is at beginning of message buffer
+    */  
+    pPab = (PPAB)p_msgbuf;
+    
+    pPab->p_atu = (PATU)pciBaseAddr;
+    pPab->pPci45LinBaseAddr =  (PU8)pciBaseAddr;
+    
+    /* Set outbound message frame addr - skip over Adapter Block */
+    pPab->outMsgBlockPhyAddr = (U32)(p_phymsgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
+    pPab->pLinOutMsgBlock    = (PU8)(p_msgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
+
+    /* store callback function addresses */
+    pPab->pTransCallbackFunc = TransmitCallbackFunction;
+    pPab->pRecvCallbackFunc  = ReceiveCallbackFunction;
+    pPab->pRebootCallbackFunc  = RebootCallbackFunction;
+    pPab->pCallbackFunc  = (PFNCALLBACK)NULL;
+
+    /*
+    ** Initialize I2O IOP
+    */
+    result = GetI2OStatus(pPab);
+    
+    if (result != RC_RTN_NO_ERROR)
+        return result;
+
+    if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL)
+    {
+        printk("pPab->IOPState == op: resetting adapter\n");
+        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
+    }
+        
+    result = SendI2OOutboundQInitMsg(pPab);
+    
+    if (result != RC_RTN_NO_ERROR)
+        return result;
+
+    result = SendEnableSysMsg(pPab);
+   
+    if (result != RC_RTN_NO_ERROR)
+        return result;
+   
+    PCIAdapterBlock[AdapterID] = pPab;
+    return RC_RTN_NO_ERROR;
+}
+
+/*
+** =========================================================================
+** Disable and Enable I2O interrupts.  I2O interrupts are enabled at Init time
+** but can be disabled and re-enabled through these two function calls.
+** Packets will still be put into any posted received buffers and packets will
+** be sent through RCI2OSendPacket() functions.  Disabling I2O interrupts
+** will prevent hardware interrupt to host even though the outbound I2O msg
+** queue is not emtpy.
+** =========================================================================
+*/
+#define i960_OUT_POST_Q_INT_BIT        0x0008 /* bit set masks interrupts */
+
+RC_RETURN RCDisableI2OInterrupts(U16 AdapterID)
+{
+    PPAB pPab;
+
+
+    pPab = PCIAdapterBlock[AdapterID];
+    
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+        
+    pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT;
+
+    return RC_RTN_NO_ERROR;
+}
+
+RC_RETURN RCEnableI2OInterrupts(U16 AdapterID)
+{
+    PPAB pPab;
+
+    pPab = PCIAdapterBlock[AdapterID];
+    
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT;
+    
+    return RC_RTN_NO_ERROR;
+
+}
+
+
+/*
+** =========================================================================
+** RCI2OSendPacket()
+** =========================================================================
+*/
+RC_RETURN
+RCI2OSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock)
+{
+    U32 msgOffset;
+    PU32 pMsg;
+    int size;
+    PPAB pPab;
+
+#ifdef DEBUG
+    kprintf("RCI2OSendPacket()...\n");
+#endif /* DEBUG */
+    
+    pPab = PCIAdapterBlock[AdapterID];
+
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    /* get Inbound free Q entry - reading from In Q gets free Q entry */
+    /* offset to Msg Frame in PCI msg block */
+
+    msgOffset = pPab->p_atu->InQueue; 
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        kprintf("RCI2OSendPacket(): Inbound Free Q empty!\n");
+#endif /* DEBUG */
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+        
+    /* calc virual address of msg - virual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
+
+    if (size == -1) /* error processing TCB - send NOP msg */
+    {
+#ifdef DEBUG
+        kprintf("RCI2OSendPacket(): Error Rrocess TCB!\n");
+#endif /* DEBUG */
+        pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
+        pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+        return RC_RTN_TCB_ERROR;
+    }
+    else /* send over msg header */
+    {    
+        pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
+        pMsg[1] = I2O_LAN_PACKET_SEND << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+        pMsg[2] = InitiatorContext;
+        pMsg[3] = 0;  /* batch reply */
+        /* post to Inbound Post Q */   
+        pPab->p_atu->InQueue = msgOffset;
+        return RC_RTN_NO_ERROR;
+    }
+}
+
+/*
+** =========================================================================
+** RCI2OPostRecvBuffer()
+**
+** inputs:  pBufrCntrlBlock - pointer to buffer control block
+**
+** returns TRUE if successful in sending message, else FALSE.
+** =========================================================================
+*/
+RC_RETURN
+RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock)
+{
+    U32 msgOffset;
+    PU32 pMsg;
+    int size;
+    PPAB pPab;
+
+#ifdef DEBUG
+    kprintf("RCPostRecvBuffers()...\n");
+#endif /* DEBUG */
+    
+    /* search for DeviceHandle */
+    pPab = PCIAdapterBlock[AdapterID];
+
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+
+    /* get Inbound free Q entry - reading from In Q gets free Q entry */
+    /* offset to Msg Frame in PCI msg block */
+    msgOffset = pPab->p_atu->InQueue; 
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");
+#endif /* DEBUG */
+        return RC_RTN_FREE_Q_EMPTY;
+   
+    }
+    /* calc virual address of msg - virual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
+
+    if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */
+    {
+#ifdef DEBUG
+        kprintf("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size);
+#endif /* DEBUG */
+        pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
+        pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+        /* post to Post Q */   
+        pPab->p_atu->InQueue = msgOffset;
+        return RC_RTN_TCB_ERROR;
+    }
+    else /* send over size msg header */
+    {    
+        pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
+        pMsg[1] = I2O_LAN_RECEIVE_POST << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+        pMsg[3] = *(PU32)pTransCtrlBlock; /* number of packet buffers */
+        /* post to Post Q */   
+        pPab->p_atu->InQueue = msgOffset;
+        return RC_RTN_NO_ERROR;
+    }
+}
+
+
+/*
+** =========================================================================
+** RCProcI2OMsgQ()
+**
+** Process I2O outbound message queue until empty.
+** =========================================================================
+*/
+void 
+RCProcI2OMsgQ(U16 AdapterID)
+{
+    U32 phyAddrMsg;
+    PU8 p8Msg;
+    PU32 p32;
+    U16 count;
+    PPAB pPab;
+    unsigned char debug_msg[20];
+    
+    pPab = PCIAdapterBlock[AdapterID];
+    
+    if (pPab == NULL)
+        return;
+    
+    phyAddrMsg = pPab->p_atu->OutQueue;
+
+    while (phyAddrMsg != 0xFFFFFFFF)
+    {
+        p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
+        p32 = (PU32)p8Msg;
+        
+        //printk(" msg: 0x%x  0x%x \n", p8Msg[7], p32[5]);
+
+        /* 
+        ** Send Packet Reply Msg
+        */
+        if (I2O_LAN_PACKET_SEND == p8Msg[7])  /* function code byte */
+        {
+            count = *(PU16)(p8Msg+2);
+            count -= p8Msg[0] >> 4;
+            /* status, count, context[], adapter */
+            (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID);
+        }             
+        /* 
+        ** Receive Packet Reply Msg */
+        else if (I2O_LAN_RECEIVE_POST == p8Msg[7])
+        {
+#ifdef DEBUG    
+            kprintf("I2O_RECV_REPLY pPab:0x%08.8ulx p8Msg:0x%08.8ulx p32:0x%08.8ulx\n", pPab, p8Msg, p32);
+            kprintf("msg: 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
+                    p32[0], p32[1], p32[2], p32[3]);
+            kprintf("     0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
+                    p32[4], p32[5], p32[6], p32[7]);
+            kprintf("     0x%08.8ulx:0X%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
+                    p32[8], p32[9], p32[10], p32[11]);
+#endif
+            /*  status, count, buckets remaining, packetParmBlock, adapter */
+            (*pPab->pRecvCallbackFunc)(p8Msg[19], p8Msg[12], p32[5], p32+6, AdapterID);
+      
+      
+        }
+        else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7])
+        {
+            if (pPab->pCallbackFunc)
+            {
+                (*pPab->pCallbackFunc)(p8Msg[19],0,0,AdapterID);
+            }
+            else
+            {
+                pPab->pCallbackFunc = (PFNCALLBACK) 1;
+            }
+            //PCIAdapterBlock[AdapterID] = 0;
+        }
+        else if (I2O_PRIVATE == p8Msg[7])
+        {
+            //printk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
+            switch (p32[5])
+            {
+            case RC_PRIVATE_DEBUG_MSG:
+                msgFlag = 1;
+                /*printk("Received I2O_PRIVATE msg\n");*/
+                debug_msg[15]  = (p32[6]&0xff000000) >> 24;
+                debug_msg[14]  = (p32[6]&0x00ff0000) >> 16;
+                debug_msg[13]  = (p32[6]&0x0000ff00) >> 8;
+                debug_msg[12]  = (p32[6]&0x000000ff);
+
+                debug_msg[11]  = (p32[7]&0xff000000) >> 24;
+                debug_msg[10]  = (p32[7]&0x00ff0000) >> 16;
+                debug_msg[ 9]  = (p32[7]&0x0000ff00) >> 8;
+                debug_msg[ 8]  = (p32[7]&0x000000ff);
+
+                debug_msg[ 7]  = (p32[8]&0xff000000) >> 24;
+                debug_msg[ 6]  = (p32[8]&0x00ff0000) >> 16;
+                debug_msg[ 5] = (p32[8]&0x0000ff00) >> 8;
+                debug_msg[ 4] = (p32[8]&0x000000ff);
+
+                debug_msg[ 3] = (p32[9]&0xff000000) >> 24;
+                debug_msg[ 2] = (p32[9]&0x00ff0000) >> 16;
+                debug_msg[ 1] = (p32[9]&0x0000ff00) >> 8;
+                debug_msg[ 0] = (p32[9]&0x000000ff);
+
+                debug_msg[16] = '\0';
+                printk (debug_msg);
+                break;
+            case RC_PRIVATE_REBOOT:
+                printk("Adapter reboot initiated...\n");
+                if (pPab->pRebootCallbackFunc)
+                {
+                    (*pPab->pRebootCallbackFunc)(0,0,0,AdapterID);
+                }
+                break;
+            default:
+                printk("Unknown private I2O msg received: 0x%x\n",
+                       p32[5]);
+                break;
+            }
+        }
+
+        /* 
+        ** Process other Msg's
+        */
+        else
+        {
+            ProcessOutboundI2OMsg(pPab, phyAddrMsg);
+        }
+        
+        /* return MFA to outbound free Q*/
+        pPab->p_atu->OutQueue = phyAddrMsg;
+    
+        /* any more msgs? */
+        phyAddrMsg = pPab->p_atu->OutQueue;
+    }
+}
+
+
+/*
+** =========================================================================
+**  Returns LAN interface statistical counters to space provided by caller at
+**  StatsReturnAddr.  Returns 0 if success, else RC_RETURN code.
+**  This function will call the WaitCallback function provided by
+**  user while waiting for card to respond.
+** =========================================================================
+*/
+RC_RETURN
+RCGetLinkStatistics(U16 AdapterID, 
+                    P_RCLINKSTATS StatsReturnAddr,
+                    PFNWAITCALLBACK WaitCallback)
+{
+    U32 msgOffset;
+    volatile U32 timeout;
+    volatile PU32 pMsg;
+    volatile PU32 p32, pReturnAddr;
+    P_NICSTAT pStats;
+    int i;
+    PPAB pPab;
+
+/*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/
+
+    pPab = PCIAdapterBlock[AdapterID];
+
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    msgOffset = pPab->p_atu->InQueue;
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        kprintf("Get8255XStats(): Inbound Free Q empty!\n");
+#endif
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virual address of msg - virual already mapped to physical */
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+/*dprintf("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
+/*dprintf("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
+
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+    pMsg[3] = 0x112; /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_NIC_STATS;
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+
+    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+
+    pStats = (P_NICSTAT)p32;
+    pStats->dump_status = 0xFFFFFFFF;
+
+    /* post to Inbound Post Q */
+    pPab->p_atu->InQueue = msgOffset;
+
+    timeout = 100000;
+    while (1)
+    {
+        if (WaitCallback)
+            (*WaitCallback)();
+        
+        for (i = 0; i < 1000; i++)
+            ;
+
+        if (pStats->dump_status != 0xFFFFFFFF)
+            break;
+
+        if (!timeout--)
+        {
+#ifdef DEBUG
+            kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");
+#endif
+            return RC_RTN_MSG_REPLY_TIMEOUT;
+        }
+    }
+    
+    pReturnAddr = (PU32)StatsReturnAddr;
+    
+    /* copy Nic stats to user's structure */
+    for (i = 0; i < (int) sizeof(RCLINKSTATS) / 4; i++)
+        pReturnAddr[i] = p32[i];
+   
+    return RC_RTN_NO_ERROR;     
+}
+
+
+/*
+** =========================================================================
+** Get82558LinkStatus()
+** =========================================================================
+*/
+RC_RETURN
+RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback)
+{
+    U32 msgOffset;
+    volatile U32 timeout;
+    volatile PU32 pMsg;
+    volatile PU32 p32;
+    PPAB pPab;
+
+/*kprintf("Get82558LinkStatus() ReturnPhysAddr:0x%08.8ulx\n", ReturnAddr);*/
+
+    pPab = PCIAdapterBlock[AdapterID];
+
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    msgOffset = pPab->p_atu->InQueue;
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n");
+#endif
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virual address of msg - virual already mapped to physical */
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+/*dprintf("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
+/*dprintf("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
+
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+    pMsg[3] = 0x112; /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_STATUS;
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+
+    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    *p32 = 0xFFFFFFFF;
+    
+    /* post to Inbound Post Q */
+    pPab->p_atu->InQueue = msgOffset;
+
+    timeout = 100000;
+    while (1)
+    {
+        U32 i;
+
+        if (WaitCallback)
+            (*WaitCallback)();
+        
+        for (i = 0; i < 1000; i++)
+            ;
+
+        if (*p32 != 0xFFFFFFFF)
+            break;
+
+        if (!timeout--)
+        {
+#ifdef DEBUG
+            kprintf("Timeout waiting for link status\n");
+#endif    
+            return RC_RTN_MSG_REPLY_TIMEOUT;
+        }
+    }
+    
+    *ReturnAddr = *p32; /* 1 = up 0 = down */
+    
+    return RC_RTN_NO_ERROR;
+    
+}
+
+/*
+** =========================================================================
+** RCGetMAC()
+**
+** get the MAC address the adapter is listening for in non-promiscous mode.
+** MAC address is in media format.
+** =========================================================================
+*/
+RC_RETURN
+RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback)
+{
+    unsigned i, timeout;
+    U32      off;
+    PU32     p;
+    U32      temp[2];
+    PPAB     pPab;
+    PATU     p_atu;
+    
+    pPab = PCIAdapterBlock[AdapterID];
+    
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    p_atu = pPab->p_atu;
+
+    p_atu->EtherMacLow = 0;     /* first zero return data */
+    p_atu->EtherMacHi = 0;
+    
+    off = p_atu->InQueue;   /* get addresss of message */
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+
+    p = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+#ifdef RCDEBUG
+    printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
+           (uint)p_atu, (uint)off, (uint)p);
+#endif /* RCDEBUG */
+    /* setup private message */
+    p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
+    p[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    p[2] = 0;               /* initiator context */
+    p[3] = 0x218;           /* transaction context */
+    p[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_MAC_ADDR;
+
+
+    p_atu->InQueue = off;   /* send it to the I2O device */
+#ifdef RCDEBUG
+    printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
+           (uint)p_atu, (uint)off, (uint)p);
+#endif /* RCDEBUG */
+
+    /* wait for the rcpci45 board to update the info */
+    timeout = 1000000;
+    while (0 == p_atu->EtherMacLow) 
+    {
+        if (WaitCallback)
+            (*WaitCallback)();
+    
+        for (i = 0; i < 1000; i++)
+            ;
+
+        if (!timeout--)
+        {
+            printk("rc_getmac: Timeout\n");
+            return RC_RTN_MSG_REPLY_TIMEOUT;
+        }
+    }
+    
+    /* read the mac address  */
+    temp[0] = p_atu->EtherMacLow;
+    temp[1] = p_atu->EtherMacHi;
+    memcpy((char *)mac, (char *)temp, 6);
+
+
+#ifdef RCDEBUG
+//    printk("rc_getmac: 0x%X\n", ptr);
+#endif /* RCDEBUG */
+
+    return RC_RTN_NO_ERROR;
+}
+
+/*
+** =========================================================================
+** RCSetMAC()
+**
+** set MAC address the adapter is listening for in non-promiscous mode.
+** MAC address is in media format.
+** =========================================================================
+*/
+RC_RETURN
+RCSetMAC(U16 AdapterID, PU8 mac)
+{
+    U32  off;
+    PU32 pMsg;
+    PPAB pPab;
+
+
+    pPab = PCIAdapterBlock[AdapterID];
+    
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup private message */
+    pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_MAC_ADDR;
+    pMsg[5] = *(unsigned *)mac;  /* first four bytes */
+    pMsg[6] = *(unsigned *)(mac + 4); /* last two bytes */
+    
+    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
+
+    return RC_RTN_NO_ERROR ;
+}
+
+
+/*
+** =========================================================================
+** RCSetLinkSpeed()
+**
+** set ethernet link speed. 
+** input: speedControl - determines action to take as follows
+**          0 = reset and auto-negotiate (NWay)
+**          1 = Full Duplex 100BaseT
+**          2 = Half duplex 100BaseT
+**          3 = Full Duplex  10BaseT
+**          4 = Half duplex  10BaseT
+**          all other values are ignore (do nothing)
+** =========================================================================
+*/
+RC_RETURN
+RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode)
+{
+    U32  off;
+    PU32 pMsg;
+    PPAB pPab;
+
+    
+    pPab =PCIAdapterBlock[AdapterID];
+     
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_LINK_SPEED;
+    pMsg[5] = LinkSpeedCode;     /* link speed code */
+
+    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
+
+    return RC_RTN_NO_ERROR ;
+}
+/*
+** =========================================================================
+** RCSetPromiscuousMode()
+**
+** Defined values for Mode:
+**  0 - turn off promiscuous mode
+**  1 - turn on  promiscuous mode
+**
+** =========================================================================
+*/
+RC_RETURN
+RCSetPromiscuousMode(U16 AdapterID, U16 Mode)
+{
+    U32  off;
+    PU32 pMsg;
+    PPAB pPab;
+    
+    pPab =PCIAdapterBlock[AdapterID];
+     
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_PROMISCUOUS_MODE;
+    pMsg[5] = Mode;     /* promiscuous mode setting */
+
+    pPab->p_atu->InQueue = off;   /* send it to the device */
+
+    return RC_RTN_NO_ERROR ;
+}
+/*
+** =========================================================================
+** RCGetPromiscuousMode()
+**
+** get promiscuous mode setting
+**
+** Possible return values placed in pMode:
+**  0 = promisuous mode not set
+**  1 = promisuous mode is set
+**
+** =========================================================================
+*/
+RC_RETURN
+RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+{
+    U32 msgOffset, timeout;
+    PU32 pMsg;
+    volatile PU32 p32;
+    PPAB pPab;
+
+    pPab =PCIAdapterBlock[AdapterID];
+
+
+    msgOffset = pPab->p_atu->InQueue;
+
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virtual address of msg - virtual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    /* virtual pointer to return buffer - clear first two dwords */
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0xff;
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_PROMISCUOUS_MODE;
+    /* phys address to return status - area right after PAB */
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+   
+    /* post to Inbound Post Q */   
+
+    pPab->p_atu->InQueue = msgOffset;
+
+    /* wait for response */
+    timeout = 1000000;
+    while(1)
+    {
+        int i;
+        
+        if (WaitCallback)
+            (*WaitCallback)();
+
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0] != 0xff)
+            break;
+            
+        if (!timeout--)
+        {
+            kprintf("Timeout waiting for promiscuous mode from adapter\n");
+            kprintf("0x%08.8ulx\n", p32[0]);
+            return RC_RTN_NO_LINK_SPEED;
+        }
+    }
+
+    /* get mode */
+    *pMode = (U8)((volatile PU8)p32)[0] & 0x0f;
+
+    return RC_RTN_NO_ERROR;
+}
+/*
+** =========================================================================
+** RCSetBroadcastMode()
+**
+** Defined values for Mode:
+**  0 - turn off promiscuous mode
+**  1 - turn on  promiscuous mode
+**
+** =========================================================================
+*/
+RC_RETURN
+RCSetBroadcastMode(U16 AdapterID, U16 Mode)
+{
+    U32  off;
+    PU32 pMsg;
+    PPAB pPab;
+    
+    pPab =PCIAdapterBlock[AdapterID];
+     
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_BROADCAST_MODE;
+    pMsg[5] = Mode;     /* promiscuous mode setting */
+
+    pPab->p_atu->InQueue = off;   /* send it to the device */
+
+    return RC_RTN_NO_ERROR ;
+}
+/*
+** =========================================================================
+** RCGetBroadcastMode()
+**
+** get promiscuous mode setting
+**
+** Possible return values placed in pMode:
+**  0 = promisuous mode not set
+**  1 = promisuous mode is set
+**
+** =========================================================================
+*/
+RC_RETURN
+RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+{
+    U32 msgOffset, timeout;
+    PU32 pMsg;
+    volatile PU32 p32;
+    PPAB pPab;
+
+    pPab =PCIAdapterBlock[AdapterID];
+
+
+    msgOffset = pPab->p_atu->InQueue;
+
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virtual address of msg - virtual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    /* virtual pointer to return buffer - clear first two dwords */
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0xff;
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_BROADCAST_MODE;
+    /* phys address to return status - area right after PAB */
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+   
+    /* post to Inbound Post Q */   
+
+    pPab->p_atu->InQueue = msgOffset;
+
+    /* wait for response */
+    timeout = 1000000;
+    while(1)
+    {
+        int i;
+        
+        if (WaitCallback)
+            (*WaitCallback)();
+
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0] != 0xff)
+            break;
+            
+        if (!timeout--)
+        {
+            kprintf("Timeout waiting for promiscuous mode from adapter\n");
+            kprintf("0x%08.8ulx\n", p32[0]);
+            return RC_RTN_NO_LINK_SPEED;
+        }
+    }
+
+    /* get mode */
+    *pMode = (U8)((volatile PU8)p32)[0] & 0x0f;
+
+    return RC_RTN_NO_ERROR;
+}
+
+/*
+** =========================================================================
+** RCGetLinkSpeed()
+**
+** get ethernet link speed. 
+**
+** 0 = Unknown
+** 1 = Full Duplex 100BaseT
+** 2 = Half duplex 100BaseT
+** 3 = Full Duplex  10BaseT
+** 4 = Half duplex  10BaseT
+**
+** =========================================================================
+*/
+RC_RETURN
+RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback)
+{
+    U32 msgOffset, timeout;
+    PU32 pMsg;
+    volatile PU32 p32;
+    U8 IOPLinkSpeed;
+    PPAB pPab;
+
+    pPab =PCIAdapterBlock[AdapterID];
+
+
+    msgOffset = pPab->p_atu->InQueue;
+
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virtual address of msg - virtual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    /* virtual pointer to return buffer - clear first two dwords */
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0xff;
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_SPEED;
+    /* phys address to return status - area right after PAB */
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+   
+    /* post to Inbound Post Q */   
+
+    pPab->p_atu->InQueue = msgOffset;
+
+    /* wait for response */
+    timeout = 1000000;
+    while(1)
+    {
+        int i;
+        
+        if (WaitCallback)
+            (*WaitCallback)();
+
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0] != 0xff)
+            break;
+            
+        if (!timeout--)
+        {
+            kprintf("Timeout waiting for link speed from IOP\n");
+            kprintf("0x%08.8ulx\n", p32[0]);
+            return RC_RTN_NO_LINK_SPEED;
+        }
+    }
+
+    /* get Link speed */
+    IOPLinkSpeed = (U8)((volatile PU8)p32)[0] & 0x0f;
+
+    *pLinkSpeedCode= IOPLinkSpeed;
+
+    return RC_RTN_NO_ERROR;
+}
+
+/*
+** =========================================================================
+** RCReportDriverCapability(U16 AdapterID, U32 capability)
+**
+** Currently defined bits:
+** WARM_REBOOT_CAPABLE   0x01
+**
+** =========================================================================
+*/
+RC_RETURN
+RCReportDriverCapability(U16 AdapterID, U32 capability)
+{
+    U32  off;
+    PU32 pMsg;
+    PPAB pPab;
+
+    pPab =PCIAdapterBlock[AdapterID];
+     
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_REPORT_DRIVER_CAPABILITY;
+    pMsg[5] = capability;
+
+    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
+
+    return RC_RTN_NO_ERROR ;
+}
+
+/*
+** =========================================================================
+** RCGetFirmwareVer()
+**
+** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
+**
+** =========================================================================
+*/
+RC_RETURN
+RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback)
+{
+    U32 msgOffset, timeout;
+    PU32 pMsg;
+    volatile PU32 p32;
+    PPAB pPab;
+
+    pPab =PCIAdapterBlock[AdapterID];
+
+    msgOffset = pPab->p_atu->InQueue;
+
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+        kprintf("RCGetFirmwareVer(): Inbound Free Q empty!\n");
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virtual address of msg - virtual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    /* virtual pointer to return buffer - clear first two dwords */
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0xff;
+
+    /* setup private message */
+    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_FIRMWARE_REV;
+    /* phys address to return status - area right after PAB */
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+
+
+   
+    /* post to Inbound Post Q */   
+
+    pPab->p_atu->InQueue = msgOffset;
+
+    
+    /* wait for response */
+    timeout = 1000000;
+    while(1)
+    {
+        int i;
+        
+        if (WaitCallback)
+            (*WaitCallback)();
+            
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+
+        if (p32[0] != 0xff)
+            break;
+            
+        if (!timeout--)
+        {
+            kprintf("Timeout waiting for link speed from IOP\n");
+            return RC_RTN_NO_FIRM_VER;
+        }
+    }
+
+    strcpy(pFirmString, (PU8)p32);
+    return RC_RTN_NO_ERROR;
+}
+
+/*
+** =========================================================================
+** RCResetLANCard()
+**
+** ResourceFlags indicates whether to return buffer resource explicitly
+** to host or keep and reuse.
+** CallbackFunction (if not NULL) is the function to be called when 
+** reset is complete.
+** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
+** reset is done (if not NULL).
+**
+** =========================================================================
+*/
+RC_RETURN 
+RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
+{
+    unsigned long off;
+    unsigned long *pMsg;
+    PPAB pPab;
+    int i;
+    long timeout = 0;
+
+    
+    pPab =PCIAdapterBlock[AdapterID];
+     
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pPab->pCallbackFunc = CallbackFunction;
+
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup message */
+    pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_LAN_RESET << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+    pMsg[3] = ResourceFlags << 16;   /* resource flags */
+
+    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
+
+    if (CallbackFunction == (PFNCALLBACK)NULL)
+    {
+        /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
+           or until timer goes off */
+        while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
+        {
+            RCProcI2OMsgQ(AdapterID);
+            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
+                ;
+            timeout++;
+            if (timeout > 10000)
+            {
+                break;
+            }
+        }
+        if (ReturnAddr != (PU32)NULL)
+            *ReturnAddr = (U32)pPab->pCallbackFunc;
+    }
+
+    return RC_RTN_NO_ERROR ;
+}
+/*
+** =========================================================================
+** RCResetIOP()
+**
+** Send StatusGet Msg, wait for results return directly to buffer.
+**
+** =========================================================================
+*/
+RC_RETURN 
+RCResetIOP(U16 AdapterID)
+{
+    U32 msgOffset, timeout;
+    PU32 pMsg;
+    PPAB pPab;
+    volatile PU32 p32;
+    
+    pPab = PCIAdapterBlock[AdapterID];
+    msgOffset = pPab->p_atu->InQueue;
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virtual address of msg - virtual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_EXEC_IOP_RESET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
+    pMsg[2] = 0; /* universal context */
+    pMsg[3] = 0; /* universal context */
+    pMsg[4] = 0; /* universal context */
+    pMsg[5] = 0; /* universal context */
+    /* phys address to return status - area right after PAB */
+    pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[7] = 0;
+    pMsg[8] = 1;  /*  return 1 byte */
+
+    /* virual pointer to return buffer - clear first two dwords */
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0;
+    p32[1] = 0;
+
+    /* post to Inbound Post Q */   
+
+    pPab->p_atu->InQueue = msgOffset;
+
+    /* wait for response */
+    timeout = 1000000;
+    while(1)
+    {
+        int i;
+        
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0] || p32[1])
+            break;
+            
+        if (!timeout--)
+        {
+            printk("RCResetIOP timeout\n");
+            return RC_RTN_MSG_REPLY_TIMEOUT;
+        }
+    }
+    return RC_RTN_NO_ERROR;
+}
+
+/*
+** =========================================================================
+** RCShutdownLANCard()
+**
+** ResourceFlags indicates whether to return buffer resource explicitly
+** to host or keep and reuse.
+** CallbackFunction (if not NULL) is the function to be called when 
+** shutdown is complete.
+** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
+** shutdown is done (if not NULL).
+**
+** =========================================================================
+*/
+RC_RETURN 
+RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
+{
+    volatile PU32 pMsg;
+    U32 off;
+    PPAB pPab;
+    int i;
+    long timeout = 0;
+
+    pPab = PCIAdapterBlock[AdapterID];
+
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+
+    pPab->pCallbackFunc = CallbackFunction;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup message */
+    pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_LAN_SHUTDOWN << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+    pMsg[3] = ResourceFlags << 16;   /* resource flags */
+
+    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
+
+    if (CallbackFunction == (PFNCALLBACK)NULL)
+    {
+        /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
+           or until timer goes off */
+        while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
+        {
+            RCProcI2OMsgQ(AdapterID);
+            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
+                ;
+            timeout++;
+            if (timeout > 10000)
+            {
+                               printk("RCShutdownLANCard(): timeout\n");
+                break;
+            }
+        }
+        if (ReturnAddr != (PU32)NULL)
+            *ReturnAddr = (U32)pPab->pCallbackFunc;
+    }
+    return RC_RTN_NO_ERROR ;
+}
+
+
+/*
+** =========================================================================
+** RCSetRavlinIPandMask()
+**
+** Set the Ravlin 45/PCI cards IP address and network mask.
+**
+** IP address and mask must be in network byte order.
+** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
+** 0x04030201 and 0x00FFFFFF on a little endian machine.
+**
+** =========================================================================
+*/
+RC_RETURN
+RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask)
+{
+    volatile PU32 pMsg;
+    U32 off;
+    PPAB pPab;
+
+    pPab = PCIAdapterBlock[AdapterID];
+
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+
+    off = pPab->p_atu->InQueue; /* get addresss of message */
+    
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+    /* setup private message */
+    pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;                 /* initiator context */
+    pMsg[3] = 0x219;             /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_IP_AND_MASK;
+    pMsg[5] = ipAddr; 
+    pMsg[6] = netMask;
+
+
+    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
+    return RC_RTN_NO_ERROR ;
+
+}
+
+/*
+** =========================================================================
+** RCGetRavlinIPandMask()
+**
+** get the IP address and MASK from the card
+** 
+** =========================================================================
+*/
+RC_RETURN
+RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, 
+                     PFNWAITCALLBACK WaitCallback)
+{
+    unsigned i, timeout;
+    U32      off;
+    PU32     pMsg, p32;
+    PPAB     pPab;
+    PATU     p_atu;
+    
+#ifdef DEBUG
+    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
+#endif /* DEBUG */
+
+    pPab = PCIAdapterBlock[AdapterID];
+    
+    if (pPab == NULL)
+        return RC_RTN_ADPTR_NOT_REGISTERED;
+    
+    p_atu = pPab->p_atu;
+    off = p_atu->InQueue;   /* get addresss of message */
+    if (0xFFFFFFFF == off)
+        return RC_RTN_FREE_Q_EMPTY;
+
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    *p32 = 0xFFFFFFFF;
+
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
+
+#ifdef DEBUG
+    kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
+#endif /* DEBUG */
+    /* setup private message */
+    pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
+    pMsg[2] = 0;               /* initiator context */
+    pMsg[3] = 0x218;           /* transaction context */
+    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK;
+    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+
+    p_atu->InQueue = off;   /* send it to the I2O device */
+#ifdef DEBUG
+    kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
+#endif /* DEBUG */
+
+    /* wait for the rcpci45 board to update the info */
+    timeout = 100000;
+    while (0xffffffff == *p32)
+    {
+        if (WaitCallback)
+            (*WaitCallback)();
+    
+        for (i = 0; i < 1000; i++)
+            ;
+
+        if (!timeout--)
+        {
+#ifdef DEBUG
+            kprintf("RCGetRavlinIPandMask: Timeout\n");
+#endif /* DEBUG */
+            return RC_RTN_MSG_REPLY_TIMEOUT;
+        }
+    }
+
+#ifdef DEBUG
+    kprintf("RCGetRavlinIPandMask: after time out\n", \
+            "p32[0] (IpAddr) 0x%08.8ulx, p32[1] (IPmask) 0x%08.8ulx\n", p32[0], p32[1]);
+#endif /* DEBUG */
+    
+    /* send IP and mask to user's space  */
+    *pIpAddr  = p32[0];
+    *pNetMask = p32[1];
+
+
+#ifdef DEBUG
+    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
+#endif /* DEBUG */
+
+    return RC_RTN_NO_ERROR;
+}
+
+/* 
+** /////////////////////////////////////////////////////////////////////////
+** /////////////////////////////////////////////////////////////////////////
+**
+**                        local functions
+**
+** /////////////////////////////////////////////////////////////////////////
+** /////////////////////////////////////////////////////////////////////////
+*/
+
+/*
+** =========================================================================
+** SendI2OOutboundQInitMsg()
+**
+** =========================================================================
+*/
+static int 
+SendI2OOutboundQInitMsg(PPAB pPab)
+{
+    U32 msgOffset, timeout, phyOutQFrames, i;
+    volatile PU32 pMsg;
+    volatile PU32 p32;
+    
+    
+    
+    msgOffset = pPab->p_atu->InQueue;
+
+    
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
+#endif /* DEBUG */
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+    
+    
+    /* calc virual address of msg - virual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+#ifdef DEBUG
+    kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
+#endif /* DEBUG */
+
+    pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
+    pMsg[1] = I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
+    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+    pMsg[3] = 0x106; /* transaction context */
+    pMsg[4] = 4096; /* Host page frame size */
+    pMsg[5] = MSG_FRAME_SIZE  << 16 | 0x80; /* outbound msg frame size and Initcode */
+    pMsg[6] = 0xD0000004;       /* simple sgl element LE, EOB */
+    /* phys address to return status - area right after PAB */
+    pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+
+    /* virual pointer to return buffer - clear first two dwords */
+    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0;
+    
+    /* post to Inbound Post Q */   
+    pPab->p_atu->InQueue = msgOffset;
+    
+    /* wait for response */
+    timeout = 100000;
+    while(1)
+    {
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0])
+            break;
+            
+        if (!timeout--)
+        {
+#ifdef DEBUG
+            kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
+#endif /* DEBUG */
+            return RC_RTN_NO_I2O_STATUS;
+        }
+    }
+
+    timeout = 100000;
+    while(1)
+    {
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
+            break;
+
+        if (!timeout--)
+        {
+#ifdef DEBUG
+            kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
+#endif /* DEBUG */
+            return RC_RTN_NO_I2O_STATUS;
+        }
+    }
+
+    /* load PCI outbound free Q with MF physical addresses */
+    phyOutQFrames = pPab->outMsgBlockPhyAddr;
+
+    for (i = 0; i < NMBR_MSG_FRAMES; i++)
+    {
+        pPab->p_atu->OutQueue = phyOutQFrames;
+        phyOutQFrames += MSG_FRAME_SIZE;
+    }
+    return RC_RTN_NO_ERROR;
+}
+
+
+/*
+** =========================================================================
+** GetI2OStatus()
+**
+** Send StatusGet Msg, wait for results return directly to buffer.
+**
+** =========================================================================
+*/
+static int 
+GetI2OStatus(PPAB pPab)
+{
+    U32 msgOffset, timeout;
+    PU32 pMsg;
+    volatile PU32 p32;
+    
+    
+    msgOffset = pPab->p_atu->InQueue; 
+#ifdef DEBUG
+    printk("GetI2OStatus: msg offset = 0x%x\n", msgOffset);
+#endif /* DEBUG */
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        kprintf("GetI2OStatus(): Inbound Free Q empty!\n");
+#endif /* DEBUG */
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virual address of msg - virual already mapped to physical */    
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+    pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_EXEC_STATUS_GET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
+    pMsg[2] = 0; /* universal context */
+    pMsg[3] = 0; /* universal context */
+    pMsg[4] = 0; /* universal context */
+    pMsg[5] = 0; /* universal context */
+    /* phys address to return status - area right after PAB */
+    pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
+    pMsg[7] = 0;
+    pMsg[8] = 88;  /*  return 88 bytes */
+
+    /* virual pointer to return buffer - clear first two dwords */
+    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
+    p32[0] = 0;
+    p32[1] = 0;
+
+#ifdef DEBUG
+    kprintf("GetI2OStatus - pMsg:0x%08.8ulx, msgOffset:0x%08.8ulx, [1]:0x%08.8ulx, [6]:0x%08.8ulx\n",
+            pMsg, msgOffset, pMsg[1], pMsg[6]);
+#endif /* DEBUG */
+   
+    /* post to Inbound Post Q */   
+    pPab->p_atu->InQueue = msgOffset;
+    
+#ifdef DEBUG
+    kprintf("Return status to p32 = 0x%08.8ulx\n", p32);
+#endif /* DEBUG */
+    
+    /* wait for response */
+    timeout = 1000000;
+    while(1)
+    {
+        int i;
+        
+        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
+            ;
+            
+        if (p32[0] && p32[1])
+            break;
+            
+        if (!timeout--)
+        {
+#ifdef DEBUG
+            kprintf("Timeout waiting for status from IOP\n");
+            kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
+            kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
+            kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
+#endif /* DEBUG */
+            return RC_RTN_NO_I2O_STATUS;
+        }
+    }
+            
+#ifdef DEBUG
+    kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
+    kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
+    kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
+#endif /* DEBUG */
+    /* get IOP state */
+    pPab->IOPState = ((volatile PU8)p32)[10];
+    pPab->InboundMFrameSize  = ((volatile PU16)p32)[6];
+    
+#ifdef DEBUG
+    kprintf("IOP state 0x%02.2x InFrameSize = 0x%04.4x\n", 
+            pPab->IOPState, pPab->InboundMFrameSize);
+#endif /* DEBUG */
+    return RC_RTN_NO_ERROR;
+}
+
+
+/*
+** =========================================================================
+** SendEnableSysMsg()
+**
+**
+** =========================================================================
+*/
+static int 
+SendEnableSysMsg(PPAB pPab)
+{
+    U32 msgOffset; // timeout;
+    volatile PU32 pMsg;
+
+    msgOffset = pPab->p_atu->InQueue;
+
+    if (msgOffset == 0xFFFFFFFF)
+    {
+#ifdef DEBUG
+        kprintf("SendEnableSysMsg(): Inbound Free Q empty!\n");
+#endif /* DEBUG */
+        return RC_RTN_FREE_Q_EMPTY;
+    }
+
+    /* calc virual address of msg - virual already mapped to physical */
+    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
+
+#ifdef DEBUG
+    kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
+#endif /* DEBUG */
+
+    pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
+    pMsg[1] = I2O_EXEC_SYS_ENABLE << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
+    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
+    pMsg[3] = 0x110; /* transaction context */
+    pMsg[4] = 0x50657465; /*  RedCreek Private */
+
+    /* post to Inbound Post Q */
+    pPab->p_atu->InQueue = msgOffset;
+
+    return RC_RTN_NO_ERROR;
+}
+
+
+/*
+** =========================================================================
+** FillI2OMsgFromTCB()
+**
+** inputs   pMsgU32 - virual pointer (mapped to physical) of message frame
+**          pXmitCntrlBlock - pointer to caller buffer control block.
+**
+** fills in LAN SGL after Transaction Control Word or Bucket Count.
+** =========================================================================
+*/
+static int 
+FillI2OMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock)
+{
+    unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags;
+    PU32 pTCB, pMsg;
+
+    /* SGL element flags */   
+#define EOB        0x40000000
+#define LE         0x80000000
+#define SIMPLE_SGL 0x10000000
+#define BC_PRESENT 0x01000000
+
+    pTCB = (PU32)pTransCtrlBlock;
+    pMsg = pMsgFrame;
+    nmbrDwords = 0;
+
+#ifdef DEBUG
+    kprintf("FillI2OMsgSGLFromTCBX\n");
+    kprintf("TCB  0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
+            pTCB[0], pTCB[1], pTCB[2], pTCB[3], pTCB[4]);
+    kprintf("pTCB 0x%08.8ulx, pMsg 0x%08.8ulx\n", pTCB, pMsg);
+#endif /* DEBUG */
+    
+    nmbrBuffers = *pTCB++;
+    
+    if (!nmbrBuffers)
+    {
+        return -1;
+    }
+
+    do
+    {
+        context = *pTCB++; /* buffer tag (context) */
+        nmbrSeg = *pTCB++; /* number of segments */
+
+        if (!nmbrSeg)
+        {
+            return -1;
+        }
+        
+        flags = SIMPLE_SGL | BC_PRESENT;
+
+        if (1 == nmbrSeg)
+        {
+            flags |= EOB;
+        
+            if (1 == nmbrBuffers)
+                flags |= LE;
+        }    
+
+        /* 1st SGL buffer element has context */
+        pMsg[0] = pTCB[0] | flags ; /* send over count (segment size) */
+        pMsg[1] = context;
+        pMsg[2] = pTCB[1]; /* send buffer segment physical address */
+        nmbrDwords += 3;
+        pMsg += 3;
+        pTCB += 2;
+
+        
+        if (--nmbrSeg)
+        {
+            do
+            {
+                flags = SIMPLE_SGL;
+                
+                if (1 == nmbrSeg)
+                {
+                    flags |= EOB;
+                
+                    if (1 == nmbrBuffers)
+                        flags |= LE;
+                }    
+                
+                pMsg[0] = pTCB[0] | flags;  /* send over count */
+                pMsg[1] = pTCB[1];   /* send buffer segment physical address */
+                nmbrDwords += 2;
+                pTCB += 2;
+                pMsg += 2;
+        
+            } while (--nmbrSeg);
+        }
+        
+    } while (--nmbrBuffers);
+    
+    return nmbrDwords;
+}
+
+
+/*
+** =========================================================================
+** ProcessOutboundI2OMsg()
+**
+** process I2O reply message
+** * change to msg structure *
+** =========================================================================
+*/
+static void 
+ProcessOutboundI2OMsg(PPAB pPab, U32 phyAddrMsg)
+{
+    PU8 p8Msg;
+    PU32 p32;
+    //  U16 count;
+    
+    
+    p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
+    p32 = (PU32)p8Msg;
+    
+#ifdef DEBUG
+    kprintf("VXD: ProcessOutboundI2OMsg - pPab 0x%08.8ulx, phyAdr 0x%08.8ulx, linAdr 0x%08.8ulx\n", pPab, phyAddrMsg, p8Msg);
+    kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
+    kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
+#endif /* DEBUG */
+
+    if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS)
+    {
+#ifdef DEBUG
+        kprintf("Message reply status not success\n");
+#endif /* DEBUG */
+        return;
+    }
+    
+    switch (p8Msg[7] )  /* function code byte */
+    {
+    case I2O_EXEC_SYS_TAB_SET:
+        msgFlag = 1;
+#ifdef DEBUG
+        kprintf("Received I2O_EXEC_SYS_TAB_SET reply\n");
+#endif /* DEBUG */
+        break;
+
+    case I2O_EXEC_HRT_GET:
+        msgFlag = 1;
+#ifdef DEBUG
+        kprintf("Received I2O_EXEC_HRT_GET reply\n");
+#endif /* DEBUG */
+        break;
+        
+    case I2O_EXEC_LCT_NOTIFY:
+        msgFlag = 1;
+#ifdef DEBUG
+        kprintf("Received I2O_EXEC_LCT_NOTIFY reply\n");
+#endif /* DEBUG */
+        break;
+        
+    case I2O_EXEC_SYS_ENABLE:
+        msgFlag = 1;
+#ifdef DEBUG
+        kprintf("Received I2O_EXEC_SYS_ENABLE reply\n");
+#endif /* DEBUG */
+        break;
+
+    default:    
+#ifdef DEBUG
+        kprintf("Received UNKNOWN reply\n");
+#endif /* DEBUG */
+        break;
+    }
+}
diff --git a/drivers/net/rclanmtl.h b/drivers/net/rclanmtl.h
new file mode 100644 (file)
index 0000000..2521b1c
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+** *************************************************************************
+**
+**
+**     R C L A N M T L . H             $Revision: 5 $
+**
+**
+**  RedCreek I2O LAN Message Transport Layer header file.
+**
+**  ---------------------------------------------------------------------
+**  ---     Copyright (c) 1997-1999, RedCreek Communications Inc.     ---
+**  ---                   All rights reserved.                        ---
+**  ---------------------------------------------------------------------
+**
+**  File Description:
+**
+**  Header file for host I2O (Intelligent I/O) LAN message transport layer 
+**  API and data types.
+**
+**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** *************************************************************************
+*/
+
+#ifndef RCLANMTL_H
+#define RCLANMTL_H
+
+/* Linux specific includes */
+#define kprintf printk
+#ifdef RC_LINUX_MODULE     /* linux modules need non-library version of string functions */
+#include <linux/string.h>
+#else
+#include <string.h>
+#endif
+
+/* PCI/45 Configuration space values */
+#define RC_PCI45_VENDOR_ID  0x4916
+#define RC_PCI45_DEVICE_ID  0x1960
+
+
+ /* RedCreek API function return values */
+#define RC_RTN_NO_ERROR             0
+#define RC_RTN_I2O_NOT_INIT         1
+#define RC_RTN_FREE_Q_EMPTY         2
+#define RC_RTN_TCB_ERROR            3
+#define RC_RTN_TRANSACTION_ERROR    4
+#define RC_RTN_ADAPTER_ALREADY_INIT 5
+#define RC_RTN_MALLOC_ERROR         6
+#define RC_RTN_ADPTR_NOT_REGISTERED 7
+#define RC_RTN_MSG_REPLY_TIMEOUT    8
+#define RC_RTN_NO_I2O_STATUS        9
+#define RC_RTN_NO_FIRM_VER         10
+#define RC_RTN_NO_LINK_SPEED       11
+
+/* Driver capability flags */
+#define WARM_REBOOT_CAPABLE      0x01
+
+ /* scalar data types */
+typedef unsigned char   U8;
+typedef unsigned char*  PU8;
+typedef unsigned short  U16;
+typedef unsigned short* PU16;
+typedef unsigned long   U32;
+typedef unsigned long*  PU32;
+typedef unsigned long   BF;
+typedef int             RC_RETURN;
+
+
+ /* 
+ ** type PFNWAITCALLBACK
+ **
+ ** pointer to void function - type used for WaitCallback in some functions 
+ */
+typedef void (*PFNWAITCALLBACK)(void);  /* void argument avoids compiler complaint */
+
+ /*
+ ** type PFNTXCALLBACK 
+ **
+ ** Pointer to user's transmit callback function.  This user function is
+ ** called from RCProcI2OMsgQ() when packet have been transmitted from buffers
+ ** given in the RCI2OSendPacket() function.  BufferContext is a pointer to
+ ** an array of 32 bit context values.  These are the values the user assigned
+ ** and passed in the TCB to the RCI2OSendPacket() function.  PcktCount
+ ** indicates the number of buffer context values in the BufferContext[] array.
+ ** The User's TransmitCallbackFunction should recover (put back in free queue)
+ ** the packet buffers associated with the buffer context values.
+ */
+typedef void (*PFNTXCALLBACK)(U32  Status,
+                              U16  PcktCount,
+                              PU32 BufferContext,
+                              U16  AdaterID);
+
+ /* 
+ ** type PFNRXCALLBACK 
+ **
+ ** Pointer to user's receive callback function.  This user function
+ ** is called from RCProcI2OMsgQ() when packets have been received into
+ ** previously posted packet buffers throught the RCPostRecvBuffers() function.
+ ** The received callback function should process the Packet Descriptor Block
+ ** pointed to by PacketDescBlock. See Packet Decription Block below.
+ */
+typedef void (*PFNRXCALLBACK)(U32  Status,
+                              U8   PktCount,
+                              U32  BucketsRemain,
+                              PU32 PacketDescBlock,
+                              U16  AdapterID);
+
+ /* 
+ ** type PFNCALLBACK 
+ **
+ ** Pointer to user's generic callback function.  This user function
+ ** can be passed to LANReset or LANShutdown and is called when the 
+ ** the reset or shutdown is complete.
+ ** Param1 and Param2 are invalid for LANReset and LANShutdown.
+ */
+typedef void (*PFNCALLBACK)(U32  Status,
+                              U32  Param1,
+                              U32  Param2,
+                              U16  AdapterID);
+
+/*
+** Status - Transmit and Receive callback status word 
+**
+** A 32 bit Status is returned to the TX and RX callback functions.  This value
+** contains both the reply status and the detailed status as follows:
+**
+**  32    24     16            0
+**  +------+------+------------+
+**  | Reply|      |  Detailed  |
+**  |Status|   0  |   Status   |
+**  +------+------+------------+
+**
+** Reply Status and Detailed Status of zero indicates No Errors.
+*/
+ /* reply message status defines */
+#define    I2O_REPLY_STATUS_SUCCESS                    0x00
+#define    I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     0x02
+#define    I2O_REPLY_STATUS_TRANSACTION_ERROR          0x0A
+
+
+/* DetailedStatusCode defines */
+#define    I2O_LAN_DSC_SUCCESS                         0x0000
+#define    I2O_LAN_DSC_DEVICE_FAILURE                  0x0001
+#define    I2O_LAN_DSC_DESTINATION_NOT_FOUND           0x0002
+#define    I2O_LAN_DSC_TRANSMIT_ERROR                  0x0003
+#define    I2O_LAN_DSC_TRANSMIT_ABORTED                0x0004
+#define    I2O_LAN_DSC_RECEIVE_ERROR                   0x0005
+#define    I2O_LAN_DSC_RECEIVE_ABORTED                 0x0006
+#define    I2O_LAN_DSC_DMA_ERROR                       0x0007
+#define    I2O_LAN_DSC_BAD_PACKET_DETECTED             0x0008
+#define    I2O_LAN_DSC_OUT_OF_MEMORY                   0x0009
+#define    I2O_LAN_DSC_BUCKET_OVERRUN                  0x000A
+#define    I2O_LAN_DSC_IOP_INTERNAL_ERROR              0x000B
+#define    I2O_LAN_DSC_CANCELED                        0x000C
+#define    I2O_LAN_DSC_INVALID_TRANSACTION_CONTEXT     0x000D
+#define    I2O_LAN_DSC_DESTINATION_ADDRESS_DETECTED    0x000E
+#define    I2O_LAN_DSC_DESTINATION_ADDRESS_OMITTED     0x000F
+#define    I2O_LAN_DSC_PARTIAL_PACKET_RETURNED         0x0010
+
+
+/*
+** Packet Description Block   (Received packets)
+**
+** A pointer to this block structure is returned to the ReceiveCallback 
+** function.  It contains the list of packet buffers which have either been
+** filled with a packet or returned to host due to a LANReset function. 
+** Currently there will only be one packet per receive bucket (buffer) posted. 
+**
+**   32   24               0     
+**  +-----------------------+  -\
+**  |   Buffer 1 Context    |    \
+**  +-----------------------+     \
+**  |      0xC0000000       |     / First Bucket Descriptor
+**  +-----+-----------------+    /
+**  |  0  | packet 1 length |   / 
+**  +-----------------------+  -\
+**  |   Buffer 2 Context    |    \
+**  +-----------------------+     \
+**  |      0xC0000000       |     / Second Bucket Descriptor
+**  +-----+-----------------+    /
+**  |  0  | packet 2 length |   / 
+**  +-----+-----------------+  -
+**  |         ...           |  ----- more bucket descriptors
+**  +-----------------------+  -\
+**  |   Buffer n Context    |    \
+**  +-----------------------+     \
+**  |      0xC0000000       |     / Last Bucket Descriptor
+**  +-----+-----------------+    /
+**  |  0  | packet n length |   / 
+**  +-----+-----------------+  -
+**
+** Buffer Context values are those given to adapter in the TCB on calls to
+** RCPostRecvBuffers().
+**  
+*/
+
+
+
+/*
+** Transaction Control Block (TCB) structure
+**
+** A structure like this is filled in by the user and passed by reference to 
+** RCI2OSendPacket() and RCPostRecvBuffers() functions.  Minimum size is five
+** 32-bit words for one buffer with one segment descriptor.  
+** MAX_NMBR_POST_BUFFERS_PER_MSG defines the maximum single segment buffers
+** that can be described in a given TCB.
+**
+**   32                    0
+**  +-----------------------+
+**  |   Buffer Count        |  Number of buffers in the TCB
+**  +-----------------------+
+**  |   Buffer 1 Context    |  first buffer reference
+**  +-----------------------+
+**  |   Buffer 1 Seg Count  |  number of segments in buffer
+**  +-----------------------+
+**  |   Buffer 1 Seg Desc 1 |  first segment descriptor (size, physical address)
+**  +-----------------------+
+**  |         ...           |  more segment descriptors (size, physical address)
+**  +-----------------------+
+**  |   Buffer 1 Seg Desc n |  last segment descriptor (size, physical address)
+**  +-----------------------+
+**  |   Buffer 2 Context    |  second buffer reference
+**  +-----------------------+
+**  |   Buffer 2 Seg Count  |  number of segments in buffer
+**  +-----------------------+
+**  |   Buffer 2 Seg Desc 1 |  segment descriptor (size, physical address)
+**  +-----------------------+
+**  |         ...           |  more segment descriptors (size, physical address)
+**  +-----------------------+
+**  |   Buffer 2 Seg Desc n |
+**  +-----------------------+
+**  |         ...           |  more buffer descriptor blocks ...
+**  +-----------------------+
+**  |   Buffer n Context    |
+**  +-----------------------+
+**  |   Buffer n Seg Count  |
+**  +-----------------------+
+**  |   Buffer n Seg Desc 1 |
+**  +-----------------------+
+**  |         ...           |
+**  +-----------------------+
+**  |   Buffer n Seg Desc n |
+**  +-----------------------+
+**
+**
+** A TCB for one contigous packet buffer would look like the following:
+**
+**   32                    0
+**  +-----------------------+
+**  |         1             |  one buffer in the TCB
+**  +-----------------------+
+**  |  <user's Context>     |  user's buffer reference
+**  +-----------------------+
+**  |         1             |  one segment buffer
+**  +-----------------------+                            _
+**  |    <buffer size>      |  size                       \ 
+**  +-----------------------+                              \ segment descriptor
+**  |  <physical address>   |  physical address of buffer  /
+**  +-----------------------+                            _/
+**
+*/
+
+ /* Buffer Segment Descriptor */
+typedef struct
+{
+    U32 size;
+    U32 phyAddress;
+}
+ BSD, *PBSD;
+typedef PU32 PRCTCB;
+/*
+** -------------------------------------------------------------------------
+** Exported functions comprising the API to the LAN I2O message transport layer
+** -------------------------------------------------------------------------
+*/
+
+
+ /*
+ ** InitRCI2OMsgLayer()
+ ** 
+ ** Called once prior to using the I2O LAN message transport layer.  User 
+ ** provides both the physical and virual address of a locked page buffer 
+ ** that is used as a private buffer for the RedCreek I2O message
+ ** transport layer.  This buffer must be a contigous memory block of a 
+ ** minimum of 16K bytes and long word aligned.  The user also must provide
+ ** the base address of the RedCreek PCI adapter assigned by BIOS or operating
+ ** system.  The user provided value AdapterID is a zero based index of the
+ ** Ravlin 45/PCI adapter.  This interface number is used in all subsequent API
+ ** calls to identify which adpapter for which the function is intended.  
+ ** Up to sixteen interfaces are supported with this API.
+ **
+ ** Inputs:  AdapterID - interface number from 0 to 15
+ **          pciBaseAddr - virual base address of PCI (set by BIOS)
+ **          p_msgbuf - virual address to private message block (min. 16K)
+ **          p_phymsgbuf - physical address of private message block
+ **          TransmitCallbackFunction - address of user's TX callback function
+ **          ReceiveCallbackFunction  - address of user's RX callback function
+ **
+ */
+RC_RETURN RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr, 
+                            PU8 p_msgbuf,  PU8 p_phymsgbuf,
+                            PFNTXCALLBACK TransmitCallbackFunction,
+                            PFNRXCALLBACK ReceiveCallbackFunction,
+                            PFNCALLBACK   RebootCallbackFunction);
+
+ /*
+ ** RCSetRavlinIPandMask()
+ **
+ ** Set the Ravlin 45/PCI cards IP address and network mask.
+ **
+ ** IP address and mask must be in network byte order.
+ ** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
+ ** 0x04030201 and 0x00FFFFFF on a little endian machine.
+ **
+ */
+RC_RETURN RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask);
+
+
+/*
+** =========================================================================
+** RCGetRavlinIPandMask()
+**
+** get the IP address and MASK from the card
+** 
+** =========================================================================
+*/
+RC_RETURN
+RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, 
+                        PFNWAITCALLBACK WaitCallback);
+
+ /* 
+ ** RCProcI2OMsgQ()
+ ** 
+ ** Called from user's polling loop or Interrupt Service Routine for a PCI 
+ ** interrupt from the RedCreek PCI adapter.  User responsible for determining
+ ** and hooking the PCI interrupt. This function will call the registered
+ ** callback functions, TransmitCallbackFunction or ReceiveCallbackFunction,
+ ** if a TX or RX transaction has completed.
+ */
+void RCProcI2OMsgQ(U16 AdapterID);
+
+
+ /*
+ ** Disable and Enable I2O interrupts.  I2O interrupts are enabled at Init time
+ ** but can be disabled and re-enabled through these two function calls.
+ ** Packets will still be put into any posted recieved buffers and packets will
+ ** be sent through RCI2OSendPacket() functions.  Disabling I2O interrupts
+ ** will prevent hardware interrupt to host even though the outbound I2O msg
+ ** queue is not emtpy.
+ */
+RC_RETURN RCEnableI2OInterrupts(U16 adapterID);
+RC_RETURN RCDisableI2OInterrupts(U16 AdapterID);
+
+
+ /* 
+ ** RCPostRecvBuffers()
+ ** 
+ ** Post user's page locked buffers for use by the PCI adapter to
+ ** return ethernet packets received from the LAN.  Transaction Control Block,
+ ** provided by user, contains buffer descriptor(s) which includes a buffer
+ ** context number along with buffer size and physical address.  See TCB above.
+ ** The buffer context and actual packet length are returned to the 
+ ** ReceiveCallbackFunction when packets have been received.  Buffers posted
+ ** to the RedCreek adapter are considered owned by the adapter until the
+ ** context is return to user through the ReceiveCallbackFunction.
+ */
+RC_RETURN RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransactionCtrlBlock);
+#define MAX_NMBR_POST_BUFFERS_PER_MSG 32
+
+ /*
+ ** RCI2OSendPacket()
+ ** 
+ ** Send user's ethernet packet from a locked page buffer.  
+ ** Packet must have full MAC header, however without a CRC.  
+ ** Initiator context is a user provided value that is returned 
+ ** to the TransmitCallbackFunction when packet buffer is free.
+ ** Transmit buffer are considered owned by the adapter until context's
+ ** returned to user through the TransmitCallbackFunction.
+ */
+RC_RETURN RCI2OSendPacket(U16 AdapterID, 
+                          U32 context, 
+                          PRCTCB pTransactionCtrlBlock);
+
+
+ /* Ethernet Link Statistics structure */
+typedef struct tag_RC_link_stats
+{
+    U32 TX_good;      /* good transmit frames */
+    U32 TX_maxcol;    /* frames not TX due to MAX collisions */
+    U32 TX_latecol;   /* frames not TX due to late collisions */
+    U32 TX_urun;      /* frames not TX due to DMA underrun */
+    U32 TX_crs;       /* frames TX with lost carrier sense */
+    U32 TX_def;       /* frames deferred due to activity on link */
+    U32 TX_singlecol; /* frames TX with one and only on collision */
+    U32 TX_multcol;   /* frames TX with more than one collision */
+    U32 TX_totcol;    /* total collisions detected during TX */
+    U32 Rcv_good;     /* good frames received */
+    U32 Rcv_CRCerr;   /* frames RX and discarded with CRC errors */
+    U32 Rcv_alignerr; /* frames RX with alignment and CRC errors */
+    U32 Rcv_reserr;   /* good frames discarded due to no RX buffer */
+    U32 Rcv_orun;     /* RX frames lost due to FIFO overrun */
+    U32 Rcv_cdt;      /* RX frames with collision during RX */
+    U32 Rcv_runt;     /* RX frames shorter than 64 bytes */
+}
+ RCLINKSTATS, *P_RCLINKSTATS;
+
+ /*
+ ** RCGetLinkStatistics()
+ **
+ ** Returns link statistics in user's structure at address StatsReturnAddr
+ ** If given, not NULL, the function WaitCallback is called during the wait
+ ** loop while waiting for the adapter to respond.
+ */
+RC_RETURN RCGetLinkStatistics(U16 AdapterID,
+                              P_RCLINKSTATS StatsReturnAddr,
+                              PFNWAITCALLBACK WaitCallback);
+
+ /*
+ ** RCGetLinkStatus()
+ **
+ ** Return link status, up or down, to user's location addressed by ReturnAddr.
+ ** If given, not NULL, the function WaitCallback is called during the wait
+ ** loop while waiting for the adapter to respond.
+ */
+RC_RETURN RCGetLinkStatus(U16 AdapterID, 
+                          PU32 pReturnStatus,
+                          PFNWAITCALLBACK WaitCallback);
+                               
+ /* Link Status defines - value returned in pReturnStatus */
+#define RC_LAN_LINK_STATUS_DOWN     0
+#define RC_LAN_LINK_STATUS_UP       1
+
+ /*
+ ** RCGetMAC()
+ **
+ ** Get the current MAC address assigned to user.  RedCreek Ravlin 45/PCI 
+ ** has two MAC addresses.  One which is private to the PCI Card, and 
+ ** another MAC which is given to the user as its link layer MAC address. The
+ ** adapter runs in promiscous mode because of the dual address requirement.
+ ** The MAC address is returned to the unsigned char array pointer to by mac.
+ */
+RC_RETURN RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback);
+
+ /*
+ ** RCSetMAC()
+ **
+ ** Set a new user port MAC address.  This address will be returned on
+ ** subsequent RCGetMAC() calls.
+ */
+RC_RETURN RCSetMAC(U16 AdapterID, PU8 mac);
+
+ /*
+ ** RCSetLinkSpeed()
+ **
+ ** set adapter's link speed based on given input code.
+ */
+RC_RETURN RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode);
+ /* Set link speed codes */
+#define LNK_SPD_AUTO_NEG_NWAY   0
+#define LNK_SPD_100MB_FULL      1
+#define LNK_SPD_100MB_HALF      2
+#define LNK_SPD_10MB_FULL       3
+#define LNK_SPD_10MB_HALF       4
+
+
+
+
+ /*
+ ** RCGetLinkSpeed()
+ **
+ ** Return link speed code.
+ */
+ /* Return link speed codes */
+#define LNK_SPD_UNKNOWN         0
+#define LNK_SPD_100MB_FULL      1
+#define LNK_SPD_100MB_HALF      2
+#define LNK_SPD_10MB_FULL       3
+#define LNK_SPD_10MB_HALF       4
+
+RC_RETURN
+RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback);
+/*
+** =========================================================================
+** RCSetPromiscuousMode(U16 AdapterID, U16 Mode)
+**
+** Defined values for Mode:
+**  0 - turn off promiscuous mode
+**  1 - turn on  promiscuous mode
+**
+** =========================================================================
+*/
+#define PROMISCUOUS_MODE_OFF 0
+#define PROMISCUOUS_MODE_ON  1
+RC_RETURN
+RCSetPromiscuousMode(U16 AdapterID, U16 Mode);
+/*
+** =========================================================================
+** RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+**
+** get promiscuous mode setting
+**
+** Possible return values placed in pMode:
+**  0 = promisuous mode not set
+**  1 = promisuous mode is set
+**
+** =========================================================================
+*/
+RC_RETURN
+RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback);
+
+/*
+** =========================================================================
+** RCSetBroadcastMode(U16 AdapterID, U16 Mode)
+**
+** Defined values for Mode:
+**  0 - turn off promiscuous mode
+**  1 - turn on  promiscuous mode
+**
+** =========================================================================
+*/
+#define BROADCAST_MODE_OFF 0
+#define BROADCAST_MODE_ON  1
+RC_RETURN
+RCSetBroadcastMode(U16 AdapterID, U16 Mode);
+/*
+** =========================================================================
+** RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
+**
+** get broadcast mode setting
+**
+** Possible return values placed in pMode:
+**  0 = broadcast mode not set
+**  1 = broadcast mode is set
+**
+** =========================================================================
+*/
+RC_RETURN
+RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback);
+/*
+** =========================================================================
+** RCReportDriverCapability(U16 AdapterID, U32 capability)
+**
+** Currently defined bits:
+** WARM_REBOOT_CAPABLE   0x01
+**
+** =========================================================================
+*/
+RC_RETURN
+RCReportDriverCapability(U16 AdapterID, U32 capability);
+
+/*
+** RCGetFirmwareVer()
+**
+** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
+**
+** WARNING: user's space pointed to by pFirmString should be at least 60 bytes.
+*/
+RC_RETURN
+RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback);
+
+/*
+** ----------------------------------------------
+** LAN adapter Reset and Shutdown functions
+** ----------------------------------------------
+*/
+ /* resource flag bit assignments for RCResetLANCard() & RCShutdownLANCard() */
+#define RC_RESOURCE_RETURN_POSTED_RX_BUCKETS  0x0001 
+#define RC_RESOURCE_RETURN_PEND_TX_BUFFERS    0x0002
+
+ /*
+ ** RCResetLANCard()
+ **
+ ** Reset LAN card operation.  Causes a software reset of the ethernet
+ ** controller and restarts the command and receive units. Depending on 
+ ** the ResourceFlags given, the buffers are either returned to the
+ ** host with reply status of I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER and
+ ** detailed status of I2O_LAN_DSC_CANCELED (new receive buffers must be
+ ** posted after issuing this) OR the buffers are kept and reused by
+ ** the ethernet controller. If CallbackFunction is not NULL, the function
+ ** will be called when the reset is complete.  If the CallbackFunction is
+ ** NULL,a 1 will be put into the ReturnAddr after waiting for the reset 
+ ** to complete (please disable I2O interrupts during this method).
+ ** Any outstanding transmit or receive buffers that are complete will be
+ ** returned via the normal reply messages before the requested resource
+ ** buffers are returned.
+ ** A call to RCPostRecvBuffers() is needed to return the ethernet to full
+ ** operation if the receive buffers were returned during LANReset.
+ ** Note: The IOP status is not affected by a LAN reset.
+ */
+RC_RETURN RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
+
+
+ /*
+ ** RCShutdownLANCard()
+ **
+ ** Shutdown LAN card operation and put into an idle (suspended) state.
+ ** The LAN card is restarted with RCResetLANCard() function.
+ ** Depending on the ResourceFlags given, the buffers are either returned 
+ ** to the host with reply status of I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 
+ ** and detailed status of I2O_LAN_DSC_CANCELED (new receive buffers must be
+ ** posted after issuing this) OR the buffers are kept and reused by
+ ** the ethernet controller. If CallbackFunction is not NULL, the function
+ ** will be called when the reset is complete.  If the CallbackFunction is
+ ** NULL,a 1 will be put into the ReturnAddr after waiting for the reset 
+ ** to complete (please disable I2O interrupts during this method).
+ ** Any outstanding transmit or receive buffers that are complete will be
+ ** returned via the normal reply messages before the requested resource
+ ** buffers are returned.
+ ** Note: The IOP status is not affected by a LAN shutdown.
+ */                                      
+RC_RETURN 
+RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
+
+ /*
+ ** RCResetIOP();
+ **     Initializes IOPState to I2O_IOP_STATE_RESET.
+ **     Stops access to outbound message Q.
+ **     Discards any outstanding transmit or posted receive buffers.
+ **     Clears outbound message Q. 
+ */
+RC_RETURN 
+RCResetIOP(U16 AdapterID);
+
+#endif /* RCLANMTL_H */
diff --git a/drivers/net/rcmtl.c b/drivers/net/rcmtl.c
deleted file mode 100644 (file)
index db1509a..0000000
+++ /dev/null
@@ -1,2058 +0,0 @@
-/*
-** *************************************************************************
-**
-**
-**     R C M T L . C             $Revision: 1.1 $
-**
-**
-**  RedCreek Message Transport Layer program module.
-**
-**  ---------------------------------------------------------------------
-**  ---     Copyright (c) 1997-1998, RedCreek Communications Inc.     ---
-**  ---                   All rights reserved.                        ---
-**  ---------------------------------------------------------------------
-**
-** File Description:
-**
-** Host side message transport layer.
-**
-**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-***************************************************************************/
-
-#undef DEBUG
-
-#define RC_LINUX_MODULE
-#include "rcmtl.h"
-
-#define dprintf kprintf
-
-extern int printk(const char * fmt, ...);
-
- /* RedCreek LAN device Target ID */
-#define LAN_TARGET_ID  0x10 
- /* RedCreek's OSM default LAN receive Initiator */
-#define DEFAULT_RECV_INIT_CONTEXT  0xA17  
-
-
-/*
-** message structures
-*/
-
-#define    TID_SZ                                  12
-#define    FUNCTION_SZ                             8
-
-/* Transaction Reply Lists (TRL) Control Word structure */
-
-#define    TRL_SINGLE_FIXED_LENGTH           0x00
-#define    TRL_SINGLE_VARIABLE_LENGTH        0x40
-#define    TRL_MULTIPLE_FIXED_LENGTH         0x80
-
-/* LAN Class specific functions */
-
-#define    LAN_PACKET_SEND                         0x3B
-#define    LAN_SDU_SEND                            0x3D
-#define    LAN_RECEIVE_POST                        0x3E
-#define    LAN_RESET                               0x35
-#define    LAN_SHUTDOWN                            0x37
-
-/* Private Class specfic function */
-#define    RC_PRIVATE                                 0xFF
-
-/*  RC Executive Function Codes.  */
-
-#define    RC_CMD_ADAPTER_ASSIGN                     0xB3
-#define    RC_CMD_ADAPTER_READ                       0xB2
-#define    RC_CMD_ADAPTER_RELEASE                    0xB5
-#define    RC_CMD_BIOS_INFO_SET                      0xA5
-#define    RC_CMD_BOOT_DEVICE_SET                    0xA7
-#define    RC_CMD_CONFIG_VALIDATE                    0xBB
-#define    RC_CMD_CONN_SETUP                         0xCA
-#define    RC_CMD_DEVICE_ASSIGN                      0xB7
-#define    RC_CMD_DEVICE_RELEASE                     0xB9
-#define    RC_CMD_HRT_GET                            0xA8
-#define    RC_CMD_ADAPTER_CLEAR                          0xBE
-#define    RC_CMD_ADAPTER_CONNECT                        0xC9
-#define    RC_CMD_ADAPTER_RESET                          0xBD
-#define    RC_CMD_LCT_NOTIFY                         0xA2
-#define    RC_CMD_OUTBOUND_INIT                      0xA1
-#define    RC_CMD_PATH_ENABLE                        0xD3
-#define    RC_CMD_PATH_QUIESCE                       0xC5
-#define    RC_CMD_PATH_RESET                         0xD7
-#define    RC_CMD_STATIC_MF_CREATE                   0xDD
-#define    RC_CMD_STATIC_MF_RELEASE                  0xDF
-#define    RC_CMD_STATUS_GET                         0xA0
-#define    RC_CMD_SW_DOWNLOAD                        0xA9
-#define    RC_CMD_SW_UPLOAD                          0xAB
-#define    RC_CMD_SW_REMOVE                          0xAD
-#define    RC_CMD_SYS_ENABLE                         0xD1
-#define    RC_CMD_SYS_MODIFY                         0xC1
-#define    RC_CMD_SYS_QUIESCE                        0xC3
-#define    RC_CMD_SYS_TAB_SET                        0xA3
-
-
- /* Init Outbound Q status */
-#define    RC_CMD_OUTBOUND_INIT_IN_PROGRESS          0x01
-#define    RC_CMD_OUTBOUND_INIT_REJECTED             0x02
-#define    RC_CMD_OUTBOUND_INIT_FAILED               0x03
-#define    RC_CMD_OUTBOUND_INIT_COMPLETE             0x04
-
-
-#define    UTIL_NOP                                0x00
-
-
-/* RC Get Status State values */
-
-#define    ADAPTER_STATE_INITIALIZING                  0x01
-#define    ADAPTER_STATE_RESET                         0x02
-#define    ADAPTER_STATE_HOLD                          0x04
-#define    ADAPTER_STATE_READY                         0x05
-#define    ADAPTER_STATE_OPERATIONAL                   0x08
-#define    ADAPTER_STATE_FAILED                        0x10
-#define    ADAPTER_STATE_FAULTED                       0x11
-
-
-/* Defines for Request Status Codes:  Table 3-1 Reply Status Codes.  */
-
-#define    RC_REPLY_STATUS_SUCCESS                    0x00
-#define    RC_REPLY_STATUS_ABORT_DIRTY                0x01
-#define    RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     0x02
-#define    RC_REPLY_STATUS_ABORT_PARTIAL_TRANSFER     0x03
-#define    RC_REPLY_STATUS_ERROR_DIRTY                0x04
-#define    RC_REPLY_STATUS_ERROR_NO_DATA_TRANSFER     0x05
-#define    RC_REPLY_STATUS_ERROR_PARTIAL_TRANSFER     0x06
-#define    RC_REPLY_STATUS_PROCESS_ABORT_DIRTY        0x07
-#define    RC_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER   0x08
-#define    RC_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER   0x09
-#define    RC_REPLY_STATUS_TRANSACTION_ERROR          0x0A
-#define    RC_REPLY_STATUS_PROGRESS_REPORT            0x80
-
-
-/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/
-
-#define    RC_DS_SUCCESS                        0x0000
-#define    RC_DS_BAD_KEY                        0x0001
-#define    RC_DS_CHAIN_BUFFER_TOO_LARGE         0x0002
-#define    RC_DS_DEVICE_BUSY                    0x0003
-#define    RC_DS_DEVICE_LOCKED                  0x0004
-#define    RC_DS_DEVICE_NOT_AVAILABLE           0x0005
-#define    RC_DS_DEVICE_RESET                   0x0006
-#define    RC_DS_INAPPROPRIATE_FUNCTION         0x0007
-#define    RC_DS_INSUFFICIENT_RESOURCE_HARD     0x0008
-#define    RC_DS_INSUFFICIENT_RESOURCE_SOFT     0x0009
-#define    RC_DS_INVALID_INITIATOR_ADDRESS      0x000A
-#define    RC_DS_INVALID_MESSAGE_FLAGS          0x000B
-#define    RC_DS_INVALID_OFFSET                 0x000C
-#define    RC_DS_INVALID_PARAMETER              0x000D
-#define    RC_DS_INVALID_REQUEST                0x000E
-#define    RC_DS_INVALID_TARGET_ADDRESS         0x000F
-#define    RC_DS_MESSAGE_TOO_LARGE              0x0010
-#define    RC_DS_MESSAGE_TOO_SMALL              0x0011
-#define    RC_DS_MISSING_PARAMETER              0x0012
-#define    RC_DS_NO_SUCH_PAGE                   0x0013
-#define    RC_DS_REPLY_BUFFER_FULL              0x0014
-#define    RC_DS_TCL_ERROR                      0x0015
-#define    RC_DS_TIMEOUT                        0x0016
-#define    RC_DS_UNKNOWN_ERROR                  0x0017
-#define    RC_DS_UNKNOWN_FUNCTION               0x0018
-#define    RC_DS_UNSUPPORTED_FUNCTION           0x0019
-#define    RC_DS_UNSUPPORTED_VERSION            0x001A
-
- /* msg header defines for VersionOffset */
-#define RCMSGVER_1   0x0001
-#define SGL_OFFSET_0    RCMSGVER_1
-#define SGL_OFFSET_4    (0x0040 | RCMSGVER_1)
-#define TRL_OFFSET_5    (0x0050 | RCMSGVER_1)
-#define TRL_OFFSET_6    (0x0060 | RCMSGVER_1)
-
- /* msg header defines for MsgFlags */
-#define MSG_STATIC      0x0100
-#define MSG_64BIT_CNTXT 0x0200
-#define MSG_MULTI_TRANS 0x1000
-#define MSG_FAIL        0x2000
-#define MSG_LAST        0x4000
-#define MSG_REPLY       0x8000
-
-  /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
-#define LAN_MSG_REQST  (MSG_MULTI_TRANS | SGL_OFFSET_4)
-
- /* minimum size msg */
-#define THREE_WORD_MSG_SIZE 0x00030000
-#define FOUR_WORD_MSG_SIZE  0x00040000
-#define FIVE_WORD_MSG_SIZE  0x00050000
-#define SIX_WORD_MSG_SIZE   0x00060000
-#define SEVEN_WORD_MSG_SIZE 0x00070000
-#define EIGHT_WORD_MSG_SIZE 0x00080000
-#define NINE_WORD_MSG_SIZE  0x00090000
-
-/* Special TID Assignments */
-
-#define ADAPTER_TID   0
-#define HOST_TID  1
-
- /* RedCreek private message codes */
-#define RC_PRIVATE_GET_MAC_ADDR     0x0001/**/ /* OBSOLETE */
-#define RC_PRIVATE_SET_MAC_ADDR     0x0002
-#define RC_PRIVATE_GET_LAN_STATS    0x0003
-#define RC_PRIVATE_GET_LINK_STATUS  0x0004
-#define RC_PRIVATE_SET_LINK_SPEED   0x0005
-#define RC_PRIVATE_SET_IP_AND_MASK  0x0006
-/* #define RC_PRIVATE_GET_IP_AND_MASK  0x0007 */ /* OBSOLETE */
-#define RC_PRIVATE_GET_LINK_SPEED   0x0008
-#define RC_PRIVATE_GET_FIRMWARE_REV 0x0009
-/* #define RC_PRIVATE_GET_MAC_ADDR     0x000A *//**/
-#define RC_PRIVATE_GET_IP_AND_MASK  0x000B /**/
-#define RC_PRIVATE_DEBUG_MSG        0x000C
-#define RC_PRIVATE_REPORT_DRIVER_CAPABILITY  0x000D
-
-#define RC_PRIVATE_REBOOT           0x00FF
-
-
-/* RC message header */
-typedef struct _RC_MSG_FRAME 
-{
-   U8                          VersionOffset;
-   U8                          MsgFlags;
-   U16                         MessageSize;
-   BF                          TargetAddress:TID_SZ;
-   BF                          InitiatorAddress:TID_SZ;
-   BF                          Function:FUNCTION_SZ;
-   U32                         InitiatorContext;
-   /* SGL[] */ 
-}
- RC_MSG_FRAME, *PRC_MSG_FRAME;
-
-
- /* assumed a 16K minus 256 byte space for outbound queue message frames */
-#define MSG_FRAME_SIZE  512
-#define NMBR_MSG_FRAMES 30
-
-/*
-**  Message Unit CSR definitions for RedCreek PCI45 board
-*/
-typedef struct tag_rcatu 
-{
-    volatile unsigned long APICRegSel;  /* APIC Register Select */
-    volatile unsigned long reserved0;
-    volatile unsigned long APICWinReg;  /* APIC Window Register */
-    volatile unsigned long reserved1;
-    volatile unsigned long InMsgReg0;   /* inbound message register 0 */
-    volatile unsigned long InMsgReg1;   /* inbound message register 1 */
-    volatile unsigned long OutMsgReg0;  /* outbound message register 0 */
-    volatile unsigned long OutMsgReg1;  /* outbound message register 1 */
-    volatile unsigned long InDoorReg;   /* inbound doorbell register */
-    volatile unsigned long InIntStat;   /* inbound interrupt status register */
-    volatile unsigned long InIntMask;   /* inbound interrupt mask register */
-    volatile unsigned long OutDoorReg;  /* outbound doorbell register */
-    volatile unsigned long OutIntStat;  /* outbound interrupt status register */
-    volatile unsigned long OutIntMask;  /* outbound interrupt mask register */
-    volatile unsigned long reserved2;
-    volatile unsigned long reserved3;
-    volatile unsigned long InQueue;     /* inbound queue port */
-    volatile unsigned long OutQueue;    /* outbound queue port */
-    volatile unsigned long reserved4;
-    volatile unsigned long reserver5;
-     /* RedCreek extension */
-    volatile unsigned long EtherMacLow;
-    volatile unsigned long EtherMacHi;
-    volatile unsigned long IPaddr;
-    volatile unsigned long IPmask;
-}
- ATU, *PATU;
-
- /* 
- ** typedef PAB
- **
- ** PCI Adapter Block - holds instance specific information and is located
- ** in a reserved space at the start of the message buffer allocated by user.
- */
-typedef struct
-{
-    PATU             p_atu;                /* ptr to  ATU register block */
-    PU8              pPci45LinBaseAddr;
-    PU8              pLinOutMsgBlock;
-    U32              outMsgBlockPhyAddr; 
-    PFNTXCALLBACK    pTransCallbackFunc;
-    PFNRXCALLBACK    pRecvCallbackFunc;
-    PFNCALLBACK      pRebootCallbackFunc;
-    PFNCALLBACK      pCallbackFunc;
-    U16              ADAPTERState;
-    U16              InboundMFrameSize;
-}
- PAB, *PPAB;
-
- /* 
- ** in reserved space right after PAB in host memory is area for returning
- ** values from card 
- */
-
- /* 
- ** Array of pointers to PCI Adapter Blocks.
- ** Indexed by a zero based (0-31) interface number.
- */ 
-#define MAX_ADAPTERS 32
-static PPAB  PCIAdapterBlock[MAX_ADAPTERS] = 
-{
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
-
-/*
-** typedef NICSTAT
-**
-** Data structure for NIC statistics retruned from PCI card.  Data copied from
-** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.
-*/
-typedef struct tag_NicStat 
-{
-        unsigned long   TX_good; 
-        unsigned long   TX_maxcol;
-        unsigned long   TX_latecol;
-        unsigned long   TX_urun;
-        unsigned long   TX_crs;         /* lost carrier sense */
-        unsigned long   TX_def;         /* transmit deferred */
-        unsigned long   TX_singlecol;   /* single collisions */
-        unsigned long   TX_multcol;
-        unsigned long   TX_totcol;
-        unsigned long   Rcv_good;
-        unsigned long   Rcv_CRCerr;
-        unsigned long   Rcv_alignerr;
-        unsigned long   Rcv_reserr;     /* rnr'd pkts */
-        unsigned long   Rcv_orun;
-        unsigned long   Rcv_cdt;
-        unsigned long   Rcv_runt;
-        unsigned long   dump_status;    /* last field directly from the chip */
-} 
- NICSTAT, *P_NICSTAT;
-
-#define DUMP_DONE   0x0000A005      /* completed statistical dump */
-#define DUMP_CLEAR  0x0000A007      /* completed stat dump and clear counters */
-
-
-static volatile int msgFlag;
-
-
-/* local function prototypes */
-static void ProcessOutboundAdapterMsg(PPAB pPab, U32 phyMsgAddr);
-static int FillAdapterMsgSGLFromTCB(PU32 pMsg, PRCTCB pXmitCntrlBlock);
-static int GetAdapterStatus(PPAB pPab);
-static int SendAdapterOutboundQInitMsg(PPAB pPab);
-static int SendEnableSysMsg(PPAB pPab);
-
-
- /* 1st 100h bytes of message block is reserved for messenger instance */
-#define ADAPTER_BLOCK_RESERVED_SPACE 0x100
-
-/*
-** =========================================================================
-** InitRCApiMsgLayer()
-**
-** Initialize the RedCreek API Module and adapter.
-**
-** Inputs:  AdapterID - interface number from 0 to 15
-**          pciBaseAddr - virual base address of PCI (set by BIOS)
-**          p_msgbuf - virual address to private message block (min. 16K)
-**          p_phymsgbuf - physical address of private message block
-**          TransmitCallbackFunction - address of transmit callback function
-**          ReceiveCallbackFunction  - address of receive  callback function
-**
-** private message block is allocated by user.  It must be in locked pages.
-** p_msgbuf and p_phymsgbuf point to the same location.  Must be contigous
-** memory block of a minimum of 16K byte and long word aligned.
-** =========================================================================
-*/
-RC_RETURN
-InitRCApiMsgLayer(U16 AdapterID, U32 pciBaseAddr, 
-                  PU8 p_msgbuf,  PU8 p_phymsgbuf,
-                  PFNTXCALLBACK  TransmitCallbackFunction,
-                  PFNRXCALLBACK  ReceiveCallbackFunction,
-                  PFNCALLBACK    RebootCallbackFunction)
-{
-     int result;
-     PPAB pPab; 
-    
-#ifdef DEBUG
-     kprintf("InitAPI: Adapter:0x%04.4ux ATU:0x%08.8ulx msgbuf:0x%08.8ulx phymsgbuf:0x%08.8ulx\n"
-             "TransmitCallbackFunction:0x%08.8ulx  ReceiveCallbackFunction:0x%08.8ulx\n",
-             AdapterID, pciBaseAddr, p_msgbuf, p_phymsgbuf, TransmitCallbackFunction, ReceiveCallbackFunction);
-#endif /* DEBUG */
-
-    
-     /* Check if this interface already initialized - if so, shut it down */
-     if (PCIAdapterBlock[AdapterID] != NULL)
-     {
-          printk("PCIAdapterBlock[%d]!=NULL\n", AdapterID);
-//        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
-          PCIAdapterBlock[AdapterID] = NULL;
-     }
-
-    /* 
-    ** store adapter instance values in adapter block.
-    ** Adapter block is at beginning of message buffer
-    */  
-    pPab = (PPAB)p_msgbuf;
-    
-    pPab->p_atu = (PATU)pciBaseAddr;
-    pPab->pPci45LinBaseAddr =  (PU8)pciBaseAddr;
-    
-     /* Set outbound message frame addr - skip over Adapter Block */
-    pPab->outMsgBlockPhyAddr = (U32)(p_phymsgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
-    pPab->pLinOutMsgBlock    = (PU8)(p_msgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
-
-     /* store callback function addresses */
-    pPab->pTransCallbackFunc = TransmitCallbackFunction;
-    pPab->pRecvCallbackFunc  = ReceiveCallbackFunction;
-    pPab->pRebootCallbackFunc  = RebootCallbackFunction;
-    pPab->pCallbackFunc  = (PFNCALLBACK)NULL;
-
-    /*
-    ** Initialize API 
-    */
-    result = GetAdapterStatus(pPab);
-    
-    if (result != RC_RTN_NO_ERROR)
-        return result;
-
-    if (pPab->ADAPTERState == ADAPTER_STATE_OPERATIONAL)
-    {
-         printk("pPab->ADAPTERState == op: resetting adapter\n");
-         RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
-    }
-        
-    result = SendAdapterOutboundQInitMsg(pPab);
-    
-    if (result != RC_RTN_NO_ERROR)
-         return result;
-
-    result = SendEnableSysMsg(pPab);
-   
-    if (result != RC_RTN_NO_ERROR)
-         return result;
-   
-    PCIAdapterBlock[AdapterID] = pPab;
-    return RC_RTN_NO_ERROR;
-}
-
-/*
-** =========================================================================
-** Disable and Enable Adapter interrupts.  Adapter interrupts are enabled at Init time
-** but can be disabled and re-enabled through these two function calls.
-** Packets will still be put into any posted received buffers and packets will
-** be sent through RCSendPacket() functions.  Disabling Adapter interrupts
-** will prevent hardware interrupt to host even though the outbound Adapter msg
-** queue is not emtpy.
-** =========================================================================
-*/
-#define i960_OUT_POST_Q_INT_BIT        0x0008 /* bit set masks interrupts */
-
-RC_RETURN RCDisableAdapterInterrupts(U16 AdapterID)
-{
-    PPAB pPab;
-
-
-    pPab = PCIAdapterBlock[AdapterID];
-    
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-        
-    pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT;
-
-    return RC_RTN_NO_ERROR;
-}
-
-RC_RETURN RCEnableAdapterInterrupts(U16 AdapterID)
-{
-    PPAB pPab;
-
-    pPab = PCIAdapterBlock[AdapterID];
-    
-    if (pPab == NULL)
-         return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT;
-    
-    return RC_RTN_NO_ERROR;
-
-}
-
-
-/*
-** =========================================================================
-** RCSendPacket()
-** =========================================================================
-*/
-RC_RETURN
-RCSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock)
-{
-    U32 msgOffset;
-    PU32 pMsg;
-    int size;
-    PPAB pPab;
-
-#ifdef DEBUG
-kprintf("RCSendPacket()...\n");
-#endif /* DEBUG */
-    
-    pPab = PCIAdapterBlock[AdapterID];
-
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-     /* get Inbound free Q entry - reading from In Q gets free Q entry */
-     /* offset to Msg Frame in PCI msg block */
-
-    msgOffset = pPab->p_atu->InQueue; 
-
-    if (msgOffset == 0xFFFFFFFF)
-    {
-#ifdef DEBUG
-        kprintf("RCSendPacket(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
-        return RC_RTN_FREE_Q_EMPTY;
-    }
-        
-     /* calc virual address of msg - virual already mapped to physical */    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-    size = FillAdapterMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
-
-    if (size == -1) /* error processing TCB - send NOP msg */
-    {
-#ifdef DEBUG
-            kprintf("RCSendPacket(): Error Rrocess TCB!\n");
-#endif /* DEBUG */
-        pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
-        pMsg[1] = UTIL_NOP << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-        return RC_RTN_TCB_ERROR;
-    }
-    else /* send over msg header */
-    {    
-        pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
-        pMsg[1] = LAN_PACKET_SEND << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-        pMsg[2] = InitiatorContext;
-        pMsg[3] = 0;  /* batch reply */
-         /* post to Inbound Post Q */   
-        pPab->p_atu->InQueue = msgOffset;
-        return RC_RTN_NO_ERROR;
-    }
-}
-
-/*
-** =========================================================================
-** RCPostRecvBuffer()
-**
-** inputs:  pBufrCntrlBlock - pointer to buffer control block
-**
-** returns TRUE if successful in sending message, else FALSE.
-** =========================================================================
-*/
-RC_RETURN
-RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock)
-{
-    U32 msgOffset;
-    PU32 pMsg;
-    int size;
-    PPAB pPab;
-
-#ifdef DEBUG
-kprintf("RCPostRecvBuffers()...\n");
-#endif /* DEBUG */
-    
-     /* search for DeviceHandle */
-    pPab = PCIAdapterBlock[AdapterID];
-
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-
-     /* get Inbound free Q entry - reading from In Q gets free Q entry */
-     /* offset to Msg Frame in PCI msg block */
-    msgOffset = pPab->p_atu->InQueue; 
-
-    if (msgOffset == 0xFFFFFFFF)
-    {
-#ifdef DEBUG
-            kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
-        return RC_RTN_FREE_Q_EMPTY;
-   
-    }
-     /* calc virual address of msg - virual already mapped to physical */    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-    size = FillAdapterMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
-
-    if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */
-    {
-#ifdef DEBUG
-        kprintf("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size);
-#endif /* DEBUG */
-        pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
-        pMsg[1] = UTIL_NOP << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-         /* post to Post Q */   
-        pPab->p_atu->InQueue = msgOffset;
-        return RC_RTN_TCB_ERROR;
-    }
-    else /* send over size msg header */
-    {    
-        pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
-        pMsg[1] = LAN_RECEIVE_POST << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-        pMsg[3] = *(PU32)pTransCtrlBlock; /* number of packet buffers */
-         /* post to Post Q */   
-        pPab->p_atu->InQueue = msgOffset;
-        return RC_RTN_NO_ERROR;
-    }
-}
-
-
-/*
-** =========================================================================
-** RCProcMsgQ()
-**
-** Process outbound message queue until empty.
-** =========================================================================
-*/
-void 
-RCProcMsgQ(U16 AdapterID)
-{
-    U32 phyAddrMsg;
-    PU8 p8Msg;
-    PU32 p32;
-    U16 count;
-    PPAB pPab;
-    unsigned char debug_msg[20];
-    
-    pPab = PCIAdapterBlock[AdapterID];
-    
-    if (pPab == NULL)
-        return;
-    
-    phyAddrMsg = pPab->p_atu->OutQueue;
-
-    while (phyAddrMsg != 0xFFFFFFFF)
-    {
-        p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
-        p32 = (PU32)p8Msg;
-        
-        //printk(" msg: 0x%x  0x%x \n", p8Msg[7], p32[5]);
-
-     /* 
-     ** Send Packet Reply Msg
-     */
-        if (LAN_PACKET_SEND == p8Msg[7])  /* function code byte */
-        {
-            count = *(PU16)(p8Msg+2);
-            count -= p8Msg[0] >> 4;
-                                      /* status, count, context[], adapter */
-           (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID);
-        }             
-     /* 
-     ** Receive Packet Reply Msg */
-        else if (LAN_RECEIVE_POST == p8Msg[7])
-        {
-#ifdef DEBUG    
-    kprintf("RECV_REPLY pPab:0x%08.8ulx p8Msg:0x%08.8ulx p32:0x%08.8ulx\n", pPab, p8Msg, p32);
-    kprintf("msg: 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-            p32[0], p32[1], p32[2], p32[3]);
-    kprintf("     0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-            p32[4], p32[5], p32[6], p32[7]);
-    kprintf("     0x%08.8ulx:0X%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-            p32[8], p32[9], p32[10], p32[11]);
-#endif
-               /*  status, count, buckets remaining, packetParmBlock, adapter */
-          (*pPab->pRecvCallbackFunc)(p8Msg[19], p8Msg[12], p32[5], p32+6, AdapterID);
-      
-      
-        }
-        else if (LAN_RESET == p8Msg[7] || LAN_SHUTDOWN == p8Msg[7])
-        {
-            if (pPab->pCallbackFunc)
-            {
-                (*pPab->pCallbackFunc)(p8Msg[19],0,0,AdapterID);
-            }
-            else
-            {
-                pPab->pCallbackFunc = (PFNCALLBACK) 1;
-            }
-            //PCIAdapterBlock[AdapterID] = 0;
-        }
-        else if (RC_PRIVATE == p8Msg[7])
-        {
-            //printk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
-          switch (p32[5])
-          {
-          case RC_PRIVATE_DEBUG_MSG:
-               msgFlag = 1;
-               /*printk("Received RC_PRIVATE msg\n");*/
-               debug_msg[15]  = (p32[6]&0xff000000) >> 24;
-               debug_msg[14]  = (p32[6]&0x00ff0000) >> 16;
-               debug_msg[13]  = (p32[6]&0x0000ff00) >> 8;
-               debug_msg[12]  = (p32[6]&0x000000ff);
-
-               debug_msg[11]  = (p32[7]&0xff000000) >> 24;
-               debug_msg[10]  = (p32[7]&0x00ff0000) >> 16;
-               debug_msg[ 9]  = (p32[7]&0x0000ff00) >> 8;
-               debug_msg[ 8]  = (p32[7]&0x000000ff);
-
-               debug_msg[ 7]  = (p32[8]&0xff000000) >> 24;
-               debug_msg[ 6]  = (p32[8]&0x00ff0000) >> 16;
-               debug_msg[ 5] = (p32[8]&0x0000ff00) >> 8;
-               debug_msg[ 4] = (p32[8]&0x000000ff);
-
-               debug_msg[ 3] = (p32[9]&0xff000000) >> 24;
-               debug_msg[ 2] = (p32[9]&0x00ff0000) >> 16;
-               debug_msg[ 1] = (p32[9]&0x0000ff00) >> 8;
-               debug_msg[ 0] = (p32[9]&0x000000ff);
-
-               debug_msg[16] = '\0';
-               printk (debug_msg);
-               break;
-          case RC_PRIVATE_REBOOT:
-               printk("Adapter reboot initiated...\n");
-               if (pPab->pRebootCallbackFunc)
-               {
-                    (*pPab->pRebootCallbackFunc)(0,0,0,AdapterID);
-               }
-               break;
-          default:
-                printk("Unknown private msg received: 0x%x\n",
-                      p32[5]);
-               break;
-          }
-        }
-
-     /* 
-     ** Process other Msg's
-     */
-        else
-        {
-            ProcessOutboundAdapterMsg(pPab, phyAddrMsg);
-        }
-        
-         /* return MFA to outbound free Q*/
-        pPab->p_atu->OutQueue = phyAddrMsg;
-    
-         /* any more msgs? */
-        phyAddrMsg = pPab->p_atu->OutQueue;
-    }
-}
-
-
-/*
-** =========================================================================
-**  Returns LAN interface statistical counters to space provided by caller at
-**  StatsReturnAddr.  Returns 0 if success, else RC_RETURN code.
-**  This function will call the WaitCallback function provided by
-**  user while waiting for card to respond.
-** =========================================================================
-*/
-RC_RETURN
-RCGetLinkStatistics(U16 AdapterID, 
-                    P_RCLINKSTATS StatsReturnAddr,
-                    PFNWAITCALLBACK WaitCallback)
-{
-    U32 msgOffset;
-    volatile U32 timeout;
-    volatile PU32 pMsg;
-    volatile PU32 p32, pReturnAddr;
-    P_NICSTAT pStats;
-    int i;
-    PPAB pPab;
-
-/*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/
-
-    pPab = PCIAdapterBlock[AdapterID];
-
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    msgOffset = pPab->p_atu->InQueue;
-
-    if (msgOffset == 0xFFFFFFFF)
-    {
-    #ifdef DEBUG
-        kprintf("Get8255XStats(): Inbound Free Q empty!\n");
-    #endif
-        return RC_RTN_FREE_Q_EMPTY;
-    }
-
-     /* calc virual address of msg - virual already mapped to physical */
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-/*dprintf("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
-/*dprintf("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
-
-    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-    pMsg[3] = 0x112; /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LAN_STATS;
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-
-    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-
-    pStats = (P_NICSTAT)p32;
-    pStats->dump_status = 0xFFFFFFFF;
-
-     /* post to Inbound Post Q */
-    pPab->p_atu->InQueue = msgOffset;
-
-    timeout = 100000;
-    while (1)
-    {
-        if (WaitCallback)
-                (*WaitCallback)();
-        
-        for (i = 0; i < 1000; i++)
-            ;
-
-        if (pStats->dump_status != 0xFFFFFFFF)
-            break;
-
-        if (!timeout--)
-        {
-        #ifdef DEBUG
-            kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");
-        #endif
-            return RC_RTN_MSG_REPLY_TIMEOUT;
-        }
-    }
-    
-    pReturnAddr = (PU32)StatsReturnAddr;
-    
-     /* copy Nic stats to user's structure */
-    for (i = 0; i < (int) sizeof(RCLINKSTATS) / 4; i++)
-        pReturnAddr[i] = p32[i];
-   
-    return RC_RTN_NO_ERROR;     
-}
-
-
-/*
-** =========================================================================
-** Get82558LinkStatus()
-** =========================================================================
-*/
-RC_RETURN
-RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback)
-{
-    U32 msgOffset;
-    volatile U32 timeout;
-    volatile PU32 pMsg;
-    volatile PU32 p32;
-    PPAB pPab;
-
-/*kprintf("Get82558LinkStatus() ReturnPhysAddr:0x%08.8ulx\n", ReturnAddr);*/
-
-    pPab = PCIAdapterBlock[AdapterID];
-
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    msgOffset = pPab->p_atu->InQueue;
-
-    if (msgOffset == 0xFFFFFFFF)
-    {
-    #ifdef DEBUG
-        dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n");
-    #endif
-        return RC_RTN_FREE_Q_EMPTY;
-    }
-
-     /* calc virual address of msg - virual already mapped to physical */
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-/*dprintf("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
-/*dprintf("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
-
-    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-    pMsg[3] = 0x112; /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_STATUS;
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-
-    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-    *p32 = 0xFFFFFFFF;
-    
-     /* post to Inbound Post Q */
-    pPab->p_atu->InQueue = msgOffset;
-
-    timeout = 100000;
-    while (1)
-    {
-        U32 i;
-
-        if (WaitCallback)
-                (*WaitCallback)();
-        
-        for (i = 0; i < 1000; i++)
-            ;
-
-        if (*p32 != 0xFFFFFFFF)
-            break;
-
-        if (!timeout--)
-        {
-        #ifdef DEBUG
-            kprintf("Timeout waiting for link status\n");
-        #endif    
-            return RC_RTN_MSG_REPLY_TIMEOUT;
-        }
-    }
-    
-    *ReturnAddr = *p32; /* 1 = up 0 = down */
-    
-    return RC_RTN_NO_ERROR;
-    
-}
-
-/*
-** =========================================================================
-** RCGetMAC()
-**
-** get the MAC address the adapter is listening for in non-promiscous mode.
-** MAC address is in media format.
-** =========================================================================
-*/
-RC_RETURN
-RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback)
-{
-     unsigned i, timeout;
-     U32      off;
-     PU32     p;
-     U32      temp[2];
-     PPAB     pPab;
-     PATU     p_atu;
-    
-     pPab = PCIAdapterBlock[AdapterID];
-    
-     if (pPab == NULL)
-          return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-     p_atu = pPab->p_atu;
-
-     p_atu->EtherMacLow = 0;     /* first zero return data */
-     p_atu->EtherMacHi = 0;
-    
-     off = p_atu->InQueue;   /* get addresss of message */
-     if (0xFFFFFFFF == off)
-          return RC_RTN_FREE_Q_EMPTY;
-
-     p = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-#ifdef RCDEBUG
-     printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
-            (uint)p_atu, (uint)off, (uint)p);
-#endif /* RCDEBUG */
-     /* setup private message */
-     p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
-     p[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-     p[2] = 0;               /* initiator context */
-     p[3] = 0x218;           /* transaction context */
-     p[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_MAC_ADDR;
-
-
-     p_atu->InQueue = off;   /* send it to the device */
-#ifdef RCDEBUG
-     printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", 
-            (uint)p_atu, (uint)off, (uint)p);
-#endif /* RCDEBUG */
-
-     /* wait for the rcpci45 board to update the info */
-     timeout = 1000000;
-     while (0 == p_atu->EtherMacLow) 
-     {
-          if (WaitCallback)
-               (*WaitCallback)();
-    
-          for (i = 0; i < 1000; i++)
-               ;
-
-          if (!timeout--)
-          {
-               printk("rc_getmac: Timeout\n");
-               return RC_RTN_MSG_REPLY_TIMEOUT;
-          }
-     }
-    
-     /* read the mac address  */
-     temp[0] = p_atu->EtherMacLow;
-     temp[1] = p_atu->EtherMacHi;
-     memcpy((char *)mac, (char *)temp, 6);
-
-
-#ifdef RCDEBUG
-//    printk("rc_getmac: 0x%X\n", ptr);
-#endif /* RCDEBUG */
-
-     return RC_RTN_NO_ERROR;
-}
-
-/*
-** =========================================================================
-** RCSetMAC()
-**
-** set MAC address the adapter is listening for in non-promiscous mode.
-** MAC address is in media format.
-** =========================================================================
-*/
-RC_RETURN
-RCSetMAC(U16 AdapterID, PU8 mac)
-{
-    U32  off;
-    PU32 pMsg;
-    PPAB pPab;
-
-
-    pPab = PCIAdapterBlock[AdapterID];
-    
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    off = pPab->p_atu->InQueue; /* get addresss of message */
-    
-    if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-    /* setup private message */
-    pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = 0;                 /* initiator context */
-    pMsg[3] = 0x219;             /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_MAC_ADDR;
-    pMsg[5] = *(unsigned *)mac;  /* first four bytes */
-    pMsg[6] = *(unsigned *)(mac + 4); /* last two bytes */
-    
-    pPab->p_atu->InQueue = off;   /* send it to the device */
-
-    return RC_RTN_NO_ERROR ;
-}
-
-
-/*
-** =========================================================================
-** RCSetLinkSpeed()
-**
-** set ethernet link speed. 
-** input: speedControl - determines action to take as follows
-**          0 = reset and auto-negotiate (NWay)
-**          1 = Full Duplex 100BaseT
-**          2 = Half duplex 100BaseT
-**          3 = Full Duplex  10BaseT
-**          4 = Half duplex  10BaseT
-**          all other values are ignore (do nothing)
-** =========================================================================
-*/
-RC_RETURN
-RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode)
-{
-    U32  off;
-    PU32 pMsg;
-    PPAB pPab;
-
-    
-    pPab =PCIAdapterBlock[AdapterID];
-     
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    off = pPab->p_atu->InQueue; /* get addresss of message */
-    
-    if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-    /* setup private message */
-    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = 0;                 /* initiator context */
-    pMsg[3] = 0x219;             /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_LINK_SPEED;
-    pMsg[5] = LinkSpeedCode;     /* link speed code */
-
-    pPab->p_atu->InQueue = off;   /* send it to the device */
-
-    return RC_RTN_NO_ERROR ;
-}
-
-/*
-** =========================================================================
-** RCGetLinkSpeed()
-**
-** get ethernet link speed. 
-**
-** 0 = Unknown
-** 1 = Full Duplex 100BaseT
-** 2 = Half duplex 100BaseT
-** 3 = Full Duplex  10BaseT
-** 4 = Half duplex  10BaseT
-**
-** =========================================================================
-*/
-RC_RETURN
-RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback)
-{
-     U32 msgOffset, timeout;
-     PU32 pMsg;
-     volatile PU32 p32;
-     U8 AdapterLinkSpeed;
-     PPAB pPab;
-
-     pPab =PCIAdapterBlock[AdapterID];
-
-
-     msgOffset = pPab->p_atu->InQueue;
-
-
-     if (msgOffset == 0xFFFFFFFF)
-     {
-          kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
-          return RC_RTN_FREE_Q_EMPTY;
-     }
-
-     /* calc virtual address of msg - virtual already mapped to physical */    
-     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-     /* virtual pointer to return buffer - clear first two dwords */
-     p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-     p32[0] = 0xff;
-
-     /* setup private message */
-     pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
-     pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-     pMsg[2] = 0;                 /* initiator context */
-     pMsg[3] = 0x219;             /* transaction context */
-     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_SPEED;
-     /* phys address to return status - area right after PAB */
-     pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-   
-     /* post to Inbound Post Q */   
-
-     pPab->p_atu->InQueue = msgOffset;
-
-     /* wait for response */
-     timeout = 1000000;
-     while(1)
-     {
-          int i;
-        
-          if (WaitCallback)
-                (*WaitCallback)();
-
-          for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-               ;
-            
-          if (p32[0] != 0xff)
-               break;
-            
-          if (!timeout--)
-          {
-               kprintf("Timeout waiting for link speed from adapter\n");
-               kprintf("0x%08.8ulx\n", p32[0]);
-               return RC_RTN_NO_LINK_SPEED;
-          }
-     }
-
-     /* get Link speed */
-     AdapterLinkSpeed = (U8)((volatile PU8)p32)[0] & 0x0f;
-
-     *pLinkSpeedCode= AdapterLinkSpeed;
-
-     return RC_RTN_NO_ERROR;
-}
-
-/*
-** =========================================================================
-** RCReportDriverCapability(U16 AdapterID, U32 capability)
-**
-** Currently defined bits:
-** WARM_REBOOT_CAPABLE   0x01
-**
-** =========================================================================
-*/
-RC_RETURN
-RCReportDriverCapability(U16 AdapterID, U32 capability)
-{
-    U32  off;
-    PU32 pMsg;
-    PPAB pPab;
-
-    pPab =PCIAdapterBlock[AdapterID];
-     
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    off = pPab->p_atu->InQueue; /* get addresss of message */
-    
-    if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-    /* setup private message */
-    pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = 0;                 /* initiator context */
-    pMsg[3] = 0x219;             /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_REPORT_DRIVER_CAPABILITY;
-    pMsg[5] = capability;
-
-    pPab->p_atu->InQueue = off;   /* send it to the device */
-
-    return RC_RTN_NO_ERROR ;
-}
-
-/*
-** =========================================================================
-** RCGetFirmwareVer()
-**
-** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
-**
-** =========================================================================
-*/
-RC_RETURN
-RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback)
-{
-     U32 msgOffset, timeout;
-     PU32 pMsg;
-     volatile PU32 p32;
-     PPAB pPab;
-
-     pPab =PCIAdapterBlock[AdapterID];
-
-     msgOffset = pPab->p_atu->InQueue;
-
-
-     if (msgOffset == 0xFFFFFFFF)
-     {
-          kprintf("RCGetFirmwareVer(): Inbound Free Q empty!\n");
-          return RC_RTN_FREE_Q_EMPTY;
-     }
-
-     /* calc virtual address of msg - virtual already mapped to physical */    
-     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-     /* virtual pointer to return buffer - clear first two dwords */
-     p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-     p32[0] = 0xff;
-
-     /* setup private message */
-     pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
-     pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-     pMsg[2] = 0;                 /* initiator context */
-     pMsg[3] = 0x219;             /* transaction context */
-     pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_FIRMWARE_REV;
-     /* phys address to return status - area right after PAB */
-     pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-
-
-   
-     /* post to Inbound Post Q */   
-
-     pPab->p_atu->InQueue = msgOffset;
-
-    
-     /* wait for response */
-     timeout = 1000000;
-     while(1)
-     {
-          int i;
-        
-          if (WaitCallback)
-                (*WaitCallback)();
-            
-          for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-               ;
-
-          if (p32[0] != 0xff)
-               break;
-            
-          if (!timeout--)
-          {
-               kprintf("Timeout waiting for link speed from adapter\n");
-               return RC_RTN_NO_FIRM_VER;
-          }
-     }
-
-     strcpy(pFirmString, (PU8)p32);
-     return RC_RTN_NO_ERROR;
-}
-
-/*
-** =========================================================================
-** RCResetLANCard()
-**
-** ResourceFlags indicates whether to return buffer resource explicitly
-** to host or keep and reuse.
-** CallbackFunction (if not NULL) is the function to be called when 
-** reset is complete.
-** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
-** reset is done (if not NULL).
-**
-** =========================================================================
-*/
-RC_RETURN 
-RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
-{
-    unsigned long off;
-    unsigned long *pMsg;
-    PPAB pPab;
-    int i;
-    long timeout = 0;
-
-    
-    pPab =PCIAdapterBlock[AdapterID];
-     
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-
-    off = pPab->p_atu->InQueue; /* get addresss of message */
-    
-    if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-    
-    pPab->pCallbackFunc = CallbackFunction;
-
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-    /* setup message */
-    pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = LAN_RESET << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-    pMsg[3] = ResourceFlags << 16;   /* resource flags */
-
-    pPab->p_atu->InQueue = off;   /* send it to the device */
-
-    if (CallbackFunction == (PFNCALLBACK)NULL)
-    {
-        /* call RCProcMsgQ() until something in pPab->pCallbackFunc
-           or until timer goes off */
-        while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
-        {
-            RCProcMsgQ(AdapterID);
-            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
-               ;
-            timeout++;
-            if (timeout > 10000)
-            {
-                break;
-            }
-        }
-        if (ReturnAddr != (PU32)NULL)
-           *ReturnAddr = (U32)pPab->pCallbackFunc;
-    }
-
-    return RC_RTN_NO_ERROR ;
-}
-/*
-** =========================================================================
-** RCResetAdapter()
-**
-** Send StatusGet Msg, wait for results return directly to buffer.
-**
-** =========================================================================
-*/
-RC_RETURN 
-RCResetAdapter(U16 AdapterID)
-{
-     U32 msgOffset, timeout;
-     PU32 pMsg;
-     PPAB pPab;
-     volatile PU32 p32;
-    
-     pPab = PCIAdapterBlock[AdapterID];
-     msgOffset = pPab->p_atu->InQueue;
-
-     if (msgOffset == 0xFFFFFFFF)
-     {
-          return RC_RTN_FREE_Q_EMPTY;
-     }
-
-     /* calc virtual address of msg - virtual already mapped to physical */    
-     pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-     pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
-     pMsg[1] = RC_CMD_ADAPTER_RESET << 24 | HOST_TID << 12 | ADAPTER_TID;
-     pMsg[2] = 0; /* universal context */
-     pMsg[3] = 0; /* universal context */
-     pMsg[4] = 0; /* universal context */
-     pMsg[5] = 0; /* universal context */
-     /* phys address to return status - area right after PAB */
-     pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-     pMsg[7] = 0;
-     pMsg[8] = 1;  /*  return 1 byte */
-
-     /* virual pointer to return buffer - clear first two dwords */
-     p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-     p32[0] = 0;
-     p32[1] = 0;
-
-     /* post to Inbound Post Q */   
-
-     pPab->p_atu->InQueue = msgOffset;
-
-     /* wait for response */
-     timeout = 1000000;
-     while(1)
-     {
-          int i;
-        
-          for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-               ;
-            
-          if (p32[0] || p32[1])
-               break;
-            
-          if (!timeout--)
-          {
-               printk("RCResetAdapter timeout\n");
-               return RC_RTN_MSG_REPLY_TIMEOUT;
-          }
-     }
-     return RC_RTN_NO_ERROR;
-}
-
-/*
-** =========================================================================
-** RCShutdownLANCard()
-**
-** ResourceFlags indicates whether to return buffer resource explicitly
-** to host or keep and reuse.
-** CallbackFunction (if not NULL) is the function to be called when 
-** shutdown is complete.
-** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
-** shutdown is done (if not NULL).
-**
-** =========================================================================
-*/
-RC_RETURN 
-RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
-{
-    volatile PU32 pMsg;
-    U32 off;
-    PPAB pPab;
-    int i;
-    long timeout = 0;
-
-    pPab = PCIAdapterBlock[AdapterID];
-
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-
-    off = pPab->p_atu->InQueue; /* get addresss of message */
-    
-    if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-
-    pPab->pCallbackFunc = CallbackFunction;
-    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-    /* setup message */
-    pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = LAN_SHUTDOWN << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-    pMsg[3] = ResourceFlags << 16;   /* resource flags */
-
-    pPab->p_atu->InQueue = off;   /* send it to the device */
-
-    if (CallbackFunction == (PFNCALLBACK)NULL)
-    {
-        /* call RCProcMsgQ() until something in pPab->pCallbackFunc
-           or until timer goes off */
-        while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
-        {
-            RCProcMsgQ(AdapterID);
-            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
-               ;
-            timeout++;
-            if (timeout > 10000)
-            {
-                break;
-            }
-        }
-        if (ReturnAddr != (PU32)NULL)
-           *ReturnAddr = (U32)pPab->pCallbackFunc;
-    }
-    return RC_RTN_NO_ERROR ;
-}
-
-
-/*
-** =========================================================================
-** RCSetRavlinIPandMask()
-**
-** Set the Ravlin 45/PCI cards IP address and network mask.
-**
-** IP address and mask must be in network byte order.
-** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
-** 0x04030201 and 0x00FFFFFF on a little endian machine.
-**
-** =========================================================================
-*/
-RC_RETURN
-RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask)
-{
-    volatile PU32 pMsg;
-    U32 off;
-    PPAB pPab;
-
-    pPab = PCIAdapterBlock[AdapterID];
-
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-
-    off = pPab->p_atu->InQueue; /* get addresss of message */
-    
-    if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-    /* setup private message */
-    pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = 0;                 /* initiator context */
-    pMsg[3] = 0x219;             /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_IP_AND_MASK;
-    pMsg[5] = ipAddr; 
-    pMsg[6] = netMask;
-
-
-    pPab->p_atu->InQueue = off;   /* send it to the device */
-    return RC_RTN_NO_ERROR ;
-
-}
-
-/*
-** =========================================================================
-** RCGetRavlinIPandMask()
-**
-** get the IP address and MASK from the card
-** 
-** =========================================================================
-*/
-RC_RETURN
-RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, 
-                        PFNWAITCALLBACK WaitCallback)
-{
-    unsigned i, timeout;
-    U32      off;
-    PU32     pMsg, p32;
-    PPAB     pPab;
-    PATU     p_atu;
-    
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
-#endif /* DEBUG */
-
-    pPab = PCIAdapterBlock[AdapterID];
-    
-    if (pPab == NULL)
-        return RC_RTN_ADPTR_NOT_REGISTERED;
-    
-    p_atu = pPab->p_atu;
-    off = p_atu->InQueue;   /* get addresss of message */
-   if (0xFFFFFFFF == off)
-         return RC_RTN_FREE_Q_EMPTY;
-
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-    *p32 = 0xFFFFFFFF;
-
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
-
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
-#endif /* DEBUG */
-    /* setup private message */
-    pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_PRIVATE << 24 | HOST_TID << 12 | LAN_TARGET_ID;
-    pMsg[2] = 0;               /* initiator context */
-    pMsg[3] = 0x218;           /* transaction context */
-    pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK;
-    pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-
-    p_atu->InQueue = off;   /* send it to the device */
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
-#endif /* DEBUG */
-
-     /* wait for the rcpci45 board to update the info */
-    timeout = 100000;
-    while (0xffffffff == *p32)
-    {
-        if (WaitCallback)
-                (*WaitCallback)();
-    
-        for (i = 0; i < 1000; i++)
-            ;
-
-        if (!timeout--)
-        {
-        #ifdef DEBUG
-            kprintf("RCGetRavlinIPandMask: Timeout\n");
-        #endif /* DEBUG */
-             return RC_RTN_MSG_REPLY_TIMEOUT;
-        }
-    }
-
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: after time out\n", \
-            "p32[0] (IpAddr) 0x%08.8ulx, p32[1] (IPmask) 0x%08.8ulx\n", p32[0], p32[1]);
-#endif /* DEBUG */
-    
-    /* send IP and mask to user's space  */
-    *pIpAddr  = p32[0];
-    *pNetMask = p32[1];
-
-
-#ifdef DEBUG
-    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
-#endif /* DEBUG */
-
-    return RC_RTN_NO_ERROR;
-}
-
-/* 
-** /////////////////////////////////////////////////////////////////////////
-** /////////////////////////////////////////////////////////////////////////
-**
-**                        local functions
-**
-** /////////////////////////////////////////////////////////////////////////
-** /////////////////////////////////////////////////////////////////////////
-*/
-
-/*
-** =========================================================================
-** SendAdapterOutboundQInitMsg()
-**
-** =========================================================================
-*/
-static int 
-SendAdapterOutboundQInitMsg(PPAB pPab)
-{
-    U32 msgOffset, timeout, phyOutQFrames, i;
-    volatile PU32 pMsg;
-    volatile PU32 p32;
-    
-    
-    
-    msgOffset = pPab->p_atu->InQueue;
-
-    
-    if (msgOffset == 0xFFFFFFFF)
-    {
-#ifdef DEBUG
-        kprintf("SendAdapterOutboundQInitMsg(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
-        return RC_RTN_FREE_Q_EMPTY;
-    }
-    
-    
-     /* calc virual address of msg - virual already mapped to physical */    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-#ifdef DEBUG
-kprintf("SendAdapterOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
-#endif /* DEBUG */
-
-    pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
-    pMsg[1] = RC_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID;
-    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-    pMsg[3] = 0x106; /* transaction context */
-    pMsg[4] = 4096; /* Host page frame size */
-    pMsg[5] = MSG_FRAME_SIZE  << 16 | 0x80; /* outbound msg frame size and Initcode */
-    pMsg[6] = 0xD0000004;       /* simple sgl element LE, EOB */
-     /* phys address to return status - area right after PAB */
-    pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-
-     /* virual pointer to return buffer - clear first two dwords */
-    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-    p32[0] = 0;
-    
-     /* post to Inbound Post Q */   
-    pPab->p_atu->InQueue = msgOffset;
-    
-  /* wait for response */
-    timeout = 100000;
-    while(1)
-    {
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
-            
-        if (p32[0])
-            break;
-            
-        if (!timeout--)
-        {
-#ifdef DEBUG
-            kprintf("Timeout wait for InitOutQ InPrgress status from adapter\n");
-#endif /* DEBUG */
-            return RC_RTN_NO_STATUS;
-        }
-    }
-
-    timeout = 100000;
-    while(1)
-    {
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
-            
-        if (p32[0] == RC_CMD_OUTBOUND_INIT_COMPLETE)
-            break;
-
-        if (!timeout--)
-        {
-#ifdef DEBUG
-            kprintf("Timeout wait for InitOutQ Complete status from adapter\n");
-#endif /* DEBUG */
-            return RC_RTN_NO_STATUS;
-        }
-    }
-
-     /* load PCI outbound free Q with MF physical addresses */
-    phyOutQFrames = pPab->outMsgBlockPhyAddr;
-
-    for (i = 0; i < NMBR_MSG_FRAMES; i++)
-    {
-        pPab->p_atu->OutQueue = phyOutQFrames;
-        phyOutQFrames += MSG_FRAME_SIZE;
-    }
-    return RC_RTN_NO_ERROR;
-}
-
-
-/*
-** =========================================================================
-** GetAdapterStatus()
-**
-** Send StatusGet Msg, wait for results return directly to buffer.
-**
-** =========================================================================
-*/
-static int 
-GetAdapterStatus(PPAB pPab)
-{
-    U32 msgOffset, timeout;
-    PU32 pMsg;
-    volatile PU32 p32;
-    
-    
-    msgOffset = pPab->p_atu->InQueue; 
-    printk("GetAdapterStatus: msg offset = 0x%x\n", msgOffset);
-    if (msgOffset == 0xFFFFFFFF)
-    {
-#ifdef DEBUG
-        kprintf("GetAdapterStatus(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
-        return RC_RTN_FREE_Q_EMPTY;
-    }
-
-     /* calc virual address of msg - virual already mapped to physical */    
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-    pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_CMD_STATUS_GET << 24 | HOST_TID << 12 | ADAPTER_TID;
-    pMsg[2] = 0; /* universal context */
-    pMsg[3] = 0; /* universal context */
-    pMsg[4] = 0; /* universal context */
-    pMsg[5] = 0; /* universal context */
-     /* phys address to return status - area right after PAB */
-    pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); 
-    pMsg[7] = 0;
-    pMsg[8] = 88;  /*  return 88 bytes */
-
-     /* virual pointer to return buffer - clear first two dwords */
-    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
-    p32[0] = 0;
-    p32[1] = 0;
-
-#ifdef DEBUG
-kprintf("GetAdapterStatus - pMsg:0x%08.8ulx, msgOffset:0x%08.8ulx, [1]:0x%08.8ulx, [6]:0x%08.8ulx\n",
-    pMsg, msgOffset, pMsg[1], pMsg[6]);
-#endif /* DEBUG */
-   
-     /* post to Inbound Post Q */   
-    pPab->p_atu->InQueue = msgOffset;
-    
-#ifdef DEBUG
-kprintf("Return status to p32 = 0x%08.8ulx\n", p32);
-#endif /* DEBUG */
-    
-     /* wait for response */
-    timeout = 1000000;
-    while(1)
-    {
-        int i;
-        
-        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
-            ;
-            
-        if (p32[0] && p32[1])
-            break;
-            
-        if (!timeout--)
-        {
-#ifdef DEBUG
-            kprintf("Timeout waiting for status from adapter\n");
-kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
-kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
-kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
-#endif /* DEBUG */
-            return RC_RTN_NO_STATUS;
-        }
-    }
-            
-#ifdef DEBUG
-kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
-kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
-kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
-#endif /* DEBUG */
-    /* get adapter state */
-    pPab->ADAPTERState = ((volatile PU8)p32)[10];
-    pPab->InboundMFrameSize  = ((volatile PU16)p32)[6];
-    
-#ifdef DEBUG
-    kprintf("adapter state 0x%02.2x InFrameSize = 0x%04.4x\n", 
-                        pPab->ADAPTERState, pPab->InboundMFrameSize);
-#endif /* DEBUG */
-    return RC_RTN_NO_ERROR;
-}
-
-
-/*
-** =========================================================================
-** SendEnableSysMsg()
-**
-**
-** =========================================================================
-*/
-static int 
-SendEnableSysMsg(PPAB pPab)
-{
-    U32 msgOffset; // timeout;
-    volatile PU32 pMsg;
-
-    msgOffset = pPab->p_atu->InQueue;
-
-    if (msgOffset == 0xFFFFFFFF)
-    {
-#ifdef DEBUG
-        kprintf("SendEnableSysMsg(): Inbound Free Q empty!\n");
-#endif /* DEBUG */
-        return RC_RTN_FREE_Q_EMPTY;
-    }
-
-     /* calc virual address of msg - virual already mapped to physical */
-    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
-
-#ifdef DEBUG
-kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
-#endif /* DEBUG */
-
-    pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
-    pMsg[1] = RC_CMD_SYS_ENABLE << 24 | HOST_TID << 12 | ADAPTER_TID;
-    pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
-    pMsg[3] = 0x110; /* transaction context */
-    pMsg[4] = 0x50657465; /*  RedCreek Private */
-
-     /* post to Inbound Post Q */
-    pPab->p_atu->InQueue = msgOffset;
-
-    return RC_RTN_NO_ERROR;
-}
-
-
-/*
-** =========================================================================
-** FillI12OMsgFromTCB()
-**
-** inputs   pMsgU32 - virual pointer (mapped to physical) of message frame
-**          pXmitCntrlBlock - pointer to caller buffer control block.
-**
-** fills in LAN SGL after Transaction Control Word or Bucket Count.
-** =========================================================================
-*/
-static int 
-FillAdapterMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock)
-{
-    unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags;
-    PU32 pTCB, pMsg;
-
- /* SGL element flags */   
-#define EOB        0x40000000
-#define LE         0x80000000
-#define SIMPLE_SGL 0x10000000
-#define BC_PRESENT 0x01000000
-
-    pTCB = (PU32)pTransCtrlBlock;
-    pMsg = pMsgFrame;
-    nmbrDwords = 0;
-
-#ifdef DEBUG
- kprintf("FillAdapterMsgSGLFromTCBX\n");
-kprintf("TCB  0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
-               pTCB[0], pTCB[1], pTCB[2], pTCB[3], pTCB[4]);
-kprintf("pTCB 0x%08.8ulx, pMsg 0x%08.8ulx\n", pTCB, pMsg);
-#endif /* DEBUG */
-    
-    nmbrBuffers = *pTCB++;
-    
-    if (!nmbrBuffers)
-    {
-        return -1;
-    }
-
-    do
-    {
-        context = *pTCB++; /* buffer tag (context) */
-        nmbrSeg = *pTCB++; /* number of segments */
-
-        if (!nmbrSeg)
-        {
-            return -1;
-        }
-        
-        flags = SIMPLE_SGL | BC_PRESENT;
-
-        if (1 == nmbrSeg)
-        {
-            flags |= EOB;
-        
-            if (1 == nmbrBuffers)
-                flags |= LE;
-        }    
-
-         /* 1st SGL buffer element has context */
-        pMsg[0] = pTCB[0] | flags ; /* send over count (segment size) */
-        pMsg[1] = context;
-        pMsg[2] = pTCB[1]; /* send buffer segment physical address */
-        nmbrDwords += 3;
-        pMsg += 3;
-        pTCB += 2;
-
-        
-        if (--nmbrSeg)
-        {
-            do
-            {
-                flags = SIMPLE_SGL;
-                
-                if (1 == nmbrSeg)
-                {
-                    flags |= EOB;
-                
-                    if (1 == nmbrBuffers)
-                        flags |= LE;
-                }    
-                
-                pMsg[0] = pTCB[0] | flags;  /* send over count */
-                pMsg[1] = pTCB[1];   /* send buffer segment physical address */
-                nmbrDwords += 2;
-                pTCB += 2;
-                pMsg += 2;
-        
-            } while (--nmbrSeg);
-        }
-        
-    } while (--nmbrBuffers);
-    
-    return nmbrDwords;
-}
-
-
-/*
-** =========================================================================
-** ProcessOutboundAdapterMsg()
-**
-** process reply message
-** * change to msg structure *
-** =========================================================================
-*/
-static void 
-ProcessOutboundAdapterMsg(PPAB pPab, U32 phyAddrMsg)
-{
-    PU8 p8Msg;
-    PU32 p32;
-  //  U16 count;
-    
-    
-    p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
-    p32 = (PU32)p8Msg;
-    
-#ifdef DEBUG
- kprintf("VXD: ProcessOutboundAdapterMsg - pPab 0x%08.8ulx, phyAdr 0x%08.8ulx, linAdr 0x%08.8ulx\n", pPab, phyAddrMsg, p8Msg);
- kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
- kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
-#endif /* DEBUG */
-
-    if (p32[4] >> 24 != RC_REPLY_STATUS_SUCCESS)
-    {
-#ifdef DEBUG
-        kprintf("Message reply status not success\n");
-#endif /* DEBUG */
-        return;
-    }
-    
-    switch (p8Msg[7] )  /* function code byte */
-    {
-        case RC_CMD_SYS_TAB_SET:
-            msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received RC_CMD_SYS_TAB_SET reply\n");
-#endif /* DEBUG */
-            break;
-
-        case RC_CMD_HRT_GET:
-            msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received RC_CMD_HRT_GET reply\n");
-#endif /* DEBUG */
-            break;
-        
-        case RC_CMD_LCT_NOTIFY:
-            msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received RC_CMD_LCT_NOTIFY reply\n");
-#endif /* DEBUG */
-            break;
-        
-        case RC_CMD_SYS_ENABLE:
-            msgFlag = 1;
-#ifdef DEBUG
-        kprintf("Received RC_CMD_SYS_ENABLE reply\n");
-#endif /* DEBUG */
-            break;
-
-        default:    
-#ifdef DEBUG
-        kprintf("Received UNKNOWN reply\n");
-#endif /* DEBUG */
-            break;
-    }
-}
diff --git a/drivers/net/rcmtl.h b/drivers/net/rcmtl.h
deleted file mode 100644 (file)
index cfd14e0..0000000
+++ /dev/null
@@ -1,580 +0,0 @@
-/*
-** *************************************************************************
-**
-**
-**     R C M T L . H             $Revision: 3 $
-**
-**
-**  RedCreek Message Transport Layer header file.
-**
-**  ---------------------------------------------------------------------
-**  ---     Copyright (c) 1997-1998, RedCreek Communications Inc.     ---
-**  ---                   All rights reserved.                        ---
-**  ---------------------------------------------------------------------
-**
-**  File Description:
-**
-**  Header file for host message transport layer API and data types.
-**
-**  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., 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-** *************************************************************************
-*/
-
-#ifndef RCMTL_H
-#define RCMTL_H
-
-/* Linux specific includes */
-#define kprintf printk
-#ifdef RC_LINUX_MODULE     /* linux modules need non-library version of string functions */
-#include <linux/string.h>
-#else
-#include <string.h>
-#endif
-
-/* PCI/45 Configuration space values */
-#define RC_PCI45_VENDOR_ID  0x4916
-#define RC_PCI45_DEVICE_ID  0x1960
-
-
- /* RedCreek API function return values */
-#define RC_RTN_NO_ERROR             0
-#define RC_RTN_NOT_INIT             1
-#define RC_RTN_FREE_Q_EMPTY         2
-#define RC_RTN_TCB_ERROR            3
-#define RC_RTN_TRANSACTION_ERROR    4
-#define RC_RTN_ADAPTER_ALREADY_INIT 5
-#define RC_RTN_MALLOC_ERROR         6
-#define RC_RTN_ADPTR_NOT_REGISTERED 7
-#define RC_RTN_MSG_REPLY_TIMEOUT    8
-#define RC_RTN_NO_STATUS            9
-#define RC_RTN_NO_FIRM_VER         10
-#define RC_RTN_NO_LINK_SPEED       11
-
-/* Driver capability flags */
-#define WARM_REBOOT_CAPABLE      0x01
-
- /* scalar data types */
-typedef unsigned char   U8;
-typedef unsigned char*  PU8;
-typedef unsigned short  U16;
-typedef unsigned short* PU16;
-typedef unsigned long   U32;
-typedef unsigned long*  PU32;
-typedef unsigned long   BF;
-typedef int             RC_RETURN;
-
-
- /* 
- ** type PFNWAITCALLBACK
- **
- ** pointer to void function - type used for WaitCallback in some functions 
- */
-typedef void (*PFNWAITCALLBACK)(void);  /* void argument avoids compiler complaint */
-
- /*
- ** type PFNTXCALLBACK 
- **
- ** Pointer to user's transmit callback function.  This user function is
- ** called from RCProcMsgQ() when packet have been transmitted from buffers
- ** given in the RCSendPacket() function.  BufferContext is a pointer to
- ** an array of 32 bit context values.  These are the values the user assigned
- ** and passed in the TCB to the RCSendPacket() function.  PcktCount
- ** indicates the number of buffer context values in the BufferContext[] array.
- ** The User's TransmitCallbackFunction should recover (put back in free queue)
- ** the packet buffers associated with the buffer context values.
- */
-typedef void (*PFNTXCALLBACK)(U32  Status,
-                              U16  PcktCount,
-                              PU32 BufferContext,
-                              U16  AdaterID);
-
- /* 
- ** type PFNRXCALLBACK 
- **
- ** Pointer to user's receive callback function.  This user function
- ** is called from RCProcMsgQ() when packets have been received into
- ** previously posted packet buffers throught the RCPostRecvBuffers() function.
- ** The received callback function should process the Packet Descriptor Block
- ** pointed to by PacketDescBlock. See Packet Decription Block below.
- */
-typedef void (*PFNRXCALLBACK)(U32  Status,
-                              U8   PktCount,
-                              U32  BucketsRemain,
-                              PU32 PacketDescBlock,
-                              U16  AdapterID);
-
- /* 
- ** type PFNCALLBACK 
- **
- ** Pointer to user's generic callback function.  This user function
- ** can be passed to LANReset or LANShutdown and is called when the 
- ** the reset or shutdown is complete.
- ** Param1 and Param2 are invalid for LANReset and LANShutdown.
- */
-typedef void (*PFNCALLBACK)(U32  Status,
-                              U32  Param1,
-                              U32  Param2,
-                              U16  AdapterID);
-
-/*
-** Status - Transmit and Receive callback status word 
-**
-** A 32 bit Status is returned to the TX and RX callback functions.  This value
-** contains both the reply status and the detailed status as follows:
-**
-**  32    24     16            0
-**  +------+------+------------+
-**  | Reply|      |  Detailed  |
-**  |Status|   0  |   Status   |
-**  +------+------+------------+
-**
-** Reply Status and Detailed Status of zero indicates No Errors.
-*/
- /* reply message status defines */
-#define    RC_REPLY_STATUS_SUCCESS                    0x00
-#define    RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     0x02
-#define    RC_REPLY_STATUS_TRANSACTION_ERROR          0x0A
-
-
-/* DetailedStatusCode defines */
-#define    RC_DSC_SUCCESS                         0x0000
-#define    RC_DSC_DEVICE_FAILURE                  0x0001
-#define    RC_DSC_DESTINATION_NOT_FOUND           0x0002
-#define    RC_DSC_TRANSMIT_ERROR                  0x0003
-#define    RC_DSC_TRANSMIT_ABORTED                0x0004
-#define    RC_DSC_RECEIVE_ERROR                   0x0005
-#define    RC_DSC_RECEIVE_ABORTED                 0x0006
-#define    RC_DSC_DMA_ERROR                       0x0007
-#define    RC_DSC_BAD_PACKET_DETECTED             0x0008
-#define    RC_DSC_OUT_OF_MEMORY                   0x0009
-#define    RC_DSC_BUCKET_OVERRUN                  0x000A
-#define    RC_DSC_IOP_INTERNAL_ERROR              0x000B
-#define    RC_DSC_CANCELED                        0x000C
-#define    RC_DSC_INVALID_TRANSACTION_CONTEXT     0x000D
-#define    RC_DSC_DESTINATION_ADDRESS_DETECTED    0x000E
-#define    RC_DSC_DESTINATION_ADDRESS_OMITTED     0x000F
-#define    RC_DSC_PARTIAL_PACKET_RETURNED         0x0010
-
-
-/*
-** Packet Description Block   (Received packets)
-**
-** A pointer to this block structure is returned to the ReceiveCallback 
-** function.  It contains the list of packet buffers which have either been
-** filled with a packet or returned to host due to a LANReset function. 
-** Currently there will only be one packet per receive bucket (buffer) posted. 
-**
-**   32   24               0     
-**  +-----------------------+  -\
-**  |   Buffer 1 Context    |    \
-**  +-----------------------+     \
-**  |      0xC0000000       |     / First Bucket Descriptor
-**  +-----+-----------------+    /
-**  |  0  | packet 1 length |   / 
-**  +-----------------------+  -\
-**  |   Buffer 2 Context    |    \
-**  +-----------------------+     \
-**  |      0xC0000000       |     / Second Bucket Descriptor
-**  +-----+-----------------+    /
-**  |  0  | packet 2 length |   / 
-**  +-----+-----------------+  -
-**  |         ...           |  ----- more bucket descriptors
-**  +-----------------------+  -\
-**  |   Buffer n Context    |    \
-**  +-----------------------+     \
-**  |      0xC0000000       |     / Last Bucket Descriptor
-**  +-----+-----------------+    /
-**  |  0  | packet n length |   / 
-**  +-----+-----------------+  -
-**
-** Buffer Context values are those given to adapter in the TCB on calls to
-** RCPostRecvBuffers().
-**  
-*/
-
-
-
-/*
-** Transaction Control Block (TCB) structure
-**
-** A structure like this is filled in by the user and passed by reference to 
-** RCSendPacket() and RCPostRecvBuffers() functions.  Minimum size is five
-** 32-bit words for one buffer with one segment descriptor.  
-** MAX_NMBR_POST_BUFFERS_PER_MSG defines the maximum single segment buffers
-** that can be described in a given TCB.
-**
-**   32                    0
-**  +-----------------------+
-**  |   Buffer Count        |  Number of buffers in the TCB
-**  +-----------------------+
-**  |   Buffer 1 Context    |  first buffer reference
-**  +-----------------------+
-**  |   Buffer 1 Seg Count  |  number of segments in buffer
-**  +-----------------------+
-**  |   Buffer 1 Seg Desc 1 |  first segment descriptor (size, physical address)
-**  +-----------------------+
-**  |         ...           |  more segment descriptors (size, physical address)
-**  +-----------------------+
-**  |   Buffer 1 Seg Desc n |  last segment descriptor (size, physical address)
-**  +-----------------------+
-**  |   Buffer 2 Context    |  second buffer reference
-**  +-----------------------+
-**  |   Buffer 2 Seg Count  |  number of segments in buffer
-**  +-----------------------+
-**  |   Buffer 2 Seg Desc 1 |  segment descriptor (size, physical address)
-**  +-----------------------+
-**  |         ...           |  more segment descriptors (size, physical address)
-**  +-----------------------+
-**  |   Buffer 2 Seg Desc n |
-**  +-----------------------+
-**  |         ...           |  more buffer descriptor blocks ...
-**  +-----------------------+
-**  |   Buffer n Context    |
-**  +-----------------------+
-**  |   Buffer n Seg Count  |
-**  +-----------------------+
-**  |   Buffer n Seg Desc 1 |
-**  +-----------------------+
-**  |         ...           |
-**  +-----------------------+
-**  |   Buffer n Seg Desc n |
-**  +-----------------------+
-**
-**
-** A TCB for one contigous packet buffer would look like the following:
-**
-**   32                    0
-**  +-----------------------+
-**  |         1             |  one buffer in the TCB
-**  +-----------------------+
-**  |  <user's Context>     |  user's buffer reference
-**  +-----------------------+
-**  |         1             |  one segment buffer
-**  +-----------------------+                            _
-**  |    <buffer size>      |  size                       \ 
-**  +-----------------------+                              \ segment descriptor
-**  |  <physical address>   |  physical address of buffer  /
-**  +-----------------------+                            _/
-**
-*/
-
- /* Buffer Segment Descriptor */
-typedef struct
-{
-    U32 size;
-    U32 phyAddress;
-}
- BSD, *PBSD;
-typedef PU32 PRCTCB;
-/*
-** -------------------------------------------------------------------------
-** Exported functions comprising the API to the message transport layer
-** -------------------------------------------------------------------------
-*/
-
-
- /*
- ** InitRCApiMsgLayer()
- ** 
- ** Called once prior to using the API message transport layer.  User 
- ** provides both the physical and virual address of a locked page buffer 
- ** that is used as a private buffer for the RedCreek API message
- ** transport layer.  This buffer must be a contigous memory block of a 
- ** minimum of 16K bytes and long word aligned.  The user also must provide
- ** the base address of the RedCreek PCI adapter assigned by BIOS or operating
- ** system.  The user provided value AdapterID is a zero based index of the
- ** Ravlin 45/PCI adapter.  This interface number is used in all subsequent API
- ** calls to identify which adpapter for which the function is intended.  
- ** Up to sixteen interfaces are supported with this API.
- **
- ** Inputs:  AdapterID - interface number from 0 to 15
- **          pciBaseAddr - virual base address of PCI (set by BIOS)
- **          p_msgbuf - virual address to private message block (min. 16K)
- **          p_phymsgbuf - physical address of private message block
- **          TransmitCallbackFunction - address of user's TX callback function
- **          ReceiveCallbackFunction  - address of user's RX callback function
- **
- */
-RC_RETURN InitRCApiMsgLayer(U16 AdapterID, U32 pciBaseAddr, 
-                            PU8 p_msgbuf,  PU8 p_phymsgbuf,
-                            PFNTXCALLBACK TransmitCallbackFunction,
-                            PFNRXCALLBACK ReceiveCallbackFunction,
-                            PFNCALLBACK   RebootCallbackFunction);
-
- /*
- ** RCSetRavlinIPandMask()
- **
- ** Set the Ravlin 45/PCI cards IP address and network mask.
- **
- ** IP address and mask must be in network byte order.
- ** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
- ** 0x04030201 and 0x00FFFFFF on a little endian machine.
- **
- */
-RC_RETURN RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask);
-
-
-/*
-** =========================================================================
-** RCGetRavlinIPandMask()
-**
-** get the IP address and MASK from the card
-** 
-** =========================================================================
-*/
-RC_RETURN
-RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, 
-                        PFNWAITCALLBACK WaitCallback);
-
- /* 
- ** RCProcMsgQ()
- ** 
- ** Called from user's polling loop or Interrupt Service Routine for a PCI 
- ** interrupt from the RedCreek PCI adapter.  User responsible for determining
- ** and hooking the PCI interrupt. This function will call the registered
- ** callback functions, TransmitCallbackFunction or ReceiveCallbackFunction,
- ** if a TX or RX transaction has completed.
- */
-void RCProcMsgQ(U16 AdapterID);
-
-
- /*
- ** Disable and Enable Adapter interrupts.  Adapter interrupts are enabled at 
- ** Init time but can be disabled and re-enabled through these two function calls.
- ** Packets will still be put into any posted recieved buffers and packets will
- ** be sent through RCSendPacket() functions.  Disabling Adapter interrupts
- ** will prevent hardware interrupt to host even though the outbound msg
- ** queue is not emtpy.
- */
-RC_RETURN RCEnableAdapterInterrupts(U16 adapterID);
-RC_RETURN RCDisableAdapterInterrupts(U16 AdapterID);
-
-
- /* 
- ** RCPostRecvBuffers()
- ** 
- ** Post user's page locked buffers for use by the PCI adapter to
- ** return ethernet packets received from the LAN.  Transaction Control Block,
- ** provided by user, contains buffer descriptor(s) which includes a buffer
- ** context number along with buffer size and physical address.  See TCB above.
- ** The buffer context and actual packet length are returned to the 
- ** ReceiveCallbackFunction when packets have been received.  Buffers posted
- ** to the RedCreek adapter are considered owned by the adapter until the
- ** context is return to user through the ReceiveCallbackFunction.
- */
-RC_RETURN RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransactionCtrlBlock);
-#define MAX_NMBR_POST_BUFFERS_PER_MSG 32
-
- /*
- ** RCSendPacket()
- ** 
- ** Send user's ethernet packet from a locked page buffer.  
- ** Packet must have full MAC header, however without a CRC.  
- ** Initiator context is a user provided value that is returned 
- ** to the TransmitCallbackFunction when packet buffer is free.
- ** Transmit buffer are considered owned by the adapter until context's
- ** returned to user through the TransmitCallbackFunction.
- */
-RC_RETURN RCSendPacket(U16 AdapterID, 
-                          U32 context, 
-                          PRCTCB pTransactionCtrlBlock);
-
-
- /* Ethernet Link Statistics structure */
-typedef struct tag_RC_link_stats
-{
-    U32 TX_good;      /* good transmit frames */
-    U32 TX_maxcol;    /* frames not TX due to MAX collisions */
-    U32 TX_latecol;   /* frames not TX due to late collisions */
-    U32 TX_urun;      /* frames not TX due to DMA underrun */
-    U32 TX_crs;       /* frames TX with lost carrier sense */
-    U32 TX_def;       /* frames deferred due to activity on link */
-    U32 TX_singlecol; /* frames TX with one and only on collision */
-    U32 TX_multcol;   /* frames TX with more than one collision */
-    U32 TX_totcol;    /* total collisions detected during TX */
-    U32 Rcv_good;     /* good frames received */
-    U32 Rcv_CRCerr;   /* frames RX and discarded with CRC errors */
-    U32 Rcv_alignerr; /* frames RX with alignment and CRC errors */
-    U32 Rcv_reserr;   /* good frames discarded due to no RX buffer */
-    U32 Rcv_orun;     /* RX frames lost due to FIFO overrun */
-    U32 Rcv_cdt;      /* RX frames with collision during RX */
-    U32 Rcv_runt;     /* RX frames shorter than 64 bytes */
-}
- RCLINKSTATS, *P_RCLINKSTATS;
-
- /*
- ** RCGetLinkStatistics()
- **
- ** Returns link statistics in user's structure at address StatsReturnAddr
- ** If given, not NULL, the function WaitCallback is called during the wait
- ** loop while waiting for the adapter to respond.
- */
-RC_RETURN RCGetLinkStatistics(U16 AdapterID,
-                              P_RCLINKSTATS StatsReturnAddr,
-                              PFNWAITCALLBACK WaitCallback);
-
- /*
- ** RCGetLinkStatus()
- **
- ** Return link status, up or down, to user's location addressed by ReturnAddr.
- ** If given, not NULL, the function WaitCallback is called during the wait
- ** loop while waiting for the adapter to respond.
- */
-RC_RETURN RCGetLinkStatus(U16 AdapterID, 
-                          PU32 pReturnStatus,
-                          PFNWAITCALLBACK WaitCallback);
-                               
- /* Link Status defines - value returned in pReturnStatus */
-#define LAN_LINK_STATUS_DOWN     0
-#define LAN_LINK_STATUS_UP       1
-
- /*
- ** RCGetMAC()
- **
- ** Get the current MAC address assigned to user.  RedCreek Ravlin 45/PCI 
- ** has two MAC addresses.  One which is private to the PCI Card, and 
- ** another MAC which is given to the user as its link layer MAC address. The
- ** adapter runs in promiscous mode because of the dual address requirement.
- ** The MAC address is returned to the unsigned char array pointer to by mac.
- */
-RC_RETURN RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback);
-
- /*
- ** RCSetMAC()
- **
- ** Set a new user port MAC address.  This address will be returned on
- ** subsequent RCGetMAC() calls.
- */
-RC_RETURN RCSetMAC(U16 AdapterID, PU8 mac);
-
- /*
- ** RCSetLinkSpeed()
- **
- ** set adapter's link speed based on given input code.
- */
-RC_RETURN RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode);
- /* Set link speed codes */
-#define LNK_SPD_AUTO_NEG_NWAY   0
-#define LNK_SPD_100MB_FULL      1
-#define LNK_SPD_100MB_HALF      2
-#define LNK_SPD_10MB_FULL       3
-#define LNK_SPD_10MB_HALF       4
-
-
-
-
- /*
- ** RCGetLinkSpeed()
- **
- ** Return link speed code.
- */
- /* Return link speed codes */
-#define LNK_SPD_UNKNOWN         0
-#define LNK_SPD_100MB_FULL      1
-#define LNK_SPD_100MB_HALF      2
-#define LNK_SPD_10MB_FULL       3
-#define LNK_SPD_10MB_HALF       4
-
-RC_RETURN
-RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback);
-
-/*
-** =========================================================================
-** RCReportDriverCapability(U16 AdapterID, U32 capability)
-**
-** Currently defined bits:
-** WARM_REBOOT_CAPABLE   0x01
-**
-** =========================================================================
-*/
-RC_RETURN
-RCReportDriverCapability(U16 AdapterID, U32 capability);
-
-/*
-** RCGetFirmwareVer()
-**
-** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
-**
-** WARNING: user's space pointed to by pFirmString should be at least 60 bytes.
-*/
-RC_RETURN
-RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback);
-
-/*
-** ----------------------------------------------
-** LAN adapter Reset and Shutdown functions
-** ----------------------------------------------
-*/
- /* resource flag bit assignments for RCResetLANCard() & RCShutdownLANCard() */
-#define RC_RESOURCE_RETURN_POSTED_RX_BUCKETS  0x0001 
-#define RC_RESOURCE_RETURN_PEND_TX_BUFFERS    0x0002
-
- /*
- ** RCResetLANCard()
- **
- ** Reset LAN card operation.  Causes a software reset of the ethernet
- ** controller and restarts the command and receive units. Depending on 
- ** the ResourceFlags given, the buffers are either returned to the
- ** host with reply status of RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER and
- ** detailed status of RC_DSC_CANCELED (new receive buffers must be
- ** posted after issuing this) OR the buffers are kept and reused by
- ** the ethernet controller. If CallbackFunction is not NULL, the function
- ** will be called when the reset is complete.  If the CallbackFunction is
- ** NULL,a 1 will be put into the ReturnAddr after waiting for the reset 
- ** to complete (please disable adapter interrupts during this method).
- ** Any outstanding transmit or receive buffers that are complete will be
- ** returned via the normal reply messages before the requested resource
- ** buffers are returned.
- ** A call to RCPostRecvBuffers() is needed to return the ethernet to full
- ** operation if the receive buffers were returned during LANReset.
- ** Note: The IOP status is not affected by a LAN reset.
- */
-RC_RETURN RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
-
-
- /*
- ** RCShutdownLANCard()
- **
- ** Shutdown LAN card operation and put into an idle (suspended) state.
- ** The LAN card is restarted with RCResetLANCard() function.
- ** Depending on the ResourceFlags given, the buffers are either returned 
- ** to the host with reply status of RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 
- ** and detailed status of RC_DSC_CANCELED (new receive buffers must be
- ** posted after issuing this) OR the buffers are kept and reused by
- ** the ethernet controller. If CallbackFunction is not NULL, the function
- ** will be called when the reset is complete.  If the CallbackFunction is
- ** NULL,a 1 will be put into the ReturnAddr after waiting for the reset 
- ** to complete (please disable adapter interrupts during this method).
- ** Any outstanding transmit or receive buffers that are complete will be
- ** returned via the normal reply messages before the requested resource
- ** buffers are returned.
- ** Note: The IOP status is not affected by a LAN shutdown.
- */                                      
-RC_RETURN 
-RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction);
-
- /*
- ** RCResetAdapter();
- **     Initializes ADAPTERState to ADAPTER_STATE_RESET.
- **     Stops access to outbound message Q.
- **     Discards any outstanding transmit or posted receive buffers.
- **     Clears outbound message Q. 
- */
-RC_RETURN 
-RCResetAdapter(U16 AdapterID);
-
-#endif /* RCMTL_H */
index f53e024f0a06d8912376bc86b3fff65602f78041..2c5a070eef8eda1ed774fd491231fd3e12e2453d 100644 (file)
@@ -4,7 +4,7 @@
 **
 **
 **  ---------------------------------------------------------------------
-**  ---     Copyright (c) 1998, RedCreek Communications Inc.          ---
+**  ---     Copyright (c) 1998, 1999, RedCreek Communications Inc.    ---
 **  ---                   All rights reserved.                        ---
 **  ---------------------------------------------------------------------
 **
 **
 ** Known Problems
 ** 
-** Billions and Billions...  
-**
-** ... apparently added by Brian.  Pete knows of no bugs.
+** None known at this time.
 **
 **  TODO:
 **      -Get rid of the wait loops in the API and replace them
 **       with system independent delays ...something like
-**       "delayms(2)".
+**       "delayms(2)".  However, under normal circumstances, the 
+**       delays are very short so they're not a problem.
 **
 **  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
 **  along with this program; if not, write to the Free Software
 **  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 **
+**   
+**  Pete Popov, January 11,99: Fixed a couple of 2.1.x problems 
+**  (virt_to_bus() not called), tested it under 2.2pre5, and added a 
+**  #define to enable the use of the same file for both, the 2.0.x kernels 
+**  as well as the 2.1.x.
+**
+**  Ported to 2.1.x by Alan Cox 1998/12/9. 
+**
 ***************************************************************************/
 
-#define __NO_VERSION__ /* don't define kernel_verion in module.h */
-
 static char *version =
-"RedCreek Communications PCI linux driver version 1.32 Beta\n";
+"RedCreek Communications PCI linux driver version 2.00\n";
 
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/version.h>
 #include <linux/kernel.h>
@@ -62,25 +66,34 @@ static char *version =
 #include <asm/bitops.h>
 #include <asm/io.h>
 
+#if LINUX_VERSION_CODE >= 0x020100
+#define LINUX_2_1
+#endif
+
+#ifdef LINUX_2_1
+#include <asm/uaccess.h>
+#endif
+
 #include <linux/if_ether.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
 
+
 #define RC_LINUX_MODULE
-#include "rcmtl.h"
+#include "rclanmtl.h"
 #include "rcif.h"
 
 #define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
-
-#define FREE_IRQ(irqnum, dev) free_irq(irqnum)
-#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n)
-#define IRQ(irq, dev_id, pt_regs) (irq, pt_regs)
 
 #define NEW_MULTICAST
 #include <linux/delay.h>
 
+#ifndef LINUX_2_1
+#define ioremap vremap
+#define iounmap vfree
+#endif
+
 /* PCI/45 Configuration space values */
 #define RC_PCI45_VENDOR_ID  0x4916
 #define RC_PCI45_DEVICE_ID  0x1960
@@ -108,25 +121,25 @@ static void rc_timer(unsigned long);
 typedef struct
 {
 
-     /* 
-      *    pointer to the device structure which is part
-      * of the interface to the Linux kernel.
-      */
-      struct device *dev;            
+    /* 
+     *    pointer to the device structure which is part
+     * of the interface to the Linux kernel.
+     */
+    struct device *dev;            
      
-     char devname[8];                /* "ethN" string */
-     U8     id;                        /* the AdapterID */
-     U32    pci_addr;               /* the pci address of the adapter */
-     U32    bus;
-     U32    function;
-     struct timer_list timer;        /*  timer */
-     struct enet_statistics  stats; /* the statistics structure */
-     struct device *next;            /* points to the next RC adapter */
-     unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/
-     unsigned char shutdown;
-     unsigned char reboot;
-     unsigned char nexus;
-     PU8    PLanApiPA;             /* Pointer to Lan Api Private Area */
+    char devname[8];                /* "ethN" string */
+    U8     id;                        /* the AdapterID */
+    U32    pci_addr;               /* the pci address of the adapter */
+    U32    bus;
+    U32    function;
+    struct timer_list timer;        /*  timer */
+    struct enet_statistics  stats; /* the statistics structure */
+    struct device *next;            /* points to the next RC adapter */
+    unsigned long numOutRcvBuffers;/* number of outstanding receive buffers*/
+    unsigned char shutdown;
+    unsigned char reboot;
+    unsigned char nexus;
+    PU8    PLanApiPA;             /* Pointer to Lan Api Private Area */
 
 }
 DPA, *PDPA;
@@ -135,10 +148,10 @@ DPA, *PDPA;
 
 static PDPA  PCIAdapters[MAX_ADAPTERS] = 
 {
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
-     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
 
@@ -167,261 +180,261 @@ static struct device *root_RCdev = NULL;
 #ifdef MODULE
 int init_module(void)
 #else
-int rcpci_probe(struct device *dev)
+int rcpci_probe(struct netdevice *dev)
 #endif
 {
-     int cards_found;
+    int cards_found;
 
-     printk(version);
+    printk(version);
 
-     root_RCdev = NULL;
-     cards_found = RCscan();
-#ifdef MODULE     
-     return cards_found ? 0 : -ENODEV;
+    root_RCdev = NULL;
+    cards_found = RCscan();
+#ifdef MODULE
+    return cards_found ? 0 : -ENODEV;
 #else
-     return -1;
-#endif          
+    return -1;
+#endif
 }
 
-static int RCscan(void)
+static int RCscan()
 {
-     int cards_found = 0;
-     struct device *dev = 0;
-
-     if (pcibios_present()) 
-     {
-          static int pci_index = 0;
-          unsigned char pci_bus, pci_device_fn;
-          int scan_status;
-          int board_index = 0;
-
-          for (;pci_index < 0xff; pci_index++) 
-          {
-               unsigned char pci_irq_line;
-               unsigned short pci_command, vendor, device, class;
-               unsigned int pci_ioaddr;
-
-
-               scan_status =  
-                    (pcibios_find_device (RC_PCI45_VENDOR_ID, 
-                                          RC_PCI45_DEVICE_ID, 
-                                          pci_index, 
-                                          &pci_bus, 
-                                          &pci_device_fn));
+    int cards_found = 0;
+    struct device *dev = 0;
+
+    if (pcibios_present()) 
+    {
+        static int pci_index = 0;
+        unsigned char pci_bus, pci_device_fn;
+        int scan_status;
+        int board_index = 0;
+
+        for (;pci_index < 0xff; pci_index++) 
+        {
+            unsigned char pci_irq_line;
+            unsigned short pci_command, vendor, device, class;
+            unsigned int pci_ioaddr;
+
+
+            scan_status =  
+                (pcibios_find_device (RC_PCI45_VENDOR_ID, 
+                                      RC_PCI45_DEVICE_ID, 
+                                      pci_index, 
+                                      &pci_bus, 
+                                      &pci_device_fn));
 #ifdef RCDEBUG
-               printk("rc scan_status = 0x%X\n", scan_status);
+            printk("rc scan_status = 0x%X\n", scan_status);
 #endif
-               if (scan_status != PCIBIOS_SUCCESSFUL)
-                    break;
-               pcibios_read_config_word(pci_bus, 
-                                        pci_device_fn, 
-                                        PCI_VENDOR_ID, &vendor);
-               pcibios_read_config_word(pci_bus, 
-                                        pci_device_fn,
-                                        PCI_DEVICE_ID, &device);
-               pcibios_read_config_byte(pci_bus, 
-                                        pci_device_fn,
-                                        PCI_INTERRUPT_LINE, &pci_irq_line);
-               pcibios_read_config_dword(pci_bus, 
-                                         pci_device_fn,
-                                         PCI_BASE_ADDRESS_0, &pci_ioaddr);
-               pcibios_read_config_word(pci_bus, 
-                                        pci_device_fn,
-                                        PCI_CLASS_DEVICE, &class);
-
-               pci_ioaddr &= ~0xf;
+            if (scan_status != PCIBIOS_SUCCESSFUL)
+                break;
+            pcibios_read_config_word(pci_bus, 
+                                     pci_device_fn, 
+                                     PCI_VENDOR_ID, &vendor);
+            pcibios_read_config_word(pci_bus, 
+                                     pci_device_fn,
+                                     PCI_DEVICE_ID, &device);
+            pcibios_read_config_byte(pci_bus, 
+                                     pci_device_fn,
+                                     PCI_INTERRUPT_LINE, &pci_irq_line);
+            pcibios_read_config_dword(pci_bus, 
+                                      pci_device_fn,
+                                      PCI_BASE_ADDRESS_0, &pci_ioaddr);
+            pcibios_read_config_word(pci_bus, 
+                                     pci_device_fn,
+                                     PCI_CLASS_DEVICE, &class);
+
+            pci_ioaddr &= ~0xf;
 
 #ifdef RCDEBUG
-               printk("rc: Found RedCreek PCI adapter\n");
-               printk("rc: pci class = 0x%x  0x%x \n", class, class>>8);
-               printk("rc: pci_bus = %d,  pci_device_fn = %d\n", pci_bus, pci_device_fn);
-               printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
-               printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
+            printk("rc: Found RedCreek PCI adapter\n");
+            printk("rc: pci class = 0x%x  0x%x \n", class, class>>8);
+            printk("rc: pci_bus = %d,  pci_device_fn = %d\n", pci_bus, pci_device_fn);
+            printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
+            printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
 #endif
 
-#if 0
-               if (check_region(pci_ioaddr, 32768))
-               {
-                    printk("rc: check_region failed\n");
-                    continue;
-               }
-               else
-               {
-                    printk("rc: check_region passed\n");
-               }
+#if 1
+            if (check_region(pci_ioaddr, 2*32768))
+            {
+                printk("rc: check_region failed\n");
+                continue;
+            }
+            else
+            {
+                printk("rc: check_region passed\n");
+            }
 #endif
                
-                /*
-                 * Get and check the bus-master and latency values.
-                 * Some PCI BIOSes fail to set the master-enable bit.
-                 */
-
-                pcibios_read_config_word(pci_bus, 
-                                         pci_device_fn,
-                                         PCI_COMMAND, 
-                                         &pci_command);
-                if ( ! (pci_command & PCI_COMMAND_MASTER)) {
-                     printk("rc: PCI Master Bit has not been set!\n");
+            /*
+             * Get and check the bus-master and latency values.
+             * Some PCI BIOSes fail to set the master-enable bit.
+             */
+
+            pcibios_read_config_word(pci_bus, 
+                                     pci_device_fn,
+                                     PCI_COMMAND, 
+                                     &pci_command);
+            if ( ! (pci_command & PCI_COMMAND_MASTER)) {
+                printk("rc: PCI Master Bit has not been set!\n");
                             
-                     pci_command |= PCI_COMMAND_MASTER;
-                     pcibios_write_config_word(pci_bus, 
-                                               pci_device_fn,
-                                               PCI_COMMAND, 
-                                               pci_command);
-                }
-                if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
+                pci_command |= PCI_COMMAND_MASTER;
+                pcibios_write_config_word(pci_bus, 
+                                          pci_device_fn,
+                                          PCI_COMMAND, 
+                                          pci_command);
+            }
+            if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
                 /*
                  * If the BIOS did not set the memory enable bit, what else
                  * did it not initialize?  Skip this adapter.
                  */
-                     printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
-                         cards_found);
-                     printk("rc: Bios problem? \n");
-                     continue;
-                }
+                printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
+                       cards_found);
+                printk("rc: Bios problem? \n");
+                continue;
+            }
                     
-               dev = RCfound_device(dev, pci_ioaddr, pci_irq_line,
-                                    pci_bus, pci_device_fn,
-                                    board_index++, cards_found);
-
-               if (dev) {
-                    dev = 0;
-                    cards_found++;
-               }
-          }
-     }
-     printk("rc: found %d cards \n", cards_found);
-     return cards_found;
+            dev = RCfound_device(dev, pci_ioaddr, pci_irq_line,
+                                 pci_bus, pci_device_fn,
+                                 board_index++, cards_found);
+
+            if (dev) {
+                dev = 0;
+                cards_found++;
+            }
+        }
+    }
+    printk("rc: found %d cards \n", cards_found);
+    return cards_found;
 }
 
 static struct device *
 RCfound_device(struct device *dev, int memaddr, int irq, 
                int bus, int function, int product_index, int card_idx)
 {
-     int dev_size = 32768;        
-     unsigned long *vaddr=0;
-     PDPA pDpa;
-     int init_status;
-
-     /* 
-      * Allocate and fill new device structure. 
-      * We need enough for struct device plus DPA plus the LAN API private
-      * area, which requires a minimum of 16KB.  The top of the allocated
-      * area will be assigned to struct device; the next chunk will be
-      * assigned to DPA; and finally, the rest will be assigned to the
-      * the LAN API layer.
-      */
-     dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
-     memset(dev, 0, dev_size);
+    int dev_size = 32768;        
+    unsigned long *vaddr=0;
+    PDPA pDpa;
+    int init_status;
+
+    /* 
+     * Allocate and fill new device structure. 
+     * We need enough for struct device plus DPA plus the LAN API private
+     * area, which requires a minimum of 16KB.  The top of the allocated
+     * area will be assigned to struct device; the next chunk will be
+     * assigned to DPA; and finally, the rest will be assigned to the
+     * the LAN API layer.
+     */
+    dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+    memset(dev, 0, dev_size);
 #ifdef RCDEBUG
-     printk("rc: dev = 0x%08X\n", (uint)dev);
+    printk("rc: dev = 0x%08X\n", (uint)dev);
 #endif 
 
-     /*
-      * dev->priv will point to the start of DPA.
-      */
-     dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
-     pDpa = dev->priv;
-     dev->name = pDpa->devname;
-
-     pDpa->dev = dev;            /* this is just for easy reference */
-     pDpa->function = function;
-     pDpa->bus = bus;
-     pDpa->id = card_idx;        /* the device number */
-     pDpa->pci_addr = memaddr;
-     PCIAdapters[card_idx] = pDpa;
+    /*
+     * dev->priv will point to the start of DPA.
+     */
+    dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
+    pDpa = dev->priv;
+    dev->name = pDpa->devname;
+
+    pDpa->dev = dev;            /* this is just for easy reference */
+    pDpa->function = function;
+    pDpa->bus = bus;
+    pDpa->id = card_idx;        /* the device number */
+    pDpa->pci_addr = memaddr;
+    PCIAdapters[card_idx] = pDpa;
 #ifdef RCDEBUG
-     printk("rc: pDpa = 0x%x, id = %d \n", (uint)pDpa, (uint)pDpa->id);
+    printk("rc: pDpa = 0x%x, id = %d \n", (uint)pDpa, (uint)pDpa->id);
 #endif
 
-     /*
-      * Save the starting address of the LAN API private area.  We'll
-      * pass that to InitRCApiMsgLayer().
-      */
-     pDpa->PLanApiPA = (void *)(((long)pDpa + sizeof(DPA) + 0xff) & ~0xff);
+    /*
+     * Save the starting address of the LAN API private area.  We'll
+     * pass that to RCInitI2OMsgLayer().
+     */
+    pDpa->PLanApiPA = (void *)(((long)pDpa + sizeof(DPA) + 0xff) & ~0xff);
 #ifdef RCDEBUG
-     printk("rc: pDpa->PLanApiPA = 0x%x\n", (uint)pDpa->PLanApiPA);
+    printk("rc: pDpa->PLanApiPA = 0x%x\n", (uint)pDpa->PLanApiPA);
 #endif
     
-     /* The adapter is accessable through memory-access read/write, not
-      * I/O read/write.  Thus, we need to map it to some virtual address
-      * area in order to access the registers are normal memory.
-      */
-     vaddr = (ulong *) vremap (memaddr, 32768);
+    /* The adapter is accessable through memory-access read/write, not
+     * I/O read/write.  Thus, we need to map it to some virtual address
+     * area in order to access the registers are normal memory.
+     */
+    vaddr = (ulong *) ioremap (memaddr, 2*32768);
 #ifdef RCDEBUG
-     printk("rc: RCfound_device: 0x%x, priv = 0x%x, vaddr = 0x%x\n", 
-            (uint)dev, (uint)dev->priv, (uint)vaddr);
+    printk("rc: RCfound_device: 0x%x, priv = 0x%x, vaddr = 0x%x\n", 
+           (uint)dev, (uint)dev->priv, (uint)vaddr);
 #endif
-     dev->base_addr = (unsigned long)vaddr;
-     dev->irq = irq;
-     dev->interrupt = 0;
+    dev->base_addr = (unsigned long)vaddr;
+    dev->irq = irq;
+    dev->interrupt = 0;
+
+    /*
+     * Request a shared interrupt line.
+     */
+    if ( request_irq(dev->irq, (void *)RCinterrupt,
+                     SA_INTERRUPT|SA_SHIRQ, "RedCreek VPN Adapter", dev) )
+    {
+        printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
+        iounmap(vaddr);
+        kfree(dev);
+        return 0;
+    }
 
-     /*
-      * Request a shared interrupt line.
-      */
-     if ( request_irq(dev->irq, (void *)RCinterrupt,
-                      SA_INTERRUPT|SA_SHIRQ, "RedCreek VPN Adapter", dev) )
-     {
-          printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
-          vfree(vaddr);
-          kfree(dev);
-           return 0;
-     }
-
-     init_status = InitRCApiMsgLayer(pDpa->id, dev->base_addr, 
-                                     pDpa->PLanApiPA, pDpa->PLanApiPA,
-                                     (PFNTXCALLBACK)RCxmit_callback,
-                                     (PFNRXCALLBACK)RCrecv_callback,
-                                     (PFNCALLBACK)RCreboot_callback);
+    init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, 
+                                    pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+                                    (PFNTXCALLBACK)RCxmit_callback,
+                                    (PFNRXCALLBACK)RCrecv_callback,
+                                    (PFNCALLBACK)RCreboot_callback);
 #ifdef RCDEBUG
-     printk("rc: msg initted: status = 0x%x\n", init_status);
+    printk("rc: I2O msg initted: status = 0x%x\n", init_status);
 #endif
-     if (init_status)
-     {
-          printk("rc: Unable to initialize msg layer\n");
-          free_irq(dev->irq, dev);
-          vfree(vaddr);
-          kfree(dev);
-          return 0;
-     }
-     if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
-     {
-          printk("rc: Unable to get adapter MAC\n");
-          free_irq(dev->irq, dev);
-          vfree(vaddr);
-          kfree(dev);
-          return 0;
-     }
-
-     DriverControlWord |= WARM_REBOOT_CAPABLE;
-     RCReportDriverCapability(pDpa->id, DriverControlWord);
-
-     dev->init = RCprobe1;
-     ether_setup(dev);            /* linux kernel interface */
-
-     pDpa->next = root_RCdev;
-     root_RCdev = dev;
-
-     if (register_netdev(dev) != 0) /* linux kernel interface */
-     {
-          printk("rc: unable to register device \n");
-          free_irq(dev->irq, dev);
-          vfree(vaddr);
-          kfree(dev);
-          return 0;
-     }
-     return dev;
+    if (init_status)
+    {
+        printk("rc: Unable to initialize msg layer\n");
+        free_irq(dev->irq, dev);
+        iounmap(vaddr);
+        kfree(dev);
+        return 0;
+    }
+    if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
+    {
+        printk("rc: Unable to get adapter MAC\n");
+        free_irq(dev->irq, dev);
+        iounmap(vaddr);
+        kfree(dev);
+        return 0;
+    }
+
+    DriverControlWord |= WARM_REBOOT_CAPABLE;
+    RCReportDriverCapability(pDpa->id, DriverControlWord);
+
+    dev->init = RCprobe1;
+    ether_setup(dev);            /* linux kernel interface */
+
+    pDpa->next = root_RCdev;
+    root_RCdev = dev;
+
+    if (register_netdev(dev) != 0) /* linux kernel interface */
+    {
+        printk("rc: unable to register device \n");
+        free_irq(dev->irq, dev);
+        iounmap(vaddr);
+        kfree(dev);
+        return 0;
+    }
+    return dev;
 }
 
 static int RCprobe1(struct device *dev)
 {
-     dev->open = RCopen;
-     dev->hard_start_xmit = RC_xmit_packet;
-     dev->stop = RCclose;
-     dev->get_stats = RCget_stats;
-     dev->do_ioctl = RCioctl;
-     dev->set_config = RCconfig;
-     return 0;
+    dev->open = RCopen;
+    dev->hard_start_xmit = RC_xmit_packet;
+    dev->stop = RCclose;
+    dev->get_stats = RCget_stats;
+    dev->do_ioctl = RCioctl;
+    dev->set_config = RCconfig;
+    return 0;
 }
 
 static int
@@ -435,25 +448,25 @@ RCopen(struct device *dev)
 #ifdef RCDEBUG
     printk("rc: RCopen\n");
 #endif
-    RCEnableAdapterInterrupts(pDpa->id);
+    RCEnableI2OInterrupts(pDpa->id);
 
     if (pDpa->nexus)
     {
-       /* This is not the first time RCopen is called.  Thus,
-        * the interface was previously opened and later closed
-        * by RCclose().  RCclose() does a Shutdown; to wake up
-        * the adapter, a reset is mandatory before we can post
-        * receive buffers.  However, if the adapter initiated 
-        * a reboot while the interface was closed -- and interrupts
-        * were turned off -- we need will need to reinitialize
-        * the adapter, rather than simply waking it up.  
-        */
+        /* This is not the first time RCopen is called.  Thus,
+         * the interface was previously opened and later closed
+         * by RCclose().  RCclose() does a Shutdown; to wake up
+         * the adapter, a reset is mandatory before we can post
+         * receive buffers.  However, if the adapter initiated 
+         * a reboot while the interface was closed -- and interrupts
+         * were turned off -- we need will need to reinitialize
+         * the adapter, rather than simply waking it up.  
+         */
         printk("rc: Waking up adapter...\n");
         RCResetLANCard(pDpa->id,0,0,0);
     }
     else
     {
-       pDpa->nexus = 1;
+        pDpa->nexus = 1;
     }
 
     while(post_buffers)
@@ -466,19 +479,19 @@ RCopen(struct device *dev)
 
         if ( count < requested )
         {
-             /*
-              * Check to see if we were able to post any buffers at all.
-              */
-             if (post_buffers == MAX_NMBR_RCV_BUFFERS)
-             {
-                  printk("rc: Error RCopen: not able to allocate any buffers\r\n");
-                  return(-ENOMEM);                    
-             }
-             printk("rc: Warning RCopen: not able to allocate all requested buffers\r\n");
-             break;            /* we'll try to post more buffers later */
+            /*
+             * Check to see if we were able to post any buffers at all.
+             */
+            if (post_buffers == MAX_NMBR_RCV_BUFFERS)
+            {
+                printk("rc: Error RCopen: not able to allocate any buffers\r\n");
+                return(-ENOMEM);                    
+            }
+            printk("rc: Warning RCopen: not able to allocate all requested buffers\r\n");
+            break;            /* we'll try to post more buffers later */
         }
         else
-             post_buffers -= count;
+            post_buffers -= count;
     }
     pDpa->numOutRcvBuffers = MAX_NMBR_RCV_BUFFERS - post_buffers;
     pDpa->shutdown = 0;        /* just in case */
@@ -493,68 +506,69 @@ static int
 RC_xmit_packet(struct sk_buff *skb, struct device *dev)
 {
 
-     PDPA pDpa = (PDPA) dev->priv;
-     singleTCB tcb;
-     psingleTCB ptcb = &tcb;
-     RC_RETURN status = 0;
+    PDPA pDpa = (PDPA) dev->priv;
+    singleTCB tcb;
+    psingleTCB ptcb = &tcb;
+    RC_RETURN status = 0;
     
-     if (dev->tbusy || pDpa->shutdown || pDpa->reboot)
-     {
+        if (dev->tbusy || pDpa->shutdown || pDpa->reboot)
+        {
 #ifdef RCDEBUG
-          printk("rc: RC_xmit_packet: tbusy!\n");
+            printk("rc: RC_xmit_packet: tbusy!\n");
 #endif
-          return 1;
-     }
+            return 1;
+        }
       
-     if ( skb->len <= 0 ) 
-     {
-          printk("RC_xmit_packet: skb->len less than 0!\n");
-          return 0;
-     }
-
-     /*
-      * The user is free to reuse the TCB after RCSendPacket() returns, since
-      * the function copies the necessary info into its own private space.  Thus,
-      * our TCB can be a local structure.  The skb, on the other hand, will be
-      * freed up in our interrupt handler.
-      */
-     ptcb->bcount = 1;
-     /* 
-      * we'll get the context when the adapter interrupts us to tell us that
-      * the transmision is done. At that time, we can free skb.
-      */
-     ptcb->b.context = (U32)skb;    
-     ptcb->b.scount = 1;
-     ptcb->b.size = skb->len;
-     ptcb->b.addr = (U32)skb->data;
+    if ( skb->len <= 0 ) 
+    {
+        printk("RC_xmit_packet: skb->len less than 0!\n");
+        return 0;
+    }
+
+    /*
+     * The user is free to reuse the TCB after RCI2OSendPacket() returns, since
+     * the function copies the necessary info into its own private space.  Thus,
+     * our TCB can be a local structure.  The skb, on the other hand, will be
+     * freed up in our interrupt handler.
+     */
+    ptcb->bcount = 1;
+    /* 
+     * we'll get the context when the adapter interrupts us to tell us that
+     * the transmision is done. At that time, we can free skb.
+     */
+    ptcb->b.context = (U32)skb;    
+    ptcb->b.scount = 1;
+    ptcb->b.size = skb->len;
+    ptcb->b.addr = virt_to_bus((void *)skb->data);
 
 #ifdef RCDEBUG
-     printk("rc: RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n", 
-            (uint)skb, (uint)pDpa, (uint)pDpa->id, (uint)ptcb);
+    printk("rc: RC xmit: skb = 0x%x, pDpa = 0x%x, id = %d, ptcb = 0x%x\n", 
+           (uint)skb, (uint)pDpa, (uint)pDpa->id, (uint)ptcb);
 #endif
-     if ( (status = RCSendPacket(pDpa->id, (U32)NULL, (PRCTCB)ptcb))
-          != RC_RTN_NO_ERROR)
-     {
+    if ( (status = RCI2OSendPacket(pDpa->id, (U32)NULL, (PRCTCB)ptcb))
+         != RC_RTN_NO_ERROR)
+    {
 #ifdef RCDEBUG
-          printk("rc: RC send error 0x%x\n", (uint)status);
+        printk("rc: RC send error 0x%x\n", (uint)status);
 #endif
-          dev->tbusy = 1;
-     }
-     else
-     {
-          dev->trans_start = jiffies;
-          //       dev->tbusy = 0;
-     }
-     /*
-      * That's it!
-      */
-     return 0;
+        dev->tbusy = 1;
+        return 1;
+    }
+    else
+    {
+        dev->trans_start = jiffies;
+        //       dev->tbusy = 0;
+    }
+    /*
+     * That's it!
+     */
+    return 0;
 }
 
 /*
  * RCxmit_callback()
  *
- * The transmit callback routine. It's called by RCProcMsgQ()
+ * The transmit callback routine. It's called by RCProcI2OMsgQ()
  * because the adapter is done with one or more transmit buffers and
  * it's returning them to us, or we asked the adapter to return the
  * outstanding transmit buffers by calling RCResetLANCard() with 
@@ -571,80 +585,84 @@ RCxmit_callback(U32 Status,
     PDPA pDpa;
     struct device *dev;
 
-    pDpa = PCIAdapters[AdapterID];
-    if (!pDpa)
-    {
-        printk("rc: Fatal error: xmit callback, !pDpa\n");
-        return;
-    }
-    dev = pDpa->dev;
+        pDpa = PCIAdapters[AdapterID];
+        if (!pDpa)
+        {
+            printk("rc: Fatal error: xmit callback, !pDpa\n");
+            return;
+        }
+        dev = pDpa->dev;
 
         // printk("xmit_callback: Status = 0x%x\n", (uint)Status);
-    if (Status != RC_REPLY_STATUS_SUCCESS)
-    {
-        printk("rc: xmit_callback: Status = 0x%x\n", (uint)Status);
-    }
+        if (Status != I2O_REPLY_STATUS_SUCCESS)
+        {
+            printk("rc: xmit_callback: Status = 0x%x\n", (uint)Status);
+        }
 #ifdef RCDEBUG
-    if (pDpa->shutdown || pDpa->reboot)
-        printk("rc: xmit callback: shutdown||reboot\n");
+        if (pDpa->shutdown || pDpa->reboot)
+            printk("rc: xmit callback: shutdown||reboot\n");
 #endif
 
 #ifdef RCDEBUG     
-    printk("rc: xmit_callback: PcktCount = %d, BC = 0x%x\n", 
-            (uint)PcktCount, (uint)BufferContext);
+        printk("rc: xmit_callback: PcktCount = %d, BC = 0x%x\n", 
+               (uint)PcktCount, (uint)BufferContext);
 #endif
-    while (PcktCount--)
-    {
-        skb = (struct sk_buff *)(BufferContext[0]);
+        while (PcktCount--)
+        {
+            skb = (struct sk_buff *)(BufferContext[0]);
 #ifdef RCDEBUG
-        printk("rc: skb = 0x%x\n", (uint)skb);
+            printk("rc: skb = 0x%x\n", (uint)skb);
 #endif
-        BufferContext++;
-        dev_kfree_skb (skb, FREE_WRITE);
-    }
-    dev->tbusy = 0;
+            BufferContext++;
+#ifdef LINUX_2_1
+            dev_kfree_skb (skb);
+#else
+            dev_kfree_skb (skb, FREE_WRITE);
+#endif
+        }
+        dev->tbusy = 0;
 
 }
 
 static void
 RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
 {
-     PDPA pDpa;
-     struct device *dev;
+    PDPA pDpa;
+    struct device *dev;
      
-     pDpa = PCIAdapters[AdapterID];
-     dev = pDpa->dev;
+    pDpa = PCIAdapters[AdapterID];
+    dev = pDpa->dev;
 #ifdef RCDEBUG
-      printk("rc: RCreset_callback Status 0x%x\n", (uint)Status);
+    printk("rc: RCreset_callback Status 0x%x\n", (uint)Status);
 #endif
-      /*
-       * Check to see why we were called.
-       */
-      if (pDpa->shutdown)
-      {
-           printk("rc: Shutting down interface\n");
-           pDpa->shutdown = 0;
-           pDpa->reboot = 0;
-           MOD_DEC_USE_COUNT; 
-      }
-      else if (pDpa->reboot)
-      {
-           printk("rc: reboot, shutdown adapter\n");
-           /*
-            * We don't set any of the flags in RCShutdownLANCard()
-            * and we don't pass a callback routine to it.
-            * The adapter will have already initiated the reboot by
-            * the time the function returns.
-            */
-                  RCDisableAdapterInterrupts(pDpa->id);
-           RCShutdownLANCard(pDpa->id,0,0,0);
-           printk("rc: scheduling timer...\n");
-           init_timer(&pDpa->timer);
-           pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
-           pDpa->timer.data = (unsigned long)dev;
-           pDpa->timer.function = &rc_timer;    /* timer handler */
-           add_timer(&pDpa->timer);
-      }
+    /*
+     * Check to see why we were called.
+     */
+    if (pDpa->shutdown)
+    {
+        printk("rc: Shutting down interface\n");
+        pDpa->shutdown = 0;
+        pDpa->reboot = 0;
+        MOD_DEC_USE_COUNT; 
+    }
+    else if (pDpa->reboot)
+    {
+        printk("rc: reboot, shutdown adapter\n");
+        /*
+         * We don't set any of the flags in RCShutdownLANCard()
+         * and we don't pass a callback routine to it.
+         * The adapter will have already initiated the reboot by
+         * the time the function returns.
+         */
+        RCDisableI2OInterrupts(pDpa->id);
+        RCShutdownLANCard(pDpa->id,0,0,0);
+        printk("rc: scheduling timer...\n");
+        init_timer(&pDpa->timer);
+        pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
+        pDpa->timer.data = (unsigned long)dev;
+        pDpa->timer.function = &rc_timer;    /* timer handler */
+        add_timer(&pDpa->timer);
+    }
 
 
 
@@ -653,33 +671,33 @@ RCreset_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
 static void
 RCreboot_callback(U32 Status, U32 p1, U32 p2, U16 AdapterID)
 {
-     PDPA pDpa;
+    PDPA pDpa;
     
-     pDpa = PCIAdapters[AdapterID];
+    pDpa = PCIAdapters[AdapterID];
 #ifdef RCDEBUG
-     printk("rc: RCreboot: rcv buffers outstanding = %d\n", 
-            (uint)pDpa->numOutRcvBuffers);
+    printk("rc: RCreboot: rcv buffers outstanding = %d\n", 
+           (uint)pDpa->numOutRcvBuffers);
 #endif
-     if (pDpa->shutdown)
-     {
-          printk("rc: skipping reboot sequence -- shutdown already initiated\n");
-          return;
-     }
-     pDpa->reboot = 1;
-     /*
-      * OK, we reset the adapter and ask it to return all
-      * outstanding transmit buffers as well as the posted
-      * receive buffers.  When the adapter is done returning
-      * those buffers, it will call our RCreset_callback() 
-      * routine.  In that routine, we'll call RCShutdownLANCard()
-      * to tell the adapter that it's OK to start the reboot and
-      * schedule a timer callback routine to execute 3 seconds 
-      * later; this routine will reinitialize the adapter at that time.
-      */
-     RCResetLANCard(pDpa->id, 
-                    RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
-                    RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
-                    (PFNCALLBACK)RCreset_callback);
+    if (pDpa->shutdown)
+    {
+        printk("rc: skipping reboot sequence -- shutdown already initiated\n");
+        return;
+    }
+    pDpa->reboot = 1;
+    /*
+     * OK, we reset the adapter and ask it to return all
+     * outstanding transmit buffers as well as the posted
+     * receive buffers.  When the adapter is done returning
+     * those buffers, it will call our RCreset_callback() 
+     * routine.  In that routine, we'll call RCShutdownLANCard()
+     * to tell the adapter that it's OK to start the reboot and
+     * schedule a timer callback routine to execute 3 seconds 
+     * later; this routine will reinitialize the adapter at that time.
+     */
+    RCResetLANCard(pDpa->id, 
+                   RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
+                   RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
+                   (PFNCALLBACK)RCreset_callback);
 }
 
 
@@ -696,7 +714,7 @@ int broadcast_packet(unsigned char * address)
  * RCrecv_callback()
  * 
  * The receive packet callback routine.  This is called by
- * RCProcMsgQ() after the adapter posts buffers which have been
+ * RCProcI2OMsgQ() after the adapter posts buffers which have been
  * filled (one ethernet packet per buffer).
  */
 static void
@@ -707,134 +725,144 @@ RCrecv_callback(U32  Status,
                 U16  AdapterID)
 {
 
-     U32 len, count;
-     PDPA pDpa;
-     struct sk_buff *skb;
-     struct device *dev;
-     singleTCB tcb;
-     psingleTCB ptcb = &tcb;
+    U32 len, count;
+    PDPA pDpa;
+    struct sk_buff *skb;
+    struct device *dev;
+    singleTCB tcb;
+    psingleTCB ptcb = &tcb;
 
 
-          pDpa = PCIAdapters[AdapterID];
-          dev = pDpa->dev;
+        pDpa = PCIAdapters[AdapterID];
+        dev = pDpa->dev;
 
-          ptcb->bcount = 1;
+        ptcb->bcount = 1;
 
 #ifdef RCDEBUG
-          printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
-                 (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
+        printk("rc: RCrecv_callback: 0x%x, 0x%x, 0x%x\n",
+               (uint)PktCount, (uint)BucketsRemain, (uint)PacketDescBlock);
 #endif
         
 #ifdef RCDEBUG
-          if ((pDpa->shutdown || pDpa->reboot) && !Status)
-               printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
+        if ((pDpa->shutdown || pDpa->reboot) && !Status)
+            printk("shutdown||reboot && !Status: PktCount = %d\n",PktCount);
 #endif
 
-          if ( (Status != RC_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
-          {
-               /*
-                * Free whatever buffers the adapter returned, but don't
-                * pass them to the kernel.
-                */
+        if ( (Status != I2O_REPLY_STATUS_SUCCESS) || pDpa->shutdown)
+        {
+            /*
+             * Free whatever buffers the adapter returned, but don't
+             * pass them to the kernel.
+             */
         
-                    if (!pDpa->shutdown && !pDpa->reboot)
-                         printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
-                    else
-                         printk("rc: Returning %d buffers, status = 0x%x\n", 
-                                PktCount, (uint)Status);
-               /*
-                * TO DO: check the nature of the failure and put the adapter in
-                * failed mode if it's a hard failure.  Send a reset to the adapter
-                * and free all outstanding memory.
-                */
-               if (Status == RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
-               {
+                if (!pDpa->shutdown && !pDpa->reboot)
+                    printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
+                else
+                    printk("rc: Returning %d buffers, status = 0x%x\n", 
+                           PktCount, (uint)Status);
+            /*
+             * TO DO: check the nature of the failure and put the adapter in
+             * failed mode if it's a hard failure.  Send a reset to the adapter
+             * and free all outstanding memory.
+             */
+            if (Status == I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER)
+            {
 #ifdef RCDEBUG
-                    printk("RCrecv status ABORT NO DATA TRANSFER\n");
+                printk("RCrecv status ABORT NO DATA TRANSFER\n");
+#endif
+            }
+            /* check for reset status: I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */ 
+            if (PacketDescBlock)
+            {
+                while(PktCount--)
+                {
+                    skb = (struct sk_buff *)PacketDescBlock[0];
+#ifndef LINUX_2_1
+                    skb->free = 1;
+                    skb->lock = 0;    
 #endif
-               }
-               /* check for reset status: RC_REPLY_STATUS_ABORT_NO_DATA_TRANSFER */ 
-               if (PacketDescBlock)
-               {
-                    while(PktCount--)
-                    {
-                         skb = (struct sk_buff *)PacketDescBlock[0];
-                         skb->free = 1;
-                         skb->lock = 0;    
 #ifdef RCDEBUG
-                         printk("free skb 0x%p\n", skb);
+                    printk("free skb 0x%p\n", skb);
 #endif
-                         dev_kfree_skb(skb, FREE_READ);
-                         pDpa->numOutRcvBuffers--;
-                         PacketDescBlock += BD_SIZE; /* point to next context field */
-                    }
-               }
-               return;
-          }
-          else
-          {
-               while(PktCount--)
-               {
-                    skb = (struct sk_buff *)PacketDescBlock[0];
+#ifdef LINUX_2_1
+                    dev_kfree_skb (skb);
+#else
+                    dev_kfree_skb(skb, FREE_READ);
+#endif
+                    pDpa->numOutRcvBuffers--;
+                    PacketDescBlock += BD_SIZE; /* point to next context field */
+                }
+            }
+            return;
+        }
+        else
+        {
+            while(PktCount--)
+            {
+                skb = (struct sk_buff *)PacketDescBlock[0];
 #ifdef RCDEBUG
-                    if (pDpa->shutdown)
-                         printk("shutdown: skb=0x%x\n", (uint)skb);
+                if (pDpa->shutdown)
+                    printk("shutdown: skb=0x%x\n", (uint)skb);
 
-                    printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
-                           (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
-                           (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
+                printk("skb = 0x%x: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", (uint)skb,
+                       (uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
+                       (uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
 #endif
-                    if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
-                         (!broadcast_packet(skb->data)))
+                if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
+                     (!broadcast_packet(skb->data)))
+                {
+                    /*
+                     * Re-post the buffer to the adapter.  Since the adapter usually
+                     * return 1 to 2 receive buffers at a time, it's not too inefficient
+                     * post one buffer at a time but ... may be that should be 
+                     * optimized at some point.
+                     */
+                    ptcb->b.context = (U32)skb;    
+                    ptcb->b.scount = 1;
+                    ptcb->b.size = MAX_ETHER_SIZE;
+                    ptcb->b.addr = virt_to_bus((void *)skb->data);
+
+                    if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
                     {
-                         /*
-                          * Re-post the buffer to the adapter.  Since the adapter usually
-                          * return 1 to 2 receive buffers at a time, it's not too inefficient
-                          * post one buffer at a time but ... may be that should be 
-                          * optimized at some point.
-                          */
-                         ptcb->b.context = (U32)skb;    
-                         ptcb->b.scount = 1;
-                         ptcb->b.size = MAX_ETHER_SIZE;
-                         ptcb->b.addr = (U32)skb->data;
-
-                         if ( RCPostRecvBuffers(pDpa->id, (PRCTCB)ptcb ) != RC_RTN_NO_ERROR)
-                         {
-                              printk("rc: RCrecv_callback: post buffer failed!\n");
-                              skb->free = 1;
-                              dev_kfree_skb(skb, FREE_READ);
-                         }
-                         else
-                         {
-                              pDpa->numOutRcvBuffers++;
-                         }
+                        printk("rc: RCrecv_callback: post buffer failed!\n");
+#ifdef LINUX_2_1
+                        dev_kfree_skb (skb);
+#else
+                        skb->free = 1;
+                        dev_kfree_skb(skb, FREE_READ);
+#endif
                     }
                     else
                     {
-                         len = PacketDescBlock[2];
-                         skb->dev = dev;
-                         skb_put( skb, len ); /* adjust length and tail */
-                         skb->protocol = eth_type_trans(skb, dev);
-                         netif_rx(skb);    /* send the packet to the kernel */
-                         dev->last_rx = jiffies;
+                        pDpa->numOutRcvBuffers++;
                     }
-                    pDpa->numOutRcvBuffers--;
-                    PacketDescBlock += BD_SIZE; /* point to next context field */
-               }
-          } 
+                }
+                else
+                {
+                    len = PacketDescBlock[2];
+                    skb->dev = dev;
+                    skb_put( skb, len ); /* adjust length and tail */
+                    skb->protocol = eth_type_trans(skb, dev);
+                    netif_rx(skb);    /* send the packet to the kernel */
+                    dev->last_rx = jiffies;
+                }
+                pDpa->numOutRcvBuffers--;
+                PacketDescBlock += BD_SIZE; /* point to next context field */
+            }
+        } 
     
-          /*
-           * Replenish the posted receive buffers. 
-           * DO NOT replenish buffers if the driver has already
-           * initiated a reboot or shutdown!
-           */
-
-          if (!pDpa->shutdown && !pDpa->reboot)
-          {
-               count = RC_allocate_and_post_buffers(dev, 
-                                                    MAX_NMBR_RCV_BUFFERS-pDpa->numOutRcvBuffers);
-               pDpa->numOutRcvBuffers += count;
-          }
+        /*
+         * Replenish the posted receive buffers. 
+         * DO NOT replenish buffers if the driver has already
+         * initiated a reboot or shutdown!
+         */
+
+        if (!pDpa->shutdown && !pDpa->reboot)
+        {
+            count = RC_allocate_and_post_buffers(dev, 
+                                                 MAX_NMBR_RCV_BUFFERS-pDpa->numOutRcvBuffers);
+            pDpa->numOutRcvBuffers += count;
+        }
 
 }
 
@@ -843,156 +871,156 @@ RCrecv_callback(U32  Status,
  * 
  * Interrupt handler. 
  * This routine sets up a couple of pointers and calls
- * RCProcMsgQ(), which in turn process the message and
+ * RCProcI2OMsgQ(), which in turn process the message and
  * calls one of our callback functions.
  */
 static void 
 RCinterrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 
-     PDPA pDpa;
-     struct device *dev = (struct device *)(dev_id);
+    PDPA pDpa;
+    struct device *dev = (struct device *)(dev_id);
 
-     pDpa = (PDPA) (dev->priv);
+    pDpa = (PDPA) (dev->priv);
      
-     if (pDpa->shutdown)
-          printk("rc: shutdown: service irq\n");
+    if (pDpa->shutdown)
+        printk("rc: shutdown: service irq\n");
 
 #ifdef RCDEBUG
-     printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", 
-            (uint)pDpa, (uint)dev, (uint)pDpa->id);
-     printk("dev = 0x%x\n", (uint)dev);
+    printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n", 
+           (uint)pDpa, (uint)dev, (uint)pDpa->id);
+    printk("dev = 0x%x\n", (uint)dev);
 #endif
-     if (dev->interrupt)
-          printk("%s: Re-entering the interrupt handler.\n", dev->name);
-     dev->interrupt = 1;
+    if (dev->interrupt)
+        printk("%s: Re-entering the interrupt handler.\n", dev->name);
+    dev->interrupt = 1;
 
-     RCProcMsgQ(pDpa->id);
-     dev->interrupt = 0;
+    RCProcI2OMsgQ(pDpa->id);
+    dev->interrupt = 0;
 
-     return;
+    return;
 }
 
 #define REBOOT_REINIT_RETRY_LIMIT 10
 static void rc_timer(unsigned long data)
 {
-     struct device *dev = (struct device *)data;
-     PDPA pDpa = (PDPA) (dev->priv);
-     int init_status;
-     static int retry = 0;
-     int post_buffers = MAX_NMBR_RCV_BUFFERS;
-     int count = 0;
-     int requested = 0;
-
-     if (pDpa->reboot)
-     {
-
-          init_status = InitRCApiMsgLayer(pDpa->id, dev->base_addr, 
-                                          pDpa->PLanApiPA, pDpa->PLanApiPA,
-                                          (PFNTXCALLBACK)RCxmit_callback,
-                                          (PFNRXCALLBACK)RCrecv_callback,
-                                          (PFNCALLBACK)RCreboot_callback);
-
-          switch(init_status)
-          {
-          case RC_RTN_NO_ERROR:
+    struct device *dev = (struct device *)data;
+    PDPA pDpa = (PDPA) (dev->priv);
+    int init_status;
+    static int retry = 0;
+    int post_buffers = MAX_NMBR_RCV_BUFFERS;
+    int count = 0;
+    int requested = 0;
+
+    if (pDpa->reboot)
+    {
+
+        init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr, 
+                                        pDpa->PLanApiPA, pDpa->PLanApiPA,
+                                        (PFNTXCALLBACK)RCxmit_callback,
+                                        (PFNRXCALLBACK)RCrecv_callback,
+                                        (PFNCALLBACK)RCreboot_callback);
+
+        switch(init_status)
+        {
+        case RC_RTN_NO_ERROR:
  
-               pDpa->reboot = 0;
-               pDpa->shutdown = 0;        /* just in case */
-               RCReportDriverCapability(pDpa->id, DriverControlWord);
-               RCEnableAdapterInterrupts(pDpa->id);
-
-               if (dev->flags & IFF_UP)
-               {
-                    while(post_buffers)
-                    {
-                         if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
-                              requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
-                         else
-                              requested = post_buffers;
-                         count = RC_allocate_and_post_buffers(dev, requested);
-                         post_buffers -= count;
-                         if ( count < requested )
-                              break;
-                    }
-                    pDpa->numOutRcvBuffers = 
-                         MAX_NMBR_RCV_BUFFERS - post_buffers;
-                    printk("rc: posted %d buffers \r\n", 
-                           (uint)pDpa->numOutRcvBuffers);
-               }
-               printk("rc: Initialization done.\n");
-               return;
-          case RC_RTN_FREE_Q_EMPTY:
-               retry++;
-               printk("rc: inbound free q emtpy\n");
-               break;
-          default:
-               retry++;
-               printk("rc: unexpected bad status after reboot\n");    
-               break;
-          }
-
-          if (retry > REBOOT_REINIT_RETRY_LIMIT)
-          {
-               printk("rc: unable to reinitialize adapter after reboot\n");
-               printk("rc: decrementing driver and closing interface\n");
-               RCDisableAdapterInterrupts(pDpa->id);
-               dev->flags &= ~IFF_UP;
-               MOD_DEC_USE_COUNT; 
-          }
-          else
-          {
-               printk("rc: rescheduling timer...\n");
-               init_timer(&pDpa->timer);
-               pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
-               pDpa->timer.data = (unsigned long)dev;
-               pDpa->timer.function = &rc_timer;    /* timer handler */
-               add_timer(&pDpa->timer);
-          }
-     }
-     else
-     {
-          printk("rc: timer??\n");
-     }
+            pDpa->reboot = 0;
+            pDpa->shutdown = 0;        /* just in case */
+            RCReportDriverCapability(pDpa->id, DriverControlWord);
+            RCEnableI2OInterrupts(pDpa->id);
+
+            if (dev->flags & IFF_UP)
+            {
+                while(post_buffers)
+                {
+                    if (post_buffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
+                        requested = MAX_NMBR_POST_BUFFERS_PER_MSG;
+                    else
+                        requested = post_buffers;
+                    count = RC_allocate_and_post_buffers(dev, requested);
+                    post_buffers -= count;
+                    if ( count < requested )
+                        break;
+                }
+                pDpa->numOutRcvBuffers = 
+                    MAX_NMBR_RCV_BUFFERS - post_buffers;
+                printk("rc: posted %d buffers \r\n", 
+                       (uint)pDpa->numOutRcvBuffers);
+            }
+            printk("rc: Initialization done.\n");
+            return;
+        case RC_RTN_FREE_Q_EMPTY:
+            retry++;
+            printk("rc: inbound free q emtpy\n");
+            break;
+        default:
+            retry++;
+            printk("rc: unexpected bad status after reboot\n");    
+            break;
+        }
+
+        if (retry > REBOOT_REINIT_RETRY_LIMIT)
+        {
+            printk("rc: unable to reinitialize adapter after reboot\n");
+            printk("rc: decrementing driver and closing interface\n");
+            RCDisableI2OInterrupts(pDpa->id);
+            dev->flags &= ~IFF_UP;
+            MOD_DEC_USE_COUNT; 
+        }
+        else
+        {
+            printk("rc: rescheduling timer...\n");
+            init_timer(&pDpa->timer);
+            pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
+            pDpa->timer.data = (unsigned long)dev;
+            pDpa->timer.function = &rc_timer;    /* timer handler */
+            add_timer(&pDpa->timer);
+        }
+    }
+    else
+    {
+        printk("rc: timer??\n");
+    }
 }
 
 static int
 RCclose(struct device *dev)
 {
 
-     PDPA pDpa = (PDPA) dev->priv;
+    PDPA pDpa = (PDPA) dev->priv;
 
 #ifdef RCDEBUG
-     printk("rc: RCclose\r\n");
+    printk("rc: RCclose\r\n");
 #endif
-     if (pDpa->reboot)
-     {
-          printk("rc: skipping reset -- adapter already in reboot mode\n");
-          dev->flags &= ~IFF_UP;
-          pDpa->shutdown = 1;
-          return 0;
-     }
+    if (pDpa->reboot)
+    {
+        printk("rc: skipping reset -- adapter already in reboot mode\n");
+        dev->flags &= ~IFF_UP;
+        pDpa->shutdown = 1;
+        return 0;
+    }
 #ifdef RCDEBUG
-     printk("rc: receive buffers outstanding: %d\n", 
-            (uint)pDpa->numOutRcvBuffers);
+    printk("rc: receive buffers outstanding: %d\n", 
+           (uint)pDpa->numOutRcvBuffers);
 #endif
 
-     pDpa->shutdown = 1;
+    pDpa->shutdown = 1;
 
-     /*
-      * We can't allow the driver to be unloaded until the adapter returns
-      * all posted receive buffers.  It doesn't hurt to tell the adapter
-      * to return all posted receive buffers and outstanding xmit buffers,
-      * even if there are none.
-      */
+    /*
+     * We can't allow the driver to be unloaded until the adapter returns
+     * all posted receive buffers.  It doesn't hurt to tell the adapter
+     * to return all posted receive buffers and outstanding xmit buffers,
+     * even if there are none.
+     */
 
-     RCShutdownLANCard(pDpa->id, 
-                       RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
-                       RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
-                       (PFNCALLBACK)RCreset_callback);
+    RCShutdownLANCard(pDpa->id, 
+                      RC_RESOURCE_RETURN_POSTED_RX_BUCKETS | 
+                      RC_RESOURCE_RETURN_PEND_TX_BUFFERS,0,
+                      (PFNCALLBACK)RCreset_callback);
 
-     dev->flags &= ~IFF_UP;
-     return 0;
+        dev->flags &= ~IFF_UP;
+    return 0;
 }
 
 static struct enet_statistics *
@@ -1094,236 +1122,298 @@ static int RCioctl(struct device *dev, struct ifreq *rq, int cmd)
  
     switch (cmd)  {
  
-        case RCU_PROTOCOL_REV:
-             /*
-              * Assign user protocol revision, to tell user-level
-              * controller program whether or not it's in sync.
-              */
-             rq->ifr_ifru.ifru_data = (caddr_t) USER_PROTOCOL_REV;
-             break;
+    case RCU_PROTOCOL_REV:
+        /*
+         * Assign user protocol revision, to tell user-level
+         * controller program whether or not it's in sync.
+         */
+        rq->ifr_ifru.ifru_data = (caddr_t) USER_PROTOCOL_REV;
+        break;
   
 
-        case RCU_COMMAND:
-        {
-            int error;
-
-            error=verify_area(VERIFY_WRITE, rq->ifr_data, sizeof(RCuser));
-            if (error)  {
-                return error;
-            }
-            memcpy_fromfs(&RCuser, rq->ifr_data, sizeof(RCuser));
+    case RCU_COMMAND:
+    {
+#ifdef LINUX_2_1
+        if(copy_from_user(&RCuser, rq->ifr_data, sizeof(RCuser)))
+             return -EFAULT;
+#else
+        int error;
+        error=verify_area(VERIFY_WRITE, rq->ifr_data, sizeof(RCuser));
+        if (error)  {
+            return error;
+        }
+        memcpy_fromfs(&RCuser, rq->ifr_data, sizeof(RCuser));
+#endif
         
 #ifdef RCDEBUG
-            printk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);
+        printk("RCioctl: RCuser_cmd = 0x%x\n", RCuser.cmd);
 #endif
   
-            switch(RCuser.cmd)
+        switch(RCuser.cmd)
+        {
+        case RCUC_GETFWVER:
+            printk("RC GETFWVER\n");
+            RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
+            RCGetFirmwareVer(pDpa->id, (PU8) &RCUD_GETFWVER->FirmString, NULL);
+            break;
+        case RCUC_GETINFO:
+            printk("RC GETINFO\n");
+            RCUD_GETINFO = &RCuser.RCUS_GETINFO;
+            RCUD_GETINFO -> mem_start = dev->base_addr;
+            RCUD_GETINFO -> mem_end = dev->base_addr + 2*32768;
+            RCUD_GETINFO -> base_addr = pDpa->pci_addr;
+            RCUD_GETINFO -> irq = dev->irq;
+            break;
+        case RCUC_GETIPANDMASK:
+            printk("RC GETIPANDMASK\n");
+            RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
+            RCGetRavlinIPandMask(pDpa->id, (PU32) &RCUD_GETIPANDMASK->IpAddr,
+                                 (PU32) &RCUD_GETIPANDMASK->NetMask, NULL);
+            break;
+        case RCUC_GETLINKSTATISTICS:
+            printk("RC GETLINKSTATISTICS\n");
+            RCUD_GETLINKSTATISTICS = &RCuser.RCUS_GETLINKSTATISTICS;
+            RCGetLinkStatistics(pDpa->id, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL);
+            break;
+        case RCUC_GETLINKSTATUS:
+            printk("RC GETLINKSTATUS\n");
+            RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
+            RCGetLinkStatus(pDpa->id, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL);
+            break;
+        case RCUC_GETMAC:
+            printk("RC GETMAC\n");
+            RCUD_GETMAC = &RCuser.RCUS_GETMAC;
+            RCGetMAC(pDpa->id, (PU8) &RCUD_GETMAC->mac, NULL);
+            break;
+        case RCUC_GETPROM:
+            printk("RC GETPROM\n");
+            RCUD_GETPROM = &RCuser.RCUS_GETPROM;
+            RCGetPromiscuousMode(pDpa->id, (PU32) &RCUD_GETPROM->PromMode, NULL);
+            break;
+        case RCUC_GETBROADCAST:
+            printk("RC GETBROADCAST\n");
+            RCUD_GETBROADCAST = &RCuser.RCUS_GETBROADCAST;
+            RCGetBroadcastMode(pDpa->id, (PU32) &RCUD_GETBROADCAST->BroadcastMode, NULL);
+            break;
+        case RCUC_GETSPEED:
+            printk("RC GETSPEED\n");
+            if (!(dev->flags & IFF_UP))    
             {
-                case RCUC_GETFWVER:
-                    printk("RC GETFWVER\n");
-                    RCUD_GETFWVER = &RCuser.RCUS_GETFWVER;
-                    RCGetFirmwareVer(pDpa->id, (PU8) &RCUD_GETFWVER->FirmString, NULL);
-                    break;
-                case RCUC_GETINFO:
-                    printk("RC GETINFO\n");
-                    RCUD_GETINFO = &RCuser.RCUS_GETINFO;
-                    RCUD_GETINFO -> mem_start = dev->base_addr;
-                    RCUD_GETINFO -> mem_end = dev->base_addr + 32768;
-                    RCUD_GETINFO -> base_addr = pDpa->pci_addr;
-                    RCUD_GETINFO -> irq = dev->irq;
-                    break;
-                case RCUC_GETIPANDMASK:
-                    printk("RC GETIPANDMASK\n");
-                    RCUD_GETIPANDMASK = &RCuser.RCUS_GETIPANDMASK;
-                    RCGetRavlinIPandMask(pDpa->id, (PU32) &RCUD_GETIPANDMASK->IpAddr,
-                        (PU32) &RCUD_GETIPANDMASK->NetMask, NULL);
-                    break;
-                case RCUC_GETLINKSTATISTICS:
-                    printk("RC GETLINKSTATISTICS\n");
-                    RCUD_GETLINKSTATISTICS = &RCuser.RCUS_GETLINKSTATISTICS;
-                    RCGetLinkStatistics(pDpa->id, (P_RCLINKSTATS) &RCUD_GETLINKSTATISTICS->StatsReturn, NULL);
-                    break;
-                case RCUC_GETLINKSTATUS:
-                    printk("RC GETLINKSTATUS\n");
-                    RCUD_GETLINKSTATUS = &RCuser.RCUS_GETLINKSTATUS;
-                    RCGetLinkStatus(pDpa->id, (PU32) &RCUD_GETLINKSTATUS->ReturnStatus, NULL);
-                    break;
-                case RCUC_GETMAC:
-                    printk("RC GETMAC\n");
-                    RCUD_GETMAC = &RCuser.RCUS_GETMAC;
-                    RCGetMAC(pDpa->id, (PU8) &RCUD_GETMAC->mac, NULL);
-                    break;
-                case RCUC_GETSPEED:
-                    printk("RC GETSPEED\n");
-                    if (!(dev->flags & IFF_UP))    
-                    {
-                        printk("RCioctl, GETSPEED error: interface down\n");
-                        return -ENODATA;
-                    }
-                    RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
-                    RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL);
-                    printk("RC speed = 0x%ld\n", RCUD_GETSPEED->LinkSpeedCode);
-                    break;
-                default:
-                    printk("RC command default\n");
-                    RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
-                    RCUD_DEFAULT -> rc = 0x11223344;
-                    break;
+                printk("RCioctl, GETSPEED error: interface down\n");
+                return -ENODATA;
             }
-            memcpy_tofs(rq->ifr_data, &RCuser, sizeof(RCuser));
+            RCUD_GETSPEED = &RCuser.RCUS_GETSPEED;
+            RCGetLinkSpeed(pDpa->id, (PU32) &RCUD_GETSPEED->LinkSpeedCode, NULL);
+            printk("RC speed = 0x%ld\n", RCUD_GETSPEED->LinkSpeedCode);
+            break;
+        case RCUC_SETIPANDMASK:
+            printk("RC SETIPANDMASK\n");
+            RCUD_SETIPANDMASK = &RCuser.RCUS_SETIPANDMASK;
+            printk ("RC New IP Addr = %d.%d.%d.%d, ", (U8) ((RCUD_SETIPANDMASK->IpAddr) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->IpAddr >>  8) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->IpAddr >> 16) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->IpAddr >> 24) & 0xff));
+            printk ("RC New Mask = %d.%d.%d.%d\n", (U8) ((RCUD_SETIPANDMASK->NetMask) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->NetMask >>  8) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->NetMask >> 16) & 0xff),
+                    (U8) ((RCUD_SETIPANDMASK->NetMask >> 24) & 0xff));
+            RCSetRavlinIPandMask(pDpa->id, (U32) RCUD_SETIPANDMASK->IpAddr,
+                                 (U32) RCUD_SETIPANDMASK->NetMask);
+            break;
+        case RCUC_SETMAC:
+            printk("RC SETMAC\n");
+            RCUD_SETMAC = &RCuser.RCUS_SETMAC;
+            printk ("RC New MAC addr = %02X:%02X:%02X:%02X:%02X:%02X\n",
+                    (U8) (RCUD_SETMAC->mac[0]), (U8) (RCUD_SETMAC->mac[1]), (U8) (RCUD_SETMAC->mac[2]),
+                    (U8) (RCUD_SETMAC->mac[3]), (U8) (RCUD_SETMAC->mac[4]), (U8) (RCUD_SETMAC->mac[5]));
+            RCSetMAC(pDpa->id, (PU8) &RCUD_SETMAC->mac);
+            break;
+        case RCUC_SETSPEED:
+            printk("RC SETSPEED\n");
+            RCUD_SETSPEED = &RCuser.RCUS_SETSPEED;
+            RCSetLinkSpeed(pDpa->id, (U16) RCUD_SETSPEED->LinkSpeedCode);
+            printk("RC New speed = 0x%d\n", RCUD_SETSPEED->LinkSpeedCode);
+            break;
+        case RCUC_SETPROM:
+            printk("RC SETPROM\n");
+            RCUD_SETPROM = &RCuser.RCUS_SETPROM;
+            RCSetPromiscuousMode(pDpa->id,(U16)RCUD_SETPROM->PromMode);
+            printk("RC New prom mode = 0x%d\n", RCUD_SETPROM->PromMode);
+            break;
+        case RCUC_SETBROADCAST:
+            printk("RC SETBROADCAST\n");
+            RCUD_SETBROADCAST = &RCuser.RCUS_SETBROADCAST;
+            RCSetBroadcastMode(pDpa->id,(U16)RCUD_SETBROADCAST->BroadcastMode);
+            printk("RC New broadcast mode = 0x%d\n", RCUD_SETBROADCAST->BroadcastMode);
             break;
-        }   /* RCU_COMMAND */ 
-
         default:
-            printk("RC default\n");
-            rq->ifr_ifru.ifru_data = (caddr_t) 0x12345678;
+            printk("RC command default\n");
+            RCUD_DEFAULT = &RCuser.RCUS_DEFAULT;
+            RCUD_DEFAULT -> rc = 0x11223344;
             break;
+        }
+#ifdef LINUX_2_1
+        copy_to_user(rq->ifr_data, &RCuser, sizeof(RCuser));
+#else
+        memcpy_tofs(rq->ifr_data, &RCuser, sizeof(RCuser));
+#endif
+        break;
+    }   /* RCU_COMMAND */ 
+
+    default:
+        printk("RC default\n");
+        rq->ifr_ifru.ifru_data = (caddr_t) 0x12345678;
+        break;
     }
     return 0;
 }
 
 static int RCconfig(struct device *dev, struct ifmap *map)
 {
-     /*
-      * To be completed ...
+    /*
+     * To be completed ...
       */
-      printk("rc: RCconfig\n");
-      return 0;
-      if (dev->flags & IFF_UP)    /* can't act on a running interface */
-           return -EBUSY;
+    printk("rc: RCconfig\n");
+    return 0;
+    if (dev->flags & IFF_UP)    /* can't act on a running interface */
+        return -EBUSY;
 
      /* Don't allow changing the I/O address */
-     if (map->base_addr != dev->base_addr) {
-          printk(KERN_WARNING "RC pci45: Change I/O address not implemented\n");
-          return -EOPNOTSUPP;
-     }
-     return 0;
+    if (map->base_addr != dev->base_addr) {
+        printk(KERN_WARNING "RC pci45: Change I/O address not implemented\n");
+        return -EOPNOTSUPP;
+    }
+    return 0;
 }
 
-#ifdef MODULE
-void cleanup_module(void)
+void
+cleanup_module(void)
 {
-     PDPA pDpa;
-     struct device *next;
+    PDPA pDpa;
+    struct device *next;
 
 
 #ifdef RCDEBUG
-     printk("rc: RC cleanup_module\n");
-     printk("rc: root_RCdev = 0x%x\n", (uint)root_RCdev);
+    printk("rc: RC cleanup_module\n");
+    printk("rc: root_RCdev = 0x%x\n", (uint)root_RCdev);
 #endif
 
 
-     while (root_RCdev)
-     {
-          pDpa = (PDPA) root_RCdev->priv;
+    while (root_RCdev)
+    {
+        pDpa = (PDPA) root_RCdev->priv;
 #ifdef RCDEBUG
-          printk("rc: cleanup 0x%08X\n", (uint)root_RCdev);
+        printk("rc: cleanup 0x%08X\n", (uint)root_RCdev);
 #endif
-          printk("Adapter reset: 0x%x\n", RCResetAdapter(pDpa->id));
-          unregister_netdev(root_RCdev);
-          next = pDpa->next;
-
-          vfree((unsigned long *)root_RCdev->base_addr); 
-          free_irq( root_RCdev->irq, root_RCdev );
-          kfree(root_RCdev);
-          root_RCdev = next;
-     }
+        printk("IOP reset: 0x%x\n", RCResetIOP(pDpa->id));
+        unregister_netdev(root_RCdev);
+        next = pDpa->next;
+
+        iounmap((unsigned long *)root_RCdev->base_addr); 
+        free_irq( root_RCdev->irq, root_RCdev );
+        kfree(root_RCdev);
+        root_RCdev = next;
+    }
 }
-#endif
-
 
 static int
 RC_allocate_and_post_buffers(struct device *dev, int numBuffers)
 {
 
-     int i;
-     PDPA pDpa = (PDPA)dev->priv;
-     PU32 p;
-     psingleB pB;
-     struct sk_buff *skb;
-     RC_RETURN status;
-
-     if (!numBuffers)
-          return 0;
-     else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
-     {
+    int i;
+    PDPA pDpa = (PDPA)dev->priv;
+    PU32 p;
+    psingleB pB;
+    struct sk_buff *skb;
+    RC_RETURN status;
+
+    if (!numBuffers)
+        return 0;
+    else if (numBuffers > MAX_NMBR_POST_BUFFERS_PER_MSG)
+    {
 #ifdef RCDEBUG
-          printk("rc: Too many buffers requested!\n");
-          printk("rc: attempting to allocate only 32 buffers\n");
+        printk("rc: Too many buffers requested!\n");
+        printk("rc: attempting to allocate only 32 buffers\n");
 #endif
-          numBuffers = 32;
-     }
+        numBuffers = 32;
+    }
     
-     p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_ATOMIC);
+    p = (PU32) kmalloc(sizeof(U32) + numBuffers*sizeof(singleB), GFP_ATOMIC);
 
 #ifdef RCDEBUG
-     printk("rc: TCB = 0x%x\n", (uint)p);
+    printk("rc: TCB = 0x%x\n", (uint)p);
 #endif
 
-     if (!p)
-     {
-          printk("rc: RCopen: unable to allocate TCB\n");
-          return 0;
-     }
+    if (!p)
+    {
+        printk("rc: RCopen: unable to allocate TCB\n");
+        return 0;
+    }
 
-     p[0] = 0;                              /* Buffer Count */
-     pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
+    p[0] = 0;                              /* Buffer Count */
+    pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
 
 #ifdef RCDEBUG
-     printk("rc: p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB);
-     printk("rc: pB = 0x%x\n", (uint)pB);
+    printk("rc: p[0] = 0x%x, p = 0x%x, pB = 0x%x\n", (uint)p[0], (uint)p, (uint)pB);
+    printk("rc: pB = 0x%x\n", (uint)pB);
 #endif
 
-     for (i=0; i<numBuffers; i++)
-     {
-          skb = dev_alloc_skb(MAX_ETHER_SIZE+2);
-          if (!skb)
-          {
-               printk("rc: Doh! RCopen: unable to allocate enough skbs!\n");
-               if (*p != 0)        /* did we allocate any buffers at all? */
-               {
+    for (i=0; i<numBuffers; i++)
+    {
+        skb = dev_alloc_skb(MAX_ETHER_SIZE+2);
+        if (!skb)
+        {
+            printk("rc: Doh! RCopen: unable to allocate enough skbs!\n");
+            if (*p != 0)        /* did we allocate any buffers at all? */
+            {
 #ifdef RCDEBUG
-                    printk("rc: will post only %d buffers \n", (uint)(*p));
+                printk("rc: will post only %d buffers \n", (uint)(*p));
 #endif
-                    break;
-               }
-               else 
-               {
-                    kfree(p);    /* Free the TCB */
-                    return 0;
-               }
-          }
+                break;
+            }
+            else 
+            {
+                kfree(p);    /* Free the TCB */
+                return 0;
+            }
+        }
 #ifdef RCDEBUG
-          printk("post 0x%x\n", (uint)skb);
+        printk("post 0x%x\n", (uint)skb);
+#endif
+        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
+        pB->context = (U32)skb;
+        pB->scount = 1;        /* segment count */
+        pB->size = MAX_ETHER_SIZE;
+        pB->addr = virt_to_bus((void *)skb->data);
+        p[0]++;
+        pB++;
+    }
+
+    if ( (status = RCPostRecvBuffers(pDpa->id, (PRCTCB)p )) != RC_RTN_NO_ERROR)
+    {
+        printk("rc: Post buffer failed with error code 0x%x!\n", status);
+        pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
+        while(p[0])
+        {
+            skb = (struct sk_buff *)pB->context;
+#ifndef LINUX_2_1
+            skb->free = 1;    
 #endif
-          skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-          pB->context = (U32)skb;
-          pB->scount = 1;        /* segment count */
-          pB->size = MAX_ETHER_SIZE;
-          pB->addr = (U32)skb->data;
-          p[0]++;
-          pB++;
-     }
-
-     if ( (status = RCPostRecvBuffers(pDpa->id, (PRCTCB)p )) != RC_RTN_NO_ERROR)
-     {
-          printk("rc: Post buffer failed with error code 0x%x!\n", status);
-          pB = (psingleB)((U32)p + sizeof(U32)); /* point to the first buffer */
-          while(p[0])
-          {
-               skb = (struct sk_buff *)pB->context;
-               skb->free = 1;    
 #ifdef RCDEBUG
-               printk("rc: freeing 0x%x\n", (uint)skb);
+            printk("rc: freeing 0x%x\n", (uint)skb);
 #endif
-               dev_kfree_skb(skb, FREE_READ);
-               p[0]--;
-               pB++;
-          }
+#ifdef LINUX_2_1
+            dev_kfree_skb (skb);
+#else
+            dev_kfree_skb(skb, FREE_READ);
+#endif
+            p[0]--;
+            pB++;
+        }
 #ifdef RCDEBUG
-           printk("rc: freed all buffers, p[0] = %ld\n", p[0]);
+        printk("rc: freed all buffers, p[0] = %ld\n", p[0]);
 #endif
-     }
-     kfree(p);
-     return(p[0]);                /* return the number of posted buffers */
+    }
+    kfree(p);
+    return(p[0]);                /* return the number of posted buffers */
 }
index aac5b8cdc0c1c098e3f49949b51cc3e5e2d9d6b7..6b022cfb6cbbcf91e7d5ff2049baa6170b2c6c79 100644 (file)
@@ -110,6 +110,8 @@ struct pci_dev_info dev_info[] = {
        DEVICE( DEC,            DEC_21052,      "DC21052"),
        DEVICE( DEC,            DEC_21150,      "DC21150"),
        DEVICE( DEC,            DEC_21152,      "DC21152"),
+       DEVICE( DEC,            DEC_21154,      "DC21154"),
+       DEVICE( DEC,            DEC_21285,      "DC21285 Footbridge"),
        DEVICE( CIRRUS,         CIRRUS_7548,    "GD 7548"),
        DEVICE( CIRRUS,         CIRRUS_5430,    "GD 5430"),
        DEVICE( CIRRUS,         CIRRUS_5434_4,  "GD 5434"),
index 642be224ddb2cbc882014eb091038be6bf90ed6d..e5b815c8781955cd5f5c1a7686baa552de191ceb 100644 (file)
@@ -55,6 +55,7 @@ if [ "$CONFIG_SCSI_GENERIC_NCR5380" != "n" ]; then
 fi
 dep_tristate 'Initio 91XX support' CONFIG_SCSI_INITIO $CONFIG_SCSI
 dep_tristate 'NCR53c406a SCSI support' CONFIG_SCSI_NCR53C406A $CONFIG_SCSI
+dep_tristate 'symbios 53c416 SCSI support' CONFIG_SCSI_SYM53C416 $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
   dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx $CONFIG_SCSI
   if [ "$CONFIG_SCSI_NCR53C7xx" != "n" ]; then
index b6832ddbf0aafd7348cc212335288339a8cf6e06..6ce37b050f8c0bf8d48ae94c678c14764134ab8f 100644 (file)
@@ -380,6 +380,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_SCSI_SYM53C416),y) 
+L_OBJS += sym53c416.o 
+else 
+  ifeq ($(CONFIG_SCSI_SYM53C416),m) 
+  M_OBJS += sym53c416.o 
+  endif 
+endif 
+
 ifeq ($(CONFIG_SCSI_MEGARAID),y)
 L_OBJS += megaraid.o
 else
index 0c2f33d0e762360ca76ed36ab8fc9b04847bc40f..2435f10ae5cc2f53d2eac917f14406ebffa90ad7 100644 (file)
 #include "NCR53c406a.h"
 #endif
 
+#ifdef CONFIG_SCSI_SYM53C416 
+#include "sym53c416.h" 
+#endif
+
 #ifdef CONFIG_SCSI_DC390T
 #include "dc390.h"
 #endif
@@ -282,6 +286,9 @@ static Scsi_Host_Template builtin_scsi_hosts[] =
 #ifdef CONFIG_SCSI_NCR53C406A  /* 53C406A should come before QLOGIC */
     NCR53c406a,
 #endif
+#ifdef CONFIG_SCSI_SYM53C416 
+    SYM53C416, 
+#endif 
 #ifdef CONFIG_SCSI_QLOGIC_FAS
     QLOGICFAS,
 #endif
index c375e0a3f1b1b03dbc4eff250e35b6cc9e1ed574..6802dcc88b2d2bb99ac5d9f863acb6a444cc91cb 100644 (file)
@@ -1,24 +1,27 @@
 /*===================================================================
  *
  *                    Linux MegaRAID device driver
- * 
+ *
  * Copyright 1998 American Megatrends Inc.
  *
- *             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 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.
  *
- * Version : 0.92
+ * Version : 0.93
  * 
  * Description: Linux device driver for AMI MegaRAID controller
  *
+ * Supported controllers: MegaRAID 418, 428, 438, 466
+ * 
+ * Maintainer: Jeff L Jones <jeffreyj@ami.com>
+ *
  * History:
  *
  * Version 0.90:
- *     Works and has been tested with the MegaRAID 428 controller, and
- *     the MegaRAID 438 controller.  Probably works with the 466 also,
- *     but not tested.
+ *     Original source contributed by Dell; integrated it into the kernel and
+ *     cleaned up some things.  Added support for 438/466 controllers.
  *
  * Version 0.91:
  *     Aligned mailbox area on 16-byte boundry.
  *     Removed setting of SA_INTERRUPT flag when requesting Irq.
  *
  * Version 0.92ac:
- *     Small changes to the comments/formatting. Plus a couple of
- *     added notes. Returned to the authors. No actual code changes
- *     save printk levels.
- *     8 Oct 98        Alan Cox <alan.cox@linux.org>
+ *      Small changes to the comments/formatting. Plus a couple of
+ *      added notes. Returned to the authors. No actual code changes
+ *      save printk levels.
+ *      8 Oct 98        Alan Cox <alan.cox@linux.org>
+ *
+ *     Merged with 2.1.131 source tree.
+ *     12 Dec 98       K. Baranowski <kgb@knm.org.pl>                          
+ *
+ * Version 0.93:
+ *     Added support for vendor specific ioctl commands (0x80+xxh)
+ *     Changed some fields in MEGARAID struct to better values.
+ *     Added signature check for Rp controllers under 2.0 kernels
+ *     Changed busy-wait loop to be time-based
+ *     Fixed SMP race condition in isr
+ *     Added kfree (sgList) on release
+ *     Added #include linux/version.h to megaraid.h for hosts.h
+ *     Changed max_id to represent max logical drives instead of targets.
+ *
  *
  * BUGS:
- *     Tested with 2.1.90, but unfortunately there is a bug in pci.c which
- *     fails to detect our controller.  Does work with 2.1.118--don't know
- *     which kernel in between it was fixed in.
- *     With SMP enabled under 2.1.118 with more than one processor, gets an
- *     error message "scsi_end_request: buffer-list destroyed" under heavy
- *     IO, but doesn't seem to affect operation, or data integrity.  The
- *     message doesn't occur without SMP enabled, or with one proccessor with
- *     SMP enabled, or under any combination under 2.0 kernels.
+ *     Some older 2.1 kernels (eg. 2.1.90) have a bug in pci.c that
+ *     fails to detect the controller as a pci device on the system.
  *
  *===================================================================*/
-#define QISR 1
 
 #define CRLFSTR "\n"
 
-#define MULTIQ 1
-
 #include <linux/config.h>
 #include <linux/version.h>
 
 #if LINUX_VERSION_CODE >= 0x20100
 char kernel_version[] = UTS_RELEASE;
 
-/* originally ported by Dell Corporation; updated, released, and maintained by
-   American Megatrends */
-MODULE_AUTHOR("American Megatrends Inc."); 
-MODULE_DESCRIPTION("AMI MegaRAID driver");    
+MODULE_AUTHOR ("American Megatrends Inc.");
+MODULE_DESCRIPTION ("AMI MegaRAID driver");
 #endif
 #endif
 
@@ -107,18 +113,21 @@ MODULE_DESCRIPTION("AMI MegaRAID driver");
 
 #include "megaraid.h"
 
-/*================================================================
- *
- *                          #Defines
- *
- *================================================================*/
+//================================================================
+//
+//                          #Defines
+//
+//================================================================
 
 #if LINUX_VERSION_CODE < 0x020100
 #define ioremap vremap
 #define iounmap vfree
 
 /* simulate spin locks */
-typedef struct {volatile char lock;} spinlock_t;
+typedef struct {
+  volatile char lock;
+} spinlock_t;
+
 #define spin_lock_init(x) { (x)->lock = 0;}
 #define spin_lock_irqsave(x,flags) { while ((x)->lock) barrier();\
                                         (x)->lock=1; save_flags(flags);\
@@ -153,125 +162,124 @@ typedef struct {volatile char lock;} spinlock_t;
   spin_unlock_irqrestore(&mega_lock,cpuflag);\
 };
 
-u_long RDINDOOR(mega_host_config *megaCfg)
+u_long RDINDOOR (mega_host_config * megaCfg)
 {
-  return readl(megaCfg->base + 0x20);
+  return readl (megaCfg->base + 0x20);
 }
 
-void WRINDOOR(mega_host_config *megaCfg, u_long value)
+void WRINDOOR (mega_host_config * megaCfg, u_long value)
 {
-  writel(value,megaCfg->base+0x20);
+  writel (value, megaCfg->base + 0x20);
 }
 
-u_long RDOUTDOOR(mega_host_config *megaCfg)
+u_long RDOUTDOOR (mega_host_config * megaCfg)
 {
-  return readl(megaCfg->base+0x2C);
+  return readl (megaCfg->base + 0x2C);
 }
 
-void WROUTDOOR(mega_host_config *megaCfg, u_long value)
+void WROUTDOOR (mega_host_config * megaCfg, u_long value)
 {
-  writel(value,megaCfg->base+0x2C);
+  writel (value, megaCfg->base + 0x2C);
 }
 
-/*================================================================
- *
- *                    Function prototypes
- *
- *================================================================*/
-static int  MegaIssueCmd(mega_host_config *megaCfg,
-                        u_char *mboxData,
-                        mega_scb *scb,
+//================================================================
+//
+//                    Function prototypes
+//
+//================================================================
+static int MegaIssueCmd (mega_host_config * megaCfg,
+                        u_char * mboxData,
+                        mega_scb * scb,
                         int intr);
-static int  build_sglist(mega_host_config *megaCfg, mega_scb *scb, 
-                        u_long *buffer, u_long *length);
+static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
+                        u_long * buffer, u_long * length);
 
-static void mega_runque(void *);
-static void mega_rundoneq(void);
-static void mega_cmd_done(mega_host_config *,mega_scb *, int);
+static void mega_runque (void *);
+static void mega_rundoneq (void);
+static void mega_cmd_done (mega_host_config *, mega_scb *, int);
+static mega_scb *mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt);
 
 /* set SERDEBUG to 1 to enable serial debugging */
 #define SERDEBUG 0
 #if SERDEBUG
-static void ser_init(void);
-static void ser_puts(char *str);
-static void ser_putc(char c);
-static int  ser_printk(const char *fmt, ...);
+static void ser_init (void);
+static void ser_puts (char *str);
+static void ser_putc (char c);
+static int ser_printk (const char *fmt,...);
 #endif
 
-/*================================================================
- *
- *                    Global variables
- *
- *================================================================*/
-static int               numCtlrs = 0;
-static mega_host_config *megaCtlrs[4] = { 0 };
+//================================================================
+//
+//                    Global variables
+//
+//================================================================
+static int numCtlrs = 0;
+static mega_host_config *megaCtlrs[12] = {0};
 
 /* Change this to 0 if you want to see the raw drives */
-static int use_raid   = 1;
+static int use_raid = 1;
 
 /* Queue of pending/completed SCBs */
-static mega_scb  *qPending   = NULL;
+static mega_scb *qPending = NULL;
 static Scsi_Cmnd *qCompleted = NULL;
 
 volatile static spinlock_t mega_lock;
-static struct tq_struct runq = {0,0,mega_runque,NULL};
+static struct tq_struct runq = {0, 0, mega_runque, NULL};
 
-struct proc_dir_entry proc_scsi_megaraid = {
+struct proc_dir_entry proc_scsi_megaraid =
+{
   PROC_SCSI_MEGARAID, 8, "megaraid",
   S_IFDIR | S_IRUGO | S_IXUGO, 2
 };
 
 #if SERDEBUG
-static char strbuf[MAX_SERBUF+1];
+static char strbuf[MAX_SERBUF + 1];
 
-static void ser_init()
+static void ser_init ()
 {
-    unsigned port=COM_BASE;
-
-    outb(0x80,port+3);
-    outb(0,port+1);
-    /* 9600 Baud, if 19200: outb(6,port) */
-    outb(12, port);
-    outb(3,port+3);
-    outb(0,port+1);
+  unsigned port = COM_BASE;
+
+  outb (0x80, port + 3);
+  outb (0, port + 1);
+  /* 9600 Baud, if 19200: outb(6,port) */
+  outb (12, port);
+  outb (3, port + 3);
+  outb (0, port + 1);
 }
 
-static void ser_puts(char *str)
+static void ser_puts (char *str)
 {
-    char *ptr;
+  char *ptr;
 
-    ser_init();
-    for (ptr=str;*ptr;++ptr)
-        ser_putc(*ptr);
+  ser_init ();
+  for (ptr = str; *ptr; ++ptr)
+    ser_putc (*ptr);
 }
 
-static void ser_putc(char c)
+static void ser_putc (char c)
 {
-    unsigned port=COM_BASE;
-
-    while ((inb(port+5) & 0x20)==0);
-    outb(c,port);
-    if (c==0x0a)
-    {
-        while ((inb(port+5) & 0x20)==0);
-        outb(0x0d,port);
-    }
+  unsigned port = COM_BASE;
+
+  while ((inb (port + 5) & 0x20) == 0);
+  outb (c, port);
+  if (c == 0x0a) {
+    while ((inb (port + 5) & 0x20) == 0);
+    outb (0x0d, port);
+  }
 }
 
-static int ser_printk(const char *fmt, ...)
+static int ser_printk (const char *fmt,...)
 {
-    va_list args;
-    int i;
-    long flags;
-
-    spin_lock_irqsave(mega_lock,flags);
-    va_start(args,fmt);
-    i = vsprintf(strbuf,fmt,args);
-    ser_puts(strbuf);
-    va_end(args);
-    spin_unlock_irqrestore(&mega_lock,flags);
+  va_list args;
+  int i;
+  long flags;
+
+  va_start (args, fmt);
+  i = vsprintf (strbuf, fmt, args);
+  ser_puts (strbuf);
+  va_end (args);
 
-    return i;
+  return i;
 }
 
 #define TRACE(a)    { ser_printk a;}
@@ -280,14 +288,14 @@ static int ser_printk(const char *fmt, ...)
 #define TRACE(A)
 #endif
 
-void callDone(Scsi_Cmnd *SCpnt)
+void callDone (Scsi_Cmnd * SCpnt)
 {
   if (SCpnt->result) {
-    TRACE(("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number, 
-          SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun, 
-          SCpnt->result));
+    TRACE (("*** %.08lx %.02x <%d.%d.%d> = %x\n", SCpnt->serial_number,
+           SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, SCpnt->lun,
+           SCpnt->result));
   }
-  SCpnt->scsi_done(SCpnt);
+  SCpnt->scsi_done (SCpnt);
 }
 
 /*-------------------------------------------------------------------------
@@ -296,82 +304,79 @@ void callDone(Scsi_Cmnd *SCpnt)
  *
  *-------------------------------------------------------------------------*/
 
-/*================================================
- * Initialize SCB structures
- *================================================*/
-static void initSCB(mega_host_config *megaCfg)
+//================================================
+// Initialize SCB structures
+//================================================
+static void initSCB (mega_host_config * megaCfg)
 {
   int idx;
 
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
-    megaCfg->scbList[idx].idx    = -1;
-    megaCfg->scbList[idx].flag   = 0;
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
+    megaCfg->scbList[idx].idx = -1;
+    megaCfg->scbList[idx].flag = 0;
     megaCfg->scbList[idx].sgList = NULL;
-    megaCfg->scbList[idx].SCpnt  = NULL;
+    megaCfg->scbList[idx].SCpnt = NULL;
   }
 }
 
-/*===========================
- * Allocate a SCB structure
- *===========================*/
-static mega_scb *allocateSCB(mega_host_config *megaCfg,Scsi_Cmnd *SCpnt)
+//===========================
+// Allocate a SCB structure
+//===========================
+static mega_scb * allocateSCB (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
 {
-  int        idx;
-  long       flags;
+  int idx;
+  long flags;
 
-  spin_lock_irqsave(&mega_lock,flags);
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
+  spin_lock_irqsave (&mega_lock, flags);
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].idx < 0) {
 
-      /* Set Index and SCB pointer */ 
-      megaCfg->scbList[idx].flag  = 0;
-      megaCfg->scbList[idx].idx   = idx;
+      /* Set Index and SCB pointer */
+      megaCfg->scbList[idx].flag = 0;
+      megaCfg->scbList[idx].idx = idx;
       megaCfg->scbList[idx].SCpnt = SCpnt;
-      megaCfg->scbList[idx].next  = NULL;
-      spin_unlock_irqrestore(&mega_lock,flags);
+      megaCfg->scbList[idx].next = NULL;
+      spin_unlock_irqrestore (&mega_lock, flags);
 
       if (megaCfg->scbList[idx].sgList == NULL) {
        megaCfg->scbList[idx].sgList =
-                  kmalloc(sizeof(mega_sglist)*MAX_SGLIST,GFP_ATOMIC|GFP_DMA);
+         kmalloc (sizeof (mega_sglist) * MAX_SGLIST, GFP_ATOMIC | GFP_DMA);
       }
 
       return &megaCfg->scbList[idx];
     }
   }
-  spin_unlock_irqrestore(&mega_lock,flags);
+  spin_unlock_irqrestore (&mega_lock, flags);
+
+  printk (KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
 
-  printk(KERN_WARNING "Megaraid: Could not allocate free SCB!!!\n");
-  
   return NULL;
 }
 
-/*=======================
- * Free a SCB structure
- *=======================*/
-static void freeSCB(mega_scb *scb)
+//=======================
+// Free a SCB structure
+//=======================
+static void freeSCB (mega_scb * scb)
 {
-  long flags;
-
-  spin_lock_irqsave(&mega_lock,flags);
-  scb->flag  = 0;
-  scb->idx   = -1;
-  scb->next  = NULL;
+  scb->flag = 0;
+  scb->idx = -1;
+  scb->next = NULL;
   scb->SCpnt = NULL;
-  spin_unlock_irqrestore(&mega_lock,flags);
 }
 
 /* Run through the list of completed requests */
-static void mega_rundoneq()
+static void mega_rundoneq ()
 {
   mega_host_config *megaCfg;
-  Scsi_Cmnd        *SCpnt;
-  long              islogical;
+  Scsi_Cmnd *SCpnt;
+  long islogical;
 
-  while(1) {
-    DEQUEUE(SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
-    if (SCpnt == NULL) return;
+  while (1) {
+    DEQUEUE (SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+    if (SCpnt == NULL)
+      return;
 
-    megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+    megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
     /* Check if we're allowing access to RAID drives or physical
      *  if use_raid == 1 and this wasn't a disk on the max channel or
@@ -380,14 +385,15 @@ static void mega_rundoneq()
      */
     islogical = (SCpnt->channel == megaCfg->host->max_channel) ? 1 : 0;
     if (SCpnt->cmnd[0] == INQUIRY &&
-       ((((u_char*)SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
+       ((((u_char *) SCpnt->request_buffer)[0] & 0x1F) == TYPE_DISK) &&
        (islogical != use_raid)) {
-       SCpnt->result = 0xF0;
+      SCpnt->result = 0xF0;
     }
 
     /* Convert result to error */
-    switch(SCpnt->result) {
-    case 0x00: case 0x02:
+    switch (SCpnt->result) {
+    case 0x00:
+    case 0x02:
       SCpnt->result |= (DID_OK << 16);
       break;
     case 0x8:
@@ -399,16 +405,20 @@ static void mega_rundoneq()
     }
 
     /* Callback */
-    callDone(SCpnt);
+    callDone (SCpnt);
   }
 }
 
 /* Add command to the list of completed requests */
-static void mega_cmd_done(mega_host_config *megaCfg,mega_scb *pScb, int status)
+static void mega_cmd_done (mega_host_config * megaCfg, mega_scb * pScb, int status)
 {
+  long flags;
+
   pScb->SCpnt->result = status;
-  ENQUEUE(pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
-  freeSCB(pScb);
+  ENQUEUE (pScb->SCpnt, Scsi_Cmnd, qCompleted, host_scribble);
+  spin_lock_irqsave (&mega_lock, flags);
+  freeSCB (pScb);
+  spin_unlock_irqrestore (&mega_lock, flags);
 }
 
 /*----------------------------------------------------
@@ -416,45 +426,42 @@ static void mega_cmd_done(mega_host_config *megaCfg,mega_scb *pScb, int status)
  *
  * Run as a scheduled task 
  *----------------------------------------------------*/
-static void mega_runque(void *dummy)
+static void mega_runque (void *dummy)
 {
   mega_host_config *megaCfg;
-  mega_scb         *pScb;
-  long              flags;
+  mega_scb *pScb;
+  long flags;
 
   /* Take care of any completed requests */
-  mega_rundoneq();
+  mega_rundoneq ();
 
-  DEQUEUE(pScb,mega_scb,qPending,next);
+  DEQUEUE (pScb, mega_scb, qPending, next);
 
   if (pScb) {
-    megaCfg = (mega_host_config *)pScb->SCpnt->host->hostdata;
-
-    if (megaCfg->mbox->busy || megaCfg->flag & (IN_ISR|PENDING)) {
-      printk(KERN_DEBUG "PENDING = %x, IN_ISR = %x, mbox.busy = %x\n",(u_int)(megaCfg->flag
-            & PENDING), (u_int)(megaCfg->flag & IN_ISR), megaCfg->mbox->busy);
-      TRACE(("%.08lx %.02x <%d.%d.%d> intr%d busy%d isr%d pending%d\n",
-            pScb->SCpnt->serial_number,
-            pScb->SCpnt->cmnd[0],
-            pScb->SCpnt->channel,
-            pScb->SCpnt->target,
-            pScb->SCpnt->lun,
-            intr_count,
-            megaCfg->mbox->busy,
-            (megaCfg->flag & IN_ISR)  ? 1 : 0,
-            (megaCfg->flag & PENDING) ? 1 : 0));
+    megaCfg = (mega_host_config *) pScb->SCpnt->host->hostdata;
+
+    if (megaCfg->mbox->busy || megaCfg->flag & (IN_ISR | PENDING)) {
+      TRACE (("%.08lx %.02x <%d.%d.%d> busy%d isr%d pending%d\n",
+             pScb->SCpnt->serial_number,
+             pScb->SCpnt->cmnd[0],
+             pScb->SCpnt->channel,
+             pScb->SCpnt->target,
+             pScb->SCpnt->lun,
+             megaCfg->mbox->busy,
+             (megaCfg->flag & IN_ISR) ? 1 : 0,
+             (megaCfg->flag & PENDING) ? 1 : 0));
     }
 
-    if (MegaIssueCmd(megaCfg, pScb->mboxData, pScb, 1)) {
-      printk(KERN_DEBUG "MegaIssueCmd returned BUSY.  Rescheduling command.\n");
+    if (MegaIssueCmd (megaCfg, pScb->mboxData, pScb, 1)) {
       /* We're BUSY... come back later */
-      spin_lock_irqsave(&mega_lock,flags);
+      spin_lock_irqsave (&mega_lock, flags);
       pScb->next = qPending;
-      qPending   = pScb;
-      spin_unlock_irqrestore(&mega_lock,flags);
+      qPending = pScb;
+      spin_unlock_irqrestore (&mega_lock, flags);
 
-      if (!(megaCfg->flag & PENDING)) { /* If PENDING, irq will schedule task */
-          queue_task(&runq, &tq_scheduler);
+      if (!(megaCfg->flag & PENDING)) {
+       /* If PENDING, irq will schedule task */
+       queue_task (&runq, &tq_scheduler);
       }
     }
   }
@@ -468,17 +475,20 @@ static void mega_runque(void *dummy)
  * If NULL is returned, the scsi_done function MUST have been called
  *
  *-------------------------------------------------------------------*/
-static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
+static mega_scb * mega_build_cmd (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
 {
-  mega_scb      *pScb;
-  mega_mailbox  *mbox;
+  mega_scb *pScb;
+  mega_mailbox *mbox;
   mega_passthru *pthru;
-  long           seg;
+  long seg;
+
+  if (SCpnt->cmnd[0] & 0x80)   /* ioctl from megamgr */
+    return mega_ioctl (megaCfg, SCpnt);
 
   /* We don't support multi-luns */
   if (SCpnt->lun != 0) {
     SCpnt->result = (DID_BAD_TARGET << 16);
-    callDone(SCpnt);
+    callDone (SCpnt);
     return NULL;
   }
 
@@ -488,44 +498,44 @@ static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
    *
    *-----------------------------------------------------*/
   if (SCpnt->channel == megaCfg->host->max_channel) {
-    switch(SCpnt->cmnd[0]) {
+    switch (SCpnt->cmnd[0]) {
     case TEST_UNIT_READY:
-      memset(SCpnt->request_buffer, 0, SCpnt->request_bufflen);
+      memset (SCpnt->request_buffer, 0, SCpnt->request_bufflen);
       SCpnt->result = (DID_OK << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
 
     case MODE_SENSE:
-      memset(SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
+      memset (SCpnt->request_buffer, 0, SCpnt->cmnd[4]);
       SCpnt->result = (DID_OK << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
 
     case READ_CAPACITY:
     case INQUIRY:
       /* Allocate a SCB and initialize passthru */
-      if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) {
+      if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
        SCpnt->result = (DID_ERROR << 16);
-       callDone(SCpnt);
+       callDone (SCpnt);
        return NULL;
       }
       pthru = &pScb->pthru;
-      mbox  = (mega_mailbox *)&pScb->mboxData;
-
-      memset(mbox,  0, sizeof(pScb->mboxData));
-      memset(pthru, 0, sizeof(mega_passthru));
-      pthru->timeout      = 0;
-      pthru->ars          = 0;
-      pthru->islogical    = 1;
-      pthru->logdrv       = SCpnt->target;
-      pthru->cdblen       = SCpnt->cmd_len;
-      pthru->dataxferaddr = virt_to_bus(SCpnt->request_buffer);
-      pthru->dataxferlen  = SCpnt->request_bufflen;
-      memcpy(pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+      mbox = (mega_mailbox *) & pScb->mboxData;
+
+      memset (mbox, 0, sizeof (pScb->mboxData));
+      memset (pthru, 0, sizeof (mega_passthru));
+      pthru->timeout = 0;
+      pthru->ars = 0;
+      pthru->islogical = 1;
+      pthru->logdrv = SCpnt->target;
+      pthru->cdblen = SCpnt->cmd_len;
+      pthru->dataxferaddr = virt_to_bus (SCpnt->request_buffer);
+      pthru->dataxferlen = SCpnt->request_bufflen;
+      memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
 
       /* Initialize mailbox area */
-      mbox->cmd      = MEGA_MBOXCMD_PASSTHRU;
-      mbox->xferaddr = virt_to_bus(pthru);
+      mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+      mbox->xferaddr = virt_to_bus (pthru);
 
       return pScb;
 
@@ -534,51 +544,51 @@ static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
     case READ_10:
     case WRITE_10:
       /* Allocate a SCB and initialize mailbox */
-      if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) {
+      if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
        SCpnt->result = (DID_ERROR << 16);
-       callDone(SCpnt);
+       callDone (SCpnt);
        return NULL;
       }
-      mbox = (mega_mailbox *)&pScb->mboxData;
+      mbox = (mega_mailbox *) & pScb->mboxData;
 
-      memset(mbox, 0, sizeof(pScb->mboxData));
+      memset (mbox, 0, sizeof (pScb->mboxData));
       mbox->logdrv = SCpnt->target;
-      mbox->cmd    = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
+      mbox->cmd = (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == READ_10) ?
        MEGA_MBOXCMD_LREAD : MEGA_MBOXCMD_LWRITE;
-      
+
       /* 6-byte */
       if (*SCpnt->cmnd == READ_6 || *SCpnt->cmnd == WRITE_6) {
-       mbox->numsectors = 
-         (u_long)SCpnt->cmnd[4];
-       mbox->lba = 
-         ((u_long)SCpnt->cmnd[1] << 16) |
-         ((u_long)SCpnt->cmnd[2] << 8) |
-         (u_long)SCpnt->cmnd[3];
+       mbox->numsectors =
+         (u_long) SCpnt->cmnd[4];
+       mbox->lba =
+         ((u_long) SCpnt->cmnd[1] << 16) |
+         ((u_long) SCpnt->cmnd[2] << 8) |
+         (u_long) SCpnt->cmnd[3];
        mbox->lba &= 0x1FFFFF;
       }
-      
+
       /* 10-byte */
       if (*SCpnt->cmnd == READ_10 || *SCpnt->cmnd == WRITE_10) {
-       mbox->numsectors = 
-         (u_long)SCpnt->cmnd[8] |
-         ((u_long)SCpnt->cmnd[7] << 8);
+       mbox->numsectors =
+         (u_long) SCpnt->cmnd[8] |
+         ((u_long) SCpnt->cmnd[7] << 8);
        mbox->lba =
-         ((u_long)SCpnt->cmnd[2] << 24) |
-         ((u_long)SCpnt->cmnd[3] << 16) |
-         ((u_long)SCpnt->cmnd[4] << 8) |
-         (u_long)SCpnt->cmnd[5];
+         ((u_long) SCpnt->cmnd[2] << 24) |
+         ((u_long) SCpnt->cmnd[3] << 16) |
+         ((u_long) SCpnt->cmnd[4] << 8) |
+         (u_long) SCpnt->cmnd[5];
       }
-      
+
       /* Calculate Scatter-Gather info */
-      mbox->numsgelements = build_sglist(megaCfg, pScb, 
-                                        (u_long*)&mbox->xferaddr,
-                                        (u_long*)&seg);
+      mbox->numsgelements = build_sglist (megaCfg, pScb,
+                                         (u_long *) & mbox->xferaddr,
+                                         (u_long *) & seg);
 
       return pScb;
-      
+
     default:
       SCpnt->result = (DID_BAD_TARGET << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
     }
   }
@@ -589,113 +599,196 @@ static mega_scb *mega_build_cmd(mega_host_config *megaCfg, Scsi_Cmnd *SCpnt)
    *-----------------------------------------------------*/
   else {
     /* Allocate a SCB and initialize passthru */
-    if ((pScb = allocateSCB(megaCfg,SCpnt)) == NULL) {
+    if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
       SCpnt->result = (DID_ERROR << 16);
-      callDone(SCpnt);
+      callDone (SCpnt);
       return NULL;
     }
     pthru = &pScb->pthru;
-    mbox  = (mega_mailbox *)pScb->mboxData;
-    
-    memset(mbox,  0, sizeof(pScb->mboxData));
-    memset(pthru, 0, sizeof(mega_passthru));
-    pthru->timeout   = 0;
-    pthru->ars       = 0;
+    mbox = (mega_mailbox *) pScb->mboxData;
+
+    memset (mbox, 0, sizeof (pScb->mboxData));
+    memset (pthru, 0, sizeof (mega_passthru));
+    pthru->timeout = 0;
+    pthru->ars = 0;
     pthru->islogical = 0;
-    pthru->channel   = SCpnt->channel;
-    pthru->target    = SCpnt->target;
-    pthru->cdblen    = SCpnt->cmd_len;
-    memcpy(pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
-   
-    pthru->numsgelements = build_sglist(megaCfg, pScb,
-                                       (u_long *)&pthru->dataxferaddr,
-                                       (u_long *)&pthru->dataxferlen);
-    
+    pthru->channel = SCpnt->channel;
+    pthru->target = SCpnt->target;
+    pthru->cdblen = SCpnt->cmd_len;
+    memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmd_len);
+
+    pthru->numsgelements = build_sglist (megaCfg, pScb,
+                                        (u_long *) & pthru->dataxferaddr,
+                                        (u_long *) & pthru->dataxferlen);
+
     /* Initialize mailbox */
-    mbox->cmd      = MEGA_MBOXCMD_PASSTHRU;
-    mbox->xferaddr = virt_to_bus(pthru);
+    mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+    mbox->xferaddr = virt_to_bus (pthru);
 
     return pScb;
   }
   return NULL;
 }
 
+/*--------------------------------------------------------------------
+ * build RAID commands for controller, passed down through ioctl()
+ *--------------------------------------------------------------------*/
+static mega_scb * mega_ioctl (mega_host_config * megaCfg, Scsi_Cmnd * SCpnt)
+{
+  mega_scb *pScb;
+  mega_ioctl_mbox *mbox;
+  mega_mailbox *mailbox;
+  mega_passthru *pthru;
+  long seg;
+
+  if ((pScb = allocateSCB (megaCfg, SCpnt)) == NULL) {
+    SCpnt->result = (DID_ERROR << 16);
+    callDone (SCpnt);
+    return NULL;
+  }
+
+  mbox = (mega_ioctl_mbox *) & pScb->mboxData;
+  mailbox = (mega_mailbox *) & pScb->mboxData;
+  memset (mailbox, 0, sizeof (pScb->mboxData));
+
+  if (SCpnt->cmnd[0] == 0x83) {        /* passthrough command */
+    char cdblen = SCpnt->cmnd[2];
+
+    pthru = &pScb->pthru;
+    memset (pthru, 0, sizeof (mega_passthru));
+    pthru->islogical = SCpnt->cmnd[cdblen + 3] & 0x80;
+    pthru->timeout = SCpnt->cmnd[cdblen + 3] & 0x07;
+    pthru->reqsenselen = 10;   /* ? MAX_SENSE; */
+    pthru->ars = SCpnt->cmnd[cdblen + 3] & 0x08;
+    pthru->logdrv = SCpnt->cmnd[cdblen + 4];
+    pthru->channel = SCpnt->cmnd[cdblen + 5];
+    pthru->target = SCpnt->cmnd[cdblen + 6];
+    pthru->cdblen = cdblen;
+    memcpy (pthru->cdb, SCpnt->cmnd, SCpnt->cmnd[2]);
+
+    mailbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+    mailbox->xferaddr = virt_to_bus (pthru);
+
+    pthru->numsgelements = build_sglist (megaCfg, pScb,
+                                        (u_long *) & pthru->dataxferaddr,
+                                        (u_long *) & pthru->dataxferlen);
+
+    return pScb;
+  }
+  /* else normal (nonpassthru) command */
+
+  mbox->cmd = SCpnt->cmnd[0] & 0x7F;
+  mbox->channel = SCpnt->cmnd[1];
+  mbox->param = SCpnt->cmnd[2];
+  mbox->pad[0] = SCpnt->cmnd[3];
+  mbox->logdrv = SCpnt->cmnd[4];
+
+  mbox->numsgelements = build_sglist (megaCfg, pScb,
+                                     (u_long *) & mbox->xferaddr,
+                                     (u_long *) & seg);
+
+  return (pScb);
+}
+
+
 /*--------------------------------------------------------------------
  * Interrupt service routine
  *--------------------------------------------------------------------*/
-static void megaraid_isr(int irq, void *devp, struct pt_regs *regs)
+static void megaraid_isr (int irq, void *devp, struct pt_regs *regs)
 {
-  mega_host_config *megaCfg;
-  u_char            byte, idx, sIdx;
-  u_long            dword;
-  mega_mailbox     *mbox;
-  mega_scb         *pScb;
-  long              flags;
-  int               qCnt, qStatus;
+  mega_host_config    *megaCfg;
+  u_char byte, idx, sIdx;
+  u_long dword;
+  mega_mailbox *mbox;
+  mega_scb *pScb;
+  long flags;
+  int qCnt, qStatus;
 
-  megaCfg = (mega_host_config *)devp;
-  mbox    = (mega_mailbox *)megaCfg->mbox;
+  megaCfg = (mega_host_config *) devp;
+  mbox = (mega_mailbox *) megaCfg->mbox;
 
   if (megaCfg->host->irq == irq) {
-    spin_lock_irqsave(&mega_lock,flags);
+
+#if LINUX_VERSION_CODE >= 0x20100
+    spin_lock_irqsave (&io_request_lock, flags);
+#endif
+
+    spin_lock_irqsave (&mega_lock, flags);
 
     if (megaCfg->flag & IN_ISR) {
-      TRACE(("ISR called reentrantly!!\n"));
+      TRACE (("ISR called reentrantly!!\n"));
     }
 
     megaCfg->flag |= IN_ISR;
 
     /* Check if a valid interrupt is pending */
     if (megaCfg->flag & BOARD_QUARTZ) {
-        dword = RDOUTDOOR(megaCfg);
-        if (dword != 0x10001234) {
-            /* Spurious interrupt */
-            megaCfg->flag &= ~IN_ISR;
-            spin_unlock_irqrestore(&mega_lock,flags);
-            return;
-        }
-        WROUTDOOR(megaCfg,dword);
-    } else {
-        byte = READ_PORT(megaCfg->host->io_port, INTR_PORT);
-        if ((byte & VALID_INTR_BYTE) == 0) {
-          /* Spurious interrupt */
-          megaCfg->flag &= ~IN_ISR;
-          spin_unlock_irqrestore(&mega_lock,flags);
-          return;
-        }
-        WRITE_PORT(megaCfg->host->io_port, INTR_PORT, byte);
+      dword = RDOUTDOOR (megaCfg);
+      if (dword != 0x10001234) {
+       /* Spurious interrupt */
+       megaCfg->flag &= ~IN_ISR;
+       spin_unlock_irqrestore (&mega_lock, flags);
+#if LINUX_VERSION_CODE >= 0x20100
+        spin_unlock_irqrestore (&io_request_lock, flags);
+#endif
+       return;
+      }
+      WROUTDOOR (megaCfg, dword);
     }
-    
-    qCnt    = mbox->numstatus;
+    else {
+      byte = READ_PORT (megaCfg->host->io_port, INTR_PORT);
+      if ((byte & VALID_INTR_BYTE) == 0) {
+       /* Spurious interrupt */
+       megaCfg->flag &= ~IN_ISR;
+       spin_unlock_irqrestore (&mega_lock, flags);
+#if LINUX_VERSION_CODE >= 0x20100
+        spin_unlock_irqrestore (&io_request_lock, flags);
+#endif
+       return;
+      }
+      WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
+    }
+
+    qCnt = mbox->numstatus;
     qStatus = mbox->status;
 
-    if (qCnt > 1) {TRACE(("ISR: Received %d status\n", qCnt))
-        printk(KERN_DEBUG "Got numstatus = %d\n",qCnt);
+    if (qCnt > 1) {
+      TRACE (("ISR: Received %d status\n", qCnt))
+       printk (KERN_DEBUG "Got numstatus = %d\n", qCnt);
     }
-    
-    for(idx=0; idx<qCnt; idx++) {
+
+    for (idx = 0; idx < qCnt; idx++) {
       sIdx = mbox->completed[idx];
       if (sIdx > 0) {
-       pScb = &megaCfg->scbList[sIdx-1];
-        spin_unlock_irqrestore(&mega_lock,flags); /* locks within cmd_done */
-       mega_cmd_done(megaCfg,&megaCfg->scbList[sIdx-1], qStatus);
-        spin_lock_irqsave(&mega_lock,flags);
+       pScb = &megaCfg->scbList[sIdx - 1];
+       spin_unlock_irqrestore (&mega_lock, flags); /* megalock within cmd_done */
+       mega_cmd_done (megaCfg, &megaCfg->scbList[sIdx - 1], qStatus);
+       spin_lock_irqsave (&mega_lock, flags);
       }
     }
     if (megaCfg->flag & BOARD_QUARTZ) {
-        WRINDOOR(megaCfg,virt_to_bus(megaCfg->mbox)|0x2);
-        while (RDINDOOR(megaCfg) & 0x02);
-    } else {
-        CLEAR_INTR(megaCfg->host->io_port);
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+      while (RDINDOOR (megaCfg) & 0x02);
+    }
+    else {
+      CLEAR_INTR (megaCfg->host->io_port);
     }
 
     megaCfg->flag &= ~IN_ISR;
     megaCfg->flag &= ~PENDING;
 
+    spin_unlock_irqrestore (&mega_lock, flags);
+    mega_runque (NULL);
+
+#if LINUX_VERSION_CODE >= 0x20100
+    spin_unlock_irqrestore (&io_request_lock, flags);
+#endif
+
+#if 0
     /* Queue as a delayed ISR routine */
-    queue_task_irq_off(&runq, &tq_immediate);
-    mark_bh(IMMEDIATE_BH);
-    spin_unlock_irqrestore(&mega_lock,flags);
+    queue_task_irq_off (&runq, &tq_immediate);
+    mark_bh (IMMEDIATE_BH);
+#endif
 
   }
 }
@@ -703,111 +796,128 @@ static void megaraid_isr(int irq, void *devp, struct pt_regs *regs)
 /*==================================================*/
 /* Wait until the controller's mailbox is available */
 /*==================================================*/
-static int busyWaitMbox(mega_host_config *megaCfg)
+static int busyWaitMbox (mega_host_config * megaCfg)
 {
-  mega_mailbox *mbox = (mega_mailbox *)megaCfg->mbox;
-  long          counter;
+  mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
+  long counter;
 
-  for(counter=0; counter<0xFFFFFF; counter++) {
-    if (!mbox->busy) return 0;
+  for (counter = 0; counter < 30000; counter++) {
+    udelay (100);
+    if (!mbox->busy)
+      return 0;
   }
-  return -1;
+  return -1;                   /* give up after 3 seconds */
 }
 
-/*=====================================================
- * Post a command to the card
- *
- * Arguments:
- *   mega_host_config *megaCfg - Controller structure
- *   u_char *mboxData - Mailbox area, 16 bytes
- *   mega_scb *pScb   - SCB posting (or NULL if N/A)
- *   int intr         - if 1, interrupt, 0 is blocking
- *=====================================================*/
-static int MegaIssueCmd(mega_host_config *megaCfg,
-                       u_char *mboxData,
-                       mega_scb *pScb,
-                       int intr)
+//=====================================================
+// Post a command to the card
+//
+// Arguments:
+//   mega_host_config *megaCfg - Controller structure
+//   u_char *mboxData - Mailbox area, 16 bytes
+//   mega_scb *pScb   - SCB posting (or NULL if N/A)
+//   int intr         - if 1, interrupt, 0 is blocking
+//=====================================================
+static int MegaIssueCmd (mega_host_config * megaCfg,
+             u_char * mboxData,
+             mega_scb * pScb,
+             int intr)
 {
-  mega_mailbox *mbox = (mega_mailbox *)megaCfg->mbox;
-  long          flags;
-  u_char        byte;
-  u_long        cmdDone;
+  mega_mailbox *mbox = (mega_mailbox *) megaCfg->mbox;
+  long flags;
+  u_char byte;
+  u_long cmdDone;
+
+  mboxData[0x1] = (pScb ? pScb->idx + 1 : 0x00);       /* Set cmdid */
+  mboxData[0xF] = 1;           /* Set busy */
 
-  mboxData[0x1] = (pScb ? pScb->idx+1 : 0x00);  /* Set cmdid */
-  mboxData[0xF] = 1;                            /* Set busy */
+  spin_lock_irqsave(&mega_lock,flags);
 
   /* one bad report of problem when issuing a command while pending.
    * Wasn't able to duplicate, but it doesn't really affect performance
    * anyway, so don't allow command while PENDING
    */
+
   if (megaCfg->flag & PENDING) {
+    spin_unlock_irqrestore(&mega_lock,flags);
     return -1;
   }
 
   /* Wait until mailbox is free */
-  if (busyWaitMbox(megaCfg)) {
+  if (busyWaitMbox (megaCfg)) {
     if (pScb) {
-      TRACE(("Mailbox busy %.08lx <%d.%d.%d>\n", pScb->SCpnt->serial_number,
-            pScb->SCpnt->channel, pScb->SCpnt->target, pScb->SCpnt->lun));
+      TRACE (("Mailbox busy %.08lx <%d.%d.%d>\n", pScb->SCpnt->serial_number,
+             pScb->SCpnt->channel, pScb->SCpnt->target, pScb->SCpnt->lun));
+    } else {
+       TRACE(("pScb NULL in MegaIssueCmd!\n"));
     }
+    spin_unlock_irqrestore(&mega_lock,flags);
     return -1;
   }
 
   /* Copy mailbox data into host structure */
-  spin_lock_irqsave(&mega_lock,flags);
-  memset(mbox, 0, sizeof(mega_mailbox));
-  memcpy(mbox, mboxData, 16);
-  spin_unlock_irqrestore(&mega_lock,flags);
+  memset (mbox, 0, sizeof (mega_mailbox));
+  memcpy (mbox, mboxData, 16);
 
   /* Kick IO */
   megaCfg->flag |= PENDING;
   if (intr) {
     /* Issue interrupt (non-blocking) command */
     if (megaCfg->flag & BOARD_QUARTZ) {
-        mbox->mraid_poll = 0; 
-        mbox->mraid_ack = 0; 
-        WRINDOOR(megaCfg, virt_to_bus(megaCfg->mbox) | 0x1);
-    } else {
-        ENABLE_INTR(megaCfg->host->io_port);
-        ISSUE_COMMAND(megaCfg->host->io_port);
+      mbox->mraid_poll = 0;
+      mbox->mraid_ack = 0;
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1);
     }
+    else {
+      ENABLE_INTR (megaCfg->host->io_port);
+      ISSUE_COMMAND (megaCfg->host->io_port);
+    }
+    spin_unlock_irqrestore(&mega_lock,flags);
   }
-  else {      /* Issue non-ISR (blocking) command */
+  else {                       /* Issue non-ISR (blocking) command */
 
     if (megaCfg->flag & BOARD_QUARTZ) {
 
-      mbox->mraid_poll = 0; 
-      mbox->mraid_ack = 0; 
-      WRINDOOR(megaCfg, virt_to_bus(megaCfg->mbox) | 0x1);
+      mbox->mraid_poll = 0;
+      mbox->mraid_ack = 0;
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x1);
 
-      while((cmdDone=RDOUTDOOR(megaCfg)) != 0x10001234);
-      WROUTDOOR(megaCfg, cmdDone);
+      while ((cmdDone = RDOUTDOOR (megaCfg)) != 0x10001234);
+      WROUTDOOR (megaCfg, cmdDone);
 
+      spin_unlock_irqrestore(&mega_lock,flags);
       if (pScb) {
-       mega_cmd_done(megaCfg,pScb, mbox->status);
-       mega_rundoneq();
+       mega_cmd_done (megaCfg, pScb, mbox->status);
+       mega_rundoneq ();
       }
 
-      WRINDOOR(megaCfg,virt_to_bus(megaCfg->mbox) | 0x2);
-      while(RDINDOOR(megaCfg) & 0x2);
+      WRINDOOR (megaCfg, virt_to_bus (megaCfg->mbox) | 0x2);
+      while (RDINDOOR (megaCfg) & 0x2);
 
       megaCfg->flag &= ~PENDING;
+
     }
     else {
-      DISABLE_INTR(megaCfg->host->io_port);
-      ISSUE_COMMAND(megaCfg->host->io_port);
-      
-      while(!((byte=READ_PORT(megaCfg->host->io_port,INTR_PORT))&INTR_VALID));
-      WRITE_PORT(megaCfg->host->io_port, INTR_PORT, byte);
-      
-      ENABLE_INTR(megaCfg->host->io_port);
-      CLEAR_INTR(megaCfg->host->io_port);
-      
+      DISABLE_INTR (megaCfg->host->io_port);
+      ISSUE_COMMAND (megaCfg->host->io_port);
+
+      while (!((byte = READ_PORT (megaCfg->host->io_port, INTR_PORT)) & INTR_VALID));
+      WRITE_PORT (megaCfg->host->io_port, INTR_PORT, byte);
+
+
+      ENABLE_INTR (megaCfg->host->io_port);
+      CLEAR_INTR (megaCfg->host->io_port);
+      megaCfg->flag &= ~PENDING;
+      spin_unlock_irqrestore(&mega_lock,flags);
+
       if (pScb) {
-       mega_cmd_done(megaCfg,pScb, mbox->status);
-       mega_rundoneq();
+       mega_cmd_done (megaCfg, pScb, mbox->status);
+       mega_rundoneq ();
       }
-      megaCfg->flag &= ~PENDING;
+      else {
+       TRACE (("Error: NULL pScb!\n"));
+      }
+
     }
   }
 
@@ -817,40 +927,40 @@ static int MegaIssueCmd(mega_host_config *megaCfg,
 /*-------------------------------------------------------------------
  * Copies data to SGLIST
  *-------------------------------------------------------------------*/
-static int build_sglist(mega_host_config *megaCfg, mega_scb *scb, 
-                       u_long *buffer, u_long *length)
+static int build_sglist (mega_host_config * megaCfg, mega_scb * scb,
+             u_long * buffer, u_long * length)
 {
   struct scatterlist *sgList;
   int idx;
 
   /* Scatter-gather not used */
   if (scb->SCpnt->use_sg == 0) {
-    *buffer = virt_to_bus(scb->SCpnt->request_buffer);
-    *length = (u_long)scb->SCpnt->request_bufflen;
+    *buffer = virt_to_bus (scb->SCpnt->request_buffer);
+    *length = (u_long) scb->SCpnt->request_bufflen;
     return 0;
   }
 
-  sgList = (struct scatterlist *)scb->SCpnt->buffer;
+  sgList = (struct scatterlist *) scb->SCpnt->buffer;
   if (scb->SCpnt->use_sg == 1) {
-    *buffer = virt_to_bus(sgList[0].address);
-    *length = (u_long)sgList[0].length;
+    *buffer = virt_to_bus (sgList[0].address);
+    *length = (u_long) sgList[0].length;
     return 0;
   }
 
   /* Copy Scatter-Gather list info into controller structure */
-  for(idx=0; idx<scb->SCpnt->use_sg; idx++) {
-    scb->sgList[idx].address = virt_to_bus(sgList[idx].address);
-    scb->sgList[idx].length  = (u_long)sgList[idx].length;
+  for (idx = 0; idx < scb->SCpnt->use_sg; idx++) {
+    scb->sgList[idx].address = virt_to_bus (sgList[idx].address);
+    scb->sgList[idx].length = (u_long) sgList[idx].length;
   }
-  
+
   /* Reset pointer and length fields */
-  *buffer = virt_to_bus(scb->sgList);
+  *buffer = virt_to_bus (scb->sgList);
   *length = 0;
 
   /* Return count of SG requests */
   return scb->SCpnt->use_sg;
 }
-    
+
 /*--------------------------------------------------------------------
  * Initializes the adress of the controller's mailbox register
  *  The mailbox register is used to issue commands to the card.
@@ -867,25 +977,25 @@ static int build_sglist(mega_host_config *megaCfg, mega_scb *scb,
  *   10 01 numstatus byte
  *   11 01 status byte
  *--------------------------------------------------------------------*/
-static int mega_register_mailbox(mega_host_config *megaCfg, u_long paddr)
+static int mega_register_mailbox (mega_host_config * megaCfg, u_long paddr)
 {
   /* align on 16-byte boundry */
   megaCfg->mbox = &megaCfg->mailbox;
-  megaCfg->mbox = (mega_mailbox *) ((((ulong)megaCfg->mbox) + 16)&0xfffffff0);
-  paddr = (paddr+16)&0xfffffff0;
+  megaCfg->mbox = (mega_mailbox *) ((((ulong) megaCfg->mbox) + 16) & 0xfffffff0);
+  paddr = (paddr + 16) & 0xfffffff0;
 
   /* Register mailbox area with the firmware */
   if (megaCfg->flag & BOARD_QUARTZ) {
   }
   else {
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT0, paddr         & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT1, (paddr >>  8) & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF);
-    WRITE_PORT(megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE);
-    
-    CLEAR_INTR(megaCfg->host->io_port);
-    ENABLE_INTR(megaCfg->host->io_port);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT0, paddr & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT1, (paddr >> 8) & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT2, (paddr >> 16) & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, MBOX_PORT3, (paddr >> 24) & 0xFF);
+    WRITE_PORT (megaCfg->host->io_port, ENABLE_MBOX_REGION, ENABLE_MBOX_BYTE);
+
+    CLEAR_INTR (megaCfg->host->io_port);
+    ENABLE_INTR (megaCfg->host->io_port);
   }
   return 0;
 }
@@ -893,77 +1003,79 @@ static int mega_register_mailbox(mega_host_config *megaCfg, u_long paddr)
 /*-------------------------------------------------------------------
  * Issue an adapter info query to the controller
  *-------------------------------------------------------------------*/
-static int mega_i_query_adapter(mega_host_config *megaCfg)
+static int mega_i_query_adapter (mega_host_config * megaCfg)
 {
   mega_RAIDINQ *adapterInfo;
   mega_mailbox *mbox;
-  u_char        mboxData[16];
-  u_long        paddr;
+  u_char mboxData[16];
+  u_long paddr;
 
-  spin_lock_init(&mega_lock);
+  spin_lock_init (&mega_lock);
   /* Initialize adapter inquiry */
-  paddr = virt_to_bus(megaCfg->mega_buffer);
-  mbox  = (mega_mailbox *)mboxData;
+  paddr = virt_to_bus (megaCfg->mega_buffer);
+  mbox = (mega_mailbox *) mboxData;
 
-  memset((void *)megaCfg->mega_buffer, 0, sizeof(megaCfg->mega_buffer));
-  memset(mbox, 0, 16);
+  memset ((void *) megaCfg->mega_buffer, 0, sizeof (megaCfg->mega_buffer));
+  memset (mbox, 0, 16);
 
   /* Initialize mailbox registers */
-  mbox->cmd      = MEGA_MBOXCMD_ADAPTERINQ;
+  mbox->cmd = MEGA_MBOXCMD_ADAPTERINQ;
   mbox->xferaddr = paddr;
 
   /* Issue a blocking command to the card */
-  MegaIssueCmd(megaCfg, mboxData, NULL, 0);
-  
+  MegaIssueCmd (megaCfg, mboxData, NULL, 0);
+
   /* Initialize host/local structures with Adapter info */
-  adapterInfo = (mega_RAIDINQ *)megaCfg->mega_buffer;
+  adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer;
   megaCfg->host->max_channel = adapterInfo->AdpInfo.ChanPresent;
-  megaCfg->host->max_id      = adapterInfo->AdpInfo.MaxTargPerChan;
-  megaCfg->numldrv           = adapterInfo->LogdrvInfo.NumLDrv;
+/*  megaCfg->host->max_id = adapterInfo->AdpInfo.MaxTargPerChan; */
+  megaCfg->host->max_id = 9; /* max logical drives + 1 */
+  megaCfg->numldrv = adapterInfo->LogdrvInfo.NumLDrv;
 
 #if 0
-  printk(KERN_DEBUG "---- Logical drive info ----\n");
-  for(i=0; i<megaCfg->numldrv; i++) {
-    printk(KERN_DEBUG "%d: size: %ld prop: %x state: %x\n",i,
-          adapterInfo->LogdrvInfo.LDrvSize[i],
-          adapterInfo->LogdrvInfo.LDrvProp[i],
-          adapterInfo->LogdrvInfo.LDrvState[i]);
+  printk ("KERN_DEBUG ---- Logical drive info ----\n");
+  for (i = 0; i < megaCfg->numldrv; i++) {
+    printk ("%d: size: %ld prop: %x state: %x\n", i,
+           adapterInfo->LogdrvInfo.LDrvSize[i],
+           adapterInfo->LogdrvInfo.LDrvProp[i],
+           adapterInfo->LogdrvInfo.LDrvState[i]);
   }
-  printk(KERN_DEBUG "---- Physical drive info ----\n");
-  for(i=0; i<MAX_PHYSICAL_DRIVES; i++) {
-    if (i && !(i % 8)) printk("\n");
-    printk("%d: %x   ", i, adapterInfo->PhysdrvInfo.PDrvState[i]);
+  printk (KERN_DEBUG "---- Physical drive info ----\n");
+  for (i = 0; i < MAX_PHYSICAL_DRIVES; i++) {
+    if (i && !(i % 8))
+      printk ("\n");
+    printk ("%d: %x   ", i, adapterInfo->PhysdrvInfo.PDrvState[i]);
   }
-  printk("\n");
+  printk ("\n");
 #endif
 
   megaCfg->max_cmds = adapterInfo->AdpInfo.MaxConcCmds;
 
-#ifdef HP            /* use HP firmware and bios version encoding */
-      sprintf(megaCfg->fwVer,"%c%d%d.%d%d",
-          adapterInfo->AdpInfo.FwVer[2],
-          adapterInfo->AdpInfo.FwVer[1] >> 8,
-          adapterInfo->AdpInfo.FwVer[1] & 0x0f,
-          adapterInfo->AdpInfo.FwVer[2] >> 8,
-          adapterInfo->AdpInfo.FwVer[2] & 0x0f);
-      sprintf(megaCfg->biosVer,"%c%d%d.%d%d",
-          adapterInfo->AdpInfo.BiosVer[2],
-          adapterInfo->AdpInfo.BiosVer[1] >> 8,
-          adapterInfo->AdpInfo.BiosVer[1] & 0x0f,
-          adapterInfo->AdpInfo.BiosVer[2] >> 8,
-          adapterInfo->AdpInfo.BiosVer[2] & 0x0f);
+#ifdef HP                      /* use HP firmware and bios version encoding */
+  sprintf (megaCfg->fwVer, "%c%d%d.%d%d",
+          adapterInfo->AdpInfo.FwVer[2],
+          adapterInfo->AdpInfo.FwVer[1] >> 8,
+          adapterInfo->AdpInfo.FwVer[1] & 0x0f,
+          adapterInfo->AdpInfo.FwVer[2] >> 8,
+          adapterInfo->AdpInfo.FwVer[2] & 0x0f);
+  sprintf (megaCfg->biosVer, "%c%d%d.%d%d",
+          adapterInfo->AdpInfo.BiosVer[2],
+          adapterInfo->AdpInfo.BiosVer[1] >> 8,
+          adapterInfo->AdpInfo.BiosVer[1] & 0x0f,
+          adapterInfo->AdpInfo.BiosVer[2] >> 8,
+          adapterInfo->AdpInfo.BiosVer[2] & 0x0f);
 #else
-      memcpy(megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4);
-      megaCfg->fwVer[4] = 0;
+  memcpy (megaCfg->fwVer, adapterInfo->AdpInfo.FwVer, 4);
+  megaCfg->fwVer[4] = 0;
 
-      memcpy(megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4);
-      megaCfg->biosVer[4] = 0;
+  memcpy (megaCfg->biosVer, adapterInfo->AdpInfo.BiosVer, 4);
+  megaCfg->biosVer[4] = 0;
 #endif
 
-  printk(KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
-        megaCfg->fwVer,
-        megaCfg->biosVer,
-        megaCfg->numldrv);
+  printk (KERN_INFO "megaraid: [%s:%s] detected %d logical drives" CRLFSTR,
+         megaCfg->fwVer,
+         megaCfg->biosVer,
+         megaCfg->numldrv);
   return 0;
 }
 
@@ -976,47 +1088,56 @@ static int mega_i_query_adapter(mega_host_config *megaCfg)
 /*----------------------------------------------------------
  * Returns data to be displayed in /proc/scsi/megaraid/X
  *----------------------------------------------------------*/
-int megaraid_proc_info(char *buffer, char **start, off_t offset,
-                      int length, int inode, int inout)
+int megaraid_proc_info (char *buffer, char **start, off_t offset,
+                   int length, int inode, int inout)
 {
   *start = buffer;
   return 0;
 }
 
-int findCard(Scsi_Host_Template *pHostTmpl, 
-            u_short pciVendor, u_short pciDev,
-            long flag)
+int findCard (Scsi_Host_Template * pHostTmpl,
+         u_short pciVendor, u_short pciDev,
+         long flag)
 {
   mega_host_config *megaCfg;
   struct Scsi_Host *host;
-  u_char            pciBus, pciDevFun, megaIrq;
-  u_long            megaBase;
-  u_short           pciIdx = 0;
+  u_char pciBus, pciDevFun, megaIrq;
+  u_long megaBase;
+  u_short pciIdx = 0;
 
 #if LINUX_VERSION_CODE < 0x20100
-  while(!pcibios_find_device(pciVendor, pciDev, pciIdx,&pciBus,&pciDevFun)) {
+  while (!pcibios_find_device (pciVendor, pciDev, pciIdx, &pciBus, &pciDevFun)) {
+    if (flag & BOARD_QUARTZ) {
+      u_int magic;
+      pcibios_read_config_dword (pciBus, pciDevFun,
+                                PCI_CONF_AMISIG,
+                                &magic);
+      if (magic != AMI_SIGNATURE) {
+       continue;               /* not an AMI board */
+      }
+    }
 #else
-  struct pci_dev   *pdev=pci_devices;
+  struct pci_dev *pdev = pci_devices;
 
-  while((pdev = pci_find_device(pciVendor, pciDev, pdev))) {
+  while ((pdev = pci_find_device (pciVendor, pciDev, pdev))) {
     pciBus = pdev->bus->number;
     pciDevFun = pdev->devfn;
 #endif
-    printk(KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n",
-          pciVendor, 
-          pciDev, 
-          pciIdx, pciBus, 
-          PCI_SLOT(pciDevFun), 
-          PCI_FUNC(pciDevFun));
-    
+    printk (KERN_INFO "megaraid: found 0x%4.04x:0x%4.04x:idx %d:bus %d:slot %d:fun %d\n",
+           pciVendor,
+           pciDev,
+           pciIdx, pciBus,
+           PCI_SLOT (pciDevFun),
+           PCI_FUNC (pciDevFun));
+
     /* Read the base port and IRQ from PCI */
 #if LINUX_VERSION_CODE < 0x20100
-    pcibios_read_config_dword(pciBus, pciDevFun,
-                            PCI_BASE_ADDRESS_0,
-                            (u_int *)&megaBase);
-    pcibios_read_config_byte(pciBus, pciDevFun,                               
-                            PCI_INTERRUPT_LINE,
-                            &megaIrq);
+    pcibios_read_config_dword (pciBus, pciDevFun,
+                              PCI_BASE_ADDRESS_0,
+                              (u_int *) & megaBase);
+    pcibios_read_config_byte (pciBus, pciDevFun,
+                             PCI_INTERRUPT_LINE,
+                             &megaIrq);
 #else
     megaBase = pdev->base_address[0];
     megaIrq = pdev->irq;
@@ -1025,7 +1146,7 @@ int findCard(Scsi_Host_Template *pHostTmpl,
 
     if (flag & BOARD_QUARTZ) {
       megaBase &= PCI_BASE_ADDRESS_MEM_MASK;
-      megaBase = (long) ioremap(megaBase,128);
+      megaBase = (long) ioremap (megaBase, 128);
     }
     else {
       megaBase &= PCI_BASE_ADDRESS_IO_MASK;
@@ -1033,47 +1154,47 @@ int findCard(Scsi_Host_Template *pHostTmpl,
     }
 
     /* Initialize SCSI Host structure */
-    host    = scsi_register(pHostTmpl, sizeof(mega_host_config));
-    megaCfg = (mega_host_config *)host->hostdata;
-    memset(megaCfg, 0, sizeof(mega_host_config));
+    host = scsi_register (pHostTmpl, sizeof (mega_host_config));
+    megaCfg = (mega_host_config *) host->hostdata;
+    memset (megaCfg, 0, sizeof (mega_host_config));
+
+    printk (KERN_INFO " scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR,
+           host->host_no, (u_int) megaBase, megaIrq);
 
-    printk(KERN_INFO " scsi%d: Found a MegaRAID controller at 0x%x, IRQ: %d" CRLFSTR, 
-          host->host_no, (u_int)megaBase, megaIrq);
-    
     /* Copy resource info into structure */
-    megaCfg->flag            = flag;
-    megaCfg->host            = host;
-    megaCfg->base            = megaBase;
-    megaCfg->host->irq       = megaIrq;
-    megaCfg->host->io_port   = megaBase;
+    megaCfg->flag = flag;
+    megaCfg->host = host;
+    megaCfg->base = megaBase;
+    megaCfg->host->irq = megaIrq;
+    megaCfg->host->io_port = megaBase;
     megaCfg->host->n_io_port = 16;
     megaCfg->host->unique_id = (pciBus << 8) | pciDevFun;
-    megaCtlrs[numCtlrs++]    = megaCfg;
+    megaCtlrs[numCtlrs++] = megaCfg;
 
     if (flag != BOARD_QUARTZ) {
       /* Request our IO Range */
-      if (check_region(megaBase, 16)) {
-       printk(KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR);
-       scsi_unregister(host);
+      if (check_region (megaBase, 16)) {
+       printk (KERN_WARNING "megaraid: Couldn't register I/O range!" CRLFSTR);
+       scsi_unregister (host);
        continue;
       }
-      request_region(megaBase, 16, "megaraid");
+      request_region (megaBase, 16, "megaraid");
     }
 
     /* Request our IRQ */
-    if (request_irq(megaIrq, megaraid_isr, SA_SHIRQ, 
-                   "megaraid", megaCfg)) {
-      printk(KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR,
-            megaIrq);
-      scsi_unregister(host);
+    if (request_irq (megaIrq, megaraid_isr, SA_SHIRQ,
+                    "megaraid", megaCfg)) {
+      printk (KERN_WARNING "megaraid: Couldn't register IRQ %d!" CRLFSTR,
+             megaIrq);
+      scsi_unregister (host);
       continue;
     }
 
-    mega_register_mailbox(megaCfg, virt_to_bus((void*)&megaCfg->mailbox));
-    mega_i_query_adapter(megaCfg);
+    mega_register_mailbox (megaCfg, virt_to_bus ((void *) &megaCfg->mailbox));
+    mega_i_query_adapter (megaCfg);
 
     /* Initialize SCBs */
-    initSCB(megaCfg);
+    initSCB (megaCfg);
 
   }
   return pciIdx;
@@ -1082,23 +1203,22 @@ int findCard(Scsi_Host_Template *pHostTmpl,
 /*---------------------------------------------------------
  * Detects if a megaraid controller exists in this system
  *---------------------------------------------------------*/
-int megaraid_detect(Scsi_Host_Template *pHostTmpl)
+int megaraid_detect (Scsi_Host_Template * pHostTmpl)
 {
   int count = 0;
 
   pHostTmpl->proc_dir = &proc_scsi_megaraid;
 
 #if LINUX_VERSION_CODE < 0x20100
-  if (!pcibios_present()) 
-    {
-      printk(KERN_WARNING "megaraid: PCI bios not present." CRLFSTR);
-      return 0;
-    }
+  if (!pcibios_present ()) {
+    printk (KERN_WARNING "megaraid: PCI bios not present." CRLFSTR);
+    return 0;
+  }
 #endif
 
-  count += findCard(pHostTmpl, 0x101E, 0x9010, 0);
-  count += findCard(pHostTmpl, 0x101E, 0x9060, 0);
-  count += findCard(pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
+  count += findCard (pHostTmpl, 0x101E, 0x9010, 0);
+  count += findCard (pHostTmpl, 0x101E, 0x9060, 0);
+  count += findCard (pHostTmpl, 0x8086, 0x1960, BOARD_QUARTZ);
 
   return count;
 }
@@ -1106,33 +1226,40 @@ int megaraid_detect(Scsi_Host_Template *pHostTmpl)
 /*---------------------------------------------------------------------
  * Release the controller's resources
  *---------------------------------------------------------------------*/
-int megaraid_release(struct Scsi_Host *pSHost)
+int megaraid_release (struct Scsi_Host *pSHost)
 {
   mega_host_config *megaCfg;
-  mega_mailbox         *mbox;
-  u_char                mboxData[16];
+  mega_mailbox *mbox;
+  u_char mboxData[16];
+  int i;
 
-  megaCfg = (mega_host_config*)pSHost->hostdata;
-  mbox    = (mega_mailbox *)mboxData;
+  megaCfg = (mega_host_config *) pSHost->hostdata;
+  mbox = (mega_mailbox *) mboxData;
 
   /* Flush cache to disk */
-  memset(mbox, 0, 16);
+  memset (mbox, 0, 16);
   mboxData[0] = 0xA;
 
   /* Issue a blocking (interrupts disabled) command to the card */
-  MegaIssueCmd(megaCfg, mboxData, NULL, 0);
+  MegaIssueCmd (megaCfg, mboxData, NULL, 0);
 
-  schedule();
+  schedule ();
 
   /* Free our resources */
   if (megaCfg->flag & BOARD_QUARTZ) {
-      iounmap((void *)megaCfg->base);
-  } else {
-      release_region(megaCfg->host->io_port, 16);
+    iounmap ((void *) megaCfg->base);
   }
-  free_irq(megaCfg->host->irq, megaCfg); /* Must be freed first, otherwise
-                                            extra interrupt is generated */
-  scsi_unregister(pSHost);
+  else {
+    release_region (megaCfg->host->io_port, 16);
+  }
+  free_irq (megaCfg->host->irq, megaCfg);      /* Must be freed first, otherwise
+
+                                                  extra interrupt is generated */
+  for (i = 0; i < megaCfg->max_cmds; i++) {
+    if (megaCfg->scbList[i].sgList)
+      kfree (megaCfg->scbList[i].sgList);      /* free sgList */
+  }
+  scsi_unregister (pSHost);
 
   return 0;
 }
@@ -1140,20 +1267,20 @@ int megaraid_release(struct Scsi_Host *pSHost)
 /*----------------------------------------------
  * Get information about the card/driver 
  *----------------------------------------------*/
-const char *megaraid_info(struct Scsi_Host *pSHost)
+const char * megaraid_info (struct Scsi_Host *pSHost)
 {
-  static char           buffer[512];
-  mega_host_config  *megaCfg;
-  mega_RAIDINQ          *adapterInfo;
+  static char buffer[512];
+  mega_host_config *megaCfg;
+  mega_RAIDINQ *adapterInfo;
 
-  megaCfg     = (mega_host_config *)pSHost->hostdata;
-  adapterInfo = (mega_RAIDINQ *)megaCfg->mega_buffer;
+  megaCfg = (mega_host_config *) pSHost->hostdata;
+  adapterInfo = (mega_RAIDINQ *) megaCfg->mega_buffer;
 
-  sprintf(buffer, "AMI MegaRAID %s %d commands %d targs %d chans",
-         megaCfg->fwVer,
-         adapterInfo->AdpInfo.MaxConcCmds,
-         megaCfg->host->max_id,
-         megaCfg->host->max_channel);
+  sprintf (buffer, "AMI MegaRAID %s %d commands %d targs %d chans",
+          megaCfg->fwVer,
+          adapterInfo->AdpInfo.MaxConcCmds,
+          megaCfg->host->max_id,
+          megaCfg->host->max_channel);
   return buffer;
 }
 
@@ -1172,29 +1299,29 @@ const char *megaraid_info(struct Scsi_Host *pSHost)
  *   10 01 numstatus byte
  *   11 01 status byte 
  *-----------------------------------------------------------------*/
-int megaraid_queue(Scsi_Cmnd *SCpnt, void (*pktComp)(Scsi_Cmnd *))
+int megaraid_queue (Scsi_Cmnd * SCpnt, void (*pktComp) (Scsi_Cmnd *))
 {
   mega_host_config *megaCfg;
-  mega_scb         *pScb;
+  mega_scb *pScb;
 
-  megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+  megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
   if (!(megaCfg->flag & (1L << SCpnt->channel))) {
-    printk(KERN_INFO "scsi%d: scanning channel %c for devices.\n",
-          megaCfg->host->host_no,
-          SCpnt->channel + 'A');
+    printk (KERN_INFO "scsi%d: scanning channel %c for devices.\n",
+           megaCfg->host->host_no,
+           SCpnt->channel + 'A');
     megaCfg->flag |= (1L << SCpnt->channel);
   }
 
   SCpnt->scsi_done = pktComp;
 
   /* Allocate and build a SCB request */
-  if ((pScb = mega_build_cmd(megaCfg, SCpnt)) != NULL) {
+  if ((pScb = mega_build_cmd (megaCfg, SCpnt)) != NULL) {
     /* Add SCB to the head of the pending queue */
-    ENQUEUE(pScb, mega_scb, qPending, next);
+    ENQUEUE (pScb, mega_scb, qPending, next);
 
     /* Issue the command to the card */
-      mega_runque(NULL);
+    mega_runque (NULL);
   }
 
   return 0;
@@ -1202,37 +1329,44 @@ int megaraid_queue(Scsi_Cmnd *SCpnt, void (*pktComp)(Scsi_Cmnd *))
 
 /*----------------------------------------------------------------------
  * Issue a blocking command to the controller
- *
- * Note - this isnt 2.0.x SMP safe
  *----------------------------------------------------------------------*/
-volatile static int internal_done_flag    = 0;
+volatile static int internal_done_flag = 0;
 volatile static int internal_done_errcode = 0;
 
-static void internal_done(Scsi_Cmnd *SCpnt)
+static void internal_done (Scsi_Cmnd * SCpnt)
 {
   internal_done_errcode = SCpnt->result;
   internal_done_flag++;
 }
 
 /*
- *     This seems dangerous in an SMP environment because 
- *     while spinning on internal_done_flag in 2.0.x SMP
- *     no IRQ's will be taken, including those that might
- *     be needed to clear this.
+ *      This seems dangerous in an SMP environment because
+ *      while spinning on internal_done_flag in 2.0.x SMP
+ *      no IRQ's will be taken, including those that might
+ *      be needed to clear this.
  *
- *     I think this should be using a wait queue ?
- *                             -- AC
+ *      I think this should be using a wait queue ?
+ *                              -- AC
+ */      
+
+/*
+ *      I'll probably fix this in the next version, but
+ *      megaraid_command() will never get called since can_queue is set,
+ *      except maybe in a *really* old kernel in which case it's very
+ *      unlikely they'd be using SMP anyway.  Really this function is
+ *      just here for completeness.
+ *                              - JLJ
  */
-int megaraid_command(Scsi_Cmnd *SCpnt)
+
+int megaraid_command (Scsi_Cmnd * SCpnt)
 {
   internal_done_flag = 0;
 
   /* Queue command, and wait until it has completed */
-  megaraid_queue(SCpnt, internal_done);
+  megaraid_queue (SCpnt, internal_done);
 
-  while(!internal_done_flag)
-    barrier();
+  while (!internal_done_flag)
+    barrier ();
 
   return internal_done_errcode;
 }
@@ -1240,67 +1374,67 @@ int megaraid_command(Scsi_Cmnd *SCpnt)
 /*---------------------------------------------------------------------
  * Abort a previous SCSI request
  *---------------------------------------------------------------------*/
-int megaraid_abort(Scsi_Cmnd *SCpnt)
+int megaraid_abort (Scsi_Cmnd * SCpnt)
 {
   mega_host_config *megaCfg;
-  int       idx;
-  long      flags;
+  int idx;
+  long flags;
 
-  spin_lock_irqsave(&mega_lock,flags);
+  spin_lock_irqsave (&mega_lock, flags);
 
-  megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+  megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
-  TRACE(("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
-        SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, 
-        SCpnt->lun));
+  TRACE (("ABORT!!! %.08lx %.02x <%d.%d.%d>\n",
+       SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
+         SCpnt->lun));
   /*
    * Walk list of SCBs for any that are still outstanding
    */
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].idx >= 0) {
       if (megaCfg->scbList[idx].SCpnt == SCpnt) {
-       freeSCB(&megaCfg->scbList[idx]);
+       freeSCB (&megaCfg->scbList[idx]);
 
-       SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY<<24);
-       callDone(SCpnt);
+       SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
+       callDone (SCpnt);
       }
     }
   }
-  spin_unlock_irqrestore(&mega_lock,flags);
+  spin_unlock_irqrestore (&mega_lock, flags);
   return SCSI_ABORT_SNOOZE;
 }
 
 /*---------------------------------------------------------------------
  * Reset a previous SCSI request
  *---------------------------------------------------------------------*/
-int megaraid_reset(Scsi_Cmnd *SCpnt, unsigned int rstflags)
+int megaraid_reset (Scsi_Cmnd * SCpnt, unsigned int rstflags)
 {
   mega_host_config *megaCfg;
-  int       idx;
-  long      flags;
+  int idx;
+  long flags;
 
-  spin_lock_irqsave(&mega_lock,flags);
+  spin_lock_irqsave (&mega_lock, flags);
 
-  megaCfg = (mega_host_config *)SCpnt->host->hostdata;
+  megaCfg = (mega_host_config *) SCpnt->host->hostdata;
 
-  TRACE(("RESET: %.08lx %.02x <%d.%d.%d>\n",
-        SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target, 
-        SCpnt->lun));
+  TRACE (("RESET: %.08lx %.02x <%d.%d.%d>\n",
+       SCpnt->serial_number, SCpnt->cmnd[0], SCpnt->channel, SCpnt->target,
+         SCpnt->lun));
 
   /*
    * Walk list of SCBs for any that are still outstanding
    */
-  for(idx=0; idx<megaCfg->max_cmds; idx++) {
+  for (idx = 0; idx < megaCfg->max_cmds; idx++) {
     if (megaCfg->scbList[idx].idx >= 0) {
       SCpnt = megaCfg->scbList[idx].SCpnt;
-      freeSCB(&megaCfg->scbList[idx]);
-      SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY<<24);
-      callDone(SCpnt);
+      freeSCB (&megaCfg->scbList[idx]);
+      SCpnt->result = (DID_RESET << 16) | (SUGGEST_RETRY << 24);
+      callDone (SCpnt);
     }
   }
-  spin_unlock_irqrestore(&mega_lock,flags);
+  spin_unlock_irqrestore (&mega_lock, flags);
   return SCSI_RESET_PUNT;
-} 
+}
 
 /*-------------------------------------------------------------
  * Return the disk geometry for a particular disk
@@ -1312,23 +1446,23 @@ int megaraid_reset(Scsi_Cmnd *SCpnt, unsigned int rstflags)
  *     geom[1] = sectors
  *     geom[2] = cylinders
  *-------------------------------------------------------------*/
-int megaraid_biosparam(Disk *disk, kdev_t dev, int *geom)
+int megaraid_biosparam (Disk * disk, kdev_t dev, int *geom)
 {
-  int                   heads, sectors, cylinders;
+  int heads, sectors, cylinders;
   mega_host_config *megaCfg;
 
   /* Get pointer to host config structure */
-  megaCfg = (mega_host_config *)disk->device->host->hostdata;
+  megaCfg = (mega_host_config *) disk->device->host->hostdata;
 
   /* Default heads (64) & sectors (32) */
-  heads     = 64;
-  sectors   = 32;
+  heads = 64;
+  sectors = 32;
   cylinders = disk->capacity / (heads * sectors);
 
   /* Handle extended translation size for logical drives > 1Gb */
   if (disk->capacity >= 0x200000) {
-    heads     = 255;
-    sectors   = 63;
+    heads = 255;
+    sectors = 63;
     cylinders = disk->capacity / (heads * sectors);
   }
 
index 5442407325332e2ef9190d169fca53389f12a46e..f9449c32876d47c28be73e38e257809179b1bcd8 100644 (file)
@@ -1,6 +1,10 @@
 #ifndef __MEGARAID_H__
 #define __MEGARAID_H__
 
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
 #define IN_ISR                  0x80000000L
 #define NO_INTR                 0x40000000L
 #define IN_TIMEOUT              0x20000000L
@@ -18,7 +22,7 @@
 
 #define MEGA_CMD_TIMEOUT        10
 
-#define MAX_SGLIST              20
+#define MAX_SGLIST              17
 #define MAX_COMMANDS            254
 
 #define MAX_LOGICAL_DRIVES      8
@@ -94,6 +98,8 @@
 
 #define PCI_CONF_BASE_ADDR_OFFSET  0x10
 #define PCI_CONF_IRQ_OFFSET        0x3c
+#define PCI_CONF_AMISIG            0xa0
+#define AMI_SIGNATURE              0x11223344
 
 #if LINUX_VERSION_CODE < 0x20100
 #define MEGARAID \
     megaraid_reset,                     /* Reset Command Function    */\
     NULL,                               /* Slave Attach Function     */\
     megaraid_biosparam,                 /* Disk BIOS Parameters      */\
-    1,                                  /* # of cmds that can be\
+    254,                                /* # of cmds that can be\
                                            outstanding at any time */\
     7,                                  /* HBA Target ID             */\
     MAX_SGLIST,                         /* Scatter/Gather Table Size */\
-    1,                                  /* SCSI Commands per LUN     */\
+    64,                                 /* SCSI Commands per LUN     */\
     0,                                  /* Present                   */\
     0,                                  /* Default Unchecked ISA DMA */\
-    ENABLE_CLUSTERING }                 /* Enable Clustering         */
+    ENABLE_CLUSTERING }                /* Enable Clustering         */
 #else
 #define MEGARAID \
   {\
     abort:            megaraid_abort,          /* Abort Command Function    */\
     reset:            megaraid_reset,          /* Reset Command Function    */\
     bios_param:       megaraid_biosparam,      /* Disk BIOS Parameters      */\
-    can_queue:        255,                     /* Can Queue                 */\
+    can_queue:        254,                     /* Can Queue                 */\
     this_id:          7,                       /* HBA Target ID             */\
     sg_tablesize:     MAX_SGLIST,              /* Scatter/Gather Table Size */\
-    cmd_per_lun:      1,                       /* SCSI Commands per LUN     */\
+    cmd_per_lun:      64,                      /* SCSI Commands per LUN     */\
     present:          0,                       /* Present                   */\
     unchecked_isa_dma:0,                       /* Default Unchecked ISA DMA */\
     use_clustering:   ENABLE_CLUSTERING       /* Enable Clustering         */\
 #endif
 
 /* Structures */
-typedef struct _mega_ADP_INFO
-{
-  u_char    MaxConcCmds;
-  u_char    RbldRate;
-  u_char    MaxTargPerChan;
-  u_char    ChanPresent;
-  u_char    FwVer[4];
-  u_short   AgeOfFlash;
-  u_char    ChipSet;
-  u_char    DRAMSize;
-  u_char    CacheFlushInterval;
-  u_char    BiosVer[4];
-  u_char    resvd[7];
+typedef struct _mega_ADP_INFO {
+    u_char MaxConcCmds;
+    u_char RbldRate;
+    u_char MaxTargPerChan;
+    u_char ChanPresent;
+    u_char FwVer[4];
+    u_short AgeOfFlash;
+    u_char ChipSet;
+    u_char DRAMSize;
+    u_char CacheFlushInterval;
+    u_char BiosVer[4];
+    u_char resvd[7];
 } mega_ADP_INFO;
 
-typedef struct _mega_LDRV_INFO
-{
-  u_char   NumLDrv;
-  u_char   resvd[3];
-  u_long   LDrvSize[MAX_LOGICAL_DRIVES];
-  u_char   LDrvProp[MAX_LOGICAL_DRIVES];
-  u_char   LDrvState[MAX_LOGICAL_DRIVES];
+typedef struct _mega_LDRV_INFO {
+    u_char NumLDrv;
+    u_char resvd[3];
+    u_long LDrvSize[MAX_LOGICAL_DRIVES];
+    u_char LDrvProp[MAX_LOGICAL_DRIVES];
+    u_char LDrvState[MAX_LOGICAL_DRIVES];
 } mega_LDRV_INFO;
 
-typedef struct _mega_PDRV_INFO
-{
-  u_char   PDrvState[MAX_PHYSICAL_DRIVES];
-  u_char   resvd;
+typedef struct _mega_PDRV_INFO {
+    u_char PDrvState[MAX_PHYSICAL_DRIVES];
+    u_char resvd;
 } mega_PDRV_INFO;
 
 // RAID inquiry: Mailbox command 0x5
-typedef struct _mega_RAIDINQ
-{
-  mega_ADP_INFO    AdpInfo;
-  mega_LDRV_INFO   LogdrvInfo;
-  mega_PDRV_INFO   PhysdrvInfo;
+typedef struct _mega_RAIDINQ {
+    mega_ADP_INFO AdpInfo;
+    mega_LDRV_INFO LogdrvInfo;
+    mega_PDRV_INFO PhysdrvInfo;
 } mega_RAIDINQ;
 
 // Passthrough command: Mailbox command 0x3
-typedef struct mega_passthru
-{
-  u_char            timeout:3;              /* 0=6sec/1=60sec/2=10min/3=3hrs */
-  u_char            ars:1;
-  u_char            reserved:3;
-  u_char            islogical:1;
-  u_char            logdrv;                 /* if islogical == 1 */
-  u_char            channel;                /* if islogical == 0 */
-  u_char            target;                 /* if islogical == 0 */
-  u_char            queuetag;               /* unused */
-  u_char            queueaction;            /* unused */
-  u_char            cdb[MAX_CDB_LEN];
-  u_char            cdblen;
-  u_char            reqsenselen;
-  u_char            reqsensearea[MAX_REQ_SENSE_LEN];
-  u_char            numsgelements;
-  u_char            scsistatus;
-  u_long            dataxferaddr;
-  u_long            dataxferlen;
+typedef struct mega_passthru {
+    u_char timeout:3;          /* 0=6sec/1=60sec/2=10min/3=3hrs */
+    u_char ars:1;
+    u_char reserved:3;
+    u_char islogical:1;
+    u_char logdrv;             /* if islogical == 1 */
+    u_char channel;            /* if islogical == 0 */
+    u_char target;             /* if islogical == 0 */
+    u_char queuetag;           /* unused */
+    u_char queueaction;                /* unused */
+    u_char cdb[MAX_CDB_LEN];
+    u_char cdblen;
+    u_char reqsenselen;
+    u_char reqsensearea[MAX_REQ_SENSE_LEN];
+    u_char numsgelements;
+    u_char scsistatus;
+    u_long dataxferaddr;
+    u_long dataxferlen;
 } mega_passthru;
 
-typedef struct _mega_mailbox
-{
-  /* 0x0 */ u_char    cmd;
-  /* 0x1 */ u_char    cmdid;
-  /* 0x2 */ u_short   numsectors;
-  /* 0x4 */ u_long    lba;
-  /* 0x8 */ u_long    xferaddr;
-  /* 0xC */ u_char    logdrv;
-  /* 0xD */ u_char    numsgelements;
-  /* 0xE */ u_char    resvd;
-  /* 0xF */ u_char    busy;
-  /* 0x10*/ u_char    numstatus;
-  /* 0x11*/ u_char    status;
-  /* 0x12*/ u_char    completed[46];
-            u_char    mraid_poll;
-            u_char    mraid_ack;
-            u_char    pad[16];
+typedef struct _mega_mailbox {
+    /* 0x0 */ u_char cmd;
+    /* 0x1 */ u_char cmdid;
+    /* 0x2 */ u_short numsectors;
+    /* 0x4 */ u_long lba;
+    /* 0x8 */ u_long xferaddr;
+    /* 0xC */ u_char logdrv;
+    /* 0xD */ u_char numsgelements;
+    /* 0xE */ u_char resvd;
+    /* 0xF */ u_char busy;
+    /* 0x10 */ u_char numstatus;
+    /* 0x11 */ u_char status;
+    /* 0x12 */ u_char completed[46];
+    u_char mraid_poll;
+    u_char mraid_ack;
+    u_char pad[16];
 } mega_mailbox;
 
-typedef struct _mega_sglist
-{
-  u_long     address;
-  u_long     length;
+typedef struct _mega_ioctl_mbox {
+    /* 0x0 */ u_char cmd;
+    /* 0x1 */ u_char cmdid;
+    /* 0x2 */ u_char channel;
+    /* 0x3 */ u_char param;
+    /* 0x4 */ u_char pad[4];
+    /* 0x8 */ u_long xferaddr;
+    /* 0xC */ u_char logdrv;
+    /* 0xD */ u_char numsgelements;
+    /* 0xE */ u_char resvd;
+    /* 0xF */ u_char busy;
+    /* 0x10 */ u_char numstatus;
+    /* 0x11 */ u_char status;
+    /* 0x12 */ u_char completed[46];
+    u_char mraid_poll;
+    u_char mraid_ack;
+    u_char malign[16];
+} mega_ioctl_mbox;
+
+typedef struct _mega_sglist {
+    u_long address;
+    u_long length;
 } mega_sglist;
 
 /* Queued command data */
 typedef struct _mega_scb mega_scb;
 
-struct _mega_scb
-{
-  int             idx;
-  u_long          flag;
-  Scsi_Cmnd      *SCpnt;
-  u_char          mboxData[16];
-  mega_passthru   pthru;
-  mega_sglist    *sgList;
-  mega_scb       *next;
+struct _mega_scb {
+    int idx;
+    u_long flag;
+    Scsi_Cmnd *SCpnt;
+    u_char mboxData[16];
+    mega_passthru pthru;
+    mega_sglist *sgList;
+    mega_scb *next;
 };
 
 /* Per-controller data */
-typedef struct _mega_host_config
-{
-  u_char               numldrv;
-  u_long               flag;
-  u_long               base;
+typedef struct _mega_host_config {
+    u_char numldrv;
+    u_long flag;
+    u_long base;
 
-  struct tq_struct     megaTq;
+    struct tq_struct megaTq;
 
-  /* Host adapter parameters */
-  u_char               fwVer[7];
-  u_char               biosVer[7];
+    /* Host adapter parameters */
+    u_char fwVer[7];
+    u_char biosVer[7];
 
-  struct Scsi_Host     *host;
+    struct Scsi_Host *host;
 
-  /* The following must be DMA-able!! */
-  volatile mega_mailbox *mbox;
-  volatile mega_mailbox mailbox;
-  volatile u_char       mega_buffer[2*1024L];
+    /* The following must be DMA-able!! */
+    volatile mega_mailbox *mbox;
+    volatile mega_mailbox mailbox;
+    volatile u_char mega_buffer[2 * 1024L];
 
-  u_char                max_cmds;
-  mega_scb              scbList[MAX_COMMANDS];
+    u_char max_cmds;
+    mega_scb scbList[MAX_COMMANDS];
 } mega_host_config;
 
 extern struct proc_dir_entry proc_scsi_megaraid;
 
-const char *megaraid_info( struct Scsi_Host * );
-int        megaraid_detect( Scsi_Host_Template * );
-int        megaraid_release(struct Scsi_Host *);
-int        megaraid_command( Scsi_Cmnd * );
-int        megaraid_abort( Scsi_Cmnd * );
-int        megaraid_reset( Scsi_Cmnd *, unsigned int); 
-int        megaraid_queue( Scsi_Cmnd *, void (*done)(Scsi_Cmnd *) );
-int        megaraid_biosparam( Disk *, kdev_t, int * );
-int        megaraid_proc_info( char *buffer, char **start, off_t offset,
-                              int length, int hostno, int inout );
+const char *megaraid_info(struct Scsi_Host *);
+int megaraid_detect(Scsi_Host_Template *);
+int megaraid_release(struct Scsi_Host *);
+int megaraid_command(Scsi_Cmnd *);
+int megaraid_abort(Scsi_Cmnd *);
+int megaraid_reset(Scsi_Cmnd *, unsigned int);
+int megaraid_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
+int megaraid_biosparam(Disk *, kdev_t, int *);
+int megaraid_proc_info(char *buffer, char **start, off_t offset,
+                      int length, int hostno, int inout);
 
 #endif
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
new file mode 100644 (file)
index 0000000..a750550
--- /dev/null
@@ -0,0 +1,805 @@
+/* 
+ *  sym53c416.c
+ *  Low-level SCSI driver for sym53c416 chip.
+ *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com)
+ * 
+ *  LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>]
+ *
+ *  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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/proc_fs.h>
+#include <asm/dma.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <linux/blk.h>
+#include "scsi.h"
+#include "hosts.h"
+#include "sd.h"
+#include "sym53c416.h"
+
+#define VERSION_STRING        "Version 1.0.0"
+
+#define TC_LOW       0x00     /* Transfer counter low        */
+#define TC_MID       0x01     /* Transfer counter mid        */
+#define SCSI_FIFO    0x02     /* SCSI FIFO register          */
+#define COMMAND_REG  0x03     /* Command Register            */
+#define STATUS_REG   0x04     /* Status Register (READ)      */
+#define DEST_BUS_ID  0x04     /* Destination Bus ID (WRITE)  */
+#define INT_REG      0x05     /* Interrupt Register (READ)   */
+#define TOM          0x05     /* Time out multiplier (WRITE) */
+#define STP          0x06     /* Synchronous Transfer period */
+#define SYNC_OFFSET  0x07     /* Synchronous Offset          */
+#define CONF_REG_1   0x08     /* Configuration register 1    */
+#define CONF_REG_2   0x0B     /* Configuration register 2    */
+#define CONF_REG_3   0x0C     /* Configuration register 3    */
+#define CONF_REG_4   0x0D     /* Configuration register 4    */
+#define TC_HIGH      0x0E     /* Transfer counter high       */
+#define PIO_FIFO_1   0x10     /* PIO FIFO register 1         */
+#define PIO_FIFO_2   0x11     /* PIO FIFO register 2         */
+#define PIO_FIFO_3   0x12     /* PIO FIFO register 3         */
+#define PIO_FIFO_4   0x13     /* PIO FIFO register 4         */
+#define PIO_FIFO_CNT 0x14     /* PIO FIFO count              */
+#define PIO_INT_REG  0x15     /* PIO interrupt register      */
+#define CONF_REG_5   0x16     /* Configuration register 5    */
+#define FEATURE_EN   0x1D     /* Feature Enable register     */
+
+/* Configuration register 1 entries: */
+/* Bits 2-0: SCSI ID of host adapter */
+#define SCM    0x80                     /* Slow Cable Mode              */
+#define SRID   0x40                     /* SCSI Reset Interrupt Disable */
+#define PTM    0x20                     /* Parity Test Mode             */
+#define EPC    0x10                     /* Enable Parity Checking       */
+#define CTME   0x08                     /* Special Test Mode            */
+
+/* Configuration register 2 entries: */
+#define FE     0x40                     /* Features Enable              */
+#define SCSI2  0x08                     /* SCSI 2 Enable                */
+#define TBPA   0x04                     /* Target Bad Parity Abort      */
+
+/* Configuration register 3 entries: */
+#define IDMRC  0x80                     /* ID Message Reserved Check    */
+#define QTE    0x40                     /* Queue Tag Enable             */
+#define CDB10  0x20                     /* Command Descriptor Block 10  */
+#define FSCSI  0x10                     /* FastSCSI                     */
+#define FCLK   0x08                     /* FastClock                    */
+
+/* Configuration register 4 entries: */
+#define RBS    0x08                     /* Register bank select         */
+#define EAN    0x04                     /* Enable Active Negotiation    */
+
+/* Configuration register 5 entries: */
+#define LPSR   0x80                     /* Lower Power SCSI Reset       */
+#define IE     0x20                     /* Interrupt Enable             */
+#define LPM    0x02                     /* Low Power Mode               */
+#define WSE0   0x01                     /* 0WS Enable                   */
+
+/* Interrupt register entries: */
+#define SRST   0x80                     /* SCSI Reset                   */
+#define ILCMD  0x40                     /* Illegal Command              */
+#define DIS    0x20                     /* Disconnect                   */
+#define BS     0x10                     /* Bus Service                  */
+#define FC     0x08                     /* Function Complete            */
+#define RESEL  0x04                     /* Reselected                   */
+#define SI     0x03                     /* Selection Interrupt          */
+
+/* Status Register Entries: */
+#define SCI    0x80                     /* SCSI Core Int                */
+#define GE     0x40                     /* Gross Error                  */
+#define PE     0x20                     /* Parity Error                 */
+#define TC     0x10                     /* Terminal Count               */
+#define VGC    0x08                     /* Valid Group Code             */
+#define PHBITS 0x07                     /* Phase bits                   */
+
+/* PIO Interrupt Register Entries: */
+#define SCI    0x80                     /* SCSI Core Int                */
+#define PFI    0x40                     /* PIO FIFO Interrupt           */
+#define FULL   0x20                     /* PIO FIFO Full                */
+#define EMPTY  0x10                     /* PIO FIFO Empty               */
+#define CE     0x08                     /* Collision Error              */
+#define OUE    0x04                     /* Overflow / Underflow error   */
+#define FIE    0x02                     /* Full Interrupt Enable        */
+#define EIE    0x01                     /* Empty Interrupt Enable       */
+
+/* SYM53C416 SCSI phases (lower 3 bits of SYM53C416_STATUS_REG) */
+#define PHASE_DATA_OUT    0x00
+#define PHASE_DATA_IN     0x01
+#define PHASE_COMMAND     0x02
+#define PHASE_STATUS      0x03
+#define PHASE_RESERVED_1  0x04
+#define PHASE_RESERVED_2  0x05
+#define PHASE_MESSAGE_OUT 0x06
+#define PHASE_MESSAGE_IN  0x07
+
+/* SYM53C416 core commands */
+#define NOOP                      0x00
+#define FLUSH_FIFO                0x01
+#define RESET_CHIP                0x02
+#define RESET_SCSI_BUS            0x03
+#define DISABLE_SEL_RESEL         0x45
+#define RESEL_SEQ                 0x40
+#define SEL_WITHOUT_ATN_SEQ       0x41
+#define SEL_WITH_ATN_SEQ          0x42
+#define SEL_WITH_ATN_AND_STOP_SEQ 0x43
+#define ENABLE_SEL_RESEL          0x44
+#define SEL_WITH_ATN3_SEQ         0x46
+#define RESEL3_SEQ                0x47
+#define SND_MSG                   0x20
+#define SND_STAT                  0x21
+#define SND_DATA                  0x22
+#define DISCONNECT_SEQ            0x23
+#define TERMINATE_SEQ             0x24
+#define TARGET_COMM_COMPLETE_SEQ  0x25
+#define DISCONN                   0x27
+#define RECV_MSG_SEQ              0x28
+#define RECV_CMD                  0x29
+#define RECV_DATA                 0x2A
+#define RECV_CMD_SEQ              0x2B
+#define TARGET_ABORT_PIO          0x04
+#define TRANSFER_INFORMATION      0x10
+#define INIT_COMM_COMPLETE_SEQ    0x11
+#define MSG_ACCEPTED              0x12
+#define TRANSFER_PAD              0x18
+#define SET_ATN                   0x1A
+#define RESET_ATN                 0x1B
+#define ILLEGAL                   0xFF
+
+#define PIO_MODE                  0x80
+
+#define IO_RANGE 0x20         /* 0x00 - 0x1F                   */
+#define ID       "sym53c416"
+#define PIO_SIZE 128          /* Size of PIO fifo is 128 bytes */
+
+#define READ_TIMEOUT              150
+#define WRITE_TIMEOUT             150
+
+#ifdef MODULE
+
+#define sym53c416_base sym53c416
+#define sym53c416_base_1 sym53c416_1
+#define sym53c416_base_2 sym53c416_2
+#define sym53c416_base_3 sym53c416_3
+
+static unsigned short sym53c416_base = 0;
+static unsigned int sym53c416_irq = 0;
+static unsigned short sym53c416_base_1 = 0;
+static unsigned int sym53c416_irq_1 = 0;
+static unsigned short sym53c416_base_2 = 0;
+static unsigned int sym53c416_irq_2 = 0;
+static unsigned short sym53c416_base_3 = 0;
+static unsigned int sym53c416_irq_3 = 0;
+
+#endif
+
+/* #define DEBUG */
+
+/* Macro for debugging purposes */
+
+#ifdef DEBUG
+#define DEB(x) x
+#else
+#define DEB(x)
+#endif
+
+#define MAXHOSTS 4
+
+enum phases
+  {
+  idle,
+  data_out,
+  data_in,
+  command_ph,
+  status_ph,
+  message_out,
+  message_in
+  };
+
+typedef struct
+  {
+  int base;
+  int irq;
+  int scsi_id;
+  } host;
+
+host hosts[MAXHOSTS] = {
+                       {0, 0, SYM53C416_SCSI_ID},
+                       {0, 0, SYM53C416_SCSI_ID},
+                       {0, 0, SYM53C416_SCSI_ID},
+                       {0, 0, SYM53C416_SCSI_ID}
+                       };
+
+static int host_index = 0;
+
+static char info[120];
+
+static Scsi_Cmnd *current_command = NULL;
+
+struct proc_dir_entry proc_scsi_sym53c416 = {PROC_SCSI_SYM53C416, 7, ID, S_IFDIR | S_IRUGO | S_IXUGO, 2};
+
+int fastpio = 1;
+
+int probeaddrs[] = {0x200, 0x220, 0x240, 0};
+
+static void sym53c416_set_transfer_counter(int base, unsigned int len)
+  {
+  /* Program Transfer Counter */
+  outb(len & 0x0000FF, base + TC_LOW);
+  outb((len & 0x00FF00) >> 8, base + TC_MID);
+  outb((len & 0xFF0000) >> 16, base + TC_HIGH);
+  }
+
+/* Returns the number of bytes read */
+static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len)
+  {
+  unsigned int orig_len = len;
+  unsigned long flags = 0;
+  unsigned int bytes_left;
+  int i;
+  int timeout = READ_TIMEOUT;
+
+  /* Do transfer */
+  save_flags(flags);
+  cli();
+  while(len && timeout)
+    {
+    bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */
+    if(fastpio && bytes_left > 3)
+      {
+      insl(base + PIO_FIFO_1, buffer, bytes_left >> 2);
+      buffer += bytes_left & 0xFC;
+      len -= bytes_left & 0xFC;
+      }
+    else if(bytes_left > 0)
+      {
+      len -= bytes_left;
+      for(; bytes_left > 0; bytes_left--)
+        *(buffer++) = inb(base + PIO_FIFO_1);
+      }
+    else
+      {
+      i = jiffies + timeout;
+      restore_flags(flags);
+      while(jiffies < i && (inb(base + PIO_INT_REG) & EMPTY) && timeout)
+        if(inb(base + PIO_INT_REG) & SCI)
+          timeout = 0;
+      save_flags(flags);
+      cli();
+      if(inb(base + PIO_INT_REG) & EMPTY)
+        timeout = 0;
+      }
+    }
+  restore_flags(flags);
+  return orig_len - len;
+  }
+
+/* Returns the number of bytes written */
+static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len)
+  {
+  unsigned int orig_len = len;
+  unsigned long flags = 0;
+  unsigned int bufferfree;
+  unsigned int i;
+  unsigned int timeout = WRITE_TIMEOUT;
+
+  /* Do transfer */
+  save_flags(flags);
+  cli();
+  while(len && timeout)
+    {
+    bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT);
+    if(bufferfree > len)
+      bufferfree = len;
+    if(fastpio && bufferfree > 3)
+      {
+      outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2);
+      buffer += bufferfree & 0xFC;
+      len -= bufferfree & 0xFC;
+      }
+    else if(bufferfree > 0)
+      {
+      len -= bufferfree;
+      for(; bufferfree > 0; bufferfree--)
+        outb(*(buffer++), base + PIO_FIFO_1);
+      }
+    else
+      {
+      i = jiffies + timeout;
+      restore_flags(flags);
+      while(jiffies < i && (inb(base + PIO_INT_REG) & FULL) && timeout)
+        ;
+      save_flags(flags);
+      cli();
+      if(inb(base + PIO_INT_REG) & FULL)
+        timeout = 0;
+      }
+    }
+  restore_flags(flags);
+  return orig_len - len;
+  }
+
+static void sym53c416_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
+  {
+  int base = 0;
+  int i;
+  unsigned long flags = 0;
+  unsigned char status_reg, pio_int_reg, int_reg;
+  struct scatterlist *sglist;
+  unsigned int sgcount;
+  unsigned int tot_trans = 0;
+
+  /* We search the base address of the host adapter which caused the interrupt */
+  for(i = 0; i < host_index && !base; i++)
+    if(irq == hosts[i].irq)
+      base = hosts[i].base;
+  /* If no adapter found, we cannot handle the interrupt. Leave a message */
+  /* and continue. This should never happen...                            */
+  if(!base)
+    {
+    printk("sym53c416: No host adapter defined for interrupt %d\n", irq);
+    return;
+    }
+  /* Now we have the base address and we can start handling the interrupt */
+  save_flags(flags);
+  cli();
+  status_reg = inb(base + STATUS_REG);
+  pio_int_reg = inb(base + PIO_INT_REG);
+  int_reg = inb(base + INT_REG);
+  restore_flags(flags);
+
+  /* First, we handle error conditions */
+  if(int_reg & SCI)         /* SCSI Reset */
+    {
+    printk("sym53c416: Warning: Reset received\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_RESET << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(int_reg & ILCMD)       /* Illegal Command */
+    {
+    printk("sym53c416: Warning: Illegal Command: 0x%02x\n", inb(base + COMMAND_REG));
+    current_command->SCp.phase = idle;
+    current_command->result = DID_ERROR << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(status_reg & GE)         /* Gross Error */
+    {
+    printk("sym53c416: Warning: Gross Error\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_ERROR << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(status_reg & PE)         /* Parity Error */
+    {
+    printk("sym53c416: Warning: Parity Error\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_PARITY << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(pio_int_reg & (CE | OUE))
+    {
+    printk("sym53c416: Warning: PIO Interrupt Error\n");
+    current_command->SCp.phase = idle;
+    current_command->result = DID_ERROR << 16;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  if(int_reg & DIS)           /* Disconnect */
+    {
+    if(current_command->SCp.phase != message_in)
+      current_command->result = DID_NO_CONNECT << 16;
+    else
+      current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16);
+    current_command->SCp.phase = idle;
+    current_command->scsi_done(current_command);
+    return;
+    }
+  /* Now we handle SCSI phases         */
+  switch(status_reg & PHBITS)       /* Filter SCSI phase out of status reg */
+    {
+    case PHASE_DATA_OUT:
+      {
+      if(int_reg & BS)
+        {
+        current_command->SCp.phase = data_out;
+        outb(FLUSH_FIFO, base + COMMAND_REG);
+        sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+        outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
+        if(!current_command->use_sg)
+          tot_trans = sym53c416_write(base, current_command->request_buffer, current_command->request_bufflen);
+        else
+          {
+          sgcount = current_command->use_sg;
+          sglist = current_command->request_buffer;
+          while(sgcount--)
+            {
+            tot_trans += sym53c416_write(base, sglist->address, sglist->length);
+            sglist++;
+            }
+          }
+        if(tot_trans < current_command->underflow)
+          printk("sym53c416: Warning: underflow, wrote %d bytes, request for %d bytes\n", tot_trans, current_command->underflow);
+        }
+      break;
+      }
+    case PHASE_DATA_IN:
+      {
+      if(int_reg & BS)
+        {
+        current_command->SCp.phase = data_in;
+        outb(FLUSH_FIFO, base + COMMAND_REG);
+        sym53c416_set_transfer_counter(base, current_command->request_bufflen);
+        outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG);
+        if(!current_command->use_sg)
+          tot_trans = sym53c416_read(base, current_command->request_buffer, current_command->request_bufflen);
+        else
+          {
+          sgcount = current_command->use_sg;
+          sglist = current_command->request_buffer;
+          while(sgcount--)
+            {
+            tot_trans += sym53c416_read(base, sglist->address, sglist->length);
+            sglist++;
+            }
+          }
+        if(tot_trans < current_command->underflow)
+          printk("sym53c416: Warning: underflow, read %d bytes, request for %d bytes\n", tot_trans, current_command->underflow);
+        }
+      break;
+      }
+    case PHASE_COMMAND:
+      {
+      current_command->SCp.phase = command_ph;
+      printk("sym53c416: Warning: Unknown interrupt in command phase\n");
+      break;
+      }
+    case PHASE_STATUS:
+      {
+      current_command->SCp.phase = status_ph;
+      outb(FLUSH_FIFO, base + COMMAND_REG);
+      outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG);
+      break;
+      }
+    case PHASE_RESERVED_1:
+    case PHASE_RESERVED_2:
+      {
+      printk("sym53c416: Warning: Reserved phase\n");
+      break;
+      }
+    case PHASE_MESSAGE_OUT:
+      {
+      current_command->SCp.phase = message_out;
+      outb(SET_ATN, base + COMMAND_REG);
+      outb(MSG_ACCEPTED, base + COMMAND_REG);
+      break;
+      }
+    case PHASE_MESSAGE_IN:
+      {
+      current_command->SCp.phase = message_in;
+      current_command->SCp.Status = inb(base + SCSI_FIFO);
+      current_command->SCp.Message = inb(base + SCSI_FIFO);
+      if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT)
+        outb(SET_ATN, base + COMMAND_REG);
+      outb(MSG_ACCEPTED, base + COMMAND_REG);
+      break;
+      }
+    }
+  }
+
+static void sym53c416_init(int base, int scsi_id)
+  {
+  outb(RESET_CHIP, base + COMMAND_REG);
+  outb(NOOP, base + COMMAND_REG);
+  outb(0x99, base + TOM); /* Time out of 250 ms */
+  outb(0x05, base + STP);
+  outb(0x00, base + SYNC_OFFSET);
+  outb(EPC | scsi_id, base + CONF_REG_1);
+  outb(FE | SCSI2 | TBPA, base + CONF_REG_2);
+  outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3);
+  outb(0x83 | EAN, base + CONF_REG_4);
+  outb(IE | WSE0, base + CONF_REG_5);
+  outb(0, base + FEATURE_EN);
+  }
+
+static int sym53c416_probeirq(int base, int scsi_id)
+  {
+  int irq, irqs, i;
+
+  /* Clear interrupt register */
+  inb(base + INT_REG);
+  /* Start probing for irq's */
+  irqs = probe_irq_on();
+  /* Reinit chip */
+  sym53c416_init(base, scsi_id);
+  /* Cause interrupt */
+  outb(NOOP, base + COMMAND_REG);
+  outb(ILLEGAL, base + COMMAND_REG);
+  outb(0x07, base + DEST_BUS_ID);
+  outb(0x00, base + DEST_BUS_ID);
+  /* Wait for interrupt to occur */
+  i = jiffies + 20;
+  while(i > jiffies && !(inb(base + STATUS_REG) & SCI))
+    barrier();
+  if(i <= jiffies) /* timed out */
+    return 0;
+  /* Get occurred irq */
+  irq = probe_irq_off(irqs);
+  sym53c416_init(base, scsi_id);
+  return irq;
+  }
+
+/* Setup: sym53c416=base,irq */
+void sym53c416_setup(char *str, int *ints)
+  {
+  int i;
+
+  if(host_index >= MAXHOSTS)
+    {
+    printk("sym53c416.c: Too many hosts defined\n");
+    }
+  else
+    {
+    if(ints[0] < 1 || ints[0] > 2)
+      {
+      printk("sym53c416.c: Wrong number of parameters:\n");
+      printk("sym53c416.c: usage: sym53c416=<base>[,<irq>]\n");
+      }
+    else
+      {
+      for(i = 0; i < host_index && i >= 0; i++)
+        if(hosts[i].base == ints[1])
+          i = -2;
+      if(i >= 0)
+        {
+        hosts[host_index].base = ints[1];
+        hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0;
+        host_index++;
+        }
+      }
+    }
+  }
+
+static int sym53c416_test(int base)
+  {
+  outb(RESET_CHIP, base + COMMAND_REG);
+  outb(NOOP, base + COMMAND_REG);
+  if(inb(base + COMMAND_REG) != NOOP)
+    return 0;
+  if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF)
+    return 0;
+  if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY)
+    return 0;
+  return 1;
+  }
+
+void sym53c416_probe(void)
+  {
+  int *base = probeaddrs;
+  int ints[2];
+
+  ints[0] = 1;
+  for(; *base; base++)
+    if(!check_region(*base, IO_RANGE) && sym53c416_test(*base))
+      {
+      ints[1] = *base;
+      sym53c416_setup(NULL, ints);
+      }
+  }
+
+int sym53c416_detect(Scsi_Host_Template *tpnt)
+  {
+  unsigned long flags;
+  struct Scsi_Host * shpnt = NULL;
+  int i;
+  int count;
+
+#ifdef MODULE
+  int ints[3];
+
+  ints[0] = 2;
+  if(sym53c416_base)
+    {
+    ints[1] = sym53c416_base;
+    ints[2] = sym53c416_irq;
+    sym53c416_setup(NULL, ints);
+    }
+  if(sym53c416_base_1)
+    {
+    ints[1] = sym53c416_base_1;
+    ints[2] = sym53c416_irq_1;
+    sym53c416_setup(NULL, ints);
+    }
+  if(sym53c416_base_2)
+    {
+    ints[1] = sym53c416_base_2;
+    ints[2] = sym53c416_irq_2;
+    sym53c416_setup(NULL, ints);
+    }
+  if(sym53c416_base_3)
+    {
+    ints[1] = sym53c416_base_3;
+    ints[2] = sym53c416_irq_3;
+    sym53c416_setup(NULL, ints);
+    }
+#endif
+
+  printk("sym53c416.c: %s\n", VERSION_STRING);
+
+  sym53c416_probe();
+
+  /* Now we register and set up each host adapter found... */
+  for(count = 0, i = 0; i < host_index; i++)
+    if(!sym53c416_test(hosts[i].base))
+      printk("No sym53c416 found at address 0x%03x\n", hosts[i].base);
+    else
+      {
+      if(hosts[i].irq == 0)
+        /* We don't have an irq yet, so we should probe for one */
+        if((hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id)) == 0)
+          printk("irq autoprobing failed for sym53c416 at address 0x%03x\n", hosts[i].base);
+      if(hosts[i].irq && !check_region(hosts[i].base, IO_RANGE))
+        {
+        shpnt = scsi_register(tpnt, 0);
+        save_flags(flags);
+        cli();
+        /* Request for specified IRQ */
+        if(request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, NULL))
+          {
+          restore_flags(flags);
+          printk("Unable to assign IRQ %d\n", hosts[i].irq);
+          scsi_unregister(shpnt);
+          }
+        else
+          {
+          /* Inform the kernel of our IO range */
+          request_region(hosts[i].base, IO_RANGE, ID);
+          shpnt->unique_id = hosts[i].base;
+          shpnt->io_port = hosts[i].base;
+          shpnt->n_io_port = IO_RANGE;
+          shpnt->irq = hosts[i].irq;
+          shpnt->this_id = hosts[i].scsi_id;
+          sym53c416_init(hosts[i].base, hosts[i].scsi_id);
+          count++;
+          restore_flags(flags);
+          }
+        }
+      }
+  return count;
+  }
+
+const char *sym53c416_info(struct Scsi_Host *SChost)
+  {
+  int i;
+  int base = SChost->io_port;
+  int irq = SChost->irq;
+  int scsi_id = 0;
+  int rev = inb(base + TC_HIGH);
+
+  for(i = 0; i < host_index; i++)
+    if(hosts[i].base == base)
+      scsi_id = hosts[i].scsi_id;
+  sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow");
+  return info;
+  }
+
+int sym53c416_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
+  {
+  int base;
+  unsigned long flags = 0;
+  int i;
+
+  /* Store base register as we can have more than one controller in the system */
+  base = SCpnt->host->io_port;
+  current_command = SCpnt;                  /* set current command                */
+  current_command->scsi_done = done;        /* set ptr to done function           */
+  current_command->SCp.phase = command_ph;  /* currect phase is the command phase */
+  current_command->SCp.Status = 0;
+  current_command->SCp.Message = 0;
+
+  save_flags(flags);
+  cli();
+  outb(SCpnt->target, base + DEST_BUS_ID); /* Set scsi id target        */
+  outb(FLUSH_FIFO, base + COMMAND_REG);    /* Flush SCSI and PIO FIFO's */
+  /* Write SCSI command into the SCSI fifo */
+  for(i = 0; i < SCpnt->cmd_len; i++)
+    outb(SCpnt->cmnd[i], base + SCSI_FIFO);
+  /* Start selection sequence */
+  outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG);
+  /* Now an interrupt will be generated which we will catch in out interrupt routine */
+  restore_flags(flags);
+  return 0;
+  }
+
+static void internal_done(Scsi_Cmnd *SCpnt)
+  {
+  SCpnt->SCp.Status++;
+  }
+
+int sym53c416_command(Scsi_Cmnd *SCpnt)
+  {
+  sym53c416_queuecommand(SCpnt, internal_done);
+  SCpnt->SCp.Status = 0;
+  while(!SCpnt->SCp.Status)
+    barrier();
+  return SCpnt->result;
+  }
+
+int sym53c416_abort(Scsi_Cmnd *SCpnt)
+  {
+  printk("sym53c416_abort\n");
+
+  /* We don't know how to abort for the moment */
+  return SCSI_ABORT_SNOOZE;
+  }
+
+int sym53c416_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+  {
+  int base;
+  int scsi_id = -1;
+  int i;
+
+  printk("sym53c416_reset\n");
+  base = SCpnt->host->io_port;
+  /* search scsi_id */
+  for(i = 0; i < host_index && scsi_id != -1; i++)
+    if(hosts[i].base == base)
+      scsi_id = hosts[i].scsi_id;
+  outb(RESET_CHIP, base + COMMAND_REG);
+  outb(NOOP | PIO_MODE, base + COMMAND_REG);
+  outb(RESET_SCSI_BUS, base + COMMAND_REG);
+  sym53c416_init(base, scsi_id);
+  return SCSI_RESET_PENDING;
+  }
+
+int sym53c416_bios_param(Disk *disk, kdev_t dev, int *ip)
+  {
+  int size;
+
+  size = disk->capacity;
+  ip[0] = 64;                         /* heads                        */
+  ip[1] = 32;                         /* sectors                      */
+  if((ip[2] = size >> 11) > 1024)     /* cylinders, test for big disk */
+    {
+    ip[0] = 255;                      /* heads                        */
+    ip[1] = 63;                       /* sectors                      */
+    ip[2] = size / (255 * 63);        /* cylinders                    */
+    }
+  return 0;
+  }
+
+/* Loadable module support */
+#ifdef MODULE
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,26)
+MODULE_AUTHOR("Lieven Willems");
+MODULE_PARM(sym53c416, "1-2i");
+MODULE_PARM(sym53c416_1, "1-2i");
+MODULE_PARM(sym53c416_2, "1-2i");
+MODULE_PARM(sym53c416_3, "1-2i");
+#endif
+
+Scsi_Host_Template driver_template = SYM53C416;
+
+#include "scsi_module.c"
+#endif
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h
new file mode 100644 (file)
index 0000000..49abc83
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  sym53c416.h
+ * 
+ *  Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com)
+ *
+ *  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.
+ *
+ */
+
+#ifndef _SYM53C416_H
+#define _SYM53C416_H
+
+#if !defined(LINUX_VERSION_CODE)
+#include <linux/version.h>
+#endif
+
+#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+
+#define SYM53C416_SCSI_ID 7
+
+extern struct proc_dir_entry proc_scsi_sym53c416;
+
+extern int sym53c416_detect(Scsi_Host_Template *);
+extern const char *sym53c416_info(struct Scsi_Host *);
+extern int sym53c416_command(Scsi_Cmnd *);
+extern int sym53c416_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int sym53c416_abort(Scsi_Cmnd *);
+extern int sym53c416_reset(Scsi_Cmnd *, unsigned int);
+extern int sym53c416_bios_param(Disk *, kdev_t, int *);
+extern void sym53c416_setup(char *str, int *ints);
+
+#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,75)
+
+#define SYM53C416 {                                          \
+                  proc_dir:          &proc_scsi_sym53c416,   \
+                  name:              "Symbios Logic 53c416", \
+                  detect:            sym53c416_detect,       \
+                  info:              sym53c416_info,         \
+                  command:           sym53c416_command,      \
+                  queuecommand:      sym53c416_queuecommand, \
+                  abort:             sym53c416_abort,        \
+                  reset:             sym53c416_reset,        \
+                  bios_param:        sym53c416_bios_param,   \
+                  can_queue:         1,                      \
+                  this_id:           SYM53C416_SCSI_ID,      \
+                  sg_tablesize:      32,                     \
+                  cmd_per_lun:       1,                      \
+                  unchecked_isa_dma: 1,                      \
+                  use_clustering:    ENABLE_CLUSTERING       \
+                  }
+
+#else
+
+#define SYM53C416 {                       \
+                  NULL,                   \
+                  NULL,                   \
+                  &proc_scsi_sym53c416,   \
+                  NULL,                   \
+                  "Symbios Logic 53c416", \
+                  sym53c416_detect,       \
+                  NULL,                   \
+                  sym53c416_info,         \
+                  sym53c416_command,      \
+                  sym53c416_queuecommand, \
+                  sym53c416_abort,        \
+                  sym53c416_reset,        \
+                  NULL,                   \
+                  sym53c416_bios_param,   \
+                  1,                      \
+                  SYM53C416_SCSI_ID,      \
+                  32, /* ???? */          \
+                  1,                      \
+                  0,                      \
+                  1,                      \
+                  ENABLE_CLUSTERING       \
+                  }
+
+#endif
+
+#endif
diff --git a/drivers/sound/.defines b/drivers/sound/.defines
new file mode 100644 (file)
index 0000000..b42573c
--- /dev/null
@@ -0,0 +1,118 @@
+# Computer generated file. Please don't edit
+
+ifdef CONFIG_PSS
+CONFIG_MPU_EMU=y
+endif
+
+ifdef CONFIG_SSCAPE
+CONFIG_MPU_EMU=y
+endif
+
+ifdef CONFIG_CS4232
+CONFIG_MPU_EMU=y
+endif
+
+ifdef CONFIG_MAUI
+CONFIG_MPU_EMU=y
+endif
+
+ifdef CONFIG_PSS
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_GUS16
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_GUSMAX
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_MSS
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_SSCAPE
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_TRIX
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_MAD16
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_CS4232
+CONFIG_AD1848=y
+endif
+
+ifdef CONFIG_SB
+CONFIG_SBDSP=y
+endif
+
+ifdef CONFIG_TRIX
+CONFIG_SBDSP=y
+endif
+
+ifdef CONFIG_MAD16
+CONFIG_SBDSP=y
+endif
+
+ifdef CONFIG_SB
+CONFIG_UART401=y
+endif
+
+ifdef CONFIG_TRIX
+CONFIG_UART401=y
+endif
+
+ifdef CONFIG_MAD16
+CONFIG_UART401=y
+endif
+
+ifdef CONFIG_PAS
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_SB
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_ADLIB
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_GUS
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_MPU401
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_PSS
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_SSCAPE
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_TRIX
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_MAD16
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_CS4232
+CONFIG_SEQUENCER=y
+endif
+
+ifdef CONFIG_MAUI
+CONFIG_SEQUENCER=y
+endif
+
index b1bc3607904bd99befe4226407f4ba54ee59935f..b160c29e591e38f9491037db7bf98aa84e30d9b2 100644 (file)
-#
-# Sound driver configuration
-#
-#--------
-# There is another config script which is compatible with rest of
-# the kernel. It can be activated by running 'make mkscript' in this
-# directory. Please note that this is an _experimental_ feature which
-# doesn't work with all cards (PSS, SM Wave, AudioTrix Pro, Maui).
-#--------
-#
-$MAKE -C drivers/sound config || exit 1
+bool 'ProAudioSpectrum 16 support' CONFIG_PAS
+bool 'Sound Blaster (SB, SBPro, SB16, clones) support' CONFIG_SB
+bool 'Generic OPL2/OPL3 FM synthesizer support' CONFIG_ADLIB
+bool 'Gravis Ultrasound support' CONFIG_GUS
+bool 'MPU-401 support (NOT for SB16)' CONFIG_MPU401
+bool '6850 UART Midi support' CONFIG_UART6850
+bool 'PSS (ECHO-ADI2111) support' CONFIG_PSS
+bool '16 bit sampling option of GUS (_NOT_ GUS MAX)' CONFIG_GUS16
+bool 'GUS MAX support' CONFIG_GUSMAX
+bool 'Microsoft Sound System support' CONFIG_MSS
+bool 'Ensoniq SoundScape support' CONFIG_SSCAPE
+bool 'MediaTrix AudioTrix Pro support' CONFIG_TRIX
+bool 'Support for MAD16 and/or Mozart based cards' CONFIG_MAD16
+bool 'Support for Crystal CS4232 based (PnP) cards' CONFIG_CS4232
+bool 'Support for Turtle Beach Wave Front (Maui, Tropez) synthesizers' CONFIG_MAUI
+bool '/dev/dsp and /dev/audio support' CONFIG_AUDIO
+bool 'MIDI interface support' CONFIG_MIDI
+bool 'FM synthesizer (YM3812/OPL-3) support' CONFIG_YM3812
+
+if [ "$CONFIG_SB" = "y" ]; then
+hex 'I/O base for SB Check from manual of the card' SBC_BASE 220
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster IRQ Check from manual of the card' SBC_IRQ 7
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster DMA 0, 1 or 3' SBC_DMA 1
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'Sound Blaster 16 bit DMA (_REQUIRED_for SB16, Jazz16, SMW) 5, 6 or 7 (use 1 for 8 bit cards)' SB_DMA2 5
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+hex 'MPU401 I/O base of SB16, Jazz16 and ES1688 Check from manual of the card' SB_MPU_BASE 0
+fi
+
+if [ "$CONFIG_SB" = "y" ]; then
+int 'SB MPU401 IRQ (Jazz16, SM Wave and ES1688) Use -1 with SB16' SB_MPU_IRQ -1
+fi
+
+if [ "$CONFIG_PAS" = "y" ]; then
+int 'PAS16 IRQ 3, 4, 5, 7, 9, 10, 11, 12, 14 or 15' PAS_IRQ 10
+fi
+
+if [ "$CONFIG_PAS" = "y" ]; then
+int 'PAS16 DMA 0, 1, 3, 5, 6 or 7' PAS_DMA 3
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+hex 'I/O base for GUS 210, 220, 230, 240, 250 or 260' GUS_BASE 220
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'GUS IRQ 3, 5, 7, 9, 11, 12 or 15' GUS_IRQ 15
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'GUS DMA 1, 3, 5, 6 or 7' GUS_DMA 6
+fi
+
+if [ "$CONFIG_GUS" = "y" ]; then
+int 'Second DMA channel for GUS 1, 3, 5, 6 or 7' GUS_DMA2 -1
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+hex 'I/O base for the 16 bit daughtercard of GUS 530, 604, E80 or F40' GUS16_BASE 530
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+int 'GUS 16 bit daughtercard IRQ 3, 4, 5, 7, or 9' GUS16_IRQ 7
+fi
+
+if [ "$CONFIG_GUS16" = "y" ]; then
+int 'GUS DMA 0, 1 or 3' GUS16_DMA 3
+fi
+
+if [ "$CONFIG_MPU401" = "y" ]; then
+hex 'I/O base for MPU401 Check from manual of the card' MPU_BASE 330
+fi
+
+if [ "$CONFIG_MPU401" = "y" ]; then
+int 'MPU401 IRQ Check from manual of the card' MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+hex 'I/O base for Maui 210, 230, 260, 290, 300, 320, 338 or 330' MAUI_BASE 330
+fi
+
+if [ "$CONFIG_MAUI" = "y" ]; then
+int 'Maui IRQ 5, 9, 12 or 15' MAUI_IRQ 9
+fi
+
+if [ "$CONFIG_UART6850" = "y" ]; then
+hex 'I/O base for UART 6850 MIDI port (Unknown)' U6850_BASE 0
+fi
+
+if [ "$CONFIG_UART6850" = "y" ]; then
+int 'UART6850 IRQ (Unknown)' U6850_IRQ -1
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS I/O base 220 or 240' PSS_BASE 220
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS audio I/O base 530, 604, E80 or F40' PSS_MSS_BASE 530
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS audio IRQ 7, 9, 10 or 11' PSS_MSS_IRQ 11
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS audio DMA 0, 1 or 3' PSS_MSS_DMA 3
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+hex 'PSS MIDI I/O base ' PSS_MPU_BASE 330
+fi
+
+if [ "$CONFIG_PSS" = "y" ]; then
+int 'PSS MIDI IRQ 3, 4, 5, 7 or 9' PSS_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+hex 'MSS/WSS I/O base 530, 604, E80 or F40' MSS_BASE 530
+fi
 
+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS IRQ 7, 9, 10 or 11' MSS_IRQ 11
+fi
+
+if [ "$CONFIG_MSS" = "y" ]; then
+int 'MSS/WSS DMA 0, 1 or 3' MSS_DMA 3
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+hex 'SoundScape MIDI I/O base 320, 330, 340 or 350' SSCAPE_BASE 330
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape MIDI IRQ ' SSCAPE_IRQ 9
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape initialization DMA 0, 1 or 3' SSCAPE_DMA 3
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+hex 'SoundScape audio I/O base 534, 608, E84 or F44' SSCAPE_MSS_BASE 534
+fi
+
+if [ "$CONFIG_SSCAPE" = "y" ]; then
+int 'SoundScape audio IRQ 7, 9, 10 or 11' SSCAPE_MSS_IRQ 11
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'AudioTrix audio I/O base 530, 604, E80 or F40' TRIX_BASE 530
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix audio IRQ 7, 9, 10 or 11' TRIX_IRQ 11
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix audio DMA 0, 1 or 3' TRIX_DMA 0
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix second (duplex) DMA 0, 1 or 3' TRIX_DMA2 3
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'AudioTrix MIDI I/O base 330, 370, 3B0 or 3F0' TRIX_MPU_BASE 330
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix MIDI IRQ 3, 4, 5, 7 or 9' TRIX_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+hex 'AudioTrix SB I/O base 220, 210, 230, 240, 250, 260 or 270' TRIX_SB_BASE 220
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix SB IRQ 3, 4, 5 or 7' TRIX_SB_IRQ 7
+fi
+
+if [ "$CONFIG_TRIX" = "y" ]; then
+int 'AudioTrix SB DMA 1 or 3' TRIX_SB_DMA 1
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+hex 'CS4232 audio I/O base 530, 604, E80 or F40' CS4232_BASE 530
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 audio IRQ 5, 7, 9, 11, 12 or 15' CS4232_IRQ 11
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 audio DMA 0, 1 or 3' CS4232_DMA 0
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 second (duplex) DMA 0, 1 or 3' CS4232_DMA2 3
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+hex 'CS4232 MIDI I/O base 330, 370, 3B0 or 3F0' CS4232_MPU_BASE 330
+fi
+
+if [ "$CONFIG_CS4232" = "y" ]; then
+int 'CS4232 MIDI IRQ 5, 7, 9, 11, 12 or 15' CS4232_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+hex 'MAD16 audio I/O base 530, 604, E80 or F40' MAD16_BASE 530
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 audio IRQ 7, 9, 10 or 11' MAD16_IRQ 11
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 audio DMA 0, 1 or 3' MAD16_DMA 3
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 second (duplex) DMA 0, 1 or 3' MAD16_DMA2 0
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+hex 'MAD16 MIDI I/O base 300, 310, 320 or 330 (0 disables)' MAD16_MPU_BASE 330
+fi
+
+if [ "$CONFIG_MAD16" = "y" ]; then
+int 'MAD16 MIDI IRQ 5, 7, 9 or 10' MAD16_MPU_IRQ 9
+fi
+
+if [ "$CONFIG_AUDIO" = "y" ]; then
+int 'Audio DMA buffer size 4096, 16384, 32768 or 65536' DSP_BUFFSIZE 65536
+fi
+#
+$MAKE -C drivers/sound kernelconfig || exit 1
 bool 'Additional low level drivers' CONFIG_LOWLEVEL_SOUND
 
 if [ "$CONFIG_LOWLEVEL_SOUND" = "y" ]; then
diff --git a/drivers/sound/local.h b/drivers/sound/local.h
new file mode 100644 (file)
index 0000000..bdf1703
--- /dev/null
@@ -0,0 +1,45 @@
+/* Computer generated file. Please don't edit! */
+
+#define KERNEL_COMPATIBLE_CONFIG
+
+#define SELECTED_SOUND_OPTIONS 0x00000000
+
+#if \
+  defined(CONFIG_PSS) || defined(CONFIG_SSCAPE) || \
+  defined(CONFIG_CS4232) || defined(CONFIG_MAUI)
+#      define CONFIG_MPU_EMU
+#endif
+
+#if \
+  defined(CONFIG_PSS) || defined(CONFIG_GUS16) || \
+  defined(CONFIG_GUSMAX) || defined(CONFIG_MSS) || \
+  defined(CONFIG_SSCAPE) || defined(CONFIG_TRIX) || \
+  defined(CONFIG_MAD16) || defined(CONFIG_CS4232)
+#      define CONFIG_AD1848
+#endif
+
+#if \
+  defined(CONFIG_SB) || defined(CONFIG_TRIX) || \
+  defined(CONFIG_MAD16)
+#      define CONFIG_SBDSP
+#endif
+
+#if \
+  defined(CONFIG_SB) || defined(CONFIG_TRIX) || \
+  defined(CONFIG_MAD16)
+#      define CONFIG_UART401
+#endif
+
+#if \
+  defined(CONFIG_PAS) || defined(CONFIG_SB) || \
+  defined(CONFIG_ADLIB) || defined(CONFIG_GUS) || \
+  defined(CONFIG_MPU401) || defined(CONFIG_PSS) || \
+  defined(CONFIG_SSCAPE) || defined(CONFIG_TRIX) || \
+  defined(CONFIG_MAD16) || defined(CONFIG_CS4232) || \
+  defined(CONFIG_MAUI)
+#      define CONFIG_SEQUENCER
+#endif
+
+#define SOUND_CONFIG_DATE "Fri Jan 29 15:33:26 GMT 1999"
+#define SOUND_CONFIG_BY "root"
+#define SOUND_UNAME_A "Linux roadrunner.swansea.linux.org.uk 2.2.1-ac1 #105 Thu Jan 28 22:19:39 GMT 1999 i686 unknown"
index 5ed7d535d6a1bc0c866c18c41054ad6c5867a6aa..7273edf812384dc84d545d783917742a6d284601 100644 (file)
@@ -46,6 +46,7 @@ if [ "$CONFIG_NLS" = "y" -o "$CONFIG_NLS" = "m" ]; then
   dep_tristate 'NLS ISO 8859-7 (Modern Greek)'    CONFIG_NLS_ISO8859_7    $CONFIG_NLS
   dep_tristate 'NLS ISO 8859-8 (Hebrew)'    CONFIG_NLS_ISO8859_8    $CONFIG_NLS
   dep_tristate 'NLS ISO 8859-9 (Latin 5; Turkey)'    CONFIG_NLS_ISO8859_9    $CONFIG_NLS
+  dep_tristate 'NLS ISO 8859-15 (Latin 9; Western European Languages with Euro)' CONFIG_NLS_ISO8859_15 $CONFIG_NLS
   dep_tristate 'NLS KOI8-R (Russian)'        CONFIG_NLS_KOI8_R       $CONFIG_NLS
   endmenu
 fi
index 13897ec1eef6efb570e6a4b3660872b6a4de4227..df8d0347c504ff038add38be44cfe954e536c30f 100644 (file)
@@ -481,6 +481,14 @@ else
   endif
 endif
 
+ifeq ($(CONFIG_NLS_ISO8859_15),y)
+NLS += nls_iso8859_15.o
+else
+  ifeq ($(CONFIG_NLS_ISO8859_15),m)
+  M_OBJS += nls_iso8859_15.o
+  endif
+endif
+
 ifeq ($(CONFIG_NLS_KOI8_R),y)
 NLS += nls_koi8_r.o
 else
index e746056e404be3d6e819386d0d5ca918ae89ae81..e71978a8adc82ccfcc5476cc16d3c68c2f8280d1 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/sched.h>
 #include <linux/mm.h>
+#include <linux/file.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/stat.h>
@@ -59,50 +60,57 @@ asmlinkage int sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {      
        struct file * filp;
        int on;
+       int retval = 0;
 
-       if (fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+       filp = fget(fd);
+       
+       if(filp==NULL)
                return -EBADF;
+               
        switch (cmd) {
                case FIOCLEX:
                        FD_SET(fd, &current->files->close_on_exec);
-                       return 0;
+                       break;
 
                case FIONCLEX:
                        FD_CLR(fd, &current->files->close_on_exec);
-                       return 0;
+                       break;
 
                case FIONBIO:
-                       on = verify_area(VERIFY_READ, (unsigned int *)arg,
+                       retval = verify_area(VERIFY_READ, (unsigned int *)arg,
                                sizeof(unsigned int));
-                       if(on)  
-                               return on;
-                       on = get_user((unsigned int *) arg);
-                       if (on)
-                               filp->f_flags |= O_NONBLOCK;
-                       else
-                               filp->f_flags &= ~O_NONBLOCK;
-                       return 0;
+                       if(!retval)     
+                       {
+                               on = get_user((unsigned int *) arg);
+                               if (on)
+                                       filp->f_flags |= O_NONBLOCK;
+                               else
+                                       filp->f_flags &= ~O_NONBLOCK;
+                       }
+                       break;
 
                case FIOASYNC: /* O_SYNC is not yet implemented,
                                  but it's here for completeness. */
-                       on = verify_area(VERIFY_READ, (unsigned int *)arg,
+                       retval = verify_area(VERIFY_READ, (unsigned int *)arg,
                                sizeof(unsigned int));
-                       if(on)  
-                               return on;
-                       on = get_user ((unsigned int *) arg);
-                       if (on)
-                               filp->f_flags |= O_SYNC;
-                       else
-                               filp->f_flags &= ~O_SYNC;
-                       return 0;
+                       if(!retval)     
+                       {
+                               on = get_user ((unsigned int *) arg);
+                               if (on)
+                                       filp->f_flags |= O_SYNC;
+                               else
+                                       filp->f_flags &= ~O_SYNC;
+                       }
+                       break;
 
                default:
                        if (filp->f_inode && S_ISREG(filp->f_inode->i_mode))
-                               return file_ioctl(filp, cmd, arg);
-
-                       if (filp->f_op && filp->f_op->ioctl)
-                               return filp->f_op->ioctl(filp->f_inode, filp, cmd, arg);
-
-                       return -ENOTTY;
+                               retval = file_ioctl(filp, cmd, arg);
+                       else if (filp->f_op && filp->f_op->ioctl)
+                               retval = filp->f_op->ioctl(filp->f_inode, filp, cmd, arg);
+                       else 
+                               retval = -ENOTTY;
        }
+       fput(filp, filp->f_inode);
+       return retval;
 }
index 74af3d021fa675308daf2d7182f2981266d015a7..d8c85836c13ac732841d747b215e6bdca1ef07cb 100644 (file)
--- a/fs/nls.c
+++ b/fs/nls.c
@@ -455,6 +455,9 @@ int init_nls(void)
 #ifdef CONFIG_NLS_ISO8859_9
        init_nls_iso8859_9();
 #endif
+#ifdef CONFIG_NLS_ISO8859_15
+       init_nls_iso8859_15();
+#endif
 #ifdef CONFIG_NLS_CODEPAGE_437
        init_nls_cp437();
 #endif
diff --git a/fs/nls_iso8859-15.c b/fs/nls_iso8859-15.c
new file mode 100644 (file)
index 0000000..33478bf
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * linux/fs/nls_iso8859-15.c
+ *
+ * Charset iso8859-15 translation tables.
+ * The Unicode to charset table has only exact mappings.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/nls.h>
+
+static struct nls_unicode charset2uni[256] = {
+       /* 0x00*/
+       {0x00, 0x00}, {0x01, 0x00}, {0x02, 0x00}, {0x03, 0x00},
+       {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x00},
+       {0x08, 0x00}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x00},
+       {0x0c, 0x00}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00},
+       /* 0x10*/
+       {0x10, 0x00}, {0x11, 0x00}, {0x12, 0x00}, {0x13, 0x00},
+       {0x14, 0x00}, {0x15, 0x00}, {0x16, 0x00}, {0x17, 0x00},
+       {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00},
+       {0x1c, 0x00}, {0x1d, 0x00}, {0x1e, 0x00}, {0x1f, 0x00},
+       /* 0x20*/
+       {0x20, 0x00}, {0x21, 0x00}, {0x22, 0x00}, {0x23, 0x00},
+       {0x24, 0x00}, {0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00},
+       {0x28, 0x00}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00},
+       {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x2f, 0x00},
+       /* 0x30*/
+       {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00},
+       {0x34, 0x00}, {0x35, 0x00}, {0x36, 0x00}, {0x37, 0x00},
+       {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00},
+       {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00},
+       /* 0x40*/
+       {0x40, 0x00}, {0x41, 0x00}, {0x42, 0x00}, {0x43, 0x00},
+       {0x44, 0x00}, {0x45, 0x00}, {0x46, 0x00}, {0x47, 0x00},
+       {0x48, 0x00}, {0x49, 0x00}, {0x4a, 0x00}, {0x4b, 0x00},
+       {0x4c, 0x00}, {0x4d, 0x00}, {0x4e, 0x00}, {0x4f, 0x00},
+       /* 0x50*/
+       {0x50, 0x00}, {0x51, 0x00}, {0x52, 0x00}, {0x53, 0x00},
+       {0x54, 0x00}, {0x55, 0x00}, {0x56, 0x00}, {0x57, 0x00},
+       {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x00}, {0x5b, 0x00},
+       {0x5c, 0x00}, {0x5d, 0x00}, {0x5e, 0x00}, {0x5f, 0x00},
+       /* 0x60*/
+       {0x60, 0x00}, {0x61, 0x00}, {0x62, 0x00}, {0x63, 0x00},
+       {0x64, 0x00}, {0x65, 0x00}, {0x66, 0x00}, {0x67, 0x00},
+       {0x68, 0x00}, {0x69, 0x00}, {0x6a, 0x00}, {0x6b, 0x00},
+       {0x6c, 0x00}, {0x6d, 0x00}, {0x6e, 0x00}, {0x6f, 0x00},
+       /* 0x70*/
+       {0x70, 0x00}, {0x71, 0x00}, {0x72, 0x00}, {0x73, 0x00},
+       {0x74, 0x00}, {0x75, 0x00}, {0x76, 0x00}, {0x77, 0x00},
+       {0x78, 0x00}, {0x79, 0x00}, {0x7a, 0x00}, {0x7b, 0x00},
+       {0x7c, 0x00}, {0x7d, 0x00}, {0x7e, 0x00}, {0x7f, 0x00},
+       /* 0x80*/
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       /* 0x90*/
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00},
+       /* 0xa0*/
+       {0xa0, 0x00}, {0xa1, 0x00}, {0xa2, 0x00}, {0xa3, 0x00},
+       {0xac, 0x20}, {0xa5, 0x00}, {0x60, 0x01}, {0xa7, 0x00},
+       {0x61, 0x01}, {0xa9, 0x00}, {0xaa, 0x00}, {0xab, 0x00},
+       {0xac, 0x00}, {0xad, 0x00}, {0xae, 0x00}, {0xaf, 0x00},
+       /* 0xb0*/
+       {0xb0, 0x00}, {0xb1, 0x00}, {0xb2, 0x00}, {0xb3, 0x00},
+       {0x7d, 0x01}, {0xb5, 0x00}, {0xb6, 0x00}, {0xb7, 0x00},
+       {0x7e, 0x01}, {0xb9, 0x00}, {0xba, 0x00}, {0xbb, 0x00},
+       {0x52, 0x01}, {0x53, 0x01}, {0x78, 0x01}, {0xbf, 0x00},
+       /* 0xc0*/
+       {0xc0, 0x00}, {0xc1, 0x00}, {0xc2, 0x00}, {0xc3, 0x00},
+       {0xc4, 0x00}, {0xc5, 0x00}, {0xc6, 0x00}, {0xc7, 0x00},
+       {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x00}, {0xcb, 0x00},
+       {0xcc, 0x00}, {0xcd, 0x00}, {0xce, 0x00}, {0xcf, 0x00},
+       /* 0xd0*/
+       {0xd0, 0x00}, {0xd1, 0x00}, {0xd2, 0x00}, {0xd3, 0x00},
+       {0xd4, 0x00}, {0xd5, 0x00}, {0xd6, 0x00}, {0xd7, 0x00},
+       {0xd8, 0x00}, {0xd9, 0x00}, {0xda, 0x00}, {0xdb, 0x00},
+       {0xdc, 0x00}, {0xdd, 0x00}, {0xde, 0x00}, {0xdf, 0x00},
+       /* 0xe0*/
+       {0xe0, 0x00}, {0xe1, 0x00}, {0xe2, 0x00}, {0xe3, 0x00},
+       {0xe4, 0x00}, {0xe5, 0x00}, {0xe6, 0x00}, {0xe7, 0x00},
+       {0xe8, 0x00}, {0xe9, 0x00}, {0xea, 0x00}, {0xeb, 0x00},
+       {0xec, 0x00}, {0xed, 0x00}, {0xee, 0x00}, {0xef, 0x00},
+       /* 0xf0*/
+       {0xf0, 0x00}, {0xf1, 0x00}, {0xf2, 0x00}, {0xf3, 0x00},
+       {0xf4, 0x00}, {0xf5, 0x00}, {0xf6, 0x00}, {0xf7, 0x00},
+       {0xf8, 0x00}, {0xf9, 0x00}, {0xfa, 0x00}, {0xfb, 0x00},
+       {0xfc, 0x00}, {0xfd, 0x00}, {0xfe, 0x00}, {0xff, 0x00},
+};
+
+static unsigned char page00[256] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00-0x07 */
+       0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08-0x0f */
+       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10-0x17 */
+       0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18-0x1f */
+       0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20-0x27 */
+       0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28-0x2f */
+       0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0x30-0x37 */
+       0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38-0x3f */
+       0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0x40-0x47 */
+       0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0x48-0x4f */
+       0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0x50-0x57 */
+       0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, /* 0x58-0x5f */
+       0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0x60-0x67 */
+       0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0x68-0x6f */
+       0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0x70-0x77 */
+       0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, /* 0x78-0x7f */
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+       0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0x00, 0xa7, /* 0xa0-0xa7 */
+       0x00, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */
+       0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */
+       0x00, 0xb9, 0xba, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0xb8-0xbf */
+       0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */
+       0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */
+       0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */
+       0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */
+       0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */
+       0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */
+       0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */
+       0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0xf8-0xff */
+};
+
+static unsigned char page01[256] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+       0x00, 0x00, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+       0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+       0xbe, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char page20[256] = {
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */
+
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+       0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+static unsigned char *page_uni2charset[256] = {
+       page00, page01, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+       NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+
+       NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+       NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+
+       page20, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+       NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,
+};
+
+static void inc_use_count(void)
+{
+       MOD_INC_USE_COUNT;
+}
+
+static void dec_use_count(void)
+{
+       MOD_DEC_USE_COUNT;
+}
+
+static struct nls_table table = {
+       "iso8859-15",
+       page_uni2charset,
+       charset2uni,
+       inc_use_count,
+       dec_use_count,
+       NULL
+};
+
+int init_nls_iso8859_15(void)
+{
+       return register_nls(&table);
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+       return init_nls_iso8859_15();
+}
+
+
+void cleanup_module(void)
+{
+       unregister_nls(&table);
+       return;
+}
+#endif
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 8
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -8
+ * c-argdecl-indent: 8
+ * c-label-offset: -8
+ * c-continued-statement-offset: 8
+ * c-continued-brace-offset: 0
+ * End:
+ */
index bb4f71de877ef39f4fc2a6b7fd362b2283e9a168..0337b92b3db7e91bc6ba9486fa101e9f83887b07 100644 (file)
@@ -83,6 +83,8 @@
 #define TIOCGETD       0x5424
 #define TCSBRKP                0x5425  /* Needed for POSIX tcsendbreak() */
 #define TIOCTTYGSTRUCT 0x5426  /* For debugging only */
+#define TIOCSBRK       0x5427  /* BSD compatibility */
+#define TIOCCBRK       0x5428  /* BSD compatibility */
 
 #define TIOCSERCONFIG  0x5453
 #define TIOCSERGWILD   0x5454
index 5620b5c40a2221681c71060ca9d4d3da3b9fc26e..37e2cf0eae8926ec8542322937f2553853e928cc 100644 (file)
@@ -581,6 +581,7 @@ struct cyclades_port {
 #define        CyISA_Ywin      0x2000
 
 #define CyPCI_Ywin     0x4000
+#define CyPCI_Yctl     0x80
 #define CyPCI_Zctl     CTRL_WINDOW_SIZE
 #define CyPCI_Zwin     0x80000
 #define CyPCI_Ze_win   (2 * CyPCI_Zwin)
index b922e0d609db010a4719a15c75a4145e258a0071..fe6f35fc303a89f0f2c24ec311d6faf4b3911a36 100644 (file)
 /* bit 1 is reserved if address_space = 1 */
 
 #define PCI_CARDBUS_CIS                0x28
-#define PCI_SUBSYSTEM_ID       0x2c
-#define PCI_SUBSYSTEM_VENDOR_ID        0x2e  
+#define PCI_SUBSYSTEM_VENDOR_ID        0x2c
+#define PCI_SUBSYSTEM_ID       0x2e
 #define PCI_ROM_ADDRESS                0x30    /* 32 bits */
 #define  PCI_ROM_ADDRESS_ENABLE        0x01    /* Write 1 to enable ROM,
                                           bits 31..11 are address,
 #define PCI_DEVICE_ID_DEC_21052                0x0021
 #define PCI_DEVICE_ID_DEC_21150                0x0022
 #define PCI_DEVICE_ID_DEC_21152                0x0024
+#define PCI_DEVICE_ID_DEC_21154                0x0026
+#define PCI_DEVICE_ID_DEC_21285                0x1065
 
 #define PCI_VENDOR_ID_CIRRUS           0x1013
 #define PCI_DEVICE_ID_CIRRUS_7548      0x0038
 #define PCI_DEVICE_ID_MYLEX_DAC960P_V2 0x0001
 #define PCI_DEVICE_ID_MYLEX_DAC960P_V3 0x0002
 #define PCI_DEVICE_ID_MYLEX_DAC960P_V4 0x0010
+#define PCI_DEVICE_ID_MYLEX_DAC960P_V5 0x0020
 
 #define PCI_VENDOR_ID_APPLE            0x106b
 #define PCI_DEVICE_ID_APPLE_BANDIT     0x0001
index 7b1260a198a96a639be7351ee8491a161883b876..2a9bdcc7d80663faaa80c9b5359c171511e09dbd 100644 (file)
@@ -141,6 +141,7 @@ enum scsi_directory_inos {
        PROC_SCSI_AM53C974,
        PROC_SCSI_SSC,
        PROC_SCSI_NCR53C406A,
+       PROC_SCSI_SYM53C416,
        PROC_SCSI_MEGARAID,
        PROC_SCSI_PPA,
        PROC_SCSI_ATP870U,
index 322d75cb3d8f4868c70b26c6107afa67da3bb8b9..cc0e7da7b316dd71127da3925d6689adc4f83dac 100644 (file)
@@ -103,6 +103,7 @@ extern void u14_34f_setup(char *str, int *ints);
 extern void fdomain_setup(char *str, int *ints);
 extern void in2000_setup(char *str, int *ints);
 extern void NCR53c406a_setup(char *str, int *ints);
+extern void sym53c416_setup(char *str, int *ints);
 extern void wd7000_setup(char *str, int *ints);
 extern void dc390_setup(char* str, int *ints);
 extern void ppa_setup(char *str, int *ints);
@@ -205,6 +206,11 @@ extern void pg_setup(char *str, int *ints);
 #ifdef CONFIG_PARIDE_PCD
 extern void pcd_setup(char *str, int *ints);
 #endif
+#ifdef CONFIG_BLK_CPQ_DA
+#ifdef CONFIG_BLK_CPQ_DA_EISA
+extern void cpqarray_setup(char *str, int *ints);
+#endif
+#endif
 
 #if defined(CONFIG_SYSVIPC) || defined(CONFIG_KERNELD)
 extern void ipc_init(void);
@@ -373,6 +379,9 @@ struct kernel_param bootsetups[] = {
 #ifdef CONFIG_SCSI_NCR53C406A
        { "ncr53c406a=", NCR53c406a_setup},
 #endif
+#ifdef CONFIG_SCSI_SYM53C416
+       { "sym53c416=", sym53c416_setup}, 
+#endif
 #ifdef CONFIG_SCSI_FUTURE_DOMAIN
        { "fdomain=", fdomain_setup},
 #endif
@@ -474,6 +483,11 @@ struct kernel_param bootsetups[] = {
 #endif
 #ifdef CONFIG_APM
        { "apm=", apm_setup },
+#endif
+#ifdef CONFIG_BLK_CPQ_DA
+#ifdef CONFIG_BLK_CPQ_DA_EISA
+       { "smart2=", cpqarray_setup },
+#endif
 #endif
        { 0, 0 }
 };
index 48e93c8e8c038a9741d6005d55ecc6070c945b1d..789b9130d7ae57f513e454c85a6a3ee45cd93973 100644 (file)
@@ -76,6 +76,14 @@ function define_bool () {
        eval $1=$2
 }
 
+#
+# Define an int to a specific value.
+#
+
+function define_int () {
+       eval $1=$2
+}
+
 #
 # Create a boolean (Yes/No) function for our current menu
 # which calls our local bool function.
@@ -955,6 +963,13 @@ save_configuration () {
                esac
        }
 
+       function define_int () {
+               eval $1="$2"
+               echo "$1=$2" >>$CONFIG
+               echo "#define $1 $2" >>$CONFIG_H
+       }
+
+
        function choice () {
                #
                # Find the first choice that's already set to 'y'
index fc9338db39dee8b6b74822914ca319ba3c7dfa92..63ca8709e933c602527e5a5b445efcb61a39e197 100644 (file)
@@ -280,6 +280,7 @@ void generate_if(struct kconfig * item,
    */
   switch(item->tok)
     {
+    case tok_define_int:
     case tok_define:
       printf("} then { set %s %s } \n",  item->optionname, item->value);
       break;
@@ -464,6 +465,9 @@ void generate_if_for_outfile(struct kconfig * item,
    */
   switch(item->tok)
     {
+    case tok_define_int:
+      printf("} then {write_int $cfg $autocfg %s %s $notmod }\n", item->optionname, item->value);
+      break;
     case tok_define:
       printf("} then {write_tristate $cfg $autocfg %s %s $notmod }\n", item->optionname, item->value);
       break;
@@ -572,7 +576,8 @@ static void end_proc(int menu_num)
        * Skip items not for this menu, or ones having no conditions.
        */
       if (cfg->menu_number != menu_num ) continue;
-      if (cfg->tok != tok_define) continue;
+      if (cfg->tok != tok_define && cfg->tok != tok_define_int)
+       continue;
       /*
        * Clear all of the booleans that are defined in this menu.
        */
@@ -717,6 +722,7 @@ void dump_tk_script(struct kconfig *scfg)
          cfg->menu_line = menu_line++;
          break;
        case tok_define:
+       case tok_define_int:
          cfg->menu_number = -1;
        case tok_choice:
        default:
@@ -923,7 +929,7 @@ void dump_tk_script(struct kconfig *scfg)
       /*
        * Skip items not for this menu, or ones having no conditions.
        */
-      if( cfg->tok != tok_define) continue;
+      if( cfg->tok != tok_define && cfg->tok != tok_define_int) continue;
       if (cfg->cond != NULL ) 
        generate_if(cfg, cfg->cond, menu_num, cfg->menu_line);
       else
@@ -988,6 +994,7 @@ void dump_tk_script(struct kconfig *scfg)
        case tok_tristate:
        case tok_dep_tristate:
        case tok_define:
+       case tok_define_int:
        case tok_choose:
          if(!(cfg->flags & GLOBAL_WRITTEN))
            {
@@ -1019,7 +1026,7 @@ void dump_tk_script(struct kconfig *scfg)
                  printf("\twrite_comment $cfg $autocfg \"%s\"\n", cfg->label);
                }
 #if 0
-             else if(cfg->tok == tok_define)
+             else if(cfg->tok == tok_define || cfg->tok == tok_define_int)
                {
                  printf("\twrite_define %s %s\n", cfg->optionname,
                         cfg->value);
@@ -1043,6 +1050,12 @@ void dump_tk_script(struct kconfig *scfg)
                         cfg->optionname,
                         cfg->optionname);
                }
+             else if (cfg->tok == tok_define_int )
+               {
+                 printf("\twrite_int $cfg $autocfg %s $%s $notmod\n",
+                        cfg->optionname,
+                        cfg->optionname);
+               }
              else if (cfg->tok == tok_hex )
                {
                  printf("\twrite_hex $cfg $autocfg %s $%s $notmod\n",
@@ -1109,13 +1122,14 @@ void dump_tk_script(struct kconfig *scfg)
   clear_globalflags(config);
   for(cfg = scfg; cfg != NULL; cfg = cfg->next)
     {
-      if( cfg->tok != tok_define ) continue;
+      if( cfg->tok != tok_define && cfg->tok != tok_define_int ) 
+       continue;
       printf("\tglobal %s; set %s 0\n",  cfg->optionname,  cfg->optionname);
       cfg->flags |= GLOBAL_WRITTEN;
     }
   for(cfg = scfg; cfg != NULL; cfg = cfg->next)
     {
-      if( cfg->tok != tok_define ) continue;
+      if( cfg->tok != tok_define && cfg->tok != tok_define_int ) continue;
       if (cfg->cond != NULL ) 
        generate_if(cfg, cfg->cond, -1, 0);
       else
index 2a000217c98e53fa52ebab2ce58eaec391c35236..73b62f589716f3d6dc248f4bde8ed0ed917a779a 100644 (file)
@@ -345,6 +345,11 @@ void parse(char * pnt) {
       tok = tok_define;
       pnt += 11;
     }
+  else if (strncmp(pnt, "define_int", 10) == 0) 
+    {
+      tok = tok_define_int;
+      pnt += 10;
+    }
   else if (strncmp(pnt, "bool", 4) == 0) 
     {
       tok = tok_bool;
@@ -447,6 +452,10 @@ void parse(char * pnt) {
       if(*pnt == 'n' || *pnt == 'N' ) kcfg->value = "0";
       if(*pnt == 'm' || *pnt == 'M' ) kcfg->value = "2";
       break;
+    case tok_define_int:
+      pnt = get_string(pnt, &kcfg->optionname);
+      pnt = get_string(pnt, &kcfg->value);
+      break;
     case tok_menuname:
       pnt = get_qstring(pnt, &kcfg->label);
       break;
index 911abdfbee438b024bc06d339eab4e8ccb5bc683..61209e02abf8402ea4198adc8343622754c8c064 100644 (file)
@@ -14,6 +14,7 @@ enum token {
   tok_hex,
   tok_make,
   tok_define,
+  tok_define_int,
   tok_choose,
   tok_choice,
   tok_endmenu,