1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright (c)  * Copyright (c) 2001 Tadpole Technology plc
27  * All rights reserved.
28  * From "@(#)pcicfg.c   1.31    99/06/18 SMI"
29  */
30 
31 /*
32  * Copyright 2023 Oxide Computer Company
33  */
34 
35 /*
36  * Cardbus configurator
37  */
38 
39 #include <sys/ddi.h>
40 #include <sys/sunndi.h>
41 #include <sys/ndi_impldefs.h>
42 
43 #include <sys/pci.h>
44 #include <sys/ebus.h>
45 #include <sys/hotplug/hpctrl.h>
46 #include <sys/hotplug/pci/pcicfg.h>
47 
48 #include <sys/pctypes.h>
49 #include <sys/pcmcia.h>
50 #include <sys/sservice.h>
51 
52 #include <sys/isa_defs.h>
53 
54 #include <sys/note.h>
55 
56 #include <sys/ethernet.h>
57 
58 #include "cardbus.h"
59 #include "cardbus_parse.h"
60 #include "cardbus_cfg.h"
61 
62 /*
63  * ************************************************************************
64  * *** Implementation specific local data structures/definitions.       ***
65  * ************************************************************************
66  */
67 
68 #define	PCICFG_MAX_DEVICE 32
69 #define	PCICFG_MAX_FUNCTION 8
70 
71 static uint32_t pcicfg_max_device = PCICFG_MAX_DEVICE;
72 static uint32_t pcicfg_max_function = PCICFG_MAX_FUNCTION;
73 
74 #define	PCICFG_NODEVICE 42
75 #define	PCICFG_NOMEMORY 43
76 #define	PCICFG_NOMULTI  44
77 
78 #define	PCICFG_HIADDR(n) ((uint32_t)(((uint64_t)(n) & 0xFFFFFFFF00000000)>> 32))
79 #define	PCICFG_LOADDR(n) ((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
80 #define	PCICFG_LADDR(lo, hi)    (((uint64_t)(hi) << 32) | (uint32_t)(lo))
81 
82 #define	PCICFG_HIWORD(n) ((uint16_t)(((uint32_t)(n) & 0xFFFF0000)>> 16))
83 #define	PCICFG_LOWORD(n) ((uint16_t)((uint32_t)(n) & 0x0000FFFF))
84 #define	PCICFG_HIBYTE(n) ((uint8_t)(((uint16_t)(n) & 0xFF00)>> 8))
85 #define	PCICFG_LOBYTE(n) ((uint8_t)((uint16_t)(n) & 0x00FF))
86 
87 #define	PCICFG_ROUND_UP(addr, gran) ((uintptr_t)((gran+addr-1)&(~(gran-1))))
88 #define	PCICFG_ROUND_DOWN(addr, gran) ((uintptr_t)((addr) & ~(gran-1)))
89 
90 #define	PCICFG_MEMGRAN 0x100000
91 #define	PCICFG_IOGRAN 0x1000
92 #define	PCICFG_4GIG_LIMIT 0xFFFFFFFFUL
93 #define	CBCFG_MEMGRAN 0x1000
94 #define	CBCFG_IOGRAN 0x4
95 
96 #define	PCICFG_MEM_MULT 4
97 #define	PCICFG_IO_MULT 4
98 #define	PCICFG_RANGE_LEN 2 /* Number of range entries */
99 
100 /*
101  * ISA node declaration structure.
102  */
103 struct isa_node {
104 	char	*name;
105 	char	*compatible[5];
106 	char	*type;
107 	char	*model;
108 	uint16_t	reg;
109 	uint16_t	span;
110 };
111 
112 struct cardbus_name_entry {
113 	uint32_t class_code;
114 	char  *name;
115 	int pil;
116 };
117 
118 struct cardbus_find_ctrl {
119 	uint_t		bus;
120 	uint_t		device;
121 	uint_t		function;
122 	dev_info_t	*dip;
123 };
124 
125 #define	PCICFG_MAKE_REG_HIGH(busnum, devnum, funcnum, register)\
126 	(\
127 	((ulong_t)(busnum & 0xff) << 16)    |\
128 	((ulong_t)(devnum & 0x1f) << 11)    |\
129 	((ulong_t)(funcnum & 0x7) <<  8)    |\
130 	((ulong_t)(register & 0x3f)))
131 
132 typedef struct cardbus_phdl cardbus_phdl_t;
133 
134 struct cardbus_phdl {
135 
136 	dev_info_t	*dip;	/* Associated with the attach point */
137 	dev_info_t	*res_dip; /* dip from which io/mem is allocated */
138 	cardbus_phdl_t  *next;
139 
140 	uint64_t	memory_base;    /* Memory base for this attach point */
141 	uint64_t	memory_last;
142 	uint64_t	memory_len;
143 	uint32_t	memory_gran;
144 	uint32_t	io_base;	/* I/O base for this attach point */
145 	uint32_t	io_last;
146 	uint32_t	io_len;
147 	uint32_t	io_gran;
148 
149 	int	error;
150 	uint_t	highest_bus;    /* Highest bus seen on the probe */
151 	ndi_ra_request_t mem_req;	/* allocator request for memory */
152 	ndi_ra_request_t io_req;	/* allocator request for I/O */
153 };
154 
155 typedef struct {
156 	dev_info_t  *dip;	/* Associated with the attach point */
157 	ddi_acc_handle_t handle;    /* open handle on parent PCI config space */
158 	uint32_t    io_base;	/* I/O base for this attach point */
159 	int	io_decode_reg;
160 } isa_phdl_t;
161 
162 
163 /*
164  * forward declarations for routines defined in this module (called here)
165  */
166 static cardbus_phdl_t *cardbus_find_phdl(dev_info_t *dip);
167 static cardbus_phdl_t *cardbus_create_phdl(dev_info_t *dip);
168 static int cardbus_destroy_phdl(dev_info_t *dip);
169 static int cardbus_program_ap(dev_info_t *);
170 static void cardbus_topbridge_assign(dev_info_t *, cardbus_phdl_t *);
171 static int cardbus_bridge_ranges(dev_info_t *, cardbus_phdl_t *,
172 			ddi_acc_handle_t);
173 static int cardbus_bridge_assign(dev_info_t *, void *);
174 static int cardbus_isa_bridge_ranges(dev_info_t *dip, cardbus_phdl_t *entry,
175 			ddi_acc_handle_t handle);
176 static int cardbus_add_isa_reg(dev_info_t *, void *);
177 static int cardbus_allocate_chunk(dev_info_t *, uint8_t, uint8_t);
178 static int cardbus_free_chunk(dev_info_t *);
179 static void cardbus_setup_bridge(dev_info_t *, cardbus_phdl_t *,
180 			ddi_acc_handle_t);
181 static void cardbus_update_bridge(dev_info_t *, cardbus_phdl_t *,
182 			ddi_acc_handle_t);
183 static void cardbus_get_mem(dev_info_t *, cardbus_phdl_t *, uint32_t,
184 			uint64_t *);
185 static void cardbus_get_io(dev_info_t *, cardbus_phdl_t *, uint32_t,
186 			uint32_t *);
187 static int cardbus_sum_resources(dev_info_t *, void *);
188 static int cardbus_free_bridge_resources(dev_info_t *);
189 static int cardbus_free_device_resources(dev_info_t *);
190 static int cardbus_free_resources(dev_info_t *);
191 static int cardbus_probe_bridge(cbus_t *, dev_info_t *, uint_t,
192 			uint_t, uint_t);
193 static int cardbus_probe_children(cbus_t *, dev_info_t *, uint_t, uint_t,
194 			uint_t, uint8_t *);
195 static int cardbus_add_config_reg(dev_info_t *, uint_t, uint_t, uint_t);
196 static int cardbus_add_isa_node(cbus_t *, dev_info_t *, struct isa_node *);
197 static int cardbus_config_setup(dev_info_t *, ddi_acc_handle_t *);
198 static void cardbus_config_teardown(ddi_acc_handle_t *);
199 static void cardbus_reparent_children(dev_info_t *, dev_info_t *);
200 static int cardbus_update_assigned_prop(dev_info_t *, pci_regspec_t *);
201 static int cardbus_update_available_prop(dev_info_t *, uint32_t,
202 			uint64_t, uint64_t);
203 static int cardbus_update_ranges_prop(dev_info_t *, cardbus_range_t *);
204 static int cardbus_update_reg_prop(dev_info_t *dip, uint32_t regvalue,
205 			uint_t reg_offset);
206 static int cardbus_set_standard_props(dev_info_t *parent, dev_info_t *dip,
207 			ddi_acc_handle_t config_handle);
208 static int cardbus_set_isa_props(dev_info_t *parent, dev_info_t *dip,
209 			char *name, char *compat[]);
210 static int cardbus_set_busnode_props(dev_info_t *);
211 static int cardbus_set_busnode_isaprops(dev_info_t *);
212 static int cardbus_set_childnode_props(dev_info_t *dip,
213 			ddi_acc_handle_t config_handle);
214 static void cardbus_set_bus_numbers(ddi_acc_handle_t config_handle,
215 			uint_t primary, uint_t secondary);
216 static void enable_pci_isa_bridge(dev_info_t *dip,
217 			ddi_acc_handle_t config_handle);
218 static void enable_pci_pci_bridge(dev_info_t *dip,
219 			ddi_acc_handle_t config_handle);
220 static void enable_cardbus_bridge(dev_info_t *dip,
221 			ddi_acc_handle_t config_handle);
222 static void disable_pci_pci_bridge(dev_info_t *dip,
223 			ddi_acc_handle_t config_handle);
224 static void disable_cardbus_bridge(dev_info_t *dip,
225 			ddi_acc_handle_t config_handle);
226 static void enable_cardbus_device(dev_info_t *, ddi_acc_handle_t);
227 static void disable_cardbus_device(ddi_acc_handle_t config_handle);
228 static void cardbus_force_boolprop(dev_info_t *dip, char *pname);
229 static void cardbus_force_intprop(dev_info_t *dip, char *pname,
230 			int *pval, int len);
231 static void cardbus_force_stringprop(dev_info_t *dip, char *pname,
232 			char *pval);
233 static void split_addr(char *, int *, int *);
234 #ifdef DEBUG
235 static void cardbus_dump_common_config(ddi_acc_handle_t config_handle);
236 static void cardbus_dump_device_config(ddi_acc_handle_t config_handle);
237 static void cardbus_dump_bridge_config(ddi_acc_handle_t config_handle,
238 			uint8_t header_type);
239 static void cardbus_dump_config(ddi_acc_handle_t config_handle);
240 static void cardbus_dump_reg(dev_info_t *dip, const pci_regspec_t *regspec,
241 			int nelems);
242 #endif
243 
244 static cardbus_phdl_t *cardbus_phdl_list = NULL;
245 
246 static struct cardbus_name_entry cardbus_class_lookup [] = {
247 	{ 0x001, "display", 9 },
248 	{ 0x100, "scsi", 4 },
249 	{ 0x101, "ide", 4 },
250 	{ 0x102, "fdc", 4 },
251 	{ 0x103, "ipi", 4 },
252 	{ 0x104, "raid", 4 },
253 	{ 0x200, "ethernet", 6 },
254 	{ 0x201, "token-ring", 6 },
255 	{ 0x202, "fddi", 6 },
256 	{ 0x203, "atm", 6 },
257 	{ 0x300, "display", 9 },    /* VGA card */
258 	{ 0x380, "display", 9 },    /* other - for the Raptor Card */
259 	{ 0x400, "video", 11 },
260 	{ 0x401, "sound", 11 },
261 	{ 0x500, "memory", 11 },
262 	{ 0x501, "flash", 11 },
263 	{ 0x600, "host", 11 },
264 	{ 0x601, "isa", 11 },
265 	{ 0x602, "eisa", 11 },
266 	{ 0x603, "mca", 11 },
267 	{ 0x604, "pci", 11 },
268 	{ 0x605, "pcmcia", 11 },
269 	{ 0x606, "nubus", 11 },
270 	{ 0x607, "cardbus", 11 },
271 	{ 0x680, NULL, 8 },
272 	{ 0x700, "serial", 11 },
273 	{ 0x701, "parallel", 6 },
274 	{ 0x800, "interrupt-controller", 3 },
275 	{ 0x801, "dma-controller", 3 },
276 	{ 0x802, "timer", 3 },
277 	{ 0x803, "rtc", 3 },
278 	{ 0x900, "keyboard", 8 },
279 	{ 0x901, "pen", 8 },
280 	{ 0x902, "mouse", 8 },
281 	{ 0xa00, "dock", 1 },
282 	{ 0xb00, "cpu", 1 },
283 	{ 0xc00, "firewire", 9 },
284 	{ 0xc01, "access-bus", 4 },
285 	{ 0xc02, "ssa", 4 },
286 	{ 0xc03, "usb", 9 },
287 	{ 0xc04, "fibre-channel", 6 },
288 	{ 0, 0 }
289 };
290 
291 #ifndef _DONT_USE_1275_GENERIC_NAMES
292 static char *cardbus_get_class_name(uint32_t classcode);
293 #endif /* _DONT_USE_1275_GENERIC_NAMES */
294 
295 /*
296  * Reprogram ILINE with default value only if BIOS doesn't program it
297  */
298 int
cardbus_validate_iline(dev_info_t * dip,ddi_acc_handle_t handle)299 cardbus_validate_iline(dev_info_t *dip, ddi_acc_handle_t handle)
300 {
301 	uint8_t intline = 0xff;
302 
303 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
304 	intline = pci_config_get8(handle, PCI_CONF_ILINE);
305 	if ((intline == 0) || (intline == 0xff)) {
306 		intline = ddi_getprop(DDI_DEV_T_ANY, dip,
307 		    DDI_PROP_CANSLEEP|DDI_PROP_DONTPASS,
308 		    "interrupt-line", 0xff);
309 		if (intline == (uint8_t)0xff) {
310 			intline = ddi_getprop(DDI_DEV_T_ANY,
311 			    ddi_get_parent(dip),
312 			    DDI_PROP_CANSLEEP /* |DDI_PROP_DONTPASS */,
313 			    "interrupt-line", 0xb);
314 		}
315 
316 		pci_config_put8(handle, PCI_CONF_ILINE, intline);
317 	}
318 	(void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
319 	    "interrupt-line", intline);
320 	}
321 	return (intline);
322 }
323 
324 /*
325  * This entry point is called to configure a device (and
326  * all its children) on the given bus. It is called when
327  * a new device is added to the PCI domain.  This routine
328  * will create the device tree and program the devices
329  * registers.
330  */
331 int
cardbus_configure(cbus_t * cbp)332 cardbus_configure(cbus_t *cbp)
333 {
334 	uint_t bus;
335 	int cardbus_dev, func;
336 	dev_info_t *attach_point;
337 
338 	cardbus_err(cbp->cb_dip, 6, "cardbus_configure ()\n");
339 
340 	bus = cardbus_primary_busno(cbp->cb_dip);
341 
342 	if (ndi_devi_alloc(cbp->cb_dip, DEVI_PSEUDO_NEXNAME,
343 	    (pnode_t)DEVI_SID_NODEID,
344 	    &attach_point) != NDI_SUCCESS) {
345 		cardbus_err(cbp->cb_dip, 1,
346 		    "cardbus_configure(): Failed to alloc probe node\n");
347 		return (PCICFG_FAILURE);
348 	}
349 
350 	/*
351 	 * Node name marks this node as the "attachment point".
352 	 */
353 	if (ndi_devi_set_nodename(attach_point,
354 	    "hp_attachment", 0) != NDI_SUCCESS) {
355 		cardbus_err(cbp->cb_dip, 1,
356 		    "Failed to set nodename for attachment node\n");
357 		(void) ndi_devi_free(attach_point);
358 		return (PCICFG_FAILURE);
359 	}
360 
361 	cardbus_err(ddi_get_parent(attach_point), 8,
362 	    "Set bus type to cardbus\n");
363 	(void) ddi_prop_update_string(DDI_DEV_T_NONE,
364 	    ddi_get_parent(attach_point), PCM_DEVICETYPE,
365 	    "cardbus");
366 
367 	split_addr(ddi_get_name_addr(cbp->cb_dip), &cardbus_dev, &func);
368 
369 	cardbus_err(attach_point, 8,
370 	    "Configuring [0x%x][0x%x][0x%x]\n", bus, cardbus_dev, func);
371 
372 	switch (cardbus_probe_bridge(cbp, attach_point,
373 	    bus, cardbus_dev, func)) {
374 	case PCICFG_FAILURE:
375 		cardbus_err(cbp->cb_dip, 4,
376 		    "configure failed: bus [0x%x] slot [0x%x] func [0x%x]\n",
377 		    bus, cardbus_dev, func);
378 		goto cleanup;
379 	case PCICFG_NODEVICE:
380 		cardbus_err(cbp->cb_dip, 4,
381 		    "no device: bus [0x%x] slot [0x%x] func [0x%x]\n",
382 		    bus, cardbus_dev, func);
383 		goto cleanup;
384 	default:
385 		cardbus_err(cbp->cb_dip, 9,
386 		    "configure: bus => [%d] slot => [%d] func => [%d]\n",
387 		    bus, cardbus_dev, func);
388 		break;
389 	}
390 
391 	if (cardbus_program_ap(cbp->cb_dip) == PCICFG_SUCCESS) {
392 		(void) cardbus_reparent_children(attach_point, cbp->cb_dip);
393 		(void) ndi_devi_free(attach_point);
394 		cbp->cb_nex_ops->enable_intr(cbp->cb_dip);
395 		return (PCICFG_SUCCESS);
396 	}
397 
398 	cardbus_err(cbp->cb_dip, 1, "Failed to program devices\n");
399 
400 cleanup:
401 	/*
402 	 * Clean up a partially created "probe state" tree.
403 	 * There are no resources allocated to the in the
404 	 * probe state.
405 	 */
406 
407 	cardbus_err(cbp->cb_dip, 6,
408 	    "Look up device [0x%x] function [0x%x] to clean up\n",
409 	    cardbus_dev, func);
410 
411 	cardbus_err(cbp->cb_dip, 6,
412 	    "Cleaning up device [0x%x] function [0x%x]\n",
413 	    cardbus_dev, func);
414 
415 	/*
416 	 * If this was a bridge device it will have a
417 	 * probe handle - if not, no harm in calling this.
418 	 */
419 	(void) cardbus_destroy_phdl(cbp->cb_dip);
420 
421 	if (ddi_get_child(attach_point)) {
422 		/*
423 		 * This will free up the node
424 		 */
425 		(void) ndi_devi_offline(ddi_get_child(attach_point),
426 		    NDI_UNCONFIG|NDI_DEVI_REMOVE);
427 	}
428 	(void) ndi_devi_free(attach_point);
429 
430 	return (PCICFG_FAILURE);
431 }
432 
433 int
cardbus_unconfigure(cbus_t * cbp)434 cardbus_unconfigure(cbus_t *cbp)
435 {
436 	ddi_acc_handle_t config_handle;
437 	dev_info_t *dip = cbp->cb_dip;
438 
439 	cbp->cb_nex_ops->disable_intr(dip);
440 	if (pci_config_setup(dip, &config_handle) == DDI_SUCCESS) {
441 		disable_cardbus_bridge(dip, config_handle);
442 		(void) pci_config_teardown(&config_handle);
443 	} else {
444 		cardbus_err(dip, 1,
445 		    "cardbus_unconfigure(): Failed to setup config space\n");
446 	}
447 
448 	(void) cardbus_free_chunk(dip);
449 	cardbus_err(dip, 6,
450 	    "cardbus_unconfigure: calling cardbus_free_bridge_resources\n");
451 	(void) cardbus_free_bridge_resources(dip);
452 
453 	return (PCICFG_SUCCESS);
454 }
455 
456 int
cardbus_teardown_device(dev_info_t * dip)457 cardbus_teardown_device(dev_info_t *dip)
458 {
459 	/*
460 	 * Free up resources associated with 'dip'
461 	 */
462 
463 	if (cardbus_free_resources(dip) != PCICFG_SUCCESS) {
464 		cardbus_err(dip, 1,
465 		    "cardbus_teardown_device: Failed to free resources\n");
466 		return (PCICFG_FAILURE);
467 	}
468 
469 	if (ndi_devi_offline(dip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
470 		cardbus_err(dip, 1,
471 		    "cardbus_teardown_device: "
472 		    "Failed to offline and remove node\n");
473 		return (PCICFG_FAILURE);
474 	}
475 
476 	return (PCICFG_SUCCESS);
477 }
478 
479 /*
480  * Get the primary pci bus number. This should be the lowest number
481  * in the bus-range property of our parent.
482  */
483 int
cardbus_primary_busno(dev_info_t * dip)484 cardbus_primary_busno(dev_info_t *dip)
485 {
486 	int	len, rval;
487 	char	bus_type[16] = "(unknown)";
488 	dev_info_t *par = ddi_get_parent(dip);
489 	cardbus_bus_range_t *bus_range;
490 
491 	ASSERT(strcmp(ddi_driver_name(dip), "pcic") == 0);
492 	len = sizeof (bus_type);
493 	if ((ddi_prop_op(DDI_DEV_T_ANY, par, PROP_LEN_AND_VAL_BUF,
494 	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS,
495 	    "device_type",
496 	    (caddr_t)&bus_type, &len) == DDI_SUCCESS)) {
497 		ASSERT((strcmp(bus_type, "pci") == 0) ||
498 		    (strcmp(bus_type, "cardbus") == 0));
499 		if (ddi_getlongprop(DDI_DEV_T_ANY, par, 0, "bus-range",
500 		    (caddr_t)&bus_range, &len) == DDI_PROP_SUCCESS) {
501 			cardbus_err(dip, 9,
502 			    "cardbus_primary_busno: bus range is %d to %d\n",
503 			    bus_range->lo, bus_range->hi);
504 			rval = (int)bus_range->lo;
505 			kmem_free((caddr_t)bus_range, len);
506 			return (rval);
507 		}
508 	}
509 
510 	cardbus_err(dip, 2,
511 	    "cardbus_primary_busno: Not a pci device or no bus-range\n");
512 	return (-1);
513 }
514 
515 static cardbus_phdl_t *
cardbus_find_phdl(dev_info_t * dip)516 cardbus_find_phdl(dev_info_t *dip)
517 {
518 	cardbus_phdl_t *entry;
519 
520 	mutex_enter(&cardbus_list_mutex);
521 	for (entry = cardbus_phdl_list; entry != NULL; entry = entry->next) {
522 		if (entry->dip == dip) {
523 			mutex_exit(&cardbus_list_mutex);
524 			return (entry);
525 		}
526 	}
527 	mutex_exit(&cardbus_list_mutex);
528 
529 	/*
530 	 * Did'nt find entry - create one
531 	 */
532 	return (cardbus_create_phdl(dip));
533 }
534 
535 static cardbus_phdl_t *
cardbus_create_phdl(dev_info_t * dip)536 cardbus_create_phdl(dev_info_t *dip)
537 {
538 	cardbus_phdl_t *new;
539 
540 	new = (cardbus_phdl_t *)kmem_zalloc(sizeof (cardbus_phdl_t), KM_SLEEP);
541 
542 	new->dip = dip;
543 	new->io_gran = CBCFG_IOGRAN;
544 	new->memory_gran = CBCFG_MEMGRAN;
545 	mutex_enter(&cardbus_list_mutex);
546 	new->next = cardbus_phdl_list;
547 	cardbus_phdl_list = new;
548 	mutex_exit(&cardbus_list_mutex);
549 
550 	return (new);
551 }
552 
553 static int
cardbus_destroy_phdl(dev_info_t * dip)554 cardbus_destroy_phdl(dev_info_t *dip)
555 {
556 	cardbus_phdl_t *entry;
557 	cardbus_phdl_t *follow = NULL;
558 	ra_return_t	res;
559 
560 	mutex_enter(&cardbus_list_mutex);
561 	for (entry = cardbus_phdl_list; entry != NULL; follow = entry,
562 	    entry = entry->next) {
563 		if (entry->dip == dip) {
564 			if (entry == cardbus_phdl_list) {
565 				cardbus_phdl_list = entry->next;
566 			} else {
567 				follow->next = entry->next;
568 			}
569 			/*
570 			 * If this entry has any allocated memory
571 			 * or IO space associated with it, that
572 			 * must be freed up.
573 			 */
574 			if (entry->memory_len > 0) {
575 				res.ra_addr_lo = entry->memory_base;
576 				res.ra_len = entry->memory_len;
577 				(void) pcmcia_free_mem(entry->res_dip, &res);
578 #ifdef  _LP64
579 				cardbus_err(dip, 8,
580 				    "cardbus_destroy_phdl: "
581 				    "MEMORY BASE = [0x%lx] length [0x%lx]\n",
582 				    entry->memory_base, entry->memory_len);
583 #else
584 				cardbus_err(dip, 8,
585 				    "cardbus_destroy_phdl: "
586 				    "MEMORY BASE = [0x%llx] length [0x%llx]\n",
587 				    entry->memory_base, entry->memory_len);
588 #endif
589 			}
590 			if (entry->io_len > 0) {
591 				res.ra_addr_lo = entry->io_base;
592 				res.ra_len = entry->io_len;
593 				(void) pcmcia_free_io(entry->res_dip, &res);
594 				cardbus_err(dip, 8,
595 				    "cardbus_destroy_phdl: "
596 				    "IO BASE = [0x%x] length [0x%x]\n",
597 				    entry->io_base, entry->io_len);
598 			}
599 			/*
600 			 * Destroy this entry
601 			 */
602 			kmem_free((caddr_t)entry, sizeof (cardbus_phdl_t));
603 			mutex_exit(&cardbus_list_mutex);
604 			return (PCICFG_SUCCESS);
605 		}
606 	}
607 
608 	mutex_exit(&cardbus_list_mutex);
609 
610 	/*
611 	 * Didn't find the entry
612 	 */
613 	return (PCICFG_FAILURE);
614 }
615 
616 static int
cardbus_program_ap(dev_info_t * dip)617 cardbus_program_ap(dev_info_t *dip)
618 {
619 	cardbus_phdl_t *phdl;
620 	uint8_t header_type, sec_bus;
621 	ddi_acc_handle_t handle;
622 
623 	if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
624 		cardbus_err(dip, 1,
625 		    "cardbus_program_ap: Failed to map config space!\n");
626 		return (PCICFG_FAILURE);
627 	}
628 
629 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
630 	sec_bus = pci_config_get8(handle, PCI_BCNF_SECBUS);
631 
632 	cardbus_err(dip, 6,
633 	    "cardbus_program_ap (header_type=0x%x)\n", header_type);
634 	(void) pci_config_teardown(&handle);
635 
636 	/*
637 	 * Header type two is PCI to Cardbus bridge, see page 43 of the
638 	 * CL-PD6832 data sheet
639 	 */
640 	switch (header_type & PCI_HEADER_TYPE_M) {
641 	case PCI_HEADER_CARDBUS:
642 		cardbus_err(dip, 8,
643 		    "cardbus_program_ap calling cardbus_allocate_chunk\n");
644 		if (cardbus_allocate_chunk(dip,
645 		    header_type & PCI_HEADER_TYPE_M,
646 		    sec_bus) != PCICFG_SUCCESS) {
647 			cardbus_err(dip, 1,
648 			    "cardbus_program_ap: "
649 			    "Not enough memory to hotplug\n");
650 			(void) cardbus_destroy_phdl(dip);
651 			return (PCICFG_FAILURE);
652 		}
653 
654 		cardbus_err(dip, 8,
655 		    "cardbus_program_ap calling cardbus_find_phdl\n");
656 		phdl = cardbus_find_phdl(dip);
657 		ASSERT(phdl);
658 
659 		if (phdl == NULL) {
660 			cardbus_err(dip, 1, "cardbus_find_phdl failed\n");
661 			return (PCICFG_FAILURE);
662 		}
663 		phdl->error = PCICFG_SUCCESS;
664 		cardbus_err(dip, 8,
665 		    "cardbus_program_ap calling cardbus_topbridge_assign\n");
666 		cardbus_topbridge_assign(dip, phdl);
667 
668 		if (phdl->error != PCICFG_SUCCESS) {
669 			cardbus_err(dip, 1, "Problem assigning bridge\n");
670 			(void) cardbus_destroy_phdl(dip);
671 			return (phdl->error);
672 		}
673 		break;
674 
675 	default:
676 		return (PCICFG_FAILURE);
677 	}
678 
679 	return (PCICFG_SUCCESS);
680 }
681 
682 static void
cardbus_topbridge_assign(dev_info_t * dip,cardbus_phdl_t * entry)683 cardbus_topbridge_assign(dev_info_t *dip, cardbus_phdl_t *entry)
684 {
685 	ddi_acc_handle_t handle;
686 	uint8_t header_type;
687 
688 	cardbus_err(dip, 6, "cardbus_topbridge_assign\n");
689 
690 	if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
691 		cardbus_err(dip, 1,
692 		    "cardbus_topbridge_bridge_assign: "
693 		    "Failed to map config space!\n");
694 		return;
695 	}
696 
697 	header_type = pci_config_get8(handle,
698 	    PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
699 
700 	/* cardbus bridge is the same as PCI-PCI bridge */
701 	ASSERT((header_type == PCI_HEADER_PPB) ||
702 	    (header_type == PCI_HEADER_CARDBUS));
703 
704 	(void) cardbus_bridge_ranges(dip, entry, handle);
705 
706 	(void) pci_config_teardown(&handle);
707 }
708 
709 static int
cardbus_bridge_ranges(dev_info_t * dip,cardbus_phdl_t * entry,ddi_acc_handle_t handle)710 cardbus_bridge_ranges(dev_info_t *dip, cardbus_phdl_t *entry,
711     ddi_acc_handle_t handle)
712 {
713 	cardbus_range_t range[PCICFG_RANGE_LEN];
714 	int bus_range[2];
715 	int i;
716 
717 	cardbus_err(dip, 8, "cardbus_bridge_ranges\n");
718 
719 	bzero((caddr_t)range, sizeof (cardbus_range_t) * PCICFG_RANGE_LEN);
720 
721 	(void) cardbus_setup_bridge(dip, entry, handle);
722 
723 	range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
724 	range[0].child_lo = range[0].parent_lo = entry->io_last;
725 	range[1].child_hi = range[1].parent_hi |=
726 	    (PCI_REG_REL_M | PCI_ADDR_MEM32);
727 	range[1].child_lo = range[1].parent_lo = entry->memory_last;
728 
729 	ndi_devi_enter(dip);
730 	ddi_walk_devs(ddi_get_child(dip), cardbus_bridge_assign, (void *)entry);
731 	ndi_devi_exit(dip);
732 
733 	(void) cardbus_update_bridge(dip, entry, handle);
734 
735 	bus_range[0] = pci_config_get8(handle, PCI_BCNF_SECBUS);
736 	bus_range[1] = pci_config_get8(handle, PCI_BCNF_SUBBUS);
737 
738 	cardbus_err(dip, 8,
739 	    "Set up bus-range property to %u->%u\n",
740 	    bus_range[0], bus_range[1]);
741 
742 	if ((i = ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
743 	    "bus-range",
744 	    bus_range, 2)) != DDI_SUCCESS) {
745 
746 		if (i == DDI_PROP_NOT_FOUND) {
747 			cardbus_err(dip, 8,
748 			    "Create bus-range property, %u->%u\n",
749 			    bus_range[0], bus_range[1]);
750 			i = ddi_prop_create(DDI_DEV_T_NONE, dip,
751 			    DDI_PROP_CANSLEEP,
752 			    "bus-range", (caddr_t)bus_range,
753 			    sizeof (bus_range));
754 		}
755 
756 		if (i != DDI_PROP_SUCCESS) {
757 			cardbus_err(dip, 1,
758 			    "Failed to set bus-range property, %u->%u (%d)\n",
759 			    bus_range[0], bus_range[1], i);
760 			entry->error = PCICFG_FAILURE;
761 			return (DDI_WALK_TERMINATE);
762 		}
763 	}
764 
765 	if (entry->io_len > 0) {
766 		range[0].size_lo = entry->io_last - entry->io_base;
767 		if (cardbus_update_ranges_prop(dip, &range[0])) {
768 			cardbus_err(dip, 1, "Failed to update ranges (i/o)\n");
769 			entry->error = PCICFG_FAILURE;
770 			return (DDI_WALK_TERMINATE);
771 		}
772 	}
773 	if (entry->memory_len > 0) {
774 		range[1].size_lo = entry->memory_last - entry->memory_base;
775 		if (cardbus_update_ranges_prop(dip, &range[1])) {
776 			cardbus_err(dip, 1,
777 			    "Failed to update ranges (memory)\n");
778 			entry->error = PCICFG_FAILURE;
779 			return (DDI_WALK_TERMINATE);
780 		}
781 	}
782 
783 	return (DDI_WALK_PRUNECHILD);
784 }
785 static int
cardbus_bridge_assign(dev_info_t * dip,void * hdl)786 cardbus_bridge_assign(dev_info_t *dip, void *hdl)
787 {
788 	ddi_acc_handle_t handle;
789 	pci_regspec_t *reg;
790 	int length;
791 	int rcount;
792 	int i;
793 	int offset;
794 	uint64_t mem_answer;
795 	uint32_t io_answer, request;
796 	uint8_t header_type, base_class;
797 	cardbus_phdl_t *entry = (cardbus_phdl_t *)hdl;
798 
799 	/*
800 	 * Ignore the attachment point and pcs.
801 	 */
802 	if (strcmp(ddi_binding_name(dip), "hp_attachment") == 0 ||
803 	    strcmp(ddi_binding_name(dip), "pcs") == 0) {
804 		cardbus_err(dip, 8, "cardbus_bridge_assign: Ignoring\n");
805 		return (DDI_WALK_CONTINUE);
806 	}
807 
808 
809 	cardbus_err(dip, 6, "cardbus_bridge_assign\n");
810 
811 	if (entry == NULL) {
812 		cardbus_err(dip, 1, "Failed to get entry\n");
813 		return (DDI_WALK_TERMINATE);
814 	}
815 	if (cardbus_config_setup(dip, &handle) != DDI_SUCCESS) {
816 		cardbus_err(dip, 1,
817 		    "cardbus_bridge_assign: Failed to map config space!\n");
818 		entry->error = PCICFG_FAILURE;
819 		return (DDI_WALK_TERMINATE);
820 	}
821 
822 	header_type = pci_config_get8(handle, PCI_CONF_HEADER) &
823 	    PCI_HEADER_TYPE_M;
824 	base_class = pci_config_get8(handle, PCI_CONF_BASCLASS);
825 
826 	/*
827 	 * This function is not called for the top bridge and we are
828 	 * not enumerating down a further cardbus interface yet!
829 	 */
830 	if (base_class == PCI_CLASS_BRIDGE) {
831 		uint8_t	sub_class;
832 
833 		sub_class = pci_config_get8(handle, PCI_CONF_SUBCLASS);
834 
835 		switch (sub_class) {
836 		case PCI_BRIDGE_PCI:
837 			if (header_type == PCI_HEADER_PPB) {
838 				i = cardbus_bridge_ranges(dip, entry, handle);
839 				(void) cardbus_config_teardown(&handle);
840 				return (i);
841 			}
842 			goto bad_device;
843 
844 		case PCI_BRIDGE_ISA:
845 			i = cardbus_isa_bridge_ranges(dip, entry, handle);
846 			(void) cardbus_config_teardown(&handle);
847 			return (i);
848 
849 		case PCI_BRIDGE_CARDBUS:
850 			/*
851 			 * Fall through, there should be at least one register
852 			 * set for this.
853 			 */
854 			break;
855 
856 		case PCI_BRIDGE_OTHER:
857 		default:
858 			break;
859 		}
860 	}
861 
862 #ifdef sparc
863 	/*
864 	 * If there is an interrupt pin set program
865 	 * interrupt line with default values.
866 	 */
867 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
868 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
869 	}
870 #else
871 	(void) cardbus_validate_iline(dip, handle);
872 #endif
873 
874 	/*
875 	 * A single device (under a bridge).
876 	 * For each "reg" property with a length, allocate memory
877 	 * and program the base registers.
878 	 */
879 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
880 	    DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
881 	    &length) != DDI_PROP_SUCCESS) {
882 		cardbus_err(dip, 1, "Failed to read reg property\n");
883 		entry->error = PCICFG_FAILURE;
884 		(void) cardbus_config_teardown(&handle);
885 		return (DDI_WALK_TERMINATE);
886 	}
887 
888 	rcount = length / sizeof (pci_regspec_t);
889 	cardbus_err(dip, 9, "rcount = %d\n", rcount);
890 
891 	for (i = 0; i < rcount; i++) {
892 		if ((reg[i].pci_size_low != 0) || (reg[i].pci_size_hi != 0)) {
893 			offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
894 			switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
895 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
896 
897 				(void) cardbus_get_mem(ddi_get_parent(dip),
898 				    entry, reg[i].pci_size_low, &mem_answer);
899 				ASSERT(!PCICFG_HIADDR(mem_answer));
900 				pci_config_put32(handle, offset,
901 				    PCICFG_LOADDR(mem_answer));
902 				pci_config_put32(handle, offset + 4,
903 				    PCICFG_HIADDR(mem_answer));
904 				cardbus_err(dip, 8,
905 				    "REGISTER (64)LO [0x%x] ----> [0x%02x]\n",
906 				    pci_config_get32(handle, offset), offset);
907 				cardbus_err(dip, 8,
908 				    "REGISTER (64)HI [0x%x] ----> [0x%02x]\n",
909 				    pci_config_get32(handle, offset + 4),
910 				    offset + 4);
911 				reg[i].pci_phys_low = PCICFG_HIADDR(mem_answer);
912 				reg[i].pci_phys_mid = PCICFG_LOADDR(mem_answer);
913 				break;
914 
915 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
916 				/* allocate memory space from the allocator */
917 
918 				(void) cardbus_get_mem(ddi_get_parent(dip),
919 				    entry, reg[i].pci_size_low, &mem_answer);
920 				pci_config_put32(handle, offset, 0xffffffff);
921 				request = pci_config_get32(handle, offset);
922 
923 				pci_config_put32(handle, offset,
924 				    (uint32_t)mem_answer);
925 				reg[i].pci_phys_low = (uint32_t)mem_answer;
926 				reg[i].pci_phys_mid = 0;
927 				if (((PCI_BASE_TYPE_M & request) ==
928 				    PCI_BASE_TYPE_ALL) &&
929 				    ((PCI_BASE_SPACE_M & request) ==
930 				    PCI_BASE_SPACE_MEM)) {
931 					cardbus_err(dip, 8,
932 					    "REGISTER (64)LO [0x%x] ----> "
933 					    "[0x%02x]\n",
934 					    pci_config_get32(handle, offset),
935 					    offset);
936 					pci_config_put32(handle, offset + 4, 0);
937 					cardbus_err(dip, 8,
938 					    "REGISTER (64)HI [0x%x] ----> "
939 					    "[0x%02x]\n",
940 					    pci_config_get32(handle, offset+4),
941 					    offset + 4);
942 				} else {
943 					cardbus_err(dip, 8,
944 					    "REGISTER (32)LO [0x%x] ----> "
945 					    "[0x%02x]\n",
946 					    pci_config_get32(handle, offset),
947 					    offset);
948 				}
949 				break;
950 
951 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
952 				/* allocate I/O space from the allocator */
953 
954 				(void) cardbus_get_io(ddi_get_parent(dip),
955 				    entry, reg[i].pci_size_low, &io_answer);
956 				pci_config_put32(handle, offset, io_answer);
957 				cardbus_err(dip, 8,
958 				    "REGISTER (I/O)LO [0x%x] ----> [0x%02x]\n",
959 				    pci_config_get32(handle, offset), offset);
960 				reg[i].pci_phys_low = io_answer;
961 				break;
962 
963 			default:
964 				cardbus_err(dip, 1, "Unknown register type\n");
965 				kmem_free(reg, length);
966 				(void) cardbus_config_teardown(&handle);
967 				entry->error = PCICFG_FAILURE;
968 				return (DDI_WALK_TERMINATE);
969 			} /* switch */
970 
971 			/*
972 			 * Now that memory locations are assigned,
973 			 * update the assigned address property.
974 			 */
975 			if (cardbus_update_assigned_prop(dip,
976 			    &reg[i]) != PCICFG_SUCCESS) {
977 				kmem_free(reg, length);
978 				(void) cardbus_config_teardown(&handle);
979 				entry->error = PCICFG_FAILURE;
980 				return (DDI_WALK_TERMINATE);
981 			}
982 		}
983 	}
984 	kmem_free(reg, length);
985 	enable_cardbus_device(dip, handle);
986 #ifdef CARDBUS_DEBUG
987 	if (cardbus_debug >= 9) {
988 		cardbus_dump_config(handle);
989 	}
990 #endif
991 bad_device:
992 	(void) cardbus_config_teardown(&handle);
993 	return (DDI_WALK_CONTINUE);
994 }
995 
996 static int
cardbus_isa_bridge_ranges(dev_info_t * dip,cardbus_phdl_t * entry,ddi_acc_handle_t handle)997 cardbus_isa_bridge_ranges(dev_info_t *dip, cardbus_phdl_t *entry,
998     ddi_acc_handle_t handle)
999 {
1000 	struct ebus_pci_rangespec range;
1001 	pci_regspec_t *reg;
1002 	int length;
1003 	int rcount;
1004 	uint32_t io_answer = 0xffffffff;
1005 	isa_phdl_t isa_phdl;
1006 	int i;
1007 
1008 	cardbus_err(dip, 8, "cardbus_isa_bridge_ranges\n");
1009 
1010 	bzero((caddr_t)&range, sizeof (range));
1011 
1012 #ifdef sparc
1013 	/*
1014 	 * If there is an interrupt pin set program
1015 	 * interrupt line with default values.
1016 	 */
1017 	if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1018 		pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1019 	}
1020 #else
1021 	(void) cardbus_validate_iline(dip, handle);
1022 #endif
1023 
1024 	/*
1025 	 * For each "reg" property with a length, allocate memory.
1026 	 */
1027 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1028 	    DDI_PROP_DONTPASS, "reg", (caddr_t)&reg,
1029 	    &length) != DDI_PROP_SUCCESS) {
1030 		cardbus_err(dip, 1, "Failed to read reg property\n");
1031 		entry->error = PCICFG_FAILURE;
1032 		return (DDI_WALK_TERMINATE);
1033 	}
1034 
1035 	rcount = length / sizeof (pci_regspec_t);
1036 
1037 	for (i = 0; i < rcount; i++) {
1038 		if ((reg[i].pci_size_low != 0) || (reg[i].pci_size_hi != 0)) {
1039 			switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
1040 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
1041 				/* allocate I/O space from the allocator */
1042 
1043 				(void) cardbus_get_io(ddi_get_parent(dip),
1044 				    entry, reg[i].pci_size_low, &io_answer);
1045 				cardbus_err(dip, 8,
1046 				    "ISA (I/O)LO ----> [0x%x]\n", io_answer);
1047 				reg[i].pci_phys_low = io_answer;
1048 				range.phys_hi = 0;
1049 				range.phys_low = io_answer;
1050 				range.par_phys_hi =
1051 				    reg[i].pci_phys_hi | PCI_REG_REL_M;
1052 				range.par_phys_low = reg[i].pci_phys_low;
1053 				range.par_phys_mid = reg[i].pci_phys_mid;
1054 				range.rng_size = reg[i].pci_size_low;
1055 				i = rcount;
1056 				break;
1057 
1058 			default:
1059 				cardbus_err(dip, 1, "Unknown register type\n");
1060 				kmem_free(reg, length);
1061 				(void) cardbus_config_teardown(&handle);
1062 				entry->error = PCICFG_FAILURE;
1063 				return (DDI_WALK_TERMINATE);
1064 			} /* switch */
1065 		}
1066 	}
1067 	kmem_free(reg, length);
1068 
1069 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
1070 	    dip, "ranges", (int *)&range,
1071 	    sizeof (range)/sizeof (int));
1072 	if (io_answer != 0xffffffff) {
1073 		isa_phdl.dip = dip;
1074 		isa_phdl.handle = handle;
1075 		isa_phdl.io_base = io_answer;
1076 		isa_phdl.io_decode_reg = 0x58; /* Pos decoded IO space 0 reg */
1077 		/* i_ndi_block_device_tree_changes(&count); */
1078 		ndi_devi_enter(dip);
1079 		ddi_walk_devs(ddi_get_child(dip),
1080 		    cardbus_add_isa_reg, (void *)&isa_phdl);
1081 		/* i_ndi_allow_device_tree_changes(count); */
1082 		ndi_devi_exit(dip);
1083 	}
1084 	return (DDI_WALK_PRUNECHILD);
1085 }
1086 
1087 /*
1088  * This is specific to ITE8888 chip.
1089  */
1090 static int
cardbus_add_isa_reg(dev_info_t * dip,void * arg)1091 cardbus_add_isa_reg(dev_info_t *dip, void *arg)
1092 {
1093 	uint32_t	io_reg = 0;
1094 	int		length;
1095 	uint32_t	reg[3], *breg;
1096 	isa_phdl_t	*phdl;
1097 	uint8_t		sz;
1098 
1099 	phdl = (isa_phdl_t *)arg;
1100 	cardbus_err(dip, 6,
1101 	    "cardbus_add_isa_reg, base 0x%x\n", phdl->io_base);
1102 
1103 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1104 	    DDI_PROP_DONTPASS, "basereg", (caddr_t)&breg,
1105 	    &length) != DDI_PROP_SUCCESS) {
1106 		return (DDI_WALK_CONTINUE);
1107 	}
1108 
1109 	if ((length / sizeof (reg)) < 1) {
1110 		kmem_free(breg, length);
1111 		return (DDI_WALK_CONTINUE);
1112 	}
1113 
1114 	/*
1115 	 * Add the "reg" property.
1116 	 */
1117 	reg[0] = 0;
1118 	reg[1] = breg[1] + phdl->io_base;
1119 	reg[2] = breg[2];
1120 
1121 	/*
1122 	 * Generate the postive IO decode register setting.
1123 	 */
1124 	for (sz = 0; sz < 8; sz++)
1125 		if ((1<<sz) >= breg[2]) {
1126 			io_reg = breg[1]
1127 			    | (1uL <<31) /* Enable */
1128 			    | (2uL <<29) /* Medium speed */
1129 			    | (1uL <<28) /* Aliase enable, */
1130 					/* Don't care A[15:10] */
1131 			    | (sz<<24); /* Size code */
1132 			break;
1133 		}
1134 
1135 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1136 	    "reg", (int *)reg, 3);
1137 	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "basereg");
1138 
1139 	if (io_reg) {
1140 		pci_config_put32(phdl->handle, phdl->io_decode_reg, io_reg);
1141 		cardbus_err(dip, 6,
1142 		    "cardbus_add_isa_reg: I/O decode reg (0x%x) set to 0x%x\n",
1143 		    phdl->io_decode_reg,
1144 		    pci_config_get32(phdl->handle, phdl->io_decode_reg));
1145 		phdl->io_decode_reg += sizeof (io_reg);
1146 	} else
1147 		cardbus_err(dip, 1,
1148 		    "cardbus_add_isa_reg: register size (0x%x) too large\n",
1149 		    breg[2]);
1150 	kmem_free(breg, length);
1151 	return (DDI_WALK_CONTINUE);
1152 }
1153 
1154 /*
1155  * In case we want to ensure that some space is allocated to the
1156  * device tree below the cardbus bridge.
1157  * This is only necessary if there is a device that needs to allocate
1158  * resource below us. This can happen if there is another cardbus/PCMCIA
1159  * bridge downstream.
1160  */
1161 static uint32_t cardbus_min_spare_mem = 0;
1162 static uint32_t cardbus_min_spare_io = 0;
1163 
1164 /*
1165  * The "dip" passed to this routine is assumed to be
1166  * the device at the attachment point. Currently it is
1167  * assumed to be a bridge.
1168  */
1169 static int
cardbus_allocate_chunk(dev_info_t * dip,uint8_t type,uint8_t sec_bus)1170 cardbus_allocate_chunk(dev_info_t *dip, uint8_t type, uint8_t sec_bus)
1171 {
1172 	cardbus_phdl_t		*phdl;
1173 	ndi_ra_request_t	*mem_request;
1174 	ndi_ra_request_t	*io_request;
1175 	ra_return_t		res;
1176 
1177 	/*
1178 	 * This should not find an existing entry - so
1179 	 * it will create a new one.
1180 	 */
1181 	phdl = cardbus_find_phdl(dip);
1182 	ASSERT(phdl);
1183 
1184 	mem_request = &phdl->mem_req;
1185 	io_request  = &phdl->io_req;
1186 
1187 	/*
1188 	 * Set highest_bus here.
1189 	 * Otherwise if we don't find another bridge
1190 	 * this never gets set.
1191 	 */
1192 	phdl->highest_bus = sec_bus;
1193 
1194 	/*
1195 	 * From this point in the tree - walk the devices,
1196 	 * The function passed in will read and "sum" up
1197 	 * the memory and I/O requirements and put them in
1198 	 * structure "phdl".
1199 	 */
1200 	phdl->error = PCICFG_SUCCESS;
1201 	ndi_devi_enter(dip);
1202 	ddi_walk_devs(ddi_get_child(dip), cardbus_sum_resources, (void *)phdl);
1203 	ndi_devi_exit(dip);
1204 
1205 	if (phdl->error != PCICFG_SUCCESS) {
1206 		cmn_err(CE_WARN, "Failure summing resources\n");
1207 		return (phdl->error);
1208 	}
1209 
1210 	/*
1211 	 * Call into the memory allocator with the request.
1212 	 * Record the addresses returned in the phdl
1213 	 */
1214 #ifdef  _LP64
1215 	cardbus_err(dip, 8,
1216 	    "AP requires [0x%lx] bytes of memory space, alligned 0x%x\n",
1217 	    mem_request->ra_len, phdl->memory_gran);
1218 	cardbus_err(dip, 8,
1219 	    "AP requires [0x%lx] bytes of I/O space, alligned 0x%x\n",
1220 	    io_request->ra_len, phdl->io_gran);
1221 #else
1222 	cardbus_err(dip, 8,
1223 	    "AP requires [0x%llx] bytes of memory space, alligned 0x%x\n",
1224 	    mem_request->ra_len, phdl->memory_gran);
1225 	cardbus_err(dip, 8,
1226 	    "AP requires [0x%llx] bytes of I/O space, alligned 0x%x\n",
1227 	    io_request->ra_len, phdl->io_gran);
1228 #endif
1229 
1230 	ASSERT(type == PCI_HEADER_CARDBUS);
1231 
1232 	mem_request->ra_align_mask = phdl->memory_gran - 1;
1233 	io_request->ra_align_mask = phdl->io_gran - 1;
1234 	phdl->res_dip = (dev_info_t *)-1;
1235 
1236 	mem_request->ra_len += cardbus_min_spare_mem;
1237 	if (mem_request->ra_len) {
1238 		mem_request->ra_len =
1239 		    PCICFG_ROUND_UP(mem_request->ra_len, phdl->memory_gran);
1240 #ifdef _LP64
1241 		cardbus_err(dip, 8,
1242 		    "cardbus_allocate_chunk: ndi_ra_alloc 0x%lx bytes\n",
1243 		    mem_request->ra_len);
1244 #else
1245 		cardbus_err(dip, 8,
1246 		    "cardbus_allocate_chunk: ndi_ra_alloc 0x%llx bytes\n",
1247 		    mem_request->ra_len);
1248 #endif
1249 
1250 		if (pcmcia_alloc_mem(dip, mem_request, &res,
1251 		    &phdl->res_dip) != NDI_SUCCESS) {
1252 			cmn_err(CE_WARN, "Failed to allocate memory for %s\n",
1253 			    ddi_driver_name(dip));
1254 			return (PCICFG_FAILURE);
1255 		}
1256 
1257 		phdl->memory_base = phdl->memory_last = res.ra_addr_lo;
1258 		phdl->memory_len = res.ra_len;
1259 	}
1260 
1261 	io_request->ra_len += cardbus_min_spare_io;
1262 	if (io_request->ra_len) {
1263 
1264 #if defined(__x86)
1265 		io_request->ra_boundbase = 0x1000;
1266 		io_request->ra_boundlen = 0xefff;
1267 #else
1268 		io_request->ra_boundbase = 0;
1269 		io_request->ra_boundlen = PCICFG_4GIG_LIMIT;
1270 #endif
1271 		io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1272 		io_request->ra_len = PCICFG_ROUND_UP(io_request->ra_len,
1273 		    phdl->io_gran);
1274 		io_request->ra_align_mask = max(PCICFG_IOGRAN,
1275 		    phdl->io_gran) - 1;
1276 
1277 		if (pcmcia_alloc_io(dip, io_request, &res,
1278 		    &phdl->res_dip) != NDI_SUCCESS) {
1279 			cmn_err(CE_WARN, "Failed to allocate I/O space "
1280 			    "for %s\n", ddi_driver_name(dip));
1281 			if (mem_request->ra_len) {
1282 				res.ra_addr_lo = phdl->memory_base;
1283 				res.ra_len = phdl->memory_len;
1284 				(void) pcmcia_free_mem(phdl->res_dip, &res);
1285 				phdl->memory_len = phdl->io_len = 0;
1286 			}
1287 			return (PCICFG_FAILURE);
1288 		}
1289 
1290 		phdl->io_base = phdl->io_last = (uint32_t)res.ra_addr_lo;
1291 		phdl->io_len  = (uint32_t)res.ra_len;
1292 	}
1293 
1294 #ifdef  _LP64
1295 	cardbus_err(dip, 6,
1296 	    "MEMORY BASE = [0x%lx] length [0x%lx]\n",
1297 	    phdl->memory_base, phdl->memory_len);
1298 #else
1299 	cardbus_err(dip, 6,
1300 	    "MEMORY BASE = [0x%llx] length [0x%llx]\n",
1301 	    phdl->memory_base, phdl->memory_len);
1302 #endif
1303 	cardbus_err(dip, 6,
1304 	    "IO BASE = [0x%x] length [0x%x]\n",
1305 	    phdl->io_base, phdl->io_len);
1306 
1307 	return (PCICFG_SUCCESS);
1308 }
1309 
1310 static int
cardbus_free_chunk(dev_info_t * dip)1311 cardbus_free_chunk(dev_info_t *dip)
1312 {
1313 	uint_t	*bus;
1314 	int	k;
1315 
1316 	cardbus_err(dip, 6, "cardbus_free_chunk\n");
1317 
1318 	(void) cardbus_destroy_phdl(dip);
1319 
1320 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1321 	    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
1322 	    &k) != DDI_PROP_SUCCESS) {
1323 		cardbus_err(dip, 1,
1324 		    "cardbus_free_chunk: Failed to read bus-range property\n");
1325 		return (PCICFG_FAILURE);
1326 	}
1327 
1328 	cardbus_err(dip, 6,
1329 	    "cardbus_free_chunk: Freeing bus [%d] range [%d]\n",
1330 	    bus[0], bus[1] - bus[0] + 1);
1331 
1332 	if (ndi_ra_free(dip,
1333 	    (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
1334 	    NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1335 		cardbus_err(dip, 1,
1336 		    "cardbus_free_chunk: Failed to free bus numbers\n");
1337 
1338 		kmem_free(bus, k);
1339 		return (PCICFG_FAILURE);
1340 	}
1341 
1342 	kmem_free(bus, k);
1343 	return (PCICFG_SUCCESS);
1344 }
1345 
1346 /*
1347  * Put bridge registers into initial state
1348  */
1349 static void
cardbus_setup_bridge(dev_info_t * dip,cardbus_phdl_t * entry,ddi_acc_handle_t handle)1350 cardbus_setup_bridge(dev_info_t *dip, cardbus_phdl_t *entry,
1351     ddi_acc_handle_t handle)
1352 {
1353 	uint8_t header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1354 
1355 #ifdef _LP64
1356 	cardbus_err(NULL, 6,
1357 	    "cardbus_setup_bridge: "
1358 	    "highest bus %d, mem_last 0x%lx, io_last 0x%x\n",
1359 	    entry->highest_bus, entry->memory_last, entry->io_last);
1360 #else
1361 	cardbus_err(NULL, 6,
1362 	    "cardbus_setup_bridge: "
1363 	    "highest bus %d, mem_last 0x%llx, io_last 0x%x\n",
1364 	    entry->highest_bus, entry->memory_last, entry->io_last);
1365 #endif
1366 
1367 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1368 		uint32_t uval;
1369 
1370 		/*
1371 		 * The highest bus seen during probing is
1372 		 * the max-subordinate bus
1373 		 */
1374 		pci_config_put8(handle, PCI_BCNF_SUBBUS, entry->highest_bus);
1375 
1376 		uval = PCICFG_ROUND_UP(entry->memory_last, PCICFG_MEMGRAN);
1377 		if (uval != entry->memory_last) {
1378 #ifdef _LP64
1379 			cardbus_err(dip, 8,
1380 			    "Adding [0x%lx] before bridge (mem)\n",
1381 			    uval - entry->memory_last);
1382 #else
1383 			cardbus_err(dip, 8,
1384 			    "Adding [0x%llx] before bridge (mem)\n",
1385 			    uval - entry->memory_last);
1386 #endif
1387 			(void) cardbus_get_mem(ddi_get_parent(dip), entry,
1388 			    uval - entry->memory_last, NULL);
1389 		}
1390 
1391 		/*
1392 		 * Program the memory base register with the
1393 		 * start of the memory range
1394 		 */
1395 #ifdef _LP64
1396 		cardbus_err(NULL, 8,
1397 		    "store 0x%x(0x%lx) in pci bridge memory base register\n",
1398 		    PCICFG_HIWORD(PCICFG_LOADDR(uval)),
1399 		    entry->memory_last);
1400 #else
1401 		cardbus_err(NULL, 8,
1402 		    "store 0x%x(0x%llx) in pci bridge memory base register\n",
1403 		    PCICFG_HIWORD(PCICFG_LOADDR(uval)),
1404 		    entry->memory_last);
1405 #endif
1406 		pci_config_put16(handle, PCI_BCNF_MEM_BASE,
1407 		    PCICFG_HIWORD(PCICFG_LOADDR(uval)));
1408 
1409 		uval = PCICFG_ROUND_UP(entry->io_last, PCICFG_IOGRAN);
1410 		if (uval != entry->io_last) {
1411 			cardbus_err(dip, 8,
1412 			    "Adding [0x%x] before bridge (I/O)\n",
1413 			    uval - entry->io_last);
1414 			(void) cardbus_get_io(ddi_get_parent(dip), entry,
1415 			    uval - entry->io_last, NULL);
1416 		}
1417 		cardbus_err(NULL, 8,
1418 		    "store 0x%02x/0x%04x(0x%x) in "
1419 		    "pci bridge I/O hi/low base register\n",
1420 		    PCICFG_HIWORD(PCICFG_LOADDR(uval)),
1421 		    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(uval))),
1422 		    entry->io_last);
1423 		/*
1424 		 * Program the I/O base register with the start of the I/O range
1425 		 */
1426 		pci_config_put8(handle, PCI_BCNF_IO_BASE_LOW,
1427 		    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(uval))));
1428 
1429 		pci_config_put16(handle, PCI_BCNF_IO_BASE_HI,
1430 		    PCICFG_HIWORD(PCICFG_LOADDR(uval)));
1431 
1432 		/*
1433 		 * Clear status bits
1434 		 */
1435 		pci_config_put16(handle, PCI_BCNF_SEC_STATUS, 0xffff);
1436 
1437 		/*
1438 		 * Turn off prefetchable range
1439 		 */
1440 		pci_config_put32(handle, PCI_BCNF_PF_BASE_LOW, 0x0000ffff);
1441 		pci_config_put32(handle, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
1442 
1443 		pci_config_put32(handle, PCI_BCNF_PF_LIMIT_HIGH, 0x0);
1444 
1445 #ifdef sparc
1446 		/*
1447 		 * If there is an interrupt pin set program
1448 		 * interrupt line with default values.
1449 		 */
1450 		if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1451 			pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1452 		}
1453 #else
1454 		(void) cardbus_validate_iline(dip, handle);
1455 #endif
1456 
1457 
1458 	} else if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_CARDBUS) {
1459 
1460 		/*
1461 		 * The highest bus seen during probing is
1462 		 * the max-subordinate bus
1463 		 */
1464 		pci_config_put8(handle, PCI_CBUS_SUB_BUS_NO,
1465 		    entry->highest_bus);
1466 
1467 		/*
1468 		 * Program the memory base register with the
1469 		 * start of the memory range
1470 		 */
1471 #ifdef _LP64
1472 		cardbus_err(NULL, 8,
1473 		    "store 0x%x(0x%lx) in "
1474 		    "cardbus memory base register 0, len 0x%lx\n",
1475 		    PCICFG_LOADDR(entry->memory_last), entry->memory_last,
1476 		    entry->memory_len);
1477 #else
1478 		cardbus_err(NULL, 8,
1479 		    "store 0x%x(0x%llx) in "
1480 		    "cardbus memory base register 0, len 0x%llx\n",
1481 		    PCICFG_LOADDR(entry->memory_last), entry->memory_last,
1482 		    entry->memory_len);
1483 #endif
1484 
1485 		pci_config_put32(handle, PCI_CBUS_MEM_BASE0,
1486 		    PCICFG_LOADDR(entry->memory_last));
1487 
1488 		/*
1489 		 * Program the I/O base register with the start of the I/O range
1490 		 */
1491 		cardbus_err(NULL, 8,
1492 		    "store 0x%x in cb IO base register 0 len 0x%x\n",
1493 		    PCICFG_LOADDR(entry->io_last),
1494 		    entry->io_len);
1495 
1496 		pci_config_put32(handle, PCI_CBUS_IO_BASE0,
1497 		    PCICFG_LOADDR(entry->io_last));
1498 
1499 		/*
1500 		 * Clear status bits
1501 		 */
1502 		pci_config_put16(handle, PCI_CBUS_SEC_STATUS, 0xffff);
1503 
1504 #ifdef sparc
1505 		/*
1506 		 * If there is an interrupt pin set program
1507 		 * interrupt line with default values.
1508 		 */
1509 		if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1510 			pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1511 		}
1512 #else
1513 		(void) cardbus_validate_iline(dip, handle);
1514 #endif
1515 
1516 
1517 		/*
1518 		 * LATER: use these registers
1519 		 */
1520 		pci_config_put32(handle, PCI_CBUS_MEM_BASE1, 0);
1521 		pci_config_put32(handle, PCI_CBUS_MEM_LIMIT1, 0);
1522 		pci_config_put32(handle, PCI_CBUS_IO_BASE1, 0);
1523 		pci_config_put32(handle, PCI_CBUS_IO_LIMIT1, 0);
1524 	} else {
1525 		cmn_err(CE_WARN, "header type 0x%x, probably unknown bridge\n",
1526 		    header_type & PCI_HEADER_TYPE_M);
1527 	}
1528 
1529 	cardbus_err(NULL, 7, "cardbus_setup_bridge complete\n");
1530 }
1531 
1532 static void
cardbus_update_bridge(dev_info_t * dip,cardbus_phdl_t * entry,ddi_acc_handle_t handle)1533 cardbus_update_bridge(dev_info_t *dip, cardbus_phdl_t *entry,
1534     ddi_acc_handle_t handle)
1535 {
1536 	uint_t length;
1537 	uint16_t word16 = pci_config_get16(handle, PCI_CONF_COMM);
1538 	const uint8_t header_type =
1539 	    pci_config_get8(handle, PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
1540 	uint32_t bridge_gran;
1541 	uint64_t rlval;
1542 
1543 	if (header_type == PCI_HEADER_CARDBUS)
1544 		bridge_gran = CBCFG_MEMGRAN;
1545 	else
1546 		bridge_gran = PCICFG_MEMGRAN;
1547 
1548 	/*
1549 	 * Program the memory limit register with the end of the memory range
1550 	 */
1551 #ifdef _LP64
1552 	cardbus_err(dip, 6,
1553 	    "cardbus_update_bridge: Mem base 0x%lx len 0x%lx "
1554 	    "last 0x%lx gran 0x%x gran end 0x%lx\n",
1555 	    entry->memory_base, entry->memory_len,
1556 	    entry->memory_last, entry->memory_gran,
1557 	    PCICFG_ROUND_UP(entry->memory_last, entry->memory_gran));
1558 #else
1559 	cardbus_err(dip, 6,
1560 	    "cardbus_update_bridge: Mem base 0x%llx len 0x%llx "
1561 	    "last 0x%llx gran 0x%x gran end 0x%lx\n",
1562 	    entry->memory_base, entry->memory_len,
1563 	    entry->memory_last, entry->memory_gran,
1564 	    PCICFG_ROUND_UP(entry->memory_last, entry->memory_gran));
1565 #endif
1566 	/*
1567 	 * Since this is a bridge, the rest of this range will
1568 	 * be responded to by the bridge.  We have to round up
1569 	 * so no other device claims it.
1570 	 */
1571 	length = PCICFG_ROUND_UP(entry->memory_last + cardbus_min_spare_mem,
1572 	    bridge_gran) - entry->memory_last;
1573 
1574 	if (length > 0) {
1575 		/*
1576 		 * This is to allow space that isn't actually being used by
1577 		 * anything to be allocated by devices such as a downstream
1578 		 * PCMCIA controller.
1579 		 */
1580 		(void) cardbus_get_mem(dip, entry, length, NULL);
1581 		cardbus_err(dip, 8,
1582 		    "Added [0x%x] at the top of the bridge (mem)\n", length);
1583 	}
1584 
1585 	if (entry->memory_len) {
1586 		if (header_type == PCI_HEADER_CARDBUS) {
1587 			rlval = PCICFG_ROUND_DOWN(entry->memory_last - 1,
1588 			    CBCFG_MEMGRAN);
1589 #ifdef _LP64
1590 			cardbus_err(dip, 8,
1591 			    "store 0x%x(0x%lx) in memory limit register 0\n",
1592 			    PCICFG_LOADDR(rlval), rlval);
1593 #else
1594 			cardbus_err(dip, 8,
1595 			    "store 0x%x(0x%llx) in memory limit register 0\n",
1596 			    PCICFG_LOADDR(rlval), rlval);
1597 #endif
1598 			pci_config_put32(handle, PCI_CBUS_MEM_LIMIT0,
1599 			    PCICFG_LOADDR(rlval));
1600 		} else {
1601 			rlval = PCICFG_ROUND_DOWN(entry->memory_last - 1,
1602 			    PCICFG_MEMGRAN);
1603 #ifdef _LP64
1604 			cardbus_err(dip, 8,
1605 			    "store 0x%x(0x%lx) in memory limit register\n",
1606 			    PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1607 			    rlval);
1608 #else
1609 			cardbus_err(dip, 8,
1610 			    "store 0x%x(0x%llx) in memory limit register\n",
1611 			    PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1612 			    rlval);
1613 #endif
1614 			pci_config_put16(handle, PCI_BCNF_MEM_LIMIT,
1615 			    PCICFG_HIWORD(PCICFG_LOADDR(rlval)));
1616 		}
1617 		word16 |= PCI_COMM_MAE;
1618 	}
1619 
1620 	cardbus_err(dip, 6,
1621 	    "cardbus_update_bridge: I/O base 0x%x len 0x%x last 0x%x "
1622 	    "gran 0x%x gran_end 0x%lx\n",
1623 	    entry->io_base, entry->io_len, entry->io_last, entry->io_gran,
1624 	    PCICFG_ROUND_UP(entry->io_last, entry->io_gran));
1625 
1626 	if (header_type == PCI_HEADER_CARDBUS)
1627 		bridge_gran = CBCFG_IOGRAN;
1628 	else
1629 		bridge_gran = PCICFG_IOGRAN;
1630 
1631 	/*
1632 	 * Same as above for I/O space. Since this is a
1633 	 * bridge, the rest of this range will be responded
1634 	 * to by the bridge.  We have to round up so no
1635 	 * other device claims it.
1636 	 */
1637 	length = PCICFG_ROUND_UP(entry->io_last + cardbus_min_spare_io,
1638 	    bridge_gran) - entry->io_last;
1639 	if (length > 0) {
1640 		(void) cardbus_get_io(dip, entry, length, NULL);
1641 		cardbus_err(dip, 8,
1642 		    "Added [0x%x] at the top of the bridge (I/O)\n",  length);
1643 	}
1644 
1645 	/*
1646 	 * Program the I/O limit register with the end of the I/O range
1647 	 */
1648 	if (entry->io_len) {
1649 		if (header_type == PCI_HEADER_CARDBUS) {
1650 			rlval = PCICFG_ROUND_DOWN(entry->io_last - 1,
1651 			    CBCFG_IOGRAN);
1652 #ifdef _LP64
1653 			cardbus_err(dip, 8,
1654 			    "store 0x%lx in IO limit register 0\n", rlval);
1655 #else
1656 			cardbus_err(dip, 8,
1657 			    "store 0x%llx in IO limit register 0\n", rlval);
1658 #endif
1659 			pci_config_put32(handle, PCI_CBUS_IO_LIMIT0, rlval);
1660 		} else {
1661 			rlval = PCICFG_ROUND_DOWN(entry->io_last - 1,
1662 			    PCICFG_IOGRAN);
1663 #ifdef _LP64
1664 			cardbus_err(dip, 8,
1665 			    "store 0x%x/0x%x(0x%lx) in "
1666 			    "IO limit low/hi register\n",
1667 			    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(rlval))),
1668 			    PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1669 			    rlval);
1670 #else
1671 			cardbus_err(dip, 8,
1672 			    "store 0x%x/0x%x(0x%llx) in "
1673 			    "IO limit low/hi register\n",
1674 			    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(rlval))),
1675 			    PCICFG_HIWORD(PCICFG_LOADDR(rlval)),
1676 			    rlval);
1677 #endif
1678 
1679 			pci_config_put8(handle, PCI_BCNF_IO_LIMIT_LOW,
1680 			    PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(rlval))));
1681 			pci_config_put16(handle, PCI_BCNF_IO_LIMIT_HI,
1682 			    PCICFG_HIWORD(PCICFG_LOADDR(rlval)));
1683 		}
1684 		word16 |= PCI_COMM_IO;
1685 	}
1686 
1687 	pci_config_put16(handle, PCI_CONF_COMM, word16);
1688 }
1689 
1690 static void
cardbus_get_mem(dev_info_t * dip,cardbus_phdl_t * entry,uint32_t length,uint64_t * ans)1691 cardbus_get_mem(dev_info_t *dip, cardbus_phdl_t *entry,
1692     uint32_t length, uint64_t *ans)
1693 {
1694 	uint32_t hole;
1695 
1696 #ifdef  _LP64
1697 	cardbus_err(NULL, 6,
1698 	    "cardbus_get_mem: memory_last 0x%lx, length 0x%x, "
1699 	    "memory_base 0x%lx, memory_len 0x%lx ans=0x%p\n",
1700 	    entry->memory_last, length,
1701 	    entry->memory_base, entry->memory_len, (void *) ans);
1702 #else
1703 	cardbus_err(NULL, 6,
1704 	    "cardbus_get_mem: memory_last 0x%llx, length 0x%x, "
1705 	    "memory_base 0x%llx, memory_len 0x%llx ans=0x%p\n",
1706 	    entry->memory_last, length,
1707 	    entry->memory_base, entry->memory_len, (void *) ans);
1708 #endif
1709 
1710 	if (ans) {
1711 		/*
1712 		 * Round up the request to the "size" boundary
1713 		 */
1714 		hole = PCICFG_ROUND_UP(entry->memory_last, length) -
1715 		    entry->memory_last;
1716 		if (hole != 0) {
1717 			(void) cardbus_update_available_prop(dip,
1718 			    PCI_ADDR_MEM32,
1719 			    entry->memory_last,
1720 			    (uint64_t)hole);
1721 			entry->memory_last += hole;
1722 
1723 #ifdef  _LP64
1724 			cardbus_err(NULL, 6,
1725 			    "cardbus_get_mem: "
1726 			    "rounded memory_last up by 0x%x to 0x%lx, ",
1727 			    hole, entry->memory_last);
1728 #else
1729 			cardbus_err(NULL, 6,
1730 			    "cardbus_get_mem: "
1731 			    "rounded memory_last up by 0x%x to 0x%llx, ",
1732 			    hole, entry->memory_last);
1733 #endif
1734 		}
1735 	} else
1736 		(void) cardbus_update_available_prop(dip, PCI_ADDR_MEM32,
1737 		    entry->memory_last,
1738 		    (uint64_t)length);
1739 
1740 	/*
1741 	 * These routines should parcel out the memory
1742 	 * completely.  There should never be a case of
1743 	 * over running the bounds.
1744 	 */
1745 	if ((entry->memory_last + length) >
1746 	    (entry->memory_base + entry->memory_len))
1747 		cardbus_err(NULL, 1,
1748 #ifdef  _LP64
1749 		    "cardbus_get_mem: assert will fail %ld <= %ld,"
1750 		    "(0x%lx + 0x%x) <= (0x%lx + 0x%lx)\n",
1751 #else
1752 		    "cardbus_get_mem: assert will fail %lld <= %lld, "
1753 		    "(0x%llx + 0x%x) <= (0x%llx + 0x%llx)\n",
1754 #endif
1755 		    entry->memory_last + length,
1756 		    entry->memory_base + entry->memory_len,
1757 		    entry->memory_last,
1758 		    length,
1759 		    entry->memory_base,
1760 		    entry->memory_len);
1761 
1762 	ASSERT((entry->memory_last + length) <=
1763 	    (entry->memory_base + entry->memory_len));
1764 	/*
1765 	 * If ans is NULL don't return anything,
1766 	 * they are just asking to reserve the memory.
1767 	 */
1768 	if (ans != NULL)
1769 		*ans = entry->memory_last;
1770 
1771 	/*
1772 	 * Increment to the next location
1773 	 */
1774 	entry->memory_last += length;
1775 }
1776 
1777 static void
cardbus_get_io(dev_info_t * dip,cardbus_phdl_t * entry,uint32_t length,uint32_t * ans)1778 cardbus_get_io(dev_info_t *dip, cardbus_phdl_t *entry,
1779     uint32_t length, uint32_t *ans)
1780 {
1781 	uint32_t	hole;
1782 
1783 	cardbus_err(NULL, 6,
1784 	    "cardbus_get_io: io_last 0x%x, length 0x%x, "
1785 	    "io_base 0x%x, io_len 0x%x ans=0x%p\n",
1786 	    entry->io_last, length,
1787 	    entry->io_base, entry->io_len, (void *) ans);
1788 
1789 	if (ans) {
1790 		/*
1791 		 * Round up the request to the "size" boundary
1792 		 */
1793 		hole = PCICFG_ROUND_UP(entry->io_last, length) - entry->io_last;
1794 		if (hole != 0) {
1795 			(void) cardbus_update_available_prop(dip, PCI_ADDR_IO,
1796 			    (uint64_t)entry->io_last,
1797 			    (uint64_t)hole);
1798 			entry->io_last += hole;
1799 
1800 			cardbus_err(NULL, 6,
1801 			    "cardbus_get_io: "
1802 			    "rounded io_last up by 0x%x to 0x%x, ",
1803 			    hole, entry->io_last);
1804 		}
1805 	} else
1806 		(void) cardbus_update_available_prop(dip, PCI_ADDR_IO,
1807 		    (uint64_t)entry->io_last,
1808 		    (uint64_t)length);
1809 	/*
1810 	 * These routines should parcel out the memory
1811 	 * completely.  There should never be a case of
1812 	 * over running the bounds.
1813 	 */
1814 	ASSERT((entry->io_last + length) <=
1815 	    (entry->io_base + entry->io_len));
1816 
1817 	/*
1818 	 * If ans is NULL don't return anything,
1819 	 * they are just asking to reserve the memory.
1820 	 */
1821 	if (ans != NULL)
1822 		*ans = entry->io_last;
1823 
1824 	/*
1825 	 * Increment to the next location
1826 	 */
1827 	entry->io_last += length;
1828 }
1829 
1830 static int
cardbus_sum_resources(dev_info_t * dip,void * hdl)1831 cardbus_sum_resources(dev_info_t *dip, void *hdl)
1832 {
1833 	cardbus_phdl_t *entry = (cardbus_phdl_t *)hdl;
1834 	pci_regspec_t *pci_rp;
1835 	int length;
1836 	int rcount;
1837 	int i, ret;
1838 	ndi_ra_request_t *mem_request;
1839 	ndi_ra_request_t *io_request;
1840 	uint8_t header_type, base_class;
1841 	ddi_acc_handle_t handle;
1842 
1843 	/*
1844 	 * Ignore the attachment point and pcs.
1845 	 */
1846 	if (strcmp(ddi_binding_name(dip), "hp_attachment") == 0 ||
1847 	    strcmp(ddi_binding_name(dip), "pcs") == 0) {
1848 		cardbus_err(dip, 8, "cardbus_sum_resources: Ignoring\n");
1849 		return (DDI_WALK_CONTINUE);
1850 	}
1851 
1852 	mem_request = &entry->mem_req;
1853 	io_request =  &entry->io_req;
1854 
1855 	if (cardbus_config_setup(dip, &handle) != DDI_SUCCESS) {
1856 		cardbus_err(dip, 1,
1857 		    "cardbus_sum_resources: Failed to map config space!\n");
1858 		entry->error = PCICFG_FAILURE;
1859 		return (DDI_WALK_TERMINATE);
1860 	}
1861 
1862 	ret = DDI_WALK_CONTINUE;
1863 	header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1864 	base_class = pci_config_get8(handle, PCI_CONF_BASCLASS);
1865 
1866 	/*
1867 	 * If its a bridge - just record the highest bus seen
1868 	 */
1869 	if (base_class == PCI_CLASS_BRIDGE) {
1870 		uint8_t	sub_class;
1871 
1872 		sub_class = pci_config_get8(handle, PCI_CONF_SUBCLASS);
1873 
1874 		switch (sub_class) {
1875 		case PCI_BRIDGE_PCI:
1876 			if ((header_type & PCI_HEADER_TYPE_M)
1877 			    == PCI_HEADER_PPB) {
1878 
1879 				if (entry->highest_bus < pci_config_get8(handle,
1880 				    PCI_BCNF_SECBUS)) {
1881 					entry->highest_bus = pci_config_get8(
1882 					    handle, PCI_BCNF_SECBUS);
1883 				}
1884 
1885 				(void) cardbus_config_teardown(&handle);
1886 #if defined(CARDBUS_DEBUG)
1887 				if (mem_request->ra_len !=
1888 				    PCICFG_ROUND_UP(mem_request->ra_len,
1889 				    PCICFG_MEMGRAN)) {
1890 
1891 #ifdef _LP64
1892 					cardbus_err(dip, 8,
1893 					    "Pre-align [0x%lx] to PCI bridge "
1894 					    "memory gran "
1895 					    "[0x%lx] -> [0x%lx]\n",
1896 					    PCICFG_ROUND_UP(mem_request->ra_len,
1897 					    PCICFG_MEMGRAN) -
1898 					    mem_request->ra_len,
1899 					    mem_request->ra_len,
1900 					    PCICFG_ROUND_UP(mem_request->ra_len,
1901 					    PCICFG_MEMGRAN));
1902 #else
1903 					cardbus_err(dip, 8,
1904 					    "Pre-align [0x%llx] to PCI bridge "
1905 					    "memory gran "
1906 					    "[0x%llx] -> [0x%lx]\n",
1907 					    PCICFG_ROUND_UP(mem_request->ra_len,
1908 					    PCICFG_MEMGRAN) -
1909 					    mem_request->ra_len,
1910 					    mem_request->ra_len,
1911 					    PCICFG_ROUND_UP(mem_request->ra_len,
1912 					    PCICFG_MEMGRAN));
1913 #endif
1914 				}
1915 
1916 				if (io_request->ra_len !=
1917 				    PCICFG_ROUND_UP(io_request->ra_len,
1918 				    PCICFG_IOGRAN)) {
1919 
1920 #ifdef _LP64
1921 					cardbus_err(dip, 8,
1922 					    "Pre-align [0x%lx] to PCI bridge "
1923 					    "I/O gran "
1924 					    "[0x%lx] -> [0x%lx]\n",
1925 					    PCICFG_ROUND_UP(io_request->ra_len,
1926 					    PCICFG_IOGRAN) -
1927 					    io_request->ra_len,
1928 					    io_request->ra_len,
1929 					    PCICFG_ROUND_UP(io_request->ra_len,
1930 					    PCICFG_IOGRAN));
1931 #else
1932 					cardbus_err(dip, 8,
1933 					    "Pre-align [0x%llx] to PCI bridge "
1934 					    "I/O gran "
1935 					    "[0x%llx] -> [0x%lx]\n",
1936 					    PCICFG_ROUND_UP(io_request->ra_len,
1937 					    PCICFG_IOGRAN) -
1938 					    io_request->ra_len,
1939 					    io_request->ra_len,
1940 					    PCICFG_ROUND_UP(io_request->ra_len,
1941 					    PCICFG_IOGRAN));
1942 #endif
1943 				}
1944 
1945 #endif
1946 				mem_request->ra_len = PCICFG_ROUND_UP(
1947 				    mem_request->ra_len, PCICFG_MEMGRAN);
1948 				io_request->ra_len = PCICFG_ROUND_UP(
1949 				    io_request->ra_len, PCICFG_IOGRAN);
1950 				if (entry->memory_gran < PCICFG_MEMGRAN)
1951 					entry->memory_gran = PCICFG_MEMGRAN;
1952 				if (entry->io_gran < PCICFG_IOGRAN)
1953 					entry->io_gran = PCICFG_IOGRAN;
1954 				ddi_walk_devs(ddi_get_child(dip),
1955 				    cardbus_sum_resources,
1956 				    (void *)entry);
1957 #if defined(CARDBUS_DEBUG)
1958 				if (mem_request->ra_len !=
1959 				    PCICFG_ROUND_UP(mem_request->ra_len +
1960 				    cardbus_min_spare_mem, PCICFG_MEMGRAN)) {
1961 
1962 #ifdef _LP64
1963 					cardbus_err(dip, 8,
1964 					    "Post-align [0x%lx] to PCI bridge "
1965 					    "memory gran "
1966 					    "[0x%lx] -> [0x%lx]\n",
1967 					    PCICFG_ROUND_UP(
1968 					    mem_request->ra_len +
1969 					    cardbus_min_spare_mem,
1970 					    PCICFG_MEMGRAN) -
1971 					    mem_request->ra_len,
1972 					    mem_request->ra_len,
1973 					    PCICFG_ROUND_UP(mem_request->ra_len
1974 					    + cardbus_min_spare_mem,
1975 					    PCICFG_MEMGRAN));
1976 #else
1977 					cardbus_err(dip, 8,
1978 					    "Post-align [0x%llx] to PCI bridge "
1979 					    "memory gran "
1980 					    "[0x%llx] -> [0x%lx]\n",
1981 					    PCICFG_ROUND_UP(
1982 					    mem_request->ra_len +
1983 					    cardbus_min_spare_mem,
1984 					    PCICFG_MEMGRAN) -
1985 					    mem_request->ra_len,
1986 					    mem_request->ra_len,
1987 					    PCICFG_ROUND_UP(mem_request->ra_len
1988 					    + cardbus_min_spare_mem,
1989 					    PCICFG_MEMGRAN));
1990 #endif
1991 				}
1992 
1993 				if (io_request->ra_len !=
1994 				    PCICFG_ROUND_UP(io_request->ra_len +
1995 				    cardbus_min_spare_io,
1996 				    PCICFG_IOGRAN)) {
1997 
1998 #ifdef _LP64
1999 					cardbus_err(dip, 8,
2000 					    "Post-align [0x%lx] to PCI bridge "
2001 					    "I/O gran "
2002 					    "[0x%lx] -> [0x%lx]\n",
2003 					    PCICFG_ROUND_UP(io_request->ra_len +
2004 					    cardbus_min_spare_io,
2005 					    PCICFG_IOGRAN) -
2006 					    io_request->ra_len,
2007 					    io_request->ra_len,
2008 					    PCICFG_ROUND_UP(io_request->ra_len +
2009 					    cardbus_min_spare_io,
2010 					    PCICFG_IOGRAN));
2011 #else
2012 					cardbus_err(dip, 8,
2013 					    "Post-align [0x%llx] to PCI bridge "
2014 					    "I/O gran "
2015 					    "[0x%llx] -> [0x%lx]\n",
2016 					    PCICFG_ROUND_UP(io_request->ra_len +
2017 					    cardbus_min_spare_io,
2018 					    PCICFG_IOGRAN) -
2019 					    io_request->ra_len,
2020 					    io_request->ra_len,
2021 					    PCICFG_ROUND_UP(io_request->ra_len +
2022 					    cardbus_min_spare_io,
2023 					    PCICFG_IOGRAN));
2024 #endif
2025 				}
2026 #endif
2027 				mem_request->ra_len = PCICFG_ROUND_UP(
2028 				    mem_request->ra_len + cardbus_min_spare_mem,
2029 				    PCICFG_MEMGRAN);
2030 				io_request->ra_len = PCICFG_ROUND_UP(
2031 				    io_request->ra_len + cardbus_min_spare_io,
2032 				    PCICFG_IOGRAN);
2033 			}
2034 			return (DDI_WALK_PRUNECHILD);
2035 
2036 		case PCI_BRIDGE_CARDBUS:
2037 			/*
2038 			 * Cardbus has I/O registers.
2039 			 */
2040 			break;
2041 
2042 		case PCI_BRIDGE_ISA:
2043 			/*
2044 			 * All the registers requirements for ISA
2045 			 * are stored in the reg structure of the bridge.
2046 			 * Children of ISA are not of type PCI
2047 			 * so must not come through here because
2048 			 * cardbus_config_setup() will fail.
2049 			 */
2050 			ret = DDI_WALK_PRUNECHILD;
2051 			break;
2052 
2053 		default:
2054 			/*
2055 			 * Treat other bridges as leaf nodes.
2056 			 */
2057 			break;
2058 		}
2059 	}
2060 
2061 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2062 	    DDI_PROP_DONTPASS, "reg", (caddr_t)&pci_rp,
2063 	    &length) != DDI_PROP_SUCCESS) {
2064 		/*
2065 		 * If one node in (the subtree of nodes)
2066 		 * does'nt have a "reg" property fail the
2067 		 * allocation.
2068 		 */
2069 		entry->memory_len = 0;
2070 		entry->io_len = 0;
2071 		entry->error = PCICFG_FAILURE;
2072 		(void) cardbus_config_teardown(&handle);
2073 		return (DDI_WALK_TERMINATE);
2074 	}
2075 
2076 	/*
2077 	 * For each "reg" property with a length, add that to the
2078 	 * total memory (or I/O) to allocate.
2079 	 */
2080 	rcount = length / sizeof (pci_regspec_t);
2081 
2082 	for (i = 0; i < rcount; i++) {
2083 
2084 		switch (PCI_REG_ADDR_G(pci_rp[i].pci_phys_hi)) {
2085 
2086 		case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2087 			mem_request->ra_len =
2088 			    pci_rp[i].pci_size_low +
2089 			    PCICFG_ROUND_UP(mem_request->ra_len,
2090 			    pci_rp[i].pci_size_low);
2091 
2092 			cardbus_err(dip, 8,
2093 			    "ADDING 32 --->0x%x for BAR@0x%x\n",
2094 			    pci_rp[i].pci_size_low,
2095 			    PCI_REG_REG_G(pci_rp[i].pci_phys_hi));
2096 			/*
2097 			 * the granualarity needs to be the larger of
2098 			 * the maximum amount of memory that we're going to
2099 			 * ask for, and the PCI-PCI bridge granularity (1M)
2100 			 */
2101 			if (pci_rp[i].pci_size_low > entry->memory_gran)
2102 				entry->memory_gran = pci_rp[i].pci_size_low;
2103 			break;
2104 
2105 		case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2106 			mem_request->ra_len =
2107 			    pci_rp[i].pci_size_low +
2108 			    PCICFG_ROUND_UP(mem_request->ra_len,
2109 			    pci_rp[i].pci_size_low);
2110 			cardbus_err(dip, 8,
2111 			    "ADDING 64 --->0x%x for BAR@0x%x\n",
2112 			    pci_rp[i].pci_size_low,
2113 			    PCI_REG_REG_G(pci_rp[i].pci_phys_hi));
2114 
2115 			if (pci_rp[i].pci_size_low > entry->memory_gran)
2116 				entry->memory_gran = pci_rp[i].pci_size_low;
2117 			break;
2118 
2119 		case PCI_REG_ADDR_G(PCI_ADDR_IO):
2120 			io_request->ra_len =
2121 			    pci_rp[i].pci_size_low +
2122 			    PCICFG_ROUND_UP(io_request->ra_len,
2123 			    pci_rp[i].pci_size_low);
2124 			cardbus_err(dip, 8,
2125 			    "ADDING I/O --->0x%x for BAR@0x%x\n",
2126 			    pci_rp[i].pci_size_low,
2127 			    PCI_REG_REG_G(pci_rp[i].pci_phys_hi));
2128 
2129 			if (pci_rp[i].pci_size_low > entry->io_gran)
2130 				entry->io_gran = pci_rp[i].pci_size_low;
2131 			break;
2132 
2133 		default:
2134 			/* Config space register - not included */
2135 			break;
2136 		}
2137 	}
2138 
2139 	/*
2140 	 * free the memory allocated by ddi_getlongprop
2141 	 */
2142 	kmem_free(pci_rp, length);
2143 
2144 	/*
2145 	 * continue the walk to the next sibling to sum memory
2146 	 */
2147 
2148 	(void) cardbus_config_teardown(&handle);
2149 
2150 #ifdef  _LP64
2151 	cardbus_err(dip, 8,
2152 	    "Memory 0x%lx bytes, I/O 0x%lx bytes, "
2153 	    "Memgran 0x%x, IOgran 0x%x\n",
2154 	    mem_request->ra_len, io_request->ra_len,
2155 	    entry->memory_gran, entry->io_gran);
2156 #else
2157 	cardbus_err(dip, 8,
2158 	    "Memory 0x%llx bytes, I/O 0x%llx bytes, "
2159 	    "Memgran 0x%x, IOgran 0x%x\n",
2160 	    mem_request->ra_len, io_request->ra_len,
2161 	    entry->memory_gran, entry->io_gran);
2162 #endif
2163 
2164 	return (ret);
2165 }
2166 
2167 /*
2168  * Free resources allocated to a bridge.
2169  * Note that this routine does not call ndi_ra_free() to actually
2170  * free memory/IO/Bus. This is done as a single chunk for the entire
2171  * device tree in cardbus_free_chunk().
2172  */
2173 static int
cardbus_free_bridge_resources(dev_info_t * dip)2174 cardbus_free_bridge_resources(dev_info_t *dip)
2175 {
2176 	cardbus_range_t	*ranges;
2177 	uint_t		*bus;
2178 	int		k;
2179 	int		length;
2180 	int		i;
2181 
2182 	cardbus_err(dip, 6, "cardbus_free_bridge_resources\n");
2183 
2184 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2185 	    DDI_PROP_DONTPASS, "ranges", (caddr_t)&ranges,
2186 	    &length) == DDI_PROP_SUCCESS) {
2187 		for (i = 0; i < length / sizeof (cardbus_range_t); i++) {
2188 			if (ranges[i].size_lo != 0 || ranges[i].size_hi != 0) {
2189 				switch (ranges[i].parent_hi & PCI_REG_ADDR_M) {
2190 				case PCI_ADDR_IO:
2191 					cardbus_err(dip, 6,
2192 					    "Need to Free I/O    "
2193 					    "base/length = [0x%x]/[0x%x]\n",
2194 					    ranges[i].child_lo,
2195 					    ranges[i].size_lo);
2196 					break;
2197 
2198 				case PCI_ADDR_MEM32:
2199 				case PCI_ADDR_MEM64:
2200 					cardbus_err(dip, 6,
2201 					    "Need to Free Memory base/length = "
2202 					    "[0x%x.%x]/[0x%x]\n",
2203 					    ranges[i].child_mid,
2204 					    ranges[i].child_lo,
2205 					    ranges[i].size_lo);
2206 					break;
2207 
2208 				default:
2209 					cardbus_err(dip, 6,
2210 					    "Unknown memory space\n");
2211 					break;
2212 				}
2213 			}
2214 		}
2215 
2216 		kmem_free(ranges, length);
2217 		(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "ranges");
2218 	} else {
2219 		cardbus_err(dip, 8,
2220 		    "cardbus_free_bridge_resources: Failed"
2221 		    "to read ranges property\n");
2222 	}
2223 
2224 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2225 	    DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
2226 	    &k) != DDI_PROP_SUCCESS) {
2227 		cardbus_err(dip, 6, "Failed to read bus-range property\n");
2228 		return (PCICFG_FAILURE);
2229 	}
2230 
2231 	cardbus_err(dip, 6,
2232 	    "Need to free bus [%d] range [%d]\n",
2233 	    bus[0], bus[1] - bus[0] + 1);
2234 	kmem_free(bus, k);
2235 	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "available");
2236 	(void) ndi_prop_remove(DDI_DEV_T_NONE, dip, "bus-range");
2237 
2238 	return (PCICFG_SUCCESS);
2239 }
2240 
2241 static int
cardbus_free_device_resources(dev_info_t * dip)2242 cardbus_free_device_resources(dev_info_t *dip)
2243 {
2244 	pci_regspec_t *assigned;
2245 
2246 	int length;
2247 	int acount;
2248 	int i;
2249 
2250 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2251 	    DDI_PROP_DONTPASS, "assigned-addresses",
2252 	    (caddr_t)&assigned,
2253 	    &length) != DDI_PROP_SUCCESS) {
2254 		cardbus_err(dip, 1,
2255 		    "Failed to read assigned-addresses property\n");
2256 		return (PCICFG_FAILURE);
2257 	}
2258 
2259 	/*
2260 	 * For each "assigned-addresses" property entry with a length,
2261 	 * call the memory allocation routines to return the
2262 	 * resource.
2263 	 */
2264 	acount = length / sizeof (pci_regspec_t);
2265 	for (i = 0; i < acount; i++) {
2266 
2267 		/*
2268 		 * Free the resource if the size of it is not zero.
2269 		 */
2270 		if ((assigned[i].pci_size_low != 0)||
2271 		    (assigned[i].pci_size_hi != 0)) {
2272 			switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2273 			case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2274 				cardbus_err(dip, 6,
2275 				    "Need to return 0x%x of 32 bit MEM space"
2276 				    " @ 0x%x from register 0x%x\n",
2277 				    assigned[i].pci_size_low,
2278 				    assigned[i].pci_phys_low,
2279 				    PCI_REG_REG_G(assigned[i].pci_phys_hi));
2280 
2281 				break;
2282 
2283 			case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2284 				cardbus_err(dip, 6,
2285 				    "Need to return 0x%x of 64 bit MEM space"
2286 				    " @ 0x%x.%x from register 0x%x\n",
2287 				    assigned[i].pci_size_low,
2288 				    assigned[i].pci_phys_mid,
2289 				    assigned[i].pci_phys_low,
2290 				    PCI_REG_REG_G(assigned[i].pci_phys_hi));
2291 
2292 				break;
2293 
2294 			case PCI_REG_ADDR_G(PCI_ADDR_IO):
2295 				cardbus_err(dip, 6,
2296 				    "Need to return 0x%x of IO space @ 0x%x"
2297 				    " from register 0x%x\n",
2298 				    assigned[i].pci_size_low,
2299 				    assigned[i].pci_phys_low,
2300 				    PCI_REG_REG_G(assigned[i].pci_phys_hi));
2301 				break;
2302 
2303 			default:
2304 				cardbus_err(dip, 1, "Unknown register type\n");
2305 				kmem_free(assigned, length);
2306 				return (PCICFG_FAILURE);
2307 			} /* switch */
2308 		}
2309 	}
2310 	kmem_free(assigned, length);
2311 	return (PCICFG_SUCCESS);
2312 }
2313 
2314 static int
cardbus_free_resources(dev_info_t * dip)2315 cardbus_free_resources(dev_info_t *dip)
2316 {
2317 	uint32_t classcode;
2318 
2319 	classcode = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2320 	    "class-code", -1);
2321 	/*
2322 	 * A different algorithim is used for bridges and leaf devices.
2323 	 */
2324 	if (classcode != -1) {
2325 		classcode = ((uint_t)classcode & 0xffff00) >> 8;
2326 		if (classcode == 0x604 || classcode == 0x607) {
2327 			if (cardbus_free_bridge_resources(dip)
2328 			    != PCICFG_SUCCESS) {
2329 				cardbus_err(dip, 1,
2330 				    "Failed freeing up bridge resources\n");
2331 				return (PCICFG_FAILURE);
2332 			}
2333 			return (PCICFG_SUCCESS);
2334 		}
2335 	}
2336 
2337 	if (cardbus_free_device_resources(dip) != PCICFG_SUCCESS) {
2338 		cardbus_err(dip, 1, "Failed freeing up device resources\n");
2339 		return (PCICFG_FAILURE);
2340 	}
2341 	return (PCICFG_SUCCESS);
2342 }
2343 
2344 static int
cardbus_probe_bridge(cbus_t * cbp,dev_info_t * attpt,uint_t bus,uint_t device,uint_t func)2345 cardbus_probe_bridge(cbus_t *cbp, dev_info_t *attpt, uint_t bus,
2346     uint_t device, uint_t func)
2347 {
2348 	/* Declairations */
2349 	cardbus_bus_range_t	*bus_range;
2350 	int			i, j;
2351 	uint8_t			header_type;
2352 	ddi_acc_handle_t	config_handle;
2353 	ndi_ra_request_t	req;
2354 	uint_t			new_bus;
2355 	uint64_t		blen;
2356 	uint64_t		next_bus;
2357 
2358 	cardbus_err(cbp->cb_dip, 6,
2359 	    "cardbus_probe_bridge bus %d device %d func %d\n",
2360 	    bus, device, func);
2361 
2362 	ndi_devi_enter(cbp->cb_dip);
2363 	if (pci_config_setup(cbp->cb_dip, &config_handle) != DDI_SUCCESS) {
2364 
2365 		cardbus_err(cbp->cb_dip, 1,
2366 		    "cardbus_probe_bridge(): Failed to setup config space\n");
2367 
2368 		ndi_devi_exit(cbp->cb_dip);
2369 		return (PCICFG_FAILURE);
2370 	}
2371 
2372 	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
2373 
2374 	/*
2375 	 * As soon as we have access to config space, check device
2376 	 * is a bridge.
2377 	 */
2378 	if ((header_type & PCI_HEADER_TYPE_M) != PCI_HEADER_CARDBUS)
2379 		goto failed;
2380 
2381 	cardbus_err(cbp->cb_dip, 8,
2382 	    "---Vendor ID = [0x%04x]\n",
2383 	    pci_config_get16(config_handle, PCI_CONF_VENID));
2384 	cardbus_err(cbp->cb_dip, 8,
2385 	    "---Device ID = [0x%04x]\n",
2386 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
2387 
2388 	/* say what type of header */
2389 	cardbus_err(cbp->cb_dip, 8,
2390 	    "--%s bridge found root bus [0x%x] device [0x%x] func [0x%x]\n",
2391 	    ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) ?
2392 	    "PCI-PCI" : "Cardbus",
2393 	    bus, device, func);
2394 
2395 	if (ddi_getlongprop(DDI_DEV_T_ANY, cbp->cb_dip, 0, "bus-range",
2396 	    (caddr_t)&bus_range, &i) != DDI_PROP_SUCCESS)
2397 		cardbus_err(cbp->cb_dip, 1,
2398 		    "No bus-range property seems to have been set up\n");
2399 	else {
2400 		cardbus_err(cbp->cb_dip, 8,
2401 		    "allowable bus range is %u->%u\n",
2402 		    bus_range->lo, bus_range->hi);
2403 		kmem_free((caddr_t)bus_range, i);
2404 	}
2405 
2406 	/*
2407 	 * Get next bus in sequence and program device.
2408 	 */
2409 	bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
2410 	req.ra_len = 1;
2411 
2412 	if (ndi_ra_alloc(cbp->cb_dip, &req,
2413 	    &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
2414 	    NDI_RA_PASS) != NDI_SUCCESS) {
2415 		cmn_err(CE_WARN, "Failed to get a bus number\n");
2416 		goto failed;
2417 	}
2418 
2419 	new_bus = next_bus;
2420 	cardbus_err(cbp->cb_dip, 8,
2421 	    "NEW bus found [%u]->[%u]\n", bus, new_bus);
2422 
2423 	(void) cardbus_set_bus_numbers(config_handle, bus, new_bus);
2424 
2425 	/* Enable it all */
2426 	enable_cardbus_bridge(cbp->cb_dip, config_handle);
2427 
2428 	/*
2429 	 * Probe all children devices
2430 	 */
2431 	for (i = 0; i < pcicfg_max_device; i++)
2432 		for (j = 0; j < pcicfg_max_function; j++)
2433 			switch (cardbus_probe_children(cbp, attpt, new_bus, i,
2434 			    j, &header_type)) {
2435 
2436 			case PCICFG_FAILURE:
2437 				cardbus_err(cbp->cb_dip, 1,
2438 				    "Failed to configure bus "
2439 				    "[0x%x] device [0x%x] func [0x%x]\n",
2440 				    new_bus, i, j);
2441 				disable_cardbus_bridge(cbp->cb_dip,
2442 				    config_handle);
2443 				goto failed;
2444 
2445 			case PCICFG_NODEVICE:
2446 				/*
2447 				 * if there's no function 0
2448 				 * there's no point in probing other
2449 				 * functions
2450 				 */
2451 				if (j != 0)
2452 					break;
2453 				/* FALLTHROUGH */
2454 			case PCICFG_NOMULTI:
2455 				j = pcicfg_max_function;
2456 				break;
2457 
2458 			default:
2459 				break;
2460 			}
2461 
2462 	(void) pci_config_teardown(&config_handle);
2463 	(void) i_ndi_config_node(attpt, DS_LINKED, 0);
2464 	ndi_devi_exit(cbp->cb_dip);
2465 
2466 	return (PCICFG_SUCCESS);
2467 
2468 failed:
2469 	(void) pci_config_teardown(&config_handle);
2470 	ndi_devi_exit(cbp->cb_dip);
2471 
2472 	return (PCICFG_FAILURE);
2473 }
2474 
2475 static struct isa_node isa_nodes[] = {
2476 	{"dummy", {NULL, NULL, NULL, NULL, NULL}, "serial", "", 0x4e, 0x2}
2477 };
2478 
2479 static int
cardbus_probe_children(cbus_t * cbp,dev_info_t * parent,uint_t bus,uint_t device,uint_t func,uint8_t * header_type)2480 cardbus_probe_children(cbus_t *cbp, dev_info_t *parent, uint_t bus,
2481     uint_t device, uint_t func, uint8_t *header_type)
2482 {
2483 	dev_info_t		*new_child;
2484 	ddi_acc_handle_t	config_handle;
2485 	int			i, j;
2486 	ndi_ra_request_t	req;
2487 	uint64_t		next_bus;
2488 	uint64_t		blen;
2489 	uint32_t		request;
2490 	uint8_t			base_class;
2491 	uint_t			new_bus;
2492 	int			ret;
2493 
2494 	cardbus_err(parent, 6,
2495 	    "cardbus_probe_children bus %d device %d func %d\n",
2496 	    bus, device, func);
2497 
2498 	/*
2499 	 * This node will be put immediately below
2500 	 * "parent". Allocate a blank device node.  It will either
2501 	 * be filled in or freed up based on further probing.
2502 	 */
2503 
2504 	ndi_devi_enter(parent);
2505 
2506 	if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
2507 	    (pnode_t)DEVI_SID_NODEID,
2508 	    &new_child) != NDI_SUCCESS) {
2509 		cardbus_err(parent, 1,
2510 		    "cardbus_probe_children(): Failed to alloc child node\n");
2511 		ndi_devi_exit(parent);
2512 		return (PCICFG_FAILURE);
2513 	}
2514 
2515 	if (cardbus_add_config_reg(new_child, bus,
2516 	    device, func) != DDI_SUCCESS) {
2517 		cardbus_err(parent, 1,
2518 		    "cardbus_probe_children(): Failed to add candidate REG\n");
2519 		goto failedconfig;
2520 	}
2521 
2522 	if ((ret = cardbus_config_setup(new_child, &config_handle))
2523 	    != PCICFG_SUCCESS) {
2524 
2525 		if (ret == PCICFG_NODEVICE) {
2526 			(void) ndi_devi_free(new_child);
2527 			return (ret);
2528 		}
2529 		cardbus_err(parent, 1,
2530 		    "cardbus_probe_children(): Failed to setup config space\n");
2531 
2532 		goto failedconfig;
2533 	}
2534 
2535 	base_class = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
2536 
2537 	if (func == 0) {
2538 		/*
2539 		 * Preserve the header type from function 0.
2540 		 * Additional functions may not preserve the PCI_HEADER_MULTI
2541 		 * bit.
2542 		 */
2543 		*header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
2544 	} else if (!(*header_type & PCI_HEADER_MULTI) ||
2545 	    ((*header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) ||
2546 	    (base_class == PCI_CLASS_BRIDGE)) {
2547 
2548 		(void) cardbus_config_teardown(&config_handle);
2549 		(void) ndi_devi_free(new_child);
2550 		return (PCICFG_NOMULTI);
2551 	}
2552 
2553 	/*
2554 	 * As soon as we have access to config space,
2555 	 * turn off device. It will get turned on
2556 	 * later (after memory is assigned).
2557 	 * not if it's a cardbus device. It may be OK to leave
2558 	 * it on - try LATER
2559 	 */
2560 	disable_cardbus_device(config_handle);
2561 
2562 	/*
2563 	 * Set 1275 properties common to all devices
2564 	 */
2565 	if (cardbus_set_standard_props(parent, new_child,
2566 	    config_handle) != PCICFG_SUCCESS) {
2567 		cardbus_err(parent, 1, "Failed to set standard properties\n");
2568 		goto failedchild;
2569 	}
2570 
2571 	/*
2572 	 * Child node properties  NOTE: Both for PCI-PCI bridge and child node
2573 	 */
2574 	if (cardbus_set_childnode_props(new_child,
2575 	    config_handle) != PCICFG_SUCCESS) {
2576 		goto failedchild;
2577 	}
2578 
2579 	cardbus_err(parent, 8,
2580 	    "---Vendor ID = [0x%04x]\n",
2581 	    pci_config_get16(config_handle, PCI_CONF_VENID));
2582 	cardbus_err(parent, 8,
2583 	    "---Device ID = [0x%04x]\n",
2584 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
2585 
2586 	if (base_class == PCI_CLASS_BRIDGE) {
2587 		uint8_t	sub_class;
2588 
2589 		sub_class = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
2590 
2591 		switch (sub_class) {
2592 		case PCI_BRIDGE_PCI:
2593 			if ((*header_type & PCI_HEADER_TYPE_M)
2594 			    == PCI_HEADER_PPB) {
2595 				cardbus_bus_range_t *bus_range;
2596 				int k;
2597 
2598 				/* say what type of header */
2599 				cardbus_err(parent, 8,
2600 				    "-- Found PCI-PCI bridge @ "
2601 				    " bus [0x%x] device [0x%x] func [0x%x]\n",
2602 				    bus, device, func);
2603 
2604 				if (ddi_getlongprop(DDI_DEV_T_ANY,
2605 				    new_child, 0, "bus-range",
2606 				    (caddr_t)&bus_range,
2607 				    &k) != DDI_PROP_SUCCESS)
2608 					cardbus_err(new_child, 1,
2609 					    "No bus-range property"
2610 					    " seems to have been set up\n");
2611 				else {
2612 					cardbus_err(new_child, 8,
2613 					    "allowable bus range is %u->%u\n",
2614 					    bus_range->lo, bus_range->hi);
2615 					kmem_free((caddr_t)bus_range, k);
2616 				}
2617 
2618 				/*
2619 				 * Get next bus in sequence and program device.
2620 				 */
2621 				bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
2622 				req.ra_len = 1;
2623 
2624 				if (ndi_ra_alloc(new_child, &req,
2625 				    &next_bus, &blen,
2626 				    NDI_RA_TYPE_PCI_BUSNUM,
2627 				    NDI_RA_PASS) != NDI_SUCCESS) {
2628 					cmn_err(CE_WARN,
2629 					    "Failed to get a bus number\n");
2630 					goto failedchild;
2631 				}
2632 
2633 				new_bus = next_bus;
2634 
2635 				cardbus_err(new_child, 8,
2636 				    "NEW bus found [%u]->[%u]\n", bus, new_bus);
2637 
2638 				/* Enable it all */
2639 				enable_pci_pci_bridge(new_child, config_handle);
2640 				(void) cardbus_set_bus_numbers(config_handle,
2641 				    bus, new_bus);
2642 
2643 #if defined(CARDBUS_DEBUG)
2644 				if (cardbus_debug >= 9) {
2645 					cardbus_dump_config(config_handle);
2646 				}
2647 #endif
2648 
2649 				/*
2650 				 * Set bus properties
2651 				 */
2652 				if (cardbus_set_busnode_props(new_child)
2653 				    != PCICFG_SUCCESS) {
2654 					cardbus_err(new_child, 1,
2655 					    "Failed to set busnode props\n");
2656 					disable_pci_pci_bridge(new_child,
2657 					    config_handle);
2658 					goto failedchild;
2659 				}
2660 
2661 				/*
2662 				 * Probe all children devices
2663 				 */
2664 				for (i = 0; i < pcicfg_max_device; i++)
2665 					for (j = 0; j < pcicfg_max_function;
2666 					    j++)
2667 						switch (cardbus_probe_children(
2668 						    cbp,
2669 						    new_child,
2670 						    new_bus, i,
2671 						    j, header_type)) {
2672 						case PCICFG_FAILURE:
2673 							cardbus_err(parent, 1,
2674 							    "Failed to "
2675 							    "configure "
2676 							    "bus [0x%x] "
2677 							    "device [0x%x] "
2678 							    "func [0x%x]\n",
2679 							    new_bus, i, j);
2680 							disable_pci_pci_bridge(
2681 							    new_child,
2682 							    config_handle);
2683 							goto failedchild;
2684 
2685 						case PCICFG_NODEVICE:
2686 							/*
2687 							 * if there's no
2688 							 * function 0
2689 							 * there's no point in
2690 							 * probing other
2691 							 * functions
2692 							 */
2693 							if (j != 0)
2694 								break;
2695 							/* FALLTHROUGH */
2696 						case PCICFG_NOMULTI:
2697 							j = pcicfg_max_function;
2698 							break;
2699 
2700 						default:
2701 							break;
2702 						}
2703 			}
2704 			break;
2705 
2706 		case PCI_BRIDGE_CARDBUS:
2707 			cardbus_err(parent, 8,
2708 			    "--Found Cardbus bridge @ "
2709 			    "bus [0x%x] device [0x%x] func [0x%x]\n",
2710 			    bus, device, func);
2711 			pci_config_put32(config_handle,
2712 			    PCI_CONF_BASE0, 0xffffffff);
2713 
2714 			request = pci_config_get32(config_handle,
2715 			    PCI_CONF_BASE0);
2716 
2717 			/*
2718 			 * If its a zero length, don't do
2719 			 * any programming.
2720 			 */
2721 			if (request != 0) {
2722 				if (request == (uint32_t)0xffffffff) {
2723 					cmn_err(CE_WARN,
2724 					    "cardbus_probe_children: "
2725 					    "can't access device");
2726 					goto failedchild;
2727 				}
2728 				/*
2729 				 * Add to the "reg" property
2730 				 */
2731 				if (cardbus_update_reg_prop(new_child,
2732 				    request,
2733 				    PCI_CONF_BASE0) != PCICFG_SUCCESS) {
2734 					goto failedchild;
2735 				}
2736 				cardbus_err(parent, 8,
2737 				    "BASE register [0x%x] asks for "
2738 				    "[0x%x]=[0x%x](32)\n",
2739 				    PCI_CONF_BASE0, request,
2740 				    (~(PCI_BASE_M_ADDR_M & request))+1);
2741 			}
2742 			break;
2743 
2744 		case PCI_BRIDGE_ISA:
2745 			cardbus_err(parent, 8,
2746 			    "--Found ISA bridge @ "
2747 			    "bus [0x%x] device [0x%x] func [0x%x]\n",
2748 			    bus, device, func);
2749 			enable_pci_isa_bridge(new_child, config_handle);
2750 
2751 #if defined(CARDBUS_DEBUG)
2752 			if (cardbus_debug >= 4) {
2753 				cardbus_dump_common_config(config_handle);
2754 				cardbus_err(NULL, 1,
2755 				    " DDMA SlvCh0 = [0x%04x]        "
2756 				    "DDMA SlvCh1 = [0x%04x]\n",
2757 				    pci_config_get16(config_handle, 0x40),
2758 				    pci_config_get16(config_handle, 0x42));
2759 				cardbus_err(NULL, 1,
2760 				    " DDMA SlvCh2 = [0x%04x]        "
2761 				    "DDMA SlvCh3 = [0x%04x]\n",
2762 				    pci_config_get16(config_handle, 0x44),
2763 				    pci_config_get16(config_handle, 0x46));
2764 				cardbus_err(NULL, 1,
2765 				    " DDMA SlvCh5 = [0x%04x]        "
2766 				    "DDMA SlvCh6 = [0x%04x]\n",
2767 				    pci_config_get16(config_handle, 0x4a),
2768 				    pci_config_get16(config_handle, 0x4c));
2769 				cardbus_err(NULL, 1,
2770 				    " DDMA SlvCh7 = [0x%04x]        "
2771 				    "Misc Cntrl  = [0x%02x]\n",
2772 				    pci_config_get16(config_handle, 0x4e),
2773 				    pci_config_get8(config_handle, 0x57));
2774 				cardbus_err(NULL, 1,
2775 				    " DMA Cntl    = [0x%02x]          "
2776 				    "DMA TyF Tim = [0x%02x]\n",
2777 				    pci_config_get8(config_handle, 0x48),
2778 				    pci_config_get8(config_handle, 0x49));
2779 				cardbus_err(NULL, 1,
2780 				    " TimCntrl    = [0x%02x]          "
2781 				    "MTOP        = [0x%02x]\n",
2782 				    pci_config_get8(config_handle, 0x50),
2783 				    pci_config_get8(config_handle, 0x51));
2784 				cardbus_err(NULL, 1,
2785 				    " MDMA Access = [0x%02x]          "
2786 				    "ROMCS       = [0x%02x]\n",
2787 				    pci_config_get8(config_handle, 0x52),
2788 				    pci_config_get8(config_handle, 0x53));
2789 				cardbus_err(NULL, 1,
2790 				    " Dscrd Tmr   = [0x%02x]          "
2791 				    "Retry Tmr   = [0x%02x]\n",
2792 				    pci_config_get8(config_handle, 0x55),
2793 				    pci_config_get8(config_handle, 0x54));
2794 				cardbus_err(NULL, 1,
2795 				    " I/O Spc 0   = [0x%08x]    "
2796 				    "I/O Spc 1   = [0x%08x]\n",
2797 				    pci_config_get32(config_handle, 0x58),
2798 				    pci_config_get32(config_handle, 0x5c));
2799 				cardbus_err(NULL, 1,
2800 				    " I/O Spc 2   = [0x%08x]    "
2801 				    "I/O Spc 3   = [0x%08x]\n",
2802 				    pci_config_get32(config_handle, 0x60),
2803 				    pci_config_get32(config_handle, 0x64));
2804 				cardbus_err(NULL, 1,
2805 				    " I/O Spc 4   = [0x%08x]    "
2806 				    "I/O Spc 5   = [0x%08x]\n",
2807 				    pci_config_get32(config_handle, 0x68),
2808 				    pci_config_get32(config_handle, 0x6c));
2809 				cardbus_err(NULL, 1,
2810 				    " Mem Spc 0   = [0x%08x]    "
2811 				    "Mem Spc 1   = [0x%08x]\n",
2812 				    pci_config_get32(config_handle, 0x70),
2813 				    pci_config_get32(config_handle, 0x74));
2814 				cardbus_err(NULL, 1,
2815 				    " Mem Spc 2   = [0x%08x]    "
2816 				    "Mem Spc 3   = [0x%08x]\n",
2817 				    pci_config_get32(config_handle, 0x78),
2818 				    pci_config_get32(config_handle, 0x7c));
2819 			}
2820 #endif
2821 			/*
2822 			 * Set bus properties
2823 			 */
2824 			if (cardbus_set_busnode_isaprops(new_child)
2825 			    != PCICFG_SUCCESS) {
2826 				cardbus_err(new_child, 1,
2827 				    "Failed to set busnode props\n");
2828 				disable_cardbus_device(config_handle);
2829 				goto failedchild;
2830 			}
2831 
2832 			/*
2833 			 * Add to the "reg" property.
2834 			 * Simply grab 1K of I/O space.
2835 			 */
2836 			if (cardbus_update_reg_prop(new_child,
2837 			    0xfffffc00 | PCI_BASE_SPACE_IO,
2838 			    PCI_CONF_BASE0) != PCICFG_SUCCESS) {
2839 				goto failedchild;
2840 			}
2841 
2842 			/*
2843 			 * Probe all potential children devices.
2844 			 */
2845 			for (i = 0;
2846 			    i < sizeof (isa_nodes) / sizeof (isa_nodes[0]);
2847 			    i++)
2848 				switch (cardbus_add_isa_node(cbp, new_child,
2849 				    &isa_nodes[i])) {
2850 				case PCICFG_FAILURE:
2851 					cardbus_err(parent, 1,
2852 					    "Failed to configure isa bus\n");
2853 					disable_cardbus_device(config_handle);
2854 					goto failedchild;
2855 
2856 				case PCICFG_NODEVICE:
2857 					continue;
2858 				}
2859 
2860 			break;
2861 
2862 		case PCI_BRIDGE_OTHER:
2863 		default:
2864 			cardbus_err(parent, 8,
2865 			    "--Found unknown bridge, subclass 0x%x @ "
2866 			    "bus [0x%x] device [0x%x] func [0x%x]\n",
2867 			    sub_class, bus, device, func);
2868 			goto leaf_node;
2869 		}
2870 	} else {
2871 		cardbus_err(parent, 8,
2872 		    "--Leaf device found "
2873 		    "bus [0x%x] device [0x%x] func [0x%x]\n",
2874 		    bus, device, func);
2875 		/*
2876 		 * Ethernet devices.
2877 		 */
2878 		if (strcmp(ddi_binding_name(new_child), "ethernet") == 0) {
2879 			extern int localetheraddr(struct ether_addr *,
2880 			    struct ether_addr *);
2881 			uchar_t mac[6];
2882 
2883 			cardbus_force_stringprop(new_child,
2884 			    "device_type", "network");
2885 
2886 			if (localetheraddr(NULL, (struct ether_addr *)mac)) {
2887 				(void) ddi_prop_create(DDI_DEV_T_NONE,
2888 				    new_child,
2889 				    DDI_PROP_CANSLEEP, "local-mac-address",
2890 				    (caddr_t)mac, 6);
2891 			}
2892 		}
2893 leaf_node:
2894 		if (cbp->cb_dsp) {
2895 			struct cb_deviceset_props *cdsp = cbp->cb_dsp;
2896 			uint16_t venid = pci_config_get16(config_handle,
2897 			    PCI_CONF_VENID);
2898 			uint16_t devid = pci_config_get16(config_handle,
2899 			    PCI_CONF_DEVID);
2900 			ddi_prop_t *propp;
2901 
2902 			for (cdsp = cbp->cb_dsp; cdsp; cdsp = cdsp->next) {
2903 				if (cdsp->binding_name &&
2904 				    strcmp(ddi_binding_name(new_child),
2905 				    cdsp->binding_name))
2906 					continue;
2907 				if (cdsp->venid && (cdsp->venid != venid))
2908 					continue;
2909 				if (cdsp->devid && (cdsp->devid != devid))
2910 					continue;
2911 				if (cdsp->nodename) {
2912 					if (ndi_devi_set_nodename(new_child,
2913 					    cdsp->nodename,
2914 					    0) != NDI_SUCCESS)
2915 						cardbus_err(new_child, 1,
2916 						    "Failed to set nodename\n");
2917 				}
2918 				for (propp = cdsp->prop_list; propp;
2919 				    propp = propp->prop_next) {
2920 					switch (propp->prop_flags) {
2921 					case DDI_PROP_TYPE_INT:
2922 						cardbus_force_intprop(
2923 						    new_child,
2924 						    propp->prop_name,
2925 						    (int *)propp->prop_val,
2926 						    propp->prop_len);
2927 						break;
2928 					case DDI_PROP_TYPE_STRING:
2929 						cardbus_force_stringprop(
2930 						    new_child,
2931 						    propp->prop_name,
2932 						    (char *)propp->prop_val);
2933 						break;
2934 					case DDI_PROP_TYPE_ANY:
2935 						cardbus_force_boolprop(
2936 						    new_child,
2937 						    propp->prop_name);
2938 						break;
2939 					}
2940 				}
2941 			}
2942 		}
2943 
2944 #if defined(CARDBUS_DEBUG)
2945 		if (cardbus_debug >= 9) {
2946 			cardbus_dump_config(config_handle);
2947 		}
2948 #endif
2949 
2950 		i = PCI_CONF_BASE0;
2951 
2952 		while (i <= PCI_CONF_BASE5) {
2953 			pci_config_put32(config_handle, i, 0xffffffff);
2954 
2955 			request = pci_config_get32(config_handle, i);
2956 
2957 			/*
2958 			 * If its a zero length, don't do
2959 			 * any programming.
2960 			 */
2961 			if (request != 0) {
2962 				if (request == (uint32_t)0xffffffff) {
2963 					cmn_err(CE_WARN,
2964 					    "cardbus_probe_children: "
2965 					    "can't access device");
2966 					goto failedchild;
2967 				}
2968 				/*
2969 				 * Add to the "reg" property
2970 				 */
2971 				if (cardbus_update_reg_prop(new_child,
2972 				    request, i) != PCICFG_SUCCESS) {
2973 					goto failedchild;
2974 				}
2975 			} else {
2976 				cardbus_err(parent, 8, "All memory found\n");
2977 				break;
2978 			}
2979 
2980 			/*
2981 			 * Increment by eight if it is 64 bit address space
2982 			 * only if memory space
2983 			 */
2984 			if (((PCI_BASE_TYPE_M & request)
2985 			    == PCI_BASE_TYPE_ALL) &&
2986 			    ((PCI_BASE_SPACE_M & request)
2987 			    == PCI_BASE_SPACE_MEM)) {
2988 				cardbus_err(parent, 8,
2989 				    "BASE register [0x%x] asks for "
2990 				    "[0x%x]=[0x%x] (64)\n",
2991 				    i, request,
2992 				    (~(PCI_BASE_M_ADDR_M & request))+1);
2993 				i += 8;
2994 			} else {
2995 				cardbus_err(parent, 8,
2996 				    "BASE register [0x%x] asks for "
2997 				    "[0x%x]=[0x%x](32)\n",
2998 				    i, request,
2999 				    (~(PCI_BASE_M_ADDR_M & request))+1);
3000 				i += 4;
3001 			}
3002 		}
3003 
3004 		/*
3005 		 * Get the ROM size and create register for it
3006 		 */
3007 		pci_config_put32(config_handle, PCI_CONF_ROM, 0xffffffff);
3008 
3009 		request = pci_config_get32(config_handle, PCI_CONF_ROM);
3010 		/*
3011 		 * If its a zero length, don't do
3012 		 * any programming.
3013 		 */
3014 
3015 		if (request != 0) {
3016 			cardbus_err(parent, 9,
3017 			    "BASE register [0x%x] asks for "
3018 			    "[0x%x]=[0x%x] (ROM)\n",
3019 			    PCI_CONF_ROM, request,
3020 			    (~(PCI_BASE_ROM_ADDR_M & request))+1);
3021 			/*
3022 			 * Add to the "reg" property
3023 			 */
3024 			if (cardbus_update_reg_prop(new_child,
3025 			    request,
3026 			    PCI_CONF_ROM) != PCICFG_SUCCESS) {
3027 				goto failedchild;
3028 			}
3029 		}
3030 	}
3031 
3032 	(void) cardbus_config_teardown(&config_handle);
3033 
3034 	/*
3035 	 * Attach the child to its parent
3036 	 */
3037 	(void) i_ndi_config_node(new_child, DS_LINKED, 0);
3038 	ndi_devi_exit(parent);
3039 
3040 	return (PCICFG_SUCCESS);
3041 failedchild:
3042 	/*
3043 	 * check if it should be taken offline (if online)
3044 	 */
3045 	(void) cardbus_config_teardown(&config_handle);
3046 
3047 failedconfig:
3048 
3049 	(void) ndi_devi_free(new_child);
3050 	ndi_devi_exit(parent);
3051 
3052 	return (PCICFG_FAILURE);
3053 }
3054 
3055 static int
cardbus_add_config_reg(dev_info_t * dip,uint_t bus,uint_t device,uint_t func)3056 cardbus_add_config_reg(dev_info_t *dip,
3057     uint_t bus, uint_t device, uint_t func)
3058 {
3059 	int reg[10] = { PCI_ADDR_CONFIG, 0, 0, 0, 0};
3060 
3061 	reg[0] = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
3062 
3063 	return (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3064 	    "reg", reg, 5));
3065 }
3066 
3067 static int
cardbus_add_isa_node(cbus_t * cbp,dev_info_t * parent,struct isa_node * node)3068 cardbus_add_isa_node(cbus_t *cbp, dev_info_t *parent, struct isa_node *node)
3069 {
3070 	dev_info_t		*new_child;
3071 	int			ret;
3072 	uint32_t		reg[3];
3073 
3074 	_NOTE(ARGUNUSED(cbp))
3075 
3076 	cardbus_err(parent, 6, "cardbus_add_isa_node\n");
3077 
3078 	/*
3079 	 * This node will be put immediately below
3080 	 * "parent". Allocate a blank device node.
3081 	 */
3082 	if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
3083 	    (pnode_t)DEVI_SID_NODEID,
3084 	    &new_child) != NDI_SUCCESS) {
3085 		cardbus_err(parent, 1,
3086 		    "cardbus_add_isa_child(): Failed to alloc child node\n");
3087 		return (PCICFG_FAILURE);
3088 	}
3089 
3090 	/*
3091 	 * Set properties common to ISA devices
3092 	 */
3093 	if (cardbus_set_isa_props(parent, new_child, node->name,
3094 	    node->compatible) != PCICFG_SUCCESS) {
3095 		cardbus_err(parent, 1, "Failed to set ISA properties\n");
3096 		goto failed;
3097 	}
3098 
3099 	cardbus_err(new_child, 8, "--Leaf ISA device\n");
3100 
3101 	/*
3102 	 * Add the "reg" property.
3103 	 */
3104 	reg[0] = 0;
3105 	reg[1] = node->reg;
3106 	reg[2] = node->span;
3107 
3108 	ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
3109 	    "basereg", (int *)reg, 3);
3110 	if (ret != DDI_SUCCESS)
3111 		goto failed;
3112 
3113 	(void) i_ndi_config_node(new_child, DS_LINKED, 0);
3114 
3115 	return (PCICFG_SUCCESS);
3116 
3117 failed:
3118 	(void) ndi_devi_free(new_child);
3119 
3120 	return (PCICFG_FAILURE);
3121 }
3122 
3123 static int
cardbus_config_setup(dev_info_t * dip,ddi_acc_handle_t * handle)3124 cardbus_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
3125 {
3126 	caddr_t		cfgaddr;
3127 	ddi_device_acc_attr_t	attr;
3128 	dev_info_t	*anode;
3129 	int	status;
3130 	int	rlen;
3131 	pci_regspec_t	*reg;
3132 	int		ret;
3133 #ifdef sparc
3134 	int16_t		val;
3135 #endif
3136 
3137 	cardbus_err(dip, 10,
3138 	    "cardbus_config_setup(dip=0x%p)\n", (void *) dip);
3139 
3140 	/*
3141 	 * Get the pci register spec from the node
3142 	 */
3143 	status = ddi_getlongprop(DDI_DEV_T_NONE,
3144 	    dip, DDI_PROP_DONTPASS, "reg",
3145 	    (caddr_t)&reg, &rlen);
3146 
3147 	cardbus_err(dip, 10,
3148 	    "cardbus_config_setup, reg = 0x%p\n", (void *) reg);
3149 
3150 	switch (status) {
3151 	case DDI_PROP_SUCCESS:
3152 		break;
3153 	case DDI_PROP_NO_MEMORY:
3154 		cardbus_err(dip, 1, "reg present, but unable to get memory\n");
3155 		return (PCICFG_FAILURE);
3156 	default:
3157 		cardbus_err(dip, 1, "no reg property\n");
3158 		return (PCICFG_FAILURE);
3159 	}
3160 
3161 	anode = dip;
3162 
3163 	/*
3164 	 * Find the attachment point node
3165 	 */
3166 	while ((anode != NULL) && (strcmp(ddi_binding_name(anode),
3167 	    "hp_attachment") != 0)) {
3168 		anode = ddi_get_parent(anode);
3169 	}
3170 
3171 	if (anode == NULL) {
3172 		cardbus_err(dip, 1, "Tree not in PROBE state\n");
3173 		kmem_free((caddr_t)reg, rlen);
3174 		return (PCICFG_FAILURE);
3175 	}
3176 
3177 	if ((ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, anode,
3178 	    "reg", (int *)reg, 5)) != 0) {
3179 		cardbus_err(dip, 1,
3180 		    "Failed to update reg property, error code %d\n", ret);
3181 		kmem_free((caddr_t)reg, rlen);
3182 		return (PCICFG_FAILURE);
3183 	}
3184 
3185 	attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
3186 	attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
3187 	attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
3188 
3189 	if (ddi_regs_map_setup(anode, 0, &cfgaddr,
3190 	    0, /* PCI_CONF_HDR_SIZE */
3191 	    0,
3192 	    &attr, handle) != DDI_SUCCESS) {
3193 		cardbus_err(dip, 1,
3194 		    "Failed to setup registers for [0x%x][0x%x][0x%x]\n",
3195 		    PCI_REG_BUS_G(reg->pci_phys_hi),
3196 		    PCI_REG_DEV_G(reg->pci_phys_hi),
3197 		    PCI_REG_FUNC_G(reg->pci_phys_hi));
3198 		kmem_free((caddr_t)reg, rlen);
3199 		return (PCICFG_FAILURE);
3200 	}
3201 
3202 	cardbus_err(dip, 9,
3203 	    "PROBING =>->->->->->-> [0x%x][0x%x][0x%x] 0x%x 0x%p\n",
3204 	    PCI_REG_BUS_G(reg->pci_phys_hi),
3205 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3206 	    PCI_REG_FUNC_G(reg->pci_phys_hi),
3207 	    reg->pci_phys_hi, (void *) cfgaddr);
3208 
3209 	/*
3210 	 * must do peek16 otherwise the system crashes when probing
3211 	 * a non zero function on a non-multi-function card.
3212 	 */
3213 #ifdef sparc
3214 	if (ddi_peek16(anode, (int16_t *)cfgaddr, &val) != DDI_SUCCESS) {
3215 		cardbus_err(dip, 8,
3216 		    "cardbus_config_setup peek failed\n");
3217 		ret = PCICFG_NODEVICE;
3218 	} else if (ddi_get16(*handle, (uint16_t *)cfgaddr) == 0xffff) {
3219 		cardbus_err(dip, 8,
3220 		    "cardbus_config_setup PCICFG_NODEVICE\n");
3221 		ret = PCICFG_NODEVICE;
3222 #elif defined(__x86)
3223 	if (ddi_get16(*handle, (uint16_t *)cfgaddr) == 0xffff) {
3224 		cardbus_err(dip, 8,
3225 		    "cardbus_config_setup PCICFG_NODEVICE\n");
3226 		ret = PCICFG_NODEVICE;
3227 #endif
3228 	} else {
3229 		cardbus_err(dip, 1,
3230 		    "cardbus_config_setup found device at:[0x%x][0x%x][0x%x]\n",
3231 		    PCI_REG_BUS_G(reg->pci_phys_hi),
3232 		    PCI_REG_DEV_G(reg->pci_phys_hi),
3233 		    PCI_REG_FUNC_G(reg->pci_phys_hi));
3234 
3235 		ret = PCICFG_SUCCESS;
3236 	}
3237 
3238 	kmem_free((caddr_t)reg, rlen);
3239 	if (ret != PCICFG_SUCCESS) {
3240 		cardbus_config_teardown(handle);
3241 	}
3242 
3243 	cardbus_err(dip, 7,
3244 	    "cardbus_config_setup returning %d\n", ret);
3245 
3246 	return (ret);
3247 }
3248 
3249 static void
3250 cardbus_config_teardown(ddi_acc_handle_t *handle)
3251 {
3252 	(void) ddi_regs_map_free(handle);
3253 }
3254 
3255 static void
3256 cardbus_reparent_children(dev_info_t *dip, dev_info_t *parent)
3257 {
3258 	dev_info_t *child;
3259 
3260 	while (child = ddi_get_child(dip)) {
3261 		ASSERT(i_ddi_node_state(child) <= DS_LINKED);
3262 		/*
3263 		 * Unlink node from tree before reparenting
3264 		 */
3265 		ndi_devi_enter(dip);
3266 		(void) i_ndi_unconfig_node(child, DS_PROTO, 0);
3267 		ndi_devi_exit(dip);
3268 		DEVI(child)->devi_parent = DEVI(parent);
3269 		DEVI(child)->devi_bus_ctl = DEVI(parent);
3270 		ndi_devi_enter(parent);
3271 		(void) i_ndi_config_node(child, DS_LINKED, 0);
3272 		ndi_devi_exit(parent);
3273 	}
3274 }
3275 
3276 static int
3277 cardbus_update_assigned_prop(dev_info_t *dip, pci_regspec_t *newone)
3278 {
3279 	int		alen;
3280 	pci_regspec_t	*assigned;
3281 	caddr_t		newreg;
3282 	uint_t		status;
3283 
3284 	status = ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3285 	    "assigned-addresses", (caddr_t)&assigned, &alen);
3286 	switch (status) {
3287 	case DDI_PROP_SUCCESS:
3288 		cardbus_err(dip, 5,
3289 		    "cardbus_update_assigned_prop: found prop len %d\n",
3290 		    alen);
3291 		/*
3292 		 * Allocate memory for the existing
3293 		 * assigned-addresses(s) plus one and then
3294 		 * build it.
3295 		 */
3296 		newreg = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
3297 
3298 		bcopy(assigned, newreg, alen);
3299 		bcopy(newone, newreg + alen, sizeof (*newone));
3300 		break;
3301 
3302 	case DDI_PROP_NO_MEMORY:
3303 		cardbus_err(dip, 1,
3304 		    "no memory for assigned-addresses property\n");
3305 		return (PCICFG_FAILURE);
3306 
3307 	default:
3308 		cardbus_err(dip, 5,
3309 		    "cardbus_update_assigned_prop: creating prop\n");
3310 		alen = 0;
3311 		newreg = (caddr_t)newone;
3312 		break;
3313 	}
3314 
3315 	/*
3316 	 * Write out the new "assigned-addresses" spec
3317 	 */
3318 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3319 	    "assigned-addresses", (int *)newreg,
3320 	    (alen + sizeof (*newone))/sizeof (int));
3321 
3322 	if (status == DDI_PROP_SUCCESS)
3323 		kmem_free((caddr_t)newreg, alen+sizeof (*newone));
3324 
3325 	if (alen)
3326 		kmem_free(assigned, alen);
3327 
3328 	return (PCICFG_SUCCESS);
3329 }
3330 
3331 static int
3332 cardbus_update_available_prop(dev_info_t *dip, uint32_t hi_type,
3333     uint64_t base, uint64_t size)
3334 {
3335 	int		alen, rlen;
3336 	pci_regspec_t	*available, *reg;
3337 	pci_regspec_t	addition;
3338 	caddr_t		newreg;
3339 	uint_t		status;
3340 
3341 	cardbus_err(dip, 6, "cardbus_update_available_prop\n");
3342 
3343 	status = ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3344 	    "reg", (caddr_t)&reg, &rlen);
3345 
3346 	switch (status) {
3347 	case DDI_PROP_SUCCESS:
3348 		break;
3349 	case DDI_PROP_NO_MEMORY:
3350 		cardbus_err(dip, 1, "reg present, but unable to get memory\n");
3351 		return (PCICFG_FAILURE);
3352 	default:
3353 		cardbus_err(dip, 1, "no reg property\n");
3354 		return (PCICFG_FAILURE);
3355 	}
3356 
3357 	status = ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS,
3358 	    "available", (caddr_t)&available, &alen);
3359 	switch (status) {
3360 	case DDI_PROP_SUCCESS:
3361 		break;
3362 	case DDI_PROP_NO_MEMORY:
3363 		cardbus_err(dip, 1, "no memory for available property\n");
3364 		kmem_free((caddr_t)reg, rlen);
3365 		return (PCICFG_FAILURE);
3366 	default:
3367 		alen = 0;
3368 	}
3369 
3370 	/*
3371 	 * Allocate memory for the existing
3372 	 * available(s) plus one and then
3373 	 * build it.
3374 	 */
3375 	newreg = kmem_zalloc(alen + sizeof (pci_regspec_t), KM_SLEEP);
3376 
3377 	/*
3378 	 * Build the regspec, then add it to the existing one(s)
3379 	 */
3380 	addition.pci_phys_hi = hi_type |
3381 	    PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3382 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3383 	    PCI_REG_FUNC_G(reg->pci_phys_hi), 0);
3384 
3385 	addition.pci_phys_mid = (uint32_t)((base>>32) & 0xffffffff);
3386 	addition.pci_phys_low = (uint32_t)(base & 0xffffffff);
3387 	addition.pci_size_hi = (uint32_t)((size>>32) & 0xffffffff);
3388 	addition.pci_size_low = (uint32_t)(size & 0xffffffff);
3389 
3390 #ifdef DEBUG
3391 	cardbus_dump_reg(dip, &addition, 1);
3392 #endif
3393 
3394 	if (alen)
3395 		bcopy(available, newreg, alen);
3396 	bcopy(&addition, newreg + alen, sizeof (pci_regspec_t));
3397 
3398 	/*
3399 	 * Write out the new "available" spec
3400 	 */
3401 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3402 	    "available", (int *)newreg,
3403 	    (alen + sizeof (pci_regspec_t))/sizeof (int));
3404 
3405 	if (alen)
3406 		kmem_free((caddr_t)available, alen);
3407 	kmem_free((caddr_t)reg, rlen);
3408 	kmem_free((caddr_t)newreg, alen + sizeof (pci_regspec_t));
3409 
3410 	return (PCICFG_SUCCESS);
3411 }
3412 
3413 static int
3414 cardbus_update_ranges_prop(dev_info_t *dip, cardbus_range_t *addition)
3415 {
3416 	int		rlen;
3417 	cardbus_range_t	*ranges;
3418 	caddr_t		newreg;
3419 	uint_t		status;
3420 #if defined(CARDBUS_DEBUG)
3421 	int	i, nrange;
3422 	const cardbus_range_t	*nr;
3423 #endif
3424 
3425 	cardbus_err(dip, 6, "cardbus_update_ranges_prop\n");
3426 
3427 	status = ddi_getlongprop(DDI_DEV_T_NONE,
3428 	    dip, DDI_PROP_DONTPASS, "ranges",
3429 	    (caddr_t)&ranges, &rlen);
3430 
3431 	switch (status) {
3432 	case DDI_PROP_SUCCESS:
3433 		break;
3434 	case DDI_PROP_NO_MEMORY:
3435 		cardbus_err(dip, 1,
3436 		    "ranges present, but unable to get memory\n");
3437 		return (PCICFG_FAILURE);
3438 	default:
3439 		cardbus_err(dip, 8, "no ranges property - creating one\n");
3440 		if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
3441 		    dip, "ranges", (int *)addition,
3442 		    sizeof (cardbus_range_t)/sizeof (int))
3443 		    != DDI_SUCCESS) {
3444 			cardbus_err(dip, 1, "Did'nt create ranges property\n");
3445 			return (PCICFG_FAILURE);
3446 		}
3447 		return (PCICFG_SUCCESS);
3448 	}
3449 
3450 	/*
3451 	 * Allocate memory for the existing reg(s) plus one and then
3452 	 * build it.
3453 	 */
3454 	newreg = kmem_zalloc(rlen+sizeof (cardbus_range_t), KM_SLEEP);
3455 
3456 	bcopy(ranges, newreg, rlen);
3457 	bcopy(addition, newreg + rlen, sizeof (cardbus_range_t));
3458 
3459 	/*
3460 	 * Write out the new "ranges" property
3461 	 */
3462 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3463 	    dip, "ranges", (int *)newreg,
3464 	    (rlen + sizeof (cardbus_range_t))/sizeof (int));
3465 
3466 #if defined(CARDBUS_DEBUG)
3467 	cardbus_err(dip, 8, "cardbus_update_ranges_prop ranges property:\n");
3468 
3469 	nrange = rlen / sizeof (cardbus_range_t);
3470 	nr = (cardbus_range_t *)newreg;
3471 	for (i = 0; i <= nrange; i++) {
3472 		/* nrange is one higher for new entry */
3473 		cardbus_err(dip, 9,
3474 		    "\trange parent addr 0x%x.0x%x.0x%x "
3475 		    "child addr 0x%x.0x%x.0x%x size 0x%x.0x%x\n",
3476 		    nr->parent_hi,
3477 		    nr->parent_mid, nr->parent_lo,
3478 		    nr->child_hi,
3479 		    nr->child_mid, nr->child_lo,
3480 		    nr->size_hi, nr->size_lo);
3481 		nr++;
3482 	}
3483 #endif
3484 
3485 	kmem_free((caddr_t)newreg, rlen+sizeof (cardbus_range_t));
3486 	kmem_free((caddr_t)ranges, rlen);
3487 
3488 	return (PCICFG_SUCCESS);
3489 }
3490 
3491 static int
3492 cardbus_update_reg_prop(dev_info_t *dip, uint32_t regvalue, uint_t reg_offset)
3493 {
3494 	int	rlen;
3495 	pci_regspec_t	*reg;
3496 	caddr_t		newreg;
3497 	uint32_t	hiword;
3498 	pci_regspec_t	addition;
3499 	uint32_t	size;
3500 	uint_t		status;
3501 
3502 	status = ddi_getlongprop(DDI_DEV_T_NONE,
3503 	    dip, DDI_PROP_DONTPASS, "reg", (caddr_t)&reg, &rlen);
3504 
3505 	switch (status) {
3506 	case DDI_PROP_SUCCESS:
3507 		break;
3508 	case DDI_PROP_NO_MEMORY:
3509 		cardbus_err(dip, 1, "reg present, but unable to get memory\n");
3510 		return (PCICFG_FAILURE);
3511 	default:
3512 		cardbus_err(dip, 1, "no reg property\n");
3513 		return (PCICFG_FAILURE);
3514 	}
3515 
3516 	/*
3517 	 * Allocate memory for the existing reg(s) plus one and then
3518 	 * build it.
3519 	 */
3520 	newreg = kmem_zalloc(rlen+sizeof (pci_regspec_t), KM_SLEEP);
3521 
3522 	/*
3523 	 * Build the regspec, then add it to the existing one(s)
3524 	 */
3525 	hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3526 	    PCI_REG_DEV_G(reg->pci_phys_hi),
3527 	    PCI_REG_FUNC_G(reg->pci_phys_hi),
3528 	    reg_offset);
3529 
3530 	if (reg_offset == PCI_CONF_ROM) {
3531 		size = (~(PCI_BASE_ROM_ADDR_M & regvalue))+1;
3532 		hiword |= PCI_ADDR_MEM32;
3533 	} else {
3534 		size = (~(PCI_BASE_M_ADDR_M & regvalue))+1;
3535 
3536 		if ((PCI_BASE_SPACE_M & regvalue) == PCI_BASE_SPACE_MEM) {
3537 			if ((PCI_BASE_TYPE_M & regvalue) == PCI_BASE_TYPE_MEM) {
3538 				hiword |= PCI_ADDR_MEM32;
3539 			} else if ((PCI_BASE_TYPE_M & regvalue)
3540 			    == PCI_BASE_TYPE_ALL) {
3541 				/*
3542 				 * This is a 64 bit PCI memory space.
3543 				 * It needs to be allocated as 32 bit
3544 				 * for bus map purposes.
3545 				 */
3546 				hiword |= PCI_ADDR_MEM32;
3547 			}
3548 		} else {
3549 			hiword |= PCI_ADDR_IO;
3550 		}
3551 	}
3552 
3553 	addition.pci_phys_hi = hiword;
3554 	addition.pci_phys_mid = 0;
3555 	addition.pci_phys_low = 0;
3556 	addition.pci_size_hi = 0;
3557 	addition.pci_size_low = size;
3558 
3559 	cardbus_err(dip, 8,
3560 	    "cardbus_update_reg_prop, phys_hi 0x%08x,"
3561 	    " phys_mid 0x%08x, phys_low 0x%08x, size_hi 0x%08x,"
3562 	    " size_low 0x%08x\n", hiword, 0, 0, 0, size);
3563 
3564 	bcopy(reg, newreg, rlen);
3565 	bcopy(&addition, newreg + rlen, sizeof (pci_regspec_t));
3566 
3567 	/*
3568 	 * Write out the new "reg" property
3569 	 */
3570 	(void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3571 	    dip, "reg", (int *)newreg,
3572 	    (rlen + sizeof (pci_regspec_t))/sizeof (int));
3573 
3574 	kmem_free((caddr_t)reg, rlen);
3575 	kmem_free((caddr_t)newreg, rlen+sizeof (pci_regspec_t));
3576 
3577 	return (PCICFG_SUCCESS);
3578 }
3579 
3580 /*
3581  * Setup the basic 1275 properties based on information found in the config
3582  * header of the PCI device
3583  */
3584 static int
3585 cardbus_set_standard_props(dev_info_t *parent, dev_info_t *dip,
3586     ddi_acc_handle_t config_handle)
3587 {
3588 	int ret;
3589 	uint16_t val;
3590 	uint32_t wordval;
3591 	uint8_t byteval;
3592 
3593 	/* These two exists only for non-bridges */
3594 	if ((pci_config_get8(config_handle,
3595 	    PCI_CONF_HEADER) & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) {
3596 		byteval = pci_config_get8(config_handle, PCI_CONF_MIN_G);
3597 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3598 		    "min-grant", byteval)) != DDI_SUCCESS) {
3599 			cardbus_err(dip, 1, "Failed to sent min-grant\n");
3600 			return (ret);
3601 		}
3602 
3603 		byteval = pci_config_get8(config_handle, PCI_CONF_MAX_L);
3604 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3605 		    "max-latency", byteval)) != DDI_SUCCESS) {
3606 			return (ret);
3607 		}
3608 	}
3609 
3610 	/*
3611 	 * These should always exist and have the value of the
3612 	 * corresponding register value
3613 	 */
3614 	val = pci_config_get16(config_handle, PCI_CONF_VENID);
3615 
3616 	/*
3617 	 * according to section 6.2.1 of revision 2 of the PCI local
3618 	 * bus specification - 0FFFFh is an invalid value for the vendor ID
3619 	 */
3620 	if (val == 0xffff) {
3621 		cardbus_err(dip, 1, "Illegal vendor-id 0x%x\n", val);
3622 		return (PCICFG_FAILURE);
3623 	}
3624 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3625 	    "vendor-id", val)) != DDI_SUCCESS) {
3626 		return (ret);
3627 	}
3628 
3629 	val = pci_config_get16(config_handle, PCI_CONF_DEVID);
3630 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3631 	    "device-id", val)) != DDI_SUCCESS) {
3632 		return (ret);
3633 	}
3634 	byteval = pci_config_get8(config_handle, PCI_CONF_REVID);
3635 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3636 	    "revision-id", byteval)) != DDI_SUCCESS) {
3637 		return (ret);
3638 	}
3639 
3640 	wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3641 	    (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3642 
3643 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3644 	    "class-code", wordval)) != DDI_SUCCESS) {
3645 		return (ret);
3646 	}
3647 	val = (pci_config_get16(config_handle,
3648 	    PCI_CONF_STAT) & PCI_STAT_DEVSELT) >> 9;
3649 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3650 	    "devsel-speed", val)) != DDI_SUCCESS) {
3651 		return (ret);
3652 	}
3653 
3654 	/*
3655 	 * The next three are bits set in the status register.  The property is
3656 	 * present (but with no value other than its own existence) if the bit
3657 	 * is set, non-existent otherwise
3658 	 */
3659 	if (ddi_prop_exists(DDI_DEV_T_ANY, parent, DDI_PROP_DONTPASS,
3660 	    "fast-back-to-back") &&
3661 	    pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_FBBC) {
3662 
3663 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3664 		    "fast-back-to-back", 0)) != DDI_SUCCESS) {
3665 			return (ret);
3666 		}
3667 	}
3668 	if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_66MHZ) {
3669 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3670 		    "66mhz-capable", 0)) != DDI_SUCCESS) {
3671 			return (ret);
3672 		}
3673 	}
3674 	if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_UDF) {
3675 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3676 		    "udf-supported", 0)) != DDI_SUCCESS) {
3677 			return (ret);
3678 		}
3679 	}
3680 
3681 	/*
3682 	 * These next three are optional and are not present
3683 	 * if the corresponding register is zero.  If the value
3684 	 * is non-zero then the property exists with the value
3685 	 * of the register.
3686 	 */
3687 
3688 	/* look in the correct place for header type 2 */
3689 	byteval = pci_config_get8(config_handle, PCI_CONF_HEADER);
3690 	if ((byteval & PCI_HEADER_TYPE_M) == PCI_HEADER_TWO) {
3691 		if ((val = pci_config_get16(config_handle,
3692 		    PCI_CBUS_SUBVENID)) != 0) {
3693 			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3694 			    "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3695 				return (ret);
3696 			}
3697 		}
3698 		if ((val = pci_config_get16(config_handle,
3699 		    PCI_CBUS_SUBSYSID)) != 0) {
3700 			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3701 			    "subsystem-id", val)) != DDI_SUCCESS) {
3702 				return (ret);
3703 			}
3704 		}
3705 	} else {
3706 		if ((val = pci_config_get16(config_handle,
3707 		    PCI_CONF_SUBVENID)) != 0) {
3708 			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3709 			    "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3710 				return (ret);
3711 			}
3712 		}
3713 		if ((val = pci_config_get16(config_handle,
3714 		    PCI_CONF_SUBSYSID)) != 0) {
3715 			if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3716 			    "subsystem-id", val)) != DDI_SUCCESS) {
3717 				return (ret);
3718 			}
3719 		}
3720 	}
3721 
3722 	if ((val = pci_config_get8(config_handle,
3723 	    PCI_CONF_CACHE_LINESZ)) != 0) {
3724 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3725 		    "cache-line-size", val)) != DDI_SUCCESS) {
3726 			return (ret);
3727 		}
3728 	}
3729 
3730 	/*
3731 	 * If the Interrupt Pin register is non-zero then the
3732 	 * interrupts property exists
3733 	 */
3734 	if ((byteval = pci_config_get8(config_handle, PCI_CONF_IPIN)) != 0) {
3735 		/*
3736 		 * If interrupt pin is non-zero,
3737 		 * record the interrupt line used
3738 		 */
3739 		cardbus_err(dip, 8, "Adding interrupts property\n");
3740 		if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3741 		    "interrupts", byteval)) != DDI_SUCCESS) {
3742 			return (ret);
3743 		}
3744 	}
3745 	return (PCICFG_SUCCESS);
3746 }
3747 
3748 /*
3749  * Setup the basic properties required by the ISA node.
3750  */
3751 static int
3752 cardbus_set_isa_props(dev_info_t *parent, dev_info_t *dip,
3753     char *name, char *compat[])
3754 {
3755 	int ret, n;
3756 
3757 	_NOTE(ARGUNUSED(parent))
3758 
3759 	cardbus_err(dip, 8, "Adding interrupts property\n");
3760 	if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3761 	    "interrupts", 1)) != DDI_SUCCESS) {
3762 		return (ret);
3763 	}
3764 
3765 	/*
3766 	 * The node name field needs to be filled in with the name
3767 	 */
3768 	if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3769 		cardbus_err(dip, 1, "Failed to set nodename for node\n");
3770 		return (PCICFG_FAILURE);
3771 	}
3772 
3773 	/*
3774 	 * Create the compatible property as an array of pointers
3775 	 * to strings.  Start with the buffer created above.
3776 	 */
3777 	n = 0;
3778 	while (compat[n] != NULL)
3779 		n++;
3780 
3781 	if (n != 0)
3782 		if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
3783 		    "compatible", compat, n)) != DDI_SUCCESS)
3784 			return (ret);
3785 
3786 	return (PCICFG_SUCCESS);
3787 }
3788 
3789 static int
3790 cardbus_set_busnode_props(dev_info_t *dip)
3791 {
3792 	cardbus_err(dip, 6, "cardbus_set_busnode_props\n");
3793 
3794 	cardbus_force_stringprop(dip, "device_type", "pci");
3795 
3796 	if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3797 	    "#address-cells", 3) != DDI_SUCCESS) {
3798 		cardbus_err(dip, 4, "Failed to set #address-cells\n");
3799 	}
3800 	if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3801 	    "#size-cells", 2) != DDI_SUCCESS) {
3802 		cardbus_err(dip, 4, "Failed to set #size-cells\n");
3803 	}
3804 	return (PCICFG_SUCCESS);
3805 }
3806 
3807 static int
3808 cardbus_set_busnode_isaprops(dev_info_t *dip)
3809 {
3810 	cardbus_err(dip, 6, "cardbus_set_busnode_props\n");
3811 
3812 	cardbus_force_stringprop(dip, "device_type", "isa");
3813 
3814 	if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3815 	    "#address-cells", 2) != DDI_SUCCESS) {
3816 		cardbus_err(dip, 4, "Failed to set #address-cells\n");
3817 	}
3818 	if (ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3819 	    "#size-cells", 1) != DDI_SUCCESS) {
3820 		cardbus_err(dip, 4, "Failed to set #size-cells\n");
3821 	}
3822 	return (PCICFG_SUCCESS);
3823 }
3824 
3825 /*
3826  * Use cb%x,%x rather than pci%x,%x so that we can use specific cardbus
3827  * drivers in /etc/driver_aliases if required
3828  */
3829 static int
3830 cardbus_set_childnode_props(dev_info_t *dip, ddi_acc_handle_t config_handle)
3831 {
3832 	int		ret;
3833 #ifndef _DONT_USE_1275_GENERIC_NAMES
3834 	uint32_t	wordval;
3835 #endif
3836 	char		*name;
3837 	char		buffer[64];
3838 	uint32_t	classcode;
3839 	char		*compat[8];
3840 	int		i, n;
3841 	uint16_t	subsysid, subvenid, devid, venid;
3842 	uint8_t		header_type;
3843 
3844 	/*
3845 	 * NOTE: These are for both a child and PCI-PCI bridge node
3846 	 */
3847 #ifndef _DONT_USE_1275_GENERIC_NAMES
3848 	wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3849 	    (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3850 #endif
3851 
3852 	/* Cardbus support */
3853 	venid = pci_config_get16(config_handle, PCI_CONF_VENID);
3854 	devid = pci_config_get16(config_handle, PCI_CONF_DEVID);
3855 
3856 	header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
3857 	if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_TWO) {
3858 		subvenid = pci_config_get16(config_handle, PCI_CBUS_SUBVENID);
3859 		subsysid = pci_config_get16(config_handle, PCI_CBUS_SUBSYSID);
3860 	} else {
3861 		subvenid = pci_config_get16(config_handle, PCI_CONF_SUBVENID);
3862 		subsysid = pci_config_get16(config_handle, PCI_CONF_SUBSYSID);
3863 	}
3864 
3865 	if (subsysid != 0) {
3866 		(void) sprintf(buffer, "pci%x,%x", subvenid, subsysid);
3867 	} else {
3868 		(void) sprintf(buffer, "pci%x,%x", venid, devid);
3869 	}
3870 
3871 	cardbus_err(dip, 8, "Childname is %s\n", buffer);
3872 
3873 	/*
3874 	 * In some environments, trying to use "generic" 1275 names is
3875 	 * not the convention.  In those cases use the name as created
3876 	 * above.  In all the rest of the cases, check to see if there
3877 	 * is a generic name first.
3878 	 */
3879 #ifdef _DONT_USE_1275_GENERIC_NAMES
3880 	name = buffer;
3881 #else
3882 	if ((name = cardbus_get_class_name(wordval>>8)) == NULL) {
3883 		/*
3884 		 * Set name to the above fabricated name
3885 		 */
3886 		name = buffer;
3887 	}
3888 
3889 	cardbus_err(dip, 8, "Set nodename to %s\n", name);
3890 #endif
3891 
3892 	/*
3893 	 * The node name field needs to be filled in with the name
3894 	 */
3895 	if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3896 		cardbus_err(dip, 1, "Failed to set nodename for node\n");
3897 		return (PCICFG_FAILURE);
3898 	}
3899 
3900 	/*
3901 	 * Create the compatible property as an array of pointers
3902 	 * to strings.  Start with the cb name.
3903 	 */
3904 	n = 0;
3905 
3906 	if (subsysid != 0) {
3907 		(void) sprintf(buffer, "cb%x,%x", subvenid, subsysid);
3908 	} else {
3909 		(void) sprintf(buffer, "cb%x,%x", venid, devid);
3910 	}
3911 
3912 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3913 	(void) strcpy(compat[n++], buffer);
3914 
3915 	if (subsysid != 0) {
3916 		/*
3917 		 * Add subsys numbers as pci compatible.
3918 		 */
3919 		(void) sprintf(buffer, "pci%x,%x", subvenid, subsysid);
3920 		compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3921 		(void) strcpy(compat[n++], buffer);
3922 	}
3923 
3924 	/*
3925 	 * Add in the VendorID/DeviceID compatible name.
3926 	 */
3927 	(void) sprintf(buffer, "pci%x,%x", venid, devid);
3928 
3929 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3930 	(void) strcpy(compat[n++], buffer);
3931 
3932 	classcode = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3933 	    (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3934 
3935 	/*
3936 	 * Add in the Classcode
3937 	 */
3938 	(void) sprintf(buffer, "pciclass,%06x", classcode);
3939 
3940 	cardbus_err(dip, 8, "class code %s\n", buffer);
3941 
3942 	compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3943 	(void) strcpy(compat[n++], buffer);
3944 
3945 	if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
3946 	    "compatible", (char **)compat, n)) != DDI_SUCCESS) {
3947 		return (ret);
3948 	}
3949 
3950 	for (i = 0; i < n; i++) {
3951 		kmem_free(compat[i], strlen(compat[i]) + 1);
3952 	}
3953 
3954 	return (PCICFG_SUCCESS);
3955 }
3956 
3957 /*
3958  * Program the bus numbers into the bridge
3959  */
3960 static void
3961 cardbus_set_bus_numbers(ddi_acc_handle_t config_handle,
3962     uint_t primary, uint_t secondary)
3963 {
3964 	cardbus_err(NULL, 8,
3965 	    "cardbus_set_bus_numbers [%d->%d]\n", primary, secondary);
3966 
3967 	/*
3968 	 * Primary bus#
3969 	 */
3970 	pci_config_put8(config_handle, PCI_BCNF_PRIBUS, primary);
3971 
3972 	/*
3973 	 * Secondary bus#
3974 	 */
3975 	pci_config_put8(config_handle, PCI_BCNF_SECBUS, secondary);
3976 
3977 	/*
3978 	 * Set the subordinate bus number to ff in order to pass through any
3979 	 * type 1 cycle with a bus number higher than the secondary bus#
3980 	 * Note that this is reduced once the probe is complete in the
3981 	 * cardbus_setup_bridge() function.
3982 	 */
3983 	pci_config_put8(config_handle, PCI_BCNF_SUBBUS, 0xFF);
3984 }
3985 
3986 static void
3987 enable_pci_isa_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
3988 {
3989 	uint16_t comm, stat;
3990 
3991 	stat = pci_config_get16(config_handle, PCI_CONF_STAT);
3992 	comm = pci_config_get16(config_handle, PCI_CONF_COMM);
3993 
3994 	/*
3995 	 * Enable memory, IO, bus mastership and error detection.
3996 	 */
3997 	comm |= (PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO |
3998 	    PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
3999 	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
4000 	    "fast-back-to-back"))
4001 		comm |= PCI_COMM_BACK2BACK_ENAB;
4002 	pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4003 	cardbus_err(NULL, 8,
4004 	    "enable_pci_isa_bridge stat 0x%04x comm 0x%04x\n", stat, comm);
4005 
4006 	/*
4007 	 * ITE8888 Specific registers.
4008 	 */
4009 	pci_config_put8(config_handle, 0x50, 0x00); /* Timing Control */
4010 	pci_config_put8(config_handle, 0x52, 0x00); /* Master DMA Access */
4011 	pci_config_put8(config_handle, 0x53, 0x01); /* ROMCS */
4012 }
4013 
4014 static void
4015 enable_pci_pci_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4016 {
4017 	uint16_t comm, stat, bctrl;
4018 
4019 	stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4020 	comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4021 	bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4022 
4023 	comm &= ~(PCI_COMM_IO | PCI_COMM_MAE);
4024 	comm |= (PCI_COMM_ME | PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
4025 
4026 	/*
4027 	 * Enable back to back.
4028 	 */
4029 	if (stat & PCI_STAT_FBBC)
4030 		comm |= PCI_COMM_BACK2BACK_ENAB;
4031 
4032 	pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4033 
4034 	/*
4035 	 * Reset the sub-ordinate bus.
4036 	 */
4037 	if (!(bctrl & PCI_BCNF_BCNTRL_RESET))
4038 		pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL,
4039 		    bctrl | PCI_BCNF_BCNTRL_RESET);
4040 	else
4041 		bctrl &= ~PCI_BCNF_BCNTRL_RESET;
4042 
4043 	/*
4044 	 * Enable error reporting.
4045 	 */
4046 	bctrl |= (PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE |
4047 	    PCI_BCNF_BCNTRL_MAST_AB_MODE);
4048 
4049 	/*
4050 	 * Enable back to back on secondary bus.
4051 	 */
4052 	if (stat & PCI_STAT_FBBC)
4053 		bctrl |= PCI_BCNF_BCNTRL_B2B_ENAB;
4054 
4055 	pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4056 	cardbus_err(dip, 8,
4057 	    "enable_pci_pci_bridge stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4058 	    stat, comm, bctrl);
4059 }
4060 
4061 static int	cardbus_reset_wait = 20;
4062 
4063 static void
4064 enable_cardbus_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4065 {
4066 	uint16_t comm, stat, bctrl;
4067 
4068 	stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4069 	comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4070 	bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4071 
4072 	/*
4073 	 * Don't mess with the command register on the cardbus bridge
4074 	 * itself. This should have been done when it's parent
4075 	 * did the setup. Some devices *require* certain things to
4076 	 * disabled, this can be done using the "command-preserve"
4077 	 * property and if we mess with it here it breaks that.
4078 	 *
4079 	 * comm |= (PCI_COMM_ME | PCI_COMM_PARITY_DETECT |
4080 	 *	PCI_COMM_SERR_ENABLE);
4081 	 */
4082 
4083 	/*
4084 	 * Reset the sub-ordinate bus.
4085 	 */
4086 	if (!(bctrl & PCI_BCNF_BCNTRL_RESET))
4087 		pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL,
4088 		    bctrl | PCI_BCNF_BCNTRL_RESET);
4089 	else
4090 		bctrl &= ~PCI_BCNF_BCNTRL_RESET;
4091 
4092 	/*
4093 	 * Turn off pre-fetch.
4094 	 */
4095 	bctrl &= ~(CB_BCNF_BCNTRL_MEM0_PREF | CB_BCNF_BCNTRL_MEM1_PREF |
4096 	    PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE);
4097 
4098 	/*
4099 	 * Enable error reporting.
4100 	 */
4101 	bctrl |= (PCI_BCNF_BCNTRL_MAST_AB_MODE | CB_BCNF_BCNTRL_WRITE_POST);
4102 	if (comm & PCI_COMM_PARITY_DETECT)
4103 		bctrl |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
4104 	if (comm & PCI_COMM_SERR_ENABLE)
4105 		bctrl |= PCI_BCNF_BCNTRL_SERR_ENABLE;
4106 
4107 	pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4108 	pci_config_put8(config_handle, PCI_CBUS_LATENCY_TIMER,
4109 	    cardbus_latency_timer);
4110 
4111 	pci_config_put16(config_handle, PCI_CONF_STAT, stat);
4112 	pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4113 
4114 	cardbus_err(dip, 8,
4115 	    "enable_cardbus_bridge() stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4116 	    stat, comm, bctrl);
4117 
4118 	/* after resetting the bridge, wait for everything to stablize */
4119 	delay(drv_usectohz(cardbus_reset_wait * 1000));
4120 
4121 }
4122 
4123 static void
4124 disable_pci_pci_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4125 {
4126 	uint16_t comm, bctrl;
4127 
4128 	comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4129 	bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4130 
4131 	/*
4132 	 * Turn off subordinate bus access.
4133 	 */
4134 	pci_config_put8(config_handle, PCI_BCNF_SECBUS, 0);
4135 	pci_config_put8(config_handle, PCI_BCNF_SUBBUS, 0);
4136 
4137 	/*
4138 	 * Disable error reporting.
4139 	 */
4140 	bctrl &= ~(PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE |
4141 	    PCI_BCNF_BCNTRL_MAST_AB_MODE);
4142 	comm = 0;
4143 
4144 	pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4145 	pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4146 
4147 	cardbus_err(dip, 6,
4148 	    "disable_pci_pci_bridge() stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4149 	    pci_config_get16(config_handle, PCI_CONF_STAT), comm, bctrl);
4150 }
4151 
4152 static void
4153 disable_cardbus_bridge(dev_info_t *dip, ddi_acc_handle_t config_handle)
4154 {
4155 	uint16_t comm, bctrl;
4156 
4157 	comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4158 	bctrl = pci_config_get16(config_handle, PCI_CBUS_BRIDGE_CTRL);
4159 
4160 	/*
4161 	 * Turn off subordinate bus access.
4162 	 */
4163 	pci_config_put8(config_handle, PCI_BCNF_SECBUS, 0);
4164 	pci_config_put8(config_handle, PCI_BCNF_SUBBUS, 0);
4165 
4166 	/*
4167 	 * Disable error reporting.
4168 	 */
4169 	bctrl &= ~(PCI_BCNF_BCNTRL_PARITY_ENABLE | PCI_BCNF_BCNTRL_SERR_ENABLE |
4170 	    PCI_BCNF_BCNTRL_MAST_AB_MODE);
4171 
4172 	pci_config_put32(config_handle, PCI_CBUS_MEM_LIMIT0, 0);
4173 	pci_config_put32(config_handle, PCI_CBUS_MEM_BASE0, 0);
4174 	pci_config_put32(config_handle, PCI_CBUS_IO_LIMIT0, 0);
4175 	pci_config_put32(config_handle, PCI_CBUS_IO_BASE0, 0);
4176 	pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4177 	pci_config_put16(config_handle, PCI_CBUS_BRIDGE_CTRL, bctrl);
4178 
4179 	cardbus_err(dip, 6,
4180 	    "disable_cardbus_bridge() stat 0x%04x comm 0x%04x bctrl 0x%04x\n",
4181 	    pci_config_get16(config_handle, PCI_CONF_STAT), comm, bctrl);
4182 }
4183 
4184 static void
4185 enable_cardbus_device(dev_info_t *dip, ddi_acc_handle_t config_handle)
4186 {
4187 	uint16_t comm, stat;
4188 
4189 	stat = pci_config_get16(config_handle, PCI_CONF_STAT);
4190 	comm = pci_config_get16(config_handle, PCI_CONF_COMM);
4191 
4192 	/*
4193 	 * Enable memory, IO, bus mastership and error detection.
4194 	 */
4195 	comm |= (PCI_COMM_ME | PCI_COMM_MAE | PCI_COMM_IO |
4196 	    PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
4197 	if (ddi_prop_exists(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
4198 	    "fast-back-to-back"))
4199 		comm |= PCI_COMM_BACK2BACK_ENAB;
4200 	pci_config_put16(config_handle, PCI_CONF_COMM, comm);
4201 	cardbus_err(NULL, 8,
4202 	    "enable_cardbus_device stat 0x%04x comm 0x%04x\n", stat, comm);
4203 }
4204 
4205 static void
4206 disable_cardbus_device(ddi_acc_handle_t config_handle)
4207 {
4208 	cardbus_err(NULL, 8, "disable_cardbus_device\n");
4209 
4210 	/*
4211 	 * Turn off everything in the command register.
4212 	 */
4213 	pci_config_put16(config_handle, PCI_CONF_COMM, 0x0);
4214 }
4215 
4216 #ifndef _DONT_USE_1275_GENERIC_NAMES
4217 static char *
4218 cardbus_get_class_name(uint32_t classcode)
4219 {
4220 	struct cardbus_name_entry *ptr;
4221 
4222 	for (ptr = &cardbus_class_lookup[0]; ptr->name != NULL; ptr++) {
4223 		if (ptr->class_code == classcode) {
4224 			return (ptr->name);
4225 		}
4226 	}
4227 	return (NULL);
4228 }
4229 #endif /* _DONT_USE_1275_GENERIC_NAMES */
4230 
4231 static void
4232 cardbus_force_boolprop(dev_info_t *dip, char *pname)
4233 {
4234 	int ret;
4235 
4236 	if ((ret = ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
4237 	    pname)) != DDI_SUCCESS) {
4238 		if (ret == DDI_PROP_NOT_FOUND)
4239 			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
4240 			    DDI_PROP_CANSLEEP, pname,
4241 			    (caddr_t)NULL, 0) != DDI_SUCCESS)
4242 				cardbus_err(dip, 4,
4243 				    "Failed to set boolean property "
4244 				    "\"%s\"\n", pname);
4245 	}
4246 }
4247 
4248 static void
4249 cardbus_force_intprop(dev_info_t *dip, char *pname, int *pval, int len)
4250 {
4251 	int ret;
4252 
4253 	if ((ret = ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
4254 	    pname, pval, len)) != DDI_SUCCESS) {
4255 		if (ret == DDI_PROP_NOT_FOUND)
4256 			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
4257 			    DDI_PROP_CANSLEEP, pname,
4258 			    (caddr_t)pval, len*sizeof (int))
4259 			    != DDI_SUCCESS)
4260 				cardbus_err(dip, 4,
4261 				    "Failed to set int property \"%s\"\n",
4262 				    pname);
4263 	}
4264 }
4265 
4266 static void
4267 cardbus_force_stringprop(dev_info_t *dip, char *pname, char *pval)
4268 {
4269 	int ret;
4270 
4271 	if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
4272 	    pname, pval)) != DDI_SUCCESS) {
4273 		if (ret == DDI_PROP_NOT_FOUND)
4274 			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
4275 			    DDI_PROP_CANSLEEP, pname,
4276 			    pval, strlen(pval) + 1) != DDI_SUCCESS)
4277 				cardbus_err(dip, 4,
4278 				    "Failed to set string property "
4279 				    "\"%s\" to \"%s\"\n",
4280 				    pname, pval);
4281 	}
4282 }
4283 
4284 static void
4285 split_addr(char *naddr, int *dev, int *func)
4286 {
4287 	char	c;
4288 	int	*ip = dev;
4289 
4290 	*dev = 0;
4291 	*func = 0;
4292 
4293 	while (c = *naddr++) {
4294 		if (c == ',') {
4295 			ip = func;
4296 			continue;
4297 		}
4298 		if (c >= '0' && c <= '9') {
4299 			*ip = (*ip * 16) + (c - '0');
4300 		} else if (c >= 'a' && c <= 'f') {
4301 			*ip = (*ip * 16) + 10 + (c - 'a');
4302 		} else
4303 			break;
4304 	}
4305 }
4306 
4307 #ifdef DEBUG
4308 static void
4309 cardbus_dump_common_config(ddi_acc_handle_t config_handle)
4310 {
4311 	cardbus_err(NULL, 1,
4312 	    " Vendor ID   = [0x%04x]        "
4313 	    "Device ID   = [0x%04x]\n",
4314 	    pci_config_get16(config_handle, PCI_CONF_VENID),
4315 	    pci_config_get16(config_handle, PCI_CONF_DEVID));
4316 	cardbus_err(NULL, 1,
4317 	    " Command REG = [0x%04x]        "
4318 	    "Status  REG = [0x%04x]\n",
4319 	    pci_config_get16(config_handle, PCI_CONF_COMM),
4320 	    pci_config_get16(config_handle, PCI_CONF_STAT));
4321 	cardbus_err(NULL, 1,
4322 	    " Revision ID = [0x%02x]          "
4323 	    "Prog Class  = [0x%02x]\n",
4324 	    pci_config_get8(config_handle, PCI_CONF_REVID),
4325 	    pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
4326 	cardbus_err(NULL, 1,
4327 	    " Dev Class   = [0x%02x]          "
4328 	    "Base Class  = [0x%02x]\n",
4329 	    pci_config_get8(config_handle, PCI_CONF_SUBCLASS),
4330 	    pci_config_get8(config_handle, PCI_CONF_BASCLASS));
4331 	cardbus_err(NULL, 1,
4332 	    " Cache LnSz  = [0x%02x]          "
4333 	    "Latency Tmr = [0x%02x]\n",
4334 	    pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ),
4335 	    pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER));
4336 	cardbus_err(NULL, 1,
4337 	    " Header Type = [0x%02x]          "
4338 	    "BIST        = [0x%02x]\n",
4339 	    pci_config_get8(config_handle, PCI_CONF_HEADER),
4340 	    pci_config_get8(config_handle, PCI_CONF_BIST));
4341 }
4342 
4343 static void
4344 cardbus_dump_device_config(ddi_acc_handle_t config_handle)
4345 {
4346 	cardbus_dump_common_config(config_handle);
4347 
4348 	cardbus_err(NULL, 1,
4349 	    " BASE 0      = [0x%08x]	BASE 1      = [0x%08x]\n",
4350 	    pci_config_get32(config_handle, PCI_CONF_BASE0),
4351 	    pci_config_get32(config_handle, PCI_CONF_BASE1));
4352 	cardbus_err(NULL, 1,
4353 	    " BASE 2      = [0x%08x]	BASE 3      = [0x%08x]\n",
4354 	    pci_config_get32(config_handle, PCI_CONF_BASE2),
4355 	    pci_config_get32(config_handle, PCI_CONF_BASE3));
4356 	cardbus_err(NULL, 1,
4357 	    " BASE 4      = [0x%08x]	BASE 5      = [0x%08x]\n",
4358 	    pci_config_get32(config_handle, PCI_CONF_BASE4),
4359 	    pci_config_get32(config_handle, PCI_CONF_BASE5));
4360 	cardbus_err(NULL, 1,
4361 	    " Cardbus CIS = [0x%08x]	ROM         = [0x%08x]\n",
4362 	    pci_config_get32(config_handle, PCI_CONF_CIS),
4363 	    pci_config_get32(config_handle, PCI_CONF_ROM));
4364 	cardbus_err(NULL, 1,
4365 	    " Sub VID     = [0x%04x]	Sub SID     = [0x%04x]\n",
4366 	    pci_config_get16(config_handle, PCI_CONF_SUBVENID),
4367 	    pci_config_get16(config_handle, PCI_CONF_SUBSYSID));
4368 	cardbus_err(NULL, 1,
4369 	    " I Line      = [0x%02x]	I Pin       = [0x%02x]\n",
4370 	    pci_config_get8(config_handle, PCI_CONF_ILINE),
4371 	    pci_config_get8(config_handle, PCI_CONF_IPIN));
4372 	cardbus_err(NULL, 1,
4373 	    " Max Grant   = [0x%02x]	Max Latent  = [0x%02x]\n",
4374 	    pci_config_get8(config_handle, PCI_CONF_MIN_G),
4375 	    pci_config_get8(config_handle, PCI_CONF_MAX_L));
4376 }
4377 
4378 static void
4379 cardbus_dump_bridge_config(ddi_acc_handle_t config_handle, uint8_t header_type)
4380 {
4381 	if (header_type == PCI_HEADER_PPB) {
4382 		cardbus_dump_common_config(config_handle);
4383 		cardbus_err(NULL, 1,
4384 		    "........................................\n");
4385 	} else {
4386 		cardbus_dump_common_config(config_handle);
4387 		cardbus_err(NULL, 1,
4388 		    " Mem Base    = [0x%08x]	CBus Status = [0x%04x]\n",
4389 		    pci_config_get32(config_handle, PCI_CBUS_SOCK_REG),
4390 		    pci_config_get16(config_handle, PCI_CBUS_SEC_STATUS));
4391 	}
4392 
4393 	cardbus_err(NULL, 1,
4394 	    " Pri Bus	= [0x%02x]		Sec Bus	= [0x%02x]\n",
4395 	    pci_config_get8(config_handle, PCI_BCNF_PRIBUS),
4396 	    pci_config_get8(config_handle, PCI_BCNF_SECBUS));
4397 	cardbus_err(NULL, 1,
4398 	    " Sub Bus     = [0x%02x]		Sec Latency = [0x%02x]\n",
4399 	    pci_config_get8(config_handle, PCI_BCNF_SUBBUS),
4400 	    pci_config_get8(config_handle, PCI_BCNF_LATENCY_TIMER));
4401 
4402 	switch (header_type) {
4403 	case PCI_HEADER_PPB:
4404 		cardbus_err(NULL, 1,
4405 		    " I/O Base LO = [0x%02x]	I/O Lim LO  = [0x%02x]\n",
4406 		    pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW),
4407 		    pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW));
4408 		cardbus_err(NULL, 1,
4409 		    " Sec. Status = [0x%04x]\n",
4410 		    pci_config_get16(config_handle, PCI_BCNF_SEC_STATUS));
4411 		cardbus_err(NULL, 1,
4412 		    " Mem Base    = [0x%04x]	Mem Limit   = [0x%04x]\n",
4413 		    pci_config_get16(config_handle, PCI_BCNF_MEM_BASE),
4414 		    pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT));
4415 		cardbus_err(NULL, 1,
4416 		    " PF Mem Base = [0x%04x]	PF Mem Lim  = [0x%04x]\n",
4417 		    pci_config_get16(config_handle, PCI_BCNF_PF_BASE_LOW),
4418 		    pci_config_get16(config_handle, PCI_BCNF_PF_LIMIT_LOW));
4419 		cardbus_err(NULL, 1,
4420 		    " PF Base HI  = [0x%08x]	PF Lim  HI  = [0x%08x]\n",
4421 		    pci_config_get32(config_handle, PCI_BCNF_PF_BASE_HIGH),
4422 		    pci_config_get32(config_handle, PCI_BCNF_PF_LIMIT_HIGH));
4423 		cardbus_err(NULL, 1,
4424 		    " I/O Base HI = [0x%04x]	I/O Lim HI  = [0x%04x]\n",
4425 		    pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI),
4426 		    pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI));
4427 		cardbus_err(NULL, 1,
4428 		    " ROM addr    = [0x%08x]\n",
4429 		    pci_config_get32(config_handle, PCI_BCNF_ROM));
4430 		break;
4431 	case PCI_HEADER_CARDBUS:
4432 		cardbus_err(NULL, 1,
4433 		    " Mem Base 0  = [0x%08x]	Mem Limit 0 = [0x%08x]\n",
4434 		    pci_config_get32(config_handle, PCI_CBUS_MEM_BASE0),
4435 		    pci_config_get32(config_handle, PCI_CBUS_MEM_LIMIT0));
4436 		cardbus_err(NULL, 1,
4437 		    " Mem Base 1  = [0x%08x]	Mem Limit 1 = [0x%08x]\n",
4438 		    pci_config_get32(config_handle, PCI_CBUS_MEM_BASE1),
4439 		    pci_config_get32(config_handle, PCI_CBUS_MEM_LIMIT1));
4440 		cardbus_err(NULL, 1,
4441 		    " IO Base 0   = [0x%08x]	IO Limit 0  = [0x%08x]\n",
4442 		    pci_config_get32(config_handle, PCI_CBUS_IO_BASE0),
4443 		    pci_config_get32(config_handle, PCI_CBUS_IO_LIMIT0));
4444 		cardbus_err(NULL, 1,
4445 		    " IO Base 1   = [0x%08x]	IO Limit 1  = [0x%08x]\n",
4446 		    pci_config_get32(config_handle, PCI_CBUS_IO_BASE1),
4447 		    pci_config_get32(config_handle, PCI_CBUS_IO_LIMIT1));
4448 		break;
4449 	}
4450 	cardbus_err(NULL, 1,
4451 	    " Intr Line   = [0x%02x]		Intr Pin    = [0x%02x]\n",
4452 	    pci_config_get8(config_handle, PCI_BCNF_ILINE),
4453 	    pci_config_get8(config_handle, PCI_BCNF_IPIN));
4454 	cardbus_err(NULL, 1,
4455 	    " Bridge Ctrl = [0x%04x]\n",
4456 	    pci_config_get16(config_handle, PCI_BCNF_BCNTRL));
4457 
4458 	switch (header_type) {
4459 	case PCI_HEADER_CARDBUS:
4460 		cardbus_err(NULL, 1,
4461 		    " Sub VID     = [0x%04x]	Sub SID     = [0x%04x]\n",
4462 		    pci_config_get16(config_handle, PCI_CBUS_SUBVENID),
4463 		    pci_config_get16(config_handle, PCI_CBUS_SUBSYSID));
4464 		/* LATER: TI1250 only */
4465 		cardbus_err(NULL, 1,
4466 		    " Sys Control = [0x%08x]\n",
4467 		    pci_config_get32(config_handle, 0x80));
4468 	}
4469 }
4470 
4471 static void
4472 cardbus_dump_config(ddi_acc_handle_t config_handle)
4473 {
4474 	uint8_t header_type = pci_config_get8(config_handle,
4475 	    PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
4476 
4477 	if (header_type == PCI_HEADER_PPB || header_type == PCI_HEADER_CARDBUS)
4478 		cardbus_dump_bridge_config(config_handle, header_type);
4479 	else
4480 		cardbus_dump_device_config(config_handle);
4481 }
4482 
4483 static void
4484 cardbus_dump_reg(dev_info_t *dip, const pci_regspec_t *regspec, int nelems)
4485 {
4486 	/* int rlen = nelems * sizeof(pci_regspec_t); */
4487 
4488 	cardbus_err(dip, 6,
4489 	    "cardbus_dump_reg: \"reg\" has %d elements\n", nelems);
4490 
4491 #if defined(CARDBUS_DEBUG)
4492 	if (cardbus_debug >= 1) {
4493 		int	i;
4494 		uint32_t *regs = (uint32_t *)regspec;
4495 
4496 		for (i = 0; i < nelems; i++) {
4497 
4498 			cardbus_err(NULL, 6,
4499 			    "\t%d:%08x %08x %08x %08x %08x\n",
4500 			    i, regs[0], regs[1], regs[2], regs[3], regs[4]);
4501 		}
4502 	}
4503 #endif
4504 }
4505 
4506 #endif
4507 
4508 #if defined(CARDBUS_DEBUG)
4509 void
4510 cardbus_dump_children(dev_info_t *dip, int level)
4511 {
4512 	dev_info_t *next;
4513 
4514 	cardbus_err(dip, 1,
4515 	    "\t%d: %s: 0x%p\n", level, ddi_node_name(dip), (void *) dip);
4516 	for (next = ddi_get_child(dip); next;
4517 	    next = ddi_get_next_sibling(next))
4518 		cardbus_dump_children(next, level + 1);
4519 }
4520 
4521 void
4522 cardbus_dump_family_tree(dev_info_t *dip)
4523 {
4524 	cardbus_err(dip, 1, "0x%p family tree:\n", (void *) dip);
4525 	cardbus_dump_children(dip, 1);
4526 }
4527 #endif
4528