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