2003-03-18 Marcel Telka <marcel@telka.sk>
* configure.ac (AC_CHECK_HEADERS): Added test for linux/ppdev.h. * src/tap/Makefile.am (libtap_a_SOURCES): Added parport/ppdev.c. * src/tap/parport.c (parport_drivers): Added ppdev parport driver. * src/tap/parport/ppdev.c: New file. git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@399 b68d4a1b-bc3d-0410-92ed-d4ac073336b7master
parent
0af1945181
commit
d75952bec4
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* Linux ppdev Driver
|
||||
* Copyright (C) 2003 ETC s.r.o.
|
||||
*
|
||||
* 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 Marcel Telka <marcel@telka.sk>, 2003.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LINUX_PPDEV_H
|
||||
|
||||
#include "gettext.h"
|
||||
#define _(s) gettext(s)
|
||||
#define N_(s) gettext_noop(s)
|
||||
#define P_(s,p,n) ngettext(s,p,n)
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stropts.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/ppdev.h>
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "parport.h"
|
||||
#include "cable.h"
|
||||
|
||||
parport_driver_t ppdev_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; /* ppdev parallel ports */
|
||||
|
||||
typedef struct {
|
||||
char *portname;
|
||||
int fd;
|
||||
} ppdev_params_t;
|
||||
|
||||
static parport_t *
|
||||
ppdev_parport_alloc( const char *port )
|
||||
{
|
||||
ppdev_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 = &ppdev_parport_driver;
|
||||
parport->cable = NULL;
|
||||
|
||||
node->port = parport;
|
||||
node->next = ports;
|
||||
|
||||
ports = node;
|
||||
|
||||
return parport;
|
||||
}
|
||||
|
||||
static void
|
||||
ppdev_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( ((ppdev_params_t *) port->params)->portname );
|
||||
free( port->params );
|
||||
free( port );
|
||||
}
|
||||
|
||||
static cable_t *
|
||||
ppdev_connect( const char **par, int parnum )
|
||||
{
|
||||
int i;
|
||||
port_node_t *pn;
|
||||
parport_t *parport;
|
||||
cable_t *cable;
|
||||
|
||||
if (parnum != 2) {
|
||||
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 ppdev port %s\n"), pn->port->cable->driver->description, par[0] );
|
||||
pn->port->cable->driver->disconnect( pn->port->cable );
|
||||
break;
|
||||
}
|
||||
|
||||
if (strcmp( par[1], "none" ) == 0) {
|
||||
printf( _("Changed cable to 'none'\n") );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; cable_drivers[i]; i++)
|
||||
if (strcmp( par[1], cable_drivers[i]->name ) == 0)
|
||||
break;
|
||||
|
||||
if (!cable_drivers[i]) {
|
||||
printf( _("Unknown cable: %s\n"), par[1] );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
printf( _("Initializing %s on ppdev port %s\n"), cable_drivers[i]->description, par[0] );
|
||||
|
||||
parport = ppdev_parport_alloc( par[0] );
|
||||
if (!parport) {
|
||||
printf( _("%s(%d) Out of memory.\n"), __FILE__, __LINE__ );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cable = cable_drivers[i]->connect( cable_drivers[i], parport );
|
||||
if (!cable)
|
||||
ppdev_parport_free( parport );
|
||||
|
||||
return cable;
|
||||
}
|
||||
|
||||
static int
|
||||
ppdev_open( parport_t *parport )
|
||||
{
|
||||
ppdev_params_t *p = parport->params;
|
||||
|
||||
printf( "Opening port: %s\n", p->portname );
|
||||
p->fd = open( p->portname, O_RDWR );
|
||||
printf( "Result: %d\n", p->fd );
|
||||
if (p->fd < 0)
|
||||
return -1;
|
||||
|
||||
if ((ioctl( p->fd, PPEXCL ) == -1) || (ioctl( p->fd, PPCLAIM ) == -1)) {
|
||||
close( p->fd );
|
||||
p->fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ppdev_close( parport_t *parport )
|
||||
{
|
||||
int r = 0;
|
||||
ppdev_params_t *p = parport->params;
|
||||
|
||||
if (ioctl( p->fd, PPRELEASE ) == -1)
|
||||
r = -1;
|
||||
|
||||
if (close( p->fd ) != 0)
|
||||
return -1;
|
||||
|
||||
p->fd = -1;
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
ppdev_set_data( parport_t *parport, uint8_t data )
|
||||
{
|
||||
ppdev_params_t *p = parport->params;
|
||||
|
||||
if (ioctl( p->fd, PPWDATA, &data ) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ppdev_get_data( parport_t *parport )
|
||||
{
|
||||
unsigned char d;
|
||||
ppdev_params_t *p = parport->params;
|
||||
|
||||
if (ioctl( p->fd, PPRDATA, &d ) == -1)
|
||||
return -1;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static int
|
||||
ppdev_get_status( parport_t *parport )
|
||||
{
|
||||
unsigned char d;
|
||||
ppdev_params_t *p = parport->params;
|
||||
|
||||
if (ioctl( p->fd, PPRSTATUS, &d ) == -1)
|
||||
return -1;
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
static int
|
||||
ppdev_set_control( parport_t *parport, uint8_t data )
|
||||
{
|
||||
ppdev_params_t *p = parport->params;
|
||||
|
||||
if (ioctl( p->fd, PPWCONTROL, &data ) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
parport_driver_t ppdev_parport_driver = {
|
||||
"ppdev",
|
||||
ppdev_connect,
|
||||
ppdev_parport_free,
|
||||
ppdev_open,
|
||||
ppdev_close,
|
||||
ppdev_set_data,
|
||||
ppdev_get_data,
|
||||
ppdev_get_status,
|
||||
ppdev_set_control
|
||||
};
|
||||
|
||||
#endif /* HAVE_LINUX_PPDEV_H */
|
Loading…
Reference in New Issue