xref: /titanic_44/usr/src/uts/i86pc/io/pci/pci.c (revision 60b08185ce63023f22fd6b2ed0db8c0d119b2023)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  *	Host to PCI local bus driver
31  */
32 
33 #include <sys/conf.h>
34 #include <sys/modctl.h>
35 #include <sys/pci.h>
36 #include <sys/pci_impl.h>
37 #include <sys/sysmacros.h>
38 #include <sys/sunndi.h>
39 #include <sys/hotplug/pci/pcihp.h>
40 #include <sys/pci_cfgspace.h>
41 #include <io/pci/pci_common.h>
42 #include <io/pci/pci_tools_ext.h>
43 #include <io/pci/pci_var.h>
44 
45 /* Save minimal state. */
46 void *pci_statep;
47 
48 /*
49  * Bus Operation functions
50  */
51 static int	pci_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
52 		    off_t, off_t, caddr_t *);
53 static int	pci_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
54 		    void *, void *);
55 static int	pci_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t,
56 		    ddi_intr_handle_impl_t *, void *);
57 
58 struct bus_ops pci_bus_ops = {
59 	BUSO_REV,
60 	pci_bus_map,
61 	NULL,
62 	NULL,
63 	NULL,
64 	i_ddi_map_fault,
65 	ddi_dma_map,
66 	ddi_dma_allochdl,
67 	ddi_dma_freehdl,
68 	ddi_dma_bindhdl,
69 	ddi_dma_unbindhdl,
70 	ddi_dma_flush,
71 	ddi_dma_win,
72 	ddi_dma_mctl,
73 	pci_ctlops,
74 	ddi_bus_prop_op,
75 	0,		/* (*bus_get_eventcookie)();	*/
76 	0,		/* (*bus_add_eventcall)();	*/
77 	0,		/* (*bus_remove_eventcall)();	*/
78 	0,		/* (*bus_post_event)();		*/
79 	0,		/* (*bus_intr_ctl)(); */
80 	0,		/* (*bus_config)(); */
81 	0,		/* (*bus_unconfig)(); */
82 	NULL,		/* (*bus_fm_init)(); */
83 	NULL,		/* (*bus_fm_fini)(); */
84 	NULL,		/* (*bus_fm_access_enter)(); */
85 	NULL,		/* (*bus_fm_access_exit)(); */
86 	NULL,		/* (*bus_power)(); */
87 	pci_intr_ops	/* (*bus_intr_op)(); */
88 };
89 
90 /*
91  * One goal here is to leverage off of the pcihp.c source without making
92  * changes to it.  Call into it's cb_ops directly if needed, piggybacking
93  * anything else needed by the pci_tools.c module.  Only pci_tools and pcihp
94  * will be opening PCI nexus driver file descriptors.
95  */
96 static int	pci_open(dev_t *, int, int, cred_t *);
97 static int	pci_close(dev_t, int, int, cred_t *);
98 static int	pci_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
99 static int	pci_prop_op(dev_t, dev_info_t *, ddi_prop_op_t, int, char *,
100 		    caddr_t, int *);
101 static int	pci_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
102 
103 struct cb_ops pci_cb_ops = {
104 	pci_open,			/* open */
105 	pci_close,			/* close */
106 	nodev,				/* strategy */
107 	nodev,				/* print */
108 	nodev,				/* dump */
109 	nodev,				/* read */
110 	nodev,				/* write */
111 	pci_ioctl,			/* ioctl */
112 	nodev,				/* devmap */
113 	nodev,				/* mmap */
114 	nodev,				/* segmap */
115 	nochpoll,			/* poll */
116 	pci_prop_op,			/* cb_prop_op */
117 	NULL,				/* streamtab */
118 	D_NEW | D_MP | D_HOTPLUG,	/* Driver compatibility flag */
119 	CB_REV,				/* rev */
120 	nodev,				/* int (*cb_aread)() */
121 	nodev				/* int (*cb_awrite)() */
122 };
123 
124 /*
125  * Device Node Operation functions
126  */
127 static int pci_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
128 static int pci_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
129 
130 struct dev_ops pci_ops = {
131 	DEVO_REV,		/* devo_rev */
132 	0,			/* refcnt  */
133 	pci_info,		/* info */
134 	nulldev,		/* identify */
135 	nulldev,		/* probe */
136 	pci_attach,		/* attach */
137 	pci_detach,		/* detach */
138 	nulldev,		/* reset */
139 	&pci_cb_ops,		/* driver operations */
140 	&pci_bus_ops		/* bus operations */
141 };
142 
143 /*
144  * This variable controls the default setting of the command register
145  * for pci devices.  See pci_initchild() for details.
146  */
147 static ushort_t pci_command_default = PCI_COMM_ME |
148 					PCI_COMM_MAE |
149 					PCI_COMM_IO;
150 
151 /*
152  * Internal routines in support of particular pci_ctlops.
153  */
154 static int pci_removechild(dev_info_t *child);
155 static int pci_initchild(dev_info_t *child);
156 
157 /*
158  * These are the access routines.  The pci_bus_map sets the handle
159  * to point to these.
160  */
161 static uint8_t pci_config_rd8(ddi_acc_impl_t *hdlp, uint8_t *addr);
162 static uint16_t pci_config_rd16(ddi_acc_impl_t *hdlp, uint16_t *addr);
163 static uint32_t pci_config_rd32(ddi_acc_impl_t *hdlp, uint32_t *addr);
164 static uint64_t pci_config_rd64(ddi_acc_impl_t *hdlp, uint64_t *addr);
165 
166 static void pci_config_wr8(ddi_acc_impl_t *hdlp, uint8_t *addr,
167 				uint8_t value);
168 static void pci_config_wr16(ddi_acc_impl_t *hdlp, uint16_t *addr,
169 				uint16_t value);
170 static void pci_config_wr32(ddi_acc_impl_t *hdlp, uint32_t *addr,
171 				uint32_t value);
172 static void pci_config_wr64(ddi_acc_impl_t *hdlp, uint64_t *addr,
173 				uint64_t value);
174 
175 static void pci_config_rep_rd8(ddi_acc_impl_t *hdlp, uint8_t *host_addr,
176 	uint8_t *dev_addr, size_t repcount, uint_t flags);
177 static void pci_config_rep_rd16(ddi_acc_impl_t *hdlp, uint16_t *host_addr,
178 	uint16_t *dev_addr, size_t repcount, uint_t flags);
179 static void pci_config_rep_rd32(ddi_acc_impl_t *hdlp, uint32_t *host_addr,
180 	uint32_t *dev_addr, size_t repcount, uint_t flags);
181 static void pci_config_rep_rd64(ddi_acc_impl_t *hdlp, uint64_t *host_addr,
182 	uint64_t *dev_addr, size_t repcount, uint_t flags);
183 
184 static void pci_config_rep_wr8(ddi_acc_impl_t *hdlp, uint8_t *host_addr,
185 	uint8_t *dev_addr, size_t repcount, uint_t flags);
186 static void pci_config_rep_wr16(ddi_acc_impl_t *hdlp, uint16_t *host_addr,
187 	uint16_t *dev_addr, size_t repcount, uint_t flags);
188 static void pci_config_rep_wr32(ddi_acc_impl_t *hdlp, uint32_t *host_addr,
189 	uint32_t *dev_addr, size_t repcount, uint_t flags);
190 static void pci_config_rep_wr64(ddi_acc_impl_t *hdlp, uint64_t *host_addr,
191 	uint64_t *dev_addr, size_t repcount, uint_t flags);
192 
193 /*
194  * Module linkage information for the kernel.
195  */
196 
197 static struct modldrv modldrv = {
198 	&mod_driverops, /* Type of module */
199 	"host to PCI nexus driver %I%",
200 	&pci_ops,	/* driver ops */
201 };
202 
203 static struct modlinkage modlinkage = {
204 	MODREV_1,
205 	(void *)&modldrv,
206 	NULL
207 };
208 
209 int
210 _init(void)
211 {
212 	int e;
213 
214 	/*
215 	 * Initialize per-pci bus soft state pointer.
216 	 */
217 	e = ddi_soft_state_init(&pci_statep, sizeof (pci_state_t), 1);
218 	if (e != 0)
219 		return (e);
220 
221 	if ((e = mod_install(&modlinkage)) != 0)
222 		ddi_soft_state_fini(&pci_statep);
223 
224 	return (e);
225 }
226 
227 int
228 _fini(void)
229 {
230 	int rc;
231 
232 	rc = mod_remove(&modlinkage);
233 	if (rc != 0)
234 		return (rc);
235 
236 	ddi_soft_state_fini(&pci_statep);
237 
238 	return (rc);
239 }
240 
241 int
242 _info(struct modinfo *modinfop)
243 {
244 	return (mod_info(&modlinkage, modinfop));
245 }
246 
247 /*ARGSUSED*/
248 static int
249 pci_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
250 {
251 	/*
252 	 * Use the minor number as constructed by pcihp, as the index value to
253 	 * ddi_soft_state_zalloc.
254 	 */
255 	int instance = ddi_get_instance(devi);
256 	pci_state_t *pcip = NULL;
257 
258 	if (ddi_prop_update_string(DDI_DEV_T_NONE, devi, "device_type", "pci")
259 	    != DDI_PROP_SUCCESS) {
260 		cmn_err(CE_WARN, "pci:  'device_type' prop create failed");
261 	}
262 
263 	if (ddi_soft_state_zalloc(pci_statep, instance) == DDI_SUCCESS) {
264 		pcip = ddi_get_soft_state(pci_statep, instance);
265 	}
266 
267 	if (pcip == NULL) {
268 		goto bad_soft_state;
269 	}
270 
271 	pcip->pci_dip = devi;
272 
273 	/*
274 	 * Initialize hotplug support on this bus. At minimum
275 	 * (for non hotplug bus) this would create ":devctl" minor
276 	 * node to support DEVCTL_DEVICE_* and DEVCTL_BUS_* ioctls
277 	 * to this bus.
278 	 */
279 	if (pcihp_init(devi) != DDI_SUCCESS) {
280 		cmn_err(CE_WARN, "pci: Failed to setup hotplug framework");
281 		goto bad_pcihp_init;
282 	}
283 
284 	/* Second arg: initialize for pci, not pci_express */
285 	if (pcitool_init(devi, B_FALSE) != DDI_SUCCESS) {
286 		goto bad_pcitool_init;
287 	}
288 
289 	ddi_report_dev(devi);
290 
291 	return (DDI_SUCCESS);
292 
293 bad_pcitool_init:
294 	(void) pcihp_uninit(devi);
295 bad_pcihp_init:
296 	ddi_soft_state_free(pci_statep, instance);
297 bad_soft_state:
298 	return (DDI_FAILURE);
299 }
300 
301 /*ARGSUSED*/
302 static int
303 pci_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
304 {
305 	/* Uninitialize pcitool support. */
306 	pcitool_uninit(devi);
307 
308 	/* Uninitialize hotplug support on this bus. */
309 	(void) pcihp_uninit(devi);
310 
311 	ddi_soft_state_free(pci_statep, DIP_TO_MINOR(devi));
312 
313 	return (DDI_SUCCESS);
314 }
315 
316 static int
317 pci_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
318 	off_t offset, off_t len, caddr_t *vaddrp)
319 {
320 	struct regspec reg;
321 	ddi_map_req_t mr;
322 	ddi_acc_hdl_t *hp;
323 	ddi_acc_impl_t *ap;
324 	pci_regspec_t pci_reg;
325 	pci_regspec_t *pci_rp;
326 	int 	rnumber;
327 	int	length;
328 	pci_acc_cfblk_t *cfp;
329 	int	space;
330 
331 
332 	mr = *mp; /* Get private copy of request */
333 	mp = &mr;
334 
335 	/*
336 	 * check for register number
337 	 */
338 	switch (mp->map_type) {
339 	case DDI_MT_REGSPEC:
340 		pci_reg = *(pci_regspec_t *)(mp->map_obj.rp);
341 		pci_rp = &pci_reg;
342 		if (pci_common_get_reg_prop(rdip, pci_rp) != DDI_SUCCESS)
343 			return (DDI_FAILURE);
344 		break;
345 	case DDI_MT_RNUMBER:
346 		rnumber = mp->map_obj.rnumber;
347 		/*
348 		 * get ALL "reg" properties for dip, select the one of
349 		 * of interest. In x86, "assigned-addresses" property
350 		 * is identical to the "reg" property, so there is no
351 		 * need to cross check the two to determine the physical
352 		 * address of the registers.
353 		 * This routine still performs some validity checks to
354 		 * make sure that everything is okay.
355 		 */
356 		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip,
357 		    DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
358 		    (uint_t *)&length) != DDI_PROP_SUCCESS)
359 			return (DDI_FAILURE);
360 
361 		/*
362 		 * validate the register number.
363 		 */
364 		length /= (sizeof (pci_regspec_t) / sizeof (int));
365 		if (rnumber >= length) {
366 			ddi_prop_free(pci_rp);
367 			return (DDI_FAILURE);
368 		}
369 
370 		/*
371 		 * copy the required entry.
372 		 */
373 		pci_reg = pci_rp[rnumber];
374 
375 		/*
376 		 * free the memory allocated by ddi_prop_lookup_int_array
377 		 */
378 		ddi_prop_free(pci_rp);
379 
380 		pci_rp = &pci_reg;
381 		if (pci_common_get_reg_prop(rdip, pci_rp) != DDI_SUCCESS)
382 			return (DDI_FAILURE);
383 		mp->map_type = DDI_MT_REGSPEC;
384 		break;
385 	default:
386 		return (DDI_ME_INVAL);
387 	}
388 
389 	space = pci_rp->pci_phys_hi & PCI_REG_ADDR_M;
390 
391 	/*
392 	 * check for unmap and unlock of address space
393 	 */
394 	if ((mp->map_op == DDI_MO_UNMAP) || (mp->map_op == DDI_MO_UNLOCK)) {
395 		/*
396 		 * Adjust offset and length
397 		 * A non-zero length means override the one in the regspec.
398 		 */
399 		pci_rp->pci_phys_low += (uint_t)offset;
400 		if (len != 0)
401 			pci_rp->pci_size_low = len;
402 
403 		switch (space) {
404 		case PCI_ADDR_CONFIG:
405 			/* No work required on unmap of Config space */
406 			return (DDI_SUCCESS);
407 
408 		case PCI_ADDR_IO:
409 			reg.regspec_bustype = 1;
410 			break;
411 
412 		case PCI_ADDR_MEM64:
413 			/*
414 			 * MEM64 requires special treatment on map, to check
415 			 * that the device is below 4G.  On unmap, however,
416 			 * we can assume that everything is OK... the map
417 			 * must have succeeded.
418 			 */
419 			/* FALLTHROUGH */
420 		case PCI_ADDR_MEM32:
421 			reg.regspec_bustype = 0;
422 			break;
423 
424 		default:
425 			return (DDI_FAILURE);
426 		}
427 		reg.regspec_addr = pci_rp->pci_phys_low;
428 		reg.regspec_size = pci_rp->pci_size_low;
429 
430 		mp->map_obj.rp = &reg;
431 		return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp));
432 
433 	}
434 
435 	/* check for user mapping request - not legal for Config */
436 	if (mp->map_op == DDI_MO_MAP_HANDLE && space == PCI_ADDR_CONFIG) {
437 		return (DDI_FAILURE);
438 	}
439 
440 	/*
441 	 * check for config space
442 	 * On x86, CONFIG is not mapped via MMU and there is
443 	 * no endian-ness issues. Set the attr field in the handle to
444 	 * indicate that the common routines to call the nexus driver.
445 	 */
446 	if (space == PCI_ADDR_CONFIG) {
447 		hp = (ddi_acc_hdl_t *)mp->map_handlep;
448 
449 		/* Can't map config space without a handle */
450 		if (hp == NULL)
451 			return (DDI_FAILURE);
452 
453 		ap = (ddi_acc_impl_t *)hp->ah_platform_private;
454 
455 		/* endian-ness check */
456 		if (hp->ah_acc.devacc_attr_endian_flags == DDI_STRUCTURE_BE_ACC)
457 			return (DDI_FAILURE);
458 
459 		/*
460 		 * range check
461 		 */
462 		if ((offset >= 256) || (len > 256) || (offset + len > 256))
463 			return (DDI_FAILURE);
464 		*vaddrp = (caddr_t)offset;
465 
466 		ap->ahi_acc_attr |= DDI_ACCATTR_CONFIG_SPACE;
467 		ap->ahi_put8 = pci_config_wr8;
468 		ap->ahi_get8 = pci_config_rd8;
469 		ap->ahi_put64 = pci_config_wr64;
470 		ap->ahi_get64 = pci_config_rd64;
471 		ap->ahi_rep_put8 = pci_config_rep_wr8;
472 		ap->ahi_rep_get8 = pci_config_rep_rd8;
473 		ap->ahi_rep_put64 = pci_config_rep_wr64;
474 		ap->ahi_rep_get64 = pci_config_rep_rd64;
475 		ap->ahi_get16 = pci_config_rd16;
476 		ap->ahi_get32 = pci_config_rd32;
477 		ap->ahi_put16 = pci_config_wr16;
478 		ap->ahi_put32 = pci_config_wr32;
479 		ap->ahi_rep_get16 = pci_config_rep_rd16;
480 		ap->ahi_rep_get32 = pci_config_rep_rd32;
481 		ap->ahi_rep_put16 = pci_config_rep_wr16;
482 		ap->ahi_rep_put32 = pci_config_rep_wr32;
483 
484 		/* Initialize to default check/notify functions */
485 		ap->ahi_fault_check = i_ddi_acc_fault_check;
486 		ap->ahi_fault_notify = i_ddi_acc_fault_notify;
487 		ap->ahi_fault = 0;
488 		impl_acc_err_init(hp);
489 
490 		/* record the device address for future reference */
491 		cfp = (pci_acc_cfblk_t *)&hp->ah_bus_private;
492 		cfp->c_busnum = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
493 		cfp->c_devnum = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
494 		cfp->c_funcnum = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
495 
496 		return (DDI_SUCCESS);
497 	}
498 
499 	/*
500 	 * range check
501 	 */
502 	if ((offset >= pci_rp->pci_size_low) ||
503 	    (len > pci_rp->pci_size_low) ||
504 	    (offset + len > pci_rp->pci_size_low)) {
505 		return (DDI_FAILURE);
506 	}
507 
508 	/*
509 	 * Adjust offset and length
510 	 * A non-zero length means override the one in the regspec.
511 	 */
512 	pci_rp->pci_phys_low += (uint_t)offset;
513 	if (len != 0)
514 		pci_rp->pci_size_low = len;
515 
516 	/*
517 	 * convert the pci regsec into the generic regspec used by the
518 	 * parent root nexus driver.
519 	 */
520 	switch (space) {
521 	case PCI_ADDR_IO:
522 		reg.regspec_bustype = 1;
523 		break;
524 	case PCI_ADDR_MEM64:
525 		/*
526 		 * We can't handle 64-bit devices that are mapped above
527 		 * 4G or that are larger than 4G.
528 		 */
529 		if (pci_rp->pci_phys_mid != 0 ||
530 		    pci_rp->pci_size_hi != 0)
531 			return (DDI_FAILURE);
532 		/*
533 		 * Other than that, we can treat them as 32-bit mappings
534 		 */
535 		/* FALLTHROUGH */
536 	case PCI_ADDR_MEM32:
537 		reg.regspec_bustype = 0;
538 		break;
539 	default:
540 		return (DDI_FAILURE);
541 	}
542 	reg.regspec_addr = pci_rp->pci_phys_low;
543 	reg.regspec_size = pci_rp->pci_size_low;
544 
545 	mp->map_obj.rp = &reg;
546 	return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp));
547 }
548 
549 
550 /*ARGSUSED*/
551 static int
552 pci_ctlops(dev_info_t *dip, dev_info_t *rdip,
553 	ddi_ctl_enum_t ctlop, void *arg, void *result)
554 {
555 	pci_regspec_t *drv_regp;
556 	uint_t	reglen;
557 	int	rn;
558 	int	totreg;
559 
560 	switch (ctlop) {
561 	case DDI_CTLOPS_REPORTDEV:
562 		if (rdip == (dev_info_t *)0)
563 			return (DDI_FAILURE);
564 		cmn_err(CE_CONT, "?PCI-device: %s@%s, %s%d\n",
565 		    ddi_node_name(rdip), ddi_get_name_addr(rdip),
566 		    ddi_driver_name(rdip),
567 		    ddi_get_instance(rdip));
568 		return (DDI_SUCCESS);
569 
570 	case DDI_CTLOPS_INITCHILD:
571 		return (pci_initchild((dev_info_t *)arg));
572 
573 	case DDI_CTLOPS_UNINITCHILD:
574 		return (pci_removechild((dev_info_t *)arg));
575 
576 	case DDI_CTLOPS_SIDDEV:
577 		return (DDI_SUCCESS);
578 
579 	case DDI_CTLOPS_REGSIZE:
580 	case DDI_CTLOPS_NREGS:
581 		if (rdip == (dev_info_t *)0)
582 			return (DDI_FAILURE);
583 
584 		*(int *)result = 0;
585 		if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, rdip,
586 				DDI_PROP_DONTPASS, "reg", (int **)&drv_regp,
587 				&reglen) != DDI_PROP_SUCCESS) {
588 			return (DDI_FAILURE);
589 		}
590 
591 		totreg = (reglen * sizeof (int)) / sizeof (pci_regspec_t);
592 		if (ctlop == DDI_CTLOPS_NREGS)
593 			*(int *)result = totreg;
594 		else if (ctlop == DDI_CTLOPS_REGSIZE) {
595 			rn = *(int *)arg;
596 			if (rn >= totreg) {
597 				ddi_prop_free(drv_regp);
598 				return (DDI_FAILURE);
599 			}
600 			*(off_t *)result = drv_regp[rn].pci_size_low;
601 		}
602 		ddi_prop_free(drv_regp);
603 
604 		return (DDI_SUCCESS);
605 
606 	case DDI_CTLOPS_POWER: {
607 		power_req_t	*reqp = (power_req_t *)arg;
608 		/*
609 		 * We currently understand reporting of PCI_PM_IDLESPEED
610 		 * capability. Everything else is passed up.
611 		 */
612 		if ((reqp->request_type == PMR_REPORT_PMCAP) &&
613 		    (reqp->req.report_pmcap_req.cap ==  PCI_PM_IDLESPEED)) {
614 
615 			return (DDI_SUCCESS);
616 		}
617 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
618 	}
619 
620 	default:
621 		return (ddi_ctlops(dip, rdip, ctlop, arg, result));
622 	}
623 
624 	/* NOTREACHED */
625 
626 }
627 
628 /*
629  * pci_intr_ops
630  */
631 static int
632 pci_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op,
633     ddi_intr_handle_impl_t *hdlp, void *result)
634 {
635 	return (pci_common_intr_ops(pdip, rdip, intr_op, hdlp, result));
636 }
637 
638 
639 static int
640 pci_initchild(dev_info_t *child)
641 {
642 	char name[80];
643 	ddi_acc_handle_t config_handle;
644 	ushort_t command_preserve, command;
645 
646 	if (pci_common_name_child(child, name, 80) != DDI_SUCCESS) {
647 		return (DDI_FAILURE);
648 	}
649 	ddi_set_name_addr(child, name);
650 
651 	/*
652 	 * Pseudo nodes indicate a prototype node with per-instance
653 	 * properties to be merged into the real h/w device node.
654 	 * The interpretation of the unit-address is DD[,F]
655 	 * where DD is the device id and F is the function.
656 	 */
657 	if (ndi_dev_is_persistent_node(child) == 0) {
658 		extern int pci_allow_pseudo_children;
659 
660 		ddi_set_parent_data(child, NULL);
661 
662 		/*
663 		 * Try to merge the properties from this prototype
664 		 * node into real h/w nodes.
665 		 */
666 		if (ndi_merge_node(child, pci_common_name_child) ==
667 		    DDI_SUCCESS) {
668 			/*
669 			 * Merged ok - return failure to remove the node.
670 			 */
671 			ddi_set_name_addr(child, NULL);
672 			return (DDI_FAILURE);
673 		}
674 
675 		/* workaround for ddivs to run under PCI */
676 		if (pci_allow_pseudo_children) {
677 			/*
678 			 * If the "interrupts" property doesn't exist,
679 			 * this must be the ddivs no-intr case, and it returns
680 			 * DDI_SUCCESS instead of DDI_FAILURE.
681 			 */
682 			if (ddi_prop_get_int(DDI_DEV_T_ANY, child,
683 			    DDI_PROP_DONTPASS, "interrupts", -1) == -1)
684 				return (DDI_SUCCESS);
685 			/*
686 			 * Create the ddi_parent_private_data for a pseudo
687 			 * child.
688 			 */
689 			pci_common_set_parent_private_data(child);
690 			return (DDI_SUCCESS);
691 		}
692 
693 		/*
694 		 * The child was not merged into a h/w node,
695 		 * but there's not much we can do with it other
696 		 * than return failure to cause the node to be removed.
697 		 */
698 		cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
699 		    ddi_get_name(child), ddi_get_name_addr(child),
700 		    ddi_get_name(child));
701 		ddi_set_name_addr(child, NULL);
702 		return (DDI_NOT_WELL_FORMED);
703 	}
704 
705 	if (ddi_prop_get_int(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
706 	    "interrupts", -1) != -1)
707 		pci_common_set_parent_private_data(child);
708 	else
709 		ddi_set_parent_data(child, NULL);
710 
711 	/*
712 	 * initialize command register
713 	 */
714 	if (pci_config_setup(child, &config_handle) != DDI_SUCCESS)
715 		return (DDI_FAILURE);
716 
717 	/*
718 	 * Support for the "command-preserve" property.
719 	 */
720 	command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
721 						DDI_PROP_DONTPASS,
722 						"command-preserve", 0);
723 	command = pci_config_get16(config_handle, PCI_CONF_COMM);
724 	command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
725 	command |= (pci_command_default & ~command_preserve);
726 	pci_config_put16(config_handle, PCI_CONF_COMM, command);
727 
728 	pci_config_teardown(&config_handle);
729 	return (DDI_SUCCESS);
730 }
731 
732 static int
733 pci_removechild(dev_info_t *dip)
734 {
735 	struct ddi_parent_private_data *pdptr;
736 
737 	if ((pdptr = ddi_get_parent_data(dip)) != NULL) {
738 		kmem_free(pdptr, (sizeof (*pdptr) + sizeof (struct intrspec)));
739 		ddi_set_parent_data(dip, NULL);
740 	}
741 	ddi_set_name_addr(dip, NULL);
742 
743 	/*
744 	 * Strip the node to properly convert it back to prototype form
745 	 */
746 	ddi_remove_minor_node(dip, NULL);
747 
748 	impl_rem_dev_props(dip);
749 
750 	return (DDI_SUCCESS);
751 }
752 
753 
754 /*
755  * These are the get and put functions to be shared with drivers. The
756  * mutex locking is done inside the functions referenced, rather than
757  * here, and is thus shared across PCI child drivers and any other
758  * consumers of PCI config space (such as the ACPI subsystem).
759  *
760  * The configuration space addresses come in as pointers.  This is fine on
761  * a 32-bit system, where the VM space and configuration space are the same
762  * size.  It's not such a good idea on a 64-bit system, where memory
763  * addresses are twice as large as configuration space addresses.  At some
764  * point in the call tree we need to take a stand and say "you are 32-bit
765  * from this time forth", and this seems like a nice self-contained place.
766  */
767 
768 static uint8_t
769 pci_config_rd8(ddi_acc_impl_t *hdlp, uint8_t *addr)
770 {
771 	pci_acc_cfblk_t *cfp;
772 	uint8_t	rval;
773 	int reg;
774 
775 	ASSERT64(((uintptr_t)addr >> 32) == 0);
776 
777 	reg = (int)(uintptr_t)addr;
778 
779 	cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private;
780 
781 	rval = (*pci_getb_func)(cfp->c_busnum, cfp->c_devnum, cfp->c_funcnum,
782 	    reg);
783 
784 	return (rval);
785 }
786 
787 static void
788 pci_config_rep_rd8(ddi_acc_impl_t *hdlp, uint8_t *host_addr,
789 	uint8_t *dev_addr, size_t repcount, uint_t flags)
790 {
791 	uint8_t *h, *d;
792 
793 	h = host_addr;
794 	d = dev_addr;
795 
796 	if (flags == DDI_DEV_AUTOINCR)
797 		for (; repcount; repcount--)
798 			*h++ = pci_config_rd8(hdlp, d++);
799 	else
800 		for (; repcount; repcount--)
801 			*h++ = pci_config_rd8(hdlp, d);
802 }
803 
804 static uint16_t
805 pci_config_rd16(ddi_acc_impl_t *hdlp, uint16_t *addr)
806 {
807 	pci_acc_cfblk_t *cfp;
808 	uint16_t rval;
809 	int reg;
810 
811 	ASSERT64(((uintptr_t)addr >> 32) == 0);
812 
813 	reg = (int)(uintptr_t)addr;
814 
815 	cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private;
816 
817 	rval = (*pci_getw_func)(cfp->c_busnum, cfp->c_devnum, cfp->c_funcnum,
818 	    reg);
819 
820 	return (rval);
821 }
822 
823 static void
824 pci_config_rep_rd16(ddi_acc_impl_t *hdlp, uint16_t *host_addr,
825 	uint16_t *dev_addr, size_t repcount, uint_t flags)
826 {
827 	uint16_t *h, *d;
828 
829 	h = host_addr;
830 	d = dev_addr;
831 
832 	if (flags == DDI_DEV_AUTOINCR)
833 		for (; repcount; repcount--)
834 			*h++ = pci_config_rd16(hdlp, d++);
835 	else
836 		for (; repcount; repcount--)
837 			*h++ = pci_config_rd16(hdlp, d);
838 }
839 
840 static uint32_t
841 pci_config_rd32(ddi_acc_impl_t *hdlp, uint32_t *addr)
842 {
843 	pci_acc_cfblk_t *cfp;
844 	uint32_t rval;
845 	int reg;
846 
847 	ASSERT64(((uintptr_t)addr >> 32) == 0);
848 
849 	reg = (int)(uintptr_t)addr;
850 
851 	cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private;
852 
853 	rval = (*pci_getl_func)(cfp->c_busnum, cfp->c_devnum,
854 	    cfp->c_funcnum, reg);
855 
856 	return (rval);
857 }
858 
859 static void
860 pci_config_rep_rd32(ddi_acc_impl_t *hdlp, uint32_t *host_addr,
861 	uint32_t *dev_addr, size_t repcount, uint_t flags)
862 {
863 	uint32_t *h, *d;
864 
865 	h = host_addr;
866 	d = dev_addr;
867 
868 	if (flags == DDI_DEV_AUTOINCR)
869 		for (; repcount; repcount--)
870 			*h++ = pci_config_rd32(hdlp, d++);
871 	else
872 		for (; repcount; repcount--)
873 			*h++ = pci_config_rd32(hdlp, d);
874 }
875 
876 
877 static void
878 pci_config_wr8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value)
879 {
880 	pci_acc_cfblk_t *cfp;
881 	int reg;
882 
883 	ASSERT64(((uintptr_t)addr >> 32) == 0);
884 
885 	reg = (int)(uintptr_t)addr;
886 
887 	cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private;
888 
889 	(*pci_putb_func)(cfp->c_busnum, cfp->c_devnum,
890 	    cfp->c_funcnum, reg, value);
891 }
892 
893 static void
894 pci_config_rep_wr8(ddi_acc_impl_t *hdlp, uint8_t *host_addr,
895 	uint8_t *dev_addr, size_t repcount, uint_t flags)
896 {
897 	uint8_t *h, *d;
898 
899 	h = host_addr;
900 	d = dev_addr;
901 
902 	if (flags == DDI_DEV_AUTOINCR)
903 		for (; repcount; repcount--)
904 			pci_config_wr8(hdlp, d++, *h++);
905 	else
906 		for (; repcount; repcount--)
907 			pci_config_wr8(hdlp, d, *h++);
908 }
909 
910 static void
911 pci_config_wr16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value)
912 {
913 	pci_acc_cfblk_t *cfp;
914 	int reg;
915 
916 	ASSERT64(((uintptr_t)addr >> 32) == 0);
917 
918 	reg = (int)(uintptr_t)addr;
919 
920 	cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private;
921 
922 	(*pci_putw_func)(cfp->c_busnum, cfp->c_devnum,
923 	    cfp->c_funcnum, reg, value);
924 }
925 
926 static void
927 pci_config_rep_wr16(ddi_acc_impl_t *hdlp, uint16_t *host_addr,
928 	uint16_t *dev_addr, size_t repcount, uint_t flags)
929 {
930 	uint16_t *h, *d;
931 
932 	h = host_addr;
933 	d = dev_addr;
934 
935 	if (flags == DDI_DEV_AUTOINCR)
936 		for (; repcount; repcount--)
937 			pci_config_wr16(hdlp, d++, *h++);
938 	else
939 		for (; repcount; repcount--)
940 			pci_config_wr16(hdlp, d, *h++);
941 }
942 
943 static void
944 pci_config_wr32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value)
945 {
946 	pci_acc_cfblk_t *cfp;
947 	int reg;
948 
949 	ASSERT64(((uintptr_t)addr >> 32) == 0);
950 
951 	reg = (int)(uintptr_t)addr;
952 
953 	cfp = (pci_acc_cfblk_t *)&hdlp->ahi_common.ah_bus_private;
954 
955 	(*pci_putl_func)(cfp->c_busnum, cfp->c_devnum,
956 	    cfp->c_funcnum, reg, value);
957 }
958 
959 static void
960 pci_config_rep_wr32(ddi_acc_impl_t *hdlp, uint32_t *host_addr,
961 	uint32_t *dev_addr, size_t repcount, uint_t flags)
962 {
963 	uint32_t *h, *d;
964 
965 	h = host_addr;
966 	d = dev_addr;
967 
968 	if (flags == DDI_DEV_AUTOINCR)
969 		for (; repcount; repcount--)
970 			pci_config_wr32(hdlp, d++, *h++);
971 	else
972 		for (; repcount; repcount--)
973 			pci_config_wr32(hdlp, d, *h++);
974 }
975 
976 static uint64_t
977 pci_config_rd64(ddi_acc_impl_t *hdlp, uint64_t *addr)
978 {
979 	uint32_t lw_val;
980 	uint32_t hi_val;
981 	uint32_t *dp;
982 	uint64_t val;
983 
984 	dp = (uint32_t *)addr;
985 	lw_val = pci_config_rd32(hdlp, dp);
986 	dp++;
987 	hi_val = pci_config_rd32(hdlp, dp);
988 	val = ((uint64_t)hi_val << 32) | lw_val;
989 	return (val);
990 }
991 
992 static void
993 pci_config_wr64(ddi_acc_impl_t *hdlp, uint64_t *addr, uint64_t value)
994 {
995 	uint32_t lw_val;
996 	uint32_t hi_val;
997 	uint32_t *dp;
998 
999 	dp = (uint32_t *)addr;
1000 	lw_val = (uint32_t)(value & 0xffffffff);
1001 	hi_val = (uint32_t)(value >> 32);
1002 	pci_config_wr32(hdlp, dp, lw_val);
1003 	dp++;
1004 	pci_config_wr32(hdlp, dp, hi_val);
1005 }
1006 
1007 static void
1008 pci_config_rep_rd64(ddi_acc_impl_t *hdlp, uint64_t *host_addr,
1009 	uint64_t *dev_addr, size_t repcount, uint_t flags)
1010 {
1011 	if (flags == DDI_DEV_AUTOINCR) {
1012 		for (; repcount; repcount--)
1013 			*host_addr++ = pci_config_rd64(hdlp, dev_addr++);
1014 	} else {
1015 		for (; repcount; repcount--)
1016 			*host_addr++ = pci_config_rd64(hdlp, dev_addr);
1017 	}
1018 }
1019 
1020 static void
1021 pci_config_rep_wr64(ddi_acc_impl_t *hdlp, uint64_t *host_addr,
1022 	uint64_t *dev_addr, size_t repcount, uint_t flags)
1023 {
1024 	if (flags == DDI_DEV_AUTOINCR) {
1025 		for (; repcount; repcount--)
1026 			pci_config_wr64(hdlp, host_addr++, *dev_addr++);
1027 	} else {
1028 		for (; repcount; repcount--)
1029 			pci_config_wr64(hdlp, host_addr++, *dev_addr);
1030 	}
1031 }
1032 
1033 
1034 /*
1035  * When retrofitting this module for pci_tools, functions such as open, close,
1036  * and ioctl are now pulled into this module.  Before this, the functions in
1037  * the pcihp module were referenced directly.  Now they are called or
1038  * referenced through the pcihp cb_ops structure from functions in this module.
1039  */
1040 
1041 static int
1042 pci_open(dev_t *devp, int flags, int otyp, cred_t *credp)
1043 {
1044 	return ((pcihp_get_cb_ops())->cb_open(devp, flags, otyp, credp));
1045 }
1046 
1047 static int
1048 pci_close(dev_t dev, int flags, int otyp, cred_t *credp)
1049 {
1050 	return ((pcihp_get_cb_ops())->cb_close(dev, flags, otyp, credp));
1051 }
1052 
1053 static int
1054 pci_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, int *rvalp)
1055 {
1056 	minor_t		minor = getminor(dev);
1057 	int		instance = PCIHP_AP_MINOR_NUM_TO_INSTANCE(minor);
1058 	pci_state_t	*pci_p = ddi_get_soft_state(pci_statep, instance);
1059 
1060 	if (pci_p == NULL)
1061 		return (ENXIO);
1062 
1063 	return (pci_common_ioctl(pci_p->pci_dip,
1064 	    dev, cmd, arg, mode, credp, rvalp));
1065 }
1066 
1067 
1068 static int
1069 pci_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
1070 	int flags, char *name, caddr_t valuep, int *lengthp)
1071 {
1072 	return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip, prop_op, flags,
1073 	    name, valuep, lengthp));
1074 }
1075 
1076 static int
1077 pci_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
1078 {
1079 	return (pcihp_info(dip, cmd, arg, result));
1080 }
1081