diff options
Diffstat (limited to 'drivers/char')
80 files changed, 12466 insertions, 8126 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 24f922f12783..b10f4d8fdc7f 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -201,6 +201,21 @@ config MOXA_SMARTIO | |||
201 | The module will be called mxser. If you want to do that, say M | 201 | The module will be called mxser. If you want to do that, say M |
202 | here. | 202 | here. |
203 | 203 | ||
204 | config MOXA_SMARTIO_NEW | ||
205 | tristate "Moxa SmartIO support v. 2.0 (EXPERIMENTAL)" | ||
206 | depends on SERIAL_NONSTANDARD | ||
207 | help | ||
208 | Say Y here if you have a Moxa SmartIO multiport serial card and/or | ||
209 | want to help develop a new version of this driver. | ||
210 | |||
211 | This is upgraded (1.9.1) driver from original Moxa drivers with | ||
212 | changes finally resulting in PCI probing. | ||
213 | |||
214 | Use at your own risk. | ||
215 | |||
216 | This driver can also be built as a module. The module will be called | ||
217 | mxser_new. If you want to do that, say M here. | ||
218 | |||
204 | config ISI | 219 | config ISI |
205 | tristate "Multi-Tech multiport card support (EXPERIMENTAL)" | 220 | tristate "Multi-Tech multiport card support (EXPERIMENTAL)" |
206 | depends on SERIAL_NONSTANDARD | 221 | depends on SERIAL_NONSTANDARD |
diff --git a/drivers/char/Makefile b/drivers/char/Makefile index b1fcdab90947..fc110637ced6 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_MOXA_INTELLIO) += moxa.o | |||
31 | obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o | 31 | obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o |
32 | obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o | 32 | obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o |
33 | obj-$(CONFIG_MOXA_SMARTIO) += mxser.o | 33 | obj-$(CONFIG_MOXA_SMARTIO) += mxser.o |
34 | obj-$(CONFIG_MOXA_SMARTIO_NEW) += mxser_new.o | ||
34 | obj-$(CONFIG_COMPUTONE) += ip2/ | 35 | obj-$(CONFIG_COMPUTONE) += ip2/ |
35 | obj-$(CONFIG_RISCOM8) += riscom8.o | 36 | obj-$(CONFIG_RISCOM8) += riscom8.o |
36 | obj-$(CONFIG_ISI) += isicom.o | 37 | obj-$(CONFIG_ISI) += isicom.o |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 00b17ae39736..2f2c4efff8a3 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
@@ -459,7 +459,7 @@ static const struct aper_size_info_32 nforce3_sizes[5] = | |||
459 | 459 | ||
460 | /* Handle shadow device of the Nvidia NForce3 */ | 460 | /* Handle shadow device of the Nvidia NForce3 */ |
461 | /* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */ | 461 | /* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */ |
462 | static int __devinit nforce3_agp_init(struct pci_dev *pdev) | 462 | static int nforce3_agp_init(struct pci_dev *pdev) |
463 | { | 463 | { |
464 | u32 tmp, apbase, apbar, aplimit; | 464 | u32 tmp, apbase, apbar, aplimit; |
465 | struct pci_dev *dev1; | 465 | struct pci_dev *dev1; |
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c index 66086fa2d59a..feb4ac802a0d 100644 --- a/drivers/char/amiserial.c +++ b/drivers/char/amiserial.c | |||
@@ -104,7 +104,7 @@ static struct async_struct *IRQ_ports; | |||
104 | 104 | ||
105 | static unsigned char current_ctl_bits; | 105 | static unsigned char current_ctl_bits; |
106 | 106 | ||
107 | static void change_speed(struct async_struct *info, struct termios *old); | 107 | static void change_speed(struct async_struct *info, struct ktermios *old); |
108 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); | 108 | static void rs_wait_until_sent(struct tty_struct *tty, int timeout); |
109 | 109 | ||
110 | 110 | ||
@@ -694,7 +694,7 @@ static void shutdown(struct async_struct * info) | |||
694 | * the specified baud rate for a serial port. | 694 | * the specified baud rate for a serial port. |
695 | */ | 695 | */ |
696 | static void change_speed(struct async_struct *info, | 696 | static void change_speed(struct async_struct *info, |
697 | struct termios *old_termios) | 697 | struct ktermios *old_termios) |
698 | { | 698 | { |
699 | int quot = 0, baud_base, baud; | 699 | int quot = 0, baud_base, baud; |
700 | unsigned cflag, cval = 0; | 700 | unsigned cflag, cval = 0; |
@@ -1365,7 +1365,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1365 | return 0; | 1365 | return 0; |
1366 | } | 1366 | } |
1367 | 1367 | ||
1368 | static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) | 1368 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
1369 | { | 1369 | { |
1370 | struct async_struct *info = (struct async_struct *)tty->driver_data; | 1370 | struct async_struct *info = (struct async_struct *)tty->driver_data; |
1371 | unsigned long flags; | 1371 | unsigned long flags; |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 8ce3f34cfc22..c02d9e99e050 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -82,7 +82,7 @@ static inline u32 cs5535_lowhigh_base(int reg) | |||
82 | static ssize_t cs5535_gpio_write(struct file *file, const char __user *data, | 82 | static ssize_t cs5535_gpio_write(struct file *file, const char __user *data, |
83 | size_t len, loff_t *ppos) | 83 | size_t len, loff_t *ppos) |
84 | { | 84 | { |
85 | u32 m = iminor(file->f_dentry->d_inode); | 85 | u32 m = iminor(file->f_path.dentry->d_inode); |
86 | int i, j; | 86 | int i, j; |
87 | u32 base = gpio_base + cs5535_lowhigh_base(m); | 87 | u32 base = gpio_base + cs5535_lowhigh_base(m); |
88 | u32 m0, m1; | 88 | u32 m0, m1; |
@@ -117,7 +117,7 @@ static ssize_t cs5535_gpio_write(struct file *file, const char __user *data, | |||
117 | static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, | 117 | static ssize_t cs5535_gpio_read(struct file *file, char __user *buf, |
118 | size_t len, loff_t *ppos) | 118 | size_t len, loff_t *ppos) |
119 | { | 119 | { |
120 | u32 m = iminor(file->f_dentry->d_inode); | 120 | u32 m = iminor(file->f_path.dentry->d_inode); |
121 | u32 base = gpio_base + cs5535_lowhigh_base(m); | 121 | u32 base = gpio_base + cs5535_lowhigh_base(m); |
122 | int rd_bit = 1 << (m & 0x0f); | 122 | int rd_bit = 1 << (m & 0x0f); |
123 | int i; | 123 | int i; |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index acb2de5e3a98..3ffa0807754c 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
@@ -1,8 +1,6 @@ | |||
1 | #undef BLOCKMOVE | 1 | #undef BLOCKMOVE |
2 | #define Z_WAKE | 2 | #define Z_WAKE |
3 | #undef Z_EXT_CHARS_IN_BUFFER | 3 | #undef Z_EXT_CHARS_IN_BUFFER |
4 | static char rcsid[] = | ||
5 | "$Revision: 2.3.2.20 $$Date: 2004/02/25 18:14:16 $"; | ||
6 | 4 | ||
7 | /* | 5 | /* |
8 | * linux/drivers/char/cyclades.c | 6 | * linux/drivers/char/cyclades.c |
@@ -593,18 +591,20 @@ static char rcsid[] = | |||
593 | * | 591 | * |
594 | */ | 592 | */ |
595 | 593 | ||
594 | #define CY_VERSION "2.4" | ||
595 | |||
596 | /* If you need to install more boards than NR_CARDS, change the constant | 596 | /* If you need to install more boards than NR_CARDS, change the constant |
597 | in the definition below. No other change is necessary to support up to | 597 | in the definition below. No other change is necessary to support up to |
598 | eight boards. Beyond that you'll have to extend cy_isa_addresses. */ | 598 | eight boards. Beyond that you'll have to extend cy_isa_addresses. */ |
599 | 599 | ||
600 | #define NR_CARDS 4 | 600 | #define NR_CARDS 4 |
601 | 601 | ||
602 | /* | 602 | /* |
603 | If the total number of ports is larger than NR_PORTS, change this | 603 | If the total number of ports is larger than NR_PORTS, change this |
604 | constant in the definition below. No other change is necessary to | 604 | constant in the definition below. No other change is necessary to |
605 | support more boards/ports. */ | 605 | support more boards/ports. */ |
606 | 606 | ||
607 | #define NR_PORTS 256 | 607 | #define NR_PORTS 256 |
608 | 608 | ||
609 | #define ZE_V1_NPORTS 64 | 609 | #define ZE_V1_NPORTS 64 |
610 | #define ZO_V1 0 | 610 | #define ZO_V1 0 |
@@ -625,9 +625,9 @@ static char rcsid[] = | |||
625 | #undef CY_PCI_DEBUG | 625 | #undef CY_PCI_DEBUG |
626 | 626 | ||
627 | #if 0 | 627 | #if 0 |
628 | #define PAUSE __asm__("nop"); | 628 | #define PAUSE __asm__("nop") |
629 | #else | 629 | #else |
630 | #define PAUSE ; | 630 | #define PAUSE do {} while (0) |
631 | #endif | 631 | #endif |
632 | 632 | ||
633 | /* | 633 | /* |
@@ -663,7 +663,7 @@ static char rcsid[] = | |||
663 | do { \ | 663 | do { \ |
664 | spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \ | 664 | spin_lock_irqsave(&cy_card[info->card].card_lock, flags); \ |
665 | } while (0) | 665 | } while (0) |
666 | 666 | ||
667 | #define CY_UNLOCK(info,flags) \ | 667 | #define CY_UNLOCK(info,flags) \ |
668 | do { \ | 668 | do { \ |
669 | spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \ | 669 | spin_unlock_irqrestore(&cy_card[info->card].card_lock, flags); \ |
@@ -676,14 +676,14 @@ static char rcsid[] = | |||
676 | #include <linux/stat.h> | 676 | #include <linux/stat.h> |
677 | #include <linux/proc_fs.h> | 677 | #include <linux/proc_fs.h> |
678 | 678 | ||
679 | static void cy_throttle (struct tty_struct *tty); | 679 | static void cy_throttle(struct tty_struct *tty); |
680 | static void cy_send_xchar (struct tty_struct *tty, char ch); | 680 | static void cy_send_xchar(struct tty_struct *tty, char ch); |
681 | 681 | ||
682 | #define IS_CYC_Z(card) ((card).num_chips == -1) | 682 | #define IS_CYC_Z(card) ((card).num_chips == -1) |
683 | 683 | ||
684 | #define Z_FPGA_CHECK(card) \ | 684 | #define Z_FPGA_CHECK(card) \ |
685 | ((cy_readl(&((struct RUNTIME_9060 __iomem *) \ | 685 | ((cy_readl(&((struct RUNTIME_9060 __iomem *) \ |
686 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) | 686 | ((card).ctl_addr))->init_ctrl) & (1<<17)) != 0) |
687 | 687 | ||
688 | #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \ | 688 | #define ISZLOADED(card) (((ZO_V1==cy_readl(&((struct RUNTIME_9060 __iomem *) \ |
689 | ((card).ctl_addr))->mail_box_0)) || \ | 689 | ((card).ctl_addr))->mail_box_0)) || \ |
@@ -698,8 +698,6 @@ static void cy_send_xchar (struct tty_struct *tty, char ch); | |||
698 | 698 | ||
699 | #define STD_COM_FLAGS (0) | 699 | #define STD_COM_FLAGS (0) |
700 | 700 | ||
701 | #define JIFFIES_DIFF(n, j) ((j) - (n)) | ||
702 | |||
703 | static struct tty_driver *cy_serial_driver; | 701 | static struct tty_driver *cy_serial_driver; |
704 | 702 | ||
705 | #ifdef CONFIG_ISA | 703 | #ifdef CONFIG_ISA |
@@ -713,27 +711,28 @@ static struct tty_driver *cy_serial_driver; | |||
713 | */ | 711 | */ |
714 | 712 | ||
715 | static unsigned int cy_isa_addresses[] = { | 713 | static unsigned int cy_isa_addresses[] = { |
716 | 0xD0000, | 714 | 0xD0000, |
717 | 0xD2000, | 715 | 0xD2000, |
718 | 0xD4000, | 716 | 0xD4000, |
719 | 0xD6000, | 717 | 0xD6000, |
720 | 0xD8000, | 718 | 0xD8000, |
721 | 0xDA000, | 719 | 0xDA000, |
722 | 0xDC000, | 720 | 0xDC000, |
723 | 0xDE000, | 721 | 0xDE000, |
724 | 0,0,0,0,0,0,0,0 | 722 | 0, 0, 0, 0, 0, 0, 0, 0 |
725 | }; | 723 | }; |
724 | |||
726 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) | 725 | #define NR_ISA_ADDRS ARRAY_SIZE(cy_isa_addresses) |
727 | 726 | ||
728 | #ifdef MODULE | 727 | #ifdef MODULE |
729 | static long maddr[NR_CARDS] = { 0, }; | 728 | static long maddr[NR_CARDS] = { 0, }; |
730 | static int irq[NR_CARDS] = { 0, }; | 729 | static int irq[NR_CARDS] = { 0, }; |
731 | 730 | ||
732 | module_param_array(maddr, long, NULL, 0); | 731 | module_param_array(maddr, long, NULL, 0); |
733 | module_param_array(irq, int, NULL, 0); | 732 | module_param_array(irq, int, NULL, 0); |
734 | #endif | 733 | #endif |
735 | 734 | ||
736 | #endif /* CONFIG_ISA */ | 735 | #endif /* CONFIG_ISA */ |
737 | 736 | ||
738 | /* This is the per-card data structure containing address, irq, number of | 737 | /* This is the per-card data structure containing address, irq, number of |
739 | channels, etc. This driver supports a maximum of NR_CARDS cards. | 738 | channels, etc. This driver supports a maximum of NR_CARDS cards. |
@@ -745,7 +744,7 @@ static struct cyclades_card cy_card[NR_CARDS]; | |||
745 | */ | 744 | */ |
746 | static struct cyclades_port cy_port[NR_PORTS]; | 745 | static struct cyclades_port cy_port[NR_PORTS]; |
747 | 746 | ||
748 | static int cy_next_channel; /* next minor available */ | 747 | static int cy_next_channel; /* next minor available */ |
749 | 748 | ||
750 | /* | 749 | /* |
751 | * This is used to look up the divisor speeds and the timeouts | 750 | * This is used to look up the divisor speeds and the timeouts |
@@ -757,36 +756,42 @@ static int cy_next_channel; /* next minor available */ | |||
757 | * 20 | 756 | * 20 |
758 | */ | 757 | */ |
759 | static int baud_table[] = { | 758 | static int baud_table[] = { |
760 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, | 759 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, |
761 | 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800,115200,150000, | 760 | 1800, 2400, 4800, 9600, 19200, 38400, 57600, 76800, 115200, 150000, |
762 | 230400, 0}; | 761 | 230400, 0 |
763 | 762 | }; | |
764 | static char baud_co_25[] = { /* 25 MHz clock option table */ | 763 | |
765 | /* value => 00 01 02 03 04 */ | 764 | static char baud_co_25[] = { /* 25 MHz clock option table */ |
766 | /* divide by 8 32 128 512 2048 */ | 765 | /* value => 00 01 02 03 04 */ |
767 | 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, | 766 | /* divide by 8 32 128 512 2048 */ |
768 | 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | 767 | 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, |
769 | 768 | 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | |
770 | static char baud_bpr_25[] = { /* 25 MHz baud rate period table */ | 769 | }; |
771 | 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, | 770 | |
772 | 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15}; | 771 | static char baud_bpr_25[] = { /* 25 MHz baud rate period table */ |
773 | 772 | 0x00, 0xf5, 0xa3, 0x6f, 0x5c, 0x51, 0xf5, 0xa3, 0x51, 0xa3, | |
774 | static char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */ | 773 | 0x6d, 0x51, 0xa3, 0x51, 0xa3, 0x51, 0x36, 0x29, 0x1b, 0x15 |
775 | /* value => 00 01 02 03 04 */ | 774 | }; |
776 | /* divide by 8 32 128 512 2048 */ | 775 | |
777 | 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, | 776 | static char baud_co_60[] = { /* 60 MHz clock option table (CD1400 J) */ |
778 | 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, | 777 | /* value => 00 01 02 03 04 */ |
779 | 0x00}; | 778 | /* divide by 8 32 128 512 2048 */ |
780 | 779 | 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, | |
781 | static char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */ | 780 | 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, |
782 | 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62, | 781 | 0x00 |
783 | 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32, | 782 | }; |
784 | 0x21}; | 783 | |
785 | 784 | static char baud_bpr_60[] = { /* 60 MHz baud rate period table (CD1400 J) */ | |
786 | static char baud_cor3[] = { /* receive threshold */ | 785 | 0x00, 0x82, 0x21, 0xff, 0xdb, 0xc3, 0x92, 0x62, 0xc3, 0x62, |
787 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | 786 | 0x41, 0xc3, 0x62, 0xc3, 0x62, 0xc3, 0x82, 0x62, 0x41, 0x32, |
788 | 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07, | 787 | 0x21 |
789 | 0x07}; | 788 | }; |
789 | |||
790 | static char baud_cor3[] = { /* receive threshold */ | ||
791 | 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | ||
792 | 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x07, | ||
793 | 0x07 | ||
794 | }; | ||
790 | 795 | ||
791 | /* | 796 | /* |
792 | * The Cyclades driver implements HW flow control as any serial driver. | 797 | * The Cyclades driver implements HW flow control as any serial driver. |
@@ -799,42 +804,42 @@ static char baud_cor3[] = { /* receive threshold */ | |||
799 | * cables. | 804 | * cables. |
800 | */ | 805 | */ |
801 | 806 | ||
802 | static char rflow_thr[] = { /* rflow threshold */ | 807 | static char rflow_thr[] = { /* rflow threshold */ |
803 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 808 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
804 | 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, | 809 | 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, |
805 | 0x0a}; | 810 | 0x0a |
811 | }; | ||
806 | 812 | ||
807 | /* The Cyclom-Ye has placed the sequential chips in non-sequential | 813 | /* The Cyclom-Ye has placed the sequential chips in non-sequential |
808 | * address order. This look-up table overcomes that problem. | 814 | * address order. This look-up table overcomes that problem. |
809 | */ | 815 | */ |
810 | static int cy_chip_offset [] = | 816 | static int cy_chip_offset[] = { 0x0000, |
811 | { 0x0000, | 817 | 0x0400, |
812 | 0x0400, | 818 | 0x0800, |
813 | 0x0800, | 819 | 0x0C00, |
814 | 0x0C00, | 820 | 0x0200, |
815 | 0x0200, | 821 | 0x0600, |
816 | 0x0600, | 822 | 0x0A00, |
817 | 0x0A00, | 823 | 0x0E00 |
818 | 0x0E00 | 824 | }; |
819 | }; | ||
820 | 825 | ||
821 | /* PCI related definitions */ | 826 | /* PCI related definitions */ |
822 | 827 | ||
823 | static unsigned short cy_pci_nboard; | 828 | static unsigned short cy_pci_nboard; |
824 | static unsigned short cy_isa_nboard; | 829 | static unsigned short cy_isa_nboard; |
825 | static unsigned short cy_nboard; | 830 | static unsigned short cy_nboard; |
826 | #ifdef CONFIG_PCI | 831 | #ifdef CONFIG_PCI |
827 | static unsigned short cy_pci_dev_id[] = { | 832 | static unsigned short cy_pci_dev_id[] = { |
828 | PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */ | 833 | PCI_DEVICE_ID_CYCLOM_Y_Lo, /* PCI < 1Mb */ |
829 | PCI_DEVICE_ID_CYCLOM_Y_Hi, /* PCI > 1Mb */ | 834 | PCI_DEVICE_ID_CYCLOM_Y_Hi, /* PCI > 1Mb */ |
830 | PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */ | 835 | PCI_DEVICE_ID_CYCLOM_4Y_Lo, /* 4Y PCI < 1Mb */ |
831 | PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */ | 836 | PCI_DEVICE_ID_CYCLOM_4Y_Hi, /* 4Y PCI > 1Mb */ |
832 | PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */ | 837 | PCI_DEVICE_ID_CYCLOM_8Y_Lo, /* 8Y PCI < 1Mb */ |
833 | PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */ | 838 | PCI_DEVICE_ID_CYCLOM_8Y_Hi, /* 8Y PCI > 1Mb */ |
834 | PCI_DEVICE_ID_CYCLOM_Z_Lo, /* Z PCI < 1Mb */ | 839 | PCI_DEVICE_ID_CYCLOM_Z_Lo, /* Z PCI < 1Mb */ |
835 | PCI_DEVICE_ID_CYCLOM_Z_Hi, /* Z PCI > 1Mb */ | 840 | PCI_DEVICE_ID_CYCLOM_Z_Hi, /* Z PCI > 1Mb */ |
836 | 0 /* end of table */ | 841 | 0 /* end of table */ |
837 | }; | 842 | }; |
838 | #endif | 843 | #endif |
839 | 844 | ||
840 | static void cy_start(struct tty_struct *); | 845 | static void cy_start(struct tty_struct *); |
@@ -842,9 +847,9 @@ static void set_line_char(struct cyclades_port *); | |||
842 | static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong); | 847 | static int cyz_issue_cmd(struct cyclades_card *, uclong, ucchar, uclong); |
843 | #ifdef CONFIG_ISA | 848 | #ifdef CONFIG_ISA |
844 | static unsigned detect_isa_irq(void __iomem *); | 849 | static unsigned detect_isa_irq(void __iomem *); |
845 | #endif /* CONFIG_ISA */ | 850 | #endif /* CONFIG_ISA */ |
846 | 851 | ||
847 | static int cyclades_get_proc_info(char *, char **, off_t , int , int *, void *); | 852 | static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *); |
848 | 853 | ||
849 | #ifndef CONFIG_CYZ_INTR | 854 | #ifndef CONFIG_CYZ_INTR |
850 | static void cyz_poll(unsigned long); | 855 | static void cyz_poll(unsigned long); |
@@ -855,41 +860,36 @@ static long cyz_polling_cycle = CZ_DEF_POLL; | |||
855 | static int cyz_timeron = 0; | 860 | static int cyz_timeron = 0; |
856 | static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); | 861 | static DEFINE_TIMER(cyz_timerlist, cyz_poll, 0, 0); |
857 | 862 | ||
858 | #else /* CONFIG_CYZ_INTR */ | 863 | #else /* CONFIG_CYZ_INTR */ |
859 | static void cyz_rx_restart(unsigned long); | 864 | static void cyz_rx_restart(unsigned long); |
860 | static struct timer_list cyz_rx_full_timer[NR_PORTS]; | 865 | static struct timer_list cyz_rx_full_timer[NR_PORTS]; |
861 | #endif /* CONFIG_CYZ_INTR */ | 866 | #endif /* CONFIG_CYZ_INTR */ |
862 | 867 | ||
863 | static inline int | 868 | static inline int serial_paranoia_check(struct cyclades_port *info, |
864 | serial_paranoia_check(struct cyclades_port *info, | 869 | char *name, const char *routine) |
865 | char *name, const char *routine) | ||
866 | { | 870 | { |
867 | #ifdef SERIAL_PARANOIA_CHECK | 871 | #ifdef SERIAL_PARANOIA_CHECK |
868 | static const char *badmagic = | 872 | if (!info) { |
869 | "cyc Warning: bad magic number for serial struct (%s) in %s\n"; | 873 | printk("cyc Warning: null cyclades_port for (%s) in %s\n", |
870 | static const char *badinfo = | 874 | name, routine); |
871 | "cyc Warning: null cyclades_port for (%s) in %s\n"; | 875 | return 1; |
872 | static const char *badrange = | 876 | } |
873 | "cyc Warning: cyclades_port out of range for (%s) in %s\n"; | 877 | |
874 | 878 | if ((long)info < (long)(&cy_port[0]) || | |
875 | if (!info) { | 879 | (long)(&cy_port[NR_PORTS]) < (long)info) { |
876 | printk(badinfo, name, routine); | 880 | printk("cyc Warning: cyclades_port out of range for (%s) in " |
877 | return 1; | 881 | "%s\n", name, routine); |
878 | } | 882 | return 1; |
879 | 883 | } | |
880 | if( (long)info < (long)(&cy_port[0]) | 884 | |
881 | || (long)(&cy_port[NR_PORTS]) < (long)info ){ | 885 | if (info->magic != CYCLADES_MAGIC) { |
882 | printk(badrange, name, routine); | 886 | printk("cyc Warning: bad magic number for serial struct (%s) " |
883 | return 1; | 887 | "in %s\n", name, routine); |
884 | } | 888 | return 1; |
885 | 889 | } | |
886 | if (info->magic != CYCLADES_MAGIC) { | ||
887 | printk(badmagic, name, routine); | ||
888 | return 1; | ||
889 | } | ||
890 | #endif | 890 | #endif |
891 | return 0; | 891 | return 0; |
892 | } /* serial_paranoia_check */ | 892 | } /* serial_paranoia_check */ |
893 | 893 | ||
894 | /* | 894 | /* |
895 | * This routine is used by the interrupt handler to schedule | 895 | * This routine is used by the interrupt handler to schedule |
@@ -897,13 +897,11 @@ serial_paranoia_check(struct cyclades_port *info, | |||
897 | * (also known as the "bottom half"). This can be called any | 897 | * (also known as the "bottom half"). This can be called any |
898 | * number of times for any channel without harm. | 898 | * number of times for any channel without harm. |
899 | */ | 899 | */ |
900 | static inline void | 900 | static inline void cy_sched_event(struct cyclades_port *info, int event) |
901 | cy_sched_event(struct cyclades_port *info, int event) | ||
902 | { | 901 | { |
903 | info->event |= 1 << event; /* remember what kind of event and who */ | 902 | info->event |= 1 << event; /* remember what kind of event and who */ |
904 | schedule_work(&info->tqueue); | 903 | schedule_work(&info->tqueue); |
905 | } /* cy_sched_event */ | 904 | } /* cy_sched_event */ |
906 | |||
907 | 905 | ||
908 | /* | 906 | /* |
909 | * This routine is used to handle the "bottom half" processing for the | 907 | * This routine is used to handle the "bottom half" processing for the |
@@ -930,41 +928,36 @@ do_softint(struct work_struct *work) | |||
930 | { | 928 | { |
931 | struct cyclades_port *info = | 929 | struct cyclades_port *info = |
932 | container_of(work, struct cyclades_port, tqueue); | 930 | container_of(work, struct cyclades_port, tqueue); |
933 | struct tty_struct *tty; | 931 | struct tty_struct *tty; |
934 | 932 | ||
935 | tty = info->tty; | 933 | tty = info->tty; |
936 | if (!tty) | 934 | if (!tty) |
937 | return; | 935 | return; |
938 | 936 | ||
939 | if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { | 937 | if (test_and_clear_bit(Cy_EVENT_HANGUP, &info->event)) { |
940 | tty_hangup(info->tty); | 938 | tty_hangup(info->tty); |
941 | wake_up_interruptible(&info->open_wait); | 939 | wake_up_interruptible(&info->open_wait); |
942 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 940 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
943 | } | 941 | } |
944 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) { | 942 | if (test_and_clear_bit(Cy_EVENT_OPEN_WAKEUP, &info->event)) |
945 | wake_up_interruptible(&info->open_wait); | 943 | wake_up_interruptible(&info->open_wait); |
946 | } | ||
947 | #ifdef CONFIG_CYZ_INTR | 944 | #ifdef CONFIG_CYZ_INTR |
948 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) { | 945 | if (test_and_clear_bit(Cy_EVENT_Z_RX_FULL, &info->event)) { |
949 | if (cyz_rx_full_timer[info->line].function == NULL) { | 946 | if (cyz_rx_full_timer[info->line].function == NULL) { |
950 | cyz_rx_full_timer[info->line].expires = jiffies + 1; | 947 | cyz_rx_full_timer[info->line].expires = jiffies + 1; |
951 | cyz_rx_full_timer[info->line].function = cyz_rx_restart; | 948 | cyz_rx_full_timer[info->line].function = cyz_rx_restart; |
952 | cyz_rx_full_timer[info->line].data = (unsigned long)info; | 949 | cyz_rx_full_timer[info->line].data = |
953 | add_timer(&cyz_rx_full_timer[info->line]); | 950 | (unsigned long)info; |
951 | add_timer(&cyz_rx_full_timer[info->line]); | ||
952 | } | ||
954 | } | 953 | } |
955 | } | ||
956 | #endif | 954 | #endif |
957 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) { | 955 | if (test_and_clear_bit(Cy_EVENT_DELTA_WAKEUP, &info->event)) |
958 | wake_up_interruptible(&info->delta_msr_wait); | 956 | wake_up_interruptible(&info->delta_msr_wait); |
959 | } | 957 | tty_wakeup(tty); |
960 | if (test_and_clear_bit(Cy_EVENT_WRITE_WAKEUP, &info->event)) { | ||
961 | tty_wakeup(tty); | ||
962 | wake_up_interruptible(&tty->write_wait); | ||
963 | } | ||
964 | #ifdef Z_WAKE | 958 | #ifdef Z_WAKE |
965 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) { | 959 | if (test_and_clear_bit(Cy_EVENT_SHUTDOWN_WAKEUP, &info->event)) |
966 | wake_up_interruptible(&info->shutdown_wait); | 960 | wake_up_interruptible(&info->shutdown_wait); |
967 | } | ||
968 | #endif | 961 | #endif |
969 | } /* do_softint */ | 962 | } /* do_softint */ |
970 | 963 | ||
@@ -979,341 +972,339 @@ do_softint(struct work_struct *work) | |||
979 | 972 | ||
980 | This function is only called from inside spinlock-protected code. | 973 | This function is only called from inside spinlock-protected code. |
981 | */ | 974 | */ |
982 | static int | 975 | static int cyy_issue_cmd(void __iomem * base_addr, u_char cmd, int index) |
983 | cyy_issue_cmd(void __iomem *base_addr, u_char cmd, int index) | ||
984 | { | 976 | { |
985 | volatile int i; | 977 | volatile int i; |
986 | 978 | ||
987 | /* Check to see that the previous command has completed */ | 979 | /* Check to see that the previous command has completed */ |
988 | for(i = 0 ; i < 100 ; i++){ | 980 | for (i = 0; i < 100; i++) { |
989 | if (cy_readb(base_addr+(CyCCR<<index)) == 0){ | 981 | if (cy_readb(base_addr + (CyCCR << index)) == 0) { |
990 | break; | 982 | break; |
983 | } | ||
984 | udelay(10L); | ||
991 | } | 985 | } |
992 | udelay(10L); | 986 | /* if the CCR never cleared, the previous command |
993 | } | 987 | didn't finish within the "reasonable time" */ |
994 | /* if the CCR never cleared, the previous command | 988 | if (i == 100) |
995 | didn't finish within the "reasonable time" */ | 989 | return -1; |
996 | if (i == 100) return (-1); | ||
997 | 990 | ||
998 | /* Issue the new command */ | 991 | /* Issue the new command */ |
999 | cy_writeb(base_addr+(CyCCR<<index), cmd); | 992 | cy_writeb(base_addr + (CyCCR << index), cmd); |
1000 | 993 | ||
1001 | return(0); | 994 | return 0; |
1002 | } /* cyy_issue_cmd */ | 995 | } /* cyy_issue_cmd */ |
1003 | 996 | ||
1004 | #ifdef CONFIG_ISA | 997 | #ifdef CONFIG_ISA |
1005 | /* ISA interrupt detection code */ | 998 | /* ISA interrupt detection code */ |
1006 | static unsigned | 999 | static unsigned detect_isa_irq(void __iomem * address) |
1007 | detect_isa_irq(void __iomem *address) | ||
1008 | { | 1000 | { |
1009 | int irq; | 1001 | int irq; |
1010 | unsigned long irqs, flags; | 1002 | unsigned long irqs, flags; |
1011 | int save_xir, save_car; | 1003 | int save_xir, save_car; |
1012 | int index = 0; /* IRQ probing is only for ISA */ | 1004 | int index = 0; /* IRQ probing is only for ISA */ |
1013 | 1005 | ||
1014 | /* forget possible initially masked and pending IRQ */ | 1006 | /* forget possible initially masked and pending IRQ */ |
1015 | irq = probe_irq_off(probe_irq_on()); | 1007 | irq = probe_irq_off(probe_irq_on()); |
1016 | 1008 | ||
1017 | /* Clear interrupts on the board first */ | 1009 | /* Clear interrupts on the board first */ |
1018 | cy_writeb(address + (Cy_ClrIntr<<index), 0); | 1010 | cy_writeb(address + (Cy_ClrIntr << index), 0); |
1019 | /* Cy_ClrIntr is 0x1800 */ | 1011 | /* Cy_ClrIntr is 0x1800 */ |
1020 | 1012 | ||
1021 | irqs = probe_irq_on(); | 1013 | irqs = probe_irq_on(); |
1022 | /* Wait ... */ | 1014 | /* Wait ... */ |
1023 | udelay(5000L); | 1015 | udelay(5000L); |
1024 | 1016 | ||
1025 | /* Enable the Tx interrupts on the CD1400 */ | 1017 | /* Enable the Tx interrupts on the CD1400 */ |
1026 | local_irq_save(flags); | 1018 | local_irq_save(flags); |
1027 | cy_writeb(address + (CyCAR<<index), 0); | 1019 | cy_writeb(address + (CyCAR << index), 0); |
1028 | cyy_issue_cmd(address, CyCHAN_CTL|CyENB_XMTR, index); | 1020 | cyy_issue_cmd(address, CyCHAN_CTL | CyENB_XMTR, index); |
1029 | 1021 | ||
1030 | cy_writeb(address + (CyCAR<<index), 0); | 1022 | cy_writeb(address + (CyCAR << index), 0); |
1031 | cy_writeb(address + (CySRER<<index), | 1023 | cy_writeb(address + (CySRER << index), |
1032 | cy_readb(address + (CySRER<<index)) | CyTxRdy); | 1024 | cy_readb(address + (CySRER << index)) | CyTxRdy); |
1033 | local_irq_restore(flags); | 1025 | local_irq_restore(flags); |
1034 | 1026 | ||
1035 | /* Wait ... */ | 1027 | /* Wait ... */ |
1036 | udelay(5000L); | 1028 | udelay(5000L); |
1037 | 1029 | ||
1038 | /* Check which interrupt is in use */ | 1030 | /* Check which interrupt is in use */ |
1039 | irq = probe_irq_off(irqs); | 1031 | irq = probe_irq_off(irqs); |
1040 | 1032 | ||
1041 | /* Clean up */ | 1033 | /* Clean up */ |
1042 | save_xir = (u_char) cy_readb(address + (CyTIR<<index)); | 1034 | save_xir = (u_char) cy_readb(address + (CyTIR << index)); |
1043 | save_car = cy_readb(address + (CyCAR<<index)); | 1035 | save_car = cy_readb(address + (CyCAR << index)); |
1044 | cy_writeb(address + (CyCAR<<index), (save_xir & 0x3)); | 1036 | cy_writeb(address + (CyCAR << index), (save_xir & 0x3)); |
1045 | cy_writeb(address + (CySRER<<index), | 1037 | cy_writeb(address + (CySRER << index), |
1046 | cy_readb(address + (CySRER<<index)) & ~CyTxRdy); | 1038 | cy_readb(address + (CySRER << index)) & ~CyTxRdy); |
1047 | cy_writeb(address + (CyTIR<<index), (save_xir & 0x3f)); | 1039 | cy_writeb(address + (CyTIR << index), (save_xir & 0x3f)); |
1048 | cy_writeb(address + (CyCAR<<index), (save_car)); | 1040 | cy_writeb(address + (CyCAR << index), (save_car)); |
1049 | cy_writeb(address + (Cy_ClrIntr<<index), 0); | 1041 | cy_writeb(address + (Cy_ClrIntr << index), 0); |
1050 | /* Cy_ClrIntr is 0x1800 */ | 1042 | /* Cy_ClrIntr is 0x1800 */ |
1051 | 1043 | ||
1052 | return (irq > 0)? irq : 0; | 1044 | return (irq > 0) ? irq : 0; |
1053 | } | 1045 | } |
1054 | #endif /* CONFIG_ISA */ | 1046 | #endif /* CONFIG_ISA */ |
1055 | 1047 | ||
1056 | /* The real interrupt service routine is called | 1048 | static void cyy_intr_chip(struct cyclades_card *cinfo, int chip, |
1057 | whenever the card wants its hand held--chars | 1049 | void __iomem * base_addr, int status, int index) |
1058 | received, out buffer empty, modem change, etc. | ||
1059 | */ | ||
1060 | static irqreturn_t | ||
1061 | cyy_interrupt(int irq, void *dev_id) | ||
1062 | { | 1050 | { |
1063 | struct tty_struct *tty; | 1051 | struct cyclades_port *info; |
1064 | int status; | 1052 | struct tty_struct *tty; |
1065 | struct cyclades_card *cinfo; | 1053 | volatile int char_count; |
1066 | struct cyclades_port *info; | 1054 | int i, j, len, mdm_change, mdm_status, outch; |
1067 | void __iomem *base_addr, *card_base_addr; | 1055 | int save_xir, channel, save_car; |
1068 | int chip; | 1056 | char data; |
1069 | int save_xir, channel, save_car; | 1057 | |
1070 | char data; | 1058 | if (status & CySRReceive) { /* reception interrupt */ |
1071 | volatile int char_count; | ||
1072 | int outch; | ||
1073 | int i,j,index; | ||
1074 | int too_many; | ||
1075 | int had_work; | ||
1076 | int mdm_change; | ||
1077 | int mdm_status; | ||
1078 | int len; | ||
1079 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ | ||
1080 | #ifdef CY_DEBUG_INTERRUPTS | ||
1081 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | ||
1082 | #endif | ||
1083 | return IRQ_NONE; /* spurious interrupt */ | ||
1084 | } | ||
1085 | |||
1086 | card_base_addr = cinfo->base_addr; | ||
1087 | index = cinfo->bus_index; | ||
1088 | |||
1089 | |||
1090 | /* This loop checks all chips in the card. Make a note whenever | ||
1091 | _any_ chip had some work to do, as this is considered an | ||
1092 | indication that there will be more to do. Only when no chip | ||
1093 | has any work does this outermost loop exit. | ||
1094 | */ | ||
1095 | do{ | ||
1096 | had_work = 0; | ||
1097 | for ( chip = 0 ; chip < cinfo->num_chips ; chip ++) { | ||
1098 | base_addr = cinfo->base_addr + (cy_chip_offset[chip]<<index); | ||
1099 | too_many = 0; | ||
1100 | while ( (status = cy_readb(base_addr+(CySVRR<<index))) != 0x00) { | ||
1101 | had_work++; | ||
1102 | /* The purpose of the following test is to ensure that | ||
1103 | no chip can monopolize the driver. This forces the | ||
1104 | chips to be checked in a round-robin fashion (after | ||
1105 | draining each of a bunch (1000) of characters). | ||
1106 | */ | ||
1107 | if(1000<too_many++){ | ||
1108 | break; | ||
1109 | } | ||
1110 | if (status & CySRReceive) { /* reception interrupt */ | ||
1111 | #ifdef CY_DEBUG_INTERRUPTS | 1059 | #ifdef CY_DEBUG_INTERRUPTS |
1112 | printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); | 1060 | printk("cyy_interrupt: rcvd intr, chip %d\n\r", chip); |
1113 | #endif | 1061 | #endif |
1114 | /* determine the channel & change to that context */ | 1062 | /* determine the channel & change to that context */ |
1115 | spin_lock(&cinfo->card_lock); | 1063 | spin_lock(&cinfo->card_lock); |
1116 | save_xir = (u_char) cy_readb(base_addr+(CyRIR<<index)); | 1064 | save_xir = (u_char) cy_readb(base_addr + (CyRIR << index)); |
1117 | channel = (u_short ) (save_xir & CyIRChannel); | 1065 | channel = (u_short) (save_xir & CyIRChannel); |
1118 | i = channel + chip * 4 + cinfo->first_line; | 1066 | i = channel + chip * 4 + cinfo->first_line; |
1119 | info = &cy_port[i]; | 1067 | info = &cy_port[i]; |
1120 | info->last_active = jiffies; | 1068 | info->last_active = jiffies; |
1121 | save_car = cy_readb(base_addr+(CyCAR<<index)); | 1069 | save_car = cy_readb(base_addr + (CyCAR << index)); |
1122 | cy_writeb(base_addr+(CyCAR<<index), save_xir); | 1070 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1123 | 1071 | ||
1124 | /* if there is nowhere to put the data, discard it */ | 1072 | /* if there is nowhere to put the data, discard it */ |
1125 | if(info->tty == 0){ | 1073 | if (info->tty == 0) { |
1126 | j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask); | 1074 | j = (cy_readb(base_addr + (CyRIVR << index)) & |
1127 | if ( j == CyIVRRxEx ) { /* exception */ | 1075 | CyIVRMask); |
1128 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1076 | if (j == CyIVRRxEx) { /* exception */ |
1129 | } else { /* normal character reception */ | 1077 | data = cy_readb(base_addr + (CyRDSR << index)); |
1130 | char_count = cy_readb(base_addr+(CyRDCR<<index)); | 1078 | } else { /* normal character reception */ |
1131 | while(char_count--){ | 1079 | char_count = cy_readb(base_addr + |
1132 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1080 | (CyRDCR << index)); |
1133 | } | 1081 | while (char_count--) { |
1134 | } | 1082 | data = cy_readb(base_addr + |
1135 | }else{ /* there is an open port for this data */ | 1083 | (CyRDSR << index)); |
1136 | tty = info->tty; | 1084 | } |
1137 | j = (cy_readb(base_addr+(CyRIVR<<index)) & CyIVRMask); | 1085 | } |
1138 | if ( j == CyIVRRxEx ) { /* exception */ | 1086 | } else { /* there is an open port for this data */ |
1139 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1087 | tty = info->tty; |
1140 | 1088 | j = (cy_readb(base_addr + (CyRIVR << index)) & | |
1141 | /* For statistics only */ | 1089 | CyIVRMask); |
1142 | if (data & CyBREAK) | 1090 | if (j == CyIVRRxEx) { /* exception */ |
1143 | info->icount.brk++; | 1091 | data = cy_readb(base_addr + (CyRDSR << index)); |
1144 | else if(data & CyFRAME) | 1092 | |
1145 | info->icount.frame++; | 1093 | /* For statistics only */ |
1146 | else if(data & CyPARITY) | 1094 | if (data & CyBREAK) |
1147 | info->icount.parity++; | 1095 | info->icount.brk++; |
1148 | else if(data & CyOVERRUN) | 1096 | else if (data & CyFRAME) |
1149 | info->icount.overrun++; | 1097 | info->icount.frame++; |
1150 | 1098 | else if (data & CyPARITY) | |
1151 | if(data & info->ignore_status_mask){ | 1099 | info->icount.parity++; |
1152 | info->icount.rx++; | 1100 | else if (data & CyOVERRUN) |
1153 | continue; | 1101 | info->icount.overrun++; |
1154 | } | 1102 | |
1155 | if (tty_buffer_request_room(tty, 1)) { | 1103 | if (data & info->ignore_status_mask) { |
1156 | if (data & info->read_status_mask){ | ||
1157 | if(data & CyBREAK){ | ||
1158 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_BREAK); | ||
1159 | info->icount.rx++; | ||
1160 | if (info->flags & ASYNC_SAK){ | ||
1161 | do_SAK(tty); | ||
1162 | } | ||
1163 | }else if(data & CyFRAME){ | ||
1164 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); | ||
1165 | info->icount.rx++; | ||
1166 | info->idle_stats.frame_errs++; | ||
1167 | }else if(data & CyPARITY){ | ||
1168 | /* Pieces of seven... */ | ||
1169 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_PARITY); | ||
1170 | info->icount.rx++; | ||
1171 | info->idle_stats.parity_errs++; | ||
1172 | }else if(data & CyOVERRUN){ | ||
1173 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1174 | info->icount.rx++; | 1104 | info->icount.rx++; |
1175 | /* If the flip buffer itself is | 1105 | return; |
1176 | overflowing, we still lose | 1106 | } |
1177 | the next incoming character. | 1107 | if (tty_buffer_request_room(tty, 1)) { |
1178 | */ | 1108 | if (data & info->read_status_mask) { |
1179 | tty_insert_flip_char(tty, cy_readb(base_addr+(CyRDSR<<index)), TTY_FRAME); | 1109 | if (data & CyBREAK) { |
1180 | info->icount.rx++; | 1110 | tty_insert_flip_char( |
1111 | tty, | ||
1112 | cy_readb( | ||
1113 | base_addr + | ||
1114 | (CyRDSR << | ||
1115 | index)), | ||
1116 | TTY_BREAK); | ||
1117 | info->icount.rx++; | ||
1118 | if (info->flags & | ||
1119 | ASYNC_SAK) { | ||
1120 | do_SAK(tty); | ||
1121 | } | ||
1122 | } else if (data & CyFRAME) { | ||
1123 | tty_insert_flip_char( | ||
1124 | tty, | ||
1125 | cy_readb( | ||
1126 | base_addr + | ||
1127 | (CyRDSR << | ||
1128 | index)), | ||
1129 | TTY_FRAME); | ||
1130 | info->icount.rx++; | ||
1131 | info->idle_stats. | ||
1132 | frame_errs++; | ||
1133 | } else if (data & CyPARITY) { | ||
1134 | /* Pieces of seven... */ | ||
1135 | tty_insert_flip_char( | ||
1136 | tty, | ||
1137 | cy_readb( | ||
1138 | base_addr + | ||
1139 | (CyRDSR << | ||
1140 | index)), | ||
1141 | TTY_PARITY); | ||
1142 | info->icount.rx++; | ||
1143 | info->idle_stats. | ||
1144 | parity_errs++; | ||
1145 | } else if (data & CyOVERRUN) { | ||
1146 | tty_insert_flip_char( | ||
1147 | tty, 0, | ||
1148 | TTY_OVERRUN); | ||
1149 | info->icount.rx++; | ||
1150 | /* If the flip buffer itself is | ||
1151 | overflowing, we still lose | ||
1152 | the next incoming character. | ||
1153 | */ | ||
1154 | tty_insert_flip_char( | ||
1155 | tty, | ||
1156 | cy_readb( | ||
1157 | base_addr + | ||
1158 | (CyRDSR << | ||
1159 | index)), | ||
1160 | TTY_FRAME); | ||
1161 | info->icount.rx++; | ||
1162 | info->idle_stats. | ||
1163 | overruns++; | ||
1164 | /* These two conditions may imply */ | ||
1165 | /* a normal read should be done. */ | ||
1166 | /* }else if(data & CyTIMEOUT){ */ | ||
1167 | /* }else if(data & CySPECHAR){ */ | ||
1168 | } else { | ||
1169 | tty_insert_flip_char( | ||
1170 | tty, 0, | ||
1171 | TTY_NORMAL); | ||
1172 | info->icount.rx++; | ||
1173 | } | ||
1174 | } else { | ||
1175 | tty_insert_flip_char(tty, 0, | ||
1176 | TTY_NORMAL); | ||
1177 | info->icount.rx++; | ||
1178 | } | ||
1179 | } else { | ||
1180 | /* there was a software buffer | ||
1181 | overrun and nothing could be | ||
1182 | done about it!!! */ | ||
1183 | info->icount.buf_overrun++; | ||
1181 | info->idle_stats.overruns++; | 1184 | info->idle_stats.overruns++; |
1182 | /* These two conditions may imply */ | 1185 | } |
1183 | /* a normal read should be done. */ | 1186 | } else { /* normal character reception */ |
1184 | /* }else if(data & CyTIMEOUT){ */ | 1187 | /* load # chars available from the chip */ |
1185 | /* }else if(data & CySPECHAR){ */ | 1188 | char_count = cy_readb(base_addr + |
1186 | }else { | 1189 | (CyRDCR << index)); |
1187 | tty_insert_flip_char(tty, 0, TTY_NORMAL); | ||
1188 | info->icount.rx++; | ||
1189 | } | ||
1190 | }else{ | ||
1191 | tty_insert_flip_char(tty, 0, TTY_NORMAL); | ||
1192 | info->icount.rx++; | ||
1193 | } | ||
1194 | }else{ | ||
1195 | /* there was a software buffer | ||
1196 | overrun and nothing could be | ||
1197 | done about it!!! */ | ||
1198 | info->icount.buf_overrun++; | ||
1199 | info->idle_stats.overruns++; | ||
1200 | } | ||
1201 | } else { /* normal character reception */ | ||
1202 | /* load # chars available from the chip */ | ||
1203 | char_count = cy_readb(base_addr+(CyRDCR<<index)); | ||
1204 | 1190 | ||
1205 | #ifdef CY_ENABLE_MONITORING | 1191 | #ifdef CY_ENABLE_MONITORING |
1206 | ++info->mon.int_count; | 1192 | ++info->mon.int_count; |
1207 | info->mon.char_count += char_count; | 1193 | info->mon.char_count += char_count; |
1208 | if (char_count > info->mon.char_max) | 1194 | if (char_count > info->mon.char_max) |
1209 | info->mon.char_max = char_count; | 1195 | info->mon.char_max = char_count; |
1210 | info->mon.char_last = char_count; | 1196 | info->mon.char_last = char_count; |
1211 | #endif | 1197 | #endif |
1212 | len = tty_buffer_request_room(tty, char_count); | 1198 | len = tty_buffer_request_room(tty, char_count); |
1213 | while(len--){ | 1199 | while (len--) { |
1214 | data = cy_readb(base_addr+(CyRDSR<<index)); | 1200 | data = cy_readb(base_addr + |
1215 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 1201 | (CyRDSR << index)); |
1216 | info->idle_stats.recv_bytes++; | 1202 | tty_insert_flip_char(tty, data, |
1217 | info->icount.rx++; | 1203 | TTY_NORMAL); |
1204 | info->idle_stats.recv_bytes++; | ||
1205 | info->icount.rx++; | ||
1218 | #ifdef CY_16Y_HACK | 1206 | #ifdef CY_16Y_HACK |
1219 | udelay(10L); | 1207 | udelay(10L); |
1220 | #endif | 1208 | #endif |
1221 | } | 1209 | } |
1222 | info->idle_stats.recv_idle = jiffies; | 1210 | info->idle_stats.recv_idle = jiffies; |
1223 | } | 1211 | } |
1224 | tty_schedule_flip(tty); | 1212 | tty_schedule_flip(tty); |
1225 | } | 1213 | } |
1226 | /* end of service */ | 1214 | /* end of service */ |
1227 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); | 1215 | cy_writeb(base_addr + (CyRIR << index), (save_xir & 0x3f)); |
1228 | cy_writeb(base_addr+(CyCAR<<index), (save_car)); | 1216 | cy_writeb(base_addr + (CyCAR << index), (save_car)); |
1229 | spin_unlock(&cinfo->card_lock); | 1217 | spin_unlock(&cinfo->card_lock); |
1230 | } | 1218 | } |
1231 | 1219 | ||
1232 | 1220 | if (status & CySRTransmit) { /* transmission interrupt */ | |
1233 | if (status & CySRTransmit) { /* transmission interrupt */ | 1221 | /* Since we only get here when the transmit buffer |
1234 | /* Since we only get here when the transmit buffer | 1222 | is empty, we know we can always stuff a dozen |
1235 | is empty, we know we can always stuff a dozen | 1223 | characters. */ |
1236 | characters. */ | ||
1237 | #ifdef CY_DEBUG_INTERRUPTS | 1224 | #ifdef CY_DEBUG_INTERRUPTS |
1238 | printk("cyy_interrupt: xmit intr, chip %d\n\r", chip); | 1225 | printk("cyy_interrupt: xmit intr, chip %d\n\r", chip); |
1239 | #endif | 1226 | #endif |
1240 | 1227 | ||
1241 | /* determine the channel & change to that context */ | 1228 | /* determine the channel & change to that context */ |
1242 | spin_lock(&cinfo->card_lock); | 1229 | spin_lock(&cinfo->card_lock); |
1243 | save_xir = (u_char) cy_readb(base_addr+(CyTIR<<index)); | 1230 | save_xir = (u_char) cy_readb(base_addr + (CyTIR << index)); |
1244 | channel = (u_short ) (save_xir & CyIRChannel); | 1231 | channel = (u_short) (save_xir & CyIRChannel); |
1245 | i = channel + chip * 4 + cinfo->first_line; | 1232 | i = channel + chip * 4 + cinfo->first_line; |
1246 | save_car = cy_readb(base_addr+(CyCAR<<index)); | 1233 | save_car = cy_readb(base_addr + (CyCAR << index)); |
1247 | cy_writeb(base_addr+(CyCAR<<index), save_xir); | 1234 | cy_writeb(base_addr + (CyCAR << index), save_xir); |
1248 | 1235 | ||
1249 | /* validate the port# (as configured and open) */ | 1236 | /* validate the port# (as configured and open) */ |
1250 | if( (i < 0) || (NR_PORTS <= i) ){ | 1237 | if ((i < 0) || (NR_PORTS <= i)) { |
1251 | cy_writeb(base_addr+(CySRER<<index), | 1238 | cy_writeb(base_addr + (CySRER << index), |
1252 | cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy); | 1239 | cy_readb(base_addr + (CySRER << index)) & |
1253 | goto txend; | 1240 | ~CyTxRdy); |
1254 | } | 1241 | goto txend; |
1255 | info = &cy_port[i]; | 1242 | } |
1256 | info->last_active = jiffies; | 1243 | info = &cy_port[i]; |
1257 | if(info->tty == 0){ | 1244 | info->last_active = jiffies; |
1258 | cy_writeb(base_addr+(CySRER<<index), | 1245 | if (info->tty == 0) { |
1259 | cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy); | 1246 | cy_writeb(base_addr + (CySRER << index), |
1260 | goto txdone; | 1247 | cy_readb(base_addr + (CySRER << index)) & |
1261 | } | 1248 | ~CyTxRdy); |
1262 | 1249 | goto txdone; | |
1263 | /* load the on-chip space for outbound data */ | 1250 | } |
1264 | char_count = info->xmit_fifo_size; | 1251 | |
1265 | 1252 | /* load the on-chip space for outbound data */ | |
1266 | if(info->x_char) { /* send special char */ | 1253 | char_count = info->xmit_fifo_size; |
1267 | outch = info->x_char; | 1254 | |
1268 | cy_writeb(base_addr+(CyTDR<<index), outch); | 1255 | if (info->x_char) { /* send special char */ |
1269 | char_count--; | 1256 | outch = info->x_char; |
1257 | cy_writeb(base_addr + (CyTDR << index), outch); | ||
1258 | char_count--; | ||
1270 | info->icount.tx++; | 1259 | info->icount.tx++; |
1271 | info->x_char = 0; | 1260 | info->x_char = 0; |
1272 | } | 1261 | } |
1273 | 1262 | ||
1274 | if (info->breakon || info->breakoff) { | 1263 | if (info->breakon || info->breakoff) { |
1275 | if (info->breakon) { | 1264 | if (info->breakon) { |
1276 | cy_writeb(base_addr + (CyTDR<<index), 0); | 1265 | cy_writeb(base_addr + (CyTDR << index), 0); |
1277 | cy_writeb(base_addr + (CyTDR<<index), 0x81); | 1266 | cy_writeb(base_addr + (CyTDR << index), 0x81); |
1278 | info->breakon = 0; | 1267 | info->breakon = 0; |
1279 | char_count -= 2; | 1268 | char_count -= 2; |
1280 | } | 1269 | } |
1281 | if (info->breakoff) { | 1270 | if (info->breakoff) { |
1282 | cy_writeb(base_addr + (CyTDR<<index), 0); | 1271 | cy_writeb(base_addr + (CyTDR << index), 0); |
1283 | cy_writeb(base_addr + (CyTDR<<index), 0x83); | 1272 | cy_writeb(base_addr + (CyTDR << index), 0x83); |
1284 | info->breakoff = 0; | 1273 | info->breakoff = 0; |
1285 | char_count -= 2; | 1274 | char_count -= 2; |
1286 | } | 1275 | } |
1287 | } | 1276 | } |
1288 | 1277 | ||
1289 | while (char_count-- > 0){ | 1278 | while (char_count-- > 0) { |
1290 | if (!info->xmit_cnt){ | 1279 | if (!info->xmit_cnt) { |
1291 | if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) { | 1280 | if (cy_readb(base_addr + (CySRER << index)) & |
1292 | cy_writeb(base_addr+(CySRER<<index), | 1281 | CyTxMpty) { |
1293 | cy_readb(base_addr+(CySRER<<index)) & | 1282 | cy_writeb(base_addr + (CySRER << index), |
1294 | ~CyTxMpty); | 1283 | cy_readb(base_addr + |
1295 | } else { | 1284 | (CySRER << index)) & |
1296 | cy_writeb(base_addr+(CySRER<<index), | 1285 | ~CyTxMpty); |
1297 | ((cy_readb(base_addr+(CySRER<<index)) | 1286 | } else { |
1298 | & ~CyTxRdy) | 1287 | cy_writeb(base_addr + (CySRER << index), |
1299 | | CyTxMpty)); | 1288 | (cy_readb(base_addr + |
1300 | } | 1289 | (CySRER << index)) & |
1301 | goto txdone; | 1290 | ~CyTxRdy) | CyTxMpty); |
1291 | } | ||
1292 | goto txdone; | ||
1302 | } | 1293 | } |
1303 | if (info->xmit_buf == 0){ | 1294 | if (info->xmit_buf == 0) { |
1304 | cy_writeb(base_addr+(CySRER<<index), | 1295 | cy_writeb(base_addr + (CySRER << index), |
1305 | cy_readb(base_addr+(CySRER<<index)) & | 1296 | cy_readb(base_addr + (CySRER << index))& |
1306 | ~CyTxRdy); | 1297 | ~CyTxRdy); |
1307 | goto txdone; | 1298 | goto txdone; |
1308 | } | 1299 | } |
1309 | if (info->tty->stopped || info->tty->hw_stopped){ | 1300 | if (info->tty->stopped || info->tty->hw_stopped) { |
1310 | cy_writeb(base_addr+(CySRER<<index), | 1301 | cy_writeb(base_addr + (CySRER << index), |
1311 | cy_readb(base_addr+(CySRER<<index)) & | 1302 | cy_readb(base_addr + (CySRER << index))& |
1312 | ~CyTxRdy); | 1303 | ~CyTxRdy); |
1313 | goto txdone; | 1304 | goto txdone; |
1314 | } | 1305 | } |
1315 | /* Because the Embedded Transmit Commands have | 1306 | /* Because the Embedded Transmit Commands have |
1316 | been enabled, we must check to see if the | 1307 | been enabled, we must check to see if the |
1317 | escape character, NULL, is being sent. If it | 1308 | escape character, NULL, is being sent. If it |
1318 | is, we must ensure that there is room for it | 1309 | is, we must ensure that there is room for it |
1319 | to be doubled in the output stream. Therefore | 1310 | to be doubled in the output stream. Therefore |
@@ -1322,125 +1313,182 @@ cyy_interrupt(int irq, void *dev_id) | |||
1322 | after the check for a NULL output character. | 1313 | after the check for a NULL output character. |
1323 | This is necessary because there may not be | 1314 | This is necessary because there may not be |
1324 | room for the two chars needed to send a NULL.) | 1315 | room for the two chars needed to send a NULL.) |
1325 | */ | 1316 | */ |
1326 | outch = info->xmit_buf[info->xmit_tail]; | 1317 | outch = info->xmit_buf[info->xmit_tail]; |
1327 | if( outch ){ | 1318 | if (outch) { |
1328 | info->xmit_cnt--; | 1319 | info->xmit_cnt--; |
1329 | info->xmit_tail = (info->xmit_tail + 1) | 1320 | info->xmit_tail = (info->xmit_tail + 1) & |
1330 | & (SERIAL_XMIT_SIZE - 1); | 1321 | (SERIAL_XMIT_SIZE - 1); |
1331 | cy_writeb(base_addr+(CyTDR<<index), outch); | 1322 | cy_writeb(base_addr + (CyTDR << index), outch); |
1332 | info->icount.tx++; | ||
1333 | }else{ | ||
1334 | if(char_count > 1){ | ||
1335 | info->xmit_cnt--; | ||
1336 | info->xmit_tail = (info->xmit_tail + 1) | ||
1337 | & (SERIAL_XMIT_SIZE - 1); | ||
1338 | cy_writeb(base_addr+(CyTDR<<index), | ||
1339 | outch); | ||
1340 | cy_writeb(base_addr+(CyTDR<<index), 0); | ||
1341 | info->icount.tx++; | 1323 | info->icount.tx++; |
1342 | char_count--; | 1324 | } else { |
1343 | }else{ | 1325 | if (char_count > 1) { |
1344 | } | 1326 | info->xmit_cnt--; |
1345 | } | 1327 | info->xmit_tail = (info->xmit_tail + 1)& |
1346 | } | 1328 | (SERIAL_XMIT_SIZE - 1); |
1347 | 1329 | cy_writeb(base_addr + (CyTDR << index), | |
1348 | txdone: | 1330 | outch); |
1349 | if (info->xmit_cnt < WAKEUP_CHARS) { | 1331 | cy_writeb(base_addr + (CyTDR << index), |
1350 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | 1332 | 0); |
1351 | } | 1333 | info->icount.tx++; |
1352 | txend: | 1334 | char_count--; |
1353 | /* end of service */ | 1335 | } else { |
1354 | cy_writeb(base_addr+(CyTIR<<index), | 1336 | } |
1355 | (save_xir & 0x3f)); | 1337 | } |
1356 | cy_writeb(base_addr+(CyCAR<<index), (save_car)); | 1338 | } |
1357 | spin_unlock(&cinfo->card_lock); | 1339 | |
1358 | } | 1340 | txdone: |
1359 | 1341 | if (info->xmit_cnt < WAKEUP_CHARS) { | |
1360 | if (status & CySRModem) { /* modem interrupt */ | 1342 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); |
1361 | 1343 | } | |
1362 | /* determine the channel & change to that context */ | 1344 | txend: |
1363 | spin_lock(&cinfo->card_lock); | 1345 | /* end of service */ |
1364 | save_xir = (u_char) cy_readb(base_addr+(CyMIR<<index)); | 1346 | cy_writeb(base_addr + (CyTIR << index), (save_xir & 0x3f)); |
1365 | channel = (u_short ) (save_xir & CyIRChannel); | 1347 | cy_writeb(base_addr + (CyCAR << index), (save_car)); |
1366 | info = &cy_port[channel + chip * 4 | 1348 | spin_unlock(&cinfo->card_lock); |
1367 | + cinfo->first_line]; | 1349 | } |
1368 | info->last_active = jiffies; | 1350 | |
1369 | save_car = cy_readb(base_addr+(CyCAR<<index)); | 1351 | if (status & CySRModem) { /* modem interrupt */ |
1370 | cy_writeb(base_addr+(CyCAR<<index), save_xir); | 1352 | |
1371 | 1353 | /* determine the channel & change to that context */ | |
1372 | mdm_change = cy_readb(base_addr+(CyMISR<<index)); | 1354 | spin_lock(&cinfo->card_lock); |
1373 | mdm_status = cy_readb(base_addr+(CyMSVR1<<index)); | 1355 | save_xir = (u_char) cy_readb(base_addr + (CyMIR << index)); |
1374 | 1356 | channel = (u_short) (save_xir & CyIRChannel); | |
1375 | if(info->tty == 0){/* no place for data, ignore it*/ | 1357 | info = &cy_port[channel + chip * 4 + cinfo->first_line]; |
1376 | ; | 1358 | info->last_active = jiffies; |
1377 | }else{ | 1359 | save_car = cy_readb(base_addr + (CyCAR << index)); |
1360 | cy_writeb(base_addr + (CyCAR << index), save_xir); | ||
1361 | |||
1362 | mdm_change = cy_readb(base_addr + (CyMISR << index)); | ||
1363 | mdm_status = cy_readb(base_addr + (CyMSVR1 << index)); | ||
1364 | |||
1365 | if (info->tty == 0) { /* no place for data, ignore it */ | ||
1366 | ; | ||
1367 | } else { | ||
1378 | if (mdm_change & CyANY_DELTA) { | 1368 | if (mdm_change & CyANY_DELTA) { |
1379 | /* For statistics only */ | 1369 | /* For statistics only */ |
1380 | if (mdm_change & CyDCD) info->icount.dcd++; | 1370 | if (mdm_change & CyDCD) |
1381 | if (mdm_change & CyCTS) info->icount.cts++; | 1371 | info->icount.dcd++; |
1382 | if (mdm_change & CyDSR) info->icount.dsr++; | 1372 | if (mdm_change & CyCTS) |
1383 | if (mdm_change & CyRI) info->icount.rng++; | 1373 | info->icount.cts++; |
1374 | if (mdm_change & CyDSR) | ||
1375 | info->icount.dsr++; | ||
1376 | if (mdm_change & CyRI) | ||
1377 | info->icount.rng++; | ||
1378 | |||
1379 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | ||
1380 | } | ||
1381 | |||
1382 | if ((mdm_change & CyDCD) && | ||
1383 | (info->flags & ASYNC_CHECK_CD)) { | ||
1384 | if (mdm_status & CyDCD) { | ||
1385 | cy_sched_event(info, | ||
1386 | Cy_EVENT_OPEN_WAKEUP); | ||
1387 | } else { | ||
1388 | cy_sched_event(info, Cy_EVENT_HANGUP); | ||
1389 | } | ||
1390 | } | ||
1391 | if ((mdm_change & CyCTS) && | ||
1392 | (info->flags & ASYNC_CTS_FLOW)) { | ||
1393 | if (info->tty->hw_stopped) { | ||
1394 | if (mdm_status & CyCTS) { | ||
1395 | /* cy_start isn't used | ||
1396 | because... !!! */ | ||
1397 | info->tty->hw_stopped = 0; | ||
1398 | cy_writeb(base_addr + | ||
1399 | (CySRER << index), | ||
1400 | cy_readb(base_addr + | ||
1401 | (CySRER << | ||
1402 | index))| | ||
1403 | CyTxRdy); | ||
1404 | cy_sched_event(info, | ||
1405 | Cy_EVENT_WRITE_WAKEUP); | ||
1406 | } | ||
1407 | } else { | ||
1408 | if (!(mdm_status & CyCTS)) { | ||
1409 | /* cy_stop isn't used | ||
1410 | because ... !!! */ | ||
1411 | info->tty->hw_stopped = 1; | ||
1412 | cy_writeb(base_addr + | ||
1413 | (CySRER << index), | ||
1414 | cy_readb(base_addr + | ||
1415 | (CySRER << | ||
1416 | index)) & | ||
1417 | ~CyTxRdy); | ||
1418 | } | ||
1419 | } | ||
1420 | } | ||
1421 | if (mdm_change & CyDSR) { | ||
1422 | } | ||
1423 | if (mdm_change & CyRI) { | ||
1424 | } | ||
1425 | } | ||
1426 | /* end of service */ | ||
1427 | cy_writeb(base_addr + (CyMIR << index), (save_xir & 0x3f)); | ||
1428 | cy_writeb(base_addr + (CyCAR << index), save_car); | ||
1429 | spin_unlock(&cinfo->card_lock); | ||
1430 | } | ||
1431 | } | ||
1432 | |||
1433 | /* The real interrupt service routine is called | ||
1434 | whenever the card wants its hand held--chars | ||
1435 | received, out buffer empty, modem change, etc. | ||
1436 | */ | ||
1437 | static irqreturn_t cyy_interrupt(int irq, void *dev_id) | ||
1438 | { | ||
1439 | int status; | ||
1440 | struct cyclades_card *cinfo; | ||
1441 | void __iomem *base_addr, *card_base_addr; | ||
1442 | int chip; | ||
1443 | int index; | ||
1444 | int too_many; | ||
1445 | int had_work; | ||
1446 | |||
1447 | if ((cinfo = (struct cyclades_card *)dev_id) == 0) { | ||
1448 | #ifdef CY_DEBUG_INTERRUPTS | ||
1449 | printk("cyy_interrupt: spurious interrupt %d\n\r", irq); | ||
1450 | #endif | ||
1451 | return IRQ_NONE; /* spurious interrupt */ | ||
1452 | } | ||
1453 | |||
1454 | card_base_addr = cinfo->base_addr; | ||
1455 | index = cinfo->bus_index; | ||
1384 | 1456 | ||
1385 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1457 | /* This loop checks all chips in the card. Make a note whenever |
1458 | _any_ chip had some work to do, as this is considered an | ||
1459 | indication that there will be more to do. Only when no chip | ||
1460 | has any work does this outermost loop exit. | ||
1461 | */ | ||
1462 | do { | ||
1463 | had_work = 0; | ||
1464 | for (chip = 0; chip < cinfo->num_chips; chip++) { | ||
1465 | base_addr = cinfo->base_addr + | ||
1466 | (cy_chip_offset[chip] << index); | ||
1467 | too_many = 0; | ||
1468 | while ((status = cy_readb(base_addr + | ||
1469 | (CySVRR << index))) != 0x00) { | ||
1470 | had_work++; | ||
1471 | /* The purpose of the following test is to ensure that | ||
1472 | no chip can monopolize the driver. This forces the | ||
1473 | chips to be checked in a round-robin fashion (after | ||
1474 | draining each of a bunch (1000) of characters). | ||
1475 | */ | ||
1476 | if (1000 < too_many++) { | ||
1477 | break; | ||
1478 | } | ||
1479 | cyy_intr_chip(cinfo, chip, base_addr, status, | ||
1480 | index); | ||
1386 | } | 1481 | } |
1482 | } | ||
1483 | } while (had_work); | ||
1387 | 1484 | ||
1388 | if((mdm_change & CyDCD) | 1485 | /* clear interrupts */ |
1389 | && (info->flags & ASYNC_CHECK_CD)){ | 1486 | spin_lock(&cinfo->card_lock); |
1390 | if(mdm_status & CyDCD){ | 1487 | cy_writeb(card_base_addr + (Cy_ClrIntr << index), 0); |
1391 | cy_sched_event(info, | 1488 | /* Cy_ClrIntr is 0x1800 */ |
1392 | Cy_EVENT_OPEN_WAKEUP); | 1489 | spin_unlock(&cinfo->card_lock); |
1393 | }else{ | 1490 | return IRQ_HANDLED; |
1394 | cy_sched_event(info, | 1491 | } /* cyy_interrupt */ |
1395 | Cy_EVENT_HANGUP); | ||
1396 | } | ||
1397 | } | ||
1398 | if((mdm_change & CyCTS) | ||
1399 | && (info->flags & ASYNC_CTS_FLOW)){ | ||
1400 | if(info->tty->hw_stopped){ | ||
1401 | if(mdm_status & CyCTS){ | ||
1402 | /* cy_start isn't used | ||
1403 | because... !!! */ | ||
1404 | info->tty->hw_stopped = 0; | ||
1405 | cy_writeb(base_addr+(CySRER<<index), | ||
1406 | cy_readb(base_addr+(CySRER<<index)) | | ||
1407 | CyTxRdy); | ||
1408 | cy_sched_event(info, | ||
1409 | Cy_EVENT_WRITE_WAKEUP); | ||
1410 | } | ||
1411 | }else{ | ||
1412 | if(!(mdm_status & CyCTS)){ | ||
1413 | /* cy_stop isn't used | ||
1414 | because ... !!! */ | ||
1415 | info->tty->hw_stopped = 1; | ||
1416 | cy_writeb(base_addr+(CySRER<<index), | ||
1417 | cy_readb(base_addr+(CySRER<<index)) & | ||
1418 | ~CyTxRdy); | ||
1419 | } | ||
1420 | } | ||
1421 | } | ||
1422 | if(mdm_change & CyDSR){ | ||
1423 | } | ||
1424 | if(mdm_change & CyRI){ | ||
1425 | } | ||
1426 | } | ||
1427 | /* end of service */ | ||
1428 | cy_writeb(base_addr+(CyMIR<<index), | ||
1429 | (save_xir & 0x3f)); | ||
1430 | cy_writeb(base_addr+(CyCAR<<index), save_car); | ||
1431 | spin_unlock(&cinfo->card_lock); | ||
1432 | } | ||
1433 | } /* end while status != 0 */ | ||
1434 | } /* end loop for chips... */ | ||
1435 | } while(had_work); | ||
1436 | |||
1437 | /* clear interrupts */ | ||
1438 | spin_lock(&cinfo->card_lock); | ||
1439 | cy_writeb(card_base_addr + (Cy_ClrIntr<<index), 0); | ||
1440 | /* Cy_ClrIntr is 0x1800 */ | ||
1441 | spin_unlock(&cinfo->card_lock); | ||
1442 | return IRQ_HANDLED; | ||
1443 | } /* cyy_interrupt */ | ||
1444 | 1492 | ||
1445 | /***********************************************************/ | 1493 | /***********************************************************/ |
1446 | /********* End of block of Cyclom-Y specific code **********/ | 1494 | /********* End of block of Cyclom-Y specific code **********/ |
@@ -1448,643 +1496,655 @@ cyy_interrupt(int irq, void *dev_id) | |||
1448 | /***********************************************************/ | 1496 | /***********************************************************/ |
1449 | 1497 | ||
1450 | static int | 1498 | static int |
1451 | cyz_fetch_msg( struct cyclades_card *cinfo, | 1499 | cyz_fetch_msg(struct cyclades_card *cinfo, |
1452 | uclong *channel, ucchar *cmd, uclong *param) | 1500 | uclong * channel, ucchar * cmd, uclong * param) |
1453 | { | 1501 | { |
1454 | struct FIRM_ID __iomem *firm_id; | 1502 | struct FIRM_ID __iomem *firm_id; |
1455 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1503 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1456 | struct BOARD_CTRL __iomem *board_ctrl; | 1504 | struct BOARD_CTRL __iomem *board_ctrl; |
1457 | unsigned long loc_doorbell; | 1505 | unsigned long loc_doorbell; |
1458 | 1506 | ||
1459 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1507 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1460 | if (!ISZLOADED(*cinfo)){ | 1508 | if (!ISZLOADED(*cinfo)) { |
1461 | return (-1); | 1509 | return -1; |
1462 | } | 1510 | } |
1463 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1511 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & |
1464 | board_ctrl = &zfw_ctrl->board_ctrl; | 1512 | 0xfffff); |
1465 | 1513 | board_ctrl = &zfw_ctrl->board_ctrl; | |
1466 | loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *) | 1514 | |
1467 | (cinfo->ctl_addr))->loc_doorbell); | 1515 | loc_doorbell = cy_readl(&((struct RUNTIME_9060 __iomem *) |
1468 | if (loc_doorbell){ | 1516 | (cinfo->ctl_addr))->loc_doorbell); |
1469 | *cmd = (char)(0xff & loc_doorbell); | 1517 | if (loc_doorbell) { |
1470 | *channel = cy_readl(&board_ctrl->fwcmd_channel); | 1518 | *cmd = (char)(0xff & loc_doorbell); |
1471 | *param = (uclong)cy_readl(&board_ctrl->fwcmd_param); | 1519 | *channel = cy_readl(&board_ctrl->fwcmd_channel); |
1472 | cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->loc_doorbell, | 1520 | *param = (uclong) cy_readl(&board_ctrl->fwcmd_param); |
1473 | 0xffffffff); | 1521 | cy_writel(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> |
1474 | return 1; | 1522 | loc_doorbell, 0xffffffff); |
1475 | } | 1523 | return 1; |
1476 | return 0; | 1524 | } |
1477 | } /* cyz_fetch_msg */ | 1525 | return 0; |
1526 | } /* cyz_fetch_msg */ | ||
1478 | 1527 | ||
1479 | static int | 1528 | static int |
1480 | cyz_issue_cmd( struct cyclades_card *cinfo, | 1529 | cyz_issue_cmd(struct cyclades_card *cinfo, |
1481 | uclong channel, ucchar cmd, uclong param) | 1530 | uclong channel, ucchar cmd, uclong param) |
1482 | { | 1531 | { |
1483 | struct FIRM_ID __iomem *firm_id; | 1532 | struct FIRM_ID __iomem *firm_id; |
1484 | struct ZFW_CTRL __iomem *zfw_ctrl; | 1533 | struct ZFW_CTRL __iomem *zfw_ctrl; |
1485 | struct BOARD_CTRL __iomem *board_ctrl; | 1534 | struct BOARD_CTRL __iomem *board_ctrl; |
1486 | unsigned long __iomem *pci_doorbell; | 1535 | unsigned long __iomem *pci_doorbell; |
1487 | int index; | 1536 | int index; |
1488 | 1537 | ||
1489 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1538 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1490 | if (!ISZLOADED(*cinfo)){ | 1539 | if (!ISZLOADED(*cinfo)) { |
1491 | return (-1); | 1540 | return -1; |
1492 | } | 1541 | } |
1493 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1542 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & |
1494 | board_ctrl = &zfw_ctrl->board_ctrl; | 1543 | 0xfffff); |
1495 | 1544 | board_ctrl = &zfw_ctrl->board_ctrl; | |
1496 | index = 0; | 1545 | |
1497 | pci_doorbell = &((struct RUNTIME_9060 __iomem *) (cinfo->ctl_addr))->pci_doorbell; | 1546 | index = 0; |
1498 | while( (cy_readl(pci_doorbell) & 0xff) != 0){ | 1547 | pci_doorbell = |
1499 | if (index++ == 1000){ | 1548 | &((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->pci_doorbell; |
1500 | return((int)(cy_readl(pci_doorbell) & 0xff)); | 1549 | while ((cy_readl(pci_doorbell) & 0xff) != 0) { |
1501 | } | 1550 | if (index++ == 1000) { |
1502 | udelay(50L); | 1551 | return (int)(cy_readl(pci_doorbell) & 0xff); |
1503 | } | 1552 | } |
1504 | cy_writel(&board_ctrl->hcmd_channel, channel); | 1553 | udelay(50L); |
1505 | cy_writel(&board_ctrl->hcmd_param , param); | 1554 | } |
1506 | cy_writel(pci_doorbell, (long)cmd); | 1555 | cy_writel(&board_ctrl->hcmd_channel, channel); |
1507 | 1556 | cy_writel(&board_ctrl->hcmd_param, param); | |
1508 | return(0); | 1557 | cy_writel(pci_doorbell, (long)cmd); |
1509 | } /* cyz_issue_cmd */ | 1558 | |
1559 | return 0; | ||
1560 | } /* cyz_issue_cmd */ | ||
1510 | 1561 | ||
1511 | static void | 1562 | static void |
1512 | cyz_handle_rx(struct cyclades_port *info, | 1563 | cyz_handle_rx(struct cyclades_port *info, |
1513 | volatile struct CH_CTRL __iomem *ch_ctrl, | 1564 | volatile struct CH_CTRL __iomem * ch_ctrl, |
1514 | volatile struct BUF_CTRL __iomem *buf_ctrl) | 1565 | volatile struct BUF_CTRL __iomem * buf_ctrl) |
1515 | { | 1566 | { |
1516 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1567 | struct cyclades_card *cinfo = &cy_card[info->card]; |
1517 | struct tty_struct *tty = info->tty; | 1568 | struct tty_struct *tty = info->tty; |
1518 | volatile int char_count; | 1569 | volatile int char_count; |
1519 | int len; | 1570 | int len; |
1520 | #ifdef BLOCKMOVE | 1571 | #ifdef BLOCKMOVE |
1521 | int small_count; | 1572 | int small_count; |
1522 | #else | 1573 | #else |
1523 | char data; | 1574 | char data; |
1524 | #endif | 1575 | #endif |
1525 | volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; | 1576 | volatile uclong rx_put, rx_get, new_rx_get, rx_bufsize, rx_bufaddr; |
1526 | 1577 | ||
1527 | rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get); | 1578 | rx_get = new_rx_get = cy_readl(&buf_ctrl->rx_get); |
1528 | rx_put = cy_readl(&buf_ctrl->rx_put); | 1579 | rx_put = cy_readl(&buf_ctrl->rx_put); |
1529 | rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize); | 1580 | rx_bufsize = cy_readl(&buf_ctrl->rx_bufsize); |
1530 | rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr); | 1581 | rx_bufaddr = cy_readl(&buf_ctrl->rx_bufaddr); |
1531 | if (rx_put >= rx_get) | 1582 | if (rx_put >= rx_get) |
1532 | char_count = rx_put - rx_get; | 1583 | char_count = rx_put - rx_get; |
1533 | else | 1584 | else |
1534 | char_count = rx_put - rx_get + rx_bufsize; | 1585 | char_count = rx_put - rx_get + rx_bufsize; |
1535 | 1586 | ||
1536 | if ( char_count ) { | 1587 | if (char_count) { |
1537 | info->last_active = jiffies; | 1588 | info->last_active = jiffies; |
1538 | info->jiffies[1] = jiffies; | 1589 | info->jiffies[1] = jiffies; |
1539 | 1590 | ||
1540 | #ifdef CY_ENABLE_MONITORING | 1591 | #ifdef CY_ENABLE_MONITORING |
1541 | info->mon.int_count++; | 1592 | info->mon.int_count++; |
1542 | info->mon.char_count += char_count; | 1593 | info->mon.char_count += char_count; |
1543 | if (char_count > info->mon.char_max) | 1594 | if (char_count > info->mon.char_max) |
1544 | info->mon.char_max = char_count; | 1595 | info->mon.char_max = char_count; |
1545 | info->mon.char_last = char_count; | 1596 | info->mon.char_last = char_count; |
1546 | #endif | 1597 | #endif |
1547 | if(tty == 0){ | 1598 | if (tty == 0) { |
1548 | /* flush received characters */ | 1599 | /* flush received characters */ |
1549 | new_rx_get = (new_rx_get + char_count) & (rx_bufsize - 1); | 1600 | new_rx_get = (new_rx_get + char_count) & |
1550 | info->rflush_count++; | 1601 | (rx_bufsize - 1); |
1551 | }else{ | 1602 | info->rflush_count++; |
1603 | } else { | ||
1552 | #ifdef BLOCKMOVE | 1604 | #ifdef BLOCKMOVE |
1553 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) | 1605 | /* we'd like to use memcpy(t, f, n) and memset(s, c, count) |
1554 | for performance, but because of buffer boundaries, there | 1606 | for performance, but because of buffer boundaries, there |
1555 | may be several steps to the operation */ | 1607 | may be several steps to the operation */ |
1556 | while(0 < (small_count = | 1608 | while (0 < (small_count = min_t(unsigned int, |
1557 | min_t(unsigned int, (rx_bufsize - new_rx_get), | 1609 | rx_bufsize - new_rx_get, |
1558 | min_t(unsigned int, (TTY_FLIPBUF_SIZE - tty->flip.count), char_count)) | 1610 | min_t(unsigned int, TTY_FLIPBUF_SIZE - |
1559 | )) { | 1611 | tty->flip.count, char_count)))){ |
1560 | memcpy_fromio(tty->flip.char_buf_ptr, | 1612 | memcpy_fromio(tty->flip.char_buf_ptr, |
1561 | (char *)(cinfo->base_addr | 1613 | (char *)(cinfo->base_addr + rx_bufaddr + |
1562 | + rx_bufaddr + new_rx_get), | 1614 | new_rx_get), |
1563 | small_count); | 1615 | small_count); |
1564 | 1616 | ||
1565 | tty->flip.char_buf_ptr += small_count; | 1617 | tty->flip.char_buf_ptr += small_count; |
1566 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, small_count); | 1618 | memset(tty->flip.flag_buf_ptr, TTY_NORMAL, |
1567 | tty->flip.flag_buf_ptr += small_count; | 1619 | small_count); |
1568 | new_rx_get = (new_rx_get + small_count) & (rx_bufsize - 1); | 1620 | tty->flip.flag_buf_ptr += small_count; |
1569 | char_count -= small_count; | 1621 | new_rx_get = (new_rx_get + small_count) & |
1570 | info->icount.rx += small_count; | 1622 | (rx_bufsize - 1); |
1571 | info->idle_stats.recv_bytes += small_count; | 1623 | char_count -= small_count; |
1572 | tty->flip.count += small_count; | 1624 | info->icount.rx += small_count; |
1573 | } | 1625 | info->idle_stats.recv_bytes += small_count; |
1626 | tty->flip.count += small_count; | ||
1627 | } | ||
1574 | #else | 1628 | #else |
1575 | len = tty_buffer_request_room(tty, char_count); | 1629 | len = tty_buffer_request_room(tty, char_count); |
1576 | while(len--){ | 1630 | while (len--) { |
1577 | data = cy_readb(cinfo->base_addr + rx_bufaddr + new_rx_get); | 1631 | data = cy_readb(cinfo->base_addr + rx_bufaddr + |
1578 | new_rx_get = (new_rx_get + 1) & (rx_bufsize - 1); | 1632 | new_rx_get); |
1579 | tty_insert_flip_char(tty, data, TTY_NORMAL); | 1633 | new_rx_get = (new_rx_get + 1)& (rx_bufsize - 1); |
1580 | info->idle_stats.recv_bytes++; | 1634 | tty_insert_flip_char(tty, data, TTY_NORMAL); |
1581 | info->icount.rx++; | 1635 | info->idle_stats.recv_bytes++; |
1582 | } | 1636 | info->icount.rx++; |
1637 | } | ||
1583 | #endif | 1638 | #endif |
1584 | #ifdef CONFIG_CYZ_INTR | 1639 | #ifdef CONFIG_CYZ_INTR |
1585 | /* Recalculate the number of chars in the RX buffer and issue | 1640 | /* Recalculate the number of chars in the RX buffer and issue |
1586 | a cmd in case it's higher than the RX high water mark */ | 1641 | a cmd in case it's higher than the RX high water mark */ |
1587 | rx_put = cy_readl(&buf_ctrl->rx_put); | 1642 | rx_put = cy_readl(&buf_ctrl->rx_put); |
1588 | if (rx_put >= rx_get) | 1643 | if (rx_put >= rx_get) |
1589 | char_count = rx_put - rx_get; | 1644 | char_count = rx_put - rx_get; |
1590 | else | 1645 | else |
1591 | char_count = rx_put - rx_get + rx_bufsize; | 1646 | char_count = rx_put - rx_get + rx_bufsize; |
1592 | if(char_count >= cy_readl(&buf_ctrl->rx_threshold)) { | 1647 | if (char_count >= (int)cy_readl(&buf_ctrl-> |
1593 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); | 1648 | rx_threshold)) { |
1594 | } | 1649 | cy_sched_event(info, Cy_EVENT_Z_RX_FULL); |
1650 | } | ||
1595 | #endif | 1651 | #endif |
1596 | info->idle_stats.recv_idle = jiffies; | 1652 | info->idle_stats.recv_idle = jiffies; |
1597 | tty_schedule_flip(tty); | 1653 | tty_schedule_flip(tty); |
1654 | } | ||
1655 | /* Update rx_get */ | ||
1656 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | ||
1598 | } | 1657 | } |
1599 | /* Update rx_get */ | ||
1600 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | ||
1601 | } | ||
1602 | } | 1658 | } |
1603 | 1659 | ||
1604 | static void | 1660 | static void |
1605 | cyz_handle_tx(struct cyclades_port *info, | 1661 | cyz_handle_tx(struct cyclades_port *info, |
1606 | volatile struct CH_CTRL __iomem *ch_ctrl, | 1662 | volatile struct CH_CTRL __iomem * ch_ctrl, |
1607 | volatile struct BUF_CTRL __iomem *buf_ctrl) | 1663 | volatile struct BUF_CTRL __iomem * buf_ctrl) |
1608 | { | 1664 | { |
1609 | struct cyclades_card *cinfo = &cy_card[info->card]; | 1665 | struct cyclades_card *cinfo = &cy_card[info->card]; |
1610 | struct tty_struct *tty = info->tty; | 1666 | struct tty_struct *tty = info->tty; |
1611 | char data; | 1667 | char data; |
1612 | volatile int char_count; | 1668 | volatile int char_count; |
1613 | #ifdef BLOCKMOVE | 1669 | #ifdef BLOCKMOVE |
1614 | int small_count; | 1670 | int small_count; |
1615 | #endif | 1671 | #endif |
1616 | volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr; | 1672 | volatile uclong tx_put, tx_get, tx_bufsize, tx_bufaddr; |
1617 | 1673 | ||
1618 | if (info->xmit_cnt <= 0) /* Nothing to transmit */ | 1674 | if (info->xmit_cnt <= 0) /* Nothing to transmit */ |
1619 | return; | 1675 | return; |
1620 | 1676 | ||
1621 | tx_get = cy_readl(&buf_ctrl->tx_get); | 1677 | tx_get = cy_readl(&buf_ctrl->tx_get); |
1622 | tx_put = cy_readl(&buf_ctrl->tx_put); | 1678 | tx_put = cy_readl(&buf_ctrl->tx_put); |
1623 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); | 1679 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); |
1624 | tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr); | 1680 | tx_bufaddr = cy_readl(&buf_ctrl->tx_bufaddr); |
1625 | if (tx_put >= tx_get) | 1681 | if (tx_put >= tx_get) |
1626 | char_count = tx_get - tx_put - 1 + tx_bufsize; | 1682 | char_count = tx_get - tx_put - 1 + tx_bufsize; |
1627 | else | 1683 | else |
1628 | char_count = tx_get - tx_put - 1; | 1684 | char_count = tx_get - tx_put - 1; |
1629 | 1685 | ||
1630 | if ( char_count ) { | 1686 | if (char_count) { |
1631 | 1687 | ||
1632 | if( tty == 0 ){ | 1688 | if (tty == 0) { |
1633 | goto ztxdone; | 1689 | goto ztxdone; |
1634 | } | 1690 | } |
1635 | 1691 | ||
1636 | if(info->x_char) { /* send special char */ | 1692 | if (info->x_char) { /* send special char */ |
1637 | data = info->x_char; | 1693 | data = info->x_char; |
1638 | 1694 | ||
1639 | cy_writeb((cinfo->base_addr + tx_bufaddr + tx_put), data); | 1695 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); |
1640 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1696 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1641 | info->x_char = 0; | 1697 | info->x_char = 0; |
1642 | char_count--; | 1698 | char_count--; |
1643 | info->icount.tx++; | 1699 | info->icount.tx++; |
1644 | info->last_active = jiffies; | 1700 | info->last_active = jiffies; |
1645 | info->jiffies[2] = jiffies; | 1701 | info->jiffies[2] = jiffies; |
1646 | } | 1702 | } |
1647 | #ifdef BLOCKMOVE | 1703 | #ifdef BLOCKMOVE |
1648 | while(0 < (small_count = | 1704 | while (0 < (small_count = min_t(unsigned int, |
1649 | min_t(unsigned int, (tx_bufsize - tx_put), | 1705 | tx_bufsize - tx_put, min_t(unsigned int, |
1650 | min_t(unsigned int, (SERIAL_XMIT_SIZE - info->xmit_tail), | 1706 | (SERIAL_XMIT_SIZE - info->xmit_tail), |
1651 | min_t(unsigned int, info->xmit_cnt, char_count))))) { | 1707 | min_t(unsigned int, info->xmit_cnt, |
1652 | 1708 | char_count))))) { | |
1653 | memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + tx_put), | 1709 | |
1654 | &info->xmit_buf[info->xmit_tail], | 1710 | memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + |
1655 | small_count); | 1711 | tx_put), |
1656 | 1712 | &info->xmit_buf[info->xmit_tail], | |
1657 | tx_put = (tx_put + small_count) & (tx_bufsize - 1); | 1713 | small_count); |
1658 | char_count -= small_count; | 1714 | |
1659 | info->icount.tx += small_count; | 1715 | tx_put = (tx_put + small_count) & (tx_bufsize - 1); |
1660 | info->xmit_cnt -= small_count; | 1716 | char_count -= small_count; |
1661 | info->xmit_tail = | 1717 | info->icount.tx += small_count; |
1662 | (info->xmit_tail + small_count) & (SERIAL_XMIT_SIZE - 1); | 1718 | info->xmit_cnt -= small_count; |
1663 | info->last_active = jiffies; | 1719 | info->xmit_tail = (info->xmit_tail + small_count) & |
1664 | info->jiffies[2] = jiffies; | 1720 | (SERIAL_XMIT_SIZE - 1); |
1665 | } | 1721 | info->last_active = jiffies; |
1722 | info->jiffies[2] = jiffies; | ||
1723 | } | ||
1666 | #else | 1724 | #else |
1667 | while (info->xmit_cnt && char_count){ | 1725 | while (info->xmit_cnt && char_count) { |
1668 | data = info->xmit_buf[info->xmit_tail]; | 1726 | data = info->xmit_buf[info->xmit_tail]; |
1669 | info->xmit_cnt--; | 1727 | info->xmit_cnt--; |
1670 | info->xmit_tail = (info->xmit_tail + 1) & (SERIAL_XMIT_SIZE - 1); | 1728 | info->xmit_tail = (info->xmit_tail + 1) & |
1671 | 1729 | (SERIAL_XMIT_SIZE - 1); | |
1672 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); | 1730 | |
1673 | tx_put = (tx_put + 1) & (tx_bufsize - 1); | 1731 | cy_writeb(cinfo->base_addr + tx_bufaddr + tx_put, data); |
1674 | char_count--; | 1732 | tx_put = (tx_put + 1) & (tx_bufsize - 1); |
1675 | info->icount.tx++; | 1733 | char_count--; |
1676 | info->last_active = jiffies; | 1734 | info->icount.tx++; |
1677 | info->jiffies[2] = jiffies; | 1735 | info->last_active = jiffies; |
1678 | } | 1736 | info->jiffies[2] = jiffies; |
1737 | } | ||
1679 | #endif | 1738 | #endif |
1680 | ztxdone: | 1739 | ztxdone: |
1681 | if (info->xmit_cnt < WAKEUP_CHARS) { | 1740 | if (info->xmit_cnt < WAKEUP_CHARS) { |
1682 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); | 1741 | cy_sched_event(info, Cy_EVENT_WRITE_WAKEUP); |
1742 | } | ||
1743 | /* Update tx_put */ | ||
1744 | cy_writel(&buf_ctrl->tx_put, tx_put); | ||
1683 | } | 1745 | } |
1684 | /* Update tx_put */ | ||
1685 | cy_writel(&buf_ctrl->tx_put, tx_put); | ||
1686 | } | ||
1687 | } | 1746 | } |
1688 | 1747 | ||
1689 | static void | 1748 | static void cyz_handle_cmd(struct cyclades_card *cinfo) |
1690 | cyz_handle_cmd(struct cyclades_card *cinfo) | ||
1691 | { | 1749 | { |
1692 | struct tty_struct *tty; | 1750 | struct tty_struct *tty; |
1693 | struct cyclades_port *info; | 1751 | struct cyclades_port *info; |
1694 | static volatile struct FIRM_ID __iomem *firm_id; | 1752 | static volatile struct FIRM_ID __iomem *firm_id; |
1695 | static volatile struct ZFW_CTRL __iomem *zfw_ctrl; | 1753 | static volatile struct ZFW_CTRL __iomem *zfw_ctrl; |
1696 | static volatile struct BOARD_CTRL __iomem *board_ctrl; | 1754 | static volatile struct BOARD_CTRL __iomem *board_ctrl; |
1697 | static volatile struct CH_CTRL __iomem *ch_ctrl; | 1755 | static volatile struct CH_CTRL __iomem *ch_ctrl; |
1698 | static volatile struct BUF_CTRL __iomem *buf_ctrl; | 1756 | static volatile struct BUF_CTRL __iomem *buf_ctrl; |
1699 | uclong channel; | 1757 | uclong channel; |
1700 | ucchar cmd; | 1758 | ucchar cmd; |
1701 | uclong param; | 1759 | uclong param; |
1702 | uclong hw_ver, fw_ver; | 1760 | uclong hw_ver, fw_ver; |
1703 | int special_count; | 1761 | int special_count; |
1704 | int delta_count; | 1762 | int delta_count; |
1705 | 1763 | ||
1706 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1764 | firm_id = cinfo->base_addr + ID_ADDRESS; |
1707 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1765 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & |
1708 | board_ctrl = &zfw_ctrl->board_ctrl; | 1766 | 0xfffff); |
1709 | fw_ver = cy_readl(&board_ctrl->fw_version); | 1767 | board_ctrl = &zfw_ctrl->board_ctrl; |
1710 | hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))->mail_box_0); | 1768 | fw_ver = cy_readl(&board_ctrl->fw_version); |
1711 | 1769 | hw_ver = cy_readl(&((struct RUNTIME_9060 __iomem *)(cinfo->ctl_addr))-> | |
1712 | 1770 | mail_box_0); | |
1713 | while(cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { | 1771 | |
1714 | special_count = 0; | 1772 | while (cyz_fetch_msg(cinfo, &channel, &cmd, ¶m) == 1) { |
1715 | delta_count = 0; | 1773 | special_count = 0; |
1716 | info = &cy_port[channel + cinfo->first_line]; | 1774 | delta_count = 0; |
1717 | if((tty = info->tty) == 0) { | 1775 | info = &cy_port[channel + cinfo->first_line]; |
1718 | continue; | 1776 | if ((tty = info->tty) == 0) { |
1719 | } | 1777 | continue; |
1720 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | ||
1721 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | ||
1722 | |||
1723 | switch(cmd) { | ||
1724 | case C_CM_PR_ERROR: | ||
1725 | tty_insert_flip_char(tty, 0, TTY_PARITY); | ||
1726 | info->icount.rx++; | ||
1727 | special_count++; | ||
1728 | break; | ||
1729 | case C_CM_FR_ERROR: | ||
1730 | tty_insert_flip_char(tty, 0, TTY_FRAME); | ||
1731 | info->icount.rx++; | ||
1732 | special_count++; | ||
1733 | break; | ||
1734 | case C_CM_RXBRK: | ||
1735 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
1736 | info->icount.rx++; | ||
1737 | special_count++; | ||
1738 | break; | ||
1739 | case C_CM_MDCD: | ||
1740 | info->icount.dcd++; | ||
1741 | delta_count++; | ||
1742 | if (info->flags & ASYNC_CHECK_CD){ | ||
1743 | if ((fw_ver > 241 ? | ||
1744 | ((u_long)param) : | ||
1745 | cy_readl(&ch_ctrl->rs_status)) & C_RS_DCD) { | ||
1746 | cy_sched_event(info, Cy_EVENT_OPEN_WAKEUP); | ||
1747 | }else{ | ||
1748 | cy_sched_event(info, Cy_EVENT_HANGUP); | ||
1749 | } | ||
1750 | } | 1778 | } |
1751 | break; | 1779 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
1752 | case C_CM_MCTS: | 1780 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); |
1753 | info->icount.cts++; | 1781 | |
1754 | delta_count++; | 1782 | switch (cmd) { |
1755 | break; | 1783 | case C_CM_PR_ERROR: |
1756 | case C_CM_MRI: | 1784 | tty_insert_flip_char(tty, 0, TTY_PARITY); |
1757 | info->icount.rng++; | 1785 | info->icount.rx++; |
1758 | delta_count++; | 1786 | special_count++; |
1759 | break; | 1787 | break; |
1760 | case C_CM_MDSR: | 1788 | case C_CM_FR_ERROR: |
1761 | info->icount.dsr++; | 1789 | tty_insert_flip_char(tty, 0, TTY_FRAME); |
1762 | delta_count++; | 1790 | info->icount.rx++; |
1763 | break; | 1791 | special_count++; |
1792 | break; | ||
1793 | case C_CM_RXBRK: | ||
1794 | tty_insert_flip_char(tty, 0, TTY_BREAK); | ||
1795 | info->icount.rx++; | ||
1796 | special_count++; | ||
1797 | break; | ||
1798 | case C_CM_MDCD: | ||
1799 | info->icount.dcd++; | ||
1800 | delta_count++; | ||
1801 | if (info->flags & ASYNC_CHECK_CD) { | ||
1802 | if ((fw_ver > 241 ? ((u_long) param) : | ||
1803 | cy_readl(&ch_ctrl->rs_status)) & | ||
1804 | C_RS_DCD) { | ||
1805 | cy_sched_event(info, | ||
1806 | Cy_EVENT_OPEN_WAKEUP); | ||
1807 | } else { | ||
1808 | cy_sched_event(info, Cy_EVENT_HANGUP); | ||
1809 | } | ||
1810 | } | ||
1811 | break; | ||
1812 | case C_CM_MCTS: | ||
1813 | info->icount.cts++; | ||
1814 | delta_count++; | ||
1815 | break; | ||
1816 | case C_CM_MRI: | ||
1817 | info->icount.rng++; | ||
1818 | delta_count++; | ||
1819 | break; | ||
1820 | case C_CM_MDSR: | ||
1821 | info->icount.dsr++; | ||
1822 | delta_count++; | ||
1823 | break; | ||
1764 | #ifdef Z_WAKE | 1824 | #ifdef Z_WAKE |
1765 | case C_CM_IOCTLW: | 1825 | case C_CM_IOCTLW: |
1766 | cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP); | 1826 | cy_sched_event(info, Cy_EVENT_SHUTDOWN_WAKEUP); |
1767 | break; | 1827 | break; |
1768 | #endif | 1828 | #endif |
1769 | #ifdef CONFIG_CYZ_INTR | 1829 | #ifdef CONFIG_CYZ_INTR |
1770 | case C_CM_RXHIWM: | 1830 | case C_CM_RXHIWM: |
1771 | case C_CM_RXNNDT: | 1831 | case C_CM_RXNNDT: |
1772 | case C_CM_INTBACK2: | 1832 | case C_CM_INTBACK2: |
1773 | /* Reception Interrupt */ | 1833 | /* Reception Interrupt */ |
1774 | #ifdef CY_DEBUG_INTERRUPTS | 1834 | #ifdef CY_DEBUG_INTERRUPTS |
1775 | printk("cyz_interrupt: rcvd intr, card %d, port %ld\n\r", | 1835 | printk("cyz_interrupt: rcvd intr, card %d, " |
1776 | info->card, channel); | 1836 | "port %ld\n\r", info->card, channel); |
1777 | #endif | 1837 | #endif |
1778 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1838 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); |
1779 | break; | 1839 | break; |
1780 | case C_CM_TXBEMPTY: | 1840 | case C_CM_TXBEMPTY: |
1781 | case C_CM_TXLOWWM: | 1841 | case C_CM_TXLOWWM: |
1782 | case C_CM_INTBACK: | 1842 | case C_CM_INTBACK: |
1783 | /* Transmission Interrupt */ | 1843 | /* Transmission Interrupt */ |
1784 | #ifdef CY_DEBUG_INTERRUPTS | 1844 | #ifdef CY_DEBUG_INTERRUPTS |
1785 | printk("cyz_interrupt: xmit intr, card %d, port %ld\n\r", | 1845 | printk("cyz_interrupt: xmit intr, card %d, " |
1786 | info->card, channel); | 1846 | "port %ld\n\r", info->card, channel); |
1787 | #endif | 1847 | #endif |
1788 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1848 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); |
1789 | break; | 1849 | break; |
1790 | #endif /* CONFIG_CYZ_INTR */ | 1850 | #endif /* CONFIG_CYZ_INTR */ |
1791 | case C_CM_FATAL: | 1851 | case C_CM_FATAL: |
1792 | /* should do something with this !!! */ | 1852 | /* should do something with this !!! */ |
1793 | break; | 1853 | break; |
1794 | default: | 1854 | default: |
1795 | break; | 1855 | break; |
1856 | } | ||
1857 | if (delta_count) | ||
1858 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | ||
1859 | if (special_count) | ||
1860 | tty_schedule_flip(tty); | ||
1796 | } | 1861 | } |
1797 | if(delta_count) | ||
1798 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | ||
1799 | if(special_count) | ||
1800 | tty_schedule_flip(tty); | ||
1801 | } | ||
1802 | } | 1862 | } |
1803 | 1863 | ||
1804 | #ifdef CONFIG_CYZ_INTR | 1864 | #ifdef CONFIG_CYZ_INTR |
1805 | static irqreturn_t | 1865 | static irqreturn_t cyz_interrupt(int irq, void *dev_id) |
1806 | cyz_interrupt(int irq, void *dev_id) | ||
1807 | { | 1866 | { |
1808 | struct cyclades_card *cinfo; | 1867 | struct cyclades_card *cinfo; |
1809 | 1868 | ||
1810 | if((cinfo = (struct cyclades_card *)dev_id) == 0){ | 1869 | if ((cinfo = (struct cyclades_card *)dev_id) == 0) { |
1811 | #ifdef CY_DEBUG_INTERRUPTS | 1870 | #ifdef CY_DEBUG_INTERRUPTS |
1812 | printk("cyz_interrupt: spurious interrupt %d\n\r", irq); | 1871 | printk("cyz_interrupt: spurious interrupt %d\n\r", irq); |
1813 | #endif | 1872 | #endif |
1814 | return IRQ_NONE; /* spurious interrupt */ | 1873 | return IRQ_NONE; /* spurious interrupt */ |
1815 | } | 1874 | } |
1816 | 1875 | ||
1817 | if (!ISZLOADED(*cinfo)) { | 1876 | if (!ISZLOADED(*cinfo)) { |
1818 | #ifdef CY_DEBUG_INTERRUPTS | 1877 | #ifdef CY_DEBUG_INTERRUPTS |
1819 | printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq); | 1878 | printk("cyz_interrupt: board not yet loaded (IRQ%d).\n\r", irq); |
1820 | #endif | 1879 | #endif |
1821 | return IRQ_NONE; | 1880 | return IRQ_NONE; |
1822 | } | 1881 | } |
1823 | 1882 | ||
1824 | /* Handle the interrupts */ | 1883 | /* Handle the interrupts */ |
1825 | cyz_handle_cmd(cinfo); | 1884 | cyz_handle_cmd(cinfo); |
1826 | 1885 | ||
1827 | return IRQ_HANDLED; | 1886 | return IRQ_HANDLED; |
1828 | } /* cyz_interrupt */ | 1887 | } /* cyz_interrupt */ |
1829 | 1888 | ||
1830 | static void | 1889 | static void cyz_rx_restart(unsigned long arg) |
1831 | cyz_rx_restart(unsigned long arg) | ||
1832 | { | 1890 | { |
1833 | struct cyclades_port *info = (struct cyclades_port *)arg; | 1891 | struct cyclades_port *info = (struct cyclades_port *)arg; |
1834 | int retval; | 1892 | int retval; |
1835 | int card = info->card; | 1893 | int card = info->card; |
1836 | uclong channel = (info->line) - (cy_card[card].first_line); | 1894 | uclong channel = (info->line) - (cy_card[card].first_line); |
1837 | unsigned long flags; | 1895 | unsigned long flags; |
1838 | 1896 | ||
1839 | CY_LOCK(info, flags); | 1897 | CY_LOCK(info, flags); |
1840 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L); | 1898 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK2, 0L); |
1841 | if (retval != 0){ | 1899 | if (retval != 0) { |
1842 | printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", | 1900 | printk("cyc:cyz_rx_restart retval on ttyC%d was %x\n", |
1843 | info->line, retval); | 1901 | info->line, retval); |
1844 | } | 1902 | } |
1845 | cyz_rx_full_timer[info->line].function = NULL; | 1903 | cyz_rx_full_timer[info->line].function = NULL; |
1846 | CY_UNLOCK(info, flags); | 1904 | CY_UNLOCK(info, flags); |
1847 | } | 1905 | } |
1848 | 1906 | ||
1849 | #else /* CONFIG_CYZ_INTR */ | 1907 | #else /* CONFIG_CYZ_INTR */ |
1850 | 1908 | ||
1851 | static void | 1909 | static void cyz_poll(unsigned long arg) |
1852 | cyz_poll(unsigned long arg) | ||
1853 | { | 1910 | { |
1854 | struct cyclades_card *cinfo; | 1911 | struct cyclades_card *cinfo; |
1855 | struct cyclades_port *info; | 1912 | struct cyclades_port *info; |
1856 | struct tty_struct *tty; | 1913 | struct tty_struct *tty; |
1857 | static volatile struct FIRM_ID *firm_id; | 1914 | static volatile struct FIRM_ID *firm_id; |
1858 | static volatile struct ZFW_CTRL *zfw_ctrl; | 1915 | static volatile struct ZFW_CTRL *zfw_ctrl; |
1859 | static volatile struct BOARD_CTRL *board_ctrl; | 1916 | static volatile struct BOARD_CTRL *board_ctrl; |
1860 | static volatile struct CH_CTRL *ch_ctrl; | 1917 | static volatile struct CH_CTRL *ch_ctrl; |
1861 | static volatile struct BUF_CTRL *buf_ctrl; | 1918 | static volatile struct BUF_CTRL *buf_ctrl; |
1862 | int card, port; | 1919 | int card, port; |
1863 | |||
1864 | cyz_timerlist.expires = jiffies + (HZ); | ||
1865 | for (card = 0 ; card < NR_CARDS ; card++){ | ||
1866 | cinfo = &cy_card[card]; | ||
1867 | |||
1868 | if (!IS_CYC_Z(*cinfo)) continue; | ||
1869 | if (!ISZLOADED(*cinfo)) continue; | ||
1870 | 1920 | ||
1871 | firm_id = cinfo->base_addr + ID_ADDRESS; | 1921 | cyz_timerlist.expires = jiffies + (HZ); |
1872 | zfw_ctrl = cinfo->base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 1922 | for (card = 0; card < NR_CARDS; card++) { |
1873 | board_ctrl = &(zfw_ctrl->board_ctrl); | 1923 | cinfo = &cy_card[card]; |
1924 | |||
1925 | if (!IS_CYC_Z(*cinfo)) | ||
1926 | continue; | ||
1927 | if (!ISZLOADED(*cinfo)) | ||
1928 | continue; | ||
1929 | |||
1930 | firm_id = cinfo->base_addr + ID_ADDRESS; | ||
1931 | zfw_ctrl = cinfo->base_addr + | ||
1932 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
1933 | board_ctrl = &(zfw_ctrl->board_ctrl); | ||
1874 | 1934 | ||
1875 | /* Skip first polling cycle to avoid racing conditions with the FW */ | 1935 | /* Skip first polling cycle to avoid racing conditions with the FW */ |
1876 | if (!cinfo->intr_enabled) { | 1936 | if (!cinfo->intr_enabled) { |
1877 | cinfo->nports = (int) cy_readl(&board_ctrl->n_channel); | 1937 | cinfo->nports = (int)cy_readl(&board_ctrl->n_channel); |
1878 | cinfo->intr_enabled = 1; | 1938 | cinfo->intr_enabled = 1; |
1879 | continue; | 1939 | continue; |
1880 | } | 1940 | } |
1881 | 1941 | ||
1882 | cyz_handle_cmd(cinfo); | 1942 | cyz_handle_cmd(cinfo); |
1883 | 1943 | ||
1884 | for (port = 0 ; port < cinfo->nports ; port++) { | 1944 | for (port = 0; port < cinfo->nports; port++) { |
1885 | info = &cy_port[ port + cinfo->first_line ]; | 1945 | info = &cy_port[port + cinfo->first_line]; |
1886 | tty = info->tty; | 1946 | tty = info->tty; |
1887 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); | 1947 | ch_ctrl = &(zfw_ctrl->ch_ctrl[port]); |
1888 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); | 1948 | buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); |
1889 | 1949 | ||
1890 | if (!info->throttle) | 1950 | if (!info->throttle) |
1891 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); | 1951 | cyz_handle_rx(info, ch_ctrl, buf_ctrl); |
1892 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); | 1952 | cyz_handle_tx(info, ch_ctrl, buf_ctrl); |
1953 | } | ||
1954 | /* poll every 'cyz_polling_cycle' period */ | ||
1955 | cyz_timerlist.expires = jiffies + cyz_polling_cycle; | ||
1893 | } | 1956 | } |
1894 | /* poll every 'cyz_polling_cycle' period */ | 1957 | add_timer(&cyz_timerlist); |
1895 | cyz_timerlist.expires = jiffies + cyz_polling_cycle; | 1958 | } /* cyz_poll */ |
1896 | } | ||
1897 | add_timer(&cyz_timerlist); | ||
1898 | 1959 | ||
1899 | return; | 1960 | #endif /* CONFIG_CYZ_INTR */ |
1900 | } /* cyz_poll */ | ||
1901 | |||
1902 | #endif /* CONFIG_CYZ_INTR */ | ||
1903 | 1961 | ||
1904 | /********** End of block of Cyclades-Z specific code *********/ | 1962 | /********** End of block of Cyclades-Z specific code *********/ |
1905 | /***********************************************************/ | 1963 | /***********************************************************/ |
1906 | 1964 | ||
1907 | |||
1908 | /* This is called whenever a port becomes active; | 1965 | /* This is called whenever a port becomes active; |
1909 | interrupts are enabled and DTR & RTS are turned on. | 1966 | interrupts are enabled and DTR & RTS are turned on. |
1910 | */ | 1967 | */ |
1911 | static int | 1968 | static int startup(struct cyclades_port *info) |
1912 | startup(struct cyclades_port * info) | ||
1913 | { | 1969 | { |
1914 | unsigned long flags; | 1970 | unsigned long flags; |
1915 | int retval = 0; | 1971 | int retval = 0; |
1916 | void __iomem *base_addr; | 1972 | void __iomem *base_addr; |
1917 | int card,chip,channel,index; | 1973 | int card, chip, channel, index; |
1918 | unsigned long page; | 1974 | unsigned long page; |
1919 | 1975 | ||
1920 | card = info->card; | 1976 | card = info->card; |
1921 | channel = (info->line) - (cy_card[card].first_line); | 1977 | channel = (info->line) - (cy_card[card].first_line); |
1922 | 1978 | ||
1923 | page = get_zeroed_page(GFP_KERNEL); | 1979 | page = get_zeroed_page(GFP_KERNEL); |
1924 | if (!page) | 1980 | if (!page) |
1925 | return -ENOMEM; | 1981 | return -ENOMEM; |
1926 | 1982 | ||
1927 | CY_LOCK(info, flags); | 1983 | CY_LOCK(info, flags); |
1928 | 1984 | ||
1929 | if (info->flags & ASYNC_INITIALIZED){ | 1985 | if (info->flags & ASYNC_INITIALIZED) { |
1930 | free_page(page); | 1986 | free_page(page); |
1931 | goto errout; | 1987 | goto errout; |
1932 | } | 1988 | } |
1933 | 1989 | ||
1934 | if (!info->type){ | 1990 | if (!info->type) { |
1935 | if (info->tty){ | 1991 | if (info->tty) { |
1936 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 1992 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
1937 | } | 1993 | } |
1938 | free_page(page); | 1994 | free_page(page); |
1939 | goto errout; | 1995 | goto errout; |
1940 | } | 1996 | } |
1941 | 1997 | ||
1942 | if (info->xmit_buf) | 1998 | if (info->xmit_buf) |
1943 | free_page(page); | 1999 | free_page(page); |
1944 | else | 2000 | else |
1945 | info->xmit_buf = (unsigned char *) page; | 2001 | info->xmit_buf = (unsigned char *)page; |
1946 | 2002 | ||
1947 | CY_UNLOCK(info, flags); | 2003 | CY_UNLOCK(info, flags); |
1948 | 2004 | ||
1949 | set_line_char(info); | 2005 | set_line_char(info); |
1950 | 2006 | ||
1951 | if (!IS_CYC_Z(cy_card[card])) { | 2007 | if (!IS_CYC_Z(cy_card[card])) { |
1952 | chip = channel>>2; | 2008 | chip = channel >> 2; |
1953 | channel &= 0x03; | 2009 | channel &= 0x03; |
1954 | index = cy_card[card].bus_index; | 2010 | index = cy_card[card].bus_index; |
1955 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | 2011 | base_addr = cy_card[card].base_addr + |
2012 | (cy_chip_offset[chip] << index); | ||
1956 | 2013 | ||
1957 | #ifdef CY_DEBUG_OPEN | 2014 | #ifdef CY_DEBUG_OPEN |
1958 | printk("cyc startup card %d, chip %d, channel %d, base_addr %lx\n", | 2015 | printk("cyc startup card %d, chip %d, channel %d, " |
1959 | card, chip, channel, (long)base_addr);/**/ | 2016 | "base_addr %lx\n", |
2017 | card, chip, channel, (long)base_addr); | ||
2018 | /**/ | ||
1960 | #endif | 2019 | #endif |
2020 | CY_LOCK(info, flags); | ||
1961 | 2021 | ||
1962 | CY_LOCK(info, flags); | 2022 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
1963 | |||
1964 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | ||
1965 | 2023 | ||
1966 | cy_writeb(base_addr+(CyRTPR<<index), (info->default_timeout | 2024 | cy_writeb(base_addr + (CyRTPR << index), |
1967 | ? info->default_timeout : 0x02)); /* 10ms rx timeout */ | 2025 | (info->default_timeout ? info->default_timeout : 0x02)); |
2026 | /* 10ms rx timeout */ | ||
1968 | 2027 | ||
1969 | cyy_issue_cmd(base_addr,CyCHAN_CTL|CyENB_RCVR|CyENB_XMTR,index); | 2028 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyENB_RCVR | CyENB_XMTR, |
2029 | index); | ||
1970 | 2030 | ||
1971 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 2031 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
1972 | cy_writeb(base_addr+(CyMSVR1<<index), CyRTS); | 2032 | cy_writeb(base_addr + (CyMSVR1 << index), CyRTS); |
1973 | cy_writeb(base_addr+(CyMSVR2<<index), CyDTR); | 2033 | cy_writeb(base_addr + (CyMSVR2 << index), CyDTR); |
1974 | 2034 | ||
1975 | #ifdef CY_DEBUG_DTR | 2035 | #ifdef CY_DEBUG_DTR |
1976 | printk("cyc:startup raising DTR\n"); | 2036 | printk("cyc:startup raising DTR\n"); |
1977 | printk(" status: 0x%x, 0x%x\n", | 2037 | printk(" status: 0x%x, 0x%x\n", |
1978 | cy_readb(base_addr+(CyMSVR1<<index)), | 2038 | cy_readb(base_addr + (CyMSVR1 << index)), |
1979 | cy_readb(base_addr+(CyMSVR2<<index))); | 2039 | cy_readb(base_addr + (CyMSVR2 << index))); |
1980 | #endif | 2040 | #endif |
1981 | 2041 | ||
1982 | cy_writeb(base_addr+(CySRER<<index), | 2042 | cy_writeb(base_addr + (CySRER << index), |
1983 | cy_readb(base_addr+(CySRER<<index)) | CyRxData); | 2043 | cy_readb(base_addr + (CySRER << index)) | CyRxData); |
1984 | info->flags |= ASYNC_INITIALIZED; | 2044 | info->flags |= ASYNC_INITIALIZED; |
1985 | 2045 | ||
1986 | if (info->tty){ | 2046 | if (info->tty) { |
1987 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 2047 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
1988 | } | 2048 | } |
1989 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 2049 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
1990 | info->breakon = info->breakoff = 0; | 2050 | info->breakon = info->breakoff = 0; |
1991 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); | 2051 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); |
1992 | info->idle_stats.in_use = | 2052 | info->idle_stats.in_use = |
1993 | info->idle_stats.recv_idle = | 2053 | info->idle_stats.recv_idle = |
1994 | info->idle_stats.xmit_idle = jiffies; | 2054 | info->idle_stats.xmit_idle = jiffies; |
1995 | 2055 | ||
1996 | CY_UNLOCK(info, flags); | 2056 | CY_UNLOCK(info, flags); |
1997 | 2057 | ||
1998 | } else { | 2058 | } else { |
1999 | struct FIRM_ID __iomem *firm_id; | 2059 | struct FIRM_ID __iomem *firm_id; |
2000 | struct ZFW_CTRL __iomem *zfw_ctrl; | 2060 | struct ZFW_CTRL __iomem *zfw_ctrl; |
2001 | struct BOARD_CTRL __iomem *board_ctrl; | 2061 | struct BOARD_CTRL __iomem *board_ctrl; |
2002 | struct CH_CTRL __iomem *ch_ctrl; | 2062 | struct CH_CTRL __iomem *ch_ctrl; |
2003 | int retval; | 2063 | int retval; |
2004 | 2064 | ||
2005 | base_addr = cy_card[card].base_addr; | 2065 | base_addr = cy_card[card].base_addr; |
2006 | 2066 | ||
2007 | firm_id = base_addr + ID_ADDRESS; | 2067 | firm_id = base_addr + ID_ADDRESS; |
2008 | if (!ISZLOADED(cy_card[card])){ | 2068 | if (!ISZLOADED(cy_card[card])) { |
2009 | return -ENODEV; | 2069 | return -ENODEV; |
2010 | } | 2070 | } |
2011 | 2071 | ||
2012 | zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2072 | zfw_ctrl = cy_card[card].base_addr + |
2013 | board_ctrl = &zfw_ctrl->board_ctrl; | 2073 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2014 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2074 | board_ctrl = &zfw_ctrl->board_ctrl; |
2075 | ch_ctrl = zfw_ctrl->ch_ctrl; | ||
2015 | 2076 | ||
2016 | #ifdef CY_DEBUG_OPEN | 2077 | #ifdef CY_DEBUG_OPEN |
2017 | printk("cyc startup Z card %d, channel %d, base_addr %lx\n", | 2078 | printk("cyc startup Z card %d, channel %d, base_addr %lx\n", |
2018 | card, channel, (long)base_addr);/**/ | 2079 | card, channel, (long)base_addr); |
2080 | /**/ | ||
2019 | #endif | 2081 | #endif |
2082 | CY_LOCK(info, flags); | ||
2020 | 2083 | ||
2021 | CY_LOCK(info, flags); | 2084 | cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); |
2022 | |||
2023 | cy_writel(&ch_ctrl[channel].op_mode, C_CH_ENABLE); | ||
2024 | #ifdef Z_WAKE | 2085 | #ifdef Z_WAKE |
2025 | #ifdef CONFIG_CYZ_INTR | 2086 | #ifdef CONFIG_CYZ_INTR |
2026 | cy_writel(&ch_ctrl[channel].intr_enable, | 2087 | cy_writel(&ch_ctrl[channel].intr_enable, |
2027 | C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT| | 2088 | C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | |
2028 | C_IN_IOCTLW| | 2089 | C_IN_RXNNDT | C_IN_IOCTLW | C_IN_MDCD); |
2029 | C_IN_MDCD); | ||
2030 | #else | 2090 | #else |
2031 | cy_writel(&ch_ctrl[channel].intr_enable, | 2091 | cy_writel(&ch_ctrl[channel].intr_enable, |
2032 | C_IN_IOCTLW| | 2092 | C_IN_IOCTLW | C_IN_MDCD); |
2033 | C_IN_MDCD); | 2093 | #endif /* CONFIG_CYZ_INTR */ |
2034 | #endif /* CONFIG_CYZ_INTR */ | ||
2035 | #else | 2094 | #else |
2036 | #ifdef CONFIG_CYZ_INTR | 2095 | #ifdef CONFIG_CYZ_INTR |
2037 | cy_writel(&ch_ctrl[channel].intr_enable, | 2096 | cy_writel(&ch_ctrl[channel].intr_enable, |
2038 | C_IN_TXBEMPTY|C_IN_TXLOWWM|C_IN_RXHIWM|C_IN_RXNNDT| | 2097 | C_IN_TXBEMPTY | C_IN_TXLOWWM | C_IN_RXHIWM | |
2039 | C_IN_MDCD); | 2098 | C_IN_RXNNDT | C_IN_MDCD); |
2040 | #else | 2099 | #else |
2041 | cy_writel(&ch_ctrl[channel].intr_enable, | 2100 | cy_writel(&ch_ctrl[channel].intr_enable, C_IN_MDCD); |
2042 | C_IN_MDCD); | 2101 | #endif /* CONFIG_CYZ_INTR */ |
2043 | #endif /* CONFIG_CYZ_INTR */ | 2102 | #endif /* Z_WAKE */ |
2044 | #endif /* Z_WAKE */ | 2103 | |
2045 | 2104 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | |
2046 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | 2105 | if (retval != 0) { |
2047 | if (retval != 0){ | 2106 | printk("cyc:startup(1) retval on ttyC%d was %x\n", |
2048 | printk("cyc:startup(1) retval on ttyC%d was %x\n", | 2107 | info->line, retval); |
2049 | info->line, retval); | 2108 | } |
2050 | } | ||
2051 | 2109 | ||
2052 | /* Flush RX buffers before raising DTR and RTS */ | 2110 | /* Flush RX buffers before raising DTR and RTS */ |
2053 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, 0L); | 2111 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_RX, |
2054 | if (retval != 0){ | 2112 | 0L); |
2055 | printk("cyc:startup(2) retval on ttyC%d was %x\n", | 2113 | if (retval != 0) { |
2056 | info->line, retval); | 2114 | printk("cyc:startup(2) retval on ttyC%d was %x\n", |
2057 | } | 2115 | info->line, retval); |
2116 | } | ||
2058 | 2117 | ||
2059 | /* set timeout !!! */ | 2118 | /* set timeout !!! */ |
2060 | /* set RTS and DTR !!! */ | 2119 | /* set RTS and DTR !!! */ |
2061 | cy_writel(&ch_ctrl[channel].rs_control, | 2120 | cy_writel(&ch_ctrl[channel].rs_control, |
2062 | cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | C_RS_DTR) ; | 2121 | cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS | |
2063 | retval = cyz_issue_cmd(&cy_card[info->card], | 2122 | C_RS_DTR); |
2064 | channel, C_CM_IOCTLM, 0L); | 2123 | retval = cyz_issue_cmd(&cy_card[info->card], channel, |
2065 | if (retval != 0){ | 2124 | C_CM_IOCTLM, 0L); |
2066 | printk("cyc:startup(3) retval on ttyC%d was %x\n", | 2125 | if (retval != 0) { |
2067 | info->line, retval); | 2126 | printk("cyc:startup(3) retval on ttyC%d was %x\n", |
2068 | } | 2127 | info->line, retval); |
2128 | } | ||
2069 | #ifdef CY_DEBUG_DTR | 2129 | #ifdef CY_DEBUG_DTR |
2070 | printk("cyc:startup raising Z DTR\n"); | 2130 | printk("cyc:startup raising Z DTR\n"); |
2071 | #endif | 2131 | #endif |
2072 | 2132 | ||
2073 | /* enable send, recv, modem !!! */ | 2133 | /* enable send, recv, modem !!! */ |
2074 | 2134 | ||
2075 | info->flags |= ASYNC_INITIALIZED; | 2135 | info->flags |= ASYNC_INITIALIZED; |
2076 | if (info->tty){ | 2136 | if (info->tty) { |
2077 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 2137 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
2078 | } | 2138 | } |
2079 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 2139 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
2080 | info->breakon = info->breakoff = 0; | 2140 | info->breakon = info->breakoff = 0; |
2081 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); | 2141 | memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); |
2082 | info->idle_stats.in_use = | 2142 | info->idle_stats.in_use = |
2083 | info->idle_stats.recv_idle = | 2143 | info->idle_stats.recv_idle = |
2084 | info->idle_stats.xmit_idle = jiffies; | 2144 | info->idle_stats.xmit_idle = jiffies; |
2085 | 2145 | ||
2086 | CY_UNLOCK(info, flags); | 2146 | CY_UNLOCK(info, flags); |
2087 | } | 2147 | } |
2088 | 2148 | ||
2089 | #ifdef CY_DEBUG_OPEN | 2149 | #ifdef CY_DEBUG_OPEN |
2090 | printk(" cyc startup done\n"); | 2150 | printk(" cyc startup done\n"); |
@@ -2094,165 +2154,165 @@ startup(struct cyclades_port * info) | |||
2094 | errout: | 2154 | errout: |
2095 | CY_UNLOCK(info, flags); | 2155 | CY_UNLOCK(info, flags); |
2096 | return retval; | 2156 | return retval; |
2097 | } /* startup */ | 2157 | } /* startup */ |
2098 | |||
2099 | 2158 | ||
2100 | static void | 2159 | static void start_xmit(struct cyclades_port *info) |
2101 | start_xmit( struct cyclades_port *info ) | ||
2102 | { | 2160 | { |
2103 | unsigned long flags; | 2161 | unsigned long flags; |
2104 | void __iomem *base_addr; | 2162 | void __iomem *base_addr; |
2105 | int card,chip,channel,index; | 2163 | int card, chip, channel, index; |
2106 | |||
2107 | card = info->card; | ||
2108 | channel = (info->line) - (cy_card[card].first_line); | ||
2109 | if (!IS_CYC_Z(cy_card[card])) { | ||
2110 | chip = channel>>2; | ||
2111 | channel &= 0x03; | ||
2112 | index = cy_card[card].bus_index; | ||
2113 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
2114 | 2164 | ||
2115 | CY_LOCK(info, flags); | 2165 | card = info->card; |
2116 | cy_writeb(base_addr+(CyCAR<<index), channel); | 2166 | channel = (info->line) - (cy_card[card].first_line); |
2117 | cy_writeb(base_addr+(CySRER<<index), | 2167 | if (!IS_CYC_Z(cy_card[card])) { |
2118 | cy_readb(base_addr+(CySRER<<index)) | CyTxRdy); | 2168 | chip = channel >> 2; |
2119 | CY_UNLOCK(info, flags); | 2169 | channel &= 0x03; |
2120 | } else { | 2170 | index = cy_card[card].bus_index; |
2171 | base_addr = cy_card[card].base_addr + | ||
2172 | (cy_chip_offset[chip] << index); | ||
2173 | |||
2174 | CY_LOCK(info, flags); | ||
2175 | cy_writeb(base_addr + (CyCAR << index), channel); | ||
2176 | cy_writeb(base_addr + (CySRER << index), | ||
2177 | cy_readb(base_addr + (CySRER << index)) | CyTxRdy); | ||
2178 | CY_UNLOCK(info, flags); | ||
2179 | } else { | ||
2121 | #ifdef CONFIG_CYZ_INTR | 2180 | #ifdef CONFIG_CYZ_INTR |
2122 | int retval; | 2181 | int retval; |
2123 | 2182 | ||
2124 | CY_LOCK(info, flags); | 2183 | CY_LOCK(info, flags); |
2125 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, 0L); | 2184 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_INTBACK, |
2126 | if (retval != 0){ | 2185 | 0L); |
2127 | printk("cyc:start_xmit retval on ttyC%d was %x\n", | 2186 | if (retval != 0) { |
2128 | info->line, retval); | 2187 | printk("cyc:start_xmit retval on ttyC%d was %x\n", |
2129 | } | 2188 | info->line, retval); |
2130 | CY_UNLOCK(info, flags); | 2189 | } |
2131 | #else /* CONFIG_CYZ_INTR */ | 2190 | CY_UNLOCK(info, flags); |
2132 | /* Don't have to do anything at this time */ | 2191 | #else /* CONFIG_CYZ_INTR */ |
2133 | #endif /* CONFIG_CYZ_INTR */ | 2192 | /* Don't have to do anything at this time */ |
2134 | } | 2193 | #endif /* CONFIG_CYZ_INTR */ |
2135 | } /* start_xmit */ | 2194 | } |
2195 | } /* start_xmit */ | ||
2136 | 2196 | ||
2137 | /* | 2197 | /* |
2138 | * This routine shuts down a serial port; interrupts are disabled, | 2198 | * This routine shuts down a serial port; interrupts are disabled, |
2139 | * and DTR is dropped if the hangup on close termio flag is on. | 2199 | * and DTR is dropped if the hangup on close termio flag is on. |
2140 | */ | 2200 | */ |
2141 | static void | 2201 | static void shutdown(struct cyclades_port *info) |
2142 | shutdown(struct cyclades_port * info) | ||
2143 | { | 2202 | { |
2144 | unsigned long flags; | 2203 | unsigned long flags; |
2145 | void __iomem *base_addr; | 2204 | void __iomem *base_addr; |
2146 | int card,chip,channel,index; | 2205 | int card, chip, channel, index; |
2147 | 2206 | ||
2148 | if (!(info->flags & ASYNC_INITIALIZED)){ | 2207 | if (!(info->flags & ASYNC_INITIALIZED)) { |
2149 | return; | 2208 | return; |
2150 | } | 2209 | } |
2151 | 2210 | ||
2152 | card = info->card; | 2211 | card = info->card; |
2153 | channel = info->line - cy_card[card].first_line; | 2212 | channel = info->line - cy_card[card].first_line; |
2154 | if (!IS_CYC_Z(cy_card[card])) { | 2213 | if (!IS_CYC_Z(cy_card[card])) { |
2155 | chip = channel>>2; | 2214 | chip = channel >> 2; |
2156 | channel &= 0x03; | 2215 | channel &= 0x03; |
2157 | index = cy_card[card].bus_index; | 2216 | index = cy_card[card].bus_index; |
2158 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | 2217 | base_addr = cy_card[card].base_addr + |
2218 | (cy_chip_offset[chip] << index); | ||
2159 | 2219 | ||
2160 | #ifdef CY_DEBUG_OPEN | 2220 | #ifdef CY_DEBUG_OPEN |
2161 | printk("cyc shutdown Y card %d, chip %d, channel %d, base_addr %lx\n", | 2221 | printk("cyc shutdown Y card %d, chip %d, channel %d, " |
2162 | card, chip, channel, (long)base_addr); | 2222 | "base_addr %lx\n", |
2223 | card, chip, channel, (long)base_addr); | ||
2163 | #endif | 2224 | #endif |
2164 | 2225 | ||
2165 | CY_LOCK(info, flags); | 2226 | CY_LOCK(info, flags); |
2166 | 2227 | ||
2167 | /* Clear delta_msr_wait queue to avoid mem leaks. */ | 2228 | /* Clear delta_msr_wait queue to avoid mem leaks. */ |
2168 | wake_up_interruptible(&info->delta_msr_wait); | 2229 | wake_up_interruptible(&info->delta_msr_wait); |
2169 | 2230 | ||
2170 | if (info->xmit_buf){ | 2231 | if (info->xmit_buf) { |
2171 | unsigned char * temp; | 2232 | unsigned char *temp; |
2172 | temp = info->xmit_buf; | 2233 | temp = info->xmit_buf; |
2173 | info->xmit_buf = NULL; | 2234 | info->xmit_buf = NULL; |
2174 | free_page((unsigned long) temp); | 2235 | free_page((unsigned long)temp); |
2175 | } | 2236 | } |
2176 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 2237 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
2177 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { | 2238 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { |
2178 | cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS); | 2239 | cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); |
2179 | cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR); | 2240 | cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); |
2180 | #ifdef CY_DEBUG_DTR | 2241 | #ifdef CY_DEBUG_DTR |
2181 | printk("cyc shutdown dropping DTR\n"); | 2242 | printk("cyc shutdown dropping DTR\n"); |
2182 | printk(" status: 0x%x, 0x%x\n", | 2243 | printk(" status: 0x%x, 0x%x\n", |
2183 | cy_readb(base_addr+(CyMSVR1<<index)), | 2244 | cy_readb(base_addr + (CyMSVR1 << index)), |
2184 | cy_readb(base_addr+(CyMSVR2<<index))); | 2245 | cy_readb(base_addr + (CyMSVR2 << index))); |
2185 | #endif | 2246 | #endif |
2186 | } | 2247 | } |
2187 | cyy_issue_cmd(base_addr,CyCHAN_CTL|CyDIS_RCVR,index); | 2248 | cyy_issue_cmd(base_addr, CyCHAN_CTL | CyDIS_RCVR, index); |
2188 | /* it may be appropriate to clear _XMIT at | 2249 | /* it may be appropriate to clear _XMIT at |
2189 | some later date (after testing)!!! */ | 2250 | some later date (after testing)!!! */ |
2190 | 2251 | ||
2191 | if (info->tty){ | 2252 | if (info->tty) { |
2192 | set_bit(TTY_IO_ERROR, &info->tty->flags); | 2253 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
2193 | } | 2254 | } |
2194 | info->flags &= ~ASYNC_INITIALIZED; | 2255 | info->flags &= ~ASYNC_INITIALIZED; |
2195 | CY_UNLOCK(info, flags); | 2256 | CY_UNLOCK(info, flags); |
2196 | } else { | 2257 | } else { |
2197 | struct FIRM_ID __iomem *firm_id; | 2258 | struct FIRM_ID __iomem *firm_id; |
2198 | struct ZFW_CTRL __iomem *zfw_ctrl; | 2259 | struct ZFW_CTRL __iomem *zfw_ctrl; |
2199 | struct BOARD_CTRL __iomem *board_ctrl; | 2260 | struct BOARD_CTRL __iomem *board_ctrl; |
2200 | struct CH_CTRL __iomem *ch_ctrl; | 2261 | struct CH_CTRL __iomem *ch_ctrl; |
2201 | int retval; | 2262 | int retval; |
2202 | 2263 | ||
2203 | base_addr = cy_card[card].base_addr; | 2264 | base_addr = cy_card[card].base_addr; |
2204 | #ifdef CY_DEBUG_OPEN | 2265 | #ifdef CY_DEBUG_OPEN |
2205 | printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n", | 2266 | printk("cyc shutdown Z card %d, channel %d, base_addr %lx\n", |
2206 | card, channel, (long)base_addr); | 2267 | card, channel, (long)base_addr); |
2207 | #endif | 2268 | #endif |
2208 | 2269 | ||
2209 | firm_id = base_addr + ID_ADDRESS; | 2270 | firm_id = base_addr + ID_ADDRESS; |
2210 | if (!ISZLOADED(cy_card[card])) { | 2271 | if (!ISZLOADED(cy_card[card])) { |
2211 | return; | 2272 | return; |
2212 | } | 2273 | } |
2213 | 2274 | ||
2214 | zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 2275 | zfw_ctrl = cy_card[card].base_addr + |
2215 | board_ctrl = &zfw_ctrl->board_ctrl; | 2276 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2216 | ch_ctrl = zfw_ctrl->ch_ctrl; | 2277 | board_ctrl = &zfw_ctrl->board_ctrl; |
2278 | ch_ctrl = zfw_ctrl->ch_ctrl; | ||
2217 | 2279 | ||
2218 | CY_LOCK(info, flags); | 2280 | CY_LOCK(info, flags); |
2219 | 2281 | ||
2220 | if (info->xmit_buf){ | 2282 | if (info->xmit_buf) { |
2221 | unsigned char * temp; | 2283 | unsigned char *temp; |
2222 | temp = info->xmit_buf; | 2284 | temp = info->xmit_buf; |
2223 | info->xmit_buf = NULL; | 2285 | info->xmit_buf = NULL; |
2224 | free_page((unsigned long) temp); | 2286 | free_page((unsigned long)temp); |
2225 | } | ||
2226 | |||
2227 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { | ||
2228 | cy_writel(&ch_ctrl[channel].rs_control, | ||
2229 | (uclong)(cy_readl(&ch_ctrl[channel].rs_control) & | ||
2230 | ~(C_RS_RTS | C_RS_DTR))); | ||
2231 | retval = cyz_issue_cmd(&cy_card[info->card], | ||
2232 | channel, C_CM_IOCTLM, 0L); | ||
2233 | if (retval != 0){ | ||
2234 | printk("cyc:shutdown retval on ttyC%d was %x\n", | ||
2235 | info->line, retval); | ||
2236 | } | 2287 | } |
2288 | |||
2289 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { | ||
2290 | cy_writel(&ch_ctrl[channel].rs_control, | ||
2291 | (uclong)(cy_readl(&ch_ctrl[channel].rs_control)& | ||
2292 | ~(C_RS_RTS | C_RS_DTR))); | ||
2293 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | ||
2294 | C_CM_IOCTLM, 0L); | ||
2295 | if (retval != 0) { | ||
2296 | printk("cyc:shutdown retval on ttyC%d was %x\n", | ||
2297 | info->line, retval); | ||
2298 | } | ||
2237 | #ifdef CY_DEBUG_DTR | 2299 | #ifdef CY_DEBUG_DTR |
2238 | printk("cyc:shutdown dropping Z DTR\n"); | 2300 | printk("cyc:shutdown dropping Z DTR\n"); |
2239 | #endif | 2301 | #endif |
2240 | } | 2302 | } |
2241 | |||
2242 | if (info->tty){ | ||
2243 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
2244 | } | ||
2245 | info->flags &= ~ASYNC_INITIALIZED; | ||
2246 | 2303 | ||
2247 | CY_UNLOCK(info, flags); | 2304 | if (info->tty) { |
2248 | } | 2305 | set_bit(TTY_IO_ERROR, &info->tty->flags); |
2306 | } | ||
2307 | info->flags &= ~ASYNC_INITIALIZED; | ||
2308 | |||
2309 | CY_UNLOCK(info, flags); | ||
2310 | } | ||
2249 | 2311 | ||
2250 | #ifdef CY_DEBUG_OPEN | 2312 | #ifdef CY_DEBUG_OPEN |
2251 | printk(" cyc shutdown done\n"); | 2313 | printk(" cyc shutdown done\n"); |
2252 | #endif | 2314 | #endif |
2253 | return; | 2315 | } /* shutdown */ |
2254 | } /* shutdown */ | ||
2255 | |||
2256 | 2316 | ||
2257 | /* | 2317 | /* |
2258 | * ------------------------------------------------------------ | 2318 | * ------------------------------------------------------------ |
@@ -2261,527 +2321,546 @@ shutdown(struct cyclades_port * info) | |||
2261 | */ | 2321 | */ |
2262 | 2322 | ||
2263 | static int | 2323 | static int |
2264 | block_til_ready(struct tty_struct *tty, struct file * filp, | 2324 | block_til_ready(struct tty_struct *tty, struct file *filp, |
2265 | struct cyclades_port *info) | 2325 | struct cyclades_port *info) |
2266 | { | 2326 | { |
2267 | DECLARE_WAITQUEUE(wait, current); | 2327 | DECLARE_WAITQUEUE(wait, current); |
2268 | struct cyclades_card *cinfo; | 2328 | struct cyclades_card *cinfo; |
2269 | unsigned long flags; | 2329 | unsigned long flags; |
2270 | int chip, channel,index; | 2330 | int chip, channel, index; |
2271 | int retval; | 2331 | int retval; |
2272 | void __iomem *base_addr; | 2332 | void __iomem *base_addr; |
2273 | 2333 | ||
2274 | cinfo = &cy_card[info->card]; | 2334 | cinfo = &cy_card[info->card]; |
2275 | channel = info->line - cinfo->first_line; | 2335 | channel = info->line - cinfo->first_line; |
2276 | 2336 | ||
2277 | /* | 2337 | /* |
2278 | * If the device is in the middle of being closed, then block | 2338 | * If the device is in the middle of being closed, then block |
2279 | * until it's done, and then try again. | 2339 | * until it's done, and then try again. |
2280 | */ | 2340 | */ |
2281 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { | 2341 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { |
2282 | if (info->flags & ASYNC_CLOSING) { | 2342 | if (info->flags & ASYNC_CLOSING) { |
2283 | interruptible_sleep_on(&info->close_wait); | 2343 | interruptible_sleep_on(&info->close_wait); |
2344 | } | ||
2345 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | ||
2346 | } | ||
2347 | |||
2348 | /* | ||
2349 | * If non-blocking mode is set, then make the check up front | ||
2350 | * and then exit. | ||
2351 | */ | ||
2352 | if ((filp->f_flags & O_NONBLOCK) || (tty->flags & (1 << TTY_IO_ERROR))) { | ||
2353 | info->flags |= ASYNC_NORMAL_ACTIVE; | ||
2354 | return 0; | ||
2284 | } | 2355 | } |
2285 | return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 2356 | |
2286 | } | 2357 | /* |
2287 | 2358 | * Block waiting for the carrier detect and the line to become | |
2288 | /* | 2359 | * free (i.e., not in use by the callout). While we are in |
2289 | * If non-blocking mode is set, then make the check up front | 2360 | * this loop, info->count is dropped by one, so that |
2290 | * and then exit. | 2361 | * cy_close() knows when to free things. We restore it upon |
2291 | */ | 2362 | * exit, either normal or abnormal. |
2292 | if ((filp->f_flags & O_NONBLOCK) || | 2363 | */ |
2293 | (tty->flags & (1 << TTY_IO_ERROR))) { | 2364 | retval = 0; |
2294 | info->flags |= ASYNC_NORMAL_ACTIVE; | 2365 | add_wait_queue(&info->open_wait, &wait); |
2295 | return 0; | ||
2296 | } | ||
2297 | |||
2298 | /* | ||
2299 | * Block waiting for the carrier detect and the line to become | ||
2300 | * free (i.e., not in use by the callout). While we are in | ||
2301 | * this loop, info->count is dropped by one, so that | ||
2302 | * cy_close() knows when to free things. We restore it upon | ||
2303 | * exit, either normal or abnormal. | ||
2304 | */ | ||
2305 | retval = 0; | ||
2306 | add_wait_queue(&info->open_wait, &wait); | ||
2307 | #ifdef CY_DEBUG_OPEN | 2366 | #ifdef CY_DEBUG_OPEN |
2308 | printk("cyc block_til_ready before block: ttyC%d, count = %d\n", | 2367 | printk("cyc block_til_ready before block: ttyC%d, count = %d\n", |
2309 | info->line, info->count);/**/ | 2368 | info->line, info->count); |
2369 | /**/ | ||
2310 | #endif | 2370 | #endif |
2311 | CY_LOCK(info, flags); | 2371 | CY_LOCK(info, flags); |
2312 | if (!tty_hung_up_p(filp)) | 2372 | if (!tty_hung_up_p(filp)) |
2313 | info->count--; | 2373 | info->count--; |
2314 | CY_UNLOCK(info, flags); | 2374 | CY_UNLOCK(info, flags); |
2315 | #ifdef CY_DEBUG_COUNT | 2375 | #ifdef CY_DEBUG_COUNT |
2316 | printk("cyc block_til_ready: (%d): decrementing count to %d\n", | 2376 | printk("cyc block_til_ready: (%d): decrementing count to %d\n", |
2317 | current->pid, info->count); | 2377 | current->pid, info->count); |
2318 | #endif | 2378 | #endif |
2319 | info->blocked_open++; | 2379 | info->blocked_open++; |
2320 | 2380 | ||
2321 | if (!IS_CYC_Z(*cinfo)) { | 2381 | if (!IS_CYC_Z(*cinfo)) { |
2322 | chip = channel>>2; | 2382 | chip = channel >> 2; |
2323 | channel &= 0x03; | 2383 | channel &= 0x03; |
2324 | index = cinfo->bus_index; | 2384 | index = cinfo->bus_index; |
2325 | base_addr = cinfo->base_addr + (cy_chip_offset[chip]<<index); | 2385 | base_addr = cinfo->base_addr + (cy_chip_offset[chip] << index); |
2326 | 2386 | ||
2327 | while (1) { | 2387 | while (1) { |
2328 | CY_LOCK(info, flags); | 2388 | CY_LOCK(info, flags); |
2329 | if ((tty->termios->c_cflag & CBAUD)){ | 2389 | if ((tty->termios->c_cflag & CBAUD)) { |
2330 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 2390 | cy_writeb(base_addr + (CyCAR << index), |
2331 | cy_writeb(base_addr+(CyMSVR1<<index), CyRTS); | 2391 | (u_char) channel); |
2332 | cy_writeb(base_addr+(CyMSVR2<<index), CyDTR); | 2392 | cy_writeb(base_addr + (CyMSVR1 << index), |
2393 | CyRTS); | ||
2394 | cy_writeb(base_addr + (CyMSVR2 << index), | ||
2395 | CyDTR); | ||
2333 | #ifdef CY_DEBUG_DTR | 2396 | #ifdef CY_DEBUG_DTR |
2334 | printk("cyc:block_til_ready raising DTR\n"); | 2397 | printk("cyc:block_til_ready raising DTR\n"); |
2335 | printk(" status: 0x%x, 0x%x\n", | 2398 | printk(" status: 0x%x, 0x%x\n", |
2336 | cy_readb(base_addr+(CyMSVR1<<index)), | 2399 | cy_readb(base_addr + |
2337 | cy_readb(base_addr+(CyMSVR2<<index))); | 2400 | (CyMSVR1 << index)), |
2401 | cy_readb(base_addr + | ||
2402 | (CyMSVR2 << index))); | ||
2338 | #endif | 2403 | #endif |
2339 | } | 2404 | } |
2340 | CY_UNLOCK(info, flags); | 2405 | CY_UNLOCK(info, flags); |
2341 | 2406 | ||
2342 | set_current_state(TASK_INTERRUPTIBLE); | 2407 | set_current_state(TASK_INTERRUPTIBLE); |
2343 | if (tty_hung_up_p(filp) | 2408 | if (tty_hung_up_p(filp) || |
2344 | || !(info->flags & ASYNC_INITIALIZED) ){ | 2409 | !(info->flags & ASYNC_INITIALIZED)) { |
2345 | retval = ((info->flags & ASYNC_HUP_NOTIFY) ? | 2410 | retval = ((info->flags & ASYNC_HUP_NOTIFY) ? |
2346 | -EAGAIN : -ERESTARTSYS); | 2411 | -EAGAIN : -ERESTARTSYS); |
2347 | break; | 2412 | break; |
2348 | } | 2413 | } |
2349 | 2414 | ||
2350 | CY_LOCK(info, flags); | 2415 | CY_LOCK(info, flags); |
2351 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 2416 | cy_writeb(base_addr + (CyCAR << index), |
2352 | if (!(info->flags & ASYNC_CLOSING) | 2417 | (u_char) channel); |
2353 | && (C_CLOCAL(tty) | 2418 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || |
2354 | || (cy_readb(base_addr+(CyMSVR1<<index)) & CyDCD))) { | 2419 | (cy_readb(base_addr + |
2420 | (CyMSVR1 << index)) & CyDCD))) { | ||
2421 | CY_UNLOCK(info, flags); | ||
2422 | break; | ||
2423 | } | ||
2355 | CY_UNLOCK(info, flags); | 2424 | CY_UNLOCK(info, flags); |
2356 | break; | ||
2357 | } | ||
2358 | CY_UNLOCK(info, flags); | ||
2359 | 2425 | ||
2360 | if (signal_pending(current)) { | 2426 | if (signal_pending(current)) { |
2361 | retval = -ERESTARTSYS; | 2427 | retval = -ERESTARTSYS; |
2362 | break; | 2428 | break; |
2363 | } | 2429 | } |
2364 | #ifdef CY_DEBUG_OPEN | 2430 | #ifdef CY_DEBUG_OPEN |
2365 | printk("cyc block_til_ready blocking: ttyC%d, count = %d\n", | 2431 | printk("cyc block_til_ready blocking: ttyC%d, " |
2366 | info->line, info->count);/**/ | 2432 | "count = %d\n", |
2433 | info->line, info->count); | ||
2434 | /**/ | ||
2367 | #endif | 2435 | #endif |
2368 | schedule(); | 2436 | schedule(); |
2369 | } | 2437 | } |
2370 | } else { | 2438 | } else { |
2371 | struct FIRM_ID __iomem *firm_id; | 2439 | struct FIRM_ID __iomem *firm_id; |
2372 | struct ZFW_CTRL __iomem *zfw_ctrl; | 2440 | struct ZFW_CTRL __iomem *zfw_ctrl; |
2373 | struct BOARD_CTRL __iomem *board_ctrl; | 2441 | struct BOARD_CTRL __iomem *board_ctrl; |
2374 | struct CH_CTRL __iomem *ch_ctrl; | 2442 | struct CH_CTRL __iomem *ch_ctrl; |
2375 | int retval; | 2443 | int retval; |
2376 | 2444 | ||
2377 | base_addr = cinfo->base_addr; | 2445 | base_addr = cinfo->base_addr; |
2378 | firm_id = base_addr + ID_ADDRESS; | 2446 | firm_id = base_addr + ID_ADDRESS; |
2379 | if (!ISZLOADED(*cinfo)){ | 2447 | if (!ISZLOADED(*cinfo)) { |
2380 | current->state = TASK_RUNNING; | 2448 | current->state = TASK_RUNNING; |
2381 | remove_wait_queue(&info->open_wait, &wait); | 2449 | remove_wait_queue(&info->open_wait, &wait); |
2382 | return -EINVAL; | 2450 | return -EINVAL; |
2383 | } | ||
2384 | |||
2385 | zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
2386 | board_ctrl = &zfw_ctrl->board_ctrl; | ||
2387 | ch_ctrl = zfw_ctrl->ch_ctrl; | ||
2388 | |||
2389 | while (1) { | ||
2390 | if ((tty->termios->c_cflag & CBAUD)){ | ||
2391 | cy_writel(&ch_ctrl[channel].rs_control, | ||
2392 | cy_readl(&ch_ctrl[channel].rs_control) | | ||
2393 | (C_RS_RTS | C_RS_DTR)); | ||
2394 | retval = cyz_issue_cmd(&cy_card[info->card], | ||
2395 | channel, C_CM_IOCTLM, 0L); | ||
2396 | if (retval != 0){ | ||
2397 | printk("cyc:block_til_ready retval on ttyC%d was %x\n", | ||
2398 | info->line, retval); | ||
2399 | } | 2451 | } |
2452 | |||
2453 | zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & | ||
2454 | 0xfffff); | ||
2455 | board_ctrl = &zfw_ctrl->board_ctrl; | ||
2456 | ch_ctrl = zfw_ctrl->ch_ctrl; | ||
2457 | |||
2458 | while (1) { | ||
2459 | if ((tty->termios->c_cflag & CBAUD)) { | ||
2460 | cy_writel(&ch_ctrl[channel].rs_control, | ||
2461 | cy_readl(&ch_ctrl[channel]. | ||
2462 | rs_control) | (C_RS_RTS | | ||
2463 | C_RS_DTR)); | ||
2464 | retval = cyz_issue_cmd(&cy_card[info->card], | ||
2465 | channel, C_CM_IOCTLM, 0L); | ||
2466 | if (retval != 0) { | ||
2467 | printk("cyc:block_til_ready retval on " | ||
2468 | "ttyC%d was %x\n", | ||
2469 | info->line, retval); | ||
2470 | } | ||
2400 | #ifdef CY_DEBUG_DTR | 2471 | #ifdef CY_DEBUG_DTR |
2401 | printk("cyc:block_til_ready raising Z DTR\n"); | 2472 | printk("cyc:block_til_ready raising Z DTR\n"); |
2402 | #endif | 2473 | #endif |
2403 | } | 2474 | } |
2404 | 2475 | ||
2405 | set_current_state(TASK_INTERRUPTIBLE); | 2476 | set_current_state(TASK_INTERRUPTIBLE); |
2406 | if (tty_hung_up_p(filp) | 2477 | if (tty_hung_up_p(filp) || |
2407 | || !(info->flags & ASYNC_INITIALIZED) ){ | 2478 | !(info->flags & ASYNC_INITIALIZED)) { |
2408 | retval = ((info->flags & ASYNC_HUP_NOTIFY) ? | 2479 | retval = ((info->flags & ASYNC_HUP_NOTIFY) ? |
2409 | -EAGAIN : -ERESTARTSYS); | 2480 | -EAGAIN : -ERESTARTSYS); |
2410 | break; | 2481 | break; |
2411 | } | 2482 | } |
2412 | if (!(info->flags & ASYNC_CLOSING) | 2483 | if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || |
2413 | && (C_CLOCAL(tty) | 2484 | (cy_readl(&ch_ctrl[channel].rs_status) & |
2414 | || (cy_readl(&ch_ctrl[channel].rs_status) & C_RS_DCD))) { | 2485 | C_RS_DCD))) { |
2415 | break; | 2486 | break; |
2416 | } | 2487 | } |
2417 | if (signal_pending(current)) { | 2488 | if (signal_pending(current)) { |
2418 | retval = -ERESTARTSYS; | 2489 | retval = -ERESTARTSYS; |
2419 | break; | 2490 | break; |
2420 | } | 2491 | } |
2421 | #ifdef CY_DEBUG_OPEN | 2492 | #ifdef CY_DEBUG_OPEN |
2422 | printk("cyc block_til_ready blocking: ttyC%d, count = %d\n", | 2493 | printk("cyc block_til_ready blocking: ttyC%d, " |
2423 | info->line, info->count);/**/ | 2494 | "count = %d\n", |
2495 | info->line, info->count); | ||
2496 | /**/ | ||
2424 | #endif | 2497 | #endif |
2425 | schedule(); | 2498 | schedule(); |
2499 | } | ||
2426 | } | 2500 | } |
2427 | } | 2501 | current->state = TASK_RUNNING; |
2428 | current->state = TASK_RUNNING; | 2502 | remove_wait_queue(&info->open_wait, &wait); |
2429 | remove_wait_queue(&info->open_wait, &wait); | 2503 | if (!tty_hung_up_p(filp)) { |
2430 | if (!tty_hung_up_p(filp)){ | 2504 | info->count++; |
2431 | info->count++; | ||
2432 | #ifdef CY_DEBUG_COUNT | 2505 | #ifdef CY_DEBUG_COUNT |
2433 | printk("cyc:block_til_ready (%d): incrementing count to %d\n", | 2506 | printk("cyc:block_til_ready (%d): incrementing count to %d\n", |
2434 | current->pid, info->count); | 2507 | current->pid, info->count); |
2435 | #endif | 2508 | #endif |
2436 | } | 2509 | } |
2437 | info->blocked_open--; | 2510 | info->blocked_open--; |
2438 | #ifdef CY_DEBUG_OPEN | 2511 | #ifdef CY_DEBUG_OPEN |
2439 | printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n", | 2512 | printk("cyc:block_til_ready after blocking: ttyC%d, count = %d\n", |
2440 | info->line, info->count);/**/ | 2513 | info->line, info->count); |
2514 | /**/ | ||
2441 | #endif | 2515 | #endif |
2442 | if (retval) | 2516 | if (retval) |
2443 | return retval; | 2517 | return retval; |
2444 | info->flags |= ASYNC_NORMAL_ACTIVE; | 2518 | info->flags |= ASYNC_NORMAL_ACTIVE; |
2445 | return 0; | 2519 | return 0; |
2446 | } /* block_til_ready */ | 2520 | } /* block_til_ready */ |
2447 | |||
2448 | 2521 | ||
2449 | /* | 2522 | /* |
2450 | * This routine is called whenever a serial port is opened. It | 2523 | * This routine is called whenever a serial port is opened. It |
2451 | * performs the serial-specific initialization for the tty structure. | 2524 | * performs the serial-specific initialization for the tty structure. |
2452 | */ | 2525 | */ |
2453 | static int | 2526 | static int cy_open(struct tty_struct *tty, struct file *filp) |
2454 | cy_open(struct tty_struct *tty, struct file * filp) | ||
2455 | { | 2527 | { |
2456 | struct cyclades_port *info; | 2528 | struct cyclades_port *info; |
2457 | int retval, line; | 2529 | int retval, line; |
2458 | |||
2459 | line = tty->index; | ||
2460 | if ((line < 0) || (NR_PORTS <= line)){ | ||
2461 | return -ENODEV; | ||
2462 | } | ||
2463 | info = &cy_port[line]; | ||
2464 | if (info->line < 0){ | ||
2465 | return -ENODEV; | ||
2466 | } | ||
2467 | |||
2468 | /* If the card's firmware hasn't been loaded, | ||
2469 | treat it as absent from the system. This | ||
2470 | will make the user pay attention. | ||
2471 | */ | ||
2472 | if (IS_CYC_Z(cy_card[info->card])) { | ||
2473 | struct cyclades_card *cinfo = &cy_card[info->card]; | ||
2474 | struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; | ||
2475 | |||
2476 | if (!ISZLOADED(*cinfo)) { | ||
2477 | if (((ZE_V1 ==cy_readl(&((struct RUNTIME_9060 __iomem *) | ||
2478 | (cinfo->ctl_addr))->mail_box_0)) && | ||
2479 | Z_FPGA_CHECK (*cinfo)) && | ||
2480 | (ZFIRM_HLT == cy_readl (&firm_id->signature))) | ||
2481 | { | ||
2482 | printk ("cyc:Cyclades-Z Error: you need an external power supply for this number of ports.\n\rFirmware halted.\r\n"); | ||
2483 | } else { | ||
2484 | printk("cyc:Cyclades-Z firmware not yet loaded\n"); | ||
2485 | } | ||
2486 | return -ENODEV; | ||
2487 | } | ||
2488 | #ifdef CONFIG_CYZ_INTR | ||
2489 | else { | ||
2490 | /* In case this Z board is operating in interrupt mode, its | ||
2491 | interrupts should be enabled as soon as the first open happens | ||
2492 | to one of its ports. */ | ||
2493 | if (!cinfo->intr_enabled) { | ||
2494 | struct ZFW_CTRL __iomem *zfw_ctrl; | ||
2495 | struct BOARD_CTRL __iomem *board_ctrl; | ||
2496 | |||
2497 | zfw_ctrl = cinfo->base_addr + (cy_readl (&firm_id->zfwctrl_addr) & 0xfffff); | ||
2498 | 2530 | ||
2499 | board_ctrl = &zfw_ctrl->board_ctrl; | 2531 | line = tty->index; |
2532 | if ((line < 0) || (NR_PORTS <= line)) { | ||
2533 | return -ENODEV; | ||
2534 | } | ||
2535 | info = &cy_port[line]; | ||
2536 | if (info->line < 0) { | ||
2537 | return -ENODEV; | ||
2538 | } | ||
2500 | 2539 | ||
2501 | /* Enable interrupts on the PLX chip */ | 2540 | /* If the card's firmware hasn't been loaded, |
2502 | cy_writew(cinfo->ctl_addr+0x68, | 2541 | treat it as absent from the system. This |
2503 | cy_readw(cinfo->ctl_addr+0x68)|0x0900); | 2542 | will make the user pay attention. |
2504 | /* Enable interrupts on the FW */ | 2543 | */ |
2505 | retval = cyz_issue_cmd(cinfo, | 2544 | if (IS_CYC_Z(cy_card[info->card])) { |
2506 | 0, C_CM_IRQ_ENBL, 0L); | 2545 | struct cyclades_card *cinfo = &cy_card[info->card]; |
2507 | if (retval != 0){ | 2546 | struct FIRM_ID __iomem *firm_id = cinfo->base_addr + ID_ADDRESS; |
2508 | printk("cyc:IRQ enable retval was %x\n", retval); | 2547 | |
2548 | if (!ISZLOADED(*cinfo)) { | ||
2549 | if (((ZE_V1 == cy_readl( | ||
2550 | &((struct RUNTIME_9060 __iomem *) | ||
2551 | (cinfo->ctl_addr))->mail_box_0)) && | ||
2552 | Z_FPGA_CHECK(*cinfo)) && | ||
2553 | (ZFIRM_HLT == cy_readl( | ||
2554 | &firm_id->signature))) { | ||
2555 | printk("cyc:Cyclades-Z Error: you need an " | ||
2556 | "external power supply for this number " | ||
2557 | "of ports.\n\rFirmware halted.\r\n"); | ||
2558 | } else { | ||
2559 | printk("cyc:Cyclades-Z firmware not yet " | ||
2560 | "loaded\n"); | ||
2561 | } | ||
2562 | return -ENODEV; | ||
2509 | } | 2563 | } |
2510 | cinfo->nports = (int) cy_readl (&board_ctrl->n_channel); | 2564 | #ifdef CONFIG_CYZ_INTR |
2511 | cinfo->intr_enabled = 1; | 2565 | else { |
2512 | } | 2566 | /* In case this Z board is operating in interrupt mode, its |
2567 | interrupts should be enabled as soon as the first open | ||
2568 | happens to one of its ports. */ | ||
2569 | if (!cinfo->intr_enabled) { | ||
2570 | struct ZFW_CTRL __iomem *zfw_ctrl; | ||
2571 | struct BOARD_CTRL __iomem *board_ctrl; | ||
2572 | |||
2573 | zfw_ctrl = cinfo->base_addr + | ||
2574 | (cy_readl(&firm_id->zfwctrl_addr) & | ||
2575 | 0xfffff); | ||
2576 | |||
2577 | board_ctrl = &zfw_ctrl->board_ctrl; | ||
2578 | |||
2579 | /* Enable interrupts on the PLX chip */ | ||
2580 | cy_writew(cinfo->ctl_addr + 0x68, | ||
2581 | cy_readw(cinfo->ctl_addr + | ||
2582 | 0x68) | 0x0900); | ||
2583 | /* Enable interrupts on the FW */ | ||
2584 | retval = cyz_issue_cmd(cinfo, 0, | ||
2585 | C_CM_IRQ_ENBL, 0L); | ||
2586 | if (retval != 0) { | ||
2587 | printk("cyc:IRQ enable retval was %x\n", | ||
2588 | retval); | ||
2589 | } | ||
2590 | cinfo->nports = | ||
2591 | (int)cy_readl(&board_ctrl->n_channel); | ||
2592 | cinfo->intr_enabled = 1; | ||
2593 | } | ||
2594 | } | ||
2595 | #endif /* CONFIG_CYZ_INTR */ | ||
2596 | /* Make sure this Z port really exists in hardware */ | ||
2597 | if (info->line > (cinfo->first_line + cinfo->nports - 1)) | ||
2598 | return -ENODEV; | ||
2513 | } | 2599 | } |
2514 | #endif /* CONFIG_CYZ_INTR */ | ||
2515 | /* Make sure this Z port really exists in hardware */ | ||
2516 | if (info->line > (cinfo->first_line + cinfo->nports - 1)) | ||
2517 | return -ENODEV; | ||
2518 | } | ||
2519 | #ifdef CY_DEBUG_OTHER | 2600 | #ifdef CY_DEBUG_OTHER |
2520 | printk("cyc:cy_open ttyC%d\n", info->line); /* */ | 2601 | printk("cyc:cy_open ttyC%d\n", info->line); /* */ |
2521 | #endif | 2602 | #endif |
2522 | tty->driver_data = info; | 2603 | tty->driver_data = info; |
2523 | info->tty = tty; | 2604 | info->tty = tty; |
2524 | if (serial_paranoia_check(info, tty->name, "cy_open")){ | 2605 | if (serial_paranoia_check(info, tty->name, "cy_open")) { |
2525 | return -ENODEV; | 2606 | return -ENODEV; |
2526 | } | 2607 | } |
2527 | #ifdef CY_DEBUG_OPEN | 2608 | #ifdef CY_DEBUG_OPEN |
2528 | printk("cyc:cy_open ttyC%d, count = %d\n", | 2609 | printk("cyc:cy_open ttyC%d, count = %d\n", info->line, info->count); |
2529 | info->line, info->count);/**/ | 2610 | /**/ |
2530 | #endif | 2611 | #endif |
2531 | info->count++; | 2612 | info->count++; |
2532 | #ifdef CY_DEBUG_COUNT | 2613 | #ifdef CY_DEBUG_COUNT |
2533 | printk("cyc:cy_open (%d): incrementing count to %d\n", | 2614 | printk("cyc:cy_open (%d): incrementing count to %d\n", |
2534 | current->pid, info->count); | 2615 | current->pid, info->count); |
2535 | #endif | 2616 | #endif |
2536 | 2617 | ||
2537 | /* | 2618 | /* |
2538 | * If the port is the middle of closing, bail out now | 2619 | * If the port is the middle of closing, bail out now |
2539 | */ | 2620 | */ |
2540 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { | 2621 | if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { |
2541 | if (info->flags & ASYNC_CLOSING) | 2622 | if (info->flags & ASYNC_CLOSING) |
2542 | interruptible_sleep_on(&info->close_wait); | 2623 | interruptible_sleep_on(&info->close_wait); |
2543 | return ((info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN : -ERESTARTSYS); | 2624 | return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
2544 | } | 2625 | } |
2545 | |||
2546 | /* | ||
2547 | * Start up serial port | ||
2548 | */ | ||
2549 | retval = startup(info); | ||
2550 | if (retval){ | ||
2551 | return retval; | ||
2552 | } | ||
2553 | |||
2554 | retval = block_til_ready(tty, filp, info); | ||
2555 | if (retval) { | ||
2556 | #ifdef CY_DEBUG_OPEN | ||
2557 | printk("cyc:cy_open returning after block_til_ready with %d\n", | ||
2558 | retval); | ||
2559 | #endif | ||
2560 | return retval; | ||
2561 | } | ||
2562 | 2626 | ||
2563 | info->throttle = 0; | 2627 | /* |
2628 | * Start up serial port | ||
2629 | */ | ||
2630 | retval = startup(info); | ||
2631 | if (retval) { | ||
2632 | return retval; | ||
2633 | } | ||
2564 | 2634 | ||
2635 | retval = block_til_ready(tty, filp, info); | ||
2636 | if (retval) { | ||
2565 | #ifdef CY_DEBUG_OPEN | 2637 | #ifdef CY_DEBUG_OPEN |
2566 | printk(" cyc:cy_open done\n");/**/ | 2638 | printk("cyc:cy_open returning after block_til_ready with %d\n", |
2639 | retval); | ||
2567 | #endif | 2640 | #endif |
2641 | return retval; | ||
2642 | } | ||
2568 | 2643 | ||
2569 | return 0; | 2644 | info->throttle = 0; |
2570 | } /* cy_open */ | ||
2571 | 2645 | ||
2646 | #ifdef CY_DEBUG_OPEN | ||
2647 | printk(" cyc:cy_open done\n"); | ||
2648 | /**/ | ||
2649 | #endif | ||
2650 | return 0; | ||
2651 | } /* cy_open */ | ||
2572 | 2652 | ||
2573 | /* | 2653 | /* |
2574 | * cy_wait_until_sent() --- wait until the transmitter is empty | 2654 | * cy_wait_until_sent() --- wait until the transmitter is empty |
2575 | */ | 2655 | */ |
2576 | static void | 2656 | static void cy_wait_until_sent(struct tty_struct *tty, int timeout) |
2577 | cy_wait_until_sent(struct tty_struct *tty, int timeout) | ||
2578 | { | 2657 | { |
2579 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 2658 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2580 | void __iomem *base_addr; | 2659 | void __iomem *base_addr; |
2581 | int card,chip,channel,index; | 2660 | int card, chip, channel, index; |
2582 | unsigned long orig_jiffies; | 2661 | unsigned long orig_jiffies; |
2583 | int char_time; | 2662 | int char_time; |
2584 | 2663 | ||
2585 | if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent")) | 2664 | if (serial_paranoia_check(info, tty->name, "cy_wait_until_sent")) |
2586 | return; | 2665 | return; |
2587 | 2666 | ||
2588 | if (info->xmit_fifo_size == 0) | 2667 | if (info->xmit_fifo_size == 0) |
2589 | return; /* Just in case.... */ | 2668 | return; /* Just in case.... */ |
2590 | 2669 | ||
2591 | 2670 | orig_jiffies = jiffies; | |
2592 | orig_jiffies = jiffies; | 2671 | /* |
2593 | /* | 2672 | * Set the check interval to be 1/5 of the estimated time to |
2594 | * Set the check interval to be 1/5 of the estimated time to | 2673 | * send a single character, and make it at least 1. The check |
2595 | * send a single character, and make it at least 1. The check | 2674 | * interval should also be less than the timeout. |
2596 | * interval should also be less than the timeout. | 2675 | * |
2597 | * | 2676 | * Note: we have to use pretty tight timings here to satisfy |
2598 | * Note: we have to use pretty tight timings here to satisfy | 2677 | * the NIST-PCTS. |
2599 | * the NIST-PCTS. | 2678 | */ |
2600 | */ | 2679 | char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size; |
2601 | char_time = (info->timeout - HZ/50) / info->xmit_fifo_size; | 2680 | char_time = char_time / 5; |
2602 | char_time = char_time / 5; | 2681 | if (char_time <= 0) |
2603 | if (char_time <= 0) | 2682 | char_time = 1; |
2604 | char_time = 1; | 2683 | if (timeout < 0) |
2605 | if (timeout < 0) | 2684 | timeout = 0; |
2606 | timeout = 0; | 2685 | if (timeout) |
2607 | if (timeout) | 2686 | char_time = min(char_time, timeout); |
2608 | char_time = min(char_time, timeout); | 2687 | /* |
2609 | /* | 2688 | * If the transmitter hasn't cleared in twice the approximate |
2610 | * If the transmitter hasn't cleared in twice the approximate | 2689 | * amount of time to send the entire FIFO, it probably won't |
2611 | * amount of time to send the entire FIFO, it probably won't | 2690 | * ever clear. This assumes the UART isn't doing flow |
2612 | * ever clear. This assumes the UART isn't doing flow | 2691 | * control, which is currently the case. Hence, if it ever |
2613 | * control, which is currently the case. Hence, if it ever | 2692 | * takes longer than info->timeout, this is probably due to a |
2614 | * takes longer than info->timeout, this is probably due to a | 2693 | * UART bug of some kind. So, we clamp the timeout parameter at |
2615 | * UART bug of some kind. So, we clamp the timeout parameter at | 2694 | * 2*info->timeout. |
2616 | * 2*info->timeout. | 2695 | */ |
2617 | */ | 2696 | if (!timeout || timeout > 2 * info->timeout) |
2618 | if (!timeout || timeout > 2*info->timeout) | 2697 | timeout = 2 * info->timeout; |
2619 | timeout = 2*info->timeout; | ||
2620 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2698 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2621 | printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time); | 2699 | printk("In cy_wait_until_sent(%d) check=%lu...", timeout, char_time); |
2622 | printk("jiff=%lu...", jiffies); | 2700 | printk("jiff=%lu...", jiffies); |
2623 | #endif | 2701 | #endif |
2624 | card = info->card; | 2702 | card = info->card; |
2625 | channel = (info->line) - (cy_card[card].first_line); | 2703 | channel = (info->line) - (cy_card[card].first_line); |
2626 | if (!IS_CYC_Z(cy_card[card])) { | 2704 | if (!IS_CYC_Z(cy_card[card])) { |
2627 | chip = channel>>2; | 2705 | chip = channel >> 2; |
2628 | channel &= 0x03; | 2706 | channel &= 0x03; |
2629 | index = cy_card[card].bus_index; | 2707 | index = cy_card[card].bus_index; |
2630 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | 2708 | base_addr = |
2631 | while (cy_readb(base_addr+(CySRER<<index)) & CyTxRdy) { | 2709 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); |
2710 | while (cy_readb(base_addr + (CySRER << index)) & CyTxRdy) { | ||
2632 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2711 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2633 | printk("Not clean (jiff=%lu)...", jiffies); | 2712 | printk("Not clean (jiff=%lu)...", jiffies); |
2634 | #endif | 2713 | #endif |
2635 | if (msleep_interruptible(jiffies_to_msecs(char_time))) | 2714 | if (msleep_interruptible(jiffies_to_msecs(char_time))) |
2636 | break; | 2715 | break; |
2637 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | 2716 | if (timeout && time_after(jiffies, orig_jiffies + |
2638 | break; | 2717 | timeout)) |
2718 | break; | ||
2719 | } | ||
2720 | } else { | ||
2721 | /* Nothing to do! */ | ||
2639 | } | 2722 | } |
2640 | } else { | 2723 | /* Run one more char cycle */ |
2641 | // Nothing to do! | 2724 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); |
2642 | } | ||
2643 | /* Run one more char cycle */ | ||
2644 | msleep_interruptible(jiffies_to_msecs(char_time * 5)); | ||
2645 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT | 2725 | #ifdef CY_DEBUG_WAIT_UNTIL_SENT |
2646 | printk("Clean (jiff=%lu)...done\n", jiffies); | 2726 | printk("Clean (jiff=%lu)...done\n", jiffies); |
2647 | #endif | 2727 | #endif |
2648 | } | 2728 | } |
2649 | 2729 | ||
2650 | /* | 2730 | /* |
2651 | * This routine is called when a particular tty device is closed. | 2731 | * This routine is called when a particular tty device is closed. |
2652 | */ | 2732 | */ |
2653 | static void | 2733 | static void cy_close(struct tty_struct *tty, struct file *filp) |
2654 | cy_close(struct tty_struct *tty, struct file *filp) | ||
2655 | { | 2734 | { |
2656 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2735 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2657 | unsigned long flags; | 2736 | unsigned long flags; |
2658 | 2737 | ||
2659 | #ifdef CY_DEBUG_OTHER | 2738 | #ifdef CY_DEBUG_OTHER |
2660 | printk("cyc:cy_close ttyC%d\n", info->line); | 2739 | printk("cyc:cy_close ttyC%d\n", info->line); |
2661 | #endif | 2740 | #endif |
2662 | 2741 | ||
2663 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")){ | 2742 | if (!info || serial_paranoia_check(info, tty->name, "cy_close")) { |
2664 | return; | 2743 | return; |
2665 | } | 2744 | } |
2666 | 2745 | ||
2667 | CY_LOCK(info, flags); | 2746 | CY_LOCK(info, flags); |
2668 | /* If the TTY is being hung up, nothing to do */ | 2747 | /* If the TTY is being hung up, nothing to do */ |
2669 | if (tty_hung_up_p(filp)) { | 2748 | if (tty_hung_up_p(filp)) { |
2670 | CY_UNLOCK(info, flags); | 2749 | CY_UNLOCK(info, flags); |
2671 | return; | 2750 | return; |
2672 | } | 2751 | } |
2673 | |||
2674 | #ifdef CY_DEBUG_OPEN | 2752 | #ifdef CY_DEBUG_OPEN |
2675 | printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count); | 2753 | printk("cyc:cy_close ttyC%d, count = %d\n", info->line, info->count); |
2676 | #endif | 2754 | #endif |
2677 | if ((tty->count == 1) && (info->count != 1)) { | 2755 | if ((tty->count == 1) && (info->count != 1)) { |
2678 | /* | 2756 | /* |
2679 | * Uh, oh. tty->count is 1, which means that the tty | 2757 | * Uh, oh. tty->count is 1, which means that the tty |
2680 | * structure will be freed. Info->count should always | 2758 | * structure will be freed. Info->count should always |
2681 | * be one in these conditions. If it's greater than | 2759 | * be one in these conditions. If it's greater than |
2682 | * one, we've got real problems, since it means the | 2760 | * one, we've got real problems, since it means the |
2683 | * serial port won't be shutdown. | 2761 | * serial port won't be shutdown. |
2684 | */ | 2762 | */ |
2685 | printk("cyc:cy_close: bad serial port count; tty->count is 1, " | 2763 | printk("cyc:cy_close: bad serial port count; tty->count is 1, " |
2686 | "info->count is %d\n", info->count); | 2764 | "info->count is %d\n", info->count); |
2687 | info->count = 1; | 2765 | info->count = 1; |
2688 | } | 2766 | } |
2689 | #ifdef CY_DEBUG_COUNT | 2767 | #ifdef CY_DEBUG_COUNT |
2690 | printk("cyc:cy_close at (%d): decrementing count to %d\n", | 2768 | printk("cyc:cy_close at (%d): decrementing count to %d\n", |
2691 | current->pid, info->count - 1); | 2769 | current->pid, info->count - 1); |
2692 | #endif | 2770 | #endif |
2693 | if (--info->count < 0) { | 2771 | if (--info->count < 0) { |
2694 | #ifdef CY_DEBUG_COUNT | 2772 | #ifdef CY_DEBUG_COUNT |
2695 | printk("cyc:cyc_close setting count to 0\n"); | 2773 | printk("cyc:cyc_close setting count to 0\n"); |
2696 | #endif | 2774 | #endif |
2697 | info->count = 0; | 2775 | info->count = 0; |
2698 | } | ||
2699 | if (info->count) { | ||
2700 | CY_UNLOCK(info, flags); | ||
2701 | return; | ||
2702 | } | ||
2703 | info->flags |= ASYNC_CLOSING; | ||
2704 | |||
2705 | /* | ||
2706 | * Now we wait for the transmit buffer to clear; and we notify | ||
2707 | * the line discipline to only process XON/XOFF characters. | ||
2708 | */ | ||
2709 | tty->closing = 1; | ||
2710 | CY_UNLOCK(info, flags); | ||
2711 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { | ||
2712 | tty_wait_until_sent(tty, info->closing_wait); | ||
2713 | } | ||
2714 | CY_LOCK(info, flags); | ||
2715 | |||
2716 | if (!IS_CYC_Z(cy_card[info->card])) { | ||
2717 | int channel = info->line - cy_card[info->card].first_line; | ||
2718 | int index = cy_card[info->card].bus_index; | ||
2719 | void __iomem *base_addr = cy_card[info->card].base_addr + (cy_chip_offset[channel>>2] << index); | ||
2720 | /* Stop accepting input */ | ||
2721 | channel &= 0x03; | ||
2722 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | ||
2723 | cy_writeb(base_addr+(CySRER<<index), | ||
2724 | cy_readb(base_addr+(CySRER<<index)) & ~CyRxData); | ||
2725 | if (info->flags & ASYNC_INITIALIZED) { | ||
2726 | /* Waiting for on-board buffers to be empty before closing | ||
2727 | the port */ | ||
2728 | CY_UNLOCK(info, flags); | ||
2729 | cy_wait_until_sent(tty, info->timeout); | ||
2730 | CY_LOCK(info, flags); | ||
2731 | } | 2776 | } |
2732 | } else { | 2777 | if (info->count) { |
2733 | #ifdef Z_WAKE | 2778 | CY_UNLOCK(info, flags); |
2734 | /* Waiting for on-board buffers to be empty before closing the port */ | 2779 | return; |
2735 | void __iomem *base_addr = cy_card[info->card].base_addr; | 2780 | } |
2736 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; | 2781 | info->flags |= ASYNC_CLOSING; |
2737 | struct ZFW_CTRL __iomem *zfw_ctrl = base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
2738 | struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; | ||
2739 | int channel = info->line - cy_card[info->card].first_line; | ||
2740 | int retval; | ||
2741 | 2782 | ||
2742 | if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { | 2783 | /* |
2743 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | 2784 | * Now we wait for the transmit buffer to clear; and we notify |
2744 | C_CM_IOCTLW, 0L); | 2785 | * the line discipline to only process XON/XOFF characters. |
2745 | if (retval != 0){ | 2786 | */ |
2746 | printk("cyc:cy_close retval on ttyC%d was %x\n", | 2787 | tty->closing = 1; |
2747 | info->line, retval); | 2788 | CY_UNLOCK(info, flags); |
2748 | } | 2789 | if (info->closing_wait != CY_CLOSING_WAIT_NONE) { |
2749 | CY_UNLOCK(info, flags); | 2790 | tty_wait_until_sent(tty, info->closing_wait); |
2750 | interruptible_sleep_on(&info->shutdown_wait); | ||
2751 | CY_LOCK(info, flags); | ||
2752 | } | 2791 | } |
2792 | CY_LOCK(info, flags); | ||
2793 | |||
2794 | if (!IS_CYC_Z(cy_card[info->card])) { | ||
2795 | int channel = info->line - cy_card[info->card].first_line; | ||
2796 | int index = cy_card[info->card].bus_index; | ||
2797 | void __iomem *base_addr = cy_card[info->card].base_addr + | ||
2798 | (cy_chip_offset[channel >> 2] << index); | ||
2799 | /* Stop accepting input */ | ||
2800 | channel &= 0x03; | ||
2801 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); | ||
2802 | cy_writeb(base_addr + (CySRER << index), | ||
2803 | cy_readb(base_addr + (CySRER << index)) & ~CyRxData); | ||
2804 | if (info->flags & ASYNC_INITIALIZED) { | ||
2805 | /* Waiting for on-board buffers to be empty before closing | ||
2806 | the port */ | ||
2807 | CY_UNLOCK(info, flags); | ||
2808 | cy_wait_until_sent(tty, info->timeout); | ||
2809 | CY_LOCK(info, flags); | ||
2810 | } | ||
2811 | } else { | ||
2812 | #ifdef Z_WAKE | ||
2813 | /* Waiting for on-board buffers to be empty before closing the port */ | ||
2814 | void __iomem *base_addr = cy_card[info->card].base_addr; | ||
2815 | struct FIRM_ID __iomem *firm_id = base_addr + ID_ADDRESS; | ||
2816 | struct ZFW_CTRL __iomem *zfw_ctrl = | ||
2817 | base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
2818 | struct CH_CTRL __iomem *ch_ctrl = zfw_ctrl->ch_ctrl; | ||
2819 | int channel = info->line - cy_card[info->card].first_line; | ||
2820 | int retval; | ||
2821 | |||
2822 | if (cy_readl(&ch_ctrl[channel].flow_status) != C_FS_TXIDLE) { | ||
2823 | retval = cyz_issue_cmd(&cy_card[info->card], channel, | ||
2824 | C_CM_IOCTLW, 0L); | ||
2825 | if (retval != 0) { | ||
2826 | printk("cyc:cy_close retval on ttyC%d was %x\n", | ||
2827 | info->line, retval); | ||
2828 | } | ||
2829 | CY_UNLOCK(info, flags); | ||
2830 | interruptible_sleep_on(&info->shutdown_wait); | ||
2831 | CY_LOCK(info, flags); | ||
2832 | } | ||
2753 | #endif | 2833 | #endif |
2754 | } | 2834 | } |
2755 | 2835 | ||
2756 | CY_UNLOCK(info, flags); | ||
2757 | shutdown(info); | ||
2758 | if (tty->driver->flush_buffer) | ||
2759 | tty->driver->flush_buffer(tty); | ||
2760 | tty_ldisc_flush(tty); | ||
2761 | CY_LOCK(info, flags); | ||
2762 | |||
2763 | tty->closing = 0; | ||
2764 | info->event = 0; | ||
2765 | info->tty = NULL; | ||
2766 | if (info->blocked_open) { | ||
2767 | CY_UNLOCK(info, flags); | 2836 | CY_UNLOCK(info, flags); |
2768 | if (info->close_delay) { | 2837 | shutdown(info); |
2769 | msleep_interruptible(jiffies_to_msecs(info->close_delay)); | 2838 | if (tty->driver->flush_buffer) |
2770 | } | 2839 | tty->driver->flush_buffer(tty); |
2771 | wake_up_interruptible(&info->open_wait); | 2840 | tty_ldisc_flush(tty); |
2772 | CY_LOCK(info, flags); | 2841 | CY_LOCK(info, flags); |
2773 | } | 2842 | |
2774 | info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 2843 | tty->closing = 0; |
2775 | wake_up_interruptible(&info->close_wait); | 2844 | info->event = 0; |
2845 | info->tty = NULL; | ||
2846 | if (info->blocked_open) { | ||
2847 | CY_UNLOCK(info, flags); | ||
2848 | if (info->close_delay) { | ||
2849 | msleep_interruptible(jiffies_to_msecs | ||
2850 | (info->close_delay)); | ||
2851 | } | ||
2852 | wake_up_interruptible(&info->open_wait); | ||
2853 | CY_LOCK(info, flags); | ||
2854 | } | ||
2855 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | ||
2856 | wake_up_interruptible(&info->close_wait); | ||
2776 | 2857 | ||
2777 | #ifdef CY_DEBUG_OTHER | 2858 | #ifdef CY_DEBUG_OTHER |
2778 | printk(" cyc:cy_close done\n"); | 2859 | printk(" cyc:cy_close done\n"); |
2779 | #endif | 2860 | #endif |
2780 | 2861 | ||
2781 | CY_UNLOCK(info, flags); | 2862 | CY_UNLOCK(info, flags); |
2782 | return; | 2863 | } /* cy_close */ |
2783 | } /* cy_close */ | ||
2784 | |||
2785 | 2864 | ||
2786 | /* This routine gets called when tty_write has put something into | 2865 | /* This routine gets called when tty_write has put something into |
2787 | * the write_queue. The characters may come from user space or | 2866 | * the write_queue. The characters may come from user space or |
@@ -2796,50 +2875,49 @@ cy_close(struct tty_struct *tty, struct file *filp) | |||
2796 | * If the port is already active, there is no need to kick it. | 2875 | * If the port is already active, there is no need to kick it. |
2797 | * | 2876 | * |
2798 | */ | 2877 | */ |
2799 | static int | 2878 | static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count) |
2800 | cy_write(struct tty_struct * tty, const unsigned char *buf, int count) | ||
2801 | { | 2879 | { |
2802 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2880 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2803 | unsigned long flags; | 2881 | unsigned long flags; |
2804 | int c, ret = 0; | 2882 | int c, ret = 0; |
2805 | 2883 | ||
2806 | #ifdef CY_DEBUG_IO | 2884 | #ifdef CY_DEBUG_IO |
2807 | printk("cyc:cy_write ttyC%d\n", info->line); /* */ | 2885 | printk("cyc:cy_write ttyC%d\n", info->line); /* */ |
2808 | #endif | 2886 | #endif |
2809 | 2887 | ||
2810 | if (serial_paranoia_check(info, tty->name, "cy_write")){ | 2888 | if (serial_paranoia_check(info, tty->name, "cy_write")) { |
2811 | return 0; | 2889 | return 0; |
2812 | } | 2890 | } |
2813 | |||
2814 | if (!info->xmit_buf) | ||
2815 | return 0; | ||
2816 | 2891 | ||
2817 | CY_LOCK(info, flags); | 2892 | if (!info->xmit_buf) |
2818 | while (1) { | 2893 | return 0; |
2819 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), | ||
2820 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); | ||
2821 | |||
2822 | if (c <= 0) | ||
2823 | break; | ||
2824 | |||
2825 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
2826 | info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); | ||
2827 | info->xmit_cnt += c; | ||
2828 | buf += c; | ||
2829 | count -= c; | ||
2830 | ret += c; | ||
2831 | } | ||
2832 | CY_UNLOCK(info, flags); | ||
2833 | |||
2834 | info->idle_stats.xmit_bytes += ret; | ||
2835 | info->idle_stats.xmit_idle = jiffies; | ||
2836 | |||
2837 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { | ||
2838 | start_xmit(info); | ||
2839 | } | ||
2840 | return ret; | ||
2841 | } /* cy_write */ | ||
2842 | 2894 | ||
2895 | CY_LOCK(info, flags); | ||
2896 | while (1) { | ||
2897 | c = min(count, min((int)(SERIAL_XMIT_SIZE - info->xmit_cnt - 1), | ||
2898 | (int)(SERIAL_XMIT_SIZE - info->xmit_head))); | ||
2899 | |||
2900 | if (c <= 0) | ||
2901 | break; | ||
2902 | |||
2903 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
2904 | info->xmit_head = (info->xmit_head + c) & | ||
2905 | (SERIAL_XMIT_SIZE - 1); | ||
2906 | info->xmit_cnt += c; | ||
2907 | buf += c; | ||
2908 | count -= c; | ||
2909 | ret += c; | ||
2910 | } | ||
2911 | CY_UNLOCK(info, flags); | ||
2912 | |||
2913 | info->idle_stats.xmit_bytes += ret; | ||
2914 | info->idle_stats.xmit_idle = jiffies; | ||
2915 | |||
2916 | if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { | ||
2917 | start_xmit(info); | ||
2918 | } | ||
2919 | return ret; | ||
2920 | } /* cy_write */ | ||
2843 | 2921 | ||
2844 | /* | 2922 | /* |
2845 | * This routine is called by the kernel to write a single | 2923 | * This routine is called by the kernel to write a single |
@@ -2848,60 +2926,56 @@ cy_write(struct tty_struct * tty, const unsigned char *buf, int count) | |||
2848 | * done stuffing characters into the driver. If there is no room | 2926 | * done stuffing characters into the driver. If there is no room |
2849 | * in the queue, the character is ignored. | 2927 | * in the queue, the character is ignored. |
2850 | */ | 2928 | */ |
2851 | static void | 2929 | static void cy_put_char(struct tty_struct *tty, unsigned char ch) |
2852 | cy_put_char(struct tty_struct *tty, unsigned char ch) | ||
2853 | { | 2930 | { |
2854 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2931 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2855 | unsigned long flags; | 2932 | unsigned long flags; |
2856 | 2933 | ||
2857 | #ifdef CY_DEBUG_IO | 2934 | #ifdef CY_DEBUG_IO |
2858 | printk("cyc:cy_put_char ttyC%d\n", info->line); | 2935 | printk("cyc:cy_put_char ttyC%d\n", info->line); |
2859 | #endif | 2936 | #endif |
2860 | 2937 | ||
2861 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) | 2938 | if (serial_paranoia_check(info, tty->name, "cy_put_char")) |
2862 | return; | 2939 | return; |
2863 | 2940 | ||
2864 | if (!info->xmit_buf) | 2941 | if (!info->xmit_buf) |
2865 | return; | 2942 | return; |
2866 | 2943 | ||
2867 | CY_LOCK(info, flags); | 2944 | CY_LOCK(info, flags); |
2868 | if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { | 2945 | if (info->xmit_cnt >= (int)(SERIAL_XMIT_SIZE - 1)) { |
2869 | CY_UNLOCK(info, flags); | 2946 | CY_UNLOCK(info, flags); |
2870 | return; | 2947 | return; |
2871 | } | 2948 | } |
2872 | 2949 | ||
2873 | info->xmit_buf[info->xmit_head++] = ch; | 2950 | info->xmit_buf[info->xmit_head++] = ch; |
2874 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; | 2951 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; |
2875 | info->xmit_cnt++; | 2952 | info->xmit_cnt++; |
2876 | info->idle_stats.xmit_bytes++; | 2953 | info->idle_stats.xmit_bytes++; |
2877 | info->idle_stats.xmit_idle = jiffies; | 2954 | info->idle_stats.xmit_idle = jiffies; |
2878 | CY_UNLOCK(info, flags); | 2955 | CY_UNLOCK(info, flags); |
2879 | } /* cy_put_char */ | 2956 | } /* cy_put_char */ |
2880 | |||
2881 | 2957 | ||
2882 | /* | 2958 | /* |
2883 | * This routine is called by the kernel after it has written a | 2959 | * This routine is called by the kernel after it has written a |
2884 | * series of characters to the tty device using put_char(). | 2960 | * series of characters to the tty device using put_char(). |
2885 | */ | 2961 | */ |
2886 | static void | 2962 | static void cy_flush_chars(struct tty_struct *tty) |
2887 | cy_flush_chars(struct tty_struct *tty) | ||
2888 | { | 2963 | { |
2889 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2964 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2890 | 2965 | ||
2891 | #ifdef CY_DEBUG_IO | 2966 | #ifdef CY_DEBUG_IO |
2892 | printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */ | 2967 | printk("cyc:cy_flush_chars ttyC%d\n", info->line); /* */ |
2893 | #endif | 2968 | #endif |
2894 | 2969 | ||
2895 | if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) | 2970 | if (serial_paranoia_check(info, tty->name, "cy_flush_chars")) |
2896 | return; | 2971 | return; |
2897 | |||
2898 | if (info->xmit_cnt <= 0 || tty->stopped | ||
2899 | || tty->hw_stopped || !info->xmit_buf) | ||
2900 | return; | ||
2901 | 2972 | ||
2902 | start_xmit(info); | 2973 | if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || |
2903 | } /* cy_flush_chars */ | 2974 | !info->xmit_buf) |
2975 | return; | ||
2904 | 2976 | ||
2977 | start_xmit(info); | ||
2978 | } /* cy_flush_chars */ | ||
2905 | 2979 | ||
2906 | /* | 2980 | /* |
2907 | * This routine returns the numbers of characters the tty driver | 2981 | * This routine returns the numbers of characters the tty driver |
@@ -2909,75 +2983,70 @@ cy_flush_chars(struct tty_struct *tty) | |||
2909 | * to change as output buffers get emptied, or if the output flow | 2983 | * to change as output buffers get emptied, or if the output flow |
2910 | * control is activated. | 2984 | * control is activated. |
2911 | */ | 2985 | */ |
2912 | static int | 2986 | static int cy_write_room(struct tty_struct *tty) |
2913 | cy_write_room(struct tty_struct *tty) | ||
2914 | { | 2987 | { |
2915 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 2988 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2916 | int ret; | 2989 | int ret; |
2917 | 2990 | ||
2918 | #ifdef CY_DEBUG_IO | 2991 | #ifdef CY_DEBUG_IO |
2919 | printk("cyc:cy_write_room ttyC%d\n", info->line); /* */ | 2992 | printk("cyc:cy_write_room ttyC%d\n", info->line); /* */ |
2920 | #endif | 2993 | #endif |
2921 | 2994 | ||
2922 | if (serial_paranoia_check(info, tty->name, "cy_write_room")) | 2995 | if (serial_paranoia_check(info, tty->name, "cy_write_room")) |
2923 | return 0; | 2996 | return 0; |
2924 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; | 2997 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; |
2925 | if (ret < 0) | 2998 | if (ret < 0) |
2926 | ret = 0; | 2999 | ret = 0; |
2927 | return ret; | 3000 | return ret; |
2928 | } /* cy_write_room */ | 3001 | } /* cy_write_room */ |
2929 | |||
2930 | 3002 | ||
2931 | static int | 3003 | static int cy_chars_in_buffer(struct tty_struct *tty) |
2932 | cy_chars_in_buffer(struct tty_struct *tty) | ||
2933 | { | 3004 | { |
2934 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 3005 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
2935 | int card, channel; | 3006 | int card, channel; |
2936 | 3007 | ||
2937 | if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) | 3008 | if (serial_paranoia_check(info, tty->name, "cy_chars_in_buffer")) |
2938 | return 0; | 3009 | return 0; |
2939 | 3010 | ||
2940 | card = info->card; | 3011 | card = info->card; |
2941 | channel = (info->line) - (cy_card[card].first_line); | 3012 | channel = (info->line) - (cy_card[card].first_line); |
2942 | 3013 | ||
2943 | #ifdef Z_EXT_CHARS_IN_BUFFER | 3014 | #ifdef Z_EXT_CHARS_IN_BUFFER |
2944 | if (!IS_CYC_Z(cy_card[card])) { | 3015 | if (!IS_CYC_Z(cy_card[card])) { |
2945 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 3016 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
2946 | #ifdef CY_DEBUG_IO | 3017 | #ifdef CY_DEBUG_IO |
2947 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", | 3018 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt); /* */ |
2948 | info->line, info->xmit_cnt); /* */ | ||
2949 | #endif | 3019 | #endif |
2950 | return info->xmit_cnt; | 3020 | return info->xmit_cnt; |
2951 | #ifdef Z_EXT_CHARS_IN_BUFFER | 3021 | #ifdef Z_EXT_CHARS_IN_BUFFER |
2952 | } else { | 3022 | } else { |
2953 | static volatile struct FIRM_ID *firm_id; | 3023 | static volatile struct FIRM_ID *firm_id; |
2954 | static volatile struct ZFW_CTRL *zfw_ctrl; | 3024 | static volatile struct ZFW_CTRL *zfw_ctrl; |
2955 | static volatile struct CH_CTRL *ch_ctrl; | 3025 | static volatile struct CH_CTRL *ch_ctrl; |
2956 | static volatile struct BUF_CTRL *buf_ctrl; | 3026 | static volatile struct BUF_CTRL *buf_ctrl; |
2957 | int char_count; | 3027 | int char_count; |
2958 | volatile uclong tx_put, tx_get, tx_bufsize; | 3028 | volatile uclong tx_put, tx_get, tx_bufsize; |
2959 | 3029 | ||
2960 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3030 | firm_id = cy_card[card].base_addr + ID_ADDRESS; |
2961 | zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3031 | zfw_ctrl = cy_card[card].base_addr + |
2962 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | 3032 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); |
2963 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | 3033 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
2964 | 3034 | buf_ctrl = &(zfw_ctrl->buf_ctrl[channel]); | |
2965 | tx_get = cy_readl(&buf_ctrl->tx_get); | 3035 | |
2966 | tx_put = cy_readl(&buf_ctrl->tx_put); | 3036 | tx_get = cy_readl(&buf_ctrl->tx_get); |
2967 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); | 3037 | tx_put = cy_readl(&buf_ctrl->tx_put); |
2968 | if (tx_put >= tx_get) | 3038 | tx_bufsize = cy_readl(&buf_ctrl->tx_bufsize); |
2969 | char_count = tx_put - tx_get; | 3039 | if (tx_put >= tx_get) |
2970 | else | 3040 | char_count = tx_put - tx_get; |
2971 | char_count = tx_put - tx_get + tx_bufsize; | 3041 | else |
3042 | char_count = tx_put - tx_get + tx_bufsize; | ||
2972 | #ifdef CY_DEBUG_IO | 3043 | #ifdef CY_DEBUG_IO |
2973 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", | 3044 | printk("cyc:cy_chars_in_buffer ttyC%d %d\n", info->line, info->xmit_cnt + char_count); /* */ |
2974 | info->line, info->xmit_cnt + char_count); /* */ | ||
2975 | #endif | 3045 | #endif |
2976 | return (info->xmit_cnt + char_count); | 3046 | return info->xmit_cnt + char_count; |
2977 | } | 3047 | } |
2978 | #endif /* Z_EXT_CHARS_IN_BUFFER */ | 3048 | #endif /* Z_EXT_CHARS_IN_BUFFER */ |
2979 | } /* cy_chars_in_buffer */ | 3049 | } /* cy_chars_in_buffer */ |
2980 | |||
2981 | 3050 | ||
2982 | /* | 3051 | /* |
2983 | * ------------------------------------------------------------ | 3052 | * ------------------------------------------------------------ |
@@ -2985,178 +3054,179 @@ cy_chars_in_buffer(struct tty_struct *tty) | |||
2985 | * ------------------------------------------------------------ | 3054 | * ------------------------------------------------------------ |
2986 | */ | 3055 | */ |
2987 | 3056 | ||
2988 | static void | 3057 | static void cyy_baud_calc(struct cyclades_port *info, uclong baud) |
2989 | cyy_baud_calc(struct cyclades_port *info, uclong baud) | ||
2990 | { | 3058 | { |
2991 | int co, co_val, bpr; | 3059 | int co, co_val, bpr; |
2992 | uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000); | 3060 | uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : |
2993 | 3061 | 25000000); | |
2994 | if (baud == 0) { | 3062 | |
2995 | info->tbpr = info->tco = info->rbpr = info->rco = 0; | 3063 | if (baud == 0) { |
2996 | return; | 3064 | info->tbpr = info->tco = info->rbpr = info->rco = 0; |
2997 | } | 3065 | return; |
2998 | 3066 | } | |
2999 | /* determine which prescaler to use */ | 3067 | |
3000 | for (co = 4, co_val = 2048; co; co--, co_val >>= 2) { | 3068 | /* determine which prescaler to use */ |
3001 | if (cy_clock / co_val / baud > 63) | 3069 | for (co = 4, co_val = 2048; co; co--, co_val >>= 2) { |
3002 | break; | 3070 | if (cy_clock / co_val / baud > 63) |
3003 | } | 3071 | break; |
3004 | 3072 | } | |
3005 | bpr = (cy_clock / co_val * 2 / baud + 1) / 2; | 3073 | |
3006 | if (bpr > 255) | 3074 | bpr = (cy_clock / co_val * 2 / baud + 1) / 2; |
3007 | bpr = 255; | 3075 | if (bpr > 255) |
3008 | 3076 | bpr = 255; | |
3009 | info->tbpr = info->rbpr = bpr; | 3077 | |
3010 | info->tco = info->rco = co; | 3078 | info->tbpr = info->rbpr = bpr; |
3079 | info->tco = info->rco = co; | ||
3011 | } | 3080 | } |
3012 | 3081 | ||
3013 | /* | 3082 | /* |
3014 | * This routine finds or computes the various line characteristics. | 3083 | * This routine finds or computes the various line characteristics. |
3015 | * It used to be called config_setup | 3084 | * It used to be called config_setup |
3016 | */ | 3085 | */ |
3017 | static void | 3086 | static void set_line_char(struct cyclades_port *info) |
3018 | set_line_char(struct cyclades_port * info) | ||
3019 | { | 3087 | { |
3020 | unsigned long flags; | 3088 | unsigned long flags; |
3021 | void __iomem *base_addr; | 3089 | void __iomem *base_addr; |
3022 | int card,chip,channel,index; | 3090 | int card, chip, channel, index; |
3023 | unsigned cflag, iflag; | 3091 | unsigned cflag, iflag; |
3024 | unsigned short chip_number; | 3092 | unsigned short chip_number; |
3025 | int baud, baud_rate = 0; | 3093 | int baud, baud_rate = 0; |
3026 | int i; | 3094 | int i; |
3027 | 3095 | ||
3028 | 3096 | if (!info->tty || !info->tty->termios) { | |
3029 | if (!info->tty || !info->tty->termios){ | 3097 | return; |
3030 | return; | ||
3031 | } | ||
3032 | if (info->line == -1){ | ||
3033 | return; | ||
3034 | } | ||
3035 | cflag = info->tty->termios->c_cflag; | ||
3036 | iflag = info->tty->termios->c_iflag; | ||
3037 | |||
3038 | /* | ||
3039 | * Set up the tty->alt_speed kludge | ||
3040 | */ | ||
3041 | if (info->tty) { | ||
3042 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) | ||
3043 | info->tty->alt_speed = 57600; | ||
3044 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) | ||
3045 | info->tty->alt_speed = 115200; | ||
3046 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) | ||
3047 | info->tty->alt_speed = 230400; | ||
3048 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) | ||
3049 | info->tty->alt_speed = 460800; | ||
3050 | } | ||
3051 | |||
3052 | card = info->card; | ||
3053 | channel = (info->line) - (cy_card[card].first_line); | ||
3054 | chip_number = channel / 4; | ||
3055 | |||
3056 | if (!IS_CYC_Z(cy_card[card])) { | ||
3057 | |||
3058 | index = cy_card[card].bus_index; | ||
3059 | |||
3060 | /* baud rate */ | ||
3061 | baud = tty_get_baud_rate(info->tty); | ||
3062 | if ((baud == 38400) && | ||
3063 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { | ||
3064 | if (info->custom_divisor) | ||
3065 | baud_rate = info->baud / info->custom_divisor; | ||
3066 | else | ||
3067 | baud_rate = info->baud; | ||
3068 | } else if (baud > CD1400_MAX_SPEED) { | ||
3069 | baud = CD1400_MAX_SPEED; | ||
3070 | } | 3098 | } |
3071 | /* find the baud index */ | 3099 | if (info->line == -1) { |
3072 | for (i = 0; i < 20; i++) { | 3100 | return; |
3073 | if (baud == baud_table[i]) { | ||
3074 | break; | ||
3075 | } | ||
3076 | } | 3101 | } |
3077 | if (i == 20) { | 3102 | cflag = info->tty->termios->c_cflag; |
3078 | i = 19; /* CD1400_MAX_SPEED */ | 3103 | iflag = info->tty->termios->c_iflag; |
3079 | } | ||
3080 | 3104 | ||
3081 | if ((baud == 38400) && | 3105 | /* |
3082 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { | 3106 | * Set up the tty->alt_speed kludge |
3083 | cyy_baud_calc(info, baud_rate); | 3107 | */ |
3084 | } else { | 3108 | if (info->tty) { |
3085 | if(info->chip_rev >= CD1400_REV_J) { | 3109 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) |
3086 | /* It is a CD1400 rev. J or later */ | 3110 | info->tty->alt_speed = 57600; |
3087 | info->tbpr = baud_bpr_60[i]; /* Tx BPR */ | 3111 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) |
3088 | info->tco = baud_co_60[i]; /* Tx CO */ | 3112 | info->tty->alt_speed = 115200; |
3089 | info->rbpr = baud_bpr_60[i]; /* Rx BPR */ | 3113 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) |
3090 | info->rco = baud_co_60[i]; /* Rx CO */ | 3114 | info->tty->alt_speed = 230400; |
3091 | } else { | 3115 | if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) |
3092 | info->tbpr = baud_bpr_25[i]; /* Tx BPR */ | 3116 | info->tty->alt_speed = 460800; |
3093 | info->tco = baud_co_25[i]; /* Tx CO */ | ||
3094 | info->rbpr = baud_bpr_25[i]; /* Rx BPR */ | ||
3095 | info->rco = baud_co_25[i]; /* Rx CO */ | ||
3096 | } | ||
3097 | } | ||
3098 | if (baud_table[i] == 134) { | ||
3099 | /* get it right for 134.5 baud */ | ||
3100 | info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2; | ||
3101 | } else if ((baud == 38400) && | ||
3102 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { | ||
3103 | info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2; | ||
3104 | } else if (baud_table[i]) { | ||
3105 | info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2; | ||
3106 | /* this needs to be propagated into the card info */ | ||
3107 | } else { | ||
3108 | info->timeout = 0; | ||
3109 | } | ||
3110 | /* By tradition (is it a standard?) a baud rate of zero | ||
3111 | implies the line should be/has been closed. A bit | ||
3112 | later in this routine such a test is performed. */ | ||
3113 | |||
3114 | /* byte size and parity */ | ||
3115 | info->cor5 = 0; | ||
3116 | info->cor4 = 0; | ||
3117 | info->cor3 = (info->default_threshold | ||
3118 | ? info->default_threshold | ||
3119 | : baud_cor3[i]); /* receive threshold */ | ||
3120 | info->cor2 = CyETC; | ||
3121 | switch(cflag & CSIZE){ | ||
3122 | case CS5: | ||
3123 | info->cor1 = Cy_5_BITS; | ||
3124 | break; | ||
3125 | case CS6: | ||
3126 | info->cor1 = Cy_6_BITS; | ||
3127 | break; | ||
3128 | case CS7: | ||
3129 | info->cor1 = Cy_7_BITS; | ||
3130 | break; | ||
3131 | case CS8: | ||
3132 | info->cor1 = Cy_8_BITS; | ||
3133 | break; | ||
3134 | } | ||
3135 | if(cflag & CSTOPB){ | ||
3136 | info->cor1 |= Cy_2_STOP; | ||
3137 | } | ||
3138 | if (cflag & PARENB){ | ||
3139 | if (cflag & PARODD){ | ||
3140 | info->cor1 |= CyPARITY_O; | ||
3141 | }else{ | ||
3142 | info->cor1 |= CyPARITY_E; | ||
3143 | } | ||
3144 | }else{ | ||
3145 | info->cor1 |= CyPARITY_NONE; | ||
3146 | } | ||
3147 | |||
3148 | /* CTS flow control flag */ | ||
3149 | if (cflag & CRTSCTS){ | ||
3150 | info->flags |= ASYNC_CTS_FLOW; | ||
3151 | info->cor2 |= CyCtsAE; | ||
3152 | }else{ | ||
3153 | info->flags &= ~ASYNC_CTS_FLOW; | ||
3154 | info->cor2 &= ~CyCtsAE; | ||
3155 | } | 3117 | } |
3156 | if (cflag & CLOCAL) | 3118 | |
3157 | info->flags &= ~ASYNC_CHECK_CD; | 3119 | card = info->card; |
3158 | else | 3120 | channel = (info->line) - (cy_card[card].first_line); |
3159 | info->flags |= ASYNC_CHECK_CD; | 3121 | chip_number = channel / 4; |
3122 | |||
3123 | if (!IS_CYC_Z(cy_card[card])) { | ||
3124 | |||
3125 | index = cy_card[card].bus_index; | ||
3126 | |||
3127 | /* baud rate */ | ||
3128 | baud = tty_get_baud_rate(info->tty); | ||
3129 | if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == | ||
3130 | ASYNC_SPD_CUST) { | ||
3131 | if (info->custom_divisor) | ||
3132 | baud_rate = info->baud / info->custom_divisor; | ||
3133 | else | ||
3134 | baud_rate = info->baud; | ||
3135 | } else if (baud > CD1400_MAX_SPEED) { | ||
3136 | baud = CD1400_MAX_SPEED; | ||
3137 | } | ||
3138 | /* find the baud index */ | ||
3139 | for (i = 0; i < 20; i++) { | ||
3140 | if (baud == baud_table[i]) { | ||
3141 | break; | ||
3142 | } | ||
3143 | } | ||
3144 | if (i == 20) { | ||
3145 | i = 19; /* CD1400_MAX_SPEED */ | ||
3146 | } | ||
3147 | |||
3148 | if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == | ||
3149 | ASYNC_SPD_CUST) { | ||
3150 | cyy_baud_calc(info, baud_rate); | ||
3151 | } else { | ||
3152 | if (info->chip_rev >= CD1400_REV_J) { | ||
3153 | /* It is a CD1400 rev. J or later */ | ||
3154 | info->tbpr = baud_bpr_60[i]; /* Tx BPR */ | ||
3155 | info->tco = baud_co_60[i]; /* Tx CO */ | ||
3156 | info->rbpr = baud_bpr_60[i]; /* Rx BPR */ | ||
3157 | info->rco = baud_co_60[i]; /* Rx CO */ | ||
3158 | } else { | ||
3159 | info->tbpr = baud_bpr_25[i]; /* Tx BPR */ | ||
3160 | info->tco = baud_co_25[i]; /* Tx CO */ | ||
3161 | info->rbpr = baud_bpr_25[i]; /* Rx BPR */ | ||
3162 | info->rco = baud_co_25[i]; /* Rx CO */ | ||
3163 | } | ||
3164 | } | ||
3165 | if (baud_table[i] == 134) { | ||
3166 | /* get it right for 134.5 baud */ | ||
3167 | info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + | ||
3168 | 2; | ||
3169 | } else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == | ||
3170 | ASYNC_SPD_CUST) { | ||
3171 | info->timeout = (info->xmit_fifo_size * HZ * 15 / | ||
3172 | baud_rate) + 2; | ||
3173 | } else if (baud_table[i]) { | ||
3174 | info->timeout = (info->xmit_fifo_size * HZ * 15 / | ||
3175 | baud_table[i]) + 2; | ||
3176 | /* this needs to be propagated into the card info */ | ||
3177 | } else { | ||
3178 | info->timeout = 0; | ||
3179 | } | ||
3180 | /* By tradition (is it a standard?) a baud rate of zero | ||
3181 | implies the line should be/has been closed. A bit | ||
3182 | later in this routine such a test is performed. */ | ||
3183 | |||
3184 | /* byte size and parity */ | ||
3185 | info->cor5 = 0; | ||
3186 | info->cor4 = 0; | ||
3187 | /* receive threshold */ | ||
3188 | info->cor3 = (info->default_threshold ? | ||
3189 | info->default_threshold : baud_cor3[i]); | ||
3190 | info->cor2 = CyETC; | ||
3191 | switch (cflag & CSIZE) { | ||
3192 | case CS5: | ||
3193 | info->cor1 = Cy_5_BITS; | ||
3194 | break; | ||
3195 | case CS6: | ||
3196 | info->cor1 = Cy_6_BITS; | ||
3197 | break; | ||
3198 | case CS7: | ||
3199 | info->cor1 = Cy_7_BITS; | ||
3200 | break; | ||
3201 | case CS8: | ||
3202 | info->cor1 = Cy_8_BITS; | ||
3203 | break; | ||
3204 | } | ||
3205 | if (cflag & CSTOPB) { | ||
3206 | info->cor1 |= Cy_2_STOP; | ||
3207 | } | ||
3208 | if (cflag & PARENB) { | ||
3209 | if (cflag & PARODD) { | ||
3210 | info->cor1 |= CyPARITY_O; | ||
3211 | } else { | ||
3212 | info->cor1 |= CyPARITY_E; | ||
3213 | } | ||
3214 | } else { | ||
3215 | info->cor1 |= CyPARITY_NONE; | ||
3216 | } | ||
3217 | |||
3218 | /* CTS flow control flag */ | ||
3219 | if (cflag & CRTSCTS) { | ||
3220 | info->flags |= ASYNC_CTS_FLOW; | ||
3221 | info->cor2 |= CyCtsAE; | ||
3222 | } else { | ||
3223 | info->flags &= ~ASYNC_CTS_FLOW; | ||
3224 | info->cor2 &= ~CyCtsAE; | ||
3225 | } | ||
3226 | if (cflag & CLOCAL) | ||
3227 | info->flags &= ~ASYNC_CHECK_CD; | ||
3228 | else | ||
3229 | info->flags |= ASYNC_CHECK_CD; | ||
3160 | 3230 | ||
3161 | /*********************************************** | 3231 | /*********************************************** |
3162 | The hardware option, CyRtsAO, presents RTS when | 3232 | The hardware option, CyRtsAO, presents RTS when |
@@ -3168,300 +3238,319 @@ set_line_char(struct cyclades_port * info) | |||
3168 | cable. Contact Marcio Saito for details. | 3238 | cable. Contact Marcio Saito for details. |
3169 | ***********************************************/ | 3239 | ***********************************************/ |
3170 | 3240 | ||
3171 | chip = channel>>2; | 3241 | chip = channel >> 2; |
3172 | channel &= 0x03; | 3242 | channel &= 0x03; |
3173 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | 3243 | base_addr = cy_card[card].base_addr + |
3244 | (cy_chip_offset[chip] << index); | ||
3174 | 3245 | ||
3175 | CY_LOCK(info, flags); | 3246 | CY_LOCK(info, flags); |
3176 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 3247 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
3177 | 3248 | ||
3178 | /* tx and rx baud rate */ | 3249 | /* tx and rx baud rate */ |
3179 | 3250 | ||
3180 | cy_writeb(base_addr+(CyTCOR<<index), info->tco); | 3251 | cy_writeb(base_addr + (CyTCOR << index), info->tco); |
3181 | cy_writeb(base_addr+(CyTBPR<<index), info->tbpr); | 3252 | cy_writeb(base_addr + (CyTBPR << index), info->tbpr); |
3182 | cy_writeb(base_addr+(CyRCOR<<index), info->rco); | 3253 | cy_writeb(base_addr + (CyRCOR << index), info->rco); |
3183 | cy_writeb(base_addr+(CyRBPR<<index), info->rbpr); | 3254 | cy_writeb(base_addr + (CyRBPR << index), info->rbpr); |
3184 | 3255 | ||
3185 | /* set line characteristics according configuration */ | 3256 | /* set line characteristics according configuration */ |
3186 | 3257 | ||
3187 | cy_writeb(base_addr+(CySCHR1<<index), | 3258 | cy_writeb(base_addr + (CySCHR1 << index), |
3188 | START_CHAR(info->tty)); | 3259 | START_CHAR(info->tty)); |
3189 | cy_writeb(base_addr+(CySCHR2<<index), | 3260 | cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->tty)); |
3190 | STOP_CHAR(info->tty)); | 3261 | cy_writeb(base_addr + (CyCOR1 << index), info->cor1); |
3191 | cy_writeb(base_addr+(CyCOR1<<index), info->cor1); | 3262 | cy_writeb(base_addr + (CyCOR2 << index), info->cor2); |
3192 | cy_writeb(base_addr+(CyCOR2<<index), info->cor2); | 3263 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); |
3193 | cy_writeb(base_addr+(CyCOR3<<index), info->cor3); | 3264 | cy_writeb(base_addr + (CyCOR4 << index), info->cor4); |
3194 | cy_writeb(base_addr+(CyCOR4<<index), info->cor4); | 3265 | cy_writeb(base_addr + (CyCOR5 << index), info->cor5); |
3195 | cy_writeb(base_addr+(CyCOR5<<index), info->cor5); | 3266 | |
3196 | 3267 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR1ch | CyCOR2ch | | |
3197 | cyy_issue_cmd(base_addr, | 3268 | CyCOR3ch, index); |
3198 | CyCOR_CHANGE|CyCOR1ch|CyCOR2ch|CyCOR3ch,index); | 3269 | |
3199 | 3270 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); /* !!! Is this needed? */ | |
3200 | cy_writeb(base_addr+(CyCAR<<index), | 3271 | cy_writeb(base_addr + (CyRTPR << index), |
3201 | (u_char)channel); /* !!! Is this needed? */ | 3272 | (info->default_timeout ? info->default_timeout : 0x02)); |
3202 | cy_writeb(base_addr+(CyRTPR<<index), (info->default_timeout | 3273 | /* 10ms rx timeout */ |
3203 | ? info->default_timeout | 3274 | |
3204 | : 0x02)); /* 10ms rx timeout */ | 3275 | if (C_CLOCAL(info->tty)) { |
3205 | 3276 | /* without modem intr */ | |
3206 | if (C_CLOCAL(info->tty)) { | 3277 | cy_writeb(base_addr + (CySRER << index), |
3207 | /* without modem intr */ | 3278 | cy_readb(base_addr + |
3208 | cy_writeb(base_addr+(CySRER<<index), | 3279 | (CySRER << index)) | CyMdmCh); |
3209 | cy_readb(base_addr+(CySRER<<index)) | CyMdmCh); | 3280 | /* act on 1->0 modem transitions */ |
3210 | /* act on 1->0 modem transitions */ | 3281 | if ((cflag & CRTSCTS) && info->rflow) { |
3211 | if ((cflag & CRTSCTS) && info->rflow) { | 3282 | cy_writeb(base_addr + (CyMCOR1 << index), |
3212 | cy_writeb(base_addr+(CyMCOR1<<index), | 3283 | (CyCTS | rflow_thr[i])); |
3213 | (CyCTS|rflow_thr[i])); | 3284 | } else { |
3214 | } else { | 3285 | cy_writeb(base_addr + (CyMCOR1 << index), |
3215 | cy_writeb(base_addr+(CyMCOR1<<index), CyCTS); | 3286 | CyCTS); |
3216 | } | 3287 | } |
3217 | /* act on 0->1 modem transitions */ | 3288 | /* act on 0->1 modem transitions */ |
3218 | cy_writeb(base_addr+(CyMCOR2<<index), CyCTS); | 3289 | cy_writeb(base_addr + (CyMCOR2 << index), CyCTS); |
3219 | } else { | ||
3220 | /* without modem intr */ | ||
3221 | cy_writeb(base_addr+(CySRER<<index), | ||
3222 | cy_readb(base_addr+(CySRER<<index)) | CyMdmCh); | ||
3223 | /* act on 1->0 modem transitions */ | ||
3224 | if ((cflag & CRTSCTS) && info->rflow) { | ||
3225 | cy_writeb(base_addr+(CyMCOR1<<index), | ||
3226 | (CyDSR|CyCTS|CyRI|CyDCD|rflow_thr[i])); | ||
3227 | } else { | ||
3228 | cy_writeb(base_addr+(CyMCOR1<<index), | ||
3229 | CyDSR|CyCTS|CyRI|CyDCD); | ||
3230 | } | ||
3231 | /* act on 0->1 modem transitions */ | ||
3232 | cy_writeb(base_addr+(CyMCOR2<<index), | ||
3233 | CyDSR|CyCTS|CyRI|CyDCD); | ||
3234 | } | ||
3235 | |||
3236 | if(i == 0){ /* baud rate is zero, turn off line */ | ||
3237 | if (info->rtsdtr_inv) { | ||
3238 | cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS); | ||
3239 | } else { | 3290 | } else { |
3240 | cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR); | 3291 | /* without modem intr */ |
3292 | cy_writeb(base_addr + (CySRER << index), | ||
3293 | cy_readb(base_addr + | ||
3294 | (CySRER << index)) | CyMdmCh); | ||
3295 | /* act on 1->0 modem transitions */ | ||
3296 | if ((cflag & CRTSCTS) && info->rflow) { | ||
3297 | cy_writeb(base_addr + (CyMCOR1 << index), | ||
3298 | (CyDSR | CyCTS | CyRI | CyDCD | | ||
3299 | rflow_thr[i])); | ||
3300 | } else { | ||
3301 | cy_writeb(base_addr + (CyMCOR1 << index), | ||
3302 | CyDSR | CyCTS | CyRI | CyDCD); | ||
3303 | } | ||
3304 | /* act on 0->1 modem transitions */ | ||
3305 | cy_writeb(base_addr + (CyMCOR2 << index), | ||
3306 | CyDSR | CyCTS | CyRI | CyDCD); | ||
3241 | } | 3307 | } |
3308 | |||
3309 | if (i == 0) { /* baud rate is zero, turn off line */ | ||
3310 | if (info->rtsdtr_inv) { | ||
3311 | cy_writeb(base_addr + (CyMSVR1 << index), | ||
3312 | ~CyRTS); | ||
3313 | } else { | ||
3314 | cy_writeb(base_addr + (CyMSVR2 << index), | ||
3315 | ~CyDTR); | ||
3316 | } | ||
3242 | #ifdef CY_DEBUG_DTR | 3317 | #ifdef CY_DEBUG_DTR |
3243 | printk("cyc:set_line_char dropping DTR\n"); | 3318 | printk("cyc:set_line_char dropping DTR\n"); |
3244 | printk(" status: 0x%x, 0x%x\n", | 3319 | printk(" status: 0x%x, 0x%x\n", |
3245 | cy_readb(base_addr+(CyMSVR1<<index)), | 3320 | cy_readb(base_addr + (CyMSVR1 << index)), |
3246 | cy_readb(base_addr+(CyMSVR2<<index))); | 3321 | cy_readb(base_addr + (CyMSVR2 << index))); |
3247 | #endif | 3322 | #endif |
3248 | }else{ | 3323 | } else { |
3249 | if (info->rtsdtr_inv) { | 3324 | if (info->rtsdtr_inv) { |
3250 | cy_writeb(base_addr+(CyMSVR1<<index), CyRTS); | 3325 | cy_writeb(base_addr + (CyMSVR1 << index), |
3251 | } else { | 3326 | CyRTS); |
3252 | cy_writeb(base_addr+(CyMSVR2<<index), CyDTR); | 3327 | } else { |
3253 | } | 3328 | cy_writeb(base_addr + (CyMSVR2 << index), |
3329 | CyDTR); | ||
3330 | } | ||
3254 | #ifdef CY_DEBUG_DTR | 3331 | #ifdef CY_DEBUG_DTR |
3255 | printk("cyc:set_line_char raising DTR\n"); | 3332 | printk("cyc:set_line_char raising DTR\n"); |
3256 | printk(" status: 0x%x, 0x%x\n", | 3333 | printk(" status: 0x%x, 0x%x\n", |
3257 | cy_readb(base_addr+(CyMSVR1<<index)), | 3334 | cy_readb(base_addr + (CyMSVR1 << index)), |
3258 | cy_readb(base_addr+(CyMSVR2<<index))); | 3335 | cy_readb(base_addr + (CyMSVR2 << index))); |
3259 | #endif | 3336 | #endif |
3260 | } | 3337 | } |
3261 | |||
3262 | if (info->tty){ | ||
3263 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
3264 | } | ||
3265 | CY_UNLOCK(info, flags); | ||
3266 | 3338 | ||
3267 | } else { | 3339 | if (info->tty) { |
3268 | struct FIRM_ID __iomem *firm_id; | 3340 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
3269 | struct ZFW_CTRL __iomem *zfw_ctrl; | 3341 | } |
3270 | struct BOARD_CTRL __iomem *board_ctrl; | 3342 | CY_UNLOCK(info, flags); |
3271 | struct CH_CTRL __iomem *ch_ctrl; | ||
3272 | struct BUF_CTRL __iomem *buf_ctrl; | ||
3273 | uclong sw_flow; | ||
3274 | int retval; | ||
3275 | |||
3276 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | ||
3277 | if (!ISZLOADED(cy_card[card])) { | ||
3278 | return; | ||
3279 | } | ||
3280 | 3343 | ||
3281 | zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
3282 | board_ctrl = &zfw_ctrl->board_ctrl; | ||
3283 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); | ||
3284 | buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; | ||
3285 | |||
3286 | /* baud rate */ | ||
3287 | baud = tty_get_baud_rate(info->tty); | ||
3288 | if ((baud == 38400) && | ||
3289 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { | ||
3290 | if (info->custom_divisor) | ||
3291 | baud_rate = info->baud / info->custom_divisor; | ||
3292 | else | ||
3293 | baud_rate = info->baud; | ||
3294 | } else if (baud > CYZ_MAX_SPEED) { | ||
3295 | baud = CYZ_MAX_SPEED; | ||
3296 | } | ||
3297 | cy_writel(&ch_ctrl->comm_baud , baud); | ||
3298 | |||
3299 | if (baud == 134) { | ||
3300 | /* get it right for 134.5 baud */ | ||
3301 | info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2; | ||
3302 | } else if ((baud == 38400) && | ||
3303 | ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) { | ||
3304 | info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2; | ||
3305 | } else if (baud) { | ||
3306 | info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2; | ||
3307 | /* this needs to be propagated into the card info */ | ||
3308 | } else { | 3344 | } else { |
3309 | info->timeout = 0; | 3345 | struct FIRM_ID __iomem *firm_id; |
3310 | } | 3346 | struct ZFW_CTRL __iomem *zfw_ctrl; |
3347 | struct BOARD_CTRL __iomem *board_ctrl; | ||
3348 | struct CH_CTRL __iomem *ch_ctrl; | ||
3349 | struct BUF_CTRL __iomem *buf_ctrl; | ||
3350 | uclong sw_flow; | ||
3351 | int retval; | ||
3352 | |||
3353 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | ||
3354 | if (!ISZLOADED(cy_card[card])) { | ||
3355 | return; | ||
3356 | } | ||
3311 | 3357 | ||
3312 | /* byte size and parity */ | 3358 | zfw_ctrl = cy_card[card].base_addr + |
3313 | switch(cflag & CSIZE){ | 3359 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3314 | case CS5: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS5); break; | 3360 | board_ctrl = &zfw_ctrl->board_ctrl; |
3315 | case CS6: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS6); break; | 3361 | ch_ctrl = &(zfw_ctrl->ch_ctrl[channel]); |
3316 | case CS7: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS7); break; | 3362 | buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; |
3317 | case CS8: cy_writel(&ch_ctrl->comm_data_l , C_DL_CS8); break; | 3363 | |
3318 | } | 3364 | /* baud rate */ |
3319 | if(cflag & CSTOPB){ | 3365 | baud = tty_get_baud_rate(info->tty); |
3320 | cy_writel(&ch_ctrl->comm_data_l, | 3366 | if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == |
3321 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); | 3367 | ASYNC_SPD_CUST) { |
3322 | }else{ | 3368 | if (info->custom_divisor) |
3323 | cy_writel(&ch_ctrl->comm_data_l, | 3369 | baud_rate = info->baud / info->custom_divisor; |
3324 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); | 3370 | else |
3325 | } | 3371 | baud_rate = info->baud; |
3326 | if (cflag & PARENB){ | 3372 | } else if (baud > CYZ_MAX_SPEED) { |
3327 | if (cflag & PARODD){ | 3373 | baud = CYZ_MAX_SPEED; |
3328 | cy_writel(&ch_ctrl->comm_parity , C_PR_ODD); | 3374 | } |
3329 | }else{ | 3375 | cy_writel(&ch_ctrl->comm_baud, baud); |
3330 | cy_writel(&ch_ctrl->comm_parity , C_PR_EVEN); | 3376 | |
3331 | } | 3377 | if (baud == 134) { |
3332 | }else{ | 3378 | /* get it right for 134.5 baud */ |
3333 | cy_writel(&ch_ctrl->comm_parity , C_PR_NONE); | 3379 | info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + |
3334 | } | 3380 | 2; |
3381 | } else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == | ||
3382 | ASYNC_SPD_CUST) { | ||
3383 | info->timeout = (info->xmit_fifo_size * HZ * 15 / | ||
3384 | baud_rate) + 2; | ||
3385 | } else if (baud) { | ||
3386 | info->timeout = (info->xmit_fifo_size * HZ * 15 / | ||
3387 | baud) + 2; | ||
3388 | /* this needs to be propagated into the card info */ | ||
3389 | } else { | ||
3390 | info->timeout = 0; | ||
3391 | } | ||
3335 | 3392 | ||
3336 | /* CTS flow control flag */ | 3393 | /* byte size and parity */ |
3337 | if (cflag & CRTSCTS){ | 3394 | switch (cflag & CSIZE) { |
3338 | cy_writel(&ch_ctrl->hw_flow, | 3395 | case CS5: |
3339 | cy_readl(&ch_ctrl->hw_flow) | C_RS_CTS | C_RS_RTS); | 3396 | cy_writel(&ch_ctrl->comm_data_l, C_DL_CS5); |
3340 | }else{ | 3397 | break; |
3341 | cy_writel(&ch_ctrl->hw_flow, | 3398 | case CS6: |
3342 | cy_readl(&ch_ctrl->hw_flow) & ~(C_RS_CTS | C_RS_RTS)); | 3399 | cy_writel(&ch_ctrl->comm_data_l, C_DL_CS6); |
3343 | } | 3400 | break; |
3344 | /* As the HW flow control is done in firmware, the driver doesn't | 3401 | case CS7: |
3345 | need to care about it */ | 3402 | cy_writel(&ch_ctrl->comm_data_l, C_DL_CS7); |
3346 | info->flags &= ~ASYNC_CTS_FLOW; | 3403 | break; |
3347 | 3404 | case CS8: | |
3348 | /* XON/XOFF/XANY flow control flags */ | 3405 | cy_writel(&ch_ctrl->comm_data_l, C_DL_CS8); |
3349 | sw_flow = 0; | 3406 | break; |
3350 | if (iflag & IXON){ | 3407 | } |
3351 | sw_flow |= C_FL_OXX; | 3408 | if (cflag & CSTOPB) { |
3352 | if (iflag & IXANY) | 3409 | cy_writel(&ch_ctrl->comm_data_l, |
3353 | sw_flow |= C_FL_OIXANY; | 3410 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_2STOP); |
3354 | } | 3411 | } else { |
3355 | cy_writel(&ch_ctrl->sw_flow, sw_flow); | 3412 | cy_writel(&ch_ctrl->comm_data_l, |
3413 | cy_readl(&ch_ctrl->comm_data_l) | C_DL_1STOP); | ||
3414 | } | ||
3415 | if (cflag & PARENB) { | ||
3416 | if (cflag & PARODD) { | ||
3417 | cy_writel(&ch_ctrl->comm_parity, C_PR_ODD); | ||
3418 | } else { | ||
3419 | cy_writel(&ch_ctrl->comm_parity, C_PR_EVEN); | ||
3420 | } | ||
3421 | } else { | ||
3422 | cy_writel(&ch_ctrl->comm_parity, C_PR_NONE); | ||
3423 | } | ||
3356 | 3424 | ||
3357 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); | 3425 | /* CTS flow control flag */ |
3358 | if (retval != 0){ | 3426 | if (cflag & CRTSCTS) { |
3359 | printk("cyc:set_line_char retval on ttyC%d was %x\n", | 3427 | cy_writel(&ch_ctrl->hw_flow, |
3360 | info->line, retval); | 3428 | cy_readl(&ch_ctrl-> |
3361 | } | 3429 | hw_flow) | C_RS_CTS | C_RS_RTS); |
3430 | } else { | ||
3431 | cy_writel(&ch_ctrl->hw_flow, | ||
3432 | cy_readl(&ch_ctrl-> | ||
3433 | hw_flow) & ~(C_RS_CTS | C_RS_RTS)); | ||
3434 | } | ||
3435 | /* As the HW flow control is done in firmware, the driver | ||
3436 | doesn't need to care about it */ | ||
3437 | info->flags &= ~ASYNC_CTS_FLOW; | ||
3438 | |||
3439 | /* XON/XOFF/XANY flow control flags */ | ||
3440 | sw_flow = 0; | ||
3441 | if (iflag & IXON) { | ||
3442 | sw_flow |= C_FL_OXX; | ||
3443 | if (iflag & IXANY) | ||
3444 | sw_flow |= C_FL_OIXANY; | ||
3445 | } | ||
3446 | cy_writel(&ch_ctrl->sw_flow, sw_flow); | ||
3362 | 3447 | ||
3363 | /* CD sensitivity */ | 3448 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTL, 0L); |
3364 | if (cflag & CLOCAL){ | 3449 | if (retval != 0) { |
3365 | info->flags &= ~ASYNC_CHECK_CD; | 3450 | printk("cyc:set_line_char retval on ttyC%d was %x\n", |
3366 | }else{ | 3451 | info->line, retval); |
3367 | info->flags |= ASYNC_CHECK_CD; | 3452 | } |
3368 | } | 3453 | |
3454 | /* CD sensitivity */ | ||
3455 | if (cflag & CLOCAL) { | ||
3456 | info->flags &= ~ASYNC_CHECK_CD; | ||
3457 | } else { | ||
3458 | info->flags |= ASYNC_CHECK_CD; | ||
3459 | } | ||
3369 | 3460 | ||
3370 | if(baud == 0){ /* baud rate is zero, turn off line */ | 3461 | if (baud == 0) { /* baud rate is zero, turn off line */ |
3371 | cy_writel(&ch_ctrl->rs_control, | 3462 | cy_writel(&ch_ctrl->rs_control, |
3372 | cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR); | 3463 | cy_readl(&ch_ctrl->rs_control) & ~C_RS_DTR); |
3373 | #ifdef CY_DEBUG_DTR | 3464 | #ifdef CY_DEBUG_DTR |
3374 | printk("cyc:set_line_char dropping Z DTR\n"); | 3465 | printk("cyc:set_line_char dropping Z DTR\n"); |
3375 | #endif | 3466 | #endif |
3376 | }else{ | 3467 | } else { |
3377 | cy_writel(&ch_ctrl->rs_control, | 3468 | cy_writel(&ch_ctrl->rs_control, |
3378 | cy_readl(&ch_ctrl->rs_control) | C_RS_DTR); | 3469 | cy_readl(&ch_ctrl->rs_control) | C_RS_DTR); |
3379 | #ifdef CY_DEBUG_DTR | 3470 | #ifdef CY_DEBUG_DTR |
3380 | printk("cyc:set_line_char raising Z DTR\n"); | 3471 | printk("cyc:set_line_char raising Z DTR\n"); |
3381 | #endif | 3472 | #endif |
3382 | } | 3473 | } |
3383 | 3474 | ||
3384 | retval = cyz_issue_cmd( &cy_card[card], channel, C_CM_IOCTLM, 0L); | 3475 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_IOCTLM,0L); |
3385 | if (retval != 0){ | 3476 | if (retval != 0) { |
3386 | printk("cyc:set_line_char(2) retval on ttyC%d was %x\n", | 3477 | printk("cyc:set_line_char(2) retval on ttyC%d was %x\n", |
3387 | info->line, retval); | 3478 | info->line, retval); |
3388 | } | 3479 | } |
3389 | 3480 | ||
3390 | if (info->tty){ | 3481 | if (info->tty) { |
3391 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | 3482 | clear_bit(TTY_IO_ERROR, &info->tty->flags); |
3483 | } | ||
3392 | } | 3484 | } |
3393 | } | 3485 | } /* set_line_char */ |
3394 | } /* set_line_char */ | ||
3395 | |||
3396 | 3486 | ||
3397 | static int | 3487 | static int |
3398 | get_serial_info(struct cyclades_port * info, | 3488 | get_serial_info(struct cyclades_port *info, |
3399 | struct serial_struct __user * retinfo) | 3489 | struct serial_struct __user * retinfo) |
3400 | { | 3490 | { |
3401 | struct serial_struct tmp; | 3491 | struct serial_struct tmp; |
3402 | struct cyclades_card *cinfo = &cy_card[info->card]; | 3492 | struct cyclades_card *cinfo = &cy_card[info->card]; |
3403 | |||
3404 | if (!retinfo) | ||
3405 | return -EFAULT; | ||
3406 | memset(&tmp, 0, sizeof(tmp)); | ||
3407 | tmp.type = info->type; | ||
3408 | tmp.line = info->line; | ||
3409 | tmp.port = info->card * 0x100 + info->line - cinfo->first_line; | ||
3410 | tmp.irq = cinfo->irq; | ||
3411 | tmp.flags = info->flags; | ||
3412 | tmp.close_delay = info->close_delay; | ||
3413 | tmp.baud_base = info->baud; | ||
3414 | tmp.custom_divisor = info->custom_divisor; | ||
3415 | tmp.hub6 = 0; /*!!!*/ | ||
3416 | return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0; | ||
3417 | } /* get_serial_info */ | ||
3418 | 3493 | ||
3494 | if (!retinfo) | ||
3495 | return -EFAULT; | ||
3496 | memset(&tmp, 0, sizeof(tmp)); | ||
3497 | tmp.type = info->type; | ||
3498 | tmp.line = info->line; | ||
3499 | tmp.port = info->card * 0x100 + info->line - cinfo->first_line; | ||
3500 | tmp.irq = cinfo->irq; | ||
3501 | tmp.flags = info->flags; | ||
3502 | tmp.close_delay = info->close_delay; | ||
3503 | tmp.baud_base = info->baud; | ||
3504 | tmp.custom_divisor = info->custom_divisor; | ||
3505 | tmp.hub6 = 0; /*!!! */ | ||
3506 | return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; | ||
3507 | } /* get_serial_info */ | ||
3419 | 3508 | ||
3420 | static int | 3509 | static int |
3421 | set_serial_info(struct cyclades_port * info, | 3510 | set_serial_info(struct cyclades_port *info, |
3422 | struct serial_struct __user * new_info) | 3511 | struct serial_struct __user * new_info) |
3423 | { | 3512 | { |
3424 | struct serial_struct new_serial; | 3513 | struct serial_struct new_serial; |
3425 | struct cyclades_port old_info; | 3514 | struct cyclades_port old_info; |
3426 | 3515 | ||
3427 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 3516 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
3428 | return -EFAULT; | 3517 | return -EFAULT; |
3429 | old_info = *info; | 3518 | old_info = *info; |
3430 | 3519 | ||
3431 | if (!capable(CAP_SYS_ADMIN)) { | 3520 | if (!capable(CAP_SYS_ADMIN)) { |
3432 | if ((new_serial.close_delay != info->close_delay) || | 3521 | if (new_serial.close_delay != info->close_delay || |
3433 | (new_serial.baud_base != info->baud) || | 3522 | new_serial.baud_base != info->baud || |
3434 | ((new_serial.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK) != | 3523 | (new_serial.flags & ASYNC_FLAGS & |
3435 | (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))) | 3524 | ~ASYNC_USR_MASK) != |
3436 | return -EPERM; | 3525 | (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) |
3437 | info->flags = ((info->flags & ~ASYNC_USR_MASK) | | 3526 | return -EPERM; |
3438 | (new_serial.flags & ASYNC_USR_MASK)); | 3527 | info->flags = (info->flags & ~ASYNC_USR_MASK) | |
3439 | info->baud = new_serial.baud_base; | 3528 | (new_serial.flags & ASYNC_USR_MASK); |
3440 | info->custom_divisor = new_serial.custom_divisor; | 3529 | info->baud = new_serial.baud_base; |
3441 | goto check_and_exit; | 3530 | info->custom_divisor = new_serial.custom_divisor; |
3442 | } | 3531 | goto check_and_exit; |
3443 | 3532 | } | |
3444 | 3533 | ||
3445 | /* | 3534 | /* |
3446 | * OK, past this point, all the error checking has been done. | 3535 | * OK, past this point, all the error checking has been done. |
3447 | * At this point, we start making changes..... | 3536 | * At this point, we start making changes..... |
3448 | */ | 3537 | */ |
3449 | 3538 | ||
3450 | info->baud = new_serial.baud_base; | 3539 | info->baud = new_serial.baud_base; |
3451 | info->custom_divisor = new_serial.custom_divisor; | 3540 | info->custom_divisor = new_serial.custom_divisor; |
3452 | info->flags = ((info->flags & ~ASYNC_FLAGS) | | 3541 | info->flags = (info->flags & ~ASYNC_FLAGS) | |
3453 | (new_serial.flags & ASYNC_FLAGS)); | 3542 | (new_serial.flags & ASYNC_FLAGS); |
3454 | info->close_delay = new_serial.close_delay * HZ/100; | 3543 | info->close_delay = new_serial.close_delay * HZ / 100; |
3455 | info->closing_wait = new_serial.closing_wait * HZ/100; | 3544 | info->closing_wait = new_serial.closing_wait * HZ / 100; |
3456 | 3545 | ||
3457 | check_and_exit: | 3546 | check_and_exit: |
3458 | if (info->flags & ASYNC_INITIALIZED){ | 3547 | if (info->flags & ASYNC_INITIALIZED) { |
3459 | set_line_char(info); | 3548 | set_line_char(info); |
3460 | return 0; | 3549 | return 0; |
3461 | }else{ | 3550 | } else { |
3462 | return startup(info); | 3551 | return startup(info); |
3463 | } | 3552 | } |
3464 | } /* set_serial_info */ | 3553 | } /* set_serial_info */ |
3465 | 3554 | ||
3466 | /* | 3555 | /* |
3467 | * get_lsr_info - get line status register info | 3556 | * get_lsr_info - get line status register info |
@@ -3473,441 +3562,452 @@ check_and_exit: | |||
3473 | * transmit holding register is empty. This functionality | 3562 | * transmit holding register is empty. This functionality |
3474 | * allows an RS485 driver to be written in user space. | 3563 | * allows an RS485 driver to be written in user space. |
3475 | */ | 3564 | */ |
3476 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user *value) | 3565 | static int get_lsr_info(struct cyclades_port *info, unsigned int __user * value) |
3477 | { | 3566 | { |
3478 | int card, chip, channel, index; | 3567 | int card, chip, channel, index; |
3479 | unsigned char status; | 3568 | unsigned char status; |
3480 | unsigned int result; | 3569 | unsigned int result; |
3481 | unsigned long flags; | 3570 | unsigned long flags; |
3482 | void __iomem *base_addr; | 3571 | void __iomem *base_addr; |
3483 | |||
3484 | card = info->card; | ||
3485 | channel = (info->line) - (cy_card[card].first_line); | ||
3486 | if (!IS_CYC_Z(cy_card[card])) { | ||
3487 | chip = channel>>2; | ||
3488 | channel &= 0x03; | ||
3489 | index = cy_card[card].bus_index; | ||
3490 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
3491 | 3572 | ||
3492 | CY_LOCK(info, flags); | 3573 | card = info->card; |
3493 | status = cy_readb(base_addr+(CySRER<<index)) & (CyTxRdy|CyTxMpty); | 3574 | channel = (info->line) - (cy_card[card].first_line); |
3494 | CY_UNLOCK(info, flags); | 3575 | if (!IS_CYC_Z(cy_card[card])) { |
3495 | result = (status ? 0 : TIOCSER_TEMT); | 3576 | chip = channel >> 2; |
3496 | } else { | 3577 | channel &= 0x03; |
3497 | /* Not supported yet */ | 3578 | index = cy_card[card].bus_index; |
3498 | return -EINVAL; | 3579 | base_addr = |
3499 | } | 3580 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); |
3500 | return put_user(result, (unsigned long __user *) value); | 3581 | |
3582 | CY_LOCK(info, flags); | ||
3583 | status = cy_readb(base_addr + (CySRER << index)) & | ||
3584 | (CyTxRdy | CyTxMpty); | ||
3585 | CY_UNLOCK(info, flags); | ||
3586 | result = (status ? 0 : TIOCSER_TEMT); | ||
3587 | } else { | ||
3588 | /* Not supported yet */ | ||
3589 | return -EINVAL; | ||
3590 | } | ||
3591 | return put_user(result, (unsigned long __user *)value); | ||
3501 | } | 3592 | } |
3502 | 3593 | ||
3503 | static int | 3594 | static int cy_tiocmget(struct tty_struct *tty, struct file *file) |
3504 | cy_tiocmget(struct tty_struct *tty, struct file *file) | ||
3505 | { | 3595 | { |
3506 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 3596 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
3507 | int card,chip,channel,index; | 3597 | int card, chip, channel, index; |
3508 | void __iomem *base_addr; | 3598 | void __iomem *base_addr; |
3509 | unsigned long flags; | 3599 | unsigned long flags; |
3510 | unsigned char status; | 3600 | unsigned char status; |
3511 | unsigned long lstatus; | 3601 | unsigned long lstatus; |
3512 | unsigned int result; | 3602 | unsigned int result; |
3513 | struct FIRM_ID __iomem *firm_id; | 3603 | struct FIRM_ID __iomem *firm_id; |
3514 | struct ZFW_CTRL __iomem *zfw_ctrl; | 3604 | struct ZFW_CTRL __iomem *zfw_ctrl; |
3515 | struct BOARD_CTRL __iomem *board_ctrl; | 3605 | struct BOARD_CTRL __iomem *board_ctrl; |
3516 | struct CH_CTRL __iomem *ch_ctrl; | 3606 | struct CH_CTRL __iomem *ch_ctrl; |
3517 | 3607 | ||
3518 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) | 3608 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) |
3519 | return -ENODEV; | 3609 | return -ENODEV; |
3520 | |||
3521 | card = info->card; | ||
3522 | channel = (info->line) - (cy_card[card].first_line); | ||
3523 | if (!IS_CYC_Z(cy_card[card])) { | ||
3524 | chip = channel>>2; | ||
3525 | channel &= 0x03; | ||
3526 | index = cy_card[card].bus_index; | ||
3527 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
3528 | 3610 | ||
3529 | CY_LOCK(info, flags); | 3611 | card = info->card; |
3530 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 3612 | channel = (info->line) - (cy_card[card].first_line); |
3531 | status = cy_readb(base_addr+(CyMSVR1<<index)); | 3613 | if (!IS_CYC_Z(cy_card[card])) { |
3532 | status |= cy_readb(base_addr+(CyMSVR2<<index)); | 3614 | chip = channel >> 2; |
3533 | CY_UNLOCK(info, flags); | 3615 | channel &= 0x03; |
3616 | index = cy_card[card].bus_index; | ||
3617 | base_addr = | ||
3618 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3534 | 3619 | ||
3535 | if (info->rtsdtr_inv) { | 3620 | CY_LOCK(info, flags); |
3536 | result = ((status & CyRTS) ? TIOCM_DTR : 0) | 3621 | cy_writeb(base_addr + (CyCAR << index), (u_char) channel); |
3537 | | ((status & CyDTR) ? TIOCM_RTS : 0); | 3622 | status = cy_readb(base_addr + (CyMSVR1 << index)); |
3623 | status |= cy_readb(base_addr + (CyMSVR2 << index)); | ||
3624 | CY_UNLOCK(info, flags); | ||
3625 | |||
3626 | if (info->rtsdtr_inv) { | ||
3627 | result = ((status & CyRTS) ? TIOCM_DTR : 0) | | ||
3628 | ((status & CyDTR) ? TIOCM_RTS : 0); | ||
3629 | } else { | ||
3630 | result = ((status & CyRTS) ? TIOCM_RTS : 0) | | ||
3631 | ((status & CyDTR) ? TIOCM_DTR : 0); | ||
3632 | } | ||
3633 | result |= ((status & CyDCD) ? TIOCM_CAR : 0) | | ||
3634 | ((status & CyRI) ? TIOCM_RNG : 0) | | ||
3635 | ((status & CyDSR) ? TIOCM_DSR : 0) | | ||
3636 | ((status & CyCTS) ? TIOCM_CTS : 0); | ||
3538 | } else { | 3637 | } else { |
3539 | result = ((status & CyRTS) ? TIOCM_RTS : 0) | 3638 | base_addr = cy_card[card].base_addr; |
3540 | | ((status & CyDTR) ? TIOCM_DTR : 0); | ||
3541 | } | ||
3542 | result |= ((status & CyDCD) ? TIOCM_CAR : 0) | ||
3543 | | ((status & CyRI) ? TIOCM_RNG : 0) | ||
3544 | | ((status & CyDSR) ? TIOCM_DSR : 0) | ||
3545 | | ((status & CyCTS) ? TIOCM_CTS : 0); | ||
3546 | } else { | ||
3547 | base_addr = cy_card[card].base_addr; | ||
3548 | |||
3549 | if (cy_card[card].num_chips != -1){ | ||
3550 | return -EINVAL; | ||
3551 | } | ||
3552 | 3639 | ||
3553 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3640 | if (cy_card[card].num_chips != -1) { |
3554 | if (ISZLOADED(cy_card[card])) { | 3641 | return -EINVAL; |
3555 | zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3642 | } |
3556 | board_ctrl = &zfw_ctrl->board_ctrl; | ||
3557 | ch_ctrl = zfw_ctrl->ch_ctrl; | ||
3558 | lstatus = cy_readl(&ch_ctrl[channel].rs_status); | ||
3559 | result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | ||
3560 | | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | ||
3561 | | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | ||
3562 | | ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) | ||
3563 | | ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) | ||
3564 | | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); | ||
3565 | }else{ | ||
3566 | result = 0; | ||
3567 | return -ENODEV; | ||
3568 | } | ||
3569 | 3643 | ||
3570 | } | 3644 | firm_id = cy_card[card].base_addr + ID_ADDRESS; |
3571 | return result; | 3645 | if (ISZLOADED(cy_card[card])) { |
3572 | } /* cy_tiomget */ | 3646 | zfw_ctrl = cy_card[card].base_addr + |
3647 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | ||
3648 | board_ctrl = &zfw_ctrl->board_ctrl; | ||
3649 | ch_ctrl = zfw_ctrl->ch_ctrl; | ||
3650 | lstatus = cy_readl(&ch_ctrl[channel].rs_status); | ||
3651 | result = ((lstatus & C_RS_RTS) ? TIOCM_RTS : 0) | | ||
3652 | ((lstatus & C_RS_DTR) ? TIOCM_DTR : 0) | | ||
3653 | ((lstatus & C_RS_DCD) ? TIOCM_CAR : 0) | | ||
3654 | ((lstatus & C_RS_RI) ? TIOCM_RNG : 0) | | ||
3655 | ((lstatus & C_RS_DSR) ? TIOCM_DSR : 0) | | ||
3656 | ((lstatus & C_RS_CTS) ? TIOCM_CTS : 0); | ||
3657 | } else { | ||
3658 | result = 0; | ||
3659 | return -ENODEV; | ||
3660 | } | ||
3573 | 3661 | ||
3662 | } | ||
3663 | return result; | ||
3664 | } /* cy_tiomget */ | ||
3574 | 3665 | ||
3575 | static int | 3666 | static int |
3576 | cy_tiocmset(struct tty_struct *tty, struct file *file, | 3667 | cy_tiocmset(struct tty_struct *tty, struct file *file, |
3577 | unsigned int set, unsigned int clear) | 3668 | unsigned int set, unsigned int clear) |
3578 | { | 3669 | { |
3579 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 3670 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
3580 | int card,chip,channel,index; | 3671 | int card, chip, channel, index; |
3581 | void __iomem *base_addr; | 3672 | void __iomem *base_addr; |
3582 | unsigned long flags; | 3673 | unsigned long flags; |
3583 | struct FIRM_ID __iomem *firm_id; | 3674 | struct FIRM_ID __iomem *firm_id; |
3584 | struct ZFW_CTRL __iomem *zfw_ctrl; | 3675 | struct ZFW_CTRL __iomem *zfw_ctrl; |
3585 | struct BOARD_CTRL __iomem *board_ctrl; | 3676 | struct BOARD_CTRL __iomem *board_ctrl; |
3586 | struct CH_CTRL __iomem *ch_ctrl; | 3677 | struct CH_CTRL __iomem *ch_ctrl; |
3587 | int retval; | 3678 | int retval; |
3588 | 3679 | ||
3589 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) | 3680 | if (serial_paranoia_check(info, tty->name, __FUNCTION__)) |
3590 | return -ENODEV; | 3681 | return -ENODEV; |
3591 | 3682 | ||
3592 | card = info->card; | 3683 | card = info->card; |
3593 | channel = (info->line) - (cy_card[card].first_line); | 3684 | channel = (info->line) - (cy_card[card].first_line); |
3594 | if (!IS_CYC_Z(cy_card[card])) { | 3685 | if (!IS_CYC_Z(cy_card[card])) { |
3595 | chip = channel>>2; | 3686 | chip = channel >> 2; |
3596 | channel &= 0x03; | 3687 | channel &= 0x03; |
3597 | index = cy_card[card].bus_index; | 3688 | index = cy_card[card].bus_index; |
3598 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | 3689 | base_addr = |
3599 | 3690 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | |
3600 | if (set & TIOCM_RTS){ | 3691 | |
3601 | CY_LOCK(info, flags); | 3692 | if (set & TIOCM_RTS) { |
3602 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 3693 | CY_LOCK(info, flags); |
3603 | if (info->rtsdtr_inv) { | 3694 | cy_writeb(base_addr + (CyCAR << index), |
3604 | cy_writeb(base_addr+(CyMSVR2<<index), CyDTR); | 3695 | (u_char) channel); |
3605 | } else { | 3696 | if (info->rtsdtr_inv) { |
3606 | cy_writeb(base_addr+(CyMSVR1<<index), CyRTS); | 3697 | cy_writeb(base_addr + (CyMSVR2 << index), |
3607 | } | 3698 | CyDTR); |
3608 | CY_UNLOCK(info, flags); | 3699 | } else { |
3609 | } | 3700 | cy_writeb(base_addr + (CyMSVR1 << index), |
3610 | if (clear & TIOCM_RTS) { | 3701 | CyRTS); |
3611 | CY_LOCK(info, flags); | 3702 | } |
3612 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 3703 | CY_UNLOCK(info, flags); |
3613 | if (info->rtsdtr_inv) { | 3704 | } |
3614 | cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR); | 3705 | if (clear & TIOCM_RTS) { |
3615 | } else { | 3706 | CY_LOCK(info, flags); |
3616 | cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS); | 3707 | cy_writeb(base_addr + (CyCAR << index), |
3617 | } | 3708 | (u_char) channel); |
3618 | CY_UNLOCK(info, flags); | 3709 | if (info->rtsdtr_inv) { |
3619 | } | 3710 | cy_writeb(base_addr + (CyMSVR2 << index), |
3620 | if (set & TIOCM_DTR){ | 3711 | ~CyDTR); |
3621 | CY_LOCK(info, flags); | 3712 | } else { |
3622 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 3713 | cy_writeb(base_addr + (CyMSVR1 << index), |
3623 | if (info->rtsdtr_inv) { | 3714 | ~CyRTS); |
3624 | cy_writeb(base_addr+(CyMSVR1<<index), CyRTS); | 3715 | } |
3625 | } else { | 3716 | CY_UNLOCK(info, flags); |
3626 | cy_writeb(base_addr+(CyMSVR2<<index), CyDTR); | 3717 | } |
3627 | } | 3718 | if (set & TIOCM_DTR) { |
3719 | CY_LOCK(info, flags); | ||
3720 | cy_writeb(base_addr + (CyCAR << index), | ||
3721 | (u_char) channel); | ||
3722 | if (info->rtsdtr_inv) { | ||
3723 | cy_writeb(base_addr + (CyMSVR1 << index), | ||
3724 | CyRTS); | ||
3725 | } else { | ||
3726 | cy_writeb(base_addr + (CyMSVR2 << index), | ||
3727 | CyDTR); | ||
3728 | } | ||
3628 | #ifdef CY_DEBUG_DTR | 3729 | #ifdef CY_DEBUG_DTR |
3629 | printk("cyc:set_modem_info raising DTR\n"); | 3730 | printk("cyc:set_modem_info raising DTR\n"); |
3630 | printk(" status: 0x%x, 0x%x\n", | 3731 | printk(" status: 0x%x, 0x%x\n", |
3631 | cy_readb(base_addr+(CyMSVR1<<index)), | 3732 | cy_readb(base_addr + (CyMSVR1 << index)), |
3632 | cy_readb(base_addr+(CyMSVR2<<index))); | 3733 | cy_readb(base_addr + (CyMSVR2 << index))); |
3633 | #endif | 3734 | #endif |
3634 | CY_UNLOCK(info, flags); | 3735 | CY_UNLOCK(info, flags); |
3635 | } | 3736 | } |
3636 | if (clear & TIOCM_DTR) { | 3737 | if (clear & TIOCM_DTR) { |
3637 | CY_LOCK(info, flags); | 3738 | CY_LOCK(info, flags); |
3638 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | 3739 | cy_writeb(base_addr + (CyCAR << index), |
3639 | if (info->rtsdtr_inv) { | 3740 | (u_char) channel); |
3640 | cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS); | 3741 | if (info->rtsdtr_inv) { |
3641 | } else { | 3742 | cy_writeb(base_addr + (CyMSVR1 << index), |
3642 | cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR); | 3743 | ~CyRTS); |
3643 | } | 3744 | } else { |
3745 | cy_writeb(base_addr + (CyMSVR2 << index), | ||
3746 | ~CyDTR); | ||
3747 | } | ||
3644 | 3748 | ||
3645 | #ifdef CY_DEBUG_DTR | 3749 | #ifdef CY_DEBUG_DTR |
3646 | printk("cyc:set_modem_info dropping DTR\n"); | 3750 | printk("cyc:set_modem_info dropping DTR\n"); |
3647 | printk(" status: 0x%x, 0x%x\n", | 3751 | printk(" status: 0x%x, 0x%x\n", |
3648 | cy_readb(base_addr+(CyMSVR1<<index)), | 3752 | cy_readb(base_addr + (CyMSVR1 << index)), |
3649 | cy_readb(base_addr+(CyMSVR2<<index))); | 3753 | cy_readb(base_addr + (CyMSVR2 << index))); |
3650 | #endif | 3754 | #endif |
3651 | CY_UNLOCK(info, flags); | 3755 | CY_UNLOCK(info, flags); |
3652 | } | 3756 | } |
3653 | } else { | 3757 | } else { |
3654 | base_addr = cy_card[card].base_addr; | 3758 | base_addr = cy_card[card].base_addr; |
3655 | 3759 | ||
3656 | firm_id = cy_card[card].base_addr + ID_ADDRESS; | 3760 | firm_id = cy_card[card].base_addr + ID_ADDRESS; |
3657 | if (ISZLOADED(cy_card[card])) { | 3761 | if (ISZLOADED(cy_card[card])) { |
3658 | zfw_ctrl = cy_card[card].base_addr + (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3762 | zfw_ctrl = cy_card[card].base_addr + |
3659 | board_ctrl = &zfw_ctrl->board_ctrl; | 3763 | (cy_readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3660 | ch_ctrl = zfw_ctrl->ch_ctrl; | 3764 | board_ctrl = &zfw_ctrl->board_ctrl; |
3661 | 3765 | ch_ctrl = zfw_ctrl->ch_ctrl; | |
3662 | if (set & TIOCM_RTS){ | 3766 | |
3663 | CY_LOCK(info, flags); | 3767 | if (set & TIOCM_RTS) { |
3664 | cy_writel(&ch_ctrl[channel].rs_control, | 3768 | CY_LOCK(info, flags); |
3665 | cy_readl(&ch_ctrl[channel].rs_control) | C_RS_RTS); | 3769 | cy_writel(&ch_ctrl[channel].rs_control, |
3666 | CY_UNLOCK(info, flags); | 3770 | cy_readl(&ch_ctrl[channel]. |
3667 | } | 3771 | rs_control) | C_RS_RTS); |
3668 | if (clear & TIOCM_RTS) { | 3772 | CY_UNLOCK(info, flags); |
3669 | CY_LOCK(info, flags); | 3773 | } |
3670 | cy_writel(&ch_ctrl[channel].rs_control, | 3774 | if (clear & TIOCM_RTS) { |
3671 | cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_RTS); | 3775 | CY_LOCK(info, flags); |
3672 | CY_UNLOCK(info, flags); | 3776 | cy_writel(&ch_ctrl[channel].rs_control, |
3673 | } | 3777 | cy_readl(&ch_ctrl[channel]. |
3674 | if (set & TIOCM_DTR){ | 3778 | rs_control) & ~C_RS_RTS); |
3675 | CY_LOCK(info, flags); | 3779 | CY_UNLOCK(info, flags); |
3676 | cy_writel(&ch_ctrl[channel].rs_control, | 3780 | } |
3677 | cy_readl(&ch_ctrl[channel].rs_control) | C_RS_DTR); | 3781 | if (set & TIOCM_DTR) { |
3782 | CY_LOCK(info, flags); | ||
3783 | cy_writel(&ch_ctrl[channel].rs_control, | ||
3784 | cy_readl(&ch_ctrl[channel]. | ||
3785 | rs_control) | C_RS_DTR); | ||
3678 | #ifdef CY_DEBUG_DTR | 3786 | #ifdef CY_DEBUG_DTR |
3679 | printk("cyc:set_modem_info raising Z DTR\n"); | 3787 | printk("cyc:set_modem_info raising Z DTR\n"); |
3680 | #endif | 3788 | #endif |
3681 | CY_UNLOCK(info, flags); | 3789 | CY_UNLOCK(info, flags); |
3682 | } | 3790 | } |
3683 | if (clear & TIOCM_DTR) { | 3791 | if (clear & TIOCM_DTR) { |
3684 | CY_LOCK(info, flags); | 3792 | CY_LOCK(info, flags); |
3685 | cy_writel(&ch_ctrl[channel].rs_control, | 3793 | cy_writel(&ch_ctrl[channel].rs_control, |
3686 | cy_readl(&ch_ctrl[channel].rs_control) & ~C_RS_DTR); | 3794 | cy_readl(&ch_ctrl[channel]. |
3795 | rs_control) & ~C_RS_DTR); | ||
3687 | #ifdef CY_DEBUG_DTR | 3796 | #ifdef CY_DEBUG_DTR |
3688 | printk("cyc:set_modem_info clearing Z DTR\n"); | 3797 | printk("cyc:set_modem_info clearing Z DTR\n"); |
3689 | #endif | 3798 | #endif |
3690 | CY_UNLOCK(info, flags); | 3799 | CY_UNLOCK(info, flags); |
3691 | } | 3800 | } |
3692 | }else{ | 3801 | } else { |
3693 | return -ENODEV; | 3802 | return -ENODEV; |
3694 | } | 3803 | } |
3695 | CY_LOCK(info, flags); | 3804 | CY_LOCK(info, flags); |
3696 | retval = cyz_issue_cmd(&cy_card[info->card], | 3805 | retval = cyz_issue_cmd(&cy_card[info->card], |
3697 | channel, C_CM_IOCTLM,0L); | 3806 | channel, C_CM_IOCTLM, 0L); |
3698 | if (retval != 0){ | 3807 | if (retval != 0) { |
3699 | printk("cyc:set_modem_info retval on ttyC%d was %x\n", | 3808 | printk("cyc:set_modem_info retval on ttyC%d was %x\n", |
3700 | info->line, retval); | 3809 | info->line, retval); |
3810 | } | ||
3811 | CY_UNLOCK(info, flags); | ||
3701 | } | 3812 | } |
3702 | CY_UNLOCK(info, flags); | 3813 | return 0; |
3703 | } | 3814 | } /* cy_tiocmset */ |
3704 | return 0; | ||
3705 | } /* cy_tiocmset */ | ||
3706 | 3815 | ||
3707 | /* | 3816 | /* |
3708 | * cy_break() --- routine which turns the break handling on or off | 3817 | * cy_break() --- routine which turns the break handling on or off |
3709 | */ | 3818 | */ |
3710 | static void | 3819 | static void cy_break(struct tty_struct *tty, int break_state) |
3711 | cy_break(struct tty_struct *tty, int break_state) | ||
3712 | { | 3820 | { |
3713 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 3821 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
3714 | unsigned long flags; | 3822 | unsigned long flags; |
3715 | 3823 | ||
3716 | if (serial_paranoia_check(info, tty->name, "cy_break")) | 3824 | if (serial_paranoia_check(info, tty->name, "cy_break")) |
3717 | return; | 3825 | return; |
3718 | 3826 | ||
3719 | CY_LOCK(info, flags); | 3827 | CY_LOCK(info, flags); |
3720 | if (!IS_CYC_Z(cy_card[info->card])) { | 3828 | if (!IS_CYC_Z(cy_card[info->card])) { |
3721 | /* Let the transmit ISR take care of this (since it | 3829 | /* Let the transmit ISR take care of this (since it |
3722 | requires stuffing characters into the output stream). | 3830 | requires stuffing characters into the output stream). |
3723 | */ | 3831 | */ |
3724 | if (break_state == -1) { | 3832 | if (break_state == -1) { |
3725 | if (!info->breakon) { | 3833 | if (!info->breakon) { |
3726 | info->breakon = 1; | 3834 | info->breakon = 1; |
3727 | if (!info->xmit_cnt) { | 3835 | if (!info->xmit_cnt) { |
3728 | CY_UNLOCK(info, flags); | 3836 | CY_UNLOCK(info, flags); |
3729 | start_xmit(info); | 3837 | start_xmit(info); |
3730 | CY_LOCK(info, flags); | 3838 | CY_LOCK(info, flags); |
3839 | } | ||
3840 | } | ||
3841 | } else { | ||
3842 | if (!info->breakoff) { | ||
3843 | info->breakoff = 1; | ||
3844 | if (!info->xmit_cnt) { | ||
3845 | CY_UNLOCK(info, flags); | ||
3846 | start_xmit(info); | ||
3847 | CY_LOCK(info, flags); | ||
3848 | } | ||
3849 | } | ||
3731 | } | 3850 | } |
3732 | } | ||
3733 | } else { | 3851 | } else { |
3734 | if (!info->breakoff) { | 3852 | int retval; |
3735 | info->breakoff = 1; | 3853 | |
3736 | if (!info->xmit_cnt) { | 3854 | if (break_state == -1) { |
3737 | CY_UNLOCK(info, flags); | 3855 | retval = cyz_issue_cmd(&cy_card[info->card], |
3738 | start_xmit(info); | 3856 | info->line - cy_card[info->card].first_line, |
3739 | CY_LOCK(info, flags); | 3857 | C_CM_SET_BREAK, 0L); |
3858 | if (retval != 0) { | ||
3859 | printk("cyc:cy_break (set) retval on ttyC%d " | ||
3860 | "was %x\n", info->line, retval); | ||
3861 | } | ||
3862 | } else { | ||
3863 | retval = cyz_issue_cmd(&cy_card[info->card], | ||
3864 | info->line - cy_card[info->card].first_line, | ||
3865 | C_CM_CLR_BREAK, 0L); | ||
3866 | if (retval != 0) { | ||
3867 | printk("cyc:cy_break (clr) retval on ttyC%d " | ||
3868 | "was %x\n", info->line, retval); | ||
3869 | } | ||
3740 | } | 3870 | } |
3741 | } | ||
3742 | } | ||
3743 | } else { | ||
3744 | int retval; | ||
3745 | |||
3746 | if (break_state == -1) { | ||
3747 | retval = cyz_issue_cmd(&cy_card[info->card], | ||
3748 | (info->line) - (cy_card[info->card].first_line), | ||
3749 | C_CM_SET_BREAK, 0L); | ||
3750 | if (retval != 0) { | ||
3751 | printk("cyc:cy_break (set) retval on ttyC%d was %x\n", | ||
3752 | info->line, retval); | ||
3753 | } | ||
3754 | } else { | ||
3755 | retval = cyz_issue_cmd(&cy_card[info->card], | ||
3756 | (info->line) - (cy_card[info->card].first_line), | ||
3757 | C_CM_CLR_BREAK, 0L); | ||
3758 | if (retval != 0) { | ||
3759 | printk("cyc:cy_break (clr) retval on ttyC%d was %x\n", | ||
3760 | info->line, retval); | ||
3761 | } | ||
3762 | } | 3871 | } |
3763 | } | 3872 | CY_UNLOCK(info, flags); |
3764 | CY_UNLOCK(info, flags); | 3873 | } /* cy_break */ |
3765 | } /* cy_break */ | ||
3766 | 3874 | ||
3767 | static int | 3875 | static int |
3768 | get_mon_info(struct cyclades_port * info, struct cyclades_monitor __user * mon) | 3876 | get_mon_info(struct cyclades_port *info, struct cyclades_monitor __user * mon) |
3769 | { | 3877 | { |
3770 | 3878 | ||
3771 | if(copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) | 3879 | if (copy_to_user(mon, &info->mon, sizeof(struct cyclades_monitor))) |
3772 | return -EFAULT; | 3880 | return -EFAULT; |
3773 | info->mon.int_count = 0; | 3881 | info->mon.int_count = 0; |
3774 | info->mon.char_count = 0; | 3882 | info->mon.char_count = 0; |
3775 | info->mon.char_max = 0; | 3883 | info->mon.char_max = 0; |
3776 | info->mon.char_last = 0; | 3884 | info->mon.char_last = 0; |
3777 | return 0; | 3885 | return 0; |
3778 | }/* get_mon_info */ | 3886 | } /* get_mon_info */ |
3779 | |||
3780 | 3887 | ||
3781 | static int | 3888 | static int set_threshold(struct cyclades_port *info, unsigned long value) |
3782 | set_threshold(struct cyclades_port * info, unsigned long value) | ||
3783 | { | 3889 | { |
3784 | void __iomem *base_addr; | 3890 | void __iomem *base_addr; |
3785 | int card,channel,chip,index; | 3891 | int card, channel, chip, index; |
3786 | unsigned long flags; | 3892 | unsigned long flags; |
3787 | |||
3788 | card = info->card; | ||
3789 | channel = info->line - cy_card[card].first_line; | ||
3790 | if (!IS_CYC_Z(cy_card[card])) { | ||
3791 | chip = channel>>2; | ||
3792 | channel &= 0x03; | ||
3793 | index = cy_card[card].bus_index; | ||
3794 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
3795 | |||
3796 | info->cor3 &= ~CyREC_FIFO; | ||
3797 | info->cor3 |= value & CyREC_FIFO; | ||
3798 | 3893 | ||
3799 | CY_LOCK(info, flags); | 3894 | card = info->card; |
3800 | cy_writeb(base_addr+(CyCOR3<<index), info->cor3); | 3895 | channel = info->line - cy_card[card].first_line; |
3801 | cyy_issue_cmd(base_addr,CyCOR_CHANGE|CyCOR3ch,index); | 3896 | if (!IS_CYC_Z(cy_card[card])) { |
3802 | CY_UNLOCK(info, flags); | 3897 | chip = channel >> 2; |
3803 | } else { | 3898 | channel &= 0x03; |
3804 | // Nothing to do! | 3899 | index = cy_card[card].bus_index; |
3805 | } | 3900 | base_addr = |
3806 | return 0; | 3901 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); |
3807 | }/* set_threshold */ | ||
3808 | 3902 | ||
3903 | info->cor3 &= ~CyREC_FIFO; | ||
3904 | info->cor3 |= value & CyREC_FIFO; | ||
3809 | 3905 | ||
3810 | static int | 3906 | CY_LOCK(info, flags); |
3811 | get_threshold(struct cyclades_port * info, unsigned long __user *value) | 3907 | cy_writeb(base_addr + (CyCOR3 << index), info->cor3); |
3812 | { | 3908 | cyy_issue_cmd(base_addr, CyCOR_CHANGE | CyCOR3ch, index); |
3813 | void __iomem *base_addr; | 3909 | CY_UNLOCK(info, flags); |
3814 | int card,channel,chip,index; | 3910 | } else { |
3815 | unsigned long tmp; | 3911 | /* Nothing to do! */ |
3816 | 3912 | } | |
3817 | card = info->card; | ||
3818 | channel = info->line - cy_card[card].first_line; | ||
3819 | if (!IS_CYC_Z(cy_card[card])) { | ||
3820 | chip = channel>>2; | ||
3821 | channel &= 0x03; | ||
3822 | index = cy_card[card].bus_index; | ||
3823 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
3824 | |||
3825 | tmp = cy_readb(base_addr+(CyCOR3<<index)) & CyREC_FIFO; | ||
3826 | return put_user(tmp,value); | ||
3827 | } else { | ||
3828 | // Nothing to do! | ||
3829 | return 0; | 3913 | return 0; |
3830 | } | 3914 | } /* set_threshold */ |
3831 | }/* get_threshold */ | ||
3832 | |||
3833 | 3915 | ||
3834 | static int | 3916 | static int |
3835 | set_default_threshold(struct cyclades_port * info, unsigned long value) | 3917 | get_threshold(struct cyclades_port *info, unsigned long __user * value) |
3836 | { | 3918 | { |
3837 | info->default_threshold = value & 0x0f; | 3919 | void __iomem *base_addr; |
3838 | return 0; | 3920 | int card, channel, chip, index; |
3839 | }/* set_default_threshold */ | 3921 | unsigned long tmp; |
3840 | 3922 | ||
3923 | card = info->card; | ||
3924 | channel = info->line - cy_card[card].first_line; | ||
3925 | if (!IS_CYC_Z(cy_card[card])) { | ||
3926 | chip = channel >> 2; | ||
3927 | channel &= 0x03; | ||
3928 | index = cy_card[card].bus_index; | ||
3929 | base_addr = | ||
3930 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3931 | |||
3932 | tmp = cy_readb(base_addr + (CyCOR3 << index)) & CyREC_FIFO; | ||
3933 | return put_user(tmp, value); | ||
3934 | } else { | ||
3935 | /* Nothing to do! */ | ||
3936 | return 0; | ||
3937 | } | ||
3938 | } /* get_threshold */ | ||
3841 | 3939 | ||
3842 | static int | 3940 | static int |
3843 | get_default_threshold(struct cyclades_port * info, unsigned long __user *value) | 3941 | set_default_threshold(struct cyclades_port *info, unsigned long value) |
3844 | { | 3942 | { |
3845 | return put_user(info->default_threshold,value); | 3943 | info->default_threshold = value & 0x0f; |
3846 | }/* get_default_threshold */ | 3944 | return 0; |
3847 | 3945 | } /* set_default_threshold */ | |
3848 | 3946 | ||
3849 | static int | 3947 | static int |
3850 | set_timeout(struct cyclades_port * info, unsigned long value) | 3948 | get_default_threshold(struct cyclades_port *info, unsigned long __user * value) |
3851 | { | 3949 | { |
3852 | void __iomem *base_addr; | 3950 | return put_user(info->default_threshold, value); |
3853 | int card,channel,chip,index; | 3951 | } /* get_default_threshold */ |
3854 | unsigned long flags; | ||
3855 | |||
3856 | card = info->card; | ||
3857 | channel = info->line - cy_card[card].first_line; | ||
3858 | if (!IS_CYC_Z(cy_card[card])) { | ||
3859 | chip = channel>>2; | ||
3860 | channel &= 0x03; | ||
3861 | index = cy_card[card].bus_index; | ||
3862 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
3863 | 3952 | ||
3864 | CY_LOCK(info, flags); | 3953 | static int set_timeout(struct cyclades_port *info, unsigned long value) |
3865 | cy_writeb(base_addr+(CyRTPR<<index), value & 0xff); | 3954 | { |
3866 | CY_UNLOCK(info, flags); | 3955 | void __iomem *base_addr; |
3867 | } else { | 3956 | int card, channel, chip, index; |
3868 | // Nothing to do! | 3957 | unsigned long flags; |
3869 | } | ||
3870 | return 0; | ||
3871 | }/* set_timeout */ | ||
3872 | 3958 | ||
3959 | card = info->card; | ||
3960 | channel = info->line - cy_card[card].first_line; | ||
3961 | if (!IS_CYC_Z(cy_card[card])) { | ||
3962 | chip = channel >> 2; | ||
3963 | channel &= 0x03; | ||
3964 | index = cy_card[card].bus_index; | ||
3965 | base_addr = | ||
3966 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3873 | 3967 | ||
3874 | static int | 3968 | CY_LOCK(info, flags); |
3875 | get_timeout(struct cyclades_port * info, unsigned long __user *value) | 3969 | cy_writeb(base_addr + (CyRTPR << index), value & 0xff); |
3876 | { | 3970 | CY_UNLOCK(info, flags); |
3877 | void __iomem *base_addr; | 3971 | } else { |
3878 | int card,channel,chip,index; | 3972 | /* Nothing to do! */ |
3879 | unsigned long tmp; | 3973 | } |
3880 | |||
3881 | card = info->card; | ||
3882 | channel = info->line - cy_card[card].first_line; | ||
3883 | if (!IS_CYC_Z(cy_card[card])) { | ||
3884 | chip = channel>>2; | ||
3885 | channel &= 0x03; | ||
3886 | index = cy_card[card].bus_index; | ||
3887 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
3888 | |||
3889 | tmp = cy_readb(base_addr+(CyRTPR<<index)); | ||
3890 | return put_user(tmp,value); | ||
3891 | } else { | ||
3892 | // Nothing to do! | ||
3893 | return 0; | 3974 | return 0; |
3894 | } | 3975 | } /* set_timeout */ |
3895 | }/* get_timeout */ | ||
3896 | |||
3897 | 3976 | ||
3898 | static int | 3977 | static int get_timeout(struct cyclades_port *info, unsigned long __user * value) |
3899 | set_default_timeout(struct cyclades_port * info, unsigned long value) | ||
3900 | { | 3978 | { |
3901 | info->default_timeout = value & 0xff; | 3979 | void __iomem *base_addr; |
3902 | return 0; | 3980 | int card, channel, chip, index; |
3903 | }/* set_default_timeout */ | 3981 | unsigned long tmp; |
3904 | 3982 | ||
3983 | card = info->card; | ||
3984 | channel = info->line - cy_card[card].first_line; | ||
3985 | if (!IS_CYC_Z(cy_card[card])) { | ||
3986 | chip = channel >> 2; | ||
3987 | channel &= 0x03; | ||
3988 | index = cy_card[card].bus_index; | ||
3989 | base_addr = | ||
3990 | cy_card[card].base_addr + (cy_chip_offset[chip] << index); | ||
3991 | |||
3992 | tmp = cy_readb(base_addr + (CyRTPR << index)); | ||
3993 | return put_user(tmp, value); | ||
3994 | } else { | ||
3995 | /* Nothing to do! */ | ||
3996 | return 0; | ||
3997 | } | ||
3998 | } /* get_timeout */ | ||
3999 | |||
4000 | static int set_default_timeout(struct cyclades_port *info, unsigned long value) | ||
4001 | { | ||
4002 | info->default_timeout = value & 0xff; | ||
4003 | return 0; | ||
4004 | } /* set_default_timeout */ | ||
3905 | 4005 | ||
3906 | static int | 4006 | static int |
3907 | get_default_timeout(struct cyclades_port * info, unsigned long __user *value) | 4007 | get_default_timeout(struct cyclades_port *info, unsigned long __user * value) |
3908 | { | 4008 | { |
3909 | return put_user(info->default_timeout,value); | 4009 | return put_user(info->default_timeout, value); |
3910 | }/* get_default_timeout */ | 4010 | } /* get_default_timeout */ |
3911 | 4011 | ||
3912 | /* | 4012 | /* |
3913 | * This routine allows the tty driver to implement device- | 4013 | * This routine allows the tty driver to implement device- |
@@ -3915,184 +4015,193 @@ get_default_timeout(struct cyclades_port * info, unsigned long __user *value) | |||
3915 | * not recognized by the driver, it should return ENOIOCTLCMD. | 4015 | * not recognized by the driver, it should return ENOIOCTLCMD. |
3916 | */ | 4016 | */ |
3917 | static int | 4017 | static int |
3918 | cy_ioctl(struct tty_struct *tty, struct file * file, | 4018 | cy_ioctl(struct tty_struct *tty, struct file *file, |
3919 | unsigned int cmd, unsigned long arg) | 4019 | unsigned int cmd, unsigned long arg) |
3920 | { | 4020 | { |
3921 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 4021 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
3922 | struct cyclades_icount cprev, cnow; /* kernel counter temps */ | 4022 | struct cyclades_icount cprev, cnow; /* kernel counter temps */ |
3923 | struct serial_icounter_struct __user *p_cuser; /* user space */ | 4023 | struct serial_icounter_struct __user *p_cuser; /* user space */ |
3924 | int ret_val = 0; | 4024 | int ret_val = 0; |
3925 | unsigned long flags; | 4025 | unsigned long flags; |
3926 | void __user *argp = (void __user *)arg; | 4026 | void __user *argp = (void __user *)arg; |
3927 | 4027 | ||
3928 | if (serial_paranoia_check(info, tty->name, "cy_ioctl")) | 4028 | if (serial_paranoia_check(info, tty->name, "cy_ioctl")) |
3929 | return -ENODEV; | 4029 | return -ENODEV; |
3930 | 4030 | ||
3931 | #ifdef CY_DEBUG_OTHER | 4031 | #ifdef CY_DEBUG_OTHER |
3932 | printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", | 4032 | printk("cyc:cy_ioctl ttyC%d, cmd = %x arg = %lx\n", info->line, cmd, arg); /* */ |
3933 | info->line, cmd, arg); /* */ | ||
3934 | #endif | 4033 | #endif |
3935 | 4034 | ||
3936 | switch (cmd) { | 4035 | switch (cmd) { |
3937 | case CYGETMON: | 4036 | case CYGETMON: |
3938 | ret_val = get_mon_info(info, argp); | 4037 | ret_val = get_mon_info(info, argp); |
3939 | break; | 4038 | break; |
3940 | case CYGETTHRESH: | 4039 | case CYGETTHRESH: |
3941 | ret_val = get_threshold(info, argp); | 4040 | ret_val = get_threshold(info, argp); |
3942 | break; | 4041 | break; |
3943 | case CYSETTHRESH: | 4042 | case CYSETTHRESH: |
3944 | ret_val = set_threshold(info, arg); | 4043 | ret_val = set_threshold(info, arg); |
3945 | break; | 4044 | break; |
3946 | case CYGETDEFTHRESH: | 4045 | case CYGETDEFTHRESH: |
3947 | ret_val = get_default_threshold(info, argp); | 4046 | ret_val = get_default_threshold(info, argp); |
3948 | break; | 4047 | break; |
3949 | case CYSETDEFTHRESH: | 4048 | case CYSETDEFTHRESH: |
3950 | ret_val = set_default_threshold(info, arg); | 4049 | ret_val = set_default_threshold(info, arg); |
3951 | break; | 4050 | break; |
3952 | case CYGETTIMEOUT: | 4051 | case CYGETTIMEOUT: |
3953 | ret_val = get_timeout(info, argp); | 4052 | ret_val = get_timeout(info, argp); |
3954 | break; | 4053 | break; |
3955 | case CYSETTIMEOUT: | 4054 | case CYSETTIMEOUT: |
3956 | ret_val = set_timeout(info, arg); | 4055 | ret_val = set_timeout(info, arg); |
3957 | break; | 4056 | break; |
3958 | case CYGETDEFTIMEOUT: | 4057 | case CYGETDEFTIMEOUT: |
3959 | ret_val = get_default_timeout(info, argp); | 4058 | ret_val = get_default_timeout(info, argp); |
3960 | break; | 4059 | break; |
3961 | case CYSETDEFTIMEOUT: | 4060 | case CYSETDEFTIMEOUT: |
3962 | ret_val = set_default_timeout(info, arg); | 4061 | ret_val = set_default_timeout(info, arg); |
3963 | break; | 4062 | break; |
3964 | case CYSETRFLOW: | 4063 | case CYSETRFLOW: |
3965 | info->rflow = (int)arg; | 4064 | info->rflow = (int)arg; |
3966 | ret_val = 0; | 4065 | ret_val = 0; |
3967 | break; | 4066 | break; |
3968 | case CYGETRFLOW: | 4067 | case CYGETRFLOW: |
3969 | ret_val = info->rflow; | 4068 | ret_val = info->rflow; |
3970 | break; | 4069 | break; |
3971 | case CYSETRTSDTR_INV: | 4070 | case CYSETRTSDTR_INV: |
3972 | info->rtsdtr_inv = (int)arg; | 4071 | info->rtsdtr_inv = (int)arg; |
3973 | ret_val = 0; | 4072 | ret_val = 0; |
3974 | break; | 4073 | break; |
3975 | case CYGETRTSDTR_INV: | 4074 | case CYGETRTSDTR_INV: |
3976 | ret_val = info->rtsdtr_inv; | 4075 | ret_val = info->rtsdtr_inv; |
3977 | break; | 4076 | break; |
3978 | case CYGETCARDINFO: | 4077 | case CYGETCARDINFO: |
3979 | if (copy_to_user(argp, &cy_card[info->card], | 4078 | if (copy_to_user(argp, &cy_card[info->card], |
3980 | sizeof (struct cyclades_card))) { | 4079 | sizeof(struct cyclades_card))) { |
3981 | ret_val = -EFAULT; | 4080 | ret_val = -EFAULT; |
4081 | break; | ||
4082 | } | ||
4083 | ret_val = 0; | ||
3982 | break; | 4084 | break; |
3983 | } | ||
3984 | ret_val = 0; | ||
3985 | break; | ||
3986 | case CYGETCD1400VER: | 4085 | case CYGETCD1400VER: |
3987 | ret_val = info->chip_rev; | 4086 | ret_val = info->chip_rev; |
3988 | break; | 4087 | break; |
3989 | #ifndef CONFIG_CYZ_INTR | 4088 | #ifndef CONFIG_CYZ_INTR |
3990 | case CYZSETPOLLCYCLE: | 4089 | case CYZSETPOLLCYCLE: |
3991 | cyz_polling_cycle = (arg * HZ) / 1000; | 4090 | cyz_polling_cycle = (arg * HZ) / 1000; |
3992 | ret_val = 0; | 4091 | ret_val = 0; |
3993 | break; | 4092 | break; |
3994 | case CYZGETPOLLCYCLE: | 4093 | case CYZGETPOLLCYCLE: |
3995 | ret_val = (cyz_polling_cycle * 1000) / HZ; | 4094 | ret_val = (cyz_polling_cycle * 1000) / HZ; |
3996 | break; | 4095 | break; |
3997 | #endif /* CONFIG_CYZ_INTR */ | 4096 | #endif /* CONFIG_CYZ_INTR */ |
3998 | case CYSETWAIT: | 4097 | case CYSETWAIT: |
3999 | info->closing_wait = (unsigned short)arg * HZ/100; | 4098 | info->closing_wait = (unsigned short)arg *HZ / 100; |
4000 | ret_val = 0; | 4099 | ret_val = 0; |
4001 | break; | 4100 | break; |
4002 | case CYGETWAIT: | 4101 | case CYGETWAIT: |
4003 | ret_val = info->closing_wait / (HZ/100); | 4102 | ret_val = info->closing_wait / (HZ / 100); |
4004 | break; | 4103 | break; |
4005 | case TIOCGSERIAL: | 4104 | case TIOCGSERIAL: |
4006 | ret_val = get_serial_info(info, argp); | 4105 | ret_val = get_serial_info(info, argp); |
4007 | break; | 4106 | break; |
4008 | case TIOCSSERIAL: | 4107 | case TIOCSSERIAL: |
4009 | ret_val = set_serial_info(info, argp); | 4108 | ret_val = set_serial_info(info, argp); |
4010 | break; | 4109 | break; |
4011 | case TIOCSERGETLSR: /* Get line status register */ | 4110 | case TIOCSERGETLSR: /* Get line status register */ |
4012 | ret_val = get_lsr_info(info, argp); | 4111 | ret_val = get_lsr_info(info, argp); |
4013 | break; | 4112 | break; |
4014 | /* | 4113 | /* |
4015 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | 4114 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change |
4016 | * - mask passed in arg for lines of interest | 4115 | * - mask passed in arg for lines of interest |
4017 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | 4116 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) |
4018 | * Caller should use TIOCGICOUNT to see which one it was | 4117 | * Caller should use TIOCGICOUNT to see which one it was |
4019 | */ | 4118 | */ |
4020 | case TIOCMIWAIT: | 4119 | case TIOCMIWAIT: |
4021 | CY_LOCK(info, flags); | ||
4022 | /* note the counters on entry */ | ||
4023 | cprev = info->icount; | ||
4024 | CY_UNLOCK(info, flags); | ||
4025 | while (1) { | ||
4026 | interruptible_sleep_on(&info->delta_msr_wait); | ||
4027 | /* see if a signal did it */ | ||
4028 | if (signal_pending(current)) { | ||
4029 | return -ERESTARTSYS; | ||
4030 | } | ||
4031 | |||
4032 | CY_LOCK(info, flags); | 4120 | CY_LOCK(info, flags); |
4033 | cnow = info->icount; /* atomic copy */ | 4121 | /* note the counters on entry */ |
4122 | cprev = info->icount; | ||
4034 | CY_UNLOCK(info, flags); | 4123 | CY_UNLOCK(info, flags); |
4124 | while (1) { | ||
4125 | interruptible_sleep_on(&info->delta_msr_wait); | ||
4126 | /* see if a signal did it */ | ||
4127 | if (signal_pending(current)) { | ||
4128 | return -ERESTARTSYS; | ||
4129 | } | ||
4035 | 4130 | ||
4036 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && | 4131 | CY_LOCK(info, flags); |
4037 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { | 4132 | cnow = info->icount; /* atomic copy */ |
4038 | return -EIO; /* no change => error */ | 4133 | CY_UNLOCK(info, flags); |
4039 | } | ||
4040 | if ( ((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || | ||
4041 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || | ||
4042 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
4043 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)) ) { | ||
4044 | return 0; | ||
4045 | } | ||
4046 | cprev = cnow; | ||
4047 | } | ||
4048 | /* NOTREACHED */ | ||
4049 | 4134 | ||
4050 | /* | 4135 | if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && |
4051 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | 4136 | cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) { |
4052 | * Return: write counters to the user passed counter struct | 4137 | return -EIO; /* no change => error */ |
4053 | * NB: both 1->0 and 0->1 transitions are counted except for | 4138 | } |
4054 | * RI where only 0->1 is counted. | 4139 | if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) || |
4055 | */ | 4140 | ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) || |
4141 | ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) || | ||
4142 | ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) { | ||
4143 | return 0; | ||
4144 | } | ||
4145 | cprev = cnow; | ||
4146 | } | ||
4147 | /* NOTREACHED */ | ||
4148 | |||
4149 | /* | ||
4150 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
4151 | * Return: write counters to the user passed counter struct | ||
4152 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
4153 | * RI where only 0->1 is counted. | ||
4154 | */ | ||
4056 | case TIOCGICOUNT: | 4155 | case TIOCGICOUNT: |
4057 | CY_LOCK(info, flags); | 4156 | CY_LOCK(info, flags); |
4058 | cnow = info->icount; | 4157 | cnow = info->icount; |
4059 | CY_UNLOCK(info, flags); | 4158 | CY_UNLOCK(info, flags); |
4060 | p_cuser = argp; | 4159 | p_cuser = argp; |
4061 | ret_val = put_user(cnow.cts, &p_cuser->cts); | 4160 | ret_val = put_user(cnow.cts, &p_cuser->cts); |
4062 | if (ret_val) return ret_val; | 4161 | if (ret_val) |
4063 | ret_val = put_user(cnow.dsr, &p_cuser->dsr); | 4162 | return ret_val; |
4064 | if (ret_val) return ret_val; | 4163 | ret_val = put_user(cnow.dsr, &p_cuser->dsr); |
4065 | ret_val = put_user(cnow.rng, &p_cuser->rng); | 4164 | if (ret_val) |
4066 | if (ret_val) return ret_val; | 4165 | return ret_val; |
4067 | ret_val = put_user(cnow.dcd, &p_cuser->dcd); | 4166 | ret_val = put_user(cnow.rng, &p_cuser->rng); |
4068 | if (ret_val) return ret_val; | 4167 | if (ret_val) |
4069 | ret_val = put_user(cnow.rx, &p_cuser->rx); | 4168 | return ret_val; |
4070 | if (ret_val) return ret_val; | 4169 | ret_val = put_user(cnow.dcd, &p_cuser->dcd); |
4071 | ret_val = put_user(cnow.tx, &p_cuser->tx); | 4170 | if (ret_val) |
4072 | if (ret_val) return ret_val; | 4171 | return ret_val; |
4073 | ret_val = put_user(cnow.frame, &p_cuser->frame); | 4172 | ret_val = put_user(cnow.rx, &p_cuser->rx); |
4074 | if (ret_val) return ret_val; | 4173 | if (ret_val) |
4075 | ret_val = put_user(cnow.overrun, &p_cuser->overrun); | 4174 | return ret_val; |
4076 | if (ret_val) return ret_val; | 4175 | ret_val = put_user(cnow.tx, &p_cuser->tx); |
4077 | ret_val = put_user(cnow.parity, &p_cuser->parity); | 4176 | if (ret_val) |
4078 | if (ret_val) return ret_val; | 4177 | return ret_val; |
4079 | ret_val = put_user(cnow.brk, &p_cuser->brk); | 4178 | ret_val = put_user(cnow.frame, &p_cuser->frame); |
4080 | if (ret_val) return ret_val; | 4179 | if (ret_val) |
4081 | ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); | 4180 | return ret_val; |
4082 | if (ret_val) return ret_val; | 4181 | ret_val = put_user(cnow.overrun, &p_cuser->overrun); |
4083 | ret_val = 0; | 4182 | if (ret_val) |
4084 | break; | 4183 | return ret_val; |
4085 | default: | 4184 | ret_val = put_user(cnow.parity, &p_cuser->parity); |
4086 | ret_val = -ENOIOCTLCMD; | 4185 | if (ret_val) |
4087 | } | 4186 | return ret_val; |
4187 | ret_val = put_user(cnow.brk, &p_cuser->brk); | ||
4188 | if (ret_val) | ||
4189 | return ret_val; | ||
4190 | ret_val = put_user(cnow.buf_overrun, &p_cuser->buf_overrun); | ||
4191 | if (ret_val) | ||
4192 | return ret_val; | ||
4193 | ret_val = 0; | ||
4194 | break; | ||
4195 | default: | ||
4196 | ret_val = -ENOIOCTLCMD; | ||
4197 | } | ||
4088 | 4198 | ||
4089 | #ifdef CY_DEBUG_OTHER | 4199 | #ifdef CY_DEBUG_OTHER |
4090 | printk(" cyc:cy_ioctl done\n"); | 4200 | printk(" cyc:cy_ioctl done\n"); |
4091 | #endif | 4201 | #endif |
4092 | 4202 | ||
4093 | return ret_val; | 4203 | return ret_val; |
4094 | } /* cy_ioctl */ | 4204 | } /* cy_ioctl */ |
4095 | |||
4096 | 4205 | ||
4097 | /* | 4206 | /* |
4098 | * This routine allows the tty driver to be notified when | 4207 | * This routine allows the tty driver to be notified when |
@@ -4100,66 +4209,64 @@ cy_ioctl(struct tty_struct *tty, struct file * file, | |||
4100 | * well-designed tty driver should be prepared to accept the case | 4209 | * well-designed tty driver should be prepared to accept the case |
4101 | * where old == NULL, and try to do something rational. | 4210 | * where old == NULL, and try to do something rational. |
4102 | */ | 4211 | */ |
4103 | static void | 4212 | static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
4104 | cy_set_termios(struct tty_struct *tty, struct termios * old_termios) | ||
4105 | { | 4213 | { |
4106 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4214 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4107 | 4215 | ||
4108 | #ifdef CY_DEBUG_OTHER | 4216 | #ifdef CY_DEBUG_OTHER |
4109 | printk("cyc:cy_set_termios ttyC%d\n", info->line); | 4217 | printk("cyc:cy_set_termios ttyC%d\n", info->line); |
4110 | #endif | 4218 | #endif |
4111 | 4219 | ||
4112 | if ((tty->termios->c_cflag == old_termios->c_cflag) && | 4220 | if (tty->termios->c_cflag == old_termios->c_cflag && |
4113 | ((tty->termios->c_iflag & (IXON|IXANY)) == | 4221 | (tty->termios->c_iflag & (IXON | IXANY)) == |
4114 | (old_termios->c_iflag & (IXON|IXANY)))) | 4222 | (old_termios->c_iflag & (IXON | IXANY))) |
4115 | return; | 4223 | return; |
4116 | set_line_char(info); | 4224 | set_line_char(info); |
4117 | 4225 | ||
4118 | if ((old_termios->c_cflag & CRTSCTS) && | 4226 | if ((old_termios->c_cflag & CRTSCTS) && |
4119 | !(tty->termios->c_cflag & CRTSCTS)) { | 4227 | !(tty->termios->c_cflag & CRTSCTS)) { |
4120 | tty->hw_stopped = 0; | 4228 | tty->hw_stopped = 0; |
4121 | cy_start(tty); | 4229 | cy_start(tty); |
4122 | } | 4230 | } |
4123 | #if 0 | 4231 | #if 0 |
4124 | /* | 4232 | /* |
4125 | * No need to wake up processes in open wait, since they | 4233 | * No need to wake up processes in open wait, since they |
4126 | * sample the CLOCAL flag once, and don't recheck it. | 4234 | * sample the CLOCAL flag once, and don't recheck it. |
4127 | * XXX It's not clear whether the current behavior is correct | 4235 | * XXX It's not clear whether the current behavior is correct |
4128 | * or not. Hence, this may change..... | 4236 | * or not. Hence, this may change..... |
4129 | */ | 4237 | */ |
4130 | if (!(old_termios->c_cflag & CLOCAL) && | 4238 | if (!(old_termios->c_cflag & CLOCAL) && |
4131 | (tty->termios->c_cflag & CLOCAL)) | 4239 | (tty->termios->c_cflag & CLOCAL)) |
4132 | wake_up_interruptible(&info->open_wait); | 4240 | wake_up_interruptible(&info->open_wait); |
4133 | #endif | 4241 | #endif |
4134 | 4242 | } /* cy_set_termios */ | |
4135 | return; | ||
4136 | } /* cy_set_termios */ | ||
4137 | 4243 | ||
4138 | /* This function is used to send a high-priority XON/XOFF character to | 4244 | /* This function is used to send a high-priority XON/XOFF character to |
4139 | the device. | 4245 | the device. |
4140 | */ | 4246 | */ |
4141 | static void | 4247 | static void cy_send_xchar(struct tty_struct *tty, char ch) |
4142 | cy_send_xchar (struct tty_struct *tty, char ch) | ||
4143 | { | 4248 | { |
4144 | struct cyclades_port *info = (struct cyclades_port *) tty->driver_data; | 4249 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4145 | int card, channel; | 4250 | int card, channel; |
4146 | 4251 | ||
4147 | if (serial_paranoia_check (info, tty->name, "cy_send_xchar")) | 4252 | if (serial_paranoia_check(info, tty->name, "cy_send_xchar")) |
4148 | return; | 4253 | return; |
4149 | 4254 | ||
4150 | info->x_char = ch; | 4255 | info->x_char = ch; |
4151 | 4256 | ||
4152 | if (ch) | 4257 | if (ch) |
4153 | cy_start (tty); | 4258 | cy_start(tty); |
4154 | 4259 | ||
4155 | card = info->card; | 4260 | card = info->card; |
4156 | channel = info->line - cy_card[card].first_line; | 4261 | channel = info->line - cy_card[card].first_line; |
4157 | 4262 | ||
4158 | if (IS_CYC_Z (cy_card[card])) { | 4263 | if (IS_CYC_Z(cy_card[card])) { |
4159 | if (ch == STOP_CHAR (tty)) | 4264 | if (ch == STOP_CHAR(tty)) |
4160 | cyz_issue_cmd (&cy_card[card], channel, C_CM_SENDXOFF, 0L); | 4265 | cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXOFF, |
4161 | else if (ch == START_CHAR (tty)) | 4266 | 0L); |
4162 | cyz_issue_cmd (&cy_card[card], channel, C_CM_SENDXON, 0L); | 4267 | else if (ch == START_CHAR(tty)) |
4268 | cyz_issue_cmd(&cy_card[card], channel, C_CM_SENDXON, | ||
4269 | 0L); | ||
4163 | } | 4270 | } |
4164 | } | 4271 | } |
4165 | 4272 | ||
@@ -4167,260 +4274,248 @@ cy_send_xchar (struct tty_struct *tty, char ch) | |||
4167 | that incoming characters should be throttled because the input | 4274 | that incoming characters should be throttled because the input |
4168 | buffers are close to full. | 4275 | buffers are close to full. |
4169 | */ | 4276 | */ |
4170 | static void | 4277 | static void cy_throttle(struct tty_struct *tty) |
4171 | cy_throttle(struct tty_struct * tty) | ||
4172 | { | 4278 | { |
4173 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4279 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4174 | unsigned long flags; | 4280 | unsigned long flags; |
4175 | void __iomem *base_addr; | 4281 | void __iomem *base_addr; |
4176 | int card,chip,channel,index; | 4282 | int card, chip, channel, index; |
4177 | 4283 | ||
4178 | #ifdef CY_DEBUG_THROTTLE | 4284 | #ifdef CY_DEBUG_THROTTLE |
4179 | char buf[64]; | 4285 | char buf[64]; |
4180 | 4286 | ||
4181 | printk("cyc:throttle %s: %d....ttyC%d\n", | 4287 | printk("cyc:throttle %s: %d....ttyC%d\n", tty_name(tty, buf), |
4182 | tty_name(tty, buf), | 4288 | tty->ldisc.chars_in_buffer(tty), info->line); |
4183 | tty->ldisc.chars_in_buffer(tty), info->line); | ||
4184 | #endif | 4289 | #endif |
4185 | 4290 | ||
4186 | if (serial_paranoia_check(info, tty->name, "cy_throttle")){ | 4291 | if (serial_paranoia_check(info, tty->name, "cy_throttle")) { |
4187 | return; | 4292 | return; |
4188 | } | 4293 | } |
4189 | |||
4190 | card = info->card; | ||
4191 | |||
4192 | if (I_IXOFF(tty)) { | ||
4193 | if (!IS_CYC_Z (cy_card[card])) | ||
4194 | cy_send_xchar (tty, STOP_CHAR (tty)); | ||
4195 | else | ||
4196 | info->throttle = 1; | ||
4197 | } | ||
4198 | |||
4199 | if (tty->termios->c_cflag & CRTSCTS) { | ||
4200 | channel = info->line - cy_card[card].first_line; | ||
4201 | if (!IS_CYC_Z(cy_card[card])) { | ||
4202 | chip = channel>>2; | ||
4203 | channel &= 0x03; | ||
4204 | index = cy_card[card].bus_index; | ||
4205 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
4206 | |||
4207 | CY_LOCK(info, flags); | ||
4208 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | ||
4209 | if (info->rtsdtr_inv) { | ||
4210 | cy_writeb(base_addr+(CyMSVR2<<index), ~CyDTR); | ||
4211 | } else { | ||
4212 | cy_writeb(base_addr+(CyMSVR1<<index), ~CyRTS); | ||
4213 | } | ||
4214 | CY_UNLOCK(info, flags); | ||
4215 | } else { | ||
4216 | info->throttle = 1; | ||
4217 | } | ||
4218 | } | ||
4219 | 4294 | ||
4220 | return; | 4295 | card = info->card; |
4221 | } /* cy_throttle */ | 4296 | |
4297 | if (I_IXOFF(tty)) { | ||
4298 | if (!IS_CYC_Z(cy_card[card])) | ||
4299 | cy_send_xchar(tty, STOP_CHAR(tty)); | ||
4300 | else | ||
4301 | info->throttle = 1; | ||
4302 | } | ||
4222 | 4303 | ||
4304 | if (tty->termios->c_cflag & CRTSCTS) { | ||
4305 | channel = info->line - cy_card[card].first_line; | ||
4306 | if (!IS_CYC_Z(cy_card[card])) { | ||
4307 | chip = channel >> 2; | ||
4308 | channel &= 0x03; | ||
4309 | index = cy_card[card].bus_index; | ||
4310 | base_addr = cy_card[card].base_addr + | ||
4311 | (cy_chip_offset[chip] << index); | ||
4312 | |||
4313 | CY_LOCK(info, flags); | ||
4314 | cy_writeb(base_addr + (CyCAR << index), | ||
4315 | (u_char) channel); | ||
4316 | if (info->rtsdtr_inv) { | ||
4317 | cy_writeb(base_addr + (CyMSVR2 << index), | ||
4318 | ~CyDTR); | ||
4319 | } else { | ||
4320 | cy_writeb(base_addr + (CyMSVR1 << index), | ||
4321 | ~CyRTS); | ||
4322 | } | ||
4323 | CY_UNLOCK(info, flags); | ||
4324 | } else { | ||
4325 | info->throttle = 1; | ||
4326 | } | ||
4327 | } | ||
4328 | } /* cy_throttle */ | ||
4223 | 4329 | ||
4224 | /* | 4330 | /* |
4225 | * This routine notifies the tty driver that it should signal | 4331 | * This routine notifies the tty driver that it should signal |
4226 | * that characters can now be sent to the tty without fear of | 4332 | * that characters can now be sent to the tty without fear of |
4227 | * overrunning the input buffers of the line disciplines. | 4333 | * overrunning the input buffers of the line disciplines. |
4228 | */ | 4334 | */ |
4229 | static void | 4335 | static void cy_unthrottle(struct tty_struct *tty) |
4230 | cy_unthrottle(struct tty_struct * tty) | ||
4231 | { | 4336 | { |
4232 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4337 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4233 | unsigned long flags; | 4338 | unsigned long flags; |
4234 | void __iomem *base_addr; | 4339 | void __iomem *base_addr; |
4235 | int card,chip,channel,index; | 4340 | int card, chip, channel, index; |
4236 | 4341 | ||
4237 | #ifdef CY_DEBUG_THROTTLE | 4342 | #ifdef CY_DEBUG_THROTTLE |
4238 | char buf[64]; | 4343 | char buf[64]; |
4239 | |||
4240 | printk("cyc:unthrottle %s: %d....ttyC%d\n", | ||
4241 | tty_name(tty, buf), | ||
4242 | tty->ldisc.chars_in_buffer(tty), info->line); | ||
4243 | #endif | ||
4244 | 4344 | ||
4245 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")){ | 4345 | printk("cyc:unthrottle %s: %d....ttyC%d\n", tty_name(tty, buf), |
4246 | return; | 4346 | tty->ldisc.chars_in_buffer(tty), info->line); |
4247 | } | 4347 | #endif |
4248 | 4348 | ||
4249 | if (I_IXOFF(tty)) { | 4349 | if (serial_paranoia_check(info, tty->name, "cy_unthrottle")) { |
4250 | if (info->x_char) | 4350 | return; |
4251 | info->x_char = 0; | ||
4252 | else | ||
4253 | cy_send_xchar (tty, START_CHAR (tty)); | ||
4254 | } | ||
4255 | |||
4256 | if (tty->termios->c_cflag & CRTSCTS) { | ||
4257 | card = info->card; | ||
4258 | channel = info->line - cy_card[card].first_line; | ||
4259 | if (!IS_CYC_Z(cy_card[card])) { | ||
4260 | chip = channel>>2; | ||
4261 | channel &= 0x03; | ||
4262 | index = cy_card[card].bus_index; | ||
4263 | base_addr = cy_card[card].base_addr + (cy_chip_offset[chip]<<index); | ||
4264 | |||
4265 | CY_LOCK(info, flags); | ||
4266 | cy_writeb(base_addr+(CyCAR<<index), (u_char)channel); | ||
4267 | if (info->rtsdtr_inv) { | ||
4268 | cy_writeb(base_addr+(CyMSVR2<<index), CyDTR); | ||
4269 | } else { | ||
4270 | cy_writeb(base_addr+(CyMSVR1<<index), CyRTS); | ||
4271 | } | ||
4272 | CY_UNLOCK(info, flags); | ||
4273 | } else { | ||
4274 | info->throttle = 0; | ||
4275 | } | 4351 | } |
4276 | } | ||
4277 | 4352 | ||
4278 | return; | 4353 | if (I_IXOFF(tty)) { |
4279 | } /* cy_unthrottle */ | 4354 | if (info->x_char) |
4355 | info->x_char = 0; | ||
4356 | else | ||
4357 | cy_send_xchar(tty, START_CHAR(tty)); | ||
4358 | } | ||
4280 | 4359 | ||
4360 | if (tty->termios->c_cflag & CRTSCTS) { | ||
4361 | card = info->card; | ||
4362 | channel = info->line - cy_card[card].first_line; | ||
4363 | if (!IS_CYC_Z(cy_card[card])) { | ||
4364 | chip = channel >> 2; | ||
4365 | channel &= 0x03; | ||
4366 | index = cy_card[card].bus_index; | ||
4367 | base_addr = cy_card[card].base_addr + | ||
4368 | (cy_chip_offset[chip] << index); | ||
4369 | |||
4370 | CY_LOCK(info, flags); | ||
4371 | cy_writeb(base_addr + (CyCAR << index), | ||
4372 | (u_char) channel); | ||
4373 | if (info->rtsdtr_inv) { | ||
4374 | cy_writeb(base_addr + (CyMSVR2 << index), | ||
4375 | CyDTR); | ||
4376 | } else { | ||
4377 | cy_writeb(base_addr + (CyMSVR1 << index), | ||
4378 | CyRTS); | ||
4379 | } | ||
4380 | CY_UNLOCK(info, flags); | ||
4381 | } else { | ||
4382 | info->throttle = 0; | ||
4383 | } | ||
4384 | } | ||
4385 | } /* cy_unthrottle */ | ||
4281 | 4386 | ||
4282 | /* cy_start and cy_stop provide software output flow control as a | 4387 | /* cy_start and cy_stop provide software output flow control as a |
4283 | function of XON/XOFF, software CTS, and other such stuff. | 4388 | function of XON/XOFF, software CTS, and other such stuff. |
4284 | */ | 4389 | */ |
4285 | static void | 4390 | static void cy_stop(struct tty_struct *tty) |
4286 | cy_stop(struct tty_struct *tty) | ||
4287 | { | 4391 | { |
4288 | struct cyclades_card *cinfo; | 4392 | struct cyclades_card *cinfo; |
4289 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4393 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4290 | void __iomem *base_addr; | 4394 | void __iomem *base_addr; |
4291 | int chip,channel,index; | 4395 | int chip, channel, index; |
4292 | unsigned long flags; | 4396 | unsigned long flags; |
4293 | 4397 | ||
4294 | #ifdef CY_DEBUG_OTHER | 4398 | #ifdef CY_DEBUG_OTHER |
4295 | printk("cyc:cy_stop ttyC%d\n", info->line); /* */ | 4399 | printk("cyc:cy_stop ttyC%d\n", info->line); /* */ |
4296 | #endif | 4400 | #endif |
4297 | 4401 | ||
4298 | if (serial_paranoia_check(info, tty->name, "cy_stop")) | 4402 | if (serial_paranoia_check(info, tty->name, "cy_stop")) |
4299 | return; | 4403 | return; |
4300 | |||
4301 | cinfo = &cy_card[info->card]; | ||
4302 | channel = info->line - cinfo->first_line; | ||
4303 | if (!IS_CYC_Z(*cinfo)) { | ||
4304 | index = cinfo->bus_index; | ||
4305 | chip = channel>>2; | ||
4306 | channel &= 0x03; | ||
4307 | base_addr = cy_card[info->card].base_addr + (cy_chip_offset[chip]<<index); | ||
4308 | |||
4309 | CY_LOCK(info, flags); | ||
4310 | cy_writeb(base_addr+(CyCAR<<index), | ||
4311 | (u_char)(channel & 0x0003)); /* index channel */ | ||
4312 | cy_writeb(base_addr+(CySRER<<index), | ||
4313 | cy_readb(base_addr+(CySRER<<index)) & ~CyTxRdy); | ||
4314 | CY_UNLOCK(info, flags); | ||
4315 | } else { | ||
4316 | // Nothing to do! | ||
4317 | } | ||
4318 | 4404 | ||
4319 | return; | 4405 | cinfo = &cy_card[info->card]; |
4320 | } /* cy_stop */ | 4406 | channel = info->line - cinfo->first_line; |
4407 | if (!IS_CYC_Z(*cinfo)) { | ||
4408 | index = cinfo->bus_index; | ||
4409 | chip = channel >> 2; | ||
4410 | channel &= 0x03; | ||
4411 | base_addr = cy_card[info->card].base_addr + | ||
4412 | (cy_chip_offset[chip] << index); | ||
4321 | 4413 | ||
4414 | CY_LOCK(info, flags); | ||
4415 | cy_writeb(base_addr + (CyCAR << index), | ||
4416 | (u_char)(channel & 0x0003)); /* index channel */ | ||
4417 | cy_writeb(base_addr + (CySRER << index), | ||
4418 | cy_readb(base_addr + (CySRER << index)) & ~CyTxRdy); | ||
4419 | CY_UNLOCK(info, flags); | ||
4420 | } else { | ||
4421 | /* Nothing to do! */ | ||
4422 | } | ||
4423 | } /* cy_stop */ | ||
4322 | 4424 | ||
4323 | static void | 4425 | static void cy_start(struct tty_struct *tty) |
4324 | cy_start(struct tty_struct *tty) | ||
4325 | { | 4426 | { |
4326 | struct cyclades_card *cinfo; | 4427 | struct cyclades_card *cinfo; |
4327 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4428 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4328 | void __iomem *base_addr; | 4429 | void __iomem *base_addr; |
4329 | int chip,channel,index; | 4430 | int chip, channel, index; |
4330 | unsigned long flags; | 4431 | unsigned long flags; |
4331 | 4432 | ||
4332 | #ifdef CY_DEBUG_OTHER | 4433 | #ifdef CY_DEBUG_OTHER |
4333 | printk("cyc:cy_start ttyC%d\n", info->line); /* */ | 4434 | printk("cyc:cy_start ttyC%d\n", info->line); /* */ |
4334 | #endif | 4435 | #endif |
4335 | 4436 | ||
4336 | if (serial_paranoia_check(info, tty->name, "cy_start")) | 4437 | if (serial_paranoia_check(info, tty->name, "cy_start")) |
4337 | return; | 4438 | return; |
4338 | |||
4339 | cinfo = &cy_card[info->card]; | ||
4340 | channel = info->line - cinfo->first_line; | ||
4341 | index = cinfo->bus_index; | ||
4342 | if (!IS_CYC_Z(*cinfo)) { | ||
4343 | chip = channel>>2; | ||
4344 | channel &= 0x03; | ||
4345 | base_addr = cy_card[info->card].base_addr + (cy_chip_offset[chip]<<index); | ||
4346 | |||
4347 | CY_LOCK(info, flags); | ||
4348 | cy_writeb(base_addr+(CyCAR<<index), | ||
4349 | (u_char)(channel & 0x0003)); /* index channel */ | ||
4350 | cy_writeb(base_addr+(CySRER<<index), | ||
4351 | cy_readb(base_addr+(CySRER<<index)) | CyTxRdy); | ||
4352 | CY_UNLOCK(info, flags); | ||
4353 | } else { | ||
4354 | // Nothing to do! | ||
4355 | } | ||
4356 | 4439 | ||
4357 | return; | 4440 | cinfo = &cy_card[info->card]; |
4358 | } /* cy_start */ | 4441 | channel = info->line - cinfo->first_line; |
4442 | index = cinfo->bus_index; | ||
4443 | if (!IS_CYC_Z(*cinfo)) { | ||
4444 | chip = channel >> 2; | ||
4445 | channel &= 0x03; | ||
4446 | base_addr = cy_card[info->card].base_addr + | ||
4447 | (cy_chip_offset[chip] << index); | ||
4359 | 4448 | ||
4449 | CY_LOCK(info, flags); | ||
4450 | cy_writeb(base_addr + (CyCAR << index), (u_char) (channel & 0x0003)); /* index channel */ | ||
4451 | cy_writeb(base_addr + (CySRER << index), | ||
4452 | cy_readb(base_addr + (CySRER << index)) | CyTxRdy); | ||
4453 | CY_UNLOCK(info, flags); | ||
4454 | } else { | ||
4455 | /* Nothing to do! */ | ||
4456 | } | ||
4457 | } /* cy_start */ | ||
4360 | 4458 | ||
4361 | static void | 4459 | static void cy_flush_buffer(struct tty_struct *tty) |
4362 | cy_flush_buffer(struct tty_struct *tty) | ||
4363 | { | 4460 | { |
4364 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 4461 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4365 | int card, channel, retval; | 4462 | int card, channel, retval; |
4366 | unsigned long flags; | 4463 | unsigned long flags; |
4367 | 4464 | ||
4368 | #ifdef CY_DEBUG_IO | 4465 | #ifdef CY_DEBUG_IO |
4369 | printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */ | 4466 | printk("cyc:cy_flush_buffer ttyC%d\n", info->line); /* */ |
4370 | #endif | 4467 | #endif |
4371 | 4468 | ||
4372 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) | 4469 | if (serial_paranoia_check(info, tty->name, "cy_flush_buffer")) |
4373 | return; | 4470 | return; |
4374 | |||
4375 | card = info->card; | ||
4376 | channel = (info->line) - (cy_card[card].first_line); | ||
4377 | 4471 | ||
4378 | CY_LOCK(info, flags); | 4472 | card = info->card; |
4379 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | 4473 | channel = (info->line) - (cy_card[card].first_line); |
4380 | CY_UNLOCK(info, flags); | ||
4381 | 4474 | ||
4382 | if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board | ||
4383 | buffers as well */ | ||
4384 | CY_LOCK(info, flags); | 4475 | CY_LOCK(info, flags); |
4385 | retval = cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L); | 4476 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; |
4386 | if (retval != 0) { | ||
4387 | printk("cyc: flush_buffer retval on ttyC%d was %x\n", | ||
4388 | info->line, retval); | ||
4389 | } | ||
4390 | CY_UNLOCK(info, flags); | 4477 | CY_UNLOCK(info, flags); |
4391 | } | ||
4392 | tty_wakeup(tty); | ||
4393 | wake_up_interruptible(&tty->write_wait); | ||
4394 | } /* cy_flush_buffer */ | ||
4395 | 4478 | ||
4479 | if (IS_CYC_Z(cy_card[card])) { /* If it is a Z card, flush the on-board | ||
4480 | buffers as well */ | ||
4481 | CY_LOCK(info, flags); | ||
4482 | retval = | ||
4483 | cyz_issue_cmd(&cy_card[card], channel, C_CM_FLUSH_TX, 0L); | ||
4484 | if (retval != 0) { | ||
4485 | printk("cyc: flush_buffer retval on ttyC%d was %x\n", | ||
4486 | info->line, retval); | ||
4487 | } | ||
4488 | CY_UNLOCK(info, flags); | ||
4489 | } | ||
4490 | tty_wakeup(tty); | ||
4491 | wake_up_interruptible(&tty->write_wait); | ||
4492 | } /* cy_flush_buffer */ | ||
4396 | 4493 | ||
4397 | /* | 4494 | /* |
4398 | * cy_hangup() --- called by tty_hangup() when a hangup is signaled. | 4495 | * cy_hangup() --- called by tty_hangup() when a hangup is signaled. |
4399 | */ | 4496 | */ |
4400 | static void | 4497 | static void cy_hangup(struct tty_struct *tty) |
4401 | cy_hangup(struct tty_struct *tty) | ||
4402 | { | 4498 | { |
4403 | struct cyclades_port * info = (struct cyclades_port *)tty->driver_data; | 4499 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
4404 | 4500 | ||
4405 | #ifdef CY_DEBUG_OTHER | 4501 | #ifdef CY_DEBUG_OTHER |
4406 | printk("cyc:cy_hangup ttyC%d\n", info->line); /* */ | 4502 | printk("cyc:cy_hangup ttyC%d\n", info->line); /* */ |
4407 | #endif | 4503 | #endif |
4408 | 4504 | ||
4409 | if (serial_paranoia_check(info, tty->name, "cy_hangup")) | 4505 | if (serial_paranoia_check(info, tty->name, "cy_hangup")) |
4410 | return; | 4506 | return; |
4411 | 4507 | ||
4412 | cy_flush_buffer(tty); | 4508 | cy_flush_buffer(tty); |
4413 | shutdown(info); | 4509 | shutdown(info); |
4414 | info->event = 0; | 4510 | info->event = 0; |
4415 | info->count = 0; | 4511 | info->count = 0; |
4416 | #ifdef CY_DEBUG_COUNT | 4512 | #ifdef CY_DEBUG_COUNT |
4417 | printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid); | 4513 | printk("cyc:cy_hangup (%d): setting count to 0\n", current->pid); |
4418 | #endif | 4514 | #endif |
4419 | info->tty = NULL; | 4515 | info->tty = NULL; |
4420 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | 4516 | info->flags &= ~ASYNC_NORMAL_ACTIVE; |
4421 | wake_up_interruptible(&info->open_wait); | 4517 | wake_up_interruptible(&info->open_wait); |
4422 | } /* cy_hangup */ | 4518 | } /* cy_hangup */ |
4423 | |||
4424 | 4519 | ||
4425 | /* | 4520 | /* |
4426 | * --------------------------------------------------------------------- | 4521 | * --------------------------------------------------------------------- |
@@ -4433,82 +4528,84 @@ cy_hangup(struct tty_struct *tty) | |||
4433 | /* initialize chips on Cyclom-Y card -- return number of valid | 4528 | /* initialize chips on Cyclom-Y card -- return number of valid |
4434 | chips (which is number of ports/4) */ | 4529 | chips (which is number of ports/4) */ |
4435 | static unsigned short __init | 4530 | static unsigned short __init |
4436 | cyy_init_card(void __iomem *true_base_addr,int index) | 4531 | cyy_init_card(void __iomem * true_base_addr, int index) |
4437 | { | 4532 | { |
4438 | unsigned int chip_number; | 4533 | unsigned int chip_number; |
4439 | void __iomem *base_addr; | 4534 | void __iomem *base_addr; |
4440 | 4535 | ||
4441 | cy_writeb(true_base_addr+(Cy_HwReset<<index), 0); | 4536 | cy_writeb(true_base_addr + (Cy_HwReset << index), 0); |
4442 | /* Cy_HwReset is 0x1400 */ | 4537 | /* Cy_HwReset is 0x1400 */ |
4443 | cy_writeb(true_base_addr+(Cy_ClrIntr<<index), 0); | 4538 | cy_writeb(true_base_addr + (Cy_ClrIntr << index), 0); |
4444 | /* Cy_ClrIntr is 0x1800 */ | 4539 | /* Cy_ClrIntr is 0x1800 */ |
4445 | udelay(500L); | 4540 | udelay(500L); |
4446 | 4541 | ||
4447 | for(chip_number=0; chip_number<CyMAX_CHIPS_PER_CARD; chip_number++){ | 4542 | for (chip_number = 0; chip_number < CyMAX_CHIPS_PER_CARD; chip_number++) { |
4448 | base_addr = true_base_addr + (cy_chip_offset[chip_number]<<index); | 4543 | base_addr = |
4449 | mdelay(1); | 4544 | true_base_addr + (cy_chip_offset[chip_number] << index); |
4450 | if(cy_readb(base_addr+(CyCCR<<index)) != 0x00){ | 4545 | mdelay(1); |
4451 | /************* | 4546 | if (cy_readb(base_addr + (CyCCR << index)) != 0x00) { |
4452 | printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", | 4547 | /************* |
4453 | chip_number, (unsigned long)base_addr); | 4548 | printk(" chip #%d at %#6lx is never idle (CCR != 0)\n", |
4454 | *************/ | 4549 | chip_number, (unsigned long)base_addr); |
4455 | return chip_number; | 4550 | *************/ |
4456 | } | 4551 | return chip_number; |
4457 | 4552 | } | |
4458 | cy_writeb(base_addr+(CyGFRCR<<index), 0); | 4553 | |
4459 | udelay(10L); | 4554 | cy_writeb(base_addr + (CyGFRCR << index), 0); |
4460 | 4555 | udelay(10L); | |
4461 | /* The Cyclom-16Y does not decode address bit 9 and therefore | 4556 | |
4462 | cannot distinguish between references to chip 0 and a non- | 4557 | /* The Cyclom-16Y does not decode address bit 9 and therefore |
4463 | existent chip 4. If the preceding clearing of the supposed | 4558 | cannot distinguish between references to chip 0 and a non- |
4464 | chip 4 GFRCR register appears at chip 0, there is no chip 4 | 4559 | existent chip 4. If the preceding clearing of the supposed |
4465 | and this must be a Cyclom-16Y, not a Cyclom-32Ye. | 4560 | chip 4 GFRCR register appears at chip 0, there is no chip 4 |
4466 | */ | 4561 | and this must be a Cyclom-16Y, not a Cyclom-32Ye. |
4467 | if (chip_number == 4 | 4562 | */ |
4468 | && cy_readb(true_base_addr | 4563 | if (chip_number == 4 && cy_readb(true_base_addr + |
4469 | + (cy_chip_offset[0]<<index) | 4564 | (cy_chip_offset[0] << index) + |
4470 | + (CyGFRCR<<index)) == 0){ | 4565 | (CyGFRCR << index)) == 0) { |
4471 | return chip_number; | 4566 | return chip_number; |
4472 | } | 4567 | } |
4473 | 4568 | ||
4474 | cy_writeb(base_addr+(CyCCR<<index), CyCHIP_RESET); | 4569 | cy_writeb(base_addr + (CyCCR << index), CyCHIP_RESET); |
4475 | mdelay(1); | 4570 | mdelay(1); |
4476 | 4571 | ||
4477 | if(cy_readb(base_addr+(CyGFRCR<<index)) == 0x00){ | 4572 | if (cy_readb(base_addr + (CyGFRCR << index)) == 0x00) { |
4478 | /* | 4573 | /* |
4479 | printk(" chip #%d at %#6lx is not responding ", | 4574 | printk(" chip #%d at %#6lx is not responding ", |
4480 | chip_number, (unsigned long)base_addr); | 4575 | chip_number, (unsigned long)base_addr); |
4481 | printk("(GFRCR stayed 0)\n", | 4576 | printk("(GFRCR stayed 0)\n", |
4482 | */ | 4577 | */ |
4483 | return chip_number; | 4578 | return chip_number; |
4484 | } | 4579 | } |
4485 | if((0xf0 & (cy_readb(base_addr+(CyGFRCR<<index)))) != 0x40){ | 4580 | if ((0xf0 & (cy_readb(base_addr + (CyGFRCR << index)))) != |
4486 | /* | 4581 | 0x40) { |
4487 | printk(" chip #%d at %#6lx is not valid (GFRCR == %#2x)\n", | 4582 | /* |
4488 | chip_number, (unsigned long)base_addr, | 4583 | printk(" chip #%d at %#6lx is not valid (GFRCR == " |
4489 | base_addr[CyGFRCR<<index]); | 4584 | "%#2x)\n", |
4490 | */ | 4585 | chip_number, (unsigned long)base_addr, |
4491 | return chip_number; | 4586 | base_addr[CyGFRCR<<index]); |
4492 | } | 4587 | */ |
4493 | cy_writeb(base_addr+(CyGCR<<index), CyCH0_SERIAL); | 4588 | return chip_number; |
4494 | if (cy_readb(base_addr+(CyGFRCR<<index)) >= CD1400_REV_J){ | 4589 | } |
4495 | /* It is a CD1400 rev. J or later */ | 4590 | cy_writeb(base_addr + (CyGCR << index), CyCH0_SERIAL); |
4496 | /* Impossible to reach 5ms with this chip. | 4591 | if (cy_readb(base_addr + (CyGFRCR << index)) >= CD1400_REV_J) { |
4497 | Changed to 2ms instead (f = 500 Hz). */ | 4592 | /* It is a CD1400 rev. J or later */ |
4498 | cy_writeb(base_addr+(CyPPR<<index), CyCLOCK_60_2MS); | 4593 | /* Impossible to reach 5ms with this chip. |
4499 | } else { | 4594 | Changed to 2ms instead (f = 500 Hz). */ |
4500 | /* f = 200 Hz */ | 4595 | cy_writeb(base_addr + (CyPPR << index), CyCLOCK_60_2MS); |
4501 | cy_writeb(base_addr+(CyPPR<<index), CyCLOCK_25_5MS); | 4596 | } else { |
4502 | } | 4597 | /* f = 200 Hz */ |
4598 | cy_writeb(base_addr + (CyPPR << index), CyCLOCK_25_5MS); | ||
4599 | } | ||
4503 | 4600 | ||
4504 | /* | 4601 | /* |
4505 | printk(" chip #%d at %#6lx is rev 0x%2x\n", | 4602 | printk(" chip #%d at %#6lx is rev 0x%2x\n", |
4506 | chip_number, (unsigned long)base_addr, | 4603 | chip_number, (unsigned long)base_addr, |
4507 | cy_readb(base_addr+(CyGFRCR<<index))); | 4604 | cy_readb(base_addr+(CyGFRCR<<index))); |
4508 | */ | 4605 | */ |
4509 | } | 4606 | } |
4510 | return chip_number; | 4607 | return chip_number; |
4511 | } /* cyy_init_card */ | 4608 | } /* cyy_init_card */ |
4512 | 4609 | ||
4513 | /* | 4610 | /* |
4514 | * --------------------------------------------------------------------- | 4611 | * --------------------------------------------------------------------- |
@@ -4516,126 +4613,124 @@ cyy_init_card(void __iomem *true_base_addr,int index) | |||
4516 | * sets global variables and return the number of ISA boards found. | 4613 | * sets global variables and return the number of ISA boards found. |
4517 | * --------------------------------------------------------------------- | 4614 | * --------------------------------------------------------------------- |
4518 | */ | 4615 | */ |
4519 | static int __init | 4616 | static int __init cy_detect_isa(void) |
4520 | cy_detect_isa(void) | ||
4521 | { | 4617 | { |
4522 | #ifdef CONFIG_ISA | 4618 | #ifdef CONFIG_ISA |
4523 | unsigned short cy_isa_irq,nboard; | 4619 | unsigned short cy_isa_irq, nboard; |
4524 | void __iomem *cy_isa_address; | 4620 | void __iomem *cy_isa_address; |
4525 | unsigned short i,j,cy_isa_nchan; | 4621 | unsigned short i, j, cy_isa_nchan; |
4526 | #ifdef MODULE | 4622 | #ifdef MODULE |
4527 | int isparam = 0; | 4623 | int isparam = 0; |
4528 | #endif | 4624 | #endif |
4529 | 4625 | ||
4530 | nboard = 0; | 4626 | nboard = 0; |
4531 | 4627 | ||
4532 | #ifdef MODULE | 4628 | #ifdef MODULE |
4533 | /* Check for module parameters */ | 4629 | /* Check for module parameters */ |
4534 | for(i = 0 ; i < NR_CARDS; i++) { | 4630 | for (i = 0; i < NR_CARDS; i++) { |
4535 | if (maddr[i] || i) { | 4631 | if (maddr[i] || i) { |
4536 | isparam = 1; | 4632 | isparam = 1; |
4537 | cy_isa_addresses[i] = maddr[i]; | 4633 | cy_isa_addresses[i] = maddr[i]; |
4538 | } | 4634 | } |
4539 | if (!maddr[i]) | 4635 | if (!maddr[i]) |
4540 | break; | 4636 | break; |
4541 | } | 4637 | } |
4542 | #endif | 4638 | #endif |
4543 | 4639 | ||
4544 | /* scan the address table probing for Cyclom-Y/ISA boards */ | 4640 | /* scan the address table probing for Cyclom-Y/ISA boards */ |
4545 | for (i = 0 ; i < NR_ISA_ADDRS ; i++) { | 4641 | for (i = 0; i < NR_ISA_ADDRS; i++) { |
4546 | unsigned int isa_address = cy_isa_addresses[i]; | 4642 | unsigned int isa_address = cy_isa_addresses[i]; |
4547 | if (isa_address == 0x0000) { | 4643 | if (isa_address == 0x0000) { |
4548 | return(nboard); | 4644 | return nboard; |
4549 | } | 4645 | } |
4550 | 4646 | ||
4551 | /* probe for CD1400... */ | 4647 | /* probe for CD1400... */ |
4552 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); | 4648 | cy_isa_address = ioremap(isa_address, CyISA_Ywin); |
4553 | cy_isa_nchan = CyPORTS_PER_CHIP * | 4649 | cy_isa_nchan = CyPORTS_PER_CHIP * |
4554 | cyy_init_card(cy_isa_address,0); | 4650 | cyy_init_card(cy_isa_address, 0); |
4555 | if (cy_isa_nchan == 0) { | 4651 | if (cy_isa_nchan == 0) { |
4556 | continue; | 4652 | continue; |
4557 | } | 4653 | } |
4558 | |||
4559 | #ifdef MODULE | 4654 | #ifdef MODULE |
4560 | if (isparam && irq[i]) | 4655 | if (isparam && irq[i]) |
4561 | cy_isa_irq = irq[i]; | 4656 | cy_isa_irq = irq[i]; |
4562 | else | 4657 | else |
4563 | #endif | 4658 | #endif |
4564 | /* find out the board's irq by probing */ | 4659 | /* find out the board's irq by probing */ |
4565 | cy_isa_irq = detect_isa_irq(cy_isa_address); | 4660 | cy_isa_irq = detect_isa_irq(cy_isa_address); |
4566 | if (cy_isa_irq == 0) { | 4661 | if (cy_isa_irq == 0) { |
4567 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4662 | printk("Cyclom-Y/ISA found at 0x%lx ", |
4568 | (unsigned long) cy_isa_address); | 4663 | (unsigned long)cy_isa_address); |
4569 | printk("but the IRQ could not be detected.\n"); | 4664 | printk("but the IRQ could not be detected.\n"); |
4570 | continue; | 4665 | continue; |
4571 | } | 4666 | } |
4572 | 4667 | ||
4573 | if((cy_next_channel+cy_isa_nchan) > NR_PORTS) { | 4668 | if ((cy_next_channel + cy_isa_nchan) > NR_PORTS) { |
4574 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4669 | printk("Cyclom-Y/ISA found at 0x%lx ", |
4575 | (unsigned long) cy_isa_address); | 4670 | (unsigned long)cy_isa_address); |
4576 | printk("but no more channels are available.\n"); | 4671 | printk("but no more channels are available.\n"); |
4577 | printk("Change NR_PORTS in cyclades.c and recompile kernel.\n"); | 4672 | printk("Change NR_PORTS in cyclades.c and recompile " |
4578 | return(nboard); | 4673 | "kernel.\n"); |
4579 | } | 4674 | return nboard; |
4580 | /* fill the next cy_card structure available */ | 4675 | } |
4581 | for (j = 0 ; j < NR_CARDS ; j++) { | 4676 | /* fill the next cy_card structure available */ |
4582 | if (cy_card[j].base_addr == 0) break; | 4677 | for (j = 0; j < NR_CARDS; j++) { |
4583 | } | 4678 | if (cy_card[j].base_addr == 0) |
4584 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4679 | break; |
4585 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4680 | } |
4586 | (unsigned long) cy_isa_address); | 4681 | if (j == NR_CARDS) { /* no more cy_cards available */ |
4587 | printk("but no more cards can be used .\n"); | 4682 | printk("Cyclom-Y/ISA found at 0x%lx ", |
4588 | printk("Change NR_CARDS in cyclades.c and recompile kernel.\n"); | 4683 | (unsigned long)cy_isa_address); |
4589 | return(nboard); | 4684 | printk("but no more cards can be used .\n"); |
4590 | } | 4685 | printk("Change NR_CARDS in cyclades.c and recompile " |
4591 | 4686 | "kernel.\n"); | |
4592 | /* allocate IRQ */ | 4687 | return nboard; |
4593 | if(request_irq(cy_isa_irq, cyy_interrupt, | 4688 | } |
4594 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) | 4689 | |
4595 | { | 4690 | /* allocate IRQ */ |
4596 | printk("Cyclom-Y/ISA found at 0x%lx ", | 4691 | if (request_irq(cy_isa_irq, cyy_interrupt, |
4597 | (unsigned long) cy_isa_address); | 4692 | IRQF_DISABLED, "Cyclom-Y", &cy_card[j])) { |
4598 | printk("but could not allocate IRQ#%d.\n", | 4693 | printk("Cyclom-Y/ISA found at 0x%lx ", |
4599 | cy_isa_irq); | 4694 | (unsigned long)cy_isa_address); |
4600 | return(nboard); | 4695 | printk("but could not allocate IRQ#%d.\n", cy_isa_irq); |
4601 | } | 4696 | return nboard; |
4602 | 4697 | } | |
4603 | /* set cy_card */ | 4698 | |
4604 | cy_card[j].base_addr = cy_isa_address; | 4699 | /* set cy_card */ |
4605 | cy_card[j].ctl_addr = NULL; | 4700 | cy_card[j].base_addr = cy_isa_address; |
4606 | cy_card[j].irq = (int) cy_isa_irq; | 4701 | cy_card[j].ctl_addr = NULL; |
4607 | cy_card[j].bus_index = 0; | 4702 | cy_card[j].irq = (int)cy_isa_irq; |
4608 | cy_card[j].first_line = cy_next_channel; | 4703 | cy_card[j].bus_index = 0; |
4609 | cy_card[j].num_chips = cy_isa_nchan/4; | 4704 | cy_card[j].first_line = cy_next_channel; |
4610 | nboard++; | 4705 | cy_card[j].num_chips = cy_isa_nchan / 4; |
4611 | 4706 | nboard++; | |
4612 | /* print message */ | 4707 | |
4613 | printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ", | 4708 | /* print message */ |
4614 | j+1, (unsigned long) cy_isa_address, | 4709 | printk("Cyclom-Y/ISA #%d: 0x%lx-0x%lx, IRQ%d, ", |
4615 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), | 4710 | j + 1, (unsigned long)cy_isa_address, |
4616 | cy_isa_irq); | 4711 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), |
4617 | printk("%d channels starting from port %d.\n", | 4712 | cy_isa_irq); |
4618 | cy_isa_nchan, cy_next_channel); | 4713 | printk("%d channels starting from port %d.\n", |
4619 | cy_next_channel += cy_isa_nchan; | 4714 | cy_isa_nchan, cy_next_channel); |
4620 | } | 4715 | cy_next_channel += cy_isa_nchan; |
4621 | return(nboard); | 4716 | } |
4717 | return nboard; | ||
4622 | #else | 4718 | #else |
4623 | return(0); | 4719 | return 0; |
4624 | #endif /* CONFIG_ISA */ | 4720 | #endif /* CONFIG_ISA */ |
4625 | } /* cy_detect_isa */ | 4721 | } /* cy_detect_isa */ |
4626 | 4722 | ||
4627 | static void | 4723 | static void plx_init(void __iomem * addr, uclong initctl) |
4628 | plx_init(void __iomem *addr, uclong initctl) | ||
4629 | { | 4724 | { |
4630 | /* Reset PLX */ | 4725 | /* Reset PLX */ |
4631 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000); | 4726 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x40000000); |
4632 | udelay(100L); | 4727 | udelay(100L); |
4633 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000); | 4728 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x40000000); |
4634 | 4729 | ||
4635 | /* Reload Config. Registers from EEPROM */ | 4730 | /* Reload Config. Registers from EEPROM */ |
4636 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000); | 4731 | cy_writel(addr + initctl, cy_readl(addr + initctl) | 0x20000000); |
4637 | udelay(100L); | 4732 | udelay(100L); |
4638 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000); | 4733 | cy_writel(addr + initctl, cy_readl(addr + initctl) & ~0x20000000); |
4639 | } | 4734 | } |
4640 | 4735 | ||
4641 | /* | 4736 | /* |
@@ -4644,43 +4739,42 @@ plx_init(void __iomem *addr, uclong initctl) | |||
4644 | * sets global variables and return the number of PCI boards found. | 4739 | * sets global variables and return the number of PCI boards found. |
4645 | * --------------------------------------------------------------------- | 4740 | * --------------------------------------------------------------------- |
4646 | */ | 4741 | */ |
4647 | static int __init | 4742 | static int __init cy_detect_pci(void) |
4648 | cy_detect_pci(void) | ||
4649 | { | 4743 | { |
4650 | #ifdef CONFIG_PCI | 4744 | #ifdef CONFIG_PCI |
4651 | 4745 | ||
4652 | struct pci_dev *pdev = NULL; | 4746 | struct pci_dev *pdev = NULL; |
4653 | unsigned char cyy_rev_id; | 4747 | unsigned char cyy_rev_id; |
4654 | unsigned char cy_pci_irq = 0; | 4748 | unsigned char cy_pci_irq = 0; |
4655 | uclong cy_pci_phys0, cy_pci_phys2; | 4749 | uclong cy_pci_phys0, cy_pci_phys2; |
4656 | void __iomem *cy_pci_addr0, *cy_pci_addr2; | 4750 | void __iomem *cy_pci_addr0, *cy_pci_addr2; |
4657 | unsigned short i,j,cy_pci_nchan, plx_ver; | 4751 | unsigned short i, j, cy_pci_nchan, plx_ver; |
4658 | unsigned short device_id,dev_index = 0; | 4752 | unsigned short device_id, dev_index = 0; |
4659 | uclong mailbox; | 4753 | uclong mailbox; |
4660 | uclong ZeIndex = 0; | 4754 | uclong ZeIndex = 0; |
4661 | void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS]; | 4755 | void __iomem *Ze_addr0[NR_CARDS], *Ze_addr2[NR_CARDS]; |
4662 | uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS]; | 4756 | uclong Ze_phys0[NR_CARDS], Ze_phys2[NR_CARDS]; |
4663 | unsigned char Ze_irq[NR_CARDS]; | 4757 | unsigned char Ze_irq[NR_CARDS]; |
4664 | struct pci_dev *Ze_pdev[NR_CARDS]; | 4758 | struct pci_dev *Ze_pdev[NR_CARDS]; |
4665 | 4759 | ||
4666 | for (i = 0; i < NR_CARDS; i++) { | 4760 | for (i = 0; i < NR_CARDS; i++) { |
4667 | /* look for a Cyclades card by vendor and device id */ | 4761 | /* look for a Cyclades card by vendor and device id */ |
4668 | while((device_id = cy_pci_dev_id[dev_index]) != 0) { | 4762 | while ((device_id = cy_pci_dev_id[dev_index]) != 0) { |
4669 | if((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES, | 4763 | if ((pdev = pci_get_device(PCI_VENDOR_ID_CYCLADES, |
4670 | device_id, pdev)) == NULL) { | 4764 | device_id, pdev)) == NULL) { |
4671 | dev_index++; /* try next device id */ | 4765 | dev_index++; /* try next device id */ |
4672 | } else { | 4766 | } else { |
4673 | break; /* found a board */ | 4767 | break; /* found a board */ |
4674 | } | 4768 | } |
4675 | } | 4769 | } |
4676 | 4770 | ||
4677 | if (device_id == 0) | 4771 | if (device_id == 0) |
4678 | break; | 4772 | break; |
4679 | 4773 | ||
4680 | if (pci_enable_device(pdev)) | 4774 | if (pci_enable_device(pdev)) |
4681 | continue; | 4775 | continue; |
4682 | 4776 | ||
4683 | /* read PCI configuration area */ | 4777 | /* read PCI configuration area */ |
4684 | cy_pci_irq = pdev->irq; | 4778 | cy_pci_irq = pdev->irq; |
4685 | cy_pci_phys0 = pci_resource_start(pdev, 0); | 4779 | cy_pci_phys0 = pci_resource_start(pdev, 0); |
4686 | cy_pci_phys2 = pci_resource_start(pdev, 2); | 4780 | cy_pci_phys2 = pci_resource_start(pdev, 2); |
@@ -4688,482 +4782,497 @@ cy_detect_pci(void) | |||
4688 | 4782 | ||
4689 | device_id &= ~PCI_DEVICE_ID_MASK; | 4783 | device_id &= ~PCI_DEVICE_ID_MASK; |
4690 | 4784 | ||
4691 | if ((device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) | 4785 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
4692 | || (device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi)){ | 4786 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
4693 | #ifdef CY_PCI_DEBUG | 4787 | #ifdef CY_PCI_DEBUG |
4694 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", | 4788 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", |
4695 | pdev->bus->number, pdev->devfn); | 4789 | pdev->bus->number, pdev->devfn); |
4696 | printk("rev_id=%d) IRQ%d\n", | 4790 | printk("rev_id=%d) IRQ%d\n", |
4697 | cyy_rev_id, (int)cy_pci_irq); | 4791 | cyy_rev_id, (int)cy_pci_irq); |
4698 | printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n", | 4792 | printk("Cyclom-Y/PCI:found winaddr=0x%lx " |
4699 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | 4793 | "ctladdr=0x%lx\n", |
4794 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | ||
4700 | #endif | 4795 | #endif |
4701 | 4796 | ||
4702 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | 4797 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { |
4703 | printk(" Warning: PCI I/O bit incorrectly set. " | 4798 | printk(" Warning: PCI I/O bit incorrectly " |
4704 | "Ignoring it...\n"); | 4799 | "set. Ignoring it...\n"); |
4705 | pdev->resource[2].flags &= ~IORESOURCE_IO; | 4800 | pdev->resource[2].flags &= ~IORESOURCE_IO; |
4706 | } | 4801 | } |
4707 | |||
4708 | /* Although we don't use this I/O region, we should | ||
4709 | request it from the kernel anyway, to avoid problems | ||
4710 | with other drivers accessing it. */ | ||
4711 | if (pci_request_regions(pdev, "Cyclom-Y") != 0) { | ||
4712 | printk(KERN_ERR "cyclades: failed to reserve PCI resources\n"); | ||
4713 | continue; | ||
4714 | } | ||
4715 | 4802 | ||
4803 | /* Although we don't use this I/O region, we should | ||
4804 | request it from the kernel anyway, to avoid problems | ||
4805 | with other drivers accessing it. */ | ||
4806 | if (pci_request_regions(pdev, "Cyclom-Y") != 0) { | ||
4807 | printk(KERN_ERR "cyclades: failed to reserve " | ||
4808 | "PCI resources\n"); | ||
4809 | continue; | ||
4810 | } | ||
4716 | #if defined(__alpha__) | 4811 | #if defined(__alpha__) |
4717 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ | 4812 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */ |
4718 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", | 4813 | printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ", |
4719 | pdev->bus->number, pdev->devfn); | 4814 | pdev->bus->number, pdev->devfn); |
4720 | printk("rev_id=%d) IRQ%d\n", | 4815 | printk("rev_id=%d) IRQ%d\n", |
4721 | cyy_rev_id, (int)cy_pci_irq); | 4816 | cyy_rev_id, (int)cy_pci_irq); |
4722 | printk("Cyclom-Y/PCI:found winaddr=0x%lx ctladdr=0x%lx\n", | 4817 | printk("Cyclom-Y/PCI:found winaddr=0x%lx " |
4723 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | 4818 | "ctladdr=0x%lx\n", |
4724 | printk("Cyclom-Y/PCI not supported for low addresses in " | 4819 | (ulong)cy_pci_phys2, |
4725 | "Alpha systems.\n"); | 4820 | (ulong)cy_pci_phys0); |
4726 | i--; | 4821 | printk("Cyclom-Y/PCI not supported for low " |
4727 | continue; | 4822 | "addresses in Alpha systems.\n"); |
4728 | } | 4823 | i--; |
4824 | continue; | ||
4825 | } | ||
4729 | #endif | 4826 | #endif |
4730 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl); | 4827 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Yctl); |
4731 | cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin); | 4828 | cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ywin); |
4732 | 4829 | ||
4733 | #ifdef CY_PCI_DEBUG | 4830 | #ifdef CY_PCI_DEBUG |
4734 | printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", | 4831 | printk("Cyclom-Y/PCI: relocate winaddr=0x%lx " |
4735 | (u_long)cy_pci_addr2, (u_long)cy_pci_addr0); | 4832 | "ctladdr=0x%lx\n", |
4833 | (u_long)cy_pci_addr2, (u_long)cy_pci_addr0); | ||
4736 | #endif | 4834 | #endif |
4737 | cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * | 4835 | cy_pci_nchan = (unsigned short)(CyPORTS_PER_CHIP * |
4738 | cyy_init_card(cy_pci_addr2, 1)); | 4836 | cyy_init_card(cy_pci_addr2, 1)); |
4739 | if(cy_pci_nchan == 0) { | 4837 | if (cy_pci_nchan == 0) { |
4740 | printk("Cyclom-Y PCI host card with "); | 4838 | printk("Cyclom-Y PCI host card with "); |
4741 | printk("no Serial-Modules at 0x%lx.\n", | 4839 | printk("no Serial-Modules at 0x%lx.\n", |
4742 | (ulong) cy_pci_phys2); | 4840 | (ulong) cy_pci_phys2); |
4743 | i--; | 4841 | i--; |
4744 | continue; | 4842 | continue; |
4745 | } | 4843 | } |
4746 | if((cy_next_channel+cy_pci_nchan) > NR_PORTS) { | 4844 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { |
4747 | printk("Cyclom-Y/PCI found at 0x%lx ", | 4845 | printk("Cyclom-Y/PCI found at 0x%lx ", |
4748 | (ulong) cy_pci_phys2); | 4846 | (ulong) cy_pci_phys2); |
4749 | printk("but no channels are available.\n"); | 4847 | printk("but no channels are available.\n"); |
4750 | printk("Change NR_PORTS in cyclades.c and recompile kernel.\n"); | 4848 | printk("Change NR_PORTS in cyclades.c and " |
4751 | return(i); | 4849 | "recompile kernel.\n"); |
4752 | } | 4850 | return i; |
4753 | /* fill the next cy_card structure available */ | 4851 | } |
4754 | for (j = 0 ; j < NR_CARDS ; j++) { | 4852 | /* fill the next cy_card structure available */ |
4755 | if (cy_card[j].base_addr == 0) break; | 4853 | for (j = 0; j < NR_CARDS; j++) { |
4756 | } | 4854 | if (cy_card[j].base_addr == 0) |
4757 | if (j == NR_CARDS) { /* no more cy_cards available */ | 4855 | break; |
4758 | printk("Cyclom-Y/PCI found at 0x%lx ", | 4856 | } |
4759 | (ulong) cy_pci_phys2); | 4857 | if (j == NR_CARDS) { /* no more cy_cards available */ |
4760 | printk("but no more cards can be used.\n"); | 4858 | printk("Cyclom-Y/PCI found at 0x%lx ", |
4761 | printk("Change NR_CARDS in cyclades.c and recompile kernel.\n"); | 4859 | (ulong) cy_pci_phys2); |
4762 | return(i); | 4860 | printk("but no more cards can be used.\n"); |
4763 | } | 4861 | printk("Change NR_CARDS in cyclades.c and " |
4764 | 4862 | "recompile kernel.\n"); | |
4765 | /* allocate IRQ */ | 4863 | return i; |
4766 | if(request_irq(cy_pci_irq, cyy_interrupt, | 4864 | } |
4767 | IRQF_SHARED, "Cyclom-Y", &cy_card[j])) | 4865 | |
4768 | { | 4866 | /* allocate IRQ */ |
4769 | printk("Cyclom-Y/PCI found at 0x%lx ", | 4867 | if (request_irq(cy_pci_irq, cyy_interrupt, |
4770 | (ulong) cy_pci_phys2); | 4868 | IRQF_SHARED, "Cyclom-Y", &cy_card[j])) { |
4771 | printk("but could not allocate IRQ%d.\n", | 4869 | printk("Cyclom-Y/PCI found at 0x%lx ", |
4772 | cy_pci_irq); | 4870 | (ulong) cy_pci_phys2); |
4773 | return(i); | 4871 | printk("but could not allocate IRQ%d.\n", |
4774 | } | 4872 | cy_pci_irq); |
4775 | 4873 | return i; | |
4776 | /* set cy_card */ | 4874 | } |
4777 | cy_card[j].base_phys = (ulong)cy_pci_phys2; | ||
4778 | cy_card[j].ctl_phys = (ulong)cy_pci_phys0; | ||
4779 | cy_card[j].base_addr = cy_pci_addr2; | ||
4780 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
4781 | cy_card[j].irq = (int) cy_pci_irq; | ||
4782 | cy_card[j].bus_index = 1; | ||
4783 | cy_card[j].first_line = cy_next_channel; | ||
4784 | cy_card[j].num_chips = cy_pci_nchan/4; | ||
4785 | cy_card[j].pdev = pdev; | ||
4786 | |||
4787 | /* enable interrupts in the PCI interface */ | ||
4788 | plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f; | ||
4789 | switch (plx_ver) { | ||
4790 | case PLX_9050: | ||
4791 | |||
4792 | cy_writeb(cy_pci_addr0+0x4c, 0x43); | ||
4793 | break; | ||
4794 | |||
4795 | case PLX_9060: | ||
4796 | case PLX_9080: | ||
4797 | default: /* Old boards, use PLX_9060 */ | ||
4798 | |||
4799 | plx_init(cy_pci_addr0, 0x6c); | ||
4800 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4801 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4802 | re-write it to the PCI config. registers. | ||
4803 | This will remain here until we find a permanent fix. */ | ||
4804 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq); | ||
4805 | |||
4806 | cy_writew(cy_pci_addr0+0x68, | ||
4807 | cy_readw(cy_pci_addr0+0x68)|0x0900); | ||
4808 | break; | ||
4809 | } | ||
4810 | 4875 | ||
4811 | /* print message */ | 4876 | /* set cy_card */ |
4812 | printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | 4877 | cy_card[j].base_phys = (ulong) cy_pci_phys2; |
4813 | j+1, | 4878 | cy_card[j].ctl_phys = (ulong) cy_pci_phys0; |
4814 | (ulong)cy_pci_phys2, | 4879 | cy_card[j].base_addr = cy_pci_addr2; |
4815 | (ulong)(cy_pci_phys2 + CyPCI_Ywin - 1), | 4880 | cy_card[j].ctl_addr = cy_pci_addr0; |
4816 | (int)cy_pci_irq); | 4881 | cy_card[j].irq = (int)cy_pci_irq; |
4817 | printk("%d channels starting from port %d.\n", | 4882 | cy_card[j].bus_index = 1; |
4818 | cy_pci_nchan, cy_next_channel); | 4883 | cy_card[j].first_line = cy_next_channel; |
4819 | 4884 | cy_card[j].num_chips = cy_pci_nchan / 4; | |
4820 | cy_next_channel += cy_pci_nchan; | 4885 | cy_card[j].pdev = pdev; |
4821 | }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo){ | 4886 | |
4822 | /* print message */ | 4887 | /* enable interrupts in the PCI interface */ |
4823 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | 4888 | plx_ver = cy_readb(cy_pci_addr2 + CyPLX_VER) & 0x0f; |
4824 | pdev->bus->number, pdev->devfn); | 4889 | switch (plx_ver) { |
4825 | printk("rev_id=%d) IRQ%d\n", | 4890 | case PLX_9050: |
4826 | cyy_rev_id, (int)cy_pci_irq); | 4891 | |
4827 | printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n", | 4892 | cy_writeb(cy_pci_addr0 + 0x4c, 0x43); |
4828 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | 4893 | break; |
4829 | printk("Cyclades-Z/PCI not supported for low addresses\n"); | 4894 | |
4830 | break; | 4895 | case PLX_9060: |
4831 | }else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi){ | 4896 | case PLX_9080: |
4897 | default: /* Old boards, use PLX_9060 */ | ||
4898 | |||
4899 | plx_init(cy_pci_addr0, 0x6c); | ||
4900 | /* For some yet unknown reason, once the PLX9060 reloads | ||
4901 | the EEPROM, the IRQ is lost and, thus, we have to | ||
4902 | re-write it to the PCI config. registers. | ||
4903 | This will remain here until we find a permanent | ||
4904 | fix. */ | ||
4905 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | ||
4906 | cy_pci_irq); | ||
4907 | |||
4908 | cy_writew(cy_pci_addr0 + 0x68, | ||
4909 | cy_readw(cy_pci_addr0 + | ||
4910 | 0x68) | 0x0900); | ||
4911 | break; | ||
4912 | } | ||
4913 | |||
4914 | /* print message */ | ||
4915 | printk("Cyclom-Y/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | ||
4916 | j + 1, (ulong)cy_pci_phys2, | ||
4917 | (ulong) (cy_pci_phys2 + CyPCI_Ywin - 1), | ||
4918 | (int)cy_pci_irq); | ||
4919 | printk("%d channels starting from port %d.\n", | ||
4920 | cy_pci_nchan, cy_next_channel); | ||
4921 | |||
4922 | cy_next_channel += cy_pci_nchan; | ||
4923 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Lo) { | ||
4924 | /* print message */ | ||
4925 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | ||
4926 | pdev->bus->number, pdev->devfn); | ||
4927 | printk("rev_id=%d) IRQ%d\n", | ||
4928 | cyy_rev_id, (int)cy_pci_irq); | ||
4929 | printk("Cyclades-Z/PCI: found winaddr=0x%lx " | ||
4930 | "ctladdr=0x%lx\n", | ||
4931 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | ||
4932 | printk("Cyclades-Z/PCI not supported for low " | ||
4933 | "addresses\n"); | ||
4934 | break; | ||
4935 | } else if (device_id == PCI_DEVICE_ID_CYCLOM_Z_Hi) { | ||
4832 | #ifdef CY_PCI_DEBUG | 4936 | #ifdef CY_PCI_DEBUG |
4833 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", | 4937 | printk("Cyclades-Z/PCI (bus=0x0%x, pci_id=0x%x, ", |
4834 | pdev->bus->number, pdev->devfn); | 4938 | pdev->bus->number, pdev->devfn); |
4835 | printk("rev_id=%d) IRQ%d\n", | 4939 | printk("rev_id=%d) IRQ%d\n", |
4836 | cyy_rev_id, (int)cy_pci_irq); | 4940 | cyy_rev_id, (int)cy_pci_irq); |
4837 | printk("Cyclades-Z/PCI: found winaddr=0x%lx ctladdr=0x%lx\n", | 4941 | printk("Cyclades-Z/PCI: found winaddr=0x%lx " |
4838 | (ulong)cy_pci_phys2, (ulong)cy_pci_phys0); | 4942 | "ctladdr=0x%lx\n", |
4943 | (ulong) cy_pci_phys2, (ulong) cy_pci_phys0); | ||
4839 | #endif | 4944 | #endif |
4840 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl); | 4945 | cy_pci_addr0 = ioremap(cy_pci_phys0, CyPCI_Zctl); |
4841 | 4946 | ||
4842 | /* Disable interrupts on the PLX before resetting it */ | 4947 | /* Disable interrupts on the PLX before resetting it */ |
4843 | cy_writew(cy_pci_addr0+0x68, | 4948 | cy_writew(cy_pci_addr0 + 0x68, |
4844 | cy_readw(cy_pci_addr0+0x68) & ~0x0900); | 4949 | cy_readw(cy_pci_addr0 + 0x68) & ~0x0900); |
4845 | 4950 | ||
4846 | plx_init(cy_pci_addr0, 0x6c); | 4951 | plx_init(cy_pci_addr0, 0x6c); |
4847 | /* For some yet unknown reason, once the PLX9060 reloads | 4952 | /* For some yet unknown reason, once the PLX9060 reloads |
4848 | the EEPROM, the IRQ is lost and, thus, we have to | 4953 | the EEPROM, the IRQ is lost and, thus, we have to |
4849 | re-write it to the PCI config. registers. | 4954 | re-write it to the PCI config. registers. |
4850 | This will remain here until we find a permanent fix. */ | 4955 | This will remain here until we find a permanent |
4851 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, cy_pci_irq); | 4956 | fix. */ |
4852 | 4957 | pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, | |
4853 | mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) | 4958 | cy_pci_irq); |
4854 | cy_pci_addr0)->mail_box_0); | 4959 | |
4855 | 4960 | mailbox = | |
4856 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { | 4961 | (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) |
4857 | printk(" Warning: PCI I/O bit incorrectly set. " | 4962 | cy_pci_addr0)->mail_box_0); |
4858 | "Ignoring it...\n"); | 4963 | |
4859 | pdev->resource[2].flags &= ~IORESOURCE_IO; | 4964 | if (pci_resource_flags(pdev, 2) & IORESOURCE_IO) { |
4860 | } | 4965 | printk(" Warning: PCI I/O bit incorrectly " |
4966 | "set. Ignoring it...\n"); | ||
4967 | pdev->resource[2].flags &= ~IORESOURCE_IO; | ||
4968 | } | ||
4861 | 4969 | ||
4862 | /* Although we don't use this I/O region, we should | 4970 | /* Although we don't use this I/O region, we should |
4863 | request it from the kernel anyway, to avoid problems | 4971 | request it from the kernel anyway, to avoid problems |
4864 | with other drivers accessing it. */ | 4972 | with other drivers accessing it. */ |
4865 | if (pci_request_regions(pdev, "Cyclades-Z") != 0) { | 4973 | if (pci_request_regions(pdev, "Cyclades-Z") != 0) { |
4866 | printk(KERN_ERR "cyclades: failed to reserve PCI resources\n"); | 4974 | printk(KERN_ERR "cyclades: failed to reserve " |
4867 | continue; | 4975 | "PCI resources\n"); |
4868 | } | 4976 | continue; |
4869 | 4977 | } | |
4870 | if (mailbox == ZE_V1) { | 4978 | |
4871 | cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Ze_win); | 4979 | if (mailbox == ZE_V1) { |
4872 | if (ZeIndex == NR_CARDS) { | 4980 | cy_pci_addr2 = ioremap(cy_pci_phys2, |
4873 | printk("Cyclades-Ze/PCI found at 0x%lx ", | 4981 | CyPCI_Ze_win); |
4874 | (ulong)cy_pci_phys2); | 4982 | if (ZeIndex == NR_CARDS) { |
4875 | printk("but no more cards can be used.\n"); | 4983 | printk("Cyclades-Ze/PCI found at " |
4876 | printk("Change NR_CARDS in cyclades.c and recompile kernel.\n"); | 4984 | "0x%lx but no more cards can " |
4877 | } else { | 4985 | "be used.\nChange NR_CARDS in " |
4878 | Ze_phys0[ZeIndex] = cy_pci_phys0; | 4986 | "cyclades.c and recompile " |
4879 | Ze_phys2[ZeIndex] = cy_pci_phys2; | 4987 | "kernel.\n", |
4880 | Ze_addr0[ZeIndex] = cy_pci_addr0; | 4988 | (ulong)cy_pci_phys2); |
4881 | Ze_addr2[ZeIndex] = cy_pci_addr2; | 4989 | } else { |
4882 | Ze_irq[ZeIndex] = cy_pci_irq; | 4990 | Ze_phys0[ZeIndex] = cy_pci_phys0; |
4883 | Ze_pdev[ZeIndex] = pdev; | 4991 | Ze_phys2[ZeIndex] = cy_pci_phys2; |
4884 | ZeIndex++; | 4992 | Ze_addr0[ZeIndex] = cy_pci_addr0; |
4885 | } | 4993 | Ze_addr2[ZeIndex] = cy_pci_addr2; |
4886 | i--; | 4994 | Ze_irq[ZeIndex] = cy_pci_irq; |
4887 | continue; | 4995 | Ze_pdev[ZeIndex] = pdev; |
4888 | } else { | 4996 | ZeIndex++; |
4889 | cy_pci_addr2 = ioremap(cy_pci_phys2, CyPCI_Zwin); | 4997 | } |
4890 | } | 4998 | i--; |
4999 | continue; | ||
5000 | } else { | ||
5001 | cy_pci_addr2 = ioremap(cy_pci_phys2,CyPCI_Zwin); | ||
5002 | } | ||
4891 | 5003 | ||
4892 | #ifdef CY_PCI_DEBUG | 5004 | #ifdef CY_PCI_DEBUG |
4893 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", | 5005 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx " |
4894 | (ulong)cy_pci_addr2, (ulong)cy_pci_addr0); | 5006 | "ctladdr=0x%lx\n", |
4895 | if (mailbox == ZO_V1) { | 5007 | (ulong) cy_pci_addr2, (ulong) cy_pci_addr0); |
4896 | cy_writel(&((struct RUNTIME_9060 *) | 5008 | if (mailbox == ZO_V1) { |
4897 | (cy_pci_addr0))->loc_addr_base, WIN_CREG); | 5009 | cy_writel(&((struct RUNTIME_9060 *) |
4898 | PAUSE | 5010 | (cy_pci_addr0))->loc_addr_base, |
4899 | printk("Cyclades-8Zo/PCI: FPGA id %lx, ver %lx\n", | 5011 | WIN_CREG); |
4900 | (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *) | 5012 | PAUSE; |
4901 | (cy_pci_addr2))->fpga_id)), | 5013 | printk("Cyclades-8Zo/PCI: FPGA id %lx, ver " |
4902 | (ulong)(0xff & cy_readl(&((struct CUSTOM_REG *) | 5014 | "%lx\n", (ulong) (0xff & |
4903 | (cy_pci_addr2))->fpga_version))); | 5015 | cy_readl(&((struct CUSTOM_REG *) |
4904 | cy_writel(&((struct RUNTIME_9060 *) | 5016 | (cy_pci_addr2))->fpga_id)), |
4905 | (cy_pci_addr0))->loc_addr_base, WIN_RAM); | 5017 | (ulong)(0xff & |
4906 | } else { | 5018 | cy_readl(&((struct CUSTOM_REG *) |
4907 | printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n"); | 5019 | (cy_pci_addr2))-> |
4908 | } | 5020 | fpga_version))); |
5021 | cy_writel(&((struct RUNTIME_9060 *) | ||
5022 | (cy_pci_addr0))->loc_addr_base, | ||
5023 | WIN_RAM); | ||
5024 | } else { | ||
5025 | printk("Cyclades-Z/PCI: New Cyclades-Z board. " | ||
5026 | "FPGA not loaded\n"); | ||
5027 | } | ||
4909 | #endif | 5028 | #endif |
4910 | /* The following clears the firmware id word. This ensures | 5029 | /* The following clears the firmware id word. This |
4911 | that the driver will not attempt to talk to the board | 5030 | ensures that the driver will not attempt to talk to |
4912 | until it has been properly initialized. | 5031 | the board until it has been properly initialized. |
4913 | */ | 5032 | */ |
4914 | PAUSE | 5033 | PAUSE; |
4915 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) | 5034 | if ((mailbox == ZO_V1) || (mailbox == ZO_V2)) |
4916 | cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); | 5035 | cy_writel(cy_pci_addr2 + ID_ADDRESS, 0L); |
4917 | 5036 | ||
4918 | /* This must be a Cyclades-8Zo/PCI. The extendable | 5037 | /* This must be a Cyclades-8Zo/PCI. The extendable |
4919 | version will have a different device_id and will | 5038 | version will have a different device_id and will |
4920 | be allocated its maximum number of ports. */ | 5039 | be allocated its maximum number of ports. */ |
4921 | cy_pci_nchan = 8; | 5040 | cy_pci_nchan = 8; |
4922 | 5041 | ||
4923 | if((cy_next_channel+cy_pci_nchan) > NR_PORTS) { | 5042 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { |
4924 | printk("Cyclades-8Zo/PCI found at 0x%lx ", | 5043 | printk("Cyclades-8Zo/PCI found at 0x%lx but" |
4925 | (ulong)cy_pci_phys2); | 5044 | "no channels are available.\nChange " |
4926 | printk("but no channels are available.\n"); | 5045 | "NR_PORTS in cyclades.c and recompile " |
4927 | printk("Change NR_PORTS in cyclades.c and recompile kernel.\n"); | 5046 | "kernel.\n", (ulong)cy_pci_phys2); |
4928 | return(i); | 5047 | return i; |
4929 | } | 5048 | } |
4930 | |||
4931 | /* fill the next cy_card structure available */ | ||
4932 | for (j = 0 ; j < NR_CARDS ; j++) { | ||
4933 | if (cy_card[j].base_addr == 0) break; | ||
4934 | } | ||
4935 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
4936 | printk("Cyclades-8Zo/PCI found at 0x%lx ", | ||
4937 | (ulong)cy_pci_phys2); | ||
4938 | printk("but no more cards can be used.\n"); | ||
4939 | printk("Change NR_CARDS in cyclades.c and recompile kernel.\n"); | ||
4940 | return(i); | ||
4941 | } | ||
4942 | 5049 | ||
5050 | /* fill the next cy_card structure available */ | ||
5051 | for (j = 0; j < NR_CARDS; j++) { | ||
5052 | if (cy_card[j].base_addr == 0) | ||
5053 | break; | ||
5054 | } | ||
5055 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
5056 | printk("Cyclades-8Zo/PCI found at 0x%lx but" | ||
5057 | "no more cards can be used.\nChange " | ||
5058 | "NR_CARDS in cyclades.c and recompile " | ||
5059 | "kernel.\n", (ulong)cy_pci_phys2); | ||
5060 | return i; | ||
5061 | } | ||
5062 | #ifdef CONFIG_CYZ_INTR | ||
5063 | /* allocate IRQ only if board has an IRQ */ | ||
5064 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { | ||
5065 | if (request_irq(cy_pci_irq, cyz_interrupt, | ||
5066 | IRQF_SHARED, "Cyclades-Z", | ||
5067 | &cy_card[j])) { | ||
5068 | printk("Cyclom-8Zo/PCI found at 0x%lx " | ||
5069 | "but could not allocate " | ||
5070 | "IRQ%d.\n", (ulong)cy_pci_phys2, | ||
5071 | cy_pci_irq); | ||
5072 | return i; | ||
5073 | } | ||
5074 | } | ||
5075 | #endif /* CONFIG_CYZ_INTR */ | ||
5076 | |||
5077 | /* set cy_card */ | ||
5078 | cy_card[j].base_phys = cy_pci_phys2; | ||
5079 | cy_card[j].ctl_phys = cy_pci_phys0; | ||
5080 | cy_card[j].base_addr = cy_pci_addr2; | ||
5081 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
5082 | cy_card[j].irq = (int)cy_pci_irq; | ||
5083 | cy_card[j].bus_index = 1; | ||
5084 | cy_card[j].first_line = cy_next_channel; | ||
5085 | cy_card[j].num_chips = -1; | ||
5086 | cy_card[j].pdev = pdev; | ||
5087 | |||
5088 | /* print message */ | ||
4943 | #ifdef CONFIG_CYZ_INTR | 5089 | #ifdef CONFIG_CYZ_INTR |
4944 | /* allocate IRQ only if board has an IRQ */ | 5090 | /* don't report IRQ if board is no IRQ */ |
4945 | if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) { | 5091 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) |
4946 | if(request_irq(cy_pci_irq, cyz_interrupt, | 5092 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, " |
4947 | IRQF_SHARED, "Cyclades-Z", &cy_card[j])) | 5093 | "IRQ%d, ", j + 1, (ulong)cy_pci_phys2, |
4948 | { | 5094 | (ulong) (cy_pci_phys2 + CyPCI_Zwin - 1), |
4949 | printk("Cyclom-8Zo/PCI found at 0x%lx ", | 5095 | (int)cy_pci_irq); |
4950 | (ulong) cy_pci_phys2); | 5096 | else |
4951 | printk("but could not allocate IRQ%d.\n", | 5097 | #endif /* CONFIG_CYZ_INTR */ |
4952 | cy_pci_irq); | 5098 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ", |
4953 | return(i); | 5099 | j + 1, (ulong)cy_pci_phys2, |
4954 | } | 5100 | (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1)); |
5101 | |||
5102 | printk("%d channels starting from port %d.\n", | ||
5103 | cy_pci_nchan, cy_next_channel); | ||
5104 | cy_next_channel += cy_pci_nchan; | ||
4955 | } | 5105 | } |
4956 | #endif /* CONFIG_CYZ_INTR */ | 5106 | } |
4957 | |||
4958 | |||
4959 | /* set cy_card */ | ||
4960 | cy_card[j].base_phys = cy_pci_phys2; | ||
4961 | cy_card[j].ctl_phys = cy_pci_phys0; | ||
4962 | cy_card[j].base_addr = cy_pci_addr2; | ||
4963 | cy_card[j].ctl_addr = cy_pci_addr0; | ||
4964 | cy_card[j].irq = (int) cy_pci_irq; | ||
4965 | cy_card[j].bus_index = 1; | ||
4966 | cy_card[j].first_line = cy_next_channel; | ||
4967 | cy_card[j].num_chips = -1; | ||
4968 | cy_card[j].pdev = pdev; | ||
4969 | 5107 | ||
4970 | /* print message */ | 5108 | for (; ZeIndex != 0 && i < NR_CARDS; i++) { |
4971 | #ifdef CONFIG_CYZ_INTR | 5109 | cy_pci_phys0 = Ze_phys0[0]; |
4972 | /* don't report IRQ if board is no IRQ */ | 5110 | cy_pci_phys2 = Ze_phys2[0]; |
4973 | if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) | 5111 | cy_pci_addr0 = Ze_addr0[0]; |
4974 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | 5112 | cy_pci_addr2 = Ze_addr2[0]; |
4975 | j+1,(ulong)cy_pci_phys2, | 5113 | cy_pci_irq = Ze_irq[0]; |
4976 | (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1), | 5114 | pdev = Ze_pdev[0]; |
4977 | (int)cy_pci_irq); | 5115 | for (j = 0; j < ZeIndex - 1; j++) { |
4978 | else | 5116 | Ze_phys0[j] = Ze_phys0[j + 1]; |
4979 | #endif /* CONFIG_CYZ_INTR */ | 5117 | Ze_phys2[j] = Ze_phys2[j + 1]; |
4980 | printk("Cyclades-8Zo/PCI #%d: 0x%lx-0x%lx, ", | 5118 | Ze_addr0[j] = Ze_addr0[j + 1]; |
4981 | j+1,(ulong)cy_pci_phys2, | 5119 | Ze_addr2[j] = Ze_addr2[j + 1]; |
4982 | (ulong)(cy_pci_phys2 + CyPCI_Zwin - 1)); | 5120 | Ze_irq[j] = Ze_irq[j + 1]; |
4983 | 5121 | Ze_pdev[j] = Ze_pdev[j + 1]; | |
4984 | printk("%d channels starting from port %d.\n", | 5122 | } |
4985 | cy_pci_nchan,cy_next_channel); | 5123 | ZeIndex--; |
4986 | cy_next_channel += cy_pci_nchan; | 5124 | mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) |
4987 | } | 5125 | cy_pci_addr0)->mail_box_0); |
4988 | } | ||
4989 | |||
4990 | for (; ZeIndex != 0 && i < NR_CARDS; i++) { | ||
4991 | cy_pci_phys0 = Ze_phys0[0]; | ||
4992 | cy_pci_phys2 = Ze_phys2[0]; | ||
4993 | cy_pci_addr0 = Ze_addr0[0]; | ||
4994 | cy_pci_addr2 = Ze_addr2[0]; | ||
4995 | cy_pci_irq = Ze_irq[0]; | ||
4996 | pdev = Ze_pdev[0]; | ||
4997 | for (j = 0 ; j < ZeIndex-1 ; j++) { | ||
4998 | Ze_phys0[j] = Ze_phys0[j+1]; | ||
4999 | Ze_phys2[j] = Ze_phys2[j+1]; | ||
5000 | Ze_addr0[j] = Ze_addr0[j+1]; | ||
5001 | Ze_addr2[j] = Ze_addr2[j+1]; | ||
5002 | Ze_irq[j] = Ze_irq[j+1]; | ||
5003 | Ze_pdev[j] = Ze_pdev[j+1]; | ||
5004 | } | ||
5005 | ZeIndex--; | ||
5006 | mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 __iomem *) | ||
5007 | cy_pci_addr0)->mail_box_0); | ||
5008 | #ifdef CY_PCI_DEBUG | 5126 | #ifdef CY_PCI_DEBUG |
5009 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", | 5127 | printk("Cyclades-Z/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n", |
5010 | (ulong)cy_pci_addr2, (ulong)cy_pci_addr0); | 5128 | (ulong)cy_pci_addr2, (ulong)cy_pci_addr0); |
5011 | printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not loaded\n"); | 5129 | printk("Cyclades-Z/PCI: New Cyclades-Z board. FPGA not " |
5130 | "loaded\n"); | ||
5012 | #endif | 5131 | #endif |
5013 | PAUSE | 5132 | PAUSE; |
5014 | /* This must be the new Cyclades-Ze/PCI. */ | 5133 | /* This must be the new Cyclades-Ze/PCI. */ |
5015 | cy_pci_nchan = ZE_V1_NPORTS; | 5134 | cy_pci_nchan = ZE_V1_NPORTS; |
5016 | 5135 | ||
5017 | if((cy_next_channel+cy_pci_nchan) > NR_PORTS) { | 5136 | if ((cy_next_channel + cy_pci_nchan) > NR_PORTS) { |
5018 | printk("Cyclades-Ze/PCI found at 0x%lx ", | 5137 | printk("Cyclades-Ze/PCI found at 0x%lx but no channels " |
5019 | (ulong)cy_pci_phys2); | 5138 | "are available.\nChange NR_PORTS in cyclades.c " |
5020 | printk("but no channels are available.\n"); | 5139 | "and recompile kernel.\n", |
5021 | printk("Change NR_PORTS in cyclades.c and recompile kernel.\n"); | 5140 | (ulong) cy_pci_phys2); |
5022 | return(i); | 5141 | return i; |
5023 | } | 5142 | } |
5024 | |||
5025 | /* fill the next cy_card structure available */ | ||
5026 | for (j = 0 ; j < NR_CARDS ; j++) { | ||
5027 | if (cy_card[j].base_addr == 0) break; | ||
5028 | } | ||
5029 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
5030 | printk("Cyclades-Ze/PCI found at 0x%lx ", | ||
5031 | (ulong)cy_pci_phys2); | ||
5032 | printk("but no more cards can be used.\n"); | ||
5033 | printk("Change NR_CARDS in cyclades.c and recompile kernel.\n"); | ||
5034 | return(i); | ||
5035 | } | ||
5036 | 5143 | ||
5144 | /* fill the next cy_card structure available */ | ||
5145 | for (j = 0; j < NR_CARDS; j++) { | ||
5146 | if (cy_card[j].base_addr == 0) | ||
5147 | break; | ||
5148 | } | ||
5149 | if (j == NR_CARDS) { /* no more cy_cards available */ | ||
5150 | printk("Cyclades-Ze/PCI found at 0x%lx but no more " | ||
5151 | "cards can be used.\nChange NR_CARDS in " | ||
5152 | "cyclades.c and recompile kernel.\n", | ||
5153 | (ulong) cy_pci_phys2); | ||
5154 | return i; | ||
5155 | } | ||
5037 | #ifdef CONFIG_CYZ_INTR | 5156 | #ifdef CONFIG_CYZ_INTR |
5038 | /* allocate IRQ only if board has an IRQ */ | 5157 | /* allocate IRQ only if board has an IRQ */ |
5039 | if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) { | 5158 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) { |
5040 | if(request_irq(cy_pci_irq, cyz_interrupt, | 5159 | if (request_irq(cy_pci_irq, cyz_interrupt, |
5041 | IRQF_SHARED, "Cyclades-Z", &cy_card[j])) | 5160 | IRQF_SHARED, "Cyclades-Z", |
5042 | { | 5161 | &cy_card[j])) { |
5043 | printk("Cyclom-Ze/PCI found at 0x%lx ", | 5162 | printk("Cyclom-Ze/PCI found at 0x%lx ", |
5044 | (ulong) cy_pci_phys2); | 5163 | (ulong) cy_pci_phys2); |
5045 | printk("but could not allocate IRQ%d.\n", | 5164 | printk("but could not allocate IRQ%d.\n", |
5046 | cy_pci_irq); | 5165 | cy_pci_irq); |
5047 | return(i); | 5166 | return i; |
5048 | } | 5167 | } |
5049 | } | 5168 | } |
5050 | #endif /* CONFIG_CYZ_INTR */ | 5169 | #endif /* CONFIG_CYZ_INTR */ |
5051 | 5170 | ||
5052 | /* set cy_card */ | 5171 | /* set cy_card */ |
5053 | cy_card[j].base_phys = cy_pci_phys2; | 5172 | cy_card[j].base_phys = cy_pci_phys2; |
5054 | cy_card[j].ctl_phys = cy_pci_phys0; | 5173 | cy_card[j].ctl_phys = cy_pci_phys0; |
5055 | cy_card[j].base_addr = cy_pci_addr2; | 5174 | cy_card[j].base_addr = cy_pci_addr2; |
5056 | cy_card[j].ctl_addr = cy_pci_addr0; | 5175 | cy_card[j].ctl_addr = cy_pci_addr0; |
5057 | cy_card[j].irq = (int) cy_pci_irq; | 5176 | cy_card[j].irq = (int)cy_pci_irq; |
5058 | cy_card[j].bus_index = 1; | 5177 | cy_card[j].bus_index = 1; |
5059 | cy_card[j].first_line = cy_next_channel; | 5178 | cy_card[j].first_line = cy_next_channel; |
5060 | cy_card[j].num_chips = -1; | 5179 | cy_card[j].num_chips = -1; |
5061 | cy_card[j].pdev = pdev; | 5180 | cy_card[j].pdev = pdev; |
5062 | 5181 | ||
5063 | /* print message */ | 5182 | /* print message */ |
5064 | #ifdef CONFIG_CYZ_INTR | 5183 | #ifdef CONFIG_CYZ_INTR |
5065 | /* don't report IRQ if board is no IRQ */ | 5184 | /* don't report IRQ if board is no IRQ */ |
5066 | if( (cy_pci_irq != 0) && (cy_pci_irq != 255) ) | 5185 | if ((cy_pci_irq != 0) && (cy_pci_irq != 255)) |
5067 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", | 5186 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, IRQ%d, ", |
5068 | j+1,(ulong)cy_pci_phys2, | 5187 | j + 1, (ulong) cy_pci_phys2, |
5069 | (ulong)(cy_pci_phys2 + CyPCI_Ze_win - 1), | 5188 | (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1), |
5070 | (int)cy_pci_irq); | 5189 | (int)cy_pci_irq); |
5071 | else | 5190 | else |
5072 | #endif /* CONFIG_CYZ_INTR */ | 5191 | #endif /* CONFIG_CYZ_INTR */ |
5073 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ", | 5192 | printk("Cyclades-Ze/PCI #%d: 0x%lx-0x%lx, ", |
5074 | j+1,(ulong)cy_pci_phys2, | 5193 | j + 1, (ulong) cy_pci_phys2, |
5075 | (ulong)(cy_pci_phys2 + CyPCI_Ze_win - 1)); | 5194 | (ulong) (cy_pci_phys2 + CyPCI_Ze_win - 1)); |
5076 | 5195 | ||
5077 | printk("%d channels starting from port %d.\n", | 5196 | printk("%d channels starting from port %d.\n", |
5078 | cy_pci_nchan,cy_next_channel); | 5197 | cy_pci_nchan, cy_next_channel); |
5079 | cy_next_channel += cy_pci_nchan; | 5198 | cy_next_channel += cy_pci_nchan; |
5080 | } | 5199 | } |
5081 | if (ZeIndex != 0) { | 5200 | if (ZeIndex != 0) { |
5082 | printk("Cyclades-Ze/PCI found at 0x%x ", | 5201 | printk("Cyclades-Ze/PCI found at 0x%x but no more cards can be " |
5083 | (unsigned int) Ze_phys2[0]); | 5202 | "used.\nChange NR_CARDS in cyclades.c and recompile " |
5084 | printk("but no more cards can be used.\n"); | 5203 | "kernel.\n", (unsigned int)Ze_phys2[0]); |
5085 | printk("Change NR_CARDS in cyclades.c and recompile kernel.\n"); | ||
5086 | } | 5204 | } |
5087 | return(i); | 5205 | return i; |
5088 | #else | 5206 | #else |
5089 | return(0); | 5207 | return 0; |
5090 | #endif /* ifdef CONFIG_PCI */ | 5208 | #endif /* ifdef CONFIG_PCI */ |
5091 | } /* cy_detect_pci */ | 5209 | } /* cy_detect_pci */ |
5092 | |||
5093 | 5210 | ||
5094 | /* | 5211 | /* |
5095 | * This routine prints out the appropriate serial driver version number | 5212 | * This routine prints out the appropriate serial driver version number |
5096 | * and identifies which options were configured into this driver. | 5213 | * and identifies which options were configured into this driver. |
5097 | */ | 5214 | */ |
5098 | static inline void | 5215 | static inline void show_version(void) |
5099 | show_version(void) | ||
5100 | { | 5216 | { |
5101 | char *rcsvers, *rcsdate, *tmp; | 5217 | printk("Cyclades driver " CY_VERSION "\n"); |
5102 | rcsvers = strchr(rcsid, ' '); rcsvers++; | 5218 | printk(" built %s %s\n", __DATE__, __TIME__); |
5103 | tmp = strchr(rcsvers, ' '); *tmp++ = '\0'; | 5219 | } /* show_version */ |
5104 | rcsdate = strchr(tmp, ' '); rcsdate++; | 5220 | |
5105 | tmp = strrchr(rcsdate, ' '); *tmp = '\0'; | 5221 | static int |
5106 | printk("Cyclades driver %s %s\n", | ||
5107 | rcsvers, rcsdate); | ||
5108 | printk(" built %s %s\n", | ||
5109 | __DATE__, __TIME__); | ||
5110 | } /* show_version */ | ||
5111 | |||
5112 | static int | ||
5113 | cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, | 5222 | cyclades_get_proc_info(char *buf, char **start, off_t offset, int length, |
5114 | int *eof, void *data) | 5223 | int *eof, void *data) |
5115 | { | 5224 | { |
5116 | struct cyclades_port *info; | 5225 | struct cyclades_port *info; |
5117 | int i; | 5226 | int i; |
5118 | int len=0; | 5227 | int len = 0; |
5119 | off_t begin=0; | 5228 | off_t begin = 0; |
5120 | off_t pos=0; | 5229 | off_t pos = 0; |
5121 | int size; | 5230 | int size; |
5122 | __u32 cur_jifs = jiffies; | 5231 | __u32 cur_jifs = jiffies; |
5123 | 5232 | ||
5124 | size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn IdleIn Overruns Ldisc\n"); | 5233 | size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn " |
5125 | 5234 | "IdleIn Overruns Ldisc\n"); | |
5126 | pos += size; | 5235 | |
5127 | len += size; | 5236 | pos += size; |
5128 | |||
5129 | /* Output one line for each known port */ | ||
5130 | for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) { | ||
5131 | info = &cy_port[i]; | ||
5132 | |||
5133 | if (info->count) | ||
5134 | size = sprintf(buf+len, | ||
5135 | "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n", | ||
5136 | info->line, | ||
5137 | JIFFIES_DIFF(info->idle_stats.in_use, cur_jifs) / HZ, | ||
5138 | info->idle_stats.xmit_bytes, | ||
5139 | JIFFIES_DIFF(info->idle_stats.xmit_idle, cur_jifs) / HZ, | ||
5140 | info->idle_stats.recv_bytes, | ||
5141 | JIFFIES_DIFF(info->idle_stats.recv_idle, cur_jifs) / HZ, | ||
5142 | info->idle_stats.overruns, | ||
5143 | (long) info->tty->ldisc.num); | ||
5144 | else | ||
5145 | size = sprintf(buf+len, | ||
5146 | "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n", | ||
5147 | info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); | ||
5148 | len += size; | 5237 | len += size; |
5149 | pos = begin + len; | ||
5150 | 5238 | ||
5151 | if (pos < offset) { | 5239 | /* Output one line for each known port */ |
5152 | len = 0; | 5240 | for (i = 0; i < NR_PORTS && cy_port[i].line >= 0; i++) { |
5153 | begin = pos; | 5241 | info = &cy_port[i]; |
5242 | |||
5243 | if (info->count) | ||
5244 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " | ||
5245 | "%8lu %9lu %6ld\n", info->line, | ||
5246 | (cur_jifs - info->idle_stats.in_use) / HZ, | ||
5247 | info->idle_stats.xmit_bytes, | ||
5248 | (cur_jifs - info->idle_stats.xmit_idle) / HZ, | ||
5249 | info->idle_stats.recv_bytes, | ||
5250 | (cur_jifs - info->idle_stats.recv_idle) / HZ, | ||
5251 | info->idle_stats.overruns, | ||
5252 | (long)info->tty->ldisc.num); | ||
5253 | else | ||
5254 | size = sprintf(buf + len, "%3d %8lu %10lu %8lu %10lu " | ||
5255 | "%8lu %9lu %6ld\n", | ||
5256 | info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L); | ||
5257 | len += size; | ||
5258 | pos = begin + len; | ||
5259 | |||
5260 | if (pos < offset) { | ||
5261 | len = 0; | ||
5262 | begin = pos; | ||
5263 | } | ||
5264 | if (pos > offset + length) | ||
5265 | goto done; | ||
5154 | } | 5266 | } |
5155 | if (pos > offset + length) | 5267 | *eof = 1; |
5156 | goto done; | ||
5157 | } | ||
5158 | *eof = 1; | ||
5159 | done: | 5268 | done: |
5160 | *start = buf + (offset - begin); /* Start of wanted data */ | 5269 | *start = buf + (offset - begin); /* Start of wanted data */ |
5161 | len -= (offset - begin); /* Start slop */ | 5270 | len -= (offset - begin); /* Start slop */ |
5162 | if (len > length) | 5271 | if (len > length) |
5163 | len = length; /* Ending slop */ | 5272 | len = length; /* Ending slop */ |
5164 | if (len < 0) | 5273 | if (len < 0) |
5165 | len = 0; | 5274 | len = 0; |
5166 | return len; | 5275 | return len; |
5167 | } | 5276 | } |
5168 | 5277 | ||
5169 | /* The serial driver boot-time initialization code! | 5278 | /* The serial driver boot-time initialization code! |
@@ -5185,290 +5294,288 @@ done: | |||
5185 | */ | 5294 | */ |
5186 | 5295 | ||
5187 | static const struct tty_operations cy_ops = { | 5296 | static const struct tty_operations cy_ops = { |
5188 | .open = cy_open, | 5297 | .open = cy_open, |
5189 | .close = cy_close, | 5298 | .close = cy_close, |
5190 | .write = cy_write, | 5299 | .write = cy_write, |
5191 | .put_char = cy_put_char, | 5300 | .put_char = cy_put_char, |
5192 | .flush_chars = cy_flush_chars, | 5301 | .flush_chars = cy_flush_chars, |
5193 | .write_room = cy_write_room, | 5302 | .write_room = cy_write_room, |
5194 | .chars_in_buffer = cy_chars_in_buffer, | 5303 | .chars_in_buffer = cy_chars_in_buffer, |
5195 | .flush_buffer = cy_flush_buffer, | 5304 | .flush_buffer = cy_flush_buffer, |
5196 | .ioctl = cy_ioctl, | 5305 | .ioctl = cy_ioctl, |
5197 | .throttle = cy_throttle, | 5306 | .throttle = cy_throttle, |
5198 | .unthrottle = cy_unthrottle, | 5307 | .unthrottle = cy_unthrottle, |
5199 | .set_termios = cy_set_termios, | 5308 | .set_termios = cy_set_termios, |
5200 | .stop = cy_stop, | 5309 | .stop = cy_stop, |
5201 | .start = cy_start, | 5310 | .start = cy_start, |
5202 | .hangup = cy_hangup, | 5311 | .hangup = cy_hangup, |
5203 | .break_ctl = cy_break, | 5312 | .break_ctl = cy_break, |
5204 | .wait_until_sent = cy_wait_until_sent, | 5313 | .wait_until_sent = cy_wait_until_sent, |
5205 | .read_proc = cyclades_get_proc_info, | 5314 | .read_proc = cyclades_get_proc_info, |
5206 | .tiocmget = cy_tiocmget, | 5315 | .tiocmget = cy_tiocmget, |
5207 | .tiocmset = cy_tiocmset, | 5316 | .tiocmset = cy_tiocmset, |
5208 | }; | 5317 | }; |
5209 | 5318 | ||
5210 | static int __init | 5319 | static int __init cy_init(void) |
5211 | cy_init(void) | ||
5212 | { | 5320 | { |
5213 | struct cyclades_port *info; | 5321 | struct cyclades_port *info; |
5214 | struct cyclades_card *cinfo; | 5322 | struct cyclades_card *cinfo; |
5215 | int number_z_boards = 0; | 5323 | int number_z_boards = 0; |
5216 | int board,port,i,index; | 5324 | int board, port, i, index; |
5217 | unsigned long mailbox; | 5325 | unsigned long mailbox; |
5218 | unsigned short chip_number; | 5326 | unsigned short chip_number; |
5219 | int nports; | 5327 | int nports; |
5220 | 5328 | ||
5221 | cy_serial_driver = alloc_tty_driver(NR_PORTS); | 5329 | cy_serial_driver = alloc_tty_driver(NR_PORTS); |
5222 | if (!cy_serial_driver) | 5330 | if (!cy_serial_driver) |
5223 | return -ENOMEM; | 5331 | return -ENOMEM; |
5224 | show_version(); | 5332 | show_version(); |
5225 | 5333 | ||
5226 | /* Initialize the tty_driver structure */ | 5334 | /* Initialize the tty_driver structure */ |
5227 | 5335 | ||
5228 | cy_serial_driver->owner = THIS_MODULE; | 5336 | cy_serial_driver->owner = THIS_MODULE; |
5229 | cy_serial_driver->driver_name = "cyclades"; | 5337 | cy_serial_driver->driver_name = "cyclades"; |
5230 | cy_serial_driver->name = "ttyC"; | 5338 | cy_serial_driver->name = "ttyC"; |
5231 | cy_serial_driver->major = CYCLADES_MAJOR; | 5339 | cy_serial_driver->major = CYCLADES_MAJOR; |
5232 | cy_serial_driver->minor_start = 0; | 5340 | cy_serial_driver->minor_start = 0; |
5233 | cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | 5341 | cy_serial_driver->type = TTY_DRIVER_TYPE_SERIAL; |
5234 | cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; | 5342 | cy_serial_driver->subtype = SERIAL_TYPE_NORMAL; |
5235 | cy_serial_driver->init_termios = tty_std_termios; | 5343 | cy_serial_driver->init_termios = tty_std_termios; |
5236 | cy_serial_driver->init_termios.c_cflag = | 5344 | cy_serial_driver->init_termios.c_cflag = |
5237 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 5345 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
5238 | cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; | 5346 | cy_serial_driver->flags = TTY_DRIVER_REAL_RAW; |
5239 | tty_set_operations(cy_serial_driver, &cy_ops); | 5347 | tty_set_operations(cy_serial_driver, &cy_ops); |
5240 | 5348 | ||
5241 | if (tty_register_driver(cy_serial_driver)) | 5349 | if (tty_register_driver(cy_serial_driver)) |
5242 | panic("Couldn't register Cyclades serial driver\n"); | 5350 | panic("Couldn't register Cyclades serial driver\n"); |
5243 | 5351 | ||
5244 | for (i = 0; i < NR_CARDS; i++) { | 5352 | for (i = 0; i < NR_CARDS; i++) { |
5245 | /* base_addr=0 indicates board not found */ | 5353 | /* base_addr=0 indicates board not found */ |
5246 | cy_card[i].base_addr = NULL; | 5354 | cy_card[i].base_addr = NULL; |
5247 | } | 5355 | } |
5248 | 5356 | ||
5249 | /* the code below is responsible to find the boards. Each different | 5357 | /* the code below is responsible to find the boards. Each different |
5250 | type of board has its own detection routine. If a board is found, | 5358 | type of board has its own detection routine. If a board is found, |
5251 | the next cy_card structure available is set by the detection | 5359 | the next cy_card structure available is set by the detection |
5252 | routine. These functions are responsible for checking the | 5360 | routine. These functions are responsible for checking the |
5253 | availability of cy_card and cy_port data structures and updating | 5361 | availability of cy_card and cy_port data structures and updating |
5254 | the cy_next_channel. */ | 5362 | the cy_next_channel. */ |
5255 | 5363 | ||
5256 | /* look for isa boards */ | 5364 | /* look for isa boards */ |
5257 | cy_isa_nboard = cy_detect_isa(); | 5365 | cy_isa_nboard = cy_detect_isa(); |
5258 | 5366 | ||
5259 | /* look for pci boards */ | 5367 | /* look for pci boards */ |
5260 | cy_pci_nboard = cy_detect_pci(); | 5368 | cy_pci_nboard = cy_detect_pci(); |
5261 | 5369 | ||
5262 | cy_nboard = cy_isa_nboard + cy_pci_nboard; | 5370 | cy_nboard = cy_isa_nboard + cy_pci_nboard; |
5263 | 5371 | ||
5264 | /* invalidate remaining cy_card structures */ | 5372 | /* invalidate remaining cy_card structures */ |
5265 | for (i = 0 ; i < NR_CARDS ; i++) { | 5373 | for (i = 0; i < NR_CARDS; i++) { |
5266 | if (cy_card[i].base_addr == 0) { | 5374 | if (cy_card[i].base_addr == 0) { |
5267 | cy_card[i].first_line = -1; | 5375 | cy_card[i].first_line = -1; |
5268 | cy_card[i].ctl_addr = NULL; | 5376 | cy_card[i].ctl_addr = NULL; |
5269 | cy_card[i].irq = 0; | 5377 | cy_card[i].irq = 0; |
5270 | cy_card[i].bus_index = 0; | 5378 | cy_card[i].bus_index = 0; |
5271 | cy_card[i].first_line = 0; | 5379 | cy_card[i].first_line = 0; |
5272 | cy_card[i].num_chips = 0; | 5380 | cy_card[i].num_chips = 0; |
5273 | } | 5381 | } |
5274 | } | 5382 | } |
5275 | /* invalidate remaining cy_port structures */ | 5383 | /* invalidate remaining cy_port structures */ |
5276 | for (i = cy_next_channel ; i < NR_PORTS ; i++) { | 5384 | for (i = cy_next_channel; i < NR_PORTS; i++) { |
5277 | cy_port[i].line = -1; | 5385 | cy_port[i].line = -1; |
5278 | cy_port[i].magic = -1; | 5386 | cy_port[i].magic = -1; |
5279 | } | 5387 | } |
5280 | 5388 | ||
5281 | /* initialize per-port data structures for each valid board found */ | 5389 | /* initialize per-port data structures for each valid board found */ |
5282 | for (board = 0 ; board < cy_nboard ; board++) { | 5390 | for (board = 0; board < cy_nboard; board++) { |
5283 | cinfo = &cy_card[board]; | 5391 | cinfo = &cy_card[board]; |
5284 | if (cinfo->num_chips == -1) { /* Cyclades-Z */ | 5392 | if (cinfo->num_chips == -1) { /* Cyclades-Z */ |
5285 | number_z_boards++; | 5393 | number_z_boards++; |
5286 | mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *) | 5394 | mailbox = cy_readl(&((struct RUNTIME_9060 __iomem *) |
5287 | cy_card[board].ctl_addr)->mail_box_0); | 5395 | cy_card[board].ctl_addr)-> |
5288 | nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; | 5396 | mail_box_0); |
5289 | cinfo->intr_enabled = 0; | 5397 | nports = (mailbox == ZE_V1) ? ZE_V1_NPORTS : 8; |
5290 | cinfo->nports = 0; /* Will be correctly set later, after | 5398 | cinfo->intr_enabled = 0; |
5291 | Z FW is loaded */ | 5399 | cinfo->nports = 0; /* Will be correctly set later, after |
5292 | spin_lock_init(&cinfo->card_lock); | 5400 | Z FW is loaded */ |
5293 | for (port = cinfo->first_line ; | 5401 | spin_lock_init(&cinfo->card_lock); |
5294 | port < cinfo->first_line + nports; | 5402 | for (port = cinfo->first_line; |
5295 | port++) | 5403 | port < cinfo->first_line + nports; port++) { |
5296 | { | 5404 | info = &cy_port[port]; |
5297 | info = &cy_port[port]; | 5405 | info->magic = CYCLADES_MAGIC; |
5298 | info->magic = CYCLADES_MAGIC; | 5406 | info->type = PORT_STARTECH; |
5299 | info->type = PORT_STARTECH; | 5407 | info->card = board; |
5300 | info->card = board; | 5408 | info->line = port; |
5301 | info->line = port; | 5409 | info->chip_rev = 0; |
5302 | info->chip_rev = 0; | 5410 | info->flags = STD_COM_FLAGS; |
5303 | info->flags = STD_COM_FLAGS; | 5411 | info->tty = NULL; |
5304 | info->tty = NULL; | 5412 | if (mailbox == ZO_V1) |
5305 | if (mailbox == ZO_V1) | 5413 | info->xmit_fifo_size = CYZ_FIFO_SIZE; |
5306 | info->xmit_fifo_size = CYZ_FIFO_SIZE; | 5414 | else |
5307 | else | 5415 | info->xmit_fifo_size = |
5308 | info->xmit_fifo_size = 4 * CYZ_FIFO_SIZE; | 5416 | 4 * CYZ_FIFO_SIZE; |
5309 | info->cor1 = 0; | 5417 | info->cor1 = 0; |
5310 | info->cor2 = 0; | 5418 | info->cor2 = 0; |
5311 | info->cor3 = 0; | 5419 | info->cor3 = 0; |
5312 | info->cor4 = 0; | 5420 | info->cor4 = 0; |
5313 | info->cor5 = 0; | 5421 | info->cor5 = 0; |
5314 | info->tbpr = 0; | 5422 | info->tbpr = 0; |
5315 | info->tco = 0; | 5423 | info->tco = 0; |
5316 | info->rbpr = 0; | 5424 | info->rbpr = 0; |
5317 | info->rco = 0; | 5425 | info->rco = 0; |
5318 | info->custom_divisor = 0; | 5426 | info->custom_divisor = 0; |
5319 | info->close_delay = 5*HZ/10; | 5427 | info->close_delay = 5 * HZ / 10; |
5320 | info->closing_wait = CLOSING_WAIT_DELAY; | 5428 | info->closing_wait = CLOSING_WAIT_DELAY; |
5321 | info->icount.cts = info->icount.dsr = | 5429 | info->icount.cts = info->icount.dsr = |
5322 | info->icount.rng = info->icount.dcd = 0; | 5430 | info->icount.rng = info->icount.dcd = 0; |
5323 | info->icount.rx = info->icount.tx = 0; | 5431 | info->icount.rx = info->icount.tx = 0; |
5324 | info->icount.frame = info->icount.parity = 0; | 5432 | info->icount.frame = info->icount.parity = 0; |
5325 | info->icount.overrun = info->icount.brk = 0; | 5433 | info->icount.overrun = info->icount.brk = 0; |
5326 | info->x_char = 0; | 5434 | info->x_char = 0; |
5327 | info->event = 0; | 5435 | info->event = 0; |
5328 | info->count = 0; | 5436 | info->count = 0; |
5329 | info->blocked_open = 0; | 5437 | info->blocked_open = 0; |
5330 | info->default_threshold = 0; | 5438 | info->default_threshold = 0; |
5331 | info->default_timeout = 0; | 5439 | info->default_timeout = 0; |
5332 | INIT_WORK(&info->tqueue, do_softint); | 5440 | INIT_WORK(&info->tqueue, do_softint); |
5333 | init_waitqueue_head(&info->open_wait); | 5441 | init_waitqueue_head(&info->open_wait); |
5334 | init_waitqueue_head(&info->close_wait); | 5442 | init_waitqueue_head(&info->close_wait); |
5335 | init_waitqueue_head(&info->shutdown_wait); | 5443 | init_waitqueue_head(&info->shutdown_wait); |
5336 | init_waitqueue_head(&info->delta_msr_wait); | 5444 | init_waitqueue_head(&info->delta_msr_wait); |
5337 | /* info->session */ | 5445 | /* info->session */ |
5338 | /* info->pgrp */ | 5446 | /* info->pgrp */ |
5339 | info->read_status_mask = 0; | 5447 | info->read_status_mask = 0; |
5340 | /* info->timeout */ | 5448 | /* info->timeout */ |
5341 | /* Bentson's vars */ | 5449 | /* Bentson's vars */ |
5342 | info->jiffies[0] = 0; | 5450 | info->jiffies[0] = 0; |
5343 | info->jiffies[1] = 0; | 5451 | info->jiffies[1] = 0; |
5344 | info->jiffies[2] = 0; | 5452 | info->jiffies[2] = 0; |
5345 | info->rflush_count = 0; | 5453 | info->rflush_count = 0; |
5346 | #ifdef CONFIG_CYZ_INTR | 5454 | #ifdef CONFIG_CYZ_INTR |
5347 | init_timer(&cyz_rx_full_timer[port]); | 5455 | init_timer(&cyz_rx_full_timer[port]); |
5348 | cyz_rx_full_timer[port].function = NULL; | 5456 | cyz_rx_full_timer[port].function = NULL; |
5349 | #endif | 5457 | #endif |
5350 | } | 5458 | } |
5351 | continue; | 5459 | continue; |
5352 | }else{ /* Cyclom-Y of some kind*/ | 5460 | } else { /* Cyclom-Y of some kind */ |
5353 | index = cinfo->bus_index; | 5461 | index = cinfo->bus_index; |
5354 | spin_lock_init(&cinfo->card_lock); | 5462 | spin_lock_init(&cinfo->card_lock); |
5355 | cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; | 5463 | cinfo->nports = CyPORTS_PER_CHIP * cinfo->num_chips; |
5356 | for (port = cinfo->first_line ; | 5464 | for (port = cinfo->first_line; |
5357 | port < cinfo->first_line + cinfo->nports ; | 5465 | port < cinfo->first_line + cinfo->nports; port++) { |
5358 | port++) | 5466 | info = &cy_port[port]; |
5359 | { | 5467 | info->magic = CYCLADES_MAGIC; |
5360 | info = &cy_port[port]; | 5468 | info->type = PORT_CIRRUS; |
5361 | info->magic = CYCLADES_MAGIC; | 5469 | info->card = board; |
5362 | info->type = PORT_CIRRUS; | 5470 | info->line = port; |
5363 | info->card = board; | 5471 | info->flags = STD_COM_FLAGS; |
5364 | info->line = port; | 5472 | info->tty = NULL; |
5365 | info->flags = STD_COM_FLAGS; | 5473 | info->xmit_fifo_size = CyMAX_CHAR_FIFO; |
5366 | info->tty = NULL; | 5474 | info->cor1 = |
5367 | info->xmit_fifo_size = CyMAX_CHAR_FIFO; | 5475 | CyPARITY_NONE | Cy_1_STOP | Cy_8_BITS; |
5368 | info->cor1 = CyPARITY_NONE|Cy_1_STOP|Cy_8_BITS; | 5476 | info->cor2 = CyETC; |
5369 | info->cor2 = CyETC; | 5477 | info->cor3 = 0x08; /* _very_ small rcv threshold */ |
5370 | info->cor3 = 0x08; /* _very_ small rcv threshold */ | 5478 | info->cor4 = 0; |
5371 | info->cor4 = 0; | 5479 | info->cor5 = 0; |
5372 | info->cor5 = 0; | 5480 | info->custom_divisor = 0; |
5373 | info->custom_divisor = 0; | 5481 | info->close_delay = 5 * HZ / 10; |
5374 | info->close_delay = 5*HZ/10; | 5482 | info->closing_wait = CLOSING_WAIT_DELAY; |
5375 | info->closing_wait = CLOSING_WAIT_DELAY; | 5483 | info->icount.cts = info->icount.dsr = |
5376 | info->icount.cts = info->icount.dsr = | 5484 | info->icount.rng = info->icount.dcd = 0; |
5377 | info->icount.rng = info->icount.dcd = 0; | 5485 | info->icount.rx = info->icount.tx = 0; |
5378 | info->icount.rx = info->icount.tx = 0; | 5486 | info->icount.frame = info->icount.parity = 0; |
5379 | info->icount.frame = info->icount.parity = 0; | 5487 | info->icount.overrun = info->icount.brk = 0; |
5380 | info->icount.overrun = info->icount.brk = 0; | 5488 | chip_number = (port - cinfo->first_line) / 4; |
5381 | chip_number = (port - cinfo->first_line) / 4; | 5489 | if ((info->chip_rev = |
5382 | if ((info->chip_rev = | 5490 | cy_readb(cinfo->base_addr + |
5383 | cy_readb(cinfo->base_addr + | 5491 | (cy_chip_offset[chip_number] << |
5384 | (cy_chip_offset[chip_number]<<index) + | 5492 | index) + (CyGFRCR << index))) >= |
5385 | (CyGFRCR<<index))) >= CD1400_REV_J) { | 5493 | CD1400_REV_J) { |
5386 | /* It is a CD1400 rev. J or later */ | 5494 | /* It is a CD1400 rev. J or later */ |
5387 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ | 5495 | info->tbpr = baud_bpr_60[13]; /* Tx BPR */ |
5388 | info->tco = baud_co_60[13]; /* Tx CO */ | 5496 | info->tco = baud_co_60[13]; /* Tx CO */ |
5389 | info->rbpr = baud_bpr_60[13]; /* Rx BPR */ | 5497 | info->rbpr = baud_bpr_60[13]; /* Rx BPR */ |
5390 | info->rco = baud_co_60[13]; /* Rx CO */ | 5498 | info->rco = baud_co_60[13]; /* Rx CO */ |
5391 | info->rflow = 0; | 5499 | info->rflow = 0; |
5392 | info->rtsdtr_inv = 1; | 5500 | info->rtsdtr_inv = 1; |
5393 | } else { | 5501 | } else { |
5394 | info->tbpr = baud_bpr_25[13]; /* Tx BPR */ | 5502 | info->tbpr = baud_bpr_25[13]; /* Tx BPR */ |
5395 | info->tco = baud_co_25[13]; /* Tx CO */ | 5503 | info->tco = baud_co_25[13]; /* Tx CO */ |
5396 | info->rbpr = baud_bpr_25[13]; /* Rx BPR */ | 5504 | info->rbpr = baud_bpr_25[13]; /* Rx BPR */ |
5397 | info->rco = baud_co_25[13]; /* Rx CO */ | 5505 | info->rco = baud_co_25[13]; /* Rx CO */ |
5398 | info->rflow = 0; | 5506 | info->rflow = 0; |
5399 | info->rtsdtr_inv = 0; | 5507 | info->rtsdtr_inv = 0; |
5400 | } | 5508 | } |
5401 | info->x_char = 0; | 5509 | info->x_char = 0; |
5402 | info->event = 0; | 5510 | info->event = 0; |
5403 | info->count = 0; | 5511 | info->count = 0; |
5404 | info->blocked_open = 0; | 5512 | info->blocked_open = 0; |
5405 | info->default_threshold = 0; | 5513 | info->default_threshold = 0; |
5406 | info->default_timeout = 0; | 5514 | info->default_timeout = 0; |
5407 | INIT_WORK(&info->tqueue, do_softint); | 5515 | INIT_WORK(&info->tqueue, do_softint); |
5408 | init_waitqueue_head(&info->open_wait); | 5516 | init_waitqueue_head(&info->open_wait); |
5409 | init_waitqueue_head(&info->close_wait); | 5517 | init_waitqueue_head(&info->close_wait); |
5410 | init_waitqueue_head(&info->shutdown_wait); | 5518 | init_waitqueue_head(&info->shutdown_wait); |
5411 | init_waitqueue_head(&info->delta_msr_wait); | 5519 | init_waitqueue_head(&info->delta_msr_wait); |
5412 | /* info->session */ | 5520 | /* info->session */ |
5413 | /* info->pgrp */ | 5521 | /* info->pgrp */ |
5414 | info->read_status_mask = | 5522 | info->read_status_mask = |
5415 | CyTIMEOUT| CySPECHAR| CyBREAK | 5523 | CyTIMEOUT | CySPECHAR | CyBREAK |
5416 | | CyPARITY| CyFRAME| CyOVERRUN; | 5524 | | CyPARITY | CyFRAME | CyOVERRUN; |
5417 | /* info->timeout */ | 5525 | /* info->timeout */ |
5418 | } | 5526 | } |
5419 | } | 5527 | } |
5420 | } | 5528 | } |
5421 | 5529 | ||
5422 | #ifndef CONFIG_CYZ_INTR | 5530 | #ifndef CONFIG_CYZ_INTR |
5423 | if (number_z_boards && !cyz_timeron){ | 5531 | if (number_z_boards && !cyz_timeron) { |
5424 | cyz_timeron++; | 5532 | cyz_timeron++; |
5425 | cyz_timerlist.expires = jiffies + 1; | 5533 | cyz_timerlist.expires = jiffies + 1; |
5426 | add_timer(&cyz_timerlist); | 5534 | add_timer(&cyz_timerlist); |
5427 | #ifdef CY_PCI_DEBUG | 5535 | #ifdef CY_PCI_DEBUG |
5428 | printk("Cyclades-Z polling initialized\n"); | 5536 | printk("Cyclades-Z polling initialized\n"); |
5429 | #endif | 5537 | #endif |
5430 | } | 5538 | } |
5431 | #endif /* CONFIG_CYZ_INTR */ | 5539 | #endif /* CONFIG_CYZ_INTR */ |
5540 | |||
5541 | return 0; | ||
5432 | 5542 | ||
5433 | return 0; | 5543 | } /* cy_init */ |
5434 | |||
5435 | } /* cy_init */ | ||
5436 | 5544 | ||
5437 | static void __exit | 5545 | static void __exit cy_cleanup_module(void) |
5438 | cy_cleanup_module(void) | ||
5439 | { | 5546 | { |
5440 | int i, e1; | 5547 | int i, e1; |
5441 | 5548 | ||
5442 | #ifndef CONFIG_CYZ_INTR | 5549 | #ifndef CONFIG_CYZ_INTR |
5443 | if (cyz_timeron){ | 5550 | if (cyz_timeron){ |
5444 | cyz_timeron = 0; | 5551 | cyz_timeron = 0; |
5445 | del_timer(&cyz_timerlist); | 5552 | del_timer(&cyz_timerlist); |
5446 | } | 5553 | } |
5447 | #endif /* CONFIG_CYZ_INTR */ | 5554 | #endif /* CONFIG_CYZ_INTR */ |
5448 | 5555 | ||
5449 | if ((e1 = tty_unregister_driver(cy_serial_driver))) | 5556 | if ((e1 = tty_unregister_driver(cy_serial_driver))) |
5450 | printk("cyc: failed to unregister Cyclades serial driver(%d)\n", | 5557 | printk("cyc: failed to unregister Cyclades serial driver(%d)\n", |
5451 | e1); | 5558 | e1); |
5452 | 5559 | ||
5453 | put_tty_driver(cy_serial_driver); | 5560 | put_tty_driver(cy_serial_driver); |
5454 | 5561 | ||
5455 | for (i = 0; i < NR_CARDS; i++) { | 5562 | for (i = 0; i < NR_CARDS; i++) { |
5456 | if (cy_card[i].base_addr) { | 5563 | if (cy_card[i].base_addr) { |
5457 | iounmap(cy_card[i].base_addr); | 5564 | iounmap(cy_card[i].base_addr); |
5458 | if (cy_card[i].ctl_addr) | 5565 | if (cy_card[i].ctl_addr) |
5459 | iounmap(cy_card[i].ctl_addr); | 5566 | iounmap(cy_card[i].ctl_addr); |
5460 | if (cy_card[i].irq | 5567 | if (cy_card[i].irq |
5461 | #ifndef CONFIG_CYZ_INTR | 5568 | #ifndef CONFIG_CYZ_INTR |
5462 | && cy_card[i].num_chips != -1 /* not a Z card */ | 5569 | && cy_card[i].num_chips != -1 /* not a Z card */ |
5463 | #endif /* CONFIG_CYZ_INTR */ | 5570 | #endif /* CONFIG_CYZ_INTR */ |
5464 | ) | 5571 | ) |
5465 | free_irq(cy_card[i].irq, &cy_card[i]); | 5572 | free_irq(cy_card[i].irq, &cy_card[i]); |
5466 | #ifdef CONFIG_PCI | 5573 | #ifdef CONFIG_PCI |
5467 | if (cy_card[i].pdev) | 5574 | if (cy_card[i].pdev) |
5468 | pci_release_regions(cy_card[i].pdev); | 5575 | pci_release_regions(cy_card[i].pdev); |
5469 | #endif | 5576 | #endif |
5470 | } | 5577 | } |
5471 | } | 5578 | } |
5472 | } /* cy_cleanup_module */ | 5579 | } /* cy_cleanup_module */ |
5473 | 5580 | ||
5474 | module_init(cy_init); | 5581 | module_init(cy_init); |
diff --git a/drivers/char/decserial.c b/drivers/char/decserial.c index 85f404e25c73..8ea2bea2b183 100644 --- a/drivers/char/decserial.c +++ b/drivers/char/decserial.c | |||
@@ -23,20 +23,12 @@ | |||
23 | extern int zs_init(void); | 23 | extern int zs_init(void); |
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #ifdef CONFIG_DZ | ||
27 | extern int dz_init(void); | ||
28 | #endif | ||
29 | |||
30 | #ifdef CONFIG_SERIAL_CONSOLE | 26 | #ifdef CONFIG_SERIAL_CONSOLE |
31 | 27 | ||
32 | #ifdef CONFIG_ZS | 28 | #ifdef CONFIG_ZS |
33 | extern void zs_serial_console_init(void); | 29 | extern void zs_serial_console_init(void); |
34 | #endif | 30 | #endif |
35 | 31 | ||
36 | #ifdef CONFIG_DZ | ||
37 | extern void dz_serial_console_init(void); | ||
38 | #endif | ||
39 | |||
40 | #endif | 32 | #endif |
41 | 33 | ||
42 | /* rs_init - starts up the serial interface - | 34 | /* rs_init - starts up the serial interface - |
@@ -46,23 +38,11 @@ extern void dz_serial_console_init(void); | |||
46 | 38 | ||
47 | int __init rs_init(void) | 39 | int __init rs_init(void) |
48 | { | 40 | { |
49 | 41 | #ifdef CONFIG_ZS | |
50 | #if defined(CONFIG_ZS) && defined(CONFIG_DZ) | ||
51 | if (IOASIC) | 42 | if (IOASIC) |
52 | return zs_init(); | 43 | return zs_init(); |
53 | else | ||
54 | return dz_init(); | ||
55 | #else | ||
56 | |||
57 | #ifdef CONFIG_ZS | ||
58 | return zs_init(); | ||
59 | #endif | ||
60 | |||
61 | #ifdef CONFIG_DZ | ||
62 | return dz_init(); | ||
63 | #endif | ||
64 | |||
65 | #endif | 44 | #endif |
45 | return -ENXIO; | ||
66 | } | 46 | } |
67 | 47 | ||
68 | __initcall(rs_init); | 48 | __initcall(rs_init); |
@@ -76,21 +56,9 @@ __initcall(rs_init); | |||
76 | */ | 56 | */ |
77 | static int __init decserial_console_init(void) | 57 | static int __init decserial_console_init(void) |
78 | { | 58 | { |
79 | #if defined(CONFIG_ZS) && defined(CONFIG_DZ) | 59 | #ifdef CONFIG_ZS |
80 | if (IOASIC) | 60 | if (IOASIC) |
81 | zs_serial_console_init(); | 61 | zs_serial_console_init(); |
82 | else | ||
83 | dz_serial_console_init(); | ||
84 | #else | ||
85 | |||
86 | #ifdef CONFIG_ZS | ||
87 | zs_serial_console_init(); | ||
88 | #endif | ||
89 | |||
90 | #ifdef CONFIG_DZ | ||
91 | dz_serial_console_init(); | ||
92 | #endif | ||
93 | |||
94 | #endif | 62 | #endif |
95 | return 0; | 63 | return 0; |
96 | } | 64 | } |
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c index d4f874520082..fafeb34f89d5 100644 --- a/drivers/char/drm/drm_ioc32.c +++ b/drivers/char/drm/drm_ioc32.c | |||
@@ -102,7 +102,7 @@ static int compat_drm_version(struct file *file, unsigned int cmd, | |||
102 | &version->desc)) | 102 | &version->desc)) |
103 | return -EFAULT; | 103 | return -EFAULT; |
104 | 104 | ||
105 | err = drm_ioctl(file->f_dentry->d_inode, file, | 105 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
106 | DRM_IOCTL_VERSION, (unsigned long)version); | 106 | DRM_IOCTL_VERSION, (unsigned long)version); |
107 | if (err) | 107 | if (err) |
108 | return err; | 108 | return err; |
@@ -143,7 +143,7 @@ static int compat_drm_getunique(struct file *file, unsigned int cmd, | |||
143 | &u->unique)) | 143 | &u->unique)) |
144 | return -EFAULT; | 144 | return -EFAULT; |
145 | 145 | ||
146 | err = drm_ioctl(file->f_dentry->d_inode, file, | 146 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
147 | DRM_IOCTL_GET_UNIQUE, (unsigned long)u); | 147 | DRM_IOCTL_GET_UNIQUE, (unsigned long)u); |
148 | if (err) | 148 | if (err) |
149 | return err; | 149 | return err; |
@@ -172,7 +172,7 @@ static int compat_drm_setunique(struct file *file, unsigned int cmd, | |||
172 | &u->unique)) | 172 | &u->unique)) |
173 | return -EFAULT; | 173 | return -EFAULT; |
174 | 174 | ||
175 | return drm_ioctl(file->f_dentry->d_inode, file, | 175 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
176 | DRM_IOCTL_SET_UNIQUE, (unsigned long)u); | 176 | DRM_IOCTL_SET_UNIQUE, (unsigned long)u); |
177 | } | 177 | } |
178 | 178 | ||
@@ -203,7 +203,7 @@ static int compat_drm_getmap(struct file *file, unsigned int cmd, | |||
203 | if (__put_user(idx, &map->offset)) | 203 | if (__put_user(idx, &map->offset)) |
204 | return -EFAULT; | 204 | return -EFAULT; |
205 | 205 | ||
206 | err = drm_ioctl(file->f_dentry->d_inode, file, | 206 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
207 | DRM_IOCTL_GET_MAP, (unsigned long)map); | 207 | DRM_IOCTL_GET_MAP, (unsigned long)map); |
208 | if (err) | 208 | if (err) |
209 | return err; | 209 | return err; |
@@ -244,7 +244,7 @@ static int compat_drm_addmap(struct file *file, unsigned int cmd, | |||
244 | || __put_user(m32.flags, &map->flags)) | 244 | || __put_user(m32.flags, &map->flags)) |
245 | return -EFAULT; | 245 | return -EFAULT; |
246 | 246 | ||
247 | err = drm_ioctl(file->f_dentry->d_inode, file, | 247 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
248 | DRM_IOCTL_ADD_MAP, (unsigned long)map); | 248 | DRM_IOCTL_ADD_MAP, (unsigned long)map); |
249 | if (err) | 249 | if (err) |
250 | return err; | 250 | return err; |
@@ -282,7 +282,7 @@ static int compat_drm_rmmap(struct file *file, unsigned int cmd, | |||
282 | if (__put_user((void *)(unsigned long)handle, &map->handle)) | 282 | if (__put_user((void *)(unsigned long)handle, &map->handle)) |
283 | return -EFAULT; | 283 | return -EFAULT; |
284 | 284 | ||
285 | return drm_ioctl(file->f_dentry->d_inode, file, | 285 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
286 | DRM_IOCTL_RM_MAP, (unsigned long)map); | 286 | DRM_IOCTL_RM_MAP, (unsigned long)map); |
287 | } | 287 | } |
288 | 288 | ||
@@ -312,7 +312,7 @@ static int compat_drm_getclient(struct file *file, unsigned int cmd, | |||
312 | if (__put_user(idx, &client->idx)) | 312 | if (__put_user(idx, &client->idx)) |
313 | return -EFAULT; | 313 | return -EFAULT; |
314 | 314 | ||
315 | err = drm_ioctl(file->f_dentry->d_inode, file, | 315 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
316 | DRM_IOCTL_GET_CLIENT, (unsigned long)client); | 316 | DRM_IOCTL_GET_CLIENT, (unsigned long)client); |
317 | if (err) | 317 | if (err) |
318 | return err; | 318 | return err; |
@@ -349,7 +349,7 @@ static int compat_drm_getstats(struct file *file, unsigned int cmd, | |||
349 | if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) | 349 | if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats))) |
350 | return -EFAULT; | 350 | return -EFAULT; |
351 | 351 | ||
352 | err = drm_ioctl(file->f_dentry->d_inode, file, | 352 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
353 | DRM_IOCTL_GET_STATS, (unsigned long)stats); | 353 | DRM_IOCTL_GET_STATS, (unsigned long)stats); |
354 | if (err) | 354 | if (err) |
355 | return err; | 355 | return err; |
@@ -393,7 +393,7 @@ static int compat_drm_addbufs(struct file *file, unsigned int cmd, | |||
393 | || __put_user(agp_start, &buf->agp_start)) | 393 | || __put_user(agp_start, &buf->agp_start)) |
394 | return -EFAULT; | 394 | return -EFAULT; |
395 | 395 | ||
396 | err = drm_ioctl(file->f_dentry->d_inode, file, | 396 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
397 | DRM_IOCTL_ADD_BUFS, (unsigned long)buf); | 397 | DRM_IOCTL_ADD_BUFS, (unsigned long)buf); |
398 | if (err) | 398 | if (err) |
399 | return err; | 399 | return err; |
@@ -425,7 +425,7 @@ static int compat_drm_markbufs(struct file *file, unsigned int cmd, | |||
425 | || __put_user(b32.high_mark, &buf->high_mark)) | 425 | || __put_user(b32.high_mark, &buf->high_mark)) |
426 | return -EFAULT; | 426 | return -EFAULT; |
427 | 427 | ||
428 | return drm_ioctl(file->f_dentry->d_inode, file, | 428 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
429 | DRM_IOCTL_MARK_BUFS, (unsigned long)buf); | 429 | DRM_IOCTL_MARK_BUFS, (unsigned long)buf); |
430 | } | 430 | } |
431 | 431 | ||
@@ -467,7 +467,7 @@ static int compat_drm_infobufs(struct file *file, unsigned int cmd, | |||
467 | || __put_user(list, &request->list)) | 467 | || __put_user(list, &request->list)) |
468 | return -EFAULT; | 468 | return -EFAULT; |
469 | 469 | ||
470 | err = drm_ioctl(file->f_dentry->d_inode, file, | 470 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
471 | DRM_IOCTL_INFO_BUFS, (unsigned long)request); | 471 | DRM_IOCTL_INFO_BUFS, (unsigned long)request); |
472 | if (err) | 472 | if (err) |
473 | return err; | 473 | return err; |
@@ -529,7 +529,7 @@ static int compat_drm_mapbufs(struct file *file, unsigned int cmd, | |||
529 | || __put_user(list, &request->list)) | 529 | || __put_user(list, &request->list)) |
530 | return -EFAULT; | 530 | return -EFAULT; |
531 | 531 | ||
532 | err = drm_ioctl(file->f_dentry->d_inode, file, | 532 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
533 | DRM_IOCTL_MAP_BUFS, (unsigned long)request); | 533 | DRM_IOCTL_MAP_BUFS, (unsigned long)request); |
534 | if (err) | 534 | if (err) |
535 | return err; | 535 | return err; |
@@ -576,7 +576,7 @@ static int compat_drm_freebufs(struct file *file, unsigned int cmd, | |||
576 | &request->list)) | 576 | &request->list)) |
577 | return -EFAULT; | 577 | return -EFAULT; |
578 | 578 | ||
579 | return drm_ioctl(file->f_dentry->d_inode, file, | 579 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
580 | DRM_IOCTL_FREE_BUFS, (unsigned long)request); | 580 | DRM_IOCTL_FREE_BUFS, (unsigned long)request); |
581 | } | 581 | } |
582 | 582 | ||
@@ -603,7 +603,7 @@ static int compat_drm_setsareactx(struct file *file, unsigned int cmd, | |||
603 | &request->handle)) | 603 | &request->handle)) |
604 | return -EFAULT; | 604 | return -EFAULT; |
605 | 605 | ||
606 | return drm_ioctl(file->f_dentry->d_inode, file, | 606 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
607 | DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); | 607 | DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request); |
608 | } | 608 | } |
609 | 609 | ||
@@ -626,7 +626,7 @@ static int compat_drm_getsareactx(struct file *file, unsigned int cmd, | |||
626 | if (__put_user(ctx_id, &request->ctx_id)) | 626 | if (__put_user(ctx_id, &request->ctx_id)) |
627 | return -EFAULT; | 627 | return -EFAULT; |
628 | 628 | ||
629 | err = drm_ioctl(file->f_dentry->d_inode, file, | 629 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
630 | DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); | 630 | DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request); |
631 | if (err) | 631 | if (err) |
632 | return err; | 632 | return err; |
@@ -662,7 +662,7 @@ static int compat_drm_resctx(struct file *file, unsigned int cmd, | |||
662 | &res->contexts)) | 662 | &res->contexts)) |
663 | return -EFAULT; | 663 | return -EFAULT; |
664 | 664 | ||
665 | err = drm_ioctl(file->f_dentry->d_inode, file, | 665 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
666 | DRM_IOCTL_RES_CTX, (unsigned long)res); | 666 | DRM_IOCTL_RES_CTX, (unsigned long)res); |
667 | if (err) | 667 | if (err) |
668 | return err; | 668 | return err; |
@@ -716,7 +716,7 @@ static int compat_drm_dma(struct file *file, unsigned int cmd, | |||
716 | &d->request_sizes)) | 716 | &d->request_sizes)) |
717 | return -EFAULT; | 717 | return -EFAULT; |
718 | 718 | ||
719 | err = drm_ioctl(file->f_dentry->d_inode, file, | 719 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
720 | DRM_IOCTL_DMA, (unsigned long)d); | 720 | DRM_IOCTL_DMA, (unsigned long)d); |
721 | if (err) | 721 | if (err) |
722 | return err; | 722 | return err; |
@@ -749,7 +749,7 @@ static int compat_drm_agp_enable(struct file *file, unsigned int cmd, | |||
749 | if (put_user(m32.mode, &mode->mode)) | 749 | if (put_user(m32.mode, &mode->mode)) |
750 | return -EFAULT; | 750 | return -EFAULT; |
751 | 751 | ||
752 | return drm_ioctl(file->f_dentry->d_inode, file, | 752 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
753 | DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); | 753 | DRM_IOCTL_AGP_ENABLE, (unsigned long)mode); |
754 | } | 754 | } |
755 | 755 | ||
@@ -779,7 +779,7 @@ static int compat_drm_agp_info(struct file *file, unsigned int cmd, | |||
779 | if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) | 779 | if (!access_ok(VERIFY_WRITE, info, sizeof(*info))) |
780 | return -EFAULT; | 780 | return -EFAULT; |
781 | 781 | ||
782 | err = drm_ioctl(file->f_dentry->d_inode, file, | 782 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
783 | DRM_IOCTL_AGP_INFO, (unsigned long)info); | 783 | DRM_IOCTL_AGP_INFO, (unsigned long)info); |
784 | if (err) | 784 | if (err) |
785 | return err; | 785 | return err; |
@@ -825,7 +825,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, | |||
825 | || __put_user(req32.type, &request->type)) | 825 | || __put_user(req32.type, &request->type)) |
826 | return -EFAULT; | 826 | return -EFAULT; |
827 | 827 | ||
828 | err = drm_ioctl(file->f_dentry->d_inode, file, | 828 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
829 | DRM_IOCTL_AGP_ALLOC, (unsigned long)request); | 829 | DRM_IOCTL_AGP_ALLOC, (unsigned long)request); |
830 | if (err) | 830 | if (err) |
831 | return err; | 831 | return err; |
@@ -833,7 +833,7 @@ static int compat_drm_agp_alloc(struct file *file, unsigned int cmd, | |||
833 | if (__get_user(req32.handle, &request->handle) | 833 | if (__get_user(req32.handle, &request->handle) |
834 | || __get_user(req32.physical, &request->physical) | 834 | || __get_user(req32.physical, &request->physical) |
835 | || copy_to_user(argp, &req32, sizeof(req32))) { | 835 | || copy_to_user(argp, &req32, sizeof(req32))) { |
836 | drm_ioctl(file->f_dentry->d_inode, file, | 836 | drm_ioctl(file->f_path.dentry->d_inode, file, |
837 | DRM_IOCTL_AGP_FREE, (unsigned long)request); | 837 | DRM_IOCTL_AGP_FREE, (unsigned long)request); |
838 | return -EFAULT; | 838 | return -EFAULT; |
839 | } | 839 | } |
@@ -854,7 +854,7 @@ static int compat_drm_agp_free(struct file *file, unsigned int cmd, | |||
854 | || __put_user(handle, &request->handle)) | 854 | || __put_user(handle, &request->handle)) |
855 | return -EFAULT; | 855 | return -EFAULT; |
856 | 856 | ||
857 | return drm_ioctl(file->f_dentry->d_inode, file, | 857 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
858 | DRM_IOCTL_AGP_FREE, (unsigned long)request); | 858 | DRM_IOCTL_AGP_FREE, (unsigned long)request); |
859 | } | 859 | } |
860 | 860 | ||
@@ -879,7 +879,7 @@ static int compat_drm_agp_bind(struct file *file, unsigned int cmd, | |||
879 | || __put_user(req32.offset, &request->offset)) | 879 | || __put_user(req32.offset, &request->offset)) |
880 | return -EFAULT; | 880 | return -EFAULT; |
881 | 881 | ||
882 | return drm_ioctl(file->f_dentry->d_inode, file, | 882 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
883 | DRM_IOCTL_AGP_BIND, (unsigned long)request); | 883 | DRM_IOCTL_AGP_BIND, (unsigned long)request); |
884 | } | 884 | } |
885 | 885 | ||
@@ -896,7 +896,7 @@ static int compat_drm_agp_unbind(struct file *file, unsigned int cmd, | |||
896 | || __put_user(handle, &request->handle)) | 896 | || __put_user(handle, &request->handle)) |
897 | return -EFAULT; | 897 | return -EFAULT; |
898 | 898 | ||
899 | return drm_ioctl(file->f_dentry->d_inode, file, | 899 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
900 | DRM_IOCTL_AGP_UNBIND, (unsigned long)request); | 900 | DRM_IOCTL_AGP_UNBIND, (unsigned long)request); |
901 | } | 901 | } |
902 | #endif /* __OS_HAS_AGP */ | 902 | #endif /* __OS_HAS_AGP */ |
@@ -921,7 +921,7 @@ static int compat_drm_sg_alloc(struct file *file, unsigned int cmd, | |||
921 | || __put_user(x, &request->size)) | 921 | || __put_user(x, &request->size)) |
922 | return -EFAULT; | 922 | return -EFAULT; |
923 | 923 | ||
924 | err = drm_ioctl(file->f_dentry->d_inode, file, | 924 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
925 | DRM_IOCTL_SG_ALLOC, (unsigned long)request); | 925 | DRM_IOCTL_SG_ALLOC, (unsigned long)request); |
926 | if (err) | 926 | if (err) |
927 | return err; | 927 | return err; |
@@ -948,7 +948,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd, | |||
948 | || __put_user(x << PAGE_SHIFT, &request->handle)) | 948 | || __put_user(x << PAGE_SHIFT, &request->handle)) |
949 | return -EFAULT; | 949 | return -EFAULT; |
950 | 950 | ||
951 | return drm_ioctl(file->f_dentry->d_inode, file, | 951 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
952 | DRM_IOCTL_SG_FREE, (unsigned long)request); | 952 | DRM_IOCTL_SG_FREE, (unsigned long)request); |
953 | } | 953 | } |
954 | 954 | ||
@@ -988,7 +988,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd, | |||
988 | || __put_user(req32.request.signal, &request->request.signal)) | 988 | || __put_user(req32.request.signal, &request->request.signal)) |
989 | return -EFAULT; | 989 | return -EFAULT; |
990 | 990 | ||
991 | err = drm_ioctl(file->f_dentry->d_inode, file, | 991 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
992 | DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); | 992 | DRM_IOCTL_WAIT_VBLANK, (unsigned long)request); |
993 | if (err) | 993 | if (err) |
994 | return err; | 994 | return err; |
@@ -1060,7 +1060,7 @@ long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
1060 | if (fn != NULL) | 1060 | if (fn != NULL) |
1061 | ret = (*fn) (filp, cmd, arg); | 1061 | ret = (*fn) (filp, cmd, arg); |
1062 | else | 1062 | else |
1063 | ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 1063 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); |
1064 | unlock_kernel(); | 1064 | unlock_kernel(); |
1065 | 1065 | ||
1066 | return ret; | 1066 | return ret; |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 74686e9a2d34..b9cfc077f6bc 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
@@ -147,14 +147,14 @@ static __inline__ struct page *drm_do_vm_shm_nopage(struct vm_area_struct *vma, | |||
147 | if (address > vma->vm_end) | 147 | if (address > vma->vm_end) |
148 | return NOPAGE_SIGBUS; /* Disallow mremap */ | 148 | return NOPAGE_SIGBUS; /* Disallow mremap */ |
149 | if (!map) | 149 | if (!map) |
150 | return NOPAGE_OOM; /* Nothing allocated */ | 150 | return NOPAGE_SIGBUS; /* Nothing allocated */ |
151 | 151 | ||
152 | offset = address - vma->vm_start; | 152 | offset = address - vma->vm_start; |
153 | i = (unsigned long)map->handle + offset; | 153 | i = (unsigned long)map->handle + offset; |
154 | page = (map->type == _DRM_CONSISTENT) ? | 154 | page = (map->type == _DRM_CONSISTENT) ? |
155 | virt_to_page((void *)i) : vmalloc_to_page((void *)i); | 155 | virt_to_page((void *)i) : vmalloc_to_page((void *)i); |
156 | if (!page) | 156 | if (!page) |
157 | return NOPAGE_OOM; | 157 | return NOPAGE_SIGBUS; |
158 | get_page(page); | 158 | get_page(page); |
159 | 159 | ||
160 | DRM_DEBUG("shm_nopage 0x%lx\n", address); | 160 | DRM_DEBUG("shm_nopage 0x%lx\n", address); |
@@ -272,7 +272,7 @@ static __inline__ struct page *drm_do_vm_dma_nopage(struct vm_area_struct *vma, | |||
272 | if (address > vma->vm_end) | 272 | if (address > vma->vm_end) |
273 | return NOPAGE_SIGBUS; /* Disallow mremap */ | 273 | return NOPAGE_SIGBUS; /* Disallow mremap */ |
274 | if (!dma->pagelist) | 274 | if (!dma->pagelist) |
275 | return NOPAGE_OOM; /* Nothing allocated */ | 275 | return NOPAGE_SIGBUS; /* Nothing allocated */ |
276 | 276 | ||
277 | offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ | 277 | offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */ |
278 | page_nr = offset >> PAGE_SHIFT; | 278 | page_nr = offset >> PAGE_SHIFT; |
@@ -310,7 +310,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma, | |||
310 | if (address > vma->vm_end) | 310 | if (address > vma->vm_end) |
311 | return NOPAGE_SIGBUS; /* Disallow mremap */ | 311 | return NOPAGE_SIGBUS; /* Disallow mremap */ |
312 | if (!entry->pagelist) | 312 | if (!entry->pagelist) |
313 | return NOPAGE_OOM; /* Nothing allocated */ | 313 | return NOPAGE_SIGBUS; /* Nothing allocated */ |
314 | 314 | ||
315 | offset = address - vma->vm_start; | 315 | offset = address - vma->vm_start; |
316 | map_offset = map->offset - (unsigned long)dev->sg->virtual; | 316 | map_offset = map->offset - (unsigned long)dev->sg->virtual; |
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c index 296248cdc767..1fe68a251b75 100644 --- a/drivers/char/drm/i915_ioc32.c +++ b/drivers/char/drm/i915_ioc32.c | |||
@@ -66,7 +66,7 @@ static int compat_i915_batchbuffer(struct file *file, unsigned int cmd, | |||
66 | &batchbuffer->cliprects)) | 66 | &batchbuffer->cliprects)) |
67 | return -EFAULT; | 67 | return -EFAULT; |
68 | 68 | ||
69 | return drm_ioctl(file->f_dentry->d_inode, file, | 69 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
70 | DRM_IOCTL_I915_BATCHBUFFER, | 70 | DRM_IOCTL_I915_BATCHBUFFER, |
71 | (unsigned long)batchbuffer); | 71 | (unsigned long)batchbuffer); |
72 | } | 72 | } |
@@ -102,7 +102,7 @@ static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd, | |||
102 | &cmdbuffer->cliprects)) | 102 | &cmdbuffer->cliprects)) |
103 | return -EFAULT; | 103 | return -EFAULT; |
104 | 104 | ||
105 | return drm_ioctl(file->f_dentry->d_inode, file, | 105 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
106 | DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer); | 106 | DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer); |
107 | } | 107 | } |
108 | 108 | ||
@@ -125,7 +125,7 @@ static int compat_i915_irq_emit(struct file *file, unsigned int cmd, | |||
125 | &request->irq_seq)) | 125 | &request->irq_seq)) |
126 | return -EFAULT; | 126 | return -EFAULT; |
127 | 127 | ||
128 | return drm_ioctl(file->f_dentry->d_inode, file, | 128 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
129 | DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request); | 129 | DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request); |
130 | } | 130 | } |
131 | typedef struct drm_i915_getparam32 { | 131 | typedef struct drm_i915_getparam32 { |
@@ -149,7 +149,7 @@ static int compat_i915_getparam(struct file *file, unsigned int cmd, | |||
149 | &request->value)) | 149 | &request->value)) |
150 | return -EFAULT; | 150 | return -EFAULT; |
151 | 151 | ||
152 | return drm_ioctl(file->f_dentry->d_inode, file, | 152 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
153 | DRM_IOCTL_I915_GETPARAM, (unsigned long)request); | 153 | DRM_IOCTL_I915_GETPARAM, (unsigned long)request); |
154 | } | 154 | } |
155 | 155 | ||
@@ -178,7 +178,7 @@ static int compat_i915_alloc(struct file *file, unsigned int cmd, | |||
178 | &request->region_offset)) | 178 | &request->region_offset)) |
179 | return -EFAULT; | 179 | return -EFAULT; |
180 | 180 | ||
181 | return drm_ioctl(file->f_dentry->d_inode, file, | 181 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
182 | DRM_IOCTL_I915_ALLOC, (unsigned long)request); | 182 | DRM_IOCTL_I915_ALLOC, (unsigned long)request); |
183 | } | 183 | } |
184 | 184 | ||
@@ -215,7 +215,7 @@ long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
215 | if (fn != NULL) | 215 | if (fn != NULL) |
216 | ret = (*fn) (filp, cmd, arg); | 216 | ret = (*fn) (filp, cmd, arg); |
217 | else | 217 | else |
218 | ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 218 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); |
219 | unlock_kernel(); | 219 | unlock_kernel(); |
220 | 220 | ||
221 | return ret; | 221 | return ret; |
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c index 54a18eb2fc04..30d00478ddee 100644 --- a/drivers/char/drm/mga_ioc32.c +++ b/drivers/char/drm/mga_ioc32.c | |||
@@ -100,7 +100,7 @@ static int compat_mga_init(struct file *file, unsigned int cmd, | |||
100 | if (err) | 100 | if (err) |
101 | return -EFAULT; | 101 | return -EFAULT; |
102 | 102 | ||
103 | return drm_ioctl(file->f_dentry->d_inode, file, | 103 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
104 | DRM_IOCTL_MGA_INIT, (unsigned long)init); | 104 | DRM_IOCTL_MGA_INIT, (unsigned long)init); |
105 | } | 105 | } |
106 | 106 | ||
@@ -125,7 +125,7 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd, | |||
125 | &getparam->value)) | 125 | &getparam->value)) |
126 | return -EFAULT; | 126 | return -EFAULT; |
127 | 127 | ||
128 | return drm_ioctl(file->f_dentry->d_inode, file, | 128 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
129 | DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); | 129 | DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); |
130 | } | 130 | } |
131 | 131 | ||
@@ -166,7 +166,7 @@ static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd, | |||
166 | || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) | 166 | || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size)) |
167 | return -EFAULT; | 167 | return -EFAULT; |
168 | 168 | ||
169 | err = drm_ioctl(file->f_dentry->d_inode, file, | 169 | err = drm_ioctl(file->f_path.dentry->d_inode, file, |
170 | DRM_IOCTL_MGA_DMA_BOOTSTRAP, | 170 | DRM_IOCTL_MGA_DMA_BOOTSTRAP, |
171 | (unsigned long)dma_bootstrap); | 171 | (unsigned long)dma_bootstrap); |
172 | if (err) | 172 | if (err) |
@@ -224,7 +224,7 @@ long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
224 | if (fn != NULL) | 224 | if (fn != NULL) |
225 | ret = (*fn) (filp, cmd, arg); | 225 | ret = (*fn) (filp, cmd, arg); |
226 | else | 226 | else |
227 | ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 227 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); |
228 | unlock_kernel(); | 228 | unlock_kernel(); |
229 | 229 | ||
230 | return ret; | 230 | return ret; |
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c index 9dd6d4116e47..d3cb676eee84 100644 --- a/drivers/char/drm/r128_ioc32.c +++ b/drivers/char/drm/r128_ioc32.c | |||
@@ -95,7 +95,7 @@ static int compat_r128_init(struct file *file, unsigned int cmd, | |||
95 | &init->agp_textures_offset)) | 95 | &init->agp_textures_offset)) |
96 | return -EFAULT; | 96 | return -EFAULT; |
97 | 97 | ||
98 | return drm_ioctl(file->f_dentry->d_inode, file, | 98 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
99 | DRM_IOCTL_R128_INIT, (unsigned long)init); | 99 | DRM_IOCTL_R128_INIT, (unsigned long)init); |
100 | } | 100 | } |
101 | 101 | ||
@@ -129,7 +129,7 @@ static int compat_r128_depth(struct file *file, unsigned int cmd, | |||
129 | &depth->mask)) | 129 | &depth->mask)) |
130 | return -EFAULT; | 130 | return -EFAULT; |
131 | 131 | ||
132 | return drm_ioctl(file->f_dentry->d_inode, file, | 132 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
133 | DRM_IOCTL_R128_DEPTH, (unsigned long)depth); | 133 | DRM_IOCTL_R128_DEPTH, (unsigned long)depth); |
134 | 134 | ||
135 | } | 135 | } |
@@ -153,7 +153,7 @@ static int compat_r128_stipple(struct file *file, unsigned int cmd, | |||
153 | &stipple->mask)) | 153 | &stipple->mask)) |
154 | return -EFAULT; | 154 | return -EFAULT; |
155 | 155 | ||
156 | return drm_ioctl(file->f_dentry->d_inode, file, | 156 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
157 | DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); | 157 | DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple); |
158 | } | 158 | } |
159 | 159 | ||
@@ -178,7 +178,7 @@ static int compat_r128_getparam(struct file *file, unsigned int cmd, | |||
178 | &getparam->value)) | 178 | &getparam->value)) |
179 | return -EFAULT; | 179 | return -EFAULT; |
180 | 180 | ||
181 | return drm_ioctl(file->f_dentry->d_inode, file, | 181 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
182 | DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); | 182 | DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam); |
183 | } | 183 | } |
184 | 184 | ||
@@ -214,7 +214,7 @@ long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
214 | if (fn != NULL) | 214 | if (fn != NULL) |
215 | ret = (*fn) (filp, cmd, arg); | 215 | ret = (*fn) (filp, cmd, arg); |
216 | else | 216 | else |
217 | ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 217 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); |
218 | unlock_kernel(); | 218 | unlock_kernel(); |
219 | 219 | ||
220 | return ret; | 220 | return ret; |
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c index 0ccfd3618ff1..1f1f9cc055a4 100644 --- a/drivers/char/drm/radeon_ioc32.c +++ b/drivers/char/drm/radeon_ioc32.c | |||
@@ -92,7 +92,7 @@ static int compat_radeon_cp_init(struct file *file, unsigned int cmd, | |||
92 | &init->gart_textures_offset)) | 92 | &init->gart_textures_offset)) |
93 | return -EFAULT; | 93 | return -EFAULT; |
94 | 94 | ||
95 | return drm_ioctl(file->f_dentry->d_inode, file, | 95 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
96 | DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); | 96 | DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init); |
97 | } | 97 | } |
98 | 98 | ||
@@ -125,7 +125,7 @@ static int compat_radeon_cp_clear(struct file *file, unsigned int cmd, | |||
125 | &clr->depth_boxes)) | 125 | &clr->depth_boxes)) |
126 | return -EFAULT; | 126 | return -EFAULT; |
127 | 127 | ||
128 | return drm_ioctl(file->f_dentry->d_inode, file, | 128 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
129 | DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); | 129 | DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr); |
130 | } | 130 | } |
131 | 131 | ||
@@ -149,7 +149,7 @@ static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd, | |||
149 | &request->mask)) | 149 | &request->mask)) |
150 | return -EFAULT; | 150 | return -EFAULT; |
151 | 151 | ||
152 | return drm_ioctl(file->f_dentry->d_inode, file, | 152 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
153 | DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); | 153 | DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request); |
154 | } | 154 | } |
155 | 155 | ||
@@ -204,7 +204,7 @@ static int compat_radeon_cp_texture(struct file *file, unsigned int cmd, | |||
204 | &image->data)) | 204 | &image->data)) |
205 | return -EFAULT; | 205 | return -EFAULT; |
206 | 206 | ||
207 | return drm_ioctl(file->f_dentry->d_inode, file, | 207 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
208 | DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); | 208 | DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request); |
209 | } | 209 | } |
210 | 210 | ||
@@ -238,7 +238,7 @@ static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd, | |||
238 | &request->prim)) | 238 | &request->prim)) |
239 | return -EFAULT; | 239 | return -EFAULT; |
240 | 240 | ||
241 | return drm_ioctl(file->f_dentry->d_inode, file, | 241 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
242 | DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); | 242 | DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request); |
243 | } | 243 | } |
244 | 244 | ||
@@ -268,7 +268,7 @@ static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd, | |||
268 | &request->boxes)) | 268 | &request->boxes)) |
269 | return -EFAULT; | 269 | return -EFAULT; |
270 | 270 | ||
271 | return drm_ioctl(file->f_dentry->d_inode, file, | 271 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
272 | DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); | 272 | DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request); |
273 | } | 273 | } |
274 | 274 | ||
@@ -293,7 +293,7 @@ static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd, | |||
293 | &request->value)) | 293 | &request->value)) |
294 | return -EFAULT; | 294 | return -EFAULT; |
295 | 295 | ||
296 | return drm_ioctl(file->f_dentry->d_inode, file, | 296 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
297 | DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); | 297 | DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request); |
298 | } | 298 | } |
299 | 299 | ||
@@ -322,7 +322,7 @@ static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd, | |||
322 | &request->region_offset)) | 322 | &request->region_offset)) |
323 | return -EFAULT; | 323 | return -EFAULT; |
324 | 324 | ||
325 | return drm_ioctl(file->f_dentry->d_inode, file, | 325 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
326 | DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); | 326 | DRM_IOCTL_RADEON_ALLOC, (unsigned long)request); |
327 | } | 327 | } |
328 | 328 | ||
@@ -345,7 +345,7 @@ static int compat_radeon_irq_emit(struct file *file, unsigned int cmd, | |||
345 | &request->irq_seq)) | 345 | &request->irq_seq)) |
346 | return -EFAULT; | 346 | return -EFAULT; |
347 | 347 | ||
348 | return drm_ioctl(file->f_dentry->d_inode, file, | 348 | return drm_ioctl(file->f_path.dentry->d_inode, file, |
349 | DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); | 349 | DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request); |
350 | } | 350 | } |
351 | 351 | ||
@@ -386,7 +386,7 @@ long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
386 | if (fn != NULL) | 386 | if (fn != NULL) |
387 | ret = (*fn) (filp, cmd, arg); | 387 | ret = (*fn) (filp, cmd, arg); |
388 | else | 388 | else |
389 | ret = drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg); | 389 | ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg); |
390 | unlock_kernel(); | 390 | unlock_kernel(); |
391 | 391 | ||
392 | return ret; | 392 | return ret; |
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c index 9b1bf60ffbe7..06f2dbf17710 100644 --- a/drivers/char/dsp56k.c +++ b/drivers/char/dsp56k.c | |||
@@ -201,7 +201,7 @@ static int dsp56k_upload(u_char __user *bin, int len) | |||
201 | static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count, | 201 | static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count, |
202 | loff_t *ppos) | 202 | loff_t *ppos) |
203 | { | 203 | { |
204 | struct inode *inode = file->f_dentry->d_inode; | 204 | struct inode *inode = file->f_path.dentry->d_inode; |
205 | int dev = iminor(inode) & 0x0f; | 205 | int dev = iminor(inode) & 0x0f; |
206 | 206 | ||
207 | switch(dev) | 207 | switch(dev) |
@@ -264,7 +264,7 @@ static ssize_t dsp56k_read(struct file *file, char __user *buf, size_t count, | |||
264 | static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t count, | 264 | static ssize_t dsp56k_write(struct file *file, const char __user *buf, size_t count, |
265 | loff_t *ppos) | 265 | loff_t *ppos) |
266 | { | 266 | { |
267 | struct inode *inode = file->f_dentry->d_inode; | 267 | struct inode *inode = file->f_path.dentry->d_inode; |
268 | int dev = iminor(inode) & 0x0f; | 268 | int dev = iminor(inode) & 0x0f; |
269 | 269 | ||
270 | switch(dev) | 270 | switch(dev) |
@@ -420,7 +420,7 @@ static int dsp56k_ioctl(struct inode *inode, struct file *file, | |||
420 | #if 0 | 420 | #if 0 |
421 | static unsigned int dsp56k_poll(struct file *file, poll_table *wait) | 421 | static unsigned int dsp56k_poll(struct file *file, poll_table *wait) |
422 | { | 422 | { |
423 | int dev = iminor(file->f_dentry->d_inode) & 0x0f; | 423 | int dev = iminor(file->f_path.dentry->d_inode) & 0x0f; |
424 | 424 | ||
425 | switch(dev) | 425 | switch(dev) |
426 | { | 426 | { |
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c index 5e82c3bad2e3..d4005e94fe5f 100644 --- a/drivers/char/dtlk.c +++ b/drivers/char/dtlk.c | |||
@@ -122,7 +122,7 @@ static void dtlk_timer_tick(unsigned long data); | |||
122 | static ssize_t dtlk_read(struct file *file, char __user *buf, | 122 | static ssize_t dtlk_read(struct file *file, char __user *buf, |
123 | size_t count, loff_t * ppos) | 123 | size_t count, loff_t * ppos) |
124 | { | 124 | { |
125 | unsigned int minor = iminor(file->f_dentry->d_inode); | 125 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
126 | char ch; | 126 | char ch; |
127 | int i = 0, retries; | 127 | int i = 0, retries; |
128 | 128 | ||
@@ -174,7 +174,7 @@ static ssize_t dtlk_write(struct file *file, const char __user *buf, | |||
174 | } | 174 | } |
175 | #endif | 175 | #endif |
176 | 176 | ||
177 | if (iminor(file->f_dentry->d_inode) != DTLK_MINOR) | 177 | if (iminor(file->f_path.dentry->d_inode) != DTLK_MINOR) |
178 | return -EINVAL; | 178 | return -EINVAL; |
179 | 179 | ||
180 | while (1) { | 180 | while (1) { |
diff --git a/drivers/char/epca.c b/drivers/char/epca.c index 7c71eb779802..a0f822c9d74d 100644 --- a/drivers/char/epca.c +++ b/drivers/char/epca.c | |||
@@ -199,7 +199,7 @@ static int pc_ioctl(struct tty_struct *, struct file *, | |||
199 | unsigned int, unsigned long); | 199 | unsigned int, unsigned long); |
200 | static int info_ioctl(struct tty_struct *, struct file *, | 200 | static int info_ioctl(struct tty_struct *, struct file *, |
201 | unsigned int, unsigned long); | 201 | unsigned int, unsigned long); |
202 | static void pc_set_termios(struct tty_struct *, struct termios *); | 202 | static void pc_set_termios(struct tty_struct *, struct ktermios *); |
203 | static void do_softint(struct work_struct *work); | 203 | static void do_softint(struct work_struct *work); |
204 | static void pc_stop(struct tty_struct *); | 204 | static void pc_stop(struct tty_struct *); |
205 | static void pc_start(struct tty_struct *); | 205 | static void pc_start(struct tty_struct *); |
@@ -1236,6 +1236,8 @@ static int __init pc_init(void) | |||
1236 | pc_driver->init_termios.c_oflag = 0; | 1236 | pc_driver->init_termios.c_oflag = 0; |
1237 | pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 1237 | pc_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
1238 | pc_driver->init_termios.c_lflag = 0; | 1238 | pc_driver->init_termios.c_lflag = 0; |
1239 | pc_driver->init_termios.c_ispeed = 9600; | ||
1240 | pc_driver->init_termios.c_ospeed = 9600; | ||
1239 | pc_driver->flags = TTY_DRIVER_REAL_RAW; | 1241 | pc_driver->flags = TTY_DRIVER_REAL_RAW; |
1240 | tty_set_operations(pc_driver, &pc_ops); | 1242 | tty_set_operations(pc_driver, &pc_ops); |
1241 | 1243 | ||
@@ -1250,6 +1252,8 @@ static int __init pc_init(void) | |||
1250 | pc_info->init_termios.c_oflag = 0; | 1252 | pc_info->init_termios.c_oflag = 0; |
1251 | pc_info->init_termios.c_lflag = 0; | 1253 | pc_info->init_termios.c_lflag = 0; |
1252 | pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; | 1254 | pc_info->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; |
1255 | pc_info->init_termios.c_ispeed = 9600; | ||
1256 | pc_info->init_termios.c_ospeed = 9600; | ||
1253 | pc_info->flags = TTY_DRIVER_REAL_RAW; | 1257 | pc_info->flags = TTY_DRIVER_REAL_RAW; |
1254 | tty_set_operations(pc_info, &info_ops); | 1258 | tty_set_operations(pc_info, &info_ops); |
1255 | 1259 | ||
@@ -1999,7 +2003,7 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch) | |||
1999 | { /* Begin epcaparam */ | 2003 | { /* Begin epcaparam */ |
2000 | 2004 | ||
2001 | unsigned int cmdHead; | 2005 | unsigned int cmdHead; |
2002 | struct termios *ts; | 2006 | struct ktermios *ts; |
2003 | struct board_chan __iomem *bc; | 2007 | struct board_chan __iomem *bc; |
2004 | unsigned mval, hflow, cflag, iflag; | 2008 | unsigned mval, hflow, cflag, iflag; |
2005 | 2009 | ||
@@ -2114,7 +2118,7 @@ static void receive_data(struct channel *ch) | |||
2114 | { /* Begin receive_data */ | 2118 | { /* Begin receive_data */ |
2115 | 2119 | ||
2116 | unchar *rptr; | 2120 | unchar *rptr; |
2117 | struct termios *ts = NULL; | 2121 | struct ktermios *ts = NULL; |
2118 | struct tty_struct *tty; | 2122 | struct tty_struct *tty; |
2119 | struct board_chan __iomem *bc; | 2123 | struct board_chan __iomem *bc; |
2120 | int dataToRead, wrapgap, bytesAvailable; | 2124 | int dataToRead, wrapgap, bytesAvailable; |
@@ -2362,12 +2366,14 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2362 | switch (cmd) | 2366 | switch (cmd) |
2363 | { /* Begin switch cmd */ | 2367 | { /* Begin switch cmd */ |
2364 | 2368 | ||
2369 | #if 0 /* Handled by calling layer properly */ | ||
2365 | case TCGETS: | 2370 | case TCGETS: |
2366 | if (copy_to_user(argp, tty->termios, sizeof(struct termios))) | 2371 | if (copy_to_user(argp, tty->termios, sizeof(struct ktermios))) |
2367 | return -EFAULT; | 2372 | return -EFAULT; |
2368 | return 0; | 2373 | return 0; |
2369 | case TCGETA: | 2374 | case TCGETA: |
2370 | return get_termio(tty, argp); | 2375 | return get_termio(tty, argp); |
2376 | #endif | ||
2371 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | 2377 | case TCSBRK: /* SVID version: non-zero arg --> no break */ |
2372 | retval = tty_check_change(tty); | 2378 | retval = tty_check_change(tty); |
2373 | if (retval) | 2379 | if (retval) |
@@ -2536,7 +2542,7 @@ static int pc_ioctl(struct tty_struct *tty, struct file * file, | |||
2536 | 2542 | ||
2537 | /* --------------------- Begin pc_set_termios ----------------------- */ | 2543 | /* --------------------- Begin pc_set_termios ----------------------- */ |
2538 | 2544 | ||
2539 | static void pc_set_termios(struct tty_struct *tty, struct termios *old_termios) | 2545 | static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
2540 | { /* Begin pc_set_termios */ | 2546 | { /* Begin pc_set_termios */ |
2541 | 2547 | ||
2542 | struct channel *ch; | 2548 | struct channel *ch; |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 93b551962513..d1bfbaa2aa02 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
@@ -1915,7 +1915,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
1915 | return 0; | 1915 | return 0; |
1916 | } | 1916 | } |
1917 | 1917 | ||
1918 | static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios) | 1918 | static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
1919 | { | 1919 | { |
1920 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; | 1920 | struct esp_struct *info = (struct esp_struct *)tty->driver_data; |
1921 | unsigned long flags; | 1921 | unsigned long flags; |
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c index 87127e49c0db..e769811e7417 100644 --- a/drivers/char/generic_serial.c +++ b/drivers/char/generic_serial.c | |||
@@ -718,11 +718,11 @@ static unsigned int gs_baudrates[] = { | |||
718 | 718 | ||
719 | 719 | ||
720 | void gs_set_termios (struct tty_struct * tty, | 720 | void gs_set_termios (struct tty_struct * tty, |
721 | struct termios * old_termios) | 721 | struct ktermios * old_termios) |
722 | { | 722 | { |
723 | struct gs_port *port; | 723 | struct gs_port *port; |
724 | int baudrate, tmp, rv; | 724 | int baudrate, tmp, rv; |
725 | struct termios *tiosp; | 725 | struct ktermios *tiosp; |
726 | 726 | ||
727 | func_enter(); | 727 | func_enter(); |
728 | 728 | ||
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 9902ffad3b12..cc2cd46bedc6 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
40 | #include <linux/delay.h> | 40 | #include <linux/delay.h> |
41 | #include <linux/freezer.h> | ||
41 | 42 | ||
42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
43 | 44 | ||
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 8728255c9463..207f7343ba60 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -192,11 +192,13 @@ MODULE_VERSION(HVCS_DRIVER_VERSION); | |||
192 | * that will cause echoing or we'll go into recursive loop echoing chars back | 192 | * that will cause echoing or we'll go into recursive loop echoing chars back |
193 | * and forth with the console drivers. | 193 | * and forth with the console drivers. |
194 | */ | 194 | */ |
195 | static struct termios hvcs_tty_termios = { | 195 | static struct ktermios hvcs_tty_termios = { |
196 | .c_iflag = IGNBRK | IGNPAR, | 196 | .c_iflag = IGNBRK | IGNPAR, |
197 | .c_oflag = OPOST, | 197 | .c_oflag = OPOST, |
198 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, | 198 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, |
199 | .c_cc = INIT_C_CC | 199 | .c_cc = INIT_C_CC, |
200 | .c_ispeed = 38400, | ||
201 | .c_ospeed = 38400 | ||
200 | }; | 202 | }; |
201 | 203 | ||
202 | /* | 204 | /* |
@@ -337,11 +339,6 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp); | |||
337 | static void hvcs_close(struct tty_struct *tty, struct file *filp); | 339 | static void hvcs_close(struct tty_struct *tty, struct file *filp); |
338 | static void hvcs_hangup(struct tty_struct * tty); | 340 | static void hvcs_hangup(struct tty_struct * tty); |
339 | 341 | ||
340 | static void hvcs_create_device_attrs(struct hvcs_struct *hvcsd); | ||
341 | static void hvcs_remove_device_attrs(struct vio_dev *vdev); | ||
342 | static void hvcs_create_driver_attrs(void); | ||
343 | static void hvcs_remove_driver_attrs(void); | ||
344 | |||
345 | static int __devinit hvcs_probe(struct vio_dev *dev, | 342 | static int __devinit hvcs_probe(struct vio_dev *dev, |
346 | const struct vio_device_id *id); | 343 | const struct vio_device_id *id); |
347 | static int __devexit hvcs_remove(struct vio_dev *dev); | 344 | static int __devexit hvcs_remove(struct vio_dev *dev); |
@@ -353,6 +350,172 @@ static void __exit hvcs_module_exit(void); | |||
353 | #define HVCS_TRY_WRITE 0x00000004 | 350 | #define HVCS_TRY_WRITE 0x00000004 |
354 | #define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ) | 351 | #define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ) |
355 | 352 | ||
353 | static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) | ||
354 | { | ||
355 | return viod->dev.driver_data; | ||
356 | } | ||
357 | /* The sysfs interface for the driver and devices */ | ||
358 | |||
359 | static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
360 | { | ||
361 | struct vio_dev *viod = to_vio_dev(dev); | ||
362 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
363 | unsigned long flags; | ||
364 | int retval; | ||
365 | |||
366 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
367 | retval = sprintf(buf, "%X\n", hvcsd->p_unit_address); | ||
368 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
369 | return retval; | ||
370 | } | ||
371 | static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL); | ||
372 | |||
373 | static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
374 | { | ||
375 | struct vio_dev *viod = to_vio_dev(dev); | ||
376 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
377 | unsigned long flags; | ||
378 | int retval; | ||
379 | |||
380 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
381 | retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); | ||
382 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
383 | return retval; | ||
384 | } | ||
385 | static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL); | ||
386 | |||
387 | static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf, | ||
388 | size_t count) | ||
389 | { | ||
390 | /* | ||
391 | * Don't need this feature at the present time because firmware doesn't | ||
392 | * yet support multiple partners. | ||
393 | */ | ||
394 | printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n"); | ||
395 | return -EPERM; | ||
396 | } | ||
397 | |||
398 | static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
399 | { | ||
400 | struct vio_dev *viod = to_vio_dev(dev); | ||
401 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
402 | unsigned long flags; | ||
403 | int retval; | ||
404 | |||
405 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
406 | retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); | ||
407 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
408 | return retval; | ||
409 | } | ||
410 | |||
411 | static DEVICE_ATTR(current_vty, | ||
412 | S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store); | ||
413 | |||
414 | static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf, | ||
415 | size_t count) | ||
416 | { | ||
417 | struct vio_dev *viod = to_vio_dev(dev); | ||
418 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
419 | unsigned long flags; | ||
420 | |||
421 | /* writing a '0' to this sysfs entry will result in the disconnect. */ | ||
422 | if (simple_strtol(buf, NULL, 0) != 0) | ||
423 | return -EINVAL; | ||
424 | |||
425 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
426 | |||
427 | if (hvcsd->open_count > 0) { | ||
428 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
429 | printk(KERN_INFO "HVCS: vterm state unchanged. " | ||
430 | "The hvcs device node is still in use.\n"); | ||
431 | return -EPERM; | ||
432 | } | ||
433 | |||
434 | if (hvcsd->connected == 0) { | ||
435 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
436 | printk(KERN_INFO "HVCS: vterm state unchanged. The" | ||
437 | " vty-server is not connected to a vty.\n"); | ||
438 | return -EPERM; | ||
439 | } | ||
440 | |||
441 | hvcs_partner_free(hvcsd); | ||
442 | printk(KERN_INFO "HVCS: Closed vty-server@%X and" | ||
443 | " partner vty@%X:%d connection.\n", | ||
444 | hvcsd->vdev->unit_address, | ||
445 | hvcsd->p_unit_address, | ||
446 | (uint32_t)hvcsd->p_partition_ID); | ||
447 | |||
448 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
449 | return count; | ||
450 | } | ||
451 | |||
452 | static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
453 | { | ||
454 | struct vio_dev *viod = to_vio_dev(dev); | ||
455 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
456 | unsigned long flags; | ||
457 | int retval; | ||
458 | |||
459 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
460 | retval = sprintf(buf, "%d\n", hvcsd->connected); | ||
461 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
462 | return retval; | ||
463 | } | ||
464 | static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR, | ||
465 | hvcs_vterm_state_show, hvcs_vterm_state_store); | ||
466 | |||
467 | static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
468 | { | ||
469 | struct vio_dev *viod = to_vio_dev(dev); | ||
470 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
471 | unsigned long flags; | ||
472 | int retval; | ||
473 | |||
474 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
475 | retval = sprintf(buf, "%d\n", hvcsd->index); | ||
476 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
477 | return retval; | ||
478 | } | ||
479 | |||
480 | static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL); | ||
481 | |||
482 | static struct attribute *hvcs_attrs[] = { | ||
483 | &dev_attr_partner_vtys.attr, | ||
484 | &dev_attr_partner_clcs.attr, | ||
485 | &dev_attr_current_vty.attr, | ||
486 | &dev_attr_vterm_state.attr, | ||
487 | &dev_attr_index.attr, | ||
488 | NULL, | ||
489 | }; | ||
490 | |||
491 | static struct attribute_group hvcs_attr_group = { | ||
492 | .attrs = hvcs_attrs, | ||
493 | }; | ||
494 | |||
495 | static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf) | ||
496 | { | ||
497 | /* A 1 means it is updating, a 0 means it is done updating */ | ||
498 | return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status); | ||
499 | } | ||
500 | |||
501 | static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf, | ||
502 | size_t count) | ||
503 | { | ||
504 | if ((simple_strtol(buf, NULL, 0) != 1) | ||
505 | && (hvcs_rescan_status != 0)) | ||
506 | return -EINVAL; | ||
507 | |||
508 | hvcs_rescan_status = 1; | ||
509 | printk(KERN_INFO "HVCS: rescanning partner info for all" | ||
510 | " vty-servers.\n"); | ||
511 | hvcs_rescan_devices_list(); | ||
512 | hvcs_rescan_status = 0; | ||
513 | return count; | ||
514 | } | ||
515 | |||
516 | static DRIVER_ATTR(rescan, | ||
517 | S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store); | ||
518 | |||
356 | static void hvcs_kick(void) | 519 | static void hvcs_kick(void) |
357 | { | 520 | { |
358 | hvcs_kicked = 1; | 521 | hvcs_kicked = 1; |
@@ -575,7 +738,7 @@ static void destroy_hvcs_struct(struct kobject *kobj) | |||
575 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 738 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
576 | spin_unlock(&hvcs_structs_lock); | 739 | spin_unlock(&hvcs_structs_lock); |
577 | 740 | ||
578 | hvcs_remove_device_attrs(vdev); | 741 | sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group); |
579 | 742 | ||
580 | kfree(hvcsd); | 743 | kfree(hvcsd); |
581 | } | 744 | } |
@@ -608,6 +771,7 @@ static int __devinit hvcs_probe( | |||
608 | { | 771 | { |
609 | struct hvcs_struct *hvcsd; | 772 | struct hvcs_struct *hvcsd; |
610 | int index; | 773 | int index; |
774 | int retval; | ||
611 | 775 | ||
612 | if (!dev || !id) { | 776 | if (!dev || !id) { |
613 | printk(KERN_ERR "HVCS: probed with invalid parameter.\n"); | 777 | printk(KERN_ERR "HVCS: probed with invalid parameter.\n"); |
@@ -658,14 +822,16 @@ static int __devinit hvcs_probe( | |||
658 | * the hvcs_struct has been added to the devices list then the user app | 822 | * the hvcs_struct has been added to the devices list then the user app |
659 | * will get -ENODEV. | 823 | * will get -ENODEV. |
660 | */ | 824 | */ |
661 | |||
662 | spin_lock(&hvcs_structs_lock); | 825 | spin_lock(&hvcs_structs_lock); |
663 | |||
664 | list_add_tail(&(hvcsd->next), &hvcs_structs); | 826 | list_add_tail(&(hvcsd->next), &hvcs_structs); |
665 | |||
666 | spin_unlock(&hvcs_structs_lock); | 827 | spin_unlock(&hvcs_structs_lock); |
667 | 828 | ||
668 | hvcs_create_device_attrs(hvcsd); | 829 | retval = sysfs_create_group(&dev->dev.kobj, &hvcs_attr_group); |
830 | if (retval) { | ||
831 | printk(KERN_ERR "HVCS: Can't create sysfs attrs for vty-server@%X\n", | ||
832 | hvcsd->vdev->unit_address); | ||
833 | return retval; | ||
834 | } | ||
669 | 835 | ||
670 | printk(KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address); | 836 | printk(KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address); |
671 | 837 | ||
@@ -1354,8 +1520,10 @@ static int __init hvcs_module_init(void) | |||
1354 | if (!hvcs_tty_driver) | 1520 | if (!hvcs_tty_driver) |
1355 | return -ENOMEM; | 1521 | return -ENOMEM; |
1356 | 1522 | ||
1357 | if (hvcs_alloc_index_list(num_ttys_to_alloc)) | 1523 | if (hvcs_alloc_index_list(num_ttys_to_alloc)) { |
1358 | return -ENOMEM; | 1524 | rc = -ENOMEM; |
1525 | goto index_fail; | ||
1526 | } | ||
1359 | 1527 | ||
1360 | hvcs_tty_driver->owner = THIS_MODULE; | 1528 | hvcs_tty_driver->owner = THIS_MODULE; |
1361 | 1529 | ||
@@ -1385,41 +1553,57 @@ static int __init hvcs_module_init(void) | |||
1385 | * dynamically assigned major and minor numbers for our devices. | 1553 | * dynamically assigned major and minor numbers for our devices. |
1386 | */ | 1554 | */ |
1387 | if (tty_register_driver(hvcs_tty_driver)) { | 1555 | if (tty_register_driver(hvcs_tty_driver)) { |
1388 | printk(KERN_ERR "HVCS: registration " | 1556 | printk(KERN_ERR "HVCS: registration as a tty driver failed.\n"); |
1389 | " as a tty driver failed.\n"); | 1557 | rc = -EIO; |
1390 | hvcs_free_index_list(); | 1558 | goto register_fail; |
1391 | put_tty_driver(hvcs_tty_driver); | ||
1392 | return -EIO; | ||
1393 | } | 1559 | } |
1394 | 1560 | ||
1395 | hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL); | 1561 | hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL); |
1396 | if (!hvcs_pi_buff) { | 1562 | if (!hvcs_pi_buff) { |
1397 | tty_unregister_driver(hvcs_tty_driver); | 1563 | rc = -ENOMEM; |
1398 | hvcs_free_index_list(); | 1564 | goto buff_alloc_fail; |
1399 | put_tty_driver(hvcs_tty_driver); | ||
1400 | return -ENOMEM; | ||
1401 | } | 1565 | } |
1402 | 1566 | ||
1403 | hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); | 1567 | hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); |
1404 | if (IS_ERR(hvcs_task)) { | 1568 | if (IS_ERR(hvcs_task)) { |
1405 | printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n"); | 1569 | printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n"); |
1406 | kfree(hvcs_pi_buff); | 1570 | rc = -EIO; |
1407 | tty_unregister_driver(hvcs_tty_driver); | 1571 | goto kthread_fail; |
1408 | hvcs_free_index_list(); | ||
1409 | put_tty_driver(hvcs_tty_driver); | ||
1410 | return -EIO; | ||
1411 | } | 1572 | } |
1412 | 1573 | ||
1413 | rc = vio_register_driver(&hvcs_vio_driver); | 1574 | rc = vio_register_driver(&hvcs_vio_driver); |
1575 | if (rc) { | ||
1576 | printk(KERN_ERR "HVCS: can't register vio driver\n"); | ||
1577 | goto vio_fail; | ||
1578 | } | ||
1414 | 1579 | ||
1415 | /* | 1580 | /* |
1416 | * This needs to be done AFTER the vio_register_driver() call or else | 1581 | * This needs to be done AFTER the vio_register_driver() call or else |
1417 | * the kobjects won't be initialized properly. | 1582 | * the kobjects won't be initialized properly. |
1418 | */ | 1583 | */ |
1419 | hvcs_create_driver_attrs(); | 1584 | rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); |
1585 | if (rc) { | ||
1586 | printk(KERN_ERR "HVCS: sysfs attr create failed\n"); | ||
1587 | goto attr_fail; | ||
1588 | } | ||
1420 | 1589 | ||
1421 | printk(KERN_INFO "HVCS: driver module inserted.\n"); | 1590 | printk(KERN_INFO "HVCS: driver module inserted.\n"); |
1422 | 1591 | ||
1592 | return 0; | ||
1593 | |||
1594 | attr_fail: | ||
1595 | vio_unregister_driver(&hvcs_vio_driver); | ||
1596 | vio_fail: | ||
1597 | kthread_stop(hvcs_task); | ||
1598 | kthread_fail: | ||
1599 | kfree(hvcs_pi_buff); | ||
1600 | buff_alloc_fail: | ||
1601 | tty_unregister_driver(hvcs_tty_driver); | ||
1602 | register_fail: | ||
1603 | hvcs_free_index_list(); | ||
1604 | index_fail: | ||
1605 | put_tty_driver(hvcs_tty_driver); | ||
1606 | hvcs_tty_driver = NULL; | ||
1423 | return rc; | 1607 | return rc; |
1424 | } | 1608 | } |
1425 | 1609 | ||
@@ -1441,7 +1625,7 @@ static void __exit hvcs_module_exit(void) | |||
1441 | hvcs_pi_buff = NULL; | 1625 | hvcs_pi_buff = NULL; |
1442 | spin_unlock(&hvcs_pi_lock); | 1626 | spin_unlock(&hvcs_pi_lock); |
1443 | 1627 | ||
1444 | hvcs_remove_driver_attrs(); | 1628 | driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan); |
1445 | 1629 | ||
1446 | vio_unregister_driver(&hvcs_vio_driver); | 1630 | vio_unregister_driver(&hvcs_vio_driver); |
1447 | 1631 | ||
@@ -1456,191 +1640,3 @@ static void __exit hvcs_module_exit(void) | |||
1456 | 1640 | ||
1457 | module_init(hvcs_module_init); | 1641 | module_init(hvcs_module_init); |
1458 | module_exit(hvcs_module_exit); | 1642 | module_exit(hvcs_module_exit); |
1459 | |||
1460 | static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) | ||
1461 | { | ||
1462 | return viod->dev.driver_data; | ||
1463 | } | ||
1464 | /* The sysfs interface for the driver and devices */ | ||
1465 | |||
1466 | static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1467 | { | ||
1468 | struct vio_dev *viod = to_vio_dev(dev); | ||
1469 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
1470 | unsigned long flags; | ||
1471 | int retval; | ||
1472 | |||
1473 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1474 | retval = sprintf(buf, "%X\n", hvcsd->p_unit_address); | ||
1475 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1476 | return retval; | ||
1477 | } | ||
1478 | static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL); | ||
1479 | |||
1480 | static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1481 | { | ||
1482 | struct vio_dev *viod = to_vio_dev(dev); | ||
1483 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
1484 | unsigned long flags; | ||
1485 | int retval; | ||
1486 | |||
1487 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1488 | retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); | ||
1489 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1490 | return retval; | ||
1491 | } | ||
1492 | static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL); | ||
1493 | |||
1494 | static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf, | ||
1495 | size_t count) | ||
1496 | { | ||
1497 | /* | ||
1498 | * Don't need this feature at the present time because firmware doesn't | ||
1499 | * yet support multiple partners. | ||
1500 | */ | ||
1501 | printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n"); | ||
1502 | return -EPERM; | ||
1503 | } | ||
1504 | |||
1505 | static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1506 | { | ||
1507 | struct vio_dev *viod = to_vio_dev(dev); | ||
1508 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
1509 | unsigned long flags; | ||
1510 | int retval; | ||
1511 | |||
1512 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1513 | retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); | ||
1514 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1515 | return retval; | ||
1516 | } | ||
1517 | |||
1518 | static DEVICE_ATTR(current_vty, | ||
1519 | S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store); | ||
1520 | |||
1521 | static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf, | ||
1522 | size_t count) | ||
1523 | { | ||
1524 | struct vio_dev *viod = to_vio_dev(dev); | ||
1525 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
1526 | unsigned long flags; | ||
1527 | |||
1528 | /* writing a '0' to this sysfs entry will result in the disconnect. */ | ||
1529 | if (simple_strtol(buf, NULL, 0) != 0) | ||
1530 | return -EINVAL; | ||
1531 | |||
1532 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1533 | |||
1534 | if (hvcsd->open_count > 0) { | ||
1535 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1536 | printk(KERN_INFO "HVCS: vterm state unchanged. " | ||
1537 | "The hvcs device node is still in use.\n"); | ||
1538 | return -EPERM; | ||
1539 | } | ||
1540 | |||
1541 | if (hvcsd->connected == 0) { | ||
1542 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1543 | printk(KERN_INFO "HVCS: vterm state unchanged. The" | ||
1544 | " vty-server is not connected to a vty.\n"); | ||
1545 | return -EPERM; | ||
1546 | } | ||
1547 | |||
1548 | hvcs_partner_free(hvcsd); | ||
1549 | printk(KERN_INFO "HVCS: Closed vty-server@%X and" | ||
1550 | " partner vty@%X:%d connection.\n", | ||
1551 | hvcsd->vdev->unit_address, | ||
1552 | hvcsd->p_unit_address, | ||
1553 | (uint32_t)hvcsd->p_partition_ID); | ||
1554 | |||
1555 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1556 | return count; | ||
1557 | } | ||
1558 | |||
1559 | static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1560 | { | ||
1561 | struct vio_dev *viod = to_vio_dev(dev); | ||
1562 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
1563 | unsigned long flags; | ||
1564 | int retval; | ||
1565 | |||
1566 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1567 | retval = sprintf(buf, "%d\n", hvcsd->connected); | ||
1568 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1569 | return retval; | ||
1570 | } | ||
1571 | static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR, | ||
1572 | hvcs_vterm_state_show, hvcs_vterm_state_store); | ||
1573 | |||
1574 | static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
1575 | { | ||
1576 | struct vio_dev *viod = to_vio_dev(dev); | ||
1577 | struct hvcs_struct *hvcsd = from_vio_dev(viod); | ||
1578 | unsigned long flags; | ||
1579 | int retval; | ||
1580 | |||
1581 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1582 | retval = sprintf(buf, "%d\n", hvcsd->index); | ||
1583 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1584 | return retval; | ||
1585 | } | ||
1586 | |||
1587 | static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL); | ||
1588 | |||
1589 | static struct attribute *hvcs_attrs[] = { | ||
1590 | &dev_attr_partner_vtys.attr, | ||
1591 | &dev_attr_partner_clcs.attr, | ||
1592 | &dev_attr_current_vty.attr, | ||
1593 | &dev_attr_vterm_state.attr, | ||
1594 | &dev_attr_index.attr, | ||
1595 | NULL, | ||
1596 | }; | ||
1597 | |||
1598 | static struct attribute_group hvcs_attr_group = { | ||
1599 | .attrs = hvcs_attrs, | ||
1600 | }; | ||
1601 | |||
1602 | static void hvcs_create_device_attrs(struct hvcs_struct *hvcsd) | ||
1603 | { | ||
1604 | struct vio_dev *vdev = hvcsd->vdev; | ||
1605 | sysfs_create_group(&vdev->dev.kobj, &hvcs_attr_group); | ||
1606 | } | ||
1607 | |||
1608 | static void hvcs_remove_device_attrs(struct vio_dev *vdev) | ||
1609 | { | ||
1610 | sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group); | ||
1611 | } | ||
1612 | |||
1613 | static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf) | ||
1614 | { | ||
1615 | /* A 1 means it is updating, a 0 means it is done updating */ | ||
1616 | return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status); | ||
1617 | } | ||
1618 | |||
1619 | static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf, | ||
1620 | size_t count) | ||
1621 | { | ||
1622 | if ((simple_strtol(buf, NULL, 0) != 1) | ||
1623 | && (hvcs_rescan_status != 0)) | ||
1624 | return -EINVAL; | ||
1625 | |||
1626 | hvcs_rescan_status = 1; | ||
1627 | printk(KERN_INFO "HVCS: rescanning partner info for all" | ||
1628 | " vty-servers.\n"); | ||
1629 | hvcs_rescan_devices_list(); | ||
1630 | hvcs_rescan_status = 0; | ||
1631 | return count; | ||
1632 | } | ||
1633 | static DRIVER_ATTR(rescan, | ||
1634 | S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store); | ||
1635 | |||
1636 | static void hvcs_create_driver_attrs(void) | ||
1637 | { | ||
1638 | struct device_driver *driverfs = &(hvcs_vio_driver.driver); | ||
1639 | driver_create_file(driverfs, &driver_attr_rescan); | ||
1640 | } | ||
1641 | |||
1642 | static void hvcs_remove_driver_attrs(void) | ||
1643 | { | ||
1644 | struct device_driver *driverfs = &(hvcs_vio_driver.driver); | ||
1645 | driver_remove_file(driverfs, &driver_attr_rescan); | ||
1646 | } | ||
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 82a41d5b4ed0..d7806834fc17 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -1161,6 +1161,8 @@ static int __init hvsi_init(void) | |||
1161 | hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM; | 1161 | hvsi_driver->type = TTY_DRIVER_TYPE_SYSTEM; |
1162 | hvsi_driver->init_termios = tty_std_termios; | 1162 | hvsi_driver->init_termios = tty_std_termios; |
1163 | hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; | 1163 | hvsi_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL; |
1164 | hvsi_driver->init_termios.c_ispeed = 9600; | ||
1165 | hvsi_driver->init_termios.c_ospeed = 9600; | ||
1164 | hvsi_driver->flags = TTY_DRIVER_REAL_RAW; | 1166 | hvsi_driver->flags = TTY_DRIVER_REAL_RAW; |
1165 | tty_set_operations(hvsi_driver, &hvsi_ops); | 1167 | tty_set_operations(hvsi_driver, &hvsi_ops); |
1166 | 1168 | ||
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 9f7635f75178..5f3acd8e64b8 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig | |||
@@ -3,17 +3,20 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | config HW_RANDOM | 5 | config HW_RANDOM |
6 | bool "Hardware Random Number Generator Core support" | 6 | tristate "Hardware Random Number Generator Core support" |
7 | default y | 7 | default m |
8 | ---help--- | 8 | ---help--- |
9 | Hardware Random Number Generator Core infrastructure. | 9 | Hardware Random Number Generator Core infrastructure. |
10 | 10 | ||
11 | To compile this driver as a module, choose M here: the | ||
12 | module will be called rng-core. | ||
13 | |||
11 | If unsure, say Y. | 14 | If unsure, say Y. |
12 | 15 | ||
13 | config HW_RANDOM_INTEL | 16 | config HW_RANDOM_INTEL |
14 | tristate "Intel HW Random Number Generator support" | 17 | tristate "Intel HW Random Number Generator support" |
15 | depends on HW_RANDOM && (X86 || IA64) && PCI | 18 | depends on HW_RANDOM && (X86 || IA64) && PCI |
16 | default y | 19 | default HW_RANDOM |
17 | ---help--- | 20 | ---help--- |
18 | This driver provides kernel-side support for the Random Number | 21 | This driver provides kernel-side support for the Random Number |
19 | Generator hardware found on Intel i8xx-based motherboards. | 22 | Generator hardware found on Intel i8xx-based motherboards. |
@@ -26,7 +29,7 @@ config HW_RANDOM_INTEL | |||
26 | config HW_RANDOM_AMD | 29 | config HW_RANDOM_AMD |
27 | tristate "AMD HW Random Number Generator support" | 30 | tristate "AMD HW Random Number Generator support" |
28 | depends on HW_RANDOM && X86 && PCI | 31 | depends on HW_RANDOM && X86 && PCI |
29 | default y | 32 | default HW_RANDOM |
30 | ---help--- | 33 | ---help--- |
31 | This driver provides kernel-side support for the Random Number | 34 | This driver provides kernel-side support for the Random Number |
32 | Generator hardware found on AMD 76x-based motherboards. | 35 | Generator hardware found on AMD 76x-based motherboards. |
@@ -39,7 +42,7 @@ config HW_RANDOM_AMD | |||
39 | config HW_RANDOM_GEODE | 42 | config HW_RANDOM_GEODE |
40 | tristate "AMD Geode HW Random Number Generator support" | 43 | tristate "AMD Geode HW Random Number Generator support" |
41 | depends on HW_RANDOM && X86 && PCI | 44 | depends on HW_RANDOM && X86 && PCI |
42 | default y | 45 | default HW_RANDOM |
43 | ---help--- | 46 | ---help--- |
44 | This driver provides kernel-side support for the Random Number | 47 | This driver provides kernel-side support for the Random Number |
45 | Generator hardware found on the AMD Geode LX. | 48 | Generator hardware found on the AMD Geode LX. |
@@ -52,7 +55,7 @@ config HW_RANDOM_GEODE | |||
52 | config HW_RANDOM_VIA | 55 | config HW_RANDOM_VIA |
53 | tristate "VIA HW Random Number Generator support" | 56 | tristate "VIA HW Random Number Generator support" |
54 | depends on HW_RANDOM && X86_32 | 57 | depends on HW_RANDOM && X86_32 |
55 | default y | 58 | default HW_RANDOM |
56 | ---help--- | 59 | ---help--- |
57 | This driver provides kernel-side support for the Random Number | 60 | This driver provides kernel-side support for the Random Number |
58 | Generator hardware found on VIA based motherboards. | 61 | Generator hardware found on VIA based motherboards. |
@@ -65,7 +68,7 @@ config HW_RANDOM_VIA | |||
65 | config HW_RANDOM_IXP4XX | 68 | config HW_RANDOM_IXP4XX |
66 | tristate "Intel IXP4xx NPU HW Random Number Generator support" | 69 | tristate "Intel IXP4xx NPU HW Random Number Generator support" |
67 | depends on HW_RANDOM && ARCH_IXP4XX | 70 | depends on HW_RANDOM && ARCH_IXP4XX |
68 | default y | 71 | default HW_RANDOM |
69 | ---help--- | 72 | ---help--- |
70 | This driver provides kernel-side support for the Random | 73 | This driver provides kernel-side support for the Random |
71 | Number Generator hardware found on the Intel IXP4xx NPU. | 74 | Number Generator hardware found on the Intel IXP4xx NPU. |
@@ -78,7 +81,7 @@ config HW_RANDOM_IXP4XX | |||
78 | config HW_RANDOM_OMAP | 81 | config HW_RANDOM_OMAP |
79 | tristate "OMAP Random Number Generator support" | 82 | tristate "OMAP Random Number Generator support" |
80 | depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX) | 83 | depends on HW_RANDOM && (ARCH_OMAP16XX || ARCH_OMAP24XX) |
81 | default y | 84 | default HW_RANDOM |
82 | ---help--- | 85 | ---help--- |
83 | This driver provides kernel-side support for the Random Number | 86 | This driver provides kernel-side support for the Random Number |
84 | Generator hardware found on OMAP16xx and OMAP24xx multimedia | 87 | Generator hardware found on OMAP16xx and OMAP24xx multimedia |
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index e263ae96f940..c41fa19454e3 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile | |||
@@ -2,7 +2,8 @@ | |||
2 | # Makefile for HW Random Number Generator (RNG) device drivers. | 2 | # Makefile for HW Random Number Generator (RNG) device drivers. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_HW_RANDOM) += core.o | 5 | obj-$(CONFIG_HW_RANDOM) += rng-core.o |
6 | rng-core-y := core.o | ||
6 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o | 7 | obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o |
7 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o | 8 | obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o |
8 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o | 9 | obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o |
diff --git a/drivers/char/ip2/i2cmd.h b/drivers/char/ip2/i2cmd.h index baa4e721b758..29277ec6b8ed 100644 --- a/drivers/char/ip2/i2cmd.h +++ b/drivers/char/ip2/i2cmd.h | |||
@@ -367,11 +367,6 @@ static UCHAR cc02[]; | |||
367 | #define CSE_NULL 3 // Replace with a null | 367 | #define CSE_NULL 3 // Replace with a null |
368 | #define CSE_MARK 4 // Replace with a 3-character sequence (as Unix) | 368 | #define CSE_MARK 4 // Replace with a 3-character sequence (as Unix) |
369 | 369 | ||
370 | #define CMD_SET_REPLACEMENT(arg,ch) \ | ||
371 | (((cmdSyntaxPtr)(ct36a))->cmd[1] = (arg), \ | ||
372 | (((cmdSyntaxPtr)(ct36a))->cmd[2] = (ch), \ | ||
373 | (cmdSyntaxPtr)(ct36a)) | ||
374 | |||
375 | #define CSE_REPLACE 0x8 // Replace the errored character with the | 370 | #define CSE_REPLACE 0x8 // Replace the errored character with the |
376 | // replacement character defined here | 371 | // replacement character defined here |
377 | 372 | ||
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c index c213fdbdb2b0..78045767ec33 100644 --- a/drivers/char/ip2/i2lib.c +++ b/drivers/char/ip2/i2lib.c | |||
@@ -1016,7 +1016,6 @@ i2Output(i2ChanStrPtr pCh, const char *pSource, int count) | |||
1016 | unsigned short channel; | 1016 | unsigned short channel; |
1017 | unsigned short stuffIndex; | 1017 | unsigned short stuffIndex; |
1018 | unsigned long flags; | 1018 | unsigned long flags; |
1019 | int rc = 0; | ||
1020 | 1019 | ||
1021 | int bailout = 10; | 1020 | int bailout = 10; |
1022 | 1021 | ||
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index cda2459c1d60..7c70310a49b5 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -177,7 +177,7 @@ static int ip2_write_room(PTTY); | |||
177 | static int ip2_chars_in_buf(PTTY); | 177 | static int ip2_chars_in_buf(PTTY); |
178 | static void ip2_flush_buffer(PTTY); | 178 | static void ip2_flush_buffer(PTTY); |
179 | static int ip2_ioctl(PTTY, struct file *, UINT, ULONG); | 179 | static int ip2_ioctl(PTTY, struct file *, UINT, ULONG); |
180 | static void ip2_set_termios(PTTY, struct termios *); | 180 | static void ip2_set_termios(PTTY, struct ktermios *); |
181 | static void ip2_set_line_discipline(PTTY); | 181 | static void ip2_set_line_discipline(PTTY); |
182 | static void ip2_throttle(PTTY); | 182 | static void ip2_throttle(PTTY); |
183 | static void ip2_unthrottle(PTTY); | 183 | static void ip2_unthrottle(PTTY); |
@@ -198,7 +198,7 @@ static void do_status(struct work_struct *); | |||
198 | 198 | ||
199 | static void ip2_wait_until_sent(PTTY,int); | 199 | static void ip2_wait_until_sent(PTTY,int); |
200 | 200 | ||
201 | static void set_params (i2ChanStrPtr, struct termios *); | 201 | static void set_params (i2ChanStrPtr, struct ktermios *); |
202 | static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); | 202 | static int get_serial_info(i2ChanStrPtr, struct serial_struct __user *); |
203 | static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); | 203 | static int set_serial_info(i2ChanStrPtr, struct serial_struct __user *); |
204 | 204 | ||
@@ -2398,7 +2398,7 @@ set_serial_info( i2ChanStrPtr pCh, struct serial_struct __user *new_info ) | |||
2398 | /* */ | 2398 | /* */ |
2399 | /******************************************************************************/ | 2399 | /******************************************************************************/ |
2400 | static void | 2400 | static void |
2401 | ip2_set_termios( PTTY tty, struct termios *old_termios ) | 2401 | ip2_set_termios( PTTY tty, struct ktermios *old_termios ) |
2402 | { | 2402 | { |
2403 | i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data; | 2403 | i2ChanStrPtr pCh = (i2ChanStrPtr)tty->driver_data; |
2404 | 2404 | ||
@@ -2440,11 +2440,11 @@ ip2_set_line_discipline ( PTTY tty ) | |||
2440 | /* change. */ | 2440 | /* change. */ |
2441 | /******************************************************************************/ | 2441 | /******************************************************************************/ |
2442 | static void | 2442 | static void |
2443 | set_params( i2ChanStrPtr pCh, struct termios *o_tios ) | 2443 | set_params( i2ChanStrPtr pCh, struct ktermios *o_tios ) |
2444 | { | 2444 | { |
2445 | tcflag_t cflag, iflag, lflag; | 2445 | tcflag_t cflag, iflag, lflag; |
2446 | char stop_char, start_char; | 2446 | char stop_char, start_char; |
2447 | struct termios dummy; | 2447 | struct ktermios dummy; |
2448 | 2448 | ||
2449 | lflag = pCh->pTTY->termios->c_lflag; | 2449 | lflag = pCh->pTTY->termios->c_lflag; |
2450 | cflag = pCh->pTTY->termios->c_cflag; | 2450 | cflag = pCh->pTTY->termios->c_cflag; |
@@ -2700,7 +2700,7 @@ static | |||
2700 | ssize_t | 2700 | ssize_t |
2701 | ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off ) | 2701 | ip2_ipl_read(struct file *pFile, char __user *pData, size_t count, loff_t *off ) |
2702 | { | 2702 | { |
2703 | unsigned int minor = iminor(pFile->f_dentry->d_inode); | 2703 | unsigned int minor = iminor(pFile->f_path.dentry->d_inode); |
2704 | int rc = 0; | 2704 | int rc = 0; |
2705 | 2705 | ||
2706 | #ifdef IP2DEBUG_IPL | 2706 | #ifdef IP2DEBUG_IPL |
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 0030cd8e2e95..6c59baa887a8 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -33,11 +33,13 @@ | |||
33 | #include <linux/ipmi_msgdefs.h> /* for completion codes */ | 33 | #include <linux/ipmi_msgdefs.h> /* for completion codes */ |
34 | #include "ipmi_si_sm.h" | 34 | #include "ipmi_si_sm.h" |
35 | 35 | ||
36 | static int bt_debug = 0x00; /* Production value 0, see following flags */ | 36 | #define BT_DEBUG_OFF 0 /* Used in production */ |
37 | #define BT_DEBUG_ENABLE 1 /* Generic messages */ | ||
38 | #define BT_DEBUG_MSG 2 /* Prints all request/response buffers */ | ||
39 | #define BT_DEBUG_STATES 4 /* Verbose look at state changes */ | ||
40 | |||
41 | static int bt_debug = BT_DEBUG_OFF; | ||
37 | 42 | ||
38 | #define BT_DEBUG_ENABLE 1 | ||
39 | #define BT_DEBUG_MSG 2 | ||
40 | #define BT_DEBUG_STATES 4 | ||
41 | module_param(bt_debug, int, 0644); | 43 | module_param(bt_debug, int, 0644); |
42 | MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); | 44 | MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); |
43 | 45 | ||
@@ -47,38 +49,54 @@ MODULE_PARM_DESC(bt_debug, "debug bitmask, 1=enable, 2=messages, 4=states"); | |||
47 | Since the Open IPMI architecture is single-message oriented at this | 49 | Since the Open IPMI architecture is single-message oriented at this |
48 | stage, the queue depth of BT is of no concern. */ | 50 | stage, the queue depth of BT is of no concern. */ |
49 | 51 | ||
50 | #define BT_NORMAL_TIMEOUT 5000000 /* seconds in microseconds */ | 52 | #define BT_NORMAL_TIMEOUT 5 /* seconds */ |
51 | #define BT_RETRY_LIMIT 2 | 53 | #define BT_NORMAL_RETRY_LIMIT 2 |
52 | #define BT_RESET_DELAY 6000000 /* 6 seconds after warm reset */ | 54 | #define BT_RESET_DELAY 6 /* seconds after warm reset */ |
55 | |||
56 | /* States are written in chronological order and usually cover | ||
57 | multiple rows of the state table discussion in the IPMI spec. */ | ||
53 | 58 | ||
54 | enum bt_states { | 59 | enum bt_states { |
55 | BT_STATE_IDLE, | 60 | BT_STATE_IDLE = 0, /* Order is critical in this list */ |
56 | BT_STATE_XACTION_START, | 61 | BT_STATE_XACTION_START, |
57 | BT_STATE_WRITE_BYTES, | 62 | BT_STATE_WRITE_BYTES, |
58 | BT_STATE_WRITE_END, | ||
59 | BT_STATE_WRITE_CONSUME, | 63 | BT_STATE_WRITE_CONSUME, |
60 | BT_STATE_B2H_WAIT, | 64 | BT_STATE_READ_WAIT, |
61 | BT_STATE_READ_END, | 65 | BT_STATE_CLEAR_B2H, |
62 | BT_STATE_RESET1, /* These must come last */ | 66 | BT_STATE_READ_BYTES, |
67 | BT_STATE_RESET1, /* These must come last */ | ||
63 | BT_STATE_RESET2, | 68 | BT_STATE_RESET2, |
64 | BT_STATE_RESET3, | 69 | BT_STATE_RESET3, |
65 | BT_STATE_RESTART, | 70 | BT_STATE_RESTART, |
66 | BT_STATE_HOSED | 71 | BT_STATE_PRINTME, |
72 | BT_STATE_CAPABILITIES_BEGIN, | ||
73 | BT_STATE_CAPABILITIES_END, | ||
74 | BT_STATE_LONG_BUSY /* BT doesn't get hosed :-) */ | ||
67 | }; | 75 | }; |
68 | 76 | ||
77 | /* Macros seen at the end of state "case" blocks. They help with legibility | ||
78 | and debugging. */ | ||
79 | |||
80 | #define BT_STATE_CHANGE(X,Y) { bt->state = X; return Y; } | ||
81 | |||
82 | #define BT_SI_SM_RETURN(Y) { last_printed = BT_STATE_PRINTME; return Y; } | ||
83 | |||
69 | struct si_sm_data { | 84 | struct si_sm_data { |
70 | enum bt_states state; | 85 | enum bt_states state; |
71 | enum bt_states last_state; /* assist printing and resets */ | ||
72 | unsigned char seq; /* BT sequence number */ | 86 | unsigned char seq; /* BT sequence number */ |
73 | struct si_sm_io *io; | 87 | struct si_sm_io *io; |
74 | unsigned char write_data[IPMI_MAX_MSG_LENGTH]; | 88 | unsigned char write_data[IPMI_MAX_MSG_LENGTH]; |
75 | int write_count; | 89 | int write_count; |
76 | unsigned char read_data[IPMI_MAX_MSG_LENGTH]; | 90 | unsigned char read_data[IPMI_MAX_MSG_LENGTH]; |
77 | int read_count; | 91 | int read_count; |
78 | int truncated; | 92 | int truncated; |
79 | long timeout; | 93 | long timeout; /* microseconds countdown */ |
80 | unsigned int error_retries; /* end of "common" fields */ | 94 | int error_retries; /* end of "common" fields */ |
81 | int nonzero_status; /* hung BMCs stay all 0 */ | 95 | int nonzero_status; /* hung BMCs stay all 0 */ |
96 | enum bt_states complete; /* to divert the state machine */ | ||
97 | int BT_CAP_outreqs; | ||
98 | long BT_CAP_req2rsp; | ||
99 | int BT_CAP_retries; /* Recommended retries */ | ||
82 | }; | 100 | }; |
83 | 101 | ||
84 | #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */ | 102 | #define BT_CLR_WR_PTR 0x01 /* See IPMI 1.5 table 11.6.4 */ |
@@ -111,86 +129,118 @@ struct si_sm_data { | |||
111 | static char *state2txt(unsigned char state) | 129 | static char *state2txt(unsigned char state) |
112 | { | 130 | { |
113 | switch (state) { | 131 | switch (state) { |
114 | case BT_STATE_IDLE: return("IDLE"); | 132 | case BT_STATE_IDLE: return("IDLE"); |
115 | case BT_STATE_XACTION_START: return("XACTION"); | 133 | case BT_STATE_XACTION_START: return("XACTION"); |
116 | case BT_STATE_WRITE_BYTES: return("WR_BYTES"); | 134 | case BT_STATE_WRITE_BYTES: return("WR_BYTES"); |
117 | case BT_STATE_WRITE_END: return("WR_END"); | 135 | case BT_STATE_WRITE_CONSUME: return("WR_CONSUME"); |
118 | case BT_STATE_WRITE_CONSUME: return("WR_CONSUME"); | 136 | case BT_STATE_READ_WAIT: return("RD_WAIT"); |
119 | case BT_STATE_B2H_WAIT: return("B2H_WAIT"); | 137 | case BT_STATE_CLEAR_B2H: return("CLEAR_B2H"); |
120 | case BT_STATE_READ_END: return("RD_END"); | 138 | case BT_STATE_READ_BYTES: return("RD_BYTES"); |
121 | case BT_STATE_RESET1: return("RESET1"); | 139 | case BT_STATE_RESET1: return("RESET1"); |
122 | case BT_STATE_RESET2: return("RESET2"); | 140 | case BT_STATE_RESET2: return("RESET2"); |
123 | case BT_STATE_RESET3: return("RESET3"); | 141 | case BT_STATE_RESET3: return("RESET3"); |
124 | case BT_STATE_RESTART: return("RESTART"); | 142 | case BT_STATE_RESTART: return("RESTART"); |
125 | case BT_STATE_HOSED: return("HOSED"); | 143 | case BT_STATE_LONG_BUSY: return("LONG_BUSY"); |
144 | case BT_STATE_CAPABILITIES_BEGIN: return("CAP_BEGIN"); | ||
145 | case BT_STATE_CAPABILITIES_END: return("CAP_END"); | ||
126 | } | 146 | } |
127 | return("BAD STATE"); | 147 | return("BAD STATE"); |
128 | } | 148 | } |
129 | #define STATE2TXT state2txt(bt->state) | 149 | #define STATE2TXT state2txt(bt->state) |
130 | 150 | ||
131 | static char *status2txt(unsigned char status, char *buf) | 151 | static char *status2txt(unsigned char status) |
132 | { | 152 | { |
153 | /* | ||
154 | * This cannot be called by two threads at the same time and | ||
155 | * the buffer is always consumed immediately, so the static is | ||
156 | * safe to use. | ||
157 | */ | ||
158 | static char buf[40]; | ||
159 | |||
133 | strcpy(buf, "[ "); | 160 | strcpy(buf, "[ "); |
134 | if (status & BT_B_BUSY) strcat(buf, "B_BUSY "); | 161 | if (status & BT_B_BUSY) |
135 | if (status & BT_H_BUSY) strcat(buf, "H_BUSY "); | 162 | strcat(buf, "B_BUSY "); |
136 | if (status & BT_OEM0) strcat(buf, "OEM0 "); | 163 | if (status & BT_H_BUSY) |
137 | if (status & BT_SMS_ATN) strcat(buf, "SMS "); | 164 | strcat(buf, "H_BUSY "); |
138 | if (status & BT_B2H_ATN) strcat(buf, "B2H "); | 165 | if (status & BT_OEM0) |
139 | if (status & BT_H2B_ATN) strcat(buf, "H2B "); | 166 | strcat(buf, "OEM0 "); |
167 | if (status & BT_SMS_ATN) | ||
168 | strcat(buf, "SMS "); | ||
169 | if (status & BT_B2H_ATN) | ||
170 | strcat(buf, "B2H "); | ||
171 | if (status & BT_H2B_ATN) | ||
172 | strcat(buf, "H2B "); | ||
140 | strcat(buf, "]"); | 173 | strcat(buf, "]"); |
141 | return buf; | 174 | return buf; |
142 | } | 175 | } |
143 | #define STATUS2TXT(buf) status2txt(status, buf) | 176 | #define STATUS2TXT status2txt(status) |
177 | |||
178 | /* called externally at insmod time, and internally on cleanup */ | ||
144 | 179 | ||
145 | /* This will be called from within this module on a hosed condition */ | ||
146 | #define FIRST_SEQ 0 | ||
147 | static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io) | 180 | static unsigned int bt_init_data(struct si_sm_data *bt, struct si_sm_io *io) |
148 | { | 181 | { |
149 | bt->state = BT_STATE_IDLE; | 182 | memset(bt, 0, sizeof(struct si_sm_data)); |
150 | bt->last_state = BT_STATE_IDLE; | 183 | if (bt->io != io) { /* external: one-time only things */ |
151 | bt->seq = FIRST_SEQ; | 184 | bt->io = io; |
152 | bt->io = io; | 185 | bt->seq = 0; |
153 | bt->write_count = 0; | 186 | } |
154 | bt->read_count = 0; | 187 | bt->state = BT_STATE_IDLE; /* start here */ |
155 | bt->error_retries = 0; | 188 | bt->complete = BT_STATE_IDLE; /* end here */ |
156 | bt->nonzero_status = 0; | 189 | bt->BT_CAP_req2rsp = BT_NORMAL_TIMEOUT * 1000000; |
157 | bt->truncated = 0; | 190 | bt->BT_CAP_retries = BT_NORMAL_RETRY_LIMIT; |
158 | bt->timeout = BT_NORMAL_TIMEOUT; | 191 | /* BT_CAP_outreqs == zero is a flag to read BT Capabilities */ |
159 | return 3; /* We claim 3 bytes of space; ought to check SPMI table */ | 192 | return 3; /* We claim 3 bytes of space; ought to check SPMI table */ |
160 | } | 193 | } |
161 | 194 | ||
195 | /* Jam a completion code (probably an error) into a response */ | ||
196 | |||
197 | static void force_result(struct si_sm_data *bt, unsigned char completion_code) | ||
198 | { | ||
199 | bt->read_data[0] = 4; /* # following bytes */ | ||
200 | bt->read_data[1] = bt->write_data[1] | 4; /* Odd NetFn/LUN */ | ||
201 | bt->read_data[2] = bt->write_data[2]; /* seq (ignored) */ | ||
202 | bt->read_data[3] = bt->write_data[3]; /* Command */ | ||
203 | bt->read_data[4] = completion_code; | ||
204 | bt->read_count = 5; | ||
205 | } | ||
206 | |||
207 | /* The upper state machine starts here */ | ||
208 | |||
162 | static int bt_start_transaction(struct si_sm_data *bt, | 209 | static int bt_start_transaction(struct si_sm_data *bt, |
163 | unsigned char *data, | 210 | unsigned char *data, |
164 | unsigned int size) | 211 | unsigned int size) |
165 | { | 212 | { |
166 | unsigned int i; | 213 | unsigned int i; |
167 | 214 | ||
168 | if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2))) | 215 | if (size < 2) |
169 | return -1; | 216 | return IPMI_REQ_LEN_INVALID_ERR; |
217 | if (size > IPMI_MAX_MSG_LENGTH) | ||
218 | return IPMI_REQ_LEN_EXCEEDED_ERR; | ||
170 | 219 | ||
171 | if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) | 220 | if (bt->state == BT_STATE_LONG_BUSY) |
172 | return -2; | 221 | return IPMI_NODE_BUSY_ERR; |
222 | |||
223 | if (bt->state != BT_STATE_IDLE) | ||
224 | return IPMI_NOT_IN_MY_STATE_ERR; | ||
173 | 225 | ||
174 | if (bt_debug & BT_DEBUG_MSG) { | 226 | if (bt_debug & BT_DEBUG_MSG) { |
175 | printk(KERN_WARNING "+++++++++++++++++++++++++++++++++++++\n"); | 227 | printk(KERN_WARNING "BT: +++++++++++++++++ New command\n"); |
176 | printk(KERN_WARNING "BT: write seq=0x%02X:", bt->seq); | 228 | printk(KERN_WARNING "BT: NetFn/LUN CMD [%d data]:", size - 2); |
177 | for (i = 0; i < size; i ++) | 229 | for (i = 0; i < size; i ++) |
178 | printk (" %02x", data[i]); | 230 | printk (" %02x", data[i]); |
179 | printk("\n"); | 231 | printk("\n"); |
180 | } | 232 | } |
181 | bt->write_data[0] = size + 1; /* all data plus seq byte */ | 233 | bt->write_data[0] = size + 1; /* all data plus seq byte */ |
182 | bt->write_data[1] = *data; /* NetFn/LUN */ | 234 | bt->write_data[1] = *data; /* NetFn/LUN */ |
183 | bt->write_data[2] = bt->seq; | 235 | bt->write_data[2] = bt->seq++; |
184 | memcpy(bt->write_data + 3, data + 1, size - 1); | 236 | memcpy(bt->write_data + 3, data + 1, size - 1); |
185 | bt->write_count = size + 2; | 237 | bt->write_count = size + 2; |
186 | |||
187 | bt->error_retries = 0; | 238 | bt->error_retries = 0; |
188 | bt->nonzero_status = 0; | 239 | bt->nonzero_status = 0; |
189 | bt->read_count = 0; | ||
190 | bt->truncated = 0; | 240 | bt->truncated = 0; |
191 | bt->state = BT_STATE_XACTION_START; | 241 | bt->state = BT_STATE_XACTION_START; |
192 | bt->last_state = BT_STATE_IDLE; | 242 | bt->timeout = bt->BT_CAP_req2rsp; |
193 | bt->timeout = BT_NORMAL_TIMEOUT; | 243 | force_result(bt, IPMI_ERR_UNSPECIFIED); |
194 | return 0; | 244 | return 0; |
195 | } | 245 | } |
196 | 246 | ||
@@ -198,38 +248,30 @@ static int bt_start_transaction(struct si_sm_data *bt, | |||
198 | it calls this. Strip out the length and seq bytes. */ | 248 | it calls this. Strip out the length and seq bytes. */ |
199 | 249 | ||
200 | static int bt_get_result(struct si_sm_data *bt, | 250 | static int bt_get_result(struct si_sm_data *bt, |
201 | unsigned char *data, | 251 | unsigned char *data, |
202 | unsigned int length) | 252 | unsigned int length) |
203 | { | 253 | { |
204 | int i, msg_len; | 254 | int i, msg_len; |
205 | 255 | ||
206 | msg_len = bt->read_count - 2; /* account for length & seq */ | 256 | msg_len = bt->read_count - 2; /* account for length & seq */ |
207 | /* Always NetFn, Cmd, cCode */ | ||
208 | if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) { | 257 | if (msg_len < 3 || msg_len > IPMI_MAX_MSG_LENGTH) { |
209 | printk(KERN_DEBUG "BT results: bad msg_len = %d\n", msg_len); | 258 | force_result(bt, IPMI_ERR_UNSPECIFIED); |
210 | data[0] = bt->write_data[1] | 0x4; /* Kludge a response */ | ||
211 | data[1] = bt->write_data[3]; | ||
212 | data[2] = IPMI_ERR_UNSPECIFIED; | ||
213 | msg_len = 3; | 259 | msg_len = 3; |
214 | } else { | 260 | } |
215 | data[0] = bt->read_data[1]; | 261 | data[0] = bt->read_data[1]; |
216 | data[1] = bt->read_data[3]; | 262 | data[1] = bt->read_data[3]; |
217 | if (length < msg_len) | 263 | if (length < msg_len || bt->truncated) { |
218 | bt->truncated = 1; | 264 | data[2] = IPMI_ERR_MSG_TRUNCATED; |
219 | if (bt->truncated) { /* can be set in read_all_bytes() */ | 265 | msg_len = 3; |
220 | data[2] = IPMI_ERR_MSG_TRUNCATED; | 266 | } else |
221 | msg_len = 3; | 267 | memcpy(data + 2, bt->read_data + 4, msg_len - 2); |
222 | } else | ||
223 | memcpy(data + 2, bt->read_data + 4, msg_len - 2); | ||
224 | 268 | ||
225 | if (bt_debug & BT_DEBUG_MSG) { | 269 | if (bt_debug & BT_DEBUG_MSG) { |
226 | printk (KERN_WARNING "BT: res (raw)"); | 270 | printk (KERN_WARNING "BT: result %d bytes:", msg_len); |
227 | for (i = 0; i < msg_len; i++) | 271 | for (i = 0; i < msg_len; i++) |
228 | printk(" %02x", data[i]); | 272 | printk(" %02x", data[i]); |
229 | printk ("\n"); | 273 | printk ("\n"); |
230 | } | ||
231 | } | 274 | } |
232 | bt->read_count = 0; /* paranoia */ | ||
233 | return msg_len; | 275 | return msg_len; |
234 | } | 276 | } |
235 | 277 | ||
@@ -238,22 +280,40 @@ static int bt_get_result(struct si_sm_data *bt, | |||
238 | 280 | ||
239 | static void reset_flags(struct si_sm_data *bt) | 281 | static void reset_flags(struct si_sm_data *bt) |
240 | { | 282 | { |
283 | if (bt_debug) | ||
284 | printk(KERN_WARNING "IPMI BT: flag reset %s\n", | ||
285 | status2txt(BT_STATUS)); | ||
241 | if (BT_STATUS & BT_H_BUSY) | 286 | if (BT_STATUS & BT_H_BUSY) |
242 | BT_CONTROL(BT_H_BUSY); | 287 | BT_CONTROL(BT_H_BUSY); /* force clear */ |
243 | if (BT_STATUS & BT_B_BUSY) | 288 | BT_CONTROL(BT_CLR_WR_PTR); /* always reset */ |
244 | BT_CONTROL(BT_B_BUSY); | 289 | BT_CONTROL(BT_SMS_ATN); /* always clear */ |
245 | BT_CONTROL(BT_CLR_WR_PTR); | 290 | BT_INTMASK_W(BT_BMC_HWRST); |
246 | BT_CONTROL(BT_SMS_ATN); | 291 | } |
247 | 292 | ||
248 | if (BT_STATUS & BT_B2H_ATN) { | 293 | /* Get rid of an unwanted/stale response. This should only be needed for |
249 | int i; | 294 | BMCs that support multiple outstanding requests. */ |
250 | BT_CONTROL(BT_H_BUSY); | 295 | |
251 | BT_CONTROL(BT_B2H_ATN); | 296 | static void drain_BMC2HOST(struct si_sm_data *bt) |
252 | BT_CONTROL(BT_CLR_RD_PTR); | 297 | { |
253 | for (i = 0; i < IPMI_MAX_MSG_LENGTH + 2; i++) | 298 | int i, size; |
254 | BMC2HOST; | 299 | |
255 | BT_CONTROL(BT_H_BUSY); | 300 | if (!(BT_STATUS & BT_B2H_ATN)) /* Not signalling a response */ |
256 | } | 301 | return; |
302 | |||
303 | BT_CONTROL(BT_H_BUSY); /* now set */ | ||
304 | BT_CONTROL(BT_B2H_ATN); /* always clear */ | ||
305 | BT_STATUS; /* pause */ | ||
306 | BT_CONTROL(BT_B2H_ATN); /* some BMCs are stubborn */ | ||
307 | BT_CONTROL(BT_CLR_RD_PTR); /* always reset */ | ||
308 | if (bt_debug) | ||
309 | printk(KERN_WARNING "IPMI BT: stale response %s; ", | ||
310 | status2txt(BT_STATUS)); | ||
311 | size = BMC2HOST; | ||
312 | for (i = 0; i < size ; i++) | ||
313 | BMC2HOST; | ||
314 | BT_CONTROL(BT_H_BUSY); /* now clear */ | ||
315 | if (bt_debug) | ||
316 | printk("drained %d bytes\n", size + 1); | ||
257 | } | 317 | } |
258 | 318 | ||
259 | static inline void write_all_bytes(struct si_sm_data *bt) | 319 | static inline void write_all_bytes(struct si_sm_data *bt) |
@@ -261,201 +321,256 @@ static inline void write_all_bytes(struct si_sm_data *bt) | |||
261 | int i; | 321 | int i; |
262 | 322 | ||
263 | if (bt_debug & BT_DEBUG_MSG) { | 323 | if (bt_debug & BT_DEBUG_MSG) { |
264 | printk(KERN_WARNING "BT: write %d bytes seq=0x%02X", | 324 | printk(KERN_WARNING "BT: write %d bytes seq=0x%02X", |
265 | bt->write_count, bt->seq); | 325 | bt->write_count, bt->seq); |
266 | for (i = 0; i < bt->write_count; i++) | 326 | for (i = 0; i < bt->write_count; i++) |
267 | printk (" %02x", bt->write_data[i]); | 327 | printk (" %02x", bt->write_data[i]); |
268 | printk ("\n"); | 328 | printk ("\n"); |
269 | } | 329 | } |
270 | for (i = 0; i < bt->write_count; i++) | 330 | for (i = 0; i < bt->write_count; i++) |
271 | HOST2BMC(bt->write_data[i]); | 331 | HOST2BMC(bt->write_data[i]); |
272 | } | 332 | } |
273 | 333 | ||
274 | static inline int read_all_bytes(struct si_sm_data *bt) | 334 | static inline int read_all_bytes(struct si_sm_data *bt) |
275 | { | 335 | { |
276 | unsigned char i; | 336 | unsigned char i; |
277 | 337 | ||
338 | /* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode. | ||
339 | Keep layout of first four bytes aligned with write_data[] */ | ||
340 | |||
278 | bt->read_data[0] = BMC2HOST; | 341 | bt->read_data[0] = BMC2HOST; |
279 | bt->read_count = bt->read_data[0]; | 342 | bt->read_count = bt->read_data[0]; |
280 | if (bt_debug & BT_DEBUG_MSG) | ||
281 | printk(KERN_WARNING "BT: read %d bytes:", bt->read_count); | ||
282 | 343 | ||
283 | /* minimum: length, NetFn, Seq, Cmd, cCode == 5 total, or 4 more | ||
284 | following the length byte. */ | ||
285 | if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) { | 344 | if (bt->read_count < 4 || bt->read_count >= IPMI_MAX_MSG_LENGTH) { |
286 | if (bt_debug & BT_DEBUG_MSG) | 345 | if (bt_debug & BT_DEBUG_MSG) |
287 | printk("bad length %d\n", bt->read_count); | 346 | printk(KERN_WARNING "BT: bad raw rsp len=%d\n", |
347 | bt->read_count); | ||
288 | bt->truncated = 1; | 348 | bt->truncated = 1; |
289 | return 1; /* let next XACTION START clean it up */ | 349 | return 1; /* let next XACTION START clean it up */ |
290 | } | 350 | } |
291 | for (i = 1; i <= bt->read_count; i++) | 351 | for (i = 1; i <= bt->read_count; i++) |
292 | bt->read_data[i] = BMC2HOST; | 352 | bt->read_data[i] = BMC2HOST; |
293 | bt->read_count++; /* account for the length byte */ | 353 | bt->read_count++; /* Account internally for length byte */ |
294 | 354 | ||
295 | if (bt_debug & BT_DEBUG_MSG) { | 355 | if (bt_debug & BT_DEBUG_MSG) { |
296 | for (i = 0; i < bt->read_count; i++) | 356 | int max = bt->read_count; |
357 | |||
358 | printk(KERN_WARNING "BT: got %d bytes seq=0x%02X", | ||
359 | max, bt->read_data[2]); | ||
360 | if (max > 16) | ||
361 | max = 16; | ||
362 | for (i = 0; i < max; i++) | ||
297 | printk (" %02x", bt->read_data[i]); | 363 | printk (" %02x", bt->read_data[i]); |
298 | printk ("\n"); | 364 | printk ("%s\n", bt->read_count == max ? "" : " ..."); |
299 | } | 365 | } |
300 | if (bt->seq != bt->write_data[2]) /* idiot check */ | ||
301 | printk(KERN_DEBUG "BT: internal error: sequence mismatch\n"); | ||
302 | 366 | ||
303 | /* per the spec, the (NetFn, Seq, Cmd) tuples should match */ | 367 | /* per the spec, the (NetFn[1], Seq[2], Cmd[3]) tuples must match */ |
304 | if ((bt->read_data[3] == bt->write_data[3]) && /* Cmd */ | 368 | if ((bt->read_data[3] == bt->write_data[3]) && |
305 | (bt->read_data[2] == bt->write_data[2]) && /* Sequence */ | 369 | (bt->read_data[2] == bt->write_data[2]) && |
306 | ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8))) | 370 | ((bt->read_data[1] & 0xF8) == (bt->write_data[1] & 0xF8))) |
307 | return 1; | 371 | return 1; |
308 | 372 | ||
309 | if (bt_debug & BT_DEBUG_MSG) | 373 | if (bt_debug & BT_DEBUG_MSG) |
310 | printk(KERN_WARNING "BT: bad packet: " | 374 | printk(KERN_WARNING "IPMI BT: bad packet: " |
311 | "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n", | 375 | "want 0x(%02X, %02X, %02X) got (%02X, %02X, %02X)\n", |
312 | bt->write_data[1], bt->write_data[2], bt->write_data[3], | 376 | bt->write_data[1] | 0x04, bt->write_data[2], bt->write_data[3], |
313 | bt->read_data[1], bt->read_data[2], bt->read_data[3]); | 377 | bt->read_data[1], bt->read_data[2], bt->read_data[3]); |
314 | return 0; | 378 | return 0; |
315 | } | 379 | } |
316 | 380 | ||
317 | /* Modifies bt->state appropriately, need to get into the bt_event() switch */ | 381 | /* Restart if retries are left, or return an error completion code */ |
318 | 382 | ||
319 | static void error_recovery(struct si_sm_data *bt, char *reason) | 383 | static enum si_sm_result error_recovery(struct si_sm_data *bt, |
384 | unsigned char status, | ||
385 | unsigned char cCode) | ||
320 | { | 386 | { |
321 | unsigned char status; | 387 | char *reason; |
322 | char buf[40]; /* For getting status */ | ||
323 | 388 | ||
324 | bt->timeout = BT_NORMAL_TIMEOUT; /* various places want to retry */ | 389 | bt->timeout = bt->BT_CAP_req2rsp; |
325 | 390 | ||
326 | status = BT_STATUS; | 391 | switch (cCode) { |
327 | printk(KERN_DEBUG "BT: %s in %s %s\n", reason, STATE2TXT, | 392 | case IPMI_TIMEOUT_ERR: |
328 | STATUS2TXT(buf)); | 393 | reason = "timeout"; |
394 | break; | ||
395 | default: | ||
396 | reason = "internal error"; | ||
397 | break; | ||
398 | } | ||
399 | |||
400 | printk(KERN_WARNING "IPMI BT: %s in %s %s ", /* open-ended line */ | ||
401 | reason, STATE2TXT, STATUS2TXT); | ||
329 | 402 | ||
403 | /* Per the IPMI spec, retries are based on the sequence number | ||
404 | known only to this module, so manage a restart here. */ | ||
330 | (bt->error_retries)++; | 405 | (bt->error_retries)++; |
331 | if (bt->error_retries > BT_RETRY_LIMIT) { | 406 | if (bt->error_retries < bt->BT_CAP_retries) { |
332 | printk(KERN_DEBUG "retry limit (%d) exceeded\n", BT_RETRY_LIMIT); | 407 | printk("%d retries left\n", |
333 | bt->state = BT_STATE_HOSED; | 408 | bt->BT_CAP_retries - bt->error_retries); |
334 | if (!bt->nonzero_status) | 409 | bt->state = BT_STATE_RESTART; |
335 | printk(KERN_ERR "IPMI: BT stuck, try power cycle\n"); | 410 | return SI_SM_CALL_WITHOUT_DELAY; |
336 | else if (bt->error_retries <= BT_RETRY_LIMIT + 1) { | ||
337 | printk(KERN_DEBUG "IPMI: BT reset (takes 5 secs)\n"); | ||
338 | bt->state = BT_STATE_RESET1; | ||
339 | } | ||
340 | return; | ||
341 | } | 411 | } |
342 | 412 | ||
343 | /* Sometimes the BMC queues get in an "off-by-one" state...*/ | 413 | printk("failed %d retries, sending error response\n", |
344 | if ((bt->state == BT_STATE_B2H_WAIT) && (status & BT_B2H_ATN)) { | 414 | bt->BT_CAP_retries); |
345 | printk(KERN_DEBUG "retry B2H_WAIT\n"); | 415 | if (!bt->nonzero_status) |
346 | return; | 416 | printk(KERN_ERR "IPMI BT: stuck, try power cycle\n"); |
417 | |||
418 | /* this is most likely during insmod */ | ||
419 | else if (bt->seq <= (unsigned char)(bt->BT_CAP_retries & 0xFF)) { | ||
420 | printk(KERN_WARNING "IPMI: BT reset (takes 5 secs)\n"); | ||
421 | bt->state = BT_STATE_RESET1; | ||
422 | return SI_SM_CALL_WITHOUT_DELAY; | ||
347 | } | 423 | } |
348 | 424 | ||
349 | printk(KERN_DEBUG "restart command\n"); | 425 | /* Concoct a useful error message, set up the next state, and |
350 | bt->state = BT_STATE_RESTART; | 426 | be done with this sequence. */ |
427 | |||
428 | bt->state = BT_STATE_IDLE; | ||
429 | switch (cCode) { | ||
430 | case IPMI_TIMEOUT_ERR: | ||
431 | if (status & BT_B_BUSY) { | ||
432 | cCode = IPMI_NODE_BUSY_ERR; | ||
433 | bt->state = BT_STATE_LONG_BUSY; | ||
434 | } | ||
435 | break; | ||
436 | default: | ||
437 | break; | ||
438 | } | ||
439 | force_result(bt, cCode); | ||
440 | return SI_SM_TRANSACTION_COMPLETE; | ||
351 | } | 441 | } |
352 | 442 | ||
353 | /* Check the status and (possibly) advance the BT state machine. The | 443 | /* Check status and (usually) take action and change this state machine. */ |
354 | default return is SI_SM_CALL_WITH_DELAY. */ | ||
355 | 444 | ||
356 | static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | 445 | static enum si_sm_result bt_event(struct si_sm_data *bt, long time) |
357 | { | 446 | { |
358 | unsigned char status; | 447 | unsigned char status, BT_CAP[8]; |
359 | char buf[40]; /* For getting status */ | 448 | static enum bt_states last_printed = BT_STATE_PRINTME; |
360 | int i; | 449 | int i; |
361 | 450 | ||
362 | status = BT_STATUS; | 451 | status = BT_STATUS; |
363 | bt->nonzero_status |= status; | 452 | bt->nonzero_status |= status; |
364 | 453 | if ((bt_debug & BT_DEBUG_STATES) && (bt->state != last_printed)) { | |
365 | if ((bt_debug & BT_DEBUG_STATES) && (bt->state != bt->last_state)) | ||
366 | printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n", | 454 | printk(KERN_WARNING "BT: %s %s TO=%ld - %ld \n", |
367 | STATE2TXT, | 455 | STATE2TXT, |
368 | STATUS2TXT(buf), | 456 | STATUS2TXT, |
369 | bt->timeout, | 457 | bt->timeout, |
370 | time); | 458 | time); |
371 | bt->last_state = bt->state; | 459 | last_printed = bt->state; |
460 | } | ||
372 | 461 | ||
373 | if (bt->state == BT_STATE_HOSED) | 462 | /* Commands that time out may still (eventually) provide a response. |
374 | return SI_SM_HOSED; | 463 | This stale response will get in the way of a new response so remove |
464 | it if possible (hopefully during IDLE). Even if it comes up later | ||
465 | it will be rejected by its (now-forgotten) seq number. */ | ||
466 | |||
467 | if ((bt->state < BT_STATE_WRITE_BYTES) && (status & BT_B2H_ATN)) { | ||
468 | drain_BMC2HOST(bt); | ||
469 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); | ||
470 | } | ||
375 | 471 | ||
376 | if (bt->state != BT_STATE_IDLE) { /* do timeout test */ | 472 | if ((bt->state != BT_STATE_IDLE) && |
473 | (bt->state < BT_STATE_PRINTME)) { /* check timeout */ | ||
377 | bt->timeout -= time; | 474 | bt->timeout -= time; |
378 | if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) { | 475 | if ((bt->timeout < 0) && (bt->state < BT_STATE_RESET1)) |
379 | error_recovery(bt, "timed out"); | 476 | return error_recovery(bt, |
380 | return SI_SM_CALL_WITHOUT_DELAY; | 477 | status, |
381 | } | 478 | IPMI_TIMEOUT_ERR); |
382 | } | 479 | } |
383 | 480 | ||
384 | switch (bt->state) { | 481 | switch (bt->state) { |
385 | 482 | ||
386 | case BT_STATE_IDLE: /* check for asynchronous messages */ | 483 | /* Idle state first checks for asynchronous messages from another |
484 | channel, then does some opportunistic housekeeping. */ | ||
485 | |||
486 | case BT_STATE_IDLE: | ||
387 | if (status & BT_SMS_ATN) { | 487 | if (status & BT_SMS_ATN) { |
388 | BT_CONTROL(BT_SMS_ATN); /* clear it */ | 488 | BT_CONTROL(BT_SMS_ATN); /* clear it */ |
389 | return SI_SM_ATTN; | 489 | return SI_SM_ATTN; |
390 | } | 490 | } |
391 | return SI_SM_IDLE; | ||
392 | 491 | ||
393 | case BT_STATE_XACTION_START: | 492 | if (status & BT_H_BUSY) /* clear a leftover H_BUSY */ |
394 | if (status & BT_H_BUSY) { | ||
395 | BT_CONTROL(BT_H_BUSY); | 493 | BT_CONTROL(BT_H_BUSY); |
396 | break; | ||
397 | } | ||
398 | if (status & BT_B2H_ATN) | ||
399 | break; | ||
400 | bt->state = BT_STATE_WRITE_BYTES; | ||
401 | return SI_SM_CALL_WITHOUT_DELAY; /* for logging */ | ||
402 | 494 | ||
403 | case BT_STATE_WRITE_BYTES: | 495 | /* Read BT capabilities if it hasn't been done yet */ |
496 | if (!bt->BT_CAP_outreqs) | ||
497 | BT_STATE_CHANGE(BT_STATE_CAPABILITIES_BEGIN, | ||
498 | SI_SM_CALL_WITHOUT_DELAY); | ||
499 | bt->timeout = bt->BT_CAP_req2rsp; | ||
500 | BT_SI_SM_RETURN(SI_SM_IDLE); | ||
501 | |||
502 | case BT_STATE_XACTION_START: | ||
404 | if (status & (BT_B_BUSY | BT_H2B_ATN)) | 503 | if (status & (BT_B_BUSY | BT_H2B_ATN)) |
405 | break; | 504 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); |
505 | if (BT_STATUS & BT_H_BUSY) | ||
506 | BT_CONTROL(BT_H_BUSY); /* force clear */ | ||
507 | BT_STATE_CHANGE(BT_STATE_WRITE_BYTES, | ||
508 | SI_SM_CALL_WITHOUT_DELAY); | ||
509 | |||
510 | case BT_STATE_WRITE_BYTES: | ||
511 | if (status & BT_H_BUSY) | ||
512 | BT_CONTROL(BT_H_BUSY); /* clear */ | ||
406 | BT_CONTROL(BT_CLR_WR_PTR); | 513 | BT_CONTROL(BT_CLR_WR_PTR); |
407 | write_all_bytes(bt); | 514 | write_all_bytes(bt); |
408 | BT_CONTROL(BT_H2B_ATN); /* clears too fast to catch? */ | 515 | BT_CONTROL(BT_H2B_ATN); /* can clear too fast to catch */ |
409 | bt->state = BT_STATE_WRITE_CONSUME; | 516 | BT_STATE_CHANGE(BT_STATE_WRITE_CONSUME, |
410 | return SI_SM_CALL_WITHOUT_DELAY; /* it MIGHT sail through */ | 517 | SI_SM_CALL_WITHOUT_DELAY); |
411 | |||
412 | case BT_STATE_WRITE_CONSUME: /* BMCs usually blow right thru here */ | ||
413 | if (status & (BT_H2B_ATN | BT_B_BUSY)) | ||
414 | break; | ||
415 | bt->state = BT_STATE_B2H_WAIT; | ||
416 | /* fall through with status */ | ||
417 | |||
418 | /* Stay in BT_STATE_B2H_WAIT until a packet matches. However, spinning | ||
419 | hard here, constantly reading status, seems to hold off the | ||
420 | generation of B2H_ATN so ALWAYS return CALL_WITH_DELAY. */ | ||
421 | |||
422 | case BT_STATE_B2H_WAIT: | ||
423 | if (!(status & BT_B2H_ATN)) | ||
424 | break; | ||
425 | |||
426 | /* Assume ordered, uncached writes: no need to wait */ | ||
427 | if (!(status & BT_H_BUSY)) | ||
428 | BT_CONTROL(BT_H_BUSY); /* set */ | ||
429 | BT_CONTROL(BT_B2H_ATN); /* clear it, ACK to the BMC */ | ||
430 | BT_CONTROL(BT_CLR_RD_PTR); /* reset the queue */ | ||
431 | i = read_all_bytes(bt); | ||
432 | BT_CONTROL(BT_H_BUSY); /* clear */ | ||
433 | if (!i) /* Try this state again */ | ||
434 | break; | ||
435 | bt->state = BT_STATE_READ_END; | ||
436 | return SI_SM_CALL_WITHOUT_DELAY; /* for logging */ | ||
437 | |||
438 | case BT_STATE_READ_END: | ||
439 | |||
440 | /* I could wait on BT_H_BUSY to go clear for a truly clean | ||
441 | exit. However, this is already done in XACTION_START | ||
442 | and the (possible) extra loop/status/possible wait affects | ||
443 | performance. So, as long as it works, just ignore H_BUSY */ | ||
444 | |||
445 | #ifdef MAKE_THIS_TRUE_IF_NECESSARY | ||
446 | 518 | ||
447 | if (status & BT_H_BUSY) | 519 | case BT_STATE_WRITE_CONSUME: |
448 | break; | 520 | if (status & (BT_B_BUSY | BT_H2B_ATN)) |
449 | #endif | 521 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); |
450 | bt->seq++; | 522 | BT_STATE_CHANGE(BT_STATE_READ_WAIT, |
451 | bt->state = BT_STATE_IDLE; | 523 | SI_SM_CALL_WITHOUT_DELAY); |
452 | return SI_SM_TRANSACTION_COMPLETE; | 524 | |
525 | /* Spinning hard can suppress B2H_ATN and force a timeout */ | ||
526 | |||
527 | case BT_STATE_READ_WAIT: | ||
528 | if (!(status & BT_B2H_ATN)) | ||
529 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); | ||
530 | BT_CONTROL(BT_H_BUSY); /* set */ | ||
531 | |||
532 | /* Uncached, ordered writes should just proceeed serially but | ||
533 | some BMCs don't clear B2H_ATN with one hit. Fast-path a | ||
534 | workaround without too much penalty to the general case. */ | ||
535 | |||
536 | BT_CONTROL(BT_B2H_ATN); /* clear it to ACK the BMC */ | ||
537 | BT_STATE_CHANGE(BT_STATE_CLEAR_B2H, | ||
538 | SI_SM_CALL_WITHOUT_DELAY); | ||
539 | |||
540 | case BT_STATE_CLEAR_B2H: | ||
541 | if (status & BT_B2H_ATN) { /* keep hitting it */ | ||
542 | BT_CONTROL(BT_B2H_ATN); | ||
543 | BT_SI_SM_RETURN(SI_SM_CALL_WITH_DELAY); | ||
544 | } | ||
545 | BT_STATE_CHANGE(BT_STATE_READ_BYTES, | ||
546 | SI_SM_CALL_WITHOUT_DELAY); | ||
547 | |||
548 | case BT_STATE_READ_BYTES: | ||
549 | if (!(status & BT_H_BUSY)) /* check in case of retry */ | ||
550 | BT_CONTROL(BT_H_BUSY); | ||
551 | BT_CONTROL(BT_CLR_RD_PTR); /* start of BMC2HOST buffer */ | ||
552 | i = read_all_bytes(bt); /* true == packet seq match */ | ||
553 | BT_CONTROL(BT_H_BUSY); /* NOW clear */ | ||
554 | if (!i) /* Not my message */ | ||
555 | BT_STATE_CHANGE(BT_STATE_READ_WAIT, | ||
556 | SI_SM_CALL_WITHOUT_DELAY); | ||
557 | bt->state = bt->complete; | ||
558 | return bt->state == BT_STATE_IDLE ? /* where to next? */ | ||
559 | SI_SM_TRANSACTION_COMPLETE : /* normal */ | ||
560 | SI_SM_CALL_WITHOUT_DELAY; /* Startup magic */ | ||
561 | |||
562 | case BT_STATE_LONG_BUSY: /* For example: after FW update */ | ||
563 | if (!(status & BT_B_BUSY)) { | ||
564 | reset_flags(bt); /* next state is now IDLE */ | ||
565 | bt_init_data(bt, bt->io); | ||
566 | } | ||
567 | return SI_SM_CALL_WITH_DELAY; /* No repeat printing */ | ||
453 | 568 | ||
454 | case BT_STATE_RESET1: | 569 | case BT_STATE_RESET1: |
455 | reset_flags(bt); | 570 | reset_flags(bt); |
456 | bt->timeout = BT_RESET_DELAY; | 571 | drain_BMC2HOST(bt); |
457 | bt->state = BT_STATE_RESET2; | 572 | BT_STATE_CHANGE(BT_STATE_RESET2, |
458 | break; | 573 | SI_SM_CALL_WITH_DELAY); |
459 | 574 | ||
460 | case BT_STATE_RESET2: /* Send a soft reset */ | 575 | case BT_STATE_RESET2: /* Send a soft reset */ |
461 | BT_CONTROL(BT_CLR_WR_PTR); | 576 | BT_CONTROL(BT_CLR_WR_PTR); |
@@ -464,29 +579,59 @@ static enum si_sm_result bt_event(struct si_sm_data *bt, long time) | |||
464 | HOST2BMC(42); /* Sequence number */ | 579 | HOST2BMC(42); /* Sequence number */ |
465 | HOST2BMC(3); /* Cmd == Soft reset */ | 580 | HOST2BMC(3); /* Cmd == Soft reset */ |
466 | BT_CONTROL(BT_H2B_ATN); | 581 | BT_CONTROL(BT_H2B_ATN); |
467 | bt->state = BT_STATE_RESET3; | 582 | bt->timeout = BT_RESET_DELAY * 1000000; |
468 | break; | 583 | BT_STATE_CHANGE(BT_STATE_RESET3, |
584 | SI_SM_CALL_WITH_DELAY); | ||
469 | 585 | ||
470 | case BT_STATE_RESET3: | 586 | case BT_STATE_RESET3: /* Hold off everything for a bit */ |
471 | if (bt->timeout > 0) | 587 | if (bt->timeout > 0) |
472 | return SI_SM_CALL_WITH_DELAY; | 588 | return SI_SM_CALL_WITH_DELAY; |
473 | bt->state = BT_STATE_RESTART; /* printk in debug modes */ | 589 | drain_BMC2HOST(bt); |
474 | break; | 590 | BT_STATE_CHANGE(BT_STATE_RESTART, |
591 | SI_SM_CALL_WITH_DELAY); | ||
475 | 592 | ||
476 | case BT_STATE_RESTART: /* don't reset retries! */ | 593 | case BT_STATE_RESTART: /* don't reset retries or seq! */ |
477 | reset_flags(bt); | ||
478 | bt->write_data[2] = ++bt->seq; | ||
479 | bt->read_count = 0; | 594 | bt->read_count = 0; |
480 | bt->nonzero_status = 0; | 595 | bt->nonzero_status = 0; |
481 | bt->timeout = BT_NORMAL_TIMEOUT; | 596 | bt->timeout = bt->BT_CAP_req2rsp; |
482 | bt->state = BT_STATE_XACTION_START; | 597 | BT_STATE_CHANGE(BT_STATE_XACTION_START, |
483 | break; | 598 | SI_SM_CALL_WITH_DELAY); |
484 | 599 | ||
485 | default: /* HOSED is supposed to be caught much earlier */ | 600 | /* Get BT Capabilities, using timing of upper level state machine. |
486 | error_recovery(bt, "internal logic error"); | 601 | Set outreqs to prevent infinite loop on timeout. */ |
487 | break; | 602 | case BT_STATE_CAPABILITIES_BEGIN: |
488 | } | 603 | bt->BT_CAP_outreqs = 1; |
489 | return SI_SM_CALL_WITH_DELAY; | 604 | { |
605 | unsigned char GetBT_CAP[] = { 0x18, 0x36 }; | ||
606 | bt->state = BT_STATE_IDLE; | ||
607 | bt_start_transaction(bt, GetBT_CAP, sizeof(GetBT_CAP)); | ||
608 | } | ||
609 | bt->complete = BT_STATE_CAPABILITIES_END; | ||
610 | BT_STATE_CHANGE(BT_STATE_XACTION_START, | ||
611 | SI_SM_CALL_WITH_DELAY); | ||
612 | |||
613 | case BT_STATE_CAPABILITIES_END: | ||
614 | i = bt_get_result(bt, BT_CAP, sizeof(BT_CAP)); | ||
615 | bt_init_data(bt, bt->io); | ||
616 | if ((i == 8) && !BT_CAP[2]) { | ||
617 | bt->BT_CAP_outreqs = BT_CAP[3]; | ||
618 | bt->BT_CAP_req2rsp = BT_CAP[6] * 1000000; | ||
619 | bt->BT_CAP_retries = BT_CAP[7]; | ||
620 | } else | ||
621 | printk(KERN_WARNING "IPMI BT: using default values\n"); | ||
622 | if (!bt->BT_CAP_outreqs) | ||
623 | bt->BT_CAP_outreqs = 1; | ||
624 | printk(KERN_WARNING "IPMI BT: req2rsp=%ld secs retries=%d\n", | ||
625 | bt->BT_CAP_req2rsp / 1000000L, bt->BT_CAP_retries); | ||
626 | bt->timeout = bt->BT_CAP_req2rsp; | ||
627 | return SI_SM_CALL_WITHOUT_DELAY; | ||
628 | |||
629 | default: /* should never occur */ | ||
630 | return error_recovery(bt, | ||
631 | status, | ||
632 | IPMI_ERR_UNSPECIFIED); | ||
633 | } | ||
634 | return SI_SM_CALL_WITH_DELAY; | ||
490 | } | 635 | } |
491 | 636 | ||
492 | static int bt_detect(struct si_sm_data *bt) | 637 | static int bt_detect(struct si_sm_data *bt) |
@@ -497,7 +642,7 @@ static int bt_detect(struct si_sm_data *bt) | |||
497 | test that first. The calling routine uses negative logic. */ | 642 | test that first. The calling routine uses negative logic. */ |
498 | 643 | ||
499 | if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) | 644 | if ((BT_STATUS == 0xFF) && (BT_INTMASK_R == 0xFF)) |
500 | return 1; | 645 | return 1; |
501 | reset_flags(bt); | 646 | reset_flags(bt); |
502 | return 0; | 647 | return 0; |
503 | } | 648 | } |
@@ -513,11 +658,11 @@ static int bt_size(void) | |||
513 | 658 | ||
514 | struct si_sm_handlers bt_smi_handlers = | 659 | struct si_sm_handlers bt_smi_handlers = |
515 | { | 660 | { |
516 | .init_data = bt_init_data, | 661 | .init_data = bt_init_data, |
517 | .start_transaction = bt_start_transaction, | 662 | .start_transaction = bt_start_transaction, |
518 | .get_result = bt_get_result, | 663 | .get_result = bt_get_result, |
519 | .event = bt_event, | 664 | .event = bt_event, |
520 | .detect = bt_detect, | 665 | .detect = bt_detect, |
521 | .cleanup = bt_cleanup, | 666 | .cleanup = bt_cleanup, |
522 | .size = bt_size, | 667 | .size = bt_size, |
523 | }; | 668 | }; |
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 81fcf0ce21d1..e257835a9a73 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -596,6 +596,31 @@ static int ipmi_ioctl(struct inode *inode, | |||
596 | rv = 0; | 596 | rv = 0; |
597 | break; | 597 | break; |
598 | } | 598 | } |
599 | |||
600 | case IPMICTL_GET_MAINTENANCE_MODE_CMD: | ||
601 | { | ||
602 | int mode; | ||
603 | |||
604 | mode = ipmi_get_maintenance_mode(priv->user); | ||
605 | if (copy_to_user(arg, &mode, sizeof(mode))) { | ||
606 | rv = -EFAULT; | ||
607 | break; | ||
608 | } | ||
609 | rv = 0; | ||
610 | break; | ||
611 | } | ||
612 | |||
613 | case IPMICTL_SET_MAINTENANCE_MODE_CMD: | ||
614 | { | ||
615 | int mode; | ||
616 | |||
617 | if (copy_from_user(&mode, arg, sizeof(mode))) { | ||
618 | rv = -EFAULT; | ||
619 | break; | ||
620 | } | ||
621 | rv = ipmi_set_maintenance_mode(priv->user, mode); | ||
622 | break; | ||
623 | } | ||
599 | } | 624 | } |
600 | 625 | ||
601 | return rv; | 626 | return rv; |
@@ -773,7 +798,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, | |||
773 | if (copy_to_user(precv64, &recv64, sizeof(recv64))) | 798 | if (copy_to_user(precv64, &recv64, sizeof(recv64))) |
774 | return -EFAULT; | 799 | return -EFAULT; |
775 | 800 | ||
776 | rc = ipmi_ioctl(filep->f_dentry->d_inode, filep, | 801 | rc = ipmi_ioctl(filep->f_path.dentry->d_inode, filep, |
777 | ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) | 802 | ((cmd == COMPAT_IPMICTL_RECEIVE_MSG) |
778 | ? IPMICTL_RECEIVE_MSG | 803 | ? IPMICTL_RECEIVE_MSG |
779 | : IPMICTL_RECEIVE_MSG_TRUNC), | 804 | : IPMICTL_RECEIVE_MSG_TRUNC), |
@@ -790,7 +815,7 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd, | |||
790 | return rc; | 815 | return rc; |
791 | } | 816 | } |
792 | default: | 817 | default: |
793 | return ipmi_ioctl(filep->f_dentry->d_inode, filep, cmd, arg); | 818 | return ipmi_ioctl(filep->f_path.dentry->d_inode, filep, cmd, arg); |
794 | } | 819 | } |
795 | } | 820 | } |
796 | #endif | 821 | #endif |
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c index 2062675f9e99..c1b8228cb7b6 100644 --- a/drivers/char/ipmi/ipmi_kcs_sm.c +++ b/drivers/char/ipmi/ipmi_kcs_sm.c | |||
@@ -93,8 +93,8 @@ enum kcs_states { | |||
93 | state machine. */ | 93 | state machine. */ |
94 | }; | 94 | }; |
95 | 95 | ||
96 | #define MAX_KCS_READ_SIZE 80 | 96 | #define MAX_KCS_READ_SIZE IPMI_MAX_MSG_LENGTH |
97 | #define MAX_KCS_WRITE_SIZE 80 | 97 | #define MAX_KCS_WRITE_SIZE IPMI_MAX_MSG_LENGTH |
98 | 98 | ||
99 | /* Timeouts in microseconds. */ | 99 | /* Timeouts in microseconds. */ |
100 | #define IBF_RETRY_TIMEOUT 1000000 | 100 | #define IBF_RETRY_TIMEOUT 1000000 |
@@ -261,12 +261,14 @@ static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data, | |||
261 | { | 261 | { |
262 | unsigned int i; | 262 | unsigned int i; |
263 | 263 | ||
264 | if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) { | 264 | if (size < 2) |
265 | return -1; | 265 | return IPMI_REQ_LEN_INVALID_ERR; |
266 | } | 266 | if (size > MAX_KCS_WRITE_SIZE) |
267 | if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) { | 267 | return IPMI_REQ_LEN_EXCEEDED_ERR; |
268 | return -2; | 268 | |
269 | } | 269 | if ((kcs->state != KCS_IDLE) && (kcs->state != KCS_HOSED)) |
270 | return IPMI_NOT_IN_MY_STATE_ERR; | ||
271 | |||
270 | if (kcs_debug & KCS_DEBUG_MSG) { | 272 | if (kcs_debug & KCS_DEBUG_MSG) { |
271 | printk(KERN_DEBUG "start_kcs_transaction -"); | 273 | printk(KERN_DEBUG "start_kcs_transaction -"); |
272 | for (i = 0; i < size; i ++) { | 274 | for (i = 0; i < size; i ++) { |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index c47add8e47df..5703ee28e1cc 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define PFX "IPMI message handler: " | 49 | #define PFX "IPMI message handler: " |
50 | 50 | ||
51 | #define IPMI_DRIVER_VERSION "39.0" | 51 | #define IPMI_DRIVER_VERSION "39.1" |
52 | 52 | ||
53 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); | 53 | static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void); |
54 | static int ipmi_init_msghandler(void); | 54 | static int ipmi_init_msghandler(void); |
@@ -59,6 +59,9 @@ static int initialized = 0; | |||
59 | static struct proc_dir_entry *proc_ipmi_root = NULL; | 59 | static struct proc_dir_entry *proc_ipmi_root = NULL; |
60 | #endif /* CONFIG_PROC_FS */ | 60 | #endif /* CONFIG_PROC_FS */ |
61 | 61 | ||
62 | /* Remain in auto-maintenance mode for this amount of time (in ms). */ | ||
63 | #define IPMI_MAINTENANCE_MODE_TIMEOUT 30000 | ||
64 | |||
62 | #define MAX_EVENTS_IN_QUEUE 25 | 65 | #define MAX_EVENTS_IN_QUEUE 25 |
63 | 66 | ||
64 | /* Don't let a message sit in a queue forever, always time it with at lest | 67 | /* Don't let a message sit in a queue forever, always time it with at lest |
@@ -193,17 +196,28 @@ struct ipmi_smi | |||
193 | 196 | ||
194 | struct kref refcount; | 197 | struct kref refcount; |
195 | 198 | ||
199 | /* Used for a list of interfaces. */ | ||
200 | struct list_head link; | ||
201 | |||
196 | /* The list of upper layers that are using me. seq_lock | 202 | /* The list of upper layers that are using me. seq_lock |
197 | * protects this. */ | 203 | * protects this. */ |
198 | struct list_head users; | 204 | struct list_head users; |
199 | 205 | ||
206 | /* Information to supply to users. */ | ||
207 | unsigned char ipmi_version_major; | ||
208 | unsigned char ipmi_version_minor; | ||
209 | |||
200 | /* Used for wake ups at startup. */ | 210 | /* Used for wake ups at startup. */ |
201 | wait_queue_head_t waitq; | 211 | wait_queue_head_t waitq; |
202 | 212 | ||
203 | struct bmc_device *bmc; | 213 | struct bmc_device *bmc; |
204 | char *my_dev_name; | 214 | char *my_dev_name; |
215 | char *sysfs_name; | ||
205 | 216 | ||
206 | /* This is the lower-layer's sender routine. */ | 217 | /* This is the lower-layer's sender routine. Note that you |
218 | * must either be holding the ipmi_interfaces_mutex or be in | ||
219 | * an umpreemptible region to use this. You must fetch the | ||
220 | * value into a local variable and make sure it is not NULL. */ | ||
207 | struct ipmi_smi_handlers *handlers; | 221 | struct ipmi_smi_handlers *handlers; |
208 | void *send_info; | 222 | void *send_info; |
209 | 223 | ||
@@ -242,6 +256,7 @@ struct ipmi_smi | |||
242 | spinlock_t events_lock; /* For dealing with event stuff. */ | 256 | spinlock_t events_lock; /* For dealing with event stuff. */ |
243 | struct list_head waiting_events; | 257 | struct list_head waiting_events; |
244 | unsigned int waiting_events_count; /* How many events in queue? */ | 258 | unsigned int waiting_events_count; /* How many events in queue? */ |
259 | int delivering_events; | ||
245 | 260 | ||
246 | /* The event receiver for my BMC, only really used at panic | 261 | /* The event receiver for my BMC, only really used at panic |
247 | shutdown as a place to store this. */ | 262 | shutdown as a place to store this. */ |
@@ -250,6 +265,12 @@ struct ipmi_smi | |||
250 | unsigned char local_sel_device; | 265 | unsigned char local_sel_device; |
251 | unsigned char local_event_generator; | 266 | unsigned char local_event_generator; |
252 | 267 | ||
268 | /* For handling of maintenance mode. */ | ||
269 | int maintenance_mode; | ||
270 | int maintenance_mode_enable; | ||
271 | int auto_maintenance_timeout; | ||
272 | spinlock_t maintenance_mode_lock; /* Used in a timer... */ | ||
273 | |||
253 | /* A cheap hack, if this is non-null and a message to an | 274 | /* A cheap hack, if this is non-null and a message to an |
254 | interface comes in with a NULL user, call this routine with | 275 | interface comes in with a NULL user, call this routine with |
255 | it. Note that the message will still be freed by the | 276 | it. Note that the message will still be freed by the |
@@ -338,13 +359,6 @@ struct ipmi_smi | |||
338 | }; | 359 | }; |
339 | #define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev) | 360 | #define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev) |
340 | 361 | ||
341 | /* Used to mark an interface entry that cannot be used but is not a | ||
342 | * free entry, either, primarily used at creation and deletion time so | ||
343 | * a slot doesn't get reused too quickly. */ | ||
344 | #define IPMI_INVALID_INTERFACE_ENTRY ((ipmi_smi_t) ((long) 1)) | ||
345 | #define IPMI_INVALID_INTERFACE(i) (((i) == NULL) \ | ||
346 | || (i == IPMI_INVALID_INTERFACE_ENTRY)) | ||
347 | |||
348 | /** | 362 | /** |
349 | * The driver model view of the IPMI messaging driver. | 363 | * The driver model view of the IPMI messaging driver. |
350 | */ | 364 | */ |
@@ -354,16 +368,13 @@ static struct device_driver ipmidriver = { | |||
354 | }; | 368 | }; |
355 | static DEFINE_MUTEX(ipmidriver_mutex); | 369 | static DEFINE_MUTEX(ipmidriver_mutex); |
356 | 370 | ||
357 | #define MAX_IPMI_INTERFACES 4 | 371 | static struct list_head ipmi_interfaces = LIST_HEAD_INIT(ipmi_interfaces); |
358 | static ipmi_smi_t ipmi_interfaces[MAX_IPMI_INTERFACES]; | 372 | static DEFINE_MUTEX(ipmi_interfaces_mutex); |
359 | |||
360 | /* Directly protects the ipmi_interfaces data structure. */ | ||
361 | static DEFINE_SPINLOCK(interfaces_lock); | ||
362 | 373 | ||
363 | /* List of watchers that want to know when smi's are added and | 374 | /* List of watchers that want to know when smi's are added and |
364 | deleted. */ | 375 | deleted. */ |
365 | static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers); | 376 | static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers); |
366 | static DECLARE_RWSEM(smi_watchers_sem); | 377 | static DEFINE_MUTEX(smi_watchers_mutex); |
367 | 378 | ||
368 | 379 | ||
369 | static void free_recv_msg_list(struct list_head *q) | 380 | static void free_recv_msg_list(struct list_head *q) |
@@ -423,48 +434,84 @@ static void intf_free(struct kref *ref) | |||
423 | kfree(intf); | 434 | kfree(intf); |
424 | } | 435 | } |
425 | 436 | ||
437 | struct watcher_entry { | ||
438 | int intf_num; | ||
439 | ipmi_smi_t intf; | ||
440 | struct list_head link; | ||
441 | }; | ||
442 | |||
426 | int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) | 443 | int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) |
427 | { | 444 | { |
428 | int i; | 445 | ipmi_smi_t intf; |
429 | unsigned long flags; | 446 | struct list_head to_deliver = LIST_HEAD_INIT(to_deliver); |
447 | struct watcher_entry *e, *e2; | ||
448 | |||
449 | mutex_lock(&smi_watchers_mutex); | ||
450 | |||
451 | mutex_lock(&ipmi_interfaces_mutex); | ||
430 | 452 | ||
431 | down_write(&smi_watchers_sem); | 453 | /* Build a list of things to deliver. */ |
432 | list_add(&(watcher->link), &smi_watchers); | 454 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
433 | up_write(&smi_watchers_sem); | 455 | if (intf->intf_num == -1) |
434 | spin_lock_irqsave(&interfaces_lock, flags); | ||
435 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | ||
436 | ipmi_smi_t intf = ipmi_interfaces[i]; | ||
437 | if (IPMI_INVALID_INTERFACE(intf)) | ||
438 | continue; | 456 | continue; |
439 | spin_unlock_irqrestore(&interfaces_lock, flags); | 457 | e = kmalloc(sizeof(*e), GFP_KERNEL); |
440 | watcher->new_smi(i, intf->si_dev); | 458 | if (!e) |
441 | spin_lock_irqsave(&interfaces_lock, flags); | 459 | goto out_err; |
460 | kref_get(&intf->refcount); | ||
461 | e->intf = intf; | ||
462 | e->intf_num = intf->intf_num; | ||
463 | list_add_tail(&e->link, &to_deliver); | ||
442 | } | 464 | } |
443 | spin_unlock_irqrestore(&interfaces_lock, flags); | 465 | |
466 | /* We will succeed, so add it to the list. */ | ||
467 | list_add(&watcher->link, &smi_watchers); | ||
468 | |||
469 | mutex_unlock(&ipmi_interfaces_mutex); | ||
470 | |||
471 | list_for_each_entry_safe(e, e2, &to_deliver, link) { | ||
472 | list_del(&e->link); | ||
473 | watcher->new_smi(e->intf_num, e->intf->si_dev); | ||
474 | kref_put(&e->intf->refcount, intf_free); | ||
475 | kfree(e); | ||
476 | } | ||
477 | |||
478 | mutex_unlock(&smi_watchers_mutex); | ||
479 | |||
444 | return 0; | 480 | return 0; |
481 | |||
482 | out_err: | ||
483 | mutex_unlock(&ipmi_interfaces_mutex); | ||
484 | mutex_unlock(&smi_watchers_mutex); | ||
485 | list_for_each_entry_safe(e, e2, &to_deliver, link) { | ||
486 | list_del(&e->link); | ||
487 | kref_put(&e->intf->refcount, intf_free); | ||
488 | kfree(e); | ||
489 | } | ||
490 | return -ENOMEM; | ||
445 | } | 491 | } |
446 | 492 | ||
447 | int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher) | 493 | int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher) |
448 | { | 494 | { |
449 | down_write(&smi_watchers_sem); | 495 | mutex_lock(&smi_watchers_mutex); |
450 | list_del(&(watcher->link)); | 496 | list_del(&(watcher->link)); |
451 | up_write(&smi_watchers_sem); | 497 | mutex_unlock(&smi_watchers_mutex); |
452 | return 0; | 498 | return 0; |
453 | } | 499 | } |
454 | 500 | ||
501 | /* | ||
502 | * Must be called with smi_watchers_mutex held. | ||
503 | */ | ||
455 | static void | 504 | static void |
456 | call_smi_watchers(int i, struct device *dev) | 505 | call_smi_watchers(int i, struct device *dev) |
457 | { | 506 | { |
458 | struct ipmi_smi_watcher *w; | 507 | struct ipmi_smi_watcher *w; |
459 | 508 | ||
460 | down_read(&smi_watchers_sem); | ||
461 | list_for_each_entry(w, &smi_watchers, link) { | 509 | list_for_each_entry(w, &smi_watchers, link) { |
462 | if (try_module_get(w->owner)) { | 510 | if (try_module_get(w->owner)) { |
463 | w->new_smi(i, dev); | 511 | w->new_smi(i, dev); |
464 | module_put(w->owner); | 512 | module_put(w->owner); |
465 | } | 513 | } |
466 | } | 514 | } |
467 | up_read(&smi_watchers_sem); | ||
468 | } | 515 | } |
469 | 516 | ||
470 | static int | 517 | static int |
@@ -590,6 +637,17 @@ static void deliver_response(struct ipmi_recv_msg *msg) | |||
590 | } | 637 | } |
591 | } | 638 | } |
592 | 639 | ||
640 | static void | ||
641 | deliver_err_response(struct ipmi_recv_msg *msg, int err) | ||
642 | { | ||
643 | msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | ||
644 | msg->msg_data[0] = err; | ||
645 | msg->msg.netfn |= 1; /* Convert to a response. */ | ||
646 | msg->msg.data_len = 1; | ||
647 | msg->msg.data = msg->msg_data; | ||
648 | deliver_response(msg); | ||
649 | } | ||
650 | |||
593 | /* Find the next sequence number not being used and add the given | 651 | /* Find the next sequence number not being used and add the given |
594 | message with the given timeout to the sequence table. This must be | 652 | message with the given timeout to the sequence table. This must be |
595 | called with the interface's seq_lock held. */ | 653 | called with the interface's seq_lock held. */ |
@@ -727,14 +785,8 @@ static int intf_err_seq(ipmi_smi_t intf, | |||
727 | } | 785 | } |
728 | spin_unlock_irqrestore(&(intf->seq_lock), flags); | 786 | spin_unlock_irqrestore(&(intf->seq_lock), flags); |
729 | 787 | ||
730 | if (msg) { | 788 | if (msg) |
731 | msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | 789 | deliver_err_response(msg, err); |
732 | msg->msg_data[0] = err; | ||
733 | msg->msg.netfn |= 1; /* Convert to a response. */ | ||
734 | msg->msg.data_len = 1; | ||
735 | msg->msg.data = msg->msg_data; | ||
736 | deliver_response(msg); | ||
737 | } | ||
738 | 790 | ||
739 | return rv; | 791 | return rv; |
740 | } | 792 | } |
@@ -776,17 +828,18 @@ int ipmi_create_user(unsigned int if_num, | |||
776 | if (!new_user) | 828 | if (!new_user) |
777 | return -ENOMEM; | 829 | return -ENOMEM; |
778 | 830 | ||
779 | spin_lock_irqsave(&interfaces_lock, flags); | 831 | mutex_lock(&ipmi_interfaces_mutex); |
780 | intf = ipmi_interfaces[if_num]; | 832 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
781 | if ((if_num >= MAX_IPMI_INTERFACES) || IPMI_INVALID_INTERFACE(intf)) { | 833 | if (intf->intf_num == if_num) |
782 | spin_unlock_irqrestore(&interfaces_lock, flags); | 834 | goto found; |
783 | rv = -EINVAL; | ||
784 | goto out_kfree; | ||
785 | } | 835 | } |
836 | /* Not found, return an error */ | ||
837 | rv = -EINVAL; | ||
838 | goto out_kfree; | ||
786 | 839 | ||
840 | found: | ||
787 | /* Note that each existing user holds a refcount to the interface. */ | 841 | /* Note that each existing user holds a refcount to the interface. */ |
788 | kref_get(&intf->refcount); | 842 | kref_get(&intf->refcount); |
789 | spin_unlock_irqrestore(&interfaces_lock, flags); | ||
790 | 843 | ||
791 | kref_init(&new_user->refcount); | 844 | kref_init(&new_user->refcount); |
792 | new_user->handler = handler; | 845 | new_user->handler = handler; |
@@ -807,6 +860,10 @@ int ipmi_create_user(unsigned int if_num, | |||
807 | } | 860 | } |
808 | } | 861 | } |
809 | 862 | ||
863 | /* Hold the lock so intf->handlers is guaranteed to be good | ||
864 | * until now */ | ||
865 | mutex_unlock(&ipmi_interfaces_mutex); | ||
866 | |||
810 | new_user->valid = 1; | 867 | new_user->valid = 1; |
811 | spin_lock_irqsave(&intf->seq_lock, flags); | 868 | spin_lock_irqsave(&intf->seq_lock, flags); |
812 | list_add_rcu(&new_user->link, &intf->users); | 869 | list_add_rcu(&new_user->link, &intf->users); |
@@ -817,6 +874,7 @@ int ipmi_create_user(unsigned int if_num, | |||
817 | out_kref: | 874 | out_kref: |
818 | kref_put(&intf->refcount, intf_free); | 875 | kref_put(&intf->refcount, intf_free); |
819 | out_kfree: | 876 | out_kfree: |
877 | mutex_unlock(&ipmi_interfaces_mutex); | ||
820 | kfree(new_user); | 878 | kfree(new_user); |
821 | return rv; | 879 | return rv; |
822 | } | 880 | } |
@@ -846,6 +904,7 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
846 | && (intf->seq_table[i].recv_msg->user == user)) | 904 | && (intf->seq_table[i].recv_msg->user == user)) |
847 | { | 905 | { |
848 | intf->seq_table[i].inuse = 0; | 906 | intf->seq_table[i].inuse = 0; |
907 | ipmi_free_recv_msg(intf->seq_table[i].recv_msg); | ||
849 | } | 908 | } |
850 | } | 909 | } |
851 | spin_unlock_irqrestore(&intf->seq_lock, flags); | 910 | spin_unlock_irqrestore(&intf->seq_lock, flags); |
@@ -872,9 +931,13 @@ int ipmi_destroy_user(ipmi_user_t user) | |||
872 | kfree(rcvr); | 931 | kfree(rcvr); |
873 | } | 932 | } |
874 | 933 | ||
875 | module_put(intf->handlers->owner); | 934 | mutex_lock(&ipmi_interfaces_mutex); |
876 | if (intf->handlers->dec_usecount) | 935 | if (intf->handlers) { |
877 | intf->handlers->dec_usecount(intf->send_info); | 936 | module_put(intf->handlers->owner); |
937 | if (intf->handlers->dec_usecount) | ||
938 | intf->handlers->dec_usecount(intf->send_info); | ||
939 | } | ||
940 | mutex_unlock(&ipmi_interfaces_mutex); | ||
878 | 941 | ||
879 | kref_put(&intf->refcount, intf_free); | 942 | kref_put(&intf->refcount, intf_free); |
880 | 943 | ||
@@ -887,8 +950,8 @@ void ipmi_get_version(ipmi_user_t user, | |||
887 | unsigned char *major, | 950 | unsigned char *major, |
888 | unsigned char *minor) | 951 | unsigned char *minor) |
889 | { | 952 | { |
890 | *major = ipmi_version_major(&user->intf->bmc->id); | 953 | *major = user->intf->ipmi_version_major; |
891 | *minor = ipmi_version_minor(&user->intf->bmc->id); | 954 | *minor = user->intf->ipmi_version_minor; |
892 | } | 955 | } |
893 | 956 | ||
894 | int ipmi_set_my_address(ipmi_user_t user, | 957 | int ipmi_set_my_address(ipmi_user_t user, |
@@ -931,6 +994,65 @@ int ipmi_get_my_LUN(ipmi_user_t user, | |||
931 | return 0; | 994 | return 0; |
932 | } | 995 | } |
933 | 996 | ||
997 | int ipmi_get_maintenance_mode(ipmi_user_t user) | ||
998 | { | ||
999 | int mode; | ||
1000 | unsigned long flags; | ||
1001 | |||
1002 | spin_lock_irqsave(&user->intf->maintenance_mode_lock, flags); | ||
1003 | mode = user->intf->maintenance_mode; | ||
1004 | spin_unlock_irqrestore(&user->intf->maintenance_mode_lock, flags); | ||
1005 | |||
1006 | return mode; | ||
1007 | } | ||
1008 | EXPORT_SYMBOL(ipmi_get_maintenance_mode); | ||
1009 | |||
1010 | static void maintenance_mode_update(ipmi_smi_t intf) | ||
1011 | { | ||
1012 | if (intf->handlers->set_maintenance_mode) | ||
1013 | intf->handlers->set_maintenance_mode( | ||
1014 | intf->send_info, intf->maintenance_mode_enable); | ||
1015 | } | ||
1016 | |||
1017 | int ipmi_set_maintenance_mode(ipmi_user_t user, int mode) | ||
1018 | { | ||
1019 | int rv = 0; | ||
1020 | unsigned long flags; | ||
1021 | ipmi_smi_t intf = user->intf; | ||
1022 | |||
1023 | spin_lock_irqsave(&intf->maintenance_mode_lock, flags); | ||
1024 | if (intf->maintenance_mode != mode) { | ||
1025 | switch (mode) { | ||
1026 | case IPMI_MAINTENANCE_MODE_AUTO: | ||
1027 | intf->maintenance_mode = mode; | ||
1028 | intf->maintenance_mode_enable | ||
1029 | = (intf->auto_maintenance_timeout > 0); | ||
1030 | break; | ||
1031 | |||
1032 | case IPMI_MAINTENANCE_MODE_OFF: | ||
1033 | intf->maintenance_mode = mode; | ||
1034 | intf->maintenance_mode_enable = 0; | ||
1035 | break; | ||
1036 | |||
1037 | case IPMI_MAINTENANCE_MODE_ON: | ||
1038 | intf->maintenance_mode = mode; | ||
1039 | intf->maintenance_mode_enable = 1; | ||
1040 | break; | ||
1041 | |||
1042 | default: | ||
1043 | rv = -EINVAL; | ||
1044 | goto out_unlock; | ||
1045 | } | ||
1046 | |||
1047 | maintenance_mode_update(intf); | ||
1048 | } | ||
1049 | out_unlock: | ||
1050 | spin_unlock_irqrestore(&intf->maintenance_mode_lock, flags); | ||
1051 | |||
1052 | return rv; | ||
1053 | } | ||
1054 | EXPORT_SYMBOL(ipmi_set_maintenance_mode); | ||
1055 | |||
934 | int ipmi_set_gets_events(ipmi_user_t user, int val) | 1056 | int ipmi_set_gets_events(ipmi_user_t user, int val) |
935 | { | 1057 | { |
936 | unsigned long flags; | 1058 | unsigned long flags; |
@@ -943,20 +1065,33 @@ int ipmi_set_gets_events(ipmi_user_t user, int val) | |||
943 | spin_lock_irqsave(&intf->events_lock, flags); | 1065 | spin_lock_irqsave(&intf->events_lock, flags); |
944 | user->gets_events = val; | 1066 | user->gets_events = val; |
945 | 1067 | ||
946 | if (val) { | 1068 | if (intf->delivering_events) |
947 | /* Deliver any queued events. */ | 1069 | /* |
1070 | * Another thread is delivering events for this, so | ||
1071 | * let it handle any new events. | ||
1072 | */ | ||
1073 | goto out; | ||
1074 | |||
1075 | /* Deliver any queued events. */ | ||
1076 | while (user->gets_events && !list_empty(&intf->waiting_events)) { | ||
948 | list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) | 1077 | list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link) |
949 | list_move_tail(&msg->link, &msgs); | 1078 | list_move_tail(&msg->link, &msgs); |
950 | intf->waiting_events_count = 0; | 1079 | intf->waiting_events_count = 0; |
951 | } | ||
952 | 1080 | ||
953 | /* Hold the events lock while doing this to preserve order. */ | 1081 | intf->delivering_events = 1; |
954 | list_for_each_entry_safe(msg, msg2, &msgs, link) { | 1082 | spin_unlock_irqrestore(&intf->events_lock, flags); |
955 | msg->user = user; | 1083 | |
956 | kref_get(&user->refcount); | 1084 | list_for_each_entry_safe(msg, msg2, &msgs, link) { |
957 | deliver_response(msg); | 1085 | msg->user = user; |
1086 | kref_get(&user->refcount); | ||
1087 | deliver_response(msg); | ||
1088 | } | ||
1089 | |||
1090 | spin_lock_irqsave(&intf->events_lock, flags); | ||
1091 | intf->delivering_events = 0; | ||
958 | } | 1092 | } |
959 | 1093 | ||
1094 | out: | ||
960 | spin_unlock_irqrestore(&intf->events_lock, flags); | 1095 | spin_unlock_irqrestore(&intf->events_lock, flags); |
961 | 1096 | ||
962 | return 0; | 1097 | return 0; |
@@ -1067,7 +1202,8 @@ int ipmi_unregister_for_cmd(ipmi_user_t user, | |||
1067 | void ipmi_user_set_run_to_completion(ipmi_user_t user, int val) | 1202 | void ipmi_user_set_run_to_completion(ipmi_user_t user, int val) |
1068 | { | 1203 | { |
1069 | ipmi_smi_t intf = user->intf; | 1204 | ipmi_smi_t intf = user->intf; |
1070 | intf->handlers->set_run_to_completion(intf->send_info, val); | 1205 | if (intf->handlers) |
1206 | intf->handlers->set_run_to_completion(intf->send_info, val); | ||
1071 | } | 1207 | } |
1072 | 1208 | ||
1073 | static unsigned char | 1209 | static unsigned char |
@@ -1178,10 +1314,11 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1178 | int retries, | 1314 | int retries, |
1179 | unsigned int retry_time_ms) | 1315 | unsigned int retry_time_ms) |
1180 | { | 1316 | { |
1181 | int rv = 0; | 1317 | int rv = 0; |
1182 | struct ipmi_smi_msg *smi_msg; | 1318 | struct ipmi_smi_msg *smi_msg; |
1183 | struct ipmi_recv_msg *recv_msg; | 1319 | struct ipmi_recv_msg *recv_msg; |
1184 | unsigned long flags; | 1320 | unsigned long flags; |
1321 | struct ipmi_smi_handlers *handlers; | ||
1185 | 1322 | ||
1186 | 1323 | ||
1187 | if (supplied_recv) { | 1324 | if (supplied_recv) { |
@@ -1204,6 +1341,13 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1204 | } | 1341 | } |
1205 | } | 1342 | } |
1206 | 1343 | ||
1344 | rcu_read_lock(); | ||
1345 | handlers = intf->handlers; | ||
1346 | if (!handlers) { | ||
1347 | rv = -ENODEV; | ||
1348 | goto out_err; | ||
1349 | } | ||
1350 | |||
1207 | recv_msg->user = user; | 1351 | recv_msg->user = user; |
1208 | if (user) | 1352 | if (user) |
1209 | kref_get(&user->refcount); | 1353 | kref_get(&user->refcount); |
@@ -1246,6 +1390,24 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1246 | goto out_err; | 1390 | goto out_err; |
1247 | } | 1391 | } |
1248 | 1392 | ||
1393 | if (((msg->netfn == IPMI_NETFN_APP_REQUEST) | ||
1394 | && ((msg->cmd == IPMI_COLD_RESET_CMD) | ||
1395 | || (msg->cmd == IPMI_WARM_RESET_CMD))) | ||
1396 | || (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST)) | ||
1397 | { | ||
1398 | spin_lock_irqsave(&intf->maintenance_mode_lock, flags); | ||
1399 | intf->auto_maintenance_timeout | ||
1400 | = IPMI_MAINTENANCE_MODE_TIMEOUT; | ||
1401 | if (!intf->maintenance_mode | ||
1402 | && !intf->maintenance_mode_enable) | ||
1403 | { | ||
1404 | intf->maintenance_mode_enable = 1; | ||
1405 | maintenance_mode_update(intf); | ||
1406 | } | ||
1407 | spin_unlock_irqrestore(&intf->maintenance_mode_lock, | ||
1408 | flags); | ||
1409 | } | ||
1410 | |||
1249 | if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) { | 1411 | if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) { |
1250 | spin_lock_irqsave(&intf->counter_lock, flags); | 1412 | spin_lock_irqsave(&intf->counter_lock, flags); |
1251 | intf->sent_invalid_commands++; | 1413 | intf->sent_invalid_commands++; |
@@ -1520,11 +1682,14 @@ static int i_ipmi_request(ipmi_user_t user, | |||
1520 | printk("\n"); | 1682 | printk("\n"); |
1521 | } | 1683 | } |
1522 | #endif | 1684 | #endif |
1523 | intf->handlers->sender(intf->send_info, smi_msg, priority); | 1685 | |
1686 | handlers->sender(intf->send_info, smi_msg, priority); | ||
1687 | rcu_read_unlock(); | ||
1524 | 1688 | ||
1525 | return 0; | 1689 | return 0; |
1526 | 1690 | ||
1527 | out_err: | 1691 | out_err: |
1692 | rcu_read_unlock(); | ||
1528 | ipmi_free_smi_msg(smi_msg); | 1693 | ipmi_free_smi_msg(smi_msg); |
1529 | ipmi_free_recv_msg(recv_msg); | 1694 | ipmi_free_recv_msg(recv_msg); |
1530 | return rv; | 1695 | return rv; |
@@ -1604,6 +1769,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, | |||
1604 | -1, 0); | 1769 | -1, 0); |
1605 | } | 1770 | } |
1606 | 1771 | ||
1772 | #ifdef CONFIG_PROC_FS | ||
1607 | static int ipmb_file_read_proc(char *page, char **start, off_t off, | 1773 | static int ipmb_file_read_proc(char *page, char **start, off_t off, |
1608 | int count, int *eof, void *data) | 1774 | int count, int *eof, void *data) |
1609 | { | 1775 | { |
@@ -1692,6 +1858,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
1692 | 1858 | ||
1693 | return (out - ((char *) page)); | 1859 | return (out - ((char *) page)); |
1694 | } | 1860 | } |
1861 | #endif /* CONFIG_PROC_FS */ | ||
1695 | 1862 | ||
1696 | int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, | 1863 | int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name, |
1697 | read_proc_t *read_proc, write_proc_t *write_proc, | 1864 | read_proc_t *read_proc, write_proc_t *write_proc, |
@@ -1817,13 +1984,12 @@ static int __find_bmc_prod_dev_id(struct device *dev, void *data) | |||
1817 | struct bmc_device *bmc = dev_get_drvdata(dev); | 1984 | struct bmc_device *bmc = dev_get_drvdata(dev); |
1818 | 1985 | ||
1819 | return (bmc->id.product_id == id->product_id | 1986 | return (bmc->id.product_id == id->product_id |
1820 | && bmc->id.product_id == id->product_id | ||
1821 | && bmc->id.device_id == id->device_id); | 1987 | && bmc->id.device_id == id->device_id); |
1822 | } | 1988 | } |
1823 | 1989 | ||
1824 | static struct bmc_device *ipmi_find_bmc_prod_dev_id( | 1990 | static struct bmc_device *ipmi_find_bmc_prod_dev_id( |
1825 | struct device_driver *drv, | 1991 | struct device_driver *drv, |
1826 | unsigned char product_id, unsigned char device_id) | 1992 | unsigned int product_id, unsigned char device_id) |
1827 | { | 1993 | { |
1828 | struct prod_dev_id id = { | 1994 | struct prod_dev_id id = { |
1829 | .product_id = product_id, | 1995 | .product_id = product_id, |
@@ -1940,6 +2106,9 @@ static ssize_t guid_show(struct device *dev, struct device_attribute *attr, | |||
1940 | 2106 | ||
1941 | static void remove_files(struct bmc_device *bmc) | 2107 | static void remove_files(struct bmc_device *bmc) |
1942 | { | 2108 | { |
2109 | if (!bmc->dev) | ||
2110 | return; | ||
2111 | |||
1943 | device_remove_file(&bmc->dev->dev, | 2112 | device_remove_file(&bmc->dev->dev, |
1944 | &bmc->device_id_attr); | 2113 | &bmc->device_id_attr); |
1945 | device_remove_file(&bmc->dev->dev, | 2114 | device_remove_file(&bmc->dev->dev, |
@@ -1973,7 +2142,8 @@ cleanup_bmc_device(struct kref *ref) | |||
1973 | bmc = container_of(ref, struct bmc_device, refcount); | 2142 | bmc = container_of(ref, struct bmc_device, refcount); |
1974 | 2143 | ||
1975 | remove_files(bmc); | 2144 | remove_files(bmc); |
1976 | platform_device_unregister(bmc->dev); | 2145 | if (bmc->dev) |
2146 | platform_device_unregister(bmc->dev); | ||
1977 | kfree(bmc); | 2147 | kfree(bmc); |
1978 | } | 2148 | } |
1979 | 2149 | ||
@@ -1981,7 +2151,11 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) | |||
1981 | { | 2151 | { |
1982 | struct bmc_device *bmc = intf->bmc; | 2152 | struct bmc_device *bmc = intf->bmc; |
1983 | 2153 | ||
1984 | sysfs_remove_link(&intf->si_dev->kobj, "bmc"); | 2154 | if (intf->sysfs_name) { |
2155 | sysfs_remove_link(&intf->si_dev->kobj, intf->sysfs_name); | ||
2156 | kfree(intf->sysfs_name); | ||
2157 | intf->sysfs_name = NULL; | ||
2158 | } | ||
1985 | if (intf->my_dev_name) { | 2159 | if (intf->my_dev_name) { |
1986 | sysfs_remove_link(&bmc->dev->dev.kobj, intf->my_dev_name); | 2160 | sysfs_remove_link(&bmc->dev->dev.kobj, intf->my_dev_name); |
1987 | kfree(intf->my_dev_name); | 2161 | kfree(intf->my_dev_name); |
@@ -1990,6 +2164,7 @@ static void ipmi_bmc_unregister(ipmi_smi_t intf) | |||
1990 | 2164 | ||
1991 | mutex_lock(&ipmidriver_mutex); | 2165 | mutex_lock(&ipmidriver_mutex); |
1992 | kref_put(&bmc->refcount, cleanup_bmc_device); | 2166 | kref_put(&bmc->refcount, cleanup_bmc_device); |
2167 | intf->bmc = NULL; | ||
1993 | mutex_unlock(&ipmidriver_mutex); | 2168 | mutex_unlock(&ipmidriver_mutex); |
1994 | } | 2169 | } |
1995 | 2170 | ||
@@ -1997,6 +2172,56 @@ static int create_files(struct bmc_device *bmc) | |||
1997 | { | 2172 | { |
1998 | int err; | 2173 | int err; |
1999 | 2174 | ||
2175 | bmc->device_id_attr.attr.name = "device_id"; | ||
2176 | bmc->device_id_attr.attr.owner = THIS_MODULE; | ||
2177 | bmc->device_id_attr.attr.mode = S_IRUGO; | ||
2178 | bmc->device_id_attr.show = device_id_show; | ||
2179 | |||
2180 | bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; | ||
2181 | bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE; | ||
2182 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; | ||
2183 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; | ||
2184 | |||
2185 | bmc->revision_attr.attr.name = "revision"; | ||
2186 | bmc->revision_attr.attr.owner = THIS_MODULE; | ||
2187 | bmc->revision_attr.attr.mode = S_IRUGO; | ||
2188 | bmc->revision_attr.show = revision_show; | ||
2189 | |||
2190 | bmc->firmware_rev_attr.attr.name = "firmware_revision"; | ||
2191 | bmc->firmware_rev_attr.attr.owner = THIS_MODULE; | ||
2192 | bmc->firmware_rev_attr.attr.mode = S_IRUGO; | ||
2193 | bmc->firmware_rev_attr.show = firmware_rev_show; | ||
2194 | |||
2195 | bmc->version_attr.attr.name = "ipmi_version"; | ||
2196 | bmc->version_attr.attr.owner = THIS_MODULE; | ||
2197 | bmc->version_attr.attr.mode = S_IRUGO; | ||
2198 | bmc->version_attr.show = ipmi_version_show; | ||
2199 | |||
2200 | bmc->add_dev_support_attr.attr.name = "additional_device_support"; | ||
2201 | bmc->add_dev_support_attr.attr.owner = THIS_MODULE; | ||
2202 | bmc->add_dev_support_attr.attr.mode = S_IRUGO; | ||
2203 | bmc->add_dev_support_attr.show = add_dev_support_show; | ||
2204 | |||
2205 | bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; | ||
2206 | bmc->manufacturer_id_attr.attr.owner = THIS_MODULE; | ||
2207 | bmc->manufacturer_id_attr.attr.mode = S_IRUGO; | ||
2208 | bmc->manufacturer_id_attr.show = manufacturer_id_show; | ||
2209 | |||
2210 | bmc->product_id_attr.attr.name = "product_id"; | ||
2211 | bmc->product_id_attr.attr.owner = THIS_MODULE; | ||
2212 | bmc->product_id_attr.attr.mode = S_IRUGO; | ||
2213 | bmc->product_id_attr.show = product_id_show; | ||
2214 | |||
2215 | bmc->guid_attr.attr.name = "guid"; | ||
2216 | bmc->guid_attr.attr.owner = THIS_MODULE; | ||
2217 | bmc->guid_attr.attr.mode = S_IRUGO; | ||
2218 | bmc->guid_attr.show = guid_show; | ||
2219 | |||
2220 | bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; | ||
2221 | bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE; | ||
2222 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; | ||
2223 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; | ||
2224 | |||
2000 | err = device_create_file(&bmc->dev->dev, | 2225 | err = device_create_file(&bmc->dev->dev, |
2001 | &bmc->device_id_attr); | 2226 | &bmc->device_id_attr); |
2002 | if (err) goto out; | 2227 | if (err) goto out; |
@@ -2066,7 +2291,8 @@ out: | |||
2066 | return err; | 2291 | return err; |
2067 | } | 2292 | } |
2068 | 2293 | ||
2069 | static int ipmi_bmc_register(ipmi_smi_t intf) | 2294 | static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum, |
2295 | const char *sysfs_name) | ||
2070 | { | 2296 | { |
2071 | int rv; | 2297 | int rv; |
2072 | struct bmc_device *bmc = intf->bmc; | 2298 | struct bmc_device *bmc = intf->bmc; |
@@ -2106,9 +2332,39 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2106 | bmc->id.product_id, | 2332 | bmc->id.product_id, |
2107 | bmc->id.device_id); | 2333 | bmc->id.device_id); |
2108 | } else { | 2334 | } else { |
2109 | bmc->dev = platform_device_alloc("ipmi_bmc", | 2335 | char name[14]; |
2110 | bmc->id.device_id); | 2336 | unsigned char orig_dev_id = bmc->id.device_id; |
2337 | int warn_printed = 0; | ||
2338 | |||
2339 | snprintf(name, sizeof(name), | ||
2340 | "ipmi_bmc.%4.4x", bmc->id.product_id); | ||
2341 | |||
2342 | while (ipmi_find_bmc_prod_dev_id(&ipmidriver, | ||
2343 | bmc->id.product_id, | ||
2344 | bmc->id.device_id)) | ||
2345 | { | ||
2346 | if (!warn_printed) { | ||
2347 | printk(KERN_WARNING PFX | ||
2348 | "This machine has two different BMCs" | ||
2349 | " with the same product id and device" | ||
2350 | " id. This is an error in the" | ||
2351 | " firmware, but incrementing the" | ||
2352 | " device id to work around the problem." | ||
2353 | " Prod ID = 0x%x, Dev ID = 0x%x\n", | ||
2354 | bmc->id.product_id, bmc->id.device_id); | ||
2355 | warn_printed = 1; | ||
2356 | } | ||
2357 | bmc->id.device_id++; /* Wraps at 255 */ | ||
2358 | if (bmc->id.device_id == orig_dev_id) { | ||
2359 | printk(KERN_ERR PFX | ||
2360 | "Out of device ids!\n"); | ||
2361 | break; | ||
2362 | } | ||
2363 | } | ||
2364 | |||
2365 | bmc->dev = platform_device_alloc(name, bmc->id.device_id); | ||
2111 | if (!bmc->dev) { | 2366 | if (!bmc->dev) { |
2367 | mutex_unlock(&ipmidriver_mutex); | ||
2112 | printk(KERN_ERR | 2368 | printk(KERN_ERR |
2113 | "ipmi_msghandler:" | 2369 | "ipmi_msghandler:" |
2114 | " Unable to allocate platform device\n"); | 2370 | " Unable to allocate platform device\n"); |
@@ -2121,6 +2377,8 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2121 | rv = platform_device_add(bmc->dev); | 2377 | rv = platform_device_add(bmc->dev); |
2122 | mutex_unlock(&ipmidriver_mutex); | 2378 | mutex_unlock(&ipmidriver_mutex); |
2123 | if (rv) { | 2379 | if (rv) { |
2380 | platform_device_put(bmc->dev); | ||
2381 | bmc->dev = NULL; | ||
2124 | printk(KERN_ERR | 2382 | printk(KERN_ERR |
2125 | "ipmi_msghandler:" | 2383 | "ipmi_msghandler:" |
2126 | " Unable to register bmc device: %d\n", | 2384 | " Unable to register bmc device: %d\n", |
@@ -2130,57 +2388,6 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2130 | return rv; | 2388 | return rv; |
2131 | } | 2389 | } |
2132 | 2390 | ||
2133 | bmc->device_id_attr.attr.name = "device_id"; | ||
2134 | bmc->device_id_attr.attr.owner = THIS_MODULE; | ||
2135 | bmc->device_id_attr.attr.mode = S_IRUGO; | ||
2136 | bmc->device_id_attr.show = device_id_show; | ||
2137 | |||
2138 | bmc->provides_dev_sdrs_attr.attr.name = "provides_device_sdrs"; | ||
2139 | bmc->provides_dev_sdrs_attr.attr.owner = THIS_MODULE; | ||
2140 | bmc->provides_dev_sdrs_attr.attr.mode = S_IRUGO; | ||
2141 | bmc->provides_dev_sdrs_attr.show = provides_dev_sdrs_show; | ||
2142 | |||
2143 | bmc->revision_attr.attr.name = "revision"; | ||
2144 | bmc->revision_attr.attr.owner = THIS_MODULE; | ||
2145 | bmc->revision_attr.attr.mode = S_IRUGO; | ||
2146 | bmc->revision_attr.show = revision_show; | ||
2147 | |||
2148 | bmc->firmware_rev_attr.attr.name = "firmware_revision"; | ||
2149 | bmc->firmware_rev_attr.attr.owner = THIS_MODULE; | ||
2150 | bmc->firmware_rev_attr.attr.mode = S_IRUGO; | ||
2151 | bmc->firmware_rev_attr.show = firmware_rev_show; | ||
2152 | |||
2153 | bmc->version_attr.attr.name = "ipmi_version"; | ||
2154 | bmc->version_attr.attr.owner = THIS_MODULE; | ||
2155 | bmc->version_attr.attr.mode = S_IRUGO; | ||
2156 | bmc->version_attr.show = ipmi_version_show; | ||
2157 | |||
2158 | bmc->add_dev_support_attr.attr.name | ||
2159 | = "additional_device_support"; | ||
2160 | bmc->add_dev_support_attr.attr.owner = THIS_MODULE; | ||
2161 | bmc->add_dev_support_attr.attr.mode = S_IRUGO; | ||
2162 | bmc->add_dev_support_attr.show = add_dev_support_show; | ||
2163 | |||
2164 | bmc->manufacturer_id_attr.attr.name = "manufacturer_id"; | ||
2165 | bmc->manufacturer_id_attr.attr.owner = THIS_MODULE; | ||
2166 | bmc->manufacturer_id_attr.attr.mode = S_IRUGO; | ||
2167 | bmc->manufacturer_id_attr.show = manufacturer_id_show; | ||
2168 | |||
2169 | bmc->product_id_attr.attr.name = "product_id"; | ||
2170 | bmc->product_id_attr.attr.owner = THIS_MODULE; | ||
2171 | bmc->product_id_attr.attr.mode = S_IRUGO; | ||
2172 | bmc->product_id_attr.show = product_id_show; | ||
2173 | |||
2174 | bmc->guid_attr.attr.name = "guid"; | ||
2175 | bmc->guid_attr.attr.owner = THIS_MODULE; | ||
2176 | bmc->guid_attr.attr.mode = S_IRUGO; | ||
2177 | bmc->guid_attr.show = guid_show; | ||
2178 | |||
2179 | bmc->aux_firmware_rev_attr.attr.name = "aux_firmware_revision"; | ||
2180 | bmc->aux_firmware_rev_attr.attr.owner = THIS_MODULE; | ||
2181 | bmc->aux_firmware_rev_attr.attr.mode = S_IRUGO; | ||
2182 | bmc->aux_firmware_rev_attr.show = aux_firmware_rev_show; | ||
2183 | |||
2184 | rv = create_files(bmc); | 2391 | rv = create_files(bmc); |
2185 | if (rv) { | 2392 | if (rv) { |
2186 | mutex_lock(&ipmidriver_mutex); | 2393 | mutex_lock(&ipmidriver_mutex); |
@@ -2202,29 +2409,44 @@ static int ipmi_bmc_register(ipmi_smi_t intf) | |||
2202 | * create symlink from system interface device to bmc device | 2409 | * create symlink from system interface device to bmc device |
2203 | * and back. | 2410 | * and back. |
2204 | */ | 2411 | */ |
2412 | intf->sysfs_name = kstrdup(sysfs_name, GFP_KERNEL); | ||
2413 | if (!intf->sysfs_name) { | ||
2414 | rv = -ENOMEM; | ||
2415 | printk(KERN_ERR | ||
2416 | "ipmi_msghandler: allocate link to BMC: %d\n", | ||
2417 | rv); | ||
2418 | goto out_err; | ||
2419 | } | ||
2420 | |||
2205 | rv = sysfs_create_link(&intf->si_dev->kobj, | 2421 | rv = sysfs_create_link(&intf->si_dev->kobj, |
2206 | &bmc->dev->dev.kobj, "bmc"); | 2422 | &bmc->dev->dev.kobj, intf->sysfs_name); |
2207 | if (rv) { | 2423 | if (rv) { |
2424 | kfree(intf->sysfs_name); | ||
2425 | intf->sysfs_name = NULL; | ||
2208 | printk(KERN_ERR | 2426 | printk(KERN_ERR |
2209 | "ipmi_msghandler: Unable to create bmc symlink: %d\n", | 2427 | "ipmi_msghandler: Unable to create bmc symlink: %d\n", |
2210 | rv); | 2428 | rv); |
2211 | goto out_err; | 2429 | goto out_err; |
2212 | } | 2430 | } |
2213 | 2431 | ||
2214 | size = snprintf(dummy, 0, "ipmi%d", intf->intf_num); | 2432 | size = snprintf(dummy, 0, "ipmi%d", ifnum); |
2215 | intf->my_dev_name = kmalloc(size+1, GFP_KERNEL); | 2433 | intf->my_dev_name = kmalloc(size+1, GFP_KERNEL); |
2216 | if (!intf->my_dev_name) { | 2434 | if (!intf->my_dev_name) { |
2435 | kfree(intf->sysfs_name); | ||
2436 | intf->sysfs_name = NULL; | ||
2217 | rv = -ENOMEM; | 2437 | rv = -ENOMEM; |
2218 | printk(KERN_ERR | 2438 | printk(KERN_ERR |
2219 | "ipmi_msghandler: allocate link from BMC: %d\n", | 2439 | "ipmi_msghandler: allocate link from BMC: %d\n", |
2220 | rv); | 2440 | rv); |
2221 | goto out_err; | 2441 | goto out_err; |
2222 | } | 2442 | } |
2223 | snprintf(intf->my_dev_name, size+1, "ipmi%d", intf->intf_num); | 2443 | snprintf(intf->my_dev_name, size+1, "ipmi%d", ifnum); |
2224 | 2444 | ||
2225 | rv = sysfs_create_link(&bmc->dev->dev.kobj, &intf->si_dev->kobj, | 2445 | rv = sysfs_create_link(&bmc->dev->dev.kobj, &intf->si_dev->kobj, |
2226 | intf->my_dev_name); | 2446 | intf->my_dev_name); |
2227 | if (rv) { | 2447 | if (rv) { |
2448 | kfree(intf->sysfs_name); | ||
2449 | intf->sysfs_name = NULL; | ||
2228 | kfree(intf->my_dev_name); | 2450 | kfree(intf->my_dev_name); |
2229 | intf->my_dev_name = NULL; | 2451 | intf->my_dev_name = NULL; |
2230 | printk(KERN_ERR | 2452 | printk(KERN_ERR |
@@ -2409,17 +2631,14 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2409 | void *send_info, | 2631 | void *send_info, |
2410 | struct ipmi_device_id *device_id, | 2632 | struct ipmi_device_id *device_id, |
2411 | struct device *si_dev, | 2633 | struct device *si_dev, |
2634 | const char *sysfs_name, | ||
2412 | unsigned char slave_addr) | 2635 | unsigned char slave_addr) |
2413 | { | 2636 | { |
2414 | int i, j; | 2637 | int i, j; |
2415 | int rv; | 2638 | int rv; |
2416 | ipmi_smi_t intf; | 2639 | ipmi_smi_t intf; |
2417 | unsigned long flags; | 2640 | ipmi_smi_t tintf; |
2418 | int version_major; | 2641 | struct list_head *link; |
2419 | int version_minor; | ||
2420 | |||
2421 | version_major = ipmi_version_major(device_id); | ||
2422 | version_minor = ipmi_version_minor(device_id); | ||
2423 | 2642 | ||
2424 | /* Make sure the driver is actually initialized, this handles | 2643 | /* Make sure the driver is actually initialized, this handles |
2425 | problems with initialization order. */ | 2644 | problems with initialization order. */ |
@@ -2437,12 +2656,16 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2437 | if (!intf) | 2656 | if (!intf) |
2438 | return -ENOMEM; | 2657 | return -ENOMEM; |
2439 | memset(intf, 0, sizeof(*intf)); | 2658 | memset(intf, 0, sizeof(*intf)); |
2659 | |||
2660 | intf->ipmi_version_major = ipmi_version_major(device_id); | ||
2661 | intf->ipmi_version_minor = ipmi_version_minor(device_id); | ||
2662 | |||
2440 | intf->bmc = kzalloc(sizeof(*intf->bmc), GFP_KERNEL); | 2663 | intf->bmc = kzalloc(sizeof(*intf->bmc), GFP_KERNEL); |
2441 | if (!intf->bmc) { | 2664 | if (!intf->bmc) { |
2442 | kfree(intf); | 2665 | kfree(intf); |
2443 | return -ENOMEM; | 2666 | return -ENOMEM; |
2444 | } | 2667 | } |
2445 | intf->intf_num = -1; | 2668 | intf->intf_num = -1; /* Mark it invalid for now. */ |
2446 | kref_init(&intf->refcount); | 2669 | kref_init(&intf->refcount); |
2447 | intf->bmc->id = *device_id; | 2670 | intf->bmc->id = *device_id; |
2448 | intf->si_dev = si_dev; | 2671 | intf->si_dev = si_dev; |
@@ -2470,26 +2693,30 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2470 | INIT_LIST_HEAD(&intf->waiting_events); | 2693 | INIT_LIST_HEAD(&intf->waiting_events); |
2471 | intf->waiting_events_count = 0; | 2694 | intf->waiting_events_count = 0; |
2472 | mutex_init(&intf->cmd_rcvrs_mutex); | 2695 | mutex_init(&intf->cmd_rcvrs_mutex); |
2696 | spin_lock_init(&intf->maintenance_mode_lock); | ||
2473 | INIT_LIST_HEAD(&intf->cmd_rcvrs); | 2697 | INIT_LIST_HEAD(&intf->cmd_rcvrs); |
2474 | init_waitqueue_head(&intf->waitq); | 2698 | init_waitqueue_head(&intf->waitq); |
2475 | 2699 | ||
2476 | spin_lock_init(&intf->counter_lock); | 2700 | spin_lock_init(&intf->counter_lock); |
2477 | intf->proc_dir = NULL; | 2701 | intf->proc_dir = NULL; |
2478 | 2702 | ||
2479 | rv = -ENOMEM; | 2703 | mutex_lock(&smi_watchers_mutex); |
2480 | spin_lock_irqsave(&interfaces_lock, flags); | 2704 | mutex_lock(&ipmi_interfaces_mutex); |
2481 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 2705 | /* Look for a hole in the numbers. */ |
2482 | if (ipmi_interfaces[i] == NULL) { | 2706 | i = 0; |
2483 | intf->intf_num = i; | 2707 | link = &ipmi_interfaces; |
2484 | /* Reserve the entry till we are done. */ | 2708 | list_for_each_entry_rcu(tintf, &ipmi_interfaces, link) { |
2485 | ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY; | 2709 | if (tintf->intf_num != i) { |
2486 | rv = 0; | 2710 | link = &tintf->link; |
2487 | break; | 2711 | break; |
2488 | } | 2712 | } |
2713 | i++; | ||
2489 | } | 2714 | } |
2490 | spin_unlock_irqrestore(&interfaces_lock, flags); | 2715 | /* Add the new interface in numeric order. */ |
2491 | if (rv) | 2716 | if (i == 0) |
2492 | goto out; | 2717 | list_add_rcu(&intf->link, &ipmi_interfaces); |
2718 | else | ||
2719 | list_add_tail_rcu(&intf->link, link); | ||
2493 | 2720 | ||
2494 | rv = handlers->start_processing(send_info, intf); | 2721 | rv = handlers->start_processing(send_info, intf); |
2495 | if (rv) | 2722 | if (rv) |
@@ -2497,8 +2724,9 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2497 | 2724 | ||
2498 | get_guid(intf); | 2725 | get_guid(intf); |
2499 | 2726 | ||
2500 | if ((version_major > 1) | 2727 | if ((intf->ipmi_version_major > 1) |
2501 | || ((version_major == 1) && (version_minor >= 5))) | 2728 | || ((intf->ipmi_version_major == 1) |
2729 | && (intf->ipmi_version_minor >= 5))) | ||
2502 | { | 2730 | { |
2503 | /* Start scanning the channels to see what is | 2731 | /* Start scanning the channels to see what is |
2504 | available. */ | 2732 | available. */ |
@@ -2521,64 +2749,67 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers, | |||
2521 | if (rv == 0) | 2749 | if (rv == 0) |
2522 | rv = add_proc_entries(intf, i); | 2750 | rv = add_proc_entries(intf, i); |
2523 | 2751 | ||
2524 | rv = ipmi_bmc_register(intf); | 2752 | rv = ipmi_bmc_register(intf, i, sysfs_name); |
2525 | 2753 | ||
2526 | out: | 2754 | out: |
2527 | if (rv) { | 2755 | if (rv) { |
2528 | if (intf->proc_dir) | 2756 | if (intf->proc_dir) |
2529 | remove_proc_entries(intf); | 2757 | remove_proc_entries(intf); |
2758 | intf->handlers = NULL; | ||
2759 | list_del_rcu(&intf->link); | ||
2760 | mutex_unlock(&ipmi_interfaces_mutex); | ||
2761 | mutex_unlock(&smi_watchers_mutex); | ||
2762 | synchronize_rcu(); | ||
2530 | kref_put(&intf->refcount, intf_free); | 2763 | kref_put(&intf->refcount, intf_free); |
2531 | if (i < MAX_IPMI_INTERFACES) { | ||
2532 | spin_lock_irqsave(&interfaces_lock, flags); | ||
2533 | ipmi_interfaces[i] = NULL; | ||
2534 | spin_unlock_irqrestore(&interfaces_lock, flags); | ||
2535 | } | ||
2536 | } else { | 2764 | } else { |
2537 | spin_lock_irqsave(&interfaces_lock, flags); | 2765 | /* After this point the interface is legal to use. */ |
2538 | ipmi_interfaces[i] = intf; | 2766 | intf->intf_num = i; |
2539 | spin_unlock_irqrestore(&interfaces_lock, flags); | 2767 | mutex_unlock(&ipmi_interfaces_mutex); |
2540 | call_smi_watchers(i, intf->si_dev); | 2768 | call_smi_watchers(i, intf->si_dev); |
2769 | mutex_unlock(&smi_watchers_mutex); | ||
2541 | } | 2770 | } |
2542 | 2771 | ||
2543 | return rv; | 2772 | return rv; |
2544 | } | 2773 | } |
2545 | 2774 | ||
2775 | static void cleanup_smi_msgs(ipmi_smi_t intf) | ||
2776 | { | ||
2777 | int i; | ||
2778 | struct seq_table *ent; | ||
2779 | |||
2780 | /* No need for locks, the interface is down. */ | ||
2781 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) { | ||
2782 | ent = &(intf->seq_table[i]); | ||
2783 | if (!ent->inuse) | ||
2784 | continue; | ||
2785 | deliver_err_response(ent->recv_msg, IPMI_ERR_UNSPECIFIED); | ||
2786 | } | ||
2787 | } | ||
2788 | |||
2546 | int ipmi_unregister_smi(ipmi_smi_t intf) | 2789 | int ipmi_unregister_smi(ipmi_smi_t intf) |
2547 | { | 2790 | { |
2548 | int i; | ||
2549 | struct ipmi_smi_watcher *w; | 2791 | struct ipmi_smi_watcher *w; |
2550 | unsigned long flags; | 2792 | int intf_num = intf->intf_num; |
2551 | 2793 | ||
2552 | ipmi_bmc_unregister(intf); | 2794 | ipmi_bmc_unregister(intf); |
2553 | 2795 | ||
2554 | spin_lock_irqsave(&interfaces_lock, flags); | 2796 | mutex_lock(&smi_watchers_mutex); |
2555 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 2797 | mutex_lock(&ipmi_interfaces_mutex); |
2556 | if (ipmi_interfaces[i] == intf) { | 2798 | intf->intf_num = -1; |
2557 | /* Set the interface number reserved until we | 2799 | intf->handlers = NULL; |
2558 | * are done. */ | 2800 | list_del_rcu(&intf->link); |
2559 | ipmi_interfaces[i] = IPMI_INVALID_INTERFACE_ENTRY; | 2801 | mutex_unlock(&ipmi_interfaces_mutex); |
2560 | intf->intf_num = -1; | 2802 | synchronize_rcu(); |
2561 | break; | ||
2562 | } | ||
2563 | } | ||
2564 | spin_unlock_irqrestore(&interfaces_lock,flags); | ||
2565 | 2803 | ||
2566 | if (i == MAX_IPMI_INTERFACES) | 2804 | cleanup_smi_msgs(intf); |
2567 | return -ENODEV; | ||
2568 | 2805 | ||
2569 | remove_proc_entries(intf); | 2806 | remove_proc_entries(intf); |
2570 | 2807 | ||
2571 | /* Call all the watcher interfaces to tell them that | 2808 | /* Call all the watcher interfaces to tell them that |
2572 | an interface is gone. */ | 2809 | an interface is gone. */ |
2573 | down_read(&smi_watchers_sem); | ||
2574 | list_for_each_entry(w, &smi_watchers, link) | 2810 | list_for_each_entry(w, &smi_watchers, link) |
2575 | w->smi_gone(i); | 2811 | w->smi_gone(intf_num); |
2576 | up_read(&smi_watchers_sem); | 2812 | mutex_unlock(&smi_watchers_mutex); |
2577 | |||
2578 | /* Allow the entry to be reused now. */ | ||
2579 | spin_lock_irqsave(&interfaces_lock, flags); | ||
2580 | ipmi_interfaces[i] = NULL; | ||
2581 | spin_unlock_irqrestore(&interfaces_lock,flags); | ||
2582 | 2813 | ||
2583 | kref_put(&intf->refcount, intf_free); | 2814 | kref_put(&intf->refcount, intf_free); |
2584 | return 0; | 2815 | return 0; |
@@ -2660,6 +2891,7 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2660 | struct ipmi_ipmb_addr *ipmb_addr; | 2891 | struct ipmi_ipmb_addr *ipmb_addr; |
2661 | struct ipmi_recv_msg *recv_msg; | 2892 | struct ipmi_recv_msg *recv_msg; |
2662 | unsigned long flags; | 2893 | unsigned long flags; |
2894 | struct ipmi_smi_handlers *handlers; | ||
2663 | 2895 | ||
2664 | if (msg->rsp_size < 10) { | 2896 | if (msg->rsp_size < 10) { |
2665 | /* Message not big enough, just ignore it. */ | 2897 | /* Message not big enough, just ignore it. */ |
@@ -2716,10 +2948,16 @@ static int handle_ipmb_get_msg_cmd(ipmi_smi_t intf, | |||
2716 | printk("\n"); | 2948 | printk("\n"); |
2717 | } | 2949 | } |
2718 | #endif | 2950 | #endif |
2719 | intf->handlers->sender(intf->send_info, msg, 0); | 2951 | rcu_read_lock(); |
2720 | 2952 | handlers = intf->handlers; | |
2721 | rv = -1; /* We used the message, so return the value that | 2953 | if (handlers) { |
2722 | causes it to not be freed or queued. */ | 2954 | handlers->sender(intf->send_info, msg, 0); |
2955 | /* We used the message, so return the value | ||
2956 | that causes it to not be freed or | ||
2957 | queued. */ | ||
2958 | rv = -1; | ||
2959 | } | ||
2960 | rcu_read_unlock(); | ||
2723 | } else { | 2961 | } else { |
2724 | /* Deliver the message to the user. */ | 2962 | /* Deliver the message to the user. */ |
2725 | spin_lock_irqsave(&intf->counter_lock, flags); | 2963 | spin_lock_irqsave(&intf->counter_lock, flags); |
@@ -3309,16 +3547,6 @@ void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf) | |||
3309 | rcu_read_unlock(); | 3547 | rcu_read_unlock(); |
3310 | } | 3548 | } |
3311 | 3549 | ||
3312 | static void | ||
3313 | handle_msg_timeout(struct ipmi_recv_msg *msg) | ||
3314 | { | ||
3315 | msg->recv_type = IPMI_RESPONSE_RECV_TYPE; | ||
3316 | msg->msg_data[0] = IPMI_TIMEOUT_COMPLETION_CODE; | ||
3317 | msg->msg.netfn |= 1; /* Convert to a response. */ | ||
3318 | msg->msg.data_len = 1; | ||
3319 | msg->msg.data = msg->msg_data; | ||
3320 | deliver_response(msg); | ||
3321 | } | ||
3322 | 3550 | ||
3323 | static struct ipmi_smi_msg * | 3551 | static struct ipmi_smi_msg * |
3324 | smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, | 3552 | smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg, |
@@ -3350,7 +3578,11 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3350 | struct list_head *timeouts, long timeout_period, | 3578 | struct list_head *timeouts, long timeout_period, |
3351 | int slot, unsigned long *flags) | 3579 | int slot, unsigned long *flags) |
3352 | { | 3580 | { |
3353 | struct ipmi_recv_msg *msg; | 3581 | struct ipmi_recv_msg *msg; |
3582 | struct ipmi_smi_handlers *handlers; | ||
3583 | |||
3584 | if (intf->intf_num == -1) | ||
3585 | return; | ||
3354 | 3586 | ||
3355 | if (!ent->inuse) | 3587 | if (!ent->inuse) |
3356 | return; | 3588 | return; |
@@ -3393,13 +3625,19 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent, | |||
3393 | return; | 3625 | return; |
3394 | 3626 | ||
3395 | spin_unlock_irqrestore(&intf->seq_lock, *flags); | 3627 | spin_unlock_irqrestore(&intf->seq_lock, *flags); |
3628 | |||
3396 | /* Send the new message. We send with a zero | 3629 | /* Send the new message. We send with a zero |
3397 | * priority. It timed out, I doubt time is | 3630 | * priority. It timed out, I doubt time is |
3398 | * that critical now, and high priority | 3631 | * that critical now, and high priority |
3399 | * messages are really only for messages to the | 3632 | * messages are really only for messages to the |
3400 | * local MC, which don't get resent. */ | 3633 | * local MC, which don't get resent. */ |
3401 | intf->handlers->sender(intf->send_info, | 3634 | handlers = intf->handlers; |
3402 | smi_msg, 0); | 3635 | if (handlers) |
3636 | intf->handlers->sender(intf->send_info, | ||
3637 | smi_msg, 0); | ||
3638 | else | ||
3639 | ipmi_free_smi_msg(smi_msg); | ||
3640 | |||
3403 | spin_lock_irqsave(&intf->seq_lock, *flags); | 3641 | spin_lock_irqsave(&intf->seq_lock, *flags); |
3404 | } | 3642 | } |
3405 | } | 3643 | } |
@@ -3411,18 +3649,12 @@ static void ipmi_timeout_handler(long timeout_period) | |||
3411 | struct ipmi_recv_msg *msg, *msg2; | 3649 | struct ipmi_recv_msg *msg, *msg2; |
3412 | struct ipmi_smi_msg *smi_msg, *smi_msg2; | 3650 | struct ipmi_smi_msg *smi_msg, *smi_msg2; |
3413 | unsigned long flags; | 3651 | unsigned long flags; |
3414 | int i, j; | 3652 | int i; |
3415 | 3653 | ||
3416 | INIT_LIST_HEAD(&timeouts); | 3654 | INIT_LIST_HEAD(&timeouts); |
3417 | 3655 | ||
3418 | spin_lock(&interfaces_lock); | 3656 | rcu_read_lock(); |
3419 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 3657 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
3420 | intf = ipmi_interfaces[i]; | ||
3421 | if (IPMI_INVALID_INTERFACE(intf)) | ||
3422 | continue; | ||
3423 | kref_get(&intf->refcount); | ||
3424 | spin_unlock(&interfaces_lock); | ||
3425 | |||
3426 | /* See if any waiting messages need to be processed. */ | 3658 | /* See if any waiting messages need to be processed. */ |
3427 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); | 3659 | spin_lock_irqsave(&intf->waiting_msgs_lock, flags); |
3428 | list_for_each_entry_safe(smi_msg, smi_msg2, | 3660 | list_for_each_entry_safe(smi_msg, smi_msg2, |
@@ -3442,35 +3674,60 @@ static void ipmi_timeout_handler(long timeout_period) | |||
3442 | have timed out, putting them in the timeouts | 3674 | have timed out, putting them in the timeouts |
3443 | list. */ | 3675 | list. */ |
3444 | spin_lock_irqsave(&intf->seq_lock, flags); | 3676 | spin_lock_irqsave(&intf->seq_lock, flags); |
3445 | for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) | 3677 | for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) |
3446 | check_msg_timeout(intf, &(intf->seq_table[j]), | 3678 | check_msg_timeout(intf, &(intf->seq_table[i]), |
3447 | &timeouts, timeout_period, j, | 3679 | &timeouts, timeout_period, i, |
3448 | &flags); | 3680 | &flags); |
3449 | spin_unlock_irqrestore(&intf->seq_lock, flags); | 3681 | spin_unlock_irqrestore(&intf->seq_lock, flags); |
3450 | 3682 | ||
3451 | list_for_each_entry_safe(msg, msg2, &timeouts, link) | 3683 | list_for_each_entry_safe(msg, msg2, &timeouts, link) |
3452 | handle_msg_timeout(msg); | 3684 | deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE); |
3453 | 3685 | ||
3454 | kref_put(&intf->refcount, intf_free); | 3686 | /* |
3455 | spin_lock(&interfaces_lock); | 3687 | * Maintenance mode handling. Check the timeout |
3688 | * optimistically before we claim the lock. It may | ||
3689 | * mean a timeout gets missed occasionally, but that | ||
3690 | * only means the timeout gets extended by one period | ||
3691 | * in that case. No big deal, and it avoids the lock | ||
3692 | * most of the time. | ||
3693 | */ | ||
3694 | if (intf->auto_maintenance_timeout > 0) { | ||
3695 | spin_lock_irqsave(&intf->maintenance_mode_lock, flags); | ||
3696 | if (intf->auto_maintenance_timeout > 0) { | ||
3697 | intf->auto_maintenance_timeout | ||
3698 | -= timeout_period; | ||
3699 | if (!intf->maintenance_mode | ||
3700 | && (intf->auto_maintenance_timeout <= 0)) | ||
3701 | { | ||
3702 | intf->maintenance_mode_enable = 0; | ||
3703 | maintenance_mode_update(intf); | ||
3704 | } | ||
3705 | } | ||
3706 | spin_unlock_irqrestore(&intf->maintenance_mode_lock, | ||
3707 | flags); | ||
3708 | } | ||
3456 | } | 3709 | } |
3457 | spin_unlock(&interfaces_lock); | 3710 | rcu_read_unlock(); |
3458 | } | 3711 | } |
3459 | 3712 | ||
3460 | static void ipmi_request_event(void) | 3713 | static void ipmi_request_event(void) |
3461 | { | 3714 | { |
3462 | ipmi_smi_t intf; | 3715 | ipmi_smi_t intf; |
3463 | int i; | 3716 | struct ipmi_smi_handlers *handlers; |
3464 | 3717 | ||
3465 | spin_lock(&interfaces_lock); | 3718 | rcu_read_lock(); |
3466 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 3719 | /* Called from the timer, no need to check if handlers is |
3467 | intf = ipmi_interfaces[i]; | 3720 | * valid. */ |
3468 | if (IPMI_INVALID_INTERFACE(intf)) | 3721 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
3722 | /* No event requests when in maintenance mode. */ | ||
3723 | if (intf->maintenance_mode_enable) | ||
3469 | continue; | 3724 | continue; |
3470 | 3725 | ||
3471 | intf->handlers->request_events(intf->send_info); | 3726 | handlers = intf->handlers; |
3727 | if (handlers) | ||
3728 | handlers->request_events(intf->send_info); | ||
3472 | } | 3729 | } |
3473 | spin_unlock(&interfaces_lock); | 3730 | rcu_read_unlock(); |
3474 | } | 3731 | } |
3475 | 3732 | ||
3476 | static struct timer_list ipmi_timer; | 3733 | static struct timer_list ipmi_timer; |
@@ -3599,7 +3856,6 @@ static void send_panic_events(char *str) | |||
3599 | struct kernel_ipmi_msg msg; | 3856 | struct kernel_ipmi_msg msg; |
3600 | ipmi_smi_t intf; | 3857 | ipmi_smi_t intf; |
3601 | unsigned char data[16]; | 3858 | unsigned char data[16]; |
3602 | int i; | ||
3603 | struct ipmi_system_interface_addr *si; | 3859 | struct ipmi_system_interface_addr *si; |
3604 | struct ipmi_addr addr; | 3860 | struct ipmi_addr addr; |
3605 | struct ipmi_smi_msg smi_msg; | 3861 | struct ipmi_smi_msg smi_msg; |
@@ -3633,9 +3889,9 @@ static void send_panic_events(char *str) | |||
3633 | recv_msg.done = dummy_recv_done_handler; | 3889 | recv_msg.done = dummy_recv_done_handler; |
3634 | 3890 | ||
3635 | /* For every registered interface, send the event. */ | 3891 | /* For every registered interface, send the event. */ |
3636 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 3892 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
3637 | intf = ipmi_interfaces[i]; | 3893 | if (!intf->handlers) |
3638 | if (IPMI_INVALID_INTERFACE(intf)) | 3894 | /* Interface is not ready. */ |
3639 | continue; | 3895 | continue; |
3640 | 3896 | ||
3641 | /* Send the event announcing the panic. */ | 3897 | /* Send the event announcing the panic. */ |
@@ -3660,13 +3916,14 @@ static void send_panic_events(char *str) | |||
3660 | if (!str) | 3916 | if (!str) |
3661 | return; | 3917 | return; |
3662 | 3918 | ||
3663 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 3919 | /* For every registered interface, send the event. */ |
3920 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { | ||
3664 | char *p = str; | 3921 | char *p = str; |
3665 | struct ipmi_ipmb_addr *ipmb; | 3922 | struct ipmi_ipmb_addr *ipmb; |
3666 | int j; | 3923 | int j; |
3667 | 3924 | ||
3668 | intf = ipmi_interfaces[i]; | 3925 | if (intf->intf_num == -1) |
3669 | if (IPMI_INVALID_INTERFACE(intf)) | 3926 | /* Interface was not ready yet. */ |
3670 | continue; | 3927 | continue; |
3671 | 3928 | ||
3672 | /* First job here is to figure out where to send the | 3929 | /* First job here is to figure out where to send the |
@@ -3792,7 +4049,6 @@ static int panic_event(struct notifier_block *this, | |||
3792 | unsigned long event, | 4049 | unsigned long event, |
3793 | void *ptr) | 4050 | void *ptr) |
3794 | { | 4051 | { |
3795 | int i; | ||
3796 | ipmi_smi_t intf; | 4052 | ipmi_smi_t intf; |
3797 | 4053 | ||
3798 | if (has_panicked) | 4054 | if (has_panicked) |
@@ -3800,9 +4056,9 @@ static int panic_event(struct notifier_block *this, | |||
3800 | has_panicked = 1; | 4056 | has_panicked = 1; |
3801 | 4057 | ||
3802 | /* For every registered interface, set it to run to completion. */ | 4058 | /* For every registered interface, set it to run to completion. */ |
3803 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) { | 4059 | list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { |
3804 | intf = ipmi_interfaces[i]; | 4060 | if (!intf->handlers) |
3805 | if (IPMI_INVALID_INTERFACE(intf)) | 4061 | /* Interface is not ready. */ |
3806 | continue; | 4062 | continue; |
3807 | 4063 | ||
3808 | intf->handlers->set_run_to_completion(intf->send_info, 1); | 4064 | intf->handlers->set_run_to_completion(intf->send_info, 1); |
@@ -3823,7 +4079,6 @@ static struct notifier_block panic_block = { | |||
3823 | 4079 | ||
3824 | static int ipmi_init_msghandler(void) | 4080 | static int ipmi_init_msghandler(void) |
3825 | { | 4081 | { |
3826 | int i; | ||
3827 | int rv; | 4082 | int rv; |
3828 | 4083 | ||
3829 | if (initialized) | 4084 | if (initialized) |
@@ -3838,9 +4093,6 @@ static int ipmi_init_msghandler(void) | |||
3838 | printk(KERN_INFO "ipmi message handler version " | 4093 | printk(KERN_INFO "ipmi message handler version " |
3839 | IPMI_DRIVER_VERSION "\n"); | 4094 | IPMI_DRIVER_VERSION "\n"); |
3840 | 4095 | ||
3841 | for (i = 0; i < MAX_IPMI_INTERFACES; i++) | ||
3842 | ipmi_interfaces[i] = NULL; | ||
3843 | |||
3844 | #ifdef CONFIG_PROC_FS | 4096 | #ifdef CONFIG_PROC_FS |
3845 | proc_ipmi_root = proc_mkdir("ipmi", NULL); | 4097 | proc_ipmi_root = proc_mkdir("ipmi", NULL); |
3846 | if (!proc_ipmi_root) { | 4098 | if (!proc_ipmi_root) { |
diff --git a/drivers/char/ipmi/ipmi_poweroff.c b/drivers/char/ipmi/ipmi_poweroff.c index 8d941db83457..597eb4f88b84 100644 --- a/drivers/char/ipmi/ipmi_poweroff.c +++ b/drivers/char/ipmi/ipmi_poweroff.c | |||
@@ -43,6 +43,9 @@ | |||
43 | 43 | ||
44 | #define PFX "IPMI poweroff: " | 44 | #define PFX "IPMI poweroff: " |
45 | 45 | ||
46 | static void ipmi_po_smi_gone(int if_num); | ||
47 | static void ipmi_po_new_smi(int if_num, struct device *device); | ||
48 | |||
46 | /* Definitions for controlling power off (if the system supports it). It | 49 | /* Definitions for controlling power off (if the system supports it). It |
47 | * conveniently matches the IPMI chassis control values. */ | 50 | * conveniently matches the IPMI chassis control values. */ |
48 | #define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */ | 51 | #define IPMI_CHASSIS_POWER_DOWN 0 /* power down, the default. */ |
@@ -51,6 +54,37 @@ | |||
51 | /* the IPMI data command */ | 54 | /* the IPMI data command */ |
52 | static int poweroff_powercycle; | 55 | static int poweroff_powercycle; |
53 | 56 | ||
57 | /* Which interface to use, -1 means the first we see. */ | ||
58 | static int ifnum_to_use = -1; | ||
59 | |||
60 | /* Our local state. */ | ||
61 | static int ready = 0; | ||
62 | static ipmi_user_t ipmi_user; | ||
63 | static int ipmi_ifnum; | ||
64 | static void (*specific_poweroff_func)(ipmi_user_t user) = NULL; | ||
65 | |||
66 | /* Holds the old poweroff function so we can restore it on removal. */ | ||
67 | static void (*old_poweroff_func)(void); | ||
68 | |||
69 | static int set_param_ifnum(const char *val, struct kernel_param *kp) | ||
70 | { | ||
71 | int rv = param_set_int(val, kp); | ||
72 | if (rv) | ||
73 | return rv; | ||
74 | if ((ifnum_to_use < 0) || (ifnum_to_use == ipmi_ifnum)) | ||
75 | return 0; | ||
76 | |||
77 | ipmi_po_smi_gone(ipmi_ifnum); | ||
78 | ipmi_po_new_smi(ifnum_to_use, NULL); | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | module_param_call(ifnum_to_use, set_param_ifnum, param_get_int, | ||
83 | &ifnum_to_use, 0644); | ||
84 | MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " | ||
85 | "timer. Setting to -1 defaults to the first registered " | ||
86 | "interface"); | ||
87 | |||
54 | /* parameter definition to allow user to flag power cycle */ | 88 | /* parameter definition to allow user to flag power cycle */ |
55 | module_param(poweroff_powercycle, int, 0644); | 89 | module_param(poweroff_powercycle, int, 0644); |
56 | MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); | 90 | MODULE_PARM_DESC(poweroff_powercycle, " Set to non-zero to enable power cycle instead of power down. Power cycle is contingent on hardware support, otherwise it defaults back to power down."); |
@@ -142,6 +176,42 @@ static int ipmi_request_in_rc_mode(ipmi_user_t user, | |||
142 | #define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01 | 176 | #define IPMI_ATCA_GET_ADDR_INFO_CMD 0x01 |
143 | #define IPMI_PICMG_ID 0 | 177 | #define IPMI_PICMG_ID 0 |
144 | 178 | ||
179 | #define IPMI_NETFN_OEM 0x2e | ||
180 | #define IPMI_ATCA_PPS_GRACEFUL_RESTART 0x11 | ||
181 | #define IPMI_ATCA_PPS_IANA "\x00\x40\x0A" | ||
182 | #define IPMI_MOTOROLA_MANUFACTURER_ID 0x0000A1 | ||
183 | #define IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID 0x0051 | ||
184 | |||
185 | static void (*atca_oem_poweroff_hook)(ipmi_user_t user) = NULL; | ||
186 | |||
187 | static void pps_poweroff_atca (ipmi_user_t user) | ||
188 | { | ||
189 | struct ipmi_system_interface_addr smi_addr; | ||
190 | struct kernel_ipmi_msg send_msg; | ||
191 | int rv; | ||
192 | /* | ||
193 | * Configure IPMI address for local access | ||
194 | */ | ||
195 | smi_addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; | ||
196 | smi_addr.channel = IPMI_BMC_CHANNEL; | ||
197 | smi_addr.lun = 0; | ||
198 | |||
199 | printk(KERN_INFO PFX "PPS powerdown hook used"); | ||
200 | |||
201 | send_msg.netfn = IPMI_NETFN_OEM; | ||
202 | send_msg.cmd = IPMI_ATCA_PPS_GRACEFUL_RESTART; | ||
203 | send_msg.data = IPMI_ATCA_PPS_IANA; | ||
204 | send_msg.data_len = 3; | ||
205 | rv = ipmi_request_in_rc_mode(user, | ||
206 | (struct ipmi_addr *) &smi_addr, | ||
207 | &send_msg); | ||
208 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | ||
209 | printk(KERN_ERR PFX "Unable to send ATCA ," | ||
210 | " IPMI error 0x%x\n", rv); | ||
211 | } | ||
212 | return; | ||
213 | } | ||
214 | |||
145 | static int ipmi_atca_detect (ipmi_user_t user) | 215 | static int ipmi_atca_detect (ipmi_user_t user) |
146 | { | 216 | { |
147 | struct ipmi_system_interface_addr smi_addr; | 217 | struct ipmi_system_interface_addr smi_addr; |
@@ -167,6 +237,13 @@ static int ipmi_atca_detect (ipmi_user_t user) | |||
167 | rv = ipmi_request_wait_for_response(user, | 237 | rv = ipmi_request_wait_for_response(user, |
168 | (struct ipmi_addr *) &smi_addr, | 238 | (struct ipmi_addr *) &smi_addr, |
169 | &send_msg); | 239 | &send_msg); |
240 | |||
241 | printk(KERN_INFO PFX "ATCA Detect mfg 0x%X prod 0x%X\n", mfg_id, prod_id); | ||
242 | if((mfg_id == IPMI_MOTOROLA_MANUFACTURER_ID) | ||
243 | && (prod_id == IPMI_MOTOROLA_PPS_IPMC_PRODUCT_ID)) { | ||
244 | printk(KERN_INFO PFX "Installing Pigeon Point Systems Poweroff Hook\n"); | ||
245 | atca_oem_poweroff_hook = pps_poweroff_atca; | ||
246 | } | ||
170 | return !rv; | 247 | return !rv; |
171 | } | 248 | } |
172 | 249 | ||
@@ -200,12 +277,19 @@ static void ipmi_poweroff_atca (ipmi_user_t user) | |||
200 | rv = ipmi_request_in_rc_mode(user, | 277 | rv = ipmi_request_in_rc_mode(user, |
201 | (struct ipmi_addr *) &smi_addr, | 278 | (struct ipmi_addr *) &smi_addr, |
202 | &send_msg); | 279 | &send_msg); |
203 | if (rv) { | 280 | /** At this point, the system may be shutting down, and most |
281 | ** serial drivers (if used) will have interrupts turned off | ||
282 | ** it may be better to ignore IPMI_UNKNOWN_ERR_COMPLETION_CODE | ||
283 | ** return code | ||
284 | **/ | ||
285 | if (rv && rv != IPMI_UNKNOWN_ERR_COMPLETION_CODE) { | ||
204 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," | 286 | printk(KERN_ERR PFX "Unable to send ATCA powerdown message," |
205 | " IPMI error 0x%x\n", rv); | 287 | " IPMI error 0x%x\n", rv); |
206 | goto out; | 288 | goto out; |
207 | } | 289 | } |
208 | 290 | ||
291 | if(atca_oem_poweroff_hook) | ||
292 | return atca_oem_poweroff_hook(user); | ||
209 | out: | 293 | out: |
210 | return; | 294 | return; |
211 | } | 295 | } |
@@ -440,15 +524,6 @@ static struct poweroff_function poweroff_functions[] = { | |||
440 | / sizeof(struct poweroff_function)) | 524 | / sizeof(struct poweroff_function)) |
441 | 525 | ||
442 | 526 | ||
443 | /* Our local state. */ | ||
444 | static int ready = 0; | ||
445 | static ipmi_user_t ipmi_user; | ||
446 | static void (*specific_poweroff_func)(ipmi_user_t user) = NULL; | ||
447 | |||
448 | /* Holds the old poweroff function so we can restore it on removal. */ | ||
449 | static void (*old_poweroff_func)(void); | ||
450 | |||
451 | |||
452 | /* Called on a powerdown request. */ | 527 | /* Called on a powerdown request. */ |
453 | static void ipmi_poweroff_function (void) | 528 | static void ipmi_poweroff_function (void) |
454 | { | 529 | { |
@@ -473,6 +548,9 @@ static void ipmi_po_new_smi(int if_num, struct device *device) | |||
473 | if (ready) | 548 | if (ready) |
474 | return; | 549 | return; |
475 | 550 | ||
551 | if ((ifnum_to_use >= 0) && (ifnum_to_use != if_num)) | ||
552 | return; | ||
553 | |||
476 | rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, | 554 | rv = ipmi_create_user(if_num, &ipmi_poweroff_handler, NULL, |
477 | &ipmi_user); | 555 | &ipmi_user); |
478 | if (rv) { | 556 | if (rv) { |
@@ -481,6 +559,8 @@ static void ipmi_po_new_smi(int if_num, struct device *device) | |||
481 | return; | 559 | return; |
482 | } | 560 | } |
483 | 561 | ||
562 | ipmi_ifnum = if_num; | ||
563 | |||
484 | /* | 564 | /* |
485 | * Do a get device ide and store some results, since this is | 565 | * Do a get device ide and store some results, since this is |
486 | * used by several functions. | 566 | * used by several functions. |
@@ -541,9 +621,15 @@ static void ipmi_po_new_smi(int if_num, struct device *device) | |||
541 | 621 | ||
542 | static void ipmi_po_smi_gone(int if_num) | 622 | static void ipmi_po_smi_gone(int if_num) |
543 | { | 623 | { |
544 | /* This can never be called, because once poweroff driver is | 624 | if (!ready) |
545 | registered, the interface can't go away until the power | 625 | return; |
546 | driver is unregistered. */ | 626 | |
627 | if (ipmi_ifnum != if_num) | ||
628 | return; | ||
629 | |||
630 | ready = 0; | ||
631 | ipmi_destroy_user(ipmi_user); | ||
632 | pm_power_off = old_poweroff_func; | ||
547 | } | 633 | } |
548 | 634 | ||
549 | static struct ipmi_smi_watcher smi_watcher = | 635 | static struct ipmi_smi_watcher smi_watcher = |
@@ -616,9 +702,9 @@ static int ipmi_poweroff_init (void) | |||
616 | printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); | 702 | printk(KERN_ERR PFX "Unable to register SMI watcher: %d\n", rv); |
617 | goto out_err; | 703 | goto out_err; |
618 | } | 704 | } |
619 | #endif | ||
620 | 705 | ||
621 | out_err: | 706 | out_err: |
707 | #endif | ||
622 | return rv; | 708 | return rv; |
623 | } | 709 | } |
624 | 710 | ||
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index bb1fac104fda..81a0c89598e7 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -61,6 +61,10 @@ | |||
61 | #include "ipmi_si_sm.h" | 61 | #include "ipmi_si_sm.h" |
62 | #include <linux/init.h> | 62 | #include <linux/init.h> |
63 | #include <linux/dmi.h> | 63 | #include <linux/dmi.h> |
64 | #include <linux/string.h> | ||
65 | #include <linux/ctype.h> | ||
66 | |||
67 | #define PFX "ipmi_si: " | ||
64 | 68 | ||
65 | /* Measure times between events in the driver. */ | 69 | /* Measure times between events in the driver. */ |
66 | #undef DEBUG_TIMING | 70 | #undef DEBUG_TIMING |
@@ -92,7 +96,7 @@ enum si_intf_state { | |||
92 | enum si_type { | 96 | enum si_type { |
93 | SI_KCS, SI_SMIC, SI_BT | 97 | SI_KCS, SI_SMIC, SI_BT |
94 | }; | 98 | }; |
95 | static char *si_to_str[] = { "KCS", "SMIC", "BT" }; | 99 | static char *si_to_str[] = { "kcs", "smic", "bt" }; |
96 | 100 | ||
97 | #define DEVICE_NAME "ipmi_si" | 101 | #define DEVICE_NAME "ipmi_si" |
98 | 102 | ||
@@ -222,7 +226,10 @@ struct smi_info | |||
222 | static int force_kipmid[SI_MAX_PARMS]; | 226 | static int force_kipmid[SI_MAX_PARMS]; |
223 | static int num_force_kipmid; | 227 | static int num_force_kipmid; |
224 | 228 | ||
229 | static int unload_when_empty = 1; | ||
230 | |||
225 | static int try_smi_init(struct smi_info *smi); | 231 | static int try_smi_init(struct smi_info *smi); |
232 | static void cleanup_one_si(struct smi_info *to_clean); | ||
226 | 233 | ||
227 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); | 234 | static ATOMIC_NOTIFIER_HEAD(xaction_notifier_list); |
228 | static int register_xaction_notifier(struct notifier_block * nb) | 235 | static int register_xaction_notifier(struct notifier_block * nb) |
@@ -240,14 +247,18 @@ static void deliver_recv_msg(struct smi_info *smi_info, | |||
240 | spin_lock(&(smi_info->si_lock)); | 247 | spin_lock(&(smi_info->si_lock)); |
241 | } | 248 | } |
242 | 249 | ||
243 | static void return_hosed_msg(struct smi_info *smi_info) | 250 | static void return_hosed_msg(struct smi_info *smi_info, int cCode) |
244 | { | 251 | { |
245 | struct ipmi_smi_msg *msg = smi_info->curr_msg; | 252 | struct ipmi_smi_msg *msg = smi_info->curr_msg; |
246 | 253 | ||
254 | if (cCode < 0 || cCode > IPMI_ERR_UNSPECIFIED) | ||
255 | cCode = IPMI_ERR_UNSPECIFIED; | ||
256 | /* else use it as is */ | ||
257 | |||
247 | /* Make it a reponse */ | 258 | /* Make it a reponse */ |
248 | msg->rsp[0] = msg->data[0] | 4; | 259 | msg->rsp[0] = msg->data[0] | 4; |
249 | msg->rsp[1] = msg->data[1]; | 260 | msg->rsp[1] = msg->data[1]; |
250 | msg->rsp[2] = 0xFF; /* Unknown error. */ | 261 | msg->rsp[2] = cCode; |
251 | msg->rsp_size = 3; | 262 | msg->rsp_size = 3; |
252 | 263 | ||
253 | smi_info->curr_msg = NULL; | 264 | smi_info->curr_msg = NULL; |
@@ -298,7 +309,7 @@ static enum si_sm_result start_next_msg(struct smi_info *smi_info) | |||
298 | smi_info->curr_msg->data, | 309 | smi_info->curr_msg->data, |
299 | smi_info->curr_msg->data_size); | 310 | smi_info->curr_msg->data_size); |
300 | if (err) { | 311 | if (err) { |
301 | return_hosed_msg(smi_info); | 312 | return_hosed_msg(smi_info, err); |
302 | } | 313 | } |
303 | 314 | ||
304 | rv = SI_SM_CALL_WITHOUT_DELAY; | 315 | rv = SI_SM_CALL_WITHOUT_DELAY; |
@@ -640,7 +651,7 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, | |||
640 | /* If we were handling a user message, format | 651 | /* If we were handling a user message, format |
641 | a response to send to the upper layer to | 652 | a response to send to the upper layer to |
642 | tell it about the error. */ | 653 | tell it about the error. */ |
643 | return_hosed_msg(smi_info); | 654 | return_hosed_msg(smi_info, IPMI_ERR_UNSPECIFIED); |
644 | } | 655 | } |
645 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); | 656 | si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0); |
646 | } | 657 | } |
@@ -684,22 +695,24 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, | |||
684 | { | 695 | { |
685 | /* We are idle and the upper layer requested that I fetch | 696 | /* We are idle and the upper layer requested that I fetch |
686 | events, so do so. */ | 697 | events, so do so. */ |
687 | unsigned char msg[2]; | 698 | atomic_set(&smi_info->req_events, 0); |
688 | 699 | ||
689 | spin_lock(&smi_info->count_lock); | 700 | smi_info->curr_msg = ipmi_alloc_smi_msg(); |
690 | smi_info->flag_fetches++; | 701 | if (!smi_info->curr_msg) |
691 | spin_unlock(&smi_info->count_lock); | 702 | goto out; |
692 | 703 | ||
693 | atomic_set(&smi_info->req_events, 0); | 704 | smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); |
694 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | 705 | smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD; |
695 | msg[1] = IPMI_GET_MSG_FLAGS_CMD; | 706 | smi_info->curr_msg->data_size = 2; |
696 | 707 | ||
697 | smi_info->handlers->start_transaction( | 708 | smi_info->handlers->start_transaction( |
698 | smi_info->si_sm, msg, 2); | 709 | smi_info->si_sm, |
699 | smi_info->si_state = SI_GETTING_FLAGS; | 710 | smi_info->curr_msg->data, |
711 | smi_info->curr_msg->data_size); | ||
712 | smi_info->si_state = SI_GETTING_EVENTS; | ||
700 | goto restart; | 713 | goto restart; |
701 | } | 714 | } |
702 | 715 | out: | |
703 | return si_sm_result; | 716 | return si_sm_result; |
704 | } | 717 | } |
705 | 718 | ||
@@ -714,6 +727,15 @@ static void sender(void *send_info, | |||
714 | struct timeval t; | 727 | struct timeval t; |
715 | #endif | 728 | #endif |
716 | 729 | ||
730 | if (atomic_read(&smi_info->stop_operation)) { | ||
731 | msg->rsp[0] = msg->data[0] | 4; | ||
732 | msg->rsp[1] = msg->data[1]; | ||
733 | msg->rsp[2] = IPMI_ERR_UNSPECIFIED; | ||
734 | msg->rsp_size = 3; | ||
735 | deliver_recv_msg(smi_info, msg); | ||
736 | return; | ||
737 | } | ||
738 | |||
717 | spin_lock_irqsave(&(smi_info->msg_lock), flags); | 739 | spin_lock_irqsave(&(smi_info->msg_lock), flags); |
718 | #ifdef DEBUG_TIMING | 740 | #ifdef DEBUG_TIMING |
719 | do_gettimeofday(&t); | 741 | do_gettimeofday(&t); |
@@ -805,13 +827,21 @@ static void poll(void *send_info) | |||
805 | { | 827 | { |
806 | struct smi_info *smi_info = send_info; | 828 | struct smi_info *smi_info = send_info; |
807 | 829 | ||
808 | smi_event_handler(smi_info, 0); | 830 | /* |
831 | * Make sure there is some delay in the poll loop so we can | ||
832 | * drive time forward and timeout things. | ||
833 | */ | ||
834 | udelay(10); | ||
835 | smi_event_handler(smi_info, 10); | ||
809 | } | 836 | } |
810 | 837 | ||
811 | static void request_events(void *send_info) | 838 | static void request_events(void *send_info) |
812 | { | 839 | { |
813 | struct smi_info *smi_info = send_info; | 840 | struct smi_info *smi_info = send_info; |
814 | 841 | ||
842 | if (atomic_read(&smi_info->stop_operation)) | ||
843 | return; | ||
844 | |||
815 | atomic_set(&smi_info->req_events, 1); | 845 | atomic_set(&smi_info->req_events, 1); |
816 | } | 846 | } |
817 | 847 | ||
@@ -949,12 +979,21 @@ static int smi_start_processing(void *send_info, | |||
949 | return 0; | 979 | return 0; |
950 | } | 980 | } |
951 | 981 | ||
982 | static void set_maintenance_mode(void *send_info, int enable) | ||
983 | { | ||
984 | struct smi_info *smi_info = send_info; | ||
985 | |||
986 | if (!enable) | ||
987 | atomic_set(&smi_info->req_events, 0); | ||
988 | } | ||
989 | |||
952 | static struct ipmi_smi_handlers handlers = | 990 | static struct ipmi_smi_handlers handlers = |
953 | { | 991 | { |
954 | .owner = THIS_MODULE, | 992 | .owner = THIS_MODULE, |
955 | .start_processing = smi_start_processing, | 993 | .start_processing = smi_start_processing, |
956 | .sender = sender, | 994 | .sender = sender, |
957 | .request_events = request_events, | 995 | .request_events = request_events, |
996 | .set_maintenance_mode = set_maintenance_mode, | ||
958 | .set_run_to_completion = set_run_to_completion, | 997 | .set_run_to_completion = set_run_to_completion, |
959 | .poll = poll, | 998 | .poll = poll, |
960 | }; | 999 | }; |
@@ -987,6 +1026,16 @@ static int num_regshifts = 0; | |||
987 | static int slave_addrs[SI_MAX_PARMS]; | 1026 | static int slave_addrs[SI_MAX_PARMS]; |
988 | static int num_slave_addrs = 0; | 1027 | static int num_slave_addrs = 0; |
989 | 1028 | ||
1029 | #define IPMI_IO_ADDR_SPACE 0 | ||
1030 | #define IPMI_MEM_ADDR_SPACE 1 | ||
1031 | static char *addr_space_to_str[] = { "I/O", "mem" }; | ||
1032 | |||
1033 | static int hotmod_handler(const char *val, struct kernel_param *kp); | ||
1034 | |||
1035 | module_param_call(hotmod, hotmod_handler, NULL, NULL, 0200); | ||
1036 | MODULE_PARM_DESC(hotmod, "Add and remove interfaces. See" | ||
1037 | " Documentation/IPMI.txt in the kernel sources for the" | ||
1038 | " gory details."); | ||
990 | 1039 | ||
991 | module_param_named(trydefaults, si_trydefaults, bool, 0); | 1040 | module_param_named(trydefaults, si_trydefaults, bool, 0); |
992 | MODULE_PARM_DESC(trydefaults, "Setting this to 'false' will disable the" | 1041 | MODULE_PARM_DESC(trydefaults, "Setting this to 'false' will disable the" |
@@ -1038,12 +1087,12 @@ module_param_array(force_kipmid, int, &num_force_kipmid, 0); | |||
1038 | MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or" | 1087 | MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or" |
1039 | " disabled(0). Normally the IPMI driver auto-detects" | 1088 | " disabled(0). Normally the IPMI driver auto-detects" |
1040 | " this, but the value may be overridden by this parm."); | 1089 | " this, but the value may be overridden by this parm."); |
1090 | module_param(unload_when_empty, int, 0); | ||
1091 | MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are" | ||
1092 | " specified or found, default is 1. Setting to 0" | ||
1093 | " is useful for hot add of devices using hotmod."); | ||
1041 | 1094 | ||
1042 | 1095 | ||
1043 | #define IPMI_IO_ADDR_SPACE 0 | ||
1044 | #define IPMI_MEM_ADDR_SPACE 1 | ||
1045 | static char *addr_space_to_str[] = { "I/O", "memory" }; | ||
1046 | |||
1047 | static void std_irq_cleanup(struct smi_info *info) | 1096 | static void std_irq_cleanup(struct smi_info *info) |
1048 | { | 1097 | { |
1049 | if (info->si_type == SI_BT) | 1098 | if (info->si_type == SI_BT) |
@@ -1317,6 +1366,234 @@ static int mem_setup(struct smi_info *info) | |||
1317 | return 0; | 1366 | return 0; |
1318 | } | 1367 | } |
1319 | 1368 | ||
1369 | /* | ||
1370 | * Parms come in as <op1>[:op2[:op3...]]. ops are: | ||
1371 | * add|remove,kcs|bt|smic,mem|i/o,<address>[,<opt1>[,<opt2>[,...]]] | ||
1372 | * Options are: | ||
1373 | * rsp=<regspacing> | ||
1374 | * rsi=<regsize> | ||
1375 | * rsh=<regshift> | ||
1376 | * irq=<irq> | ||
1377 | * ipmb=<ipmb addr> | ||
1378 | */ | ||
1379 | enum hotmod_op { HM_ADD, HM_REMOVE }; | ||
1380 | struct hotmod_vals { | ||
1381 | char *name; | ||
1382 | int val; | ||
1383 | }; | ||
1384 | static struct hotmod_vals hotmod_ops[] = { | ||
1385 | { "add", HM_ADD }, | ||
1386 | { "remove", HM_REMOVE }, | ||
1387 | { NULL } | ||
1388 | }; | ||
1389 | static struct hotmod_vals hotmod_si[] = { | ||
1390 | { "kcs", SI_KCS }, | ||
1391 | { "smic", SI_SMIC }, | ||
1392 | { "bt", SI_BT }, | ||
1393 | { NULL } | ||
1394 | }; | ||
1395 | static struct hotmod_vals hotmod_as[] = { | ||
1396 | { "mem", IPMI_MEM_ADDR_SPACE }, | ||
1397 | { "i/o", IPMI_IO_ADDR_SPACE }, | ||
1398 | { NULL } | ||
1399 | }; | ||
1400 | static int ipmi_strcasecmp(const char *s1, const char *s2) | ||
1401 | { | ||
1402 | while (*s1 || *s2) { | ||
1403 | if (!*s1) | ||
1404 | return -1; | ||
1405 | if (!*s2) | ||
1406 | return 1; | ||
1407 | if (*s1 != *s2) | ||
1408 | return *s1 - *s2; | ||
1409 | s1++; | ||
1410 | s2++; | ||
1411 | } | ||
1412 | return 0; | ||
1413 | } | ||
1414 | static int parse_str(struct hotmod_vals *v, int *val, char *name, char **curr) | ||
1415 | { | ||
1416 | char *s; | ||
1417 | int i; | ||
1418 | |||
1419 | s = strchr(*curr, ','); | ||
1420 | if (!s) { | ||
1421 | printk(KERN_WARNING PFX "No hotmod %s given.\n", name); | ||
1422 | return -EINVAL; | ||
1423 | } | ||
1424 | *s = '\0'; | ||
1425 | s++; | ||
1426 | for (i = 0; hotmod_ops[i].name; i++) { | ||
1427 | if (ipmi_strcasecmp(*curr, v[i].name) == 0) { | ||
1428 | *val = v[i].val; | ||
1429 | *curr = s; | ||
1430 | return 0; | ||
1431 | } | ||
1432 | } | ||
1433 | |||
1434 | printk(KERN_WARNING PFX "Invalid hotmod %s '%s'\n", name, *curr); | ||
1435 | return -EINVAL; | ||
1436 | } | ||
1437 | |||
1438 | static int hotmod_handler(const char *val, struct kernel_param *kp) | ||
1439 | { | ||
1440 | char *str = kstrdup(val, GFP_KERNEL); | ||
1441 | int rv = -EINVAL; | ||
1442 | char *next, *curr, *s, *n, *o; | ||
1443 | enum hotmod_op op; | ||
1444 | enum si_type si_type; | ||
1445 | int addr_space; | ||
1446 | unsigned long addr; | ||
1447 | int regspacing; | ||
1448 | int regsize; | ||
1449 | int regshift; | ||
1450 | int irq; | ||
1451 | int ipmb; | ||
1452 | int ival; | ||
1453 | struct smi_info *info; | ||
1454 | |||
1455 | if (!str) | ||
1456 | return -ENOMEM; | ||
1457 | |||
1458 | /* Kill any trailing spaces, as we can get a "\n" from echo. */ | ||
1459 | ival = strlen(str) - 1; | ||
1460 | while ((ival >= 0) && isspace(str[ival])) { | ||
1461 | str[ival] = '\0'; | ||
1462 | ival--; | ||
1463 | } | ||
1464 | |||
1465 | for (curr = str; curr; curr = next) { | ||
1466 | regspacing = 1; | ||
1467 | regsize = 1; | ||
1468 | regshift = 0; | ||
1469 | irq = 0; | ||
1470 | ipmb = 0x20; | ||
1471 | |||
1472 | next = strchr(curr, ':'); | ||
1473 | if (next) { | ||
1474 | *next = '\0'; | ||
1475 | next++; | ||
1476 | } | ||
1477 | |||
1478 | rv = parse_str(hotmod_ops, &ival, "operation", &curr); | ||
1479 | if (rv) | ||
1480 | break; | ||
1481 | op = ival; | ||
1482 | |||
1483 | rv = parse_str(hotmod_si, &ival, "interface type", &curr); | ||
1484 | if (rv) | ||
1485 | break; | ||
1486 | si_type = ival; | ||
1487 | |||
1488 | rv = parse_str(hotmod_as, &addr_space, "address space", &curr); | ||
1489 | if (rv) | ||
1490 | break; | ||
1491 | |||
1492 | s = strchr(curr, ','); | ||
1493 | if (s) { | ||
1494 | *s = '\0'; | ||
1495 | s++; | ||
1496 | } | ||
1497 | addr = simple_strtoul(curr, &n, 0); | ||
1498 | if ((*n != '\0') || (*curr == '\0')) { | ||
1499 | printk(KERN_WARNING PFX "Invalid hotmod address" | ||
1500 | " '%s'\n", curr); | ||
1501 | break; | ||
1502 | } | ||
1503 | |||
1504 | while (s) { | ||
1505 | curr = s; | ||
1506 | s = strchr(curr, ','); | ||
1507 | if (s) { | ||
1508 | *s = '\0'; | ||
1509 | s++; | ||
1510 | } | ||
1511 | o = strchr(curr, '='); | ||
1512 | if (o) { | ||
1513 | *o = '\0'; | ||
1514 | o++; | ||
1515 | } | ||
1516 | #define HOTMOD_INT_OPT(name, val) \ | ||
1517 | if (ipmi_strcasecmp(curr, name) == 0) { \ | ||
1518 | if (!o) { \ | ||
1519 | printk(KERN_WARNING PFX \ | ||
1520 | "No option given for '%s'\n", \ | ||
1521 | curr); \ | ||
1522 | goto out; \ | ||
1523 | } \ | ||
1524 | val = simple_strtoul(o, &n, 0); \ | ||
1525 | if ((*n != '\0') || (*o == '\0')) { \ | ||
1526 | printk(KERN_WARNING PFX \ | ||
1527 | "Bad option given for '%s'\n", \ | ||
1528 | curr); \ | ||
1529 | goto out; \ | ||
1530 | } \ | ||
1531 | } | ||
1532 | |||
1533 | HOTMOD_INT_OPT("rsp", regspacing) | ||
1534 | else HOTMOD_INT_OPT("rsi", regsize) | ||
1535 | else HOTMOD_INT_OPT("rsh", regshift) | ||
1536 | else HOTMOD_INT_OPT("irq", irq) | ||
1537 | else HOTMOD_INT_OPT("ipmb", ipmb) | ||
1538 | else { | ||
1539 | printk(KERN_WARNING PFX | ||
1540 | "Invalid hotmod option '%s'\n", | ||
1541 | curr); | ||
1542 | goto out; | ||
1543 | } | ||
1544 | #undef HOTMOD_INT_OPT | ||
1545 | } | ||
1546 | |||
1547 | if (op == HM_ADD) { | ||
1548 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
1549 | if (!info) { | ||
1550 | rv = -ENOMEM; | ||
1551 | goto out; | ||
1552 | } | ||
1553 | |||
1554 | info->addr_source = "hotmod"; | ||
1555 | info->si_type = si_type; | ||
1556 | info->io.addr_data = addr; | ||
1557 | info->io.addr_type = addr_space; | ||
1558 | if (addr_space == IPMI_MEM_ADDR_SPACE) | ||
1559 | info->io_setup = mem_setup; | ||
1560 | else | ||
1561 | info->io_setup = port_setup; | ||
1562 | |||
1563 | info->io.addr = NULL; | ||
1564 | info->io.regspacing = regspacing; | ||
1565 | if (!info->io.regspacing) | ||
1566 | info->io.regspacing = DEFAULT_REGSPACING; | ||
1567 | info->io.regsize = regsize; | ||
1568 | if (!info->io.regsize) | ||
1569 | info->io.regsize = DEFAULT_REGSPACING; | ||
1570 | info->io.regshift = regshift; | ||
1571 | info->irq = irq; | ||
1572 | if (info->irq) | ||
1573 | info->irq_setup = std_irq_setup; | ||
1574 | info->slave_addr = ipmb; | ||
1575 | |||
1576 | try_smi_init(info); | ||
1577 | } else { | ||
1578 | /* remove */ | ||
1579 | struct smi_info *e, *tmp_e; | ||
1580 | |||
1581 | mutex_lock(&smi_infos_lock); | ||
1582 | list_for_each_entry_safe(e, tmp_e, &smi_infos, link) { | ||
1583 | if (e->io.addr_type != addr_space) | ||
1584 | continue; | ||
1585 | if (e->si_type != si_type) | ||
1586 | continue; | ||
1587 | if (e->io.addr_data == addr) | ||
1588 | cleanup_one_si(e); | ||
1589 | } | ||
1590 | mutex_unlock(&smi_infos_lock); | ||
1591 | } | ||
1592 | } | ||
1593 | out: | ||
1594 | kfree(str); | ||
1595 | return rv; | ||
1596 | } | ||
1320 | 1597 | ||
1321 | static __devinit void hardcode_find_bmc(void) | 1598 | static __devinit void hardcode_find_bmc(void) |
1322 | { | 1599 | { |
@@ -1333,11 +1610,11 @@ static __devinit void hardcode_find_bmc(void) | |||
1333 | 1610 | ||
1334 | info->addr_source = "hardcoded"; | 1611 | info->addr_source = "hardcoded"; |
1335 | 1612 | ||
1336 | if (!si_type[i] || strcmp(si_type[i], "kcs") == 0) { | 1613 | if (!si_type[i] || ipmi_strcasecmp(si_type[i], "kcs") == 0) { |
1337 | info->si_type = SI_KCS; | 1614 | info->si_type = SI_KCS; |
1338 | } else if (strcmp(si_type[i], "smic") == 0) { | 1615 | } else if (ipmi_strcasecmp(si_type[i], "smic") == 0) { |
1339 | info->si_type = SI_SMIC; | 1616 | info->si_type = SI_SMIC; |
1340 | } else if (strcmp(si_type[i], "bt") == 0) { | 1617 | } else if (ipmi_strcasecmp(si_type[i], "bt") == 0) { |
1341 | info->si_type = SI_BT; | 1618 | info->si_type = SI_BT; |
1342 | } else { | 1619 | } else { |
1343 | printk(KERN_WARNING | 1620 | printk(KERN_WARNING |
@@ -1952,19 +2229,9 @@ static int try_get_dev_id(struct smi_info *smi_info) | |||
1952 | static int type_file_read_proc(char *page, char **start, off_t off, | 2229 | static int type_file_read_proc(char *page, char **start, off_t off, |
1953 | int count, int *eof, void *data) | 2230 | int count, int *eof, void *data) |
1954 | { | 2231 | { |
1955 | char *out = (char *) page; | ||
1956 | struct smi_info *smi = data; | 2232 | struct smi_info *smi = data; |
1957 | 2233 | ||
1958 | switch (smi->si_type) { | 2234 | return sprintf(page, "%s\n", si_to_str[smi->si_type]); |
1959 | case SI_KCS: | ||
1960 | return sprintf(out, "kcs\n"); | ||
1961 | case SI_SMIC: | ||
1962 | return sprintf(out, "smic\n"); | ||
1963 | case SI_BT: | ||
1964 | return sprintf(out, "bt\n"); | ||
1965 | default: | ||
1966 | return 0; | ||
1967 | } | ||
1968 | } | 2235 | } |
1969 | 2236 | ||
1970 | static int stat_file_read_proc(char *page, char **start, off_t off, | 2237 | static int stat_file_read_proc(char *page, char **start, off_t off, |
@@ -2000,7 +2267,24 @@ static int stat_file_read_proc(char *page, char **start, off_t off, | |||
2000 | out += sprintf(out, "incoming_messages: %ld\n", | 2267 | out += sprintf(out, "incoming_messages: %ld\n", |
2001 | smi->incoming_messages); | 2268 | smi->incoming_messages); |
2002 | 2269 | ||
2003 | return (out - ((char *) page)); | 2270 | return out - page; |
2271 | } | ||
2272 | |||
2273 | static int param_read_proc(char *page, char **start, off_t off, | ||
2274 | int count, int *eof, void *data) | ||
2275 | { | ||
2276 | struct smi_info *smi = data; | ||
2277 | |||
2278 | return sprintf(page, | ||
2279 | "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n", | ||
2280 | si_to_str[smi->si_type], | ||
2281 | addr_space_to_str[smi->io.addr_type], | ||
2282 | smi->io.addr_data, | ||
2283 | smi->io.regspacing, | ||
2284 | smi->io.regsize, | ||
2285 | smi->io.regshift, | ||
2286 | smi->irq, | ||
2287 | smi->slave_addr); | ||
2004 | } | 2288 | } |
2005 | 2289 | ||
2006 | /* | 2290 | /* |
@@ -2362,6 +2646,7 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2362 | new_smi, | 2646 | new_smi, |
2363 | &new_smi->device_id, | 2647 | &new_smi->device_id, |
2364 | new_smi->dev, | 2648 | new_smi->dev, |
2649 | "bmc", | ||
2365 | new_smi->slave_addr); | 2650 | new_smi->slave_addr); |
2366 | if (rv) { | 2651 | if (rv) { |
2367 | printk(KERN_ERR | 2652 | printk(KERN_ERR |
@@ -2390,6 +2675,16 @@ static int try_smi_init(struct smi_info *new_smi) | |||
2390 | goto out_err_stop_timer; | 2675 | goto out_err_stop_timer; |
2391 | } | 2676 | } |
2392 | 2677 | ||
2678 | rv = ipmi_smi_add_proc_entry(new_smi->intf, "params", | ||
2679 | param_read_proc, NULL, | ||
2680 | new_smi, THIS_MODULE); | ||
2681 | if (rv) { | ||
2682 | printk(KERN_ERR | ||
2683 | "ipmi_si: Unable to create proc entry: %d\n", | ||
2684 | rv); | ||
2685 | goto out_err_stop_timer; | ||
2686 | } | ||
2687 | |||
2393 | list_add_tail(&new_smi->link, &smi_infos); | 2688 | list_add_tail(&new_smi->link, &smi_infos); |
2394 | 2689 | ||
2395 | mutex_unlock(&smi_infos_lock); | 2690 | mutex_unlock(&smi_infos_lock); |
@@ -2483,7 +2778,12 @@ static __devinit int init_ipmi_si(void) | |||
2483 | #endif | 2778 | #endif |
2484 | 2779 | ||
2485 | #ifdef CONFIG_PCI | 2780 | #ifdef CONFIG_PCI |
2486 | pci_module_init(&ipmi_pci_driver); | 2781 | rv = pci_register_driver(&ipmi_pci_driver); |
2782 | if (rv){ | ||
2783 | printk(KERN_ERR | ||
2784 | "init_ipmi_si: Unable to register PCI driver: %d\n", | ||
2785 | rv); | ||
2786 | } | ||
2487 | #endif | 2787 | #endif |
2488 | 2788 | ||
2489 | if (si_trydefaults) { | 2789 | if (si_trydefaults) { |
@@ -2498,7 +2798,7 @@ static __devinit int init_ipmi_si(void) | |||
2498 | } | 2798 | } |
2499 | 2799 | ||
2500 | mutex_lock(&smi_infos_lock); | 2800 | mutex_lock(&smi_infos_lock); |
2501 | if (list_empty(&smi_infos)) { | 2801 | if (unload_when_empty && list_empty(&smi_infos)) { |
2502 | mutex_unlock(&smi_infos_lock); | 2802 | mutex_unlock(&smi_infos_lock); |
2503 | #ifdef CONFIG_PCI | 2803 | #ifdef CONFIG_PCI |
2504 | pci_unregister_driver(&ipmi_pci_driver); | 2804 | pci_unregister_driver(&ipmi_pci_driver); |
@@ -2513,7 +2813,7 @@ static __devinit int init_ipmi_si(void) | |||
2513 | } | 2813 | } |
2514 | module_init(init_ipmi_si); | 2814 | module_init(init_ipmi_si); |
2515 | 2815 | ||
2516 | static void __devexit cleanup_one_si(struct smi_info *to_clean) | 2816 | static void cleanup_one_si(struct smi_info *to_clean) |
2517 | { | 2817 | { |
2518 | int rv; | 2818 | int rv; |
2519 | unsigned long flags; | 2819 | unsigned long flags; |
diff --git a/drivers/char/ipmi/ipmi_smic_sm.c b/drivers/char/ipmi/ipmi_smic_sm.c index 39d7e5ef1a2b..e64ea7d25d24 100644 --- a/drivers/char/ipmi/ipmi_smic_sm.c +++ b/drivers/char/ipmi/ipmi_smic_sm.c | |||
@@ -141,12 +141,14 @@ static int start_smic_transaction(struct si_sm_data *smic, | |||
141 | { | 141 | { |
142 | unsigned int i; | 142 | unsigned int i; |
143 | 143 | ||
144 | if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) { | 144 | if (size < 2) |
145 | return -1; | 145 | return IPMI_REQ_LEN_INVALID_ERR; |
146 | } | 146 | if (size > MAX_SMIC_WRITE_SIZE) |
147 | if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) { | 147 | return IPMI_REQ_LEN_EXCEEDED_ERR; |
148 | return -2; | 148 | |
149 | } | 149 | if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) |
150 | return IPMI_NOT_IN_MY_STATE_ERR; | ||
151 | |||
150 | if (smic_debug & SMIC_DEBUG_MSG) { | 152 | if (smic_debug & SMIC_DEBUG_MSG) { |
151 | printk(KERN_INFO "start_smic_transaction -"); | 153 | printk(KERN_INFO "start_smic_transaction -"); |
152 | for (i = 0; i < size; i ++) { | 154 | for (i = 0; i < size; i ++) { |
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 73f759eaa5a6..90fb2a541916 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -135,6 +135,7 @@ | |||
135 | static int nowayout = WATCHDOG_NOWAYOUT; | 135 | static int nowayout = WATCHDOG_NOWAYOUT; |
136 | 136 | ||
137 | static ipmi_user_t watchdog_user = NULL; | 137 | static ipmi_user_t watchdog_user = NULL; |
138 | static int watchdog_ifnum; | ||
138 | 139 | ||
139 | /* Default the timeout to 10 seconds. */ | 140 | /* Default the timeout to 10 seconds. */ |
140 | static int timeout = 10; | 141 | static int timeout = 10; |
@@ -161,6 +162,8 @@ static struct fasync_struct *fasync_q = NULL; | |||
161 | static char pretimeout_since_last_heartbeat = 0; | 162 | static char pretimeout_since_last_heartbeat = 0; |
162 | static char expect_close; | 163 | static char expect_close; |
163 | 164 | ||
165 | static int ifnum_to_use = -1; | ||
166 | |||
164 | static DECLARE_RWSEM(register_sem); | 167 | static DECLARE_RWSEM(register_sem); |
165 | 168 | ||
166 | /* Parameters to ipmi_set_timeout */ | 169 | /* Parameters to ipmi_set_timeout */ |
@@ -169,6 +172,8 @@ static DECLARE_RWSEM(register_sem); | |||
169 | #define IPMI_SET_TIMEOUT_FORCE_HB 2 | 172 | #define IPMI_SET_TIMEOUT_FORCE_HB 2 |
170 | 173 | ||
171 | static int ipmi_set_timeout(int do_heartbeat); | 174 | static int ipmi_set_timeout(int do_heartbeat); |
175 | static void ipmi_register_watchdog(int ipmi_intf); | ||
176 | static void ipmi_unregister_watchdog(int ipmi_intf); | ||
172 | 177 | ||
173 | /* If true, the driver will start running as soon as it is configured | 178 | /* If true, the driver will start running as soon as it is configured |
174 | and ready. */ | 179 | and ready. */ |
@@ -245,6 +250,26 @@ static int get_param_str(char *buffer, struct kernel_param *kp) | |||
245 | return strlen(buffer); | 250 | return strlen(buffer); |
246 | } | 251 | } |
247 | 252 | ||
253 | |||
254 | static int set_param_wdog_ifnum(const char *val, struct kernel_param *kp) | ||
255 | { | ||
256 | int rv = param_set_int(val, kp); | ||
257 | if (rv) | ||
258 | return rv; | ||
259 | if ((ifnum_to_use < 0) || (ifnum_to_use == watchdog_ifnum)) | ||
260 | return 0; | ||
261 | |||
262 | ipmi_unregister_watchdog(watchdog_ifnum); | ||
263 | ipmi_register_watchdog(ifnum_to_use); | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | module_param_call(ifnum_to_use, set_param_wdog_ifnum, get_param_int, | ||
268 | &ifnum_to_use, 0644); | ||
269 | MODULE_PARM_DESC(ifnum_to_use, "The interface number to use for the watchdog " | ||
270 | "timer. Setting to -1 defaults to the first registered " | ||
271 | "interface"); | ||
272 | |||
248 | module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644); | 273 | module_param_call(timeout, set_param_int, get_param_int, &timeout, 0644); |
249 | MODULE_PARM_DESC(timeout, "Timeout value in seconds."); | 274 | MODULE_PARM_DESC(timeout, "Timeout value in seconds."); |
250 | 275 | ||
@@ -263,12 +288,13 @@ module_param_call(preop, set_param_str, get_param_str, preop_op, 0644); | |||
263 | MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " | 288 | MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: " |
264 | "preop_none, preop_panic, preop_give_data."); | 289 | "preop_none, preop_panic, preop_give_data."); |
265 | 290 | ||
266 | module_param(start_now, int, 0); | 291 | module_param(start_now, int, 0444); |
267 | MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as" | 292 | MODULE_PARM_DESC(start_now, "Set to 1 to start the watchdog as" |
268 | "soon as the driver is loaded."); | 293 | "soon as the driver is loaded."); |
269 | 294 | ||
270 | module_param(nowayout, int, 0644); | 295 | module_param(nowayout, int, 0644); |
271 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=CONFIG_WATCHDOG_NOWAYOUT)"); | 296 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " |
297 | "(default=CONFIG_WATCHDOG_NOWAYOUT)"); | ||
272 | 298 | ||
273 | /* Default state of the timer. */ | 299 | /* Default state of the timer. */ |
274 | static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE; | 300 | static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE; |
@@ -872,6 +898,11 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
872 | if (watchdog_user) | 898 | if (watchdog_user) |
873 | goto out; | 899 | goto out; |
874 | 900 | ||
901 | if ((ifnum_to_use >= 0) && (ifnum_to_use != ipmi_intf)) | ||
902 | goto out; | ||
903 | |||
904 | watchdog_ifnum = ipmi_intf; | ||
905 | |||
875 | rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &watchdog_user); | 906 | rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &watchdog_user); |
876 | if (rv < 0) { | 907 | if (rv < 0) { |
877 | printk(KERN_CRIT PFX "Unable to register with ipmi\n"); | 908 | printk(KERN_CRIT PFX "Unable to register with ipmi\n"); |
@@ -901,6 +932,39 @@ static void ipmi_register_watchdog(int ipmi_intf) | |||
901 | } | 932 | } |
902 | } | 933 | } |
903 | 934 | ||
935 | static void ipmi_unregister_watchdog(int ipmi_intf) | ||
936 | { | ||
937 | int rv; | ||
938 | |||
939 | down_write(®ister_sem); | ||
940 | |||
941 | if (!watchdog_user) | ||
942 | goto out; | ||
943 | |||
944 | if (watchdog_ifnum != ipmi_intf) | ||
945 | goto out; | ||
946 | |||
947 | /* Make sure no one can call us any more. */ | ||
948 | misc_deregister(&ipmi_wdog_miscdev); | ||
949 | |||
950 | /* Wait to make sure the message makes it out. The lower layer has | ||
951 | pointers to our buffers, we want to make sure they are done before | ||
952 | we release our memory. */ | ||
953 | while (atomic_read(&set_timeout_tofree)) | ||
954 | schedule_timeout_uninterruptible(1); | ||
955 | |||
956 | /* Disconnect from IPMI. */ | ||
957 | rv = ipmi_destroy_user(watchdog_user); | ||
958 | if (rv) { | ||
959 | printk(KERN_WARNING PFX "error unlinking from IPMI: %d\n", | ||
960 | rv); | ||
961 | } | ||
962 | watchdog_user = NULL; | ||
963 | |||
964 | out: | ||
965 | up_write(®ister_sem); | ||
966 | } | ||
967 | |||
904 | #ifdef HAVE_NMI_HANDLER | 968 | #ifdef HAVE_NMI_HANDLER |
905 | static int | 969 | static int |
906 | ipmi_nmi(void *dev_id, int cpu, int handled) | 970 | ipmi_nmi(void *dev_id, int cpu, int handled) |
@@ -1004,9 +1068,7 @@ static void ipmi_new_smi(int if_num, struct device *device) | |||
1004 | 1068 | ||
1005 | static void ipmi_smi_gone(int if_num) | 1069 | static void ipmi_smi_gone(int if_num) |
1006 | { | 1070 | { |
1007 | /* This can never be called, because once the watchdog is | 1071 | ipmi_unregister_watchdog(if_num); |
1008 | registered, the interface can't go away until the watchdog | ||
1009 | is unregistered. */ | ||
1010 | } | 1072 | } |
1011 | 1073 | ||
1012 | static struct ipmi_smi_watcher smi_watcher = | 1074 | static struct ipmi_smi_watcher smi_watcher = |
@@ -1148,30 +1210,32 @@ static int __init ipmi_wdog_init(void) | |||
1148 | 1210 | ||
1149 | check_parms(); | 1211 | check_parms(); |
1150 | 1212 | ||
1213 | register_reboot_notifier(&wdog_reboot_notifier); | ||
1214 | atomic_notifier_chain_register(&panic_notifier_list, | ||
1215 | &wdog_panic_notifier); | ||
1216 | |||
1151 | rv = ipmi_smi_watcher_register(&smi_watcher); | 1217 | rv = ipmi_smi_watcher_register(&smi_watcher); |
1152 | if (rv) { | 1218 | if (rv) { |
1153 | #ifdef HAVE_NMI_HANDLER | 1219 | #ifdef HAVE_NMI_HANDLER |
1154 | if (preaction_val == WDOG_PRETIMEOUT_NMI) | 1220 | if (preaction_val == WDOG_PRETIMEOUT_NMI) |
1155 | release_nmi(&ipmi_nmi_handler); | 1221 | release_nmi(&ipmi_nmi_handler); |
1156 | #endif | 1222 | #endif |
1223 | atomic_notifier_chain_unregister(&panic_notifier_list, | ||
1224 | &wdog_panic_notifier); | ||
1225 | unregister_reboot_notifier(&wdog_reboot_notifier); | ||
1157 | printk(KERN_WARNING PFX "can't register smi watcher\n"); | 1226 | printk(KERN_WARNING PFX "can't register smi watcher\n"); |
1158 | return rv; | 1227 | return rv; |
1159 | } | 1228 | } |
1160 | 1229 | ||
1161 | register_reboot_notifier(&wdog_reboot_notifier); | ||
1162 | atomic_notifier_chain_register(&panic_notifier_list, | ||
1163 | &wdog_panic_notifier); | ||
1164 | |||
1165 | printk(KERN_INFO PFX "driver initialized\n"); | 1230 | printk(KERN_INFO PFX "driver initialized\n"); |
1166 | 1231 | ||
1167 | return 0; | 1232 | return 0; |
1168 | } | 1233 | } |
1169 | 1234 | ||
1170 | static __exit void ipmi_unregister_watchdog(void) | 1235 | static void __exit ipmi_wdog_exit(void) |
1171 | { | 1236 | { |
1172 | int rv; | 1237 | ipmi_smi_watcher_unregister(&smi_watcher); |
1173 | 1238 | ipmi_unregister_watchdog(watchdog_ifnum); | |
1174 | down_write(®ister_sem); | ||
1175 | 1239 | ||
1176 | #ifdef HAVE_NMI_HANDLER | 1240 | #ifdef HAVE_NMI_HANDLER |
1177 | if (nmi_handler_registered) | 1241 | if (nmi_handler_registered) |
@@ -1179,37 +1243,8 @@ static __exit void ipmi_unregister_watchdog(void) | |||
1179 | #endif | 1243 | #endif |
1180 | 1244 | ||
1181 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1245 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1182 | &wdog_panic_notifier); | 1246 | &wdog_panic_notifier); |
1183 | unregister_reboot_notifier(&wdog_reboot_notifier); | 1247 | unregister_reboot_notifier(&wdog_reboot_notifier); |
1184 | |||
1185 | if (! watchdog_user) | ||
1186 | goto out; | ||
1187 | |||
1188 | /* Make sure no one can call us any more. */ | ||
1189 | misc_deregister(&ipmi_wdog_miscdev); | ||
1190 | |||
1191 | /* Wait to make sure the message makes it out. The lower layer has | ||
1192 | pointers to our buffers, we want to make sure they are done before | ||
1193 | we release our memory. */ | ||
1194 | while (atomic_read(&set_timeout_tofree)) | ||
1195 | schedule_timeout_uninterruptible(1); | ||
1196 | |||
1197 | /* Disconnect from IPMI. */ | ||
1198 | rv = ipmi_destroy_user(watchdog_user); | ||
1199 | if (rv) { | ||
1200 | printk(KERN_WARNING PFX "error unlinking from IPMI: %d\n", | ||
1201 | rv); | ||
1202 | } | ||
1203 | watchdog_user = NULL; | ||
1204 | |||
1205 | out: | ||
1206 | up_write(®ister_sem); | ||
1207 | } | ||
1208 | |||
1209 | static void __exit ipmi_wdog_exit(void) | ||
1210 | { | ||
1211 | ipmi_smi_watcher_unregister(&smi_watcher); | ||
1212 | ipmi_unregister_watchdog(); | ||
1213 | } | 1248 | } |
1214 | module_exit(ipmi_wdog_exit); | 1249 | module_exit(ipmi_wdog_exit); |
1215 | module_init(ipmi_wdog_init); | 1250 | module_init(ipmi_wdog_init); |
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c index 1637c1d9a4ba..5a747e685993 100644 --- a/drivers/char/isicom.c +++ b/drivers/char/isicom.c | |||
@@ -172,12 +172,14 @@ static struct pci_driver isicom_driver = { | |||
172 | static int prev_card = 3; /* start servicing isi_card[0] */ | 172 | static int prev_card = 3; /* start servicing isi_card[0] */ |
173 | static struct tty_driver *isicom_normal; | 173 | static struct tty_driver *isicom_normal; |
174 | 174 | ||
175 | static struct timer_list tx; | 175 | static DECLARE_COMPLETION(isi_timerdone); |
176 | static char re_schedule = 1; | 176 | static char re_schedule = 1; |
177 | 177 | ||
178 | static void isicom_tx(unsigned long _data); | 178 | static void isicom_tx(unsigned long _data); |
179 | static void isicom_start(struct tty_struct *tty); | 179 | static void isicom_start(struct tty_struct *tty); |
180 | 180 | ||
181 | static DEFINE_TIMER(tx, isicom_tx, 0, 0); | ||
182 | |||
181 | /* baud index mappings from linux defns to isi */ | 183 | /* baud index mappings from linux defns to isi */ |
182 | 184 | ||
183 | static signed char linuxb_to_isib[] = { | 185 | static signed char linuxb_to_isib[] = { |
@@ -193,9 +195,9 @@ struct isi_board { | |||
193 | unsigned short shift_count; | 195 | unsigned short shift_count; |
194 | struct isi_port * ports; | 196 | struct isi_port * ports; |
195 | signed char count; | 197 | signed char count; |
196 | unsigned char isa; | ||
197 | spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ | 198 | spinlock_t card_lock; /* Card wide lock 11/5/00 -sameer */ |
198 | unsigned long flags; | 199 | unsigned long flags; |
200 | unsigned int index; | ||
199 | }; | 201 | }; |
200 | 202 | ||
201 | struct isi_port { | 203 | struct isi_port { |
@@ -514,17 +516,11 @@ static void isicom_tx(unsigned long _data) | |||
514 | /* schedule another tx for hopefully in about 10ms */ | 516 | /* schedule another tx for hopefully in about 10ms */ |
515 | sched_again: | 517 | sched_again: |
516 | if (!re_schedule) { | 518 | if (!re_schedule) { |
517 | re_schedule = 2; | 519 | complete(&isi_timerdone); |
518 | return; | 520 | return; |
519 | } | 521 | } |
520 | 522 | ||
521 | init_timer(&tx); | 523 | mod_timer(&tx, jiffies + msecs_to_jiffies(10)); |
522 | tx.expires = jiffies + HZ/100; | ||
523 | tx.data = 0; | ||
524 | tx.function = isicom_tx; | ||
525 | add_timer(&tx); | ||
526 | |||
527 | return; | ||
528 | } | 524 | } |
529 | 525 | ||
530 | /* Interrupt handlers */ | 526 | /* Interrupt handlers */ |
@@ -562,14 +558,12 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
562 | base = card->base; | 558 | base = card->base; |
563 | spin_lock(&card->card_lock); | 559 | spin_lock(&card->card_lock); |
564 | 560 | ||
565 | if (card->isa == NO) { | 561 | /* |
566 | /* | 562 | * disable any interrupts from the PCI card and lower the |
567 | * disable any interrupts from the PCI card and lower the | 563 | * interrupt line |
568 | * interrupt line | 564 | */ |
569 | */ | 565 | outw(0x8000, base+0x04); |
570 | outw(0x8000, base+0x04); | 566 | ClearInterrupt(base); |
571 | ClearInterrupt(base); | ||
572 | } | ||
573 | 567 | ||
574 | inw(base); /* get the dummy word out */ | 568 | inw(base); /* get the dummy word out */ |
575 | header = inw(base); | 569 | header = inw(base); |
@@ -579,19 +573,13 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
579 | if (channel + 1 > card->port_count) { | 573 | if (channel + 1 > card->port_count) { |
580 | printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): " | 574 | printk(KERN_WARNING "ISICOM: isicom_interrupt(0x%lx): " |
581 | "%d(channel) > port_count.\n", base, channel+1); | 575 | "%d(channel) > port_count.\n", base, channel+1); |
582 | if (card->isa) | 576 | outw(0x0000, base+0x04); /* enable interrupts */ |
583 | ClearInterrupt(base); | ||
584 | else | ||
585 | outw(0x0000, base+0x04); /* enable interrupts */ | ||
586 | spin_unlock(&card->card_lock); | 577 | spin_unlock(&card->card_lock); |
587 | return IRQ_HANDLED; | 578 | return IRQ_HANDLED; |
588 | } | 579 | } |
589 | port = card->ports + channel; | 580 | port = card->ports + channel; |
590 | if (!(port->flags & ASYNC_INITIALIZED)) { | 581 | if (!(port->flags & ASYNC_INITIALIZED)) { |
591 | if (card->isa) | 582 | outw(0x0000, base+0x04); /* enable interrupts */ |
592 | ClearInterrupt(base); | ||
593 | else | ||
594 | outw(0x0000, base+0x04); /* enable interrupts */ | ||
595 | return IRQ_HANDLED; | 583 | return IRQ_HANDLED; |
596 | } | 584 | } |
597 | 585 | ||
@@ -604,10 +592,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
604 | } | 592 | } |
605 | if (byte_count & 0x01) | 593 | if (byte_count & 0x01) |
606 | inw(base); | 594 | inw(base); |
607 | if (card->isa == YES) | 595 | outw(0x0000, base+0x04); /* enable interrupts */ |
608 | ClearInterrupt(base); | ||
609 | else | ||
610 | outw(0x0000, base+0x04); /* enable interrupts */ | ||
611 | spin_unlock(&card->card_lock); | 596 | spin_unlock(&card->card_lock); |
612 | return IRQ_HANDLED; | 597 | return IRQ_HANDLED; |
613 | } | 598 | } |
@@ -708,10 +693,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
708 | } | 693 | } |
709 | tty_flip_buffer_push(tty); | 694 | tty_flip_buffer_push(tty); |
710 | } | 695 | } |
711 | if (card->isa == YES) | 696 | outw(0x0000, base+0x04); /* enable interrupts */ |
712 | ClearInterrupt(base); | ||
713 | else | ||
714 | outw(0x0000, base+0x04); /* enable interrupts */ | ||
715 | 697 | ||
716 | return IRQ_HANDLED; | 698 | return IRQ_HANDLED; |
717 | } | 699 | } |
@@ -964,8 +946,8 @@ static int isicom_open(struct tty_struct *tty, struct file *filp) | |||
964 | { | 946 | { |
965 | struct isi_port *port; | 947 | struct isi_port *port; |
966 | struct isi_board *card; | 948 | struct isi_board *card; |
967 | unsigned int line, board; | 949 | unsigned int board; |
968 | int error; | 950 | int error, line; |
969 | 951 | ||
970 | line = tty->index; | 952 | line = tty->index; |
971 | if (line < 0 || line > PORT_COUNT-1) | 953 | if (line < 0 || line > PORT_COUNT-1) |
@@ -1399,7 +1381,7 @@ static int isicom_ioctl(struct tty_struct *tty, struct file *filp, | |||
1399 | 1381 | ||
1400 | /* set_termios et all */ | 1382 | /* set_termios et all */ |
1401 | static void isicom_set_termios(struct tty_struct *tty, | 1383 | static void isicom_set_termios(struct tty_struct *tty, |
1402 | struct termios *old_termios) | 1384 | struct ktermios *old_termios) |
1403 | { | 1385 | { |
1404 | struct isi_port *port = tty->driver_data; | 1386 | struct isi_port *port = tty->driver_data; |
1405 | 1387 | ||
@@ -1520,37 +1502,6 @@ static void isicom_flush_buffer(struct tty_struct *tty) | |||
1520 | * Driver init and deinit functions | 1502 | * Driver init and deinit functions |
1521 | */ | 1503 | */ |
1522 | 1504 | ||
1523 | static int __devinit isicom_register_ioregion(struct pci_dev *pdev, | ||
1524 | const unsigned int index) | ||
1525 | { | ||
1526 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1527 | |||
1528 | if (!board->base) | ||
1529 | return -EINVAL; | ||
1530 | |||
1531 | if (!request_region(board->base, 16, ISICOM_NAME)) { | ||
1532 | dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " | ||
1533 | "will be disabled.\n", board->base, board->base + 15, | ||
1534 | index + 1); | ||
1535 | return -EBUSY; | ||
1536 | } | ||
1537 | |||
1538 | return 0; | ||
1539 | } | ||
1540 | |||
1541 | static void isicom_unregister_ioregion(struct pci_dev *pdev) | ||
1542 | { | ||
1543 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1544 | |||
1545 | if (!board->base) | ||
1546 | return; | ||
1547 | |||
1548 | release_region(board->base, 16); | ||
1549 | dev_dbg(&pdev->dev, "I/O Region 0x%lx-0x%lx released.\n", | ||
1550 | board->base, board->base + 15); | ||
1551 | board->base = 0; | ||
1552 | } | ||
1553 | |||
1554 | static const struct tty_operations isicom_ops = { | 1505 | static const struct tty_operations isicom_ops = { |
1555 | .open = isicom_open, | 1506 | .open = isicom_open, |
1556 | .close = isicom_close, | 1507 | .close = isicom_close, |
@@ -1571,70 +1522,6 @@ static const struct tty_operations isicom_ops = { | |||
1571 | .tiocmset = isicom_tiocmset, | 1522 | .tiocmset = isicom_tiocmset, |
1572 | }; | 1523 | }; |
1573 | 1524 | ||
1574 | static int __devinit isicom_register_tty_driver(void) | ||
1575 | { | ||
1576 | int error = -ENOMEM; | ||
1577 | |||
1578 | /* tty driver structure initialization */ | ||
1579 | isicom_normal = alloc_tty_driver(PORT_COUNT); | ||
1580 | if (!isicom_normal) | ||
1581 | goto end; | ||
1582 | |||
1583 | isicom_normal->owner = THIS_MODULE; | ||
1584 | isicom_normal->name = "ttyM"; | ||
1585 | isicom_normal->major = ISICOM_NMAJOR; | ||
1586 | isicom_normal->minor_start = 0; | ||
1587 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; | ||
1588 | isicom_normal->subtype = SERIAL_TYPE_NORMAL; | ||
1589 | isicom_normal->init_termios = tty_std_termios; | ||
1590 | isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | | ||
1591 | CLOCAL; | ||
1592 | isicom_normal->flags = TTY_DRIVER_REAL_RAW; | ||
1593 | tty_set_operations(isicom_normal, &isicom_ops); | ||
1594 | |||
1595 | if ((error = tty_register_driver(isicom_normal))) { | ||
1596 | pr_dbg("Couldn't register the dialin driver, error=%d\n", | ||
1597 | error); | ||
1598 | put_tty_driver(isicom_normal); | ||
1599 | } | ||
1600 | end: | ||
1601 | return error; | ||
1602 | } | ||
1603 | |||
1604 | static void isicom_unregister_tty_driver(void) | ||
1605 | { | ||
1606 | int error; | ||
1607 | |||
1608 | if ((error = tty_unregister_driver(isicom_normal))) | ||
1609 | pr_dbg("couldn't unregister normal driver, error=%d.\n", error); | ||
1610 | |||
1611 | put_tty_driver(isicom_normal); | ||
1612 | } | ||
1613 | |||
1614 | static int __devinit isicom_register_isr(struct pci_dev *pdev, | ||
1615 | const unsigned int index) | ||
1616 | { | ||
1617 | struct isi_board *board = pci_get_drvdata(pdev); | ||
1618 | unsigned long irqflags = IRQF_DISABLED; | ||
1619 | int retval = -EINVAL; | ||
1620 | |||
1621 | if (!board->base) | ||
1622 | goto end; | ||
1623 | |||
1624 | if (board->isa == NO) | ||
1625 | irqflags |= IRQF_SHARED; | ||
1626 | |||
1627 | retval = request_irq(board->irq, isicom_interrupt, irqflags, | ||
1628 | ISICOM_NAME, board); | ||
1629 | if (retval < 0) | ||
1630 | dev_warn(&pdev->dev, "Could not install handler at Irq %d. " | ||
1631 | "Card%d will be disabled.\n", board->irq, index + 1); | ||
1632 | else | ||
1633 | retval = 0; | ||
1634 | end: | ||
1635 | return retval; | ||
1636 | } | ||
1637 | |||
1638 | static int __devinit reset_card(struct pci_dev *pdev, | 1525 | static int __devinit reset_card(struct pci_dev *pdev, |
1639 | const unsigned int card, unsigned int *signature) | 1526 | const unsigned int card, unsigned int *signature) |
1640 | { | 1527 | { |
@@ -1656,36 +1543,23 @@ static int __devinit reset_card(struct pci_dev *pdev, | |||
1656 | 1543 | ||
1657 | *signature = inw(base + 0x4) & 0xff; | 1544 | *signature = inw(base + 0x4) & 0xff; |
1658 | 1545 | ||
1659 | if (board->isa == YES) { | 1546 | portcount = inw(base + 0x2); |
1660 | if (!(inw(base + 0xe) & 0x1) || (inw(base + 0x2))) { | 1547 | if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) && |
1661 | dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", | 1548 | (portcount != 4) && (portcount != 8))) { |
1662 | inw(base + 0x2), inw(base + 0xe)); | 1549 | dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", |
1663 | dev_err(&pdev->dev, "ISILoad:ISA Card%d reset failure " | 1550 | inw(base + 0x2), inw(base + 0xe)); |
1664 | "(Possible bad I/O Port Address 0x%lx).\n", | 1551 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure " |
1665 | card + 1, base); | 1552 | "(Possible bad I/O Port Address 0x%lx).\n", |
1666 | retval = -EIO; | 1553 | card + 1, base); |
1667 | goto end; | 1554 | retval = -EIO; |
1668 | } | 1555 | goto end; |
1669 | } else { | ||
1670 | portcount = inw(base + 0x2); | ||
1671 | if (!(inw(base + 0xe) & 0x1) || ((portcount != 0) && | ||
1672 | (portcount != 4) && (portcount != 8))) { | ||
1673 | dev_dbg(&pdev->dev, "base+0x2=0x%lx, base+0xe=0x%lx\n", | ||
1674 | inw(base + 0x2), inw(base + 0xe)); | ||
1675 | dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure " | ||
1676 | "(Possible bad I/O Port Address 0x%lx).\n", | ||
1677 | card + 1, base); | ||
1678 | retval = -EIO; | ||
1679 | goto end; | ||
1680 | } | ||
1681 | } | 1556 | } |
1682 | 1557 | ||
1683 | switch (*signature) { | 1558 | switch (*signature) { |
1684 | case 0xa5: | 1559 | case 0xa5: |
1685 | case 0xbb: | 1560 | case 0xbb: |
1686 | case 0xdd: | 1561 | case 0xdd: |
1687 | board->port_count = (board->isa == NO && portcount == 4) ? 4 : | 1562 | board->port_count = (portcount == 4) ? 4 : 8; |
1688 | 8; | ||
1689 | board->shift_count = 12; | 1563 | board->shift_count = 12; |
1690 | break; | 1564 | break; |
1691 | case 0xcc: | 1565 | case 0xcc: |
@@ -1831,6 +1705,11 @@ static int __devinit load_firmware(struct pci_dev *pdev, | |||
1831 | } | 1705 | } |
1832 | 1706 | ||
1833 | data = kmalloc(word_count * 2, GFP_KERNEL); | 1707 | data = kmalloc(word_count * 2, GFP_KERNEL); |
1708 | if (data == NULL) { | ||
1709 | dev_err(&pdev->dev, "Card%d, firmware upload " | ||
1710 | "failed, not enough memory\n", index + 1); | ||
1711 | goto errrelfw; | ||
1712 | } | ||
1834 | inw(base); | 1713 | inw(base); |
1835 | insw(base, data, word_count); | 1714 | insw(base, data, word_count); |
1836 | InterruptTheCard(base); | 1715 | InterruptTheCard(base); |
@@ -1879,8 +1758,6 @@ end: | |||
1879 | /* | 1758 | /* |
1880 | * Insmod can set static symbols so keep these static | 1759 | * Insmod can set static symbols so keep these static |
1881 | */ | 1760 | */ |
1882 | static int io[4]; | ||
1883 | static int irq[4]; | ||
1884 | static int card; | 1761 | static int card; |
1885 | 1762 | ||
1886 | static int __devinit isicom_probe(struct pci_dev *pdev, | 1763 | static int __devinit isicom_probe(struct pci_dev *pdev, |
@@ -1906,20 +1783,29 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1906 | break; | 1783 | break; |
1907 | } | 1784 | } |
1908 | 1785 | ||
1786 | board->index = index; | ||
1909 | board->base = ioaddr; | 1787 | board->base = ioaddr; |
1910 | board->irq = pciirq; | 1788 | board->irq = pciirq; |
1911 | board->isa = NO; | ||
1912 | card++; | 1789 | card++; |
1913 | 1790 | ||
1914 | pci_set_drvdata(pdev, board); | 1791 | pci_set_drvdata(pdev, board); |
1915 | 1792 | ||
1916 | retval = isicom_register_ioregion(pdev, index); | 1793 | retval = pci_request_region(pdev, 3, ISICOM_NAME); |
1917 | if (retval < 0) | 1794 | if (retval) { |
1795 | dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d " | ||
1796 | "will be disabled.\n", board->base, board->base + 15, | ||
1797 | index + 1); | ||
1798 | retval = -EBUSY; | ||
1918 | goto err; | 1799 | goto err; |
1800 | } | ||
1919 | 1801 | ||
1920 | retval = isicom_register_isr(pdev, index); | 1802 | retval = request_irq(board->irq, isicom_interrupt, |
1921 | if (retval < 0) | 1803 | IRQF_SHARED | IRQF_DISABLED, ISICOM_NAME, board); |
1804 | if (retval < 0) { | ||
1805 | dev_err(&pdev->dev, "Could not install handler at Irq %d. " | ||
1806 | "Card%d will be disabled.\n", board->irq, index + 1); | ||
1922 | goto errunrr; | 1807 | goto errunrr; |
1808 | } | ||
1923 | 1809 | ||
1924 | retval = reset_card(pdev, index, &signature); | 1810 | retval = reset_card(pdev, index, &signature); |
1925 | if (retval < 0) | 1811 | if (retval < 0) |
@@ -1929,12 +1815,16 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1929 | if (retval < 0) | 1815 | if (retval < 0) |
1930 | goto errunri; | 1816 | goto errunri; |
1931 | 1817 | ||
1818 | for (index = 0; index < board->port_count; index++) | ||
1819 | tty_register_device(isicom_normal, board->index * 16 + index, | ||
1820 | &pdev->dev); | ||
1821 | |||
1932 | return 0; | 1822 | return 0; |
1933 | 1823 | ||
1934 | errunri: | 1824 | errunri: |
1935 | free_irq(board->irq, board); | 1825 | free_irq(board->irq, board); |
1936 | errunrr: | 1826 | errunrr: |
1937 | isicom_unregister_ioregion(pdev); | 1827 | pci_release_region(pdev, 3); |
1938 | err: | 1828 | err: |
1939 | board->base = 0; | 1829 | board->base = 0; |
1940 | return retval; | 1830 | return retval; |
@@ -1943,18 +1833,21 @@ err: | |||
1943 | static void __devexit isicom_remove(struct pci_dev *pdev) | 1833 | static void __devexit isicom_remove(struct pci_dev *pdev) |
1944 | { | 1834 | { |
1945 | struct isi_board *board = pci_get_drvdata(pdev); | 1835 | struct isi_board *board = pci_get_drvdata(pdev); |
1836 | unsigned int i; | ||
1837 | |||
1838 | for (i = 0; i < board->port_count; i++) | ||
1839 | tty_unregister_device(isicom_normal, board->index * 16 + i); | ||
1946 | 1840 | ||
1947 | free_irq(board->irq, board); | 1841 | free_irq(board->irq, board); |
1948 | isicom_unregister_ioregion(pdev); | 1842 | pci_release_region(pdev, 3); |
1949 | } | 1843 | } |
1950 | 1844 | ||
1951 | static int __devinit isicom_setup(void) | 1845 | static int __init isicom_init(void) |
1952 | { | 1846 | { |
1953 | int retval, idx, channel; | 1847 | int retval, idx, channel; |
1954 | struct isi_port *port; | 1848 | struct isi_port *port; |
1955 | 1849 | ||
1956 | card = 0; | 1850 | card = 0; |
1957 | memset(isi_ports, 0, sizeof(isi_ports)); | ||
1958 | 1851 | ||
1959 | for(idx = 0; idx < BOARD_COUNT; idx++) { | 1852 | for(idx = 0; idx < BOARD_COUNT; idx++) { |
1960 | port = &isi_ports[idx * 16]; | 1853 | port = &isi_ports[idx * 16]; |
@@ -1975,66 +1868,65 @@ static int __devinit isicom_setup(void) | |||
1975 | } | 1868 | } |
1976 | isi_card[idx].base = 0; | 1869 | isi_card[idx].base = 0; |
1977 | isi_card[idx].irq = 0; | 1870 | isi_card[idx].irq = 0; |
1978 | |||
1979 | if (!io[idx]) | ||
1980 | continue; | ||
1981 | |||
1982 | if (irq[idx] == 2 || irq[idx] == 3 || irq[idx] == 4 || | ||
1983 | irq[idx] == 5 || irq[idx] == 7 || | ||
1984 | irq[idx] == 10 || irq[idx] == 11 || | ||
1985 | irq[idx] == 12 || irq[idx] == 15) { | ||
1986 | printk(KERN_ERR "ISICOM: ISA not supported yet.\n"); | ||
1987 | retval = -EINVAL; | ||
1988 | goto error; | ||
1989 | } else | ||
1990 | printk(KERN_ERR "ISICOM: Irq %d unsupported. " | ||
1991 | "Disabling Card%d...\n", irq[idx], idx + 1); | ||
1992 | } | 1871 | } |
1993 | 1872 | ||
1994 | retval = isicom_register_tty_driver(); | 1873 | /* tty driver structure initialization */ |
1995 | if (retval < 0) | 1874 | isicom_normal = alloc_tty_driver(PORT_COUNT); |
1875 | if (!isicom_normal) { | ||
1876 | retval = -ENOMEM; | ||
1996 | goto error; | 1877 | goto error; |
1878 | } | ||
1879 | |||
1880 | isicom_normal->owner = THIS_MODULE; | ||
1881 | isicom_normal->name = "ttyM"; | ||
1882 | isicom_normal->major = ISICOM_NMAJOR; | ||
1883 | isicom_normal->minor_start = 0; | ||
1884 | isicom_normal->type = TTY_DRIVER_TYPE_SERIAL; | ||
1885 | isicom_normal->subtype = SERIAL_TYPE_NORMAL; | ||
1886 | isicom_normal->init_termios = tty_std_termios; | ||
1887 | isicom_normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | | ||
1888 | CLOCAL; | ||
1889 | isicom_normal->flags = TTY_DRIVER_REAL_RAW | | ||
1890 | TTY_DRIVER_DYNAMIC_DEV; | ||
1891 | tty_set_operations(isicom_normal, &isicom_ops); | ||
1892 | |||
1893 | retval = tty_register_driver(isicom_normal); | ||
1894 | if (retval) { | ||
1895 | pr_dbg("Couldn't register the dialin driver\n"); | ||
1896 | goto err_puttty; | ||
1897 | } | ||
1997 | 1898 | ||
1998 | retval = pci_register_driver(&isicom_driver); | 1899 | retval = pci_register_driver(&isicom_driver); |
1999 | if (retval < 0) { | 1900 | if (retval < 0) { |
2000 | printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); | 1901 | printk(KERN_ERR "ISICOM: Unable to register pci driver.\n"); |
2001 | goto errtty; | 1902 | goto err_unrtty; |
2002 | } | 1903 | } |
2003 | 1904 | ||
2004 | init_timer(&tx); | 1905 | mod_timer(&tx, jiffies + 1); |
2005 | tx.expires = jiffies + 1; | ||
2006 | tx.data = 0; | ||
2007 | tx.function = isicom_tx; | ||
2008 | re_schedule = 1; | ||
2009 | add_timer(&tx); | ||
2010 | 1906 | ||
2011 | return 0; | 1907 | return 0; |
2012 | errtty: | 1908 | err_unrtty: |
2013 | isicom_unregister_tty_driver(); | 1909 | tty_unregister_driver(isicom_normal); |
1910 | err_puttty: | ||
1911 | put_tty_driver(isicom_normal); | ||
2014 | error: | 1912 | error: |
2015 | return retval; | 1913 | return retval; |
2016 | } | 1914 | } |
2017 | 1915 | ||
2018 | static void __exit isicom_exit(void) | 1916 | static void __exit isicom_exit(void) |
2019 | { | 1917 | { |
2020 | unsigned int index = 0; | ||
2021 | |||
2022 | re_schedule = 0; | 1918 | re_schedule = 0; |
2023 | 1919 | ||
2024 | while (re_schedule != 2 && index++ < 100) | 1920 | wait_for_completion_timeout(&isi_timerdone, HZ); |
2025 | msleep(10); | ||
2026 | 1921 | ||
2027 | pci_unregister_driver(&isicom_driver); | 1922 | pci_unregister_driver(&isicom_driver); |
2028 | isicom_unregister_tty_driver(); | 1923 | tty_unregister_driver(isicom_normal); |
1924 | put_tty_driver(isicom_normal); | ||
2029 | } | 1925 | } |
2030 | 1926 | ||
2031 | module_init(isicom_setup); | 1927 | module_init(isicom_init); |
2032 | module_exit(isicom_exit); | 1928 | module_exit(isicom_exit); |
2033 | 1929 | ||
2034 | MODULE_AUTHOR("MultiTech"); | 1930 | MODULE_AUTHOR("MultiTech"); |
2035 | MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); | 1931 | MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech"); |
2036 | MODULE_LICENSE("GPL"); | 1932 | MODULE_LICENSE("GPL"); |
2037 | module_param_array(io, int, NULL, 0); | ||
2038 | MODULE_PARM_DESC(io, "I/O ports for the cards"); | ||
2039 | module_param_array(irq, int, NULL, 0); | ||
2040 | MODULE_PARM_DESC(irq, "Interrupts for the cards"); | ||
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c index bd9195e17956..68645d351873 100644 --- a/drivers/char/istallion.c +++ b/drivers/char/istallion.c | |||
@@ -14,14 +14,6 @@ | |||
14 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
15 | * (at your option) any later version. | 15 | * (at your option) any later version. |
16 | * | 16 | * |
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | 17 | */ |
26 | 18 | ||
27 | /*****************************************************************************/ | 19 | /*****************************************************************************/ |
@@ -41,6 +33,7 @@ | |||
41 | #include <linux/device.h> | 33 | #include <linux/device.h> |
42 | #include <linux/wait.h> | 34 | #include <linux/wait.h> |
43 | #include <linux/eisa.h> | 35 | #include <linux/eisa.h> |
36 | #include <linux/ctype.h> | ||
44 | 37 | ||
45 | #include <asm/io.h> | 38 | #include <asm/io.h> |
46 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
@@ -61,21 +54,10 @@ | |||
61 | #define BRD_BRUMBY4 2 | 54 | #define BRD_BRUMBY4 2 |
62 | #define BRD_ONBOARD2 3 | 55 | #define BRD_ONBOARD2 3 |
63 | #define BRD_ONBOARD 4 | 56 | #define BRD_ONBOARD 4 |
64 | #define BRD_BRUMBY8 5 | ||
65 | #define BRD_BRUMBY16 6 | ||
66 | #define BRD_ONBOARDE 7 | 57 | #define BRD_ONBOARDE 7 |
67 | #define BRD_ONBOARD32 9 | ||
68 | #define BRD_ONBOARD2_32 10 | ||
69 | #define BRD_ONBOARDRS 11 | ||
70 | #define BRD_EASYIO 20 | ||
71 | #define BRD_ECH 21 | ||
72 | #define BRD_ECHMC 22 | ||
73 | #define BRD_ECP 23 | 58 | #define BRD_ECP 23 |
74 | #define BRD_ECPE 24 | 59 | #define BRD_ECPE 24 |
75 | #define BRD_ECPMC 25 | 60 | #define BRD_ECPMC 25 |
76 | #define BRD_ECHPCI 26 | ||
77 | #define BRD_ECH64PCI 27 | ||
78 | #define BRD_EASYIOPCI 28 | ||
79 | #define BRD_ECPPCI 29 | 61 | #define BRD_ECPPCI 29 |
80 | 62 | ||
81 | #define BRD_BRUMBY BRD_BRUMBY4 | 63 | #define BRD_BRUMBY BRD_BRUMBY4 |
@@ -119,20 +101,16 @@ | |||
119 | * interrupt is required. | 101 | * interrupt is required. |
120 | */ | 102 | */ |
121 | 103 | ||
122 | typedef struct { | 104 | struct stlconf { |
123 | int brdtype; | 105 | int brdtype; |
124 | int ioaddr1; | 106 | int ioaddr1; |
125 | int ioaddr2; | 107 | int ioaddr2; |
126 | unsigned long memaddr; | 108 | unsigned long memaddr; |
127 | int irq; | 109 | int irq; |
128 | int irqtype; | 110 | int irqtype; |
129 | } stlconf_t; | ||
130 | |||
131 | static stlconf_t stli_brdconf[] = { | ||
132 | /*{ BRD_ECP, 0x2a0, 0, 0xcc000, 0, 0 },*/ | ||
133 | }; | 111 | }; |
134 | 112 | ||
135 | static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); | 113 | static unsigned int stli_nrbrds; |
136 | 114 | ||
137 | /* stli_lock must NOT be taken holding brd_lock */ | 115 | /* stli_lock must NOT be taken holding brd_lock */ |
138 | static spinlock_t stli_lock; /* TTY logic lock */ | 116 | static spinlock_t stli_lock; /* TTY logic lock */ |
@@ -194,9 +172,11 @@ static struct tty_struct *stli_txcooktty; | |||
194 | * with this termios initially. Basically all it defines is a raw port | 172 | * with this termios initially. Basically all it defines is a raw port |
195 | * at 9600 baud, 8 data bits, no parity, 1 stop bit. | 173 | * at 9600 baud, 8 data bits, no parity, 1 stop bit. |
196 | */ | 174 | */ |
197 | static struct termios stli_deftermios = { | 175 | static struct ktermios stli_deftermios = { |
198 | .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), | 176 | .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), |
199 | .c_cc = INIT_C_CC, | 177 | .c_cc = INIT_C_CC, |
178 | .c_ispeed = 9600, | ||
179 | .c_ospeed = 9600, | ||
200 | }; | 180 | }; |
201 | 181 | ||
202 | /* | 182 | /* |
@@ -205,13 +185,12 @@ static struct termios stli_deftermios = { | |||
205 | */ | 185 | */ |
206 | static comstats_t stli_comstats; | 186 | static comstats_t stli_comstats; |
207 | static combrd_t stli_brdstats; | 187 | static combrd_t stli_brdstats; |
208 | static asystats_t stli_cdkstats; | 188 | static struct asystats stli_cdkstats; |
209 | static stlibrd_t stli_dummybrd; | ||
210 | static stliport_t stli_dummyport; | ||
211 | 189 | ||
212 | /*****************************************************************************/ | 190 | /*****************************************************************************/ |
213 | 191 | ||
214 | static stlibrd_t *stli_brds[STL_MAXBRDS]; | 192 | static DEFINE_MUTEX(stli_brdslock); |
193 | static struct stlibrd *stli_brds[STL_MAXBRDS]; | ||
215 | 194 | ||
216 | static int stli_shared; | 195 | static int stli_shared; |
217 | 196 | ||
@@ -223,6 +202,7 @@ static int stli_shared; | |||
223 | */ | 202 | */ |
224 | #define BST_FOUND 0x1 | 203 | #define BST_FOUND 0x1 |
225 | #define BST_STARTED 0x2 | 204 | #define BST_STARTED 0x2 |
205 | #define BST_PROBED 0x4 | ||
226 | 206 | ||
227 | /* | 207 | /* |
228 | * Define the set of port state flags. These are marked for internal | 208 | * Define the set of port state flags. These are marked for internal |
@@ -255,18 +235,18 @@ static char *stli_brdnames[] = { | |||
255 | "Brumby", | 235 | "Brumby", |
256 | "Brumby", | 236 | "Brumby", |
257 | "ONboard-EI", | 237 | "ONboard-EI", |
258 | (char *) NULL, | 238 | NULL, |
259 | "ONboard", | 239 | "ONboard", |
260 | "ONboard-MC", | 240 | "ONboard-MC", |
261 | "ONboard-MC", | 241 | "ONboard-MC", |
262 | (char *) NULL, | 242 | NULL, |
263 | (char *) NULL, | 243 | NULL, |
264 | (char *) NULL, | 244 | NULL, |
265 | (char *) NULL, | 245 | NULL, |
266 | (char *) NULL, | 246 | NULL, |
267 | (char *) NULL, | 247 | NULL, |
268 | (char *) NULL, | 248 | NULL, |
269 | (char *) NULL, | 249 | NULL, |
270 | "EasyIO", | 250 | "EasyIO", |
271 | "EC8/32-AT", | 251 | "EC8/32-AT", |
272 | "EC8/32-MC", | 252 | "EC8/32-MC", |
@@ -304,12 +284,10 @@ static char **stli_brdsp[] = { | |||
304 | * parse any module arguments. | 284 | * parse any module arguments. |
305 | */ | 285 | */ |
306 | 286 | ||
307 | typedef struct stlibrdtype { | 287 | static struct stlibrdtype { |
308 | char *name; | 288 | char *name; |
309 | int type; | 289 | int type; |
310 | } stlibrdtype_t; | 290 | } stli_brdstr[] = { |
311 | |||
312 | static stlibrdtype_t stli_brdstr[] = { | ||
313 | { "stallion", BRD_STALLION }, | 291 | { "stallion", BRD_STALLION }, |
314 | { "1", BRD_STALLION }, | 292 | { "1", BRD_STALLION }, |
315 | { "brumby", BRD_BRUMBY }, | 293 | { "brumby", BRD_BRUMBY }, |
@@ -379,6 +357,7 @@ MODULE_PARM_DESC(board2, "Board 2 config -> name[,ioaddr[,memaddr]"); | |||
379 | module_param_array(board3, charp, NULL, 0); | 357 | module_param_array(board3, charp, NULL, 0); |
380 | MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]"); | 358 | MODULE_PARM_DESC(board3, "Board 3 config -> name[,ioaddr[,memaddr]"); |
381 | 359 | ||
360 | #if STLI_EISAPROBE != 0 | ||
382 | /* | 361 | /* |
383 | * Set up a default memory address table for EISA board probing. | 362 | * Set up a default memory address table for EISA board probing. |
384 | * The default addresses are all bellow 1Mbyte, which has to be the | 363 | * The default addresses are all bellow 1Mbyte, which has to be the |
@@ -396,14 +375,11 @@ static unsigned long stli_eisamemprobeaddrs[] = { | |||
396 | }; | 375 | }; |
397 | 376 | ||
398 | static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); | 377 | static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); |
378 | #endif | ||
399 | 379 | ||
400 | /* | 380 | /* |
401 | * Define the Stallion PCI vendor and device IDs. | 381 | * Define the Stallion PCI vendor and device IDs. |
402 | */ | 382 | */ |
403 | #ifdef CONFIG_PCI | ||
404 | #ifndef PCI_VENDOR_ID_STALLION | ||
405 | #define PCI_VENDOR_ID_STALLION 0x124d | ||
406 | #endif | ||
407 | #ifndef PCI_DEVICE_ID_ECRA | 383 | #ifndef PCI_DEVICE_ID_ECRA |
408 | #define PCI_DEVICE_ID_ECRA 0x0004 | 384 | #define PCI_DEVICE_ID_ECRA 0x0004 |
409 | #endif | 385 | #endif |
@@ -414,7 +390,7 @@ static struct pci_device_id istallion_pci_tbl[] = { | |||
414 | }; | 390 | }; |
415 | MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); | 391 | MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); |
416 | 392 | ||
417 | #endif /* CONFIG_PCI */ | 393 | static struct pci_driver stli_pcidriver; |
418 | 394 | ||
419 | /*****************************************************************************/ | 395 | /*****************************************************************************/ |
420 | 396 | ||
@@ -615,22 +591,10 @@ MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); | |||
615 | /*****************************************************************************/ | 591 | /*****************************************************************************/ |
616 | 592 | ||
617 | /* | 593 | /* |
618 | * Define some handy local macros... | ||
619 | */ | ||
620 | #undef MIN | ||
621 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b)) | ||
622 | |||
623 | #undef TOLOWER | ||
624 | #define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x)) | ||
625 | |||
626 | /*****************************************************************************/ | ||
627 | |||
628 | /* | ||
629 | * Prototype all functions in this driver! | 594 | * Prototype all functions in this driver! |
630 | */ | 595 | */ |
631 | 596 | ||
632 | static int stli_parsebrd(stlconf_t *confp, char **argp); | 597 | static int stli_parsebrd(struct stlconf *confp, char **argp); |
633 | static int stli_init(void); | ||
634 | static int stli_open(struct tty_struct *tty, struct file *filp); | 598 | static int stli_open(struct tty_struct *tty, struct file *filp); |
635 | static void stli_close(struct tty_struct *tty, struct file *filp); | 599 | static void stli_close(struct tty_struct *tty, struct file *filp); |
636 | static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); | 600 | static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count); |
@@ -639,7 +603,7 @@ static void stli_flushchars(struct tty_struct *tty); | |||
639 | static int stli_writeroom(struct tty_struct *tty); | 603 | static int stli_writeroom(struct tty_struct *tty); |
640 | static int stli_charsinbuffer(struct tty_struct *tty); | 604 | static int stli_charsinbuffer(struct tty_struct *tty); |
641 | static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); | 605 | static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); |
642 | static void stli_settermios(struct tty_struct *tty, struct termios *old); | 606 | static void stli_settermios(struct tty_struct *tty, struct ktermios *old); |
643 | static void stli_throttle(struct tty_struct *tty); | 607 | static void stli_throttle(struct tty_struct *tty); |
644 | static void stli_unthrottle(struct tty_struct *tty); | 608 | static void stli_unthrottle(struct tty_struct *tty); |
645 | static void stli_stop(struct tty_struct *tty); | 609 | static void stli_stop(struct tty_struct *tty); |
@@ -649,86 +613,84 @@ static void stli_breakctl(struct tty_struct *tty, int state); | |||
649 | static void stli_waituntilsent(struct tty_struct *tty, int timeout); | 613 | static void stli_waituntilsent(struct tty_struct *tty, int timeout); |
650 | static void stli_sendxchar(struct tty_struct *tty, char ch); | 614 | static void stli_sendxchar(struct tty_struct *tty, char ch); |
651 | static void stli_hangup(struct tty_struct *tty); | 615 | static void stli_hangup(struct tty_struct *tty); |
652 | static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos); | 616 | static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos); |
653 | 617 | ||
654 | static int stli_brdinit(stlibrd_t *brdp); | 618 | static int stli_brdinit(struct stlibrd *brdp); |
655 | static int stli_startbrd(stlibrd_t *brdp); | 619 | static int stli_startbrd(struct stlibrd *brdp); |
656 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); | 620 | static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); |
657 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); | 621 | static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); |
658 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 622 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); |
659 | static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp); | 623 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp); |
660 | static void stli_poll(unsigned long arg); | 624 | static void stli_poll(unsigned long arg); |
661 | static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp); | 625 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp); |
662 | static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); | 626 | static int stli_initopen(struct stlibrd *brdp, struct stliport *portp); |
663 | static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); | 627 | static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); |
664 | static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait); | 628 | static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait); |
665 | static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp); | 629 | static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp); |
666 | static void stli_dohangup(struct work_struct *); | 630 | static void stli_dohangup(struct work_struct *); |
667 | static int stli_setport(stliport_t *portp); | 631 | static int stli_setport(struct stliport *portp); |
668 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 632 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
669 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 633 | static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
670 | static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); | 634 | static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback); |
671 | static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp); | 635 | static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp); |
672 | static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp); | 636 | static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp); |
673 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); | 637 | static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); |
674 | static long stli_mktiocm(unsigned long sigvalue); | 638 | static long stli_mktiocm(unsigned long sigvalue); |
675 | static void stli_read(stlibrd_t *brdp, stliport_t *portp); | 639 | static void stli_read(struct stlibrd *brdp, struct stliport *portp); |
676 | static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp); | 640 | static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp); |
677 | static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp); | 641 | static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp); |
678 | static int stli_getbrdstats(combrd_t __user *bp); | 642 | static int stli_getbrdstats(combrd_t __user *bp); |
679 | static int stli_getportstats(stliport_t *portp, comstats_t __user *cp); | 643 | static int stli_getportstats(struct stliport *portp, comstats_t __user *cp); |
680 | static int stli_portcmdstats(stliport_t *portp); | 644 | static int stli_portcmdstats(struct stliport *portp); |
681 | static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp); | 645 | static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp); |
682 | static int stli_getportstruct(stliport_t __user *arg); | 646 | static int stli_getportstruct(struct stliport __user *arg); |
683 | static int stli_getbrdstruct(stlibrd_t __user *arg); | 647 | static int stli_getbrdstruct(struct stlibrd __user *arg); |
684 | static stlibrd_t *stli_allocbrd(void); | 648 | static struct stlibrd *stli_allocbrd(void); |
685 | 649 | ||
686 | static void stli_ecpinit(stlibrd_t *brdp); | 650 | static void stli_ecpinit(struct stlibrd *brdp); |
687 | static void stli_ecpenable(stlibrd_t *brdp); | 651 | static void stli_ecpenable(struct stlibrd *brdp); |
688 | static void stli_ecpdisable(stlibrd_t *brdp); | 652 | static void stli_ecpdisable(struct stlibrd *brdp); |
689 | static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 653 | static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
690 | static void stli_ecpreset(stlibrd_t *brdp); | 654 | static void stli_ecpreset(struct stlibrd *brdp); |
691 | static void stli_ecpintr(stlibrd_t *brdp); | 655 | static void stli_ecpintr(struct stlibrd *brdp); |
692 | static void stli_ecpeiinit(stlibrd_t *brdp); | 656 | static void stli_ecpeiinit(struct stlibrd *brdp); |
693 | static void stli_ecpeienable(stlibrd_t *brdp); | 657 | static void stli_ecpeienable(struct stlibrd *brdp); |
694 | static void stli_ecpeidisable(stlibrd_t *brdp); | 658 | static void stli_ecpeidisable(struct stlibrd *brdp); |
695 | static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 659 | static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
696 | static void stli_ecpeireset(stlibrd_t *brdp); | 660 | static void stli_ecpeireset(struct stlibrd *brdp); |
697 | static void stli_ecpmcenable(stlibrd_t *brdp); | 661 | static void stli_ecpmcenable(struct stlibrd *brdp); |
698 | static void stli_ecpmcdisable(stlibrd_t *brdp); | 662 | static void stli_ecpmcdisable(struct stlibrd *brdp); |
699 | static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 663 | static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
700 | static void stli_ecpmcreset(stlibrd_t *brdp); | 664 | static void stli_ecpmcreset(struct stlibrd *brdp); |
701 | static void stli_ecppciinit(stlibrd_t *brdp); | 665 | static void stli_ecppciinit(struct stlibrd *brdp); |
702 | static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 666 | static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
703 | static void stli_ecppcireset(stlibrd_t *brdp); | 667 | static void stli_ecppcireset(struct stlibrd *brdp); |
704 | 668 | ||
705 | static void stli_onbinit(stlibrd_t *brdp); | 669 | static void stli_onbinit(struct stlibrd *brdp); |
706 | static void stli_onbenable(stlibrd_t *brdp); | 670 | static void stli_onbenable(struct stlibrd *brdp); |
707 | static void stli_onbdisable(stlibrd_t *brdp); | 671 | static void stli_onbdisable(struct stlibrd *brdp); |
708 | static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 672 | static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
709 | static void stli_onbreset(stlibrd_t *brdp); | 673 | static void stli_onbreset(struct stlibrd *brdp); |
710 | static void stli_onbeinit(stlibrd_t *brdp); | 674 | static void stli_onbeinit(struct stlibrd *brdp); |
711 | static void stli_onbeenable(stlibrd_t *brdp); | 675 | static void stli_onbeenable(struct stlibrd *brdp); |
712 | static void stli_onbedisable(stlibrd_t *brdp); | 676 | static void stli_onbedisable(struct stlibrd *brdp); |
713 | static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 677 | static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
714 | static void stli_onbereset(stlibrd_t *brdp); | 678 | static void stli_onbereset(struct stlibrd *brdp); |
715 | static void stli_bbyinit(stlibrd_t *brdp); | 679 | static void stli_bbyinit(struct stlibrd *brdp); |
716 | static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 680 | static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
717 | static void stli_bbyreset(stlibrd_t *brdp); | 681 | static void stli_bbyreset(struct stlibrd *brdp); |
718 | static void stli_stalinit(stlibrd_t *brdp); | 682 | static void stli_stalinit(struct stlibrd *brdp); |
719 | static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line); | 683 | static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line); |
720 | static void stli_stalreset(stlibrd_t *brdp); | 684 | static void stli_stalreset(struct stlibrd *brdp); |
721 | 685 | ||
722 | static stliport_t *stli_getport(int brdnr, int panelnr, int portnr); | 686 | static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, unsigned int portnr); |
723 | 687 | ||
724 | static int stli_initecp(stlibrd_t *brdp); | 688 | static int stli_initecp(struct stlibrd *brdp); |
725 | static int stli_initonb(stlibrd_t *brdp); | 689 | static int stli_initonb(struct stlibrd *brdp); |
726 | static int stli_eisamemprobe(stlibrd_t *brdp); | 690 | #if STLI_EISAPROBE != 0 |
727 | static int stli_initports(stlibrd_t *brdp); | 691 | static int stli_eisamemprobe(struct stlibrd *brdp); |
728 | |||
729 | #ifdef CONFIG_PCI | ||
730 | static int stli_initpcibrd(int brdtype, struct pci_dev *devp); | ||
731 | #endif | 692 | #endif |
693 | static int stli_initports(struct stlibrd *brdp); | ||
732 | 694 | ||
733 | /*****************************************************************************/ | 695 | /*****************************************************************************/ |
734 | 696 | ||
@@ -766,136 +728,19 @@ static int stli_timeron; | |||
766 | 728 | ||
767 | static struct class *istallion_class; | 729 | static struct class *istallion_class; |
768 | 730 | ||
769 | /* | 731 | static void stli_cleanup_ports(struct stlibrd *brdp) |
770 | * Loadable module initialization stuff. | ||
771 | */ | ||
772 | |||
773 | static int __init istallion_module_init(void) | ||
774 | { | ||
775 | stli_init(); | ||
776 | return 0; | ||
777 | } | ||
778 | |||
779 | /*****************************************************************************/ | ||
780 | |||
781 | static void __exit istallion_module_exit(void) | ||
782 | { | ||
783 | stlibrd_t *brdp; | ||
784 | stliport_t *portp; | ||
785 | int i, j; | ||
786 | |||
787 | printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, | ||
788 | stli_drvversion); | ||
789 | |||
790 | /* | ||
791 | * Free up all allocated resources used by the ports. This includes | ||
792 | * memory and interrupts. | ||
793 | */ | ||
794 | if (stli_timeron) { | ||
795 | stli_timeron = 0; | ||
796 | del_timer_sync(&stli_timerlist); | ||
797 | } | ||
798 | |||
799 | i = tty_unregister_driver(stli_serial); | ||
800 | if (i) { | ||
801 | printk("STALLION: failed to un-register tty driver, " | ||
802 | "errno=%d\n", -i); | ||
803 | return; | ||
804 | } | ||
805 | put_tty_driver(stli_serial); | ||
806 | for (i = 0; i < 4; i++) | ||
807 | class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | ||
808 | class_destroy(istallion_class); | ||
809 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) | ||
810 | printk("STALLION: failed to un-register serial memory device, " | ||
811 | "errno=%d\n", -i); | ||
812 | |||
813 | kfree(stli_txcookbuf); | ||
814 | |||
815 | for (i = 0; (i < stli_nrbrds); i++) { | ||
816 | if ((brdp = stli_brds[i]) == NULL) | ||
817 | continue; | ||
818 | for (j = 0; (j < STL_MAXPORTS); j++) { | ||
819 | portp = brdp->ports[j]; | ||
820 | if (portp != NULL) { | ||
821 | if (portp->tty != NULL) | ||
822 | tty_hangup(portp->tty); | ||
823 | kfree(portp); | ||
824 | } | ||
825 | } | ||
826 | |||
827 | iounmap(brdp->membase); | ||
828 | if (brdp->iosize > 0) | ||
829 | release_region(brdp->iobase, brdp->iosize); | ||
830 | kfree(brdp); | ||
831 | stli_brds[i] = NULL; | ||
832 | } | ||
833 | } | ||
834 | |||
835 | module_init(istallion_module_init); | ||
836 | module_exit(istallion_module_exit); | ||
837 | |||
838 | /*****************************************************************************/ | ||
839 | |||
840 | /* | ||
841 | * Check for any arguments passed in on the module load command line. | ||
842 | */ | ||
843 | |||
844 | static void stli_argbrds(void) | ||
845 | { | ||
846 | stlconf_t conf; | ||
847 | stlibrd_t *brdp; | ||
848 | int i; | ||
849 | |||
850 | for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) { | ||
851 | memset(&conf, 0, sizeof(conf)); | ||
852 | if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) | ||
853 | continue; | ||
854 | if ((brdp = stli_allocbrd()) == NULL) | ||
855 | continue; | ||
856 | stli_nrbrds = i + 1; | ||
857 | brdp->brdnr = i; | ||
858 | brdp->brdtype = conf.brdtype; | ||
859 | brdp->iobase = conf.ioaddr1; | ||
860 | brdp->memaddr = conf.memaddr; | ||
861 | stli_brdinit(brdp); | ||
862 | } | ||
863 | } | ||
864 | |||
865 | /*****************************************************************************/ | ||
866 | |||
867 | /* | ||
868 | * Convert an ascii string number into an unsigned long. | ||
869 | */ | ||
870 | |||
871 | static unsigned long stli_atol(char *str) | ||
872 | { | 732 | { |
873 | unsigned long val; | 733 | struct stliport *portp; |
874 | int base, c; | 734 | unsigned int j; |
875 | char *sp; | 735 | |
876 | 736 | for (j = 0; j < STL_MAXPORTS; j++) { | |
877 | val = 0; | 737 | portp = brdp->ports[j]; |
878 | sp = str; | 738 | if (portp != NULL) { |
879 | if ((*sp == '0') && (*(sp+1) == 'x')) { | 739 | if (portp->tty != NULL) |
880 | base = 16; | 740 | tty_hangup(portp->tty); |
881 | sp += 2; | 741 | kfree(portp); |
882 | } else if (*sp == '0') { | ||
883 | base = 8; | ||
884 | sp++; | ||
885 | } else { | ||
886 | base = 10; | ||
887 | } | ||
888 | |||
889 | for (; (*sp != 0); sp++) { | ||
890 | c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0'); | ||
891 | if ((c < 0) || (c >= base)) { | ||
892 | printk("STALLION: invalid argument %s\n", str); | ||
893 | val = 0; | ||
894 | break; | ||
895 | } | 742 | } |
896 | val = (val * base) + c; | ||
897 | } | 743 | } |
898 | return(val); | ||
899 | } | 744 | } |
900 | 745 | ||
901 | /*****************************************************************************/ | 746 | /*****************************************************************************/ |
@@ -904,16 +749,16 @@ static unsigned long stli_atol(char *str) | |||
904 | * Parse the supplied argument string, into the board conf struct. | 749 | * Parse the supplied argument string, into the board conf struct. |
905 | */ | 750 | */ |
906 | 751 | ||
907 | static int stli_parsebrd(stlconf_t *confp, char **argp) | 752 | static int stli_parsebrd(struct stlconf *confp, char **argp) |
908 | { | 753 | { |
754 | unsigned int i; | ||
909 | char *sp; | 755 | char *sp; |
910 | int i; | ||
911 | 756 | ||
912 | if (argp[0] == NULL || *argp[0] == 0) | 757 | if (argp[0] == NULL || *argp[0] == 0) |
913 | return 0; | 758 | return 0; |
914 | 759 | ||
915 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) | 760 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) |
916 | *sp = TOLOWER(*sp); | 761 | *sp = tolower(*sp); |
917 | 762 | ||
918 | for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) { | 763 | for (i = 0; i < ARRAY_SIZE(stli_brdstr); i++) { |
919 | if (strcmp(stli_brdstr[i].name, argp[0]) == 0) | 764 | if (strcmp(stli_brdstr[i].name, argp[0]) == 0) |
@@ -926,9 +771,9 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) | |||
926 | 771 | ||
927 | confp->brdtype = stli_brdstr[i].type; | 772 | confp->brdtype = stli_brdstr[i].type; |
928 | if (argp[1] != NULL && *argp[1] != 0) | 773 | if (argp[1] != NULL && *argp[1] != 0) |
929 | confp->ioaddr1 = stli_atol(argp[1]); | 774 | confp->ioaddr1 = simple_strtoul(argp[1], NULL, 0); |
930 | if (argp[2] != NULL && *argp[2] != 0) | 775 | if (argp[2] != NULL && *argp[2] != 0) |
931 | confp->memaddr = stli_atol(argp[2]); | 776 | confp->memaddr = simple_strtoul(argp[2], NULL, 0); |
932 | return(1); | 777 | return(1); |
933 | } | 778 | } |
934 | 779 | ||
@@ -936,10 +781,10 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) | |||
936 | 781 | ||
937 | static int stli_open(struct tty_struct *tty, struct file *filp) | 782 | static int stli_open(struct tty_struct *tty, struct file *filp) |
938 | { | 783 | { |
939 | stlibrd_t *brdp; | 784 | struct stlibrd *brdp; |
940 | stliport_t *portp; | 785 | struct stliport *portp; |
941 | unsigned int minordev; | 786 | unsigned int minordev, brdnr, portnr; |
942 | int brdnr, portnr, rc; | 787 | int rc; |
943 | 788 | ||
944 | minordev = tty->index; | 789 | minordev = tty->index; |
945 | brdnr = MINOR2BRD(minordev); | 790 | brdnr = MINOR2BRD(minordev); |
@@ -951,7 +796,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
951 | if ((brdp->state & BST_STARTED) == 0) | 796 | if ((brdp->state & BST_STARTED) == 0) |
952 | return -ENODEV; | 797 | return -ENODEV; |
953 | portnr = MINOR2PORT(minordev); | 798 | portnr = MINOR2PORT(minordev); |
954 | if ((portnr < 0) || (portnr > brdp->nrports)) | 799 | if (portnr > brdp->nrports) |
955 | return -ENODEV; | 800 | return -ENODEV; |
956 | 801 | ||
957 | portp = brdp->ports[portnr]; | 802 | portp = brdp->ports[portnr]; |
@@ -1031,8 +876,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) | |||
1031 | 876 | ||
1032 | static void stli_close(struct tty_struct *tty, struct file *filp) | 877 | static void stli_close(struct tty_struct *tty, struct file *filp) |
1033 | { | 878 | { |
1034 | stlibrd_t *brdp; | 879 | struct stlibrd *brdp; |
1035 | stliport_t *portp; | 880 | struct stliport *portp; |
1036 | unsigned long flags; | 881 | unsigned long flags; |
1037 | 882 | ||
1038 | portp = tty->driver_data; | 883 | portp = tty->driver_data; |
@@ -1109,7 +954,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) | |||
1109 | * this still all happens pretty quickly. | 954 | * this still all happens pretty quickly. |
1110 | */ | 955 | */ |
1111 | 956 | ||
1112 | static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) | 957 | static int stli_initopen(struct stlibrd *brdp, struct stliport *portp) |
1113 | { | 958 | { |
1114 | struct tty_struct *tty; | 959 | struct tty_struct *tty; |
1115 | asynotify_t nt; | 960 | asynotify_t nt; |
@@ -1157,7 +1002,7 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) | |||
1157 | * to overlap. | 1002 | * to overlap. |
1158 | */ | 1003 | */ |
1159 | 1004 | ||
1160 | static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) | 1005 | static int stli_rawopen(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) |
1161 | { | 1006 | { |
1162 | cdkhdr_t __iomem *hdrp; | 1007 | cdkhdr_t __iomem *hdrp; |
1163 | cdkctrl_t __iomem *cp; | 1008 | cdkctrl_t __iomem *cp; |
@@ -1228,7 +1073,7 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i | |||
1228 | * wait is true then must have user context (to sleep). | 1073 | * wait is true then must have user context (to sleep). |
1229 | */ | 1074 | */ |
1230 | 1075 | ||
1231 | static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) | 1076 | static int stli_rawclose(struct stlibrd *brdp, struct stliport *portp, unsigned long arg, int wait) |
1232 | { | 1077 | { |
1233 | cdkhdr_t __iomem *hdrp; | 1078 | cdkhdr_t __iomem *hdrp; |
1234 | cdkctrl_t __iomem *cp; | 1079 | cdkctrl_t __iomem *cp; |
@@ -1292,7 +1137,7 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, | |||
1292 | * to complete (as opposed to initiating the command then returning). | 1137 | * to complete (as opposed to initiating the command then returning). |
1293 | */ | 1138 | */ |
1294 | 1139 | ||
1295 | static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) | 1140 | static int stli_cmdwait(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) |
1296 | { | 1141 | { |
1297 | wait_event_interruptible(portp->raw_wait, | 1142 | wait_event_interruptible(portp->raw_wait, |
1298 | !test_bit(ST_CMDING, &portp->state)); | 1143 | !test_bit(ST_CMDING, &portp->state)); |
@@ -1318,16 +1163,16 @@ static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, v | |||
1318 | * waiting for the command to complete - so must have user context. | 1163 | * waiting for the command to complete - so must have user context. |
1319 | */ | 1164 | */ |
1320 | 1165 | ||
1321 | static int stli_setport(stliport_t *portp) | 1166 | static int stli_setport(struct stliport *portp) |
1322 | { | 1167 | { |
1323 | stlibrd_t *brdp; | 1168 | struct stlibrd *brdp; |
1324 | asyport_t aport; | 1169 | asyport_t aport; |
1325 | 1170 | ||
1326 | if (portp == NULL) | 1171 | if (portp == NULL) |
1327 | return -ENODEV; | 1172 | return -ENODEV; |
1328 | if (portp->tty == NULL) | 1173 | if (portp->tty == NULL) |
1329 | return -ENODEV; | 1174 | return -ENODEV; |
1330 | if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds) | 1175 | if (portp->brdnr >= stli_nrbrds) |
1331 | return -ENODEV; | 1176 | return -ENODEV; |
1332 | brdp = stli_brds[portp->brdnr]; | 1177 | brdp = stli_brds[portp->brdnr]; |
1333 | if (brdp == NULL) | 1178 | if (brdp == NULL) |
@@ -1344,7 +1189,7 @@ static int stli_setport(stliport_t *portp) | |||
1344 | * maybe because if we are clocal then we don't need to wait... | 1189 | * maybe because if we are clocal then we don't need to wait... |
1345 | */ | 1190 | */ |
1346 | 1191 | ||
1347 | static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) | 1192 | static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct file *filp) |
1348 | { | 1193 | { |
1349 | unsigned long flags; | 1194 | unsigned long flags; |
1350 | int rc, doclocal; | 1195 | int rc, doclocal; |
@@ -1409,8 +1254,8 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1409 | unsigned char __iomem *bits; | 1254 | unsigned char __iomem *bits; |
1410 | unsigned char __iomem *shbuf; | 1255 | unsigned char __iomem *shbuf; |
1411 | unsigned char *chbuf; | 1256 | unsigned char *chbuf; |
1412 | stliport_t *portp; | 1257 | struct stliport *portp; |
1413 | stlibrd_t *brdp; | 1258 | struct stlibrd *brdp; |
1414 | unsigned int len, stlen, head, tail, size; | 1259 | unsigned int len, stlen, head, tail, size; |
1415 | unsigned long flags; | 1260 | unsigned long flags; |
1416 | 1261 | ||
@@ -1419,7 +1264,7 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1419 | portp = tty->driver_data; | 1264 | portp = tty->driver_data; |
1420 | if (portp == NULL) | 1265 | if (portp == NULL) |
1421 | return 0; | 1266 | return 0; |
1422 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1267 | if (portp->brdnr >= stli_nrbrds) |
1423 | return 0; | 1268 | return 0; |
1424 | brdp = stli_brds[portp->brdnr]; | 1269 | brdp = stli_brds[portp->brdnr]; |
1425 | if (brdp == NULL) | 1270 | if (brdp == NULL) |
@@ -1445,12 +1290,12 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun | |||
1445 | stlen = len; | 1290 | stlen = len; |
1446 | } | 1291 | } |
1447 | 1292 | ||
1448 | len = MIN(len, count); | 1293 | len = min(len, (unsigned int)count); |
1449 | count = 0; | 1294 | count = 0; |
1450 | shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); | 1295 | shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); |
1451 | 1296 | ||
1452 | while (len > 0) { | 1297 | while (len > 0) { |
1453 | stlen = MIN(len, stlen); | 1298 | stlen = min(len, stlen); |
1454 | memcpy_toio(shbuf + head, chbuf, stlen); | 1299 | memcpy_toio(shbuf + head, chbuf, stlen); |
1455 | chbuf += stlen; | 1300 | chbuf += stlen; |
1456 | len -= stlen; | 1301 | len -= stlen; |
@@ -1516,8 +1361,8 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1516 | unsigned char __iomem *bits; | 1361 | unsigned char __iomem *bits; |
1517 | cdkasy_t __iomem *ap; | 1362 | cdkasy_t __iomem *ap; |
1518 | struct tty_struct *cooktty; | 1363 | struct tty_struct *cooktty; |
1519 | stliport_t *portp; | 1364 | struct stliport *portp; |
1520 | stlibrd_t *brdp; | 1365 | struct stlibrd *brdp; |
1521 | unsigned int len, stlen, head, tail, size, count, cooksize; | 1366 | unsigned int len, stlen, head, tail, size, count, cooksize; |
1522 | unsigned char *buf; | 1367 | unsigned char *buf; |
1523 | unsigned char __iomem *shbuf; | 1368 | unsigned char __iomem *shbuf; |
@@ -1541,7 +1386,7 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1541 | portp = tty->driver_data; | 1386 | portp = tty->driver_data; |
1542 | if (portp == NULL) | 1387 | if (portp == NULL) |
1543 | return; | 1388 | return; |
1544 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1389 | if (portp->brdnr >= stli_nrbrds) |
1545 | return; | 1390 | return; |
1546 | brdp = stli_brds[portp->brdnr]; | 1391 | brdp = stli_brds[portp->brdnr]; |
1547 | if (brdp == NULL) | 1392 | if (brdp == NULL) |
@@ -1564,13 +1409,13 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1564 | stlen = len; | 1409 | stlen = len; |
1565 | } | 1410 | } |
1566 | 1411 | ||
1567 | len = MIN(len, cooksize); | 1412 | len = min(len, cooksize); |
1568 | count = 0; | 1413 | count = 0; |
1569 | shbuf = EBRDGETMEMPTR(brdp, portp->txoffset); | 1414 | shbuf = EBRDGETMEMPTR(brdp, portp->txoffset); |
1570 | buf = stli_txcookbuf; | 1415 | buf = stli_txcookbuf; |
1571 | 1416 | ||
1572 | while (len > 0) { | 1417 | while (len > 0) { |
1573 | stlen = MIN(len, stlen); | 1418 | stlen = min(len, stlen); |
1574 | memcpy_toio(shbuf + head, buf, stlen); | 1419 | memcpy_toio(shbuf + head, buf, stlen); |
1575 | buf += stlen; | 1420 | buf += stlen; |
1576 | len -= stlen; | 1421 | len -= stlen; |
@@ -1604,8 +1449,8 @@ static void stli_flushchars(struct tty_struct *tty) | |||
1604 | static int stli_writeroom(struct tty_struct *tty) | 1449 | static int stli_writeroom(struct tty_struct *tty) |
1605 | { | 1450 | { |
1606 | cdkasyrq_t __iomem *rp; | 1451 | cdkasyrq_t __iomem *rp; |
1607 | stliport_t *portp; | 1452 | struct stliport *portp; |
1608 | stlibrd_t *brdp; | 1453 | struct stlibrd *brdp; |
1609 | unsigned int head, tail, len; | 1454 | unsigned int head, tail, len; |
1610 | unsigned long flags; | 1455 | unsigned long flags; |
1611 | 1456 | ||
@@ -1619,7 +1464,7 @@ static int stli_writeroom(struct tty_struct *tty) | |||
1619 | portp = tty->driver_data; | 1464 | portp = tty->driver_data; |
1620 | if (portp == NULL) | 1465 | if (portp == NULL) |
1621 | return 0; | 1466 | return 0; |
1622 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1467 | if (portp->brdnr >= stli_nrbrds) |
1623 | return 0; | 1468 | return 0; |
1624 | brdp = stli_brds[portp->brdnr]; | 1469 | brdp = stli_brds[portp->brdnr]; |
1625 | if (brdp == NULL) | 1470 | if (brdp == NULL) |
@@ -1657,8 +1502,8 @@ static int stli_writeroom(struct tty_struct *tty) | |||
1657 | static int stli_charsinbuffer(struct tty_struct *tty) | 1502 | static int stli_charsinbuffer(struct tty_struct *tty) |
1658 | { | 1503 | { |
1659 | cdkasyrq_t __iomem *rp; | 1504 | cdkasyrq_t __iomem *rp; |
1660 | stliport_t *portp; | 1505 | struct stliport *portp; |
1661 | stlibrd_t *brdp; | 1506 | struct stlibrd *brdp; |
1662 | unsigned int head, tail, len; | 1507 | unsigned int head, tail, len; |
1663 | unsigned long flags; | 1508 | unsigned long flags; |
1664 | 1509 | ||
@@ -1667,7 +1512,7 @@ static int stli_charsinbuffer(struct tty_struct *tty) | |||
1667 | portp = tty->driver_data; | 1512 | portp = tty->driver_data; |
1668 | if (portp == NULL) | 1513 | if (portp == NULL) |
1669 | return 0; | 1514 | return 0; |
1670 | if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) | 1515 | if (portp->brdnr >= stli_nrbrds) |
1671 | return 0; | 1516 | return 0; |
1672 | brdp = stli_brds[portp->brdnr]; | 1517 | brdp = stli_brds[portp->brdnr]; |
1673 | if (brdp == NULL) | 1518 | if (brdp == NULL) |
@@ -1695,10 +1540,10 @@ static int stli_charsinbuffer(struct tty_struct *tty) | |||
1695 | * Generate the serial struct info. | 1540 | * Generate the serial struct info. |
1696 | */ | 1541 | */ |
1697 | 1542 | ||
1698 | static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) | 1543 | static int stli_getserial(struct stliport *portp, struct serial_struct __user *sp) |
1699 | { | 1544 | { |
1700 | struct serial_struct sio; | 1545 | struct serial_struct sio; |
1701 | stlibrd_t *brdp; | 1546 | struct stlibrd *brdp; |
1702 | 1547 | ||
1703 | memset(&sio, 0, sizeof(struct serial_struct)); | 1548 | memset(&sio, 0, sizeof(struct serial_struct)); |
1704 | sio.type = PORT_UNKNOWN; | 1549 | sio.type = PORT_UNKNOWN; |
@@ -1728,7 +1573,7 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) | |||
1728 | * just quietly ignore any requests to change irq, etc. | 1573 | * just quietly ignore any requests to change irq, etc. |
1729 | */ | 1574 | */ |
1730 | 1575 | ||
1731 | static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) | 1576 | static int stli_setserial(struct stliport *portp, struct serial_struct __user *sp) |
1732 | { | 1577 | { |
1733 | struct serial_struct sio; | 1578 | struct serial_struct sio; |
1734 | int rc; | 1579 | int rc; |
@@ -1759,13 +1604,13 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) | |||
1759 | 1604 | ||
1760 | static int stli_tiocmget(struct tty_struct *tty, struct file *file) | 1605 | static int stli_tiocmget(struct tty_struct *tty, struct file *file) |
1761 | { | 1606 | { |
1762 | stliport_t *portp = tty->driver_data; | 1607 | struct stliport *portp = tty->driver_data; |
1763 | stlibrd_t *brdp; | 1608 | struct stlibrd *brdp; |
1764 | int rc; | 1609 | int rc; |
1765 | 1610 | ||
1766 | if (portp == NULL) | 1611 | if (portp == NULL) |
1767 | return -ENODEV; | 1612 | return -ENODEV; |
1768 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1613 | if (portp->brdnr >= stli_nrbrds) |
1769 | return 0; | 1614 | return 0; |
1770 | brdp = stli_brds[portp->brdnr]; | 1615 | brdp = stli_brds[portp->brdnr]; |
1771 | if (brdp == NULL) | 1616 | if (brdp == NULL) |
@@ -1783,13 +1628,13 @@ static int stli_tiocmget(struct tty_struct *tty, struct file *file) | |||
1783 | static int stli_tiocmset(struct tty_struct *tty, struct file *file, | 1628 | static int stli_tiocmset(struct tty_struct *tty, struct file *file, |
1784 | unsigned int set, unsigned int clear) | 1629 | unsigned int set, unsigned int clear) |
1785 | { | 1630 | { |
1786 | stliport_t *portp = tty->driver_data; | 1631 | struct stliport *portp = tty->driver_data; |
1787 | stlibrd_t *brdp; | 1632 | struct stlibrd *brdp; |
1788 | int rts = -1, dtr = -1; | 1633 | int rts = -1, dtr = -1; |
1789 | 1634 | ||
1790 | if (portp == NULL) | 1635 | if (portp == NULL) |
1791 | return -ENODEV; | 1636 | return -ENODEV; |
1792 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1637 | if (portp->brdnr >= stli_nrbrds) |
1793 | return 0; | 1638 | return 0; |
1794 | brdp = stli_brds[portp->brdnr]; | 1639 | brdp = stli_brds[portp->brdnr]; |
1795 | if (brdp == NULL) | 1640 | if (brdp == NULL) |
@@ -1814,8 +1659,8 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, | |||
1814 | 1659 | ||
1815 | static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) | 1660 | static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) |
1816 | { | 1661 | { |
1817 | stliport_t *portp; | 1662 | struct stliport *portp; |
1818 | stlibrd_t *brdp; | 1663 | struct stlibrd *brdp; |
1819 | unsigned int ival; | 1664 | unsigned int ival; |
1820 | int rc; | 1665 | int rc; |
1821 | void __user *argp = (void __user *)arg; | 1666 | void __user *argp = (void __user *)arg; |
@@ -1823,7 +1668,7 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
1823 | portp = tty->driver_data; | 1668 | portp = tty->driver_data; |
1824 | if (portp == NULL) | 1669 | if (portp == NULL) |
1825 | return -ENODEV; | 1670 | return -ENODEV; |
1826 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1671 | if (portp->brdnr >= stli_nrbrds) |
1827 | return 0; | 1672 | return 0; |
1828 | brdp = stli_brds[portp->brdnr]; | 1673 | brdp = stli_brds[portp->brdnr]; |
1829 | if (brdp == NULL) | 1674 | if (brdp == NULL) |
@@ -1889,11 +1734,11 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm | |||
1889 | * Looks like it is true for the current ttys implementation..!! | 1734 | * Looks like it is true for the current ttys implementation..!! |
1890 | */ | 1735 | */ |
1891 | 1736 | ||
1892 | static void stli_settermios(struct tty_struct *tty, struct termios *old) | 1737 | static void stli_settermios(struct tty_struct *tty, struct ktermios *old) |
1893 | { | 1738 | { |
1894 | stliport_t *portp; | 1739 | struct stliport *portp; |
1895 | stlibrd_t *brdp; | 1740 | struct stlibrd *brdp; |
1896 | struct termios *tiosp; | 1741 | struct ktermios *tiosp; |
1897 | asyport_t aport; | 1742 | asyport_t aport; |
1898 | 1743 | ||
1899 | if (tty == NULL) | 1744 | if (tty == NULL) |
@@ -1901,7 +1746,7 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old) | |||
1901 | portp = tty->driver_data; | 1746 | portp = tty->driver_data; |
1902 | if (portp == NULL) | 1747 | if (portp == NULL) |
1903 | return; | 1748 | return; |
1904 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1749 | if (portp->brdnr >= stli_nrbrds) |
1905 | return; | 1750 | return; |
1906 | brdp = stli_brds[portp->brdnr]; | 1751 | brdp = stli_brds[portp->brdnr]; |
1907 | if (brdp == NULL) | 1752 | if (brdp == NULL) |
@@ -1937,7 +1782,7 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old) | |||
1937 | 1782 | ||
1938 | static void stli_throttle(struct tty_struct *tty) | 1783 | static void stli_throttle(struct tty_struct *tty) |
1939 | { | 1784 | { |
1940 | stliport_t *portp = tty->driver_data; | 1785 | struct stliport *portp = tty->driver_data; |
1941 | if (portp == NULL) | 1786 | if (portp == NULL) |
1942 | return; | 1787 | return; |
1943 | set_bit(ST_RXSTOP, &portp->state); | 1788 | set_bit(ST_RXSTOP, &portp->state); |
@@ -1953,7 +1798,7 @@ static void stli_throttle(struct tty_struct *tty) | |||
1953 | 1798 | ||
1954 | static void stli_unthrottle(struct tty_struct *tty) | 1799 | static void stli_unthrottle(struct tty_struct *tty) |
1955 | { | 1800 | { |
1956 | stliport_t *portp = tty->driver_data; | 1801 | struct stliport *portp = tty->driver_data; |
1957 | if (portp == NULL) | 1802 | if (portp == NULL) |
1958 | return; | 1803 | return; |
1959 | clear_bit(ST_RXSTOP, &portp->state); | 1804 | clear_bit(ST_RXSTOP, &portp->state); |
@@ -1992,7 +1837,7 @@ static void stli_start(struct tty_struct *tty) | |||
1992 | 1837 | ||
1993 | static void stli_dohangup(struct work_struct *ugly_api) | 1838 | static void stli_dohangup(struct work_struct *ugly_api) |
1994 | { | 1839 | { |
1995 | stliport_t *portp = container_of(ugly_api, stliport_t, tqhangup); | 1840 | struct stliport *portp = container_of(ugly_api, struct stliport, tqhangup); |
1996 | if (portp->tty != NULL) { | 1841 | if (portp->tty != NULL) { |
1997 | tty_hangup(portp->tty); | 1842 | tty_hangup(portp->tty); |
1998 | } | 1843 | } |
@@ -2009,14 +1854,14 @@ static void stli_dohangup(struct work_struct *ugly_api) | |||
2009 | 1854 | ||
2010 | static void stli_hangup(struct tty_struct *tty) | 1855 | static void stli_hangup(struct tty_struct *tty) |
2011 | { | 1856 | { |
2012 | stliport_t *portp; | 1857 | struct stliport *portp; |
2013 | stlibrd_t *brdp; | 1858 | struct stlibrd *brdp; |
2014 | unsigned long flags; | 1859 | unsigned long flags; |
2015 | 1860 | ||
2016 | portp = tty->driver_data; | 1861 | portp = tty->driver_data; |
2017 | if (portp == NULL) | 1862 | if (portp == NULL) |
2018 | return; | 1863 | return; |
2019 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1864 | if (portp->brdnr >= stli_nrbrds) |
2020 | return; | 1865 | return; |
2021 | brdp = stli_brds[portp->brdnr]; | 1866 | brdp = stli_brds[portp->brdnr]; |
2022 | if (brdp == NULL) | 1867 | if (brdp == NULL) |
@@ -2062,14 +1907,14 @@ static void stli_hangup(struct tty_struct *tty) | |||
2062 | 1907 | ||
2063 | static void stli_flushbuffer(struct tty_struct *tty) | 1908 | static void stli_flushbuffer(struct tty_struct *tty) |
2064 | { | 1909 | { |
2065 | stliport_t *portp; | 1910 | struct stliport *portp; |
2066 | stlibrd_t *brdp; | 1911 | struct stlibrd *brdp; |
2067 | unsigned long ftype, flags; | 1912 | unsigned long ftype, flags; |
2068 | 1913 | ||
2069 | portp = tty->driver_data; | 1914 | portp = tty->driver_data; |
2070 | if (portp == NULL) | 1915 | if (portp == NULL) |
2071 | return; | 1916 | return; |
2072 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1917 | if (portp->brdnr >= stli_nrbrds) |
2073 | return; | 1918 | return; |
2074 | brdp = stli_brds[portp->brdnr]; | 1919 | brdp = stli_brds[portp->brdnr]; |
2075 | if (brdp == NULL) | 1920 | if (brdp == NULL) |
@@ -2099,14 +1944,14 @@ static void stli_flushbuffer(struct tty_struct *tty) | |||
2099 | 1944 | ||
2100 | static void stli_breakctl(struct tty_struct *tty, int state) | 1945 | static void stli_breakctl(struct tty_struct *tty, int state) |
2101 | { | 1946 | { |
2102 | stlibrd_t *brdp; | 1947 | struct stlibrd *brdp; |
2103 | stliport_t *portp; | 1948 | struct stliport *portp; |
2104 | long arg; | 1949 | long arg; |
2105 | 1950 | ||
2106 | portp = tty->driver_data; | 1951 | portp = tty->driver_data; |
2107 | if (portp == NULL) | 1952 | if (portp == NULL) |
2108 | return; | 1953 | return; |
2109 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 1954 | if (portp->brdnr >= stli_nrbrds) |
2110 | return; | 1955 | return; |
2111 | brdp = stli_brds[portp->brdnr]; | 1956 | brdp = stli_brds[portp->brdnr]; |
2112 | if (brdp == NULL) | 1957 | if (brdp == NULL) |
@@ -2120,7 +1965,7 @@ static void stli_breakctl(struct tty_struct *tty, int state) | |||
2120 | 1965 | ||
2121 | static void stli_waituntilsent(struct tty_struct *tty, int timeout) | 1966 | static void stli_waituntilsent(struct tty_struct *tty, int timeout) |
2122 | { | 1967 | { |
2123 | stliport_t *portp; | 1968 | struct stliport *portp; |
2124 | unsigned long tend; | 1969 | unsigned long tend; |
2125 | 1970 | ||
2126 | if (tty == NULL) | 1971 | if (tty == NULL) |
@@ -2146,14 +1991,14 @@ static void stli_waituntilsent(struct tty_struct *tty, int timeout) | |||
2146 | 1991 | ||
2147 | static void stli_sendxchar(struct tty_struct *tty, char ch) | 1992 | static void stli_sendxchar(struct tty_struct *tty, char ch) |
2148 | { | 1993 | { |
2149 | stlibrd_t *brdp; | 1994 | struct stlibrd *brdp; |
2150 | stliport_t *portp; | 1995 | struct stliport *portp; |
2151 | asyctrl_t actrl; | 1996 | asyctrl_t actrl; |
2152 | 1997 | ||
2153 | portp = tty->driver_data; | 1998 | portp = tty->driver_data; |
2154 | if (portp == NULL) | 1999 | if (portp == NULL) |
2155 | return; | 2000 | return; |
2156 | if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) | 2001 | if (portp->brdnr >= stli_nrbrds) |
2157 | return; | 2002 | return; |
2158 | brdp = stli_brds[portp->brdnr]; | 2003 | brdp = stli_brds[portp->brdnr]; |
2159 | if (brdp == NULL) | 2004 | if (brdp == NULL) |
@@ -2181,7 +2026,7 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) | |||
2181 | * short then padded with spaces). | 2026 | * short then padded with spaces). |
2182 | */ | 2027 | */ |
2183 | 2028 | ||
2184 | static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos) | 2029 | static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos) |
2185 | { | 2030 | { |
2186 | char *sp, *uart; | 2031 | char *sp, *uart; |
2187 | int rc, cnt; | 2032 | int rc, cnt; |
@@ -2244,9 +2089,9 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p | |||
2244 | 2089 | ||
2245 | static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) | 2090 | static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) |
2246 | { | 2091 | { |
2247 | stlibrd_t *brdp; | 2092 | struct stlibrd *brdp; |
2248 | stliport_t *portp; | 2093 | struct stliport *portp; |
2249 | int brdnr, portnr, totalport; | 2094 | unsigned int brdnr, portnr, totalport; |
2250 | int curoff, maxoff; | 2095 | int curoff, maxoff; |
2251 | char *pos; | 2096 | char *pos; |
2252 | 2097 | ||
@@ -2316,7 +2161,7 @@ stli_readdone: | |||
2316 | * entry point) | 2161 | * entry point) |
2317 | */ | 2162 | */ |
2318 | 2163 | ||
2319 | static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) | 2164 | static void __stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) |
2320 | { | 2165 | { |
2321 | cdkhdr_t __iomem *hdrp; | 2166 | cdkhdr_t __iomem *hdrp; |
2322 | cdkctrl_t __iomem *cp; | 2167 | cdkctrl_t __iomem *cp; |
@@ -2352,7 +2197,7 @@ static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd | |||
2352 | spin_unlock_irqrestore(&brd_lock, flags); | 2197 | spin_unlock_irqrestore(&brd_lock, flags); |
2353 | } | 2198 | } |
2354 | 2199 | ||
2355 | static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) | 2200 | static void stli_sendcmd(struct stlibrd *brdp, struct stliport *portp, unsigned long cmd, void *arg, int size, int copyback) |
2356 | { | 2201 | { |
2357 | unsigned long flags; | 2202 | unsigned long flags; |
2358 | 2203 | ||
@@ -2371,7 +2216,7 @@ static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, | |||
2371 | * more chars to unload. | 2216 | * more chars to unload. |
2372 | */ | 2217 | */ |
2373 | 2218 | ||
2374 | static void stli_read(stlibrd_t *brdp, stliport_t *portp) | 2219 | static void stli_read(struct stlibrd *brdp, struct stliport *portp) |
2375 | { | 2220 | { |
2376 | cdkasyrq_t __iomem *rp; | 2221 | cdkasyrq_t __iomem *rp; |
2377 | char __iomem *shbuf; | 2222 | char __iomem *shbuf; |
@@ -2406,7 +2251,7 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) | |||
2406 | while (len > 0) { | 2251 | while (len > 0) { |
2407 | unsigned char *cptr; | 2252 | unsigned char *cptr; |
2408 | 2253 | ||
2409 | stlen = MIN(len, stlen); | 2254 | stlen = min(len, stlen); |
2410 | tty_prepare_flip_string(tty, &cptr, stlen); | 2255 | tty_prepare_flip_string(tty, &cptr, stlen); |
2411 | memcpy_fromio(cptr, shbuf + tail, stlen); | 2256 | memcpy_fromio(cptr, shbuf + tail, stlen); |
2412 | len -= stlen; | 2257 | len -= stlen; |
@@ -2433,7 +2278,7 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) | |||
2433 | * difficult to deal with them here. | 2278 | * difficult to deal with them here. |
2434 | */ | 2279 | */ |
2435 | 2280 | ||
2436 | static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) | 2281 | static void stli_dodelaycmd(struct stliport *portp, cdkctrl_t __iomem *cp) |
2437 | { | 2282 | { |
2438 | int cmd; | 2283 | int cmd; |
2439 | 2284 | ||
@@ -2481,7 +2326,7 @@ static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) | |||
2481 | * then port is still busy, otherwise no longer busy. | 2326 | * then port is still busy, otherwise no longer busy. |
2482 | */ | 2327 | */ |
2483 | 2328 | ||
2484 | static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | 2329 | static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp) |
2485 | { | 2330 | { |
2486 | cdkasy_t __iomem *ap; | 2331 | cdkasy_t __iomem *ap; |
2487 | cdkctrl_t __iomem *cp; | 2332 | cdkctrl_t __iomem *cp; |
@@ -2628,9 +2473,9 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) | |||
2628 | * at the cdk header structure. | 2473 | * at the cdk header structure. |
2629 | */ | 2474 | */ |
2630 | 2475 | ||
2631 | static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) | 2476 | static void stli_brdpoll(struct stlibrd *brdp, cdkhdr_t __iomem *hdrp) |
2632 | { | 2477 | { |
2633 | stliport_t *portp; | 2478 | struct stliport *portp; |
2634 | unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; | 2479 | unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; |
2635 | unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; | 2480 | unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; |
2636 | unsigned char __iomem *slavep; | 2481 | unsigned char __iomem *slavep; |
@@ -2697,11 +2542,10 @@ static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) | |||
2697 | static void stli_poll(unsigned long arg) | 2542 | static void stli_poll(unsigned long arg) |
2698 | { | 2543 | { |
2699 | cdkhdr_t __iomem *hdrp; | 2544 | cdkhdr_t __iomem *hdrp; |
2700 | stlibrd_t *brdp; | 2545 | struct stlibrd *brdp; |
2701 | int brdnr; | 2546 | unsigned int brdnr; |
2702 | 2547 | ||
2703 | stli_timerlist.expires = STLI_TIMEOUT; | 2548 | mod_timer(&stli_timerlist, STLI_TIMEOUT); |
2704 | add_timer(&stli_timerlist); | ||
2705 | 2549 | ||
2706 | /* | 2550 | /* |
2707 | * Check each board and do any servicing required. | 2551 | * Check each board and do any servicing required. |
@@ -2730,7 +2574,7 @@ static void stli_poll(unsigned long arg) | |||
2730 | * the slave. | 2574 | * the slave. |
2731 | */ | 2575 | */ |
2732 | 2576 | ||
2733 | static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp) | 2577 | static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermios *tiosp) |
2734 | { | 2578 | { |
2735 | memset(pp, 0, sizeof(asyport_t)); | 2579 | memset(pp, 0, sizeof(asyport_t)); |
2736 | 2580 | ||
@@ -2879,13 +2723,13 @@ static long stli_mktiocm(unsigned long sigvalue) | |||
2879 | * we need to do here is set up the appropriate per port data structures. | 2723 | * we need to do here is set up the appropriate per port data structures. |
2880 | */ | 2724 | */ |
2881 | 2725 | ||
2882 | static int stli_initports(stlibrd_t *brdp) | 2726 | static int stli_initports(struct stlibrd *brdp) |
2883 | { | 2727 | { |
2884 | stliport_t *portp; | 2728 | struct stliport *portp; |
2885 | int i, panelnr, panelport; | 2729 | unsigned int i, panelnr, panelport; |
2886 | 2730 | ||
2887 | for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { | 2731 | for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { |
2888 | portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); | 2732 | portp = kzalloc(sizeof(struct stliport), GFP_KERNEL); |
2889 | if (!portp) { | 2733 | if (!portp) { |
2890 | printk("STALLION: failed to allocate port structure\n"); | 2734 | printk("STALLION: failed to allocate port structure\n"); |
2891 | continue; | 2735 | continue; |
@@ -2919,7 +2763,7 @@ static int stli_initports(stlibrd_t *brdp) | |||
2919 | * All the following routines are board specific hardware operations. | 2763 | * All the following routines are board specific hardware operations. |
2920 | */ | 2764 | */ |
2921 | 2765 | ||
2922 | static void stli_ecpinit(stlibrd_t *brdp) | 2766 | static void stli_ecpinit(struct stlibrd *brdp) |
2923 | { | 2767 | { |
2924 | unsigned long memconf; | 2768 | unsigned long memconf; |
2925 | 2769 | ||
@@ -2934,21 +2778,21 @@ static void stli_ecpinit(stlibrd_t *brdp) | |||
2934 | 2778 | ||
2935 | /*****************************************************************************/ | 2779 | /*****************************************************************************/ |
2936 | 2780 | ||
2937 | static void stli_ecpenable(stlibrd_t *brdp) | 2781 | static void stli_ecpenable(struct stlibrd *brdp) |
2938 | { | 2782 | { |
2939 | outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); | 2783 | outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); |
2940 | } | 2784 | } |
2941 | 2785 | ||
2942 | /*****************************************************************************/ | 2786 | /*****************************************************************************/ |
2943 | 2787 | ||
2944 | static void stli_ecpdisable(stlibrd_t *brdp) | 2788 | static void stli_ecpdisable(struct stlibrd *brdp) |
2945 | { | 2789 | { |
2946 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); | 2790 | outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); |
2947 | } | 2791 | } |
2948 | 2792 | ||
2949 | /*****************************************************************************/ | 2793 | /*****************************************************************************/ |
2950 | 2794 | ||
2951 | static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 2795 | static void __iomem *stli_ecpgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
2952 | { | 2796 | { |
2953 | void __iomem *ptr; | 2797 | void __iomem *ptr; |
2954 | unsigned char val; | 2798 | unsigned char val; |
@@ -2969,7 +2813,7 @@ static void __iomem *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, in | |||
2969 | 2813 | ||
2970 | /*****************************************************************************/ | 2814 | /*****************************************************************************/ |
2971 | 2815 | ||
2972 | static void stli_ecpreset(stlibrd_t *brdp) | 2816 | static void stli_ecpreset(struct stlibrd *brdp) |
2973 | { | 2817 | { |
2974 | outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); | 2818 | outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); |
2975 | udelay(10); | 2819 | udelay(10); |
@@ -2979,7 +2823,7 @@ static void stli_ecpreset(stlibrd_t *brdp) | |||
2979 | 2823 | ||
2980 | /*****************************************************************************/ | 2824 | /*****************************************************************************/ |
2981 | 2825 | ||
2982 | static void stli_ecpintr(stlibrd_t *brdp) | 2826 | static void stli_ecpintr(struct stlibrd *brdp) |
2983 | { | 2827 | { |
2984 | outb(0x1, brdp->iobase); | 2828 | outb(0x1, brdp->iobase); |
2985 | } | 2829 | } |
@@ -2990,7 +2834,7 @@ static void stli_ecpintr(stlibrd_t *brdp) | |||
2990 | * The following set of functions act on ECP EISA boards. | 2834 | * The following set of functions act on ECP EISA boards. |
2991 | */ | 2835 | */ |
2992 | 2836 | ||
2993 | static void stli_ecpeiinit(stlibrd_t *brdp) | 2837 | static void stli_ecpeiinit(struct stlibrd *brdp) |
2994 | { | 2838 | { |
2995 | unsigned long memconf; | 2839 | unsigned long memconf; |
2996 | 2840 | ||
@@ -3008,21 +2852,21 @@ static void stli_ecpeiinit(stlibrd_t *brdp) | |||
3008 | 2852 | ||
3009 | /*****************************************************************************/ | 2853 | /*****************************************************************************/ |
3010 | 2854 | ||
3011 | static void stli_ecpeienable(stlibrd_t *brdp) | 2855 | static void stli_ecpeienable(struct stlibrd *brdp) |
3012 | { | 2856 | { |
3013 | outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR)); | 2857 | outb(ECP_EIENABLE, (brdp->iobase + ECP_EICONFR)); |
3014 | } | 2858 | } |
3015 | 2859 | ||
3016 | /*****************************************************************************/ | 2860 | /*****************************************************************************/ |
3017 | 2861 | ||
3018 | static void stli_ecpeidisable(stlibrd_t *brdp) | 2862 | static void stli_ecpeidisable(struct stlibrd *brdp) |
3019 | { | 2863 | { |
3020 | outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); | 2864 | outb(ECP_EIDISABLE, (brdp->iobase + ECP_EICONFR)); |
3021 | } | 2865 | } |
3022 | 2866 | ||
3023 | /*****************************************************************************/ | 2867 | /*****************************************************************************/ |
3024 | 2868 | ||
3025 | static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 2869 | static void __iomem *stli_ecpeigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3026 | { | 2870 | { |
3027 | void __iomem *ptr; | 2871 | void __iomem *ptr; |
3028 | unsigned char val; | 2872 | unsigned char val; |
@@ -3046,7 +2890,7 @@ static void __iomem *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, | |||
3046 | 2890 | ||
3047 | /*****************************************************************************/ | 2891 | /*****************************************************************************/ |
3048 | 2892 | ||
3049 | static void stli_ecpeireset(stlibrd_t *brdp) | 2893 | static void stli_ecpeireset(struct stlibrd *brdp) |
3050 | { | 2894 | { |
3051 | outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); | 2895 | outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); |
3052 | udelay(10); | 2896 | udelay(10); |
@@ -3060,21 +2904,21 @@ static void stli_ecpeireset(stlibrd_t *brdp) | |||
3060 | * The following set of functions act on ECP MCA boards. | 2904 | * The following set of functions act on ECP MCA boards. |
3061 | */ | 2905 | */ |
3062 | 2906 | ||
3063 | static void stli_ecpmcenable(stlibrd_t *brdp) | 2907 | static void stli_ecpmcenable(struct stlibrd *brdp) |
3064 | { | 2908 | { |
3065 | outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR)); | 2909 | outb(ECP_MCENABLE, (brdp->iobase + ECP_MCCONFR)); |
3066 | } | 2910 | } |
3067 | 2911 | ||
3068 | /*****************************************************************************/ | 2912 | /*****************************************************************************/ |
3069 | 2913 | ||
3070 | static void stli_ecpmcdisable(stlibrd_t *brdp) | 2914 | static void stli_ecpmcdisable(struct stlibrd *brdp) |
3071 | { | 2915 | { |
3072 | outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); | 2916 | outb(ECP_MCDISABLE, (brdp->iobase + ECP_MCCONFR)); |
3073 | } | 2917 | } |
3074 | 2918 | ||
3075 | /*****************************************************************************/ | 2919 | /*****************************************************************************/ |
3076 | 2920 | ||
3077 | static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 2921 | static void __iomem *stli_ecpmcgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3078 | { | 2922 | { |
3079 | void __iomem *ptr; | 2923 | void __iomem *ptr; |
3080 | unsigned char val; | 2924 | unsigned char val; |
@@ -3095,7 +2939,7 @@ static void __iomem *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, | |||
3095 | 2939 | ||
3096 | /*****************************************************************************/ | 2940 | /*****************************************************************************/ |
3097 | 2941 | ||
3098 | static void stli_ecpmcreset(stlibrd_t *brdp) | 2942 | static void stli_ecpmcreset(struct stlibrd *brdp) |
3099 | { | 2943 | { |
3100 | outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR)); | 2944 | outb(ECP_MCSTOP, (brdp->iobase + ECP_MCCONFR)); |
3101 | udelay(10); | 2945 | udelay(10); |
@@ -3109,7 +2953,7 @@ static void stli_ecpmcreset(stlibrd_t *brdp) | |||
3109 | * The following set of functions act on ECP PCI boards. | 2953 | * The following set of functions act on ECP PCI boards. |
3110 | */ | 2954 | */ |
3111 | 2955 | ||
3112 | static void stli_ecppciinit(stlibrd_t *brdp) | 2956 | static void stli_ecppciinit(struct stlibrd *brdp) |
3113 | { | 2957 | { |
3114 | outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); | 2958 | outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); |
3115 | udelay(10); | 2959 | udelay(10); |
@@ -3119,7 +2963,7 @@ static void stli_ecppciinit(stlibrd_t *brdp) | |||
3119 | 2963 | ||
3120 | /*****************************************************************************/ | 2964 | /*****************************************************************************/ |
3121 | 2965 | ||
3122 | static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 2966 | static void __iomem *stli_ecppcigetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3123 | { | 2967 | { |
3124 | void __iomem *ptr; | 2968 | void __iomem *ptr; |
3125 | unsigned char val; | 2969 | unsigned char val; |
@@ -3140,7 +2984,7 @@ static void __iomem *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, | |||
3140 | 2984 | ||
3141 | /*****************************************************************************/ | 2985 | /*****************************************************************************/ |
3142 | 2986 | ||
3143 | static void stli_ecppcireset(stlibrd_t *brdp) | 2987 | static void stli_ecppcireset(struct stlibrd *brdp) |
3144 | { | 2988 | { |
3145 | outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); | 2989 | outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); |
3146 | udelay(10); | 2990 | udelay(10); |
@@ -3154,7 +2998,7 @@ static void stli_ecppcireset(stlibrd_t *brdp) | |||
3154 | * The following routines act on ONboards. | 2998 | * The following routines act on ONboards. |
3155 | */ | 2999 | */ |
3156 | 3000 | ||
3157 | static void stli_onbinit(stlibrd_t *brdp) | 3001 | static void stli_onbinit(struct stlibrd *brdp) |
3158 | { | 3002 | { |
3159 | unsigned long memconf; | 3003 | unsigned long memconf; |
3160 | 3004 | ||
@@ -3171,21 +3015,21 @@ static void stli_onbinit(stlibrd_t *brdp) | |||
3171 | 3015 | ||
3172 | /*****************************************************************************/ | 3016 | /*****************************************************************************/ |
3173 | 3017 | ||
3174 | static void stli_onbenable(stlibrd_t *brdp) | 3018 | static void stli_onbenable(struct stlibrd *brdp) |
3175 | { | 3019 | { |
3176 | outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); | 3020 | outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); |
3177 | } | 3021 | } |
3178 | 3022 | ||
3179 | /*****************************************************************************/ | 3023 | /*****************************************************************************/ |
3180 | 3024 | ||
3181 | static void stli_onbdisable(stlibrd_t *brdp) | 3025 | static void stli_onbdisable(struct stlibrd *brdp) |
3182 | { | 3026 | { |
3183 | outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); | 3027 | outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); |
3184 | } | 3028 | } |
3185 | 3029 | ||
3186 | /*****************************************************************************/ | 3030 | /*****************************************************************************/ |
3187 | 3031 | ||
3188 | static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3032 | static void __iomem *stli_onbgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3189 | { | 3033 | { |
3190 | void __iomem *ptr; | 3034 | void __iomem *ptr; |
3191 | 3035 | ||
@@ -3202,7 +3046,7 @@ static void __iomem *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, in | |||
3202 | 3046 | ||
3203 | /*****************************************************************************/ | 3047 | /*****************************************************************************/ |
3204 | 3048 | ||
3205 | static void stli_onbreset(stlibrd_t *brdp) | 3049 | static void stli_onbreset(struct stlibrd *brdp) |
3206 | { | 3050 | { |
3207 | outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); | 3051 | outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); |
3208 | udelay(10); | 3052 | udelay(10); |
@@ -3216,7 +3060,7 @@ static void stli_onbreset(stlibrd_t *brdp) | |||
3216 | * The following routines act on ONboard EISA. | 3060 | * The following routines act on ONboard EISA. |
3217 | */ | 3061 | */ |
3218 | 3062 | ||
3219 | static void stli_onbeinit(stlibrd_t *brdp) | 3063 | static void stli_onbeinit(struct stlibrd *brdp) |
3220 | { | 3064 | { |
3221 | unsigned long memconf; | 3065 | unsigned long memconf; |
3222 | 3066 | ||
@@ -3236,21 +3080,21 @@ static void stli_onbeinit(stlibrd_t *brdp) | |||
3236 | 3080 | ||
3237 | /*****************************************************************************/ | 3081 | /*****************************************************************************/ |
3238 | 3082 | ||
3239 | static void stli_onbeenable(stlibrd_t *brdp) | 3083 | static void stli_onbeenable(struct stlibrd *brdp) |
3240 | { | 3084 | { |
3241 | outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); | 3085 | outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); |
3242 | } | 3086 | } |
3243 | 3087 | ||
3244 | /*****************************************************************************/ | 3088 | /*****************************************************************************/ |
3245 | 3089 | ||
3246 | static void stli_onbedisable(stlibrd_t *brdp) | 3090 | static void stli_onbedisable(struct stlibrd *brdp) |
3247 | { | 3091 | { |
3248 | outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); | 3092 | outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); |
3249 | } | 3093 | } |
3250 | 3094 | ||
3251 | /*****************************************************************************/ | 3095 | /*****************************************************************************/ |
3252 | 3096 | ||
3253 | static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3097 | static void __iomem *stli_onbegetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3254 | { | 3098 | { |
3255 | void __iomem *ptr; | 3099 | void __iomem *ptr; |
3256 | unsigned char val; | 3100 | unsigned char val; |
@@ -3274,7 +3118,7 @@ static void __iomem *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, i | |||
3274 | 3118 | ||
3275 | /*****************************************************************************/ | 3119 | /*****************************************************************************/ |
3276 | 3120 | ||
3277 | static void stli_onbereset(stlibrd_t *brdp) | 3121 | static void stli_onbereset(struct stlibrd *brdp) |
3278 | { | 3122 | { |
3279 | outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); | 3123 | outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); |
3280 | udelay(10); | 3124 | udelay(10); |
@@ -3288,7 +3132,7 @@ static void stli_onbereset(stlibrd_t *brdp) | |||
3288 | * The following routines act on Brumby boards. | 3132 | * The following routines act on Brumby boards. |
3289 | */ | 3133 | */ |
3290 | 3134 | ||
3291 | static void stli_bbyinit(stlibrd_t *brdp) | 3135 | static void stli_bbyinit(struct stlibrd *brdp) |
3292 | { | 3136 | { |
3293 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); | 3137 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); |
3294 | udelay(10); | 3138 | udelay(10); |
@@ -3300,7 +3144,7 @@ static void stli_bbyinit(stlibrd_t *brdp) | |||
3300 | 3144 | ||
3301 | /*****************************************************************************/ | 3145 | /*****************************************************************************/ |
3302 | 3146 | ||
3303 | static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3147 | static void __iomem *stli_bbygetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3304 | { | 3148 | { |
3305 | void __iomem *ptr; | 3149 | void __iomem *ptr; |
3306 | unsigned char val; | 3150 | unsigned char val; |
@@ -3315,7 +3159,7 @@ static void __iomem *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, in | |||
3315 | 3159 | ||
3316 | /*****************************************************************************/ | 3160 | /*****************************************************************************/ |
3317 | 3161 | ||
3318 | static void stli_bbyreset(stlibrd_t *brdp) | 3162 | static void stli_bbyreset(struct stlibrd *brdp) |
3319 | { | 3163 | { |
3320 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); | 3164 | outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); |
3321 | udelay(10); | 3165 | udelay(10); |
@@ -3329,7 +3173,7 @@ static void stli_bbyreset(stlibrd_t *brdp) | |||
3329 | * The following routines act on original old Stallion boards. | 3173 | * The following routines act on original old Stallion boards. |
3330 | */ | 3174 | */ |
3331 | 3175 | ||
3332 | static void stli_stalinit(stlibrd_t *brdp) | 3176 | static void stli_stalinit(struct stlibrd *brdp) |
3333 | { | 3177 | { |
3334 | outb(0x1, brdp->iobase); | 3178 | outb(0x1, brdp->iobase); |
3335 | mdelay(1000); | 3179 | mdelay(1000); |
@@ -3337,7 +3181,7 @@ static void stli_stalinit(stlibrd_t *brdp) | |||
3337 | 3181 | ||
3338 | /*****************************************************************************/ | 3182 | /*****************************************************************************/ |
3339 | 3183 | ||
3340 | static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) | 3184 | static void __iomem *stli_stalgetmemptr(struct stlibrd *brdp, unsigned long offset, int line) |
3341 | { | 3185 | { |
3342 | BUG_ON(offset > brdp->memsize); | 3186 | BUG_ON(offset > brdp->memsize); |
3343 | return brdp->membase + (offset % STAL_PAGESIZE); | 3187 | return brdp->membase + (offset % STAL_PAGESIZE); |
@@ -3345,7 +3189,7 @@ static void __iomem *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, i | |||
3345 | 3189 | ||
3346 | /*****************************************************************************/ | 3190 | /*****************************************************************************/ |
3347 | 3191 | ||
3348 | static void stli_stalreset(stlibrd_t *brdp) | 3192 | static void stli_stalreset(struct stlibrd *brdp) |
3349 | { | 3193 | { |
3350 | u32 __iomem *vecp; | 3194 | u32 __iomem *vecp; |
3351 | 3195 | ||
@@ -3362,21 +3206,22 @@ static void stli_stalreset(stlibrd_t *brdp) | |||
3362 | * board types. | 3206 | * board types. |
3363 | */ | 3207 | */ |
3364 | 3208 | ||
3365 | static int stli_initecp(stlibrd_t *brdp) | 3209 | static int stli_initecp(struct stlibrd *brdp) |
3366 | { | 3210 | { |
3367 | cdkecpsig_t sig; | 3211 | cdkecpsig_t sig; |
3368 | cdkecpsig_t __iomem *sigsp; | 3212 | cdkecpsig_t __iomem *sigsp; |
3369 | unsigned int status, nxtid; | 3213 | unsigned int status, nxtid; |
3370 | char *name; | 3214 | char *name; |
3371 | int panelnr, nrports; | 3215 | int retval, panelnr, nrports; |
3372 | 3216 | ||
3373 | if (!request_region(brdp->iobase, brdp->iosize, "istallion")) | 3217 | if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { |
3374 | return -EIO; | 3218 | retval = -ENODEV; |
3375 | 3219 | goto err; | |
3376 | if ((brdp->iobase == 0) || (brdp->memaddr == 0)) | 3220 | } |
3377 | { | 3221 | |
3378 | release_region(brdp->iobase, brdp->iosize); | 3222 | if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { |
3379 | return -ENODEV; | 3223 | retval = -EIO; |
3224 | goto err; | ||
3380 | } | 3225 | } |
3381 | 3226 | ||
3382 | brdp->iosize = ECP_IOSIZE; | 3227 | brdp->iosize = ECP_IOSIZE; |
@@ -3388,7 +3233,6 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3388 | */ | 3233 | */ |
3389 | switch (brdp->brdtype) { | 3234 | switch (brdp->brdtype) { |
3390 | case BRD_ECP: | 3235 | case BRD_ECP: |
3391 | brdp->membase = (void *) brdp->memaddr; | ||
3392 | brdp->memsize = ECP_MEMSIZE; | 3236 | brdp->memsize = ECP_MEMSIZE; |
3393 | brdp->pagesize = ECP_ATPAGESIZE; | 3237 | brdp->pagesize = ECP_ATPAGESIZE; |
3394 | brdp->init = stli_ecpinit; | 3238 | brdp->init = stli_ecpinit; |
@@ -3402,7 +3246,6 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3402 | break; | 3246 | break; |
3403 | 3247 | ||
3404 | case BRD_ECPE: | 3248 | case BRD_ECPE: |
3405 | brdp->membase = (void *) brdp->memaddr; | ||
3406 | brdp->memsize = ECP_MEMSIZE; | 3249 | brdp->memsize = ECP_MEMSIZE; |
3407 | brdp->pagesize = ECP_EIPAGESIZE; | 3250 | brdp->pagesize = ECP_EIPAGESIZE; |
3408 | brdp->init = stli_ecpeiinit; | 3251 | brdp->init = stli_ecpeiinit; |
@@ -3416,7 +3259,6 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3416 | break; | 3259 | break; |
3417 | 3260 | ||
3418 | case BRD_ECPMC: | 3261 | case BRD_ECPMC: |
3419 | brdp->membase = (void *) brdp->memaddr; | ||
3420 | brdp->memsize = ECP_MEMSIZE; | 3262 | brdp->memsize = ECP_MEMSIZE; |
3421 | brdp->pagesize = ECP_MCPAGESIZE; | 3263 | brdp->pagesize = ECP_MCPAGESIZE; |
3422 | brdp->init = NULL; | 3264 | brdp->init = NULL; |
@@ -3430,7 +3272,6 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3430 | break; | 3272 | break; |
3431 | 3273 | ||
3432 | case BRD_ECPPCI: | 3274 | case BRD_ECPPCI: |
3433 | brdp->membase = (void *) brdp->memaddr; | ||
3434 | brdp->memsize = ECP_PCIMEMSIZE; | 3275 | brdp->memsize = ECP_PCIMEMSIZE; |
3435 | brdp->pagesize = ECP_PCIPAGESIZE; | 3276 | brdp->pagesize = ECP_PCIPAGESIZE; |
3436 | brdp->init = stli_ecppciinit; | 3277 | brdp->init = stli_ecppciinit; |
@@ -3444,8 +3285,8 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3444 | break; | 3285 | break; |
3445 | 3286 | ||
3446 | default: | 3287 | default: |
3447 | release_region(brdp->iobase, brdp->iosize); | 3288 | retval = -EINVAL; |
3448 | return -EINVAL; | 3289 | goto err_reg; |
3449 | } | 3290 | } |
3450 | 3291 | ||
3451 | /* | 3292 | /* |
@@ -3457,10 +3298,9 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3457 | EBRDINIT(brdp); | 3298 | EBRDINIT(brdp); |
3458 | 3299 | ||
3459 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3300 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); |
3460 | if (brdp->membase == NULL) | 3301 | if (brdp->membase == NULL) { |
3461 | { | 3302 | retval = -ENOMEM; |
3462 | release_region(brdp->iobase, brdp->iosize); | 3303 | goto err_reg; |
3463 | return -ENOMEM; | ||
3464 | } | 3304 | } |
3465 | 3305 | ||
3466 | /* | 3306 | /* |
@@ -3473,10 +3313,9 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3473 | memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); | 3313 | memcpy_fromio(&sig, sigsp, sizeof(cdkecpsig_t)); |
3474 | EBRDDISABLE(brdp); | 3314 | EBRDDISABLE(brdp); |
3475 | 3315 | ||
3476 | if (sig.magic != cpu_to_le32(ECP_MAGIC)) | 3316 | if (sig.magic != cpu_to_le32(ECP_MAGIC)) { |
3477 | { | 3317 | retval = -ENODEV; |
3478 | release_region(brdp->iobase, brdp->iosize); | 3318 | goto err_unmap; |
3479 | return -ENODEV; | ||
3480 | } | 3319 | } |
3481 | 3320 | ||
3482 | /* | 3321 | /* |
@@ -3501,6 +3340,13 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3501 | 3340 | ||
3502 | brdp->state |= BST_FOUND; | 3341 | brdp->state |= BST_FOUND; |
3503 | return 0; | 3342 | return 0; |
3343 | err_unmap: | ||
3344 | iounmap(brdp->membase); | ||
3345 | brdp->membase = NULL; | ||
3346 | err_reg: | ||
3347 | release_region(brdp->iobase, brdp->iosize); | ||
3348 | err: | ||
3349 | return retval; | ||
3504 | } | 3350 | } |
3505 | 3351 | ||
3506 | /*****************************************************************************/ | 3352 | /*****************************************************************************/ |
@@ -3510,23 +3356,27 @@ static int stli_initecp(stlibrd_t *brdp) | |||
3510 | * This handles only these board types. | 3356 | * This handles only these board types. |
3511 | */ | 3357 | */ |
3512 | 3358 | ||
3513 | static int stli_initonb(stlibrd_t *brdp) | 3359 | static int stli_initonb(struct stlibrd *brdp) |
3514 | { | 3360 | { |
3515 | cdkonbsig_t sig; | 3361 | cdkonbsig_t sig; |
3516 | cdkonbsig_t __iomem *sigsp; | 3362 | cdkonbsig_t __iomem *sigsp; |
3517 | char *name; | 3363 | char *name; |
3518 | int i; | 3364 | int i, retval; |
3519 | 3365 | ||
3520 | /* | 3366 | /* |
3521 | * Do a basic sanity check on the IO and memory addresses. | 3367 | * Do a basic sanity check on the IO and memory addresses. |
3522 | */ | 3368 | */ |
3523 | if (brdp->iobase == 0 || brdp->memaddr == 0) | 3369 | if (brdp->iobase == 0 || brdp->memaddr == 0) { |
3524 | return -ENODEV; | 3370 | retval = -ENODEV; |
3371 | goto err; | ||
3372 | } | ||
3525 | 3373 | ||
3526 | brdp->iosize = ONB_IOSIZE; | 3374 | brdp->iosize = ONB_IOSIZE; |
3527 | 3375 | ||
3528 | if (!request_region(brdp->iobase, brdp->iosize, "istallion")) | 3376 | if (!request_region(brdp->iobase, brdp->iosize, "istallion")) { |
3529 | return -EIO; | 3377 | retval = -EIO; |
3378 | goto err; | ||
3379 | } | ||
3530 | 3380 | ||
3531 | /* | 3381 | /* |
3532 | * Based on the specific board type setup the common vars to access | 3382 | * Based on the specific board type setup the common vars to access |
@@ -3535,10 +3385,7 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3535 | */ | 3385 | */ |
3536 | switch (brdp->brdtype) { | 3386 | switch (brdp->brdtype) { |
3537 | case BRD_ONBOARD: | 3387 | case BRD_ONBOARD: |
3538 | case BRD_ONBOARD32: | ||
3539 | case BRD_ONBOARD2: | 3388 | case BRD_ONBOARD2: |
3540 | case BRD_ONBOARD2_32: | ||
3541 | case BRD_ONBOARDRS: | ||
3542 | brdp->memsize = ONB_MEMSIZE; | 3389 | brdp->memsize = ONB_MEMSIZE; |
3543 | brdp->pagesize = ONB_ATPAGESIZE; | 3390 | brdp->pagesize = ONB_ATPAGESIZE; |
3544 | brdp->init = stli_onbinit; | 3391 | brdp->init = stli_onbinit; |
@@ -3569,8 +3416,6 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3569 | break; | 3416 | break; |
3570 | 3417 | ||
3571 | case BRD_BRUMBY4: | 3418 | case BRD_BRUMBY4: |
3572 | case BRD_BRUMBY8: | ||
3573 | case BRD_BRUMBY16: | ||
3574 | brdp->memsize = BBY_MEMSIZE; | 3419 | brdp->memsize = BBY_MEMSIZE; |
3575 | brdp->pagesize = BBY_PAGESIZE; | 3420 | brdp->pagesize = BBY_PAGESIZE; |
3576 | brdp->init = stli_bbyinit; | 3421 | brdp->init = stli_bbyinit; |
@@ -3597,8 +3442,8 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3597 | break; | 3442 | break; |
3598 | 3443 | ||
3599 | default: | 3444 | default: |
3600 | release_region(brdp->iobase, brdp->iosize); | 3445 | retval = -EINVAL; |
3601 | return -EINVAL; | 3446 | goto err_reg; |
3602 | } | 3447 | } |
3603 | 3448 | ||
3604 | /* | 3449 | /* |
@@ -3610,10 +3455,9 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3610 | EBRDINIT(brdp); | 3455 | EBRDINIT(brdp); |
3611 | 3456 | ||
3612 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); | 3457 | brdp->membase = ioremap(brdp->memaddr, brdp->memsize); |
3613 | if (brdp->membase == NULL) | 3458 | if (brdp->membase == NULL) { |
3614 | { | 3459 | retval = -ENOMEM; |
3615 | release_region(brdp->iobase, brdp->iosize); | 3460 | goto err_reg; |
3616 | return -ENOMEM; | ||
3617 | } | 3461 | } |
3618 | 3462 | ||
3619 | /* | 3463 | /* |
@@ -3629,10 +3473,9 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3629 | if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || | 3473 | if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || |
3630 | sig.magic1 != cpu_to_le16(ONB_MAGIC1) || | 3474 | sig.magic1 != cpu_to_le16(ONB_MAGIC1) || |
3631 | sig.magic2 != cpu_to_le16(ONB_MAGIC2) || | 3475 | sig.magic2 != cpu_to_le16(ONB_MAGIC2) || |
3632 | sig.magic3 != cpu_to_le16(ONB_MAGIC3)) | 3476 | sig.magic3 != cpu_to_le16(ONB_MAGIC3)) { |
3633 | { | 3477 | retval = -ENODEV; |
3634 | release_region(brdp->iobase, brdp->iosize); | 3478 | goto err_unmap; |
3635 | return -ENODEV; | ||
3636 | } | 3479 | } |
3637 | 3480 | ||
3638 | /* | 3481 | /* |
@@ -3654,6 +3497,13 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3654 | 3497 | ||
3655 | brdp->state |= BST_FOUND; | 3498 | brdp->state |= BST_FOUND; |
3656 | return 0; | 3499 | return 0; |
3500 | err_unmap: | ||
3501 | iounmap(brdp->membase); | ||
3502 | brdp->membase = NULL; | ||
3503 | err_reg: | ||
3504 | release_region(brdp->iobase, brdp->iosize); | ||
3505 | err: | ||
3506 | return retval; | ||
3657 | } | 3507 | } |
3658 | 3508 | ||
3659 | /*****************************************************************************/ | 3509 | /*****************************************************************************/ |
@@ -3664,14 +3514,15 @@ static int stli_initonb(stlibrd_t *brdp) | |||
3664 | * read in the memory map, and get the show on the road... | 3514 | * read in the memory map, and get the show on the road... |
3665 | */ | 3515 | */ |
3666 | 3516 | ||
3667 | static int stli_startbrd(stlibrd_t *brdp) | 3517 | static int stli_startbrd(struct stlibrd *brdp) |
3668 | { | 3518 | { |
3669 | cdkhdr_t __iomem *hdrp; | 3519 | cdkhdr_t __iomem *hdrp; |
3670 | cdkmem_t __iomem *memp; | 3520 | cdkmem_t __iomem *memp; |
3671 | cdkasy_t __iomem *ap; | 3521 | cdkasy_t __iomem *ap; |
3672 | unsigned long flags; | 3522 | unsigned long flags; |
3673 | stliport_t *portp; | 3523 | unsigned int portnr, nrdevs, i; |
3674 | int portnr, nrdevs, i, rc = 0; | 3524 | struct stliport *portp; |
3525 | int rc = 0; | ||
3675 | u32 memoff; | 3526 | u32 memoff; |
3676 | 3527 | ||
3677 | spin_lock_irqsave(&brd_lock, flags); | 3528 | spin_lock_irqsave(&brd_lock, flags); |
@@ -3758,8 +3609,7 @@ stli_donestartup: | |||
3758 | 3609 | ||
3759 | if (! stli_timeron) { | 3610 | if (! stli_timeron) { |
3760 | stli_timeron++; | 3611 | stli_timeron++; |
3761 | stli_timerlist.expires = STLI_TIMEOUT; | 3612 | mod_timer(&stli_timerlist, STLI_TIMEOUT); |
3762 | add_timer(&stli_timerlist); | ||
3763 | } | 3613 | } |
3764 | 3614 | ||
3765 | return rc; | 3615 | return rc; |
@@ -3771,49 +3621,32 @@ stli_donestartup: | |||
3771 | * Probe and initialize the specified board. | 3621 | * Probe and initialize the specified board. |
3772 | */ | 3622 | */ |
3773 | 3623 | ||
3774 | static int __init stli_brdinit(stlibrd_t *brdp) | 3624 | static int __devinit stli_brdinit(struct stlibrd *brdp) |
3775 | { | 3625 | { |
3776 | stli_brds[brdp->brdnr] = brdp; | 3626 | int retval; |
3777 | 3627 | ||
3778 | switch (brdp->brdtype) { | 3628 | switch (brdp->brdtype) { |
3779 | case BRD_ECP: | 3629 | case BRD_ECP: |
3780 | case BRD_ECPE: | 3630 | case BRD_ECPE: |
3781 | case BRD_ECPMC: | 3631 | case BRD_ECPMC: |
3782 | case BRD_ECPPCI: | 3632 | case BRD_ECPPCI: |
3783 | stli_initecp(brdp); | 3633 | retval = stli_initecp(brdp); |
3784 | break; | 3634 | break; |
3785 | case BRD_ONBOARD: | 3635 | case BRD_ONBOARD: |
3786 | case BRD_ONBOARDE: | 3636 | case BRD_ONBOARDE: |
3787 | case BRD_ONBOARD2: | 3637 | case BRD_ONBOARD2: |
3788 | case BRD_ONBOARD32: | ||
3789 | case BRD_ONBOARD2_32: | ||
3790 | case BRD_ONBOARDRS: | ||
3791 | case BRD_BRUMBY4: | 3638 | case BRD_BRUMBY4: |
3792 | case BRD_BRUMBY8: | ||
3793 | case BRD_BRUMBY16: | ||
3794 | case BRD_STALLION: | 3639 | case BRD_STALLION: |
3795 | stli_initonb(brdp); | 3640 | retval = stli_initonb(brdp); |
3796 | break; | 3641 | break; |
3797 | case BRD_EASYIO: | ||
3798 | case BRD_ECH: | ||
3799 | case BRD_ECHMC: | ||
3800 | case BRD_ECHPCI: | ||
3801 | printk(KERN_ERR "STALLION: %s board type not supported in " | ||
3802 | "this driver\n", stli_brdnames[brdp->brdtype]); | ||
3803 | return -ENODEV; | ||
3804 | default: | 3642 | default: |
3805 | printk(KERN_ERR "STALLION: board=%d is unknown board " | 3643 | printk(KERN_ERR "STALLION: board=%d is unknown board " |
3806 | "type=%d\n", brdp->brdnr, brdp->brdtype); | 3644 | "type=%d\n", brdp->brdnr, brdp->brdtype); |
3807 | return -ENODEV; | 3645 | retval = -ENODEV; |
3808 | } | 3646 | } |
3809 | 3647 | ||
3810 | if ((brdp->state & BST_FOUND) == 0) { | 3648 | if (retval) |
3811 | printk(KERN_ERR "STALLION: %s board not found, board=%d " | 3649 | return retval; |
3812 | "io=%x mem=%x\n", | ||
3813 | stli_brdnames[brdp->brdtype], brdp->brdnr, | ||
3814 | brdp->iobase, (int) brdp->memaddr); | ||
3815 | return -ENODEV; | ||
3816 | } | ||
3817 | 3650 | ||
3818 | stli_initports(brdp); | 3651 | stli_initports(brdp); |
3819 | printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x " | 3652 | printk(KERN_INFO "STALLION: %s found, board=%d io=%x mem=%x " |
@@ -3823,6 +3656,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) | |||
3823 | return 0; | 3656 | return 0; |
3824 | } | 3657 | } |
3825 | 3658 | ||
3659 | #if STLI_EISAPROBE != 0 | ||
3826 | /*****************************************************************************/ | 3660 | /*****************************************************************************/ |
3827 | 3661 | ||
3828 | /* | 3662 | /* |
@@ -3830,7 +3664,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) | |||
3830 | * might be. This is a bit if hack, but it is the best we can do. | 3664 | * might be. This is a bit if hack, but it is the best we can do. |
3831 | */ | 3665 | */ |
3832 | 3666 | ||
3833 | static int stli_eisamemprobe(stlibrd_t *brdp) | 3667 | static int stli_eisamemprobe(struct stlibrd *brdp) |
3834 | { | 3668 | { |
3835 | cdkecpsig_t ecpsig, __iomem *ecpsigp; | 3669 | cdkecpsig_t ecpsig, __iomem *ecpsigp; |
3836 | cdkonbsig_t onbsig, __iomem *onbsigp; | 3670 | cdkonbsig_t onbsig, __iomem *onbsigp; |
@@ -3916,10 +3750,11 @@ static int stli_eisamemprobe(stlibrd_t *brdp) | |||
3916 | } | 3750 | } |
3917 | return 0; | 3751 | return 0; |
3918 | } | 3752 | } |
3753 | #endif | ||
3919 | 3754 | ||
3920 | static int stli_getbrdnr(void) | 3755 | static int stli_getbrdnr(void) |
3921 | { | 3756 | { |
3922 | int i; | 3757 | unsigned int i; |
3923 | 3758 | ||
3924 | for (i = 0; i < STL_MAXBRDS; i++) { | 3759 | for (i = 0; i < STL_MAXBRDS; i++) { |
3925 | if (!stli_brds[i]) { | 3760 | if (!stli_brds[i]) { |
@@ -3931,6 +3766,7 @@ static int stli_getbrdnr(void) | |||
3931 | return -1; | 3766 | return -1; |
3932 | } | 3767 | } |
3933 | 3768 | ||
3769 | #if STLI_EISAPROBE != 0 | ||
3934 | /*****************************************************************************/ | 3770 | /*****************************************************************************/ |
3935 | 3771 | ||
3936 | /* | 3772 | /* |
@@ -3945,9 +3781,9 @@ static int stli_getbrdnr(void) | |||
3945 | 3781 | ||
3946 | static int stli_findeisabrds(void) | 3782 | static int stli_findeisabrds(void) |
3947 | { | 3783 | { |
3948 | stlibrd_t *brdp; | 3784 | struct stlibrd *brdp; |
3949 | unsigned int iobase, eid; | 3785 | unsigned int iobase, eid, i; |
3950 | int i; | 3786 | int brdnr, found = 0; |
3951 | 3787 | ||
3952 | /* | 3788 | /* |
3953 | * Firstly check if this is an EISA system. If this is not an EISA system then | 3789 | * Firstly check if this is an EISA system. If this is not an EISA system then |
@@ -3985,9 +3821,11 @@ static int stli_findeisabrds(void) | |||
3985 | * Allocate a board structure and initialize it. | 3821 | * Allocate a board structure and initialize it. |
3986 | */ | 3822 | */ |
3987 | if ((brdp = stli_allocbrd()) == NULL) | 3823 | if ((brdp = stli_allocbrd()) == NULL) |
3988 | return -ENOMEM; | 3824 | return found ? : -ENOMEM; |
3989 | if ((brdp->brdnr = stli_getbrdnr()) < 0) | 3825 | brdnr = stli_getbrdnr(); |
3990 | return -ENOMEM; | 3826 | if (brdnr < 0) |
3827 | return found ? : -ENOMEM; | ||
3828 | brdp->brdnr = (unsigned int)brdnr; | ||
3991 | eid = inb(iobase + 0xc82); | 3829 | eid = inb(iobase + 0xc82); |
3992 | if (eid == ECP_EISAID) | 3830 | if (eid == ECP_EISAID) |
3993 | brdp->brdtype = BRD_ECPE; | 3831 | brdp->brdtype = BRD_ECPE; |
@@ -3999,11 +3837,24 @@ static int stli_findeisabrds(void) | |||
3999 | outb(0x1, (iobase + 0xc84)); | 3837 | outb(0x1, (iobase + 0xc84)); |
4000 | if (stli_eisamemprobe(brdp)) | 3838 | if (stli_eisamemprobe(brdp)) |
4001 | outb(0, (iobase + 0xc84)); | 3839 | outb(0, (iobase + 0xc84)); |
4002 | stli_brdinit(brdp); | 3840 | if (stli_brdinit(brdp) < 0) { |
3841 | kfree(brdp); | ||
3842 | continue; | ||
3843 | } | ||
3844 | |||
3845 | stli_brds[brdp->brdnr] = brdp; | ||
3846 | found++; | ||
3847 | |||
3848 | for (i = 0; i < brdp->nrports; i++) | ||
3849 | tty_register_device(stli_serial, | ||
3850 | brdp->brdnr * STL_MAXPORTS + i, NULL); | ||
4003 | } | 3851 | } |
4004 | 3852 | ||
4005 | return 0; | 3853 | return found; |
4006 | } | 3854 | } |
3855 | #else | ||
3856 | static inline int stli_findeisabrds(void) { return 0; } | ||
3857 | #endif | ||
4007 | 3858 | ||
4008 | /*****************************************************************************/ | 3859 | /*****************************************************************************/ |
4009 | 3860 | ||
@@ -4013,72 +3864,104 @@ static int stli_findeisabrds(void) | |||
4013 | 3864 | ||
4014 | /*****************************************************************************/ | 3865 | /*****************************************************************************/ |
4015 | 3866 | ||
4016 | #ifdef CONFIG_PCI | ||
4017 | |||
4018 | /* | 3867 | /* |
4019 | * We have a Stallion board. Allocate a board structure and | 3868 | * We have a Stallion board. Allocate a board structure and |
4020 | * initialize it. Read its IO and MEMORY resources from PCI | 3869 | * initialize it. Read its IO and MEMORY resources from PCI |
4021 | * configuration space. | 3870 | * configuration space. |
4022 | */ | 3871 | */ |
4023 | 3872 | ||
4024 | static int stli_initpcibrd(int brdtype, struct pci_dev *devp) | 3873 | static int __devinit stli_pciprobe(struct pci_dev *pdev, |
3874 | const struct pci_device_id *ent) | ||
4025 | { | 3875 | { |
4026 | stlibrd_t *brdp; | 3876 | struct stlibrd *brdp; |
4027 | 3877 | unsigned int i; | |
4028 | if (pci_enable_device(devp)) | 3878 | int brdnr, retval = -EIO; |
4029 | return -EIO; | 3879 | |
4030 | if ((brdp = stli_allocbrd()) == NULL) | 3880 | retval = pci_enable_device(pdev); |
4031 | return -ENOMEM; | 3881 | if (retval) |
4032 | if ((brdp->brdnr = stli_getbrdnr()) < 0) { | 3882 | goto err; |
3883 | brdp = stli_allocbrd(); | ||
3884 | if (brdp == NULL) { | ||
3885 | retval = -ENOMEM; | ||
3886 | goto err; | ||
3887 | } | ||
3888 | mutex_lock(&stli_brdslock); | ||
3889 | brdnr = stli_getbrdnr(); | ||
3890 | if (brdnr < 0) { | ||
4033 | printk(KERN_INFO "STALLION: too many boards found, " | 3891 | printk(KERN_INFO "STALLION: too many boards found, " |
4034 | "maximum supported %d\n", STL_MAXBRDS); | 3892 | "maximum supported %d\n", STL_MAXBRDS); |
4035 | return 0; | 3893 | mutex_unlock(&stli_brdslock); |
3894 | retval = -EIO; | ||
3895 | goto err_fr; | ||
4036 | } | 3896 | } |
4037 | brdp->brdtype = brdtype; | 3897 | brdp->brdnr = (unsigned int)brdnr; |
3898 | stli_brds[brdp->brdnr] = brdp; | ||
3899 | mutex_unlock(&stli_brdslock); | ||
3900 | brdp->brdtype = BRD_ECPPCI; | ||
4038 | /* | 3901 | /* |
4039 | * We have all resources from the board, so lets setup the actual | 3902 | * We have all resources from the board, so lets setup the actual |
4040 | * board structure now. | 3903 | * board structure now. |
4041 | */ | 3904 | */ |
4042 | brdp->iobase = pci_resource_start(devp, 3); | 3905 | brdp->iobase = pci_resource_start(pdev, 3); |
4043 | brdp->memaddr = pci_resource_start(devp, 2); | 3906 | brdp->memaddr = pci_resource_start(pdev, 2); |
4044 | stli_brdinit(brdp); | 3907 | retval = stli_brdinit(brdp); |
3908 | if (retval) | ||
3909 | goto err_null; | ||
3910 | |||
3911 | brdp->state |= BST_PROBED; | ||
3912 | pci_set_drvdata(pdev, brdp); | ||
3913 | |||
3914 | EBRDENABLE(brdp); | ||
3915 | brdp->enable = NULL; | ||
3916 | brdp->disable = NULL; | ||
3917 | |||
3918 | for (i = 0; i < brdp->nrports; i++) | ||
3919 | tty_register_device(stli_serial, brdp->brdnr * STL_MAXPORTS + i, | ||
3920 | &pdev->dev); | ||
4045 | 3921 | ||
4046 | return 0; | 3922 | return 0; |
3923 | err_null: | ||
3924 | stli_brds[brdp->brdnr] = NULL; | ||
3925 | err_fr: | ||
3926 | kfree(brdp); | ||
3927 | err: | ||
3928 | return retval; | ||
4047 | } | 3929 | } |
4048 | 3930 | ||
4049 | /*****************************************************************************/ | 3931 | static void stli_pciremove(struct pci_dev *pdev) |
3932 | { | ||
3933 | struct stlibrd *brdp = pci_get_drvdata(pdev); | ||
4050 | 3934 | ||
4051 | /* | 3935 | stli_cleanup_ports(brdp); |
4052 | * Find all Stallion PCI boards that might be installed. Initialize each | ||
4053 | * one as it is found. | ||
4054 | */ | ||
4055 | 3936 | ||
4056 | static int stli_findpcibrds(void) | 3937 | iounmap(brdp->membase); |
4057 | { | 3938 | if (brdp->iosize > 0) |
4058 | struct pci_dev *dev = NULL; | 3939 | release_region(brdp->iobase, brdp->iosize); |
4059 | 3940 | ||
4060 | while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) { | 3941 | stli_brds[brdp->brdnr] = NULL; |
4061 | stli_initpcibrd(BRD_ECPPCI, dev); | 3942 | kfree(brdp); |
4062 | } | ||
4063 | return 0; | ||
4064 | } | 3943 | } |
4065 | 3944 | ||
4066 | #endif | 3945 | static struct pci_driver stli_pcidriver = { |
4067 | 3946 | .name = "istallion", | |
3947 | .id_table = istallion_pci_tbl, | ||
3948 | .probe = stli_pciprobe, | ||
3949 | .remove = __devexit_p(stli_pciremove) | ||
3950 | }; | ||
4068 | /*****************************************************************************/ | 3951 | /*****************************************************************************/ |
4069 | 3952 | ||
4070 | /* | 3953 | /* |
4071 | * Allocate a new board structure. Fill out the basic info in it. | 3954 | * Allocate a new board structure. Fill out the basic info in it. |
4072 | */ | 3955 | */ |
4073 | 3956 | ||
4074 | static stlibrd_t *stli_allocbrd(void) | 3957 | static struct stlibrd *stli_allocbrd(void) |
4075 | { | 3958 | { |
4076 | stlibrd_t *brdp; | 3959 | struct stlibrd *brdp; |
4077 | 3960 | ||
4078 | brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); | 3961 | brdp = kzalloc(sizeof(struct stlibrd), GFP_KERNEL); |
4079 | if (!brdp) { | 3962 | if (!brdp) { |
4080 | printk(KERN_ERR "STALLION: failed to allocate memory " | 3963 | printk(KERN_ERR "STALLION: failed to allocate memory " |
4081 | "(size=%Zd)\n", sizeof(stlibrd_t)); | 3964 | "(size=%Zd)\n", sizeof(struct stlibrd)); |
4082 | return NULL; | 3965 | return NULL; |
4083 | } | 3966 | } |
4084 | brdp->magic = STLI_BOARDMAGIC; | 3967 | brdp->magic = STLI_BOARDMAGIC; |
@@ -4094,43 +3977,37 @@ static stlibrd_t *stli_allocbrd(void) | |||
4094 | 3977 | ||
4095 | static int stli_initbrds(void) | 3978 | static int stli_initbrds(void) |
4096 | { | 3979 | { |
4097 | stlibrd_t *brdp, *nxtbrdp; | 3980 | struct stlibrd *brdp, *nxtbrdp; |
4098 | stlconf_t *confp; | 3981 | struct stlconf conf; |
4099 | int i, j; | 3982 | unsigned int i, j, found = 0; |
4100 | 3983 | int retval; | |
4101 | if (stli_nrbrds > STL_MAXBRDS) { | ||
4102 | printk(KERN_INFO "STALLION: too many boards in configuration " | ||
4103 | "table, truncating to %d\n", STL_MAXBRDS); | ||
4104 | stli_nrbrds = STL_MAXBRDS; | ||
4105 | } | ||
4106 | 3984 | ||
4107 | /* | 3985 | for (stli_nrbrds = 0; stli_nrbrds < ARRAY_SIZE(stli_brdsp); |
4108 | * Firstly scan the list of static boards configured. Allocate | 3986 | stli_nrbrds++) { |
4109 | * resources and initialize the boards as found. If this is a | 3987 | memset(&conf, 0, sizeof(conf)); |
4110 | * module then let the module args override static configuration. | 3988 | if (stli_parsebrd(&conf, stli_brdsp[stli_nrbrds]) == 0) |
4111 | */ | 3989 | continue; |
4112 | for (i = 0; (i < stli_nrbrds); i++) { | ||
4113 | confp = &stli_brdconf[i]; | ||
4114 | stli_parsebrd(confp, stli_brdsp[i]); | ||
4115 | if ((brdp = stli_allocbrd()) == NULL) | 3990 | if ((brdp = stli_allocbrd()) == NULL) |
4116 | return -ENOMEM; | 3991 | continue; |
4117 | brdp->brdnr = i; | 3992 | brdp->brdnr = stli_nrbrds; |
4118 | brdp->brdtype = confp->brdtype; | 3993 | brdp->brdtype = conf.brdtype; |
4119 | brdp->iobase = confp->ioaddr1; | 3994 | brdp->iobase = conf.ioaddr1; |
4120 | brdp->memaddr = confp->memaddr; | 3995 | brdp->memaddr = conf.memaddr; |
4121 | stli_brdinit(brdp); | 3996 | if (stli_brdinit(brdp) < 0) { |
3997 | kfree(brdp); | ||
3998 | continue; | ||
3999 | } | ||
4000 | stli_brds[brdp->brdnr] = brdp; | ||
4001 | found++; | ||
4002 | |||
4003 | for (i = 0; i < brdp->nrports; i++) | ||
4004 | tty_register_device(stli_serial, | ||
4005 | brdp->brdnr * STL_MAXPORTS + i, NULL); | ||
4122 | } | 4006 | } |
4123 | 4007 | ||
4124 | /* | 4008 | retval = stli_findeisabrds(); |
4125 | * Static configuration table done, so now use dynamic methods to | 4009 | if (retval > 0) |
4126 | * see if any more boards should be configured. | 4010 | found += retval; |
4127 | */ | ||
4128 | stli_argbrds(); | ||
4129 | if (STLI_EISAPROBE) | ||
4130 | stli_findeisabrds(); | ||
4131 | #ifdef CONFIG_PCI | ||
4132 | stli_findpcibrds(); | ||
4133 | #endif | ||
4134 | 4011 | ||
4135 | /* | 4012 | /* |
4136 | * All found boards are initialized. Now for a little optimization, if | 4013 | * All found boards are initialized. Now for a little optimization, if |
@@ -4170,7 +4047,16 @@ static int stli_initbrds(void) | |||
4170 | } | 4047 | } |
4171 | } | 4048 | } |
4172 | 4049 | ||
4050 | retval = pci_register_driver(&stli_pcidriver); | ||
4051 | if (retval && found == 0) { | ||
4052 | printk(KERN_ERR "Neither isa nor eisa cards found nor pci " | ||
4053 | "driver can be registered!\n"); | ||
4054 | goto err; | ||
4055 | } | ||
4056 | |||
4173 | return 0; | 4057 | return 0; |
4058 | err: | ||
4059 | return retval; | ||
4174 | } | 4060 | } |
4175 | 4061 | ||
4176 | /*****************************************************************************/ | 4062 | /*****************************************************************************/ |
@@ -4185,12 +4071,13 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof | |||
4185 | { | 4071 | { |
4186 | unsigned long flags; | 4072 | unsigned long flags; |
4187 | void __iomem *memptr; | 4073 | void __iomem *memptr; |
4188 | stlibrd_t *brdp; | 4074 | struct stlibrd *brdp; |
4189 | int brdnr, size, n; | 4075 | unsigned int brdnr; |
4076 | int size, n; | ||
4190 | void *p; | 4077 | void *p; |
4191 | loff_t off = *offp; | 4078 | loff_t off = *offp; |
4192 | 4079 | ||
4193 | brdnr = iminor(fp->f_dentry->d_inode); | 4080 | brdnr = iminor(fp->f_path.dentry->d_inode); |
4194 | if (brdnr >= stli_nrbrds) | 4081 | if (brdnr >= stli_nrbrds) |
4195 | return -ENODEV; | 4082 | return -ENODEV; |
4196 | brdp = stli_brds[brdnr]; | 4083 | brdp = stli_brds[brdnr]; |
@@ -4201,7 +4088,7 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof | |||
4201 | if (off >= brdp->memsize || off + count < off) | 4088 | if (off >= brdp->memsize || off + count < off) |
4202 | return 0; | 4089 | return 0; |
4203 | 4090 | ||
4204 | size = MIN(count, (brdp->memsize - off)); | 4091 | size = min(count, (size_t)(brdp->memsize - off)); |
4205 | 4092 | ||
4206 | /* | 4093 | /* |
4207 | * Copy the data a page at a time | 4094 | * Copy the data a page at a time |
@@ -4215,8 +4102,8 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof | |||
4215 | spin_lock_irqsave(&brd_lock, flags); | 4102 | spin_lock_irqsave(&brd_lock, flags); |
4216 | EBRDENABLE(brdp); | 4103 | EBRDENABLE(brdp); |
4217 | memptr = EBRDGETMEMPTR(brdp, off); | 4104 | memptr = EBRDGETMEMPTR(brdp, off); |
4218 | n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); | 4105 | n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); |
4219 | n = MIN(n, PAGE_SIZE); | 4106 | n = min(n, (int)PAGE_SIZE); |
4220 | memcpy_fromio(p, memptr, n); | 4107 | memcpy_fromio(p, memptr, n); |
4221 | EBRDDISABLE(brdp); | 4108 | EBRDDISABLE(brdp); |
4222 | spin_unlock_irqrestore(&brd_lock, flags); | 4109 | spin_unlock_irqrestore(&brd_lock, flags); |
@@ -4248,13 +4135,14 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou | |||
4248 | { | 4135 | { |
4249 | unsigned long flags; | 4136 | unsigned long flags; |
4250 | void __iomem *memptr; | 4137 | void __iomem *memptr; |
4251 | stlibrd_t *brdp; | 4138 | struct stlibrd *brdp; |
4252 | char __user *chbuf; | 4139 | char __user *chbuf; |
4253 | int brdnr, size, n; | 4140 | unsigned int brdnr; |
4141 | int size, n; | ||
4254 | void *p; | 4142 | void *p; |
4255 | loff_t off = *offp; | 4143 | loff_t off = *offp; |
4256 | 4144 | ||
4257 | brdnr = iminor(fp->f_dentry->d_inode); | 4145 | brdnr = iminor(fp->f_path.dentry->d_inode); |
4258 | 4146 | ||
4259 | if (brdnr >= stli_nrbrds) | 4147 | if (brdnr >= stli_nrbrds) |
4260 | return -ENODEV; | 4148 | return -ENODEV; |
@@ -4267,7 +4155,7 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou | |||
4267 | return 0; | 4155 | return 0; |
4268 | 4156 | ||
4269 | chbuf = (char __user *) buf; | 4157 | chbuf = (char __user *) buf; |
4270 | size = MIN(count, (brdp->memsize - off)); | 4158 | size = min(count, (size_t)(brdp->memsize - off)); |
4271 | 4159 | ||
4272 | /* | 4160 | /* |
4273 | * Copy the data a page at a time | 4161 | * Copy the data a page at a time |
@@ -4278,8 +4166,8 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou | |||
4278 | return -ENOMEM; | 4166 | return -ENOMEM; |
4279 | 4167 | ||
4280 | while (size > 0) { | 4168 | while (size > 0) { |
4281 | n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); | 4169 | n = min(size, (int)(brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); |
4282 | n = MIN(n, PAGE_SIZE); | 4170 | n = min(n, (int)PAGE_SIZE); |
4283 | if (copy_from_user(p, chbuf, n)) { | 4171 | if (copy_from_user(p, chbuf, n)) { |
4284 | if (count == 0) | 4172 | if (count == 0) |
4285 | count = -EFAULT; | 4173 | count = -EFAULT; |
@@ -4309,8 +4197,8 @@ out: | |||
4309 | 4197 | ||
4310 | static int stli_getbrdstats(combrd_t __user *bp) | 4198 | static int stli_getbrdstats(combrd_t __user *bp) |
4311 | { | 4199 | { |
4312 | stlibrd_t *brdp; | 4200 | struct stlibrd *brdp; |
4313 | int i; | 4201 | unsigned int i; |
4314 | 4202 | ||
4315 | if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) | 4203 | if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) |
4316 | return -EFAULT; | 4204 | return -EFAULT; |
@@ -4346,19 +4234,20 @@ static int stli_getbrdstats(combrd_t __user *bp) | |||
4346 | * Resolve the referenced port number into a port struct pointer. | 4234 | * Resolve the referenced port number into a port struct pointer. |
4347 | */ | 4235 | */ |
4348 | 4236 | ||
4349 | static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) | 4237 | static struct stliport *stli_getport(unsigned int brdnr, unsigned int panelnr, |
4238 | unsigned int portnr) | ||
4350 | { | 4239 | { |
4351 | stlibrd_t *brdp; | 4240 | struct stlibrd *brdp; |
4352 | int i; | 4241 | unsigned int i; |
4353 | 4242 | ||
4354 | if (brdnr < 0 || brdnr >= STL_MAXBRDS) | 4243 | if (brdnr >= STL_MAXBRDS) |
4355 | return NULL; | 4244 | return NULL; |
4356 | brdp = stli_brds[brdnr]; | 4245 | brdp = stli_brds[brdnr]; |
4357 | if (brdp == NULL) | 4246 | if (brdp == NULL) |
4358 | return NULL; | 4247 | return NULL; |
4359 | for (i = 0; (i < panelnr); i++) | 4248 | for (i = 0; (i < panelnr); i++) |
4360 | portnr += brdp->panels[i]; | 4249 | portnr += brdp->panels[i]; |
4361 | if ((portnr < 0) || (portnr >= brdp->nrports)) | 4250 | if (portnr >= brdp->nrports) |
4362 | return NULL; | 4251 | return NULL; |
4363 | return brdp->ports[portnr]; | 4252 | return brdp->ports[portnr]; |
4364 | } | 4253 | } |
@@ -4371,10 +4260,10 @@ static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) | |||
4371 | * what port to get stats for (used through board control device). | 4260 | * what port to get stats for (used through board control device). |
4372 | */ | 4261 | */ |
4373 | 4262 | ||
4374 | static int stli_portcmdstats(stliport_t *portp) | 4263 | static int stli_portcmdstats(struct stliport *portp) |
4375 | { | 4264 | { |
4376 | unsigned long flags; | 4265 | unsigned long flags; |
4377 | stlibrd_t *brdp; | 4266 | struct stlibrd *brdp; |
4378 | int rc; | 4267 | int rc; |
4379 | 4268 | ||
4380 | memset(&stli_comstats, 0, sizeof(comstats_t)); | 4269 | memset(&stli_comstats, 0, sizeof(comstats_t)); |
@@ -4445,9 +4334,9 @@ static int stli_portcmdstats(stliport_t *portp) | |||
4445 | * what port to get stats for (used through board control device). | 4334 | * what port to get stats for (used through board control device). |
4446 | */ | 4335 | */ |
4447 | 4336 | ||
4448 | static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) | 4337 | static int stli_getportstats(struct stliport *portp, comstats_t __user *cp) |
4449 | { | 4338 | { |
4450 | stlibrd_t *brdp; | 4339 | struct stlibrd *brdp; |
4451 | int rc; | 4340 | int rc; |
4452 | 4341 | ||
4453 | if (!portp) { | 4342 | if (!portp) { |
@@ -4476,9 +4365,9 @@ static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) | |||
4476 | * Clear the port stats structure. We also return it zeroed out... | 4365 | * Clear the port stats structure. We also return it zeroed out... |
4477 | */ | 4366 | */ |
4478 | 4367 | ||
4479 | static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) | 4368 | static int stli_clrportstats(struct stliport *portp, comstats_t __user *cp) |
4480 | { | 4369 | { |
4481 | stlibrd_t *brdp; | 4370 | struct stlibrd *brdp; |
4482 | int rc; | 4371 | int rc; |
4483 | 4372 | ||
4484 | if (!portp) { | 4373 | if (!portp) { |
@@ -4515,17 +4404,18 @@ static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) | |||
4515 | * Return the entire driver ports structure to a user app. | 4404 | * Return the entire driver ports structure to a user app. |
4516 | */ | 4405 | */ |
4517 | 4406 | ||
4518 | static int stli_getportstruct(stliport_t __user *arg) | 4407 | static int stli_getportstruct(struct stliport __user *arg) |
4519 | { | 4408 | { |
4520 | stliport_t *portp; | 4409 | struct stliport stli_dummyport; |
4410 | struct stliport *portp; | ||
4521 | 4411 | ||
4522 | if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t))) | 4412 | if (copy_from_user(&stli_dummyport, arg, sizeof(struct stliport))) |
4523 | return -EFAULT; | 4413 | return -EFAULT; |
4524 | portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr, | 4414 | portp = stli_getport(stli_dummyport.brdnr, stli_dummyport.panelnr, |
4525 | stli_dummyport.portnr); | 4415 | stli_dummyport.portnr); |
4526 | if (!portp) | 4416 | if (!portp) |
4527 | return -ENODEV; | 4417 | return -ENODEV; |
4528 | if (copy_to_user(arg, portp, sizeof(stliport_t))) | 4418 | if (copy_to_user(arg, portp, sizeof(struct stliport))) |
4529 | return -EFAULT; | 4419 | return -EFAULT; |
4530 | return 0; | 4420 | return 0; |
4531 | } | 4421 | } |
@@ -4536,18 +4426,19 @@ static int stli_getportstruct(stliport_t __user *arg) | |||
4536 | * Return the entire driver board structure to a user app. | 4426 | * Return the entire driver board structure to a user app. |
4537 | */ | 4427 | */ |
4538 | 4428 | ||
4539 | static int stli_getbrdstruct(stlibrd_t __user *arg) | 4429 | static int stli_getbrdstruct(struct stlibrd __user *arg) |
4540 | { | 4430 | { |
4541 | stlibrd_t *brdp; | 4431 | struct stlibrd stli_dummybrd; |
4432 | struct stlibrd *brdp; | ||
4542 | 4433 | ||
4543 | if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t))) | 4434 | if (copy_from_user(&stli_dummybrd, arg, sizeof(struct stlibrd))) |
4544 | return -EFAULT; | 4435 | return -EFAULT; |
4545 | if ((stli_dummybrd.brdnr < 0) || (stli_dummybrd.brdnr >= STL_MAXBRDS)) | 4436 | if (stli_dummybrd.brdnr >= STL_MAXBRDS) |
4546 | return -ENODEV; | 4437 | return -ENODEV; |
4547 | brdp = stli_brds[stli_dummybrd.brdnr]; | 4438 | brdp = stli_brds[stli_dummybrd.brdnr]; |
4548 | if (!brdp) | 4439 | if (!brdp) |
4549 | return -ENODEV; | 4440 | return -ENODEV; |
4550 | if (copy_to_user(arg, brdp, sizeof(stlibrd_t))) | 4441 | if (copy_to_user(arg, brdp, sizeof(struct stlibrd))) |
4551 | return -EFAULT; | 4442 | return -EFAULT; |
4552 | return 0; | 4443 | return 0; |
4553 | } | 4444 | } |
@@ -4562,7 +4453,7 @@ static int stli_getbrdstruct(stlibrd_t __user *arg) | |||
4562 | 4453 | ||
4563 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) | 4454 | static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) |
4564 | { | 4455 | { |
4565 | stlibrd_t *brdp; | 4456 | struct stlibrd *brdp; |
4566 | int brdnr, rc, done; | 4457 | int brdnr, rc, done; |
4567 | void __user *argp = (void __user *)arg; | 4458 | void __user *argp = (void __user *)arg; |
4568 | 4459 | ||
@@ -4661,46 +4552,53 @@ static const struct tty_operations stli_ops = { | |||
4661 | }; | 4552 | }; |
4662 | 4553 | ||
4663 | /*****************************************************************************/ | 4554 | /*****************************************************************************/ |
4555 | /* | ||
4556 | * Loadable module initialization stuff. | ||
4557 | */ | ||
4558 | |||
4559 | static void istallion_cleanup_isa(void) | ||
4560 | { | ||
4561 | struct stlibrd *brdp; | ||
4562 | unsigned int j; | ||
4563 | |||
4564 | for (j = 0; (j < stli_nrbrds); j++) { | ||
4565 | if ((brdp = stli_brds[j]) == NULL || (brdp->state & BST_PROBED)) | ||
4566 | continue; | ||
4664 | 4567 | ||
4665 | static int __init stli_init(void) | 4568 | stli_cleanup_ports(brdp); |
4569 | |||
4570 | iounmap(brdp->membase); | ||
4571 | if (brdp->iosize > 0) | ||
4572 | release_region(brdp->iobase, brdp->iosize); | ||
4573 | kfree(brdp); | ||
4574 | stli_brds[j] = NULL; | ||
4575 | } | ||
4576 | } | ||
4577 | |||
4578 | static int __init istallion_module_init(void) | ||
4666 | { | 4579 | { |
4667 | int i; | 4580 | unsigned int i; |
4581 | int retval; | ||
4582 | |||
4668 | printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); | 4583 | printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); |
4669 | 4584 | ||
4670 | spin_lock_init(&stli_lock); | 4585 | spin_lock_init(&stli_lock); |
4671 | spin_lock_init(&brd_lock); | 4586 | spin_lock_init(&brd_lock); |
4672 | 4587 | ||
4673 | stli_initbrds(); | ||
4674 | |||
4675 | stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | ||
4676 | if (!stli_serial) | ||
4677 | return -ENOMEM; | ||
4678 | |||
4679 | /* | ||
4680 | * Allocate a temporary write buffer. | ||
4681 | */ | ||
4682 | stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); | 4588 | stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); |
4683 | if (!stli_txcookbuf) | 4589 | if (!stli_txcookbuf) { |
4684 | printk(KERN_ERR "STALLION: failed to allocate memory " | 4590 | printk(KERN_ERR "STALLION: failed to allocate memory " |
4685 | "(size=%d)\n", STLI_TXBUFSIZE); | 4591 | "(size=%d)\n", STLI_TXBUFSIZE); |
4592 | retval = -ENOMEM; | ||
4593 | goto err; | ||
4594 | } | ||
4686 | 4595 | ||
4687 | /* | 4596 | stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); |
4688 | * Set up a character driver for the shared memory region. We need this | 4597 | if (!stli_serial) { |
4689 | * to down load the slave code image. Also it is a useful debugging tool. | 4598 | retval = -ENOMEM; |
4690 | */ | 4599 | goto err_free; |
4691 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem)) | 4600 | } |
4692 | printk(KERN_ERR "STALLION: failed to register serial memory " | ||
4693 | "device\n"); | ||
4694 | |||
4695 | istallion_class = class_create(THIS_MODULE, "staliomem"); | ||
4696 | for (i = 0; i < 4; i++) | ||
4697 | class_device_create(istallion_class, NULL, | ||
4698 | MKDEV(STL_SIOMEMMAJOR, i), | ||
4699 | NULL, "staliomem%d", i); | ||
4700 | 4601 | ||
4701 | /* | ||
4702 | * Set up the tty driver structure and register us as a driver. | ||
4703 | */ | ||
4704 | stli_serial->owner = THIS_MODULE; | 4602 | stli_serial->owner = THIS_MODULE; |
4705 | stli_serial->driver_name = stli_drvname; | 4603 | stli_serial->driver_name = stli_drvname; |
4706 | stli_serial->name = stli_serialname; | 4604 | stli_serial->name = stli_serialname; |
@@ -4709,15 +4607,79 @@ static int __init stli_init(void) | |||
4709 | stli_serial->type = TTY_DRIVER_TYPE_SERIAL; | 4607 | stli_serial->type = TTY_DRIVER_TYPE_SERIAL; |
4710 | stli_serial->subtype = SERIAL_TYPE_NORMAL; | 4608 | stli_serial->subtype = SERIAL_TYPE_NORMAL; |
4711 | stli_serial->init_termios = stli_deftermios; | 4609 | stli_serial->init_termios = stli_deftermios; |
4712 | stli_serial->flags = TTY_DRIVER_REAL_RAW; | 4610 | stli_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
4713 | tty_set_operations(stli_serial, &stli_ops); | 4611 | tty_set_operations(stli_serial, &stli_ops); |
4714 | 4612 | ||
4715 | if (tty_register_driver(stli_serial)) { | 4613 | retval = tty_register_driver(stli_serial); |
4716 | put_tty_driver(stli_serial); | 4614 | if (retval) { |
4717 | printk(KERN_ERR "STALLION: failed to register serial driver\n"); | 4615 | printk(KERN_ERR "STALLION: failed to register serial driver\n"); |
4718 | return -EBUSY; | 4616 | goto err_ttyput; |
4719 | } | 4617 | } |
4618 | |||
4619 | retval = stli_initbrds(); | ||
4620 | if (retval) | ||
4621 | goto err_ttyunr; | ||
4622 | |||
4623 | /* | ||
4624 | * Set up a character driver for the shared memory region. We need this | ||
4625 | * to down load the slave code image. Also it is a useful debugging tool. | ||
4626 | */ | ||
4627 | retval = register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stli_fsiomem); | ||
4628 | if (retval) { | ||
4629 | printk(KERN_ERR "STALLION: failed to register serial memory " | ||
4630 | "device\n"); | ||
4631 | goto err_deinit; | ||
4632 | } | ||
4633 | |||
4634 | istallion_class = class_create(THIS_MODULE, "staliomem"); | ||
4635 | for (i = 0; i < 4; i++) | ||
4636 | class_device_create(istallion_class, NULL, | ||
4637 | MKDEV(STL_SIOMEMMAJOR, i), | ||
4638 | NULL, "staliomem%d", i); | ||
4639 | |||
4720 | return 0; | 4640 | return 0; |
4641 | err_deinit: | ||
4642 | pci_unregister_driver(&stli_pcidriver); | ||
4643 | istallion_cleanup_isa(); | ||
4644 | err_ttyunr: | ||
4645 | tty_unregister_driver(stli_serial); | ||
4646 | err_ttyput: | ||
4647 | put_tty_driver(stli_serial); | ||
4648 | err_free: | ||
4649 | kfree(stli_txcookbuf); | ||
4650 | err: | ||
4651 | return retval; | ||
4721 | } | 4652 | } |
4722 | 4653 | ||
4723 | /*****************************************************************************/ | 4654 | /*****************************************************************************/ |
4655 | |||
4656 | static void __exit istallion_module_exit(void) | ||
4657 | { | ||
4658 | unsigned int j; | ||
4659 | |||
4660 | printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, | ||
4661 | stli_drvversion); | ||
4662 | |||
4663 | if (stli_timeron) { | ||
4664 | stli_timeron = 0; | ||
4665 | del_timer_sync(&stli_timerlist); | ||
4666 | } | ||
4667 | |||
4668 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); | ||
4669 | |||
4670 | for (j = 0; j < 4; j++) | ||
4671 | class_device_destroy(istallion_class, MKDEV(STL_SIOMEMMAJOR, | ||
4672 | j)); | ||
4673 | class_destroy(istallion_class); | ||
4674 | |||
4675 | pci_unregister_driver(&stli_pcidriver); | ||
4676 | istallion_cleanup_isa(); | ||
4677 | |||
4678 | tty_unregister_driver(stli_serial); | ||
4679 | put_tty_driver(stli_serial); | ||
4680 | |||
4681 | kfree(stli_txcookbuf); | ||
4682 | } | ||
4683 | |||
4684 | module_init(istallion_module_init); | ||
4685 | module_exit(istallion_module_exit); | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 20b6c8b30248..7a6c1c0b7a95 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -710,7 +710,7 @@ static void k_fn(struct vc_data *vc, unsigned char value, char up_flag) | |||
710 | 710 | ||
711 | static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) | 711 | static void k_cur(struct vc_data *vc, unsigned char value, char up_flag) |
712 | { | 712 | { |
713 | static const char *cur_chars = "BDCA"; | 713 | static const char cur_chars[] = "BDCA"; |
714 | 714 | ||
715 | if (up_flag) | 715 | if (up_flag) |
716 | return; | 716 | return; |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 1ecea7d448f1..b70b5388b5a8 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -296,7 +296,7 @@ static int lp_wait_ready(int minor, int nonblock) | |||
296 | static ssize_t lp_write(struct file * file, const char __user * buf, | 296 | static ssize_t lp_write(struct file * file, const char __user * buf, |
297 | size_t count, loff_t *ppos) | 297 | size_t count, loff_t *ppos) |
298 | { | 298 | { |
299 | unsigned int minor = iminor(file->f_dentry->d_inode); | 299 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
300 | struct parport *port = lp_table[minor].dev->port; | 300 | struct parport *port = lp_table[minor].dev->port; |
301 | char *kbuf = lp_table[minor].lp_buffer; | 301 | char *kbuf = lp_table[minor].lp_buffer; |
302 | ssize_t retv = 0; | 302 | ssize_t retv = 0; |
@@ -415,7 +415,7 @@ static ssize_t lp_read(struct file * file, char __user * buf, | |||
415 | size_t count, loff_t *ppos) | 415 | size_t count, loff_t *ppos) |
416 | { | 416 | { |
417 | DEFINE_WAIT(wait); | 417 | DEFINE_WAIT(wait); |
418 | unsigned int minor=iminor(file->f_dentry->d_inode); | 418 | unsigned int minor=iminor(file->f_path.dentry->d_inode); |
419 | struct parport *port = lp_table[minor].dev->port; | 419 | struct parport *port = lp_table[minor].dev->port; |
420 | ssize_t retval = 0; | 420 | ssize_t retval = 0; |
421 | char *kbuf = lp_table[minor].lp_buffer; | 421 | char *kbuf = lp_table[minor].lp_buffer; |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index e67eef4867ba..089020e0ee5a 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -774,7 +774,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) | |||
774 | { | 774 | { |
775 | loff_t ret; | 775 | loff_t ret; |
776 | 776 | ||
777 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | 777 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); |
778 | switch (orig) { | 778 | switch (orig) { |
779 | case 0: | 779 | case 0: |
780 | file->f_pos = offset; | 780 | file->f_pos = offset; |
@@ -789,7 +789,7 @@ static loff_t memory_lseek(struct file * file, loff_t offset, int orig) | |||
789 | default: | 789 | default: |
790 | ret = -EINVAL; | 790 | ret = -EINVAL; |
791 | } | 791 | } |
792 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 792 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
793 | return ret; | 793 | return ret; |
794 | } | 794 | } |
795 | 795 | ||
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 7a484fc7cb9e..7e975f606924 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c | |||
@@ -199,6 +199,8 @@ int misc_register(struct miscdevice * misc) | |||
199 | dev_t dev; | 199 | dev_t dev; |
200 | int err = 0; | 200 | int err = 0; |
201 | 201 | ||
202 | INIT_LIST_HEAD(&misc->list); | ||
203 | |||
202 | down(&misc_sem); | 204 | down(&misc_sem); |
203 | list_for_each_entry(c, &misc_list, list) { | 205 | list_for_each_entry(c, &misc_list, list) { |
204 | if (c->minor == misc->minor) { | 206 | if (c->minor == misc->minor) { |
diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 22b9905c1e52..c09160383a53 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c | |||
@@ -680,7 +680,7 @@ static int __init mmtimer_init(void) | |||
680 | if (sn_rtc_cycles_per_second < 100000) { | 680 | if (sn_rtc_cycles_per_second < 100000) { |
681 | printk(KERN_ERR "%s: unable to determine clock frequency\n", | 681 | printk(KERN_ERR "%s: unable to determine clock frequency\n", |
682 | MMTIMER_NAME); | 682 | MMTIMER_NAME); |
683 | return -1; | 683 | goto out1; |
684 | } | 684 | } |
685 | 685 | ||
686 | mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second / | 686 | mmtimer_femtoperiod = ((unsigned long)1E15 + sn_rtc_cycles_per_second / |
@@ -689,13 +689,13 @@ static int __init mmtimer_init(void) | |||
689 | if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, IRQF_PERCPU, MMTIMER_NAME, NULL)) { | 689 | if (request_irq(SGI_MMTIMER_VECTOR, mmtimer_interrupt, IRQF_PERCPU, MMTIMER_NAME, NULL)) { |
690 | printk(KERN_WARNING "%s: unable to allocate interrupt.", | 690 | printk(KERN_WARNING "%s: unable to allocate interrupt.", |
691 | MMTIMER_NAME); | 691 | MMTIMER_NAME); |
692 | return -1; | 692 | goto out1; |
693 | } | 693 | } |
694 | 694 | ||
695 | if (misc_register(&mmtimer_miscdev)) { | 695 | if (misc_register(&mmtimer_miscdev)) { |
696 | printk(KERN_ERR "%s: failed to register device\n", | 696 | printk(KERN_ERR "%s: failed to register device\n", |
697 | MMTIMER_NAME); | 697 | MMTIMER_NAME); |
698 | return -1; | 698 | goto out2; |
699 | } | 699 | } |
700 | 700 | ||
701 | /* Get max numbered node, calculate slots needed */ | 701 | /* Get max numbered node, calculate slots needed */ |
@@ -709,16 +709,18 @@ static int __init mmtimer_init(void) | |||
709 | if (timers == NULL) { | 709 | if (timers == NULL) { |
710 | printk(KERN_ERR "%s: failed to allocate memory for device\n", | 710 | printk(KERN_ERR "%s: failed to allocate memory for device\n", |
711 | MMTIMER_NAME); | 711 | MMTIMER_NAME); |
712 | return -1; | 712 | goto out3; |
713 | } | 713 | } |
714 | 714 | ||
715 | memset(timers,0,(sizeof(mmtimer_t *)*maxn)); | ||
716 | |||
715 | /* Allocate mmtimer_t's for each online node */ | 717 | /* Allocate mmtimer_t's for each online node */ |
716 | for_each_online_node(node) { | 718 | for_each_online_node(node) { |
717 | timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node); | 719 | timers[node] = kmalloc_node(sizeof(mmtimer_t)*NUM_COMPARATORS, GFP_KERNEL, node); |
718 | if (timers[node] == NULL) { | 720 | if (timers[node] == NULL) { |
719 | printk(KERN_ERR "%s: failed to allocate memory for device\n", | 721 | printk(KERN_ERR "%s: failed to allocate memory for device\n", |
720 | MMTIMER_NAME); | 722 | MMTIMER_NAME); |
721 | return -1; | 723 | goto out4; |
722 | } | 724 | } |
723 | for (i=0; i< NUM_COMPARATORS; i++) { | 725 | for (i=0; i< NUM_COMPARATORS; i++) { |
724 | mmtimer_t * base = timers[node] + i; | 726 | mmtimer_t * base = timers[node] + i; |
@@ -739,6 +741,17 @@ static int __init mmtimer_init(void) | |||
739 | sn_rtc_cycles_per_second/(unsigned long)1E6); | 741 | sn_rtc_cycles_per_second/(unsigned long)1E6); |
740 | 742 | ||
741 | return 0; | 743 | return 0; |
744 | |||
745 | out4: | ||
746 | for_each_online_node(node) { | ||
747 | kfree(timers[node]); | ||
748 | } | ||
749 | out3: | ||
750 | misc_deregister(&mmtimer_miscdev); | ||
751 | out2: | ||
752 | free_irq(SGI_MMTIMER_VECTOR, NULL); | ||
753 | out1: | ||
754 | return -1; | ||
742 | } | 755 | } |
743 | 756 | ||
744 | module_init(mmtimer_init); | 757 | module_init(mmtimer_init); |
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 2d025a9fd14d..f391a24a1b44 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c | |||
@@ -234,7 +234,7 @@ static void moxa_put_char(struct tty_struct *, unsigned char); | |||
234 | static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); | 234 | static int moxa_ioctl(struct tty_struct *, struct file *, unsigned int, unsigned long); |
235 | static void moxa_throttle(struct tty_struct *); | 235 | static void moxa_throttle(struct tty_struct *); |
236 | static void moxa_unthrottle(struct tty_struct *); | 236 | static void moxa_unthrottle(struct tty_struct *); |
237 | static void moxa_set_termios(struct tty_struct *, struct termios *); | 237 | static void moxa_set_termios(struct tty_struct *, struct ktermios *); |
238 | static void moxa_stop(struct tty_struct *); | 238 | static void moxa_stop(struct tty_struct *); |
239 | static void moxa_start(struct tty_struct *); | 239 | static void moxa_start(struct tty_struct *); |
240 | static void moxa_hangup(struct tty_struct *); | 240 | static void moxa_hangup(struct tty_struct *); |
@@ -261,7 +261,7 @@ static void MoxaPortEnable(int); | |||
261 | static void MoxaPortDisable(int); | 261 | static void MoxaPortDisable(int); |
262 | static long MoxaPortGetMaxBaud(int); | 262 | static long MoxaPortGetMaxBaud(int); |
263 | static long MoxaPortSetBaud(int, long); | 263 | static long MoxaPortSetBaud(int, long); |
264 | static int MoxaPortSetTermio(int, struct termios *, speed_t); | 264 | static int MoxaPortSetTermio(int, struct ktermios *, speed_t); |
265 | static int MoxaPortGetLineOut(int, int *, int *); | 265 | static int MoxaPortGetLineOut(int, int *, int *); |
266 | static void MoxaPortLineCtrl(int, int, int); | 266 | static void MoxaPortLineCtrl(int, int, int); |
267 | static void MoxaPortFlowCtrl(int, int, int, int, int, int); | 267 | static void MoxaPortFlowCtrl(int, int, int, int, int, int); |
@@ -355,6 +355,8 @@ static int __init moxa_init(void) | |||
355 | moxaDriver->init_termios.c_oflag = 0; | 355 | moxaDriver->init_termios.c_oflag = 0; |
356 | moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 356 | moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
357 | moxaDriver->init_termios.c_lflag = 0; | 357 | moxaDriver->init_termios.c_lflag = 0; |
358 | moxaDriver->init_termios.c_ispeed = 9600; | ||
359 | moxaDriver->init_termios.c_ospeed = 9600; | ||
358 | moxaDriver->flags = TTY_DRIVER_REAL_RAW; | 360 | moxaDriver->flags = TTY_DRIVER_REAL_RAW; |
359 | tty_set_operations(moxaDriver, &moxa_ops); | 361 | tty_set_operations(moxaDriver, &moxa_ops); |
360 | 362 | ||
@@ -498,9 +500,12 @@ static void __exit moxa_exit(void) | |||
498 | printk("Couldn't unregister MOXA Intellio family serial driver\n"); | 500 | printk("Couldn't unregister MOXA Intellio family serial driver\n"); |
499 | put_tty_driver(moxaDriver); | 501 | put_tty_driver(moxaDriver); |
500 | 502 | ||
501 | for (i = 0; i < MAX_BOARDS; i++) | 503 | for (i = 0; i < MAX_BOARDS; i++) { |
504 | if (moxaBaseAddr[i]) | ||
505 | iounmap(moxaBaseAddr[i]); | ||
502 | if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI) | 506 | if (moxa_boards[i].busType == MOXA_BUS_TYPE_PCI) |
503 | pci_dev_put(moxa_boards[i].pciInfo.pdev); | 507 | pci_dev_put(moxa_boards[i].pciInfo.pdev); |
508 | } | ||
504 | 509 | ||
505 | if (verbose) | 510 | if (verbose) |
506 | printk("Done\n"); | 511 | printk("Done\n"); |
@@ -861,7 +866,7 @@ static void moxa_unthrottle(struct tty_struct *tty) | |||
861 | } | 866 | } |
862 | 867 | ||
863 | static void moxa_set_termios(struct tty_struct *tty, | 868 | static void moxa_set_termios(struct tty_struct *tty, |
864 | struct termios *old_termios) | 869 | struct ktermios *old_termios) |
865 | { | 870 | { |
866 | struct moxa_str *ch = (struct moxa_str *) tty->driver_data; | 871 | struct moxa_str *ch = (struct moxa_str *) tty->driver_data; |
867 | 872 | ||
@@ -975,7 +980,7 @@ static void moxa_poll(unsigned long ignored) | |||
975 | 980 | ||
976 | static void set_tty_param(struct tty_struct *tty) | 981 | static void set_tty_param(struct tty_struct *tty) |
977 | { | 982 | { |
978 | register struct termios *ts; | 983 | register struct ktermios *ts; |
979 | struct moxa_str *ch; | 984 | struct moxa_str *ch; |
980 | int rts, cts, txflow, rxflow, xany; | 985 | int rts, cts, txflow, rxflow, xany; |
981 | 986 | ||
@@ -1146,7 +1151,7 @@ static void shut_down(struct moxa_str *ch) | |||
1146 | static void receive_data(struct moxa_str *ch) | 1151 | static void receive_data(struct moxa_str *ch) |
1147 | { | 1152 | { |
1148 | struct tty_struct *tp; | 1153 | struct tty_struct *tp; |
1149 | struct termios *ts; | 1154 | struct ktermios *ts; |
1150 | unsigned long flags; | 1155 | unsigned long flags; |
1151 | 1156 | ||
1152 | ts = NULL; | 1157 | ts = NULL; |
@@ -1909,9 +1914,9 @@ int MoxaPortsOfCard(int cardno) | |||
1909 | * | 1914 | * |
1910 | * Function 12: Configure the port. | 1915 | * Function 12: Configure the port. |
1911 | * Syntax: | 1916 | * Syntax: |
1912 | * int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud); | 1917 | * int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud); |
1913 | * int port : port number (0 - 127) | 1918 | * int port : port number (0 - 127) |
1914 | * struct termios * termio : termio structure pointer | 1919 | * struct ktermios * termio : termio structure pointer |
1915 | * speed_t baud : baud rate | 1920 | * speed_t baud : baud rate |
1916 | * | 1921 | * |
1917 | * return: -1 : this port is invalid or termio == NULL | 1922 | * return: -1 : this port is invalid or termio == NULL |
@@ -2192,7 +2197,7 @@ long MoxaPortSetBaud(int port, long baud) | |||
2192 | return (baud); | 2197 | return (baud); |
2193 | } | 2198 | } |
2194 | 2199 | ||
2195 | int MoxaPortSetTermio(int port, struct termios *termio, speed_t baud) | 2200 | int MoxaPortSetTermio(int port, struct ktermios *termio, speed_t baud) |
2196 | { | 2201 | { |
2197 | void __iomem *ofsAddr; | 2202 | void __iomem *ofsAddr; |
2198 | tcflag_t cflag; | 2203 | tcflag_t cflag; |
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 5ed2486b7581..c063359baf78 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -328,8 +328,8 @@ struct mxser_struct { | |||
328 | int xmit_tail; | 328 | int xmit_tail; |
329 | int xmit_cnt; | 329 | int xmit_cnt; |
330 | struct work_struct tqueue; | 330 | struct work_struct tqueue; |
331 | struct termios normal_termios; | 331 | struct ktermios normal_termios; |
332 | struct termios callout_termios; | 332 | struct ktermios callout_termios; |
333 | wait_queue_head_t open_wait; | 333 | wait_queue_head_t open_wait; |
334 | wait_queue_head_t close_wait; | 334 | wait_queue_head_t close_wait; |
335 | wait_queue_head_t delta_msr_wait; | 335 | wait_queue_head_t delta_msr_wait; |
@@ -364,8 +364,8 @@ static int mxserBoardCAP[MXSER_BOARDS] = { | |||
364 | static struct tty_driver *mxvar_sdriver; | 364 | static struct tty_driver *mxvar_sdriver; |
365 | static struct mxser_struct mxvar_table[MXSER_PORTS]; | 365 | static struct mxser_struct mxvar_table[MXSER_PORTS]; |
366 | static struct tty_struct *mxvar_tty[MXSER_PORTS + 1]; | 366 | static struct tty_struct *mxvar_tty[MXSER_PORTS + 1]; |
367 | static struct termios *mxvar_termios[MXSER_PORTS + 1]; | 367 | static struct ktermios *mxvar_termios[MXSER_PORTS + 1]; |
368 | static struct termios *mxvar_termios_locked[MXSER_PORTS + 1]; | 368 | static struct ktermios *mxvar_termios_locked[MXSER_PORTS + 1]; |
369 | static struct mxser_log mxvar_log; | 369 | static struct mxser_log mxvar_log; |
370 | static int mxvar_diagflag; | 370 | static int mxvar_diagflag; |
371 | static unsigned char mxser_msr[MXSER_PORTS + 1]; | 371 | static unsigned char mxser_msr[MXSER_PORTS + 1]; |
@@ -402,7 +402,7 @@ static int mxser_ioctl(struct tty_struct *, struct file *, uint, ulong); | |||
402 | static int mxser_ioctl_special(unsigned int, void __user *); | 402 | static int mxser_ioctl_special(unsigned int, void __user *); |
403 | static void mxser_throttle(struct tty_struct *); | 403 | static void mxser_throttle(struct tty_struct *); |
404 | static void mxser_unthrottle(struct tty_struct *); | 404 | static void mxser_unthrottle(struct tty_struct *); |
405 | static void mxser_set_termios(struct tty_struct *, struct termios *); | 405 | static void mxser_set_termios(struct tty_struct *, struct ktermios *); |
406 | static void mxser_stop(struct tty_struct *); | 406 | static void mxser_stop(struct tty_struct *); |
407 | static void mxser_start(struct tty_struct *); | 407 | static void mxser_start(struct tty_struct *); |
408 | static void mxser_hangup(struct tty_struct *); | 408 | static void mxser_hangup(struct tty_struct *); |
@@ -414,7 +414,7 @@ static void mxser_check_modem_status(struct mxser_struct *, int); | |||
414 | static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *); | 414 | static int mxser_block_til_ready(struct tty_struct *, struct file *, struct mxser_struct *); |
415 | static int mxser_startup(struct mxser_struct *); | 415 | static int mxser_startup(struct mxser_struct *); |
416 | static void mxser_shutdown(struct mxser_struct *); | 416 | static void mxser_shutdown(struct mxser_struct *); |
417 | static int mxser_change_speed(struct mxser_struct *, struct termios *old_termios); | 417 | static int mxser_change_speed(struct mxser_struct *, struct ktermios *old_termios); |
418 | static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *); | 418 | static int mxser_get_serial_info(struct mxser_struct *, struct serial_struct __user *); |
419 | static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *); | 419 | static int mxser_set_serial_info(struct mxser_struct *, struct serial_struct __user *); |
420 | static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *); | 420 | static int mxser_get_lsr_info(struct mxser_struct *, unsigned int __user *); |
@@ -515,6 +515,7 @@ static void __exit mxser_module_exit(void) | |||
515 | if (pdev != NULL) { /* PCI */ | 515 | if (pdev != NULL) { /* PCI */ |
516 | release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); | 516 | release_region(pci_resource_start(pdev, 2), pci_resource_len(pdev, 2)); |
517 | release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3)); | 517 | release_region(pci_resource_start(pdev, 3), pci_resource_len(pdev, 3)); |
518 | pci_dev_put(pdev); | ||
518 | } else { | 519 | } else { |
519 | release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports); | 520 | release_region(mxsercfg[i].ioaddr[0], 8 * mxsercfg[i].ports); |
520 | release_region(mxsercfg[i].vector, 1); | 521 | release_region(mxsercfg[i].vector, 1); |
@@ -556,7 +557,7 @@ static int mxser_initbrd(int board, struct mxser_hwconf *hwconf) | |||
556 | n = board * MXSER_PORTS_PER_BOARD; | 557 | n = board * MXSER_PORTS_PER_BOARD; |
557 | info = &mxvar_table[n]; | 558 | info = &mxvar_table[n]; |
558 | /*if (verbose) */ { | 559 | /*if (verbose) */ { |
559 | printk(KERN_DEBUG " ttyM%d - ttyM%d ", | 560 | printk(KERN_DEBUG " ttyMI%d - ttyMI%d ", |
560 | n, n + hwconf->ports - 1); | 561 | n, n + hwconf->ports - 1); |
561 | printk(" max. baud rate = %d bps.\n", | 562 | printk(" max. baud rate = %d bps.\n", |
562 | hwconf->MaxCanSetBaudRate[0]); | 563 | hwconf->MaxCanSetBaudRate[0]); |
@@ -717,7 +718,7 @@ static int mxser_init(void) | |||
717 | /* Initialize the tty_driver structure */ | 718 | /* Initialize the tty_driver structure */ |
718 | memset(mxvar_sdriver, 0, sizeof(struct tty_driver)); | 719 | memset(mxvar_sdriver, 0, sizeof(struct tty_driver)); |
719 | mxvar_sdriver->magic = TTY_DRIVER_MAGIC; | 720 | mxvar_sdriver->magic = TTY_DRIVER_MAGIC; |
720 | mxvar_sdriver->name = "ttyM"; | 721 | mxvar_sdriver->name = "ttyMI"; |
721 | mxvar_sdriver->major = ttymajor; | 722 | mxvar_sdriver->major = ttymajor; |
722 | mxvar_sdriver->minor_start = 0; | 723 | mxvar_sdriver->minor_start = 0; |
723 | mxvar_sdriver->num = MXSER_PORTS + 1; | 724 | mxvar_sdriver->num = MXSER_PORTS + 1; |
@@ -725,6 +726,8 @@ static int mxser_init(void) | |||
725 | mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; | 726 | mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; |
726 | mxvar_sdriver->init_termios = tty_std_termios; | 727 | mxvar_sdriver->init_termios = tty_std_termios; |
727 | mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; | 728 | mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; |
729 | mxvar_sdriver->init_termios.c_ispeed = 9600; | ||
730 | mxvar_sdriver->init_termios.c_ospeed = 9600; | ||
728 | mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW; | 731 | mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW; |
729 | tty_set_operations(mxvar_sdriver, &mxser_ops); | 732 | tty_set_operations(mxvar_sdriver, &mxser_ops); |
730 | mxvar_sdriver->ttys = mxvar_tty; | 733 | mxvar_sdriver->ttys = mxvar_tty; |
@@ -839,9 +842,9 @@ static int mxser_init(void) | |||
839 | index = 0; | 842 | index = 0; |
840 | b = 0; | 843 | b = 0; |
841 | while (b < n) { | 844 | while (b < n) { |
842 | pdev = pci_find_device(mxser_pcibrds[b].vendor, | 845 | pdev = pci_get_device(mxser_pcibrds[b].vendor, |
843 | mxser_pcibrds[b].device, pdev); | 846 | mxser_pcibrds[b].device, pdev); |
844 | if (pdev == NULL) { | 847 | if (pdev == NULL) { |
845 | b++; | 848 | b++; |
846 | continue; | 849 | continue; |
847 | } | 850 | } |
@@ -893,6 +896,9 @@ static int mxser_init(void) | |||
893 | if (mxser_initbrd(m, &hwconf) < 0) | 896 | if (mxser_initbrd(m, &hwconf) < 0) |
894 | continue; | 897 | continue; |
895 | m++; | 898 | m++; |
899 | /* Keep an extra reference if we succeeded. It will | ||
900 | be returned at unload time */ | ||
901 | pci_dev_get(pdev); | ||
896 | } | 902 | } |
897 | } | 903 | } |
898 | #endif | 904 | #endif |
@@ -994,7 +1000,7 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) | |||
994 | mxser_change_speed(info, NULL); | 1000 | mxser_change_speed(info, NULL); |
995 | } | 1001 | } |
996 | 1002 | ||
997 | info->session = current->signal->session; | 1003 | info->session = process_session(current); |
998 | info->pgrp = process_group(current); | 1004 | info->pgrp = process_group(current); |
999 | 1005 | ||
1000 | /* | 1006 | /* |
@@ -1745,7 +1751,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1745 | /* MX_UNLOCK(&info->slock); */ | 1751 | /* MX_UNLOCK(&info->slock); */ |
1746 | } | 1752 | } |
1747 | 1753 | ||
1748 | static void mxser_set_termios(struct tty_struct *tty, struct termios *old_termios) | 1754 | static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
1749 | { | 1755 | { |
1750 | struct mxser_struct *info = tty->driver_data; | 1756 | struct mxser_struct *info = tty->driver_data; |
1751 | unsigned long flags; | 1757 | unsigned long flags; |
@@ -2537,7 +2543,7 @@ static void mxser_shutdown(struct mxser_struct *info) | |||
2537 | * This routine is called to set the UART divisor registers to match | 2543 | * This routine is called to set the UART divisor registers to match |
2538 | * the specified baud rate for a serial port. | 2544 | * the specified baud rate for a serial port. |
2539 | */ | 2545 | */ |
2540 | static int mxser_change_speed(struct mxser_struct *info, struct termios *old_termios) | 2546 | static int mxser_change_speed(struct mxser_struct *info, struct ktermios *old_termios) |
2541 | { | 2547 | { |
2542 | unsigned cflag, cval, fcr; | 2548 | unsigned cflag, cval, fcr; |
2543 | int ret = 0; | 2549 | int ret = 0; |
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c new file mode 100644 index 000000000000..efa8076c33e0 --- /dev/null +++ b/drivers/char/mxser_new.c | |||
@@ -0,0 +1,2804 @@ | |||
1 | /* | ||
2 | * mxser.c -- MOXA Smartio/Industio family multiport serial driver. | ||
3 | * | ||
4 | * Copyright (C) 1999-2006 Moxa Technologies (support@moxa.com.tw). | ||
5 | * Copyright (C) 2006 Jiri Slaby <jirislaby@gmail.com> | ||
6 | * | ||
7 | * This code is loosely based on the 1.8 moxa driver which is based on | ||
8 | * Linux serial driver, written by Linus Torvalds, Theodore T'so and | ||
9 | * others. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * Fed through a cleanup, indent and remove of non 2.6 code by Alan Cox | ||
17 | * <alan@redhat.com>. The original 1.8 code is available on www.moxa.com. | ||
18 | * - Fixed x86_64 cleanness | ||
19 | * - Fixed sleep with spinlock held in mxser_send_break | ||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/autoconf.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/signal.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <linux/timer.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/tty.h> | ||
30 | #include <linux/tty_flip.h> | ||
31 | #include <linux/serial.h> | ||
32 | #include <linux/serial_reg.h> | ||
33 | #include <linux/major.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/fcntl.h> | ||
36 | #include <linux/ptrace.h> | ||
37 | #include <linux/gfp.h> | ||
38 | #include <linux/ioport.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/smp_lock.h> | ||
41 | #include <linux/delay.h> | ||
42 | #include <linux/pci.h> | ||
43 | |||
44 | #include <asm/system.h> | ||
45 | #include <asm/io.h> | ||
46 | #include <asm/irq.h> | ||
47 | #include <asm/bitops.h> | ||
48 | #include <asm/uaccess.h> | ||
49 | |||
50 | #include "mxser_new.h" | ||
51 | |||
52 | #define MXSER_VERSION "2.0" | ||
53 | #define MXSERMAJOR 174 | ||
54 | #define MXSERCUMAJOR 175 | ||
55 | |||
56 | #define MXSER_EVENT_TXLOW 1 | ||
57 | |||
58 | #define MXSER_BOARDS 4 /* Max. boards */ | ||
59 | #define MXSER_PORTS_PER_BOARD 8 /* Max. ports per board */ | ||
60 | #define MXSER_PORTS (MXSER_BOARDS * MXSER_PORTS_PER_BOARD) | ||
61 | #define MXSER_ISR_PASS_LIMIT 99999L | ||
62 | |||
63 | #define MXSER_ERR_IOADDR -1 | ||
64 | #define MXSER_ERR_IRQ -2 | ||
65 | #define MXSER_ERR_IRQ_CONFLIT -3 | ||
66 | #define MXSER_ERR_VECTOR -4 | ||
67 | |||
68 | #define WAKEUP_CHARS 256 | ||
69 | |||
70 | #define UART_MCR_AFE 0x20 | ||
71 | #define UART_LSR_SPECIAL 0x1E | ||
72 | |||
73 | #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|\ | ||
74 | IXON|IXOFF)) | ||
75 | |||
76 | #define C168_ASIC_ID 1 | ||
77 | #define C104_ASIC_ID 2 | ||
78 | #define C102_ASIC_ID 0xB | ||
79 | #define CI132_ASIC_ID 4 | ||
80 | #define CI134_ASIC_ID 3 | ||
81 | #define CI104J_ASIC_ID 5 | ||
82 | |||
83 | #define MXSER_HIGHBAUD 1 | ||
84 | #define MXSER_HAS2 2 | ||
85 | |||
86 | /* This is only for PCI */ | ||
87 | static const struct { | ||
88 | int type; | ||
89 | int tx_fifo; | ||
90 | int rx_fifo; | ||
91 | int xmit_fifo_size; | ||
92 | int rx_high_water; | ||
93 | int rx_trigger; | ||
94 | int rx_low_water; | ||
95 | long max_baud; | ||
96 | } Gpci_uart_info[] = { | ||
97 | {MOXA_OTHER_UART, 16, 16, 16, 14, 14, 1, 921600L}, | ||
98 | {MOXA_MUST_MU150_HWID, 64, 64, 64, 48, 48, 16, 230400L}, | ||
99 | {MOXA_MUST_MU860_HWID, 128, 128, 128, 96, 96, 32, 921600L} | ||
100 | }; | ||
101 | #define UART_INFO_NUM ARRAY_SIZE(Gpci_uart_info) | ||
102 | |||
103 | struct mxser_cardinfo { | ||
104 | unsigned int nports; | ||
105 | char *name; | ||
106 | unsigned int flags; | ||
107 | }; | ||
108 | |||
109 | static const struct mxser_cardinfo mxser_cards[] = { | ||
110 | { 8, "C168 series", }, /* C168-ISA */ | ||
111 | { 4, "C104 series", }, /* C104-ISA */ | ||
112 | { 4, "CI-104J series", }, /* CI104J */ | ||
113 | { 8, "C168H/PCI series", }, /* C168-PCI */ | ||
114 | { 4, "C104H/PCI series", }, /* C104-PCI */ | ||
115 | { 4, "C102 series", MXSER_HAS2 }, /* C102-ISA */ | ||
116 | { 4, "CI-132 series", MXSER_HAS2 }, /* CI132 */ | ||
117 | { 4, "CI-134 series", }, /* CI134 */ | ||
118 | { 2, "CP-132 series", }, /* CP132 */ | ||
119 | { 4, "CP-114 series", }, /* CP114 */ | ||
120 | { 4, "CT-114 series", }, /* CT114 */ | ||
121 | { 2, "CP-102 series", MXSER_HIGHBAUD }, /* CP102 */ | ||
122 | { 4, "CP-104U series", }, /* CP104U */ | ||
123 | { 8, "CP-168U series", }, /* CP168U */ | ||
124 | { 2, "CP-132U series", }, /* CP132U */ | ||
125 | { 4, "CP-134U series", }, /* CP134U */ | ||
126 | { 4, "CP-104JU series", }, /* CP104JU */ | ||
127 | { 8, "Moxa UC7000 Serial", }, /* RC7000 */ | ||
128 | { 8, "CP-118U series", }, /* CP118U */ | ||
129 | { 2, "CP-102UL series", }, /* CP102UL */ | ||
130 | { 2, "CP-102U series", }, /* CP102U */ | ||
131 | { 8, "CP-118EL series", }, /* CP118EL */ | ||
132 | { 8, "CP-168EL series", }, /* CP168EL */ | ||
133 | { 4, "CP-104EL series", } /* CP104EL */ | ||
134 | }; | ||
135 | |||
136 | /* driver_data correspond to the lines in the structure above | ||
137 | see also ISA probe function before you change something */ | ||
138 | static struct pci_device_id mxser_pcibrds[] = { | ||
139 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C168), | ||
140 | .driver_data = 3 }, | ||
141 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_C104), | ||
142 | .driver_data = 4 }, | ||
143 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132), | ||
144 | .driver_data = 8 }, | ||
145 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP114), | ||
146 | .driver_data = 9 }, | ||
147 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CT114), | ||
148 | .driver_data = 10 }, | ||
149 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102), | ||
150 | .driver_data = 11 }, | ||
151 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104U), | ||
152 | .driver_data = 12 }, | ||
153 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168U), | ||
154 | .driver_data = 13 }, | ||
155 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP132U), | ||
156 | .driver_data = 14 }, | ||
157 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP134U), | ||
158 | .driver_data = 15 }, | ||
159 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104JU), | ||
160 | .driver_data = 16 }, | ||
161 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_RC7000), | ||
162 | .driver_data = 17 }, | ||
163 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118U), | ||
164 | .driver_data = 18 }, | ||
165 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102UL), | ||
166 | .driver_data = 19 }, | ||
167 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP102U), | ||
168 | .driver_data = 20 }, | ||
169 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP118EL), | ||
170 | .driver_data = 21 }, | ||
171 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP168EL), | ||
172 | .driver_data = 22 }, | ||
173 | { PCI_DEVICE(PCI_VENDOR_ID_MOXA, PCI_DEVICE_ID_MOXA_CP104EL), | ||
174 | .driver_data = 23 }, | ||
175 | { } | ||
176 | }; | ||
177 | MODULE_DEVICE_TABLE(pci, mxser_pcibrds); | ||
178 | |||
179 | static int ioaddr[MXSER_BOARDS] = { 0, 0, 0, 0 }; | ||
180 | static int ttymajor = MXSERMAJOR; | ||
181 | static int calloutmajor = MXSERCUMAJOR; | ||
182 | |||
183 | /* Variables for insmod */ | ||
184 | |||
185 | MODULE_AUTHOR("Casper Yang"); | ||
186 | MODULE_DESCRIPTION("MOXA Smartio/Industio Family Multiport Board Device Driver"); | ||
187 | module_param_array(ioaddr, int, NULL, 0); | ||
188 | module_param(ttymajor, int, 0); | ||
189 | MODULE_LICENSE("GPL"); | ||
190 | |||
191 | struct mxser_log { | ||
192 | int tick; | ||
193 | unsigned long rxcnt[MXSER_PORTS]; | ||
194 | unsigned long txcnt[MXSER_PORTS]; | ||
195 | }; | ||
196 | |||
197 | |||
198 | struct mxser_mon { | ||
199 | unsigned long rxcnt; | ||
200 | unsigned long txcnt; | ||
201 | unsigned long up_rxcnt; | ||
202 | unsigned long up_txcnt; | ||
203 | int modem_status; | ||
204 | unsigned char hold_reason; | ||
205 | }; | ||
206 | |||
207 | struct mxser_mon_ext { | ||
208 | unsigned long rx_cnt[32]; | ||
209 | unsigned long tx_cnt[32]; | ||
210 | unsigned long up_rxcnt[32]; | ||
211 | unsigned long up_txcnt[32]; | ||
212 | int modem_status[32]; | ||
213 | |||
214 | long baudrate[32]; | ||
215 | int databits[32]; | ||
216 | int stopbits[32]; | ||
217 | int parity[32]; | ||
218 | int flowctrl[32]; | ||
219 | int fifo[32]; | ||
220 | int iftype[32]; | ||
221 | }; | ||
222 | |||
223 | struct mxser_board; | ||
224 | |||
225 | struct mxser_port { | ||
226 | struct mxser_board *board; | ||
227 | struct tty_struct *tty; | ||
228 | |||
229 | unsigned long ioaddr; | ||
230 | unsigned long opmode_ioaddr; | ||
231 | int max_baud; | ||
232 | |||
233 | int rx_high_water; | ||
234 | int rx_trigger; /* Rx fifo trigger level */ | ||
235 | int rx_low_water; | ||
236 | int baud_base; /* max. speed */ | ||
237 | long realbaud; | ||
238 | int type; /* UART type */ | ||
239 | int flags; /* defined in tty.h */ | ||
240 | long session; /* Session of opening process */ | ||
241 | long pgrp; /* pgrp of opening process */ | ||
242 | |||
243 | int x_char; /* xon/xoff character */ | ||
244 | int IER; /* Interrupt Enable Register */ | ||
245 | int MCR; /* Modem control register */ | ||
246 | |||
247 | unsigned char stop_rx; | ||
248 | unsigned char ldisc_stop_rx; | ||
249 | |||
250 | int custom_divisor; | ||
251 | int close_delay; | ||
252 | unsigned short closing_wait; | ||
253 | unsigned char err_shadow; | ||
254 | unsigned long event; | ||
255 | |||
256 | int count; /* # of fd on device */ | ||
257 | int blocked_open; /* # of blocked opens */ | ||
258 | struct async_icount icount; /* kernel counters for 4 input interrupts */ | ||
259 | int timeout; | ||
260 | |||
261 | int read_status_mask; | ||
262 | int ignore_status_mask; | ||
263 | int xmit_fifo_size; | ||
264 | unsigned char *xmit_buf; | ||
265 | int xmit_head; | ||
266 | int xmit_tail; | ||
267 | int xmit_cnt; | ||
268 | |||
269 | struct ktermios normal_termios; | ||
270 | struct ktermios callout_termios; | ||
271 | |||
272 | struct mxser_mon mon_data; | ||
273 | |||
274 | spinlock_t slock; | ||
275 | struct work_struct tqueue; | ||
276 | wait_queue_head_t open_wait; | ||
277 | wait_queue_head_t close_wait; | ||
278 | wait_queue_head_t delta_msr_wait; | ||
279 | }; | ||
280 | |||
281 | struct mxser_board { | ||
282 | unsigned int idx; | ||
283 | int irq; | ||
284 | const struct mxser_cardinfo *info; | ||
285 | unsigned long vector; | ||
286 | unsigned long vector_mask; | ||
287 | |||
288 | int chip_flag; | ||
289 | int uart_type; | ||
290 | |||
291 | struct mxser_port ports[MXSER_PORTS_PER_BOARD]; | ||
292 | }; | ||
293 | |||
294 | struct mxser_mstatus { | ||
295 | tcflag_t cflag; | ||
296 | int cts; | ||
297 | int dsr; | ||
298 | int ri; | ||
299 | int dcd; | ||
300 | }; | ||
301 | |||
302 | static struct mxser_mstatus GMStatus[MXSER_PORTS]; | ||
303 | |||
304 | static int mxserBoardCAP[MXSER_BOARDS] = { | ||
305 | 0, 0, 0, 0 | ||
306 | /* 0x180, 0x280, 0x200, 0x320 */ | ||
307 | }; | ||
308 | |||
309 | static struct mxser_board mxser_boards[MXSER_BOARDS]; | ||
310 | static struct tty_driver *mxvar_sdriver; | ||
311 | static struct mxser_log mxvar_log; | ||
312 | static int mxvar_diagflag; | ||
313 | static unsigned char mxser_msr[MXSER_PORTS + 1]; | ||
314 | static struct mxser_mon_ext mon_data_ext; | ||
315 | static int mxser_set_baud_method[MXSER_PORTS + 1]; | ||
316 | static spinlock_t gm_lock; | ||
317 | |||
318 | static int CheckIsMoxaMust(int io) | ||
319 | { | ||
320 | u8 oldmcr, hwid; | ||
321 | int i; | ||
322 | |||
323 | outb(0, io + UART_LCR); | ||
324 | DISABLE_MOXA_MUST_ENCHANCE_MODE(io); | ||
325 | oldmcr = inb(io + UART_MCR); | ||
326 | outb(0, io + UART_MCR); | ||
327 | SET_MOXA_MUST_XON1_VALUE(io, 0x11); | ||
328 | if ((hwid = inb(io + UART_MCR)) != 0) { | ||
329 | outb(oldmcr, io + UART_MCR); | ||
330 | return MOXA_OTHER_UART; | ||
331 | } | ||
332 | |||
333 | GET_MOXA_MUST_HARDWARE_ID(io, &hwid); | ||
334 | for (i = 1; i < UART_INFO_NUM; i++) { /* 0 = OTHER_UART */ | ||
335 | if (hwid == Gpci_uart_info[i].type) | ||
336 | return (int)hwid; | ||
337 | } | ||
338 | return MOXA_OTHER_UART; | ||
339 | } | ||
340 | |||
341 | static void process_txrx_fifo(struct mxser_port *info) | ||
342 | { | ||
343 | int i; | ||
344 | |||
345 | if ((info->type == PORT_16450) || (info->type == PORT_8250)) { | ||
346 | info->rx_trigger = 1; | ||
347 | info->rx_high_water = 1; | ||
348 | info->rx_low_water = 1; | ||
349 | info->xmit_fifo_size = 1; | ||
350 | } else | ||
351 | for (i = 0; i < UART_INFO_NUM; i++) | ||
352 | if (info->board->chip_flag == Gpci_uart_info[i].type) { | ||
353 | info->rx_trigger = Gpci_uart_info[i].rx_trigger; | ||
354 | info->rx_low_water = Gpci_uart_info[i].rx_low_water; | ||
355 | info->rx_high_water = Gpci_uart_info[i].rx_high_water; | ||
356 | info->xmit_fifo_size = Gpci_uart_info[i].xmit_fifo_size; | ||
357 | break; | ||
358 | } | ||
359 | } | ||
360 | |||
361 | static void mxser_do_softint(struct work_struct *work) | ||
362 | { | ||
363 | struct mxser_port *info = container_of(work, struct mxser_port, tqueue); | ||
364 | struct tty_struct *tty = info->tty; | ||
365 | |||
366 | if (test_and_clear_bit(MXSER_EVENT_TXLOW, &info->event)) | ||
367 | tty_wakeup(tty); | ||
368 | } | ||
369 | |||
370 | static unsigned char mxser_get_msr(int baseaddr, int mode, int port) | ||
371 | { | ||
372 | unsigned char status = 0; | ||
373 | |||
374 | status = inb(baseaddr + UART_MSR); | ||
375 | |||
376 | mxser_msr[port] &= 0x0F; | ||
377 | mxser_msr[port] |= status; | ||
378 | status = mxser_msr[port]; | ||
379 | if (mode) | ||
380 | mxser_msr[port] = 0; | ||
381 | |||
382 | return status; | ||
383 | } | ||
384 | |||
385 | static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp, | ||
386 | struct mxser_port *port) | ||
387 | { | ||
388 | DECLARE_WAITQUEUE(wait, current); | ||
389 | int retval; | ||
390 | int do_clocal = 0; | ||
391 | unsigned long flags; | ||
392 | |||
393 | /* | ||
394 | * If non-blocking mode is set, or the port is not enabled, | ||
395 | * then make the check up front and then exit. | ||
396 | */ | ||
397 | if ((filp->f_flags & O_NONBLOCK) || | ||
398 | test_bit(TTY_IO_ERROR, &tty->flags)) { | ||
399 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
400 | return 0; | ||
401 | } | ||
402 | |||
403 | if (tty->termios->c_cflag & CLOCAL) | ||
404 | do_clocal = 1; | ||
405 | |||
406 | /* | ||
407 | * Block waiting for the carrier detect and the line to become | ||
408 | * free (i.e., not in use by the callout). While we are in | ||
409 | * this loop, port->count is dropped by one, so that | ||
410 | * mxser_close() knows when to free things. We restore it upon | ||
411 | * exit, either normal or abnormal. | ||
412 | */ | ||
413 | retval = 0; | ||
414 | add_wait_queue(&port->open_wait, &wait); | ||
415 | |||
416 | spin_lock_irqsave(&port->slock, flags); | ||
417 | if (!tty_hung_up_p(filp)) | ||
418 | port->count--; | ||
419 | spin_unlock_irqrestore(&port->slock, flags); | ||
420 | port->blocked_open++; | ||
421 | while (1) { | ||
422 | spin_lock_irqsave(&port->slock, flags); | ||
423 | outb(inb(port->ioaddr + UART_MCR) | | ||
424 | UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR); | ||
425 | spin_unlock_irqrestore(&port->slock, flags); | ||
426 | set_current_state(TASK_INTERRUPTIBLE); | ||
427 | if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { | ||
428 | if (port->flags & ASYNC_HUP_NOTIFY) | ||
429 | retval = -EAGAIN; | ||
430 | else | ||
431 | retval = -ERESTARTSYS; | ||
432 | break; | ||
433 | } | ||
434 | if (!(port->flags & ASYNC_CLOSING) && | ||
435 | (do_clocal || | ||
436 | (inb(port->ioaddr + UART_MSR) & UART_MSR_DCD))) | ||
437 | break; | ||
438 | if (signal_pending(current)) { | ||
439 | retval = -ERESTARTSYS; | ||
440 | break; | ||
441 | } | ||
442 | schedule(); | ||
443 | } | ||
444 | set_current_state(TASK_RUNNING); | ||
445 | remove_wait_queue(&port->open_wait, &wait); | ||
446 | if (!tty_hung_up_p(filp)) | ||
447 | port->count++; | ||
448 | port->blocked_open--; | ||
449 | if (retval) | ||
450 | return retval; | ||
451 | port->flags |= ASYNC_NORMAL_ACTIVE; | ||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static int mxser_set_baud(struct mxser_port *info, long newspd) | ||
456 | { | ||
457 | int quot = 0; | ||
458 | unsigned char cval; | ||
459 | int ret = 0; | ||
460 | unsigned long flags; | ||
461 | |||
462 | if (!info->tty || !info->tty->termios) | ||
463 | return ret; | ||
464 | |||
465 | if (!(info->ioaddr)) | ||
466 | return ret; | ||
467 | |||
468 | if (newspd > info->max_baud) | ||
469 | return 0; | ||
470 | |||
471 | info->realbaud = newspd; | ||
472 | if (newspd == 134) { | ||
473 | quot = (2 * info->baud_base / 269); | ||
474 | } else if (newspd) { | ||
475 | quot = info->baud_base / newspd; | ||
476 | if (quot == 0) | ||
477 | quot = 1; | ||
478 | } else { | ||
479 | quot = 0; | ||
480 | } | ||
481 | |||
482 | info->timeout = ((info->xmit_fifo_size * HZ * 10 * quot) / info->baud_base); | ||
483 | info->timeout += HZ / 50; /* Add .02 seconds of slop */ | ||
484 | |||
485 | if (quot) { | ||
486 | spin_lock_irqsave(&info->slock, flags); | ||
487 | info->MCR |= UART_MCR_DTR; | ||
488 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
489 | spin_unlock_irqrestore(&info->slock, flags); | ||
490 | } else { | ||
491 | spin_lock_irqsave(&info->slock, flags); | ||
492 | info->MCR &= ~UART_MCR_DTR; | ||
493 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
494 | spin_unlock_irqrestore(&info->slock, flags); | ||
495 | return ret; | ||
496 | } | ||
497 | |||
498 | cval = inb(info->ioaddr + UART_LCR); | ||
499 | |||
500 | outb(cval | UART_LCR_DLAB, info->ioaddr + UART_LCR); /* set DLAB */ | ||
501 | |||
502 | outb(quot & 0xff, info->ioaddr + UART_DLL); /* LS of divisor */ | ||
503 | outb(quot >> 8, info->ioaddr + UART_DLM); /* MS of divisor */ | ||
504 | outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ | ||
505 | |||
506 | |||
507 | return ret; | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | * This routine is called to set the UART divisor registers to match | ||
512 | * the specified baud rate for a serial port. | ||
513 | */ | ||
514 | static int mxser_change_speed(struct mxser_port *info, | ||
515 | struct ktermios *old_termios) | ||
516 | { | ||
517 | unsigned cflag, cval, fcr; | ||
518 | int ret = 0; | ||
519 | unsigned char status; | ||
520 | long baud; | ||
521 | unsigned long flags; | ||
522 | |||
523 | if (!info->tty || !info->tty->termios) | ||
524 | return ret; | ||
525 | cflag = info->tty->termios->c_cflag; | ||
526 | if (!(info->ioaddr)) | ||
527 | return ret; | ||
528 | |||
529 | if (mxser_set_baud_method[info->tty->index] == 0) { | ||
530 | baud = tty_get_baud_rate(info->tty); | ||
531 | mxser_set_baud(info, baud); | ||
532 | } | ||
533 | |||
534 | /* byte size and parity */ | ||
535 | switch (cflag & CSIZE) { | ||
536 | case CS5: | ||
537 | cval = 0x00; | ||
538 | break; | ||
539 | case CS6: | ||
540 | cval = 0x01; | ||
541 | break; | ||
542 | case CS7: | ||
543 | cval = 0x02; | ||
544 | break; | ||
545 | case CS8: | ||
546 | cval = 0x03; | ||
547 | break; | ||
548 | default: | ||
549 | cval = 0x00; | ||
550 | break; /* too keep GCC shut... */ | ||
551 | } | ||
552 | if (cflag & CSTOPB) | ||
553 | cval |= 0x04; | ||
554 | if (cflag & PARENB) | ||
555 | cval |= UART_LCR_PARITY; | ||
556 | if (!(cflag & PARODD)) | ||
557 | cval |= UART_LCR_EPAR; | ||
558 | if (cflag & CMSPAR) | ||
559 | cval |= UART_LCR_SPAR; | ||
560 | |||
561 | if ((info->type == PORT_8250) || (info->type == PORT_16450)) { | ||
562 | if (info->board->chip_flag) { | ||
563 | fcr = UART_FCR_ENABLE_FIFO; | ||
564 | fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; | ||
565 | SET_MOXA_MUST_FIFO_VALUE(info); | ||
566 | } else | ||
567 | fcr = 0; | ||
568 | } else { | ||
569 | fcr = UART_FCR_ENABLE_FIFO; | ||
570 | if (info->board->chip_flag) { | ||
571 | fcr |= MOXA_MUST_FCR_GDA_MODE_ENABLE; | ||
572 | SET_MOXA_MUST_FIFO_VALUE(info); | ||
573 | } else { | ||
574 | switch (info->rx_trigger) { | ||
575 | case 1: | ||
576 | fcr |= UART_FCR_TRIGGER_1; | ||
577 | break; | ||
578 | case 4: | ||
579 | fcr |= UART_FCR_TRIGGER_4; | ||
580 | break; | ||
581 | case 8: | ||
582 | fcr |= UART_FCR_TRIGGER_8; | ||
583 | break; | ||
584 | default: | ||
585 | fcr |= UART_FCR_TRIGGER_14; | ||
586 | break; | ||
587 | } | ||
588 | } | ||
589 | } | ||
590 | |||
591 | /* CTS flow control flag and modem status interrupts */ | ||
592 | info->IER &= ~UART_IER_MSI; | ||
593 | info->MCR &= ~UART_MCR_AFE; | ||
594 | if (cflag & CRTSCTS) { | ||
595 | info->flags |= ASYNC_CTS_FLOW; | ||
596 | info->IER |= UART_IER_MSI; | ||
597 | if ((info->type == PORT_16550A) || (info->board->chip_flag)) { | ||
598 | info->MCR |= UART_MCR_AFE; | ||
599 | } else { | ||
600 | status = inb(info->ioaddr + UART_MSR); | ||
601 | if (info->tty->hw_stopped) { | ||
602 | if (status & UART_MSR_CTS) { | ||
603 | info->tty->hw_stopped = 0; | ||
604 | if (info->type != PORT_16550A && | ||
605 | !info->board->chip_flag) { | ||
606 | outb(info->IER & ~UART_IER_THRI, | ||
607 | info->ioaddr + | ||
608 | UART_IER); | ||
609 | info->IER |= UART_IER_THRI; | ||
610 | outb(info->IER, info->ioaddr + | ||
611 | UART_IER); | ||
612 | } | ||
613 | set_bit(MXSER_EVENT_TXLOW, &info->event); | ||
614 | schedule_work(&info->tqueue); } | ||
615 | } else { | ||
616 | if (!(status & UART_MSR_CTS)) { | ||
617 | info->tty->hw_stopped = 1; | ||
618 | if ((info->type != PORT_16550A) && | ||
619 | (!info->board->chip_flag)) { | ||
620 | info->IER &= ~UART_IER_THRI; | ||
621 | outb(info->IER, info->ioaddr + | ||
622 | UART_IER); | ||
623 | } | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | } else { | ||
628 | info->flags &= ~ASYNC_CTS_FLOW; | ||
629 | } | ||
630 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
631 | if (cflag & CLOCAL) { | ||
632 | info->flags &= ~ASYNC_CHECK_CD; | ||
633 | } else { | ||
634 | info->flags |= ASYNC_CHECK_CD; | ||
635 | info->IER |= UART_IER_MSI; | ||
636 | } | ||
637 | outb(info->IER, info->ioaddr + UART_IER); | ||
638 | |||
639 | /* | ||
640 | * Set up parity check flag | ||
641 | */ | ||
642 | info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; | ||
643 | if (I_INPCK(info->tty)) | ||
644 | info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; | ||
645 | if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) | ||
646 | info->read_status_mask |= UART_LSR_BI; | ||
647 | |||
648 | info->ignore_status_mask = 0; | ||
649 | |||
650 | if (I_IGNBRK(info->tty)) { | ||
651 | info->ignore_status_mask |= UART_LSR_BI; | ||
652 | info->read_status_mask |= UART_LSR_BI; | ||
653 | /* | ||
654 | * If we're ignore parity and break indicators, ignore | ||
655 | * overruns too. (For real raw support). | ||
656 | */ | ||
657 | if (I_IGNPAR(info->tty)) { | ||
658 | info->ignore_status_mask |= | ||
659 | UART_LSR_OE | | ||
660 | UART_LSR_PE | | ||
661 | UART_LSR_FE; | ||
662 | info->read_status_mask |= | ||
663 | UART_LSR_OE | | ||
664 | UART_LSR_PE | | ||
665 | UART_LSR_FE; | ||
666 | } | ||
667 | } | ||
668 | if (info->board->chip_flag) { | ||
669 | spin_lock_irqsave(&info->slock, flags); | ||
670 | SET_MOXA_MUST_XON1_VALUE(info->ioaddr, START_CHAR(info->tty)); | ||
671 | SET_MOXA_MUST_XOFF1_VALUE(info->ioaddr, STOP_CHAR(info->tty)); | ||
672 | if (I_IXON(info->tty)) { | ||
673 | ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | ||
674 | } else { | ||
675 | DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | ||
676 | } | ||
677 | if (I_IXOFF(info->tty)) { | ||
678 | ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | ||
679 | } else { | ||
680 | DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | ||
681 | } | ||
682 | spin_unlock_irqrestore(&info->slock, flags); | ||
683 | } | ||
684 | |||
685 | |||
686 | outb(fcr, info->ioaddr + UART_FCR); /* set fcr */ | ||
687 | outb(cval, info->ioaddr + UART_LCR); | ||
688 | |||
689 | return ret; | ||
690 | } | ||
691 | |||
692 | static void mxser_check_modem_status(struct mxser_port *port, int status) | ||
693 | { | ||
694 | /* update input line counters */ | ||
695 | if (status & UART_MSR_TERI) | ||
696 | port->icount.rng++; | ||
697 | if (status & UART_MSR_DDSR) | ||
698 | port->icount.dsr++; | ||
699 | if (status & UART_MSR_DDCD) | ||
700 | port->icount.dcd++; | ||
701 | if (status & UART_MSR_DCTS) | ||
702 | port->icount.cts++; | ||
703 | port->mon_data.modem_status = status; | ||
704 | wake_up_interruptible(&port->delta_msr_wait); | ||
705 | |||
706 | if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { | ||
707 | if (status & UART_MSR_DCD) | ||
708 | wake_up_interruptible(&port->open_wait); | ||
709 | schedule_work(&port->tqueue); | ||
710 | } | ||
711 | |||
712 | if (port->flags & ASYNC_CTS_FLOW) { | ||
713 | if (port->tty->hw_stopped) { | ||
714 | if (status & UART_MSR_CTS) { | ||
715 | port->tty->hw_stopped = 0; | ||
716 | |||
717 | if ((port->type != PORT_16550A) && | ||
718 | (!port->board->chip_flag)) { | ||
719 | outb(port->IER & ~UART_IER_THRI, | ||
720 | port->ioaddr + UART_IER); | ||
721 | port->IER |= UART_IER_THRI; | ||
722 | outb(port->IER, port->ioaddr + | ||
723 | UART_IER); | ||
724 | } | ||
725 | set_bit(MXSER_EVENT_TXLOW, &port->event); | ||
726 | schedule_work(&port->tqueue); | ||
727 | } | ||
728 | } else { | ||
729 | if (!(status & UART_MSR_CTS)) { | ||
730 | port->tty->hw_stopped = 1; | ||
731 | if (port->type != PORT_16550A && | ||
732 | !port->board->chip_flag) { | ||
733 | port->IER &= ~UART_IER_THRI; | ||
734 | outb(port->IER, port->ioaddr + | ||
735 | UART_IER); | ||
736 | } | ||
737 | } | ||
738 | } | ||
739 | } | ||
740 | } | ||
741 | |||
742 | static int mxser_startup(struct mxser_port *info) | ||
743 | { | ||
744 | unsigned long page; | ||
745 | unsigned long flags; | ||
746 | |||
747 | page = __get_free_page(GFP_KERNEL); | ||
748 | if (!page) | ||
749 | return -ENOMEM; | ||
750 | |||
751 | spin_lock_irqsave(&info->slock, flags); | ||
752 | |||
753 | if (info->flags & ASYNC_INITIALIZED) { | ||
754 | free_page(page); | ||
755 | spin_unlock_irqrestore(&info->slock, flags); | ||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | if (!info->ioaddr || !info->type) { | ||
760 | if (info->tty) | ||
761 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
762 | free_page(page); | ||
763 | spin_unlock_irqrestore(&info->slock, flags); | ||
764 | return 0; | ||
765 | } | ||
766 | if (info->xmit_buf) | ||
767 | free_page(page); | ||
768 | else | ||
769 | info->xmit_buf = (unsigned char *) page; | ||
770 | |||
771 | /* | ||
772 | * Clear the FIFO buffers and disable them | ||
773 | * (they will be reenabled in mxser_change_speed()) | ||
774 | */ | ||
775 | if (info->board->chip_flag) | ||
776 | outb((UART_FCR_CLEAR_RCVR | | ||
777 | UART_FCR_CLEAR_XMIT | | ||
778 | MOXA_MUST_FCR_GDA_MODE_ENABLE), info->ioaddr + UART_FCR); | ||
779 | else | ||
780 | outb((UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), | ||
781 | info->ioaddr + UART_FCR); | ||
782 | |||
783 | /* | ||
784 | * At this point there's no way the LSR could still be 0xFF; | ||
785 | * if it is, then bail out, because there's likely no UART | ||
786 | * here. | ||
787 | */ | ||
788 | if (inb(info->ioaddr + UART_LSR) == 0xff) { | ||
789 | spin_unlock_irqrestore(&info->slock, flags); | ||
790 | if (capable(CAP_SYS_ADMIN)) { | ||
791 | if (info->tty) | ||
792 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
793 | return 0; | ||
794 | } else | ||
795 | return -ENODEV; | ||
796 | } | ||
797 | |||
798 | /* | ||
799 | * Clear the interrupt registers. | ||
800 | */ | ||
801 | (void) inb(info->ioaddr + UART_LSR); | ||
802 | (void) inb(info->ioaddr + UART_RX); | ||
803 | (void) inb(info->ioaddr + UART_IIR); | ||
804 | (void) inb(info->ioaddr + UART_MSR); | ||
805 | |||
806 | /* | ||
807 | * Now, initialize the UART | ||
808 | */ | ||
809 | outb(UART_LCR_WLEN8, info->ioaddr + UART_LCR); /* reset DLAB */ | ||
810 | info->MCR = UART_MCR_DTR | UART_MCR_RTS; | ||
811 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
812 | |||
813 | /* | ||
814 | * Finally, enable interrupts | ||
815 | */ | ||
816 | info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI; | ||
817 | |||
818 | if (info->board->chip_flag) | ||
819 | info->IER |= MOXA_MUST_IER_EGDAI; | ||
820 | outb(info->IER, info->ioaddr + UART_IER); /* enable interrupts */ | ||
821 | |||
822 | /* | ||
823 | * And clear the interrupt registers again for luck. | ||
824 | */ | ||
825 | (void) inb(info->ioaddr + UART_LSR); | ||
826 | (void) inb(info->ioaddr + UART_RX); | ||
827 | (void) inb(info->ioaddr + UART_IIR); | ||
828 | (void) inb(info->ioaddr + UART_MSR); | ||
829 | |||
830 | if (info->tty) | ||
831 | clear_bit(TTY_IO_ERROR, &info->tty->flags); | ||
832 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
833 | |||
834 | /* | ||
835 | * and set the speed of the serial port | ||
836 | */ | ||
837 | spin_unlock_irqrestore(&info->slock, flags); | ||
838 | mxser_change_speed(info, NULL); | ||
839 | |||
840 | info->flags |= ASYNC_INITIALIZED; | ||
841 | return 0; | ||
842 | } | ||
843 | |||
844 | /* | ||
845 | * This routine will shutdown a serial port; interrupts maybe disabled, and | ||
846 | * DTR is dropped if the hangup on close termio flag is on. | ||
847 | */ | ||
848 | static void mxser_shutdown(struct mxser_port *info) | ||
849 | { | ||
850 | unsigned long flags; | ||
851 | |||
852 | if (!(info->flags & ASYNC_INITIALIZED)) | ||
853 | return; | ||
854 | |||
855 | spin_lock_irqsave(&info->slock, flags); | ||
856 | |||
857 | /* | ||
858 | * clear delta_msr_wait queue to avoid mem leaks: we may free the irq | ||
859 | * here so the queue might never be waken up | ||
860 | */ | ||
861 | wake_up_interruptible(&info->delta_msr_wait); | ||
862 | |||
863 | /* | ||
864 | * Free the IRQ, if necessary | ||
865 | */ | ||
866 | if (info->xmit_buf) { | ||
867 | free_page((unsigned long) info->xmit_buf); | ||
868 | info->xmit_buf = NULL; | ||
869 | } | ||
870 | |||
871 | info->IER = 0; | ||
872 | outb(0x00, info->ioaddr + UART_IER); | ||
873 | |||
874 | if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) | ||
875 | info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); | ||
876 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
877 | |||
878 | /* clear Rx/Tx FIFO's */ | ||
879 | if (info->board->chip_flag) | ||
880 | outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | | ||
881 | MOXA_MUST_FCR_GDA_MODE_ENABLE, | ||
882 | info->ioaddr + UART_FCR); | ||
883 | else | ||
884 | outb(UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, | ||
885 | info->ioaddr + UART_FCR); | ||
886 | |||
887 | /* read data port to reset things */ | ||
888 | (void) inb(info->ioaddr + UART_RX); | ||
889 | |||
890 | if (info->tty) | ||
891 | set_bit(TTY_IO_ERROR, &info->tty->flags); | ||
892 | |||
893 | info->flags &= ~ASYNC_INITIALIZED; | ||
894 | |||
895 | if (info->board->chip_flag) | ||
896 | SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); | ||
897 | |||
898 | spin_unlock_irqrestore(&info->slock, flags); | ||
899 | } | ||
900 | |||
901 | /* | ||
902 | * This routine is called whenever a serial port is opened. It | ||
903 | * enables interrupts for a serial port, linking in its async structure into | ||
904 | * the IRQ chain. It also performs the serial-specific | ||
905 | * initialization for the tty structure. | ||
906 | */ | ||
907 | static int mxser_open(struct tty_struct *tty, struct file *filp) | ||
908 | { | ||
909 | struct mxser_port *info; | ||
910 | int retval, line; | ||
911 | |||
912 | /* initialize driver_data in case something fails */ | ||
913 | tty->driver_data = NULL; | ||
914 | |||
915 | line = tty->index; | ||
916 | if (line == MXSER_PORTS) | ||
917 | return 0; | ||
918 | if (line < 0 || line > MXSER_PORTS) | ||
919 | return -ENODEV; | ||
920 | info = &mxser_boards[line / MXSER_PORTS_PER_BOARD].ports[line % MXSER_PORTS_PER_BOARD]; | ||
921 | if (!info->ioaddr) | ||
922 | return -ENODEV; | ||
923 | |||
924 | tty->driver_data = info; | ||
925 | info->tty = tty; | ||
926 | /* | ||
927 | * Start up serial port | ||
928 | */ | ||
929 | info->count++; | ||
930 | retval = mxser_startup(info); | ||
931 | if (retval) | ||
932 | return retval; | ||
933 | |||
934 | retval = mxser_block_til_ready(tty, filp, info); | ||
935 | if (retval) | ||
936 | return retval; | ||
937 | |||
938 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { | ||
939 | if (tty->driver->subtype == SERIAL_TYPE_NORMAL) | ||
940 | *tty->termios = info->normal_termios; | ||
941 | else | ||
942 | *tty->termios = info->callout_termios; | ||
943 | mxser_change_speed(info, NULL); | ||
944 | } | ||
945 | |||
946 | info->session = process_session(current); | ||
947 | info->pgrp = process_group(current); | ||
948 | |||
949 | /* unmark here for very high baud rate (ex. 921600 bps) used */ | ||
950 | tty->low_latency = 1; | ||
951 | return 0; | ||
952 | } | ||
953 | |||
954 | /* | ||
955 | * This routine is called when the serial port gets closed. First, we | ||
956 | * wait for the last remaining data to be sent. Then, we unlink its | ||
957 | * async structure from the interrupt chain if necessary, and we free | ||
958 | * that IRQ if nothing is left in the chain. | ||
959 | */ | ||
960 | static void mxser_close(struct tty_struct *tty, struct file *filp) | ||
961 | { | ||
962 | struct mxser_port *info = tty->driver_data; | ||
963 | |||
964 | unsigned long timeout; | ||
965 | unsigned long flags; | ||
966 | |||
967 | if (tty->index == MXSER_PORTS) | ||
968 | return; | ||
969 | if (!info) | ||
970 | return; | ||
971 | |||
972 | spin_lock_irqsave(&info->slock, flags); | ||
973 | |||
974 | if (tty_hung_up_p(filp)) { | ||
975 | spin_unlock_irqrestore(&info->slock, flags); | ||
976 | return; | ||
977 | } | ||
978 | if ((tty->count == 1) && (info->count != 1)) { | ||
979 | /* | ||
980 | * Uh, oh. tty->count is 1, which means that the tty | ||
981 | * structure will be freed. Info->count should always | ||
982 | * be one in these conditions. If it's greater than | ||
983 | * one, we've got real problems, since it means the | ||
984 | * serial port won't be shutdown. | ||
985 | */ | ||
986 | printk(KERN_ERR "mxser_close: bad serial port count; " | ||
987 | "tty->count is 1, info->count is %d\n", info->count); | ||
988 | info->count = 1; | ||
989 | } | ||
990 | if (--info->count < 0) { | ||
991 | printk(KERN_ERR "mxser_close: bad serial port count for " | ||
992 | "ttys%d: %d\n", tty->index, info->count); | ||
993 | info->count = 0; | ||
994 | } | ||
995 | if (info->count) { | ||
996 | spin_unlock_irqrestore(&info->slock, flags); | ||
997 | return; | ||
998 | } | ||
999 | info->flags |= ASYNC_CLOSING; | ||
1000 | spin_unlock_irqrestore(&info->slock, flags); | ||
1001 | /* | ||
1002 | * Save the termios structure, since this port may have | ||
1003 | * separate termios for callout and dialin. | ||
1004 | */ | ||
1005 | if (info->flags & ASYNC_NORMAL_ACTIVE) | ||
1006 | info->normal_termios = *tty->termios; | ||
1007 | /* | ||
1008 | * Now we wait for the transmit buffer to clear; and we notify | ||
1009 | * the line discipline to only process XON/XOFF characters. | ||
1010 | */ | ||
1011 | tty->closing = 1; | ||
1012 | if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) | ||
1013 | tty_wait_until_sent(tty, info->closing_wait); | ||
1014 | /* | ||
1015 | * At this point we stop accepting input. To do this, we | ||
1016 | * disable the receive line status interrupts, and tell the | ||
1017 | * interrupt driver to stop checking the data ready bit in the | ||
1018 | * line status register. | ||
1019 | */ | ||
1020 | info->IER &= ~UART_IER_RLSI; | ||
1021 | if (info->board->chip_flag) | ||
1022 | info->IER &= ~MOXA_MUST_RECV_ISR; | ||
1023 | |||
1024 | if (info->flags & ASYNC_INITIALIZED) { | ||
1025 | outb(info->IER, info->ioaddr + UART_IER); | ||
1026 | /* | ||
1027 | * Before we drop DTR, make sure the UART transmitter | ||
1028 | * has completely drained; this is especially | ||
1029 | * important if there is a transmit FIFO! | ||
1030 | */ | ||
1031 | timeout = jiffies + HZ; | ||
1032 | while (!(inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT)) { | ||
1033 | schedule_timeout_interruptible(5); | ||
1034 | if (time_after(jiffies, timeout)) | ||
1035 | break; | ||
1036 | } | ||
1037 | } | ||
1038 | mxser_shutdown(info); | ||
1039 | |||
1040 | if (tty->driver->flush_buffer) | ||
1041 | tty->driver->flush_buffer(tty); | ||
1042 | |||
1043 | tty_ldisc_flush(tty); | ||
1044 | |||
1045 | tty->closing = 0; | ||
1046 | info->event = 0; | ||
1047 | info->tty = NULL; | ||
1048 | if (info->blocked_open) { | ||
1049 | if (info->close_delay) | ||
1050 | schedule_timeout_interruptible(info->close_delay); | ||
1051 | wake_up_interruptible(&info->open_wait); | ||
1052 | } | ||
1053 | |||
1054 | info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); | ||
1055 | wake_up_interruptible(&info->close_wait); | ||
1056 | |||
1057 | } | ||
1058 | |||
1059 | static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) | ||
1060 | { | ||
1061 | int c, total = 0; | ||
1062 | struct mxser_port *info = tty->driver_data; | ||
1063 | unsigned long flags; | ||
1064 | |||
1065 | if (!info->xmit_buf) | ||
1066 | return 0; | ||
1067 | |||
1068 | while (1) { | ||
1069 | c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, | ||
1070 | SERIAL_XMIT_SIZE - info->xmit_head)); | ||
1071 | if (c <= 0) | ||
1072 | break; | ||
1073 | |||
1074 | memcpy(info->xmit_buf + info->xmit_head, buf, c); | ||
1075 | spin_lock_irqsave(&info->slock, flags); | ||
1076 | info->xmit_head = (info->xmit_head + c) & | ||
1077 | (SERIAL_XMIT_SIZE - 1); | ||
1078 | info->xmit_cnt += c; | ||
1079 | spin_unlock_irqrestore(&info->slock, flags); | ||
1080 | |||
1081 | buf += c; | ||
1082 | count -= c; | ||
1083 | total += c; | ||
1084 | } | ||
1085 | |||
1086 | if (info->xmit_cnt && !tty->stopped) { | ||
1087 | if (!tty->hw_stopped || | ||
1088 | (info->type == PORT_16550A) || | ||
1089 | (info->board->chip_flag)) { | ||
1090 | spin_lock_irqsave(&info->slock, flags); | ||
1091 | outb(info->IER & ~UART_IER_THRI, info->ioaddr + | ||
1092 | UART_IER); | ||
1093 | info->IER |= UART_IER_THRI; | ||
1094 | outb(info->IER, info->ioaddr + UART_IER); | ||
1095 | spin_unlock_irqrestore(&info->slock, flags); | ||
1096 | } | ||
1097 | } | ||
1098 | return total; | ||
1099 | } | ||
1100 | |||
1101 | static void mxser_put_char(struct tty_struct *tty, unsigned char ch) | ||
1102 | { | ||
1103 | struct mxser_port *info = tty->driver_data; | ||
1104 | unsigned long flags; | ||
1105 | |||
1106 | if (!info->xmit_buf) | ||
1107 | return; | ||
1108 | |||
1109 | if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) | ||
1110 | return; | ||
1111 | |||
1112 | spin_lock_irqsave(&info->slock, flags); | ||
1113 | info->xmit_buf[info->xmit_head++] = ch; | ||
1114 | info->xmit_head &= SERIAL_XMIT_SIZE - 1; | ||
1115 | info->xmit_cnt++; | ||
1116 | spin_unlock_irqrestore(&info->slock, flags); | ||
1117 | if (!tty->stopped) { | ||
1118 | if (!tty->hw_stopped || | ||
1119 | (info->type == PORT_16550A) || | ||
1120 | info->board->chip_flag) { | ||
1121 | spin_lock_irqsave(&info->slock, flags); | ||
1122 | outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); | ||
1123 | info->IER |= UART_IER_THRI; | ||
1124 | outb(info->IER, info->ioaddr + UART_IER); | ||
1125 | spin_unlock_irqrestore(&info->slock, flags); | ||
1126 | } | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1130 | |||
1131 | static void mxser_flush_chars(struct tty_struct *tty) | ||
1132 | { | ||
1133 | struct mxser_port *info = tty->driver_data; | ||
1134 | unsigned long flags; | ||
1135 | |||
1136 | if (info->xmit_cnt <= 0 || | ||
1137 | tty->stopped || | ||
1138 | !info->xmit_buf || | ||
1139 | (tty->hw_stopped && | ||
1140 | (info->type != PORT_16550A) && | ||
1141 | (!info->board->chip_flag) | ||
1142 | )) | ||
1143 | return; | ||
1144 | |||
1145 | spin_lock_irqsave(&info->slock, flags); | ||
1146 | |||
1147 | outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); | ||
1148 | info->IER |= UART_IER_THRI; | ||
1149 | outb(info->IER, info->ioaddr + UART_IER); | ||
1150 | |||
1151 | spin_unlock_irqrestore(&info->slock, flags); | ||
1152 | } | ||
1153 | |||
1154 | static int mxser_write_room(struct tty_struct *tty) | ||
1155 | { | ||
1156 | struct mxser_port *info = tty->driver_data; | ||
1157 | int ret; | ||
1158 | |||
1159 | ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; | ||
1160 | if (ret < 0) | ||
1161 | ret = 0; | ||
1162 | return ret; | ||
1163 | } | ||
1164 | |||
1165 | static int mxser_chars_in_buffer(struct tty_struct *tty) | ||
1166 | { | ||
1167 | struct mxser_port *info = tty->driver_data; | ||
1168 | return info->xmit_cnt; | ||
1169 | } | ||
1170 | |||
1171 | static void mxser_flush_buffer(struct tty_struct *tty) | ||
1172 | { | ||
1173 | struct mxser_port *info = tty->driver_data; | ||
1174 | char fcr; | ||
1175 | unsigned long flags; | ||
1176 | |||
1177 | |||
1178 | spin_lock_irqsave(&info->slock, flags); | ||
1179 | info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; | ||
1180 | |||
1181 | fcr = inb(info->ioaddr + UART_FCR); | ||
1182 | outb((fcr | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT), | ||
1183 | info->ioaddr + UART_FCR); | ||
1184 | outb(fcr, info->ioaddr + UART_FCR); | ||
1185 | |||
1186 | spin_unlock_irqrestore(&info->slock, flags); | ||
1187 | |||
1188 | tty_wakeup(tty); | ||
1189 | } | ||
1190 | |||
1191 | /* | ||
1192 | * ------------------------------------------------------------ | ||
1193 | * friends of mxser_ioctl() | ||
1194 | * ------------------------------------------------------------ | ||
1195 | */ | ||
1196 | static int mxser_get_serial_info(struct mxser_port *info, | ||
1197 | struct serial_struct __user *retinfo) | ||
1198 | { | ||
1199 | struct serial_struct tmp; | ||
1200 | |||
1201 | if (!retinfo) | ||
1202 | return -EFAULT; | ||
1203 | memset(&tmp, 0, sizeof(tmp)); | ||
1204 | tmp.type = info->type; | ||
1205 | tmp.line = info->tty->index; | ||
1206 | tmp.port = info->ioaddr; | ||
1207 | tmp.irq = info->board->irq; | ||
1208 | tmp.flags = info->flags; | ||
1209 | tmp.baud_base = info->baud_base; | ||
1210 | tmp.close_delay = info->close_delay; | ||
1211 | tmp.closing_wait = info->closing_wait; | ||
1212 | tmp.custom_divisor = info->custom_divisor; | ||
1213 | tmp.hub6 = 0; | ||
1214 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | ||
1215 | return -EFAULT; | ||
1216 | return 0; | ||
1217 | } | ||
1218 | |||
1219 | static int mxser_set_serial_info(struct mxser_port *info, | ||
1220 | struct serial_struct __user *new_info) | ||
1221 | { | ||
1222 | struct serial_struct new_serial; | ||
1223 | unsigned int flags; | ||
1224 | int retval = 0; | ||
1225 | |||
1226 | if (!new_info || !info->ioaddr) | ||
1227 | return -EFAULT; | ||
1228 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) | ||
1229 | return -EFAULT; | ||
1230 | |||
1231 | if ((new_serial.irq != info->board->irq) || | ||
1232 | (new_serial.port != info->ioaddr) || | ||
1233 | (new_serial.custom_divisor != info->custom_divisor) || | ||
1234 | (new_serial.baud_base != info->baud_base)) | ||
1235 | return -EPERM; | ||
1236 | |||
1237 | flags = info->flags & ASYNC_SPD_MASK; | ||
1238 | |||
1239 | if (!capable(CAP_SYS_ADMIN)) { | ||
1240 | if ((new_serial.baud_base != info->baud_base) || | ||
1241 | (new_serial.close_delay != info->close_delay) || | ||
1242 | ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK))) | ||
1243 | return -EPERM; | ||
1244 | info->flags = ((info->flags & ~ASYNC_USR_MASK) | | ||
1245 | (new_serial.flags & ASYNC_USR_MASK)); | ||
1246 | } else { | ||
1247 | /* | ||
1248 | * OK, past this point, all the error checking has been done. | ||
1249 | * At this point, we start making changes..... | ||
1250 | */ | ||
1251 | info->flags = ((info->flags & ~ASYNC_FLAGS) | | ||
1252 | (new_serial.flags & ASYNC_FLAGS)); | ||
1253 | info->close_delay = new_serial.close_delay * HZ / 100; | ||
1254 | info->closing_wait = new_serial.closing_wait * HZ / 100; | ||
1255 | info->tty->low_latency = | ||
1256 | (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; | ||
1257 | info->tty->low_latency = 0; | ||
1258 | } | ||
1259 | |||
1260 | info->type = new_serial.type; | ||
1261 | |||
1262 | process_txrx_fifo(info); | ||
1263 | |||
1264 | if (info->flags & ASYNC_INITIALIZED) { | ||
1265 | if (flags != (info->flags & ASYNC_SPD_MASK)) | ||
1266 | mxser_change_speed(info, NULL); | ||
1267 | } else | ||
1268 | retval = mxser_startup(info); | ||
1269 | |||
1270 | return retval; | ||
1271 | } | ||
1272 | |||
1273 | /* | ||
1274 | * mxser_get_lsr_info - get line status register info | ||
1275 | * | ||
1276 | * Purpose: Let user call ioctl() to get info when the UART physically | ||
1277 | * is emptied. On bus types like RS485, the transmitter must | ||
1278 | * release the bus after transmitting. This must be done when | ||
1279 | * the transmit shift register is empty, not be done when the | ||
1280 | * transmit holding register is empty. This functionality | ||
1281 | * allows an RS485 driver to be written in user space. | ||
1282 | */ | ||
1283 | static int mxser_get_lsr_info(struct mxser_port *info, | ||
1284 | unsigned int __user *value) | ||
1285 | { | ||
1286 | unsigned char status; | ||
1287 | unsigned int result; | ||
1288 | unsigned long flags; | ||
1289 | |||
1290 | spin_lock_irqsave(&info->slock, flags); | ||
1291 | status = inb(info->ioaddr + UART_LSR); | ||
1292 | spin_unlock_irqrestore(&info->slock, flags); | ||
1293 | result = ((status & UART_LSR_TEMT) ? TIOCSER_TEMT : 0); | ||
1294 | return put_user(result, value); | ||
1295 | } | ||
1296 | |||
1297 | /* | ||
1298 | * This routine sends a break character out the serial port. | ||
1299 | */ | ||
1300 | static void mxser_send_break(struct mxser_port *info, int duration) | ||
1301 | { | ||
1302 | unsigned long flags; | ||
1303 | |||
1304 | if (!info->ioaddr) | ||
1305 | return; | ||
1306 | set_current_state(TASK_INTERRUPTIBLE); | ||
1307 | spin_lock_irqsave(&info->slock, flags); | ||
1308 | outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC, | ||
1309 | info->ioaddr + UART_LCR); | ||
1310 | spin_unlock_irqrestore(&info->slock, flags); | ||
1311 | schedule_timeout(duration); | ||
1312 | spin_lock_irqsave(&info->slock, flags); | ||
1313 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, | ||
1314 | info->ioaddr + UART_LCR); | ||
1315 | spin_unlock_irqrestore(&info->slock, flags); | ||
1316 | } | ||
1317 | |||
1318 | static int mxser_tiocmget(struct tty_struct *tty, struct file *file) | ||
1319 | { | ||
1320 | struct mxser_port *info = tty->driver_data; | ||
1321 | unsigned char control, status; | ||
1322 | unsigned long flags; | ||
1323 | |||
1324 | |||
1325 | if (tty->index == MXSER_PORTS) | ||
1326 | return -ENOIOCTLCMD; | ||
1327 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | ||
1328 | return -EIO; | ||
1329 | |||
1330 | control = info->MCR; | ||
1331 | |||
1332 | spin_lock_irqsave(&info->slock, flags); | ||
1333 | status = inb(info->ioaddr + UART_MSR); | ||
1334 | if (status & UART_MSR_ANY_DELTA) | ||
1335 | mxser_check_modem_status(info, status); | ||
1336 | spin_unlock_irqrestore(&info->slock, flags); | ||
1337 | return ((control & UART_MCR_RTS) ? TIOCM_RTS : 0) | | ||
1338 | ((control & UART_MCR_DTR) ? TIOCM_DTR : 0) | | ||
1339 | ((status & UART_MSR_DCD) ? TIOCM_CAR : 0) | | ||
1340 | ((status & UART_MSR_RI) ? TIOCM_RNG : 0) | | ||
1341 | ((status & UART_MSR_DSR) ? TIOCM_DSR : 0) | | ||
1342 | ((status & UART_MSR_CTS) ? TIOCM_CTS : 0); | ||
1343 | } | ||
1344 | |||
1345 | static int mxser_tiocmset(struct tty_struct *tty, struct file *file, | ||
1346 | unsigned int set, unsigned int clear) | ||
1347 | { | ||
1348 | struct mxser_port *info = tty->driver_data; | ||
1349 | unsigned long flags; | ||
1350 | |||
1351 | |||
1352 | if (tty->index == MXSER_PORTS) | ||
1353 | return -ENOIOCTLCMD; | ||
1354 | if (test_bit(TTY_IO_ERROR, &tty->flags)) | ||
1355 | return -EIO; | ||
1356 | |||
1357 | spin_lock_irqsave(&info->slock, flags); | ||
1358 | |||
1359 | if (set & TIOCM_RTS) | ||
1360 | info->MCR |= UART_MCR_RTS; | ||
1361 | if (set & TIOCM_DTR) | ||
1362 | info->MCR |= UART_MCR_DTR; | ||
1363 | |||
1364 | if (clear & TIOCM_RTS) | ||
1365 | info->MCR &= ~UART_MCR_RTS; | ||
1366 | if (clear & TIOCM_DTR) | ||
1367 | info->MCR &= ~UART_MCR_DTR; | ||
1368 | |||
1369 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
1370 | spin_unlock_irqrestore(&info->slock, flags); | ||
1371 | return 0; | ||
1372 | } | ||
1373 | |||
1374 | static int mxser_program_mode(int port) | ||
1375 | { | ||
1376 | int id, i, j, n; | ||
1377 | |||
1378 | spin_lock(&gm_lock); | ||
1379 | outb(0, port); | ||
1380 | outb(0, port); | ||
1381 | outb(0, port); | ||
1382 | (void)inb(port); | ||
1383 | (void)inb(port); | ||
1384 | outb(0, port); | ||
1385 | (void)inb(port); | ||
1386 | spin_unlock(&gm_lock); | ||
1387 | |||
1388 | id = inb(port + 1) & 0x1F; | ||
1389 | if ((id != C168_ASIC_ID) && | ||
1390 | (id != C104_ASIC_ID) && | ||
1391 | (id != C102_ASIC_ID) && | ||
1392 | (id != CI132_ASIC_ID) && | ||
1393 | (id != CI134_ASIC_ID) && | ||
1394 | (id != CI104J_ASIC_ID)) | ||
1395 | return -1; | ||
1396 | for (i = 0, j = 0; i < 4; i++) { | ||
1397 | n = inb(port + 2); | ||
1398 | if (n == 'M') { | ||
1399 | j = 1; | ||
1400 | } else if ((j == 1) && (n == 1)) { | ||
1401 | j = 2; | ||
1402 | break; | ||
1403 | } else | ||
1404 | j = 0; | ||
1405 | } | ||
1406 | if (j != 2) | ||
1407 | id = -2; | ||
1408 | return id; | ||
1409 | } | ||
1410 | |||
1411 | static void mxser_normal_mode(int port) | ||
1412 | { | ||
1413 | int i, n; | ||
1414 | |||
1415 | outb(0xA5, port + 1); | ||
1416 | outb(0x80, port + 3); | ||
1417 | outb(12, port + 0); /* 9600 bps */ | ||
1418 | outb(0, port + 1); | ||
1419 | outb(0x03, port + 3); /* 8 data bits */ | ||
1420 | outb(0x13, port + 4); /* loop back mode */ | ||
1421 | for (i = 0; i < 16; i++) { | ||
1422 | n = inb(port + 5); | ||
1423 | if ((n & 0x61) == 0x60) | ||
1424 | break; | ||
1425 | if ((n & 1) == 1) | ||
1426 | (void)inb(port); | ||
1427 | } | ||
1428 | outb(0x00, port + 4); | ||
1429 | } | ||
1430 | |||
1431 | #define CHIP_SK 0x01 /* Serial Data Clock in Eprom */ | ||
1432 | #define CHIP_DO 0x02 /* Serial Data Output in Eprom */ | ||
1433 | #define CHIP_CS 0x04 /* Serial Chip Select in Eprom */ | ||
1434 | #define CHIP_DI 0x08 /* Serial Data Input in Eprom */ | ||
1435 | #define EN_CCMD 0x000 /* Chip's command register */ | ||
1436 | #define EN0_RSARLO 0x008 /* Remote start address reg 0 */ | ||
1437 | #define EN0_RSARHI 0x009 /* Remote start address reg 1 */ | ||
1438 | #define EN0_RCNTLO 0x00A /* Remote byte count reg WR */ | ||
1439 | #define EN0_RCNTHI 0x00B /* Remote byte count reg WR */ | ||
1440 | #define EN0_DCFG 0x00E /* Data configuration reg WR */ | ||
1441 | #define EN0_PORT 0x010 /* Rcv missed frame error counter RD */ | ||
1442 | #define ENC_PAGE0 0x000 /* Select page 0 of chip registers */ | ||
1443 | #define ENC_PAGE3 0x0C0 /* Select page 3 of chip registers */ | ||
1444 | static int mxser_read_register(int port, unsigned short *regs) | ||
1445 | { | ||
1446 | int i, k, value, id; | ||
1447 | unsigned int j; | ||
1448 | |||
1449 | id = mxser_program_mode(port); | ||
1450 | if (id < 0) | ||
1451 | return id; | ||
1452 | for (i = 0; i < 14; i++) { | ||
1453 | k = (i & 0x3F) | 0x180; | ||
1454 | for (j = 0x100; j > 0; j >>= 1) { | ||
1455 | outb(CHIP_CS, port); | ||
1456 | if (k & j) { | ||
1457 | outb(CHIP_CS | CHIP_DO, port); | ||
1458 | outb(CHIP_CS | CHIP_DO | CHIP_SK, port); /* A? bit of read */ | ||
1459 | } else { | ||
1460 | outb(CHIP_CS, port); | ||
1461 | outb(CHIP_CS | CHIP_SK, port); /* A? bit of read */ | ||
1462 | } | ||
1463 | } | ||
1464 | (void)inb(port); | ||
1465 | value = 0; | ||
1466 | for (k = 0, j = 0x8000; k < 16; k++, j >>= 1) { | ||
1467 | outb(CHIP_CS, port); | ||
1468 | outb(CHIP_CS | CHIP_SK, port); | ||
1469 | if (inb(port) & CHIP_DI) | ||
1470 | value |= j; | ||
1471 | } | ||
1472 | regs[i] = value; | ||
1473 | outb(0, port); | ||
1474 | } | ||
1475 | mxser_normal_mode(port); | ||
1476 | return id; | ||
1477 | } | ||
1478 | |||
1479 | static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | ||
1480 | { | ||
1481 | struct mxser_port *port; | ||
1482 | int result, status; | ||
1483 | unsigned int i, j; | ||
1484 | |||
1485 | switch (cmd) { | ||
1486 | case MOXA_GET_CONF: | ||
1487 | /* if (copy_to_user(argp, mxsercfg, | ||
1488 | sizeof(struct mxser_hwconf) * 4)) | ||
1489 | return -EFAULT; | ||
1490 | return 0;*/ | ||
1491 | return -ENXIO; | ||
1492 | case MOXA_GET_MAJOR: | ||
1493 | if (copy_to_user(argp, &ttymajor, sizeof(int))) | ||
1494 | return -EFAULT; | ||
1495 | return 0; | ||
1496 | |||
1497 | case MOXA_GET_CUMAJOR: | ||
1498 | if (copy_to_user(argp, &calloutmajor, sizeof(int))) | ||
1499 | return -EFAULT; | ||
1500 | return 0; | ||
1501 | |||
1502 | case MOXA_CHKPORTENABLE: | ||
1503 | result = 0; | ||
1504 | |||
1505 | for (i = 0; i < MXSER_BOARDS; i++) | ||
1506 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) | ||
1507 | if (mxser_boards[i].ports[j].ioaddr) | ||
1508 | result |= (1 << i); | ||
1509 | |||
1510 | return put_user(result, (unsigned long __user *)argp); | ||
1511 | case MOXA_GETDATACOUNT: | ||
1512 | if (copy_to_user(argp, &mxvar_log, sizeof(mxvar_log))) | ||
1513 | return -EFAULT; | ||
1514 | return 0; | ||
1515 | case MOXA_GETMSTATUS: | ||
1516 | for (i = 0; i < MXSER_BOARDS; i++) | ||
1517 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | ||
1518 | port = &mxser_boards[i].ports[j]; | ||
1519 | |||
1520 | GMStatus[i].ri = 0; | ||
1521 | if (!port->ioaddr) { | ||
1522 | GMStatus[i].dcd = 0; | ||
1523 | GMStatus[i].dsr = 0; | ||
1524 | GMStatus[i].cts = 0; | ||
1525 | continue; | ||
1526 | } | ||
1527 | |||
1528 | if (!port->tty || !port->tty->termios) | ||
1529 | GMStatus[i].cflag = | ||
1530 | port->normal_termios.c_cflag; | ||
1531 | else | ||
1532 | GMStatus[i].cflag = | ||
1533 | port->tty->termios->c_cflag; | ||
1534 | |||
1535 | status = inb(port->ioaddr + UART_MSR); | ||
1536 | if (status & 0x80 /*UART_MSR_DCD */ ) | ||
1537 | GMStatus[i].dcd = 1; | ||
1538 | else | ||
1539 | GMStatus[i].dcd = 0; | ||
1540 | |||
1541 | if (status & 0x20 /*UART_MSR_DSR */ ) | ||
1542 | GMStatus[i].dsr = 1; | ||
1543 | else | ||
1544 | GMStatus[i].dsr = 0; | ||
1545 | |||
1546 | |||
1547 | if (status & 0x10 /*UART_MSR_CTS */ ) | ||
1548 | GMStatus[i].cts = 1; | ||
1549 | else | ||
1550 | GMStatus[i].cts = 0; | ||
1551 | } | ||
1552 | if (copy_to_user(argp, GMStatus, | ||
1553 | sizeof(struct mxser_mstatus) * MXSER_PORTS)) | ||
1554 | return -EFAULT; | ||
1555 | return 0; | ||
1556 | case MOXA_ASPP_MON_EXT: { | ||
1557 | int status, p, shiftbit; | ||
1558 | unsigned long opmode; | ||
1559 | unsigned cflag, iflag; | ||
1560 | |||
1561 | for (i = 0; i < MXSER_BOARDS; i++) | ||
1562 | for (j = 0; j < MXSER_PORTS_PER_BOARD; j++) { | ||
1563 | port = &mxser_boards[i].ports[j]; | ||
1564 | if (!port->ioaddr) | ||
1565 | continue; | ||
1566 | |||
1567 | status = mxser_get_msr(port->ioaddr, 0, i); | ||
1568 | |||
1569 | if (status & UART_MSR_TERI) | ||
1570 | port->icount.rng++; | ||
1571 | if (status & UART_MSR_DDSR) | ||
1572 | port->icount.dsr++; | ||
1573 | if (status & UART_MSR_DDCD) | ||
1574 | port->icount.dcd++; | ||
1575 | if (status & UART_MSR_DCTS) | ||
1576 | port->icount.cts++; | ||
1577 | |||
1578 | port->mon_data.modem_status = status; | ||
1579 | mon_data_ext.rx_cnt[i] = port->mon_data.rxcnt; | ||
1580 | mon_data_ext.tx_cnt[i] = port->mon_data.txcnt; | ||
1581 | mon_data_ext.up_rxcnt[i] = | ||
1582 | port->mon_data.up_rxcnt; | ||
1583 | mon_data_ext.up_txcnt[i] = | ||
1584 | port->mon_data.up_txcnt; | ||
1585 | mon_data_ext.modem_status[i] = | ||
1586 | port->mon_data.modem_status; | ||
1587 | mon_data_ext.baudrate[i] = port->realbaud; | ||
1588 | |||
1589 | if (!port->tty || !port->tty->termios) { | ||
1590 | cflag = port->normal_termios.c_cflag; | ||
1591 | iflag = port->normal_termios.c_iflag; | ||
1592 | } else { | ||
1593 | cflag = port->tty->termios->c_cflag; | ||
1594 | iflag = port->tty->termios->c_iflag; | ||
1595 | } | ||
1596 | |||
1597 | mon_data_ext.databits[i] = cflag & CSIZE; | ||
1598 | |||
1599 | mon_data_ext.stopbits[i] = cflag & CSTOPB; | ||
1600 | |||
1601 | mon_data_ext.parity[i] = | ||
1602 | cflag & (PARENB | PARODD | CMSPAR); | ||
1603 | |||
1604 | mon_data_ext.flowctrl[i] = 0x00; | ||
1605 | |||
1606 | if (cflag & CRTSCTS) | ||
1607 | mon_data_ext.flowctrl[i] |= 0x03; | ||
1608 | |||
1609 | if (iflag & (IXON | IXOFF)) | ||
1610 | mon_data_ext.flowctrl[i] |= 0x0C; | ||
1611 | |||
1612 | if (port->type == PORT_16550A) | ||
1613 | mon_data_ext.fifo[i] = 1; | ||
1614 | else | ||
1615 | mon_data_ext.fifo[i] = 0; | ||
1616 | |||
1617 | p = i % 4; | ||
1618 | shiftbit = p * 2; | ||
1619 | opmode = inb(port->opmode_ioaddr) >> shiftbit; | ||
1620 | opmode &= OP_MODE_MASK; | ||
1621 | |||
1622 | mon_data_ext.iftype[i] = opmode; | ||
1623 | |||
1624 | } | ||
1625 | if (copy_to_user(argp, &mon_data_ext, | ||
1626 | sizeof(mon_data_ext))) | ||
1627 | return -EFAULT; | ||
1628 | |||
1629 | return 0; | ||
1630 | |||
1631 | } default: | ||
1632 | return -ENOIOCTLCMD; | ||
1633 | } | ||
1634 | return 0; | ||
1635 | } | ||
1636 | |||
1637 | static int mxser_ioctl(struct tty_struct *tty, struct file *file, | ||
1638 | unsigned int cmd, unsigned long arg) | ||
1639 | { | ||
1640 | struct mxser_port *info = tty->driver_data; | ||
1641 | struct async_icount cprev, cnow; /* kernel counter temps */ | ||
1642 | struct serial_icounter_struct __user *p_cuser; | ||
1643 | unsigned long templ; | ||
1644 | unsigned long flags; | ||
1645 | void __user *argp = (void __user *)arg; | ||
1646 | int retval; | ||
1647 | |||
1648 | if (tty->index == MXSER_PORTS) | ||
1649 | return mxser_ioctl_special(cmd, argp); | ||
1650 | |||
1651 | if (cmd == MOXA_SET_OP_MODE || cmd == MOXA_GET_OP_MODE) { | ||
1652 | int p; | ||
1653 | unsigned long opmode; | ||
1654 | static unsigned char ModeMask[] = { 0xfc, 0xf3, 0xcf, 0x3f }; | ||
1655 | int shiftbit; | ||
1656 | unsigned char val, mask; | ||
1657 | |||
1658 | p = tty->index % 4; | ||
1659 | if (cmd == MOXA_SET_OP_MODE) { | ||
1660 | if (get_user(opmode, (int __user *) argp)) | ||
1661 | return -EFAULT; | ||
1662 | if (opmode != RS232_MODE && | ||
1663 | opmode != RS485_2WIRE_MODE && | ||
1664 | opmode != RS422_MODE && | ||
1665 | opmode != RS485_4WIRE_MODE) | ||
1666 | return -EFAULT; | ||
1667 | mask = ModeMask[p]; | ||
1668 | shiftbit = p * 2; | ||
1669 | val = inb(info->opmode_ioaddr); | ||
1670 | val &= mask; | ||
1671 | val |= (opmode << shiftbit); | ||
1672 | outb(val, info->opmode_ioaddr); | ||
1673 | } else { | ||
1674 | shiftbit = p * 2; | ||
1675 | opmode = inb(info->opmode_ioaddr) >> shiftbit; | ||
1676 | opmode &= OP_MODE_MASK; | ||
1677 | if (copy_to_user(argp, &opmode, sizeof(int))) | ||
1678 | return -EFAULT; | ||
1679 | } | ||
1680 | return 0; | ||
1681 | } | ||
1682 | |||
1683 | if (cmd != TIOCGSERIAL && cmd != TIOCMIWAIT && cmd != TIOCGICOUNT && | ||
1684 | test_bit(TTY_IO_ERROR, &tty->flags)) | ||
1685 | return -EIO; | ||
1686 | |||
1687 | switch (cmd) { | ||
1688 | case TCSBRK: /* SVID version: non-zero arg --> no break */ | ||
1689 | retval = tty_check_change(tty); | ||
1690 | if (retval) | ||
1691 | return retval; | ||
1692 | tty_wait_until_sent(tty, 0); | ||
1693 | if (!arg) | ||
1694 | mxser_send_break(info, HZ / 4); /* 1/4 second */ | ||
1695 | return 0; | ||
1696 | case TCSBRKP: /* support for POSIX tcsendbreak() */ | ||
1697 | retval = tty_check_change(tty); | ||
1698 | if (retval) | ||
1699 | return retval; | ||
1700 | tty_wait_until_sent(tty, 0); | ||
1701 | mxser_send_break(info, arg ? arg * (HZ / 10) : HZ / 4); | ||
1702 | return 0; | ||
1703 | case TIOCGSOFTCAR: | ||
1704 | return put_user(C_CLOCAL(tty) ? 1 : 0, (unsigned long __user *)argp); | ||
1705 | case TIOCSSOFTCAR: | ||
1706 | if (get_user(templ, (unsigned long __user *) argp)) | ||
1707 | return -EFAULT; | ||
1708 | arg = templ; | ||
1709 | tty->termios->c_cflag = ((tty->termios->c_cflag & ~CLOCAL) | (arg ? CLOCAL : 0)); | ||
1710 | return 0; | ||
1711 | case TIOCGSERIAL: | ||
1712 | return mxser_get_serial_info(info, argp); | ||
1713 | case TIOCSSERIAL: | ||
1714 | return mxser_set_serial_info(info, argp); | ||
1715 | case TIOCSERGETLSR: /* Get line status register */ | ||
1716 | return mxser_get_lsr_info(info, argp); | ||
1717 | /* | ||
1718 | * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change | ||
1719 | * - mask passed in arg for lines of interest | ||
1720 | * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking) | ||
1721 | * Caller should use TIOCGICOUNT to see which one it was | ||
1722 | */ | ||
1723 | case TIOCMIWAIT: { | ||
1724 | DECLARE_WAITQUEUE(wait, current); | ||
1725 | int ret; | ||
1726 | spin_lock_irqsave(&info->slock, flags); | ||
1727 | cprev = info->icount; /* note the counters on entry */ | ||
1728 | spin_unlock_irqrestore(&info->slock, flags); | ||
1729 | |||
1730 | add_wait_queue(&info->delta_msr_wait, &wait); | ||
1731 | while (1) { | ||
1732 | spin_lock_irqsave(&info->slock, flags); | ||
1733 | cnow = info->icount; /* atomic copy */ | ||
1734 | spin_unlock_irqrestore(&info->slock, flags); | ||
1735 | |||
1736 | set_current_state(TASK_INTERRUPTIBLE); | ||
1737 | if (((arg & TIOCM_RNG) && | ||
1738 | (cnow.rng != cprev.rng)) || | ||
1739 | ((arg & TIOCM_DSR) && | ||
1740 | (cnow.dsr != cprev.dsr)) || | ||
1741 | ((arg & TIOCM_CD) && | ||
1742 | (cnow.dcd != cprev.dcd)) || | ||
1743 | ((arg & TIOCM_CTS) && | ||
1744 | (cnow.cts != cprev.cts))) { | ||
1745 | ret = 0; | ||
1746 | break; | ||
1747 | } | ||
1748 | /* see if a signal did it */ | ||
1749 | if (signal_pending(current)) { | ||
1750 | ret = -ERESTARTSYS; | ||
1751 | break; | ||
1752 | } | ||
1753 | cprev = cnow; | ||
1754 | } | ||
1755 | current->state = TASK_RUNNING; | ||
1756 | remove_wait_queue(&info->delta_msr_wait, &wait); | ||
1757 | break; | ||
1758 | } | ||
1759 | /* NOTREACHED */ | ||
1760 | /* | ||
1761 | * Get counter of input serial line interrupts (DCD,RI,DSR,CTS) | ||
1762 | * Return: write counters to the user passed counter struct | ||
1763 | * NB: both 1->0 and 0->1 transitions are counted except for | ||
1764 | * RI where only 0->1 is counted. | ||
1765 | */ | ||
1766 | case TIOCGICOUNT: | ||
1767 | spin_lock_irqsave(&info->slock, flags); | ||
1768 | cnow = info->icount; | ||
1769 | spin_unlock_irqrestore(&info->slock, flags); | ||
1770 | p_cuser = argp; | ||
1771 | if (put_user(cnow.frame, &p_cuser->frame)) | ||
1772 | return -EFAULT; | ||
1773 | if (put_user(cnow.brk, &p_cuser->brk)) | ||
1774 | return -EFAULT; | ||
1775 | if (put_user(cnow.overrun, &p_cuser->overrun)) | ||
1776 | return -EFAULT; | ||
1777 | if (put_user(cnow.buf_overrun, &p_cuser->buf_overrun)) | ||
1778 | return -EFAULT; | ||
1779 | if (put_user(cnow.parity, &p_cuser->parity)) | ||
1780 | return -EFAULT; | ||
1781 | if (put_user(cnow.rx, &p_cuser->rx)) | ||
1782 | return -EFAULT; | ||
1783 | if (put_user(cnow.tx, &p_cuser->tx)) | ||
1784 | return -EFAULT; | ||
1785 | put_user(cnow.cts, &p_cuser->cts); | ||
1786 | put_user(cnow.dsr, &p_cuser->dsr); | ||
1787 | put_user(cnow.rng, &p_cuser->rng); | ||
1788 | put_user(cnow.dcd, &p_cuser->dcd); | ||
1789 | return 0; | ||
1790 | case MOXA_HighSpeedOn: | ||
1791 | return put_user(info->baud_base != 115200 ? 1 : 0, (int __user *)argp); | ||
1792 | case MOXA_SDS_RSTICOUNTER: | ||
1793 | info->mon_data.rxcnt = 0; | ||
1794 | info->mon_data.txcnt = 0; | ||
1795 | return 0; | ||
1796 | case MOXA_ASPP_SETBAUD:{ | ||
1797 | long baud; | ||
1798 | if (get_user(baud, (long __user *)argp)) | ||
1799 | return -EFAULT; | ||
1800 | mxser_set_baud(info, baud); | ||
1801 | return 0; | ||
1802 | } | ||
1803 | case MOXA_ASPP_GETBAUD: | ||
1804 | if (copy_to_user(argp, &info->realbaud, sizeof(long))) | ||
1805 | return -EFAULT; | ||
1806 | |||
1807 | return 0; | ||
1808 | |||
1809 | case MOXA_ASPP_OQUEUE:{ | ||
1810 | int len, lsr; | ||
1811 | |||
1812 | len = mxser_chars_in_buffer(tty); | ||
1813 | |||
1814 | lsr = inb(info->ioaddr + UART_LSR) & UART_LSR_TEMT; | ||
1815 | |||
1816 | len += (lsr ? 0 : 1); | ||
1817 | |||
1818 | if (copy_to_user(argp, &len, sizeof(int))) | ||
1819 | return -EFAULT; | ||
1820 | |||
1821 | return 0; | ||
1822 | } | ||
1823 | case MOXA_ASPP_MON: { | ||
1824 | int mcr, status; | ||
1825 | |||
1826 | status = mxser_get_msr(info->ioaddr, 1, tty->index); | ||
1827 | mxser_check_modem_status(info, status); | ||
1828 | |||
1829 | mcr = inb(info->ioaddr + UART_MCR); | ||
1830 | if (mcr & MOXA_MUST_MCR_XON_FLAG) | ||
1831 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFHOLD; | ||
1832 | else | ||
1833 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFHOLD; | ||
1834 | |||
1835 | if (mcr & MOXA_MUST_MCR_TX_XON) | ||
1836 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_XOFFXENT; | ||
1837 | else | ||
1838 | info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; | ||
1839 | |||
1840 | if (info->tty->hw_stopped) | ||
1841 | info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; | ||
1842 | else | ||
1843 | info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; | ||
1844 | |||
1845 | if (copy_to_user(argp, &info->mon_data, | ||
1846 | sizeof(struct mxser_mon))) | ||
1847 | return -EFAULT; | ||
1848 | |||
1849 | return 0; | ||
1850 | } | ||
1851 | case MOXA_ASPP_LSTATUS: { | ||
1852 | if (copy_to_user(argp, &info->err_shadow, | ||
1853 | sizeof(unsigned char))) | ||
1854 | return -EFAULT; | ||
1855 | |||
1856 | info->err_shadow = 0; | ||
1857 | return 0; | ||
1858 | } | ||
1859 | case MOXA_SET_BAUD_METHOD: { | ||
1860 | int method; | ||
1861 | |||
1862 | if (get_user(method, (int __user *)argp)) | ||
1863 | return -EFAULT; | ||
1864 | mxser_set_baud_method[tty->index] = method; | ||
1865 | if (copy_to_user(argp, &method, sizeof(int))) | ||
1866 | return -EFAULT; | ||
1867 | |||
1868 | return 0; | ||
1869 | } | ||
1870 | default: | ||
1871 | return -ENOIOCTLCMD; | ||
1872 | } | ||
1873 | return 0; | ||
1874 | } | ||
1875 | |||
1876 | static void mxser_stoprx(struct tty_struct *tty) | ||
1877 | { | ||
1878 | struct mxser_port *info = tty->driver_data; | ||
1879 | |||
1880 | info->ldisc_stop_rx = 1; | ||
1881 | if (I_IXOFF(tty)) { | ||
1882 | if (info->board->chip_flag) { | ||
1883 | info->IER &= ~MOXA_MUST_RECV_ISR; | ||
1884 | outb(info->IER, info->ioaddr + UART_IER); | ||
1885 | } else { | ||
1886 | info->x_char = STOP_CHAR(tty); | ||
1887 | outb(0, info->ioaddr + UART_IER); | ||
1888 | info->IER |= UART_IER_THRI; | ||
1889 | outb(info->IER, info->ioaddr + UART_IER); | ||
1890 | } | ||
1891 | } | ||
1892 | |||
1893 | if (info->tty->termios->c_cflag & CRTSCTS) { | ||
1894 | info->MCR &= ~UART_MCR_RTS; | ||
1895 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
1896 | } | ||
1897 | } | ||
1898 | |||
1899 | /* | ||
1900 | * This routine is called by the upper-layer tty layer to signal that | ||
1901 | * incoming characters should be throttled. | ||
1902 | */ | ||
1903 | static void mxser_throttle(struct tty_struct *tty) | ||
1904 | { | ||
1905 | mxser_stoprx(tty); | ||
1906 | } | ||
1907 | |||
1908 | static void mxser_unthrottle(struct tty_struct *tty) | ||
1909 | { | ||
1910 | struct mxser_port *info = tty->driver_data; | ||
1911 | |||
1912 | /* startrx */ | ||
1913 | info->ldisc_stop_rx = 0; | ||
1914 | if (I_IXOFF(tty)) { | ||
1915 | if (info->x_char) | ||
1916 | info->x_char = 0; | ||
1917 | else { | ||
1918 | if (info->board->chip_flag) { | ||
1919 | info->IER |= MOXA_MUST_RECV_ISR; | ||
1920 | outb(info->IER, info->ioaddr + UART_IER); | ||
1921 | } else { | ||
1922 | info->x_char = START_CHAR(tty); | ||
1923 | outb(0, info->ioaddr + UART_IER); | ||
1924 | info->IER |= UART_IER_THRI; | ||
1925 | outb(info->IER, info->ioaddr + UART_IER); | ||
1926 | } | ||
1927 | } | ||
1928 | } | ||
1929 | |||
1930 | if (info->tty->termios->c_cflag & CRTSCTS) { | ||
1931 | info->MCR |= UART_MCR_RTS; | ||
1932 | outb(info->MCR, info->ioaddr + UART_MCR); | ||
1933 | } | ||
1934 | } | ||
1935 | |||
1936 | /* | ||
1937 | * mxser_stop() and mxser_start() | ||
1938 | * | ||
1939 | * This routines are called before setting or resetting tty->stopped. | ||
1940 | * They enable or disable transmitter interrupts, as necessary. | ||
1941 | */ | ||
1942 | static void mxser_stop(struct tty_struct *tty) | ||
1943 | { | ||
1944 | struct mxser_port *info = tty->driver_data; | ||
1945 | unsigned long flags; | ||
1946 | |||
1947 | spin_lock_irqsave(&info->slock, flags); | ||
1948 | if (info->IER & UART_IER_THRI) { | ||
1949 | info->IER &= ~UART_IER_THRI; | ||
1950 | outb(info->IER, info->ioaddr + UART_IER); | ||
1951 | } | ||
1952 | spin_unlock_irqrestore(&info->slock, flags); | ||
1953 | } | ||
1954 | |||
1955 | static void mxser_start(struct tty_struct *tty) | ||
1956 | { | ||
1957 | struct mxser_port *info = tty->driver_data; | ||
1958 | unsigned long flags; | ||
1959 | |||
1960 | spin_lock_irqsave(&info->slock, flags); | ||
1961 | if (info->xmit_cnt && info->xmit_buf) { | ||
1962 | outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); | ||
1963 | info->IER |= UART_IER_THRI; | ||
1964 | outb(info->IER, info->ioaddr + UART_IER); | ||
1965 | } | ||
1966 | spin_unlock_irqrestore(&info->slock, flags); | ||
1967 | } | ||
1968 | |||
1969 | static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | ||
1970 | { | ||
1971 | struct mxser_port *info = tty->driver_data; | ||
1972 | unsigned long flags; | ||
1973 | |||
1974 | if ((tty->termios->c_cflag != old_termios->c_cflag) || | ||
1975 | (RELEVANT_IFLAG(tty->termios->c_iflag) != RELEVANT_IFLAG(old_termios->c_iflag))) { | ||
1976 | |||
1977 | mxser_change_speed(info, old_termios); | ||
1978 | |||
1979 | if ((old_termios->c_cflag & CRTSCTS) && | ||
1980 | !(tty->termios->c_cflag & CRTSCTS)) { | ||
1981 | tty->hw_stopped = 0; | ||
1982 | mxser_start(tty); | ||
1983 | } | ||
1984 | } | ||
1985 | |||
1986 | /* Handle sw stopped */ | ||
1987 | if ((old_termios->c_iflag & IXON) && | ||
1988 | !(tty->termios->c_iflag & IXON)) { | ||
1989 | tty->stopped = 0; | ||
1990 | |||
1991 | if (info->board->chip_flag) { | ||
1992 | spin_lock_irqsave(&info->slock, flags); | ||
1993 | DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(info->ioaddr); | ||
1994 | spin_unlock_irqrestore(&info->slock, flags); | ||
1995 | } | ||
1996 | |||
1997 | mxser_start(tty); | ||
1998 | } | ||
1999 | } | ||
2000 | |||
2001 | /* | ||
2002 | * mxser_wait_until_sent() --- wait until the transmitter is empty | ||
2003 | */ | ||
2004 | static void mxser_wait_until_sent(struct tty_struct *tty, int timeout) | ||
2005 | { | ||
2006 | struct mxser_port *info = tty->driver_data; | ||
2007 | unsigned long orig_jiffies, char_time; | ||
2008 | int lsr; | ||
2009 | |||
2010 | if (info->type == PORT_UNKNOWN) | ||
2011 | return; | ||
2012 | |||
2013 | if (info->xmit_fifo_size == 0) | ||
2014 | return; /* Just in case.... */ | ||
2015 | |||
2016 | orig_jiffies = jiffies; | ||
2017 | /* | ||
2018 | * Set the check interval to be 1/5 of the estimated time to | ||
2019 | * send a single character, and make it at least 1. The check | ||
2020 | * interval should also be less than the timeout. | ||
2021 | * | ||
2022 | * Note: we have to use pretty tight timings here to satisfy | ||
2023 | * the NIST-PCTS. | ||
2024 | */ | ||
2025 | char_time = (info->timeout - HZ / 50) / info->xmit_fifo_size; | ||
2026 | char_time = char_time / 5; | ||
2027 | if (char_time == 0) | ||
2028 | char_time = 1; | ||
2029 | if (timeout && timeout < char_time) | ||
2030 | char_time = timeout; | ||
2031 | /* | ||
2032 | * If the transmitter hasn't cleared in twice the approximate | ||
2033 | * amount of time to send the entire FIFO, it probably won't | ||
2034 | * ever clear. This assumes the UART isn't doing flow | ||
2035 | * control, which is currently the case. Hence, if it ever | ||
2036 | * takes longer than info->timeout, this is probably due to a | ||
2037 | * UART bug of some kind. So, we clamp the timeout parameter at | ||
2038 | * 2*info->timeout. | ||
2039 | */ | ||
2040 | if (!timeout || timeout > 2 * info->timeout) | ||
2041 | timeout = 2 * info->timeout; | ||
2042 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | ||
2043 | printk(KERN_DEBUG "In rs_wait_until_sent(%d) check=%lu...", | ||
2044 | timeout, char_time); | ||
2045 | printk("jiff=%lu...", jiffies); | ||
2046 | #endif | ||
2047 | while (!((lsr = inb(info->ioaddr + UART_LSR)) & UART_LSR_TEMT)) { | ||
2048 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | ||
2049 | printk("lsr = %d (jiff=%lu)...", lsr, jiffies); | ||
2050 | #endif | ||
2051 | schedule_timeout_interruptible(char_time); | ||
2052 | if (signal_pending(current)) | ||
2053 | break; | ||
2054 | if (timeout && time_after(jiffies, orig_jiffies + timeout)) | ||
2055 | break; | ||
2056 | } | ||
2057 | set_current_state(TASK_RUNNING); | ||
2058 | |||
2059 | #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT | ||
2060 | printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies); | ||
2061 | #endif | ||
2062 | } | ||
2063 | |||
2064 | /* | ||
2065 | * This routine is called by tty_hangup() when a hangup is signaled. | ||
2066 | */ | ||
2067 | void mxser_hangup(struct tty_struct *tty) | ||
2068 | { | ||
2069 | struct mxser_port *info = tty->driver_data; | ||
2070 | |||
2071 | mxser_flush_buffer(tty); | ||
2072 | mxser_shutdown(info); | ||
2073 | info->event = 0; | ||
2074 | info->count = 0; | ||
2075 | info->flags &= ~ASYNC_NORMAL_ACTIVE; | ||
2076 | info->tty = NULL; | ||
2077 | wake_up_interruptible(&info->open_wait); | ||
2078 | } | ||
2079 | |||
2080 | /* | ||
2081 | * mxser_rs_break() --- routine which turns the break handling on or off | ||
2082 | */ | ||
2083 | static void mxser_rs_break(struct tty_struct *tty, int break_state) | ||
2084 | { | ||
2085 | struct mxser_port *info = tty->driver_data; | ||
2086 | unsigned long flags; | ||
2087 | |||
2088 | spin_lock_irqsave(&info->slock, flags); | ||
2089 | if (break_state == -1) | ||
2090 | outb(inb(info->ioaddr + UART_LCR) | UART_LCR_SBC, | ||
2091 | info->ioaddr + UART_LCR); | ||
2092 | else | ||
2093 | outb(inb(info->ioaddr + UART_LCR) & ~UART_LCR_SBC, | ||
2094 | info->ioaddr + UART_LCR); | ||
2095 | spin_unlock_irqrestore(&info->slock, flags); | ||
2096 | } | ||
2097 | |||
2098 | static void mxser_receive_chars(struct mxser_port *port, int *status) | ||
2099 | { | ||
2100 | struct tty_struct *tty = port->tty; | ||
2101 | unsigned char ch, gdl; | ||
2102 | int ignored = 0; | ||
2103 | int cnt = 0; | ||
2104 | int recv_room; | ||
2105 | int max = 256; | ||
2106 | unsigned long flags; | ||
2107 | |||
2108 | spin_lock_irqsave(&port->slock, flags); | ||
2109 | |||
2110 | recv_room = tty->receive_room; | ||
2111 | if ((recv_room == 0) && (!port->ldisc_stop_rx)) | ||
2112 | mxser_stoprx(tty); | ||
2113 | |||
2114 | if (port->board->chip_flag != MOXA_OTHER_UART) { | ||
2115 | |||
2116 | if (*status & UART_LSR_SPECIAL) | ||
2117 | goto intr_old; | ||
2118 | if (port->board->chip_flag == MOXA_MUST_MU860_HWID && | ||
2119 | (*status & MOXA_MUST_LSR_RERR)) | ||
2120 | goto intr_old; | ||
2121 | if (*status & MOXA_MUST_LSR_RERR) | ||
2122 | goto intr_old; | ||
2123 | |||
2124 | gdl = inb(port->ioaddr + MOXA_MUST_GDL_REGISTER); | ||
2125 | |||
2126 | if (port->board->chip_flag == MOXA_MUST_MU150_HWID) | ||
2127 | gdl &= MOXA_MUST_GDL_MASK; | ||
2128 | if (gdl >= recv_room) { | ||
2129 | if (!port->ldisc_stop_rx) | ||
2130 | mxser_stoprx(tty); | ||
2131 | } | ||
2132 | while (gdl--) { | ||
2133 | ch = inb(port->ioaddr + UART_RX); | ||
2134 | tty_insert_flip_char(tty, ch, 0); | ||
2135 | cnt++; | ||
2136 | } | ||
2137 | goto end_intr; | ||
2138 | } | ||
2139 | intr_old: | ||
2140 | |||
2141 | do { | ||
2142 | if (max-- < 0) | ||
2143 | break; | ||
2144 | |||
2145 | ch = inb(port->ioaddr + UART_RX); | ||
2146 | if (port->board->chip_flag && (*status & UART_LSR_OE)) | ||
2147 | outb(0x23, port->ioaddr + UART_FCR); | ||
2148 | *status &= port->read_status_mask; | ||
2149 | if (*status & port->ignore_status_mask) { | ||
2150 | if (++ignored > 100) | ||
2151 | break; | ||
2152 | } else { | ||
2153 | char flag = 0; | ||
2154 | if (*status & UART_LSR_SPECIAL) { | ||
2155 | if (*status & UART_LSR_BI) { | ||
2156 | flag = TTY_BREAK; | ||
2157 | port->icount.brk++; | ||
2158 | |||
2159 | if (port->flags & ASYNC_SAK) | ||
2160 | do_SAK(tty); | ||
2161 | } else if (*status & UART_LSR_PE) { | ||
2162 | flag = TTY_PARITY; | ||
2163 | port->icount.parity++; | ||
2164 | } else if (*status & UART_LSR_FE) { | ||
2165 | flag = TTY_FRAME; | ||
2166 | port->icount.frame++; | ||
2167 | } else if (*status & UART_LSR_OE) { | ||
2168 | flag = TTY_OVERRUN; | ||
2169 | port->icount.overrun++; | ||
2170 | } | ||
2171 | } | ||
2172 | tty_insert_flip_char(tty, ch, flag); | ||
2173 | cnt++; | ||
2174 | if (cnt >= recv_room) { | ||
2175 | if (!port->ldisc_stop_rx) | ||
2176 | mxser_stoprx(tty); | ||
2177 | break; | ||
2178 | } | ||
2179 | |||
2180 | } | ||
2181 | |||
2182 | if (port->board->chip_flag) | ||
2183 | break; | ||
2184 | |||
2185 | *status = inb(port->ioaddr + UART_LSR); | ||
2186 | } while (*status & UART_LSR_DR); | ||
2187 | |||
2188 | end_intr: | ||
2189 | mxvar_log.rxcnt[port->tty->index] += cnt; | ||
2190 | port->mon_data.rxcnt += cnt; | ||
2191 | port->mon_data.up_rxcnt += cnt; | ||
2192 | spin_unlock_irqrestore(&port->slock, flags); | ||
2193 | |||
2194 | tty_flip_buffer_push(tty); | ||
2195 | } | ||
2196 | |||
2197 | static void mxser_transmit_chars(struct mxser_port *port) | ||
2198 | { | ||
2199 | int count, cnt; | ||
2200 | unsigned long flags; | ||
2201 | |||
2202 | spin_lock_irqsave(&port->slock, flags); | ||
2203 | |||
2204 | if (port->x_char) { | ||
2205 | outb(port->x_char, port->ioaddr + UART_TX); | ||
2206 | port->x_char = 0; | ||
2207 | mxvar_log.txcnt[port->tty->index]++; | ||
2208 | port->mon_data.txcnt++; | ||
2209 | port->mon_data.up_txcnt++; | ||
2210 | port->icount.tx++; | ||
2211 | goto unlock; | ||
2212 | } | ||
2213 | |||
2214 | if (port->xmit_buf == 0) | ||
2215 | goto unlock; | ||
2216 | |||
2217 | if ((port->xmit_cnt <= 0) || port->tty->stopped || | ||
2218 | (port->tty->hw_stopped && | ||
2219 | (port->type != PORT_16550A) && | ||
2220 | (!port->board->chip_flag))) { | ||
2221 | port->IER &= ~UART_IER_THRI; | ||
2222 | outb(port->IER, port->ioaddr + UART_IER); | ||
2223 | goto unlock; | ||
2224 | } | ||
2225 | |||
2226 | cnt = port->xmit_cnt; | ||
2227 | count = port->xmit_fifo_size; | ||
2228 | do { | ||
2229 | outb(port->xmit_buf[port->xmit_tail++], | ||
2230 | port->ioaddr + UART_TX); | ||
2231 | port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); | ||
2232 | if (--port->xmit_cnt <= 0) | ||
2233 | break; | ||
2234 | } while (--count > 0); | ||
2235 | mxvar_log.txcnt[port->tty->index] += (cnt - port->xmit_cnt); | ||
2236 | |||
2237 | port->mon_data.txcnt += (cnt - port->xmit_cnt); | ||
2238 | port->mon_data.up_txcnt += (cnt - port->xmit_cnt); | ||
2239 | port->icount.tx += (cnt - port->xmit_cnt); | ||
2240 | |||
2241 | if (port->xmit_cnt < WAKEUP_CHARS) { | ||
2242 | set_bit(MXSER_EVENT_TXLOW, &port->event); | ||
2243 | schedule_work(&port->tqueue); | ||
2244 | } | ||
2245 | if (port->xmit_cnt <= 0) { | ||
2246 | port->IER &= ~UART_IER_THRI; | ||
2247 | outb(port->IER, port->ioaddr + UART_IER); | ||
2248 | } | ||
2249 | unlock: | ||
2250 | spin_unlock_irqrestore(&port->slock, flags); | ||
2251 | } | ||
2252 | |||
2253 | /* | ||
2254 | * This is the serial driver's generic interrupt routine | ||
2255 | */ | ||
2256 | static irqreturn_t mxser_interrupt(int irq, void *dev_id) | ||
2257 | { | ||
2258 | int status, iir, i; | ||
2259 | struct mxser_board *brd = NULL; | ||
2260 | struct mxser_port *port; | ||
2261 | int max, irqbits, bits, msr; | ||
2262 | int pass_counter = 0; | ||
2263 | unsigned int int_cnt; | ||
2264 | int handled = IRQ_NONE; | ||
2265 | |||
2266 | for (i = 0; i < MXSER_BOARDS; i++) | ||
2267 | if (dev_id == &mxser_boards[i]) { | ||
2268 | brd = dev_id; | ||
2269 | break; | ||
2270 | } | ||
2271 | |||
2272 | if (i == MXSER_BOARDS) | ||
2273 | goto irq_stop; | ||
2274 | if (brd == NULL) | ||
2275 | goto irq_stop; | ||
2276 | max = brd->info->nports; | ||
2277 | while (1) { | ||
2278 | irqbits = inb(brd->vector) & brd->vector_mask; | ||
2279 | if (irqbits == brd->vector_mask) | ||
2280 | break; | ||
2281 | |||
2282 | handled = IRQ_HANDLED; | ||
2283 | for (i = 0, bits = 1; i < max; i++, irqbits |= bits, bits <<= 1) { | ||
2284 | if (irqbits == brd->vector_mask) | ||
2285 | break; | ||
2286 | if (bits & irqbits) | ||
2287 | continue; | ||
2288 | port = &brd->ports[i]; | ||
2289 | |||
2290 | int_cnt = 0; | ||
2291 | do { | ||
2292 | iir = inb(port->ioaddr + UART_IIR); | ||
2293 | if (iir & UART_IIR_NO_INT) | ||
2294 | break; | ||
2295 | iir &= MOXA_MUST_IIR_MASK; | ||
2296 | if (!port->tty) { | ||
2297 | status = inb(port->ioaddr + UART_LSR); | ||
2298 | outb(0x27, port->ioaddr + UART_FCR); | ||
2299 | inb(port->ioaddr + UART_MSR); | ||
2300 | break; | ||
2301 | } | ||
2302 | |||
2303 | status = inb(port->ioaddr + UART_LSR); | ||
2304 | |||
2305 | if (status & UART_LSR_PE) | ||
2306 | port->err_shadow |= NPPI_NOTIFY_PARITY; | ||
2307 | if (status & UART_LSR_FE) | ||
2308 | port->err_shadow |= NPPI_NOTIFY_FRAMING; | ||
2309 | if (status & UART_LSR_OE) | ||
2310 | port->err_shadow |= | ||
2311 | NPPI_NOTIFY_HW_OVERRUN; | ||
2312 | if (status & UART_LSR_BI) | ||
2313 | port->err_shadow |= NPPI_NOTIFY_BREAK; | ||
2314 | |||
2315 | if (port->board->chip_flag) { | ||
2316 | if (iir == MOXA_MUST_IIR_GDA || | ||
2317 | iir == MOXA_MUST_IIR_RDA || | ||
2318 | iir == MOXA_MUST_IIR_RTO || | ||
2319 | iir == MOXA_MUST_IIR_LSR) | ||
2320 | mxser_receive_chars(port, | ||
2321 | &status); | ||
2322 | |||
2323 | } else { | ||
2324 | status &= port->read_status_mask; | ||
2325 | if (status & UART_LSR_DR) | ||
2326 | mxser_receive_chars(port, | ||
2327 | &status); | ||
2328 | } | ||
2329 | msr = inb(port->ioaddr + UART_MSR); | ||
2330 | if (msr & UART_MSR_ANY_DELTA) | ||
2331 | mxser_check_modem_status(port, msr); | ||
2332 | |||
2333 | if (port->board->chip_flag) { | ||
2334 | if (iir == 0x02 && (status & | ||
2335 | UART_LSR_THRE)) | ||
2336 | mxser_transmit_chars(port); | ||
2337 | } else { | ||
2338 | if (status & UART_LSR_THRE) | ||
2339 | mxser_transmit_chars(port); | ||
2340 | } | ||
2341 | } while (int_cnt++ < MXSER_ISR_PASS_LIMIT); | ||
2342 | } | ||
2343 | if (pass_counter++ > MXSER_ISR_PASS_LIMIT) | ||
2344 | break; /* Prevent infinite loops */ | ||
2345 | } | ||
2346 | |||
2347 | irq_stop: | ||
2348 | return handled; | ||
2349 | } | ||
2350 | |||
2351 | static const struct tty_operations mxser_ops = { | ||
2352 | .open = mxser_open, | ||
2353 | .close = mxser_close, | ||
2354 | .write = mxser_write, | ||
2355 | .put_char = mxser_put_char, | ||
2356 | .flush_chars = mxser_flush_chars, | ||
2357 | .write_room = mxser_write_room, | ||
2358 | .chars_in_buffer = mxser_chars_in_buffer, | ||
2359 | .flush_buffer = mxser_flush_buffer, | ||
2360 | .ioctl = mxser_ioctl, | ||
2361 | .throttle = mxser_throttle, | ||
2362 | .unthrottle = mxser_unthrottle, | ||
2363 | .set_termios = mxser_set_termios, | ||
2364 | .stop = mxser_stop, | ||
2365 | .start = mxser_start, | ||
2366 | .hangup = mxser_hangup, | ||
2367 | .break_ctl = mxser_rs_break, | ||
2368 | .wait_until_sent = mxser_wait_until_sent, | ||
2369 | .tiocmget = mxser_tiocmget, | ||
2370 | .tiocmset = mxser_tiocmset, | ||
2371 | }; | ||
2372 | |||
2373 | /* | ||
2374 | * The MOXA Smartio/Industio serial driver boot-time initialization code! | ||
2375 | */ | ||
2376 | |||
2377 | static void mxser_release_res(struct mxser_board *brd, struct pci_dev *pdev, | ||
2378 | unsigned int irq) | ||
2379 | { | ||
2380 | if (irq) | ||
2381 | free_irq(brd->irq, brd); | ||
2382 | if (pdev != NULL) { /* PCI */ | ||
2383 | pci_release_region(pdev, 2); | ||
2384 | pci_release_region(pdev, 3); | ||
2385 | pci_dev_put(pdev); | ||
2386 | } else { | ||
2387 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | ||
2388 | release_region(brd->vector, 1); | ||
2389 | } | ||
2390 | } | ||
2391 | |||
2392 | static int __devinit mxser_initbrd(struct mxser_board *brd, | ||
2393 | struct pci_dev *pdev) | ||
2394 | { | ||
2395 | struct mxser_port *info; | ||
2396 | unsigned int i; | ||
2397 | int retval; | ||
2398 | |||
2399 | printk(KERN_INFO "max. baud rate = %d bps.\n", brd->ports[0].max_baud); | ||
2400 | |||
2401 | for (i = 0; i < brd->info->nports; i++) { | ||
2402 | info = &brd->ports[i]; | ||
2403 | info->board = brd; | ||
2404 | info->stop_rx = 0; | ||
2405 | info->ldisc_stop_rx = 0; | ||
2406 | |||
2407 | /* Enhance mode enabled here */ | ||
2408 | if (brd->chip_flag != MOXA_OTHER_UART) | ||
2409 | ENABLE_MOXA_MUST_ENCHANCE_MODE(info->ioaddr); | ||
2410 | |||
2411 | info->flags = ASYNC_SHARE_IRQ; | ||
2412 | info->type = brd->uart_type; | ||
2413 | |||
2414 | process_txrx_fifo(info); | ||
2415 | |||
2416 | info->custom_divisor = info->baud_base * 16; | ||
2417 | info->close_delay = 5 * HZ / 10; | ||
2418 | info->closing_wait = 30 * HZ; | ||
2419 | INIT_WORK(&info->tqueue, mxser_do_softint); | ||
2420 | info->normal_termios = mxvar_sdriver->init_termios; | ||
2421 | init_waitqueue_head(&info->open_wait); | ||
2422 | init_waitqueue_head(&info->close_wait); | ||
2423 | init_waitqueue_head(&info->delta_msr_wait); | ||
2424 | memset(&info->mon_data, 0, sizeof(struct mxser_mon)); | ||
2425 | info->err_shadow = 0; | ||
2426 | spin_lock_init(&info->slock); | ||
2427 | |||
2428 | /* before set INT ISR, disable all int */ | ||
2429 | outb(inb(info->ioaddr + UART_IER) & 0xf0, | ||
2430 | info->ioaddr + UART_IER); | ||
2431 | } | ||
2432 | /* | ||
2433 | * Allocate the IRQ if necessary | ||
2434 | */ | ||
2435 | |||
2436 | retval = request_irq(brd->irq, mxser_interrupt, | ||
2437 | (brd->ports[0].flags & ASYNC_SHARE_IRQ) ? IRQF_SHARED : | ||
2438 | IRQF_DISABLED, "mxser", brd); | ||
2439 | if (retval) { | ||
2440 | printk(KERN_ERR "Board %s: Request irq failed, IRQ (%d) may " | ||
2441 | "conflict with another device.\n", | ||
2442 | brd->info->name, brd->irq); | ||
2443 | /* We hold resources, we need to release them. */ | ||
2444 | mxser_release_res(brd, pdev, 0); | ||
2445 | return retval; | ||
2446 | } | ||
2447 | return 0; | ||
2448 | } | ||
2449 | |||
2450 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | ||
2451 | { | ||
2452 | int id, i, bits; | ||
2453 | unsigned short regs[16], irq; | ||
2454 | unsigned char scratch, scratch2; | ||
2455 | |||
2456 | brd->chip_flag = MOXA_OTHER_UART; | ||
2457 | |||
2458 | id = mxser_read_register(cap, regs); | ||
2459 | switch (id) { | ||
2460 | case C168_ASIC_ID: | ||
2461 | brd->info = &mxser_cards[0]; | ||
2462 | break; | ||
2463 | case C104_ASIC_ID: | ||
2464 | brd->info = &mxser_cards[1]; | ||
2465 | break; | ||
2466 | case CI104J_ASIC_ID: | ||
2467 | brd->info = &mxser_cards[2]; | ||
2468 | break; | ||
2469 | case C102_ASIC_ID: | ||
2470 | brd->info = &mxser_cards[5]; | ||
2471 | break; | ||
2472 | case CI132_ASIC_ID: | ||
2473 | brd->info = &mxser_cards[6]; | ||
2474 | break; | ||
2475 | case CI134_ASIC_ID: | ||
2476 | brd->info = &mxser_cards[7]; | ||
2477 | break; | ||
2478 | default: | ||
2479 | return 0; | ||
2480 | } | ||
2481 | |||
2482 | irq = 0; | ||
2483 | /* some ISA cards have 2 ports, but we want to see them as 4-port (why?) | ||
2484 | Flag-hack checks if configuration should be read as 2-port here. */ | ||
2485 | if (brd->info->nports == 2 || (brd->info->flags & MXSER_HAS2)) { | ||
2486 | irq = regs[9] & 0xF000; | ||
2487 | irq = irq | (irq >> 4); | ||
2488 | if (irq != (regs[9] & 0xFF00)) | ||
2489 | return MXSER_ERR_IRQ_CONFLIT; | ||
2490 | } else if (brd->info->nports == 4) { | ||
2491 | irq = regs[9] & 0xF000; | ||
2492 | irq = irq | (irq >> 4); | ||
2493 | irq = irq | (irq >> 8); | ||
2494 | if (irq != regs[9]) | ||
2495 | return MXSER_ERR_IRQ_CONFLIT; | ||
2496 | } else if (brd->info->nports == 8) { | ||
2497 | irq = regs[9] & 0xF000; | ||
2498 | irq = irq | (irq >> 4); | ||
2499 | irq = irq | (irq >> 8); | ||
2500 | if ((irq != regs[9]) || (irq != regs[10])) | ||
2501 | return MXSER_ERR_IRQ_CONFLIT; | ||
2502 | } | ||
2503 | |||
2504 | if (!irq) | ||
2505 | return MXSER_ERR_IRQ; | ||
2506 | brd->irq = ((int)(irq & 0xF000) >> 12); | ||
2507 | for (i = 0; i < 8; i++) | ||
2508 | brd->ports[i].ioaddr = (int) regs[i + 1] & 0xFFF8; | ||
2509 | if ((regs[12] & 0x80) == 0) | ||
2510 | return MXSER_ERR_VECTOR; | ||
2511 | brd->vector = (int)regs[11]; /* interrupt vector */ | ||
2512 | if (id == 1) | ||
2513 | brd->vector_mask = 0x00FF; | ||
2514 | else | ||
2515 | brd->vector_mask = 0x000F; | ||
2516 | for (i = 7, bits = 0x0100; i >= 0; i--, bits <<= 1) { | ||
2517 | if (regs[12] & bits) { | ||
2518 | brd->ports[i].baud_base = 921600; | ||
2519 | brd->ports[i].max_baud = 921600; | ||
2520 | } else { | ||
2521 | brd->ports[i].baud_base = 115200; | ||
2522 | brd->ports[i].max_baud = 115200; | ||
2523 | } | ||
2524 | } | ||
2525 | scratch2 = inb(cap + UART_LCR) & (~UART_LCR_DLAB); | ||
2526 | outb(scratch2 | UART_LCR_DLAB, cap + UART_LCR); | ||
2527 | outb(0, cap + UART_EFR); /* EFR is the same as FCR */ | ||
2528 | outb(scratch2, cap + UART_LCR); | ||
2529 | outb(UART_FCR_ENABLE_FIFO, cap + UART_FCR); | ||
2530 | scratch = inb(cap + UART_IIR); | ||
2531 | |||
2532 | if (scratch & 0xC0) | ||
2533 | brd->uart_type = PORT_16550A; | ||
2534 | else | ||
2535 | brd->uart_type = PORT_16450; | ||
2536 | if (!request_region(brd->ports[0].ioaddr, 8 * brd->info->nports, | ||
2537 | "mxser(IO)")) | ||
2538 | return MXSER_ERR_IOADDR; | ||
2539 | if (!request_region(brd->vector, 1, "mxser(vector)")) { | ||
2540 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | ||
2541 | return MXSER_ERR_VECTOR; | ||
2542 | } | ||
2543 | return brd->info->nports; | ||
2544 | } | ||
2545 | |||
2546 | static int __devinit mxser_probe(struct pci_dev *pdev, | ||
2547 | const struct pci_device_id *ent) | ||
2548 | { | ||
2549 | struct mxser_board *brd; | ||
2550 | unsigned int i, j; | ||
2551 | unsigned long ioaddress; | ||
2552 | int retval = -EINVAL; | ||
2553 | |||
2554 | for (i = 0; i < MXSER_BOARDS; i++) | ||
2555 | if (mxser_boards[i].info == NULL) | ||
2556 | break; | ||
2557 | |||
2558 | if (i >= MXSER_BOARDS) { | ||
2559 | printk(KERN_ERR "Too many Smartio/Industio family boards found " | ||
2560 | "(maximum %d), board not configured\n", MXSER_BOARDS); | ||
2561 | goto err; | ||
2562 | } | ||
2563 | |||
2564 | brd = &mxser_boards[i]; | ||
2565 | brd->idx = i * MXSER_PORTS_PER_BOARD; | ||
2566 | printk(KERN_INFO "Found MOXA %s board (BusNo=%d, DevNo=%d)\n", | ||
2567 | mxser_cards[ent->driver_data].name, | ||
2568 | pdev->bus->number, PCI_SLOT(pdev->devfn)); | ||
2569 | |||
2570 | retval = pci_enable_device(pdev); | ||
2571 | if (retval) { | ||
2572 | printk(KERN_ERR "Moxa SmartI/O PCI enable fail !\n"); | ||
2573 | goto err; | ||
2574 | } | ||
2575 | |||
2576 | /* io address */ | ||
2577 | ioaddress = pci_resource_start(pdev, 2); | ||
2578 | retval = pci_request_region(pdev, 2, "mxser(IO)"); | ||
2579 | if (retval) | ||
2580 | goto err; | ||
2581 | |||
2582 | brd->info = &mxser_cards[ent->driver_data]; | ||
2583 | for (i = 0; i < brd->info->nports; i++) | ||
2584 | brd->ports[i].ioaddr = ioaddress + 8 * i; | ||
2585 | |||
2586 | /* vector */ | ||
2587 | ioaddress = pci_resource_start(pdev, 3); | ||
2588 | retval = pci_request_region(pdev, 3, "mxser(vector)"); | ||
2589 | if (retval) | ||
2590 | goto err_relio; | ||
2591 | brd->vector = ioaddress; | ||
2592 | |||
2593 | /* irq */ | ||
2594 | brd->irq = pdev->irq; | ||
2595 | |||
2596 | brd->chip_flag = CheckIsMoxaMust(brd->ports[0].ioaddr); | ||
2597 | brd->uart_type = PORT_16550A; | ||
2598 | brd->vector_mask = 0; | ||
2599 | |||
2600 | for (i = 0; i < brd->info->nports; i++) { | ||
2601 | for (j = 0; j < UART_INFO_NUM; j++) { | ||
2602 | if (Gpci_uart_info[j].type == brd->chip_flag) { | ||
2603 | brd->ports[i].max_baud = | ||
2604 | Gpci_uart_info[j].max_baud; | ||
2605 | |||
2606 | /* exception....CP-102 */ | ||
2607 | if (brd->info->flags & MXSER_HIGHBAUD) | ||
2608 | brd->ports[i].max_baud = 921600; | ||
2609 | break; | ||
2610 | } | ||
2611 | } | ||
2612 | } | ||
2613 | |||
2614 | if (brd->chip_flag == MOXA_MUST_MU860_HWID) { | ||
2615 | for (i = 0; i < brd->info->nports; i++) { | ||
2616 | if (i < 4) | ||
2617 | brd->ports[i].opmode_ioaddr = ioaddress + 4; | ||
2618 | else | ||
2619 | brd->ports[i].opmode_ioaddr = ioaddress + 0x0c; | ||
2620 | } | ||
2621 | outb(0, ioaddress + 4); /* default set to RS232 mode */ | ||
2622 | outb(0, ioaddress + 0x0c); /* default set to RS232 mode */ | ||
2623 | } | ||
2624 | |||
2625 | for (i = 0; i < brd->info->nports; i++) { | ||
2626 | brd->vector_mask |= (1 << i); | ||
2627 | brd->ports[i].baud_base = 921600; | ||
2628 | } | ||
2629 | |||
2630 | /* mxser_initbrd will hook ISR. */ | ||
2631 | if (mxser_initbrd(brd, pdev) < 0) | ||
2632 | goto err_relvec; | ||
2633 | |||
2634 | for (i = 0; i < brd->info->nports; i++) | ||
2635 | tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); | ||
2636 | |||
2637 | pci_set_drvdata(pdev, brd); | ||
2638 | |||
2639 | return 0; | ||
2640 | err_relvec: | ||
2641 | pci_release_region(pdev, 3); | ||
2642 | err_relio: | ||
2643 | pci_release_region(pdev, 2); | ||
2644 | brd->info = NULL; | ||
2645 | err: | ||
2646 | return retval; | ||
2647 | } | ||
2648 | |||
2649 | static void __devexit mxser_remove(struct pci_dev *pdev) | ||
2650 | { | ||
2651 | struct mxser_board *brd = pci_get_drvdata(pdev); | ||
2652 | unsigned int i; | ||
2653 | |||
2654 | for (i = 0; i < brd->info->nports; i++) | ||
2655 | tty_unregister_device(mxvar_sdriver, brd->idx + i); | ||
2656 | |||
2657 | mxser_release_res(brd, pdev, 1); | ||
2658 | } | ||
2659 | |||
2660 | static struct pci_driver mxser_driver = { | ||
2661 | .name = "mxser", | ||
2662 | .id_table = mxser_pcibrds, | ||
2663 | .probe = mxser_probe, | ||
2664 | .remove = __devexit_p(mxser_remove) | ||
2665 | }; | ||
2666 | |||
2667 | static int __init mxser_module_init(void) | ||
2668 | { | ||
2669 | struct mxser_board *brd; | ||
2670 | unsigned long cap; | ||
2671 | unsigned int i, m, isaloop; | ||
2672 | int retval, b; | ||
2673 | |||
2674 | pr_debug("Loading module mxser ...\n"); | ||
2675 | |||
2676 | mxvar_sdriver = alloc_tty_driver(MXSER_PORTS + 1); | ||
2677 | if (!mxvar_sdriver) | ||
2678 | return -ENOMEM; | ||
2679 | spin_lock_init(&gm_lock); | ||
2680 | |||
2681 | printk(KERN_INFO "MOXA Smartio/Industio family driver version %s\n", | ||
2682 | MXSER_VERSION); | ||
2683 | |||
2684 | /* Initialize the tty_driver structure */ | ||
2685 | mxvar_sdriver->magic = TTY_DRIVER_MAGIC; | ||
2686 | mxvar_sdriver->name = "ttyMI"; | ||
2687 | mxvar_sdriver->major = ttymajor; | ||
2688 | mxvar_sdriver->minor_start = 0; | ||
2689 | mxvar_sdriver->num = MXSER_PORTS + 1; | ||
2690 | mxvar_sdriver->type = TTY_DRIVER_TYPE_SERIAL; | ||
2691 | mxvar_sdriver->subtype = SERIAL_TYPE_NORMAL; | ||
2692 | mxvar_sdriver->init_termios = tty_std_termios; | ||
2693 | mxvar_sdriver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; | ||
2694 | mxvar_sdriver->flags = TTY_DRIVER_REAL_RAW|TTY_DRIVER_DYNAMIC_DEV; | ||
2695 | tty_set_operations(mxvar_sdriver, &mxser_ops); | ||
2696 | |||
2697 | retval = tty_register_driver(mxvar_sdriver); | ||
2698 | if (retval) { | ||
2699 | printk(KERN_ERR "Couldn't install MOXA Smartio/Industio family " | ||
2700 | "tty driver !\n"); | ||
2701 | goto err_put; | ||
2702 | } | ||
2703 | |||
2704 | mxvar_diagflag = 0; | ||
2705 | |||
2706 | m = 0; | ||
2707 | /* Start finding ISA boards here */ | ||
2708 | for (isaloop = 0; isaloop < 2; isaloop++) | ||
2709 | for (b = 0; b < MXSER_BOARDS && m < MXSER_BOARDS; b++) { | ||
2710 | if (!isaloop) | ||
2711 | cap = mxserBoardCAP[b]; /* predefined */ | ||
2712 | else | ||
2713 | cap = ioaddr[b]; /* module param */ | ||
2714 | |||
2715 | if (!cap) | ||
2716 | continue; | ||
2717 | |||
2718 | brd = &mxser_boards[m]; | ||
2719 | retval = mxser_get_ISA_conf(cap, brd); | ||
2720 | |||
2721 | if (retval != 0) | ||
2722 | printk(KERN_INFO "Found MOXA %s board " | ||
2723 | "(CAP=0x%x)\n", | ||
2724 | brd->info->name, ioaddr[b]); | ||
2725 | |||
2726 | if (retval <= 0) { | ||
2727 | if (retval == MXSER_ERR_IRQ) | ||
2728 | printk(KERN_ERR "Invalid interrupt " | ||
2729 | "number, board not " | ||
2730 | "configured\n"); | ||
2731 | else if (retval == MXSER_ERR_IRQ_CONFLIT) | ||
2732 | printk(KERN_ERR "Invalid interrupt " | ||
2733 | "number, board not " | ||
2734 | "configured\n"); | ||
2735 | else if (retval == MXSER_ERR_VECTOR) | ||
2736 | printk(KERN_ERR "Invalid interrupt " | ||
2737 | "vector, board not " | ||
2738 | "configured\n"); | ||
2739 | else if (retval == MXSER_ERR_IOADDR) | ||
2740 | printk(KERN_ERR "Invalid I/O address, " | ||
2741 | "board not configured\n"); | ||
2742 | |||
2743 | brd->info = NULL; | ||
2744 | continue; | ||
2745 | } | ||
2746 | |||
2747 | /* mxser_initbrd will hook ISR. */ | ||
2748 | if (mxser_initbrd(brd, NULL) < 0) { | ||
2749 | brd->info = NULL; | ||
2750 | continue; | ||
2751 | } | ||
2752 | |||
2753 | brd->idx = m * MXSER_PORTS_PER_BOARD; | ||
2754 | for (i = 0; i < brd->info->nports; i++) | ||
2755 | tty_register_device(mxvar_sdriver, brd->idx + i, | ||
2756 | NULL); | ||
2757 | |||
2758 | m++; | ||
2759 | } | ||
2760 | |||
2761 | retval = pci_register_driver(&mxser_driver); | ||
2762 | if (retval) { | ||
2763 | printk(KERN_ERR "Can't register pci driver\n"); | ||
2764 | if (!m) { | ||
2765 | retval = -ENODEV; | ||
2766 | goto err_unr; | ||
2767 | } /* else: we have some ISA cards under control */ | ||
2768 | } | ||
2769 | |||
2770 | pr_debug("Done.\n"); | ||
2771 | |||
2772 | return 0; | ||
2773 | err_unr: | ||
2774 | tty_unregister_driver(mxvar_sdriver); | ||
2775 | err_put: | ||
2776 | put_tty_driver(mxvar_sdriver); | ||
2777 | return retval; | ||
2778 | } | ||
2779 | |||
2780 | static void __exit mxser_module_exit(void) | ||
2781 | { | ||
2782 | unsigned int i, j; | ||
2783 | |||
2784 | pr_debug("Unloading module mxser ...\n"); | ||
2785 | |||
2786 | pci_unregister_driver(&mxser_driver); | ||
2787 | |||
2788 | for (i = 0; i < MXSER_BOARDS; i++) /* ISA remains */ | ||
2789 | if (mxser_boards[i].info != NULL) | ||
2790 | for (j = 0; j < mxser_boards[i].info->nports; j++) | ||
2791 | tty_unregister_device(mxvar_sdriver, | ||
2792 | mxser_boards[i].idx + j); | ||
2793 | tty_unregister_driver(mxvar_sdriver); | ||
2794 | put_tty_driver(mxvar_sdriver); | ||
2795 | |||
2796 | for (i = 0; i < MXSER_BOARDS; i++) | ||
2797 | if (mxser_boards[i].info != NULL) | ||
2798 | mxser_release_res(&mxser_boards[i], NULL, 1); | ||
2799 | |||
2800 | pr_debug("Done.\n"); | ||
2801 | } | ||
2802 | |||
2803 | module_init(mxser_module_init); | ||
2804 | module_exit(mxser_module_exit); | ||
diff --git a/drivers/char/mxser_new.h b/drivers/char/mxser_new.h new file mode 100644 index 000000000000..a08f0ecb09ba --- /dev/null +++ b/drivers/char/mxser_new.h | |||
@@ -0,0 +1,450 @@ | |||
1 | #ifndef _MXSER_H | ||
2 | #define _MXSER_H | ||
3 | |||
4 | /* | ||
5 | * Semi-public control interfaces | ||
6 | */ | ||
7 | |||
8 | /* | ||
9 | * MOXA ioctls | ||
10 | */ | ||
11 | |||
12 | #define MOXA 0x400 | ||
13 | #define MOXA_GETDATACOUNT (MOXA + 23) | ||
14 | #define MOXA_GET_CONF (MOXA + 35) | ||
15 | #define MOXA_DIAGNOSE (MOXA + 50) | ||
16 | #define MOXA_CHKPORTENABLE (MOXA + 60) | ||
17 | #define MOXA_HighSpeedOn (MOXA + 61) | ||
18 | #define MOXA_GET_MAJOR (MOXA + 63) | ||
19 | #define MOXA_GET_CUMAJOR (MOXA + 64) | ||
20 | #define MOXA_GETMSTATUS (MOXA + 65) | ||
21 | #define MOXA_SET_OP_MODE (MOXA + 66) | ||
22 | #define MOXA_GET_OP_MODE (MOXA + 67) | ||
23 | |||
24 | #define RS232_MODE 0 | ||
25 | #define RS485_2WIRE_MODE 1 | ||
26 | #define RS422_MODE 2 | ||
27 | #define RS485_4WIRE_MODE 3 | ||
28 | #define OP_MODE_MASK 3 | ||
29 | // above add by Victor Yu. 01-05-2004 | ||
30 | |||
31 | #define TTY_THRESHOLD_THROTTLE 128 | ||
32 | |||
33 | #define LO_WATER (TTY_FLIPBUF_SIZE) | ||
34 | #define HI_WATER (TTY_FLIPBUF_SIZE*2*3/4) | ||
35 | |||
36 | // added by James. 03-11-2004. | ||
37 | #define MOXA_SDS_GETICOUNTER (MOXA + 68) | ||
38 | #define MOXA_SDS_RSTICOUNTER (MOXA + 69) | ||
39 | // (above) added by James. | ||
40 | |||
41 | #define MOXA_ASPP_OQUEUE (MOXA + 70) | ||
42 | #define MOXA_ASPP_SETBAUD (MOXA + 71) | ||
43 | #define MOXA_ASPP_GETBAUD (MOXA + 72) | ||
44 | #define MOXA_ASPP_MON (MOXA + 73) | ||
45 | #define MOXA_ASPP_LSTATUS (MOXA + 74) | ||
46 | #define MOXA_ASPP_MON_EXT (MOXA + 75) | ||
47 | #define MOXA_SET_BAUD_METHOD (MOXA + 76) | ||
48 | |||
49 | |||
50 | /* --------------------------------------------------- */ | ||
51 | |||
52 | #define NPPI_NOTIFY_PARITY 0x01 | ||
53 | #define NPPI_NOTIFY_FRAMING 0x02 | ||
54 | #define NPPI_NOTIFY_HW_OVERRUN 0x04 | ||
55 | #define NPPI_NOTIFY_SW_OVERRUN 0x08 | ||
56 | #define NPPI_NOTIFY_BREAK 0x10 | ||
57 | |||
58 | #define NPPI_NOTIFY_CTSHOLD 0x01 // Tx hold by CTS low | ||
59 | #define NPPI_NOTIFY_DSRHOLD 0x02 // Tx hold by DSR low | ||
60 | #define NPPI_NOTIFY_XOFFHOLD 0x08 // Tx hold by Xoff received | ||
61 | #define NPPI_NOTIFY_XOFFXENT 0x10 // Xoff Sent | ||
62 | |||
63 | //CheckIsMoxaMust return value | ||
64 | #define MOXA_OTHER_UART 0x00 | ||
65 | #define MOXA_MUST_MU150_HWID 0x01 | ||
66 | #define MOXA_MUST_MU860_HWID 0x02 | ||
67 | |||
68 | // follow just for Moxa Must chip define. | ||
69 | // | ||
70 | // when LCR register (offset 0x03) write following value, | ||
71 | // the Must chip will enter enchance mode. And write value | ||
72 | // on EFR (offset 0x02) bit 6,7 to change bank. | ||
73 | #define MOXA_MUST_ENTER_ENCHANCE 0xBF | ||
74 | |||
75 | // when enhance mode enable, access on general bank register | ||
76 | #define MOXA_MUST_GDL_REGISTER 0x07 | ||
77 | #define MOXA_MUST_GDL_MASK 0x7F | ||
78 | #define MOXA_MUST_GDL_HAS_BAD_DATA 0x80 | ||
79 | |||
80 | #define MOXA_MUST_LSR_RERR 0x80 // error in receive FIFO | ||
81 | // enchance register bank select and enchance mode setting register | ||
82 | // when LCR register equal to 0xBF | ||
83 | #define MOXA_MUST_EFR_REGISTER 0x02 | ||
84 | // enchance mode enable | ||
85 | #define MOXA_MUST_EFR_EFRB_ENABLE 0x10 | ||
86 | // enchance reister bank set 0, 1, 2 | ||
87 | #define MOXA_MUST_EFR_BANK0 0x00 | ||
88 | #define MOXA_MUST_EFR_BANK1 0x40 | ||
89 | #define MOXA_MUST_EFR_BANK2 0x80 | ||
90 | #define MOXA_MUST_EFR_BANK3 0xC0 | ||
91 | #define MOXA_MUST_EFR_BANK_MASK 0xC0 | ||
92 | |||
93 | // set XON1 value register, when LCR=0xBF and change to bank0 | ||
94 | #define MOXA_MUST_XON1_REGISTER 0x04 | ||
95 | |||
96 | // set XON2 value register, when LCR=0xBF and change to bank0 | ||
97 | #define MOXA_MUST_XON2_REGISTER 0x05 | ||
98 | |||
99 | // set XOFF1 value register, when LCR=0xBF and change to bank0 | ||
100 | #define MOXA_MUST_XOFF1_REGISTER 0x06 | ||
101 | |||
102 | // set XOFF2 value register, when LCR=0xBF and change to bank0 | ||
103 | #define MOXA_MUST_XOFF2_REGISTER 0x07 | ||
104 | |||
105 | #define MOXA_MUST_RBRTL_REGISTER 0x04 | ||
106 | #define MOXA_MUST_RBRTH_REGISTER 0x05 | ||
107 | #define MOXA_MUST_RBRTI_REGISTER 0x06 | ||
108 | #define MOXA_MUST_THRTL_REGISTER 0x07 | ||
109 | #define MOXA_MUST_ENUM_REGISTER 0x04 | ||
110 | #define MOXA_MUST_HWID_REGISTER 0x05 | ||
111 | #define MOXA_MUST_ECR_REGISTER 0x06 | ||
112 | #define MOXA_MUST_CSR_REGISTER 0x07 | ||
113 | |||
114 | // good data mode enable | ||
115 | #define MOXA_MUST_FCR_GDA_MODE_ENABLE 0x20 | ||
116 | // only good data put into RxFIFO | ||
117 | #define MOXA_MUST_FCR_GDA_ONLY_ENABLE 0x10 | ||
118 | |||
119 | // enable CTS interrupt | ||
120 | #define MOXA_MUST_IER_ECTSI 0x80 | ||
121 | // enable RTS interrupt | ||
122 | #define MOXA_MUST_IER_ERTSI 0x40 | ||
123 | // enable Xon/Xoff interrupt | ||
124 | #define MOXA_MUST_IER_XINT 0x20 | ||
125 | // enable GDA interrupt | ||
126 | #define MOXA_MUST_IER_EGDAI 0x10 | ||
127 | |||
128 | #define MOXA_MUST_RECV_ISR (UART_IER_RDI | MOXA_MUST_IER_EGDAI) | ||
129 | |||
130 | // GDA interrupt pending | ||
131 | #define MOXA_MUST_IIR_GDA 0x1C | ||
132 | #define MOXA_MUST_IIR_RDA 0x04 | ||
133 | #define MOXA_MUST_IIR_RTO 0x0C | ||
134 | #define MOXA_MUST_IIR_LSR 0x06 | ||
135 | |||
136 | // recieved Xon/Xoff or specical interrupt pending | ||
137 | #define MOXA_MUST_IIR_XSC 0x10 | ||
138 | |||
139 | // RTS/CTS change state interrupt pending | ||
140 | #define MOXA_MUST_IIR_RTSCTS 0x20 | ||
141 | #define MOXA_MUST_IIR_MASK 0x3E | ||
142 | |||
143 | #define MOXA_MUST_MCR_XON_FLAG 0x40 | ||
144 | #define MOXA_MUST_MCR_XON_ANY 0x80 | ||
145 | #define MOXA_MUST_MCR_TX_XON 0x08 | ||
146 | |||
147 | |||
148 | // software flow control on chip mask value | ||
149 | #define MOXA_MUST_EFR_SF_MASK 0x0F | ||
150 | // send Xon1/Xoff1 | ||
151 | #define MOXA_MUST_EFR_SF_TX1 0x08 | ||
152 | // send Xon2/Xoff2 | ||
153 | #define MOXA_MUST_EFR_SF_TX2 0x04 | ||
154 | // send Xon1,Xon2/Xoff1,Xoff2 | ||
155 | #define MOXA_MUST_EFR_SF_TX12 0x0C | ||
156 | // don't send Xon/Xoff | ||
157 | #define MOXA_MUST_EFR_SF_TX_NO 0x00 | ||
158 | // Tx software flow control mask | ||
159 | #define MOXA_MUST_EFR_SF_TX_MASK 0x0C | ||
160 | // don't receive Xon/Xoff | ||
161 | #define MOXA_MUST_EFR_SF_RX_NO 0x00 | ||
162 | // receive Xon1/Xoff1 | ||
163 | #define MOXA_MUST_EFR_SF_RX1 0x02 | ||
164 | // receive Xon2/Xoff2 | ||
165 | #define MOXA_MUST_EFR_SF_RX2 0x01 | ||
166 | // receive Xon1,Xon2/Xoff1,Xoff2 | ||
167 | #define MOXA_MUST_EFR_SF_RX12 0x03 | ||
168 | // Rx software flow control mask | ||
169 | #define MOXA_MUST_EFR_SF_RX_MASK 0x03 | ||
170 | |||
171 | //#define MOXA_MUST_MIN_XOFFLIMIT 66 | ||
172 | //#define MOXA_MUST_MIN_XONLIMIT 20 | ||
173 | //#define ID1_RX_TRIG 120 | ||
174 | |||
175 | |||
176 | #define CHECK_MOXA_MUST_XOFFLIMIT(info) { \ | ||
177 | if ( (info)->IsMoxaMustChipFlag && \ | ||
178 | (info)->HandFlow.XoffLimit < MOXA_MUST_MIN_XOFFLIMIT ) { \ | ||
179 | (info)->HandFlow.XoffLimit = MOXA_MUST_MIN_XOFFLIMIT; \ | ||
180 | (info)->HandFlow.XonLimit = MOXA_MUST_MIN_XONLIMIT; \ | ||
181 | } \ | ||
182 | } | ||
183 | |||
184 | #define ENABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \ | ||
185 | u8 __oldlcr, __efr; \ | ||
186 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
187 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
188 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
189 | __efr |= MOXA_MUST_EFR_EFRB_ENABLE; \ | ||
190 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
191 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
192 | } | ||
193 | |||
194 | #define DISABLE_MOXA_MUST_ENCHANCE_MODE(baseio) { \ | ||
195 | u8 __oldlcr, __efr; \ | ||
196 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
197 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
198 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
199 | __efr &= ~MOXA_MUST_EFR_EFRB_ENABLE; \ | ||
200 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
201 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
202 | } | ||
203 | |||
204 | #define SET_MOXA_MUST_XON1_VALUE(baseio, Value) { \ | ||
205 | u8 __oldlcr, __efr; \ | ||
206 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
207 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
208 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
209 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
210 | __efr |= MOXA_MUST_EFR_BANK0; \ | ||
211 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
212 | outb((u8)(Value), (baseio)+MOXA_MUST_XON1_REGISTER); \ | ||
213 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
214 | } | ||
215 | |||
216 | #define SET_MOXA_MUST_XON2_VALUE(baseio, Value) { \ | ||
217 | u8 __oldlcr, __efr; \ | ||
218 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
219 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
220 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
221 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
222 | __efr |= MOXA_MUST_EFR_BANK0; \ | ||
223 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
224 | outb((u8)(Value), (baseio)+MOXA_MUST_XON2_REGISTER); \ | ||
225 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
226 | } | ||
227 | |||
228 | #define SET_MOXA_MUST_XOFF1_VALUE(baseio, Value) { \ | ||
229 | u8 __oldlcr, __efr; \ | ||
230 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
231 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
232 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
233 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
234 | __efr |= MOXA_MUST_EFR_BANK0; \ | ||
235 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
236 | outb((u8)(Value), (baseio)+MOXA_MUST_XOFF1_REGISTER); \ | ||
237 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
238 | } | ||
239 | |||
240 | #define SET_MOXA_MUST_XOFF2_VALUE(baseio, Value) { \ | ||
241 | u8 __oldlcr, __efr; \ | ||
242 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
243 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
244 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
245 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
246 | __efr |= MOXA_MUST_EFR_BANK0; \ | ||
247 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
248 | outb((u8)(Value), (baseio)+MOXA_MUST_XOFF2_REGISTER); \ | ||
249 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
250 | } | ||
251 | |||
252 | #define SET_MOXA_MUST_RBRTL_VALUE(baseio, Value) { \ | ||
253 | u8 __oldlcr, __efr; \ | ||
254 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
255 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
256 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
257 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
258 | __efr |= MOXA_MUST_EFR_BANK1; \ | ||
259 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
260 | outb((u8)(Value), (baseio)+MOXA_MUST_RBRTL_REGISTER); \ | ||
261 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
262 | } | ||
263 | |||
264 | #define SET_MOXA_MUST_RBRTH_VALUE(baseio, Value) { \ | ||
265 | u8 __oldlcr, __efr; \ | ||
266 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
267 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
268 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
269 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
270 | __efr |= MOXA_MUST_EFR_BANK1; \ | ||
271 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
272 | outb((u8)(Value), (baseio)+MOXA_MUST_RBRTH_REGISTER); \ | ||
273 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
274 | } | ||
275 | |||
276 | #define SET_MOXA_MUST_RBRTI_VALUE(baseio, Value) { \ | ||
277 | u8 __oldlcr, __efr; \ | ||
278 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
279 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
280 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
281 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
282 | __efr |= MOXA_MUST_EFR_BANK1; \ | ||
283 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
284 | outb((u8)(Value), (baseio)+MOXA_MUST_RBRTI_REGISTER); \ | ||
285 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
286 | } | ||
287 | |||
288 | #define SET_MOXA_MUST_THRTL_VALUE(baseio, Value) { \ | ||
289 | u8 __oldlcr, __efr; \ | ||
290 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
291 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
292 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
293 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
294 | __efr |= MOXA_MUST_EFR_BANK1; \ | ||
295 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
296 | outb((u8)(Value), (baseio)+MOXA_MUST_THRTL_REGISTER); \ | ||
297 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
298 | } | ||
299 | |||
300 | //#define MOXA_MUST_RBRL_VALUE 4 | ||
301 | #define SET_MOXA_MUST_FIFO_VALUE(info) { \ | ||
302 | u8 __oldlcr, __efr; \ | ||
303 | __oldlcr = inb((info)->ioaddr+UART_LCR); \ | ||
304 | outb(MOXA_MUST_ENTER_ENCHANCE, (info)->ioaddr+UART_LCR); \ | ||
305 | __efr = inb((info)->ioaddr+MOXA_MUST_EFR_REGISTER); \ | ||
306 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
307 | __efr |= MOXA_MUST_EFR_BANK1; \ | ||
308 | outb(__efr, (info)->ioaddr+MOXA_MUST_EFR_REGISTER); \ | ||
309 | outb((u8)((info)->rx_high_water), (info)->ioaddr+MOXA_MUST_RBRTH_REGISTER); \ | ||
310 | outb((u8)((info)->rx_trigger), (info)->ioaddr+MOXA_MUST_RBRTI_REGISTER); \ | ||
311 | outb((u8)((info)->rx_low_water), (info)->ioaddr+MOXA_MUST_RBRTL_REGISTER); \ | ||
312 | outb(__oldlcr, (info)->ioaddr+UART_LCR); \ | ||
313 | } | ||
314 | |||
315 | |||
316 | |||
317 | #define SET_MOXA_MUST_ENUM_VALUE(baseio, Value) { \ | ||
318 | u8 __oldlcr, __efr; \ | ||
319 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
320 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
321 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
322 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
323 | __efr |= MOXA_MUST_EFR_BANK2; \ | ||
324 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
325 | outb((u8)(Value), (baseio)+MOXA_MUST_ENUM_REGISTER); \ | ||
326 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
327 | } | ||
328 | |||
329 | #define GET_MOXA_MUST_HARDWARE_ID(baseio, pId) { \ | ||
330 | u8 __oldlcr, __efr; \ | ||
331 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
332 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
333 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
334 | __efr &= ~MOXA_MUST_EFR_BANK_MASK; \ | ||
335 | __efr |= MOXA_MUST_EFR_BANK2; \ | ||
336 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
337 | *pId = inb((baseio)+MOXA_MUST_HWID_REGISTER); \ | ||
338 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
339 | } | ||
340 | |||
341 | #define SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
342 | u8 __oldlcr, __efr; \ | ||
343 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
344 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
345 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
346 | __efr &= ~MOXA_MUST_EFR_SF_MASK; \ | ||
347 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
348 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
349 | } | ||
350 | |||
351 | #define SET_MOXA_MUST_JUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
352 | u8 __oldlcr, __efr; \ | ||
353 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
354 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
355 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
356 | __efr &= ~MOXA_MUST_EFR_SF_MASK; \ | ||
357 | __efr |= MOXA_MUST_EFR_SF_TX1; \ | ||
358 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
359 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
360 | } | ||
361 | |||
362 | #define ENABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
363 | u8 __oldlcr, __efr; \ | ||
364 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
365 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
366 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
367 | __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ | ||
368 | __efr |= MOXA_MUST_EFR_SF_TX1; \ | ||
369 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
370 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
371 | } | ||
372 | |||
373 | #define DISABLE_MOXA_MUST_TX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
374 | u8 __oldlcr, __efr; \ | ||
375 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
376 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
377 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
378 | __efr &= ~MOXA_MUST_EFR_SF_TX_MASK; \ | ||
379 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
380 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
381 | } | ||
382 | |||
383 | #define SET_MOXA_MUST_JUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
384 | u8 __oldlcr, __efr; \ | ||
385 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
386 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
387 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
388 | __efr &= ~MOXA_MUST_EFR_SF_MASK; \ | ||
389 | __efr |= MOXA_MUST_EFR_SF_RX1; \ | ||
390 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
391 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
392 | } | ||
393 | |||
394 | #define ENABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
395 | u8 __oldlcr, __efr; \ | ||
396 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
397 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
398 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
399 | __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ | ||
400 | __efr |= MOXA_MUST_EFR_SF_RX1; \ | ||
401 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
402 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
403 | } | ||
404 | |||
405 | #define DISABLE_MOXA_MUST_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
406 | u8 __oldlcr, __efr; \ | ||
407 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
408 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
409 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
410 | __efr &= ~MOXA_MUST_EFR_SF_RX_MASK; \ | ||
411 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
412 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
413 | } | ||
414 | |||
415 | #define ENABLE_MOXA_MUST_TX_RX_SOFTWARE_FLOW_CONTROL(baseio) { \ | ||
416 | u8 __oldlcr, __efr; \ | ||
417 | __oldlcr = inb((baseio)+UART_LCR); \ | ||
418 | outb(MOXA_MUST_ENTER_ENCHANCE, (baseio)+UART_LCR); \ | ||
419 | __efr = inb((baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
420 | __efr &= ~MOXA_MUST_EFR_SF_MASK; \ | ||
421 | __efr |= (MOXA_MUST_EFR_SF_RX1|MOXA_MUST_EFR_SF_TX1); \ | ||
422 | outb(__efr, (baseio)+MOXA_MUST_EFR_REGISTER); \ | ||
423 | outb(__oldlcr, (baseio)+UART_LCR); \ | ||
424 | } | ||
425 | |||
426 | #define ENABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) { \ | ||
427 | u8 __oldmcr; \ | ||
428 | __oldmcr = inb((baseio)+UART_MCR); \ | ||
429 | __oldmcr |= MOXA_MUST_MCR_XON_ANY; \ | ||
430 | outb(__oldmcr, (baseio)+UART_MCR); \ | ||
431 | } | ||
432 | |||
433 | #define DISABLE_MOXA_MUST_XON_ANY_FLOW_CONTROL(baseio) { \ | ||
434 | u8 __oldmcr; \ | ||
435 | __oldmcr = inb((baseio)+UART_MCR); \ | ||
436 | __oldmcr &= ~MOXA_MUST_MCR_XON_ANY; \ | ||
437 | outb(__oldmcr, (baseio)+UART_MCR); \ | ||
438 | } | ||
439 | |||
440 | #define READ_MOXA_MUST_GDL(baseio) inb((baseio)+MOXA_MUST_GDL_REGISTER) | ||
441 | |||
442 | |||
443 | #ifndef INIT_WORK | ||
444 | #define INIT_WORK(_work, _func, _data){ \ | ||
445 | _data->tqueue.routine = _func;\ | ||
446 | _data->tqueue.data = _data;\ | ||
447 | } | ||
448 | #endif | ||
449 | |||
450 | #endif | ||
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c index 203dc2b661d5..103d338f21e2 100644 --- a/drivers/char/n_r3964.c +++ b/drivers/char/n_r3964.c | |||
@@ -142,7 +142,7 @@ static ssize_t r3964_write(struct tty_struct * tty, struct file * file, | |||
142 | const unsigned char * buf, size_t nr); | 142 | const unsigned char * buf, size_t nr); |
143 | static int r3964_ioctl(struct tty_struct * tty, struct file * file, | 143 | static int r3964_ioctl(struct tty_struct * tty, struct file * file, |
144 | unsigned int cmd, unsigned long arg); | 144 | unsigned int cmd, unsigned long arg); |
145 | static void r3964_set_termios(struct tty_struct *tty, struct termios * old); | 145 | static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old); |
146 | static unsigned int r3964_poll(struct tty_struct * tty, struct file * file, | 146 | static unsigned int r3964_poll(struct tty_struct * tty, struct file * file, |
147 | struct poll_table_struct *wait); | 147 | struct poll_table_struct *wait); |
148 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, | 148 | static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, |
@@ -1347,7 +1347,7 @@ static int r3964_ioctl(struct tty_struct * tty, struct file * file, | |||
1347 | } | 1347 | } |
1348 | } | 1348 | } |
1349 | 1349 | ||
1350 | static void r3964_set_termios(struct tty_struct *tty, struct termios * old) | 1350 | static void r3964_set_termios(struct tty_struct *tty, struct ktermios * old) |
1351 | { | 1351 | { |
1352 | TRACE_L("set_termios"); | 1352 | TRACE_L("set_termios"); |
1353 | } | 1353 | } |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 603b9ade5eb0..e96a00fe1389 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -994,7 +994,7 @@ int is_ignored(int sig) | |||
994 | * when the ldisc is closed. | 994 | * when the ldisc is closed. |
995 | */ | 995 | */ |
996 | 996 | ||
997 | static void n_tty_set_termios(struct tty_struct *tty, struct termios * old) | 997 | static void n_tty_set_termios(struct tty_struct *tty, struct ktermios * old) |
998 | { | 998 | { |
999 | if (!tty) | 999 | if (!tty) |
1000 | return; | 1000 | return; |
diff --git a/drivers/char/nsc_gpio.c b/drivers/char/nsc_gpio.c index 4d47d79bcea7..808d44e9a32a 100644 --- a/drivers/char/nsc_gpio.c +++ b/drivers/char/nsc_gpio.c | |||
@@ -41,7 +41,7 @@ void nsc_gpio_dump(struct nsc_gpio_ops *amp, unsigned index) | |||
41 | ssize_t nsc_gpio_write(struct file *file, const char __user *data, | 41 | ssize_t nsc_gpio_write(struct file *file, const char __user *data, |
42 | size_t len, loff_t *ppos) | 42 | size_t len, loff_t *ppos) |
43 | { | 43 | { |
44 | unsigned m = iminor(file->f_dentry->d_inode); | 44 | unsigned m = iminor(file->f_path.dentry->d_inode); |
45 | struct nsc_gpio_ops *amp = file->private_data; | 45 | struct nsc_gpio_ops *amp = file->private_data; |
46 | struct device *dev = amp->dev; | 46 | struct device *dev = amp->dev; |
47 | size_t i; | 47 | size_t i; |
@@ -104,7 +104,7 @@ ssize_t nsc_gpio_write(struct file *file, const char __user *data, | |||
104 | ssize_t nsc_gpio_read(struct file *file, char __user * buf, | 104 | ssize_t nsc_gpio_read(struct file *file, char __user * buf, |
105 | size_t len, loff_t * ppos) | 105 | size_t len, loff_t * ppos) |
106 | { | 106 | { |
107 | unsigned m = iminor(file->f_dentry->d_inode); | 107 | unsigned m = iminor(file->f_path.dentry->d_inode); |
108 | int value; | 108 | int value; |
109 | struct nsc_gpio_ops *amp = file->private_data; | 109 | struct nsc_gpio_ops *amp = file->private_data; |
110 | 110 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 1bd12296dca5..5152cedd8878 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -75,8 +75,10 @@ | |||
75 | #include <pcmcia/cisreg.h> | 75 | #include <pcmcia/cisreg.h> |
76 | #include <pcmcia/ds.h> | 76 | #include <pcmcia/ds.h> |
77 | 77 | ||
78 | #ifdef CONFIG_HDLC_MODULE | 78 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_CS_MODULE)) |
79 | #define CONFIG_HDLC 1 | 79 | #define SYNCLINK_GENERIC_HDLC 1 |
80 | #else | ||
81 | #define SYNCLINK_GENERIC_HDLC 0 | ||
80 | #endif | 82 | #endif |
81 | 83 | ||
82 | #define GET_USER(error,value,addr) error = get_user(value,addr) | 84 | #define GET_USER(error,value,addr) error = get_user(value,addr) |
@@ -235,7 +237,7 @@ typedef struct _mgslpc_info { | |||
235 | int dosyncppp; | 237 | int dosyncppp; |
236 | spinlock_t netlock; | 238 | spinlock_t netlock; |
237 | 239 | ||
238 | #ifdef CONFIG_HDLC | 240 | #if SYNCLINK_GENERIC_HDLC |
239 | struct net_device *netdev; | 241 | struct net_device *netdev; |
240 | #endif | 242 | #endif |
241 | 243 | ||
@@ -392,7 +394,7 @@ static void tx_timeout(unsigned long context); | |||
392 | 394 | ||
393 | static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg); | 395 | static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg); |
394 | 396 | ||
395 | #ifdef CONFIG_HDLC | 397 | #if SYNCLINK_GENERIC_HDLC |
396 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | 398 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) |
397 | static void hdlcdev_tx_done(MGSLPC_INFO *info); | 399 | static void hdlcdev_tx_done(MGSLPC_INFO *info); |
398 | static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size); | 400 | static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size); |
@@ -1053,7 +1055,7 @@ static void tx_done(MGSLPC_INFO *info) | |||
1053 | info->drop_rts_on_tx_done = 0; | 1055 | info->drop_rts_on_tx_done = 0; |
1054 | } | 1056 | } |
1055 | 1057 | ||
1056 | #ifdef CONFIG_HDLC | 1058 | #if SYNCLINK_GENERIC_HDLC |
1057 | if (info->netcount) | 1059 | if (info->netcount) |
1058 | hdlcdev_tx_done(info); | 1060 | hdlcdev_tx_done(info); |
1059 | else | 1061 | else |
@@ -1164,7 +1166,7 @@ static void dcd_change(MGSLPC_INFO *info) | |||
1164 | } | 1166 | } |
1165 | else | 1167 | else |
1166 | info->input_signal_events.dcd_down++; | 1168 | info->input_signal_events.dcd_down++; |
1167 | #ifdef CONFIG_HDLC | 1169 | #if SYNCLINK_GENERIC_HDLC |
1168 | if (info->netcount) { | 1170 | if (info->netcount) { |
1169 | if (info->serial_signals & SerialSignal_DCD) | 1171 | if (info->serial_signals & SerialSignal_DCD) |
1170 | netif_carrier_on(info->netdev); | 1172 | netif_carrier_on(info->netdev); |
@@ -2373,7 +2375,7 @@ static int ioctl_common(MGSLPC_INFO *info, unsigned int cmd, unsigned long arg) | |||
2373 | * tty pointer to tty structure | 2375 | * tty pointer to tty structure |
2374 | * termios pointer to buffer to hold returned old termios | 2376 | * termios pointer to buffer to hold returned old termios |
2375 | */ | 2377 | */ |
2376 | static void mgslpc_set_termios(struct tty_struct *tty, struct termios *old_termios) | 2378 | static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
2377 | { | 2379 | { |
2378 | MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; | 2380 | MGSLPC_INFO *info = (MGSLPC_INFO *)tty->driver_data; |
2379 | unsigned long flags; | 2381 | unsigned long flags; |
@@ -2953,7 +2955,7 @@ static void mgslpc_add_device(MGSLPC_INFO *info) | |||
2953 | printk( "SyncLink PC Card %s:IO=%04X IRQ=%d\n", | 2955 | printk( "SyncLink PC Card %s:IO=%04X IRQ=%d\n", |
2954 | info->device_name, info->io_base, info->irq_level); | 2956 | info->device_name, info->io_base, info->irq_level); |
2955 | 2957 | ||
2956 | #ifdef CONFIG_HDLC | 2958 | #if SYNCLINK_GENERIC_HDLC |
2957 | hdlcdev_init(info); | 2959 | hdlcdev_init(info); |
2958 | #endif | 2960 | #endif |
2959 | } | 2961 | } |
@@ -2969,7 +2971,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) | |||
2969 | last->next_device = info->next_device; | 2971 | last->next_device = info->next_device; |
2970 | else | 2972 | else |
2971 | mgslpc_device_list = info->next_device; | 2973 | mgslpc_device_list = info->next_device; |
2972 | #ifdef CONFIG_HDLC | 2974 | #if SYNCLINK_GENERIC_HDLC |
2973 | hdlcdev_exit(info); | 2975 | hdlcdev_exit(info); |
2974 | #endif | 2976 | #endif |
2975 | release_resources(info); | 2977 | release_resources(info); |
@@ -3901,7 +3903,7 @@ static int rx_get_frame(MGSLPC_INFO *info) | |||
3901 | return_frame = 1; | 3903 | return_frame = 1; |
3902 | } | 3904 | } |
3903 | framesize = 0; | 3905 | framesize = 0; |
3904 | #ifdef CONFIG_HDLC | 3906 | #if SYNCLINK_GENERIC_HDLC |
3905 | { | 3907 | { |
3906 | struct net_device_stats *stats = hdlc_stats(info->netdev); | 3908 | struct net_device_stats *stats = hdlc_stats(info->netdev); |
3907 | stats->rx_errors++; | 3909 | stats->rx_errors++; |
@@ -3935,7 +3937,7 @@ static int rx_get_frame(MGSLPC_INFO *info) | |||
3935 | ++framesize; | 3937 | ++framesize; |
3936 | } | 3938 | } |
3937 | 3939 | ||
3938 | #ifdef CONFIG_HDLC | 3940 | #if SYNCLINK_GENERIC_HDLC |
3939 | if (info->netcount) | 3941 | if (info->netcount) |
3940 | hdlcdev_rx(info, buf->data, framesize); | 3942 | hdlcdev_rx(info, buf->data, framesize); |
3941 | else | 3943 | else |
@@ -4091,7 +4093,7 @@ static void tx_timeout(unsigned long context) | |||
4091 | 4093 | ||
4092 | spin_unlock_irqrestore(&info->lock,flags); | 4094 | spin_unlock_irqrestore(&info->lock,flags); |
4093 | 4095 | ||
4094 | #ifdef CONFIG_HDLC | 4096 | #if SYNCLINK_GENERIC_HDLC |
4095 | if (info->netcount) | 4097 | if (info->netcount) |
4096 | hdlcdev_tx_done(info); | 4098 | hdlcdev_tx_done(info); |
4097 | else | 4099 | else |
@@ -4099,7 +4101,7 @@ static void tx_timeout(unsigned long context) | |||
4099 | bh_transmit(info); | 4101 | bh_transmit(info); |
4100 | } | 4102 | } |
4101 | 4103 | ||
4102 | #ifdef CONFIG_HDLC | 4104 | #if SYNCLINK_GENERIC_HDLC |
4103 | 4105 | ||
4104 | /** | 4106 | /** |
4105 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) | 4107 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) |
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index c1e3dd837fc8..4abd1eff61d6 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c | |||
@@ -106,7 +106,7 @@ static inline void pp_enable_irq (struct pp_struct *pp) | |||
106 | static ssize_t pp_read (struct file * file, char __user * buf, size_t count, | 106 | static ssize_t pp_read (struct file * file, char __user * buf, size_t count, |
107 | loff_t * ppos) | 107 | loff_t * ppos) |
108 | { | 108 | { |
109 | unsigned int minor = iminor(file->f_dentry->d_inode); | 109 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
110 | struct pp_struct *pp = file->private_data; | 110 | struct pp_struct *pp = file->private_data; |
111 | char * kbuffer; | 111 | char * kbuffer; |
112 | ssize_t bytes_read = 0; | 112 | ssize_t bytes_read = 0; |
@@ -189,7 +189,7 @@ static ssize_t pp_read (struct file * file, char __user * buf, size_t count, | |||
189 | static ssize_t pp_write (struct file * file, const char __user * buf, | 189 | static ssize_t pp_write (struct file * file, const char __user * buf, |
190 | size_t count, loff_t * ppos) | 190 | size_t count, loff_t * ppos) |
191 | { | 191 | { |
192 | unsigned int minor = iminor(file->f_dentry->d_inode); | 192 | unsigned int minor = iminor(file->f_path.dentry->d_inode); |
193 | struct pp_struct *pp = file->private_data; | 193 | struct pp_struct *pp = file->private_data; |
194 | char * kbuffer; | 194 | char * kbuffer; |
195 | ssize_t bytes_written = 0; | 195 | ssize_t bytes_written = 0; |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index 80d3eedd7f96..c07a1b5cd05d 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -218,7 +218,7 @@ out: | |||
218 | return retval; | 218 | return retval; |
219 | } | 219 | } |
220 | 220 | ||
221 | static void pty_set_termios(struct tty_struct *tty, struct termios *old_termios) | 221 | static void pty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
222 | { | 222 | { |
223 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | 223 | tty->termios->c_cflag &= ~(CSIZE | PARENB); |
224 | tty->termios->c_cflag |= (CS8 | CREAD); | 224 | tty->termios->c_cflag |= (CS8 | CREAD); |
@@ -272,6 +272,8 @@ static void __init legacy_pty_init(void) | |||
272 | pty_driver->init_termios.c_oflag = 0; | 272 | pty_driver->init_termios.c_oflag = 0; |
273 | pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 273 | pty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
274 | pty_driver->init_termios.c_lflag = 0; | 274 | pty_driver->init_termios.c_lflag = 0; |
275 | pty_driver->init_termios.c_ispeed = 38400; | ||
276 | pty_driver->init_termios.c_ospeed = 38400; | ||
275 | pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; | 277 | pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; |
276 | pty_driver->other = pty_slave_driver; | 278 | pty_driver->other = pty_slave_driver; |
277 | tty_set_operations(pty_driver, &pty_ops); | 279 | tty_set_operations(pty_driver, &pty_ops); |
@@ -286,6 +288,8 @@ static void __init legacy_pty_init(void) | |||
286 | pty_slave_driver->subtype = PTY_TYPE_SLAVE; | 288 | pty_slave_driver->subtype = PTY_TYPE_SLAVE; |
287 | pty_slave_driver->init_termios = tty_std_termios; | 289 | pty_slave_driver->init_termios = tty_std_termios; |
288 | pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 290 | pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
291 | pty_slave_driver->init_termios.c_ispeed = 38400; | ||
292 | pty_slave_driver->init_termios.c_ospeed = 38400; | ||
289 | pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS | | 293 | pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS | |
290 | TTY_DRIVER_REAL_RAW; | 294 | TTY_DRIVER_REAL_RAW; |
291 | pty_slave_driver->other = pty_driver; | 295 | pty_slave_driver->other = pty_driver; |
@@ -366,6 +370,8 @@ static void __init unix98_pty_init(void) | |||
366 | ptm_driver->init_termios.c_oflag = 0; | 370 | ptm_driver->init_termios.c_oflag = 0; |
367 | ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 371 | ptm_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
368 | ptm_driver->init_termios.c_lflag = 0; | 372 | ptm_driver->init_termios.c_lflag = 0; |
373 | ptm_driver->init_termios.c_ispeed = 38400; | ||
374 | ptm_driver->init_termios.c_ospeed = 38400; | ||
369 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 375 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
370 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 376 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
371 | ptm_driver->other = pts_driver; | 377 | ptm_driver->other = pts_driver; |
@@ -381,6 +387,8 @@ static void __init unix98_pty_init(void) | |||
381 | pts_driver->subtype = PTY_TYPE_SLAVE; | 387 | pts_driver->subtype = PTY_TYPE_SLAVE; |
382 | pts_driver->init_termios = tty_std_termios; | 388 | pts_driver->init_termios = tty_std_termios; |
383 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 389 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
390 | pts_driver->init_termios.c_ispeed = 38400; | ||
391 | pts_driver->init_termios.c_ospeed = 38400; | ||
384 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | 392 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | |
385 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | 393 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; |
386 | pts_driver->other = ptm_driver; | 394 | pts_driver->other = ptm_driver; |
diff --git a/drivers/char/random.c b/drivers/char/random.c index 4c6782a1ecdb..092a01cc02da 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1048,7 +1048,7 @@ random_write(struct file * file, const char __user * buffer, | |||
1048 | if (p == buffer) { | 1048 | if (p == buffer) { |
1049 | return (ssize_t)ret; | 1049 | return (ssize_t)ret; |
1050 | } else { | 1050 | } else { |
1051 | struct inode *inode = file->f_dentry->d_inode; | 1051 | struct inode *inode = file->f_path.dentry->d_inode; |
1052 | inode->i_mtime = current_fs_time(inode->i_sb); | 1052 | inode->i_mtime = current_fs_time(inode->i_sb); |
1053 | mark_inode_dirty(inode); | 1053 | mark_inode_dirty(inode); |
1054 | return (ssize_t)(p - buffer); | 1054 | return (ssize_t)(p - buffer); |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index 3b32313f6eb4..645e20a06ece 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -75,7 +75,7 @@ static int raw_open(struct inode *inode, struct file *filp) | |||
75 | filp->f_flags |= O_DIRECT; | 75 | filp->f_flags |= O_DIRECT; |
76 | filp->f_mapping = bdev->bd_inode->i_mapping; | 76 | filp->f_mapping = bdev->bd_inode->i_mapping; |
77 | if (++raw_devices[minor].inuse == 1) | 77 | if (++raw_devices[minor].inuse == 1) |
78 | filp->f_dentry->d_inode->i_mapping = | 78 | filp->f_path.dentry->d_inode->i_mapping = |
79 | bdev->bd_inode->i_mapping; | 79 | bdev->bd_inode->i_mapping; |
80 | filp->private_data = bdev; | 80 | filp->private_data = bdev; |
81 | mutex_unlock(&raw_mutex); | 81 | mutex_unlock(&raw_mutex); |
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 7ac68cb3bedd..e79b2ede8510 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c | |||
@@ -1026,6 +1026,7 @@ static int __init rio_init(void) | |||
1026 | found++; | 1026 | found++; |
1027 | } else { | 1027 | } else { |
1028 | iounmap(p->RIOHosts[p->RIONumHosts].Caddr); | 1028 | iounmap(p->RIOHosts[p->RIONumHosts].Caddr); |
1029 | p->RIOHosts[p->RIONumHosts].Caddr = NULL; | ||
1029 | } | 1030 | } |
1030 | } | 1031 | } |
1031 | 1032 | ||
@@ -1078,6 +1079,7 @@ static int __init rio_init(void) | |||
1078 | found++; | 1079 | found++; |
1079 | } else { | 1080 | } else { |
1080 | iounmap(p->RIOHosts[p->RIONumHosts].Caddr); | 1081 | iounmap(p->RIOHosts[p->RIONumHosts].Caddr); |
1082 | p->RIOHosts[p->RIONumHosts].Caddr = NULL; | ||
1081 | } | 1083 | } |
1082 | #else | 1084 | #else |
1083 | printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); | 1085 | printk(KERN_ERR "Found an older RIO PCI card, but the driver is not " "compiled to support it.\n"); |
@@ -1117,8 +1119,10 @@ static int __init rio_init(void) | |||
1117 | } | 1119 | } |
1118 | } | 1120 | } |
1119 | 1121 | ||
1120 | if (!okboard) | 1122 | if (!okboard) { |
1121 | iounmap(hp->Caddr); | 1123 | iounmap(hp->Caddr); |
1124 | hp->Caddr = NULL; | ||
1125 | } | ||
1122 | } | 1126 | } |
1123 | } | 1127 | } |
1124 | 1128 | ||
@@ -1188,6 +1192,8 @@ static void __exit rio_exit(void) | |||
1188 | } | 1192 | } |
1189 | /* It is safe/allowed to del_timer a non-active timer */ | 1193 | /* It is safe/allowed to del_timer a non-active timer */ |
1190 | del_timer(&hp->timer); | 1194 | del_timer(&hp->timer); |
1195 | if (hp->Caddr) | ||
1196 | iounmap(hp->Caddr); | ||
1191 | if (hp->Type == RIO_PCI) | 1197 | if (hp->Type == RIO_PCI) |
1192 | pci_dev_put(hp->pdev); | 1198 | pci_dev_put(hp->pdev); |
1193 | } | 1199 | } |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 722dd3e74185..e2a94bfb2a43 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -82,11 +82,6 @@ | |||
82 | static struct riscom_board * IRQ_to_board[16]; | 82 | static struct riscom_board * IRQ_to_board[16]; |
83 | static struct tty_driver *riscom_driver; | 83 | static struct tty_driver *riscom_driver; |
84 | 84 | ||
85 | static unsigned long baud_table[] = { | ||
86 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
87 | 9600, 19200, 38400, 57600, 76800, 0, | ||
88 | }; | ||
89 | |||
90 | static struct riscom_board rc_board[RC_NBOARD] = { | 85 | static struct riscom_board rc_board[RC_NBOARD] = { |
91 | { | 86 | { |
92 | .base = RC_IOBASE1, | 87 | .base = RC_IOBASE1, |
@@ -1544,7 +1539,7 @@ static void rc_hangup(struct tty_struct * tty) | |||
1544 | wake_up_interruptible(&port->open_wait); | 1539 | wake_up_interruptible(&port->open_wait); |
1545 | } | 1540 | } |
1546 | 1541 | ||
1547 | static void rc_set_termios(struct tty_struct * tty, struct termios * old_termios) | 1542 | static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termios) |
1548 | { | 1543 | { |
1549 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; | 1544 | struct riscom_port *port = (struct riscom_port *)tty->driver_data; |
1550 | unsigned long flags; | 1545 | unsigned long flags; |
@@ -1619,6 +1614,8 @@ static inline int rc_init_drivers(void) | |||
1619 | riscom_driver->init_termios = tty_std_termios; | 1614 | riscom_driver->init_termios = tty_std_termios; |
1620 | riscom_driver->init_termios.c_cflag = | 1615 | riscom_driver->init_termios.c_cflag = |
1621 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1616 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1617 | riscom_driver->init_termios.c_ispeed = 9600; | ||
1618 | riscom_driver->init_termios.c_ospeed = 9600; | ||
1622 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; | 1619 | riscom_driver->flags = TTY_DRIVER_REAL_RAW; |
1623 | tty_set_operations(riscom_driver, &riscom_ops); | 1620 | tty_set_operations(riscom_driver, &riscom_ops); |
1624 | if ((error = tty_register_driver(riscom_driver))) { | 1621 | if ((error = tty_register_driver(riscom_driver))) { |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index bac80056f7e0..e94a62e30fc4 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -712,7 +712,7 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
712 | * user mode into the driver (exception handler). *info CD manipulation is spinlock protected. | 712 | * user mode into the driver (exception handler). *info CD manipulation is spinlock protected. |
713 | */ | 713 | */ |
714 | static void configure_r_port(struct r_port *info, | 714 | static void configure_r_port(struct r_port *info, |
715 | struct termios *old_termios) | 715 | struct ktermios *old_termios) |
716 | { | 716 | { |
717 | unsigned cflag; | 717 | unsigned cflag; |
718 | unsigned long flags; | 718 | unsigned long flags; |
@@ -1017,7 +1017,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
1017 | /* | 1017 | /* |
1018 | * Info->count is now 1; so it's safe to sleep now. | 1018 | * Info->count is now 1; so it's safe to sleep now. |
1019 | */ | 1019 | */ |
1020 | info->session = current->signal->session; | 1020 | info->session = process_session(current); |
1021 | info->pgrp = process_group(current); | 1021 | info->pgrp = process_group(current); |
1022 | 1022 | ||
1023 | if ((info->flags & ROCKET_INITIALIZED) == 0) { | 1023 | if ((info->flags & ROCKET_INITIALIZED) == 0) { |
@@ -1194,7 +1194,7 @@ static void rp_close(struct tty_struct *tty, struct file *filp) | |||
1194 | } | 1194 | } |
1195 | 1195 | ||
1196 | static void rp_set_termios(struct tty_struct *tty, | 1196 | static void rp_set_termios(struct tty_struct *tty, |
1197 | struct termios *old_termios) | 1197 | struct ktermios *old_termios) |
1198 | { | 1198 | { |
1199 | struct r_port *info = (struct r_port *) tty->driver_data; | 1199 | struct r_port *info = (struct r_port *) tty->driver_data; |
1200 | CHANNEL_t *cp; | 1200 | CHANNEL_t *cp; |
@@ -2214,7 +2214,7 @@ static int __init init_PCI(int boards_found) | |||
2214 | int count = 0; | 2214 | int count = 0; |
2215 | 2215 | ||
2216 | /* Work through the PCI device list, pulling out ours */ | 2216 | /* Work through the PCI device list, pulling out ours */ |
2217 | while ((dev = pci_find_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) { | 2217 | while ((dev = pci_get_device(PCI_VENDOR_ID_RP, PCI_ANY_ID, dev))) { |
2218 | if (register_PCI(count + boards_found, dev)) | 2218 | if (register_PCI(count + boards_found, dev)) |
2219 | count++; | 2219 | count++; |
2220 | } | 2220 | } |
@@ -2436,6 +2436,8 @@ static int __init rp_init(void) | |||
2436 | rocket_driver->init_termios = tty_std_termios; | 2436 | rocket_driver->init_termios = tty_std_termios; |
2437 | rocket_driver->init_termios.c_cflag = | 2437 | rocket_driver->init_termios.c_cflag = |
2438 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2438 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2439 | rocket_driver->init_termios.c_ispeed = 9600; | ||
2440 | rocket_driver->init_termios.c_ospeed = 9600; | ||
2439 | #ifdef ROCKET_SOFT_FLOW | 2441 | #ifdef ROCKET_SOFT_FLOW |
2440 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 2442 | rocket_driver->flags |= TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; |
2441 | #endif | 2443 | #endif |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 4217d38caef9..75de5f66517a 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -695,6 +695,8 @@ static int a2232_init_drivers(void) | |||
695 | a2232_driver->init_termios = tty_std_termios; | 695 | a2232_driver->init_termios = tty_std_termios; |
696 | a2232_driver->init_termios.c_cflag = | 696 | a2232_driver->init_termios.c_cflag = |
697 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 697 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
698 | a2232_driver->init_termios.c_ispeed = 9600; | ||
699 | a2232_driver->init_termios.c_ospeed = 9600; | ||
698 | a2232_driver->flags = TTY_DRIVER_REAL_RAW; | 700 | a2232_driver->flags = TTY_DRIVER_REAL_RAW; |
699 | tty_set_operations(a2232_driver, &a2232_ops); | 701 | tty_set_operations(a2232_driver, &a2232_ops); |
700 | if ((error = tty_register_driver(a2232_driver))) { | 702 | if ((error = tty_register_driver(a2232_driver))) { |
diff --git a/drivers/char/serial167.c b/drivers/char/serial167.c index 9ba13af234be..af50d32ae2c7 100644 --- a/drivers/char/serial167.c +++ b/drivers/char/serial167.c | |||
@@ -1695,7 +1695,7 @@ cy_ioctl(struct tty_struct *tty, struct file * file, | |||
1695 | 1695 | ||
1696 | 1696 | ||
1697 | static void | 1697 | static void |
1698 | cy_set_termios(struct tty_struct *tty, struct termios * old_termios) | 1698 | cy_set_termios(struct tty_struct *tty, struct ktermios * old_termios) |
1699 | { | 1699 | { |
1700 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; | 1700 | struct cyclades_port *info = (struct cyclades_port *)tty->driver_data; |
1701 | 1701 | ||
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index fc87070f1866..17d54e1331b2 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -979,7 +979,7 @@ static ssize_t sonypi_misc_read(struct file *file, char __user *buf, | |||
979 | } | 979 | } |
980 | 980 | ||
981 | if (ret > 0) { | 981 | if (ret > 0) { |
982 | struct inode *inode = file->f_dentry->d_inode; | 982 | struct inode *inode = file->f_path.dentry->d_inode; |
983 | inode->i_atime = current_fs_time(inode->i_sb); | 983 | inode->i_atime = current_fs_time(inode->i_sb); |
984 | } | 984 | } |
985 | 985 | ||
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c index 99137ab66b62..20946f5127e0 100644 --- a/drivers/char/specialix.c +++ b/drivers/char/specialix.c | |||
@@ -2311,7 +2311,7 @@ static void sx_hangup(struct tty_struct * tty) | |||
2311 | } | 2311 | } |
2312 | 2312 | ||
2313 | 2313 | ||
2314 | static void sx_set_termios(struct tty_struct * tty, struct termios * old_termios) | 2314 | static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termios) |
2315 | { | 2315 | { |
2316 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; | 2316 | struct specialix_port *port = (struct specialix_port *)tty->driver_data; |
2317 | unsigned long flags; | 2317 | unsigned long flags; |
@@ -2400,6 +2400,8 @@ static int sx_init_drivers(void) | |||
2400 | specialix_driver->init_termios = tty_std_termios; | 2400 | specialix_driver->init_termios = tty_std_termios; |
2401 | specialix_driver->init_termios.c_cflag = | 2401 | specialix_driver->init_termios.c_cflag = |
2402 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2402 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2403 | specialix_driver->init_termios.c_ispeed = 9600; | ||
2404 | specialix_driver->init_termios.c_ospeed = 9600; | ||
2403 | specialix_driver->flags = TTY_DRIVER_REAL_RAW; | 2405 | specialix_driver->flags = TTY_DRIVER_REAL_RAW; |
2404 | tty_set_operations(specialix_driver, &sx_ops); | 2406 | tty_set_operations(specialix_driver, &sx_ops); |
2405 | 2407 | ||
@@ -2475,7 +2477,7 @@ static int __init specialix_init(void) | |||
2475 | i++; | 2477 | i++; |
2476 | continue; | 2478 | continue; |
2477 | } | 2479 | } |
2478 | pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, | 2480 | pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, |
2479 | PCI_DEVICE_ID_SPECIALIX_IO8, | 2481 | PCI_DEVICE_ID_SPECIALIX_IO8, |
2480 | pdev); | 2482 | pdev); |
2481 | if (!pdev) break; | 2483 | if (!pdev) break; |
@@ -2491,6 +2493,9 @@ static int __init specialix_init(void) | |||
2491 | if (!sx_probe(&sx_board[i])) | 2493 | if (!sx_probe(&sx_board[i])) |
2492 | found ++; | 2494 | found ++; |
2493 | } | 2495 | } |
2496 | /* May exit pci_get sequence early with lots of boards */ | ||
2497 | if (pdev != NULL) | ||
2498 | pci_dev_put(pdev); | ||
2494 | } | 2499 | } |
2495 | #endif | 2500 | #endif |
2496 | 2501 | ||
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c index 5e2de62bce70..e45113a7a472 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,45 +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. | 66 | unsigned int brdtype; |
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 | typedef struct { | ||
92 | 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 | } stlconf_t; | ||
99 | |||
100 | static stlconf_t stl_brdconf[] = { | ||
101 | /*{ BRD_EASYIO, 0x2a0, 0, 0, 10, 0 },*/ | ||
102 | }; | 72 | }; |
103 | 73 | ||
104 | static int stl_nrbrds = ARRAY_SIZE(stl_brdconf); | 74 | static unsigned int stl_nrbrds; |
105 | 75 | ||
106 | /*****************************************************************************/ | 76 | /*****************************************************************************/ |
107 | 77 | ||
@@ -143,34 +113,30 @@ static struct tty_driver *stl_serial; | |||
143 | * with this termios initially. Basically all it defines is a raw port | 113 | * with this termios initially. Basically all it defines is a raw port |
144 | * at 9600, 8 data bits, 1 stop bit. | 114 | * at 9600, 8 data bits, 1 stop bit. |
145 | */ | 115 | */ |
146 | static struct termios stl_deftermios = { | 116 | static struct ktermios stl_deftermios = { |
147 | .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), | 117 | .c_cflag = (B9600 | CS8 | CREAD | HUPCL | CLOCAL), |
148 | .c_cc = INIT_C_CC, | 118 | .c_cc = INIT_C_CC, |
119 | .c_ispeed = 9600, | ||
120 | .c_ospeed = 9600, | ||
149 | }; | 121 | }; |
150 | 122 | ||
151 | /* | 123 | /* |
152 | * Define global stats structures. Not used often, and can be | ||
153 | * re-used for each stats call. | ||
154 | */ | ||
155 | static comstats_t stl_comstats; | ||
156 | static combrd_t stl_brdstats; | ||
157 | static stlbrd_t stl_dummybrd; | ||
158 | static stlport_t stl_dummyport; | ||
159 | |||
160 | /* | ||
161 | * Define global place to put buffer overflow characters. | 124 | * Define global place to put buffer overflow characters. |
162 | */ | 125 | */ |
163 | static char stl_unwanted[SC26198_RXFIFOSIZE]; | 126 | static char stl_unwanted[SC26198_RXFIFOSIZE]; |
164 | 127 | ||
165 | /*****************************************************************************/ | 128 | /*****************************************************************************/ |
166 | 129 | ||
167 | static stlbrd_t *stl_brds[STL_MAXBRDS]; | 130 | static DEFINE_MUTEX(stl_brdslock); |
131 | static struct stlbrd *stl_brds[STL_MAXBRDS]; | ||
168 | 132 | ||
169 | /* | 133 | /* |
170 | * Per board state flags. Used with the state field of the board struct. | 134 | * Per board state flags. Used with the state field of the board struct. |
171 | * Not really much here! | 135 | * Not really much here! |
172 | */ | 136 | */ |
173 | #define BRD_FOUND 0x1 | 137 | #define BRD_FOUND 0x1 |
138 | #define STL_PROBED 0x2 | ||
139 | |||
174 | 140 | ||
175 | /* | 141 | /* |
176 | * Define the port structure istate flags. These set of flags are | 142 | * Define the port structure istate flags. These set of flags are |
@@ -187,32 +153,32 @@ static stlbrd_t *stl_brds[STL_MAXBRDS]; | |||
187 | * referencing boards when printing trace and stuff. | 153 | * referencing boards when printing trace and stuff. |
188 | */ | 154 | */ |
189 | static char *stl_brdnames[] = { | 155 | static char *stl_brdnames[] = { |
190 | (char *) NULL, | 156 | NULL, |
191 | (char *) NULL, | 157 | NULL, |
192 | (char *) NULL, | 158 | NULL, |
193 | (char *) NULL, | 159 | NULL, |
194 | (char *) NULL, | 160 | NULL, |
195 | (char *) NULL, | 161 | NULL, |
196 | (char *) NULL, | 162 | NULL, |
197 | (char *) NULL, | 163 | NULL, |
198 | (char *) NULL, | 164 | NULL, |
199 | (char *) NULL, | 165 | NULL, |
200 | (char *) NULL, | 166 | NULL, |
201 | (char *) NULL, | 167 | NULL, |
202 | (char *) NULL, | 168 | NULL, |
203 | (char *) NULL, | 169 | NULL, |
204 | (char *) NULL, | 170 | NULL, |
205 | (char *) NULL, | 171 | NULL, |
206 | (char *) NULL, | 172 | NULL, |
207 | (char *) NULL, | 173 | NULL, |
208 | (char *) NULL, | 174 | NULL, |
209 | (char *) NULL, | 175 | NULL, |
210 | "EasyIO", | 176 | "EasyIO", |
211 | "EC8/32-AT", | 177 | "EC8/32-AT", |
212 | "EC8/32-MC", | 178 | "EC8/32-MC", |
213 | (char *) NULL, | 179 | NULL, |
214 | (char *) NULL, | 180 | NULL, |
215 | (char *) NULL, | 181 | NULL, |
216 | "EC8/32-PCI", | 182 | "EC8/32-PCI", |
217 | "EC8/64-PCI", | 183 | "EC8/64-PCI", |
218 | "EasyIO-PCI", | 184 | "EasyIO-PCI", |
@@ -225,7 +191,7 @@ static char *stl_brdnames[] = { | |||
225 | * load line. These allow for easy board definitions, and easy | 191 | * load line. These allow for easy board definitions, and easy |
226 | * modification of the io, memory and irq resoucres. | 192 | * modification of the io, memory and irq resoucres. |
227 | */ | 193 | */ |
228 | static int stl_nargs = 0; | 194 | static unsigned int stl_nargs; |
229 | static char *board0[4]; | 195 | static char *board0[4]; |
230 | static char *board1[4]; | 196 | static char *board1[4]; |
231 | static char *board2[4]; | 197 | static char *board2[4]; |
@@ -243,12 +209,10 @@ static char **stl_brdsp[] = { | |||
243 | * parse any module arguments. | 209 | * parse any module arguments. |
244 | */ | 210 | */ |
245 | 211 | ||
246 | typedef struct stlbrdtype { | 212 | static struct { |
247 | char *name; | 213 | char *name; |
248 | int type; | 214 | int type; |
249 | } stlbrdtype_t; | 215 | } stl_brdstr[] = { |
250 | |||
251 | static stlbrdtype_t stl_brdstr[] = { | ||
252 | { "easyio", BRD_EASYIO }, | 216 | { "easyio", BRD_EASYIO }, |
253 | { "eio", BRD_EASYIO }, | 217 | { "eio", BRD_EASYIO }, |
254 | { "20", BRD_EASYIO }, | 218 | { "20", BRD_EASYIO }, |
@@ -282,9 +246,6 @@ static stlbrdtype_t stl_brdstr[] = { | |||
282 | /* | 246 | /* |
283 | * Define the module agruments. | 247 | * Define the module agruments. |
284 | */ | 248 | */ |
285 | MODULE_AUTHOR("Greg Ungerer"); | ||
286 | MODULE_DESCRIPTION("Stallion Multiport Serial Driver"); | ||
287 | MODULE_LICENSE("GPL"); | ||
288 | 249 | ||
289 | module_param_array(board0, charp, &stl_nargs, 0); | 250 | module_param_array(board0, charp, &stl_nargs, 0); |
290 | MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]"); | 251 | MODULE_PARM_DESC(board0, "Board 0 config -> name[,ioaddr[,ioaddr2][,irq]]"); |
@@ -386,8 +347,6 @@ static spinlock_t stallion_lock; /* Guard the tty driver */ | |||
386 | 347 | ||
387 | /*****************************************************************************/ | 348 | /*****************************************************************************/ |
388 | 349 | ||
389 | #ifdef CONFIG_PCI | ||
390 | |||
391 | /* | 350 | /* |
392 | * Define the Stallion PCI vendor and device IDs. | 351 | * Define the Stallion PCI vendor and device IDs. |
393 | */ | 352 | */ |
@@ -407,22 +366,19 @@ static spinlock_t stallion_lock; /* Guard the tty driver */ | |||
407 | /* | 366 | /* |
408 | * Define structure to hold all Stallion PCI boards. | 367 | * Define structure to hold all Stallion PCI boards. |
409 | */ | 368 | */ |
410 | typedef struct stlpcibrd { | ||
411 | unsigned short vendid; | ||
412 | unsigned short devid; | ||
413 | int brdtype; | ||
414 | } stlpcibrd_t; | ||
415 | |||
416 | static stlpcibrd_t stl_pcibrds[] = { | ||
417 | { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864, BRD_ECH64PCI }, | ||
418 | { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI, BRD_EASYIOPCI }, | ||
419 | { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832, BRD_ECHPCI }, | ||
420 | { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410, BRD_ECHPCI }, | ||
421 | }; | ||
422 | |||
423 | static int stl_nrpcibrds = ARRAY_SIZE(stl_pcibrds); | ||
424 | 369 | ||
425 | #endif | 370 | static struct pci_device_id stl_pcibrds[] = { |
371 | { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI864), | ||
372 | .driver_data = BRD_ECH64PCI }, | ||
373 | { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_EIOPCI), | ||
374 | .driver_data = BRD_EASYIOPCI }, | ||
375 | { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECHPCI832), | ||
376 | .driver_data = BRD_ECHPCI }, | ||
377 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_87410), | ||
378 | .driver_data = BRD_ECHPCI }, | ||
379 | { } | ||
380 | }; | ||
381 | MODULE_DEVICE_TABLE(pci, stl_pcibrds); | ||
426 | 382 | ||
427 | /*****************************************************************************/ | 383 | /*****************************************************************************/ |
428 | 384 | ||
@@ -442,134 +398,74 @@ static unsigned int stl_baudrates[] = { | |||
442 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 | 398 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600 |
443 | }; | 399 | }; |
444 | 400 | ||
445 | /* | ||
446 | * Define some handy local macros... | ||
447 | */ | ||
448 | #undef MIN | ||
449 | #define MIN(a,b) (((a) <= (b)) ? (a) : (b)) | ||
450 | |||
451 | #undef TOLOWER | ||
452 | #define TOLOWER(x) ((((x) >= 'A') && ((x) <= 'Z')) ? ((x) + 0x20) : (x)) | ||
453 | |||
454 | /*****************************************************************************/ | 401 | /*****************************************************************************/ |
455 | 402 | ||
456 | /* | 403 | /* |
457 | * Declare all those functions in this driver! | 404 | * Declare all those functions in this driver! |
458 | */ | 405 | */ |
459 | 406 | ||
460 | static void stl_argbrds(void); | ||
461 | static int stl_parsebrd(stlconf_t *confp, char **argp); | ||
462 | |||
463 | static unsigned long stl_atol(char *str); | ||
464 | |||
465 | static int stl_init(void); | ||
466 | static int stl_open(struct tty_struct *tty, struct file *filp); | ||
467 | static void stl_close(struct tty_struct *tty, struct file *filp); | ||
468 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count); | ||
469 | static void stl_putchar(struct tty_struct *tty, unsigned char ch); | ||
470 | static void stl_flushchars(struct tty_struct *tty); | ||
471 | static int stl_writeroom(struct tty_struct *tty); | ||
472 | static int stl_charsinbuffer(struct tty_struct *tty); | ||
473 | static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); | ||
474 | static void stl_settermios(struct tty_struct *tty, struct termios *old); | ||
475 | static void stl_throttle(struct tty_struct *tty); | ||
476 | static void stl_unthrottle(struct tty_struct *tty); | ||
477 | static void stl_stop(struct tty_struct *tty); | ||
478 | static void stl_start(struct tty_struct *tty); | ||
479 | static void stl_flushbuffer(struct tty_struct *tty); | ||
480 | static void stl_breakctl(struct tty_struct *tty, int state); | ||
481 | static void stl_waituntilsent(struct tty_struct *tty, int timeout); | ||
482 | static void stl_sendxchar(struct tty_struct *tty, char ch); | ||
483 | static void stl_hangup(struct tty_struct *tty); | ||
484 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); | 407 | static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); |
485 | static int stl_portinfo(stlport_t *portp, int portnr, char *pos); | 408 | static int stl_brdinit(struct stlbrd *brdp); |
486 | static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data); | 409 | static int stl_getportstats(struct stlport *portp, comstats_t __user *cp); |
487 | 410 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp); | |
488 | static int stl_brdinit(stlbrd_t *brdp); | 411 | static int stl_waitcarrier(struct stlport *portp, struct file *filp); |
489 | static int stl_initports(stlbrd_t *brdp, stlpanel_t *panelp); | ||
490 | static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp); | ||
491 | static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp); | ||
492 | static int stl_getbrdstats(combrd_t __user *bp); | ||
493 | static int stl_getportstats(stlport_t *portp, comstats_t __user *cp); | ||
494 | static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp); | ||
495 | static int stl_getportstruct(stlport_t __user *arg); | ||
496 | static int stl_getbrdstruct(stlbrd_t __user *arg); | ||
497 | static int stl_waitcarrier(stlport_t *portp, struct file *filp); | ||
498 | static int stl_eiointr(stlbrd_t *brdp); | ||
499 | static int stl_echatintr(stlbrd_t *brdp); | ||
500 | static int stl_echmcaintr(stlbrd_t *brdp); | ||
501 | static int stl_echpciintr(stlbrd_t *brdp); | ||
502 | static int stl_echpci64intr(stlbrd_t *brdp); | ||
503 | static void stl_offintr(struct work_struct *); | ||
504 | static stlbrd_t *stl_allocbrd(void); | ||
505 | static stlport_t *stl_getport(int brdnr, int panelnr, int portnr); | ||
506 | |||
507 | static inline int stl_initbrds(void); | ||
508 | static inline int stl_initeio(stlbrd_t *brdp); | ||
509 | static inline int stl_initech(stlbrd_t *brdp); | ||
510 | static inline int stl_getbrdnr(void); | ||
511 | |||
512 | #ifdef CONFIG_PCI | ||
513 | static inline int stl_findpcibrds(void); | ||
514 | static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp); | ||
515 | #endif | ||
516 | 412 | ||
517 | /* | 413 | /* |
518 | * CD1400 uart specific handling functions. | 414 | * CD1400 uart specific handling functions. |
519 | */ | 415 | */ |
520 | static void stl_cd1400setreg(stlport_t *portp, int regnr, int value); | 416 | static void stl_cd1400setreg(struct stlport *portp, int regnr, int value); |
521 | static int stl_cd1400getreg(stlport_t *portp, int regnr); | 417 | static int stl_cd1400getreg(struct stlport *portp, int regnr); |
522 | static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value); | 418 | static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value); |
523 | static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp); | 419 | static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp); |
524 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp); | 420 | static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); |
525 | static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp); | 421 | static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp); |
526 | static int stl_cd1400getsignals(stlport_t *portp); | 422 | static int stl_cd1400getsignals(struct stlport *portp); |
527 | static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts); | 423 | static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts); |
528 | static void stl_cd1400ccrwait(stlport_t *portp); | 424 | static void stl_cd1400ccrwait(struct stlport *portp); |
529 | static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx); | 425 | static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx); |
530 | static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx); | 426 | static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx); |
531 | static void stl_cd1400disableintrs(stlport_t *portp); | 427 | static void stl_cd1400disableintrs(struct stlport *portp); |
532 | static void stl_cd1400sendbreak(stlport_t *portp, int len); | 428 | static void stl_cd1400sendbreak(struct stlport *portp, int len); |
533 | static void stl_cd1400flowctrl(stlport_t *portp, int state); | 429 | static void stl_cd1400flowctrl(struct stlport *portp, int state); |
534 | static void stl_cd1400sendflow(stlport_t *portp, int state); | 430 | static void stl_cd1400sendflow(struct stlport *portp, int state); |
535 | static void stl_cd1400flush(stlport_t *portp); | 431 | static void stl_cd1400flush(struct stlport *portp); |
536 | static int stl_cd1400datastate(stlport_t *portp); | 432 | static int stl_cd1400datastate(struct stlport *portp); |
537 | static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase); | 433 | static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase); |
538 | static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase); | 434 | static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase); |
539 | static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr); | 435 | static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr); |
540 | static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr); | 436 | static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr); |
541 | static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr); | 437 | static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr); |
542 | 438 | ||
543 | static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr); | 439 | static inline int stl_cd1400breakisr(struct stlport *portp, int ioaddr); |
544 | 440 | ||
545 | /* | 441 | /* |
546 | * SC26198 uart specific handling functions. | 442 | * SC26198 uart specific handling functions. |
547 | */ | 443 | */ |
548 | static void stl_sc26198setreg(stlport_t *portp, int regnr, int value); | 444 | static void stl_sc26198setreg(struct stlport *portp, int regnr, int value); |
549 | static int stl_sc26198getreg(stlport_t *portp, int regnr); | 445 | static int stl_sc26198getreg(struct stlport *portp, int regnr); |
550 | static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value); | 446 | static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value); |
551 | static int stl_sc26198getglobreg(stlport_t *portp, int regnr); | 447 | static int stl_sc26198getglobreg(struct stlport *portp, int regnr); |
552 | static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp); | 448 | static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp); |
553 | static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp); | 449 | static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); |
554 | static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp); | 450 | static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp); |
555 | static int stl_sc26198getsignals(stlport_t *portp); | 451 | static int stl_sc26198getsignals(struct stlport *portp); |
556 | static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts); | 452 | static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts); |
557 | static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx); | 453 | static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx); |
558 | static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx); | 454 | static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx); |
559 | static void stl_sc26198disableintrs(stlport_t *portp); | 455 | static void stl_sc26198disableintrs(struct stlport *portp); |
560 | static void stl_sc26198sendbreak(stlport_t *portp, int len); | 456 | static void stl_sc26198sendbreak(struct stlport *portp, int len); |
561 | static void stl_sc26198flowctrl(stlport_t *portp, int state); | 457 | static void stl_sc26198flowctrl(struct stlport *portp, int state); |
562 | static void stl_sc26198sendflow(stlport_t *portp, int state); | 458 | static void stl_sc26198sendflow(struct stlport *portp, int state); |
563 | static void stl_sc26198flush(stlport_t *portp); | 459 | static void stl_sc26198flush(struct stlport *portp); |
564 | static int stl_sc26198datastate(stlport_t *portp); | 460 | static int stl_sc26198datastate(struct stlport *portp); |
565 | static void stl_sc26198wait(stlport_t *portp); | 461 | static void stl_sc26198wait(struct stlport *portp); |
566 | static void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty); | 462 | static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty); |
567 | static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase); | 463 | static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase); |
568 | static void stl_sc26198txisr(stlport_t *port); | 464 | static void stl_sc26198txisr(struct stlport *port); |
569 | static void stl_sc26198rxisr(stlport_t *port, unsigned int iack); | 465 | static void stl_sc26198rxisr(struct stlport *port, unsigned int iack); |
570 | static void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch); | 466 | static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch); |
571 | static void stl_sc26198rxbadchars(stlport_t *portp); | 467 | static void stl_sc26198rxbadchars(struct stlport *portp); |
572 | static void stl_sc26198otherisr(stlport_t *port, unsigned int iack); | 468 | static void stl_sc26198otherisr(struct stlport *port, unsigned int iack); |
573 | 469 | ||
574 | /*****************************************************************************/ | 470 | /*****************************************************************************/ |
575 | 471 | ||
@@ -577,20 +473,20 @@ static void stl_sc26198otherisr(stlport_t *port, unsigned int iack); | |||
577 | * Generic UART support structure. | 473 | * Generic UART support structure. |
578 | */ | 474 | */ |
579 | typedef struct uart { | 475 | typedef struct uart { |
580 | int (*panelinit)(stlbrd_t *brdp, stlpanel_t *panelp); | 476 | int (*panelinit)(struct stlbrd *brdp, struct stlpanel *panelp); |
581 | void (*portinit)(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp); | 477 | void (*portinit)(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp); |
582 | void (*setport)(stlport_t *portp, struct termios *tiosp); | 478 | void (*setport)(struct stlport *portp, struct ktermios *tiosp); |
583 | int (*getsignals)(stlport_t *portp); | 479 | int (*getsignals)(struct stlport *portp); |
584 | void (*setsignals)(stlport_t *portp, int dtr, int rts); | 480 | void (*setsignals)(struct stlport *portp, int dtr, int rts); |
585 | void (*enablerxtx)(stlport_t *portp, int rx, int tx); | 481 | void (*enablerxtx)(struct stlport *portp, int rx, int tx); |
586 | void (*startrxtx)(stlport_t *portp, int rx, int tx); | 482 | void (*startrxtx)(struct stlport *portp, int rx, int tx); |
587 | void (*disableintrs)(stlport_t *portp); | 483 | void (*disableintrs)(struct stlport *portp); |
588 | void (*sendbreak)(stlport_t *portp, int len); | 484 | void (*sendbreak)(struct stlport *portp, int len); |
589 | void (*flowctrl)(stlport_t *portp, int state); | 485 | void (*flowctrl)(struct stlport *portp, int state); |
590 | void (*sendflow)(stlport_t *portp, int state); | 486 | void (*sendflow)(struct stlport *portp, int state); |
591 | void (*flush)(stlport_t *portp); | 487 | void (*flush)(struct stlport *portp); |
592 | int (*datastate)(stlport_t *portp); | 488 | int (*datastate)(struct stlport *portp); |
593 | void (*intr)(stlpanel_t *panelp, unsigned int iobase); | 489 | void (*intr)(struct stlpanel *panelp, unsigned int iobase); |
594 | } uart_t; | 490 | } uart_t; |
595 | 491 | ||
596 | /* | 492 | /* |
@@ -712,184 +608,35 @@ static const struct file_operations stl_fsiomem = { | |||
712 | .ioctl = stl_memioctl, | 608 | .ioctl = stl_memioctl, |
713 | }; | 609 | }; |
714 | 610 | ||
715 | /*****************************************************************************/ | ||
716 | |||
717 | static struct class *stallion_class; | 611 | static struct class *stallion_class; |
718 | 612 | ||
719 | /* | 613 | /* |
720 | * Loadable module initialization stuff. | ||
721 | */ | ||
722 | |||
723 | static int __init stallion_module_init(void) | ||
724 | { | ||
725 | stl_init(); | ||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | /*****************************************************************************/ | ||
730 | |||
731 | static void __exit stallion_module_exit(void) | ||
732 | { | ||
733 | stlbrd_t *brdp; | ||
734 | stlpanel_t *panelp; | ||
735 | stlport_t *portp; | ||
736 | int i, j, k; | ||
737 | |||
738 | #ifdef DEBUG | ||
739 | printk("cleanup_module()\n"); | ||
740 | #endif | ||
741 | |||
742 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | ||
743 | stl_drvversion); | ||
744 | |||
745 | /* | ||
746 | * Free up all allocated resources used by the ports. This includes | ||
747 | * memory and interrupts. As part of this process we will also do | ||
748 | * a hangup on every open port - to try to flush out any processes | ||
749 | * hanging onto ports. | ||
750 | */ | ||
751 | i = tty_unregister_driver(stl_serial); | ||
752 | put_tty_driver(stl_serial); | ||
753 | if (i) { | ||
754 | printk("STALLION: failed to un-register tty driver, " | ||
755 | "errno=%d\n", -i); | ||
756 | return; | ||
757 | } | ||
758 | for (i = 0; i < 4; i++) | ||
759 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | ||
760 | if ((i = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) | ||
761 | printk("STALLION: failed to un-register serial memory device, " | ||
762 | "errno=%d\n", -i); | ||
763 | class_destroy(stallion_class); | ||
764 | |||
765 | for (i = 0; (i < stl_nrbrds); i++) { | ||
766 | if ((brdp = stl_brds[i]) == (stlbrd_t *) NULL) | ||
767 | continue; | ||
768 | |||
769 | free_irq(brdp->irq, brdp); | ||
770 | |||
771 | for (j = 0; (j < STL_MAXPANELS); j++) { | ||
772 | panelp = brdp->panels[j]; | ||
773 | if (panelp == (stlpanel_t *) NULL) | ||
774 | continue; | ||
775 | for (k = 0; (k < STL_PORTSPERPANEL); k++) { | ||
776 | portp = panelp->ports[k]; | ||
777 | if (portp == (stlport_t *) NULL) | ||
778 | continue; | ||
779 | if (portp->tty != (struct tty_struct *) NULL) | ||
780 | stl_hangup(portp->tty); | ||
781 | kfree(portp->tx.buf); | ||
782 | kfree(portp); | ||
783 | } | ||
784 | kfree(panelp); | ||
785 | } | ||
786 | |||
787 | release_region(brdp->ioaddr1, brdp->iosize1); | ||
788 | if (brdp->iosize2 > 0) | ||
789 | release_region(brdp->ioaddr2, brdp->iosize2); | ||
790 | |||
791 | kfree(brdp); | ||
792 | stl_brds[i] = (stlbrd_t *) NULL; | ||
793 | } | ||
794 | } | ||
795 | |||
796 | module_init(stallion_module_init); | ||
797 | module_exit(stallion_module_exit); | ||
798 | |||
799 | /*****************************************************************************/ | ||
800 | |||
801 | /* | ||
802 | * Check for any arguments passed in on the module load command line. | 614 | * Check for any arguments passed in on the module load command line. |
803 | */ | 615 | */ |
804 | 616 | ||
805 | static void stl_argbrds(void) | ||
806 | { | ||
807 | stlconf_t conf; | ||
808 | stlbrd_t *brdp; | ||
809 | int i; | ||
810 | |||
811 | #ifdef DEBUG | ||
812 | printk("stl_argbrds()\n"); | ||
813 | #endif | ||
814 | |||
815 | for (i = stl_nrbrds; (i < stl_nargs); i++) { | ||
816 | memset(&conf, 0, sizeof(conf)); | ||
817 | if (stl_parsebrd(&conf, stl_brdsp[i]) == 0) | ||
818 | continue; | ||
819 | if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL) | ||
820 | continue; | ||
821 | stl_nrbrds = i + 1; | ||
822 | brdp->brdnr = i; | ||
823 | brdp->brdtype = conf.brdtype; | ||
824 | brdp->ioaddr1 = conf.ioaddr1; | ||
825 | brdp->ioaddr2 = conf.ioaddr2; | ||
826 | brdp->irq = conf.irq; | ||
827 | brdp->irqtype = conf.irqtype; | ||
828 | stl_brdinit(brdp); | ||
829 | } | ||
830 | } | ||
831 | |||
832 | /*****************************************************************************/ | ||
833 | |||
834 | /* | ||
835 | * Convert an ascii string number into an unsigned long. | ||
836 | */ | ||
837 | |||
838 | static unsigned long stl_atol(char *str) | ||
839 | { | ||
840 | unsigned long val; | ||
841 | int base, c; | ||
842 | char *sp; | ||
843 | |||
844 | val = 0; | ||
845 | sp = str; | ||
846 | if ((*sp == '0') && (*(sp+1) == 'x')) { | ||
847 | base = 16; | ||
848 | sp += 2; | ||
849 | } else if (*sp == '0') { | ||
850 | base = 8; | ||
851 | sp++; | ||
852 | } else { | ||
853 | base = 10; | ||
854 | } | ||
855 | |||
856 | for (; (*sp != 0); sp++) { | ||
857 | c = (*sp > '9') ? (TOLOWER(*sp) - 'a' + 10) : (*sp - '0'); | ||
858 | if ((c < 0) || (c >= base)) { | ||
859 | printk("STALLION: invalid argument %s\n", str); | ||
860 | val = 0; | ||
861 | break; | ||
862 | } | ||
863 | val = (val * base) + c; | ||
864 | } | ||
865 | return val; | ||
866 | } | ||
867 | |||
868 | /*****************************************************************************/ | 617 | /*****************************************************************************/ |
869 | 618 | ||
870 | /* | 619 | /* |
871 | * Parse the supplied argument string, into the board conf struct. | 620 | * Parse the supplied argument string, into the board conf struct. |
872 | */ | 621 | */ |
873 | 622 | ||
874 | static int stl_parsebrd(stlconf_t *confp, char **argp) | 623 | static int __init stl_parsebrd(struct stlconf *confp, char **argp) |
875 | { | 624 | { |
876 | char *sp; | 625 | char *sp; |
877 | int i; | 626 | unsigned int i; |
878 | 627 | ||
879 | #ifdef DEBUG | 628 | pr_debug("stl_parsebrd(confp=%p,argp=%p)\n", confp, argp); |
880 | printk("stl_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); | ||
881 | #endif | ||
882 | 629 | ||
883 | if ((argp[0] == (char *) NULL) || (*argp[0] == 0)) | 630 | if ((argp[0] == NULL) || (*argp[0] == 0)) |
884 | return 0; | 631 | return 0; |
885 | 632 | ||
886 | for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) | 633 | for (sp = argp[0], i = 0; (*sp != 0) && (i < 25); sp++, i++) |
887 | *sp = TOLOWER(*sp); | 634 | *sp = tolower(*sp); |
888 | 635 | ||
889 | for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) { | 636 | for (i = 0; i < ARRAY_SIZE(stl_brdstr); i++) |
890 | if (strcmp(stl_brdstr[i].name, argp[0]) == 0) | 637 | if (strcmp(stl_brdstr[i].name, argp[0]) == 0) |
891 | break; | 638 | break; |
892 | } | 639 | |
893 | if (i == ARRAY_SIZE(stl_brdstr)) { | 640 | if (i == ARRAY_SIZE(stl_brdstr)) { |
894 | printk("STALLION: unknown board name, %s?\n", argp[0]); | 641 | printk("STALLION: unknown board name, %s?\n", argp[0]); |
895 | return 0; | 642 | return 0; |
@@ -898,16 +645,16 @@ static int stl_parsebrd(stlconf_t *confp, char **argp) | |||
898 | confp->brdtype = stl_brdstr[i].type; | 645 | confp->brdtype = stl_brdstr[i].type; |
899 | 646 | ||
900 | i = 1; | 647 | i = 1; |
901 | if ((argp[i] != (char *) NULL) && (*argp[i] != 0)) | 648 | if ((argp[i] != NULL) && (*argp[i] != 0)) |
902 | confp->ioaddr1 = stl_atol(argp[i]); | 649 | confp->ioaddr1 = simple_strtoul(argp[i], NULL, 0); |
903 | i++; | 650 | i++; |
904 | if (confp->brdtype == BRD_ECH) { | 651 | if (confp->brdtype == BRD_ECH) { |
905 | if ((argp[i] != (char *) NULL) && (*argp[i] != 0)) | 652 | if ((argp[i] != NULL) && (*argp[i] != 0)) |
906 | confp->ioaddr2 = stl_atol(argp[i]); | 653 | confp->ioaddr2 = simple_strtoul(argp[i], NULL, 0); |
907 | i++; | 654 | i++; |
908 | } | 655 | } |
909 | if ((argp[i] != (char *) NULL) && (*argp[i] != 0)) | 656 | if ((argp[i] != NULL) && (*argp[i] != 0)) |
910 | confp->irq = stl_atol(argp[i]); | 657 | confp->irq = simple_strtoul(argp[i], NULL, 0); |
911 | return 1; | 658 | return 1; |
912 | } | 659 | } |
913 | 660 | ||
@@ -917,14 +664,14 @@ static int stl_parsebrd(stlconf_t *confp, char **argp) | |||
917 | * Allocate a new board structure. Fill out the basic info in it. | 664 | * Allocate a new board structure. Fill out the basic info in it. |
918 | */ | 665 | */ |
919 | 666 | ||
920 | static stlbrd_t *stl_allocbrd(void) | 667 | static struct stlbrd *stl_allocbrd(void) |
921 | { | 668 | { |
922 | stlbrd_t *brdp; | 669 | struct stlbrd *brdp; |
923 | 670 | ||
924 | brdp = kzalloc(sizeof(stlbrd_t), GFP_KERNEL); | 671 | brdp = kzalloc(sizeof(struct stlbrd), GFP_KERNEL); |
925 | if (!brdp) { | 672 | if (!brdp) { |
926 | printk("STALLION: failed to allocate memory (size=%Zd)\n", | 673 | printk("STALLION: failed to allocate memory (size=%Zd)\n", |
927 | sizeof(stlbrd_t)); | 674 | sizeof(struct stlbrd)); |
928 | return NULL; | 675 | return NULL; |
929 | } | 676 | } |
930 | 677 | ||
@@ -936,26 +683,23 @@ static stlbrd_t *stl_allocbrd(void) | |||
936 | 683 | ||
937 | static int stl_open(struct tty_struct *tty, struct file *filp) | 684 | static int stl_open(struct tty_struct *tty, struct file *filp) |
938 | { | 685 | { |
939 | stlport_t *portp; | 686 | struct stlport *portp; |
940 | stlbrd_t *brdp; | 687 | struct stlbrd *brdp; |
941 | unsigned int minordev; | 688 | unsigned int minordev, brdnr, panelnr; |
942 | int brdnr, panelnr, portnr, rc; | 689 | int portnr, rc; |
943 | 690 | ||
944 | #ifdef DEBUG | 691 | pr_debug("stl_open(tty=%p,filp=%p): device=%s\n", tty, filp, tty->name); |
945 | printk("stl_open(tty=%x,filp=%x): device=%s\n", (int) tty, | ||
946 | (int) filp, tty->name); | ||
947 | #endif | ||
948 | 692 | ||
949 | minordev = tty->index; | 693 | minordev = tty->index; |
950 | brdnr = MINOR2BRD(minordev); | 694 | brdnr = MINOR2BRD(minordev); |
951 | if (brdnr >= stl_nrbrds) | 695 | if (brdnr >= stl_nrbrds) |
952 | return -ENODEV; | 696 | return -ENODEV; |
953 | brdp = stl_brds[brdnr]; | 697 | brdp = stl_brds[brdnr]; |
954 | if (brdp == (stlbrd_t *) NULL) | 698 | if (brdp == NULL) |
955 | return -ENODEV; | 699 | return -ENODEV; |
956 | minordev = MINOR2PORT(minordev); | 700 | minordev = MINOR2PORT(minordev); |
957 | for (portnr = -1, panelnr = 0; (panelnr < STL_MAXPANELS); panelnr++) { | 701 | for (portnr = -1, panelnr = 0; panelnr < STL_MAXPANELS; panelnr++) { |
958 | if (brdp->panels[panelnr] == (stlpanel_t *) NULL) | 702 | if (brdp->panels[panelnr] == NULL) |
959 | break; | 703 | break; |
960 | if (minordev < brdp->panels[panelnr]->nrports) { | 704 | if (minordev < brdp->panels[panelnr]->nrports) { |
961 | portnr = minordev; | 705 | portnr = minordev; |
@@ -967,7 +711,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
967 | return -ENODEV; | 711 | return -ENODEV; |
968 | 712 | ||
969 | portp = brdp->panels[panelnr]->ports[portnr]; | 713 | portp = brdp->panels[panelnr]->ports[portnr]; |
970 | if (portp == (stlport_t *) NULL) | 714 | if (portp == NULL) |
971 | return -ENODEV; | 715 | return -ENODEV; |
972 | 716 | ||
973 | /* | 717 | /* |
@@ -1013,10 +757,10 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
1013 | * previous opens still in effect. If we are a normal serial device | 757 | * previous opens still in effect. If we are a normal serial device |
1014 | * then also we might have to wait for carrier. | 758 | * then also we might have to wait for carrier. |
1015 | */ | 759 | */ |
1016 | if (!(filp->f_flags & O_NONBLOCK)) { | 760 | if (!(filp->f_flags & O_NONBLOCK)) |
1017 | if ((rc = stl_waitcarrier(portp, filp)) != 0) | 761 | if ((rc = stl_waitcarrier(portp, filp)) != 0) |
1018 | return rc; | 762 | return rc; |
1019 | } | 763 | |
1020 | portp->flags |= ASYNC_NORMAL_ACTIVE; | 764 | portp->flags |= ASYNC_NORMAL_ACTIVE; |
1021 | 765 | ||
1022 | return 0; | 766 | return 0; |
@@ -1029,14 +773,12 @@ static int stl_open(struct tty_struct *tty, struct file *filp) | |||
1029 | * maybe because if we are clocal then we don't need to wait... | 773 | * maybe because if we are clocal then we don't need to wait... |
1030 | */ | 774 | */ |
1031 | 775 | ||
1032 | static int stl_waitcarrier(stlport_t *portp, struct file *filp) | 776 | static int stl_waitcarrier(struct stlport *portp, struct file *filp) |
1033 | { | 777 | { |
1034 | unsigned long flags; | 778 | unsigned long flags; |
1035 | int rc, doclocal; | 779 | int rc, doclocal; |
1036 | 780 | ||
1037 | #ifdef DEBUG | 781 | pr_debug("stl_waitcarrier(portp=%p,filp=%p)\n", portp, filp); |
1038 | printk("stl_waitcarrier(portp=%x,filp=%x)\n", (int) portp, (int) filp); | ||
1039 | #endif | ||
1040 | 782 | ||
1041 | rc = 0; | 783 | rc = 0; |
1042 | doclocal = 0; | 784 | doclocal = 0; |
@@ -1062,9 +804,8 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1062 | break; | 804 | break; |
1063 | } | 805 | } |
1064 | if (((portp->flags & ASYNC_CLOSING) == 0) && | 806 | if (((portp->flags & ASYNC_CLOSING) == 0) && |
1065 | (doclocal || (portp->sigs & TIOCM_CD))) { | 807 | (doclocal || (portp->sigs & TIOCM_CD))) |
1066 | break; | 808 | break; |
1067 | } | ||
1068 | if (signal_pending(current)) { | 809 | if (signal_pending(current)) { |
1069 | rc = -ERESTARTSYS; | 810 | rc = -ERESTARTSYS; |
1070 | break; | 811 | break; |
@@ -1083,17 +824,61 @@ static int stl_waitcarrier(stlport_t *portp, struct file *filp) | |||
1083 | 824 | ||
1084 | /*****************************************************************************/ | 825 | /*****************************************************************************/ |
1085 | 826 | ||
827 | static void stl_flushbuffer(struct tty_struct *tty) | ||
828 | { | ||
829 | struct stlport *portp; | ||
830 | |||
831 | pr_debug("stl_flushbuffer(tty=%p)\n", tty); | ||
832 | |||
833 | if (tty == NULL) | ||
834 | return; | ||
835 | portp = tty->driver_data; | ||
836 | if (portp == NULL) | ||
837 | return; | ||
838 | |||
839 | stl_flush(portp); | ||
840 | tty_wakeup(tty); | ||
841 | } | ||
842 | |||
843 | /*****************************************************************************/ | ||
844 | |||
845 | static void stl_waituntilsent(struct tty_struct *tty, int timeout) | ||
846 | { | ||
847 | struct stlport *portp; | ||
848 | unsigned long tend; | ||
849 | |||
850 | pr_debug("stl_waituntilsent(tty=%p,timeout=%d)\n", tty, timeout); | ||
851 | |||
852 | if (tty == NULL) | ||
853 | return; | ||
854 | portp = tty->driver_data; | ||
855 | if (portp == NULL) | ||
856 | return; | ||
857 | |||
858 | if (timeout == 0) | ||
859 | timeout = HZ; | ||
860 | tend = jiffies + timeout; | ||
861 | |||
862 | while (stl_datastate(portp)) { | ||
863 | if (signal_pending(current)) | ||
864 | break; | ||
865 | msleep_interruptible(20); | ||
866 | if (time_after_eq(jiffies, tend)) | ||
867 | break; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | /*****************************************************************************/ | ||
872 | |||
1086 | static void stl_close(struct tty_struct *tty, struct file *filp) | 873 | static void stl_close(struct tty_struct *tty, struct file *filp) |
1087 | { | 874 | { |
1088 | stlport_t *portp; | 875 | struct stlport *portp; |
1089 | unsigned long flags; | 876 | unsigned long flags; |
1090 | 877 | ||
1091 | #ifdef DEBUG | 878 | pr_debug("stl_close(tty=%p,filp=%p)\n", tty, filp); |
1092 | printk("stl_close(tty=%x,filp=%x)\n", (int) tty, (int) filp); | ||
1093 | #endif | ||
1094 | 879 | ||
1095 | portp = tty->driver_data; | 880 | portp = tty->driver_data; |
1096 | if (portp == (stlport_t *) NULL) | 881 | if (portp == NULL) |
1097 | return; | 882 | return; |
1098 | 883 | ||
1099 | spin_lock_irqsave(&stallion_lock, flags); | 884 | spin_lock_irqsave(&stallion_lock, flags); |
@@ -1136,17 +921,17 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1136 | stl_enablerxtx(portp, 0, 0); | 921 | stl_enablerxtx(portp, 0, 0); |
1137 | stl_flushbuffer(tty); | 922 | stl_flushbuffer(tty); |
1138 | portp->istate = 0; | 923 | portp->istate = 0; |
1139 | if (portp->tx.buf != (char *) NULL) { | 924 | if (portp->tx.buf != NULL) { |
1140 | kfree(portp->tx.buf); | 925 | kfree(portp->tx.buf); |
1141 | portp->tx.buf = (char *) NULL; | 926 | portp->tx.buf = NULL; |
1142 | portp->tx.head = (char *) NULL; | 927 | portp->tx.head = NULL; |
1143 | portp->tx.tail = (char *) NULL; | 928 | portp->tx.tail = NULL; |
1144 | } | 929 | } |
1145 | set_bit(TTY_IO_ERROR, &tty->flags); | 930 | set_bit(TTY_IO_ERROR, &tty->flags); |
1146 | tty_ldisc_flush(tty); | 931 | tty_ldisc_flush(tty); |
1147 | 932 | ||
1148 | tty->closing = 0; | 933 | tty->closing = 0; |
1149 | portp->tty = (struct tty_struct *) NULL; | 934 | portp->tty = NULL; |
1150 | 935 | ||
1151 | if (portp->openwaitcnt) { | 936 | if (portp->openwaitcnt) { |
1152 | if (portp->close_delay) | 937 | if (portp->close_delay) |
@@ -1167,20 +952,17 @@ static void stl_close(struct tty_struct *tty, struct file *filp) | |||
1167 | 952 | ||
1168 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count) | 953 | static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count) |
1169 | { | 954 | { |
1170 | stlport_t *portp; | 955 | struct stlport *portp; |
1171 | unsigned int len, stlen; | 956 | unsigned int len, stlen; |
1172 | unsigned char *chbuf; | 957 | unsigned char *chbuf; |
1173 | char *head, *tail; | 958 | char *head, *tail; |
1174 | 959 | ||
1175 | #ifdef DEBUG | 960 | pr_debug("stl_write(tty=%p,buf=%p,count=%d)\n", tty, buf, count); |
1176 | printk("stl_write(tty=%x,buf=%x,count=%d)\n", | ||
1177 | (int) tty, (int) buf, count); | ||
1178 | #endif | ||
1179 | 961 | ||
1180 | portp = tty->driver_data; | 962 | portp = tty->driver_data; |
1181 | if (portp == (stlport_t *) NULL) | 963 | if (portp == NULL) |
1182 | return 0; | 964 | return 0; |
1183 | if (portp->tx.buf == (char *) NULL) | 965 | if (portp->tx.buf == NULL) |
1184 | return 0; | 966 | return 0; |
1185 | 967 | ||
1186 | /* | 968 | /* |
@@ -1201,10 +983,10 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
1201 | stlen = len; | 983 | stlen = len; |
1202 | } | 984 | } |
1203 | 985 | ||
1204 | len = MIN(len, count); | 986 | len = min(len, (unsigned int)count); |
1205 | count = 0; | 987 | count = 0; |
1206 | while (len > 0) { | 988 | while (len > 0) { |
1207 | stlen = MIN(len, stlen); | 989 | stlen = min(len, stlen); |
1208 | memcpy(head, chbuf, stlen); | 990 | memcpy(head, chbuf, stlen); |
1209 | len -= stlen; | 991 | len -= stlen; |
1210 | chbuf += stlen; | 992 | chbuf += stlen; |
@@ -1227,20 +1009,18 @@ static int stl_write(struct tty_struct *tty, const unsigned char *buf, int count | |||
1227 | 1009 | ||
1228 | static void stl_putchar(struct tty_struct *tty, unsigned char ch) | 1010 | static void stl_putchar(struct tty_struct *tty, unsigned char ch) |
1229 | { | 1011 | { |
1230 | stlport_t *portp; | 1012 | struct stlport *portp; |
1231 | unsigned int len; | 1013 | unsigned int len; |
1232 | char *head, *tail; | 1014 | char *head, *tail; |
1233 | 1015 | ||
1234 | #ifdef DEBUG | 1016 | pr_debug("stl_putchar(tty=%p,ch=%x)\n", tty, ch); |
1235 | printk("stl_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch); | ||
1236 | #endif | ||
1237 | 1017 | ||
1238 | if (tty == (struct tty_struct *) NULL) | 1018 | if (tty == NULL) |
1239 | return; | 1019 | return; |
1240 | portp = tty->driver_data; | 1020 | portp = tty->driver_data; |
1241 | if (portp == (stlport_t *) NULL) | 1021 | if (portp == NULL) |
1242 | return; | 1022 | return; |
1243 | if (portp->tx.buf == (char *) NULL) | 1023 | if (portp->tx.buf == NULL) |
1244 | return; | 1024 | return; |
1245 | 1025 | ||
1246 | head = portp->tx.head; | 1026 | head = portp->tx.head; |
@@ -1267,18 +1047,16 @@ static void stl_putchar(struct tty_struct *tty, unsigned char ch) | |||
1267 | 1047 | ||
1268 | static void stl_flushchars(struct tty_struct *tty) | 1048 | static void stl_flushchars(struct tty_struct *tty) |
1269 | { | 1049 | { |
1270 | stlport_t *portp; | 1050 | struct stlport *portp; |
1271 | 1051 | ||
1272 | #ifdef DEBUG | 1052 | pr_debug("stl_flushchars(tty=%p)\n", tty); |
1273 | printk("stl_flushchars(tty=%x)\n", (int) tty); | ||
1274 | #endif | ||
1275 | 1053 | ||
1276 | if (tty == (struct tty_struct *) NULL) | 1054 | if (tty == NULL) |
1277 | return; | 1055 | return; |
1278 | portp = tty->driver_data; | 1056 | portp = tty->driver_data; |
1279 | if (portp == (stlport_t *) NULL) | 1057 | if (portp == NULL) |
1280 | return; | 1058 | return; |
1281 | if (portp->tx.buf == (char *) NULL) | 1059 | if (portp->tx.buf == NULL) |
1282 | return; | 1060 | return; |
1283 | 1061 | ||
1284 | stl_startrxtx(portp, -1, 1); | 1062 | stl_startrxtx(portp, -1, 1); |
@@ -1288,24 +1066,22 @@ static void stl_flushchars(struct tty_struct *tty) | |||
1288 | 1066 | ||
1289 | static int stl_writeroom(struct tty_struct *tty) | 1067 | static int stl_writeroom(struct tty_struct *tty) |
1290 | { | 1068 | { |
1291 | stlport_t *portp; | 1069 | struct stlport *portp; |
1292 | char *head, *tail; | 1070 | char *head, *tail; |
1293 | 1071 | ||
1294 | #ifdef DEBUG | 1072 | pr_debug("stl_writeroom(tty=%p)\n", tty); |
1295 | printk("stl_writeroom(tty=%x)\n", (int) tty); | ||
1296 | #endif | ||
1297 | 1073 | ||
1298 | if (tty == (struct tty_struct *) NULL) | 1074 | if (tty == NULL) |
1299 | return 0; | 1075 | return 0; |
1300 | portp = tty->driver_data; | 1076 | portp = tty->driver_data; |
1301 | if (portp == (stlport_t *) NULL) | 1077 | if (portp == NULL) |
1302 | return 0; | 1078 | return 0; |
1303 | if (portp->tx.buf == (char *) NULL) | 1079 | if (portp->tx.buf == NULL) |
1304 | return 0; | 1080 | return 0; |
1305 | 1081 | ||
1306 | head = portp->tx.head; | 1082 | head = portp->tx.head; |
1307 | tail = portp->tx.tail; | 1083 | tail = portp->tx.tail; |
1308 | return ((head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1)); | 1084 | return (head >= tail) ? (STL_TXBUFSIZE - (head - tail) - 1) : (tail - head - 1); |
1309 | } | 1085 | } |
1310 | 1086 | ||
1311 | /*****************************************************************************/ | 1087 | /*****************************************************************************/ |
@@ -1321,20 +1097,18 @@ static int stl_writeroom(struct tty_struct *tty) | |||
1321 | 1097 | ||
1322 | static int stl_charsinbuffer(struct tty_struct *tty) | 1098 | static int stl_charsinbuffer(struct tty_struct *tty) |
1323 | { | 1099 | { |
1324 | stlport_t *portp; | 1100 | struct stlport *portp; |
1325 | unsigned int size; | 1101 | unsigned int size; |
1326 | char *head, *tail; | 1102 | char *head, *tail; |
1327 | 1103 | ||
1328 | #ifdef DEBUG | 1104 | pr_debug("stl_charsinbuffer(tty=%p)\n", tty); |
1329 | printk("stl_charsinbuffer(tty=%x)\n", (int) tty); | ||
1330 | #endif | ||
1331 | 1105 | ||
1332 | if (tty == (struct tty_struct *) NULL) | 1106 | if (tty == NULL) |
1333 | return 0; | 1107 | return 0; |
1334 | portp = tty->driver_data; | 1108 | portp = tty->driver_data; |
1335 | if (portp == (stlport_t *) NULL) | 1109 | if (portp == NULL) |
1336 | return 0; | 1110 | return 0; |
1337 | if (portp->tx.buf == (char *) NULL) | 1111 | if (portp->tx.buf == NULL) |
1338 | return 0; | 1112 | return 0; |
1339 | 1113 | ||
1340 | head = portp->tx.head; | 1114 | head = portp->tx.head; |
@@ -1351,14 +1125,12 @@ static int stl_charsinbuffer(struct tty_struct *tty) | |||
1351 | * Generate the serial struct info. | 1125 | * Generate the serial struct info. |
1352 | */ | 1126 | */ |
1353 | 1127 | ||
1354 | static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp) | 1128 | static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp) |
1355 | { | 1129 | { |
1356 | struct serial_struct sio; | 1130 | struct serial_struct sio; |
1357 | stlbrd_t *brdp; | 1131 | struct stlbrd *brdp; |
1358 | 1132 | ||
1359 | #ifdef DEBUG | 1133 | pr_debug("stl_getserial(portp=%p,sp=%p)\n", portp, sp); |
1360 | printk("stl_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); | ||
1361 | #endif | ||
1362 | 1134 | ||
1363 | memset(&sio, 0, sizeof(struct serial_struct)); | 1135 | memset(&sio, 0, sizeof(struct serial_struct)); |
1364 | sio.line = portp->portnr; | 1136 | sio.line = portp->portnr; |
@@ -1378,7 +1150,7 @@ static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp) | |||
1378 | } | 1150 | } |
1379 | 1151 | ||
1380 | brdp = stl_brds[portp->brdnr]; | 1152 | brdp = stl_brds[portp->brdnr]; |
1381 | if (brdp != (stlbrd_t *) NULL) | 1153 | if (brdp != NULL) |
1382 | sio.irq = brdp->irq; | 1154 | sio.irq = brdp->irq; |
1383 | 1155 | ||
1384 | return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; | 1156 | return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? -EFAULT : 0; |
@@ -1392,13 +1164,11 @@ static int stl_getserial(stlport_t *portp, struct serial_struct __user *sp) | |||
1392 | * just quietly ignore any requests to change irq, etc. | 1164 | * just quietly ignore any requests to change irq, etc. |
1393 | */ | 1165 | */ |
1394 | 1166 | ||
1395 | static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp) | 1167 | static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp) |
1396 | { | 1168 | { |
1397 | struct serial_struct sio; | 1169 | struct serial_struct sio; |
1398 | 1170 | ||
1399 | #ifdef DEBUG | 1171 | pr_debug("stl_setserial(portp=%p,sp=%p)\n", portp, sp); |
1400 | printk("stl_setserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); | ||
1401 | #endif | ||
1402 | 1172 | ||
1403 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) | 1173 | if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) |
1404 | return -EFAULT; | 1174 | return -EFAULT; |
@@ -1424,12 +1194,12 @@ static int stl_setserial(stlport_t *portp, struct serial_struct __user *sp) | |||
1424 | 1194 | ||
1425 | static int stl_tiocmget(struct tty_struct *tty, struct file *file) | 1195 | static int stl_tiocmget(struct tty_struct *tty, struct file *file) |
1426 | { | 1196 | { |
1427 | stlport_t *portp; | 1197 | struct stlport *portp; |
1428 | 1198 | ||
1429 | if (tty == (struct tty_struct *) NULL) | 1199 | if (tty == NULL) |
1430 | return -ENODEV; | 1200 | return -ENODEV; |
1431 | portp = tty->driver_data; | 1201 | portp = tty->driver_data; |
1432 | if (portp == (stlport_t *) NULL) | 1202 | if (portp == NULL) |
1433 | return -ENODEV; | 1203 | return -ENODEV; |
1434 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1204 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1435 | return -EIO; | 1205 | return -EIO; |
@@ -1440,13 +1210,13 @@ static int stl_tiocmget(struct tty_struct *tty, struct file *file) | |||
1440 | static int stl_tiocmset(struct tty_struct *tty, struct file *file, | 1210 | static int stl_tiocmset(struct tty_struct *tty, struct file *file, |
1441 | unsigned int set, unsigned int clear) | 1211 | unsigned int set, unsigned int clear) |
1442 | { | 1212 | { |
1443 | stlport_t *portp; | 1213 | struct stlport *portp; |
1444 | int rts = -1, dtr = -1; | 1214 | int rts = -1, dtr = -1; |
1445 | 1215 | ||
1446 | if (tty == (struct tty_struct *) NULL) | 1216 | if (tty == NULL) |
1447 | return -ENODEV; | 1217 | return -ENODEV; |
1448 | portp = tty->driver_data; | 1218 | portp = tty->driver_data; |
1449 | if (portp == (stlport_t *) NULL) | 1219 | if (portp == NULL) |
1450 | return -ENODEV; | 1220 | return -ENODEV; |
1451 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1221 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1452 | return -EIO; | 1222 | return -EIO; |
@@ -1466,27 +1236,24 @@ static int stl_tiocmset(struct tty_struct *tty, struct file *file, | |||
1466 | 1236 | ||
1467 | static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) | 1237 | static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) |
1468 | { | 1238 | { |
1469 | stlport_t *portp; | 1239 | struct stlport *portp; |
1470 | unsigned int ival; | 1240 | unsigned int ival; |
1471 | int rc; | 1241 | int rc; |
1472 | void __user *argp = (void __user *)arg; | 1242 | void __user *argp = (void __user *)arg; |
1473 | 1243 | ||
1474 | #ifdef DEBUG | 1244 | pr_debug("stl_ioctl(tty=%p,file=%p,cmd=%x,arg=%lx)\n", tty, file, cmd, |
1475 | printk("stl_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", | 1245 | arg); |
1476 | (int) tty, (int) file, cmd, (int) arg); | ||
1477 | #endif | ||
1478 | 1246 | ||
1479 | if (tty == (struct tty_struct *) NULL) | 1247 | if (tty == NULL) |
1480 | return -ENODEV; | 1248 | return -ENODEV; |
1481 | portp = tty->driver_data; | 1249 | portp = tty->driver_data; |
1482 | if (portp == (stlport_t *) NULL) | 1250 | if (portp == NULL) |
1483 | return -ENODEV; | 1251 | return -ENODEV; |
1484 | 1252 | ||
1485 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && | 1253 | if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && |
1486 | (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { | 1254 | (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) |
1487 | if (tty->flags & (1 << TTY_IO_ERROR)) | 1255 | if (tty->flags & (1 << TTY_IO_ERROR)) |
1488 | return -EIO; | 1256 | return -EIO; |
1489 | } | ||
1490 | 1257 | ||
1491 | rc = 0; | 1258 | rc = 0; |
1492 | 1259 | ||
@@ -1531,19 +1298,37 @@ static int stl_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd | |||
1531 | 1298 | ||
1532 | /*****************************************************************************/ | 1299 | /*****************************************************************************/ |
1533 | 1300 | ||
1534 | static void stl_settermios(struct tty_struct *tty, struct termios *old) | 1301 | /* |
1302 | * Start the transmitter again. Just turn TX interrupts back on. | ||
1303 | */ | ||
1304 | |||
1305 | static void stl_start(struct tty_struct *tty) | ||
1535 | { | 1306 | { |
1536 | stlport_t *portp; | 1307 | struct stlport *portp; |
1537 | struct termios *tiosp; | ||
1538 | 1308 | ||
1539 | #ifdef DEBUG | 1309 | pr_debug("stl_start(tty=%p)\n", tty); |
1540 | printk("stl_settermios(tty=%x,old=%x)\n", (int) tty, (int) old); | ||
1541 | #endif | ||
1542 | 1310 | ||
1543 | if (tty == (struct tty_struct *) NULL) | 1311 | if (tty == NULL) |
1544 | return; | 1312 | return; |
1545 | portp = tty->driver_data; | 1313 | portp = tty->driver_data; |
1546 | if (portp == (stlport_t *) NULL) | 1314 | if (portp == NULL) |
1315 | return; | ||
1316 | stl_startrxtx(portp, -1, 1); | ||
1317 | } | ||
1318 | |||
1319 | /*****************************************************************************/ | ||
1320 | |||
1321 | static void stl_settermios(struct tty_struct *tty, struct ktermios *old) | ||
1322 | { | ||
1323 | struct stlport *portp; | ||
1324 | struct ktermios *tiosp; | ||
1325 | |||
1326 | pr_debug("stl_settermios(tty=%p,old=%p)\n", tty, old); | ||
1327 | |||
1328 | if (tty == NULL) | ||
1329 | return; | ||
1330 | portp = tty->driver_data; | ||
1331 | if (portp == NULL) | ||
1547 | return; | 1332 | return; |
1548 | 1333 | ||
1549 | tiosp = tty->termios; | 1334 | tiosp = tty->termios; |
@@ -1571,16 +1356,14 @@ static void stl_settermios(struct tty_struct *tty, struct termios *old) | |||
1571 | 1356 | ||
1572 | static void stl_throttle(struct tty_struct *tty) | 1357 | static void stl_throttle(struct tty_struct *tty) |
1573 | { | 1358 | { |
1574 | stlport_t *portp; | 1359 | struct stlport *portp; |
1575 | 1360 | ||
1576 | #ifdef DEBUG | 1361 | pr_debug("stl_throttle(tty=%p)\n", tty); |
1577 | printk("stl_throttle(tty=%x)\n", (int) tty); | ||
1578 | #endif | ||
1579 | 1362 | ||
1580 | if (tty == (struct tty_struct *) NULL) | 1363 | if (tty == NULL) |
1581 | return; | 1364 | return; |
1582 | portp = tty->driver_data; | 1365 | portp = tty->driver_data; |
1583 | if (portp == (stlport_t *) NULL) | 1366 | if (portp == NULL) |
1584 | return; | 1367 | return; |
1585 | stl_flowctrl(portp, 0); | 1368 | stl_flowctrl(portp, 0); |
1586 | } | 1369 | } |
@@ -1593,16 +1376,14 @@ static void stl_throttle(struct tty_struct *tty) | |||
1593 | 1376 | ||
1594 | static void stl_unthrottle(struct tty_struct *tty) | 1377 | static void stl_unthrottle(struct tty_struct *tty) |
1595 | { | 1378 | { |
1596 | stlport_t *portp; | 1379 | struct stlport *portp; |
1597 | 1380 | ||
1598 | #ifdef DEBUG | 1381 | pr_debug("stl_unthrottle(tty=%p)\n", tty); |
1599 | printk("stl_unthrottle(tty=%x)\n", (int) tty); | ||
1600 | #endif | ||
1601 | 1382 | ||
1602 | if (tty == (struct tty_struct *) NULL) | 1383 | if (tty == NULL) |
1603 | return; | 1384 | return; |
1604 | portp = tty->driver_data; | 1385 | portp = tty->driver_data; |
1605 | if (portp == (stlport_t *) NULL) | 1386 | if (portp == NULL) |
1606 | return; | 1387 | return; |
1607 | stl_flowctrl(portp, 1); | 1388 | stl_flowctrl(portp, 1); |
1608 | } | 1389 | } |
@@ -1616,16 +1397,14 @@ static void stl_unthrottle(struct tty_struct *tty) | |||
1616 | 1397 | ||
1617 | static void stl_stop(struct tty_struct *tty) | 1398 | static void stl_stop(struct tty_struct *tty) |
1618 | { | 1399 | { |
1619 | stlport_t *portp; | 1400 | struct stlport *portp; |
1620 | 1401 | ||
1621 | #ifdef DEBUG | 1402 | pr_debug("stl_stop(tty=%p)\n", tty); |
1622 | printk("stl_stop(tty=%x)\n", (int) tty); | ||
1623 | #endif | ||
1624 | 1403 | ||
1625 | if (tty == (struct tty_struct *) NULL) | 1404 | if (tty == NULL) |
1626 | return; | 1405 | return; |
1627 | portp = tty->driver_data; | 1406 | portp = tty->driver_data; |
1628 | if (portp == (stlport_t *) NULL) | 1407 | if (portp == NULL) |
1629 | return; | 1408 | return; |
1630 | stl_startrxtx(portp, -1, 0); | 1409 | stl_startrxtx(portp, -1, 0); |
1631 | } | 1410 | } |
@@ -1633,28 +1412,6 @@ static void stl_stop(struct tty_struct *tty) | |||
1633 | /*****************************************************************************/ | 1412 | /*****************************************************************************/ |
1634 | 1413 | ||
1635 | /* | 1414 | /* |
1636 | * Start the transmitter again. Just turn TX interrupts back on. | ||
1637 | */ | ||
1638 | |||
1639 | static void stl_start(struct tty_struct *tty) | ||
1640 | { | ||
1641 | stlport_t *portp; | ||
1642 | |||
1643 | #ifdef DEBUG | ||
1644 | printk("stl_start(tty=%x)\n", (int) tty); | ||
1645 | #endif | ||
1646 | |||
1647 | if (tty == (struct tty_struct *) NULL) | ||
1648 | return; | ||
1649 | portp = tty->driver_data; | ||
1650 | if (portp == (stlport_t *) NULL) | ||
1651 | return; | ||
1652 | stl_startrxtx(portp, -1, 1); | ||
1653 | } | ||
1654 | |||
1655 | /*****************************************************************************/ | ||
1656 | |||
1657 | /* | ||
1658 | * Hangup this port. This is pretty much like closing the port, only | 1415 | * Hangup this port. This is pretty much like closing the port, only |
1659 | * a little more brutal. No waiting for data to drain. Shutdown the | 1416 | * a little more brutal. No waiting for data to drain. Shutdown the |
1660 | * port and maybe drop signals. | 1417 | * port and maybe drop signals. |
@@ -1662,16 +1419,14 @@ static void stl_start(struct tty_struct *tty) | |||
1662 | 1419 | ||
1663 | static void stl_hangup(struct tty_struct *tty) | 1420 | static void stl_hangup(struct tty_struct *tty) |
1664 | { | 1421 | { |
1665 | stlport_t *portp; | 1422 | struct stlport *portp; |
1666 | 1423 | ||
1667 | #ifdef DEBUG | 1424 | pr_debug("stl_hangup(tty=%p)\n", tty); |
1668 | printk("stl_hangup(tty=%x)\n", (int) tty); | ||
1669 | #endif | ||
1670 | 1425 | ||
1671 | if (tty == (struct tty_struct *) NULL) | 1426 | if (tty == NULL) |
1672 | return; | 1427 | return; |
1673 | portp = tty->driver_data; | 1428 | portp = tty->driver_data; |
1674 | if (portp == (stlport_t *) NULL) | 1429 | if (portp == NULL) |
1675 | return; | 1430 | return; |
1676 | 1431 | ||
1677 | portp->flags &= ~ASYNC_INITIALIZED; | 1432 | portp->flags &= ~ASYNC_INITIALIZED; |
@@ -1682,13 +1437,13 @@ static void stl_hangup(struct tty_struct *tty) | |||
1682 | stl_flushbuffer(tty); | 1437 | stl_flushbuffer(tty); |
1683 | portp->istate = 0; | 1438 | portp->istate = 0; |
1684 | set_bit(TTY_IO_ERROR, &tty->flags); | 1439 | set_bit(TTY_IO_ERROR, &tty->flags); |
1685 | if (portp->tx.buf != (char *) NULL) { | 1440 | if (portp->tx.buf != NULL) { |
1686 | kfree(portp->tx.buf); | 1441 | kfree(portp->tx.buf); |
1687 | portp->tx.buf = (char *) NULL; | 1442 | portp->tx.buf = NULL; |
1688 | portp->tx.head = (char *) NULL; | 1443 | portp->tx.head = NULL; |
1689 | portp->tx.tail = (char *) NULL; | 1444 | portp->tx.tail = NULL; |
1690 | } | 1445 | } |
1691 | portp->tty = (struct tty_struct *) NULL; | 1446 | portp->tty = NULL; |
1692 | portp->flags &= ~ASYNC_NORMAL_ACTIVE; | 1447 | portp->flags &= ~ASYNC_NORMAL_ACTIVE; |
1693 | portp->refcount = 0; | 1448 | portp->refcount = 0; |
1694 | wake_up_interruptible(&portp->open_wait); | 1449 | wake_up_interruptible(&portp->open_wait); |
@@ -1696,38 +1451,16 @@ static void stl_hangup(struct tty_struct *tty) | |||
1696 | 1451 | ||
1697 | /*****************************************************************************/ | 1452 | /*****************************************************************************/ |
1698 | 1453 | ||
1699 | static void stl_flushbuffer(struct tty_struct *tty) | ||
1700 | { | ||
1701 | stlport_t *portp; | ||
1702 | |||
1703 | #ifdef DEBUG | ||
1704 | printk("stl_flushbuffer(tty=%x)\n", (int) tty); | ||
1705 | #endif | ||
1706 | |||
1707 | if (tty == (struct tty_struct *) NULL) | ||
1708 | return; | ||
1709 | portp = tty->driver_data; | ||
1710 | if (portp == (stlport_t *) NULL) | ||
1711 | return; | ||
1712 | |||
1713 | stl_flush(portp); | ||
1714 | tty_wakeup(tty); | ||
1715 | } | ||
1716 | |||
1717 | /*****************************************************************************/ | ||
1718 | |||
1719 | static void stl_breakctl(struct tty_struct *tty, int state) | 1454 | static void stl_breakctl(struct tty_struct *tty, int state) |
1720 | { | 1455 | { |
1721 | stlport_t *portp; | 1456 | struct stlport *portp; |
1722 | 1457 | ||
1723 | #ifdef DEBUG | 1458 | pr_debug("stl_breakctl(tty=%p,state=%d)\n", tty, state); |
1724 | printk("stl_breakctl(tty=%x,state=%d)\n", (int) tty, state); | ||
1725 | #endif | ||
1726 | 1459 | ||
1727 | if (tty == (struct tty_struct *) NULL) | 1460 | if (tty == NULL) |
1728 | return; | 1461 | return; |
1729 | portp = tty->driver_data; | 1462 | portp = tty->driver_data; |
1730 | if (portp == (stlport_t *) NULL) | 1463 | if (portp == NULL) |
1731 | return; | 1464 | return; |
1732 | 1465 | ||
1733 | stl_sendbreak(portp, ((state == -1) ? 1 : 2)); | 1466 | stl_sendbreak(portp, ((state == -1) ? 1 : 2)); |
@@ -1735,48 +1468,16 @@ static void stl_breakctl(struct tty_struct *tty, int state) | |||
1735 | 1468 | ||
1736 | /*****************************************************************************/ | 1469 | /*****************************************************************************/ |
1737 | 1470 | ||
1738 | static void stl_waituntilsent(struct tty_struct *tty, int timeout) | ||
1739 | { | ||
1740 | stlport_t *portp; | ||
1741 | unsigned long tend; | ||
1742 | |||
1743 | #ifdef DEBUG | ||
1744 | printk("stl_waituntilsent(tty=%x,timeout=%d)\n", (int) tty, timeout); | ||
1745 | #endif | ||
1746 | |||
1747 | if (tty == (struct tty_struct *) NULL) | ||
1748 | return; | ||
1749 | portp = tty->driver_data; | ||
1750 | if (portp == (stlport_t *) NULL) | ||
1751 | return; | ||
1752 | |||
1753 | if (timeout == 0) | ||
1754 | timeout = HZ; | ||
1755 | tend = jiffies + timeout; | ||
1756 | |||
1757 | while (stl_datastate(portp)) { | ||
1758 | if (signal_pending(current)) | ||
1759 | break; | ||
1760 | msleep_interruptible(20); | ||
1761 | if (time_after_eq(jiffies, tend)) | ||
1762 | break; | ||
1763 | } | ||
1764 | } | ||
1765 | |||
1766 | /*****************************************************************************/ | ||
1767 | |||
1768 | static void stl_sendxchar(struct tty_struct *tty, char ch) | 1471 | static void stl_sendxchar(struct tty_struct *tty, char ch) |
1769 | { | 1472 | { |
1770 | stlport_t *portp; | 1473 | struct stlport *portp; |
1771 | 1474 | ||
1772 | #ifdef DEBUG | 1475 | pr_debug("stl_sendxchar(tty=%p,ch=%x)\n", tty, ch); |
1773 | printk("stl_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch); | ||
1774 | #endif | ||
1775 | 1476 | ||
1776 | if (tty == (struct tty_struct *) NULL) | 1477 | if (tty == NULL) |
1777 | return; | 1478 | return; |
1778 | portp = tty->driver_data; | 1479 | portp = tty->driver_data; |
1779 | if (portp == (stlport_t *) NULL) | 1480 | if (portp == NULL) |
1780 | return; | 1481 | return; |
1781 | 1482 | ||
1782 | if (ch == STOP_CHAR(tty)) | 1483 | if (ch == STOP_CHAR(tty)) |
@@ -1797,7 +1498,7 @@ static void stl_sendxchar(struct tty_struct *tty, char ch) | |||
1797 | * short then padded with spaces). | 1498 | * short then padded with spaces). |
1798 | */ | 1499 | */ |
1799 | 1500 | ||
1800 | static int stl_portinfo(stlport_t *portp, int portnr, char *pos) | 1501 | static int stl_portinfo(struct stlport *portp, int portnr, char *pos) |
1801 | { | 1502 | { |
1802 | char *sp; | 1503 | char *sp; |
1803 | int sigs, cnt; | 1504 | int sigs, cnt; |
@@ -1826,7 +1527,7 @@ static int stl_portinfo(stlport_t *portp, int portnr, char *pos) | |||
1826 | *sp = ' '; | 1527 | *sp = ' '; |
1827 | sp += cnt; | 1528 | sp += cnt; |
1828 | 1529 | ||
1829 | for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++) | 1530 | for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++) |
1830 | *sp++ = ' '; | 1531 | *sp++ = ' '; |
1831 | if (cnt >= MAXLINE) | 1532 | if (cnt >= MAXLINE) |
1832 | pos[(MAXLINE - 2)] = '+'; | 1533 | pos[(MAXLINE - 2)] = '+'; |
@@ -1843,18 +1544,15 @@ static int stl_portinfo(stlport_t *portp, int portnr, char *pos) | |||
1843 | 1544 | ||
1844 | static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) | 1545 | static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) |
1845 | { | 1546 | { |
1846 | stlbrd_t *brdp; | 1547 | struct stlbrd *brdp; |
1847 | stlpanel_t *panelp; | 1548 | struct stlpanel *panelp; |
1848 | stlport_t *portp; | 1549 | struct stlport *portp; |
1849 | int brdnr, panelnr, portnr, totalport; | 1550 | unsigned int brdnr, panelnr, portnr; |
1850 | int curoff, maxoff; | 1551 | int totalport, curoff, maxoff; |
1851 | char *pos; | 1552 | char *pos; |
1852 | 1553 | ||
1853 | #ifdef DEBUG | 1554 | pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p," |
1854 | printk("stl_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x," | 1555 | "data=%p\n", page, start, off, count, eof, data); |
1855 | "data=%x\n", (int) page, (int) start, (int) off, count, | ||
1856 | (int) eof, (int) data); | ||
1857 | #endif | ||
1858 | 1556 | ||
1859 | pos = page; | 1557 | pos = page; |
1860 | totalport = 0; | 1558 | totalport = 0; |
@@ -1873,9 +1571,9 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof | |||
1873 | * We scan through for each board, panel and port. The offset is | 1571 | * We scan through for each board, panel and port. The offset is |
1874 | * calculated on the fly, and irrelevant ports are skipped. | 1572 | * calculated on the fly, and irrelevant ports are skipped. |
1875 | */ | 1573 | */ |
1876 | for (brdnr = 0; (brdnr < stl_nrbrds); brdnr++) { | 1574 | for (brdnr = 0; brdnr < stl_nrbrds; brdnr++) { |
1877 | brdp = stl_brds[brdnr]; | 1575 | brdp = stl_brds[brdnr]; |
1878 | if (brdp == (stlbrd_t *) NULL) | 1576 | if (brdp == NULL) |
1879 | continue; | 1577 | continue; |
1880 | if (brdp->state == 0) | 1578 | if (brdp->state == 0) |
1881 | continue; | 1579 | continue; |
@@ -1887,9 +1585,9 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof | |||
1887 | } | 1585 | } |
1888 | 1586 | ||
1889 | totalport = brdnr * STL_MAXPORTS; | 1587 | totalport = brdnr * STL_MAXPORTS; |
1890 | for (panelnr = 0; (panelnr < brdp->nrpanels); panelnr++) { | 1588 | for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) { |
1891 | panelp = brdp->panels[panelnr]; | 1589 | panelp = brdp->panels[panelnr]; |
1892 | if (panelp == (stlpanel_t *) NULL) | 1590 | if (panelp == NULL) |
1893 | continue; | 1591 | continue; |
1894 | 1592 | ||
1895 | maxoff = curoff + (panelp->nrports * MAXLINE); | 1593 | maxoff = curoff + (panelp->nrports * MAXLINE); |
@@ -1899,10 +1597,10 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof | |||
1899 | continue; | 1597 | continue; |
1900 | } | 1598 | } |
1901 | 1599 | ||
1902 | for (portnr = 0; (portnr < panelp->nrports); portnr++, | 1600 | for (portnr = 0; portnr < panelp->nrports; portnr++, |
1903 | totalport++) { | 1601 | totalport++) { |
1904 | portp = panelp->ports[portnr]; | 1602 | portp = panelp->ports[portnr]; |
1905 | if (portp == (stlport_t *) NULL) | 1603 | if (portp == NULL) |
1906 | continue; | 1604 | continue; |
1907 | if (off >= (curoff += MAXLINE)) | 1605 | if (off >= (curoff += MAXLINE)) |
1908 | continue; | 1606 | continue; |
@@ -1917,7 +1615,7 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof | |||
1917 | 1615 | ||
1918 | stl_readdone: | 1616 | stl_readdone: |
1919 | *start = page; | 1617 | *start = page; |
1920 | return (pos - page); | 1618 | return pos - page; |
1921 | } | 1619 | } |
1922 | 1620 | ||
1923 | /*****************************************************************************/ | 1621 | /*****************************************************************************/ |
@@ -1929,11 +1627,9 @@ stl_readdone: | |||
1929 | 1627 | ||
1930 | static irqreturn_t stl_intr(int irq, void *dev_id) | 1628 | static irqreturn_t stl_intr(int irq, void *dev_id) |
1931 | { | 1629 | { |
1932 | stlbrd_t *brdp = (stlbrd_t *) dev_id; | 1630 | struct stlbrd *brdp = dev_id; |
1933 | 1631 | ||
1934 | #ifdef DEBUG | 1632 | pr_debug("stl_intr(brdp=%p,irq=%d)\n", brdp, irq); |
1935 | printk("stl_intr(brdp=%x,irq=%d)\n", (int) brdp, irq); | ||
1936 | #endif | ||
1937 | 1633 | ||
1938 | return IRQ_RETVAL((* brdp->isr)(brdp)); | 1634 | return IRQ_RETVAL((* brdp->isr)(brdp)); |
1939 | } | 1635 | } |
@@ -1944,9 +1640,9 @@ static irqreturn_t stl_intr(int irq, void *dev_id) | |||
1944 | * Interrupt service routine for EasyIO board types. | 1640 | * Interrupt service routine for EasyIO board types. |
1945 | */ | 1641 | */ |
1946 | 1642 | ||
1947 | static int stl_eiointr(stlbrd_t *brdp) | 1643 | static int stl_eiointr(struct stlbrd *brdp) |
1948 | { | 1644 | { |
1949 | stlpanel_t *panelp; | 1645 | struct stlpanel *panelp; |
1950 | unsigned int iobase; | 1646 | unsigned int iobase; |
1951 | int handled = 0; | 1647 | int handled = 0; |
1952 | 1648 | ||
@@ -1967,18 +1663,17 @@ static int stl_eiointr(stlbrd_t *brdp) | |||
1967 | * Interrupt service routine for ECH-AT board types. | 1663 | * Interrupt service routine for ECH-AT board types. |
1968 | */ | 1664 | */ |
1969 | 1665 | ||
1970 | static int stl_echatintr(stlbrd_t *brdp) | 1666 | static int stl_echatintr(struct stlbrd *brdp) |
1971 | { | 1667 | { |
1972 | stlpanel_t *panelp; | 1668 | struct stlpanel *panelp; |
1973 | unsigned int ioaddr; | 1669 | unsigned int ioaddr, bnknr; |
1974 | int bnknr; | ||
1975 | int handled = 0; | 1670 | int handled = 0; |
1976 | 1671 | ||
1977 | outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); | 1672 | outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); |
1978 | 1673 | ||
1979 | while (inb(brdp->iostatus) & ECH_INTRPEND) { | 1674 | while (inb(brdp->iostatus) & ECH_INTRPEND) { |
1980 | handled = 1; | 1675 | handled = 1; |
1981 | for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { | 1676 | for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { |
1982 | ioaddr = brdp->bnkstataddr[bnknr]; | 1677 | ioaddr = brdp->bnkstataddr[bnknr]; |
1983 | if (inb(ioaddr) & ECH_PNLINTRPEND) { | 1678 | if (inb(ioaddr) & ECH_PNLINTRPEND) { |
1984 | panelp = brdp->bnk2panel[bnknr]; | 1679 | panelp = brdp->bnk2panel[bnknr]; |
@@ -1998,16 +1693,15 @@ static int stl_echatintr(stlbrd_t *brdp) | |||
1998 | * Interrupt service routine for ECH-MCA board types. | 1693 | * Interrupt service routine for ECH-MCA board types. |
1999 | */ | 1694 | */ |
2000 | 1695 | ||
2001 | static int stl_echmcaintr(stlbrd_t *brdp) | 1696 | static int stl_echmcaintr(struct stlbrd *brdp) |
2002 | { | 1697 | { |
2003 | stlpanel_t *panelp; | 1698 | struct stlpanel *panelp; |
2004 | unsigned int ioaddr; | 1699 | unsigned int ioaddr, bnknr; |
2005 | int bnknr; | ||
2006 | int handled = 0; | 1700 | int handled = 0; |
2007 | 1701 | ||
2008 | while (inb(brdp->iostatus) & ECH_INTRPEND) { | 1702 | while (inb(brdp->iostatus) & ECH_INTRPEND) { |
2009 | handled = 1; | 1703 | handled = 1; |
2010 | for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { | 1704 | for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { |
2011 | ioaddr = brdp->bnkstataddr[bnknr]; | 1705 | ioaddr = brdp->bnkstataddr[bnknr]; |
2012 | if (inb(ioaddr) & ECH_PNLINTRPEND) { | 1706 | if (inb(ioaddr) & ECH_PNLINTRPEND) { |
2013 | panelp = brdp->bnk2panel[bnknr]; | 1707 | panelp = brdp->bnk2panel[bnknr]; |
@@ -2024,16 +1718,15 @@ static int stl_echmcaintr(stlbrd_t *brdp) | |||
2024 | * Interrupt service routine for ECH-PCI board types. | 1718 | * Interrupt service routine for ECH-PCI board types. |
2025 | */ | 1719 | */ |
2026 | 1720 | ||
2027 | static int stl_echpciintr(stlbrd_t *brdp) | 1721 | static int stl_echpciintr(struct stlbrd *brdp) |
2028 | { | 1722 | { |
2029 | stlpanel_t *panelp; | 1723 | struct stlpanel *panelp; |
2030 | unsigned int ioaddr; | 1724 | unsigned int ioaddr, bnknr, recheck; |
2031 | int bnknr, recheck; | ||
2032 | int handled = 0; | 1725 | int handled = 0; |
2033 | 1726 | ||
2034 | while (1) { | 1727 | while (1) { |
2035 | recheck = 0; | 1728 | recheck = 0; |
2036 | for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { | 1729 | for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { |
2037 | outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl); | 1730 | outb(brdp->bnkpageaddr[bnknr], brdp->ioctrl); |
2038 | ioaddr = brdp->bnkstataddr[bnknr]; | 1731 | ioaddr = brdp->bnkstataddr[bnknr]; |
2039 | if (inb(ioaddr) & ECH_PNLINTRPEND) { | 1732 | if (inb(ioaddr) & ECH_PNLINTRPEND) { |
@@ -2055,16 +1748,15 @@ static int stl_echpciintr(stlbrd_t *brdp) | |||
2055 | * Interrupt service routine for ECH-8/64-PCI board types. | 1748 | * Interrupt service routine for ECH-8/64-PCI board types. |
2056 | */ | 1749 | */ |
2057 | 1750 | ||
2058 | static int stl_echpci64intr(stlbrd_t *brdp) | 1751 | static int stl_echpci64intr(struct stlbrd *brdp) |
2059 | { | 1752 | { |
2060 | stlpanel_t *panelp; | 1753 | struct stlpanel *panelp; |
2061 | unsigned int ioaddr; | 1754 | unsigned int ioaddr, bnknr; |
2062 | int bnknr; | ||
2063 | int handled = 0; | 1755 | int handled = 0; |
2064 | 1756 | ||
2065 | while (inb(brdp->ioctrl) & 0x1) { | 1757 | while (inb(brdp->ioctrl) & 0x1) { |
2066 | handled = 1; | 1758 | handled = 1; |
2067 | for (bnknr = 0; (bnknr < brdp->nrbnks); bnknr++) { | 1759 | for (bnknr = 0; bnknr < brdp->nrbnks; bnknr++) { |
2068 | ioaddr = brdp->bnkstataddr[bnknr]; | 1760 | ioaddr = brdp->bnkstataddr[bnknr]; |
2069 | if (inb(ioaddr) & ECH_PNLINTRPEND) { | 1761 | if (inb(ioaddr) & ECH_PNLINTRPEND) { |
2070 | panelp = brdp->bnk2panel[bnknr]; | 1762 | panelp = brdp->bnk2panel[bnknr]; |
@@ -2083,35 +1775,32 @@ static int stl_echpci64intr(stlbrd_t *brdp) | |||
2083 | */ | 1775 | */ |
2084 | static void stl_offintr(struct work_struct *work) | 1776 | static void stl_offintr(struct work_struct *work) |
2085 | { | 1777 | { |
2086 | stlport_t *portp = container_of(work, stlport_t, tqueue); | 1778 | struct stlport *portp = container_of(work, struct stlport, tqueue); |
2087 | struct tty_struct *tty; | 1779 | struct tty_struct *tty; |
2088 | unsigned int oldsigs; | 1780 | unsigned int oldsigs; |
2089 | 1781 | ||
2090 | #ifdef DEBUG | 1782 | pr_debug("stl_offintr(portp=%p)\n", portp); |
2091 | printk("stl_offintr(portp=%x)\n", (int) portp); | ||
2092 | #endif | ||
2093 | 1783 | ||
2094 | if (portp == (stlport_t *) NULL) | 1784 | if (portp == NULL) |
2095 | return; | 1785 | return; |
2096 | 1786 | ||
2097 | tty = portp->tty; | 1787 | tty = portp->tty; |
2098 | if (tty == (struct tty_struct *) NULL) | 1788 | if (tty == NULL) |
2099 | return; | 1789 | return; |
2100 | 1790 | ||
2101 | lock_kernel(); | 1791 | lock_kernel(); |
2102 | if (test_bit(ASYI_TXLOW, &portp->istate)) { | 1792 | if (test_bit(ASYI_TXLOW, &portp->istate)) |
2103 | tty_wakeup(tty); | 1793 | tty_wakeup(tty); |
2104 | } | 1794 | |
2105 | if (test_bit(ASYI_DCDCHANGE, &portp->istate)) { | 1795 | if (test_bit(ASYI_DCDCHANGE, &portp->istate)) { |
2106 | clear_bit(ASYI_DCDCHANGE, &portp->istate); | 1796 | clear_bit(ASYI_DCDCHANGE, &portp->istate); |
2107 | oldsigs = portp->sigs; | 1797 | oldsigs = portp->sigs; |
2108 | portp->sigs = stl_getsignals(portp); | 1798 | portp->sigs = stl_getsignals(portp); |
2109 | if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) | 1799 | if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) |
2110 | wake_up_interruptible(&portp->open_wait); | 1800 | wake_up_interruptible(&portp->open_wait); |
2111 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) { | 1801 | if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) |
2112 | if (portp->flags & ASYNC_CHECK_CD) | 1802 | if (portp->flags & ASYNC_CHECK_CD) |
2113 | tty_hangup(tty); /* FIXME: module removal race here - AKPM */ | 1803 | tty_hangup(tty); /* FIXME: module removal race here - AKPM */ |
2114 | } | ||
2115 | } | 1804 | } |
2116 | unlock_kernel(); | 1805 | unlock_kernel(); |
2117 | } | 1806 | } |
@@ -2122,14 +1811,13 @@ static void stl_offintr(struct work_struct *work) | |||
2122 | * Initialize all the ports on a panel. | 1811 | * Initialize all the ports on a panel. |
2123 | */ | 1812 | */ |
2124 | 1813 | ||
2125 | static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | 1814 | static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp) |
2126 | { | 1815 | { |
2127 | stlport_t *portp; | 1816 | struct stlport *portp; |
2128 | int chipmask, i; | 1817 | unsigned int i; |
1818 | int chipmask; | ||
2129 | 1819 | ||
2130 | #ifdef DEBUG | 1820 | pr_debug("stl_initports(brdp=%p,panelp=%p)\n", brdp, panelp); |
2131 | printk("stl_initports(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); | ||
2132 | #endif | ||
2133 | 1821 | ||
2134 | chipmask = stl_panelinit(brdp, panelp); | 1822 | chipmask = stl_panelinit(brdp, panelp); |
2135 | 1823 | ||
@@ -2137,11 +1825,11 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2137 | * All UART's are initialized (if found!). Now go through and setup | 1825 | * All UART's are initialized (if found!). Now go through and setup |
2138 | * each ports data structures. | 1826 | * each ports data structures. |
2139 | */ | 1827 | */ |
2140 | for (i = 0; (i < panelp->nrports); i++) { | 1828 | for (i = 0; i < panelp->nrports; i++) { |
2141 | portp = kzalloc(sizeof(stlport_t), GFP_KERNEL); | 1829 | portp = kzalloc(sizeof(struct stlport), GFP_KERNEL); |
2142 | if (!portp) { | 1830 | if (!portp) { |
2143 | printk("STALLION: failed to allocate memory " | 1831 | printk("STALLION: failed to allocate memory " |
2144 | "(size=%Zd)\n", sizeof(stlport_t)); | 1832 | "(size=%Zd)\n", sizeof(struct stlport)); |
2145 | break; | 1833 | break; |
2146 | } | 1834 | } |
2147 | 1835 | ||
@@ -2164,7 +1852,30 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2164 | stl_portinit(brdp, panelp, portp); | 1852 | stl_portinit(brdp, panelp, portp); |
2165 | } | 1853 | } |
2166 | 1854 | ||
2167 | return(0); | 1855 | return 0; |
1856 | } | ||
1857 | |||
1858 | static void stl_cleanup_panels(struct stlbrd *brdp) | ||
1859 | { | ||
1860 | struct stlpanel *panelp; | ||
1861 | struct stlport *portp; | ||
1862 | unsigned int j, k; | ||
1863 | |||
1864 | for (j = 0; j < STL_MAXPANELS; j++) { | ||
1865 | panelp = brdp->panels[j]; | ||
1866 | if (panelp == NULL) | ||
1867 | continue; | ||
1868 | for (k = 0; k < STL_PORTSPERPANEL; k++) { | ||
1869 | portp = panelp->ports[k]; | ||
1870 | if (portp == NULL) | ||
1871 | continue; | ||
1872 | if (portp->tty != NULL) | ||
1873 | stl_hangup(portp->tty); | ||
1874 | kfree(portp->tx.buf); | ||
1875 | kfree(portp); | ||
1876 | } | ||
1877 | kfree(panelp); | ||
1878 | } | ||
2168 | } | 1879 | } |
2169 | 1880 | ||
2170 | /*****************************************************************************/ | 1881 | /*****************************************************************************/ |
@@ -2173,16 +1884,14 @@ static int __init stl_initports(stlbrd_t *brdp, stlpanel_t *panelp) | |||
2173 | * Try to find and initialize an EasyIO board. | 1884 | * Try to find and initialize an EasyIO board. |
2174 | */ | 1885 | */ |
2175 | 1886 | ||
2176 | static inline int stl_initeio(stlbrd_t *brdp) | 1887 | static int __devinit stl_initeio(struct stlbrd *brdp) |
2177 | { | 1888 | { |
2178 | stlpanel_t *panelp; | 1889 | struct stlpanel *panelp; |
2179 | unsigned int status; | 1890 | unsigned int status; |
2180 | char *name; | 1891 | char *name; |
2181 | int rc; | 1892 | int retval; |
2182 | 1893 | ||
2183 | #ifdef DEBUG | 1894 | pr_debug("stl_initeio(brdp=%p)\n", brdp); |
2184 | printk("stl_initeio(brdp=%x)\n", (int) brdp); | ||
2185 | #endif | ||
2186 | 1895 | ||
2187 | brdp->ioctrl = brdp->ioaddr1 + 1; | 1896 | brdp->ioctrl = brdp->ioaddr1 + 1; |
2188 | brdp->iostatus = brdp->ioaddr1 + 2; | 1897 | brdp->iostatus = brdp->ioaddr1 + 2; |
@@ -2207,18 +1916,20 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2207 | (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { | 1916 | (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { |
2208 | printk("STALLION: invalid irq=%d for brd=%d\n", | 1917 | printk("STALLION: invalid irq=%d for brd=%d\n", |
2209 | brdp->irq, brdp->brdnr); | 1918 | brdp->irq, brdp->brdnr); |
2210 | return(-EINVAL); | 1919 | retval = -EINVAL; |
1920 | goto err; | ||
2211 | } | 1921 | } |
2212 | outb((stl_vecmap[brdp->irq] | EIO_0WS | | 1922 | outb((stl_vecmap[brdp->irq] | EIO_0WS | |
2213 | ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)), | 1923 | ((brdp->irqtype) ? EIO_INTLEVEL : EIO_INTEDGE)), |
2214 | brdp->ioctrl); | 1924 | brdp->ioctrl); |
2215 | } | 1925 | } |
2216 | 1926 | ||
1927 | retval = -EBUSY; | ||
2217 | if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { | 1928 | if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { |
2218 | printk(KERN_WARNING "STALLION: Warning, board %d I/O address " | 1929 | printk(KERN_WARNING "STALLION: Warning, board %d I/O address " |
2219 | "%x conflicts with another device\n", brdp->brdnr, | 1930 | "%x conflicts with another device\n", brdp->brdnr, |
2220 | brdp->ioaddr1); | 1931 | brdp->ioaddr1); |
2221 | return(-EBUSY); | 1932 | goto err; |
2222 | } | 1933 | } |
2223 | 1934 | ||
2224 | if (brdp->iosize2 > 0) | 1935 | if (brdp->iosize2 > 0) |
@@ -2229,8 +1940,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2229 | printk(KERN_WARNING "STALLION: Warning, also " | 1940 | printk(KERN_WARNING "STALLION: Warning, also " |
2230 | "releasing board %d I/O address %x \n", | 1941 | "releasing board %d I/O address %x \n", |
2231 | brdp->brdnr, brdp->ioaddr1); | 1942 | brdp->brdnr, brdp->ioaddr1); |
2232 | release_region(brdp->ioaddr1, brdp->iosize1); | 1943 | goto err_rel1; |
2233 | return(-EBUSY); | ||
2234 | } | 1944 | } |
2235 | 1945 | ||
2236 | /* | 1946 | /* |
@@ -2239,6 +1949,7 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2239 | brdp->clk = CD1400_CLK; | 1949 | brdp->clk = CD1400_CLK; |
2240 | brdp->isr = stl_eiointr; | 1950 | brdp->isr = stl_eiointr; |
2241 | 1951 | ||
1952 | retval = -ENODEV; | ||
2242 | switch (status & EIO_IDBITMASK) { | 1953 | switch (status & EIO_IDBITMASK) { |
2243 | case EIO_8PORTM: | 1954 | case EIO_8PORTM: |
2244 | brdp->clk = CD1400_CLK8M; | 1955 | brdp->clk = CD1400_CLK8M; |
@@ -2262,11 +1973,11 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2262 | brdp->nrports = 16; | 1973 | brdp->nrports = 16; |
2263 | break; | 1974 | break; |
2264 | default: | 1975 | default: |
2265 | return(-ENODEV); | 1976 | goto err_rel2; |
2266 | } | 1977 | } |
2267 | break; | 1978 | break; |
2268 | default: | 1979 | default: |
2269 | return(-ENODEV); | 1980 | goto err_rel2; |
2270 | } | 1981 | } |
2271 | 1982 | ||
2272 | /* | 1983 | /* |
@@ -2274,11 +1985,12 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2274 | * can complete the setup. | 1985 | * can complete the setup. |
2275 | */ | 1986 | */ |
2276 | 1987 | ||
2277 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 1988 | panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); |
2278 | if (!panelp) { | 1989 | if (!panelp) { |
2279 | printk(KERN_WARNING "STALLION: failed to allocate memory " | 1990 | printk(KERN_WARNING "STALLION: failed to allocate memory " |
2280 | "(size=%Zd)\n", sizeof(stlpanel_t)); | 1991 | "(size=%Zd)\n", sizeof(struct stlpanel)); |
2281 | return -ENOMEM; | 1992 | retval = -ENOMEM; |
1993 | goto err_rel2; | ||
2282 | } | 1994 | } |
2283 | 1995 | ||
2284 | panelp->magic = STL_PANELMAGIC; | 1996 | panelp->magic = STL_PANELMAGIC; |
@@ -2288,10 +2000,10 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2288 | panelp->iobase = brdp->ioaddr1; | 2000 | panelp->iobase = brdp->ioaddr1; |
2289 | panelp->hwid = status; | 2001 | panelp->hwid = status; |
2290 | if ((status & EIO_IDBITMASK) == EIO_MK3) { | 2002 | if ((status & EIO_IDBITMASK) == EIO_MK3) { |
2291 | panelp->uartp = (void *) &stl_sc26198uart; | 2003 | panelp->uartp = &stl_sc26198uart; |
2292 | panelp->isr = stl_sc26198intr; | 2004 | panelp->isr = stl_sc26198intr; |
2293 | } else { | 2005 | } else { |
2294 | panelp->uartp = (void *) &stl_cd1400uart; | 2006 | panelp->uartp = &stl_cd1400uart; |
2295 | panelp->isr = stl_cd1400eiointr; | 2007 | panelp->isr = stl_cd1400eiointr; |
2296 | } | 2008 | } |
2297 | 2009 | ||
@@ -2302,11 +2014,20 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2302 | if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { | 2014 | if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { |
2303 | printk("STALLION: failed to register interrupt " | 2015 | printk("STALLION: failed to register interrupt " |
2304 | "routine for %s irq=%d\n", name, brdp->irq); | 2016 | "routine for %s irq=%d\n", name, brdp->irq); |
2305 | rc = -ENODEV; | 2017 | retval = -ENODEV; |
2306 | } else { | 2018 | goto err_fr; |
2307 | rc = 0; | ||
2308 | } | 2019 | } |
2309 | return rc; | 2020 | |
2021 | return 0; | ||
2022 | err_fr: | ||
2023 | stl_cleanup_panels(brdp); | ||
2024 | err_rel2: | ||
2025 | if (brdp->iosize2 > 0) | ||
2026 | release_region(brdp->ioaddr2, brdp->iosize2); | ||
2027 | err_rel1: | ||
2028 | release_region(brdp->ioaddr1, brdp->iosize1); | ||
2029 | err: | ||
2030 | return retval; | ||
2310 | } | 2031 | } |
2311 | 2032 | ||
2312 | /*****************************************************************************/ | 2033 | /*****************************************************************************/ |
@@ -2316,16 +2037,14 @@ static inline int stl_initeio(stlbrd_t *brdp) | |||
2316 | * dealing with all types of ECH board. | 2037 | * dealing with all types of ECH board. |
2317 | */ | 2038 | */ |
2318 | 2039 | ||
2319 | static inline int stl_initech(stlbrd_t *brdp) | 2040 | static int __devinit stl_initech(struct stlbrd *brdp) |
2320 | { | 2041 | { |
2321 | stlpanel_t *panelp; | 2042 | struct stlpanel *panelp; |
2322 | unsigned int status, nxtid, ioaddr, conflict; | 2043 | unsigned int status, nxtid, ioaddr, conflict, panelnr, banknr, i; |
2323 | int panelnr, banknr, i; | 2044 | int retval; |
2324 | char *name; | 2045 | char *name; |
2325 | 2046 | ||
2326 | #ifdef DEBUG | 2047 | pr_debug("stl_initech(brdp=%p)\n", brdp); |
2327 | printk("stl_initech(brdp=%x)\n", (int) brdp); | ||
2328 | #endif | ||
2329 | 2048 | ||
2330 | status = 0; | 2049 | status = 0; |
2331 | conflict = 0; | 2050 | conflict = 0; |
@@ -2342,20 +2061,23 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2342 | brdp->ioctrl = brdp->ioaddr1 + 1; | 2061 | brdp->ioctrl = brdp->ioaddr1 + 1; |
2343 | brdp->iostatus = brdp->ioaddr1 + 1; | 2062 | brdp->iostatus = brdp->ioaddr1 + 1; |
2344 | status = inb(brdp->iostatus); | 2063 | status = inb(brdp->iostatus); |
2345 | if ((status & ECH_IDBITMASK) != ECH_ID) | 2064 | if ((status & ECH_IDBITMASK) != ECH_ID) { |
2346 | return(-ENODEV); | 2065 | retval = -ENODEV; |
2066 | goto err; | ||
2067 | } | ||
2347 | if ((brdp->irq < 0) || (brdp->irq > 15) || | 2068 | if ((brdp->irq < 0) || (brdp->irq > 15) || |
2348 | (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { | 2069 | (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { |
2349 | printk("STALLION: invalid irq=%d for brd=%d\n", | 2070 | printk("STALLION: invalid irq=%d for brd=%d\n", |
2350 | brdp->irq, brdp->brdnr); | 2071 | brdp->irq, brdp->brdnr); |
2351 | return(-EINVAL); | 2072 | retval = -EINVAL; |
2073 | goto err; | ||
2352 | } | 2074 | } |
2353 | status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1); | 2075 | status = ((brdp->ioaddr2 & ECH_ADDR2MASK) >> 1); |
2354 | status |= (stl_vecmap[brdp->irq] << 1); | 2076 | status |= (stl_vecmap[brdp->irq] << 1); |
2355 | outb((status | ECH_BRDRESET), brdp->ioaddr1); | 2077 | outb((status | ECH_BRDRESET), brdp->ioaddr1); |
2356 | brdp->ioctrlval = ECH_INTENABLE | | 2078 | brdp->ioctrlval = ECH_INTENABLE | |
2357 | ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE); | 2079 | ((brdp->irqtype) ? ECH_INTLEVEL : ECH_INTEDGE); |
2358 | for (i = 0; (i < 10); i++) | 2080 | for (i = 0; i < 10; i++) |
2359 | outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); | 2081 | outb((brdp->ioctrlval | ECH_BRDENABLE), brdp->ioctrl); |
2360 | brdp->iosize1 = 2; | 2082 | brdp->iosize1 = 2; |
2361 | brdp->iosize2 = 32; | 2083 | brdp->iosize2 = 32; |
@@ -2368,13 +2090,16 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2368 | brdp->ioctrl = brdp->ioaddr1 + 0x20; | 2090 | brdp->ioctrl = brdp->ioaddr1 + 0x20; |
2369 | brdp->iostatus = brdp->ioctrl; | 2091 | brdp->iostatus = brdp->ioctrl; |
2370 | status = inb(brdp->iostatus); | 2092 | status = inb(brdp->iostatus); |
2371 | if ((status & ECH_IDBITMASK) != ECH_ID) | 2093 | if ((status & ECH_IDBITMASK) != ECH_ID) { |
2372 | return(-ENODEV); | 2094 | retval = -ENODEV; |
2095 | goto err; | ||
2096 | } | ||
2373 | if ((brdp->irq < 0) || (brdp->irq > 15) || | 2097 | if ((brdp->irq < 0) || (brdp->irq > 15) || |
2374 | (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { | 2098 | (stl_vecmap[brdp->irq] == (unsigned char) 0xff)) { |
2375 | printk("STALLION: invalid irq=%d for brd=%d\n", | 2099 | printk("STALLION: invalid irq=%d for brd=%d\n", |
2376 | brdp->irq, brdp->brdnr); | 2100 | brdp->irq, brdp->brdnr); |
2377 | return(-EINVAL); | 2101 | retval = -EINVAL; |
2102 | goto err; | ||
2378 | } | 2103 | } |
2379 | outb(ECHMC_BRDRESET, brdp->ioctrl); | 2104 | outb(ECHMC_BRDRESET, brdp->ioctrl); |
2380 | outb(ECHMC_INTENABLE, brdp->ioctrl); | 2105 | outb(ECHMC_INTENABLE, brdp->ioctrl); |
@@ -2401,19 +2126,20 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2401 | 2126 | ||
2402 | default: | 2127 | default: |
2403 | printk("STALLION: unknown board type=%d\n", brdp->brdtype); | 2128 | printk("STALLION: unknown board type=%d\n", brdp->brdtype); |
2404 | return(-EINVAL); | 2129 | retval = -EINVAL; |
2405 | break; | 2130 | goto err; |
2406 | } | 2131 | } |
2407 | 2132 | ||
2408 | /* | 2133 | /* |
2409 | * Check boards for possible IO address conflicts and return fail status | 2134 | * Check boards for possible IO address conflicts and return fail status |
2410 | * if an IO conflict found. | 2135 | * if an IO conflict found. |
2411 | */ | 2136 | */ |
2137 | retval = -EBUSY; | ||
2412 | if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { | 2138 | if (!request_region(brdp->ioaddr1, brdp->iosize1, name)) { |
2413 | printk(KERN_WARNING "STALLION: Warning, board %d I/O address " | 2139 | printk(KERN_WARNING "STALLION: Warning, board %d I/O address " |
2414 | "%x conflicts with another device\n", brdp->brdnr, | 2140 | "%x conflicts with another device\n", brdp->brdnr, |
2415 | brdp->ioaddr1); | 2141 | brdp->ioaddr1); |
2416 | return(-EBUSY); | 2142 | goto err; |
2417 | } | 2143 | } |
2418 | 2144 | ||
2419 | if (brdp->iosize2 > 0) | 2145 | if (brdp->iosize2 > 0) |
@@ -2424,8 +2150,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2424 | printk(KERN_WARNING "STALLION: Warning, also " | 2150 | printk(KERN_WARNING "STALLION: Warning, also " |
2425 | "releasing board %d I/O address %x \n", | 2151 | "releasing board %d I/O address %x \n", |
2426 | brdp->brdnr, brdp->ioaddr1); | 2152 | brdp->brdnr, brdp->ioaddr1); |
2427 | release_region(brdp->ioaddr1, brdp->iosize1); | 2153 | goto err_rel1; |
2428 | return(-EBUSY); | ||
2429 | } | 2154 | } |
2430 | 2155 | ||
2431 | /* | 2156 | /* |
@@ -2440,19 +2165,19 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2440 | panelnr = 0; | 2165 | panelnr = 0; |
2441 | nxtid = 0; | 2166 | nxtid = 0; |
2442 | 2167 | ||
2443 | for (i = 0; (i < STL_MAXPANELS); i++) { | 2168 | for (i = 0; i < STL_MAXPANELS; i++) { |
2444 | if (brdp->brdtype == BRD_ECHPCI) { | 2169 | if (brdp->brdtype == BRD_ECHPCI) { |
2445 | outb(nxtid, brdp->ioctrl); | 2170 | outb(nxtid, brdp->ioctrl); |
2446 | ioaddr = brdp->ioaddr2; | 2171 | ioaddr = brdp->ioaddr2; |
2447 | } | 2172 | } |
2448 | status = inb(ioaddr + ECH_PNLSTATUS); | 2173 | status = inb(ioaddr + ECH_PNLSTATUS); |
2449 | if ((status & ECH_PNLIDMASK) != nxtid) | 2174 | if ((status & ECH_PNLIDMASK) != nxtid) |
2450 | break; | 2175 | goto err_fr; |
2451 | panelp = kzalloc(sizeof(stlpanel_t), GFP_KERNEL); | 2176 | panelp = kzalloc(sizeof(struct stlpanel), GFP_KERNEL); |
2452 | if (!panelp) { | 2177 | if (!panelp) { |
2453 | printk("STALLION: failed to allocate memory " | 2178 | printk("STALLION: failed to allocate memory " |
2454 | "(size=%Zd)\n", sizeof(stlpanel_t)); | 2179 | "(size=%Zd)\n", sizeof(struct stlpanel)); |
2455 | break; | 2180 | goto err_fr; |
2456 | } | 2181 | } |
2457 | panelp->magic = STL_PANELMAGIC; | 2182 | panelp->magic = STL_PANELMAGIC; |
2458 | panelp->brdnr = brdp->brdnr; | 2183 | panelp->brdnr = brdp->brdnr; |
@@ -2465,7 +2190,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2465 | brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS; | 2190 | brdp->bnkstataddr[banknr++] = ioaddr + ECH_PNLSTATUS; |
2466 | 2191 | ||
2467 | if (status & ECH_PNLXPID) { | 2192 | if (status & ECH_PNLXPID) { |
2468 | panelp->uartp = (void *) &stl_sc26198uart; | 2193 | panelp->uartp = &stl_sc26198uart; |
2469 | panelp->isr = stl_sc26198intr; | 2194 | panelp->isr = stl_sc26198intr; |
2470 | if (status & ECH_PNL16PORT) { | 2195 | if (status & ECH_PNL16PORT) { |
2471 | panelp->nrports = 16; | 2196 | panelp->nrports = 16; |
@@ -2473,11 +2198,10 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2473 | brdp->bnkpageaddr[banknr] = nxtid; | 2198 | brdp->bnkpageaddr[banknr] = nxtid; |
2474 | brdp->bnkstataddr[banknr++] = ioaddr + 4 + | 2199 | brdp->bnkstataddr[banknr++] = ioaddr + 4 + |
2475 | ECH_PNLSTATUS; | 2200 | ECH_PNLSTATUS; |
2476 | } else { | 2201 | } else |
2477 | panelp->nrports = 8; | 2202 | panelp->nrports = 8; |
2478 | } | ||
2479 | } else { | 2203 | } else { |
2480 | panelp->uartp = (void *) &stl_cd1400uart; | 2204 | panelp->uartp = &stl_cd1400uart; |
2481 | panelp->isr = stl_cd1400echintr; | 2205 | panelp->isr = stl_cd1400echintr; |
2482 | if (status & ECH_PNL16PORT) { | 2206 | if (status & ECH_PNL16PORT) { |
2483 | panelp->nrports = 16; | 2207 | panelp->nrports = 16; |
@@ -2500,7 +2224,7 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2500 | brdp->panels[panelnr++] = panelp; | 2224 | brdp->panels[panelnr++] = panelp; |
2501 | if ((brdp->brdtype != BRD_ECHPCI) && | 2225 | if ((brdp->brdtype != BRD_ECHPCI) && |
2502 | (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) | 2226 | (ioaddr >= (brdp->ioaddr2 + brdp->iosize2))) |
2503 | break; | 2227 | goto err_fr; |
2504 | } | 2228 | } |
2505 | 2229 | ||
2506 | brdp->nrpanels = panelnr; | 2230 | brdp->nrpanels = panelnr; |
@@ -2512,12 +2236,19 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2512 | if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { | 2236 | if (request_irq(brdp->irq, stl_intr, IRQF_SHARED, name, brdp) != 0) { |
2513 | printk("STALLION: failed to register interrupt " | 2237 | printk("STALLION: failed to register interrupt " |
2514 | "routine for %s irq=%d\n", name, brdp->irq); | 2238 | "routine for %s irq=%d\n", name, brdp->irq); |
2515 | i = -ENODEV; | 2239 | retval = -ENODEV; |
2516 | } else { | 2240 | goto err_fr; |
2517 | i = 0; | ||
2518 | } | 2241 | } |
2519 | 2242 | ||
2520 | return(i); | 2243 | return 0; |
2244 | err_fr: | ||
2245 | stl_cleanup_panels(brdp); | ||
2246 | if (brdp->iosize2 > 0) | ||
2247 | release_region(brdp->ioaddr2, brdp->iosize2); | ||
2248 | err_rel1: | ||
2249 | release_region(brdp->ioaddr1, brdp->iosize1); | ||
2250 | err: | ||
2251 | return retval; | ||
2521 | } | 2252 | } |
2522 | 2253 | ||
2523 | /*****************************************************************************/ | 2254 | /*****************************************************************************/ |
@@ -2529,48 +2260,61 @@ static inline int stl_initech(stlbrd_t *brdp) | |||
2529 | * since the initial search and setup is very different. | 2260 | * since the initial search and setup is very different. |
2530 | */ | 2261 | */ |
2531 | 2262 | ||
2532 | static int __init stl_brdinit(stlbrd_t *brdp) | 2263 | static int __devinit stl_brdinit(struct stlbrd *brdp) |
2533 | { | 2264 | { |
2534 | int i; | 2265 | int i, retval; |
2535 | 2266 | ||
2536 | #ifdef DEBUG | 2267 | pr_debug("stl_brdinit(brdp=%p)\n", brdp); |
2537 | printk("stl_brdinit(brdp=%x)\n", (int) brdp); | ||
2538 | #endif | ||
2539 | 2268 | ||
2540 | switch (brdp->brdtype) { | 2269 | switch (brdp->brdtype) { |
2541 | case BRD_EASYIO: | 2270 | case BRD_EASYIO: |
2542 | case BRD_EASYIOPCI: | 2271 | case BRD_EASYIOPCI: |
2543 | stl_initeio(brdp); | 2272 | retval = stl_initeio(brdp); |
2273 | if (retval) | ||
2274 | goto err; | ||
2544 | break; | 2275 | break; |
2545 | case BRD_ECH: | 2276 | case BRD_ECH: |
2546 | case BRD_ECHMC: | 2277 | case BRD_ECHMC: |
2547 | case BRD_ECHPCI: | 2278 | case BRD_ECHPCI: |
2548 | case BRD_ECH64PCI: | 2279 | case BRD_ECH64PCI: |
2549 | stl_initech(brdp); | 2280 | retval = stl_initech(brdp); |
2281 | if (retval) | ||
2282 | goto err; | ||
2550 | break; | 2283 | break; |
2551 | default: | 2284 | default: |
2552 | printk("STALLION: board=%d is unknown board type=%d\n", | 2285 | printk("STALLION: board=%d is unknown board type=%d\n", |
2553 | brdp->brdnr, brdp->brdtype); | 2286 | brdp->brdnr, brdp->brdtype); |
2554 | return(ENODEV); | 2287 | retval = -ENODEV; |
2288 | goto err; | ||
2555 | } | 2289 | } |
2556 | 2290 | ||
2557 | stl_brds[brdp->brdnr] = brdp; | ||
2558 | if ((brdp->state & BRD_FOUND) == 0) { | 2291 | if ((brdp->state & BRD_FOUND) == 0) { |
2559 | printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", | 2292 | printk("STALLION: %s board not found, board=%d io=%x irq=%d\n", |
2560 | stl_brdnames[brdp->brdtype], brdp->brdnr, | 2293 | stl_brdnames[brdp->brdtype], brdp->brdnr, |
2561 | brdp->ioaddr1, brdp->irq); | 2294 | brdp->ioaddr1, brdp->irq); |
2562 | return(ENODEV); | 2295 | goto err_free; |
2563 | } | 2296 | } |
2564 | 2297 | ||
2565 | for (i = 0; (i < STL_MAXPANELS); i++) | 2298 | for (i = 0; i < STL_MAXPANELS; i++) |
2566 | if (brdp->panels[i] != (stlpanel_t *) NULL) | 2299 | if (brdp->panels[i] != NULL) |
2567 | stl_initports(brdp, brdp->panels[i]); | 2300 | stl_initports(brdp, brdp->panels[i]); |
2568 | 2301 | ||
2569 | printk("STALLION: %s found, board=%d io=%x irq=%d " | 2302 | printk("STALLION: %s found, board=%d io=%x irq=%d " |
2570 | "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype], | 2303 | "nrpanels=%d nrports=%d\n", stl_brdnames[brdp->brdtype], |
2571 | brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels, | 2304 | brdp->brdnr, brdp->ioaddr1, brdp->irq, brdp->nrpanels, |
2572 | brdp->nrports); | 2305 | brdp->nrports); |
2573 | return(0); | 2306 | |
2307 | return 0; | ||
2308 | err_free: | ||
2309 | free_irq(brdp->irq, brdp); | ||
2310 | |||
2311 | stl_cleanup_panels(brdp); | ||
2312 | |||
2313 | release_region(brdp->ioaddr1, brdp->iosize1); | ||
2314 | if (brdp->iosize2 > 0) | ||
2315 | release_region(brdp->ioaddr2, brdp->iosize2); | ||
2316 | err: | ||
2317 | return retval; | ||
2574 | } | 2318 | } |
2575 | 2319 | ||
2576 | /*****************************************************************************/ | 2320 | /*****************************************************************************/ |
@@ -2579,59 +2323,62 @@ static int __init stl_brdinit(stlbrd_t *brdp) | |||
2579 | * Find the next available board number that is free. | 2323 | * Find the next available board number that is free. |
2580 | */ | 2324 | */ |
2581 | 2325 | ||
2582 | static inline int stl_getbrdnr(void) | 2326 | static int __devinit stl_getbrdnr(void) |
2583 | { | 2327 | { |
2584 | int i; | 2328 | unsigned int i; |
2585 | 2329 | ||
2586 | for (i = 0; (i < STL_MAXBRDS); i++) { | 2330 | for (i = 0; i < STL_MAXBRDS; i++) |
2587 | if (stl_brds[i] == (stlbrd_t *) NULL) { | 2331 | if (stl_brds[i] == NULL) { |
2588 | if (i >= stl_nrbrds) | 2332 | if (i >= stl_nrbrds) |
2589 | stl_nrbrds = i + 1; | 2333 | stl_nrbrds = i + 1; |
2590 | return(i); | 2334 | return i; |
2591 | } | 2335 | } |
2592 | } | 2336 | |
2593 | return(-1); | 2337 | return -1; |
2594 | } | 2338 | } |
2595 | 2339 | ||
2596 | /*****************************************************************************/ | 2340 | /*****************************************************************************/ |
2597 | |||
2598 | #ifdef CONFIG_PCI | ||
2599 | |||
2600 | /* | 2341 | /* |
2601 | * We have a Stallion board. Allocate a board structure and | 2342 | * We have a Stallion board. Allocate a board structure and |
2602 | * initialize it. Read its IO and IRQ resources from PCI | 2343 | * initialize it. Read its IO and IRQ resources from PCI |
2603 | * configuration space. | 2344 | * configuration space. |
2604 | */ | 2345 | */ |
2605 | 2346 | ||
2606 | static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp) | 2347 | static int __devinit stl_pciprobe(struct pci_dev *pdev, |
2348 | const struct pci_device_id *ent) | ||
2607 | { | 2349 | { |
2608 | stlbrd_t *brdp; | 2350 | struct stlbrd *brdp; |
2609 | 2351 | unsigned int i, brdtype = ent->driver_data; | |
2610 | #ifdef DEBUG | 2352 | int brdnr, retval = -ENODEV; |
2611 | printk("stl_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", brdtype, | 2353 | |
2612 | devp->bus->number, devp->devfn); | 2354 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) |
2613 | #endif | 2355 | goto err; |
2614 | 2356 | ||
2615 | if (pci_enable_device(devp)) | 2357 | dev_info(&pdev->dev, "please, report this to LKML: %x/%x/%x\n", |
2616 | return(-EIO); | 2358 | pdev->vendor, pdev->device, pdev->class); |
2617 | if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL) | 2359 | |
2618 | return(-ENOMEM); | 2360 | retval = pci_enable_device(pdev); |
2619 | if ((brdp->brdnr = stl_getbrdnr()) < 0) { | 2361 | if (retval) |
2620 | printk("STALLION: too many boards found, " | 2362 | goto err; |
2363 | brdp = stl_allocbrd(); | ||
2364 | if (brdp == NULL) { | ||
2365 | retval = -ENOMEM; | ||
2366 | goto err; | ||
2367 | } | ||
2368 | mutex_lock(&stl_brdslock); | ||
2369 | brdnr = stl_getbrdnr(); | ||
2370 | if (brdnr < 0) { | ||
2371 | dev_err(&pdev->dev, "too many boards found, " | ||
2621 | "maximum supported %d\n", STL_MAXBRDS); | 2372 | "maximum supported %d\n", STL_MAXBRDS); |
2622 | return(0); | 2373 | mutex_unlock(&stl_brdslock); |
2374 | goto err_fr; | ||
2623 | } | 2375 | } |
2624 | brdp->brdtype = brdtype; | 2376 | brdp->brdnr = (unsigned int)brdnr; |
2377 | stl_brds[brdp->brdnr] = brdp; | ||
2378 | mutex_unlock(&stl_brdslock); | ||
2625 | 2379 | ||
2626 | /* | 2380 | brdp->brdtype = brdtype; |
2627 | * Different Stallion boards use the BAR registers in different ways, | 2381 | brdp->state |= STL_PROBED; |
2628 | * so set up io addresses based on board type. | ||
2629 | */ | ||
2630 | #ifdef DEBUG | ||
2631 | printk("%s(%d): BAR[]=%x,%x,%x,%x IRQ=%x\n", __FILE__, __LINE__, | ||
2632 | pci_resource_start(devp, 0), pci_resource_start(devp, 1), | ||
2633 | pci_resource_start(devp, 2), pci_resource_start(devp, 3), devp->irq); | ||
2634 | #endif | ||
2635 | 2382 | ||
2636 | /* | 2383 | /* |
2637 | * We have all resources from the board, so let's setup the actual | 2384 | * We have all resources from the board, so let's setup the actual |
@@ -2639,120 +2386,70 @@ static inline int stl_initpcibrd(int brdtype, struct pci_dev *devp) | |||
2639 | */ | 2386 | */ |
2640 | switch (brdtype) { | 2387 | switch (brdtype) { |
2641 | case BRD_ECHPCI: | 2388 | case BRD_ECHPCI: |
2642 | brdp->ioaddr2 = pci_resource_start(devp, 0); | 2389 | brdp->ioaddr2 = pci_resource_start(pdev, 0); |
2643 | brdp->ioaddr1 = pci_resource_start(devp, 1); | 2390 | brdp->ioaddr1 = pci_resource_start(pdev, 1); |
2644 | break; | 2391 | break; |
2645 | case BRD_ECH64PCI: | 2392 | case BRD_ECH64PCI: |
2646 | brdp->ioaddr2 = pci_resource_start(devp, 2); | 2393 | brdp->ioaddr2 = pci_resource_start(pdev, 2); |
2647 | brdp->ioaddr1 = pci_resource_start(devp, 1); | 2394 | brdp->ioaddr1 = pci_resource_start(pdev, 1); |
2648 | break; | 2395 | break; |
2649 | case BRD_EASYIOPCI: | 2396 | case BRD_EASYIOPCI: |
2650 | brdp->ioaddr1 = pci_resource_start(devp, 2); | 2397 | brdp->ioaddr1 = pci_resource_start(pdev, 2); |
2651 | brdp->ioaddr2 = pci_resource_start(devp, 1); | 2398 | brdp->ioaddr2 = pci_resource_start(pdev, 1); |
2652 | break; | 2399 | break; |
2653 | default: | 2400 | default: |
2654 | printk("STALLION: unknown PCI board type=%d\n", brdtype); | 2401 | dev_err(&pdev->dev, "unknown PCI board type=%u\n", brdtype); |
2655 | break; | 2402 | break; |
2656 | } | 2403 | } |
2657 | 2404 | ||
2658 | brdp->irq = devp->irq; | 2405 | brdp->irq = pdev->irq; |
2659 | stl_brdinit(brdp); | 2406 | retval = stl_brdinit(brdp); |
2660 | 2407 | if (retval) | |
2661 | return(0); | 2408 | goto err_null; |
2662 | } | ||
2663 | |||
2664 | /*****************************************************************************/ | ||
2665 | |||
2666 | /* | ||
2667 | * Find all Stallion PCI boards that might be installed. Initialize each | ||
2668 | * one as it is found. | ||
2669 | */ | ||
2670 | |||
2671 | 2409 | ||
2672 | static inline int stl_findpcibrds(void) | 2410 | pci_set_drvdata(pdev, brdp); |
2673 | { | ||
2674 | struct pci_dev *dev = NULL; | ||
2675 | int i, rc; | ||
2676 | |||
2677 | #ifdef DEBUG | ||
2678 | printk("stl_findpcibrds()\n"); | ||
2679 | #endif | ||
2680 | 2411 | ||
2681 | for (i = 0; (i < stl_nrpcibrds); i++) | 2412 | for (i = 0; i < brdp->nrports; i++) |
2682 | while ((dev = pci_find_device(stl_pcibrds[i].vendid, | 2413 | tty_register_device(stl_serial, |
2683 | stl_pcibrds[i].devid, dev))) { | 2414 | brdp->brdnr * STL_MAXPORTS + i, &pdev->dev); |
2684 | |||
2685 | /* | ||
2686 | * Found a device on the PCI bus that has our vendor and | ||
2687 | * device ID. Need to check now that it is really us. | ||
2688 | */ | ||
2689 | if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) | ||
2690 | continue; | ||
2691 | |||
2692 | rc = stl_initpcibrd(stl_pcibrds[i].brdtype, dev); | ||
2693 | if (rc) | ||
2694 | return(rc); | ||
2695 | } | ||
2696 | 2415 | ||
2697 | return(0); | 2416 | return 0; |
2417 | err_null: | ||
2418 | stl_brds[brdp->brdnr] = NULL; | ||
2419 | err_fr: | ||
2420 | kfree(brdp); | ||
2421 | err: | ||
2422 | return retval; | ||
2698 | } | 2423 | } |
2699 | 2424 | ||
2700 | #endif | 2425 | static void __devexit stl_pciremove(struct pci_dev *pdev) |
2701 | |||
2702 | /*****************************************************************************/ | ||
2703 | |||
2704 | /* | ||
2705 | * Scan through all the boards in the configuration and see what we | ||
2706 | * can find. Handle EIO and the ECH boards a little differently here | ||
2707 | * since the initial search and setup is too different. | ||
2708 | */ | ||
2709 | |||
2710 | static inline int stl_initbrds(void) | ||
2711 | { | 2426 | { |
2712 | stlbrd_t *brdp; | 2427 | struct stlbrd *brdp = pci_get_drvdata(pdev); |
2713 | stlconf_t *confp; | 2428 | unsigned int i; |
2714 | int i; | ||
2715 | 2429 | ||
2716 | #ifdef DEBUG | 2430 | free_irq(brdp->irq, brdp); |
2717 | printk("stl_initbrds()\n"); | ||
2718 | #endif | ||
2719 | 2431 | ||
2720 | if (stl_nrbrds > STL_MAXBRDS) { | 2432 | stl_cleanup_panels(brdp); |
2721 | printk("STALLION: too many boards in configuration table, " | ||
2722 | "truncating to %d\n", STL_MAXBRDS); | ||
2723 | stl_nrbrds = STL_MAXBRDS; | ||
2724 | } | ||
2725 | 2433 | ||
2726 | /* | 2434 | release_region(brdp->ioaddr1, brdp->iosize1); |
2727 | * Firstly scan the list of static boards configured. Allocate | 2435 | if (brdp->iosize2 > 0) |
2728 | * resources and initialize the boards as found. | 2436 | release_region(brdp->ioaddr2, brdp->iosize2); |
2729 | */ | ||
2730 | for (i = 0; (i < stl_nrbrds); i++) { | ||
2731 | confp = &stl_brdconf[i]; | ||
2732 | stl_parsebrd(confp, stl_brdsp[i]); | ||
2733 | if ((brdp = stl_allocbrd()) == (stlbrd_t *) NULL) | ||
2734 | return(-ENOMEM); | ||
2735 | brdp->brdnr = i; | ||
2736 | brdp->brdtype = confp->brdtype; | ||
2737 | brdp->ioaddr1 = confp->ioaddr1; | ||
2738 | brdp->ioaddr2 = confp->ioaddr2; | ||
2739 | brdp->irq = confp->irq; | ||
2740 | brdp->irqtype = confp->irqtype; | ||
2741 | stl_brdinit(brdp); | ||
2742 | } | ||
2743 | 2437 | ||
2744 | /* | 2438 | for (i = 0; i < brdp->nrports; i++) |
2745 | * Find any dynamically supported boards. That is via module load | 2439 | tty_unregister_device(stl_serial, |
2746 | * line options or auto-detected on the PCI bus. | 2440 | brdp->brdnr * STL_MAXPORTS + i); |
2747 | */ | ||
2748 | stl_argbrds(); | ||
2749 | #ifdef CONFIG_PCI | ||
2750 | stl_findpcibrds(); | ||
2751 | #endif | ||
2752 | 2441 | ||
2753 | return(0); | 2442 | stl_brds[brdp->brdnr] = NULL; |
2443 | kfree(brdp); | ||
2754 | } | 2444 | } |
2755 | 2445 | ||
2446 | static struct pci_driver stl_pcidriver = { | ||
2447 | .name = "stallion", | ||
2448 | .id_table = stl_pcibrds, | ||
2449 | .probe = stl_pciprobe, | ||
2450 | .remove = __devexit_p(stl_pciremove) | ||
2451 | }; | ||
2452 | |||
2756 | /*****************************************************************************/ | 2453 | /*****************************************************************************/ |
2757 | 2454 | ||
2758 | /* | 2455 | /* |
@@ -2761,17 +2458,18 @@ static inline int stl_initbrds(void) | |||
2761 | 2458 | ||
2762 | static int stl_getbrdstats(combrd_t __user *bp) | 2459 | static int stl_getbrdstats(combrd_t __user *bp) |
2763 | { | 2460 | { |
2764 | stlbrd_t *brdp; | 2461 | combrd_t stl_brdstats; |
2765 | stlpanel_t *panelp; | 2462 | struct stlbrd *brdp; |
2766 | int i; | 2463 | struct stlpanel *panelp; |
2464 | unsigned int i; | ||
2767 | 2465 | ||
2768 | if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t))) | 2466 | if (copy_from_user(&stl_brdstats, bp, sizeof(combrd_t))) |
2769 | return -EFAULT; | 2467 | return -EFAULT; |
2770 | if (stl_brdstats.brd >= STL_MAXBRDS) | 2468 | if (stl_brdstats.brd >= STL_MAXBRDS) |
2771 | return(-ENODEV); | 2469 | return -ENODEV; |
2772 | brdp = stl_brds[stl_brdstats.brd]; | 2470 | brdp = stl_brds[stl_brdstats.brd]; |
2773 | if (brdp == (stlbrd_t *) NULL) | 2471 | if (brdp == NULL) |
2774 | return(-ENODEV); | 2472 | return -ENODEV; |
2775 | 2473 | ||
2776 | memset(&stl_brdstats, 0, sizeof(combrd_t)); | 2474 | memset(&stl_brdstats, 0, sizeof(combrd_t)); |
2777 | stl_brdstats.brd = brdp->brdnr; | 2475 | stl_brdstats.brd = brdp->brdnr; |
@@ -2783,7 +2481,7 @@ static int stl_getbrdstats(combrd_t __user *bp) | |||
2783 | stl_brdstats.irq = brdp->irq; | 2481 | stl_brdstats.irq = brdp->irq; |
2784 | stl_brdstats.nrpanels = brdp->nrpanels; | 2482 | stl_brdstats.nrpanels = brdp->nrpanels; |
2785 | stl_brdstats.nrports = brdp->nrports; | 2483 | stl_brdstats.nrports = brdp->nrports; |
2786 | for (i = 0; (i < brdp->nrpanels); i++) { | 2484 | for (i = 0; i < brdp->nrpanels; i++) { |
2787 | panelp = brdp->panels[i]; | 2485 | panelp = brdp->panels[i]; |
2788 | stl_brdstats.panels[i].panel = i; | 2486 | stl_brdstats.panels[i].panel = i; |
2789 | stl_brdstats.panels[i].hwid = panelp->hwid; | 2487 | stl_brdstats.panels[i].hwid = panelp->hwid; |
@@ -2799,24 +2497,24 @@ static int stl_getbrdstats(combrd_t __user *bp) | |||
2799 | * Resolve the referenced port number into a port struct pointer. | 2497 | * Resolve the referenced port number into a port struct pointer. |
2800 | */ | 2498 | */ |
2801 | 2499 | ||
2802 | static stlport_t *stl_getport(int brdnr, int panelnr, int portnr) | 2500 | static struct stlport *stl_getport(int brdnr, int panelnr, int portnr) |
2803 | { | 2501 | { |
2804 | stlbrd_t *brdp; | 2502 | struct stlbrd *brdp; |
2805 | stlpanel_t *panelp; | 2503 | struct stlpanel *panelp; |
2806 | 2504 | ||
2807 | if ((brdnr < 0) || (brdnr >= STL_MAXBRDS)) | 2505 | if (brdnr < 0 || brdnr >= STL_MAXBRDS) |
2808 | return((stlport_t *) NULL); | 2506 | return NULL; |
2809 | brdp = stl_brds[brdnr]; | 2507 | brdp = stl_brds[brdnr]; |
2810 | if (brdp == (stlbrd_t *) NULL) | 2508 | if (brdp == NULL) |
2811 | return((stlport_t *) NULL); | 2509 | return NULL; |
2812 | if ((panelnr < 0) || (panelnr >= brdp->nrpanels)) | 2510 | if (panelnr < 0 || (unsigned int)panelnr >= brdp->nrpanels) |
2813 | return((stlport_t *) NULL); | 2511 | return NULL; |
2814 | panelp = brdp->panels[panelnr]; | 2512 | panelp = brdp->panels[panelnr]; |
2815 | if (panelp == (stlpanel_t *) NULL) | 2513 | if (panelp == NULL) |
2816 | return((stlport_t *) NULL); | 2514 | return NULL; |
2817 | if ((portnr < 0) || (portnr >= panelp->nrports)) | 2515 | if (portnr < 0 || (unsigned int)portnr >= panelp->nrports) |
2818 | return((stlport_t *) NULL); | 2516 | return NULL; |
2819 | return(panelp->ports[portnr]); | 2517 | return panelp->ports[portnr]; |
2820 | } | 2518 | } |
2821 | 2519 | ||
2822 | /*****************************************************************************/ | 2520 | /*****************************************************************************/ |
@@ -2827,8 +2525,9 @@ static stlport_t *stl_getport(int brdnr, int panelnr, int portnr) | |||
2827 | * what port to get stats for (used through board control device). | 2525 | * what port to get stats for (used through board control device). |
2828 | */ | 2526 | */ |
2829 | 2527 | ||
2830 | static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | 2528 | static int stl_getportstats(struct stlport *portp, comstats_t __user *cp) |
2831 | { | 2529 | { |
2530 | comstats_t stl_comstats; | ||
2832 | unsigned char *head, *tail; | 2531 | unsigned char *head, *tail; |
2833 | unsigned long flags; | 2532 | unsigned long flags; |
2834 | 2533 | ||
@@ -2837,8 +2536,8 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2837 | return -EFAULT; | 2536 | return -EFAULT; |
2838 | portp = stl_getport(stl_comstats.brd, stl_comstats.panel, | 2537 | portp = stl_getport(stl_comstats.brd, stl_comstats.panel, |
2839 | stl_comstats.port); | 2538 | stl_comstats.port); |
2840 | if (portp == (stlport_t *) NULL) | 2539 | if (portp == NULL) |
2841 | return(-ENODEV); | 2540 | return -ENODEV; |
2842 | } | 2541 | } |
2843 | 2542 | ||
2844 | portp->stats.state = portp->istate; | 2543 | portp->stats.state = portp->istate; |
@@ -2853,25 +2552,24 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2853 | portp->stats.rxbuffered = 0; | 2552 | portp->stats.rxbuffered = 0; |
2854 | 2553 | ||
2855 | spin_lock_irqsave(&stallion_lock, flags); | 2554 | spin_lock_irqsave(&stallion_lock, flags); |
2856 | if (portp->tty != (struct tty_struct *) NULL) { | 2555 | if (portp->tty != NULL) |
2857 | if (portp->tty->driver_data == portp) { | 2556 | if (portp->tty->driver_data == portp) { |
2858 | portp->stats.ttystate = portp->tty->flags; | 2557 | portp->stats.ttystate = portp->tty->flags; |
2859 | /* No longer available as a statistic */ | 2558 | /* No longer available as a statistic */ |
2860 | portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */ | 2559 | portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */ |
2861 | if (portp->tty->termios != (struct termios *) NULL) { | 2560 | if (portp->tty->termios != NULL) { |
2862 | portp->stats.cflags = portp->tty->termios->c_cflag; | 2561 | portp->stats.cflags = portp->tty->termios->c_cflag; |
2863 | portp->stats.iflags = portp->tty->termios->c_iflag; | 2562 | portp->stats.iflags = portp->tty->termios->c_iflag; |
2864 | portp->stats.oflags = portp->tty->termios->c_oflag; | 2563 | portp->stats.oflags = portp->tty->termios->c_oflag; |
2865 | portp->stats.lflags = portp->tty->termios->c_lflag; | 2564 | portp->stats.lflags = portp->tty->termios->c_lflag; |
2866 | } | 2565 | } |
2867 | } | 2566 | } |
2868 | } | ||
2869 | spin_unlock_irqrestore(&stallion_lock, flags); | 2567 | spin_unlock_irqrestore(&stallion_lock, flags); |
2870 | 2568 | ||
2871 | head = portp->tx.head; | 2569 | head = portp->tx.head; |
2872 | tail = portp->tx.tail; | 2570 | tail = portp->tx.tail; |
2873 | portp->stats.txbuffered = ((head >= tail) ? (head - tail) : | 2571 | portp->stats.txbuffered = (head >= tail) ? (head - tail) : |
2874 | (STL_TXBUFSIZE - (tail - head))); | 2572 | (STL_TXBUFSIZE - (tail - head)); |
2875 | 2573 | ||
2876 | portp->stats.signals = (unsigned long) stl_getsignals(portp); | 2574 | portp->stats.signals = (unsigned long) stl_getsignals(portp); |
2877 | 2575 | ||
@@ -2885,15 +2583,17 @@ static int stl_getportstats(stlport_t *portp, comstats_t __user *cp) | |||
2885 | * Clear the port stats structure. We also return it zeroed out... | 2583 | * Clear the port stats structure. We also return it zeroed out... |
2886 | */ | 2584 | */ |
2887 | 2585 | ||
2888 | static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp) | 2586 | static int stl_clrportstats(struct stlport *portp, comstats_t __user *cp) |
2889 | { | 2587 | { |
2588 | comstats_t stl_comstats; | ||
2589 | |||
2890 | if (!portp) { | 2590 | if (!portp) { |
2891 | if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) | 2591 | if (copy_from_user(&stl_comstats, cp, sizeof(comstats_t))) |
2892 | return -EFAULT; | 2592 | return -EFAULT; |
2893 | portp = stl_getport(stl_comstats.brd, stl_comstats.panel, | 2593 | portp = stl_getport(stl_comstats.brd, stl_comstats.panel, |
2894 | stl_comstats.port); | 2594 | stl_comstats.port); |
2895 | if (portp == (stlport_t *) NULL) | 2595 | if (portp == NULL) |
2896 | return(-ENODEV); | 2596 | return -ENODEV; |
2897 | } | 2597 | } |
2898 | 2598 | ||
2899 | memset(&portp->stats, 0, sizeof(comstats_t)); | 2599 | memset(&portp->stats, 0, sizeof(comstats_t)); |
@@ -2910,17 +2610,18 @@ static int stl_clrportstats(stlport_t *portp, comstats_t __user *cp) | |||
2910 | * Return the entire driver ports structure to a user app. | 2610 | * Return the entire driver ports structure to a user app. |
2911 | */ | 2611 | */ |
2912 | 2612 | ||
2913 | static int stl_getportstruct(stlport_t __user *arg) | 2613 | static int stl_getportstruct(struct stlport __user *arg) |
2914 | { | 2614 | { |
2915 | stlport_t *portp; | 2615 | struct stlport stl_dummyport; |
2616 | struct stlport *portp; | ||
2916 | 2617 | ||
2917 | if (copy_from_user(&stl_dummyport, arg, sizeof(stlport_t))) | 2618 | if (copy_from_user(&stl_dummyport, arg, sizeof(struct stlport))) |
2918 | return -EFAULT; | 2619 | return -EFAULT; |
2919 | portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr, | 2620 | portp = stl_getport(stl_dummyport.brdnr, stl_dummyport.panelnr, |
2920 | stl_dummyport.portnr); | 2621 | stl_dummyport.portnr); |
2921 | if (!portp) | 2622 | if (!portp) |
2922 | return -ENODEV; | 2623 | return -ENODEV; |
2923 | return copy_to_user(arg, portp, sizeof(stlport_t)) ? -EFAULT : 0; | 2624 | return copy_to_user(arg, portp, sizeof(struct stlport)) ? -EFAULT : 0; |
2924 | } | 2625 | } |
2925 | 2626 | ||
2926 | /*****************************************************************************/ | 2627 | /*****************************************************************************/ |
@@ -2929,18 +2630,19 @@ static int stl_getportstruct(stlport_t __user *arg) | |||
2929 | * Return the entire driver board structure to a user app. | 2630 | * Return the entire driver board structure to a user app. |
2930 | */ | 2631 | */ |
2931 | 2632 | ||
2932 | static int stl_getbrdstruct(stlbrd_t __user *arg) | 2633 | static int stl_getbrdstruct(struct stlbrd __user *arg) |
2933 | { | 2634 | { |
2934 | stlbrd_t *brdp; | 2635 | struct stlbrd stl_dummybrd; |
2636 | struct stlbrd *brdp; | ||
2935 | 2637 | ||
2936 | if (copy_from_user(&stl_dummybrd, arg, sizeof(stlbrd_t))) | 2638 | if (copy_from_user(&stl_dummybrd, arg, sizeof(struct stlbrd))) |
2937 | return -EFAULT; | 2639 | return -EFAULT; |
2938 | if ((stl_dummybrd.brdnr < 0) || (stl_dummybrd.brdnr >= STL_MAXBRDS)) | 2640 | if (stl_dummybrd.brdnr >= STL_MAXBRDS) |
2939 | return -ENODEV; | 2641 | return -ENODEV; |
2940 | brdp = stl_brds[stl_dummybrd.brdnr]; | 2642 | brdp = stl_brds[stl_dummybrd.brdnr]; |
2941 | if (!brdp) | 2643 | if (!brdp) |
2942 | return(-ENODEV); | 2644 | return -ENODEV; |
2943 | return copy_to_user(arg, brdp, sizeof(stlbrd_t)) ? -EFAULT : 0; | 2645 | return copy_to_user(arg, brdp, sizeof(struct stlbrd)) ? -EFAULT : 0; |
2944 | } | 2646 | } |
2945 | 2647 | ||
2946 | /*****************************************************************************/ | 2648 | /*****************************************************************************/ |
@@ -2956,14 +2658,11 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
2956 | int brdnr, rc; | 2658 | int brdnr, rc; |
2957 | void __user *argp = (void __user *)arg; | 2659 | void __user *argp = (void __user *)arg; |
2958 | 2660 | ||
2959 | #ifdef DEBUG | 2661 | pr_debug("stl_memioctl(ip=%p,fp=%p,cmd=%x,arg=%lx)\n", ip, fp, cmd,arg); |
2960 | printk("stl_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", (int) ip, | ||
2961 | (int) fp, cmd, (int) arg); | ||
2962 | #endif | ||
2963 | 2662 | ||
2964 | brdnr = iminor(ip); | 2663 | brdnr = iminor(ip); |
2965 | if (brdnr >= STL_MAXBRDS) | 2664 | if (brdnr >= STL_MAXBRDS) |
2966 | return(-ENODEV); | 2665 | return -ENODEV; |
2967 | rc = 0; | 2666 | rc = 0; |
2968 | 2667 | ||
2969 | switch (cmd) { | 2668 | switch (cmd) { |
@@ -2987,7 +2686,7 @@ static int stl_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, uns | |||
2987 | break; | 2686 | break; |
2988 | } | 2687 | } |
2989 | 2688 | ||
2990 | return(rc); | 2689 | return rc; |
2991 | } | 2690 | } |
2992 | 2691 | ||
2993 | static const struct tty_operations stl_ops = { | 2692 | static const struct tty_operations stl_ops = { |
@@ -3015,55 +2714,6 @@ static const struct tty_operations stl_ops = { | |||
3015 | }; | 2714 | }; |
3016 | 2715 | ||
3017 | /*****************************************************************************/ | 2716 | /*****************************************************************************/ |
3018 | |||
3019 | static int __init stl_init(void) | ||
3020 | { | ||
3021 | int i; | ||
3022 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | ||
3023 | |||
3024 | spin_lock_init(&stallion_lock); | ||
3025 | spin_lock_init(&brd_lock); | ||
3026 | |||
3027 | stl_initbrds(); | ||
3028 | |||
3029 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | ||
3030 | if (!stl_serial) | ||
3031 | return -1; | ||
3032 | |||
3033 | /* | ||
3034 | * Set up a character driver for per board stuff. This is mainly used | ||
3035 | * to do stats ioctls on the ports. | ||
3036 | */ | ||
3037 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) | ||
3038 | printk("STALLION: failed to register serial board device\n"); | ||
3039 | |||
3040 | stallion_class = class_create(THIS_MODULE, "staliomem"); | ||
3041 | for (i = 0; i < 4; i++) | ||
3042 | class_device_create(stallion_class, NULL, | ||
3043 | MKDEV(STL_SIOMEMMAJOR, i), NULL, | ||
3044 | "staliomem%d", i); | ||
3045 | |||
3046 | stl_serial->owner = THIS_MODULE; | ||
3047 | stl_serial->driver_name = stl_drvname; | ||
3048 | stl_serial->name = "ttyE"; | ||
3049 | stl_serial->major = STL_SERIALMAJOR; | ||
3050 | stl_serial->minor_start = 0; | ||
3051 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; | ||
3052 | stl_serial->subtype = SERIAL_TYPE_NORMAL; | ||
3053 | stl_serial->init_termios = stl_deftermios; | ||
3054 | stl_serial->flags = TTY_DRIVER_REAL_RAW; | ||
3055 | tty_set_operations(stl_serial, &stl_ops); | ||
3056 | |||
3057 | if (tty_register_driver(stl_serial)) { | ||
3058 | put_tty_driver(stl_serial); | ||
3059 | printk("STALLION: failed to register serial driver\n"); | ||
3060 | return -1; | ||
3061 | } | ||
3062 | |||
3063 | return 0; | ||
3064 | } | ||
3065 | |||
3066 | /*****************************************************************************/ | ||
3067 | /* CD1400 HARDWARE FUNCTIONS */ | 2717 | /* CD1400 HARDWARE FUNCTIONS */ |
3068 | /*****************************************************************************/ | 2718 | /*****************************************************************************/ |
3069 | 2719 | ||
@@ -3073,21 +2723,21 @@ static int __init stl_init(void) | |||
3073 | * (Maybe should make this inline...) | 2723 | * (Maybe should make this inline...) |
3074 | */ | 2724 | */ |
3075 | 2725 | ||
3076 | static int stl_cd1400getreg(stlport_t *portp, int regnr) | 2726 | static int stl_cd1400getreg(struct stlport *portp, int regnr) |
3077 | { | 2727 | { |
3078 | outb((regnr + portp->uartaddr), portp->ioaddr); | 2728 | outb((regnr + portp->uartaddr), portp->ioaddr); |
3079 | return inb(portp->ioaddr + EREG_DATA); | 2729 | return inb(portp->ioaddr + EREG_DATA); |
3080 | } | 2730 | } |
3081 | 2731 | ||
3082 | static void stl_cd1400setreg(stlport_t *portp, int regnr, int value) | 2732 | static void stl_cd1400setreg(struct stlport *portp, int regnr, int value) |
3083 | { | 2733 | { |
3084 | outb((regnr + portp->uartaddr), portp->ioaddr); | 2734 | outb(regnr + portp->uartaddr, portp->ioaddr); |
3085 | outb(value, portp->ioaddr + EREG_DATA); | 2735 | outb(value, portp->ioaddr + EREG_DATA); |
3086 | } | 2736 | } |
3087 | 2737 | ||
3088 | static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value) | 2738 | static int stl_cd1400updatereg(struct stlport *portp, int regnr, int value) |
3089 | { | 2739 | { |
3090 | outb((regnr + portp->uartaddr), portp->ioaddr); | 2740 | outb(regnr + portp->uartaddr, portp->ioaddr); |
3091 | if (inb(portp->ioaddr + EREG_DATA) != value) { | 2741 | if (inb(portp->ioaddr + EREG_DATA) != value) { |
3092 | outb(value, portp->ioaddr + EREG_DATA); | 2742 | outb(value, portp->ioaddr + EREG_DATA); |
3093 | return 1; | 2743 | return 1; |
@@ -3103,16 +2753,14 @@ static int stl_cd1400updatereg(stlport_t *portp, int regnr, int value) | |||
3103 | * identical when dealing with ports. | 2753 | * identical when dealing with ports. |
3104 | */ | 2754 | */ |
3105 | 2755 | ||
3106 | static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | 2756 | static int stl_cd1400panelinit(struct stlbrd *brdp, struct stlpanel *panelp) |
3107 | { | 2757 | { |
3108 | unsigned int gfrcr; | 2758 | unsigned int gfrcr; |
3109 | int chipmask, i, j; | 2759 | int chipmask, i, j; |
3110 | int nrchips, uartaddr, ioaddr; | 2760 | int nrchips, uartaddr, ioaddr; |
3111 | unsigned long flags; | 2761 | unsigned long flags; |
3112 | 2762 | ||
3113 | #ifdef DEBUG | 2763 | pr_debug("stl_panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); |
3114 | printk("stl_panelinit(brdp=%x,panelp=%x)\n", (int) brdp, (int) panelp); | ||
3115 | #endif | ||
3116 | 2764 | ||
3117 | spin_lock_irqsave(&brd_lock, flags); | 2765 | spin_lock_irqsave(&brd_lock, flags); |
3118 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 2766 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
@@ -3122,13 +2770,12 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3122 | */ | 2770 | */ |
3123 | chipmask = 0; | 2771 | chipmask = 0; |
3124 | nrchips = panelp->nrports / CD1400_PORTS; | 2772 | nrchips = panelp->nrports / CD1400_PORTS; |
3125 | for (i = 0; (i < nrchips); i++) { | 2773 | for (i = 0; i < nrchips; i++) { |
3126 | if (brdp->brdtype == BRD_ECHPCI) { | 2774 | if (brdp->brdtype == BRD_ECHPCI) { |
3127 | outb((panelp->pagenr + (i >> 1)), brdp->ioctrl); | 2775 | outb((panelp->pagenr + (i >> 1)), brdp->ioctrl); |
3128 | ioaddr = panelp->iobase; | 2776 | ioaddr = panelp->iobase; |
3129 | } else { | 2777 | } else |
3130 | ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1)); | 2778 | ioaddr = panelp->iobase + (EREG_BANKSIZE * (i >> 1)); |
3131 | } | ||
3132 | uartaddr = (i & 0x01) ? 0x080 : 0; | 2779 | uartaddr = (i & 0x01) ? 0x080 : 0; |
3133 | outb((GFRCR + uartaddr), ioaddr); | 2780 | outb((GFRCR + uartaddr), ioaddr); |
3134 | outb(0, (ioaddr + EREG_DATA)); | 2781 | outb(0, (ioaddr + EREG_DATA)); |
@@ -3136,10 +2783,10 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3136 | outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); | 2783 | outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); |
3137 | outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); | 2784 | outb(CCR_RESETFULL, (ioaddr + EREG_DATA)); |
3138 | outb((GFRCR + uartaddr), ioaddr); | 2785 | outb((GFRCR + uartaddr), ioaddr); |
3139 | for (j = 0; (j < CCR_MAXWAIT); j++) { | 2786 | for (j = 0; j < CCR_MAXWAIT; j++) |
3140 | if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0) | 2787 | if ((gfrcr = inb(ioaddr + EREG_DATA)) != 0) |
3141 | break; | 2788 | break; |
3142 | } | 2789 | |
3143 | if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) { | 2790 | if ((j >= CCR_MAXWAIT) || (gfrcr < 0x40) || (gfrcr > 0x60)) { |
3144 | printk("STALLION: cd1400 not responding, " | 2791 | printk("STALLION: cd1400 not responding, " |
3145 | "brd=%d panel=%d chip=%d\n", | 2792 | "brd=%d panel=%d chip=%d\n", |
@@ -3162,16 +2809,14 @@ static int stl_cd1400panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
3162 | * Initialize hardware specific port registers. | 2809 | * Initialize hardware specific port registers. |
3163 | */ | 2810 | */ |
3164 | 2811 | ||
3165 | static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) | 2812 | static void stl_cd1400portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) |
3166 | { | 2813 | { |
3167 | unsigned long flags; | 2814 | unsigned long flags; |
3168 | #ifdef DEBUG | 2815 | pr_debug("stl_cd1400portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, |
3169 | printk("stl_cd1400portinit(brdp=%x,panelp=%x,portp=%x)\n", | 2816 | panelp, portp); |
3170 | (int) brdp, (int) panelp, (int) portp); | ||
3171 | #endif | ||
3172 | 2817 | ||
3173 | if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) || | 2818 | if ((brdp == NULL) || (panelp == NULL) || |
3174 | (portp == (stlport_t *) NULL)) | 2819 | (portp == NULL)) |
3175 | return; | 2820 | return; |
3176 | 2821 | ||
3177 | spin_lock_irqsave(&brd_lock, flags); | 2822 | spin_lock_irqsave(&brd_lock, flags); |
@@ -3195,15 +2840,13 @@ static void stl_cd1400portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *po | |||
3195 | * since it won't usually take too long to be ready. | 2840 | * since it won't usually take too long to be ready. |
3196 | */ | 2841 | */ |
3197 | 2842 | ||
3198 | static void stl_cd1400ccrwait(stlport_t *portp) | 2843 | static void stl_cd1400ccrwait(struct stlport *portp) |
3199 | { | 2844 | { |
3200 | int i; | 2845 | int i; |
3201 | 2846 | ||
3202 | for (i = 0; (i < CCR_MAXWAIT); i++) { | 2847 | for (i = 0; i < CCR_MAXWAIT; i++) |
3203 | if (stl_cd1400getreg(portp, CCR) == 0) { | 2848 | if (stl_cd1400getreg(portp, CCR) == 0) |
3204 | return; | 2849 | return; |
3205 | } | ||
3206 | } | ||
3207 | 2850 | ||
3208 | printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n", | 2851 | printk("STALLION: cd1400 not responding, port=%d panel=%d brd=%d\n", |
3209 | portp->portnr, portp->panelnr, portp->brdnr); | 2852 | portp->portnr, portp->panelnr, portp->brdnr); |
@@ -3216,9 +2859,9 @@ static void stl_cd1400ccrwait(stlport_t *portp) | |||
3216 | * settings. | 2859 | * settings. |
3217 | */ | 2860 | */ |
3218 | 2861 | ||
3219 | static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | 2862 | static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp) |
3220 | { | 2863 | { |
3221 | stlbrd_t *brdp; | 2864 | struct stlbrd *brdp; |
3222 | unsigned long flags; | 2865 | unsigned long flags; |
3223 | unsigned int clkdiv, baudrate; | 2866 | unsigned int clkdiv, baudrate; |
3224 | unsigned char cor1, cor2, cor3; | 2867 | unsigned char cor1, cor2, cor3; |
@@ -3242,7 +2885,7 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3242 | sreroff = 0; | 2885 | sreroff = 0; |
3243 | 2886 | ||
3244 | brdp = stl_brds[portp->brdnr]; | 2887 | brdp = stl_brds[portp->brdnr]; |
3245 | if (brdp == (stlbrd_t *) NULL) | 2888 | if (brdp == NULL) |
3246 | return; | 2889 | return; |
3247 | 2890 | ||
3248 | /* | 2891 | /* |
@@ -3339,8 +2982,8 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3339 | baudrate = STL_CD1400MAXBAUD; | 2982 | baudrate = STL_CD1400MAXBAUD; |
3340 | 2983 | ||
3341 | if (baudrate > 0) { | 2984 | if (baudrate > 0) { |
3342 | for (clk = 0; (clk < CD1400_NUMCLKS); clk++) { | 2985 | for (clk = 0; clk < CD1400_NUMCLKS; clk++) { |
3343 | clkdiv = ((portp->clk / stl_cd1400clkdivs[clk]) / baudrate); | 2986 | clkdiv = (portp->clk / stl_cd1400clkdivs[clk]) / baudrate; |
3344 | if (clkdiv < 0x100) | 2987 | if (clkdiv < 0x100) |
3345 | break; | 2988 | break; |
3346 | } | 2989 | } |
@@ -3355,9 +2998,8 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3355 | mcor2 |= MCOR2_DCD; | 2998 | mcor2 |= MCOR2_DCD; |
3356 | sreron |= SRER_MODEM; | 2999 | sreron |= SRER_MODEM; |
3357 | portp->flags |= ASYNC_CHECK_CD; | 3000 | portp->flags |= ASYNC_CHECK_CD; |
3358 | } else { | 3001 | } else |
3359 | portp->flags &= ~ASYNC_CHECK_CD; | 3002 | portp->flags &= ~ASYNC_CHECK_CD; |
3360 | } | ||
3361 | 3003 | ||
3362 | /* | 3004 | /* |
3363 | * Setup cd1400 enhanced modes if we can. In particular we want to | 3005 | * Setup cd1400 enhanced modes if we can. In particular we want to |
@@ -3382,18 +3024,16 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3382 | * them all up. | 3024 | * them all up. |
3383 | */ | 3025 | */ |
3384 | 3026 | ||
3385 | #ifdef DEBUG | 3027 | pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", |
3386 | printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", | ||
3387 | portp->portnr, portp->panelnr, portp->brdnr); | 3028 | portp->portnr, portp->panelnr, portp->brdnr); |
3388 | printk(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", | 3029 | pr_debug(" cor1=%x cor2=%x cor3=%x cor4=%x cor5=%x\n", |
3389 | cor1, cor2, cor3, cor4, cor5); | 3030 | cor1, cor2, cor3, cor4, cor5); |
3390 | printk(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", | 3031 | pr_debug(" mcor1=%x mcor2=%x rtpr=%x sreron=%x sreroff=%x\n", |
3391 | mcor1, mcor2, rtpr, sreron, sreroff); | 3032 | mcor1, mcor2, rtpr, sreron, sreroff); |
3392 | printk(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div); | 3033 | pr_debug(" tcor=%x tbpr=%x rcor=%x rbpr=%x\n", clk, div, clk, div); |
3393 | printk(" schr1=%x schr2=%x schr3=%x schr4=%x\n", | 3034 | pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", |
3394 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], | 3035 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], |
3395 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3036 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
3396 | #endif | ||
3397 | 3037 | ||
3398 | spin_lock_irqsave(&brd_lock, flags); | 3038 | spin_lock_irqsave(&brd_lock, flags); |
3399 | BRDENABLE(portp->brdnr, portp->pagenr); | 3039 | BRDENABLE(portp->brdnr, portp->pagenr); |
@@ -3441,15 +3081,13 @@ static void stl_cd1400setport(stlport_t *portp, struct termios *tiosp) | |||
3441 | * Set the state of the DTR and RTS signals. | 3081 | * Set the state of the DTR and RTS signals. |
3442 | */ | 3082 | */ |
3443 | 3083 | ||
3444 | static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | 3084 | static void stl_cd1400setsignals(struct stlport *portp, int dtr, int rts) |
3445 | { | 3085 | { |
3446 | unsigned char msvr1, msvr2; | 3086 | unsigned char msvr1, msvr2; |
3447 | unsigned long flags; | 3087 | unsigned long flags; |
3448 | 3088 | ||
3449 | #ifdef DEBUG | 3089 | pr_debug("stl_cd1400setsignals(portp=%p,dtr=%d,rts=%d)\n", |
3450 | printk("stl_cd1400setsignals(portp=%x,dtr=%d,rts=%d)\n", | 3090 | portp, dtr, rts); |
3451 | (int) portp, dtr, rts); | ||
3452 | #endif | ||
3453 | 3091 | ||
3454 | msvr1 = 0; | 3092 | msvr1 = 0; |
3455 | msvr2 = 0; | 3093 | msvr2 = 0; |
@@ -3475,15 +3113,13 @@ static void stl_cd1400setsignals(stlport_t *portp, int dtr, int rts) | |||
3475 | * Return the state of the signals. | 3113 | * Return the state of the signals. |
3476 | */ | 3114 | */ |
3477 | 3115 | ||
3478 | static int stl_cd1400getsignals(stlport_t *portp) | 3116 | static int stl_cd1400getsignals(struct stlport *portp) |
3479 | { | 3117 | { |
3480 | unsigned char msvr1, msvr2; | 3118 | unsigned char msvr1, msvr2; |
3481 | unsigned long flags; | 3119 | unsigned long flags; |
3482 | int sigs; | 3120 | int sigs; |
3483 | 3121 | ||
3484 | #ifdef DEBUG | 3122 | pr_debug("stl_cd1400getsignals(portp=%p)\n", portp); |
3485 | printk("stl_cd1400getsignals(portp=%x)\n", (int) portp); | ||
3486 | #endif | ||
3487 | 3123 | ||
3488 | spin_lock_irqsave(&brd_lock, flags); | 3124 | spin_lock_irqsave(&brd_lock, flags); |
3489 | BRDENABLE(portp->brdnr, portp->pagenr); | 3125 | BRDENABLE(portp->brdnr, portp->pagenr); |
@@ -3513,15 +3149,13 @@ static int stl_cd1400getsignals(stlport_t *portp) | |||
3513 | * Enable/Disable the Transmitter and/or Receiver. | 3149 | * Enable/Disable the Transmitter and/or Receiver. |
3514 | */ | 3150 | */ |
3515 | 3151 | ||
3516 | static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | 3152 | static void stl_cd1400enablerxtx(struct stlport *portp, int rx, int tx) |
3517 | { | 3153 | { |
3518 | unsigned char ccr; | 3154 | unsigned char ccr; |
3519 | unsigned long flags; | 3155 | unsigned long flags; |
3520 | 3156 | ||
3521 | #ifdef DEBUG | 3157 | pr_debug("stl_cd1400enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); |
3522 | printk("stl_cd1400enablerxtx(portp=%x,rx=%d,tx=%d)\n", | 3158 | |
3523 | (int) portp, rx, tx); | ||
3524 | #endif | ||
3525 | ccr = 0; | 3159 | ccr = 0; |
3526 | 3160 | ||
3527 | if (tx == 0) | 3161 | if (tx == 0) |
@@ -3549,15 +3183,12 @@ static void stl_cd1400enablerxtx(stlport_t *portp, int rx, int tx) | |||
3549 | * Start/stop the Transmitter and/or Receiver. | 3183 | * Start/stop the Transmitter and/or Receiver. |
3550 | */ | 3184 | */ |
3551 | 3185 | ||
3552 | static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | 3186 | static void stl_cd1400startrxtx(struct stlport *portp, int rx, int tx) |
3553 | { | 3187 | { |
3554 | unsigned char sreron, sreroff; | 3188 | unsigned char sreron, sreroff; |
3555 | unsigned long flags; | 3189 | unsigned long flags; |
3556 | 3190 | ||
3557 | #ifdef DEBUG | 3191 | pr_debug("stl_cd1400startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); |
3558 | printk("stl_cd1400startrxtx(portp=%x,rx=%d,tx=%d)\n", | ||
3559 | (int) portp, rx, tx); | ||
3560 | #endif | ||
3561 | 3192 | ||
3562 | sreron = 0; | 3193 | sreron = 0; |
3563 | sreroff = 0; | 3194 | sreroff = 0; |
@@ -3589,13 +3220,12 @@ static void stl_cd1400startrxtx(stlport_t *portp, int rx, int tx) | |||
3589 | * Disable all interrupts from this port. | 3220 | * Disable all interrupts from this port. |
3590 | */ | 3221 | */ |
3591 | 3222 | ||
3592 | static void stl_cd1400disableintrs(stlport_t *portp) | 3223 | static void stl_cd1400disableintrs(struct stlport *portp) |
3593 | { | 3224 | { |
3594 | unsigned long flags; | 3225 | unsigned long flags; |
3595 | 3226 | ||
3596 | #ifdef DEBUG | 3227 | pr_debug("stl_cd1400disableintrs(portp=%p)\n", portp); |
3597 | printk("stl_cd1400disableintrs(portp=%x)\n", (int) portp); | 3228 | |
3598 | #endif | ||
3599 | spin_lock_irqsave(&brd_lock, flags); | 3229 | spin_lock_irqsave(&brd_lock, flags); |
3600 | BRDENABLE(portp->brdnr, portp->pagenr); | 3230 | BRDENABLE(portp->brdnr, portp->pagenr); |
3601 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); | 3231 | stl_cd1400setreg(portp, CAR, (portp->portnr & 0x03)); |
@@ -3606,13 +3236,11 @@ static void stl_cd1400disableintrs(stlport_t *portp) | |||
3606 | 3236 | ||
3607 | /*****************************************************************************/ | 3237 | /*****************************************************************************/ |
3608 | 3238 | ||
3609 | static void stl_cd1400sendbreak(stlport_t *portp, int len) | 3239 | static void stl_cd1400sendbreak(struct stlport *portp, int len) |
3610 | { | 3240 | { |
3611 | unsigned long flags; | 3241 | unsigned long flags; |
3612 | 3242 | ||
3613 | #ifdef DEBUG | 3243 | pr_debug("stl_cd1400sendbreak(portp=%p,len=%d)\n", portp, len); |
3614 | printk("stl_cd1400sendbreak(portp=%x,len=%d)\n", (int) portp, len); | ||
3615 | #endif | ||
3616 | 3244 | ||
3617 | spin_lock_irqsave(&brd_lock, flags); | 3245 | spin_lock_irqsave(&brd_lock, flags); |
3618 | BRDENABLE(portp->brdnr, portp->pagenr); | 3246 | BRDENABLE(portp->brdnr, portp->pagenr); |
@@ -3633,19 +3261,17 @@ static void stl_cd1400sendbreak(stlport_t *portp, int len) | |||
3633 | * Take flow control actions... | 3261 | * Take flow control actions... |
3634 | */ | 3262 | */ |
3635 | 3263 | ||
3636 | static void stl_cd1400flowctrl(stlport_t *portp, int state) | 3264 | static void stl_cd1400flowctrl(struct stlport *portp, int state) |
3637 | { | 3265 | { |
3638 | struct tty_struct *tty; | 3266 | struct tty_struct *tty; |
3639 | unsigned long flags; | 3267 | unsigned long flags; |
3640 | 3268 | ||
3641 | #ifdef DEBUG | 3269 | pr_debug("stl_cd1400flowctrl(portp=%p,state=%x)\n", portp, state); |
3642 | printk("stl_cd1400flowctrl(portp=%x,state=%x)\n", (int) portp, state); | ||
3643 | #endif | ||
3644 | 3270 | ||
3645 | if (portp == (stlport_t *) NULL) | 3271 | if (portp == NULL) |
3646 | return; | 3272 | return; |
3647 | tty = portp->tty; | 3273 | tty = portp->tty; |
3648 | if (tty == (struct tty_struct *) NULL) | 3274 | if (tty == NULL) |
3649 | return; | 3275 | return; |
3650 | 3276 | ||
3651 | spin_lock_irqsave(&brd_lock, flags); | 3277 | spin_lock_irqsave(&brd_lock, flags); |
@@ -3697,19 +3323,17 @@ static void stl_cd1400flowctrl(stlport_t *portp, int state) | |||
3697 | * Send a flow control character... | 3323 | * Send a flow control character... |
3698 | */ | 3324 | */ |
3699 | 3325 | ||
3700 | static void stl_cd1400sendflow(stlport_t *portp, int state) | 3326 | static void stl_cd1400sendflow(struct stlport *portp, int state) |
3701 | { | 3327 | { |
3702 | struct tty_struct *tty; | 3328 | struct tty_struct *tty; |
3703 | unsigned long flags; | 3329 | unsigned long flags; |
3704 | 3330 | ||
3705 | #ifdef DEBUG | 3331 | pr_debug("stl_cd1400sendflow(portp=%p,state=%x)\n", portp, state); |
3706 | printk("stl_cd1400sendflow(portp=%x,state=%x)\n", (int) portp, state); | ||
3707 | #endif | ||
3708 | 3332 | ||
3709 | if (portp == (stlport_t *) NULL) | 3333 | if (portp == NULL) |
3710 | return; | 3334 | return; |
3711 | tty = portp->tty; | 3335 | tty = portp->tty; |
3712 | if (tty == (struct tty_struct *) NULL) | 3336 | if (tty == NULL) |
3713 | return; | 3337 | return; |
3714 | 3338 | ||
3715 | spin_lock_irqsave(&brd_lock, flags); | 3339 | spin_lock_irqsave(&brd_lock, flags); |
@@ -3732,15 +3356,13 @@ static void stl_cd1400sendflow(stlport_t *portp, int state) | |||
3732 | 3356 | ||
3733 | /*****************************************************************************/ | 3357 | /*****************************************************************************/ |
3734 | 3358 | ||
3735 | static void stl_cd1400flush(stlport_t *portp) | 3359 | static void stl_cd1400flush(struct stlport *portp) |
3736 | { | 3360 | { |
3737 | unsigned long flags; | 3361 | unsigned long flags; |
3738 | 3362 | ||
3739 | #ifdef DEBUG | 3363 | pr_debug("stl_cd1400flush(portp=%p)\n", portp); |
3740 | printk("stl_cd1400flush(portp=%x)\n", (int) portp); | ||
3741 | #endif | ||
3742 | 3364 | ||
3743 | if (portp == (stlport_t *) NULL) | 3365 | if (portp == NULL) |
3744 | return; | 3366 | return; |
3745 | 3367 | ||
3746 | spin_lock_irqsave(&brd_lock, flags); | 3368 | spin_lock_irqsave(&brd_lock, flags); |
@@ -3763,13 +3385,11 @@ static void stl_cd1400flush(stlport_t *portp) | |||
3763 | * maintains the busy port flag. | 3385 | * maintains the busy port flag. |
3764 | */ | 3386 | */ |
3765 | 3387 | ||
3766 | static int stl_cd1400datastate(stlport_t *portp) | 3388 | static int stl_cd1400datastate(struct stlport *portp) |
3767 | { | 3389 | { |
3768 | #ifdef DEBUG | 3390 | pr_debug("stl_cd1400datastate(portp=%p)\n", portp); |
3769 | printk("stl_cd1400datastate(portp=%x)\n", (int) portp); | ||
3770 | #endif | ||
3771 | 3391 | ||
3772 | if (portp == (stlport_t *) NULL) | 3392 | if (portp == NULL) |
3773 | return 0; | 3393 | return 0; |
3774 | 3394 | ||
3775 | return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0; | 3395 | return test_bit(ASYI_TXBUSY, &portp->istate) ? 1 : 0; |
@@ -3781,14 +3401,11 @@ static int stl_cd1400datastate(stlport_t *portp) | |||
3781 | * Interrupt service routine for cd1400 EasyIO boards. | 3401 | * Interrupt service routine for cd1400 EasyIO boards. |
3782 | */ | 3402 | */ |
3783 | 3403 | ||
3784 | static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | 3404 | static void stl_cd1400eiointr(struct stlpanel *panelp, unsigned int iobase) |
3785 | { | 3405 | { |
3786 | unsigned char svrtype; | 3406 | unsigned char svrtype; |
3787 | 3407 | ||
3788 | #ifdef DEBUG | 3408 | pr_debug("stl_cd1400eiointr(panelp=%p,iobase=%x)\n", panelp, iobase); |
3789 | printk("stl_cd1400eiointr(panelp=%x,iobase=%x)\n", | ||
3790 | (int) panelp, iobase); | ||
3791 | #endif | ||
3792 | 3409 | ||
3793 | spin_lock(&brd_lock); | 3410 | spin_lock(&brd_lock); |
3794 | outb(SVRR, iobase); | 3411 | outb(SVRR, iobase); |
@@ -3814,14 +3431,11 @@ static void stl_cd1400eiointr(stlpanel_t *panelp, unsigned int iobase) | |||
3814 | * Interrupt service routine for cd1400 panels. | 3431 | * Interrupt service routine for cd1400 panels. |
3815 | */ | 3432 | */ |
3816 | 3433 | ||
3817 | static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase) | 3434 | static void stl_cd1400echintr(struct stlpanel *panelp, unsigned int iobase) |
3818 | { | 3435 | { |
3819 | unsigned char svrtype; | 3436 | unsigned char svrtype; |
3820 | 3437 | ||
3821 | #ifdef DEBUG | 3438 | pr_debug("stl_cd1400echintr(panelp=%p,iobase=%x)\n", panelp, iobase); |
3822 | printk("stl_cd1400echintr(panelp=%x,iobase=%x)\n", (int) panelp, | ||
3823 | iobase); | ||
3824 | #endif | ||
3825 | 3439 | ||
3826 | outb(SVRR, iobase); | 3440 | outb(SVRR, iobase); |
3827 | svrtype = inb(iobase + EREG_DATA); | 3441 | svrtype = inb(iobase + EREG_DATA); |
@@ -3843,7 +3457,7 @@ static void stl_cd1400echintr(stlpanel_t *panelp, unsigned int iobase) | |||
3843 | * this is the only way to generate them on the cd1400. | 3457 | * this is the only way to generate them on the cd1400. |
3844 | */ | 3458 | */ |
3845 | 3459 | ||
3846 | static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr) | 3460 | static int stl_cd1400breakisr(struct stlport *portp, int ioaddr) |
3847 | { | 3461 | { |
3848 | if (portp->brklen == 1) { | 3462 | if (portp->brklen == 1) { |
3849 | outb((COR2 + portp->uartaddr), ioaddr); | 3463 | outb((COR2 + portp->uartaddr), ioaddr); |
@@ -3885,16 +3499,14 @@ static inline int stl_cd1400breakisr(stlport_t *portp, int ioaddr) | |||
3885 | * be NULL if the buffer has been freed. | 3499 | * be NULL if the buffer has been freed. |
3886 | */ | 3500 | */ |
3887 | 3501 | ||
3888 | static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr) | 3502 | static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr) |
3889 | { | 3503 | { |
3890 | stlport_t *portp; | 3504 | struct stlport *portp; |
3891 | int len, stlen; | 3505 | int len, stlen; |
3892 | char *head, *tail; | 3506 | char *head, *tail; |
3893 | unsigned char ioack, srer; | 3507 | unsigned char ioack, srer; |
3894 | 3508 | ||
3895 | #ifdef DEBUG | 3509 | pr_debug("stl_cd1400txisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); |
3896 | printk("stl_cd1400txisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr); | ||
3897 | #endif | ||
3898 | 3510 | ||
3899 | ioack = inb(ioaddr + EREG_TXACK); | 3511 | ioack = inb(ioaddr + EREG_TXACK); |
3900 | if (((ioack & panelp->ackmask) != 0) || | 3512 | if (((ioack & panelp->ackmask) != 0) || |
@@ -3933,9 +3545,9 @@ static void stl_cd1400txisr(stlpanel_t *panelp, int ioaddr) | |||
3933 | } | 3545 | } |
3934 | outb(srer, (ioaddr + EREG_DATA)); | 3546 | outb(srer, (ioaddr + EREG_DATA)); |
3935 | } else { | 3547 | } else { |
3936 | len = MIN(len, CD1400_TXFIFOSIZE); | 3548 | len = min(len, CD1400_TXFIFOSIZE); |
3937 | portp->stats.txtotal += len; | 3549 | portp->stats.txtotal += len; |
3938 | stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail)); | 3550 | stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail)); |
3939 | outb((TDR + portp->uartaddr), ioaddr); | 3551 | outb((TDR + portp->uartaddr), ioaddr); |
3940 | outsb((ioaddr + EREG_DATA), tail, stlen); | 3552 | outsb((ioaddr + EREG_DATA), tail, stlen); |
3941 | len -= stlen; | 3553 | len -= stlen; |
@@ -3966,17 +3578,15 @@ stl_txalldone: | |||
3966 | * shutdown a port not in user context. Need to handle this case. | 3578 | * shutdown a port not in user context. Need to handle this case. |
3967 | */ | 3579 | */ |
3968 | 3580 | ||
3969 | static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | 3581 | static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr) |
3970 | { | 3582 | { |
3971 | stlport_t *portp; | 3583 | struct stlport *portp; |
3972 | struct tty_struct *tty; | 3584 | struct tty_struct *tty; |
3973 | unsigned int ioack, len, buflen; | 3585 | unsigned int ioack, len, buflen; |
3974 | unsigned char status; | 3586 | unsigned char status; |
3975 | char ch; | 3587 | char ch; |
3976 | 3588 | ||
3977 | #ifdef DEBUG | 3589 | pr_debug("stl_cd1400rxisr(panelp=%p,ioaddr=%x)\n", panelp, ioaddr); |
3978 | printk("stl_cd1400rxisr(panelp=%x,ioaddr=%x)\n", (int) panelp, ioaddr); | ||
3979 | #endif | ||
3980 | 3590 | ||
3981 | ioack = inb(ioaddr + EREG_RXACK); | 3591 | ioack = inb(ioaddr + EREG_RXACK); |
3982 | if ((ioack & panelp->ackmask) != 0) { | 3592 | if ((ioack & panelp->ackmask) != 0) { |
@@ -3990,13 +3600,13 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
3990 | outb((RDCR + portp->uartaddr), ioaddr); | 3600 | outb((RDCR + portp->uartaddr), ioaddr); |
3991 | len = inb(ioaddr + EREG_DATA); | 3601 | len = inb(ioaddr + EREG_DATA); |
3992 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { | 3602 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { |
3993 | len = MIN(len, sizeof(stl_unwanted)); | 3603 | len = min(len, sizeof(stl_unwanted)); |
3994 | outb((RDSR + portp->uartaddr), ioaddr); | 3604 | outb((RDSR + portp->uartaddr), ioaddr); |
3995 | insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); | 3605 | insb((ioaddr + EREG_DATA), &stl_unwanted[0], len); |
3996 | portp->stats.rxlost += len; | 3606 | portp->stats.rxlost += len; |
3997 | portp->stats.rxtotal += len; | 3607 | portp->stats.rxtotal += len; |
3998 | } else { | 3608 | } else { |
3999 | len = MIN(len, buflen); | 3609 | len = min(len, buflen); |
4000 | if (len > 0) { | 3610 | if (len > 0) { |
4001 | unsigned char *ptr; | 3611 | unsigned char *ptr; |
4002 | outb((RDSR + portp->uartaddr), ioaddr); | 3612 | outb((RDSR + portp->uartaddr), ioaddr); |
@@ -4033,18 +3643,16 @@ static void stl_cd1400rxisr(stlpanel_t *panelp, int ioaddr) | |||
4033 | do_SAK(tty); | 3643 | do_SAK(tty); |
4034 | BRDENABLE(portp->brdnr, portp->pagenr); | 3644 | BRDENABLE(portp->brdnr, portp->pagenr); |
4035 | } | 3645 | } |
4036 | } else if (status & ST_PARITY) { | 3646 | } else if (status & ST_PARITY) |
4037 | status = TTY_PARITY; | 3647 | status = TTY_PARITY; |
4038 | } else if (status & ST_FRAMING) { | 3648 | else if (status & ST_FRAMING) |
4039 | status = TTY_FRAME; | 3649 | status = TTY_FRAME; |
4040 | } else if(status & ST_OVERRUN) { | 3650 | else if(status & ST_OVERRUN) |
4041 | status = TTY_OVERRUN; | 3651 | status = TTY_OVERRUN; |
4042 | } else { | 3652 | else |
4043 | status = 0; | 3653 | status = 0; |
4044 | } | 3654 | } else |
4045 | } else { | ||
4046 | status = 0; | 3655 | status = 0; |
4047 | } | ||
4048 | tty_insert_flip_char(tty, ch, status); | 3656 | tty_insert_flip_char(tty, ch, status); |
4049 | tty_schedule_flip(tty); | 3657 | tty_schedule_flip(tty); |
4050 | } | 3658 | } |
@@ -4066,15 +3674,13 @@ stl_rxalldone: | |||
4066 | * processing routine. | 3674 | * processing routine. |
4067 | */ | 3675 | */ |
4068 | 3676 | ||
4069 | static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr) | 3677 | static void stl_cd1400mdmisr(struct stlpanel *panelp, int ioaddr) |
4070 | { | 3678 | { |
4071 | stlport_t *portp; | 3679 | struct stlport *portp; |
4072 | unsigned int ioack; | 3680 | unsigned int ioack; |
4073 | unsigned char misr; | 3681 | unsigned char misr; |
4074 | 3682 | ||
4075 | #ifdef DEBUG | 3683 | pr_debug("stl_cd1400mdmisr(panelp=%p)\n", panelp); |
4076 | printk("stl_cd1400mdmisr(panelp=%x)\n", (int) panelp); | ||
4077 | #endif | ||
4078 | 3684 | ||
4079 | ioack = inb(ioaddr + EREG_MDACK); | 3685 | ioack = inb(ioaddr + EREG_MDACK); |
4080 | if (((ioack & panelp->ackmask) != 0) || | 3686 | if (((ioack & panelp->ackmask) != 0) || |
@@ -4106,19 +3712,19 @@ static void stl_cd1400mdmisr(stlpanel_t *panelp, int ioaddr) | |||
4106 | * (Maybe should make this inline...) | 3712 | * (Maybe should make this inline...) |
4107 | */ | 3713 | */ |
4108 | 3714 | ||
4109 | static int stl_sc26198getreg(stlport_t *portp, int regnr) | 3715 | static int stl_sc26198getreg(struct stlport *portp, int regnr) |
4110 | { | 3716 | { |
4111 | outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); | 3717 | outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); |
4112 | return inb(portp->ioaddr + XP_DATA); | 3718 | return inb(portp->ioaddr + XP_DATA); |
4113 | } | 3719 | } |
4114 | 3720 | ||
4115 | static void stl_sc26198setreg(stlport_t *portp, int regnr, int value) | 3721 | static void stl_sc26198setreg(struct stlport *portp, int regnr, int value) |
4116 | { | 3722 | { |
4117 | outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); | 3723 | outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); |
4118 | outb(value, (portp->ioaddr + XP_DATA)); | 3724 | outb(value, (portp->ioaddr + XP_DATA)); |
4119 | } | 3725 | } |
4120 | 3726 | ||
4121 | static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value) | 3727 | static int stl_sc26198updatereg(struct stlport *portp, int regnr, int value) |
4122 | { | 3728 | { |
4123 | outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); | 3729 | outb((regnr | portp->uartaddr), (portp->ioaddr + XP_ADDR)); |
4124 | if (inb(portp->ioaddr + XP_DATA) != value) { | 3730 | if (inb(portp->ioaddr + XP_DATA) != value) { |
@@ -4134,14 +3740,14 @@ static int stl_sc26198updatereg(stlport_t *portp, int regnr, int value) | |||
4134 | * Functions to get and set the sc26198 global registers. | 3740 | * Functions to get and set the sc26198 global registers. |
4135 | */ | 3741 | */ |
4136 | 3742 | ||
4137 | static int stl_sc26198getglobreg(stlport_t *portp, int regnr) | 3743 | static int stl_sc26198getglobreg(struct stlport *portp, int regnr) |
4138 | { | 3744 | { |
4139 | outb(regnr, (portp->ioaddr + XP_ADDR)); | 3745 | outb(regnr, (portp->ioaddr + XP_ADDR)); |
4140 | return inb(portp->ioaddr + XP_DATA); | 3746 | return inb(portp->ioaddr + XP_DATA); |
4141 | } | 3747 | } |
4142 | 3748 | ||
4143 | #if 0 | 3749 | #if 0 |
4144 | static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value) | 3750 | static void stl_sc26198setglobreg(struct stlport *portp, int regnr, int value) |
4145 | { | 3751 | { |
4146 | outb(regnr, (portp->ioaddr + XP_ADDR)); | 3752 | outb(regnr, (portp->ioaddr + XP_ADDR)); |
4147 | outb(value, (portp->ioaddr + XP_DATA)); | 3753 | outb(value, (portp->ioaddr + XP_DATA)); |
@@ -4156,15 +3762,12 @@ static void stl_sc26198setglobreg(stlport_t *portp, int regnr, int value) | |||
4156 | * identical when dealing with ports. | 3762 | * identical when dealing with ports. |
4157 | */ | 3763 | */ |
4158 | 3764 | ||
4159 | static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | 3765 | static int stl_sc26198panelinit(struct stlbrd *brdp, struct stlpanel *panelp) |
4160 | { | 3766 | { |
4161 | int chipmask, i; | 3767 | int chipmask, i; |
4162 | int nrchips, ioaddr; | 3768 | int nrchips, ioaddr; |
4163 | 3769 | ||
4164 | #ifdef DEBUG | 3770 | pr_debug("stl_sc26198panelinit(brdp=%p,panelp=%p)\n", brdp, panelp); |
4165 | printk("stl_sc26198panelinit(brdp=%x,panelp=%x)\n", | ||
4166 | (int) brdp, (int) panelp); | ||
4167 | #endif | ||
4168 | 3771 | ||
4169 | BRDENABLE(panelp->brdnr, panelp->pagenr); | 3772 | BRDENABLE(panelp->brdnr, panelp->pagenr); |
4170 | 3773 | ||
@@ -4176,7 +3779,7 @@ static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
4176 | if (brdp->brdtype == BRD_ECHPCI) | 3779 | if (brdp->brdtype == BRD_ECHPCI) |
4177 | outb(panelp->pagenr, brdp->ioctrl); | 3780 | outb(panelp->pagenr, brdp->ioctrl); |
4178 | 3781 | ||
4179 | for (i = 0; (i < nrchips); i++) { | 3782 | for (i = 0; i < nrchips; i++) { |
4180 | ioaddr = panelp->iobase + (i * 4); | 3783 | ioaddr = panelp->iobase + (i * 4); |
4181 | outb(SCCR, (ioaddr + XP_ADDR)); | 3784 | outb(SCCR, (ioaddr + XP_ADDR)); |
4182 | outb(CR_RESETALL, (ioaddr + XP_DATA)); | 3785 | outb(CR_RESETALL, (ioaddr + XP_DATA)); |
@@ -4204,15 +3807,13 @@ static int stl_sc26198panelinit(stlbrd_t *brdp, stlpanel_t *panelp) | |||
4204 | * Initialize hardware specific port registers. | 3807 | * Initialize hardware specific port registers. |
4205 | */ | 3808 | */ |
4206 | 3809 | ||
4207 | static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *portp) | 3810 | static void stl_sc26198portinit(struct stlbrd *brdp, struct stlpanel *panelp, struct stlport *portp) |
4208 | { | 3811 | { |
4209 | #ifdef DEBUG | 3812 | pr_debug("stl_sc26198portinit(brdp=%p,panelp=%p,portp=%p)\n", brdp, |
4210 | printk("stl_sc26198portinit(brdp=%x,panelp=%x,portp=%x)\n", | 3813 | panelp, portp); |
4211 | (int) brdp, (int) panelp, (int) portp); | ||
4212 | #endif | ||
4213 | 3814 | ||
4214 | if ((brdp == (stlbrd_t *) NULL) || (panelp == (stlpanel_t *) NULL) || | 3815 | if ((brdp == NULL) || (panelp == NULL) || |
4215 | (portp == (stlport_t *) NULL)) | 3816 | (portp == NULL)) |
4216 | return; | 3817 | return; |
4217 | 3818 | ||
4218 | portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4); | 3819 | portp->ioaddr = panelp->iobase + ((portp->portnr < 8) ? 0 : 4); |
@@ -4232,9 +3833,9 @@ static void stl_sc26198portinit(stlbrd_t *brdp, stlpanel_t *panelp, stlport_t *p | |||
4232 | * settings. | 3833 | * settings. |
4233 | */ | 3834 | */ |
4234 | 3835 | ||
4235 | static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | 3836 | static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp) |
4236 | { | 3837 | { |
4237 | stlbrd_t *brdp; | 3838 | struct stlbrd *brdp; |
4238 | unsigned long flags; | 3839 | unsigned long flags; |
4239 | unsigned int baudrate; | 3840 | unsigned int baudrate; |
4240 | unsigned char mr0, mr1, mr2, clk; | 3841 | unsigned char mr0, mr1, mr2, clk; |
@@ -4249,7 +3850,7 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4249 | imroff = 0; | 3850 | imroff = 0; |
4250 | 3851 | ||
4251 | brdp = stl_brds[portp->brdnr]; | 3852 | brdp = stl_brds[portp->brdnr]; |
4252 | if (brdp == (stlbrd_t *) NULL) | 3853 | if (brdp == NULL) |
4253 | return; | 3854 | return; |
4254 | 3855 | ||
4255 | /* | 3856 | /* |
@@ -4298,9 +3899,8 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4298 | mr1 |= (MR1_PARENB | MR1_PARODD); | 3899 | mr1 |= (MR1_PARENB | MR1_PARODD); |
4299 | else | 3900 | else |
4300 | mr1 |= (MR1_PARENB | MR1_PAREVEN); | 3901 | mr1 |= (MR1_PARENB | MR1_PAREVEN); |
4301 | } else { | 3902 | } else |
4302 | mr1 |= MR1_PARNONE; | 3903 | mr1 |= MR1_PARNONE; |
4303 | } | ||
4304 | 3904 | ||
4305 | mr1 |= MR1_ERRBLOCK; | 3905 | mr1 |= MR1_ERRBLOCK; |
4306 | 3906 | ||
@@ -4340,12 +3940,10 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4340 | if (baudrate > STL_SC26198MAXBAUD) | 3940 | if (baudrate > STL_SC26198MAXBAUD) |
4341 | baudrate = STL_SC26198MAXBAUD; | 3941 | baudrate = STL_SC26198MAXBAUD; |
4342 | 3942 | ||
4343 | if (baudrate > 0) { | 3943 | if (baudrate > 0) |
4344 | for (clk = 0; (clk < SC26198_NRBAUDS); clk++) { | 3944 | for (clk = 0; clk < SC26198_NRBAUDS; clk++) |
4345 | if (baudrate <= sc26198_baudtable[clk]) | 3945 | if (baudrate <= sc26198_baudtable[clk]) |
4346 | break; | 3946 | break; |
4347 | } | ||
4348 | } | ||
4349 | 3947 | ||
4350 | /* | 3948 | /* |
4351 | * Check what form of modem signaling is required and set it up. | 3949 | * Check what form of modem signaling is required and set it up. |
@@ -4367,9 +3965,9 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4367 | if (tiosp->c_iflag & IXON) { | 3965 | if (tiosp->c_iflag & IXON) { |
4368 | mr0 |= MR0_SWFTX | MR0_SWFT; | 3966 | mr0 |= MR0_SWFTX | MR0_SWFT; |
4369 | imron |= IR_XONXOFF; | 3967 | imron |= IR_XONXOFF; |
4370 | } else { | 3968 | } else |
4371 | imroff |= IR_XONXOFF; | 3969 | imroff |= IR_XONXOFF; |
4372 | } | 3970 | |
4373 | if (tiosp->c_iflag & IXOFF) | 3971 | if (tiosp->c_iflag & IXOFF) |
4374 | mr0 |= MR0_SWFRX; | 3972 | mr0 |= MR0_SWFRX; |
4375 | 3973 | ||
@@ -4383,15 +3981,13 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4383 | * them all up. | 3981 | * them all up. |
4384 | */ | 3982 | */ |
4385 | 3983 | ||
4386 | #ifdef DEBUG | 3984 | pr_debug("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", |
4387 | printk("SETPORT: portnr=%d panelnr=%d brdnr=%d\n", | ||
4388 | portp->portnr, portp->panelnr, portp->brdnr); | 3985 | portp->portnr, portp->panelnr, portp->brdnr); |
4389 | printk(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk); | 3986 | pr_debug(" mr0=%x mr1=%x mr2=%x clk=%x\n", mr0, mr1, mr2, clk); |
4390 | printk(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff); | 3987 | pr_debug(" iopr=%x imron=%x imroff=%x\n", iopr, imron, imroff); |
4391 | printk(" schr1=%x schr2=%x schr3=%x schr4=%x\n", | 3988 | pr_debug(" schr1=%x schr2=%x schr3=%x schr4=%x\n", |
4392 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], | 3989 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP], |
4393 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); | 3990 | tiosp->c_cc[VSTART], tiosp->c_cc[VSTOP]); |
4394 | #endif | ||
4395 | 3991 | ||
4396 | spin_lock_irqsave(&brd_lock, flags); | 3992 | spin_lock_irqsave(&brd_lock, flags); |
4397 | BRDENABLE(portp->brdnr, portp->pagenr); | 3993 | BRDENABLE(portp->brdnr, portp->pagenr); |
@@ -4429,15 +4025,13 @@ static void stl_sc26198setport(stlport_t *portp, struct termios *tiosp) | |||
4429 | * Set the state of the DTR and RTS signals. | 4025 | * Set the state of the DTR and RTS signals. |
4430 | */ | 4026 | */ |
4431 | 4027 | ||
4432 | static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | 4028 | static void stl_sc26198setsignals(struct stlport *portp, int dtr, int rts) |
4433 | { | 4029 | { |
4434 | unsigned char iopioron, iopioroff; | 4030 | unsigned char iopioron, iopioroff; |
4435 | unsigned long flags; | 4031 | unsigned long flags; |
4436 | 4032 | ||
4437 | #ifdef DEBUG | 4033 | pr_debug("stl_sc26198setsignals(portp=%p,dtr=%d,rts=%d)\n", portp, |
4438 | printk("stl_sc26198setsignals(portp=%x,dtr=%d,rts=%d)\n", | 4034 | dtr, rts); |
4439 | (int) portp, dtr, rts); | ||
4440 | #endif | ||
4441 | 4035 | ||
4442 | iopioron = 0; | 4036 | iopioron = 0; |
4443 | iopioroff = 0; | 4037 | iopioroff = 0; |
@@ -4464,15 +4058,13 @@ static void stl_sc26198setsignals(stlport_t *portp, int dtr, int rts) | |||
4464 | * Return the state of the signals. | 4058 | * Return the state of the signals. |
4465 | */ | 4059 | */ |
4466 | 4060 | ||
4467 | static int stl_sc26198getsignals(stlport_t *portp) | 4061 | static int stl_sc26198getsignals(struct stlport *portp) |
4468 | { | 4062 | { |
4469 | unsigned char ipr; | 4063 | unsigned char ipr; |
4470 | unsigned long flags; | 4064 | unsigned long flags; |
4471 | int sigs; | 4065 | int sigs; |
4472 | 4066 | ||
4473 | #ifdef DEBUG | 4067 | pr_debug("stl_sc26198getsignals(portp=%p)\n", portp); |
4474 | printk("stl_sc26198getsignals(portp=%x)\n", (int) portp); | ||
4475 | #endif | ||
4476 | 4068 | ||
4477 | spin_lock_irqsave(&brd_lock, flags); | 4069 | spin_lock_irqsave(&brd_lock, flags); |
4478 | BRDENABLE(portp->brdnr, portp->pagenr); | 4070 | BRDENABLE(portp->brdnr, portp->pagenr); |
@@ -4495,15 +4087,12 @@ static int stl_sc26198getsignals(stlport_t *portp) | |||
4495 | * Enable/Disable the Transmitter and/or Receiver. | 4087 | * Enable/Disable the Transmitter and/or Receiver. |
4496 | */ | 4088 | */ |
4497 | 4089 | ||
4498 | static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | 4090 | static void stl_sc26198enablerxtx(struct stlport *portp, int rx, int tx) |
4499 | { | 4091 | { |
4500 | unsigned char ccr; | 4092 | unsigned char ccr; |
4501 | unsigned long flags; | 4093 | unsigned long flags; |
4502 | 4094 | ||
4503 | #ifdef DEBUG | 4095 | pr_debug("stl_sc26198enablerxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx,tx); |
4504 | printk("stl_sc26198enablerxtx(portp=%x,rx=%d,tx=%d)\n", | ||
4505 | (int) portp, rx, tx); | ||
4506 | #endif | ||
4507 | 4096 | ||
4508 | ccr = portp->crenable; | 4097 | ccr = portp->crenable; |
4509 | if (tx == 0) | 4098 | if (tx == 0) |
@@ -4529,15 +4118,12 @@ static void stl_sc26198enablerxtx(stlport_t *portp, int rx, int tx) | |||
4529 | * Start/stop the Transmitter and/or Receiver. | 4118 | * Start/stop the Transmitter and/or Receiver. |
4530 | */ | 4119 | */ |
4531 | 4120 | ||
4532 | static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | 4121 | static void stl_sc26198startrxtx(struct stlport *portp, int rx, int tx) |
4533 | { | 4122 | { |
4534 | unsigned char imr; | 4123 | unsigned char imr; |
4535 | unsigned long flags; | 4124 | unsigned long flags; |
4536 | 4125 | ||
4537 | #ifdef DEBUG | 4126 | pr_debug("stl_sc26198startrxtx(portp=%p,rx=%d,tx=%d)\n", portp, rx, tx); |
4538 | printk("stl_sc26198startrxtx(portp=%x,rx=%d,tx=%d)\n", | ||
4539 | (int) portp, rx, tx); | ||
4540 | #endif | ||
4541 | 4127 | ||
4542 | imr = portp->imr; | 4128 | imr = portp->imr; |
4543 | if (tx == 0) | 4129 | if (tx == 0) |
@@ -4565,13 +4151,11 @@ static void stl_sc26198startrxtx(stlport_t *portp, int rx, int tx) | |||
4565 | * Disable all interrupts from this port. | 4151 | * Disable all interrupts from this port. |
4566 | */ | 4152 | */ |
4567 | 4153 | ||
4568 | static void stl_sc26198disableintrs(stlport_t *portp) | 4154 | static void stl_sc26198disableintrs(struct stlport *portp) |
4569 | { | 4155 | { |
4570 | unsigned long flags; | 4156 | unsigned long flags; |
4571 | 4157 | ||
4572 | #ifdef DEBUG | 4158 | pr_debug("stl_sc26198disableintrs(portp=%p)\n", portp); |
4573 | printk("stl_sc26198disableintrs(portp=%x)\n", (int) portp); | ||
4574 | #endif | ||
4575 | 4159 | ||
4576 | spin_lock_irqsave(&brd_lock, flags); | 4160 | spin_lock_irqsave(&brd_lock, flags); |
4577 | BRDENABLE(portp->brdnr, portp->pagenr); | 4161 | BRDENABLE(portp->brdnr, portp->pagenr); |
@@ -4583,22 +4167,20 @@ static void stl_sc26198disableintrs(stlport_t *portp) | |||
4583 | 4167 | ||
4584 | /*****************************************************************************/ | 4168 | /*****************************************************************************/ |
4585 | 4169 | ||
4586 | static void stl_sc26198sendbreak(stlport_t *portp, int len) | 4170 | static void stl_sc26198sendbreak(struct stlport *portp, int len) |
4587 | { | 4171 | { |
4588 | unsigned long flags; | 4172 | unsigned long flags; |
4589 | 4173 | ||
4590 | #ifdef DEBUG | 4174 | pr_debug("stl_sc26198sendbreak(portp=%p,len=%d)\n", portp, len); |
4591 | printk("stl_sc26198sendbreak(portp=%x,len=%d)\n", (int) portp, len); | ||
4592 | #endif | ||
4593 | 4175 | ||
4594 | spin_lock_irqsave(&brd_lock, flags); | 4176 | spin_lock_irqsave(&brd_lock, flags); |
4595 | BRDENABLE(portp->brdnr, portp->pagenr); | 4177 | BRDENABLE(portp->brdnr, portp->pagenr); |
4596 | if (len == 1) { | 4178 | if (len == 1) { |
4597 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); | 4179 | stl_sc26198setreg(portp, SCCR, CR_TXSTARTBREAK); |
4598 | portp->stats.txbreaks++; | 4180 | portp->stats.txbreaks++; |
4599 | } else { | 4181 | } else |
4600 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); | 4182 | stl_sc26198setreg(portp, SCCR, CR_TXSTOPBREAK); |
4601 | } | 4183 | |
4602 | BRDDISABLE(portp->brdnr); | 4184 | BRDDISABLE(portp->brdnr); |
4603 | spin_unlock_irqrestore(&brd_lock, flags); | 4185 | spin_unlock_irqrestore(&brd_lock, flags); |
4604 | } | 4186 | } |
@@ -4609,20 +4191,18 @@ static void stl_sc26198sendbreak(stlport_t *portp, int len) | |||
4609 | * Take flow control actions... | 4191 | * Take flow control actions... |
4610 | */ | 4192 | */ |
4611 | 4193 | ||
4612 | static void stl_sc26198flowctrl(stlport_t *portp, int state) | 4194 | static void stl_sc26198flowctrl(struct stlport *portp, int state) |
4613 | { | 4195 | { |
4614 | struct tty_struct *tty; | 4196 | struct tty_struct *tty; |
4615 | unsigned long flags; | 4197 | unsigned long flags; |
4616 | unsigned char mr0; | 4198 | unsigned char mr0; |
4617 | 4199 | ||
4618 | #ifdef DEBUG | 4200 | pr_debug("stl_sc26198flowctrl(portp=%p,state=%x)\n", portp, state); |
4619 | printk("stl_sc26198flowctrl(portp=%x,state=%x)\n", (int) portp, state); | ||
4620 | #endif | ||
4621 | 4201 | ||
4622 | if (portp == (stlport_t *) NULL) | 4202 | if (portp == NULL) |
4623 | return; | 4203 | return; |
4624 | tty = portp->tty; | 4204 | tty = portp->tty; |
4625 | if (tty == (struct tty_struct *) NULL) | 4205 | if (tty == NULL) |
4626 | return; | 4206 | return; |
4627 | 4207 | ||
4628 | spin_lock_irqsave(&brd_lock, flags); | 4208 | spin_lock_irqsave(&brd_lock, flags); |
@@ -4680,20 +4260,18 @@ static void stl_sc26198flowctrl(stlport_t *portp, int state) | |||
4680 | * Send a flow control character. | 4260 | * Send a flow control character. |
4681 | */ | 4261 | */ |
4682 | 4262 | ||
4683 | static void stl_sc26198sendflow(stlport_t *portp, int state) | 4263 | static void stl_sc26198sendflow(struct stlport *portp, int state) |
4684 | { | 4264 | { |
4685 | struct tty_struct *tty; | 4265 | struct tty_struct *tty; |
4686 | unsigned long flags; | 4266 | unsigned long flags; |
4687 | unsigned char mr0; | 4267 | unsigned char mr0; |
4688 | 4268 | ||
4689 | #ifdef DEBUG | 4269 | pr_debug("stl_sc26198sendflow(portp=%p,state=%x)\n", portp, state); |
4690 | printk("stl_sc26198sendflow(portp=%x,state=%x)\n", (int) portp, state); | ||
4691 | #endif | ||
4692 | 4270 | ||
4693 | if (portp == (stlport_t *) NULL) | 4271 | if (portp == NULL) |
4694 | return; | 4272 | return; |
4695 | tty = portp->tty; | 4273 | tty = portp->tty; |
4696 | if (tty == (struct tty_struct *) NULL) | 4274 | if (tty == NULL) |
4697 | return; | 4275 | return; |
4698 | 4276 | ||
4699 | spin_lock_irqsave(&brd_lock, flags); | 4277 | spin_lock_irqsave(&brd_lock, flags); |
@@ -4721,15 +4299,13 @@ static void stl_sc26198sendflow(stlport_t *portp, int state) | |||
4721 | 4299 | ||
4722 | /*****************************************************************************/ | 4300 | /*****************************************************************************/ |
4723 | 4301 | ||
4724 | static void stl_sc26198flush(stlport_t *portp) | 4302 | static void stl_sc26198flush(struct stlport *portp) |
4725 | { | 4303 | { |
4726 | unsigned long flags; | 4304 | unsigned long flags; |
4727 | 4305 | ||
4728 | #ifdef DEBUG | 4306 | pr_debug("stl_sc26198flush(portp=%p)\n", portp); |
4729 | printk("stl_sc26198flush(portp=%x)\n", (int) portp); | ||
4730 | #endif | ||
4731 | 4307 | ||
4732 | if (portp == (stlport_t *) NULL) | 4308 | if (portp == NULL) |
4733 | return; | 4309 | return; |
4734 | 4310 | ||
4735 | spin_lock_irqsave(&brd_lock, flags); | 4311 | spin_lock_irqsave(&brd_lock, flags); |
@@ -4751,16 +4327,14 @@ static void stl_sc26198flush(stlport_t *portp) | |||
4751 | * check the port statusy register to be sure. | 4327 | * check the port statusy register to be sure. |
4752 | */ | 4328 | */ |
4753 | 4329 | ||
4754 | static int stl_sc26198datastate(stlport_t *portp) | 4330 | static int stl_sc26198datastate(struct stlport *portp) |
4755 | { | 4331 | { |
4756 | unsigned long flags; | 4332 | unsigned long flags; |
4757 | unsigned char sr; | 4333 | unsigned char sr; |
4758 | 4334 | ||
4759 | #ifdef DEBUG | 4335 | pr_debug("stl_sc26198datastate(portp=%p)\n", portp); |
4760 | printk("stl_sc26198datastate(portp=%x)\n", (int) portp); | ||
4761 | #endif | ||
4762 | 4336 | ||
4763 | if (portp == (stlport_t *) NULL) | 4337 | if (portp == NULL) |
4764 | return 0; | 4338 | return 0; |
4765 | if (test_bit(ASYI_TXBUSY, &portp->istate)) | 4339 | if (test_bit(ASYI_TXBUSY, &portp->istate)) |
4766 | return 1; | 4340 | return 1; |
@@ -4781,18 +4355,16 @@ static int stl_sc26198datastate(stlport_t *portp) | |||
4781 | * to process a command... | 4355 | * to process a command... |
4782 | */ | 4356 | */ |
4783 | 4357 | ||
4784 | static void stl_sc26198wait(stlport_t *portp) | 4358 | static void stl_sc26198wait(struct stlport *portp) |
4785 | { | 4359 | { |
4786 | int i; | 4360 | int i; |
4787 | 4361 | ||
4788 | #ifdef DEBUG | 4362 | pr_debug("stl_sc26198wait(portp=%p)\n", portp); |
4789 | printk("stl_sc26198wait(portp=%x)\n", (int) portp); | ||
4790 | #endif | ||
4791 | 4363 | ||
4792 | if (portp == (stlport_t *) NULL) | 4364 | if (portp == NULL) |
4793 | return; | 4365 | return; |
4794 | 4366 | ||
4795 | for (i = 0; (i < 20); i++) | 4367 | for (i = 0; i < 20; i++) |
4796 | stl_sc26198getglobreg(portp, TSTR); | 4368 | stl_sc26198getglobreg(portp, TSTR); |
4797 | } | 4369 | } |
4798 | 4370 | ||
@@ -4804,7 +4376,7 @@ static void stl_sc26198wait(stlport_t *portp) | |||
4804 | * automatic flow control modes of the sc26198. | 4376 | * automatic flow control modes of the sc26198. |
4805 | */ | 4377 | */ |
4806 | 4378 | ||
4807 | static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty) | 4379 | static void stl_sc26198txunflow(struct stlport *portp, struct tty_struct *tty) |
4808 | { | 4380 | { |
4809 | unsigned char mr0; | 4381 | unsigned char mr0; |
4810 | 4382 | ||
@@ -4822,9 +4394,9 @@ static inline void stl_sc26198txunflow(stlport_t *portp, struct tty_struct *tty) | |||
4822 | * Interrupt service routine for sc26198 panels. | 4394 | * Interrupt service routine for sc26198 panels. |
4823 | */ | 4395 | */ |
4824 | 4396 | ||
4825 | static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | 4397 | static void stl_sc26198intr(struct stlpanel *panelp, unsigned int iobase) |
4826 | { | 4398 | { |
4827 | stlport_t *portp; | 4399 | struct stlport *portp; |
4828 | unsigned int iack; | 4400 | unsigned int iack; |
4829 | 4401 | ||
4830 | spin_lock(&brd_lock); | 4402 | spin_lock(&brd_lock); |
@@ -4860,16 +4432,14 @@ static void stl_sc26198intr(stlpanel_t *panelp, unsigned int iobase) | |||
4860 | * be NULL if the buffer has been freed. | 4432 | * be NULL if the buffer has been freed. |
4861 | */ | 4433 | */ |
4862 | 4434 | ||
4863 | static void stl_sc26198txisr(stlport_t *portp) | 4435 | static void stl_sc26198txisr(struct stlport *portp) |
4864 | { | 4436 | { |
4865 | unsigned int ioaddr; | 4437 | unsigned int ioaddr; |
4866 | unsigned char mr0; | 4438 | unsigned char mr0; |
4867 | int len, stlen; | 4439 | int len, stlen; |
4868 | char *head, *tail; | 4440 | char *head, *tail; |
4869 | 4441 | ||
4870 | #ifdef DEBUG | 4442 | pr_debug("stl_sc26198txisr(portp=%p)\n", portp); |
4871 | printk("stl_sc26198txisr(portp=%x)\n", (int) portp); | ||
4872 | #endif | ||
4873 | 4443 | ||
4874 | ioaddr = portp->ioaddr; | 4444 | ioaddr = portp->ioaddr; |
4875 | head = portp->tx.head; | 4445 | head = portp->tx.head; |
@@ -4894,9 +4464,9 @@ static void stl_sc26198txisr(stlport_t *portp) | |||
4894 | outb(mr0, (ioaddr + XP_DATA)); | 4464 | outb(mr0, (ioaddr + XP_DATA)); |
4895 | } | 4465 | } |
4896 | } else { | 4466 | } else { |
4897 | len = MIN(len, SC26198_TXFIFOSIZE); | 4467 | len = min(len, SC26198_TXFIFOSIZE); |
4898 | portp->stats.txtotal += len; | 4468 | portp->stats.txtotal += len; |
4899 | stlen = MIN(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail)); | 4469 | stlen = min(len, ((portp->tx.buf + STL_TXBUFSIZE) - tail)); |
4900 | outb(GTXFIFO, (ioaddr + XP_ADDR)); | 4470 | outb(GTXFIFO, (ioaddr + XP_ADDR)); |
4901 | outsb((ioaddr + XP_DATA), tail, stlen); | 4471 | outsb((ioaddr + XP_DATA), tail, stlen); |
4902 | len -= stlen; | 4472 | len -= stlen; |
@@ -4923,14 +4493,12 @@ static void stl_sc26198txisr(stlport_t *portp) | |||
4923 | * shutdown a port not in user context. Need to handle this case. | 4493 | * shutdown a port not in user context. Need to handle this case. |
4924 | */ | 4494 | */ |
4925 | 4495 | ||
4926 | static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | 4496 | static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack) |
4927 | { | 4497 | { |
4928 | struct tty_struct *tty; | 4498 | struct tty_struct *tty; |
4929 | unsigned int len, buflen, ioaddr; | 4499 | unsigned int len, buflen, ioaddr; |
4930 | 4500 | ||
4931 | #ifdef DEBUG | 4501 | pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); |
4932 | printk("stl_sc26198rxisr(portp=%x,iack=%x)\n", (int) portp, iack); | ||
4933 | #endif | ||
4934 | 4502 | ||
4935 | tty = portp->tty; | 4503 | tty = portp->tty; |
4936 | ioaddr = portp->ioaddr; | 4504 | ioaddr = portp->ioaddr; |
@@ -4939,13 +4507,13 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
4939 | 4507 | ||
4940 | if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { | 4508 | if ((iack & IVR_TYPEMASK) == IVR_RXDATA) { |
4941 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { | 4509 | if (tty == NULL || (buflen = tty_buffer_request_room(tty, len)) == 0) { |
4942 | len = MIN(len, sizeof(stl_unwanted)); | 4510 | len = min(len, sizeof(stl_unwanted)); |
4943 | outb(GRXFIFO, (ioaddr + XP_ADDR)); | 4511 | outb(GRXFIFO, (ioaddr + XP_ADDR)); |
4944 | insb((ioaddr + XP_DATA), &stl_unwanted[0], len); | 4512 | insb((ioaddr + XP_DATA), &stl_unwanted[0], len); |
4945 | portp->stats.rxlost += len; | 4513 | portp->stats.rxlost += len; |
4946 | portp->stats.rxtotal += len; | 4514 | portp->stats.rxtotal += len; |
4947 | } else { | 4515 | } else { |
4948 | len = MIN(len, buflen); | 4516 | len = min(len, buflen); |
4949 | if (len > 0) { | 4517 | if (len > 0) { |
4950 | unsigned char *ptr; | 4518 | unsigned char *ptr; |
4951 | outb(GRXFIFO, (ioaddr + XP_ADDR)); | 4519 | outb(GRXFIFO, (ioaddr + XP_ADDR)); |
@@ -4965,8 +4533,8 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
4965 | * flow control modes of the sc26198. | 4533 | * flow control modes of the sc26198. |
4966 | */ | 4534 | */ |
4967 | if (test_bit(ASYI_TXFLOWED, &portp->istate)) { | 4535 | if (test_bit(ASYI_TXFLOWED, &portp->istate)) { |
4968 | if ((tty != (struct tty_struct *) NULL) && | 4536 | if ((tty != NULL) && |
4969 | (tty->termios != (struct termios *) NULL) && | 4537 | (tty->termios != NULL) && |
4970 | (tty->termios->c_iflag & IXANY)) { | 4538 | (tty->termios->c_iflag & IXANY)) { |
4971 | stl_sc26198txunflow(portp, tty); | 4539 | stl_sc26198txunflow(portp, tty); |
4972 | } | 4540 | } |
@@ -4979,7 +4547,7 @@ static void stl_sc26198rxisr(stlport_t *portp, unsigned int iack) | |||
4979 | * Process an RX bad character. | 4547 | * Process an RX bad character. |
4980 | */ | 4548 | */ |
4981 | 4549 | ||
4982 | static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, char ch) | 4550 | static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char ch) |
4983 | { | 4551 | { |
4984 | struct tty_struct *tty; | 4552 | struct tty_struct *tty; |
4985 | unsigned int ioaddr; | 4553 | unsigned int ioaddr; |
@@ -4996,7 +4564,7 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch | |||
4996 | if (status & SR_RXBREAK) | 4564 | if (status & SR_RXBREAK) |
4997 | portp->stats.rxbreaks++; | 4565 | portp->stats.rxbreaks++; |
4998 | 4566 | ||
4999 | if ((tty != (struct tty_struct *) NULL) && | 4567 | if ((tty != NULL) && |
5000 | ((portp->rxignoremsk & status) == 0)) { | 4568 | ((portp->rxignoremsk & status) == 0)) { |
5001 | if (portp->rxmarkmsk & status) { | 4569 | if (portp->rxmarkmsk & status) { |
5002 | if (status & SR_RXBREAK) { | 4570 | if (status & SR_RXBREAK) { |
@@ -5005,18 +4573,16 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch | |||
5005 | do_SAK(tty); | 4573 | do_SAK(tty); |
5006 | BRDENABLE(portp->brdnr, portp->pagenr); | 4574 | BRDENABLE(portp->brdnr, portp->pagenr); |
5007 | } | 4575 | } |
5008 | } else if (status & SR_RXPARITY) { | 4576 | } else if (status & SR_RXPARITY) |
5009 | status = TTY_PARITY; | 4577 | status = TTY_PARITY; |
5010 | } else if (status & SR_RXFRAMING) { | 4578 | else if (status & SR_RXFRAMING) |
5011 | status = TTY_FRAME; | 4579 | status = TTY_FRAME; |
5012 | } else if(status & SR_RXOVERRUN) { | 4580 | else if(status & SR_RXOVERRUN) |
5013 | status = TTY_OVERRUN; | 4581 | status = TTY_OVERRUN; |
5014 | } else { | 4582 | else |
5015 | status = 0; | 4583 | status = 0; |
5016 | } | 4584 | } else |
5017 | } else { | ||
5018 | status = 0; | 4585 | status = 0; |
5019 | } | ||
5020 | 4586 | ||
5021 | tty_insert_flip_char(tty, ch, status); | 4587 | tty_insert_flip_char(tty, ch, status); |
5022 | tty_schedule_flip(tty); | 4588 | tty_schedule_flip(tty); |
@@ -5037,7 +4603,7 @@ static inline void stl_sc26198rxbadch(stlport_t *portp, unsigned char status, ch | |||
5037 | * the FIFO). | 4603 | * the FIFO). |
5038 | */ | 4604 | */ |
5039 | 4605 | ||
5040 | static void stl_sc26198rxbadchars(stlport_t *portp) | 4606 | static void stl_sc26198rxbadchars(struct stlport *portp) |
5041 | { | 4607 | { |
5042 | unsigned char status, mr1; | 4608 | unsigned char status, mr1; |
5043 | char ch; | 4609 | char ch; |
@@ -5070,13 +4636,11 @@ static void stl_sc26198rxbadchars(stlport_t *portp) | |||
5070 | * processing time. | 4636 | * processing time. |
5071 | */ | 4637 | */ |
5072 | 4638 | ||
5073 | static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack) | 4639 | static void stl_sc26198otherisr(struct stlport *portp, unsigned int iack) |
5074 | { | 4640 | { |
5075 | unsigned char cir, ipr, xisr; | 4641 | unsigned char cir, ipr, xisr; |
5076 | 4642 | ||
5077 | #ifdef DEBUG | 4643 | pr_debug("stl_sc26198otherisr(portp=%p,iack=%x)\n", portp, iack); |
5078 | printk("stl_sc26198otherisr(portp=%x,iack=%x)\n", (int) portp, iack); | ||
5079 | #endif | ||
5080 | 4644 | ||
5081 | cir = stl_sc26198getglobreg(portp, CIR); | 4645 | cir = stl_sc26198getglobreg(portp, CIR); |
5082 | 4646 | ||
@@ -5109,4 +4673,172 @@ static void stl_sc26198otherisr(stlport_t *portp, unsigned int iack) | |||
5109 | } | 4673 | } |
5110 | } | 4674 | } |
5111 | 4675 | ||
5112 | /*****************************************************************************/ | 4676 | static void stl_free_isabrds(void) |
4677 | { | ||
4678 | struct stlbrd *brdp; | ||
4679 | unsigned int i; | ||
4680 | |||
4681 | for (i = 0; i < stl_nrbrds; i++) { | ||
4682 | if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) | ||
4683 | continue; | ||
4684 | |||
4685 | free_irq(brdp->irq, brdp); | ||
4686 | |||
4687 | stl_cleanup_panels(brdp); | ||
4688 | |||
4689 | release_region(brdp->ioaddr1, brdp->iosize1); | ||
4690 | if (brdp->iosize2 > 0) | ||
4691 | release_region(brdp->ioaddr2, brdp->iosize2); | ||
4692 | |||
4693 | kfree(brdp); | ||
4694 | stl_brds[i] = NULL; | ||
4695 | } | ||
4696 | } | ||
4697 | |||
4698 | /* | ||
4699 | * Loadable module initialization stuff. | ||
4700 | */ | ||
4701 | static int __init stallion_module_init(void) | ||
4702 | { | ||
4703 | struct stlbrd *brdp; | ||
4704 | struct stlconf conf; | ||
4705 | unsigned int i, j; | ||
4706 | int retval; | ||
4707 | |||
4708 | printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); | ||
4709 | |||
4710 | spin_lock_init(&stallion_lock); | ||
4711 | spin_lock_init(&brd_lock); | ||
4712 | |||
4713 | /* | ||
4714 | * Find any dynamically supported boards. That is via module load | ||
4715 | * line options. | ||
4716 | */ | ||
4717 | for (i = stl_nrbrds; i < stl_nargs; i++) { | ||
4718 | memset(&conf, 0, sizeof(conf)); | ||
4719 | if (stl_parsebrd(&conf, stl_brdsp[i]) == 0) | ||
4720 | continue; | ||
4721 | if ((brdp = stl_allocbrd()) == NULL) | ||
4722 | continue; | ||
4723 | brdp->brdnr = i; | ||
4724 | brdp->brdtype = conf.brdtype; | ||
4725 | brdp->ioaddr1 = conf.ioaddr1; | ||
4726 | brdp->ioaddr2 = conf.ioaddr2; | ||
4727 | brdp->irq = conf.irq; | ||
4728 | brdp->irqtype = conf.irqtype; | ||
4729 | if (stl_brdinit(brdp)) | ||
4730 | kfree(brdp); | ||
4731 | else { | ||
4732 | for (j = 0; j < brdp->nrports; j++) | ||
4733 | tty_register_device(stl_serial, | ||
4734 | brdp->brdnr * STL_MAXPORTS + j, NULL); | ||
4735 | stl_brds[brdp->brdnr] = brdp; | ||
4736 | stl_nrbrds = i + 1; | ||
4737 | } | ||
4738 | } | ||
4739 | |||
4740 | /* this has to be _after_ isa finding because of locking */ | ||
4741 | retval = pci_register_driver(&stl_pcidriver); | ||
4742 | if (retval && stl_nrbrds == 0) | ||
4743 | goto err; | ||
4744 | |||
4745 | stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); | ||
4746 | if (!stl_serial) { | ||
4747 | retval = -ENOMEM; | ||
4748 | goto err_pcidr; | ||
4749 | } | ||
4750 | |||
4751 | /* | ||
4752 | * Set up a character driver for per board stuff. This is mainly used | ||
4753 | * to do stats ioctls on the ports. | ||
4754 | */ | ||
4755 | if (register_chrdev(STL_SIOMEMMAJOR, "staliomem", &stl_fsiomem)) | ||
4756 | printk("STALLION: failed to register serial board device\n"); | ||
4757 | |||
4758 | stallion_class = class_create(THIS_MODULE, "staliomem"); | ||
4759 | if (IS_ERR(stallion_class)) { | ||
4760 | retval = PTR_ERR(stallion_class); | ||
4761 | goto err_reg; | ||
4762 | } | ||
4763 | for (i = 0; i < 4; i++) | ||
4764 | class_device_create(stallion_class, NULL, | ||
4765 | MKDEV(STL_SIOMEMMAJOR, i), NULL, | ||
4766 | "staliomem%d", i); | ||
4767 | |||
4768 | stl_serial->owner = THIS_MODULE; | ||
4769 | stl_serial->driver_name = stl_drvname; | ||
4770 | stl_serial->name = "ttyE"; | ||
4771 | stl_serial->major = STL_SERIALMAJOR; | ||
4772 | stl_serial->minor_start = 0; | ||
4773 | stl_serial->type = TTY_DRIVER_TYPE_SERIAL; | ||
4774 | stl_serial->subtype = SERIAL_TYPE_NORMAL; | ||
4775 | stl_serial->init_termios = stl_deftermios; | ||
4776 | stl_serial->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
4777 | tty_set_operations(stl_serial, &stl_ops); | ||
4778 | |||
4779 | retval = tty_register_driver(stl_serial); | ||
4780 | if (retval) { | ||
4781 | printk("STALLION: failed to register serial driver\n"); | ||
4782 | goto err_clsdev; | ||
4783 | } | ||
4784 | |||
4785 | return 0; | ||
4786 | err_clsdev: | ||
4787 | for (i = 0; i < 4; i++) | ||
4788 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | ||
4789 | class_destroy(stallion_class); | ||
4790 | err_reg: | ||
4791 | unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"); | ||
4792 | put_tty_driver(stl_serial); | ||
4793 | err_pcidr: | ||
4794 | pci_unregister_driver(&stl_pcidriver); | ||
4795 | stl_free_isabrds(); | ||
4796 | err: | ||
4797 | return retval; | ||
4798 | } | ||
4799 | |||
4800 | static void __exit stallion_module_exit(void) | ||
4801 | { | ||
4802 | struct stlbrd *brdp; | ||
4803 | unsigned int i, j; | ||
4804 | int retval; | ||
4805 | |||
4806 | pr_debug("cleanup_module()\n"); | ||
4807 | |||
4808 | printk(KERN_INFO "Unloading %s: version %s\n", stl_drvtitle, | ||
4809 | stl_drvversion); | ||
4810 | |||
4811 | /* | ||
4812 | * Free up all allocated resources used by the ports. This includes | ||
4813 | * memory and interrupts. As part of this process we will also do | ||
4814 | * a hangup on every open port - to try to flush out any processes | ||
4815 | * hanging onto ports. | ||
4816 | */ | ||
4817 | for (i = 0; i < stl_nrbrds; i++) { | ||
4818 | if ((brdp = stl_brds[i]) == NULL || (brdp->state & STL_PROBED)) | ||
4819 | continue; | ||
4820 | for (j = 0; j < brdp->nrports; j++) | ||
4821 | tty_unregister_device(stl_serial, | ||
4822 | brdp->brdnr * STL_MAXPORTS + j); | ||
4823 | } | ||
4824 | tty_unregister_driver(stl_serial); | ||
4825 | put_tty_driver(stl_serial); | ||
4826 | |||
4827 | for (i = 0; i < 4; i++) | ||
4828 | class_device_destroy(stallion_class, MKDEV(STL_SIOMEMMAJOR, i)); | ||
4829 | if ((retval = unregister_chrdev(STL_SIOMEMMAJOR, "staliomem"))) | ||
4830 | printk("STALLION: failed to un-register serial memory device, " | ||
4831 | "errno=%d\n", -retval); | ||
4832 | class_destroy(stallion_class); | ||
4833 | |||
4834 | pci_unregister_driver(&stl_pcidriver); | ||
4835 | |||
4836 | stl_free_isabrds(); | ||
4837 | } | ||
4838 | |||
4839 | module_init(stallion_module_init); | ||
4840 | module_exit(stallion_module_exit); | ||
4841 | |||
4842 | MODULE_AUTHOR("Greg Ungerer"); | ||
4843 | MODULE_DESCRIPTION("Stallion Multiport Serial Driver"); | ||
4844 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index cc10af08cb05..a3008ce13015 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
@@ -32,7 +32,6 @@ | |||
32 | * USA. | 32 | * USA. |
33 | * | 33 | * |
34 | * Revision history: | 34 | * Revision history: |
35 | * $Log: sx.c,v $ | ||
36 | * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff | 35 | * Revision 1.33 2000/03/09 10:00:00 pvdl,wolff |
37 | * - Fixed module and port counting | 36 | * - Fixed module and port counting |
38 | * - Fixed signal handling | 37 | * - Fixed signal handling |
@@ -199,9 +198,7 @@ | |||
199 | * | 198 | * |
200 | * */ | 199 | * */ |
201 | 200 | ||
202 | 201 | #define SX_VERSION 1.33 | |
203 | #define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $" | ||
204 | #define RCS_REV "$Revision: 1.33 $" | ||
205 | 202 | ||
206 | #include <linux/module.h> | 203 | #include <linux/module.h> |
207 | #include <linux/kdev_t.h> | 204 | #include <linux/kdev_t.h> |
@@ -217,6 +214,7 @@ | |||
217 | #include <linux/fcntl.h> | 214 | #include <linux/fcntl.h> |
218 | #include <linux/major.h> | 215 | #include <linux/major.h> |
219 | #include <linux/delay.h> | 216 | #include <linux/delay.h> |
217 | #include <linux/eisa.h> | ||
220 | #include <linux/pci.h> | 218 | #include <linux/pci.h> |
221 | #include <linux/slab.h> | 219 | #include <linux/slab.h> |
222 | #include <linux/init.h> | 220 | #include <linux/init.h> |
@@ -240,7 +238,6 @@ | |||
240 | #include <linux/generic_serial.h> | 238 | #include <linux/generic_serial.h> |
241 | #include "sx.h" | 239 | #include "sx.h" |
242 | 240 | ||
243 | |||
244 | /* I don't think that this driver can handle more than 256 ports on | 241 | /* I don't think that this driver can handle more than 256 ports on |
245 | one machine. You'll have to increase the number of boards in sx.h | 242 | one machine. You'll have to increase the number of boards in sx.h |
246 | if you want more than 4 boards. */ | 243 | if you want more than 4 boards. */ |
@@ -249,21 +246,12 @@ | |||
249 | #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 | 246 | #define PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8 0x2000 |
250 | #endif | 247 | #endif |
251 | 248 | ||
252 | #ifdef CONFIG_PCI | ||
253 | static struct pci_device_id sx_pci_tbl[] = { | ||
254 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, PCI_ANY_ID, PCI_ANY_ID }, | ||
255 | { 0 } | ||
256 | }; | ||
257 | MODULE_DEVICE_TABLE(pci, sx_pci_tbl); | ||
258 | #endif /* CONFIG_PCI */ | ||
259 | |||
260 | /* Configurable options: | 249 | /* Configurable options: |
261 | (Don't be too sure that it'll work if you toggle them) */ | 250 | (Don't be too sure that it'll work if you toggle them) */ |
262 | 251 | ||
263 | /* Am I paranoid or not ? ;-) */ | 252 | /* Am I paranoid or not ? ;-) */ |
264 | #undef SX_PARANOIA_CHECK | 253 | #undef SX_PARANOIA_CHECK |
265 | 254 | ||
266 | |||
267 | /* 20 -> 2000 per second. The card should rate-limit interrupts at 100 | 255 | /* 20 -> 2000 per second. The card should rate-limit interrupts at 100 |
268 | Hz, but it is user configurable. I don't recommend going above 1000 | 256 | Hz, but it is user configurable. I don't recommend going above 1000 |
269 | Hz. The interrupt ratelimit might trigger if the interrupt is | 257 | Hz. The interrupt ratelimit might trigger if the interrupt is |
@@ -277,7 +265,6 @@ MODULE_DEVICE_TABLE(pci, sx_pci_tbl); | |||
277 | interrupt. Use polling. */ | 265 | interrupt. Use polling. */ |
278 | #undef IRQ_RATE_LIMIT | 266 | #undef IRQ_RATE_LIMIT |
279 | 267 | ||
280 | |||
281 | #if 0 | 268 | #if 0 |
282 | /* Not implemented */ | 269 | /* Not implemented */ |
283 | /* | 270 | /* |
@@ -286,35 +273,33 @@ MODULE_DEVICE_TABLE(pci, sx_pci_tbl); | |||
286 | */ | 273 | */ |
287 | #define SX_REPORT_FIFO | 274 | #define SX_REPORT_FIFO |
288 | #define SX_REPORT_OVERRUN | 275 | #define SX_REPORT_OVERRUN |
289 | #endif | 276 | #endif |
290 | |||
291 | 277 | ||
292 | /* Function prototypes */ | 278 | /* Function prototypes */ |
293 | static void sx_disable_tx_interrupts (void * ptr); | 279 | static void sx_disable_tx_interrupts(void *ptr); |
294 | static void sx_enable_tx_interrupts (void * ptr); | 280 | static void sx_enable_tx_interrupts(void *ptr); |
295 | static void sx_disable_rx_interrupts (void * ptr); | 281 | static void sx_disable_rx_interrupts(void *ptr); |
296 | static void sx_enable_rx_interrupts (void * ptr); | 282 | static void sx_enable_rx_interrupts(void *ptr); |
297 | static int sx_get_CD (void * ptr); | 283 | static int sx_get_CD(void *ptr); |
298 | static void sx_shutdown_port (void * ptr); | 284 | static void sx_shutdown_port(void *ptr); |
299 | static int sx_set_real_termios (void *ptr); | 285 | static int sx_set_real_termios(void *ptr); |
300 | static void sx_close (void *ptr); | 286 | static void sx_close(void *ptr); |
301 | static int sx_chars_in_buffer (void * ptr); | 287 | static int sx_chars_in_buffer(void *ptr); |
302 | static int sx_init_board (struct sx_board *board); | 288 | static int sx_init_board(struct sx_board *board); |
303 | static int sx_init_portstructs (int nboards, int nports); | 289 | static int sx_init_portstructs(int nboards, int nports); |
304 | static int sx_fw_ioctl (struct inode *inode, struct file *filp, | 290 | static int sx_fw_ioctl(struct inode *inode, struct file *filp, |
305 | unsigned int cmd, unsigned long arg); | 291 | unsigned int cmd, unsigned long arg); |
306 | static int sx_init_drivers(void); | 292 | static int sx_init_drivers(void); |
307 | 293 | ||
308 | |||
309 | static struct tty_driver *sx_driver; | 294 | static struct tty_driver *sx_driver; |
310 | 295 | ||
296 | static DEFINE_MUTEX(sx_boards_lock); | ||
311 | static struct sx_board boards[SX_NBOARDS]; | 297 | static struct sx_board boards[SX_NBOARDS]; |
312 | static struct sx_port *sx_ports; | 298 | static struct sx_port *sx_ports; |
313 | static int sx_initialized; | 299 | static int sx_initialized; |
314 | static int sx_nports; | 300 | static int sx_nports; |
315 | static int sx_debug; | 301 | static int sx_debug; |
316 | 302 | ||
317 | |||
318 | /* You can have the driver poll your card. | 303 | /* You can have the driver poll your card. |
319 | - Set sx_poll to 1 to poll every timer tick (10ms on Intel). | 304 | - Set sx_poll to 1 to poll every timer tick (10ms on Intel). |
320 | This is used when the card cannot use an interrupt for some reason. | 305 | This is used when the card cannot use an interrupt for some reason. |
@@ -333,27 +318,36 @@ static int sx_slowpoll; | |||
333 | 318 | ||
334 | static int sx_maxints = 100; | 319 | static int sx_maxints = 100; |
335 | 320 | ||
321 | #ifdef CONFIG_ISA | ||
322 | |||
336 | /* These are the only open spaces in my computer. Yours may have more | 323 | /* These are the only open spaces in my computer. Yours may have more |
337 | or less.... -- REW | 324 | or less.... -- REW |
338 | duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl | 325 | duh: Card at 0xa0000 is possible on HP Netserver?? -- pvdl |
339 | */ | 326 | */ |
340 | static int sx_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, | 327 | static int sx_probe_addrs[] = { |
341 | 0xc8000, 0xd8000, 0xe8000}; | 328 | 0xc0000, 0xd0000, 0xe0000, |
342 | static int si_probe_addrs[]= {0xc0000, 0xd0000, 0xe0000, | 329 | 0xc8000, 0xd8000, 0xe8000 |
343 | 0xc8000, 0xd8000, 0xe8000, 0xa0000}; | 330 | }; |
344 | static int si1_probe_addrs[]= { 0xd0000}; | 331 | static int si_probe_addrs[] = { |
332 | 0xc0000, 0xd0000, 0xe0000, | ||
333 | 0xc8000, 0xd8000, 0xe8000, 0xa0000 | ||
334 | }; | ||
335 | static int si1_probe_addrs[] = { | ||
336 | 0xd0000 | ||
337 | }; | ||
345 | 338 | ||
346 | #define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) | 339 | #define NR_SX_ADDRS ARRAY_SIZE(sx_probe_addrs) |
347 | #define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) | 340 | #define NR_SI_ADDRS ARRAY_SIZE(si_probe_addrs) |
348 | #define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) | 341 | #define NR_SI1_ADDRS ARRAY_SIZE(si1_probe_addrs) |
349 | 342 | ||
343 | module_param_array(sx_probe_addrs, int, NULL, 0); | ||
344 | module_param_array(si_probe_addrs, int, NULL, 0); | ||
345 | #endif | ||
350 | 346 | ||
351 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. | 347 | /* Set the mask to all-ones. This alas, only supports 32 interrupts. |
352 | Some architectures may need more. */ | 348 | Some architectures may need more. */ |
353 | static int sx_irqmask = -1; | 349 | static int sx_irqmask = -1; |
354 | 350 | ||
355 | module_param_array(sx_probe_addrs, int, NULL, 0); | ||
356 | module_param_array(si_probe_addrs, int, NULL, 0); | ||
357 | module_param(sx_poll, int, 0); | 351 | module_param(sx_poll, int, 0); |
358 | module_param(sx_slowpoll, int, 0); | 352 | module_param(sx_slowpoll, int, 0); |
359 | module_param(sx_maxints, int, 0); | 353 | module_param(sx_maxints, int, 0); |
@@ -368,13 +362,12 @@ static struct real_driver sx_real_driver = { | |||
368 | sx_disable_rx_interrupts, | 362 | sx_disable_rx_interrupts, |
369 | sx_enable_rx_interrupts, | 363 | sx_enable_rx_interrupts, |
370 | sx_get_CD, | 364 | sx_get_CD, |
371 | sx_shutdown_port, | 365 | sx_shutdown_port, |
372 | sx_set_real_termios, | 366 | sx_set_real_termios, |
373 | sx_chars_in_buffer, | 367 | sx_chars_in_buffer, |
374 | sx_close, | 368 | sx_close, |
375 | }; | 369 | }; |
376 | 370 | ||
377 | |||
378 | /* | 371 | /* |
379 | This driver can spew a whole lot of debugging output at you. If you | 372 | This driver can spew a whole lot of debugging output at you. If you |
380 | need maximum performance, you should disable the DEBUG define. To | 373 | need maximum performance, you should disable the DEBUG define. To |
@@ -385,23 +378,17 @@ static struct real_driver sx_real_driver = { | |||
385 | */ | 378 | */ |
386 | #define DEBUG | 379 | #define DEBUG |
387 | 380 | ||
388 | |||
389 | #ifdef DEBUG | 381 | #ifdef DEBUG |
390 | #define sx_dprintk(f, str...) if (sx_debug & f) printk (str) | 382 | #define sx_dprintk(f, str...) if (sx_debug & f) printk (str) |
391 | #else | 383 | #else |
392 | #define sx_dprintk(f, str...) /* nothing */ | 384 | #define sx_dprintk(f, str...) /* nothing */ |
393 | #endif | 385 | #endif |
394 | 386 | ||
387 | #define func_enter() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__) | ||
388 | #define func_exit() sx_dprintk(SX_DEBUG_FLOW, "sx: exit %s\n",__FUNCTION__) | ||
395 | 389 | ||
396 | 390 | #define func_enter2() sx_dprintk(SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ | |
397 | #define func_enter() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s\n",__FUNCTION__) | 391 | __FUNCTION__, port->line) |
398 | #define func_exit() sx_dprintk (SX_DEBUG_FLOW, "sx: exit %s\n", __FUNCTION__) | ||
399 | |||
400 | #define func_enter2() sx_dprintk (SX_DEBUG_FLOW, "sx: enter %s (port %d)\n", \ | ||
401 | __FUNCTION__, port->line) | ||
402 | |||
403 | |||
404 | |||
405 | 392 | ||
406 | /* | 393 | /* |
407 | * Firmware loader driver specific routines | 394 | * Firmware loader driver specific routines |
@@ -409,31 +396,26 @@ static struct real_driver sx_real_driver = { | |||
409 | */ | 396 | */ |
410 | 397 | ||
411 | static const struct file_operations sx_fw_fops = { | 398 | static const struct file_operations sx_fw_fops = { |
412 | .owner = THIS_MODULE, | 399 | .owner = THIS_MODULE, |
413 | .ioctl = sx_fw_ioctl, | 400 | .ioctl = sx_fw_ioctl, |
414 | }; | 401 | }; |
415 | 402 | ||
416 | static struct miscdevice sx_fw_device = { | 403 | static struct miscdevice sx_fw_device = { |
417 | SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops | 404 | SXCTL_MISC_MINOR, "sxctl", &sx_fw_fops |
418 | }; | 405 | }; |
419 | 406 | ||
420 | |||
421 | |||
422 | |||
423 | |||
424 | #ifdef SX_PARANOIA_CHECK | 407 | #ifdef SX_PARANOIA_CHECK |
425 | 408 | ||
426 | /* This doesn't work. Who's paranoid around here? Not me! */ | 409 | /* This doesn't work. Who's paranoid around here? Not me! */ |
427 | 410 | ||
428 | static inline int sx_paranoia_check(struct sx_port const * port, | 411 | static inline int sx_paranoia_check(struct sx_port const *port, |
429 | char *name, const char *routine) | 412 | char *name, const char *routine) |
430 | { | 413 | { |
414 | static const char *badmagic = KERN_ERR "sx: Warning: bad sx port magic " | ||
415 | "number for device %s in %s\n"; | ||
416 | static const char *badinfo = KERN_ERR "sx: Warning: null sx port for " | ||
417 | "device %s in %s\n"; | ||
431 | 418 | ||
432 | static const char *badmagic = | ||
433 | KERN_ERR "sx: Warning: bad sx port magic number for device %s in %s\n"; | ||
434 | static const char *badinfo = | ||
435 | KERN_ERR "sx: Warning: null sx port for device %s in %s\n"; | ||
436 | |||
437 | if (!port) { | 419 | if (!port) { |
438 | printk(badinfo, name, routine); | 420 | printk(badinfo, name, routine); |
439 | return 1; | 421 | return 1; |
@@ -456,23 +438,24 @@ static inline int sx_paranoia_check(struct sx_port const * port, | |||
456 | #define TIMEOUT_1 30 | 438 | #define TIMEOUT_1 30 |
457 | #define TIMEOUT_2 1000000 | 439 | #define TIMEOUT_2 1000000 |
458 | 440 | ||
459 | |||
460 | #ifdef DEBUG | 441 | #ifdef DEBUG |
461 | static void my_hd_io(void __iomem *p, int len) | 442 | static void my_hd_io(void __iomem *p, int len) |
462 | { | 443 | { |
463 | int i, j, ch; | 444 | int i, j, ch; |
464 | unsigned char __iomem *addr = p; | 445 | unsigned char __iomem *addr = p; |
465 | 446 | ||
466 | for (i=0;i<len;i+=16) { | 447 | for (i = 0; i < len; i += 16) { |
467 | printk ("%p ", addr+i); | 448 | printk("%p ", addr + i); |
468 | for (j=0;j<16;j++) { | 449 | for (j = 0; j < 16; j++) { |
469 | printk ("%02x %s", readb(addr+j+i), (j==7)?" ":""); | 450 | printk("%02x %s", readb(addr + j + i), |
451 | (j == 7) ? " " : ""); | ||
470 | } | 452 | } |
471 | for (j=0;j<16;j++) { | 453 | for (j = 0; j < 16; j++) { |
472 | ch = readb(addr+j+i); | 454 | ch = readb(addr + j + i); |
473 | printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch)); | 455 | printk("%c", (ch < 0x20) ? '.' : |
456 | ((ch > 0x7f) ? '.' : ch)); | ||
474 | } | 457 | } |
475 | printk ("\n"); | 458 | printk("\n"); |
476 | } | 459 | } |
477 | } | 460 | } |
478 | static void my_hd(void *p, int len) | 461 | static void my_hd(void *p, int len) |
@@ -480,419 +463,468 @@ static void my_hd(void *p, int len) | |||
480 | int i, j, ch; | 463 | int i, j, ch; |
481 | unsigned char *addr = p; | 464 | unsigned char *addr = p; |
482 | 465 | ||
483 | for (i=0;i<len;i+=16) { | 466 | for (i = 0; i < len; i += 16) { |
484 | printk ("%p ", addr+i); | 467 | printk("%p ", addr + i); |
485 | for (j=0;j<16;j++) { | 468 | for (j = 0; j < 16; j++) { |
486 | printk ("%02x %s", addr[j+i], (j==7)?" ":""); | 469 | printk("%02x %s", addr[j + i], (j == 7) ? " " : ""); |
487 | } | 470 | } |
488 | for (j=0;j<16;j++) { | 471 | for (j = 0; j < 16; j++) { |
489 | ch = addr[j+i]; | 472 | ch = addr[j + i]; |
490 | printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch)); | 473 | printk("%c", (ch < 0x20) ? '.' : |
474 | ((ch > 0x7f) ? '.' : ch)); | ||
491 | } | 475 | } |
492 | printk ("\n"); | 476 | printk("\n"); |
493 | } | 477 | } |
494 | } | 478 | } |
495 | #endif | 479 | #endif |
496 | 480 | ||
497 | |||
498 | |||
499 | /* This needs redoing for Alpha -- REW -- Done. */ | 481 | /* This needs redoing for Alpha -- REW -- Done. */ |
500 | 482 | ||
501 | static inline void write_sx_byte (struct sx_board *board, int offset, u8 byte) | 483 | static inline void write_sx_byte(struct sx_board *board, int offset, u8 byte) |
502 | { | 484 | { |
503 | writeb (byte, board->base+offset); | 485 | writeb(byte, board->base + offset); |
504 | } | 486 | } |
505 | 487 | ||
506 | static inline u8 read_sx_byte (struct sx_board *board, int offset) | 488 | static inline u8 read_sx_byte(struct sx_board *board, int offset) |
507 | { | 489 | { |
508 | return readb (board->base+offset); | 490 | return readb(board->base + offset); |
509 | } | 491 | } |
510 | 492 | ||
511 | 493 | static inline void write_sx_word(struct sx_board *board, int offset, u16 word) | |
512 | static inline void write_sx_word (struct sx_board *board, int offset, u16 word) | ||
513 | { | 494 | { |
514 | writew (word, board->base+offset); | 495 | writew(word, board->base + offset); |
515 | } | 496 | } |
516 | 497 | ||
517 | static inline u16 read_sx_word (struct sx_board *board, int offset) | 498 | static inline u16 read_sx_word(struct sx_board *board, int offset) |
518 | { | 499 | { |
519 | return readw (board->base + offset); | 500 | return readw(board->base + offset); |
520 | } | 501 | } |
521 | 502 | ||
522 | 503 | static int sx_busy_wait_eq(struct sx_board *board, | |
523 | static int sx_busy_wait_eq (struct sx_board *board, | 504 | int offset, int mask, int correctval) |
524 | int offset, int mask, int correctval) | ||
525 | { | 505 | { |
526 | int i; | 506 | int i; |
527 | 507 | ||
528 | func_enter (); | 508 | func_enter(); |
529 | 509 | ||
530 | for (i=0; i < TIMEOUT_1 ;i++) | 510 | for (i = 0; i < TIMEOUT_1; i++) |
531 | if ((read_sx_byte (board, offset) & mask) == correctval) { | 511 | if ((read_sx_byte(board, offset) & mask) == correctval) { |
532 | func_exit (); | 512 | func_exit(); |
533 | return 1; | 513 | return 1; |
534 | } | 514 | } |
535 | 515 | ||
536 | for (i=0; i < TIMEOUT_2 ;i++) { | 516 | for (i = 0; i < TIMEOUT_2; i++) { |
537 | if ((read_sx_byte (board, offset) & mask) == correctval) { | 517 | if ((read_sx_byte(board, offset) & mask) == correctval) { |
538 | func_exit (); | 518 | func_exit(); |
539 | return 1; | 519 | return 1; |
540 | } | 520 | } |
541 | udelay (1); | 521 | udelay(1); |
542 | } | 522 | } |
543 | 523 | ||
544 | func_exit (); | 524 | func_exit(); |
545 | return 0; | 525 | return 0; |
546 | } | 526 | } |
547 | 527 | ||
548 | 528 | static int sx_busy_wait_neq(struct sx_board *board, | |
549 | static int sx_busy_wait_neq (struct sx_board *board, | 529 | int offset, int mask, int badval) |
550 | int offset, int mask, int badval) | ||
551 | { | 530 | { |
552 | int i; | 531 | int i; |
553 | 532 | ||
554 | func_enter (); | 533 | func_enter(); |
555 | 534 | ||
556 | for (i=0; i < TIMEOUT_1 ;i++) | 535 | for (i = 0; i < TIMEOUT_1; i++) |
557 | if ((read_sx_byte (board, offset) & mask) != badval) { | 536 | if ((read_sx_byte(board, offset) & mask) != badval) { |
558 | func_exit (); | 537 | func_exit(); |
559 | return 1; | 538 | return 1; |
560 | } | 539 | } |
561 | 540 | ||
562 | for (i=0; i < TIMEOUT_2 ;i++) { | 541 | for (i = 0; i < TIMEOUT_2; i++) { |
563 | if ((read_sx_byte (board, offset) & mask) != badval) { | 542 | if ((read_sx_byte(board, offset) & mask) != badval) { |
564 | func_exit (); | 543 | func_exit(); |
565 | return 1; | 544 | return 1; |
566 | } | 545 | } |
567 | udelay (1); | 546 | udelay(1); |
568 | } | 547 | } |
569 | 548 | ||
570 | func_exit (); | 549 | func_exit(); |
571 | return 0; | 550 | return 0; |
572 | } | 551 | } |
573 | 552 | ||
574 | |||
575 | |||
576 | /* 5.6.4 of 6210028 r2.3 */ | 553 | /* 5.6.4 of 6210028 r2.3 */ |
577 | static int sx_reset (struct sx_board *board) | 554 | static int sx_reset(struct sx_board *board) |
578 | { | 555 | { |
579 | func_enter (); | 556 | func_enter(); |
580 | 557 | ||
581 | if (IS_SX_BOARD (board)) { | 558 | if (IS_SX_BOARD(board)) { |
582 | 559 | ||
583 | write_sx_byte (board, SX_CONFIG, 0); | 560 | write_sx_byte(board, SX_CONFIG, 0); |
584 | write_sx_byte (board, SX_RESET, 1); /* Value doesn't matter */ | 561 | write_sx_byte(board, SX_RESET, 1); /* Value doesn't matter */ |
585 | 562 | ||
586 | if (!sx_busy_wait_eq (board, SX_RESET_STATUS, 1, 0)) { | 563 | if (!sx_busy_wait_eq(board, SX_RESET_STATUS, 1, 0)) { |
587 | printk (KERN_INFO "sx: Card doesn't respond to reset....\n"); | 564 | printk(KERN_INFO "sx: Card doesn't respond to " |
565 | "reset...\n"); | ||
588 | return 0; | 566 | return 0; |
589 | } | 567 | } |
590 | } else if (IS_EISA_BOARD(board)) { | 568 | } else if (IS_EISA_BOARD(board)) { |
591 | outb(board->irq<<4, board->eisa_base+0xc02); | 569 | outb(board->irq << 4, board->eisa_base + 0xc02); |
592 | } else if (IS_SI1_BOARD(board)) { | 570 | } else if (IS_SI1_BOARD(board)) { |
593 | write_sx_byte (board, SI1_ISA_RESET, 0); // value does not matter | 571 | write_sx_byte(board, SI1_ISA_RESET, 0); /*value doesn't matter*/ |
594 | } else { | 572 | } else { |
595 | /* Gory details of the SI/ISA board */ | 573 | /* Gory details of the SI/ISA board */ |
596 | write_sx_byte (board, SI2_ISA_RESET, SI2_ISA_RESET_SET); | 574 | write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_SET); |
597 | write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR); | 575 | write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_CLEAR); |
598 | write_sx_byte (board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR); | 576 | write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_CLEAR); |
599 | write_sx_byte (board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR); | 577 | write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_CLEAR); |
600 | write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); | 578 | write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); |
601 | write_sx_byte (board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR); | 579 | write_sx_byte(board, SI2_ISA_IRQSET, SI2_ISA_IRQSET_CLEAR); |
602 | } | 580 | } |
603 | 581 | ||
604 | func_exit (); | 582 | func_exit(); |
605 | return 1; | 583 | return 1; |
606 | } | 584 | } |
607 | 585 | ||
608 | |||
609 | /* This doesn't work on machines where "NULL" isn't 0 */ | 586 | /* This doesn't work on machines where "NULL" isn't 0 */ |
610 | /* If you have one of those, someone will need to write | 587 | /* If you have one of those, someone will need to write |
611 | the equivalent of this, which will amount to about 3 lines. I don't | 588 | the equivalent of this, which will amount to about 3 lines. I don't |
612 | want to complicate this right now. -- REW | 589 | want to complicate this right now. -- REW |
613 | (See, I do write comments every now and then :-) */ | 590 | (See, I do write comments every now and then :-) */ |
614 | #define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem)) | 591 | #define OFFSETOF(strct, elem) ((long)&(((struct strct *)NULL)->elem)) |
615 | |||
616 | |||
617 | #define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem)) | ||
618 | #define MODU_OFFSET(board,addr,elem) (addr + OFFSETOF (_SXMODULE, elem)) | ||
619 | #define BRD_OFFSET(board,elem) (OFFSETOF (_SXCARD, elem)) | ||
620 | 592 | ||
593 | #define CHAN_OFFSET(port,elem) (port->ch_base + OFFSETOF (_SXCHANNEL, elem)) | ||
594 | #define MODU_OFFSET(board,addr,elem) (addr + OFFSETOF (_SXMODULE, elem)) | ||
595 | #define BRD_OFFSET(board,elem) (OFFSETOF (_SXCARD, elem)) | ||
621 | 596 | ||
622 | #define sx_write_channel_byte(port, elem, val) \ | 597 | #define sx_write_channel_byte(port, elem, val) \ |
623 | write_sx_byte (port->board, CHAN_OFFSET (port, elem), val) | 598 | write_sx_byte (port->board, CHAN_OFFSET (port, elem), val) |
624 | 599 | ||
625 | #define sx_read_channel_byte(port, elem) \ | 600 | #define sx_read_channel_byte(port, elem) \ |
626 | read_sx_byte (port->board, CHAN_OFFSET (port, elem)) | 601 | read_sx_byte (port->board, CHAN_OFFSET (port, elem)) |
627 | 602 | ||
628 | #define sx_write_channel_word(port, elem, val) \ | 603 | #define sx_write_channel_word(port, elem, val) \ |
629 | write_sx_word (port->board, CHAN_OFFSET (port, elem), val) | 604 | write_sx_word (port->board, CHAN_OFFSET (port, elem), val) |
630 | 605 | ||
631 | #define sx_read_channel_word(port, elem) \ | 606 | #define sx_read_channel_word(port, elem) \ |
632 | read_sx_word (port->board, CHAN_OFFSET (port, elem)) | 607 | read_sx_word (port->board, CHAN_OFFSET (port, elem)) |
633 | |||
634 | 608 | ||
635 | #define sx_write_module_byte(board, addr, elem, val) \ | 609 | #define sx_write_module_byte(board, addr, elem, val) \ |
636 | write_sx_byte (board, MODU_OFFSET (board, addr, elem), val) | 610 | write_sx_byte (board, MODU_OFFSET (board, addr, elem), val) |
637 | 611 | ||
638 | #define sx_read_module_byte(board, addr, elem) \ | 612 | #define sx_read_module_byte(board, addr, elem) \ |
639 | read_sx_byte (board, MODU_OFFSET (board, addr, elem)) | 613 | read_sx_byte (board, MODU_OFFSET (board, addr, elem)) |
640 | 614 | ||
641 | #define sx_write_module_word(board, addr, elem, val) \ | 615 | #define sx_write_module_word(board, addr, elem, val) \ |
642 | write_sx_word (board, MODU_OFFSET (board, addr, elem), val) | 616 | write_sx_word (board, MODU_OFFSET (board, addr, elem), val) |
643 | 617 | ||
644 | #define sx_read_module_word(board, addr, elem) \ | 618 | #define sx_read_module_word(board, addr, elem) \ |
645 | read_sx_word (board, MODU_OFFSET (board, addr, elem)) | 619 | read_sx_word (board, MODU_OFFSET (board, addr, elem)) |
646 | |||
647 | 620 | ||
648 | #define sx_write_board_byte(board, elem, val) \ | 621 | #define sx_write_board_byte(board, elem, val) \ |
649 | write_sx_byte (board, BRD_OFFSET (board, elem), val) | 622 | write_sx_byte (board, BRD_OFFSET (board, elem), val) |
650 | 623 | ||
651 | #define sx_read_board_byte(board, elem) \ | 624 | #define sx_read_board_byte(board, elem) \ |
652 | read_sx_byte (board, BRD_OFFSET (board, elem)) | 625 | read_sx_byte (board, BRD_OFFSET (board, elem)) |
653 | 626 | ||
654 | #define sx_write_board_word(board, elem, val) \ | 627 | #define sx_write_board_word(board, elem, val) \ |
655 | write_sx_word (board, BRD_OFFSET (board, elem), val) | 628 | write_sx_word (board, BRD_OFFSET (board, elem), val) |
656 | 629 | ||
657 | #define sx_read_board_word(board, elem) \ | 630 | #define sx_read_board_word(board, elem) \ |
658 | read_sx_word (board, BRD_OFFSET (board, elem)) | 631 | read_sx_word (board, BRD_OFFSET (board, elem)) |
659 | |||
660 | 632 | ||
661 | static int sx_start_board (struct sx_board *board) | 633 | static int sx_start_board(struct sx_board *board) |
662 | { | 634 | { |
663 | if (IS_SX_BOARD (board)) { | 635 | if (IS_SX_BOARD(board)) { |
664 | write_sx_byte (board, SX_CONFIG, SX_CONF_BUSEN); | 636 | write_sx_byte(board, SX_CONFIG, SX_CONF_BUSEN); |
665 | } else if (IS_EISA_BOARD(board)) { | 637 | } else if (IS_EISA_BOARD(board)) { |
666 | write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); | 638 | write_sx_byte(board, SI2_EISA_OFF, SI2_EISA_VAL); |
667 | outb((board->irq<<4)|4, board->eisa_base+0xc02); | 639 | outb((board->irq << 4) | 4, board->eisa_base + 0xc02); |
668 | } else if (IS_SI1_BOARD(board)) { | 640 | } else if (IS_SI1_BOARD(board)) { |
669 | write_sx_byte (board, SI1_ISA_RESET_CLEAR, 0); | 641 | write_sx_byte(board, SI1_ISA_RESET_CLEAR, 0); |
670 | write_sx_byte (board, SI1_ISA_INTCL, 0); | 642 | write_sx_byte(board, SI1_ISA_INTCL, 0); |
671 | } else { | 643 | } else { |
672 | /* Don't bug me about the clear_set. | 644 | /* Don't bug me about the clear_set. |
673 | I haven't the foggiest idea what it's about -- REW */ | 645 | I haven't the foggiest idea what it's about -- REW */ |
674 | write_sx_byte (board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR); | 646 | write_sx_byte(board, SI2_ISA_RESET, SI2_ISA_RESET_CLEAR); |
675 | write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); | 647 | write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); |
676 | } | 648 | } |
677 | return 1; | 649 | return 1; |
678 | } | 650 | } |
679 | 651 | ||
680 | #define SX_IRQ_REG_VAL(board) \ | 652 | #define SX_IRQ_REG_VAL(board) \ |
681 | ((board->flags & SX_ISA_BOARD)?(board->irq << 4):0) | 653 | ((board->flags & SX_ISA_BOARD) ? (board->irq << 4) : 0) |
682 | 654 | ||
683 | /* Note. The SX register is write-only. Therefore, we have to enable the | 655 | /* Note. The SX register is write-only. Therefore, we have to enable the |
684 | bus too. This is a no-op, if you don't mess with this driver... */ | 656 | bus too. This is a no-op, if you don't mess with this driver... */ |
685 | static int sx_start_interrupts (struct sx_board *board) | 657 | static int sx_start_interrupts(struct sx_board *board) |
686 | { | 658 | { |
687 | 659 | ||
688 | /* Don't call this with board->irq == 0 */ | 660 | /* Don't call this with board->irq == 0 */ |
689 | 661 | ||
690 | if (IS_SX_BOARD(board)) { | 662 | if (IS_SX_BOARD(board)) { |
691 | write_sx_byte (board, SX_CONFIG, SX_IRQ_REG_VAL (board) | | 663 | write_sx_byte(board, SX_CONFIG, SX_IRQ_REG_VAL(board) | |
692 | SX_CONF_BUSEN | | 664 | SX_CONF_BUSEN | SX_CONF_HOSTIRQ); |
693 | SX_CONF_HOSTIRQ); | ||
694 | } else if (IS_EISA_BOARD(board)) { | 665 | } else if (IS_EISA_BOARD(board)) { |
695 | inb(board->eisa_base+0xc03); | 666 | inb(board->eisa_base + 0xc03); |
696 | } else if (IS_SI1_BOARD(board)) { | 667 | } else if (IS_SI1_BOARD(board)) { |
697 | write_sx_byte (board, SI1_ISA_INTCL,0); | 668 | write_sx_byte(board, SI1_ISA_INTCL, 0); |
698 | write_sx_byte (board, SI1_ISA_INTCL_CLEAR,0); | 669 | write_sx_byte(board, SI1_ISA_INTCL_CLEAR, 0); |
699 | } else { | 670 | } else { |
700 | switch (board->irq) { | 671 | switch (board->irq) { |
701 | case 11:write_sx_byte (board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET);break; | 672 | case 11: |
702 | case 12:write_sx_byte (board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET);break; | 673 | write_sx_byte(board, SI2_ISA_IRQ11, SI2_ISA_IRQ11_SET); |
703 | case 15:write_sx_byte (board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET);break; | 674 | break; |
704 | default:printk (KERN_INFO "sx: SI/XIO card doesn't support interrupt %d.\n", | 675 | case 12: |
705 | board->irq); | 676 | write_sx_byte(board, SI2_ISA_IRQ12, SI2_ISA_IRQ12_SET); |
706 | return 0; | 677 | break; |
678 | case 15: | ||
679 | write_sx_byte(board, SI2_ISA_IRQ15, SI2_ISA_IRQ15_SET); | ||
680 | break; | ||
681 | default: | ||
682 | printk(KERN_INFO "sx: SI/XIO card doesn't support " | ||
683 | "interrupt %d.\n", board->irq); | ||
684 | return 0; | ||
707 | } | 685 | } |
708 | write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); | 686 | write_sx_byte(board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); |
709 | } | 687 | } |
710 | 688 | ||
711 | return 1; | 689 | return 1; |
712 | } | 690 | } |
713 | 691 | ||
714 | 692 | static int sx_send_command(struct sx_port *port, | |
715 | static int sx_send_command (struct sx_port *port, | 693 | int command, int mask, int newstat) |
716 | int command, int mask, int newstat) | ||
717 | { | 694 | { |
718 | func_enter2 (); | 695 | func_enter2(); |
719 | write_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat), command); | 696 | write_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat), command); |
720 | func_exit (); | 697 | func_exit(); |
721 | return sx_busy_wait_eq (port->board, CHAN_OFFSET (port, hi_hstat), mask, newstat); | 698 | return sx_busy_wait_eq(port->board, CHAN_OFFSET(port, hi_hstat), mask, |
699 | newstat); | ||
722 | } | 700 | } |
723 | 701 | ||
724 | 702 | static char *mod_type_s(int module_type) | |
725 | static char *mod_type_s (int module_type) | ||
726 | { | 703 | { |
727 | switch (module_type) { | 704 | switch (module_type) { |
728 | case TA4: return "TA4"; | 705 | case TA4: |
729 | case TA8: return "TA8"; | 706 | return "TA4"; |
730 | case TA4_ASIC: return "TA4_ASIC"; | 707 | case TA8: |
731 | case TA8_ASIC: return "TA8_ASIC"; | 708 | return "TA8"; |
732 | case MTA_CD1400:return "MTA_CD1400"; | 709 | case TA4_ASIC: |
733 | case SXDC: return "SXDC"; | 710 | return "TA4_ASIC"; |
734 | default:return "Unknown/invalid"; | 711 | case TA8_ASIC: |
712 | return "TA8_ASIC"; | ||
713 | case MTA_CD1400: | ||
714 | return "MTA_CD1400"; | ||
715 | case SXDC: | ||
716 | return "SXDC"; | ||
717 | default: | ||
718 | return "Unknown/invalid"; | ||
735 | } | 719 | } |
736 | } | 720 | } |
737 | 721 | ||
738 | 722 | static char *pan_type_s(int pan_type) | |
739 | static char *pan_type_s (int pan_type) | ||
740 | { | 723 | { |
741 | switch (pan_type) { | 724 | switch (pan_type) { |
742 | case MOD_RS232DB25: return "MOD_RS232DB25"; | 725 | case MOD_RS232DB25: |
743 | case MOD_RS232RJ45: return "MOD_RS232RJ45"; | 726 | return "MOD_RS232DB25"; |
744 | case MOD_RS422DB25: return "MOD_RS422DB25"; | 727 | case MOD_RS232RJ45: |
745 | case MOD_PARALLEL: return "MOD_PARALLEL"; | 728 | return "MOD_RS232RJ45"; |
746 | case MOD_2_RS232DB25: return "MOD_2_RS232DB25"; | 729 | case MOD_RS422DB25: |
747 | case MOD_2_RS232RJ45: return "MOD_2_RS232RJ45"; | 730 | return "MOD_RS422DB25"; |
748 | case MOD_2_RS422DB25: return "MOD_2_RS422DB25"; | 731 | case MOD_PARALLEL: |
749 | case MOD_RS232DB25MALE: return "MOD_RS232DB25MALE"; | 732 | return "MOD_PARALLEL"; |
750 | case MOD_2_PARALLEL: return "MOD_2_PARALLEL"; | 733 | case MOD_2_RS232DB25: |
751 | case MOD_BLANK: return "empty"; | 734 | return "MOD_2_RS232DB25"; |
752 | default:return "invalid"; | 735 | case MOD_2_RS232RJ45: |
736 | return "MOD_2_RS232RJ45"; | ||
737 | case MOD_2_RS422DB25: | ||
738 | return "MOD_2_RS422DB25"; | ||
739 | case MOD_RS232DB25MALE: | ||
740 | return "MOD_RS232DB25MALE"; | ||
741 | case MOD_2_PARALLEL: | ||
742 | return "MOD_2_PARALLEL"; | ||
743 | case MOD_BLANK: | ||
744 | return "empty"; | ||
745 | default: | ||
746 | return "invalid"; | ||
753 | } | 747 | } |
754 | } | 748 | } |
755 | 749 | ||
756 | 750 | static int mod_compat_type(int module_type) | |
757 | static int mod_compat_type (int module_type) | ||
758 | { | 751 | { |
759 | return module_type >> 4; | 752 | return module_type >> 4; |
760 | } | 753 | } |
761 | 754 | ||
762 | static void sx_reconfigure_port(struct sx_port *port) | 755 | static void sx_reconfigure_port(struct sx_port *port) |
763 | { | 756 | { |
764 | if (sx_read_channel_byte (port, hi_hstat) == HS_IDLE_OPEN) { | 757 | if (sx_read_channel_byte(port, hi_hstat) == HS_IDLE_OPEN) { |
765 | if (sx_send_command (port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) { | 758 | if (sx_send_command(port, HS_CONFIG, -1, HS_IDLE_OPEN) != 1) { |
766 | printk (KERN_WARNING "sx: Sent reconfigure command, but card didn't react.\n"); | 759 | printk(KERN_WARNING "sx: Sent reconfigure command, but " |
760 | "card didn't react.\n"); | ||
767 | } | 761 | } |
768 | } else { | 762 | } else { |
769 | sx_dprintk (SX_DEBUG_TERMIOS, | 763 | sx_dprintk(SX_DEBUG_TERMIOS, "sx: Not sending reconfigure: " |
770 | "sx: Not sending reconfigure: port isn't open (%02x).\n", | 764 | "port isn't open (%02x).\n", |
771 | sx_read_channel_byte (port, hi_hstat)); | 765 | sx_read_channel_byte(port, hi_hstat)); |
772 | } | 766 | } |
773 | } | 767 | } |
774 | 768 | ||
775 | static void sx_setsignals (struct sx_port *port, int dtr, int rts) | 769 | static void sx_setsignals(struct sx_port *port, int dtr, int rts) |
776 | { | 770 | { |
777 | int t; | 771 | int t; |
778 | func_enter2 (); | 772 | func_enter2(); |
779 | 773 | ||
780 | t = sx_read_channel_byte (port, hi_op); | 774 | t = sx_read_channel_byte(port, hi_op); |
781 | if (dtr >= 0) t = dtr? (t | OP_DTR): (t & ~OP_DTR); | 775 | if (dtr >= 0) |
782 | if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS); | 776 | t = dtr ? (t | OP_DTR) : (t & ~OP_DTR); |
783 | sx_write_channel_byte (port, hi_op, t); | 777 | if (rts >= 0) |
784 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); | 778 | t = rts ? (t | OP_RTS) : (t & ~OP_RTS); |
779 | sx_write_channel_byte(port, hi_op, t); | ||
780 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts); | ||
785 | 781 | ||
786 | func_exit (); | 782 | func_exit(); |
787 | } | 783 | } |
788 | 784 | ||
789 | 785 | static int sx_getsignals(struct sx_port *port) | |
790 | |||
791 | static int sx_getsignals (struct sx_port *port) | ||
792 | { | 786 | { |
793 | int i_stat,o_stat; | 787 | int i_stat, o_stat; |
794 | 788 | ||
795 | o_stat = sx_read_channel_byte (port, hi_op); | 789 | o_stat = sx_read_channel_byte(port, hi_op); |
796 | i_stat = sx_read_channel_byte (port, hi_ip); | 790 | i_stat = sx_read_channel_byte(port, hi_ip); |
797 | 791 | ||
798 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) %02x/%02x\n", | 792 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "getsignals: %d/%d (%d/%d) " |
799 | (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, | 793 | "%02x/%02x\n", |
800 | port->c_dcd, sx_get_CD (port), | 794 | (o_stat & OP_DTR) != 0, (o_stat & OP_RTS) != 0, |
801 | sx_read_channel_byte (port, hi_ip), | 795 | port->c_dcd, sx_get_CD(port), |
802 | sx_read_channel_byte (port, hi_state)); | 796 | sx_read_channel_byte(port, hi_ip), |
803 | 797 | sx_read_channel_byte(port, hi_state)); | |
804 | return (((o_stat & OP_DTR)?TIOCM_DTR:0) | | 798 | |
805 | ((o_stat & OP_RTS)?TIOCM_RTS:0) | | 799 | return (((o_stat & OP_DTR) ? TIOCM_DTR : 0) | |
806 | ((i_stat & IP_CTS)?TIOCM_CTS:0) | | 800 | ((o_stat & OP_RTS) ? TIOCM_RTS : 0) | |
807 | ((i_stat & IP_DCD)?TIOCM_CAR:0) | | 801 | ((i_stat & IP_CTS) ? TIOCM_CTS : 0) | |
808 | ((i_stat & IP_DSR)?TIOCM_DSR:0) | | 802 | ((i_stat & IP_DCD) ? TIOCM_CAR : 0) | |
809 | ((i_stat & IP_RI)?TIOCM_RNG:0) | 803 | ((i_stat & IP_DSR) ? TIOCM_DSR : 0) | |
810 | ); | 804 | ((i_stat & IP_RI) ? TIOCM_RNG : 0)); |
811 | } | 805 | } |
812 | 806 | ||
813 | 807 | static void sx_set_baud(struct sx_port *port) | |
814 | static void sx_set_baud (struct sx_port *port) | ||
815 | { | 808 | { |
816 | int t; | 809 | int t; |
817 | 810 | ||
818 | if (port->board->ta_type == MOD_SXDC) { | 811 | if (port->board->ta_type == MOD_SXDC) { |
819 | switch (port->gs.baud) { | 812 | switch (port->gs.baud) { |
820 | /* Save some typing work... */ | 813 | /* Save some typing work... */ |
821 | #define e(x) case x:t= BAUD_ ## x ; break | 814 | #define e(x) case x: t = BAUD_ ## x; break |
822 | e(50);e(75);e(110);e(150);e(200);e(300);e(600); | 815 | e(50); |
823 | e(1200);e(1800);e(2000);e(2400);e(4800);e(7200); | 816 | e(75); |
824 | e(9600);e(14400);e(19200);e(28800);e(38400); | 817 | e(110); |
825 | e(56000);e(57600);e(64000);e(76800);e(115200); | 818 | e(150); |
826 | e(128000);e(150000);e(230400);e(256000);e(460800); | 819 | e(200); |
827 | e(921600); | 820 | e(300); |
828 | case 134 :t = BAUD_134_5; break; | 821 | e(600); |
829 | case 0 :t = -1; | 822 | e(1200); |
830 | break; | 823 | e(1800); |
824 | e(2000); | ||
825 | e(2400); | ||
826 | e(4800); | ||
827 | e(7200); | ||
828 | e(9600); | ||
829 | e(14400); | ||
830 | e(19200); | ||
831 | e(28800); | ||
832 | e(38400); | ||
833 | e(56000); | ||
834 | e(57600); | ||
835 | e(64000); | ||
836 | e(76800); | ||
837 | e(115200); | ||
838 | e(128000); | ||
839 | e(150000); | ||
840 | e(230400); | ||
841 | e(256000); | ||
842 | e(460800); | ||
843 | e(921600); | ||
844 | case 134: | ||
845 | t = BAUD_134_5; | ||
846 | break; | ||
847 | case 0: | ||
848 | t = -1; | ||
849 | break; | ||
831 | default: | 850 | default: |
832 | /* Can I return "invalid"? */ | 851 | /* Can I return "invalid"? */ |
833 | t = BAUD_9600; | 852 | t = BAUD_9600; |
834 | printk (KERN_INFO "sx: unsupported baud rate: %d.\n", port->gs.baud); | 853 | printk(KERN_INFO "sx: unsupported baud rate: %d.\n", |
854 | port->gs.baud); | ||
835 | break; | 855 | break; |
836 | } | 856 | } |
837 | #undef e | 857 | #undef e |
838 | if (t > 0) { | 858 | if (t > 0) { |
839 | /* The baud rate is not set to 0, so we're enabeling DTR... -- REW */ | 859 | /* The baud rate is not set to 0, so we're enabeling DTR... -- REW */ |
840 | sx_setsignals (port, 1, -1); | 860 | sx_setsignals(port, 1, -1); |
841 | /* XXX This is not TA & MTA compatible */ | 861 | /* XXX This is not TA & MTA compatible */ |
842 | sx_write_channel_byte (port, hi_csr, 0xff); | 862 | sx_write_channel_byte(port, hi_csr, 0xff); |
843 | 863 | ||
844 | sx_write_channel_byte (port, hi_txbaud, t); | 864 | sx_write_channel_byte(port, hi_txbaud, t); |
845 | sx_write_channel_byte (port, hi_rxbaud, t); | 865 | sx_write_channel_byte(port, hi_rxbaud, t); |
846 | } else { | 866 | } else { |
847 | sx_setsignals (port, 0, -1); | 867 | sx_setsignals(port, 0, -1); |
848 | } | 868 | } |
849 | } else { | 869 | } else { |
850 | switch (port->gs.baud) { | 870 | switch (port->gs.baud) { |
851 | #define e(x) case x:t= CSR_ ## x ; break | 871 | #define e(x) case x: t = CSR_ ## x; break |
852 | e(75);e(150);e(300);e(600);e(1200);e(2400);e(4800); | 872 | e(75); |
853 | e(1800);e(9600); | 873 | e(150); |
854 | e(19200);e(57600);e(38400); | 874 | e(300); |
855 | /* TA supports 110, but not 115200, MTA supports 115200, but not 110 */ | 875 | e(600); |
856 | case 110: | 876 | e(1200); |
877 | e(2400); | ||
878 | e(4800); | ||
879 | e(1800); | ||
880 | e(9600); | ||
881 | e(19200); | ||
882 | e(57600); | ||
883 | e(38400); | ||
884 | /* TA supports 110, but not 115200, MTA supports 115200, but not 110 */ | ||
885 | case 110: | ||
857 | if (port->board->ta_type == MOD_TA) { | 886 | if (port->board->ta_type == MOD_TA) { |
858 | t = CSR_110; | 887 | t = CSR_110; |
859 | break; | 888 | break; |
860 | } else { | 889 | } else { |
861 | t = CSR_9600; | 890 | t = CSR_9600; |
862 | printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud); | 891 | printk(KERN_INFO "sx: Unsupported baud rate: " |
892 | "%d.\n", port->gs.baud); | ||
863 | break; | 893 | break; |
864 | } | 894 | } |
865 | case 115200: | 895 | case 115200: |
866 | if (port->board->ta_type == MOD_TA) { | 896 | if (port->board->ta_type == MOD_TA) { |
867 | t = CSR_9600; | 897 | t = CSR_9600; |
868 | printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud); | 898 | printk(KERN_INFO "sx: Unsupported baud rate: " |
899 | "%d.\n", port->gs.baud); | ||
869 | break; | 900 | break; |
870 | } else { | 901 | } else { |
871 | t = CSR_110; | 902 | t = CSR_110; |
872 | break; | 903 | break; |
873 | } | 904 | } |
874 | case 0 :t = -1; | 905 | case 0: |
875 | break; | 906 | t = -1; |
907 | break; | ||
876 | default: | 908 | default: |
877 | t = CSR_9600; | 909 | t = CSR_9600; |
878 | printk (KERN_INFO "sx: Unsupported baud rate: %d.\n", port->gs.baud); | 910 | printk(KERN_INFO "sx: Unsupported baud rate: %d.\n", |
911 | port->gs.baud); | ||
879 | break; | 912 | break; |
880 | } | 913 | } |
881 | #undef e | 914 | #undef e |
882 | if (t >= 0) { | 915 | if (t >= 0) { |
883 | sx_setsignals (port, 1, -1); | 916 | sx_setsignals(port, 1, -1); |
884 | sx_write_channel_byte (port, hi_csr, t * 0x11); | 917 | sx_write_channel_byte(port, hi_csr, t * 0x11); |
885 | } else { | 918 | } else { |
886 | sx_setsignals (port, 0, -1); | 919 | sx_setsignals(port, 0, -1); |
887 | } | 920 | } |
888 | } | 921 | } |
889 | } | 922 | } |
890 | 923 | ||
891 | |||
892 | /* Simon Allen's version of this routine was 225 lines long. 85 is a lot | 924 | /* Simon Allen's version of this routine was 225 lines long. 85 is a lot |
893 | better. -- REW */ | 925 | better. -- REW */ |
894 | 926 | ||
895 | static int sx_set_real_termios (void *ptr) | 927 | static int sx_set_real_termios(void *ptr) |
896 | { | 928 | { |
897 | struct sx_port *port = ptr; | 929 | struct sx_port *port = ptr; |
898 | 930 | ||
@@ -907,80 +939,83 @@ static int sx_set_real_termios (void *ptr) | |||
907 | belongs (next to the drop dtr if baud == 0) -- REW */ | 939 | belongs (next to the drop dtr if baud == 0) -- REW */ |
908 | /* sx_setsignals (port, 1, -1); */ | 940 | /* sx_setsignals (port, 1, -1); */ |
909 | 941 | ||
910 | sx_set_baud (port); | 942 | sx_set_baud(port); |
911 | 943 | ||
912 | #define CFLAG port->gs.tty->termios->c_cflag | 944 | #define CFLAG port->gs.tty->termios->c_cflag |
913 | sx_write_channel_byte (port, hi_mr1, | 945 | sx_write_channel_byte(port, hi_mr1, |
914 | (C_PARENB (port->gs.tty)? MR1_WITH:MR1_NONE) | | 946 | (C_PARENB(port->gs.tty) ? MR1_WITH : MR1_NONE) | |
915 | (C_PARODD (port->gs.tty)? MR1_ODD:MR1_EVEN) | | 947 | (C_PARODD(port->gs.tty) ? MR1_ODD : MR1_EVEN) | |
916 | (C_CRTSCTS(port->gs.tty)? MR1_RTS_RXFLOW:0) | | 948 | (C_CRTSCTS(port->gs.tty) ? MR1_RTS_RXFLOW : 0) | |
917 | (((CFLAG & CSIZE)==CS8) ? MR1_8_BITS:0) | | 949 | (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) | |
918 | (((CFLAG & CSIZE)==CS7) ? MR1_7_BITS:0) | | 950 | (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) | |
919 | (((CFLAG & CSIZE)==CS6) ? MR1_6_BITS:0) | | 951 | (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) | |
920 | (((CFLAG & CSIZE)==CS5) ? MR1_5_BITS:0) ); | 952 | (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0)); |
921 | 953 | ||
922 | sx_write_channel_byte (port, hi_mr2, | 954 | sx_write_channel_byte(port, hi_mr2, |
923 | (C_CRTSCTS(port->gs.tty)?MR2_CTS_TXFLOW:0) | | 955 | (C_CRTSCTS(port->gs.tty) ? MR2_CTS_TXFLOW : 0) | |
924 | (C_CSTOPB (port->gs.tty)?MR2_2_STOP:MR2_1_STOP)); | 956 | (C_CSTOPB(port->gs.tty) ? MR2_2_STOP : |
957 | MR2_1_STOP)); | ||
925 | 958 | ||
926 | switch (CFLAG & CSIZE) { | 959 | switch (CFLAG & CSIZE) { |
927 | case CS8:sx_write_channel_byte (port, hi_mask, 0xff);break; | 960 | case CS8: |
928 | case CS7:sx_write_channel_byte (port, hi_mask, 0x7f);break; | 961 | sx_write_channel_byte(port, hi_mask, 0xff); |
929 | case CS6:sx_write_channel_byte (port, hi_mask, 0x3f);break; | 962 | break; |
930 | case CS5:sx_write_channel_byte (port, hi_mask, 0x1f);break; | 963 | case CS7: |
964 | sx_write_channel_byte(port, hi_mask, 0x7f); | ||
965 | break; | ||
966 | case CS6: | ||
967 | sx_write_channel_byte(port, hi_mask, 0x3f); | ||
968 | break; | ||
969 | case CS5: | ||
970 | sx_write_channel_byte(port, hi_mask, 0x1f); | ||
971 | break; | ||
931 | default: | 972 | default: |
932 | printk (KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE); | 973 | printk(KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE); |
933 | break; | 974 | break; |
934 | } | 975 | } |
935 | 976 | ||
936 | sx_write_channel_byte (port, hi_prtcl, | 977 | sx_write_channel_byte(port, hi_prtcl, |
937 | (I_IXON (port->gs.tty)?SP_TXEN:0) | | 978 | (I_IXON(port->gs.tty) ? SP_TXEN : 0) | |
938 | (I_IXOFF (port->gs.tty)?SP_RXEN:0) | | 979 | (I_IXOFF(port->gs.tty) ? SP_RXEN : 0) | |
939 | (I_IXANY (port->gs.tty)?SP_TANY:0) | | 980 | (I_IXANY(port->gs.tty) ? SP_TANY : 0) | SP_DCEN); |
940 | SP_DCEN); | ||
941 | 981 | ||
942 | sx_write_channel_byte (port, hi_break, | 982 | sx_write_channel_byte(port, hi_break, |
943 | (I_IGNBRK(port->gs.tty)?BR_IGN:0 | | 983 | (I_IGNBRK(port->gs.tty) ? BR_IGN : 0 | |
944 | I_BRKINT(port->gs.tty)?BR_INT:0)); | 984 | I_BRKINT(port->gs.tty) ? BR_INT : 0)); |
945 | 985 | ||
946 | sx_write_channel_byte (port, hi_txon, START_CHAR (port->gs.tty)); | 986 | sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.tty)); |
947 | sx_write_channel_byte (port, hi_rxon, START_CHAR (port->gs.tty)); | 987 | sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.tty)); |
948 | sx_write_channel_byte (port, hi_txoff, STOP_CHAR (port->gs.tty)); | 988 | sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.tty)); |
949 | sx_write_channel_byte (port, hi_rxoff, STOP_CHAR (port->gs.tty)); | 989 | sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.tty)); |
950 | 990 | ||
951 | sx_reconfigure_port(port); | 991 | sx_reconfigure_port(port); |
952 | 992 | ||
953 | /* Tell line discipline whether we will do input cooking */ | 993 | /* Tell line discipline whether we will do input cooking */ |
954 | if(I_OTHER(port->gs.tty)) { | 994 | if (I_OTHER(port->gs.tty)) { |
955 | clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); | 995 | clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); |
956 | } else { | 996 | } else { |
957 | set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); | 997 | set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); |
958 | } | 998 | } |
959 | sx_dprintk (SX_DEBUG_TERMIOS, "iflags: %x(%d) ", | 999 | sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", |
960 | port->gs.tty->termios->c_iflag, | 1000 | port->gs.tty->termios->c_iflag, I_OTHER(port->gs.tty)); |
961 | I_OTHER(port->gs.tty)); | ||
962 | |||
963 | 1001 | ||
964 | /* Tell line discipline whether we will do output cooking. | 1002 | /* Tell line discipline whether we will do output cooking. |
965 | * If OPOST is set and no other output flags are set then we can do output | 1003 | * If OPOST is set and no other output flags are set then we can do output |
966 | * processing. Even if only *one* other flag in the O_OTHER group is set | 1004 | * processing. Even if only *one* other flag in the O_OTHER group is set |
967 | * we do cooking in software. | 1005 | * we do cooking in software. |
968 | */ | 1006 | */ |
969 | if(O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) { | 1007 | if (O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) { |
970 | set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); | 1008 | set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); |
971 | } else { | 1009 | } else { |
972 | clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); | 1010 | clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); |
973 | } | 1011 | } |
974 | sx_dprintk (SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", | 1012 | sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", |
975 | port->gs.tty->termios->c_oflag, | 1013 | port->gs.tty->termios->c_oflag, O_OTHER(port->gs.tty)); |
976 | O_OTHER(port->gs.tty)); | ||
977 | /* port->c_dcd = sx_get_CD (port); */ | 1014 | /* port->c_dcd = sx_get_CD (port); */ |
978 | func_exit (); | 1015 | func_exit(); |
979 | return 0; | 1016 | return 0; |
980 | } | 1017 | } |
981 | 1018 | ||
982 | |||
983 | |||
984 | /* ********************************************************************** * | 1019 | /* ********************************************************************** * |
985 | * the interrupt related routines * | 1020 | * the interrupt related routines * |
986 | * ********************************************************************** */ | 1021 | * ********************************************************************** */ |
@@ -996,245 +1031,260 @@ static int sx_set_real_termios (void *ptr) | |||
996 | know I'm dead against that, but I think it is required in this | 1031 | know I'm dead against that, but I think it is required in this |
997 | case. */ | 1032 | case. */ |
998 | 1033 | ||
999 | 1034 | static void sx_transmit_chars(struct sx_port *port) | |
1000 | static void sx_transmit_chars (struct sx_port *port) | ||
1001 | { | 1035 | { |
1002 | int c; | 1036 | int c; |
1003 | int tx_ip; | 1037 | int tx_ip; |
1004 | int txroom; | 1038 | int txroom; |
1005 | 1039 | ||
1006 | func_enter2 (); | 1040 | func_enter2(); |
1007 | sx_dprintk (SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", | 1041 | sx_dprintk(SX_DEBUG_TRANSMIT, "Port %p: transmit %d chars\n", |
1008 | port, port->gs.xmit_cnt); | 1042 | port, port->gs.xmit_cnt); |
1009 | 1043 | ||
1010 | if (test_and_set_bit (SX_PORT_TRANSMIT_LOCK, &port->locks)) { | 1044 | if (test_and_set_bit(SX_PORT_TRANSMIT_LOCK, &port->locks)) { |
1011 | return; | 1045 | return; |
1012 | } | 1046 | } |
1013 | 1047 | ||
1014 | while (1) { | 1048 | while (1) { |
1015 | c = port->gs.xmit_cnt; | 1049 | c = port->gs.xmit_cnt; |
1016 | 1050 | ||
1017 | sx_dprintk (SX_DEBUG_TRANSMIT, "Copying %d ", c); | 1051 | sx_dprintk(SX_DEBUG_TRANSMIT, "Copying %d ", c); |
1018 | tx_ip = sx_read_channel_byte (port, hi_txipos); | 1052 | tx_ip = sx_read_channel_byte(port, hi_txipos); |
1019 | 1053 | ||
1020 | /* Took me 5 minutes to deduce this formula. | 1054 | /* Took me 5 minutes to deduce this formula. |
1021 | Luckily it is literally in the manual in section 6.5.4.3.5 */ | 1055 | Luckily it is literally in the manual in section 6.5.4.3.5 */ |
1022 | txroom = (sx_read_channel_byte (port, hi_txopos) - tx_ip - 1) & 0xff; | 1056 | txroom = (sx_read_channel_byte(port, hi_txopos) - tx_ip - 1) & |
1057 | 0xff; | ||
1023 | 1058 | ||
1024 | /* Don't copy more bytes than there is room for in the buffer */ | 1059 | /* Don't copy more bytes than there is room for in the buffer */ |
1025 | if (c > txroom) | 1060 | if (c > txroom) |
1026 | c = txroom; | 1061 | c = txroom; |
1027 | sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom ); | 1062 | sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, txroom); |
1028 | 1063 | ||
1029 | /* Don't copy past the end of the hardware transmit buffer */ | 1064 | /* Don't copy past the end of the hardware transmit buffer */ |
1030 | if (c > 0x100 - tx_ip) | 1065 | if (c > 0x100 - tx_ip) |
1031 | c = 0x100 - tx_ip; | 1066 | c = 0x100 - tx_ip; |
1032 | 1067 | ||
1033 | sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100-tx_ip ); | 1068 | sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%d) ", c, 0x100 - tx_ip); |
1034 | 1069 | ||
1035 | /* Don't copy pas the end of the source buffer */ | 1070 | /* Don't copy pas the end of the source buffer */ |
1036 | if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) | 1071 | if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) |
1037 | c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; | 1072 | c = SERIAL_XMIT_SIZE - port->gs.xmit_tail; |
1038 | 1073 | ||
1039 | sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n", | 1074 | sx_dprintk(SX_DEBUG_TRANSMIT, " %d(%ld) \n", |
1040 | c, SERIAL_XMIT_SIZE- port->gs.xmit_tail); | 1075 | c, SERIAL_XMIT_SIZE - port->gs.xmit_tail); |
1041 | |||
1042 | /* If for one reason or another, we can't copy more data, we're done! */ | ||
1043 | if (c == 0) break; | ||
1044 | 1076 | ||
1077 | /* If for one reason or another, we can't copy more data, we're | ||
1078 | done! */ | ||
1079 | if (c == 0) | ||
1080 | break; | ||
1045 | 1081 | ||
1046 | memcpy_toio (port->board->base + CHAN_OFFSET(port,hi_txbuf) + tx_ip, | 1082 | memcpy_toio(port->board->base + CHAN_OFFSET(port, hi_txbuf) + |
1047 | port->gs.xmit_buf + port->gs.xmit_tail, c); | 1083 | tx_ip, port->gs.xmit_buf + port->gs.xmit_tail, c); |
1048 | 1084 | ||
1049 | /* Update the pointer in the card */ | 1085 | /* Update the pointer in the card */ |
1050 | sx_write_channel_byte (port, hi_txipos, (tx_ip+c) & 0xff); | 1086 | sx_write_channel_byte(port, hi_txipos, (tx_ip + c) & 0xff); |
1051 | 1087 | ||
1052 | /* Update the kernel buffer end */ | 1088 | /* Update the kernel buffer end */ |
1053 | port->gs.xmit_tail = (port->gs.xmit_tail + c) & (SERIAL_XMIT_SIZE-1); | 1089 | port->gs.xmit_tail = (port->gs.xmit_tail + c) & |
1090 | (SERIAL_XMIT_SIZE - 1); | ||
1054 | 1091 | ||
1055 | /* This one last. (this is essential) | 1092 | /* This one last. (this is essential) |
1056 | It would allow others to start putting more data into the buffer! */ | 1093 | It would allow others to start putting more data into the |
1094 | buffer! */ | ||
1057 | port->gs.xmit_cnt -= c; | 1095 | port->gs.xmit_cnt -= c; |
1058 | } | 1096 | } |
1059 | 1097 | ||
1060 | if (port->gs.xmit_cnt == 0) { | 1098 | if (port->gs.xmit_cnt == 0) { |
1061 | sx_disable_tx_interrupts (port); | 1099 | sx_disable_tx_interrupts(port); |
1062 | } | 1100 | } |
1063 | 1101 | ||
1064 | if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { | 1102 | if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { |
1065 | tty_wakeup(port->gs.tty); | 1103 | tty_wakeup(port->gs.tty); |
1066 | sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", | 1104 | sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", |
1067 | port->gs.wakeup_chars); | 1105 | port->gs.wakeup_chars); |
1068 | } | 1106 | } |
1069 | 1107 | ||
1070 | clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks); | 1108 | clear_bit(SX_PORT_TRANSMIT_LOCK, &port->locks); |
1071 | func_exit (); | 1109 | func_exit(); |
1072 | } | 1110 | } |
1073 | 1111 | ||
1074 | |||
1075 | /* Note the symmetry between receiving chars and transmitting them! | 1112 | /* Note the symmetry between receiving chars and transmitting them! |
1076 | Note: The kernel should have implemented both a receive buffer and | 1113 | Note: The kernel should have implemented both a receive buffer and |
1077 | a transmit buffer. */ | 1114 | a transmit buffer. */ |
1078 | 1115 | ||
1079 | /* Inlined: Called only once. Remove the inline when you add another call */ | 1116 | /* Inlined: Called only once. Remove the inline when you add another call */ |
1080 | static inline void sx_receive_chars (struct sx_port *port) | 1117 | static inline void sx_receive_chars(struct sx_port *port) |
1081 | { | 1118 | { |
1082 | int c; | 1119 | int c; |
1083 | int rx_op; | 1120 | int rx_op; |
1084 | struct tty_struct *tty; | 1121 | struct tty_struct *tty; |
1085 | int copied=0; | 1122 | int copied = 0; |
1086 | unsigned char *rp; | 1123 | unsigned char *rp; |
1087 | 1124 | ||
1088 | func_enter2 (); | 1125 | func_enter2(); |
1089 | tty = port->gs.tty; | 1126 | tty = port->gs.tty; |
1090 | while (1) { | 1127 | while (1) { |
1091 | rx_op = sx_read_channel_byte (port, hi_rxopos); | 1128 | rx_op = sx_read_channel_byte(port, hi_rxopos); |
1092 | c = (sx_read_channel_byte (port, hi_rxipos) - rx_op) & 0xff; | 1129 | c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff; |
1093 | 1130 | ||
1094 | sx_dprintk (SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); | 1131 | sx_dprintk(SX_DEBUG_RECEIVE, "rxop=%d, c = %d.\n", rx_op, c); |
1095 | 1132 | ||
1096 | /* Don't copy past the end of the hardware receive buffer */ | 1133 | /* Don't copy past the end of the hardware receive buffer */ |
1097 | if (rx_op + c > 0x100) c = 0x100 - rx_op; | 1134 | if (rx_op + c > 0x100) |
1135 | c = 0x100 - rx_op; | ||
1098 | 1136 | ||
1099 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | 1137 | sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); |
1100 | 1138 | ||
1101 | /* Don't copy more bytes than there is room for in the buffer */ | 1139 | /* Don't copy more bytes than there is room for in the buffer */ |
1102 | 1140 | ||
1103 | c = tty_prepare_flip_string(tty, &rp, c); | 1141 | c = tty_prepare_flip_string(tty, &rp, c); |
1104 | 1142 | ||
1105 | sx_dprintk (SX_DEBUG_RECEIVE, "c = %d.\n", c); | 1143 | sx_dprintk(SX_DEBUG_RECEIVE, "c = %d.\n", c); |
1106 | 1144 | ||
1107 | /* If for one reason or another, we can't copy more data, we're done! */ | 1145 | /* If for one reason or another, we can't copy more data, we're done! */ |
1108 | if (c == 0) break; | 1146 | if (c == 0) |
1147 | break; | ||
1109 | 1148 | ||
1110 | sx_dprintk (SX_DEBUG_RECEIVE , "Copying over %d chars. First is %d at %lx\n", c, | 1149 | sx_dprintk(SX_DEBUG_RECEIVE, "Copying over %d chars. First is " |
1111 | read_sx_byte (port->board, CHAN_OFFSET(port,hi_rxbuf) + rx_op), | 1150 | "%d at %lx\n", c, read_sx_byte(port->board, |
1112 | CHAN_OFFSET(port, hi_rxbuf)); | 1151 | CHAN_OFFSET(port, hi_rxbuf) + rx_op), |
1113 | memcpy_fromio (rp, | 1152 | CHAN_OFFSET(port, hi_rxbuf)); |
1114 | port->board->base + CHAN_OFFSET(port,hi_rxbuf) + rx_op, c); | 1153 | memcpy_fromio(rp, port->board->base + |
1154 | CHAN_OFFSET(port, hi_rxbuf) + rx_op, c); | ||
1115 | 1155 | ||
1116 | /* This one last. ( Not essential.) | 1156 | /* This one last. ( Not essential.) |
1117 | It allows the card to start putting more data into the buffer! | 1157 | It allows the card to start putting more data into the |
1158 | buffer! | ||
1118 | Update the pointer in the card */ | 1159 | Update the pointer in the card */ |
1119 | sx_write_channel_byte (port, hi_rxopos, (rx_op + c) & 0xff); | 1160 | sx_write_channel_byte(port, hi_rxopos, (rx_op + c) & 0xff); |
1120 | 1161 | ||
1121 | copied += c; | 1162 | copied += c; |
1122 | } | 1163 | } |
1123 | if (copied) { | 1164 | if (copied) { |
1124 | struct timeval tv; | 1165 | struct timeval tv; |
1125 | 1166 | ||
1126 | do_gettimeofday (&tv); | 1167 | do_gettimeofday(&tv); |
1127 | sx_dprintk (SX_DEBUG_RECEIVE, | 1168 | sx_dprintk(SX_DEBUG_RECEIVE, "pushing flipq port %d (%3d " |
1128 | "pushing flipq port %d (%3d chars): %d.%06d (%d/%d)\n", | 1169 | "chars): %d.%06d (%d/%d)\n", port->line, |
1129 | port->line, copied, | 1170 | copied, (int)(tv.tv_sec % 60), (int)tv.tv_usec, |
1130 | (int) (tv.tv_sec % 60), (int)tv.tv_usec, tty->raw, tty->real_raw); | 1171 | tty->raw, tty->real_raw); |
1131 | 1172 | ||
1132 | /* Tell the rest of the system the news. Great news. New characters! */ | 1173 | /* Tell the rest of the system the news. Great news. New |
1133 | tty_flip_buffer_push (tty); | 1174 | characters! */ |
1175 | tty_flip_buffer_push(tty); | ||
1134 | /* tty_schedule_flip (tty); */ | 1176 | /* tty_schedule_flip (tty); */ |
1135 | } | 1177 | } |
1136 | 1178 | ||
1137 | func_exit (); | 1179 | func_exit(); |
1138 | } | 1180 | } |
1139 | 1181 | ||
1140 | /* Inlined: it is called only once. Remove the inline if you add another | 1182 | /* Inlined: it is called only once. Remove the inline if you add another |
1141 | call */ | 1183 | call */ |
1142 | static inline void sx_check_modem_signals (struct sx_port *port) | 1184 | static inline void sx_check_modem_signals(struct sx_port *port) |
1143 | { | 1185 | { |
1144 | int hi_state; | 1186 | int hi_state; |
1145 | int c_dcd; | 1187 | int c_dcd; |
1146 | 1188 | ||
1147 | hi_state = sx_read_channel_byte (port, hi_state); | 1189 | hi_state = sx_read_channel_byte(port, hi_state); |
1148 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", | 1190 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Checking modem signals (%d/%d)\n", |
1149 | port->c_dcd, sx_get_CD (port)); | 1191 | port->c_dcd, sx_get_CD(port)); |
1150 | 1192 | ||
1151 | if (hi_state & ST_BREAK) { | 1193 | if (hi_state & ST_BREAK) { |
1152 | hi_state &= ~ST_BREAK; | 1194 | hi_state &= ~ST_BREAK; |
1153 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a break.\n"); | 1195 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a break.\n"); |
1154 | sx_write_channel_byte (port, hi_state, hi_state); | 1196 | sx_write_channel_byte(port, hi_state, hi_state); |
1155 | gs_got_break (&port->gs); | 1197 | gs_got_break(&port->gs); |
1156 | } | 1198 | } |
1157 | if (hi_state & ST_DCD) { | 1199 | if (hi_state & ST_DCD) { |
1158 | hi_state &= ~ST_DCD; | 1200 | hi_state &= ~ST_DCD; |
1159 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); | 1201 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "got a DCD change.\n"); |
1160 | sx_write_channel_byte (port, hi_state, hi_state); | 1202 | sx_write_channel_byte(port, hi_state, hi_state); |
1161 | c_dcd = sx_get_CD (port); | 1203 | c_dcd = sx_get_CD(port); |
1162 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); | 1204 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD is now %d\n", c_dcd); |
1163 | if (c_dcd != port->c_dcd) { | 1205 | if (c_dcd != port->c_dcd) { |
1164 | port->c_dcd = c_dcd; | 1206 | port->c_dcd = c_dcd; |
1165 | if (sx_get_CD (port)) { | 1207 | if (sx_get_CD(port)) { |
1166 | /* DCD went UP */ | 1208 | /* DCD went UP */ |
1167 | if ((sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) && | 1209 | if ((sx_read_channel_byte(port, hi_hstat) != |
1168 | !(port->gs.tty->termios->c_cflag & CLOCAL) ) { | 1210 | HS_IDLE_CLOSED) && |
1169 | /* Are we blocking in open?*/ | 1211 | !(port->gs.tty->termios-> |
1170 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD active, unblocking open\n"); | 1212 | c_cflag & CLOCAL)) { |
1171 | wake_up_interruptible(&port->gs.open_wait); | 1213 | /* Are we blocking in open? */ |
1214 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " | ||
1215 | "active, unblocking open\n"); | ||
1216 | wake_up_interruptible(&port->gs. | ||
1217 | open_wait); | ||
1172 | } else { | 1218 | } else { |
1173 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD raised. Ignoring.\n"); | 1219 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " |
1220 | "raised. Ignoring.\n"); | ||
1174 | } | 1221 | } |
1175 | } else { | 1222 | } else { |
1176 | /* DCD went down! */ | 1223 | /* DCD went down! */ |
1177 | if (!(port->gs.tty->termios->c_cflag & CLOCAL) ) { | 1224 | if (!(port->gs.tty->termios->c_cflag & CLOCAL)){ |
1178 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. hanging up....\n"); | 1225 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " |
1179 | tty_hangup (port->gs.tty); | 1226 | "dropped. hanging up....\n"); |
1227 | tty_hangup(port->gs.tty); | ||
1180 | } else { | 1228 | } else { |
1181 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "DCD dropped. ignoring.\n"); | 1229 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " |
1230 | "dropped. ignoring.\n"); | ||
1182 | } | 1231 | } |
1183 | } | 1232 | } |
1184 | } else { | 1233 | } else { |
1185 | sx_dprintk (SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us DCD changed, but it didn't.\n"); | 1234 | sx_dprintk(SX_DEBUG_MODEMSIGNALS, "Hmmm. card told us " |
1235 | "DCD changed, but it didn't.\n"); | ||
1186 | } | 1236 | } |
1187 | } | 1237 | } |
1188 | } | 1238 | } |
1189 | 1239 | ||
1190 | |||
1191 | /* This is what an interrupt routine should look like. | 1240 | /* This is what an interrupt routine should look like. |
1192 | * Small, elegant, clear. | 1241 | * Small, elegant, clear. |
1193 | */ | 1242 | */ |
1194 | 1243 | ||
1195 | static irqreturn_t sx_interrupt (int irq, void *ptr) | 1244 | static irqreturn_t sx_interrupt(int irq, void *ptr) |
1196 | { | 1245 | { |
1197 | struct sx_board *board = ptr; | 1246 | struct sx_board *board = ptr; |
1198 | struct sx_port *port; | 1247 | struct sx_port *port; |
1199 | int i; | 1248 | int i; |
1200 | 1249 | ||
1201 | func_enter (); | 1250 | func_enter(); |
1202 | sx_dprintk (SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, board->irq); | 1251 | sx_dprintk(SX_DEBUG_FLOW, "sx: enter sx_interrupt (%d/%d)\n", irq, |
1252 | board->irq); | ||
1203 | 1253 | ||
1204 | /* AAargh! The order in which to do these things is essential and | 1254 | /* AAargh! The order in which to do these things is essential and |
1205 | not trivial. | 1255 | not trivial. |
1206 | 1256 | ||
1207 | - Rate limit goes before "recursive". Otherwise a series of | 1257 | - Rate limit goes before "recursive". Otherwise a series of |
1208 | recursive calls will hang the machine in the interrupt routine. | 1258 | recursive calls will hang the machine in the interrupt routine. |
1209 | 1259 | ||
1210 | - hardware twiddling goes before "recursive". Otherwise when we | 1260 | - hardware twiddling goes before "recursive". Otherwise when we |
1211 | poll the card, and a recursive interrupt happens, we won't | 1261 | poll the card, and a recursive interrupt happens, we won't |
1212 | ack the card, so it might keep on interrupting us. (especially | 1262 | ack the card, so it might keep on interrupting us. (especially |
1213 | level sensitive interrupt systems like PCI). | 1263 | level sensitive interrupt systems like PCI). |
1214 | 1264 | ||
1215 | - Rate limit goes before hardware twiddling. Otherwise we won't | 1265 | - Rate limit goes before hardware twiddling. Otherwise we won't |
1216 | catch a card that has gone bonkers. | 1266 | catch a card that has gone bonkers. |
1217 | 1267 | ||
1218 | - The "initialized" test goes after the hardware twiddling. Otherwise | 1268 | - The "initialized" test goes after the hardware twiddling. Otherwise |
1219 | the card will stick us in the interrupt routine again. | 1269 | the card will stick us in the interrupt routine again. |
1220 | 1270 | ||
1221 | - The initialized test goes before recursive. | 1271 | - The initialized test goes before recursive. |
1222 | */ | 1272 | */ |
1223 | |||
1224 | |||
1225 | 1273 | ||
1226 | #ifdef IRQ_RATE_LIMIT | 1274 | #ifdef IRQ_RATE_LIMIT |
1227 | /* Aaargh! I'm ashamed. This costs more lines-of-code than the | 1275 | /* Aaargh! I'm ashamed. This costs more lines-of-code than the |
1228 | actual interrupt routine!. (Well, used to when I wrote that comment) */ | 1276 | actual interrupt routine!. (Well, used to when I wrote that |
1277 | comment) */ | ||
1229 | { | 1278 | { |
1230 | static int lastjif; | 1279 | static int lastjif; |
1231 | static int nintr=0; | 1280 | static int nintr = 0; |
1232 | 1281 | ||
1233 | if (lastjif == jiffies) { | 1282 | if (lastjif == jiffies) { |
1234 | if (++nintr > IRQ_RATE_LIMIT) { | 1283 | if (++nintr > IRQ_RATE_LIMIT) { |
1235 | free_irq (board->irq, board); | 1284 | free_irq(board->irq, board); |
1236 | printk (KERN_ERR "sx: Too many interrupts. Turning off interrupt %d.\n", | 1285 | printk(KERN_ERR "sx: Too many interrupts. " |
1237 | board->irq); | 1286 | "Turning off interrupt %d.\n", |
1287 | board->irq); | ||
1238 | } | 1288 | } |
1239 | } else { | 1289 | } else { |
1240 | lastjif = jiffies; | 1290 | lastjif = jiffies; |
@@ -1243,19 +1293,20 @@ static irqreturn_t sx_interrupt (int irq, void *ptr) | |||
1243 | } | 1293 | } |
1244 | #endif | 1294 | #endif |
1245 | 1295 | ||
1246 | |||
1247 | if (board->irq == irq) { | 1296 | if (board->irq == irq) { |
1248 | /* Tell the card we've noticed the interrupt. */ | 1297 | /* Tell the card we've noticed the interrupt. */ |
1249 | 1298 | ||
1250 | sx_write_board_word (board, cc_int_pending, 0); | 1299 | sx_write_board_word(board, cc_int_pending, 0); |
1251 | if (IS_SX_BOARD (board)) { | 1300 | if (IS_SX_BOARD(board)) { |
1252 | write_sx_byte (board, SX_RESET_IRQ, 1); | 1301 | write_sx_byte(board, SX_RESET_IRQ, 1); |
1253 | } else if (IS_EISA_BOARD(board)) { | 1302 | } else if (IS_EISA_BOARD(board)) { |
1254 | inb(board->eisa_base+0xc03); | 1303 | inb(board->eisa_base + 0xc03); |
1255 | write_sx_word(board, 8, 0); | 1304 | write_sx_word(board, 8, 0); |
1256 | } else { | 1305 | } else { |
1257 | write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_CLEAR); | 1306 | write_sx_byte(board, SI2_ISA_INTCLEAR, |
1258 | write_sx_byte (board, SI2_ISA_INTCLEAR, SI2_ISA_INTCLEAR_SET); | 1307 | SI2_ISA_INTCLEAR_CLEAR); |
1308 | write_sx_byte(board, SI2_ISA_INTCLEAR, | ||
1309 | SI2_ISA_INTCLEAR_SET); | ||
1259 | } | 1310 | } |
1260 | } | 1311 | } |
1261 | 1312 | ||
@@ -1264,53 +1315,48 @@ static irqreturn_t sx_interrupt (int irq, void *ptr) | |||
1264 | if (!(board->flags & SX_BOARD_INITIALIZED)) | 1315 | if (!(board->flags & SX_BOARD_INITIALIZED)) |
1265 | return IRQ_HANDLED; | 1316 | return IRQ_HANDLED; |
1266 | 1317 | ||
1267 | if (test_and_set_bit (SX_BOARD_INTR_LOCK, &board->locks)) { | 1318 | if (test_and_set_bit(SX_BOARD_INTR_LOCK, &board->locks)) { |
1268 | printk (KERN_ERR "Recursive interrupt! (%d)\n", board->irq); | 1319 | printk(KERN_ERR "Recursive interrupt! (%d)\n", board->irq); |
1269 | return IRQ_HANDLED; | 1320 | return IRQ_HANDLED; |
1270 | } | 1321 | } |
1271 | 1322 | ||
1272 | for (i=0;i<board->nports;i++) { | 1323 | for (i = 0; i < board->nports; i++) { |
1273 | port = &board->ports[i]; | 1324 | port = &board->ports[i]; |
1274 | if (port->gs.flags & GS_ACTIVE) { | 1325 | if (port->gs.flags & GS_ACTIVE) { |
1275 | if (sx_read_channel_byte (port, hi_state)) { | 1326 | if (sx_read_channel_byte(port, hi_state)) { |
1276 | sx_dprintk (SX_DEBUG_INTERRUPTS, | 1327 | sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: " |
1277 | "Port %d: modem signal change?... \n", i); | 1328 | "modem signal change?... \n",i); |
1278 | sx_check_modem_signals (port); | 1329 | sx_check_modem_signals(port); |
1279 | } | 1330 | } |
1280 | if (port->gs.xmit_cnt) { | 1331 | if (port->gs.xmit_cnt) { |
1281 | sx_transmit_chars (port); | 1332 | sx_transmit_chars(port); |
1282 | } | 1333 | } |
1283 | if (!(port->gs.flags & SX_RX_THROTTLE)) { | 1334 | if (!(port->gs.flags & SX_RX_THROTTLE)) { |
1284 | sx_receive_chars (port); | 1335 | sx_receive_chars(port); |
1285 | } | 1336 | } |
1286 | } | 1337 | } |
1287 | } | 1338 | } |
1288 | 1339 | ||
1289 | clear_bit (SX_BOARD_INTR_LOCK, &board->locks); | 1340 | clear_bit(SX_BOARD_INTR_LOCK, &board->locks); |
1290 | 1341 | ||
1291 | sx_dprintk (SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, board->irq); | 1342 | sx_dprintk(SX_DEBUG_FLOW, "sx: exit sx_interrupt (%d/%d)\n", irq, |
1292 | func_exit (); | 1343 | board->irq); |
1344 | func_exit(); | ||
1293 | return IRQ_HANDLED; | 1345 | return IRQ_HANDLED; |
1294 | } | 1346 | } |
1295 | 1347 | ||
1296 | 1348 | static void sx_pollfunc(unsigned long data) | |
1297 | static void sx_pollfunc (unsigned long data) | ||
1298 | { | 1349 | { |
1299 | struct sx_board *board = (struct sx_board *) data; | 1350 | struct sx_board *board = (struct sx_board *)data; |
1300 | |||
1301 | func_enter (); | ||
1302 | 1351 | ||
1303 | sx_interrupt (0, board); | 1352 | func_enter(); |
1304 | 1353 | ||
1305 | init_timer(&board->timer); | 1354 | sx_interrupt(0, board); |
1306 | 1355 | ||
1307 | board->timer.expires = jiffies + sx_poll; | 1356 | mod_timer(&board->timer, jiffies + sx_poll); |
1308 | add_timer (&board->timer); | 1357 | func_exit(); |
1309 | func_exit (); | ||
1310 | } | 1358 | } |
1311 | 1359 | ||
1312 | |||
1313 | |||
1314 | /* ********************************************************************** * | 1360 | /* ********************************************************************** * |
1315 | * Here are the routines that actually * | 1361 | * Here are the routines that actually * |
1316 | * interface with the generic_serial driver * | 1362 | * interface with the generic_serial driver * |
@@ -1319,9 +1365,9 @@ static void sx_pollfunc (unsigned long data) | |||
1319 | /* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */ | 1365 | /* Ehhm. I don't know how to fiddle with interrupts on the SX card. --REW */ |
1320 | /* Hmm. Ok I figured it out. You don't. */ | 1366 | /* Hmm. Ok I figured it out. You don't. */ |
1321 | 1367 | ||
1322 | static void sx_disable_tx_interrupts (void * ptr) | 1368 | static void sx_disable_tx_interrupts(void *ptr) |
1323 | { | 1369 | { |
1324 | struct sx_port *port = ptr; | 1370 | struct sx_port *port = ptr; |
1325 | func_enter2(); | 1371 | func_enter2(); |
1326 | 1372 | ||
1327 | port->gs.flags &= ~GS_TX_INTEN; | 1373 | port->gs.flags &= ~GS_TX_INTEN; |
@@ -1329,30 +1375,28 @@ static void sx_disable_tx_interrupts (void * ptr) | |||
1329 | func_exit(); | 1375 | func_exit(); |
1330 | } | 1376 | } |
1331 | 1377 | ||
1332 | 1378 | static void sx_enable_tx_interrupts(void *ptr) | |
1333 | static void sx_enable_tx_interrupts (void * ptr) | ||
1334 | { | 1379 | { |
1335 | struct sx_port *port = ptr; | 1380 | struct sx_port *port = ptr; |
1336 | int data_in_buffer; | 1381 | int data_in_buffer; |
1337 | func_enter2(); | 1382 | func_enter2(); |
1338 | 1383 | ||
1339 | /* First transmit the characters that we're supposed to */ | 1384 | /* First transmit the characters that we're supposed to */ |
1340 | sx_transmit_chars (port); | 1385 | sx_transmit_chars(port); |
1341 | 1386 | ||
1342 | /* The sx card will never interrupt us if we don't fill the buffer | 1387 | /* The sx card will never interrupt us if we don't fill the buffer |
1343 | past 25%. So we keep considering interrupts off if that's the case. */ | 1388 | past 25%. So we keep considering interrupts off if that's the case. */ |
1344 | data_in_buffer = (sx_read_channel_byte (port, hi_txipos) - | 1389 | data_in_buffer = (sx_read_channel_byte(port, hi_txipos) - |
1345 | sx_read_channel_byte (port, hi_txopos)) & 0xff; | 1390 | sx_read_channel_byte(port, hi_txopos)) & 0xff; |
1346 | 1391 | ||
1347 | /* XXX Must be "HIGH_WATER" for SI card according to doc. */ | 1392 | /* XXX Must be "HIGH_WATER" for SI card according to doc. */ |
1348 | if (data_in_buffer < LOW_WATER) | 1393 | if (data_in_buffer < LOW_WATER) |
1349 | port->gs.flags &= ~GS_TX_INTEN; | 1394 | port->gs.flags &= ~GS_TX_INTEN; |
1350 | 1395 | ||
1351 | func_exit(); | 1396 | func_exit(); |
1352 | } | 1397 | } |
1353 | 1398 | ||
1354 | 1399 | static void sx_disable_rx_interrupts(void *ptr) | |
1355 | static void sx_disable_rx_interrupts (void * ptr) | ||
1356 | { | 1400 | { |
1357 | /* struct sx_port *port = ptr; */ | 1401 | /* struct sx_port *port = ptr; */ |
1358 | func_enter(); | 1402 | func_enter(); |
@@ -1360,7 +1404,7 @@ static void sx_disable_rx_interrupts (void * ptr) | |||
1360 | func_exit(); | 1404 | func_exit(); |
1361 | } | 1405 | } |
1362 | 1406 | ||
1363 | static void sx_enable_rx_interrupts (void * ptr) | 1407 | static void sx_enable_rx_interrupts(void *ptr) |
1364 | { | 1408 | { |
1365 | /* struct sx_port *port = ptr; */ | 1409 | /* struct sx_port *port = ptr; */ |
1366 | func_enter(); | 1410 | func_enter(); |
@@ -1368,55 +1412,48 @@ static void sx_enable_rx_interrupts (void * ptr) | |||
1368 | func_exit(); | 1412 | func_exit(); |
1369 | } | 1413 | } |
1370 | 1414 | ||
1371 | |||
1372 | /* Jeez. Isn't this simple? */ | 1415 | /* Jeez. Isn't this simple? */ |
1373 | static int sx_get_CD (void * ptr) | 1416 | static int sx_get_CD(void *ptr) |
1374 | { | 1417 | { |
1375 | struct sx_port *port = ptr; | 1418 | struct sx_port *port = ptr; |
1376 | func_enter2(); | 1419 | func_enter2(); |
1377 | 1420 | ||
1378 | func_exit(); | 1421 | func_exit(); |
1379 | return ((sx_read_channel_byte (port, hi_ip) & IP_DCD) != 0); | 1422 | return ((sx_read_channel_byte(port, hi_ip) & IP_DCD) != 0); |
1380 | } | 1423 | } |
1381 | 1424 | ||
1382 | |||
1383 | /* Jeez. Isn't this simple? */ | 1425 | /* Jeez. Isn't this simple? */ |
1384 | static int sx_chars_in_buffer (void * ptr) | 1426 | static int sx_chars_in_buffer(void *ptr) |
1385 | { | 1427 | { |
1386 | struct sx_port *port = ptr; | 1428 | struct sx_port *port = ptr; |
1387 | func_enter2(); | 1429 | func_enter2(); |
1388 | 1430 | ||
1389 | func_exit(); | 1431 | func_exit(); |
1390 | return ((sx_read_channel_byte (port, hi_txipos) - | 1432 | return ((sx_read_channel_byte(port, hi_txipos) - |
1391 | sx_read_channel_byte (port, hi_txopos)) & 0xff); | 1433 | sx_read_channel_byte(port, hi_txopos)) & 0xff); |
1392 | } | 1434 | } |
1393 | 1435 | ||
1394 | 1436 | static void sx_shutdown_port(void *ptr) | |
1395 | static void sx_shutdown_port (void * ptr) | ||
1396 | { | 1437 | { |
1397 | struct sx_port *port = ptr; | 1438 | struct sx_port *port = ptr; |
1398 | 1439 | ||
1399 | func_enter(); | 1440 | func_enter(); |
1400 | 1441 | ||
1401 | port->gs.flags &= ~ GS_ACTIVE; | 1442 | port->gs.flags &= ~GS_ACTIVE; |
1402 | if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) { | 1443 | if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) { |
1403 | sx_setsignals (port, 0, 0); | 1444 | sx_setsignals(port, 0, 0); |
1404 | sx_reconfigure_port(port); | 1445 | sx_reconfigure_port(port); |
1405 | } | 1446 | } |
1406 | 1447 | ||
1407 | func_exit(); | 1448 | func_exit(); |
1408 | } | 1449 | } |
1409 | 1450 | ||
1410 | |||
1411 | |||
1412 | |||
1413 | |||
1414 | /* ********************************************************************** * | 1451 | /* ********************************************************************** * |
1415 | * Here are the routines that actually * | 1452 | * Here are the routines that actually * |
1416 | * interface with the rest of the system * | 1453 | * interface with the rest of the system * |
1417 | * ********************************************************************** */ | 1454 | * ********************************************************************** */ |
1418 | 1455 | ||
1419 | static int sx_open (struct tty_struct * tty, struct file * filp) | 1456 | static int sx_open(struct tty_struct *tty, struct file *filp) |
1420 | { | 1457 | { |
1421 | struct sx_port *port; | 1458 | struct sx_port *port; |
1422 | int retval, line; | 1459 | int retval, line; |
@@ -1429,18 +1466,18 @@ static int sx_open (struct tty_struct * tty, struct file * filp) | |||
1429 | } | 1466 | } |
1430 | 1467 | ||
1431 | line = tty->index; | 1468 | line = tty->index; |
1432 | sx_dprintk (SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, np=%d)\n", | 1469 | sx_dprintk(SX_DEBUG_OPEN, "%d: opening line %d. tty=%p ctty=%p, " |
1433 | current->pid, line, tty, current->signal->tty, sx_nports); | 1470 | "np=%d)\n", current->pid, line, tty, |
1471 | current->signal->tty, sx_nports); | ||
1434 | 1472 | ||
1435 | if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) | 1473 | if ((line < 0) || (line >= SX_NPORTS) || (line >= sx_nports)) |
1436 | return -ENODEV; | 1474 | return -ENODEV; |
1437 | 1475 | ||
1438 | port = & sx_ports[line]; | 1476 | port = &sx_ports[line]; |
1439 | port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a | 1477 | port->c_dcd = 0; /* Make sure that the first interrupt doesn't detect a |
1440 | 1 -> 0 transition. */ | 1478 | 1 -> 0 transition. */ |
1441 | 1479 | ||
1442 | 1480 | sx_dprintk(SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd); | |
1443 | sx_dprintk (SX_DEBUG_OPEN, "port = %p c_dcd = %d\n", port, port->c_dcd); | ||
1444 | 1481 | ||
1445 | spin_lock_irqsave(&port->gs.driver_lock, flags); | 1482 | spin_lock_irqsave(&port->gs.driver_lock, flags); |
1446 | 1483 | ||
@@ -1449,13 +1486,13 @@ static int sx_open (struct tty_struct * tty, struct file * filp) | |||
1449 | port->gs.count++; | 1486 | port->gs.count++; |
1450 | spin_unlock_irqrestore(&port->gs.driver_lock, flags); | 1487 | spin_unlock_irqrestore(&port->gs.driver_lock, flags); |
1451 | 1488 | ||
1452 | sx_dprintk (SX_DEBUG_OPEN, "starting port\n"); | 1489 | sx_dprintk(SX_DEBUG_OPEN, "starting port\n"); |
1453 | 1490 | ||
1454 | /* | 1491 | /* |
1455 | * Start up serial port | 1492 | * Start up serial port |
1456 | */ | 1493 | */ |
1457 | retval = gs_init_port(&port->gs); | 1494 | retval = gs_init_port(&port->gs); |
1458 | sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n"); | 1495 | sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n"); |
1459 | if (retval) { | 1496 | if (retval) { |
1460 | port->gs.count--; | 1497 | port->gs.count--; |
1461 | return retval; | 1498 | return retval; |
@@ -1463,19 +1500,20 @@ static int sx_open (struct tty_struct * tty, struct file * filp) | |||
1463 | 1500 | ||
1464 | port->gs.flags |= GS_ACTIVE; | 1501 | port->gs.flags |= GS_ACTIVE; |
1465 | if (port->gs.count <= 1) | 1502 | if (port->gs.count <= 1) |
1466 | sx_setsignals (port, 1,1); | 1503 | sx_setsignals(port, 1, 1); |
1467 | 1504 | ||
1468 | #if 0 | 1505 | #if 0 |
1469 | if (sx_debug & SX_DEBUG_OPEN) | 1506 | if (sx_debug & SX_DEBUG_OPEN) |
1470 | my_hd (port, sizeof (*port)); | 1507 | my_hd(port, sizeof(*port)); |
1471 | #else | 1508 | #else |
1472 | if (sx_debug & SX_DEBUG_OPEN) | 1509 | if (sx_debug & SX_DEBUG_OPEN) |
1473 | my_hd_io (port->board->base + port->ch_base, sizeof (*port)); | 1510 | my_hd_io(port->board->base + port->ch_base, sizeof(*port)); |
1474 | #endif | 1511 | #endif |
1475 | 1512 | ||
1476 | if (port->gs.count <= 1) { | 1513 | if (port->gs.count <= 1) { |
1477 | if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { | 1514 | if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { |
1478 | printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n"); | 1515 | printk(KERN_ERR "sx: Card didn't respond to LOPEN " |
1516 | "command.\n"); | ||
1479 | spin_lock_irqsave(&port->gs.driver_lock, flags); | 1517 | spin_lock_irqsave(&port->gs.driver_lock, flags); |
1480 | port->gs.count--; | 1518 | port->gs.count--; |
1481 | spin_unlock_irqrestore(&port->gs.driver_lock, flags); | 1519 | spin_unlock_irqrestore(&port->gs.driver_lock, flags); |
@@ -1484,75 +1522,76 @@ static int sx_open (struct tty_struct * tty, struct file * filp) | |||
1484 | } | 1522 | } |
1485 | 1523 | ||
1486 | retval = gs_block_til_ready(port, filp); | 1524 | retval = gs_block_til_ready(port, filp); |
1487 | sx_dprintk (SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", | 1525 | sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", |
1488 | retval, port->gs.count); | 1526 | retval, port->gs.count); |
1489 | 1527 | ||
1490 | if (retval) { | 1528 | if (retval) { |
1491 | /* | 1529 | /* |
1492 | * Don't lower gs.count here because sx_close() will be called later | 1530 | * Don't lower gs.count here because sx_close() will be called later |
1493 | */ | 1531 | */ |
1494 | 1532 | ||
1495 | return retval; | 1533 | return retval; |
1496 | } | 1534 | } |
1497 | /* tty->low_latency = 1; */ | 1535 | /* tty->low_latency = 1; */ |
1498 | 1536 | ||
1499 | port->c_dcd = sx_get_CD (port); | 1537 | port->c_dcd = sx_get_CD(port); |
1500 | sx_dprintk (SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); | 1538 | sx_dprintk(SX_DEBUG_OPEN, "at open: cd=%d\n", port->c_dcd); |
1501 | 1539 | ||
1502 | func_exit(); | 1540 | func_exit(); |
1503 | return 0; | 1541 | return 0; |
1504 | 1542 | ||
1505 | } | 1543 | } |
1506 | 1544 | ||
1507 | 1545 | static void sx_close(void *ptr) | |
1508 | static void sx_close (void *ptr) | ||
1509 | { | 1546 | { |
1510 | struct sx_port *port = ptr; | 1547 | struct sx_port *port = ptr; |
1511 | /* Give the port 5 seconds to close down. */ | 1548 | /* Give the port 5 seconds to close down. */ |
1512 | int to = 5 * HZ; | 1549 | int to = 5 * HZ; |
1513 | 1550 | ||
1514 | func_enter (); | 1551 | func_enter(); |
1515 | 1552 | ||
1516 | sx_setsignals (port, 0, 0); | 1553 | sx_setsignals(port, 0, 0); |
1517 | sx_reconfigure_port(port); | 1554 | sx_reconfigure_port(port); |
1518 | sx_send_command (port, HS_CLOSE, 0, 0); | 1555 | sx_send_command(port, HS_CLOSE, 0, 0); |
1519 | 1556 | ||
1520 | while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED)) | 1557 | while (to-- && (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED)) |
1521 | if (msleep_interruptible(10)) | 1558 | if (msleep_interruptible(10)) |
1522 | break; | 1559 | break; |
1523 | if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) { | 1560 | if (sx_read_channel_byte(port, hi_hstat) != HS_IDLE_CLOSED) { |
1524 | if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) { | 1561 | if (sx_send_command(port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) |
1525 | printk (KERN_ERR | 1562 | != 1) { |
1526 | "sx: sent the force_close command, but card didn't react\n"); | 1563 | printk(KERN_ERR "sx: sent the force_close command, but " |
1564 | "card didn't react\n"); | ||
1527 | } else | 1565 | } else |
1528 | sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n"); | 1566 | sx_dprintk(SX_DEBUG_CLOSE, "sent the force_close " |
1567 | "command.\n"); | ||
1529 | } | 1568 | } |
1530 | 1569 | ||
1531 | sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", | 1570 | sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", |
1532 | 5 * HZ - to - 1, port->gs.count); | 1571 | 5 * HZ - to - 1, port->gs.count); |
1533 | 1572 | ||
1534 | if(port->gs.count) { | 1573 | if (port->gs.count) { |
1535 | sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count); | 1574 | sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", |
1536 | //printk ("%s SETTING port count to zero: %p count: %d\n", __FUNCTION__, port, port->gs.count); | 1575 | port->gs.count); |
1537 | //port->gs.count = 0; | 1576 | /*printk("%s SETTING port count to zero: %p count: %d\n", |
1577 | __FUNCTION__, port, port->gs.count); | ||
1578 | port->gs.count = 0;*/ | ||
1538 | } | 1579 | } |
1539 | 1580 | ||
1540 | func_exit (); | 1581 | func_exit(); |
1541 | } | 1582 | } |
1542 | 1583 | ||
1543 | |||
1544 | |||
1545 | /* This is relatively thorough. But then again it is only 20 lines. */ | 1584 | /* This is relatively thorough. But then again it is only 20 lines. */ |
1546 | #define MARCHUP for (i=min;i<max;i++) | 1585 | #define MARCHUP for (i = min; i < max; i++) |
1547 | #define MARCHDOWN for (i=max-1;i>=min;i--) | 1586 | #define MARCHDOWN for (i = max - 1; i >= min; i--) |
1548 | #define W0 write_sx_byte (board, i, 0x55) | 1587 | #define W0 write_sx_byte(board, i, 0x55) |
1549 | #define W1 write_sx_byte (board, i, 0xaa) | 1588 | #define W1 write_sx_byte(board, i, 0xaa) |
1550 | #define R0 if (read_sx_byte (board, i) != 0x55) return 1 | 1589 | #define R0 if (read_sx_byte(board, i) != 0x55) return 1 |
1551 | #define R1 if (read_sx_byte (board, i) != 0xaa) return 1 | 1590 | #define R1 if (read_sx_byte(board, i) != 0xaa) return 1 |
1552 | 1591 | ||
1553 | /* This memtest takes a human-noticable time. You normally only do it | 1592 | /* This memtest takes a human-noticable time. You normally only do it |
1554 | once a boot, so I guess that it is worth it. */ | 1593 | once a boot, so I guess that it is worth it. */ |
1555 | static int do_memtest (struct sx_board *board, int min, int max) | 1594 | static int do_memtest(struct sx_board *board, int min, int max) |
1556 | { | 1595 | { |
1557 | int i; | 1596 | int i; |
1558 | 1597 | ||
@@ -1561,16 +1600,37 @@ static int do_memtest (struct sx_board *board, int min, int max) | |||
1561 | intermittent errors. -- REW | 1600 | intermittent errors. -- REW |
1562 | (For the theory behind memory testing see: | 1601 | (For the theory behind memory testing see: |
1563 | Testing Semiconductor Memories by A.J. van de Goor.) */ | 1602 | Testing Semiconductor Memories by A.J. van de Goor.) */ |
1564 | MARCHUP {W0;} | 1603 | MARCHUP { |
1565 | MARCHUP {R0;W1;R1;W0;R0;W1;} | 1604 | W0; |
1566 | MARCHUP {R1;W0;W1;} | 1605 | } |
1567 | MARCHDOWN {R1;W0;W1;W0;} | 1606 | MARCHUP { |
1568 | MARCHDOWN {R0;W1;W0;} | 1607 | R0; |
1608 | W1; | ||
1609 | R1; | ||
1610 | W0; | ||
1611 | R0; | ||
1612 | W1; | ||
1613 | } | ||
1614 | MARCHUP { | ||
1615 | R1; | ||
1616 | W0; | ||
1617 | W1; | ||
1618 | } | ||
1619 | MARCHDOWN { | ||
1620 | R1; | ||
1621 | W0; | ||
1622 | W1; | ||
1623 | W0; | ||
1624 | } | ||
1625 | MARCHDOWN { | ||
1626 | R0; | ||
1627 | W1; | ||
1628 | W0; | ||
1629 | } | ||
1569 | 1630 | ||
1570 | return 0; | 1631 | return 0; |
1571 | } | 1632 | } |
1572 | 1633 | ||
1573 | |||
1574 | #undef MARCHUP | 1634 | #undef MARCHUP |
1575 | #undef MARCHDOWN | 1635 | #undef MARCHDOWN |
1576 | #undef W0 | 1636 | #undef W0 |
@@ -1578,33 +1638,54 @@ static int do_memtest (struct sx_board *board, int min, int max) | |||
1578 | #undef R0 | 1638 | #undef R0 |
1579 | #undef R1 | 1639 | #undef R1 |
1580 | 1640 | ||
1581 | #define MARCHUP for (i=min;i<max;i+=2) | 1641 | #define MARCHUP for (i = min; i < max; i += 2) |
1582 | #define MARCHDOWN for (i=max-1;i>=min;i-=2) | 1642 | #define MARCHDOWN for (i = max - 1; i >= min; i -= 2) |
1583 | #define W0 write_sx_word (board, i, 0x55aa) | 1643 | #define W0 write_sx_word(board, i, 0x55aa) |
1584 | #define W1 write_sx_word (board, i, 0xaa55) | 1644 | #define W1 write_sx_word(board, i, 0xaa55) |
1585 | #define R0 if (read_sx_word (board, i) != 0x55aa) return 1 | 1645 | #define R0 if (read_sx_word(board, i) != 0x55aa) return 1 |
1586 | #define R1 if (read_sx_word (board, i) != 0xaa55) return 1 | 1646 | #define R1 if (read_sx_word(board, i) != 0xaa55) return 1 |
1587 | 1647 | ||
1588 | #if 0 | 1648 | #if 0 |
1589 | /* This memtest takes a human-noticable time. You normally only do it | 1649 | /* This memtest takes a human-noticable time. You normally only do it |
1590 | once a boot, so I guess that it is worth it. */ | 1650 | once a boot, so I guess that it is worth it. */ |
1591 | static int do_memtest_w (struct sx_board *board, int min, int max) | 1651 | static int do_memtest_w(struct sx_board *board, int min, int max) |
1592 | { | 1652 | { |
1593 | int i; | 1653 | int i; |
1594 | 1654 | ||
1595 | MARCHUP {W0;} | 1655 | MARCHUP { |
1596 | MARCHUP {R0;W1;R1;W0;R0;W1;} | 1656 | W0; |
1597 | MARCHUP {R1;W0;W1;} | 1657 | } |
1598 | MARCHDOWN {R1;W0;W1;W0;} | 1658 | MARCHUP { |
1599 | MARCHDOWN {R0;W1;W0;} | 1659 | R0; |
1660 | W1; | ||
1661 | R1; | ||
1662 | W0; | ||
1663 | R0; | ||
1664 | W1; | ||
1665 | } | ||
1666 | MARCHUP { | ||
1667 | R1; | ||
1668 | W0; | ||
1669 | W1; | ||
1670 | } | ||
1671 | MARCHDOWN { | ||
1672 | R1; | ||
1673 | W0; | ||
1674 | W1; | ||
1675 | W0; | ||
1676 | } | ||
1677 | MARCHDOWN { | ||
1678 | R0; | ||
1679 | W1; | ||
1680 | W0; | ||
1681 | } | ||
1600 | 1682 | ||
1601 | return 0; | 1683 | return 0; |
1602 | } | 1684 | } |
1603 | #endif | 1685 | #endif |
1604 | 1686 | ||
1605 | 1687 | static int sx_fw_ioctl(struct inode *inode, struct file *filp, | |
1606 | static int sx_fw_ioctl (struct inode *inode, struct file *filp, | 1688 | unsigned int cmd, unsigned long arg) |
1607 | unsigned int cmd, unsigned long arg) | ||
1608 | { | 1689 | { |
1609 | int rc = 0; | 1690 | int rc = 0; |
1610 | int __user *descr = (int __user *)arg; | 1691 | int __user *descr = (int __user *)arg; |
@@ -1616,7 +1697,7 @@ static int sx_fw_ioctl (struct inode *inode, struct file *filp, | |||
1616 | 1697 | ||
1617 | func_enter(); | 1698 | func_enter(); |
1618 | 1699 | ||
1619 | #if 0 | 1700 | #if 0 |
1620 | /* Removed superuser check: Sysops can use the permissions on the device | 1701 | /* Removed superuser check: Sysops can use the permissions on the device |
1621 | file to restrict access. Recommendation: Root only. (root.root 600) */ | 1702 | file to restrict access. Recommendation: Root only. (root.root 600) */ |
1622 | if (!capable(CAP_SYS_ADMIN)) { | 1703 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -1624,103 +1705,115 @@ static int sx_fw_ioctl (struct inode *inode, struct file *filp, | |||
1624 | } | 1705 | } |
1625 | #endif | 1706 | #endif |
1626 | 1707 | ||
1627 | sx_dprintk (SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); | 1708 | sx_dprintk(SX_DEBUG_FIRMWARE, "IOCTL %x: %lx\n", cmd, arg); |
1628 | 1709 | ||
1629 | if (!board) board = &boards[0]; | 1710 | if (!board) |
1711 | board = &boards[0]; | ||
1630 | if (board->flags & SX_BOARD_PRESENT) { | 1712 | if (board->flags & SX_BOARD_PRESENT) { |
1631 | sx_dprintk (SX_DEBUG_FIRMWARE, "Board present! (%x)\n", | 1713 | sx_dprintk(SX_DEBUG_FIRMWARE, "Board present! (%x)\n", |
1632 | board->flags); | 1714 | board->flags); |
1633 | } else { | 1715 | } else { |
1634 | sx_dprintk (SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", | 1716 | sx_dprintk(SX_DEBUG_FIRMWARE, "Board not present! (%x) all:", |
1635 | board->flags); | 1717 | board->flags); |
1636 | for (i=0;i< SX_NBOARDS;i++) | 1718 | for (i = 0; i < SX_NBOARDS; i++) |
1637 | sx_dprintk (SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); | 1719 | sx_dprintk(SX_DEBUG_FIRMWARE, "<%x> ", boards[i].flags); |
1638 | sx_dprintk (SX_DEBUG_FIRMWARE, "\n"); | 1720 | sx_dprintk(SX_DEBUG_FIRMWARE, "\n"); |
1639 | return -EIO; | 1721 | return -EIO; |
1640 | } | 1722 | } |
1641 | 1723 | ||
1642 | switch (cmd) { | 1724 | switch (cmd) { |
1643 | case SXIO_SET_BOARD: | 1725 | case SXIO_SET_BOARD: |
1644 | sx_dprintk (SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); | 1726 | sx_dprintk(SX_DEBUG_FIRMWARE, "set board to %ld\n", arg); |
1645 | if (arg >= SX_NBOARDS) return -EIO; | 1727 | if (arg >= SX_NBOARDS) |
1646 | sx_dprintk (SX_DEBUG_FIRMWARE, "not out of range\n"); | 1728 | return -EIO; |
1647 | if (!(boards[arg].flags & SX_BOARD_PRESENT)) return -EIO; | 1729 | sx_dprintk(SX_DEBUG_FIRMWARE, "not out of range\n"); |
1648 | sx_dprintk (SX_DEBUG_FIRMWARE, ".. and present!\n"); | 1730 | if (!(boards[arg].flags & SX_BOARD_PRESENT)) |
1731 | return -EIO; | ||
1732 | sx_dprintk(SX_DEBUG_FIRMWARE, ".. and present!\n"); | ||
1649 | board = &boards[arg]; | 1733 | board = &boards[arg]; |
1650 | break; | 1734 | break; |
1651 | case SXIO_GET_TYPE: | 1735 | case SXIO_GET_TYPE: |
1652 | rc = -ENOENT; /* If we manage to miss one, return error. */ | 1736 | rc = -ENOENT; /* If we manage to miss one, return error. */ |
1653 | if (IS_SX_BOARD (board)) rc = SX_TYPE_SX; | 1737 | if (IS_SX_BOARD(board)) |
1654 | if (IS_CF_BOARD (board)) rc = SX_TYPE_CF; | 1738 | rc = SX_TYPE_SX; |
1655 | if (IS_SI_BOARD (board)) rc = SX_TYPE_SI; | 1739 | if (IS_CF_BOARD(board)) |
1656 | if (IS_SI1_BOARD (board)) rc = SX_TYPE_SI; | 1740 | rc = SX_TYPE_CF; |
1657 | if (IS_EISA_BOARD (board)) rc = SX_TYPE_SI; | 1741 | if (IS_SI_BOARD(board)) |
1658 | sx_dprintk (SX_DEBUG_FIRMWARE, "returning type= %d\n", rc); | 1742 | rc = SX_TYPE_SI; |
1743 | if (IS_SI1_BOARD(board)) | ||
1744 | rc = SX_TYPE_SI; | ||
1745 | if (IS_EISA_BOARD(board)) | ||
1746 | rc = SX_TYPE_SI; | ||
1747 | sx_dprintk(SX_DEBUG_FIRMWARE, "returning type= %d\n", rc); | ||
1659 | break; | 1748 | break; |
1660 | case SXIO_DO_RAMTEST: | 1749 | case SXIO_DO_RAMTEST: |
1661 | if (sx_initialized) /* Already initialized: better not ramtest the board. */ | 1750 | if (sx_initialized) /* Already initialized: better not ramtest the board. */ |
1662 | return -EPERM; | 1751 | return -EPERM; |
1663 | if (IS_SX_BOARD (board)) { | 1752 | if (IS_SX_BOARD(board)) { |
1664 | rc = do_memtest (board, 0, 0x7000); | 1753 | rc = do_memtest(board, 0, 0x7000); |
1665 | if (!rc) rc = do_memtest (board, 0, 0x7000); | 1754 | if (!rc) |
1666 | /*if (!rc) rc = do_memtest_w (board, 0, 0x7000);*/ | 1755 | rc = do_memtest(board, 0, 0x7000); |
1756 | /*if (!rc) rc = do_memtest_w (board, 0, 0x7000); */ | ||
1667 | } else { | 1757 | } else { |
1668 | rc = do_memtest (board, 0, 0x7ff8); | 1758 | rc = do_memtest(board, 0, 0x7ff8); |
1669 | /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ | 1759 | /* if (!rc) rc = do_memtest_w (board, 0, 0x7ff8); */ |
1670 | } | 1760 | } |
1671 | sx_dprintk (SX_DEBUG_FIRMWARE, "returning memtest result= %d\n", rc); | 1761 | sx_dprintk(SX_DEBUG_FIRMWARE, "returning memtest result= %d\n", |
1762 | rc); | ||
1672 | break; | 1763 | break; |
1673 | case SXIO_DOWNLOAD: | 1764 | case SXIO_DOWNLOAD: |
1674 | if (sx_initialized) /* Already initialized */ | 1765 | if (sx_initialized) /* Already initialized */ |
1675 | return -EEXIST; | 1766 | return -EEXIST; |
1676 | if (!sx_reset (board)) | 1767 | if (!sx_reset(board)) |
1677 | return -EIO; | 1768 | return -EIO; |
1678 | sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); | 1769 | sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); |
1679 | 1770 | ||
1680 | tmp = kmalloc (SX_CHUNK_SIZE, GFP_USER); | 1771 | tmp = kmalloc(SX_CHUNK_SIZE, GFP_USER); |
1681 | if (!tmp) return -ENOMEM; | 1772 | if (!tmp) |
1682 | get_user (nbytes, descr++); | 1773 | return -ENOMEM; |
1683 | get_user (offset, descr++); | 1774 | get_user(nbytes, descr++); |
1684 | get_user (data, descr++); | 1775 | get_user(offset, descr++); |
1776 | get_user(data, descr++); | ||
1685 | while (nbytes && data) { | 1777 | while (nbytes && data) { |
1686 | for (i=0;i<nbytes;i += SX_CHUNK_SIZE) { | 1778 | for (i = 0; i < nbytes; i += SX_CHUNK_SIZE) { |
1687 | if (copy_from_user(tmp, (char __user *)data+i, | 1779 | if (copy_from_user(tmp, (char __user *)data + i, |
1688 | (i + SX_CHUNK_SIZE > | 1780 | (i + SX_CHUNK_SIZE > nbytes) ? |
1689 | nbytes) ? nbytes - i : | 1781 | nbytes - i : SX_CHUNK_SIZE)) { |
1690 | SX_CHUNK_SIZE)) { | 1782 | kfree(tmp); |
1691 | kfree (tmp); | ||
1692 | return -EFAULT; | 1783 | return -EFAULT; |
1693 | } | 1784 | } |
1694 | memcpy_toio(board->base2 + offset + i, tmp, | 1785 | memcpy_toio(board->base2 + offset + i, tmp, |
1695 | (i+SX_CHUNK_SIZE>nbytes)?nbytes-i:SX_CHUNK_SIZE); | 1786 | (i + SX_CHUNK_SIZE > nbytes) ? |
1787 | nbytes - i : SX_CHUNK_SIZE); | ||
1696 | } | 1788 | } |
1697 | 1789 | ||
1698 | get_user (nbytes, descr++); | 1790 | get_user(nbytes, descr++); |
1699 | get_user (offset, descr++); | 1791 | get_user(offset, descr++); |
1700 | get_user (data, descr++); | 1792 | get_user(data, descr++); |
1701 | } | 1793 | } |
1702 | kfree (tmp); | 1794 | kfree(tmp); |
1703 | sx_nports += sx_init_board (board); | 1795 | sx_nports += sx_init_board(board); |
1704 | rc = sx_nports; | 1796 | rc = sx_nports; |
1705 | break; | 1797 | break; |
1706 | case SXIO_INIT: | 1798 | case SXIO_INIT: |
1707 | if (sx_initialized) /* Already initialized */ | 1799 | if (sx_initialized) /* Already initialized */ |
1708 | return -EEXIST; | 1800 | return -EEXIST; |
1709 | /* This is not allowed until all boards are initialized... */ | 1801 | /* This is not allowed until all boards are initialized... */ |
1710 | for (i=0;i<SX_NBOARDS;i++) { | 1802 | for (i = 0; i < SX_NBOARDS; i++) { |
1711 | if ( (boards[i].flags & SX_BOARD_PRESENT) && | 1803 | if ((boards[i].flags & SX_BOARD_PRESENT) && |
1712 | !(boards[i].flags & SX_BOARD_INITIALIZED)) | 1804 | !(boards[i].flags & SX_BOARD_INITIALIZED)) |
1713 | return -EIO; | 1805 | return -EIO; |
1714 | } | 1806 | } |
1715 | for (i=0;i<SX_NBOARDS;i++) | 1807 | for (i = 0; i < SX_NBOARDS; i++) |
1716 | if (!(boards[i].flags & SX_BOARD_PRESENT)) break; | 1808 | if (!(boards[i].flags & SX_BOARD_PRESENT)) |
1717 | 1809 | break; | |
1718 | sx_dprintk (SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, " | 1810 | |
1719 | "%d channels, first board: %d ports\n", | 1811 | sx_dprintk(SX_DEBUG_FIRMWARE, "initing portstructs, %d boards, " |
1720 | i, sx_nports, boards[0].nports); | 1812 | "%d channels, first board: %d ports\n", |
1721 | rc = sx_init_portstructs (i, sx_nports); | 1813 | i, sx_nports, boards[0].nports); |
1722 | sx_init_drivers (); | 1814 | rc = sx_init_portstructs(i, sx_nports); |
1723 | if (rc >= 0) | 1815 | sx_init_drivers(); |
1816 | if (rc >= 0) | ||
1724 | sx_initialized++; | 1817 | sx_initialized++; |
1725 | break; | 1818 | break; |
1726 | case SXIO_SETDEBUG: | 1819 | case SXIO_SETDEBUG: |
@@ -1737,32 +1830,32 @@ static int sx_fw_ioctl (struct inode *inode, struct file *filp, | |||
1737 | rc = sx_nports; | 1830 | rc = sx_nports; |
1738 | break; | 1831 | break; |
1739 | default: | 1832 | default: |
1740 | printk (KERN_WARNING "Unknown ioctl on firmware device (%x).\n", cmd); | 1833 | printk(KERN_WARNING "Unknown ioctl on firmware device (%x).\n", |
1834 | cmd); | ||
1741 | break; | 1835 | break; |
1742 | } | 1836 | } |
1743 | func_exit (); | 1837 | func_exit(); |
1744 | return rc; | 1838 | return rc; |
1745 | } | 1839 | } |
1746 | 1840 | ||
1747 | 1841 | static void sx_break(struct tty_struct *tty, int flag) | |
1748 | static void sx_break (struct tty_struct * tty, int flag) | ||
1749 | { | 1842 | { |
1750 | struct sx_port *port = tty->driver_data; | 1843 | struct sx_port *port = tty->driver_data; |
1751 | int rv; | 1844 | int rv; |
1752 | 1845 | ||
1753 | func_enter (); | 1846 | func_enter(); |
1754 | 1847 | ||
1755 | if (flag) | 1848 | if (flag) |
1756 | rv = sx_send_command (port, HS_START, -1, HS_IDLE_BREAK); | 1849 | rv = sx_send_command(port, HS_START, -1, HS_IDLE_BREAK); |
1757 | else | 1850 | else |
1758 | rv = sx_send_command (port, HS_STOP, -1, HS_IDLE_OPEN); | 1851 | rv = sx_send_command(port, HS_STOP, -1, HS_IDLE_OPEN); |
1759 | if (rv != 1) printk (KERN_ERR "sx: couldn't send break (%x).\n", | 1852 | if (rv != 1) |
1760 | read_sx_byte (port->board, CHAN_OFFSET (port, hi_hstat))); | 1853 | printk(KERN_ERR "sx: couldn't send break (%x).\n", |
1854 | read_sx_byte(port->board, CHAN_OFFSET(port, hi_hstat))); | ||
1761 | 1855 | ||
1762 | func_exit (); | 1856 | func_exit(); |
1763 | } | 1857 | } |
1764 | 1858 | ||
1765 | |||
1766 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) | 1859 | static int sx_tiocmget(struct tty_struct *tty, struct file *file) |
1767 | { | 1860 | { |
1768 | struct sx_port *port = tty->driver_data; | 1861 | struct sx_port *port = tty->driver_data; |
@@ -1770,7 +1863,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file) | |||
1770 | } | 1863 | } |
1771 | 1864 | ||
1772 | static int sx_tiocmset(struct tty_struct *tty, struct file *file, | 1865 | static int sx_tiocmset(struct tty_struct *tty, struct file *file, |
1773 | unsigned int set, unsigned int clear) | 1866 | unsigned int set, unsigned int clear) |
1774 | { | 1867 | { |
1775 | struct sx_port *port = tty->driver_data; | 1868 | struct sx_port *port = tty->driver_data; |
1776 | int rts = -1, dtr = -1; | 1869 | int rts = -1, dtr = -1; |
@@ -1789,8 +1882,8 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file, | |||
1789 | return 0; | 1882 | return 0; |
1790 | } | 1883 | } |
1791 | 1884 | ||
1792 | static int sx_ioctl (struct tty_struct * tty, struct file * filp, | 1885 | static int sx_ioctl(struct tty_struct *tty, struct file *filp, |
1793 | unsigned int cmd, unsigned long arg) | 1886 | unsigned int cmd, unsigned long arg) |
1794 | { | 1887 | { |
1795 | int rc; | 1888 | int rc; |
1796 | struct sx_port *port = tty->driver_data; | 1889 | struct sx_port *port = tty->driver_data; |
@@ -1803,10 +1896,10 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp, | |||
1803 | switch (cmd) { | 1896 | switch (cmd) { |
1804 | case TIOCGSOFTCAR: | 1897 | case TIOCGSOFTCAR: |
1805 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), | 1898 | rc = put_user(((tty->termios->c_cflag & CLOCAL) ? 1 : 0), |
1806 | (unsigned __user *) argp); | 1899 | (unsigned __user *)argp); |
1807 | break; | 1900 | break; |
1808 | case TIOCSSOFTCAR: | 1901 | case TIOCSSOFTCAR: |
1809 | if ((rc = get_user(ival, (unsigned __user *) argp)) == 0) { | 1902 | if ((rc = get_user(ival, (unsigned __user *)argp)) == 0) { |
1810 | tty->termios->c_cflag = | 1903 | tty->termios->c_cflag = |
1811 | (tty->termios->c_cflag & ~CLOCAL) | | 1904 | (tty->termios->c_cflag & ~CLOCAL) | |
1812 | (ival ? CLOCAL : 0); | 1905 | (ival ? CLOCAL : 0); |
@@ -1827,7 +1920,6 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp, | |||
1827 | return rc; | 1920 | return rc; |
1828 | } | 1921 | } |
1829 | 1922 | ||
1830 | |||
1831 | /* The throttle/unthrottle scheme for the Specialix card is different | 1923 | /* The throttle/unthrottle scheme for the Specialix card is different |
1832 | * from other drivers and deserves some explanation. | 1924 | * from other drivers and deserves some explanation. |
1833 | * The Specialix hardware takes care of XON/XOFF | 1925 | * The Specialix hardware takes care of XON/XOFF |
@@ -1844,7 +1936,7 @@ static int sx_ioctl (struct tty_struct * tty, struct file * filp, | |||
1844 | * flow control scheme is in use for that port. -- Simon Allen | 1936 | * flow control scheme is in use for that port. -- Simon Allen |
1845 | */ | 1937 | */ |
1846 | 1938 | ||
1847 | static void sx_throttle (struct tty_struct * tty) | 1939 | static void sx_throttle(struct tty_struct *tty) |
1848 | { | 1940 | { |
1849 | struct sx_port *port = (struct sx_port *)tty->driver_data; | 1941 | struct sx_port *port = (struct sx_port *)tty->driver_data; |
1850 | 1942 | ||
@@ -1852,14 +1944,13 @@ static void sx_throttle (struct tty_struct * tty) | |||
1852 | /* If the port is using any type of input flow | 1944 | /* If the port is using any type of input flow |
1853 | * control then throttle the port. | 1945 | * control then throttle the port. |
1854 | */ | 1946 | */ |
1855 | if((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty)) ) { | 1947 | if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { |
1856 | port->gs.flags |= SX_RX_THROTTLE; | 1948 | port->gs.flags |= SX_RX_THROTTLE; |
1857 | } | 1949 | } |
1858 | func_exit(); | 1950 | func_exit(); |
1859 | } | 1951 | } |
1860 | 1952 | ||
1861 | 1953 | static void sx_unthrottle(struct tty_struct *tty) | |
1862 | static void sx_unthrottle (struct tty_struct * tty) | ||
1863 | { | 1954 | { |
1864 | struct sx_port *port = (struct sx_port *)tty->driver_data; | 1955 | struct sx_port *port = (struct sx_port *)tty->driver_data; |
1865 | 1956 | ||
@@ -1873,15 +1964,11 @@ static void sx_unthrottle (struct tty_struct * tty) | |||
1873 | return; | 1964 | return; |
1874 | } | 1965 | } |
1875 | 1966 | ||
1876 | |||
1877 | /* ********************************************************************** * | 1967 | /* ********************************************************************** * |
1878 | * Here are the initialization routines. * | 1968 | * Here are the initialization routines. * |
1879 | * ********************************************************************** */ | 1969 | * ********************************************************************** */ |
1880 | 1970 | ||
1881 | 1971 | static int sx_init_board(struct sx_board *board) | |
1882 | |||
1883 | |||
1884 | static int sx_init_board (struct sx_board *board) | ||
1885 | { | 1972 | { |
1886 | int addr; | 1973 | int addr; |
1887 | int chans; | 1974 | int chans; |
@@ -1893,36 +1980,38 @@ static int sx_init_board (struct sx_board *board) | |||
1893 | 1980 | ||
1894 | board->flags |= SX_BOARD_INITIALIZED; | 1981 | board->flags |= SX_BOARD_INITIALIZED; |
1895 | 1982 | ||
1896 | if (read_sx_byte (board, 0)) | 1983 | if (read_sx_byte(board, 0)) |
1897 | /* CF boards may need this. */ | 1984 | /* CF boards may need this. */ |
1898 | write_sx_byte(board,0, 0); | 1985 | write_sx_byte(board, 0, 0); |
1899 | 1986 | ||
1900 | /* This resets the processor again, to make sure it didn't do any | 1987 | /* This resets the processor again, to make sure it didn't do any |
1901 | foolish things while we were downloading the image */ | 1988 | foolish things while we were downloading the image */ |
1902 | if (!sx_reset (board)) | 1989 | if (!sx_reset(board)) |
1903 | return 0; | 1990 | return 0; |
1904 | 1991 | ||
1905 | sx_start_board (board); | 1992 | sx_start_board(board); |
1906 | udelay (10); | 1993 | udelay(10); |
1907 | if (!sx_busy_wait_neq (board, 0, 0xff, 0)) { | 1994 | if (!sx_busy_wait_neq(board, 0, 0xff, 0)) { |
1908 | printk (KERN_ERR "sx: Ooops. Board won't initialize.\n"); | 1995 | printk(KERN_ERR "sx: Ooops. Board won't initialize.\n"); |
1909 | return 0; | 1996 | return 0; |
1910 | } | 1997 | } |
1911 | 1998 | ||
1912 | /* Ok. So now the processor on the card is running. It gathered | 1999 | /* Ok. So now the processor on the card is running. It gathered |
1913 | some info for us... */ | 2000 | some info for us... */ |
1914 | sx_dprintk (SX_DEBUG_INIT, "The sxcard structure:\n"); | 2001 | sx_dprintk(SX_DEBUG_INIT, "The sxcard structure:\n"); |
1915 | if (sx_debug & SX_DEBUG_INIT) my_hd_io (board->base, 0x10); | 2002 | if (sx_debug & SX_DEBUG_INIT) |
1916 | sx_dprintk (SX_DEBUG_INIT, "the first sx_module structure:\n"); | 2003 | my_hd_io(board->base, 0x10); |
1917 | if (sx_debug & SX_DEBUG_INIT) my_hd_io (board->base + 0x80, 0x30); | 2004 | sx_dprintk(SX_DEBUG_INIT, "the first sx_module structure:\n"); |
1918 | 2005 | if (sx_debug & SX_DEBUG_INIT) | |
1919 | sx_dprintk (SX_DEBUG_INIT, | 2006 | my_hd_io(board->base + 0x80, 0x30); |
1920 | "init_status: %x, %dk memory, firmware V%x.%02x,\n", | 2007 | |
1921 | read_sx_byte (board, 0), read_sx_byte(board, 1), | 2008 | sx_dprintk(SX_DEBUG_INIT, "init_status: %x, %dk memory, firmware " |
1922 | read_sx_byte (board, 5), read_sx_byte(board, 4)); | 2009 | "V%x.%02x,\n", |
1923 | 2010 | read_sx_byte(board, 0), read_sx_byte(board, 1), | |
1924 | if (read_sx_byte (board, 0) == 0xff) { | 2011 | read_sx_byte(board, 5), read_sx_byte(board, 4)); |
1925 | printk (KERN_INFO "sx: No modules found. Sorry.\n"); | 2012 | |
2013 | if (read_sx_byte(board, 0) == 0xff) { | ||
2014 | printk(KERN_INFO "sx: No modules found. Sorry.\n"); | ||
1926 | board->nports = 0; | 2015 | board->nports = 0; |
1927 | return 0; | 2016 | return 0; |
1928 | } | 2017 | } |
@@ -1930,82 +2019,97 @@ static int sx_init_board (struct sx_board *board) | |||
1930 | chans = 0; | 2019 | chans = 0; |
1931 | 2020 | ||
1932 | if (IS_SX_BOARD(board)) { | 2021 | if (IS_SX_BOARD(board)) { |
1933 | sx_write_board_word (board, cc_int_count, sx_maxints); | 2022 | sx_write_board_word(board, cc_int_count, sx_maxints); |
1934 | } else { | 2023 | } else { |
1935 | if (sx_maxints) | 2024 | if (sx_maxints) |
1936 | sx_write_board_word (board, cc_int_count, SI_PROCESSOR_CLOCK/8/sx_maxints); | 2025 | sx_write_board_word(board, cc_int_count, |
2026 | SI_PROCESSOR_CLOCK / 8 / sx_maxints); | ||
1937 | } | 2027 | } |
1938 | 2028 | ||
1939 | /* grab the first module type... */ | 2029 | /* grab the first module type... */ |
1940 | /* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */ | 2030 | /* board->ta_type = mod_compat_type (read_sx_byte (board, 0x80 + 0x08)); */ |
1941 | board->ta_type = mod_compat_type (sx_read_module_byte (board, 0x80, mc_chip)); | 2031 | board->ta_type = mod_compat_type(sx_read_module_byte(board, 0x80, |
2032 | mc_chip)); | ||
1942 | 2033 | ||
1943 | /* XXX byteorder */ | 2034 | /* XXX byteorder */ |
1944 | for (addr = 0x80;addr != 0;addr = read_sx_word (board, addr) & 0x7fff) { | 2035 | for (addr = 0x80; addr != 0; addr = read_sx_word(board, addr) & 0x7fff){ |
1945 | type = sx_read_module_byte (board, addr, mc_chip); | 2036 | type = sx_read_module_byte(board, addr, mc_chip); |
1946 | sx_dprintk (SX_DEBUG_INIT, "Module at %x: %d channels\n", | 2037 | sx_dprintk(SX_DEBUG_INIT, "Module at %x: %d channels\n", |
1947 | addr, read_sx_byte (board, addr + 2)); | 2038 | addr, read_sx_byte(board, addr + 2)); |
1948 | 2039 | ||
1949 | chans += sx_read_module_byte (board, addr, mc_type); | 2040 | chans += sx_read_module_byte(board, addr, mc_type); |
1950 | 2041 | ||
1951 | sx_dprintk (SX_DEBUG_INIT, "module is an %s, which has %s/%s panels\n", | 2042 | sx_dprintk(SX_DEBUG_INIT, "module is an %s, which has %s/%s " |
1952 | mod_type_s (type), | 2043 | "panels\n", |
1953 | pan_type_s (sx_read_module_byte (board, addr, mc_mods) & 0xf), | 2044 | mod_type_s(type), |
1954 | pan_type_s (sx_read_module_byte (board, addr, mc_mods) >> 4)); | 2045 | pan_type_s(sx_read_module_byte(board, addr, |
1955 | 2046 | mc_mods) & 0xf), | |
1956 | sx_dprintk (SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC version: %x\n", | 2047 | pan_type_s(sx_read_module_byte(board, addr, |
1957 | sx_read_module_byte (board, addr, mc_rev1), | 2048 | mc_mods) >> 4)); |
1958 | sx_read_module_byte (board, addr, mc_rev2), | 2049 | |
1959 | sx_read_module_byte (board, addr, mc_mtaasic_rev)); | 2050 | sx_dprintk(SX_DEBUG_INIT, "CD1400 versions: %x/%x, ASIC " |
2051 | "version: %x\n", | ||
2052 | sx_read_module_byte(board, addr, mc_rev1), | ||
2053 | sx_read_module_byte(board, addr, mc_rev2), | ||
2054 | sx_read_module_byte(board, addr, mc_mtaasic_rev)); | ||
1960 | 2055 | ||
1961 | /* The following combinations are illegal: It should theoretically | 2056 | /* The following combinations are illegal: It should theoretically |
1962 | work, but timing problems make the bus HANG. */ | 2057 | work, but timing problems make the bus HANG. */ |
1963 | 2058 | ||
1964 | if (mod_compat_type (type) != board->ta_type) { | 2059 | if (mod_compat_type(type) != board->ta_type) { |
1965 | printk (KERN_ERR "sx: This is an invalid configuration.\n" | 2060 | printk(KERN_ERR "sx: This is an invalid " |
1966 | "Don't mix TA/MTA/SXDC on the same hostadapter.\n"); | 2061 | "configuration.\nDon't mix TA/MTA/SXDC on the " |
1967 | chans=0; | 2062 | "same hostadapter.\n"); |
2063 | chans = 0; | ||
1968 | break; | 2064 | break; |
1969 | } | 2065 | } |
1970 | if ((IS_EISA_BOARD(board) || | 2066 | if ((IS_EISA_BOARD(board) || |
1971 | IS_SI_BOARD(board)) && (mod_compat_type(type) == 4)) { | 2067 | IS_SI_BOARD(board)) && |
1972 | printk (KERN_ERR "sx: This is an invalid configuration.\n" | 2068 | (mod_compat_type(type) == 4)) { |
1973 | "Don't use SXDCs on an SI/XIO adapter.\n"); | 2069 | printk(KERN_ERR "sx: This is an invalid " |
1974 | chans=0; | 2070 | "configuration.\nDon't use SXDCs on an SI/XIO " |
2071 | "adapter.\n"); | ||
2072 | chans = 0; | ||
1975 | break; | 2073 | break; |
1976 | } | 2074 | } |
1977 | #if 0 /* Problem fixed: firmware 3.05 */ | 2075 | #if 0 /* Problem fixed: firmware 3.05 */ |
1978 | if (IS_SX_BOARD(board) && (type == TA8)) { | 2076 | if (IS_SX_BOARD(board) && (type == TA8)) { |
1979 | /* There are some issues with the firmware and the DCD/RTS | 2077 | /* There are some issues with the firmware and the DCD/RTS |
1980 | lines. It might work if you tie them together or something. | 2078 | lines. It might work if you tie them together or something. |
1981 | It might also work if you get a newer sx_firmware. Therefore | 2079 | It might also work if you get a newer sx_firmware. Therefore |
1982 | this is just a warning. */ | 2080 | this is just a warning. */ |
1983 | printk (KERN_WARNING "sx: The SX host doesn't work too well " | 2081 | printk(KERN_WARNING |
1984 | "with the TA8 adapters.\nSpecialix is working on it.\n"); | 2082 | "sx: The SX host doesn't work too well " |
2083 | "with the TA8 adapters.\nSpecialix is working on it.\n"); | ||
1985 | } | 2084 | } |
1986 | #endif | 2085 | #endif |
1987 | } | 2086 | } |
1988 | 2087 | ||
1989 | if (chans) { | 2088 | if (chans) { |
1990 | /* board->flags |= SX_BOARD_PRESENT; */ | 2089 | if (board->irq > 0) { |
1991 | if(board->irq > 0) { | ||
1992 | /* fixed irq, probably PCI */ | 2090 | /* fixed irq, probably PCI */ |
1993 | if(sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ | 2091 | if (sx_irqmask & (1 << board->irq)) { /* may we use this irq? */ |
1994 | if(request_irq(board->irq, sx_interrupt, IRQF_SHARED | IRQF_DISABLED, "sx", board)) { | 2092 | if (request_irq(board->irq, sx_interrupt, |
1995 | printk(KERN_ERR "sx: Cannot allocate irq %d.\n", board->irq); | 2093 | IRQF_SHARED | IRQF_DISABLED, |
2094 | "sx", board)) { | ||
2095 | printk(KERN_ERR "sx: Cannot allocate " | ||
2096 | "irq %d.\n", board->irq); | ||
1996 | board->irq = 0; | 2097 | board->irq = 0; |
1997 | } | 2098 | } |
1998 | } else | 2099 | } else |
1999 | board->irq = 0; | 2100 | board->irq = 0; |
2000 | } else if(board->irq < 0 && sx_irqmask) { | 2101 | } else if (board->irq < 0 && sx_irqmask) { |
2001 | /* auto-allocate irq */ | 2102 | /* auto-allocate irq */ |
2002 | int irqnr; | 2103 | int irqnr; |
2003 | int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK); | 2104 | int irqmask = sx_irqmask & (IS_SX_BOARD(board) ? |
2004 | for(irqnr = 15; irqnr > 0; irqnr--) | 2105 | SX_ISA_IRQ_MASK : SI2_ISA_IRQ_MASK); |
2005 | if(irqmask & (1 << irqnr)) | 2106 | for (irqnr = 15; irqnr > 0; irqnr--) |
2006 | if(! request_irq(irqnr, sx_interrupt, IRQF_SHARED | IRQF_DISABLED, "sx", board)) | 2107 | if (irqmask & (1 << irqnr)) |
2108 | if (!request_irq(irqnr, sx_interrupt, | ||
2109 | IRQF_SHARED | IRQF_DISABLED, | ||
2110 | "sx", board)) | ||
2007 | break; | 2111 | break; |
2008 | if(! irqnr) | 2112 | if (!irqnr) |
2009 | printk(KERN_ERR "sx: Cannot allocate IRQ.\n"); | 2113 | printk(KERN_ERR "sx: Cannot allocate IRQ.\n"); |
2010 | board->irq = irqnr; | 2114 | board->irq = irqnr; |
2011 | } else | 2115 | } else |
@@ -2013,52 +2117,48 @@ static int sx_init_board (struct sx_board *board) | |||
2013 | 2117 | ||
2014 | if (board->irq) { | 2118 | if (board->irq) { |
2015 | /* Found a valid interrupt, start up interrupts! */ | 2119 | /* Found a valid interrupt, start up interrupts! */ |
2016 | sx_dprintk (SX_DEBUG_INIT, "Using irq %d.\n", board->irq); | 2120 | sx_dprintk(SX_DEBUG_INIT, "Using irq %d.\n", |
2017 | sx_start_interrupts (board); | 2121 | board->irq); |
2122 | sx_start_interrupts(board); | ||
2018 | board->poll = sx_slowpoll; | 2123 | board->poll = sx_slowpoll; |
2019 | board->flags |= SX_IRQ_ALLOCATED; | 2124 | board->flags |= SX_IRQ_ALLOCATED; |
2020 | } else { | 2125 | } else { |
2021 | /* no irq: setup board for polled operation */ | 2126 | /* no irq: setup board for polled operation */ |
2022 | board->poll = sx_poll; | 2127 | board->poll = sx_poll; |
2023 | sx_dprintk (SX_DEBUG_INIT, "Using poll-interval %d.\n", board->poll); | 2128 | sx_dprintk(SX_DEBUG_INIT, "Using poll-interval %d.\n", |
2129 | board->poll); | ||
2024 | } | 2130 | } |
2025 | 2131 | ||
2026 | /* The timer should be initialized anyway: That way we can safely | 2132 | /* The timer should be initialized anyway: That way we can |
2027 | del_timer it when the module is unloaded. */ | 2133 | safely del_timer it when the module is unloaded. */ |
2028 | init_timer (&board->timer); | 2134 | setup_timer(&board->timer, sx_pollfunc, (unsigned long)board); |
2029 | 2135 | ||
2030 | if (board->poll) { | 2136 | if (board->poll) |
2031 | board->timer.data = (unsigned long) board; | 2137 | mod_timer(&board->timer, jiffies + board->poll); |
2032 | board->timer.function = sx_pollfunc; | ||
2033 | board->timer.expires = jiffies + board->poll; | ||
2034 | add_timer (&board->timer); | ||
2035 | } | ||
2036 | } else { | 2138 | } else { |
2037 | board->irq = 0; | 2139 | board->irq = 0; |
2038 | } | 2140 | } |
2039 | 2141 | ||
2040 | board->nports = chans; | 2142 | board->nports = chans; |
2041 | sx_dprintk (SX_DEBUG_INIT, "returning %d ports.", board->nports); | 2143 | sx_dprintk(SX_DEBUG_INIT, "returning %d ports.", board->nports); |
2042 | 2144 | ||
2043 | func_exit(); | 2145 | func_exit(); |
2044 | return chans; | 2146 | return chans; |
2045 | } | 2147 | } |
2046 | 2148 | ||
2047 | 2149 | static void __devinit printheader(void) | |
2048 | static void printheader(void) | ||
2049 | { | 2150 | { |
2050 | static int header_printed; | 2151 | static int header_printed; |
2051 | 2152 | ||
2052 | if (!header_printed) { | 2153 | if (!header_printed) { |
2053 | printk (KERN_INFO "Specialix SX driver " | 2154 | printk(KERN_INFO "Specialix SX driver " |
2054 | "(C) 1998/1999 R.E.Wolff@BitWizard.nl \n"); | 2155 | "(C) 1998/1999 R.E.Wolff@BitWizard.nl\n"); |
2055 | printk (KERN_INFO "sx: version %s\n", RCS_ID); | 2156 | printk(KERN_INFO "sx: version " __stringify(SX_VERSION) "\n"); |
2056 | header_printed = 1; | 2157 | header_printed = 1; |
2057 | } | 2158 | } |
2058 | } | 2159 | } |
2059 | 2160 | ||
2060 | 2161 | static int __devinit probe_sx(struct sx_board *board) | |
2061 | static int probe_sx (struct sx_board *board) | ||
2062 | { | 2162 | { |
2063 | struct vpd_prom vpdp; | 2163 | struct vpd_prom vpdp; |
2064 | char *p; | 2164 | char *p; |
@@ -2066,51 +2166,57 @@ static int probe_sx (struct sx_board *board) | |||
2066 | 2166 | ||
2067 | func_enter(); | 2167 | func_enter(); |
2068 | 2168 | ||
2069 | if (!IS_CF_BOARD (board)) { | 2169 | if (!IS_CF_BOARD(board)) { |
2070 | sx_dprintk (SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", | 2170 | sx_dprintk(SX_DEBUG_PROBE, "Going to verify vpd prom at %p.\n", |
2071 | board->base + SX_VPD_ROM); | 2171 | board->base + SX_VPD_ROM); |
2072 | 2172 | ||
2073 | if (sx_debug & SX_DEBUG_PROBE) | 2173 | if (sx_debug & SX_DEBUG_PROBE) |
2074 | my_hd_io(board->base + SX_VPD_ROM, 0x40); | 2174 | my_hd_io(board->base + SX_VPD_ROM, 0x40); |
2075 | 2175 | ||
2076 | p = (char *) &vpdp; | 2176 | p = (char *)&vpdp; |
2077 | for (i=0;i< sizeof (struct vpd_prom);i++) | 2177 | for (i = 0; i < sizeof(struct vpd_prom); i++) |
2078 | *p++ = read_sx_byte (board, SX_VPD_ROM + i*2); | 2178 | *p++ = read_sx_byte(board, SX_VPD_ROM + i * 2); |
2079 | 2179 | ||
2080 | if (sx_debug & SX_DEBUG_PROBE) | 2180 | if (sx_debug & SX_DEBUG_PROBE) |
2081 | my_hd (&vpdp, 0x20); | 2181 | my_hd(&vpdp, 0x20); |
2082 | 2182 | ||
2083 | sx_dprintk (SX_DEBUG_PROBE, "checking identifier...\n"); | 2183 | sx_dprintk(SX_DEBUG_PROBE, "checking identifier...\n"); |
2084 | 2184 | ||
2085 | if (strncmp (vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) { | 2185 | if (strncmp(vpdp.identifier, SX_VPD_IDENT_STRING, 16) != 0) { |
2086 | sx_dprintk (SX_DEBUG_PROBE, "Got non-SX identifier: '%s'\n", | 2186 | sx_dprintk(SX_DEBUG_PROBE, "Got non-SX identifier: " |
2087 | vpdp.identifier); | 2187 | "'%s'\n", vpdp.identifier); |
2088 | return 0; | 2188 | return 0; |
2089 | } | 2189 | } |
2090 | } | 2190 | } |
2091 | 2191 | ||
2092 | printheader (); | 2192 | printheader(); |
2093 | |||
2094 | if (!IS_CF_BOARD (board)) { | ||
2095 | printk (KERN_DEBUG "sx: Found an SX board at %lx\n", board->hw_base); | ||
2096 | printk (KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, uniq ID:%08x, ", | ||
2097 | vpdp.hwrev, vpdp.hwass, vpdp.uniqid); | ||
2098 | printk ( "Manufactured: %d/%d\n", | ||
2099 | 1970 + vpdp.myear, vpdp.mweek); | ||
2100 | 2193 | ||
2194 | if (!IS_CF_BOARD(board)) { | ||
2195 | printk(KERN_DEBUG "sx: Found an SX board at %lx\n", | ||
2196 | board->hw_base); | ||
2197 | printk(KERN_DEBUG "sx: hw_rev: %d, assembly level: %d, " | ||
2198 | "uniq ID:%08x, ", | ||
2199 | vpdp.hwrev, vpdp.hwass, vpdp.uniqid); | ||
2200 | printk("Manufactured: %d/%d\n", 1970 + vpdp.myear, vpdp.mweek); | ||
2101 | 2201 | ||
2102 | if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != SX_PCI_UNIQUEID1) && | 2202 | if ((((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != |
2103 | (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) { | 2203 | SX_PCI_UNIQUEID1) && (((vpdp.uniqid >> 24) & |
2104 | /* This might be a bit harsh. This was the primary reason the | 2204 | SX_UNIQUEID_MASK) != SX_ISA_UNIQUEID1)) { |
2105 | SX/ISA card didn't work at first... */ | 2205 | /* This might be a bit harsh. This was the primary |
2106 | printk (KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA card. Sorry: giving up.\n"); | 2206 | reason the SX/ISA card didn't work at first... */ |
2207 | printk(KERN_ERR "sx: Hmm. Not an SX/PCI or SX/ISA " | ||
2208 | "card. Sorry: giving up.\n"); | ||
2107 | return (0); | 2209 | return (0); |
2108 | } | 2210 | } |
2109 | 2211 | ||
2110 | if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == SX_ISA_UNIQUEID1) { | 2212 | if (((vpdp.uniqid >> 24) & SX_UNIQUEID_MASK) == |
2213 | SX_ISA_UNIQUEID1) { | ||
2111 | if (((unsigned long)board->hw_base) & 0x8000) { | 2214 | if (((unsigned long)board->hw_base) & 0x8000) { |
2112 | printk (KERN_WARNING "sx: Warning: There may be hardware problems with the card at %lx.\n", board->hw_base); | 2215 | printk(KERN_WARNING "sx: Warning: There may be " |
2113 | printk (KERN_WARNING "sx: Read sx.txt for more info.\n"); | 2216 | "hardware problems with the card at " |
2217 | "%lx.\n", board->hw_base); | ||
2218 | printk(KERN_WARNING "sx: Read sx.txt for more " | ||
2219 | "info.\n"); | ||
2114 | } | 2220 | } |
2115 | } | 2221 | } |
2116 | } | 2222 | } |
@@ -2118,17 +2224,15 @@ static int probe_sx (struct sx_board *board) | |||
2118 | board->nports = -1; | 2224 | board->nports = -1; |
2119 | 2225 | ||
2120 | /* This resets the processor, and keeps it off the bus. */ | 2226 | /* This resets the processor, and keeps it off the bus. */ |
2121 | if (!sx_reset (board)) | 2227 | if (!sx_reset(board)) |
2122 | return 0; | 2228 | return 0; |
2123 | sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); | 2229 | sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); |
2124 | |||
2125 | board->flags |= SX_BOARD_PRESENT; | ||
2126 | 2230 | ||
2127 | func_exit(); | 2231 | func_exit(); |
2128 | return 1; | 2232 | return 1; |
2129 | } | 2233 | } |
2130 | 2234 | ||
2131 | 2235 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | |
2132 | 2236 | ||
2133 | /* Specialix probes for this card at 32k increments from 640k to 16M. | 2237 | /* Specialix probes for this card at 32k increments from 640k to 16M. |
2134 | I consider machines with less than 16M unlikely nowadays, so I'm | 2238 | I consider machines with less than 16M unlikely nowadays, so I'm |
@@ -2136,28 +2240,27 @@ static int probe_sx (struct sx_board *board) | |||
2136 | card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves | 2240 | card. 0xe0000 and 0xf0000 are taken by the BIOS. That only leaves |
2137 | 0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */ | 2241 | 0xc0000, 0xc8000, 0xd0000 and 0xd8000 . */ |
2138 | 2242 | ||
2139 | static int probe_si (struct sx_board *board) | 2243 | static int __devinit probe_si(struct sx_board *board) |
2140 | { | 2244 | { |
2141 | int i; | 2245 | int i; |
2142 | 2246 | ||
2143 | func_enter(); | 2247 | func_enter(); |
2144 | sx_dprintk (SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at %p.\n", board->hw_base, | 2248 | sx_dprintk(SX_DEBUG_PROBE, "Going to verify SI signature hw %lx at " |
2145 | board->base + SI2_ISA_ID_BASE); | 2249 | "%p.\n", board->hw_base, board->base + SI2_ISA_ID_BASE); |
2146 | 2250 | ||
2147 | if (sx_debug & SX_DEBUG_PROBE) | 2251 | if (sx_debug & SX_DEBUG_PROBE) |
2148 | my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8); | 2252 | my_hd_io(board->base + SI2_ISA_ID_BASE, 0x8); |
2149 | 2253 | ||
2150 | if (!IS_EISA_BOARD(board)) { | 2254 | if (!IS_EISA_BOARD(board)) { |
2151 | if( IS_SI1_BOARD(board) ) | 2255 | if (IS_SI1_BOARD(board)) { |
2152 | { | 2256 | for (i = 0; i < 8; i++) { |
2153 | for (i=0;i<8;i++) { | 2257 | write_sx_byte(board, SI2_ISA_ID_BASE + 7 - i,i); |
2154 | write_sx_byte (board, SI2_ISA_ID_BASE+7-i,i); | 2258 | } |
2155 | |||
2156 | } | 2259 | } |
2157 | } | 2260 | for (i = 0; i < 8; i++) { |
2158 | for (i=0;i<8;i++) { | 2261 | if ((read_sx_byte(board, SI2_ISA_ID_BASE + 7 - i) & 7) |
2159 | if ((read_sx_byte (board, SI2_ISA_ID_BASE+7-i) & 7) != i) { | 2262 | != i) { |
2160 | func_exit (); | 2263 | func_exit(); |
2161 | return 0; | 2264 | return 0; |
2162 | } | 2265 | } |
2163 | } | 2266 | } |
@@ -2167,20 +2270,20 @@ static int probe_si (struct sx_board *board) | |||
2167 | but to prevent trouble, we'd better double check that we don't | 2270 | but to prevent trouble, we'd better double check that we don't |
2168 | have an SI1 board when we're probing for an SI2 board.... */ | 2271 | have an SI1 board when we're probing for an SI2 board.... */ |
2169 | 2272 | ||
2170 | write_sx_byte (board, SI2_ISA_ID_BASE,0x10); | 2273 | write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); |
2171 | if ( IS_SI1_BOARD(board)) { | 2274 | if (IS_SI1_BOARD(board)) { |
2172 | /* This should be an SI1 board, which has this | 2275 | /* This should be an SI1 board, which has this |
2173 | location writable... */ | 2276 | location writable... */ |
2174 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) { | 2277 | if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { |
2175 | func_exit (); | 2278 | func_exit(); |
2176 | return 0; | 2279 | return 0; |
2177 | } | 2280 | } |
2178 | } else { | 2281 | } else { |
2179 | /* This should be an SI2 board, which has the bottom | 2282 | /* This should be an SI2 board, which has the bottom |
2180 | 3 bits non-writable... */ | 2283 | 3 bits non-writable... */ |
2181 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) { | 2284 | if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { |
2182 | func_exit (); | 2285 | func_exit(); |
2183 | return 0; | 2286 | return 0; |
2184 | } | 2287 | } |
2185 | } | 2288 | } |
2186 | 2289 | ||
@@ -2188,45 +2291,44 @@ static int probe_si (struct sx_board *board) | |||
2188 | but to prevent trouble, we'd better double check that we don't | 2291 | but to prevent trouble, we'd better double check that we don't |
2189 | have an SI1 board when we're probing for an SI2 board.... */ | 2292 | have an SI1 board when we're probing for an SI2 board.... */ |
2190 | 2293 | ||
2191 | write_sx_byte (board, SI2_ISA_ID_BASE,0x10); | 2294 | write_sx_byte(board, SI2_ISA_ID_BASE, 0x10); |
2192 | if ( IS_SI1_BOARD(board)) { | 2295 | if (IS_SI1_BOARD(board)) { |
2193 | /* This should be an SI1 board, which has this | 2296 | /* This should be an SI1 board, which has this |
2194 | location writable... */ | 2297 | location writable... */ |
2195 | if (read_sx_byte (board, SI2_ISA_ID_BASE) != 0x10) { | 2298 | if (read_sx_byte(board, SI2_ISA_ID_BASE) != 0x10) { |
2196 | func_exit(); | 2299 | func_exit(); |
2197 | return 0; | 2300 | return 0; |
2198 | } | 2301 | } |
2199 | } else { | 2302 | } else { |
2200 | /* This should be an SI2 board, which has the bottom | 2303 | /* This should be an SI2 board, which has the bottom |
2201 | 3 bits non-writable... */ | 2304 | 3 bits non-writable... */ |
2202 | if (read_sx_byte (board, SI2_ISA_ID_BASE) == 0x10) { | 2305 | if (read_sx_byte(board, SI2_ISA_ID_BASE) == 0x10) { |
2203 | func_exit (); | 2306 | func_exit(); |
2204 | return 0; | 2307 | return 0; |
2205 | } | 2308 | } |
2206 | } | 2309 | } |
2207 | 2310 | ||
2208 | printheader (); | 2311 | printheader(); |
2209 | 2312 | ||
2210 | printk (KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); | 2313 | printk(KERN_DEBUG "sx: Found an SI board at %lx\n", board->hw_base); |
2211 | /* Compared to the SX boards, it is a complete guess as to what | 2314 | /* Compared to the SX boards, it is a complete guess as to what |
2212 | this card is up to... */ | 2315 | this card is up to... */ |
2213 | 2316 | ||
2214 | board->nports = -1; | 2317 | board->nports = -1; |
2215 | 2318 | ||
2216 | /* This resets the processor, and keeps it off the bus. */ | 2319 | /* This resets the processor, and keeps it off the bus. */ |
2217 | if (!sx_reset (board)) | 2320 | if (!sx_reset(board)) |
2218 | return 0; | 2321 | return 0; |
2219 | sx_dprintk (SX_DEBUG_INIT, "reset the board...\n"); | 2322 | sx_dprintk(SX_DEBUG_INIT, "reset the board...\n"); |
2220 | |||
2221 | board->flags |= SX_BOARD_PRESENT; | ||
2222 | 2323 | ||
2223 | func_exit(); | 2324 | func_exit(); |
2224 | return 1; | 2325 | return 1; |
2225 | } | 2326 | } |
2327 | #endif | ||
2226 | 2328 | ||
2227 | static const struct tty_operations sx_ops = { | 2329 | static const struct tty_operations sx_ops = { |
2228 | .break_ctl = sx_break, | 2330 | .break_ctl = sx_break, |
2229 | .open = sx_open, | 2331 | .open = sx_open, |
2230 | .close = gs_close, | 2332 | .close = gs_close, |
2231 | .write = gs_write, | 2333 | .write = gs_write, |
2232 | .put_char = gs_put_char, | 2334 | .put_char = gs_put_char, |
@@ -2261,34 +2363,23 @@ static int sx_init_drivers(void) | |||
2261 | sx_driver->type = TTY_DRIVER_TYPE_SERIAL; | 2363 | sx_driver->type = TTY_DRIVER_TYPE_SERIAL; |
2262 | sx_driver->subtype = SERIAL_TYPE_NORMAL; | 2364 | sx_driver->subtype = SERIAL_TYPE_NORMAL; |
2263 | sx_driver->init_termios = tty_std_termios; | 2365 | sx_driver->init_termios = tty_std_termios; |
2264 | sx_driver->init_termios.c_cflag = | 2366 | sx_driver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2265 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2367 | sx_driver->init_termios.c_ispeed = 9600; |
2368 | sx_driver->init_termios.c_ospeed = 9600; | ||
2266 | sx_driver->flags = TTY_DRIVER_REAL_RAW; | 2369 | sx_driver->flags = TTY_DRIVER_REAL_RAW; |
2267 | tty_set_operations(sx_driver, &sx_ops); | 2370 | tty_set_operations(sx_driver, &sx_ops); |
2268 | 2371 | ||
2269 | if ((error = tty_register_driver(sx_driver))) { | 2372 | if ((error = tty_register_driver(sx_driver))) { |
2270 | put_tty_driver(sx_driver); | 2373 | put_tty_driver(sx_driver); |
2271 | printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n", | 2374 | printk(KERN_ERR "sx: Couldn't register sx driver, error = %d\n", |
2272 | error); | 2375 | error); |
2273 | return 1; | 2376 | return 1; |
2274 | } | 2377 | } |
2275 | func_exit(); | 2378 | func_exit(); |
2276 | return 0; | 2379 | return 0; |
2277 | } | 2380 | } |
2278 | 2381 | ||
2279 | 2382 | static int sx_init_portstructs(int nboards, int nports) | |
2280 | static void * ckmalloc (int size) | ||
2281 | { | ||
2282 | void *p; | ||
2283 | |||
2284 | p = kmalloc(size, GFP_KERNEL); | ||
2285 | if (p) | ||
2286 | memset(p, 0, size); | ||
2287 | return p; | ||
2288 | } | ||
2289 | |||
2290 | |||
2291 | static int sx_init_portstructs (int nboards, int nports) | ||
2292 | { | 2383 | { |
2293 | struct sx_board *board; | 2384 | struct sx_board *board; |
2294 | struct sx_port *port; | 2385 | struct sx_port *port; |
@@ -2299,8 +2390,9 @@ static int sx_init_portstructs (int nboards, int nports) | |||
2299 | func_enter(); | 2390 | func_enter(); |
2300 | 2391 | ||
2301 | /* Many drivers statically allocate the maximum number of ports | 2392 | /* Many drivers statically allocate the maximum number of ports |
2302 | There is no reason not to allocate them dynamically. Is there? -- REW */ | 2393 | There is no reason not to allocate them dynamically. |
2303 | sx_ports = ckmalloc(nports * sizeof (struct sx_port)); | 2394 | Is there? -- REW */ |
2395 | sx_ports = kcalloc(nports, sizeof(struct sx_port), GFP_KERNEL); | ||
2304 | if (!sx_ports) | 2396 | if (!sx_ports) |
2305 | return -ENOMEM; | 2397 | return -ENOMEM; |
2306 | 2398 | ||
@@ -2308,10 +2400,10 @@ static int sx_init_portstructs (int nboards, int nports) | |||
2308 | for (i = 0; i < nboards; i++) { | 2400 | for (i = 0; i < nboards; i++) { |
2309 | board = &boards[i]; | 2401 | board = &boards[i]; |
2310 | board->ports = port; | 2402 | board->ports = port; |
2311 | for (j=0; j < boards[i].nports;j++) { | 2403 | for (j = 0; j < boards[i].nports; j++) { |
2312 | sx_dprintk (SX_DEBUG_INIT, "initing port %d\n", j); | 2404 | sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); |
2313 | port->gs.magic = SX_MAGIC; | 2405 | port->gs.magic = SX_MAGIC; |
2314 | port->gs.close_delay = HZ/2; | 2406 | port->gs.close_delay = HZ / 2; |
2315 | port->gs.closing_wait = 30 * HZ; | 2407 | port->gs.closing_wait = 30 * HZ; |
2316 | port->board = board; | 2408 | port->board = board; |
2317 | port->gs.rd = &sx_real_driver; | 2409 | port->gs.rd = &sx_real_driver; |
@@ -2323,8 +2415,8 @@ static int sx_init_portstructs (int nboards, int nports) | |||
2323 | * Initializing wait queue | 2415 | * Initializing wait queue |
2324 | */ | 2416 | */ |
2325 | init_waitqueue_head(&port->gs.open_wait); | 2417 | init_waitqueue_head(&port->gs.open_wait); |
2326 | init_waitqueue_head(&port->gs.close_wait); | 2418 | init_waitqueue_head(&port->gs.close_wait); |
2327 | 2419 | ||
2328 | port++; | 2420 | port++; |
2329 | } | 2421 | } |
2330 | } | 2422 | } |
@@ -2335,28 +2427,36 @@ static int sx_init_portstructs (int nboards, int nports) | |||
2335 | board = &boards[i]; | 2427 | board = &boards[i]; |
2336 | board->port_base = portno; | 2428 | board->port_base = portno; |
2337 | /* Possibly the configuration was rejected. */ | 2429 | /* Possibly the configuration was rejected. */ |
2338 | sx_dprintk (SX_DEBUG_PROBE, "Board has %d channels\n", board->nports); | 2430 | sx_dprintk(SX_DEBUG_PROBE, "Board has %d channels\n", |
2339 | if (board->nports <= 0) continue; | 2431 | board->nports); |
2432 | if (board->nports <= 0) | ||
2433 | continue; | ||
2340 | /* XXX byteorder ?? */ | 2434 | /* XXX byteorder ?? */ |
2341 | for (addr = 0x80;addr != 0;addr = read_sx_word (board, addr) & 0x7fff) { | 2435 | for (addr = 0x80; addr != 0; |
2342 | chans = sx_read_module_byte (board, addr, mc_type); | 2436 | addr = read_sx_word(board, addr) & 0x7fff) { |
2343 | sx_dprintk (SX_DEBUG_PROBE, "Module at %x: %d channels\n", addr, chans); | 2437 | chans = sx_read_module_byte(board, addr, mc_type); |
2344 | sx_dprintk (SX_DEBUG_PROBE, "Port at"); | 2438 | sx_dprintk(SX_DEBUG_PROBE, "Module at %x: %d " |
2345 | for (j=0;j<chans;j++) { | 2439 | "channels\n", addr, chans); |
2346 | /* The "sx-way" is the way it SHOULD be done. That way in the | 2440 | sx_dprintk(SX_DEBUG_PROBE, "Port at"); |
2347 | future, the firmware may for example pack the structures a bit | 2441 | for (j = 0; j < chans; j++) { |
2348 | more efficient. Neil tells me it isn't going to happen anytime | 2442 | /* The "sx-way" is the way it SHOULD be done. |
2349 | soon though. */ | 2443 | That way in the future, the firmware may for |
2444 | example pack the structures a bit more | ||
2445 | efficient. Neil tells me it isn't going to | ||
2446 | happen anytime soon though. */ | ||
2350 | if (IS_SX_BOARD(board)) | 2447 | if (IS_SX_BOARD(board)) |
2351 | port->ch_base = sx_read_module_word (board, addr+j*2, mc_chan_pointer); | 2448 | port->ch_base = sx_read_module_word( |
2449 | board, addr + j * 2, | ||
2450 | mc_chan_pointer); | ||
2352 | else | 2451 | else |
2353 | port->ch_base = addr + 0x100 + 0x300*j; | 2452 | port->ch_base = addr + 0x100 + 0x300 *j; |
2354 | 2453 | ||
2355 | sx_dprintk (SX_DEBUG_PROBE, " %x", port->ch_base); | 2454 | sx_dprintk(SX_DEBUG_PROBE, " %x", |
2455 | port->ch_base); | ||
2356 | port->line = portno++; | 2456 | port->line = portno++; |
2357 | port++; | 2457 | port++; |
2358 | } | 2458 | } |
2359 | sx_dprintk (SX_DEBUG_PROBE, "\n"); | 2459 | sx_dprintk(SX_DEBUG_PROBE, "\n"); |
2360 | } | 2460 | } |
2361 | /* This has to be done earlier. */ | 2461 | /* This has to be done earlier. */ |
2362 | /* board->flags |= SX_BOARD_INITIALIZED; */ | 2462 | /* board->flags |= SX_BOARD_INITIALIZED; */ |
@@ -2366,6 +2466,17 @@ static int sx_init_portstructs (int nboards, int nports) | |||
2366 | return 0; | 2466 | return 0; |
2367 | } | 2467 | } |
2368 | 2468 | ||
2469 | static unsigned int sx_find_free_board(void) | ||
2470 | { | ||
2471 | unsigned int i; | ||
2472 | |||
2473 | for (i = 0; i < SX_NBOARDS; i++) | ||
2474 | if (!(boards[i].flags & SX_BOARD_PRESENT)) | ||
2475 | break; | ||
2476 | |||
2477 | return i; | ||
2478 | } | ||
2479 | |||
2369 | static void __exit sx_release_drivers(void) | 2480 | static void __exit sx_release_drivers(void) |
2370 | { | 2481 | { |
2371 | func_enter(); | 2482 | func_enter(); |
@@ -2374,7 +2485,122 @@ static void __exit sx_release_drivers(void) | |||
2374 | func_exit(); | 2485 | func_exit(); |
2375 | } | 2486 | } |
2376 | 2487 | ||
2377 | #ifdef CONFIG_PCI | 2488 | static void __devexit sx_remove_card(struct sx_board *board, |
2489 | struct pci_dev *pdev) | ||
2490 | { | ||
2491 | if (board->flags & SX_BOARD_INITIALIZED) { | ||
2492 | /* The board should stop messing with us. (actually I mean the | ||
2493 | interrupt) */ | ||
2494 | sx_reset(board); | ||
2495 | if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED)) | ||
2496 | free_irq(board->irq, board); | ||
2497 | |||
2498 | /* It is safe/allowed to del_timer a non-active timer */ | ||
2499 | del_timer(&board->timer); | ||
2500 | if (pdev) { | ||
2501 | pci_iounmap(pdev, board->base); | ||
2502 | pci_release_region(pdev, IS_CF_BOARD(board) ? 3 : 2); | ||
2503 | } else { | ||
2504 | iounmap(board->base); | ||
2505 | release_region(board->hw_base, board->hw_len); | ||
2506 | } | ||
2507 | |||
2508 | board->flags &= ~(SX_BOARD_INITIALIZED | SX_BOARD_PRESENT); | ||
2509 | } | ||
2510 | } | ||
2511 | |||
2512 | #ifdef CONFIG_EISA | ||
2513 | |||
2514 | static int __devinit sx_eisa_probe(struct device *dev) | ||
2515 | { | ||
2516 | struct eisa_device *edev = to_eisa_device(dev); | ||
2517 | struct sx_board *board; | ||
2518 | unsigned long eisa_slot = edev->base_addr; | ||
2519 | unsigned int i; | ||
2520 | int retval = -EIO; | ||
2521 | |||
2522 | mutex_lock(&sx_boards_lock); | ||
2523 | i = sx_find_free_board(); | ||
2524 | if (i == SX_NBOARDS) { | ||
2525 | mutex_unlock(&sx_boards_lock); | ||
2526 | goto err; | ||
2527 | } | ||
2528 | board = &boards[i]; | ||
2529 | board->flags |= SX_BOARD_PRESENT; | ||
2530 | mutex_unlock(&sx_boards_lock); | ||
2531 | |||
2532 | dev_info(dev, "XIO : Signature found in EISA slot %lu, " | ||
2533 | "Product %d Rev %d (REPORT THIS TO LKLM)\n", | ||
2534 | eisa_slot >> 12, | ||
2535 | inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 2), | ||
2536 | inb(eisa_slot + EISA_VENDOR_ID_OFFSET + 3)); | ||
2537 | |||
2538 | board->eisa_base = eisa_slot; | ||
2539 | board->flags &= ~SX_BOARD_TYPE; | ||
2540 | board->flags |= SI_EISA_BOARD; | ||
2541 | |||
2542 | board->hw_base = ((inb(eisa_slot + 0xc01) << 8) + | ||
2543 | inb(eisa_slot + 0xc00)) << 16; | ||
2544 | board->hw_len = SI2_EISA_WINDOW_LEN; | ||
2545 | if (!request_region(board->hw_base, board->hw_len, "sx")) { | ||
2546 | dev_err(dev, "can't request region\n"); | ||
2547 | goto err_flag; | ||
2548 | } | ||
2549 | board->base2 = | ||
2550 | board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN); | ||
2551 | if (!board->base) { | ||
2552 | dev_err(dev, "can't remap memory\n"); | ||
2553 | goto err_reg; | ||
2554 | } | ||
2555 | |||
2556 | sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base); | ||
2557 | sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base); | ||
2558 | board->irq = inb(eisa_slot + 0xc02) >> 4; | ||
2559 | sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq); | ||
2560 | |||
2561 | if (!probe_si(board)) | ||
2562 | goto err_unmap; | ||
2563 | |||
2564 | dev_set_drvdata(dev, board); | ||
2565 | |||
2566 | return 0; | ||
2567 | err_unmap: | ||
2568 | iounmap(board->base); | ||
2569 | err_reg: | ||
2570 | release_region(board->hw_base, board->hw_len); | ||
2571 | err_flag: | ||
2572 | board->flags &= ~SX_BOARD_PRESENT; | ||
2573 | err: | ||
2574 | return retval; | ||
2575 | } | ||
2576 | |||
2577 | static int __devexit sx_eisa_remove(struct device *dev) | ||
2578 | { | ||
2579 | struct sx_board *board = dev_get_drvdata(dev); | ||
2580 | |||
2581 | sx_remove_card(board, NULL); | ||
2582 | |||
2583 | return 0; | ||
2584 | } | ||
2585 | |||
2586 | static struct eisa_device_id sx_eisa_tbl[] = { | ||
2587 | { "SLX" }, | ||
2588 | { "" } | ||
2589 | }; | ||
2590 | |||
2591 | MODULE_DEVICE_TABLE(eisa, sx_eisa_tbl); | ||
2592 | |||
2593 | static struct eisa_driver sx_eisadriver = { | ||
2594 | .id_table = sx_eisa_tbl, | ||
2595 | .driver = { | ||
2596 | .name = "sx", | ||
2597 | .probe = sx_eisa_probe, | ||
2598 | .remove = __devexit_p(sx_eisa_remove), | ||
2599 | } | ||
2600 | }; | ||
2601 | |||
2602 | #endif | ||
2603 | |||
2378 | /******************************************************** | 2604 | /******************************************************** |
2379 | * Setting bit 17 in the CNTRL register of the PLX 9050 * | 2605 | * Setting bit 17 in the CNTRL register of the PLX 9050 * |
2380 | * chip forces a retry on writes while a read is pending.* | 2606 | * chip forces a retry on writes while a read is pending.* |
@@ -2386,233 +2612,265 @@ static void __exit sx_release_drivers(void) | |||
2386 | EEprom. As the bit is read/write for the CPU, we can fix it here, | 2612 | EEprom. As the bit is read/write for the CPU, we can fix it here, |
2387 | if we detect that it isn't set correctly. -- REW */ | 2613 | if we detect that it isn't set correctly. -- REW */ |
2388 | 2614 | ||
2389 | static void fix_sx_pci (struct pci_dev *pdev, struct sx_board *board) | 2615 | static void __devinit fix_sx_pci(struct pci_dev *pdev, struct sx_board *board) |
2390 | { | 2616 | { |
2391 | unsigned int hwbase; | 2617 | unsigned int hwbase; |
2392 | void __iomem *rebase; | 2618 | void __iomem *rebase; |
2393 | unsigned int t; | 2619 | unsigned int t; |
2394 | 2620 | ||
2395 | #define CNTRL_REG_OFFSET 0x50 | 2621 | #define CNTRL_REG_OFFSET 0x50 |
2396 | #define CNTRL_REG_GOODVALUE 0x18260000 | 2622 | #define CNTRL_REG_GOODVALUE 0x18260000 |
2397 | 2623 | ||
2398 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); | 2624 | pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase); |
2399 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; | 2625 | hwbase &= PCI_BASE_ADDRESS_MEM_MASK; |
2400 | rebase = ioremap(hwbase, 0x80); | 2626 | rebase = ioremap(hwbase, 0x80); |
2401 | t = readl (rebase + CNTRL_REG_OFFSET); | 2627 | t = readl(rebase + CNTRL_REG_OFFSET); |
2402 | if (t != CNTRL_REG_GOODVALUE) { | 2628 | if (t != CNTRL_REG_GOODVALUE) { |
2403 | printk (KERN_DEBUG "sx: performing cntrl reg fix: %08x -> %08x\n", t, CNTRL_REG_GOODVALUE); | 2629 | printk(KERN_DEBUG "sx: performing cntrl reg fix: %08x -> " |
2404 | writel (CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); | 2630 | "%08x\n", t, CNTRL_REG_GOODVALUE); |
2631 | writel(CNTRL_REG_GOODVALUE, rebase + CNTRL_REG_OFFSET); | ||
2405 | } | 2632 | } |
2406 | iounmap(rebase); | 2633 | iounmap(rebase); |
2407 | } | 2634 | } |
2408 | #endif | ||
2409 | |||
2410 | 2635 | ||
2411 | static int __init sx_init(void) | 2636 | static int __devinit sx_pci_probe(struct pci_dev *pdev, |
2637 | const struct pci_device_id *ent) | ||
2412 | { | 2638 | { |
2413 | int i; | ||
2414 | int found = 0; | ||
2415 | int eisa_slot; | ||
2416 | struct sx_board *board; | 2639 | struct sx_board *board; |
2640 | unsigned int i, reg; | ||
2641 | int retval = -EIO; | ||
2417 | 2642 | ||
2418 | #ifdef CONFIG_PCI | 2643 | mutex_lock(&sx_boards_lock); |
2419 | struct pci_dev *pdev = NULL; | 2644 | i = sx_find_free_board(); |
2420 | unsigned int tint; | 2645 | if (i == SX_NBOARDS) { |
2421 | unsigned short tshort; | 2646 | mutex_unlock(&sx_boards_lock); |
2422 | #endif | 2647 | goto err; |
2648 | } | ||
2649 | board = &boards[i]; | ||
2650 | board->flags |= SX_BOARD_PRESENT; | ||
2651 | mutex_unlock(&sx_boards_lock); | ||
2423 | 2652 | ||
2424 | func_enter(); | 2653 | retval = pci_enable_device(pdev); |
2425 | sx_dprintk (SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", sx_debug); | 2654 | if (retval) |
2426 | if (abs ((long) (&sx_debug) - sx_debug) < 0x10000) { | 2655 | goto err_flag; |
2427 | printk (KERN_WARNING "sx: sx_debug is an address, instead of a value. " | 2656 | |
2428 | "Assuming -1.\n"); | 2657 | board->flags &= ~SX_BOARD_TYPE; |
2429 | printk ("(%p)\n", &sx_debug); | 2658 | board->flags |= (pdev->subsystem_vendor == 0x200) ? SX_PCI_BOARD : |
2430 | sx_debug=-1; | 2659 | SX_CFPCI_BOARD; |
2660 | |||
2661 | /* CF boards use base address 3.... */ | ||
2662 | reg = IS_CF_BOARD(board) ? 3 : 2; | ||
2663 | retval = pci_request_region(pdev, reg, "sx"); | ||
2664 | if (retval) { | ||
2665 | dev_err(&pdev->dev, "can't request region\n"); | ||
2666 | goto err_flag; | ||
2667 | } | ||
2668 | board->hw_base = pci_resource_start(pdev, reg); | ||
2669 | board->base2 = | ||
2670 | board->base = pci_iomap(pdev, reg, WINDOW_LEN(board)); | ||
2671 | if (!board->base) { | ||
2672 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
2673 | goto err_reg; | ||
2431 | } | 2674 | } |
2432 | 2675 | ||
2433 | if (misc_register(&sx_fw_device) < 0) { | 2676 | /* Most of the stuff on the CF board is offset by 0x18000 .... */ |
2434 | printk(KERN_ERR "SX: Unable to register firmware loader driver.\n"); | 2677 | if (IS_CF_BOARD(board)) |
2435 | return -EIO; | 2678 | board->base += 0x18000; |
2679 | |||
2680 | board->irq = pdev->irq; | ||
2681 | |||
2682 | dev_info(&pdev->dev, "Got a specialix card: %p(%d) %x.\n", board->base, | ||
2683 | board->irq, board->flags); | ||
2684 | |||
2685 | if (!probe_sx(board)) { | ||
2686 | retval = -EIO; | ||
2687 | goto err_unmap; | ||
2436 | } | 2688 | } |
2437 | 2689 | ||
2438 | #ifdef CONFIG_PCI | 2690 | fix_sx_pci(pdev, board); |
2439 | while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, | ||
2440 | PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | ||
2441 | pdev))) { | ||
2442 | if (pci_enable_device(pdev)) | ||
2443 | continue; | ||
2444 | 2691 | ||
2445 | /* Specialix has a whole bunch of cards with | 2692 | pci_set_drvdata(pdev, board); |
2446 | 0x2000 as the device ID. They say its because | ||
2447 | the standard requires it. Stupid standard. */ | ||
2448 | /* It seems that reading a word doesn't work reliably on 2.0. | ||
2449 | Also, reading a non-aligned dword doesn't work. So we read the | ||
2450 | whole dword at 0x2c and extract the word at 0x2e (SUBSYSTEM_ID) | ||
2451 | ourselves */ | ||
2452 | /* I don't know why the define doesn't work, constant 0x2c does --REW */ | ||
2453 | pci_read_config_dword (pdev, 0x2c, &tint); | ||
2454 | tshort = (tint >> 16) & 0xffff; | ||
2455 | sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x.\n", tint); | ||
2456 | /* sx_dprintk (SX_DEBUG_PROBE, "pdev = %d/%d (%x)\n", pdev, tint); */ | ||
2457 | if ((tshort != 0x0200) && (tshort != 0x0300)) { | ||
2458 | sx_dprintk (SX_DEBUG_PROBE, "But it's not an SX card (%d)...\n", | ||
2459 | tshort); | ||
2460 | continue; | ||
2461 | } | ||
2462 | board = &boards[found]; | ||
2463 | 2693 | ||
2464 | board->flags &= ~SX_BOARD_TYPE; | 2694 | return 0; |
2465 | board->flags |= (tshort == 0x200)?SX_PCI_BOARD: | 2695 | err_unmap: |
2466 | SX_CFPCI_BOARD; | 2696 | pci_iounmap(pdev, board->base); |
2467 | 2697 | err_reg: | |
2468 | /* CF boards use base address 3.... */ | 2698 | pci_release_region(pdev, reg); |
2469 | if (IS_CF_BOARD (board)) | 2699 | err_flag: |
2470 | board->hw_base = pci_resource_start (pdev, 3); | 2700 | board->flags &= ~SX_BOARD_PRESENT; |
2471 | else | 2701 | err: |
2472 | board->hw_base = pci_resource_start (pdev, 2); | 2702 | return retval; |
2473 | board->base2 = | 2703 | } |
2474 | board->base = ioremap(board->hw_base, WINDOW_LEN (board)); | ||
2475 | if (!board->base) { | ||
2476 | printk(KERN_ERR "ioremap failed\n"); | ||
2477 | /* XXX handle error */ | ||
2478 | } | ||
2479 | 2704 | ||
2480 | /* Most of the stuff on the CF board is offset by | 2705 | static void __devexit sx_pci_remove(struct pci_dev *pdev) |
2481 | 0x18000 .... */ | 2706 | { |
2482 | if (IS_CF_BOARD (board)) board->base += 0x18000; | 2707 | struct sx_board *board = pci_get_drvdata(pdev); |
2483 | 2708 | ||
2484 | board->irq = pdev->irq; | 2709 | sx_remove_card(board, pdev); |
2710 | } | ||
2485 | 2711 | ||
2486 | sx_dprintk (SX_DEBUG_PROBE, "Got a specialix card: %x/%p(%d) %x.\n", | 2712 | /* Specialix has a whole bunch of cards with 0x2000 as the device ID. They say |
2487 | tint, boards[found].base, board->irq, board->flags); | 2713 | its because the standard requires it. So check for SUBVENDOR_ID. */ |
2714 | static struct pci_device_id sx_pci_tbl[] = { | ||
2715 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | ||
2716 | .subvendor = 0x0200,.subdevice = PCI_ANY_ID }, | ||
2717 | { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, | ||
2718 | .subvendor = 0x0300,.subdevice = PCI_ANY_ID }, | ||
2719 | { 0 } | ||
2720 | }; | ||
2488 | 2721 | ||
2489 | if (probe_sx (board)) { | 2722 | MODULE_DEVICE_TABLE(pci, sx_pci_tbl); |
2490 | found++; | 2723 | |
2491 | fix_sx_pci (pdev, board); | 2724 | static struct pci_driver sx_pcidriver = { |
2492 | } else | 2725 | .name = "sx", |
2493 | iounmap(board->base2); | 2726 | .id_table = sx_pci_tbl, |
2494 | } | 2727 | .probe = sx_pci_probe, |
2728 | .remove = __devexit_p(sx_pci_remove) | ||
2729 | }; | ||
2730 | |||
2731 | static int __init sx_init(void) | ||
2732 | { | ||
2733 | #ifdef CONFIG_EISA | ||
2734 | int retval1; | ||
2495 | #endif | 2735 | #endif |
2736 | #ifdef CONFIG_ISA | ||
2737 | struct sx_board *board; | ||
2738 | unsigned int i; | ||
2739 | #endif | ||
2740 | unsigned int found = 0; | ||
2741 | int retval; | ||
2742 | |||
2743 | func_enter(); | ||
2744 | sx_dprintk(SX_DEBUG_INIT, "Initing sx module... (sx_debug=%d)\n", | ||
2745 | sx_debug); | ||
2746 | if (abs((long)(&sx_debug) - sx_debug) < 0x10000) { | ||
2747 | printk(KERN_WARNING "sx: sx_debug is an address, instead of a " | ||
2748 | "value. Assuming -1.\n(%p)\n", &sx_debug); | ||
2749 | sx_debug = -1; | ||
2750 | } | ||
2496 | 2751 | ||
2497 | for (i=0;i<NR_SX_ADDRS;i++) { | 2752 | if (misc_register(&sx_fw_device) < 0) { |
2753 | printk(KERN_ERR "SX: Unable to register firmware loader " | ||
2754 | "driver.\n"); | ||
2755 | return -EIO; | ||
2756 | } | ||
2757 | #ifdef CONFIG_ISA | ||
2758 | for (i = 0; i < NR_SX_ADDRS; i++) { | ||
2498 | board = &boards[found]; | 2759 | board = &boards[found]; |
2499 | board->hw_base = sx_probe_addrs[i]; | 2760 | board->hw_base = sx_probe_addrs[i]; |
2761 | board->hw_len = SX_WINDOW_LEN; | ||
2762 | if (!request_region(board->hw_base, board->hw_len, "sx")) | ||
2763 | continue; | ||
2500 | board->base2 = | 2764 | board->base2 = |
2501 | board->base = ioremap(board->hw_base, SX_WINDOW_LEN); | 2765 | board->base = ioremap(board->hw_base, board->hw_len); |
2766 | if (!board->base) | ||
2767 | goto err_sx_reg; | ||
2502 | board->flags &= ~SX_BOARD_TYPE; | 2768 | board->flags &= ~SX_BOARD_TYPE; |
2503 | board->flags |= SX_ISA_BOARD; | 2769 | board->flags |= SX_ISA_BOARD; |
2504 | board->irq = sx_irqmask?-1:0; | 2770 | board->irq = sx_irqmask ? -1 : 0; |
2505 | 2771 | ||
2506 | if (probe_sx (board)) { | 2772 | if (probe_sx(board)) { |
2773 | board->flags |= SX_BOARD_PRESENT; | ||
2507 | found++; | 2774 | found++; |
2508 | } else { | 2775 | } else { |
2509 | iounmap(board->base); | 2776 | iounmap(board->base); |
2777 | err_sx_reg: | ||
2778 | release_region(board->hw_base, board->hw_len); | ||
2510 | } | 2779 | } |
2511 | } | 2780 | } |
2512 | 2781 | ||
2513 | for (i=0;i<NR_SI_ADDRS;i++) { | 2782 | for (i = 0; i < NR_SI_ADDRS; i++) { |
2514 | board = &boards[found]; | 2783 | board = &boards[found]; |
2515 | board->hw_base = si_probe_addrs[i]; | 2784 | board->hw_base = si_probe_addrs[i]; |
2785 | board->hw_len = SI2_ISA_WINDOW_LEN; | ||
2786 | if (!request_region(board->hw_base, board->hw_len, "sx")) | ||
2787 | continue; | ||
2516 | board->base2 = | 2788 | board->base2 = |
2517 | board->base = ioremap(board->hw_base, SI2_ISA_WINDOW_LEN); | 2789 | board->base = ioremap(board->hw_base, board->hw_len); |
2790 | if (!board->base) | ||
2791 | goto err_si_reg; | ||
2518 | board->flags &= ~SX_BOARD_TYPE; | 2792 | board->flags &= ~SX_BOARD_TYPE; |
2519 | board->flags |= SI_ISA_BOARD; | 2793 | board->flags |= SI_ISA_BOARD; |
2520 | board->irq = sx_irqmask ?-1:0; | 2794 | board->irq = sx_irqmask ? -1 : 0; |
2521 | 2795 | ||
2522 | if (probe_si (board)) { | 2796 | if (probe_si(board)) { |
2797 | board->flags |= SX_BOARD_PRESENT; | ||
2523 | found++; | 2798 | found++; |
2524 | } else { | 2799 | } else { |
2525 | iounmap (board->base); | 2800 | iounmap(board->base); |
2801 | err_si_reg: | ||
2802 | release_region(board->hw_base, board->hw_len); | ||
2526 | } | 2803 | } |
2527 | } | 2804 | } |
2528 | for (i=0;i<NR_SI1_ADDRS;i++) { | 2805 | for (i = 0; i < NR_SI1_ADDRS; i++) { |
2529 | board = &boards[found]; | 2806 | board = &boards[found]; |
2530 | board->hw_base = si1_probe_addrs[i]; | 2807 | board->hw_base = si1_probe_addrs[i]; |
2808 | board->hw_len = SI1_ISA_WINDOW_LEN; | ||
2809 | if (!request_region(board->hw_base, board->hw_len, "sx")) | ||
2810 | continue; | ||
2531 | board->base2 = | 2811 | board->base2 = |
2532 | board->base = ioremap(board->hw_base, SI1_ISA_WINDOW_LEN); | 2812 | board->base = ioremap(board->hw_base, board->hw_len); |
2813 | if (!board->base) | ||
2814 | goto err_si1_reg; | ||
2533 | board->flags &= ~SX_BOARD_TYPE; | 2815 | board->flags &= ~SX_BOARD_TYPE; |
2534 | board->flags |= SI1_ISA_BOARD; | 2816 | board->flags |= SI1_ISA_BOARD; |
2535 | board->irq = sx_irqmask ?-1:0; | 2817 | board->irq = sx_irqmask ? -1 : 0; |
2536 | 2818 | ||
2537 | if (probe_si (board)) { | 2819 | if (probe_si(board)) { |
2820 | board->flags |= SX_BOARD_PRESENT; | ||
2538 | found++; | 2821 | found++; |
2539 | } else { | 2822 | } else { |
2540 | iounmap (board->base); | 2823 | iounmap(board->base); |
2824 | err_si1_reg: | ||
2825 | release_region(board->hw_base, board->hw_len); | ||
2541 | } | 2826 | } |
2542 | } | 2827 | } |
2828 | #endif | ||
2829 | #ifdef CONFIG_EISA | ||
2830 | retval1 = eisa_driver_register(&sx_eisadriver); | ||
2831 | #endif | ||
2832 | retval = pci_register_driver(&sx_pcidriver); | ||
2543 | 2833 | ||
2544 | sx_dprintk(SX_DEBUG_PROBE, "Probing for EISA cards\n"); | ||
2545 | for(eisa_slot=0x1000; eisa_slot<0x10000; eisa_slot+=0x1000) | ||
2546 | { | ||
2547 | if((inb(eisa_slot+0xc80)==0x4d) && | ||
2548 | (inb(eisa_slot+0xc81)==0x98)) | ||
2549 | { | ||
2550 | sx_dprintk(SX_DEBUG_PROBE, "%s : Signature found in EISA slot %d, Product %d Rev %d\n", | ||
2551 | "XIO", (eisa_slot>>12), inb(eisa_slot+0xc82), inb(eisa_slot+0xc83)); | ||
2552 | |||
2553 | board = &boards[found]; | ||
2554 | board->eisa_base = eisa_slot; | ||
2555 | board->flags &= ~SX_BOARD_TYPE; | ||
2556 | board->flags |= SI_EISA_BOARD; | ||
2557 | |||
2558 | board->hw_base = (((inb(0xc01+eisa_slot) << 8) + inb(0xc00+eisa_slot)) << 16); | ||
2559 | board->base2 = | ||
2560 | board->base = ioremap(board->hw_base, SI2_EISA_WINDOW_LEN); | ||
2561 | |||
2562 | sx_dprintk(SX_DEBUG_PROBE, "IO hw_base address: %lx\n", board->hw_base); | ||
2563 | sx_dprintk(SX_DEBUG_PROBE, "base: %p\n", board->base); | ||
2564 | board->irq = inb(board->eisa_base+0xc02)>>4; | ||
2565 | sx_dprintk(SX_DEBUG_PROBE, "IRQ: %d\n", board->irq); | ||
2566 | |||
2567 | probe_si(board); | ||
2568 | |||
2569 | found++; | ||
2570 | } | ||
2571 | } | ||
2572 | if (found) { | 2834 | if (found) { |
2573 | printk (KERN_INFO "sx: total of %d boards detected.\n", found); | 2835 | printk(KERN_INFO "sx: total of %d boards detected.\n", found); |
2574 | } else { | 2836 | retval = 0; |
2575 | misc_deregister(&sx_fw_device); | 2837 | } else if (retval) { |
2838 | #ifdef CONFIG_EISA | ||
2839 | retval = retval1; | ||
2840 | if (retval1) | ||
2841 | #endif | ||
2842 | misc_deregister(&sx_fw_device); | ||
2576 | } | 2843 | } |
2577 | 2844 | ||
2578 | func_exit(); | 2845 | func_exit(); |
2579 | return found?0:-EIO; | 2846 | return retval; |
2580 | } | 2847 | } |
2581 | 2848 | ||
2582 | 2849 | static void __exit sx_exit(void) | |
2583 | static void __exit sx_exit (void) | ||
2584 | { | 2850 | { |
2585 | int i; | 2851 | int i; |
2586 | struct sx_board *board; | ||
2587 | 2852 | ||
2588 | func_enter(); | 2853 | func_enter(); |
2589 | for (i = 0; i < SX_NBOARDS; i++) { | 2854 | #ifdef CONFIG_EISA |
2590 | board = &boards[i]; | 2855 | eisa_driver_unregister(&sx_eisadriver); |
2591 | if (board->flags & SX_BOARD_INITIALIZED) { | 2856 | #endif |
2592 | sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up board at %p\n", board->base); | 2857 | pci_unregister_driver(&sx_pcidriver); |
2593 | /* The board should stop messing with us. | 2858 | |
2594 | (actually I mean the interrupt) */ | 2859 | for (i = 0; i < SX_NBOARDS; i++) |
2595 | sx_reset (board); | 2860 | sx_remove_card(&boards[i], NULL); |
2596 | if ((board->irq) && (board->flags & SX_IRQ_ALLOCATED)) | 2861 | |
2597 | free_irq (board->irq, board); | ||
2598 | |||
2599 | /* It is safe/allowed to del_timer a non-active timer */ | ||
2600 | del_timer (& board->timer); | ||
2601 | iounmap(board->base); | ||
2602 | } | ||
2603 | } | ||
2604 | if (misc_deregister(&sx_fw_device) < 0) { | 2862 | if (misc_deregister(&sx_fw_device) < 0) { |
2605 | printk (KERN_INFO "sx: couldn't deregister firmware loader device\n"); | 2863 | printk(KERN_INFO "sx: couldn't deregister firmware loader " |
2864 | "device\n"); | ||
2606 | } | 2865 | } |
2607 | sx_dprintk (SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", sx_initialized); | 2866 | sx_dprintk(SX_DEBUG_CLEANUP, "Cleaning up drivers (%d)\n", |
2867 | sx_initialized); | ||
2608 | if (sx_initialized) | 2868 | if (sx_initialized) |
2609 | sx_release_drivers (); | 2869 | sx_release_drivers(); |
2610 | 2870 | ||
2611 | kfree (sx_ports); | 2871 | kfree(sx_ports); |
2612 | func_exit(); | 2872 | func_exit(); |
2613 | } | 2873 | } |
2614 | 2874 | ||
2615 | module_init(sx_init); | 2875 | module_init(sx_init); |
2616 | module_exit(sx_exit); | 2876 | module_exit(sx_exit); |
2617 | |||
2618 | |||
diff --git a/drivers/char/sx.h b/drivers/char/sx.h index e01f83cbe299..432aad0a2ddd 100644 --- a/drivers/char/sx.h +++ b/drivers/char/sx.h | |||
@@ -35,6 +35,7 @@ struct sx_board { | |||
35 | void __iomem *base; | 35 | void __iomem *base; |
36 | void __iomem *base2; | 36 | void __iomem *base2; |
37 | unsigned long hw_base; | 37 | unsigned long hw_base; |
38 | resource_size_t hw_len; | ||
38 | int eisa_base; | 39 | int eisa_base; |
39 | int port_base; /* Number of the first port */ | 40 | int port_base; /* Number of the first port */ |
40 | struct sx_port *ports; | 41 | struct sx_port *ports; |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index 147c30da81ea..acc6fab601cc 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -101,8 +101,10 @@ | |||
101 | #include <linux/hdlc.h> | 101 | #include <linux/hdlc.h> |
102 | #include <linux/dma-mapping.h> | 102 | #include <linux/dma-mapping.h> |
103 | 103 | ||
104 | #ifdef CONFIG_HDLC_MODULE | 104 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_MODULE)) |
105 | #define CONFIG_HDLC 1 | 105 | #define SYNCLINK_GENERIC_HDLC 1 |
106 | #else | ||
107 | #define SYNCLINK_GENERIC_HDLC 0 | ||
106 | #endif | 108 | #endif |
107 | 109 | ||
108 | #define GET_USER(error,value,addr) error = get_user(value,addr) | 110 | #define GET_USER(error,value,addr) error = get_user(value,addr) |
@@ -320,7 +322,7 @@ struct mgsl_struct { | |||
320 | int dosyncppp; | 322 | int dosyncppp; |
321 | spinlock_t netlock; | 323 | spinlock_t netlock; |
322 | 324 | ||
323 | #ifdef CONFIG_HDLC | 325 | #if SYNCLINK_GENERIC_HDLC |
324 | struct net_device *netdev; | 326 | struct net_device *netdev; |
325 | #endif | 327 | #endif |
326 | }; | 328 | }; |
@@ -728,7 +730,7 @@ static void usc_loopmode_send_done( struct mgsl_struct * info ); | |||
728 | 730 | ||
729 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg); | 731 | static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigned long arg); |
730 | 732 | ||
731 | #ifdef CONFIG_HDLC | 733 | #if SYNCLINK_GENERIC_HDLC |
732 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | 734 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) |
733 | static void hdlcdev_tx_done(struct mgsl_struct *info); | 735 | static void hdlcdev_tx_done(struct mgsl_struct *info); |
734 | static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size); | 736 | static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size); |
@@ -1277,7 +1279,7 @@ static void mgsl_isr_transmit_status( struct mgsl_struct *info ) | |||
1277 | info->drop_rts_on_tx_done = 0; | 1279 | info->drop_rts_on_tx_done = 0; |
1278 | } | 1280 | } |
1279 | 1281 | ||
1280 | #ifdef CONFIG_HDLC | 1282 | #if SYNCLINK_GENERIC_HDLC |
1281 | if (info->netcount) | 1283 | if (info->netcount) |
1282 | hdlcdev_tx_done(info); | 1284 | hdlcdev_tx_done(info); |
1283 | else | 1285 | else |
@@ -1342,7 +1344,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) | |||
1342 | info->input_signal_events.dcd_up++; | 1344 | info->input_signal_events.dcd_up++; |
1343 | } else | 1345 | } else |
1344 | info->input_signal_events.dcd_down++; | 1346 | info->input_signal_events.dcd_down++; |
1345 | #ifdef CONFIG_HDLC | 1347 | #if SYNCLINK_GENERIC_HDLC |
1346 | if (info->netcount) { | 1348 | if (info->netcount) { |
1347 | if (status & MISCSTATUS_DCD) | 1349 | if (status & MISCSTATUS_DCD) |
1348 | netif_carrier_on(info->netdev); | 1350 | netif_carrier_on(info->netdev); |
@@ -3058,7 +3060,7 @@ static int mgsl_ioctl_common(struct mgsl_struct *info, unsigned int cmd, unsigne | |||
3058 | * | 3060 | * |
3059 | * Return Value: None | 3061 | * Return Value: None |
3060 | */ | 3062 | */ |
3061 | static void mgsl_set_termios(struct tty_struct *tty, struct termios *old_termios) | 3063 | static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
3062 | { | 3064 | { |
3063 | struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data; | 3065 | struct mgsl_struct *info = (struct mgsl_struct *)tty->driver_data; |
3064 | unsigned long flags; | 3066 | unsigned long flags; |
@@ -4313,7 +4315,7 @@ static void mgsl_add_device( struct mgsl_struct *info ) | |||
4313 | info->max_frame_size ); | 4315 | info->max_frame_size ); |
4314 | } | 4316 | } |
4315 | 4317 | ||
4316 | #ifdef CONFIG_HDLC | 4318 | #if SYNCLINK_GENERIC_HDLC |
4317 | hdlcdev_init(info); | 4319 | hdlcdev_init(info); |
4318 | #endif | 4320 | #endif |
4319 | 4321 | ||
@@ -4403,6 +4405,8 @@ static int mgsl_init_tty(void) | |||
4403 | serial_driver->init_termios = tty_std_termios; | 4405 | serial_driver->init_termios = tty_std_termios; |
4404 | serial_driver->init_termios.c_cflag = | 4406 | serial_driver->init_termios.c_cflag = |
4405 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 4407 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
4408 | serial_driver->init_termios.c_ispeed = 9600; | ||
4409 | serial_driver->init_termios.c_ospeed = 9600; | ||
4406 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 4410 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
4407 | tty_set_operations(serial_driver, &mgsl_ops); | 4411 | tty_set_operations(serial_driver, &mgsl_ops); |
4408 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 4412 | if ((rc = tty_register_driver(serial_driver)) < 0) { |
@@ -4471,7 +4475,7 @@ static void synclink_cleanup(void) | |||
4471 | 4475 | ||
4472 | info = mgsl_device_list; | 4476 | info = mgsl_device_list; |
4473 | while(info) { | 4477 | while(info) { |
4474 | #ifdef CONFIG_HDLC | 4478 | #if SYNCLINK_GENERIC_HDLC |
4475 | hdlcdev_exit(info); | 4479 | hdlcdev_exit(info); |
4476 | #endif | 4480 | #endif |
4477 | mgsl_release_resources(info); | 4481 | mgsl_release_resources(info); |
@@ -6645,7 +6649,7 @@ static int mgsl_get_rx_frame(struct mgsl_struct *info) | |||
6645 | return_frame = 1; | 6649 | return_frame = 1; |
6646 | } | 6650 | } |
6647 | framesize = 0; | 6651 | framesize = 0; |
6648 | #ifdef CONFIG_HDLC | 6652 | #if SYNCLINK_GENERIC_HDLC |
6649 | { | 6653 | { |
6650 | struct net_device_stats *stats = hdlc_stats(info->netdev); | 6654 | struct net_device_stats *stats = hdlc_stats(info->netdev); |
6651 | stats->rx_errors++; | 6655 | stats->rx_errors++; |
@@ -6721,7 +6725,7 @@ static int mgsl_get_rx_frame(struct mgsl_struct *info) | |||
6721 | *ptmp); | 6725 | *ptmp); |
6722 | } | 6726 | } |
6723 | 6727 | ||
6724 | #ifdef CONFIG_HDLC | 6728 | #if SYNCLINK_GENERIC_HDLC |
6725 | if (info->netcount) | 6729 | if (info->netcount) |
6726 | hdlcdev_rx(info,info->intermediate_rxbuffer,framesize); | 6730 | hdlcdev_rx(info,info->intermediate_rxbuffer,framesize); |
6727 | else | 6731 | else |
@@ -7625,7 +7629,7 @@ static void mgsl_tx_timeout(unsigned long context) | |||
7625 | 7629 | ||
7626 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 7630 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
7627 | 7631 | ||
7628 | #ifdef CONFIG_HDLC | 7632 | #if SYNCLINK_GENERIC_HDLC |
7629 | if (info->netcount) | 7633 | if (info->netcount) |
7630 | hdlcdev_tx_done(info); | 7634 | hdlcdev_tx_done(info); |
7631 | else | 7635 | else |
@@ -7701,7 +7705,7 @@ static int usc_loopmode_active( struct mgsl_struct * info) | |||
7701 | return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ; | 7705 | return usc_InReg( info, CCSR ) & BIT7 ? 1 : 0 ; |
7702 | } | 7706 | } |
7703 | 7707 | ||
7704 | #ifdef CONFIG_HDLC | 7708 | #if SYNCLINK_GENERIC_HDLC |
7705 | 7709 | ||
7706 | /** | 7710 | /** |
7707 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) | 7711 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 07f34d43dc7f..792c79c315e0 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -83,8 +83,10 @@ | |||
83 | 83 | ||
84 | #include "linux/synclink.h" | 84 | #include "linux/synclink.h" |
85 | 85 | ||
86 | #ifdef CONFIG_HDLC_MODULE | 86 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) |
87 | #define CONFIG_HDLC 1 | 87 | #define SYNCLINK_GENERIC_HDLC 1 |
88 | #else | ||
89 | #define SYNCLINK_GENERIC_HDLC 0 | ||
88 | #endif | 90 | #endif |
89 | 91 | ||
90 | /* | 92 | /* |
@@ -149,7 +151,7 @@ static struct tty_driver *serial_driver; | |||
149 | static int open(struct tty_struct *tty, struct file * filp); | 151 | static int open(struct tty_struct *tty, struct file * filp); |
150 | static void close(struct tty_struct *tty, struct file * filp); | 152 | static void close(struct tty_struct *tty, struct file * filp); |
151 | static void hangup(struct tty_struct *tty); | 153 | static void hangup(struct tty_struct *tty); |
152 | static void set_termios(struct tty_struct *tty, struct termios *old_termios); | 154 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); |
153 | 155 | ||
154 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); | 156 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); |
155 | static void put_char(struct tty_struct *tty, unsigned char ch); | 157 | static void put_char(struct tty_struct *tty, unsigned char ch); |
@@ -171,7 +173,7 @@ static void set_break(struct tty_struct *tty, int break_state); | |||
171 | /* | 173 | /* |
172 | * generic HDLC support and callbacks | 174 | * generic HDLC support and callbacks |
173 | */ | 175 | */ |
174 | #ifdef CONFIG_HDLC | 176 | #if SYNCLINK_GENERIC_HDLC |
175 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | 177 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) |
176 | static void hdlcdev_tx_done(struct slgt_info *info); | 178 | static void hdlcdev_tx_done(struct slgt_info *info); |
177 | static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); | 179 | static void hdlcdev_rx(struct slgt_info *info, char *buf, int size); |
@@ -359,7 +361,7 @@ struct slgt_info { | |||
359 | int netcount; | 361 | int netcount; |
360 | int dosyncppp; | 362 | int dosyncppp; |
361 | spinlock_t netlock; | 363 | spinlock_t netlock; |
362 | #ifdef CONFIG_HDLC | 364 | #if SYNCLINK_GENERIC_HDLC |
363 | struct net_device *netdev; | 365 | struct net_device *netdev; |
364 | #endif | 366 | #endif |
365 | 367 | ||
@@ -814,7 +816,7 @@ static void hangup(struct tty_struct *tty) | |||
814 | wake_up_interruptible(&info->open_wait); | 816 | wake_up_interruptible(&info->open_wait); |
815 | } | 817 | } |
816 | 818 | ||
817 | static void set_termios(struct tty_struct *tty, struct termios *old_termios) | 819 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
818 | { | 820 | { |
819 | struct slgt_info *info = tty->driver_data; | 821 | struct slgt_info *info = tty->driver_data; |
820 | unsigned long flags; | 822 | unsigned long flags; |
@@ -1354,7 +1356,7 @@ static void set_break(struct tty_struct *tty, int break_state) | |||
1354 | spin_unlock_irqrestore(&info->lock,flags); | 1356 | spin_unlock_irqrestore(&info->lock,flags); |
1355 | } | 1357 | } |
1356 | 1358 | ||
1357 | #ifdef CONFIG_HDLC | 1359 | #if SYNCLINK_GENERIC_HDLC |
1358 | 1360 | ||
1359 | /** | 1361 | /** |
1360 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) | 1362 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) |
@@ -2002,7 +2004,7 @@ static void dcd_change(struct slgt_info *info) | |||
2002 | } else { | 2004 | } else { |
2003 | info->input_signal_events.dcd_down++; | 2005 | info->input_signal_events.dcd_down++; |
2004 | } | 2006 | } |
2005 | #ifdef CONFIG_HDLC | 2007 | #if SYNCLINK_GENERIC_HDLC |
2006 | if (info->netcount) { | 2008 | if (info->netcount) { |
2007 | if (info->signals & SerialSignal_DCD) | 2009 | if (info->signals & SerialSignal_DCD) |
2008 | netif_carrier_on(info->netdev); | 2010 | netif_carrier_on(info->netdev); |
@@ -2180,7 +2182,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status) | |||
2180 | set_signals(info); | 2182 | set_signals(info); |
2181 | } | 2183 | } |
2182 | 2184 | ||
2183 | #ifdef CONFIG_HDLC | 2185 | #if SYNCLINK_GENERIC_HDLC |
2184 | if (info->netcount) | 2186 | if (info->netcount) |
2185 | hdlcdev_tx_done(info); | 2187 | hdlcdev_tx_done(info); |
2186 | else | 2188 | else |
@@ -3306,7 +3308,7 @@ static void add_device(struct slgt_info *info) | |||
3306 | devstr, info->device_name, info->phys_reg_addr, | 3308 | devstr, info->device_name, info->phys_reg_addr, |
3307 | info->irq_level, info->max_frame_size); | 3309 | info->irq_level, info->max_frame_size); |
3308 | 3310 | ||
3309 | #ifdef CONFIG_HDLC | 3311 | #if SYNCLINK_GENERIC_HDLC |
3310 | hdlcdev_init(info); | 3312 | hdlcdev_init(info); |
3311 | #endif | 3313 | #endif |
3312 | } | 3314 | } |
@@ -3488,7 +3490,7 @@ static void slgt_cleanup(void) | |||
3488 | /* release devices */ | 3490 | /* release devices */ |
3489 | info = slgt_device_list; | 3491 | info = slgt_device_list; |
3490 | while(info) { | 3492 | while(info) { |
3491 | #ifdef CONFIG_HDLC | 3493 | #if SYNCLINK_GENERIC_HDLC |
3492 | hdlcdev_exit(info); | 3494 | hdlcdev_exit(info); |
3493 | #endif | 3495 | #endif |
3494 | free_dma_bufs(info); | 3496 | free_dma_bufs(info); |
@@ -3522,6 +3524,7 @@ static int __init slgt_init(void) | |||
3522 | 3524 | ||
3523 | if (!slgt_device_list) { | 3525 | if (!slgt_device_list) { |
3524 | printk("%s no devices found\n",driver_name); | 3526 | printk("%s no devices found\n",driver_name); |
3527 | pci_unregister_driver(&pci_driver); | ||
3525 | return -ENODEV; | 3528 | return -ENODEV; |
3526 | } | 3529 | } |
3527 | 3530 | ||
@@ -3543,6 +3546,8 @@ static int __init slgt_init(void) | |||
3543 | serial_driver->init_termios = tty_std_termios; | 3546 | serial_driver->init_termios = tty_std_termios; |
3544 | serial_driver->init_termios.c_cflag = | 3547 | serial_driver->init_termios.c_cflag = |
3545 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 3548 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
3549 | serial_driver->init_termios.c_ispeed = 9600; | ||
3550 | serial_driver->init_termios.c_ospeed = 9600; | ||
3546 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 3551 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
3547 | tty_set_operations(serial_driver, &ops); | 3552 | tty_set_operations(serial_driver, &ops); |
3548 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 3553 | if ((rc = tty_register_driver(serial_driver)) < 0) { |
@@ -4433,7 +4438,7 @@ check_again: | |||
4433 | framesize = 0; | 4438 | framesize = 0; |
4434 | } | 4439 | } |
4435 | 4440 | ||
4436 | #ifdef CONFIG_HDLC | 4441 | #if SYNCLINK_GENERIC_HDLC |
4437 | if (framesize == 0) { | 4442 | if (framesize == 0) { |
4438 | struct net_device_stats *stats = hdlc_stats(info->netdev); | 4443 | struct net_device_stats *stats = hdlc_stats(info->netdev); |
4439 | stats->rx_errors++; | 4444 | stats->rx_errors++; |
@@ -4476,7 +4481,7 @@ check_again: | |||
4476 | framesize++; | 4481 | framesize++; |
4477 | } | 4482 | } |
4478 | 4483 | ||
4479 | #ifdef CONFIG_HDLC | 4484 | #if SYNCLINK_GENERIC_HDLC |
4480 | if (info->netcount) | 4485 | if (info->netcount) |
4481 | hdlcdev_rx(info,info->tmp_rbuf, framesize); | 4486 | hdlcdev_rx(info,info->tmp_rbuf, framesize); |
4482 | else | 4487 | else |
@@ -4779,7 +4784,7 @@ static void tx_timeout(unsigned long context) | |||
4779 | info->tx_count = 0; | 4784 | info->tx_count = 0; |
4780 | spin_unlock_irqrestore(&info->lock,flags); | 4785 | spin_unlock_irqrestore(&info->lock,flags); |
4781 | 4786 | ||
4782 | #ifdef CONFIG_HDLC | 4787 | #if SYNCLINK_GENERIC_HDLC |
4783 | if (info->netcount) | 4788 | if (info->netcount) |
4784 | hdlcdev_tx_done(info); | 4789 | hdlcdev_tx_done(info); |
4785 | else | 4790 | else |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index 13a57245cf2e..53e8ccf94fe3 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -67,8 +67,10 @@ | |||
67 | #include <linux/workqueue.h> | 67 | #include <linux/workqueue.h> |
68 | #include <linux/hdlc.h> | 68 | #include <linux/hdlc.h> |
69 | 69 | ||
70 | #ifdef CONFIG_HDLC_MODULE | 70 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) |
71 | #define CONFIG_HDLC 1 | 71 | #define SYNCLINK_GENERIC_HDLC 1 |
72 | #else | ||
73 | #define SYNCLINK_GENERIC_HDLC 0 | ||
72 | #endif | 74 | #endif |
73 | 75 | ||
74 | #define GET_USER(error,value,addr) error = get_user(value,addr) | 76 | #define GET_USER(error,value,addr) error = get_user(value,addr) |
@@ -280,7 +282,7 @@ typedef struct _synclinkmp_info { | |||
280 | int dosyncppp; | 282 | int dosyncppp; |
281 | spinlock_t netlock; | 283 | spinlock_t netlock; |
282 | 284 | ||
283 | #ifdef CONFIG_HDLC | 285 | #if SYNCLINK_GENERIC_HDLC |
284 | struct net_device *netdev; | 286 | struct net_device *netdev; |
285 | #endif | 287 | #endif |
286 | 288 | ||
@@ -517,7 +519,7 @@ static struct tty_driver *serial_driver; | |||
517 | static int open(struct tty_struct *tty, struct file * filp); | 519 | static int open(struct tty_struct *tty, struct file * filp); |
518 | static void close(struct tty_struct *tty, struct file * filp); | 520 | static void close(struct tty_struct *tty, struct file * filp); |
519 | static void hangup(struct tty_struct *tty); | 521 | static void hangup(struct tty_struct *tty); |
520 | static void set_termios(struct tty_struct *tty, struct termios *old_termios); | 522 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios); |
521 | 523 | ||
522 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); | 524 | static int write(struct tty_struct *tty, const unsigned char *buf, int count); |
523 | static void put_char(struct tty_struct *tty, unsigned char ch); | 525 | static void put_char(struct tty_struct *tty, unsigned char ch); |
@@ -536,7 +538,7 @@ static void throttle(struct tty_struct * tty); | |||
536 | static void unthrottle(struct tty_struct * tty); | 538 | static void unthrottle(struct tty_struct * tty); |
537 | static void set_break(struct tty_struct *tty, int break_state); | 539 | static void set_break(struct tty_struct *tty, int break_state); |
538 | 540 | ||
539 | #ifdef CONFIG_HDLC | 541 | #if SYNCLINK_GENERIC_HDLC |
540 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) | 542 | #define dev_to_port(D) (dev_to_hdlc(D)->priv) |
541 | static void hdlcdev_tx_done(SLMP_INFO *info); | 543 | static void hdlcdev_tx_done(SLMP_INFO *info); |
542 | static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size); | 544 | static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size); |
@@ -916,7 +918,7 @@ static void hangup(struct tty_struct *tty) | |||
916 | 918 | ||
917 | /* Set new termios settings | 919 | /* Set new termios settings |
918 | */ | 920 | */ |
919 | static void set_termios(struct tty_struct *tty, struct termios *old_termios) | 921 | static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) |
920 | { | 922 | { |
921 | SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; | 923 | SLMP_INFO *info = (SLMP_INFO *)tty->driver_data; |
922 | unsigned long flags; | 924 | unsigned long flags; |
@@ -1607,7 +1609,7 @@ static void set_break(struct tty_struct *tty, int break_state) | |||
1607 | spin_unlock_irqrestore(&info->lock,flags); | 1609 | spin_unlock_irqrestore(&info->lock,flags); |
1608 | } | 1610 | } |
1609 | 1611 | ||
1610 | #ifdef CONFIG_HDLC | 1612 | #if SYNCLINK_GENERIC_HDLC |
1611 | 1613 | ||
1612 | /** | 1614 | /** |
1613 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) | 1615 | * called by generic HDLC layer when protocol selected (PPP, frame relay, etc.) |
@@ -2339,7 +2341,7 @@ static void isr_txeom(SLMP_INFO * info, unsigned char status) | |||
2339 | set_signals(info); | 2341 | set_signals(info); |
2340 | } | 2342 | } |
2341 | 2343 | ||
2342 | #ifdef CONFIG_HDLC | 2344 | #if SYNCLINK_GENERIC_HDLC |
2343 | if (info->netcount) | 2345 | if (info->netcount) |
2344 | hdlcdev_tx_done(info); | 2346 | hdlcdev_tx_done(info); |
2345 | else | 2347 | else |
@@ -2523,7 +2525,7 @@ void isr_io_pin( SLMP_INFO *info, u16 status ) | |||
2523 | info->input_signal_events.dcd_up++; | 2525 | info->input_signal_events.dcd_up++; |
2524 | } else | 2526 | } else |
2525 | info->input_signal_events.dcd_down++; | 2527 | info->input_signal_events.dcd_down++; |
2526 | #ifdef CONFIG_HDLC | 2528 | #if SYNCLINK_GENERIC_HDLC |
2527 | if (info->netcount) { | 2529 | if (info->netcount) { |
2528 | if (status & SerialSignal_DCD) | 2530 | if (status & SerialSignal_DCD) |
2529 | netif_carrier_on(info->netdev); | 2531 | netif_carrier_on(info->netdev); |
@@ -3783,7 +3785,7 @@ void add_device(SLMP_INFO *info) | |||
3783 | info->irq_level, | 3785 | info->irq_level, |
3784 | info->max_frame_size ); | 3786 | info->max_frame_size ); |
3785 | 3787 | ||
3786 | #ifdef CONFIG_HDLC | 3788 | #if SYNCLINK_GENERIC_HDLC |
3787 | hdlcdev_init(info); | 3789 | hdlcdev_init(info); |
3788 | #endif | 3790 | #endif |
3789 | } | 3791 | } |
@@ -3977,7 +3979,7 @@ static void synclinkmp_cleanup(void) | |||
3977 | /* release devices */ | 3979 | /* release devices */ |
3978 | info = synclinkmp_device_list; | 3980 | info = synclinkmp_device_list; |
3979 | while(info) { | 3981 | while(info) { |
3980 | #ifdef CONFIG_HDLC | 3982 | #if SYNCLINK_GENERIC_HDLC |
3981 | hdlcdev_exit(info); | 3983 | hdlcdev_exit(info); |
3982 | #endif | 3984 | #endif |
3983 | free_dma_bufs(info); | 3985 | free_dma_bufs(info); |
@@ -4032,6 +4034,8 @@ static int __init synclinkmp_init(void) | |||
4032 | serial_driver->init_termios = tty_std_termios; | 4034 | serial_driver->init_termios = tty_std_termios; |
4033 | serial_driver->init_termios.c_cflag = | 4035 | serial_driver->init_termios.c_cflag = |
4034 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 4036 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
4037 | serial_driver->init_termios.c_ispeed = 9600; | ||
4038 | serial_driver->init_termios.c_ospeed = 9600; | ||
4035 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 4039 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
4036 | tty_set_operations(serial_driver, &ops); | 4040 | tty_set_operations(serial_driver, &ops); |
4037 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 4041 | if ((rc = tty_register_driver(serial_driver)) < 0) { |
@@ -4979,7 +4983,7 @@ CheckAgain: | |||
4979 | info->icount.rxcrc++; | 4983 | info->icount.rxcrc++; |
4980 | 4984 | ||
4981 | framesize = 0; | 4985 | framesize = 0; |
4982 | #ifdef CONFIG_HDLC | 4986 | #if SYNCLINK_GENERIC_HDLC |
4983 | { | 4987 | { |
4984 | struct net_device_stats *stats = hdlc_stats(info->netdev); | 4988 | struct net_device_stats *stats = hdlc_stats(info->netdev); |
4985 | stats->rx_errors++; | 4989 | stats->rx_errors++; |
@@ -5020,7 +5024,7 @@ CheckAgain: | |||
5020 | index = 0; | 5024 | index = 0; |
5021 | } | 5025 | } |
5022 | 5026 | ||
5023 | #ifdef CONFIG_HDLC | 5027 | #if SYNCLINK_GENERIC_HDLC |
5024 | if (info->netcount) | 5028 | if (info->netcount) |
5025 | hdlcdev_rx(info,info->tmp_rx_buf,framesize); | 5029 | hdlcdev_rx(info,info->tmp_rx_buf,framesize); |
5026 | else | 5030 | else |
@@ -5531,7 +5535,7 @@ void tx_timeout(unsigned long context) | |||
5531 | 5535 | ||
5532 | spin_unlock_irqrestore(&info->lock,flags); | 5536 | spin_unlock_irqrestore(&info->lock,flags); |
5533 | 5537 | ||
5534 | #ifdef CONFIG_HDLC | 5538 | #if SYNCLINK_GENERIC_HDLC |
5535 | if (info->netcount) | 5539 | if (info->netcount) |
5536 | hdlcdev_tx_done(info); | 5540 | hdlcdev_tx_done(info); |
5537 | else | 5541 | else |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index c64f5bcff947..05810c8d20bc 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -182,6 +182,18 @@ static struct sysrq_key_op sysrq_showstate_op = { | |||
182 | .enable_mask = SYSRQ_ENABLE_DUMP, | 182 | .enable_mask = SYSRQ_ENABLE_DUMP, |
183 | }; | 183 | }; |
184 | 184 | ||
185 | static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) | ||
186 | { | ||
187 | show_state_filter(TASK_UNINTERRUPTIBLE); | ||
188 | } | ||
189 | static struct sysrq_key_op sysrq_showstate_blocked_op = { | ||
190 | .handler = sysrq_handle_showstate_blocked, | ||
191 | .help_msg = "showBlockedTasks", | ||
192 | .action_msg = "Show Blocked State", | ||
193 | .enable_mask = SYSRQ_ENABLE_DUMP, | ||
194 | }; | ||
195 | |||
196 | |||
185 | static void sysrq_handle_showmem(int key, struct tty_struct *tty) | 197 | static void sysrq_handle_showmem(int key, struct tty_struct *tty) |
186 | { | 198 | { |
187 | show_mem(); | 199 | show_mem(); |
@@ -304,7 +316,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { | |||
304 | /* May be assigned at init time by SMP VOYAGER */ | 316 | /* May be assigned at init time by SMP VOYAGER */ |
305 | NULL, /* v */ | 317 | NULL, /* v */ |
306 | NULL, /* w */ | 318 | NULL, /* w */ |
307 | NULL, /* x */ | 319 | &sysrq_showstate_blocked_op, /* x */ |
308 | NULL, /* y */ | 320 | NULL, /* y */ |
309 | NULL /* z */ | 321 | NULL /* z */ |
310 | }; | 322 | }; |
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index bb1bad4c18f9..4c431cb7cf1b 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c | |||
@@ -164,7 +164,7 @@ static ssize_t tanbac_tb0219_read(struct file *file, char __user *buf, size_t le | |||
164 | unsigned int minor; | 164 | unsigned int minor; |
165 | char value; | 165 | char value; |
166 | 166 | ||
167 | minor = iminor(file->f_dentry->d_inode); | 167 | minor = iminor(file->f_path.dentry->d_inode); |
168 | switch (minor) { | 168 | switch (minor) { |
169 | case 0: | 169 | case 0: |
170 | value = get_led(); | 170 | value = get_led(); |
@@ -200,7 +200,7 @@ static ssize_t tanbac_tb0219_write(struct file *file, const char __user *data, | |||
200 | int retval = 0; | 200 | int retval = 0; |
201 | char c; | 201 | char c; |
202 | 202 | ||
203 | minor = iminor(file->f_dentry->d_inode); | 203 | minor = iminor(file->f_path.dentry->d_inode); |
204 | switch (minor) { | 204 | switch (minor) { |
205 | case 0: | 205 | case 0: |
206 | type = TYPE_LED; | 206 | type = TYPE_LED; |
diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 9df0ca1be0e3..47fb20f69695 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c | |||
@@ -285,7 +285,7 @@ static ssize_t | |||
285 | tipar_write (struct file *file, const char __user *buf, size_t count, | 285 | tipar_write (struct file *file, const char __user *buf, size_t count, |
286 | loff_t * ppos) | 286 | loff_t * ppos) |
287 | { | 287 | { |
288 | unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; | 288 | unsigned int minor = iminor(file->f_path.dentry->d_inode) - TIPAR_MINOR; |
289 | ssize_t n; | 289 | ssize_t n; |
290 | 290 | ||
291 | parport_claim_or_block(table[minor].dev); | 291 | parport_claim_or_block(table[minor].dev); |
@@ -313,7 +313,7 @@ static ssize_t | |||
313 | tipar_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) | 313 | tipar_read(struct file *file, char __user *buf, size_t count, loff_t * ppos) |
314 | { | 314 | { |
315 | int b = 0; | 315 | int b = 0; |
316 | unsigned int minor = iminor(file->f_dentry->d_inode) - TIPAR_MINOR; | 316 | unsigned int minor = iminor(file->f_path.dentry->d_inode) - TIPAR_MINOR; |
317 | ssize_t retval = 0; | 317 | ssize_t retval = 0; |
318 | ssize_t n = 0; | 318 | ssize_t n = 0; |
319 | 319 | ||
diff --git a/drivers/char/toshiba.c b/drivers/char/toshiba.c index dd36fd04a842..07067c31c4ec 100644 --- a/drivers/char/toshiba.c +++ b/drivers/char/toshiba.c | |||
@@ -249,6 +249,7 @@ int tosh_smm(SMMRegisters *regs) | |||
249 | 249 | ||
250 | return eax; | 250 | return eax; |
251 | } | 251 | } |
252 | EXPORT_SYMBOL(tosh_smm); | ||
252 | 253 | ||
253 | 254 | ||
254 | static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, | 255 | static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd, |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 774fa861169a..33e1f66e39cb 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -1155,6 +1155,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1155 | 1155 | ||
1156 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { | 1156 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { |
1157 | list_del(&chip->list); | 1157 | list_del(&chip->list); |
1158 | misc_deregister(&chip->vendor.miscdev); | ||
1158 | put_device(dev); | 1159 | put_device(dev); |
1159 | clear_bit(chip->dev_num, dev_mask); | 1160 | clear_bit(chip->dev_num, dev_mask); |
1160 | kfree(chip); | 1161 | kfree(chip); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index b3cfc8bc613c..4044c864fdd4 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -109,13 +109,15 @@ | |||
109 | #define TTY_PARANOIA_CHECK 1 | 109 | #define TTY_PARANOIA_CHECK 1 |
110 | #define CHECK_TTY_COUNT 1 | 110 | #define CHECK_TTY_COUNT 1 |
111 | 111 | ||
112 | struct termios tty_std_termios = { /* for the benefit of tty drivers */ | 112 | struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ |
113 | .c_iflag = ICRNL | IXON, | 113 | .c_iflag = ICRNL | IXON, |
114 | .c_oflag = OPOST | ONLCR, | 114 | .c_oflag = OPOST | ONLCR, |
115 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, | 115 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, |
116 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | | 116 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | |
117 | ECHOCTL | ECHOKE | IEXTEN, | 117 | ECHOCTL | ECHOKE | IEXTEN, |
118 | .c_cc = INIT_C_CC | 118 | .c_cc = INIT_C_CC, |
119 | .c_ispeed = 38400, | ||
120 | .c_ospeed = 38400 | ||
119 | }; | 121 | }; |
120 | 122 | ||
121 | EXPORT_SYMBOL(tty_std_termios); | 123 | EXPORT_SYMBOL(tty_std_termios); |
@@ -126,7 +128,7 @@ EXPORT_SYMBOL(tty_std_termios); | |||
126 | 128 | ||
127 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | 129 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ |
128 | 130 | ||
129 | /* Semaphore to protect creating and releasing a tty. This is shared with | 131 | /* Mutex to protect creating and releasing a tty. This is shared with |
130 | vt.c for deeply disgusting hack reasons */ | 132 | vt.c for deeply disgusting hack reasons */ |
131 | DEFINE_MUTEX(tty_mutex); | 133 | DEFINE_MUTEX(tty_mutex); |
132 | EXPORT_SYMBOL(tty_mutex); | 134 | EXPORT_SYMBOL(tty_mutex); |
@@ -250,7 +252,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
250 | "!= #fd's(%d) in %s\n", | 252 | "!= #fd's(%d) in %s\n", |
251 | tty->name, tty->count, count, routine); | 253 | tty->name, tty->count, count, routine); |
252 | return count; | 254 | return count; |
253 | } | 255 | } |
254 | #endif | 256 | #endif |
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
@@ -259,18 +261,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
259 | * Tty buffer allocation management | 261 | * Tty buffer allocation management |
260 | */ | 262 | */ |
261 | 263 | ||
262 | |||
263 | /** | ||
264 | * tty_buffer_free_all - free buffers used by a tty | ||
265 | * @tty: tty to free from | ||
266 | * | ||
267 | * Remove all the buffers pending on a tty whether queued with data | ||
268 | * or in the free ring. Must be called when the tty is no longer in use | ||
269 | * | ||
270 | * Locking: none | ||
271 | */ | ||
272 | |||
273 | |||
274 | /** | 264 | /** |
275 | * tty_buffer_free_all - free buffers used by a tty | 265 | * tty_buffer_free_all - free buffers used by a tty |
276 | * @tty: tty to free from | 266 | * @tty: tty to free from |
@@ -614,7 +604,7 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | |||
614 | * they are not on hot paths so a little discipline won't do | 604 | * they are not on hot paths so a little discipline won't do |
615 | * any harm. | 605 | * any harm. |
616 | * | 606 | * |
617 | * Locking: takes termios_sem | 607 | * Locking: takes termios_mutex |
618 | */ | 608 | */ |
619 | 609 | ||
620 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 610 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) |
@@ -915,7 +905,7 @@ static void tty_ldisc_enable(struct tty_struct *tty) | |||
915 | * context. | 905 | * context. |
916 | * | 906 | * |
917 | * Locking: takes tty_ldisc_lock. | 907 | * Locking: takes tty_ldisc_lock. |
918 | * called functions take termios_sem | 908 | * called functions take termios_mutex |
919 | */ | 909 | */ |
920 | 910 | ||
921 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) | 911 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) |
@@ -1251,6 +1241,22 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
1251 | } | 1241 | } |
1252 | 1242 | ||
1253 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); | 1243 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
1244 | |||
1245 | /** | ||
1246 | * tty_reset_termios - reset terminal state | ||
1247 | * @tty: tty to reset | ||
1248 | * | ||
1249 | * Restore a terminal to the driver default state | ||
1250 | */ | ||
1251 | |||
1252 | static void tty_reset_termios(struct tty_struct *tty) | ||
1253 | { | ||
1254 | mutex_lock(&tty->termios_mutex); | ||
1255 | *tty->termios = tty->driver->init_termios; | ||
1256 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1257 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1258 | mutex_unlock(&tty->termios_mutex); | ||
1259 | } | ||
1254 | 1260 | ||
1255 | /** | 1261 | /** |
1256 | * do_tty_hangup - actual handler for hangup events | 1262 | * do_tty_hangup - actual handler for hangup events |
@@ -1267,12 +1273,12 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
1267 | * | 1273 | * |
1268 | * Locking: | 1274 | * Locking: |
1269 | * BKL | 1275 | * BKL |
1270 | * redirect lock for undoing redirection | 1276 | * redirect lock for undoing redirection |
1271 | * file list lock for manipulating list of ttys | 1277 | * file list lock for manipulating list of ttys |
1272 | * tty_ldisc_lock from called functions | 1278 | * tty_ldisc_lock from called functions |
1273 | * termios_sem resetting termios data | 1279 | * termios_mutex resetting termios data |
1274 | * tasklist_lock to walk task list for hangup event | 1280 | * tasklist_lock to walk task list for hangup event |
1275 | * | 1281 | * ->siglock to protect ->signal/->sighand |
1276 | */ | 1282 | */ |
1277 | static void do_tty_hangup(struct work_struct *work) | 1283 | static void do_tty_hangup(struct work_struct *work) |
1278 | { | 1284 | { |
@@ -1339,11 +1345,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
1339 | * N_TTY. | 1345 | * N_TTY. |
1340 | */ | 1346 | */ |
1341 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) | 1347 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1342 | { | 1348 | tty_reset_termios(tty); |
1343 | mutex_lock(&tty->termios_mutex); | ||
1344 | *tty->termios = tty->driver->init_termios; | ||
1345 | mutex_unlock(&tty->termios_mutex); | ||
1346 | } | ||
1347 | 1349 | ||
1348 | /* Defer ldisc switch */ | 1350 | /* Defer ldisc switch */ |
1349 | /* tty_deferred_ldisc_switch(N_TTY); | 1351 | /* tty_deferred_ldisc_switch(N_TTY); |
@@ -1354,14 +1356,18 @@ static void do_tty_hangup(struct work_struct *work) | |||
1354 | read_lock(&tasklist_lock); | 1356 | read_lock(&tasklist_lock); |
1355 | if (tty->session > 0) { | 1357 | if (tty->session > 0) { |
1356 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 1358 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { |
1359 | spin_lock_irq(&p->sighand->siglock); | ||
1357 | if (p->signal->tty == tty) | 1360 | if (p->signal->tty == tty) |
1358 | p->signal->tty = NULL; | 1361 | p->signal->tty = NULL; |
1359 | if (!p->signal->leader) | 1362 | if (!p->signal->leader) { |
1363 | spin_unlock_irq(&p->sighand->siglock); | ||
1360 | continue; | 1364 | continue; |
1361 | group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | 1365 | } |
1362 | group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | 1366 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); |
1367 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | ||
1363 | if (tty->pgrp > 0) | 1368 | if (tty->pgrp > 0) |
1364 | p->signal->tty_old_pgrp = tty->pgrp; | 1369 | p->signal->tty_old_pgrp = tty->pgrp; |
1370 | spin_unlock_irq(&p->sighand->siglock); | ||
1365 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | 1371 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); |
1366 | } | 1372 | } |
1367 | read_unlock(&tasklist_lock); | 1373 | read_unlock(&tasklist_lock); |
@@ -1453,6 +1459,14 @@ int tty_hung_up_p(struct file * filp) | |||
1453 | 1459 | ||
1454 | EXPORT_SYMBOL(tty_hung_up_p); | 1460 | EXPORT_SYMBOL(tty_hung_up_p); |
1455 | 1461 | ||
1462 | static void session_clear_tty(pid_t session) | ||
1463 | { | ||
1464 | struct task_struct *p; | ||
1465 | do_each_task_pid(session, PIDTYPE_SID, p) { | ||
1466 | proc_clear_tty(p); | ||
1467 | } while_each_task_pid(session, PIDTYPE_SID, p); | ||
1468 | } | ||
1469 | |||
1456 | /** | 1470 | /** |
1457 | * disassociate_ctty - disconnect controlling tty | 1471 | * disassociate_ctty - disconnect controlling tty |
1458 | * @on_exit: true if exiting so need to "hang up" the session | 1472 | * @on_exit: true if exiting so need to "hang up" the session |
@@ -1469,31 +1483,35 @@ EXPORT_SYMBOL(tty_hung_up_p); | |||
1469 | * The argument on_exit is set to 1 if called when a process is | 1483 | * The argument on_exit is set to 1 if called when a process is |
1470 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 1484 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
1471 | * | 1485 | * |
1472 | * Locking: tty_mutex is taken to protect current->signal->tty | 1486 | * Locking: |
1473 | * BKL is taken for hysterical raisins | 1487 | * BKL is taken for hysterical raisins |
1474 | * Tasklist lock is taken (under tty_mutex) to walk process | 1488 | * tty_mutex is taken to protect tty |
1475 | * lists for the session. | 1489 | * ->siglock is taken to protect ->signal/->sighand |
1490 | * tasklist_lock is taken to walk process list for sessions | ||
1491 | * ->siglock is taken to protect ->signal/->sighand | ||
1476 | */ | 1492 | */ |
1477 | 1493 | ||
1478 | void disassociate_ctty(int on_exit) | 1494 | void disassociate_ctty(int on_exit) |
1479 | { | 1495 | { |
1480 | struct tty_struct *tty; | 1496 | struct tty_struct *tty; |
1481 | struct task_struct *p; | ||
1482 | int tty_pgrp = -1; | 1497 | int tty_pgrp = -1; |
1498 | int session; | ||
1483 | 1499 | ||
1484 | lock_kernel(); | 1500 | lock_kernel(); |
1485 | 1501 | ||
1486 | mutex_lock(&tty_mutex); | 1502 | mutex_lock(&tty_mutex); |
1487 | tty = current->signal->tty; | 1503 | tty = get_current_tty(); |
1488 | if (tty) { | 1504 | if (tty) { |
1489 | tty_pgrp = tty->pgrp; | 1505 | tty_pgrp = tty->pgrp; |
1490 | mutex_unlock(&tty_mutex); | 1506 | mutex_unlock(&tty_mutex); |
1507 | /* XXX: here we race, there is nothing protecting tty */ | ||
1491 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 1508 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
1492 | tty_vhangup(tty); | 1509 | tty_vhangup(tty); |
1493 | } else { | 1510 | } else { |
1494 | if (current->signal->tty_old_pgrp) { | 1511 | pid_t old_pgrp = current->signal->tty_old_pgrp; |
1495 | kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); | 1512 | if (old_pgrp) { |
1496 | kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); | 1513 | kill_pg(old_pgrp, SIGHUP, on_exit); |
1514 | kill_pg(old_pgrp, SIGCONT, on_exit); | ||
1497 | } | 1515 | } |
1498 | mutex_unlock(&tty_mutex); | 1516 | mutex_unlock(&tty_mutex); |
1499 | unlock_kernel(); | 1517 | unlock_kernel(); |
@@ -1505,19 +1523,29 @@ void disassociate_ctty(int on_exit) | |||
1505 | kill_pg(tty_pgrp, SIGCONT, on_exit); | 1523 | kill_pg(tty_pgrp, SIGCONT, on_exit); |
1506 | } | 1524 | } |
1507 | 1525 | ||
1508 | /* Must lock changes to tty_old_pgrp */ | 1526 | spin_lock_irq(¤t->sighand->siglock); |
1509 | mutex_lock(&tty_mutex); | ||
1510 | current->signal->tty_old_pgrp = 0; | 1527 | current->signal->tty_old_pgrp = 0; |
1511 | tty->session = 0; | 1528 | session = process_session(current); |
1512 | tty->pgrp = -1; | 1529 | spin_unlock_irq(¤t->sighand->siglock); |
1530 | |||
1531 | mutex_lock(&tty_mutex); | ||
1532 | /* It is possible that do_tty_hangup has free'd this tty */ | ||
1533 | tty = get_current_tty(); | ||
1534 | if (tty) { | ||
1535 | tty->session = 0; | ||
1536 | tty->pgrp = 0; | ||
1537 | } else { | ||
1538 | #ifdef TTY_DEBUG_HANGUP | ||
1539 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | ||
1540 | " = NULL", tty); | ||
1541 | #endif | ||
1542 | } | ||
1543 | mutex_unlock(&tty_mutex); | ||
1513 | 1544 | ||
1514 | /* Now clear signal->tty under the lock */ | 1545 | /* Now clear signal->tty under the lock */ |
1515 | read_lock(&tasklist_lock); | 1546 | read_lock(&tasklist_lock); |
1516 | do_each_task_pid(current->signal->session, PIDTYPE_SID, p) { | 1547 | session_clear_tty(session); |
1517 | p->signal->tty = NULL; | ||
1518 | } while_each_task_pid(current->signal->session, PIDTYPE_SID, p); | ||
1519 | read_unlock(&tasklist_lock); | 1548 | read_unlock(&tasklist_lock); |
1520 | mutex_unlock(&tty_mutex); | ||
1521 | unlock_kernel(); | 1549 | unlock_kernel(); |
1522 | } | 1550 | } |
1523 | 1551 | ||
@@ -1615,7 +1643,7 @@ static ssize_t tty_read(struct file * file, char __user * buf, size_t count, | |||
1615 | struct tty_ldisc *ld; | 1643 | struct tty_ldisc *ld; |
1616 | 1644 | ||
1617 | tty = (struct tty_struct *)file->private_data; | 1645 | tty = (struct tty_struct *)file->private_data; |
1618 | inode = file->f_dentry->d_inode; | 1646 | inode = file->f_path.dentry->d_inode; |
1619 | if (tty_paranoia_check(tty, inode, "tty_read")) | 1647 | if (tty_paranoia_check(tty, inode, "tty_read")) |
1620 | return -EIO; | 1648 | return -EIO; |
1621 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 1649 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) |
@@ -1718,7 +1746,7 @@ static inline ssize_t do_tty_write( | |||
1718 | cond_resched(); | 1746 | cond_resched(); |
1719 | } | 1747 | } |
1720 | if (written) { | 1748 | if (written) { |
1721 | struct inode *inode = file->f_dentry->d_inode; | 1749 | struct inode *inode = file->f_path.dentry->d_inode; |
1722 | inode->i_mtime = current_fs_time(inode->i_sb); | 1750 | inode->i_mtime = current_fs_time(inode->i_sb); |
1723 | ret = written; | 1751 | ret = written; |
1724 | } | 1752 | } |
@@ -1749,7 +1777,7 @@ static ssize_t tty_write(struct file * file, const char __user * buf, size_t cou | |||
1749 | loff_t *ppos) | 1777 | loff_t *ppos) |
1750 | { | 1778 | { |
1751 | struct tty_struct * tty; | 1779 | struct tty_struct * tty; |
1752 | struct inode *inode = file->f_dentry->d_inode; | 1780 | struct inode *inode = file->f_path.dentry->d_inode; |
1753 | ssize_t ret; | 1781 | ssize_t ret; |
1754 | struct tty_ldisc *ld; | 1782 | struct tty_ldisc *ld; |
1755 | 1783 | ||
@@ -1856,8 +1884,8 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1856 | struct tty_struct **ret_tty) | 1884 | struct tty_struct **ret_tty) |
1857 | { | 1885 | { |
1858 | struct tty_struct *tty, *o_tty; | 1886 | struct tty_struct *tty, *o_tty; |
1859 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1887 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; |
1860 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | 1888 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; |
1861 | int retval = 0; | 1889 | int retval = 0; |
1862 | 1890 | ||
1863 | /* check whether we're reopening an existing tty */ | 1891 | /* check whether we're reopening an existing tty */ |
@@ -1904,7 +1932,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1904 | } | 1932 | } |
1905 | 1933 | ||
1906 | if (!*tp_loc) { | 1934 | if (!*tp_loc) { |
1907 | tp = (struct termios *) kmalloc(sizeof(struct termios), | 1935 | tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), |
1908 | GFP_KERNEL); | 1936 | GFP_KERNEL); |
1909 | if (!tp) | 1937 | if (!tp) |
1910 | goto free_mem_out; | 1938 | goto free_mem_out; |
@@ -1912,11 +1940,11 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1912 | } | 1940 | } |
1913 | 1941 | ||
1914 | if (!*ltp_loc) { | 1942 | if (!*ltp_loc) { |
1915 | ltp = (struct termios *) kmalloc(sizeof(struct termios), | 1943 | ltp = (struct ktermios *) kmalloc(sizeof(struct ktermios), |
1916 | GFP_KERNEL); | 1944 | GFP_KERNEL); |
1917 | if (!ltp) | 1945 | if (!ltp) |
1918 | goto free_mem_out; | 1946 | goto free_mem_out; |
1919 | memset(ltp, 0, sizeof(struct termios)); | 1947 | memset(ltp, 0, sizeof(struct ktermios)); |
1920 | } | 1948 | } |
1921 | 1949 | ||
1922 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | 1950 | if (driver->type == TTY_DRIVER_TYPE_PTY) { |
@@ -1937,19 +1965,19 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1937 | } | 1965 | } |
1938 | 1966 | ||
1939 | if (!*o_tp_loc) { | 1967 | if (!*o_tp_loc) { |
1940 | o_tp = (struct termios *) | 1968 | o_tp = (struct ktermios *) |
1941 | kmalloc(sizeof(struct termios), GFP_KERNEL); | 1969 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1942 | if (!o_tp) | 1970 | if (!o_tp) |
1943 | goto free_mem_out; | 1971 | goto free_mem_out; |
1944 | *o_tp = driver->other->init_termios; | 1972 | *o_tp = driver->other->init_termios; |
1945 | } | 1973 | } |
1946 | 1974 | ||
1947 | if (!*o_ltp_loc) { | 1975 | if (!*o_ltp_loc) { |
1948 | o_ltp = (struct termios *) | 1976 | o_ltp = (struct ktermios *) |
1949 | kmalloc(sizeof(struct termios), GFP_KERNEL); | 1977 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1950 | if (!o_ltp) | 1978 | if (!o_ltp) |
1951 | goto free_mem_out; | 1979 | goto free_mem_out; |
1952 | memset(o_ltp, 0, sizeof(struct termios)); | 1980 | memset(o_ltp, 0, sizeof(struct ktermios)); |
1953 | } | 1981 | } |
1954 | 1982 | ||
1955 | /* | 1983 | /* |
@@ -1988,6 +2016,9 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1988 | *ltp_loc = ltp; | 2016 | *ltp_loc = ltp; |
1989 | tty->termios = *tp_loc; | 2017 | tty->termios = *tp_loc; |
1990 | tty->termios_locked = *ltp_loc; | 2018 | tty->termios_locked = *ltp_loc; |
2019 | /* Compatibility until drivers always set this */ | ||
2020 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
2021 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1991 | driver->refcount++; | 2022 | driver->refcount++; |
1992 | tty->count++; | 2023 | tty->count++; |
1993 | 2024 | ||
@@ -2090,7 +2121,7 @@ release_mem_out: | |||
2090 | static void release_mem(struct tty_struct *tty, int idx) | 2121 | static void release_mem(struct tty_struct *tty, int idx) |
2091 | { | 2122 | { |
2092 | struct tty_struct *o_tty; | 2123 | struct tty_struct *o_tty; |
2093 | struct termios *tp; | 2124 | struct ktermios *tp; |
2094 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 2125 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; |
2095 | 2126 | ||
2096 | if ((o_tty = tty->link) != NULL) { | 2127 | if ((o_tty = tty->link) != NULL) { |
@@ -2156,7 +2187,7 @@ static void release_dev(struct file * filp) | |||
2156 | unsigned long flags; | 2187 | unsigned long flags; |
2157 | 2188 | ||
2158 | tty = (struct tty_struct *)filp->private_data; | 2189 | tty = (struct tty_struct *)filp->private_data; |
2159 | if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev")) | 2190 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "release_dev")) |
2160 | return; | 2191 | return; |
2161 | 2192 | ||
2162 | check_tty_count(tty, "release_dev"); | 2193 | check_tty_count(tty, "release_dev"); |
@@ -2337,16 +2368,10 @@ static void release_dev(struct file * filp) | |||
2337 | * tty. | 2368 | * tty. |
2338 | */ | 2369 | */ |
2339 | if (tty_closing || o_tty_closing) { | 2370 | if (tty_closing || o_tty_closing) { |
2340 | struct task_struct *p; | ||
2341 | |||
2342 | read_lock(&tasklist_lock); | 2371 | read_lock(&tasklist_lock); |
2343 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 2372 | session_clear_tty(tty->session); |
2344 | p->signal->tty = NULL; | ||
2345 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | ||
2346 | if (o_tty) | 2373 | if (o_tty) |
2347 | do_each_task_pid(o_tty->session, PIDTYPE_SID, p) { | 2374 | session_clear_tty(o_tty->session); |
2348 | p->signal->tty = NULL; | ||
2349 | } while_each_task_pid(o_tty->session, PIDTYPE_SID, p); | ||
2350 | read_unlock(&tasklist_lock); | 2375 | read_unlock(&tasklist_lock); |
2351 | } | 2376 | } |
2352 | 2377 | ||
@@ -2443,9 +2468,9 @@ static void release_dev(struct file * filp) | |||
2443 | * The termios state of a pty is reset on first open so that | 2468 | * The termios state of a pty is reset on first open so that |
2444 | * settings don't persist across reuse. | 2469 | * settings don't persist across reuse. |
2445 | * | 2470 | * |
2446 | * Locking: tty_mutex protects current->signal->tty, get_tty_driver and | 2471 | * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. |
2447 | * init_dev work. tty->count should protect the rest. | 2472 | * tty->count should protect the rest. |
2448 | * task_lock is held to update task details for sessions | 2473 | * ->siglock protects ->signal/->sighand |
2449 | */ | 2474 | */ |
2450 | 2475 | ||
2451 | static int tty_open(struct inode * inode, struct file * filp) | 2476 | static int tty_open(struct inode * inode, struct file * filp) |
@@ -2467,12 +2492,13 @@ retry_open: | |||
2467 | mutex_lock(&tty_mutex); | 2492 | mutex_lock(&tty_mutex); |
2468 | 2493 | ||
2469 | if (device == MKDEV(TTYAUX_MAJOR,0)) { | 2494 | if (device == MKDEV(TTYAUX_MAJOR,0)) { |
2470 | if (!current->signal->tty) { | 2495 | tty = get_current_tty(); |
2496 | if (!tty) { | ||
2471 | mutex_unlock(&tty_mutex); | 2497 | mutex_unlock(&tty_mutex); |
2472 | return -ENXIO; | 2498 | return -ENXIO; |
2473 | } | 2499 | } |
2474 | driver = current->signal->tty->driver; | 2500 | driver = tty->driver; |
2475 | index = current->signal->tty->index; | 2501 | index = tty->index; |
2476 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | 2502 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
2477 | /* noctty = 1; */ | 2503 | /* noctty = 1; */ |
2478 | goto got_driver; | 2504 | goto got_driver; |
@@ -2547,17 +2573,16 @@ got_driver: | |||
2547 | filp->f_op = &tty_fops; | 2573 | filp->f_op = &tty_fops; |
2548 | goto retry_open; | 2574 | goto retry_open; |
2549 | } | 2575 | } |
2576 | |||
2577 | mutex_lock(&tty_mutex); | ||
2578 | spin_lock_irq(¤t->sighand->siglock); | ||
2550 | if (!noctty && | 2579 | if (!noctty && |
2551 | current->signal->leader && | 2580 | current->signal->leader && |
2552 | !current->signal->tty && | 2581 | !current->signal->tty && |
2553 | tty->session == 0) { | 2582 | tty->session == 0) |
2554 | task_lock(current); | 2583 | __proc_set_tty(current, tty); |
2555 | current->signal->tty = tty; | 2584 | spin_unlock_irq(¤t->sighand->siglock); |
2556 | task_unlock(current); | 2585 | mutex_unlock(&tty_mutex); |
2557 | current->signal->tty_old_pgrp = 0; | ||
2558 | tty->session = current->signal->session; | ||
2559 | tty->pgrp = process_group(current); | ||
2560 | } | ||
2561 | return 0; | 2586 | return 0; |
2562 | } | 2587 | } |
2563 | 2588 | ||
@@ -2672,7 +2697,7 @@ static unsigned int tty_poll(struct file * filp, poll_table * wait) | |||
2672 | int ret = 0; | 2697 | int ret = 0; |
2673 | 2698 | ||
2674 | tty = (struct tty_struct *)filp->private_data; | 2699 | tty = (struct tty_struct *)filp->private_data; |
2675 | if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll")) | 2700 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
2676 | return 0; | 2701 | return 0; |
2677 | 2702 | ||
2678 | ld = tty_ldisc_ref_wait(tty); | 2703 | ld = tty_ldisc_ref_wait(tty); |
@@ -2688,7 +2713,7 @@ static int tty_fasync(int fd, struct file * filp, int on) | |||
2688 | int retval; | 2713 | int retval; |
2689 | 2714 | ||
2690 | tty = (struct tty_struct *)filp->private_data; | 2715 | tty = (struct tty_struct *)filp->private_data; |
2691 | if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_fasync")) | 2716 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
2692 | return 0; | 2717 | return 0; |
2693 | 2718 | ||
2694 | retval = fasync_helper(fd, filp, on, &tty->fasync); | 2719 | retval = fasync_helper(fd, filp, on, &tty->fasync); |
@@ -2747,7 +2772,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2747 | * | 2772 | * |
2748 | * Copies the kernel idea of the window size into the user buffer. | 2773 | * Copies the kernel idea of the window size into the user buffer. |
2749 | * | 2774 | * |
2750 | * Locking: tty->termios_sem is taken to ensure the winsize data | 2775 | * Locking: tty->termios_mutex is taken to ensure the winsize data |
2751 | * is consistent. | 2776 | * is consistent. |
2752 | */ | 2777 | */ |
2753 | 2778 | ||
@@ -2774,8 +2799,8 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) | |||
2774 | * Locking: | 2799 | * Locking: |
2775 | * Called function use the console_sem is used to ensure we do | 2800 | * Called function use the console_sem is used to ensure we do |
2776 | * not try and resize the console twice at once. | 2801 | * not try and resize the console twice at once. |
2777 | * The tty->termios_sem is used to ensure we don't double | 2802 | * The tty->termios_mutex is used to ensure we don't double |
2778 | * resize and get confused. Lock order - tty->termios.sem before | 2803 | * resize and get confused. Lock order - tty->termios_mutex before |
2779 | * console sem | 2804 | * console sem |
2780 | */ | 2805 | */ |
2781 | 2806 | ||
@@ -2880,25 +2905,28 @@ static int fionbio(struct file *file, int __user *p) | |||
2880 | * leader to set this tty as the controlling tty for the session. | 2905 | * leader to set this tty as the controlling tty for the session. |
2881 | * | 2906 | * |
2882 | * Locking: | 2907 | * Locking: |
2883 | * Takes tasklist lock internally to walk sessions | ||
2884 | * Takes task_lock() when updating signal->tty | ||
2885 | * Takes tty_mutex() to protect tty instance | 2908 | * Takes tty_mutex() to protect tty instance |
2886 | * | 2909 | * Takes tasklist_lock internally to walk sessions |
2910 | * Takes ->siglock() when updating signal->tty | ||
2887 | */ | 2911 | */ |
2888 | 2912 | ||
2889 | static int tiocsctty(struct tty_struct *tty, int arg) | 2913 | static int tiocsctty(struct tty_struct *tty, int arg) |
2890 | { | 2914 | { |
2891 | struct task_struct *p; | 2915 | int ret = 0; |
2892 | |||
2893 | if (current->signal->leader && | 2916 | if (current->signal->leader && |
2894 | (current->signal->session == tty->session)) | 2917 | (process_session(current) == tty->session)) |
2895 | return 0; | 2918 | return ret; |
2919 | |||
2920 | mutex_lock(&tty_mutex); | ||
2896 | /* | 2921 | /* |
2897 | * The process must be a session leader and | 2922 | * The process must be a session leader and |
2898 | * not have a controlling tty already. | 2923 | * not have a controlling tty already. |
2899 | */ | 2924 | */ |
2900 | if (!current->signal->leader || current->signal->tty) | 2925 | if (!current->signal->leader || current->signal->tty) { |
2901 | return -EPERM; | 2926 | ret = -EPERM; |
2927 | goto unlock; | ||
2928 | } | ||
2929 | |||
2902 | if (tty->session > 0) { | 2930 | if (tty->session > 0) { |
2903 | /* | 2931 | /* |
2904 | * This tty is already the controlling | 2932 | * This tty is already the controlling |
@@ -2908,24 +2936,18 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2908 | /* | 2936 | /* |
2909 | * Steal it away | 2937 | * Steal it away |
2910 | */ | 2938 | */ |
2911 | |||
2912 | read_lock(&tasklist_lock); | 2939 | read_lock(&tasklist_lock); |
2913 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 2940 | session_clear_tty(tty->session); |
2914 | p->signal->tty = NULL; | ||
2915 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | ||
2916 | read_unlock(&tasklist_lock); | 2941 | read_unlock(&tasklist_lock); |
2917 | } else | 2942 | } else { |
2918 | return -EPERM; | 2943 | ret = -EPERM; |
2944 | goto unlock; | ||
2945 | } | ||
2919 | } | 2946 | } |
2920 | mutex_lock(&tty_mutex); | 2947 | proc_set_tty(current, tty); |
2921 | task_lock(current); | 2948 | unlock: |
2922 | current->signal->tty = tty; | ||
2923 | task_unlock(current); | ||
2924 | mutex_unlock(&tty_mutex); | 2949 | mutex_unlock(&tty_mutex); |
2925 | current->signal->tty_old_pgrp = 0; | 2950 | return ret; |
2926 | tty->session = current->signal->session; | ||
2927 | tty->pgrp = process_group(current); | ||
2928 | return 0; | ||
2929 | } | 2951 | } |
2930 | 2952 | ||
2931 | /** | 2953 | /** |
@@ -2937,7 +2959,7 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2937 | * Obtain the process group of the tty. If there is no process group | 2959 | * Obtain the process group of the tty. If there is no process group |
2938 | * return an error. | 2960 | * return an error. |
2939 | * | 2961 | * |
2940 | * Locking: none. Reference to ->signal->tty is safe. | 2962 | * Locking: none. Reference to current->signal->tty is safe. |
2941 | */ | 2963 | */ |
2942 | 2964 | ||
2943 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2965 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
@@ -2974,13 +2996,13 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2974 | return retval; | 2996 | return retval; |
2975 | if (!current->signal->tty || | 2997 | if (!current->signal->tty || |
2976 | (current->signal->tty != real_tty) || | 2998 | (current->signal->tty != real_tty) || |
2977 | (real_tty->session != current->signal->session)) | 2999 | (real_tty->session != process_session(current))) |
2978 | return -ENOTTY; | 3000 | return -ENOTTY; |
2979 | if (get_user(pgrp, p)) | 3001 | if (get_user(pgrp, p)) |
2980 | return -EFAULT; | 3002 | return -EFAULT; |
2981 | if (pgrp < 0) | 3003 | if (pgrp < 0) |
2982 | return -EINVAL; | 3004 | return -EINVAL; |
2983 | if (session_of_pgrp(pgrp) != current->signal->session) | 3005 | if (session_of_pgrp(pgrp) != process_session(current)) |
2984 | return -EPERM; | 3006 | return -EPERM; |
2985 | real_tty->pgrp = pgrp; | 3007 | real_tty->pgrp = pgrp; |
2986 | return 0; | 3008 | return 0; |
@@ -2995,7 +3017,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2995 | * Obtain the session id of the tty. If there is no session | 3017 | * Obtain the session id of the tty. If there is no session |
2996 | * return an error. | 3018 | * return an error. |
2997 | * | 3019 | * |
2998 | * Locking: none. Reference to ->signal->tty is safe. | 3020 | * Locking: none. Reference to current->signal->tty is safe. |
2999 | */ | 3021 | */ |
3000 | 3022 | ||
3001 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 3023 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
@@ -3214,14 +3236,11 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3214 | clear_bit(TTY_EXCLUSIVE, &tty->flags); | 3236 | clear_bit(TTY_EXCLUSIVE, &tty->flags); |
3215 | return 0; | 3237 | return 0; |
3216 | case TIOCNOTTY: | 3238 | case TIOCNOTTY: |
3217 | /* FIXME: taks lock or tty_mutex ? */ | ||
3218 | if (current->signal->tty != tty) | 3239 | if (current->signal->tty != tty) |
3219 | return -ENOTTY; | 3240 | return -ENOTTY; |
3220 | if (current->signal->leader) | 3241 | if (current->signal->leader) |
3221 | disassociate_ctty(0); | 3242 | disassociate_ctty(0); |
3222 | task_lock(current); | 3243 | proc_clear_tty(current); |
3223 | current->signal->tty = NULL; | ||
3224 | task_unlock(current); | ||
3225 | return 0; | 3244 | return 0; |
3226 | case TIOCSCTTY: | 3245 | case TIOCSCTTY: |
3227 | return tiocsctty(tty, arg); | 3246 | return tiocsctty(tty, arg); |
@@ -3321,7 +3340,7 @@ static void __do_SAK(struct work_struct *work) | |||
3321 | 3340 | ||
3322 | if (!tty) | 3341 | if (!tty) |
3323 | return; | 3342 | return; |
3324 | session = tty->session; | 3343 | session = tty->session; |
3325 | 3344 | ||
3326 | /* We don't want an ldisc switch during this */ | 3345 | /* We don't want an ldisc switch during this */ |
3327 | disc = tty_ldisc_ref(tty); | 3346 | disc = tty_ldisc_ref(tty); |
@@ -3336,7 +3355,7 @@ static void __do_SAK(struct work_struct *work) | |||
3336 | /* Kill the entire session */ | 3355 | /* Kill the entire session */ |
3337 | do_each_task_pid(session, PIDTYPE_SID, p) { | 3356 | do_each_task_pid(session, PIDTYPE_SID, p) { |
3338 | printk(KERN_NOTICE "SAK: killed process %d" | 3357 | printk(KERN_NOTICE "SAK: killed process %d" |
3339 | " (%s): p->signal->session==tty->session\n", | 3358 | " (%s): process_session(p)==tty->session\n", |
3340 | p->pid, p->comm); | 3359 | p->pid, p->comm); |
3341 | send_sig(SIGKILL, p, 1); | 3360 | send_sig(SIGKILL, p, 1); |
3342 | } while_each_task_pid(session, PIDTYPE_SID, p); | 3361 | } while_each_task_pid(session, PIDTYPE_SID, p); |
@@ -3346,7 +3365,7 @@ static void __do_SAK(struct work_struct *work) | |||
3346 | do_each_thread(g, p) { | 3365 | do_each_thread(g, p) { |
3347 | if (p->signal->tty == tty) { | 3366 | if (p->signal->tty == tty) { |
3348 | printk(KERN_NOTICE "SAK: killed process %d" | 3367 | printk(KERN_NOTICE "SAK: killed process %d" |
3349 | " (%s): p->signal->session==tty->session\n", | 3368 | " (%s): process_session(p)==tty->session\n", |
3350 | p->pid, p->comm); | 3369 | p->pid, p->comm); |
3351 | send_sig(SIGKILL, p, 1); | 3370 | send_sig(SIGKILL, p, 1); |
3352 | continue; | 3371 | continue; |
@@ -3456,84 +3475,6 @@ static void flush_to_ldisc(struct work_struct *work) | |||
3456 | tty_ldisc_deref(disc); | 3475 | tty_ldisc_deref(disc); |
3457 | } | 3476 | } |
3458 | 3477 | ||
3459 | /* | ||
3460 | * Routine which returns the baud rate of the tty | ||
3461 | * | ||
3462 | * Note that the baud_table needs to be kept in sync with the | ||
3463 | * include/asm/termbits.h file. | ||
3464 | */ | ||
3465 | static int baud_table[] = { | ||
3466 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
3467 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, | ||
3468 | #ifdef __sparc__ | ||
3469 | 76800, 153600, 307200, 614400, 921600 | ||
3470 | #else | ||
3471 | 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, | ||
3472 | 2500000, 3000000, 3500000, 4000000 | ||
3473 | #endif | ||
3474 | }; | ||
3475 | |||
3476 | static int n_baud_table = ARRAY_SIZE(baud_table); | ||
3477 | |||
3478 | /** | ||
3479 | * tty_termios_baud_rate | ||
3480 | * @termios: termios structure | ||
3481 | * | ||
3482 | * Convert termios baud rate data into a speed. This should be called | ||
3483 | * with the termios lock held if this termios is a terminal termios | ||
3484 | * structure. May change the termios data. | ||
3485 | * | ||
3486 | * Locking: none | ||
3487 | */ | ||
3488 | |||
3489 | int tty_termios_baud_rate(struct termios *termios) | ||
3490 | { | ||
3491 | unsigned int cbaud; | ||
3492 | |||
3493 | cbaud = termios->c_cflag & CBAUD; | ||
3494 | |||
3495 | if (cbaud & CBAUDEX) { | ||
3496 | cbaud &= ~CBAUDEX; | ||
3497 | |||
3498 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | ||
3499 | termios->c_cflag &= ~CBAUDEX; | ||
3500 | else | ||
3501 | cbaud += 15; | ||
3502 | } | ||
3503 | return baud_table[cbaud]; | ||
3504 | } | ||
3505 | |||
3506 | EXPORT_SYMBOL(tty_termios_baud_rate); | ||
3507 | |||
3508 | /** | ||
3509 | * tty_get_baud_rate - get tty bit rates | ||
3510 | * @tty: tty to query | ||
3511 | * | ||
3512 | * Returns the baud rate as an integer for this terminal. The | ||
3513 | * termios lock must be held by the caller and the terminal bit | ||
3514 | * flags may be updated. | ||
3515 | * | ||
3516 | * Locking: none | ||
3517 | */ | ||
3518 | |||
3519 | int tty_get_baud_rate(struct tty_struct *tty) | ||
3520 | { | ||
3521 | int baud = tty_termios_baud_rate(tty->termios); | ||
3522 | |||
3523 | if (baud == 38400 && tty->alt_speed) { | ||
3524 | if (!tty->warned) { | ||
3525 | printk(KERN_WARNING "Use of setserial/setrocket to " | ||
3526 | "set SPD_* flags is deprecated\n"); | ||
3527 | tty->warned = 1; | ||
3528 | } | ||
3529 | baud = tty->alt_speed; | ||
3530 | } | ||
3531 | |||
3532 | return baud; | ||
3533 | } | ||
3534 | |||
3535 | EXPORT_SYMBOL(tty_get_baud_rate); | ||
3536 | |||
3537 | /** | 3478 | /** |
3538 | * tty_flip_buffer_push - terminal | 3479 | * tty_flip_buffer_push - terminal |
3539 | * @tty: tty to push | 3480 | * @tty: tty to push |
@@ -3756,8 +3697,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3756 | 3697 | ||
3757 | if (p) { | 3698 | if (p) { |
3758 | driver->ttys = (struct tty_struct **)p; | 3699 | driver->ttys = (struct tty_struct **)p; |
3759 | driver->termios = (struct termios **)(p + driver->num); | 3700 | driver->termios = (struct ktermios **)(p + driver->num); |
3760 | driver->termios_locked = (struct termios **)(p + driver->num * 2); | 3701 | driver->termios_locked = (struct ktermios **)(p + driver->num * 2); |
3761 | } else { | 3702 | } else { |
3762 | driver->ttys = NULL; | 3703 | driver->ttys = NULL; |
3763 | driver->termios = NULL; | 3704 | driver->termios = NULL; |
@@ -3796,7 +3737,7 @@ EXPORT_SYMBOL(tty_register_driver); | |||
3796 | int tty_unregister_driver(struct tty_driver *driver) | 3737 | int tty_unregister_driver(struct tty_driver *driver) |
3797 | { | 3738 | { |
3798 | int i; | 3739 | int i; |
3799 | struct termios *tp; | 3740 | struct ktermios *tp; |
3800 | void *p; | 3741 | void *p; |
3801 | 3742 | ||
3802 | if (driver->refcount) | 3743 | if (driver->refcount) |
@@ -3834,9 +3775,52 @@ int tty_unregister_driver(struct tty_driver *driver) | |||
3834 | cdev_del(&driver->cdev); | 3775 | cdev_del(&driver->cdev); |
3835 | return 0; | 3776 | return 0; |
3836 | } | 3777 | } |
3837 | |||
3838 | EXPORT_SYMBOL(tty_unregister_driver); | 3778 | EXPORT_SYMBOL(tty_unregister_driver); |
3839 | 3779 | ||
3780 | dev_t tty_devnum(struct tty_struct *tty) | ||
3781 | { | ||
3782 | return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; | ||
3783 | } | ||
3784 | EXPORT_SYMBOL(tty_devnum); | ||
3785 | |||
3786 | void proc_clear_tty(struct task_struct *p) | ||
3787 | { | ||
3788 | spin_lock_irq(&p->sighand->siglock); | ||
3789 | p->signal->tty = NULL; | ||
3790 | spin_unlock_irq(&p->sighand->siglock); | ||
3791 | } | ||
3792 | EXPORT_SYMBOL(proc_clear_tty); | ||
3793 | |||
3794 | void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | ||
3795 | { | ||
3796 | if (tty) { | ||
3797 | tty->session = process_session(tsk); | ||
3798 | tty->pgrp = process_group(tsk); | ||
3799 | } | ||
3800 | tsk->signal->tty = tty; | ||
3801 | tsk->signal->tty_old_pgrp = 0; | ||
3802 | } | ||
3803 | |||
3804 | void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | ||
3805 | { | ||
3806 | spin_lock_irq(&tsk->sighand->siglock); | ||
3807 | __proc_set_tty(tsk, tty); | ||
3808 | spin_unlock_irq(&tsk->sighand->siglock); | ||
3809 | } | ||
3810 | |||
3811 | struct tty_struct *get_current_tty(void) | ||
3812 | { | ||
3813 | struct tty_struct *tty; | ||
3814 | WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); | ||
3815 | tty = current->signal->tty; | ||
3816 | /* | ||
3817 | * session->tty can be changed/cleared from under us, make sure we | ||
3818 | * issue the load. The obtained pointer, when not NULL, is valid as | ||
3819 | * long as we hold tty_mutex. | ||
3820 | */ | ||
3821 | barrier(); | ||
3822 | return tty; | ||
3823 | } | ||
3840 | 3824 | ||
3841 | /* | 3825 | /* |
3842 | * Initialize the console device. This is called *early*, so | 3826 | * Initialize the console device. This is called *early*, so |
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 3b6fa7b0be8b..dee47f40c6a3 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #define TERMIOS_FLUSH 1 | 36 | #define TERMIOS_FLUSH 1 |
37 | #define TERMIOS_WAIT 2 | 37 | #define TERMIOS_WAIT 2 |
38 | #define TERMIOS_TERMIO 4 | 38 | #define TERMIOS_TERMIO 4 |
39 | #define TERMIOS_OLD 8 | ||
39 | 40 | ||
40 | 41 | ||
41 | /** | 42 | /** |
@@ -84,9 +85,9 @@ stop_waiting: | |||
84 | 85 | ||
85 | EXPORT_SYMBOL(tty_wait_until_sent); | 86 | EXPORT_SYMBOL(tty_wait_until_sent); |
86 | 87 | ||
87 | static void unset_locked_termios(struct termios *termios, | 88 | static void unset_locked_termios(struct ktermios *termios, |
88 | struct termios *old, | 89 | struct ktermios *old, |
89 | struct termios *locked) | 90 | struct ktermios *locked) |
90 | { | 91 | { |
91 | int i; | 92 | int i; |
92 | 93 | ||
@@ -105,8 +106,204 @@ static void unset_locked_termios(struct termios *termios, | |||
105 | for (i=0; i < NCCS; i++) | 106 | for (i=0; i < NCCS; i++) |
106 | termios->c_cc[i] = locked->c_cc[i] ? | 107 | termios->c_cc[i] = locked->c_cc[i] ? |
107 | old->c_cc[i] : termios->c_cc[i]; | 108 | old->c_cc[i] : termios->c_cc[i]; |
109 | /* FIXME: What should we do for i/ospeed */ | ||
108 | } | 110 | } |
109 | 111 | ||
112 | /* | ||
113 | * Routine which returns the baud rate of the tty | ||
114 | * | ||
115 | * Note that the baud_table needs to be kept in sync with the | ||
116 | * include/asm/termbits.h file. | ||
117 | */ | ||
118 | static const speed_t baud_table[] = { | ||
119 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
120 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, | ||
121 | #ifdef __sparc__ | ||
122 | 76800, 153600, 307200, 614400, 921600 | ||
123 | #else | ||
124 | 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, | ||
125 | 2500000, 3000000, 3500000, 4000000 | ||
126 | #endif | ||
127 | }; | ||
128 | |||
129 | #ifndef __sparc__ | ||
130 | static const tcflag_t baud_bits[] = { | ||
131 | B0, B50, B75, B110, B134, B150, B200, B300, B600, | ||
132 | B1200, B1800, B2400, B4800, B9600, B19200, B38400, | ||
133 | B57600, B115200, B230400, B460800, B500000, B576000, | ||
134 | B921600, B1000000, B1152000, B1500000, B2000000, B2500000, | ||
135 | B3000000, B3500000, B4000000 | ||
136 | }; | ||
137 | #else | ||
138 | static const tcflag_t baud_bits[] = { | ||
139 | B0, B50, B75, B110, B134, B150, B200, B300, B600, | ||
140 | B1200, B1800, B2400, B4800, B9600, B19200, B38400, | ||
141 | B57600, B115200, B230400, B460800, B76800, B153600, | ||
142 | B307200, B614400, B921600 | ||
143 | }; | ||
144 | #endif | ||
145 | |||
146 | static int n_baud_table = ARRAY_SIZE(baud_table); | ||
147 | |||
148 | /** | ||
149 | * tty_termios_baud_rate | ||
150 | * @termios: termios structure | ||
151 | * | ||
152 | * Convert termios baud rate data into a speed. This should be called | ||
153 | * with the termios lock held if this termios is a terminal termios | ||
154 | * structure. May change the termios data. Device drivers can call this | ||
155 | * function but should use ->c_[io]speed directly as they are updated. | ||
156 | * | ||
157 | * Locking: none | ||
158 | */ | ||
159 | |||
160 | speed_t tty_termios_baud_rate(struct ktermios *termios) | ||
161 | { | ||
162 | unsigned int cbaud; | ||
163 | |||
164 | cbaud = termios->c_cflag & CBAUD; | ||
165 | |||
166 | #ifdef BOTHER | ||
167 | /* Magic token for arbitary speed via c_ispeed/c_ospeed */ | ||
168 | if (cbaud == BOTHER) | ||
169 | return termios->c_ospeed; | ||
170 | #endif | ||
171 | if (cbaud & CBAUDEX) { | ||
172 | cbaud &= ~CBAUDEX; | ||
173 | |||
174 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | ||
175 | termios->c_cflag &= ~CBAUDEX; | ||
176 | else | ||
177 | cbaud += 15; | ||
178 | } | ||
179 | return baud_table[cbaud]; | ||
180 | } | ||
181 | |||
182 | EXPORT_SYMBOL(tty_termios_baud_rate); | ||
183 | |||
184 | /** | ||
185 | * tty_termios_input_baud_rate | ||
186 | * @termios: termios structure | ||
187 | * | ||
188 | * Convert termios baud rate data into a speed. This should be called | ||
189 | * with the termios lock held if this termios is a terminal termios | ||
190 | * structure. May change the termios data. Device drivers can call this | ||
191 | * function but should use ->c_[io]speed directly as they are updated. | ||
192 | * | ||
193 | * Locking: none | ||
194 | */ | ||
195 | |||
196 | speed_t tty_termios_input_baud_rate(struct ktermios *termios) | ||
197 | { | ||
198 | #ifdef IBSHIFT | ||
199 | unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD; | ||
200 | |||
201 | if (cbaud == B0) | ||
202 | return tty_termios_baud_rate(termios); | ||
203 | |||
204 | /* Magic token for arbitary speed via c_ispeed*/ | ||
205 | if (cbaud == BOTHER) | ||
206 | return termios->c_ispeed; | ||
207 | |||
208 | if (cbaud & CBAUDEX) { | ||
209 | cbaud &= ~CBAUDEX; | ||
210 | |||
211 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | ||
212 | termios->c_cflag &= ~(CBAUDEX << IBSHIFT); | ||
213 | else | ||
214 | cbaud += 15; | ||
215 | } | ||
216 | return baud_table[cbaud]; | ||
217 | #else | ||
218 | return tty_termios_baud_rate(termios); | ||
219 | #endif | ||
220 | } | ||
221 | |||
222 | EXPORT_SYMBOL(tty_termios_input_baud_rate); | ||
223 | |||
224 | #ifdef BOTHER | ||
225 | |||
226 | /** | ||
227 | * tty_termios_encode_baud_rate | ||
228 | * @termios: termios structure | ||
229 | * @ispeed: input speed | ||
230 | * @ospeed: output speed | ||
231 | * | ||
232 | * Encode the speeds set into the passed termios structure. This is | ||
233 | * used as a library helper for drivers os that they can report back | ||
234 | * the actual speed selected when it differs from the speed requested | ||
235 | * | ||
236 | * For now input and output speed must agree. | ||
237 | * | ||
238 | * Locking: Caller should hold termios lock. This is already held | ||
239 | * when calling this function from the driver termios handler. | ||
240 | */ | ||
241 | |||
242 | void tty_termios_encode_baud_rate(struct ktermios *termios, speed_t ibaud, speed_t obaud) | ||
243 | { | ||
244 | int i = 0; | ||
245 | int ifound = 0, ofound = 0; | ||
246 | |||
247 | termios->c_ispeed = ibaud; | ||
248 | termios->c_ospeed = obaud; | ||
249 | |||
250 | termios->c_cflag &= ~CBAUD; | ||
251 | /* Identical speed means no input encoding (ie B0 << IBSHIFT)*/ | ||
252 | if (termios->c_ispeed == termios->c_ospeed) | ||
253 | ifound = 1; | ||
254 | |||
255 | do { | ||
256 | if (obaud == baud_table[i]) { | ||
257 | termios->c_cflag |= baud_bits[i]; | ||
258 | ofound = 1; | ||
259 | /* So that if ibaud == obaud we don't set it */ | ||
260 | continue; | ||
261 | } | ||
262 | if (ibaud == baud_table[i]) { | ||
263 | termios->c_cflag |= (baud_bits[i] << IBSHIFT); | ||
264 | ifound = 1; | ||
265 | } | ||
266 | } | ||
267 | while(++i < n_baud_table); | ||
268 | if (!ofound) | ||
269 | termios->c_cflag |= BOTHER; | ||
270 | if (!ifound) | ||
271 | termios->c_cflag |= (BOTHER << IBSHIFT); | ||
272 | } | ||
273 | |||
274 | EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | ||
275 | |||
276 | #endif | ||
277 | |||
278 | /** | ||
279 | * tty_get_baud_rate - get tty bit rates | ||
280 | * @tty: tty to query | ||
281 | * | ||
282 | * Returns the baud rate as an integer for this terminal. The | ||
283 | * termios lock must be held by the caller and the terminal bit | ||
284 | * flags may be updated. | ||
285 | * | ||
286 | * Locking: none | ||
287 | */ | ||
288 | |||
289 | speed_t tty_get_baud_rate(struct tty_struct *tty) | ||
290 | { | ||
291 | speed_t baud = tty_termios_baud_rate(tty->termios); | ||
292 | |||
293 | if (baud == 38400 && tty->alt_speed) { | ||
294 | if (!tty->warned) { | ||
295 | printk(KERN_WARNING "Use of setserial/setrocket to " | ||
296 | "set SPD_* flags is deprecated\n"); | ||
297 | tty->warned = 1; | ||
298 | } | ||
299 | baud = tty->alt_speed; | ||
300 | } | ||
301 | |||
302 | return baud; | ||
303 | } | ||
304 | |||
305 | EXPORT_SYMBOL(tty_get_baud_rate); | ||
306 | |||
110 | /** | 307 | /** |
111 | * change_termios - update termios values | 308 | * change_termios - update termios values |
112 | * @tty: tty to update | 309 | * @tty: tty to update |
@@ -119,10 +316,10 @@ static void unset_locked_termios(struct termios *termios, | |||
119 | * Locking: termios_sem | 316 | * Locking: termios_sem |
120 | */ | 317 | */ |
121 | 318 | ||
122 | static void change_termios(struct tty_struct * tty, struct termios * new_termios) | 319 | static void change_termios(struct tty_struct * tty, struct ktermios * new_termios) |
123 | { | 320 | { |
124 | int canon_change; | 321 | int canon_change; |
125 | struct termios old_termios = *tty->termios; | 322 | struct ktermios old_termios = *tty->termios; |
126 | struct tty_ldisc *ld; | 323 | struct tty_ldisc *ld; |
127 | 324 | ||
128 | /* | 325 | /* |
@@ -195,23 +392,39 @@ static void change_termios(struct tty_struct * tty, struct termios * new_termios | |||
195 | 392 | ||
196 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) | 393 | static int set_termios(struct tty_struct * tty, void __user *arg, int opt) |
197 | { | 394 | { |
198 | struct termios tmp_termios; | 395 | struct ktermios tmp_termios; |
199 | struct tty_ldisc *ld; | 396 | struct tty_ldisc *ld; |
200 | int retval = tty_check_change(tty); | 397 | int retval = tty_check_change(tty); |
201 | 398 | ||
202 | if (retval) | 399 | if (retval) |
203 | return retval; | 400 | return retval; |
204 | 401 | ||
402 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); | ||
403 | |||
205 | if (opt & TERMIOS_TERMIO) { | 404 | if (opt & TERMIOS_TERMIO) { |
206 | memcpy(&tmp_termios, tty->termios, sizeof(struct termios)); | ||
207 | if (user_termio_to_kernel_termios(&tmp_termios, | 405 | if (user_termio_to_kernel_termios(&tmp_termios, |
208 | (struct termio __user *)arg)) | 406 | (struct termio __user *)arg)) |
209 | return -EFAULT; | 407 | return -EFAULT; |
408 | #ifdef TCGETS2 | ||
409 | } else if (opt & TERMIOS_OLD) { | ||
410 | if (user_termios_to_kernel_termios_1(&tmp_termios, | ||
411 | (struct termios __user *)arg)) | ||
412 | return -EFAULT; | ||
210 | } else { | 413 | } else { |
211 | if (user_termios_to_kernel_termios(&tmp_termios, | 414 | if (user_termios_to_kernel_termios(&tmp_termios, |
212 | (struct termios __user *)arg)) | 415 | (struct termios2 __user *)arg)) |
213 | return -EFAULT; | 416 | return -EFAULT; |
214 | } | 417 | } |
418 | #else | ||
419 | } else if (user_termios_to_kernel_termios(&tmp_termios, | ||
420 | (struct termios __user *)arg)) | ||
421 | return -EFAULT; | ||
422 | #endif | ||
423 | |||
424 | /* If old style Bfoo values are used then load c_ispeed/c_ospeed with the real speed | ||
425 | so its unconditionally usable */ | ||
426 | tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios); | ||
427 | tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios); | ||
215 | 428 | ||
216 | ld = tty_ldisc_ref(tty); | 429 | ld = tty_ldisc_ref(tty); |
217 | 430 | ||
@@ -286,8 +499,8 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) | |||
286 | struct sgttyb tmp; | 499 | struct sgttyb tmp; |
287 | 500 | ||
288 | mutex_lock(&tty->termios_mutex); | 501 | mutex_lock(&tty->termios_mutex); |
289 | tmp.sg_ispeed = 0; | 502 | tmp.sg_ispeed = tty->termios->c_ispeed; |
290 | tmp.sg_ospeed = 0; | 503 | tmp.sg_ospeed = tty->termios->c_ospeed; |
291 | tmp.sg_erase = tty->termios->c_cc[VERASE]; | 504 | tmp.sg_erase = tty->termios->c_cc[VERASE]; |
292 | tmp.sg_kill = tty->termios->c_cc[VKILL]; | 505 | tmp.sg_kill = tty->termios->c_cc[VKILL]; |
293 | tmp.sg_flags = get_sgflags(tty); | 506 | tmp.sg_flags = get_sgflags(tty); |
@@ -296,7 +509,7 @@ static int get_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) | |||
296 | return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 509 | return copy_to_user(sgttyb, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
297 | } | 510 | } |
298 | 511 | ||
299 | static void set_sgflags(struct termios * termios, int flags) | 512 | static void set_sgflags(struct ktermios * termios, int flags) |
300 | { | 513 | { |
301 | termios->c_iflag = ICRNL | IXON; | 514 | termios->c_iflag = ICRNL | IXON; |
302 | termios->c_oflag = 0; | 515 | termios->c_oflag = 0; |
@@ -337,7 +550,7 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) | |||
337 | { | 550 | { |
338 | int retval; | 551 | int retval; |
339 | struct sgttyb tmp; | 552 | struct sgttyb tmp; |
340 | struct termios termios; | 553 | struct ktermios termios; |
341 | 554 | ||
342 | retval = tty_check_change(tty); | 555 | retval = tty_check_change(tty); |
343 | if (retval) | 556 | if (retval) |
@@ -351,6 +564,10 @@ static int set_sgttyb(struct tty_struct * tty, struct sgttyb __user * sgttyb) | |||
351 | termios.c_cc[VERASE] = tmp.sg_erase; | 564 | termios.c_cc[VERASE] = tmp.sg_erase; |
352 | termios.c_cc[VKILL] = tmp.sg_kill; | 565 | termios.c_cc[VKILL] = tmp.sg_kill; |
353 | set_sgflags(&termios, tmp.sg_flags); | 566 | set_sgflags(&termios, tmp.sg_flags); |
567 | /* Try and encode into Bfoo format */ | ||
568 | #ifdef BOTHER | ||
569 | tty_termios_encode_baud_rate(&termios, termios.c_ispeed, termios.c_ospeed); | ||
570 | #endif | ||
354 | mutex_unlock(&tty->termios_mutex); | 571 | mutex_unlock(&tty->termios_mutex); |
355 | change_termios(tty, &termios); | 572 | change_termios(tty, &termios); |
356 | return 0; | 573 | return 0; |
@@ -481,16 +698,33 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, | |||
481 | case TIOCSLTC: | 698 | case TIOCSLTC: |
482 | return set_ltchars(real_tty, p); | 699 | return set_ltchars(real_tty, p); |
483 | #endif | 700 | #endif |
701 | case TCSETSF: | ||
702 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT | TERMIOS_OLD); | ||
703 | case TCSETSW: | ||
704 | return set_termios(real_tty, p, TERMIOS_WAIT | TERMIOS_OLD); | ||
705 | case TCSETS: | ||
706 | return set_termios(real_tty, p, TERMIOS_OLD); | ||
707 | #ifndef TCGETS2 | ||
484 | case TCGETS: | 708 | case TCGETS: |
485 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) | 709 | if (kernel_termios_to_user_termios((struct termios __user *)arg, real_tty->termios)) |
486 | return -EFAULT; | 710 | return -EFAULT; |
487 | return 0; | 711 | return 0; |
488 | case TCSETSF: | 712 | #else |
713 | case TCGETS: | ||
714 | if (kernel_termios_to_user_termios_1((struct termios __user *)arg, real_tty->termios)) | ||
715 | return -EFAULT; | ||
716 | return 0; | ||
717 | case TCGETS2: | ||
718 | if (kernel_termios_to_user_termios((struct termios2 __user *)arg, real_tty->termios)) | ||
719 | return -EFAULT; | ||
720 | return 0; | ||
721 | case TCSETSF2: | ||
489 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); | 722 | return set_termios(real_tty, p, TERMIOS_FLUSH | TERMIOS_WAIT); |
490 | case TCSETSW: | 723 | case TCSETSW2: |
491 | return set_termios(real_tty, p, TERMIOS_WAIT); | 724 | return set_termios(real_tty, p, TERMIOS_WAIT); |
492 | case TCSETS: | 725 | case TCSETS2: |
493 | return set_termios(real_tty, p, 0); | 726 | return set_termios(real_tty, p, 0); |
727 | #endif | ||
494 | case TCGETA: | 728 | case TCGETA: |
495 | return get_termio(real_tty, p); | 729 | return get_termio(real_tty, p); |
496 | case TCSETAF: | 730 | case TCSETAF: |
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c index f442b574b44a..26776517f04c 100644 --- a/drivers/char/vc_screen.c +++ b/drivers/char/vc_screen.c | |||
@@ -72,7 +72,7 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
72 | int size; | 72 | int size; |
73 | 73 | ||
74 | down(&con_buf_sem); | 74 | down(&con_buf_sem); |
75 | size = vcs_size(file->f_dentry->d_inode); | 75 | size = vcs_size(file->f_path.dentry->d_inode); |
76 | switch (orig) { | 76 | switch (orig) { |
77 | default: | 77 | default: |
78 | up(&con_buf_sem); | 78 | up(&con_buf_sem); |
@@ -98,7 +98,7 @@ static loff_t vcs_lseek(struct file *file, loff_t offset, int orig) | |||
98 | static ssize_t | 98 | static ssize_t |
99 | vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 99 | vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
100 | { | 100 | { |
101 | struct inode *inode = file->f_dentry->d_inode; | 101 | struct inode *inode = file->f_path.dentry->d_inode; |
102 | unsigned int currcons = iminor(inode); | 102 | unsigned int currcons = iminor(inode); |
103 | struct vc_data *vc; | 103 | struct vc_data *vc; |
104 | long pos; | 104 | long pos; |
@@ -271,7 +271,7 @@ unlock_out: | |||
271 | static ssize_t | 271 | static ssize_t |
272 | vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 272 | vcs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
273 | { | 273 | { |
274 | struct inode *inode = file->f_dentry->d_inode; | 274 | struct inode *inode = file->f_path.dentry->d_inode; |
275 | unsigned int currcons = iminor(inode); | 275 | unsigned int currcons = iminor(inode); |
276 | struct vc_data *vc; | 276 | struct vc_data *vc; |
277 | long pos; | 277 | long pos; |
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 73c78bf75d7f..94d79cb8ce8d 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c | |||
@@ -442,7 +442,7 @@ static ssize_t viotap_write(struct file *file, const char *buf, | |||
442 | if (op == NULL) | 442 | if (op == NULL) |
443 | return -ENOMEM; | 443 | return -ENOMEM; |
444 | 444 | ||
445 | get_dev_info(file->f_dentry->d_inode, &devi); | 445 | get_dev_info(file->f_path.dentry->d_inode, &devi); |
446 | 446 | ||
447 | /* | 447 | /* |
448 | * We need to make sure we can send a request. We use | 448 | * We need to make sure we can send a request. We use |
@@ -532,7 +532,7 @@ static ssize_t viotap_read(struct file *file, char *buf, size_t count, | |||
532 | if (op == NULL) | 532 | if (op == NULL) |
533 | return -ENOMEM; | 533 | return -ENOMEM; |
534 | 534 | ||
535 | get_dev_info(file->f_dentry->d_inode, &devi); | 535 | get_dev_info(file->f_path.dentry->d_inode, &devi); |
536 | 536 | ||
537 | /* | 537 | /* |
538 | * We need to make sure we can send a request. We use | 538 | * We need to make sure we can send a request. We use |
@@ -612,7 +612,7 @@ static int viotap_ioctl(struct inode *inode, struct file *file, | |||
612 | if (op == NULL) | 612 | if (op == NULL) |
613 | return -ENOMEM; | 613 | return -ENOMEM; |
614 | 614 | ||
615 | get_dev_info(file->f_dentry->d_inode, &devi); | 615 | get_dev_info(file->f_path.dentry->d_inode, &devi); |
616 | 616 | ||
617 | down(&reqSem); | 617 | down(&reqSem); |
618 | 618 | ||
@@ -777,7 +777,7 @@ static int viotap_open(struct inode *inode, struct file *file) | |||
777 | if (op == NULL) | 777 | if (op == NULL) |
778 | return -ENOMEM; | 778 | return -ENOMEM; |
779 | 779 | ||
780 | get_dev_info(file->f_dentry->d_inode, &devi); | 780 | get_dev_info(file->f_path.dentry->d_inode, &devi); |
781 | 781 | ||
782 | /* Note: We currently only support one mode! */ | 782 | /* Note: We currently only support one mode! */ |
783 | if ((devi.devno >= viotape_numdev) || (devi.mode)) { | 783 | if ((devi.devno >= viotape_numdev) || (devi.mode)) { |
@@ -822,7 +822,7 @@ static int viotap_release(struct inode *inode, struct file *file) | |||
822 | return -ENOMEM; | 822 | return -ENOMEM; |
823 | init_completion(&op->com); | 823 | init_completion(&op->com); |
824 | 824 | ||
825 | get_dev_info(file->f_dentry->d_inode, &devi); | 825 | get_dev_info(file->f_path.dentry->d_inode, &devi); |
826 | 826 | ||
827 | if (devi.devno >= viotape_numdev) { | 827 | if (devi.devno >= viotape_numdev) { |
828 | ret = -ENODEV; | 828 | ret = -ENODEV; |
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c index d0b94dd1af6d..e01317cb1a0e 100644 --- a/drivers/char/vme_scc.c +++ b/drivers/char/vme_scc.c | |||
@@ -153,6 +153,8 @@ static int scc_init_drivers(void) | |||
153 | scc_driver->init_termios = tty_std_termios; | 153 | scc_driver->init_termios = tty_std_termios; |
154 | scc_driver->init_termios.c_cflag = | 154 | scc_driver->init_termios.c_cflag = |
155 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 155 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
156 | scc_driver->init_termios.c_ispeed = 9600; | ||
157 | scc_driver->init_termios.c_ospeed = 9600; | ||
156 | scc_driver->flags = TTY_DRIVER_REAL_RAW; | 158 | scc_driver->flags = TTY_DRIVER_REAL_RAW; |
157 | tty_set_operations(scc_driver, &scc_ops); | 159 | tty_set_operations(scc_driver, &scc_ops); |
158 | 160 | ||
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c index 8e7949305171..a744dad9cf45 100644 --- a/drivers/char/vr41xx_giu.c +++ b/drivers/char/vr41xx_giu.c | |||
@@ -506,7 +506,7 @@ static ssize_t gpio_read(struct file *file, char __user *buf, size_t len, | |||
506 | unsigned int pin; | 506 | unsigned int pin; |
507 | char value = '0'; | 507 | char value = '0'; |
508 | 508 | ||
509 | pin = iminor(file->f_dentry->d_inode); | 509 | pin = iminor(file->f_path.dentry->d_inode); |
510 | if (pin >= giu_nr_pins) | 510 | if (pin >= giu_nr_pins) |
511 | return -EBADF; | 511 | return -EBADF; |
512 | 512 | ||
@@ -530,7 +530,7 @@ static ssize_t gpio_write(struct file *file, const char __user *data, | |||
530 | char c; | 530 | char c; |
531 | int retval = 0; | 531 | int retval = 0; |
532 | 532 | ||
533 | pin = iminor(file->f_dentry->d_inode); | 533 | pin = iminor(file->f_path.dentry->d_inode); |
534 | if (pin >= giu_nr_pins) | 534 | if (pin >= giu_nr_pins) |
535 | return -EBADF; | 535 | return -EBADF; |
536 | 536 | ||
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 75ff0286e1ad..a8239dac994f 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -152,7 +152,7 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y); | |||
152 | static void save_cur(struct vc_data *vc); | 152 | static void save_cur(struct vc_data *vc); |
153 | static void reset_terminal(struct vc_data *vc, int do_clear); | 153 | static void reset_terminal(struct vc_data *vc, int do_clear); |
154 | static void con_flush_chars(struct tty_struct *tty); | 154 | static void con_flush_chars(struct tty_struct *tty); |
155 | static void set_vesa_blanking(char __user *p); | 155 | static int set_vesa_blanking(char __user *p); |
156 | static void set_cursor(struct vc_data *vc); | 156 | static void set_cursor(struct vc_data *vc); |
157 | static void hide_cursor(struct vc_data *vc); | 157 | static void hide_cursor(struct vc_data *vc); |
158 | static void console_callback(struct work_struct *ignored); | 158 | static void console_callback(struct work_struct *ignored); |
@@ -2369,7 +2369,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2369 | ret = __put_user(data, p); | 2369 | ret = __put_user(data, p); |
2370 | break; | 2370 | break; |
2371 | case TIOCL_SETVESABLANK: | 2371 | case TIOCL_SETVESABLANK: |
2372 | set_vesa_blanking(p); | 2372 | ret = set_vesa_blanking(p); |
2373 | break; | 2373 | break; |
2374 | case TIOCL_GETKMSGREDIRECT: | 2374 | case TIOCL_GETKMSGREDIRECT: |
2375 | data = kmsg_redirect; | 2375 | data = kmsg_redirect; |
@@ -3313,11 +3313,15 @@ postcore_initcall(vtconsole_class_init); | |||
3313 | * Screen blanking | 3313 | * Screen blanking |
3314 | */ | 3314 | */ |
3315 | 3315 | ||
3316 | static void set_vesa_blanking(char __user *p) | 3316 | static int set_vesa_blanking(char __user *p) |
3317 | { | 3317 | { |
3318 | unsigned int mode; | 3318 | unsigned int mode; |
3319 | get_user(mode, p + 1); | 3319 | |
3320 | vesa_blank_mode = (mode < 4) ? mode : 0; | 3320 | if (get_user(mode, p + 1)) |
3321 | return -EFAULT; | ||
3322 | |||
3323 | vesa_blank_mode = (mode < 4) ? mode : 0; | ||
3324 | return 0; | ||
3321 | } | 3325 | } |
3322 | 3326 | ||
3323 | void do_blank_screen(int entering_gfx) | 3327 | void do_blank_screen(int entering_gfx) |
diff --git a/drivers/char/watchdog/at91rm9200_wdt.c b/drivers/char/watchdog/at91rm9200_wdt.c index 4e7a1145e78f..cb86967e2c5f 100644 --- a/drivers/char/watchdog/at91rm9200_wdt.c +++ b/drivers/char/watchdog/at91rm9200_wdt.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/watchdog.h> | 21 | #include <linux/watchdog.h> |
22 | #include <asm/bitops.h> | 22 | #include <asm/bitops.h> |
23 | #include <asm/uaccess.h> | 23 | #include <asm/uaccess.h> |
24 | #include <asm/arch/at91_st.h> | ||
24 | 25 | ||
25 | 26 | ||
26 | #define WDT_DEFAULT_TIME 5 /* seconds */ | 27 | #define WDT_DEFAULT_TIME 5 /* seconds */ |
diff --git a/drivers/char/watchdog/pcwd_usb.c b/drivers/char/watchdog/pcwd_usb.c index e275dd4a705d..61138726b501 100644 --- a/drivers/char/watchdog/pcwd_usb.c +++ b/drivers/char/watchdog/pcwd_usb.c | |||
@@ -634,7 +634,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, const struct usb_devi | |||
634 | usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); | 634 | usb_pcwd->intr_size = (le16_to_cpu(endpoint->wMaxPacketSize) > 8 ? le16_to_cpu(endpoint->wMaxPacketSize) : 8); |
635 | 635 | ||
636 | /* set up the memory buffer's */ | 636 | /* set up the memory buffer's */ |
637 | if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, SLAB_ATOMIC, &usb_pcwd->intr_dma))) { | 637 | if (!(usb_pcwd->intr_buffer = usb_buffer_alloc(udev, usb_pcwd->intr_size, GFP_ATOMIC, &usb_pcwd->intr_dma))) { |
638 | printk(KERN_ERR PFX "Out of memory\n"); | 638 | printk(KERN_ERR PFX "Out of memory\n"); |
639 | goto error; | 639 | goto error; |
640 | } | 640 | } |