From: <ljs...@us...> - 2006-09-14 02:04:18
|
Revision: 352 http://svn.sourceforge.net/cadcdev/?rev=352&view=rev Author: ljsebald Date: 2006-09-13 19:04:08 -0700 (Wed, 13 Sep 2006) Log Message: ----------- Adding in the first of the big network changes that I have been working on. Modified Paths: -------------- kos/kernel/libc/koslib/Makefile Added Paths: ----------- kos/include/arpa/ kos/include/arpa/inet.h kos/include/netinet/ kos/include/netinet/in.h kos/kernel/libc/koslib/inet_addr.c Added: kos/include/arpa/inet.h =================================================================== --- kos/include/arpa/inet.h (rev 0) +++ kos/include/arpa/inet.h 2006-09-14 02:04:08 UTC (rev 352) @@ -0,0 +1,26 @@ +/* KallistiOS ##version## + + arpa/inet.h + Copyright (C)2006 Lawrence Sebald + +*/ + +#ifndef __ARPA_INET_H +#define __ARPA_INET_H + +#include <sys/cdefs.h> +#include <netinet/in.h> + +__BEGIN_DECLS + +uint32 htonl(uint32 value); +uint32 ntohl(uint32 value); + +uint16 htons(uint16 value); +uint16 ntohs(uint16 value); + +in_addr_t inet_addr(const char *cp); + +__END_DECLS + +#endif /* __ARPA_INET_H */ Added: kos/include/netinet/in.h =================================================================== --- kos/include/netinet/in.h (rev 0) +++ kos/include/netinet/in.h 2006-09-14 02:04:08 UTC (rev 352) @@ -0,0 +1,44 @@ +/* KallistiOS ##version## + + netinet/in.h + Copyright (C)2006 Lawrence Sebald + +*/ + +#ifndef __NETINET_IN_H +#define __NETINET_IN_H + +#include <sys/cdefs.h> +#include <arch/types.h> + +__BEGIN_DECLS + +typedef uint16 in_port_t; +typedef uint32 in_addr_t; + +#ifndef __SA_FAMILY_T_DEFINED +#define __SA_FAMILY_T_DEFINED +typedef uint32 sa_family_t; +#endif + +struct in_addr { + in_addr_t s_addr; +}; + +struct sockaddr_in { + sa_family_t sin_family; + in_port_t sin_port; + struct in_addr sin_addr; + unsigned char sin_zero[8]; +}; + +#define INADDR_ANY 0x00000000 +#define INADDR_BROADCAST 0xFFFFFFFF + +/* IP Protocols */ +#define IPPROTO_IP 0 +#define IPPROTO_UDP 17 + +__END_DECLS + +#endif /* __NETINET_IN_H */ Modified: kos/kernel/libc/koslib/Makefile =================================================================== --- kos/kernel/libc/koslib/Makefile 2006-09-14 01:38:50 UTC (rev 351) +++ kos/kernel/libc/koslib/Makefile 2006-09-14 02:04:08 UTC (rev 352) @@ -10,6 +10,6 @@ OBJS = abort.o byteorder.o memset2.o memset4.o memcpy2.o memcpy4.o \ assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \ opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \ - telldir.o usleep.o + telldir.o usleep.o inet_addr.o include $(KOS_BASE)/Makefile.prefab Added: kos/kernel/libc/koslib/inet_addr.c =================================================================== --- kos/kernel/libc/koslib/inet_addr.c (rev 0) +++ kos/kernel/libc/koslib/inet_addr.c 2006-09-14 02:04:08 UTC (rev 352) @@ -0,0 +1,49 @@ +/* KallistiOS ##version## + + inet_addr.c + Copyright (C)2006 Lawrence Sebald + +*/ + +#include <arpa/inet.h> +#include <stdlib.h> + +in_addr_t inet_addr(const char *cp) { + in_addr_t result = 0; + long tmp; + char *ptr; + + tmp = strtoul(cp, &ptr, 10); + if(tmp > 0xFF || cp == ptr) { + return (in_addr_t) -1; + } + else { + result = tmp << 24; + } + + tmp = strtoul(ptr + 1, &ptr, 10); + if(tmp > 0xFF || cp == ptr) { + return (in_addr_t) -1; + } + else { + result |= tmp << 16; + } + + tmp = strtoul(ptr + 1, &ptr, 10); + if(tmp > 0xFF || cp == ptr) { + return (in_addr_t) -1; + } + else { + result |= tmp << 8; + } + + tmp = strtoul(ptr + 1, &ptr, 10); + if(tmp > 0xFF || cp == ptr) { + return (in_addr_t) -1; + } + else { + result |= tmp; + } + + return (in_addr_t) htonl(result); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2006-09-14 03:04:57
|
Revision: 354 http://svn.sourceforge.net/cadcdev/?rev=354&view=rev Author: ljsebald Date: 2006-09-13 20:04:48 -0700 (Wed, 13 Sep 2006) Log Message: ----------- Another networking change coming up. This is a bit of cleaning in the net_ipv4.c file. Modified Paths: -------------- kos/include/kos/net.h kos/kernel/net/net_ipv4.c Modified: kos/include/kos/net.h =================================================================== --- kos/include/kos/net.h 2006-09-14 02:39:59 UTC (rev 353) +++ kos/include/kos/net.h 2006-09-14 03:04:48 UTC (rev 354) @@ -198,6 +198,10 @@ within the ip. */ uint32 net_ipv4_address(const uint8 addr[4]); +/* Parse an IP address that is packet into a uint32 into an array of the + individual bytes */ +void net_ipv4_parse_address(uint32 addr, uint8 out[4]); + /***** net_udp.c **********************************************************/ /* Init */ Modified: kos/kernel/net/net_ipv4.c =================================================================== --- kos/kernel/net/net_ipv4.c 2006-09-14 02:39:59 UTC (rev 353) +++ kos/kernel/net/net_ipv4.c 2006-09-14 03:04:48 UTC (rev 354) @@ -2,7 +2,7 @@ kernel/net/net_ipv4.c - Copyright (C) 2005 Lawrence Sebald + Copyright (C) 2005, 2006 Lawrence Sebald Portions adapted from KOS' old net_icmp.c file: Copyright (c) 2002 Dan Potter @@ -11,6 +11,8 @@ #include <stdio.h> #include <string.h> +#include <errno.h> +#include <arpa/inet.h> #include <kos/net.h> #include "net_ipv4.h" #include "net_icmp.h" @@ -22,7 +24,7 @@ uint32 net_ntohl(uint32 n) { return ((n & 0xFF) << 24) | ((n & 0xFF00) << 8) | - ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF); + ((n >> 8) & 0xFF00) | ((n >> 24) & 0xFF); } /* Perform an IP-style checksum on a block of data */ @@ -43,7 +45,8 @@ } /* Determine if a given IP is in the current network */ -static int is_in_network(const uint8 src[4], const uint8 dest[4], const uint8 netmask[4]) { +static int is_in_network(const uint8 src[4], const uint8 dest[4], + const uint8 netmask[4]) { int i; for(i = 0; i < 4; i++) { @@ -55,19 +58,21 @@ } /* Send a packet on the specified network adaptor */ -int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, int size) { +int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, + int size) { uint8 dest_ip[4]; uint8 dest_mac[6]; uint8 pkt[size + sizeof(ip_hdr_t) + sizeof(eth_hdr_t)]; eth_hdr_t *ehdr; - dest_ip[0] = (uint8)(hdr->dest & 0xFF); - dest_ip[1] = (uint8)(hdr->dest >> 8); - dest_ip[2] = (uint8)(hdr->dest >> 16); - dest_ip[3] = (uint8)(hdr->dest >> 24); + if(net == NULL) { + net = net_default_dev; + } - /* Is this the loopback address? */ - if(dest_ip[0] == 127 && dest_ip[1] == 0 && dest_ip[2] == 0 && dest_ip[3] == 1) { + net_ipv4_parse_address(ntohl(hdr->dest), dest_ip); + + /* Is this the loopback address (127.0.0.1)? */ + if(ntohl(hdr->dest) == 0x7F000001) { /* Fill in the ethernet header */ ehdr = (eth_hdr_t *)pkt; memset(ehdr->dest, 0, 6); @@ -80,24 +85,29 @@ ehdr->type[1] = 0x00; /* Put the IP header / data into our ethernet packet */ - memcpy(pkt + sizeof(eth_hdr_t), hdr, 4 * (hdr->version_ihl & 0x0f)); - memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data, size); + memcpy(pkt + sizeof(eth_hdr_t), hdr, + 4 * (hdr->version_ihl & 0x0f)); + memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), + data, size); /* Send it away */ - net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) + size); + net_input(NULL, pkt, sizeof(eth_hdr_t) + sizeof(ip_hdr_t) + + size); return 0; } - /* Is it in our network? */ - if(!is_in_network(net->ip_addr, dest_ip, net->netmask)) + /* Is it in our network? */ + if(!is_in_network(net->ip_addr, dest_ip, net->netmask)) { memcpy(dest_ip, net->gateway, 4); + } /* Get our destination's MAC address */ - if(net_arp_lookup(net, dest_ip, dest_mac) == -1) + if(net_arp_lookup(net, dest_ip, dest_mac) == -1) { + errno = ENETUNREACH; return -1; + } - /* Fill in the ethernet header */ ehdr = (eth_hdr_t *)pkt; memcpy(ehdr->dest, dest_mac, 6); @@ -107,10 +117,12 @@ /* Put the IP header / data into our ethernet packet */ memcpy(pkt + sizeof(eth_hdr_t), hdr, 4 * (hdr->version_ihl & 0x0f)); - memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data, size); + memcpy(pkt + sizeof(eth_hdr_t) + 4 * (hdr->version_ihl & 0x0f), data, + size); /* Send it away */ - net->if_tx(net, pkt, sizeof(ip_hdr_t) + size + sizeof(eth_hdr_t), NETIF_BLOCK); + net->if_tx(net, pkt, sizeof(ip_hdr_t) + size + sizeof(eth_hdr_t), + NETIF_BLOCK); return 0; } @@ -120,45 +132,58 @@ ip_hdr_t *ip; int i; uint8 *data; + uint16 *ethproto; /* Get pointers */ - eth = (eth_hdr_t*)(pkt); - ip = (ip_hdr_t*)(pkt + sizeof(eth_hdr_t)); - data = (uint8 *)(pkt + sizeof(eth_hdr_t) + 4*(ip->version_ihl & 0x0f)); + eth = (eth_hdr_t*) (pkt); + ip = (ip_hdr_t*) (pkt + sizeof(eth_hdr_t)); + data = (uint8 *) (pkt + sizeof(eth_hdr_t) + 4 * + (ip->version_ihl & 0x0f)); + ethproto = (uint16 *) (pkt + 12); - /* Non-IP */ - if (eth->type[0] != 0x08) + /* Make sure this packet is actually marked as an IP packet */ + if(ntohs(*ethproto) != 0x0800) { + dbglog(DBG_KDEBUG, "net_ipv4: Discarding non IP packet\n"); return 0; + } - if (eth->type[1] != 0x00) - return 0; - /* Check ip header checksum */ i = ip->checksum; ip->checksum = 0; - ip->checksum = net_ipv4_checksum((uint16*)ip, 2 * (ip->version_ihl & 0x0f)); - if (i != ip->checksum) { - dbglog(DBG_KDEBUG, "net_ipv4: ip with invalid checksum\n"); + ip->checksum = net_ipv4_checksum((uint16*)ip, 2 * + (ip->version_ihl & 0x0f)); + + if(i != ip->checksum) { + dbglog(DBG_KDEBUG, "net_ipv4: Discarding recieved IP packet " + "with invalid checksum\n"); return 0; } - switch(ip->protocol) { + switch(ip->protocol) { case 1: - net_icmp_input(src, eth, ip, data, net_ntohs(ip->length) - + net_icmp_input(src, eth, ip, data, ntohs(ip->length) - (ip->version_ihl & 0x0f) * 4); break; case 17: - net_udp_input(src, eth, ip, data, net_ntohs(ip->length) - + net_udp_input(src, eth, ip, data, ntohs(ip->length) - (ip->version_ihl & 0x0f) * 4); break; default: - dbglog(DBG_KDEBUG, "net_ipv4: unknown ip protocol: %d\n", ip->protocol); + dbglog(DBG_KDEBUG, "net_ipv4: Discarding recieved IP " + "packet with unkown protocol: %d\n", + ip->protocol); } return 0; } uint32 net_ipv4_address(const uint8 addr[4]) { - uint32 ad = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | (addr[3]); - return ad; + return (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | (addr[3]); } + +void net_ipv4_parse_address(uint32 addr, uint8 out[4]) { + out[0] = (uint8) ((addr >> 24) & 0xFF); + out[1] = (uint8) ((addr >> 16) & 0xFF); + out[2] = (uint8) ((addr >> 8) & 0xFF); + out[3] = (uint8) (addr & 0xFF); +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2006-09-16 16:18:36
|
Revision: 355 http://svn.sourceforge.net/cadcdev/?rev=355&view=rev Author: ljsebald Date: 2006-09-16 09:18:26 -0700 (Sat, 16 Sep 2006) Log Message: ----------- This is the last of the big networking changes for now. This update adds a completely new UDP system, and a working sockets system to go along with it. Modified Paths: -------------- kos/include/kos/net.h kos/kernel/fs/Makefile kos/kernel/net/net_core.c kos/kernel/net/net_udp.c kos/kernel/net/net_udp.h Added Paths: ----------- kos/include/kos/fs_socket.h kos/include/sys/socket.h kos/kernel/fs/fs_socket.c Added: kos/include/kos/fs_socket.h =================================================================== --- kos/include/kos/fs_socket.h (rev 0) +++ kos/include/kos/fs_socket.h 2006-09-16 16:18:26 UTC (rev 355) @@ -0,0 +1,38 @@ +/* KallistiOS ##version## + + kos/fs_socket.h + Copyright (C) 2006 Lawrence Sebald + +*/ + +#ifndef __KOS_FS_SOCKET_H +#define __KOS_FS_SOCKET_H + +#include <sys/cdefs.h> +__BEGIN_DECLS + +#include <arch/types.h> +#include <kos/limits.h> +#include <kos/fs.h> +#include <sys/queue.h> + +typedef struct net_socket { + /* List handle */ + LIST_ENTRY(net_socket) sock_list; + + /* Protocol of this socket. This corresponds to the IP protocol number */ + int protocol; + + /* Protocol specific data */ + void *data; +} net_socket_t; + +int fs_socket_init(); +int fs_socket_shutdown(); + +int fs_socket_setflags(int sock, int flags); + +__END_DECLS + +#endif /* __KOS_FS_SOCKET_H */ + Modified: kos/include/kos/net.h =================================================================== --- kos/include/kos/net.h 2006-09-14 03:04:48 UTC (rev 354) +++ kos/include/kos/net.h 2006-09-16 16:18:26 UTC (rev 355) @@ -210,23 +210,6 @@ /* Shutdown */ void net_udp_shutdown(); -/* Send a raw UDP packet, without a socket */ -int net_udp_send_raw(netif_t *net, uint16 src_port, uint16 dst_port, - const uint8 dst_ip[4], const uint8 *data, int size); - -/* Open a socket between the local system, and a remote host */ -int net_udp_sock_open(uint16 loc_port, uint32 loc_addr, uint16 rem_port, - uint32 rem_addr); - -/* Close a previously opened socket */ -int net_udp_sock_close(int sock); - -/* Send a packet on a socket */ -int net_udp_send(int sock, const uint8 *data, int size); - -/* Recieve a packet on a socket */ -int net_udp_recv(int sock, uint8 *buf, int size); - /***** net_core.c *********************************************************/ /* Interface list; note: do not manipulate directly */ Added: kos/include/sys/socket.h =================================================================== --- kos/include/sys/socket.h (rev 0) +++ kos/include/sys/socket.h 2006-09-16 16:18:26 UTC (rev 355) @@ -0,0 +1,56 @@ +/* KallistiOS ##version## + + sys/socket.h + Copyright (C)2006 Lawrence Sebald + +*/ + +#ifndef __SYS_SOCKET_H +#define __SYS_SOCKET_H + +#include <sys/cdefs.h> +#include <arch/types.h> + +__BEGIN_DECLS + +typedef uint32 socklen_t; + +#ifndef __SA_FAMILY_T_DEFINED +#define __SA_FAMILY_T_DEFINED +typedef uint32 sa_family_t; +#endif + +struct sockaddr { + sa_family_t sa_family; + char sa_data[]; +}; + +/* Socket types, currently only SOCK_DGRAM is available */ +#define SOCK_DGRAM 1 + +/* Socket address families. Currently only AF_INET is available */ +#define AF_INET 1 + +#define PF_INET AF_INET + +/* Socket shutdown macros. */ +#define SHUT_RD 0x00000001 +#define SHUT_WR 0x00000002 +#define SHUT_RDWR (SHUT_RD | SHUT_WR) + +int accept(int socket, struct sockaddr *address, socklen_t *address_len); +int bind(int socket, const struct sockaddr *address, socklen_t address_len); +int connect(int socket, const struct sockaddr *address, socklen_t address_len); +int listen(int socket, int backlog); +ssize_t recv(int socket, void *buffer, size_t length, int flags); +ssize_t recvfrom(int socket, void *buffer, size_t length, int flags, + struct sockaddr *address, socklen_t *address_len); +ssize_t send(int socket, const void *message, size_t length, int flags); +ssize_t sendto(int socket, const void *message, size_t length, int flags, + const struct sockaddr *dest_addr, socklen_t dest_len); +int shutdown(int socket, int how); +int socket(int domain, int type, int protocol); + +__END_DECLS + +#endif /* __SYS_SOCKET_H */ Modified: kos/kernel/fs/Makefile =================================================================== --- kos/kernel/fs/Makefile 2006-09-14 03:04:48 UTC (rev 354) +++ kos/kernel/fs/Makefile 2006-09-16 16:18:26 UTC (rev 355) @@ -6,7 +6,7 @@ # $Id: Makefile,v 1.3 2002/08/13 04:54:22 bardtx Exp $ OBJS = fs.o fs_romdisk.o fs_ramdisk.o fs_pty.o -OBJS += fs_utils.o elf.o +OBJS += fs_utils.o elf.o fs_socket.o SUBDIRS = include $(KOS_BASE)/Makefile.prefab Added: kos/kernel/fs/fs_socket.c =================================================================== --- kos/kernel/fs/fs_socket.c (rev 0) +++ kos/kernel/fs/fs_socket.c 2006-09-16 16:18:26 UTC (rev 355) @@ -0,0 +1,298 @@ +/* KallistiOS ##version## + + fs_socket.c + Copyright (C) 2006 Lawrence Sebald + +*/ + +#include <kos/mutex.h> +#include <arch/spinlock.h> +#include <kos/dbgio.h> +#include <kos/fs.h> +#include <kos/fs_socket.h> +#include <kos/net.h> + +#include <errno.h> +#include <string.h> +#include <malloc.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "../net/net_ipv4.h" +#include "../net/net_udp.h" + +/* Define the socket list type */ +LIST_HEAD(socket_list, net_socket); + +static struct socket_list sockets; +static mutex_t *list_mutex; + +static void fs_socket_close(void *hnd) { + net_socket_t *sock = (net_socket_t *) hnd; + + mutex_lock(list_mutex); + LIST_REMOVE(sock, sock_list); + mutex_unlock(list_mutex); + + net_udp_close(hnd); + + free(sock); +} + +static off_t fs_socket_tell(void *hnd) { + errno = ESPIPE; + return (off_t) -1; +} + +/* VFS handler */ +static vfs_handler_t vh = { + /* Name handler */ + { + { 0 }, /* Name */ + 0, /* tbfi */ + 0x00010000, /* Version 1.0 */ + 0, /* Flags */ + NMMGR_TYPE_VFS, + NMMGR_LIST_INIT, + }, + + 0, NULL, /* No cache, privdata */ + + NULL, /* open */ + fs_socket_close, /* close */ + NULL, /* read */ + NULL, /* write */ + NULL, /* seek */ + fs_socket_tell, /* tell */ + NULL, /* total */ + NULL, /* readdir */ + NULL, /* ioctl */ + NULL, /* rename */ + NULL, /* unlink */ + NULL, /* mmap */ + NULL, /* complete */ + NULL, /* stat */ + NULL, /* mkdir */ + NULL /* rmdir */ +}; + +/* Have we been initialized? */ +static int initted = 0; + +int fs_socket_init() { + if(initted == 1) + return 0; + + LIST_INIT(&sockets); + + if(nmmgr_handler_add(&vh.nmmgr) < 0) + return -1; + + list_mutex = mutex_create(); + initted = 1; + + return 0; +} + +int fs_socket_shutdown() { + net_socket_t *c, *n; + + if(initted == 0) + return 0; + + mutex_lock(list_mutex); + c = LIST_FIRST(&sockets); + while(c != NULL) { + n = LIST_NEXT(c, sock_list); + + vh.close(c); + + free(c); + c = n; + } + + if(nmmgr_handler_remove(&vh.nmmgr) < 0) + return -1; + + mutex_destroy(list_mutex); + + initted = 0; + + return 0; +} + +int fs_socket_setflags(int sock, int flags) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_setflags(hnd, flags); +} + +int socket(int domain, int type, int protocol) { + net_socket_t *sock; + file_t hnd; + + /* First, check the arguments for validity */ + if(domain != AF_INET) { + errno = EAFNOSUPPORT; + return -1; + } + + if(type != SOCK_DGRAM) { + errno = EPROTONOSUPPORT; + return -1; + } + + if(protocol != 0 && protocol != IPPROTO_UDP) { + errno = EPROTONOSUPPORT; + return -1; + } + + /* Allocate the socket structure, if we have the space */ + sock = (net_socket_t *) malloc(sizeof(net_socket_t)); + if(!sock) { + errno = ENOMEM; + return -1; + } + + /* Attempt to get a handle for this socket */ + hnd = fs_open_handle(&vh, sock); + if(hnd < 0) { + free(sock); + return -1; + } + + /* We only support UDP right now, so this is ok... */ + sock->protocol = IPPROTO_UDP; + + /* Initialize protocol-specific data */ + if(net_udp_socket(sock, domain, type, protocol) == -1) { + fs_close(hnd); + return -1; + } + + /* Add this socket into the list of sockets, and return */ + mutex_lock(list_mutex); + LIST_INSERT_HEAD(&sockets, sock, sock_list); + mutex_unlock(list_mutex); + + return hnd; +} + +int accept(int sock, struct sockaddr *address, socklen_t *address_len) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_accept(hnd, address, address_len); +} + +int bind(int sock, const struct sockaddr *address, socklen_t address_len) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_bind(hnd, address, address_len); +} + +int connect(int sock, const struct sockaddr *address, socklen_t address_len) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_connect(hnd, address, address_len); +} + +int listen(int sock, int backlog) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_listen(hnd, backlog); +} + +ssize_t recv(int sock, void *buffer, size_t length, int flags) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_recv(hnd, buffer, length, flags); +} + +ssize_t recvfrom(int sock, void *buffer, size_t length, int flags, + struct sockaddr *address, socklen_t *address_len) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_recvfrom(hnd, buffer, length, flags, address, + address_len); +} + +ssize_t send(int sock, const void *message, size_t length, int flags) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_send(hnd, message, length, flags); +} + +ssize_t sendto(int sock, const void *message, size_t length, int flags, + const struct sockaddr *dest_addr, socklen_t dest_len) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_sendto(hnd, message, length, flags, dest_addr, dest_len); +} + +int shutdown(int sock, int how) { + net_socket_t *hnd; + + hnd = (net_socket_t *) fs_get_handle(sock); + if(hnd == NULL) { + errno = EBADF; + return -1; + } + + return net_udp_shutdownsock(hnd, how); +} Modified: kos/kernel/net/net_core.c =================================================================== --- kos/kernel/net/net_core.c 2006-09-14 03:04:48 UTC (rev 354) +++ kos/kernel/net/net_core.c 2006-09-16 16:18:26 UTC (rev 355) @@ -10,6 +10,7 @@ #include <malloc.h> #include <stdio.h> #include <kos/net.h> +#include <kos/fs_socket.h> CVSID("$Id: net_core.c,v 1.5 2002/10/26 07:59:50 bardtx Exp $"); @@ -100,7 +101,7 @@ net_default_dev = n; - return olddev; + return olddev; } /* Device detect / init */ @@ -144,6 +145,11 @@ /* Initialize the ARP cache */ net_arp_init(); + /* Initialize the UDP system */ + net_udp_init(); + + fs_socket_init(); + return 0; } @@ -165,4 +171,9 @@ /* Shut down the ARP cache */ net_arp_shutdown(); + + /* Shut down the UDP system */ + net_udp_shutdown(); + + fs_socket_shutdown(); } Modified: kos/kernel/net/net_udp.c =================================================================== --- kos/kernel/net/net_udp.c 2006-09-14 03:04:48 UTC (rev 354) +++ kos/kernel/net/net_udp.c 2006-09-16 16:18:26 UTC (rev 355) @@ -1,295 +1,689 @@ /* KallistiOS ##version## kernel/net/net_udp.c - Copyright (C) 2005 Lawrence Sebald + Copyright (C) 2005, 2006 Lawrence Sebald */ #include <stdio.h> #include <string.h> #include <malloc.h> +#include <arpa/inet.h> #include <kos/net.h> #include <kos/mutex.h> +#include <kos/cond.h> #include <sys/queue.h> +#include <kos/dbgio.h> +#include <kos/fs_socket.h> +#include <sys/socket.h> +#include <errno.h> #include "net_ipv4.h" #include "net_udp.h" -typedef struct udp_pkt { - TAILQ_ENTRY(udp_pkt) pkt_queue; - udp_hdr_t hdr; - uint8 *data; - uint16 datasize; -} udp_pkt_t; +struct udp_pkt { + TAILQ_ENTRY(udp_pkt) pkt_queue; + struct sockaddr_in from; + uint8 *data; + uint16 datasize; +}; TAILQ_HEAD(udp_pkt_queue, udp_pkt); -typedef struct udp_sock { - LIST_ENTRY(udp_sock) sock_list; - int sock_num; - uint16 loc_port; - uint16 rem_port; - uint32 loc_addr; - uint32 rem_addr; - struct udp_pkt_queue packets; -} udp_sock_t; +struct udp_sock { + LIST_ENTRY(udp_sock) sock_list; + struct sockaddr_in local_addr; + struct sockaddr_in remote_addr; + int flags; + + struct udp_pkt_queue packets; +}; + LIST_HEAD(udp_sock_list, udp_sock); -static struct udp_sock_list net_udp_socks = LIST_HEAD_INITIALIZER(0); -static int cur_udp_sock = 0; -static uint8 udp_buf[1514]; +static struct udp_sock_list net_udp_sockets = LIST_HEAD_INITIALIZER(0); +static mutex_t *udp_mutex; +static condvar_t *udp_packets_ready; -int net_udp_sock_open(uint16 loc_port, uint32 loc_addr, uint16 rem_port, uint32 rem_addr) { - udp_sock_t *ns; +int net_udp_accept(net_socket_t *hnd, struct sockaddr *addr, + socklen_t *addr_len) { + errno = EOPNOTSUPP; + return -1; +} - LIST_FOREACH(ns, &net_udp_socks, sock_list) { - if(ns->loc_port == loc_port && ns->loc_addr == loc_addr && - ns->rem_port == rem_port && ns->rem_addr == rem_addr) { - dbglog(DBG_KDEBUG, "net_udp: Attempt to create already existing socket\n"); - return 0; - } - } +int net_udp_bind(net_socket_t *hnd, const struct sockaddr *addr, + socklen_t addr_len) { + struct udp_sock *udpsock, *iter; + struct sockaddr_in *realaddr; - ns = (udp_sock_t *)malloc(sizeof(udp_sock_t)); + /* Verify the parameters sent in first */ + if(addr == NULL) { + errno = EFAULT; + return -1; + } - ns->sock_num = ++cur_udp_sock; - ns->loc_port = loc_port; - ns->loc_addr = loc_addr; - ns->rem_port = rem_port; - ns->rem_addr = rem_addr; + if(addr->sa_family != AF_INET) { + errno = EAFNOSUPPORT; + return -1; + } - TAILQ_INIT(&ns->packets); - LIST_INSERT_HEAD(&net_udp_socks, ns, sock_list); + /* Get the sockaddr_in structure, rather than the sockaddr one */ + realaddr = (struct sockaddr_in *) addr; - return cur_udp_sock; + mutex_lock(udp_mutex); + + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } + + /* See if we requested a specific port or not */ + if(realaddr->sin_port != 0) { + /* Make sure we don't already have a socket bound to the + port specified */ + + LIST_FOREACH(iter, &net_udp_sockets, sock_list) { + if(iter->local_addr.sin_port == realaddr->sin_port) { + mutex_unlock(udp_mutex); + errno = EADDRINUSE; + return -1; + } + } + + udpsock->local_addr = *realaddr; + } + else { + uint16 port = 1024, tmp = 0; + + /* Grab the first unused port >= 1024. This is, unfortunately, O(n^2) */ + while(tmp != port) { + tmp = port; + + LIST_FOREACH(iter, &net_udp_sockets, sock_list) { + if(iter->local_addr.sin_port == port) { + ++port; + break; + } + } + } + + udpsock->local_addr = *realaddr; + udpsock->local_addr.sin_port = htons(port); + } + + mutex_unlock(udp_mutex); + + return 0; } -int net_udp_sock_close(int socknum) { - udp_sock_t *ns; - udp_pkt_t *pkt; +int net_udp_connect(net_socket_t *hnd, const struct sockaddr *addr, + socklen_t addr_len) { + struct udp_sock *udpsock; + struct sockaddr_in *realaddr; - LIST_FOREACH(ns, &net_udp_socks, sock_list) { - if(ns->sock_num == socknum) { - LIST_REMOVE(ns, sock_list); - TAILQ_FOREACH(pkt, &ns->packets, pkt_queue) { - TAILQ_REMOVE(&ns->packets, pkt, pkt_queue); - free(pkt->data); - free(pkt); - } - free(ns); + if(addr == NULL) { + errno = EFAULT; + return -1; + } - return 0; - } - } + if(addr->sa_family != AF_INET) { + errno = EAFNOSUPPORT; + return -1; + } - dbglog(DBG_KDEBUG, "net_udp: Attempt to close unopened socket"); - return -1; + mutex_lock(udp_mutex); + + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } + + if(udpsock->remote_addr.sin_addr.s_addr != INADDR_ANY) { + mutex_unlock(udp_mutex); + errno = EISCONN; + return -1; + } + + realaddr = (struct sockaddr_in *) addr; + if(realaddr->sin_port == 0 || realaddr->sin_addr.s_addr == INADDR_ANY) { + mutex_unlock(udp_mutex); + errno = EADDRNOTAVAIL; + return -1; + } + + udpsock->remote_addr.sin_addr.s_addr = realaddr->sin_addr.s_addr; + udpsock->remote_addr.sin_port = realaddr->sin_port; + + mutex_unlock(udp_mutex); + + return 0; } -int net_udp_recv(int sock, uint8 *buf, int size) { - udp_sock_t *ns; - udp_pkt_t *pkt; +int net_udp_listen(net_socket_t *hnd, int backlog) { + errno = EOPNOTSUPP; + return -1; +} - LIST_FOREACH(ns, &net_udp_socks, sock_list) { - if(ns->sock_num == sock) { - pkt = TAILQ_FIRST(&ns->packets); - if(pkt) { - if(size >= pkt->datasize) { - memcpy(buf, pkt->data, pkt->datasize); - TAILQ_REMOVE(&ns->packets, pkt, pkt_queue); - size = pkt->datasize; - free(pkt->data); - free(pkt); - return size; - } - else { - uint8 tbuf[pkt->datasize - size]; - memcpy(buf, pkt->data, size); - memcpy(tbuf, pkt->data + size, pkt->datasize - size); - free(pkt->data); - pkt->data = (uint8 *)malloc(pkt->datasize - size); - memcpy(pkt->data, tbuf, pkt->datasize - size); - pkt->datasize -= size; - return size; - } - } - else { - return 0; - } - } - } +ssize_t net_udp_recv(net_socket_t *hnd, void *buffer, size_t length, int flags) { + struct udp_sock *udpsock; + struct udp_pkt *pkt; - dbglog(DBG_KDEBUG, "net_udp: attempt to recv on unopened socket\n"); + mutex_lock(udp_mutex); - return -1; + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } + + if(udpsock->remote_addr.sin_addr.s_addr == INADDR_ANY || + udpsock->remote_addr.sin_port == 0) { + mutex_unlock(udp_mutex); + errno = ENOTCONN; + return -1; + } + + if(udpsock->flags & SHUT_RD) { + mutex_unlock(udp_mutex); + return 0; + } + + if(buffer == NULL) { + mutex_unlock(udp_mutex); + errno = EFAULT; + return -1; + } + + if(TAILQ_EMPTY(&udpsock->packets) && (udpsock->flags & O_NONBLOCK)) { + mutex_unlock(udp_mutex); + errno = EWOULDBLOCK; + return -1; + } + + if(TAILQ_EMPTY(&udpsock->packets)) { + cond_wait(udp_packets_ready, udp_mutex); + } + + pkt = TAILQ_FIRST(&udpsock->packets); + + if(pkt->datasize > length) { + memcpy(buffer, pkt->data, length); + } + else { + memcpy(buffer, pkt->data, pkt->datasize); + length = pkt->datasize; + } + + TAILQ_REMOVE(&udpsock->packets, pkt, pkt_queue); + free(pkt->data); + free(pkt); + + mutex_unlock(udp_mutex); + + return length; } -int net_udp_send(int sock, const uint8 *data, int size) { - udp_sock_t *ns; - - LIST_FOREACH(ns, &net_udp_socks, sock_list) { - if(ns->sock_num == sock) { - ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *)udp_buf; - ip_hdr_t ip; - int internsize; +ssize_t net_udp_recvfrom(net_socket_t *hnd, void *buffer, size_t length, + int flags, struct sockaddr *addr, + socklen_t *addr_len) { + struct udp_sock *udpsock; + struct udp_pkt *pkt; - /* Fill in the UDP Header */ - ps->src_addr = ns->loc_addr; - ps->dst_addr = ns->rem_addr; - ps->zero = 0; - ps->proto = 17; - ps->length = net_ntohs(size + sizeof(udp_hdr_t)); - ps->src_port = ns->loc_port; - ps->dst_port = ns->rem_port; - ps->hdrlength = ps->length; - ps->checksum = 0; - memcpy(ps->data, data, size); + mutex_lock(udp_mutex); - if(size % 2) { - internsize = size + 1; - ps->data[internsize] = 0; - } - else - internsize = size; + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } - /* Compute the UDP Checksum */ - ps->checksum = net_ipv4_checksum((uint16 *)udp_buf, (internsize + sizeof(udp_hdr_t) + 12) / 2); + if(udpsock->flags & SHUT_RD) { + mutex_unlock(udp_mutex); + return 0; + } - /* Fill in the IP Header */ - ip.version_ihl = 0x45; /* 20 byte header, ipv4 */ - ip.tos = 0; - ip.length = net_ntohs(sizeof(udp_hdr_t) + size + 20); - ip.packet_id = 0; - ip.flags_frag_offs = net_ntohs(0x4000); - ip.ttl = 64; - ip.protocol = 17; /* UDP */ - ip.checksum = 0; - ip.src = ps->src_addr; - ip.dest = ps->dst_addr; + if(buffer == NULL || addr_len == NULL) { + mutex_unlock(udp_mutex); + errno = EFAULT; + return -1; + } - /* Compute the IP Checksum */ - ip.checksum = net_ipv4_checksum((uint16*)&ip, sizeof(ip_hdr_t) / 2); + if(TAILQ_EMPTY(&udpsock->packets) && (udpsock->flags & O_NONBLOCK)) { + mutex_unlock(udp_mutex); + errno = EWOULDBLOCK; + return -1; + } - net_ipv4_send_packet(net_default_dev, &ip, (uint8 *)(udp_buf + 12), sizeof(udp_hdr_t) + size); + while(TAILQ_EMPTY(&udpsock->packets)) { + cond_wait(udp_packets_ready, udp_mutex); + } - return size; - } - } + pkt = TAILQ_FIRST(&udpsock->packets); - dbglog(DBG_KDEBUG, "net_udp: attempt to send on unopened socket\n"); - - return -1; + if(pkt->datasize > length) { + memcpy(buffer, pkt->data, length); + } + else { + memcpy(buffer, pkt->data, pkt->datasize); + length = pkt->datasize; + } + + if(addr != NULL) { + struct sockaddr_in realaddr; + + realaddr.sin_family = AF_INET; + realaddr.sin_addr.s_addr = pkt->from.sin_addr.s_addr; + realaddr.sin_port = pkt->from.sin_port; + memset(realaddr.sin_zero, 0, 8); + + if(*addr_len < sizeof(struct sockaddr_in)) { + memcpy(addr, &realaddr, *addr_len); + } + else { + memcpy(addr, &realaddr, sizeof(struct sockaddr_in)); + *addr_len = sizeof(struct sockaddr_in); + } + } + + TAILQ_REMOVE(&udpsock->packets, pkt, pkt_queue); + free(pkt->data); + free(pkt); + + mutex_unlock(udp_mutex); + + return length; } -int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ip, const uint8 *data, int size) { - ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t*)udp_buf; - uint16 i; - udp_sock_t *sock; - udp_pkt_t *pkt; +ssize_t net_udp_send(net_socket_t *hnd, const void *message, size_t length, + int flags) { + struct udp_sock *udpsock; - ps->src_addr = ip->src; - ps->dst_addr = ip->dest; - ps->zero = 0; - ps->proto = ip->protocol; - memcpy(&ps->src_port, data, size); - ps->length = net_ntohs(size); + mutex_lock(udp_mutex); - if(size % 2) { - ps->data[size - sizeof(udp_hdr_t)] = 0; - ++size; - } + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } - i = ps->checksum; - ps->checksum = 0; - ps->checksum = net_ipv4_checksum((uint16 *)udp_buf, (size + 12) / 2); + if(udpsock->flags & SHUT_WR) { + mutex_unlock(udp_mutex); + errno = EPIPE; + return -1; + } -#ifdef DEBUG_UDP - printf("UDP Header Dump:\n"); - printf(" Pseudo-Header:\n"); - printf("src_addr = 0x%08x\n", ps->src_addr); - printf("dst_addr = 0x%08x\n", ps->dst_addr); - printf("zero = 0x%02x\n", ps->zero); - printf("proto = 0x%02x\n", ps->proto); - printf("length = 0x%04x\n", ps->length); - printf("src_port = 0x%04x\n", ps->src_port); - printf("dst_port = 0x%04x\n", ps->dst_port); - printf("hdrlength = 0x%04x\n", ps->hdrlength); - printf("checksum = 0x%04x\n", ps->checksum); -#endif + if(udpsock->remote_addr.sin_addr.s_addr == INADDR_ANY || + udpsock->remote_addr.sin_port == 0) { + mutex_unlock(udp_mutex); + errno = ENOTCONN; + return -1; + } - if(i != ps->checksum) { - dbglog(DBG_KDEBUG, "net_udp: discarding UDP packet with invalid checksum\n"); - dbglog(DBG_KDEBUG, "net_udp: was %x, expected %x\n", i, ps->checksum); - return -1; - } + if(message == NULL) { + mutex_unlock(udp_mutex); + errno = EFAULT; + return -1; + } - LIST_FOREACH(sock, &net_udp_socks, sock_list) { - if(sock->loc_port == ps->dst_port && sock->loc_addr == ps->dst_addr && - ((sock->rem_port == ps->src_port && sock->rem_addr == ps->src_addr) || - (sock->rem_port == 0 && sock->rem_addr == 0))) { - sock->rem_port = ps->src_port; - sock->rem_addr = ps->src_addr; - pkt = (udp_pkt_t *) malloc(sizeof(udp_pkt_t)); - pkt->datasize = size - sizeof(udp_hdr_t); - pkt->data = (uint8 *) malloc(pkt->datasize); - memcpy(&pkt->hdr, &ps->src_port, sizeof(udp_hdr_t)); - memcpy(pkt->data, ps->data, pkt->datasize); - TAILQ_INSERT_TAIL(&sock->packets, pkt, pkt_queue); - return 0; - } - } + if(udpsock->local_addr.sin_port == 0) { + uint16 port = 1024, tmp = 0; + struct udp_sock *iter; - dbglog(DBG_KDEBUG, "net_udp: discarding UDP packet for unopened socket\n"); + /* Grab the first unused port >= 1024. This is, unfortunately, O(n^2) */ + while(tmp != port) { + tmp = port; - return 0; + LIST_FOREACH(iter, &net_udp_sockets, sock_list) { + if(iter->local_addr.sin_port == port) { + ++port; + break; + } + } + } + + udpsock->local_addr.sin_port = htons(port); + } + + mutex_unlock(udp_mutex); + + return net_udp_send_raw(NULL, udpsock->local_addr.sin_addr.s_addr, + udpsock->local_addr.sin_port, + udpsock->remote_addr.sin_addr.s_addr, + udpsock->remote_addr.sin_port, (uint8 *) message, + length); } -int net_udp_send_raw(netif_t *net, uint16 src_port, uint16 dst_port, const uint8 ipa[4], - const uint8 *data, int size) { - ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *)udp_buf; - ip_hdr_t ip; - int internsize; +ssize_t net_udp_sendto(net_socket_t *hnd, const void *message, size_t length, + int flags, const struct sockaddr *addr, + socklen_t addr_len) { + struct udp_sock *udpsock; + struct sockaddr_in *realaddr; - /* Fill in the UDP Header */ - if(net == NULL) /* Sending from the loopback device? */ - ps->src_addr = 0x0100007f; /* 127.0.0.1 */ - else - ps->src_addr = net_ntohl(net_ipv4_address(net->ip_addr)); - ps->dst_addr = net_ntohl(net_ipv4_address(ipa)); - ps->zero = 0; - ps->proto = 17; - ps->length = net_ntohs(size + sizeof(udp_hdr_t)); - ps->src_port = net_ntohs(src_port); - ps->dst_port = net_ntohs(dst_port); - ps->hdrlength = ps->length; - ps->checksum = 0; - memcpy(ps->data, data, size); + mutex_lock(udp_mutex); - if(size % 2) { - internsize = size + 1; - ps->data[internsize] = 0; - } - else - internsize = size; - + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } - /* Compute the UDP Checksum */ - ps->checksum = net_ipv4_checksum((uint16 *)udp_buf, (internsize + sizeof(udp_hdr_t) + 12) / 2); + if(udpsock->flags & SHUT_WR) { + mutex_unlock(udp_mutex); + errno = EPIPE; + return -1; + } - /* Fill in the IP Header */ - ip.version_ihl = 0x45; /* 20 byte header, ipv4 */ - ip.tos = 0; - ip.length = net_ntohs(sizeof(udp_hdr_t) + size + 20); - ip.packet_id = 0; - ip.flags_frag_offs = net_ntohs(0x4000); - ip.ttl = 64; - ip.protocol = 17; /* UDP */ - ip.checksum = 0; - ip.src = ps->src_addr; - ip.dest = ps->dst_addr; + if(message == NULL || addr == NULL) { + mutex_unlock(udp_mutex); + errno = EFAULT; + return -1; + } - /* Compute the IP Checksum */ - ip.checksum = net_ipv4_checksum((uint16*)&ip, sizeof(ip_hdr_t) / 2); + realaddr = (struct sockaddr_in *) addr; - return net_ipv4_send_packet(net, &ip, (uint8 *)(udp_buf + 12), sizeof(udp_hdr_t) + size); + if(udpsock->local_addr.sin_port == 0) { + uint16 port = 1024, tmp = 0; + struct udp_sock *iter; + + /* Grab the first unused port >= 1024. This is, unfortunately, O(n^2) */ + while(tmp != port) { + tmp = port; + + LIST_FOREACH(iter, &net_udp_sockets, sock_list) { + if(iter->local_addr.sin_port == port) { + ++port; + break; + } + } + } + + udpsock->local_addr.sin_port = htons(port); + } + + mutex_unlock(udp_mutex); + + return net_udp_send_raw(NULL, udpsock->local_addr.sin_addr.s_addr, + udpsock->local_addr.sin_port, + realaddr->sin_addr.s_addr, realaddr->sin_port, + (uint8 *) message, length); } + +int net_udp_shutdownsock(net_socket_t *hnd, int how) { + struct udp_sock *udpsock; + + mutex_lock(udp_mutex); + + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } + + if(how & 0xFFFFFFFC) { + mutex_unlock(udp_mutex); + errno = EINVAL; + } + + udpsock->flags |= how; + + mutex_unlock(udp_mutex); + + return 0; +} + +int net_udp_socket(net_socket_t *hnd, int domain, int type, int protocol) { + struct udp_sock *udpsock; + + udpsock = (struct udp_sock *) malloc(sizeof(struct udp_sock)); + if(udpsock == NULL) { + errno = ENOMEM; + return -1; + } + + udpsock->remote_addr.sin_family = AF_INET; + udpsock->remote_addr.sin_addr.s_addr = INADDR_ANY; + udpsock->remote_addr.sin_port = 0; + + udpsock->local_addr.sin_family = AF_INET; + udpsock->local_addr.sin_addr.s_addr = INADDR_ANY; + udpsock->local_addr.sin_port = 0; + + udpsock->flags = 0; + + TAILQ_INIT(&udpsock->packets); + + mutex_lock(udp_mutex); + LIST_INSERT_HEAD(&net_udp_sockets, udpsock, sock_list); + mutex_unlock(udp_mutex); + + hnd->data = udpsock; + + return 0; +} + +void net_udp_close(net_socket_t *hnd) { + struct udp_sock *udpsock; + struct udp_pkt *pkt; + + mutex_lock(udp_mutex); + + udpsock = (struct udp_sock *)hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + } + + TAILQ_FOREACH(pkt, &udpsock->packets, pkt_queue) { + free(pkt->data); + TAILQ_REMOVE(&udpsock->packets, pkt, pkt_queue); + free(pkt); + } + + LIST_REMOVE(udpsock, sock_list); + + free(udpsock); + mutex_unlock(udp_mutex); +} + +int net_udp_setflags(net_socket_t *hnd, int flags) { + struct udp_sock *udpsock; + + mutex_lock(udp_mutex); + + udpsock = (struct udp_sock *) hnd->data; + if(udpsock == NULL) { + mutex_unlock(udp_mutex); + errno = EBADF; + return -1; + } + + if(flags & (~O_NONBLOCK)) { + mutex_unlock(udp_mutex); + errno = EINVAL; + return -1; + } + + udpsock->flags |= flags; + mutex_unlock(udp_mutex); + + return 0; +} + +int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ip, const uint8 *data, + int size) { + uint8 buf[size + 13]; + ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *)buf; + uint16 checksum; + struct udp_sock *sock; + struct udp_pkt *pkt; + + ps->src_addr = ip->src; + ps->dst_addr = ip->dest; + ps->zero = 0; + ps->proto = ip->protocol; + memcpy(&ps->src_port, data, size); + ps->length = htons(size); + + /* check this.... */ + if(size & 0x01) { + ps->data[size - sizeof(udp_hdr_t)] = 0; + checksum = ps->checksum; + ps->checksum = 0; + ps->checksum = net_ipv4_checksum((uint16 *) buf, (size + 13) >> 1); + } + else { + checksum = ps->checksum; + ps->checksum = 0; + ps->checksum = net_ipv4_checksum((uint16 *) buf, (size + 12) >> 1); + } + + if(checksum != ps->checksum) { + dbglog(DBG_KDEBUG, "net_udp: discarding UDP packet with invalid " + "checksum\n" + " calculated 0x%04X, sent 0x%04X\n", + ps->checksum, checksum); + return -1; + } + + if(mutex_trylock(udp_mutex)) { + dbglog(DBG_KDEBUG, "net_udp: discarding packet due to locked mutex\n"); + return -1; + } + + LIST_FOREACH(sock, &net_udp_sockets, sock_list) { + /* See if we have a socket matching the description provided */ + if(sock->local_addr.sin_port == ps->dst_port && + ((sock->remote_addr.sin_port == ps->src_port && + sock->remote_addr.sin_addr.s_addr == ps->src_addr) || + (sock->remote_addr.sin_port == 0 && + sock->remote_addr.sin_addr.s_addr == INADDR_ANY))) { + pkt = (struct udp_pkt *) malloc(sizeof(struct udp_pkt)); + + pkt->datasize = size - sizeof(udp_hdr_t); + pkt->data = (uint8 *) malloc(pkt->datasize); + + pkt->from.sin_family = AF_INET; + pkt->from.sin_addr.s_addr = ip->src; + pkt->from.sin_port = ps->src_port; + + memcpy(pkt->data, ps->data, pkt->datasize); + + TAILQ_INSERT_TAIL(&sock->packets, pkt, pkt_queue); + + cond_broadcast(udp_packets_ready); + + mutex_unlock(udp_mutex); + + return 0; + } + } + + dbglog(DBG_KDEBUG, "net_udp: Discarding packet for non-opened socket\n"); + mutex_unlock(udp_mutex); + + return 0; +} + +int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port, + uint32 dst_ip, uint16 dst_port, const uint8 *data, + int size) { + uint8 buf[size + 13 + sizeof(udp_hdr_t)]; + ip_pseudo_hdr_t *ps = (ip_pseudo_hdr_t *) buf; + ip_hdr_t ip; + + if(net == NULL && net_default_dev == NULL) { + errno = ENETDOWN; + return -1; + } + + if(src_ip == INADDR_ANY) { + if(net == NULL && net_default_dev != NULL) { + ps->src_addr = htonl(net_ipv4_address(net_default_dev->ip_addr)); + } + else if(net != NULL) { + ps->src_addr = htonl(net_ipv4_address(net->ip_addr)); + } + } + else { + ps->src_addr = src_ip; + } + + buf[size + 12 + sizeof(udp_hdr_t)] = 0; + memcpy(ps->data, data, size); + size += sizeof(udp_hdr_t); + + ps->dst_addr = dst_ip; + ps->zero = 0; + ps->proto = 17; + ps->length = htons(size); + ps->src_port = src_port; + ps->dst_port = dst_port; + ps->hdrlength = ps->length; + ps->checksum = 0; + + /* Compute the UDP checksum */ + if(size & 0x01) { + ps->checksum = net_ipv4_checksum((uint16 *) buf, + (size + 13) >> 1); + } + else { + ps->checksum = net_ipv4_checksum((uint16 *) buf, + (size + 12) >> 1); + } + + /* Fill in the IPv4 Header */ + ip.version_ihl = 0x45; + ip.tos = 0; + ip.length = htons(size + 20); + ip.packet_id = 0; + ip.flags_frag_offs = htons(0x4000); + ip.ttl = 64; + ip.protocol = 17; + ip.checksum = 0; + ip.src = ps->src_addr; + ip.dest = ps->dst_addr; + + /* Compute the IPv4 checksum */ + ip.checksum = net_ipv4_checksum((uint16 *) &ip, sizeof(ip_hdr_t) >> 1); + + /* send it away.... */ + if(net_ipv4_send_packet(net, &ip, buf + 12, size)) { + /* If net_ipv4_send_packet() returns anything but 0, its an error, + errno should be set already from it. */ + return -1; + } + else { + return size - sizeof(udp_hdr_t); + } +} + +int net_udp_init() { + udp_mutex = mutex_create(); + + if(udp_mutex == NULL) { + return -1; + } + + udp_packets_ready = cond_create(); + + if(udp_packets_ready == NULL) { + mutex_destroy(udp_mutex); + return -1; + } + + return 0; +} + +void net_udp_shutdown() { + mutex_destroy(udp_mutex); + cond_destroy(udp_packets_ready); +} Modified: kos/kernel/net/net_udp.h =================================================================== --- kos/kernel/net/net_udp.h 2006-09-14 03:04:48 UTC (rev 354) +++ kos/kernel/net/net_udp.h 2006-09-16 16:18:26 UTC (rev 355) @@ -1,22 +1,52 @@ /* KallistiOS ##version## kernel/net/net_udp.h - Copyright (C) 2005 Lawrence Sebald + Copyright (C) 2005, 2006 Lawrence Sebald */ #ifndef __LOCAL_NET_UDP_H #define __LOCAL_NET_UDP_H +#include <sys/socket.h> +#include <kos/fs_socket.h> + #define packed __attribute__((packed)) typedef struct { - uint16 src_port packed; - uint16 dst_port packed; - uint16 length packed; - uint16 checksum packed; + uint16 src_port packed; + uint16 dst_port packed; + uint16 length packed; + uint16 checksum packed; } udp_hdr_t; #undef packed -int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ih, const uint8 *data, int size); +int net_udp_input(netif_t *src, eth_hdr_t *eh, ip_hdr_t *ih, const uint8 *data, + int size); +int net_udp_send_raw(netif_t *net, uint32 src_ip, uint16 src_port, + uint32 dst_ip, uint16 dst_port, const uint8 *data, + int size); +/* Sockets */ +int net_udp_accept(net_socket_t *hnd, struct sockaddr *addr, + socklen_t *addr_len); +int net_udp_bind(net_socket_t *hnd, const struct sockaddr *addr, + socklen_t addr_len); +int net_udp_connect(net_socket_t *hnd, const struct sockaddr *addr, + socklen_t addr_len); +int net_udp_listen(net_socket_t *hnd, int backlog); +ssize_t net_udp_recv(net_socket_t *hnd, void *buffer, size_t length, int flags); +ssize_t net_udp_recvfrom(net_socket_t *hnd, void *buffer, size_t length, + int flags, struct sockaddr *addr, socklen_t *addr_len); +ssize_t net_udp_send(net_socket_t *hnd, const void *message, size_t length, + int flags); +ssize_t net_udp_sendto(net_socket_t *hnd, const void *message, size_t length, + int flags, const struct sockaddr *addr, + socklen_t addr_len); +int net_udp_shutdownsock(net_socket_t *hnd, int how); +int net_udp_socket(net_socket_t *hnd, int domain, int type, int protocol); + +void net_udp_close(net_socket_t *hnd); + +int net_udp_setflags(net_socket_t *hnd, int flags); + #endif /* __LOCAL_NET_UDP_H */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ba...@us...> - 2006-09-17 23:44:15
|
Revision: 358 http://svn.sourceforge.net/cadcdev/?rev=358&view=rev Author: bardtx Date: 2006-09-17 16:44:08 -0700 (Sun, 17 Sep 2006) Log Message: ----------- kos: Patch #1552702 from SourceForge: A patch that includes realpath() to gain support for "." and ".." in pathnames. Also includes some small changes to map standard functions to KOS functions. Modified Paths: -------------- kos/include/kos/limits.h kos/kernel/libc/koslib/Makefile Added Paths: ----------- kos/include/limits.h kos/kernel/libc/koslib/chdir.c kos/kernel/libc/koslib/creat.c kos/kernel/libc/koslib/getcwd.c kos/kernel/libc/koslib/mkdir.c kos/kernel/libc/koslib/realpath.c kos/kernel/libc/koslib/rename.c kos/kernel/libc/koslib/rmdir.c kos/kernel/libc/koslib/sleep.c Modified: kos/include/kos/limits.h =================================================================== --- kos/include/kos/limits.h 2006-09-17 23:33:39 UTC (rev 357) +++ kos/include/kos/limits.h 2006-09-17 23:44:08 UTC (rev 358) @@ -11,5 +11,6 @@ #define __KOS_LIMITS_H #define MAX_FN_LEN 256 /* Max filename length */ +#define PATH_MAX 4095 /* Max path length */ #endif /* __KOS_LIMITS_H */ Added: kos/include/limits.h =================================================================== --- kos/include/limits.h (rev 0) +++ kos/include/limits.h 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,13 @@ +/* KallistiOS ##version## + + limits.h + Copyright (C)2006 Dan Potter + +*/ + +#ifndef __LIMITS_H +#define __LIMITS_H + +#include <kos/limits.h> + +#endif /* __LIMITS_H */ Modified: kos/kernel/libc/koslib/Makefile =================================================================== --- kos/kernel/libc/koslib/Makefile 2006-09-17 23:33:39 UTC (rev 357) +++ kos/kernel/libc/koslib/Makefile 2006-09-17 23:44:08 UTC (rev 358) @@ -10,6 +10,7 @@ OBJS = abort.o byteorder.o memset2.o memset4.o memcpy2.o memcpy4.o \ assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \ opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \ - telldir.o usleep.o inet_addr.o + telldir.o usleep.o inet_addr.o realpath.o getcwd.o chdir.o mkdir.o \ + creat.o sleep.o rmdir.o rename.o include $(KOS_BASE)/Makefile.prefab Added: kos/kernel/libc/koslib/chdir.c =================================================================== --- kos/kernel/libc/koslib/chdir.c (rev 0) +++ kos/kernel/libc/koslib/chdir.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,12 @@ +/* KallistiOS ##version## + + chdir.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <kos/fs.h> + +int chdir(const char *path) +{ + return fs_chdir(path); +} Added: kos/kernel/libc/koslib/creat.c =================================================================== --- kos/kernel/libc/koslib/creat.c (rev 0) +++ kos/kernel/libc/koslib/creat.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,12 @@ +/* KallistiOS ##version## + + creat.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <fcntl.h> + +int creat(const char *pathname, mode_t mode) +{ + return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode); +} Added: kos/kernel/libc/koslib/getcwd.c =================================================================== --- kos/kernel/libc/koslib/getcwd.c (rev 0) +++ kos/kernel/libc/koslib/getcwd.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,23 @@ +/* KallistiOS ##version## + + getcwd.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <string.h> +#include <errno.h> + +#include <kos/fs.h> + +char *getcwd(char *buf, size_t size) +{ + const char *wd = fs_getwd(); + + if (strlen(wd) + 1 > size) { + errno = ERANGE; + return NULL; + } + + strcpy(buf, wd); + return buf; +} Added: kos/kernel/libc/koslib/mkdir.c =================================================================== --- kos/kernel/libc/koslib/mkdir.c (rev 0) +++ kos/kernel/libc/koslib/mkdir.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,12 @@ +/* KallistiOS ##version## + + mkdir.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <kos/fs.h> + +int mkdir(const char *pathname, mode_t mode) +{ + return fs_mkdir(pathname); +} Added: kos/kernel/libc/koslib/realpath.c =================================================================== --- kos/kernel/libc/koslib/realpath.c (rev 0) +++ kos/kernel/libc/koslib/realpath.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2003 Constantin S. Svintsoff <ko...@ic...> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The names of the authors may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +#include <sys/param.h> +#include <sys/stat.h> + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <limits.h> + +/* + * char *realpath(const char *path, char resolved[PATH_MAX]); + * + * Find the real name of path, by removing all ".", ".." and symlink + * components. Returns (resolved) on success, or (NULL) on failure, + * in which case the path which caused trouble is left in (resolved). + */ +char * +realpath(const char *path, char resolved[PATH_MAX]) +{ + char *p, *q, *s; + size_t left_len, resolved_len; + int serrno; + char left[PATH_MAX], next_token[PATH_MAX]; + + serrno = errno; + if (path[0] == '/') { + resolved[0] = '/'; + resolved[1] = '\0'; + if (path[1] == '\0') + return (resolved); + resolved_len = 1; + left_len = strlcpy(left, path + 1, sizeof(left)); + } else { + if (getcwd(resolved, PATH_MAX) == NULL) { + strlcpy(resolved, ".", PATH_MAX); + return (NULL); + } + resolved_len = strlen(resolved); + left_len = strlcpy(left, path, sizeof(left)); + } + if (left_len >= sizeof(left) || resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + + /* + * Iterate over path components in `left'. + */ + while (left_len != 0) { + /* + * Extract the next path component and adjust `left' + * and its length. + */ + p = strchr(left, '/'); + s = p ? p : left + left_len; + if (s - left >= sizeof(next_token)) { + errno = ENAMETOOLONG; + return (NULL); + } + memcpy(next_token, left, s - left); + next_token[s - left] = '\0'; + left_len -= s - left; + if (p != NULL) + memmove(left, s + 1, left_len + 1); + if (resolved[resolved_len - 1] != '/') { + if (resolved_len + 1 >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + resolved[resolved_len++] = '/'; + resolved[resolved_len] = '\0'; + } + if (next_token[0] == '\0') + continue; + else if (strcmp(next_token, ".") == 0) + continue; + else if (strcmp(next_token, "..") == 0) { + /* + * Strip the last path component except when we have + * single "/" + */ + if (resolved_len > 1) { + resolved[resolved_len - 1] = '\0'; + q = strrchr(resolved, '/') + 1; + *q = '\0'; + resolved_len = q - resolved; + } + continue; + } + + /* + * Append the next path component and lstat() it. If + * lstat() fails we still can return successfully if + * there are no more path components left. + */ + resolved_len = strlcat(resolved, next_token, PATH_MAX); + if (resolved_len >= PATH_MAX) { + errno = ENAMETOOLONG; + return (NULL); + } + } + + /* + * Remove trailing slash except when the resolved pathname + * is a single "/". + */ + if (resolved_len > 1 && resolved[resolved_len - 1] == '/') + resolved[resolved_len - 1] = '\0'; + return (resolved); +} Added: kos/kernel/libc/koslib/rename.c =================================================================== --- kos/kernel/libc/koslib/rename.c (rev 0) +++ kos/kernel/libc/koslib/rename.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,12 @@ +/* KallistiOS ##version## + + rename.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <kos/fs.h> + +int rename(const char *oldpath, const char *newpath) +{ + return fs_rename(oldpath, newpath); +} Added: kos/kernel/libc/koslib/rmdir.c =================================================================== --- kos/kernel/libc/koslib/rmdir.c (rev 0) +++ kos/kernel/libc/koslib/rmdir.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,12 @@ +/* KallistiOS ##version## + + rmdir.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <kos/fs.h> + +int rmdir(const char *pathname) +{ + return fs_rmdir(pathname); +} Added: kos/kernel/libc/koslib/sleep.c =================================================================== --- kos/kernel/libc/koslib/sleep.c (rev 0) +++ kos/kernel/libc/koslib/sleep.c 2006-09-17 23:44:08 UTC (rev 358) @@ -0,0 +1,14 @@ +/* KallistiOS ##version## + + sleep.c + Copyright (C)2005 Walter van Niftrik +*/ + +#include <kos/thread.h> + +unsigned int sleep(unsigned int seconds) +{ + thd_sleep(seconds * 1000); + + return 0; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ba...@us...> - 2006-09-18 00:45:27
|
Revision: 373 http://svn.sourceforge.net/cadcdev/?rev=373&view=rev Author: bardtx Date: 2006-09-17 17:45:21 -0700 (Sun, 17 Sep 2006) Log Message: ----------- kos: Revert limits.h change earlier.. breaks other stuff Modified Paths: -------------- kos/kernel/libc/koslib/realpath.c Removed Paths: ------------- kos/include/limits.h Deleted: kos/include/limits.h =================================================================== --- kos/include/limits.h 2006-09-18 00:31:09 UTC (rev 372) +++ kos/include/limits.h 2006-09-18 00:45:21 UTC (rev 373) @@ -1,13 +0,0 @@ -/* KallistiOS ##version## - - limits.h - Copyright (C)2006 Dan Potter - -*/ - -#ifndef __LIMITS_H -#define __LIMITS_H - -#include <kos/limits.h> - -#endif /* __LIMITS_H */ Modified: kos/kernel/libc/koslib/realpath.c =================================================================== --- kos/kernel/libc/koslib/realpath.c 2006-09-18 00:31:09 UTC (rev 372) +++ kos/kernel/libc/koslib/realpath.c 2006-09-18 00:45:21 UTC (rev 373) @@ -30,6 +30,7 @@ #include <sys/param.h> #include <sys/stat.h> +#include <kos/limits.h> #include <errno.h> #include <stdlib.h> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2007-08-03 04:19:58
|
Revision: 430 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=430&view=rev Author: ljsebald Date: 2007-08-02 21:19:54 -0700 (Thu, 02 Aug 2007) Log Message: ----------- Adding in a few more inet functions for dealing with parsing and packing internet addresses. Modified Paths: -------------- kos/include/arpa/inet.h kos/include/netinet/in.h kos/kernel/libc/koslib/Makefile kos/kernel/libc/koslib/inet_addr.c Added Paths: ----------- kos/kernel/libc/koslib/inet_aton.c kos/kernel/libc/koslib/inet_ntoa.c kos/kernel/libc/koslib/inet_ntop.c kos/kernel/libc/koslib/inet_pton.c Modified: kos/include/arpa/inet.h =================================================================== --- kos/include/arpa/inet.h 2007-07-29 03:21:16 UTC (rev 429) +++ kos/include/arpa/inet.h 2007-08-03 04:19:54 UTC (rev 430) @@ -1,7 +1,7 @@ /* KallistiOS ##version## arpa/inet.h - Copyright (C)2006 Lawrence Sebald + Copyright (C) 2006, 2007 Lawrence Sebald */ @@ -9,10 +9,13 @@ #define __ARPA_INET_H #include <sys/cdefs.h> -#include <netinet/in.h> __BEGIN_DECLS +#include <sys/types.h> +#include <netinet/in.h> +#include <sys/socket.h> + uint32 htonl(uint32 value); uint32 ntohl(uint32 value); @@ -20,7 +23,14 @@ uint16 ntohs(uint16 value); in_addr_t inet_addr(const char *cp); +int inet_aton(const char *cp, struct in_addr *pin); +int inet_pton(int af, const char *src, void *dst); +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); + +/* Non-reentrant */ +char *inet_ntoa(struct in_addr addr); + __END_DECLS #endif /* __ARPA_INET_H */ Modified: kos/include/netinet/in.h =================================================================== --- kos/include/netinet/in.h 2007-07-29 03:21:16 UTC (rev 429) +++ kos/include/netinet/in.h 2007-08-03 04:19:54 UTC (rev 430) @@ -1,7 +1,7 @@ /* KallistiOS ##version## netinet/in.h - Copyright (C)2006 Lawrence Sebald + Copyright (C) 2006, 2007 Lawrence Sebald */ @@ -13,8 +13,15 @@ __BEGIN_DECLS +#ifndef __IN_PORT_T_DEFINED +#define __IN_PORT_T_DEFINED typedef uint16 in_port_t; +#endif + +#ifndef __IN_ADDR_T_DEFINED +#define __IN_ADDR_T_DEFINED typedef uint32 in_addr_t; +#endif #ifndef __SA_FAMILY_T_DEFINED #define __SA_FAMILY_T_DEFINED @@ -34,10 +41,13 @@ #define INADDR_ANY 0x00000000 #define INADDR_BROADCAST 0xFFFFFFFF +#define INADDR_NONE 0xFFFFFFFF /* IP Protocols */ -#define IPPROTO_IP 0 -#define IPPROTO_UDP 17 +#define IPPROTO_IP 0 +#define IPPROTO_ICMP 1 +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 __END_DECLS Modified: kos/kernel/libc/koslib/Makefile =================================================================== --- kos/kernel/libc/koslib/Makefile 2007-07-29 03:21:16 UTC (rev 429) +++ kos/kernel/libc/koslib/Makefile 2007-08-03 04:19:54 UTC (rev 430) @@ -11,6 +11,7 @@ assert.o dbglog.o malloc.o crtbegin.o crtend.o atexit.o \ opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \ telldir.o usleep.o inet_addr.o realpath.o getcwd.o chdir.o mkdir.o \ - creat.o sleep.o rmdir.o rename.o + creat.o sleep.o rmdir.o rename.o inet_pton.o inet_ntop.o \ + inet_ntoa.o inet_aton.o include $(KOS_BASE)/Makefile.prefab Modified: kos/kernel/libc/koslib/inet_addr.c =================================================================== --- kos/kernel/libc/koslib/inet_addr.c 2007-07-29 03:21:16 UTC (rev 429) +++ kos/kernel/libc/koslib/inet_addr.c 2007-08-03 04:19:54 UTC (rev 430) @@ -1,49 +1,19 @@ /* KallistiOS ##version## inet_addr.c - Copyright (C)2006 Lawrence Sebald + Copyright (C) 2006, 2007 Lawrence Sebald */ #include <arpa/inet.h> -#include <stdlib.h> in_addr_t inet_addr(const char *cp) { - in_addr_t result = 0; - long tmp; - char *ptr; + struct in_addr addr; - tmp = strtoul(cp, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; + /* inet_aton() returns 0 on failure, 1 on success */ + if(inet_aton(cp, &addr)) { + return addr.s_addr; } - else { - result = tmp << 24; - } - tmp = strtoul(ptr + 1, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; - } - else { - result |= tmp << 16; - } - - tmp = strtoul(ptr + 1, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; - } - else { - result |= tmp << 8; - } - - tmp = strtoul(ptr + 1, &ptr, 10); - if(tmp > 0xFF || cp == ptr) { - return (in_addr_t) -1; - } - else { - result |= tmp; - } - - return (in_addr_t) htonl(result); + return INADDR_NONE; } Added: kos/kernel/libc/koslib/inet_aton.c =================================================================== --- kos/kernel/libc/koslib/inet_aton.c (rev 0) +++ kos/kernel/libc/koslib/inet_aton.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,118 @@ +/* KallistiOS ##version## + + inet_aton.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> + +int inet_aton(const char *cp, struct in_addr *pin) { + int parts[4] = { 0 }; + int count = 0; + int base = 0; + char tmp; + + for(; *cp && count < 4; ++cp) { + if(*cp == '.') { + ++count; + base = 0; + } + else if(base == 0) { + /* Determine which base this part is in */ + if(*cp == '0') { + tmp = *++cp; + + if(tmp == '.') { + base = 0; + parts[count++] = 0; + } + else if(tmp == '\0') { + base = 0; + parts[count] = 0; + --cp; + } + else if(tmp != 'x' && tmp != 'X') { + /* Octal, handle the character just read too. */ + base = 8; + parts[count] = *cp - '0'; + } + else { + /* Hexadecimal */ + base = 16; + } + } + else if(*cp > '0' && *cp <= '9') { + /* Decimal, handle the digit */ + base = 10; + parts[count] = *cp - '0'; + } + else { + /* Non-number starting character... bail out. */ + return 0; + } + } + else if(base == 10 && *cp >= '0' && *cp <= '9') { + parts[count] *= 10; + parts[count] += *cp - '0'; + } + else if(base == 8 && *cp >= '0' && *cp <= '7') { + parts[count] <<= 3; + parts[count] += *cp - '0'; + } + else if(base == 16) { + parts[count] <<= 4; + + if(*cp >= '0' && *cp <= '9') { + parts[count] += *cp - '0'; + } + else if(*cp >= 'A' && *cp <= 'F') { + parts[count] += *cp - 'A' + 10; + } + else if(*cp >= 'a' && *cp <= 'f') { + parts[count] += *cp - 'a' + 10; + } + else { + /* Invalid hex digit */ + return 0; + } + } + else { + /* Invalid digit, and not a dot... bail */ + return 0; + } + } + + if(count == 4) { + /* Too many dots, bail out */ + return 0; + } + + /* Validate each part */ + if(count == 0) { + /* Easiest case, store our computed part, and it's done */ + pin->s_addr = htonl(parts[0]); + } + else if(count == 1) { + if(parts[0] > 0xFF || parts[1] > 0xFFFFFF) + return 0; + + pin->s_addr = htonl(parts[0] << 24 | parts[1]); + } + else if(count == 2) { + if(parts[0] > 0xFF || parts[1] > 0xFF || parts[2] > 0xFFFF) + return 0; + + pin->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | parts[2]); + } + else { + if(parts[0] > 0xFF || parts[1] > 0xFF || + parts[2] > 0xFF || parts[3] > 0xFF) + return 0; + + pin->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | + parts[2] << 8 | parts[3]); + } + + return 1; +} Added: kos/kernel/libc/koslib/inet_ntoa.c =================================================================== --- kos/kernel/libc/koslib/inet_ntoa.c (rev 0) +++ kos/kernel/libc/koslib/inet_ntoa.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,45 @@ +/* KallistiOS ##version## + + inet_ntoa.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> + +char *inet_ntoa(struct in_addr addr) { + static char str[16]; /* XXX.XXX.XXX.XXX = 15 chars + 1 for NUL */ + char tmp[3]; + int i, part; + char *ch = tmp; + char *ch2 = str; + + /* Parse each 8 bits individually. */ + for(i = 0; i < 4; ++i) { + /* Treat the 32-bit address value as if it were an array of 8-bit + values. This works, regardless of the endianness of the host system + because the specs require the address passed in here to be in + network byte order (big endian). */ + part = ((uint8 *) &addr.s_addr)[i]; + + do { + *ch++ = '0' + (char)(part % 10); + part /= 10; + } while(part); + + /* tmp now contains the inverse of the number that is in the given + 8 bits. Reverse it for the final result, rewinding ch to the + beginning of tmp in the process. */ + while(ch != tmp) { + *ch2++ = *--ch; + } + + *ch2++ = '.'; + } + + /* There's a trailing '.' at the end of the address, change it to the + required NUL character */ + *--ch2 = 0; + + return str; +} Added: kos/kernel/libc/koslib/inet_ntop.c =================================================================== --- kos/kernel/libc/koslib/inet_ntop.c (rev 0) +++ kos/kernel/libc/koslib/inet_ntop.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,58 @@ +/* KallistiOS ##version## + + inet_ntop.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> +#include <errno.h> + +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { + char tmp[3]; + int i, part; + char *ch = tmp; + char *ch2 = dst; + struct in_addr *addr = (struct in_addr *)src; + + if(af != AF_INET) { + errno = EAFNOSUPPORT; + return NULL; + } + + /* Parse each 8 bits individually. */ + for(i = 0; i < 4; ++i) { + /* Treat the 32-bit address value as if it were an array of 8-bit + values. This works, regardless of the endianness of the host system + because the specs require the address passed in here to be in + network byte order (big endian). */ + part = ((uint8 *) &addr->s_addr)[i]; + + do { + *ch++ = '0' + (char)(part % 10); + part /= 10; + } while(part); + + /* tmp now contains the inverse of the number that is in the given + 8 bits. Reverse it for the final result, rewinding ch to the + beginning of tmp in the process. */ + while(ch != tmp && size) { + *ch2++ = *--ch; + --size; + } + + if(!size) { + errno = ENOSPC; + return NULL; + } + + *ch2++ = '.'; + --size; + } + + /* There's a trailing '.' at the end of the address, change it to the + required NUL character */ + *--ch2 = 0; + + return dst; +} Added: kos/kernel/libc/koslib/inet_pton.c =================================================================== --- kos/kernel/libc/koslib/inet_pton.c (rev 0) +++ kos/kernel/libc/koslib/inet_pton.c 2007-08-03 04:19:54 UTC (rev 430) @@ -0,0 +1,51 @@ +/* KallistiOS ##version## + + inet_pton.c + Copyright (C) 2007 Lawrence Sebald + +*/ + +#include <arpa/inet.h> +#include <errno.h> + +int inet_pton(int af, const char *src, void *dst) { + int parts[4] = { 0 }; + int count = 0; + struct in_addr *addr = (struct in_addr *)dst; + + if(af != AF_INET) { + errno = EAFNOSUPPORT; + return -1; + } + + for(; *src && count < 4; ++src) { + if(*src == '.') { + ++count; + } + /* Unlike inet_aton(), inet_pton() only supports decimal parts */ + else if(*src >= '0' && *src <= '9') { + parts[count] *= 10; + parts[count] += *src - '0'; + } + else { + /* Invalid digit, and not a dot... bail */ + return 0; + } + } + + if(count != 3) { + /* Not the right number of parts, bail */ + return 0; + } + + /* Validate each part, note that unlike inet_aton(), inet_pton() only + supports the standard xxx.xxx.xxx.xxx addresses. */ + if(parts[0] > 0xFF || parts[1] > 0xFF || + parts[2] > 0xFF || parts[3] > 0xFF) + return 0; + + addr->s_addr = htonl(parts[0] << 24 | parts[1] << 16 | + parts[2] << 8 | parts[3]); + + return 1; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2007-12-12 01:12:29
|
Revision: 551 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=551&view=rev Author: ljsebald Date: 2007-12-11 17:12:25 -0800 (Tue, 11 Dec 2007) Log Message: ----------- Committing C-style comments patch from quzar. Modified Paths: -------------- kos/include/kos/dbgio.h kos/kernel/arch/dreamcast/hardware/flashrom.c kos/kernel/arch/dreamcast/hardware/scif.c kos/kernel/arch/dreamcast/hardware/video.c kos/kernel/arch/dreamcast/include/dc/flashrom.h kos/kernel/arch/dreamcast/include/dc/fmath.h Modified: kos/include/kos/dbgio.h =================================================================== --- kos/include/kos/dbgio.h 2007-11-24 05:20:47 UTC (rev 550) +++ kos/include/kos/dbgio.h 2007-12-12 01:12:25 UTC (rev 551) @@ -15,110 +15,110 @@ #include <arch/types.h> -/// This struct represents a single dbgio interface. This should represent -/// a generic pollable console interface. We will store an ordered list of -/// these statically linked into the program and fall back from one to the -/// next until one returns true for detected(). Note that the last device in -/// this chain is the null console, which will always return true. +/* This struct represents a single dbgio interface. This should represent + a generic pollable console interface. We will store an ordered list of + these statically linked into the program and fall back from one to the + next until one returns true for detected(). Note that the last device in + this chain is the null console, which will always return true. */ typedef struct dbgio_handler { - /// Name of the dbgio handler + /* Name of the dbgio handler */ const char * name; - /// Returns 1 if the device is available and usable, or 0 if it - /// appears not to be. + /* Returns 1 if the device is available and usable, or 0 if it + appears not to be. */ int (*detected)(); - /// Init the interface with default parameters. + /* Init the interface with default parameters. */ int (*init)(); - /// Shut down the interface + /* Shut down the interface */ int (*shutdown)(); - /// Set polled/IRQ usage + /* Set polled/IRQ usage */ int (*set_irq_usage)(int mode); - /// Read one char from the console or -1 if there's nothing to read, - /// or an error condition exists (check errno). + /* Read one char from the console or -1 if there's nothing to read, + or an error condition exists (check errno). */ int (*read)(); - /// Write one char to the console (may need to call flush()). - /// Returns the number of chars written or -1 on error. + /* Write one char to the console (may need to call flush()). + Returns the number of chars written or -1 on error. */ int (*write)(int c); - /// Flush any queued written bytes. Returns -1 on error. + /* Flush any queued written bytes. Returns -1 on error. */ int (*flush)(); - /// Send an entire buffer. Returns the number of chars written or - /// -1 on error. If xlat is non-zero, then newline transformations - /// may occur. + /* Send an entire buffer. Returns the number of chars written or + -1 on error. If xlat is non-zero, then newline transformations + may occur. */ int (*write_buffer)(const uint8 *data, int len, int xlat); - /// Read a buffer (block). Returns the number of chars read or - /// -1 on error. + /* Read a buffer (block). Returns the number of chars read or + -1 on error. */ int (*read_buffer)(uint8 *data, int len); } dbgio_handler_t; -// These two should be initialized in arch. +/* These two should be initialized in arch. */ extern dbgio_handler_t * dbgio_handlers[]; extern int dbgio_handler_cnt; -// This is defined by the shared code, in case there's no valid handler. +/* This is defined by the shared code, in case there's no valid handler. */ extern dbgio_handler_t dbgio_null; -/// Manually select a new dbgio interface by name. Returns 0 on success or -/// -1 on error. Note that even if the given device isn't detected, this -/// will still let you select it. +/* Manually select a new dbgio interface by name. Returns 0 on success or + -1 on error. Note that even if the given device isn't detected, this + will still let you select it. */ int dbgio_dev_select(const char * name); -/// Returns the name of the currently selected device. +/* Returns the name of the currently selected device. */ const char * dbgio_dev_get(); -/// Initialize the dbgio console. The device selection process is as -/// described above. +/* Initialize the dbgio console. The device selection process is as + described above. */ int dbgio_init(); -/// Set IRQ usage - we default to polled +/* Set IRQ usage - we default to polled */ int dbgio_set_irq_usage(int mode); #define DBGIO_MODE_POLLED 0 #define DBGIO_MODE_IRQ 1 -/// Read one char from the console or -1 if there's nothing to read, -/// or an error condition exists (check errno). +/* Read one char from the console or -1 if there's nothing to read, + or an error condition exists (check errno). */ int dbgio_read(); -/// Write one char to the console (may need to call flush()). -/// Returns the number of chars written or -1 on error. +/* Write one char to the console (may need to call flush()). + Returns the number of chars written or -1 on error. */ int dbgio_write(int c); -/// Flush any queued written bytes. Returns -1 on error. +/* Flush any queued written bytes. Returns -1 on error. */ int dbgio_flush(); -/// Send an entire buffer. Returns the number of chars written or -/// -1 on error. +/* Send an entire buffer. Returns the number of chars written or + -1 on error. */ int dbgio_write_buffer(const uint8 *data, int len); -/// Read a buffer (block). Returns the number of chars read or -/// -1 on error. +/* Read a buffer (block). Returns the number of chars read or + -1 on error. */ int dbgio_read_buffer(uint8 *data, int len); -/// Send an entire buffer. Returns the number of chars written or -/// -1 on error. Newline translations may occur. +/* Send an entire buffer. Returns the number of chars written or + -1 on error. Newline translations may occur. */ int dbgio_write_buffer_xlat(const uint8 *data, int len); -/// Send a string (null-terminated). Returns the number of chars -/// written or -1 on error. +/* Send a string (null-terminated). Returns the number of chars + written or -1 on error. */ int dbgio_write_str(const char *str); -/// Disable debug I/O globally +/* Disable debug I/O globally */ void dbgio_disable(); -/// Enable debug I/O globally +/* Enable debug I/O globally */ void dbgio_enable(); -/// Printf functionality +/* Printf functionality */ int dbgio_printf(const char *fmt, ...) __printflike(1, 2); __END_DECLS -#endif // __KOS_DBGIO_H +#endif /* __KOS_DBGIO_H */ Modified: kos/kernel/arch/dreamcast/hardware/flashrom.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/flashrom.c 2007-11-24 05:20:47 UTC (rev 550) +++ kos/kernel/arch/dreamcast/hardware/flashrom.c 2007-12-12 01:12:25 UTC (rev 551) @@ -158,7 +158,7 @@ that's easiest to deal with. Block 0 is the magic block, so we won't check that. */ for (i=0; i<bmcnt*8; i++) { - // Little shortcut + /* Little shortcut */ if (bitmap[i / 8] == 0) i += 8; @@ -273,58 +273,58 @@ typedef struct { union { struct { - // Block 0xE0 - uint16 blockid; // Should be 0xE0 - uint8 prodname[4]; // SEGA - uint8 unk1; // 0x13 - uint8 method; - uint8 unk2[2]; // 0x00 0x00 - uint8 ip[4]; // These are all in big-endian notation + /* Block 0xE0 */ + uint16 blockid; /* Should be 0xE0 */ + uint8 prodname[4]; /* SEGA */ + uint8 unk1; /* 0x13 */ + uint8 method; + uint8 unk2[2]; /* 0x00 0x00 */ + uint8 ip[4]; /* These are all in big-endian notation */ uint8 nm[4]; uint8 bc[4]; uint8 dns1[4]; uint8 dns2[4]; uint8 gw[4]; - uint8 unk3[4]; // All zeros - char hostname[24]; // Host name + uint8 unk3[4]; /* All zeros */ + char hostname[24]; /* Host name */ uint16 crc; } e0; struct { - // Block E2 - uint16 blockid; // Should be 0xE2 + /* Block E2 */ + uint16 blockid; /* Should be 0xE2 */ uint8 unk[12]; char email[48]; uint16 crc; } e2; struct { - // Block E4 - uint16 blockid; // Should be 0xE4 + /* Block E4 */ + uint16 blockid; /* Should be 0xE4 */ uint8 unk[32]; char smtp[28]; uint16 crc; } e4; struct { - // Block E5 - uint16 blockid; // Should be 0xE5 + /* Block E5 */ + uint16 blockid; /* Should be 0xE5 */ uint8 unk[36]; char pop3[24]; uint16 crc; } e5; struct { - // Block E6 - uint16 blockid; // Should be 0xE6 + /* Block E6 */ + uint16 blockid; /* Should be 0xE6 */ uint8 unk[40]; char pop3_login[20]; uint16 crc; } e6; struct { - // Block E7 - uint16 blockid; // Should be 0xE7 + /* Block E7 */ + uint16 blockid; /* Should be 0xE7 */ uint8 unk[12]; char pop3_passwd[32]; char proxy_host[16]; @@ -332,8 +332,8 @@ } e7; struct { - // Block E8 - uint16 blockid; // Should be 0xE8 + /* Block E8 */ + uint16 blockid; /* Should be 0xE8 */ uint8 unk1[48]; uint16 proxy_port; uint16 unk2; @@ -342,8 +342,8 @@ } e8; struct { - // Block E9 - uint16 blockid; // Should be 0xE9 + /* Block E9 */ + uint16 blockid; /* Should be 0xE9 */ uint8 unk[40]; char ppp_passwd[20]; uint16 crc; @@ -356,12 +356,12 @@ isp_settings_t * isp = (isp_settings_t *)buffer; int found = 0; - // Clean out the output config buffer. + /* Clean out the output config buffer. */ memset(out, 0, sizeof(flashrom_ispcfg_t)); - // Get the E0 config block + /* Get the E0 config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_IP_SETTINGS, buffer) >= 0) { - // Fill in values from it + /* Fill in values from it */ out->method = isp->e0.method; memcpy(out->ip, isp->e0.ip, 4); memcpy(out->nm, isp->e0.nm, 4); @@ -375,45 +375,45 @@ found++; } - // Get the email config block + /* Get the email config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_EMAIL, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ memcpy(out->email, isp->e2.email, 48); out->email_valid = 1; found++; } - // Get the smtp config block + /* Get the smtp config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_SMTP, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ memcpy(out->smtp, isp->e4.smtp, 28); out->smtp_valid = 1; found++; } - // Get the pop3 config block + /* Get the pop3 config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_POP3, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ memcpy(out->pop3, isp->e5.pop3, 24); out->pop3_valid = 1; found++; } - // Get the pop3 login config block + /* Get the pop3 login config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_POP3LOGIN, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ memcpy(out->pop3_login, isp->e6.pop3_login, 20); out->pop3_login_valid = 1; found++; } - // Get the pop3 passwd config block + /* Get the pop3 passwd config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_POP3PASSWD, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ memcpy(out->pop3_passwd, isp->e7.pop3_passwd, 32); memcpy(out->proxy_host, isp->e7.proxy_host, 16); @@ -421,9 +421,9 @@ found++; } - // Get the PPP login config block + /* Get the PPP login config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_PPPLOGIN, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ out->proxy_port = isp->e8.proxy_port; memcpy(out->ppp_login, isp->e8.ppp_login, 8); @@ -431,9 +431,9 @@ found++; } - // Get the PPP passwd config block + /* Get the PPP passwd config block */ if (flashrom_get_block(FLASHROM_PT_BLOCK_1, FLASHROM_B1_PPPPASSWD, buffer) >= 0) { - // Fill in the values from it + /* Fill in the values from it */ memcpy(out->ppp_passwd, isp->e9.ppp_passwd, 20); out->ppp_passwd_valid = 1; Modified: kos/kernel/arch/dreamcast/hardware/scif.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/scif.c 2007-11-24 05:20:47 UTC (rev 550) +++ kos/kernel/arch/dreamcast/hardware/scif.c 2007-12-12 01:12:25 UTC (rev 551) @@ -42,7 +42,7 @@ static int serial_baud = DEFAULT_SERIAL_BAUD, serial_fifo = DEFAULT_SERIAL_FIFO; -// This will get set to zero if we fail to send. +/* This will get set to zero if we fail to send. */ static int serial_enabled = 1; /* Set serial parameters; this is not platform independent like I want @@ -52,7 +52,7 @@ serial_fifo = fifo; } -// Receive ring buffer +/* Receive ring buffer */ #define BUFSIZE 1024 static uint8 recvbuf[BUFSIZE]; static int rb_head = 0, rb_tail = 0, rb_cnt = 0; @@ -67,11 +67,11 @@ rb_head = (rb_head + 1) % BUFSIZE; rb_cnt++; - // If we're within 32 bytes of being out of space, pause for - // the moment. + /* If we're within 32 bytes of being out of space, pause for + the moment. */ if (!rb_paused && (BUFSIZE - rb_cnt) < 32) { rb_paused = 1; - SCSPTR2 = 0x20; // Set CTS=0 + SCSPTR2 = 0x20; /* Set CTS=0 */ } } @@ -81,7 +81,7 @@ rb_tail = (rb_tail + 1) % BUFSIZE; rb_cnt--; - // If we're paused and clear again, re-enabled receiving. + /* If we're paused and clear again, re-enabled receiving. */ if (rb_paused && (BUFSIZE - rb_cnt) >= 64) { rb_paused = 0; SCSPTR2 = 0x00; @@ -104,14 +104,14 @@ out if possible. If our internal ring buffer comes close to overflowing, the best we can do is twiddle RTS/CTS for a while. */ static void scif_err_irq(irq_t src, irq_context_t * cxt) { - // Clear status bits + /* Clear status bits */ SCSCR2 &= ~0x08; SCSCR2 |= 0x08; printf("scif_err_irq called\n"); - // Did we get an error condition? - if (SCFSR2 & 0x9c) { // Check ER, BRK, FER, PER + /* Did we get an error condition? */ + if (SCFSR2 & 0x9c) { /* Check ER, BRK, FER, PER */ printf("SCFSR2 status was %04x\n", SCFSR2); /* Try to clear it */ SCFCR2 = 0x06; @@ -128,29 +128,26 @@ } static void scif_data_irq(irq_t src, irq_context_t * cxt) { - // Clear status bits + /* Clear status bits */ SCSCR2 &= ~0x40; SCSCR2 |= 0x40; - //printf("scif_data_irq called\n"); - - // Check for received data available. + /* Check for received data available. */ if (SCFSR2 & 3) { while (SCFDR2 & 0x1f) { int c = SCFRDR2; - //printf("received char '%d'\n", c); rb_push_char(c); } SCFSR2 &= ~3; } } -// Are we using IRQs? +/* Are we using IRQs? */ static int scif_irq_usage = 0; int scif_set_irq_usage(int on) { scif_irq_usage = on; - // Clear out the buffer in any case + /* Clear out the buffer in any case */ rb_reset(); if (scif_irq_usage) { @@ -176,26 +173,26 @@ return 0; } -// We are always detected, though we might end up realizing there's no -// cable connected later... +/* We are always detected, though we might end up realizing there's no + cable connected later... */ int scif_detected() { return 1; } -// We use this for the dbgio interface because we always init SCIF. +/* We use this for the dbgio interface because we always init SCIF. */ int scif_init_fake() { return 0; } /* Initialize the SCIF port; baud_rate must be at least 9600 and no more than 57600. 115200 does NOT work for most PCs. */ -// recv trigger to 1 byte +/* recv trigger to 1 byte */ int scif_init() { int i; /* int fifo = 1; */ - // If dcload-serial is active, then do nothing here, or we'll - // screw that up. + /* If dcload-serial is active, then do nothing here, or we'll + screw that up. */ if (dcload_type == DCLOAD_TYPE_SER) return 0; @@ -209,7 +206,7 @@ SCSMR2 = 0; /* If baudrate unset, set baudrate, N = P0/(32*B)-1 */ - // B = P0/32*(N+1) + /* B = P0/32*(N+1) */ if (SCBRR2 == 0xff) SCBRR2 = (50000000 / (32 * serial_baud)) - 1; @@ -252,7 +249,7 @@ } if (scif_irq_usage) { - // Do we have anything ready? + /* Do we have anything ready? */ if (rb_space_used() <= 0) { errno = EAGAIN; return -1; @@ -266,10 +263,10 @@ return -1; } - // Get the input char + /* Get the input char */ c = SCFRDR2; - // Ack + /* Ack */ SCFSR2 &= ~0x92; return c; @@ -366,7 +363,7 @@ return i; } -// Tie all of that together into a dbgio package. +/* Tie all of that together into a dbgio package. */ dbgio_handler_t dbgio_scif = { "scif", scif_detected, Modified: kos/kernel/arch/dreamcast/hardware/video.c =================================================================== --- kos/kernel/arch/dreamcast/hardware/video.c 2007-11-24 05:20:47 UTC (rev 550) +++ kos/kernel/arch/dreamcast/hardware/video.c 2007-12-12 01:12:25 UTC (rev 551) @@ -11,20 +11,20 @@ #include <string.h> #include <stdio.h> -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ CVSID("$Id: video.c,v 1.11.2.2 2003/08/02 01:52:31 bardtx Exp $"); -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ -//----------------------------------------------------------------------------- -// This table is indexed w/ DM_* +/*-----------------------------------------------------------------------------*/ + /* This table is indexed w/ DM_* */ vid_mode_t vid_builtin[DM_MODE_COUNT] = { - // NULL mode.. - // DM_INVALID = 0 + /* NULL mode.. */ + /* DM_INVALID = 0 */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, { 0, 0, 0, 0 } }, - // 320x240 VGA 60Hz - // DM_320x240_VGA + /* 320x240 VGA 60Hz */ + /* DM_320x240_VGA */ { DM_320x240, 320, 240, @@ -40,8 +40,8 @@ { 0, 0, 0, 0 } }, - // 320x240 NTSC 60Hz - // DM_320x240_NTSC + /* 320x240 NTSC 60Hz */ + /* DM_320x240_NTSC */ { DM_320x240, 320, 240, @@ -57,8 +57,8 @@ { 0, 0, 0, 0 } }, - // 640x480 VGA 60Hz - // DM_640x480_VGA + /* 640x480 VGA 60Hz */ + /* DM_640x480_VGA */ { DM_640x480, 640, 480, @@ -74,8 +74,8 @@ { 0, 0, 0, 0 } }, - // 640x480 NTSC 60Hz IL - // DM_640x480_NTSC_IL + /* 640x480 NTSC 60Hz IL */ + /* DM_640x480_NTSC_IL */ { DM_640x480, 640, 480, @@ -91,13 +91,13 @@ { 0, 0, 0, 0 } }, - // 800x608 NTSC 60Hz (VGA) [BROKEN!] - // DM_800x608_VGA + /* 800x608 NTSC 60Hz (VGA) [BROKEN!] */ + /* DM_800x608_VGA */ { DM_800x608, 320, 240, VID_INTERLACE, - 1/*CT_ANY*/, // This will block the mode from being set. + 1/*CT_ANY*/, /* This will block the mode from being set. */ 0, 262, 857, 164, 24, @@ -108,8 +108,8 @@ { 0, 0, 0, 0 } }, - // 640x480 PAL 50Hz IL - // DM_640x480_PAL_IL + /* 640x480 PAL 50Hz IL */ + /* DM_640x480_PAL_IL */ { DM_640x480, 640, 480, @@ -125,8 +125,8 @@ { 0, 0, 0, 0 } }, - // 256x256 PAL 50Hz IL (seems to output the same w/o VID_PAL, ie. in NTSC IL mode) - // DM_256x256_PAL_IL + /* 256x256 PAL 50Hz IL (seems to output the same w/o VID_PAL, ie. in NTSC IL mode) */ + /* DM_256x256_PAL_IL */ { DM_256x256, 256, 256, @@ -142,8 +142,8 @@ { 0, 0, 0, 0 } }, - // 768x480 NTSC 60Hz IL (thanks DCGrendel) - // DM_768x480_NTSC_IL + /* 768x480 NTSC 60Hz IL (thanks DCGrendel) */ + /* DM_768x480_NTSC_IL */ { DM_768x480, 768, 480, @@ -159,8 +159,8 @@ { 0, 0, 0, 0 } }, - // 768x576 PAL 50Hz IL (DCG) - // DM_768x576_PAL_IL + /* 768x576 PAL 50Hz IL (DCG) */ + /* DM_768x576_PAL_IL */ { DM_768x576, 768, 576, @@ -176,8 +176,8 @@ { 0, 0, 0, 0 } }, - // 768x480 PAL 50Hz IL - // DM_768x480_PAL_IL + /* 768x480 PAL 50Hz IL */ + /* DM_768x480_PAL_IL */ { DM_768x480, 768, 480, @@ -193,8 +193,8 @@ { 0, 0, 0, 0 } }, - // 320x240 PAL 50Hz (thanks Marco Martins aka Mekanaizer) - // DM_320x240_PAL + /* 320x240 PAL 50Hz (thanks Marco Martins aka Mekanaizer) */ + /* DM_320x240_PAL */ { DM_320x240, 320, 240, @@ -210,21 +210,21 @@ { 0, 0, 0, 0 } }, - // END - // DM_SENTINEL + /* END */ + /* DM_SENTINEL */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, { 0, 0, 0, 0 } } - // DM_MODE_COUNT + /* DM_MODE_COUNT */ }; -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ volatile uint32 *regs = (uint32*)0xA05F8000; vid_mode_t currmode = { 0 }; vid_mode_t *vid_mode = 0; uint16 *vram_s; uint32 *vram_l; -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ /* Checks the attached cable type (to the A/V port). Returns one of the following: 0 == VGA @@ -242,34 +242,34 @@ *porta = (*porta & 0xfff0ffff) | 0x000a0000; - // Read port8 and port9 + /* Read port8 and port9 */ return (*((uint16*)(porta + 1)) >> 8) & 3; } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_set_mode(int dm, int pm) { vid_mode_t mode; int i, ct, found; ct = vid_check_cable(); - // Check to see if we should use a direct mode index, a generic - // mode check, or if it's just invalid. + /* Check to see if we should use a direct mode index, a generic + mode check, or if it's just invalid. */ if (dm > DM_INVALID && dm < DM_SENTINEL) { memcpy(&mode, &vid_builtin[dm], sizeof(vid_mode_t)); } else if (dm >= DM_GENERIC_FIRST && dm <= DM_GENERIC_LAST) { found = 0; for (i=1; i<DM_SENTINEL; i++) { - // Is it the right generic mode? + /* Is it the right generic mode? */ if (vid_builtin[i].generic != dm) continue; - // Do we have the right cable type? + /* Do we have the right cable type? */ if (vid_builtin[i].cable_type != CT_ANY && vid_builtin[i].cable_type != ct) continue; - // Ok, nothing else to check right now -- we've got our mode + /* Ok, nothing else to check right now -- we've got our mode */ memcpy(&mode, &vid_builtin[i], sizeof(vid_mode_t)); found = 1; break; @@ -283,40 +283,40 @@ return; } - // We set this here so actual mode is bit-depth independent.. + /* We set this here so actual mode is bit-depth independent.. */ mode.pm = pm; - // This is also to be generic + /* This is also to be generic */ mode.cable_type = ct; - // This will make a private copy of our "mode" + /* This will make a private copy of our "mode" */ vid_set_mode_ex(&mode); } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_set_mode_ex(vid_mode_t *mode) { static uint8 bpp[4] = { 2, 2, 0, 4 }; uint16 ct; uint32 data; - // Verify cable type for video mode. + /* Verify cable type for video mode. */ ct = vid_check_cable(); if (mode->cable_type != CT_ANY) { if (mode->cable_type != ct) { - // Maybe this should have the ability to be forced (thru param) - // so you can set a mode with VGA params with RGB cable type? - //ct=mode->cable_type; + /* Maybe this should have the ability to be forced (thru param) + so you can set a mode with VGA params with RGB cable type? */ + /*ct=mode->cable_type; */ dbglog(DBG_ERROR, "vid_set_mode: Mode not allowed for this cable type (%i!=%i)\n", mode->cable_type, ct); return; } } - // Blank screen and reset display enable (looks nicer) - regs[0x3A] |= 8; // Blank - regs[0x11] &= ~1; // Display disable + /* Blank screen and reset display enable (looks nicer) */ + regs[0x3A] |= 8; /* Blank */ + regs[0x11] &= ~1; /* Display disable */ - // Clear interlace flag if VGA (this maybe should be in here?) + /* Clear interlace flag if VGA (this maybe should be in here?) */ if (ct == CT_VGA) { mode->flags &= ~VID_INTERLACE; if (mode->flags & VID_LINEDOUBLE) @@ -329,7 +329,7 @@ vid_border_color(0, 0, 0); - // Pixelformat + /* Pixelformat */ data = (mode->pm << 2); if (ct == CT_VGA) { data |= 1 << 23; @@ -338,10 +338,10 @@ } regs[0x11] = data; - // Linestride + /* Linestride */ regs[0x13] = (mode->width * bpp[mode->pm]) / 8; - // Display size + /* Display size */ data = ((mode->width * bpp[mode->pm]) / 4) - 1; if (ct == CT_VGA || (!(mode->flags & VID_INTERLACE))) { data |= (1 << 20) | ((mode->height - 1) << 10); @@ -351,14 +351,14 @@ } regs[0x17] = data; - // vblank irq + /* vblank irq */ if(ct == CT_VGA) { regs[0x33] = (mode->scanint1 << 16) | (mode->scanint2 << 1); } else { regs[0x33] = (mode->scanint1 << 16) | mode->scanint2; } - // Interlace stuff + /* Interlace stuff */ data = 0x100; if (mode->flags & VID_INTERLACE) { data |= 0x10; @@ -370,21 +370,21 @@ } regs[0x34] = data; - // Border window + /* Border window */ regs[0x35] = (mode->borderx1 << 16) | mode->borderx2; regs[0x37] = (mode->bordery1 << 16) | mode->bordery2; - // Scanlines and clocks. + /* Scanlines and clocks. */ regs[0x36] = (mode->scanlines << 16) | mode->clocks; - // Horizontal pixel doubling + /* Horizontal pixel doubling */ if (mode->flags & VID_PIXELDOUBLE) { regs[0x3A] |= 0x100; } else { regs[0x3A] &= ~0x100; } - // Bitmap window + /* Bitmap window */ regs[0x3B] = mode->bitmapx; data = mode->bitmapy; if (mode->flags & VID_PAL) { @@ -393,43 +393,43 @@ data = (data << 16) | mode->bitmapy; regs[0x3C] = data; - // Everything is ok + /* Everything is ok */ memcpy(&currmode, mode, sizeof(vid_mode_t)); vid_mode = &currmode; vid_set_start(0); - // Set cable type + /* Set cable type */ if (mode->cable_type & 1) { *((vuint32*)0xa0702c00) |= 0x300; } else { *((vuint32*)0xa0702c00) &= ~0x300; } - // Re-enable the display + /* Re-enable the display */ regs[0x3A] &= ~8; regs[0x11] |= 1; } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_set_start(uint32 base) { static uint8 bpp[4] = { 2, 2, 0, 4 }; - // Set vram base of current framebuffer + /* Set vram base of current framebuffer */ base &= 0x007FFFFF; regs[0x14] = base; - // These are nice to have. + /* These are nice to have. */ vram_s = (uint16*)(0xA5000000|base); vram_l = (uint32*)(0xA5000000|base); - // Set odd-field if interlaced. + /* Set odd-field if interlaced. */ if (vid_mode->flags & VID_INTERLACE) { regs[0x15] = base + (currmode.width * bpp[currmode.pm]); } } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_flip(int fb) { uint16 oldfb; @@ -448,14 +448,14 @@ vid_set_start(vid_mode->fb_base[vid_mode->fb_curr]); } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_border_color(int r, int g, int b) { regs[0x0040/4] = ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF); } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ /* Clears the screen with a given color [This is the old KOS function by Dan.] @@ -484,7 +484,7 @@ } } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ /* Clears all of video memory as quickly as possible [This is the old KOS function by Dan.] @@ -495,7 +495,7 @@ sq_clr((uint32 *)0xa5000000, 8*1024*1024); } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ /* Waits for a vertical refresh to start. This is the period between when the scan beam reaches the bottom of the picture, and when it starts again at the top. @@ -512,17 +512,17 @@ ; } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_init(int disp_mode, int pixel_mode) { - // Set mode and clear vram + /* Set mode and clear vram */ vid_set_mode(disp_mode, pixel_mode); vid_clear(0, 0, 0); vid_flip(0); } -//----------------------------------------------------------------------------- +/*-----------------------------------------------------------------------------*/ void vid_shutdown() { - // Play nice with loaders, like KOS used to do. + /* Play nice with loaders, like KOS used to do. */ vid_init(DM_640x480, PM_RGB565); } Modified: kos/kernel/arch/dreamcast/include/dc/flashrom.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/flashrom.h 2007-11-24 05:20:47 UTC (rev 550) +++ kos/kernel/arch/dreamcast/include/dc/flashrom.h 2007-12-12 01:12:25 UTC (rev 551) @@ -28,23 +28,23 @@ /** An enumeration of partitions available in the flashrom. */ -#define FLASHROM_PT_SYSTEM 0 //< Factory settings (read-only, 8K) -#define FLASHROM_PT_RESERVED 1 //< reserved (all 0s, 8K) -#define FLASHROM_PT_BLOCK_1 2 //< Block allocated (16K) -#define FLASHROM_PT_SETTINGS 3 //< Game settings (block allocated, 32K) -#define FLASHROM_PT_BLOCK_2 4 //< Block allocated (64K) +#define FLASHROM_PT_SYSTEM 0 /*< Factory settings (read-only, 8K) */ +#define FLASHROM_PT_RESERVED 1 /*< reserved (all 0s, 8K) */ +#define FLASHROM_PT_BLOCK_1 2 /*< Block allocated (16K) */ +#define FLASHROM_PT_SETTINGS 3 /*< Game settings (block allocated, 32K) */ +#define FLASHROM_PT_BLOCK_2 4 /*< Block allocated (64K) */ /** An enumeration of logical blocks available in the flashrom. */ -#define FLASHROM_B1_SYSCFG 0x05 //< System config (BLOCK_1) -#define FLASHROM_B1_IP_SETTINGS 0xE0 //< IP settings for BBA (BLOCK_1) -#define FLASHROM_B1_EMAIL 0xE2 //< Email address (BLOCK_1) -#define FLASHROM_B1_SMTP 0xE4 //< SMTP server setting (BLOCK_1) -#define FLASHROM_B1_POP3 0xE5 //< POP3 server setting (BLOCK_1) -#define FLASHROM_B1_POP3LOGIN 0xE6 //< POP3 login setting (BLOCK_1) -#define FLASHROM_B1_POP3PASSWD 0xE7 //< POP3 password setting + proxy (BLOCK_1) -#define FLASHROM_B1_PPPLOGIN 0xE8 //< PPP username + proxy (BLOCK_1) -#define FLASHROM_B1_PPPPASSWD 0xE9 //< PPP passwd (BLOCK_1) +#define FLASHROM_B1_SYSCFG 0x05 /*< System config (BLOCK_1) */ +#define FLASHROM_B1_IP_SETTINGS 0xE0 /*< IP settings for BBA (BLOCK_1) */ +#define FLASHROM_B1_EMAIL 0xE2 /*< Email address (BLOCK_1) */ +#define FLASHROM_B1_SMTP 0xE4 /*< SMTP server setting (BLOCK_1) */ +#define FLASHROM_B1_POP3 0xE5 /*< POP3 server setting (BLOCK_1) */ +#define FLASHROM_B1_POP3LOGIN 0xE6 /*< POP3 login setting (BLOCK_1) */ +#define FLASHROM_B1_POP3PASSWD 0xE7 /*< POP3 password setting + proxy (BLOCK_1) */ +#define FLASHROM_B1_PPPLOGIN 0xE8 /*< PPP username + proxy (BLOCK_1) */ +#define FLASHROM_B1_PPPPASSWD 0xE9 /*< PPP passwd (BLOCK_1) */ /** Implements the FLASHROM_INFO syscall; given a partition ID, @@ -101,9 +101,9 @@ This struct will be filled by calling the flashrom_get_syscfg call below. */ typedef struct flashrom_syscfg { - int language; //< Language setting (see defines above) - int audio; //< 0 == mono, 1 == stereo - int autostart; //< 0 == off, 1 == on + int language; /*< Language setting (see defines above) */ + int audio; /*< 0 == mono, 1 == stereo */ + int autostart; /*< 0 == off, 1 == on */ } flashrom_syscfg_t; /** @@ -136,37 +136,37 @@ This struct will be filled by calling flashrom_get_isp_settings below. Thanks to Sam Steele for this info. */ typedef struct flashrom_ispcfg { - int ip_valid; //< >0 if the IP settings are valid - int method; //< DHCP, Static, dialup(?), PPPoE - uint8 ip[4]; //< Host IP address - uint8 nm[4]; //< Netmask - uint8 bc[4]; //< Broadcast address - uint8 gw[4]; //< Gateway address - uint8 dns[2][4]; //< DNS servers (2) - char hostname[24]; //< DHCP/Host name + int ip_valid; /*< >0 if the IP settings are valid */ + int method; /*< DHCP, Static, dialup(?), PPPoE */ + uint8 ip[4]; /*< Host IP address */ + uint8 nm[4]; /*< Netmask */ + uint8 bc[4]; /*< Broadcast address */ + uint8 gw[4]; /*< Gateway address */ + uint8 dns[2][4]; /*< DNS servers (2) */ + char hostname[24]; /*< DHCP/Host name */ - int email_valid; //< >0 if the email setting is valid - char email[48]; //< Email address + int email_valid; /*< >0 if the email setting is valid */ + char email[48]; /*< Email address */ - int smtp_valid; //< >0 if the smtp setting is valid - char smtp[28]; //< SMTP server + int smtp_valid; /*< >0 if the smtp setting is valid */ + char smtp[28]; /*< SMTP server */ - int pop3_valid; //< >0 if the pop3 setting is valid - char pop3[24]; //< POP3 server + int pop3_valid; /*< >0 if the pop3 setting is valid */ + char pop3[24]; /*< POP3 server */ - int pop3_login_valid; //< >0 if the login setting is valid - char pop3_login[20]; //< POP3 login + int pop3_login_valid; /*< >0 if the login setting is valid */ + char pop3_login[20]; /*< POP3 login */ - int pop3_passwd_valid; //< >0 if the passwd/proxy setting is valid - char pop3_passwd[32]; //< POP3 passwd - char proxy_host[16]; //< Proxy server hostname + int pop3_passwd_valid; /*< >0 if the passwd/proxy setting is valid */ + char pop3_passwd[32]; /*< POP3 passwd */ + char proxy_host[16]; /*< Proxy server hostname */ - int ppp_login_valid; //< >0 if the PPP login/proxy setting is valid - int proxy_port; //< Proxy server port - char ppp_login[8]; //< PPP login + int ppp_login_valid; /*< >0 if the PPP login/proxy setting is valid */ + int proxy_port; /*< Proxy server port */ + char ppp_login[8]; /*< PPP login */ - int ppp_passwd_valid; //< >0 if the PPP passwd setting is valid - char ppp_passwd[20]; //< PPP password + int ppp_passwd_valid; /*< >0 if the PPP passwd setting is valid */ + char ppp_passwd[20]; /*< PPP password */ } flashrom_ispcfg_t; /** Modified: kos/kernel/arch/dreamcast/include/dc/fmath.h =================================================================== --- kos/kernel/arch/dreamcast/include/dc/fmath.h 2007-11-24 05:20:47 UTC (rev 550) +++ kos/kernel/arch/dreamcast/include/dc/fmath.h 2007-12-12 01:12:25 UTC (rev 551) @@ -102,7 +102,7 @@ : "=f" (__value) : "f" (__arg) : "fpul", "fr0"); \ __value; }) -// Floating point inner product (dot product) +/* Floating point inner product (dot product) */ #define __fipr(x, y, z, w, a, b, c, d) ({ \ register float __x __asm__("fr0") = (x); \ register float __y __asm__("fr1") = (y); \ @@ -120,7 +120,7 @@ ); \ __w; }) -// Floating point inner product w/self (square of vector magnitude) +/* Floating point inner product w/self (square of vector magnitude) */ #define __fipr_magnitude_sqr(x, y, z, w) ({ \ register float __x __asm__("fr4") = (x); \ register float __y __asm__("fr5") = (y); \ @@ -133,13 +133,13 @@ ); \ __w; }) -// Returns v1 dot v2 (inner product) +/* Returns v1 dot v2 (inner product) */ extern inline float fipr(float x, float y, float z, float w, float a, float b, float c, float d) { return __fipr(x, y, z, w, a, b, c, d); } -// Returns v1 dot v1 (square of magnitude) +/* Returns v1 dot v1 (square of magnitude) */ extern inline float fipr_magnitude_sqr(float x, float y, float z, float w) { return __fipr_magnitude_sqr(x, y, z, w); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <at...@us...> - 2008-04-04 21:44:39
|
Revision: 564 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=564&view=rev Author: atani Date: 2008-04-04 14:44:27 -0700 (Fri, 04 Apr 2008) Log Message: ----------- Adding svn:ignore for most generated files Property Changed: ---------------- dcload/dcload-ip/example-src/ dcload/dcload-ip/host-src/tool/ dcload/dcload-ip/target-src/1st_read/ dcload/dcload-ip/target-src/dcload/ dcload/dcload-serial/example-src/ dcload/dcload-serial/host-src/misc/ dcload/dcload-serial/host-src/tool/ dcload/dcload-serial/target-src/1st_read/ dcload/dcload-serial/target-src/dcload/ kos/ kos/addons/lib/dreamcast/ kos/doc/manual/ kos/examples/dreamcast/2ndmix/ kos/kernel/arch/dreamcast/kernel/ kos/kernel/arch/dreamcast/sound/arm/ kos/kernel/exports/ kos/kernel/stubs/ kos/lib/dreamcast/ kos/utils/dc-chain/ kos/utils/gba-crcfix/ kos/utils/genromfs/ kos/utils/vqenc/ kos/utils/wav2adpcm/ kos-ports/libmp3/xingmp3/ kos-ports/liboggvorbis/liboggvorbis/libogg/build/ kos-ports/liboggvorbis/liboggvorbis/libogg/src/ kos-ports/liboggvorbis/liboggvorbis/libvorbis/build/ kos-ports/liboggvorbis/liboggvorbis/libvorbis/lib/ kos-ports/liboggvorbis/liboggvorbisplay/lib/ kos-ports/lua/lib/ Property changes on: dcload/dcload-ip/example-src ___________________________________________________________________ Name: svn:ignore + *.bin *.srec Property changes on: dcload/dcload-ip/host-src/tool ___________________________________________________________________ Name: svn:ignore + dc-tool Property changes on: dcload/dcload-ip/target-src/1st_read ___________________________________________________________________ Name: svn:ignore + *.bin *.srec Property changes on: dcload/dcload-ip/target-src/dcload ___________________________________________________________________ Name: svn:ignore + *.bin *.srec Property changes on: dcload/dcload-serial/example-src ___________________________________________________________________ Name: svn:ignore + *.bin *.srec Property changes on: dcload/dcload-serial/host-src/misc ___________________________________________________________________ Name: svn:ignore + lzo Property changes on: dcload/dcload-serial/host-src/tool ___________________________________________________________________ Name: svn:ignore + dc-tool Property changes on: dcload/dcload-serial/target-src/1st_read ___________________________________________________________________ Name: svn:ignore + *.bin *.srec Property changes on: dcload/dcload-serial/target-src/dcload ___________________________________________________________________ Name: svn:ignore + *.bin *.srec *.lzo Property changes on: kos ___________________________________________________________________ Name: svn:ignore + environ.sh Property changes on: kos/addons/lib/dreamcast ___________________________________________________________________ Name: svn:ignore + *.a Property changes on: kos/doc/manual ___________________________________________________________________ Name: svn:ignore + kos_html.zip kos_html kgl_html.zip kgl_html kos.pdf kos.aux kos.log Property changes on: kos/examples/dreamcast/2ndmix ___________________________________________________________________ Name: svn:ignore + romdisk.img Property changes on: kos/kernel/arch/dreamcast/kernel ___________________________________________________________________ Name: svn:ignore + arch_exports.c Property changes on: kos/kernel/arch/dreamcast/sound/arm ___________________________________________________________________ Name: svn:ignore + prog.elf Property changes on: kos/kernel/exports ___________________________________________________________________ Name: svn:ignore + kernel_exports.c Property changes on: kos/kernel/stubs ___________________________________________________________________ Name: svn:ignore + * Property changes on: kos/lib/dreamcast ___________________________________________________________________ Name: svn:ignore + *.a Property changes on: kos/utils/dc-chain ___________________________________________________________________ Name: svn:ignore + logs Property changes on: kos/utils/gba-crcfix ___________________________________________________________________ Name: svn:ignore + gba-crcfix Property changes on: kos/utils/genromfs ___________________________________________________________________ Name: svn:ignore + genromfs Property changes on: kos/utils/vqenc ___________________________________________________________________ Name: svn:ignore + vqenc Property changes on: kos/utils/wav2adpcm ___________________________________________________________________ Name: svn:ignore + wav2adpcm Property changes on: kos-ports/libmp3/xingmp3 ___________________________________________________________________ Name: svn:ignore + *.a Property changes on: kos-ports/liboggvorbis/liboggvorbis/libogg/build ___________________________________________________________________ Name: svn:ignore + * Property changes on: kos-ports/liboggvorbis/liboggvorbis/libogg/src ___________________________________________________________________ Name: svn:ignore + *.o *.a Property changes on: kos-ports/liboggvorbis/liboggvorbis/libvorbis/build ___________________________________________________________________ Name: svn:ignore + * Property changes on: kos-ports/liboggvorbis/liboggvorbis/libvorbis/lib ___________________________________________________________________ Name: svn:ignore + * Property changes on: kos-ports/liboggvorbis/liboggvorbisplay/lib ___________________________________________________________________ Name: svn:ignore + * Property changes on: kos-ports/lua/lib ___________________________________________________________________ Name: svn:ignore + *.a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2008-05-19 15:23:47
|
Revision: 583 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=583&view=rev Author: ljsebald Date: 2008-05-19 08:23:23 -0700 (Mon, 19 May 2008) Log Message: ----------- Adding in a new synchronization primitive: reader/writer semaphores, along with an example program for them. Modified Paths: -------------- kos/examples/dreamcast/basic/threading/Makefile kos/kernel/thread/Makefile Added Paths: ----------- kos/examples/dreamcast/basic/threading/rwsem/ kos/examples/dreamcast/basic/threading/rwsem/Makefile kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c kos/include/kos/rwsem.h kos/kernel/thread/rwsem.c Modified: kos/examples/dreamcast/basic/threading/Makefile =================================================================== --- kos/examples/dreamcast/basic/threading/Makefile 2008-05-19 14:49:36 UTC (rev 582) +++ kos/examples/dreamcast/basic/threading/Makefile 2008-05-19 15:23:23 UTC (rev 583) @@ -7,11 +7,14 @@ all: $(KOS_MAKE) -C general + $(KOS_MAKE) -C rwsem clean: $(KOS_MAKE) -C general clean + $(KOS_MAKE) -C rwsem clean dist: $(KOS_MAKE) -C general dist + $(KOS_MAKE) -C rwsem dist Added: kos/examples/dreamcast/basic/threading/rwsem/Makefile =================================================================== --- kos/examples/dreamcast/basic/threading/rwsem/Makefile (rev 0) +++ kos/examples/dreamcast/basic/threading/rwsem/Makefile 2008-05-19 15:23:23 UTC (rev 583) @@ -0,0 +1,29 @@ +# KallistiOS ##version## +# +# basic/threading/rwsem/Makefile +# Copyright (C) 2008 Lawrence Sebald +# + +all: rm-elf rwsem_test.elf + +include $(KOS_BASE)/Makefile.rules + +OBJS = rwsem_test.o + +clean: rm-elf + -rm -f $(OBJS) + +rm-elf: + -rm -f rwsem_test.elf + +rwsem_test.elf: $(OBJS) + $(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o rwsem_test.elf $(KOS_START) \ + $(OBJS) $(DATAOBJS) $(OBJEXTRA) $(KOS_LIBS) + + +run: rwsem_test.elf + $(KOS_LOADER) rwsem_test.elf + +dist: + rm -f $(OBJS) + $(KOS_STRIP) rwsem_test.elf \ No newline at end of file Added: kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c (rev 0) +++ kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2008-05-19 15:23:23 UTC (rev 583) @@ -0,0 +1,146 @@ +/* KallistiOS ##version## + + rwsem_test.c + Copyright (C) 2008 Lawrence Sebald + +*/ + +/* This program is a test of the reader/writer semaphores added in KOS 1.3.0. + Basically, what a reader/writer semaphore does is it allows unlimited readers + to occupy their critical sections, while guaranteeing exclusive access to + writers. This is a concept that I picked up from my undergraduate operating + systems class that I figured would probably be useful for KOS. */ + +#include <stdio.h> + +#include <kos/thread.h> +#include <kos/rwsem.h> + +#include <arch/arch.h> +#include <dc/maple.h> +#include <dc/maple/controller.h> + +#define UNUSED __attribute__((unused)) + +rw_semaphore_t *s = NULL; +uint32 number = 0; + +void writer0(void *param UNUSED) { + int i; + + for(i = 0; i < 20; ++i) { + if(rwsem_write_lock(s)) { + printf("Writer 0 could not obtain write lock!\n"); + return; + } + + printf("Writer 0 obtained write lock\n"); + number += 8; + rwsem_write_unlock(s); + + thd_sleep(10); + } + + printf("Writer 0 done\n"); +} + +void writer1(void *param UNUSED) { + int i; + + for(i = 0; i < 17; ++i) { + if(rwsem_write_lock(s)) { + printf("Writer 1 could not obtain write lock!\n"); + return; + } + + printf("Writer 1 obtained write lock\n"); + number *= 3; + rwsem_write_unlock(s); + + thd_sleep(5); + } + + printf("Writer 1 done\n"); +} + +void reader0(void *param UNUSED) { + int i; + + for(i = 0; i < 12; ++i) { + if(rwsem_read_lock(s)) { + printf("Reader 0 could not obtain read lock!\n"); + return; + } + + printf("Reader 0 obtained read lock\n"); + printf("Number: %lu\n", number); + rwsem_read_unlock(s); + + thd_sleep(20); + } + + printf("Reader 0 done\n"); +} + +void reader1(void *param UNUSED) { + int i; + + for(i = 0; i < 23; ++i) { + if(rwsem_read_lock(s)) { + printf("Reader 1 could not obtain read lock!\n"); + return; + } + + printf("Reader 1 obtained read lock\n"); + printf("Number * 2: %lu\n", number * 2); + rwsem_read_unlock(s); + + thd_sleep(16); + } + + printf("Reader 1 done\n"); +} + +KOS_INIT_FLAGS(INIT_DEFAULT); +int main(int argc, char *argv[]) { + kthread_t *w0, *w1, *r0, *r1; + + /* Exit if the user presse all buttons at once. */ + cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, + arch_exit); + + printf("KallistiOS Reader/Writer Semaphore test program\n"); + + /* Create the reader/writer semaphore that will be used. */ + s = rwsem_create(); + + if(!s) { + printf("Could not create RW semaphore, bailing out!\n"); + arch_exit(); + } + + printf("About to create threads\n"); + w0 = thd_create(writer0, NULL); + w1 = thd_create(writer1, NULL); + r0 = thd_create(reader0, NULL); + r1 = thd_create(reader1, NULL); + + printf("About to sleep\n"); + thd_wait(w0); + thd_wait(w1); + thd_wait(r0); + thd_wait(r1); + + if(rwsem_read_lock(s)) { + printf("Could not obtain final read lock!\n"); + arch_exit(); + } + + printf("Final number: %lu\n", number); + + rwsem_read_unlock(s); + rwsem_destroy(s); + + printf("Reader/Writer semaphore tests completed successfully!\n"); + return 0; +} Added: kos/include/kos/rwsem.h =================================================================== --- kos/include/kos/rwsem.h (rev 0) +++ kos/include/kos/rwsem.h 2008-05-19 15:23:23 UTC (rev 583) @@ -0,0 +1,86 @@ +/* KallistiOS ##version## + + include/kos/rwsem.h + Copyright (C) 2008 Lawrence Sebald + +*/ + +/* This file defines a concept that might be familiar to anyone who's ever + hacked around on the Linux kernel a bit: reader/writer semaphores. Basically, + reader/writer semaphores allow an unlimitted readers to occupy the critical + section at any given time. Since readers, by definition, do not change any + data other than their own local variables this should in theory be safe. + Writers on the other hand require exclusive access to the critical section. + Writers only may proceed into the critical section if the write lock is not + held on the semaphore and if there are no readers currently in the critical + section. Also, no reader will be allowed into the critical section if the + write lock is held. */ + +#ifndef __KOS_RWSEM_H +#define __KOS_RWSEM_H + +#include <sys/cdefs.h> +__BEGIN_DECLS + +#include <sys/queue.h> + +/* Reader/writer semaphore structure */ +typedef struct rw_semaphore { + /* List entry for the global list of reader/writer semaphores */ + LIST_ENTRY(rw_semaphore) list; + + /* How many readers currently hold the semaphore lock? */ + int read_count; + + /* Does a writer currently hold the lock? */ + int write_lock; +} rw_semaphore_t; + +LIST_HEAD(rwsemlist, rw_semaphore); + +/* Allocate a new reader/writer semaphore. Returns NULL on failure. + ENOMEM - Out of memory */ +rw_semaphore_t *rwsem_create(); + +/* Destroy a reader/writer semaphore */ +void rwsem_destroy(rw_semaphore_t *s); + +/* Lock a reader/writer semaphore for reading. Returns -1 on error. + EPERM - called inside an interrupt + EINTR - was interrupted */ +int rwsem_read_lock(rw_semaphore_t *s); + +/* Lock a reader/writer semaphore for writing. Returns -1 on error. + EPERM - called inside an interrupt + EINTR - was interrupted */ +int rwsem_write_lock(rw_semaphore_t *s); + +/* Unlock a reader/writer semaphore from a read lock. Returns -1 on error. */ +int rwsem_read_unlock(rw_semaphore_t *s); + +/* Unlock a reader/writer semaphore from a write lock. Returns -1 on error. */ +int rwsem_write_unlock(rw_semaphore_t *s); + +/* Attempt to lock a reader/writer semaphore for reading. If the call to + rwsem_read_lock() would normally block, return -1 for error. + EWOULDBLOCK - would block */ +int rwsem_read_trylock(rw_semaphore_t *s); + +/* Attempt to lock a reader/writer semaphore for writing. If the call to + rwsem_write_lock() would normally block, return -1 for error. + EWOULDBLOCK - would block */ +int rwsem_write_trylock(rw_semaphore_t *s); + +/* Return the reader/writer semaphore reader count */ +int rwsem_read_count(rw_semaphore_t *s); + +/* Return the reader/writer semaphore write lock status */ +int rwsem_write_locked(rw_semaphore_t *s); + +/* Init / shutdown */ +int rwsem_init(); +void rwsem_shutdown(); + +__END_DECLS + +#endif /* __KOS_RWSEM_H */ Modified: kos/kernel/thread/Makefile =================================================================== --- kos/kernel/thread/Makefile 2008-05-19 14:49:36 UTC (rev 582) +++ kos/kernel/thread/Makefile 2008-05-19 15:23:23 UTC (rev 583) @@ -6,7 +6,7 @@ # $Id: Makefile,v 1.4 2003/02/14 08:25:07 bardtx Exp $ OBJS = sem.o cond.o mutex.o genwait.o -OBJS += thread.o +OBJS += thread.o rwsem.o SUBDIRS = include $(KOS_BASE)/Makefile.prefab Added: kos/kernel/thread/rwsem.c =================================================================== --- kos/kernel/thread/rwsem.c (rev 0) +++ kos/kernel/thread/rwsem.c 2008-05-19 15:23:23 UTC (rev 583) @@ -0,0 +1,224 @@ +/* KallistiOS ##version## + + rwsem.c + Copyright (C) 2008 Lawrence Sebald +*/ + +/* Defines reader/writer semaphores */ + +#include <malloc.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <sys/queue.h> + +#include <kos/rwsem.h> +#include <kos/genwait.h> +#include <arch/spinlock.h> + +/* Reader/writer semaphore list spinlock */ +static spinlock_t mutex; + +/* Global list of reader/writer semaphores */ +static struct rwsemlist rwsem_list; + +/* Allocate a new reader/writer semaphore */ +rw_semaphore_t *rwsem_create() { + rw_semaphore_t *s; + + s = (rw_semaphore_t *)malloc(sizeof(rw_semaphore_t)); + if(!s) { + errno = ENOMEM; + return NULL; + } + + s->read_count = 0; + s->write_lock = 0; + + spinlock_lock(&mutex); + LIST_INSERT_HEAD(&rwsem_list, s, list); + spinlock_unlock(&mutex); + + return s; +} + +/* Destroy a reader/writer semaphore */ +void rwsem_destroy(rw_semaphore_t *s) { + /* XXXX: Should really cause anyone waiting to get an error back on their + wait... hmm. */ + spinlock_lock(&mutex); + LIST_REMOVE(s, list); + spinlock_unlock(&mutex); + + free(s); +} + +/* Lock a reader/writer semaphore for reading */ +int rwsem_read_lock(rw_semaphore_t *s) { + int old, rv = 0; + + if(irq_inside_int()) { + dbglog(DBG_WARNING, "rwsem_read_lock: called inside interrupt\n"); + errno = EPERM; + return -1; + } + + old = irq_disable(); + + /* If the write lock is not held, let the thread proceed */ + if(!s->write_lock) { + ++s->read_count; + } + else { + /* Block until the write lock is not held any more */ + rv = genwait_wait(s, "rwsem_read_lock", 0, NULL); + + if(rv < 0) { + assert(errno == EINTR); + rv = -1; + } + else { + ++s->read_count; + } + } + + irq_restore(old); + return rv; +} + +/* Lock a reader/writer semaphore for writing */ +int rwsem_write_lock(rw_semaphore_t *s) { + int old, rv = 0; + + if(irq_inside_int()) { + dbglog(DBG_WARNING, "rwsem_write_lock: called inside interrupt\n"); + errno = EPERM; + return -1; + } + + old = irq_disable(); + + /* If the write lock is not held and there are no readers in their critical + sections, let the thread proceed. */ + if(!s->write_lock && !s->read_count) { + s->write_lock = 1; + } + else { + /* Block until the write lock is not held and there are no readers + inside their critical sections */ + rv = genwait_wait(&s->write_lock, "rwsem_write_lock", 0, NULL); + + if(rv < 0) { + assert(errno == EINTR); + rv = -1; + } + else { + s->write_lock = 1; + } + } + + irq_restore(old); + return rv; +} + +/* Unlock a reader/writer semaphore from a read lock. */ +int rwsem_read_unlock(rw_semaphore_t *s) { + int old; + + old = irq_disable(); + + --s->read_count; + + /* If this was the last reader, attempt to wake any writers waiting. */ + if(!s->read_count) { + genwait_wake_one(&s->write_lock); + } + + irq_restore(old); + + return 0; +} + +/* Unlock a reader/writer semaphore from a write lock. */ +int rwsem_write_unlock(rw_semaphore_t *s) { + int old, woken; + + old = irq_disable(); + + s->write_lock = 0; + + /* Give writers priority, attempt to wake any writers first. */ + woken = genwait_wake_cnt(&s->write_lock, 1); + + if(!woken) { + /* No writers were waiting, wake up any readers. */ + genwait_wake_all(s); + } + + irq_restore(old); + + return 0; +} + +/* Attempt to lock a reader/writer semaphore for reading, but do not block. */ +int rwsem_read_trylock(rw_semaphore_t *s) { + int old, rv; + + old = irq_disable(); + + /* Is the write lock held? */ + if(s->write_lock) { + rv = -1; + errno = EWOULDBLOCK; + } + else { + rv = 0; + ++s->read_count; + } + + irq_restore(old); + return rv; +} + +/* Attempt to lock a reader/writer semaphore for writing, but do not block. */ +int rwsem_write_trylock(rw_semaphore_t *s) { + int old, rv; + + old = irq_disable(); + + /* Are there any readers in their critical sections, or is the write lock + already held, if so we can't do anything about that now. */ + if(s->read_count || s->write_lock) { + rv = -1; + errno = EWOULDBLOCK; + } + else { + rv = 0; + s->write_lock = 1; + } + + irq_restore(old); + return rv; +} + +/* Return the current reader count */ +int rwsem_read_count(rw_semaphore_t *s) { + return s->read_count; +} + +/* Return the current status of the write lock */ +int rwsem_write_locked(rw_semaphore_t *s) { + return s->write_lock; +} + +/* Initialize reader/writer semaphores */ +int rwsem_init() { + LIST_INIT(&rwsem_list); + spinlock_init(&mutex); + return 0; +} + +/* Shut down reader/writer semaphores */ +void rwsem_shutdown() { + /* XXXX: Do something useful */ +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2008-05-19 15:28:49
|
Revision: 584 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=584&view=rev Author: ljsebald Date: 2008-05-19 08:28:34 -0700 (Mon, 19 May 2008) Log Message: ----------- Oops... forgot a few things. Modified Paths: -------------- kos/include/kos.h kos/kernel/thread/thread.c Modified: kos/include/kos.h =================================================================== --- kos/include/kos.h 2008-05-19 15:23:23 UTC (rev 583) +++ kos/include/kos.h 2008-05-19 15:28:34 UTC (rev 584) @@ -29,6 +29,7 @@ #include <kos/limits.h> #include <kos/thread.h> #include <kos/sem.h> +#include <kos/rwsem.h> #include <kos/mutex.h> #include <kos/cond.h> #include <kos/genwait.h> Modified: kos/kernel/thread/thread.c =================================================================== --- kos/kernel/thread/thread.c 2008-05-19 15:23:23 UTC (rev 583) +++ kos/kernel/thread/thread.c 2008-05-19 15:28:34 UTC (rev 584) @@ -12,6 +12,7 @@ #include <reent.h> #include <kos/thread.h> #include <kos/sem.h> +#include <kos/rwsem.h> #include <kos/cond.h> #include <kos/genwait.h> #include <arch/irq.h> @@ -769,6 +770,7 @@ /* Initialize thread sync primitives */ genwait_init(); + rwsem_init(); sem_init(); cond_init(); @@ -809,6 +811,7 @@ } /* Shutdown thread sync primitives */ + rwsem_shutdown(); sem_shutdown(); cond_shutdown(); genwait_shutdown(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2008-05-20 03:05:51
|
Revision: 588 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=588&view=rev Author: ljsebald Date: 2008-05-19 20:05:38 -0700 (Mon, 19 May 2008) Log Message: ----------- Add support for "upgrading" a reader/writer semaphore from a read lock to a write lock. Modified Paths: -------------- kos/include/kos/rwsem.h kos/kernel/thread/rwsem.c Modified: kos/include/kos/rwsem.h =================================================================== --- kos/include/kos/rwsem.h 2008-05-20 02:45:34 UTC (rev 587) +++ kos/include/kos/rwsem.h 2008-05-20 03:05:38 UTC (rev 588) @@ -71,6 +71,17 @@ EWOULDBLOCK - would block */ int rwsem_write_trylock(rw_semaphore_t *s); +/* "Upgrade" a read lock to a write lock. Returns -1 on error. + EPERM - called inside an interrupt + EINTR - was interrupted */ +int rwsem_read_upgrade(rw_semaphore_t *s); + +/* Attempt to upgrade a read lock to a write lock. If the call to + rwsem_read_upgrade() would normally block, return -1 for error. + Note that on error, the read lock is still held. + EWOULDBLOCK - would block */ +int rwsem_read_tryupgrade(rw_semaphore_t *s); + /* Return the reader/writer semaphore reader count */ int rwsem_read_count(rw_semaphore_t *s); Modified: kos/kernel/thread/rwsem.c =================================================================== --- kos/kernel/thread/rwsem.c 2008-05-20 02:45:34 UTC (rev 587) +++ kos/kernel/thread/rwsem.c 2008-05-20 03:05:38 UTC (rev 588) @@ -201,6 +201,60 @@ return rv; } +/* "Upgrade" a read lock to a write lock. */ +int rwsem_read_upgrade(rw_semaphore_t *s) { + int old, rv = 0; + + if(irq_inside_int()) { + dbglog(DBG_WARNING, "rwsem_read_upgrade: called inside interrupt\n"); + errno = EPERM; + return -1; + } + + old = irq_disable(); + + --s->read_count; + + /* If there are still other readers, wait patiently for our turn. */ + if(s->read_count) { + rv = genwait_wait(&s->write_lock, "rwsem_read_upgrade", 0, NULL); + + if(rv < 0) { + assert(errno == EINTR); + rv = -1; + } + else { + s->write_lock = 1; + } + } + else { + s->write_lock = 1; + } + + irq_restore(old); + return rv; +} + +/* Attempt to upgrade a read lock to a write lock, but do not block. */ +int rwsem_read_tryupgrade(rw_semaphore_t *s) { + int old, rv; + + old = irq_disable(); + + if(s->read_count != 1) { + rv = -1; + errno = EWOULDBLOCK; + } + else { + rv = 0; + s->read_count = 0; + s->write_lock = 1; + } + + irq_restore(old); + return rv; +} + /* Return the current reader count */ int rwsem_read_count(rw_semaphore_t *s) { return s->read_count; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ljs...@us...> - 2008-05-28 13:34:32
|
Revision: 592 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=592&view=rev Author: ljsebald Date: 2008-05-28 06:34:29 -0700 (Wed, 28 May 2008) Log Message: ----------- Adding in another new synchronization primitive: recursive locks, along with an example/test program for them. Modified Paths: -------------- kos/examples/dreamcast/basic/threading/Makefile kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c kos/include/kos.h kos/kernel/thread/Makefile kos/kernel/thread/thread.c Added Paths: ----------- kos/examples/dreamcast/basic/threading/recursive_lock/ kos/examples/dreamcast/basic/threading/recursive_lock/Makefile kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c kos/include/kos/recursive_lock.h kos/kernel/thread/recursive_lock.c Modified: kos/examples/dreamcast/basic/threading/Makefile =================================================================== --- kos/examples/dreamcast/basic/threading/Makefile 2008-05-21 22:04:23 UTC (rev 591) +++ kos/examples/dreamcast/basic/threading/Makefile 2008-05-28 13:34:29 UTC (rev 592) @@ -8,13 +8,15 @@ all: $(KOS_MAKE) -C general $(KOS_MAKE) -C rwsem + $(KOS_MAKE) -C recursive_lock clean: $(KOS_MAKE) -C general clean $(KOS_MAKE) -C rwsem clean - + $(KOS_MAKE) -C recursive_lock clean + dist: $(KOS_MAKE) -C general dist $(KOS_MAKE) -C rwsem dist + $(KOS_MAKE) -C recursive_lock dist - Added: kos/examples/dreamcast/basic/threading/recursive_lock/Makefile =================================================================== --- kos/examples/dreamcast/basic/threading/recursive_lock/Makefile (rev 0) +++ kos/examples/dreamcast/basic/threading/recursive_lock/Makefile 2008-05-28 13:34:29 UTC (rev 592) @@ -0,0 +1,29 @@ +# KallistiOS ##version## +# +# basic/threading/recursive_lock/Makefile +# Copyright (C) 2008 Lawrence Sebald +# + +all: rm-elf rlock_test.elf + +include $(KOS_BASE)/Makefile.rules + +OBJS = rlock_test.o + +clean: rm-elf + -rm -f $(OBJS) + +rm-elf: + -rm -f rlock_test.elf + +rlock_test.elf: $(OBJS) + $(KOS_CC) $(KOS_CFLAGS) $(KOS_LDFLAGS) -o rlock_test.elf $(KOS_START) \ + $(OBJS) $(DATAOBJS) $(OBJEXTRA) $(KOS_LIBS) + + +run: rlock_test.elf + $(KOS_LOADER) rlock_test.elf + +dist: + rm -f $(OBJS) + $(KOS_STRIP) rlock_test.elf \ No newline at end of file Added: kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c (rev 0) +++ kos/examples/dreamcast/basic/threading/recursive_lock/rlock_test.c 2008-05-28 13:34:29 UTC (rev 592) @@ -0,0 +1,128 @@ +/* KallistiOS ##version## + + rlock_test.c + Copyright (C) 2008 Lawrence Sebald + +*/ + +/* This program is a test for the recursive locks added in KOS 1.3.0. This + synchronization primitive works essentially the same as a mutex, but allows + the thread that owns the lock to acquire it as many times as it wants. */ + +#include <stdio.h> + +#include <kos/thread.h> +#include <kos/recursive_lock.h> + +#include <arch/arch.h> +#include <dc/maple.h> +#include <dc/maple/controller.h> + +#define UNUSED __attribute__((unused)) + +recursive_lock_t *l = NULL; + +void thd0(void *param UNUSED) { + int i; + + printf("Thd 0: About to obtain lock 10 times\n"); + + for(i = 0; i < 10; ++i) { + rlock_lock(l); + } + + printf("Thd 0: Lock acquired %d times\n", l->count); + printf("Thd 0: About to sleep\n"); + thd_sleep(100); + + printf("Thd 0: Awake, about to release lock 9 times\n"); + + for(i = 0; i < 9; ++i) { + rlock_unlock(l); + } + + printf("Thd 0: About to sleep again\n"); + thd_sleep(10); + + printf("Thd 0: Awake, about to release lock\n"); + rlock_unlock(l); + printf("Thd 0: done\n"); +} + +void thd1(void *param UNUSED) { + printf("Thd 1: About to obtain lock 2 times\n"); + rlock_lock(l); + rlock_lock(l); + + printf("Thd 1: About to pass timeslice\n"); + thd_pass(); + + printf("Thd 1: Awake, going to release lock 2 times\n"); + rlock_unlock(l); + rlock_unlock(l); + + printf("Thd 1: About to obtain lock 1 time\n"); + rlock_lock(l); + + printf("Thd 1: About to release lock\n"); + rlock_unlock(l); + printf("Thd 1: done\n"); +} + +void thd2(void *param UNUSED) { + int i; + + printf("Thd 2: About to obtain lock 200 times\n"); + + for(i = 0; i < 200; ++i) { + rlock_lock(l); + } + + printf("Thd 2: About to release lock 200 times\n"); + + for(i = 0; i < 200; ++i) { + rlock_unlock(l); + } + + printf("Thd 2: done\n"); +} + +KOS_INIT_FLAGS(INIT_DEFAULT); + +int main(int argc, char *argv[]) { + kthread_t *t0, *t1, *t2; + + /* Exit if the user presses all buttons at once. */ + cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, + arch_exit); + + printf("KallistiOS Recursive Lock test program\n"); + + /* Create the recursive lock */ + l = rlock_create(); + + if(!l) { + printf("Could not create recursive lock, bailing out!\n"); + arch_exit(); + } + + printf("About to create threads\n"); + t0 = thd_create(thd0, NULL); + t1 = thd_create(thd1, NULL); + t2 = thd_create(thd2, NULL); + + printf("About to sleep\n"); + thd_wait(t0); + thd_wait(t1); + thd_wait(t2); + + if(rlock_is_locked(l)) { + printf("Lock is still locked!\n"); + arch_exit(); + } + + rlock_destroy(l); + + printf("Recursive lock tests completed successfully!\n"); + return 0; +} Modified: kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c =================================================================== --- kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2008-05-21 22:04:23 UTC (rev 591) +++ kos/examples/dreamcast/basic/threading/rwsem/rwsem_test.c 2008-05-28 13:34:29 UTC (rev 592) @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) { kthread_t *w0, *w1, *r0, *r1; - /* Exit if the user presse all buttons at once. */ + /* Exit if the user presses all buttons at once. */ cont_btn_callback(0, CONT_START | CONT_A | CONT_B | CONT_X | CONT_Y, arch_exit); Added: kos/include/kos/recursive_lock.h =================================================================== --- kos/include/kos/recursive_lock.h (rev 0) +++ kos/include/kos/recursive_lock.h 2008-05-28 13:34:29 UTC (rev 592) @@ -0,0 +1,59 @@ +/* KallistiOS ##version## + + include/kos/recursive_lock.h + Copyright (C) 2008 Lawrence Sebald + +*/ + +/* This file defines a recursive lock mechanism. Basically, think of these as + a mutex that a single thread can acquire as many times as it wants, but no + other threads can acquire. */ + +#ifndef __KOS_RECURSIVE_LOCK_H +#define __KOS_RECURSIVE_LOCK_H + +#include <sys/cdefs.h> +__BEGIN_DECLS + +#include <sys/queue.h> +#include <kos/thread.h> + +typedef struct recursive_lock { + /* What thread currently holds the lock, if any? */ + kthread_t *holder; + + /* How many times does this thread hold the lock? */ + int count; +} recursive_lock_t; + +/* Allocate a new recursive lock. Returns NULL on failure. + ENOMEM - Out of memory */ +recursive_lock_t *rlock_create(); + +/* Destroy a recursive lock */ +void rlock_destroy(recursive_lock_t *l); + +/* Lock a recursive lock. Returns -1 on error. + EPERM - called inside an interrupt + EINTR - was interrupted */ +int rlock_lock(recursive_lock_t *l); + +/* Unlock a recursive lock. Returns -1 on error. + EPERM - the lock is not held by the current thread */ +int rlock_unlock(recursive_lock_t *l); + +/* Attempt to lock a recursive lock. If the call to rlock_lock() would normally + block, return -1 for error. + EWOULDBLOCK - would block */ +int rlock_trylock(recursive_lock_t *l); + +/* Return whether the lock is currently held. */ +int rlock_is_locked(recursive_lock_t *l); + +/* Init / shutdown */ +int rlock_init(); +void rlock_shutdown(); + +__END_DECLS + +#endif /* !__KOS_RECURSIVE_LOCK_H */ Modified: kos/include/kos.h =================================================================== --- kos/include/kos.h 2008-05-21 22:04:23 UTC (rev 591) +++ kos/include/kos.h 2008-05-28 13:34:29 UTC (rev 592) @@ -30,6 +30,7 @@ #include <kos/thread.h> #include <kos/sem.h> #include <kos/rwsem.h> +#include <kos/recursive_lock.h> #include <kos/mutex.h> #include <kos/cond.h> #include <kos/genwait.h> Modified: kos/kernel/thread/Makefile =================================================================== --- kos/kernel/thread/Makefile 2008-05-21 22:04:23 UTC (rev 591) +++ kos/kernel/thread/Makefile 2008-05-28 13:34:29 UTC (rev 592) @@ -6,7 +6,7 @@ # $Id: Makefile,v 1.4 2003/02/14 08:25:07 bardtx Exp $ OBJS = sem.o cond.o mutex.o genwait.o -OBJS += thread.o rwsem.o +OBJS += thread.o rwsem.o recursive_lock.o SUBDIRS = include $(KOS_BASE)/Makefile.prefab Added: kos/kernel/thread/recursive_lock.c =================================================================== --- kos/kernel/thread/recursive_lock.c (rev 0) +++ kos/kernel/thread/recursive_lock.c 2008-05-28 13:34:29 UTC (rev 592) @@ -0,0 +1,146 @@ +/* KallistiOS ##version## + + recursive_lock.c + Copyright (C) 2008 Lawrence Sebald +*/ + +/* This file defines recursive locks. */ + +#include <malloc.h> +#include <stdio.h> +#include <assert.h> +#include <errno.h> +#include <sys/queue.h> + +#include <kos/recursive_lock.h> +#include <kos/thread.h> +#include <kos/genwait.h> + +/* Create a recursive lock */ +recursive_lock_t *rlock_create() { + recursive_lock_t *rv; + + rv = (recursive_lock_t *)malloc(sizeof(recursive_lock_t)); + if(!rv) { + errno = ENOMEM; + } + + rv->holder = NULL; + rv->count = 0; + + return rv; +} + +/* Destroy a recursive lock */ +void rlock_destroy(recursive_lock_t *l) { + assert(l); + assert(!l->count); + + free(l); +} + +/* Lock a recursive lock */ +int rlock_lock(recursive_lock_t *l) { + int old, rv = 0; + + if(irq_inside_int()) { + dbglog(DBG_WARNING, "rlock_lock: called inside interrupt\n"); + errno = EPERM; + return -1; + } + + old = irq_disable(); + + /* If the lock is not held, let the thread proceed */ + if(!l->count) { + assert(!l->holder); + + l->count = 1; + l->holder = thd_current; + } + else if(l->holder == thd_current) { + ++l->count; + } + else { + /* Block until the lock isn't held any more */ + rv = genwait_wait(l, "rlock_lock", 0, NULL); + + if(rv < 0) { + assert(errno == EINTR); + rv = -1; + } + else { + l->count = 1; + l->holder = thd_current; + } + } + + irq_restore(old); + return rv; +} + +/* Unlock a recursive lock */ +int rlock_unlock(recursive_lock_t *l) { + int old, rv = 0; + + old = irq_disable(); + + /* Make sure we currently hold the lock */ + if(l->holder != thd_current) { + rv = -1; + errno = EPERM; + } + else { + --l->count; + + /* If we're done holding the lock, mark it as such, and signal the next + thread waiting, if any. */ + if(!l->count) { + l->holder = NULL; + genwait_wake_one(l); + } + } + + irq_restore(old); + return rv; +} + +/* Attempt to lock a recursive lock */ +int rlock_trylock(recursive_lock_t *l) { + int old, rv = 0; + + old = irq_disable(); + + /* Check if the lock is held, if so, check if the current thread holds the + lock. */ + if(l->count) { + if(l->holder == thd_current) { + ++l->count; + } + else { + rv = -1; + errno = EWOULDBLOCK; + } + } + else { + l->holder = thd_current; + l->count = 1; + } + + irq_restore(old); + return rv; +} + +/* Return whether or not the lock is currently held */ +int rlock_is_locked(recursive_lock_t *l) { + return !!l->count; +} + +/* Initialize recursive locks */ +int rlock_init() { + return 0; +} + +/* Shut down recursive locks */ +void rlock_shutdown() { +} Modified: kos/kernel/thread/thread.c =================================================================== --- kos/kernel/thread/thread.c 2008-05-21 22:04:23 UTC (rev 591) +++ kos/kernel/thread/thread.c 2008-05-28 13:34:29 UTC (rev 592) @@ -13,6 +13,7 @@ #include <kos/thread.h> #include <kos/sem.h> #include <kos/rwsem.h> +#include <kos/recursive_lock.h> #include <kos/cond.h> #include <kos/genwait.h> #include <arch/irq.h> @@ -771,6 +772,7 @@ /* Initialize thread sync primitives */ genwait_init(); rwsem_init(); + rlock_init(); sem_init(); cond_init(); @@ -812,6 +814,7 @@ /* Shutdown thread sync primitives */ rwsem_shutdown(); + rlock_shutdown(); sem_shutdown(); cond_shutdown(); genwait_shutdown(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <los...@us...> - 2008-05-30 17:32:42
|
Revision: 595 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=595&view=rev Author: lostgeneration Date: 2008-05-30 10:32:39 -0700 (Fri, 30 May 2008) Log Message: ----------- Moved check for free(NULL) up in code to avoid potential problems. * It seems that calling free(NULL) was causing problems. Moving the check for NULL up seems to help. Modified Paths: -------------- kos/doc/CHANGELOG kos/kernel/libc/koslib/malloc.c Modified: kos/doc/CHANGELOG =================================================================== --- kos/doc/CHANGELOG 2008-05-28 13:43:26 UTC (rev 594) +++ kos/doc/CHANGELOG 2008-05-30 17:32:39 UTC (rev 595) @@ -154,6 +154,7 @@ - *** Added support for upgrading a read lock on a reader/writer semaphore to a write lock [LS] - *** Added a recursive lock synchronization primitive [LS] +- *** Moved checking for free(NULL) up in code to avoid potential problems [HL] KallistiOS version 1.2.0 ----------------------------------------------- - DC Fix to use DCARM7_CFLAGS when compiling ARM driver [Christian Groessler == CG] Modified: kos/kernel/libc/koslib/malloc.c =================================================================== --- kos/kernel/libc/koslib/malloc.c 2008-05-28 13:43:26 UTC (rev 594) +++ kos/kernel/libc/koslib/malloc.c 2008-05-30 17:32:39 UTC (rev 595) @@ -1733,6 +1733,10 @@ int dmg = 0; #endif + /* standard C says if block is NULL, do not try to free it */ + if(m == NULL) + return; + if (MALLOC_PREACTION != 0) { return; } @@ -1744,9 +1748,6 @@ thd_current->tid, rv, (uint32)m); #endif - if (m == NULL) - return; - ctl = get_memctl(m); if (ctl->magic != BLOCK_MAGIC) { #ifndef KM_DBG_VERBOSE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <los...@us...> - 2008-06-20 02:40:30
|
Revision: 596 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=596&view=rev Author: lostgeneration Date: 2008-06-19 19:40:29 -0700 (Thu, 19 Jun 2008) Log Message: ----------- Removed legacy libc and libm. * Since libc and libm are now provided by newlib on the primary port * (Dreamcast), these are no longer used or needed. Removed Paths: ------------- kos/libc/ kos/libm/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sa...@us...> - 2008-06-23 22:00:04
|
Revision: 597 http://cadcdev.svn.sourceforge.net/cadcdev/?rev=597&view=rev Author: sannyx Date: 2008-06-23 14:59:58 -0700 (Mon, 23 Jun 2008) Log Message: ----------- don't allow opening a file with O_DIR Modified Paths: -------------- kos/doc/CHANGELOG kos/kernel/arch/dreamcast/sound/arm/stream.drv kos/kernel/fs/fs_ramdisk.c Modified: kos/doc/CHANGELOG =================================================================== --- kos/doc/CHANGELOG 2008-06-20 02:40:29 UTC (rev 596) +++ kos/doc/CHANGELOG 2008-06-23 21:59:58 UTC (rev 597) @@ -155,6 +155,7 @@ a write lock [LS] - *** Added a recursive lock synchronization primitive [LS] - *** Moved checking for free(NULL) up in code to avoid potential problems [HL] +- DC fs_ramdisk.c: Don't allow opening a file with O_DIR [CG] KallistiOS version 1.2.0 ----------------------------------------------- - DC Fix to use DCARM7_CFLAGS when compiling ARM driver [Christian Groessler == CG] Modified: kos/kernel/arch/dreamcast/sound/arm/stream.drv =================================================================== (Binary files differ) Modified: kos/kernel/fs/fs_ramdisk.c =================================================================== --- kos/kernel/fs/fs_ramdisk.c 2008-06-20 02:40:29 UTC (rev 596) +++ kos/kernel/fs/fs_ramdisk.c 2008-06-23 21:59:58 UTC (rev 597) @@ -138,7 +138,7 @@ in the dir. */ if (fn[0] != 0) { f = ramdisk_find(parent, fn, strlen(fn)); - if (!dir && f->type == STAT_TYPE_DIR) + if ((!dir && f->type == STAT_TYPE_DIR) || (dir && f->type != STAT_TYPE_DIR)) return NULL; } else { /* We must have been looking for the dir itself */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |