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 33 extern "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 61 static int pshot_debug = 0; 62 static 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 68 static int pshot_debug_on = 0; 69 static 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 91 typedef struct pshot_minor pshot_minor_t; 92 typedef struct pshot pshot_t; 93 94 struct pshot_minor { 95 pshot_t *pshot; 96 minor_t minor; 97 char name[PSHOT_MAX_MINOR_NAMELEN]; 98 }; 99 100 struct 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 118 static size_t pshot_numbits(size_t); 119 static minor_t pshot_minor_encode(int, minor_t); 120 static int pshot_minor_decode_inst(minor_t); 121 static 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 129 typedef struct pshot_device { 130 char *name; 131 char *nodetype; 132 char *compat; 133 } pshot_device_t; 134 135 #define PSHOT_DEV_ANYNT 0x1 136 137 static char *pshot_str2nt(char *); 138 static pshot_device_t *pshot_devices_from_props(dev_info_t *, size_t *, int); 139 static void pshot_devices_free(pshot_device_t *, size_t); 140 static int pshot_devices_setup(dev_info_t *); 141 static 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 */ 161 static int pshot_open(dev_t *, int, int, cred_t *); 162 static int pshot_close(dev_t, int, int, cred_t *); 163 static int pshot_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 164 static int pshot_probe(dev_info_t *); 165 static int pshot_attach(dev_info_t *, ddi_attach_cmd_t); 166 static int pshot_detach(dev_info_t *, ddi_detach_cmd_t); 167 static int pshot_info(dev_info_t *, ddi_info_cmd_t, void *, void **); 168 static int pshot_power(dev_info_t *dip, int cmpt, int level); 169 170 static int pshot_devctl(pshot_t *, minor_t, int, intptr_t, int, cred_t *, 171 int *); 172 static 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 195 typedef 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 203 static void pshot_event_cb(dev_info_t *dip, ddi_eventcookie_t cookie, 204 void *arg, void *bus_impldata); 205 206 static int pshot_event(pshot_t *pshot, int event_tag, dev_info_t *child, 207 void *bus_impldata); 208 209 #ifdef DEBUG 210 static void pshot_event_cb_test(dev_info_t *dip, ddi_eventcookie_t cookie, 211 void *arg, void *bus_impldata); 212 static void pshot_event_test(void *arg); 213 static void pshot_event_test_post_one(void *arg); 214 #endif 215 216 /* event busops */ 217 static int pshot_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, 218 char *name, ddi_eventcookie_t *event_cookiep); 219 static 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); 222 static int pshot_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id); 223 static int pshot_post_event(dev_info_t *dip, dev_info_t *rdip, 224 ddi_eventcookie_t eventid, void *impl_data); 225 226 /* function prototypes */ 227 static int pshot_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop, 228 void *arg, void *result); 229 static int pshot_initchild(dev_info_t *, dev_info_t *); 230 static int pshot_uninitchild(dev_info_t *, dev_info_t *); 231 static int pshot_bus_config(dev_info_t *, uint_t, 232 ddi_bus_config_op_t, void *, dev_info_t **); 233 static int pshot_bus_unconfig(dev_info_t *, uint_t, 234 ddi_bus_config_op_t, void *); 235 static int pshot_bus_config_setup_nexus(dev_info_t *, char *cname, char *caddr); 236 static int pshot_bus_config_setup_leaf(dev_info_t *, char *cname, char *caddr); 237 static int pshot_bus_config_test_specials(dev_info_t *parent, 238 char *devname, char *cname, char *caddr); 239 static int pshot_bus_introp(dev_info_t *, dev_info_t *, ddi_intr_op_t, 240 ddi_intr_handle_impl_t *, void *); 241 242 static void pshot_setup_autoattach(dev_info_t *); 243 static int pshot_bus_power(dev_info_t *dip, void *impl_arg, 244 pm_bus_power_op_t op, void *arg, void *result); 245 static void pshot_nexus_properties(dev_info_t *, dev_info_t *, char *, char *); 246 static 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