Add support for FreeBSD's ppi interface (by Daniel O'Connor)

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@851 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Kolja Waschk 17 years ago
parent 04377b79dd
commit ba186f369d

@ -1,5 +1,9 @@
2007-12-15 Kolja Waschk <kawk>
* configure.ac, tap/parport/parport.c, tap/parport/ppi.c,
tap/parport/direct.c: Adapted openwince patch by Daniel
O'Connor, [1235990] Add support for FreeBSD's ppi interface
(closes our copy of that tracker item, 1829585)
* src/cmd/cable.c, include/cable.h, src/tap/cable/*.c: Add
help function to every cable; temporarily allow old syntax
for cable command when used for parallel port cables

@ -171,6 +171,7 @@ AC_CHECK_FUNCS(swprintf)
AC_CHECK_FUNC(clock_gettime, [], [ AC_CHECK_LIB(rt, clock_gettime) ])
AC_CHECK_HEADERS(linux/ppdev.h)
AC_CHECK_HEADERS(dev/ppbus/ppi.h)
VL_LIB_READLINE

@ -33,6 +33,7 @@ libtap_a_SOURCES = \
parport.c \
parport/direct.c \
parport/ppdev.c \
parport/ppi.c \
cable.c \
cable/generic.h \
cable/generic.c \

@ -43,6 +43,9 @@ extern parport_driver_t ftdi_mpsse_parport_driver;
#ifdef HAVE_LIBUSB
extern parport_driver_t xpcu_pp_driver;
#endif /* HAVE_LIBUSB */
#ifdef HAVE_DEV_PPBUS_PPI_H
extern parport_driver_t ppi_parport_driver;
#endif /* HAVE_DEV_PPBUS_PPI_H */
parport_driver_t *parport_drivers[] = {
#if defined(HAVE_IOPERM) || defined(HAVE_I386_SET_IOPERM)
@ -62,9 +65,13 @@ parport_driver_t *parport_drivers[] = {
#ifdef HAVE_LIBUSB
&xpcu_pp_driver,
#endif /* HAVE_LIBUSB */
#ifdef HAVE_DEV_PPBUS_PPI_H
&ppi_parport_driver,
#endif /* HAVE_DEV_PPBUS_PPI_H */
NULL /* last must be NULL */
};
int
parport_open( parport_t *port )
{

@ -46,6 +46,10 @@
static __inline int
ioperm( unsigned long from, unsigned long num, int permit )
{
#ifdef __FreeBSD__
if (i386_set_ioperm( from, num, permit ) == -1)
return -1;
#else
u_long ports[32];
u_long i;
@ -60,14 +64,17 @@ ioperm( unsigned long from, unsigned long num, int permit )
if (i386_set_ioperm( ports ) == -1)
return -1;
#endif
return 0;
}
static __inline int
iopl( int level )
{
#ifndef __FreeBSD__
return i386_iopl( level );
#endif
return 0;
}
static __inline unsigned char

@ -0,0 +1,222 @@
/*
* $Id$
*
* FreeBSD ppi Driver
* Copyright (C) 2005 Daniel O'Connor
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Written by Daniel O'Connor <doconnor@gsoft.com.au> July 2005.
*
*/
#include "sysdep.h"
#ifdef HAVE_DEV_PPBUS_PPI_H
#include <fcntl.h>
#include <unistd.h>
#include <dev/ppbus/ppi.h>
#include <dev/ppbus/ppbconf.h>
#include <stdlib.h>
#include <string.h>
#include "parport.h"
#include "cable.h"
parport_driver_t ppi_parport_driver;
typedef struct port_node_t port_node_t;
struct port_node_t {
parport_t *port;
port_node_t *next;
};
static port_node_t *ports = NULL; /* ppi parallel ports */
typedef struct {
char *portname;
int fd;
} ppi_params_t;
static parport_t *
ppi_parport_alloc( const char *port )
{
ppi_params_t *params = malloc( sizeof *params );
char *portname = strdup( port );
parport_t *parport = malloc( sizeof *parport );
port_node_t *node = malloc( sizeof *node );
if (!node || !parport || !params || !portname) {
free( node );
free( parport );
free( params );
free( portname );
return NULL;
}
params->portname = portname;
params->fd = -1;
parport->params = params;
parport->driver = &ppi_parport_driver;
parport->cable = NULL;
node->port = parport;
node->next = ports;
ports = node;
return parport;
}
static void
ppi_parport_free( parport_t *port )
{
port_node_t **prev;
for (prev = &ports; *prev; prev = &((*prev)->next))
if ((*prev)->port == port)
break;
if (*prev) {
port_node_t *pn = *prev;
*prev = pn->next;
free( pn );
}
free( ((ppi_params_t *) port->params)->portname );
free( port->params );
free( port );
}
static cable_t *
ppi_connect( const char **par, int parnum )
{
port_node_t *pn;
parport_t *parport;
if (parnum != 1) {
printf( _("Syntax error!\n") );
return NULL;
}
for (pn = ports; pn; pn = pn->next)
if (strcmp( pn->port->params, par[0] ) == 0) {
printf( _("Disconnecting %s from ppi port %s\n"), _(pn->port->cable->driver->description), par[0] );
pn->port->cable->driver->disconnect( pn->port->cable );
break;
}
printf( _("Initializing on ppi port %s\n"), par[0] );
parport = ppi_parport_alloc( par[0] );
if (!parport) {
printf( _("%s(%d) Out of memory.\n"), __FILE__, __LINE__ );
return NULL;
}
return parport;
}
static int
ppi_open( parport_t *parport )
{
ppi_params_t *p = parport->params;
p->fd = open( p->portname, O_RDWR );
if (p->fd < 0)
return -1;
return 0;
}
static int
ppi_close( parport_t *parport )
{
int r = 0;
ppi_params_t *p = parport->params;
if (close( p->fd ) != 0)
return -1;
p->fd = -1;
return r;
}
static int
ppi_set_data( parport_t *parport, uint8_t data )
{
ppi_params_t *p = parport->params;
if (ioctl( p->fd, PPISDATA, &data ) == -1)
return -1;
return 0;
}
static int
ppi_get_data( parport_t *parport )
{
unsigned char d;
ppi_params_t *p = parport->params;
if (ioctl( p->fd, PPIGDATA, &d ) == -1)
return -1;
return d;
}
static int
ppi_get_status( parport_t *parport )
{
unsigned char d;
ppi_params_t *p = parport->params;
if (ioctl( p->fd, PPIGSTATUS, &d ) == -1)
return -1;
return d ^ 0x80; /* BUSY is inverted */
}
static int
ppi_set_control( parport_t *parport, uint8_t data )
{
ppi_params_t *p = parport->params;
data ^= 0x0B; /* SELECT, AUTOFD, and STROBE are inverted */
if (ioctl( p->fd, PPIGCTRL, &data ) == -1)
return -1;
return 0;
}
parport_driver_t ppi_parport_driver = {
"ppi",
ppi_connect,
ppi_parport_free,
ppi_open,
ppi_close,
ppi_set_data,
ppi_get_data,
ppi_get_status,
ppi_set_control
};
#endif /* HAVE_DEV_PPBUS_PPI_H */
Loading…
Cancel
Save