.\" $NetBSD: pcmcia.9,v 1.22 2018/02/11 14:17:24 wiz Exp $
.\"
.\" Copyright (c) 2001 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Gregory McGarry.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd April 15, 2010
.Dt PCMCIA 9
.Os
.Sh NAME
.Nm PCMCIA ,
.Nm pcmcia_function_init ,
.Nm pcmcia_function_enable ,
.Nm pcmcia_function_disable ,
.Nm pcmcia_io_alloc ,
.Nm pcmcia_io_free ,
.Nm pcmcia_io_map ,
.Nm pcmcia_io_unmap ,
.Nm pcmcia_mem_alloc ,
.Nm pcmcia_mem_free ,
.Nm pcmcia_mem_map ,
.Nm pcmcia_mem_unmap ,
.Nm pcmcia_intr_establish ,
.Nm pcmcia_intr_disestablish ,
.Nm pcmcia_cis_read_1 ,
.Nm pcmcia_cis_read_2 ,
.Nm pcmcia_cis_read_3 ,
.Nm pcmcia_cis_read_4 ,
.Nm pcmcia_cis_read_n ,
.Nm pcmcia_scan_cis
.Nd support for PCMCIA PC-Card devices
.Sh SYNOPSIS
.In sys/bus.h
.In dev/pcmcia/pcmciareg.h
.In dev/pcmcia/pcmciavar.h
.In dev/pcmcia/pcmciadevs.h
.Ft void
.Fn pcmcia_function_init "struct pcmcia_function *pf" \
"struct pcmcia_config_entry *cfe"
.Ft int
.Fn pcmcia_function_enable "struct pcmcia_function *pf"
.Ft void
.Fn pcmcia_function_disable "struct pcmcia_function *pf"
.Ft int
.Fn pcmcia_io_alloc "struct pcmcia_function *pf" "bus_addr_t start" \
"bus_size_t size" "bus_size_t align" "struct pcmcia_io_handle *pciop"
.Ft void
.Fn pcmcia_io_free "struct pcmcia_function *pf" \
"struct pcmcia_io_handle *pcihp"
.Ft int
.Fn pcmcia_io_map "struct pcmcia_function *pf" "int width" \
"struct pcmcia_io_handle *pcihp" "int *windowp"
.Ft void
.Fn pcmcia_io_unmap "struct pcmcia_function *pf" "int window"
.Ft int
.Fn pcmcia_mem_alloc "struct pcmcia_function *pf" "bus_size_t size" \
"struct pcmcia_mem_handle *pcmhp"
.Ft void
.Fn pcmcia_mem_free "struct pcmcia_function *pf" \
"struct pcmcia_mem_handle *pcmhp"
.Ft int
.Fn 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"
.Ft void
.Fn pcmcia_mem_unmap "struct pcmcia_function *pf" "int window"
.Ft void *
.Fn pcmcia_intr_establish "struct pcmcia_function *pf" "int level" \
"int (*handler)(void *)" "void *arg"
.Ft void
.Fn pcmcia_intr_disestablish "struct pcmcia_function *pf" "void *ih"
.Ft uint8_t
.Fn pcmcia_cis_read_1 "struct pcmcia_tuple *tuple" "int index"
.Ft uint16_t
.Fn pcmcia_cis_read_2 "struct pcmcia_tuple *tuple" "int index"
.Ft uint32_t
.Fn pcmcia_cis_read_3 "struct pcmcia_tuple *tuple" "int index"
.Ft uint32_t
.Fn pcmcia_cis_read_4 "struct pcmcia_tuple *tuple" "int index"
.Ft uint32_t
.Fn pcmcia_cis_read_n "struct pcmcia_tuple *tuple" "int number" "int index"
.Ft int
.Fn pcmcia_scan_cis "struct device *dev" \
"int (*func)(struct pcmcia_tuple *, void *)" "void *arg"
.Sh DESCRIPTION
The machine-independent
.Nm
subsystem provides support for PC-Card devices defined by the Personal
Computer Memory Card International Association (PCMCIA).
The
.Nm
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.
.Pp
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.
.Pp
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.
.Pp
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.
.Pp
PCMCIA devices do not support DMA, however memory on the device can be
mapped into the address space of the host.
.Sh DATA TYPES
Drivers attached to the
.Nm
bus will make use of the following data types:
.Bl -tag -width compact
.It Fa struct pcmcia_card
Devices (cards) have their identity recorded in this structure.
It contains the following members:
.Bd -literal
char *cis1_info[4];
int32_t manufacturer;
int32_t product;
uint16_t error;
SIMPLEQ_HEAD(, pcmcia_function) pf_head;
.Ed
.It Fa 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.
.It struct pcmcia_config_entry
Contains information about the resources requested by the device.
It contains the following members:
.Bd -literal
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;
.Ed
.It Fa struct pcmcia_tuple
A handle for identifying an entry in the CIS.
.It Fa 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.
.It Fa struct pcmcia_mem_handle
A handle for mapping and allocating memory address spaces.
It contains the tag and handle for accessing the bus-space.
.It Fa struct pcmcia_attach_args
A structure used to inform the driver of the
device properties.
It contains the following members:
.Bd -literal
int32_t manufacturer;
int32_t product;
struct pcmcia_card *card;
struct pcmcia_function *pf;
.Ed
.El
.Sh FUNCTIONS
.Bl -tag -width compact
.It Fn pcmcia_function_init "pf" "cfe"
Initialise the machine-independent
.Nm
state with the config entry
.Fa cfe .
.It Fn pcmcia_function_enable "pf"
Provide power to the socket containing the device specified by
device function
.Fa pf .
.It Fn pcmcia_function_disable "pf"
Remove power from the socket containing the device specified by
device function
.Fa pf .
.It Fn pcmcia_io_alloc "pf" "start" "size" "align" "pciop"
Request I/O space for device function
.Fa pf
at address
.Fa start
of size
.Fa size .
Alignment is specified by
.Fa align .
A handle for the I/O space is returned in
.Fa pciop .
.It Fn pcmcia_io_free "pf" "pcihp"
Release I/O space with handle
.Fa pcihp
for device function
.Fa pf .
.It Fn pcmcia_io_map "pf" "width" "pcihp" "windowp"
Map device I/O for device function
.Fa pf
to the I/O space with handle
.Fa pcihp .
The width of data access is specified by
.Fa width .
Valid values for the width are:
.Bl -tag -width PCMCIA_WIDTH_AUTO
.It PCMCIA_WIDTH_AUTO
Use the largest I/O width reported by the device.
.It PCMCIA_WIDTH_IO8
Force 8-bit I/O width.
.It PCMCIA_WIDTH_IO16
Force 16-bit I/O width.
.El
.Pp
A handle for the mapped I/O window is returned in
.Fa windowp .
.It Fn pcmcia_io_unmap "pf" "window"
Unmap the I/O window
.Fa window
for device function
.Fa pf .
.It Fn pcmcia_mem_alloc "pf" "size" "pcmhp"
Request memory space for device function
.Fa pf
of size
.Fa size .
A handle for the memory space is returned in
.Fa pcmhp .
.It Fn pcmcia_mem_free "pf" "pcmhp"
Release memory space with handle
.Fa pcmhp
for device function
.Fa pf .
.It Fn pcmcia_mem_map "pf" "width" "card_addr" "size" "pcmhp" "offsetp" \
"windowp"
Map device memory for device function
.Fa pf
to the memory space with handle
.Fa pcmhp .
The address of the device memory starts at
.Fa card_addr
and is size
.Fa size .
The width of data access is specified by
.Fa width .
Valid values for the width are:
.Bl -tag -width PCMCIA_WIDTH_MEM16
.It PCMCIA_WIDTH_MEM8
Force 8-bit memory width.
.It PCMCIA_WIDTH_MEM16
Force 16-bit memory width.
.El
.Pp
A handle for the mapped memory window is returned in
.Fa windowp
and a bus-space offset into the memory window is returned in
.Fa offsetp .
.It Fn pcmcia_mem_unmap "pf" "window"
Unmap the memory window
.Fa window
for device function
.Fa pf .
.It Fn pcmcia_intr_establish "pf" "level" "handler" "arg"
Establish an interrupt handler for device function
.Fa pf .
The priority of the interrupt is specified by
.Fa level .
When the interrupt occurs the function
.Fa handler
is called with argument
.Fa arg .
The return value is a handle for the interrupt handler.
.Fn pcmcia_intr_establish
returns an opaque handle to an event descriptor if it succeeds, and
returns NULL on failure.
.It Fn pcmcia_intr_disestablish "pf" "ih"
Dis-establish the interrupt handler for device function
.Fa pf
with handle
.Fa ih .
The handle was returned from
.Fn pcmcia_intr_establish .
.It Fn pcmcia_cis_read_1 "tuple" "index"
Read one byte from tuple
.Fa tuple
at index
.Fa index
in the CIS.
.It Fn pcmcia_cis_read_2 "tuple" "index"
Read two bytes from tuple
.Fa tuple
at index
.Fa index
in the CIS.
.It Fn pcmcia_cis_read_3 "tuple" "index"
Read three bytes from tuple
.Fa tuple
at index
.Fa index
in the CIS.
.It Fn pcmcia_cis_read_4 "tuple" "index"
Read four bytes from tuple
.Fa tuple
at index
.Fa index
in the CIS.
.It Fn pcmcia_cis_read_n "tuple" "number" "index"
Read
.Fa n
bytes from tuple
.Fa tuple
at index
.Fa index
in the CIS.
.It Fn pcmcia_scan_cis "dev" "func" "arg"
Scan the CIS for device
.Fa dev .
For each tuple in the CIS, function
.Fa func
is called with the tuple and the argument
.Fa arg .
.Fa func
should return 0 if the tuple it was called with is the one it was
looking for, or 1 otherwise.
.El
.Sh AUTOCONFIGURATION
During autoconfiguration, a
.Nm
driver will receive a pointer to
.Fa struct pcmcia_attach_args
describing the device attached to the PCMCIA bus.
Drivers match the device using the
.Em manufacturer
and
.Em product
members.
.Pp
During the driver attach step, drivers will use the pcmcia function
.Em pf .
The driver should traverse the list of config entries searching for a
useful configuration.
This config entry is passed to
.Fn pcmcia_function_init
to initialise the machine-independent interface.
I/O and memory resources should be initialised using
.Fn pcmcia_io_alloc
and
.Fn pcmcia_mem_alloc
using the specified resources in the config entry.
These resources can then be mapped into processor bus space using
.Fn pcmcia_io_map
and
.Fn pcmcia_mem_map
respectively.
Upon successful allocation of resources, power can be applied to the
device with
.Fn pcmcia_function_enable
so that device-specific interrogation can be performed.
Finally, power should be removed from the device using
.Fn pcmcia_function_disable .
.Pp
Since PCMCIA devices support dynamic configuration, drivers should
make use of
.Xr pmf 9
framework.
Power can be applied and the interrupt handler should be established
through this interface.
.Sh DMA SUPPORT
PCMCIA devices do not support DMA.
.Sh CODE REFERENCES
The PCMCIA subsystem itself is implemented within the file
.Pa sys/dev/pcmcia/pcmcia.c .
The database of known devices exists within the file
.Pa sys/dev/pcmcia/pcmciadevs_data.h
and is generated automatically from the file
.Pa sys/dev/pcmcia/pcmciadevs .
New manufacturer and product identifiers should be added to this file.
The database can be regenerated using the Makefile
.Pa sys/dev/pcmcia/Makefile.pcmciadevs .
.Sh SEE ALSO
.Xr pcic 4 ,
.Xr pcmcia 4 ,
.Xr tcic 4 ,
.Xr autoconf 9 ,
.Xr bus_dma 9 ,
.Xr bus_space 9 ,
.Xr driver 9
.Rs
.%A Personal Computer Memory Card International Association (PCMCIA)
.%T "PC Card 95 Standard"
.%D 1995
.Re
.Sh HISTORY
The machine-independent PCMCIA subsystem appeared in
.Nx 1.3 .