1843e1988Sjohnlev /* 2843e1988Sjohnlev * CDDL HEADER START 3843e1988Sjohnlev * 4843e1988Sjohnlev * The contents of this file are subject to the terms of the 5843e1988Sjohnlev * Common Development and Distribution License (the "License"). 6843e1988Sjohnlev * You may not use this file except in compliance with the License. 7843e1988Sjohnlev * 8843e1988Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9843e1988Sjohnlev * or http://www.opensolaris.org/os/licensing. 10843e1988Sjohnlev * See the License for the specific language governing permissions 11843e1988Sjohnlev * and limitations under the License. 12843e1988Sjohnlev * 13843e1988Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each 14843e1988Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15843e1988Sjohnlev * If applicable, add the following below this CDDL HEADER, with the 16843e1988Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying 17843e1988Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner] 18843e1988Sjohnlev * 19843e1988Sjohnlev * CDDL HEADER END 20843e1988Sjohnlev */ 21843e1988Sjohnlev /* 22*19397407SSherry Moore * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23843e1988Sjohnlev * Use is subject to license terms. 24843e1988Sjohnlev */ 25843e1988Sjohnlev 26843e1988Sjohnlev 27843e1988Sjohnlev /* 28843e1988Sjohnlev * CPU nexus driver 29843e1988Sjohnlev */ 30843e1988Sjohnlev 31843e1988Sjohnlev #include <sys/types.h> 32843e1988Sjohnlev #include <sys/param.h> 33843e1988Sjohnlev #include <sys/conf.h> 34843e1988Sjohnlev #include <sys/devops.h> 35843e1988Sjohnlev #include <sys/modctl.h> 36843e1988Sjohnlev #include <sys/cmn_err.h> 37843e1988Sjohnlev #include <sys/ddi.h> 38843e1988Sjohnlev #include <sys/sunddi.h> 39843e1988Sjohnlev #include <sys/sunndi.h> 40843e1988Sjohnlev 41843e1988Sjohnlev static int cpunex_attach(dev_info_t *, ddi_attach_cmd_t); 42843e1988Sjohnlev static int cpunex_detach(dev_info_t *, ddi_detach_cmd_t); 43843e1988Sjohnlev static int cpunex_bus_ctl(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 44843e1988Sjohnlev void *, void *); 45843e1988Sjohnlev 46843e1988Sjohnlev static struct bus_ops cpunex_bus_ops = { 47843e1988Sjohnlev BUSO_REV, 48843e1988Sjohnlev nullbusmap, 49843e1988Sjohnlev NULL, 50843e1988Sjohnlev NULL, 51843e1988Sjohnlev NULL, 52843e1988Sjohnlev i_ddi_map_fault, 53843e1988Sjohnlev ddi_no_dma_map, 54843e1988Sjohnlev ddi_no_dma_allochdl, 55843e1988Sjohnlev ddi_no_dma_freehdl, 56843e1988Sjohnlev ddi_no_dma_bindhdl, 57843e1988Sjohnlev ddi_no_dma_unbindhdl, 58843e1988Sjohnlev ddi_no_dma_flush, 59843e1988Sjohnlev ddi_no_dma_win, 60843e1988Sjohnlev ddi_no_dma_mctl, 61843e1988Sjohnlev cpunex_bus_ctl, 62843e1988Sjohnlev ddi_bus_prop_op, 63843e1988Sjohnlev }; 64843e1988Sjohnlev 65843e1988Sjohnlev static struct dev_ops cpunex_ops = { 66843e1988Sjohnlev DEVO_REV, 67843e1988Sjohnlev 0, 68843e1988Sjohnlev ddi_no_info, 69843e1988Sjohnlev nulldev, 70843e1988Sjohnlev nulldev, 71843e1988Sjohnlev cpunex_attach, 72843e1988Sjohnlev cpunex_detach, 73843e1988Sjohnlev nodev, 74843e1988Sjohnlev NULL, 75843e1988Sjohnlev &cpunex_bus_ops, 76*19397407SSherry Moore NULL, 77*19397407SSherry Moore ddi_quiesce_not_needed, /* quiesce */ 78843e1988Sjohnlev }; 79843e1988Sjohnlev 80843e1988Sjohnlev static struct modldrv modldrv = { 81843e1988Sjohnlev &mod_driverops, 82*19397407SSherry Moore "cpu nexus driver", 83843e1988Sjohnlev &cpunex_ops 84843e1988Sjohnlev }; 85843e1988Sjohnlev 86843e1988Sjohnlev static struct modlinkage modlinkage = { 87843e1988Sjohnlev MODREV_1, 88843e1988Sjohnlev &modldrv, 89843e1988Sjohnlev NULL 90843e1988Sjohnlev }; 91843e1988Sjohnlev 92843e1988Sjohnlev /* 93843e1988Sjohnlev * cpunex_bus_ctl() 94843e1988Sjohnlev * This routine implements nexus bus ctl operations. Of importance are 95843e1988Sjohnlev * DDI_CTLOPS_REPORTDEV, DDI_CTLOPS_INITCHILD, DDI_CTLOPS_UNINITCHILD 96843e1988Sjohnlev * and DDI_CTLOPS_POWER. For DDI_CTLOPS_INITCHILD, it tries to lookup 97843e1988Sjohnlev * reg property on the child node and builds and sets the name. 98843e1988Sjohnlev */ 99843e1988Sjohnlev static int 100843e1988Sjohnlev cpunex_bus_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t op, void *arg, 101843e1988Sjohnlev void *result) 102843e1988Sjohnlev { 103843e1988Sjohnlev switch (op) { 104843e1988Sjohnlev case DDI_CTLOPS_REPORTDEV: { 105843e1988Sjohnlev dev_info_t *pdip = ddi_get_parent(rdip); 106843e1988Sjohnlev cmn_err(CE_CONT, "?%s%d at %s%d", 107843e1988Sjohnlev ddi_node_name(rdip), ddi_get_instance(rdip), 108843e1988Sjohnlev ddi_node_name(pdip), ddi_get_instance(pdip)); 109843e1988Sjohnlev return (DDI_SUCCESS); 110843e1988Sjohnlev } 111843e1988Sjohnlev 112843e1988Sjohnlev case DDI_CTLOPS_INITCHILD: { 113843e1988Sjohnlev dev_info_t *cdip = (dev_info_t *)arg; 114843e1988Sjohnlev int i; 115843e1988Sjohnlev char caddr[MAXNAMELEN]; 116843e1988Sjohnlev 117843e1988Sjohnlev i = ddi_prop_get_int(DDI_DEV_T_ANY, cdip, 118843e1988Sjohnlev DDI_PROP_DONTPASS, "reg", -1); 119843e1988Sjohnlev 120843e1988Sjohnlev if (i == -1) { 121843e1988Sjohnlev cmn_err(CE_NOTE, "!%s(%d): \"reg\" property " 122843e1988Sjohnlev "not found", ddi_node_name(cdip), 123843e1988Sjohnlev ddi_get_instance(cdip)); 124843e1988Sjohnlev return (DDI_NOT_WELL_FORMED); 125843e1988Sjohnlev } 126843e1988Sjohnlev 127843e1988Sjohnlev (void) sprintf(caddr, "%d", i); 128843e1988Sjohnlev ddi_set_name_addr(cdip, caddr); 129843e1988Sjohnlev 130843e1988Sjohnlev return (DDI_SUCCESS); 131843e1988Sjohnlev } 132843e1988Sjohnlev 133843e1988Sjohnlev case DDI_CTLOPS_UNINITCHILD: { 134843e1988Sjohnlev ddi_prop_remove_all((dev_info_t *)arg); 135843e1988Sjohnlev ddi_set_name_addr((dev_info_t *)arg, NULL); 136843e1988Sjohnlev return (DDI_SUCCESS); 137843e1988Sjohnlev } 138843e1988Sjohnlev 139843e1988Sjohnlev default: { 140843e1988Sjohnlev return (ddi_ctlops(dip, rdip, op, arg, result)); 141843e1988Sjohnlev } 142843e1988Sjohnlev } 143843e1988Sjohnlev } 144843e1988Sjohnlev 145843e1988Sjohnlev /*ARGSUSED*/ 146843e1988Sjohnlev static int 147843e1988Sjohnlev cpunex_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 148843e1988Sjohnlev { 149843e1988Sjohnlev switch (cmd) { 150843e1988Sjohnlev case DDI_ATTACH: 151843e1988Sjohnlev case DDI_RESUME: 152843e1988Sjohnlev break; 153843e1988Sjohnlev default: 154843e1988Sjohnlev return (DDI_FAILURE); 155843e1988Sjohnlev } 156843e1988Sjohnlev 157843e1988Sjohnlev return (DDI_SUCCESS); 158843e1988Sjohnlev } 159843e1988Sjohnlev 160843e1988Sjohnlev /*ARGSUSED*/ 161843e1988Sjohnlev static int 162843e1988Sjohnlev cpunex_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 163843e1988Sjohnlev { 164843e1988Sjohnlev switch (cmd) { 165843e1988Sjohnlev case DDI_DETACH: 166843e1988Sjohnlev case DDI_SUSPEND: 167843e1988Sjohnlev break; 168843e1988Sjohnlev default: 169843e1988Sjohnlev return (DDI_FAILURE); 170843e1988Sjohnlev } 171843e1988Sjohnlev 172843e1988Sjohnlev return (DDI_SUCCESS); 173843e1988Sjohnlev } 174843e1988Sjohnlev 175843e1988Sjohnlev int 176843e1988Sjohnlev _init(void) 177843e1988Sjohnlev { 178843e1988Sjohnlev int error; 179843e1988Sjohnlev 180843e1988Sjohnlev error = mod_install(&modlinkage); 181843e1988Sjohnlev return (error); 182843e1988Sjohnlev } 183843e1988Sjohnlev 184843e1988Sjohnlev int 185843e1988Sjohnlev _fini(void) 186843e1988Sjohnlev { 187843e1988Sjohnlev int error; 188843e1988Sjohnlev 189843e1988Sjohnlev error = mod_remove(&modlinkage); 190843e1988Sjohnlev return (error); 191843e1988Sjohnlev } 192843e1988Sjohnlev 193843e1988Sjohnlev int 194843e1988Sjohnlev _info(struct modinfo *modinfop) 195843e1988Sjohnlev { 196843e1988Sjohnlev return (mod_info(&modlinkage, modinfop)); 197843e1988Sjohnlev } 198