From fb658862b5231b5a92c60fa310edf00161ea9f57 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:12:11 -0500 Subject: [PATCH] 2.0.37pre5 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) --- Documentation/Configure.help | 16 + arch/i386/config.in | 2 +- drivers/block/Config.in | 6 +- drivers/block/DAC960.c | 1 + drivers/block/README.smart2 | 17 + drivers/block/cpqarray.c | 184 ++- drivers/block/cpqarray.h | 2 + drivers/block/ide.c | 10 +- drivers/block/paride/friq.c | 42 +- drivers/block/paride/on26.c | 5 +- drivers/char/cyclades.c | 26 +- drivers/char/random.c | 10 + drivers/net/Makefile | 4 +- drivers/net/README.rcpci | 79 ++ drivers/net/de4x5.c | 28 +- drivers/net/de4x5.h | 1 + drivers/net/dummy.c | 5 + drivers/net/rcif.h | 68 +- drivers/net/{rcmtl.c => rclanmtl.c} | 1457 +++++++++++++---------- drivers/net/{rcmtl.h => rclanmtl.h} | 177 ++- drivers/net/rcpci45.c | 1674 ++++++++++++++------------- drivers/pci/pci.c | 2 + drivers/scsi/Config.in | 1 + drivers/scsi/Makefile | 8 + drivers/scsi/hosts.c | 7 + drivers/scsi/megaraid.c | 1290 ++++++++++++--------- drivers/scsi/megaraid.h | 236 ++-- drivers/scsi/sym53c416.c | 805 +++++++++++++ drivers/scsi/sym53c416.h | 91 ++ drivers/sound/.defines | 118 ++ drivers/sound/Config.in | 258 ++++- drivers/sound/local.h | 45 + fs/Config.in | 1 + fs/Makefile | 8 + fs/ioctl.c | 62 +- fs/nls.c | 3 + fs/nls_iso8859-15.c | 268 +++++ include/asm-alpha/ioctls.h | 2 + include/linux/cyclades.h | 1 + include/linux/pci.h | 7 +- include/linux/proc_fs.h | 1 + init/main.c | 14 + scripts/Menuconfig | 15 + scripts/tkgen.c | 24 +- scripts/tkparse.c | 9 + scripts/tkparse.h | 1 + 46 files changed, 4818 insertions(+), 2273 deletions(-) create mode 100644 drivers/net/README.rcpci rename drivers/net/{rcmtl.c => rclanmtl.c} (52%) rename drivers/net/{rcmtl.h => rclanmtl.h} (78%) create mode 100644 drivers/scsi/sym53c416.c create mode 100644 drivers/scsi/sym53c416.h create mode 100644 drivers/sound/.defines create mode 100644 drivers/sound/local.h create mode 100644 fs/nls_iso8859-15.c diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 75db1ff151b1..f349b4b13627 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -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=, [sym53c416_1=,] + + 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 diff --git a/arch/i386/config.in b/arch/i386/config.in index 52ea7df77e29..b6cb215f2a6e 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -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 diff --git a/drivers/block/Config.in b/drivers/block/Config.in index 5c70f0ad4d47..502cbb4efd10 100644 --- a/drivers/block/Config.in +++ b/drivers/block/Config.in @@ -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 diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 1dcf660e4680..28b0014596fc 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "DAC960.h" diff --git a/drivers/block/README.smart2 b/drivers/block/README.smart2 index 78fd159fde6a..053451754549 100644 --- a/drivers/block/README.smart2 +++ b/drivers/block/README.smart2 @@ -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: -------- diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 08313f5ecd85..c04a72bc6bee 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -42,10 +42,10 @@ #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 @@ -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; ivaddr + 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; iioaddr = 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<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<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; ivaddr; /* 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; } diff --git a/drivers/block/cpqarray.h b/drivers/block/cpqarray.h index 144eca4edfc5..f913569f11ba 100644 --- a/drivers/block/cpqarray.h +++ b/drivers/block/cpqarray.h @@ -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; diff --git a/drivers/block/ide.c b/drivers/block/ide.c index d6ff11d35d54..27bec67185f9 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -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. */ diff --git a/drivers/block/paride/friq.c b/drivers/block/paride/friq.c index 9b7e98501a54..37ebaa047976 100644 --- a/drivers/block/paride/friq.c +++ b/drivers/block/paride/friq.c @@ -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 #include @@ -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, diff --git a/drivers/block/paride/on26.c b/drivers/block/paride/on26.c index 231e01c0a477..d1e85cd28edb 100644 --- a/drivers/block/paride/on26.c +++ b/drivers/block/paride/on26.c @@ -12,10 +12,11 @@ 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 #include @@ -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); } diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 8b7695ff54b9..5d30a41ff23e 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c @@ -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; } diff --git a/drivers/char/random.c b/drivers/char/random.c index 3e8d21d55036..28de370b901d 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -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 */ diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a084af63f6ed..e7e06d9b37d3 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -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 index 000000000000..e3710f0b375e --- /dev/null +++ b/drivers/net/README.rcpci @@ -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 " +"route add -net eth0" + +optional (if you want to be able to access other networks): +"route add default gw 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". diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c index b6364cd6c30b..510aeea13e0a 100644 --- a/drivers/net/de4x5.c +++ b/drivers/net/de4x5.c @@ -404,11 +404,12 @@ 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 @@ -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 */ diff --git a/drivers/net/de4x5.h b/drivers/net/de4x5.h index c0c58ccf4beb..0a83efa91418 100644 --- a/drivers/net/de4x5.h +++ b/drivers/net/de4x5.h @@ -121,6 +121,7 @@ #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)) diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c index 6f360b968032..a8426bf4d64d 100644 --- a/drivers/net/dummy.c +++ b/drivers/net/dummy.c @@ -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; } diff --git a/drivers/net/rcif.h b/drivers/net/rcif.h index 4996b01daba5..a41f05aac20d 100644 --- a/drivers/net/rcif.h +++ b/drivers/net/rcif.h @@ -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/rcmtl.c b/drivers/net/rclanmtl.c similarity index 52% rename from drivers/net/rcmtl.c rename to drivers/net/rclanmtl.c index db1509affebd..971fb49b6d7e 100644 --- a/drivers/net/rcmtl.c +++ b/drivers/net/rclanmtl.c @@ -2,19 +2,19 @@ ** ************************************************************************* ** ** -** R C M T L . C $Revision: 1.1 $ +** R C L A N M T L . C $Revision: 5 $ ** ** -** RedCreek Message Transport Layer program module. +** RedCreek I2O LAN Message Transport Layer program module. ** ** --------------------------------------------------------------------- -** --- Copyright (c) 1997-1998, RedCreek Communications Inc. --- +** --- Copyright (c) 1997-1999, RedCreek Communications Inc. --- ** --- All rights reserved. --- ** --------------------------------------------------------------------- ** -** File Description: +** File Description: ** -** Host side message transport layer. +** 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 @@ -29,155 +29,155 @@ ** 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" +#include "rclanmtl.h" #define dprintf kprintf extern int printk(const char * fmt, ...); /* RedCreek LAN device Target ID */ -#define LAN_TARGET_ID 0x10 +#define RC_LAN_TARGET_ID 0x10 /* RedCreek's OSM default LAN receive Initiator */ #define DEFAULT_RECV_INIT_CONTEXT 0xA17 /* -** message structures +** I2O message structures */ -#define TID_SZ 12 -#define FUNCTION_SZ 8 +#define I2O_TID_SZ 12 +#define I2O_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 +#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 LAN_PACKET_SEND 0x3B -#define LAN_SDU_SEND 0x3D -#define LAN_RECEIVE_POST 0x3E -#define LAN_RESET 0x35 -#define LAN_SHUTDOWN 0x37 +#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 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 +#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 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 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 UTIL_NOP 0x00 +#define I2O_UTIL_NOP 0x00 -/* RC Get Status State values */ +/* I2O 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 +#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 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 +#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 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 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 @@ -199,13 +199,13 @@ extern int printk(const char * fmt, ...); /* Special TID Assignments */ -#define ADAPTER_TID 0 -#define HOST_TID 1 +#define I2O_IOP_TID 0 +#define I2O_HOST_TID 1 - /* RedCreek private message codes */ + /* RedCreek I2O 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_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 @@ -216,23 +216,27 @@ extern int printk(const char * fmt, ...); #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 -/* RC message header */ -typedef struct _RC_MSG_FRAME +/* I2O message header */ +typedef struct _I2O_MESSAGE_FRAME { - U8 VersionOffset; - U8 MsgFlags; - U16 MessageSize; - BF TargetAddress:TID_SZ; - BF InitiatorAddress:TID_SZ; - BF Function:FUNCTION_SZ; - U32 InitiatorContext; - /* SGL[] */ + U8 VersionOffset; + U8 MsgFlags; + U16 MessageSize; + BF TargetAddress:I2O_TID_SZ; + BF InitiatorAddress:I2O_TID_SZ; + BF Function:I2O_FUNCTION_SZ; + U32 InitiatorContext; + /* SGL[] */ } - RC_MSG_FRAME, *PRC_MSG_FRAME; +I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME; /* assumed a 16K minus 256 byte space for outbound queue message frames */ @@ -264,13 +268,13 @@ typedef struct tag_rcatu volatile unsigned long OutQueue; /* outbound queue port */ volatile unsigned long reserved4; volatile unsigned long reserver5; - /* RedCreek extension */ + /* RedCreek extension */ volatile unsigned long EtherMacLow; volatile unsigned long EtherMacHi; volatile unsigned long IPaddr; volatile unsigned long IPmask; } - ATU, *PATU; +ATU, *PATU; /* ** typedef PAB @@ -288,10 +292,10 @@ typedef struct PFNRXCALLBACK pRecvCallbackFunc; PFNCALLBACK pRebootCallbackFunc; PFNCALLBACK pCallbackFunc; - U16 ADAPTERState; + U16 IOPState; U16 InboundMFrameSize; } - PAB, *PPAB; +PAB, *PPAB; /* ** in reserved space right after PAB in host memory is area for returning @@ -320,25 +324,25 @@ static PPAB PCIAdapterBlock[MAX_ADAPTERS] = */ 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 */ + 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; +NICSTAT, *P_NICSTAT; #define DUMP_DONE 0x0000A005 /* completed statistical dump */ @@ -349,21 +353,21 @@ 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 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 */ +/* 1st 100h bytes of message block is reserved for messenger instance */ #define ADAPTER_BLOCK_RESERVED_SPACE 0x100 /* ** ========================================================================= -** InitRCApiMsgLayer() +** RCInitI2OMsgLayer() ** -** Initialize the RedCreek API Module and adapter. +** Initialize the RedCreek I2O Module and adapter. ** ** Inputs: AdapterID - interface number from 0 to 15 ** pciBaseAddr - virual base address of PCI (set by BIOS) @@ -378,29 +382,29 @@ static int SendEnableSysMsg(PPAB pPab); ** ========================================================================= */ RC_RETURN -InitRCApiMsgLayer(U16 AdapterID, U32 pciBaseAddr, +RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr, PU8 p_msgbuf, PU8 p_phymsgbuf, PFNTXCALLBACK TransmitCallbackFunction, PFNRXCALLBACK ReceiveCallbackFunction, PFNCALLBACK RebootCallbackFunction) { - int result; - PPAB pPab; + 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); + 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); + /* 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; - } + PCIAdapterBlock[AdapterID] = NULL; + } /* ** store adapter instance values in adapter block. @@ -411,39 +415,39 @@ InitRCApiMsgLayer(U16 AdapterID, U32 pciBaseAddr, pPab->p_atu = (PATU)pciBaseAddr; pPab->pPci45LinBaseAddr = (PU8)pciBaseAddr; - /* Set outbound message frame addr - skip over Adapter Block */ + /* 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 */ + /* store callback function addresses */ pPab->pTransCallbackFunc = TransmitCallbackFunction; pPab->pRecvCallbackFunc = ReceiveCallbackFunction; pPab->pRebootCallbackFunc = RebootCallbackFunction; pPab->pCallbackFunc = (PFNCALLBACK)NULL; /* - ** Initialize API + ** Initialize I2O IOP */ - result = GetAdapterStatus(pPab); + result = GetI2OStatus(pPab); if (result != RC_RTN_NO_ERROR) return result; - if (pPab->ADAPTERState == ADAPTER_STATE_OPERATIONAL) + if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL) { - printk("pPab->ADAPTERState == op: resetting adapter\n"); - RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL); + printk("pPab->IOPState == op: resetting adapter\n"); + RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL); } - result = SendAdapterOutboundQInitMsg(pPab); + result = SendI2OOutboundQInitMsg(pPab); if (result != RC_RTN_NO_ERROR) - return result; + return result; result = SendEnableSysMsg(pPab); if (result != RC_RTN_NO_ERROR) - return result; + return result; PCIAdapterBlock[AdapterID] = pPab; return RC_RTN_NO_ERROR; @@ -451,17 +455,17 @@ InitRCApiMsgLayer(U16 AdapterID, U32 pciBaseAddr, /* ** ========================================================================= -** Disable and Enable Adapter interrupts. Adapter interrupts are enabled at Init time +** 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 RCSendPacket() functions. Disabling Adapter interrupts -** will prevent hardware interrupt to host even though the outbound Adapter msg +** 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 RCDisableAdapterInterrupts(U16 AdapterID) +RC_RETURN RCDisableI2OInterrupts(U16 AdapterID) { PPAB pPab; @@ -476,14 +480,14 @@ RC_RETURN RCDisableAdapterInterrupts(U16 AdapterID) return RC_RTN_NO_ERROR; } -RC_RETURN RCEnableAdapterInterrupts(U16 AdapterID) +RC_RETURN RCEnableI2OInterrupts(U16 AdapterID) { PPAB pPab; pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) - return RC_RTN_ADPTR_NOT_REGISTERED; + return RC_RTN_ADPTR_NOT_REGISTERED; pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT; @@ -494,11 +498,11 @@ RC_RETURN RCEnableAdapterInterrupts(U16 AdapterID) /* ** ========================================================================= -** RCSendPacket() +** RCI2OSendPacket() ** ========================================================================= */ RC_RETURN -RCSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock) +RCI2OSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock) { U32 msgOffset; PU32 pMsg; @@ -506,7 +510,7 @@ RCSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock) PPAB pPab; #ifdef DEBUG -kprintf("RCSendPacket()...\n"); + kprintf("RCI2OSendPacket()...\n"); #endif /* DEBUG */ pPab = PCIAdapterBlock[AdapterID]; @@ -514,40 +518,40 @@ kprintf("RCSendPacket()...\n"); 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 */ + /* 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"); + 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 */ + /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset); - size = FillAdapterMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock); + size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock); if (size == -1) /* error processing TCB - send NOP msg */ { #ifdef DEBUG - kprintf("RCSendPacket(): Error Rrocess TCB!\n"); + kprintf("RCI2OSendPacket(): 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; + 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] = LAN_PACKET_SEND << 24 | HOST_TID << 12 | LAN_TARGET_ID; + 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 */ + /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; return RC_RTN_NO_ERROR; } @@ -556,7 +560,7 @@ kprintf("RCSendPacket()...\n"); /* ** ========================================================================= -** RCPostRecvBuffer() +** RCI2OPostRecvBuffer() ** ** inputs: pBufrCntrlBlock - pointer to buffer control block ** @@ -572,32 +576,32 @@ RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock) PPAB pPab; #ifdef DEBUG -kprintf("RCPostRecvBuffers()...\n"); + kprintf("RCPostRecvBuffers()...\n"); #endif /* DEBUG */ - /* search for DeviceHandle */ + /* 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 */ + /* 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"); + 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 */ + /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset); - size = FillAdapterMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock); + size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock); if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */ { @@ -605,18 +609,18 @@ kprintf("RCPostRecvBuffers()...\n"); 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 */ + 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] = LAN_RECEIVE_POST << 24 | HOST_TID << 12 | LAN_TARGET_ID; + 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 */ + /* post to Post Q */ pPab->p_atu->InQueue = msgOffset; return RC_RTN_NO_ERROR; } @@ -625,13 +629,13 @@ kprintf("RCPostRecvBuffers()...\n"); /* ** ========================================================================= -** RCProcMsgQ() +** RCProcI2OMsgQ() ** -** Process outbound message queue until empty. +** Process I2O outbound message queue until empty. ** ========================================================================= */ void -RCProcMsgQ(U16 AdapterID) +RCProcI2OMsgQ(U16 AdapterID) { U32 phyAddrMsg; PU8 p8Msg; @@ -654,35 +658,35 @@ RCProcMsgQ(U16 AdapterID) //printk(" msg: 0x%x 0x%x \n", p8Msg[7], p32[5]); - /* - ** Send Packet Reply Msg - */ - if (LAN_PACKET_SEND == p8Msg[7]) /* function code byte */ + /* + ** 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); + /* status, count, context[], adapter */ + (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID); } - /* - ** Receive Packet Reply Msg */ - else if (LAN_RECEIVE_POST == p8Msg[7]) + /* + ** Receive Packet Reply Msg */ + else if (I2O_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]); + 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); + /* 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]) + else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7]) { if (pPab->pCallbackFunc) { @@ -694,63 +698,63 @@ RCProcMsgQ(U16 AdapterID) } //PCIAdapterBlock[AdapterID] = 0; } - else if (RC_PRIVATE == p8Msg[7]) + 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 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) - { + 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 msg received: 0x%x\n", - p32[5]); - break; - } + } + break; + default: + printk("Unknown private I2O msg received: 0x%x\n", + p32[5]); + break; + } } - /* - ** Process other Msg's - */ + /* + ** Process other Msg's + */ else { - ProcessOutboundAdapterMsg(pPab, phyAddrMsg); + ProcessOutboundI2OMsg(pPab, phyAddrMsg); } - /* return MFA to outbound free Q*/ + /* return MFA to outbound free Q*/ pPab->p_atu->OutQueue = phyAddrMsg; - /* any more msgs? */ + /* any more msgs? */ phyAddrMsg = pPab->p_atu->OutQueue; } } @@ -788,23 +792,23 @@ RCGetLinkStatistics(U16 AdapterID, if (msgOffset == 0xFFFFFFFF) { - #ifdef DEBUG +#ifdef DEBUG kprintf("Get8255XStats(): Inbound Free Q empty!\n"); - #endif +#endif return RC_RTN_FREE_Q_EMPTY; } - /* calc virual address of msg - virual already mapped to physical */ + /* 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[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_LAN_STATS; + 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)); @@ -812,14 +816,14 @@ RCGetLinkStatistics(U16 AdapterID, pStats = (P_NICSTAT)p32; pStats->dump_status = 0xFFFFFFFF; - /* post to Inbound Post Q */ + /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; timeout = 100000; while (1) { if (WaitCallback) - (*WaitCallback)(); + (*WaitCallback)(); for (i = 0; i < 1000; i++) ; @@ -829,16 +833,16 @@ RCGetLinkStatistics(U16 AdapterID, if (!timeout--) { - #ifdef DEBUG +#ifdef DEBUG kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n"); - #endif +#endif return RC_RTN_MSG_REPLY_TIMEOUT; } } pReturnAddr = (PU32)StatsReturnAddr; - /* copy Nic stats to user's structure */ + /* copy Nic stats to user's structure */ for (i = 0; i < (int) sizeof(RCLINKSTATS) / 4; i++) pReturnAddr[i] = p32[i]; @@ -871,19 +875,19 @@ RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback) if (msgOffset == 0xFFFFFFFF) { - #ifdef DEBUG +#ifdef DEBUG dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n"); - #endif +#endif return RC_RTN_FREE_Q_EMPTY; } - /* calc virual address of msg - virual already mapped to physical */ + /* 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[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; @@ -892,7 +896,7 @@ RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback) p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB)); *p32 = 0xFFFFFFFF; - /* post to Inbound Post Q */ + /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; timeout = 100000; @@ -901,7 +905,7 @@ RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback) U32 i; if (WaitCallback) - (*WaitCallback)(); + (*WaitCallback)(); for (i = 0; i < 1000; i++) ; @@ -911,9 +915,9 @@ RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback) if (!timeout--) { - #ifdef DEBUG +#ifdef DEBUG kprintf("Timeout waiting for link status\n"); - #endif +#endif return RC_RTN_MSG_REPLY_TIMEOUT; } } @@ -935,76 +939,76 @@ RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback) RC_RETURN RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback) { - unsigned i, timeout; - U32 off; - PU32 p; - U32 temp[2]; - PPAB pPab; - PATU p_atu; + unsigned i, timeout; + U32 off; + PU32 p; + U32 temp[2]; + PPAB pPab; + PATU p_atu; - pPab = PCIAdapterBlock[AdapterID]; + pPab = PCIAdapterBlock[AdapterID]; - if (pPab == NULL) - return RC_RTN_ADPTR_NOT_REGISTERED; + if (pPab == NULL) + return RC_RTN_ADPTR_NOT_REGISTERED; - p_atu = pPab->p_atu; + p_atu = pPab->p_atu; - p_atu->EtherMacLow = 0; /* first zero return data */ - p_atu->EtherMacHi = 0; + p_atu->EtherMacLow = 0; /* first zero return data */ + p_atu->EtherMacHi = 0; - off = p_atu->InQueue; /* get addresss of message */ + off = p_atu->InQueue; /* get addresss of message */ - if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + if (0xFFFFFFFF == off) + return RC_RTN_FREE_Q_EMPTY; - p = (PU32)(pPab->pPci45LinBaseAddr + off); + 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); + 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; + /* 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 device */ + 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); + 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)(); + /* 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++) - ; + for (i = 0; i < 1000; i++) + ; - if (!timeout--) - { - printk("rc_getmac: Timeout\n"); - return RC_RTN_MSG_REPLY_TIMEOUT; - } - } + 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); + /* 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; + return RC_RTN_NO_ERROR; } @@ -1032,20 +1036,20 @@ RCSetMAC(U16 AdapterID, PU8 mac) off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + 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[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 device */ + pPab->p_atu->InQueue = off; /* send it to the I2O device */ return RC_RTN_NO_ERROR ; } @@ -1081,22 +1085,264 @@ RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode) off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + 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[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; +} /* ** ========================================================================= @@ -1115,73 +1361,73 @@ RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode) RC_RETURN RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback) { - U32 msgOffset, timeout; - PU32 pMsg; - volatile PU32 p32; - U8 AdapterLinkSpeed; - PPAB pPab; + U32 msgOffset, timeout; + PU32 pMsg; + volatile PU32 p32; + U8 IOPLinkSpeed; + PPAB pPab; - pPab =PCIAdapterBlock[AdapterID]; + pPab =PCIAdapterBlock[AdapterID]; - msgOffset = pPab->p_atu->InQueue; + msgOffset = pPab->p_atu->InQueue; - if (msgOffset == 0xFFFFFFFF) - { - kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n"); - return RC_RTN_FREE_Q_EMPTY; - } + 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); + /* 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; + /* 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); + /* 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 */ + /* post to Inbound Post Q */ - pPab->p_atu->InQueue = msgOffset; + pPab->p_atu->InQueue = msgOffset; - /* wait for response */ - timeout = 1000000; - while(1) - { - int i; + /* wait for response */ + timeout = 1000000; + while(1) + { + int i; - if (WaitCallback) - (*WaitCallback)(); + if (WaitCallback) + (*WaitCallback)(); - for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ - ; + for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ + ; - if (p32[0] != 0xff) - break; + 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; - } - } + 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 */ - AdapterLinkSpeed = (U8)((volatile PU8)p32)[0] & 0x0f; + /* get Link speed */ + IOPLinkSpeed = (U8)((volatile PU8)p32)[0] & 0x0f; - *pLinkSpeedCode= AdapterLinkSpeed; + *pLinkSpeedCode= IOPLinkSpeed; - return RC_RTN_NO_ERROR; + return RC_RTN_NO_ERROR; } /* @@ -1208,19 +1454,19 @@ RCReportDriverCapability(U16 AdapterID, U32 capability) off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + 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[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 device */ + pPab->p_atu->InQueue = off; /* send it to the I2O device */ return RC_RTN_NO_ERROR ; } @@ -1236,69 +1482,69 @@ RCReportDriverCapability(U16 AdapterID, U32 capability) RC_RETURN RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback) { - U32 msgOffset, timeout; - PU32 pMsg; - volatile PU32 p32; - PPAB pPab; + U32 msgOffset, timeout; + PU32 pMsg; + volatile PU32 p32; + PPAB pPab; - pPab =PCIAdapterBlock[AdapterID]; + pPab =PCIAdapterBlock[AdapterID]; - msgOffset = pPab->p_atu->InQueue; + msgOffset = pPab->p_atu->InQueue; - if (msgOffset == 0xFFFFFFFF) - { - kprintf("RCGetFirmwareVer(): Inbound Free Q empty!\n"); - return RC_RTN_FREE_Q_EMPTY; - } + 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); + /* 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; + /* 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); + /* 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 */ + /* post to Inbound Post Q */ - pPab->p_atu->InQueue = msgOffset; + pPab->p_atu->InQueue = msgOffset; - /* wait for response */ - timeout = 1000000; - while(1) - { - int i; + /* wait for response */ + timeout = 1000000; + while(1) + { + int i; - if (WaitCallback) - (*WaitCallback)(); + if (WaitCallback) + (*WaitCallback)(); - for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ - ; + for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ + ; - if (p32[0] != 0xff) - break; + 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; + 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; } /* @@ -1332,7 +1578,7 @@ RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK Ca off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + return RC_RTN_FREE_Q_EMPTY; pPab->pCallbackFunc = CallbackFunction; @@ -1340,21 +1586,21 @@ RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK Ca /* setup message */ pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0; - pMsg[1] = LAN_RESET << 24 | HOST_TID << 12 | LAN_TARGET_ID; + 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 device */ + pPab->p_atu->InQueue = off; /* send it to the I2O device */ if (CallbackFunction == (PFNCALLBACK)NULL) { - /* call RCProcMsgQ() until something in pPab->pCallbackFunc + /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc or until timer goes off */ while (pPab->pCallbackFunc == (PFNCALLBACK)NULL) { - RCProcMsgQ(AdapterID); + RCProcI2OMsgQ(AdapterID); for (i = 0; i < 100000; i++) /* please don't hog the bus!!! */ - ; + ; timeout++; if (timeout > 10000) { @@ -1362,77 +1608,77 @@ RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK Ca } } if (ReturnAddr != (PU32)NULL) - *ReturnAddr = (U32)pPab->pCallbackFunc; + *ReturnAddr = (U32)pPab->pCallbackFunc; } return RC_RTN_NO_ERROR ; } /* ** ========================================================================= -** RCResetAdapter() +** RCResetIOP() ** ** Send StatusGet Msg, wait for results return directly to buffer. ** ** ========================================================================= */ RC_RETURN -RCResetAdapter(U16 AdapterID) +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] = 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; + 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!!! */ - ; + for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ + ; - if (p32[0] || p32[1]) - break; + if (p32[0] || p32[1]) + break; - if (!timeout--) - { - printk("RCResetAdapter timeout\n"); - return RC_RTN_MSG_REPLY_TIMEOUT; - } - } - return RC_RTN_NO_ERROR; + if (!timeout--) + { + printk("RCResetIOP timeout\n"); + return RC_RTN_MSG_REPLY_TIMEOUT; + } + } + return RC_RTN_NO_ERROR; } /* @@ -1465,7 +1711,7 @@ RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + return RC_RTN_FREE_Q_EMPTY; pPab->pCallbackFunc = CallbackFunction; @@ -1473,29 +1719,30 @@ RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK /* setup message */ pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0; - pMsg[1] = LAN_SHUTDOWN << 24 | HOST_TID << 12 | LAN_TARGET_ID; + 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 device */ + pPab->p_atu->InQueue = off; /* send it to the I2O device */ if (CallbackFunction == (PFNCALLBACK)NULL) { - /* call RCProcMsgQ() until something in pPab->pCallbackFunc + /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc or until timer goes off */ while (pPab->pCallbackFunc == (PFNCALLBACK)NULL) { - RCProcMsgQ(AdapterID); + 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; + *ReturnAddr = (U32)pPab->pCallbackFunc; } return RC_RTN_NO_ERROR ; } @@ -1528,13 +1775,13 @@ RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask) off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + 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[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; @@ -1542,7 +1789,7 @@ RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask) pMsg[6] = netMask; - pPab->p_atu->InQueue = off; /* send it to the device */ + pPab->p_atu->InQueue = off; /* send it to the I2O device */ return RC_RTN_NO_ERROR ; } @@ -1557,7 +1804,7 @@ RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask) */ RC_RETURN RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, - PFNWAITCALLBACK WaitCallback) + PFNWAITCALLBACK WaitCallback) { unsigned i, timeout; U32 off; @@ -1577,8 +1824,8 @@ RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, p_atu = pPab->p_atu; off = p_atu->InQueue; /* get addresss of message */ - if (0xFFFFFFFF == off) - return RC_RTN_FREE_Q_EMPTY; + if (0xFFFFFFFF == off) + return RC_RTN_FREE_Q_EMPTY; p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB)); *p32 = 0xFFFFFFFF; @@ -1590,33 +1837,33 @@ RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, #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[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 device */ + 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 */ + /* wait for the rcpci45 board to update the info */ timeout = 100000; while (0xffffffff == *p32) { if (WaitCallback) - (*WaitCallback)(); + (*WaitCallback)(); for (i = 0; i < 1000; i++) ; if (!timeout--) { - #ifdef DEBUG +#ifdef DEBUG kprintf("RCGetRavlinIPandMask: Timeout\n"); - #endif /* DEBUG */ - return RC_RTN_MSG_REPLY_TIMEOUT; +#endif /* DEBUG */ + return RC_RTN_MSG_REPLY_TIMEOUT; } } @@ -1649,12 +1896,12 @@ RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, /* ** ========================================================================= -** SendAdapterOutboundQInitMsg() +** SendI2OOutboundQInitMsg() ** ** ========================================================================= */ static int -SendAdapterOutboundQInitMsg(PPAB pPab) +SendI2OOutboundQInitMsg(PPAB pPab) { U32 msgOffset, timeout, phyOutQFrames, i; volatile PU32 pMsg; @@ -1668,37 +1915,37 @@ SendAdapterOutboundQInitMsg(PPAB pPab) if (msgOffset == 0xFFFFFFFF) { #ifdef DEBUG - kprintf("SendAdapterOutboundQInitMsg(): Inbound Free Q empty!\n"); + 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 */ + /* 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); + 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] = RC_CMD_OUTBOUND_INIT << 24 | HOST_TID << 12 | ADAPTER_TID; + 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 */ + /* 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 */ + /* 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 */ + /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; - /* wait for response */ + /* wait for response */ timeout = 100000; while(1) { @@ -1711,9 +1958,9 @@ kprintf("SendAdapterOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08. if (!timeout--) { #ifdef DEBUG - kprintf("Timeout wait for InitOutQ InPrgress status from adapter\n"); + kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n"); #endif /* DEBUG */ - return RC_RTN_NO_STATUS; + return RC_RTN_NO_I2O_STATUS; } } @@ -1723,19 +1970,19 @@ kprintf("SendAdapterOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08. for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */ ; - if (p32[0] == RC_CMD_OUTBOUND_INIT_COMPLETE) + if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE) break; if (!timeout--) { #ifdef DEBUG - kprintf("Timeout wait for InitOutQ Complete status from adapter\n"); + kprintf("Timeout wait for InitOutQ Complete status from IOP\n"); #endif /* DEBUG */ - return RC_RTN_NO_STATUS; + return RC_RTN_NO_I2O_STATUS; } } - /* load PCI outbound free Q with MF physical addresses */ + /* load PCI outbound free Q with MF physical addresses */ phyOutQFrames = pPab->outMsgBlockPhyAddr; for (i = 0; i < NMBR_MSG_FRAMES; i++) @@ -1749,14 +1996,14 @@ kprintf("SendAdapterOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08. /* ** ========================================================================= -** GetAdapterStatus() +** GetI2OStatus() ** ** Send StatusGet Msg, wait for results return directly to buffer. ** ** ========================================================================= */ static int -GetAdapterStatus(PPAB pPab) +GetI2OStatus(PPAB pPab) { U32 msgOffset, timeout; PU32 pMsg; @@ -1764,47 +2011,49 @@ GetAdapterStatus(PPAB pPab) msgOffset = pPab->p_atu->InQueue; - printk("GetAdapterStatus: msg offset = 0x%x\n", msgOffset); +#ifdef DEBUG + printk("GetI2OStatus: msg offset = 0x%x\n", msgOffset); +#endif /* DEBUG */ if (msgOffset == 0xFFFFFFFF) { #ifdef DEBUG - kprintf("GetAdapterStatus(): Inbound Free Q empty!\n"); + 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 */ + /* 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[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 */ + /* 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 */ + /* 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]); + 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 */ + /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; #ifdef DEBUG -kprintf("Return status to p32 = 0x%08.8ulx\n", p32); + kprintf("Return status to p32 = 0x%08.8ulx\n", p32); #endif /* DEBUG */ - /* wait for response */ + /* wait for response */ timeout = 1000000; while(1) { @@ -1819,27 +2068,27 @@ kprintf("Return status to p32 = 0x%08.8ulx\n", p32); 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]); + 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_STATUS; + 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]); + 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]; + /* get IOP state */ + pPab->IOPState = ((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); + kprintf("IOP state 0x%02.2x InFrameSize = 0x%04.4x\n", + pPab->IOPState, pPab->InboundMFrameSize); #endif /* DEBUG */ return RC_RTN_NO_ERROR; } @@ -1868,20 +2117,20 @@ SendEnableSysMsg(PPAB pPab) return RC_RTN_FREE_Q_EMPTY; } - /* calc virual address of msg - virual already mapped to physical */ + /* 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); + 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[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 */ + /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; return RC_RTN_NO_ERROR; @@ -1890,7 +2139,7 @@ kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pM /* ** ========================================================================= -** FillI12OMsgFromTCB() +** FillI2OMsgFromTCB() ** ** inputs pMsgU32 - virual pointer (mapped to physical) of message frame ** pXmitCntrlBlock - pointer to caller buffer control block. @@ -1899,12 +2148,12 @@ kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pM ** ========================================================================= */ static int -FillAdapterMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock) +FillI2OMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock) { unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags; PU32 pTCB, pMsg; - /* SGL element flags */ + /* SGL element flags */ #define EOB 0x40000000 #define LE 0x80000000 #define SIMPLE_SGL 0x10000000 @@ -1915,10 +2164,10 @@ FillAdapterMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock) 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); + 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++; @@ -1948,7 +2197,7 @@ kprintf("pTCB 0x%08.8ulx, pMsg 0x%08.8ulx\n", pTCB, pMsg); flags |= LE; } - /* 1st SGL buffer element has context */ + /* 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 */ @@ -1988,30 +2237,30 @@ kprintf("pTCB 0x%08.8ulx, pMsg 0x%08.8ulx\n", pTCB, pMsg); /* ** ========================================================================= -** ProcessOutboundAdapterMsg() +** ProcessOutboundI2OMsg() ** -** process reply message +** process I2O reply message ** * change to msg structure * ** ========================================================================= */ static void -ProcessOutboundAdapterMsg(PPAB pPab, U32 phyAddrMsg) +ProcessOutboundI2OMsg(PPAB pPab, U32 phyAddrMsg) { PU8 p8Msg; PU32 p32; - // U16 count; + // 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]); + 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 != RC_REPLY_STATUS_SUCCESS) + if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS) { #ifdef DEBUG kprintf("Message reply status not success\n"); @@ -2021,38 +2270,38 @@ ProcessOutboundAdapterMsg(PPAB pPab, U32 phyAddrMsg) switch (p8Msg[7] ) /* function code byte */ { - case RC_CMD_SYS_TAB_SET: - msgFlag = 1; + case I2O_EXEC_SYS_TAB_SET: + msgFlag = 1; #ifdef DEBUG - kprintf("Received RC_CMD_SYS_TAB_SET reply\n"); + kprintf("Received I2O_EXEC_SYS_TAB_SET reply\n"); #endif /* DEBUG */ - break; + break; - case RC_CMD_HRT_GET: - msgFlag = 1; + case I2O_EXEC_HRT_GET: + msgFlag = 1; #ifdef DEBUG - kprintf("Received RC_CMD_HRT_GET reply\n"); + kprintf("Received I2O_EXEC_HRT_GET reply\n"); #endif /* DEBUG */ - break; + break; - case RC_CMD_LCT_NOTIFY: - msgFlag = 1; + case I2O_EXEC_LCT_NOTIFY: + msgFlag = 1; #ifdef DEBUG - kprintf("Received RC_CMD_LCT_NOTIFY reply\n"); + kprintf("Received I2O_EXEC_LCT_NOTIFY reply\n"); #endif /* DEBUG */ - break; + break; - case RC_CMD_SYS_ENABLE: - msgFlag = 1; + case I2O_EXEC_SYS_ENABLE: + msgFlag = 1; #ifdef DEBUG - kprintf("Received RC_CMD_SYS_ENABLE reply\n"); + kprintf("Received I2O_EXEC_SYS_ENABLE reply\n"); #endif /* DEBUG */ - break; + break; - default: + default: #ifdef DEBUG kprintf("Received UNKNOWN reply\n"); #endif /* DEBUG */ - break; + break; } } diff --git a/drivers/net/rcmtl.h b/drivers/net/rclanmtl.h similarity index 78% rename from drivers/net/rcmtl.h rename to drivers/net/rclanmtl.h index cfd14e0fa888..2521b1ceecf3 100644 --- a/drivers/net/rcmtl.h +++ b/drivers/net/rclanmtl.h @@ -2,19 +2,20 @@ ** ************************************************************************* ** ** -** R C M T L . H $Revision: 3 $ +** R C L A N M T L . H $Revision: 5 $ ** ** -** RedCreek Message Transport Layer header file. +** RedCreek I2O LAN Message Transport Layer header file. ** ** --------------------------------------------------------------------- -** --- Copyright (c) 1997-1998, RedCreek Communications Inc. --- +** --- Copyright (c) 1997-1999, RedCreek Communications Inc. --- ** --- All rights reserved. --- ** --------------------------------------------------------------------- ** ** File Description: ** -** Header file for host message transport layer API and data types. +** 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 @@ -33,8 +34,8 @@ ** ************************************************************************* */ -#ifndef RCMTL_H -#define RCMTL_H +#ifndef RCLANMTL_H +#define RCLANMTL_H /* Linux specific includes */ #define kprintf printk @@ -51,7 +52,7 @@ /* RedCreek API function return values */ #define RC_RTN_NO_ERROR 0 -#define RC_RTN_NOT_INIT 1 +#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 @@ -59,7 +60,7 @@ #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_I2O_STATUS 9 #define RC_RTN_NO_FIRM_VER 10 #define RC_RTN_NO_LINK_SPEED 11 @@ -88,10 +89,10 @@ typedef void (*PFNWAITCALLBACK)(void); /* void argument avoids compiler complai ** 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 + ** 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 RCSendPacket() function. PcktCount + ** 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. @@ -105,7 +106,7 @@ typedef void (*PFNTXCALLBACK)(U32 Status, ** type PFNRXCALLBACK ** ** Pointer to user's receive callback function. This user function - ** is called from RCProcMsgQ() when packets have been received into + ** 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. @@ -144,29 +145,29 @@ typedef void (*PFNCALLBACK)(U32 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 +#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 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 +#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 /* @@ -211,7 +212,7 @@ typedef void (*PFNCALLBACK)(U32 Status, ** 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 +** 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. @@ -282,17 +283,17 @@ typedef struct typedef PU32 PRCTCB; /* ** ------------------------------------------------------------------------- -** Exported functions comprising the API to the message transport layer +** Exported functions comprising the API to the LAN I2O message transport layer ** ------------------------------------------------------------------------- */ /* - ** InitRCApiMsgLayer() + ** InitRCI2OMsgLayer() ** - ** Called once prior to using the API message transport layer. User + ** 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 API message + ** 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 @@ -309,7 +310,7 @@ typedef PU32 PRCTCB; ** ReceiveCallbackFunction - address of user's RX callback function ** */ -RC_RETURN InitRCApiMsgLayer(U16 AdapterID, U32 pciBaseAddr, +RC_RETURN RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr, PU8 p_msgbuf, PU8 p_phymsgbuf, PFNTXCALLBACK TransmitCallbackFunction, PFNRXCALLBACK ReceiveCallbackFunction, @@ -341,7 +342,7 @@ RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, PFNWAITCALLBACK WaitCallback); /* - ** RCProcMsgQ() + ** RCProcI2OMsgQ() ** ** Called from user's polling loop or Interrupt Service Routine for a PCI ** interrupt from the RedCreek PCI adapter. User responsible for determining @@ -349,19 +350,19 @@ RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask, ** callback functions, TransmitCallbackFunction or ReceiveCallbackFunction, ** if a TX or RX transaction has completed. */ -void RCProcMsgQ(U16 AdapterID); +void RCProcI2OMsgQ(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. + ** 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 RCSendPacket() functions. Disabling Adapter interrupts - ** will prevent hardware interrupt to host even though the outbound msg + ** 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 RCEnableAdapterInterrupts(U16 adapterID); -RC_RETURN RCDisableAdapterInterrupts(U16 AdapterID); +RC_RETURN RCEnableI2OInterrupts(U16 adapterID); +RC_RETURN RCDisableI2OInterrupts(U16 AdapterID); /* @@ -380,7 +381,7 @@ RC_RETURN RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransactionCtrlBlock); #define MAX_NMBR_POST_BUFFERS_PER_MSG 32 /* - ** RCSendPacket() + ** RCI2OSendPacket() ** ** Send user's ethernet packet from a locked page buffer. ** Packet must have full MAC header, however without a CRC. @@ -389,7 +390,7 @@ RC_RETURN RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransactionCtrlBlock); ** Transmit buffer are considered owned by the adapter until context's ** returned to user through the TransmitCallbackFunction. */ -RC_RETURN RCSendPacket(U16 AdapterID, +RC_RETURN RCI2OSendPacket(U16 AdapterID, U32 context, PRCTCB pTransactionCtrlBlock); @@ -439,8 +440,8 @@ RC_RETURN RCGetLinkStatus(U16 AdapterID, PFNWAITCALLBACK WaitCallback); /* Link Status defines - value returned in pReturnStatus */ -#define LAN_LINK_STATUS_DOWN 0 -#define LAN_LINK_STATUS_UP 1 +#define RC_LAN_LINK_STATUS_DOWN 0 +#define RC_LAN_LINK_STATUS_UP 1 /* ** RCGetMAC() @@ -491,7 +492,63 @@ RC_RETURN RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode); 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) @@ -529,13 +586,13 @@ RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback); ** 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 + ** 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 adapter interrupts during this method). + ** 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. @@ -552,13 +609,13 @@ RC_RETURN RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNC ** 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 + ** 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 adapter interrupts during this method). + ** 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. @@ -568,13 +625,13 @@ RC_RETURN RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction); /* - ** RCResetAdapter(); - ** Initializes ADAPTERState to ADAPTER_STATE_RESET. + ** 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 -RCResetAdapter(U16 AdapterID); +RCResetIOP(U16 AdapterID); -#endif /* RCMTL_H */ +#endif /* RCLANMTL_H */ diff --git a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c index f53e024f0a06..2c5a070eef8e 100644 --- a/drivers/net/rcpci45.c +++ b/drivers/net/rcpci45.c @@ -4,7 +4,7 @@ ** ** ** --------------------------------------------------------------------- -** --- Copyright (c) 1998, RedCreek Communications Inc. --- +** --- Copyright (c) 1998, 1999, RedCreek Communications Inc. --- ** --- All rights reserved. --- ** --------------------------------------------------------------------- ** @@ -12,14 +12,13 @@ ** ** 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 @@ -35,15 +34,20 @@ ** 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 #include #include #include @@ -62,25 +66,34 @@ static char *version = #include #include +#if LINUX_VERSION_CODE >= 0x020100 +#define LINUX_2_1 +#endif + +#ifdef LINUX_2_1 +#include +#endif + #include #include #include #include + #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 +#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; icontext = (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 */ } diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index aac5b8cdc0c1..6b022cfb6cbb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -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"), diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index 642be224ddb2..e5b815c87819 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -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 diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index b6832ddbf0aa..6ce37b050f8c 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -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 diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 0c2f33d0e762..2435f10ae5cc 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -153,6 +153,10 @@ #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 diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index c375e0a3f1b1..6802dcc88b2d 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -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 + * * 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. @@ -35,28 +38,33 @@ * 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 + * 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 + * + * Merged with 2.1.131 source tree. + * 12 Dec 98 K. Baranowski + * + * 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 #include @@ -66,10 +74,8 @@ #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; idxmax_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; idxmax_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; idxcompleted[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; idxSCpnt->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; inumldrv; 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; iPhysdrvInfo.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; idxmax_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; idxmax_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); } diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 544240732533..f9449c32876d 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -1,6 +1,10 @@ #ifndef __MEGARAID_H__ #define __MEGARAID_H__ +#ifndef LINUX_VERSION_CODE +#include +#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 \ @@ -111,14 +117,14 @@ 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 \ {\ @@ -132,10 +138,10 @@ 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 */\ @@ -143,140 +149,150 @@ #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 index 000000000000..a750550d80a1 --- /dev/null +++ b/drivers/scsi/sym53c416.c @@ -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=[,] + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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=[,]\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 index 000000000000..49abc83cac7a --- /dev/null +++ b/drivers/scsi/sym53c416.h @@ -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 +#endif + +#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s)) + +#include +#include + +#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 index 000000000000..b42573cd05fa --- /dev/null +++ b/drivers/sound/.defines @@ -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 + diff --git a/drivers/sound/Config.in b/drivers/sound/Config.in index b1bc3607904b..b160c29e591e 100644 --- a/drivers/sound/Config.in +++ b/drivers/sound/Config.in @@ -1,15 +1,251 @@ -# -# 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 index 000000000000..bdf1703b8d2b --- /dev/null +++ b/drivers/sound/local.h @@ -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" diff --git a/fs/Config.in b/fs/Config.in index 5ed7d535d6a1..7273edf81238 100644 --- a/fs/Config.in +++ b/fs/Config.in @@ -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 diff --git a/fs/Makefile b/fs/Makefile index 13897ec1eef6..df8d0347c504 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -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 diff --git a/fs/ioctl.c b/fs/ioctl.c index e746056e404b..e71978a8adc8 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -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, ¤t->files->close_on_exec); - return 0; + break; case FIONCLEX: FD_CLR(fd, ¤t->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; } diff --git a/fs/nls.c b/fs/nls.c index 74af3d021fa6..d8c85836c13a 100644 --- 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 index 000000000000..33478bf9b1de --- /dev/null +++ b/fs/nls_iso8859-15.c @@ -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 +#include +#include +#include + +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: + */ diff --git a/include/asm-alpha/ioctls.h b/include/asm-alpha/ioctls.h index bb4f71de877e..0337b92b3db7 100644 --- a/include/asm-alpha/ioctls.h +++ b/include/asm-alpha/ioctls.h @@ -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 diff --git a/include/linux/cyclades.h b/include/linux/cyclades.h index 5620b5c40a22..37e2cf0eae89 100644 --- a/include/linux/cyclades.h +++ b/include/linux/cyclades.h @@ -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) diff --git a/include/linux/pci.h b/include/linux/pci.h index b922e0d609db..fe6f35fc303a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -119,8 +119,8 @@ /* 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, @@ -304,6 +304,8 @@ #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 @@ -478,6 +480,7 @@ #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 diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 7b1260a198a9..2a9bdcc7d806 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -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, diff --git a/init/main.c b/init/main.c index 322d75cb3d8f..cc0e7da7b316 100644 --- a/init/main.c +++ b/init/main.c @@ -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 } }; diff --git a/scripts/Menuconfig b/scripts/Menuconfig index 48e93c8e8c03..789b9130d7ae 100644 --- a/scripts/Menuconfig +++ b/scripts/Menuconfig @@ -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' diff --git a/scripts/tkgen.c b/scripts/tkgen.c index fc9338db39de..63ca8709e933 100644 --- a/scripts/tkgen.c +++ b/scripts/tkgen.c @@ -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 diff --git a/scripts/tkparse.c b/scripts/tkparse.c index 2a000217c98e..73b62f589716 100644 --- a/scripts/tkparse.c +++ b/scripts/tkparse.c @@ -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; diff --git a/scripts/tkparse.h b/scripts/tkparse.h index 911abdfbee43..61209e02abf8 100644 --- a/scripts/tkparse.h +++ b/scripts/tkparse.h @@ -14,6 +14,7 @@ enum token { tok_hex, tok_make, tok_define, + tok_define_int, tok_choose, tok_choice, tok_endmenu, -- 2.39.5