keyspan_dsd.c revision 02dd21081e66fa04b4c6f0962352e15edcabfbb0
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
*
* DSD code for keyspan usb2serial adapters
*
*/
#define USBDRV_MAJOR_VER 2
#define USBDRV_MINOR_VER 0
/*
* DSD operations which are filled in ds_ops structure.
*/
static int keyspan_attach(ds_attach_info_t *);
static void keyspan_detach(ds_hdl_t);
/* power management */
static int keyspan_usb_power(ds_hdl_t, int, int, int *);
static int keyspan_suspend(ds_hdl_t);
static int keyspan_resume(ds_hdl_t);
/* hotplug */
static int keyspan_disconnect(ds_hdl_t);
static int keyspan_reconnect(ds_hdl_t);
/* standard UART operations */
/* data xfer */
/*
* Sub-routines
*/
/* configuration routines */
static void keyspan_free_soft_state(keyspan_state_t *);
static void keyspan_init_sync_objs(keyspan_state_t *);
static void keyspan_fini_sync_objs(keyspan_state_t *);
static int keyspan_usb_register(keyspan_state_t *);
static void keyspan_usb_unregister(keyspan_state_t *);
static int keyspan_attach_dev(keyspan_state_t *);
static void keyspan_attach_ports(keyspan_state_t *);
static void keyspan_detach_ports(keyspan_state_t *);
static void keyspan_init_port_params(keyspan_state_t *);
static void keyspan_free_descr_tree(keyspan_state_t *);
static int keyspan_register_events(keyspan_state_t *);
static void keyspan_unregister_events(keyspan_state_t *);
static void keyspan_set_dev_state_online(keyspan_state_t *);
/* hotplug */
static int keyspan_restore_device_state(keyspan_state_t *);
static int keyspan_restore_ports_state(keyspan_state_t *);
/* power management */
static int keyspan_create_pm_components(keyspan_state_t *);
static void keyspan_destroy_pm_components(keyspan_state_t *);
static int keyspan_pm_set_busy(keyspan_state_t *);
static void keyspan_pm_set_idle(keyspan_state_t *);
static int keyspan_pwrlvl0(keyspan_state_t *);
static int keyspan_pwrlvl1(keyspan_state_t *);
static int keyspan_pwrlvl2(keyspan_state_t *);
static int keyspan_pwrlvl3(keyspan_state_t *);
/* pipe operations */
static int keyspan_attach_pipes(keyspan_state_t *);
static void keyspan_detach_pipes(keyspan_state_t *);
static void keyspan_disconnect_pipes(keyspan_state_t *);
static int keyspan_reconnect_pipes(keyspan_state_t *);
/* data transfer routines */
static int keyspan_wait_tx_drain(keyspan_port_t *, int);
/* misc */
static void keyspan_default_port_params(keyspan_port_t *);
static void keyspan_save_port_params(keyspan_port_t *);
/*
* Model specific functions.
*/
/* usa19hs specific functions */
static void keyspan_build_cmd_msg_usa19hs(keyspan_port_t *,
ds_port_params_t *);
static void keyspan_default_port_params_usa19hs(keyspan_port_t *);
static void keyspan_save_port_params_usa19hs(keyspan_port_t *);
/* usa49 specific functions */
static void keyspan_build_cmd_msg_usa49(keyspan_port_t *,
ds_port_params_t *);
static void keyspan_default_port_params_usa49(keyspan_port_t *);
static void keyspan_save_port_params_usa49(keyspan_port_t *);
/*
* DSD ops structure
*/
};
/*
* For USA19HS baud speed, precalculated using the following algorithm:
*
* speed = (uint16_t)(14769231L / baud);
*/
static uint16_t keyspan_speedtab_usa19hs[] = {
0x0, /* B0 */
0x481d, /* B50 */
0x3013, /* B75 */
0x20c7, /* B110 */
0x1ae8, /* B134 */
0x1809, /* B150 */
0x1207, /* B200 */
0xc04, /* B300 */
0x602, /* B600 */
0x301, /* B1200 */
0x200, /* B1800 */
0x180, /* B2400 */
0xc0, /* B4800 */
0x60, /* B9600 */
0x30, /* B19200 */
0x18, /* B38400 */
0x10, /* B57600 */
0xc, /* B76800 */
0x8, /* B115200 */
0x6, /* B153600 */
0x4, /* B230400 */
};
/*
* For USA49WLC baud speed, precalculated.
*/
static uint16_t keyspan_speedtab_usa49[] = {
0x0, /* B0 */
0x7530, /* B50 */
0x4e20, /* B75 */
0x3544, /* B110 */
0x2bba, /* B134 */
0x2710, /* B150 */
0x1d4c, /* B200 */
0x1388, /* B300 */
0x9c4, /* B600 */
0x4e2, /* B1200 */
0x25e, /* B1800 */
0x271, /* B2400 */
0xfa, /* B4800 */
0x7d, /* B9600 */
0x19, /* B19200 */
0x27, /* B38400 */
0x1a, /* B57600 */
0xd, /* B76800 */
0xd, /* B115200 */
0x6, /* B153600 */
0x4, /* B230400 */
};
/*
* For USA49WLC prescaler, precalculated.
*/
static uint8_t keyspan_prescaler_49wlc[] = {
0x0, /* B0 */
0x8, /* B50 */
0x8, /* B75 */
0x8, /* B110 */
0x8, /* B134 */
0x8, /* B150 */
0x8, /* B200 */
0x8, /* B300 */
0x8, /* B600 */
0x8, /* B1200 */
0xb, /* B1800 */
0x8, /* B2400 */
0xa, /* B4800 */
0xa, /* B9600 */
0x19, /* B19200 */
0x8, /* B38400 */
0x8, /* B57600 */
0xc, /* B76800 */
0x8, /* B115200 */
0xd, /* B153600 */
0xd, /* B230400 */
};
/* convert baud code into baud rate */
static int keyspan_speed2baud[] = {
0, /* B0 */
50, /* B50 */
75, /* B75 */
110, /* B110 */
134, /* B134 */
150, /* B150 */
200, /* B200 */
300, /* B300 */
600, /* B600 */
1200, /* B1200 */
1800, /* B1800 */
2400, /* B2400 */
4800, /* B4800 */
9600, /* B9600 */
19200, /* B19200 */
38400, /* B38400 */
57600, /* B57600 */
76800, /* B76800 */
115200, /* B115200 */
153600, /* B153600 */
230400, /* B230400 */
};
/* debug support */
static int
{
int rval = USB_SUCCESS;
KM_SLEEP);
goto fail_register;
}
/* init mutex and semaphore */
/* get device specific parameters */
goto fail_attach_dev;
}
case KEYSPAN_USA19HS_PID:
case KEYSPAN_USA49WLC_PID:
break;
case KEYSPAN_USA49WG_PID:
break;
default:
"the device's product id can't be recognized");
return (USB_FAILURE);
}
if (rval != USB_SUCCESS) {
"keyspan_init_pipes: failed.");
goto fail_init_pipes;
}
"keyspan_create_pm_components: failed.");
goto fail_pm;
}
goto fail_events;
}
/* open the global pipes */
"keyspan_attach_pipes: failed.");
goto fail_attach_pipes;
}
return (USB_SUCCESS);
return (USB_FAILURE);
}
/*
* ds_detach
*/
static void
{
}
/*
* ds_register_cb
*/
static int
{
return (USB_FAILURE);
}
return (USB_SUCCESS);
}
/*
* ds_unregister_cb
*/
static void
{
}
}
/*
* initialize hardware serial port
*
* 'open_pipes' specifies whether to open USB pipes or not
*/
int
{
int rval;
if (open_pipes) {
/* open r/w pipes for this port */
return (rval);
}
}
case KEYSPAN_USA19HS_PID:
case KEYSPAN_USA49WLC_PID:
goto fail;
}
break;
case KEYSPAN_USA49WG_PID:
/* open data in pipe the first time, start receiving data */
goto fail;
}
/* the device is reconnected to host, restart receiving data */
goto fail;
}
ksp->ks_reconnect_flag = 0;
} else {
}
break;
default:
"the device's product id can't be recognized");
return (USB_FAILURE);
}
/* set the default port parameters and send cmd msg to enable port */
(void) keyspan_send_cmd(kp);
return (rval);
fail:
if (open_pipes) {
/* close all ports' data pipes */
}
"keyspan_open_hw_port: failed. This port can't be used.");
return (rval);
}
/*
* ds_open_port
*/
static int
{
int rval;
return (USB_FAILURE);
}
return (USB_FAILURE);
}
return (USB_FAILURE);
}
/*
* initialize state
*/
/*
* initialize hardware serial port, B_TRUE means open pipes
*/
if (rval != USB_SUCCESS) {
}
return (rval);
}
/*
* close hardware serial port
*/
void
{
"keyspan_close_hw_port");
/*
* a device disconnect event. So its required to check the
* pipe handle and proceed if it is not NULL
*/
return;
}
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_close_hw_port:"
"the device's product id can't be recognized");
return;
}
/* send close port cmd to this port */
"keyspan_close_hw_port: closing hw port, send cmd FAILED");
}
/* blow away bulkin requests or pipe close will wait until timeout */
case KEYSPAN_USA19HS_PID:
case KEYSPAN_USA49WLC_PID:
break;
case KEYSPAN_USA49WG_PID:
/*
* if only this port is opened, shared data in pipe
* can be reset.
*/
} else {
}
break;
default:
"keyspan_close_hw_port: the device's product id can't"
"be recognized");
}
(void) keyspan_close_port_pipes(kp);
}
/*
* ds_close_port
*/
static int
{
return (USB_FAILURE);
}
/* close hardware serial port */
/*
* free resources and finalize state
*/
}
}
return (USB_SUCCESS);
}
/*
* power management
*
* ds_usb_power
*/
/*ARGSUSED*/
static int
{
int rval;
/*
* check if we are transitioning to a legal power level
*/
"illegal power level %d, pwr_states=%x",
return (USB_FAILURE);
}
/*
* if we are about to raise power and asked to lower power, fail
*/
return (USB_FAILURE);
}
switch (level) {
case USB_DEV_OS_PWR_OFF:
break;
case USB_DEV_OS_PWR_1:
break;
case USB_DEV_OS_PWR_2:
break;
case USB_DEV_OS_FULL_PWR:
break;
default:
ASSERT(0); /* cannot happen */
}
return (rval);
}
/*
* ds_suspend
*/
static int
{
int state;
return (state);
}
/*
* ds_resume
*/
static int
{
int current_state;
int rval;
/* needed as power up state of dev is "unknown" to system */
if (current_state != USB_DEV_ONLINE) {
} else {
rval = USB_SUCCESS;
}
return (rval);
}
/*
* ds_disconnect
*/
static int
{
int state;
return (state);
}
/*
* ds_reconnect
*/
static int
{
return (keyspan_restore_device_state(ksp));
}
/*
* ds_set_port_params
*/
static int
{
"keyspan_set_port_params: port: %d params", cnt);
if (cnt <= 0) {
return (USB_SUCCESS);
}
"keyspan_send_cmd() FAILED");
return (USB_FAILURE);
}
return (USB_SUCCESS);
}
/*
* ds_set_modem_ctl
*/
static int
{
case KEYSPAN_USA19HS_PID:
} else {
}
} else {
}
} else {
}
} else {
}
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
} else {
}
} else {
}
} else {
}
} else {
}
break;
default:
"keyspan_get_modem_ctl:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
"keyspan_send_cmd() FAILED");
return (USB_FAILURE);
}
return (USB_SUCCESS);
}
/*
* ds_get_modem_ctl
*/
static int
{
int val = 0;
/*
* rts and dtr are not in status_msg, but we can get it from
* status_flag since it represents what we set the device last time.
*/
}
}
/* usbser don't deal with TIOCM_RI status */
case KEYSPAN_USA19HS_PID:
}
}
}
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
}
}
}
break;
default:
"keyspan_get_modem_ctl:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
"success. status_flag = %x, val=0%o",
return (USB_SUCCESS);
}
/*
* ds_break_ctl
*/
static int
{
int is_break;
int rval = USB_SUCCESS;
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_break_ctl:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
return (rval);
}
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_break_ctl:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
if (rval == USB_SUCCESS) {
/* resume transmit */
}
return (rval);
}
"keyspan_break_ctl: not necessary to set break, is_break = %d",
is_break);
return (rval);
}
/*
* ds_loopback
*/
static int
{
int is_loop;
int rval = USB_SUCCESS;
/* check bit indicating internal loopback state */
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_loopback:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_loopback:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
} else {
"keyspan_loopback: not necessary to set loopback,"
"is_loop = %d", is_loop);
}
return (rval);
}
/*
* ds_tx
*/
static int
{
int xferd;
/*
* sanity checks
*/
return (USB_SUCCESS);
}
return (USB_SUCCESS);
}
/*
* ds_rx. the real data receiving is in keyspan_open_hw_port
*/
static mblk_t *
{
return (mp);
}
/*
* ds_stop
*/
static void
{
}
}
/*
* ds_start
*/
static void
{
}
}
}
/*
* ds_fifo_flush
* send flush cmd and wait for completion, then turn off the flush.
*/
static int
{
"keyspan_fifo_flush: dir=%x", dir);
/* discard the data in DSD buffers */
}
}
return (USB_SUCCESS);
}
/*
* ds_fifo_drain
*
* it is the caller's responsibility to cease submitting new tx data
* while this function executes
*/
static int
{
int rval = USB_SUCCESS;
"keyspan_fifo_drain, timeout = %d", timeout);
/* wait until local data drains */
return (USB_FAILURE);
}
/* wait until hw fifo drains */
return (rval);
}
/*
* configuration routines
* ----------------------
*
*/
/*
* free state structure
*/
static void
{
}
/*
* register/unregister USBA client
*/
static int
{
int rval;
if (rval == USB_SUCCESS) {
USB_PARSE_LVL_IF, 0);
if (rval == USB_SUCCESS) {
&keyspan_instance_debug, 0);
}
}
return (rval);
}
static void
{
}
/*
*/
static void
{
}
static void
{
}
/*
* device specific attributes
*/
static int
{
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
break;
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_attach_dev:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
return (USB_SUCCESS);
}
/*
* allocate and initialize per port resources.
*/
static void
{
int i;
sizeof (keyspan_port_t), KM_SLEEP);
kp->kp_port_num = i;
&keyspan_instance_debug, 0);
}
}
/*
* free per port resources
*/
static void
{
int i;
}
}
}
static void
{
int i;
/* the max data len of every bulk in req. */
USB_SUCCESS) {
} else {
}
} else {
} else {
}
}
/* the max data len of every bulk out req. */
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
break;
case KEYSPAN_USA49WG_PID:
/*
* USA49WG port0 uses intr out pipe send data while
* other ports use bulk out pipes, so port0's max
* packet length for "bulk out" is different from other
* ports' while the same as USA49WLC.
*/
write_len = ((i == 0) ? KEYSPAN_BULKOUT_MAX_LEN_49WLC :
break;
default:
"keyspan_init_port_params:"
"the device's product id can't be recognized");
return;
}
}
}
/*
* free descriptor tree
*/
static void
{
}
/*
* register/unregister USB event callbacks
*/
static int
{
}
static void
{
}
static void
{
}
/*
* send command to the port and save the params after its completion for
* USA19HS and USA49WLC
*/
int
{
int rval = USB_SUCCESS;
int size;
case KEYSPAN_USA19HS_PID:
size = sizeof (keyspan_usa19hs_port_ctrl_msg_t);
break;
case KEYSPAN_USA49WLC_PID:
size = sizeof (keyspan_usa49_port_ctrl_msg_t);
break;
default:
"keyspan_send_cmd_usa49:"
"the device's product id can't be recognized");
return (USB_FAILURE);
}
return (USB_FAILURE);
}
if (rval == USB_SUCCESS) {
} else {
": failure, rval=%d", rval);
}
return (rval);
}
/*
* send command to the port and save the params after its completion for
* USA_49WG only
*/
int
{
int rval = USB_SUCCESS;
int size = sizeof (keyspan_usa49_port_ctrl_msg_t);
return (USB_FAILURE);
}
if (rval == USB_SUCCESS) {
} else {
"keyspan_send_cmd_usa49wg: failure, rval=%d", rval);
}
if (mp) {
}
return (rval);
}
/*
* send command to the port and save the params after its completion
*/
int
{
int rval = USB_FAILURE;
case KEYSPAN_USA19HS_PID:
case KEYSPAN_USA49WLC_PID:
break;
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_send_cmd: "
"the device's product id can't be recognized");
}
if (rval != USB_SUCCESS) {
"keyspan_send_cmd() FAILED");
return (rval);
}
return (USB_SUCCESS);
}
/*
* hotplug
* -------
*
* restore device state after CPR resume or reconnect
*/
static int
{
int state;
return (state);
}
return (state);
}
if (state == USB_DEV_DISCONNECTED) {
"device has been reconnected but data may have been lost");
}
return (state);
}
/*
* init device state
*/
/*
* now restore each open port
*/
(void) keyspan_restore_ports_state(ksp);
return (state);
}
/*
* restore ports state after CPR resume or reconnect
*/
static int
{
int rval = USB_SUCCESS;
int err;
int i;
/*
* only care about open ports
*/
continue;
}
/* open hardware serial port */
if (err != USB_SUCCESS) {
"keyspan_restore_ports_state: failed");
}
}
return (rval);
}
/*
* power management
* ----------------
*
*
* create PM components
*/
static int
{
"keyspan_create_pm_components: failed");
return (USB_SUCCESS);
}
return (USB_SUCCESS);
}
/*
* destroy PM components
*/
static void
{
int rval;
if (pm->pm_wakeup_enabled) {
if (rval != USB_SUCCESS) {
"keyspan_destroy_pm_components: disable "
"remote wakeup failed, rval=%d", rval);
}
}
}
}
/*
* mark device busy and raise power
*/
static int
{
/* if already marked busy, just increment the counter */
if (pm->pm_busy_cnt++ > 0) {
return (USB_SUCCESS);
}
(void) pm_busy_component(dip, 0);
return (USB_SUCCESS);
}
/* need to raise power */
"keyspan_pm_set_busy: raise power");
return (USB_SUCCESS);
}
/*
* mark device idle
*/
static void
{
/*
* if more ports use the device, do not mark as yet
*/
if (--pm->pm_busy_cnt > 0) {
return;
}
(void) pm_idle_component(dip, 0);
}
/*
* Functions to handle power transition for OS levels 0 -> 3
*/
static int
{
int rval;
switch (ksp->ks_dev_state) {
case USB_DEV_ONLINE:
/* issue USB D3 command to the device */
}
/* FALLTHRU */
case USB_DEV_DISCONNECTED:
case USB_DEV_SUSPENDED:
/* allow a disconnect/cpr'ed device to go to lower power */
return (USB_SUCCESS);
case USB_DEV_PWRED_DOWN:
default:
"keyspan_pwrlvl0: illegal device state");
return (USB_FAILURE);
}
}
static int
{
/* issue USB D2 command to the device */
return (USB_FAILURE);
}
static int
{
/* issue USB D1 command to the device */
return (USB_FAILURE);
}
static int
{
int rval;
switch (ksp->ks_dev_state) {
case USB_DEV_PWRED_DOWN:
/* Issue USB D0 command to the device here */
}
/* FALLTHRU */
case USB_DEV_ONLINE:
/* we are already in full power */
/* FALLTHRU */
case USB_DEV_DISCONNECTED:
case USB_DEV_SUSPENDED:
return (USB_SUCCESS);
default:
"keyspan_pwrlvl3: illegal device state");
return (USB_FAILURE);
}
}
/*
* pipe operations
* ---------------
*
* XXX keyspan seem to malfunction after the pipes are closed
* and reopened again (does not respond to OPEN_PORT command).
* so we open them once in attach
*/
static int
{
return (keyspan_open_dev_pipes(ksp));
}
void
{
/*
* Blow away status bulk in requests or
* pipe close will wait until timeout.
*/
}
/* Close the globle pipes */
}
/*
* during device disconnect/suspend, close pipes if they are open.
*/
static void
{
}
/*
*/
static int
{
int rval = USB_SUCCESS;
return (rval);
}
/*
* data transfer routines
* ----------------------
*
*
* start data transmit
*/
void
{
int len; /* # of bytes we can transmit */
int data_len = 0; /* # of bytes in 'data' */
int tran_len;
int rval;
int status_len = 0;
if (xferd) {
*xferd = 0;
}
return;
}
/*
* Some keyspan adapters, such as usa49wlc,
* need use the first byte as flag.
*/
case KEYSPAN_USA19HS_PID:
return;
}
/* copy at most 'len' bytes from mblk chain for transmission */
if (data_len <= 0) {
"keyspan_tx_start:keyspan_tx_copy_data copied"
" zero bytes");
}
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
return;
}
/*
* the data format is [status byte][63 data bytes][...][status]
* byte][up to 63 bytes] according to keyspan spec
*/
/* Add status byte per 63 data bytes */
/* copy at most 63 bytes from mblk chain for trans */
if (tran_len <= 0) {
"keyspan_tx_start:keyspan_tx_copy_data copied"
" zero bytes");
break;
}
}
break;
default:
"the device's product id can't be recognized");
return;
}
/*
* For USA-49WG, the port0 uses intr out pipe as data out pipe, while
* other ports use bulk out pipe.
*/
if ((kp->kp_port_num == 0) &&
} else {
}
/*
* if send failed, put data back
*/
if (rval != USB_SUCCESS) {
} else if (xferd) {
}
}
/*
* copy no more than 'len' bytes from mblk chain to transmit mblk 'data'.
* return number of bytes copied
*/
int
{
int copylen; /* # of bytes to copy from 'mp' to 'data' */
int data_len = 0;
return (data_len);
}
} else {
}
}
"copied data_len = %d", data_len);
return (data_len);
}
/*
* wait until local tx buffer drains.
* 'timeout' is in seconds, zero means wait forever
*/
static int
{
int over = 0;
"timeout = %d", timeout);
if (timeout > 0) {
} else {
}
}
}
/*
* returns 0 if device is not online, != 0 otherwise
*/
int
{
int rval;
return (rval);
}
/*
* link a message block to tail of message
* account for the case when message is null
*/
void
{
if (*mpp) {
} else {
}
}
/*
* put a message block at the head of the message
* account for the case when message is null
*/
void
{
case KEYSPAN_USA19HS_PID:
if (*mpp) {
}
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
/* get rid of the first byte of the msg data which is a flag */
if (*mpp) {
}
break;
default:
"the device's product id can't be recognized");
return;
}
}
/*
* Set the port parameters to default values
*/
static void
{
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_default_port_params:"
"the device's product id can't be recognized");
}
"keyspan_default_port_params: setted.");
}
/*
* Build the command message according to the params from usbser.
* The message will then be sent to deivce by keyspan_send_cmd.
*/
static void
{
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_build_cmd_msg:"
"the device's product id can't be recognized");
}
}
/* save the port params after send cmd successfully */
static void
{
case KEYSPAN_USA19HS_PID:
break;
case KEYSPAN_USA49WLC_PID:
case KEYSPAN_USA49WG_PID:
break;
default:
"keyspan_save_port_params:"
"the device's product id can't be recognized");
}
"keyspan_save_port_params: baud = %x, lcr = %x,"
}
/* save the port params after send cmd successfully */
static void
{
if (ctrl_msg->setClocking) {
}
}
} else {
}
}
} else {
}
}
if (ctrl_msg->portEnabled) {
} else {
}
"keyspan_save_port_params: baud = %x, lcr = %x,"
}
/*
* Set the port parameters to default values
*/
static void
{
/* set baud rate to 9600 */
}
/*
* Build the command message according to the params from usbser.
* The message will then be sent to deivce by keyspan_send_cmd.
*/
static void
{
int cnt, i;
"keyspan_build_cmd_msg_usa19hs: tp = %p", (void *)tp);
/* bzero all elements */
/* it is usaually 16, according to Keyspan spec */
/* from 1ms to 31ms, according to Keyspan spec. */
return;
}
/* translate tp parameters into cmd_msg elements */
case DS_PARAM_BAUD:
/*
* if we don't support this speed,
* then return failure.
*/
"keyspan_build_cmd_msg_usa19hs:"
" bad baud %d", ui);
break;
}
/* if the same as the old rate, need not set the rate */
"keyspan_build_cmd_msg_usa19hs:"
" same as old baud setting, baud = %d",
break;
}
& 0xff;
"keyspan_build_cmd_msg_usa19hs: baud=%d",
break;
case DS_PARAM_PARITY:
/*
* Since USA_PARITY_NONE == 0, it's not
* necessary to or it in here.
*/
} else {
}
}
"keyspan_build_cmd_msg_usa19hs: parity=%x,lcr = %x",
break;
case DS_PARAM_STOPB:
} else {
/*
* STOPBITS_5678_1 equals zero,
* so it's not necessary to or it in.
*/
"keyspan_build_cmd_msg_usa19hs:"
" STOPBITS_5678_1");
}
"keyspan_build_cmd_msg_usa19hs: stopb=%x, lcr = %x",
break;
case DS_PARAM_CHARSZ:
case CS5:
/*
* USA_DATABITS_5 equals zero,
* not necessary to or it in.
*/
"keyspan_build_cmd_msg_usa19hs:"
" USA_DATABITS_5");
break;
case CS6:
break;
case CS7:
break;
case CS8:
default:
/*
* The default value is USA_DATABITS_8. It is
* safe to set to the default one here.
*/
break;
}
"keyspan_build_cmd_msg_usa19hs: cs=%x, lcr = %x",
break;
case DS_PARAM_XON_XOFF:
"keyspan_build_cmd_msg_usa19hs: xonChar=%x, "
break;
case DS_PARAM_FLOW_CTL:
} else {
/* Clear the tx flow control setting */
ctrl_msg->txFlowControl = 0;
}
} else {
/* Clear the rx flow control setting */
ctrl_msg->rxFlowControl = 0;
}
"keyspan_build_cmd_msg_usa19hs: txFlowControl = %x,"
break;
default:
"keyspan_build_cmd_msg_usa19hs: bad param %d",
break;
}
}
/*
* Enable the lcr settings only if they are different
* with the existing settings.
*/
}
/*
* Build the command message according to the params from usbser.
* The message will then be sent to deivce by keyspan_send_cmd.
*/
static void
{
int cnt, i;
"keyspan_build_cmd_msg_usa49: tp = %p", (void *)tp);
/* bzero all elements */
/* it is usaually 16, according to Keyspan spec */
return;
}
/* translate tp parameters into cmd_msg elements */
case DS_PARAM_BAUD:
/*
* If we don't support this speed,
* then return failure.
*/
"keyspan_build_cmd_msg_usa49:"
" bad baud %d", ui);
break;
}
/* if the same as the old rate, need not set the rate */
"keyspan_build_cmd_msg_usa49: "
"same as old baud setting, baud = %d",
break;
}
& 0xff;
"keyspan_build_cmd_msg_usa49: baud=%d",
break;
case DS_PARAM_PARITY:
/*
* Since USA_PARITY_NONE == 0,
* it's not necessary to or it in here.
*/
} else {
}
}
"keyspan_build_cmd_msg_usa49: parity=%x, lcr = %x",
break;
case DS_PARAM_STOPB:
} else {
/*
* STOPBITS_5678_1 equals zero,
* not necessary to or it in.
*/
"keyspan_build_cmd_msg_usa49: "
"STOPBITS_5678_1");
}
"keyspan_build_cmd_msg_usa49: stopb=%x, lcr = %x",
break;
case DS_PARAM_CHARSZ:
case CS5:
/*
* USA_DATABITS_5 equals zero,
* not necessary to or it in.
*/
"keyspan_build_cmd_msg_usa49:"
" USA_DATABITS_5");
break;
case CS6:
break;
case CS7:
break;
case CS8:
default:
break;
}
"keyspan_build_cmd_msg_usa49: cs=%x, lcr = %x",
break;
case DS_PARAM_XON_XOFF:
"keyspan_build_cmd_msg_usa49: xonChar=%x, "
break;
case DS_PARAM_FLOW_CTL:
} else {
ctrl_msg->ctsFlowControl = 0;
}
"keyspan_build_cmd_msg_usa49: "
"pe->val.ui = %x, flow_ctl: RTSXOFF, "
}
"keyspan_build_cmd_msg_usa49: ctsFlowControl = %x,"
break;
default:
"keyspan_build_cmd_msg_usa49: bad param %d",
break;
}
}
/*
* enable the lcr settings only if they are different
* with the existing settings.
*/
}
/*
* Set the port parameters to default values
*/
static void
{
ctrl_msg->resetDataToggle = 0;
ctrl_msg->disablePort = 0;
/* set baud rate to 9600 */
}
/* save the port params after send cmd successfully */
static void
{
if (ctrl_msg->setClocking) {
}
}
} else {
}
}
} else {
}
}
if (ctrl_msg->enablePort) {
} else {
}
/*
* There are no flags in status msg (49wlc) can indicate the
* break status, so we make use of ctrl_msg->txBreak here.
*/
} else {
}
"keyspan_save_port_params: baud = %x, lcr = %x,"
}