mirror of https://github.com/zrafa/xinu-avr.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.1 KiB
131 lines
3.1 KiB
/* rdscontrol.c - rdscontrol */ |
|
|
|
#include <xinu.h> |
|
|
|
/*------------------------------------------------------------------------ |
|
* rdscontrol - Provide control functions for the remote disk |
|
*------------------------------------------------------------------------ |
|
*/ |
|
devcall rdscontrol ( |
|
struct dentry *devptr, /* Entry in device switch table */ |
|
int32 func, /* The control function to use */ |
|
int32 arg1, /* Argument #1 */ |
|
int32 arg2 /* Argument #2 */ |
|
) |
|
{ |
|
struct rdscblk *rdptr; /* Pointer to control block */ |
|
struct rdbuff *bptr; /* Ptr to buffer that will be */ |
|
/* placed on the req. queue */ |
|
struct rdbuff *pptr; /* Ptr to "previous" node on */ |
|
/* a list */ |
|
struct rd_msg_dreq msg; /* Buffer for delete request */ |
|
struct rd_msg_dres resp; /* Buffer for delete response */ |
|
char *to, *from; /* Used during name copy */ |
|
int32 retval; /* Return value */ |
|
|
|
/* Verify that device is currently open */ |
|
|
|
rdptr = &rdstab[devptr->dvminor]; |
|
if (rdptr->rd_state != RD_OPEN) { |
|
return SYSERR; |
|
} |
|
|
|
/* Ensure rdsprocess is runnning */ |
|
|
|
if ( ! rdptr->rd_comruns ) { |
|
rdptr->rd_comruns = TRUE; |
|
resume(rdptr->rd_comproc); |
|
} |
|
|
|
switch (func) { |
|
|
|
/* Synchronize writes */ |
|
|
|
case RDS_CTL_SYNC: |
|
|
|
/* Allocate a buffer to use for the request list */ |
|
|
|
bptr = rdsbufalloc(rdptr); |
|
if (bptr == (struct rdbuff *)SYSERR) { |
|
return SYSERR; |
|
} |
|
|
|
/* Form a sync request */ |
|
|
|
bptr->rd_op = RD_OP_SYNC; |
|
bptr->rd_refcnt = 1; |
|
bptr->rd_blknum = 0; /* Unused */ |
|
bptr->rd_status = RD_INVALID; |
|
bptr->rd_pid = getpid(); |
|
|
|
/* Insert new request into list just before tail */ |
|
|
|
pptr = rdptr->rd_rtprev; |
|
rdptr->rd_rtprev = bptr; |
|
bptr->rd_next = pptr->rd_next; |
|
bptr->rd_prev = pptr; |
|
pptr->rd_next = bptr; |
|
|
|
/* Prepare to wait until item is processed */ |
|
|
|
recvclr(); |
|
|
|
/* Signal then semaphore to start communication */ |
|
|
|
signal(rdptr->rd_reqsem); |
|
|
|
/* Block to wait for a message */ |
|
|
|
bptr = (struct rdbuff *)receive(); |
|
if (bptr == (struct rdbuff *)SYSERR) { |
|
return SYSERR; |
|
} |
|
break; |
|
|
|
/* Delete the remote disk (entirely remove it) */ |
|
|
|
case RDS_CTL_DEL: |
|
|
|
/* Handcraft a message for the server that requests */ |
|
/* deleting the disk with the specified ID */ |
|
|
|
msg.rd_type = htons(RD_MSG_DREQ);/* Request deletion */ |
|
msg.rd_status = htons(0); |
|
msg.rd_seq = 0; /* rdscomm will insert sequence # later */ |
|
to = msg.rd_id; |
|
memset(to, NULLCH, RD_IDLEN); /* Initialize to zeroes */ |
|
from = rdptr->rd_id; |
|
while ( (*to++ = *from++) != NULLCH ) { /* copy ID */ |
|
; |
|
} |
|
|
|
/* Send message and receive response */ |
|
|
|
retval = rdscomm((struct rd_msg_hdr *)&msg, |
|
sizeof(struct rd_msg_dreq), |
|
(struct rd_msg_hdr *)&resp, |
|
sizeof(struct rd_msg_dres), |
|
rdptr); |
|
|
|
/* Check response */ |
|
|
|
if (retval == SYSERR) { |
|
return SYSERR; |
|
} else if (retval == TIMEOUT) { |
|
kprintf("Timeout during remote file delete\n\r"); |
|
return SYSERR; |
|
} else if (ntohs(resp.rd_status) != 0) { |
|
return SYSERR; |
|
} |
|
|
|
/* Close local device */ |
|
|
|
return rdsclose(devptr); |
|
|
|
default: |
|
kprintf("rfsControl: function %d not valid\n\r", func); |
|
return SYSERR; |
|
} |
|
|
|
return OK; |
|
}
|
|
|