From f5a4783b701e9e620767d6ac3b2f96b4966278c2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 9 Oct 2011 16:28:57 +0200 Subject: [PATCH] io: Create an io indirection to allow to compile multiple io backends Right now only one io driver is compiled in and this one will be selected at application start. --- Makefile.am | 2 +- io.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ io.h | 11 +++++++++ io_iokit.c | 21 +++++++++++++---- io_libusb.c | 32 ++++++++++++++++++++++---- io_posix.c | 22 ++++++++++++++---- io_win32.c | 22 ++++++++++++++---- main.c | 2 ++ 8 files changed, 160 insertions(+), 17 deletions(-) create mode 100644 io.c diff --git a/Makefile.am b/Makefile.am index 56effdb..a1f695f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = gnu bin_PROGRAMS = sam7 -sam7_SOURCES = main.c io_@IOTYPE@.c samba.c cmd.c +sam7_SOURCES = main.c io.c io_@IOTYPE@.c samba.c cmd.c noinst_HEADERS = io.h samba.h cmd.h loader128_data.h loader256_data.h EXTRA_DIST = driver/Makefile driver/at91.c \ diff --git a/io.c b/io.c new file mode 100644 index 0000000..304e4ed --- /dev/null +++ b/io.c @@ -0,0 +1,65 @@ +/* + * io.c + * + * Copyright (C) 2011 Holger Freyther, all rights reserved + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + */ + +#include "io.h" + +#include + +static struct io_driver *g_driver = NULL; + +static struct io_driver *drivers[5] = { NULL, }; +static int last_driver = 0; + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + +int io_driver_register(struct io_driver *driver) +{ + if (last_driver > ARRAY_SIZE(drivers)) { + fprintf(stderr, "Registered more than %d devices.\n", + ARRAY_SIZE(drivers)); + return -1; + } + + drivers[last_driver++] = driver; + return 0; +} + +struct io_driver *io_driver_at(int i) +{ + if (i >= last_driver) + return NULL; + return drivers[i]; +} + +void io_driver_activate(struct io_driver *driver) +{ + printf("Activating driver: %s\n", driver->name); + g_driver = driver; +} + +int io_init(char *dev) +{ + return g_driver->io_init(dev); +} + +int io_cleanup(void) +{ + return g_driver->io_cleanup(); +} + +int io_write(void *buff, int len) +{ + return g_driver->io_write(buff, len); +} + +int io_read(void *buff, int len) +{ + return g_driver->io_read(buff, len); +} diff --git a/io.h b/io.h index cb45dab..a8a916f 100644 --- a/io.h +++ b/io.h @@ -19,6 +19,17 @@ #define USB_VID_ATMEL 0x03eb #define USB_PID_SAMBA 0x6124 +struct io_driver { + char *name; + int (*io_init) (char *dev); + int (*io_cleanup) (void); + int (*io_write) (void *buff, int len); + int (*io_read) (void *buff, int len); +}; + +int io_driver_register(struct io_driver *driver); +struct io_driver *io_driver_at(int); +void io_driver_activate(struct io_driver *driver); int io_init( char *dev ); int io_cleanup( void ); diff --git a/io_iokit.c b/io_iokit.c index 89b298e..dfcb0f5 100644 --- a/io_iokit.c +++ b/io_iokit.c @@ -2,6 +2,7 @@ * io.c * * Copyright (C) 2005 Erik Gilling, all rights reserved + * Copyright (C) 2011 Holger Freyther, all rights reserved * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -203,7 +204,7 @@ static int do_dev( io_service_t usbDeviceRef ) } -int io_init( char *dev __attribute__((unused)) ) +static int iokit_io_init( char *dev __attribute__((unused)) ) { kern_return_t err; @@ -274,7 +275,7 @@ int io_init( char *dev __attribute__((unused)) ) } -int io_cleanup( void ) +static int iokit_io_cleanup( void ) { if( intf ) { (*intf)->USBInterfaceClose(intf); @@ -291,7 +292,7 @@ int io_cleanup( void ) return 0; } -int io_write( void *buff, int len ) +static int iokit_io_write( void *buff, int len ) { if( (*intf)->WritePipe( intf, outPipeRef, buff, (UInt32) len ) != kIOReturnSuccess ) { @@ -301,7 +302,7 @@ int io_write( void *buff, int len ) return len; } -int io_read( void *buff, int len ) +static int iokit_io_read( void *buff, int len ) { UInt32 size = len; @@ -315,3 +316,15 @@ int io_read( void *buff, int len ) return (int) size; } +static struct io_driver iokit_driver = { + .name = "iokit", + .io_init = iokit_io_init, + .io_cleanup = iokit_io_cleanup, + .io_write = iokit_io_write, + .io_read = iokit_io_read, +}; + +static void __attribute__((constructor)) iokit_on_load(void) +{ + io_driver_register(&iokit_driver); +} diff --git a/io_libusb.c b/io_libusb.c index 0c30494..4890747 100644 --- a/io_libusb.c +++ b/io_libusb.c @@ -1,3 +1,14 @@ +/* + * io_libusb.c + * + * Copyright (C) 200X ??? + * Copyright (C) 2011 Holger Hans Peter Freyther + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + * + */ #include "config.h" #include @@ -8,7 +19,7 @@ static usb_dev_handle *io_handle; -int io_init( char *dev ) +static int lusb_io_init( char *dev ) { struct usb_bus *bus; struct usb_device *usbdev; @@ -43,7 +54,7 @@ int io_init( char *dev ) return -1; } -int io_cleanup( void ) +static int lusb_io_cleanup( void ) { usb_release_interface(io_handle, 1); usb_close(io_handle); @@ -51,7 +62,7 @@ int io_cleanup( void ) } -int io_write( void *buff, int len ) +static int lusb_io_write( void *buff, int len ) { int ret = usb_bulk_write(io_handle, 0x1, buff, len, 5000); if( ret < 0 ) { @@ -60,7 +71,7 @@ int io_write( void *buff, int len ) return ret; } -int io_read( void *buff, int len ) +static int lusb_io_read( void *buff, int len ) { int ret = usb_bulk_read(io_handle, 0x82, buff, len, 5000); if( ret < 0 ) { @@ -68,3 +79,16 @@ int io_read( void *buff, int len ) } return ret; } + +static struct io_driver lusb_driver = { + .name = "libusb", + .io_init = lusb_io_init, + .io_cleanup = lusb_io_cleanup, + .io_write = lusb_io_write, + .io_read = lusb_io_read, +}; + +static void __attribute__((constructor)) lusb_on_load(void) +{ + io_driver_register(&lusb_driver); +} diff --git a/io_posix.c b/io_posix.c index e7e80ad..60ae235 100644 --- a/io_posix.c +++ b/io_posix.c @@ -2,6 +2,7 @@ * io.c * * Copyright (C) 2005 Erik Gilling, all rights reserved + * Copyright (C) 2011 Holger Freyther, all rights reserved * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -35,7 +36,7 @@ static int io_fd; #undef DEBUG_IO -int io_init( char *dev ) +static int posix_io_init( char *dev ) { if( dev == NULL ) { dev = SAM7_TTY; @@ -52,13 +53,14 @@ int io_init( char *dev ) return samba_init(); } -int io_cleanup( void ) +static int posix_io_cleanup( void ) { close( io_fd ); return 0; } -int io_write( void *buff, int len ) + +static int posix_io_write( void *buff, int len ) { int write_len = 0; int ret; @@ -79,7 +81,7 @@ int io_write( void *buff, int len ) return write_len; } -int io_read( void *buff, int len ) +static int posix_io_read( void *buff, int len ) { #ifdef DEBUG_IO int i; @@ -98,3 +100,15 @@ int io_read( void *buff, int len ) #endif } +static struct io_driver posix_driver = { + .name = "posix", + .io_init = posix_io_init, + .io_cleanup = posix_io_cleanup, + .io_write = posix_io_write, + .io_read = posix_io_read, +}; + +static void __attribute__((constructor)) posix_on_load(void) +{ + io_driver_register(&posix_driver); +} diff --git a/io_win32.c b/io_win32.c index 698e550..137026a 100644 --- a/io_win32.c +++ b/io_win32.c @@ -2,6 +2,7 @@ * io_win32.c * * Copyright (C) 2005 Erik Gilling, all rights reserved + * Copyright (C) 2011 Holger Hans Peter Freyther * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -32,7 +33,7 @@ DEFINE_GUID(USBIODS_GUID, HANDLE io_pipe_in, io_pipe_out; -int io_init( char *dev ) +static int win32_io_init( char *dev ) { char *devname; @@ -130,14 +131,15 @@ int io_init( char *dev ) return -1; } -int io_cleanup( void ) +static int win32_io_cleanup( void ) { CloseHandle( io_pipe_out ); CloseHandle( io_pipe_in ); return 0; } -int io_write( void *buff, int len ) + +static int win32_io_write( void *buff, int len ) { int write_len = 0; DWORD bytes_written; @@ -154,7 +156,7 @@ int io_write( void *buff, int len ) return write_len; } -int io_read( void *buff, int len ) +static int win32_io_read( void *buff, int len ) { int read_len = 0; DWORD bytes_read; @@ -171,3 +173,15 @@ int io_read( void *buff, int len ) return read_len; } +static struct io_driver win32_driver = { + .name = "win32", + .io_init = win32_io_init, + .io_cleanup = win32_io_cleanup, + .io_write = win32_io_write, + .io_read = win32_io_read, +}; + +static void __attribute__((constructor)) win32_on_load(void) +{ + io_driver_register(&win32_driver); +} diff --git a/main.c b/main.c index 3d44929..9a33ba0 100644 --- a/main.c +++ b/main.c @@ -91,6 +91,8 @@ int main( int argc, char *argv[] ) } } + /* Activate a default driver */ + io_driver_activate(io_driver_at(0)); if( io_init( line ) < 0 ) { fprintf(stderr, "Failed to initialize the SAM7 device.\n");