diff options
-rw-r--r-- | drivers/parport/parport_serial.c | 66 | ||||
-rw-r--r-- | drivers/tty/serial/8250_pci.c | 104 | ||||
-rw-r--r-- | include/linux/pci_ids.h | 4 |
3 files changed, 157 insertions, 17 deletions
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index f01e26440f1..342a3de6c67 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -33,6 +33,9 @@ enum parport_pc_pci_cards { | |||
33 | netmos_9xx5_combo, | 33 | netmos_9xx5_combo, |
34 | netmos_9855, | 34 | netmos_9855, |
35 | netmos_9855_2p, | 35 | netmos_9855_2p, |
36 | netmos_9900, | ||
37 | netmos_9900_2p, | ||
38 | netmos_99xx_1p, | ||
36 | avlab_1s1p, | 39 | avlab_1s1p, |
37 | avlab_1s2p, | 40 | avlab_1s2p, |
38 | avlab_2s1p, | 41 | avlab_2s1p, |
@@ -72,22 +75,20 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc | |||
72 | dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 75 | dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
73 | dev->subsystem_device == 0x0299) | 76 | dev->subsystem_device == 0x0299) |
74 | return -ENODEV; | 77 | return -ENODEV; |
75 | /* | 78 | |
76 | * Netmos uses the subdevice ID to indicate the number of parallel | 79 | if (dev->device == PCI_DEVICE_ID_NETMOS_9912) { |
77 | * and serial ports. The form is 0x00PS, where <P> is the number of | 80 | par->numports = 1; |
78 | * parallel ports and <S> is the number of serial ports. | 81 | } else { |
79 | */ | 82 | /* |
80 | par->numports = (dev->subsystem_device & 0xf0) >> 4; | 83 | * Netmos uses the subdevice ID to indicate the number of parallel |
81 | if (par->numports > ARRAY_SIZE(par->addr)) | 84 | * and serial ports. The form is 0x00PS, where <P> is the number of |
82 | par->numports = ARRAY_SIZE(par->addr); | 85 | * parallel ports and <S> is the number of serial ports. |
83 | /* | 86 | */ |
84 | * This function is currently only called for cards with up to | 87 | par->numports = (dev->subsystem_device & 0xf0) >> 4; |
85 | * one parallel port. | 88 | if (par->numports > ARRAY_SIZE(par->addr)) |
86 | * Parallel port BAR is either before or after serial ports BARS; | 89 | par->numports = ARRAY_SIZE(par->addr); |
87 | * hence, lo should be either 0 or equal to the number of serial ports. | 90 | } |
88 | */ | 91 | |
89 | if (par->addr[0].lo != 0) | ||
90 | par->addr[0].lo = dev->subsystem_device & 0xf; | ||
91 | return 0; | 92 | return 0; |
92 | } | 93 | } |
93 | 94 | ||
@@ -97,6 +98,9 @@ static struct parport_pc_pci cards[] __devinitdata = { | |||
97 | /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, | 98 | /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, |
98 | /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, | 99 | /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, |
99 | /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } }, | 100 | /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } }, |
101 | /* netmos_9900 */ {1, { { 3, 4 }, }, netmos_parallel_init }, | ||
102 | /* netmos_9900_2p */ {2, { { 0, 1 }, { 3, 4 }, } }, | ||
103 | /* netmos_99xx_1p */ {1, { { 0, 1 }, } }, | ||
100 | /* avlab_1s1p */ { 1, { { 1, 2}, } }, | 104 | /* avlab_1s1p */ { 1, { { 1, 2}, } }, |
101 | /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, | 105 | /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, |
102 | /* avlab_2s1p */ { 1, { { 2, 3}, } }, | 106 | /* avlab_2s1p */ { 1, { { 2, 3}, } }, |
@@ -127,6 +131,14 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
127 | 0x1000, 0x0022, 0, 0, netmos_9855_2p }, | 131 | 0x1000, 0x0022, 0, 0, netmos_9855_2p }, |
128 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, | 132 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, |
129 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, | 133 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, |
134 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | ||
135 | 0xA000, 0x3011, 0, 0, netmos_9900 }, | ||
136 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | ||
137 | 0xA000, 0x3012, 0, 0, netmos_9900 }, | ||
138 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | ||
139 | 0xA000, 0x3020, 0, 0, netmos_9900_2p }, | ||
140 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912, | ||
141 | 0xA000, 0x2000, 0, 0, netmos_99xx_1p }, | ||
130 | /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ | 142 | /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ |
131 | { PCI_VENDOR_ID_AFAVLAB, 0x2110, | 143 | { PCI_VENDOR_ID_AFAVLAB, 0x2110, |
132 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, | 144 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, |
@@ -219,6 +231,24 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { | |||
219 | .base_baud = 115200, | 231 | .base_baud = 115200, |
220 | .uart_offset = 8, | 232 | .uart_offset = 8, |
221 | }, | 233 | }, |
234 | [netmos_9900] = { /* n/t */ | ||
235 | .flags = FL_BASE0 | FL_BASE_BARS, | ||
236 | .num_ports = 1, | ||
237 | .base_baud = 115200, | ||
238 | .uart_offset = 8, | ||
239 | }, | ||
240 | [netmos_9900_2p] = { /* parallel only */ /* n/t */ | ||
241 | .flags = FL_BASE0, | ||
242 | .num_ports = 0, | ||
243 | .base_baud = 115200, | ||
244 | .uart_offset = 8, | ||
245 | }, | ||
246 | [netmos_99xx_1p] = { /* parallel only */ /* n/t */ | ||
247 | .flags = FL_BASE0, | ||
248 | .num_ports = 0, | ||
249 | .base_baud = 115200, | ||
250 | .uart_offset = 8, | ||
251 | }, | ||
222 | [avlab_1s1p] = { /* n/t */ | 252 | [avlab_1s1p] = { /* n/t */ |
223 | .flags = FL_BASE0 | FL_BASE_BARS, | 253 | .flags = FL_BASE0 | FL_BASE_BARS, |
224 | .num_ports = 1, | 254 | .num_ports = 1, |
@@ -285,6 +315,10 @@ static int __devinit serial_register (struct pci_dev *dev, | |||
285 | struct serial_private *serial; | 315 | struct serial_private *serial; |
286 | 316 | ||
287 | board = &pci_parport_serial_boards[id->driver_data]; | 317 | board = &pci_parport_serial_boards[id->driver_data]; |
318 | |||
319 | if (board->num_ports == 0) | ||
320 | return 0; | ||
321 | |||
288 | serial = pciserial_init_ports(dev, board); | 322 | serial = pciserial_init_ports(dev, board); |
289 | 323 | ||
290 | if (IS_ERR(serial)) | 324 | if (IS_ERR(serial)) |
diff --git a/drivers/tty/serial/8250_pci.c b/drivers/tty/serial/8250_pci.c index 4b4968a294b..0b255cef57e 100644 --- a/drivers/tty/serial/8250_pci.c +++ b/drivers/tty/serial/8250_pci.c | |||
@@ -56,6 +56,9 @@ struct serial_private { | |||
56 | int line[0]; | 56 | int line[0]; |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static int pci_default_setup(struct serial_private*, | ||
60 | const struct pciserial_board*, struct uart_port*, int); | ||
61 | |||
59 | static void moan_device(const char *str, struct pci_dev *dev) | 62 | static void moan_device(const char *str, struct pci_dev *dev) |
60 | { | 63 | { |
61 | printk(KERN_WARNING | 64 | printk(KERN_WARNING |
@@ -752,6 +755,62 @@ pci_ni8430_setup(struct serial_private *priv, | |||
752 | return setup_port(priv, port, bar, offset, board->reg_shift); | 755 | return setup_port(priv, port, bar, offset, board->reg_shift); |
753 | } | 756 | } |
754 | 757 | ||
758 | static int pci_netmos_9900_setup(struct serial_private *priv, | ||
759 | const struct pciserial_board *board, | ||
760 | struct uart_port *port, int idx) | ||
761 | { | ||
762 | unsigned int bar; | ||
763 | |||
764 | if ((priv->dev->subsystem_device & 0xff00) == 0x3000) { | ||
765 | /* netmos apparently orders BARs by datasheet layout, so serial | ||
766 | * ports get BARs 0 and 3 (or 1 and 4 for memmapped) | ||
767 | */ | ||
768 | bar = 3 * idx; | ||
769 | |||
770 | return setup_port(priv, port, bar, 0, board->reg_shift); | ||
771 | } else { | ||
772 | return pci_default_setup(priv, board, port, idx); | ||
773 | } | ||
774 | } | ||
775 | |||
776 | /* the 99xx series comes with a range of device IDs and a variety | ||
777 | * of capabilities: | ||
778 | * | ||
779 | * 9900 has varying capabilities and can cascade to sub-controllers | ||
780 | * (cascading should be purely internal) | ||
781 | * 9904 is hardwired with 4 serial ports | ||
782 | * 9912 and 9922 are hardwired with 2 serial ports | ||
783 | */ | ||
784 | static int pci_netmos_9900_numports(struct pci_dev *dev) | ||
785 | { | ||
786 | unsigned int c = dev->class; | ||
787 | unsigned int pi; | ||
788 | unsigned short sub_serports; | ||
789 | |||
790 | pi = (c & 0xff); | ||
791 | |||
792 | if (pi == 2) { | ||
793 | return 1; | ||
794 | } else if ((pi == 0) && | ||
795 | (dev->device == PCI_DEVICE_ID_NETMOS_9900)) { | ||
796 | /* two possibilities: 0x30ps encodes number of parallel and | ||
797 | * serial ports, or 0x1000 indicates *something*. This is not | ||
798 | * immediately obvious, since the 2s1p+4s configuration seems | ||
799 | * to offer all functionality on functions 0..2, while still | ||
800 | * advertising the same function 3 as the 4s+2s1p config. | ||
801 | */ | ||
802 | sub_serports = dev->subsystem_device & 0xf; | ||
803 | if (sub_serports > 0) { | ||
804 | return sub_serports; | ||
805 | } else { | ||
806 | printk(KERN_NOTICE "NetMos/Mostech serial driver ignoring port on ambiguous config.\n"); | ||
807 | return 0; | ||
808 | } | ||
809 | } | ||
810 | |||
811 | moan_device("unknown NetMos/Mostech program interface", dev); | ||
812 | return 0; | ||
813 | } | ||
755 | 814 | ||
756 | static int pci_netmos_init(struct pci_dev *dev) | 815 | static int pci_netmos_init(struct pci_dev *dev) |
757 | { | 816 | { |
@@ -761,12 +820,28 @@ static int pci_netmos_init(struct pci_dev *dev) | |||
761 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || | 820 | if ((dev->device == PCI_DEVICE_ID_NETMOS_9901) || |
762 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) | 821 | (dev->device == PCI_DEVICE_ID_NETMOS_9865)) |
763 | return 0; | 822 | return 0; |
823 | |||
764 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && | 824 | if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && |
765 | dev->subsystem_device == 0x0299) | 825 | dev->subsystem_device == 0x0299) |
766 | return 0; | 826 | return 0; |
767 | 827 | ||
828 | switch (dev->device) { /* FALLTHROUGH on all */ | ||
829 | case PCI_DEVICE_ID_NETMOS_9904: | ||
830 | case PCI_DEVICE_ID_NETMOS_9912: | ||
831 | case PCI_DEVICE_ID_NETMOS_9922: | ||
832 | case PCI_DEVICE_ID_NETMOS_9900: | ||
833 | num_serial = pci_netmos_9900_numports(dev); | ||
834 | break; | ||
835 | |||
836 | default: | ||
837 | if (num_serial == 0 ) { | ||
838 | moan_device("unknown NetMos/Mostech device", dev); | ||
839 | } | ||
840 | } | ||
841 | |||
768 | if (num_serial == 0) | 842 | if (num_serial == 0) |
769 | return -ENODEV; | 843 | return -ENODEV; |
844 | |||
770 | return num_serial; | 845 | return num_serial; |
771 | } | 846 | } |
772 | 847 | ||
@@ -1417,7 +1492,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1417 | .subvendor = PCI_ANY_ID, | 1492 | .subvendor = PCI_ANY_ID, |
1418 | .subdevice = PCI_ANY_ID, | 1493 | .subdevice = PCI_ANY_ID, |
1419 | .init = pci_netmos_init, | 1494 | .init = pci_netmos_init, |
1420 | .setup = pci_default_setup, | 1495 | .setup = pci_netmos_9900_setup, |
1421 | }, | 1496 | }, |
1422 | /* | 1497 | /* |
1423 | * For Oxford Semiconductor Tornado based devices | 1498 | * For Oxford Semiconductor Tornado based devices |
@@ -1644,6 +1719,7 @@ enum pci_board_num_t { | |||
1644 | pbn_ADDIDATA_PCIe_8_3906250, | 1719 | pbn_ADDIDATA_PCIe_8_3906250, |
1645 | pbn_ce4100_1_115200, | 1720 | pbn_ce4100_1_115200, |
1646 | pbn_omegapci, | 1721 | pbn_omegapci, |
1722 | pbn_NETMOS9900_2s_115200, | ||
1647 | }; | 1723 | }; |
1648 | 1724 | ||
1649 | /* | 1725 | /* |
@@ -2345,6 +2421,11 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2345 | .base_baud = 115200, | 2421 | .base_baud = 115200, |
2346 | .uart_offset = 0x200, | 2422 | .uart_offset = 0x200, |
2347 | }, | 2423 | }, |
2424 | [pbn_NETMOS9900_2s_115200] = { | ||
2425 | .flags = FL_BASE0, | ||
2426 | .num_ports = 2, | ||
2427 | .base_baud = 115200, | ||
2428 | }, | ||
2348 | }; | 2429 | }; |
2349 | 2430 | ||
2350 | static const struct pci_device_id softmodem_blacklist[] = { | 2431 | static const struct pci_device_id softmodem_blacklist[] = { |
@@ -3826,6 +3907,27 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3826 | 0xA000, 0x1000, | 3907 | 0xA000, 0x1000, |
3827 | 0, 0, pbn_b0_1_115200 }, | 3908 | 0, 0, pbn_b0_1_115200 }, |
3828 | 3909 | ||
3910 | /* the 9901 is a rebranded 9912 */ | ||
3911 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912, | ||
3912 | 0xA000, 0x1000, | ||
3913 | 0, 0, pbn_b0_1_115200 }, | ||
3914 | |||
3915 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9922, | ||
3916 | 0xA000, 0x1000, | ||
3917 | 0, 0, pbn_b0_1_115200 }, | ||
3918 | |||
3919 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9904, | ||
3920 | 0xA000, 0x1000, | ||
3921 | 0, 0, pbn_b0_1_115200 }, | ||
3922 | |||
3923 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | ||
3924 | 0xA000, 0x1000, | ||
3925 | 0, 0, pbn_b0_1_115200 }, | ||
3926 | |||
3927 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, | ||
3928 | 0xA000, 0x3002, | ||
3929 | 0, 0, pbn_NETMOS9900_2s_115200 }, | ||
3930 | |||
3829 | /* | 3931 | /* |
3830 | * Best Connectivity PCI Multi I/O cards | 3932 | * Best Connectivity PCI Multi I/O cards |
3831 | */ | 3933 | */ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index a311008af5e..034ebb4451c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2821,7 +2821,11 @@ | |||
2821 | #define PCI_DEVICE_ID_NETMOS_9845 0x9845 | 2821 | #define PCI_DEVICE_ID_NETMOS_9845 0x9845 |
2822 | #define PCI_DEVICE_ID_NETMOS_9855 0x9855 | 2822 | #define PCI_DEVICE_ID_NETMOS_9855 0x9855 |
2823 | #define PCI_DEVICE_ID_NETMOS_9865 0x9865 | 2823 | #define PCI_DEVICE_ID_NETMOS_9865 0x9865 |
2824 | #define PCI_DEVICE_ID_NETMOS_9900 0x9900 | ||
2824 | #define PCI_DEVICE_ID_NETMOS_9901 0x9901 | 2825 | #define PCI_DEVICE_ID_NETMOS_9901 0x9901 |
2826 | #define PCI_DEVICE_ID_NETMOS_9904 0x9904 | ||
2827 | #define PCI_DEVICE_ID_NETMOS_9912 0x9912 | ||
2828 | #define PCI_DEVICE_ID_NETMOS_9922 0x9922 | ||
2825 | 2829 | ||
2826 | #define PCI_VENDOR_ID_3COM_2 0xa727 | 2830 | #define PCI_VENDOR_ID_3COM_2 0xa727 |
2827 | 2831 | ||