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