.\" $NetBSD: pcmcia.9,v 1.3 2001/09/04 03:00:47 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the NetBSD .\" Foundation, Inc. and its contributors. .\" 4. Neither the name of The NetBSD Foundation nor the names of its .\" contributors may be used to endorse or promote products derived .\" from this software without specific prior written permission. .\" .\" 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 June 4, 2001 .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 PC-Card devices .Sh SYNOPSIS .Fd #include .Fd #include .Fd #include .Fd #include .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" \ "bus_addr_t offset" "bus_size_t size" "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_addr_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 u_int8_t .Fn pcmcia_cis_read_1 "struct pcmcia_tuple *tuple" "int index" .Ft u_int16_t .Fn pcmcia_cis_read_2 "struct pcmcia_tuple *tuple" "int index" .Ft u_int32_t .Fn pcmcia_cis_read_3 "struct pcmcia_tuple *tuple" "int index" .Ft u_int32_t .Fn pcmcia_cis_read_4 "struct pcmcia_tuple *tuple" "int index" .Ft u_int32_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 Assocation (PCMCIA). The .Nn 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 utilised 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 a 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; u_int16_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; u_int32_t flags; int iftype; int num_iospace; u_long iomask; struct { u_long length; u_long start; } iospace[4]; u_int16_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" "offset" "size" "pcihp" "windowp" Map device I/O for device function .Fa pf to the I/O space with handle .Fa pcihp . An I/O window of size .Fa size is mapped at offset .Fa offset in the chipset I/O window. 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 .sp 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 .sp A handle for the mapped memory window is returned in .Fa windowp and a bus-space handle for 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 .Fn powerhook_establish 9 . 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 This section describes places within the .Nx source tree where actual code implementing or utilising the machine-independent PCMCIA subsystem can be found. All pathnames are relative to .Pa /usr/src . .Pp 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 .Rs .%A Personal Computer Memory Card International Association (PCMCIA) .%T "PC Card 95 Standard" .%D 1995 .Re .sp .Xr pcic 4 , .Xr pcmcia 4 , .Xr tcic 4 , .Xr autoconf 9 , .Xr bus_dma 9 , .Xr bus_space 9 , .Xr driver 9 .Sh HISTORY The machine-independent PCMCIA subsystem appeared in .Nx 1.3 .