xref: /openbmc/linux/drivers/char/applicom.c (revision 6ee73861)
1 /* Derived from Applicom driver ac.c for SCO Unix                            */
2 /* Ported by David Woodhouse, Axiom (Cambridge) Ltd.                         */
3 /* dwmw2@infradead.org 30/8/98                                               */
4 /* $Id: ac.c,v 1.30 2000/03/22 16:03:57 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 /*****************************************************************************/
21 
22 
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/interrupt.h>
26 #include <linux/sched.h>
27 #include <linux/slab.h>
28 #include <linux/errno.h>
29 #include <linux/miscdevice.h>
30 #include <linux/pci.h>
31 #include <linux/wait.h>
32 #include <linux/init.h>
33 #include <linux/fs.h>
34 
35 #include <asm/io.h>
36 #include <asm/uaccess.h>
37 
38 #include "applicom.h"
39 
40 
41 /* NOTE: We use for loops with {write,read}b() instead of
42    memcpy_{from,to}io throughout this driver. This is because
43    the board doesn't correctly handle word accesses - only
44    bytes.
45 */
46 
47 
48 #undef DEBUG
49 
50 #define MAX_BOARD 8		/* maximum of pc board possible */
51 #define MAX_ISA_BOARD 4
52 #define LEN_RAM_IO 0x800
53 #define AC_MINOR 157
54 
55 #ifndef PCI_VENDOR_ID_APPLICOM
56 #define PCI_VENDOR_ID_APPLICOM                0x1389
57 #define PCI_DEVICE_ID_APPLICOM_PCIGENERIC     0x0001
58 #define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002
59 #define PCI_DEVICE_ID_APPLICOM_PCI2000PFB     0x0003
60 #endif
61 
62 static char *applicom_pci_devnames[] = {
63 	"PCI board",
64 	"PCI2000IBS / PCI2000CAN",
65 	"PCI2000PFB"
66 };
67 
68 static struct pci_device_id applicom_pci_tbl[] = {
69 	{ PCI_VDEVICE(APPLICOM, PCI_DEVICE_ID_APPLICOM_PCIGENERIC) },
70 	{ PCI_VDEVICE(APPLICOM, PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN) },
71 	{ PCI_VDEVICE(APPLICOM, PCI_DEVICE_ID_APPLICOM_PCI2000PFB) },
72 	{ 0 }
73 };
74 MODULE_DEVICE_TABLE(pci, applicom_pci_tbl);
75 
76 MODULE_AUTHOR("David Woodhouse & Applicom International");
77 MODULE_DESCRIPTION("Driver for Applicom Profibus card");
78 MODULE_LICENSE("GPL");
79 MODULE_ALIAS_MISCDEV(AC_MINOR);
80 
81 MODULE_SUPPORTED_DEVICE("ac");
82 
83 
84 static struct applicom_board {
85 	unsigned long PhysIO;
86 	void __iomem *RamIO;
87 	wait_queue_head_t FlagSleepSend;
88 	long irq;
89 	spinlock_t mutex;
90 } apbs[MAX_BOARD];
91 
92 static unsigned int irq = 0;	/* interrupt number IRQ       */
93 static unsigned long mem = 0;	/* physical segment of board  */
94 
95 module_param(irq, uint, 0);
96 MODULE_PARM_DESC(irq, "IRQ of the Applicom board");
97 module_param(mem, ulong, 0);
98 MODULE_PARM_DESC(mem, "Shared Memory Address of Applicom board");
99 
100 static unsigned int numboards;	/* number of installed boards */
101 static volatile unsigned char Dummy;
102 static DECLARE_WAIT_QUEUE_HEAD(FlagSleepRec);
103 static unsigned int WriteErrorCount;	/* number of write error      */
104 static unsigned int ReadErrorCount;	/* number of read error       */
105 static unsigned int DeviceErrorCount;	/* number of device error     */
106 
107 static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *);
108 static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *);
109 static int ac_ioctl(struct inode *, struct file *, unsigned int,
110 		    unsigned long);
111 static irqreturn_t ac_interrupt(int, void *);
112 
113 static const struct file_operations ac_fops = {
114 	.owner = THIS_MODULE,
115 	.llseek = no_llseek,
116 	.read = ac_read,
117 	.write = ac_write,
118 	.ioctl = ac_ioctl,
119 };
120 
121 static struct miscdevice ac_miscdev = {
122 	AC_MINOR,
123 	"ac",
124 	&ac_fops
125 };
126 
127 static int dummy;	/* dev_id for request_irq() */
128 
129 static int ac_register_board(unsigned long physloc, void __iomem *loc,
130 		      unsigned char boardno)
131 {
132 	volatile unsigned char byte_reset_it;
133 
134 	if((readb(loc + CONF_END_TEST)     != 0x00) ||
135 	   (readb(loc + CONF_END_TEST + 1) != 0x55) ||
136 	   (readb(loc + CONF_END_TEST + 2) != 0xAA) ||
137 	   (readb(loc + CONF_END_TEST + 3) != 0xFF))
138 		return 0;
139 
140 	if (!boardno)
141 		boardno = readb(loc + NUMCARD_OWNER_TO_PC);
142 
143 	if (!boardno || boardno > MAX_BOARD) {
144 		printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n",
145 		       boardno, physloc, MAX_BOARD);
146 		return 0;
147 	}
148 
149 	if (apbs[boardno - 1].RamIO) {
150 		printk(KERN_WARNING "Board #%d (at 0x%lx) conflicts with previous board #%d (at 0x%lx)\n",
151 		       boardno, physloc, boardno, apbs[boardno-1].PhysIO);
152 		return 0;
153 	}
154 
155 	boardno--;
156 
157 	apbs[boardno].PhysIO = physloc;
158 	apbs[boardno].RamIO = loc;
159 	init_waitqueue_head(&apbs[boardno].FlagSleepSend);
160 	spin_lock_init(&apbs[boardno].mutex);
161 	byte_reset_it = readb(loc + RAM_IT_TO_PC);
162 
163 	numboards++;
164 	return boardno + 1;
165 }
166 
167 static void __exit applicom_exit(void)
168 {
169 	unsigned int i;
170 
171 	misc_deregister(&ac_miscdev);
172 
173 	for (i = 0; i < MAX_BOARD; i++) {
174 
175 		if (!apbs[i].RamIO)
176 			continue;
177 
178 		if (apbs[i].irq)
179 			free_irq(apbs[i].irq, &dummy);
180 
181 		iounmap(apbs[i].RamIO);
182 	}
183 }
184 
185 static int __init applicom_init(void)
186 {
187 	int i, numisa = 0;
188 	struct pci_dev *dev = NULL;
189 	void __iomem *RamIO;
190 	int boardno, ret;
191 
192 	printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n");
193 
194 	/* No mem and irq given - check for a PCI card */
195 
196 	while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) {
197 
198 		if (!pci_match_id(applicom_pci_tbl, dev))
199 			continue;
200 
201 		if (pci_enable_device(dev))
202 			return -EIO;
203 
204 		RamIO = ioremap_nocache(pci_resource_start(dev, 0), LEN_RAM_IO);
205 
206 		if (!RamIO) {
207 			printk(KERN_INFO "ac.o: Failed to ioremap PCI memory "
208 				"space at 0x%llx\n",
209 				(unsigned long long)pci_resource_start(dev, 0));
210 			pci_disable_device(dev);
211 			return -EIO;
212 		}
213 
214 		printk(KERN_INFO "Applicom %s found at mem 0x%llx, irq %d\n",
215 		       applicom_pci_devnames[dev->device-1],
216 			   (unsigned long long)pci_resource_start(dev, 0),
217 		       dev->irq);
218 
219 		boardno = ac_register_board(pci_resource_start(dev, 0),
220 				RamIO, 0);
221 		if (!boardno) {
222 			printk(KERN_INFO "ac.o: PCI Applicom device doesn't have correct signature.\n");
223 			iounmap(RamIO);
224 			pci_disable_device(dev);
225 			continue;
226 		}
227 
228 		if (request_irq(dev->irq, &ac_interrupt, IRQF_SHARED, "Applicom PCI", &dummy)) {
229 			printk(KERN_INFO "Could not allocate IRQ %d for PCI Applicom device.\n", dev->irq);
230 			iounmap(RamIO);
231 			pci_disable_device(dev);
232 			apbs[boardno - 1].RamIO = NULL;
233 			continue;
234 		}
235 
236 		/* Enable interrupts. */
237 
238 		writeb(0x40, apbs[boardno - 1].RamIO + RAM_IT_FROM_PC);
239 
240 		apbs[boardno - 1].irq = dev->irq;
241 	}
242 
243 	/* Finished with PCI cards. If none registered,
244 	 * and there was no mem/irq specified, exit */
245 
246 	if (!mem || !irq) {
247 		if (numboards)
248 			goto fin;
249 		else {
250 			printk(KERN_INFO "ac.o: No PCI boards found.\n");
251 			printk(KERN_INFO "ac.o: For an ISA board you must supply memory and irq parameters.\n");
252 			return -ENXIO;
253 		}
254 	}
255 
256 	/* Now try the specified ISA cards */
257 
258 	for (i = 0; i < MAX_ISA_BOARD; i++) {
259 		RamIO = ioremap_nocache(mem + (LEN_RAM_IO * i), LEN_RAM_IO);
260 
261 		if (!RamIO) {
262 			printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n", i + 1);
263 			continue;
264 		}
265 
266 		if (!(boardno = ac_register_board((unsigned long)mem+ (LEN_RAM_IO*i),
267 						  RamIO,i+1))) {
268 			iounmap(RamIO);
269 			continue;
270 		}
271 
272 		printk(KERN_NOTICE "Applicom ISA card found at mem 0x%lx, irq %d\n", mem + (LEN_RAM_IO*i), irq);
273 
274 		if (!numisa) {
275 			if (request_irq(irq, &ac_interrupt, IRQF_SHARED, "Applicom ISA", &dummy)) {
276 				printk(KERN_WARNING "Could not allocate IRQ %d for ISA Applicom device.\n", irq);
277 				iounmap(RamIO);
278 				apbs[boardno - 1].RamIO = NULL;
279 			}
280 			else
281 				apbs[boardno - 1].irq = irq;
282 		}
283 		else
284 			apbs[boardno - 1].irq = 0;
285 
286 		numisa++;
287 	}
288 
289 	if (!numisa)
290 		printk(KERN_WARNING "ac.o: No valid ISA Applicom boards found "
291 				"at mem 0x%lx\n", mem);
292 
293  fin:
294 	init_waitqueue_head(&FlagSleepRec);
295 
296 	WriteErrorCount = 0;
297 	ReadErrorCount = 0;
298 	DeviceErrorCount = 0;
299 
300 	if (numboards) {
301 		ret = misc_register(&ac_miscdev);
302 		if (ret) {
303 			printk(KERN_WARNING "ac.o: Unable to register misc device\n");
304 			goto out;
305 		}
306 		for (i = 0; i < MAX_BOARD; i++) {
307 			int serial;
308 			char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1];
309 
310 			if (!apbs[i].RamIO)
311 				continue;
312 
313 			for (serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++)
314 				boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial);
315 
316 			boardname[serial] = 0;
317 
318 
319 			printk(KERN_INFO "Applicom board %d: %s, PROM V%d.%d",
320 			       i+1, boardname,
321 			       (int)(readb(apbs[i].RamIO + VERS) >> 4),
322 			       (int)(readb(apbs[i].RamIO + VERS) & 0xF));
323 
324 			serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) +
325 				(readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) +
326 				(readb(apbs[i].RamIO + SERIAL_NUMBER + 2) );
327 
328 			if (serial != 0)
329 				printk(" S/N %d\n", serial);
330 			else
331 				printk("\n");
332 		}
333 		return 0;
334 	}
335 
336 	else
337 		return -ENXIO;
338 
339 out:
340 	for (i = 0; i < MAX_BOARD; i++) {
341 		if (!apbs[i].RamIO)
342 			continue;
343 		if (apbs[i].irq)
344 			free_irq(apbs[i].irq, &dummy);
345 		iounmap(apbs[i].RamIO);
346 	}
347 	pci_disable_device(dev);
348 	return ret;
349 }
350 
351 module_init(applicom_init);
352 module_exit(applicom_exit);
353 
354 
355 static ssize_t ac_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
356 {
357 	unsigned int NumCard;	/* Board number 1 -> 8           */
358 	unsigned int IndexCard;	/* Index board number 0 -> 7     */
359 	unsigned char TicCard;	/* Board TIC to send             */
360 	unsigned long flags;	/* Current priority              */
361 	struct st_ram_io st_loc;
362 	struct mailbox tmpmailbox;
363 #ifdef DEBUG
364 	int c;
365 #endif
366 	DECLARE_WAITQUEUE(wait, current);
367 
368 	if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) {
369 		static int warncount = 5;
370 		if (warncount) {
371 			printk(KERN_INFO "Hmmm. write() of Applicom card, length %zd != expected %zd\n",
372 			       count, sizeof(struct st_ram_io) + sizeof(struct mailbox));
373 			warncount--;
374 		}
375 		return -EINVAL;
376 	}
377 
378 	if(copy_from_user(&st_loc, buf, sizeof(struct st_ram_io)))
379 		return -EFAULT;
380 
381 	if(copy_from_user(&tmpmailbox, &buf[sizeof(struct st_ram_io)],
382 			  sizeof(struct mailbox)))
383 		return -EFAULT;
384 
385 	NumCard = st_loc.num_card;	/* board number to send          */
386 	TicCard = st_loc.tic_des_from_pc;	/* tic number to send            */
387 	IndexCard = NumCard - 1;
388 
389 	if((NumCard < 1) || (NumCard > MAX_BOARD) || !apbs[IndexCard].RamIO)
390 		return -EINVAL;
391 
392 #ifdef DEBUG
393 	printk("Write to applicom card #%d. struct st_ram_io follows:",
394 	       IndexCard+1);
395 
396 		for (c = 0; c < sizeof(struct st_ram_io);) {
397 
398 			printk("\n%5.5X: %2.2X", c, ((unsigned char *) &st_loc)[c]);
399 
400 			for (c++; c % 8 && c < sizeof(struct st_ram_io); c++) {
401 				printk(" %2.2X", ((unsigned char *) &st_loc)[c]);
402 			}
403 		}
404 
405 		printk("\nstruct mailbox follows:");
406 
407 		for (c = 0; c < sizeof(struct mailbox);) {
408 			printk("\n%5.5X: %2.2X", c, ((unsigned char *) &tmpmailbox)[c]);
409 
410 			for (c++; c % 8 && c < sizeof(struct mailbox); c++) {
411 				printk(" %2.2X", ((unsigned char *) &tmpmailbox)[c]);
412 			}
413 		}
414 
415 		printk("\n");
416 #endif
417 
418 	spin_lock_irqsave(&apbs[IndexCard].mutex, flags);
419 
420 	/* Test octet ready correct */
421 	if(readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) > 2) {
422 		Dummy = readb(apbs[IndexCard].RamIO + VERS);
423 		spin_unlock_irqrestore(&apbs[IndexCard].mutex, flags);
424 		printk(KERN_WARNING "APPLICOM driver write error board %d, DataFromPcReady = %d\n",
425 		       IndexCard,(int)readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY));
426 		DeviceErrorCount++;
427 		return -EIO;
428 	}
429 
430 	/* Place ourselves on the wait queue */
431 	set_current_state(TASK_INTERRUPTIBLE);
432 	add_wait_queue(&apbs[IndexCard].FlagSleepSend, &wait);
433 
434 	/* Check whether the card is ready for us */
435 	while (readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) != 0) {
436 		Dummy = readb(apbs[IndexCard].RamIO + VERS);
437 		/* It's busy. Sleep. */
438 
439 		spin_unlock_irqrestore(&apbs[IndexCard].mutex, flags);
440 		schedule();
441 		if (signal_pending(current)) {
442 			remove_wait_queue(&apbs[IndexCard].FlagSleepSend,
443 					  &wait);
444 			return -EINTR;
445 		}
446 		spin_lock_irqsave(&apbs[IndexCard].mutex, flags);
447 		set_current_state(TASK_INTERRUPTIBLE);
448 	}
449 
450 	/* We may not have actually slept */
451 	set_current_state(TASK_RUNNING);
452 	remove_wait_queue(&apbs[IndexCard].FlagSleepSend, &wait);
453 
454 	writeb(1, apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
455 
456 	/* Which is best - lock down the pages with rawio and then
457 	   copy directly, or use bounce buffers? For now we do the latter
458 	   because it works with 2.2 still */
459 	{
460 		unsigned char *from = (unsigned char *) &tmpmailbox;
461 		void __iomem *to = apbs[IndexCard].RamIO + RAM_FROM_PC;
462 		int c;
463 
464 		for (c = 0; c < sizeof(struct mailbox); c++)
465 			writeb(*(from++), to++);
466 	}
467 
468 	writeb(0x20, apbs[IndexCard].RamIO + TIC_OWNER_FROM_PC);
469 	writeb(0xff, apbs[IndexCard].RamIO + NUMCARD_OWNER_FROM_PC);
470 	writeb(TicCard, apbs[IndexCard].RamIO + TIC_DES_FROM_PC);
471 	writeb(NumCard, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC);
472 	writeb(2, apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
473 	writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
474 	Dummy = readb(apbs[IndexCard].RamIO + VERS);
475 	spin_unlock_irqrestore(&apbs[IndexCard].mutex, flags);
476 	return 0;
477 }
478 
479 static int do_ac_read(int IndexCard, char __user *buf,
480 		struct st_ram_io *st_loc, struct mailbox *mailbox)
481 {
482 	void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC;
483 	unsigned char *to = (unsigned char *)mailbox;
484 #ifdef DEBUG
485 	int c;
486 #endif
487 
488 	st_loc->tic_owner_to_pc = readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC);
489 	st_loc->numcard_owner_to_pc = readb(apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC);
490 
491 
492 	{
493 		int c;
494 
495 		for (c = 0; c < sizeof(struct mailbox); c++)
496 			*(to++) = readb(from++);
497 	}
498 	writeb(1, apbs[IndexCard].RamIO + ACK_FROM_PC_READY);
499 	writeb(1, apbs[IndexCard].RamIO + TYP_ACK_FROM_PC);
500 	writeb(IndexCard+1, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC);
501 	writeb(readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC),
502 	       apbs[IndexCard].RamIO + TIC_ACK_FROM_PC);
503 	writeb(2, apbs[IndexCard].RamIO + ACK_FROM_PC_READY);
504 	writeb(0, apbs[IndexCard].RamIO + DATA_TO_PC_READY);
505 	writeb(2, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
506 	Dummy = readb(apbs[IndexCard].RamIO + VERS);
507 
508 #ifdef DEBUG
509 		printk("Read from applicom card #%d. struct st_ram_io follows:", NumCard);
510 
511 		for (c = 0; c < sizeof(struct st_ram_io);) {
512 			printk("\n%5.5X: %2.2X", c, ((unsigned char *)st_loc)[c]);
513 
514 			for (c++; c % 8 && c < sizeof(struct st_ram_io); c++) {
515 				printk(" %2.2X", ((unsigned char *)st_loc)[c]);
516 			}
517 		}
518 
519 		printk("\nstruct mailbox follows:");
520 
521 		for (c = 0; c < sizeof(struct mailbox);) {
522 			printk("\n%5.5X: %2.2X", c, ((unsigned char *)mailbox)[c]);
523 
524 			for (c++; c % 8 && c < sizeof(struct mailbox); c++) {
525 				printk(" %2.2X", ((unsigned char *)mailbox)[c]);
526 			}
527 		}
528 		printk("\n");
529 #endif
530 	return (sizeof(struct st_ram_io) + sizeof(struct mailbox));
531 }
532 
533 static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_t *ptr)
534 {
535 	unsigned long flags;
536 	unsigned int i;
537 	unsigned char tmp;
538 	int ret = 0;
539 	DECLARE_WAITQUEUE(wait, current);
540 #ifdef DEBUG
541 	int loopcount=0;
542 #endif
543 	/* No need to ratelimit this. Only root can trigger it anyway */
544 	if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) {
545 		printk( KERN_WARNING "Hmmm. read() of Applicom card, length %zd != expected %zd\n",
546 			count,sizeof(struct st_ram_io) + sizeof(struct mailbox));
547 		return -EINVAL;
548 	}
549 
550 	while(1) {
551 		/* Stick ourself on the wait queue */
552 		set_current_state(TASK_INTERRUPTIBLE);
553 		add_wait_queue(&FlagSleepRec, &wait);
554 
555 		/* Scan each board, looking for one which has a packet for us */
556 		for (i=0; i < MAX_BOARD; i++) {
557 			if (!apbs[i].RamIO)
558 				continue;
559 			spin_lock_irqsave(&apbs[i].mutex, flags);
560 
561 			tmp = readb(apbs[i].RamIO + DATA_TO_PC_READY);
562 
563 			if (tmp == 2) {
564 				struct st_ram_io st_loc;
565 				struct mailbox mailbox;
566 
567 				/* Got a packet for us */
568 				ret = do_ac_read(i, buf, &st_loc, &mailbox);
569 				spin_unlock_irqrestore(&apbs[i].mutex, flags);
570 				set_current_state(TASK_RUNNING);
571 				remove_wait_queue(&FlagSleepRec, &wait);
572 
573 				if (copy_to_user(buf, &st_loc, sizeof(st_loc)))
574 					return -EFAULT;
575 				if (copy_to_user(buf + sizeof(st_loc), &mailbox, sizeof(mailbox)))
576 					return -EFAULT;
577 				return tmp;
578 			}
579 
580 			if (tmp > 2) {
581 				/* Got an error */
582 				Dummy = readb(apbs[i].RamIO + VERS);
583 
584 				spin_unlock_irqrestore(&apbs[i].mutex, flags);
585 				set_current_state(TASK_RUNNING);
586 				remove_wait_queue(&FlagSleepRec, &wait);
587 
588 				printk(KERN_WARNING "APPLICOM driver read error board %d, DataToPcReady = %d\n",
589 				       i,(int)readb(apbs[i].RamIO + DATA_TO_PC_READY));
590 				DeviceErrorCount++;
591 				return -EIO;
592 			}
593 
594 			/* Nothing for us. Try the next board */
595 			Dummy = readb(apbs[i].RamIO + VERS);
596 			spin_unlock_irqrestore(&apbs[i].mutex, flags);
597 
598 		} /* per board */
599 
600 		/* OK - No boards had data for us. Sleep now */
601 
602 		schedule();
603 		remove_wait_queue(&FlagSleepRec, &wait);
604 
605 		if (signal_pending(current))
606 			return -EINTR;
607 
608 #ifdef DEBUG
609 		if (loopcount++ > 2) {
610 			printk(KERN_DEBUG "Looping in ac_read. loopcount %d\n", loopcount);
611 		}
612 #endif
613 	}
614 }
615 
616 static irqreturn_t ac_interrupt(int vec, void *dev_instance)
617 {
618 	unsigned int i;
619 	unsigned int FlagInt;
620 	unsigned int LoopCount;
621 	int handled = 0;
622 
623 	//    printk("Applicom interrupt on IRQ %d occurred\n", vec);
624 
625 	LoopCount = 0;
626 
627 	do {
628 		FlagInt = 0;
629 		for (i = 0; i < MAX_BOARD; i++) {
630 
631 			/* Skip if this board doesn't exist */
632 			if (!apbs[i].RamIO)
633 				continue;
634 
635 			spin_lock(&apbs[i].mutex);
636 
637 			/* Skip if this board doesn't want attention */
638 			if(readb(apbs[i].RamIO + RAM_IT_TO_PC) == 0) {
639 				spin_unlock(&apbs[i].mutex);
640 				continue;
641 			}
642 
643 			handled = 1;
644 			FlagInt = 1;
645 			writeb(0, apbs[i].RamIO + RAM_IT_TO_PC);
646 
647 			if (readb(apbs[i].RamIO + DATA_TO_PC_READY) > 2) {
648 				printk(KERN_WARNING "APPLICOM driver interrupt err board %d, DataToPcReady = %d\n",
649 				       i+1,(int)readb(apbs[i].RamIO + DATA_TO_PC_READY));
650 				DeviceErrorCount++;
651 			}
652 
653 			if((readb(apbs[i].RamIO + DATA_FROM_PC_READY) > 2) &&
654 			   (readb(apbs[i].RamIO + DATA_FROM_PC_READY) != 6)) {
655 
656 				printk(KERN_WARNING "APPLICOM driver interrupt err board %d, DataFromPcReady = %d\n",
657 				       i+1,(int)readb(apbs[i].RamIO + DATA_FROM_PC_READY));
658 				DeviceErrorCount++;
659 			}
660 
661 			if (readb(apbs[i].RamIO + DATA_TO_PC_READY) == 2) {	/* mailbox sent by the card ?   */
662 				if (waitqueue_active(&FlagSleepRec)) {
663 				wake_up_interruptible(&FlagSleepRec);
664 			}
665 			}
666 
667 			if (readb(apbs[i].RamIO + DATA_FROM_PC_READY) == 0) {	/* ram i/o free for write by pc ? */
668 				if (waitqueue_active(&apbs[i].FlagSleepSend)) {	/* process sleep during read ?    */
669 					wake_up_interruptible(&apbs[i].FlagSleepSend);
670 				}
671 			}
672 			Dummy = readb(apbs[i].RamIO + VERS);
673 
674 			if(readb(apbs[i].RamIO + RAM_IT_TO_PC)) {
675 				/* There's another int waiting on this card */
676 				spin_unlock(&apbs[i].mutex);
677 				i--;
678 			} else {
679 				spin_unlock(&apbs[i].mutex);
680 			}
681 		}
682 		if (FlagInt)
683 			LoopCount = 0;
684 		else
685 			LoopCount++;
686 	} while(LoopCount < 2);
687 	return IRQ_RETVAL(handled);
688 }
689 
690 
691 
692 static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
693 
694 {				/* @ ADG ou ATO selon le cas */
695 	int i;
696 	unsigned char IndexCard;
697 	void __iomem *pmem;
698 	int ret = 0;
699 	volatile unsigned char byte_reset_it;
700 	struct st_ram_io *adgl;
701 	void __user *argp = (void __user *)arg;
702 
703 	/* In general, the device is only openable by root anyway, so we're not
704 	   particularly concerned that bogus ioctls can flood the console. */
705 
706 	adgl = kmalloc(sizeof(struct st_ram_io), GFP_KERNEL);
707 	if (!adgl)
708 		return -ENOMEM;
709 
710 	if (copy_from_user(adgl, argp, sizeof(struct st_ram_io))) {
711 		kfree(adgl);
712 		return -EFAULT;
713 	}
714 
715 	IndexCard = adgl->num_card-1;
716 
717 	if(cmd != 6 && ((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) {
718 		static int warncount = 10;
719 		if (warncount) {
720 			printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1);
721 			warncount--;
722 		}
723 		kfree(adgl);
724 		return -EINVAL;
725 	}
726 
727 	switch (cmd) {
728 
729 	case 0:
730 		pmem = apbs[IndexCard].RamIO;
731 		for (i = 0; i < sizeof(struct st_ram_io); i++)
732 			((unsigned char *)adgl)[i]=readb(pmem++);
733 		if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
734 			ret = -EFAULT;
735 		break;
736 	case 1:
737 		pmem = apbs[IndexCard].RamIO + CONF_END_TEST;
738 		for (i = 0; i < 4; i++)
739 			adgl->conf_end_test[i] = readb(pmem++);
740 		for (i = 0; i < 2; i++)
741 			adgl->error_code[i] = readb(pmem++);
742 		for (i = 0; i < 4; i++)
743 			adgl->parameter_error[i] = readb(pmem++);
744 		pmem = apbs[IndexCard].RamIO + VERS;
745 		adgl->vers = readb(pmem);
746 		pmem = apbs[IndexCard].RamIO + TYPE_CARD;
747 		for (i = 0; i < 20; i++)
748 			adgl->reserv1[i] = readb(pmem++);
749 		*(int *)&adgl->reserv1[20] =
750 			(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER) << 16) +
751 			(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) +
752 			(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2) );
753 
754 		if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
755 			ret = -EFAULT;
756 		break;
757 	case 2:
758 		pmem = apbs[IndexCard].RamIO + CONF_END_TEST;
759 		for (i = 0; i < 10; i++)
760 			writeb(0xff, pmem++);
761 		writeb(adgl->data_from_pc_ready,
762 		       apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
763 
764 		writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
765 
766 		for (i = 0; i < MAX_BOARD; i++) {
767 			if (apbs[i].RamIO) {
768 				byte_reset_it = readb(apbs[i].RamIO + RAM_IT_TO_PC);
769 			}
770 		}
771 		break;
772 	case 3:
773 		pmem = apbs[IndexCard].RamIO + TIC_DES_FROM_PC;
774 		writeb(adgl->tic_des_from_pc, pmem);
775 		break;
776 	case 4:
777 		pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC;
778 		adgl->tic_owner_to_pc     = readb(pmem++);
779 		adgl->numcard_owner_to_pc = readb(pmem);
780 		if (copy_to_user(argp, adgl,sizeof(struct st_ram_io)))
781 			ret = -EFAULT;
782 		break;
783 	case 5:
784 		writeb(adgl->num_card, apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC);
785 		writeb(adgl->num_card, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC);
786 		writeb(adgl->num_card, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC);
787 		writeb(4, apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
788 		writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
789 		break;
790 	case 6:
791 		printk(KERN_INFO "APPLICOM driver release .... V2.8.0 ($Revision: 1.30 $)\n");
792 		printk(KERN_INFO "Number of installed boards . %d\n", (int) numboards);
793 		printk(KERN_INFO "Segment of board ........... %X\n", (int) mem);
794 		printk(KERN_INFO "Interrupt IRQ number ....... %d\n", (int) irq);
795 		for (i = 0; i < MAX_BOARD; i++) {
796 			int serial;
797 			char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1];
798 
799 			if (!apbs[i].RamIO)
800 				continue;
801 
802 			for (serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++)
803 				boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial);
804 			boardname[serial] = 0;
805 
806 			printk(KERN_INFO "Prom version board %d ....... V%d.%d %s",
807 			       i+1,
808 			       (int)(readb(apbs[IndexCard].RamIO + VERS) >> 4),
809 			       (int)(readb(apbs[IndexCard].RamIO + VERS) & 0xF),
810 			       boardname);
811 
812 
813 			serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) +
814 				(readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) +
815 				(readb(apbs[i].RamIO + SERIAL_NUMBER + 2) );
816 
817 			if (serial != 0)
818 				printk(" S/N %d\n", serial);
819 			else
820 				printk("\n");
821 		}
822 		if (DeviceErrorCount != 0)
823 			printk(KERN_INFO "DeviceErrorCount ........... %d\n", DeviceErrorCount);
824 		if (ReadErrorCount != 0)
825 			printk(KERN_INFO "ReadErrorCount ............. %d\n", ReadErrorCount);
826 		if (WriteErrorCount != 0)
827 			printk(KERN_INFO "WriteErrorCount ............ %d\n", WriteErrorCount);
828 		if (waitqueue_active(&FlagSleepRec))
829 			printk(KERN_INFO "Process in read pending\n");
830 		for (i = 0; i < MAX_BOARD; i++) {
831 			if (apbs[i].RamIO && waitqueue_active(&apbs[i].FlagSleepSend))
832 				printk(KERN_INFO "Process in write pending board %d\n",i+1);
833 		}
834 		break;
835 	default:
836 		ret = -ENOTTY;
837 		break;
838 	}
839 	Dummy = readb(apbs[IndexCard].RamIO + VERS);
840 	kfree(adgl);
841 	return 0;
842 }
843 
844