1 /* Derived from Applicom driver ac.c for SCO Unix */
2 /* Ported by David Woodhouse, Axiom (Cambridge) Ltd. */
3 /* Dave@mvhi.com 30/8/98 */
4 /* $Id: ac.c,v 1.16 1999/08/28 15:11:50 dwmw2 Exp $ */
5 /* This module is for Linux 2.1 and 2.2 series kernels. */
6 /*****************************************************************************/
7 /* J PAGET 18/02/94 passage V2.4.2 ioctl avec code 2 reset to les interrupt */
8 /* ceci pour reseter correctement apres une sortie sauvage */
9 /* J PAGET 02/05/94 passage V2.4.3 dans le traitement de d'interruption, */
10 /* LoopCount n'etait pas initialise a 0. */
11 /* F LAFORSE 04/07/95 version V2.6.0 lecture bidon apres acces a une carte */
12 /* pour liberer le bus */
13 /* J.PAGET 19/11/95 version V2.6.1 Nombre, addresse,irq n'est plus configure */
14 /* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */
15 /* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */
16 /* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */
17 /* adresses de base des cartes, IOCTL 6 plus complet */
18 /* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */
19 /* de code autre que le texte V2.6.1 en V2.8.0 */
20 /*****************************************************************************/
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <asm/errno.h>
27 #include <asm/uaccess.h>
28 #include <linux/miscdevice.h>
29 #include <linux/pci.h>
30 #include <linux/wait.h>
31 #include <linux/init.h>
33 #ifndef LINUX_VERSION_CODE
34 #include <linux/version.h>
38 #define DEVPRIO PZERO+8
41 #define MAX_BOARD 8 /* maximum of pc board possible */
42 #define MAX_ISA_BOARD 4
43 #define LEN_RAM_IO 0x800
46 #ifndef PCI_VENDOR_ID_APPLICOM
47 #define PCI_VENDOR_ID_APPLICOM 0x1389
48 #define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
49 #define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002
50 #define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003
51 #define MAX_PCI_DEVICE_NUM 3
54 static char *applicom_pci_devnames
[]={
55 "PCI board", "PCI2000IBS / PCI2000CAN", "PCI2000PFB"};
57 MODULE_AUTHOR("David Woodhouse & Applicom International");
58 MODULE_DESCRIPTION("Driver for Applicom Profibus card");
59 MODULE_PARM(irq
, "i");
60 MODULE_PARM_DESC(irq
, "IRQ of the Applicom board");
62 MODULE_PARM_DESC(mem
, "Shared Memory Address of Applicom board");
64 MODULE_SUPPORTED_DEVICE("ac");
67 struct applicom_board
{
70 #if LINUX_VERSION_CODE > 0x20300
71 wait_queue_head_t FlagSleepSend
;
73 struct wait_queue
*FlagSleepSend
;
78 static unsigned int irq
=0; /* interrupt number IRQ */
79 static unsigned long mem
=0; /* physical segment of board */
81 static unsigned int numboards
; /* number of installed boards */
82 static volatile unsigned char Dummy
;
83 #if LINUX_VERSION_CODE > 0x20300
84 static DECLARE_WAIT_QUEUE_HEAD (FlagSleepRec
);
86 static struct wait_queue
*FlagSleepRec
;
88 static unsigned int WriteErrorCount
; /* number of write error */
89 static unsigned int ReadErrorCount
; /* number of read error */
90 static unsigned int DeviceErrorCount
; /* number of device error */
92 static loff_t
ac_llseek(struct file
*file
, loff_t offset
, int origin
);
93 static int ac_open(struct inode
*inode
, struct file
*filp
);
94 static ssize_t
ac_read (struct file
*filp
, char *buf
, size_t count
, loff_t
*ptr
);
95 static ssize_t
ac_write (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
);
96 static int ac_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
);
97 static int ac_release(struct inode
*inode
, struct file
*file
);
98 static void ac_interrupt(int irq
, void *dev_instance
, struct pt_regs
*regs
);
100 struct file_operations ac_fops
={
101 ac_llseek
, /* llseek */
103 ac_write
, /* write */
106 ac_ioctl
, /* ioctl */
110 ac_release
, /* release */
114 struct miscdevice ac_miscdev
={
120 int ac_register_board(unsigned long physloc
, unsigned long loc
,
121 unsigned char boardno
)
123 volatile unsigned char byte_reset_it
;
125 if((readb(loc
+ CONF_END_TEST
) != 0x00) ||
126 (readb(loc
+ CONF_END_TEST
+ 1) != 0x55) ||
127 (readb(loc
+ CONF_END_TEST
+ 2) != 0xAA) ||
128 (readb(loc
+ CONF_END_TEST
+ 3) != 0xFF))
133 boardno
= readb(loc
+ NUMCARD_OWNER_TO_PC
);
135 if (!boardno
&& boardno
> MAX_BOARD
)
137 printk(KERN_WARNING
"Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n",boardno
, physloc
, MAX_BOARD
);
141 if (apbs
[boardno
-1].RamIO
)
143 printk(KERN_WARNING
"Board #%d (at 0x%lx) conflicts with previous board #%d (at 0x%lx)\n",
144 boardno
, physloc
, boardno
, apbs
[boardno
-1].PhysIO
);
150 apbs
[boardno
].PhysIO
= physloc
;
151 apbs
[boardno
].RamIO
= loc
;
152 #if LINUX_VERSION_CODE > 0x20300
153 init_waitqueue_head(&apbs
[boardno
].FlagSleepSend
);
155 apbs
[boardno
].FlagSleepSend
= NULL
;
157 byte_reset_it
= readb(loc
+ RAM_IT_TO_PC
);
165 #define applicom_init init_module
167 void cleanup_module(void)
171 misc_deregister(&ac_miscdev
);
172 for (i
=0; i
< MAX_BOARD
; i
++)
176 iounmap((void *)apbs
[i
].RamIO
);
178 free_irq(apbs
[i
].irq
,&ac_open
);
180 // printk("Removing Applicom module\n");
185 int __init
applicom_init(void)
188 struct pci_dev
*dev
= NULL
;
191 #if LINUX_VERSION_CODE > 0x20300
192 #define PCI_BASE_ADDRESS(dev) (dev->resource[0].start)
194 #define PCI_BASE_ADDRESS(dev) (dev->base_address[0])
197 printk(KERN_INFO
"Applicom driver: $Id: ac.c,v 1.16 1999/08/28 15:11:50 dwmw2 Exp $\n");
199 /* No mem and irq given - check for a PCI card */
201 while ( (dev
= pci_find_device(PCI_VENDOR_ID_APPLICOM
, 1, dev
)))
203 // mem = dev->base_address[0];
206 RamIO
= ioremap(PCI_BASE_ADDRESS(dev
), LEN_RAM_IO
);
209 printk(KERN_INFO
"ac.o: Failed to ioremap PCI memory space at 0x%lx\n", PCI_BASE_ADDRESS(dev
));
213 printk(KERN_INFO
"Applicom %s found at mem 0x%lx, irq %d\n",
214 applicom_pci_devnames
[dev
->device
-1], PCI_BASE_ADDRESS(dev
),
217 if (!(boardno
= ac_register_board(PCI_BASE_ADDRESS(dev
),
218 (unsigned long)RamIO
,0)))
220 printk(KERN_INFO
"ac.o: PCI Applicom device doesn't have correct signature.\n");
225 if (request_irq(dev
->irq
, &ac_interrupt
, SA_SHIRQ
, "Applicom PCI", &ac_open
))
227 printk(KERN_INFO
"Could not allocate IRQ %d for PCI Applicom device.\n", dev
->irq
);
229 apbs
[boardno
-1].RamIO
= 0;
233 /* Enable interrupts. */
235 writeb(0x40, apbs
[boardno
-1].RamIO
+ RAM_IT_FROM_PC
);
237 apbs
[boardno
-1].irq
= dev
->irq
;
240 /* Finished with PCI cards. If none registered,
241 * and there was no mem/irq specified, exit */
249 printk(KERN_INFO
"ac.o: No PCI boards found.\n");
250 printk(KERN_INFO
"ac.o: For an ISA board you must supply memory and irq parameters.\n");
255 /* Now try the specified ISA cards */
257 RamIO
= ioremap(mem
, LEN_RAM_IO
* MAX_ISA_BOARD
);
260 printk(KERN_INFO
"ac.o: Failed to ioremap ISA memory space at 0x%lx\n",mem
);
263 for (i
=0; i
< MAX_ISA_BOARD
; i
++)
265 RamIO
= ioremap(mem
+ (LEN_RAM_IO
*i
), LEN_RAM_IO
);
268 printk(KERN_INFO
"ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n",i
+1);
272 if (!(boardno
= ac_register_board((unsigned long)mem
+ (LEN_RAM_IO
*i
),
273 (unsigned long)RamIO
,i
+1))) {
278 printk("Applicom ISA card found at mem 0x%lx, irq %d\n", mem
+ (LEN_RAM_IO
*i
), irq
);
282 if (request_irq(irq
, &ac_interrupt
, SA_SHIRQ
, "Applicom ISA", &ac_open
))
284 printk("Could not allocate IRQ %d for ISA Applicom device.\n", irq
);
285 iounmap((void *)RamIO
);
286 apbs
[boardno
-1].RamIO
= 0;
288 apbs
[boardno
-1].irq
=irq
;
291 apbs
[boardno
-1].irq
=0;
297 printk("ac.o: No valid ISA Applicom boards found at mem 0x%lx\n",mem
);
299 #if LINUX_VERSION_CODE > 0x20300
300 init_waitqueue_head(&FlagSleepRec
);
306 DeviceErrorCount
= 0;
311 misc_register (&ac_miscdev
);
312 for (i
=0; i
<MAX_BOARD
; i
++)
315 char boardname
[(SERIAL_NUMBER
- TYPE_CARD
) + 1];
320 for(serial
= 0; serial
< SERIAL_NUMBER
- TYPE_CARD
; serial
++)
321 boardname
[serial
] = readb(apbs
[i
].RamIO
+ TYPE_CARD
+ serial
);
325 printk("Applicom board %d: %s, PROM V%d.%d",
327 (int)(readb(apbs
[i
].RamIO
+ VERS
) >> 4),
328 (int)(readb(apbs
[i
].RamIO
+ VERS
) & 0xF));
330 serial
= (readb(apbs
[i
].RamIO
+ SERIAL_NUMBER
) << 16) +
331 (readb(apbs
[i
].RamIO
+ SERIAL_NUMBER
+ 1) << 8) +
332 (readb(apbs
[i
].RamIO
+ SERIAL_NUMBER
+ 2) );
335 printk (" S/N %d\n", serial
);
348 __initcall (applicom_init
);
351 static loff_t
ac_llseek(struct file
*file
, loff_t offset
, int origin
)
356 static int ac_open(struct inode
*inode
, struct file
*filp
)
362 static int ac_release(struct inode
*inode
, struct file
*file
)
369 static ssize_t
ac_write (struct file
*file
, const char *buf
, size_t count
, loff_t
*ppos
)
371 unsigned int NumCard
; /* Board number 1 -> 8 */
372 unsigned int IndexCard
; /* Index board number 0 -> 7 */
373 unsigned char TicCard
; /* Board TIC to send */
374 unsigned long flags
; /* Current priority */
375 struct st_ram_io st_loc
;
376 struct mailbox tmpmailbox
;
378 if (count
!= sizeof(struct st_ram_io
) + sizeof(struct mailbox
)) {
379 printk("Hmmm. write() of Applicom card, length %d != expected %d\n",count
,sizeof(struct st_ram_io
) + sizeof(struct mailbox
));
383 if(copy_from_user (&st_loc
, buf
, sizeof(struct st_ram_io
))) {
386 if(copy_from_user (&tmpmailbox
, &buf
[sizeof(struct st_ram_io
)], sizeof(struct mailbox
))) {
390 NumCard
= st_loc
.num_card
; /* board number to send */
391 TicCard
= st_loc
.tic_des_from_pc
; /* tic number to send */
392 IndexCard
= NumCard
-1;
393 if((NumCard
< 1) || (NumCard
> MAX_BOARD
) || !apbs
[IndexCard
].RamIO
)
394 { /* User board number not OK */
395 // printk("Write to invalid Applicom board %d\n", NumCard);
396 return -EINVAL
; /* Return error code user buffer */
403 printk("Write to applicom card #%d. struct st_ram_io follows:",NumCard
);
407 for (c
=0; c
< sizeof(struct st_ram_io
);)
409 printk("\n%5.5X: %2.2X",c
,((unsigned char *)&st_loc
)[c
]);
411 for (c
++ ; c
%8 && c
<sizeof(struct st_ram_io
); c
++)
413 printk(" %2.2X",((unsigned char *)&st_loc
)[c
]);
417 printk("\nstruct mailbox follows:");
419 for (c
=0; c
< sizeof(struct mailbox
);)
421 printk("\n%5.5X: %2.2X",c
,((unsigned char *)&tmpmailbox
)[c
]);
423 for (c
++ ; c
%8 && c
<sizeof(struct mailbox
); c
++)
425 printk(" %2.2X",((unsigned char *)&tmpmailbox
)[c
]);
435 cli(); /* disable interrupt */
437 if(readb(apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
) > 2) /* Test octet ready correct */
439 Dummy
= readb(apbs
[IndexCard
].RamIO
+ VERS
);
440 restore_flags(flags
);
441 printk("APPLICOM driver write error board %d, DataFromPcReady = %d\n",
442 IndexCard
,(int)readb(apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
));
446 while (readb(apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
) != 0)
448 Dummy
= readb(apbs
[IndexCard
].RamIO
+ VERS
);
449 restore_flags(flags
);
450 interruptible_sleep_on (&apbs
[IndexCard
].FlagSleepSend
);
451 if (signal_pending(current
))
456 writeb(1, apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
);
458 // memcpy_toio ((void *)apbs[IndexCard].PtrRamFromPc, (void *)&tmpmailbox, sizeof(struct mailbox));
460 unsigned char *from
= (unsigned char *)&tmpmailbox
;
461 unsigned long to
= (unsigned long)apbs
[IndexCard
].RamIO
+ RAM_FROM_PC
;
464 for (c
=0; c
<sizeof(struct mailbox
) ; c
++)
465 writeb(*(from
++), to
++);
467 writeb(0x20, apbs
[IndexCard
].RamIO
+ TIC_OWNER_FROM_PC
);
468 writeb(0xff, apbs
[IndexCard
].RamIO
+ NUMCARD_OWNER_FROM_PC
);
469 writeb(TicCard
, apbs
[IndexCard
].RamIO
+ TIC_DES_FROM_PC
);
470 writeb(NumCard
, apbs
[IndexCard
].RamIO
+ NUMCARD_DES_FROM_PC
);
471 writeb(2, apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
);
472 writeb(1, apbs
[IndexCard
].RamIO
+ RAM_IT_FROM_PC
);
473 Dummy
= readb(apbs
[IndexCard
].RamIO
+ VERS
);
474 restore_flags (flags
);
478 static ssize_t
ac_read (struct file
*filp
, char *buf
, size_t count
, loff_t
*ptr
)
480 unsigned int NumCard
; /* board number 1 -> 8 */
481 unsigned int IndexCard
; /* index board number 0 -> 7 */
485 struct st_ram_io st_loc
;
486 struct mailbox tmpmailbox
; /* bounce buffer - can't copy to user space with cli() */
489 if (count
!= sizeof(struct st_ram_io
) + sizeof(struct mailbox
)) {
490 printk("Hmmm. read() of Applicom card, length %d != expected %d\n",count
,sizeof(struct st_ram_io
) + sizeof(struct mailbox
));
501 for (i
=0; i
< MAX_BOARD
; i
++)
506 tmp
= readb(apbs
[i
].RamIO
+ DATA_TO_PC_READY
);
511 if (tmp
> 2) /* Test octet ready correct */
513 Dummy
= readb(apbs
[i
].RamIO
+ VERS
);
514 restore_flags(flags
);
515 printk("APPLICOM driver read error board %d, DataToPcReady = %d\n",
516 i
,(int)readb(apbs
[i
].RamIO
+ DATA_TO_PC_READY
));
520 Dummy
= readb(apbs
[i
].RamIO
+ VERS
);
525 restore_flags(flags
);
526 interruptible_sleep_on (&FlagSleepRec
);
527 if (signal_pending(current
))
536 st_loc
.tic_owner_to_pc
= readb(apbs
[IndexCard
].RamIO
+ TIC_OWNER_TO_PC
);
537 st_loc
.numcard_owner_to_pc
= readb(apbs
[IndexCard
].RamIO
+ NUMCARD_OWNER_TO_PC
);
540 // memcpy_fromio(&tmpmailbox, apbs[IndexCard].PtrRamToPc, sizeof(struct mailbox));
542 unsigned long from
= (unsigned long)apbs
[IndexCard
].RamIO
+ RAM_TO_PC
;
543 unsigned char *to
= (unsigned char *)&tmpmailbox
;
546 for (c
=0; c
<sizeof(struct mailbox
) ; c
++)
547 *(to
++) = readb(from
++);
549 writeb(1,apbs
[IndexCard
].RamIO
+ ACK_FROM_PC_READY
);
550 writeb(1,apbs
[IndexCard
].RamIO
+ TYP_ACK_FROM_PC
);
551 writeb(NumCard
, apbs
[IndexCard
].RamIO
+ NUMCARD_ACK_FROM_PC
);
552 writeb(readb(apbs
[IndexCard
].RamIO
+ TIC_OWNER_TO_PC
),
553 apbs
[IndexCard
].RamIO
+ TIC_ACK_FROM_PC
);
554 writeb(2, apbs
[IndexCard
].RamIO
+ ACK_FROM_PC_READY
);
555 writeb(0, apbs
[IndexCard
].RamIO
+ DATA_TO_PC_READY
);
556 writeb(2, apbs
[IndexCard
].RamIO
+ RAM_IT_FROM_PC
);
557 Dummy
= readb(apbs
[IndexCard
].RamIO
+ VERS
);
558 restore_flags(flags
);
563 printk("Read from applicom card #%d. struct st_ram_io follows:",NumCard
);
565 for (c
=0; c
< sizeof(struct st_ram_io
);)
567 printk("\n%5.5X: %2.2X",c
,((unsigned char *)&st_loc
)[c
]);
569 for (c
++ ; c
%8 && c
<sizeof(struct st_ram_io
); c
++)
571 printk(" %2.2X",((unsigned char *)&st_loc
)[c
]);
575 printk("\nstruct mailbox follows:");
577 for (c
=0; c
< sizeof(struct mailbox
);)
579 printk("\n%5.5X: %2.2X",c
,((unsigned char *)&tmpmailbox
)[c
]);
581 for (c
++ ; c
%8 && c
<sizeof(struct mailbox
); c
++)
583 printk(" %2.2X",((unsigned char *)&tmpmailbox
)[c
]);
592 /* Je suis stupide. DW. */
594 if(copy_to_user (buf
, &st_loc
, sizeof(struct st_ram_io
)))
596 if(copy_to_user (&buf
[sizeof(struct st_ram_io
)], &tmpmailbox
, sizeof(struct mailbox
)))
602 static void ac_interrupt(int vec
, void *dev_instance
, struct pt_regs
*regs
)
605 unsigned int FlagInt
;
606 unsigned int LoopCount
;
607 // volatile unsigned char ResetIntBoard;
609 // printk("Applicom interrupt on IRQ %d occurred\n", vec);
612 // for(i=boardno;i<MAX_BOARD;i++) /* loop for not configured board */
613 // if (apbs[i].RamIO)
614 // ResetIntBoard = *apbs[i].PtrRamItToPc; /* reset interrupt of unused boards */
619 for(i
=0;i
<MAX_BOARD
;i
++)
624 if(readb(apbs
[i
].RamIO
+ RAM_IT_TO_PC
) != 0)
626 writeb(0, apbs
[i
].RamIO
+ RAM_IT_TO_PC
);
628 if(readb(apbs
[i
].RamIO
+ DATA_TO_PC_READY
) > 2)
630 printk("APPLICOM driver interrupt err board %d, DataToPcReady = %d\n",
631 i
+1,(int)readb(apbs
[i
].RamIO
+ DATA_TO_PC_READY
));
634 if((readb(apbs
[i
].RamIO
+ DATA_FROM_PC_READY
) > 2) &&
635 (readb(apbs
[i
].RamIO
+ DATA_FROM_PC_READY
) != 6))
637 printk("APPLICOM driver interrupt err board %d, DataFromPcReady = %d\n",
638 i
+1,(int)readb(apbs
[i
].RamIO
+ DATA_FROM_PC_READY
));
641 if(readb(apbs
[i
].RamIO
+ DATA_TO_PC_READY
) == 2) /* mailbox sent by the card ? */
643 wake_up_interruptible(&FlagSleepRec
);
645 if(readb(apbs
[i
].RamIO
+ DATA_FROM_PC_READY
) == 0) /* ram i/o free for write by pc ? */
647 if(waitqueue_active(&apbs
[i
].FlagSleepSend
)) /* process sleep during read ? */
649 wake_up_interruptible(&apbs
[i
].FlagSleepSend
);
652 Dummy
= readb(apbs
[i
].RamIO
+ VERS
);
654 if(readb(apbs
[i
].RamIO
+ RAM_IT_TO_PC
))
655 i
--; /* There's another int waiting on this card */
657 if(FlagInt
) LoopCount
= 0;
660 while(LoopCount
< 2);
664 static int ac_ioctl(struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
666 { /* @ ADG ou ATO selon le cas */
668 unsigned char IndexCard
;
670 volatile unsigned char byte_reset_it
;
671 struct st_ram_io adgl
;
672 unsigned char TmpRamIo
[sizeof(struct st_ram_io
)];
675 if (copy_from_user (&adgl
, (void *)arg
,sizeof(struct st_ram_io
)))
678 IndexCard
= adgl
.num_card
-1;
679 if(cmd
!= 0 && cmd
!= 6 &&
680 ((IndexCard
>= MAX_BOARD
) || !apbs
[IndexCard
].RamIO
))
682 printk("APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard
+1);
683 printk("apbs[%d].RamIO = %lx\n",IndexCard
, apbs
[IndexCard
].RamIO
);
690 pmem
= apbs
[IndexCard
].RamIO
;
691 for(i
=0;i
<sizeof(struct st_ram_io
);i
++)TmpRamIo
[i
]=readb(pmem
++);
692 if (copy_to_user((void *)arg
, TmpRamIo
, sizeof(struct st_ram_io
)))
696 pmem
= apbs
[IndexCard
].RamIO
+ CONF_END_TEST
;
698 adgl
.conf_end_test
[i
] = readb(pmem
++);
700 adgl
.error_code
[i
] = readb(pmem
++);
702 adgl
.parameter_error
[i
] = readb(pmem
++);
703 pmem
= apbs
[IndexCard
].RamIO
+ VERS
;
704 adgl
.vers
= readb(pmem
);
705 pmem
= apbs
[IndexCard
].RamIO
+ TYPE_CARD
;
707 adgl
.reserv1
[i
] = readb(pmem
++);
708 *(int *)&adgl
.reserv1
[20] =
709 (readb(apbs
[IndexCard
].RamIO
+ SERIAL_NUMBER
) << 16) +
710 (readb(apbs
[IndexCard
].RamIO
+ SERIAL_NUMBER
+ 1) << 8) +
711 (readb(apbs
[IndexCard
].RamIO
+ SERIAL_NUMBER
+ 2) );
713 if (copy_to_user ((void *)arg
, &adgl
, sizeof(struct st_ram_io
)))
717 pmem
= apbs
[IndexCard
].RamIO
+ CONF_END_TEST
;
719 writeb(0xff, pmem
++);
720 writeb(adgl
.data_from_pc_ready
,
721 apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
);
723 writeb(1, apbs
[IndexCard
].RamIO
+ RAM_IT_FROM_PC
);
724 #if LINUX_VERSION_CODE > 0x20300
725 init_waitqueue_head (&FlagSleepRec
);
729 for (i
=0;i
<MAX_BOARD
;i
++)
733 #if LINUX_VERSION_CODE > 0x20300
734 init_waitqueue_head (&apbs
[i
].FlagSleepSend
);
736 apbs
[i
].FlagSleepSend
= NULL
;
738 byte_reset_it
= readb(apbs
[i
].RamIO
+ RAM_IT_TO_PC
);
743 pmem
= apbs
[IndexCard
].RamIO
+ TIC_DES_FROM_PC
;
744 writeb(adgl
.tic_des_from_pc
, pmem
);
747 pmem
= apbs
[IndexCard
].RamIO
+ TIC_OWNER_TO_PC
;
748 adgl
.tic_owner_to_pc
= readb(pmem
++);
749 adgl
.numcard_owner_to_pc
= readb(pmem
);
750 if (copy_to_user ((void *)arg
, &adgl
,sizeof(struct st_ram_io
)))
754 writeb(adgl
.num_card
, apbs
[IndexCard
].RamIO
+ NUMCARD_OWNER_TO_PC
);
755 writeb(adgl
.num_card
, apbs
[IndexCard
].RamIO
+ NUMCARD_DES_FROM_PC
);
756 writeb(adgl
.num_card
, apbs
[IndexCard
].RamIO
+ NUMCARD_ACK_FROM_PC
);
757 writeb(4, apbs
[IndexCard
].RamIO
+ DATA_FROM_PC_READY
);
758 writeb(1, apbs
[IndexCard
].RamIO
+ RAM_IT_FROM_PC
);
761 printk("APPLICOM driver release .... V2.8.0\n");
762 printk("Number of installed boards . %d\n",(int)numboards
);
763 printk("Segment of board ........... %X\n",(int)mem
);
764 printk("Interrupt IRQ number ....... %d\n",(int)irq
);
765 for(i
=0;i
<MAX_BOARD
;i
++)
768 char boardname
[(SERIAL_NUMBER
- TYPE_CARD
) + 1];
774 for(serial
= 0; serial
< SERIAL_NUMBER
- TYPE_CARD
; serial
++)
775 boardname
[serial
] = readb(apbs
[i
].RamIO
+ TYPE_CARD
+ serial
);
779 printk("Prom version board %d ....... V%d.%d %s",
781 (int)(readb(apbs
[IndexCard
].RamIO
+ VERS
) >> 4),
782 (int)(readb(apbs
[IndexCard
].RamIO
+ VERS
) & 0xF),
786 serial
= (readb(apbs
[i
].RamIO
+ SERIAL_NUMBER
) << 16) +
787 (readb(apbs
[i
].RamIO
+ SERIAL_NUMBER
+ 1) << 8) +
788 (readb(apbs
[i
].RamIO
+ SERIAL_NUMBER
+ 2) );
791 printk (" S/N %d\n", serial
);
795 if(DeviceErrorCount
!= 0)
796 printk("DeviceErrorCount ........... %d\n",DeviceErrorCount
);
797 if(ReadErrorCount
!= 0)
798 printk("ReadErrorCount ............. %d\n",ReadErrorCount
);
799 if(WriteErrorCount
!= 0)
800 printk("WriteErrorCount ............ %d\n",WriteErrorCount
);
801 if(waitqueue_active(&FlagSleepRec
))
802 printk("Process in read pending\n");
803 for(i
=0;i
<MAX_BOARD
;i
++)
805 if (apbs
[i
].RamIO
&& waitqueue_active(&apbs
[i
].FlagSleepSend
))
806 printk("Process in write pending board %d\n",i
+1);
810 printk("APPLICOM driver ioctl, unknown function code %d\n",cmd
) ;
814 Dummy
= readb(apbs
[IndexCard
].RamIO
+ VERS
);
819 static int __init
applicom_setup(char *str
)
823 (void)get_options(str
, 4, ints
);
826 printk(KERN_WARNING
"Too many arguments to 'applicom=', expected mem,irq only.\n");
830 printk("applicom numargs: %d\n", ints
[0]);
838 #if LINUX_VERSION_CODE > 0x20300
839 __setup("applicom=", applicom_setup
);