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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_USB_USBSER_KEYSPAN_VAR_H 27 #define _SYS_USB_USBSER_KEYSPAN_VAR_H 28 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * keyspan implementation definitions 33 */ 34 35 #include <sys/types.h> 36 #include <sys/dditypes.h> 37 #include <sys/note.h> 38 39 #include <sys/usb/clients/usbser/usbser_dsdi.h> 40 41 #include <sys/usb/clients/usbser/usbser_keyspan/usa90msg.h> 42 #include <sys/usb/clients/usbser/usbser_keyspan/usa49msg.h> 43 44 #ifdef __cplusplus 45 extern "C" { 46 #endif 47 48 /* product id */ 49 #define KEYSPAN_USA19HS_PID 0x121 50 #define KEYSPAN_USA49WLC_PID 0x12a 51 #define KEYSPAN_USA49WG_PID 0x131 52 53 #define KEYSPAN_MAX_PORT_NUM 4 54 55 /* 56 * forward typedefs needed to resolve recursive header dependencies 57 */ 58 typedef struct keyspan_pre_state keyspan_pre_state_t; 59 typedef struct keyspan_state keyspan_state_t; 60 typedef struct keyspan_port keyspan_port_t; 61 62 #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h> 63 64 /* 65 * temporary soft state for pre_attach 66 */ 67 struct keyspan_pre_state { 68 dev_info_t *kb_dip; /* device info */ 69 int kb_instance; /* instance */ 70 usb_client_dev_data_t *kb_dev_data; /* registration data */ 71 usb_log_handle_t kb_lh; /* USBA log handle */ 72 keyspan_pipe_t kb_def_pipe; /* default pipe */ 73 }; 74 75 /* Firmware structure */ 76 typedef struct usbser_keyspan_fw_record { 77 uint16_t address; 78 uint8_t data_len; 79 uint8_t data[64]; 80 } usbser_keyspan_fw_record_t; 81 82 #define ezusb_hex_record usbser_keyspan_fw_record 83 84 /* 85 * PM support 86 */ 87 typedef struct keyspan_power { 88 uint8_t pm_wakeup_enabled; /* remote wakeup enabled */ 89 uint8_t pm_pwr_states; /* bit mask of power states */ 90 boolean_t pm_raise_power; /* driver is about to raise power */ 91 uint8_t pm_cur_power; /* current power level */ 92 uint_t pm_busy_cnt; /* number of set_busy requests */ 93 } keyspan_pm_t; 94 95 /* 96 * device specific info structure 97 */ 98 typedef struct keyspan_dev_spec { 99 100 uint16_t id_product; /* product ID value */ 101 uint8_t port_cnt; /* How many ports on the device */ 102 uint8_t ctrl_ep_addr; /* Endpoint used to control the device */ 103 uint8_t stat_ep_addr; /* Endpoint used to get device status */ 104 uint8_t dataout_ep_addr[4]; /* Endpoint used to send data */ 105 106 /* Endpoint used to get data from device */ 107 uint8_t datain_ep_addr[4]; 108 } keyspan_dev_spec_t; 109 110 /* 111 * To support different keyspan adapters, use union type 112 * for different cmd msg format. 113 */ 114 typedef union keyspan_port_ctrl_msg { 115 keyspan_usa19hs_port_ctrl_msg_t usa19hs; 116 keyspan_usa49_port_ctrl_msg_t usa49; 117 } keyspan_port_ctrl_msg_t; 118 119 /* 120 * To support different keyspan adapters, use union type 121 * for different status msg format. 122 */ 123 typedef union keyspan_port_status_msg { 124 keyspan_usa19hs_port_status_msg_t usa19hs; 125 keyspan_usa49_port_status_msg_t usa49; 126 } keyspan_port_status_msg_t; 127 128 /* 129 * per device state structure 130 */ 131 struct keyspan_state { 132 kmutex_t ks_mutex; /* structure lock */ 133 dev_info_t *ks_dip; /* device info */ 134 keyspan_port_t *ks_ports; /* per port structs */ 135 keyspan_dev_spec_t ks_dev_spec; /* device specific info */ 136 137 /* 138 * we use semaphore to serialize pipe open/close by different ports. 139 * mutex could be used too, but it causes trouble when warlocking 140 * with USBA: some functions inside usb_pipe_close() wait on cv 141 * 142 * since semaphore is only used for serialization during 143 * open/close and suspend/resume, there is no deadlock hazard 144 */ 145 ksema_t ks_pipes_sema; 146 147 /* 148 * USBA related 149 */ 150 usb_client_dev_data_t *ks_dev_data; /* registration data */ 151 usb_event_t *ks_usb_events; /* usb events */ 152 153 keyspan_pipe_t ks_def_pipe; /* default pipe */ 154 155 /* bulk in pipe for getting device status */ 156 keyspan_pipe_t ks_statin_pipe; 157 158 /* bulk out pipe for sending control cmd to device */ 159 keyspan_pipe_t ks_ctrlout_pipe; 160 161 usb_log_handle_t ks_lh; /* USBA log handle */ 162 int ks_dev_state; /* USB device state */ 163 keyspan_pm_t *ks_pm; /* PM support */ 164 165 /* 166 * The following only used on USA_49WG 167 */ 168 /* Shared bulk in pipe handle */ 169 usb_pipe_handle_t ks_datain_pipe_handle; 170 171 /* counter for opened bulk in pipe */ 172 uint8_t ks_datain_open_cnt; 173 174 /* Flag for device reconnect */ 175 uint8_t ks_reconnect_flag; 176 177 }; 178 179 _NOTE(MUTEX_PROTECTS_DATA(keyspan_state::ks_mutex, keyspan_state)) 180 _NOTE(DATA_READABLE_WITHOUT_LOCK(keyspan_state::{ 181 ks_dip 182 ks_dev_data 183 ks_usb_events 184 ks_dev_spec 185 ks_ports 186 ks_def_pipe 187 ks_ctrlout_pipe.pipe_handle 188 ks_statin_pipe.pipe_handle 189 ks_lh 190 ks_pm 191 })) 192 193 /* 194 * per port structure 195 */ 196 struct keyspan_port { 197 kmutex_t kp_mutex; /* structure lock */ 198 keyspan_state_t *kp_ksp; /* back pointer to the state */ 199 char kp_lh_name[16]; /* log handle name */ 200 usb_log_handle_t kp_lh; /* log handle */ 201 uint_t kp_port_num; /* port number */ 202 int kp_state; /* port state */ 203 int kp_flags; /* port flags */ 204 ds_cb_t kp_cb; /* DSD callbacks */ 205 kcondvar_t kp_tx_cv; /* cv to wait for tx completion */ 206 /* 207 * data receipt and transmit 208 */ 209 mblk_t *kp_rx_mp; /* received data */ 210 mblk_t *kp_tx_mp; /* data to transmit */ 211 boolean_t kp_no_more_reads; /* disable reads */ 212 213 /* The control cmd sent to the port */ 214 keyspan_port_ctrl_msg_t kp_ctrl_msg; 215 216 /* status msg of the port */ 217 keyspan_port_status_msg_t kp_status_msg; 218 219 uint_t kp_baud; /* the current baud speed code */ 220 uint8_t kp_lcr; /* the current lcr value */ 221 /* 222 * the current port status, including: rts, dtr, 223 * break, loopback, enable. 224 */ 225 uint8_t kp_status_flag; 226 227 keyspan_pipe_t kp_datain_pipe; /* bulk in data pipe */ 228 keyspan_pipe_t kp_dataout_pipe; /* bulk out data pipe */ 229 230 uint_t kp_read_len; /* max length of bulkin request */ 231 uint_t kp_write_len; /* max length of bulkout request */ 232 }; 233 234 _NOTE(MUTEX_PROTECTS_DATA(keyspan_port::kp_mutex, keyspan_port)) 235 _NOTE(DATA_READABLE_WITHOUT_LOCK(keyspan_port::{ 236 kp_ksp 237 kp_lh 238 kp_port_num 239 kp_read_len 240 kp_write_len 241 kp_cb 242 kp_datain_pipe.pipe_handle 243 kp_datain_pipe.pipe_ep_descr 244 })) 245 246 /* lock relationships */ 247 _NOTE(LOCK_ORDER(keyspan_state::ks_mutex keyspan_port::kp_mutex)) 248 _NOTE(LOCK_ORDER(keyspan_port::kp_mutex keyspan_pipe::pipe_mutex)) 249 250 /* port status flags */ 251 enum { 252 KEYSPAN_PORT_ENABLE = 0x0001, /* port is enabled */ 253 KEYSPAN_PORT_RTS = 0x0002, /* port's rts is set */ 254 KEYSPAN_PORT_DTR = 0x0004, /* port's dtr is set */ 255 KEYSPAN_PORT_TXBREAK = 0x0008, /* port is in TX break mod */ 256 KEYSPAN_PORT_LOOPBACK = 0x0010, /* port is in loopback mod */ 257 258 /* the ctrl cmd sent to this port is responded */ 259 KEYSPAN_PORT_CTRLRESP = 0x0020, 260 KEYSPAN_PORT_RXBREAK = 0x0040 /* port is in RX break mod */ 261 }; 262 263 /* port state */ 264 enum { 265 KEYSPAN_PORT_NOT_INIT = 0, /* port is not initialized */ 266 KEYSPAN_PORT_CLOSED, /* port is closed */ 267 KEYSPAN_PORT_OPENING, /* port is being opened */ 268 KEYSPAN_PORT_OPEN /* port is open */ 269 }; 270 271 /* port flags */ 272 enum { 273 KEYSPAN_PORT_TX_STOPPED = 0x0001 /* transmit not allowed */ 274 }; 275 276 /* various tunables */ 277 enum { 278 KEYSPAN_BULK_TIMEOUT = 3, /* transfer timeout */ 279 KEYSPAN_BULKIN_MAX_LEN = 64, /* bulk in max length */ 280 KEYSPAN_BULKIN_MAX_LEN_49WG = 512, /* bulk in max length */ 281 /* 282 * From keyspan spec, USA49WLC max packet length for bulk out transfer 283 * is 64, the format is [status byte][up to 63 data bytes], so the 284 * max data length per transfer is 63 bytes, USA19HS doesn't need 285 * extra status byte. USA49WG max packet length for bulk out transfer 286 * is 512, the format is [status byte][63 data bytes]...[status byte] 287 * [up to 63 data bytes], so the max data length per transfer is 504 288 * bytes, while the port0 use intr out pipe send data, the packet 289 * format is the same as USA49WLC, so the max data length for USA49WG 290 * port0 is 63 bytes. 291 */ 292 KEYSPAN_BULKOUT_MAX_LEN_19HS = 64, /* for 19HS only */ 293 KEYSPAN_BULKOUT_MAX_LEN_49WLC = 63, /* for 49WLC and 49WG port0 */ 294 KEYSPAN_BULKOUT_MAX_LEN_49WG = 504, /* for 49WG other ports */ 295 KEYSPAN_STATIN_MAX_LEN = 16 /* status in max length */ 296 }; 297 298 /* This flag indicates if the firmware already downloaded to the device */ 299 #define KEYSPAN_FW_FLAG 0x8000 300 301 /* Vendor specific ctrl req, used to set/download bytes in the device memory */ 302 #define KEYSPAN_REQ_SET 0xa0 303 /* Vendor specific ctrl req, used to send ctrl command for USA_49WG model */ 304 #define KEYSPAN_SET_CONTROL_REQUEST 0xB0 305 306 /* 307 * debug printing masks 308 */ 309 #define DPRINT_ATTACH 0x00000001 310 #define DPRINT_OPEN 0x00000002 311 #define DPRINT_CLOSE 0x00000004 312 #define DPRINT_DEF_PIPE 0x00000010 313 #define DPRINT_IN_PIPE 0x00000020 314 #define DPRINT_OUT_PIPE 0x00000040 315 #define DPRINT_INTR_PIPE 0x00000080 316 #define DPRINT_PIPE_RESET 0x00000100 317 #define DPRINT_IN_DATA 0x00000200 318 #define DPRINT_OUT_DATA 0x00000400 319 #define DPRINT_CTLOP 0x00000800 320 #define DPRINT_HOTPLUG 0x00001000 321 #define DPRINT_PM 0x00002000 322 #define DPRINT_MASK_ALL 0xFFFFFFFF 323 324 /* 325 * misc macros 326 */ 327 #define NELEM(a) (sizeof (a) / sizeof (*(a))) 328 329 /* common DSD functions */ 330 int keyspan_tx_copy_data(keyspan_port_t *, mblk_t *, int); 331 void keyspan_tx_start(keyspan_port_t *, int *); 332 void keyspan_put_tail(mblk_t **, mblk_t *); 333 void keyspan_put_head(mblk_t **, mblk_t *, keyspan_port_t *); 334 335 void keyspan_bulkin_cb(usb_pipe_handle_t, usb_bulk_req_t *); 336 void keyspan_bulkout_cb(usb_pipe_handle_t, usb_bulk_req_t *); 337 338 int keyspan_restore_device(keyspan_state_t *); 339 int keyspan_send_cmd(keyspan_port_t *); 340 341 int keyspan_dev_is_online(keyspan_state_t *); 342 343 344 #ifdef __cplusplus 345 } 346 #endif 347 348 #endif /* _SYS_USB_USBSER_KEYSPAN_VAR_H */ 349