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