pccardvar.h revision 139749
150276Speter/*	$NetBSD: pcmciavar.h,v 1.12 2000/02/08 12:51:31 enami Exp $	*/
2166124Srafan/* $FreeBSD: head/sys/dev/pccard/pccardvar.h 139749 2005-01-06 01:43:34Z imp $ */
350276Speter
450276Speter/*-
550276Speter * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
650276Speter *
750276Speter * Redistribution and use in source and binary forms, with or without
850276Speter * modification, are permitted provided that the following conditions
950276Speter * are met:
1050276Speter * 1. Redistributions of source code must retain the above copyright
1150276Speter *    notice, this list of conditions and the following disclaimer.
1250276Speter * 2. Redistributions in binary form must reproduce the above copyright
1350276Speter *    notice, this list of conditions and the following disclaimer in the
1450276Speter *    documentation and/or other materials provided with the distribution.
1550276Speter * 3. All advertising materials mentioning features or use of this software
1650276Speter *    must display the following acknowledgement:
1750276Speter *	This product includes software developed by Marc Horowitz.
1850276Speter * 4. The name of the author may not be used to endorse or promote products
1950276Speter *    derived from this software without specific prior written permission.
2050276Speter *
2150276Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2250276Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2350276Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2450276Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2550276Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2650276Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2750276Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2850276Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2950276Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30166124Srafan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31166124Srafan */
3250276Speter
3350276Speterextern int	pccard_verbose;
3450276Speter
3550276Speter/*
3650276Speter * Contains information about mapped/allocated i/o spaces.
37166124Srafan */
3850276Speterstruct pccard_io_handle {
3950276Speter	bus_space_tag_t iot;		/* bus space tag (from chipset) */
4050276Speter	bus_space_handle_t ioh;		/* mapped space handle */
41166124Srafan	bus_addr_t      addr;		/* resulting address in bus space */
4250276Speter	bus_size_t      size;		/* size of i/o space */
4376726Speter	int             flags;		/* misc. information */
44166124Srafan	int		width;
4550276Speter};
4676726Speter
4750276Speter#define	PCCARD_IO_ALLOCATED	0x01	/* i/o space was allocated */
4876726Speter
4976726Speter/*
50166124Srafan * Contains information about allocated memory space.
51166124Srafan */
52166124Srafanstruct pccard_mem_handle {
53166124Srafan	bus_space_tag_t memt;		/* bus space tag (from chipset) */
54166124Srafan	bus_space_handle_t memh;	/* mapped space handle */
55166124Srafan	bus_addr_t      addr;		/* resulting address in bus space */
5676726Speter	bus_size_t      size;		/* size of mem space */
5776726Speter	bus_size_t      realsize;	/* how much we really allocated */
5876726Speter	bus_addr_t	cardaddr;	/* Absolute address on card */
5950276Speter	int		kind;
60};
61
62/* pccard itself */
63
64#define PCCARD_CFE_MWAIT_REQUIRED	0x0001
65#define PCCARD_CFE_RDYBSY_ACTIVE	0x0002
66#define PCCARD_CFE_WP_ACTIVE		0x0004
67#define PCCARD_CFE_BVD_ACTIVE		0x0008
68#define PCCARD_CFE_IO8			0x0010
69#define PCCARD_CFE_IO16			0x0020
70#define PCCARD_CFE_IRQSHARE		0x0040
71#define PCCARD_CFE_IRQPULSE		0x0080
72#define PCCARD_CFE_IRQLEVEL		0x0100
73#define PCCARD_CFE_POWERDOWN		0x0200
74#define PCCARD_CFE_READONLY		0x0400
75#define PCCARD_CFE_AUDIO		0x0800
76
77struct pccard_config_entry {
78	int		number;
79	uint32_t	flags;
80	int		iftype;
81	int		num_iospace;
82
83	/*
84	 * The card will only decode this mask in any case, so we can
85	 * do dynamic allocation with this in mind, in case the suggestions
86	 * below are no good.
87	 */
88	u_long		iomask;
89	struct {
90		u_long	length;
91		u_long	start;
92	} iospace[4];		/* XXX this could be as high as 16 */
93	uint16_t	irqmask;
94	int		num_memspace;
95	struct {
96		u_long	length;
97		u_long	cardaddr;
98		u_long	hostaddr;
99	} memspace[2];		/* XXX this could be as high as 8 */
100	int		maxtwins;
101	struct resource *iores[4];
102	int		iorid[4];
103	struct resource *irqres;
104	int		irqrid;
105	struct resource *memres[2];
106	int		memrid[2];
107	STAILQ_ENTRY(pccard_config_entry) cfe_list;
108};
109
110struct pccard_funce_disk {
111	int pfd_interface;
112};
113
114struct pccard_funce_lan {
115	int pfl_nidlen;
116	uint8_t pfl_nid[8];
117};
118
119union pccard_funce {
120	struct pccard_funce_disk pfv_disk;
121	struct pccard_funce_lan pfv_lan;
122};
123
124struct pccard_function {
125	/* read off the card */
126	int		number;
127	int		function;
128	int		last_config_index;
129	uint32_t	ccr_base;	/* Offset with card's memory */
130	uint32_t	ccr_mask;
131	struct resource *ccr_res;
132	int		ccr_rid;
133	STAILQ_HEAD(, pccard_config_entry) cfe_head;
134	STAILQ_ENTRY(pccard_function) pf_list;
135	/* run-time state */
136	struct pccard_softc *sc;
137	struct pccard_config_entry *cfe;
138	struct pccard_mem_handle pf_pcmh;
139	device_t	dev;
140#define	pf_ccrt		pf_pcmh.memt
141#define	pf_ccrh		pf_pcmh.memh
142#define	pf_ccr_realsize	pf_pcmh.realsize
143	uint32_t	pf_ccr_offset;	/* Offset from ccr_base of CIS */
144	int		pf_ccr_window;
145	bus_addr_t	pf_mfc_iobase;
146	bus_addr_t	pf_mfc_iomax;
147	int		pf_flags;
148	driver_intr_t	*intr_handler;
149	void		*intr_handler_arg;
150	void		*intr_handler_cookie;
151
152	union pccard_funce pf_funce; /* CISTPL_FUNCE */
153#define pf_funce_disk_interface pf_funce.pfv_disk.pfd_interface
154#define pf_funce_lan_nid pf_funce.pfv_lan.pfl_nid
155#define pf_funce_lan_nidlen pf_funce.pfv_lan.pfl_nidlen
156};
157
158/* pf_flags */
159#define	PFF_ENABLED	0x0001		/* function is enabled */
160
161struct pccard_card {
162	int		cis1_major;
163	int		cis1_minor;
164	/* XXX waste of space? */
165	char		cis1_info_buf[256];
166	char		*cis1_info[4];
167	/*
168	 * Use int32_t for manufacturer and product so that they can
169	 * hold the id value found in card CIS and special value that
170	 * indicates no id was found.
171	 */
172	int32_t		manufacturer;
173#define	PCMCIA_VENDOR_INVALID	-1
174	int32_t		product;
175#define	PCMCIA_PRODUCT_INVALID		-1
176	int16_t		prodext;
177	uint16_t	error;
178#define	PCMCIA_CIS_INVALID		{ NULL, NULL, NULL, NULL }
179	STAILQ_HEAD(, pccard_function) pf_head;
180};
181
182#define	PCCARD_WIDTH_AUTO	0
183#define	PCCARD_WIDTH_IO8	1
184#define	PCCARD_WIDTH_IO16	2
185
186/* More later? */
187struct pccard_ivar {
188	struct resource_list resources;
189	struct pccard_function *fcn;
190};
191
192struct pccard_softc {
193	device_t		dev;
194	/* this stuff is for the socket */
195
196	/* this stuff is for the card */
197	struct pccard_card card;
198	int		sc_enabled_count;	/* num functions enabled */
199};
200
201struct pccard_cis_quirk {
202	int32_t manufacturer;
203	int32_t product;
204	char *cis1_info[4];
205	struct pccard_function *pf;
206	struct pccard_config_entry *cfe;
207};
208
209struct pccard_tuple {
210	unsigned int	code;
211	unsigned int	length;
212	u_long		mult;
213	bus_addr_t	ptr;
214	bus_space_tag_t	memt;
215	bus_space_handle_t memh;
216};
217
218struct pccard_product {
219	const char	*pp_name;		/* NULL if end of table */
220#define PCCARD_VENDOR_ANY (0xffffffff)
221	uint32_t	pp_vendor;
222#define PCCARD_PRODUCT_ANY (0xffffffff)
223	uint32_t	pp_product;
224	int		pp_expfunc;
225	const char	*pp_cis[4];
226};
227
228typedef int (*pccard_product_match_fn) (device_t dev,
229    const struct pccard_product *ent, int vpfmatch);
230
231#include "card_if.h"
232
233/*
234 * make this inline so that we don't have to worry about dangling references
235 * to it in the modules or the code.
236 */
237static __inline const struct pccard_product *
238pccard_product_lookup(device_t dev, const struct pccard_product *tab,
239    size_t ent_size, pccard_product_match_fn matchfn)
240{
241	return CARD_DO_PRODUCT_LOOKUP(device_get_parent(dev), dev,
242	    tab, ent_size, matchfn);
243}
244
245void	pccard_read_cis(struct pccard_softc *);
246void	pccard_check_cis_quirks(device_t);
247void	pccard_print_cis(device_t);
248int	pccard_scan_cis(device_t,
249		int (*) (struct pccard_tuple *, void *), void *);
250
251#define	pccard_cis_read_1(tuple, idx0)					\
252	(bus_space_read_1((tuple)->memt, (tuple)->memh, (tuple)->mult*(idx0)))
253
254#define	pccard_tuple_read_1(tuple, idx1)				\
255	(pccard_cis_read_1((tuple), ((tuple)->ptr+(2+(idx1)))))
256
257#define	pccard_tuple_read_2(tuple, idx2)				\
258	(pccard_tuple_read_1((tuple), (idx2)) |				\
259	 (pccard_tuple_read_1((tuple), (idx2)+1)<<8))
260
261#define	pccard_tuple_read_3(tuple, idx3)				\
262	(pccard_tuple_read_1((tuple), (idx3)) |				\
263	 (pccard_tuple_read_1((tuple), (idx3)+1)<<8) |			\
264	 (pccard_tuple_read_1((tuple), (idx3)+2)<<16))
265
266#define	pccard_tuple_read_4(tuple, idx4)				\
267	(pccard_tuple_read_1((tuple), (idx4)) |				\
268	 (pccard_tuple_read_1((tuple), (idx4)+1)<<8) |			\
269	 (pccard_tuple_read_1((tuple), (idx4)+2)<<16) |			\
270	 (pccard_tuple_read_1((tuple), (idx4)+3)<<24))
271
272#define	pccard_tuple_read_n(tuple, n, idxn)				\
273	(((n)==1)?pccard_tuple_read_1((tuple), (idxn)) :		\
274	 (((n)==2)?pccard_tuple_read_2((tuple), (idxn)) :		\
275	  (((n)==3)?pccard_tuple_read_3((tuple), (idxn)) :		\
276	   /* n == 4 */ pccard_tuple_read_4((tuple), (idxn)))))
277
278#define	PCCARD_SPACE_MEMORY	1
279#define	PCCARD_SPACE_IO		2
280
281#define	pccard_mfc(sc)							\
282		(STAILQ_FIRST(&(sc)->card.pf_head) &&			\
283		 STAILQ_NEXT(STAILQ_FIRST(&(sc)->card.pf_head),pf_list))
284
285#define	pccard_io_alloc(pf, start, size, align, pciop)			\
286	(pccard_chip_io_alloc((pf)->sc->pct, pf->sc->pch, (start),	\
287	 (size), (align), (pciop)))
288
289#define	pccard_io_free(pf, pciohp)					\
290	(pccard_chip_io_free((pf)->sc->pct, (pf)->sc->pch, (pciohp)))
291
292int	pccard_io_map(struct pccard_function *, int, bus_addr_t,
293	    bus_size_t, struct pccard_io_handle *, int *);
294void	pccard_io_unmap(struct pccard_function *, int);
295
296#define pccard_mem_alloc(pf, size, pcmhp)				\
297	(pccard_chip_mem_alloc((pf)->sc->pct, (pf)->sc->pch, (size), (pcmhp)))
298#define pccard_mem_free(pf, pcmhp)					\
299	(pccard_chip_mem_free((pf)->sc->pct, (pf)->sc->pch, (pcmhp)))
300#define pccard_mem_map(pf, kind, card_addr, size, pcmhp, offsetp, windowp) \
301	(pccard_chip_mem_map((pf)->sc->pct, (pf)->sc->pch, (kind),	\
302	 (card_addr), (size), (pcmhp), (offsetp), (windowp)))
303#define	pccard_mem_unmap(pf, window)					\
304	(pccard_chip_mem_unmap((pf)->sc->pct, (pf)->sc->pch, (window)))
305
306/* compat layer */
307static __inline int
308pccard_compat_probe(device_t dev)
309{
310	return (CARD_COMPAT_DO_PROBE(device_get_parent(dev), dev));
311}
312
313static __inline int
314pccard_compat_attach(device_t dev)
315{
316	return (CARD_COMPAT_DO_ATTACH(device_get_parent(dev), dev));
317}
318
319/* ivar interface */
320enum {
321	PCCARD_IVAR_ETHADDR,	/* read ethernet address from CIS tupple */
322	PCCARD_IVAR_VENDOR,
323	PCCARD_IVAR_PRODUCT,
324	PCCARD_IVAR_PRODEXT,
325	PCCARD_IVAR_FUNCTION_NUMBER,
326	PCCARD_IVAR_VENDOR_STR,	/* CIS string for "Manufacturer" */
327	PCCARD_IVAR_PRODUCT_STR,/* CIS strnig for "Product" */
328	PCCARD_IVAR_CIS3_STR,
329	PCCARD_IVAR_CIS4_STR,
330	PCCARD_IVAR_FUNCTION
331};
332
333#define PCCARD_ACCESSOR(A, B, T)					\
334__inline static int							\
335pccard_get_ ## A(device_t dev, T *t)					\
336{									\
337	return BUS_READ_IVAR(device_get_parent(dev), dev,		\
338	    PCCARD_IVAR_ ## B, (uintptr_t *) t);			\
339}
340
341PCCARD_ACCESSOR(ether,		ETHADDR,		uint8_t)
342PCCARD_ACCESSOR(vendor,		VENDOR,			uint32_t)
343PCCARD_ACCESSOR(product,	PRODUCT,		uint32_t)
344PCCARD_ACCESSOR(prodext,	PRODEXT,		uint16_t)
345PCCARD_ACCESSOR(function_number,FUNCTION_NUMBER,	uint32_t)
346PCCARD_ACCESSOR(function,	FUNCTION,		uint32_t)
347PCCARD_ACCESSOR(vendor_str,	VENDOR_STR,		const char *)
348PCCARD_ACCESSOR(product_str,	PRODUCT_STR,		const char *)
349PCCARD_ACCESSOR(cis3_str,	CIS3_STR,		const char *)
350PCCARD_ACCESSOR(cis4_str,	CIS4_STR,		const char *)
351
352/* shared memory flags */
353enum {
354	PCCARD_A_MEM_COM,       /* common */
355	PCCARD_A_MEM_ATTR,      /* attribute */
356	PCCARD_A_MEM_8BIT,      /* 8 bit */
357	PCCARD_A_MEM_16BIT      /* 16 bit */
358};
359
360#define PCCARD_SOFTC(d) (struct pccard_softc *) device_get_softc(d)
361#define PCCARD_IVAR(d) (struct pccard_ivar *) device_get_ivars(d)
362
363#define PCCARD_S(a, b) PCMCIA_STR_ ## a ## _ ## b
364#define PCCARD_P(a, b) PCMCIA_PRODUCT_ ## a ## _ ## b
365#define PCCARD_C(a, b) PCMCIA_CIS_ ## a ## _ ## b
366#define PCMCIA_CARD_D(v, p, f) { PCCARD_S(v, p), PCMCIA_VENDOR_ ## v, \
367		PCCARD_P(v, p), f, PCCARD_C(v, p) }
368#define PCMCIA_CARD2_D(v1, p1, p2, f) \
369		{ PCMCIA_STR_ ## p2, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \
370		  f, PCMCIA_CIS_ ## p2}
371#define PCMCIA_CARD(v, p, f) { NULL, PCMCIA_VENDOR_ ## v, \
372		PCCARD_P(v, p), f, PCCARD_C(v, p) }
373#define PCMCIA_CARD2(v1, p1, p2, f) \
374		{ NULL, PCMCIA_VENDOR_ ## v1, PCCARD_P(v1, p1), \
375		  f, PCMCIA_CIS_ ## p2}
376