diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-27 23:54:12 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-27 23:54:12 +0000 |
commit | d3e71cb08747743fce908122bab08b479eb403a5 (patch) | |
tree | cbec6948fdbdee9af81cf3ecfb504070d2745d7b /drivers/char/applicom.c | |
parent | fe7ff1706e323d0e5ed83972960a1ecc1ee538b3 (diff) |
Merge with Linux 2.3.99-pre3.
Diffstat (limited to 'drivers/char/applicom.c')
-rw-r--r-- | drivers/char/applicom.c | 1167 |
1 files changed, 559 insertions, 608 deletions
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c index f6304943a..65be2102f 100644 --- a/drivers/char/applicom.c +++ b/drivers/char/applicom.c @@ -14,7 +14,7 @@ /* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */ /* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */ /* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */ -/* adresses de base des cartes, IOCTL 6 plus complet */ +/* adresses de base des cartes, IOCTL 6 plus complet */ /* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */ /* de code autre que le texte V2.6.1 en V2.8.0 */ /*****************************************************************************/ @@ -37,108 +37,102 @@ #undef DEBUG #define DEVPRIO PZERO+8 #define FALSE 0 -#define TRUE ~FALSE -#define MAX_BOARD 8 /* maximum of pc board possible */ +#define TRUE ~FALSE +#define MAX_BOARD 8 /* maximum of pc board possible */ #define MAX_ISA_BOARD 4 #define LEN_RAM_IO 0x800 #define AC_MINOR 157 #ifndef PCI_VENDOR_ID_APPLICOM -#define PCI_VENDOR_ID_APPLICOM 0x1389 +#define PCI_VENDOR_ID_APPLICOM 0x1389 #define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001 #define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002 #define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003 #define MAX_PCI_DEVICE_NUM 3 #endif -static char *applicom_pci_devnames[]={ - "PCI board", "PCI2000IBS / PCI2000CAN", "PCI2000PFB"}; +static char *applicom_pci_devnames[] = { + "PCI board", "PCI2000IBS / PCI2000CAN", "PCI2000PFB" +}; MODULE_AUTHOR("David Woodhouse & Applicom International"); MODULE_DESCRIPTION("Driver for Applicom Profibus card"); MODULE_PARM(irq, "i"); MODULE_PARM_DESC(irq, "IRQ of the Applicom board"); -MODULE_PARM(mem,"i"); +MODULE_PARM(mem, "i"); MODULE_PARM_DESC(mem, "Shared Memory Address of Applicom board"); MODULE_SUPPORTED_DEVICE("ac"); struct applicom_board { - unsigned long PhysIO; - unsigned long RamIO; + unsigned long PhysIO; + unsigned long RamIO; #if LINUX_VERSION_CODE > 0x20300 - wait_queue_head_t FlagSleepSend; + wait_queue_head_t FlagSleepSend; #else - struct wait_queue *FlagSleepSend; + struct wait_queue *FlagSleepSend; #endif - long irq; + long irq; } apbs[MAX_BOARD]; -static unsigned int irq=0; /* interrupt number IRQ */ -static unsigned long mem=0; /* physical segment of board */ +static unsigned int irq = 0; /* interrupt number IRQ */ +static unsigned long mem = 0; /* physical segment of board */ -static unsigned int numboards; /* number of installed boards */ +static unsigned int numboards; /* number of installed boards */ static volatile unsigned char Dummy; #if LINUX_VERSION_CODE > 0x20300 -static DECLARE_WAIT_QUEUE_HEAD (FlagSleepRec); +static DECLARE_WAIT_QUEUE_HEAD(FlagSleepRec); #else static struct wait_queue *FlagSleepRec; #endif -static unsigned int WriteErrorCount; /* number of write error */ -static unsigned int ReadErrorCount; /* number of read error */ -static unsigned int DeviceErrorCount; /* number of device error */ +static unsigned int WriteErrorCount; /* number of write error */ +static unsigned int ReadErrorCount; /* number of read error */ +static unsigned int DeviceErrorCount; /* number of device error */ static loff_t ac_llseek(struct file *file, loff_t offset, int origin); static int ac_open(struct inode *inode, struct file *filp); -static ssize_t ac_read (struct file *filp, char *buf, size_t count, loff_t *ptr); -static ssize_t ac_write (struct file *file, const char *buf, size_t count, loff_t *ppos); +static ssize_t ac_read(struct file *filp, char *buf, size_t count, loff_t * ptr); +static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos); static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); static int ac_release(struct inode *inode, struct file *file); static void ac_interrupt(int irq, void *dev_instance, struct pt_regs *regs); -struct file_operations ac_fops={ - llseek: ac_llseek, - read: ac_read, - write: ac_write, - ioctl: ac_ioctl, - open: ac_open, - release: ac_release, +struct file_operations ac_fops = { + llseek:ac_llseek, + read:ac_read, + write:ac_write, + ioctl:ac_ioctl, + open:ac_open, + release:ac_release, }; -struct miscdevice ac_miscdev={ - AC_MINOR, - "ac", - &ac_fops +struct miscdevice ac_miscdev = { + AC_MINOR, + "ac", + &ac_fops }; -int ac_register_board(unsigned long physloc, unsigned long loc, - unsigned char boardno) +int ac_register_board(unsigned long physloc, unsigned long loc, unsigned char boardno) { volatile unsigned char byte_reset_it; - if((readb(loc + CONF_END_TEST) != 0x00) || - (readb(loc + CONF_END_TEST + 1) != 0x55) || - (readb(loc + CONF_END_TEST + 2) != 0xAA) || - (readb(loc + CONF_END_TEST + 3) != 0xFF)) - return 0; + if ((readb(loc + CONF_END_TEST) != 0x00) || (readb(loc + CONF_END_TEST + 1) != 0x55) || (readb(loc + CONF_END_TEST + 2) != 0xAA) || (readb(loc + CONF_END_TEST + 3) != 0xFF)) + return 0; if (!boardno) - boardno = readb(loc + NUMCARD_OWNER_TO_PC); + boardno = readb(loc + NUMCARD_OWNER_TO_PC); - if (!boardno && boardno > MAX_BOARD) - { - printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n",boardno, physloc, MAX_BOARD); - return 0; - } + if (!boardno && boardno > MAX_BOARD) { + printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n", boardno, physloc, MAX_BOARD); + return 0; + } - if (apbs[boardno-1].RamIO) - { - printk(KERN_WARNING "Board #%d (at 0x%lx) conflicts with previous board #%d (at 0x%lx)\n", - boardno, physloc, boardno, apbs[boardno-1].PhysIO); - return 0; - } + if (apbs[boardno - 1].RamIO) { + printk(KERN_WARNING "Board #%d (at 0x%lx) conflicts with previous board #%d (at 0x%lx)\n", boardno, physloc, boardno, apbs[boardno - 1].PhysIO); + return 0; + } boardno--; @@ -152,7 +146,7 @@ int ac_register_board(unsigned long physloc, unsigned long loc, byte_reset_it = readb(loc + RAM_IT_TO_PC); numboards++; - return boardno+1; + return boardno + 1; } #ifdef MODULE @@ -164,22 +158,21 @@ void cleanup_module(void) int i; misc_deregister(&ac_miscdev); - for (i=0; i< MAX_BOARD; i++) - { - if (!apbs[i].RamIO) - continue; - iounmap((void *)apbs[i].RamIO); - if (apbs[i].irq) - free_irq(apbs[i].irq,&ac_open); - } - // printk("Removing Applicom module\n"); + for (i = 0; i < MAX_BOARD; i++) { + if (!apbs[i].RamIO) + continue; + iounmap((void *) apbs[i].RamIO); + if (apbs[i].irq) + free_irq(apbs[i].irq, &ac_open); + } + // printk("Removing Applicom module\n"); } -#endif /* MODULE */ +#endif /* MODULE */ int __init applicom_init(void) { - int i, numisa=0; + int i, numisa = 0; struct pci_dev *dev = NULL; void *RamIO; int boardno; @@ -190,157 +183,137 @@ int __init applicom_init(void) #endif printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.16 1999/08/28 15:11:50 dwmw2 Exp $\n"); - + /* No mem and irq given - check for a PCI card */ - - while ( (dev = pci_find_device(PCI_VENDOR_ID_APPLICOM, 1, dev))) - { - // mem = dev->base_address[0]; - // irq = dev->irq; - - RamIO = ioremap(PCI_BASE_ADDRESS(dev), LEN_RAM_IO); - - if (!RamIO) { - printk(KERN_INFO "ac.o: Failed to ioremap PCI memory space at 0x%lx\n", PCI_BASE_ADDRESS(dev)); - return -EIO; - } - - printk(KERN_INFO "Applicom %s found at mem 0x%lx, irq %d\n", - applicom_pci_devnames[dev->device-1], PCI_BASE_ADDRESS(dev), - dev->irq); - - if (!(boardno = ac_register_board(PCI_BASE_ADDRESS(dev), - (unsigned long)RamIO,0))) - { - printk(KERN_INFO "ac.o: PCI Applicom device doesn't have correct signature.\n"); - iounmap(RamIO); - continue; - } - - if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &ac_open)) - { - printk(KERN_INFO "Could not allocate IRQ %d for PCI Applicom device.\n", dev->irq); - iounmap(RamIO); - apbs[boardno-1].RamIO = 0; - continue; - } - - /* Enable interrupts. */ - - writeb(0x40, apbs[boardno-1].RamIO + RAM_IT_FROM_PC); - - apbs[boardno-1].irq = dev->irq; - } - + + while ((dev = pci_find_device(PCI_VENDOR_ID_APPLICOM, 1, dev))) { + // mem = dev->base_address[0]; + // irq = dev->irq; + + RamIO = ioremap(PCI_BASE_ADDRESS(dev), LEN_RAM_IO); + + if (!RamIO) { + printk(KERN_INFO "ac.o: Failed to ioremap PCI memory space at 0x%lx\n", PCI_BASE_ADDRESS(dev)); + return -EIO; + } + + printk(KERN_INFO "Applicom %s found at mem 0x%lx, irq %d\n", applicom_pci_devnames[dev->device - 1], PCI_BASE_ADDRESS(dev), dev->irq); + + if (!(boardno = ac_register_board(PCI_BASE_ADDRESS(dev), (unsigned long) RamIO, 0))) { + printk(KERN_INFO "ac.o: PCI Applicom device doesn't have correct signature.\n"); + iounmap(RamIO); + continue; + } + + if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &ac_open)) { + printk(KERN_INFO "Could not allocate IRQ %d for PCI Applicom device.\n", dev->irq); + iounmap(RamIO); + apbs[boardno - 1].RamIO = 0; + continue; + } + + /* Enable interrupts. */ + + writeb(0x40, apbs[boardno - 1].RamIO + RAM_IT_FROM_PC); + + apbs[boardno - 1].irq = dev->irq; + } + /* Finished with PCI cards. If none registered, * and there was no mem/irq specified, exit */ - if (!mem || !irq) - { - if (numboards) - goto fin; - else - { - printk(KERN_INFO "ac.o: No PCI boards found.\n"); - printk(KERN_INFO "ac.o: For an ISA board you must supply memory and irq parameters.\n"); - return -ENXIO; - } - } - + if (!mem || !irq) { + if (numboards) + goto fin; + else { + printk(KERN_INFO "ac.o: No PCI boards found.\n"); + printk(KERN_INFO "ac.o: For an ISA board you must supply memory and irq parameters.\n"); + return -ENXIO; + } + } + /* Now try the specified ISA cards */ - RamIO = ioremap(mem, LEN_RAM_IO * MAX_ISA_BOARD); + RamIO = ioremap(mem, LEN_RAM_IO * MAX_ISA_BOARD); if (!RamIO) { - printk(KERN_INFO "ac.o: Failed to ioremap ISA memory space at 0x%lx\n",mem); + printk(KERN_INFO "ac.o: Failed to ioremap ISA memory space at 0x%lx\n", mem); + } + + for (i = 0; i < MAX_ISA_BOARD; i++) { + RamIO = ioremap(mem + (LEN_RAM_IO * i), LEN_RAM_IO); + + if (!RamIO) { + printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n", i + 1); + continue; + } + + if (!(boardno = ac_register_board((unsigned long) mem + (LEN_RAM_IO * i), (unsigned long) RamIO, i + 1))) { + iounmap(RamIO); + continue; + } + + printk("Applicom ISA card found at mem 0x%lx, irq %d\n", mem + (LEN_RAM_IO * i), irq); + + if (!numisa) { + if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &ac_open)) { + printk("Could not allocate IRQ %d for ISA Applicom device.\n", irq); + iounmap((void *) RamIO); + apbs[boardno - 1].RamIO = 0; + } + apbs[boardno - 1].irq = irq; + } else + apbs[boardno - 1].irq = 0; + + numisa++; } - - for (i=0; i< MAX_ISA_BOARD; i++) - { - RamIO = ioremap(mem+ (LEN_RAM_IO*i), LEN_RAM_IO); - - if (!RamIO) { - printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n",i+1); - continue; - } - - if (!(boardno = ac_register_board((unsigned long)mem+ (LEN_RAM_IO*i), - (unsigned long)RamIO,i+1))) { - iounmap(RamIO); - continue; - } - - printk("Applicom ISA card found at mem 0x%lx, irq %d\n", mem + (LEN_RAM_IO*i), irq); - - if (!numisa) - { - if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &ac_open)) - { - printk("Could not allocate IRQ %d for ISA Applicom device.\n", irq); - iounmap((void *)RamIO); - apbs[boardno-1].RamIO = 0; - } - apbs[boardno-1].irq=irq; - } - else - apbs[boardno-1].irq=0; - - numisa++; - } if (!numisa) - printk("ac.o: No valid ISA Applicom boards found at mem 0x%lx\n",mem); + printk("ac.o: No valid ISA Applicom boards found at mem 0x%lx\n", mem); #if LINUX_VERSION_CODE > 0x20300 init_waitqueue_head(&FlagSleepRec); #else - FlagSleepRec = NULL; + FlagSleepRec = NULL; #endif - WriteErrorCount = 0; - ReadErrorCount = 0; + WriteErrorCount = 0; + ReadErrorCount = 0; DeviceErrorCount = 0; -fin: - if (numboards) - { - misc_register (&ac_miscdev); - for (i=0; i<MAX_BOARD; i++) - { - int serial; - char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1]; + fin: + if (numboards) { + misc_register(&ac_miscdev); + for (i = 0; i < MAX_BOARD; i++) { + int serial; + char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1]; - if (!apbs[i].RamIO) - continue; - - for(serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++) - boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial); - boardname[serial]=0; - + if (!apbs[i].RamIO) + continue; - printk("Applicom board %d: %s, PROM V%d.%d", - i+1, boardname, - (int)(readb(apbs[i].RamIO + VERS) >> 4), - (int)(readb(apbs[i].RamIO + VERS) & 0xF)); + for (serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++) + boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial); + boardname[serial] = 0; + + + printk(KERN_INFO "Applicom board %d: %s, PROM V%d.%d", i + 1, boardname, (int) (readb(apbs[i].RamIO + VERS) >> 4), (int) (readb(apbs[i].RamIO + VERS) & 0xF)); + + serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) + (readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) + (readb(apbs[i].RamIO + SERIAL_NUMBER + 2)); + + if (serial != 0) + printk(" S/N %d\n", serial); + else + printk("\n"); + } + return 0; + } - serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) + - (readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) + - (readb(apbs[i].RamIO + SERIAL_NUMBER + 2) ); - - if (serial != 0) - printk (" S/N %d\n", serial); - else - printk("\n"); - } - return 0; - } - else - return -ENXIO; + return -ENXIO; } #ifndef MODULE -__initcall (applicom_init); +__initcall(applicom_init); #endif static loff_t ac_llseek(struct file *file, loff_t offset, int origin) @@ -361,477 +334,455 @@ static int ac_release(struct inode *inode, struct file *file) } -static ssize_t ac_write (struct file *file, const char *buf, size_t count, loff_t *ppos) +static ssize_t ac_write(struct file *file, const char *buf, size_t count, loff_t * ppos) { - unsigned int NumCard; /* Board number 1 -> 8 */ - unsigned int IndexCard; /* Index board number 0 -> 7 */ - unsigned char TicCard; /* Board TIC to send */ - unsigned long flags; /* Current priority */ - struct st_ram_io st_loc; - struct mailbox tmpmailbox; - - if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) { - printk("Hmmm. write() of Applicom card, length %d != expected %d\n",count,sizeof(struct st_ram_io) + sizeof(struct mailbox)); - return -EINVAL; - } - - if(copy_from_user (&st_loc, buf, sizeof(struct st_ram_io))) { - return -EFAULT; - } - if(copy_from_user (&tmpmailbox, &buf[sizeof(struct st_ram_io)], sizeof(struct mailbox))) { - return -EFAULT; - } - - NumCard = st_loc.num_card; /* board number to send */ - TicCard = st_loc.tic_des_from_pc; /* tic number to send */ - IndexCard = NumCard -1; - if((NumCard < 1) || (NumCard > MAX_BOARD) || !apbs[IndexCard].RamIO) - { /* User board number not OK */ - // printk("Write to invalid Applicom board %d\n", NumCard); - return -EINVAL; /* Return error code user buffer */ - } - + unsigned int NumCard; /* Board number 1 -> 8 */ + unsigned int IndexCard; /* Index board number 0 -> 7 */ + unsigned char TicCard; /* Board TIC to send */ + unsigned long flags; /* Current priority */ + struct st_ram_io st_loc; + struct mailbox tmpmailbox; + + if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) { + printk("Hmmm. write() of Applicom card, length %d != expected %d\n", count, sizeof(struct st_ram_io) + sizeof(struct mailbox)); + return -EINVAL; + } + + if (copy_from_user(&st_loc, buf, sizeof(struct st_ram_io))) { + return -EFAULT; + } + if (copy_from_user(&tmpmailbox, &buf[sizeof(struct st_ram_io)], sizeof(struct mailbox))) { + return -EFAULT; + } + + NumCard = st_loc.num_card; /* board number to send */ + TicCard = st_loc.tic_des_from_pc; /* tic number to send */ + IndexCard = NumCard - 1; + if ((NumCard < 1) || (NumCard > MAX_BOARD) || !apbs[IndexCard].RamIO) { /* User board number not OK */ + // printk("Write to invalid Applicom board %d\n", NumCard); + return -EINVAL; /* Return error code user buffer */ + } #ifdef DEBUG - { - int c; - - printk("Write to applicom card #%d. struct st_ram_io follows:",NumCard); - - - - for (c=0; c< sizeof(struct st_ram_io);) - { - printk("\n%5.5X: %2.2X",c,((unsigned char *)&st_loc)[c]); - - for (c++ ; c%8 && c<sizeof(struct st_ram_io); c++) - { - printk(" %2.2X",((unsigned char *)&st_loc)[c]); - } - } + { + int c; + + printk("Write to applicom card #%d. struct st_ram_io follows:", NumCard); + + + + for (c = 0; c < sizeof(struct st_ram_io);) { + printk("\n%5.5X: %2.2X", c, ((unsigned char *) &st_loc)[c]); + + for (c++; c % 8 && c < sizeof(struct st_ram_io); c++) { + printk(" %2.2X", ((unsigned char *) &st_loc)[c]); + } + } + + printk("\nstruct mailbox follows:"); + + for (c = 0; c < sizeof(struct mailbox);) { + printk("\n%5.5X: %2.2X", c, ((unsigned char *) &tmpmailbox)[c]); + + for (c++; c % 8 && c < sizeof(struct mailbox); c++) { + printk(" %2.2X", ((unsigned char *) &tmpmailbox)[c]); + } + } + + printk("\n"); + } - printk("\nstruct mailbox follows:"); - - for (c=0; c< sizeof(struct mailbox);) - { - printk("\n%5.5X: %2.2X",c,((unsigned char *)&tmpmailbox)[c]); - - for (c++ ; c%8 && c<sizeof(struct mailbox); c++) - { - printk(" %2.2X",((unsigned char *)&tmpmailbox)[c]); - } - } - - printk("\n"); - } - #endif - save_flags (flags); - cli(); /* disable interrupt */ - - if(readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) > 2) /* Test octet ready correct */ - { - Dummy = readb(apbs[IndexCard].RamIO + VERS); - restore_flags(flags); - printk("APPLICOM driver write error board %d, DataFromPcReady = %d\n", - IndexCard,(int)readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY)); - DeviceErrorCount++; - return -EIO; - } - while (readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) != 0) - { - Dummy = readb(apbs[IndexCard].RamIO + VERS); - restore_flags(flags); - interruptible_sleep_on (&apbs[IndexCard].FlagSleepSend); - if (signal_pending(current)) - return -EINTR; - save_flags(flags); - cli(); - } - writeb(1, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); - - // memcpy_toio ((void *)apbs[IndexCard].PtrRamFromPc, (void *)&tmpmailbox, sizeof(struct mailbox)); - { - unsigned char *from = (unsigned char *)&tmpmailbox; - unsigned long to = (unsigned long)apbs[IndexCard].RamIO + RAM_FROM_PC; - int c; - - for (c=0; c<sizeof(struct mailbox) ; c++) - writeb(*(from++), to++); - } - writeb(0x20, apbs[IndexCard].RamIO + TIC_OWNER_FROM_PC); - writeb(0xff, apbs[IndexCard].RamIO + NUMCARD_OWNER_FROM_PC); - writeb(TicCard, apbs[IndexCard].RamIO + TIC_DES_FROM_PC); - writeb(NumCard, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC); - writeb(2, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); - writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); - Dummy = readb(apbs[IndexCard].RamIO + VERS); - restore_flags (flags); - return 0; + save_flags(flags); + cli(); /* disable interrupt */ + + if (readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) > 2) { /* Test octet ready correct */ + Dummy = readb(apbs[IndexCard].RamIO + VERS); + restore_flags(flags); + printk("APPLICOM driver write error board %d, DataFromPcReady = %d\n", IndexCard, (int) readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY)); + DeviceErrorCount++; + return -EIO; + } + while (readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) != 0) { + Dummy = readb(apbs[IndexCard].RamIO + VERS); + restore_flags(flags); + /* + * FIXME: Race on wakeup. Race on re-entering write + * in another thread. + */ + interruptible_sleep_on(&apbs[IndexCard].FlagSleepSend); + if (signal_pending(current)) + return -EINTR; + save_flags(flags); + cli(); + } + writeb(1, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); + + // memcpy_toio ((void *)apbs[IndexCard].PtrRamFromPc, (void *)&tmpmailbox, sizeof(struct mailbox)); + { + unsigned char *from = (unsigned char *) &tmpmailbox; + unsigned long to = (unsigned long) apbs[IndexCard].RamIO + RAM_FROM_PC; + int c; + + for (c = 0; c < sizeof(struct mailbox); c++) + writeb(*(from++), to++); + } + writeb(0x20, apbs[IndexCard].RamIO + TIC_OWNER_FROM_PC); + writeb(0xff, apbs[IndexCard].RamIO + NUMCARD_OWNER_FROM_PC); + writeb(TicCard, apbs[IndexCard].RamIO + TIC_DES_FROM_PC); + writeb(NumCard, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC); + writeb(2, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); + writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); + Dummy = readb(apbs[IndexCard].RamIO + VERS); + restore_flags(flags); + return 0; } -static ssize_t ac_read (struct file *filp, char *buf, size_t count, loff_t *ptr) +static ssize_t ac_read(struct file *filp, char *buf, size_t count, loff_t * ptr) { - unsigned int NumCard; /* board number 1 -> 8 */ - unsigned int IndexCard; /* index board number 0 -> 7 */ - unsigned long flags; - unsigned int i; - unsigned char tmp=0; - struct st_ram_io st_loc; - struct mailbox tmpmailbox; /* bounce buffer - can't copy to user space with cli() */ - - - if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) { - printk("Hmmm. read() of Applicom card, length %d != expected %d\n",count,sizeof(struct st_ram_io) + sizeof(struct mailbox)); - return -EINVAL; - } - - save_flags(flags); - cli(); - - i = 0; - - while (tmp != 2) - { - for (i=0; i < MAX_BOARD; i++) - { - if (!apbs[i].RamIO) - continue; - - tmp = readb(apbs[i].RamIO + DATA_TO_PC_READY); - - if (tmp == 2) - break; - - if (tmp > 2) /* Test octet ready correct */ - { - Dummy = readb(apbs[i].RamIO + VERS); - restore_flags(flags); - printk("APPLICOM driver read error board %d, DataToPcReady = %d\n", - i,(int)readb(apbs[i].RamIO + DATA_TO_PC_READY)); - DeviceErrorCount++; - return -EIO; - } - Dummy = readb(apbs[i].RamIO + VERS); + unsigned int NumCard; /* board number 1 -> 8 */ + unsigned int IndexCard; /* index board number 0 -> 7 */ + unsigned long flags; + unsigned int i; + unsigned char tmp = 0; + struct st_ram_io st_loc; + struct mailbox tmpmailbox; /* bounce buffer - can't copy to user space with cli() */ + + + if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) { + printk("Hmmm. read() of Applicom card, length %d != expected %d\n", count, sizeof(struct st_ram_io) + sizeof(struct mailbox)); + return -EINVAL; + } + save_flags(flags); + cli(); + + i = 0; + + while (tmp != 2) { + for (i = 0; i < MAX_BOARD; i++) { + if (!apbs[i].RamIO) + continue; + + tmp = readb(apbs[i].RamIO + DATA_TO_PC_READY); + + if (tmp == 2) + break; + + if (tmp > 2) { /* Test octet ready correct */ + Dummy = readb(apbs[i].RamIO + VERS); + restore_flags(flags); + printk(KERN_WARNING "APPLICOM driver read error board %d, DataToPcReady = %d\n", i, (int) readb(apbs[i].RamIO + DATA_TO_PC_READY)); + DeviceErrorCount++; + return -EIO; + } + Dummy = readb(apbs[i].RamIO + VERS); + + } + if (tmp != 2) { + /* + * FIXME: race on wakeup. O_NDELAY not implemented + * Parallel read threads race. + */ + restore_flags(flags); + interruptible_sleep_on(&FlagSleepRec); + if (signal_pending(current)) + return -EINTR; + save_flags(flags); + cli(); + } } - if (tmp != 2) + + IndexCard = i; + NumCard = i + 1; + st_loc.tic_owner_to_pc = readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC); + st_loc.numcard_owner_to_pc = readb(apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC); + + + // memcpy_fromio(&tmpmailbox, apbs[IndexCard].PtrRamToPc, sizeof(struct mailbox)); { - restore_flags(flags); - interruptible_sleep_on (&FlagSleepRec); - if (signal_pending(current)) - return -EINTR; - save_flags(flags); - cli(); + unsigned long from = (unsigned long) apbs[IndexCard].RamIO + RAM_TO_PC; + unsigned char *to = (unsigned char *) &tmpmailbox; + int c; + + for (c = 0; c < sizeof(struct mailbox); c++) + *(to++) = readb(from++); } - } - - IndexCard = i; - NumCard = i+1; - st_loc.tic_owner_to_pc = readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC); - st_loc.numcard_owner_to_pc = readb(apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC); - - - // memcpy_fromio(&tmpmailbox, apbs[IndexCard].PtrRamToPc, sizeof(struct mailbox)); - { - unsigned long from = (unsigned long)apbs[IndexCard].RamIO + RAM_TO_PC; - unsigned char *to = (unsigned char *)&tmpmailbox; - int c; - - for (c=0; c<sizeof(struct mailbox) ; c++) - *(to++) = readb(from++); - } - writeb(1,apbs[IndexCard].RamIO + ACK_FROM_PC_READY); - writeb(1,apbs[IndexCard].RamIO + TYP_ACK_FROM_PC); - writeb(NumCard, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC); - writeb(readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC), - apbs[IndexCard].RamIO + TIC_ACK_FROM_PC); - writeb(2, apbs[IndexCard].RamIO + ACK_FROM_PC_READY); - writeb(0, apbs[IndexCard].RamIO + DATA_TO_PC_READY); - writeb(2, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); - Dummy = readb(apbs[IndexCard].RamIO + VERS); - restore_flags(flags); + writeb(1, apbs[IndexCard].RamIO + ACK_FROM_PC_READY); + writeb(1, apbs[IndexCard].RamIO + TYP_ACK_FROM_PC); + writeb(NumCard, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC); + writeb(readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC), apbs[IndexCard].RamIO + TIC_ACK_FROM_PC); + writeb(2, apbs[IndexCard].RamIO + ACK_FROM_PC_READY); + writeb(0, apbs[IndexCard].RamIO + DATA_TO_PC_READY); + writeb(2, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); + Dummy = readb(apbs[IndexCard].RamIO + VERS); + restore_flags(flags); #ifdef DEBUG - { int c; + { + int c; - printk("Read from applicom card #%d. struct st_ram_io follows:",NumCard); - - for (c=0; c< sizeof(struct st_ram_io);) - { - printk("\n%5.5X: %2.2X",c,((unsigned char *)&st_loc)[c]); - - for (c++ ; c%8 && c<sizeof(struct st_ram_io); c++) - { - printk(" %2.2X",((unsigned char *)&st_loc)[c]); - } - } + printk("Read from applicom card #%d. struct st_ram_io follows:", NumCard); - printk("\nstruct mailbox follows:"); - - for (c=0; c< sizeof(struct mailbox);) - { - printk("\n%5.5X: %2.2X",c,((unsigned char *)&tmpmailbox)[c]); - - for (c++ ; c%8 && c<sizeof(struct mailbox); c++) - { - printk(" %2.2X",((unsigned char *)&tmpmailbox)[c]); - } - } - printk("\n"); - - } + for (c = 0; c < sizeof(struct st_ram_io);) { + printk("\n%5.5X: %2.2X", c, ((unsigned char *) &st_loc)[c]); + + for (c++; c % 8 && c < sizeof(struct st_ram_io); c++) { + printk(" %2.2X", ((unsigned char *) &st_loc)[c]); + } + } + + printk("\nstruct mailbox follows:"); + + for (c = 0; c < sizeof(struct mailbox);) { + printk("\n%5.5X: %2.2X", c, ((unsigned char *) &tmpmailbox)[c]); + + for (c++; c % 8 && c < sizeof(struct mailbox); c++) { + printk(" %2.2X", ((unsigned char *) &tmpmailbox)[c]); + } + } + printk("\n"); + + } #endif - - /* Je suis stupide. DW. */ - if(copy_to_user (buf, &st_loc, sizeof(struct st_ram_io))) - return -EFAULT; - if(copy_to_user (&buf[sizeof(struct st_ram_io)], &tmpmailbox, sizeof(struct mailbox))) - return -EFAULT; + /* Je suis stupide. DW. */ - return 0; + if (copy_to_user(buf, &st_loc, sizeof(struct st_ram_io))) + return -EFAULT; + if (copy_to_user(&buf[sizeof(struct st_ram_io)], &tmpmailbox, sizeof(struct mailbox))) + return -EFAULT; + + return 0; } static void ac_interrupt(int vec, void *dev_instance, struct pt_regs *regs) { - unsigned int i; - unsigned int FlagInt; - unsigned int LoopCount; - // volatile unsigned char ResetIntBoard; - - // printk("Applicom interrupt on IRQ %d occurred\n", vec); - - LoopCount = 0; - // for(i=boardno;i<MAX_BOARD;i++) /* loop for not configured board */ - // if (apbs[i].RamIO) - // ResetIntBoard = *apbs[i].PtrRamItToPc; /* reset interrupt of unused boards */ - - do - { - FlagInt = FALSE; - for(i=0;i<MAX_BOARD;i++) - { - if (!apbs[i].RamIO) - continue; - - if(readb(apbs[i].RamIO + RAM_IT_TO_PC) != 0) - FlagInt = TRUE; - writeb(0, apbs[i].RamIO + RAM_IT_TO_PC); - - if(readb(apbs[i].RamIO + DATA_TO_PC_READY) > 2) - { - printk("APPLICOM driver interrupt err board %d, DataToPcReady = %d\n", - i+1,(int)readb(apbs[i].RamIO + DATA_TO_PC_READY)); - DeviceErrorCount++; - } - if((readb(apbs[i].RamIO + DATA_FROM_PC_READY) > 2) && - (readb(apbs[i].RamIO + DATA_FROM_PC_READY) != 6)) - { - printk("APPLICOM driver interrupt err board %d, DataFromPcReady = %d\n", - i+1,(int)readb(apbs[i].RamIO + DATA_FROM_PC_READY)); - DeviceErrorCount++; - } - if(readb(apbs[i].RamIO + DATA_TO_PC_READY) == 2) /* mailbox sent by the card ? */ - { - wake_up_interruptible(&FlagSleepRec); - } - if(readb(apbs[i].RamIO + DATA_FROM_PC_READY) == 0) /* ram i/o free for write by pc ? */ - { - if(waitqueue_active(&apbs[i].FlagSleepSend)) /* process sleep during read ? */ - { - wake_up_interruptible(&apbs[i].FlagSleepSend); - } - } - Dummy = readb(apbs[i].RamIO + VERS); - - if(readb(apbs[i].RamIO + RAM_IT_TO_PC)) - i--; /* There's another int waiting on this card */ - } - if(FlagInt) LoopCount = 0; - else LoopCount++; - } - while(LoopCount < 2); + unsigned int i; + unsigned int FlagInt; + unsigned int LoopCount; + // volatile unsigned char ResetIntBoard; + + // printk("Applicom interrupt on IRQ %d occurred\n", vec); + + LoopCount = 0; + // for(i=boardno;i<MAX_BOARD;i++) /* loop for not configured board */ + // if (apbs[i].RamIO) + // ResetIntBoard = *apbs[i].PtrRamItToPc; /* reset interrupt of unused boards */ + + do { + FlagInt = FALSE; + for (i = 0; i < MAX_BOARD; i++) { + if (!apbs[i].RamIO) + continue; + + if (readb(apbs[i].RamIO + RAM_IT_TO_PC) != 0) + FlagInt = TRUE; + writeb(0, apbs[i].RamIO + RAM_IT_TO_PC); + + if (readb(apbs[i].RamIO + DATA_TO_PC_READY) > 2) { + printk(KERN_WARNING "APPLICOM driver interrupt err board %d, DataToPcReady = %d\n", i + 1, (int) readb(apbs[i].RamIO + DATA_TO_PC_READY)); + DeviceErrorCount++; + } + if ((readb(apbs[i].RamIO + DATA_FROM_PC_READY) > 2) && (readb(apbs[i].RamIO + DATA_FROM_PC_READY) != 6)) { + printk("APPLICOM driver interrupt err board %d, DataFromPcReady = %d\n", i + 1, (int) readb(apbs[i].RamIO + DATA_FROM_PC_READY)); + DeviceErrorCount++; + } + if (readb(apbs[i].RamIO + DATA_TO_PC_READY) == 2) { /* mailbox sent by the card ? */ + wake_up_interruptible(&FlagSleepRec); + } + if (readb(apbs[i].RamIO + DATA_FROM_PC_READY) == 0) { /* ram i/o free for write by pc ? */ + if (waitqueue_active(&apbs[i].FlagSleepSend)) { /* process sleep during read ? */ + wake_up_interruptible(&apbs[i].FlagSleepSend); + } + } + Dummy = readb(apbs[i].RamIO + VERS); + + if (readb(apbs[i].RamIO + RAM_IT_TO_PC)) + i--; /* There's another int waiting on this card */ + } + if (FlagInt) + LoopCount = 0; + else + LoopCount++; + } + while (LoopCount < 2); } static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ /* @ ADG ou ATO selon le cas */ + int i; + unsigned char IndexCard; + unsigned long pmem; + volatile unsigned char byte_reset_it; + struct st_ram_io adgl; + unsigned char TmpRamIo[sizeof(struct st_ram_io)]; -{ /* @ ADG ou ATO selon le cas */ - int i; - unsigned char IndexCard; - unsigned long pmem ; - volatile unsigned char byte_reset_it; - struct st_ram_io adgl ; - unsigned char TmpRamIo[sizeof(struct st_ram_io)]; - - - if (copy_from_user (&adgl, (void *)arg,sizeof(struct st_ram_io))) - return -EFAULT; - - IndexCard = adgl.num_card-1; - if(cmd != 0 && cmd != 6 && - ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) - { - printk("APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1); - printk("apbs[%d].RamIO = %lx\n",IndexCard, apbs[IndexCard].RamIO); - return -EINVAL; - } - - switch( cmd ) - { - case 0 : - pmem = apbs[IndexCard].RamIO; - for(i=0;i<sizeof(struct st_ram_io);i++)TmpRamIo[i]=readb(pmem++); - if (copy_to_user((void *)arg, TmpRamIo, sizeof(struct st_ram_io))) - return -EFAULT; - break; - case 1 : - pmem = apbs[IndexCard].RamIO + CONF_END_TEST; - for (i=0;i<4;i++) - adgl.conf_end_test[i] = readb(pmem++); - for (i=0;i<2;i++) - adgl.error_code[i] = readb(pmem++); - for (i=0;i<4;i++) - adgl.parameter_error[i] = readb(pmem++); - pmem = apbs[IndexCard].RamIO + VERS; - adgl.vers = readb(pmem); - pmem = apbs[IndexCard].RamIO + TYPE_CARD; - for (i=0;i<20;i++) - adgl.reserv1[i] = readb(pmem++); - *(int *)&adgl.reserv1[20] = - (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER) << 16) + - (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) + - (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2) ); - - if (copy_to_user ((void *)arg, &adgl, sizeof(struct st_ram_io))) - return -EFAULT; - break; - case 2 : - pmem = apbs[IndexCard].RamIO + CONF_END_TEST; - for (i=0;i<10;i++) - writeb(0xff, pmem++); - writeb(adgl.data_from_pc_ready, - apbs[IndexCard].RamIO + DATA_FROM_PC_READY); - - writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); + + if (copy_from_user(&adgl, (void *) arg, sizeof(struct st_ram_io))) + return -EFAULT; + + IndexCard = adgl.num_card - 1; + + /* + * FIXME: user can flood the console using bogus ioctls + */ + + if (cmd != 0 && cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) { + printk("APPLICOM driver IOCTL, bad board number %d\n", (int) IndexCard + 1); + printk("apbs[%d].RamIO = %lx\n", IndexCard, apbs[IndexCard].RamIO); + return -EINVAL; + } + + /* + * FIXME races between ioctls with multiple clients + */ + + switch (cmd) { + case 0: + pmem = apbs[IndexCard].RamIO; + for (i = 0; i < sizeof(struct st_ram_io); i++) + TmpRamIo[i] = readb(pmem++); + if (copy_to_user((void *) arg, TmpRamIo, sizeof(struct st_ram_io))) + return -EFAULT; + break; + case 1: + pmem = apbs[IndexCard].RamIO + CONF_END_TEST; + for (i = 0; i < 4; i++) + adgl.conf_end_test[i] = readb(pmem++); + for (i = 0; i < 2; i++) + adgl.error_code[i] = readb(pmem++); + for (i = 0; i < 4; i++) + adgl.parameter_error[i] = readb(pmem++); + pmem = apbs[IndexCard].RamIO + VERS; + adgl.vers = readb(pmem); + pmem = apbs[IndexCard].RamIO + TYPE_CARD; + for (i = 0; i < 20; i++) + adgl.reserv1[i] = readb(pmem++); + *(int *) &adgl.reserv1[20] = (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER) << 16) + (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) + (readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2)); + + if (copy_to_user((void *) arg, &adgl, sizeof(struct st_ram_io))) + return -EFAULT; + break; + case 2: + pmem = apbs[IndexCard].RamIO + CONF_END_TEST; + for (i = 0; i < 10; i++) + writeb(0xff, pmem++); + writeb(adgl.data_from_pc_ready, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); + + writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); + + /* + * FIXME: can trash waitqueue that is active. + */ #if LINUX_VERSION_CODE > 0x20300 - init_waitqueue_head (&FlagSleepRec); + init_waitqueue_head(&FlagSleepRec); #else - FlagSleepRec = NULL; + FlagSleepRec = NULL; #endif - for (i=0;i<MAX_BOARD;i++) - { - if (apbs[i].RamIO) - { + for (i = 0; i < MAX_BOARD; i++) { + if (apbs[i].RamIO) { #if LINUX_VERSION_CODE > 0x20300 - init_waitqueue_head (&apbs[i].FlagSleepSend); + init_waitqueue_head(&apbs[i].FlagSleepSend); #else - apbs[i].FlagSleepSend = NULL; + apbs[i].FlagSleepSend = NULL; #endif - byte_reset_it = readb(apbs[i].RamIO + RAM_IT_TO_PC); - } - } - break ; - case 3 : - pmem = apbs[IndexCard].RamIO + TIC_DES_FROM_PC; - writeb(adgl.tic_des_from_pc, pmem); - break; - case 4 : - pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC; - adgl.tic_owner_to_pc = readb(pmem++); - adgl.numcard_owner_to_pc = readb(pmem); - if (copy_to_user ((void *)arg, &adgl,sizeof(struct st_ram_io))) - return -EFAULT; - break; - case 5 : - writeb(adgl.num_card, apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC); - writeb(adgl.num_card, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC); - writeb(adgl.num_card, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC); - writeb(4, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); - writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); - break ; - case 6 : - printk("APPLICOM driver release .... V2.8.0\n"); - printk("Number of installed boards . %d\n",(int)numboards); - printk("Segment of board ........... %X\n",(int)mem); - printk("Interrupt IRQ number ....... %d\n",(int)irq); - for(i=0;i<MAX_BOARD;i++) - { - int serial; - char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1]; - - if (!apbs[i].RamIO) - continue; - - - for(serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++) - boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial); - boardname[serial]=0; - - - printk("Prom version board %d ....... V%d.%d %s", - i+1, - (int)(readb(apbs[IndexCard].RamIO + VERS) >> 4), - (int)(readb(apbs[IndexCard].RamIO + VERS) & 0xF), - boardname); - - - serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) + - (readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) + - (readb(apbs[i].RamIO + SERIAL_NUMBER + 2) ); - - if (serial != 0) - printk (" S/N %d\n", serial); - else - printk("\n"); - } - if(DeviceErrorCount != 0) - printk("DeviceErrorCount ........... %d\n",DeviceErrorCount); - if(ReadErrorCount != 0) - printk("ReadErrorCount ............. %d\n",ReadErrorCount); - if(WriteErrorCount != 0) - printk("WriteErrorCount ............ %d\n",WriteErrorCount); - if(waitqueue_active(&FlagSleepRec)) - printk("Process in read pending\n"); - for(i=0;i<MAX_BOARD;i++) - { - if (apbs[i].RamIO && waitqueue_active(&apbs[i].FlagSleepSend)) - printk("Process in write pending board %d\n",i+1); - } - break; - default : - printk("APPLICOM driver ioctl, unknown function code %d\n",cmd) ; - return -EINVAL; - break; - } - Dummy = readb(apbs[IndexCard].RamIO + VERS); - return 0; + byte_reset_it = readb(apbs[i].RamIO + RAM_IT_TO_PC); + } + } + break; + case 3: + pmem = apbs[IndexCard].RamIO + TIC_DES_FROM_PC; + writeb(adgl.tic_des_from_pc, pmem); + break; + case 4: + pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC; + adgl.tic_owner_to_pc = readb(pmem++); + adgl.numcard_owner_to_pc = readb(pmem); + if (copy_to_user((void *) arg, &adgl, sizeof(struct st_ram_io))) + return -EFAULT; + break; + case 5: + writeb(adgl.num_card, apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC); + writeb(adgl.num_card, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC); + writeb(adgl.num_card, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC); + writeb(4, apbs[IndexCard].RamIO + DATA_FROM_PC_READY); + writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC); + break; + case 6: + printk(KERN_INFO "APPLICOM driver release .... V2.8.0\n"); + printk(KERN_INFO "Number of installed boards . %d\n", (int) numboards); + printk(KERN_INFO "Segment of board ........... %X\n", (int) mem); + printk(KERN_INFO "Interrupt IRQ number ....... %d\n", (int) irq); + for (i = 0; i < MAX_BOARD; i++) { + int serial; + char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1]; + + if (!apbs[i].RamIO) + continue; + + + for (serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++) + boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial); + boardname[serial] = 0; + + + printk(KERN_INFO "Prom version board %d ....... V%d.%d %s", i + 1, (int) (readb(apbs[IndexCard].RamIO + VERS) >> 4), (int) (readb(apbs[IndexCard].RamIO + VERS) & 0xF), boardname); + + + serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) + (readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) + (readb(apbs[i].RamIO + SERIAL_NUMBER + 2)); + + if (serial != 0) + printk(" S/N %d\n", serial); + else + printk("\n"); + } + if (DeviceErrorCount != 0) + printk(KERN_INFO "DeviceErrorCount ........... %d\n", DeviceErrorCount); + if (ReadErrorCount != 0) + printk(KERN_INFO "ReadErrorCount ............. %d\n", ReadErrorCount); + if (WriteErrorCount != 0) + printk(KERN_INFO "WriteErrorCount ............ %d\n", WriteErrorCount); + if (waitqueue_active(&FlagSleepRec)) + printk("Process in read pending\n"); + for (i = 0; i < MAX_BOARD; i++) { + if (apbs[i].RamIO && waitqueue_active(&apbs[i].FlagSleepSend)) + printk("Process in write pending board %d\n", i + 1); + } + break; + default: + printk("APPLICOM driver ioctl, unknown function code %d\n", cmd); + return -EINVAL; + break; + } + Dummy = readb(apbs[IndexCard].RamIO + VERS); + return 0; } #ifndef MODULE static int __init applicom_setup(char *str) { int ints[4]; - - (void)get_options(str, 4, ints); + + (void) get_options(str, 4, ints); if (ints[0] > 2) { printk(KERN_WARNING "Too many arguments to 'applicom=', expected mem,irq only.\n"); } - + if (ints[0] < 2) { printk("applicom numargs: %d\n", ints[0]); return 0; } - - mem=ints[1]; - irq=ints[2]; + + mem = ints[1]; + irq = ints[2]; return 1; } + #if LINUX_VERSION_CODE > 0x20300 __setup("applicom=", applicom_setup); #endif -#endif /* MODULE */ - +#endif /* MODULE */ |