ttymux_ioctl.c revision 544f04c0a127b3f42f33facf10edfc0e0d896bc3
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* DESCRIPTION
*
* ttymux_ioctl - Handler for ttymux specific ioctl calls.
*
*/
#include "ttymux_impl.h"
/*
* Extern declarations
*/
extern int nulldev();
/*
* Imported ttymux routines
*/
extern void sm_debug(char *, ...);
extern void sm_log(char *, ...);
extern sm_lqi_t *get_lqi_byid(int);
/*
* Exported ttymux routines
*/
int ttymux_abort_ioctl(mblk_t *);
int ttymux_device_init(sm_lqi_t *);
int ttymux_device_fini(sm_lqi_t *);
/*
* Imported ttymux variables
*/
static int
{
return (EINVAL);
#ifdef _SYSCALL32_IMPL
return (EINVAL);
} else
#endif
return (EINVAL);
} else {
}
return (0);
}
/*
* Given a device path return an OBP alias for it if it exists.
*/
static char *
{
char *buf1;
char *buf2;
int proplen;
if (node == OBP_BADNODE)
return (NULL);
/*
* Ask for first property by passing a NULL string
*/
buf1[0] = '\0';
break; /* end of prop list */
if (proplen == 0)
continue;
return (buf2);
}
}
return (NULL);
}
/*
* Tell OBP that this device is now usable
*/
static void
{
char *enb_str = "\" enable-device\" rot $call-method";
if (!cn->sm_obp_con)
return;
}
/*
* Tell OBP that this device is no longer usable
*/
static void
{
char *dis_str = "\" disable-device\" rot $call-method";
if (!cn->sm_obp_con)
return;
}
static void
{
return;
cn->sm_obp_con));
/*
* Indicate to the linked device that it is
* providing a multiplexed console.
*/
DDI_PROP_CANSLEEP, "obp-input-console", 0, 0);
DDI_PROP_CANSLEEP, "obp-output-console", 0, 0);
}
if (flags) {
if (cn->sm_obp_con)
}
/*
* Tell OBP that its ok to use this console
*/
}
static void
{
return;
/*
* Indicate to the linked device that it is no longer
* providing a multiplexed console.
*/
ldip, "obp-input-console");
ldip, "obp-output-console");
}
}
static int
{
if (proplen < 0)
return (proplen);
if (proplen > 0)
else
*propval = 0;
return (proplen);
}
/*
* Parse a list of tokens
*/
static char *
{
if (p == 0 || *p == 0)
return (NULL);
e = p + strlen(p);
do {
*p = 0;
*lasts = p + 1;
return (tok);
}
tok = p;
}
} while (++p < e);
return (tok);
return (NULL);
}
/*
* Add or remove an alias from a property list of aliases:
* path: an OBP device path
* pname: property name containing a space separated list of aliases
* append: if true include the alias for path in the property list
* otherwise remove the alias from the list.
*/
static int
{
char *pval; /* value of property */
char *aliases[TTYMUX_MAX_LINKS];
return (1);
}
return (1);
char *aval;
continue;
/* does this alias match the requested path */
goto out;
}
} else {
}
}
if (append) {
goto out;
if (mnode != 0) {
*mnode = '\0';
*mnode = ':';
}
}
goto out;
}
} else if (!found) {
goto out;
}
if (len == 0)
goto out;
for (i = 0; ; ) {
if (++i == cnt)
break;
}
out:
return (0);
}
/*
*
*/
static int
{
return (1);
}
if (prom_is_openprom() == 0)
return (0);
return (0);
}
/*
* Convert a dev_t to a device path
*/
static char *
{
char *p, *path;
return (NULL);
}
return (path);
}
static int
{
uint_t j;
"TTYMUX_DISASSOC" : "TTYMUX_ASSOC"));
return (EINVAL);
}
}
return (0);
}
break;
break;
}
}
if (cmd == TTYMUX_DISASSOC) {
if (j == ms->sm_cons_cnt) {
return (0);
}
/*
* Disable the console in OBP and then delete this console
* this console - note that this also deletes OBP
* information - i.e. once it is disassociated it cannot
* be reused as an OBP console - roll on polled I/O!
*/
else
}
}
if (ms->sm_cons_cnt > 0)
j, ms->sm_cons_cnt));
} else if (cmd == TTYMUX_ASSOC) {
if (j == ms->sm_cons_cnt) {
if (j == TTYMUX_MAX_LINKS) {
return (ENOMEM);
}
} else {
}
} else {
KM_SLEEP);
}
else
}
"TTYMUX_DISASSOC" : "TTYMUX_ASSOC"));
return (0);
}
static int
{
int j, cnt;
if (ms == 0)
return (0);
cn++, j++) {
a->ttymux_tag = (uint_t)0;
a->ttymux_ldev = NODEV;
cnt++;
a++;
}
}
return (cnt);
}
#ifdef _SYSCALL32_IMPL
/*
* Look for any consoles that are not currently plumbed under the multiplexer.
*/
static int
{
int j, cnt;
if (ms == 0)
return (0);
cn++, j++) {
a->ttymux32_linkid = 0;
a->ttymux32_tag = (uint32_t)0;
a->ttymux32_ldev = NODEV32;
cnt++;
a++;
}
}
return (cnt);
}
#endif
static int
{
int j, cnt;
if (ms == 0)
return (0);
cn++, j++) {
cnt++;
}
return (cnt);
}
/*
* Exported interfaces
*/
/*
* A console device is no longer associated.
*/
int
{
int j;
return (0);
for (j = 0; j < ms->sm_cons_cnt; j++) {
return (0);
}
}
return (1);
}
/*
* A console device is being introduced.
*/
int
{
int j;
return (0);
for (j = 0; j < ms->sm_cons_cnt; j++) {
return (0);
}
}
return (1);
}
/*
* Process a TTYMUX_ASSOCIATE or TTYMUX_DISASSOCIATE ioctl.
*/
static int
{
int err;
return (err);
return (EINVAL);
err = 0;
if (assoc.ttymux_linkid < 0)
}
} else {
}
if (err != 0) {
return (err);
return (0);
}
assoc.ttymux_path));
return (0);
}
/*
* Process a TTYMUX_GETLINK ioctl.
*/
int
{
return (EINVAL);
#ifdef _SYSCALL32_IMPL
return (EINVAL);
return (ENOLINK);
}
} else
#endif
{
return (EINVAL);
return (ENOLINK);
}
}
return (0);
}
/*
* Response to receiving an M_IOCDATA message for the TTYMUX_LIST ioctl.
*/
static int
{
return (EINVAL);
}
if (csp->cp_private)
}
#ifdef _SYSCALL32_IMPL
} else
#endif
{
}
if (pmp)
else
return (0);
}
/*
* Process a TTYMUX_LIST ioctl.
*/
int
{
int unit;
int cnt;
void *asl;
void *uaddr;
return (sm_iocresp(mp));
}
/*
* Is this a query for the number of linked devices?
*/
unit++)
return (0);
}
return (EINVAL);
}
#ifdef _SYSCALL32_IMPL
} else
#endif
{
}
return (EAGAIN);
}
#ifdef _SYSCALL32_IMPL
for (unit = 0;
unit++) {
if (cnt-- == 0)
break;
assoc++;
}
}
if (cnt > 0) {
/* see if there are unconfigured consoles */
} else {
}
} else
#endif
{
for (unit = 0;
unit++) {
if (cnt-- == 0)
break;
assoc++;
}
}
if (cnt > 0) {
/* see if there are unconfigured consoles */
} else {
}
}
return (0);
}
/*
* Process a TTYMUX_CONSDEV ioctl.
*/
static int
{
#ifdef _SYSCALL32_IMPL
err = 0;
} else {
}
} else
#endif
err = 0;
}
return (err);
}
/*
* Process a ioctl relating to aborting on the console.
*/
int
{
#ifdef _SYSCALL32_IMPL
struct ttymux_abort32 {
enum ttymux_break_type method;
} *abreq32;
#endif
enum ttymux_break_type method;
switch (cmd) {
case CONSSETABORTENABLE:
}
break;
case CONSGETABORTENABLE:
} else {
(sm_ssp->sm_ctrla_abort_on ||
}
break;
case TTYMUX_GETABORTSTR:
} else {
}
break;
case TTYMUX_GETABORT:
case TTYMUX_SETABORT:
lqi = 0;
#ifdef _SYSCALL32_IMPL
} else {
abreq32 = (struct ttymux_abort32 *)
}
} else
#endif
} else {
}
if (err != 0) {
}
} else if (cmd == TTYMUX_GETABORT) {
if (lqi->sm_break_abort_on == 0 &&
lqi->sm_ctrla_abort_on == 0) {
enable = 0;
} else {
enable = 1;
if (lqi->sm_break_abort_on == 0)
else if (lqi->sm_ctrla_abort_on == 0)
else
}
#ifdef _SYSCALL32_IMPL
} else
#endif
{
}
} else {
if (lqi == 0) {
if (method == HARDWARE_BREAK)
else if (method == SOFTWARE_BREAK)
else if (method == SOFTHARD_BREAK) {
} else {
}
if (sm_ssp->sm_lconsole) {
} else {
}
}
while (lqi) {
if (method == HARDWARE_BREAK)
else if (method == SOFTWARE_BREAK)
else if (method == SOFTHARD_BREAK) {
} else {
}
}
}
break;
default:
}
}
/*
* Process ioctls specific to the ttymux driver.
*/
/*ARGSUSED*/
int
{
/*
* This routine does not support transparent ioctls
*/
return (ENOTSUP);
}
case TTYMUX_CONSDEV:
break;
case TTYMUX_ASSOC:
case TTYMUX_DISASSOC:
break;
case TTYMUX_GETLINK:
break;
case TTYMUX_LIST:
return (ttymux_query_links_ioctl(mp));
case TTYMUX_SETCTL:
case TTYMUX_GETCTL:
break;
case TTYMUX_GETABORTSTR:
case TTYMUX_SETABORT:
case TTYMUX_GETABORT:
break;
default:
break;
}
}