| PCMCIA(9) | Kernel Developer's Manual | PCMCIA(9) |
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
#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);
The machine-independent PCMCIA subsystem
provides support for PC-Card devices defined by the Personal Computer Memory
Card International Association (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.
Drivers attached to the PCMCIA bus will
make use of the following data types:
char *cis1_info[4];
int32_t manufacturer;
int32_t product;
uint16_t error;
SIMPLEQ_HEAD(, pcmcia_function) pf_head;
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;
int32_t manufacturer; int32_t product; struct pcmcia_card *card; struct pcmcia_function *pf;
pcmcia_function_init(pf,
cfe)PCMCIA state
with the config entry cfe.pcmcia_function_enable(pf)pcmcia_function_disable(pf)pcmcia_io_alloc(pf,
start, size,
align, pciop)pcmcia_io_free(pf,
pcihp)pcmcia_io_map(pf,
width, pcihp,
windowp)A handle for the mapped I/O window is returned in windowp.
pcmcia_io_unmap(pf,
window)pcmcia_mem_alloc(pf,
size, pcmhp)pcmcia_mem_free(pf,
pcmhp)pcmcia_mem_map(pf,
width, card_addr,
size, pcmhp,
offsetp, windowp)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)pcmcia_intr_establish(pf,
level, handler,
arg)pcmcia_intr_establish() returns an opaque
handle to an event descriptor if it succeeds, and returns NULL on
failure.pcmcia_intr_disestablish(pf,
ih)pcmcia_intr_establish().pcmcia_cis_read_1(tuple,
index)pcmcia_cis_read_2(tuple,
index)pcmcia_cis_read_3(tuple,
index)pcmcia_cis_read_4(tuple,
index)pcmcia_cis_read_n(tuple,
number, index)pcmcia_scan_cis(dev,
func, arg)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.
PCMCIA devices do not support DMA.
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.
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.
The machine-independent PCMCIA subsystem appeared in NetBSD 1.3.
| April 15, 2010 | NetBSD 11.0 |