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
)
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.
struct
pcmcia_card
char *cis1_info[4];
int32_t manufacturer;
int32_t product;
uint16_t error;
SIMPLEQ_HEAD(, pcmcia_function) pf_head;
struct
pcmcia_function
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
struct
pcmcia_io_handle
struct
pcmcia_mem_handle
struct
pcmcia_attach_args
int32_t manufacturer;
int32_t product;
struct pcmcia_card *card;
struct pcmcia_function *pf;
pf
, cfe
)
cfe
.
pf
)
pf
.
pf
)
pf
.
pf
, start
, size
, align
, pciop
)
pf
at address
start
of size
size
.
Alignment is specified by
align
.
A handle for the I/O space is returned in
pciop
.
pf
, pcihp
)
pcihp
for device function
pf
.
pf
, width
, pcihp
, windowp
)
pf
to the I/O space with handle
pcihp
.
The width of data access is specified by
width
.
Valid values for the width are:
windowp
.
pf
, window
)
window
for device function
pf
.
pf
, size
, pcmhp
)
pf
of size
size
.
A handle for the memory space is returned in
pcmhp
.
pf
, pcmhp
)
pcmhp
for device function
pf
.
pf
, width
, card_addr
, size
, pcmhp
, offsetp
, windowp
)
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:
windowp
and a bus-space offset into the memory window is returned in
offsetp
.
pf
, window
)
window
for device function
pf
.
pf
, level
, handler
, arg
)
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.
pf
, ih
)
pf
with handle
ih
.
The handle was returned from
pcmcia_intr_establish(
).
tuple
, index
)
tuple
at index
index
in the CIS.
tuple
, index
)
tuple
at index
index
in the CIS.
tuple
, index
)
tuple
at index
index
in the CIS.
tuple
, index
)
tuple
at index
index
in the CIS.
tuple
, number
, index
)
n
bytes from tuple
tuple
at index
index
in the CIS.
dev
, func
, arg
)
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.
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
powerhook_establish(9
).
Power can be applied and the interrupt handler should be established
through this interface.
/usr/src
.
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
.