1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _SYS_EBUS_H
#define _SYS_EBUS_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* driver state type:
*/
typedef enum { NEW = 0, ATTACHED, RESUMED, DETACHED,
SUSPENDED, PM_SUSPENDED } driver_state_t;
/*
* The i86pc specific code fragments are to support the debug of "honeynut"
* and "multigrain" prototypes on i86pc platform. Most of the fragments
* deal with differences in the interrupt dispatching between the prototypes
* and the cheerio ebus. On the prototype boards, all interrupt lines are
* tied together. For this case, the nexus driver uses a common interrupt
* handler to poll all of its children.
*/
#if defined(i86pc)
#define MAX_EBUS_DEVS 6
/*
* ebus device interrupt info;
*/
typedef struct {
char *name;
uint_t inuse;
uint_t (*handler)();
caddr_t arg;
} ebus_intr_slot_t;
#endif
struct ebus_intr_map {
uint32_t ebus_phys_hi;
uint32_t ebus_phys_low;
uint32_t ebus_intr;
uint32_t intr_ctlr_nodeid;
uint32_t ino;
};
struct ebus_intr_map_mask {
uint32_t ebus_phys_hi;
uint32_t ebus_phys_low;
uint32_t ebus_intr;
};
/*
* definition of ebus reg spec entry:
*/
typedef struct {
uint32_t addr_hi;
uint32_t addr_low;
uint32_t size;
} ebus_regspec_t;
/* Range entry for 3-cell parent address */
struct ebus_pci_rangespec {
uint32_t phys_hi; /* Child hi range address */
uint32_t phys_low; /* Child low range address */
uint32_t par_phys_hi; /* Parent hi rng addr */
uint32_t par_phys_mid; /* Parent mid rng addr */
uint32_t par_phys_low; /* Parent low rng addr */
uint32_t rng_size; /* Range size */
};
/* Range entry for 2-cell parent address */
struct ebus_jbus_rangespec {
uint32_t phys_hi; /* Child hi range address */
uint32_t phys_low; /* Child low range address */
uint32_t par_phys_hi; /* Parent hi rng addr */
uint32_t par_phys_low; /* Parent low rng addr */
uint32_t rng_size; /* Range size */
};
typedef union vrangespec {
struct ebus_pci_rangespec pci_rangespec;
struct ebus_jbus_rangespec jbus_rangespec;
} vrangespec_t;
typedef union vregspec {
struct pci_phys_spec pci_regspec;
struct regspec jbus_regspec;
} vregspec_t;
/*
* driver soft state structure:
*/
typedef struct {
dev_info_t *dip;
driver_state_t state;
pci_regspec_t *reg;
int nreg;
vrangespec_t *vrangep;
int vrange_len;
int vrange_cnt;
kmutex_t ebus_mutex;
uint_t ebus_soft_state;
#define EBUS_SOFT_STATE_CLOSED 0x00
#define EBUS_SOFT_STATE_OPEN 0x01
#define EBUS_SOFT_STATE_OPEN_EXCL 0x02
#if defined(i86pc)
ddi_iblock_cookie_t iblock;
ddi_idevice_cookie_t idevice;
ebus_intr_slot_t intr_slot[MAX_EBUS_DEVS];
#endif
#if defined(__sparc)
/* Interrupt support */
int intr_map_size;
struct ebus_intr_map *intr_map;
struct ebus_intr_map_mask *intr_map_mask;
#endif
int ebus_addr_cells;
int ebus_paddr_cells;
int ebus_psz_cells;
int ebus_sz_cells;
} ebus_devstate_t;
/*
* use macros for soft state and driver properties:
*/
#define get_ebus_soft_state(i) \
((ebus_devstate_t *)ddi_get_soft_state(per_ebus_state, (i)))
#define alloc_ebus_soft_state(i) \
ddi_soft_state_zalloc(per_ebus_state, (i))
#define free_ebus_soft_state(i) \
ddi_soft_state_free(per_ebus_state, (i))
#define getprop(dip, name, addr, intp) \
ddi_getlongprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
(name), (caddr_t)(addr), (intp))
#define IS_RIO(dip) \
((ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, \
"device-id", -1) == 0x1100) && \
(ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, \
"vendor-id", -1) == 0x108e))
#define EBUS_4MHZ 4000
/*
* register offsets and lengths:
*/
#define TCR_OFFSET 0x710000
#define TCR_LENGTH 12
/*
* timing control register settings:
*/
#define TCR1 0x08101008
#define TCR2 0x08100020
#define TCR3 0x00000020
#if defined(DEBUG)
#define D_IDENTIFY 0x00000001
#define D_ATTACH 0x00000002
#define D_DETACH 0x00000004
#define D_MAP 0x00000008
#define D_CTLOPS 0x00000010
#define D_INTR 0x00000100
#define DBG(flag, psp, fmt) \
ebus_debug(flag, psp, fmt, 0, 0, 0, 0, 0);
#define DBG1(flag, psp, fmt, a1) \
ebus_debug(flag, psp, fmt, (uintptr_t)(a1), 0, 0, 0, 0);
#define DBG2(flag, psp, fmt, a1, a2) \
ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
#define DBG3(flag, psp, fmt, a1, a2, a3) \
ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
(uintptr_t)(a3), 0, 0);
#define DBG4(flag, psp, fmt, a1, a2, a3, a4) \
ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
(uintptr_t)(a3), \
(uintptr_t)(a4), 0);
#define DBG5(flag, psp, fmt, a1, a2, a3, a4, a5) \
ebus_debug(flag, psp, fmt, (uintptr_t)(a1), (uintptr_t)(a2), \
(uintptr_t)(a3), \
(uintptr_t)(a4), (uintptr_t)(a5));
static void
ebus_debug(uint_t, ebus_devstate_t *, char *, uintptr_t, uintptr_t, uintptr_t,
uintptr_t, uintptr_t);
#else
#define DBG(flag, psp, fmt)
#define DBG1(flag, psp, fmt, a1)
#define DBG2(flag, psp, fmt, a1, a2)
#define DBG3(flag, psp, fmt, a1, a2, a3)
#define DBG4(flag, psp, fmt, a1, a2, a3, a4)
#define DBG5(flag, psp, fmt, a1, a2, a3, a4, a5)
#endif
#ifdef __cplusplus
}
#endif
#endif /* _SYS_EBUS_H */
|