pccardvar.h revision 113322
166200Simp/*	$NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 enami Exp $	*/
252506Simp/* $FreeBSD: head/sys/dev/pccard/pccardvar.h 113322 2003-04-10 07:21:11Z imp $ */
352506Simp
452506Simp/*
552506Simp * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
652506Simp *
752506Simp * Redistribution and use in source and binary forms, with or without
852506Simp * modification, are permitted provided that the following conditions
952506Simp * are met:
1052506Simp * 1. Redistributions of source code must retain the above copyright
1152506Simp *    notice, this list of conditions and the following disclaimer.
1252506Simp * 2. Redistributions in binary form must reproduce the above copyright
1352506Simp *    notice, this list of conditions and the following disclaimer in the
1452506Simp *    documentation and/or other materials provided with the distribution.
1552506Simp * 3. All advertising materials mentioning features or use of this software
1652506Simp *    must display the following acknowledgement:
1752506Simp *	This product includes software developed by Marc Horowitz.
1852506Simp * 4. The name of the author may not be used to endorse or promote products
1952506Simp *    derived from this software without specific prior written permission.
2052506Simp *
2152506Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2252506Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2352506Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2452506Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2552506Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2652506Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2752506Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2852506Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2952506Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3052506Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3152506Simp */
3252506Simp
3352506Simp#include <sys/types.h>
3452506Simp#include <sys/queue.h>
3552506Simp
3652506Simp#include <machine/bus.h>
3752506Simp
3852506Simpextern int	pccard_verbose;
3952506Simp
4052506Simp/*
4152506Simp * Contains information about mapped/allocated i/o spaces.
4252506Simp */
4352506Simpstruct pccard_io_handle {
4452506Simp	bus_space_tag_t iot;		/* bus space tag (from chipset) */
4552506Simp	bus_space_handle_t ioh;		/* mapped space handle */
4652506Simp	bus_addr_t      addr;		/* resulting address in bus space */
4752506Simp	bus_size_t      size;		/* size of i/o space */
4852506Simp	int             flags;		/* misc. information */
4954250Simp	int		width;
5052506Simp};
5152506Simp
5252506Simp#define	PCCARD_IO_ALLOCATED	0x01	/* i/o space was allocated */
5352506Simp
5452506Simp/*
5552506Simp * Contains information about allocated memory space.
5652506Simp */
5752506Simpstruct pccard_mem_handle {
5852506Simp	bus_space_tag_t memt;		/* bus space tag (from chipset) */
5952506Simp	bus_space_handle_t memh;	/* mapped space handle */
6052506Simp	bus_addr_t      addr;		/* resulting address in bus space */
6152506Simp	bus_size_t      size;		/* size of mem space */
6252506Simp	bus_size_t      realsize;	/* how much we really allocated */
6389959Simp	long		offset;		/* mapped Offset on card */
6489959Simp	bus_addr_t	cardaddr;	/* Absolute address on card */
6554250Simp	int		kind;
6652506Simp};
6752506Simp
6852506Simp/* pccard itself */
6952506Simp
7052506Simp#define PCCARD_CFE_MWAIT_REQUIRED	0x0001
7152506Simp#define PCCARD_CFE_RDYBSY_ACTIVE	0x0002
7252506Simp#define PCCARD_CFE_WP_ACTIVE		0x0004
7352506Simp#define PCCARD_CFE_BVD_ACTIVE		0x0008
7452506Simp#define PCCARD_CFE_IO8			0x0010
7552506Simp#define PCCARD_CFE_IO16			0x0020
7652506Simp#define PCCARD_CFE_IRQSHARE		0x0040
7752506Simp#define PCCARD_CFE_IRQPULSE		0x0080
7852506Simp#define PCCARD_CFE_IRQLEVEL		0x0100
7952506Simp#define PCCARD_CFE_POWERDOWN		0x0200
8052506Simp#define PCCARD_CFE_READONLY		0x0400
8152506Simp#define PCCARD_CFE_AUDIO		0x0800
8252506Simp
8352506Simpstruct pccard_config_entry {
8452506Simp	int		number;
85113241Simp	uint32_t	flags;
8652506Simp	int		iftype;
8752506Simp	int		num_iospace;
8852506Simp
8952506Simp	/*
9052506Simp	 * The card will only decode this mask in any case, so we can
9152506Simp	 * do dynamic allocation with this in mind, in case the suggestions
9252506Simp	 * below are no good.
9352506Simp	 */
9452506Simp	u_long		iomask;
9552506Simp	struct {
9652506Simp		u_long	length;
9752506Simp		u_long	start;
9852506Simp	} iospace[4];		/* XXX this could be as high as 16 */
99113241Simp	uint16_t	irqmask;
10052506Simp	int		num_memspace;
10152506Simp	struct {
10252506Simp		u_long	length;
10352506Simp		u_long	cardaddr;
10452506Simp		u_long	hostaddr;
10552506Simp	} memspace[2];		/* XXX this could be as high as 8 */
10652506Simp	int		maxtwins;
10767187Simp	struct resource *iores[4];
10867187Simp	int		iorid[4];
10967187Simp	struct resource *irqres;
11067187Simp	int		irqrid;
11167187Simp	struct resource *memres[2];
11267187Simp	int		memrid[2];
11360938Sjake	STAILQ_ENTRY(pccard_config_entry) cfe_list;
11452506Simp};
11552506Simp
11682781Sshibastruct pccard_funce_disk {
11782781Sshiba	int pfd_interface;
11882781Sshiba};
11982781Sshiba
12082781Sshibastruct pccard_funce_lan {
12182781Sshiba	int pfl_nidlen;
122113241Simp	uint8_t pfl_nid[8];
12382781Sshiba};
12482781Sshiba
12582781Sshibaunion pccard_funce {
12682781Sshiba	struct pccard_funce_disk pfv_disk;
12782781Sshiba	struct pccard_funce_lan pfv_lan;
12882781Sshiba};
12982781Sshiba
13052506Simpstruct pccard_function {
13152506Simp	/* read off the card */
13252506Simp	int		number;
13352506Simp	int		function;
13452506Simp	int		last_config_index;
135106898Simp	uint32_t	ccr_base;	/* Offset with card's memory */
136106898Simp	uint32_t	ccr_mask;
13755720Simp	struct resource *ccr_res;
13855720Simp	int		ccr_rid;
13960938Sjake	STAILQ_HEAD(, pccard_config_entry) cfe_head;
14060938Sjake	STAILQ_ENTRY(pccard_function) pf_list;
14152506Simp	/* run-time state */
14252506Simp	struct pccard_softc *sc;
14352506Simp	struct pccard_config_entry *cfe;
14452506Simp	struct pccard_mem_handle pf_pcmh;
14564927Simp	device_t	dev;
14652506Simp#define	pf_ccrt		pf_pcmh.memt
14752506Simp#define	pf_ccrh		pf_pcmh.memh
14852506Simp#define	pf_ccr_realsize	pf_pcmh.realsize
149106898Simp	uint32_t	pf_ccr_offset;	/* Offset from ccr_base of CIS */
15052506Simp	int		pf_ccr_window;
151106898Simp	long		pf_mfc_iobase;	/* Right type? */
15252506Simp	long		pf_mfc_iomax;
15352506Simp	int		pf_flags;
15470715Sjon	driver_intr_t	*intr_handler;
15570715Sjon	void		*intr_handler_arg;
15670715Sjon	void		*intr_handler_cookie;
15782781Sshiba
15882781Sshiba	union pccard_funce pf_funce; /* CISTPL_FUNCE */
15982781Sshiba#define pf_funce_disk_interface pf_funce.pfv_disk.pfd_interface
16082781Sshiba#define pf_funce_lan_nid pf_funce.pfv_lan.pfl_nid
16182781Sshiba#define pf_funce_lan_nidlen pf_funce.pfv_lan.pfl_nidlen
16252506Simp};
16352506Simp
16452506Simp/* pf_flags */
16552506Simp#define	PFF_ENABLED	0x0001		/* function is enabled */
16652506Simp
16752506Simpstruct pccard_card {
16852506Simp	int		cis1_major;
16952506Simp	int		cis1_minor;
17052506Simp	/* XXX waste of space? */
17152506Simp	char		cis1_info_buf[256];
17252506Simp	char		*cis1_info[4];
17352506Simp	/*
17452506Simp	 * Use int32_t for manufacturer and product so that they can
17552506Simp	 * hold the id value found in card CIS and special value that
17652506Simp	 * indicates no id was found.
17752506Simp	 */
17852506Simp	int32_t		manufacturer;
17986272Simp#define	PCMCIA_VENDOR_INVALID	-1
18052506Simp	int32_t		product;
18186272Simp#define	PCMCIA_PRODUCT_INVALID		-1
18290964Sshiba	int16_t		prodext;
183113241Simp	uint16_t	error;
18486272Simp#define	PCMCIA_CIS_INVALID		{ NULL, NULL, NULL, NULL }
18560938Sjake	STAILQ_HEAD(, pccard_function) pf_head;
18652506Simp};
18752506Simp
18859389Simp#define	PCCARD_MEM_ATTR		1
18959389Simp#define	PCCARD_MEM_COMMON	2
19059389Simp
19159389Simp#define	PCCARD_WIDTH_AUTO	0
19259389Simp#define	PCCARD_WIDTH_IO8	1
19359389Simp#define	PCCARD_WIDTH_IO16	2
19459389Simp
19553873Simp/* More later? */
19653873Simpstruct pccard_ivar {
19753873Simp	struct resource_list resources;
19865917Simp	struct pccard_function *fcn;
19952506Simp};
20052506Simp
20152506Simpstruct pccard_softc {
20255720Simp	device_t		dev;
20352506Simp	/* this stuff is for the socket */
20452506Simp
20552506Simp	/* this stuff is for the card */
20652506Simp	struct pccard_card card;
20755500Simp	int		sc_enabled_count;	/* num functions enabled */
20852506Simp};
20952506Simp
21052506Simpvoid
21154250Simppccardbus_if_setup(struct pccard_softc*);
21252506Simp
21352506Simpstruct pccard_cis_quirk {
21452506Simp	int32_t manufacturer;
21552506Simp	int32_t product;
21652506Simp	char *cis1_info[4];
21752506Simp	struct pccard_function *pf;
21852506Simp	struct pccard_config_entry *cfe;
21952506Simp};
22052506Simp
22152506Simpstruct pccard_tuple {
22252506Simp	unsigned int	code;
22352506Simp	unsigned int	length;
22452506Simp	u_long		mult;
22552506Simp	bus_addr_t	ptr;
22652506Simp	bus_space_tag_t	memt;
22752506Simp	bus_space_handle_t memh;
22852506Simp};
22952506Simp
23066200Simpstruct pccard_product {
23166200Simp	const char	*pp_name;		/* NULL if end of table */
232113241Simp#define PCCARD_VENDOR_ANY (0xffffffff)
233113241Simp	uint32_t	pp_vendor;
234113241Simp#define PCCARD_PRODUCT_ANY (0xffffffff)
235113241Simp	uint32_t	pp_product;
23666200Simp	int		pp_expfunc;
23771322Simp	const char	*pp_cis[4];
23866200Simp};
23966200Simp
24066200Simptypedef int (*pccard_product_match_fn) (device_t dev,
24166200Simp    const struct pccard_product *ent, int vpfmatch);
24266200Simp
243100218Simp#include "card_if.h"
24466200Simp
245100218Simp/*
246100218Simp * make this inline so that we don't have to worry about dangling references
247100218Simp * to it in the modules or the code.
248100218Simp */
249100218Simpstatic __inline const struct pccard_product *
250100218Simppccard_product_lookup(device_t dev, const struct pccard_product *tab,
251100218Simp    size_t ent_size, pccard_product_match_fn matchfn)
252100218Simp{
253100218Simp	return CARD_DO_PRODUCT_LOOKUP(device_get_parent(dev), dev,
254100218Simp	    tab, ent_size, matchfn);
255100218Simp}
256100218Simp
25754250Simpvoid	pccard_read_cis(struct pccard_softc *);
25852506Simpvoid	pccard_check_cis_quirks(device_t);
25952506Simpvoid	pccard_print_cis(device_t);
26059193Simpint	pccard_scan_cis(device_t,
26159193Simp		int (*) (struct pccard_tuple *, void *), void *);
26252506Simp
26352506Simp#define	pccard_cis_read_1(tuple, idx0)					\
26452506Simp	(bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0)))
26552506Simp
26652506Simp#define	pccard_tuple_read_1(tuple, idx1)				\
26752506Simp	(pccard_cis_read_1((tuple), ((tuple)->ptr+(2+(idx1)))))
26852506Simp
26952506Simp#define	pccard_tuple_read_2(tuple, idx2)				\
27082378Sjon	(pccard_tuple_read_1((tuple), (idx2)) |				\
27152506Simp	 (pccard_tuple_read_1((tuple), (idx2)+1)<<8))
27252506Simp
27352506Simp#define	pccard_tuple_read_3(tuple, idx3)				\
27452506Simp	(pccard_tuple_read_1((tuple), (idx3)) |				\
27552506Simp	 (pccard_tuple_read_1((tuple), (idx3)+1)<<8) |			\
27652506Simp	 (pccard_tuple_read_1((tuple), (idx3)+2)<<16))
27752506Simp
27852506Simp#define	pccard_tuple_read_4(tuple, idx4)				\
27952506Simp	(pccard_tuple_read_1((tuple), (idx4)) |				\
28052506Simp	 (pccard_tuple_read_1((tuple), (idx4)+1)<<8) |			\
28152506Simp	 (pccard_tuple_read_1((tuple), (idx4)+2)<<16) |			\
28252506Simp	 (pccard_tuple_read_1((tuple), (idx4)+3)<<24))
28352506Simp
28452506Simp#define	pccard_tuple_read_n(tuple, n, idxn)				\
28552506Simp	(((n)==1)?pccard_tuple_read_1((tuple), (idxn)) :		\
28652506Simp	 (((n)==2)?pccard_tuple_read_2((tuple), (idxn)) :		\
28752506Simp	  (((n)==3)?pccard_tuple_read_3((tuple), (idxn)) :		\
28852506Simp	   /* n == 4 */ pccard_tuple_read_4((tuple), (idxn)))))
28952506Simp
29052506Simp#define	PCCARD_SPACE_MEMORY	1
29152506Simp#define	PCCARD_SPACE_IO		2
29252506Simp
29352506Simp#define	pccard_mfc(sc)	(STAILQ_FIRST(&(sc)->card.pf_head) &&		\
29452506Simp		 STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list))
29552506Simp
29652506Simp#define	pccard_io_alloc(pf, start, size, align, pciop)			\
29752506Simp	(pccard_chip_io_alloc((pf)->sc->pct, pf->sc->pch, (start),	\
29852506Simp	 (size), (align), (pciop)))
29952506Simp
30052506Simp#define	pccard_io_free(pf, pciohp)					\
30152506Simp	(pccard_chip_io_free((pf)->sc->pct, (pf)->sc->pch, (pciohp)))
30252506Simp
30354250Simpint	pccard_io_map(struct pccard_function *, int, bus_addr_t,
30454250Simp	    bus_size_t, struct pccard_io_handle *, int *);
30554250Simpvoid	pccard_io_unmap(struct pccard_function *, int);
30652506Simp
30752506Simp#define pccard_mem_alloc(pf, size, pcmhp)				\
30852506Simp	(pccard_chip_mem_alloc((pf)->sc->pct, (pf)->sc->pch, (size), (pcmhp)))
30952506Simp#define pccard_mem_free(pf, pcmhp)					\
31052506Simp	(pccard_chip_mem_free((pf)->sc->pct, (pf)->sc->pch, (pcmhp)))
31152506Simp#define pccard_mem_map(pf, kind, card_addr, size, pcmhp, offsetp, windowp) \
31252506Simp	(pccard_chip_mem_map((pf)->sc->pct, (pf)->sc->pch, (kind),	\
31352506Simp	 (card_addr), (size), (pcmhp), (offsetp), (windowp)))
31452506Simp#define	pccard_mem_unmap(pf, window)					\
31552506Simp	(pccard_chip_mem_unmap((pf)->sc->pct, (pf)->sc->pch, (window)))
31656361Shosokawa
31766058Simp/* compat layer */
31874636Simpstatic __inline int
31974636Simppccard_compat_probe(device_t dev)
32074636Simp{
32174636Simp	return (CARD_COMPAT_DO_PROBE(device_get_parent(dev), dev));
32274636Simp}
32366058Simp
32474636Simpstatic __inline int
32574636Simppccard_compat_attach(device_t dev)
32674636Simp{
32774636Simp	return (CARD_COMPAT_DO_ATTACH(device_get_parent(dev), dev));
32874636Simp}
32974636Simp
33056361Shosokawa/* ivar interface */
33156361Shosokawaenum {
33256361Shosokawa	PCCARD_IVAR_ETHADDR,	/* read ethernet address from CIS tupple */
33366200Simp	PCCARD_IVAR_VENDOR,
33466200Simp	PCCARD_IVAR_PRODUCT,
33590964Sshiba	PCCARD_IVAR_PRODEXT,
33666200Simp	PCCARD_IVAR_FUNCTION_NUMBER,
33766200Simp	PCCARD_IVAR_VENDOR_STR,	/* CIS string for "Manufacturer" */
33866200Simp	PCCARD_IVAR_PRODUCT_STR,/* CIS strnig for "Product" */
33967167Simp	PCCARD_IVAR_CIS3_STR,
34075761Simp	PCCARD_IVAR_CIS4_STR,
34175761Simp	PCCARD_IVAR_FUNCTION
34256361Shosokawa};
34356361Shosokawa
34466200Simp#define PCCARD_ACCESSOR(A, B, T)					\
34566200Simp__inline static int							\
34666200Simppccard_get_ ## A(device_t dev, T *t)					\
34766200Simp{									\
34882378Sjon	return BUS_READ_IVAR(device_get_parent(dev), dev,		\
34966200Simp	    PCCARD_IVAR_ ## B, (uintptr_t *) t);			\
35056361Shosokawa}
35158581Simp
352113241SimpPCCARD_ACCESSOR(ether,		ETHADDR,		uint8_t)
353113241SimpPCCARD_ACCESSOR(vendor,		VENDOR,			uint32_t)
354113241SimpPCCARD_ACCESSOR(product,	PRODUCT,		uint32_t)
355113241SimpPCCARD_ACCESSOR(prodext,	PRODEXT,		uint16_t)
356113241SimpPCCARD_ACCESSOR(function_number,FUNCTION_NUMBER,	uint32_t)
357113241SimpPCCARD_ACCESSOR(function,	FUNCTION,		uint32_t)
35866200SimpPCCARD_ACCESSOR(vendor_str,	VENDOR_STR,		char *)
35966200SimpPCCARD_ACCESSOR(product_str,	PRODUCT_STR,		char *)
36066200SimpPCCARD_ACCESSOR(cis3_str,	CIS3_STR,		char *)
36166200Simp
36276387Sdmlb/* shared memory flags */
36358581Simpenum {
36476387Sdmlb	PCCARD_A_MEM_COM,       /* common */
36576387Sdmlb	PCCARD_A_MEM_ATTR,      /* attribute */
36676387Sdmlb	PCCARD_A_MEM_8BIT,      /* 8 bit */
36776387Sdmlb	PCCARD_A_MEM_16BIT      /* 16 bit */
36858581Simp};
36958581Simp
37064850Simp#define PCCARD_SOFTC(d) (struct pccard_softc *) device_get_softc(d)
37166847Simp#define PCCARD_IVAR(d) (struct pccard_ivar *) device_get_ivars(d)
37286385Simp
37386385Simp#define PCCARD_S(a, b) PCMCIA_STR_ ## a ## _ ## b
37486385Simp#define PCCARD_P(a, b) PCMCIA_PRODUCT_ ## a ## _ ## b
37586385Simp#define PCCARD_C(a, b) PCMCIA_CIS_ ## a ## _ ## b
376113322Simp#define PCMCIA_CARD_D(v, p, f) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \
37786385Simp		PCCARD_P(v, p), f, PCCARD_C(v, p) }
378113322Simp#define PCMCIA_CARD2_D(v1, p1, p2, f) \
37986385Simp		{ PCMCIA_STR_ ## p2, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \
38086385Simp		  f, PCMCIA_CIS_ ## p2}
381113322Simp#if 1
382113322Simp#define PCMCIA_CARD(v, p, f) { NULL, PCMCIA_VENDOR_ ## v, \
383113257Simp		PCCARD_P(v, p), f, PCCARD_C(v, p) }
384113322Simp#define PCMCIA_CARD2(v1, p1, p2, f) \
385113257Simp		{ NULL, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \
386113257Simp		  f, PCMCIA_CIS_ ## p2}
387113322Simp#endif
388