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 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25 /*
26 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
27 */
28
29 /*
30 * Sun4u PCI to PCI bus bridge nexus driver
31 */
32
33 #include <sys/conf.h>
34 #include <sys/kmem.h>
35 #include <sys/debug.h>
36 #include <sys/modctl.h>
37 #include <sys/autoconf.h>
38 #include <sys/ddi_impldefs.h>
39 #include <sys/ddi_subrdefs.h>
40 #include <sys/pci_impl.h>
41 #include <sys/pcie_impl.h>
42 #include <sys/pci_cap.h>
43 #include <sys/pci/pci_nexus.h>
44 #include <sys/pci/pci_regs.h>
45 #include <sys/ddi.h>
46 #include <sys/sunndi.h>
47 #include <sys/sunddi.h>
48 #include <sys/fm/protocol.h>
49 #include <sys/ddifm.h>
50 #include <sys/pci/pci_pwr.h>
51 #include <sys/pci/pci_debug.h>
52 #include <sys/hotplug/pci/pcie_hp.h>
53 #include <sys/hotplug/pci/pcihp.h>
54 #include <sys/open.h>
55 #include <sys/stat.h>
56 #include <sys/file.h>
57
58 #define NUM_LOGICAL_SLOTS 32
59
60 #define PPB_RANGE_LEN 2
61
62 #define PPB_32BIT_IO 1
63 #define PPB_32bit_MEM 1
64
65 #define PPB_MEMGRAIN 0x100000
66 #define PPB_IOGRAIN 0x1000
67
68 #define PPB_16bit_IOADDR(addr) ((uint16_t)(((uint8_t)(addr) & 0xF0) << 8))
69 #define PPB_LADDR(lo, hi) (((uint16_t)(hi) << 16) | (uint16_t)(lo))
70 #define PPB_32bit_MEMADDR(addr) (PPB_LADDR(0, ((uint16_t)(addr) & 0xFFF0)))
71
72 typedef struct slot_table {
73 uchar_t bus_id[128];
74 uchar_t slot_name[32];
75 uint8_t device_no;
76 uint8_t phys_slot_num;
77 } slot_table_t;
78
79 /*
80 * The variable controls the default setting of the command register
81 * for pci devices. See ppb_initchild() for details.
82 */
83 static ushort_t ppb_command_default = PCI_COMM_SERR_ENABLE |
84 PCI_COMM_WAIT_CYC_ENAB |
85 PCI_COMM_PARITY_DETECT |
86 PCI_COMM_ME |
87 PCI_COMM_MAE |
88 PCI_COMM_IO;
89
90 static int ppb_bus_map(dev_info_t *, dev_info_t *, ddi_map_req_t *,
91 off_t, off_t, caddr_t *);
92 static int ppb_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t,
93 void *, void *);
94 static int ppb_intr_ops(dev_info_t *dip, dev_info_t *rdip,
95 ddi_intr_op_t intr_op, ddi_intr_handle_impl_t *hdlp, void *result);
96
97 /*
98 * fm_init busop to initialize our children
99 */
100 static int ppb_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap,
101 ddi_iblock_cookie_t *ibc);
102 static void ppb_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle);
103 static void ppb_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle);
104 static int ppb_bus_power(dev_info_t *dip, void *impl_arg, pm_bus_power_op_t op,
105 void *arg, void *result);
106
107 struct bus_ops ppb_bus_ops = {
108 BUSO_REV,
109 ppb_bus_map,
110 0,
111 0,
112 0,
113 i_ddi_map_fault,
114 0,
115 ddi_dma_allochdl,
116 ddi_dma_freehdl,
117 ddi_dma_bindhdl,
118 ddi_dma_unbindhdl,
119 ddi_dma_flush,
120 ddi_dma_win,
121 ddi_dma_mctl,
122 ppb_ctlops,
123 ddi_bus_prop_op,
124 ndi_busop_get_eventcookie, /* (*bus_get_eventcookie)(); */
125 ndi_busop_add_eventcall, /* (*bus_add_eventcall)(); */
126 ndi_busop_remove_eventcall, /* (*bus_remove_eventcall)(); */
127 ndi_post_event, /* (*bus_post_event)(); */
128 0, /* (*bus_intr_ctl)(); */
129 0, /* (*bus_config)(); */
130 0, /* (*bus_unconfig)(); */
131 ppb_fm_init_child, /* (*bus_fm_init)(); */
132 NULL, /* (*bus_fm_fini)(); */
133 ppb_bus_enter, /* (*bus_enter)() */
134 ppb_bus_exit, /* (*bus_exit)() */
135 ppb_bus_power, /* (*bus_power)() */
136 ppb_intr_ops, /* (*bus_intr_op)(); */
137 pcie_hp_common_ops /* (*bus_hp_op)(); */
138 };
139
140 static int ppb_open(dev_t *devp, int flags, int otyp, cred_t *credp);
141 static int ppb_close(dev_t dev, int flags, int otyp, cred_t *credp);
142 static int ppb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
143 cred_t *credp, int *rvalp);
144 static int ppb_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op,
145 int flags, char *name, caddr_t valuep, int *lengthp);
146
147 static struct cb_ops ppb_cb_ops = {
148 ppb_open, /* open */
149 ppb_close, /* close */
150 nulldev, /* strategy */
151 nulldev, /* print */
152 nulldev, /* dump */
153 nulldev, /* read */
154 nulldev, /* write */
155 ppb_ioctl, /* ioctl */
156 nodev, /* devmap */
157 nodev, /* mmap */
158 nodev, /* segmap */
159 nochpoll, /* poll */
160 ppb_prop_op, /* cb_prop_op */
161 NULL, /* streamtab */
162 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
163 CB_REV, /* rev */
164 nodev, /* int (*cb_aread)() */
165 nodev /* int (*cb_awrite)() */
166 };
167
168 static int ppb_probe(dev_info_t *);
169 static int ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);
170 static int ppb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
171 static int ppb_info(dev_info_t *dip, ddi_info_cmd_t cmd,
172 void *arg, void **result);
173 static int ppb_pwr(dev_info_t *dip, int component, int level);
174
175 struct dev_ops ppb_ops = {
176 DEVO_REV, /* devo_rev */
177 0, /* refcnt */
178 ppb_info, /* info */
179 nulldev, /* identify */
180 ppb_probe, /* probe */
181 ppb_attach, /* attach */
182 ppb_detach, /* detach */
183 nulldev, /* reset */
184 &ppb_cb_ops, /* driver operations */
185 &ppb_bus_ops, /* bus operations */
186 ppb_pwr, /* power */
187 ddi_quiesce_not_needed, /* quiesce */
188 };
189
190 /*
191 * Module linkage information for the kernel.
192 */
193
194 static struct modldrv modldrv = {
195 &mod_driverops, /* Type of module */
196 "Standard PCI to PCI bridge nexus driver",
197 &ppb_ops, /* driver ops */
198 };
199
200 static struct modlinkage modlinkage = {
201 MODREV_1,
202 (void *)&modldrv,
203 NULL
204 };
205
206 /*
207 * soft state pointer and structure template:
208 */
209 static void *ppb_state;
210
211 struct ppb_cfg_state {
212 dev_info_t *dip;
213 ushort_t command;
214 uchar_t cache_line_size;
215 uchar_t latency_timer;
216 uchar_t header_type;
217 uchar_t sec_latency_timer;
218 ushort_t bridge_control;
219 };
220
221 typedef struct {
222
223 dev_info_t *dip;
224
225 /*
226 * configuration register state for the bus:
227 */
228 uchar_t ppb_cache_line_size;
229 uchar_t ppb_latency_timer;
230
231 /*
232 * PM support
233 */
234 ddi_acc_handle_t ppb_conf_hdl;
235 uint16_t ppb_pm_cap_ptr;
236 pci_pwr_t *ppb_pwr_p;
237
238 /*
239 * HP support
240 */
241 boolean_t hotplug_capable;
242
243 kmutex_t ppb_mutex;
244 uint_t ppb_soft_state;
245 int fm_cap;
246 ddi_iblock_cookie_t fm_ibc;
247
248 uint16_t parent_bus;
249 } ppb_devstate_t;
250
251 /*
252 * The following variable enables a workaround for the following obp bug:
253 *
254 * 1234181 - obp should set latency timer registers in pci
255 * configuration header
256 *
257 * Until this bug gets fixed in the obp, the following workaround should
258 * be enabled.
259 */
260 static uint_t ppb_set_latency_timer_register = 1;
261
262 /*
263 * The following variable enables a workaround for an obp bug to be
264 * submitted. A bug requesting a workaround fof this problem has
265 * been filed:
266 *
267 * 1235094 - need workarounds on positron nexus drivers to set cache
268 * line size registers
269 *
270 * Until this bug gets fixed in the obp, the following workaround should
271 * be enabled.
272 */
273 static uint_t ppb_set_cache_line_size_register = 1;
274
275 /*
276 * forward function declarations:
277 */
278
279 /*
280 * FMA error callback
281 * Register error handling callback with our parent. We will just call
282 * our children's error callbacks and return their status.
283 */
284 static int ppb_err_callback(dev_info_t *dip, ddi_fm_error_t *derr,
285 const void *impl_data);
286
287 /*
288 * init/fini routines to alloc/dealloc fm structures and
289 * register/unregister our callback.
290 */
291 static void ppb_fm_init(ppb_devstate_t *ppb_p);
292 static void ppb_fm_fini(ppb_devstate_t *ppb_p);
293
294 static void ppb_removechild(dev_info_t *);
295 static int ppb_initchild(dev_info_t *child);
296 static void ppb_uninitchild(dev_info_t *child);
297 static dev_info_t *get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip);
298 static void ppb_pwr_setup(ppb_devstate_t *ppb, dev_info_t *dip);
299 static void ppb_pwr_teardown(ppb_devstate_t *ppb, dev_info_t *dip);
300 static void ppb_init_hotplug(ppb_devstate_t *ppb);
301 static void ppb_create_ranges_prop(dev_info_t *, ddi_acc_handle_t);
302 uint64_t pci_debug_flags = 0;
303
304 int
_init(void)305 _init(void)
306 {
307 int e;
308 if ((e = ddi_soft_state_init(&ppb_state, sizeof (ppb_devstate_t),
309 1)) == 0 && (e = mod_install(&modlinkage)) != 0)
310 ddi_soft_state_fini(&ppb_state);
311 return (e);
312 }
313
314 int
_fini(void)315 _fini(void)
316 {
317 int e;
318
319 if ((e = mod_remove(&modlinkage)) == 0)
320 ddi_soft_state_fini(&ppb_state);
321 return (e);
322 }
323
324 int
_info(struct modinfo * modinfop)325 _info(struct modinfo *modinfop)
326 {
327 return (mod_info(&modlinkage, modinfop));
328 }
329
330 /*ARGSUSED*/
331 static int
ppb_info(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)332 ppb_info(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
333 {
334 minor_t minor = getminor((dev_t)arg);
335 int instance = PCI_MINOR_NUM_TO_INSTANCE(minor);
336 ppb_devstate_t *ppb_p = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
337 instance);
338
339
340 if (ppb_p->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
341 return (pcihp_info(dip, cmd, arg, result));
342
343 switch (cmd) {
344 default:
345 return (DDI_FAILURE);
346
347 case DDI_INFO_DEVT2INSTANCE:
348 *result = (void *)(uintptr_t)instance;
349 return (DDI_SUCCESS);
350
351 case DDI_INFO_DEVT2DEVINFO:
352 if (ppb_p == NULL)
353 return (DDI_FAILURE);
354 *result = (void *)ppb_p->dip;
355 return (DDI_SUCCESS);
356 }
357 }
358
359 /*ARGSUSED*/
360 static int
ppb_probe(register dev_info_t * devi)361 ppb_probe(register dev_info_t *devi)
362 {
363 return (DDI_PROBE_SUCCESS);
364 }
365
366 /*ARGSUSED*/
367 static int
ppb_attach(dev_info_t * devi,ddi_attach_cmd_t cmd)368 ppb_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
369 {
370 dev_info_t *root = ddi_root_node();
371 int instance;
372 ppb_devstate_t *ppb;
373 dev_info_t *pdip;
374 ddi_acc_handle_t config_handle;
375 char *bus;
376
377 switch (cmd) {
378 case DDI_ATTACH:
379
380 /*
381 * Make sure the "device_type" property exists.
382 */
383 (void) ddi_prop_update_string(DDI_DEV_T_NONE, devi,
384 "device_type", "pci");
385
386 /*
387 * Allocate and get soft state structure.
388 */
389 instance = ddi_get_instance(devi);
390 if (ddi_soft_state_zalloc(ppb_state, instance) != DDI_SUCCESS)
391 return (DDI_FAILURE);
392 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state, instance);
393 ppb->dip = devi;
394 mutex_init(&ppb->ppb_mutex, NULL, MUTEX_DRIVER, NULL);
395 ppb->ppb_soft_state = PCI_SOFT_STATE_CLOSED;
396 if (pci_config_setup(devi, &config_handle) != DDI_SUCCESS) {
397 mutex_destroy(&ppb->ppb_mutex);
398 ddi_soft_state_free(ppb_state, instance);
399 return (DDI_FAILURE);
400 }
401 ppb_pwr_setup(ppb, devi);
402
403 if (PM_CAPABLE(ppb->ppb_pwr_p)) {
404 mutex_enter(&ppb->ppb_pwr_p->pwr_mutex);
405
406 /*
407 * Before reading config registers, make sure power is
408 * on, and remains on.
409 */
410 ppb->ppb_pwr_p->pwr_fp++;
411
412 pci_pwr_change(ppb->ppb_pwr_p,
413 ppb->ppb_pwr_p->current_lvl,
414 pci_pwr_new_lvl(ppb->ppb_pwr_p));
415 }
416
417 ppb->ppb_cache_line_size =
418 pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
419 ppb->ppb_latency_timer =
420 pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
421
422 /*
423 * Check whether the "ranges" property is present.
424 * Otherwise create the ranges property by reading
425 * the configuration registers
426 */
427 if (ddi_prop_exists(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
428 "ranges") == 0) {
429 ppb_create_ranges_prop(devi, config_handle);
430 }
431
432 pci_config_teardown(&config_handle);
433
434 if (PM_CAPABLE(ppb->ppb_pwr_p)) {
435 ppb->ppb_pwr_p->pwr_fp--;
436
437 pci_pwr_change(ppb->ppb_pwr_p,
438 ppb->ppb_pwr_p->current_lvl,
439 pci_pwr_new_lvl(ppb->ppb_pwr_p));
440
441 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
442 }
443
444 ppb->parent_bus = PCIE_PCIECAP_DEV_TYPE_PCI_PSEUDO;
445 for (pdip = ddi_get_parent(ppb->dip); pdip && (pdip != root) &&
446 (ppb->parent_bus != PCIE_PCIECAP_DEV_TYPE_PCIE_DEV);
447 pdip = ddi_get_parent(pdip)) {
448 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
449 DDI_PROP_DONTPASS, "device_type", &bus) !=
450 DDI_PROP_SUCCESS)
451 break;
452
453 if (strcmp(bus, "pciex") == 0)
454 ppb->parent_bus =
455 PCIE_PCIECAP_DEV_TYPE_PCIE_DEV;
456
457 ddi_prop_free(bus);
458 }
459
460 /*
461 * Initialize hotplug support on this bus.
462 */
463 if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
464 if (pcie_init(devi, NULL) != DDI_SUCCESS) {
465 (void) ppb_detach(devi, DDI_DETACH);
466 return (DDI_FAILURE);
467 }
468 else
469 ppb_init_hotplug(ppb);
470
471 DEBUG1(DBG_ATTACH, devi,
472 "ppb_attach(): this nexus %s hotplug slots\n",
473 ppb->hotplug_capable == B_TRUE ? "has":"has no");
474
475 ppb_fm_init(ppb);
476 ddi_report_dev(devi);
477
478 return (DDI_SUCCESS);
479
480 case DDI_RESUME:
481 /*
482 * Get the soft state structure for the bridge.
483 */
484 ppb = (ppb_devstate_t *)
485 ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
486
487 pci_pwr_resume(devi, ppb->ppb_pwr_p);
488
489 return (DDI_SUCCESS);
490 }
491 return (DDI_FAILURE);
492 }
493
494 /*ARGSUSED*/
495 static int
ppb_detach(dev_info_t * devi,ddi_detach_cmd_t cmd)496 ppb_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
497 {
498 ppb_devstate_t *ppb;
499 int ret = DDI_SUCCESS;
500
501 switch (cmd) {
502 case DDI_DETACH:
503 /*
504 * And finally free the per-pci soft state after
505 * uninitializing hotplug support for this bus.
506 */
507 ppb = (ppb_devstate_t *)
508 ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
509
510 ppb_fm_fini(ppb);
511
512 if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
513 ret = pcie_uninit(devi);
514 else if (ppb->hotplug_capable == B_TRUE)
515 ret = pcihp_init(devi);
516 else
517 ddi_remove_minor_node(devi, "devctl");
518
519 if (ret != DDI_SUCCESS)
520 return (DDI_FAILURE);
521
522 (void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "device_type");
523
524 if (ppb->ppb_pwr_p != NULL) {
525 ppb_pwr_teardown(ppb, devi);
526 }
527 mutex_destroy(&ppb->ppb_mutex);
528 ddi_soft_state_free(ppb_state, ddi_get_instance(devi));
529
530 return (DDI_SUCCESS);
531
532 case DDI_SUSPEND:
533 ppb = (ppb_devstate_t *)
534 ddi_get_soft_state(ppb_state, ddi_get_instance(devi));
535
536 pci_pwr_suspend(devi, ppb->ppb_pwr_p);
537
538 return (DDI_SUCCESS);
539 }
540 return (DDI_FAILURE);
541 }
542
543 /*ARGSUSED*/
544 static int
ppb_bus_map(dev_info_t * dip,dev_info_t * rdip,ddi_map_req_t * mp,off_t offset,off_t len,caddr_t * vaddrp)545 ppb_bus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
546 off_t offset, off_t len, caddr_t *vaddrp)
547 {
548 register dev_info_t *pdip;
549
550 pdip = (dev_info_t *)DEVI(dip)->devi_parent;
551 return ((DEVI(pdip)->devi_ops->devo_bus_ops->bus_map)
552 (pdip, rdip, mp, offset, len, vaddrp));
553 }
554
555 /*ARGSUSED*/
556 static int
ppb_ctlops(dev_info_t * dip,dev_info_t * rdip,ddi_ctl_enum_t ctlop,void * arg,void * result)557 ppb_ctlops(dev_info_t *dip, dev_info_t *rdip,
558 ddi_ctl_enum_t ctlop, void *arg, void *result)
559 {
560 pci_regspec_t *drv_regp;
561 int reglen;
562 int rn;
563 struct attachspec *as;
564 struct detachspec *ds;
565 int totreg;
566 ppb_devstate_t *ppb_p;
567
568 ppb_p = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
569 ddi_get_instance(dip));
570
571 switch (ctlop) {
572 case DDI_CTLOPS_REPORTDEV:
573 if (rdip == (dev_info_t *)0)
574 return (DDI_FAILURE);
575 cmn_err(CE_CONT, "?PCI-device: %s@%s, %s%d\n",
576 ddi_node_name(rdip), ddi_get_name_addr(rdip),
577 ddi_driver_name(rdip),
578 ddi_get_instance(rdip));
579 return (DDI_SUCCESS);
580
581 case DDI_CTLOPS_INITCHILD:
582 return (ppb_initchild((dev_info_t *)arg));
583
584 case DDI_CTLOPS_UNINITCHILD:
585 ppb_uninitchild((dev_info_t *)arg);
586 return (DDI_SUCCESS);
587
588 case DDI_CTLOPS_ATTACH:
589 if (!pcie_is_child(dip, rdip))
590 return (DDI_SUCCESS);
591
592 as = (struct attachspec *)arg;
593 if ((ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) &&
594 (as->when == DDI_POST) && (as->result == DDI_SUCCESS))
595 pf_init(rdip, ppb_p->fm_ibc, as->cmd);
596
597 return (DDI_SUCCESS);
598
599 case DDI_CTLOPS_DETACH:
600 if (!pcie_is_child(dip, rdip))
601 return (DDI_SUCCESS);
602
603 ds = (struct detachspec *)arg;
604 if ((ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) &&
605 (ds->when == DDI_PRE))
606 pf_fini(rdip, ds->cmd);
607
608 return (DDI_SUCCESS);
609
610 case DDI_CTLOPS_SIDDEV:
611 return (DDI_SUCCESS);
612
613 case DDI_CTLOPS_REGSIZE:
614 case DDI_CTLOPS_NREGS:
615 if (rdip == (dev_info_t *)0)
616 return (DDI_FAILURE);
617 break;
618 default:
619 return (ddi_ctlops(dip, rdip, ctlop, arg, result));
620 }
621
622 *(int *)result = 0;
623 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip,
624 DDI_PROP_DONTPASS | DDI_PROP_CANSLEEP, "reg",
625 (caddr_t)&drv_regp, ®len) != DDI_SUCCESS)
626 return (DDI_FAILURE);
627
628 totreg = reglen / sizeof (pci_regspec_t);
629 if (ctlop == DDI_CTLOPS_NREGS)
630 *(int *)result = totreg;
631 else if (ctlop == DDI_CTLOPS_REGSIZE) {
632 rn = *(int *)arg;
633 if (rn >= totreg) {
634 kmem_free(drv_regp, reglen);
635 return (DDI_FAILURE);
636 }
637 *(off_t *)result = drv_regp[rn].pci_size_low |
638 ((uint64_t)drv_regp[rn].pci_size_hi << 32);
639 }
640
641 kmem_free(drv_regp, reglen);
642 return (DDI_SUCCESS);
643 }
644
645
646 static dev_info_t *
get_my_childs_dip(dev_info_t * dip,dev_info_t * rdip)647 get_my_childs_dip(dev_info_t *dip, dev_info_t *rdip)
648 {
649 dev_info_t *cdip = rdip;
650
651 for (; ddi_get_parent(cdip) != dip; cdip = ddi_get_parent(cdip))
652 ;
653
654 return (cdip);
655 }
656
657
658 static int
ppb_intr_ops(dev_info_t * dip,dev_info_t * rdip,ddi_intr_op_t intr_op,ddi_intr_handle_impl_t * hdlp,void * result)659 ppb_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
660 ddi_intr_handle_impl_t *hdlp, void *result)
661 {
662 dev_info_t *cdip = rdip;
663 pci_regspec_t *pci_rp;
664 int reglen, len;
665 uint32_t d, intr;
666
667 if ((intr_op == DDI_INTROP_SUPPORTED_TYPES) ||
668 (hdlp->ih_type != DDI_INTR_TYPE_FIXED))
669 goto done;
670
671 /*
672 * If the interrupt-map property is defined at this
673 * node, it will have performed the interrupt
674 * translation as part of the property, so no
675 * rotation needs to be done.
676 */
677 if (ddi_getproplen(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
678 "interrupt-map", &len) == DDI_PROP_SUCCESS)
679 goto done;
680
681 cdip = get_my_childs_dip(dip, rdip);
682
683 /*
684 * Use the devices reg property to determine its
685 * PCI bus number and device number.
686 */
687 if (ddi_getlongprop(DDI_DEV_T_ANY, cdip, DDI_PROP_DONTPASS,
688 "reg", (caddr_t)&pci_rp, ®len) != DDI_SUCCESS)
689 return (DDI_FAILURE);
690
691 intr = hdlp->ih_vector;
692
693 /* Spin the interrupt */
694 d = PCI_REG_DEV_G(pci_rp[0].pci_phys_hi);
695
696 if ((intr >= PCI_INTA) && (intr <= PCI_INTD))
697 hdlp->ih_vector = ((intr - 1 + (d % 4)) % 4 + 1);
698 else
699 cmn_err(CE_WARN, "%s%d: %s: PCI intr=%x out of range",
700 ddi_driver_name(rdip), ddi_get_instance(rdip),
701 ddi_driver_name(dip), intr);
702
703 kmem_free(pci_rp, reglen);
704
705 done:
706 /* Pass up the request to our parent. */
707 return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result));
708 }
709
710 static int
ppb_bus_power(dev_info_t * dip,void * impl_arg,pm_bus_power_op_t op,void * arg,void * result)711 ppb_bus_power(dev_info_t *dip, void *impl_arg, pm_bus_power_op_t op,
712 void *arg, void *result)
713 {
714 ppb_devstate_t *ppb;
715
716 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
717 ddi_get_instance(dip));
718
719 return (pci_pwr_ops(ppb->ppb_pwr_p, dip, impl_arg, op, arg, result));
720 }
721
722
723 /*
724 * name_child
725 *
726 * This function is called from init_child to name a node. It is
727 * also passed as a callback for node merging functions.
728 *
729 * return value: DDI_SUCCESS, DDI_FAILURE
730 */
731 static int
ppb_name_child(dev_info_t * child,char * name,int namelen)732 ppb_name_child(dev_info_t *child, char *name, int namelen)
733 {
734 pci_regspec_t *pci_rp;
735 uint_t slot, func;
736 char **unit_addr;
737 uint_t n;
738
739 /*
740 * Pseudo nodes indicate a prototype node with per-instance
741 * properties to be merged into the real h/w device node.
742 * The interpretation of the unit-address is DD[,F]
743 * where DD is the device id and F is the function.
744 */
745 if (ndi_dev_is_persistent_node(child) == 0) {
746 if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, child,
747 DDI_PROP_DONTPASS, "unit-address", &unit_addr, &n) !=
748 DDI_PROP_SUCCESS) {
749 cmn_err(CE_WARN, "cannot name node from %s.conf",
750 ddi_driver_name(child));
751 return (DDI_FAILURE);
752 }
753 if (n != 1 || *unit_addr == NULL || **unit_addr == 0) {
754 cmn_err(CE_WARN, "unit-address property in %s.conf"
755 " not well-formed", ddi_driver_name(child));
756 ddi_prop_free(unit_addr);
757 return (DDI_FAILURE);
758 }
759 (void) snprintf(name, namelen, "%s", *unit_addr);
760 ddi_prop_free(unit_addr);
761 return (DDI_SUCCESS);
762 }
763
764 /*
765 * Get the address portion of the node name based on
766 * the function and device number.
767 */
768 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
769 "reg", (int **)&pci_rp, &n) != DDI_SUCCESS) {
770 return (DDI_FAILURE);
771 }
772
773 slot = PCI_REG_DEV_G(pci_rp[0].pci_phys_hi);
774 func = PCI_REG_FUNC_G(pci_rp[0].pci_phys_hi);
775
776 if (func != 0)
777 (void) snprintf(name, namelen, "%x,%x", slot, func);
778 else
779 (void) snprintf(name, namelen, "%x", slot);
780
781 ddi_prop_free(pci_rp);
782 return (DDI_SUCCESS);
783 }
784
785 static int
ppb_initchild(dev_info_t * child)786 ppb_initchild(dev_info_t *child)
787 {
788 char name[MAXNAMELEN];
789 ddi_acc_handle_t config_handle;
790 ushort_t command_preserve, command;
791 uint_t n;
792 ushort_t bcr;
793 uchar_t header_type;
794 uchar_t min_gnt, latency_timer;
795 ppb_devstate_t *ppb;
796
797 /*
798 * Name the child
799 */
800 if (ppb_name_child(child, name, MAXNAMELEN) != DDI_SUCCESS)
801 return (DDI_FAILURE);
802
803 ddi_set_name_addr(child, name);
804 ddi_set_parent_data(child, NULL);
805
806 /*
807 * Pseudo nodes indicate a prototype node with per-instance
808 * properties to be merged into the real h/w device node.
809 * The interpretation of the unit-address is DD[,F]
810 * where DD is the device id and F is the function.
811 */
812 if (ndi_dev_is_persistent_node(child) == 0) {
813 extern int pci_allow_pseudo_children;
814
815 /*
816 * Try to merge the properties from this prototype
817 * node into real h/w nodes.
818 */
819 if (ndi_merge_node(child, ppb_name_child) == DDI_SUCCESS) {
820 /*
821 * Merged ok - return failure to remove the node.
822 */
823 ppb_removechild(child);
824 return (DDI_FAILURE);
825 }
826
827 /* workaround for ddivs to run under PCI */
828 if (pci_allow_pseudo_children)
829 return (DDI_SUCCESS);
830
831 /*
832 * The child was not merged into a h/w node,
833 * but there's not much we can do with it other
834 * than return failure to cause the node to be removed.
835 */
836 cmn_err(CE_WARN, "!%s@%s: %s.conf properties not merged",
837 ddi_driver_name(child), ddi_get_name_addr(child),
838 ddi_driver_name(child));
839 ppb_removechild(child);
840 return (DDI_NOT_WELL_FORMED);
841 }
842
843 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
844 ddi_get_instance(ddi_get_parent(child)));
845
846 ddi_set_parent_data(child, NULL);
847
848 /*
849 * If hardware is PM capable, set up the power info structure.
850 * This also ensures the the bus will not be off (0MHz) otherwise
851 * system panics during a bus access.
852 */
853 if (PM_CAPABLE(ppb->ppb_pwr_p)) {
854 /*
855 * Create a pwr_info struct for child. Bus will be
856 * at full speed after creating info.
857 */
858 pci_pwr_create_info(ppb->ppb_pwr_p, child);
859 #ifdef DEBUG
860 ASSERT(ppb->ppb_pwr_p->current_lvl == PM_LEVEL_B0);
861 #endif
862 }
863
864 /*
865 * If configuration registers were previously saved by
866 * child (before it entered D3), then let the child do the
867 * restore to set up the config regs as it'll first need to
868 * power the device out of D3.
869 */
870 if (ddi_prop_exists(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
871 "config-regs-saved-by-child") == 1) {
872 DEBUG2(DBG_PWR, ddi_get_parent(child),
873 "INITCHILD: config regs to be restored by child"
874 " for %s@%s\n", ddi_node_name(child),
875 ddi_get_name_addr(child));
876
877 return (DDI_SUCCESS);
878 }
879
880 DEBUG2(DBG_PWR, ddi_get_parent(child),
881 "INITCHILD: config regs setup for %s@%s\n",
882 ddi_node_name(child), ddi_get_name_addr(child));
883
884 if (pci_config_setup(child, &config_handle) != DDI_SUCCESS) {
885 if (PM_CAPABLE(ppb->ppb_pwr_p)) {
886 pci_pwr_rm_info(ppb->ppb_pwr_p, child);
887 }
888
889 return (DDI_FAILURE);
890 }
891
892 /*
893 * Determine the configuration header type.
894 */
895 header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
896
897 /*
898 * Support for the "command-preserve" property.
899 */
900 command_preserve = ddi_prop_get_int(DDI_DEV_T_ANY, child,
901 DDI_PROP_DONTPASS, "command-preserve", 0);
902 command = pci_config_get16(config_handle, PCI_CONF_COMM);
903 command &= (command_preserve | PCI_COMM_BACK2BACK_ENAB);
904 command |= (ppb_command_default & ~command_preserve);
905 pci_config_put16(config_handle, PCI_CONF_COMM, command);
906
907 /*
908 * If the device has a bus control register then program it
909 * based on the settings in the command register.
910 */
911 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
912 bcr = pci_config_get8(config_handle, PCI_BCNF_BCNTRL);
913 if (ppb_command_default & PCI_COMM_PARITY_DETECT)
914 bcr |= PCI_BCNF_BCNTRL_PARITY_ENABLE;
915 if (ppb_command_default & PCI_COMM_SERR_ENABLE)
916 bcr |= PCI_BCNF_BCNTRL_SERR_ENABLE;
917 bcr |= PCI_BCNF_BCNTRL_MAST_AB_MODE;
918 pci_config_put8(config_handle, PCI_BCNF_BCNTRL, bcr);
919 }
920
921 /*
922 * Initialize cache-line-size configuration register if needed.
923 */
924 if (ppb_set_cache_line_size_register &&
925 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
926 "cache-line-size", 0) == 0) {
927 pci_config_put8(config_handle, PCI_CONF_CACHE_LINESZ,
928 ppb->ppb_cache_line_size);
929 n = pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ);
930 if (n != 0) {
931 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
932 "cache-line-size", n);
933 }
934 }
935
936 /*
937 * Initialize latency timer configuration registers if needed.
938 */
939 if (ppb_set_latency_timer_register &&
940 ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
941 "latency-timer", 0) == 0) {
942
943 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_ONE) {
944 latency_timer = ppb->ppb_latency_timer;
945 pci_config_put8(config_handle, PCI_BCNF_LATENCY_TIMER,
946 ppb->ppb_latency_timer);
947 } else {
948 min_gnt = pci_config_get8(config_handle,
949 PCI_CONF_MIN_G);
950 latency_timer = min_gnt * 8;
951 }
952 pci_config_put8(config_handle, PCI_CONF_LATENCY_TIMER,
953 latency_timer);
954 n = pci_config_get8(config_handle, PCI_CONF_LATENCY_TIMER);
955 if (n != 0) {
956 (void) ndi_prop_update_int(DDI_DEV_T_NONE, child,
957 "latency-timer", n);
958 }
959 }
960
961 /*
962 * SPARC PCIe FMA specific
963 *
964 * Note: parent_data for parent is created only if this is sparc PCI-E
965 * platform, for which, SG take a different route to handle device
966 * errors.
967 */
968 if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
969 if (pcie_init_cfghdl(child) != DDI_SUCCESS) {
970 pci_config_teardown(&config_handle);
971 return (DDI_FAILURE);
972 }
973 pcie_init_dom(child);
974 }
975
976 /*
977 * Check to see if the XMITS/PCI-X workaround applies.
978 */
979 n = ddi_getprop(DDI_DEV_T_ANY, child, DDI_PROP_NOTPROM,
980 "pcix-update-cmd-reg", -1);
981
982 if (n != -1) {
983 extern void pcix_set_cmd_reg(dev_info_t *child, uint16_t value);
984 DEBUG1(DBG_INIT_CLD, child, "Turning on XMITS NCPQ "
985 "Workaround: value = %x\n", n);
986 pcix_set_cmd_reg(child, n);
987 }
988 pci_config_teardown(&config_handle);
989 return (DDI_SUCCESS);
990 }
991
992 static void
ppb_uninitchild(dev_info_t * child)993 ppb_uninitchild(dev_info_t *child)
994 {
995 ppb_devstate_t *ppb;
996
997 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
998 ddi_get_instance(ddi_get_parent(child)));
999
1000 /*
1001 * SG OPL FMA specific
1002 */
1003 if (ppb->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
1004 pcie_fini_dom(child);
1005 pcie_fini_cfghdl(child);
1006 }
1007
1008 ppb_removechild(child);
1009 }
1010
1011 static void
ppb_removechild(dev_info_t * dip)1012 ppb_removechild(dev_info_t *dip)
1013 {
1014 ppb_devstate_t *ppb;
1015
1016 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
1017 ddi_get_instance(ddi_get_parent(dip)));
1018
1019 if (PM_CAPABLE(ppb->ppb_pwr_p)) {
1020
1021 DEBUG2(DBG_PWR, ddi_get_parent(dip),
1022 "UNINITCHILD: removing pwr_info for %s@%s\n",
1023 ddi_node_name(dip), ddi_get_name_addr(dip));
1024 pci_pwr_rm_info(ppb->ppb_pwr_p, dip);
1025 }
1026
1027 ddi_set_name_addr(dip, NULL);
1028
1029 /*
1030 * Strip the node to properly convert it back to prototype form
1031 */
1032 ddi_remove_minor_node(dip, NULL);
1033
1034 impl_rem_dev_props(dip);
1035 }
1036
1037 /*
1038 * If bridge is PM capable, set up PM state for nexus.
1039 */
1040 static void
ppb_pwr_setup(ppb_devstate_t * ppb,dev_info_t * pdip)1041 ppb_pwr_setup(ppb_devstate_t *ppb, dev_info_t *pdip)
1042 {
1043 char *comp_array[5];
1044 int i;
1045 ddi_acc_handle_t conf_hdl;
1046 uint8_t pmcsr_bse;
1047 uint16_t pmcap;
1048
1049 /*
1050 * Determine if bridge is PM capable. If not, leave ppb_pwr_p NULL
1051 * and return.
1052 */
1053 if (pci_config_setup(pdip, &ppb->ppb_conf_hdl) != DDI_SUCCESS) {
1054
1055 return;
1056 }
1057
1058 conf_hdl = ppb->ppb_conf_hdl;
1059
1060 /*
1061 * Locate and store the power management cap_ptr for future references.
1062 */
1063 if ((PCI_CAP_LOCATE(conf_hdl, PCI_CAP_ID_PM, &ppb->ppb_pm_cap_ptr))
1064 == DDI_FAILURE) {
1065 DEBUG0(DBG_PWR, pdip, "bridge does not support PM. PCI"
1066 " PM data structure not found in config header\n");
1067 pci_config_teardown(&conf_hdl);
1068
1069 return;
1070 }
1071
1072 /*
1073 * Allocate PM state structure for ppb.
1074 */
1075 ppb->ppb_pwr_p = (pci_pwr_t *)
1076 kmem_zalloc(sizeof (pci_pwr_t), KM_SLEEP);
1077 ppb->ppb_pwr_p->pwr_fp = 0;
1078
1079 pmcsr_bse = PCI_CAP_GET8(conf_hdl, 0, ppb->ppb_pm_cap_ptr,
1080 PCI_PMCSR_BSE);
1081
1082 pmcap = PCI_CAP_GET16(conf_hdl, 0, ppb->ppb_pm_cap_ptr,
1083 PCI_PMCAP);
1084
1085 if (pmcap == PCI_CAP_EINVAL16 || pmcsr_bse == PCI_CAP_EINVAL8) {
1086 pci_config_teardown(&conf_hdl);
1087 return;
1088 }
1089
1090 if (pmcap & PCI_PMCAP_D1) {
1091 DEBUG0(DBG_PWR, pdip, "setup: B1 state supported\n");
1092 ppb->ppb_pwr_p->pwr_flags |= PCI_PWR_B1_CAPABLE;
1093 } else {
1094 DEBUG0(DBG_PWR, pdip, "setup: B1 state NOT supported\n");
1095 }
1096 if (pmcap & PCI_PMCAP_D2) {
1097 DEBUG0(DBG_PWR, pdip, "setup: B2 state supported\n");
1098 ppb->ppb_pwr_p->pwr_flags |= PCI_PWR_B2_CAPABLE;
1099 } else {
1100 DEBUG0(DBG_PWR, pdip, "setup: B2 via D2 NOT supported\n");
1101 }
1102
1103 if (pmcsr_bse & PCI_PMCSR_BSE_BPCC_EN) {
1104 DEBUG0(DBG_PWR, pdip,
1105 "setup: bridge power/clock control enable\n");
1106 } else {
1107 DEBUG0(DBG_PWR, pdip,
1108 "setup: bridge power/clock control disabled\n");
1109
1110 kmem_free(ppb->ppb_pwr_p, sizeof (pci_pwr_t));
1111 ppb->ppb_pwr_p = NULL;
1112 pci_config_teardown(&conf_hdl);
1113
1114 return;
1115 }
1116
1117 /*
1118 * PCI states D0 and D3 always are supported for normal PCI
1119 * devices. D1 and D2 are optional which are checked for above.
1120 * Bridge function states D0-D3 correspond to secondary bus states
1121 * B0-B3, EXCEPT if PCI_PMCSR_BSE_B2_B3 is set. In this case, setting
1122 * the bridge function to D3 will set the bridge bus to state B2 instead
1123 * of B3. D2 will not correspond to B2 (and in fact, probably
1124 * won't be D2 capable). Implicitly, this means that if
1125 * PCI_PMCSR_BSE_B2_B3 is set, the bus will not be B3 capable.
1126 */
1127 if (pmcsr_bse & PCI_PMCSR_BSE_B2_B3) {
1128 ppb->ppb_pwr_p->pwr_flags |= PCI_PWR_B2_CAPABLE;
1129 DEBUG0(DBG_PWR, pdip, "B2 supported via D3\n");
1130 } else {
1131 ppb->ppb_pwr_p->pwr_flags |= PCI_PWR_B3_CAPABLE;
1132 DEBUG0(DBG_PWR, pdip, "B3 supported via D3\n");
1133 }
1134
1135 ppb->ppb_pwr_p->pwr_dip = pdip;
1136 mutex_init(&ppb->ppb_pwr_p->pwr_mutex, NULL, MUTEX_DRIVER, NULL);
1137
1138 i = 0;
1139 comp_array[i++] = "NAME=PCI bridge PM";
1140 if (ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B3_CAPABLE) {
1141 comp_array[i++] = "0=Clock/Power Off (B3)";
1142 }
1143 if (ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B2_CAPABLE) {
1144 comp_array[i++] = "1=Clock Off (B2)";
1145 }
1146 if (ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B1_CAPABLE) {
1147 comp_array[i++] = "2=Bus Inactive (B1)";
1148 }
1149 comp_array[i++] = "3=Full Power (B0)";
1150
1151 /*
1152 * Create pm-components property. It does not already exist.
1153 */
1154 if (ddi_prop_update_string_array(DDI_DEV_T_NONE, pdip,
1155 "pm-components", comp_array, i) != DDI_PROP_SUCCESS) {
1156 cmn_err(CE_WARN,
1157 "%s%d pm-components prop update failed",
1158 ddi_driver_name(pdip), ddi_get_instance(pdip));
1159 pci_config_teardown(&conf_hdl);
1160 mutex_destroy(&ppb->ppb_pwr_p->pwr_mutex);
1161 kmem_free(ppb->ppb_pwr_p, sizeof (pci_pwr_t));
1162 ppb->ppb_pwr_p = NULL;
1163
1164 return;
1165 }
1166
1167 if (ddi_prop_create(DDI_DEV_T_NONE, pdip, DDI_PROP_CANSLEEP,
1168 "pm-want-child-notification?", NULL, 0) != DDI_PROP_SUCCESS) {
1169 cmn_err(CE_WARN,
1170 "%s%d fail to create pm-want-child-notification? prop",
1171 ddi_driver_name(pdip), ddi_get_instance(pdip));
1172
1173 (void) ddi_prop_remove(DDI_DEV_T_NONE, pdip, "pm-components");
1174 pci_config_teardown(&conf_hdl);
1175 mutex_destroy(&ppb->ppb_pwr_p->pwr_mutex);
1176 kmem_free(ppb->ppb_pwr_p, sizeof (pci_pwr_t));
1177 ppb->ppb_pwr_p = NULL;
1178
1179 return;
1180 }
1181
1182 ppb->ppb_pwr_p->current_lvl =
1183 pci_pwr_current_lvl(ppb->ppb_pwr_p);
1184 }
1185
1186 /*
1187 * Remove PM state for nexus.
1188 */
1189 static void
ppb_pwr_teardown(ppb_devstate_t * ppb,dev_info_t * dip)1190 ppb_pwr_teardown(ppb_devstate_t *ppb, dev_info_t *dip)
1191 {
1192 int low_lvl;
1193
1194 /*
1195 * Determine the lowest power level supported.
1196 */
1197 if (ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B3_CAPABLE) {
1198 low_lvl = PM_LEVEL_B3;
1199 } else {
1200 low_lvl = PM_LEVEL_B2;
1201 }
1202
1203 if (pm_lower_power(dip, PCI_PM_COMP_0, low_lvl) != DDI_SUCCESS) {
1204 cmn_err(CE_WARN, "%s%d failed to lower power",
1205 ddi_driver_name(dip), ddi_get_instance(dip));
1206 }
1207
1208 pci_config_teardown(&ppb->ppb_conf_hdl);
1209 mutex_destroy(&ppb->ppb_pwr_p->pwr_mutex);
1210 kmem_free(ppb->ppb_pwr_p, sizeof (pci_pwr_t));
1211
1212 if (ddi_prop_remove(DDI_DEV_T_NONE, dip, "pm-components") !=
1213 DDI_PROP_SUCCESS) {
1214 cmn_err(CE_WARN, "%s%d unable to remove prop pm-components",
1215 ddi_driver_name(dip), ddi_get_instance(dip));
1216 }
1217
1218 if (ddi_prop_remove(DDI_DEV_T_NONE, dip,
1219 "pm-want-child-notification?") != DDI_PROP_SUCCESS) {
1220 cmn_err(CE_WARN,
1221 "%s%d unable to remove prop pm-want_child_notification?",
1222 ddi_driver_name(dip), ddi_get_instance(dip));
1223 }
1224 }
1225
1226 /*
1227 * Examine the pmcsr register and return the software defined
1228 * state (the difference being whether D3 means B2 or B3).
1229 */
1230 int
pci_pwr_current_lvl(pci_pwr_t * pwr_p)1231 pci_pwr_current_lvl(pci_pwr_t *pwr_p)
1232 {
1233 ppb_devstate_t *ppb;
1234 uint16_t pmcsr;
1235
1236 /*
1237 * Find out current power level
1238 */
1239 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
1240 ddi_get_instance(pwr_p->pwr_dip));
1241
1242 if ((pmcsr = PCI_CAP_GET16(ppb->ppb_conf_hdl, 0,
1243 ppb->ppb_pm_cap_ptr, PCI_PMCSR)) == PCI_CAP_EINVAL16)
1244 return (DDI_FAILURE);
1245
1246 switch (pmcsr & PCI_PMCSR_STATE_MASK) {
1247 case PCI_PMCSR_D0:
1248
1249 return (PM_LEVEL_B0);
1250 case PCI_PMCSR_D1:
1251
1252 return (PM_LEVEL_B1);
1253 case PCI_PMCSR_D2:
1254
1255 return (PM_LEVEL_B2);
1256 case PCI_PMCSR_D3HOT:
1257 if ((ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B3_CAPABLE) == 0) {
1258
1259 return (PM_LEVEL_B2);
1260 } else {
1261
1262 return (PM_LEVEL_B3);
1263 }
1264 }
1265 /*NOTREACHED*/
1266 return (PM_LEVEL_B3);
1267 }
1268
1269 /*
1270 * Power entry point. Called by the PM framework to change the
1271 * current power state of the bus. This function must first verify that
1272 * the requested power change is still valid.
1273 */
1274 /*ARGSUSED*/
1275 static int
ppb_pwr(dev_info_t * dip,int component,int lvl)1276 ppb_pwr(dev_info_t *dip, int component, int lvl)
1277 {
1278 ppb_devstate_t *ppb;
1279 uint16_t pmcsr;
1280 char *str;
1281 int lowest_lvl;
1282 int old_lvl;
1283 int new_lvl;
1284
1285 ppb = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
1286 ddi_get_instance(dip));
1287 if (ppb == NULL) {
1288 cmn_err(CE_WARN, "%s%d ppb_pwr: can't get soft state",
1289 ddi_driver_name(dip), ddi_get_instance(dip));
1290
1291 return (DDI_FAILURE);
1292 }
1293
1294 DEBUG1(DBG_PWR, dip, "ppb_pwr(): ENTER level = %d\n", lvl);
1295
1296 mutex_enter(&ppb->ppb_pwr_p->pwr_mutex);
1297
1298 /*
1299 * Find out if the power setting is possible. If it is not,
1300 * set component busy and return failure. If it is possible,
1301 * and it is the lowest pwr setting possible, set component
1302 * busy so that the framework does not try to lower any further.
1303 */
1304 lowest_lvl = pci_pwr_new_lvl(ppb->ppb_pwr_p);
1305 if (lowest_lvl > lvl) {
1306 pci_pwr_component_busy(ppb->ppb_pwr_p);
1307 DEBUG2(DBG_PWR, dip, "ppb_pwr: failing power request "
1308 "lowest allowed is %d requested is %d\n",
1309 lowest_lvl, lvl);
1310 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1311
1312 return (DDI_FAILURE);
1313 } else if (lowest_lvl == lvl) {
1314 pci_pwr_component_busy(ppb->ppb_pwr_p);
1315 } else {
1316 pci_pwr_component_idle(ppb->ppb_pwr_p);
1317 }
1318
1319 if ((pmcsr = PCI_CAP_GET16(ppb->ppb_conf_hdl, 0,
1320 ppb->ppb_pm_cap_ptr, PCI_PMCSR)) == PCI_CAP_EINVAL16)
1321 return (DDI_FAILURE);
1322
1323 /*
1324 * Save the current power level. This is the actual function level,
1325 * not the translated bridge level stored in pwr_p->current_lvl
1326 */
1327 old_lvl = pmcsr & PCI_PMCSR_STATE_MASK;
1328
1329 pmcsr &= ~PCI_PMCSR_STATE_MASK;
1330 switch (lvl) {
1331 case PM_LEVEL_B0:
1332 str = "PM_LEVEL_B0 (full speed)";
1333 pmcsr |= PCI_PMCSR_D0;
1334 break;
1335 case PM_LEVEL_B1:
1336 str = "PM_LEVEL_B1 (light sleep. No bus traffic allowed)";
1337 if ((ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B1_CAPABLE) == 0) {
1338 cmn_err(CE_WARN, "%s%d PCI PM state B1 not supported",
1339 ddi_driver_name(dip), ddi_get_instance(dip));
1340
1341 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1342 return (DDI_FAILURE);
1343 }
1344 pmcsr |= PCI_PMCSR_D1;
1345 break;
1346 case PM_LEVEL_B2:
1347 str = "PM_LEVEL_B2 (clock off)";
1348 if ((ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B2_CAPABLE) == 0) {
1349 cmn_err(CE_WARN, "%s%d PM state B2 not supported...",
1350 ddi_driver_name(dip),
1351 ddi_get_instance(dip));
1352 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1353
1354 return (DDI_FAILURE);
1355 }
1356
1357 if ((ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B3_CAPABLE) == 0) {
1358 /*
1359 * If B3 isn't supported, use D3 for B2 to avoid the
1360 * possible case that D2 for B2 isn't supported.
1361 * Saves and extra check and state flag..
1362 */
1363 pmcsr |= PCI_PMCSR_D3HOT;
1364 } else {
1365 pmcsr |= PCI_PMCSR_D2;
1366 }
1367 break;
1368 case PM_LEVEL_B3:
1369 str = "PM_LEVEL_B30 (clock and power off)";
1370 if ((ppb->ppb_pwr_p->pwr_flags & PCI_PWR_B3_CAPABLE) == 0) {
1371 cmn_err(CE_WARN, "%s%d PM state B3 not supported...",
1372 ddi_driver_name(dip),
1373 ddi_get_instance(dip));
1374 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1375
1376 return (DDI_FAILURE);
1377 }
1378 pmcsr |= PCI_PMCSR_D3HOT;
1379
1380 break;
1381
1382 default:
1383 cmn_err(CE_WARN, "%s%d Unknown PM state %d",
1384 ddi_driver_name(dip), ddi_get_instance(dip), lvl);
1385 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1386
1387 return (DDI_FAILURE);
1388 }
1389
1390 new_lvl = pmcsr & PCI_PMCSR_STATE_MASK;
1391
1392 /*
1393 * Save config regs if going into HW state D3 (B2 or B3)
1394 */
1395 if ((old_lvl != PCI_PMCSR_D3HOT) && (new_lvl == PCI_PMCSR_D3HOT)) {
1396 DEBUG0(DBG_PWR, dip, "ppb_pwr(): SAVING CONFIG REGS\n");
1397 if (pci_save_config_regs(dip) != DDI_SUCCESS) {
1398 cmn_err(CE_WARN, "%s%d Save config regs failed",
1399 ddi_driver_name(dip), ddi_get_instance(dip));
1400 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1401
1402 return (DDI_FAILURE);
1403 }
1404 }
1405
1406 PCI_CAP_PUT16(ppb->ppb_conf_hdl, 0, ppb->ppb_pm_cap_ptr, PCI_PMCSR,
1407 pmcsr);
1408
1409 /*
1410 * No bus transactions should occur without waiting for
1411 * settle time specified in PCI PM spec rev 2.1 sec 5.6.1
1412 * To make things simple, just use the max time specified for
1413 * all state transitions.
1414 */
1415 delay(drv_usectohz(PCI_CLK_SETTLE_TIME));
1416
1417 /*
1418 * Restore configuration registers if coming out of HW state D3
1419 */
1420 if ((old_lvl == PCI_PMCSR_D3HOT) && (new_lvl != PCI_PMCSR_D3HOT)) {
1421 DEBUG0(DBG_PWR, dip, "ppb_pwr(): RESTORING CONFIG REGS\n");
1422 if (pci_restore_config_regs(dip) != DDI_SUCCESS) {
1423 panic("%s%d restore config regs failed",
1424 ddi_driver_name(dip), ddi_get_instance(dip));
1425 }
1426 /*NOTREACHED*/
1427 }
1428
1429 ppb->ppb_pwr_p->current_lvl = lvl;
1430
1431 mutex_exit(&ppb->ppb_pwr_p->pwr_mutex);
1432
1433 DEBUG1(DBG_PWR, dip, "ppb_set_pwr: set PM state to %s\n\n", str);
1434
1435 return (DDI_SUCCESS);
1436 }
1437
1438 /*
1439 * Initialize hotplug framework if we are hotpluggable.
1440 * Sets flag in the soft state if Hot Plug is supported and initialized
1441 * properly.
1442 */
1443 /*ARGSUSED*/
1444 static void
ppb_init_hotplug(ppb_devstate_t * ppb)1445 ppb_init_hotplug(ppb_devstate_t *ppb)
1446 {
1447 ppb->hotplug_capable = B_FALSE;
1448
1449 if (ddi_prop_exists(DDI_DEV_T_ANY, ppb->dip, DDI_PROP_DONTPASS,
1450 "hotplug-capable")) {
1451 (void) modload("misc", "pcihp");
1452
1453 if (pcihp_init(ppb->dip) != DDI_SUCCESS) {
1454 cmn_err(CE_WARN,
1455 "%s #%d: Failed setting hotplug framework",
1456 ddi_driver_name(ppb->dip),
1457 ddi_get_instance(ppb->dip));
1458 } else
1459 ppb->hotplug_capable = B_TRUE;
1460 }
1461
1462 if (ppb->hotplug_capable == B_FALSE) {
1463 /*
1464 * create minor node for devctl interfaces
1465 */
1466 if (ddi_create_minor_node(ppb->dip, "devctl", S_IFCHR,
1467 PCI_MINOR_NUM(ddi_get_instance(ppb->dip), PCI_DEVCTL_MINOR),
1468 DDI_NT_NEXUS, 0) != DDI_SUCCESS)
1469 cmn_err(CE_WARN,
1470 "%s #%d: Failed to create a minor node",
1471 ddi_driver_name(ppb->dip),
1472 ddi_get_instance(ppb->dip));
1473 }
1474 }
1475
1476 static void
ppb_create_ranges_prop(dev_info_t * dip,ddi_acc_handle_t config_handle)1477 ppb_create_ranges_prop(dev_info_t *dip,
1478 ddi_acc_handle_t config_handle)
1479 {
1480 uint32_t base, limit;
1481 ppb_ranges_t ranges[PPB_RANGE_LEN];
1482 uint8_t io_base_lo, io_limit_lo;
1483 uint16_t io_base_hi, io_limit_hi, mem_base, mem_limit;
1484 int i = 0, rangelen = sizeof (ppb_ranges_t)/sizeof (int);
1485
1486 io_base_lo = pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW);
1487 io_limit_lo = pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW);
1488 io_base_hi = pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI);
1489 io_limit_hi = pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI);
1490 mem_base = pci_config_get16(config_handle, PCI_BCNF_MEM_BASE);
1491 mem_limit = pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT);
1492
1493 /*
1494 * Create ranges for IO space
1495 */
1496 ranges[i].size_low = ranges[i].size_high = 0;
1497 ranges[i].parent_mid = ranges[i].child_mid =
1498 ranges[i].parent_high = 0;
1499 ranges[i].child_high = ranges[i].parent_high |=
1500 (PCI_REG_REL_M | PCI_ADDR_IO);
1501 base = PPB_16bit_IOADDR(io_base_lo);
1502 limit = PPB_16bit_IOADDR(io_limit_lo);
1503
1504 /*
1505 * Check for 32-bit I/O support as per PCI-to-PCI Bridge Arch Spec
1506 */
1507 if ((io_base_lo & 0xf) == PPB_32BIT_IO) {
1508 base = PPB_LADDR(base, io_base_hi);
1509 limit = PPB_LADDR(limit, io_limit_hi);
1510 }
1511
1512 /*
1513 * Check if the bridge implements an I/O address range as per
1514 * PCI-to-PCI Bridge Arch Spec
1515 */
1516 if ((io_base_lo != 0 || io_limit_lo != 0) && limit >= base) {
1517 ranges[i].parent_low = ranges[i].child_low =
1518 base;
1519 ranges[i].size_low = limit - base + PPB_IOGRAIN;
1520 i++;
1521 }
1522
1523 /*
1524 * Create ranges for 32bit memory space
1525 */
1526 base = PPB_32bit_MEMADDR(mem_base);
1527 limit = PPB_32bit_MEMADDR(mem_limit);
1528 ranges[i].size_low = ranges[i].size_high = 0;
1529 ranges[i].parent_mid = ranges[i].child_mid =
1530 ranges[i].parent_high = 0;
1531 ranges[i].child_high = ranges[i].parent_high |=
1532 (PCI_REG_REL_M | PCI_ADDR_MEM32);
1533 ranges[i].child_low = ranges[i].parent_low = base;
1534 if (limit >= base) {
1535 ranges[i].size_low = limit - base + PPB_MEMGRAIN;
1536 i++;
1537 }
1538
1539 if (i) {
1540 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges",
1541 (int *)ranges, i * rangelen);
1542 }
1543 }
1544
1545 /* ARGSUSED */
1546 static int
ppb_open(dev_t * devp,int flags,int otyp,cred_t * credp)1547 ppb_open(dev_t *devp, int flags, int otyp, cred_t *credp)
1548 {
1549 int instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(*devp));
1550 ppb_devstate_t *ppb_p = ddi_get_soft_state(ppb_state, instance);
1551
1552 /*
1553 * Make sure the open is for the right file type.
1554 */
1555 if (otyp != OTYP_CHR)
1556 return (EINVAL);
1557
1558 if (ppb_p == NULL)
1559 return (ENXIO);
1560
1561 mutex_enter(&ppb_p->ppb_mutex);
1562
1563 /*
1564 * Ioctls will be handled by SPARC PCI Express framework for all
1565 * PCIe platforms
1566 */
1567 if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
1568 int rv;
1569
1570 rv = pcie_open(ppb_p->dip, devp, flags, otyp, credp);
1571 mutex_exit(&ppb_p->ppb_mutex);
1572
1573 return (rv);
1574 } else if (ppb_p->hotplug_capable == B_TRUE) {
1575 mutex_exit(&ppb_p->ppb_mutex);
1576
1577 return ((pcihp_get_cb_ops())->cb_open(devp, flags, otyp,
1578 credp));
1579 }
1580
1581 /*
1582 * Handle the open by tracking the device state.
1583 */
1584 if (flags & FEXCL) {
1585 if (ppb_p->ppb_soft_state != PCI_SOFT_STATE_CLOSED) {
1586 mutex_exit(&ppb_p->ppb_mutex);
1587 return (EBUSY);
1588 }
1589 ppb_p->ppb_soft_state = PCI_SOFT_STATE_OPEN_EXCL;
1590 } else {
1591 if (ppb_p->ppb_soft_state == PCI_SOFT_STATE_OPEN_EXCL) {
1592 mutex_exit(&ppb_p->ppb_mutex);
1593 return (EBUSY);
1594 }
1595 ppb_p->ppb_soft_state = PCI_SOFT_STATE_OPEN;
1596 }
1597 mutex_exit(&ppb_p->ppb_mutex);
1598 return (0);
1599 }
1600
1601
1602 /* ARGSUSED */
1603 static int
ppb_close(dev_t dev,int flags,int otyp,cred_t * credp)1604 ppb_close(dev_t dev, int flags, int otyp, cred_t *credp)
1605 {
1606 int instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
1607 ppb_devstate_t *ppb_p = ddi_get_soft_state(ppb_state, instance);
1608
1609 if (otyp != OTYP_CHR)
1610 return (EINVAL);
1611
1612 if (ppb_p == NULL)
1613 return (ENXIO);
1614
1615 mutex_enter(&ppb_p->ppb_mutex);
1616 /*
1617 * Ioctls will be handled by SPARC PCI Express framework for all
1618 * PCIe platforms
1619 */
1620 if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV) {
1621 int rv;
1622
1623 rv = pcie_close(ppb_p->dip, dev, flags, otyp, credp);
1624 mutex_exit(&ppb_p->ppb_mutex);
1625
1626 return (rv);
1627 } else if (ppb_p->hotplug_capable == B_TRUE) {
1628 mutex_exit(&ppb_p->ppb_mutex);
1629 return ((pcihp_get_cb_ops())->cb_close(dev, flags, otyp,
1630 credp));
1631 }
1632
1633 ppb_p->ppb_soft_state = PCI_SOFT_STATE_CLOSED;
1634 mutex_exit(&ppb_p->ppb_mutex);
1635 return (0);
1636 }
1637
1638
1639 /*
1640 * ppb_ioctl: devctl hotplug controls
1641 */
1642 /* ARGSUSED */
1643 static int
ppb_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)1644 ppb_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1645 int *rvalp)
1646 {
1647 int instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
1648 ppb_devstate_t *ppb_p = ddi_get_soft_state(ppb_state, instance);
1649 struct devctl_iocdata *dcp;
1650 uint_t bus_state;
1651 dev_info_t *self;
1652 int rv = 0;
1653
1654 if (ppb_p == NULL)
1655 return (ENXIO);
1656
1657 /*
1658 * Ioctls will be handled by SPARC PCI Express framework for all
1659 * PCIe platforms
1660 */
1661 if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
1662 return (pcie_ioctl(ppb_p->dip, dev, cmd, arg, mode, credp,
1663 rvalp));
1664 else if (ppb_p->hotplug_capable == B_TRUE)
1665 return ((pcihp_get_cb_ops())->cb_ioctl(dev, cmd, arg, mode,
1666 credp, rvalp));
1667
1668 self = ppb_p->dip;
1669
1670 /*
1671 * We can use the generic implementation for these ioctls
1672 */
1673 switch (cmd) {
1674 case DEVCTL_DEVICE_GETSTATE:
1675 case DEVCTL_DEVICE_ONLINE:
1676 case DEVCTL_DEVICE_OFFLINE:
1677 case DEVCTL_BUS_GETSTATE:
1678 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
1679 }
1680
1681 /*
1682 * read devctl ioctl data
1683 */
1684 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1685 return (EFAULT);
1686
1687 switch (cmd) {
1688
1689 case DEVCTL_DEVICE_RESET:
1690 rv = ENOTSUP;
1691 break;
1692
1693 case DEVCTL_BUS_QUIESCE:
1694 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1695 if (bus_state == BUS_QUIESCED)
1696 break;
1697 (void) ndi_set_bus_state(self, BUS_QUIESCED);
1698 break;
1699
1700 case DEVCTL_BUS_UNQUIESCE:
1701 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1702 if (bus_state == BUS_ACTIVE)
1703 break;
1704 (void) ndi_set_bus_state(self, BUS_ACTIVE);
1705 break;
1706
1707 case DEVCTL_BUS_RESET:
1708 rv = ENOTSUP;
1709 break;
1710
1711 case DEVCTL_BUS_RESETALL:
1712 rv = ENOTSUP;
1713 break;
1714
1715 default:
1716 rv = ENOTTY;
1717 }
1718
1719 ndi_dc_freehdl(dcp);
1720 return (rv);
1721 }
1722
1723 static int
ppb_prop_op(dev_t dev,dev_info_t * dip,ddi_prop_op_t prop_op,int flags,char * name,caddr_t valuep,int * lengthp)1724 ppb_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int flags,
1725 char *name, caddr_t valuep, int *lengthp)
1726 {
1727 int instance = PCI_MINOR_NUM_TO_INSTANCE(getminor(dev));
1728 ppb_devstate_t *ppb_p = (ppb_devstate_t *)
1729 ddi_get_soft_state(ppb_state, instance);
1730
1731 if (ppb_p == NULL)
1732 return (ENXIO);
1733
1734 if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
1735 return (pcie_prop_op(dev, dip, prop_op, flags, name,
1736 valuep, lengthp));
1737
1738 return ((pcihp_get_cb_ops())->cb_prop_op(dev, dip, prop_op, flags,
1739 name, valuep, lengthp));
1740 }
1741
1742 /*
1743 * Initialize our FMA resources
1744 */
1745 static void
ppb_fm_init(ppb_devstate_t * ppb_p)1746 ppb_fm_init(ppb_devstate_t *ppb_p)
1747 {
1748 ppb_p->fm_cap = DDI_FM_EREPORT_CAPABLE | DDI_FM_ERRCB_CAPABLE |
1749 DDI_FM_ACCCHK_CAPABLE | DDI_FM_DMACHK_CAPABLE;
1750
1751 /*
1752 * Request our capability level and get our parents capability
1753 * and ibc.
1754 */
1755 ddi_fm_init(ppb_p->dip, &ppb_p->fm_cap, &ppb_p->fm_ibc);
1756 ASSERT((ppb_p->fm_cap & DDI_FM_EREPORT_CAPABLE) &&
1757 (ppb_p->fm_cap & DDI_FM_ERRCB_CAPABLE));
1758
1759 pci_ereport_setup(ppb_p->dip);
1760
1761 /*
1762 * Register error callback with our parent.
1763 */
1764 ddi_fm_handler_register(ppb_p->dip, ppb_err_callback, NULL);
1765 }
1766
1767 /*
1768 * Breakdown our FMA resources
1769 */
1770 static void
ppb_fm_fini(ppb_devstate_t * ppb_p)1771 ppb_fm_fini(ppb_devstate_t *ppb_p)
1772 {
1773 /*
1774 * Clean up allocated fm structures
1775 */
1776 ddi_fm_handler_unregister(ppb_p->dip);
1777 pci_ereport_teardown(ppb_p->dip);
1778 ddi_fm_fini(ppb_p->dip);
1779 }
1780
1781 /*
1782 * Initialize FMA resources for children devices. Called when
1783 * child calls ddi_fm_init().
1784 */
1785 /*ARGSUSED*/
1786 static int
ppb_fm_init_child(dev_info_t * dip,dev_info_t * tdip,int cap,ddi_iblock_cookie_t * ibc)1787 ppb_fm_init_child(dev_info_t *dip, dev_info_t *tdip, int cap,
1788 ddi_iblock_cookie_t *ibc)
1789 {
1790 ppb_devstate_t *ppb_p = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
1791 ddi_get_instance(dip));
1792 *ibc = ppb_p->fm_ibc;
1793 return (ppb_p->fm_cap);
1794 }
1795
1796 /*
1797 * FMA registered error callback
1798 */
1799 static int
ppb_err_callback(dev_info_t * dip,ddi_fm_error_t * derr,const void * impl_data)1800 ppb_err_callback(dev_info_t *dip, ddi_fm_error_t *derr, const void *impl_data)
1801 {
1802 ppb_devstate_t *ppb_p = (ppb_devstate_t *)ddi_get_soft_state(ppb_state,
1803 ddi_get_instance(dip));
1804
1805 /*
1806 * errors handled by SPARC PCI-E framework for PCIe platforms
1807 */
1808 if (ppb_p->parent_bus == PCIE_PCIECAP_DEV_TYPE_PCIE_DEV)
1809 return (DDI_FM_OK);
1810
1811 /*
1812 * do the following for SPARC PCI platforms
1813 */
1814 ASSERT(impl_data == NULL);
1815 pci_ereport_post(dip, derr, NULL);
1816 return (derr->fme_status);
1817 }
1818
1819 static void
ppb_bus_enter(dev_info_t * dip,ddi_acc_handle_t handle)1820 ppb_bus_enter(dev_info_t *dip, ddi_acc_handle_t handle)
1821 {
1822 i_ndi_busop_access_enter(dip, handle);
1823 }
1824
1825 /* ARGSUSED */
1826 static void
ppb_bus_exit(dev_info_t * dip,ddi_acc_handle_t handle)1827 ppb_bus_exit(dev_info_t *dip, ddi_acc_handle_t handle)
1828 {
1829 i_ndi_busop_access_exit(dip, handle);
1830 }
1831