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