1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#ifndef _SYS_PSHOT_H 28#define _SYS_PSHOT_H 29 30#pragma ident "%Z%%M% %I% %E% SMI" 31 32#ifdef __cplusplus 33extern "C" { 34#endif 35 36#include <sys/sunndi.h> 37 38/* 39 * user accessable features 40 */ 41 42/* determines max pshot_minor allocation per softstate */ 43#define PSHOT_MAX_MINOR_PERINST 2 44#define PSHOT_MAX_MINOR_NAMELEN 16 45 46#define PSHOT_NODENAME_DEVCTL "devctl" 47#define PSHOT_NODENAME_TESTCTL "testctl" 48 49#define PSHOT_PROP_DEVNAME "dev-name" 50#define PSHOT_PROP_DEVNT "dev-nt" 51#define PSHOT_PROP_DEVCOMPAT "dev-compat" 52 53 54#ifdef _KERNEL 55 56 57#define PARENT_IS_PSHOT(self) \ 58 (ddi_driver_major(self) == ddi_driver_major(ddi_get_parent(self))) 59 60 61static int pshot_debug = 0; 62static int pshot_event_test_enable = 0; 63 64#ifdef DEBUG 65#define pshot_debug pshot_debug_on 66#define pshot_event_test_enable pshot_event_test_on 67 68static int pshot_debug_on = 0; 69static int pshot_event_test_on = 0; 70 71#endif 72 73#define PSHOT_MAX_CBCACHE 6 74#define PSHOT_MAX_TSTCACHE 8 75 76/* 77 * soft state and minor node management 78 * (includes user features above) 79 */ 80 81/* 82 * a "node number" is currently implemented as an index into a pshot_minor_t 83 * array, therefore the max must be less than PSHOT_MAX_MINOR_PERINST and 84 * ideally, the minor array should be fully populated, with a node number 85 * defined for each index 86 */ 87#define PSHOT_NODENUM_DEVCTL 0 88#define PSHOT_NODENUM_TESTCTL 1 89#define PSHOT_MAX_NODENUM PSHOT_NODENUM_TESTCTL 90 91typedef struct pshot_minor pshot_minor_t; 92typedef struct pshot pshot_t; 93 94struct pshot_minor { 95 pshot_t *pshot; 96 minor_t minor; 97 char name[PSHOT_MAX_MINOR_NAMELEN]; 98}; 99 100struct pshot { 101 kmutex_t lock; 102 uint_t state; 103 dev_info_t *dip; 104 int instance; 105 ndi_event_hdl_t ndi_event_hdl; 106 ndi_event_set_t ndi_events; 107 ddi_iblock_cookie_t iblock_cookie; 108 ddi_callback_id_t callback_cache[PSHOT_MAX_CBCACHE]; 109 ddi_callback_id_t test_callback_cache[PSHOT_MAX_TSTCACHE]; 110 111 pshot_minor_t nodes[PSHOT_MAX_MINOR_PERINST]; 112 int level; /* pm power level */ 113 int busy; /* pm busy state */ 114 int busy_ioctl; /* track busy and idle ioctl calls */ 115}; 116 117 118static size_t pshot_numbits(size_t); 119static minor_t pshot_minor_encode(int, minor_t); 120static int pshot_minor_decode_inst(minor_t); 121static minor_t pshot_minor_decode_nodenum(minor_t); 122 123#define PSHOT_NODENUM_BITS() pshot_numbits(PSHOT_MAX_MINOR_PERINST) 124 125/* 126 * children device configuration 127 */ 128 129typedef struct pshot_device { 130 char *name; 131 char *nodetype; 132 char *compat; 133} pshot_device_t; 134 135#define PSHOT_DEV_ANYNT 0x1 136 137static char *pshot_str2nt(char *); 138static pshot_device_t *pshot_devices_from_props(dev_info_t *, size_t *, int); 139static void pshot_devices_free(pshot_device_t *, size_t); 140static int pshot_devices_setup(dev_info_t *); 141static int pshot_devices_grow(pshot_device_t **, size_t, 142 const pshot_device_t *, size_t); 143 144 145/* 146 * softstate state bits 147 */ 148#define IS_OPEN 0x0001 149#define IS_OPEN_EXCL 0x0002 150#define DEV_RESET_PENDING 0x0004 151#define BUS_RESET_PENDING 0x0008 152#define POWER_FLAG 0x0010 153#define FAIL_SUSPEND_FLAG 0x0020 154#define STRICT_PARENT 0x0040 155#define NO_INVOL_FLAG 0x0080 156#define PM_SUPPORTED 0x0100 157 158/* 159 * Leaf ops (supports hotplug controls to the device) 160 */ 161static int pshot_open(dev_t *, int, int, cred_t *); 162static int pshot_close(dev_t, int, int, cred_t *); 163static int pshot_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 164static int pshot_probe(dev_info_t *); 165static int pshot_attach(dev_info_t *, ddi_attach_cmd_t); 166static int pshot_detach(dev_info_t *, ddi_detach_cmd_t); 167static int pshot_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 168static int pshot_power(dev_info_t *dip, int cmpt, int level); 169 170static int pshot_devctl(pshot_t *, minor_t, int, intptr_t, int, cred_t *, 171 int *); 172static int pshot_testctl(pshot_t *, minor_t, int, intptr_t, int, cred_t *, 173 int *); 174 175/* 176 * Event handling prototype support. 177 */ 178#define PSHOT_EVENT_NAME_DEV_OFFLINE "pshot_dev_offline" 179#define PSHOT_EVENT_NAME_DEV_RESET "pshot_dev_reset" 180#define PSHOT_EVENT_NAME_BUS_RESET "pshot_bus_reset" 181#define PSHOT_EVENT_NAME_BUS_QUIESCE "pshot_bus_quiesce" 182#define PSHOT_EVENT_NAME_BUS_UNQUIESCE "pshot_bus_unquiesce" 183#define PSHOT_EVENT_NAME_BUS_TEST_POST "pshot_bus_test_post" 184#define PSHOT_EVENT_NAME_DEBUG_SET "pshot_debug_set" 185#define PSHOT_EVENT_NAME_SUB_RESET "pshot_sub_reset" 186 /* for hash sanity check */ 187 188#define PSHOT_EVENT_TAG_OFFLINE 0 189#define PSHOT_EVENT_TAG_DEV_RESET 1 190#define PSHOT_EVENT_TAG_BUS_RESET 2 191#define PSHOT_EVENT_TAG_BUS_QUIESCE 3 192#define PSHOT_EVENT_TAG_BUS_UNQUIESCE 4 193#define PSHOT_EVENT_TAG_TEST_POST 5 194 195typedef struct pshot_event_callback { 196 dev_info_t *dip; 197 int (*callback)(); 198 void *arg; 199 struct pshot_event_callback *next; 200} ps_callback_t; 201 202 203static void pshot_event_cb(dev_info_t *dip, ddi_eventcookie_t cookie, 204 void *arg, void *bus_impldata); 205 206static int pshot_event(pshot_t *pshot, int event_tag, dev_info_t *child, 207 void *bus_impldata); 208 209#ifdef DEBUG 210static void pshot_event_cb_test(dev_info_t *dip, ddi_eventcookie_t cookie, 211 void *arg, void *bus_impldata); 212static void pshot_event_test(void *arg); 213static void pshot_event_test_post_one(void *arg); 214#endif 215 216/* event busops */ 217static int pshot_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, 218 char *name, ddi_eventcookie_t *event_cookiep); 219static int pshot_add_eventcall(dev_info_t *dip, dev_info_t *rdip, 220 ddi_eventcookie_t eventid, void (*callback)(), void *arg, 221 ddi_callback_id_t *cb_id); 222static int pshot_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id); 223static int pshot_post_event(dev_info_t *dip, dev_info_t *rdip, 224 ddi_eventcookie_t eventid, void *impl_data); 225 226/* function prototypes */ 227static int pshot_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop, 228 void *arg, void *result); 229static int pshot_initchild(dev_info_t *, dev_info_t *); 230static int pshot_uninitchild(dev_info_t *, dev_info_t *); 231static int pshot_bus_config(dev_info_t *, uint_t, 232 ddi_bus_config_op_t, void *, dev_info_t **); 233static int pshot_bus_unconfig(dev_info_t *, uint_t, 234 ddi_bus_config_op_t, void *); 235static int pshot_bus_config_setup_nexus(dev_info_t *, char *cname, char *caddr); 236static int pshot_bus_config_setup_leaf(dev_info_t *, char *cname, char *caddr); 237static int pshot_bus_config_test_specials(dev_info_t *parent, 238 char *devname, char *cname, char *caddr); 239static int pshot_bus_introp(dev_info_t *, dev_info_t *, ddi_intr_op_t, 240 ddi_intr_handle_impl_t *, void *); 241 242static void pshot_setup_autoattach(dev_info_t *); 243static int pshot_bus_power(dev_info_t *dip, void *impl_arg, 244 pm_bus_power_op_t op, void *arg, void *result); 245static void pshot_nexus_properties(dev_info_t *, dev_info_t *, char *, char *); 246static void pshot_leaf_properties(dev_info_t *, dev_info_t *, char *, char *); 247 248 249#endif /* _KERNEL */ 250 251 252#ifdef __cplusplus 253} 254#endif 255 256#endif /* _SYS_PSHOT_H */ 257