Blame src/deviceid.c

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
 */