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