1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 #include <sys/types.h>
28 #include <sys/conf.h>
29 #include <sys/ddi.h>
30 #include <sys/sunddi.h>
31 #include <sys/ddi_impldefs.h>
32 #include <sys/ddi_subrdefs.h>
33 #include <sys/pci.h>
34 #include <sys/autoconf.h>
35 #include <sys/cmn_err.h>
36 #include <sys/errno.h>
37 #include <sys/kmem.h>
38 #include <sys/debug.h>
39 #include <sys/sysmacros.h>
40 #include <sys/ebus.h>
41 #include <sys/open.h>
42 #include <sys/stat.h>
43 #include <sys/file.h>
44 #include <sys/sunndi.h>
45
46 #ifdef DEBUG
47 uint64_t ebus_debug_flags = 0;
48 #endif
49
50 /*
51 * The values of the following variables are used to initialize
52 * the cache line size and latency timer registers in the ebus
53 * configuration header. Variables are used instead of constants
54 * to allow tuning from the /etc/system file.
55 */
56 static uint8_t ebus_cache_line_size = 0x10; /* 64 bytes */
57 static uint8_t ebus_latency_timer = 0x40; /* 64 PCI cycles */
58
59 /*
60 * function prototypes for bus ops routines:
61 */
62 static int
63 ebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
64 off_t offset, off_t len, caddr_t *addrp);
65 static int
66 ebus_ctlops(dev_info_t *dip, dev_info_t *rdip,
67 ddi_ctl_enum_t op, void *arg, void *result);
68 static int
69 ebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
70 ddi_intr_handle_impl_t *hdlp, void *result);
71
72 /*
73 * function prototypes for dev ops routines:
74 */
75 static int ebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
76 static int ebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
77 static int ebus_info(dev_info_t *dip, ddi_info_cmd_t infocmd,
78 void *arg, void **result);
79
80 /*
81 * general function prototypes:
82 */
83 static int ebus_config(ebus_devstate_t *ebus_p);
84 static int ebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip,
85 ebus_regspec_t *ebus_rp, vregspec_t *rp);
86 int ebus_get_ranges_prop(ebus_devstate_t *ebus_p);
87 static void ebus_get_cells_prop(ebus_devstate_t *ebus_p);
88 static void ebus_vreg_dump(ebus_devstate_t *ebus_p, vregspec_t *rp);
89
90 #define getprop(dip, name, addr, intp) \
91 ddi_getlongprop(DDI_DEV_T_ANY, (dip), DDI_PROP_DONTPASS, \
92 (name), (caddr_t)(addr), (intp))
93
94 static int ebus_open(dev_t *devp, int flags, int otyp, cred_t *credp);
95 static int ebus_close(dev_t dev, int flags, int otyp, cred_t *credp);
96 static int ebus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
97 cred_t *credp, int *rvalp);
98 struct cb_ops ebus_cb_ops = {
99 ebus_open, /* open */
100 ebus_close, /* close */
101 nodev, /* strategy */
102 nodev, /* print */
103 nodev, /* dump */
104 nodev, /* read */
105 nodev, /* write */
106 ebus_ioctl, /* ioctl */
107 nodev, /* devmap */
108 nodev, /* mmap */
109 nodev, /* segmap */
110 nochpoll, /* poll */
111 ddi_prop_op, /* cb_prop_op */
112 NULL, /* streamtab */
113 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */
114 CB_REV, /* rev */
115 nodev, /* int (*cb_aread)() */
116 nodev /* int (*cb_awrite)() */
117 };
118
119 /*
120 * bus ops and dev ops structures:
121 */
122 static struct bus_ops ebus_bus_ops = {
123 BUSO_REV,
124 ebus_map,
125 NULL,
126 NULL,
127 NULL,
128 i_ddi_map_fault,
129 ddi_dma_map,
130 ddi_dma_allochdl,
131 ddi_dma_freehdl,
132 ddi_dma_bindhdl,
133 ddi_dma_unbindhdl,
134 ddi_dma_flush,
135 ddi_dma_win,
136 ddi_dma_mctl,
137 ebus_ctlops,
138 ddi_bus_prop_op,
139 ndi_busop_get_eventcookie,
140 ndi_busop_add_eventcall,
141 ndi_busop_remove_eventcall,
142 ndi_post_event,
143 0,
144 0,
145 0,
146 0,
147 0,
148 0,
149 0,
150 0,
151 ebus_intr_ops
152 };
153
154 static struct dev_ops ebus_ops = {
155 DEVO_REV,
156 0,
157 ebus_info,
158 nulldev,
159 nulldev,
160 ebus_attach,
161 ebus_detach,
162 nodev,
163 &ebus_cb_ops,
164 &ebus_bus_ops,
165 NULL,
166 ddi_quiesce_not_supported, /* devo_quiesce */
167 };
168
169 /*
170 * module definitions:
171 */
172 #include <sys/modctl.h>
173 extern struct mod_ops mod_driverops;
174
175 static struct modldrv modldrv = {
176 &mod_driverops, /* Type of module. This one is a driver */
177 "ebus nexus driver", /* Name of module. */
178 &ebus_ops, /* driver ops */
179 };
180
181 static struct modlinkage modlinkage = {
182 MODREV_1, (void *)&modldrv, NULL
183 };
184
185 /*
186 * driver global data:
187 */
188 static void *per_ebus_state; /* per-ebus soft state pointer */
189
190
191 int
_init(void)192 _init(void)
193 {
194 int e;
195
196 /*
197 * Initialize per-ebus soft state pointer.
198 */
199 e = ddi_soft_state_init(&per_ebus_state, sizeof (ebus_devstate_t), 1);
200 if (e != 0)
201 return (e);
202
203 /*
204 * Install the module.
205 */
206 e = mod_install(&modlinkage);
207 if (e != 0)
208 ddi_soft_state_fini(&per_ebus_state);
209 return (e);
210 }
211
212 int
_fini(void)213 _fini(void)
214 {
215 int e;
216
217 /*
218 * Remove the module.
219 */
220 e = mod_remove(&modlinkage);
221 if (e != 0)
222 return (e);
223
224 /*
225 * Free the soft state info.
226 */
227 ddi_soft_state_fini(&per_ebus_state);
228 return (e);
229 }
230
231 int
_info(struct modinfo * modinfop)232 _info(struct modinfo *modinfop)
233 {
234 return (mod_info(&modlinkage, modinfop));
235 }
236
237 /* device driver entry points */
238
239 /*ARGSUSED*/
240 static int
ebus_info(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)241 ebus_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
242 {
243 ebus_devstate_t *ebus_p; /* per ebus state pointer */
244 int instance;
245
246 instance = getminor((dev_t)arg);
247 ebus_p = get_ebus_soft_state(instance);
248
249 switch (infocmd) {
250 case DDI_INFO_DEVT2INSTANCE:
251 *result = (void *)(uintptr_t)instance;
252 break;
253 case DDI_INFO_DEVT2DEVINFO:
254 if (ebus_p == NULL)
255 return (DDI_FAILURE);
256 *result = (void *)ebus_p->dip;
257 break;
258 default:
259 return (DDI_FAILURE);
260 }
261
262 return (DDI_SUCCESS);
263 }
264
265 /*
266 * attach entry point:
267 *
268 * normal attach:
269 *
270 * create soft state structure (dip, reg, nreg and state fields)
271 * map in configuration header
272 * make sure device is properly configured
273 * report device
274 */
275 static int
ebus_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)276 ebus_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
277 {
278 ebus_devstate_t *ebus_p; /* per ebus state pointer */
279 int instance;
280
281 DBG1(D_ATTACH, NULL, "dip=%p\n", dip);
282
283 switch (cmd) {
284 case DDI_ATTACH:
285
286 /*
287 * Allocate soft state for this instance.
288 */
289 instance = ddi_get_instance(dip);
290 if (ddi_soft_state_zalloc(per_ebus_state, instance)
291 != DDI_SUCCESS) {
292 DBG(D_ATTACH, NULL, "failed to alloc soft state\n");
293 return (DDI_FAILURE);
294 }
295 ebus_p = get_ebus_soft_state(instance);
296 ebus_p->dip = dip;
297 mutex_init(&ebus_p->ebus_mutex, NULL, MUTEX_DRIVER, NULL);
298 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_CLOSED;
299
300 ebus_get_cells_prop(ebus_p);
301
302 (void) ddi_prop_create(DDI_DEV_T_NONE, dip,
303 DDI_PROP_CANSLEEP, "no-dma-interrupt-sync", NULL, 0);
304 /* Get our ranges property for mapping child registers. */
305 if (ebus_get_ranges_prop(ebus_p) != DDI_SUCCESS) {
306 goto attach_fail;
307 }
308
309 /*
310 * create minor node for devctl interfaces
311 */
312 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, instance,
313 DDI_NT_NEXUS, 0) != DDI_SUCCESS) {
314 goto attach_fail;
315 }
316
317 if (ebus_config(ebus_p) != DDI_SUCCESS) {
318 ddi_remove_minor_node(dip, "devctl");
319 goto attach_fail;
320 }
321
322 /*
323 * Make the pci_report_pmcap() call only for RIO
324 * implementations.
325 */
326 if (IS_RIO(dip)) {
327 (void) pci_report_pmcap(dip, PCI_PM_IDLESPEED,
328 (void *)EBUS_4MHZ);
329 }
330
331 /*
332 * Make the state as attached and report the device.
333 */
334 ebus_p->state = ATTACHED;
335 ddi_report_dev(dip);
336 DBG(D_ATTACH, ebus_p, "returning\n");
337 break;
338
339 case DDI_RESUME:
340
341 instance = ddi_get_instance(dip);
342 ebus_p = get_ebus_soft_state(instance);
343
344 (void) ebus_config(ebus_p);
345
346 ebus_p->state = RESUMED;
347 break;
348 }
349
350 return (DDI_SUCCESS);
351
352 attach_fail:
353 mutex_destroy(&ebus_p->ebus_mutex);
354 free_ebus_soft_state(instance);
355 return (DDI_FAILURE);
356 }
357
358 /*
359 * detach entry point:
360 */
361 static int
ebus_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)362 ebus_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
363 {
364 int instance = ddi_get_instance(dip);
365 ebus_devstate_t *ebus_p = get_ebus_soft_state(instance);
366
367 switch (cmd) {
368 case DDI_DETACH:
369 DBG1(D_DETACH, ebus_p, "DDI_DETACH dip=%p\n", dip);
370
371 kmem_free(ebus_p->vrangep, ebus_p->vrange_len);
372
373 ddi_remove_minor_node(dip, "devctl");
374 mutex_destroy(&ebus_p->ebus_mutex);
375 free_ebus_soft_state(instance);
376 break;
377 case DDI_SUSPEND:
378 DBG1(D_DETACH, ebus_p, "DDI_SUSPEND dip=%p\n", dip);
379 ebus_p->state = SUSPENDED;
380 break;
381 default:
382 DBG(D_ATTACH, NULL,
383 "failed to recognize ebus detach command\n");
384 return (DDI_FAILURE);
385 }
386 return (DDI_SUCCESS);
387 }
388
389
390 int
ebus_get_ranges_prop(ebus_devstate_t * ebus_p)391 ebus_get_ranges_prop(ebus_devstate_t *ebus_p)
392 {
393 if (ddi_getlongprop(DDI_DEV_T_ANY, ebus_p->dip, DDI_PROP_DONTPASS,
394 "ranges", (caddr_t)&ebus_p->vrangep, &ebus_p->vrange_len)
395 != DDI_SUCCESS) {
396 cmn_err(CE_WARN, "Can't get %s ranges property",
397 ddi_get_name(ebus_p->dip));
398 return (DDI_ME_REGSPEC_RANGE);
399 }
400
401 ebus_p->vrange_cnt = ebus_p->vrange_len /
402 (ebus_p->ebus_paddr_cells + ebus_p->ebus_addr_cells +
403 ebus_p->ebus_psz_cells);
404
405 if (ebus_p->vrange_cnt == 0) {
406 kmem_free(ebus_p->vrangep, ebus_p->vrange_len);
407 DBG(D_ATTACH, NULL, "range is equal to zero\n");
408 return (DDI_FAILURE);
409 }
410
411 return (DDI_SUCCESS);
412 }
413
414 static void
ebus_get_cells_prop(ebus_devstate_t * ebus_p)415 ebus_get_cells_prop(ebus_devstate_t *ebus_p)
416 {
417 dev_info_t *dip = ebus_p->dip;
418 dev_info_t *pdip;
419
420 ebus_p->ebus_addr_cells = ddi_getprop(DDI_DEV_T_ANY,
421 dip, DDI_PROP_DONTPASS, "#address-cells", 2);
422
423 pdip = ddi_get_parent(dip);
424 ebus_p->ebus_paddr_cells = ddi_getprop(DDI_DEV_T_ANY,
425 pdip, DDI_PROP_DONTPASS, "#address-cells", 2);
426
427 ASSERT((ebus_p->ebus_paddr_cells == 3) ||
428 (ebus_p->ebus_paddr_cells == 2));
429
430 ebus_p->ebus_sz_cells = ddi_getprop(DDI_DEV_T_ANY,
431 dip, DDI_PROP_DONTPASS, "#size-cells", 2);
432 ebus_p->ebus_psz_cells = ddi_getprop(DDI_DEV_T_ANY,
433 pdip, DDI_PROP_DONTPASS, "#size-cells", 1);
434
435 /* XXX rootnex assumes 1 cell and does not respect #size-cells */
436 if (ddi_root_node() == pdip)
437 ebus_p->ebus_psz_cells = 1;
438
439 ASSERT((ebus_p->ebus_psz_cells == 2) ||
440 (ebus_p->ebus_psz_cells == 1));
441
442 }
443
444 /* bus driver entry points */
445
446 /*
447 * bus map entry point:
448 *
449 * if map request is for an rnumber
450 * get the corresponding regspec from device node
451 * build a new regspec in our parent's format
452 * build a new map_req with the new regspec
453 * call up the tree to complete the mapping
454 */
455 static int
ebus_map(dev_info_t * dip,dev_info_t * rdip,ddi_map_req_t * mp,off_t off,off_t len,caddr_t * addrp)456 ebus_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp,
457 off_t off, off_t len, caddr_t *addrp)
458 {
459 ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip));
460 ebus_regspec_t *ebus_rp, *ebus_regs;
461 vregspec_t vreg;
462 ddi_map_req_t p_map_request;
463 int rnumber, i, n;
464 int rval = DDI_SUCCESS;
465
466 /*
467 * Handle the mapping according to its type.
468 */
469 DBG4(D_MAP, ebus_p, "rdip=%s%d: off=%x len=%x\n",
470 ddi_get_name(rdip), ddi_get_instance(rdip), off, len);
471 switch (mp->map_type) {
472 case DDI_MT_REGSPEC:
473
474 /*
475 * We assume the register specification is in ebus format.
476 * We must convert it into a PCI format regspec and pass
477 * the request to our parent.
478 */
479 DBG3(D_MAP, ebus_p, "rdip=%s%d: REGSPEC - handlep=%p\n",
480 ddi_get_name(rdip), ddi_get_instance(rdip),
481 mp->map_handlep);
482 ebus_rp = (ebus_regspec_t *)mp->map_obj.rp;
483 break;
484
485 case DDI_MT_RNUMBER:
486
487 /*
488 * Get the "reg" property from the device node and convert
489 * it to our parent's format.
490 */
491 rnumber = mp->map_obj.rnumber;
492 DBG4(D_MAP, ebus_p, "rdip=%s%d: rnumber=%x handlep=%p\n",
493 ddi_get_name(rdip), ddi_get_instance(rdip),
494 rnumber, mp->map_handlep);
495
496 if (getprop(rdip, "reg", &ebus_regs, &i) != DDI_SUCCESS) {
497 DBG(D_MAP, ebus_p, "can't get reg property\n");
498 return (DDI_ME_RNUMBER_RANGE);
499 }
500
501 n = i / sizeof (ebus_regspec_t);
502
503 if (rnumber < 0 || rnumber >= n) {
504 DBG(D_MAP, ebus_p, "rnumber out of range\n");
505 return (DDI_ME_RNUMBER_RANGE);
506 }
507 ebus_rp = &ebus_regs[rnumber];
508 break;
509
510 default:
511 return (DDI_ME_INVAL);
512
513 }
514
515 /* Adjust our reg property with offset and length */
516 ebus_rp->addr_low += off;
517 if (len)
518 ebus_rp->size = len;
519
520 rval = ebus_apply_range(ebus_p, rdip, ebus_rp, &vreg);
521
522 if (mp->map_type == DDI_MT_RNUMBER)
523 kmem_free(ebus_regs, i);
524
525 if (rval != DDI_SUCCESS)
526 return (rval);
527
528 p_map_request = *mp;
529 p_map_request.map_type = DDI_MT_REGSPEC;
530
531 p_map_request.map_obj.rp = (struct regspec *)&vreg;
532
533 rval = ddi_map(dip, &p_map_request, 0, 0, addrp);
534 DBG1(D_MAP, ebus_p, "parent returned %x\n", rval);
535 return (rval);
536 }
537
538 /*
539 * ebus_apply_range generically relocates child's regspec to
540 * parent's format according to ebus' range spec
541 *
542 * Assumptions:
543 * - rng_caddr_hi is the space type
544 * - rng_caddr_low is the base address
545 * - ebus address is 32 bit and ebus entirely lives between 0-4G of
546 * parent space, so maths on preg/rng_cell_p[ebus_p->ebus_paddr_cells - 1],
547 * preg_cell_p[i], rng_caddr_low and ebus_rp->size are sufficient.
548 */
549 static int
ebus_apply_range(ebus_devstate_t * ebus_p,dev_info_t * rdip,ebus_regspec_t * ebus_rp,vregspec_t * rp)550 ebus_apply_range(ebus_devstate_t *ebus_p, dev_info_t *rdip,
551 ebus_regspec_t *ebus_rp, vregspec_t *rp) {
552 int b, i;
553 int nrange = ebus_p->vrange_cnt;
554 uint32_t addr_offset, rng_caddr_hi, rng_caddr_low, rng_sz;
555 uint32_t req_addr = ebus_rp->addr_low;
556
557 uint32_t *rng_cell_p = (uint32_t *)ebus_p->vrangep;
558 int rng_rec_sz = ebus_p->ebus_paddr_cells + ebus_p->ebus_addr_cells +
559 ebus_p->ebus_sz_cells;
560 uint32_t *preg_cell_p = (uint32_t *)rp;
561 int preg_rec_sz = ebus_p->ebus_paddr_cells + ebus_p->ebus_psz_cells;
562
563 static char out_of_range[] =
564 "Out of range register specification from device node <%s>";
565
566 DBG3(D_MAP, ebus_p, "Range Matching Addr 0x%x.%x size 0x%x\n",
567 ebus_rp->addr_hi, req_addr, ebus_rp->size);
568
569 for (b = 0; b < nrange; b++, rng_cell_p += rng_rec_sz) {
570
571 rng_caddr_hi = rng_cell_p[0];
572 rng_caddr_low = rng_cell_p[1];
573 rng_sz = rng_cell_p[rng_rec_sz-1];
574
575 /* Check for correct space */
576 if (ebus_rp->addr_hi != rng_caddr_hi)
577 continue;
578
579 /* Detect whether request entirely fits within a range */
580 if (req_addr < rng_caddr_low)
581 continue;
582
583 if ((req_addr + ebus_rp->size - 1)
584 > (rng_caddr_low + rng_sz - 1))
585 continue;
586
587 addr_offset = req_addr - rng_caddr_low;
588
589 /* parent addr = child addr + offset from ranges */
590 for (i = 0; i < preg_rec_sz; i++)
591 preg_cell_p[i] = 0;
592
593 /* Copy the physical address */
594 for (i = 0; i < ebus_p->ebus_paddr_cells; i++)
595 preg_cell_p[i] = rng_cell_p[ebus_p->ebus_addr_cells+i];
596
597 preg_cell_p[ebus_p->ebus_paddr_cells-1] += addr_offset;
598
599 /* Copy the size */
600 preg_cell_p[preg_rec_sz-1] = min(ebus_rp->size,
601 rng_sz - addr_offset);
602
603 #ifdef DEBUG
604 ebus_vreg_dump(ebus_p, (vregspec_t *)preg_cell_p);
605 #endif /* DEBUG */
606
607 break;
608 }
609
610 if (b == nrange) {
611 cmn_err(CE_WARN, out_of_range, ddi_get_name(rdip));
612 return (DDI_ME_REGSPEC_RANGE);
613 }
614
615 return (DDI_SUCCESS);
616 }
617
618 static int
ebus_name_child(dev_info_t * child,char * name,int namelen)619 ebus_name_child(dev_info_t *child, char *name, int namelen)
620 {
621 ebus_regspec_t *ebus_rp;
622 int reglen;
623
624 /*
625 * Get the address portion of the node name based on the
626 * address/offset.
627 */
628 if (ddi_getlongprop(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
629 "reg", (caddr_t)&ebus_rp, ®len) != DDI_SUCCESS) {
630 return (DDI_FAILURE);
631 }
632
633 (void) snprintf(name, namelen, "%x,%x", ebus_rp->addr_hi,
634 ebus_rp->addr_low);
635 kmem_free(ebus_rp, reglen);
636
637 return (DDI_SUCCESS);
638 }
639
640 /*
641 * control ops entry point:
642 *
643 * Requests handled completely:
644 * DDI_CTLOPS_INITCHILD
645 * DDI_CTLOPS_UNINITCHILD
646 * DDI_CTLOPS_REPORTDEV
647 * DDI_CTLOPS_REGSIZE
648 * DDI_CTLOPS_NREGS
649 *
650 * All others passed to parent.
651 */
652 static int
ebus_ctlops(dev_info_t * dip,dev_info_t * rdip,ddi_ctl_enum_t op,void * arg,void * result)653 ebus_ctlops(dev_info_t *dip, dev_info_t *rdip,
654 ddi_ctl_enum_t op, void *arg, void *result)
655 {
656 #ifdef DEBUG
657 ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip));
658 #endif
659 ebus_regspec_t *ebus_rp;
660 int i, n;
661 char name[10];
662
663 switch (op) {
664 case DDI_CTLOPS_INITCHILD: {
665 dev_info_t *child = (dev_info_t *)arg;
666 /*
667 * Set the address portion of the node name based on the
668 * address/offset.
669 */
670 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_INITCHILD: rdip=%s%d\n",
671 ddi_get_name(child), ddi_get_instance(child));
672
673 if (ebus_name_child(child, name, 10) != DDI_SUCCESS) {
674 DBG(D_CTLOPS, ebus_p, "can't name child\n");
675 return (DDI_FAILURE);
676 }
677
678 ddi_set_name_addr(child, name);
679 ddi_set_parent_data(child, NULL);
680 return (DDI_SUCCESS);
681 }
682
683 case DDI_CTLOPS_UNINITCHILD:
684 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_UNINITCHILD: rdip=%s%d\n",
685 ddi_get_name((dev_info_t *)arg),
686 ddi_get_instance((dev_info_t *)arg));
687 ddi_set_name_addr((dev_info_t *)arg, NULL);
688 ddi_remove_minor_node((dev_info_t *)arg, NULL);
689 impl_rem_dev_props((dev_info_t *)arg);
690 return (DDI_SUCCESS);
691
692 case DDI_CTLOPS_REPORTDEV:
693
694 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REPORTDEV: rdip=%s%d\n",
695 ddi_get_name(rdip), ddi_get_instance(rdip));
696 cmn_err(CE_CONT, "?%s%d at %s%d: offset %s\n",
697 ddi_driver_name(rdip), ddi_get_instance(rdip),
698 ddi_driver_name(dip), ddi_get_instance(dip),
699 ddi_get_name_addr(rdip));
700 return (DDI_SUCCESS);
701
702 case DDI_CTLOPS_REGSIZE:
703
704 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_REGSIZE: rdip=%s%d\n",
705 ddi_get_name(rdip), ddi_get_instance(rdip));
706 if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) {
707 DBG(D_CTLOPS, ebus_p, "can't get reg property\n");
708 return (DDI_FAILURE);
709 }
710 n = i / sizeof (ebus_regspec_t);
711 if (*(int *)arg < 0 || *(int *)arg >= n) {
712 DBG(D_MAP, ebus_p, "rnumber out of range\n");
713 kmem_free(ebus_rp, i);
714 return (DDI_FAILURE);
715 }
716 *((off_t *)result) = ebus_rp[*(int *)arg].size;
717 kmem_free(ebus_rp, i);
718 return (DDI_SUCCESS);
719
720 case DDI_CTLOPS_NREGS:
721
722 DBG2(D_CTLOPS, ebus_p, "DDI_CTLOPS_NREGS: rdip=%s%d\n",
723 ddi_get_name(rdip), ddi_get_instance(rdip));
724 if (getprop(rdip, "reg", &ebus_rp, &i) != DDI_SUCCESS) {
725 DBG(D_CTLOPS, ebus_p, "can't get reg property\n");
726 return (DDI_FAILURE);
727 }
728 *((uint_t *)result) = i / sizeof (ebus_regspec_t);
729 kmem_free(ebus_rp, i);
730 return (DDI_SUCCESS);
731 }
732
733 /*
734 * Now pass the request up to our parent.
735 */
736 DBG2(D_CTLOPS, ebus_p, "passing request to parent: rdip=%s%d\n",
737 ddi_get_name(rdip), ddi_get_instance(rdip));
738 return (ddi_ctlops(dip, rdip, op, arg, result));
739 }
740
741 struct ebus_string_to_pil {
742 int8_t *string;
743 uint32_t pil;
744 };
745
746 static struct ebus_string_to_pil ebus_name_to_pil[] = {{"SUNW,CS4231", 9},
747 {"audio", 9},
748 {"fdthree", 8},
749 {"floppy", 8},
750 {"ecpp", 3},
751 {"parallel", 3},
752 {"su", 12},
753 {"se", 12},
754 {"serial", 12},
755 {"power", 14}};
756
757 static struct ebus_string_to_pil ebus_device_type_to_pil[] = {{"serial", 12},
758 {"block", 8}};
759
760 static int
ebus_intr_ops(dev_info_t * dip,dev_info_t * rdip,ddi_intr_op_t intr_op,ddi_intr_handle_impl_t * hdlp,void * result)761 ebus_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op,
762 ddi_intr_handle_impl_t *hdlp, void *result)
763 {
764 #ifdef DEBUG
765 ebus_devstate_t *ebus_p = get_ebus_soft_state(ddi_get_instance(dip));
766 #endif
767 int32_t i, max_children, max_device_types, len;
768 char *name_p, *device_type_p;
769
770 DBG1(D_INTR, ebus_p, "ebus_p 0x%p\n", ebus_p);
771
772 /*
773 * NOTE: These ops below will never be supported in this nexus
774 * driver, hence they always return immediately.
775 */
776 switch (intr_op) {
777 case DDI_INTROP_GETCAP:
778 *(int *)result = DDI_INTR_FLAG_LEVEL;
779 return (DDI_SUCCESS);
780 case DDI_INTROP_SUPPORTED_TYPES:
781 *(int *)result = i_ddi_get_intx_nintrs(rdip) ?
782 DDI_INTR_TYPE_FIXED : 0;
783 return (DDI_SUCCESS);
784 case DDI_INTROP_SETCAP:
785 case DDI_INTROP_SETMASK:
786 case DDI_INTROP_CLRMASK:
787 case DDI_INTROP_GETPENDING:
788 return (DDI_ENOTSUP);
789 default:
790 break;
791 }
792
793 if (hdlp->ih_pri)
794 goto done;
795
796 /*
797 * This is a hack to set the PIL for the devices under ebus.
798 * We first look up a device by it's specific name, if we can't
799 * match the name, we try and match it's device_type property.
800 * Lastly we default a PIL level of 1.
801 */
802 name_p = ddi_node_name(rdip);
803 max_children = sizeof (ebus_name_to_pil) /
804 sizeof (struct ebus_string_to_pil);
805
806 for (i = 0; i < max_children; i++) {
807 if (strcmp(ebus_name_to_pil[i].string, name_p) == 0) {
808 DBG2(D_INTR, ebus_p, "child name %s; match PIL %d\n",
809 ebus_name_to_pil[i].string,
810 ebus_name_to_pil[i].pil);
811
812 hdlp->ih_pri = ebus_name_to_pil[i].pil;
813 goto done;
814 }
815 }
816
817 if (ddi_getlongprop(DDI_DEV_T_ANY, rdip, DDI_PROP_DONTPASS,
818 "device_type", (caddr_t)&device_type_p, &len) == DDI_SUCCESS) {
819
820 max_device_types = sizeof (ebus_device_type_to_pil) /
821 sizeof (struct ebus_string_to_pil);
822
823 for (i = 0; i < max_device_types; i++) {
824 if (strcmp(ebus_device_type_to_pil[i].string,
825 device_type_p) == 0) {
826 DBG2(D_INTR, ebus_p, "Device type %s; match "
827 "PIL %d\n", ebus_device_type_to_pil[i].
828 string, ebus_device_type_to_pil[i].pil);
829
830 hdlp->ih_pri = ebus_device_type_to_pil[i].pil;
831 break;
832 }
833 }
834
835 kmem_free(device_type_p, len);
836 }
837
838 /*
839 * If we get here, we need to set a default value
840 * for the PIL.
841 */
842 if (hdlp->ih_pri == 0) {
843 hdlp->ih_pri = 1;
844
845 cmn_err(CE_WARN, "%s%d assigning default interrupt level %d "
846 "for device %s%d", ddi_driver_name(dip),
847 ddi_get_instance(dip), hdlp->ih_pri, ddi_driver_name(rdip),
848 ddi_get_instance(rdip));
849 }
850
851 done:
852 /* Pass up the request to our parent. */
853 return (i_ddi_intr_ops(dip, rdip, intr_op, hdlp, result));
854 }
855
856 /*
857 * ebus_config: setup pci config space registers:
858 * enable bus mastering, memory access and error reporting
859 */
860 static int
ebus_config(ebus_devstate_t * ebus_p)861 ebus_config(ebus_devstate_t *ebus_p)
862 {
863 ddi_acc_handle_t conf_handle;
864 uint16_t comm;
865 dev_info_t *dip = ebus_p->dip;
866 char *devtype_str;
867 int devtype_len;
868
869 if (ddi_getlongprop(DDI_DEV_T_ANY, ddi_get_parent(dip),
870 DDI_PROP_DONTPASS, "device_type", (caddr_t)&devtype_str,
871 &devtype_len) != DDI_SUCCESS) {
872 cmn_err(CE_WARN, "Can't get %s device_type property",
873 ddi_get_name(ddi_get_parent(dip)));
874
875 return (DDI_FAILURE);
876 }
877
878 comm = strcmp(devtype_str, "pci");
879 kmem_free(devtype_str, devtype_len);
880
881 if (comm)
882 return (DDI_SUCCESS);
883
884 /*
885 * Make sure the master enable and memory access enable
886 * bits are set in the config command register.
887 */
888 if (pci_config_setup(ebus_p->dip, &conf_handle) != DDI_SUCCESS)
889 return (DDI_FAILURE);
890
891 comm = pci_config_get16(conf_handle, PCI_CONF_COMM),
892 #ifdef DEBUG
893 DBG1(D_MAP, ebus_p, "command register was 0x%x\n", comm);
894 #endif
895 comm |= (PCI_COMM_ME|PCI_COMM_MAE|PCI_COMM_SERR_ENABLE|
896 PCI_COMM_PARITY_DETECT);
897 pci_config_put16(conf_handle, PCI_CONF_COMM, comm),
898 #ifdef DEBUG
899 DBG1(D_MAP, ebus_p, "command register is now 0x%x\n", comm);
900 #endif
901 pci_config_put8(conf_handle, PCI_CONF_CACHE_LINESZ,
902 (uchar_t)ebus_cache_line_size);
903 pci_config_put8(conf_handle, PCI_CONF_LATENCY_TIMER,
904 (uchar_t)ebus_latency_timer);
905 pci_config_teardown(&conf_handle);
906 return (DDI_SUCCESS);
907 }
908
909 #ifdef DEBUG
910 extern void prom_printf(const char *, ...);
911
912 static void
ebus_debug(uint_t flag,ebus_devstate_t * ebus_p,char * fmt,uintptr_t a1,uintptr_t a2,uintptr_t a3,uintptr_t a4,uintptr_t a5)913 ebus_debug(uint_t flag, ebus_devstate_t *ebus_p, char *fmt,
914 uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5)
915 {
916 char *s;
917
918 if (ebus_debug_flags & flag) {
919 switch (flag) {
920 case D_ATTACH:
921 s = "attach"; break;
922 case D_DETACH:
923 s = "detach"; break;
924 case D_MAP:
925 s = "map"; break;
926 case D_CTLOPS:
927 s = "ctlops"; break;
928 case D_INTR:
929 s = "intr"; break;
930 }
931 if (ebus_p)
932 cmn_err(CE_CONT, "%s%d: %s: ",
933 ddi_get_name(ebus_p->dip),
934 ddi_get_instance(ebus_p->dip), s);
935 else
936 cmn_err(CE_CONT, "ebus: ");
937 cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5);
938 }
939 }
940
941 static void
ebus_vreg_dump(ebus_devstate_t * ebus_p,vregspec_t * rp)942 ebus_vreg_dump(ebus_devstate_t *ebus_p, vregspec_t *rp)
943 {
944 if (ebus_p->ebus_paddr_cells == 3) {
945 DBG5(D_MAP, ebus_p, "(%x,%x,%x)(%x,%x)\n",
946 rp->pci_regspec.pci_phys_hi,
947 rp->pci_regspec.pci_phys_mid,
948 rp->pci_regspec.pci_phys_low,
949 rp->pci_regspec.pci_size_hi,
950 rp->pci_regspec.pci_size_low);
951 } else if (ebus_p->ebus_paddr_cells == 2) {
952 DBG3(D_MAP, ebus_p, "%x,%x,%x\n",
953 rp->jbus_regspec.regspec_bustype,
954 rp->jbus_regspec.regspec_addr,
955 rp->jbus_regspec.regspec_size);
956 }
957 }
958 #endif /* DEBUG */
959
960 /* ARGSUSED3 */
961 static int
ebus_open(dev_t * devp,int flags,int otyp,cred_t * credp)962 ebus_open(dev_t *devp, int flags, int otyp, cred_t *credp)
963 {
964 ebus_devstate_t *ebus_p;
965
966 /*
967 * Make sure the open is for the right file type.
968 */
969 if (otyp != OTYP_CHR)
970 return (EINVAL);
971
972 /*
973 * Get the soft state structure for the device.
974 */
975 ebus_p = get_ebus_soft_state(getminor(*devp));
976 if (ebus_p == NULL)
977 return (ENXIO);
978
979 /*
980 * Handle the open by tracking the device state.
981 */
982 mutex_enter(&ebus_p->ebus_mutex);
983 if (flags & FEXCL) {
984 if (ebus_p->ebus_soft_state != EBUS_SOFT_STATE_CLOSED) {
985 mutex_exit(&ebus_p->ebus_mutex);
986 return (EBUSY);
987 }
988 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_OPEN_EXCL;
989 } else {
990 if (ebus_p->ebus_soft_state == EBUS_SOFT_STATE_OPEN_EXCL) {
991 mutex_exit(&ebus_p->ebus_mutex);
992 return (EBUSY);
993 }
994 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_OPEN;
995 }
996 mutex_exit(&ebus_p->ebus_mutex);
997 return (0);
998 }
999
1000
1001 /* ARGSUSED */
1002 static int
ebus_close(dev_t dev,int flags,int otyp,cred_t * credp)1003 ebus_close(dev_t dev, int flags, int otyp, cred_t *credp)
1004 {
1005 ebus_devstate_t *ebus_p;
1006
1007 if (otyp != OTYP_CHR)
1008 return (EINVAL);
1009
1010 ebus_p = get_ebus_soft_state(getminor(dev));
1011 if (ebus_p == NULL)
1012 return (ENXIO);
1013
1014 mutex_enter(&ebus_p->ebus_mutex);
1015 ebus_p->ebus_soft_state = EBUS_SOFT_STATE_CLOSED;
1016 mutex_exit(&ebus_p->ebus_mutex);
1017 return (0);
1018 }
1019
1020
1021 /*
1022 * ebus_ioctl: devctl hotplug controls
1023 */
1024 /* ARGSUSED */
1025 static int
ebus_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)1026 ebus_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1027 int *rvalp)
1028 {
1029 ebus_devstate_t *ebus_p;
1030 dev_info_t *self;
1031 struct devctl_iocdata *dcp;
1032 uint_t bus_state;
1033 int rv = 0;
1034
1035 ebus_p = get_ebus_soft_state(getminor(dev));
1036 if (ebus_p == NULL)
1037 return (ENXIO);
1038
1039 self = ebus_p->dip;
1040
1041 /*
1042 * We can use the generic implementation for these ioctls
1043 */
1044 switch (cmd) {
1045 case DEVCTL_DEVICE_GETSTATE:
1046 case DEVCTL_DEVICE_ONLINE:
1047 case DEVCTL_DEVICE_OFFLINE:
1048 case DEVCTL_BUS_GETSTATE:
1049 return (ndi_devctl_ioctl(self, cmd, arg, mode, 0));
1050 }
1051
1052 /*
1053 * read devctl ioctl data
1054 */
1055 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS)
1056 return (EFAULT);
1057
1058 switch (cmd) {
1059
1060 case DEVCTL_DEVICE_RESET:
1061 rv = ENOTSUP;
1062 break;
1063
1064 case DEVCTL_BUS_QUIESCE:
1065 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1066 if (bus_state == BUS_QUIESCED)
1067 break;
1068 (void) ndi_set_bus_state(self, BUS_QUIESCED);
1069 break;
1070
1071 case DEVCTL_BUS_UNQUIESCE:
1072 if (ndi_get_bus_state(self, &bus_state) == NDI_SUCCESS)
1073 if (bus_state == BUS_ACTIVE)
1074 break;
1075 (void) ndi_set_bus_state(self, BUS_ACTIVE);
1076 break;
1077
1078 case DEVCTL_BUS_RESET:
1079 rv = ENOTSUP;
1080 break;
1081
1082 case DEVCTL_BUS_RESETALL:
1083 rv = ENOTSUP;
1084 break;
1085
1086 default:
1087 rv = ENOTTY;
1088 }
1089
1090 ndi_dc_freehdl(dcp);
1091 return (rv);
1092 }
1093