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 2002-2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_1394_TARGETS_AV1394_IMPL_H 28 #define _SYS_1394_TARGETS_AV1394_IMPL_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /* 33 * av1394 driver definitions 34 */ 35 36 #include <sys/note.h> 37 #include <sys/ddi.h> 38 #include <sys/sunddi.h> 39 #include <sys/strsun.h> 40 #include <sys/mkdev.h> 41 #include <sys/tnf_probe.h> 42 #include <sys/av/iec61883.h> 43 #include <sys/1394/t1394.h> 44 #include <sys/1394/targets/av1394/av1394_isoch.h> 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 /* 51 * double-linked list 52 */ 53 typedef struct av1394_list_item_s { 54 struct av1394_list_item_s *i_next; 55 struct av1394_list_item_s *i_prev; 56 } av1394_list_item_t; 57 58 typedef struct av1394_list_s { 59 av1394_list_item_t *l_head; /* first item */ 60 av1394_list_item_t *l_tail; /* last item */ 61 int l_cnt; /* number of items */ 62 } av1394_list_t; 63 64 65 /* 66 * queue 67 */ 68 typedef struct av1394_queue_s { 69 kmutex_t q_mutex; /* mutex */ 70 av1394_list_t q_list; /* list of mblk's */ 71 int q_size; /* current data size */ 72 int q_max; /* max data size */ 73 kcondvar_t q_cv; /* data cv */ 74 } av1394_queue_t; 75 76 _NOTE(MUTEX_PROTECTS_DATA(av1394_queue_s::q_mutex, av1394_queue_s)) 77 78 #define AV1394_ENTERQ(q) mutex_enter(&(q)->q_mutex) 79 #define AV1394_LEAVEQ(q) mutex_exit(&(q)->q_mutex) 80 81 82 /* 83 * asynchronous module definitions 84 * 85 * 86 * command structure 87 */ 88 typedef struct av1394_fcp_cmd_s { 89 cmd1394_cmd_t *fc_cmd; /* 1394 command */ 90 boolean_t fc_busy; /* command is in use */ 91 kcondvar_t fc_busy_cv; /* busy cv */ 92 boolean_t fc_xmit; /* transmit in progress */ 93 kcondvar_t fc_xmit_cv; /* transmit completion cv */ 94 } av1394_fcp_cmd_t; 95 96 /* 97 * per-instance FCP structure 98 */ 99 typedef struct av1394_fcp_s { 100 av1394_fcp_cmd_t fcp_cmd; /* outgoing FCP command */ 101 av1394_fcp_cmd_t fcp_resp; /* outgoing FCP response */ 102 } av1394_fcp_t; 103 104 enum { 105 AV1394_FCP_ARQ_LEN_MAX = 0x200 /* maximum FCP ARQ length */ 106 }; 107 108 109 /* 110 * configuration ROM 111 */ 112 #define AV1394_CFGROM_INFO_LEN_ADDR (IEEE1394_CONFIG_ROM_ADDR + 0x00) 113 #define AV1394_CFGROM_BUS_NAME_ADDR (IEEE1394_CONFIG_ROM_ADDR + 0x04) 114 #define AV1394_CFGROM_EUI64_HI_ADDR (IEEE1394_CONFIG_ROM_ADDR + 0x0c) 115 #define AV1394_CFGROM_EUI64_LO_ADDR (IEEE1394_CONFIG_ROM_ADDR + 0x10) 116 117 /* offsets in quadlets */ 118 #define AV1394_CFGROM_BUS_NAME_OFF 1 119 #define AV1394_CFGROM_EUI64_HI_OFF 3 120 #define AV1394_CFGROM_EUI64_LO_OFF 4 121 122 typedef struct av1394_cfgrom_text_leaf_s { 123 uint64_t tl_addr; /* leaf entry address */ 124 uint32_t tl_desc_entry; /* entry described by this leaf */ 125 } av1394_cfgrom_text_leaf_t; 126 127 typedef struct av1394_cfgrom_parsed_dir_s { 128 av1394_cfgrom_text_leaf_t *pd_tl; /* text leaf array */ 129 int pd_tl_size; /* total # of array entries */ 130 int pd_tl_next; /* first unused entry index */ 131 } av1394_cfgrom_parsed_dir_t; 132 133 typedef struct av1394_cfgrom_parse_arg_s { 134 int pa_depth; /* parser depth */ 135 uint32_t pa_desc_entry; /* described entry */ 136 uint8_t pa_parent_k; /* parent entry's key value */ 137 uint64_t pa_addr; /* directory address */ 138 uint16_t pa_len; /* directory length */ 139 av1394_cfgrom_parsed_dir_t *pa_dir; /* current directory */ 140 } av1394_cfgrom_parse_arg_t; 141 142 enum { 143 AV1394_CFGROM_PARSE_MAX_DEPTH = 5 /* maximum parse depth */ 144 }; 145 146 typedef struct av1394_cfgrom_s { 147 krwlock_t cr_rwlock; /* structure lock */ 148 boolean_t cr_parsed; /* node ConfigROM was parsed */ 149 av1394_cfgrom_parsed_dir_t cr_root_dir; /* root directory */ 150 av1394_cfgrom_parsed_dir_t cr_unit_dir; /* unit directory */ 151 } av1394_cfgrom_t; 152 153 154 /* 155 * async command 156 */ 157 typedef struct av1394_async_cmd_s { 158 kmutex_t ac_mutex; 159 boolean_t ac_busy; 160 kcondvar_t ac_cv; 161 cmd1394_cmd_t *ac_cmd; 162 } av1394_async_cmd_t; 163 164 /* 165 * per-instance soft state structure 166 */ 167 typedef struct av1394_async_s { 168 kmutex_t a_mutex; /* structure mutex */ 169 int a_nopen; /* number of opens */ 170 int a_oflag; /* open flags */ 171 t1394_targetinfo_t a_targetinfo; /* target info */ 172 uint_t a_bus_generation; /* bus generation */ 173 av1394_fcp_t a_fcp; /* FCP module */ 174 av1394_cfgrom_t a_cfgrom; /* config ROM module */ 175 av1394_queue_t a_rq; /* read queue */ 176 struct pollhead a_pollhead; /* poll(2) support */ 177 short a_pollevents; /* polled events */ 178 } av1394_async_t; 179 180 _NOTE(MUTEX_PROTECTS_DATA(av1394_async_s::a_mutex, av1394_async_s)) 181 _NOTE(DATA_READABLE_WITHOUT_LOCK(av1394_async_s::{ 182 a_oflag 183 })) 184 185 186 /* we use special message types for the read queue */ 187 enum { 188 AV1394_M_FCP_RESP = 0x01, /* FCP response */ 189 AV1394_M_FCP_CMD = 0x02, /* FCP command */ 190 AV1394_M_BUS_RESET = 0x03, /* bus reset event */ 191 /* 192 * For efficiency, we only store 1394 request data on the read queue. 193 * ARQ headers (iec61883_arq_t) are generated when an application 194 * calls read(2). Because applications may read header separately 195 * from the data, we need to mark each mblk when its header was read 196 * but not the data - the following flag is used for this purpose. 197 */ 198 AV1394_M_NOHDR = 0x80 199 }; 200 201 #define AV1394_DBTYPE(bp) (DB_TYPE(bp) & ~AV1394_M_NOHDR) 202 #define AV1394_MARK_NOHDR(bp) (DB_TYPE(bp) |= AV1394_M_NOHDR) 203 #define AV1394_IS_NOHDR(bp) (DB_TYPE(bp) & AV1394_M_NOHDR) 204 205 206 /* 207 * device state: 208 * 209 * AV1394_DEV_DISCONNECTED 210 * | | ^ 211 * | | | 212 * detach reconnect disconnect 213 * | | | 214 * v v | 215 * AV1394_DEV_INIT ----attach---> AV1394_DEV_ONLINE 216 * (initial state) <---detach--- | ^ 217 * | | 218 * cpr suspend cpr resume 219 * | | 220 * v | 221 * AV1394_DEV_SUSPENDED 222 */ 223 typedef enum { 224 AV1394_DEV_INIT = 0, 225 AV1394_DEV_ONLINE, 226 AV1394_DEV_SUSPENDED, 227 AV1394_DEV_DISCONNECTED 228 } av1394_dev_state_t; 229 230 /* 231 * per-instance soft state structure 232 */ 233 typedef struct av1394_inst_s { 234 kmutex_t av_mutex; /* structure mutex */ 235 dev_info_t *av_dip; /* device information */ 236 int av_instance; /* instance number */ 237 av1394_dev_state_t av_dev_state; /* device state */ 238 av1394_dev_state_t av_prev_dev_state; /* previous device state */ 239 t1394_attachinfo_t av_attachinfo; /* 1394 attach info */ 240 t1394_handle_t av_t1394_hdl; /* 1394 handle */ 241 av1394_async_t av_a; /* asynchronous module */ 242 av1394_isoch_t av_i; /* isochronous module */ 243 ddi_callback_id_t av_reset_cb; /* reset event cb id */ 244 ddi_callback_id_t av_remove_cb; /* remove event cb id */ 245 ddi_callback_id_t av_insert_cb; /* insert event cb id */ 246 } av1394_inst_t; 247 248 _NOTE(MUTEX_PROTECTS_DATA(av1394_inst_s::av_mutex, av1394_inst_s::{ 249 av_dip 250 av_instance 251 av_attachinfo 252 av_t1394_hdl 253 })) 254 /* these are set during attach (single-threaded) and don't change afterwards */ 255 _NOTE(DATA_READABLE_WITHOUT_LOCK(av1394_inst_s::{ 256 av_dip 257 av_instance 258 av_attachinfo 259 av_t1394_hdl 260 })) 261 262 _NOTE(SCHEME_PROTECTS_DATA("one per call", msgb datab cmd1394_cmd 263 iec61883_arq_t iec61883_isoch_init_t iec61883_plug_init_t)) 264 265 /* 266 * minor <-> instance mapping 267 */ 268 #define AV1394_MINOR_TYPE_MASK (1 << (NBITSMINOR32 - 1)) 269 #define AV1394_ISOCH_INST2MINOR(inst) (inst) 270 #define AV1394_ASYNC_INST2MINOR(inst) ((inst) | AV1394_MINOR_TYPE_MASK) 271 #define AV1394_DEV_IS_ISOCH(dev) \ 272 ((getminor(dev) & AV1394_MINOR_TYPE_MASK) == 0) 273 #define AV1394_DEV_IS_ASYNC(dev) \ 274 ((getminor(dev) & AV1394_MINOR_TYPE_MASK) != 0) 275 #define AV1394_DEV2INST(dev) \ 276 ((getminor(dev)) & ~AV1394_MINOR_TYPE_MASK) 277 278 /* misc constants */ 279 enum { 280 AV1394_CLEANUP_LEVEL_MAX = 256 281 }; 282 283 /* current interface version */ 284 #define AV1394_IEC61883_VER IEC61883_V1_0 285 286 /* TNF probes */ 287 #define AV1394_TNF_FCP "1394 av1394 fcp " 288 #define AV1394_TNF_FCP_STACK "1394 av1394 fcp stacktrace " 289 #define AV1394_TNF_FCP_ERROR "1394 av1394 fcp error " 290 #define AV1394_TNF_ASYNC "1394 av1394 async " 291 #define AV1394_TNF_ASYNC_STACK "1394 av1394 async stacktrace " 292 #define AV1394_TNF_ASYNC_ERROR "1394 av1394 async error " 293 #define AV1394_TNF_INST "1394 av1394 inst " 294 #define AV1394_TNF_INST_STACK "1394 av1394 inst stacktrace " 295 #define AV1394_TNF_INST_ERROR "1394 av1394 inst error " 296 297 /* misc */ 298 #define NELEM(a) (sizeof (a) / sizeof (*(a))) 299 300 301 /* double-linked list */ 302 void av1394_list_init(av1394_list_t *lp); 303 void *av1394_list_head(av1394_list_t *lp); 304 void av1394_list_put_tail(av1394_list_t *lp, void *item); 305 void av1394_list_put_head(av1394_list_t *lp, void *item); 306 void *av1394_list_get_head(av1394_list_t *lp); 307 308 /* queue */ 309 void av1394_initq(av1394_queue_t *q, ddi_iblock_cookie_t ibc, int max); 310 void av1394_destroyq(av1394_queue_t *q); 311 void av1394_setmaxq(av1394_queue_t *q, int max); 312 int av1394_getmaxq(av1394_queue_t *q); 313 void av1394_flushq(av1394_queue_t *q); 314 int av1394_putq(av1394_queue_t *q, mblk_t *bp); 315 int av1394_putbq(av1394_queue_t *q, mblk_t *bp); 316 mblk_t *av1394_getq(av1394_queue_t *q); 317 mblk_t *av1394_peekq(av1394_queue_t *q); 318 mblk_t *av1394_peekq_locked(av1394_queue_t *q); 319 int av1394_qwait_sig(av1394_queue_t *q); 320 321 /* FCP */ 322 int av1394_fcp_attach(av1394_inst_t *); 323 void av1394_fcp_detach(av1394_inst_t *); 324 int av1394_fcp_open(av1394_inst_t *, int); 325 int av1394_fcp_close(av1394_inst_t *, int); 326 int av1394_fcp_write(av1394_inst_t *, iec61883_arq_t *, struct uio *); 327 328 /* config ROM */ 329 int av1394_cfgrom_init(av1394_inst_t *); 330 void av1394_cfgrom_fini(av1394_inst_t *); 331 void av1394_cfgrom_close(av1394_inst_t *); 332 int av1394_ioctl_node_get_bus_name(av1394_inst_t *, void *, int); 333 int av1394_ioctl_node_get_uid(av1394_inst_t *, void *, int); 334 int av1394_ioctl_node_get_text_leaf(av1394_inst_t *, void *, int); 335 336 /* async module */ 337 int av1394_async_attach(av1394_inst_t *); 338 void av1394_async_detach(av1394_inst_t *); 339 int av1394_async_cpr_suspend(av1394_inst_t *); 340 int av1394_async_cpr_resume(av1394_inst_t *); 341 void av1394_async_bus_reset(av1394_inst_t *); 342 void av1394_async_disconnect(av1394_inst_t *); 343 void av1394_async_reconnect(av1394_inst_t *); 344 int av1394_async_open(av1394_inst_t *, int); 345 int av1394_async_close(av1394_inst_t *, int); 346 int av1394_async_read(av1394_inst_t *, struct uio *); 347 int av1394_async_write(av1394_inst_t *, struct uio *); 348 int av1394_async_ioctl(av1394_inst_t *, int, intptr_t, int, int *); 349 int av1394_async_poll(av1394_inst_t *, short, int, short *, 350 struct pollhead **); 351 void av1394_async_putq_rq(av1394_inst_t *, mblk_t *); 352 353 #ifdef __cplusplus 354 } 355 #endif 356 357 #endif /* _SYS_1394_TARGETS_AV1394_IMPL_H */ 358