From 3aef805084f3d031ffbf02b8a00333a755c4677c Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 5 Jul 2007 12:08:54 +0000 Subject: [PATCH] Update cardbus/pccard support. The original patch was done by joerg@; I seemed to "maintain" it for quite a long time :P Obtained-from: FreeBSD Tested-by: many (intermittently tho) --- sys/bus/pccard/Makefile | 7 +- sys/bus/pccard/card_if.m | 94 +- sys/bus/pccard/cardinfo.h | 203 --- sys/bus/pccard/cis.h | 279 ---- sys/bus/pccard/driver.h | 25 - sys/bus/pccard/pccard.c | 498 +++--- sys/bus/pccard/pccard_beep.c | 140 -- sys/bus/pccard/pccard_cis.c | 173 +- sys/bus/pccard/{pccardreg.h => pccard_cis.h} | 180 +-- sys/bus/pccard/pccard_cis_quirks.c | 140 +- sys/bus/pccard/pccarddevs | 223 ++- sys/bus/pccard/pccarddevs.h | 381 +++-- sys/bus/pccard/pccardreg.h | 181 +-- sys/bus/pccard/pccardvar.h | 107 +- sys/bus/pccard/power_if.m | 6 +- sys/bus/pccard/slot.h | 136 -- sys/bus/pci/pci.c | 4 +- sys/conf/files | 5 +- sys/dev/disk/ata/ata-card.c | 5 +- sys/dev/disk/nata/ata-card.c | 5 +- sys/dev/disk/ncv/ncr53c500_pccard.c | 5 +- sys/dev/disk/nsp/nsp_pccard.c | 5 +- sys/dev/disk/stg/tmc18c30_pccard.c | 5 +- sys/dev/netif/cs/if_cs_isa.c | 3 +- sys/dev/netif/ed/if_ed_pccard.c | 14 +- sys/dev/netif/fe/if_fe_pccard.c | 3 +- sys/dev/netif/wi/if_wi_pccard.c | 10 +- sys/dev/netif/xe/if_xe_pccard.c | 5 +- sys/dev/pccard/cardbus/cardbus.c | 1309 +++++----------- sys/dev/pccard/cardbus/cardbus_cis.c | 883 +++-------- sys/dev/pccard/cardbus/cardbus_cis.h | 88 +- sys/dev/pccard/cardbus/cardbusreg.h | 18 +- sys/dev/pccard/cardbus/cardbusvar.h | 39 +- sys/dev/pccard/exca/exca.c | 444 +++++- sys/dev/pccard/exca/excareg.h | 48 +- sys/dev/pccard/exca/excavar.h | 54 +- sys/dev/pccard/pccbb/Makefile | 6 +- sys/dev/pccard/pccbb/pccbb.c | 1473 +++++++----------- sys/dev/pccard/pccbb/pccbb_isa.c | 214 +++ sys/dev/pccard/pccbb/pccbb_pci.c | 687 ++++++++ sys/dev/pccard/pccbb/pccbbdevid.h | 69 +- sys/dev/pccard/pccbb/pccbbreg.h | 73 +- sys/dev/pccard/pccbb/pccbbvar.h | 131 +- sys/dev/serial/sio/sio_pccard.c | 3 +- 44 files changed, 3769 insertions(+), 4612 deletions(-) delete mode 100644 sys/bus/pccard/cardinfo.h delete mode 100644 sys/bus/pccard/cis.h delete mode 100644 sys/bus/pccard/driver.h delete mode 100644 sys/bus/pccard/pccard_beep.c copy sys/bus/pccard/{pccardreg.h => pccard_cis.h} (57%) delete mode 100644 sys/bus/pccard/slot.h create mode 100644 sys/dev/pccard/pccbb/pccbb_isa.c create mode 100644 sys/dev/pccard/pccbb/pccbb_pci.c diff --git a/sys/bus/pccard/Makefile b/sys/bus/pccard/Makefile index f69cbdea29..e57b6e9e5a 100644 --- a/sys/bus/pccard/Makefile +++ b/sys/bus/pccard/Makefile @@ -1,13 +1,12 @@ -# $DragonFly: src/sys/bus/pccard/Makefile,v 1.2 2006/03/30 11:09:08 swildner Exp $ +# $DragonFly: src/sys/bus/pccard/Makefile,v 1.3 2007/07/05 12:08:53 sephe Exp $ # # Makefile for the PCCARD subsystem KMOD= pccard SRCS= bus_if.h device_if.h pci_if.h \ pccard.c card_if.h power_if.h\ - pccard_beep.c pccard_cis.c pccard_cis_quirks.c pccarddevs.h \ - pccardreg.h pccardvar.h \ - cis.h cardinfo.h driver.h slot.h + pccard_cis.c pccard_cis_quirks.c pccarddevs.h \ + pccardreg.h pccardvar.h .include diff --git a/sys/bus/pccard/card_if.m b/sys/bus/pccard/card_if.m index c63b40522d..81c995114f 100644 --- a/sys/bus/pccard/card_if.m +++ b/sys/bus/pccard/card_if.m @@ -1,4 +1,4 @@ -# +#- # Copyright (c) 1999 M. Warner Losh. # All rights reserved. # @@ -23,8 +23,8 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD: src/sys/dev/pccard/card_if.m,v 1.21 2002/11/02 23:00:28 imp Exp $ -# $DragonFly: src/sys/bus/pccard/card_if.m,v 1.1 2004/02/10 07:55:45 joerg Exp $ +# $FreeBSD: src/sys/dev/pccard/card_if.m,v 1.29 2005/07/01 03:40:28 imp Exp $ +# $DragonFly: src/sys/bus/pccard/card_if.m,v 1.2 2007/07/05 12:08:53 sephe Exp $ # #include @@ -68,15 +68,15 @@ METHOD int set_memory_offset { device_t dev; device_t child; int rid; - u_int32_t cardaddr; - u_int32_t *deltap; + uint32_t cardaddr; + uint32_t *deltap; } METHOD int get_memory_offset { device_t dev; device_t child; int rid; - u_int32_t *offset; + uint32_t *offset; } # @@ -93,38 +93,6 @@ METHOD int detach_card { device_t dev; } -# -# Returns the type of card this is. Maybe we don't need this. -# -METHOD int get_type { - device_t dev; - int *type; -} - -# -# Returns the function number for this device. -# -METHOD int get_function { - device_t dev; - device_t child; - int *func; -} - -# -# Activates (and powers up if necessary) the card's nth function -# since each function gets its own device, there is no need to -# to specify a function number -# -METHOD int activate_function { - device_t dev; - device_t child; -} - -METHOD int deactivate_function { - device_t dev; - device_t child; -} - # # Compatibility methods for OLDCARD drivers. We use these routines to make # it possible to call the OLDCARD driver's probe routine in the context that @@ -203,50 +171,10 @@ METHOD int compat_match { } # -# Method for devices to ask its CIS-enabled parent bus for CIS info. -# Device driver requests all tuples if type 'id', the routine places -# 'nret' number of tuples in 'buff'. Returns 0 if all tuples processed, -# or an error code if processing was aborted. -# Users of this method will be responsible for freeing the memory allocated -# by calling the cis_free method. +# Scanning function for accessing the CIS of a card in its driver. # - -HEADER { - struct cis_tupleinfo { - u_int8_t id; - int len; - char *data; - }; -}; - -CODE { - static int - null_cis_read(device_t dev, device_t child, u_int8_t id, - struct cis_tupleinfo **buff, int *nret) - { - *nret = 0; - *buff = NULL; - return ENXIO; - } - - static void - null_cis_free(device_t dev, struct cis_tupleinfo *buff, int *nret) - { - return; - } +METHOD int cis_scan { + device_t bus; + pccard_scan_t fnp; + void *argp; }; - -METHOD int cis_read { - device_t dev; - device_t child; - u_int8_t id; - struct cis_tupleinfo **buff; - int *nret; -} DEFAULT null_cis_read; - -METHOD int cis_free { - device_t dev; - struct cis_tupleinfo *buff; - int nret; -} DEFAULT null_cis_free; - diff --git a/sys/bus/pccard/cardinfo.h b/sys/bus/pccard/cardinfo.h deleted file mode 100644 index 7904da6fd7..0000000000 --- a/sys/bus/pccard/cardinfo.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Include file for PCMCIA user process interface - * - *------------------------------------------------------------------------- - * - * Copyright (c) 1995 Andrew McRae. All rights reserved. - * - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -/* $FreeBSD: src/sys/pccard/cardinfo.h,v 1.16.2.6 2002/09/22 20:26:58 imp Exp $ */ -/* $DragonFly: src/sys/bus/pccard/Attic/cardinfo.h,v 1.2 2003/06/17 04:28:55 dillon Exp $ */ - -#ifndef _PCCARD_CARDINFO_H_ -#define _PCCARD_CARDINFO_H_ - -#ifndef _KERNEL -#include -#endif -#include - -#define PIOCGSTATE _IOR('P', 1, struct slotstate) /* Get slot state */ -#define PIOCGMEM _IOWR('P', 2, struct mem_desc) /* Get memory map */ -#define PIOCSMEM _IOW('P', 3, struct mem_desc) /* Set memory map */ -#define PIOCGIO _IOWR('P', 4, struct io_desc) /* Get I/O map */ -#define PIOCSIO _IOW('P', 5, struct io_desc) /* Set I/O map */ -#define PIOCSDRV _IOWR('P', 6, struct dev_desc) /* Set driver */ -#define PIOCRWFLAG _IOW('P', 7, int) /* Set flags for drv use */ -#define PIOCRWMEM _IOWR('P', 8, unsigned long) /* Set mem for drv use */ -#define PIOCSPOW _IOW('P', 9, struct power) /* Set power structure */ -#define PIOCSVIR _IOW('P', 10, int) /* Virtual insert/remove */ -#define PIOCSBEEP _IOW('P', 11, int) /* Select Beep */ -#define PIOCSRESOURCE _IOWR('P', 12, struct pccard_resource) /* get resource info */ -/* - * Debug codes. - */ -#define PIOCGREG _IOWR('P',100, struct pcic_reg) /* get reg */ -#define PIOCSREG _IOW('P', 101, struct pcic_reg) /* Set reg */ - -/* - * Slot states for PIOCGSTATE - * - * Here's a state diagram of all the possible states: - * - * power x 1 - * ------------------- - * / \ - * / v - * resume +----------+ power x 0 +----------+ - * ------->| inactive |<--------------| filled | - * / +----------+ +----------+ - * / / \ ^ | - * nil <--------- \ insert or | | suspend or - * suspend \ power x 1 | | eject - * \ | v - * \ +----------+ - * ----------->| empty | - * eject +----------+ - * - * Note, the above diagram is for the state. On suspend, the laststate - * gets set to suspend to tell pccardd what happened. Also the nil state - * means that when the no state change has happened. Note: if you eject - * while suspended in the inactive state, you will return to the - * empty state if you do not insert a new card and to the inactive state - * if you do insert a new card. - * - * Some might argue that inactive should be sticky forever and - * eject/insert shouldn't take it out of that state. They might be - * right. On the other hand, some would argue that eject resets all - * state. They might be right. They both can't be right. The above - * represents a reasonable compromise between the two. - * - * Some bridges allow one to query to see if the card was changed while - * we were suspended. Others do not. We make no use of this functionality - * at this time. - */ -enum cardstate { noslot, empty, suspend, filled, inactive }; - -/* - * Descriptor structure for memory map. - */ -struct mem_desc { - int window; /* Memory map window number (0-4) */ - int flags; /* Flags - see below */ - caddr_t start; /* System memory start */ - int size; /* Size of memory area */ - unsigned long card; /* Card memory address */ -}; - -#define MDF_16BITS 0x01 /* Memory is 16 bits wide */ -#define MDF_ZEROWS 0x02 /* Set no wait states for memory */ -#define MDF_WS0 0x04 /* Wait state flags */ -#define MDF_WS1 0x08 -#define MDF_ATTR 0x10 /* Memory is attribute memory */ -#define MDF_WP 0x20 /* Write protect memory */ -#define MDF_ACTIVE 0x40 /* Context active (read-only) */ - -/* - * Descriptor structure for I/O map - */ -struct io_desc { - int window; /* I/O map number (0-1) */ - int flags; /* Flags - see below */ - int start; /* I/O port start */ - int size; /* Number of port addresses */ -}; - -#define IODF_WS 0x01 /* Set wait states for 16 bit I/O access */ -#define IODF_16BIT 0x02 /* I/O access are 16 bit */ -#define IODF_CS16 0x04 /* Allow card selection of 16 bit access */ -#define IODF_ZEROWS 0x08 /* No wait states for 8 bit I/O */ -#define IODF_ACTIVE 0x10 /* Context active (read-only) */ - -/* - * Device descriptor for allocation of driver. - */ -#define DEV_MISC_LEN 36 -#define DEV_MAX_CIS_LEN 40 -struct dev_desc { - char name[16]; /* Driver name */ - int unit; /* Driver unit number */ - unsigned long mem; /* Memory address of driver */ - int memsize; /* Memory size (if used) */ - int iobase; /* base of I/O ports */ - int iosize; /* Length of I/O ports */ - int irqmask; /* Interrupt number(s) to allocate */ - int flags; /* Device flags */ - uint8_t misc[DEV_MISC_LEN]; /* For any random info */ - uint8_t manufstr[DEV_MAX_CIS_LEN]; - uint8_t versstr[DEV_MAX_CIS_LEN]; - uint32_t manufacturer; /* Manufacturer ID */ - uint32_t product; /* Product ID */ - uint32_t prodext; /* Product ID (extended) */ -}; -#define DEV_DESC_HAS_SIZE 1 - -struct pcic_reg { - unsigned char reg; - unsigned char value; -}; - -/* - * Slot information. Used to read current status of slot. - */ -struct slotstate { - enum cardstate state; /* Current state of slot */ - enum cardstate laststate; /* Previous state of slot */ - int maxmem; /* Max allowed memory windows */ - int maxio; /* Max allowed I/O windows */ - int irqs; /* Bitmap of IRQs allowed */ - int flags; /* Capability flags */ -}; - -/* - * The power values are in volts * 10, e.g. 5V is 50, 3.3V is 33. - */ -struct power { - int vcc; - int vpp; -}; - -/* - * The PC-Card resource IOC_GET_RESOURCE_RANGE - */ -struct pccard_resource { - int type; - u_long size; - u_long min; - u_long max; - u_long resource_addr; -}; - - -/* - * Other system limits - */ -#define MAXSLOT 16 -#define NUM_MEM_WINDOWS 10 -#define NUM_IO_WINDOWS 6 -#define CARD_DEVICE "/dev/card%d" /* String for snprintf */ -#define PCCARD_MEMSIZE (4*1024) - -#endif /* !_PCCARD_CARDINFO_H_ */ diff --git a/sys/bus/pccard/cis.h b/sys/bus/pccard/cis.h deleted file mode 100644 index c5f8d363d9..0000000000 --- a/sys/bus/pccard/cis.h +++ /dev/null @@ -1,279 +0,0 @@ -/* - * PCMCIA card structures and defines. - * These defines relate to the user level - * structures and card information, not - * driver/process communication. - *------------------------------------------------------------------------- - * - * Copyright (c) 1995 Andrew McRae. All rights reserved. - * - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD: src/sys/pccard/cis.h,v 1.3.10.1 2000/05/23 03:56:58 imp Exp $ - * $DragonFly: src/sys/bus/pccard/Attic/cis.h,v 1.2 2003/06/17 04:28:55 dillon Exp $ - * - */ - -/* - * Card Information Structure tuples definitions - * The structure of a tuple is basically: - * - * Tuple_code - * Tuple_data_length - * Tuple_data ... - * - * Tuples are contiguous in attribute memory, and - * are terminated with a 0xFF for the tuple code or - * the tuple length. - */ -#ifndef _PCCARD_CIS_H -#define _PCCARD_CIS_H - -#define CIS_NULL 0 /* Empty tuple */ -#define CIS_MEM_COMMON 0x01 /* Device descriptor, common memory */ -#define CIS_LONGLINK_CB 0x02 /* Long link to next chain for CardBus */ -#define CIS_INDIRECT 0x03 /* Indirect access */ -#define CIS_CONF_MAP_CB 0x04 /* Card Configuration map for CardBus */ -#define CIS_CONFIG_CB 0x05 /* Card Configuration entry for CardBus */ -#define CIS_LONGLINK_MFC 0x06 /* Long link to next chain for Multi function card */ -#define CIS_BAR 0x07 /* Base address register for CardBus */ -#define CIS_CHECKSUM 0x10 /* Checksum */ -#define CIS_LONGLINK_A 0x11 /* Link to Attribute memory */ -#define CIS_LONGLINK_C 0x12 /* Link to Common memory */ -#define CIS_LINKTARGET 0x13 /* Linked tuple must start with this. */ -#define CIS_NOLINK 0x14 /* Assume no common memory link tuple. */ -#define CIS_INFO_V1 0x15 /* Card info data, version 1 */ -#define CIS_ALTSTR 0x16 /* Alternate language string tuple. */ -#define CIS_MEM_ATTR 0x17 /* Device descriptor, Attribute memory */ -#define CIS_JEDEC_C 0x18 /* JEDEC descr for common memory */ -#define CIS_JEDEC_A 0x19 /* JEDEC descr for Attribute memory */ -#define CIS_CONF_MAP 0x1A /* Card Configuration map */ -#define CIS_CONFIG 0x1B /* Card Configuration entry */ -#define CIS_DEVICE_OC 0x1C /* Other conditions info - common memory */ -#define CIS_DEVICE_OA 0x1D /* Other conditions info - attribute memory */ -#define CIS_DEVICEGEO 0x1E /* Geometry info for common memory */ -#define CIS_DEVICEGEO_A 0x1F /* Geometry info for attribute memory */ -#define CIS_MANUF_ID 0x20 /* Card manufacturer's ID */ -#define CIS_FUNC_ID 0x21 /* Function of card */ -#define CIS_FUNC_EXT 0x22 /* Functional extension */ -/* - * Data recording format tuples. - */ -#define CIS_SW_INTERLV 0x23 /* Software interleave */ -#define CIS_VERS_2 0x40 /* Card info data, version 2 */ -#define CIS_FORMAT 0x41 /* Memory card format */ -#define CIS_GEOMETRY 0x42 /* Disk sector layout */ -#define CIS_BYTEORDER 0x43 /* Byte order of memory data */ -#define CIS_DATE 0x44 /* Format data/time */ -#define CIS_BATTERY 0x45 /* Battery replacement date */ -#define CIS_ORG 0x46 /* Organization of data on card */ -#define CIS_END 0xFF /* Termination code */ - -/* - * Internal tuple definitions. - * - * Device descriptor for memory (CIS_MEM_ATTR, CIS_MEM_COMMON) - * - * Byte 1: - * 0xF0 - Device type - * 0x08 - Write protect switch - * 0x07 - Speed index (7 = extended speed) - * Byte 2: Extended speed (bit 7 = another follows) - * Byte 3: (ignored if 0xFF) - * 0xF8 - Addressable units (0's numbered) - * 0x07 - Unit size - * The three byte sequence is repeated until byte 1 == 0xFF - */ - -/* - * CIS_INFO_V1 - Version one card information. - * - * Byte 1: Major version number (should be 4) - * Byte 2: Minor version number (should be 1) - * Byte 3-x: Null terminated Manufacturer name - * Byte x-x: Null terminated product name - * Byte x-x: Null terminated additional info 1 - * Byte x-x: Null terminated additional info 2 - * Byte x: final byte must be 0xFF - */ -#define CIS_MAJOR_VERSION 4 -#define CIS_MINOR_VERSION 1 - -/* - * CIS_CONF_MAP - Provides an address map for the card - * configuration register(s), and a max value - * identifying the last configuration tuple. - * - * Byte 1: - * 0x3C - Register mask size (0's numbered) - * 0x03 - Register address size (0's numbered) - * Byte 2: - * 0x3F - ID of last configuration. - * Byte 3-n: Card register address (size is determined by - * the value in byte 1). - * Byte x-x: Card register masks (size determined by the - * value in byte 1) - */ - -/* - * CIS_CONFIG - Card configuration entry. Multiple tuples may - * exist of this type, each one describing a different - * memory/I-O map that can be used to address this card. - * The first one usually has extra config data about the - * card features. The final configuration tuple number - * is stored in the CIS_CONF_MAP tuple so that the complete - * list can be scanned. - * - * Byte 1: - * 0x3F - Configuration ID number. - * 0x40 - Indicates this is the default configuration - * 0x80 - Interface byte exists - * Byte 2: (exists only if bit 0x80 set in byte 1) - * 0x0F - Interface type value - * 0x10 - Battery voltage detect - * 0x20 - Write protect active - * 0x40 - RdyBsy active bit - * 0x80 - Wait signal required - * Byte 3: (features byte) - * 0x03 - Power sub-tuple(s) exists - * 0x04 - Timing sub-tuple exists - * 0x08 - I/O space sub-tuple exists - * 0x10 - IRQ sub-tuple exists - * 0x60 - Memory space sub-tuple(s) exists - * 0x80 - Miscellaneous sub-tuple exists - */ -#define CIS_FEAT_POWER(x) ((x) & 0x3) -#define CIS_FEAT_TIMING 0x4 -#define CIS_FEAT_I_O 0x8 -#define CIS_FEAT_IRQ 0x10 -#define CIS_FEAT_MEMORY(x) (((x) >> 5) & 0x3) -#define CIS_FEAT_MISC 0x80 -/* - * Depending on whether the "features" byte has the corresponding - * bit set, a number of sub-tuples follow. Some features have - * more than one sub-tuple, depending on the count within the - * features byte (e.g power feature bits allows up to 3 sub-tuples). - * - * Power structure sub-tuple: - * Byte 1: parameter exists - Each bit (starting from 0x01) indicates - * that a parameter block exists - up to 8 parameter blocks - * are therefore allowed). - * Byte 2: - * 0x7F - Parameter data - * 0x80 - More bytes follow (0 = last byte) - * - * Timing sub-tuple - * Byte 1: - * 0x03 - Wait scale - * 0x1C - Ready scale - * 0xE0 - Reserved scale - * Byte 2: extended wait scale if wait scale != 3 - * Byte 3: extended ready scale if ready scale != 7 - * Byte 4: extended reserved scale if reserved scale != 7 - */ -#define CIS_WAIT_SCALE(x) ((x) & 0x3) -#define CIS_READY_SCALE(x) (((x)>>2) & 0x7) -#define CIS_RESERVED_SCALE(x) (((x)>>5) & 0x7) -/* - * I/O mapping sub-tuple: - * Byte 1: - * 0x1F - I/O address lines - * 0x20 - 8 bit I/O - * 0x40 - 16 bit I/O - * 0x80 - I/O range?? - * Byte 2: - * 0x0F - 0's numbered count of I/O block subtuples following. - * 0x30 - Size of I/O address value within subtuple. Values - * can be 1 (8 bits), 2 (16 bits) or 3 (32 bits). - * 0xC0 - Size of I/O port block size value within subtuple. - * I/O block sub-tuples, count from previous block: - * Byte 1-n: I/O start address - * Byte x-x: Size of I/O port block. - */ -#define CIS_IO_ADDR(x) ((x) & 0x1F) -#define CIS_IO_8BIT 0x20 -#define CIS_IO_16BIT 0x40 -#define CIS_IO_RANGE 0x80 -#define CIS_IO_BLKS(x) ((x) & 0xF) -#define CIS_IO_ADSZ(x) (((x)>>4) & 3) -#define CIS_IO_BLKSZ(x) (((x)>>6) & 3) -/* - * IRQ sub-tuple. - * Byte 1: - * 0x0F - Irq number or mask bits - * 0x10 - IRQ mask values exist - * 0x20 - Level triggered interrupts - * 0x40 - Pulse triggered requests - * 0x80 - Interrupt sharing. - * Byte 2-3: Interrupt req mask (if 0x10 of byte 1 set). - */ -#define CIS_IRQ_IRQN(x) ((x) & 0xF) -#define CIS_IRQ_MASK 0x10 -#define CIS_IRQ_LEVEL 0x20 -#define CIS_IRQ_PULSE 0x40 -#define CIS_IRQ_SHARING 0x80 -/* - * Memory block subtuple. Depending on the features bits, the - * following subtuples are used: - * mem features == 1 - * Byte 1-2: upper 16 bits of 24 bit memory length. - * mem features == 2 - * Byte 1-2: upper 16 bits of 24 bit memory length. - * Byte 3-4: upper 16 bits of 24 bit memory address. - * mem_features == 3 - * Byte 1: - * 0x07 - 0's numbered count of memory sub-tuples - * 0x18 - Memory length size (1's numbered) - * 0x60 - Memory address size (1's numbered) - * 0x80 - Host address value exists - * Memory sub-tuples follow: - * Byte 1-n: Memory length value (<< 8) - * Byte n-n: Memory card address value (<< 8) - * Byte n-n: Memory host address value (<< 8) - */ -#define CIS_FEAT_MEM_NONE 0 /* No memory config */ -#define CIS_FEAT_MEM_LEN 1 /* Just length */ -#define CIS_FEAT_MEM_ADDR 2 /* Card address & length */ -#define CIS_FEAT_MEM_WIN 3 /* Multiple windows */ - -#define CIS_MEM_WINS(x) (((x) & 0x7)+1) -#define CIS_MEM_LENSZ(x) (((x) >> 3) & 0x3) -#define CIS_MEM_ADDRSZ(x) (((x) >> 5) & 0x3) -#define CIS_MEM_HOST 0x80 -/* - * Misc sub-tuple. - * Byte 1: - * Byte 2: - * 0x0c - DMA Request Signal - * 00 - not support DMA - * 01 - use SPKR# line - * 10 - use IOIS16# line - * 11 - use INPACK# line - * 0x10 - DMA Width - * 0 - 8 bit DMA - * 1 - 16 bit DMA - */ -#define CIS_MISC_DMA_WIDTH(x) (((x) & 0x10) >> 4) -#define CIS_MISC_DMA_REQ(x) (((x) >> 2) & 0x3) - -#endif /* _PCCARD_CIS_H */ diff --git a/sys/bus/pccard/driver.h b/sys/bus/pccard/driver.h deleted file mode 100644 index e34c7810ce..0000000000 --- a/sys/bus/pccard/driver.h +++ /dev/null @@ -1,25 +0,0 @@ -/*- - * pccard driver interface. - * Bruce Evans, November 1995. - * This file is in the public domain. - * - * $FreeBSD: src/sys/pccard/driver.h,v 1.12.2.2 2001/04/21 05:52:30 imp Exp $ - * $DragonFly: src/sys/bus/pccard/Attic/driver.h,v 1.2 2003/06/17 04:28:55 dillon Exp $ - */ - -#ifndef _PCCARD_DRIVER_H_ -#define _PCCARD_DRIVER_H_ - -struct pccard_device; - -void pccard_add_driver(struct pccard_device *); - -enum beepstate { BEEP_OFF, BEEP_ON }; - -void pccard_insert_beep(void); -void pccard_remove_beep(void); -void pccard_success_beep(void); -void pccard_failure_beep(void); -int pccard_beep_select(int); - -#endif /* !_PCCARD_DRIVER_H_ */ diff --git a/sys/bus/pccard/pccard.c b/sys/bus/pccard/pccard.c index ca4fde8038..8edd2764d9 100644 --- a/sys/bus/pccard/pccard.c +++ b/sys/bus/pccard/pccard.c @@ -1,8 +1,6 @@ /* $NetBSD: pcmcia.c,v 1.23 2000/07/28 19:17:02 drochner Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccard.c,v 1.70 2002/11/14 14:02:32 mux Exp $ */ -/* $DragonFly: src/sys/bus/pccard/pccard.c,v 1.19 2006/12/22 23:12:16 swildner Exp $ */ -/* +/*- * Copyright (c) 1997 Marc Horowitz. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,6 +27,9 @@ * 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. + * + * $FreeBSD: src/sys/dev/pccard/pccard.c,v 1.108 2005/07/15 01:43:08 imp Exp $ + * $DragonFly: src/sys/bus/pccard/pccard.c,v 1.20 2007/07/05 12:08:53 sephe Exp $ */ #include @@ -47,6 +48,7 @@ #include #include +#include #include "power_if.h" #include "card_if.h" @@ -83,7 +85,6 @@ static int pccard_ccr_read(struct pccard_function *pf, int ccr); static void pccard_ccr_write(struct pccard_function *pf, int ccr, int val); static int pccard_attach_card(device_t dev); static int pccard_detach_card(device_t dev); -static int pccard_card_gettype(device_t dev, int *type); static void pccard_function_init(struct pccard_function *pf); static void pccard_function_free(struct pccard_function *pf); static int pccard_function_enable(struct pccard_function *pf); @@ -104,12 +105,12 @@ static int pccard_get_resource(device_t dev, device_t child, int type, static void pccard_delete_resource(device_t dev, device_t child, int type, int rid); static int pccard_set_res_flags(device_t dev, device_t child, int type, - int rid, u_int32_t flags); + int rid, uint32_t flags); static int pccard_set_memory_offset(device_t dev, device_t child, int rid, - u_int32_t offset, u_int32_t *deltap); + uint32_t offset, uint32_t *deltap); static void pccard_probe_nomatch(device_t cbdev, device_t child); static int pccard_read_ivar(device_t bus, device_t child, int which, - uintptr_t *result); + u_char *result); static void pccard_driver_added(device_t dev, driver_t *driver); static struct resource *pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, @@ -146,6 +147,33 @@ pccard_ccr_write(struct pccard_function *pf, int ccr, int val) } } +static int +pccard_set_default_descr(device_t dev) +{ + const char *vendorstr, *prodstr; + uint32_t vendor, prod; + char *str; + + vendorstr = pccard_get_vendor_str(dev); + prodstr = pccard_get_product_str(dev); + if (vendorstr != NULL && prodstr != NULL) { + str = kmalloc(strlen(vendorstr) + strlen(prodstr) + 2, M_DEVBUF, + M_WAITOK); + ksprintf(str, "%s %s", vendorstr, prodstr); + device_set_desc_copy(dev, str); + kfree(str, M_DEVBUF); + } else { + vendor = pccard_get_vendor(dev); + prod = pccard_get_product(dev); + + str = kmalloc(100, M_DEVBUF, M_WAITOK); + ksnprintf(str, 100, "vendor=0x%x product=0x%x", vendor, prod); + device_set_desc_copy(dev, str); + kfree(str, M_DEVBUF); + } + return (0); +} + static int pccard_attach_card(device_t dev) { @@ -223,13 +251,14 @@ pccard_attach_card(device_t dev) * can be on at a time. */ ivar = kmalloc(sizeof(struct pccard_ivar), M_DEVBUF, - M_INTWAIT | M_ZERO); + M_WAITOK | M_ZERO); + resource_list_init(&ivar->resources); child = device_add_child(dev, NULL, -1); device_set_ivars(child, ivar); - ivar->fcn = pf; + ivar->pf = pf; pf->dev = child; /* - * XXX We might want to move the next two lines into + * XXX We might want to move the next three lines into * XXX the pccard interface layer. For the moment, this * XXX is OK, but some drivers want to pick the config * XXX entry to use as well as some address tweaks (mostly @@ -240,11 +269,13 @@ pccard_attach_card(device_t dev) if (sc->sc_enabled_count == 0) POWER_ENABLE_SOCKET(device_get_parent(dev), dev); if (pccard_function_enable(pf) == 0 && + pccard_set_default_descr(child) == 0 && device_probe_and_attach(child) == 0) { DEVPRINTF((sc->dev, "function %d CCR at %d " - "offset %x: %x %x %x %x, %x %x %x %x, %x\n", + "offset %x mask %x: " + "%x %x %x %x, %x %x %x %x, %x\n", pf->number, pf->pf_ccr_window, pf->pf_ccr_offset, - pccard_ccr_read(pf, 0x00), + pf->ccr_mask, pccard_ccr_read(pf, 0x00), pccard_ccr_read(pf, 0x02), pccard_ccr_read(pf, 0x04), pccard_ccr_read(pf, 0x06), pccard_ccr_read(pf, 0x0A), pccard_ccr_read(pf, 0x0C), pccard_ccr_read(pf, 0x0E), @@ -263,14 +294,16 @@ pccard_detach_card(device_t dev) struct pccard_softc *sc = PCCARD_SOFTC(dev); struct pccard_function *pf; struct pccard_config_entry *cfe; + int state; /* * We are running on either the PCCARD socket's event thread * or in user context detaching a device by user request. */ STAILQ_FOREACH(pf, &sc->card.pf_head, pf_list) { - int state = device_get_state(pf->dev); - + if (pf->dev == NULL) + continue; + state = device_get_state(pf->dev); if (state == DS_ATTACHED || state == DS_BUSY) device_detach(pf->dev); if (pf->cfe != NULL) @@ -294,37 +327,41 @@ pccard_detach_card(device_t dev) static const struct pccard_product * pccard_do_product_lookup(device_t bus, device_t dev, - const struct pccard_product *tab, size_t ent_size, - pccard_product_match_fn matchfn) + const struct pccard_product *tab, size_t ent_size, + pccard_product_match_fn matchfn) { const struct pccard_product *ent; int matches; - u_int32_t fcn; - u_int32_t vendor; - u_int32_t prod; + uint32_t vendor; + uint32_t prod; const char *vendorstr; const char *prodstr; + const char *cis3str; + const char *cis4str; #ifdef DIAGNOSTIC if (sizeof *ent > ent_size) - panic("pccard_product_lookup: bogus ent_size %ld", - (long) ent_size); + panic("pccard_product_lookup: bogus ent_size %jd", + (intmax_t) ent_size); #endif vendor = pccard_get_vendor(dev); prod = pccard_get_product(dev); - fcn = pccard_get_function_number(dev); vendorstr = pccard_get_vendor_str(dev); prodstr = pccard_get_product_str(dev); - for (ent = tab; ent->pp_name != NULL; ent = + cis3str = pccard_get_cis3_str(dev); + cis4str = pccard_get_cis4_str(dev); + + for (ent = tab; ent->pp_vendor != 0; ent = (const struct pccard_product *) ((const char *) ent + ent_size)) { matches = 1; if (ent->pp_vendor == PCCARD_VENDOR_ANY && - ent->pp_product == PCCARD_VENDOR_ANY && + ent->pp_product == PCCARD_PRODUCT_ANY && ent->pp_cis[0] == NULL && ent->pp_cis[1] == NULL) { - device_printf(dev, - "Total wildcard entry ignored for %s\n", - ent->pp_name); + if (ent->pp_name) + device_printf(dev, + "Total wildcard entry ignored for %s\n", + ent->pp_name); continue; } if (matches && ent->pp_vendor != PCCARD_VENDOR_ANY && @@ -333,15 +370,22 @@ pccard_do_product_lookup(device_t bus, device_t dev, if (matches && ent->pp_product != PCCARD_PRODUCT_ANY && prod != ent->pp_product) matches = 0; - if (matches && fcn != ent->pp_expfunc) - matches = 0; if (matches && ent->pp_cis[0] && - strcmp(ent->pp_cis[0], vendorstr) != 0) + (vendorstr == NULL || + strcmp(ent->pp_cis[0], vendorstr) != 0)) matches = 0; if (matches && ent->pp_cis[1] && - strcmp(ent->pp_cis[1], prodstr) != 0) + (prodstr == NULL || + strcmp(ent->pp_cis[1], prodstr) != 0)) + matches = 0; + if (matches && ent->pp_cis[2] && + (cis3str == NULL || + strcmp(ent->pp_cis[2], cis3str) != 0)) + matches = 0; + if (matches && ent->pp_cis[3] && + (cis4str == NULL || + strcmp(ent->pp_cis[3], cis4str) != 0)) matches = 0; - /* XXX need to match cis[2] and cis[3] also XXX */ if (matchfn != NULL) matches = (*matchfn)(dev, ent, matches); if (matches) @@ -350,27 +394,6 @@ pccard_do_product_lookup(device_t bus, device_t dev, return (NULL); } -static int -pccard_card_gettype(device_t dev, int *type) -{ - struct pccard_softc *sc = PCCARD_SOFTC(dev); - struct pccard_function *pf; - - /* - * set the iftype to memory if this card has no functions (not yet - * probed), or only one function, and that is not initialized yet or - * that is memory. - */ - pf = STAILQ_FIRST(&sc->card.pf_head); - if (pf == NULL || - (STAILQ_NEXT(pf, pf_list) == NULL && - (pf->cfe == NULL || pf->cfe->iftype == PCCARD_IFTYPE_MEMORY))) - *type = PCCARD_IFTYPE_MEMORY; - else - *type = PCCARD_IFTYPE_IO; - return (0); -} - /* * Initialize a PCCARD function. May be called as long as the function is * disabled. @@ -385,15 +408,13 @@ static void pccard_function_init(struct pccard_function *pf) { struct pccard_config_entry *cfe; - int i; struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); struct resource_list *rl = &devi->resources; struct resource_list_entry *rle; struct resource *r = 0; device_t bus; - int start; - int end; - int spaces; + u_long start, end, len; + int i, rid, spaces; if (pf->pf_flags & PFF_ENABLED) { kprintf("pccard_function_init: function is enabled"); @@ -402,53 +423,70 @@ pccard_function_init(struct pccard_function *pf) bus = device_get_parent(pf->dev); /* Remember which configuration entry we are using. */ STAILQ_FOREACH(cfe, &pf->cfe_head, cfe_list) { - for (i = 0; i < cfe->num_iospace; i++) - cfe->iores[i] = NULL; - cfe->irqres = NULL; + if (cfe->iftype != PCCARD_IFTYPE_IO) + continue; spaces = 0; for (i = 0; i < cfe->num_iospace; i++) { start = cfe->iospace[i].start; if (start) end = start + cfe->iospace[i].length - 1; else - end = ~0; - cfe->iorid[i] = i; - DEVPRINTF((bus, "I/O rid %d start %x end %x\n", + end = ~0UL; + DEVPRINTF((bus, "I/O rid %d start %lx end %lx\n", i, start, end)); - r = cfe->iores[i] = bus_alloc_resource(bus, - SYS_RES_IOPORT, &cfe->iorid[i], start, end, - cfe->iospace[i].length, - rman_make_alignment_flags(cfe->iospace[i].length)); - if (cfe->iores[i] == NULL) + rid = i; + len = cfe->iospace[i].length; + r = bus_alloc_resource(bus, SYS_RES_IOPORT, &rid, + start, end, len, rman_make_alignment_flags(len)); + if (r == NULL) goto not_this_one; - resource_list_add(rl, SYS_RES_IOPORT, cfe->iorid[i], - rman_get_start(r), rman_get_end(r), + resource_list_add(rl, SYS_RES_IOPORT, + rid, rman_get_start(r), rman_get_end(r), cfe->iospace[i].length); - rle = resource_list_find(rl, SYS_RES_IOPORT, - cfe->iorid[i]); + rle = resource_list_find(rl, SYS_RES_IOPORT, rid); + if (rle == NULL) + panic("Cannot add resource rid %d IOPORT", rid); rle->res = r; spaces++; } - if (cfe->num_memspace > 0) { - /* - * Not implement yet, Fix me. - */ - DEVPRINTF((bus, "Memory space not yet implemented.\n")); + for (i = 0; i < cfe->num_memspace; i++) { + start = cfe->memspace[i].hostaddr; + if (start) + end = start + cfe->memspace[i].length - 1; + else + end = ~0UL; + DEVPRINTF((bus, "Memory rid %d start %lx end %lx\n", + i, start, end)); + rid = i; + len = cfe->memspace[i].length; + r = bus_alloc_resource(bus, SYS_RES_MEMORY, &rid, + start, end, len, rman_make_alignment_flags(len)); + if (r == NULL) + goto not_this_one; + resource_list_add(rl, SYS_RES_MEMORY, + rid, rman_get_start(r), rman_get_end(r), + cfe->memspace[i].length); + rle = resource_list_find(rl, SYS_RES_MEMORY, rid); + if (rle == NULL) + panic("Cannot add resource rid %d MEM", rid); + rle->res = r; + spaces++; } if (spaces == 0) { - DEVPRINTF((bus, "Neither memory nor I/O mampped\n")); + DEVPRINTF((bus, "Neither memory nor I/O mapped\n")); goto not_this_one; } if (cfe->irqmask) { - cfe->irqrid = 0; - r = cfe->irqres = bus_alloc_resource(bus, SYS_RES_IRQ, - &cfe->irqrid, 0, ~0, 1, 0); - if (cfe->irqres == NULL) + rid = 0; + r = bus_alloc_resource_any(bus, SYS_RES_IRQ, &rid, + RF_SHAREABLE); + if (r == NULL) goto not_this_one; - resource_list_add(rl, SYS_RES_IRQ, cfe->irqrid, + resource_list_add(rl, SYS_RES_IRQ, rid, rman_get_start(r), rman_get_end(r), 1); - rle = resource_list_find(rl, SYS_RES_IRQ, - cfe->irqrid); + rle = resource_list_find(rl, SYS_RES_IRQ, rid); + if (rle == NULL) + panic("Cannot add resource rid %d IRQ", rid); rle->res = r; } /* If we get to here, we've allocated all we need */ @@ -457,31 +495,9 @@ pccard_function_init(struct pccard_function *pf) not_this_one:; DEVPRVERBOSE((bus, "Allocation failed for cfe %d\n", cfe->number)); - /* - * Release resources that we partially allocated - * from this config entry. - */ - for (i = 0; i < cfe->num_iospace; i++) { - if (cfe->iores[i] != NULL) { - bus_release_resource(bus, SYS_RES_IOPORT, - cfe->iorid[i], cfe->iores[i]); - rle = resource_list_find(rl, SYS_RES_IOPORT, - cfe->iorid[i]); - rle->res = NULL; - resource_list_delete(rl, SYS_RES_IOPORT, - cfe->iorid[i]); - } - cfe->iores[i] = NULL; - } - if (cfe->irqmask && cfe->irqres != NULL) { - bus_release_resource(bus, SYS_RES_IRQ, - cfe->irqrid, cfe->irqres); - rle = resource_list_find(rl, SYS_RES_IRQ, - cfe->irqrid); - rle->res = NULL; - resource_list_delete(rl, SYS_RES_IRQ, cfe->irqrid); - cfe->irqres = NULL; - } +#if 0 /* YYY */ + resource_list_purge(rl); +#endif } } @@ -505,7 +521,7 @@ pccard_function_free(struct pccard_function *pf) SLIST_FOREACH(rle, &devi->resources, link) { if (rle->res) { - if (rle->res->r_dev != pf->sc->dev) + if (rman_get_device(rle->res) != pf->sc->dev) device_printf(pf->sc->dev, "function_free: Resource still owned by " "child, oops. " @@ -513,7 +529,7 @@ pccard_function_free(struct pccard_function *pf) rle->type, rle->rid, rman_get_start(rle->res)); BUS_RELEASE_RESOURCE(device_get_parent(pf->sc->dev), - rle->res->r_dev, rle->type, rle->rid, rle->res); + pf->sc->dev, rle->type, rle->rid, rle->res); rle->res = NULL; } } @@ -522,33 +538,37 @@ pccard_function_free(struct pccard_function *pf) static void pccard_mfc_adjust_iobase(struct pccard_function *pf, bus_addr_t addr, - bus_addr_t offset, bus_size_t size) + bus_addr_t offset, bus_size_t size) { bus_size_t iosize, tmp; - + if (addr != 0) { if (pf->pf_mfc_iomax == 0) { pf->pf_mfc_iobase = addr + offset; - pf->pf_mfc_iomax = pf->pf_mfc_iobase + size; + pf->pf_mfc_iomax = pf->pf_mfc_iobase + size; } else { - if (pf->pf_mfc_iobase > addr + offset) + /* this makes the assumption that nothing overlaps */ + if (pf->pf_mfc_iobase > addr + offset) pf->pf_mfc_iobase = addr + offset; - if (pf->pf_mfc_iomax < addr + offset + size) + if (pf->pf_mfc_iomax < addr + offset + size) pf->pf_mfc_iomax = addr + offset + size; } - } + } + tmp = pf->pf_mfc_iomax - pf->pf_mfc_iobase; + /* round up to nearest (2^n)-1 */ for (iosize = 1; iosize < tmp; iosize <<= 1) ; iosize--; + DEVPRINTF((pf->dev, "MFC: I/O base %#jx IOSIZE %#jx\n", + (uintmax_t)pf->pf_mfc_iobase, (uintmax_t)(iosize + 1))); pccard_ccr_write(pf, PCCARD_CCR_IOBASE0, - pf->pf_mfc_iobase & 0xff); + pf->pf_mfc_iobase & 0xff); pccard_ccr_write(pf, PCCARD_CCR_IOBASE1, - (pf->pf_mfc_iobase >> 8) & 0xff); + (pf->pf_mfc_iobase >> 8) & 0xff); pccard_ccr_write(pf, PCCARD_CCR_IOBASE2, 0); pccard_ccr_write(pf, PCCARD_CCR_IOBASE3, 0); - pccard_ccr_write(pf, PCCARD_CCR_IOSIZE, iosize); } @@ -639,7 +659,7 @@ pccard_function_enable(struct pccard_function *pf) pccard_ccr_write(pf, PCCARD_CCR_SOCKETCOPY, 0); - if (pccard_mfc(pf->sc)) + if (pccard_mfc(pf->sc)) pccard_mfc_adjust_iobase(pf, 0, 0, 0); #ifdef PCCARDDEBUG @@ -697,6 +717,8 @@ pccard_function_disable(struct pccard_function *pf) struct pccard_ivar *devi = PCCARD_IVAR(pf->dev); struct resource_list_entry *rle = resource_list_find(&devi->resources, SYS_RES_IRQ, 0); + if (rle == NULL) + panic("Can't disable an interrupt with no IRQ res\n"); BUS_TEARDOWN_INTR(dev, pf->dev, rle->res, pf->intr_handler_cookie); } @@ -748,7 +770,7 @@ pccard_compat_do_attach(device_t bus, device_t dev) int err; err = CARD_COMPAT_PROBE(dev); - if (err == 0) + if (err <= 0) err = CARD_COMPAT_ATTACH(dev); return (err); } @@ -796,15 +818,8 @@ pccard_suspend(device_t self) return (0); } -static int -pccard_shutdown(device_t self) -{ - pccard_detach_card(self); - bus_generic_shutdown(self); - return (0); -} - -static int +static +int pccard_resume(device_t self) { return (0); @@ -858,8 +873,8 @@ pccard_print_child(device_t dev, device_t child) "%ld"); pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ, "%ld"); - retval += kprintf(" function %d config %d", devi->fcn->number, - devi->fcn->cfe->number); + retval += kprintf(" function %d config %d", devi->pf->number, + devi->pf->cfe->number); } retval += bus_print_child_footer(dev, child); @@ -869,7 +884,7 @@ pccard_print_child(device_t dev, device_t child) static int pccard_set_resource(device_t dev, device_t child, int type, int rid, - u_long start, u_long count) + u_long start, u_long count) { struct pccard_ivar *devi = PCCARD_IVAR(child); struct resource_list *rl = &devi->resources; @@ -926,7 +941,7 @@ pccard_delete_resource(device_t dev, device_t child, int type, int rid) static int pccard_set_res_flags(device_t dev, device_t child, int type, int rid, - u_int32_t flags) + uint32_t flags) { return (CARD_SET_RES_FLAGS(device_get_parent(dev), child, type, rid, flags)); @@ -934,7 +949,7 @@ pccard_set_res_flags(device_t dev, device_t child, int type, int rid, static int pccard_set_memory_offset(device_t dev, device_t child, int rid, - u_int32_t offset, u_int32_t *deltap) + uint32_t offset, uint32_t *deltap) { return (CARD_SET_MEMORY_OFFSET(device_get_parent(dev), child, rid, @@ -945,14 +960,18 @@ static void pccard_probe_nomatch(device_t bus, device_t child) { struct pccard_ivar *devi = PCCARD_IVAR(child); - struct pccard_function *func = devi->fcn; + struct pccard_function *pf = devi->pf; struct pccard_softc *sc = PCCARD_SOFTC(bus); + int i; device_printf(bus, ""); - kprintf(" (manufacturer=0x%04x, product=0x%04x) at function %d\n", - sc->card.manufacturer, sc->card.product, func->number); - device_printf(bus, " CIS info: %s, %s, %s\n", sc->card.cis1_info[0], - sc->card.cis1_info[1], sc->card.cis1_info[2]); + kprintf(" (manufacturer=0x%04x, product=0x%04x, function_type=%d) " + "at function %d\n", sc->card.manufacturer, sc->card.product, + pf->function, pf->number); + device_printf(bus, " CIS info: "); + for (i = 0; sc->card.cis1_info[i] != NULL && i < 4; i++) + kprintf("%s%s", i > 0 ? ", " : "", sc->card.cis1_info[i]); + kprintf("\n"); return; } @@ -961,69 +980,90 @@ pccard_child_location_str(device_t bus, device_t child, char *buf, size_t buflen) { struct pccard_ivar *devi = PCCARD_IVAR(child); - struct pccard_function *func = devi->fcn; + struct pccard_function *pf = devi->pf; - ksnprintf(buf, buflen, "function=%d", func->number); + ksnprintf(buf, buflen, "function=%d", pf->number); return (0); } +/* XXX Maybe this should be in subr_bus? */ +static void +pccard_safe_quote(char *dst, const char *src, size_t len) +{ + char *walker = dst, *ep = dst + len - 1; + + if (len == 0) + return; + while (walker < ep) + { + if (*src == '"') { + if (ep - walker < 2) + break; + *walker++ = '\\'; + } + *walker++ = *src++; + } + *walker = '\0'; +} + static int pccard_child_pnpinfo_str(device_t bus, device_t child, char *buf, size_t buflen) { struct pccard_ivar *devi = PCCARD_IVAR(child); - struct pccard_function *func = devi->fcn; + struct pccard_function *pf = devi->pf; struct pccard_softc *sc = PCCARD_SOFTC(bus); + char cis0[128], cis1[128]; + pccard_safe_quote(cis0, sc->card.cis1_info[0], sizeof(cis0)); + pccard_safe_quote(cis1, sc->card.cis1_info[1], sizeof(cis1)); ksnprintf(buf, buflen, "manufacturer=0x%04x product=0x%04x " "cisvendor=\"%s\" cisproduct=\"%s\" function_type=%d", - sc->card.manufacturer, sc->card.product, sc->card.cis1_info[0], - sc->card.cis1_info[1], func->function); + sc->card.manufacturer, sc->card.product, cis0, cis1, pf->function); return (0); } static int -pccard_read_ivar(device_t bus, device_t child, int which, uintptr_t *result) +pccard_read_ivar(device_t bus, device_t child, int which, u_char *result) { struct pccard_ivar *devi = PCCARD_IVAR(child); - struct pccard_function *func = devi->fcn; + struct pccard_function *pf = devi->pf; struct pccard_softc *sc = PCCARD_SOFTC(bus); + if (!pf) + panic("No pccard function pointer"); switch (which) { default: + return (EINVAL); case PCCARD_IVAR_ETHADDR: - *result = (uintptr_t)func->pf_funce_lan_nid; + bcopy(pf->pf_funce_lan_nid, result, ETHER_ADDR_LEN); break; case PCCARD_IVAR_VENDOR: - *result = sc->card.manufacturer; + *(uint32_t *)result = sc->card.manufacturer; break; case PCCARD_IVAR_PRODUCT: - *result = sc->card.product; + *(uint32_t *)result = sc->card.product; break; case PCCARD_IVAR_PRODEXT: - *result = sc->card.prodext; + *(uint16_t *)result = sc->card.prodext; break; case PCCARD_IVAR_FUNCTION: - *result = func->function; + *(uint32_t *)result = pf->function; break; case PCCARD_IVAR_FUNCTION_NUMBER: - if (!func) { - device_printf(bus, "No function number, bug!\n"); - return (ENOENT); - } - *result = func->number; + *(uint32_t *)result = pf->number; break; case PCCARD_IVAR_VENDOR_STR: - *result = (uintptr_t)sc->card.cis1_info[0]; + *(const char **)result = sc->card.cis1_info[0]; break; case PCCARD_IVAR_PRODUCT_STR: - *result = (uintptr_t)sc->card.cis1_info[1]; + *(const char **)result = sc->card.cis1_info[1]; break; case PCCARD_IVAR_CIS3_STR: - *result = (uintptr_t)sc->card.cis1_info[2]; + *(const char **)result = sc->card.cis1_info[2]; break; case PCCARD_IVAR_CIS4_STR: - *result = (uintptr_t)sc->card.cis1_info[3]; + *(const char **)result = sc->card.cis1_info[3]; break; } return (0); @@ -1070,7 +1110,7 @@ pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, int isdefault = (start == 0 && end == ~0UL && count == 1); struct resource *r = NULL; - + /* XXX I'm no longer sure this is right */ if (passthrough) { return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child, type, rid, start, end, count, flags)); @@ -1080,37 +1120,29 @@ pccard_alloc_resource(device_t dev, device_t child, int type, int *rid, rle = resource_list_find(&dinfo->resources, type, *rid); if (rle == NULL && isdefault) - return (NULL); /* no resource of that type/rid */ - - if ((rle == NULL) || (rle->res == NULL)) { - + return (NULL); /* no resource of that type/rid */ + if (rle == NULL || rle->res == NULL) { + /* XXX Need to adjust flags */ r = bus_alloc_resource(dev, type, rid, start, end, - count, rman_make_alignment_flags(count)); + count, flags); if (r == NULL) - goto bad; + goto bad; resource_list_add(&dinfo->resources, type, *rid, - rman_get_start(r), rman_get_end(r), count); + rman_get_start(r), rman_get_end(r), count); rle = resource_list_find(&dinfo->resources, type, *rid); if (!rle) - goto bad; + goto bad; rle->res = r; } - if (rle->res->r_dev != dev) + /* + * If dev doesn't own the device, then we can't give this device + * out. + */ + if (rman_get_device(rle->res) != dev) return (NULL); - bus_release_resource(dev, type, *rid, rle->res); - rle->res = NULL; - switch(type) { - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - if (!(flags & RF_ALIGNMENT_MASK)) - flags |= rman_make_alignment_flags(rle->count); - break; - case SYS_RES_IRQ: - flags |= RF_SHAREABLE; - break; - } - rle->res = resource_list_alloc(&dinfo->resources, dev, child, - type, rid, rle->start, rle->end, rle->count, flags); + rman_set_device(rle->res, child); + if (flags & RF_ACTIVE) + BUS_ACTIVATE_RESOURCE(dev, child, type, *rid, rle->res); return (rle->res); bad:; device_printf(dev, "WARNING: Resource not reserved by pccard\n"); @@ -1124,8 +1156,6 @@ pccard_release_resource(device_t dev, device_t child, int type, int rid, struct pccard_ivar *dinfo; int passthrough = (device_get_parent(child) != dev); struct resource_list_entry *rle = 0; - int ret; - int flags; if (passthrough) return BUS_RELEASE_RESOURCE(device_get_parent(dev), child, @@ -1145,33 +1175,20 @@ pccard_release_resource(device_t dev, device_t child, int type, int rid, device_printf(dev, "Allocated resource not recorded\n"); return ENOENT; } - - ret = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, - type, rid, r); - switch(type) { - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - flags = rman_make_alignment_flags(rle->count); - break; - case SYS_RES_IRQ: - flags = RF_SHAREABLE; - break; - default: - flags = 0; - } - rle->res = bus_alloc_resource(dev, type, &rid, - rle->start, rle->end, rle->count, flags); - if (rle->res == NULL) - device_printf(dev, "release_resource: " - "unable to reaquire resource\n"); - return ret; + /* + * Deactivate the resource (since it is being released), and + * assign it to the bus. + */ + BUS_DEACTIVATE_RESOURCE(dev, child, type, rid, rle->res); + rman_set_device(rle->res, dev); + return (0); } static void pccard_child_detached(device_t parent, device_t dev) { struct pccard_ivar *ivar = PCCARD_IVAR(dev); - struct pccard_function *pf = ivar->fcn; + struct pccard_function *pf = ivar->pf; pccard_function_disable(pf); } @@ -1194,6 +1211,10 @@ pccard_intr(void *arg) * the interrupt will pacify the card enough to keep an * interrupt storm from happening. Of course this won't * help in the non-MFC case. + * + * This has no impact for MPSAFEness of the client drivers. + * We register this with whatever flags the intr_handler + * was registered with. All these functions are MPSAFE. */ if (pccard_mfc(pf->sc)) { reg = pccard_ccr_read(pf, PCCARD_CCR_STATUS); @@ -1214,21 +1235,21 @@ pccard_setup_intr(device_t dev, device_t child, struct resource *irq, { struct pccard_softc *sc = PCCARD_SOFTC(dev); struct pccard_ivar *ivar = PCCARD_IVAR(child); - struct pccard_function *func = ivar->fcn; + struct pccard_function *pf = ivar->pf; int err; - if (func->intr_handler != NULL) + if (pf->intr_handler != NULL) panic("Only one interrupt handler per function allowed"); err = bus_generic_setup_intr(dev, child, irq, flags, pccard_intr, - func, cookiep, serializer); + pf, cookiep, serializer); if (err != 0) return (err); - func->intr_handler = intr; - func->intr_handler_arg = arg; - func->intr_handler_cookie = *cookiep; + pf->intr_handler = intr; + pf->intr_handler_arg = arg; + pf->intr_handler_cookie = *cookiep; if (pccard_mfc(sc)) { - pccard_ccr_write(func, PCCARD_CCR_OPTION, - pccard_ccr_read(func, PCCARD_CCR_OPTION) | + pccard_ccr_write(pf, PCCARD_CCR_OPTION, + pccard_ccr_read(pf, PCCARD_CCR_OPTION) | PCCARD_CCR_OPTION_IREQ_ENABLE); } return (0); @@ -1240,36 +1261,40 @@ pccard_teardown_intr(device_t dev, device_t child, struct resource *r, { struct pccard_softc *sc = PCCARD_SOFTC(dev); struct pccard_ivar *ivar = PCCARD_IVAR(child); - struct pccard_function *func = ivar->fcn; + struct pccard_function *pf = ivar->pf; int ret; if (pccard_mfc(sc)) { - pccard_ccr_write(func, PCCARD_CCR_OPTION, - pccard_ccr_read(func, PCCARD_CCR_OPTION) & + pccard_ccr_write(pf, PCCARD_CCR_OPTION, + pccard_ccr_read(pf, PCCARD_CCR_OPTION) & ~PCCARD_CCR_OPTION_IREQ_ENABLE); } ret = bus_generic_teardown_intr(dev, child, r, cookie); if (ret == 0) { - func->intr_handler = NULL; - func->intr_handler_arg = NULL; - func->intr_handler_cookie = NULL; + pf->intr_handler = NULL; + pf->intr_handler_arg = NULL; + pf->intr_handler_cookie = NULL; } return (ret); } static int -pccard_activate_resource(device_t brdev, device_t child, int type, - int rid, struct resource *r) +pccard_activate_resource(device_t brdev, device_t child, int type, int rid, + struct resource *r) { struct pccard_ivar *ivar = PCCARD_IVAR(child); - struct pccard_function *pf = ivar->fcn; - + struct pccard_function *pf = ivar->pf; + switch(type) { case SYS_RES_IOPORT: + /* + * We need to adjust IOBASE[01] and IOSIZE if we're an MFC + * card. + */ if (pccard_mfc(pf->sc)) pccard_mfc_adjust_iobase(pf, rman_get_start(r), 0, - rman_get_size(r)); + rman_get_size(r)); break; default: break; @@ -1277,13 +1302,20 @@ pccard_activate_resource(device_t brdev, device_t child, int type, return (bus_generic_activate_resource(brdev, child, type, rid, r)); } +static int +pccard_deactivate_resource(device_t brdev, device_t child, int type, + int rid, struct resource *r) +{ + /* XXX undo pccard_activate_resource? XXX */ + return (bus_generic_deactivate_resource(brdev, child, type, rid, r)); +} static device_method_t pccard_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pccard_probe), DEVMETHOD(device_attach, pccard_attach), DEVMETHOD(device_detach, pccard_detach), - DEVMETHOD(device_shutdown, pccard_shutdown), + DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, pccard_suspend), DEVMETHOD(device_resume, pccard_resume), @@ -1294,7 +1326,7 @@ static device_method_t pccard_methods[] = { DEVMETHOD(bus_alloc_resource, pccard_alloc_resource), DEVMETHOD(bus_release_resource, pccard_release_resource), DEVMETHOD(bus_activate_resource, pccard_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_deactivate_resource, pccard_deactivate_resource), DEVMETHOD(bus_setup_intr, pccard_setup_intr), DEVMETHOD(bus_teardown_intr, pccard_teardown_intr), DEVMETHOD(bus_set_resource, pccard_set_resource), @@ -1308,12 +1340,12 @@ static device_method_t pccard_methods[] = { /* Card Interface */ DEVMETHOD(card_set_res_flags, pccard_set_res_flags), DEVMETHOD(card_set_memory_offset, pccard_set_memory_offset), - DEVMETHOD(card_get_type, pccard_card_gettype), DEVMETHOD(card_attach_card, pccard_attach_card), DEVMETHOD(card_detach_card, pccard_detach_card), DEVMETHOD(card_compat_do_probe, pccard_compat_do_probe), DEVMETHOD(card_compat_do_attach, pccard_compat_do_attach), DEVMETHOD(card_do_product_lookup, pccard_do_product_lookup), + DEVMETHOD(card_cis_scan, pccard_scan_cis), { 0, 0 } }; @@ -1329,6 +1361,4 @@ devclass_t pccard_devclass; /* Maybe we need to have a slot device? */ DRIVER_MODULE(pccard, pcic, pccard_driver, pccard_devclass, 0, 0); DRIVER_MODULE(pccard, cbb, pccard_driver, pccard_devclass, 0, 0); -DRIVER_MODULE(pccard, tcic, pccard_driver, pccard_devclass, 0, 0); MODULE_VERSION(pccard, 1); -/*MODULE_DEPEND(pccard, pcic, 1, 1, 1);*/ diff --git a/sys/bus/pccard/pccard_beep.c b/sys/bus/pccard/pccard_beep.c deleted file mode 100644 index ab4a9e41b2..0000000000 --- a/sys/bus/pccard/pccard_beep.c +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * pccard noise interface. - * Nate Williams, October 1997. - * This file is in the public domain. - */ -/* $FreeBSD: src/sys/pccard/pccard_beep.c,v 1.3.2.3 2001/06/05 19:11:34 imp Exp $ */ -/* $DragonFly: src/sys/bus/pccard/Attic/pccard_beep.c,v 1.4 2004/09/18 21:05:07 joerg Exp $ */ - -#include -#include -#include - -#include - -#include "driver.h" - -static enum beepstate allow_beep = BEEP_OFF; -static struct callout beep_timer; -static int melody_type = 0; - -SYSINIT(pccard_beep, SI_SUB_DRIVERS, SI_ORDER_FIRST, callout_init, &beep_timer); - -#define MAX_TONE_MODE 3 -#define MAX_STATE 4 - -struct tone { - int pitch; - int duration; -}; - -static struct tone silent_beep[] = { - {0, 0} -}; - -static struct tone success_beep[] = { - {1200, 40}, {0, 0} -}; -static struct tone failure_beep[] = { - {3200, 40}, {0, 0} -}; -static struct tone insert_remove_beep[] = { - {1600, 20}, {0, 0} -}; - -static struct tone success_melody_beep[] = { - {1200, 7}, {1000, 7}, { 800, 15}, {0, 0} -}; -static struct tone failure_melody_beep[] = { - {2000, 7}, {2400, 7}, {2800, 15}, {0, 0} -}; -static struct tone insert_melody_beep[] = { - {1600, 10}, {1200, 5}, {0, 0} -}; -static struct tone remove_melody_beep[] = { - {1200, 10}, {1600, 5}, {0, 0} -}; - -static struct tone *melody_table[MAX_TONE_MODE][MAX_STATE] = { - { /* silent mode */ - silent_beep, silent_beep, silent_beep, silent_beep, - }, - { /* simple beep mode */ - success_beep, failure_beep, - insert_remove_beep, insert_remove_beep, - }, - { /* melody beep mode */ - success_melody_beep, failure_melody_beep, - insert_melody_beep, remove_melody_beep, - }, -}; - - -static void -pccard_beep_sub(void *arg) -{ - struct tone *melody; - melody = (struct tone *)arg; - - if (melody->pitch != 0) { - sysbeep(melody->pitch, melody->duration); - callout_reset(&beep_timer, melody->duration, - pccard_beep_sub, melody + 1); - } else - allow_beep = BEEP_ON; -} - -static void -pccard_beep_start(void *arg) -{ - struct tone *melody; - melody = (struct tone *)arg; - - if (allow_beep == BEEP_ON && melody->pitch != 0) { - allow_beep = BEEP_OFF; - sysbeep(melody->pitch, melody->duration); - callout_reset(&beep_timer, melody->duration, - pccard_beep_sub, melody + 1); - } -} - -void -pccard_success_beep(void) -{ - pccard_beep_start(melody_table[melody_type][0]); -} - -void -pccard_failure_beep(void) -{ - pccard_beep_start(melody_table[melody_type][1]); -} - -void -pccard_insert_beep(void) -{ - pccard_beep_start(melody_table[melody_type][2]); -} - -void -pccard_remove_beep(void) -{ - pccard_beep_start(melody_table[melody_type][3]); -} - -int -pccard_beep_select(int type) -{ - int errcode = 0; - - if (type == 0) { - allow_beep = BEEP_OFF; - melody_type = 0; - } else if (type < 0 || MAX_TONE_MODE - 1 < type) { - errcode = 1; - } else { - allow_beep = BEEP_ON; - melody_type = type; - } - return (errcode); -} diff --git a/sys/bus/pccard/pccard_cis.c b/sys/bus/pccard/pccard_cis.c index 2fdb283de3..12046fd846 100644 --- a/sys/bus/pccard/pccard_cis.c +++ b/sys/bus/pccard/pccard_cis.c @@ -1,8 +1,8 @@ /* $NetBSD: pcmcia_cis.c,v 1.17 2000/02/10 09:01:52 chopps Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccard_cis.c,v 1.23 2002/11/14 14:02:32 mux Exp $ */ -/* $DragonFly: src/sys/bus/pccard/pccard_cis.c,v 1.7 2006/12/22 23:12:16 swildner Exp $ */ +/* $FreeBSD: src/sys/dev/pccard/pccard_cis.c,v 1.36 2005/07/17 20:16:22 imp Exp $ */ +/* $DragonFly: src/sys/bus/pccard/pccard_cis.c,v 1.8 2007/07/05 12:08:53 sephe Exp $ */ -/* +/*- * Copyright (c) 1997 Marc Horowitz. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ #include #include +#include #include "card_if.h" @@ -51,8 +52,8 @@ extern int pccard_cis_debug; #define PCCARDCISDEBUG #ifdef PCCARDCISDEBUG -#define DPRINTF(arg) if (pccard_cis_debug) kprintf arg -#define DEVPRINTF(arg) if (pccard_cis_debug) device_printf arg +#define DPRINTF(arg) do { if (pccard_cis_debug) kprintf arg; } while (0) +#define DEVPRINTF(arg) do { if (pccard_cis_debug) device_printf arg; } while (0) #else #define DPRINTF(arg) #define DEVPRINTF(arg) @@ -69,8 +70,8 @@ struct cis_state { struct pccard_function *pf; }; -int pccard_parse_cis_tuple(struct pccard_tuple *, void *); -static int decode_funce(struct pccard_tuple *, struct pccard_function *); +static int pccard_parse_cis_tuple(const struct pccard_tuple *, void *); +static int decode_funce(const struct pccard_tuple *, struct pccard_function *); void pccard_read_cis(struct pccard_softc *sc) @@ -78,9 +79,7 @@ pccard_read_cis(struct pccard_softc *sc) struct cis_state state; bzero(&state, sizeof state); - state.card = &sc->card; - state.card->error = 0; state.card->cis1_major = -1; state.card->cis1_minor = -1; @@ -91,29 +90,26 @@ pccard_read_cis(struct pccard_softc *sc) state.card->manufacturer = PCMCIA_VENDOR_INVALID; state.card->product = PCMCIA_PRODUCT_INVALID; STAILQ_INIT(&state.card->pf_head); - state.pf = NULL; - if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple, - &state) == -1) + if (pccard_scan_cis(sc->dev, pccard_parse_cis_tuple, &state) == -1) state.card->error++; } -#define EARLY_TERM "pccard_scan_cis: early termination, " \ - "array exceeds allocation\n" - int -pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), - void *arg) +pccard_scan_cis(device_t dev, pccard_scan_t fct, void *arg) { struct resource *res; int rid; struct pccard_tuple tuple; int longlink_present; int longlink_common; - u_long longlink_addr; + u_long longlink_addr; /* Type suspect */ int mfc_count; int mfc_index; +#ifdef PCCARDCISDEBUG + int cis_none_cnt = 10; /* Only report 10 CIS_NONEs */ +#endif struct { int common; u_long addr; @@ -124,9 +120,15 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), /* allocate some memory */ + /* + * Some reports from the field suggest that a 64k memory boundary + * helps card CIS being able to be read. Try it here and see what + * the results actually are. I'm not sure I understand why this + * would make cards work better, but it is easy enough to test. + */ rid = 0; - res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, - PCCARD_CIS_SIZE, RF_ACTIVE); + res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, + PCCARD_CIS_SIZE, RF_ACTIVE | rman_make_alignment_flags(64*1024)); if (res == NULL) { device_printf(dev, "can't alloc memory to read attributes\n"); return -1; @@ -137,7 +139,8 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), tuple.memh = rman_get_bushandle(res); tuple.ptr = 0; - DPRINTF(("cis mem map %x\n", (unsigned int) tuple.memh)); + DPRINTF(("cis mem map 0x%x (resource: 0x%lx)\n", + (unsigned int) tuple.memh, rman_get_start(res))); tuple.mult = 2; @@ -152,26 +155,38 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), while (1) { while (1) { - /* get the tuple code */ - - if (tuple.ptr * tuple.mult >= PCCARD_CIS_SIZE) { - device_printf(dev, EARLY_TERM); - break; + /* + * Perform boundary check for insane cards. + * If CIS is too long, simulate CIS end. + * (This check may not be sufficient for + * malicious cards.) + */ + if (tuple.mult * tuple.ptr >= PCCARD_CIS_SIZE - 1 + - 32 /* ad hoc value */ ) { + kprintf("CIS is too long -- truncating\n"); + tuple.code = CISTPL_END; + } else { + /* get the tuple code */ + tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); } - tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); - /* two special-case tuples */ - if (tuple.code == PCCARD_CISTPL_NULL) { - DPRINTF(("CISTPL_NONE\n 00\n")); + if (tuple.code == CISTPL_NULL) { +#ifdef PCCARDCISDEBUG + if (cis_none_cnt > 0) + DPRINTF(("CISTPL_NONE\n 00\n")); + else if (cis_none_cnt == 0) + DPRINTF(("TOO MANY CIS_NONE\n")); + cis_none_cnt--; +#endif tuple.ptr++; continue; - } else if (tuple.code == PCCARD_CISTPL_END) { + } else if (tuple.code == CISTPL_END) { DPRINTF(("CISTPL_END\n ff\n")); /* Call the function for the END tuple, since the CIS semantics depend on it */ - if ((*fct) (&tuple, arg)) { + if ((*fct)(&tuple, arg)) { ret = 1; goto done; } @@ -180,24 +195,10 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), } /* now all the normal tuples */ - if ((tuple.ptr + 1) * tuple.mult >= PCCARD_CIS_SIZE) { - device_printf(dev, EARLY_TERM); - break; - } tuple.length = pccard_cis_read_1(&tuple, tuple.ptr + 1); - - /* - * sloppy check - */ - if ((tuple.ptr + 1 + tuple.length) * tuple.mult >= - PCCARD_CIS_SIZE) { - device_printf(dev, EARLY_TERM); - break; - } - switch (tuple.code) { - case PCCARD_CISTPL_LONGLINK_A: - case PCCARD_CISTPL_LONGLINK_C: + case CISTPL_LONGLINK_A: + case CISTPL_LONGLINK_C: if (tuple.length < 4) { DPRINTF(("CISTPL_LONGLINK_%s too " "short %d\n", @@ -207,17 +208,17 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), } longlink_present = 1; longlink_common = (tuple.code == - PCCARD_CISTPL_LONGLINK_C) ? 1 : 0; + CISTPL_LONGLINK_C) ? 1 : 0; longlink_addr = pccard_tuple_read_4(&tuple, 0); DPRINTF(("CISTPL_LONGLINK_%s %lx\n", longlink_common ? "C" : "A", longlink_addr)); break; - case PCCARD_CISTPL_NO_LINK: + case CISTPL_NO_LINK: longlink_present = 0; DPRINTF(("CISTPL_NO_LINK\n")); break; - case PCCARD_CISTPL_CHECKSUM: + case CISTPL_CHECKSUM: if (tuple.length < 5) { DPRINTF(("CISTPL_CHECKSUM too " "short %d\n", tuple.length)); @@ -244,19 +245,18 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), * distant regions */ if ((addr >= PCCARD_CIS_SIZE) || - ((addr + length * tuple.mult) > + ((addr + length) >= PCCARD_CIS_SIZE)) { DPRINTF((" skipped, " "too distant\n")); break; } sum = 0; - for (i = 0; i < length; i++) { + for (i = 0; i < length; i++) sum += bus_space_read_1(tuple.memt, tuple.memh, addr + tuple.mult * i); - } if (cksum != (sum & 0xff)) { DPRINTF((" failed sum=%x\n", sum)); @@ -274,7 +274,7 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), } } break; - case PCCARD_CISTPL_LONGLINK_MFC: + case CISTPL_LONGLINK_MFC: if (tuple.length < 1) { DPRINTF(("CISTPL_LONGLINK_MFC too " "short %d\n", tuple.length)); @@ -346,7 +346,7 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), */ default: { - if ((*fct) (&tuple, arg)) { + if ((*fct)(&tuple, arg)) { ret = 1; goto done; } @@ -383,7 +383,6 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), * In general, this means that if one pointer fails, it will * try the next one, instead of just bailing. */ - while (1) { if (longlink_present) { CARD_SET_RES_FLAGS(device_get_parent(dev), dev, @@ -412,7 +411,7 @@ pccard_scan_cis(device_t dev, int (*fct)(struct pccard_tuple *, void *), /* make sure that the link is valid */ tuple.code = pccard_cis_read_1(&tuple, tuple.ptr); - if (tuple.code != PCCARD_CISTPL_LINKTARGET) { + if (tuple.code != CISTPL_LINKTARGET) { DPRINTF(("CISTPL_LINKTARGET expected, " "code %02x observed\n", tuple.code)); continue; @@ -610,8 +609,8 @@ pccard_print_cis(device_t dev) card->error); } -int -pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) +static int +pccard_parse_cis_tuple(const struct pccard_tuple *tuple, void *arg) { /* most of these are educated guesses */ static struct pccard_config_entry init_cfe = { @@ -622,7 +621,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) struct cis_state *state = arg; switch (tuple->code) { - case PCCARD_CISTPL_END: + case CISTPL_END: /* if we've seen a LONGLINK_MFC, and this is the first * END after it, reset the function list. * @@ -649,7 +648,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) state->pf = NULL; } break; - case PCCARD_CISTPL_LONGLINK_MFC: + case CISTPL_LONGLINK_MFC: /* * this tuple's structure was dealt with in scan_cis. here, * record the fact that the MFC tuple was seen, so that @@ -659,8 +658,8 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) state->gotmfc = 1; break; #ifdef PCCARDCISDEBUG - case PCCARD_CISTPL_DEVICE: - case PCCARD_CISTPL_DEVICE_A: + case CISTPL_DEVICE: + case CISTPL_DEVICE_A: { u_int reg, dtype, dspeed; @@ -669,7 +668,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) dspeed = reg & PCCARD_DSPEED_MASK; DPRINTF(("CISTPL_DEVICE%s type=", - (tuple->code == PCCARD_CISTPL_DEVICE) ? "" : "_A")); + (tuple->code == CISTPL_DEVICE) ? "" : "_A")); switch (dtype) { case PCCARD_DTYPE_NULL: DPRINTF(("null")); @@ -733,7 +732,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) DPRINTF(("\n")); break; #endif - case PCCARD_CISTPL_VERS_1: + case CISTPL_VERS_1: if (tuple->length < 6) { DPRINTF(("CISTPL_VERS_1 too short %d\n", tuple->length)); @@ -760,7 +759,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) DPRINTF(("CISTPL_VERS_1\n")); } break; - case PCCARD_CISTPL_MANFID: + case CISTPL_MANFID: if (tuple->length < 4) { DPRINTF(("CISTPL_MANFID too short %d\n", tuple->length)); @@ -777,12 +776,11 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) * also handle the '6' case. So far no cards have surfaced * with a length of '6'. */ - if (tuple->length == 5 ) { + if (tuple->length == 5 ) state->card->prodext = pccard_tuple_read_1(tuple, 4); - } DPRINTF(("CISTPL_MANFID\n")); break; - case PCCARD_CISTPL_FUNCID: + case CISTPL_FUNCID: if (tuple->length < 1) { DPRINTF(("CISTPL_FUNCID too short %d\n", tuple->length)); @@ -790,7 +788,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) } if ((state->pf == NULL) || (state->gotmfc == 2)) { state->pf = kmalloc(sizeof(*state->pf), M_DEVBUF, - M_INTWAIT | M_ZERO); + M_NOWAIT | M_ZERO); state->pf->number = state->count++; state->pf->last_config_index = -1; STAILQ_INIT(&state->pf->cfe_head); @@ -802,18 +800,17 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) DPRINTF(("CISTPL_FUNCID\n")); break; - case PCCARD_CISTPL_FUNCE: + case CISTPL_FUNCE: if (state->pf == NULL || state->pf->function <= 0) { DPRINTF(("CISTPL_FUNCE is not followed by " "valid CISTPL_FUNCID\n")); break; } - if (tuple->length >= 2) { + if (tuple->length >= 2) decode_funce(tuple, state->pf); - } DPRINTF(("CISTPL_FUNCE\n")); break; - case PCCARD_CISTPL_CONFIG: + case CISTPL_CONFIG: if (tuple->length < 3) { DPRINTF(("CISTPL_CONFIG too short %d\n", tuple->length)); @@ -838,7 +835,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) } if (state->pf == NULL) { state->pf = kmalloc(sizeof(*state->pf), - M_DEVBUF, M_INTWAIT | M_ZERO); + M_DEVBUF, M_NOWAIT | M_ZERO); state->pf->number = state->count++; state->pf->last_config_index = -1; STAILQ_INIT(&state->pf->cfe_head); @@ -871,7 +868,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) } DPRINTF(("CISTPL_CONFIG\n")); break; - case PCCARD_CISTPL_CFTABLE_ENTRY: + case CISTPL_CFTABLE_ENTRY: { int idx, i, j; u_int reg, reg2; @@ -908,8 +905,12 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) * with the current default */ if (num != state->default_cfe->number) { - cfe = kmalloc(sizeof(*cfe), M_DEVBUF, M_INTWAIT); - + cfe = (struct pccard_config_entry *) + kmalloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT); + if (cfe == NULL) { + DPRINTF(("no memory for config entry\n")); + goto abort_cfe; + } *cfe = *state->default_cfe; STAILQ_INSERT_TAIL(&state->pf->cfe_head, @@ -1135,9 +1136,7 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) goto abort_cfe; } - if (memspace == PCCARD_TPCE_FS_MEMSPACE_NONE) { - cfe->num_memspace = 0; - } else if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) { + if (memspace == PCCARD_TPCE_FS_MEMSPACE_LENGTH) { cfe->num_memspace = 1; cfe->memspace[0].length = 256 * pccard_tuple_read_2(tuple, idx); @@ -1220,7 +1219,8 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) } } } - } + } else + cfe->num_memspace = 0; if (misc) { if (tuple->length <= idx) { DPRINTF(("ran out of space before TCPE_MI\n")); @@ -1260,8 +1260,10 @@ pccard_parse_cis_tuple(struct pccard_tuple *tuple, void *arg) } static int -decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf) +decode_funce(const struct pccard_tuple *tuple, struct pccard_function *pf) { + int i; + int len; int type = pccard_tuple_read_1(tuple, 0); switch (pf->function) { @@ -1273,8 +1275,7 @@ decode_funce(struct pccard_tuple *tuple, struct pccard_function *pf) break; case PCCARD_FUNCTION_NETWORK: if (type == PCCARD_TPLFE_TYPE_LAN_NID) { - int i; - int len = pccard_tuple_read_1(tuple, 1); + len = pccard_tuple_read_1(tuple, 1); if (tuple->length < 2 + len || len > 8) { /* tuple length not enough or nid too long */ break; diff --git a/sys/bus/pccard/pccardreg.h b/sys/bus/pccard/pccard_cis.h similarity index 57% copy from sys/bus/pccard/pccardreg.h copy to sys/bus/pccard/pccard_cis.h index f50352e002..c58a542783 100644 --- a/sys/bus/pccard/pccardreg.h +++ b/sys/bus/pccard/pccard_cis.h @@ -1,8 +1,7 @@ -/* $NetBSD: pcmciareg.h,v 1.7 1998/10/29 09:45:52 enami Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccardreg.h,v 1.1 1999/10/26 06:52:31 imp Exp $ */ -/* $DragonFly: src/sys/bus/pccard/pccardreg.h,v 1.3 2004/02/10 07:55:45 joerg Exp $ */ +/* $FreeBSD: src/sys/dev/pccard/pccard_cis.h,v 1.4 2005/07/13 14:59:06 imp Exp $ */ +/* $DragonFly: src/sys/bus/pccard/pccard_cis.h,v 1.1 2007/07/05 12:08:53 sephe Exp $ */ -/* +/*- * Copyright (c) 1997 Marc Horowitz. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,35 +30,30 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* most of this is from the PCCARD PC Card Standard, Release 2.1 */ - -/* Note: the weird indenting here is to make the constants more - readable. Please don't normalize it. --marc */ - /* * CIS Tuples */ /* Layer 1 Basic Compatibility Tuples */ -#define PCCARD_CISTPL_NULL 0x00 -#define PCCARD_CISTPL_DEVICE 0x01 -#define PCCARD_DTYPE_MASK 0xF0 -#define PCCARD_DTYPE_NULL 0x00 -#define PCCARD_DTYPE_ROM 0x10 -#define PCCARD_DTYPE_OTPROM 0x20 -#define PCCARD_DTYPE_EPROM 0x30 -#define PCCARD_DTYPE_EEPROM 0x40 -#define PCCARD_DTYPE_FLASH 0x50 -#define PCCARD_DTYPE_SRAM 0x60 -#define PCCARD_DTYPE_DRAM 0x70 -#define PCCARD_DTYPE_FUNCSPEC 0xD0 -#define PCCARD_DTYPE_EXTEND 0xE0 -#define PCCARD_DSPEED_MASK 0x07 -#define PCCARD_DSPEED_NULL 0x00 -#define PCCARD_DSPEED_250NS 0x01 -#define PCCARD_DSPEED_200NS 0x02 -#define PCCARD_DSPEED_150NS 0x03 -#define PCCARD_DSPEED_100NS 0x04 -#define PCCARD_DSPEED_EXT 0x07 +#define CISTPL_NULL 0x00 +#define CISTPL_DEVICE 0x01 +#define PCCARD_DTYPE_MASK 0xF0 +#define PCCARD_DTYPE_NULL 0x00 +#define PCCARD_DTYPE_ROM 0x10 +#define PCCARD_DTYPE_OTPROM 0x20 +#define PCCARD_DTYPE_EPROM 0x30 +#define PCCARD_DTYPE_EEPROM 0x40 +#define PCCARD_DTYPE_FLASH 0x50 +#define PCCARD_DTYPE_SRAM 0x60 +#define PCCARD_DTYPE_DRAM 0x70 +#define PCCARD_DTYPE_FUNCSPEC 0xD0 +#define PCCARD_DTYPE_EXTEND 0xE0 +#define PCCARD_DSPEED_MASK 0x07 +#define PCCARD_DSPEED_NULL 0x00 +#define PCCARD_DSPEED_250NS 0x01 +#define PCCARD_DSPEED_200NS 0x02 +#define PCCARD_DSPEED_150NS 0x03 +#define PCCARD_DSPEED_100NS 0x04 +#define PCCARD_DSPEED_EXT 0x07 /* * the 2.1 docs have 0x02-0x07 as reserved, but the linux drivers list the @@ -68,34 +62,35 @@ * are for real */ -#define PCCARD_CISTPL_LONGLINK_CB 0x02 -#define PCCARD_CISTPL_INDIRECT 0x03 -#define PCCARD_CISTPL_CONFIG_CB 0x04 -#define PCCARD_CISTPL_CFTABLE_ENTRY_CB 0x05 -#define PCCARD_CISTPL_LONGLINK_MFC 0x06 +#define CISTPL_LONGLINK_CB 0x02 +#define CISTPL_INDIRECT 0x03 +#define CISTPL_CONFIG_CB 0x04 +#define CISTPL_CFTABLE_ENTRY_CB 0x05 +#define CISTPL_LONGLINK_MFC 0x06 #define PCCARD_MFC_MEM_ATTR 0x00 #define PCCARD_MFC_MEM_COMMON 0x01 -#define PCCARD_CISTPL_BAR 0x07 -#define PCCARD_CISTPL_PWR_MGMNT 0x08 - -#define PCCARD_CISTPL_CHECKSUM 0x10 -#define PCCARD_CISTPL_LONGLINK_A 0x11 -#define PCCARD_CISTPL_LONGLINK_C 0x12 -#define PCCARD_CISTPL_LINKTARGET 0x13 -#define PCCARD_CISTPL_NO_LINK 0x14 -#define PCCARD_CISTPL_VERS_1 0x15 -#define PCCARD_CISTPL_ALTSTR 0x16 -#define PCCARD_CISTPL_DEVICE_A 0x17 -#define PCCARD_CISTPL_JEDEC_C 0x18 -#define PCCARD_CISTPL_JEDEC_A 0x19 -#define PCCARD_CISTPL_CONFIG 0x1A +#define CISTPL_BAR 0x07 +#define CISTPL_PWR_MGMNT 0x08 +#define CISTPL_EXTDEVICE 0x09 + +#define CISTPL_CHECKSUM 0x10 +#define CISTPL_LONGLINK_A 0x11 +#define CISTPL_LONGLINK_C 0x12 +#define CISTPL_LINKTARGET 0x13 +#define CISTPL_NO_LINK 0x14 +#define CISTPL_VERS_1 0x15 +#define CISTPL_ALTSTR 0x16 +#define CISTPL_DEVICE_A 0x17 +#define CISTPL_JEDEC_C 0x18 +#define CISTPL_JEDEC_A 0x19 +#define CISTPL_CONFIG 0x1A #define PCCARD_TPCC_RASZ_MASK 0x03 #define PCCARD_TPCC_RASZ_SHIFT 0 #define PCCARD_TPCC_RMSZ_MASK 0x3C #define PCCARD_TPCC_RMSZ_SHIFT 2 #define PCCARD_TPCC_RFSZ_MASK 0xC0 #define PCCARD_TPCC_RFSZ_SHIFT 6 -#define PCCARD_CISTPL_CFTABLE_ENTRY 0x1B +#define CISTPL_CFTABLE_ENTRY 0x1B #define PCCARD_TPCE_INDX_INTFACE 0x80 #define PCCARD_TPCE_INDX_DEFAULT 0x40 #define PCCARD_TPCE_INDX_NUM_MASK 0x3F @@ -155,12 +150,12 @@ #define PCCARD_TPCE_MI_READONLY 0x10 #define PCCARD_TPCE_MI_AUDIO 0x08 #define PCCARD_TPCE_MI_MAXTWINS 0x07 -#define PCCARD_CISTPL_DEVICE_OC 0x1C -#define PCCARD_CISTPL_DEVICE_OA 0x1D -#define PCCARD_CISTPL_DEVICE_GEO 0x1E -#define PCCARD_CISTPL_DEVICE_GEO_A 0x1F -#define PCCARD_CISTPL_MANFID 0x20 -#define PCCARD_CISTPL_FUNCID 0x21 +#define CISTPL_DEVICE_OC 0x1C +#define CISTPL_DEVICE_OA 0x1D +#define CISTPL_DEVICE_GEO 0x1E +#define CISTPL_DEVICE_GEO_A 0x1F +#define CISTPL_MANFID 0x20 +#define CISTPL_FUNCID 0x21 #define PCCARD_FUNCTION_UNSPEC -1 #define PCCARD_FUNCTION_MULTIFUNCTION 0 #define PCCARD_FUNCTION_MEMORY 1 @@ -173,7 +168,7 @@ #define PCCARD_FUNCTION_SCSI 8 #define PCCARD_FUNCTION_SECURITY 9 #define PCCARD_FUNCTION_INSTRUMENT 10 -#define PCCARD_CISTPL_FUNCE 0x22 +#define CISTPL_FUNCE 0x22 #define PCCARD_TPLFE_TYPE_LAN_TECH 0x01 #define PCCARD_TPLFE_TYPE_LAN_SPEED 0x02 #define PCCARD_TPLFE_TYPE_LAN_MEDIA 0x03 @@ -181,70 +176,29 @@ #define PCCARD_TPLFE_TYPE_LAN_CONN 0x05 #define PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE 0x01 #define PCCARD_TPLFE_DDI_PCCARD_ATA 0x01 -#define PCCARD_CISTPL_END 0xFF +#define CISTPL_END 0xFF /* Layer 2 Data Recording Format Tuples */ -#define PCCARD_CISTPL_SWIL 0x23 -/* #define PCCARD_CISTPL_RESERVED 0x24-0x3F */ -#define PCCARD_CISTPL_VERS_2 0x40 -#define PCCARD_CISTPL_FORMAT 0x41 -#define PCCARD_CISTPL_GEOMETRY 0x42 -#define PCCARD_CISTPL_BYTEORDER 0x43 -#define PCCARD_CISTPL_DATE 0x44 -#define PCCARD_CISTPL_BATTERY 0x45 -#define PCCARD_CISTPL_FORAMT_A 0x47 +#define CISTPL_SWIL 0x23 +/* #define CISTPL_RESERVED 0x24-0x3F */ +#define CISTPL_VERS_2 0x40 +#define CISTPL_FORMAT 0x41 +#define CISTPL_GEOMETRY 0x42 +#define CISTPL_BYTEORDER 0x43 +#define CISTPL_DATE 0x44 +#define CISTPL_BATTERY 0x45 +#define CISTPL_FORAMT_A 0x47 /* Layer 3 Data Organization Tuples */ -#define PCCARD_CISTPL_ORG 0x46 -/* #define PCCARD_CISTPL_RESERVED 0x47-0x7F */ +#define CISTPL_ORG 0x46 +/* #define CISTPL_RESERVED 0x47-0x7F */ /* Layer 4 System-Specific Standard Tuples */ -/* #define PCCARD_CISTPL_RESERVED 0x80-0x8F */ -#define PCCARD_CISTPL_SPCL 0x90 -/* #define PCCARD_CISTPL_RESERVED 0x90-0xFE */ - -/* - * Card Configuration Registers - */ - -#define PCCARD_CCR_OPTION 0x00 -#define PCCARD_CCR_OPTION_SRESET 0x80 -#define PCCARD_CCR_OPTION_LEVIREQ 0x40 -#define PCCARD_CCR_OPTION_CFINDEX 0x3F -#define PCCARD_CCR_OPTION_IREQ_ENABLE 0x04 -#define PCCARD_CCR_OPTION_ADDR_DECODE 0x02 -#define PCCARD_CCR_OPTION_FUNC_ENABLE 0x01 -#define PCCARD_CCR_STATUS 0x02 -#define PCCARD_CCR_STATUS_PINCHANGED 0x80 -#define PCCARD_CCR_STATUS_SIGCHG 0x40 -#define PCCARD_CCR_STATUS_IOIS8 0x20 -#define PCCARD_CCR_STATUS_RESERVED1 0x10 -#define PCCARD_CCR_STATUS_AUDIO 0x08 -#define PCCARD_CCR_STATUS_PWRDWN 0x04 -#define PCCARD_CCR_STATUS_INTR 0x02 -#define PCCARD_CCR_STATUS_INTRACK 0x01 -#define PCCARD_CCR_PIN 0x04 -#define PCCARD_CCR_PIN_CBVD1 0x80 -#define PCCARD_CCR_PIN_CBVD2 0x40 -#define PCCARD_CCR_PIN_CRDYBSY 0x20 -#define PCCARD_CCR_PIN_CWPROT 0x10 -#define PCCARD_CCR_PIN_RBVD1 0x08 -#define PCCARD_CCR_PIN_RBVD2 0x04 -#define PCCARD_CCR_PIN_RRDYBSY 0x02 -#define PCCARD_CCR_PIN_RWPROT 0x01 -#define PCCARD_CCR_SOCKETCOPY 0x06 -#define PCCARD_CCR_SOCKETCOPY_RESERVED 0x80 -#define PCCARD_CCR_SOCKETCOPY_COPY_MASK 0x70 -#define PCCARD_CCR_SOCKETCOPY_COPY_SHIFT 4 -#define PCCARD_CCR_SOCKETCOPY_SOCKET_MASK 0x0F -#define PCCARD_CCR_EXTSTATUS 0x08 -#define PCCARD_CCR_IOBASE0 0x0A -#define PCCARD_CCR_IOBASE1 0x0C -#define PCCARD_CCR_IOBASE2 0x0E -#define PCCARD_CCR_IOBASE3 0x10 -#define PCCARD_CCR_IOSIZE 0x12 +/* #define CISTPL_RESERVED 0x80-0x8F */ +#define CISTPL_SPCL 0x90 +/* #define CISTPL_RESERVED 0x90-0xFE */ -#define PCCARD_CCR_SIZE 0x14 +#define CISTPL_GENERIC -1 diff --git a/sys/bus/pccard/pccard_cis_quirks.c b/sys/bus/pccard/pccard_cis_quirks.c index cd0537ad9b..5b327cec70 100644 --- a/sys/bus/pccard/pccard_cis_quirks.c +++ b/sys/bus/pccard/pccard_cis_quirks.c @@ -1,10 +1,10 @@ /* $NetBSD: pcmcia_cis_quirks.c,v 1.6 2000/04/12 21:07:55 scw Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccard_cis_quirks.c,v 1.7 2002/02/09 21:34:06 imp Exp $ */ -/* $DragonFly: src/sys/bus/pccard/pccard_cis_quirks.c,v 1.6 2006/12/22 23:12:16 swildner Exp $ */ +/* $FreeBSD: src/sys/dev/pccard/pccard_cis_quirks.c,v 1.15 2005/03/26 21:30:49 sam Exp $ */ +/* $DragonFly: src/sys/bus/pccard/pccard_cis_quirks.c,v 1.7 2007/07/05 12:08:53 sephe Exp $ */ #define PCCARDDEBUG -/* +/*- * Copyright (c) 1998 Marc Horowitz. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,19 +34,13 @@ */ #include -#include -#include -#include -#include -#include -#include - #include -#include +#include +#include -#include -#include +#include #include +#include /* There are cards out there whose CIS flat-out lies. This file contains struct pccard_function chains for those devices. */ @@ -205,6 +199,23 @@ static struct pccard_cis_quirk pccard_cis_quirks[] = { static int n_pccard_cis_quirks = sizeof(pccard_cis_quirks)/sizeof(pccard_cis_quirks[0]); +static int +pccard_cis_quirk_match(struct pccard_softc *sc, struct pccard_cis_quirk *q) +{ + if ((sc->card.manufacturer == q->manufacturer) && + (sc->card.product == q->product) && + (((sc->card.manufacturer != PCMCIA_VENDOR_INVALID) && + (sc->card.product != PCMCIA_PRODUCT_INVALID)) || + ((sc->card.manufacturer == PCMCIA_VENDOR_INVALID) && + (sc->card.product == PCMCIA_PRODUCT_INVALID) && + sc->card.cis1_info[0] && + (strcmp(sc->card.cis1_info[0], q->cis1_info[0]) == 0) && + sc->card.cis1_info[1] && + (strcmp(sc->card.cis1_info[1], q->cis1_info[1]) == 0)))) + return (1); + return (0); +} + void pccard_check_cis_quirks(device_t dev) { @@ -213,69 +224,70 @@ pccard_check_cis_quirks(device_t dev) int i, j; struct pccard_function *pf, *pf_next, *pf_last; struct pccard_config_entry *cfe, *cfe_next; + struct pccard_cis_quirk *q; pf = NULL; pf_last = NULL; for (i=0; icard.manufacturer == pccard_cis_quirks[i].manufacturer) && - (sc->card.product == pccard_cis_quirks[i].product) && - (((sc->card.manufacturer != PCMCIA_VENDOR_INVALID) && - (sc->card.product != PCMCIA_PRODUCT_INVALID)) || - ((sc->card.manufacturer == PCMCIA_VENDOR_INVALID) && - (sc->card.product == PCMCIA_PRODUCT_INVALID) && - sc->card.cis1_info[0] && - (strcmp(sc->card.cis1_info[0], - pccard_cis_quirks[i].cis1_info[0]) == 0) && - sc->card.cis1_info[1] && - (strcmp(sc->card.cis1_info[1], - pccard_cis_quirks[i].cis1_info[1]) == 0)))) { - if (!wiped) { - if (bootverbose) { - device_printf(dev, "using CIS quirks for "); - for (j = 0; j < 4; j++) { - if (sc->card.cis1_info[j] == NULL) - break; - if (j) - kprintf(", "); - kprintf("%s", sc->card.cis1_info[j]); - } - kprintf("\n"); + q = &pccard_cis_quirks[i]; + if (!pccard_cis_quirk_match(sc, q)) + continue; + if (!wiped) { + if (bootverbose) { + device_printf(dev, "using CIS quirks for "); + for (j = 0; j < 4; j++) { + if (sc->card.cis1_info[j] == NULL) + break; + if (j) + kprintf(", "); + kprintf("%s", sc->card.cis1_info[j]); } + kprintf("\n"); + } - for (pf = STAILQ_FIRST(&sc->card.pf_head); pf != NULL; - pf = pf_next) { - for (cfe = STAILQ_FIRST(&pf->cfe_head); cfe != NULL; - cfe = cfe_next) { - cfe_next = STAILQ_NEXT(cfe, cfe_list); - kfree(cfe, M_DEVBUF); - } - pf_next = STAILQ_NEXT(pf, pf_list); - kfree(pf, M_DEVBUF); + for (pf = STAILQ_FIRST(&sc->card.pf_head); pf != NULL; + pf = pf_next) { + for (cfe = STAILQ_FIRST(&pf->cfe_head); cfe != NULL; + cfe = cfe_next) { + cfe_next = STAILQ_NEXT(cfe, cfe_list); + kfree(cfe, M_DEVBUF); } - - STAILQ_INIT(&sc->card.pf_head); - wiped = 1; + pf_next = STAILQ_NEXT(pf, pf_list); + kfree(pf, M_DEVBUF); } - if (pf_last == pccard_cis_quirks[i].pf) { - cfe = kmalloc(sizeof(*cfe), M_DEVBUF, M_INTWAIT); - *cfe = *pccard_cis_quirks[i].cfe; - - STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list); - } else { - pf = kmalloc(sizeof(*pf), M_DEVBUF, M_INTWAIT); - *pf = *pccard_cis_quirks[i].pf; - STAILQ_INIT(&pf->cfe_head); - - cfe = kmalloc(sizeof(*cfe), M_DEVBUF, M_INTWAIT); - *cfe = *pccard_cis_quirks[i].cfe; - - STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list); - STAILQ_INSERT_TAIL(&sc->card.pf_head, pf, pf_list); + STAILQ_INIT(&sc->card.pf_head); + wiped = 1; + } - pf_last = pccard_cis_quirks[i].pf; + if (pf_last == q->pf) { + cfe = kmalloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT); + if (cfe == NULL) { + device_printf(dev, "no memory for quirk (1)\n"); + continue; + } + *cfe = *q->cfe; + STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list); + } else { + pf = kmalloc(sizeof(*pf), M_DEVBUF, M_NOWAIT); + if (pf == NULL) { + device_printf(dev, + "no memory for pccard function\n"); + continue; + } + *pf = *q->pf; + STAILQ_INIT(&pf->cfe_head); + cfe = kmalloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT); + if (cfe == NULL) { + kfree(pf, M_DEVBUF); + device_printf(dev, "no memory for quirk (2)\n"); + continue; } + *cfe = *q->cfe; + STAILQ_INSERT_TAIL(&pf->cfe_head, cfe, cfe_list); + STAILQ_INSERT_TAIL(&sc->card.pf_head, pf, pf_list); + pf_last = q->pf; } } } diff --git a/sys/bus/pccard/pccarddevs b/sys/bus/pccard/pccarddevs index a7b4d909b9..8a2d606f3d 100644 --- a/sys/bus/pccard/pccarddevs +++ b/sys/bus/pccard/pccarddevs @@ -1,10 +1,10 @@ -$DragonFly: src/sys/bus/pccard/pccarddevs,v 1.3 2004/07/23 11:46:09 joerg Exp $ +$DragonFly: src/sys/bus/pccard/pccarddevs,v 1.4 2007/07/05 12:08:53 sephe Exp $ +/* $FreeBSD: src/sys/dev/pccard/pccarddevs,v 1.112 2005/07/18 21:47:38 imp Exp $ */ /* $NetBSD: pcmciadevs,v 1.186 2003/09/16 08:26:37 onoe Exp $ */ /* $OpenBSD: pcmciadevs,v 1.93 2002/06/21 08:31:10 henning Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccarddevs,v 1.85 2004/05/13 01:24:26 imp Exp $ */ /*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998-2004 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -39,18 +39,52 @@ $DragonFly: src/sys/bus/pccard/pccarddevs,v 1.3 2004/07/23 11:46:09 joerg Exp $ * POSSIBILITY OF SUCH DAMAGE. */ +/*- + * Copyright (c) 1999-2004 The FreeBSD Project. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + */ + +/* + * Tuple registration list can be found at: + * http://www.pcmcia.org/tupleidlist.htm + */ + /* * List of known PCMCIA vendors, sorted by numeric ID. */ -vendor FUJITSU 0x0004 Fujitsu Corporation -vendor INTERSIL 0x000b Intersil +vendor FUJITSU 0x0004 Fujitsu Corporation +vendor INTERSIL 0x000b Intersil vendor PANASONIC 0x0032 Matsushita Electric Industrial Co. vendor SANDISK 0x0045 Sandisk Corporation vendor NEWMEDIA 0x0057 New Media Corporation vendor INTEL 0x0089 Intel vendor IBM 0x00a4 IBM Corporation -vendor SHARP 0x00b0 Sharp Corporation +vendor SHARP 0x00b0 Sharp Corporation +vendor TOSHIBA2 0x0098 Toshiba +vendor DIGITAL 0x0100 Digital Equipment Corporation vendor 3COM 0x0101 3Com Corporation vendor MEGAHERTZ 0x0102 Megahertz Corporation vendor SOCKET 0x0104 Socket Communications @@ -65,40 +99,45 @@ vendor OLICOM 0x0121 Olicom vendor PROXIM 0x0126 Proxim vendor DSPSI 0x0128 DSP Solutions, Inc vendor ADAPTEC 0x012f Adaptec Corporation +vendor MAGICRAM 0x0135 Magic Ram, Inc vendor QUATECH 0x0137 Quatech vendor COMPAQ 0x0138 Compaq vendor OSITECH 0x0140 Ositech -vendor DLINK_2 0x0143 D-Link -vendor DLINK_3 0x0149 D-Link +vendor GREY_CELL 0x0143 Grey Cell Systems, Ltd vendor LINKSYS 0x0149 Linksys Corporation vendor NETGEAR 0x0149 Netgear vendor SIMPLETECH 0x014d Simple Technology vendor SYMBOL2 0x014d Symbol vendor LUCENT 0x0156 Lucent Technologies +vendor AGERE 0x0156 Agere Systems vendor GEMPLUS 0x0157 Gemplus vendor AIRONET 0x015f Aironet Wireless Communications vendor ERICSSON 0x016b Ericsson vendor PSION 0x016c Psion +vendor PMC 0x0175 Premax Microelectronics Corp vendor COMPAQ2 0x0183 Compaq vendor PARALON 0x0183 Paralon Technologies Inc vendor KINGSTON 0x0186 Kingston vendor MELCO 0x018a Melco Corporation vendor DAYNA 0x0194 Dayna Corporation vendor RAYTHEON 0x01a6 Raytheon -vendor IODATA 0x01bf I-O DATA -vendor BAY 0x01eb Bay Networks -vendor FARALLON 0x0200 Farallon Communications -vendor TELECOMDEVICE 0x021b Telecom Device +vendor RACORE 0x01bf Racore Computer Products +vendor BAY 0x01eb Bay Networks +vendor FARALLON 0x0200 Farallon Communications +vendor RELIA 0x0215 RELIA Technologies Corporation +vendor TELECOMDEVICE 0x021b Telecom Device vendor NOKIA 0x023d Nokia Communications vendor SAMSUNG 0x0250 Samsung vendor HWN 0x0261 Home Wireless Networks +vendor ANYCOM 0x0264 Anycom vendor ARTEM 0x0268 ARtem vendor SYMBOL 0x026c Symbol vendor BUFFALO 0x026f BUFFALO (Melco Corporation) -vendor BROMAX 0x0274 Bromax communications, Inc +vendor BROMAX 0x0274 Bromax communications, Inc vendor IODATA2 0x028a I-O DATA vendor ASUS 0x02aa ASUS vendor SIEMENS 0x02ac Siemens +vendor UNGERMANN 0x02c0 Ungermann Bass vendor MICROSOFT 0x02d2 Microsoft Corporation /* @@ -111,18 +150,26 @@ vendor BONDWELL 0x3b01 Bondwell vendor LEXARMEDIA 0x4e01 Lexar Media vendor COMPEX 0x8a01 Compex Corporation vendor ZONET 0x8a01 Zonet Technology Inc. -vendor ELSA 0xd601 Elsa +vendor ADAPTEC2 0x9005 Adaptec +vendor ELSA 0xd601 Elsa -/* - * The following vendor IDs are not, as far as I can tell, actually - * assigned to these people. However, all the ones starting with '0xc' - * look coherent enough that maybe somebody other than PCMCIA is - * assigning numbers in that range. +/* + * The following vendor IDs are the vendor's PCI ID, not their PCMCIA + * IDs. NEWMEDIA2 should likely be 'Advansys' since that's who owns + * the PCI ID. */ vendor NEWMEDIA2 0x10cd NewMedia -vendor PLANEX_2 0x14ea PLANEX +vendor PLANEX 0x14ea PLANEX vendor ACTIONTEC 0x1668 ACTIONTEC -vendor AIRVAST 0x50c2 AirVast Technology +vendor RALINK 0x1814 Ralink Technology + +/* + * The following vendor IDs are not, as far as I can tell, actually + * assigned to these people by the pcmcia. However, all the ones starting + * with '0xc' look coherent enough that maybe somebody other than PCMCIA is + * assigning numbers in that range. Maybe JEITA? + */ +vendor AIRVAST 0x50c2 AirVast Technology vendor ARCHOS 0x5241 Archos vendor DUAL 0x890f Dual vendor EDIMAX 0x890f Edimax Technology Inc. @@ -132,7 +179,8 @@ vendor ROLAND 0xc00c Roland vendor COREGA2 0xc00f Corega K.K. vendor ALLIEDTELESIS 0xc00f Allied Telesis K.K. vendor HAGIWARASYSCOM 0xc012 Hagiwara SYS-COM -vendor RATOC 0xc015 RATOC System Inc. +vendor RATOC 0xc015 RATOC System Inc. +vendor NEXTCOM 0xc020 NextCom K.K. vendor WORKBIT 0xc024 WORKBIT vendor EMTAC 0xc250 EMTAC Technology Corporation @@ -146,7 +194,7 @@ product 3COM 3CRWE737A 0x0001 3Com AirConnect Wireless LAN product 3COM 3CXM056BNW 0x002f 3Com/NoteWorthy 3CXM056-BNW 56K Modem product 3COM 3CXEM556 0x0035 3Com/Megahertz 3CXEM556 Ethernet/Modem product 3COM 3CXEM556INT 0x003d 3Com/Megahertz 3CXEM556-INT Ethernet/Modem -product 3COM 3CRWB609 0x0400 3Com Bluetooth PC Card 3CRWB60-A +product 3COM 3CRWB609 0x0040 3Com Bluetooth PC Card 3CRWB60-A product 3COM 3CCFEM556BI 0x0556 3Com/Megahertz 3CCFEM556BI Ethernet/Modem product 3COM 3C562 0x0562 3Com 3c562 33.6 Modem/10Mbps Ethernet product 3COM 3C589 0x0589 3Com 3c589 10Mbps Ethernet @@ -161,6 +209,7 @@ product ACTIONTEC PRISM 0x0101 PRISM Wireless LAN PC Card /* Adaptec Products */ product ADAPTEC APA1460 0x0001 Adaptec APA-1460 SlimSCSI product ADAPTEC APA1460A 0x0002 Adaptec APA-1460A SlimSCSI +product ADAPTEC2 ANW8030 0x0021 Adaptec ANW-8030 /* Aironet */ product AIRONET PC4500 0x0005 Aironet PC4500 Wireless LAN Adapter @@ -173,6 +222,10 @@ product AIRVAST WN_100 0x7300 AirVast WN-100 /* Allied Telesis K.K. */ product ALLIEDTELESIS LA_PCM 0x0002 Allied Telesis LA-PCM +/* Anycom */ +product ANYCOM LSE041 0x0004 AnyCom BlueCard LSE041 R1B +product ANYCOM LSE039 0x0008 Anycom Bluetooth CF Card LSE039 + /* Archos */ product ARCHOS ARC_ATAPI 0x0043 MiniCD @@ -195,12 +248,16 @@ product BONDWELL B236 0x0000 Game Card Joystick product BREEZECOM BREEZENET 0x0102 BreezeCOM BreezeNET /* Bromax Communications, Inc (Linksys OEM) */ +product BROMAX IPORT 0x1103 iPort 10/100 Ethernet +product BROMAX IPORT2 0x1121 iPort 10Mbps Ethernet product BROMAX IWN 0x1612 Instant Wireless Network PC Card -product BROMAX IWN3 0x1613 Instant Wireless Network PC Card, Versin 3 +product BROMAX IWN3 0x1613 Instant Wireless Network PC Card, V3 product BROMAX WCF11 0x3301 Instant Wireless Network CF Card /* BUFFALO */ +product BUFFALO LPC2_CLT 0x0300 BUFFALO LPC2-CLT Ethernet product BUFFALO LPC3_CLX 0x0301 BUFFALO LPC3-CLX Ethernet Adapter +product BUFFALO LPC4_TX 0x0303 BUFFALO LPC4-TX Fast Ethernet product BUFFALO WLI_PCM_S11 0x0305 BUFFALO AirStation 11Mbps WLAN product BUFFALO LPC_CF_CLT 0x0307 BUFFALO LPC-CF-CLT product BUFFALO LPC3_CLT 0x030a BUFFALO LPC3-CLT Ethernet Adapter @@ -208,11 +265,14 @@ product BUFFALO WLI_CF_S11G 0x030b BUFFALO AirStation 11Mbps CF WLAN /* Compaq Products */ product COMPAQ NC5004 0x0002 Compaq Agency NC5004 Wireless Card +product COMPAQ CPQ550 0x110a Compaq Microcom CPQ550 Ethernet/Modem product COMPAQ2 CPQ_10_100 0x010a Compaq Netelligent 10/100 Ethernet /* Compex Products */ product COMPEX AMP_WIRELESS 0x0066 AMP product COMPEX LINKPORT_ENET_B 0x0100 Compex Linkport ENET-B Ethernet +product COMPEX LANMODEM 0xc0ab New Media LANSurfer 10+56 Ethernet/Modem +product COMPEX AX88190 0xc1ab AX88190 Fast Ethernet /* Contec C-NET(PC) */ product CONTEC CNETPC 0x0000 Contec C-NET(PC)C @@ -225,9 +285,6 @@ product DAYNA COMMUNICARD_E_2 0x002f Dayna CommuniCard E /* DIGITAL Products */ product DIGITAL MOBILE_MEDIA_CDROM 0x0d00 Digital Mobile Media CD-ROM -/* D-Link Products */ -product DLINK_2 DMF560TX 0xc0ab D-Link DMF-650TX - /* DSP Solutions, Inc. (Megahertz OEM) */ product DSPSI XJEM1144 0x0101 Megahertz X-JACK product DSPSI XJACK 0x0103 Megahertz X-JACK Ethernet @@ -243,6 +300,7 @@ product ELSA MC2_IEEE 0x0001 AirLancer MC-2 IEEE product ELSA XI300_IEEE 0x0002 XI300 Wireless LAN product ELSA XI800_IEEE 0x0004 XI800 CF Wireless LAN product ELSA XI325_IEEE 0x0005 XI325 Wireless LAN +product ELSA WIFI_FLASH 0x0101 802.11b plus 128MB Flash /* EMTAC */ product EMTAC WLAN 0x0002 EMTAC A2424i 11Mbps WLAN Card @@ -254,6 +312,7 @@ product ERICSSON WIRELESSLAN 0x0001 DSSS Wireless LAN PC Card product FARALLON SKYLINE 0x0a01 SkyLINE Wireless /* Fujutsu Products */ +product FUJITSU NE200T 0x0004 Eagle Tech NE200T product FUJITSU SCSI600 0x0401 Fujitsu SCSI 600 Interface product FUJITSU LA10S 0x1003 Fujitsu Compact Flash Ethernet product FUJITSU LA501 0x2000 Fujitsu Towa LA501 Ethernet @@ -262,6 +321,10 @@ product FUJITSU WL110 0x2003 PEGA-WL110 Wireless LAN /* Gemplus */ product GEMPLUS GPR400 0x3004 GPR400 Smartcard Reader +/* Grey Cell Systems, Ltd */ +product GREY_CELL TDK3000 0x3341 TDK 3000/3400/5670 Fast Ethernet/Modem +product GREY_CELL DMF650TX 0xc0ab D-Link DMF-650TX + /* Home Wireless Networks */ product HWN AIRWAY80211 0x0002 HWN Airway Wireless PCMCIA Card @@ -286,16 +349,17 @@ product INTEL PRO100LAN56 0x110a Intel EtherExpress PRO/100 LAN Modem /* Intersil */ /* OEMs sell these things under different marketing names */ -product INTERSIL MA401RA 0x7300 Netgear MA401RA -product INTERSIL DWL650 0x7110 Dlink DWL650 +product INTERSIL ISL37100P 0x7100 ISL37100P +product INTERSIL ISL37110P 0x7110 ISL37110P +product INTERSIL ISL37300P 0x7300 ISL37300P /* I-O DATA */ -product IODATA PCLATE 0x2216 I-O DATA PCLA/TE product IODATA2 WNB11PCM 0x0002 I-O DATA WN-B11/PCM product IODATA2 WCF12 0x0673 Wireless CF Card /* Kingston Products */ product KINGSTON KNE2 0x0100 Kingston KNE-PC2 Ethernet +product KINGSTON CIO10T 0x0110 Kingston CIO10T Ethernet /* Lasat Products */ product LASAT CREDIT_288 0x2811 Lasat Credit 288 Modem @@ -311,20 +375,26 @@ product LINKSYS COMBO_ECARD 0xc1ab Linksys Combo EthernetCard /* Lucent WaveLAN/IEEE */ product LUCENT WAVELAN_IEEE 0x0002 WaveLAN/IEEE +product AGERE HERMES_II 0x0003 Agere Systems Hermes-II Wireless +product AGERE HERMES_II_5 0x0004 Agere Systems Hermes-II.5 Wireless /* MACNICA */ product MACNICA ME1_JEIDA 0x3300 MACNICA ME1 for JEIDA product MACNICA MPS110 0xa041 MACNICA Miracle SCSI-II mPS110 +/* MagicRam, Inc */ +product MAGICRAM ETHER 0x0000 MagicRAM Ethernet PC Card 933926 + /* Megahertz Products */ +product MEGAHERTZ VARIOUS 0x0000 Megahertz X-jack Ethernet product MEGAHERTZ XJEM3336 0x0006 Megahertz X-JACK Ethernet Modem product MEGAHERTZ XJ4288 0x0023 Megahertz XJ4288 Modem product MEGAHERTZ XJ4336 0x0027 Megahertz XJ4336 Modem product MEGAHERTZ XJ5560 0x0034 Megahertz X-JACK 56kbps Modem /* Melco Products */ -product MELCO LPC3_TX 0xc1ab Melco LPC3-TX product MELCO LPC3_CLX 0x0301 Melco LPC3-CLX Ethernet Adapter +product MELCO LPC3_TX 0xc1ab Melco LPC3-TX /* Microsoft Products */ product MICROSOFT MN_520 0x0001 Microsoft MN-520 WLAN Card @@ -332,26 +402,34 @@ product MICROSOFT MN_520 0x0001 Microsoft MN-520 WLAN Card /* Motorola Products */ product MOTOROLA POWER144 0x0105 Motorola Power 14.4 Modem product MOTOROLA PM100C 0x0302 Motorola Personal Messenger 100C CDPD Modem +product MOTOROLA MARINER 0x0501 Motorola Mariner Ethernet/Modem product MOTOROLA MONTANA_336 0x0505 Motorola Montana 33.6 /* New Media Products */ product NEWMEDIA BASICS 0x0019 New Media BASICS Ethernet -product NEWMEDIA LANSURFER 0x0021 NewMedia LANSurfer -product NEWMEDIA LIVEWIRE 0x1004 NewMedia LiveWire Ethernet LAN Adapter -product NEWMEDIA MULTIMEDIA 0x100b NewMedia Multimedia +product NEWMEDIA LANSURFER 0x0021 New Media LANSurfer +product NEWMEDIA LIVEWIRE 0x1004 New Media LiveWire Ethernet LAN Adapter +product NEWMEDIA MULTIMEDIA 0x100b New Media Multimedia product NEWMEDIA BUSTOASTER2 0xa002 New Media SCSI Bus Toaster product NEWMEDIA BUSTOASTER 0xc102 New Media SCSI Bus Toaster product NEWMEDIA BUSTOASTER3 0xd302 New Media SCSI Bus Toaster -product NEWMEDIA WAVJAMMER 0xe005 NewMedia .WAVjammer -product NEWMEDIA2 BUSTOASTER 0x0001 NewMedia BusToaster +product NEWMEDIA WAVJAMMER 0xe005 New Media .WAVjammer +product NEWMEDIA2 BUSTOASTER 0x0001 New Media BusToaster /* Netgear */ -product NETGEAR FA410TX 0x0230 Netgear FA410TX product NETGEAR FA410TXC 0x4530 Netgear FA410TXC product NETGEAR FA411 0x0411 Netgear FA411 /* National Instruments */ +product NI PCMCIA_232 0x0d50 National Instruments PCMCIA-232 +product NI PCMCIA_232_2 0x0d51 National Instruments PCMCIA-232/2 +product NI PCMCIA_485 0x0d51 National Instruments PCMCIA-485 +product NI PCMCIA_485_2 0x0d52 National Instruments PCMCIA-485/2 product NI PCMCIA_GPIB 0x4882 National Instruments PCMCIA-GPIB +product NI PCMCIA_232_4 0xd180 National Instruments PCMCIA-232/4 + +/* NextCom K.K. */ +product NEXTCOM NEXTHAWK 0x0001 Next Hawk Ethernet /* Nokia Products */ product NOKIA C110_WLAN 0x1110 Nokia C110/C111 @@ -362,24 +440,32 @@ product NWN WLAN_550 0x0002 NWN 550 WLAN product NWN WLAN_1148 0x0003 NWN 1148 WLAN /* Olicom Products */ +product OLICOM OC2220 0x0101 GoCard Ethernet product OLICOM TR 0x2132 GoCard Token Ring 16/4 -product OLICOM OC2220 0x2022 GoCard Ethernet product OLICOM OC2231 0x3122 GoCard Combo Eth/Modem 288 product OLICOM OC2232 0x3222 GoCard Combo Eth/Modem 336 /* Ositech Products */ -product OSITECH TRUMPCARD_SOD 0x0008 Ositech Seven of Diamonds Ethernet Card +product OSITECH JACK_144 0x0001 Ositech Jack of ??? 14.4 +product OSITECH JACK_288 0x0002 Ositech Jack of ??? 28.8 +product OSITECH JACK_336 0x0007 Ositech Jack of ??? 33.6 +product OSITECH TRUMP_SOD 0x0008 Ositech Seven of Diamonds Ethernet Card +product OSITECH TRUMP_JOH 0x000a Ositech Jack of Hearts /* Panasonic Products */ product PANASONIC KXLC002 0x0304 Panasonic 4X CD-ROM Interface Card product PANASONIC KXLC003 0x0504 Panasonic 8X CD-ROM Interface Card product PANASONIC KXLC004 0x0604 Panasonic KXL-810AN Interface Card +product PANASONIC KXLC005_2 0x0704 Panasonic 16X CD-ROM Interface Card +product PANASONIC KME 0x2604 Panasonic CD-R/RW Interface product PANASONIC KXLC005 0x2704 Panasonic 16X CD-ROM Interface Card product PANASONIC KXLC005_1 0x2904 Panasonic 16X CD-ROM Interface Card -product PANASONIC KME 0x2604 Panasonic CD-R/RW Interface /* Planex */ -product PLANEX_2 GWNS11H 0xb001 Planex GW-NS11H +product PLANEX GWNS11H 0xb001 Planex GW-NS11H + +/* Premax Microelectronics Corp. */ +product PMC LANMODEM 0x0000 LAN 33.6 Modem card /* Proxim */ product PROXIM HARMONY 0x0002 Proxim HARMONY 80211B @@ -389,6 +475,9 @@ product PROXIM RANGELANDS_8430 0x8000 Proxim RangeLAN-DS 8430 /* Psion */ product PSION GOLDCARD 0x0020 Psion Gold Card +product PSION NETGLOBAL 0x0023 Psion Gold Card NetGlobal 10/100 +product PSION NETGLOBAL2 0x0026 Psion Gold Card NetGlobal 10/100 +product PSION LANGLOBAL 0x0081 Psion LANGLOBAL /* QLogic */ product QLOGIC PC05 0x0104 Qlogic Fast SCSI @@ -396,14 +485,31 @@ product QLOGIC PC05 0x0104 Qlogic Fast SCSI /* Quatech */ product QUATECH SPP_100 0x0003 Quatech Enhanced Parallel Port product QUATECH DSP_225 0x0008 Quatech Dual Serial Port +product QUATECH DUAL 0x000e Quatech Dual Serial Port +product QUATECH QUAD_RS232 0x001b Quatech Quad RS-232 +product QUATECH QSP_100 0x0025 Quatech Quad serial Port +product QUATECH QUAD_422 0x0045 Quatech Quad serial Port +product QUATECH DUAL_RS232 0x0052 Quatech Dual RS-232 /* RATOC System Inc. Products */ /* Don't use because both cards have same product id */ -product RATOC REX_R280_9530 0x0001 RATOC REX-R280/REX-9530 +product RATOC REX_R280_9530 0x0001 RATOC REX-R280/REX-9530/CFU01 + +/* Racore Computer Products */ +product RACORE ACCTON_EN2226 0x010a Accton Fast EtherCard +product RACORE ETHERNET 0x2216 Racore PC Card Ethernet +product RACORE FASTENET 0x2328 Racore PC Card Fast Ethernet +product RACORE 8041TX 0x8041 SMC8041-TX + +/* Ralink Technology products */ +product RALINK RT2560 0x0201 RT2500 wireless adapter /* Raylink/WebGear */ product RAYTHEON WLAN 0x0000 WLAN Adapter +/* RELIA Technologies Corporation */ +product RELIA COMBO 0x2452 Reliable Combo-L/M-56K + /* Roland */ product ROLAND SCP55 0x0001 Roland SCP-55 @@ -425,6 +531,7 @@ product SIMPLETECH COMMUNICATOR288 0x0100 Simple Technology 28.8 Communicator product SIMPLETECH SPECTRUM24 0x801 Symbol Spectrum24 WLAN Adapter /* Standard Microsystems Corporation Products */ +product SMC SMC91C96 0x0001 SMC 91C96 Farallon EtherMac product SMC 8016 0x0105 SMC 8016 EtherCard product SMC EZCARD 0x8022 SMC EZCard 10 PCMCIA @@ -433,7 +540,9 @@ product SOCKET EA_ETHER 0x0000 Socket Communications EA product SOCKET LP_WLAN_CF 0x0001 Socket Communications Low Power WLAN Card product SOCKET PAGECARD 0x0003 Socket Communications PageCard product SOCKET DUAL_RS232 0x0006 Socket Communications Dual RS232 +product SOCKET ES_1000 0x000a Socket Communications Ethernet/RS-232 product SOCKET LP_ETHER 0x000d Socket Communications LP-E +product SOCKET DUAL_IO 0x0070 Socket Communications DUAL IO product SOCKET LP_ETHER_CF 0x0075 Socket Communications LP-E CF product SOCKET LP_ETH_10_100_CF 0x0145 Socket Communications 10/100 Ethernet @@ -446,9 +555,12 @@ product TDK LAK_CD021BX 0x0200 TDK LAK-CD021BX Ethernet product TDK LAK_CF010 0x0900 TDK LAC-CF010 product TDK DFL9610 0x0d0a TDK DFL9610 Ethernet & Digital Cellular product TDK C6500012 0x410a TDK ELSA MicroLink MC all +product TDK GN3410 0x4815 TDK GlobalNetworker 3410 product TDK LAK_CD031 0xc1ab TDK LAK-CD031 Ethernet +product TDK DFL5610WS 0xea15 TDK DFL5610WS Ethernet/Modem /* Telecom Device */ +product TELECOMDEVICE LM5LT 0x0101 Billionton LM5LT-10B Ethernet/Modem product TELECOMDEVICE TCD_HPC100 0x0202 Telecom Device TCD-HPC100 /* US Robotics Products */ @@ -492,7 +604,6 @@ vendor AMD -1 AMD vendor BILLIONTON -1 Billionton Systems Inc. vendor CNET -1 CNet vendor COREGA -1 Corega K.K. -vendor DIGITAL -1 Digital Equipment Corporation vendor DLINK -1 D-Link vendor DYNALINK -1 DynaLink vendor EIGERLABS -1 Eiger labs,Inc. @@ -507,16 +618,14 @@ vendor INTERSIL2 -1 Intersil vendor IODATA3 -1 I-O DATA vendor LANTECH -1 Lantech Computer Company vendor MELCO2 -1 Melco Corporation -vendor NAKAGAWAMETAL -1 NAKAGAWA METAL vendor NDC -1 NDC vendor NEC -1 NEC vendor OEM2 -1 Generic OEM vendor PLANET -1 Planet -vendor PLANEX -1 Planex Communications Inc vendor PREMAX -1 Premax vendor RPTI -1 RPTI vendor SVEC -1 SVEC/Hawking Technology -vendor SYNERGY21 -1 Synergy 21 +vendor TAMARACK -1 Tamarack vendor TEAC -1 TEAC vendor TOSHIBA -1 TOSHIBA vendor WORKBIT2 -1 WORKBIT @@ -526,7 +635,6 @@ vendor ZOOM -1 ZOOM product ACCTON EN2212 { "ACCTON", "EN2212", NULL, NULL } Accton EN2212 product ACCTON EN2216 { "ACCTON", "EN2216-PCMCIA-ETHERNET", "EN2216R01", NULL } Accton EN2216 -product ACCTON EN2226 { "Accton", "Fast&spEtherCard-16", "EN2226", "1.00" } Accton EN2226 product ADDTRON AWP100 { "Addtron", "AWP-100&spWireless&spPCMCIA", "Version&sp01.02", NULL } product ALLIEDTELESIS WR211PCM { "Allied&spTelesis&spK.K.", "WR211PCM", NULL, NULL } Allied Telesis WR211PCM product AMBICOM AMB8002T { "AmbiCom&spInc", "AMB8002T", NULL, NULL } AmbiCom AMB8002T @@ -547,7 +655,6 @@ product COREGA WIRELESS_LAN_PCCA_11 { "corega&spK.K.", "Wireless&spLAN&spPCCA-11 product COREGA WIRELESS_LAN_PCCB_11 { "corega_K.K.", "Wireless_LAN_PCCB-11", NULL, NULL } Corega Wireless LAN PCCB-11 product COREGA WIRELESS_LAN_PCCL_11 { "corega", "WL&spPCCL-11", NULL, NULL } Corega Wireless LAN PCCL-11 -product DIGITAL DEPCMXX { "DIGITAL", "DEPCM-XX", NULL, NULL } DEC DEPCM-BA product DLINK DE650 { "D-Link", "DE-650", NULL, NULL } D-Link DE-650 product DLINK DE660 { "D-Link", "DE-660", NULL, NULL } D-Link DE-660 product DLINK DE660PLUS { "D-Link", "DE-660+", NULL, NULL } D-Link DE-660+ @@ -573,16 +680,14 @@ product GEMTEK WLAN { "Intersil", "PRISM&sp2_5&spPCMCIA&spADAPTER", "ISL37300P" product IBM SCSICARD { "IBM&spCorp.", "SCSI&spPCMCIA&spCard", NULL, NULL } IBM SCSI PCMCIA Card product ICOM SL200 { "Icom", "SL-200", NULL, NULL } Icom SL-200 product INTERSIL2 PRISM2 { "INTERSIL", "HFA384x/IEEE", "Version&sp01.02", NULL } Intersil Prism II -product IODATA CBIDE2 { "IO&spDATA", "CBIDE2&sp&sp&sp&sp&sp&sp", NULL, NULL } IO-DATA CBIDE2/16-bit mode +product IODATA3 CBIDE2 { "IO&spDATA", "CBIDE2&sp&sp&sp&sp&sp&sp", NULL, NULL } IO-DATA CBIDE2/16-bit mode product IODATA3 CBSC16 { "IO&spDATA", "CBSC16&sp&sp&sp&sp&sp&sp&sp", NULL, NULL } IO-DATA CBSC16 -product IODATA PCLAT { "I-O&spDATA", "PCLA", "ETHERNET", NULL } IO-DATA PCLA/T +product IODATA3 PCLAT { "I-O&spDATA", "PCLA", "ETHERNET", NULL } IO-DATA PCLA/T product LANTECH FASTNETTX { "ASIX", "AX88190", NULL, NULL } Lantech Fastnet/TX product LINKSYS ECARD_2 { "LINKSYS", "E-CARD", NULL, NULL } Linksys E-Card -product LINKSYS PCM100 { "Linksys", "EtherFast&sp10/100&spIntegrated&spPC&spCard&sp(PCM100)", "Ver&sp1.0", NULL } product MACNICA MPS100 { "MACNICA", "MIRACLE&spSCSI", "mPS100", "D.0" } Macnica Miracle SCSI mPS100 product MEGAHERTZ XJ2288 { "MEGAHERTZ", "MODEM&spXJ2288", NULL, NULL } Megahertz XJ2288 Modem product MELCO2 LPC2_TX { "MELCO", "LPC2-TX", NULL, NULL } Melco LPC2-TX -product NAKAGAWAMETAL LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL } NAKAGAWA METAL LNT-10TN NE2000 Compatible Card product NANOSPEED PRISM2 { "NANOSPEED", "HFA384x/IEEE", "Version&sp01.02", NULL } NANOSPEED ROOT-RZ2000 WLAN Card product NDC ND5100_E { "NDC", "Ethernet", "A", NULL } Sohoware ND5100E NE2000 Compatible Card product NEC CMZ_RT_WP { "NEC", "Wireless&spCard&spCMZ-RT-WP", "Version&sp01.01", NULL } NEC Wireless Card CMZ-RT-WP @@ -591,13 +696,8 @@ product NEWMEDIA BASICS_SCSI { "BASICS&spby&spNew&spMedia&spCorporation" "SCSI&s product NTT_ME WLAN { "NTT-ME", "11Mbps&spWireless&spLAN&spPC&spCard", NULL, NULL } NTT-ME 11Mbps Wireless LAN PC Card product OEM2 CDROM1 { "PCMCIA", "CD-ROM", NULL, NULL } Generic PCMCIA CD-ROM product OEM2 IDE { "PCMCIA", "IDE&spCARD", NULL, NULL } Generic PCMCIA IDE CARD +product OEM2 ETHERNET { "PCMCIA", "Ethernet", NULL, NULL } NE2000 PC Card product PLANET SMARTCOM2000 { "PCMCIA", "UE2212", NULL, NULL } Planet SmartCOM 2000 -/* - * vendor ID of both FNW-3600-T and FNW-3700-T is LINKSYS (0x0149) and - * product ID is 0xc1ab, but it conflicts with LINKSYS Combo EthernetCard. - */ -product PLANEX FNW3600T -1 Planex FNW-3600-T -product PLANEX FNW3700T -1 Planex FNW-3700-T product RPTI EP400 { "RPTI&spLTD.", "EP400", "CISV100", NULL } RPTI EP400 product RPTI EP401 { "RPTI", "EP401&spEthernet&spNE2000&spCompatible", NULL, NULL } RPTI EP401 product PREMAX PE200 { "PMX&sp&sp&sp", "PE-200", NULL, NULL } PreMax PE-200 @@ -607,12 +707,15 @@ product RATOC REX5536AM { "PCMCIA&spSCSI&spMBH10404", "01", NULL, NULL } RATOC product RATOC REX5536M { "PCMCIA&spSCSI2&spCARD", "01", NULL, NULL } RATOC REX-5536M product RATOC REX5572 { "RATOC&spSystem&spInc.", "SOUND/SCSI2&spCARD", NULL, NULL } RATOC REX-5572 product RATOC REX9530 { "RATOC&spSystem&spInc.", "SCSI2&spCARD&sp37", NULL, NULL } RATOC REX-9530 +product RATOC REX_CFU1 { "RATOC", "USB&spHOST&spCF+&spCard", NULL, NULL } RATOC REX-CFU1 product SIMPLETECH SPECTRUM24_ALT { "Symbol&spTechnologies", "LA4111&spSpectrum24&spWireless&spLAN&spPC&spCard", NULL, NULL } LA4111 Spectrum24 Wireless LAN PC Card product SMC 2632W { "SMC", "SMC2632W", "Version&sp01.02", NULL } SMC 2632 EZ Connect Wireless PC Card -product SMC 8041 { "SMC", "8041TX-10/100-PC-Card-V2", NULL, NULL } SMC 8041TX 10/100 PC Card +product SMC 8000 { "SMC8000", "DEV1", NULL, NULL } +product SMC 8020BT { "SMC" "EtherEZ&spEthernet&sp8020", NULL, NULL } +product SMC 8020BTM { "SMC", "EtherEZ&spEthernet/Modem", "8020", NULL } product SVEC COMBOCARD { "Ethernet", "Adapter", NULL, NULL } SVEC/Hawking Tech. Combo Card product SVEC LANCARD { "SVEC", "FD605&spPCMCIA&spEtherNet&spCard", "V1-1", NULL } SVEC PCMCIA Lan Card -product SYNERGY21 S21810 { "PCMCIA", "Ethernet", "A", "004743118001" } Synergy 21 S21810+ NE2000 Compatible Card +product TAMARACK ETHERNET { "TAMARACK", "Ethernet", NULL, NULL } TAMARACK NE2000 PC Card product TEAC IDECARDII { NULL, "NinjaATA-", NULL, NULL } TEAC IDE Card/II product TOSHIBA CBIDE2 { "LOOKMEET", "CBIDE2&sp&sp&sp&sp&sp&sp", NULL, NULL } TOSHIBA PA2673U CBIDE2/16-bit mode (IO-DATA OEM) product WORKBIT2 NINJA_SCSI3 { "WBT", "NinjaSCSI-3", NULL, NULL } WORKBIT Ninja SCSI series diff --git a/sys/bus/pccard/pccarddevs.h b/sys/bus/pccard/pccarddevs.h index b56c3c257d..d2daa95f24 100644 --- a/sys/bus/pccard/pccarddevs.h +++ b/sys/bus/pccard/pccarddevs.h @@ -1,17 +1,17 @@ -/* $DragonFly: src/sys/bus/pccard/pccarddevs.h,v 1.3 2004/07/23 11:46:50 joerg Exp $ */ +/* $DragonFly: src/sys/bus/pccard/pccarddevs.h,v 1.4 2007/07/05 12:08:53 sephe Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * DragonFly: src/sys/bus/pccard/pccarddevs,v 1.3 2004/07/23 11:46:09 joerg Exp + * DragonFly */ +/* $FreeBSD: src/sys/dev/pccard/pccarddevs,v 1.112 2005/07/18 21:47:38 imp Exp $ */ /* $NetBSD: pcmciadevs,v 1.186 2003/09/16 08:26:37 onoe Exp $ */ /* $OpenBSD: pcmciadevs,v 1.93 2002/06/21 08:31:10 henning Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccarddevs,v 1.85 2004/05/13 01:24:26 imp Exp $ */ /*- - * Copyright (c) 1998 The NetBSD Foundation, Inc. + * Copyright (c) 1998-2004 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -46,6 +46,38 @@ * POSSIBILITY OF SUCH DAMAGE. */ +/*- + * Copyright (c) 1999-2004 The FreeBSD Project. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + */ + +/* + * Tuple registration list can be found at: + * http://www.pcmcia.org/tupleidlist.htm + */ + /* * List of known PCMCIA vendors, sorted by numeric ID. */ @@ -58,6 +90,8 @@ #define PCMCIA_VENDOR_INTEL 0x0089 /* Intel */ #define PCMCIA_VENDOR_IBM 0x00a4 /* IBM Corporation */ #define PCMCIA_VENDOR_SHARP 0x00b0 /* Sharp Corporation */ +#define PCMCIA_VENDOR_TOSHIBA2 0x0098 /* Toshiba */ +#define PCMCIA_VENDOR_DIGITAL 0x0100 /* Digital Equipment Corporation */ #define PCMCIA_VENDOR_3COM 0x0101 /* 3Com Corporation */ #define PCMCIA_VENDOR_MEGAHERTZ 0x0102 /* Megahertz Corporation */ #define PCMCIA_VENDOR_SOCKET 0x0104 /* Socket Communications */ @@ -72,33 +106,37 @@ #define PCMCIA_VENDOR_PROXIM 0x0126 /* Proxim */ #define PCMCIA_VENDOR_DSPSI 0x0128 /* DSP Solutions, Inc */ #define PCMCIA_VENDOR_ADAPTEC 0x012f /* Adaptec Corporation */ +#define PCMCIA_VENDOR_MAGICRAM 0x0135 /* Magic Ram, Inc */ #define PCMCIA_VENDOR_QUATECH 0x0137 /* Quatech */ #define PCMCIA_VENDOR_COMPAQ 0x0138 /* Compaq */ #define PCMCIA_VENDOR_OSITECH 0x0140 /* Ositech */ -#define PCMCIA_VENDOR_DLINK_2 0x0143 /* D-Link */ -#define PCMCIA_VENDOR_DLINK_3 0x0149 /* D-Link */ +#define PCMCIA_VENDOR_GREY_CELL 0x0143 /* Grey Cell Systems, Ltd */ #define PCMCIA_VENDOR_LINKSYS 0x0149 /* Linksys Corporation */ #define PCMCIA_VENDOR_NETGEAR 0x0149 /* Netgear */ #define PCMCIA_VENDOR_SIMPLETECH 0x014d /* Simple Technology */ #define PCMCIA_VENDOR_SYMBOL2 0x014d /* Symbol */ #define PCMCIA_VENDOR_LUCENT 0x0156 /* Lucent Technologies */ +#define PCMCIA_VENDOR_AGERE 0x0156 /* Agere Systems */ #define PCMCIA_VENDOR_GEMPLUS 0x0157 /* Gemplus */ #define PCMCIA_VENDOR_AIRONET 0x015f /* Aironet Wireless Communications */ #define PCMCIA_VENDOR_ERICSSON 0x016b /* Ericsson */ #define PCMCIA_VENDOR_PSION 0x016c /* Psion */ +#define PCMCIA_VENDOR_PMC 0x0175 /* Premax Microelectronics Corp */ #define PCMCIA_VENDOR_COMPAQ2 0x0183 /* Compaq */ #define PCMCIA_VENDOR_PARALON 0x0183 /* Paralon Technologies Inc */ #define PCMCIA_VENDOR_KINGSTON 0x0186 /* Kingston */ #define PCMCIA_VENDOR_MELCO 0x018a /* Melco Corporation */ #define PCMCIA_VENDOR_DAYNA 0x0194 /* Dayna Corporation */ #define PCMCIA_VENDOR_RAYTHEON 0x01a6 /* Raytheon */ -#define PCMCIA_VENDOR_IODATA 0x01bf /* I-O DATA */ +#define PCMCIA_VENDOR_RACORE 0x01bf /* Racore Computer Products */ #define PCMCIA_VENDOR_BAY 0x01eb /* Bay Networks */ #define PCMCIA_VENDOR_FARALLON 0x0200 /* Farallon Communications */ +#define PCMCIA_VENDOR_RELIA 0x0215 /* RELIA Technologies Corporation */ #define PCMCIA_VENDOR_TELECOMDEVICE 0x021b /* Telecom Device */ #define PCMCIA_VENDOR_NOKIA 0x023d /* Nokia Communications */ #define PCMCIA_VENDOR_SAMSUNG 0x0250 /* Samsung */ #define PCMCIA_VENDOR_HWN 0x0261 /* Home Wireless Networks */ +#define PCMCIA_VENDOR_ANYCOM 0x0264 /* Anycom */ #define PCMCIA_VENDOR_ARTEM 0x0268 /* ARtem */ #define PCMCIA_VENDOR_SYMBOL 0x026c /* Symbol */ #define PCMCIA_VENDOR_BUFFALO 0x026f /* BUFFALO (Melco Corporation) */ @@ -106,6 +144,7 @@ #define PCMCIA_VENDOR_IODATA2 0x028a /* I-O DATA */ #define PCMCIA_VENDOR_ASUS 0x02aa /* ASUS */ #define PCMCIA_VENDOR_SIEMENS 0x02ac /* Siemens */ +#define PCMCIA_VENDOR_UNGERMANN 0x02c0 /* Ungermann Bass */ #define PCMCIA_VENDOR_MICROSOFT 0x02d2 /* Microsoft Corporation */ /* @@ -118,17 +157,25 @@ #define PCMCIA_VENDOR_LEXARMEDIA 0x4e01 /* Lexar Media */ #define PCMCIA_VENDOR_COMPEX 0x8a01 /* Compex Corporation */ #define PCMCIA_VENDOR_ZONET 0x8a01 /* Zonet Technology Inc. */ +#define PCMCIA_VENDOR_ADAPTEC2 0x9005 /* Adaptec */ #define PCMCIA_VENDOR_ELSA 0xd601 /* Elsa */ -/* - * The following vendor IDs are not, as far as I can tell, actually - * assigned to these people. However, all the ones starting with '0xc' - * look coherent enough that maybe somebody other than PCMCIA is - * assigning numbers in that range. +/* + * The following vendor IDs are the vendor's PCI ID, not their PCMCIA + * IDs. NEWMEDIA2 should likely be 'Advansys' since that's who owns + * the PCI ID. */ #define PCMCIA_VENDOR_NEWMEDIA2 0x10cd /* NewMedia */ -#define PCMCIA_VENDOR_PLANEX_2 0x14ea /* PLANEX */ +#define PCMCIA_VENDOR_PLANEX 0x14ea /* PLANEX */ #define PCMCIA_VENDOR_ACTIONTEC 0x1668 /* ACTIONTEC */ +#define PCMCIA_VENDOR_RALINK 0x1814 /* Ralink Technology */ + +/* + * The following vendor IDs are not, as far as I can tell, actually + * assigned to these people by the pcmcia. However, all the ones starting + * with '0xc' look coherent enough that maybe somebody other than PCMCIA is + * assigning numbers in that range. Maybe JEITA? + */ #define PCMCIA_VENDOR_AIRVAST 0x50c2 /* AirVast Technology */ #define PCMCIA_VENDOR_ARCHOS 0x5241 /* Archos */ #define PCMCIA_VENDOR_DUAL 0x890f /* Dual */ @@ -140,6 +187,7 @@ #define PCMCIA_VENDOR_ALLIEDTELESIS 0xc00f /* Allied Telesis K.K. */ #define PCMCIA_VENDOR_HAGIWARASYSCOM 0xc012 /* Hagiwara SYS-COM */ #define PCMCIA_VENDOR_RATOC 0xc015 /* RATOC System Inc. */ +#define PCMCIA_VENDOR_NEXTCOM 0xc020 /* NextCom K.K. */ #define PCMCIA_VENDOR_WORKBIT 0xc024 /* WORKBIT */ #define PCMCIA_VENDOR_EMTAC 0xc250 /* EMTAC Technology Corporation */ @@ -162,7 +210,7 @@ #define PCMCIA_PRODUCT_3COM_3CXEM556INT 0x003d #define PCMCIA_STR_3COM_3CXEM556INT "3Com/Megahertz 3CXEM556-INT Ethernet/Modem" #define PCMCIA_CIS_3COM_3CRWB609 { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_3COM_3CRWB609 0x0400 +#define PCMCIA_PRODUCT_3COM_3CRWB609 0x0040 #define PCMCIA_STR_3COM_3CRWB609 "3Com Bluetooth PC Card 3CRWB60-A" #define PCMCIA_CIS_3COM_3CCFEM556BI { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_3COM_3CCFEM556BI 0x0556 @@ -198,6 +246,9 @@ #define PCMCIA_CIS_ADAPTEC_APA1460A { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_ADAPTEC_APA1460A 0x0002 #define PCMCIA_STR_ADAPTEC_APA1460A "Adaptec APA-1460A SlimSCSI" +#define PCMCIA_CIS_ADAPTEC2_ANW8030 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_ADAPTEC2_ANW8030 0x0021 +#define PCMCIA_STR_ADAPTEC2_ANW8030 "Adaptec ANW-8030" /* Aironet */ #define PCMCIA_CIS_AIRONET_PC4500 { NULL, NULL, NULL, NULL } @@ -220,6 +271,14 @@ #define PCMCIA_PRODUCT_ALLIEDTELESIS_LA_PCM 0x0002 #define PCMCIA_STR_ALLIEDTELESIS_LA_PCM "Allied Telesis LA-PCM" +/* Anycom */ +#define PCMCIA_CIS_ANYCOM_LSE041 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_ANYCOM_LSE041 0x0004 +#define PCMCIA_STR_ANYCOM_LSE041 "AnyCom BlueCard LSE041 R1B" +#define PCMCIA_CIS_ANYCOM_LSE039 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_ANYCOM_LSE039 0x0008 +#define PCMCIA_STR_ANYCOM_LSE039 "Anycom Bluetooth CF Card LSE039" + /* Archos */ #define PCMCIA_CIS_ARCHOS_ARC_ATAPI { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_ARCHOS_ARC_ATAPI 0x0043 @@ -260,20 +319,32 @@ #define PCMCIA_STR_BREEZECOM_BREEZENET "BreezeCOM BreezeNET" /* Bromax Communications, Inc (Linksys OEM) */ +#define PCMCIA_CIS_BROMAX_IPORT { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_BROMAX_IPORT 0x1103 +#define PCMCIA_STR_BROMAX_IPORT "iPort 10/100 Ethernet" +#define PCMCIA_CIS_BROMAX_IPORT2 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_BROMAX_IPORT2 0x1121 +#define PCMCIA_STR_BROMAX_IPORT2 "iPort 10Mbps Ethernet" #define PCMCIA_CIS_BROMAX_IWN { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_BROMAX_IWN 0x1612 #define PCMCIA_STR_BROMAX_IWN "Instant Wireless Network PC Card" #define PCMCIA_CIS_BROMAX_IWN3 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_BROMAX_IWN3 0x1613 -#define PCMCIA_STR_BROMAX_IWN3 "Instant Wireless Network PC Card, Versin 3" +#define PCMCIA_STR_BROMAX_IWN3 "Instant Wireless Network PC Card, V3" #define PCMCIA_CIS_BROMAX_WCF11 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_BROMAX_WCF11 0x3301 #define PCMCIA_STR_BROMAX_WCF11 "Instant Wireless Network CF Card" /* BUFFALO */ +#define PCMCIA_CIS_BUFFALO_LPC2_CLT { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_BUFFALO_LPC2_CLT 0x0300 +#define PCMCIA_STR_BUFFALO_LPC2_CLT "BUFFALO LPC2-CLT Ethernet" #define PCMCIA_CIS_BUFFALO_LPC3_CLX { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_BUFFALO_LPC3_CLX 0x0301 #define PCMCIA_STR_BUFFALO_LPC3_CLX "BUFFALO LPC3-CLX Ethernet Adapter" +#define PCMCIA_CIS_BUFFALO_LPC4_TX { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_BUFFALO_LPC4_TX 0x0303 +#define PCMCIA_STR_BUFFALO_LPC4_TX "BUFFALO LPC4-TX Fast Ethernet" #define PCMCIA_CIS_BUFFALO_WLI_PCM_S11 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_BUFFALO_WLI_PCM_S11 0x0305 #define PCMCIA_STR_BUFFALO_WLI_PCM_S11 "BUFFALO AirStation 11Mbps WLAN" @@ -291,6 +362,9 @@ #define PCMCIA_CIS_COMPAQ_NC5004 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_COMPAQ_NC5004 0x0002 #define PCMCIA_STR_COMPAQ_NC5004 "Compaq Agency NC5004 Wireless Card" +#define PCMCIA_CIS_COMPAQ_CPQ550 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_COMPAQ_CPQ550 0x110a +#define PCMCIA_STR_COMPAQ_CPQ550 "Compaq Microcom CPQ550 Ethernet/Modem" #define PCMCIA_CIS_COMPAQ2_CPQ_10_100 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_COMPAQ2_CPQ_10_100 0x010a #define PCMCIA_STR_COMPAQ2_CPQ_10_100 "Compaq Netelligent 10/100 Ethernet" @@ -302,6 +376,12 @@ #define PCMCIA_CIS_COMPEX_LINKPORT_ENET_B { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_COMPEX_LINKPORT_ENET_B 0x0100 #define PCMCIA_STR_COMPEX_LINKPORT_ENET_B "Compex Linkport ENET-B Ethernet" +#define PCMCIA_CIS_COMPEX_LANMODEM { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_COMPEX_LANMODEM 0xc0ab +#define PCMCIA_STR_COMPEX_LANMODEM "New Media LANSurfer 10+56 Ethernet/Modem" +#define PCMCIA_CIS_COMPEX_AX88190 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_COMPEX_AX88190 0xc1ab +#define PCMCIA_STR_COMPEX_AX88190 "AX88190 Fast Ethernet" /* Contec C-NET(PC) */ #define PCMCIA_CIS_CONTEC_CNETPC { NULL, NULL, NULL, NULL } @@ -324,11 +404,6 @@ #define PCMCIA_PRODUCT_DIGITAL_MOBILE_MEDIA_CDROM 0x0d00 #define PCMCIA_STR_DIGITAL_MOBILE_MEDIA_CDROM "Digital Mobile Media CD-ROM" -/* D-Link Products */ -#define PCMCIA_CIS_DLINK_2_DMF560TX { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_DLINK_2_DMF560TX 0xc0ab -#define PCMCIA_STR_DLINK_2_DMF560TX "D-Link DMF-650TX" - /* DSP Solutions, Inc. (Megahertz OEM) */ #define PCMCIA_CIS_DSPSI_XJEM1144 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_DSPSI_XJEM1144 0x0101 @@ -360,6 +435,9 @@ #define PCMCIA_CIS_ELSA_XI325_IEEE { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_ELSA_XI325_IEEE 0x0005 #define PCMCIA_STR_ELSA_XI325_IEEE "XI325 Wireless LAN" +#define PCMCIA_CIS_ELSA_WIFI_FLASH { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_ELSA_WIFI_FLASH 0x0101 +#define PCMCIA_STR_ELSA_WIFI_FLASH "802.11b plus 128MB Flash" /* EMTAC */ #define PCMCIA_CIS_EMTAC_WLAN { NULL, NULL, NULL, NULL } @@ -377,6 +455,9 @@ #define PCMCIA_STR_FARALLON_SKYLINE "SkyLINE Wireless" /* Fujutsu Products */ +#define PCMCIA_CIS_FUJITSU_NE200T { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_FUJITSU_NE200T 0x0004 +#define PCMCIA_STR_FUJITSU_NE200T "Eagle Tech NE200T" #define PCMCIA_CIS_FUJITSU_SCSI600 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_FUJITSU_SCSI600 0x0401 #define PCMCIA_STR_FUJITSU_SCSI600 "Fujitsu SCSI 600 Interface" @@ -395,6 +476,14 @@ #define PCMCIA_PRODUCT_GEMPLUS_GPR400 0x3004 #define PCMCIA_STR_GEMPLUS_GPR400 "GPR400 Smartcard Reader" +/* Grey Cell Systems, Ltd */ +#define PCMCIA_CIS_GREY_CELL_TDK3000 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_GREY_CELL_TDK3000 0x3341 +#define PCMCIA_STR_GREY_CELL_TDK3000 "TDK 3000/3400/5670 Fast Ethernet/Modem" +#define PCMCIA_CIS_GREY_CELL_DMF650TX { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_GREY_CELL_DMF650TX 0xc0ab +#define PCMCIA_STR_GREY_CELL_DMF650TX "D-Link DMF-650TX" + /* Home Wireless Networks */ #define PCMCIA_CIS_HWN_AIRWAY80211 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_HWN_AIRWAY80211 0x0002 @@ -451,17 +540,17 @@ /* Intersil */ /* OEMs sell these things under different marketing names */ -#define PCMCIA_CIS_INTERSIL_MA401RA { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_INTERSIL_MA401RA 0x7300 -#define PCMCIA_STR_INTERSIL_MA401RA "Netgear MA401RA" -#define PCMCIA_CIS_INTERSIL_DWL650 { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_INTERSIL_DWL650 0x7110 -#define PCMCIA_STR_INTERSIL_DWL650 "Dlink DWL650" +#define PCMCIA_CIS_INTERSIL_ISL37100P { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_INTERSIL_ISL37100P 0x7100 +#define PCMCIA_STR_INTERSIL_ISL37100P "ISL37100P" +#define PCMCIA_CIS_INTERSIL_ISL37110P { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_INTERSIL_ISL37110P 0x7110 +#define PCMCIA_STR_INTERSIL_ISL37110P "ISL37110P" +#define PCMCIA_CIS_INTERSIL_ISL37300P { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_INTERSIL_ISL37300P 0x7300 +#define PCMCIA_STR_INTERSIL_ISL37300P "ISL37300P" /* I-O DATA */ -#define PCMCIA_CIS_IODATA_PCLATE { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_IODATA_PCLATE 0x2216 -#define PCMCIA_STR_IODATA_PCLATE "I-O DATA PCLA/TE" #define PCMCIA_CIS_IODATA2_WNB11PCM { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_IODATA2_WNB11PCM 0x0002 #define PCMCIA_STR_IODATA2_WNB11PCM "I-O DATA WN-B11/PCM" @@ -473,6 +562,9 @@ #define PCMCIA_CIS_KINGSTON_KNE2 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_KINGSTON_KNE2 0x0100 #define PCMCIA_STR_KINGSTON_KNE2 "Kingston KNE-PC2 Ethernet" +#define PCMCIA_CIS_KINGSTON_CIO10T { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_KINGSTON_CIO10T 0x0110 +#define PCMCIA_STR_KINGSTON_CIO10T "Kingston CIO10T Ethernet" /* Lasat Products */ #define PCMCIA_CIS_LASAT_CREDIT_288 { NULL, NULL, NULL, NULL } @@ -502,6 +594,12 @@ #define PCMCIA_CIS_LUCENT_WAVELAN_IEEE { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_LUCENT_WAVELAN_IEEE 0x0002 #define PCMCIA_STR_LUCENT_WAVELAN_IEEE "WaveLAN/IEEE" +#define PCMCIA_CIS_AGERE_HERMES_II { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_AGERE_HERMES_II 0x0003 +#define PCMCIA_STR_AGERE_HERMES_II "Agere Systems Hermes-II Wireless" +#define PCMCIA_CIS_AGERE_HERMES_II_5 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_AGERE_HERMES_II_5 0x0004 +#define PCMCIA_STR_AGERE_HERMES_II_5 "Agere Systems Hermes-II.5 Wireless" /* MACNICA */ #define PCMCIA_CIS_MACNICA_ME1_JEIDA { NULL, NULL, NULL, NULL } @@ -511,7 +609,15 @@ #define PCMCIA_PRODUCT_MACNICA_MPS110 0xa041 #define PCMCIA_STR_MACNICA_MPS110 "MACNICA Miracle SCSI-II mPS110" +/* MagicRam, Inc */ +#define PCMCIA_CIS_MAGICRAM_ETHER { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_MAGICRAM_ETHER 0x0000 +#define PCMCIA_STR_MAGICRAM_ETHER "MagicRAM Ethernet PC Card 933926" + /* Megahertz Products */ +#define PCMCIA_CIS_MEGAHERTZ_VARIOUS { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_MEGAHERTZ_VARIOUS 0x0000 +#define PCMCIA_STR_MEGAHERTZ_VARIOUS "Megahertz X-jack Ethernet" #define PCMCIA_CIS_MEGAHERTZ_XJEM3336 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_MEGAHERTZ_XJEM3336 0x0006 #define PCMCIA_STR_MEGAHERTZ_XJEM3336 "Megahertz X-JACK Ethernet Modem" @@ -526,12 +632,12 @@ #define PCMCIA_STR_MEGAHERTZ_XJ5560 "Megahertz X-JACK 56kbps Modem" /* Melco Products */ -#define PCMCIA_CIS_MELCO_LPC3_TX { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_MELCO_LPC3_TX 0xc1ab -#define PCMCIA_STR_MELCO_LPC3_TX "Melco LPC3-TX" #define PCMCIA_CIS_MELCO_LPC3_CLX { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_MELCO_LPC3_CLX 0x0301 #define PCMCIA_STR_MELCO_LPC3_CLX "Melco LPC3-CLX Ethernet Adapter" +#define PCMCIA_CIS_MELCO_LPC3_TX { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_MELCO_LPC3_TX 0xc1ab +#define PCMCIA_STR_MELCO_LPC3_TX "Melco LPC3-TX" /* Microsoft Products */ #define PCMCIA_CIS_MICROSOFT_MN_520 { NULL, NULL, NULL, NULL } @@ -545,6 +651,9 @@ #define PCMCIA_CIS_MOTOROLA_PM100C { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_MOTOROLA_PM100C 0x0302 #define PCMCIA_STR_MOTOROLA_PM100C "Motorola Personal Messenger 100C CDPD Modem" +#define PCMCIA_CIS_MOTOROLA_MARINER { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_MOTOROLA_MARINER 0x0501 +#define PCMCIA_STR_MOTOROLA_MARINER "Motorola Mariner Ethernet/Modem" #define PCMCIA_CIS_MOTOROLA_MONTANA_336 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_MOTOROLA_MONTANA_336 0x0505 #define PCMCIA_STR_MOTOROLA_MONTANA_336 "Motorola Montana 33.6" @@ -555,13 +664,13 @@ #define PCMCIA_STR_NEWMEDIA_BASICS "New Media BASICS Ethernet" #define PCMCIA_CIS_NEWMEDIA_LANSURFER { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NEWMEDIA_LANSURFER 0x0021 -#define PCMCIA_STR_NEWMEDIA_LANSURFER "NewMedia LANSurfer" +#define PCMCIA_STR_NEWMEDIA_LANSURFER "New Media LANSurfer" #define PCMCIA_CIS_NEWMEDIA_LIVEWIRE { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NEWMEDIA_LIVEWIRE 0x1004 -#define PCMCIA_STR_NEWMEDIA_LIVEWIRE "NewMedia LiveWire Ethernet LAN Adapter" +#define PCMCIA_STR_NEWMEDIA_LIVEWIRE "New Media LiveWire Ethernet LAN Adapter" #define PCMCIA_CIS_NEWMEDIA_MULTIMEDIA { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NEWMEDIA_MULTIMEDIA 0x100b -#define PCMCIA_STR_NEWMEDIA_MULTIMEDIA "NewMedia Multimedia" +#define PCMCIA_STR_NEWMEDIA_MULTIMEDIA "New Media Multimedia" #define PCMCIA_CIS_NEWMEDIA_BUSTOASTER2 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NEWMEDIA_BUSTOASTER2 0xa002 #define PCMCIA_STR_NEWMEDIA_BUSTOASTER2 "New Media SCSI Bus Toaster" @@ -573,15 +682,12 @@ #define PCMCIA_STR_NEWMEDIA_BUSTOASTER3 "New Media SCSI Bus Toaster" #define PCMCIA_CIS_NEWMEDIA_WAVJAMMER { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NEWMEDIA_WAVJAMMER 0xe005 -#define PCMCIA_STR_NEWMEDIA_WAVJAMMER "NewMedia .WAVjammer" +#define PCMCIA_STR_NEWMEDIA_WAVJAMMER "New Media .WAVjammer" #define PCMCIA_CIS_NEWMEDIA2_BUSTOASTER { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NEWMEDIA2_BUSTOASTER 0x0001 -#define PCMCIA_STR_NEWMEDIA2_BUSTOASTER "NewMedia BusToaster" +#define PCMCIA_STR_NEWMEDIA2_BUSTOASTER "New Media BusToaster" /* Netgear */ -#define PCMCIA_CIS_NETGEAR_FA410TX { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_NETGEAR_FA410TX 0x0230 -#define PCMCIA_STR_NETGEAR_FA410TX "Netgear FA410TX" #define PCMCIA_CIS_NETGEAR_FA410TXC { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NETGEAR_FA410TXC 0x4530 #define PCMCIA_STR_NETGEAR_FA410TXC "Netgear FA410TXC" @@ -590,9 +696,29 @@ #define PCMCIA_STR_NETGEAR_FA411 "Netgear FA411" /* National Instruments */ +#define PCMCIA_CIS_NI_PCMCIA_232 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NI_PCMCIA_232 0x0d50 +#define PCMCIA_STR_NI_PCMCIA_232 "National Instruments PCMCIA-232" +#define PCMCIA_CIS_NI_PCMCIA_232_2 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NI_PCMCIA_232_2 0x0d51 +#define PCMCIA_STR_NI_PCMCIA_232_2 "National Instruments PCMCIA-232/2" +#define PCMCIA_CIS_NI_PCMCIA_485 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NI_PCMCIA_485 0x0d51 +#define PCMCIA_STR_NI_PCMCIA_485 "National Instruments PCMCIA-485" +#define PCMCIA_CIS_NI_PCMCIA_485_2 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NI_PCMCIA_485_2 0x0d52 +#define PCMCIA_STR_NI_PCMCIA_485_2 "National Instruments PCMCIA-485/2" #define PCMCIA_CIS_NI_PCMCIA_GPIB { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_NI_PCMCIA_GPIB 0x4882 #define PCMCIA_STR_NI_PCMCIA_GPIB "National Instruments PCMCIA-GPIB" +#define PCMCIA_CIS_NI_PCMCIA_232_4 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NI_PCMCIA_232_4 0xd180 +#define PCMCIA_STR_NI_PCMCIA_232_4 "National Instruments PCMCIA-232/4" + +/* NextCom K.K. */ +#define PCMCIA_CIS_NEXTCOM_NEXTHAWK { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_NEXTCOM_NEXTHAWK 0x0001 +#define PCMCIA_STR_NEXTCOM_NEXTHAWK "Next Hawk Ethernet" /* Nokia Products */ #define PCMCIA_CIS_NOKIA_C110_WLAN { NULL, NULL, NULL, NULL } @@ -611,12 +737,12 @@ #define PCMCIA_STR_NWN_WLAN_1148 "NWN 1148 WLAN" /* Olicom Products */ +#define PCMCIA_CIS_OLICOM_OC2220 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_OLICOM_OC2220 0x0101 +#define PCMCIA_STR_OLICOM_OC2220 "GoCard Ethernet" #define PCMCIA_CIS_OLICOM_TR { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_OLICOM_TR 0x2132 #define PCMCIA_STR_OLICOM_TR "GoCard Token Ring 16/4" -#define PCMCIA_CIS_OLICOM_OC2220 { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_OLICOM_OC2220 0x2022 -#define PCMCIA_STR_OLICOM_OC2220 "GoCard Ethernet" #define PCMCIA_CIS_OLICOM_OC2231 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_OLICOM_OC2231 0x3122 #define PCMCIA_STR_OLICOM_OC2231 "GoCard Combo Eth/Modem 288" @@ -625,9 +751,21 @@ #define PCMCIA_STR_OLICOM_OC2232 "GoCard Combo Eth/Modem 336" /* Ositech Products */ -#define PCMCIA_CIS_OSITECH_TRUMPCARD_SOD { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_OSITECH_TRUMPCARD_SOD 0x0008 -#define PCMCIA_STR_OSITECH_TRUMPCARD_SOD "Ositech Seven of Diamonds Ethernet Card" +#define PCMCIA_CIS_OSITECH_JACK_144 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_OSITECH_JACK_144 0x0001 +#define PCMCIA_STR_OSITECH_JACK_144 "Ositech Jack of ??? 14.4" +#define PCMCIA_CIS_OSITECH_JACK_288 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_OSITECH_JACK_288 0x0002 +#define PCMCIA_STR_OSITECH_JACK_288 "Ositech Jack of ??? 28.8" +#define PCMCIA_CIS_OSITECH_JACK_336 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_OSITECH_JACK_336 0x0007 +#define PCMCIA_STR_OSITECH_JACK_336 "Ositech Jack of ??? 33.6" +#define PCMCIA_CIS_OSITECH_TRUMP_SOD { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_OSITECH_TRUMP_SOD 0x0008 +#define PCMCIA_STR_OSITECH_TRUMP_SOD "Ositech Seven of Diamonds Ethernet Card" +#define PCMCIA_CIS_OSITECH_TRUMP_JOH { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_OSITECH_TRUMP_JOH 0x000a +#define PCMCIA_STR_OSITECH_TRUMP_JOH "Ositech Jack of Hearts" /* Panasonic Products */ #define PCMCIA_CIS_PANASONIC_KXLC002 { NULL, NULL, NULL, NULL } @@ -639,20 +777,28 @@ #define PCMCIA_CIS_PANASONIC_KXLC004 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_PANASONIC_KXLC004 0x0604 #define PCMCIA_STR_PANASONIC_KXLC004 "Panasonic KXL-810AN Interface Card" +#define PCMCIA_CIS_PANASONIC_KXLC005_2 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PANASONIC_KXLC005_2 0x0704 +#define PCMCIA_STR_PANASONIC_KXLC005_2 "Panasonic 16X CD-ROM Interface Card" +#define PCMCIA_CIS_PANASONIC_KME { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PANASONIC_KME 0x2604 +#define PCMCIA_STR_PANASONIC_KME "Panasonic CD-R/RW Interface" #define PCMCIA_CIS_PANASONIC_KXLC005 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_PANASONIC_KXLC005 0x2704 #define PCMCIA_STR_PANASONIC_KXLC005 "Panasonic 16X CD-ROM Interface Card" #define PCMCIA_CIS_PANASONIC_KXLC005_1 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_PANASONIC_KXLC005_1 0x2904 #define PCMCIA_STR_PANASONIC_KXLC005_1 "Panasonic 16X CD-ROM Interface Card" -#define PCMCIA_CIS_PANASONIC_KME { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_PANASONIC_KME 0x2604 -#define PCMCIA_STR_PANASONIC_KME "Panasonic CD-R/RW Interface" /* Planex */ -#define PCMCIA_CIS_PLANEX_2_GWNS11H { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_PLANEX_2_GWNS11H 0xb001 -#define PCMCIA_STR_PLANEX_2_GWNS11H "Planex GW-NS11H" +#define PCMCIA_CIS_PLANEX_GWNS11H { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PLANEX_GWNS11H 0xb001 +#define PCMCIA_STR_PLANEX_GWNS11H "Planex GW-NS11H" + +/* Premax Microelectronics Corp. */ +#define PCMCIA_CIS_PMC_LANMODEM { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PMC_LANMODEM 0x0000 +#define PCMCIA_STR_PMC_LANMODEM "LAN 33.6 Modem card" /* Proxim */ #define PCMCIA_CIS_PROXIM_HARMONY { NULL, NULL, NULL, NULL } @@ -672,6 +818,15 @@ #define PCMCIA_CIS_PSION_GOLDCARD { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_PSION_GOLDCARD 0x0020 #define PCMCIA_STR_PSION_GOLDCARD "Psion Gold Card" +#define PCMCIA_CIS_PSION_NETGLOBAL { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PSION_NETGLOBAL 0x0023 +#define PCMCIA_STR_PSION_NETGLOBAL "Psion Gold Card NetGlobal 10/100" +#define PCMCIA_CIS_PSION_NETGLOBAL2 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PSION_NETGLOBAL2 0x0026 +#define PCMCIA_STR_PSION_NETGLOBAL2 "Psion Gold Card NetGlobal 10/100" +#define PCMCIA_CIS_PSION_LANGLOBAL { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_PSION_LANGLOBAL 0x0081 +#define PCMCIA_STR_PSION_LANGLOBAL "Psion LANGLOBAL" /* QLogic */ #define PCMCIA_CIS_QLOGIC_PC05 { NULL, NULL, NULL, NULL } @@ -685,18 +840,57 @@ #define PCMCIA_CIS_QUATECH_DSP_225 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_QUATECH_DSP_225 0x0008 #define PCMCIA_STR_QUATECH_DSP_225 "Quatech Dual Serial Port" +#define PCMCIA_CIS_QUATECH_DUAL { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_QUATECH_DUAL 0x000e +#define PCMCIA_STR_QUATECH_DUAL "Quatech Dual Serial Port" +#define PCMCIA_CIS_QUATECH_QUAD_RS232 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_QUATECH_QUAD_RS232 0x001b +#define PCMCIA_STR_QUATECH_QUAD_RS232 "Quatech Quad RS-232" +#define PCMCIA_CIS_QUATECH_QSP_100 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_QUATECH_QSP_100 0x0025 +#define PCMCIA_STR_QUATECH_QSP_100 "Quatech Quad serial Port" +#define PCMCIA_CIS_QUATECH_QUAD_422 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_QUATECH_QUAD_422 0x0045 +#define PCMCIA_STR_QUATECH_QUAD_422 "Quatech Quad serial Port" +#define PCMCIA_CIS_QUATECH_DUAL_RS232 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_QUATECH_DUAL_RS232 0x0052 +#define PCMCIA_STR_QUATECH_DUAL_RS232 "Quatech Dual RS-232" /* RATOC System Inc. Products */ /* Don't use because both cards have same product id */ #define PCMCIA_CIS_RATOC_REX_R280_9530 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_RATOC_REX_R280_9530 0x0001 -#define PCMCIA_STR_RATOC_REX_R280_9530 "RATOC REX-R280/REX-9530" +#define PCMCIA_STR_RATOC_REX_R280_9530 "RATOC REX-R280/REX-9530/CFU01" + +/* Racore Computer Products */ +#define PCMCIA_CIS_RACORE_ACCTON_EN2226 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_RACORE_ACCTON_EN2226 0x010a +#define PCMCIA_STR_RACORE_ACCTON_EN2226 "Accton Fast EtherCard" +#define PCMCIA_CIS_RACORE_ETHERNET { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_RACORE_ETHERNET 0x2216 +#define PCMCIA_STR_RACORE_ETHERNET "Racore PC Card Ethernet" +#define PCMCIA_CIS_RACORE_FASTENET { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_RACORE_FASTENET 0x2328 +#define PCMCIA_STR_RACORE_FASTENET "Racore PC Card Fast Ethernet" +#define PCMCIA_CIS_RACORE_8041TX { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_RACORE_8041TX 0x8041 +#define PCMCIA_STR_RACORE_8041TX "SMC8041-TX" + +/* Ralink Technology products */ +#define PCMCIA_CIS_RALINK_RT2560 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_RALINK_RT2560 0x0201 +#define PCMCIA_STR_RALINK_RT2560 "RT2500 wireless adapter" /* Raylink/WebGear */ #define PCMCIA_CIS_RAYTHEON_WLAN { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_RAYTHEON_WLAN 0x0000 #define PCMCIA_STR_RAYTHEON_WLAN "WLAN Adapter" +/* RELIA Technologies Corporation */ +#define PCMCIA_CIS_RELIA_COMBO { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_RELIA_COMBO 0x2452 +#define PCMCIA_STR_RELIA_COMBO "Reliable Combo-L/M-56K" + /* Roland */ #define PCMCIA_CIS_ROLAND_SCP55 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_ROLAND_SCP55 0x0001 @@ -732,6 +926,9 @@ #define PCMCIA_STR_SIMPLETECH_SPECTRUM24 "Symbol Spectrum24 WLAN Adapter" /* Standard Microsystems Corporation Products */ +#define PCMCIA_CIS_SMC_SMC91C96 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_SMC_SMC91C96 0x0001 +#define PCMCIA_STR_SMC_SMC91C96 "SMC 91C96 Farallon EtherMac" #define PCMCIA_CIS_SMC_8016 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_SMC_8016 0x0105 #define PCMCIA_STR_SMC_8016 "SMC 8016 EtherCard" @@ -752,9 +949,15 @@ #define PCMCIA_CIS_SOCKET_DUAL_RS232 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_SOCKET_DUAL_RS232 0x0006 #define PCMCIA_STR_SOCKET_DUAL_RS232 "Socket Communications Dual RS232" +#define PCMCIA_CIS_SOCKET_ES_1000 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_SOCKET_ES_1000 0x000a +#define PCMCIA_STR_SOCKET_ES_1000 "Socket Communications Ethernet/RS-232" #define PCMCIA_CIS_SOCKET_LP_ETHER { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_SOCKET_LP_ETHER 0x000d #define PCMCIA_STR_SOCKET_LP_ETHER "Socket Communications LP-E" +#define PCMCIA_CIS_SOCKET_DUAL_IO { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_SOCKET_DUAL_IO 0x0070 +#define PCMCIA_STR_SOCKET_DUAL_IO "Socket Communications DUAL IO" #define PCMCIA_CIS_SOCKET_LP_ETHER_CF { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_SOCKET_LP_ETHER_CF 0x0075 #define PCMCIA_STR_SOCKET_LP_ETHER_CF "Socket Communications LP-E CF" @@ -783,11 +986,20 @@ #define PCMCIA_CIS_TDK_C6500012 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_TDK_C6500012 0x410a #define PCMCIA_STR_TDK_C6500012 "TDK ELSA MicroLink MC all" +#define PCMCIA_CIS_TDK_GN3410 { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_TDK_GN3410 0x4815 +#define PCMCIA_STR_TDK_GN3410 "TDK GlobalNetworker 3410" #define PCMCIA_CIS_TDK_LAK_CD031 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_TDK_LAK_CD031 0xc1ab #define PCMCIA_STR_TDK_LAK_CD031 "TDK LAK-CD031 Ethernet" +#define PCMCIA_CIS_TDK_DFL5610WS { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_TDK_DFL5610WS 0xea15 +#define PCMCIA_STR_TDK_DFL5610WS "TDK DFL5610WS Ethernet/Modem" /* Telecom Device */ +#define PCMCIA_CIS_TELECOMDEVICE_LM5LT { NULL, NULL, NULL, NULL } +#define PCMCIA_PRODUCT_TELECOMDEVICE_LM5LT 0x0101 +#define PCMCIA_STR_TELECOMDEVICE_LM5LT "Billionton LM5LT-10B Ethernet/Modem" #define PCMCIA_CIS_TELECOMDEVICE_TCD_HPC100 { NULL, NULL, NULL, NULL } #define PCMCIA_PRODUCT_TELECOMDEVICE_TCD_HPC100 0x0202 #define PCMCIA_STR_TELECOMDEVICE_TCD_HPC100 "Telecom Device TCD-HPC100" @@ -877,7 +1089,6 @@ #define PCMCIA_VENDOR_BILLIONTON 0xffffffff /* Billionton Systems Inc. */ #define PCMCIA_VENDOR_CNET 0xffffffff /* CNet */ #define PCMCIA_VENDOR_COREGA 0xffffffff /* Corega K.K. */ -#define PCMCIA_VENDOR_DIGITAL 0xffffffff /* Digital Equipment Corporation */ #define PCMCIA_VENDOR_DLINK 0xffffffff /* D-Link */ #define PCMCIA_VENDOR_DYNALINK 0xffffffff /* DynaLink */ #define PCMCIA_VENDOR_EIGERLABS 0xffffffff /* Eiger labs,Inc. */ @@ -892,16 +1103,14 @@ #define PCMCIA_VENDOR_IODATA3 0xffffffff /* I-O DATA */ #define PCMCIA_VENDOR_LANTECH 0xffffffff /* Lantech Computer Company */ #define PCMCIA_VENDOR_MELCO2 0xffffffff /* Melco Corporation */ -#define PCMCIA_VENDOR_NAKAGAWAMETAL 0xffffffff /* NAKAGAWA METAL */ #define PCMCIA_VENDOR_NDC 0xffffffff /* NDC */ #define PCMCIA_VENDOR_NEC 0xffffffff /* NEC */ #define PCMCIA_VENDOR_OEM2 0xffffffff /* Generic OEM */ #define PCMCIA_VENDOR_PLANET 0xffffffff /* Planet */ -#define PCMCIA_VENDOR_PLANEX 0xffffffff /* Planex Communications Inc */ #define PCMCIA_VENDOR_PREMAX 0xffffffff /* Premax */ #define PCMCIA_VENDOR_RPTI 0xffffffff /* RPTI */ #define PCMCIA_VENDOR_SVEC 0xffffffff /* SVEC/Hawking Technology */ -#define PCMCIA_VENDOR_SYNERGY21 0xffffffff /* Synergy 21 */ +#define PCMCIA_VENDOR_TAMARACK 0xffffffff /* Tamarack */ #define PCMCIA_VENDOR_TEAC 0xffffffff /* TEAC */ #define PCMCIA_VENDOR_TOSHIBA 0xffffffff /* TOSHIBA */ #define PCMCIA_VENDOR_WORKBIT2 0xffffffff /* WORKBIT */ @@ -915,9 +1124,6 @@ #define PCMCIA_CIS_ACCTON_EN2216 { "ACCTON", "EN2216-PCMCIA-ETHERNET", "EN2216R01", NULL } #define PCMCIA_PRODUCT_ACCTON_EN2216 0xffffffff #define PCMCIA_STR_ACCTON_EN2216 "Accton EN2216" -#define PCMCIA_CIS_ACCTON_EN2226 { "Accton", "Fast EtherCard-16", "EN2226", "1.00" } -#define PCMCIA_PRODUCT_ACCTON_EN2226 0xffffffff -#define PCMCIA_STR_ACCTON_EN2226 "Accton EN2226" #define PCMCIA_CIS_ADDTRON_AWP100 { "Addtron", "AWP-100 Wireless PCMCIA", "Version 01.02", NULL } #define PCMCIA_PRODUCT_ADDTRON_AWP100 0xffffffff #define PCMCIA_STR_ADDTRON_AWP100 "" @@ -976,9 +1182,6 @@ #define PCMCIA_PRODUCT_COREGA_WIRELESS_LAN_PCCL_11 0xffffffff #define PCMCIA_STR_COREGA_WIRELESS_LAN_PCCL_11 "Corega Wireless LAN PCCL-11" -#define PCMCIA_CIS_DIGITAL_DEPCMXX { "DIGITAL", "DEPCM-XX", NULL, NULL } -#define PCMCIA_PRODUCT_DIGITAL_DEPCMXX 0xffffffff -#define PCMCIA_STR_DIGITAL_DEPCMXX "DEC DEPCM-BA" #define PCMCIA_CIS_DLINK_DE650 { "D-Link", "DE-650", NULL, NULL } #define PCMCIA_PRODUCT_DLINK_DE650 0xffffffff #define PCMCIA_STR_DLINK_DE650 "D-Link DE-650" @@ -1046,24 +1249,21 @@ #define PCMCIA_CIS_INTERSIL2_PRISM2 { "INTERSIL", "HFA384x/IEEE", "Version 01.02", NULL } #define PCMCIA_PRODUCT_INTERSIL2_PRISM2 0xffffffff #define PCMCIA_STR_INTERSIL2_PRISM2 "Intersil Prism II" -#define PCMCIA_CIS_IODATA_CBIDE2 { "IO DATA", "CBIDE2 ", NULL, NULL } -#define PCMCIA_PRODUCT_IODATA_CBIDE2 0xffffffff -#define PCMCIA_STR_IODATA_CBIDE2 "IO-DATA CBIDE2/16-bit mode" +#define PCMCIA_CIS_IODATA3_CBIDE2 { "IO DATA", "CBIDE2 ", NULL, NULL } +#define PCMCIA_PRODUCT_IODATA3_CBIDE2 0xffffffff +#define PCMCIA_STR_IODATA3_CBIDE2 "IO-DATA CBIDE2/16-bit mode" #define PCMCIA_CIS_IODATA3_CBSC16 { "IO DATA", "CBSC16 ", NULL, NULL } #define PCMCIA_PRODUCT_IODATA3_CBSC16 0xffffffff #define PCMCIA_STR_IODATA3_CBSC16 "IO-DATA CBSC16" -#define PCMCIA_CIS_IODATA_PCLAT { "I-O DATA", "PCLA", "ETHERNET", NULL } -#define PCMCIA_PRODUCT_IODATA_PCLAT 0xffffffff -#define PCMCIA_STR_IODATA_PCLAT "IO-DATA PCLA/T" +#define PCMCIA_CIS_IODATA3_PCLAT { "I-O DATA", "PCLA", "ETHERNET", NULL } +#define PCMCIA_PRODUCT_IODATA3_PCLAT 0xffffffff +#define PCMCIA_STR_IODATA3_PCLAT "IO-DATA PCLA/T" #define PCMCIA_CIS_LANTECH_FASTNETTX { "ASIX", "AX88190", NULL, NULL } #define PCMCIA_PRODUCT_LANTECH_FASTNETTX 0xffffffff #define PCMCIA_STR_LANTECH_FASTNETTX "Lantech Fastnet/TX" #define PCMCIA_CIS_LINKSYS_ECARD_2 { "LINKSYS", "E-CARD", NULL, NULL } #define PCMCIA_PRODUCT_LINKSYS_ECARD_2 0xffffffff #define PCMCIA_STR_LINKSYS_ECARD_2 "Linksys E-Card" -#define PCMCIA_CIS_LINKSYS_PCM100 { "Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", "Ver 1.0", NULL } -#define PCMCIA_PRODUCT_LINKSYS_PCM100 0xffffffff -#define PCMCIA_STR_LINKSYS_PCM100 "" #define PCMCIA_CIS_MACNICA_MPS100 { "MACNICA", "MIRACLE SCSI", "mPS100", "D.0" } #define PCMCIA_PRODUCT_MACNICA_MPS100 0xffffffff #define PCMCIA_STR_MACNICA_MPS100 "Macnica Miracle SCSI mPS100" @@ -1073,9 +1273,6 @@ #define PCMCIA_CIS_MELCO2_LPC2_TX { "MELCO", "LPC2-TX", NULL, NULL } #define PCMCIA_PRODUCT_MELCO2_LPC2_TX 0xffffffff #define PCMCIA_STR_MELCO2_LPC2_TX "Melco LPC2-TX" -#define PCMCIA_CIS_NAKAGAWAMETAL_LNT10TN { "PCMCIA", "LNT-10TN", NULL, NULL } -#define PCMCIA_PRODUCT_NAKAGAWAMETAL_LNT10TN 0xffffffff -#define PCMCIA_STR_NAKAGAWAMETAL_LNT10TN "NAKAGAWA METAL LNT-10TN NE2000 Compatible Card" #define PCMCIA_CIS_NANOSPEED_PRISM2 { "NANOSPEED", "HFA384x/IEEE", "Version 01.02", NULL } #define PCMCIA_PRODUCT_NANOSPEED_PRISM2 0xffffffff #define PCMCIA_STR_NANOSPEED_PRISM2 "NANOSPEED ROOT-RZ2000 WLAN Card" @@ -1100,19 +1297,12 @@ #define PCMCIA_CIS_OEM2_IDE { "PCMCIA", "IDE CARD", NULL, NULL } #define PCMCIA_PRODUCT_OEM2_IDE 0xffffffff #define PCMCIA_STR_OEM2_IDE "Generic PCMCIA IDE CARD" +#define PCMCIA_CIS_OEM2_ETHERNET { "PCMCIA", "Ethernet", NULL, NULL } +#define PCMCIA_PRODUCT_OEM2_ETHERNET 0xffffffff +#define PCMCIA_STR_OEM2_ETHERNET "NE2000 PC Card" #define PCMCIA_CIS_PLANET_SMARTCOM2000 { "PCMCIA", "UE2212", NULL, NULL } #define PCMCIA_PRODUCT_PLANET_SMARTCOM2000 0xffffffff #define PCMCIA_STR_PLANET_SMARTCOM2000 "Planet SmartCOM 2000" -/* - * vendor ID of both FNW-3600-T and FNW-3700-T is LINKSYS (0x0149) and - * product ID is 0xc1ab, but it conflicts with LINKSYS Combo EthernetCard. - */ -#define PCMCIA_CIS_PLANEX_FNW3600T { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_PLANEX_FNW3600T -1 -#define PCMCIA_STR_PLANEX_FNW3600T "Planex FNW-3600-T" -#define PCMCIA_CIS_PLANEX_FNW3700T { NULL, NULL, NULL, NULL } -#define PCMCIA_PRODUCT_PLANEX_FNW3700T -1 -#define PCMCIA_STR_PLANEX_FNW3700T "Planex FNW-3700-T" #define PCMCIA_CIS_RPTI_EP400 { "RPTI LTD.", "EP400", "CISV100", NULL } #define PCMCIA_PRODUCT_RPTI_EP400 0xffffffff #define PCMCIA_STR_RPTI_EP400 "RPTI EP400" @@ -1140,24 +1330,33 @@ #define PCMCIA_CIS_RATOC_REX9530 { "RATOC System Inc.", "SCSI2 CARD 37", NULL, NULL } #define PCMCIA_PRODUCT_RATOC_REX9530 0xffffffff #define PCMCIA_STR_RATOC_REX9530 "RATOC REX-9530" +#define PCMCIA_CIS_RATOC_REX_CFU1 { "RATOC", "USB HOST CF+ Card", NULL, NULL } +#define PCMCIA_PRODUCT_RATOC_REX_CFU1 0xffffffff +#define PCMCIA_STR_RATOC_REX_CFU1 "RATOC REX-CFU1" #define PCMCIA_CIS_SIMPLETECH_SPECTRUM24_ALT { "Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", NULL, NULL } #define PCMCIA_PRODUCT_SIMPLETECH_SPECTRUM24_ALT 0xffffffff #define PCMCIA_STR_SIMPLETECH_SPECTRUM24_ALT "LA4111 Spectrum24 Wireless LAN PC Card" #define PCMCIA_CIS_SMC_2632W { "SMC", "SMC2632W", "Version 01.02", NULL } #define PCMCIA_PRODUCT_SMC_2632W 0xffffffff #define PCMCIA_STR_SMC_2632W "SMC 2632 EZ Connect Wireless PC Card" -#define PCMCIA_CIS_SMC_8041 { "SMC", "8041TX-10/100-PC-Card-V2", NULL, NULL } -#define PCMCIA_PRODUCT_SMC_8041 0xffffffff -#define PCMCIA_STR_SMC_8041 "SMC 8041TX 10/100 PC Card" +#define PCMCIA_CIS_SMC_8000 { "SMC8000", "DEV1", NULL, NULL } +#define PCMCIA_PRODUCT_SMC_8000 0xffffffff +#define PCMCIA_STR_SMC_8000 "" +#define PCMCIA_CIS_SMC_8020BT { "SMC" "EtherEZ Ethernet 8020", NULL, NULL } +#define PCMCIA_PRODUCT_SMC_8020BT 0xffffffff +#define PCMCIA_STR_SMC_8020BT "" +#define PCMCIA_CIS_SMC_8020BTM { "SMC", "EtherEZ Ethernet/Modem", "8020", NULL } +#define PCMCIA_PRODUCT_SMC_8020BTM 0xffffffff +#define PCMCIA_STR_SMC_8020BTM "" #define PCMCIA_CIS_SVEC_COMBOCARD { "Ethernet", "Adapter", NULL, NULL } #define PCMCIA_PRODUCT_SVEC_COMBOCARD 0xffffffff #define PCMCIA_STR_SVEC_COMBOCARD "SVEC/Hawking Tech. Combo Card" #define PCMCIA_CIS_SVEC_LANCARD { "SVEC", "FD605 PCMCIA EtherNet Card", "V1-1", NULL } #define PCMCIA_PRODUCT_SVEC_LANCARD 0xffffffff #define PCMCIA_STR_SVEC_LANCARD "SVEC PCMCIA Lan Card" -#define PCMCIA_CIS_SYNERGY21_S21810 { "PCMCIA", "Ethernet", "A", "004743118001" } -#define PCMCIA_PRODUCT_SYNERGY21_S21810 0xffffffff -#define PCMCIA_STR_SYNERGY21_S21810 "Synergy 21 S21810+ NE2000 Compatible Card" +#define PCMCIA_CIS_TAMARACK_ETHERNET { "TAMARACK", "Ethernet", NULL, NULL } +#define PCMCIA_PRODUCT_TAMARACK_ETHERNET 0xffffffff +#define PCMCIA_STR_TAMARACK_ETHERNET "TAMARACK NE2000 PC Card" #define PCMCIA_CIS_TEAC_IDECARDII { NULL, "NinjaATA-", NULL, NULL } #define PCMCIA_PRODUCT_TEAC_IDECARDII 0xffffffff #define PCMCIA_STR_TEAC_IDECARDII "TEAC IDE Card/II" diff --git a/sys/bus/pccard/pccardreg.h b/sys/bus/pccard/pccardreg.h index f50352e002..962104bd4c 100644 --- a/sys/bus/pccard/pccardreg.h +++ b/sys/bus/pccard/pccardreg.h @@ -1,8 +1,8 @@ /* $NetBSD: pcmciareg.h,v 1.7 1998/10/29 09:45:52 enami Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccardreg.h,v 1.1 1999/10/26 06:52:31 imp Exp $ */ -/* $DragonFly: src/sys/bus/pccard/pccardreg.h,v 1.3 2004/02/10 07:55:45 joerg Exp $ */ +/* $FreeBSD: src/sys/dev/pccard/pccardreg.h,v 1.3 2005/01/06 01:43:03 imp Exp $ */ +/* $DragonFly: src/sys/bus/pccard/pccardreg.h,v 1.4 2007/07/05 12:08:53 sephe Exp $ */ -/* +/*- * Copyright (c) 1997 Marc Horowitz. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,181 +31,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* most of this is from the PCCARD PC Card Standard, Release 2.1 */ - -/* Note: the weird indenting here is to make the constants more - readable. Please don't normalize it. --marc */ - -/* - * CIS Tuples */ - -/* Layer 1 Basic Compatibility Tuples */ -#define PCCARD_CISTPL_NULL 0x00 -#define PCCARD_CISTPL_DEVICE 0x01 -#define PCCARD_DTYPE_MASK 0xF0 -#define PCCARD_DTYPE_NULL 0x00 -#define PCCARD_DTYPE_ROM 0x10 -#define PCCARD_DTYPE_OTPROM 0x20 -#define PCCARD_DTYPE_EPROM 0x30 -#define PCCARD_DTYPE_EEPROM 0x40 -#define PCCARD_DTYPE_FLASH 0x50 -#define PCCARD_DTYPE_SRAM 0x60 -#define PCCARD_DTYPE_DRAM 0x70 -#define PCCARD_DTYPE_FUNCSPEC 0xD0 -#define PCCARD_DTYPE_EXTEND 0xE0 -#define PCCARD_DSPEED_MASK 0x07 -#define PCCARD_DSPEED_NULL 0x00 -#define PCCARD_DSPEED_250NS 0x01 -#define PCCARD_DSPEED_200NS 0x02 -#define PCCARD_DSPEED_150NS 0x03 -#define PCCARD_DSPEED_100NS 0x04 -#define PCCARD_DSPEED_EXT 0x07 - -/* - * the 2.1 docs have 0x02-0x07 as reserved, but the linux drivers list the - * follwing tuple code values. I have at least one card (3com 3c562 - * lan+modem) which has a code 0x06 tuple, so I'm going to assume that these - * are for real - */ - -#define PCCARD_CISTPL_LONGLINK_CB 0x02 -#define PCCARD_CISTPL_INDIRECT 0x03 -#define PCCARD_CISTPL_CONFIG_CB 0x04 -#define PCCARD_CISTPL_CFTABLE_ENTRY_CB 0x05 -#define PCCARD_CISTPL_LONGLINK_MFC 0x06 -#define PCCARD_MFC_MEM_ATTR 0x00 -#define PCCARD_MFC_MEM_COMMON 0x01 -#define PCCARD_CISTPL_BAR 0x07 -#define PCCARD_CISTPL_PWR_MGMNT 0x08 - -#define PCCARD_CISTPL_CHECKSUM 0x10 -#define PCCARD_CISTPL_LONGLINK_A 0x11 -#define PCCARD_CISTPL_LONGLINK_C 0x12 -#define PCCARD_CISTPL_LINKTARGET 0x13 -#define PCCARD_CISTPL_NO_LINK 0x14 -#define PCCARD_CISTPL_VERS_1 0x15 -#define PCCARD_CISTPL_ALTSTR 0x16 -#define PCCARD_CISTPL_DEVICE_A 0x17 -#define PCCARD_CISTPL_JEDEC_C 0x18 -#define PCCARD_CISTPL_JEDEC_A 0x19 -#define PCCARD_CISTPL_CONFIG 0x1A -#define PCCARD_TPCC_RASZ_MASK 0x03 -#define PCCARD_TPCC_RASZ_SHIFT 0 -#define PCCARD_TPCC_RMSZ_MASK 0x3C -#define PCCARD_TPCC_RMSZ_SHIFT 2 -#define PCCARD_TPCC_RFSZ_MASK 0xC0 -#define PCCARD_TPCC_RFSZ_SHIFT 6 -#define PCCARD_CISTPL_CFTABLE_ENTRY 0x1B -#define PCCARD_TPCE_INDX_INTFACE 0x80 -#define PCCARD_TPCE_INDX_DEFAULT 0x40 -#define PCCARD_TPCE_INDX_NUM_MASK 0x3F -#define PCCARD_TPCE_IF_MWAIT 0x80 -#define PCCARD_TPCE_IF_RDYBSY 0x40 -#define PCCARD_TPCE_IF_WP 0x20 -#define PCCARD_TPCE_IF_BVD 0x10 -#define PCCARD_TPCE_IF_IFTYPE 0x0F -#define PCCARD_IFTYPE_MEMORY 0 -#define PCCARD_IFTYPE_IO 1 -#define PCCARD_TPCE_FS_MISC 0x80 -#define PCCARD_TPCE_FS_MEMSPACE_MASK 0x60 -#define PCCARD_TPCE_FS_MEMSPACE_NONE 0x00 -#define PCCARD_TPCE_FS_MEMSPACE_LENGTH 0x20 -#define PCCARD_TPCE_FS_MEMSPACE_LENGTHADDR 0x40 -#define PCCARD_TPCE_FS_MEMSPACE_TABLE 0x60 -#define PCCARD_TPCE_FS_IRQ 0x10 -#define PCCARD_TPCE_FS_IOSPACE 0x08 -#define PCCARD_TPCE_FS_TIMING 0x04 -#define PCCARD_TPCE_FS_POWER_MASK 0x03 -#define PCCARD_TPCE_FS_POWER_NONE 0x00 -#define PCCARD_TPCE_FS_POWER_VCC 0x01 -#define PCCARD_TPCE_FS_POWER_VCCVPP1 0x02 -#define PCCARD_TPCE_FS_POWER_VCCVPP1VPP2 0x03 -#define PCCARD_TPCE_TD_RESERVED_MASK 0xE0 -#define PCCARD_TPCE_TD_RDYBSY_MASK 0x1C -#define PCCARD_TPCE_TD_WAIT_MASK 0x03 -#define PCCARD_TPCE_IO_HASRANGE 0x80 -#define PCCARD_TPCE_IO_BUSWIDTH_16BIT 0x40 -#define PCCARD_TPCE_IO_BUSWIDTH_8BIT 0x20 -#define PCCARD_TPCE_IO_IOADDRLINES_MASK 0x1F -#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_MASK 0xC0 -#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_NONE 0x00 -#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_ONE 0x40 -#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_TWO 0x80 -#define PCCARD_TPCE_IO_RANGE_LENGTHSIZE_FOUR 0xC0 -#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_MASK 0x30 -#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_NONE 0x00 -#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_ONE 0x10 -#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_TWO 0x20 -#define PCCARD_TPCE_IO_RANGE_ADDRSIZE_FOUR 0x30 -#define PCCARD_TPCE_IO_RANGE_COUNT 0x0F -#define PCCARD_TPCE_IR_SHARE 0x80 -#define PCCARD_TPCE_IR_PULSE 0x40 -#define PCCARD_TPCE_IR_LEVEL 0x20 -#define PCCARD_TPCE_IR_HASMASK 0x10 -#define PCCARD_TPCE_IR_IRQ 0x0F -#define PCCARD_TPCE_MS_HOSTADDR 0x80 -#define PCCARD_TPCE_MS_CARDADDR_SIZE_MASK 0x60 -#define PCCARD_TPCE_MS_CARDADDR_SIZE_SHIFT 5 -#define PCCARD_TPCE_MS_LENGTH_SIZE_MASK 0x18 -#define PCCARD_TPCE_MS_LENGTH_SIZE_SHIFT 3 -#define PCCARD_TPCE_MS_COUNT 0x07 -#define PCCARD_TPCE_MI_EXT 0x80 -#define PCCARD_TPCE_MI_RESERVED 0x40 -#define PCCARD_TPCE_MI_PWRDOWN 0x20 -#define PCCARD_TPCE_MI_READONLY 0x10 -#define PCCARD_TPCE_MI_AUDIO 0x08 -#define PCCARD_TPCE_MI_MAXTWINS 0x07 -#define PCCARD_CISTPL_DEVICE_OC 0x1C -#define PCCARD_CISTPL_DEVICE_OA 0x1D -#define PCCARD_CISTPL_DEVICE_GEO 0x1E -#define PCCARD_CISTPL_DEVICE_GEO_A 0x1F -#define PCCARD_CISTPL_MANFID 0x20 -#define PCCARD_CISTPL_FUNCID 0x21 -#define PCCARD_FUNCTION_UNSPEC -1 -#define PCCARD_FUNCTION_MULTIFUNCTION 0 -#define PCCARD_FUNCTION_MEMORY 1 -#define PCCARD_FUNCTION_SERIAL 2 -#define PCCARD_FUNCTION_PARALLEL 3 -#define PCCARD_FUNCTION_DISK 4 -#define PCCARD_FUNCTION_VIDEO 5 -#define PCCARD_FUNCTION_NETWORK 6 -#define PCCARD_FUNCTION_AIMS 7 -#define PCCARD_FUNCTION_SCSI 8 -#define PCCARD_FUNCTION_SECURITY 9 -#define PCCARD_FUNCTION_INSTRUMENT 10 -#define PCCARD_CISTPL_FUNCE 0x22 -#define PCCARD_TPLFE_TYPE_LAN_TECH 0x01 -#define PCCARD_TPLFE_TYPE_LAN_SPEED 0x02 -#define PCCARD_TPLFE_TYPE_LAN_MEDIA 0x03 -#define PCCARD_TPLFE_TYPE_LAN_NID 0x04 -#define PCCARD_TPLFE_TYPE_LAN_CONN 0x05 -#define PCCARD_TPLFE_TYPE_DISK_DEVICE_INTERFACE 0x01 -#define PCCARD_TPLFE_DDI_PCCARD_ATA 0x01 -#define PCCARD_CISTPL_END 0xFF - -/* Layer 2 Data Recording Format Tuples */ - -#define PCCARD_CISTPL_SWIL 0x23 -/* #define PCCARD_CISTPL_RESERVED 0x24-0x3F */ -#define PCCARD_CISTPL_VERS_2 0x40 -#define PCCARD_CISTPL_FORMAT 0x41 -#define PCCARD_CISTPL_GEOMETRY 0x42 -#define PCCARD_CISTPL_BYTEORDER 0x43 -#define PCCARD_CISTPL_DATE 0x44 -#define PCCARD_CISTPL_BATTERY 0x45 -#define PCCARD_CISTPL_FORAMT_A 0x47 - -/* Layer 3 Data Organization Tuples */ - -#define PCCARD_CISTPL_ORG 0x46 -/* #define PCCARD_CISTPL_RESERVED 0x47-0x7F */ - -/* Layer 4 System-Specific Standard Tuples */ - -/* #define PCCARD_CISTPL_RESERVED 0x80-0x8F */ -#define PCCARD_CISTPL_SPCL 0x90 -/* #define PCCARD_CISTPL_RESERVED 0x90-0xFE */ - /* * Card Configuration Registers */ diff --git a/sys/bus/pccard/pccardvar.h b/sys/bus/pccard/pccardvar.h index 8abd4943d4..cb8dbc0ad8 100644 --- a/sys/bus/pccard/pccardvar.h +++ b/sys/bus/pccard/pccardvar.h @@ -1,8 +1,8 @@ /* $NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 enami Exp $ */ -/* $FreeBSD: src/sys/dev/pccard/pccardvar.h,v 1.34 2002/11/14 05:15:50 imp Exp $ */ -/* $DragonFly: src/sys/bus/pccard/pccardvar.h,v 1.6 2006/10/25 20:55:51 dillon Exp $ */ +/* $FreeBSD: src/sys/dev/pccard/pccardvar.h,v 1.54 2005/07/13 15:00:59 imp Exp $ */ +/* $DragonFly: src/sys/bus/pccard/pccardvar.h,v 1.7 2007/07/05 12:08:53 sephe Exp $ */ -/* +/*- * Copyright (c) 1997 Marc Horowitz. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,12 +31,20 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include - extern int pccard_verbose; +/* + * PCCARD_API_LEVEL. When set to 5, we provide a 5.x compatable API + * for driver writers that have to share their code between 5.x and 6.x. + * The 5.x compatibility interfaces will be unsupported in 7.0, at which + * point we'll only support 6 and newer, etc. + */ +#ifndef PCCARD_API_LEVEL +#define PCCARD_API_LEVEL 5 +#elif PCCARD_API_LEVEL < 5 +#error "pccard API less than 5 unsupported" +#endif + /* * Contains information about mapped/allocated i/o spaces. */ @@ -60,7 +68,6 @@ struct pccard_mem_handle { bus_addr_t addr; /* resulting address in bus space */ bus_size_t size; /* size of mem space */ bus_size_t realsize; /* how much we really allocated */ - long offset; /* mapped Offset on card */ bus_addr_t cardaddr; /* Absolute address on card */ int kind; }; @@ -82,7 +89,7 @@ struct pccard_mem_handle { struct pccard_config_entry { int number; - u_int32_t flags; + uint32_t flags; int iftype; int num_iospace; @@ -96,7 +103,7 @@ struct pccard_config_entry { u_long length; u_long start; } iospace[4]; /* XXX this could be as high as 16 */ - u_int16_t irqmask; + uint16_t irqmask; int num_memspace; struct { u_long length; @@ -104,12 +111,6 @@ struct pccard_config_entry { u_long hostaddr; } memspace[2]; /* XXX this could be as high as 8 */ int maxtwins; - struct resource *iores[4]; - int iorid[4]; - struct resource *irqres; - int irqrid; - struct resource *memres[2]; - int memrid[2]; STAILQ_ENTRY(pccard_config_entry) cfe_list; }; @@ -119,7 +120,7 @@ struct pccard_funce_disk { struct pccard_funce_lan { int pfl_nidlen; - u_int8_t pfl_nid[8]; + uint8_t pfl_nid[8]; }; union pccard_funce { @@ -148,8 +149,8 @@ struct pccard_function { #define pf_ccr_realsize pf_pcmh.realsize uint32_t pf_ccr_offset; /* Offset from ccr_base of CIS */ int pf_ccr_window; - long pf_mfc_iobase; /* Right type? */ - long pf_mfc_iomax; + bus_addr_t pf_mfc_iobase; + bus_addr_t pf_mfc_iomax; int pf_flags; driver_intr_t *intr_handler; void *intr_handler_arg; @@ -180,14 +181,11 @@ struct pccard_card { int32_t product; #define PCMCIA_PRODUCT_INVALID -1 int16_t prodext; - u_int16_t error; + uint16_t error; #define PCMCIA_CIS_INVALID { NULL, NULL, NULL, NULL } STAILQ_HEAD(, pccard_function) pf_head; }; -#define PCCARD_MEM_ATTR 1 -#define PCCARD_MEM_COMMON 2 - #define PCCARD_WIDTH_AUTO 0 #define PCCARD_WIDTH_IO8 1 #define PCCARD_WIDTH_IO16 2 @@ -195,7 +193,7 @@ struct pccard_card { /* More later? */ struct pccard_ivar { struct resource_list resources; - struct pccard_function *fcn; + struct pccard_function *pf; }; struct pccard_softc { @@ -207,9 +205,6 @@ struct pccard_softc { int sc_enabled_count; /* num functions enabled */ }; -void -pccardbus_if_setup(struct pccard_softc*); - struct pccard_cis_quirk { int32_t manufacturer; int32_t product; @@ -227,13 +222,14 @@ struct pccard_tuple { bus_space_handle_t memh; }; +typedef int (*pccard_scan_t)(const struct pccard_tuple *, void *); + struct pccard_product { const char *pp_name; /* NULL if end of table */ -#define PCCARD_VENDOR_ANY ((u_int32_t) -1) - u_int32_t pp_vendor; -#define PCCARD_PRODUCT_ANY ((u_int32_t) -1) - u_int32_t pp_product; - int pp_expfunc; +#define PCCARD_VENDOR_ANY (0xffffffff) + uint32_t pp_vendor; +#define PCCARD_PRODUCT_ANY (0xffffffff) + uint32_t pp_product; const char *pp_cis[4]; }; @@ -257,8 +253,7 @@ pccard_product_lookup(device_t dev, const struct pccard_product *tab, void pccard_read_cis(struct pccard_softc *); void pccard_check_cis_quirks(device_t); void pccard_print_cis(device_t); -int pccard_scan_cis(device_t, - int (*) (struct pccard_tuple *, void *), void *); +int pccard_scan_cis(device_t, pccard_scan_t, void *); #define pccard_cis_read_1(tuple, idx0) \ (bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0))) @@ -290,7 +285,8 @@ int pccard_scan_cis(device_t, #define PCCARD_SPACE_MEMORY 1 #define PCCARD_SPACE_IO 2 -#define pccard_mfc(sc) (STAILQ_FIRST(&(sc)->card.pf_head) && \ +#define pccard_mfc(sc) \ + (STAILQ_FIRST(&(sc)->card.pf_head) && \ STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list)) #define pccard_io_alloc(pf, start, size, align, pciop) \ @@ -347,15 +343,15 @@ pccard_get_ ## A(device_t dev) \ { \ uintptr_t v; \ BUS_READ_IVAR(device_get_parent(dev), dev, PCCARD_IVAR_ ## B, &v); \ - return (T) v; \ + return (T)v; \ } -PCCARD_ACCESSOR(ether, ETHADDR, u_int8_t *) -PCCARD_ACCESSOR(vendor, VENDOR, u_int32_t) -PCCARD_ACCESSOR(product, PRODUCT, u_int32_t) -PCCARD_ACCESSOR(prodext, PRODEXT, u_int16_t) -PCCARD_ACCESSOR(function_number,FUNCTION_NUMBER, u_int32_t) -PCCARD_ACCESSOR(function, FUNCTION, u_int32_t) +PCCARD_ACCESSOR(ether, ETHADDR, uint8_t *) +PCCARD_ACCESSOR(vendor, VENDOR, uint32_t) +PCCARD_ACCESSOR(product, PRODUCT, uint32_t) +PCCARD_ACCESSOR(prodext, PRODEXT, uint16_t) +PCCARD_ACCESSOR(function_number,FUNCTION_NUMBER, uint32_t) +PCCARD_ACCESSOR(function, FUNCTION, uint32_t) PCCARD_ACCESSOR(vendor_str, VENDOR_STR, const char *) PCCARD_ACCESSOR(product_str, PRODUCT_STR, const char *) PCCARD_ACCESSOR(cis3_str, CIS3_STR, const char *) @@ -375,9 +371,26 @@ enum { #define PCCARD_S(a, b) PCMCIA_STR_ ## a ## _ ## b #define PCCARD_P(a, b) PCMCIA_PRODUCT_ ## a ## _ ## b #define PCCARD_C(a, b) PCMCIA_CIS_ ## a ## _ ## b -#define PCMCIA_CARD(v, p, f) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \ - PCCARD_P(v, p), f, PCCARD_C(v, p) } -#define PCMCIA_CARD2(v1, p1, p2, f) \ +#if PCCARD_API_LEVEL >= 6 +#define PCMCIA_CARD_D(v, p) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \ + PCCARD_P(v, p), PCCARD_C(v, p) } +#define PCMCIA_CARD2_D(v1, p1, p2) \ { PCMCIA_STR_ ## p2, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \ - f, PCMCIA_CIS_ ## p2} - + PCMCIA_CIS_ ## p2} +#define PCMCIA_CARD(v, p) { NULL, PCMCIA_VENDOR_ ## v, \ + PCCARD_P(v, p), PCCARD_C(v, p) } +#define PCMCIA_CARD2(v1, p1, p2) \ + { NULL, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \ + PCMCIA_CIS_ ## p2} +#else +#define PCMCIA_CARD_D(v, p, f) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \ + PCCARD_P(v, p), PCCARD_C(v, p) } +#define PCMCIA_CARD2_D(v1, p1, p2, f) \ + { PCMCIA_STR_ ## p2, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \ + PCMCIA_CIS_ ## p2} +#define PCMCIA_CARD(v, p, f) { NULL, PCMCIA_VENDOR_ ## v, \ + PCCARD_P(v, p), PCCARD_C(v, p) } +#define PCMCIA_CARD2(v1, p1, p2, f) \ + { NULL, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \ + PCMCIA_CIS_ ## p2} +#endif diff --git a/sys/bus/pccard/power_if.m b/sys/bus/pccard/power_if.m index 4eef372961..6ea6bf932e 100644 --- a/sys/bus/pccard/power_if.m +++ b/sys/bus/pccard/power_if.m @@ -1,4 +1,4 @@ -# +#- # Copyright (c) 1999 M. Warner Losh. # All rights reserved. # @@ -23,8 +23,8 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD: src/sys/dev/pccard/power_if.m,v 1.3 2000/04/16 06:04:13 imp Exp $ -# $DragonFly: src/sys/bus/pccard/power_if.m,v 1.1 2004/02/10 07:55:45 joerg Exp $ +# $FreeBSD: src/sys/dev/pccard/power_if.m,v 1.4 2005/01/06 01:43:03 imp Exp $ +# $DragonFly: src/sys/bus/pccard/power_if.m,v 1.2 2007/07/05 12:08:53 sephe Exp $ # #include diff --git a/sys/bus/pccard/slot.h b/sys/bus/pccard/slot.h deleted file mode 100644 index 3d2ee4988a..0000000000 --- a/sys/bus/pccard/slot.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Slot structures for PC-CARD interface. - * Each slot has a controller specific structure - * attached to it. A slot number allows - * mapping from the character device to the - * slot structure. This is separate to the - * controller slot number to allow multiple controllers - * to be accessed. - *------------------------------------------------------------------------- - * - * Copyright (c) 1995 Andrew McRae. All rights reserved. - * - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD: src/sys/pccard/slot.h,v 1.25.2.5 2002/09/22 20:26:58 imp Exp $ - * $DragonFly: src/sys/bus/pccard/Attic/slot.h,v 1.7 2006/10/25 20:55:51 dillon Exp $ - */ - -#ifndef _PCCARD_SLOT_H -#define _PCCARD_SLOT_H - -/* - * Normally we shouldn't include stuff here, but we're trying to be - * compatible with the long, dark hand of the past. - */ -#include -#include -#include -#include - -/* - * Controller data - Specific to each slot controller. - */ -struct slot; -struct slot_ctrl { - void (*mapirq)(struct slot *, int); - /* Map irq */ - int (*mapmem)(struct slot *, int); - /* Map memory */ - int (*mapio)(struct slot *, int); - /* Map io */ - void (*reset)(void *); - /* init */ - void (*disable)(struct slot *); - /* Disable slot */ - int (*power)(struct slot *); - /* Set power values */ - int (*ioctl)(struct slot *, int, caddr_t); - /* ioctl to lower level */ - void (*resume)(struct slot *); - /* suspend/resume support */ - int maxmem; /* Number of allowed memory windows */ - int maxio; /* Number of allowed I/O windows */ -}; - -/* - * Device structure for cards. Each card may have one - * or more pccard drivers attached to it; each driver is assumed - * to require at most one interrupt handler, one I/O block - * and one memory block. This structure is used to link the different - * devices together. - */ -struct pccard_devinfo { - uint8_t name[128]; - int running; /* Current state of driver */ - uint8_t misc[DEV_MISC_LEN]; /* For any random info */ - uint8_t manufstr[DEV_MAX_CIS_LEN]; - uint8_t versstr[DEV_MAX_CIS_LEN]; - uint32_t manufacturer; /* Manufacturer ID */ - uint32_t product; /* Product ID */ - uint32_t prodext; /* Product ID (extended) */ - struct slot *slt; /* Back pointer to slot */ - struct resource_list resources; -}; - -/* - * Per-slot structure. - */ -struct slot { - int slotnum; /* Slot number */ - int flags; /* Slot flags (see below) */ - int rwmem; /* Read/write flags */ - int irq; /* IRQ allocated (0 = none) */ - - /* - * flags. - */ - unsigned int insert_seq; /* Firing up under the card */ -#if 0 - struct callout insert_ch; /* Insert event timeout handle */ - struct callout poff_ch; /* Power Off timeout handle */ -#endif - - enum cardstate state, laststate; /* Current/last card states */ - struct selinfo selp; /* Info for select */ - struct mem_desc mem[NUM_MEM_WINDOWS]; /* Memory windows */ - struct io_desc io[NUM_IO_WINDOWS]; /* I/O windows */ - struct power pwr; /* Power values */ - struct slot_ctrl *ctrl; /* Per-controller data */ - void *cdata; /* Controller specific data */ - int pwr_off_pending;/* Power status of slot */ - device_t dev; /* Config system device. */ - cdev_t d; /* fs device */ -}; - -#define PCCARD_DEVICE2SOFTC(d) ((struct slot *) device_get_softc(d)) -#define PCCARD_DEV2SOFTC(d) ((struct slot *) (d)->si_drv1) - -enum card_event { card_removed, card_inserted, card_deactivated }; - -struct slot *pccard_init_slot(device_t, struct slot_ctrl *); -void pccard_event(struct slot *, enum card_event); -int pccard_suspend(device_t); -int pccard_resume(device_t); - -#endif /* !_PCCARD_SLOT_H */ diff --git a/sys/bus/pci/pci.c b/sys/bus/pci/pci.c index 2ba5d64ea7..ca7f1c0bc7 100644 --- a/sys/bus/pci/pci.c +++ b/sys/bus/pci/pci.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/pci/pci.c,v 1.141.2.15 2002/04/30 17:48:18 tmm Exp $ - * $DragonFly: src/sys/bus/pci/pci.c,v 1.39 2007/06/02 18:48:40 dillon Exp $ + * $DragonFly: src/sys/bus/pci/pci.c,v 1.40 2007/07/05 12:08:53 sephe Exp $ * */ @@ -2127,7 +2127,7 @@ static device_method_t pci_methods[] = { { 0, 0 } }; -static driver_t pci_driver = { +driver_t pci_driver = { "pci", pci_methods, 1, /* no softc */ diff --git a/sys/conf/files b/sys/conf/files index 7d18a630c0..5ab5e7a5d1 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,5 +1,5 @@ # $FreeBSD: src/sys/conf/files,v 1.340.2.137 2003/06/04 17:10:30 sam Exp $ -# $DragonFly: src/sys/conf/files,v 1.165 2007/06/26 19:30:46 dillon Exp $ +# $DragonFly: src/sys/conf/files,v 1.166 2007/07/05 12:08:53 sephe Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -107,6 +107,8 @@ dev/raid/aac/aac_cam.c optional aacp aac dev/pccard/pccbb/pccbb.c optional cbb +dev/pccard/pccbb/pccbb_isa.c optional cbb isa +dev/pccard/pccbb/pccbb_pci.c optional cbb pci dev/pccard/cardbus/cardbus.c optional cardbus dev/pccard/cardbus/cardbus_cis.c optional cardbus dev/pccard/exca/exca.c optional cbb @@ -1043,7 +1045,6 @@ bus/pccard/card_if.m standard bus/pccard/pccard.c optional pccard bus/pccard/pccard_cis.c optional pccard bus/pccard/pccard_cis_quirks.c optional pccard -bus/pccard/pccard_beep.c optional pccard bus/pccard/power_if.m standard dev/agp/agp.c optional agp dev/agp/agp_intel.c optional agp diff --git a/sys/dev/disk/ata/ata-card.c b/sys/dev/disk/ata/ata-card.c index 6d8263d552..ef912af3a4 100644 --- a/sys/dev/disk/ata/ata-card.c +++ b/sys/dev/disk/ata/ata-card.c @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-card.c,v 1.4.2.1 2002/03/18 08:37:33 sos Exp $ - * $DragonFly: src/sys/dev/disk/ata/ata-card.c,v 1.6 2006/10/25 20:55:53 dillon Exp $ + * $DragonFly: src/sys/dev/disk/ata/ata-card.c,v 1.7 2007/07/05 12:08:53 sephe Exp $ */ #include @@ -40,6 +40,7 @@ #include #include "ata-all.h" +#include #include #include #include @@ -47,7 +48,7 @@ static const struct pccard_product ata_pccard_products[] = { PCMCIA_CARD(FREECOM, PCCARDIDE, 0), PCMCIA_CARD(EXP, EXPMULTIMEDIA, 0), - PCMCIA_CARD(IODATA, CBIDE2, 0), + PCMCIA_CARD(IODATA3, CBIDE2, 0), PCMCIA_CARD(OEM2, CDROM1, 0), PCMCIA_CARD(OEM2, IDE, 0), PCMCIA_CARD(PANASONIC, KXLC005, 0), diff --git a/sys/dev/disk/nata/ata-card.c b/sys/dev/disk/nata/ata-card.c index 27baf79c1d..9199b6aa8c 100644 --- a/sys/dev/disk/nata/ata-card.c +++ b/sys/dev/disk/nata/ata-card.c @@ -24,7 +24,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ata/ata-card.c,v 1.39 2006/01/05 21:27:19 sos Exp $ - * $DragonFly: src/sys/dev/disk/nata/ata-card.c,v 1.2 2006/12/05 19:28:14 tgen Exp $ + * $DragonFly: src/sys/dev/disk/nata/ata-card.c,v 1.3 2007/07/05 12:08:53 sephe Exp $ */ #include "opt_ata.h" @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,7 @@ static const struct pccard_product ata_pccard_products[] = { PCMCIA_CARD(FREECOM, PCCARDIDE, 0), PCMCIA_CARD(EXP, EXPMULTIMEDIA, 0), - PCMCIA_CARD(IODATA, CBIDE2, 0), + PCMCIA_CARD(IODATA3, CBIDE2, 0), PCMCIA_CARD(OEM2, CDROM1, 0), PCMCIA_CARD(OEM2, IDE, 0), PCMCIA_CARD(PANASONIC, KXLC005, 0), diff --git a/sys/dev/disk/ncv/ncr53c500_pccard.c b/sys/dev/disk/ncv/ncr53c500_pccard.c index 48a9d5b73f..63c6c6b4d9 100644 --- a/sys/dev/disk/ncv/ncr53c500_pccard.c +++ b/sys/dev/disk/ncv/ncr53c500_pccard.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/ncv/ncr53c500_pccard.c,v 1.2.2.5 2001/12/17 13:30:18 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/ncv/ncr53c500_pccard.c,v 1.14 2007/05/17 21:08:47 dillon Exp $ */ +/* $DragonFly: src/sys/dev/disk/ncv/ncr53c500_pccard.c,v 1.15 2007/07/05 12:08:53 sephe Exp $ */ /* $NecBSD: ncr53c500_pisa.c,v 1.28 1998/11/26 01:59:11 honda Exp $ */ /* $NetBSD$ */ @@ -51,6 +51,7 @@ #include "dvcfg.h" +#include #include #include @@ -68,8 +69,6 @@ #include #include -#include -#include static int ncvprobe(DEVPORT_PDEVICE devi); static int ncvattach(DEVPORT_PDEVICE devi); diff --git a/sys/dev/disk/nsp/nsp_pccard.c b/sys/dev/disk/nsp/nsp_pccard.c index dc5482d4b7..1809b93117 100644 --- a/sys/dev/disk/nsp/nsp_pccard.c +++ b/sys/dev/disk/nsp/nsp_pccard.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/nsp/nsp_pccard.c,v 1.2.2.6 2001/12/17 13:30:19 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/nsp/nsp_pccard.c,v 1.12 2007/05/17 21:08:48 dillon Exp $ */ +/* $DragonFly: src/sys/dev/disk/nsp/nsp_pccard.c,v 1.13 2007/07/05 12:08:53 sephe Exp $ */ /* $NecBSD: nsp_pisa.c,v 1.4 1999/04/15 01:35:54 kmatsuda Exp $ */ /* $NetBSD$ */ @@ -47,6 +47,7 @@ #include +#include #include #include @@ -65,8 +66,6 @@ #if !defined(__FreeBSD__) || __FreeBSD_version < 500014 #include #endif -#include -#include #define PIO_MODE 0x100 /* pd_flags */ diff --git a/sys/dev/disk/stg/tmc18c30_pccard.c b/sys/dev/disk/stg/tmc18c30_pccard.c index 22482db504..080167b625 100644 --- a/sys/dev/disk/stg/tmc18c30_pccard.c +++ b/sys/dev/disk/stg/tmc18c30_pccard.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/stg/tmc18c30_pccard.c,v 1.2.2.6 2001/12/17 13:30:19 non Exp $ */ -/* $DragonFly: src/sys/dev/disk/stg/tmc18c30_pccard.c,v 1.13 2007/05/17 21:08:49 dillon Exp $ */ +/* $DragonFly: src/sys/dev/disk/stg/tmc18c30_pccard.c,v 1.14 2007/07/05 12:08:53 sephe Exp $ */ /* $NecBSD: tmc18c30_pisa.c,v 1.22 1998/11/26 01:59:21 honda Exp $ */ /* $NetBSD$ */ @@ -51,6 +51,7 @@ #include +#include #include #include @@ -66,8 +67,6 @@ #include #include -#include -#include static const struct pccard_product stg_products[] = { PCMCIA_CARD(FUTUREDOMAIN, SCSI2GO, 0), diff --git a/sys/dev/netif/cs/if_cs_isa.c b/sys/dev/netif/cs/if_cs_isa.c index bb06055447..86faeb4b0f 100644 --- a/sys/dev/netif/cs/if_cs_isa.c +++ b/sys/dev/netif/cs/if_cs_isa.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/cs/if_cs_isa.c,v 1.1.2.1 2001/01/25 20:13:48 imp Exp $ - * $DragonFly: src/sys/dev/netif/cs/if_cs_isa.c,v 1.8 2006/10/25 20:55:56 dillon Exp $ + * $DragonFly: src/sys/dev/netif/cs/if_cs_isa.c,v 1.9 2007/07/05 12:08:53 sephe Exp $ */ #include @@ -91,3 +91,4 @@ static driver_t cs_isa_driver = { extern devclass_t cs_devclass; DRIVER_MODULE(if_cs, isa, cs_isa_driver, cs_devclass, 0, 0); +MODULE_DEPEND(if_cs, isa, 1, 1, 1); diff --git a/sys/dev/netif/ed/if_ed_pccard.c b/sys/dev/netif/ed/if_ed_pccard.c index f04d3ae982..8cb09211bf 100644 --- a/sys/dev/netif/ed/if_ed_pccard.c +++ b/sys/dev/netif/ed/if_ed_pccard.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/ed/if_ed_pccard.c,v 1.55 2003/12/31 04:25:00 kato Exp $ - * $DragonFly: src/sys/dev/netif/ed/if_ed_pccard.c,v 1.18 2006/12/22 23:26:19 swildner Exp $ + * $DragonFly: src/sys/dev/netif/ed/if_ed_pccard.c,v 1.19 2007/07/05 12:08:53 sephe Exp $ */ #include "opt_ed.h" @@ -48,6 +48,7 @@ #include "if_edreg.h" #include "if_edvar.h" +#include #include #include #ifndef ED_NO_MIIBUS @@ -143,7 +144,6 @@ static const struct ed_product { { PCMCIA_CARD(COREGA, FETHER_PCC_TXF, 0), NE2000DVF_DL10019 }, { PCMCIA_CARD(DAYNA, COMMUNICARD_E_1, 0), 0}, { PCMCIA_CARD(DAYNA, COMMUNICARD_E_2, 0), 0}, - { PCMCIA_CARD(DIGITAL, DEPCMXX, 0), 0 }, { PCMCIA_CARD(DLINK, DE650, 0), 0}, { PCMCIA_CARD(DLINK, DE660, 0), 0 }, { PCMCIA_CARD(DLINK, DE660PLUS, 0), 0}, @@ -153,25 +153,25 @@ static const struct ed_product { { PCMCIA_CARD(EPSON, EEN10B, 0), 0}, { PCMCIA_CARD(EXP, THINLANCOMBO, 0), 0}, { PCMCIA_CARD(IBM, INFOMOVER, 0), 0}, - { PCMCIA_CARD(IODATA, PCLAT, 0), 0}, - { PCMCIA_CARD(IODATA, PCLATE, 0), 0}, + { PCMCIA_CARD(IODATA3, PCLAT, 0), 0}, { PCMCIA_CARD(KINGSTON, KNE2, 0), 0}, { PCMCIA_CARD(LANTECH, FASTNETTX, 0),NE2000DVF_AX88190 }, { PCMCIA_CARD(LINKSYS, COMBO_ECARD, 0), NE2000DVF_DL10019 }, { PCMCIA_CARD(LINKSYS, ECARD_1, 0), 0}, { PCMCIA_CARD(LINKSYS, ECARD_2, 0), 0}, { PCMCIA_CARD(LINKSYS, ETHERFAST, 0), NE2000DVF_DL10019 }, - { PCMCIA_CARD(LINKSYS, PCM100, 0), 0}, { PCMCIA_CARD(LINKSYS, TRUST_COMBO_ECARD, 0), 0}, - { PCMCIA_CARD(LINKSYS, ETHERFAST, 0), NE2000DVF_DL10019 }, { PCMCIA_CARD(MACNICA, ME1_JEIDA, 0), 0}, { PCMCIA_CARD(MELCO, LPC3_CLX, 0), NE2000DVF_AX88190}, { PCMCIA_CARD(MELCO, LPC3_TX, 0), NE2000DVF_AX88190 }, { PCMCIA_CARD(NDC, ND5100_E, 0), 0}, { PCMCIA_CARD(NETGEAR, FA410TXC, 0), NE2000DVF_DL10019}, { PCMCIA_CARD(NETGEAR, FA411, 0), NE2000DVF_AX88190}, + { PCMCIA_CARD(NEXTCOM, NEXTHAWK, 0), 0}, + { PCMCIA_CARD(OEM2, ETHERNET, 0), 0}, { PCMCIA_CARD(PLANET, SMARTCOM2000, 0), 0 }, { PCMCIA_CARD(PREMAX, PE200, 0), 0}, + { PCMCIA_CARD(RACORE, ETHERNET, 0), 0}, { PCMCIA_CARD(RPTI, EP400, 0), 0}, { PCMCIA_CARD(RPTI, EP401, 0), 0}, { PCMCIA_CARD(SMC, EZCARD, 0), 0}, @@ -181,7 +181,7 @@ static const struct ed_product { { PCMCIA_CARD(SOCKET, LP_ETH_10_100_CF, 0), NE2000DVF_DL10019}, { PCMCIA_CARD(SVEC, COMBOCARD, 0), 0}, { PCMCIA_CARD(SVEC, LANCARD, 0), 0}, - { PCMCIA_CARD(SYNERGY21, S21810, 0), 0}, + { PCMCIA_CARD(TAMARACK, ETHERNET, 0), 0}, { PCMCIA_CARD(TDK, LAK_CD031, 0), 0}, { PCMCIA_CARD(TELECOMDEVICE, TCD_HPC100, 0), NE2000DVF_AX88190 }, { PCMCIA_CARD(XIRCOM, CFE_10, 0), 0}, diff --git a/sys/dev/netif/fe/if_fe_pccard.c b/sys/dev/netif/fe/if_fe_pccard.c index cfeb722897..a5d77319aa 100644 --- a/sys/dev/netif/fe/if_fe_pccard.c +++ b/sys/dev/netif/fe/if_fe_pccard.c @@ -20,7 +20,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/fe/if_fe_pccard.c,v 1.2.2.1 2000/09/22 10:01:47 nyan Exp $ - * $DragonFly: src/sys/dev/netif/fe/if_fe_pccard.c,v 1.12 2006/11/07 06:43:23 dillon Exp $ + * $DragonFly: src/sys/dev/netif/fe/if_fe_pccard.c,v 1.13 2007/07/05 12:08:53 sephe Exp $ */ #include "opt_fe.h" @@ -48,7 +48,6 @@ #include #include -#include #include "card_if.h" diff --git a/sys/dev/netif/wi/if_wi_pccard.c b/sys/dev/netif/wi/if_wi_pccard.c index 012ef55a84..e902d86051 100644 --- a/sys/dev/netif/wi/if_wi_pccard.c +++ b/sys/dev/netif/wi/if_wi_pccard.c @@ -30,7 +30,7 @@ * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/wi/if_wi_pccard.c,v 1.47 2004/06/09 06:31:40 imp Exp $ - * $DragonFly: src/sys/dev/netif/wi/if_wi_pccard.c,v 1.10 2006/10/25 20:55:59 dillon Exp $ + * $DragonFly: src/sys/dev/netif/wi/if_wi_pccard.c,v 1.11 2007/07/05 12:08:53 sephe Exp $ */ /* @@ -63,6 +63,7 @@ #include #include +#include #include #include #include @@ -134,8 +135,9 @@ static const struct pccard_product wi_pccard_products[] = { PCMCIA_CARD(GEMTEK, WLAN, 0), PCMCIA_CARD(HWN, AIRWAY80211, 0), PCMCIA_CARD(INTEL, PRO_WLAN_2011, 0), - PCMCIA_CARD(INTERSIL, MA401RA, 0), - PCMCIA_CARD(INTERSIL, DWL650, 0), + PCMCIA_CARD(INTERSIL, ISL37100P, 0), + PCMCIA_CARD(INTERSIL, ISL37110P, 0), + PCMCIA_CARD(INTERSIL, ISL37300P, 0), PCMCIA_CARD(INTERSIL2, PRISM2, 0), PCMCIA_CARD(IODATA2, WCF12, 0), PCMCIA_CARD(IODATA2, WNB11PCM, 0), @@ -144,7 +146,7 @@ static const struct pccard_product wi_pccard_products[] = { PCMCIA_CARD(MICROSOFT, MN_520, 0), PCMCIA_CARD(NOKIA, C020_WLAN, 0), PCMCIA_CARD(NOKIA, C110_WLAN, 0), - PCMCIA_CARD(PLANEX_2, GWNS11H, 0), + PCMCIA_CARD(PLANEX, GWNS11H, 0), PCMCIA_CARD(PROXIM, HARMONY, 0), PCMCIA_CARD(PROXIM, RANGELANDS_8430, 0), PCMCIA_CARD(SAMSUNG, SWL_2000N, 0), diff --git a/sys/dev/netif/xe/if_xe_pccard.c b/sys/dev/netif/xe/if_xe_pccard.c index 13d94604d4..5c6c41ffd4 100644 --- a/sys/dev/netif/xe/if_xe_pccard.c +++ b/sys/dev/netif/xe/if_xe_pccard.c @@ -26,7 +26,7 @@ * xe pccard interface driver * * $FreeBSD: src/sys/dev/xe/if_xe_pccard.c,v 1.11 2003/10/14 22:51:35 rsm Exp $ - * $DragonFly: src/sys/dev/netif/xe/if_xe_pccard.c,v 1.3 2006/10/25 20:56:00 dillon Exp $ + * $DragonFly: src/sys/dev/netif/xe/if_xe_pccard.c,v 1.4 2007/07/05 12:08:53 sephe Exp $ */ #include @@ -59,9 +59,10 @@ #endif static const struct pccard_product xe_pccard_products[] = { - PCMCIA_CARD(ACCTON, EN2226, 0), + PCMCIA_CARD(COMPAQ, CPQ550, 0), PCMCIA_CARD(COMPAQ2, CPQ_10_100, 0), PCMCIA_CARD(INTEL, EEPRO100, 0), + PCMCIA_CARD(RACORE, ACCTON_EN2226, 0), PCMCIA_CARD(XIRCOM, CE, 0), PCMCIA_CARD(XIRCOM, CE2, 0), PCMCIA_CARD(XIRCOM, CE3, 0), diff --git a/sys/dev/pccard/cardbus/cardbus.c b/sys/dev/pccard/cardbus/cardbus.c index 03e087b887..ce16c2806f 100644 --- a/sys/dev/pccard/cardbus/cardbus.c +++ b/sys/dev/pccard/cardbus/cardbus.c @@ -1,23 +1,21 @@ -/* - * Copyright (c) 2000,2001 Jonathan Chen. - * All rights reserved. +/*- + * Copyright (c) 2003 M. Warner Losh. All Rights Reserved. + * Copyright (c) 2000,2001 Jonathan Chen. All rights reserved. * * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -26,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/dev/cardbus/cardbus.c,v 1.28 2002/11/27 17:30:41 imp Exp $ - * $DragonFly: src/sys/dev/pccard/cardbus/cardbus.c,v 1.10 2006/12/22 23:26:22 swildner Exp $ + * $DragonFly: src/sys/dev/pccard/cardbus/cardbus.c,v 1.11 2007/07/05 12:08:54 sephe Exp $ */ /* @@ -41,8 +39,10 @@ #include #include #include +#include #include #include + #include #include @@ -54,6 +54,7 @@ #include #include #include +#include #include #include "power_if.h" @@ -78,75 +79,301 @@ SYSCTL_INT(_hw_cardbus, OID_AUTO, cis_debug, CTLFLAG_RW, #define DEVPRINTF(x) if (cardbus_debug) device_printf x -static struct resource *cardbus_alloc_resource(device_t cbdev, device_t child, - int type, int *rid, u_long start, u_long end, u_long count, - u_int flags); +static void cardbus_add_map(device_t cbdev, device_t child, int reg); +static int cardbus_alloc_resources(device_t cbdev, device_t child); static int cardbus_attach(device_t cbdev); static int cardbus_attach_card(device_t cbdev); -static int cardbus_child_location_str(device_t cbdev, device_t child, - char *, size_t len); -static int cardbus_child_pnpinfo_str(device_t cbdev, device_t child, - char *, size_t len); -static __inline void cardbus_clear_command_bit(device_t cbdev, device_t child, - u_int16_t bit); -static void cardbus_delete_resource(device_t cbdev, device_t child, - int type, int rid); -static void cardbus_delete_resource_method(device_t cbdev, device_t child, - int type, int rid); +static int cardbus_barsort(const void *a, const void *b); static int cardbus_detach(device_t cbdev); static int cardbus_detach_card(device_t cbdev); static void cardbus_device_setup_regs(device_t brdev, int b, int s, int f, pcicfgregs *cfg); -static void cardbus_disable_busmaster_method(device_t cbdev, device_t child); -static void cardbus_disable_io_method(device_t cbdev, device_t child, - int space); static void cardbus_driver_added(device_t cbdev, driver_t *driver); -static void cardbus_enable_busmaster_method(device_t cbdev, device_t child); -static void cardbus_enable_io_method(device_t cbdev, device_t child, - int space); -static int cardbus_freecfg(struct cardbus_devinfo *dinfo); -static int cardbus_get_powerstate_method(device_t cbdev, device_t child); -static int cardbus_get_resource(device_t cbdev, device_t child, int type, - int rid, u_long *startp, u_long *countp); -static int cardbus_get_resource_method(device_t cbdev, device_t child, - int type, int rid, u_long *startp, u_long *countp); -static void cardbus_hdrtypedata(device_t brdev, int b, int s, int f, - pcicfgregs *cfg); -static int cardbus_print_child(device_t cbdev, device_t child); -static int cardbus_print_resources(struct resource_list *rl, - const char *name, int type, const char *format); -static void cardbus_print_verbose(struct cardbus_devinfo *dinfo); +static void cardbus_pickup_maps(device_t cbdev, device_t child); static int cardbus_probe(device_t cbdev); -static void cardbus_probe_nomatch(device_t cbdev, device_t child); -static struct cardbus_devinfo *cardbus_read_device(device_t brdev, int b, - int s, int f); -static void cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg); -static u_int32_t cardbus_read_config_method(device_t cbdev, - device_t child, int reg, int width); static int cardbus_read_ivar(device_t cbdev, device_t child, int which, - u_long *result); + uintptr_t *result); static void cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo); -static int cardbus_release_resource(device_t cbdev, device_t child, - int type, int rid, struct resource *r); -static __inline void cardbus_set_command_bit(device_t cbdev, device_t child, - u_int16_t bit); -static int cardbus_set_powerstate_method(device_t cbdev, device_t child, - int state); -static int cardbus_set_resource(device_t cbdev, device_t child, int type, - int rid, u_long start, u_long count, struct resource *res); -static int cardbus_set_resource_method(device_t cbdev, device_t child, - int type, int rid, u_long start, u_long count); -static int cardbus_setup_intr(device_t cbdev, device_t child, - struct resource *irq, int flags, driver_intr_t *intr, - void *arg, void **cookiep, lwkt_serialize_t); -static int cardbus_teardown_intr(device_t cbdev, device_t child, - struct resource *irq, void *cookie); -static void cardbus_write_config_method(device_t cbdev, device_t child, - int reg, u_int32_t val, int width); static int cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value); +/* + * Resource allocation + */ +/* + * Adding a memory/io resource (sans CIS) + */ + +static void +cardbus_add_map(device_t cbdev, device_t child, int reg) +{ + struct cardbus_devinfo *dinfo = device_get_ivars(child); + struct resource_list_entry *rle; + uint32_t size; + uint32_t testval; + int type; + + SLIST_FOREACH(rle, &dinfo->pci.resources, link) { + if (rle->rid == reg) + return; + } + + if (reg == CARDBUS_ROM_REG) + testval = CARDBUS_ROM_ADDRMASK; + else + testval = ~0; + + pci_write_config(child, reg, testval, 4); + testval = pci_read_config(child, reg, 4); + + if (testval == ~0 || testval == 0) + return; + + if ((testval & 1) == 0) + type = SYS_RES_MEMORY; + else + type = SYS_RES_IOPORT; + + size = CARDBUS_MAPREG_MEM_SIZE(testval); + device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n", + reg, size); + resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size); +} + +static void +cardbus_pickup_maps(device_t cbdev, device_t child) +{ + struct cardbus_devinfo *dinfo = device_get_ivars(child); + int reg; + + /* + * Try to pick up any resources that was not specified in CIS. + * Maybe this isn't any longer necessary now that we have fixed + * CIS parsing and we should filter things here? XXX + */ + for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) + cardbus_add_map(cbdev, child, PCIR_BAR(reg)); +} + +static void +cardbus_do_res(struct resource_list_entry *rle, device_t child, uint32_t start) +{ + rle->start = start; + rle->end = start + rle->count - 1; + pci_write_config(child, rle->rid, rle->start, 4); +} + +static int +cardbus_barsort(const void *a, const void *b) +{ + return ((*(const struct resource_list_entry * const *)b)->count - + (*(const struct resource_list_entry * const *)a)->count); +} + +/* XXX this function is too long */ +static int +cardbus_alloc_resources(device_t cbdev, device_t child) +{ + struct cardbus_devinfo *dinfo = device_get_ivars(child); + int count; + struct resource_list_entry *rle; + struct resource_list_entry **barlist; + int tmp; + uint32_t mem_psize = 0, mem_nsize = 0, io_size = 0; + struct resource *res; + uint32_t start,end; + int rid, flags; + + count = 0; + SLIST_FOREACH(rle, &dinfo->pci.resources, link) { + count++; + } + if (count == 0) + return (0); + barlist = kmalloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF, + M_WAITOK); + count = 0; + SLIST_FOREACH(rle, &dinfo->pci.resources, link) { + barlist[count] = rle; + if (rle->type == SYS_RES_IOPORT) { + io_size += rle->count; + } else if (rle->type == SYS_RES_MEMORY) { + if (dinfo->mprefetchable & BARBIT(rle->rid)) + mem_psize += rle->count; + else + mem_nsize += rle->count; + } + count++; + } + + /* + * We want to allocate the largest resource first, so that our + * allocated memory is packed. + */ + kqsort(barlist, count, sizeof(struct resource_list_entry *), + cardbus_barsort); + + /* Allocate prefetchable memory */ + flags = 0; + for (tmp = 0; tmp < count; tmp++) { + rle = barlist[tmp]; + if (rle->res == NULL && + rle->type == SYS_RES_MEMORY && + dinfo->mprefetchable & BARBIT(rle->rid)) { + flags = rman_make_alignment_flags(rle->count); + break; + } + } + if (flags > 0) { /* If any prefetchable memory is requested... */ + /* + * First we allocate one big space for all resources of this + * type. We do this because our parent, pccbb, needs to open + * a window to forward all addresses within the window, and + * it would be best if nobody else has resources allocated + * within the window. + * (XXX: Perhaps there might be a better way to do this?) + */ + rid = 0; + res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, + (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL, + mem_psize, flags); + if (res == NULL) { + device_printf(cbdev, + "Can't get memory for prefetch mem\n"); + kfree(barlist, M_DEVBUF); + return (EIO); + } + start = rman_get_start(res); + end = rman_get_end(res); + DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end)); + /* + * Now that we know the region is free, release it and hand it + * out piece by piece. + */ + bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); + for (tmp = 0; tmp < count; tmp++) { + rle = barlist[tmp]; + if (rle->type == SYS_RES_MEMORY && + dinfo->mprefetchable & BARBIT(rle->rid)) { + cardbus_do_res(rle, child, start); + start += rle->count; + } + } + } + + /* Allocate non-prefetchable memory */ + flags = 0; + for (tmp = 0; tmp < count; tmp++) { + rle = barlist[tmp]; + if (rle->type == SYS_RES_MEMORY && + (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) { + flags = rman_make_alignment_flags(rle->count); + break; + } + } + if (flags > 0) { /* If any non-prefetchable memory is requested... */ + /* + * First we allocate one big space for all resources of this + * type. We do this because our parent, pccbb, needs to open + * a window to forward all addresses within the window, and + * it would be best if nobody else has resources allocated + * within the window. + * (XXX: Perhaps there might be a better way to do this?) + */ + rid = 0; + res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, + ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL, + mem_nsize, flags); + if (res == NULL) { + device_printf(cbdev, + "Can't get memory for non-prefetch mem\n"); + kfree(barlist, M_DEVBUF); + return (EIO); + } + start = rman_get_start(res); + end = rman_get_end(res); + DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n", + start, end)); + /* + * Now that we know the region is free, release it and hand it + * out piece by piece. + */ + bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); + for (tmp = 0; tmp < count; tmp++) { + rle = barlist[tmp]; + if (rle->type == SYS_RES_MEMORY && + (dinfo->mprefetchable & BARBIT(rle->rid)) == 0) { + cardbus_do_res(rle, child, start); + start += rle->count; + } + } + } + + /* Allocate IO ports */ + flags = 0; + for (tmp = 0; tmp < count; tmp++) { + rle = barlist[tmp]; + if (rle->type == SYS_RES_IOPORT) { + flags = rman_make_alignment_flags(rle->count); + break; + } + } + if (flags > 0) { /* If any IO port is requested... */ + /* + * First we allocate one big space for all resources of this + * type. We do this because our parent, pccbb, needs to open + * a window to forward all addresses within the window, and + * it would be best if nobody else has resources allocated + * within the window. + * (XXX: Perhaps there might be a better way to do this?) + */ + rid = 0; + res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0, + (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags); + if (res == NULL) { + device_printf(cbdev, + "Can't get memory for IO ports\n"); + kfree(barlist, M_DEVBUF); + return (EIO); + } + start = rman_get_start(res); + end = rman_get_end(res); + DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end)); + /* + * Now that we know the region is free, release it and hand it + * out piece by piece. + */ + bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res); + for (tmp = 0; tmp < count; tmp++) { + rle = barlist[tmp]; + if (rle->type == SYS_RES_IOPORT) { + cardbus_do_res(rle, child, start); + start += rle->count; + } + } + } + + /* Allocate IRQ */ + rid = 0; + res = bus_alloc_resource_any(cbdev, SYS_RES_IRQ, &rid, RF_SHAREABLE); + if (res == NULL) { + device_printf(cbdev, "Can't get memory for irq\n"); + kfree(barlist, M_DEVBUF); + return (EIO); + } + start = rman_get_start(res); + end = rman_get_end(res); + bus_release_resource(cbdev, SYS_RES_IRQ, rid, res); + resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, start, end, + 1); + dinfo->pci.cfg.intline = rman_get_start(res); + pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1); + + kfree(barlist, M_DEVBUF); + return (0); +} + /************************************************************************/ /* Probe/Attach */ /************************************************************************/ @@ -212,33 +439,22 @@ static int cardbus_attach_card(device_t cbdev) { device_t brdev = device_get_parent(cbdev); + device_t child; int cardattached = 0; - static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */ int bus, slot, func; cardbus_detach_card(cbdev); /* detach existing cards */ - POWER_ENABLE_SOCKET(brdev, cbdev); bus = pcib_get_bus(brdev); - if (bus == 0) { - /* - * XXX EVILE BAD XXX - * Not all BIOSes initialize the secondary bus number properly, - * so if the default is bad, we just put one in and hope it - * works. - */ - bus = curr_bus_number; - pci_write_config(brdev, PCIR_SECBUS_2, curr_bus_number, 1); - pci_write_config(brdev, PCIR_SUBBUS_2, curr_bus_number + 2, 1); - curr_bus_number += 3; - } /* For each function, set it up and try to attach a driver to it */ for (slot = 0; slot <= CARDBUS_SLOTMAX; slot++) { int cardbusfunchigh = 0; for (func = 0; func <= cardbusfunchigh; func++) { - struct cardbus_devinfo *dinfo = - cardbus_read_device(brdev, bus, slot, func); + struct cardbus_devinfo *dinfo; + dinfo = (struct cardbus_devinfo *) + pci_read_device(brdev, bus, slot, func, + sizeof(struct cardbus_devinfo)); if (dinfo == NULL) continue; if (dinfo->pci.cfg.mfdev) @@ -246,17 +462,24 @@ cardbus_attach_card(device_t cbdev) cardbus_device_setup_regs(brdev, bus, slot, func, &dinfo->pci.cfg); - cardbus_print_verbose(dinfo); - dinfo->pci.cfg.dev = device_add_child(cbdev, NULL, -1); - if (!dinfo->pci.cfg.dev) { + child = device_add_child(cbdev, NULL, -1); + if (child == NULL) { DEVPRINTF((cbdev, "Cannot add child!\n")); - cardbus_freecfg(dinfo); + pci_freecfg((struct pci_devinfo *)dinfo); continue; } + dinfo->pci.cfg.dev = child; resource_list_init(&dinfo->pci.resources); - device_set_ivars(dinfo->pci.cfg.dev, dinfo); - cardbus_do_cis(cbdev, dinfo->pci.cfg.dev); - if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0) + device_set_ivars(child, dinfo); + if (cardbus_do_cis(cbdev, child) != 0) { + DEVPRINTF((cbdev, "Can't parse cis\n")); + pci_freecfg((struct pci_devinfo *)dinfo); + continue; + } + cardbus_pickup_maps(cbdev, child); + cardbus_alloc_resources(cbdev, child); + pci_print_verbose(&dinfo->pci); + if (device_probe_and_attach(child) != 0) cardbus_release_all_resources(cbdev, dinfo); else cardattached++; @@ -294,7 +517,7 @@ cardbus_detach_card(device_t cbdev) device_detach(devlist[tmp]); cardbus_release_all_resources(cbdev, dinfo); device_delete_child(cbdev, devlist[tmp]); - cardbus_freecfg(dinfo); + pci_freecfg((struct pci_devinfo *)dinfo); } POWER_DISABLE_SOCKET(device_get_parent(cbdev), cbdev); kfree(devlist, M_TEMP); @@ -306,348 +529,37 @@ cardbus_driver_added(device_t cbdev, driver_t *driver) { int numdevs; device_t *devlist; - int tmp; + device_t dev; + int i; struct cardbus_devinfo *dinfo; - device_get_children(cbdev, &devlist, &numdevs); - DEVICE_IDENTIFY(driver, cbdev); - POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev); - for (tmp = 0; tmp < numdevs; tmp++) { - if (device_get_state(devlist[tmp]) == DS_NOTPRESENT) { - dinfo = device_get_ivars(devlist[tmp]); -#ifdef notyet - cardbus_device_setup_regs(brdev, bus, slot, func, - &dinfo->pci.cfg); -#endif - cardbus_print_verbose(dinfo); - resource_list_init(&dinfo->pci.resources); - cardbus_do_cis(cbdev, dinfo->pci.cfg.dev); - if (device_probe_and_attach(dinfo->pci.cfg.dev) != 0) { - cardbus_release_all_resources(cbdev, dinfo); - } - } - } - - kfree(devlist, M_TEMP); -} - -/************************************************************************/ -/* PCI-Like config reading (copied from pci.c */ -/************************************************************************/ - -/* read configuration header into pcicfgrect structure */ - -static void -cardbus_read_extcap(device_t cbdev, pcicfgregs *cfg) -{ -#define REG(n, w) PCIB_READ_CONFIG(cbdev, cfg->bus, cfg->slot, cfg->func, n, w) - int ptr, nextptr, ptrptr; - - switch (cfg->hdrtype) { - case 0: - ptrptr = 0x34; - break; - case 2: - ptrptr = 0x14; - break; - default: - return; /* no extended capabilities support */ - } - nextptr = REG(ptrptr, 1); /* sanity check? */ - + device_get_children(cbdev, &devlist, &numdevs); /* - * Read capability entries. + * If there are no drivers attached, but there are children, + * then power the card up. */ - while (nextptr != 0) { - /* Sanity check */ - if (nextptr > 255) { - kprintf("illegal PCI extended capability offset %d\n", - nextptr); - return; - } - /* Find the next entry */ - ptr = nextptr; - nextptr = REG(ptr + 1, 1); - - /* Process this entry */ - switch (REG(ptr, 1)) { - case 0x01: /* PCI power management */ - if (cfg->pp_cap == 0) { - cfg->pp_cap = REG(ptr + PCIR_POWER_CAP, 2); - cfg->pp_status = ptr + PCIR_POWER_STATUS; - cfg->pp_pmcsr = ptr + PCIR_POWER_PMCSR; - if ((nextptr - ptr) > PCIR_POWER_DATA) - cfg->pp_data = ptr + PCIR_POWER_DATA; - } - break; - default: - break; - } + for (i = 0; i < numdevs; i++) { + dev = devlist[i]; + if (device_get_state(dev) != DS_NOTPRESENT) + break; } -#undef REG -} - -/* extract header type specific config data */ - -static void -cardbus_hdrtypedata(device_t brdev, int b, int s, int f, pcicfgregs *cfg) -{ -#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) - switch (cfg->hdrtype) { - case 0: - cfg->subvendor = REG(PCIR_SUBVEND_0, 2); - cfg->subdevice = REG(PCIR_SUBDEV_0, 2); - cfg->nummaps = PCI_MAXMAPS_0; - break; - case 1: - cfg->subvendor = REG(PCIR_SUBVEND_1, 2); - cfg->subdevice = REG(PCIR_SUBDEV_1, 2); - cfg->nummaps = PCI_MAXMAPS_1; - break; - case 2: - cfg->subvendor = REG(PCIR_SUBVEND_2, 2); - cfg->subdevice = REG(PCIR_SUBDEV_2, 2); - cfg->nummaps = PCI_MAXMAPS_2; - break; - } -#undef REG -} - -static struct cardbus_devinfo * -cardbus_read_device(device_t brdev, int b, int s, int f) -{ -#define REG(n, w) PCIB_READ_CONFIG(brdev, b, s, f, n, w) - pcicfgregs *cfg = NULL; - struct cardbus_devinfo *devlist_entry = NULL; - - if (REG(PCIR_DEVVENDOR, 4) != 0xffffffff) { - devlist_entry = kmalloc(sizeof(struct cardbus_devinfo), - M_DEVBUF, M_WAITOK | M_ZERO); - if (devlist_entry == NULL) - return (NULL); - - cfg = &devlist_entry->pci.cfg; - - cfg->bus = b; - cfg->slot = s; - cfg->func = f; - cfg->vendor = REG(PCIR_VENDOR, 2); - cfg->device = REG(PCIR_DEVICE, 2); - cfg->cmdreg = REG(PCIR_COMMAND, 2); - cfg->statreg = REG(PCIR_STATUS, 2); - cfg->baseclass = REG(PCIR_CLASS, 1); - cfg->subclass = REG(PCIR_SUBCLASS, 1); - cfg->progif = REG(PCIR_PROGIF, 1); - cfg->revid = REG(PCIR_REVID, 1); - cfg->hdrtype = REG(PCIR_HDRTYPE, 1); - cfg->cachelnsz = REG(PCIR_CACHELNSZ, 1); - cfg->lattimer = REG(PCIR_LATTIMER, 1); - cfg->intpin = REG(PCIR_INTPIN, 1); - cfg->intline = REG(PCIR_INTLINE, 1); - - cfg->mingnt = REG(PCIR_MINGNT, 1); - cfg->maxlat = REG(PCIR_MAXLAT, 1); - - cfg->mfdev = (cfg->hdrtype & PCIM_MFDEV) != 0; - cfg->hdrtype &= ~PCIM_MFDEV; - - cardbus_hdrtypedata(brdev, b, s, f, cfg); - - if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT) - cardbus_read_extcap(brdev, cfg); - - devlist_entry->pci.conf.pc_sel.pc_bus = cfg->bus; - devlist_entry->pci.conf.pc_sel.pc_dev = cfg->slot; - devlist_entry->pci.conf.pc_sel.pc_func = cfg->func; - devlist_entry->pci.conf.pc_hdr = cfg->hdrtype; - - devlist_entry->pci.conf.pc_subvendor = cfg->subvendor; - devlist_entry->pci.conf.pc_subdevice = cfg->subdevice; - devlist_entry->pci.conf.pc_vendor = cfg->vendor; - devlist_entry->pci.conf.pc_device = cfg->device; - - devlist_entry->pci.conf.pc_class = cfg->baseclass; - devlist_entry->pci.conf.pc_subclass = cfg->subclass; - devlist_entry->pci.conf.pc_progif = cfg->progif; - devlist_entry->pci.conf.pc_revid = cfg->revid; - } - return (devlist_entry); -#undef REG -} - -/* free pcicfgregs structure and all depending data structures */ - -static int -cardbus_freecfg(struct cardbus_devinfo *dinfo) -{ - kfree(dinfo, M_DEVBUF); - - return (0); -} - -static void -cardbus_print_verbose(struct cardbus_devinfo *dinfo) -{ - if (bootverbose || cardbus_debug > 0) - { - pcicfgregs *cfg = &dinfo->pci.cfg; - - kprintf("found->\tvendor=0x%04x, dev=0x%04x, revid=0x%02x\n", - cfg->vendor, cfg->device, cfg->revid); - kprintf("\tclass=[%s]%02x-%02x-%02x, hdrtype=0x%02x, mfdev=%d\n", - pci_class_to_string(cfg->baseclass), - cfg->baseclass, cfg->subclass, cfg->progif, - cfg->hdrtype, cfg->mfdev); - kprintf("\tcmdreg=0x%04x, statreg=0x%04x, " - "cachelnsz=%d (dwords)\n", - cfg->cmdreg, cfg->statreg, cfg->cachelnsz); - kprintf("\tlattimer=0x%02x (%d ns), mingnt=0x%02x (%d ns), " - "maxlat=0x%02x (%d ns)\n", - cfg->lattimer, cfg->lattimer * 30, - cfg->mingnt, cfg->mingnt * 250, cfg->maxlat, - cfg->maxlat * 250); - if (cfg->intpin > 0) - kprintf("\tintpin=%c, irq=%d\n", - cfg->intpin + 'a' - 1, cfg->intline); - } -} - -/************************************************************************/ -/* Resources */ -/************************************************************************/ - -static int -cardbus_set_resource(device_t cbdev, device_t child, int type, int rid, - u_long start, u_long count, struct resource *res) -{ - struct cardbus_devinfo *dinfo; - struct resource_list *rl; - struct resource_list_entry *rle; - - if (device_get_parent(child) != cbdev) - return ENOENT; - - dinfo = device_get_ivars(child); - rl = &dinfo->pci.resources; - rle = resource_list_find(rl, type, rid); - if (rle == NULL) { - resource_list_add(rl, type, rid, start, start + count - 1, - count); - if (res != NULL) { - rle = resource_list_find(rl, type, rid); - rle->res = res; - } - } else { - if (rle->res == NULL) { - } else if (rle->res->r_dev == cbdev && - (!(rman_get_flags(rle->res) & RF_ACTIVE))) { - int f; - f = rman_get_flags(rle->res); - bus_release_resource(cbdev, type, rid, res); - rle->res = bus_alloc_resource(cbdev, type, &rid, - start, start + count - 1, - count, f); - } else { - device_printf(cbdev, "set_resource: resource busy\n"); - return EBUSY; - } - rle->start = start; - rle->end = start + count - 1; - rle->count = count; - if (res != NULL) - rle->res = res; - } - if (device_get_parent(child) == cbdev) - pci_write_config(child, rid, start, 4); - return 0; -} - -static int -cardbus_get_resource(device_t cbdev, device_t child, int type, int rid, - u_long *startp, u_long *countp) -{ - struct cardbus_devinfo *dinfo; - struct resource_list *rl; - struct resource_list_entry *rle; - - if (device_get_parent(child) != cbdev) - return ENOENT; - - dinfo = device_get_ivars(child); - rl = &dinfo->pci.resources; - rle = resource_list_find(rl, type, rid); - if (!rle) - return ENOENT; - if (startp) - *startp = rle->start; - if (countp) - *countp = rle->count; - return 0; -} - -static void -cardbus_delete_resource(device_t cbdev, device_t child, int type, int rid) -{ - struct cardbus_devinfo *dinfo; - struct resource_list *rl; - struct resource_list_entry *rle; - - if (device_get_parent(child) != cbdev) - return; - - dinfo = device_get_ivars(child); - rl = &dinfo->pci.resources; - rle = resource_list_find(rl, type, rid); - if (rle) { - if (rle->res) { - if (rle->res->r_dev != cbdev || - rman_get_flags(rle->res) & RF_ACTIVE) { - device_printf(cbdev, "delete_resource: " - "Resource still owned by child, oops. " - "(type=%d, rid=%d, addr=%lx)\n", - rle->type, rle->rid, - rman_get_start(rle->res)); - return; - } - bus_release_resource(cbdev, type, rid, rle->res); - } - resource_list_delete(rl, type, rid); + if (i > 0 && i == numdevs) + POWER_ENABLE_SOCKET(device_get_parent(cbdev), cbdev); + for (i = 0; i < numdevs; i++) { + dev = devlist[i]; + if (device_get_state(dev) != DS_NOTPRESENT) + continue; + dinfo = device_get_ivars(dev); + pci_print_verbose(&dinfo->pci); + resource_list_init(&dinfo->pci.resources); + cardbus_do_cis(cbdev, dev); + cardbus_pickup_maps(cbdev, dev); + cardbus_alloc_resources(cbdev, dev); + if (device_probe_and_attach(dev) != 0) + cardbus_release_all_resources(cbdev, dinfo); } - if (device_get_parent(child) == cbdev) - pci_write_config(child, rid, 0, 4); -} - -static int -cardbus_set_resource_method(device_t cbdev, device_t child, int type, int rid, - u_long start, u_long count) -{ - int ret; - ret = cardbus_set_resource(cbdev, child, type, rid, start, count, NULL); - if (ret != 0) - return ret; - return BUS_SET_RESOURCE(device_get_parent(cbdev), child, type, rid, - start, count); -} - -static int -cardbus_get_resource_method(device_t cbdev, device_t child, int type, int rid, - u_long *startp, u_long *countp) -{ - int ret; - ret = cardbus_get_resource(cbdev, child, type, rid, startp, countp); - if (ret != 0) - return ret; - return BUS_GET_RESOURCE(device_get_parent(cbdev), child, type, rid, - startp, countp); -} - -static void -cardbus_delete_resource_method(device_t cbdev, device_t child, - int type, int rid) -{ - cardbus_delete_resource(cbdev, child, type, rid); - BUS_DELETE_RESOURCE(device_get_parent(cbdev), child, type, rid); + kfree(devlist, M_TEMP); } static void @@ -658,16 +570,14 @@ cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo) /* Free all allocated resources */ SLIST_FOREACH(rle, &dinfo->pci.resources, link) { if (rle->res) { - if (rle->res->r_dev != cbdev) + if (rman_get_device(rle->res) != cbdev) device_printf(cbdev, "release_all_resource: " "Resource still owned by child, oops. " "(type=%d, rid=%d, addr=%lx)\n", rle->type, rle->rid, rman_get_start(rle->res)); BUS_RELEASE_RESOURCE(device_get_parent(cbdev), - rle->res->r_dev, - rle->type, rle->rid, - rle->res); + cbdev, rle->type, rle->rid, rle->res); rle->res = NULL; /* * zero out config so the card won't acknowledge @@ -679,266 +589,12 @@ cardbus_release_all_resources(device_t cbdev, struct cardbus_devinfo *dinfo) resource_list_free(&dinfo->pci.resources); } -static struct resource * -cardbus_alloc_resource(device_t cbdev, device_t child, int type, - int *rid, u_long start, u_long end, u_long count, u_int flags) -{ - struct cardbus_devinfo *dinfo; - struct resource_list_entry *rle = 0; - int passthrough = (device_get_parent(child) != cbdev); - - if (passthrough) { - return (BUS_ALLOC_RESOURCE(device_get_parent(cbdev), child, - type, rid, start, end, count, flags)); - } - - dinfo = device_get_ivars(child); - rle = resource_list_find(&dinfo->pci.resources, type, *rid); - - if (!rle) - return NULL; /* no resource of that type/rid */ - - if (!rle->res) { - device_printf(cbdev, "WARNING: Resource not reserved by bus\n"); - return NULL; - } else { - /* Release the cardbus hold on the resource */ - if (rle->res->r_dev != cbdev) - return NULL; - bus_release_resource(cbdev, type, *rid, rle->res); - rle->res = NULL; - switch (type) { - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - if (!(flags & RF_ALIGNMENT_MASK)) - flags |= rman_make_alignment_flags(rle->count); - break; - case SYS_RES_IRQ: - flags |= RF_SHAREABLE; - break; - } - /* Allocate the resource to the child */ - return resource_list_alloc(&dinfo->pci.resources, cbdev, child, - type, rid, rle->start, rle->end, rle->count, flags); - } -} - -static int -cardbus_release_resource(device_t cbdev, device_t child, int type, int rid, - struct resource *r) -{ - struct cardbus_devinfo *dinfo; - int passthrough = (device_get_parent(child) != cbdev); - struct resource_list_entry *rle = 0; - int flags; - int ret; - - if (passthrough) { - return BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child, - type, rid, r); - } - - dinfo = device_get_ivars(child); - /* - * According to the PCI 2.2 spec, devices may share an address - * decoder between memory mapped ROM access and memory - * mapped register access. To be safe, disable ROM access - * whenever it is released. - */ - if (rid == CARDBUS_ROM_REG) { - uint32_t rom_reg; - - rom_reg = pci_read_config(child, rid, 4); - rom_reg &= ~CARDBUS_ROM_ENABLE; - pci_write_config(child, rid, rom_reg, 4); - } - - rle = resource_list_find(&dinfo->pci.resources, type, rid); - - if (!rle) { - device_printf(cbdev, "Allocated resource not found\n"); - return ENOENT; - } - if (!rle->res) { - device_printf(cbdev, "Allocated resource not recorded\n"); - return ENOENT; - } - - ret = BUS_RELEASE_RESOURCE(device_get_parent(cbdev), child, - type, rid, r); - switch (type) { - case SYS_RES_IOPORT: - case SYS_RES_MEMORY: - flags = rman_make_alignment_flags(rle->count); - break; - case SYS_RES_IRQ: - flags = RF_SHAREABLE; - break; - default: - flags = 0; - } - /* Restore cardbus hold on the resource */ - rle->res = bus_alloc_resource(cbdev, type, &rid, - rle->start, rle->end, rle->count, flags); - if (rle->res == NULL) - device_printf(cbdev, "release_resource: " - "unable to reacquire resource\n"); - return ret; -} - -static int -cardbus_setup_intr(device_t cbdev, device_t child, struct resource *irq, - int flags, driver_intr_t *intr, void *arg, - void **cookiep, lwkt_serialize_t serializer) -{ - int ret; - device_t cdev; - struct cardbus_devinfo *dinfo; - - ret = bus_generic_setup_intr(cbdev, child, irq, flags, intr, arg, - cookiep, serializer); - if (ret != 0) - return ret; - - for (cdev = child; cbdev != device_get_parent(cdev); - cdev = device_get_parent(cdev)) - /* NOTHING */; - dinfo = device_get_ivars(cdev); - - return 0; -} - -static int -cardbus_teardown_intr(device_t cbdev, device_t child, struct resource *irq, - void *cookie) -{ - int ret; - device_t cdev; - struct cardbus_devinfo *dinfo; - - ret = bus_generic_teardown_intr(cbdev, child, irq, cookie); - if (ret != 0) - return ret; - - for (cdev = child; cbdev != device_get_parent(cdev); - cdev = device_get_parent(cdev)) - /* NOTHING */; - dinfo = device_get_ivars(cdev); - - return (0); -} - - /************************************************************************/ /* Other Bus Methods */ /************************************************************************/ static int -cardbus_print_resources(struct resource_list *rl, const char *name, - int type, const char *format) -{ - struct resource_list_entry *rle; - int printed, retval; - - printed = 0; - retval = 0; - /* Yes, this is kinda cheating */ - SLIST_FOREACH(rle, rl, link) { - if (rle->type == type) { - if (printed == 0) - retval += kprintf(" %s ", name); - else if (printed > 0) - retval += kprintf(","); - printed++; - retval += kprintf(format, rle->start); - if (rle->count > 1) { - retval += kprintf("-"); - retval += kprintf(format, rle->start + - rle->count - 1); - } - } - } - return retval; -} - -static int -cardbus_print_child(device_t cbdev, device_t child) -{ - struct cardbus_devinfo *dinfo; - struct resource_list *rl; - pcicfgregs *cfg; - int retval = 0; - - dinfo = device_get_ivars(child); - cfg = &dinfo->pci.cfg; - rl = &dinfo->pci.resources; - - retval += bus_print_child_header(cbdev, child); - - retval += cardbus_print_resources(rl, "port", SYS_RES_IOPORT, "%#lx"); - retval += cardbus_print_resources(rl, "mem", SYS_RES_MEMORY, "%#lx"); - retval += cardbus_print_resources(rl, "irq", SYS_RES_IRQ, "%ld"); - if (device_get_flags(cbdev)) - retval += kprintf(" flags %#x", device_get_flags(cbdev)); - - retval += kprintf(" at device %d.%d", pci_get_slot(child), - pci_get_function(child)); - - retval += bus_print_child_footer(cbdev, child); - - return (retval); -} - -static void -cardbus_probe_nomatch(device_t cbdev, device_t child) -{ - struct cardbus_devinfo *dinfo; - pcicfgregs *cfg; - - dinfo = device_get_ivars(child); - cfg = &dinfo->pci.cfg; - device_printf(cbdev, ""); - kprintf(" (vendor=0x%04x, dev=0x%04x)", cfg->vendor, cfg->device); - kprintf(" at %d.%d", pci_get_slot(child), pci_get_function(child)); - if (cfg->intpin > 0 && cfg->intline != 255) { - kprintf(" irq %d", cfg->intline); - } - kprintf("\n"); - - return; -} - -static int -cardbus_child_location_str(device_t cbdev, device_t child, char *buf, - size_t buflen) -{ - struct cardbus_devinfo *dinfo; - pcicfgregs *cfg; - - dinfo = device_get_ivars(child); - cfg = &dinfo->pci.cfg; - ksnprintf(buf, buflen, "slot=%d function=%d", pci_get_slot(child), - pci_get_function(child)); - return (0); -} - -static int -cardbus_child_pnpinfo_str(device_t cbdev, device_t child, char *buf, - size_t buflen) -{ - struct cardbus_devinfo *dinfo; - pcicfgregs *cfg; - - dinfo = device_get_ivars(child); - cfg = &dinfo->pci.cfg; - ksnprintf(buf, buflen, "vendor=0x%04x device=0x%04x subvendor=0x%04x " - "subdevice=0x%04x", cfg->vendor, cfg->device, cfg->subvendor, - cfg->subdevice); - return (0); -} - -static int -cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result) +cardbus_read_ivar(device_t cbdev, device_t child, int which, uintptr_t *result) { struct cardbus_devinfo *dinfo; pcicfgregs *cfg; @@ -952,56 +608,14 @@ cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result) * The generic accessor doesn't deal with failure, so * we set the return value, then return an error. */ - if ((dinfo->fepresent & (1 << TPL_FUNCE_LAN_NID)) == 0) { - *((u_int8_t **) result) = NULL; - return (EINVAL); + if (dinfo->fepresent & (1 << PCCARD_TPLFE_TYPE_LAN_NID)) { + *((uint8_t **) result) = dinfo->funce.lan.nid; + break; } - *((u_int8_t **) result) = dinfo->funce.lan.nid; - break; - case PCI_IVAR_SUBVENDOR: - *result = cfg->subvendor; - break; - case PCI_IVAR_SUBDEVICE: - *result = cfg->subdevice; - break; - case PCI_IVAR_VENDOR: - *result = cfg->vendor; - break; - case PCI_IVAR_DEVICE: - *result = cfg->device; - break; - case PCI_IVAR_DEVID: - *result = (cfg->device << 16) | cfg->vendor; - break; - case PCI_IVAR_CLASS: - *result = cfg->baseclass; - break; - case PCI_IVAR_SUBCLASS: - *result = cfg->subclass; - break; - case PCI_IVAR_PROGIF: - *result = cfg->progif; - break; - case PCI_IVAR_REVID: - *result = cfg->revid; - break; - case PCI_IVAR_INTPIN: - *result = cfg->intpin; - break; - case PCI_IVAR_IRQ: - *result = cfg->intline; - break; - case PCI_IVAR_BUS: - *result = cfg->bus; - break; - case PCI_IVAR_SLOT: - *result = cfg->slot; - break; - case PCI_IVAR_FUNCTION: - *result = cfg->func; - break; + *((uint8_t **) result) = NULL; + return (EINVAL); default: - return ENOENT; + return (pci_read_ivar(cbdev, child, which, result)); } return 0; } @@ -1009,198 +623,7 @@ cardbus_read_ivar(device_t cbdev, device_t child, int which, u_long *result) static int cardbus_write_ivar(device_t cbdev, device_t child, int which, uintptr_t value) { - struct cardbus_devinfo *dinfo; - pcicfgregs *cfg; - - dinfo = device_get_ivars(child); - cfg = &dinfo->pci.cfg; - - switch (which) { - case PCI_IVAR_ETHADDR: - case PCI_IVAR_SUBVENDOR: - case PCI_IVAR_SUBDEVICE: - case PCI_IVAR_VENDOR: - case PCI_IVAR_DEVICE: - case PCI_IVAR_DEVID: - case PCI_IVAR_CLASS: - case PCI_IVAR_SUBCLASS: - case PCI_IVAR_PROGIF: - case PCI_IVAR_REVID: - case PCI_IVAR_INTPIN: - case PCI_IVAR_IRQ: - case PCI_IVAR_BUS: - case PCI_IVAR_SLOT: - case PCI_IVAR_FUNCTION: - return EINVAL; /* disallow for now */ - default: - return ENOENT; - } - return 0; -} - -/************************************************************************/ -/* Compatibility with PCI bus (XXX: Do we need this?) */ -/************************************************************************/ - -/* - * PCI power manangement - */ -static int -cardbus_set_powerstate_method(device_t cbdev, device_t child, int state) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - pcicfgregs *cfg = &dinfo->pci.cfg; - u_int16_t status; - int result; - - if (cfg->pp_cap != 0) { - status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2) - & ~PCIM_PSTAT_DMASK; - result = 0; - switch (state) { - case PCI_POWERSTATE_D0: - status |= PCIM_PSTAT_D0; - break; - case PCI_POWERSTATE_D1: - if (cfg->pp_cap & PCIM_PCAP_D1SUPP) { - status |= PCIM_PSTAT_D1; - } else { - result = EOPNOTSUPP; - } - break; - case PCI_POWERSTATE_D2: - if (cfg->pp_cap & PCIM_PCAP_D2SUPP) { - status |= PCIM_PSTAT_D2; - } else { - result = EOPNOTSUPP; - } - break; - case PCI_POWERSTATE_D3: - status |= PCIM_PSTAT_D3; - break; - default: - result = EINVAL; - } - if (result == 0) - PCI_WRITE_CONFIG(cbdev, child, cfg->pp_status, - status, 2); - } else { - result = ENXIO; - } - return (result); -} - -static int -cardbus_get_powerstate_method(device_t cbdev, device_t child) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - pcicfgregs *cfg = &dinfo->pci.cfg; - u_int16_t status; - int result; - - if (cfg->pp_cap != 0) { - status = PCI_READ_CONFIG(cbdev, child, cfg->pp_status, 2); - switch (status & PCIM_PSTAT_DMASK) { - case PCIM_PSTAT_D0: - result = PCI_POWERSTATE_D0; - break; - case PCIM_PSTAT_D1: - result = PCI_POWERSTATE_D1; - break; - case PCIM_PSTAT_D2: - result = PCI_POWERSTATE_D2; - break; - case PCIM_PSTAT_D3: - result = PCI_POWERSTATE_D3; - break; - default: - result = PCI_POWERSTATE_UNKNOWN; - break; - } - } else { - /* No support, device is always at D0 */ - result = PCI_POWERSTATE_D0; - } - return (result); -} - -static u_int32_t -cardbus_read_config_method(device_t cbdev, device_t child, int reg, int width) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - pcicfgregs *cfg = &dinfo->pci.cfg; - - return PCIB_READ_CONFIG(device_get_parent(cbdev), - cfg->bus, cfg->slot, cfg->func, reg, width); -} - -static void -cardbus_write_config_method(device_t cbdev, device_t child, int reg, - u_int32_t val, int width) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - pcicfgregs *cfg = &dinfo->pci.cfg; - - PCIB_WRITE_CONFIG(device_get_parent(cbdev), - cfg->bus, cfg->slot, cfg->func, reg, val, width); -} - -static __inline void -cardbus_set_command_bit(device_t cbdev, device_t child, u_int16_t bit) -{ - u_int16_t command; - - command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); - command |= bit; - PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); -} - -static __inline void -cardbus_clear_command_bit(device_t cbdev, device_t child, u_int16_t bit) -{ - u_int16_t command; - - command = PCI_READ_CONFIG(cbdev, child, PCIR_COMMAND, 2); - command &= ~bit; - PCI_WRITE_CONFIG(cbdev, child, PCIR_COMMAND, command, 2); -} - -static void -cardbus_enable_busmaster_method(device_t cbdev, device_t child) -{ - cardbus_set_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); -} - -static void -cardbus_disable_busmaster_method(device_t cbdev, device_t child) -{ - cardbus_clear_command_bit(cbdev, child, PCIM_CMD_BUSMASTEREN); -} - -static void -cardbus_enable_io_method(device_t cbdev, device_t child, int space) -{ - switch (space) { - case SYS_RES_IOPORT: - cardbus_set_command_bit(cbdev, child, PCIM_CMD_PORTEN); - break; - case SYS_RES_MEMORY: - cardbus_set_command_bit(cbdev, child, PCIM_CMD_MEMEN); - break; - } -} - -static void -cardbus_disable_io_method(device_t cbdev, device_t child, int space) -{ - switch (space) { - case SYS_RES_IOPORT: - cardbus_clear_command_bit(cbdev, child, PCIM_CMD_PORTEN); - break; - case SYS_RES_MEMORY: - cardbus_clear_command_bit(cbdev, child, PCIM_CMD_MEMEN); - break; - } + return(pci_write_ivar(cbdev, child, which, value)); } static device_method_t cardbus_methods[] = { @@ -1208,59 +631,25 @@ static device_method_t cardbus_methods[] = { DEVMETHOD(device_probe, cardbus_probe), DEVMETHOD(device_attach, cardbus_attach), DEVMETHOD(device_detach, cardbus_detach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), DEVMETHOD(device_suspend, cardbus_suspend), DEVMETHOD(device_resume, cardbus_resume), /* Bus interface */ - DEVMETHOD(bus_print_child, cardbus_print_child), - DEVMETHOD(bus_probe_nomatch, cardbus_probe_nomatch), DEVMETHOD(bus_read_ivar, cardbus_read_ivar), DEVMETHOD(bus_write_ivar, cardbus_write_ivar), DEVMETHOD(bus_driver_added, cardbus_driver_added), - DEVMETHOD(bus_alloc_resource, cardbus_alloc_resource), - DEVMETHOD(bus_release_resource, cardbus_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, cardbus_setup_intr), - DEVMETHOD(bus_teardown_intr, cardbus_teardown_intr), - - DEVMETHOD(bus_set_resource, cardbus_set_resource_method), - DEVMETHOD(bus_get_resource, cardbus_get_resource_method), - DEVMETHOD(bus_delete_resource, cardbus_delete_resource_method), - DEVMETHOD(bus_child_pnpinfo_str, cardbus_child_pnpinfo_str), - DEVMETHOD(bus_child_location_str, cardbus_child_location_str), /* Card Interface */ DEVMETHOD(card_attach_card, cardbus_attach_card), DEVMETHOD(card_detach_card, cardbus_detach_card), - DEVMETHOD(card_cis_read, cardbus_cis_read), - DEVMETHOD(card_cis_free, cardbus_cis_free), - - /* Cardbus/PCI interface */ - DEVMETHOD(pci_read_config, cardbus_read_config_method), - DEVMETHOD(pci_write_config, cardbus_write_config_method), - DEVMETHOD(pci_enable_busmaster, cardbus_enable_busmaster_method), - DEVMETHOD(pci_disable_busmaster, cardbus_disable_busmaster_method), - DEVMETHOD(pci_enable_io, cardbus_enable_io_method), - DEVMETHOD(pci_disable_io, cardbus_disable_io_method), - DEVMETHOD(pci_get_powerstate, cardbus_get_powerstate_method), - DEVMETHOD(pci_set_powerstate, cardbus_set_powerstate_method), {0,0} }; -static driver_t cardbus_driver = { - "cardbus", - cardbus_methods, - 0 /* no softc */ -}; +DECLARE_CLASS(pci_driver); +DEFINE_CLASS_1(cardbus, cardbus_driver, cardbus_methods, 0, pci_driver); static devclass_t cardbus_devclass; DRIVER_MODULE(cardbus, cbb, cardbus_driver, cardbus_devclass, 0, 0); MODULE_VERSION(cardbus, 1); -MODULE_DEPEND(cardbus, exca, 1, 1, 1); -/* -MODULE_DEPEND(cardbus, pccbb, 1, 1, 1); -*/ diff --git a/sys/dev/pccard/cardbus/cardbus_cis.c b/sys/dev/pccard/cardbus/cardbus_cis.c index c2d61f1f45..2628509364 100644 --- a/sys/dev/pccard/cardbus/cardbus_cis.c +++ b/sys/dev/pccard/cardbus/cardbus_cis.c @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2000,2001 Jonathan Chen. * All rights reserved. * @@ -6,18 +6,16 @@ * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -25,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.c,v 1.27 2002/11/27 06:56:29 imp Exp $ - * $DragonFly: src/sys/dev/pccard/cardbus/cardbus_cis.c,v 1.5 2006/12/22 23:26:22 swildner Exp $ + * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.c,v 1.50 2005/02/20 20:36:16 imp Exp $ + * $DragonFly: src/sys/dev/pccard/cardbus/cardbus_cis.c,v 1.6 2007/07/05 12:08:54 sephe Exp $ */ /* @@ -37,70 +35,85 @@ #include #include #include + #include #include +#include #include #include #include +#include +#include + #include #include #include -#include - extern int cardbus_cis_debug; #define DPRINTF(a) if (cardbus_cis_debug) kprintf a #define DEVPRINTF(x) if (cardbus_cis_debug) device_printf x -#define DECODE_PARAMS \ - (device_t cbdev, device_t child, int id, int len, \ - u_int8_t *tupledata, u_int32_t start, u_int32_t *off, \ - struct tuple_callbacks *info) +struct tuple_callbacks; + +typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len, + uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); struct tuple_callbacks { int id; char *name; - int (*func) DECODE_PARAMS; + tuple_cb *func; }; -#define DECODE_PROTOTYPE(NAME) static int decode_tuple_ ## NAME DECODE_PARAMS -DECODE_PROTOTYPE(generic); -DECODE_PROTOTYPE(nothing); -DECODE_PROTOTYPE(copy); -DECODE_PROTOTYPE(linktarget); -DECODE_PROTOTYPE(vers_1); -DECODE_PROTOTYPE(funcid); -DECODE_PROTOTYPE(manfid); -DECODE_PROTOTYPE(funce); -DECODE_PROTOTYPE(bar); -DECODE_PROTOTYPE(unhandled); -DECODE_PROTOTYPE(end); +static int decode_tuple_generic(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_linktarget(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_vers_1(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_funcid(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_manfid(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_funce(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_bar(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_unhandled(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); +static int decode_tuple_end(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info); + static int cardbus_read_tuple_conf(device_t cbdev, device_t child, - u_int32_t start, u_int32_t *off, int *tupleid, int *len, - u_int8_t *tupledata); + uint32_t start, uint32_t *off, int *tupleid, int *len, + uint8_t *tupledata); static int cardbus_read_tuple_mem(device_t cbdev, struct resource *res, - u_int32_t start, u_int32_t *off, int *tupleid, int *len, - u_int8_t *tupledata); + uint32_t start, uint32_t *off, int *tupleid, int *len, + uint8_t *tupledata); static int cardbus_read_tuple(device_t cbdev, device_t child, - struct resource *res, u_int32_t start, u_int32_t *off, - int *tupleid, int *len, u_int8_t *tupledata); + struct resource *res, uint32_t start, uint32_t *off, + int *tupleid, int *len, uint8_t *tupledata); static void cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, struct resource *res); static struct resource *cardbus_read_tuple_init(device_t cbdev, device_t child, - u_int32_t *start, int *rid); + uint32_t *start, int *rid); static int decode_tuple(device_t cbdev, device_t child, int tupleid, - int len, u_int8_t *tupledata, u_int32_t start, - u_int32_t *off, struct tuple_callbacks *callbacks); + int len, uint8_t *tupledata, uint32_t start, + uint32_t *off, struct tuple_callbacks *callbacks); static int cardbus_parse_cis(device_t cbdev, device_t child, struct tuple_callbacks *callbacks); -static int barsort(const void *a, const void *b); -static int cardbus_alloc_resources(device_t cbdev, device_t child); -static void cardbus_add_map(device_t cbdev, device_t child, int reg); -static void cardbus_pickup_maps(device_t cbdev, device_t child); - #define MAKETUPLE(NAME,FUNC) { CISTPL_ ## NAME, #NAME, decode_tuple_ ## FUNC } @@ -117,85 +130,50 @@ static char *funcnames[] = { "Security" }; -struct cardbus_quirk { - u_int32_t devid; /* Vendor/device of the card */ - int type; -#define CARDBUS_QUIRK_MAP_REG 1 /* PCI map register in weird place */ - int arg1; - int arg2; -}; - -struct cardbus_quirk cardbus_quirks[] = { - { 0 } -}; - -static struct cis_tupleinfo *cisread_buf; -static int ncisread_buf; - /* * Handler functions for various CIS tuples */ -DECODE_PROTOTYPE(generic) +static int +decode_tuple_generic(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { -#ifdef CARDBUS_DEBUG int i; - if (info) - kprintf("TUPLE: %s [%d]:", info->name, len); - else - kprintf("TUPLE: Unknown(0x%02x) [%d]:", id, len); - - for (i = 0; i < len; i++) { - if (i % 0x10 == 0 && len > 0x10) - kprintf("\n 0x%02x:", i); - kprintf(" %02x", tupledata[i]); - } - kprintf("\n"); -#endif - return (0); -} - -DECODE_PROTOTYPE(nothing) -{ - return (0); -} + if (cardbus_cis_debug) { + if (info) + kprintf("TUPLE: %s [%d]:", info->name, len); + else + kprintf("TUPLE: Unknown(0x%02x) [%d]:", id, len); -DECODE_PROTOTYPE(copy) -{ - struct cis_tupleinfo *tmpbuf; - - tmpbuf = kmalloc(sizeof(struct cis_tupleinfo) * (ncisread_buf+1), - M_DEVBUF, M_WAITOK); - if (ncisread_buf > 0) { - memcpy(tmpbuf, cisread_buf, - sizeof(struct cis_tupleinfo) * ncisread_buf); - kfree(cisread_buf, M_DEVBUF); + for (i = 0; i < len; i++) { + if (i % 0x10 == 0 && len > 0x10) + kprintf("\n 0x%02x:", i); + kprintf(" %02x", tupledata[i]); + } + kprintf("\n"); } - cisread_buf = tmpbuf; - - cisread_buf[ncisread_buf].id = id; - cisread_buf[ncisread_buf].len = len; - cisread_buf[ncisread_buf].data = kmalloc(len, M_DEVBUF, M_WAITOK); - memcpy(cisread_buf[ncisread_buf].data, tupledata, len); - ncisread_buf++; return (0); } -DECODE_PROTOTYPE(linktarget) +static int +decode_tuple_linktarget(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { -#ifdef CARDBUS_DEBUG int i; - kprintf("TUPLE: %s [%d]:", info->name, len); + if (cardbus_cis_debug) { + kprintf("TUPLE: %s [%d]:", info->name, len); - for (i = 0; i < len; i++) { - if (i % 0x10 == 0 && len > 0x10) - kprintf("\n 0x%02x:", i); - kprintf(" %02x", tupledata[i]); + for (i = 0; i < len; i++) { + if (i % 0x10 == 0 && len > 0x10) + kprintf("\n 0x%02x:", i); + kprintf(" %02x", tupledata[i]); + } + kprintf("\n"); } - kprintf("\n"); -#endif if (len != 3 || tupledata[0] != 'C' || tupledata[1] != 'I' || tupledata[2] != 'S') { kprintf("Invalid data for CIS Link Target!\n"); @@ -206,116 +184,104 @@ DECODE_PROTOTYPE(linktarget) return (0); } -DECODE_PROTOTYPE(vers_1) +static int +decode_tuple_vers_1(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { int i; - kprintf("Product version: %d.%d\n", tupledata[0], tupledata[1]); - kprintf("Product name: "); - for (i = 2; i < len; i++) { - if (tupledata[i] == '\0') - kprintf(" | "); - else if (tupledata[i] == 0xff) - break; - else - kprintf("%c", tupledata[i]); + if (cardbus_cis_debug) { + kprintf("Product version: %d.%d\n", tupledata[0], tupledata[1]); + kprintf("Product name: "); + for (i = 2; i < len; i++) { + if (tupledata[i] == '\0') + kprintf(" | "); + else if (tupledata[i] == 0xff) + break; + else + kprintf("%c", tupledata[i]); + } + kprintf("\n"); } - kprintf("\n"); return (0); } -DECODE_PROTOTYPE(funcid) +static int +decode_tuple_funcid(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int numnames = sizeof(funcnames) / sizeof(funcnames[0]); int i; - kprintf("Functions: "); - for (i = 0; i < len; i++) { - if (tupledata[i] < numnames) - kprintf("%s", funcnames[tupledata[i]]); - else - kprintf("Unknown(%d)", tupledata[i]); - if (i < len-1) - kprintf(", "); + if (cardbus_cis_debug) { + kprintf("Functions: "); + for (i = 0; i < len; i++) { + if (tupledata[i] < numnames) + kprintf("%s", funcnames[tupledata[i]]); + else + kprintf("Unknown(%d)", tupledata[i]); + if (i < len-1) + kprintf(", "); + } + kprintf("\n"); } - if (len > 0) dinfo->funcid = tupledata[0]; /* use first in list */ - kprintf("\n"); return (0); } -DECODE_PROTOTYPE(manfid) +static int +decode_tuple_manfid(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int i; - kprintf("Manufacturer ID: "); - for (i = 0; i < len; i++) - kprintf("%02x", tupledata[i]); - kprintf("\n"); + if (cardbus_cis_debug) { + kprintf("Manufacturer ID: "); + for (i = 0; i < len; i++) + kprintf("%02x", tupledata[i]); + kprintf("\n"); + } if (len == 5) { - dinfo->mfrid = tupledata[1] | (tupledata[2]<<8); - dinfo->prodid = tupledata[3] | (tupledata[4]<<8); + dinfo->mfrid = tupledata[1] | (tupledata[2] << 8); + dinfo->prodid = tupledata[3] | (tupledata[4] << 8); } return (0); } -DECODE_PROTOTYPE(funce) +static int +decode_tuple_funce(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { struct cardbus_devinfo *dinfo = device_get_ivars(child); int type, i; - kprintf("Function Extension: "); - for (i = 0; i < len; i++) - kprintf("%02x", tupledata[i]); - kprintf("\n"); + if (cardbus_cis_debug) { + kprintf("Function Extension: "); + for (i = 0; i < len; i++) + kprintf("%02x", tupledata[i]); + kprintf("\n"); + } if (len < 2) /* too short */ return (0); type = tupledata[0]; /* XXX <32 always? */ switch (dinfo->funcid) { - case TPL_FUNC_SERIAL: - if (type == TPL_FUNCE_SER_UART) { /* NB: len known > 1 */ - dinfo->funce.sio.type = tupledata[1] & 0x1f; - } - dinfo->fepresent |= 1<funce.lan.tech = tupledata[1]; /* XXX mask? */ - break; -#if 0 - case TPL_FUNCE_LAN_SPEED: - for (i = 0; i < 3; i++) { - if (dinfo->funce.lan.speed[i] == 0) { - if (len > 4) { - dinfo->funce.lan.speed[i] = - ...; - } - break; - } + case PCCARD_TPLFE_TYPE_LAN_NID: + if (tupledata[1] > sizeof(dinfo->funce.lan.nid)) { + /* ignore, warning? */ + return (0); } - break; -#endif - case TPL_FUNCE_LAN_MEDIA: - for (i = 0; i < 4 && dinfo->funce.lan.media[i]; i++) { - if (dinfo->funce.lan.media[i] == 0) { - /* NB: len known > 1 */ - dinfo->funce.lan.media[i] = - tupledata[1]; /*XXX? mask */ - break; - } - } - break; - case TPL_FUNCE_LAN_NID: - if (len > 6) - bcopy(&tupledata[1], dinfo->funce.lan.nid, 6); - break; - case TPL_FUNCE_LAN_CONN: - dinfo->funce.lan.contype = tupledata[1];/*XXX mask? */ + bcopy(tupledata + 2, dinfo->funce.lan.nid, + tupledata[1]); break; } dinfo->fepresent |= 1< 5 || - (type == SYS_RES_IOPORT && bar == 5)) { - device_printf(cbdev, "Invalid BAR number: %02x(%02x)\n", - reg, bar); + + bar = reg & TPL_BAR_REG_ASI_MASK; + if (bar == 0) { + device_printf(cbdev, "Invalid BAR type 0 in CIS\n"); + return (EINVAL); /* XXX Return an error? */ + } else if (bar == 7) { + /* XXX Should we try to map in Option ROMs? */ return (0); } - bar = CARDBUS_BASE0_REG + bar * 4; + + /* Convert from BAR type to BAR offset */ + bar = CARDBUS_BASE0_REG + (bar - 1) * 4; + if (type == SYS_RES_MEMORY) { - if (bar & TPL_BAR_REG_PREFETCHABLE) + if (reg & TPL_BAR_REG_PREFETCHABLE) dinfo->mprefetchable |= BARBIT(bar); - if (bar & TPL_BAR_REG_BELOW1MB) +#if 0 + /* + * XXX: It appears from a careful reading of the spec + * that we're not supposed to honor this when the bridge + * is not on the main system bus. PCI spec doesn't appear + * to allow for memory ranges not listed in the bridge's + * decode range to be decoded. The PC Card spec seems to + * indicate that this should only be done on x86 based + * machines, which seems to imply that on non-x86 machines + * the adddresses can be anywhere. This further implies that + * since the hardware can do it on non-x86 machines, it should + * be able to do it on x86 machines. Therefore, we can and + * should ignore this hint. Furthermore, the PC Card spec + * recommends always allocating memory above 1MB, contradicting + * the other part of the PC Card spec. + * + * NetBSD ignores this bit, but it also ignores the + * prefetchable bit too, so that's not an indication of + * correctness. + */ + if (reg & TPL_BAR_REG_BELOW1MB) dinfo->mbelow1mb |= BARBIT(bar); - } else if (type == SYS_RES_IOPORT) { - if (bar & TPL_BAR_REG_BELOW1MB) - dinfo->ibelow1mb |= BARBIT(bar); +#endif + } + + /* + * Sanity check the BAR length reported in the CIS with the length + * encoded in the PCI BAR. The latter seems to be more reliable. + * XXX - This probably belongs elsewhere. + */ + pci_write_config(child, bar, 0xffffffff, 4); + pci_bar = pci_read_config(child, bar, 4); + if ((pci_bar != 0x0) && (pci_bar != 0xffffffff)) { + if (type == SYS_RES_MEMORY) { + pci_bar &= ~0xf; + } else { + pci_bar &= ~0x3; + } + len = 1 << (ffs(pci_bar) - 1); } + DEVPRINTF((cbdev, "Opening BAR: type=%s, bar=%02x, len=%04x%s%s\n", (type == SYS_RES_MEMORY) ? "MEM" : "IO", bar, len, (type == SYS_RES_MEMORY && dinfo->mprefetchable & BARBIT(bar)) ? " (Prefetchable)" : "", type == SYS_RES_MEMORY ? - ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : - (dinfo->ibelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "" )); + ((dinfo->mbelow1mb & BARBIT(bar)) ? " (Below 1Mb)" : "") : "")); resource_list_add(&dinfo->pci.resources, type, bar, 0UL, ~0UL, len); @@ -376,15 +385,23 @@ DECODE_PROTOTYPE(bar) return (0); } -DECODE_PROTOTYPE(unhandled) +static int +decode_tuple_unhandled(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { + /* Make this message suck less XXX */ kprintf("TUPLE: %s [%d] is unhandled! Bailing...", info->name, len); return (-1); } -DECODE_PROTOTYPE(end) +static int +decode_tuple_end(device_t cbdev, device_t child, int id, + int len, uint8_t *tupledata, uint32_t start, uint32_t *off, + struct tuple_callbacks *info) { - kprintf("CIS reading done\n"); + if (cardbus_cis_debug) + kprintf("CIS reading done\n"); return (0); } @@ -393,12 +410,12 @@ DECODE_PROTOTYPE(end) */ static int -cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start, - u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata) +cardbus_read_tuple_conf(device_t cbdev, device_t child, uint32_t start, + uint32_t *off, int *tupleid, int *len, uint8_t *tupledata) { int i, j; - u_int32_t e; - u_int32_t loc; + uint32_t e; + uint32_t loc; loc = start + *off; @@ -422,8 +439,8 @@ cardbus_read_tuple_conf(device_t cbdev, device_t child, u_int32_t start, } static int -cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start, - u_int32_t *off, int *tupleid, int *len, u_int8_t *tupledata) +cardbus_read_tuple_mem(device_t cbdev, struct resource *res, uint32_t start, + uint32_t *off, int *tupleid, int *len, uint8_t *tupledata) { bus_space_tag_t bt; bus_space_handle_t bh; @@ -442,8 +459,8 @@ cardbus_read_tuple_mem(device_t cbdev, struct resource *res, u_int32_t start, static int cardbus_read_tuple(device_t cbdev, device_t child, struct resource *res, - u_int32_t start, u_int32_t *off, int *tupleid, int *len, - u_int8_t *tupledata) + uint32_t start, uint32_t *off, int *tupleid, int *len, + uint8_t *tupledata) { if (res == (struct resource*)~0UL) { return (cardbus_read_tuple_conf(cbdev, child, start, off, @@ -466,11 +483,11 @@ cardbus_read_tuple_finish(device_t cbdev, device_t child, int rid, } static struct resource * -cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start, +cardbus_read_tuple_init(device_t cbdev, device_t child, uint32_t *start, int *rid) { - u_int32_t testval; - u_int32_t size; + uint32_t testval; + uint32_t size; struct resource *res; switch (CARDBUS_CIS_SPACE(*start)) { @@ -536,10 +553,10 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start, if (CARDBUS_CIS_SPACE(*start) == CARDBUS_CIS_ASI_ROM) { bus_space_tag_t bt; bus_space_handle_t bh; - u_int32_t imagesize; - u_int32_t imagebase = 0; - u_int32_t pcidata; - u_int16_t romsig; + uint32_t imagesize; + uint32_t imagebase = 0; + uint32_t pcidata; + uint16_t romsig; int romnum = 0; int imagenum; @@ -552,7 +569,7 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start, imagebase + CARDBUS_EXROM_SIGNATURE); if (romsig != 0xaa55) { device_printf(cbdev, "Bad header in rom %d: " - "[%x] %04x\n", romnum, imagebase + + "[%x] %04x\n", romnum, imagebase + CARDBUS_EXROM_SIGNATURE, romsig); bus_release_resource(cbdev, SYS_RES_MEMORY, *rid, res); @@ -587,7 +604,7 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start, /* Image size is in 512 byte units */ imagesize <<= 9; - if ((bus_space_read_1(bt, bh, pcidata + + if ((bus_space_read_1(bt, bh, pcidata + CARDBUS_EXROM_DATA_INDICATOR) & 0x80) != 0) { device_printf(cbdev, "Cannot find CIS in " "Option ROM\n"); @@ -612,7 +629,7 @@ cardbus_read_tuple_init(device_t cbdev, device_t child, u_int32_t *start, static int decode_tuple(device_t cbdev, device_t child, int tupleid, int len, - u_int8_t *tupledata, u_int32_t start, u_int32_t *off, + uint8_t *tupledata, uint32_t start, uint32_t *off, struct tuple_callbacks *callbacks) { int i; @@ -621,12 +638,6 @@ decode_tuple(device_t cbdev, device_t child, int tupleid, int len, return (callbacks[i].func(cbdev, child, tupleid, len, tupledata, start, off, &callbacks[i])); } - - if (tupleid < CISTPL_CUSTOMSTART) { - device_printf(cbdev, "Undefined tuple encountered, " - "CIS parsing terminated\n"); - return (EINVAL); - } return (callbacks[i].func(cbdev, child, tupleid, len, tupledata, start, off, NULL)); } @@ -635,22 +646,27 @@ static int cardbus_parse_cis(device_t cbdev, device_t child, struct tuple_callbacks *callbacks) { - u_int8_t tupledata[MAXTUPLESIZE]; + uint8_t tupledata[MAXTUPLESIZE]; int tupleid; int len; int expect_linktarget; - u_int32_t start, off; + uint32_t start, off; struct resource *res; int rid; bzero(tupledata, MAXTUPLESIZE); expect_linktarget = TRUE; - if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0) + if ((start = pci_read_config(child, CARDBUS_CIS_REG, 4)) == 0) { + device_printf(cbdev, "CIS pointer is 0!\n"); return (ENXIO); + } off = 0; res = cardbus_read_tuple_init(cbdev, child, &start, &rid); - if (res == NULL) + if (res == NULL) { + device_printf(cbdev, "Unable to allocate resources for CIS\n"); return (ENXIO); + } + do { if (0 != cardbus_read_tuple(cbdev, child, res, start, &off, &tupleid, &len, tupledata)) { @@ -668,6 +684,8 @@ cardbus_parse_cis(device_t cbdev, device_t child, expect_linktarget = decode_tuple(cbdev, child, tupleid, len, tupledata, start, &off, callbacks); if (expect_linktarget != 0) { + device_printf(cbdev, "Parsing failed with %d\n", + expect_linktarget); cardbus_read_tuple_finish(cbdev, child, rid, res); return (expect_linktarget); } @@ -676,428 +694,22 @@ cardbus_parse_cis(device_t cbdev, device_t child, return (0); } -static int -barsort(const void *a, const void *b) -{ - return ((*(const struct resource_list_entry * const *)b)->count - - (*(const struct resource_list_entry * const *)a)->count); -} - -static int -cardbus_alloc_resources(device_t cbdev, device_t child) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - int count; - struct resource_list_entry *rle; - struct resource_list_entry **barlist; - int tmp; - u_int32_t mem_psize = 0, mem_nsize = 0, io_size = 0; - struct resource *res; - u_int32_t start,end; - int rid, flags; - - count = 0; - SLIST_FOREACH(rle, &dinfo->pci.resources, link) { - count++; - } - if (count == 0) - return (0); - barlist = kmalloc(sizeof(struct resource_list_entry*) * count, M_DEVBUF, - M_WAITOK); - count = 0; - SLIST_FOREACH(rle, &dinfo->pci.resources, link) { - barlist[count] = rle; - if (rle->type == SYS_RES_IOPORT) { - io_size += rle->count; - } else if (rle->type == SYS_RES_MEMORY) { - if (dinfo->mprefetchable & BARBIT(rle->rid)) - mem_psize += rle->count; - else - mem_nsize += rle->count; - } - count++; - } - - /* - * We want to allocate the largest resource first, so that our - * allocated memory is packed. - */ - kqsort(barlist, count, sizeof(struct resource_list_entry*), barsort); - - /* Allocate prefetchable memory */ - flags = 0; - for (tmp = 0; tmp < count; tmp++) { - if (barlist[tmp]->res == NULL && - barlist[tmp]->type == SYS_RES_MEMORY && - dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) { - flags = rman_make_alignment_flags(barlist[tmp]->count); - break; - } - } - if (flags > 0) { /* If any prefetchable memory is requested... */ - /* - * First we allocate one big space for all resources of this - * type. We do this because our parent, pccbb, needs to open - * a window to forward all addresses within the window, and - * it would be best if nobody else has resources allocated - * within the window. - * (XXX: Perhaps there might be a better way to do this?) - */ - rid = 0; - res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, - (dinfo->mprefetchable & dinfo->mbelow1mb)?0xFFFFF:~0UL, - mem_psize, flags); - start = rman_get_start(res); - end = rman_get_end(res); - DEVPRINTF((cbdev, "Prefetchable memory at %x-%x\n", start, end)); - /* - * Now that we know the region is free, release it and hand it - * out piece by piece. - */ - bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); - for (tmp = 0; tmp < count; tmp++) { - if (barlist[tmp]->res == NULL && - barlist[tmp]->type == SYS_RES_MEMORY && - dinfo->mprefetchable & BARBIT(barlist[tmp]->rid)) { - barlist[tmp]->res = bus_alloc_resource(cbdev, - barlist[tmp]->type, - &barlist[tmp]->rid, start, end, - barlist[tmp]->count, - rman_make_alignment_flags( - barlist[tmp]->count)); - if (barlist[tmp]->res == NULL) { - mem_nsize += barlist[tmp]->count; - dinfo->mprefetchable &= - ~BARBIT(barlist[tmp]->rid); - DEVPRINTF((cbdev, "Cannot pre-allocate " - "prefetchable memory, will try as " - "non-prefetchable.\n")); - } else { - barlist[tmp]->start = - rman_get_start(barlist[tmp]->res); - barlist[tmp]->end = - rman_get_end(barlist[tmp]->res); - pci_write_config(child, - barlist[tmp]->rid, - barlist[tmp]->start, 4); - DEVPRINTF((cbdev, "Prefetchable memory " - "rid=%x at %lx-%lx\n", - barlist[tmp]->rid, - barlist[tmp]->start, - barlist[tmp]->end)); - } - } - } - } - - /* Allocate non-prefetchable memory */ - flags = 0; - for (tmp = 0; tmp < count; tmp++) { - if (barlist[tmp]->res == NULL && - barlist[tmp]->type == SYS_RES_MEMORY) { - flags = rman_make_alignment_flags(barlist[tmp]->count); - break; - } - } - if (flags > 0) { /* If any non-prefetchable memory is requested... */ - /* - * First we allocate one big space for all resources of this - * type. We do this because our parent, pccbb, needs to open - * a window to forward all addresses within the window, and - * it would be best if nobody else has resources allocated - * within the window. - * (XXX: Perhaps there might be a better way to do this?) - */ - rid = 0; - res = bus_alloc_resource(cbdev, SYS_RES_MEMORY, &rid, 0, - ((~dinfo->mprefetchable) & dinfo->mbelow1mb)?0xFFFFF:~0UL, - mem_nsize, flags); - start = rman_get_start(res); - end = rman_get_end(res); - DEVPRINTF((cbdev, "Non-prefetchable memory at %x-%x\n", - start, end)); - /* - * Now that we know the region is free, release it and hand it - * out piece by piece. - */ - bus_release_resource(cbdev, SYS_RES_MEMORY, rid, res); - for (tmp = 0; tmp < count; tmp++) { - if (barlist[tmp]->res == NULL && - barlist[tmp]->type == SYS_RES_MEMORY) { - barlist[tmp]->res = bus_alloc_resource(cbdev, - barlist[tmp]->type, &barlist[tmp]->rid, - start, end, barlist[tmp]->count, - rman_make_alignment_flags( - barlist[tmp]->count)); - if (barlist[tmp]->res == NULL) { - DEVPRINTF((cbdev, "Cannot pre-allocate " - "memory for cardbus device\n")); - kfree(barlist, M_DEVBUF); - return (ENOMEM); - } - barlist[tmp]->start = - rman_get_start(barlist[tmp]->res); - barlist[tmp]->end = rman_get_end( - barlist[tmp]->res); - pci_write_config(child, barlist[tmp]->rid, - barlist[tmp]->start, 4); - DEVPRINTF((cbdev, "Non-prefetchable memory " - "rid=%x at %lx-%lx (%lx)\n", - barlist[tmp]->rid, barlist[tmp]->start, - barlist[tmp]->end, barlist[tmp]->count)); - } - } - } - - /* Allocate IO ports */ - flags = 0; - for (tmp = 0; tmp < count; tmp++) { - if (barlist[tmp]->res == NULL && - barlist[tmp]->type == SYS_RES_IOPORT) { - flags = rman_make_alignment_flags(barlist[tmp]->count); - break; - } - } - if (flags > 0) { /* If any IO port is requested... */ - /* - * First we allocate one big space for all resources of this - * type. We do this because our parent, pccbb, needs to open - * a window to forward all addresses within the window, and - * it would be best if nobody else has resources allocated - * within the window. - * (XXX: Perhaps there might be a better way to do this?) - */ - rid = 0; - res = bus_alloc_resource(cbdev, SYS_RES_IOPORT, &rid, 0, - (dinfo->ibelow1mb)?0xFFFFF:~0UL, io_size, flags); - start = rman_get_start(res); - end = rman_get_end(res); - DEVPRINTF((cbdev, "IO port at %x-%x\n", start, end)); - /* - * Now that we know the region is free, release it and hand it - * out piece by piece. - */ - bus_release_resource(cbdev, SYS_RES_IOPORT, rid, res); - for (tmp = 0; tmp < count; tmp++) { - if (barlist[tmp]->res == NULL && - barlist[tmp]->type == SYS_RES_IOPORT) { - barlist[tmp]->res = bus_alloc_resource(cbdev, - barlist[tmp]->type, &barlist[tmp]->rid, - start, end, barlist[tmp]->count, - rman_make_alignment_flags( - barlist[tmp]->count)); - if (barlist[tmp]->res == NULL) { - DEVPRINTF((cbdev, "Cannot pre-allocate " - "IO port for cardbus device\n")); - kfree(barlist, M_DEVBUF); - return (ENOMEM); - } - barlist[tmp]->start = - rman_get_start(barlist[tmp]->res); - barlist[tmp]->end = - rman_get_end(barlist[tmp]->res); - pci_write_config(child, barlist[tmp]->rid, - barlist[tmp]->start, 4); - DEVPRINTF((cbdev, "IO port rid=%x at %lx-%lx\n", - barlist[tmp]->rid, barlist[tmp]->start, - barlist[tmp]->end)); - } - } - } - - /* Allocate IRQ */ - rid = 0; - res = bus_alloc_resource(cbdev, SYS_RES_IRQ, &rid, 0, ~0UL, 1, - RF_SHAREABLE); - resource_list_add(&dinfo->pci.resources, SYS_RES_IRQ, rid, - rman_get_start(res), rman_get_end(res), 1); - rle = resource_list_find(&dinfo->pci.resources, SYS_RES_IRQ, rid); - rle->res = res; - dinfo->pci.cfg.intline = rman_get_start(res); - pci_write_config(child, PCIR_INTLINE, rman_get_start(res), 1); - - kfree(barlist, M_DEVBUF); - return (0); -} - -/* - * Adding a memory/io resource (sans CIS) - */ - -static void -cardbus_add_map(device_t cbdev, device_t child, int reg) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - struct resource_list_entry *rle; - u_int32_t size; - u_int32_t testval; - int type; - - SLIST_FOREACH(rle, &dinfo->pci.resources, link) { - if (rle->rid == reg) - return; - } - - if (reg == CARDBUS_ROM_REG) - testval = CARDBUS_ROM_ADDRMASK; - else - testval = ~0; - - pci_write_config(child, reg, testval, 4); - testval = pci_read_config(child, reg, 4); - - if (testval == ~0 || testval == 0) - return; - - if ((testval & 1) == 0) - type = SYS_RES_MEMORY; - else - type = SYS_RES_IOPORT; - - size = CARDBUS_MAPREG_MEM_SIZE(testval); - device_printf(cbdev, "Resource not specified in CIS: id=%x, size=%x\n", - reg, size); - resource_list_add(&dinfo->pci.resources, type, reg, 0UL, ~0UL, size); -} - -static void -cardbus_pickup_maps(device_t cbdev, device_t child) -{ - struct cardbus_devinfo *dinfo = device_get_ivars(child); - struct cardbus_quirk *q; - int reg; - - /* - * Try to pick up any resources that was not specified in CIS. - * Some devices (eg, 3c656) does not list all resources required by - * the driver in its CIS. - * XXX: should we do this or use quirks? - */ - for (reg = 0; reg < dinfo->pci.cfg.nummaps; reg++) { - cardbus_add_map(cbdev, child, PCIR_MAPS + reg * 4); - } - - for (q = &cardbus_quirks[0]; q->devid; q++) { - if (q->devid == ((dinfo->pci.cfg.device << 16) | dinfo->pci.cfg.vendor) - && q->type == CARDBUS_QUIRK_MAP_REG) { - cardbus_add_map(cbdev, child, q->arg1); - } - } -} - -int -cardbus_cis_read(device_t cbdev, device_t child, u_int8_t id, - struct cis_tupleinfo **buff, int *nret) -{ - struct tuple_callbacks cisread_callbacks[] = { - MAKETUPLE(NULL, nothing), - /* first entry will be overwritten */ - MAKETUPLE(NULL, nothing), - MAKETUPLE(DEVICE, nothing), - MAKETUPLE(LONG_LINK_CB, unhandled), - MAKETUPLE(INDIRECT, unhandled), - MAKETUPLE(CONFIG_CB, nothing), - MAKETUPLE(CFTABLE_ENTRY_CB, nothing), - MAKETUPLE(LONGLINK_MFC, unhandled), - MAKETUPLE(BAR, nothing), - MAKETUPLE(PWR_MGMNT, nothing), - MAKETUPLE(EXTDEVICE, nothing), - MAKETUPLE(CHECKSUM, nothing), - MAKETUPLE(LONGLINK_A, unhandled), - MAKETUPLE(LONGLINK_C, unhandled), - MAKETUPLE(LINKTARGET, nothing), - MAKETUPLE(NO_LINK, nothing), - MAKETUPLE(VERS_1, nothing), - MAKETUPLE(ALTSTR, nothing), - MAKETUPLE(DEVICE_A, nothing), - MAKETUPLE(JEDEC_C, nothing), - MAKETUPLE(JEDEC_A, nothing), - MAKETUPLE(CONFIG, nothing), - MAKETUPLE(CFTABLE_ENTRY, nothing), - MAKETUPLE(DEVICE_OC, nothing), - MAKETUPLE(DEVICE_OA, nothing), - MAKETUPLE(DEVICE_GEO, nothing), - MAKETUPLE(DEVICE_GEO_A, nothing), - MAKETUPLE(MANFID, nothing), - MAKETUPLE(FUNCID, nothing), - MAKETUPLE(FUNCE, nothing), - MAKETUPLE(SWIL, nothing), - MAKETUPLE(VERS_2, nothing), - MAKETUPLE(FORMAT, nothing), - MAKETUPLE(GEOMETRY, nothing), - MAKETUPLE(BYTEORDER, nothing), - MAKETUPLE(DATE, nothing), - MAKETUPLE(BATTERY, nothing), - MAKETUPLE(ORG, nothing), - MAKETUPLE(END, end), - MAKETUPLE(GENERIC, nothing), - }; - int ret; - - cisread_callbacks[0].id = id; - cisread_callbacks[0].name = "COPY"; - cisread_callbacks[0].func = decode_tuple_copy; - ncisread_buf = 0; - cisread_buf = NULL; - ret = cardbus_parse_cis(cbdev, child, cisread_callbacks); - - *buff = cisread_buf; - *nret = ncisread_buf; - return (ret); -} - -void -cardbus_cis_free(device_t cbdev, struct cis_tupleinfo *buff, int *nret) -{ - int i; - for (i = 0; i < *nret; i++) - kfree(buff[i].data, M_DEVBUF); - if (*nret > 0) - kfree(buff, M_DEVBUF); -} - int cardbus_do_cis(device_t cbdev, device_t child) { int ret; struct tuple_callbacks init_callbacks[] = { - MAKETUPLE(NULL, generic), - MAKETUPLE(DEVICE, generic), - MAKETUPLE(LONG_LINK_CB, unhandled), + MAKETUPLE(LONGLINK_CB, unhandled), MAKETUPLE(INDIRECT, unhandled), - MAKETUPLE(CONFIG_CB, generic), - MAKETUPLE(CFTABLE_ENTRY_CB, generic), MAKETUPLE(LONGLINK_MFC, unhandled), MAKETUPLE(BAR, bar), - MAKETUPLE(PWR_MGMNT, generic), - MAKETUPLE(EXTDEVICE, generic), - MAKETUPLE(CHECKSUM, generic), MAKETUPLE(LONGLINK_A, unhandled), MAKETUPLE(LONGLINK_C, unhandled), MAKETUPLE(LINKTARGET, linktarget), - MAKETUPLE(NO_LINK, generic), MAKETUPLE(VERS_1, vers_1), - MAKETUPLE(ALTSTR, generic), - MAKETUPLE(DEVICE_A, generic), - MAKETUPLE(JEDEC_C, generic), - MAKETUPLE(JEDEC_A, generic), - MAKETUPLE(CONFIG, generic), - MAKETUPLE(CFTABLE_ENTRY, generic), - MAKETUPLE(DEVICE_OC, generic), - MAKETUPLE(DEVICE_OA, generic), - MAKETUPLE(DEVICE_GEO, generic), - MAKETUPLE(DEVICE_GEO_A, generic), MAKETUPLE(MANFID, manfid), MAKETUPLE(FUNCID, funcid), MAKETUPLE(FUNCE, funce), - MAKETUPLE(SWIL, generic), - MAKETUPLE(VERS_2, generic), - MAKETUPLE(FORMAT, generic), - MAKETUPLE(GEOMETRY, generic), - MAKETUPLE(BYTEORDER, generic), - MAKETUPLE(DATE, generic), - MAKETUPLE(BATTERY, generic), - MAKETUPLE(ORG, generic), MAKETUPLE(END, end), MAKETUPLE(GENERIC, generic), }; @@ -1105,6 +717,5 @@ cardbus_do_cis(device_t cbdev, device_t child) ret = cardbus_parse_cis(cbdev, child, init_callbacks); if (ret < 0) return (ret); - cardbus_pickup_maps(cbdev, child); - return (cardbus_alloc_resources(cbdev, child)); + return 0; } diff --git a/sys/dev/pccard/cardbus/cardbus_cis.h b/sys/dev/pccard/cardbus/cardbus_cis.h index 479fb7168c..f16e969947 100644 --- a/sys/dev/pccard/cardbus/cardbus_cis.h +++ b/sys/dev/pccard/cardbus/cardbus_cis.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2000,2001 Jonathan Chen. * All rights reserved. * @@ -6,18 +6,16 @@ * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -25,67 +23,19 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.h,v 1.7 2002/11/27 06:56:29 imp Exp $ - * $DragonFly: src/sys/dev/pccard/cardbus/cardbus_cis.h,v 1.1 2004/02/10 07:55:47 joerg Exp $ + * $FreeBSD: src/sys/dev/cardbus/cardbus_cis.h,v 1.13 2005/02/06 21:03:13 imp Exp $ + * $DragonFly: src/sys/dev/pccard/cardbus/cardbus_cis.h,v 1.2 2007/07/05 12:08:54 sephe Exp $ */ /* * Cardbus CIS definitions */ +int cardbus_do_cis(device_t, device_t); struct cis_tupleinfo; -int cardbus_do_cis(device_t, device_t); -int cardbus_cis_read(device_t, device_t, u_int8_t, struct cis_tupleinfo**, - int*); -void cardbus_cis_free(device_t, struct cis_tupleinfo*, int*); - #define MAXTUPLESIZE 0x400 -/* CIS TUPLES */ - -#define CISTPL_NULL 0x00 -#define CISTPL_DEVICE 0x01 -#define CISTPL_LONG_LINK_CB 0x02 -#define CISTPL_INDIRECT 0x03 -#define CISTPL_CONFIG_CB 0x04 -#define CISTPL_CFTABLE_ENTRY_CB 0x05 -#define CISTPL_LONGLINK_MFC 0x06 -#define CISTPL_BAR 0x07 -#define CISTPL_PWR_MGMNT 0x08 -#define CISTPL_EXTDEVICE 0x09 -#define CISTPL_CHECKSUM 0x10 -#define CISTPL_LONGLINK_A 0x11 -#define CISTPL_LONGLINK_C 0x12 -#define CISTPL_LINKTARGET 0x13 -#define CISTPL_NO_LINK 0x14 -#define CISTPL_VERS_1 0x15 -#define CISTPL_ALTSTR 0x16 -#define CISTPL_DEVICE_A 0x17 -#define CISTPL_JEDEC_C 0x18 -#define CISTPL_JEDEC_A 0x19 -#define CISTPL_CONFIG 0x1A -#define CISTPL_CFTABLE_ENTRY 0x1B -#define CISTPL_DEVICE_OC 0x1C -#define CISTPL_DEVICE_OA 0x1D -#define CISTPL_DEVICE_GEO 0x1E -#define CISTPL_DEVICE_GEO_A 0x1F -#define CISTPL_MANFID 0x20 -#define CISTPL_FUNCID 0x21 -#define CISTPL_FUNCE 0x22 -#define CISTPL_SWIL 0x23 -#define CISTPL_VERS_2 0x40 -#define CISTPL_FORMAT 0x41 -#define CISTPL_GEOMETRY 0x42 -#define CISTPL_BYTEORDER 0x43 -#define CISTPL_DATE 0x44 -#define CISTPL_BATTERY 0x45 -#define CISTPL_ORG 0x46 -#define CISTPL_CUSTOMSTART 0x80 -#define CISTPL_END 0xFF - -#define CISTPL_GENERIC -1 /* catchall */ - /* BAR */ #define TPL_BAR_REG_ASI_MASK 0x07 #define TPL_BAR_REG_AS 0x10 @@ -93,23 +43,3 @@ void cardbus_cis_free(device_t, struct cis_tupleinfo*, int*); #define TPL_BAR_REG_PREFETCHABLE_CACHEABLE 0x40 #define TPL_BAR_REG_PREFETCHABLE 0x60 #define TPL_BAR_REG_BELOW1MB 0x80 - -/* CISTPL_FUNC */ -#define TPL_FUNC_MF 0 /* multi function tuple */ -#define TPL_FUNC_MEM 1 /* memory */ -#define TPL_FUNC_SERIAL 2 /* serial, including modem and fax */ -#define TPL_FUNC_PARALLEL 3 /* parallel, including printer and SCSI */ -#define TPL_FUNC_DISK 4 /* Disk */ -#define TPL_FUNC_VIDEO 5 /* Video Adaptor */ -#define TPL_FUNC_LAN 6 /* LAN Adaptor */ -#define TPL_FUNC_AIMS 7 /* Auto Inclement Mass Strages */ - -/* TPL_FUNC_LAN */ -#define TPL_FUNCE_LAN_TECH 1 /* technology */ -#define TPL_FUNCE_LAN_SPEED 2 /* speed */ -#define TPL_FUNCE_LAN_MEDIA 3 /* which media do you use? */ -#define TPL_FUNCE_LAN_NID 4 /* node id (address) */ -#define TPL_FUNCE_LAN_CONN 5 /* connector type (shape) */ - -/* TPL_FUNC_SERIAL */ -#define TPL_FUNCE_SER_UART 0 /* UART type */ diff --git a/sys/dev/pccard/cardbus/cardbusreg.h b/sys/dev/pccard/cardbus/cardbusreg.h index 755a5d3066..d0bb2d5d3b 100644 --- a/sys/dev/pccard/cardbus/cardbusreg.h +++ b/sys/dev/pccard/cardbus/cardbusreg.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2000,2001 Jonathan Chen. * All rights reserved. * @@ -6,18 +6,16 @@ * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -25,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/cardbus/cardbusreg.h,v 1.6 2002/10/07 22:58:24 imp Exp $ - * $DragonFly: src/sys/dev/pccard/cardbus/cardbusreg.h,v 1.1 2004/02/10 07:55:47 joerg Exp $ + * $FreeBSD: src/sys/dev/cardbus/cardbusreg.h,v 1.8 2005/01/13 19:12:10 imp Exp $ + * $DragonFly: src/sys/dev/pccard/cardbus/cardbusreg.h,v 1.2 2007/07/05 12:08:54 sephe Exp $ */ /* diff --git a/sys/dev/pccard/cardbus/cardbusvar.h b/sys/dev/pccard/cardbus/cardbusvar.h index e36910de2b..1187347df6 100644 --- a/sys/dev/pccard/cardbus/cardbusvar.h +++ b/sys/dev/pccard/cardbus/cardbusvar.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2000,2001 Jonathan Chen. * All rights reserved. * @@ -6,18 +6,16 @@ * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -25,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/cardbus/cardbusvar.h,v 1.7 2002/11/27 06:56:29 imp Exp $ - * $DragonFly: src/sys/dev/pccard/cardbus/cardbusvar.h,v 1.1 2004/02/10 07:55:47 joerg Exp $ + * $FreeBSD: src/sys/dev/cardbus/cardbusvar.h,v 1.11 2005/02/06 21:03:13 imp Exp $ + * $DragonFly: src/sys/dev/pccard/cardbus/cardbusvar.h,v 1.2 2007/07/05 12:08:54 sephe Exp $ */ /* @@ -34,24 +32,17 @@ */ struct cardbus_devinfo { struct pci_devinfo pci; - u_int8_t mprefetchable; /* bit mask of prefetchable BARs */ - u_int8_t mbelow1mb; /* bit mask of BARs which require below 1Mb */ - u_int8_t ibelow1mb; /* bit mask of BARs which require below 1Mb */ + uint8_t mprefetchable; /* bit mask of prefetchable BARs */ + uint8_t mbelow1mb; /* bit mask of BARs which require below 1Mb */ + uint8_t ibelow1mb; /* bit mask of BARs which require below 1Mb */ #define BARBIT(RID) (1<<(((RID)-CARDBUS_BASE0_REG)/4)) - u_int16_t mfrid; /* manufacturer id */ - u_int16_t prodid; /* product id */ + uint16_t mfrid; /* manufacturer id */ + uint16_t prodid; /* product id */ u_int funcid; /* function id */ union { struct { - u_int type; /* UART type */ - } sio; - struct { - u_int8_t nid[6]; /* MAC address */ - u_int8_t tech; /* technology */ - u_int8_t contype; /* connector type */ - u_int32_t speed[3]; /* available speeds */ - u_int8_t media[4]; /* media types */ + uint8_t nid[6]; /* MAC address */ } lan; } funce; - u_int32_t fepresent; /* bit mask of funce values present */ + uint32_t fepresent; /* bit mask of funce values present */ }; diff --git a/sys/dev/pccard/exca/exca.c b/sys/dev/pccard/exca/exca.c index 8efbea3575..81c5e4227a 100644 --- a/sys/dev/pccard/exca/exca.c +++ b/sys/dev/pccard/exca/exca.c @@ -1,8 +1,5 @@ -/* $FreeBSD: src/sys/dev/exca/exca.c,v 1.6 2002/10/07 06:18:50 imp Exp $ */ -/* $DragonFly: src/sys/dev/pccard/exca/exca.c,v 1.3 2006/12/22 23:26:22 swildner Exp $ */ - -/* - * Copyright (c) 2002 M Warner Losh. All rights reserved. +/*- + * Copyright (c) 2002-2005 M Warner Losh. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -53,6 +50,9 @@ * 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. + * + * $FreeBSD: src/sys/dev/exca/exca.c,v 1.19 2005/01/11 00:32:43 imp Exp $ + * $DragonFly: src/sys/dev/pccard/exca/exca.c,v 1.4 2007/07/05 12:08:54 sephe Exp $ */ #include @@ -62,7 +62,9 @@ #include #include #include +#include #include + #include #include @@ -80,6 +82,32 @@ #define DPRINTF(fmt, args...) #endif +#if 0 +static const char *chip_names[] = +{ + "CardBus socket", + "Intel i82365SL-A/B or clone", + "Intel i82365sl-DF step", + "VLSI chip", + "Cirrus Logic PD6710", + "Cirrus logic PD6722", + "Cirrus Logic PD6729", + "Vadem 365", + "Vadem 465", + "Vadem 468", + "Vadem 469", + "Ricoh RF5C296", + "Ricoh RF5C396", + "IBM clone", + "IBM KING PCMCIA Controller" +}; +#endif + +static exca_getb_fn exca_mem_getb; +static exca_putb_fn exca_mem_putb; +static exca_getb_fn exca_io_getb; +static exca_putb_fn exca_io_putb; + /* memory */ #define EXCA_MEMINFO(NUM) { \ @@ -111,6 +139,32 @@ static struct mem_map_index_st { }; #undef EXCA_MEMINFO +static uint8_t +exca_mem_getb(struct exca_softc *sc, int reg) +{ + return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg)); +} + +static void +exca_mem_putb(struct exca_softc *sc, int reg, uint8_t val) +{ + bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val); +} + +static uint8_t +exca_io_getb(struct exca_softc *sc, int reg) +{ + bus_space_write_1(sc->bst, sc->bsh, EXCA_REG_INDEX, reg + sc->offset); + return (bus_space_read_1(sc->bst, sc->bsh, EXCA_REG_DATA)); +} + +static void +exca_io_putb(struct exca_softc *sc, int reg, uint8_t val) +{ + bus_space_write_1(sc->bst, sc->bsh, EXCA_REG_INDEX, reg + sc->offset); + bus_space_write_1(sc->bst, sc->bsh, EXCA_REG_DATA, val); +} + /* * Helper function. This will map the requested memory slot. We setup the * map before we call this function. This is used to initially force the @@ -122,54 +176,61 @@ exca_do_mem_map(struct exca_softc *sc, int win) { struct mem_map_index_st *map; struct pccard_mem_handle *mem; + uint32_t offset; map = &mem_map_index[win]; mem = &sc->mem[win]; - exca_write(sc, map->sysmem_start_lsb, + offset = ((mem->cardaddr >> EXCA_CARDMEM_ADDRX_SHIFT) - + (mem->addr >> EXCA_SYSMEM_ADDRX_SHIFT)) & 0x3fff; + exca_putb(sc, map->sysmem_start_lsb, (mem->addr >> EXCA_SYSMEM_ADDRX_SHIFT) & 0xff); - exca_write(sc, map->sysmem_start_msb, + exca_putb(sc, map->sysmem_start_msb, ((mem->addr >> (EXCA_SYSMEM_ADDRX_SHIFT + 8)) & - EXCA_SYSMEM_ADDRX_START_MSB_ADDR_MASK) | 0x80); + EXCA_SYSMEM_ADDRX_START_MSB_ADDR_MASK)); - exca_write(sc, map->sysmem_stop_lsb, + exca_putb(sc, map->sysmem_stop_lsb, ((mem->addr + mem->realsize - 1) >> EXCA_SYSMEM_ADDRX_SHIFT) & 0xff); - exca_write(sc, map->sysmem_stop_msb, + exca_putb(sc, map->sysmem_stop_msb, (((mem->addr + mem->realsize - 1) >> (EXCA_SYSMEM_ADDRX_SHIFT + 8)) & EXCA_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) | EXCA_SYSMEM_ADDRX_STOP_MSB_WAIT2); - exca_write(sc, map->sysmem_win, + exca_putb(sc, map->sysmem_win, (mem->addr >> EXCA_MEMREG_WIN_SHIFT) & 0xff); - exca_write(sc, map->cardmem_lsb, - (mem->offset >> EXCA_CARDMEM_ADDRX_SHIFT) & 0xff); - exca_write(sc, map->cardmem_msb, - ((mem->offset >> (EXCA_CARDMEM_ADDRX_SHIFT + 8)) & + exca_putb(sc, map->cardmem_lsb, offset & 0xff); + exca_putb(sc, map->cardmem_msb, (((offset >> 8) & 0xff) & EXCA_CARDMEM_ADDRX_MSB_ADDR_MASK) | - ((mem->kind == PCCARD_MEM_ATTR) ? + ((mem->kind == PCCARD_A_MEM_ATTR) ? EXCA_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0)); - exca_setb(sc, EXCA_ADDRWIN_ENABLE, EXCA_ADDRWIN_ENABLE_MEMCS16 | - map->memenable); +#ifdef EXCA_DEBUG + if (mem->kind == PCCARD_A_MEM_ATTR) + kprintf("attribtue memory\n"); + else + kprintf("common memory\n"); +#endif + exca_setb(sc, EXCA_ADDRWIN_ENABLE, map->memenable | + EXCA_ADDRWIN_ENABLE_MEMCS16); DELAY(100); #ifdef EXCA_DEBUG { int r1, r2, r3, r4, r5, r6, r7; - r1 = exca_read(sc, map->sysmem_start_msb); - r2 = exca_read(sc, map->sysmem_start_lsb); - r3 = exca_read(sc, map->sysmem_stop_msb); - r4 = exca_read(sc, map->sysmem_stop_lsb); - r5 = exca_read(sc, map->cardmem_msb); - r6 = exca_read(sc, map->cardmem_lsb); - r7 = exca_read(sc, map->sysmem_win); - kprintf("exca_do_mem_map window %d: %02x%02x %02x%02x " - "%02x%02x %02x (%08x+%08x.%08x*%08lx)\n", + r1 = exca_getb(sc, map->sysmem_start_msb); + r2 = exca_getb(sc, map->sysmem_start_lsb); + r3 = exca_getb(sc, map->sysmem_stop_msb); + r4 = exca_getb(sc, map->sysmem_stop_lsb); + r5 = exca_getb(sc, map->cardmem_msb); + r6 = exca_getb(sc, map->cardmem_lsb); + r7 = exca_getb(sc, map->sysmem_win); + kprintf("exca_do_mem_map win %d: %02x%02x %02x%02x " + "%02x%02x %02x (%08x+%06x.%06x*%06x)\n", win, r1, r2, r3, r4, r5, r6, r7, mem->addr, mem->size, mem->realsize, - mem->offset); + mem->cardaddr); } #endif } @@ -195,7 +256,7 @@ exca_mem_map(struct exca_softc *sc, int kind, struct resource *res) } if (win >= EXCA_MEM_WINS) return (1); - if (((rman_get_start(res) >> EXCA_CARDMEM_ADDRX_SHIFT) & 0xff) != 0 && + if (((rman_get_start(res) >> EXCA_MEMREG_WIN_SHIFT) & 0xff) != 0 && (sc->flags & EXCA_HAS_MEMREG_WIN) == 0) { device_printf(sc->dev, "Does not support mapping above 24M."); return (1); @@ -209,11 +270,9 @@ exca_mem_map(struct exca_softc *sc, int kind, struct resource *res) sc->mem[win].realsize = sc->mem[win].size + EXCA_MEM_PAGESIZE - 1; sc->mem[win].realsize = sc->mem[win].realsize - (sc->mem[win].realsize % EXCA_MEM_PAGESIZE); - sc->mem[win].offset = (long)(sc->mem[win].addr); sc->mem[win].kind = kind; - DPRINTF("exca_mem_map window %d bus %x+%x+%lx card addr %x\n", - win, sc->mem[win].addr, sc->mem[win].size, - sc->mem[win].offset, sc->mem[win].cardaddr); + DPRINTF("exca_mem_map window %d bus %x+%x card addr %x\n", + win, sc->mem[win].addr, sc->mem[win].size, sc->mem[win].cardaddr); exca_do_mem_map(sc, win); return (0); @@ -304,12 +363,7 @@ exca_mem_unmap_res(struct exca_softc *sc, struct resource *res) * Set the offset of the memory. We use this for reading the CIS and * frobbing the pccard's pccard registers (POR, etc). Some drivers * need to access this functionality as well, since they have receive - * buffers defined in the attribute memory. Thankfully, these cards - * are few and fare between. Some cards also have common memory that - * is large and only map a small portion of it at a time (but these cards - * are rare, the more common case being to have just a small amount - * of common memory that the driver needs to bcopy data from in order to - * get at it. + * buffers defined in the attribute memory. */ int exca_mem_set_offset(struct exca_softc *sc, struct resource *res, @@ -324,16 +378,14 @@ exca_mem_set_offset(struct exca_softc *sc, struct resource *res, "set_memory_offset: specified resource not active\n"); return (ENOENT); } - sc->mem[win].cardaddr = cardaddr; + sc->mem[win].cardaddr = cardaddr & ~(EXCA_MEM_PAGESIZE - 1); delta = cardaddr % EXCA_MEM_PAGESIZE; if (deltap) *deltap = delta; - cardaddr -= delta; sc->mem[win].realsize = sc->mem[win].size + delta + EXCA_MEM_PAGESIZE - 1; sc->mem[win].realsize = sc->mem[win].realsize - (sc->mem[win].realsize % EXCA_MEM_PAGESIZE); - sc->mem[win].offset = cardaddr - sc->mem[win].addr; exca_do_mem_map(sc, win); return (0); } @@ -383,11 +435,11 @@ exca_do_io_map(struct exca_softc *sc, int win) map = &io_map_index[win]; io = &sc->io[win]; - exca_write(sc, map->start_lsb, io->addr & 0xff); - exca_write(sc, map->start_msb, (io->addr >> 8) & 0xff); + exca_putb(sc, map->start_lsb, io->addr & 0xff); + exca_putb(sc, map->start_msb, (io->addr >> 8) & 0xff); - exca_write(sc, map->stop_lsb, (io->addr + io->size - 1) & 0xff); - exca_write(sc, map->stop_msb, ((io->addr + io->size - 1) >> 8) & 0xff); + exca_putb(sc, map->stop_lsb, (io->addr + io->size - 1) & 0xff); + exca_putb(sc, map->stop_msb, ((io->addr + io->size - 1) >> 8) & 0xff); exca_clrb(sc, EXCA_IOCTL, map->ioctlmask); exca_setb(sc, EXCA_IOCTL, map->ioctlbits[io->width]); @@ -396,10 +448,10 @@ exca_do_io_map(struct exca_softc *sc, int win) #ifdef EXCA_DEBUG { int r1, r2, r3, r4; - r1 = exca_read(sc, map->start_msb); - r2 = exca_read(sc, map->start_lsb); - r3 = exca_read(sc, map->stop_msb); - r4 = exca_read(sc, map->stop_lsb); + r1 = exca_getb(sc, map->start_msb); + r2 = exca_getb(sc, map->start_lsb); + r3 = exca_getb(sc, map->stop_msb); + r4 = exca_getb(sc, map->stop_lsb); DPRINTF("exca_do_io_map window %d: %02x%02x %02x%02x " "(%08x+%08x)\n", win, r1, r2, r3, r4, io->addr, io->size); @@ -496,14 +548,14 @@ exca_wait_ready(struct exca_softc *sc) { int i; DEVPRINTF(sc->dev, "exca_wait_ready: status 0x%02x\n", - exca_read(sc, EXCA_IF_STATUS)); + exca_getb(sc, EXCA_IF_STATUS)); for (i = 0; i < 10000; i++) { - if (exca_read(sc, EXCA_IF_STATUS) & EXCA_IF_STATUS_READY) + if (exca_getb(sc, EXCA_IF_STATUS) & EXCA_IF_STATUS_READY) return; DELAY(500); } device_printf(sc->dev, "ready never happened, status = %02x\n", - exca_read(sc, EXCA_IF_STATUS)); + exca_getb(sc, EXCA_IF_STATUS)); } /* @@ -522,13 +574,12 @@ exca_wait_ready(struct exca_softc *sc) void exca_reset(struct exca_softc *sc, device_t child) { - int cardtype; int win; /* enable socket i/o */ exca_setb(sc, EXCA_PWRCTL, EXCA_PWRCTL_OE); - exca_write(sc, EXCA_INTR, EXCA_INTR_ENABLE); + exca_putb(sc, EXCA_INTR, EXCA_INTR_ENABLE); /* hold reset for 30ms */ DELAY(30*1000); /* clear the reset flag */ @@ -539,13 +590,10 @@ exca_reset(struct exca_softc *sc, device_t child) exca_wait_ready(sc); /* disable all address windows */ - exca_write(sc, EXCA_ADDRWIN_ENABLE, 0); + exca_putb(sc, EXCA_ADDRWIN_ENABLE, 0); - CARD_GET_TYPE(child, &cardtype); - exca_setb(sc, EXCA_INTR, (cardtype == PCCARD_IFTYPE_IO) ? - EXCA_INTR_CARDTYPE_IO : EXCA_INTR_CARDTYPE_MEM); - DEVPRINTF(sc->dev, "card type is %s\n", - (cardtype == PCCARD_IFTYPE_IO) ? "io" : "mem"); + exca_setb(sc, EXCA_INTR, EXCA_INTR_CARDTYPE_IO); + DEVPRINTF(sc->dev, "card type is io\n"); /* reinstall all the memory and io mappings */ for (win = 0; win < EXCA_MEM_WINS; ++win) @@ -570,6 +618,117 @@ exca_init(struct exca_softc *sc, device_t dev, sc->bsh = bsh; sc->offset = offset; sc->flags = 0; + sc->getb = exca_mem_getb; + sc->putb = exca_mem_putb; +} + +/* + * Is this socket valid? + */ +static int +exca_valid_slot(struct exca_softc *exca) +{ + uint8_t c; + + /* Assume the worst */ + exca->chipset = EXCA_BOGUS; + + /* + * see if there's a PCMCIA controller here + * Intel PCMCIA controllers use 0x82 and 0x83 + * IBM clone chips use 0x88 and 0x89, apparently + */ + c = exca_getb(exca, EXCA_IDENT); + if ((c & EXCA_IDENT_IFTYPE_MASK) != EXCA_IDENT_IFTYPE_MEM_AND_IO) + return (0); + if ((c & EXCA_IDENT_ZERO) != 0) + return (0); + switch (c & EXCA_IDENT_REV_MASK) { + /* + * 82365 or clones. + */ + case EXCA_IDENT_REV_I82365SLR0: + case EXCA_IDENT_REV_I82365SLR1: + exca->chipset = EXCA_I82365; + /* + * Check for Vadem chips by unlocking their extra + * registers and looking for valid ID. Bit 3 in + * the ID register is normally 0, except when + * EXCA_VADEMREV is set. Other bridges appear + * to ignore this frobbing. + */ + bus_space_write_1(exca->bst, exca->bsh, EXCA_REG_INDEX, + EXCA_VADEM_COOKIE1); + bus_space_write_1(exca->bst, exca->bsh, EXCA_REG_INDEX, + EXCA_VADEM_COOKIE2); + exca_setb(exca, EXCA_VADEM_VMISC, EXCA_VADEM_REV); + c = exca_getb(exca, EXCA_IDENT); + if (c & 0x08) { + switch (c & 7) { + case 1: + exca->chipset = EXCA_VG365; + break; + case 2: + exca->chipset = EXCA_VG465; + break; + case 3: + exca->chipset = EXCA_VG468; + break; + default: + exca->chipset = EXCA_VG469; + break; + } + exca_clrb(exca, EXCA_VADEM_VMISC, EXCA_VADEM_REV); + break; + } + /* + * Check for RICOH RF5C[23]96 PCMCIA Controller + */ + c = exca_getb(exca, EXCA_RICOH_ID); + if (c == EXCA_RID_396) { + exca->chipset = EXCA_RF5C396; + break; + } else if (c == EXCA_RID_296) { + exca->chipset = EXCA_RF5C296; + break; + } + /* + * Check for Cirrus logic chips. + */ + exca_putb(exca, EXCA_CIRRUS_CHIP_INFO, 0); + c = exca_getb(exca, EXCA_CIRRUS_CHIP_INFO); + if ((c & EXCA_CIRRUS_CHIP_INFO_CHIP_ID) == + EXCA_CIRRUS_CHIP_INFO_CHIP_ID) { + c = exca_getb(exca, EXCA_CIRRUS_CHIP_INFO); + if ((c & EXCA_CIRRUS_CHIP_INFO_CHIP_ID) == 0) { + if (c & EXCA_CIRRUS_CHIP_INFO_SLOTS) + exca->chipset = EXCA_PD6722; + else + exca->chipset = EXCA_PD6710; + break; + } + } + break; + + case EXCA_IDENT_REV_I82365SLDF: + /* + * Intel i82365sl-DF step or maybe a vlsi 82c146 + * we detected the vlsi case earlier, so if the controller + * isn't set, we know it is a i82365sl step D. + */ + exca->chipset = EXCA_I82365SL_DF; + break; + case EXCA_IDENT_REV_IBM1: + case EXCA_IDENT_REV_IBM2: + exca->chipset = EXCA_IBM; + break; + case EXCA_IDENT_REV_IBM_KING: + exca->chipset = EXCA_IBM_KING; + break; + default: + return (0); + } + return (1); } /* @@ -577,49 +736,164 @@ exca_init(struct exca_softc *sc, device_t dev, * slots too while we're at it. But maybe that belongs to a separate * function. * - * Callers must charantee that there are at least EXCA_NSLOTS (4) in - * the array that they pass the address of the first element in the - * "exca" parameter. + * The caller must guarantee that at least EXCA_NSLOTS are present in exca. */ int -exca_probe_slots(device_t dev, struct exca_softc *exca) +exca_probe_slots(device_t dev, struct exca_softc *exca, bus_space_tag_t iot, + bus_space_handle_t ioh) { - int rid; - struct resource *res; int err; - bus_space_tag_t iot; - bus_space_handle_t ioh; int i; err = ENXIO; - rid = 0; - res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, EXCA_IOSIZE, - RF_ACTIVE); - if (res == NULL) - return (ENXIO); - iot = rman_get_bustag(res); - ioh = rman_get_bushandle(res); - for (i = 0; i < EXCA_NSLOTS; i++) { + for (i = 0; i < EXCA_NSLOTS; i++) { exca_init(&exca[i], dev, iot, ioh, i * EXCA_SOCKET_SIZE); - if (exca_is_pcic(&exca[i])) { + exca->getb = exca_io_getb; + exca->putb = exca_io_putb; + if (exca_valid_slot(&exca[i])) err = 0; - exca[i].flags |= EXCA_SOCKET_PRESENT; - } } - bus_release_resource(dev, SYS_RES_IOPORT, rid, res); return (err); } +void +exca_insert(struct exca_softc *exca) +{ + if (exca->pccarddev != NULL) { + if (CARD_ATTACH_CARD(exca->pccarddev) != 0) + device_printf(exca->dev, + "PC Card card activation failed\n"); + } else { + device_printf(exca->dev, + "PC Card inserted, but no pccard bus.\n"); + } +} + + +void +exca_removal(struct exca_softc *exca) +{ + if (exca->pccarddev != NULL) + CARD_DETACH_CARD(exca->pccarddev); +} + int -exca_is_pcic(struct exca_softc *sc) +exca_activate_resource(struct exca_softc *exca, device_t child, int type, + int rid, struct resource *res) { - /* XXX */ - return (0); + int err; + if (!(rman_get_flags(res) & RF_ACTIVE)) { /* not already activated */ + switch (type) { + case SYS_RES_IOPORT: + err = exca_io_map(exca, PCCARD_WIDTH_AUTO, res); + break; + case SYS_RES_MEMORY: + err = exca_mem_map(exca, PCCARD_A_MEM_COM, res); + break; + default: + err = 0; + break; + } + if (err) + return (err); + + } + return (BUS_ACTIVATE_RESOURCE(device_get_parent(exca->dev), child, + type, rid, res)); +} + +int +exca_deactivate_resource(struct exca_softc *exca, device_t child, int type, + int rid, struct resource *res) +{ + if (rman_get_flags(res) & RF_ACTIVE) { /* if activated */ + switch (type) { + case SYS_RES_IOPORT: + if (exca_io_unmap_res(exca, res)) + return (ENOENT); + break; + case SYS_RES_MEMORY: + if (exca_mem_unmap_res(exca, res)) + return (ENOENT); + break; + } + } + return (BUS_DEACTIVATE_RESOURCE(device_get_parent(exca->dev), child, + type, rid, res)); } -static int exca_modevent(module_t mod, int cmd, void *arg) +#if 0 +static struct resource * +exca_alloc_resource(struct exca_softc *sc, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, uint flags) +{ + struct resource *res = NULL; + int tmp; + + switch (type) { + case SYS_RES_MEMORY: + if (start < cbb_start_mem) + start = cbb_start_mem; + if (end < start) + end = start; + flags = (flags & ~RF_ALIGNMENT_MASK) | + rman_make_alignment_flags(CBB_MEMALIGN); + break; + case SYS_RES_IOPORT: + if (start < cbb_start_16_io) + start = cbb_start_16_io; + if (end < start) + end = start; + break; + case SYS_RES_IRQ: + tmp = rman_get_start(sc->irq_res); + if (start > tmp || end < tmp || count != 1) { + device_printf(child, "requested interrupt %ld-%ld," + "count = %ld not supported by cbb\n", + start, end, count); + return (NULL); + } + flags |= RF_SHAREABLE; + start = end = rman_get_start(sc->irq_res); + break; + } + res = BUS_ALLOC_RESOURCE(up, child, type, rid, + start, end, count, flags & ~RF_ACTIVE); + if (res == NULL) + return (NULL); + cbb_insert_res(sc, res, type, *rid); + if (flags & RF_ACTIVE) { + if (bus_activate_resource(child, type, *rid, res) != 0) { + bus_release_resource(child, type, *rid, res); + return (NULL); + } + } + + return (res); +} + +static int +exca_release_resource(struct exca_softc *sc, device_t child, int type, + int rid, struct resource *res) +{ + int error; + + if (rman_get_flags(res) & RF_ACTIVE) { + error = bus_deactivate_resource(child, type, rid, res); + if (error != 0) + return (error); + } + cbb_remove_res(sc, res); + return (BUS_RELEASE_RESOURCE(device_get_parent(brdev), child, + type, rid, res)); +} +#endif + +static int +exca_modevent(module_t mod, int cmd, void *arg) { return 0; } + DEV_MODULE(exca, exca_modevent, NULL); MODULE_VERSION(exca, 1); diff --git a/sys/dev/pccard/exca/excareg.h b/sys/dev/pccard/exca/excareg.h index 36ef56e45e..390cdb1ef0 100644 --- a/sys/dev/pccard/exca/excareg.h +++ b/sys/dev/pccard/exca/excareg.h @@ -1,8 +1,8 @@ /* $NetBSD: i82365reg.h,v 1.3 1998/12/20 17:53:28 nathanw Exp $ */ -/* $FreeBSD: src/sys/dev/exca/excareg.h,v 1.2 2002/07/26 08:01:08 imp Exp $ */ -/* $DragonFly: src/sys/dev/pccard/exca/excareg.h,v 1.2 2005/06/27 02:27:10 swildner Exp $ */ +/* $FreeBSD: src/sys/dev/exca/excareg.h,v 1.5 2005/01/06 01:42:40 imp Exp $ */ +/* $DragonFly: src/sys/dev/pccard/exca/excareg.h,v 1.3 2007/07/05 12:08:54 sephe Exp $ */ -/* +/*- * Copyright (c) 2002 M Warner Losh. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -102,8 +102,12 @@ #define EXCA_IDENT_IFTYPE_RESERVED 0xC0 #define EXCA_IDENT_ZERO 0x30 #define EXCA_IDENT_REV_MASK 0x0F -#define EXCA_IDENT_REV_I82365SLR0 0x02 -#define EXCA_IDENT_REV_I82365SLR1 0x03 +#define EXCA_IDENT_REV_I82365SLR0 0x02 /* step a/b */ +#define EXCA_IDENT_REV_I82365SLR1 0x03 /* step c */ +#define EXCA_IDENT_REV_I82365SLDF 0x04 /* step df */ +#define EXCA_IDENT_REV_IBM1 0x08 /* ibm clone */ +#define EXCA_IDENT_REV_IBM2 0x09 /* ibm clone */ +#define EXCA_IDENT_REV_IBM_KING 0x0a /* ibm king */ #define EXCA_IF_STATUS 0x01 /* RO */ #define EXCA_IF_STATUS_GPI 0x80 /* General Purpose Input */ @@ -383,6 +387,22 @@ #define EXCA_CIRRUS_EXT_CONTROL_1 0x03 #define EXCA_CIRRUS_EXT_CONTROL_1_PCI_INTR_MASK 0x18 +#define EXCA_VADEM_VMISC 0x3a +#define EXCA_VADEM_REV 0x40 +#define EXCA_VADEM_COOKIE1 0x0E +#define EXCA_VADEM_COOKIE2 0x37 + +#define EXCA_RICOH_ID 0x3a +#define EXCA_RID_296 0x32 +#define EXCA_RID_396 0xb2 + +/* + * o2 micro specific registers + */ +#define EXCA_O2MICRO_CTRL_C 0x3a +#define EXCA_O2CC_IREQ_INTC 0x80 +#define EXCA_O2CC_STSCHG_INTC 0x20 + /* Plug and play */ #define EXCA_PNP_ACTIONTEC 0x1802A904 /* AEI0218 */ #define EXCA_PNP_IBM3765 0x65374d24 /* IBM3765 */ @@ -392,6 +412,10 @@ #define EXCA_PNP_82365_CARDBUS 0x030ED041 /* PNP0E03 */ #define EXCA_PNP_SCM_SWAPBOX 0x69046d4c /* SMC0469 */ +/* C-Bus PnP Definitions */ +#define EXCA_NEC_PC9801_102 0x9180a3b8 /* NEC8091 PC-9801-102 */ +#define EXCA_NEC_PC9821RA_E01 0x2181a3b8 /* NEC8121 PC-9821RA-E01 */ + /* * Mask of allowable interrupts. * @@ -404,8 +428,20 @@ * NT had a special device that would probe for conflicts early in the * boot process and formulate a mapping table. Maybe we should do * something similar. + * + * For NEC PC-98 machines, irq 3, 5, 6, 9, 10, 11, 12, 13 are allowed. + * These correspond to the C-BUS signals INT 0, 1, 2, 3, 41, 42, 5, 6 + * respectively. + * + * Hiroshi TSUKADA-san writes in FreeBSD98-testers that CBUS INT 2 + * (mapped to IRQ 6) is routed to the IRQ 7 pin of the pcic in pc98 + * cbus add-in cards. He has confirmed this routing with a visual + * inspection of his card or a VOM. */ - +#ifdef PC98 +#define EXCA_INT_MASK_ALLOWED 0x3E68 /* PC98 */ +#else #define EXCA_INT_MASK_ALLOWED 0xDEB8 /* AT */ +#endif #endif /* !_SYS_DEV_EXCA_EXCAREG_H */ diff --git a/sys/dev/pccard/exca/excavar.h b/sys/dev/pccard/exca/excavar.h index 144e2512ab..cd57b9bd3b 100644 --- a/sys/dev/pccard/exca/excavar.h +++ b/sys/dev/pccard/exca/excavar.h @@ -1,7 +1,7 @@ -/* $FreeBSD: src/sys/dev/exca/excavar.h,v 1.2 2002/07/26 08:01:08 imp Exp $ */ -/* $DragonFly: src/sys/dev/pccard/exca/excavar.h,v 1.1 2004/02/10 07:55:47 joerg Exp $ */ +/* $FreeBSD: src/sys/dev/exca/excavar.h,v 1.7 2005/01/06 01:42:40 imp Exp $ */ +/* $DragonFly: src/sys/dev/pccard/exca/excavar.h,v 1.2 2007/07/05 12:08:54 sephe Exp $ */ -/* +/*- * Copyright (c) 2002 M Warner Losh. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -62,6 +62,8 @@ * Structure to manage the ExCA part of the chip. */ struct exca_softc; +typedef uint8_t (exca_getb_fn)(struct exca_softc *, int); +typedef void (exca_putb_fn)(struct exca_softc *, int, uint8_t); struct exca_softc { @@ -75,11 +77,35 @@ struct exca_softc uint32_t flags; #define EXCA_SOCKET_PRESENT 0x00000001 #define EXCA_HAS_MEMREG_WIN 0x00000002 +#define EXCA_CARD_OK 0x00000004 +#define EXCA_EVENT 0x80000000 uint32_t offset; + int chipset; +#define EXCA_CARDBUS 0 +#define EXCA_I82365 1 /* Intel i82365SL-A/B or clone */ +#define EXCA_I82365SL_DF 2 /* Intel i82365sl-DF step */ +#define EXCA_VLSI 3 /* VLSI chip */ +#define EXCA_PD6710 4 /* Cirrus logic PD6710 */ +#define EXCA_PD6722 5 /* Cirrus logic PD6722 */ +#define EXCA_PD6729 6 /* Cirrus Logic PD6729 */ +#define EXCA_VG365 7 /* Vadem 365 */ +#define EXCA_VG465 8 /* Vadem 465 */ +#define EXCA_VG468 9 /* Vadem 468 */ +#define EXCA_VG469 10 /* Vadem 469 */ +#define EXCA_RF5C296 11 /* Ricoh RF5C296 */ +#define EXCA_RF5C396 12 /* Ricoh RF5C396 */ +#define EXCA_IBM 13 /* IBM clone */ +#define EXCA_IBM_KING 14 /* IBM KING PCMCIA Controller */ +#define EXCA_BOGUS -1 /* Invalid/not present/etc */ + exca_getb_fn *getb; + exca_putb_fn *putb; + device_t pccarddev; + uint32_t status; /* status, hw dependent */ }; void exca_init(struct exca_softc *sc, device_t dev, bus_space_tag_t, bus_space_handle_t, uint32_t); +void exca_insert(struct exca_softc *sc); int exca_io_map(struct exca_softc *sc, int width, struct resource *r); int exca_io_unmap_res(struct exca_softc *sc, struct resource *res); int exca_is_pcic(struct exca_softc *sc); @@ -89,31 +115,39 @@ int exca_mem_set_flags(struct exca_softc *sc, struct resource *res, int exca_mem_set_offset(struct exca_softc *sc, struct resource *res, uint32_t cardaddr, uint32_t *deltap); int exca_mem_unmap_res(struct exca_softc *sc, struct resource *res); -int exca_probe_slots(device_t dev, struct exca_softc *); +int exca_probe_slots(device_t dev, struct exca_softc *exca, + bus_space_tag_t iot, bus_space_handle_t ioh); +void exca_removal(struct exca_softc *); void exca_reset(struct exca_softc *, device_t child); +/* bus/device interfaces */ +int exca_activate_resource(struct exca_softc *exca, device_t child, int type, + int rid, struct resource *res); +int exca_deactivate_resource(struct exca_softc *exca, device_t child, int type, + int rid, struct resource *res); + static __inline uint8_t -exca_read(struct exca_softc *sc, int reg) +exca_getb(struct exca_softc *sc, int reg) { - return (bus_space_read_1(sc->bst, sc->bsh, sc->offset + reg)); + return (sc->getb(sc, reg)); } static __inline void -exca_write(struct exca_softc *sc, int reg, uint8_t val) +exca_putb(struct exca_softc *sc, int reg, uint8_t val) { - return (bus_space_write_1(sc->bst, sc->bsh, sc->offset + reg, val)); + sc->putb(sc, reg, val); } static __inline void exca_setb(struct exca_softc *sc, int reg, uint8_t mask) { - exca_write(sc, reg, exca_read(sc, reg) | mask); + exca_putb(sc, reg, exca_getb(sc, reg) | mask); } static __inline void exca_clrb(struct exca_softc *sc, int reg, uint8_t mask) { - exca_write(sc, reg, exca_read(sc, reg) & ~mask); + exca_putb(sc, reg, exca_getb(sc, reg) & ~mask); } #endif /* !_SYS_DEV_EXCA_EXCAVAR_H */ diff --git a/sys/dev/pccard/pccbb/Makefile b/sys/dev/pccard/pccbb/Makefile index 77a2131c0c..ac4457257b 100644 --- a/sys/dev/pccard/pccbb/Makefile +++ b/sys/dev/pccard/pccbb/Makefile @@ -1,8 +1,8 @@ -# $DragonFly: src/sys/dev/pccard/pccbb/Makefile,v 1.1 2004/02/10 07:55:47 joerg Exp $ +# $DragonFly: src/sys/dev/pccard/pccbb/Makefile,v 1.2 2007/07/05 12:08:54 sephe Exp $ KMOD= cbb -SRCS= pccbb.c \ - device_if.h bus_if.h pci_if.h pcib_if.h power_if.h card_if.h +SRCS= pccbb.c pccbb_isa.c pccbb_pci.c \ + device_if.h bus_if.h isa_if.h pci_if.h pcib_if.h power_if.h card_if.h NOMAN= .include diff --git a/sys/dev/pccard/pccbb/pccbb.c b/sys/dev/pccard/pccbb/pccbb.c index 3202451b63..0ef6538d32 100644 --- a/sys/dev/pccard/pccbb/pccbb.c +++ b/sys/dev/pccard/pccbb/pccbb.c @@ -1,24 +1,22 @@ -/* - * Copyright (c) 2002 M. Warner Losh. - * Copyright (c) 2000,2001 Jonathan Chen. +/*- + * Copyright (c) 2002-2004 M. Warner Losh. + * Copyright (c) 2000-2001 Jonathan Chen. * All rights reserved. * * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -26,11 +24,11 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/pccbb/pccbb.c,v 1.64 2002/11/23 23:09:45 imp Exp $ - * $DragonFly: src/sys/dev/pccard/pccbb/pccbb.c,v 1.20 2007/05/13 18:33:57 swildner Exp $ + * $FreeBSD: src/sys/dev/pccbb/pccbb.c,v 1.126 2005/07/17 19:40:05 imp Exp $ + * $DragonFly: src/sys/dev/pccard/pccbb/pccbb.c,v 1.21 2007/07/05 12:08:54 sephe Exp $ */ -/* +/*- * Copyright (c) 1998, 1999 and 2000 * HAYAKAWA Koichi. All rights reserved. * @@ -62,6 +60,9 @@ /* * Driver for PCI to CardBus Bridge chips + * and PCI to PCMCIA Bridge chips + * and ISA to PCMCIA host adapters + * and C Bus to PCMCIA host adapters * * References: * TI Datasheets: @@ -76,17 +77,19 @@ */ #include -#include -#include +#include #include #include #include +#include +#include #include #include -#include -#include -#include +#include #include +#include +#include +#include #include #include @@ -114,72 +117,13 @@ pci_write_config(DEV, REG, ( \ pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE) +#define CBB_CARD_PRESENT(s) ((s & CBB_STATE_CD) == 0) + #define CBB_START_MEM 0x88000000 #define CBB_START_32_IO 0x1000 #define CBB_START_16_IO 0x100 -struct yenta_chipinfo { - uint32_t yc_id; - const char *yc_name; - int yc_chiptype; -} yc_chipsets[] = { - /* Texas Instruments chips */ - {PCIC_ID_TI1031, "TI1031 PCI-PC Card Bridge", CB_TI113X}, - {PCIC_ID_TI1130, "TI1130 PCI-CardBus Bridge", CB_TI113X}, - {PCIC_ID_TI1131, "TI1131 PCI-CardBus Bridge", CB_TI113X}, - - {PCIC_ID_TI1210, "TI1210 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1211, "TI1211 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1220, "TI1220 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1221, "TI1221 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1225, "TI1225 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1250, "TI1250 PCI-CardBus Bridge", CB_TI125X}, - {PCIC_ID_TI1251, "TI1251 PCI-CardBus Bridge", CB_TI125X}, - {PCIC_ID_TI1251B,"TI1251B PCI-CardBus Bridge",CB_TI125X}, - {PCIC_ID_TI1260, "TI1260 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1260B,"TI1260B PCI-CardBus Bridge",CB_TI12XX}, - {PCIC_ID_TI1410, "TI1410 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1420, "TI1420 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1421, "TI1421 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1450, "TI1450 PCI-CardBus Bridge", CB_TI125X}, /*SIC!*/ - {PCIC_ID_TI1451, "TI1451 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1510, "TI1510 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI1520, "TI1520 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI4410, "TI4410 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI4450, "TI4450 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI4451, "TI4451 PCI-CardBus Bridge", CB_TI12XX}, - {PCIC_ID_TI4510, "TI4510 PCI-CardBus Bridge", CB_TI12XX}, - - /* Ricoh chips */ - {PCIC_ID_RICOH_RL5C465, "RF5C465 PCI-CardBus Bridge", CB_RF5C46X}, - {PCIC_ID_RICOH_RL5C466, "RF5C466 PCI-CardBus Bridge", CB_RF5C46X}, - {PCIC_ID_RICOH_RL5C475, "RF5C475 PCI-CardBus Bridge", CB_RF5C47X}, - {PCIC_ID_RICOH_RL5C476, "RF5C476 PCI-CardBus Bridge", CB_RF5C47X}, - {PCIC_ID_RICOH_RL5C477, "RF5C477 PCI-CardBus Bridge", CB_RF5C47X}, - {PCIC_ID_RICOH_RL5C478, "RF5C478 PCI-CardBus Bridge", CB_RF5C47X}, - - /* Toshiba products */ - {PCIC_ID_TOPIC95, "ToPIC95 PCI-CardBus Bridge", CB_TOPIC95}, - {PCIC_ID_TOPIC95B, "ToPIC95B PCI-CardBus Bridge", CB_TOPIC95}, - {PCIC_ID_TOPIC97, "ToPIC97 PCI-CardBus Bridge", CB_TOPIC97}, - {PCIC_ID_TOPIC100, "ToPIC100 PCI-CardBus Bridge", CB_TOPIC97}, - - /* Cirrus Logic */ - {PCIC_ID_CLPD6832, "CLPD6832 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_CLPD6833, "CLPD6833 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_CLPD6834, "CLPD6834 PCI-CardBus Bridge", CB_CIRRUS}, - - /* 02Micro */ - {PCIC_ID_OZ6832, "O2Micro OZ6832/6833 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_OZ6860, "O2Micro OZ6836/6860 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_OZ6872, "O2Micro OZ6812/6872 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_OZ6912, "O2Micro OZ6912/6972 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_OZ6922, "O2Micro OZ6922 PCI-CardBus Bridge", CB_CIRRUS}, - {PCIC_ID_OZ6933, "O2Micro OZ6933 PCI-CardBus Bridge", CB_CIRRUS}, - - /* sentinel */ - {0 /* null id */, "unknown", CB_UNKNOWN}, -}; +devclass_t cbb_devclass; /* sysctl vars */ SYSCTL_NODE(_hw, OID_AUTO, cbb, CTLFLAG_RD, 0, "CBB parameters"); @@ -208,26 +152,10 @@ TUNABLE_INT("hw.cbb.debug", &cbb_debug); SYSCTL_ULONG(_hw_cbb, OID_AUTO, debug, CTLFLAG_RW, &cbb_debug, 0, "Verbose cardbus bridge debugging"); -static int cbb_chipset(uint32_t pci_id, const char **namep); -static int cbb_probe(device_t brdev); -static void cbb_chipinit(struct cbb_softc *sc); -static int cbb_attach(device_t brdev); -static void cbb_release_helper(device_t brdev); -static int cbb_detach(device_t brdev); -static int cbb_shutdown(device_t brdev); -static void cbb_driver_added(device_t brdev, driver_t *driver); -static void cbb_child_detached(device_t brdev, device_t child); -static void cbb_event_thread(void *arg); static void cbb_insert(struct cbb_softc *sc); static void cbb_removal(struct cbb_softc *sc); -static void cbb_intr(void *arg); -static int cbb_detect_voltage(device_t brdev); -static int cbb_power(device_t brdev, int volts); +static uint32_t cbb_detect_voltage(device_t brdev); static void cbb_cardbus_reset(device_t brdev); -static int cbb_cardbus_power_enable_socket(device_t brdev, - device_t child); -static void cbb_cardbus_power_disable_socket(device_t brdev, - device_t child); static int cbb_cardbus_io_open(device_t brdev, int win, uint32_t start, uint32_t end); static int cbb_cardbus_mem_open(device_t brdev, int win, @@ -239,55 +167,14 @@ static int cbb_cardbus_deactivate_resource(device_t brdev, device_t child, int type, int rid, struct resource *res); static struct resource *cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, int *rid, u_long start, - u_long end, u_long count, uint flags); + u_long end, u_long count, u_int flags); static int cbb_cardbus_release_resource(device_t brdev, device_t child, int type, int rid, struct resource *res); -static int cbb_power_enable_socket(device_t brdev, device_t child); -static void cbb_power_disable_socket(device_t brdev, device_t child); -static int cbb_activate_resource(device_t brdev, device_t child, - int type, int rid, struct resource *r); -static int cbb_deactivate_resource(device_t brdev, device_t child, - int type, int rid, struct resource *r); -static struct resource *cbb_alloc_resource(device_t brdev, device_t child, - int type, int *rid, u_long start, u_long end, u_long count, - uint flags); -static int cbb_release_resource(device_t brdev, device_t child, - int type, int rid, struct resource *r); -static int cbb_read_ivar(device_t brdev, device_t child, int which, - uintptr_t *result); -static int cbb_write_ivar(device_t brdev, device_t child, int which, - uintptr_t value); -static int cbb_maxslots(device_t brdev); -static uint32_t cbb_read_config(device_t brdev, int b, int s, int f, - int reg, int width); -static void cbb_write_config(device_t brdev, int b, int s, int f, - int reg, uint32_t val, int width); - -/* - */ -static __inline void -cbb_set(struct cbb_softc *sc, uint32_t reg, uint32_t val) -{ - bus_space_write_4(sc->bst, sc->bsh, reg, val); -} - -static __inline uint32_t -cbb_get(struct cbb_softc *sc, uint32_t reg) -{ - return (bus_space_read_4(sc->bst, sc->bsh, reg)); -} - -static __inline void -cbb_setb(struct cbb_softc *sc, uint32_t reg, uint32_t bits) -{ - cbb_set(sc, reg, cbb_get(sc, reg) | bits); -} - -static __inline void -cbb_clrb(struct cbb_softc *sc, uint32_t reg, uint32_t bits) -{ - cbb_set(sc, reg, cbb_get(sc, reg) & ~bits); -} +static int cbb_cardbus_power_enable_socket(device_t brdev, + device_t child); +static void cbb_cardbus_power_disable_socket(device_t brdev, + device_t child); +static void cbb_func_intr(void *arg); static void cbb_remove_res(struct cbb_softc *sc, struct resource *res) @@ -314,7 +201,7 @@ cbb_find_res(struct cbb_softc *sc, int type, int rid) return (NULL); } -static int +static void cbb_insert_res(struct cbb_softc *sc, struct resource *res, int type, int rid) { @@ -326,12 +213,11 @@ cbb_insert_res(struct cbb_softc *sc, struct resource *res, int type, */ rle = kmalloc(sizeof(struct cbb_reslist), M_DEVBUF, M_NOWAIT); if (rle == NULL) - return (ENOMEM); + panic("cbb_cardbus_alloc_resource: can't record entry!"); rle->res = res; rle->type = type; rle->rid = rid; SLIST_INSERT_HEAD(&sc->rl, rle, link); - return (0); } static void @@ -349,599 +235,273 @@ cbb_destroy_res(struct cbb_softc *sc) } } -/************************************************************************/ -/* Probe/Attach */ -/************************************************************************/ - -static int -cbb_chipset(uint32_t pci_id, const char **namep) -{ - struct yenta_chipinfo *ycp; - - for (ycp = yc_chipsets; ycp->yc_id != 0 && pci_id != ycp->yc_id; ++ycp) - continue; - if (namep != NULL) - *namep = ycp->yc_name; - return (ycp->yc_chiptype); -} - -static int -cbb_probe(device_t brdev) -{ - const char *name; - uint32_t progif; - uint32_t subclass; - uint32_t class; - - /* - * Do we know that we support the chipset? If so, then we - * accept the device. - */ - if (cbb_chipset(pci_get_devid(brdev), &name) != CB_UNKNOWN) { - device_set_desc(brdev, name); - return (0); - } - - /* - * We do support generic CardBus bridges. All that we've seen - * to date have progif 0 (the Yenta spec, and successors mandate - * this). We do not support PCI PCMCIA bridges (with one exception) - * with this driver since they generally are I/O mapped. Those - * are supported by the pcic driver. This should help us be more - * future proof. - */ - class = pci_get_class(brdev); - subclass = pci_get_subclass(brdev); - progif = pci_get_progif(brdev); - if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_CARDBUS && progif == 0) { - device_set_desc(brdev, "PCI-CardBus Bridge"); - return (0); - } - return (ENXIO); -} - - -static void -cbb_chipinit(struct cbb_softc *sc) -{ - uint32_t mux, sysctrl; - - /* Set CardBus latency timer */ - if (pci_read_config(sc->dev, PCIR_SECLAT_1, 1) < 0x20) - pci_write_config(sc->dev, PCIR_SECLAT_1, 0x20, 1); - - /* Set PCI latency timer */ - if (pci_read_config(sc->dev, PCIR_LATTIMER, 1) < 0x20) - pci_write_config(sc->dev, PCIR_LATTIMER, 0x20, 1); - - /* Enable memory access */ - PCI_MASK_CONFIG(sc->dev, PCIR_COMMAND, - | PCIM_CMD_MEMEN - | PCIM_CMD_PORTEN - | PCIM_CMD_BUSMASTEREN, 2); - - /* disable Legacy IO */ - switch (sc->chipset) { - case CB_RF5C46X: - PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL, - & ~(CBBM_BRIDGECTRL_RL_3E0_EN | - CBBM_BRIDGECTRL_RL_3E2_EN), 2); - break; - default: - pci_write_config(sc->dev, CBBR_LEGACY, 0x0, 4); - break; - } - - /* Use PCI interrupt for interrupt routing */ - PCI_MASK2_CONFIG(sc->dev, CBBR_BRIDGECTRL, - & ~(CBBM_BRIDGECTRL_MASTER_ABORT | - CBBM_BRIDGECTRL_INTR_IREQ_EN), - | CBBM_BRIDGECTRL_WRITE_POST_EN, - 2); - - /* - * XXX this should be a function table, ala OLDCARD. This means - * that we could more easily support ISA interrupts for pccard - * cards if we had to. - */ - switch (sc->chipset) { - case CB_TI113X: - /* - * The TI 1031, TI 1130 and TI 1131 all require another bit - * be set to enable PCI routing of interrupts, and then - * a bit for each of the CSC and Function interrupts we - * want routed. - */ - PCI_MASK_CONFIG(sc->dev, CBBR_CBCTRL, - | CBBM_CBCTRL_113X_PCI_INTR | - CBBM_CBCTRL_113X_PCI_CSC | CBBM_CBCTRL_113X_PCI_IRQ_EN, - 1); - PCI_MASK_CONFIG(sc->dev, CBBR_DEVCTRL, - & ~(CBBM_DEVCTRL_INT_SERIAL | - CBBM_DEVCTRL_INT_PCI), 1); - break; - case CB_TI12XX: - /* - * Some TI 12xx (and [14][45]xx) based pci cards - * sometimes have issues with the MFUNC register not - * being initialized due to a bad EEPROM on board. - * Laptops that this matters on have this register - * properly initialized. - * - * The TI125X parts have a different register. - */ - mux = pci_read_config(sc->dev, CBBR_MFUNC, 4); - sysctrl = pci_read_config(sc->dev, CBBR_SYSCTRL, 4); - if (mux == 0) { - mux = (mux & ~CBBM_MFUNC_PIN0) | - CBBM_MFUNC_PIN0_INTA; - if ((sysctrl & CBBM_SYSCTRL_INTRTIE) == 0) - mux = (mux & ~CBBM_MFUNC_PIN1) | - CBBM_MFUNC_PIN1_INTB; - pci_write_config(sc->dev, CBBR_MFUNC, mux, 4); - } - /*FALLTHROUGH*/ - case CB_TI125X: - /* - * Disable zoom video. Some machines initialize this - * improperly and exerpience has shown that this helps - * on some machines. - */ - pci_write_config(sc->dev, CBBR_MMCTRL, 0, 4); - break; - case CB_TOPIC97: - /* - * Disable Zoom Video, ToPIC 97, 100. - */ - pci_write_config(sc->dev, CBBR_TOPIC_ZV_CONTROL, 0, 1); - /* - * ToPIC 97, 100 - * At offset 0xa1: INTERRUPT CONTROL register - * 0x1: Turn on INT interrupts. - */ - PCI_MASK_CONFIG(sc->dev, CBBR_TOPIC_INTCTRL, - | CBBM_TOPIC_INTCTRL_INTIRQSEL, 1); - goto topic_common; - case CB_TOPIC95: - /* - * SOCKETCTRL appears to be TOPIC 95/B specific - */ - PCI_MASK_CONFIG(sc->dev, CBBR_TOPIC_SOCKETCTRL, - | CBBM_TOPIC_SOCKETCTRL_SCR_IRQSEL, 4); - - topic_common:; - /* - * At offset 0xa0: SLOT CONTROL - * 0x80 Enable CardBus Functionality - * 0x40 Enable CardBus and PC Card registers - * 0x20 Lock ID in exca regs - * 0x10 Write protect ID in config regs - * Clear the rest of the bits, which defaults the slot - * in legacy mode to 0x3e0 and offset 0. (legacy - * mode is determined elsewhere) - */ - pci_write_config(sc->dev, CBBR_TOPIC_SLOTCTRL, - CBBM_TOPIC_SLOTCTRL_SLOTON | - CBBM_TOPIC_SLOTCTRL_SLOTEN | - CBBM_TOPIC_SLOTCTRL_ID_LOCK | - CBBM_TOPIC_SLOTCTRL_ID_WP, 1); - - /* - * At offset 0xa3 Card Detect Control Register - * 0x80 CARDBUS enbale - * 0x01 Cleared for hardware change detect - */ - PCI_MASK2_CONFIG(sc->dev, CBBR_TOPIC_CDC, - | CBBM_TOPIC_CDC_CARDBUS, - & ~CBBM_TOPIC_CDC_SWDETECT, 4); - break; - } - - /* - * Need to tell ExCA registers to route via PCI interrupts. There - * are two ways to do this. Once is to set INTR_ENABLE and the - * other is to set CSC to 0. Since both methods are mutually - * compatible, we do both. - */ - exca_write(&sc->exca, EXCA_INTR, EXCA_INTR_ENABLE); - exca_write(&sc->exca, EXCA_CSC_INTR, 0); - - /* close all memory and io windows */ - pci_write_config(sc->dev, CBBR_MEMBASE0, 0xffffffff, 4); - pci_write_config(sc->dev, CBBR_MEMLIMIT0, 0, 4); - pci_write_config(sc->dev, CBBR_MEMBASE1, 0xffffffff, 4); - pci_write_config(sc->dev, CBBR_MEMLIMIT1, 0, 4); - pci_write_config(sc->dev, CBBR_IOBASE0, 0xffffffff, 4); - pci_write_config(sc->dev, CBBR_IOLIMIT0, 0, 4); - pci_write_config(sc->dev, CBBR_IOBASE1, 0xffffffff, 4); - pci_write_config(sc->dev, CBBR_IOLIMIT1, 0, 4); -} - -static int -cbb_attach(device_t brdev) +/* + * Disable function interrupts by telling the bridge to generate IRQ1 + * interrupts. These interrupts aren't really generated by the chip, since + * IRQ1 is reserved. Some chipsets assert INTA# inappropriately during + * initialization, so this helps to work around the problem. + * + * XXX We can't do this workaround for all chipsets, because this + * XXX causes interference with the keyboard because somechipsets will + * XXX actually signal IRQ1 over their serial interrupt connections to + * XXX the south bridge. Disable it it for now. + */ +void +cbb_disable_func_intr(struct cbb_softc *sc) { - struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev); - int rid; - - lockinit(&sc->lock, "cbb", 0, 0); - sc->chipset = cbb_chipset(pci_get_devid(brdev), NULL); - sc->dev = brdev; - sc->cbdev = NULL; - sc->pccarddev = NULL; - sc->secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1); - sc->subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1); - SLIST_INIT(&sc->rl); - STAILQ_INIT(&sc->intr_handlers); - -#ifndef BURN_THE_BOATS - /* - * The PCI bus code should assign us memory in the absense - * of the BIOS doing so. However, 'should' isn't 'is,' so we kludge - * up something here until the PCI/acpi code properly assigns the - * resource. - */ +#if 0 + uint8_t reg; + reg = (exca_getb(&sc->exca[0], EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) | + EXCA_INTR_IRQ_RESERVED1; + exca_putb(&sc->exca[0], EXCA_INTR, reg); #endif - rid = CBBR_SOCKBASE; - sc->base_res = bus_alloc_resource(brdev, SYS_RES_MEMORY, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!sc->base_res) { -#ifdef BURN_THE_BOATS - device_printf(brdev, "Could not map register memory\n"); - return (ENOMEM); -#else - uint32_t sockbase; - - /* - * Generally, the BIOS will assign this memory for us. - * However, newer BIOSes do not because the MS design - * documents have mandated that this is for the OS - * to assign rather than the BIOS. This driver shouldn't - * be doing this, but until the pci bus code (or acpi) - * does this, we allow CardBus bridges to work on more - * machines. - */ - pci_write_config(brdev, rid, 0xffffffff, 4); - sockbase = pci_read_config(brdev, rid, 4); - sockbase = (sockbase & 0xfffffff0) & -(sockbase & 0xfffffff0); - sc->base_res = bus_generic_alloc_resource( - device_get_parent(brdev), brdev, SYS_RES_MEMORY, - &rid, cbb_start_mem, ~0, sockbase, - RF_ACTIVE|rman_make_alignment_flags(sockbase)); - if (!sc->base_res) { - device_printf(brdev, - "Could not grab register memory\n"); - return (ENOMEM); - } - sc->flags |= CBB_KLUDGE_ALLOC; - pci_write_config(brdev, CBBR_SOCKBASE, - rman_get_start(sc->base_res), 4); -#endif - } - DEVPRINTF((brdev, "PCI Memory allocated: %08lx\n", - rman_get_start(sc->base_res))); - - sc->bst = rman_get_bustag(sc->base_res); - sc->bsh = rman_get_bushandle(sc->base_res); - exca_init(&sc->exca, brdev, sc->bst, sc->bsh, CBB_EXCA_OFFSET); - sc->exca.flags |= EXCA_HAS_MEMREG_WIN; - cbb_chipinit(sc); - - /* attach children */ - sc->cbdev = device_add_child(brdev, "cardbus", -1); - if (sc->cbdev == NULL) - DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n")); - else if (device_probe_and_attach(sc->cbdev) != 0) { - DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n")); - sc->cbdev = NULL; - } - - sc->pccarddev = device_add_child(brdev, "pccard", -1); - if (sc->pccarddev == NULL) - DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n")); - else if (device_probe_and_attach(sc->pccarddev) != 0) { - DEVPRINTF((brdev, "WARNING: cannot attach pccard bus.\n")); - sc->pccarddev = NULL; - } - - /* Map and establish the interrupt. */ - rid = 0; - sc->irq_res = bus_alloc_resource(brdev, SYS_RES_IRQ, &rid, 0, ~0, 1, - RF_SHAREABLE | RF_ACTIVE); - if (sc->irq_res == NULL) { - kprintf("cbb: Unable to map IRQ...\n"); - goto err; - } - - if (bus_setup_intr(brdev, sc->irq_res, 0, cbb_intr, sc, - &sc->intrhand, NULL)) { - device_printf(brdev, "couldn't establish interrupt"); - goto err; - } - - /* reset 16-bit pcmcia bus */ - exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET); - - /* turn off power */ - cbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); - - /* CSC Interrupt: Card detect interrupt on */ - cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); - - /* reset interrupt */ - cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT)); - - /* Start the thread */ - if (kthread_create(cbb_event_thread, sc, &sc->event_thread, - "%s%d", device_get_name(sc->dev), device_get_unit(sc->dev))) { - device_printf (sc->dev, "unable to create event thread.\n"); - panic ("cbb_create_event_thread"); - } - - return (0); -err: - if (sc->irq_res) - bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); - if (sc->base_res) { - if (sc->flags & CBB_KLUDGE_ALLOC) - bus_generic_release_resource(device_get_parent(brdev), - brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, - sc->base_res); - else - bus_release_resource(brdev, SYS_RES_MEMORY, - CBBR_SOCKBASE, sc->base_res); - } - return (ENOMEM); } /* - * shutdown and detach both call the release helper to disable the interrupt - * and cleanup the resources. + * Enable function interrupts. We turn on function interrupts when the card + * requests an interrupt. The PCMCIA standard says that we should set + * the lower 4 bits to 0 to route via PCI. Note: we call this for both + * CardBus and R2 (PC Card) cases, but it should have no effect on CardBus + * cards. */ -static -void -cbb_release_helper(device_t brdev) +static void +cbb_enable_func_intr(struct cbb_softc *sc) { - struct cbb_softc *sc = device_get_softc(brdev); - - lockmgr(&sc->lock, LK_EXCLUSIVE); - sc->flags |= CBB_KTHREAD_DONE; - lockmgr(&sc->lock, LK_RELEASE); - if (sc->flags & CBB_KTHREAD_RUNNING) { - wakeup(sc); - tsleep(cbb_detach, 0, "pccbb", 2); - } + uint8_t reg; - /* - * Reset the bridge controller and reset the interrupt, then tear - * it down (which disables the interrupt) and de-power. - */ - PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2); - exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET); - - bus_teardown_intr(brdev, sc->irq_res, sc->intrhand); - cbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); - - /* - * Release interrupt and memory-mapped resources. Device memory - * cannot be safely accessed after we do this. - */ - bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); - if (sc->flags & CBB_KLUDGE_ALLOC) { - bus_generic_release_resource(device_get_parent(brdev), - brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, - sc->base_res); - } else { - bus_release_resource(brdev, SYS_RES_MEMORY, - CBBR_SOCKBASE, sc->base_res); - } + reg = (exca_getb(&sc->exca[0], EXCA_INTR) & ~EXCA_INTR_IRQ_MASK) | + EXCA_INTR_IRQ_NONE; + exca_putb(&sc->exca[0], EXCA_INTR, reg); } -static int +int cbb_detach(device_t brdev) { - device_t *devlist; + struct cbb_softc *sc = device_get_softc(brdev); int numdevs; + device_t *devlist; + int tmp; int error; - int i; device_get_children(brdev, &devlist, &numdevs); error = 0; - for (i = 0; i < numdevs; i++) { - if (device_detach(devlist[i]) == 0) - device_delete_child(brdev, devlist[i]); + for (tmp = 0; tmp < numdevs; tmp++) { + if (device_detach(devlist[tmp]) == 0) + device_delete_child(brdev, devlist[tmp]); else error++; } - kfree (devlist, M_TEMP); - if (error == 0) - cbb_release_helper(brdev); - else - error = ENXIO; - return (error); + kfree(devlist, M_TEMP); + if (error > 0) + return (ENXIO); + + /* + * XXX do we teardown all the ones still registered to guard against + * XXX buggy client drivers? + */ + bus_teardown_intr(brdev, sc->irq_res, sc->intrhand); + sc->flags |= CBB_KTHREAD_DONE; + if (sc->flags & CBB_KTHREAD_RUNNING) { + crit_enter(); + wakeup(&sc->generic_cv); + tsleep(sc->event_thread, 0, "cbbun", 0); + crit_exit(); + } + + bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); + bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, + sc->base_res); + return (0); } -static int +int cbb_shutdown(device_t brdev) { - device_t *devlist; - int numdevs; - int i; + struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev); + /* properly reset everything at shutdown */ - device_get_children(brdev, &devlist, &numdevs); + PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2); + exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET); - for (i = 0; i < numdevs; i++) { - if (device_shutdown(devlist[i]) == 0) - ; /* XXX delete the child without detach? */ - } - kfree (devlist, M_TEMP); - cbb_release_helper(brdev); + cbb_set(sc, CBB_SOCKET_MASK, 0); - /* - * This may prevent bios confusion on reboot for some bioses - */ + cbb_power(brdev, CARD_OFF); + + exca_putb(&sc->exca[0], EXCA_ADDRWIN_ENABLE, 0); + pci_write_config(brdev, CBBR_MEMBASE0, 0, 4); + pci_write_config(brdev, CBBR_MEMLIMIT0, 0, 4); + pci_write_config(brdev, CBBR_MEMBASE1, 0, 4); + pci_write_config(brdev, CBBR_MEMLIMIT1, 0, 4); + pci_write_config(brdev, CBBR_IOBASE0, 0, 4); + pci_write_config(brdev, CBBR_IOLIMIT0, 0, 4); + pci_write_config(brdev, CBBR_IOBASE1, 0, 4); + pci_write_config(brdev, CBBR_IOLIMIT1, 0, 4); pci_write_config(brdev, PCIR_COMMAND, 0, 2); return (0); } -static int +int cbb_setup_intr(device_t dev, device_t child, struct resource *irq, int flags, driver_intr_t *intr, void *arg, void **cookiep, lwkt_serialize_t serializer) { struct cbb_intrhand *ih; struct cbb_softc *sc = device_get_softc(dev); + int err; /* - * You aren't allowed to have fast interrupts for pccard/cardbus - * things since those interrupts are PCI and shared. Since we use - * the PCI interrupt for the status change interrupts, it can't be - * free for use by the driver. Fast interrupts must not be shared. + * Well, this is no longer strictly true. You can have multiple + * FAST ISRs, but can't mix fast and slow, so we have to assume + * least common denominator until the base system supports mixing + * and matching better. */ - ih = kmalloc(sizeof(struct cbb_intrhand), M_DEVBUF, M_WAITOK|M_ZERO); + if ((flags & INTR_FAST) != 0) + return (EINVAL); + ih = kmalloc(sizeof(struct cbb_intrhand), M_DEVBUF, M_NOWAIT); if (ih == NULL) return (ENOMEM); *cookiep = ih; ih->intr = intr; ih->arg = arg; + ih->sc = sc; ih->serializer = serializer; - STAILQ_INSERT_TAIL(&sc->intr_handlers, ih, entries); - /* - * XXX we should do what old card does to ensure that we don't - * XXX call the function's interrupt routine(s). - */ /* * XXX need to turn on ISA interrupts, if we ever support them, but * XXX for now that's all we need to do. */ - return (0); + err = BUS_SETUP_INTR(device_get_parent(dev), child, irq, flags, + cbb_func_intr, ih, &ih->cookie, NULL); + if (err != 0) { + kfree(ih, M_DEVBUF); + return (err); + } + cbb_enable_func_intr(sc); + sc->flags |= CBB_CARD_OK; + return 0; } -static int +int cbb_teardown_intr(device_t dev, device_t child, struct resource *irq, void *cookie) { struct cbb_intrhand *ih; - struct cbb_softc *sc = device_get_softc(dev); + int err; - cbb_setb(sc, CBB_SOCKET_MASK, 0); /* Quiet hardware */ /* XXX Need to do different things for ISA interrupts. */ ih = (struct cbb_intrhand *) cookie; - STAILQ_REMOVE(&sc->intr_handlers, ih, cbb_intrhand, entries); + err = BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq, + ih->cookie); + if (err != 0) + return (err); kfree(ih, M_DEVBUF); return (0); } -static void +void cbb_driver_added(device_t brdev, driver_t *driver) { struct cbb_softc *sc = device_get_softc(brdev); device_t *devlist; + device_t dev; int tmp; int numdevs; - int wake; - uint32_t sockstate; + int wake = 0; DEVICE_IDENTIFY(driver, brdev); device_get_children(brdev, &devlist, &numdevs); - wake = 0; - sockstate = cbb_get(sc, CBB_SOCKET_STATE); for (tmp = 0; tmp < numdevs; tmp++) { - if (device_get_state(devlist[tmp]) == DS_NOTPRESENT && - device_probe_and_attach(devlist[tmp]) == 0) { - if (devlist[tmp] == NULL) - /* NOTHING */; - else if (strcmp(driver->name, "cardbus") == 0) { - sc->cbdev = devlist[tmp]; - if (((sockstate & CBB_SOCKET_STAT_CD) == 0) && - (sockstate & CBB_SOCKET_STAT_CB)) - wake++; - } else if (strcmp(driver->name, "pccard") == 0) { - sc->pccarddev = devlist[tmp]; - if (((sockstate & CBB_SOCKET_STAT_CD) == 0) && - (sockstate & CBB_SOCKET_STAT_16BIT)) - wake++; - } else - device_printf(brdev, - "Unsupported child bus: %s\n", - driver->name); - } + dev = devlist[tmp]; + if (device_get_state(dev) == DS_NOTPRESENT && + device_probe_and_attach(dev) == 0) + wake++; } kfree(devlist, M_TEMP); - if (wake > 0) { - if ((cbb_get(sc, CBB_SOCKET_STATE) & CBB_SOCKET_STAT_CD) - == 0) { - wakeup(sc); - } - } + if (wake > 0) + wakeup_one(&sc->generic_cv); } -static void +void cbb_child_detached(device_t brdev, device_t child) { struct cbb_softc *sc = device_get_softc(brdev); - if (child == sc->cbdev) - sc->cbdev = NULL; - else if (child == sc->pccarddev) - sc->pccarddev = NULL; - else - device_printf(brdev, "Unknown child detached: %s %p/%p\n", - device_get_nameunit(child), sc->cbdev, sc->pccarddev); + if (child != sc->cbdev && child != sc->exca[0].pccarddev) + device_printf(brdev, "Unknown child detached: %s\n", + device_get_nameunit(child)); } /************************************************************************/ /* Kthreads */ /************************************************************************/ -static void +void cbb_event_thread(void *arg) { struct cbb_softc *sc = arg; uint32_t status; int err; + int not_a_card = 0; - /* - * We take out Giant here because we need it deep, down in - * the bowels of the vm system for mapping the memory we need - * to read the CIS. We also need it for kthread_exit, which - * drops it. - */ sc->flags |= CBB_KTHREAD_RUNNING; - while (1) { + while ((sc->flags & CBB_KTHREAD_DONE) == 0) { /* - * Check to see if we have anything first so that - * if there's a card already inserted, we do the - * right thing. + * We take out Giant here because we need it deep, + * down in the bowels of the vm system for mapping the + * memory we need to read the CIS. In addition, since + * we are adding/deleting devices from the dev tree, + * and that code isn't MP safe, we have to hold Giant. */ - lockmgr(&sc->lock, LK_EXCLUSIVE); - if (sc->flags & CBB_KTHREAD_DONE) - break; - status = cbb_get(sc, CBB_SOCKET_STATE); - /* mtx_lock(&Giant); */ - if ((status & CBB_SOCKET_STAT_CD) == 0) - cbb_insert(sc); - else + DPRINTF(("Status is 0x%x\n", status)); + if (!CBB_CARD_PRESENT(status)) { + not_a_card = 0; /* We know card type */ cbb_removal(sc); - lockmgr(&sc->lock, LK_RELEASE); - /* mtx_unlock(&Giant); */ + } else if (status & CBB_STATE_NOT_A_CARD) { + /* + * Up to 20 times, try to rescan the card when we + * see NOT_A_CARD. + */ + if (not_a_card++ < 20) { + DEVPRINTF((sc->dev, + "Not a card bit set, rescanning\n")); + cbb_setb(sc, CBB_SOCKET_FORCE, CBB_FORCE_CV_TEST); + } else { + device_printf(sc->dev, + "Can't determine card type\n"); + } + } else { + not_a_card = 0; /* We know card type */ + cbb_insert(sc); + } /* * Wait until it has been 1s since the last time we * get an interrupt. We handle the rest of the interrupt - * at the top of the loop. + * at the top of the loop. Although we clear the bit in the + * ISR, we signal sc->generic_cv from the detach path after + * we've set the CBB_KTHREAD_DONE bit, so we can't do a simple + * 1s sleep here. + * + * In our ISR, we turn off the card changed interrupt. Turn + * them back on here before we wait for them to happen. We + * turn them on/off so that we can tolerate a large latency + * between the time we signal cbb_event_thread and it gets + * a chance to run. */ - err = tsleep(sc, 0, "pccbb", 0); - while (err != EWOULDBLOCK && + crit_enter(); + cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); + tsleep(&sc->generic_cv, 0, "cbbgcv", 0); + err = 0; + while (err != EWOULDBLOCK && (sc->flags & CBB_KTHREAD_DONE) == 0) - err = tsleep(sc, 0, "pccbb", 1 * hz); + err = tsleep(&sc->generic_cv, 0, "cbbgcv", hz); + crit_exit(); } sc->flags &= ~CBB_KTHREAD_RUNNING; - lockmgr(&sc->lock, LK_RELEASE); - /* mtx_lock(&Giant); */ + wakeup(sc->event_thread); kthread_exit(); } @@ -960,28 +520,18 @@ cbb_insert(struct cbb_softc *sc) DEVPRINTF((sc->dev, "card inserted: event=0x%08x, state=%08x\n", sockevent, sockstate)); - if (sockstate & CBB_SOCKET_STAT_16BIT) { - if (sc->pccarddev != NULL) { + if (sockstate & CBB_STATE_R2_CARD) { + if (sc->exca[0].pccarddev) { sc->flags |= CBB_16BIT_CARD; - sc->flags |= CBB_CARD_OK; - if (CARD_ATTACH_CARD(sc->pccarddev) != 0) { - device_printf(sc->dev, - "PC Card card activation failed\n"); - sc->flags &= ~CBB_CARD_OK; - } + exca_insert(&sc->exca[0]); } else { device_printf(sc->dev, - "PC Card inserted, but no pccard bus.\n"); + "16-bit card inserted, but no pccard bus.\n"); } - } else if (sockstate & CBB_SOCKET_STAT_CB) { + } else if (sockstate & CBB_STATE_CB_CARD) { if (sc->cbdev != NULL) { sc->flags &= ~CBB_16BIT_CARD; - sc->flags |= CBB_CARD_OK; - if (CARD_ATTACH_CARD(sc->cbdev) != 0) { - device_printf(sc->dev, - "CardBus card activation failed\n"); - sc->flags &= ~CBB_CARD_OK; - } + CARD_ATTACH_CARD(sc->cbdev); } else { device_printf(sc->dev, "CardBus card inserted, but no cardbus bus.\n"); @@ -991,16 +541,16 @@ cbb_insert(struct cbb_softc *sc) * We should power the card down, and try again a couple of * times if this happens. XXX */ - device_printf (sc->dev, "Unsupported card type detected\n"); + device_printf(sc->dev, "Unsupported card type detected\n"); } } static void cbb_removal(struct cbb_softc *sc) { + sc->flags &= ~CBB_CARD_OK; if (sc->flags & CBB_16BIT_CARD) { - if (sc->pccarddev != NULL) - CARD_DETACH_CARD(sc->pccarddev); + exca_removal(&sc->exca[0]); } else { if (sc->cbdev != NULL) CARD_DETACH_CARD(sc->cbdev); @@ -1012,20 +562,65 @@ cbb_removal(struct cbb_softc *sc) /* Interrupt Handler */ /************************************************************************/ +/* + * Since we touch hardware in the worst case, we don't need to use atomic + * ops on the CARD_OK tests. They would save us a trip to the hardware + * if CARD_OK was recently cleared and the caches haven't updated yet. + * However, an atomic op costs between 100-200 CPU cycles. On a 3GHz + * machine, this is about 33-66ns, whereas a trip the the hardware + * is about that. On slower machines, the cost is even higher, so the + * trip to the hardware is cheaper and achieves the same ends that + * a fully locked operation would give us. + * + * This is a separate routine because we'd have to use locking and/or + * other synchronization in cbb_intr to do this there. That would be + * even more expensive. + * + * I need to investigate what this means for a SMP machine with multiple + * CPUs servicing the ISR when an eject happens. In the case of a dirty + * eject, CD glitches and we might read 'card present' from the hardware + * due to this jitter. If we assumed that cbb_intr() ran before + * cbb_func_intr(), we could just check the SOCKET_MASK register and if + * CD changes were clear there, then we'd know the card was gone. + */ static void +cbb_func_intr(void *arg) +{ + struct cbb_intrhand *ih = arg; + struct cbb_softc *sc = ih->sc; + + /* + * Make sure that the card is really there. + */ + if ((sc->flags & CBB_CARD_OK) == 0) + return; + if (!CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) { + sc->flags &= ~CBB_CARD_OK; + return; + } + + /* + * nb: don't have to check for giant or not, since that's done + * in the ISR dispatch + */ + if (ih->serializer) { + lwkt_serialize_handler_call(ih->serializer, + (inthand2_t *)ih->intr, ih->arg, NULL); + } else { + (*ih->intr)(ih->arg); + } +} + +void cbb_intr(void *arg) { struct cbb_softc *sc = arg; uint32_t sockevent; - struct cbb_intrhand *ih; - /* - * This ISR needs work XXX - */ sockevent = cbb_get(sc, CBB_SOCKET_EVENT); - if (sockevent) { + if (sockevent != 0) { /* ack the interrupt */ - cbb_setb(sc, CBB_SOCKET_EVENT, sockevent); + cbb_set(sc, CBB_SOCKET_EVENT, sockevent); /* * If anything has happened to the socket, we assume that @@ -1041,209 +636,277 @@ cbb_intr(void *arg) * excellent results. */ if (sockevent & CBB_SOCKET_EVENT_CD) { - lockmgr(&sc->lock, LK_EXCLUSIVE); + crit_enter(); + cbb_clrb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); sc->flags &= ~CBB_CARD_OK; - lockmgr(&sc->lock, LK_RELEASE); - wakeup(sc); - } - if (sockevent & CBB_SOCKET_EVENT_CSTS) { - DPRINTF((" cstsevent occurred: 0x%08x\n", - cbb_get(sc, CBB_SOCKET_STATE))); + cbb_disable_func_intr(sc); + wakeup_one(&sc->generic_cv); + crit_exit(); } + /* + * If we get a power interrupt, wakeup anybody that might + * be waiting for one. + */ if (sockevent & CBB_SOCKET_EVENT_POWER) { - DPRINTF((" pwrevent occurred: 0x%08x\n", - cbb_get(sc, CBB_SOCKET_STATE))); + crit_enter(); + sc->powerintr++; + wakeup(&sc->power_cv); + crit_exit(); } - /* Other bits? */ - } - if (sc->flags & CBB_CARD_OK) { - STAILQ_FOREACH(ih, &sc->intr_handlers, entries) { - if (ih->serializer) { - lwkt_serialize_handler_call(ih->serializer, - (inthand2_t *)ih->intr, - ih->arg, NULL); - } else { - (*ih->intr)(ih->arg); - } - } - } + /* + * Some chips also require us to read the old ExCA registe for + * card status change when we route CSC vis PCI. This isn't supposed + * to be required, but it clears the interrupt state on some chipsets. + * Maybe there's a setting that would obviate its need. Maybe we + * should test the status bits and deal with them, but so far we've + * not found any machines that don't also give us the socket status + * indication above. + * + * We have to call this unconditionally because some bridges deliver + * the even independent of the CBB_SOCKET_EVENT_CD above. + */ + exca_getb(&sc->exca[0], EXCA_CSC); } /************************************************************************/ /* Generic Power functions */ /************************************************************************/ -static int +static uint32_t cbb_detect_voltage(device_t brdev) { struct cbb_softc *sc = device_get_softc(brdev); uint32_t psr; - int vol = CARD_UKN_CARD; + uint32_t vol = CARD_UKN_CARD; psr = cbb_get(sc, CBB_SOCKET_STATE); - if (psr & CBB_SOCKET_STAT_5VCARD) + if (psr & CBB_STATE_5VCARD) vol |= CARD_5V_CARD; - if (psr & CBB_SOCKET_STAT_3VCARD) + if (psr & CBB_STATE_3VCARD) vol |= CARD_3V_CARD; - if (psr & CBB_SOCKET_STAT_XVCARD) + if (psr & CBB_STATE_XVCARD) vol |= CARD_XV_CARD; - if (psr & CBB_SOCKET_STAT_YVCARD) + if (psr & CBB_STATE_YVCARD) vol |= CARD_YV_CARD; return (vol); } -static int +static uint8_t +cbb_o2micro_power_hack(struct cbb_softc *sc) +{ + uint8_t reg; + + /* + * Issue #2: INT# not qualified with IRQ Routing Bit. An + * unexpected PCI INT# may be generated during PC-Card + * initialization even with the IRQ Routing Bit Set with some + * PC-Cards. + * + * This is a two part issue. The first part is that some of + * our older controllers have an issue in which the slot's PCI + * INT# is NOT qualified by the IRQ routing bit (PCI reg. 3Eh + * bit 7). Regardless of the IRQ routing bit, if NO ISA IRQ + * is selected (ExCA register 03h bits 3:0, of the slot, are + * cleared) we will generate INT# if IREQ# is asserted. The + * second part is because some PC-Cards prematurally assert + * IREQ# before the ExCA registers are fully programmed. This + * in turn asserts INT# because ExCA register 03h bits 3:0 + * (ISA IRQ Select) are not yet programmed. + * + * The fix for this issue, which will work for any controller + * (old or new), is to set ExCA register 03h bits 3:0 = 0001b + * (select IRQ1), of the slot, before turning on slot power. + * Selecting IRQ1 will result in INT# NOT being asserted + * (because IRQ1 is selected), and IRQ1 won't be asserted + * because our controllers don't generate IRQ1. + * + * Other, non O2Micro controllers will generate irq 1 in some + * situations, so we can't do this hack for everybody. Reports of + * keyboard controller's interrupts being suppressed occurred when + * we did this. + */ + reg = exca_getb(&sc->exca[0], EXCA_INTR); + exca_putb(&sc->exca[0], EXCA_INTR, (reg & 0xf0) | 1); + return (reg); +} + +/* + * Restore the damage that cbb_o2micro_power_hack does to EXCA_INTR so + * we don't have an interrupt storm on power on. This has the efect of + * disabling card status change interrupts for the duration of poweron. + */ +static void +cbb_o2micro_power_hack2(struct cbb_softc *sc, uint8_t reg) +{ + exca_putb(&sc->exca[0], EXCA_INTR, reg); +} + +int cbb_power(device_t brdev, int volts) { - uint32_t status, sock_ctrl; + uint32_t status, sock_ctrl, mask; struct cbb_softc *sc = device_get_softc(brdev); - int timeout; - uint32_t sockevent; - - DEVPRINTF((sc->dev, "cbb_power: %s and %s [%x]\n", - (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" : - (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" : - (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" : - (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" : - (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" : - (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" : - "VCC-UNKNOWN", - (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" : - (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V" : - (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC" : - (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" : - "VPP-UNKNOWN", - volts)); + int cnt, sane; + int retval = 0; + int on = 0; + uint8_t reg = 0; - status = cbb_get(sc, CBB_SOCKET_STATE); sock_ctrl = cbb_get(sc, CBB_SOCKET_CONTROL); + sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK; switch (volts & CARD_VCCMASK) { - case CARD_VCC_UC: + case 5: + sock_ctrl |= CBB_SOCKET_CTRL_VCC_5V; + on++; break; - case CARD_VCC_5V: - if (CBB_SOCKET_STAT_5VCARD & status) { /* check 5 V card */ - sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK; - sock_ctrl |= CBB_SOCKET_CTRL_VCC_5V; - } else { - device_printf(sc->dev, - "BAD voltage request: no 5 V card\n"); - } + case 3: + sock_ctrl |= CBB_SOCKET_CTRL_VCC_3V; + on++; break; - case CARD_VCC_3V: - if (CBB_SOCKET_STAT_3VCARD & status) { - sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK; - sock_ctrl |= CBB_SOCKET_CTRL_VCC_3V; - } else { - device_printf(sc->dev, - "BAD voltage request: no 3.3 V card\n"); - } + case XV: + sock_ctrl |= CBB_SOCKET_CTRL_VCC_XV; + on++; + break; + case YV: + sock_ctrl |= CBB_SOCKET_CTRL_VCC_YV; + on++; break; - case CARD_VCC_0V: - sock_ctrl &= ~CBB_SOCKET_CTRL_VCCMASK; + case 0: break; default: return (0); /* power NEVER changed */ - break; } - switch (volts & CARD_VPPMASK) { - case CARD_VPP_UC: - break; - case CARD_VPP_0V: - sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK; - break; - case CARD_VPP_VCC: - sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK; - sock_ctrl |= ((sock_ctrl >> 4) & 0x07); - break; - case CARD_VPP_12V: - sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK; - sock_ctrl |= CBB_SOCKET_CTRL_VPP_12V; - break; - } + /* VPP == VCC */ + sock_ctrl &= ~CBB_SOCKET_CTRL_VPPMASK; + sock_ctrl |= ((sock_ctrl >> 4) & 0x07); if (cbb_get(sc, CBB_SOCKET_CONTROL) == sock_ctrl) return (1); /* no change necessary */ + DEVPRINTF((sc->dev, "cbb_power: %dV\n", volts)); + if (volts != 0 && sc->chipset == CB_O2MICRO) + reg = cbb_o2micro_power_hack(sc); + /* + * We have to mask the card change detect interrupt while we're + * messing with the power. It is allowed to bounce while we're + * messing with power as things settle down. In addition, we mask off + * the card's function interrupt by routing it via the ISA bus. This + * bit generally only affects 16bit cards. Some bridges allow one to + * set another bit to have it also affect 32bit cards. Since 32bit + * cards are required to be better behaved, we don't bother to get + * into those bridge specific features. + */ + mask = cbb_get(sc, CBB_SOCKET_MASK); + mask |= CBB_SOCKET_MASK_POWER; + mask &= ~CBB_SOCKET_MASK_CD; + cbb_set(sc, CBB_SOCKET_MASK, mask); + PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, + |CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN, 2); cbb_set(sc, CBB_SOCKET_CONTROL, sock_ctrl); - status = cbb_get(sc, CBB_SOCKET_STATE); - - /* - * XXX This busy wait is bogus. We should wait for a power - * interrupt and then whine if the status is bad. If we're - * worried about the card not coming up, then we should also - * schedule a timeout which we can cacel in the power interrupt. - */ - timeout = 20; - do { - DELAY(20*1000); - sockevent = cbb_get(sc, CBB_SOCKET_EVENT); - } while (!(sockevent & CBB_SOCKET_EVENT_POWER) && --timeout > 0); - /* reset event status */ - /* XXX should only reset EVENT_POWER */ - cbb_set(sc, CBB_SOCKET_EVENT, sockevent); - if (timeout < 0) { - kprintf ("VCC supply failed.\n"); - return (0); + if (on) { + crit_enter(); + cnt = sc->powerintr; + sane = 200; + while (!(cbb_get(sc, CBB_SOCKET_STATE) & CBB_STATE_POWER_CYCLE) && + cnt == sc->powerintr && sane-- > 0) + tsleep(&sc->power_cv, 0, "cbbpcv", hz / 10); + crit_exit(); + if (sane <= 0) + device_printf(sc->dev, "power timeout, doom?\n"); } - /* XXX - * delay 400 ms: thgough the standard defines that the Vcc set-up time - * is 20 ms, some PC-Card bridge requires longer duration. - * XXX Note: We should check the stutus AFTER the delay to give time - * for things to stabilize. - */ - DELAY(400*1000); - - if (status & CBB_SOCKET_STAT_BADVCC) { - device_printf(sc->dev, - "bad Vcc request. ctrl=0x%x, status=0x%x\n", - sock_ctrl ,status); - kprintf("cbb_power: %s and %s [%x]\n", - (volts & CARD_VCCMASK) == CARD_VCC_UC ? "CARD_VCC_UC" : - (volts & CARD_VCCMASK) == CARD_VCC_5V ? "CARD_VCC_5V" : - (volts & CARD_VCCMASK) == CARD_VCC_3V ? "CARD_VCC_3V" : - (volts & CARD_VCCMASK) == CARD_VCC_XV ? "CARD_VCC_XV" : - (volts & CARD_VCCMASK) == CARD_VCC_YV ? "CARD_VCC_YV" : - (volts & CARD_VCCMASK) == CARD_VCC_0V ? "CARD_VCC_0V" : - "VCC-UNKNOWN", - (volts & CARD_VPPMASK) == CARD_VPP_UC ? "CARD_VPP_UC" : - (volts & CARD_VPPMASK) == CARD_VPP_12V ? "CARD_VPP_12V": - (volts & CARD_VPPMASK) == CARD_VPP_VCC ? "CARD_VPP_VCC": - (volts & CARD_VPPMASK) == CARD_VPP_0V ? "CARD_VPP_0V" : - "VPP-UNKNOWN", - volts); - return (0); + /* + * After the power is good, we can turn off the power interrupt. + * However, the PC Card standard says that we must delay turning the + * CD bit back on for a bit to allow for bouncyness on power down + * (recall that we don't wait above for a power down, since we don't + * get an interrupt for that). We're called either from the suspend + * code in which case we don't want to turn card change on again, or + * we're called from the card insertion code, in which case the cbb + * thread will turn it on for us before it waits to be woken by a + * change event. + */ + cbb_clrb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_POWER); + status = cbb_get(sc, CBB_SOCKET_STATE); + if (on) { + if ((status & CBB_STATE_POWER_CYCLE) == 0) + device_printf(sc->dev, "Power not on?\n"); + } + if (status & CBB_STATE_BAD_VCC_REQ) { + device_printf(sc->dev, "Bad Vcc requested\n"); + /* XXX Do we want to do something to mitigate things here? */ + goto done; } - return (1); /* power changed correctly */ + PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, + & ~CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN, 2); + retval = 1; +done:; + if (volts != 0 && sc->chipset == CB_O2MICRO) + cbb_o2micro_power_hack2(sc, reg); + return (retval); +} + +static int +cbb_current_voltage(device_t brdev) +{ + struct cbb_softc *sc = device_get_softc(brdev); + uint32_t ctrl; + + ctrl = cbb_get(sc, CBB_SOCKET_CONTROL); + switch (ctrl & CBB_SOCKET_CTRL_VCCMASK) { + case CBB_SOCKET_CTRL_VCC_5V: + return CARD_5V_CARD; + case CBB_SOCKET_CTRL_VCC_3V: + return CARD_3V_CARD; + case CBB_SOCKET_CTRL_VCC_XV: + return CARD_XV_CARD; + case CBB_SOCKET_CTRL_VCC_YV: + return CARD_YV_CARD; + } + return 0; } /* * detect the voltage for the card, and set it. Since the power * used is the square of the voltage, lower voltages is a big win * and what Windows does (and what Microsoft prefers). The MS paper - * also talks about preferring the CIS entry as well. + * also talks about preferring the CIS entry as well, but that has + * to be done elsewhere. We also optimize power sequencing here + * and don't change things if we're already powered up at a supported + * voltage. + * + * In addition, we power up with OE disabled. We'll set it later + * in the power up sequence. */ static int cbb_do_power(device_t brdev) { - int voltage; + struct cbb_softc *sc = device_get_softc(brdev); + uint32_t voltage, curpwr; + uint32_t status; + + /* Don't enable OE (output enable) until power stable */ + exca_clrb(&sc->exca[0], EXCA_PWRCTL, EXCA_PWRCTL_OE); - /* Prefer lowest voltage supported */ voltage = cbb_detect_voltage(brdev); - cbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); + curpwr = cbb_current_voltage(brdev); + status = cbb_get(sc, CBB_SOCKET_STATE); + if ((status & CBB_STATE_POWER_CYCLE) && (voltage & curpwr)) + return 0; + /* Prefer lowest voltage supported */ + cbb_power(brdev, CARD_OFF); if (voltage & CARD_YV_CARD) - cbb_power(brdev, CARD_VCC_YV | CARD_VPP_VCC); + cbb_power(brdev, CARD_VCC(YV)); else if (voltage & CARD_XV_CARD) - cbb_power(brdev, CARD_VCC_XV | CARD_VPP_VCC); + cbb_power(brdev, CARD_VCC(XV)); else if (voltage & CARD_3V_CARD) - cbb_power(brdev, CARD_VCC_3V | CARD_VPP_VCC); + cbb_power(brdev, CARD_VCC(3)); else if (voltage & CARD_5V_CARD) - cbb_power(brdev, CARD_VCC_5V | CARD_VPP_VCC); + cbb_power(brdev, CARD_VCC(5)); else { device_printf(brdev, "Unknown card voltage\n"); return (ENXIO); @@ -1259,19 +922,23 @@ static void cbb_cardbus_reset(device_t brdev) { struct cbb_softc *sc = device_get_softc(brdev); - int delay_us; + int delay; - delay_us = sc->chipset == CB_RF5C47X ? 400*1000 : 20*1000; + /* + * 20ms is necessary for most bridges. For some reason, the Ricoh + * RF5C47x bridges need 400ms. + */ + delay = sc->chipset == CB_RF5C47X ? 400 : 20; PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, |CBBM_BRIDGECTRL_RESET, 2); - DELAY(delay_us); + tsleep(sc, 0, "cbbP3", hz * delay / 1000); /* If a card exists, unreset it! */ - if ((cbb_get(sc, CBB_SOCKET_STATE) & CBB_SOCKET_STAT_CD) == 0) { + if (CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) { PCI_MASK_CONFIG(brdev, CBBR_BRIDGECTRL, &~CBBM_BRIDGECTRL_RESET, 2); - DELAY(delay_us); + tsleep(sc, 0, "cbbP3", hz * delay / 1000); } } @@ -1281,8 +948,7 @@ cbb_cardbus_power_enable_socket(device_t brdev, device_t child) struct cbb_softc *sc = device_get_softc(brdev); int err; - if ((cbb_get(sc, CBB_SOCKET_STATE) & CBB_SOCKET_STAT_CD) == - CBB_SOCKET_STAT_CD) + if (!CBB_CARD_PRESENT(cbb_get(sc, CBB_SOCKET_STATE))) return (ENODEV); err = cbb_do_power(brdev); @@ -1295,7 +961,7 @@ cbb_cardbus_power_enable_socket(device_t brdev, device_t child) static void cbb_cardbus_power_disable_socket(device_t brdev, device_t child) { - cbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); + cbb_power(brdev, CARD_OFF); cbb_cardbus_reset(brdev); } @@ -1366,6 +1032,13 @@ cbb_cardbus_auto_open(struct cbb_softc *sc, int type) else align = 1; + /* + * This looks somewhat bogus, and doesn't seem to really respect + * alignment. The alignment stuff is happening too late (it + * should happen at allocation time, not activation time) and + * this code looks generally to be too complex for the purpose + * it surves. + */ SLIST_FOREACH(rle, &sc->rl, link) { if (rle->type != type) ; @@ -1433,9 +1106,9 @@ cbb_cardbus_auto_open(struct cbb_softc *sc, int type) if (starts[1] != 0xffffffff) starts[1] -= starts[1] % align; if (ends[0] % align != 0) - ends[0] += align - ends[0]%align - 1; + ends[0] += align - ends[0] % align - 1; if (ends[1] % align != 0) - ends[1] += align - ends[1]%align - 1; + ends[1] += align - ends[1] % align - 1; } if (type == SYS_RES_MEMORY) { @@ -1483,11 +1156,12 @@ cbb_cardbus_deactivate_resource(device_t brdev, device_t child, int type, static struct resource * cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, - int *rid, u_long start, u_long end, u_long count, uint flags) + int *rid, u_long start, u_long end, u_long count, u_int flags) { struct cbb_softc *sc = device_get_softc(brdev); int tmp; struct resource *res; + u_long align; switch (type) { case SYS_RES_IRQ: @@ -1499,6 +1173,7 @@ cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, return (NULL); } start = end = tmp; + flags |= RF_SHAREABLE; break; case SYS_RES_IOPORT: if (start <= cbb_start_32_io) @@ -1511,6 +1186,13 @@ cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, start = cbb_start_mem; if (end < start) end = start; + if (count < CBB_MEMALIGN) + align = CBB_MEMALIGN; + else + align = count; + if (align > (1 << RF_ALIGNMENT(flags))) + flags = (flags & ~RF_ALIGNMENT_MASK) | + rman_make_alignment_flags(align); break; } @@ -1520,11 +1202,7 @@ cbb_cardbus_alloc_resource(device_t brdev, device_t child, int type, kprintf("cbb alloc res fail\n"); return (NULL); } - if (cbb_insert_res(sc, res, type, *rid)) { - BUS_RELEASE_RESOURCE(device_get_parent(brdev), child, type, - *rid, res); - return (NULL); - } + cbb_insert_res(sc, res, type, *rid); if (flags & RF_ACTIVE) if (bus_activate_resource(child, type, *rid, res) != 0) { bus_release_resource(child, type, *rid, res); @@ -1567,7 +1245,7 @@ cbb_pcic_power_enable_socket(device_t brdev, device_t child) err = cbb_do_power(brdev); if (err) return (err); - exca_reset(&sc->exca, child); + exca_reset(&sc->exca[0], child); return (0); } @@ -1580,22 +1258,22 @@ cbb_pcic_power_disable_socket(device_t brdev, device_t child) DPRINTF(("cbb_pcic_socket_disable\n")); /* reset signal asserting... */ - exca_clrb(&sc->exca, EXCA_INTR, EXCA_INTR_RESET); - DELAY(2*1000); + exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET); + tsleep(sc, 0, "cbbP1", hz / 100); /* power down the socket */ - cbb_power(brdev, CARD_VCC_0V | CARD_VPP_0V); - exca_clrb(&sc->exca, EXCA_PWRCTL, EXCA_PWRCTL_OE); + exca_clrb(&sc->exca[0], EXCA_PWRCTL, EXCA_PWRCTL_OE); + cbb_power(brdev, CARD_OFF); /* wait 300ms until power fails (Tpf). */ - DELAY(300 * 1000); + tsleep(sc, 0, "cbbP1", hz * 300 / 1000); } /************************************************************************/ /* POWER methods */ /************************************************************************/ -static int +int cbb_power_enable_socket(device_t brdev, device_t child) { struct cbb_softc *sc = device_get_softc(brdev); @@ -1606,7 +1284,7 @@ cbb_power_enable_socket(device_t brdev, device_t child) return (cbb_cardbus_power_enable_socket(brdev, child)); } -static void +void cbb_power_disable_socket(device_t brdev, device_t child) { struct cbb_softc *sc = device_get_softc(brdev); @@ -1615,30 +1293,13 @@ cbb_power_disable_socket(device_t brdev, device_t child) else cbb_cardbus_power_disable_socket(brdev, child); } + static int cbb_pcic_activate_resource(device_t brdev, device_t child, int type, int rid, struct resource *res) { - int err; struct cbb_softc *sc = device_get_softc(brdev); - if (!(rman_get_flags(res) & RF_ACTIVE)) { /* not already activated */ - switch (type) { - case SYS_RES_IOPORT: - err = exca_io_map(&sc->exca, 0, res); - break; - case SYS_RES_MEMORY: - err = exca_mem_map(&sc->exca, 0, res); - break; - default: - err = 0; - break; - } - if (err) - return (err); - - } - return (BUS_ACTIVATE_RESOURCE(device_get_parent(brdev), child, - type, rid, res)); + return (exca_activate_resource(&sc->exca[0], child, type, rid, res)); } static int @@ -1646,29 +1307,16 @@ cbb_pcic_deactivate_resource(device_t brdev, device_t child, int type, int rid, struct resource *res) { struct cbb_softc *sc = device_get_softc(brdev); - - if (rman_get_flags(res) & RF_ACTIVE) { /* if activated */ - switch (type) { - case SYS_RES_IOPORT: - if (exca_io_unmap_res(&sc->exca, res)) - return (ENOENT); - break; - case SYS_RES_MEMORY: - if (exca_mem_unmap_res(&sc->exca, res)) - return (ENOENT); - break; - } - } - return (BUS_DEACTIVATE_RESOURCE(device_get_parent(brdev), child, - type, rid, res)); + return (exca_deactivate_resource(&sc->exca[0], child, type, rid, res)); } static struct resource * cbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, uint flags) + u_long start, u_long end, u_long count, u_int flags) { struct resource *res = NULL; struct cbb_softc *sc = device_get_softc(brdev); + int align; int tmp; switch (type) { @@ -1677,8 +1325,13 @@ cbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid, start = cbb_start_mem; if (end < start) end = start; - flags = (flags & ~RF_ALIGNMENT_MASK) | - rman_make_alignment_flags(CBB_MEMALIGN); + if (count < CBB_MEMALIGN) + align = CBB_MEMALIGN; + else + align = count; + if (align > (1 << RF_ALIGNMENT(flags))) + flags = (flags & ~RF_ALIGNMENT_MASK) | + rman_make_alignment_flags(align); break; case SYS_RES_IOPORT: if (start < cbb_start_16_io) @@ -1702,11 +1355,7 @@ cbb_pcic_alloc_resource(device_t brdev, device_t child, int type, int *rid, start, end, count, flags & ~RF_ACTIVE); if (res == NULL) return (NULL); - if (cbb_insert_res(sc, res, type, *rid)) { - BUS_RELEASE_RESOURCE(device_get_parent(brdev), child, type, - *rid, res); - return (NULL); - } + cbb_insert_res(sc, res, type, *rid); if (flags & RF_ACTIVE) { if (bus_activate_resource(child, type, *rid, res) != 0) { bus_release_resource(child, type, *rid, res); @@ -1738,7 +1387,7 @@ cbb_pcic_release_resource(device_t brdev, device_t child, int type, /* PC Card methods */ /************************************************************************/ -static int +int cbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid, uint32_t flags) { @@ -1753,10 +1402,10 @@ cbb_pcic_set_res_flags(device_t brdev, device_t child, int type, int rid, "set_res_flags: specified rid not found\n"); return (ENOENT); } - return (exca_mem_set_flags(&sc->exca, res, flags)); + return (exca_mem_set_flags(&sc->exca[0], res, flags)); } -static int +int cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid, uint32_t cardaddr, uint32_t *deltap) { @@ -1769,7 +1418,7 @@ cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid, "set_memory_offset: specified rid not found\n"); return (ENOENT); } - return (exca_mem_set_offset(&sc->exca, res, cardaddr, deltap)); + return (exca_mem_set_offset(&sc->exca[0], res, cardaddr, deltap)); } /************************************************************************/ @@ -1777,7 +1426,7 @@ cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid, /************************************************************************/ -static int +int cbb_activate_resource(device_t brdev, device_t child, int type, int rid, struct resource *r) { @@ -1790,7 +1439,7 @@ cbb_activate_resource(device_t brdev, device_t child, int type, int rid, r)); } -static int +int cbb_deactivate_resource(device_t brdev, device_t child, int type, int rid, struct resource *r) { @@ -1804,9 +1453,9 @@ cbb_deactivate_resource(device_t brdev, device_t child, int type, rid, r)); } -static struct resource * +struct resource * cbb_alloc_resource(device_t brdev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, uint flags) + u_long start, u_long end, u_long count, u_int flags) { struct cbb_softc *sc = device_get_softc(brdev); @@ -1818,7 +1467,7 @@ cbb_alloc_resource(device_t brdev, device_t child, int type, int *rid, start, end, count, flags)); } -static int +int cbb_release_resource(device_t brdev, device_t child, int type, int rid, struct resource *r) { @@ -1832,7 +1481,7 @@ cbb_release_resource(device_t brdev, device_t child, int type, int rid, rid, r)); } -static int +int cbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result) { struct cbb_softc *sc = device_get_softc(brdev); @@ -1845,7 +1494,7 @@ cbb_read_ivar(device_t brdev, device_t child, int which, uintptr_t *result) return (ENOENT); } -static int +int cbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value) { struct cbb_softc *sc = device_get_softc(brdev); @@ -1862,23 +1511,26 @@ cbb_write_ivar(device_t brdev, device_t child, int which, uintptr_t value) /* PCI compat methods */ /************************************************************************/ -static int +int cbb_maxslots(device_t brdev) { return (0); } -static uint32_t +uint32_t cbb_read_config(device_t brdev, int b, int s, int f, int reg, int width) { + uint32_t rv; + /* * Pass through to the next ppb up the chain (i.e. our grandparent). */ - return (PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)), - b, s, f, reg, width)); + rv = PCIB_READ_CONFIG(device_get_parent(device_get_parent(brdev)), + b, s, f, reg, width); + return (rv); } -static void +void cbb_write_config(device_t brdev, int b, int s, int f, int reg, uint32_t val, int width) { @@ -1889,19 +1541,20 @@ cbb_write_config(device_t brdev, int b, int s, int f, int reg, uint32_t val, b, s, f, reg, val, width); } -static int +int cbb_suspend(device_t self) { int error = 0; struct cbb_softc *sc = device_get_softc(self); + cbb_set(sc, CBB_SOCKET_MASK, 0); /* Quiet hardware */ bus_teardown_intr(self, sc->irq_res, sc->intrhand); sc->flags &= ~CBB_CARD_OK; /* Card is bogus now */ error = bus_generic_suspend(self); return (error); } -static int +int cbb_resume(device_t self) { int error = 0; @@ -1921,15 +1574,15 @@ cbb_resume(device_t self) DEVPRINTF((self, "PCI Memory allocated: %08lx\n", rman_get_start(sc->base_res))); - cbb_chipinit(sc); + sc->chipinit(sc); /* reset interrupt -- Do we really need to do this? */ tmp = cbb_get(sc, CBB_SOCKET_EVENT); cbb_set(sc, CBB_SOCKET_EVENT, tmp); /* re-establish the interrupt. */ - if (bus_setup_intr(self, sc->irq_res, 0, cbb_intr, sc, - &sc->intrhand, NULL)) { + if (bus_setup_intr(self, sc->irq_res, INTR_MPSAFE, cbb_intr, sc, + &sc->intrhand, NULL)) { device_printf(self, "couldn't re-establish interrupt"); bus_release_resource(self, SYS_RES_IRQ, 0, sc->irq_res); bus_release_resource(self, SYS_RES_MEMORY, CBBR_SOCKBASE, @@ -1943,70 +1596,20 @@ cbb_resume(device_t self) cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); /* Signal the thread to wakeup. */ - wakeup(sc); + wakeup_one(&sc->generic_cv); error = bus_generic_resume(self); return (error); } -static int +int cbb_child_present(device_t self) { struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(self); uint32_t sockstate; sockstate = cbb_get(sc, CBB_SOCKET_STATE); - return ((sockstate & CBB_SOCKET_STAT_CD) != 0 && - (sc->flags & CBB_CARD_OK) != 0); + return (CBB_CARD_PRESENT(sockstate) && + (sc->flags & CBB_CARD_OK) == CBB_CARD_OK); } - -static device_method_t cbb_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, cbb_probe), - DEVMETHOD(device_attach, cbb_attach), - DEVMETHOD(device_detach, cbb_detach), - DEVMETHOD(device_shutdown, cbb_shutdown), - DEVMETHOD(device_suspend, cbb_suspend), - DEVMETHOD(device_resume, cbb_resume), - - /* bus methods */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_read_ivar, cbb_read_ivar), - DEVMETHOD(bus_write_ivar, cbb_write_ivar), - DEVMETHOD(bus_alloc_resource, cbb_alloc_resource), - DEVMETHOD(bus_release_resource, cbb_release_resource), - DEVMETHOD(bus_activate_resource, cbb_activate_resource), - DEVMETHOD(bus_deactivate_resource, cbb_deactivate_resource), - DEVMETHOD(bus_driver_added, cbb_driver_added), - DEVMETHOD(bus_child_detached, cbb_child_detached), - DEVMETHOD(bus_setup_intr, cbb_setup_intr), - DEVMETHOD(bus_teardown_intr, cbb_teardown_intr), - DEVMETHOD(bus_child_present, cbb_child_present), - - /* 16-bit card interface */ - DEVMETHOD(card_set_res_flags, cbb_pcic_set_res_flags), - DEVMETHOD(card_set_memory_offset, cbb_pcic_set_memory_offset), - - /* power interface */ - DEVMETHOD(power_enable_socket, cbb_power_enable_socket), - DEVMETHOD(power_disable_socket, cbb_power_disable_socket), - - /* pcib compatibility interface */ - DEVMETHOD(pcib_maxslots, cbb_maxslots), - DEVMETHOD(pcib_read_config, cbb_read_config), - DEVMETHOD(pcib_write_config, cbb_write_config), - {0,0} -}; - -static driver_t cbb_driver = { - "cbb", - cbb_methods, - sizeof(struct cbb_softc) -}; - -static devclass_t cbb_devclass; - -DRIVER_MODULE(cbb, pci, cbb_driver, cbb_devclass, 0, 0); -MODULE_VERSION(cbb, 1); -MODULE_DEPEND(cbb, exca, 1, 1, 1); diff --git a/sys/dev/pccard/pccbb/pccbb_isa.c b/sys/dev/pccard/pccbb/pccbb_isa.c new file mode 100644 index 0000000000..e7ab8900bf --- /dev/null +++ b/sys/dev/pccard/pccbb/pccbb_isa.c @@ -0,0 +1,214 @@ +/*- + * Copyright (c) 2002-2004 M. Warner Losh. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/dev/pccbb/pccbb_isa.c,v 1.4 2005/01/11 05:33:18 imp Exp $ + * $DragonFly: src/sys/dev/pccard/pccbb/pccbb_isa.c,v 1.1 2007/07/05 12:08:54 sephe Exp $ + */ + +/* + * Driver for ISA to PCMCIA bridges compliant with the Intel ExCA + * specification. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include +#include + +#include "power_if.h" +#include "card_if.h" + +/***************************************************************************** + * Configurable parameters. + *****************************************************************************/ + +/* sysctl vars */ +SYSCTL_NODE(_hw, OID_AUTO, pcic, CTLFLAG_RD, 0, "PCIC parameters"); + +static int isa_intr_mask = EXCA_INT_MASK_ALLOWED; +TUNABLE_INT("hw.cbb.intr_mask", &isa_intr_mask); +SYSCTL_INT(_hw_pcic, OID_AUTO, intr_mask, CTLFLAG_RD, &isa_intr_mask, 0, + "Mask of allowable interrupts for this laptop. The default is generally\n\ +correct, but some laptops do not route all the IRQ pins to the bridge to\n\ +save wires. Sometimes you need a more restrictive mask because some of the\n\ +hardware in your laptop may not have a driver so its IRQ might not be\n\ +allocated."); + +/***************************************************************************** + * End of configurable parameters. + *****************************************************************************/ + +#define DPRINTF(x) do { if (cbb_debug) kprintf x; } while (0) +#define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0) + +static struct isa_pnp_id pcic_ids[] = { + {EXCA_PNP_ACTIONTEC, NULL}, /* AEI0218 */ + {EXCA_PNP_IBM3765, NULL}, /* IBM3765 */ + {EXCA_PNP_82365, NULL}, /* PNP0E00 */ + {EXCA_PNP_CL_PD6720, NULL}, /* PNP0E01 */ + {EXCA_PNP_VLSI_82C146, NULL}, /* PNP0E02 */ + {EXCA_PNP_82365_CARDBUS, NULL}, /* PNP0E03 */ + {EXCA_PNP_SCM_SWAPBOX, NULL}, /* SCM0469 */ + {0} +}; + +/************************************************************************/ +/* Probe/Attach */ +/************************************************************************/ + +#if 0 + struct resource *res; + int rid; + int i; + + /* A little bogus, but go ahead and get the irq for CSC events */ + rid = 0; + res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE); + if (res == NULL) { + /* + * No IRQ specified, find one. This can be due to the PnP + * data not specifying any IRQ, or the default kernel not + * assinging an IRQ. + */ + for (i = 0; i < 16; i++) { + if (((1 << i) & isa_intr_mask) == 0) + continue; + res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, i, i, + 1, RF_ACTIVE); + if (res != NULL) + break; + } + if (res == NULL) + return (ENXIO); + bus_release_resource(dev, SYS_RES_IRQ, rid, res); + bus_set_resource(dev, SYS_RES_IRQ, 0, i, 1); + } else { + bus_release_resource(dev, SYS_RES_IRQ, rid, res); + } + if (res == NULL) { + device_printf(dev, "Cannot allocate mem\n"); + return (ENOMEM); + } +#endif + +static int +cbb_isa_activate(device_t dev) +{ + return (ENOMEM); +} + +static void +cbb_isa_deactivate(device_t dev) +{ +} + +static int +cbb_isa_probe(device_t dev) +{ + int error; + struct cbb_softc *sc = device_get_softc(dev); + + /* Check isapnp ids */ + error = ISA_PNP_PROBE(device_get_parent(dev), dev, pcic_ids); + if (error != 0 && error != ENOENT) + return (error); + + error = cbb_isa_activate(dev); + if (error != 0) + return (error); + + /* Check to make sure that we have actual hardware */ + error = exca_probe_slots(dev, &sc->exca[0], sc->bst, sc->bsh); + cbb_isa_deactivate(dev); + return (error); +} + +static int +cbb_isa_attach(device_t dev) +{ + return (ENOMEM); +} + +static device_method_t cbb_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, cbb_isa_probe), + DEVMETHOD(device_attach, cbb_isa_attach), + DEVMETHOD(device_detach, cbb_detach), + DEVMETHOD(device_shutdown, cbb_shutdown), + DEVMETHOD(device_suspend, cbb_suspend), + DEVMETHOD(device_resume, cbb_resume), + + /* bus methods */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, cbb_read_ivar), + DEVMETHOD(bus_write_ivar, cbb_write_ivar), + DEVMETHOD(bus_alloc_resource, cbb_alloc_resource), + DEVMETHOD(bus_release_resource, cbb_release_resource), + DEVMETHOD(bus_activate_resource, cbb_activate_resource), + DEVMETHOD(bus_deactivate_resource, cbb_deactivate_resource), + DEVMETHOD(bus_driver_added, cbb_driver_added), + DEVMETHOD(bus_child_detached, cbb_child_detached), + DEVMETHOD(bus_setup_intr, cbb_setup_intr), + DEVMETHOD(bus_teardown_intr, cbb_teardown_intr), + DEVMETHOD(bus_child_present, cbb_child_present), + + /* 16-bit card interface */ + DEVMETHOD(card_set_res_flags, cbb_pcic_set_res_flags), + DEVMETHOD(card_set_memory_offset, cbb_pcic_set_memory_offset), + + /* power interface */ + DEVMETHOD(power_enable_socket, cbb_power_enable_socket), + DEVMETHOD(power_disable_socket, cbb_power_disable_socket), + + {0,0} +}; + +static driver_t cbb_isa_driver = { + "cbb", + cbb_methods, + sizeof(struct cbb_softc) +}; + +DRIVER_MODULE(cbb, isa, cbb_isa_driver, cbb_devclass, 0, 0); +MODULE_DEPEND(cbb, exca, 1, 1, 1); diff --git a/sys/dev/pccard/pccbb/pccbb_pci.c b/sys/dev/pccard/pccbb/pccbb_pci.c new file mode 100644 index 0000000000..94702a0b7c --- /dev/null +++ b/sys/dev/pccard/pccbb/pccbb_pci.c @@ -0,0 +1,687 @@ +/*- + * Copyright (c) 2002-2004 M. Warner Losh. + * Copyright (c) 2000-2001 Jonathan Chen. + * All rights reserved. + * + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD: src/sys/dev/pccbb/pccbb_pci.c,v 1.15 2005/10/08 06:58:51 imp Exp $ + * $DragonFly: src/sys/dev/pccard/pccbb/pccbb_pci.c,v 1.1 2007/07/05 12:08:54 sephe Exp $ + */ + +/*- + * Copyright (c) 1998, 1999 and 2000 + * HAYAKAWA Koichi. All rights reserved. + * + * 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 HAYAKAWA Koichi. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * Driver for PCI to CardBus Bridge chips + * + * References: + * TI Datasheets: + * http://www-s.ti.com/cgi-bin/sc/generic2.cgi?family=PCI+CARDBUS+CONTROLLERS + * + * Written by Jonathan Chen + * The author would like to acknowledge: + * * HAYAKAWA Koichi: Author of the NetBSD code for the same thing + * * Warner Losh: Newbus/newcard guru and author of the pccard side of things + * * YAMAMOTO Shigeru: Author of another FreeBSD cardbus driver + * * David Cross: Author of the initial ugly hack for a specific cardbus card + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "power_if.h" +#include "card_if.h" +#include "pcib_if.h" + +#define DPRINTF(x) do { if (cbb_debug) kprintf x; } while (0) +#define DEVPRINTF(x) do { if (cbb_debug) device_printf x; } while (0) + +#define PCI_MASK_CONFIG(DEV,REG,MASK,SIZE) \ + pci_write_config(DEV, REG, pci_read_config(DEV, REG, SIZE) MASK, SIZE) +#define PCI_MASK2_CONFIG(DEV,REG,MASK1,MASK2,SIZE) \ + pci_write_config(DEV, REG, ( \ + pci_read_config(DEV, REG, SIZE) MASK1) MASK2, SIZE) + +static void cbb_chipinit(struct cbb_softc *sc); + +static struct yenta_chipinfo { + uint32_t yc_id; + const char *yc_name; + int yc_chiptype; +} yc_chipsets[] = { + /* Texas Instruments chips */ + {PCIC_ID_TI1031, "TI1031 PCI-PC Card Bridge", CB_TI113X}, + {PCIC_ID_TI1130, "TI1130 PCI-CardBus Bridge", CB_TI113X}, + {PCIC_ID_TI1131, "TI1131 PCI-CardBus Bridge", CB_TI113X}, + + {PCIC_ID_TI1210, "TI1210 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1211, "TI1211 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1220, "TI1220 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1221, "TI1221 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1225, "TI1225 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1250, "TI1250 PCI-CardBus Bridge", CB_TI125X}, + {PCIC_ID_TI1251, "TI1251 PCI-CardBus Bridge", CB_TI125X}, + {PCIC_ID_TI1251B,"TI1251B PCI-CardBus Bridge",CB_TI125X}, + {PCIC_ID_TI1260, "TI1260 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1260B,"TI1260B PCI-CardBus Bridge",CB_TI12XX}, + {PCIC_ID_TI1410, "TI1410 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1420, "TI1420 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1421, "TI1421 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1450, "TI1450 PCI-CardBus Bridge", CB_TI125X}, /*SIC!*/ + {PCIC_ID_TI1451, "TI1451 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1510, "TI1510 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI1520, "TI1520 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI4410, "TI4410 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI4450, "TI4450 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI4451, "TI4451 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI4510, "TI4510 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI6411, "TI6411 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI6420, "TI6420 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI6420SC, "TI6420 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI7410, "TI7410 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI7510, "TI7510 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI7610, "TI7610 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI7610M, "TI7610 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI7610SD, "TI7610 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_TI7610MS, "TI7610 PCI-CardBus Bridge", CB_TI12XX}, + + /* ENE */ + {PCIC_ID_ENE_CB710, "ENE CB710 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_ENE_CB720, "ENE CB720 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_ENE_CB1211, "ENE CB1211 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_ENE_CB1225, "ENE CB1225 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_ENE_CB1410, "ENE CB1410 PCI-CardBus Bridge", CB_TI12XX}, + {PCIC_ID_ENE_CB1420, "ENE CB1420 PCI-CardBus Bridge", CB_TI12XX}, + + /* Ricoh chips */ + {PCIC_ID_RICOH_RL5C465, "RF5C465 PCI-CardBus Bridge", CB_RF5C46X}, + {PCIC_ID_RICOH_RL5C466, "RF5C466 PCI-CardBus Bridge", CB_RF5C46X}, + {PCIC_ID_RICOH_RL5C475, "RF5C475 PCI-CardBus Bridge", CB_RF5C47X}, + {PCIC_ID_RICOH_RL5C476, "RF5C476 PCI-CardBus Bridge", CB_RF5C47X}, + {PCIC_ID_RICOH_RL5C477, "RF5C477 PCI-CardBus Bridge", CB_RF5C47X}, + {PCIC_ID_RICOH_RL5C478, "RF5C478 PCI-CardBus Bridge", CB_RF5C47X}, + + /* Toshiba products */ + {PCIC_ID_TOPIC95, "ToPIC95 PCI-CardBus Bridge", CB_TOPIC95}, + {PCIC_ID_TOPIC95B, "ToPIC95B PCI-CardBus Bridge", CB_TOPIC95}, + {PCIC_ID_TOPIC97, "ToPIC97 PCI-CardBus Bridge", CB_TOPIC97}, + {PCIC_ID_TOPIC100, "ToPIC100 PCI-CardBus Bridge", CB_TOPIC97}, + + /* Cirrus Logic */ + {PCIC_ID_CLPD6832, "CLPD6832 PCI-CardBus Bridge", CB_CIRRUS}, + {PCIC_ID_CLPD6833, "CLPD6833 PCI-CardBus Bridge", CB_CIRRUS}, + {PCIC_ID_CLPD6834, "CLPD6834 PCI-CardBus Bridge", CB_CIRRUS}, + + /* 02Micro */ + {PCIC_ID_OZ6832, "O2Micro OZ6832/6833 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ6860, "O2Micro OZ6836/6860 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ6872, "O2Micro OZ6812/6872 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ6912, "O2Micro OZ6912/6972 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ6922, "O2Micro OZ6922 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ6933, "O2Micro OZ6933 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ711E1, "O2Micro OZ711E1 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ711EC1, "O2Micro OZ711EC1/M1 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ711E2, "O2Micro OZ711E2 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ711M1, "O2Micro OZ711M1 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ711M2, "O2Micro OZ711M2 PCI-CardBus Bridge", CB_O2MICRO}, + {PCIC_ID_OZ711M3, "O2Micro OZ711M3 PCI-CardBus Bridge", CB_O2MICRO}, + + /* SMC */ + {PCIC_ID_SMC_34C90, "SMC 34C90 PCI-CardBus Bridge", CB_CIRRUS}, + + /* sentinel */ + {0 /* null id */, "unknown", CB_UNKNOWN}, +}; + +/************************************************************************/ +/* Probe/Attach */ +/************************************************************************/ + +static int +cbb_chipset(uint32_t pci_id, const char **namep) +{ + struct yenta_chipinfo *ycp; + + for (ycp = yc_chipsets; ycp->yc_id != 0 && pci_id != ycp->yc_id; ++ycp) + continue; + if (namep != NULL) + *namep = ycp->yc_name; + return (ycp->yc_chiptype); +} + +static int +cbb_pci_probe(device_t brdev) +{ + const char *name; + uint8_t progif, subclass, class; + + /* + * Do we know that we support the chipset? If so, then we + * accept the device. + */ + if (cbb_chipset(pci_get_devid(brdev), &name) != CB_UNKNOWN) { + device_set_desc(brdev, name); + return (0); + } + + /* + * We do support generic CardBus bridges. All that we've seen + * to date have progif 0 (the Yenta spec, and successors mandate + * this). + */ + class = pci_get_class(brdev); + subclass = pci_get_subclass(brdev); + progif = pci_get_progif(brdev); + if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_CARDBUS && + progif == 0) { + device_set_desc(brdev, "PCI-CardBus Bridge"); + return (0); + } + return (ENXIO); +} + +/* + * Still need this because the pci code only does power for type 0 + * header devices. + */ +static void +cbb_powerstate_d0(device_t dev) +{ + u_int32_t membase, irq; + + if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { + /* Save important PCI config data. */ + membase = pci_read_config(dev, CBBR_SOCKBASE, 4); + irq = pci_read_config(dev, PCIR_INTLINE, 4); + + /* Reset the power state. */ + device_printf(dev, "chip is in D%d power mode " + "-- setting to D0\n", pci_get_powerstate(dev)); + + pci_set_powerstate(dev, PCI_POWERSTATE_D0); + + /* Restore PCI config data. */ + pci_write_config(dev, CBBR_SOCKBASE, membase, 4); + pci_write_config(dev, PCIR_INTLINE, irq, 4); + } +} + +/* + * Print out the config space + */ +static void +cbb_print_config(device_t dev) +{ + int i; + + device_printf(dev, "PCI Configuration space:"); + for (i = 0; i < 256; i += 4) { + if (i % 16 == 0) + kprintf("\n 0x%02x: ", i); + kprintf("0x%08x ", pci_read_config(dev, i, 4)); + } + kprintf("\n"); +} + +static int +cbb_pci_attach(device_t brdev) +{ + static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */ + struct cbb_softc *sc = device_get_softc(brdev); + int rid, bus, pribus; + device_t parent, grand_parent; + + parent = device_get_parent(brdev); + grand_parent = device_get_parent(parent); + + sc->chipset = cbb_chipset(pci_get_devid(brdev), NULL); + sc->dev = brdev; + sc->cbdev = NULL; + sc->exca[0].pccarddev = NULL; + sc->secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1); + sc->subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1); + SLIST_INIT(&sc->rl); + cbb_powerstate_d0(brdev); + + rid = CBBR_SOCKBASE; + sc->base_res = bus_alloc_resource_any(brdev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (!sc->base_res) { + uint32_t sockbase; + + /* + * Generally, the BIOS will assign this memory for us. + * However, newer BIOSes do not because the MS design + * documents have mandated that this is for the OS + * to assign rather than the BIOS. This driver shouldn't + * be doing this, but until the pci bus code (or acpi) + * does this, we allow CardBus bridges to work on more + * machines. + */ + pci_write_config(brdev, rid, 0xffffffff, 4); + sockbase = pci_read_config(brdev, rid, 4); + sockbase = (sockbase & 0xfffffff0) & -(sockbase & 0xfffffff0); + sc->base_res = bus_generic_alloc_resource( + device_get_parent(brdev), brdev, SYS_RES_MEMORY, + &rid, 0x88000000, ~0, sockbase, + RF_ACTIVE | rman_make_alignment_flags(sockbase)); + if (!sc->base_res) { + device_printf(brdev, + "Could not grab register memory\n"); + return (ENOMEM); + } + pci_write_config(brdev, CBBR_SOCKBASE, + rman_get_start(sc->base_res), 4); + } else { + DEVPRINTF((brdev, "Found memory at %08lx\n", + rman_get_start(sc->base_res))); + } + + sc->bst = rman_get_bustag(sc->base_res); + sc->bsh = rman_get_bushandle(sc->base_res); + exca_init(&sc->exca[0], brdev, sc->bst, sc->bsh, CBB_EXCA_OFFSET); + sc->exca[0].flags |= EXCA_HAS_MEMREG_WIN; + sc->exca[0].chipset = EXCA_CARDBUS; + sc->chipinit = cbb_chipinit; + sc->chipinit(sc); + + /* + * This is a gross hack. We should be scanning the entire pci + * tree, assigning bus numbers in a way such that we (1) can + * reserve 1 extra bus just in case and (2) all sub busses + * are in an appropriate range. + */ + bus = pci_read_config(brdev, PCIR_SECBUS_2, 1); + pribus = pcib_get_bus(grand_parent); + DEVPRINTF((brdev, "Secondary bus is %d\n", bus)); + if (bus == 0) { + if (curr_bus_number <= pribus) + curr_bus_number = pribus + 1; + if (pci_read_config(brdev, PCIR_PRIBUS_2, 1) != pribus) { + DEVPRINTF((brdev, "Setting primary bus to %d\n", pribus)); + pci_write_config(brdev, PCIR_PRIBUS_2, pribus, 1); + } + bus = curr_bus_number; + DEVPRINTF((brdev, "Secondary bus set to %d subbus %d\n", bus, + bus + 1)); + sc->secbus = bus; + sc->subbus = bus + 1; + pci_write_config(brdev, PCIR_SECBUS_2, bus, 1); + pci_write_config(brdev, PCIR_SUBBUS_2, bus + 1, 1); + curr_bus_number += 2; + } + + /* attach children */ + sc->cbdev = device_add_child(brdev, "cardbus", -1); + if (sc->cbdev == NULL) + DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n")); + else if (device_probe_and_attach(sc->cbdev) != 0) + DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n")); + + sc->exca[0].pccarddev = device_add_child(brdev, "pccard", -1); + if (sc->exca[0].pccarddev == NULL) + DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n")); + else if (device_probe_and_attach(sc->exca[0].pccarddev) != 0) + DEVPRINTF((brdev, "WARNING: cannot attach pccard bus.\n")); + + /* Map and establish the interrupt. */ + rid = 0; + sc->irq_res = bus_alloc_resource_any(brdev, SYS_RES_IRQ, &rid, + RF_SHAREABLE | RF_ACTIVE); + if (sc->irq_res == NULL) { + kprintf("cbb: Unable to map IRQ...\n"); + goto err; + } + + if (bus_setup_intr(brdev, sc->irq_res, INTR_MPSAFE, cbb_intr, sc, + &sc->intrhand, NULL)) { + device_printf(brdev, "couldn't establish interrupt"); + goto err; + } + + /* reset 16-bit pcmcia bus */ + exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET); + + /* turn off power */ + cbb_power(brdev, CARD_OFF); + + /* CSC Interrupt: Card detect interrupt on */ + cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD); + + /* reset interrupt */ + cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT)); + + if (bootverbose) + cbb_print_config(brdev); + + /* Start the thread */ + if (kthread_create(cbb_event_thread, sc, &sc->event_thread, + "%s", device_get_nameunit(brdev))) { + device_printf(brdev, "unable to create event thread.\n"); + panic("cbb_create_event_thread"); + } + return (0); +err: + if (sc->irq_res) + bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res); + if (sc->base_res) { + bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE, + sc->base_res); + } + return (ENOMEM); +} + +static void +cbb_chipinit(struct cbb_softc *sc) +{ + uint32_t mux, sysctrl, reg; + + /* Set CardBus latency timer */ + if (pci_read_config(sc->dev, PCIR_SECLAT_1, 1) < 0x20) + pci_write_config(sc->dev, PCIR_SECLAT_1, 0x20, 1); + + /* Set PCI latency timer */ + if (pci_read_config(sc->dev, PCIR_LATTIMER, 1) < 0x20) + pci_write_config(sc->dev, PCIR_LATTIMER, 0x20, 1); + + /* Enable memory access */ + PCI_MASK_CONFIG(sc->dev, PCIR_COMMAND, + | PCIM_CMD_MEMEN + | PCIM_CMD_PORTEN + | PCIM_CMD_BUSMASTEREN, 2); + + /* disable Legacy IO */ + switch (sc->chipset) { + case CB_RF5C46X: + PCI_MASK_CONFIG(sc->dev, CBBR_BRIDGECTRL, + & ~(CBBM_BRIDGECTRL_RL_3E0_EN | + CBBM_BRIDGECTRL_RL_3E2_EN), 2); + break; + default: + pci_write_config(sc->dev, CBBR_LEGACY, 0x0, 4); + break; + } + + /* Use PCI interrupt for interrupt routing */ + PCI_MASK2_CONFIG(sc->dev, CBBR_BRIDGECTRL, + & ~(CBBM_BRIDGECTRL_MASTER_ABORT | + CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN), + | CBBM_BRIDGECTRL_WRITE_POST_EN, + 2); + + /* + * XXX this should be a function table, ala OLDCARD. This means + * that we could more easily support ISA interrupts for pccard + * cards if we had to. + */ + switch (sc->chipset) { + case CB_TI113X: + /* + * The TI 1031, TI 1130 and TI 1131 all require another bit + * be set to enable PCI routing of interrupts, and then + * a bit for each of the CSC and Function interrupts we + * want routed. + */ + PCI_MASK_CONFIG(sc->dev, CBBR_CBCTRL, + | CBBM_CBCTRL_113X_PCI_INTR | + CBBM_CBCTRL_113X_PCI_CSC | CBBM_CBCTRL_113X_PCI_IRQ_EN, + 1); + PCI_MASK_CONFIG(sc->dev, CBBR_DEVCTRL, + & ~(CBBM_DEVCTRL_INT_SERIAL | + CBBM_DEVCTRL_INT_PCI), 1); + break; + case CB_TI12XX: + /* + * Some TI 12xx (and [14][45]xx) based pci cards + * sometimes have issues with the MFUNC register not + * being initialized due to a bad EEPROM on board. + * Laptops that this matters on have this register + * properly initialized. + * + * The TI125X parts have a different register. + */ + mux = pci_read_config(sc->dev, CBBR_MFUNC, 4); + sysctrl = pci_read_config(sc->dev, CBBR_SYSCTRL, 4); + if (mux == 0) { + mux = (mux & ~CBBM_MFUNC_PIN0) | + CBBM_MFUNC_PIN0_INTA; + if ((sysctrl & CBBM_SYSCTRL_INTRTIE) == 0) + mux = (mux & ~CBBM_MFUNC_PIN1) | + CBBM_MFUNC_PIN1_INTB; + pci_write_config(sc->dev, CBBR_MFUNC, mux, 4); + } + /*FALLTHROUGH*/ + case CB_TI125X: + /* + * Disable zoom video. Some machines initialize this + * improperly and exerpience has shown that this helps + * prevent strange behavior. + */ + pci_write_config(sc->dev, CBBR_MMCTRL, 0, 4); + break; + case CB_O2MICRO: + /* + * Issue #1: INT# generated at the same time as + * selected ISA IRQ. When IREQ# or STSCHG# is active, + * in addition to the ISA IRQ being generated, INT# + * will also be generated at the same time. + * + * Some of the older controllers have an issue in + * which the slot's PCI INT# will be asserted whenever + * IREQ# or STSCGH# is asserted even if ExCA registers + * 03h or 05h have an ISA IRQ selected. + * + * The fix for this issue, which will work for any + * controller (old or new), is to set ExCA registers + * 3Ah (slot 0) & 7Ah (slot 1) bits 7:4 = 1010b. + * These bits are undocumented. By setting this + * register (of each slot) to '1010xxxxb' a routing of + * IREQ# to INTC# and STSCHG# to INTC# is selected. + * Since INTC# isn't connected there will be no + * unexpected PCI INT when IREQ# or STSCHG# is active. + * However, INTA# (slot 0) or INTB# (slot 1) will + * still be correctly generated if NO ISA IRQ is + * selected (ExCA regs 03h or 05h are cleared). + */ + reg = exca_getb(&sc->exca[0], EXCA_O2MICRO_CTRL_C); + reg = (reg & 0x0f) | + EXCA_O2CC_IREQ_INTC | EXCA_O2CC_STSCHG_INTC; + exca_putb(&sc->exca[0], EXCA_O2MICRO_CTRL_C, reg); + + break; + case CB_TOPIC97: + /* + * Disable Zoom Video, ToPIC 97, 100. + */ + pci_write_config(sc->dev, CBBR_TOPIC_ZV_CONTROL, 0, 1); + /* + * ToPIC 97, 100 + * At offset 0xa1: INTERRUPT CONTROL register + * 0x1: Turn on INT interrupts. + */ + PCI_MASK_CONFIG(sc->dev, CBBR_TOPIC_INTCTRL, + | CBBM_TOPIC_INTCTRL_INTIRQSEL, 1); + goto topic_common; + case CB_TOPIC95: + /* + * SOCKETCTRL appears to be TOPIC 95/B specific + */ + PCI_MASK_CONFIG(sc->dev, CBBR_TOPIC_SOCKETCTRL, + | CBBM_TOPIC_SOCKETCTRL_SCR_IRQSEL, 4); + + topic_common:; + /* + * At offset 0xa0: SLOT CONTROL + * 0x80 Enable CardBus Functionality + * 0x40 Enable CardBus and PC Card registers + * 0x20 Lock ID in exca regs + * 0x10 Write protect ID in config regs + * Clear the rest of the bits, which defaults the slot + * in legacy mode to 0x3e0 and offset 0. (legacy + * mode is determined elsewhere) + */ + pci_write_config(sc->dev, CBBR_TOPIC_SLOTCTRL, + CBBM_TOPIC_SLOTCTRL_SLOTON | + CBBM_TOPIC_SLOTCTRL_SLOTEN | + CBBM_TOPIC_SLOTCTRL_ID_LOCK | + CBBM_TOPIC_SLOTCTRL_ID_WP, 1); + + /* + * At offset 0xa3 Card Detect Control Register + * 0x80 CARDBUS enbale + * 0x01 Cleared for hardware change detect + */ + PCI_MASK2_CONFIG(sc->dev, CBBR_TOPIC_CDC, + | CBBM_TOPIC_CDC_CARDBUS, + & ~CBBM_TOPIC_CDC_SWDETECT, 4); + break; + } + + /* + * Need to tell ExCA registers to CSC interrupts route via PCI + * interrupts. There are two ways to do this. Once is to set + * INTR_ENABLE and the other is to set CSC to 0. Since both + * methods are mutually compatible, we do both. + */ + exca_putb(&sc->exca[0], EXCA_INTR, EXCA_INTR_ENABLE); + exca_putb(&sc->exca[0], EXCA_CSC_INTR, 0); + + cbb_disable_func_intr(sc); + + /* close all memory and io windows */ + pci_write_config(sc->dev, CBBR_MEMBASE0, 0xffffffff, 4); + pci_write_config(sc->dev, CBBR_MEMLIMIT0, 0, 4); + pci_write_config(sc->dev, CBBR_MEMBASE1, 0xffffffff, 4); + pci_write_config(sc->dev, CBBR_MEMLIMIT1, 0, 4); + pci_write_config(sc->dev, CBBR_IOBASE0, 0xffffffff, 4); + pci_write_config(sc->dev, CBBR_IOLIMIT0, 0, 4); + pci_write_config(sc->dev, CBBR_IOBASE1, 0xffffffff, 4); + pci_write_config(sc->dev, CBBR_IOLIMIT1, 0, 4); +} + +static int +cbb_route_interrupt(device_t pcib, device_t dev, int pin) +{ + struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(pcib); + + return (rman_get_start(sc->irq_res)); +} + +static device_method_t cbb_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, cbb_pci_probe), + DEVMETHOD(device_attach, cbb_pci_attach), + DEVMETHOD(device_detach, cbb_detach), + DEVMETHOD(device_shutdown, cbb_shutdown), + DEVMETHOD(device_suspend, cbb_suspend), + DEVMETHOD(device_resume, cbb_resume), + + /* bus methods */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_read_ivar, cbb_read_ivar), + DEVMETHOD(bus_write_ivar, cbb_write_ivar), + DEVMETHOD(bus_alloc_resource, cbb_alloc_resource), + DEVMETHOD(bus_release_resource, cbb_release_resource), + DEVMETHOD(bus_activate_resource, cbb_activate_resource), + DEVMETHOD(bus_deactivate_resource, cbb_deactivate_resource), + DEVMETHOD(bus_driver_added, cbb_driver_added), + DEVMETHOD(bus_child_detached, cbb_child_detached), + DEVMETHOD(bus_setup_intr, cbb_setup_intr), + DEVMETHOD(bus_teardown_intr, cbb_teardown_intr), + DEVMETHOD(bus_child_present, cbb_child_present), + + /* 16-bit card interface */ + DEVMETHOD(card_set_res_flags, cbb_pcic_set_res_flags), + DEVMETHOD(card_set_memory_offset, cbb_pcic_set_memory_offset), + + /* power interface */ + DEVMETHOD(power_enable_socket, cbb_power_enable_socket), + DEVMETHOD(power_disable_socket, cbb_power_disable_socket), + + /* pcib compatibility interface */ + DEVMETHOD(pcib_maxslots, cbb_maxslots), + DEVMETHOD(pcib_read_config, cbb_read_config), + DEVMETHOD(pcib_write_config, cbb_write_config), + DEVMETHOD(pcib_route_interrupt, cbb_route_interrupt), + + {0,0} +}; + +static driver_t cbb_driver = { + "cbb", + cbb_methods, + sizeof(struct cbb_softc) +}; + +DRIVER_MODULE(cbb, pci, cbb_driver, cbb_devclass, 0, 0); +MODULE_DEPEND(cbb, exca, 1, 1, 1); diff --git a/sys/dev/pccard/pccbb/pccbbdevid.h b/sys/dev/pccard/pccbb/pccbbdevid.h index b672f7a05a..357703f8b7 100644 --- a/sys/dev/pccard/pccbb/pccbbdevid.h +++ b/sys/dev/pccard/pccbb/pccbbdevid.h @@ -1,53 +1,66 @@ -/* - * Copyright (c) 2001 M. Warner Losh. All rights reserved. +/*- + * Copyright (c) 2001-2004 M. Warner Losh. All rights reserved. * * 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 immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. + * 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 AUTHOR ``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 AUTHOR 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. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. * - * $FreeBSD: src/sys/dev/pccbb/pccbbdevid.h,v 1.9 2002/08/10 06:35:03 imp Exp $ - * $DragonFly: src/sys/dev/pccard/pccbb/pccbbdevid.h,v 1.1 2004/02/10 07:55:47 joerg Exp $ + * $FreeBSD: src/sys/dev/pccbb/pccbbdevid.h,v 1.21 2005/09/29 20:41:04 imp Exp $ + * $DragonFly: src/sys/dev/pccard/pccbb/pccbbdevid.h,v 1.2 2007/07/05 12:08:54 sephe Exp $ */ /* Vendor/Device IDs */ -#define PCIC_ID_INTEL_82092AA 0x12218086ul /* 16bit I/O */ #define PCIC_ID_CLPD6729 0x11001013ul /* 16bit I/O */ #define PCIC_ID_CLPD6832 0x11101013ul #define PCIC_ID_CLPD6833 0x11131013ul #define PCIC_ID_CLPD6834 0x11121013ul -#define PCIC_ID_OMEGA_82C094 0x1221119bul /* 16bit I/O */ -#define PCIC_ID_OZ6729 0x67291217ul -#define PCIC_ID_OZ6730 0x673A1217ul +#define PCIC_ID_ENE_CB710 0x14111524ul +#define PCIC_ID_ENE_CB720 0x14211524ul /* ??? */ +#define PCIC_ID_ENE_CB1211 0x12111524ul /* ??? */ +#define PCIC_ID_ENE_CB1225 0x12251524ul /* ??? */ +#define PCIC_ID_ENE_CB1410 0x14101524ul +#define PCIC_ID_ENE_CB1420 0x14201524ul +#define PCIC_ID_INTEL_82092AA_0 0x12218086ul /* 16bit I/O */ +#define PCIC_ID_INTEL_82092AA_1 0x12228086ul /* 16bit I/O */ +#define PCIC_ID_OMEGA_82C094 0x1221119bul /* 16bit I/O */ +#define PCIC_ID_OZ6729 0x67291217ul /* 16bit I/O */ +#define PCIC_ID_OZ6730 0x673a1217ul /* 16bit I/O */ #define PCIC_ID_OZ6832 0x68321217ul /* Also 6833 */ #define PCIC_ID_OZ6860 0x68361217ul /* Also 6836 */ #define PCIC_ID_OZ6872 0x68721217ul /* Also 6812 */ #define PCIC_ID_OZ6912 0x69721217ul /* Also 6972 */ #define PCIC_ID_OZ6922 0x69251217ul #define PCIC_ID_OZ6933 0x69331217ul +#define PCIC_ID_OZ711EC1 0x71121217ul /* O2Micro 711EC1/M1 */ +#define PCIC_ID_OZ711E1 0x71131217ul /* O2Micro 711E1 */ +#define PCIC_ID_OZ711M1 0x71141217ul /* O2Micro 711M1 */ +#define PCIC_ID_OZ711E2 0x71e21217ul +#define PCIC_ID_OZ711M2 0x72121217ul +#define PCIC_ID_OZ711M3 0x72231217ul #define PCIC_ID_RICOH_RL5C465 0x04651180ul #define PCIC_ID_RICOH_RL5C466 0x04661180ul #define PCIC_ID_RICOH_RL5C475 0x04751180ul #define PCIC_ID_RICOH_RL5C476 0x04761180ul #define PCIC_ID_RICOH_RL5C477 0x04771180ul #define PCIC_ID_RICOH_RL5C478 0x04781180ul +#define PCIC_ID_SMC_34C90 0xb10610b3ul /* XXX */ #define PCIC_ID_TI1031 0xac13104cul #define PCIC_ID_TI1130 0xac12104cul #define PCIC_ID_TI1131 0xac15104cul @@ -67,11 +80,24 @@ #define PCIC_ID_TI1450 0xac1b104cul #define PCIC_ID_TI1451 0xac52104cul #define PCIC_ID_TI1510 0xac56104cul +#define PCIC_ID_TI1515 0xac58104cul #define PCIC_ID_TI1520 0xac55104cul +#define PCIC_ID_TI1530 0xac57104cul +#define PCIC_ID_TI1620 0xac54104cul #define PCIC_ID_TI4410 0xac41104cul #define PCIC_ID_TI4450 0xac40104cul #define PCIC_ID_TI4451 0xac42104cul #define PCIC_ID_TI4510 0xac44104cul +#define PCIC_ID_TI4520 0xac46104cul +#define PCIC_ID_TI6411 0x8031104cul /* PCI[67]x[12]1 */ +#define PCIC_ID_TI6420 0xac8d104cul /* PCI[67]x20 Smartcard dis */ +#define PCIC_ID_TI6420SC 0xac8e104cul /* PCI[67]x20 Smartcard en */ +#define PCIC_ID_TI7410 0xac49104cul +#define PCIC_ID_TI7510 0xac47104cul +#define PCIC_ID_TI7610 0xac48104cul +#define PCIC_ID_TI7610M 0xac4a104cul +#define PCIC_ID_TI7610SD 0xac4b104cul +#define PCIC_ID_TI7610MS 0xac4c104cul #define PCIC_ID_TOPIC95 0x06031179ul #define PCIC_ID_TOPIC95B 0x060a1179ul #define PCIC_ID_TOPIC97 0x060f1179ul @@ -81,7 +107,6 @@ * Other ID, from sources too vague to be reliable * Mfg model PCI ID * smc/Databook DB87144 0x310610b3 - * SMC/databook smc34c90 0xb10610b3 * Omega/Trident 82c194 0x01941023 * Omega/Trident 82c722 0x07221023? * Opti 82c814 0xc8141045 diff --git a/sys/dev/pccard/pccbb/pccbbreg.h b/sys/dev/pccard/pccbb/pccbbreg.h index 19fc85f04a..d4eb32a8d9 100644 --- a/sys/dev/pccard/pccbb/pccbbreg.h +++ b/sys/dev/pccard/pccbb/pccbbreg.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 2000,2001 Jonathan Chen. * All rights reserved. * @@ -6,18 +6,16 @@ * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -25,8 +23,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/pccbb/pccbbreg.h,v 1.12 2002/11/23 23:09:45 imp Exp $ - * $DragonFly: src/sys/dev/pccard/pccbb/pccbbreg.h,v 1.1 2004/02/10 07:55:47 joerg Exp $ + * $FreeBSD: src/sys/dev/pccbb/pccbbreg.h,v 1.17 2005/07/17 19:31:39 imp Exp $ + * $DragonFly: src/sys/dev/pccard/pccbb/pccbbreg.h,v 1.2 2007/07/05 12:08:54 sephe Exp $ */ /* @@ -76,14 +74,16 @@ #define CBBR_IOBASE1 0x34 /* len=4 */ #define CBBR_IOLIMIT1 0x38 /* len=4 */ #define CBB_MEMALIGN 4096 +#define CBB_MEMALIGN_BITS 12 #define CBB_IOALIGN 4 +#define CBB_IOALIGN_BITS 2 #define CBBR_INTRLINE 0x3c /* len=1 */ #define CBBR_INTRPIN 0x3d /* len=1 */ #define CBBR_BRIDGECTRL 0x3e /* len=2 */ # define CBBM_BRIDGECTRL_MASTER_ABORT 0x0020 # define CBBM_BRIDGECTRL_RESET 0x0040 -# define CBBM_BRIDGECTRL_INTR_IREQ_EN 0x0080 +# define CBBM_BRIDGECTRL_INTR_IREQ_ISA_EN 0x0080 # define CBBM_BRIDGECTRL_PREFETCH_0 0x0100 # define CBBM_BRIDGECTRL_PREFETCH_1 0x0200 # define CBBM_BRIDGECTRL_WRITE_POST_EN 0x0400 @@ -184,25 +184,25 @@ #define CBB_SOCKET_MASK_POWER 0x08 /* Power Cycle */ #define CBB_SOCKET_MASK_ALL 0x0F /* all of the above */ -#define CBB_SOCKET_STAT_CARDSTS 0x00000001 /* Card Status Change */ -#define CBB_SOCKET_STAT_CD1 0x00000002 /* Card Detect 1 */ -#define CBB_SOCKET_STAT_CD2 0x00000004 /* Card Detect 2 */ -#define CBB_SOCKET_STAT_CD 0x00000006 /* Card Detect all */ -#define CBB_SOCKET_STAT_PWRCYCLE 0x00000008 /* Power Cycle */ -#define CBB_SOCKET_STAT_16BIT 0x00000010 /* 16-bit Card */ -#define CBB_SOCKET_STAT_CB 0x00000020 /* Cardbus Card */ -#define CBB_SOCKET_STAT_IREQ 0x00000040 /* Ready */ -#define CBB_SOCKET_STAT_NOTCARD 0x00000080 /* Unrecognized Card */ -#define CBB_SOCKET_STAT_DATALOST 0x00000100 /* Data Lost */ -#define CBB_SOCKET_STAT_BADVCC 0x00000200 /* Bad VccRequest */ -#define CBB_SOCKET_STAT_5VCARD 0x00000400 /* 5 V Card */ -#define CBB_SOCKET_STAT_3VCARD 0x00000800 /* 3.3 V Card */ -#define CBB_SOCKET_STAT_XVCARD 0x00001000 /* X.X V Card */ -#define CBB_SOCKET_STAT_YVCARD 0x00002000 /* Y.Y V Card */ -#define CBB_SOCKET_STAT_5VSOCK 0x10000000 /* 5 V Socket */ -#define CBB_SOCKET_STAT_3VSOCK 0x20000000 /* 3.3 V Socket */ -#define CBB_SOCKET_STAT_XVSOCK 0x40000000 /* X.X V Socket */ -#define CBB_SOCKET_STAT_YVSOCK 0x80000000 /* Y.Y V Socket */ +#define CBB_STATE_CSTCHG (1UL << 0) /* Card Status Change */ +#define CBB_STATE_CD1_CHANGE (1UL << 1) /* Card Detect 1 */ +#define CBB_STATE_CD2_CHANGE (1UL << 2) /* Card Detect 2 */ +#define CBB_STATE_CD (3UL << 1) /* Card Detect all */ +#define CBB_STATE_POWER_CYCLE (1UL << 3) /* Power Cycle */ +#define CBB_STATE_R2_CARD (1UL << 4) /* 16-bit Card */ +#define CBB_STATE_CB_CARD (1UL << 5) /* Cardbus Card */ +#define CBB_STATE_IREQ (1UL << 6) /* Ready */ +#define CBB_STATE_NOT_A_CARD (1UL << 7) /* Unrecognized Card */ +#define CBB_STATE_DATA_LOST (1UL << 8) /* Data Lost */ +#define CBB_STATE_BAD_VCC_REQ (1UL << 9) /* Bad VccRequest */ +#define CBB_STATE_5VCARD (1UL << 10) /* 5 V Card */ +#define CBB_STATE_3VCARD (1UL << 11) /* 3.3 V Card */ +#define CBB_STATE_XVCARD (1UL << 12) /* X.X V Card */ +#define CBB_STATE_YVCARD (1UL << 13) /* Y.Y V Card */ +#define CBB_STATE_5VSOCK (1UL << 28) /* 5 V Socket */ +#define CBB_STATE_3VSOCK (1UL << 29) /* 3.3 V Socket */ +#define CBB_STATE_XVSOCK (1UL << 30) /* X.X V Socket */ +#define CBB_STATE_YVSOCK (1UL << 31) /* Y.Y V Socket */ #define CBB_SOCKET_CTRL_VPPMASK 0x07 #define CBB_SOCKET_CTRL_VPP_OFF 0x00 @@ -221,6 +221,19 @@ #define CBB_SOCKET_CTRL_STOPCLK 0x80 +#define CBB_FORCE_CV_TEST (1UL << 14) +#define CBB_FORCE_3VCARD (1UL << 11) +#define CBB_FORCE_5VCARD (1UL << 10) +#define CBB_FORCE_BAD_VCC_REQ (1UL << 9) +#define CBB_FORCE_DATA_LOST (1UL << 8) +#define CBB_FORCE_NOT_A_CARD (1UL << 7) +#define CBB_FORCE_CB_CARD (1UL << 5) +#define CBB_FORCE_R2_CARD (1UL << 4) +#define CBB_FORCE_POWER_CYCLE (1UL << 3) +#define CBB_FORCE_CD2_CHANGE (1UL << 2) +#define CBB_FORCE_CD1_CHANGE (1UL << 1) +#define CBB_FORCE_CSTCHG (1UL << 0) + #include #define CBB_SOCKET_EVENT 0x00 diff --git a/sys/dev/pccard/pccbb/pccbbvar.h b/sys/dev/pccard/pccbb/pccbbvar.h index 7090fb40f3..9671796873 100644 --- a/sys/dev/pccard/pccbb/pccbbvar.h +++ b/sys/dev/pccard/pccbb/pccbbvar.h @@ -1,4 +1,5 @@ -/* +/*- + * Copyright (c) 2003-2004 Warner Losh. * Copyright (c) 2000,2001 Jonathan Chen. * All rights reserved. * @@ -6,18 +7,16 @@ * 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, - * without modification, immediately at the beginning of the file. + * 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. + * 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 AUTHOR 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 AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 @@ -25,8 +24,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/pccbb/pccbbvar.h,v 1.15 2002/10/07 23:11:29 imp Exp $ - * $DragonFly: src/sys/dev/pccard/pccbb/pccbbvar.h,v 1.2 2005/12/19 01:18:58 dillon Exp $ + * $FreeBSD: src/sys/dev/pccbb/pccbbvar.h,v 1.26 2005/10/08 06:58:51 imp Exp $ + * $DragonFly: src/sys/dev/pccard/pccbb/pccbbvar.h,v 1.3 2007/07/05 12:08:54 sephe Exp $ */ /* @@ -34,10 +33,11 @@ */ struct cbb_intrhand { - driver_intr_t *intr; - void *arg; + driver_intr_t *intr; + void *arg; + struct cbb_softc *sc; + void *cookie; struct lwkt_serialize *serializer; - STAILQ_ENTRY(cbb_intrhand) entries; }; struct cbb_reslist { @@ -53,10 +53,11 @@ struct cbb_reslist { }; #define CBB_AUTO_OPEN_SMALLHOLE 0x100 +#define CBB_NSLOTS 4 struct cbb_softc { device_t dev; - struct exca_softc exca; + struct exca_softc exca[CBB_NSLOTS]; struct resource *base_res; struct resource *irq_res; void *intrhand; @@ -64,10 +65,8 @@ struct cbb_softc { bus_space_handle_t bsh; u_int8_t secbus; u_int8_t subbus; - struct lock lock; u_int32_t flags; #define CBB_CARD_OK 0x08000000 -#define CBB_KLUDGE_ALLOC 0x10000000 #define CBB_16BIT_CARD 0x20000000 #define CBB_KTHREAD_RUNNING 0x40000000 #define CBB_KTHREAD_DONE 0x80000000 @@ -81,13 +80,15 @@ struct cbb_softc { #define CB_CIRRUS 6 /* Cirrus Logic CLPD683x */ #define CB_TOPIC95 7 /* Toshiba ToPIC95 */ #define CB_TOPIC97 8 /* Toshiba ToPIC97/100 */ +#define CB_O2MICRO 9 /* O2Micro chips */ SLIST_HEAD(, cbb_reslist) rl; - STAILQ_HEAD(, cbb_intrhand) intr_handlers; - device_t cbdev; - device_t pccarddev; - struct thread *event_thread; + void (*chipinit)(struct cbb_softc *); + volatile int powerintr; + + int power_cv; + int generic_cv; }; /* result of detect_card */ @@ -98,15 +99,81 @@ struct cbb_softc { #define CARD_YV_CARD 0x08 /* for power_socket */ -#define CARD_VCC_UC 0x0000 -#define CARD_VCC_3V 0x0001 -#define CARD_VCC_XV 0x0002 -#define CARD_VCC_YV 0x0003 -#define CARD_VCC_0V 0x0004 -#define CARD_VCC_5V 0x0005 -#define CARD_VCCMASK 0x000f -#define CARD_VPP_UC 0x0000 -#define CARD_VPP_VCC 0x0010 -#define CARD_VPP_12V 0x0030 -#define CARD_VPP_0V 0x0040 -#define CARD_VPPMASK 0x00f0 +#define CARD_VCC(X) (X) +#define CARD_VPP_VCC 0xf0 +#define CARD_VCCMASK 0xf +#define CARD_VCCSHIFT 0 +#define XV 2 +#define YV 1 + +#define CARD_OFF (CARD_VCC(0)) + +extern int cbb_debug; +extern devclass_t cbb_devclass; + +int cbb_activate_resource(device_t brdev, device_t child, + int type, int rid, struct resource *r); +struct resource *cbb_alloc_resource(device_t brdev, device_t child, + int type, int *rid, u_long start, u_long end, u_long count, + u_int flags); +void cbb_child_detached(device_t brdev, device_t child); +int cbb_child_present(device_t self); +int cbb_deactivate_resource(device_t brdev, device_t child, + int type, int rid, struct resource *r); +int cbb_detach(device_t brdev); +void cbb_disable_func_intr(struct cbb_softc *sc); +void cbb_driver_added(device_t brdev, driver_t *driver); +void cbb_event_thread(void *arg); +void cbb_intr(void *arg); +int cbb_maxslots(device_t brdev); +int cbb_pcic_set_memory_offset(device_t brdev, device_t child, int rid, + uint32_t cardaddr, uint32_t *deltap); +int cbb_pcic_set_res_flags(device_t brdev, device_t child, int type, + int rid, uint32_t flags); +int cbb_power(device_t brdev, int volts); +int cbb_power_enable_socket(device_t brdev, device_t child); +void cbb_power_disable_socket(device_t brdev, device_t child); +uint32_t cbb_read_config(device_t brdev, int b, int s, int f, + int reg, int width); +int cbb_read_ivar(device_t brdev, device_t child, int which, + uintptr_t *result); +int cbb_release_resource(device_t brdev, device_t child, + int type, int rid, struct resource *r); +int cbb_resume(device_t self); +int cbb_setup_intr(device_t dev, device_t child, struct resource *irq, + int flags, driver_intr_t *intr, void *arg, void **cookiep, + lwkt_serialize_t serializer); +int cbb_shutdown(device_t brdev); +int cbb_suspend(device_t self); +int cbb_teardown_intr(device_t dev, device_t child, struct resource *irq, + void *cookie); +void cbb_write_config(device_t brdev, int b, int s, int f, + int reg, uint32_t val, int width); +int cbb_write_ivar(device_t brdev, device_t child, int which, + uintptr_t value); + +/* + */ +static __inline void +cbb_set(struct cbb_softc *sc, uint32_t reg, uint32_t val) +{ + bus_space_write_4(sc->bst, sc->bsh, reg, val); +} + +static __inline uint32_t +cbb_get(struct cbb_softc *sc, uint32_t reg) +{ + return (bus_space_read_4(sc->bst, sc->bsh, reg)); +} + +static __inline void +cbb_setb(struct cbb_softc *sc, uint32_t reg, uint32_t bits) +{ + cbb_set(sc, reg, cbb_get(sc, reg) | bits); +} + +static __inline void +cbb_clrb(struct cbb_softc *sc, uint32_t reg, uint32_t bits) +{ + cbb_set(sc, reg, cbb_get(sc, reg) & ~bits); +} diff --git a/sys/dev/serial/sio/sio_pccard.c b/sys/dev/serial/sio/sio_pccard.c index a7189f72ff..5db1dad917 100644 --- a/sys/dev/serial/sio/sio_pccard.c +++ b/sys/dev/serial/sio/sio_pccard.c @@ -30,7 +30,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/serial/sio/sio_pccard.c,v 1.6 2007/04/12 18:35:09 swildner Exp $ + * $DragonFly: src/sys/dev/serial/sio/sio_pccard.c,v 1.7 2007/07/05 12:08:54 sephe Exp $ */ #include #include @@ -45,6 +45,7 @@ #include "sioreg.h" #include "sio_private.h" +#include #include #include #include -- 2.41.0