160b08185Syz /* 260b08185Syz * CDDL HEADER START 360b08185Syz * 460b08185Syz * The contents of this file are subject to the terms of the 502dd2108Slg * Common Development and Distribution License (the "License"). 602dd2108Slg * You may not use this file except in compliance with the License. 760b08185Syz * 860b08185Syz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 960b08185Syz * or http://www.opensolaris.org/os/licensing. 1060b08185Syz * See the License for the specific language governing permissions 1160b08185Syz * and limitations under the License. 1260b08185Syz * 1360b08185Syz * When distributing Covered Code, include this CDDL HEADER in each 1460b08185Syz * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1560b08185Syz * If applicable, add the following below this CDDL HEADER, with the 1660b08185Syz * fields enclosed by brackets "[]" replaced with your own identifying 1760b08185Syz * information: Portions Copyright [yyyy] [name of copyright owner] 1860b08185Syz * 1960b08185Syz * CDDL HEADER END 2060b08185Syz */ 2160b08185Syz /* 22*d29f5a71Szhigang lu - Sun Microsystems - Beijing China * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2360b08185Syz * Use is subject to license terms. 2460b08185Syz */ 2560b08185Syz 2660b08185Syz #ifndef _SYS_USB_USBSER_KEYSPAN_VAR_H 2760b08185Syz #define _SYS_USB_USBSER_KEYSPAN_VAR_H 2860b08185Syz 2960b08185Syz 3060b08185Syz /* 3160b08185Syz * keyspan implementation definitions 3260b08185Syz */ 3360b08185Syz 3460b08185Syz #include <sys/types.h> 3560b08185Syz #include <sys/dditypes.h> 3660b08185Syz #include <sys/note.h> 3760b08185Syz 3860b08185Syz #include <sys/usb/clients/usbser/usbser_dsdi.h> 3960b08185Syz 4060b08185Syz #include <sys/usb/clients/usbser/usbser_keyspan/usa90msg.h> 4160b08185Syz #include <sys/usb/clients/usbser/usbser_keyspan/usa49msg.h> 4260b08185Syz 4360b08185Syz #ifdef __cplusplus 4460b08185Syz extern "C" { 4560b08185Syz #endif 4660b08185Syz 4760b08185Syz /* product id */ 4860b08185Syz #define KEYSPAN_USA19HS_PID 0x121 4960b08185Syz #define KEYSPAN_USA49WLC_PID 0x12a 5002dd2108Slg #define KEYSPAN_USA49WG_PID 0x131 5160b08185Syz 5260b08185Syz #define KEYSPAN_MAX_PORT_NUM 4 5360b08185Syz 5460b08185Syz /* 5560b08185Syz * forward typedefs needed to resolve recursive header dependencies 5660b08185Syz */ 5760b08185Syz typedef struct keyspan_pre_state keyspan_pre_state_t; 5860b08185Syz typedef struct keyspan_state keyspan_state_t; 5960b08185Syz typedef struct keyspan_port keyspan_port_t; 6060b08185Syz 6160b08185Syz #include <sys/usb/clients/usbser/usbser_keyspan/keyspan_pipe.h> 6260b08185Syz 6360b08185Syz /* 6460b08185Syz * temporary soft state for pre_attach 6560b08185Syz */ 6660b08185Syz struct keyspan_pre_state { 6760b08185Syz dev_info_t *kb_dip; /* device info */ 6860b08185Syz int kb_instance; /* instance */ 6960b08185Syz usb_client_dev_data_t *kb_dev_data; /* registration data */ 7060b08185Syz usb_log_handle_t kb_lh; /* USBA log handle */ 7160b08185Syz keyspan_pipe_t kb_def_pipe; /* default pipe */ 7260b08185Syz }; 7360b08185Syz 74c138f478Syz /* Firmware structure */ 75c138f478Syz typedef struct usbser_keyspan_fw_record { 76c138f478Syz uint16_t address; 77c138f478Syz uint8_t data_len; 78c138f478Syz uint8_t data[64]; 79c138f478Syz } usbser_keyspan_fw_record_t; 80c138f478Syz 81c138f478Syz #define ezusb_hex_record usbser_keyspan_fw_record 82c138f478Syz 8360b08185Syz /* 8460b08185Syz * PM support 8560b08185Syz */ 8660b08185Syz typedef struct keyspan_power { 8760b08185Syz uint8_t pm_wakeup_enabled; /* remote wakeup enabled */ 8860b08185Syz uint8_t pm_pwr_states; /* bit mask of power states */ 8960b08185Syz boolean_t pm_raise_power; /* driver is about to raise power */ 9060b08185Syz uint8_t pm_cur_power; /* current power level */ 9160b08185Syz uint_t pm_busy_cnt; /* number of set_busy requests */ 9260b08185Syz } keyspan_pm_t; 9360b08185Syz 9460b08185Syz /* 9560b08185Syz * device specific info structure 9660b08185Syz */ 9760b08185Syz typedef struct keyspan_dev_spec { 9860b08185Syz 9960b08185Syz uint16_t id_product; /* product ID value */ 10060b08185Syz uint8_t port_cnt; /* How many ports on the device */ 10160b08185Syz uint8_t ctrl_ep_addr; /* Endpoint used to control the device */ 10260b08185Syz uint8_t stat_ep_addr; /* Endpoint used to get device status */ 10360b08185Syz uint8_t dataout_ep_addr[4]; /* Endpoint used to send data */ 10460b08185Syz 10560b08185Syz /* Endpoint used to get data from device */ 10660b08185Syz uint8_t datain_ep_addr[4]; 10760b08185Syz } keyspan_dev_spec_t; 10860b08185Syz 10960b08185Syz /* 11060b08185Syz * To support different keyspan adapters, use union type 11160b08185Syz * for different cmd msg format. 11260b08185Syz */ 11360b08185Syz typedef union keyspan_port_ctrl_msg { 11460b08185Syz keyspan_usa19hs_port_ctrl_msg_t usa19hs; 11560b08185Syz keyspan_usa49_port_ctrl_msg_t usa49; 11660b08185Syz } keyspan_port_ctrl_msg_t; 11760b08185Syz 11860b08185Syz /* 11960b08185Syz * To support different keyspan adapters, use union type 12060b08185Syz * for different status msg format. 12160b08185Syz */ 12260b08185Syz typedef union keyspan_port_status_msg { 12360b08185Syz keyspan_usa19hs_port_status_msg_t usa19hs; 12460b08185Syz keyspan_usa49_port_status_msg_t usa49; 12560b08185Syz } keyspan_port_status_msg_t; 12660b08185Syz 12760b08185Syz /* 12860b08185Syz * per device state structure 12960b08185Syz */ 13060b08185Syz struct keyspan_state { 13160b08185Syz kmutex_t ks_mutex; /* structure lock */ 13260b08185Syz dev_info_t *ks_dip; /* device info */ 13360b08185Syz keyspan_port_t *ks_ports; /* per port structs */ 13460b08185Syz keyspan_dev_spec_t ks_dev_spec; /* device specific info */ 13560b08185Syz 13660b08185Syz /* 13760b08185Syz * we use semaphore to serialize pipe open/close by different ports. 13860b08185Syz * mutex could be used too, but it causes trouble when warlocking 13960b08185Syz * with USBA: some functions inside usb_pipe_close() wait on cv 14060b08185Syz * 14160b08185Syz * since semaphore is only used for serialization during 14260b08185Syz * open/close and suspend/resume, there is no deadlock hazard 14360b08185Syz */ 14460b08185Syz ksema_t ks_pipes_sema; 14560b08185Syz 14660b08185Syz /* 14760b08185Syz * USBA related 14860b08185Syz */ 14960b08185Syz usb_client_dev_data_t *ks_dev_data; /* registration data */ 15060b08185Syz usb_event_t *ks_usb_events; /* usb events */ 15160b08185Syz 15260b08185Syz keyspan_pipe_t ks_def_pipe; /* default pipe */ 15360b08185Syz 15460b08185Syz /* bulk in pipe for getting device status */ 15560b08185Syz keyspan_pipe_t ks_statin_pipe; 15660b08185Syz 15760b08185Syz /* bulk out pipe for sending control cmd to device */ 15860b08185Syz keyspan_pipe_t ks_ctrlout_pipe; 15960b08185Syz 16060b08185Syz usb_log_handle_t ks_lh; /* USBA log handle */ 16160b08185Syz int ks_dev_state; /* USB device state */ 16260b08185Syz keyspan_pm_t *ks_pm; /* PM support */ 16360b08185Syz 16402dd2108Slg /* 16502dd2108Slg * The following only used on USA_49WG 16602dd2108Slg */ 16702dd2108Slg /* Shared bulk in pipe handle */ 16802dd2108Slg usb_pipe_handle_t ks_datain_pipe_handle; 16902dd2108Slg 17002dd2108Slg /* counter for opened bulk in pipe */ 17102dd2108Slg uint8_t ks_datain_open_cnt; 17202dd2108Slg 17302dd2108Slg /* Flag for device reconnect */ 17402dd2108Slg uint8_t ks_reconnect_flag; 17502dd2108Slg 17660b08185Syz }; 17760b08185Syz 17860b08185Syz _NOTE(MUTEX_PROTECTS_DATA(keyspan_state::ks_mutex, keyspan_state)) 17960b08185Syz _NOTE(DATA_READABLE_WITHOUT_LOCK(keyspan_state::{ 18060b08185Syz ks_dip 18160b08185Syz ks_dev_data 18260b08185Syz ks_usb_events 18360b08185Syz ks_dev_spec 18460b08185Syz ks_ports 18560b08185Syz ks_def_pipe 18660b08185Syz ks_ctrlout_pipe.pipe_handle 18760b08185Syz ks_statin_pipe.pipe_handle 18860b08185Syz ks_lh 18960b08185Syz ks_pm 19060b08185Syz })) 19160b08185Syz 19260b08185Syz /* 19360b08185Syz * per port structure 19460b08185Syz */ 19560b08185Syz struct keyspan_port { 19660b08185Syz kmutex_t kp_mutex; /* structure lock */ 19760b08185Syz keyspan_state_t *kp_ksp; /* back pointer to the state */ 19860b08185Syz char kp_lh_name[16]; /* log handle name */ 19960b08185Syz usb_log_handle_t kp_lh; /* log handle */ 20060b08185Syz uint_t kp_port_num; /* port number */ 20160b08185Syz int kp_state; /* port state */ 20260b08185Syz int kp_flags; /* port flags */ 20360b08185Syz ds_cb_t kp_cb; /* DSD callbacks */ 20460b08185Syz kcondvar_t kp_tx_cv; /* cv to wait for tx completion */ 20560b08185Syz /* 20660b08185Syz * data receipt and transmit 20760b08185Syz */ 20860b08185Syz mblk_t *kp_rx_mp; /* received data */ 20960b08185Syz mblk_t *kp_tx_mp; /* data to transmit */ 21060b08185Syz boolean_t kp_no_more_reads; /* disable reads */ 21160b08185Syz 21260b08185Syz /* The control cmd sent to the port */ 21360b08185Syz keyspan_port_ctrl_msg_t kp_ctrl_msg; 21460b08185Syz 21560b08185Syz /* status msg of the port */ 21660b08185Syz keyspan_port_status_msg_t kp_status_msg; 21760b08185Syz 21860b08185Syz uint_t kp_baud; /* the current baud speed code */ 21960b08185Syz uint8_t kp_lcr; /* the current lcr value */ 22060b08185Syz /* 22160b08185Syz * the current port status, including: rts, dtr, 22260b08185Syz * break, loopback, enable. 22360b08185Syz */ 22460b08185Syz uint8_t kp_status_flag; 22560b08185Syz 22660b08185Syz keyspan_pipe_t kp_datain_pipe; /* bulk in data pipe */ 22760b08185Syz keyspan_pipe_t kp_dataout_pipe; /* bulk out data pipe */ 22860b08185Syz 22960b08185Syz uint_t kp_read_len; /* max length of bulkin request */ 23060b08185Syz uint_t kp_write_len; /* max length of bulkout request */ 23160b08185Syz }; 23260b08185Syz 23360b08185Syz _NOTE(MUTEX_PROTECTS_DATA(keyspan_port::kp_mutex, keyspan_port)) 23460b08185Syz _NOTE(DATA_READABLE_WITHOUT_LOCK(keyspan_port::{ 23560b08185Syz kp_ksp 23660b08185Syz kp_lh 23760b08185Syz kp_port_num 23860b08185Syz kp_read_len 23960b08185Syz kp_write_len 24060b08185Syz kp_cb 24160b08185Syz kp_datain_pipe.pipe_handle 24260b08185Syz kp_datain_pipe.pipe_ep_descr 24360b08185Syz })) 24460b08185Syz 24560b08185Syz /* lock relationships */ 24660b08185Syz _NOTE(LOCK_ORDER(keyspan_state::ks_mutex keyspan_port::kp_mutex)) 24760b08185Syz _NOTE(LOCK_ORDER(keyspan_port::kp_mutex keyspan_pipe::pipe_mutex)) 24860b08185Syz 24960b08185Syz /* port status flags */ 25060b08185Syz enum { 25160b08185Syz KEYSPAN_PORT_ENABLE = 0x0001, /* port is enabled */ 25260b08185Syz KEYSPAN_PORT_RTS = 0x0002, /* port's rts is set */ 25360b08185Syz KEYSPAN_PORT_DTR = 0x0004, /* port's dtr is set */ 25460b08185Syz KEYSPAN_PORT_TXBREAK = 0x0008, /* port is in TX break mod */ 25560b08185Syz KEYSPAN_PORT_LOOPBACK = 0x0010, /* port is in loopback mod */ 25660b08185Syz 25760b08185Syz /* the ctrl cmd sent to this port is responded */ 25860b08185Syz KEYSPAN_PORT_CTRLRESP = 0x0020, 25960b08185Syz KEYSPAN_PORT_RXBREAK = 0x0040 /* port is in RX break mod */ 26060b08185Syz }; 26160b08185Syz 26260b08185Syz /* port state */ 26360b08185Syz enum { 26460b08185Syz KEYSPAN_PORT_NOT_INIT = 0, /* port is not initialized */ 26560b08185Syz KEYSPAN_PORT_CLOSED, /* port is closed */ 26660b08185Syz KEYSPAN_PORT_OPENING, /* port is being opened */ 26760b08185Syz KEYSPAN_PORT_OPEN /* port is open */ 26860b08185Syz }; 26960b08185Syz 27060b08185Syz /* port flags */ 27160b08185Syz enum { 27260b08185Syz KEYSPAN_PORT_TX_STOPPED = 0x0001 /* transmit not allowed */ 27360b08185Syz }; 27460b08185Syz 27560b08185Syz /* various tunables */ 27660b08185Syz enum { 27760b08185Syz KEYSPAN_BULK_TIMEOUT = 3, /* transfer timeout */ 27860b08185Syz KEYSPAN_BULKIN_MAX_LEN = 64, /* bulk in max length */ 27902dd2108Slg KEYSPAN_BULKIN_MAX_LEN_49WG = 512, /* bulk in max length */ 28002dd2108Slg /* 28102dd2108Slg * From keyspan spec, USA49WLC max packet length for bulk out transfer 28202dd2108Slg * is 64, the format is [status byte][up to 63 data bytes], so the 28302dd2108Slg * max data length per transfer is 63 bytes, USA19HS doesn't need 28402dd2108Slg * extra status byte. USA49WG max packet length for bulk out transfer 28502dd2108Slg * is 512, the format is [status byte][63 data bytes]...[status byte] 28602dd2108Slg * [up to 63 data bytes], so the max data length per transfer is 504 28702dd2108Slg * bytes, while the port0 use intr out pipe send data, the packet 28802dd2108Slg * format is the same as USA49WLC, so the max data length for USA49WG 28902dd2108Slg * port0 is 63 bytes. 29002dd2108Slg */ 29102dd2108Slg KEYSPAN_BULKOUT_MAX_LEN_19HS = 64, /* for 19HS only */ 29202dd2108Slg KEYSPAN_BULKOUT_MAX_LEN_49WLC = 63, /* for 49WLC and 49WG port0 */ 29302dd2108Slg KEYSPAN_BULKOUT_MAX_LEN_49WG = 504, /* for 49WG other ports */ 29460b08185Syz KEYSPAN_STATIN_MAX_LEN = 16 /* status in max length */ 29560b08185Syz }; 29660b08185Syz 29760b08185Syz /* This flag indicates if the firmware already downloaded to the device */ 29860b08185Syz #define KEYSPAN_FW_FLAG 0x8000 29960b08185Syz 30060b08185Syz /* Vendor specific ctrl req, used to set/download bytes in the device memory */ 30160b08185Syz #define KEYSPAN_REQ_SET 0xa0 30202dd2108Slg /* Vendor specific ctrl req, used to send ctrl command for USA_49WG model */ 30302dd2108Slg #define KEYSPAN_SET_CONTROL_REQUEST 0xB0 30460b08185Syz 30560b08185Syz /* 30660b08185Syz * debug printing masks 30760b08185Syz */ 30860b08185Syz #define DPRINT_ATTACH 0x00000001 30960b08185Syz #define DPRINT_OPEN 0x00000002 31060b08185Syz #define DPRINT_CLOSE 0x00000004 31160b08185Syz #define DPRINT_DEF_PIPE 0x00000010 31260b08185Syz #define DPRINT_IN_PIPE 0x00000020 31360b08185Syz #define DPRINT_OUT_PIPE 0x00000040 31460b08185Syz #define DPRINT_INTR_PIPE 0x00000080 31560b08185Syz #define DPRINT_PIPE_RESET 0x00000100 31660b08185Syz #define DPRINT_IN_DATA 0x00000200 31760b08185Syz #define DPRINT_OUT_DATA 0x00000400 31860b08185Syz #define DPRINT_CTLOP 0x00000800 31960b08185Syz #define DPRINT_HOTPLUG 0x00001000 32060b08185Syz #define DPRINT_PM 0x00002000 32160b08185Syz #define DPRINT_MASK_ALL 0xFFFFFFFF 32260b08185Syz 32360b08185Syz /* 32460b08185Syz * misc macros 32560b08185Syz */ 32660b08185Syz #define NELEM(a) (sizeof (a) / sizeof (*(a))) 32760b08185Syz 32860b08185Syz /* common DSD functions */ 32960b08185Syz int keyspan_tx_copy_data(keyspan_port_t *, mblk_t *, int); 33060b08185Syz void keyspan_tx_start(keyspan_port_t *, int *); 33160b08185Syz void keyspan_put_tail(mblk_t **, mblk_t *); 33260b08185Syz void keyspan_put_head(mblk_t **, mblk_t *, keyspan_port_t *); 33360b08185Syz 33460b08185Syz void keyspan_bulkin_cb(usb_pipe_handle_t, usb_bulk_req_t *); 33560b08185Syz void keyspan_bulkout_cb(usb_pipe_handle_t, usb_bulk_req_t *); 33660b08185Syz 33760b08185Syz int keyspan_restore_device(keyspan_state_t *); 33860b08185Syz int keyspan_send_cmd(keyspan_port_t *); 33960b08185Syz 34060b08185Syz int keyspan_dev_is_online(keyspan_state_t *); 34160b08185Syz 34260b08185Syz 34360b08185Syz #ifdef __cplusplus 34460b08185Syz } 34560b08185Syz #endif 34660b08185Syz 34760b08185Syz #endif /* _SYS_USB_USBSER_KEYSPAN_VAR_H */ 348