}
s = sockets + ne.socket;
- sd = sockdata + ne.socket;
+ sd = s->s_priv;
switch (ne.event) {
/* State change. Wakes up the socket having moved state */
/* Response to creating a socket. Initialize lcn */
case NE_INIT:
s->s_state = SS_UNCONNECTED;
- s->s_lcn = ne.data;
+ sd->lcn = ne.data;
sd->event = 0;
sd->ret = ne.ret;
sd->err = 0;
as copies. It can then make any decisions it needs to make */
static int netdev_report(struct sockdata *sd)
{
- uint8_t sn = sd - sockdata;
- struct socket *s = sockets + sn;
+ struct socket *s = sd->socket;
if (uput(sd, udata.u_base, sizeof(*sd)) == -1 ||
uput(s, udata.u_base + sizeof(*sd), sizeof(*s)) == -1)
*/
static int netn_synchronous_event(struct socket *s, uint8_t state)
{
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
sd->event |= NEV_STATE | NEVW_STATE;
sd->newstate = state;
*/
static void netn_asynchronous_event(struct socket *s, uint8_t event)
{
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
sd->event |= event;
wakeup(&ne);
}
{
arg_t n = udata.u_count;
arg_t r = 0;
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
uint16_t spc;
/* Do we have room ? */
udata.u_sysio = false;
/* FIXME: if we go over 64K these will need some long casts to force
the types on the right side */
- udata.u_offset = sn * SOCKBUFOFF + RXBUFOFF + sd->tnext;
+ udata.u_offset = s->s_num * SOCKBUFOFF + RXBUFOFF + sd->tnext;
/* Wrapped part of the ring buffer */
if (n && sd->tnext > sd->tbuf) {
if (spc < n)
spc = n;
udata.u_count = spc;
- udata.u_offset = sn * SOCKBUFOFF + RXBUFOFF + sd->tnext;
+ udata.u_offset = s->s_num * SOCKBUFOFF + RXBUFOFF + sd->tnext;
/* FIXME: check writei returns and readi returns properly */
writei(net_ino, 0);
*/
static uint16_t netn_putbuf(struct socket *s)
{
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
if (udata.u_count > TXPKTSIZ) {
udata.u_error = EMSGSIZE;
return 0;
udata.u_sysio = false;
- udata.u_offset = sn * SOCKBUFOFF + RXBUFOFF + sd->tbuf * TXPKTSIZ;
+ udata.u_offset = s->s_num * SOCKBUFOFF + RXBUFOFF + sd->tbuf * TXPKTSIZ;
/* FIXME: check writei returns and readi returns properly */
writei(net_ino, 0);
sd->tlen[sd->tnext++] = udata.u_count;
*/
static uint16_t netn_getbuf(struct socket *s)
{
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
arg_t n = udata.u_count;
arg_t r = 0;
if (sd->rbuf == sd->rnext)
return 0;
udata.u_sysio = false;
- udata.u_offset = sn * SOCKBUFOFF + sd->rbuf * RXPKTSIZ;
+ udata.u_offset = s->s_num * SOCKBUFOFF + sd->rbuf * RXPKTSIZ;
udata.u_count = min(udata.u_count, sd->rlen[sd->rbuf++]);
/* FIXME: check writei returns and readi returns properly */
readi(net_ino, 0);
{
arg_t n = udata.u_count;
arg_t r = 0;
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
uint16_t spc;
if (sd->rnext == sd->rbuf)
return 0;
udata.u_sysio = false;
- udata.u_offset = sn * SOCKBUFOFF + sd->rbuf;
/* Wrapped part of the ring buffer */
if (n && sd->rnext < sd->rbuf) {
+ udata.u_offset = s->s_num * SOCKBUFOFF + sd->rbuf;
/* Write into the end space */
spc = RXBUFSIZ - sd->rbuf;
if (spc < n)
}
/* If we are not wrapped or just did the overflow write lower */
if (n) {
+ udata.u_offset = s->s_num * SOCKBUFOFF + sd->rbuf;
spc = sd->rnext - sd->rbuf;
if (spc < n)
spc = n;
*/
int net_init(struct socket *s)
{
+ struct sockdata *sd = sockdata + s->s_num;
if (!net_ino) {
udata.u_error = ENETDOWN;
return -1;
}
+ s->s_priv = sd;
+ sd->socket = s;
return netn_synchronous_event(s, SS_UNCONNECTED);
}
arg_t net_read(struct socket *s, uint8_t flag)
{
uint16_t n = 0;
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
if (sd->err) {
udata.u_error = sd->err;
arg_t net_write(struct socket * s, uint8_t flag)
{
uint16_t n = 0, t = 0;
- uint8_t sn = s - sockets;
- struct sockdata *sd = &sockdata[sn];
+ struct sockdata *sd = s->s_priv;
if (sd->err) {
udata.u_error = sd->err;
struct socket
{
- inoptr s_inode;
uint8_t s_type;
- uint8_t s_error;
-
uint8_t s_state;
#define SS_UNUSED 0 /* Free slot */
#define SS_INIT 1 /* Initializing state (for IP offloaders) */
#define SS_CLOSING 10 /* Protocol close in progress */
#define SS_CLOSED 11 /* Protocol layers done, not close()d */
/* FIXME: need state for shutdown handling */
- uint8_t s_data;
+ uint8_t s_data; /* Socket we are an accept() for */
+ uint8_t s_error;
+ uint8_t s_num; /* To save expensive maths */
struct sockaddrs s_addr[3];
#define SADDR_SRC 0
#define SADDR_DST 1
#define SI_DATA 1 /* Data is ready */
#define SI_EOF 2 /* At EOF */
#define SI_THROTTLE 4 /* Transmit is throttled */
- uint8_t s_lcn; /* Logical channel (for link layer) */
- uint8_t s_lcnflag; /* LCN private flags */
+ void *s_priv; /* Private pointer for lower layers */
+ inoptr s_inode; /* Can remove once debugged */
};
#define NSOCKTYPE 3
return 0;
}
-static int8_t alloc_socket(void)
+static struct socket *alloc_socket(void)
{
struct socket *s = sockets;
while (s < sockets + NSOCKET) {
if (s->s_state == SS_UNUSED)
- return s - sockets;
+ return s;
s++;
}
- return -1;
+ return NULL;
}
struct socket *sock_alloc_accept(struct socket *s)
{
- struct socket *n;
- int8_t i = alloc_socket();
- if (i == -1)
+ struct socket *n = alloc_socket();
+ if (n == NULL)
return NULL;
- n = &sockets[i];
memcpy(n, s, sizeof(*n));
n->s_state = SS_ACCEPTING;
- n->s_data = s - sockets;
+ n->s_data = s->s_num;
return n;
}
return NULL;
}
+
static struct socket *sock_get(int fd, uint8_t *flag)
{
struct oft *oftp;
return sockets + ino->c_node.i_nlink;
}
-static int sock_pending(struct socket *l)
+static struct socket *sock_pending(struct socket *l)
{
- uint8_t d = l - sockets;
+ uint8_t d = l->s_num;
struct socket *s = sockets;
while (s < sockets + NSOCKET) {
if (s->s_state == SS_ACCEPTWAIT && s->s_data == d)
- return s - sockets;
+ return s;
s++;
}
- return -1;
+ return NULL;
}
static int sock_autobind(struct socket *s)
memcpy(&s->s_addr[SADDR_SRC], &sa, sizeof(sa));
return net_bind(s);
}
-
static struct socket *sock_find_local(uint32_t addr, uint16_t port)
{
used(addr);
return 0;
}
+
struct sockinfo {
uint8_t af;
uint8_t type;
{ AF_INET, SOCK_RAW, 0, 0 }
};
-arg_t make_socket(struct sockinfo *s, int8_t *np)
+arg_t make_socket(struct sockinfo *s, struct socket **np)
{
- int8_t n;
+ struct socket *n;
int8_t uindex;
int8_t oftindex;
inoptr ino;
n = *np;
else {
n = alloc_socket();
- if (n == -1)
+ if (n == NULL)
return -1;
}
- sockets[n].s_type = s - socktypes; /* Pointer or uint8_t best ? */
- sockets[n].s_state = SS_INIT;
+ n->s_type = s - socktypes; /* Pointer or uint8_t best ? */
+ n->s_state = SS_INIT;
- if (net_init(&sockets[n]) == -1)
+ if (net_init(n) == -1)
goto nosock;
/* Start by getting the file and inode table entries */
/* All good - now set it up */
/* The nlink cheat needs to be taught to fsck! */
ino->c_node.i_mode = F_SOCK | 0777;
- ino->c_node.i_nlink = n; /* Cheat !! */
- sockets[n].s_inode = ino;
+ ino->c_node.i_nlink = n->s_num; /* Cheat !! */
+ n->s_inode = ino;
of_tab[oftindex].o_inode = ino;
of_tab[oftindex].o_access = O_RDWR;
udata.u_files[uindex] = oftindex;
- sock_wait_leave(&sockets[n], 0, SS_INIT);
+ sock_wait_leave(n, 0, SS_INIT);
if (np)
*np = n;
return uindex;
nooft:
udata.u_files[uindex] = NO_FILE;
nosock:
- sockets[n].s_state = SS_UNUSED;
+ n->s_state = SS_UNUSED;
return -1;
}
{
uint8_t flag;
struct socket *s = sock_get(fd, &flag);
- int8_t n;
+ struct socket *n;
int8_t nfd;
if (s == NULL)
}
/* Needs locking versus interrupts */
- while ((n = sock_pending(s)) != -1) {
+ while ((n = sock_pending(s)) != NULL) {
if (psleep_flags(s, flag))
return -1;
if (s->s_error)
}
if ((nfd = make_socket(&socktypes[SOCKTYPE_TCP], &n)) == -1)
return -1;
- sockets[n].s_state = SS_CONNECTED;
+ n->s_state = SS_CONNECTED;
return nfd;
}
#undef uaddr
#endif
+
+/* FIXME: Move to _discard */
+
+void sock_init(void)
+{
+ struct socket *s = sockets;
+ uint8_t n = 0;
+ while (s < sockets + NSOCKET)
+ s++->s_num = n;
+}