pccardvar.h revision 66200
1105197Ssam/* $NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 enami Exp $ */ 2105197Ssam/* $FreeBSD: head/sys/dev/pccard/pccardvar.h 66200 2000-09-22 01:15:26Z imp $ */ 3105197Ssam 4139823Simp/* 5105197Ssam * Copyright (c) 1997 Marc Horowitz. All rights reserved. 6105197Ssam * 7105197Ssam * Redistribution and use in source and binary forms, with or without 8105197Ssam * modification, are permitted provided that the following conditions 9105197Ssam * are met: 10105197Ssam * 1. Redistributions of source code must retain the above copyright 11105197Ssam * notice, this list of conditions and the following disclaimer. 12105197Ssam * 2. Redistributions in binary form must reproduce the above copyright 13105197Ssam * notice, this list of conditions and the following disclaimer in the 14105197Ssam * documentation and/or other materials provided with the distribution. 15105197Ssam * 3. All advertising materials mentioning features or use of this software 16105197Ssam * must display the following acknowledgement: 17105197Ssam * This product includes software developed by Marc Horowitz. 18105197Ssam * 4. The name of the author may not be used to endorse or promote products 19105197Ssam * derived from this software without specific prior written permission. 20105197Ssam * 21105197Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22105197Ssam * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23105197Ssam * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24105197Ssam * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25105197Ssam * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26105197Ssam * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27105197Ssam * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28105197Ssam * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29105197Ssam * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30105197Ssam * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31105197Ssam */ 32105197Ssam 33105197Ssam#include <sys/types.h> 34105197Ssam#include <sys/queue.h> 35105197Ssam 36105197Ssam#include <machine/bus.h> 37105197Ssam 38105197Ssamextern int pccard_verbose; 39105197Ssam 40105197Ssam/* 41105197Ssam * Contains information about mapped/allocated i/o spaces. 42105197Ssam */ 43105197Ssamstruct pccard_io_handle { 44105197Ssam bus_space_tag_t iot; /* bus space tag (from chipset) */ 45119643Ssam bus_space_handle_t ioh; /* mapped space handle */ 46119643Ssam bus_addr_t addr; /* resulting address in bus space */ 47105197Ssam bus_size_t size; /* size of i/o space */ 48105197Ssam int flags; /* misc. information */ 49105197Ssam int width; 50105197Ssam}; 51105197Ssam 52105197Ssam#define PCCARD_IO_ALLOCATED 0x01 /* i/o space was allocated */ 53105197Ssam 54105197Ssam/* 55105197Ssam * Contains information about allocated memory space. 56105197Ssam */ 57158767Spjdstruct pccard_mem_handle { 58105197Ssam bus_space_tag_t memt; /* bus space tag (from chipset) */ 59105197Ssam bus_space_handle_t memh; /* mapped space handle */ 60105197Ssam bus_addr_t addr; /* resulting address in bus space */ 61105197Ssam bus_size_t size; /* size of mem space */ 62105197Ssam bus_size_t realsize; /* how much we really allocated */ 63105197Ssam long offset; 64105197Ssam int kind; 65105197Ssam}; 66105197Ssam 67105197Ssam/* pccard itself */ 68105197Ssam 69105197Ssam#define PCCARD_CFE_MWAIT_REQUIRED 0x0001 70105197Ssam#define PCCARD_CFE_RDYBSY_ACTIVE 0x0002 71105197Ssam#define PCCARD_CFE_WP_ACTIVE 0x0004 72105197Ssam#define PCCARD_CFE_BVD_ACTIVE 0x0008 73105197Ssam#define PCCARD_CFE_IO8 0x0010 74105197Ssam#define PCCARD_CFE_IO16 0x0020 75105197Ssam#define PCCARD_CFE_IRQSHARE 0x0040 76105197Ssam#define PCCARD_CFE_IRQPULSE 0x0080 77105197Ssam#define PCCARD_CFE_IRQLEVEL 0x0100 78105197Ssam#define PCCARD_CFE_POWERDOWN 0x0200 79105197Ssam#define PCCARD_CFE_READONLY 0x0400 80105197Ssam#define PCCARD_CFE_AUDIO 0x0800 81105197Ssam 82105197Ssamstruct pccard_config_entry { 83105197Ssam int number; 84105197Ssam u_int32_t flags; 85105197Ssam int iftype; 86105197Ssam int num_iospace; 87105197Ssam 88105197Ssam /* 89105197Ssam * The card will only decode this mask in any case, so we can 90105197Ssam * do dynamic allocation with this in mind, in case the suggestions 91105197Ssam * below are no good. 92105197Ssam */ 93105197Ssam u_long iomask; 94105197Ssam struct { 95105197Ssam u_long length; 96105197Ssam u_long start; 97105197Ssam } iospace[4]; /* XXX this could be as high as 16 */ 98105197Ssam u_int16_t irqmask; 99105197Ssam int num_memspace; 100105197Ssam struct { 101105197Ssam u_long length; 102105197Ssam u_long cardaddr; 103105197Ssam u_long hostaddr; 104105197Ssam } memspace[2]; /* XXX this could be as high as 8 */ 105105197Ssam int maxtwins; 106105197Ssam STAILQ_ENTRY(pccard_config_entry) cfe_list; 107105197Ssam}; 108105197Ssam 109105197Ssamstruct pccard_function { 110105197Ssam /* read off the card */ 111105197Ssam int number; 112105197Ssam int function; 113105197Ssam int last_config_index; 114105197Ssam u_long ccr_base; 115105197Ssam u_long ccr_mask; 116105197Ssam struct resource *ccr_res; 117105197Ssam int ccr_rid; 118105197Ssam STAILQ_HEAD(, pccard_config_entry) cfe_head; 119105197Ssam STAILQ_ENTRY(pccard_function) pf_list; 120105197Ssam /* run-time state */ 121105197Ssam struct pccard_softc *sc; 122105197Ssam struct pccard_config_entry *cfe; 123125876Sguido struct pccard_mem_handle pf_pcmh; 124105197Ssam device_t dev; 125105197Ssam#define pf_ccrt pf_pcmh.memt 126105197Ssam#define pf_ccrh pf_pcmh.memh 127105197Ssam#define pf_ccr_realsize pf_pcmh.realsize 128119643Ssam bus_addr_t pf_ccr_offset; 129120585Ssam int pf_ccr_window; 130120585Ssam long pf_mfc_iobase; 131120585Ssam long pf_mfc_iomax; 132120585Ssam int (*ih_fct)(void *); 133120585Ssam void *ih_arg; 134120585Ssam int ih_ipl; 135120585Ssam int pf_flags; 136120585Ssam}; 137105197Ssam 138119643Ssam/* pf_flags */ 139120585Ssam#define PFF_ENABLED 0x0001 /* function is enabled */ 140120585Ssam 141120585Ssamstruct pccard_card { 142120585Ssam int cis1_major; 143120585Ssam int cis1_minor; 144120585Ssam /* XXX waste of space? */ 145120585Ssam char cis1_info_buf[256]; 146120585Ssam char *cis1_info[4]; 147119643Ssam /* 148105197Ssam * Use int32_t for manufacturer and product so that they can 149119643Ssam * hold the id value found in card CIS and special value that 150120585Ssam * indicates no id was found. 151120585Ssam */ 152120585Ssam int32_t manufacturer; 153120585Ssam#define PCCARD_VENDOR_INVALID -1 154120585Ssam int32_t product; 155120585Ssam#define PCCARD_PRODUCT_INVALID -1 156120585Ssam u_int16_t error; 157105197Ssam#define PCCARD_CIS_INVALID { NULL, NULL, NULL, NULL } 158119643Ssam STAILQ_HEAD(, pccard_function) pf_head; 159120585Ssam}; 160120585Ssam 161120585Ssam#define PCCARD_MEM_ATTR 1 162120585Ssam#define PCCARD_MEM_COMMON 2 163120585Ssam 164120585Ssam#define PCCARD_WIDTH_AUTO 0 165120585Ssam#define PCCARD_WIDTH_IO8 1 166105197Ssam#define PCCARD_WIDTH_IO16 2 167119643Ssam 168120585Ssam/* More later? */ 169120585Ssamstruct pccard_ivar { 170120585Ssam struct resource_list resources; 171120585Ssam struct pccard_function *fcn; 172120585Ssam}; 173120585Ssam 174120585Ssamstruct pccard_softc { 175105197Ssam device_t dev; 176105197Ssam /* this stuff is for the socket */ 177128856Ssam 178105197Ssam /* this stuff is for the card */ 179105197Ssam struct pccard_card card; 180128856Ssam int sc_enabled_count; /* num functions enabled */ 181128856Ssam}; 182128856Ssam 183105197Ssamvoid 184105197Ssampccardbus_if_setup(struct pccard_softc*); 185105197Ssam 186105197Ssamstruct pccard_cis_quirk { 187105197Ssam int32_t manufacturer; 188105197Ssam int32_t product; 189105197Ssam char *cis1_info[4]; 190105197Ssam struct pccard_function *pf; 191105197Ssam struct pccard_config_entry *cfe; 192105197Ssam}; 193105197Ssam 194105197Ssamstruct pccard_tuple { 195105197Ssam unsigned int code; 196105197Ssam unsigned int length; 197105197Ssam u_long mult; 198105197Ssam bus_addr_t ptr; 199105197Ssam bus_space_tag_t memt; 200105197Ssam bus_space_handle_t memh; 201105197Ssam}; 202105197Ssam 203105197Ssamstruct pccard_product { 204105197Ssam const char *pp_name; /* NULL if end of table */ 205105197Ssam#define PCCARD_VENDOR_ANY ((u_int32_t) -1) 206105197Ssam u_int32_t pp_vendor; 207105197Ssam#define PCCARD_PRODUCT_ANY ((u_int32_t) -1) 208105197Ssam u_int32_t pp_product; 209105197Ssam int pp_expfunc; 210105197Ssam const char *pp_vendor_str; /* NULL to not match */ 211105197Ssam const char *pp_product_str; /* NULL to not match */ 212105197Ssam}; 213105197Ssam 214105197Ssamtypedef int (*pccard_product_match_fn) (device_t dev, 215105197Ssam const struct pccard_product *ent, int vpfmatch); 216105197Ssam 217105197Ssamconst struct pccard_product 218105197Ssam *pccard_product_lookup(device_t dev, const struct pccard_product *tab, 219105197Ssam size_t ent_size, pccard_product_match_fn matchfn); 220105197Ssam 221105197Ssamvoid pccard_read_cis(struct pccard_softc *); 222105197Ssamvoid pccard_check_cis_quirks(device_t); 223105197Ssamvoid pccard_print_cis(device_t); 224105197Ssamint pccard_scan_cis(device_t, 225105197Ssam int (*) (struct pccard_tuple *, void *), void *); 226105197Ssam 227105197Ssam#define pccard_cis_read_1(tuple, idx0) \ 228105197Ssam (bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0))) 229105197Ssam 230105197Ssam#define pccard_tuple_read_1(tuple, idx1) \ 231105197Ssam (pccard_cis_read_1((tuple), ((tuple)->ptr+(2+(idx1))))) 232105197Ssam 233105197Ssam#define pccard_tuple_read_2(tuple, idx2) \ 234105197Ssam (pccard_tuple_read_1((tuple), (idx2)) | \ 235105197Ssam (pccard_tuple_read_1((tuple), (idx2)+1)<<8)) 236105197Ssam 237105197Ssam#define pccard_tuple_read_3(tuple, idx3) \ 238105197Ssam (pccard_tuple_read_1((tuple), (idx3)) | \ 239105197Ssam (pccard_tuple_read_1((tuple), (idx3)+1)<<8) | \ 240105197Ssam (pccard_tuple_read_1((tuple), (idx3)+2)<<16)) 241105197Ssam 242105197Ssam#define pccard_tuple_read_4(tuple, idx4) \ 243105197Ssam (pccard_tuple_read_1((tuple), (idx4)) | \ 244105197Ssam (pccard_tuple_read_1((tuple), (idx4)+1)<<8) | \ 245105197Ssam (pccard_tuple_read_1((tuple), (idx4)+2)<<16) | \ 246105197Ssam (pccard_tuple_read_1((tuple), (idx4)+3)<<24)) 247105197Ssam 248105197Ssam#define pccard_tuple_read_n(tuple, n, idxn) \ 249105197Ssam (((n)==1)?pccard_tuple_read_1((tuple), (idxn)) : \ 250105197Ssam (((n)==2)?pccard_tuple_read_2((tuple), (idxn)) : \ 251105197Ssam (((n)==3)?pccard_tuple_read_3((tuple), (idxn)) : \ 252105197Ssam /* n == 4 */ pccard_tuple_read_4((tuple), (idxn))))) 253105197Ssam 254105197Ssam#define PCCARD_SPACE_MEMORY 1 255105197Ssam#define PCCARD_SPACE_IO 2 256105197Ssam 257105197Ssamint pccard_ccr_read(struct pccard_function *, int); 258105197Ssamvoid pccard_ccr_write(struct pccard_function *, int, int); 259105197Ssam 260105197Ssam#define pccard_mfc(sc) (STAILQ_FIRST(&(sc)->card.pf_head) && \ 261105197Ssam STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list)) 262105197Ssam 263105197Ssam/* The following is the vestages of the NetBSD driver api */ 264105197Ssam 265105197Ssamvoid pccard_function_init(struct pccard_function *); 266105197Ssamint pccard_function_enable(struct pccard_function *); 267105197Ssamvoid pccard_function_disable(struct pccard_function *); 268105197Ssam 269105197Ssam#define pccard_io_alloc(pf, start, size, align, pciop) \ 270105197Ssam (pccard_chip_io_alloc((pf)->sc->pct, pf->sc->pch, (start), \ 271105197Ssam (size), (align), (pciop))) 272105197Ssam 273105197Ssam#define pccard_io_free(pf, pciohp) \ 274105197Ssam (pccard_chip_io_free((pf)->sc->pct, (pf)->sc->pch, (pciohp))) 275105197Ssam 276105197Ssamint pccard_io_map(struct pccard_function *, int, bus_addr_t, 277105197Ssam bus_size_t, struct pccard_io_handle *, int *); 278105197Ssamvoid pccard_io_unmap(struct pccard_function *, int); 279105197Ssam 280105197Ssam#define pccard_mem_alloc(pf, size, pcmhp) \ 281105197Ssam (pccard_chip_mem_alloc((pf)->sc->pct, (pf)->sc->pch, (size), (pcmhp))) 282105197Ssam#define pccard_mem_free(pf, pcmhp) \ 283105197Ssam (pccard_chip_mem_free((pf)->sc->pct, (pf)->sc->pch, (pcmhp))) 284105197Ssam#define pccard_mem_map(pf, kind, card_addr, size, pcmhp, offsetp, windowp) \ 285105197Ssam (pccard_chip_mem_map((pf)->sc->pct, (pf)->sc->pch, (kind), \ 286105197Ssam (card_addr), (size), (pcmhp), (offsetp), (windowp))) 287105197Ssam#define pccard_mem_unmap(pf, window) \ 288105197Ssam (pccard_chip_mem_unmap((pf)->sc->pct, (pf)->sc->pch, (window))) 289125876Sguido 290125876Sguido/* compat layer */ 291105197Ssamint pccard_compat_probe(device_t dev); 292105197Ssamint pccard_compat_attach(device_t dev); 293105197Ssam 294105197Ssam/* ivar interface */ 295105197Ssamenum { 296105197Ssam PCCARD_IVAR_ETHADDR, /* read ethernet address from CIS tupple */ 297105197Ssam PCCARD_IVAR_VENDOR, 298105197Ssam PCCARD_IVAR_PRODUCT, 299105197Ssam PCCARD_IVAR_FUNCTION_NUMBER, 300105197Ssam PCCARD_IVAR_VENDOR_STR, /* CIS string for "Manufacturer" */ 301105197Ssam PCCARD_IVAR_PRODUCT_STR,/* CIS strnig for "Product" */ 302105197Ssam PCCARD_IVAR_CIS3_STR /* Some cards need this */ 303105197Ssam}; 304105197Ssam 305105197Ssam#define PCCARD_ACCESSOR(A, B, T) \ 306105197Ssam__inline static int \ 307105197Ssampccard_get_ ## A(device_t dev, T *t) \ 308105197Ssam{ \ 309105197Ssam return BUS_READ_IVAR(device_get_parent(dev), dev, \ 310105197Ssam PCCARD_IVAR_ ## B, (uintptr_t *) t); \ 311105197Ssam} 312105197Ssam 313105197SsamPCCARD_ACCESSOR(ether, ETHADDR, u_int8_t) 314105197SsamPCCARD_ACCESSOR(vendor, VENDOR, u_int32_t) 315105197SsamPCCARD_ACCESSOR(product, PRODUCT, u_int32_t) 316105197SsamPCCARD_ACCESSOR(function_number,FUNCTION_NUMBER, u_int32_t) 317105197SsamPCCARD_ACCESSOR(vendor_str, VENDOR_STR, char *) 318105197SsamPCCARD_ACCESSOR(product_str, PRODUCT_STR, char *) 319105197SsamPCCARD_ACCESSOR(cis3_str, CIS3_STR, char *) 320105197Ssam 321105197Ssamenum { 322105197Ssam PCCARD_A_MEM_ATTR = 0x1 323105197Ssam}; 324119643Ssam 325119643Ssam#define PCCARD_SOFTC(d) (struct pccard_softc *) device_get_softc(d) 326119643Ssam