aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/stallion.c207
1 files changed, 40 insertions, 167 deletions
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 596e69c2fd0c..4ccf4a5834c9 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -41,13 +41,12 @@
41#include <linux/smp_lock.h> 41#include <linux/smp_lock.h>
42#include <linux/device.h> 42#include <linux/device.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/ctype.h>
44 45
45#include <asm/io.h> 46#include <asm/io.h>
46#include <asm/uaccess.h> 47#include <asm/uaccess.h>
47 48
48#ifdef CONFIG_PCI
49#include <linux/pci.h> 49#include <linux/pci.h>
50#endif
51 50
52/*****************************************************************************/ 51/*****************************************************************************/
53 52
@@ -63,43 +62,16 @@
63#define BRD_ECH64PCI 27 62#define BRD_ECH64PCI 27
64#define BRD_EASYIOPCI 28 63#define BRD_EASYIOPCI 28
65 64
66/* 65struct stlconf {
67 * Define a configuration structure to hold the board configuration.
68 * Need to set this up in the code (for now) with the boards that are
69 * to be configured into the system. This is what needs to be modified
70 * when adding/removing/modifying boards. Each line entry in the
71 * stl_brdconf[] array is a board. Each line contains io/irq/memory
72 * ranges for that board (as well as what type of board it is).
73 * Some examples:
74 * { BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },
75 * This line would configure an EasyIO board (4 or 8, no difference),
76 * at io address 2a0 and irq 10.
77 * Another example:
78 * { BRD_ECH, 0x2a8, 0x280, 0, 12, 0 },
79 * This line will configure an EasyConnection 8/32 board at primary io
80 * address 2a8, secondary io address 280 and irq 12.
81 * Enter as many lines into this array as you want (only the first 4
82 * will actually be used!). Any combination of EasyIO and EasyConnection
83 * boards can be specified. EasyConnection 8/32 boards can share their
84 * secondary io addresses between each other.
85 *
86 * NOTE: there is no need to put any entries in this table for PCI
87 * boards. They will be found automatically by the driver - provided
88 * PCI BIOS32 support is compiled into the kernel.
89 */
90
91static struct stlconf {
92 int brdtype; 66 int brdtype;
93 int ioaddr1; 67 int ioaddr1;
94 int ioaddr2; 68 int ioaddr2;
95 unsigned long memaddr; 69 unsigned long memaddr;
96 int irq; 70 int irq;
97 int irqtype; 71 int irqtype;
98} stl_brdconf[] = {
99 /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/
100}; 72};
101 73
102static int stl_nrbrds = ARRAY_SIZE(stl_brdconf); 74static unsigned int stl_nrbrds;
103 75
104/*****************************************************************************/ 76/*****************************************************************************/
105 77
@@ -432,15 +404,6 @@ static unsigned int stl_baudrates[] = {
432 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 404 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
433}; 405};
434 406
435/*
436 * Define some handy local macros...
437 */
438#undef MIN
439#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
440
441#undef TOLOWER
442#define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x))
443
444/*****************************************************************************/ 407/*****************************************************************************/
445 408
446/* 409/*
@@ -660,42 +623,6 @@ static struct class *stallion_class;
660/*****************************************************************************/ 623/*****************************************************************************/
661 624
662/* 625/*
663 * Convert an ascii string number into an unsigned long.
664 */
665
666static unsigned long stl_atol(char *str)
667{
668 unsigned long val;
669 int base, c;
670 char *sp;
671
672 val = 0;
673 sp = str;
674 if ((*sp == '0') && (*(sp+1) == 'x')) {
675 base = 16;
676 sp += 2;
677 } else if (*sp == '0') {
678 base = 8;
679 sp++;
680 } else {
681 base = 10;
682 }
683
684 for (; (*sp != 0); sp++) {
685 c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0');
686 if ((c < 0) || (c >= base)) {
687 printk("STALLION: invalid argument %s\n", str);
688 val = 0;
689 break;
690 }
691 val = (val * base) + c;
692 }
693 return val;
694}
695
696/*****************************************************************************/
697
698/*
699 * Parse the supplied argument string, into the board conf struct. 626 * Parse the supplied argument string, into the board conf struct.
700 */ 627 */
701 628
@@ -710,7 +637,7 @@ static int __init stl_parsebrd(struct stlconf *confp, char **argp)
710 return 0; 637 return 0;
711 638
712 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) 639 for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++)
713 *sp = TOLOWER(*sp); 640 *sp = tolower(*sp);
714 641
715 for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) { 642 for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) {
716 if (strcmp(stl_brdstr[i].name, argp[0]) == 0) 643 if (strcmp(stl_brdstr[i].name, argp[0]) == 0)
@@ -725,15 +652,15 @@ static int __init stl_parsebrd(struct stlconf *confp, char **argp)
725 652
726 i = 1; 653 i = 1;
727 if ((argp[i] != NULL) && (*argp[i] != 0)) 654 if ((argp[i] != NULL) && (*argp[i] != 0))
728 confp->ioaddr1 = stl_atol(argp[i]); 655 confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0);
729 i++; 656 i++;
730 if (confp->brdtype == BRD_ECH) { 657 if (confp->brdtype == BRD_ECH) {
731 if ((argp[i] != NULL) && (*argp[i] != 0)) 658 if ((argp[i] != NULL) && (*argp[i] != 0))
732 confp->ioaddr2 = stl_atol(argp[i]); 659 confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0);
733 i++; 660 i++;
734 } 661 }
735 if ((argp[i] != NULL) && (*argp[i] != 0)) 662 if ((argp[i] != NULL) && (*argp[i] != 0))
736 confp->irq = stl_atol(argp[i]); 663 confp->irq = simple_strtoul(argp[i], NULL, 0);
737 return 1; 664 return 1;
738} 665}
739 666
@@ -758,32 +685,6 @@ static struct stlbrd *stl_allocbrd(void)
758 return brdp; 685 return brdp;
759} 686}
760 687
761static void __init stl_argbrds(void)
762{
763 struct stlconf conf;
764 struct stlbrd *brdp;
765 int i;
766
767 pr_debug("stl_argbrds()\n");
768
769 for (i = stl_nrbrds; (i < stl_nargs); i++) {
770 memset(&conf, 0, sizeof(conf));
771 if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
772 continue;
773 if ((brdp = stl_allocbrd()) == NULL)
774 continue;
775 stl_nrbrds = i + 1;
776 brdp->brdnr = i;
777 brdp->brdtype = conf.brdtype;
778 brdp->ioaddr1 = conf.ioaddr1;
779 brdp->ioaddr2 = conf.ioaddr2;
780 brdp->irq = conf.irq;
781 brdp->irqtype = conf.irqtype;
782 if (stl_brdinit(brdp))
783 kfree(brdp);
784 }
785}
786
787/*****************************************************************************/ 688/*****************************************************************************/
788 689
789static int stl_open(struct tty_struct *tty, struct file *filp) 690static int stl_open(struct tty_struct *tty, struct file *filp)
@@ -1089,10 +990,10 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count
1089 stlen = len; 990 stlen = len;
1090 } 991 }
1091 992
1092 len = MIN(len, count); 993 len = min(len, (unsigned int)count);
1093 count = 0; 994 count = 0;
1094 while (len > 0) { 995 while (len > 0) {
1095 stlen = MIN(len, stlen); 996 stlen = min(len, stlen);
1096 memcpy(head, chbuf, stlen); 997 memcpy(head, chbuf, stlen);
1097 len -= stlen; 998 len -= stlen;
1098 chbuf += stlen; 999 chbuf += stlen;
@@ -2550,56 +2451,6 @@ static struct pci_driver stl_pcidriver = {
2550/*****************************************************************************/ 2451/*****************************************************************************/
2551 2452
2552/* 2453/*
2553 * Scan through all the boards in the configuration and see what we
2554 * can find. Handle EIO and the ECH boards a little differently here
2555 * since the initial search and setup is too different.
2556 */
2557
2558static int __init stl_initbrds(void)
2559{
2560 struct stlbrd *brdp;
2561 struct stlconf *confp;
2562 int i;
2563
2564 pr_debug("stl_initbrds()\n");
2565
2566 if (stl_nrbrds > STL_MAXBRDS) {
2567 printk("STALLION: too many boards in configuration table, "
2568 "truncating to %d\n", STL_MAXBRDS);
2569 stl_nrbrds = STL_MAXBRDS;
2570 }
2571
2572/*
2573 * Firstly scan the list of static boards configured. Allocate
2574 * resources and initialize the boards as found.
2575 */
2576 for (i = 0; (i < stl_nrbrds); i++) {
2577 confp = &stl_brdconf[i];
2578 stl_parsebrd(confp, stl_brdsp[i]);
2579 if ((brdp = stl_allocbrd()) == NULL)
2580 return(-ENOMEM);
2581 brdp->brdnr = i;
2582 brdp->brdtype = confp->brdtype;
2583 brdp->ioaddr1 = confp->ioaddr1;
2584 brdp->ioaddr2 = confp->ioaddr2;
2585 brdp->irq = confp->irq;
2586 brdp->irqtype = confp->irqtype;
2587 if (stl_brdinit(brdp))
2588 kfree(brdp);
2589 }
2590
2591/*
2592 * Find any dynamically supported boards. That is via module load
2593 * line options or auto-detected on the PCI bus.
2594 */
2595 stl_argbrds();
2596
2597 return(0);
2598}
2599
2600/*****************************************************************************/
2601
2602/*
2603 * Return the board stats structure to user app. 2454 * Return the board stats structure to user app.
2604 */ 2455 */
2605 2456
@@ -3691,9 +3542,9 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
3691 } 3542 }
3692 outb(srer, (ioaddr + EREG_DATA)); 3543 outb(srer, (ioaddr + EREG_DATA));
3693 } else { 3544 } else {
3694 len = MIN(len, CD1400_TXFIFOSIZE); 3545 len = min(len, CD1400_TXFIFOSIZE);
3695 portp->stats.txtotal += len; 3546 portp->stats.txtotal += len;
3696 stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail)); 3547 stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
3697 outb((TDR + portp->uartaddr), ioaddr); 3548 outb((TDR + portp->uartaddr), ioaddr);
3698 outsb((ioaddr + EREG_DATA), tail, stlen); 3549 outsb((ioaddr + EREG_DATA), tail, stlen);
3699 len -= stlen; 3550 len -= stlen;
@@ -3746,13 +3597,13 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3746 outb((RDCR + portp->uartaddr), ioaddr); 3597 outb((RDCR + portp->uartaddr), ioaddr);
3747 len = inb(ioaddr + EREG_DATA); 3598 len = inb(ioaddr + EREG_DATA);
3748 if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { 3599 if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
3749 len = MIN(len, sizeof(stl_unwanted)); 3600 len = min(len, sizeof(stl_unwanted));
3750 outb((RDSR + portp->uartaddr), ioaddr); 3601 outb((RDSR + portp->uartaddr), ioaddr);
3751 insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); 3602 insb((ioaddr + EREG_DATA), &stl_unwanted[0], len);
3752 portp->stats.rxlost += len; 3603 portp->stats.rxlost += len;
3753 portp->stats.rxtotal += len; 3604 portp->stats.rxtotal += len;
3754 } else { 3605 } else {
3755 len = MIN(len, buflen); 3606 len = min(len, buflen);
3756 if (len > 0) { 3607 if (len > 0) {
3757 unsigned char *ptr; 3608 unsigned char *ptr;
3758 outb((RDSR + portp->uartaddr), ioaddr); 3609 outb((RDSR + portp->uartaddr), ioaddr);
@@ -4615,9 +4466,9 @@ static void stl_sc26198txisr(struct stlport *portp)
4615 outb(mr0, (ioaddr + XP_DATA)); 4466 outb(mr0, (ioaddr + XP_DATA));
4616 } 4467 }
4617 } else { 4468 } else {
4618 len = MIN(len, SC26198_TXFIFOSIZE); 4469 len = min(len, SC26198_TXFIFOSIZE);
4619 portp->stats.txtotal += len; 4470 portp->stats.txtotal += len;
4620 stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail)); 4471 stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail));
4621 outb(GTXFIFO, (ioaddr + XP_ADDR)); 4472 outb(GTXFIFO, (ioaddr + XP_ADDR));
4622 outsb((ioaddr + XP_DATA), tail, stlen); 4473 outsb((ioaddr + XP_DATA), tail, stlen);
4623 len -= stlen; 4474 len -= stlen;
@@ -4658,13 +4509,13 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
4658 4509
4659 if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { 4510 if ((iack & IVR_TYPEMASK) == IVR_RXDATA) {
4660 if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { 4511 if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) {
4661 len = MIN(len, sizeof(stl_unwanted)); 4512 len = min(len, sizeof(stl_unwanted));
4662 outb(GRXFIFO, (ioaddr + XP_ADDR)); 4513 outb(GRXFIFO, (ioaddr + XP_ADDR));
4663 insb((ioaddr + XP_DATA), &stl_unwanted[0], len); 4514 insb((ioaddr + XP_DATA), &stl_unwanted[0], len);
4664 portp->stats.rxlost += len; 4515 portp->stats.rxlost += len;
4665 portp->stats.rxtotal += len; 4516 portp->stats.rxtotal += len;
4666 } else { 4517 } else {
4667 len = MIN(len, buflen); 4518 len = min(len, buflen);
4668 if (len > 0) { 4519 if (len > 0) {
4669 unsigned char *ptr; 4520 unsigned char *ptr;
4670 outb(GRXFIFO, (ioaddr + XP_ADDR)); 4521 outb(GRXFIFO, (ioaddr + XP_ADDR));
@@ -4831,6 +4682,8 @@ static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack)
4831 */ 4682 */
4832static int __init stallion_module_init(void) 4683static int __init stallion_module_init(void)
4833{ 4684{
4685 struct stlbrd *brdp;
4686 struct stlconf conf;
4834 unsigned int i, retval; 4687 unsigned int i, retval;
4835 4688
4836 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); 4689 printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion);
@@ -4838,7 +4691,27 @@ static int __init stallion_module_init(void)
4838 spin_lock_init(&stallion_lock); 4691 spin_lock_init(&stallion_lock);
4839 spin_lock_init(&brd_lock); 4692 spin_lock_init(&brd_lock);
4840 4693
4841 stl_initbrds(); 4694/*
4695 * Find any dynamically supported boards. That is via module load
4696 * line options.
4697 */
4698 for (i = stl_nrbrds; i < stl_nargs; i++) {
4699 memset(&conf, 0, sizeof(conf));
4700 if (stl_parsebrd(&conf, stl_brdsp[i]) == 0)
4701 continue;
4702 if ((brdp = stl_allocbrd()) == NULL)
4703 continue;
4704 brdp->brdnr = i;
4705 brdp->brdtype = conf.brdtype;
4706 brdp->ioaddr1 = conf.ioaddr1;
4707 brdp->ioaddr2 = conf.ioaddr2;
4708 brdp->irq = conf.irq;
4709 brdp->irqtype = conf.irqtype;
4710 if (stl_brdinit(brdp))
4711 kfree(brdp);
4712 else
4713 stl_nrbrds = i + 1;
4714 }
4842 4715
4843 retval = pci_register_driver(&stl_pcidriver); 4716 retval = pci_register_driver(&stl_pcidriver);
4844 if (retval) 4717 if (retval)