Linux PCMCIA support is highly dependent on kernel versions. If you upgrade your kernel, you almost certainly need to upgrade your PCMCIA drivers and tools.
Although some of the core PCMCIA drivers are in the main Linux kernel distribution, you still need the pcmcia-cs package for additional drivers and system utilities. The components of the PCMCIA system include the following:
Kernel modules for PC Card interface controllers and individual PC Cards. These modules go in /lib/modules/version/pcmcia.
The /sbin/cardmgr daemon for managing configuration when you insert or remove a card.
Various support utilities and services, located in /etc/pcmcia and /sbin.
There are too many pieces of the system to set up and configure by hand, so the pcmcia-cs package provides several scripts to get you on your way. The most important of these is an init.d script called pcmcia, where, depending on your distribution, you may need to modify a few lines to specify which PCMCIA interface controller chipset you have. Look at this section:
# Source PCMCIA configuration, if available if [ -f /etc/pcmcia.conf ] ; then # Debian startup option file . /etc/pcmcia.conf elif [ -f /etc/sysconfig/pcmcia ] ; then # Red Hat startup option file . /etc/sysconfig/pcmcia else # Slackware startup options go right here: # Should be either i82365 or tcic PCIC=i82365 # Put socket driver timing parameters here PCIC_OPTS= # Put pcmcia_core options here CORE_OPTS= # Put cardmgr options here CARDMGR_OPTS= # To set the PCMCIA scheme at startup... SCHEME= fi
The mention of specific Linux distributions may seem confusing, so step back and recall your shell script essentials from Chapter 7. The script does the following checks and actions:
If /etc/pcmcia.conf exists, the script reads configuration details from there and skips past the fi. This is probably the case if you're running Debian GNU/Linux.
If step 1 fails, the script looks for /etc/sysconfig/pcmcia, which is the location of the pcmcia file in Red Hat Linux.
If steps 1 and 2 both fail, the script directly sets PCIC, PCIC_OPTS, and so on. Note that this may apply to distributions other than Slackware Linux.
To get cardmgr talking to your PCMCIA interface controller, you should only need to set the PCIC variable. Check through your init.d and /etc files to find the file in which you need to set this variable (every distribution is different, so using grep PCIC may come in handy). If you don't know what sort of hardware you have, there is a pcic_probe program that comes with the pcmcia-cs source code that can help you. The value of PCIC should match one of the module filenames in /lib/modules/version/pcmcia; it's typically something like i82365 or tcic.
With the correct PCIC setting in place, you can manually load the interface controller driver and start cardmgr with this command:
However, because pcmcia is an init.d script, you should create rc.d links to start and stop the PCMCIA services at boot and shutdown time (refer back to Section 3.1 if you're a little hazy on this process).
The cardmgr program reads configuration data and activates scripts in /etc/pcmcia in response to cards being inserted and removed. The central card configuration database is /etc/pcmcia/config.
When you insert a PC Card, cardmgr does the following:
It reads the device identifier information from the PC Card.
It looks up the identifier in /etc/pcmcia/config, retrieving the kernel module name that contains the device driver.
It matches the kernel module name with a class name in /etc/pcmcia/config.
It loads the kernel module(s) and configures the PC Card with respect to the local options in /etc/pcmcia/config.opts.
It runs a class script located in the /etc/pcmcia directory, corresponding to the class name it found in /etc/pcmcia/config.
Let's look at the /etc/pcmcia directory in more detail. Each kernel module has one or more matching PC Card definitions in the /etc/pcmcia/config file. For example, here is an entry that matches the 3c589_cs module against its vendor and version identifier strings:
card "Lucent Technologies WaveLAN Adapter" version "Lucent Technologies", "WaveLAN/PCMCIA" bind "wavelan_cs"
The bind in the last line means to bind the card definition to one or more kernel modules. However, the card definition does not always specify that version of the hardware. cardmgr can also identify the appropriate kernel module by using other hardware criteria, including the function parameter, as in this example:
card "ATA/IDE Fixed Disk" function fixed_disk bind "ide_cs"
Well-defined device interfaces such as disks, serial ports (modems), and flash memory usually have a function parameter, but don't expect this from all devices. In particular, Ethernet cards usually don't have a function parameter. You may also see manual device-identifier matches that use the manfid keyword.
Having identified the necessary kernel module(s), cardmgr then looks for the device driver module class, which are found in the first part of /etc/pcmcia/config. Here is a sample definition that maps wavelan_cs to the network driver class:
device "wavelan_cs" class "network" module "wavelan_cs"
Each driver class has a script in /etc/pcmcia that cardmgr runs after loading and configuring a card's module (you'll see more about class scripts shortly).
You should not modify /etc/pcmcia/config; instead, enter your local configuration data in /etc/pcmcia/config.opts (cardmgr usually reads this file after config). For the most part, the PCMCIA utilities should work fine with the default settings, but the machine-and card-specific options in config.opts are at your disposal if your hardware just won't behave.
Of particular interest are the exclude and include keywords that enable you to manually specify IRQs and addresses. For example, you will see the following lines to prevent cardmgr from using standard IRQs, regardless of what the kernel may say about their availability:
# First built-in serial port exclude irq 4 # First built-in parallel port exclude irq 7
You can specify per-module options with the module keyword. These examples are also from the default config.opts file:
module "ray_cs" opts "net_type=1 essid=ESSID1" module "wvlan_cs" opts "station_name=MY_PC"
In normal circumstances, you do not configure wireless options with config.opts, but rather, with iwconfig and possibly /etc/pcmcia/wireless.opts (see Section 5.15 for more information).
Each driver class has a script in /etc/pcmcia. For example, the /etc/pcmcia/ network script corresponds to the network class mentioned earlier. cardmgr runs the class script after loading and configuring a card's module.
The /etc/pcmcia configuration scripts work like init.d boot scripts, taking an argument to start, stop, reload, or perform other actions:
start Activates the device upon card insertion
stop Deactivates the device upon card removal
restart Reinitializes the device
check Verifies the device
suspend Deactivates a card, but leaves the driver running
resume Picks up at the point where suspend left off, if possible
Just because a script exists in /etc/pcmcia doesn't mean that it actually works. These scripts run through several combinations of distribution-specific configuration files, trying to find the right settings. If your PC Card doesn't auto-configure correctly upon insertion, you may need to modify one of the scripts or its corresponding .opts configuration file.
You may find it easiest to write your own driver class scripts or modify the existing ones, but remember to make a backup of any script you decide to change. Reinstalling the pcmcia-cs package overwrites each script in /etc/pcmcia (leaving a backup with a .O extension). The .opts configuration files remain in place during a reinstall.
You should not normally need to call one of the /etc/pcmcia scripts by hand. cardmgr and cardctl (discussed next) do this for you.
The cardctl utility enables you to alter card settings and display information about cards and sockets. For example, you can view PC Card identifiers with this command:
runas cardctl ident
The output looks similar to this:
Socket 0: product info: "Lucent Technologies", "WaveLAN/IEEE", "Version 01.01", "" manfid: 0x0156, 0x0002 function: 6 (network)
Notice how this information relates to the configuration data in /etc/pcmcia/config.
Here are some other cardctl commands:
config Shows detailed low-level hardware settings.
status Displays card or socket status.
eject socket Shuts down the card in socket (use ident to identify the socket number). You should run eject on certain cards, such as SCSI cards and other interfaces that take a long time to initialize, before removing them.
insert socket Tells any relevant drivers that you just put a card into socket. Like eject, this is not necessary for most cards.
suspend socket Attempts to freeze the driver for socket and cut the power.
resume socket Attempts to recover from a suspend operation.
reset socket Resets the card in socket.
There are a few more complex options for cards that need to operate in multiple environments (schemes); see the cardctl(8) manual page and the PCMCIA-HOWTO for more information.
Most pcmcia-cs builds also come with cardinfo, a GUI display of the PCMCIA configuration. You may prefer to run this application in place of information commands such as cardctl status.