blob: e0f6bbc5460fd5ee5236aff26813448951bbbbb0 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation
* All rights reserved.
* This program and the accompanying materials
* are made available under the terms of the BSD License
* which accompanies this distribution, and is available at
* http://www.opensource.org/licenses/bsd-license.php
*
* Contributors:
* IBM Corporation - initial implementation
*****************************************************************************/
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <of.h>
#include <netdriver_int.h>
#include <fileio.h>
#include <ioctl.h>
#include "modules.h"
extern int vsprintf(char *, const char *, va_list);
extern void _exit(int status);
void exit(int status);
int printk(const char*, ...);
int open(const char* name, int flags)
{
int fd, i;
/* search free file descriptor */
for(fd=0; fd<FILEIO_MAX; ++fd) {
if(fd_array[fd].type == FILEIO_TYPE_EMPTY) {
break;
}
}
if(fd == FILEIO_MAX) {
printk ("Can not open \"%s\" because file descriptor list is full\n", name);
/* there is no free file descriptor available */
return -2;
}
for(i=0; i<MODULES_MAX; ++i) {
if(!snk_modules[i] || !snk_modules[i]->open) {
continue;
}
if(snk_modules[i]->running == 0) {
snk_modules[i]->init();
}
if(snk_modules[i]->open(&fd_array[fd], name, flags) == 0)
break;
}
if(i==MODULES_MAX) {
/* file not found */
return -1;
}
return fd;
}
int socket(int domain, int type, int proto, char *mac_addr)
{
snk_module_t *net_module;
net_module = get_module_by_type(MOD_TYPE_NETWORK);
if( !net_module || !net_module->init) {
printk("No net_init function available");
return -1;
}
/* Init net device driver */
if(net_module->running == 0) {
net_module->init();
}
if(net_module->running == 0)
return -2;
memcpy(mac_addr, &net_module->mac_addr[0], 6);
return 0;
}
int close(int fd)
{
if(fd < 0 || fd >= FILEIO_MAX
|| fd_array[fd].type == FILEIO_TYPE_EMPTY
|| fd_array[fd].close == 0)
return -1;
return fd_array[fd].close(&fd_array[fd]);
}
ssize_t read(int fd, void *buf, size_t len)
{
if(fd < 0 || fd >= FILEIO_MAX
|| fd_array[fd].type == FILEIO_TYPE_EMPTY
|| fd_array[fd].read == 0)
return -1;
return fd_array[fd].read(&fd_array[fd], buf, len);
}
ssize_t write (int fd, const void *buf, size_t len)
{
char dest_buf[512];
char *dest_buf_ptr;
const char *dbuf = buf;
int i;
if (fd == 1 || fd == 2) {
dest_buf_ptr = &dest_buf[0];
for (i = 0; i < len && i < 256; i++)
{
*dest_buf_ptr++ = *dbuf++;
if (dbuf[-1] == '\n')
*dest_buf_ptr++ = '\r';
}
len = dest_buf_ptr - &dest_buf[0];
buf = &dest_buf[0];
}
if(fd < 0 || fd >= FILEIO_MAX
|| fd_array[fd].type == FILEIO_TYPE_EMPTY
|| fd_array[fd].write == 0)
return -1;
return fd_array[fd].write(&fd_array[fd], (void *)buf, len);
}
ssize_t lseek (int fd, long offset, int whence)
{
return 0; // this syscall is unused !!!
#if 0
if (whence != 0)
return -1;
of_seek (fd_array[fd], (unsigned int) (offset>>32), (unsigned int) (offset & 0xffffffffULL));
return offset;
#endif
}
int ioctl (int fd, int request, void* data)
{
if (fd < 0
|| fd >= FILEIO_MAX
|| fd_array[fd].type == FILEIO_TYPE_EMPTY)
return -1;
if (!fd_array[fd].ioctl) { /* for backwards compatibility with network modules */
snk_module_t *net_module;
net_module = get_module_by_type(MOD_TYPE_NETWORK);
if ( !net_module || !net_module->ioctl ) {
printk("No net_ioctl function available");
return -1;
}
return net_module->ioctl(request, data);
}
return fd_array[fd].ioctl(&fd_array[fd], request, data);
}
int recv(int fd, void *packet, int packet_len, int flags)
{
snk_module_t *net_module;
net_module = get_module_by_type(MOD_TYPE_NETWORK);
if( !net_module || !net_module->read ) {
printk("No net_receive function available");
return -1;
}
return net_module->read(packet, packet_len);
}
int send(int fd, const void *packet, int packet_len, int flags)
{
snk_module_t *net_module;
net_module = get_module_by_type(MOD_TYPE_NETWORK);
if( !net_module || !net_module->write ) {
printk("No net_xmit function available");
return -1;
}
return net_module->write((void *)packet, packet_len);
}
int sendto(int fd, const void *packet, int packet_len, int flags,
const void *sock_addr, int sock_addr_len)
{
return send(fd, packet, packet_len, flags);
}
void exit(int status)
{
_exit(status);
}
int printk(const char* fmt, ...)
{
int count;
va_list ap;
char buffer[256];
va_start (ap, fmt);
count=vsprintf(buffer, fmt, ap);
write (1, buffer, count);
va_end (ap);
return count;
}