diff options
Diffstat (limited to 'drivers/char/stallion.c')
-rw-r--r-- | drivers/char/stallion.c | 207 |
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 | /* | 65 | struct 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 | |||
91 | static 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 | ||
102 | static int stl_nrbrds = ARRAY_SIZE(stl_brdconf); | 74 | static 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 | |||
666 | static 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 | ||
761 | static 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 | ||
789 | static int stl_open(struct tty_struct *tty, struct file *filp) | 690 | static 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 | |||
2558 | static 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 | */ |
4832 | static int __init stallion_module_init(void) | 4683 | static 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) |