/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
/*
* The default (sane) set of termios values, unless
* otherwise set by the user.
*/
{
CEOF,
CEOL,
}
};
void
{
/*
* We were holding an "ioctl" response pending the
* availability of an "mblk" to hold data to be passed up;
* another "ioctl" came through, which means that "ioctl"
* must have timed out or been aborted.
*/
} else
}
/*
* A "line discipline" module's queue is full.
* Check whether IMAXBEL is set; if so, output a ^G, otherwise send an M_FLUSH
* upstream flushing all the read queues.
*/
void
{
}
}
} else {
}
}
/*
* Process an "ioctl" message sent down to us, and return a reply message,
* even if we don't understand the "ioctl". Our client may want to use
* that reply message for its own purposes if we don't understand it but
* they do, and may want to modify it if we both understand it but they
* understand it better than we do.
* If the "ioctl" reply requires additional data to be passed up to the
* caller, and we cannot allocate an mblk to hold the data, we return the
* amount of data to be sent, so that our caller can do a "bufcall" and try
* again later; otherwise, we return 0.
*/
{
*errorp = 0; /* no error detected yet */
return (0);
}
case TCSETSF:
/*
* Flush the driver's queue, and send an M_FLUSH upstream
* to flush everybody above us.
*/
/* FALLTHROUGH */
case TCSETSW:
case TCSETS: {
*errorp = -1;
break;
}
/*
* The only information we look at are the iflag word,
* the cflag word, and the start and stop characters.
*/
break;
}
case TCSETAF:
/*
* Flush the driver's queue, and send an M_FLUSH upstream
* to flush everybody above us.
*/
/* FALLTHROUGH */
case TCSETAW:
case TCSETA: {
*errorp = -1;
break;
}
/*
* The only information we look at are the iflag word
* and the cflag word. Don't touch the unset portions.
*/
break;
}
case TIOCSWINSZ: {
*errorp = -1;
break;
}
/*
* If the window size changed, send a SIGWINCH.
*/
} else
break;
}
/*
* Prevent more opens.
*/
case TIOCEXCL:
break;
/*
* Permit more opens.
*/
case TIOCNXCL:
break;
/*
* Set or clear the "soft carrier" flag.
*/
case TIOCSSOFTCAR:
if (miocpullup(mp, sizeof (int)) != 0) {
*errorp = -1;
break;
}
else
break;
/*
* The permission checking has already been done at the stream
* head, since it has to be done in the context of the process
* doing the call.
*/
case TIOCSTI: {
if (miocpullup(mp, sizeof (char)) != 0) {
*errorp = -1;
break;
}
/*
* Simulate typing of a character at the terminal.
*/
else {
}
}
break;
}
}
/*
* Turn the ioctl message into an ioctl ACK message.
*/
case TCSETSF:
case TCSETSW:
case TCSETS:
case TCSETAF:
case TCSETAW:
case TCSETA:
case TIOCSWINSZ:
case TIOCEXCL:
case TIOCNXCL:
case TIOCSSOFTCAR:
case TIOCSTI:
/*
* We've done all the important work on these already;
* just reply with an ACK.
*/
break;
case TCGETS: {
ioctlrespsize = sizeof (struct termios);
goto allocfailure;
}
/*
* The only information we supply is the cflag word.
* Our copy of the iflag word is just that, a copy.
*/
break;
}
case TCGETA: {
ioctlrespsize = sizeof (struct termio);
goto allocfailure;
}
/*
* The only information we supply is the cflag word.
* Our copy of the iflag word is just that, a copy.
*/
break;
}
/*
* Get the "soft carrier" flag.
*/
case TIOCGSOFTCAR: {
ioctlrespsize = sizeof (int);
goto allocfailure;
}
else
break;
}
case TIOCGWINSZ: {
ioctlrespsize = sizeof (struct winsize);
goto allocfailure;
}
/*
* Return the current size.
*/
break;
}
default:
break;
}
return (0);
/*
* We needed to allocate something to handle this "ioctl", but
* couldn't; save this "ioctl" and arrange to get called back when
* it's more likely that we can get what we need.
* If there's already one being saved, throw it out, since it
* must have timed out.
*/
return (ioctlrespsize);
}
/*
* Init routine run from main at boot time.
* Creates a property in the "options" node that is
* the default set of termios modes upon driver open.
* If the property already existed, then it was
* defined in the options.conf file. In this case we
* need to convert this string (stty -g style) to an
* actual termios structure and store the new property
* value.
*/
void
ttyinit()
{
int i;
/*
* If the termios defaults were NOT set up by the
* user via the options.conf file, create it using the
* "sane" set of termios modes.
* Note that if the property had been created via the
* options.conf file, it would have been created as
* a string property. Since we would like to store
* a structure (termios) in this property, we need
* to change the property type to byte array.
*/
"ttyinit: Can't find options node!\n");
}
/*
* Create the property.
*/
sizeof (struct termios)) != DDI_PROP_SUCCESS) {
property);
}
return;
}
/*
* This property was already set in the options.conf
* file. We must convert it from a "stty -g" string
* to an actual termios structure.
*/
tp = &new_termios;
for (i = 0; i < NFIELDS; i++) {
/*
*/
"ttyinit: property '%s' %s\n", property,
"set incorrectly, using sane value");
tp = &default_termios;
break;
}
switch (i) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
default:
}
}
}
/*
* We need to create ttymode property as a byte array
* since it will be interpreted as a termios struct.
* The property was created as a string by default.
* So remove the old property and add the new one -
* otherwise we end up with two ttymodes properties.
*/
!= DDI_PROP_SUCCESS) {
property);
}
/*
* Store the new defaults. Since, this property was
* autoconfig'ed, we must use e_ddi_prop_update_byte_array().
*/
property);
}
}
/*
* Convert hex string representation of termios field
* to a uint_t. Increments string pointer to the next
* field, and assigns value. Returns -1 if no more fields
* or an error.
*/
static int
{
char *s = *sp;
if (s == 0)
return (-1);
*valp = 0;
while (s < ep) {
if (*s >= '0' && *s <= '9')
digit = *s++ - '0';
else if (*s >= 'a' && *s <= 'f')
else if (*s >= 'A' && *s <= 'F')
else if (*s == ':' || *s == '\0')
break;
else
return (-1);
}
/*
* Null string or empty field.
*/
if (s == *sp)
return (-1);
if (s < ep && *s == ':')
s++;
*sp = s;
return (0);
}