| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | *  linux/drivers/char/8250_pnp.c | 
|  | 3 | * | 
|  | 4 | *  Probe module for 8250/16550-type ISAPNP serial ports. | 
|  | 5 | * | 
|  | 6 | *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. | 
|  | 7 | * | 
|  | 8 | *  Copyright (C) 2001 Russell King, All Rights Reserved. | 
|  | 9 | * | 
|  | 10 | *  Ported to the Linux PnP Layer - (C) Adam Belay. | 
|  | 11 | * | 
|  | 12 | * This program is free software; you can redistribute it and/or modify | 
|  | 13 | * it under the terms of the GNU General Public License as published by | 
|  | 14 | * the Free Software Foundation; either version 2 of the License. | 
|  | 15 | * | 
|  | 16 | *  $Id: 8250_pnp.c,v 1.10 2002/07/21 21:32:30 rmk Exp $ | 
|  | 17 | */ | 
|  | 18 | #include <linux/module.h> | 
|  | 19 | #include <linux/init.h> | 
|  | 20 | #include <linux/pci.h> | 
|  | 21 | #include <linux/pnp.h> | 
|  | 22 | #include <linux/string.h> | 
|  | 23 | #include <linux/kernel.h> | 
|  | 24 | #include <linux/serial_core.h> | 
|  | 25 | #include <linux/bitops.h> | 
|  | 26 |  | 
|  | 27 | #include <asm/byteorder.h> | 
|  | 28 |  | 
|  | 29 | #include "8250.h" | 
|  | 30 |  | 
|  | 31 | #define UNKNOWN_DEV 0x3000 | 
|  | 32 |  | 
|  | 33 |  | 
|  | 34 | static const struct pnp_device_id pnp_dev_table[] = { | 
|  | 35 | /* Archtek America Corp. */ | 
|  | 36 | /* Archtek SmartLink Modem 3334BT Plug & Play */ | 
|  | 37 | {	"AAC000F",		0	}, | 
|  | 38 | /* Anchor Datacomm BV */ | 
|  | 39 | /* SXPro 144 External Data Fax Modem Plug & Play */ | 
|  | 40 | {	"ADC0001",		0	}, | 
|  | 41 | /* SXPro 288 External Data Fax Modem Plug & Play */ | 
|  | 42 | {	"ADC0002",		0	}, | 
|  | 43 | /* PROLiNK 1456VH ISA PnP K56flex Fax Modem */ | 
|  | 44 | {	"AEI0250",		0	}, | 
|  | 45 | /* Actiontec ISA PNP 56K X2 Fax Modem */ | 
|  | 46 | {	"AEI1240",		0	}, | 
|  | 47 | /* Rockwell 56K ACF II Fax+Data+Voice Modem */ | 
|  | 48 | {	"AKY1021",		0 /*SPCI_FL_NO_SHIRQ*/	}, | 
|  | 49 | /* AZT3005 PnP SOUND DEVICE */ | 
|  | 50 | {	"AZT4001",		0	}, | 
|  | 51 | /* Best Data Products Inc. Smart One 336F PnP Modem */ | 
|  | 52 | {	"BDP3336",		0	}, | 
|  | 53 | /*  Boca Research */ | 
|  | 54 | /* Boca Complete Ofc Communicator 14.4 Data-FAX */ | 
|  | 55 | {	"BRI0A49",		0	}, | 
|  | 56 | /* Boca Research 33,600 ACF Modem */ | 
|  | 57 | {	"BRI1400",		0	}, | 
|  | 58 | /* Boca 33.6 Kbps Internal FD34FSVD */ | 
|  | 59 | {	"BRI3400",		0	}, | 
|  | 60 | /* Boca 33.6 Kbps Internal FD34FSVD */ | 
|  | 61 | {	"BRI0A49",		0	}, | 
|  | 62 | /* Best Data Products Inc. Smart One 336F PnP Modem */ | 
|  | 63 | {	"BDP3336",		0	}, | 
|  | 64 | /* Computer Peripherals Inc */ | 
|  | 65 | /* EuroViVa CommCenter-33.6 SP PnP */ | 
|  | 66 | {	"CPI4050",		0	}, | 
|  | 67 | /* Creative Labs */ | 
|  | 68 | /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */ | 
|  | 69 | {	"CTL3001",		0	}, | 
|  | 70 | /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */ | 
|  | 71 | {	"CTL3011",		0	}, | 
|  | 72 | /* Creative */ | 
|  | 73 | /* Creative Modem Blaster Flash56 DI5601-1 */ | 
|  | 74 | {	"DMB1032",		0	}, | 
|  | 75 | /* Creative Modem Blaster V.90 DI5660 */ | 
|  | 76 | {	"DMB2001",		0	}, | 
|  | 77 | /* E-Tech */ | 
|  | 78 | /* E-Tech CyberBULLET PC56RVP */ | 
|  | 79 | {	"ETT0002",		0	}, | 
|  | 80 | /* FUJITSU */ | 
|  | 81 | /* Fujitsu 33600 PnP-I2 R Plug & Play */ | 
|  | 82 | {	"FUJ0202",		0	}, | 
|  | 83 | /* Fujitsu FMV-FX431 Plug & Play */ | 
|  | 84 | {	"FUJ0205",		0	}, | 
|  | 85 | /* Fujitsu 33600 PnP-I4 R Plug & Play */ | 
|  | 86 | {	"FUJ0206",		0	}, | 
|  | 87 | /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */ | 
|  | 88 | {	"FUJ0209",		0	}, | 
|  | 89 | /* Archtek America Corp. */ | 
|  | 90 | /* Archtek SmartLink Modem 3334BT Plug & Play */ | 
|  | 91 | {	"GVC000F",		0	}, | 
|  | 92 | /* Hayes */ | 
|  | 93 | /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */ | 
|  | 94 | {	"HAY0001",		0	}, | 
|  | 95 | /* Hayes Optima 336 V.34 + FAX + Voice PnP */ | 
|  | 96 | {	"HAY000C",		0	}, | 
|  | 97 | /* Hayes Optima 336B V.34 + FAX + Voice PnP */ | 
|  | 98 | {	"HAY000D",		0	}, | 
|  | 99 | /* Hayes Accura 56K Ext Fax Modem PnP */ | 
|  | 100 | {	"HAY5670",		0	}, | 
|  | 101 | /* Hayes Accura 56K Ext Fax Modem PnP */ | 
|  | 102 | {	"HAY5674",		0	}, | 
|  | 103 | /* Hayes Accura 56K Fax Modem PnP */ | 
|  | 104 | {	"HAY5675",		0	}, | 
|  | 105 | /* Hayes 288, V.34 + FAX */ | 
|  | 106 | {	"HAYF000",		0	}, | 
|  | 107 | /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */ | 
|  | 108 | {	"HAYF001",		0	}, | 
|  | 109 | /* IBM */ | 
|  | 110 | /* IBM Thinkpad 701 Internal Modem Voice */ | 
|  | 111 | {	"IBM0033",		0	}, | 
|  | 112 | /* Intertex */ | 
|  | 113 | /* Intertex 28k8 33k6 Voice EXT PnP */ | 
|  | 114 | {	"IXDC801",		0	}, | 
|  | 115 | /* Intertex 33k6 56k Voice EXT PnP */ | 
|  | 116 | {	"IXDC901",		0	}, | 
|  | 117 | /* Intertex 28k8 33k6 Voice SP EXT PnP */ | 
|  | 118 | {	"IXDD801",		0	}, | 
|  | 119 | /* Intertex 33k6 56k Voice SP EXT PnP */ | 
|  | 120 | {	"IXDD901",		0	}, | 
|  | 121 | /* Intertex 28k8 33k6 Voice SP INT PnP */ | 
|  | 122 | {	"IXDF401",		0	}, | 
|  | 123 | /* Intertex 28k8 33k6 Voice SP EXT PnP */ | 
|  | 124 | {	"IXDF801",		0	}, | 
|  | 125 | /* Intertex 33k6 56k Voice SP EXT PnP */ | 
|  | 126 | {	"IXDF901",		0	}, | 
|  | 127 | /* Kortex International */ | 
|  | 128 | /* KORTEX 28800 Externe PnP */ | 
|  | 129 | {	"KOR4522",		0	}, | 
|  | 130 | /* KXPro 33.6 Vocal ASVD PnP */ | 
|  | 131 | {	"KORF661",		0	}, | 
|  | 132 | /* Lasat */ | 
|  | 133 | /* LASAT Internet 33600 PnP */ | 
|  | 134 | {	"LAS4040",		0	}, | 
|  | 135 | /* Lasat Safire 560 PnP */ | 
|  | 136 | {	"LAS4540",		0	}, | 
|  | 137 | /* Lasat Safire 336  PnP */ | 
|  | 138 | {	"LAS5440",		0	}, | 
|  | 139 | /* Microcom, Inc. */ | 
|  | 140 | /* Microcom TravelPorte FAST V.34 Plug & Play */ | 
|  | 141 | {	"MNP0281",		0	}, | 
|  | 142 | /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */ | 
|  | 143 | {	"MNP0336",		0	}, | 
|  | 144 | /* Microcom DeskPorte FAST EP 28.8 Plug & Play */ | 
|  | 145 | {	"MNP0339",		0	}, | 
|  | 146 | /* Microcom DeskPorte 28.8P Plug & Play */ | 
|  | 147 | {	"MNP0342",		0	}, | 
|  | 148 | /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ | 
|  | 149 | {	"MNP0500",		0	}, | 
|  | 150 | /* Microcom DeskPorte FAST ES 28.8 Plug & Play */ | 
|  | 151 | {	"MNP0501",		0	}, | 
|  | 152 | /* Microcom DeskPorte 28.8S Internal Plug & Play */ | 
|  | 153 | {	"MNP0502",		0	}, | 
|  | 154 | /* Motorola */ | 
|  | 155 | /* Motorola BitSURFR Plug & Play */ | 
|  | 156 | {	"MOT1105",		0	}, | 
|  | 157 | /* Motorola TA210 Plug & Play */ | 
|  | 158 | {	"MOT1111",		0	}, | 
|  | 159 | /* Motorola HMTA 200 (ISDN) Plug & Play */ | 
|  | 160 | {	"MOT1114",		0	}, | 
|  | 161 | /* Motorola BitSURFR Plug & Play */ | 
|  | 162 | {	"MOT1115",		0	}, | 
|  | 163 | /* Motorola Lifestyle 28.8 Internal */ | 
|  | 164 | {	"MOT1190",		0	}, | 
|  | 165 | /* Motorola V.3400 Plug & Play */ | 
|  | 166 | {	"MOT1501",		0	}, | 
|  | 167 | /* Motorola Lifestyle 28.8 V.34 Plug & Play */ | 
|  | 168 | {	"MOT1502",		0	}, | 
|  | 169 | /* Motorola Power 28.8 V.34 Plug & Play */ | 
|  | 170 | {	"MOT1505",		0	}, | 
|  | 171 | /* Motorola ModemSURFR External 28.8 Plug & Play */ | 
|  | 172 | {	"MOT1509",		0	}, | 
|  | 173 | /* Motorola Premier 33.6 Desktop Plug & Play */ | 
|  | 174 | {	"MOT150A",		0	}, | 
|  | 175 | /* Motorola VoiceSURFR 56K External PnP */ | 
|  | 176 | {	"MOT150F",		0	}, | 
|  | 177 | /* Motorola ModemSURFR 56K External PnP */ | 
|  | 178 | {	"MOT1510",		0	}, | 
|  | 179 | /* Motorola ModemSURFR 56K Internal PnP */ | 
|  | 180 | {	"MOT1550",		0	}, | 
|  | 181 | /* Motorola ModemSURFR Internal 28.8 Plug & Play */ | 
|  | 182 | {	"MOT1560",		0	}, | 
|  | 183 | /* Motorola Premier 33.6 Internal Plug & Play */ | 
|  | 184 | {	"MOT1580",		0	}, | 
|  | 185 | /* Motorola OnlineSURFR 28.8 Internal Plug & Play */ | 
|  | 186 | {	"MOT15B0",		0	}, | 
|  | 187 | /* Motorola VoiceSURFR 56K Internal PnP */ | 
|  | 188 | {	"MOT15F0",		0	}, | 
|  | 189 | /* Com 1 */ | 
|  | 190 | /*  Deskline K56 Phone System PnP */ | 
|  | 191 | {	"MVX00A1",		0	}, | 
|  | 192 | /* PC Rider K56 Phone System PnP */ | 
|  | 193 | {	"MVX00F2",		0	}, | 
|  | 194 | /* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */ | 
|  | 195 | {	"nEC8241",		0	}, | 
|  | 196 | /* Pace 56 Voice Internal Plug & Play Modem */ | 
|  | 197 | {	"PMC2430",		0	}, | 
|  | 198 | /* Generic */ | 
|  | 199 | /* Generic standard PC COM port	 */ | 
|  | 200 | {	"PNP0500",		0	}, | 
|  | 201 | /* Generic 16550A-compatible COM port */ | 
|  | 202 | {	"PNP0501",		0	}, | 
|  | 203 | /* Compaq 14400 Modem */ | 
|  | 204 | {	"PNPC000",		0	}, | 
|  | 205 | /* Compaq 2400/9600 Modem */ | 
|  | 206 | {	"PNPC001",		0	}, | 
|  | 207 | /* Dial-Up Networking Serial Cable between 2 PCs */ | 
|  | 208 | {	"PNPC031",		0	}, | 
|  | 209 | /* Dial-Up Networking Parallel Cable between 2 PCs */ | 
|  | 210 | {	"PNPC032",		0	}, | 
|  | 211 | /* Standard 9600 bps Modem */ | 
|  | 212 | {	"PNPC100",		0	}, | 
|  | 213 | /* Standard 14400 bps Modem */ | 
|  | 214 | {	"PNPC101",		0	}, | 
|  | 215 | /*  Standard 28800 bps Modem*/ | 
|  | 216 | {	"PNPC102",		0	}, | 
|  | 217 | /*  Standard Modem*/ | 
|  | 218 | {	"PNPC103",		0	}, | 
|  | 219 | /*  Standard 9600 bps Modem*/ | 
|  | 220 | {	"PNPC104",		0	}, | 
|  | 221 | /*  Standard 14400 bps Modem*/ | 
|  | 222 | {	"PNPC105",		0	}, | 
|  | 223 | /*  Standard 28800 bps Modem*/ | 
|  | 224 | {	"PNPC106",		0	}, | 
|  | 225 | /*  Standard Modem */ | 
|  | 226 | {	"PNPC107",		0	}, | 
|  | 227 | /* Standard 9600 bps Modem */ | 
|  | 228 | {	"PNPC108",		0	}, | 
|  | 229 | /* Standard 14400 bps Modem */ | 
|  | 230 | {	"PNPC109",		0	}, | 
|  | 231 | /* Standard 28800 bps Modem */ | 
|  | 232 | {	"PNPC10A",		0	}, | 
|  | 233 | /* Standard Modem */ | 
|  | 234 | {	"PNPC10B",		0	}, | 
|  | 235 | /* Standard 9600 bps Modem */ | 
|  | 236 | {	"PNPC10C",		0	}, | 
|  | 237 | /* Standard 14400 bps Modem */ | 
|  | 238 | {	"PNPC10D",		0	}, | 
|  | 239 | /* Standard 28800 bps Modem */ | 
|  | 240 | {	"PNPC10E",		0	}, | 
|  | 241 | /* Standard Modem */ | 
|  | 242 | {	"PNPC10F",		0	}, | 
|  | 243 | /* Standard PCMCIA Card Modem */ | 
|  | 244 | {	"PNP2000",		0	}, | 
|  | 245 | /* Rockwell */ | 
|  | 246 | /* Modular Technology */ | 
|  | 247 | /* Rockwell 33.6 DPF Internal PnP */ | 
|  | 248 | /* Modular Technology 33.6 Internal PnP */ | 
|  | 249 | {	"ROK0030",		0	}, | 
|  | 250 | /* Kortex International */ | 
|  | 251 | /* KORTEX 14400 Externe PnP */ | 
|  | 252 | {	"ROK0100",		0	}, | 
|  | 253 | /* Rockwell 28.8 */ | 
|  | 254 | {	"ROK4120",		0	}, | 
|  | 255 | /* Viking Components, Inc */ | 
|  | 256 | /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */ | 
|  | 257 | {	"ROK4920",		0	}, | 
|  | 258 | /* Rockwell */ | 
|  | 259 | /* British Telecom */ | 
|  | 260 | /* Modular Technology */ | 
|  | 261 | /* Rockwell 33.6 DPF External PnP */ | 
|  | 262 | /* BT Prologue 33.6 External PnP */ | 
|  | 263 | /* Modular Technology 33.6 External PnP */ | 
|  | 264 | {	"RSS00A0",		0	}, | 
|  | 265 | /* Viking 56K FAX INT */ | 
|  | 266 | {	"RSS0262",		0	}, | 
|  | 267 | /* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */ | 
|  | 268 | {       "RSS0250",              0       }, | 
|  | 269 | /* SupraExpress 28.8 Data/Fax PnP modem */ | 
|  | 270 | {	"SUP1310",		0	}, | 
|  | 271 | /* SupraExpress 33.6 Data/Fax PnP modem */ | 
|  | 272 | {	"SUP1421",		0	}, | 
|  | 273 | /* SupraExpress 33.6 Data/Fax PnP modem */ | 
|  | 274 | {	"SUP1590",		0	}, | 
| Baris Cicek | 04f03bf | 2005-10-14 14:32:40 +0100 | [diff] [blame] | 275 | /* SupraExpress 336i Sp ASVD */ | 
|  | 276 | {	"SUP1620",		0	}, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 277 | /* SupraExpress 33.6 Data/Fax PnP modem */ | 
|  | 278 | {	"SUP1760",		0	}, | 
| maximilian attems | c1542cb | 2005-10-15 10:43:35 +0100 | [diff] [blame] | 279 | /* SupraExpress 56i Sp Intl */ | 
|  | 280 | {	"SUP2171",		0	}, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 281 | /* Phoebe Micro */ | 
|  | 282 | /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */ | 
|  | 283 | {	"TEX0011",		0	}, | 
|  | 284 | /* Archtek America Corp. */ | 
|  | 285 | /* Archtek SmartLink Modem 3334BT Plug & Play */ | 
|  | 286 | {	"UAC000F",		0	}, | 
|  | 287 | /* 3Com Corp. */ | 
|  | 288 | /* Gateway Telepath IIvi 33.6 */ | 
|  | 289 | {	"USR0000",		0	}, | 
|  | 290 | /* U.S. Robotics Sporster 33.6K Fax INT PnP */ | 
|  | 291 | {	"USR0002",		0	}, | 
|  | 292 | /*  Sportster Vi 14.4 PnP FAX Voicemail */ | 
|  | 293 | {	"USR0004",		0	}, | 
|  | 294 | /* U.S. Robotics 33.6K Voice INT PnP */ | 
|  | 295 | {	"USR0006",		0	}, | 
|  | 296 | /* U.S. Robotics 33.6K Voice EXT PnP */ | 
|  | 297 | {	"USR0007",		0	}, | 
|  | 298 | /* U.S. Robotics Courier V.Everything INT PnP */ | 
|  | 299 | {	"USR0009",		0	}, | 
|  | 300 | /* U.S. Robotics 33.6K Voice INT PnP */ | 
|  | 301 | {	"USR2002",		0	}, | 
|  | 302 | /* U.S. Robotics 56K Voice INT PnP */ | 
|  | 303 | {	"USR2070",		0	}, | 
|  | 304 | /* U.S. Robotics 56K Voice EXT PnP */ | 
|  | 305 | {	"USR2080",		0	}, | 
|  | 306 | /* U.S. Robotics 56K FAX INT */ | 
|  | 307 | {	"USR3031",		0	}, | 
|  | 308 | /* U.S. Robotics 56K FAX INT */ | 
|  | 309 | {	"USR3050",		0	}, | 
|  | 310 | /* U.S. Robotics 56K Voice INT PnP */ | 
|  | 311 | {	"USR3070",		0	}, | 
|  | 312 | /* U.S. Robotics 56K Voice EXT PnP */ | 
|  | 313 | {	"USR3080",		0	}, | 
|  | 314 | /* U.S. Robotics 56K Voice INT PnP */ | 
|  | 315 | {	"USR3090",		0	}, | 
|  | 316 | /* U.S. Robotics 56K Message  */ | 
|  | 317 | {	"USR9100",		0	}, | 
|  | 318 | /* U.S. Robotics 56K FAX EXT PnP*/ | 
|  | 319 | {	"USR9160",		0	}, | 
|  | 320 | /* U.S. Robotics 56K FAX INT PnP*/ | 
|  | 321 | {	"USR9170",		0	}, | 
|  | 322 | /* U.S. Robotics 56K Voice EXT PnP*/ | 
|  | 323 | {	"USR9180",		0	}, | 
|  | 324 | /* U.S. Robotics 56K Voice INT PnP*/ | 
|  | 325 | {	"USR9190",		0	}, | 
| Ben Collins | b07076e | 2006-06-26 15:24:36 +0100 | [diff] [blame] | 326 | /* Wacom tablets */ | 
|  | 327 | {	"WACF004",		0	}, | 
| Bjorn Helgaas | fa60943 | 2005-11-12 22:06:31 +0000 | [diff] [blame] | 328 | {	"WACF005",		0	}, | 
| Ben Collins | b07076e | 2006-06-26 15:24:36 +0100 | [diff] [blame] | 329 | {       "WACF006",              0       }, | 
| Matthew Garrett | 75fde2e | 2006-10-01 19:27:38 +0100 | [diff] [blame] | 330 | /* Compaq touchscreen */ | 
|  | 331 | {       "FPI2002",              0 }, | 
|  | 332 | /* Fujitsu Stylistic touchscreens */ | 
|  | 333 | {       "FUJ02B2",              0 }, | 
|  | 334 | {       "FUJ02B3",              0 }, | 
|  | 335 | /* Fujitsu Stylistic LT touchscreens */ | 
|  | 336 | {       "FUJ02B4",              0 }, | 
|  | 337 | /* Passive Fujitsu Stylistic touchscreens */ | 
|  | 338 | {       "FUJ02B6",              0 }, | 
|  | 339 | {       "FUJ02B7",              0 }, | 
|  | 340 | {       "FUJ02B8",              0 }, | 
|  | 341 | {       "FUJ02B9",              0 }, | 
|  | 342 | {       "FUJ02BC",              0 }, | 
| Danny Kukawka | 6149dd5 | 2007-03-23 00:10:01 -0700 | [diff] [blame] | 343 | /* Fujitsu Wacom Tablet PC devices */ | 
|  | 344 | {	"FUJ02E5",		0	}, | 
|  | 345 | {	"FUJ02E6",		0	}, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 346 | /* Rockwell's (PORALiNK) 33600 INT PNP */ | 
|  | 347 | {	"WCI0003",		0	}, | 
|  | 348 | /* Unkown PnP modems */ | 
|  | 349 | {	"PNPCXXX",		UNKNOWN_DEV	}, | 
|  | 350 | /* More unkown PnP modems */ | 
|  | 351 | {	"PNPDXXX",		UNKNOWN_DEV	}, | 
|  | 352 | {	"",			0	} | 
|  | 353 | }; | 
|  | 354 |  | 
|  | 355 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); | 
|  | 356 |  | 
|  | 357 | static char *modem_names[] __devinitdata = { | 
|  | 358 | "MODEM", "Modem", "modem", "FAX", "Fax", "fax", | 
|  | 359 | "56K", "56k", "K56", "33.6", "28.8", "14.4", | 
|  | 360 | "33,600", "28,800", "14,400", "33.600", "28.800", "14.400", | 
|  | 361 | "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL | 
|  | 362 | }; | 
|  | 363 |  | 
|  | 364 | static int __devinit check_name(char *name) | 
|  | 365 | { | 
|  | 366 | char **tmp; | 
|  | 367 |  | 
|  | 368 | for (tmp = modem_names; *tmp; tmp++) | 
|  | 369 | if (strstr(name, *tmp)) | 
|  | 370 | return 1; | 
|  | 371 |  | 
|  | 372 | return 0; | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | static int __devinit check_resources(struct pnp_option *option) | 
|  | 376 | { | 
|  | 377 | struct pnp_option *tmp; | 
|  | 378 | if (!option) | 
|  | 379 | return 0; | 
|  | 380 |  | 
|  | 381 | for (tmp = option; tmp; tmp = tmp->next) { | 
|  | 382 | struct pnp_port *port; | 
|  | 383 | for (port = tmp->port; port; port = port->next) | 
|  | 384 | if ((port->size == 8) && | 
|  | 385 | ((port->min == 0x2f8) || | 
|  | 386 | (port->min == 0x3f8) || | 
|  | 387 | (port->min == 0x2e8) || | 
|  | 388 | (port->min == 0x3e8))) | 
|  | 389 | return 1; | 
|  | 390 | } | 
|  | 391 |  | 
|  | 392 | return 0; | 
|  | 393 | } | 
|  | 394 |  | 
|  | 395 | /* | 
|  | 396 | * Given a complete unknown PnP device, try to use some heuristics to | 
|  | 397 | * detect modems. Currently use such heuristic set: | 
|  | 398 | *     - dev->name or dev->bus->name must contain "modem" substring; | 
|  | 399 | *     - device must have only one IO region (8 byte long) with base address | 
|  | 400 | *       0x2e8, 0x3e8, 0x2f8 or 0x3f8. | 
|  | 401 | * | 
|  | 402 | * Such detection looks very ugly, but can detect at least some of numerous | 
|  | 403 | * PnP modems, alternatively we must hardcode all modems in pnp_devices[] | 
|  | 404 | * table. | 
|  | 405 | */ | 
|  | 406 | static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) | 
|  | 407 | { | 
|  | 408 | if (!(check_name(pnp_dev_name(dev)) || (dev->card && check_name(dev->card->name)))) | 
|  | 409 | return -ENODEV; | 
|  | 410 |  | 
|  | 411 | if (check_resources(dev->independent)) | 
|  | 412 | return 0; | 
|  | 413 |  | 
|  | 414 | if (check_resources(dev->dependent)) | 
|  | 415 | return 0; | 
|  | 416 |  | 
|  | 417 | return -ENODEV; | 
|  | 418 | } | 
|  | 419 |  | 
|  | 420 | static int __devinit | 
| Bjorn Helgaas | 655a0a7 | 2005-07-29 14:03:30 -0700 | [diff] [blame] | 421 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 422 | { | 
|  | 423 | struct uart_port port; | 
|  | 424 | int ret, line, flags = dev_id->driver_data; | 
|  | 425 |  | 
|  | 426 | if (flags & UNKNOWN_DEV) { | 
|  | 427 | ret = serial_pnp_guess_board(dev, &flags); | 
|  | 428 | if (ret < 0) | 
|  | 429 | return ret; | 
|  | 430 | } | 
|  | 431 |  | 
|  | 432 | memset(&port, 0, sizeof(struct uart_port)); | 
| Bjorn Helgaas | 655a0a7 | 2005-07-29 14:03:30 -0700 | [diff] [blame] | 433 | port.irq = pnp_irq(dev, 0); | 
|  | 434 | if (pnp_port_valid(dev, 0)) { | 
|  | 435 | port.iobase = pnp_port_start(dev, 0); | 
|  | 436 | port.iotype = UPIO_PORT; | 
|  | 437 | } else if (pnp_mem_valid(dev, 0)) { | 
|  | 438 | port.mapbase = pnp_mem_start(dev, 0); | 
|  | 439 | port.iotype = UPIO_MEM; | 
|  | 440 | port.flags = UPF_IOREMAP; | 
|  | 441 | } else | 
|  | 442 | return -ENODEV; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 443 |  | 
|  | 444 | #ifdef SERIAL_DEBUG_PNP | 
| Bjorn Helgaas | 655a0a7 | 2005-07-29 14:03:30 -0700 | [diff] [blame] | 445 | printk("Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", | 
|  | 446 | port.iobase, port.mapbase, port.irq, port.iotype); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 447 | #endif | 
|  | 448 |  | 
| Bjorn Helgaas | 655a0a7 | 2005-07-29 14:03:30 -0700 | [diff] [blame] | 449 | port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | 
| Bjorn Helgaas | cb6358e | 2006-07-03 00:24:12 -0700 | [diff] [blame] | 450 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) | 
|  | 451 | port.flags |= UPF_SHARE_IRQ; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 452 | port.uartclk = 1843200; | 
|  | 453 | port.dev = &dev->dev; | 
|  | 454 |  | 
|  | 455 | line = serial8250_register_port(&port); | 
| Bjorn Helgaas | 9b22271 | 2007-02-14 00:33:05 -0800 | [diff] [blame] | 456 | if (line < 0) | 
|  | 457 | return -ENODEV; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 458 |  | 
| Bjorn Helgaas | 9b22271 | 2007-02-14 00:33:05 -0800 | [diff] [blame] | 459 | pnp_set_drvdata(dev, (void *)((long)line + 1)); | 
|  | 460 | return 0; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 461 | } | 
|  | 462 |  | 
| Bjorn Helgaas | 655a0a7 | 2005-07-29 14:03:30 -0700 | [diff] [blame] | 463 | static void __devexit serial_pnp_remove(struct pnp_dev *dev) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 464 | { | 
|  | 465 | long line = (long)pnp_get_drvdata(dev); | 
|  | 466 | if (line) | 
|  | 467 | serial8250_unregister_port(line - 1); | 
|  | 468 | } | 
|  | 469 |  | 
| Mike Galbraith | f29219f | 2006-12-06 20:39:35 -0800 | [diff] [blame] | 470 | #ifdef CONFIG_PM | 
|  | 471 | static int serial_pnp_suspend(struct pnp_dev *dev, pm_message_t state) | 
|  | 472 | { | 
|  | 473 | long line = (long)pnp_get_drvdata(dev); | 
|  | 474 |  | 
|  | 475 | if (!line) | 
|  | 476 | return -ENODEV; | 
|  | 477 | serial8250_suspend_port(line - 1); | 
|  | 478 | return 0; | 
|  | 479 | } | 
|  | 480 |  | 
|  | 481 | static int serial_pnp_resume(struct pnp_dev *dev) | 
|  | 482 | { | 
|  | 483 | long line = (long)pnp_get_drvdata(dev); | 
|  | 484 |  | 
|  | 485 | if (!line) | 
|  | 486 | return -ENODEV; | 
|  | 487 | serial8250_resume_port(line - 1); | 
|  | 488 | return 0; | 
|  | 489 | } | 
|  | 490 | #else | 
|  | 491 | #define serial_pnp_suspend NULL | 
|  | 492 | #define serial_pnp_resume NULL | 
|  | 493 | #endif /* CONFIG_PM */ | 
|  | 494 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 495 | static struct pnp_driver serial_pnp_driver = { | 
|  | 496 | .name		= "serial", | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 497 | .probe		= serial_pnp_probe, | 
|  | 498 | .remove		= __devexit_p(serial_pnp_remove), | 
| Mike Galbraith | f29219f | 2006-12-06 20:39:35 -0800 | [diff] [blame] | 499 | .suspend	= serial_pnp_suspend, | 
|  | 500 | .resume		= serial_pnp_resume, | 
|  | 501 | .id_table	= pnp_dev_table, | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 502 | }; | 
|  | 503 |  | 
|  | 504 | static int __init serial8250_pnp_init(void) | 
|  | 505 | { | 
|  | 506 | return pnp_register_driver(&serial_pnp_driver); | 
|  | 507 | } | 
|  | 508 |  | 
|  | 509 | static void __exit serial8250_pnp_exit(void) | 
|  | 510 | { | 
|  | 511 | pnp_unregister_driver(&serial_pnp_driver); | 
|  | 512 | } | 
|  | 513 |  | 
|  | 514 | module_init(serial8250_pnp_init); | 
|  | 515 | module_exit(serial8250_pnp_exit); | 
|  | 516 |  | 
|  | 517 | MODULE_LICENSE("GPL"); | 
|  | 518 | MODULE_DESCRIPTION("Generic 8250/16x50 PnP serial driver"); |