NAME
PCMCIA pcmcia_function_init,
pcmcia_function_enable,
pcmcia_function_disable,
pcmcia_io_alloc,
pcmcia_io_free,
pcmcia_io_map,
pcmcia_io_unmap,
pcmcia_mem_alloc,
pcmcia_mem_free,
pcmcia_mem_map,
pcmcia_mem_unmap,
pcmcia_intr_establish,
pcmcia_intr_disestablish,
pcmcia_cis_read_1,
pcmcia_cis_read_2,
pcmcia_cis_read_3,
pcmcia_cis_read_4,
pcmcia_cis_read_n,
pcmcia_scan_cis —
support for PCMCIA PC-Card devices
SYNOPSIS
#include <sys/bus.h>
#include <dev/pcmcia/pcmciareg.h>
#include <dev/pcmcia/pcmciavar.h>
#include <dev/pcmcia/pcmciadevs.h>
void
pcmcia_function_init(
struct
pcmcia_function *pf,
struct
pcmcia_config_entry *cfe);
int
pcmcia_function_enable(
struct
pcmcia_function *pf);
void
pcmcia_function_disable(
struct
pcmcia_function *pf);
int
pcmcia_io_alloc(
struct
pcmcia_function *pf,
bus_addr_t start,
bus_size_t size,
bus_size_t align,
struct pcmcia_io_handle
*pciop);
void
pcmcia_io_free(
struct
pcmcia_function *pf,
struct
pcmcia_io_handle *pcihp);
int
pcmcia_io_map(
struct
pcmcia_function *pf,
int
width,
struct
pcmcia_io_handle *pcihp,
int *windowp);
void
pcmcia_io_unmap(
struct
pcmcia_function *pf,
int
window);
int
pcmcia_mem_alloc(
struct
pcmcia_function *pf,
bus_size_t size,
struct pcmcia_mem_handle
*pcmhp);
void
pcmcia_mem_free(
struct
pcmcia_function *pf,
struct
pcmcia_mem_handle *pcmhp);
int
pcmcia_mem_map(
struct
pcmcia_function *pf,
int
width,
bus_addr_t
card_addr,
bus_size_t
size,
struct
pcmcia_mem_handle *pcmhp,
bus_size_t *offsetp,
int *windowp);
void
pcmcia_mem_unmap(
struct
pcmcia_function *pf,
int
window);
void *
pcmcia_intr_establish(
struct
pcmcia_function *pf,
int
level,
int (*handler)(void
*),
void *arg);
void
pcmcia_intr_disestablish(
struct
pcmcia_function *pf,
void
*ih);
uint8_t
pcmcia_cis_read_1(
struct
pcmcia_tuple *tuple,
int
index);
uint16_t
pcmcia_cis_read_2(
struct
pcmcia_tuple *tuple,
int
index);
uint32_t
pcmcia_cis_read_3(
struct
pcmcia_tuple *tuple,
int
index);
uint32_t
pcmcia_cis_read_4(
struct
pcmcia_tuple *tuple,
int
index);
uint32_t
pcmcia_cis_read_n(
struct
pcmcia_tuple *tuple,
int
number,
int index);
int
pcmcia_scan_cis(
struct
device *dev,
int
(*func)(struct pcmcia_tuple *, void *),
void *arg);
DESCRIPTION
The machine-independent
PCMCIA subsystem provides support for
PC-Card devices defined by the Personal Computer Memory Card International
Assocation (PCMCIA). The
PCMCIA bus supports insertion and
removal of cards while a system is powered-on (ie, dynamic reconfiguration).
The socket must be powered-off when a card is not present. To the user, this
appears as though the socket is "hot" during insertion and removal
events.
A PCMCIA controller interfaces the PCMCIA bus with the ISA or PCI busses on the
host system. The controller is responsible for detecting and enabling devices
and for allocating and mapping resources such as memory and interrupts to
devices on the PCMCIA bus.
Each device has a table called the Card Information Structure (CIS) which
contains configuration information. The tuples in the CIS are used by the
controller to uniquely identify the device. Additional information may be
present in the CIS, such as the ethernet MAC address, that can be accessed and
used within a device driver.
Devices on the PCMCIA bus are uniquely identified by a 32-bit manufacturer ID
and a 32-bit product ID. Additionally, devices can perform multiple functions
(such as ethernet and modem) and these functions are identified by a function
ID.
PCMCIA devices do not support DMA, however memory on the device can be mapped
into the address space of the host.
DATA TYPES
Drivers attached to the
PCMCIA bus will make use of the
following data types:
-
-
- struct
pcmcia_card
- Devices (cards) have their identity recorded in this
structure. It contains the following members:
char *cis1_info[4];
int32_t manufacturer;
int32_t product;
uint16_t error;
SIMPLEQ_HEAD(, pcmcia_function) pf_head;
-
-
- struct
pcmcia_function
- Identifies the function of the devices. A device can have
multiple functions. Consider it an opaque type for identifying a
particular function of a device.
-
-
- struct
pcmcia_config_entry
- Contains information about the resources requested by the
device. It contains the following members:
int number;
uint32_t flags;
int iftype;
int num_iospace;
u_long iomask;
struct {
u_long length;
u_long start;
} iospace[4];
uint16_t irqmask;
int num_memspace;
struct {
u_long length;
u_long cardaddr;
u_long hostaddr;
} memspace[2];
int maxtwins;
SIMPLEQ_ENTRY(pcmcia_config_entry) cfe_list;
-
-
- struct
pcmcia_tuple
- A handle for identifying an entry in the CIS.
-
-
- struct
pcmcia_io_handle
- A handle for mapping and allocating I/O address spaces. It
contains the tag and handle for accessing the bus-space.
-
-
- struct
pcmcia_mem_handle
- A handle for mapping and allocating memory address spaces.
It contains the tag and handle for accessing the bus-space.
-
-
- struct
pcmcia_attach_args
- A structure used to inform the driver of the device
properties. It contains the following members:
int32_t manufacturer;
int32_t product;
struct pcmcia_card *card;
struct pcmcia_function *pf;
FUNCTIONS
-
-
- pcmcia_function_init(pf,
cfe)
- Initialise the machine-independent PCMCIA
state with the config entry cfe.
-
-
- pcmcia_function_enable(pf)
- Provide power to the socket containing the device specified
by device function pf.
-
-
- pcmcia_function_disable(pf)
- Remove power from the socket containing the device
specified by device function pf.
-
-
- pcmcia_io_alloc(pf,
start, size,
align, pciop)
- Request I/O space for device function
pf at address start of size
size. Alignment is specified by
align. A handle for the I/O space is returned in
pciop.
-
-
- pcmcia_io_free(pf,
pcihp)
- Release I/O space with handle pcihp
for device function pf.
-
-
- pcmcia_io_map(pf,
width, pcihp,
windowp)
- Map device I/O for device function pf
to the I/O space with handle pcihp. The width of
data access is specified by width. Valid values for
the width are:
-
-
- PCMCIA_WIDTH_AUTO
- Use the largest I/O width reported by the device.
-
-
- PCMCIA_WIDTH_IO8
- Force 8-bit I/O width.
-
-
- PCMCIA_WIDTH_IO16
- Force 16-bit I/O width.
A handle for the mapped I/O window is returned in
windowp.
-
-
- pcmcia_io_unmap(pf,
window)
- Unmap the I/O window window for
device function pf.
-
-
- pcmcia_mem_alloc(pf,
size, pcmhp)
- Request memory space for device function
pf of size size. A handle for
the memory space is returned in pcmhp.
-
-
- pcmcia_mem_free(pf,
pcmhp)
- Release memory space with handle
pcmhp for device function
pf.
-
-
- pcmcia_mem_map(pf,
width, card_addr,
size, pcmhp,
offsetp, windowp)
- Map device memory for device function
pf to the memory space with handle
pcmhp. The address of the device memory starts at
card_addr and is size size.
The width of data access is specified by width.
Valid values for the width are:
-
-
- PCMCIA_WIDTH_MEM8
- Force 8-bit memory width.
-
-
- PCMCIA_WIDTH_MEM16
- Force 16-bit memory width.
A handle for the mapped memory window is returned in
windowp and a bus-space offset into the memory
window is returned in offsetp.
-
-
- pcmcia_mem_unmap(pf,
window)
- Unmap the memory window window for
device function pf.
-
-
- pcmcia_intr_establish(pf,
level, handler,
arg)
- Establish an interrupt handler for device function
pf. The priority of the interrupt is specified by
level. When the interrupt occurs the function
handler is called with argument
arg. The return value is a handle for the interrupt
handler. pcmcia_intr_establish() returns an opaque
handle to an event descriptor if it succeeds, and returns NULL on
failure.
-
-
- pcmcia_intr_disestablish(pf,
ih)
- Dis-establish the interrupt handler for device function
pf with handle ih. The handle
was returned from pcmcia_intr_establish().
-
-
- pcmcia_cis_read_1(tuple,
index)
- Read one byte from tuple tuple at
index index in the CIS.
-
-
- pcmcia_cis_read_2(tuple,
index)
- Read two bytes from tuple tuple at
index index in the CIS.
-
-
- pcmcia_cis_read_3(tuple,
index)
- Read three bytes from tuple tuple at
index index in the CIS.
-
-
- pcmcia_cis_read_4(tuple,
index)
- Read four bytes from tuple tuple at
index index in the CIS.
-
-
- pcmcia_cis_read_n(tuple,
number, index)
- Read n bytes from tuple
tuple at index index in the
CIS.
-
-
- pcmcia_scan_cis(dev,
func, arg)
- Scan the CIS for device dev. For each
tuple in the CIS, function func is called with the
tuple and the argument arg.
func should return 0 if the tuple it was called with
is the one it was looking for, or 1 otherwise.
AUTOCONFIGURATION
During autoconfiguration, a
PCMCIA driver will receive a
pointer to
struct pcmcia_attach_args describing the
device attached to the PCMCIA bus. Drivers match the device using the
manufacturer and
product members.
During the driver attach step, drivers will use the pcmcia function
pf. The driver should traverse the list of config entries
searching for a useful configuration. This config entry is passed to
pcmcia_function_init() to initialise the machine-independent
interface. I/O and memory resources should be initialised using
pcmcia_io_alloc() and
pcmcia_mem_alloc()
using the specified resources in the config entry. These resources can then be
mapped into processor bus space using
pcmcia_io_map() and
pcmcia_mem_map() respectively. Upon successful allocation of
resources, power can be applied to the device with
pcmcia_function_enable() so that device-specific
interrogation can be performed. Finally, power should be removed from the
device using
pcmcia_function_disable().
Since PCMCIA devices support dynamic configuration, drivers should make use of
pmf(9) framework. Power can be
applied and the interrupt handler should be established through this
interface.
DMA SUPPORT
PCMCIA devices do not support DMA.
CODE REFERENCES
The PCMCIA subsystem itself is implemented within the file
sys/dev/pcmcia/pcmcia.c. The database of known devices
exists within the file
sys/dev/pcmcia/pcmciadevs_data.h and
is generated automatically from the file
sys/dev/pcmcia/pcmciadevs. New manufacturer and product
identifiers should be added to this file. The database can be regenerated
using the Makefile
sys/dev/pcmcia/Makefile.pcmciadevs.
SEE ALSO
pcic(4),
pcmcia(4),
tcic(4),
autoconf(9),
bus_dma(9),
bus_space(9),
driver(9)
Personal Computer Memory Card International
Association (PCMCIA), PC Card 95 Standard,
1995.
HISTORY
The machine-independent PCMCIA subsystem appeared in
NetBSD
1.3.