#ifndef _SYS_USB_USBSER_VAR_H
#define _SYS_USB_USBSER_VAR_H
#include <sys/tty.h>
#include <sys/mkdev.h>
#include <sys/sunddi.h>
#include <sys/note.h>
#include <sys/usb/clients/usbser/usbser_dsdi.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct usbser_state usbser_state_t;
typedef struct usbser_port usbser_port_t;
typedef struct usbser_thread {
kcondvar_t thr_cv;
uint_t thr_flags;
usbser_port_t *thr_port;
void (*thr_func)(void *);
void *thr_arg;
} usbser_thread_t;
enum {
USBSER_THR_RUNNING = 0x01,
USBSER_THR_WAKE = 0x02,
USBSER_THR_EXITED = 0x04
};
#define USBSER_DEV_INIT 0x80
struct usbser_state {
struct usbser_state *us_next;
dev_info_t *us_dip;
kmutex_t us_mutex;
void *us_statep;
int us_instance;
ds_ops_t *us_ds_ops;
ds_hdl_t us_ds_hdl;
uint_t us_port_cnt;
usbser_port_t *us_ports;
uint_t us_dev_state;
usb_log_handle_t us_lh;
ddi_taskq_t *us_taskq;
};
_NOTE(MUTEX_PROTECTS_DATA(usbser_state::us_mutex, usbser_state::us_dev_state))
struct usbser_port {
kmutex_t port_mutex;
usbser_state_t *port_usp;
char port_lh_name[16];
usb_log_handle_t port_lh;
ds_ops_t *port_ds_ops;
ds_hdl_t port_ds_hdl;
uint_t port_num;
uint_t port_state;
uint_t port_act;
uint_t port_flags;
kcondvar_t port_state_cv;
kcondvar_t port_act_cv;
kcondvar_t port_car_cv;
uint_t port_wq_data_cnt;
usbser_thread_t port_wq_thread;
usbser_thread_t port_rq_thread;
tty_common_t port_ttycommon;
uchar_t port_flowc;
timeout_id_t port_delay_id;
};
_NOTE(MUTEX_PROTECTS_DATA(usbser_port::port_mutex, usbser_port))
_NOTE(DATA_READABLE_WITHOUT_LOCK(usbser_port::{
port_usp
port_lh
port_ds_ops
port_ds_hdl
port_num
port_ttycommon.t_{readq writeq}
}))
_NOTE(LOCK_ORDER(usbser_state::us_mutex usbser_port::port_mutex))
enum {
USBSER_PORT_NOT_INIT = 0,
USBSER_PORT_CLOSED,
USBSER_PORT_OPENING_TTY,
USBSER_PORT_OPENING_OUT,
USBSER_PORT_OPEN,
USBSER_PORT_SUSPENDED,
USBSER_PORT_DISCONNECTED,
USBSER_PORT_CLOSING
};
enum {
USBSER_CONTINUE = -1,
USBSER_COMPLETE = 0
};
enum {
USBSER_ACT_TX = 0x0001,
USBSER_ACT_RX = 0x0002,
USBSER_ACT_CTL = 0x0004,
USBSER_ACT_BREAK = 0x0010,
USBSER_ACT_DELAY = 0x0020,
USBSER_ACT_ALL = 0xffff
};
enum {
USBSER_FL_OUT = 0x0001,
USBSER_FL_WOPEN = 0x0002,
USBSER_FL_CARR_ON = 0x0004,
USBSER_FL_TX_STOPPED = 0x0008,
USBSER_FL_RX_STOPPED = 0x0010,
USBSER_FL_HUNGUP = 0x0020,
USBSER_FL_DSD_OPEN = 0x0040,
USBSER_FL_STATUS_CB = 0x0080,
USBSER_FL_IGNORE_CD = 0x0100,
USBSER_FL_PRESERVE = USBSER_FL_IGNORE_CD
};
#define USBSER_PORT_ACCESS_OK(pp) ((pp)->port_state == USBSER_PORT_OPEN)
#define USBSER_PORT_IS_BUSY(pp) ((pp)->port_act != 0)
#define USBSER_PORT_IS_BUSY_NON_RX(pp) \
(((pp)->port_act & (USBSER_ACT_DELAY | USBSER_ACT_CTL | \
USBSER_ACT_BREAK | USBSER_ACT_TX)) != 0)
#define USBSER_IS_OPENING(pp) \
(((pp)->port_state == USBSER_PORT_OPENING_TTY) || \
((pp)->port_state == USBSER_PORT_OPENING_OUT))
#define USBSER_NO_OTHER_OPEN(pp, minor) \
((((minor) & OUTLINE) && \
((pp)->port_state == USBSER_PORT_OPENING_OUT)) || \
(!((minor) & OUTLINE) && ((pp)->port_state == USBSER_PORT_OPENING_TTY)))
#define USBSER_OPEN_IN_OTHER_MODE(pp, minor) \
((((minor) & OUTLINE) && !((pp)->port_flags & USBSER_FL_OUT)) || \
(!((minor) & OUTLINE) && ((pp)->port_flags & USBSER_FL_OUT)))
enum {
MAXPORTS_PER_DEVICE_SHIFT = 4,
MAXPORTS_PER_DEVICE = (1 << MAXPORTS_PER_DEVICE_SHIFT),
MAXPORTS_PER_DEVICE_MASK = (MAXPORTS_PER_DEVICE - 1),
OUTLINE = (1 << (NBITSMINOR32 - 1))
};
#define USBSER_MAKEMINOR(instance, port, outline) \
((port) | ((instance) << MAXPORTS_PER_DEVICE_SHIFT) | (outline))
#define USBSER_MINOR2INST(minor) \
(((minor) & ~(OUTLINE | MAXPORTS_PER_DEVICE_MASK)) \
>> MAXPORTS_PER_DEVICE_SHIFT)
#define USBSER_MINOR2PORT(minor) ((minor) & MAXPORTS_PER_DEVICE_MASK)
enum {
USBSER_TX_FIFO_DRAIN_TIMEOUT = 5,
USBSER_WQ_DRAIN_TIMEOUT = 2,
USBSER_SUSPEND_TIMEOUT = 10
};
#define DPRINT_ATTACH 0x00000001
#define DPRINT_DETACH 0x00000002
#define DPRINT_OPEN 0x00000004
#define DPRINT_CLOSE 0x00000008
#define DPRINT_WQ 0x00000010
#define DPRINT_RQ 0x00000020
#define DPRINT_IOCTL 0x00000040
#define DPRINT_RX_CB 0x00000100
#define DPRINT_TX_CB 0x00000200
#define DPRINT_STATUS_CB 0x00000400
#define DPRINT_EVENTS 0x00001000
#define DPRINT_CPR 0x00002000
#define DPRINT_MASK_ALL 0xFFFFFFFF
#define NELEM(a) (sizeof (a) / sizeof (*(a)))
#define USBSER_DS_ATTACH(usp, aip) usp->us_ds_ops->ds_attach(aip)
#define USBSER_DS_DETACH(usp) usp->us_ds_ops->ds_detach(usp->us_ds_hdl)
#define USBSER_DS_OPEN_PORT(usp, port_num) \
usp->us_ds_ops->ds_open_port(usp->us_ds_hdl, port_num)
#define USBSER_DS_CLOSE_PORT(usp, port_num) \
usp->us_ds_ops->ds_close_port(usp->us_ds_hdl, port_num)
#define USBSER_DS_REGISTER_CB(usp, port_num, cb) \
usp->us_ds_ops->ds_register_cb(usp->us_ds_hdl, port_num, cb)
#define USBSER_DS_UNREGISTER_CB(usp, port_num) \
usp->us_ds_ops->ds_unregister_cb(usp->us_ds_hdl, port_num)
#define USBSER_DS_USB_POWER(usp, comp, level, new_statep) \
usp->us_ds_ops->ds_usb_power(usp->us_ds_hdl, comp, level, new_statep)
#define USBSER_DS_SUSPEND(usp) usp->us_ds_ops->ds_suspend(usp->us_ds_hdl)
#define USBSER_DS_RESUME(usp) usp->us_ds_ops->ds_resume(usp->us_ds_hdl)
#define USBSER_DS_DISCONNECT(usp) usp->us_ds_ops->ds_disconnect(usp->us_ds_hdl)
#define USBSER_DS_RECONNECT(usp) usp->us_ds_ops->ds_reconnect(usp->us_ds_hdl)
#define USBSER_DS_SET_PORT_PARAMS(pp, params) \
pp->port_ds_ops->ds_set_port_params(pp->port_ds_hdl, pp->port_num, \
params)
#define USBSER_DS_SET_MODEM_CTL(pp, mask, val) \
pp->port_ds_ops->ds_set_modem_ctl(pp->port_ds_hdl, pp->port_num, mask, \
val)
#define USBSER_DS_GET_MODEM_CTL(pp, mask, valp) \
pp->port_ds_ops->ds_get_modem_ctl(pp->port_ds_hdl, pp->port_num, \
mask, valp)
#define USBSER_DS_BREAK_CTL(pp, val) \
pp->port_ds_ops->ds_break_ctl(pp->port_ds_hdl, pp->port_num, val)
#define USBSER_DS_LOOPBACK(pp, val) \
pp->port_ds_ops->ds_loopback(pp->port_ds_hdl, pp->port_num, val)
#define USBSER_DS_TX(pp, mp) \
pp->port_ds_ops->ds_tx(pp->port_ds_hdl, pp->port_num, mp)
#define USBSER_DS_RX(pp) \
pp->port_ds_ops->ds_rx(pp->port_ds_hdl, pp->port_num)
#define USBSER_DS_STOP(pp, dir) \
pp->port_ds_ops->ds_stop(pp->port_ds_hdl, pp->port_num, dir)
#define USBSER_DS_START(pp, dir) \
pp->port_ds_ops->ds_start(pp->port_ds_hdl, pp->port_num, dir)
#define USBSER_DS_FIFO_FLUSH(pp, mask) \
pp->port_ds_ops->ds_fifo_flush(pp->port_ds_hdl, pp->port_num, mask)
#define USBSER_DS_FIFO_DRAIN(pp, tmout) \
pp->port_ds_ops->ds_fifo_drain(pp->port_ds_hdl, pp->port_num, tmout)
#define USBSER_DS_LOOPBACK_SUPPORTED(pp) (pp->port_ds_ops->ds_loopback != 0)
#ifdef __cplusplus
}
#endif
#endif