Step by step solutions to IT problems

Install a PNP modem in Linux

Installing a Plug-and-Play card in a modern linux distro is usually quite painless, but if something goes wrong, or if you are using an older distro, then configuring it manually may be the only option. We walk through the steps installing an old PNP modem in linux by hand, including configuring a dialup connection to your ISP.

Getting Started

A feature of some older plug-and-play cards is that they sometimes have jumpers on the card, to turn the PNP off, and pre-select an interrupt and IO range. That was the case with the US Robotics ISA modem I was installing an, jumpering the card, made installing and testing the card (to make sure it still actually worked) much easier, but I fancied a challenge, and wanted to get the card working under PNP.

The PC I was installing it in, was running an old linux distro (Slackware 8.1), and already had a plug-and-play ethernet card. This meant that as the ISA-PNP module was loaded by the network card's driver, I had a false sense of confidence that installing the modem would be easy.

To install and test a PNP modem you'll need to make sure you've installed

  • ISAPNP tools
  • Minicom (lets you send AT commands to the modem)
  • PPP tools and PPPD daemon.
Under slackware that works out as the following package,
  • a/isapnptools-1.26-i386-1.tgz
  • a/minicom-2.00.0-i386-1.tgz
  • n/ppp-2.4.1-i386-2.tgz
Obviously the package names and versions will be slightly different depending on what flavour and version of linux you're running.

Configuring Plug and Play

In order for Linux to be able to use the modem, we need to allocate it an Interrupt and IO address. To find out what settings the card wants run
pnpdump | less
First up, check that the card is even listed
# # Version 1.0, Vendor version 0.0
# ANSI string -->U.S. Robotics 56K Voice INT<--
If your card is not listed, then either it's not a pnp card, or it's not working, as linux can't see it.

The output of the pnpdump command needs to be saved to a config file (/etc/isapnp.conf) so it can be read by the isapnp command during startup. The config file should list all the available interrupts and memory addresses available to the card, and you just need to follow the instructions in the file, and choose a set of settings and then activate them. It's tempting to do this by hand, but then you too could spend the next two hours wondering why the card won't work. So the best option is to let the pnpdump command pick the best settings for your card with the command

pnpdump -c > /etc/isapnp.test

Now test the settings work with the command

isapnp /etc/isapnp.test
which should output something like
Board 1 has Identity 01 02 03 04:  USR9190 Serial No 01020304 [checksum 30]
USR9190/01020304[0]{U.S. Robotics 56K Voice INT}: Port 0x3F8; IRQ4 --- Enabled OK
The important bit is the Enabled OK at the end.

Now whilst isapnp looks like it has worked, you need to check that the settings have been taken by running

cat /proc/isapnp
which should output something like
Card 1 'USR9190:U.S. Robotics 56K Voice INT' PnP version 1.0
  Logical device 0 'USR9190:Unknown'
    Device is active
    Active port 0x3f8
    Active IRQ 4 [0x3]
where the most important line is the Device is active. If it doesn't say it's active, then the settings haven't stuck, and you will need to try differnt irq/io settings by editing the /etc/isapnp.test file.

Assuming it's worked, rename isapnp.test to isapnp.conf if there was not an existing isapnp.conf otherwise you'll need to combine the two files together. You then need to add the line

isapnp /etc/isapnp.conf
to a startup script if it doesn't already exist.

Configuring the serial port

Now that the ISA card is installed and the PNP is allocated and working, we need to tell Linux to configure the serial port. First off we need to find out what UART chip it has. Given the isapnp has allocated IRQ 4 and port 0x3f8, that means that the card is serial device /dev/ttyS0, so to check the UART type
setserial -v /dev/ttyS0 autoconfig
which should output something like
/dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4
Now we need to add the setserial command to a startup script to tell linux to configure the serial port and what uart it has. You can use
setserial -G /dev/ttyS0
to get the full parameters you can use for the setserial command, or to leave as much as possible as a default just use
setserial -v /dev/ttyS0 uart 16550A
which is probably the least you can get away with.

Testing the modem works

In order to test the modem works with the settings we've given it, and that it dials a number (ie the cable works) we will use minicom to send AT commands to the modem.

Firstly run minicom -o and configure the serial port and modem to match the settings you configured above, ensuring the port and speed are the same as configured by setserial, save the settings and restart minicom, and you should see something like

Welcome to minicom 2.00.0

OPTIONS: History Buffer, F-key Macros, Search History Buffer, I18n Compiled on Feb 24 2002, 14:58:54.

Press CTRL-A Z for help on special keys

AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0 OK

If the AT command is missing then that means that minicom couldn't talk to the modem, so check that the serial port and modem settings are correct, and you are using the correct ttyS port number.

When minicom is able to talk to the modem ok, try dialing a number, such as your mobile phone, and wait for it to ring. If your number is 0102 345678 then type into minicom

and you should hear the modem dialing, and then your phone ringing. The atdt assumes your telephone exchange supports tone dialing otherwise use atpt. Press enter to hangup the call before answering. If you get NO DIAL TONE then check the phone cable is plugged in ok, or try a different phone cable, as they are not all the same.

Configure a dialup connection

Once the modem is working and dialing ok, it is time to setup a dialup connection. In slackware the PPP package comes with a simple app pppsetup that configures everything you need, creating the /etc/ppp/options file and /etc/ppp/pppscript file that contains the dialer commands.

Things to remember are to add the atdt before the phone number, and that most modern ISPs use CHAP for authentication. If you don't want to have to sign up with an dialup ISP just to test the connection, then you may find some domain name registrars provide free dialup accounts that don't need you to register first as everybody uses the same username and password. It makes connecting when your broadband goes down much easier as there is no dialup account you need to keep active.

If you are using a different linux distro that doesn't use chat as it's dialer, then the following won't apply to you, and you will need to adjust it for whatever dialer your distro comes with.

The file /etc/ppp/pppscript is used by chat to talk to the modem and dial a connection, before the pppd takes over and uses the settings in /etc/ppp/options to make the tcpip connection to the ISP.

In order to get the connection speed reported back add REPORT CONNECT to your /etc/ppp/pppscript file, so it will look something like

"" "AT S7=45 S0=0 L1 V1 X4 &c1 E1 Q0"
OK "atdt0102345678"
Though your modem initialisation string may look different, I just use the one that minicom uses as I know minicom can dial a number.

If you don't want to have to pre-set the dns settings, as the pppsetup script requires then add usepeerdns to your /etc/ppp/options file, and then a /etc/ppp/resolve.conf file will be created when you connect, which you can get the script /etc/ppp/ip-up to copy to /etc/resolve.conf so you use the provided nameservers, rather than having to guess them. Obviously you'll want the /etc/ppp/ip-down script to copy back your original /etc/resolve.conf file, so your normal lan nameserver settings work. A sample /etc/ppp/options is listed below

# General configuration options for PPPD:
asyncmap 0
name "myisp"

So to go online just type

and you should hear the modem dialing, and then get the connection details back. Once connected make sure the connection and nameserver settings are working by pinging a host you know responds to pings such as To drop the connection just type ppp-off. These commands might be different if you use a different distro or if you use wvdial instead of chat to connect, but they should be similar enough to get it working.
Submit to    digg    reddit    simpy