* Common subroutines for all drivers
* SCCSID[] = "@(#)dksub.c 1.2 Garage 84/03/27"
#include "../machine/pte.h"
#define DKBUFUSE 5 /* max buffers /channel */
extern struct dkdev dkdev
[] ;
register struct uio
*uio
;
register struct dkdev
*tp
;
MGET(mm
, M_WAIT
, DKMT_DATA
);
if (uio
->uio_resid
>= MLEN
) {
mm
->m_off
= (int)p
- (int)mm
;
blen
= MIN(MLEN
, uio
->uio_resid
);
if (setjmp(&u
.u_qsave
)) {
if (dk_status(chan
) & DK_RCV
)
(void) dk_rabort(chan
, dkrdone
, (caddr_t
) tp
) ;
while (uio
->uio_resid
&& !err
) {
len
= MIN(uio
->uio_resid
, blen
) ;
chanstat
= dk_recv(chan
, mtod(mm
, caddr_t
), len
, tp
->d_rmode
, dkrdone
, (caddr_t
) tp
) ;
if ((dk_status(chan
) & DK_RESET
) == 0)
if ((tp
->dc_state
& DK_NDELAY
) && (dk_status(chan
) & DK_RCV
)) {
while (dk_status(chan
) & DK_RCV
)
sleep((caddr_t
)(tp
), TTOPRI
) ;
err
= uiomove(mtod(mm
, caddr_t
), len
, UIO_READ
, uio
);
if (tp
->d_rdone
!= DKR_FULL
)
dkrdone(tp
, chan
, resid
, rdone
, rctl
)
register struct dkdev
*tp
;
dkuwrite(chan
, uio
) register struct uio
*uio
;
register struct dkdev
*tp
;
register struct iovec
*iov
;
while (tp
->d_bufct
> DKBUFUSE
) {
if (tp
->dc_state
& DK_NDELAY
) {
sleep((caddr_t
)(&tp
->d_state
), TTOPRI
) ;
MGET(m
, M_WAIT
, DKMT_DATA
);
if (iov
->iov_len
>= MLEN
) {
m
->m_off
= (int)p
- (int)m
;
len
= MIN(CLBYTES
, iov
->iov_len
);
len
= MIN(MLEN
, iov
->iov_len
);
error
= uiomove(mtod(m
, caddr_t
), len
, UIO_WRITE
, uio
);
eob
= (uio
->uio_resid
== 0);
if (dk_xmit(chan
, m
, eob
, xc
, dkwdone
, (caddr_t
) 0) == 0) {
} while (uio
->uio_resid
);
register struct dkdev
*tp
;
log(LOG_ERR
, "dkwdone %d: state=0%o bufct=%d\n", chan
, tp
->d_state
,
if (tp
->d_state
& DKWAIT
) {
wakeup((caddr_t
) &tp
->d_state
) ;
/* wakeup and reinitialize channel upon receipt of reconnection message */
register struct dkdev
*tp
;
tp
->d_state
|= DKSPLICED
;
dk_cmd(chan
, DKC_XINIT
) ;
/* wait for reconnection message indicating that splice completed */
register struct dkdev
*tp
;
while ((tp
->d_state
& DKSPLICED
) == 0)
sleep((caddr_t
) tp
, TTOPRI
) ;
/* convert file desciptor to Datakit channel */
extern struct file
*getinode();
register struct file
*fp
;
register struct inode
*ip
;
ip
= (struct inode
*)fp
->f_data
;
if ((ip
->i_mode
& IFMT
) != IFCHR
) {
if (dkdevtype((dev_t
) ip
->i_rdev
))
return(minor(ip
->i_rdev
)) ;
/* validate device number as belonging to Datakit */
dkdevtype(dev
) dev_t dev
;
register md
= major(dev
) ;
if ((cdevsw
[md
].d_open
== dkopen
)
|| (cdevsw
[md
].d_open
== dktopen
)
|| (cdevsw
[md
].d_open
== dkiopen
&& md
> 0)
|| (cdevsw
[md
].d_open
== dkxopen
)