|
Packit |
d36e9b |
/*
|
|
Packit |
d36e9b |
* libieee1284 - IEEE 1284 library
|
|
Packit |
d36e9b |
* Copyright (C) 1999-2002 Tim Waugh <twaugh@redhat.com>
|
|
Packit |
d36e9b |
*
|
|
Packit |
d36e9b |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
d36e9b |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
d36e9b |
* the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
d36e9b |
* (at your option) any later version.
|
|
Packit |
d36e9b |
*
|
|
Packit |
d36e9b |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
d36e9b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
d36e9b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
d36e9b |
* GNU General Public License for more details.
|
|
Packit |
d36e9b |
*
|
|
Packit |
d36e9b |
* You should have received a copy of the GNU General Public License
|
|
Packit |
d36e9b |
* along with this program; if not, write to the Free Software
|
|
Packit |
d36e9b |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
d36e9b |
*/
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
#include <errno.h>
|
|
Packit |
d36e9b |
#include <fcntl.h>
|
|
Packit |
d36e9b |
#include <stdio.h>
|
|
Packit |
d36e9b |
#include <stdlib.h>
|
|
Packit |
d36e9b |
#include <string.h>
|
|
Packit |
d36e9b |
#if !(defined __MINGW32__ || defined _MSC_VER)
|
|
Packit |
d36e9b |
#include <sys/ioctl.h>
|
|
Packit |
d36e9b |
#else
|
|
Packit |
d36e9b |
#include <io.h> /* read(), open(), close() */
|
|
Packit |
d36e9b |
#define O_NOCTTY 0
|
|
Packit |
d36e9b |
#endif
|
|
Packit |
d36e9b |
#include <sys/stat.h>
|
|
Packit |
d36e9b |
#ifndef _MSC_VER
|
|
Packit |
d36e9b |
#include <sys/time.h>
|
|
Packit |
d36e9b |
#endif
|
|
Packit |
d36e9b |
#include <sys/types.h>
|
|
Packit |
d36e9b |
#ifdef __unix__
|
|
Packit |
d36e9b |
#include <unistd.h>
|
|
Packit |
d36e9b |
#endif
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
#include "config.h"
|
|
Packit |
d36e9b |
#include "debug.h"
|
|
Packit |
d36e9b |
#include "ieee1284.h"
|
|
Packit |
d36e9b |
#include "detect.h"
|
|
Packit |
d36e9b |
#include "parport.h"
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
#define ETRYNEXT 100
|
|
Packit |
d36e9b |
#define ENODEVID 101
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
static ssize_t
|
|
Packit |
d36e9b |
get_fresh (struct parport *port, int daisy,
|
|
Packit |
d36e9b |
char *buffer, size_t len)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
ssize_t got;
|
|
Packit |
d36e9b |
size_t idlen;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
debugprintf ("==> get_fresh\n");
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (daisy > -1)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
/* No implementation yet for IEEE 1284.3 devices. */
|
|
Packit |
d36e9b |
debugprintf ("<== E1284_NOTIMPL (IEEE 1284.3)\n");
|
|
Packit |
d36e9b |
return E1284_NOTIMPL;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
ieee1284_terminate (port);
|
|
Packit |
d36e9b |
if (ieee1284_negotiate (port,
|
|
Packit |
d36e9b |
M1284_NIBBLE | M1284_FLAG_DEVICEID) != E1284_OK)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== E1284_NOTAVAIL (couldn't negotiate)\n");
|
|
Packit |
d36e9b |
return E1284_NOTAVAIL;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
got = ieee1284_nibble_read (port, 0, buffer, 2);
|
|
Packit |
d36e9b |
if (got < 2)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== E1284_NOID (no data)\n");
|
|
Packit |
d36e9b |
return E1284_NOID;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
idlen = buffer[0] * 256 + buffer[1];
|
|
Packit |
d36e9b |
if (idlen >= len - 2)
|
|
Packit |
d36e9b |
idlen = len - 2;
|
|
Packit |
d36e9b |
got += ieee1284_nibble_read (port, 0, buffer + 2, idlen);
|
|
Packit |
d36e9b |
if ((size_t) got < len)
|
|
Packit |
d36e9b |
buffer[got] = '\0';
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
ieee1284_terminate (port);
|
|
Packit |
d36e9b |
debugprintf ("<== %d\n", got);
|
|
Packit |
d36e9b |
return got;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
static ssize_t
|
|
Packit |
d36e9b |
get_from_proc_parport (struct parport *port, int daisy,
|
|
Packit |
d36e9b |
char *buffer, size_t len)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
int fd;
|
|
Packit |
d36e9b |
char *name;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (strchr (port->name, '/') || port->name[0] == '.')
|
|
Packit |
d36e9b |
/* Hmm, suspicious. */
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
name = malloc (strlen (port->name) + 50);
|
|
Packit |
d36e9b |
if (!name)
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (daisy > -1)
|
|
Packit |
d36e9b |
sprintf (name, "/proc/parport/%s/autoprobe%d", port->name, daisy);
|
|
Packit |
d36e9b |
else
|
|
Packit |
d36e9b |
sprintf (name, "/proc/parport/%s/autoprobe", port->name);
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
fd = open (name, O_RDONLY | O_NOCTTY);
|
|
Packit |
d36e9b |
free (name);
|
|
Packit |
d36e9b |
if (fd >= 0)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
ssize_t got = read (fd, buffer + 2, len - 2);
|
|
Packit |
d36e9b |
close (fd);
|
|
Packit |
d36e9b |
if (got < 1)
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if ((size_t) (2 + got) < len)
|
|
Packit |
d36e9b |
buffer[2 + got] = '\0';
|
|
Packit |
d36e9b |
buffer[0] = (unsigned char)(got / (1<<8));
|
|
Packit |
d36e9b |
buffer[1] = (unsigned char)(got % (1<<8));
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
return got;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
static ssize_t
|
|
Packit |
d36e9b |
get_from_sys_dev_parport (struct parport *port, int daisy,
|
|
Packit |
d36e9b |
char *buffer, size_t len)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
int fd;
|
|
Packit |
d36e9b |
char *name;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (strchr (port->name, '/') || port->name[0] == '.')
|
|
Packit |
d36e9b |
/* Hmm, suspicious. */
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
name = malloc (strlen (port->name) + 50);
|
|
Packit |
d36e9b |
if (!name)
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (daisy > -1)
|
|
Packit |
d36e9b |
sprintf (name, "/proc/sys/dev/parport/%s/deviceid%d", port->name, daisy);
|
|
Packit |
d36e9b |
else
|
|
Packit |
d36e9b |
sprintf (name, "/proc/sys/dev/parport/%s/deviceid", port->name);
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
fd = open (name, O_RDONLY | O_NOCTTY);
|
|
Packit |
d36e9b |
if (fd >= 0)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
ssize_t got = read (fd, buffer, len);
|
|
Packit |
d36e9b |
free (name);
|
|
Packit |
d36e9b |
close (fd);
|
|
Packit |
d36e9b |
if (got < 1)
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
if ((size_t) got < len)
|
|
Packit |
d36e9b |
buffer[got] = '\0';
|
|
Packit |
d36e9b |
return got;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (daisy > -1)
|
|
Packit |
d36e9b |
sprintf (name, "/proc/sys/dev/parport/%s/autoprobe%d", port->name, daisy);
|
|
Packit |
d36e9b |
else
|
|
Packit |
d36e9b |
sprintf (name, "/proc/sys/dev/parport/%s/autoprobe", port->name);
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
fd = open (name, O_RDONLY | O_NOCTTY);
|
|
Packit |
d36e9b |
free (name);
|
|
Packit |
d36e9b |
if (fd >= 0)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
ssize_t got = read (fd, buffer + 2, len - 3);
|
|
Packit |
d36e9b |
close (fd);
|
|
Packit |
d36e9b |
if (got < 1)
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
buffer[2 + got] = '\0';
|
|
Packit |
d36e9b |
buffer[0] = (unsigned char)(got / (1<<8));
|
|
Packit |
d36e9b |
buffer[1] = (unsigned char)(got % (1<<8));
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
return got;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
return -ETRYNEXT;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
ssize_t
|
|
Packit |
d36e9b |
ieee1284_get_deviceid (struct parport *port, int daisy, int flags,
|
|
Packit |
d36e9b |
char *buffer, size_t len)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
int ret = -1;
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
debugprintf ("==> libieee1284_get_deviceid\n");
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (flags & ~(F1284_FRESH))
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== E1284_NOTIMPL (flags)\n");
|
|
Packit |
d36e9b |
return E1284_NOTIMPL;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
// detect_environment (0);
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (!(flags & F1284_FRESH))
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
if (capabilities & PROC_SYS_DEV_PARPORT_CAPABLE)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
ret = get_from_sys_dev_parport (port, daisy, buffer, len);
|
|
Packit |
d36e9b |
debugprintf ("Trying /proc/sys/dev/parport: %s\n",
|
|
Packit |
d36e9b |
ret < 0 ? "failed" : "success");
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
else if (capabilities & PROC_PARPORT_CAPABLE)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
ret = get_from_proc_parport (port, daisy, buffer, len);
|
|
Packit |
d36e9b |
debugprintf ("Trying /proc/parport: %s\n",
|
|
Packit |
d36e9b |
ret < 0 ? "failed" : "success");
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (ret > -1)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== %d\n", ret);
|
|
Packit |
d36e9b |
return ret;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if (ret == -ENODEVID)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== E1284_NOTAVAIL (got -ENODEVID)\n");
|
|
Packit |
d36e9b |
return E1284_NOTAVAIL;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
debugprintf ("Trying device...\n");
|
|
Packit |
d36e9b |
if ((ret = ieee1284_open (port, 0, NULL)) != E1284_OK)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== %d (from ieee1284_open)\n", ret);
|
|
Packit |
d36e9b |
return ret;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
if ((ret = ieee1284_claim (port)) != E1284_OK)
|
|
Packit |
d36e9b |
{
|
|
Packit |
d36e9b |
debugprintf ("<== %d (from ieee1284_claim)\n", ret);
|
|
Packit |
d36e9b |
return ret;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
ret = get_fresh (port, daisy, buffer, len);
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
ieee1284_release (port);
|
|
Packit |
d36e9b |
ieee1284_close (port);
|
|
Packit |
d36e9b |
debugprintf ("<== %d (from get_fresh)\n", ret);
|
|
Packit |
d36e9b |
return ret;
|
|
Packit |
d36e9b |
}
|
|
Packit |
d36e9b |
|
|
Packit |
d36e9b |
/*
|
|
Packit |
d36e9b |
* Local Variables:
|
|
Packit |
d36e9b |
* eval: (c-set-style "gnu")
|
|
Packit |
d36e9b |
* End:
|
|
Packit |
d36e9b |
*/
|