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