Dialing In/Out through same port
utzoo!decvax!decwrl!sun!megatest!fortune!hpda!hplabs!hao!csu-cs!bentson
utzoo!decvax!decwrl!sun!megatest!fortune!hpda!hplabs!hao!csu-cs!bentson
Thu Apr 14 13:25:42 AEST 1983
Here's yet another way to use a line for both dial-in and dial-out.
I got the idea for this from Donn Terry (csu-cs!hp-dcd!donn) who
thinks he spotted something about this on the net. (If anyone can
help with proper attribution of this idea, please respond by mail.)
Although this discussion relates specifically to 4.1bsd, other Un*x
should be able to fiddle this a bit to get the same results.
Randy Bentson
Colo State U - Comp Sci
Ft. Collins, CO
303/491-7016
{hplabs,lanl-a,lll-crg,hao,cires}!csu-cs!bentson
GENERAL CONCEPT
There are first class and second class citizens in the world of tty's.
The first class citizens have the OUTLINE bit set in the minor device
number. Having the outline bit set is used for dial-in/dial-out
lines. What happens is that a process such as init or getty can hang
an open on a second-class line and wait for carrier detect. If a dial-
out process does an open on a first-class line, the second class line
will not open even if carrier detect does come true for the process
using the first class line until that "first class process" closes it.
Processes using a first class line can do several opens on those lines
if they wish.
/DEV ENTRIES
This is an excerpt of our /dev directory listing. Port tty06 is the real
dialer port. The ports cua0-3 are multiplex files used by the dnd daemon
which actually does the dialing on the real dialer port.
crw------- 1 root 1, 6 Mar 15 13:04 /dev/tty06
mrw-rw-rw- 1 root 9, 8 Mar 15 11:01 /dev/cua0
mrw-rw-rw- 1 root 9, 7 Mar 15 13:04 /dev/cua1
mrw-rw-rw- 1 root 9, 6 Mar 15 11:01 /dev/cua2
mrw-rw-rw- 1 root 9, 5 Mar 15 11:01 /dev/cua3
Tty05 is the second class version of the first class port cul0. That
is, both open the same line, but one has priority over the other.
crw--w--w- 1 root 1, 5 Mar 14 18:46 /dev/tty05
crw-rw-rw- 1 root 1,133 Mar 15 13:08 /dev/cul0
This is the second dial-in/dial-out port on our system. There is no
apparent limit to the number of such dual ports beyond the maximum
second class minor device number limit of 128.
crw--w--w- 1 root 1, 4 Mar 15 12:50 /dev/tty04
crw------- 1 root 1,132 Mar 12 15:25 /dev/cul1
TTY.H FILE
Make one change to /sys/h/tty.h so that the line state can remember
that there is a request for the line as a first class citizen. It
doesn't appear that NDQB is used anywhere in the system so I preempted
use of the bit.
/* 06Mar83 RABentson changed following line from
#define NDQB 010000
to the following to support first/second class open
*/
#define OUTFLAG 010000 /* first class open in progress */
DZ DRIVER
I've used diff with two lines of context. Then here's the changes in
the dz driver. Notice that I've changed the location of the splN()
calls. I believe that this is a more stable use of the calls.
*** /sys/dev/dz.c Tue Apr 5 16:41:06 1983
--- /sys/dev/dz.7Oct81.c Wed Oct 7 14:46:11 1981
***************
*** 1,4
- /* 31Mar83 RABentson put delay in close so line stays on-hook for a bit */
- /* 06Mar83 RABentson added support for "first/second class open" */
/* dz.c 4.29 81/07/25 */
--- 1,2 -----
/* dz.c 4.29 81/07/25 */
***************
*** 30,34
* Driver information for auto-configuration stuff.
*/
- extern lbolt; /* 31Mar83 */
int dzprobe(), dzattach(), dzrint();
struct uba_device *dzinfo[NDZ];
--- 28,31 -----
* Driver information for auto-configuration stuff.
*/
int dzprobe(), dzattach(), dzrint();
struct uba_device *dzinfo[NDZ];
***************
*** 66,72
#define DZ_ON 1
#define DZ_OFF 0
-
- /* Flag indicating first class line */ /*06Mar83*/
- #define OUTLINE 0200 /*06Mar83*/
int dzstart(), dzxint(), dzdma();
--- 63,66 -----
#define DZ_ON 1
#define DZ_OFF 0
int dzstart(), dzxint(), dzdma();
***************
*** 152,156
register int unit;
! unit = minor(dev & ~OUTLINE); /*06Mar83*/
if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
u.u_error = ENXIO;
--- 146,150 -----
register int unit;
! unit = minor(dev);
if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
u.u_error = ENXIO;
***************
*** 161,166
tp->t_oproc = dzstart;
tp->t_iproc = NULL;
- (void) spl5();
- again: /*06Mar83*/
tp->t_state |= WOPEN;
if ((tp->t_state & ISOPEN) == 0) {
--- 155,158 -----
tp->t_oproc = dzstart;
tp->t_iproc = NULL;
tp->t_state |= WOPEN;
if ((tp->t_state & ISOPEN) == 0) {
***************
*** 172,176
} else if (tp->t_state&XCLUDE && u.u_uid != 0) {
u.u_error = EBUSY;
- (void) spl0();
return;
} else if ((dev & OUTLINE) && !(tp->t_state & OUTFLAG)) { /*06Mar83*/
--- 164,167 -----
} else if (tp->t_state&XCLUDE && u.u_uid != 0) {
u.u_error = EBUSY;
return;
}
***************
*** 174,181
(void) spl0();
return;
- } else if ((dev & OUTLINE) && !(tp->t_state & OUTFLAG)) { /*06Mar83*/
- u.u_error = ENXIO; /*06Mar83*/
- (void) spl0(); /*06Mar83*/
- return; /*06Mar83*/
}
if (dev & OUTLINE) tp->t_state |= OUTFLAG; /*06Mar83*/
--- 165,168 -----
u.u_error = EBUSY;
return;
}
dzmodem(unit, DZ_ON);
***************
*** 179,183
return; /*06Mar83*/
}
- if (dev & OUTLINE) tp->t_state |= OUTFLAG; /*06Mar83*/
dzmodem(unit, DZ_ON);
if (!(tp->t_state & CARR_ON) ||
--- 166,169 -----
return;
}
dzmodem(unit, DZ_ON);
(void) spl5();
***************
*** 181,187
if (dev & OUTLINE) tp->t_state |= OUTFLAG; /*06Mar83*/
dzmodem(unit, DZ_ON);
! if (!(tp->t_state & CARR_ON) ||
! ((tp->t_state & OUTFLAG) && /*06Mar83*/
! !(dev & OUTLINE))) { /*06Mar83*/
tp->t_state |= WOPEN;
sleep((caddr_t)&tp->t_rawq, TTIPRI);
--- 167,172 -----
}
dzmodem(unit, DZ_ON);
! (void) spl5();
! while ((tp->t_state & CARR_ON) == 0) {
tp->t_state |= WOPEN;
sleep((caddr_t)&tp->t_rawq, TTIPRI);
***************
*** 186,190
tp->t_state |= WOPEN;
sleep((caddr_t)&tp->t_rawq, TTIPRI);
- goto again; /*06Mar83*/
}
(void) spl0();
--- 171,174 -----
tp->t_state |= WOPEN;
sleep((caddr_t)&tp->t_rawq, TTIPRI);
}
(void) spl0();
***************
*** 189,193
}
(void) spl0();
! (*linesw[tp->t_line].l_open)(dev & ~OUTLINE, tp); /*06Mar83*/
}
--- 173,177 -----
}
(void) spl0();
! (*linesw[tp->t_line].l_open)(dev, tp);
}
***************
*** 200,204
int dz;
! unit = minor(dev & ~OUTLINE); /*06Mar83*/
dz = unit >> 3;
tp = &dz_tty[unit];
--- 184,188 -----
int dz;
! unit = minor(dev);
dz = unit >> 3;
tp = &dz_tty[unit];
***************
*** 204,208
tp = &dz_tty[unit];
(*linesw[tp->t_line].l_close)(tp);
- tp->t_state &= ~OUTFLAG;
((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
(dz_brk[dz] &= ~(1 << (unit&07)));
--- 188,191 -----
tp = &dz_tty[unit];
(*linesw[tp->t_line].l_close)(tp);
((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
(dz_brk[dz] &= ~(1 << (unit&07)));
***************
*** 217,221
register struct tty *tp;
! tp = &dz_tty[minor(dev & ~OUTLINE)]; /*06Mar83*/
(*linesw[tp->t_line].l_read)(tp);
}
--- 200,204 -----
register struct tty *tp;
! tp = &dz_tty[minor(dev)];
(*linesw[tp->t_line].l_read)(tp);
}
***************
*** 226,230
register struct tty *tp;
! tp = &dz_tty[minor(dev & ~OUTLINE)]; /*06Mar83*/
(*linesw[tp->t_line].l_write)(tp);
}
--- 209,213 -----
register struct tty *tp;
! tp = &dz_tty[minor(dev)];
(*linesw[tp->t_line].l_write)(tp);
}
***************
*** 283,287
{
register struct tty *tp;
! register int unit = minor(dev & ~OUTLINE); /*06Mar83*/
register int dz = unit >> 3;
--- 266,270 -----
{
register struct tty *tp;
! register int unit = minor(dev);
register int dz = unit >> 3;
***************
*** 432,436
dzaddr = dzpdma[unit].p_addr;
bit = 1<<(unit&07);
! if (flag == DZ_OFF){
dzaddr->dzdtr &= ~bit;
/* 31Mar83 Pause at least three seconds before allowing DTR to
--- 415,419 -----
dzaddr = dzpdma[unit].p_addr;
bit = 1<<(unit&07);
! if (flag == DZ_OFF)
dzaddr->dzdtr &= ~bit;
else
***************
*** 434,444
if (flag == DZ_OFF){
dzaddr->dzdtr &= ~bit;
! /* 31Mar83 Pause a long time before allowing DTR to be
! * turned back on. This will ensure the line is hung-up.
! */
! sleep((caddr_t)&lbolt, TTIPRI);
! sleep((caddr_t)&lbolt, TTIPRI);
! sleep((caddr_t)&lbolt, TTIPRI);
! sleep((caddr_t)&lbolt, TTIPRI);
! sleep((caddr_t)&lbolt, TTIPRI);
! sleep((caddr_t)&lbolt, TTIPRI);
! sleep((caddr_t)&lbolt, TTIPRI);
! }else
dzaddr->dzdtr |= bit;
}
--- 417,421 -----
if (flag == DZ_OFF)
dzaddr->dzdtr &= ~bit;
! else
dzaddr->dzdtr |= bit;
}
More information about the Comp.sources.unix
mailing list