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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_USB_HCDI_H 27 #define _SYS_USB_HCDI_H 28 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <sys/usb/usba/genconsole.h> 35 #include <sys/usb/usba/usba_types.h> 36 37 /* 38 * HCD ops structure 39 * 40 * - this structure defines all entry points into HCD 41 * 42 * - all client driver USBAI functions that require HCD 43 * involvement go through this ops table 44 * 45 * - at HCD attach time, the HCD ops are passed to 46 * to the USBA through usba_hcdi_attach() 47 * 48 * some of these ops implement the semantics of the corresponding 49 * USBAI interfaces. Refer to usbai.h for detailed description 50 */ 51 #define HCDI_OPS_VERSION_0 0 52 #define HCDI_OPS_VERSION_1 1 53 #define HCDI_OPS_VERSION HCDI_OPS_VERSION_1 54 55 typedef struct usba_hcdi_ops { 56 int usba_hcdi_ops_version; /* implementation version */ 57 58 dev_info_t *usba_hcdi_dip; /* HCD's devinfo ptr */ 59 60 /* can this hcd support pm? */ 61 int (*usba_hcdi_pm_support)(dev_info_t *dip); 62 63 /* 64 * usba_hcdi_pipe_open: 65 * implements the semantics of usb_pipe_open() 66 * USBA allocate the pipe_handle which contains 67 * pipe_policy and endpoint pointers 68 */ 69 int (*usba_hcdi_pipe_open)( 70 usba_pipe_handle_data_t *pipe_handle, 71 usb_flags_t usb_flags); 72 73 /* 74 * close a pipe 75 */ 76 int (*usba_hcdi_pipe_close)( 77 usba_pipe_handle_data_t *pipe_handle, 78 usb_flags_t usb_flags); 79 80 /* 81 * pipe management 82 */ 83 int (*usba_hcdi_pipe_reset)( 84 usba_pipe_handle_data_t *pipe_handle, 85 usb_flags_t usb_flags); 86 87 /* 88 * pipe management 89 */ 90 void (*usba_hcdi_pipe_reset_data_toggle)( 91 usba_pipe_handle_data_t *pipe_handle); 92 93 /* 94 * data transfer management 95 */ 96 int (*usba_hcdi_pipe_ctrl_xfer)( 97 usba_pipe_handle_data_t *pipe_handle, 98 usb_ctrl_req_t *usb_ctrl_req, 99 usb_flags_t usb_flags); 100 101 /* 102 * get HCD limitation on bulk xfer at a time? 103 */ 104 int (*usba_hcdi_bulk_transfer_size)( 105 usba_device_t *usba_device, 106 size_t *size); 107 108 /* 109 * do bulk read/write 110 */ 111 int (*usba_hcdi_pipe_bulk_xfer)( 112 usba_pipe_handle_data_t *pipe_handle, 113 usb_bulk_req_t *usb_bulk_req, 114 usb_flags_t usb_flags); 115 116 /* 117 * do interrupt pipe read/write 118 */ 119 int (*usba_hcdi_pipe_intr_xfer)( 120 usba_pipe_handle_data_t *pipe_handle, 121 usb_intr_req_t *usb_intr_req, 122 usb_flags_t usb_flags); 123 124 /* 125 * stop interrupt pipe polling 126 */ 127 int (*usba_hcdi_pipe_stop_intr_polling)( 128 usba_pipe_handle_data_t *pipe_handle, 129 usb_flags_t usb_flags); 130 131 /* 132 * do isoch pipe read/write 133 */ 134 int (*usba_hcdi_pipe_isoc_xfer)( 135 usba_pipe_handle_data_t *pipe_handle, 136 usb_isoc_req_t *usb_isoc_req, 137 usb_flags_t usb_flags); 138 139 /* 140 * stop isoc pipe polling 141 */ 142 int (*usba_hcdi_pipe_stop_isoc_polling)( 143 usba_pipe_handle_data_t *pipe_handle, 144 usb_flags_t usb_flags); 145 146 /* utility isoc functions */ 147 int (*usba_hcdi_get_current_frame_number)( 148 usba_device_t *usba_device, 149 usb_frame_number_t *frame_number); 150 151 int (*usba_hcdi_get_max_isoc_pkts)( 152 usba_device_t *usba_device, 153 uint_t *max_isoc_pkts_per_request); 154 155 /* 156 * Initialize OBP support for input 157 */ 158 int (*usba_hcdi_console_input_init)( 159 usba_pipe_handle_data_t *pipe_handle, 160 uchar_t **obp_buf, 161 usb_console_info_impl_t *console_input_info); 162 163 /* 164 * Free resources allocated by usba_hcdi_console_input_init 165 */ 166 int (*usba_hcdi_console_input_fini)( 167 usb_console_info_impl_t *console_input_info); 168 169 /* 170 * Save controller state information 171 */ 172 int (*usba_hcdi_console_input_enter)( 173 usb_console_info_impl_t *console_input_info); 174 175 /* 176 * Read character from controller 177 */ 178 int (*usba_hcdi_console_read)( 179 usb_console_info_impl_t *console_input_info, 180 uint_t *num_characters); 181 182 /* 183 * Restore controller state information 184 */ 185 int (*usba_hcdi_console_input_exit)( 186 usb_console_info_impl_t *console_input_info); 187 188 189 /* 190 * VERSION 1 ops: support for polled output 191 */ 192 int (*usba_hcdi_console_output_init)( 193 usba_pipe_handle_data_t *pipe_handle, 194 usb_console_info_impl_t *console_output_info); 195 196 int (*usba_hcdi_console_output_fini)( 197 usb_console_info_impl_t *console_output_info); 198 199 int (*usba_hcdi_console_output_enter)( 200 usb_console_info_impl_t *console_output_info); 201 202 int (*usba_hcdi_console_write)( 203 usb_console_info_impl_t *console_output_info, 204 uchar_t *buf, 205 uint_t num_characters, 206 uint_t *num_characters_written); 207 208 int (*usba_hcdi_console_output_exit)( 209 usb_console_info_impl_t *console_output_info); 210 } usba_hcdi_ops_t; 211 212 213 /* 214 * callback support: 215 * this function handles all HCD callbacks as follows: 216 * - USB_FLAGS_SLEEP determines whether the client driver made 217 * a synchronous or asynchronous USBAI call 218 * - for synchronous calls, the args are copied into the pipe handle 219 * and the sync cv of the pipe handle is signalled 220 * - for async calls and completion_reason = 0, the normal callback 221 * is invoked 222 * - for async calls and completion_reason != 0, the exception 223 * callback is invoked 224 */ 225 void 226 usba_hcdi_cb(usba_pipe_handle_data_t *ph, 227 usb_opaque_t req, 228 usb_cr_t completion_reason); 229 230 /* 231 * function to duplicate a interrupt/isoc request (for HCD) 232 */ 233 usb_intr_req_t *usba_hcdi_dup_intr_req(dev_info_t *, 234 usb_intr_req_t *, size_t, usb_flags_t); 235 usb_isoc_req_t *usba_hcdi_dup_isoc_req(dev_info_t *, 236 usb_isoc_req_t *, usb_flags_t); 237 238 /* access to private member of requests */ 239 usb_opaque_t usba_hcdi_get_req_private(usb_opaque_t); 240 void usba_hcdi_set_req_private(usb_opaque_t, usb_opaque_t); 241 usba_pipe_handle_data_t * 242 usba_hcdi_get_ph_data(usba_device_t *, uint8_t); 243 244 /* data toggle get and set */ 245 uchar_t usba_hcdi_get_data_toggle(usba_device_t *, uint8_t); 246 void usba_hcdi_set_data_toggle(usba_device_t *, uint8_t, uchar_t); 247 248 /* 249 * HCD Nexus driver support: 250 */ 251 252 /* 253 * hcd_ops allocator/deallocator 254 * USBA allocates the usba_hcdi_ops so we can easily handle 255 * versioning 256 */ 257 usba_hcdi_ops_t *usba_alloc_hcdi_ops(); 258 void usba_free_hcdi_ops(usba_hcdi_ops_t *); 259 260 /* 261 * Argument structure for usba_hcdi_register 262 */ 263 typedef struct usba_hcdi_register_args { 264 uint_t usba_hcdi_register_version; 265 dev_info_t *usba_hcdi_register_dip; 266 usba_hcdi_ops_t *usba_hcdi_register_ops; 267 ddi_dma_attr_t *usba_hcdi_register_dma_attr; 268 ddi_iblock_cookie_t usba_hcdi_register_iblock_cookie; 269 270 } usba_hcdi_register_args_t; 271 272 #define HCDI_REGISTER_VERS_0 0 273 #define HCDI_REGISTER_VERSION HCDI_REGISTER_VERS_0 274 275 276 /* 277 * make this instance known to USBA 278 * 279 * the HCD must initialize the hcdi_ops before calling this function 280 */ 281 int usba_hcdi_register(usba_hcdi_register_args_t *, uint_t); 282 283 /* 284 * detach support 285 */ 286 void usba_hcdi_unregister(dev_info_t *); 287 288 /* 289 * Hotplug kstats named structure 290 * 291 * Number of types of USB transfers 292 */ 293 #define USB_N_COUNT_KSTATS 4 294 295 typedef struct hcdi_hotplug_stats { 296 struct kstat_named hcdi_hotplug_total_success; 297 struct kstat_named hcdi_hotplug_success; 298 struct kstat_named hcdi_hotplug_total_failure; 299 struct kstat_named hcdi_hotplug_failure; 300 struct kstat_named hcdi_device_count; 301 } hcdi_hotplug_stats_t; 302 303 /* 304 * USB error kstats named structure 305 */ 306 typedef struct hcdi_error_stats { 307 /* transport completion codes */ 308 struct kstat_named cc_crc; 309 struct kstat_named cc_bitstuffing; 310 struct kstat_named cc_data_toggle_mm; 311 struct kstat_named cc_stall; 312 struct kstat_named cc_dev_not_resp; 313 struct kstat_named cc_pid_checkfailure; 314 struct kstat_named cc_unexp_pid; 315 struct kstat_named cc_data_overrun; 316 struct kstat_named cc_data_underrun; 317 struct kstat_named cc_buffer_overrun; 318 struct kstat_named cc_buffer_underrun; 319 struct kstat_named cc_timeout; 320 struct kstat_named cc_not_accessed; 321 struct kstat_named cc_no_resources; 322 struct kstat_named cc_unspecified_err; 323 struct kstat_named cc_stopped_polling; 324 struct kstat_named cc_pipe_closing; 325 struct kstat_named cc_pipe_reset; 326 struct kstat_named cc_not_supported; 327 struct kstat_named cc_flushed; 328 } hcdi_error_stats_t; 329 330 /* 331 * hcdi kstat defines 332 * XXX this needs to be a function 333 */ 334 #define HCDI_HOTPLUG_STATS(hcdi) ((hcdi)->hcdi_hotplug_stats) 335 #define HCDI_HOTPLUG_STATS_DATA(hcdi) \ 336 ((hcdi_hotplug_stats_t *)HCDI_HOTPLUG_STATS((hcdi))->ks_data) 337 338 #define HCDI_ERROR_STATS(hcdi) ((hcdi)->hcdi_error_stats) 339 #define HCDI_ERROR_STATS_DATA(hcdi) \ 340 ((hcdi_error_stats_t *)HCDI_ERROR_STATS((hcdi))->ks_data) 341 342 343 #ifdef __cplusplus 344 } 345 #endif 346 347 #endif /* _SYS_USB_HCDI_H */