LCOV - code coverage report
Current view: top level - drivers/tty/serial/8250 - 8250_pnp.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 26 70 37.1 %
Date: 2022-04-01 14:58:12 Functions: 2 8 25.0 %
Branches: 8 50 16.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  *  Probe for 8250/16550-type ISAPNP serial ports.
       4                 :            :  *
       5                 :            :  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
       6                 :            :  *
       7                 :            :  *  Copyright (C) 2001 Russell King, All Rights Reserved.
       8                 :            :  *
       9                 :            :  *  Ported to the Linux PnP Layer - (C) Adam Belay.
      10                 :            :  */
      11                 :            : #include <linux/module.h>
      12                 :            : #include <linux/pci.h>
      13                 :            : #include <linux/pnp.h>
      14                 :            : #include <linux/string.h>
      15                 :            : #include <linux/kernel.h>
      16                 :            : #include <linux/serial_core.h>
      17                 :            : #include <linux/bitops.h>
      18                 :            : 
      19                 :            : #include <asm/byteorder.h>
      20                 :            : 
      21                 :            : #include "8250.h"
      22                 :            : 
      23                 :            : #define UNKNOWN_DEV 0x3000
      24                 :            : #define CIR_PORT        0x0800
      25                 :            : 
      26                 :            : static const struct pnp_device_id pnp_dev_table[] = {
      27                 :            :         /* Archtek America Corp. */
      28                 :            :         /* Archtek SmartLink Modem 3334BT Plug & Play */
      29                 :            :         {       "AAC000F",            0       },
      30                 :            :         /* Anchor Datacomm BV */
      31                 :            :         /* SXPro 144 External Data Fax Modem Plug & Play */
      32                 :            :         {       "ADC0001",            0       },
      33                 :            :         /* SXPro 288 External Data Fax Modem Plug & Play */
      34                 :            :         {       "ADC0002",            0       },
      35                 :            :         /* PROLiNK 1456VH ISA PnP K56flex Fax Modem */
      36                 :            :         {       "AEI0250",            0       },
      37                 :            :         /* Actiontec ISA PNP 56K X2 Fax Modem */
      38                 :            :         {       "AEI1240",            0       },
      39                 :            :         /* Rockwell 56K ACF II Fax+Data+Voice Modem */
      40                 :            :         {       "AKY1021",            0 /*SPCI_FL_NO_SHIRQ*/  },
      41                 :            :         /*
      42                 :            :          * ALi Fast Infrared Controller
      43                 :            :          * Native driver (ali-ircc) is broken so at least
      44                 :            :          * it can be used with irtty-sir.
      45                 :            :          */
      46                 :            :         {       "ALI5123",            0       },
      47                 :            :         /* AZT3005 PnP SOUND DEVICE */
      48                 :            :         {       "AZT4001",            0       },
      49                 :            :         /* Best Data Products Inc. Smart One 336F PnP Modem */
      50                 :            :         {       "BDP3336",            0       },
      51                 :            :         /*  Boca Research */
      52                 :            :         /* Boca Complete Ofc Communicator 14.4 Data-FAX */
      53                 :            :         {       "BRI0A49",            0       },
      54                 :            :         /* Boca Research 33,600 ACF Modem */
      55                 :            :         {       "BRI1400",            0       },
      56                 :            :         /* Boca 33.6 Kbps Internal FD34FSVD */
      57                 :            :         {       "BRI3400",            0       },
      58                 :            :         /* Boca 33.6 Kbps Internal FD34FSVD */
      59                 :            :         {       "BRI0A49",            0       },
      60                 :            :         /* Best Data Products Inc. Smart One 336F PnP Modem */
      61                 :            :         {       "BDP3336",            0       },
      62                 :            :         /* Computer Peripherals Inc */
      63                 :            :         /* EuroViVa CommCenter-33.6 SP PnP */
      64                 :            :         {       "CPI4050",            0       },
      65                 :            :         /* Creative Labs */
      66                 :            :         /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
      67                 :            :         {       "CTL3001",            0       },
      68                 :            :         /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
      69                 :            :         {       "CTL3011",            0       },
      70                 :            :         /* Davicom ISA 33.6K Modem */
      71                 :            :         {       "DAV0336",            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                 :            :         /* Archtek SmartLink Modem 3334BRV 33.6K Data Fax Voice */
      93                 :            :         {       "GVC0303",            0       },
      94                 :            :         /* Hayes */
      95                 :            :         /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
      96                 :            :         {       "HAY0001",            0       },
      97                 :            :         /* Hayes Optima 336 V.34 + FAX + Voice PnP */
      98                 :            :         {       "HAY000C",            0       },
      99                 :            :         /* Hayes Optima 336B V.34 + FAX + Voice PnP */
     100                 :            :         {       "HAY000D",            0       },
     101                 :            :         /* Hayes Accura 56K Ext Fax Modem PnP */
     102                 :            :         {       "HAY5670",            0       },
     103                 :            :         /* Hayes Accura 56K Ext Fax Modem PnP */
     104                 :            :         {       "HAY5674",            0       },
     105                 :            :         /* Hayes Accura 56K Fax Modem PnP */
     106                 :            :         {       "HAY5675",            0       },
     107                 :            :         /* Hayes 288, V.34 + FAX */
     108                 :            :         {       "HAYF000",            0       },
     109                 :            :         /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
     110                 :            :         {       "HAYF001",            0       },
     111                 :            :         /* IBM */
     112                 :            :         /* IBM Thinkpad 701 Internal Modem Voice */
     113                 :            :         {       "IBM0033",            0       },
     114                 :            :         /* Intermec */
     115                 :            :         /* Intermec CV60 touchscreen port */
     116                 :            :         {       "PNP4972",            0       },
     117                 :            :         /* Intertex */
     118                 :            :         /* Intertex 28k8 33k6 Voice EXT PnP */
     119                 :            :         {       "IXDC801",            0       },
     120                 :            :         /* Intertex 33k6 56k Voice EXT PnP */
     121                 :            :         {       "IXDC901",            0       },
     122                 :            :         /* Intertex 28k8 33k6 Voice SP EXT PnP */
     123                 :            :         {       "IXDD801",            0       },
     124                 :            :         /* Intertex 33k6 56k Voice SP EXT PnP */
     125                 :            :         {       "IXDD901",            0       },
     126                 :            :         /* Intertex 28k8 33k6 Voice SP INT PnP */
     127                 :            :         {       "IXDF401",            0       },
     128                 :            :         /* Intertex 28k8 33k6 Voice SP EXT PnP */
     129                 :            :         {       "IXDF801",            0       },
     130                 :            :         /* Intertex 33k6 56k Voice SP EXT PnP */
     131                 :            :         {       "IXDF901",            0       },
     132                 :            :         /* Kortex International */
     133                 :            :         /* KORTEX 28800 Externe PnP */
     134                 :            :         {       "KOR4522",            0       },
     135                 :            :         /* KXPro 33.6 Vocal ASVD PnP */
     136                 :            :         {       "KORF661",            0       },
     137                 :            :         /* Lasat */
     138                 :            :         /* LASAT Internet 33600 PnP */
     139                 :            :         {       "LAS4040",            0       },
     140                 :            :         /* Lasat Safire 560 PnP */
     141                 :            :         {       "LAS4540",            0       },
     142                 :            :         /* Lasat Safire 336  PnP */
     143                 :            :         {       "LAS5440",            0       },
     144                 :            :         /* Microcom, Inc. */
     145                 :            :         /* Microcom TravelPorte FAST V.34 Plug & Play */
     146                 :            :         {       "MNP0281",            0       },
     147                 :            :         /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
     148                 :            :         {       "MNP0336",            0       },
     149                 :            :         /* Microcom DeskPorte FAST EP 28.8 Plug & Play */
     150                 :            :         {       "MNP0339",            0       },
     151                 :            :         /* Microcom DeskPorte 28.8P Plug & Play */
     152                 :            :         {       "MNP0342",            0       },
     153                 :            :         /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
     154                 :            :         {       "MNP0500",            0       },
     155                 :            :         /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
     156                 :            :         {       "MNP0501",            0       },
     157                 :            :         /* Microcom DeskPorte 28.8S Internal Plug & Play */
     158                 :            :         {       "MNP0502",            0       },
     159                 :            :         /* Motorola */
     160                 :            :         /* Motorola BitSURFR Plug & Play */
     161                 :            :         {       "MOT1105",            0       },
     162                 :            :         /* Motorola TA210 Plug & Play */
     163                 :            :         {       "MOT1111",            0       },
     164                 :            :         /* Motorola HMTA 200 (ISDN) Plug & Play */
     165                 :            :         {       "MOT1114",            0       },
     166                 :            :         /* Motorola BitSURFR Plug & Play */
     167                 :            :         {       "MOT1115",            0       },
     168                 :            :         /* Motorola Lifestyle 28.8 Internal */
     169                 :            :         {       "MOT1190",            0       },
     170                 :            :         /* Motorola V.3400 Plug & Play */
     171                 :            :         {       "MOT1501",            0       },
     172                 :            :         /* Motorola Lifestyle 28.8 V.34 Plug & Play */
     173                 :            :         {       "MOT1502",            0       },
     174                 :            :         /* Motorola Power 28.8 V.34 Plug & Play */
     175                 :            :         {       "MOT1505",            0       },
     176                 :            :         /* Motorola ModemSURFR External 28.8 Plug & Play */
     177                 :            :         {       "MOT1509",            0       },
     178                 :            :         /* Motorola Premier 33.6 Desktop Plug & Play */
     179                 :            :         {       "MOT150A",            0       },
     180                 :            :         /* Motorola VoiceSURFR 56K External PnP */
     181                 :            :         {       "MOT150F",            0       },
     182                 :            :         /* Motorola ModemSURFR 56K External PnP */
     183                 :            :         {       "MOT1510",            0       },
     184                 :            :         /* Motorola ModemSURFR 56K Internal PnP */
     185                 :            :         {       "MOT1550",            0       },
     186                 :            :         /* Motorola ModemSURFR Internal 28.8 Plug & Play */
     187                 :            :         {       "MOT1560",            0       },
     188                 :            :         /* Motorola Premier 33.6 Internal Plug & Play */
     189                 :            :         {       "MOT1580",            0       },
     190                 :            :         /* Motorola OnlineSURFR 28.8 Internal Plug & Play */
     191                 :            :         {       "MOT15B0",            0       },
     192                 :            :         /* Motorola VoiceSURFR 56K Internal PnP */
     193                 :            :         {       "MOT15F0",            0       },
     194                 :            :         /* Com 1 */
     195                 :            :         /*  Deskline K56 Phone System PnP */
     196                 :            :         {       "MVX00A1",            0       },
     197                 :            :         /* PC Rider K56 Phone System PnP */
     198                 :            :         {       "MVX00F2",            0       },
     199                 :            :         /* NEC 98NOTE SPEAKER PHONE FAX MODEM(33600bps) */
     200                 :            :         {       "nEC8241",            0       },
     201                 :            :         /* Pace 56 Voice Internal Plug & Play Modem */
     202                 :            :         {       "PMC2430",            0       },
     203                 :            :         /* Generic */
     204                 :            :         /* Generic standard PC COM port  */
     205                 :            :         {       "PNP0500",            0       },
     206                 :            :         /* Generic 16550A-compatible COM port */
     207                 :            :         {       "PNP0501",            0       },
     208                 :            :         /* Compaq 14400 Modem */
     209                 :            :         {       "PNPC000",            0       },
     210                 :            :         /* Compaq 2400/9600 Modem */
     211                 :            :         {       "PNPC001",            0       },
     212                 :            :         /* Dial-Up Networking Serial Cable between 2 PCs */
     213                 :            :         {       "PNPC031",            0       },
     214                 :            :         /* Dial-Up Networking Parallel Cable between 2 PCs */
     215                 :            :         {       "PNPC032",            0       },
     216                 :            :         /* Standard 9600 bps Modem */
     217                 :            :         {       "PNPC100",            0       },
     218                 :            :         /* Standard 14400 bps Modem */
     219                 :            :         {       "PNPC101",            0       },
     220                 :            :         /*  Standard 28800 bps Modem*/
     221                 :            :         {       "PNPC102",            0       },
     222                 :            :         /*  Standard Modem*/
     223                 :            :         {       "PNPC103",            0       },
     224                 :            :         /*  Standard 9600 bps Modem*/
     225                 :            :         {       "PNPC104",            0       },
     226                 :            :         /*  Standard 14400 bps Modem*/
     227                 :            :         {       "PNPC105",            0       },
     228                 :            :         /*  Standard 28800 bps Modem*/
     229                 :            :         {       "PNPC106",            0       },
     230                 :            :         /*  Standard Modem */
     231                 :            :         {       "PNPC107",            0       },
     232                 :            :         /* Standard 9600 bps Modem */
     233                 :            :         {       "PNPC108",            0       },
     234                 :            :         /* Standard 14400 bps Modem */
     235                 :            :         {       "PNPC109",            0       },
     236                 :            :         /* Standard 28800 bps Modem */
     237                 :            :         {       "PNPC10A",            0       },
     238                 :            :         /* Standard Modem */
     239                 :            :         {       "PNPC10B",            0       },
     240                 :            :         /* Standard 9600 bps Modem */
     241                 :            :         {       "PNPC10C",            0       },
     242                 :            :         /* Standard 14400 bps Modem */
     243                 :            :         {       "PNPC10D",            0       },
     244                 :            :         /* Standard 28800 bps Modem */
     245                 :            :         {       "PNPC10E",            0       },
     246                 :            :         /* Standard Modem */
     247                 :            :         {       "PNPC10F",            0       },
     248                 :            :         /* Standard PCMCIA Card Modem */
     249                 :            :         {       "PNP2000",            0       },
     250                 :            :         /* Rockwell */
     251                 :            :         /* Modular Technology */
     252                 :            :         /* Rockwell 33.6 DPF Internal PnP */
     253                 :            :         /* Modular Technology 33.6 Internal PnP */
     254                 :            :         {       "ROK0030",            0       },
     255                 :            :         /* Kortex International */
     256                 :            :         /* KORTEX 14400 Externe PnP */
     257                 :            :         {       "ROK0100",            0       },
     258                 :            :         /* Rockwell 28.8 */
     259                 :            :         {       "ROK4120",            0       },
     260                 :            :         /* Viking Components, Inc */
     261                 :            :         /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
     262                 :            :         {       "ROK4920",            0       },
     263                 :            :         /* Rockwell */
     264                 :            :         /* British Telecom */
     265                 :            :         /* Modular Technology */
     266                 :            :         /* Rockwell 33.6 DPF External PnP */
     267                 :            :         /* BT Prologue 33.6 External PnP */
     268                 :            :         /* Modular Technology 33.6 External PnP */
     269                 :            :         {       "RSS00A0",            0       },
     270                 :            :         /* Viking 56K FAX INT */
     271                 :            :         {       "RSS0262",            0       },
     272                 :            :         /* K56 par,VV,Voice,Speakphone,AudioSpan,PnP */
     273                 :            :         {       "RSS0250",              0       },
     274                 :            :         /* SupraExpress 28.8 Data/Fax PnP modem */
     275                 :            :         {       "SUP1310",            0       },
     276                 :            :         /* SupraExpress 336i PnP Voice Modem */
     277                 :            :         {       "SUP1381",            0       },
     278                 :            :         /* SupraExpress 33.6 Data/Fax PnP modem */
     279                 :            :         {       "SUP1421",            0       },
     280                 :            :         /* SupraExpress 33.6 Data/Fax PnP modem */
     281                 :            :         {       "SUP1590",            0       },
     282                 :            :         /* SupraExpress 336i Sp ASVD */
     283                 :            :         {       "SUP1620",            0       },
     284                 :            :         /* SupraExpress 33.6 Data/Fax PnP modem */
     285                 :            :         {       "SUP1760",            0       },
     286                 :            :         /* SupraExpress 56i Sp Intl */
     287                 :            :         {       "SUP2171",            0       },
     288                 :            :         /* Phoebe Micro */
     289                 :            :         /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
     290                 :            :         {       "TEX0011",            0       },
     291                 :            :         /* Archtek America Corp. */
     292                 :            :         /* Archtek SmartLink Modem 3334BT Plug & Play */
     293                 :            :         {       "UAC000F",            0       },
     294                 :            :         /* 3Com Corp. */
     295                 :            :         /* Gateway Telepath IIvi 33.6 */
     296                 :            :         {       "USR0000",            0       },
     297                 :            :         /* U.S. Robotics Sporster 33.6K Fax INT PnP */
     298                 :            :         {       "USR0002",            0       },
     299                 :            :         /*  Sportster Vi 14.4 PnP FAX Voicemail */
     300                 :            :         {       "USR0004",            0       },
     301                 :            :         /* U.S. Robotics 33.6K Voice INT PnP */
     302                 :            :         {       "USR0006",            0       },
     303                 :            :         /* U.S. Robotics 33.6K Voice EXT PnP */
     304                 :            :         {       "USR0007",            0       },
     305                 :            :         /* U.S. Robotics Courier V.Everything INT PnP */
     306                 :            :         {       "USR0009",            0       },
     307                 :            :         /* U.S. Robotics 33.6K Voice INT PnP */
     308                 :            :         {       "USR2002",            0       },
     309                 :            :         /* U.S. Robotics 56K Voice INT PnP */
     310                 :            :         {       "USR2070",            0       },
     311                 :            :         /* U.S. Robotics 56K Voice EXT PnP */
     312                 :            :         {       "USR2080",            0       },
     313                 :            :         /* U.S. Robotics 56K FAX INT */
     314                 :            :         {       "USR3031",            0       },
     315                 :            :         /* U.S. Robotics 56K FAX INT */
     316                 :            :         {       "USR3050",            0       },
     317                 :            :         /* U.S. Robotics 56K Voice INT PnP */
     318                 :            :         {       "USR3070",            0       },
     319                 :            :         /* U.S. Robotics 56K Voice EXT PnP */
     320                 :            :         {       "USR3080",            0       },
     321                 :            :         /* U.S. Robotics 56K Voice INT PnP */
     322                 :            :         {       "USR3090",            0       },
     323                 :            :         /* U.S. Robotics 56K Message  */
     324                 :            :         {       "USR9100",            0       },
     325                 :            :         /* U.S. Robotics 56K FAX EXT PnP*/
     326                 :            :         {       "USR9160",            0       },
     327                 :            :         /* U.S. Robotics 56K FAX INT PnP*/
     328                 :            :         {       "USR9170",            0       },
     329                 :            :         /* U.S. Robotics 56K Voice EXT PnP*/
     330                 :            :         {       "USR9180",            0       },
     331                 :            :         /* U.S. Robotics 56K Voice INT PnP*/
     332                 :            :         {       "USR9190",            0       },
     333                 :            :         /* Wacom tablets */
     334                 :            :         {       "WACFXXX",            0       },
     335                 :            :         /* Compaq touchscreen */
     336                 :            :         {       "FPI2002",              0 },
     337                 :            :         /* Fujitsu Stylistic touchscreens */
     338                 :            :         {       "FUJ02B2",              0 },
     339                 :            :         {       "FUJ02B3",              0 },
     340                 :            :         /* Fujitsu Stylistic LT touchscreens */
     341                 :            :         {       "FUJ02B4",              0 },
     342                 :            :         /* Passive Fujitsu Stylistic touchscreens */
     343                 :            :         {       "FUJ02B6",              0 },
     344                 :            :         {       "FUJ02B7",              0 },
     345                 :            :         {       "FUJ02B8",              0 },
     346                 :            :         {       "FUJ02B9",              0 },
     347                 :            :         {       "FUJ02BC",              0 },
     348                 :            :         /* Fujitsu Wacom Tablet PC device */
     349                 :            :         {       "FUJ02E5",            0       },
     350                 :            :         /* Fujitsu P-series tablet PC device */
     351                 :            :         {       "FUJ02E6",            0       },
     352                 :            :         /* Fujitsu Wacom 2FGT Tablet PC device */
     353                 :            :         {       "FUJ02E7",            0       },
     354                 :            :         /* Fujitsu Wacom 1FGT Tablet PC device */
     355                 :            :         {       "FUJ02E9",            0       },
     356                 :            :         /*
     357                 :            :          * LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6
     358                 :            :          * in disguise).
     359                 :            :          */
     360                 :            :         {       "LTS0001",            0       },
     361                 :            :         /* Rockwell's (PORALiNK) 33600 INT PNP */
     362                 :            :         {       "WCI0003",            0       },
     363                 :            :         /* Unknown PnP modems */
     364                 :            :         {       "PNPCXXX",            UNKNOWN_DEV     },
     365                 :            :         /* More unknown PnP modems */
     366                 :            :         {       "PNPDXXX",            UNKNOWN_DEV     },
     367                 :            :         /*
     368                 :            :          * Winbond CIR port, should not be probed. We should keep track of
     369                 :            :          * it to prevent the legacy serial driver from probing it.
     370                 :            :          */
     371                 :            :         {       "WEC1022",            CIR_PORT        },
     372                 :            :         /*
     373                 :            :          * SMSC IrCC SIR/FIR port, should not be probed by serial driver as
     374                 :            :          * well so its own driver can bind to it.
     375                 :            :          */
     376                 :            :         {       "SMCF010",            CIR_PORT        },
     377                 :            :         {       "",                   0       }
     378                 :            : };
     379                 :            : 
     380                 :            : MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
     381                 :            : 
     382                 :            : static const char *modem_names[] = {
     383                 :            :         "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
     384                 :            :         "56K", "56k", "K56", "33.6", "28.8", "14.4",
     385                 :            :         "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
     386                 :            :         "33600", "28800", "14400", "V.90", "V.34", "V.32", NULL
     387                 :            : };
     388                 :            : 
     389                 :          0 : static bool check_name(const char *name)
     390                 :            : {
     391                 :          0 :         const char **tmp;
     392                 :            : 
     393   [ #  #  #  # ]:          0 :         for (tmp = modem_names; *tmp; tmp++)
     394   [ #  #  #  # ]:          0 :                 if (strstr(name, *tmp))
     395                 :            :                         return true;
     396                 :            : 
     397                 :            :         return false;
     398                 :            : }
     399                 :            : 
     400                 :          0 : static bool check_resources(struct pnp_dev *dev)
     401                 :            : {
     402                 :          0 :         static const resource_size_t base[] = {0x2f8, 0x3f8, 0x2e8, 0x3e8};
     403                 :          0 :         unsigned int i;
     404                 :            : 
     405         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(base); i++) {
     406         [ #  # ]:          0 :                 if (pnp_possible_config(dev, IORESOURCE_IO, base[i], 8))
     407                 :            :                         return true;
     408                 :            :         }
     409                 :            : 
     410                 :            :         return false;
     411                 :            : }
     412                 :            : 
     413                 :            : /*
     414                 :            :  * Given a complete unknown PnP device, try to use some heuristics to
     415                 :            :  * detect modems. Currently use such heuristic set:
     416                 :            :  *     - dev->name or dev->bus->name must contain "modem" substring;
     417                 :            :  *     - device must have only one IO region (8 byte long) with base address
     418                 :            :  *       0x2e8, 0x3e8, 0x2f8 or 0x3f8.
     419                 :            :  *
     420                 :            :  * Such detection looks very ugly, but can detect at least some of numerous
     421                 :            :  * PnP modems, alternatively we must hardcode all modems in pnp_devices[]
     422                 :            :  * table.
     423                 :            :  */
     424                 :          0 : static int serial_pnp_guess_board(struct pnp_dev *dev)
     425                 :            : {
     426         [ #  # ]:          0 :         if (!(check_name(pnp_dev_name(dev)) ||
     427   [ #  #  #  # ]:          0 :             (dev->card && check_name(dev->card->name))))
     428                 :            :                 return -ENODEV;
     429                 :            : 
     430         [ #  # ]:          0 :         if (check_resources(dev))
     431                 :          0 :                 return 0;
     432                 :            : 
     433                 :            :         return -ENODEV;
     434                 :            : }
     435                 :            : 
     436                 :            : static int
     437                 :          3 : serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
     438                 :            : {
     439                 :          3 :         struct uart_8250_port uart, *port;
     440                 :          3 :         int ret, line, flags = dev_id->driver_data;
     441                 :            : 
     442         [ -  + ]:          3 :         if (flags & UNKNOWN_DEV) {
     443                 :          0 :                 ret = serial_pnp_guess_board(dev);
     444         [ #  # ]:          0 :                 if (ret < 0)
     445                 :            :                         return ret;
     446                 :            :         }
     447                 :            : 
     448                 :          3 :         memset(&uart, 0, sizeof(uart));
     449                 :          3 :         if (pnp_irq_valid(dev, 0))
     450                 :          6 :                 uart.port.irq = pnp_irq(dev, 0);
     451         [ -  + ]:          3 :         if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) {
     452                 :          0 :                 uart.port.iobase = pnp_port_start(dev, 2);
     453                 :          0 :                 uart.port.iotype = UPIO_PORT;
     454                 :          3 :         } else if (pnp_port_valid(dev, 0)) {
     455                 :          3 :                 uart.port.iobase = pnp_port_start(dev, 0);
     456                 :          3 :                 uart.port.iotype = UPIO_PORT;
     457                 :          0 :         } else if (pnp_mem_valid(dev, 0)) {
     458                 :          0 :                 uart.port.mapbase = pnp_mem_start(dev, 0);
     459                 :          0 :                 uart.port.iotype = UPIO_MEM;
     460                 :          0 :                 uart.port.flags = UPF_IOREMAP;
     461                 :            :         } else
     462                 :            :                 return -ENODEV;
     463                 :            : 
     464                 :          3 :         dev_dbg(&dev->dev,
     465                 :            :                  "Setup PNP port: port %#lx, mem %#llx, irq %u, type %u\n",
     466                 :            :                  uart.port.iobase, (unsigned long long)uart.port.mapbase,
     467                 :            :                  uart.port.irq, uart.port.iotype);
     468                 :            : 
     469         [ -  + ]:          3 :         if (flags & CIR_PORT) {
     470                 :          0 :                 uart.port.flags |= UPF_FIXED_PORT | UPF_FIXED_TYPE;
     471                 :          0 :                 uart.port.type = PORT_8250_CIR;
     472                 :            :         }
     473                 :            : 
     474                 :          3 :         uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
     475         [ -  + ]:          6 :         if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
     476                 :          0 :                 uart.port.flags |= UPF_SHARE_IRQ;
     477                 :          3 :         uart.port.uartclk = 1843200;
     478                 :          3 :         uart.port.dev = &dev->dev;
     479                 :            : 
     480                 :          3 :         line = serial8250_register_8250_port(&uart);
     481   [ +  -  +  - ]:          3 :         if (line < 0 || (flags & CIR_PORT))
     482                 :            :                 return -ENODEV;
     483                 :            : 
     484                 :          3 :         port = serial8250_get_port(line);
     485   [ +  -  +  - ]:          3 :         if (uart_console(&port->port))
     486                 :          3 :                 dev->capabilities |= PNP_CONSOLE;
     487                 :            : 
     488                 :          3 :         pnp_set_drvdata(dev, (void *)((long)line + 1));
     489                 :          3 :         return 0;
     490                 :            : }
     491                 :            : 
     492                 :          0 : static void serial_pnp_remove(struct pnp_dev *dev)
     493                 :            : {
     494         [ #  # ]:          0 :         long line = (long)pnp_get_drvdata(dev);
     495                 :            : 
     496                 :          0 :         dev->capabilities &= ~PNP_CONSOLE;
     497         [ #  # ]:          0 :         if (line)
     498                 :          0 :                 serial8250_unregister_port(line - 1);
     499                 :          0 : }
     500                 :            : 
     501                 :          0 : static int __maybe_unused serial_pnp_suspend(struct device *dev)
     502                 :            : {
     503         [ #  # ]:          0 :         long line = (long)dev_get_drvdata(dev);
     504                 :            : 
     505         [ #  # ]:          0 :         if (!line)
     506                 :            :                 return -ENODEV;
     507                 :          0 :         serial8250_suspend_port(line - 1);
     508                 :          0 :         return 0;
     509                 :            : }
     510                 :            : 
     511                 :          0 : static int __maybe_unused serial_pnp_resume(struct device *dev)
     512                 :            : {
     513         [ #  # ]:          0 :         long line = (long)dev_get_drvdata(dev);
     514                 :            : 
     515         [ #  # ]:          0 :         if (!line)
     516                 :            :                 return -ENODEV;
     517                 :          0 :         serial8250_resume_port(line - 1);
     518                 :          0 :         return 0;
     519                 :            : }
     520                 :            : 
     521                 :            : static SIMPLE_DEV_PM_OPS(serial_pnp_pm_ops, serial_pnp_suspend, serial_pnp_resume);
     522                 :            : 
     523                 :            : static struct pnp_driver serial_pnp_driver = {
     524                 :            :         .name           = "serial",
     525                 :            :         .probe          = serial_pnp_probe,
     526                 :            :         .remove         = serial_pnp_remove,
     527                 :            :         .driver         = {
     528                 :            :                 .pm     = &serial_pnp_pm_ops,
     529                 :            :         },
     530                 :            :         .id_table       = pnp_dev_table,
     531                 :            : };
     532                 :            : 
     533                 :          3 : int serial8250_pnp_init(void)
     534                 :            : {
     535                 :          3 :         return pnp_register_driver(&serial_pnp_driver);
     536                 :            : }
     537                 :            : 
     538                 :          0 : void serial8250_pnp_exit(void)
     539                 :            : {
     540                 :          0 :         pnp_unregister_driver(&serial_pnp_driver);
     541                 :          0 : }
     542                 :            : 

Generated by: LCOV version 1.14