kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			608 wiersze
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			608 wiersze
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
| /* sane - Scanner Access Now Easy.
 | |
|    Copyright (C) 1998 Christian Bucher
 | |
|    Copyright (C) 1998 Kling & Hautzinger GmbH
 | |
|    This file is part of the SANE package.
 | |
| 
 | |
|    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.
 | |
| 
 | |
|    As a special exception, the authors of SANE give permission for
 | |
|    additional uses of the libraries contained in this release of SANE.
 | |
| 
 | |
|    The exception is that, if you link a SANE library with other files
 | |
|    to produce an executable, this does not by itself cause the
 | |
|    resulting executable to be covered by the GNU General Public
 | |
|    License.  Your use of that executable is in no way restricted on
 | |
|    account of linking the SANE library code into it.
 | |
| 
 | |
|    This exception does not, however, invalidate any other reasons why
 | |
|    the executable file might be covered by the GNU General Public
 | |
|    License.
 | |
| 
 | |
|    If you submit changes to SANE to the maintainers to be included in
 | |
|    a subsequent release, you agree by submitting the changes that
 | |
|    those changes may be distributed with this exception intact.
 | |
| 
 | |
|    If you write modifications of your own for SANE, it is your choice
 | |
|    whether to permit this exception to apply to your modifications.
 | |
|    If you do not wish that, delete this exception notice.
 | |
| 
 | |
|    This file implements the bi-directional parallel-port
 | |
|    interface.  */
 | |
| 
 | |
| /*
 | |
|   RESTRICTIONS:
 | |
| 
 | |
|   - This interface is very timing sensitive, be carefull with setting
 | |
|     debug levels.
 | |
|  */
 | |
| 
 | |
| #include "../include/sane/config.h"
 | |
| 
 | |
| #define BACKEND_NAME sanei_pio
 | |
| #include "../include/sane/sanei_backend.h"		/* pick up compatibility defs */
 | |
| 
 | |
| #ifdef HAVE_UNISTD_H
 | |
| # include <unistd.h>
 | |
| #endif
 | |
| #include <sys/types.h>
 | |
| 
 | |
| #ifdef HAVE_SYS_IO_H
 | |
| # include <sys/io.h>	/* use where available (glibc 2.x, for example) */
 | |
| # ifndef SANE_HAVE_SYS_IO_H_WITH_INB_OUTB
 | |
| #  define IO_SUPPORT_MISSING
 | |
| # endif
 | |
| #elif HAVE_ASM_IO_H
 | |
| # include <asm/io.h>		/* ugly, but backwards compatible */
 | |
| #elif HAVE_SYS_HW_H
 | |
| # include <sys/hw.h>
 | |
| #elif defined(__i386__)  && defined (__GNUC__)
 | |
| 
 | |
| static __inline__ void
 | |
| outb (u_char value, u_long port)
 | |
| {
 | |
|   __asm__ __volatile__ ("outb %0,%1"::"a" (value), "d" ((u_short) port));
 | |
| }
 | |
| 
 | |
| static __inline__ u_char
 | |
| inb (u_long port)
 | |
| {
 | |
|   u_char value;
 | |
| 
 | |
|   __asm__ __volatile__ ("inb %1,%0":"=a" (value):"d" ((u_short) port));
 | |
|   return value;
 | |
| }
 | |
| 
 | |
| #else
 | |
| # define IO_SUPPORT_MISSING
 | |
| #endif
 | |
| 
 | |
| #include "../include/sane/sane.h"
 | |
| #include "../include/sane/sanei.h"
 | |
| #include "../include/sane/sanei_pio.h"
 | |
| 
 | |
| #if defined (HAVE_IOPERM) && !defined (IO_SUPPORT_MISSING)
 | |
| 
 | |
| #include <errno.h>
 | |
| #include <fcntl.h>
 | |
| #include <limits.h>
 | |
| #include <signal.h>
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/wait.h>
 | |
| #include <unistd.h>
 | |
| #include <time.h>
 | |
| 
 | |
| #include "../include/sane/saneopts.h"
 | |
| 
 | |
| #define PORT_DEV	"/dev/port"
 | |
| 
 | |
| /*    base    278 (lpt2)
 | |
| 
 | |
|               ioport  stat    ctrl
 | |
|       offs    0       1       2
 | |
|       len     1       1       1     */
 | |
| 
 | |
| /* Port definitions (`N' at end begin of label means negated signal) */
 | |
| 
 | |
| #define PIO_IOPORT		0	/* rel. addr io port      */
 | |
| 
 | |
| #define PIO_STAT		1	/* rel. addr status port  */
 | |
| #define PIO_STAT_BUSY		(1<<7)	/*  BUSY   Pin            */
 | |
| #define PIO_STAT_NACKNLG	(1<<6)	/* ~ACKNLG Pin            */
 | |
| 
 | |
| #define PIO_CTRL		2	/* rel. addr control port */
 | |
| #define PIO_CTRL_IE		(1<<5)	/* Input enable           */
 | |
| #define PIO_CTRL_IRQE		(1<<4)	/* enable IRQ             */
 | |
| #define PIO_CTRL_DIR		(1<<3)	/* DIR pin, DIR=1 => out */
 | |
| #define PIO_CTRL_NINIT		(1<<2)	/* reset output           */
 | |
| #define PIO_CTRL_FDXT		(1<<1)	/* Paper FEED (unused)    */
 | |
| #define PIO_CTRL_NSTROBE	(1<<0)	/* strobe pin             */
 | |
| 
 | |
| #define PIO_APPLYRESET		2000	/* reset in 10us at init time  */
 | |
| 
 | |
| #define DL40	 6
 | |
| #define DL50	 7
 | |
| #define DL60	 8
 | |
| #define DL61	 9
 | |
| #define DL70	10
 | |
| #define DL71	11
 | |
| 
 | |
| #ifdef NDEBUG
 | |
| # define DBG_INIT()
 | |
| #endif
 | |
| 
 | |
| typedef struct
 | |
|   {
 | |
|     u_long base;		/* i/o base address */
 | |
|     int fd;			/* >= 0 when using /dev/port */
 | |
|     int max_time_seconds;/* forever if <= 0 */
 | |
|     u_int in_use;		/* port in use? */
 | |
|   }
 | |
| PortRec, *Port;
 | |
| 
 | |
| static PortRec port[] =
 | |
|   {
 | |
|     {0x378, -1, 0, 0},
 | |
|     {0x278, -1, 0, 0}
 | |
|   };
 | |
| 
 | |
| extern int setuid (uid_t);
 | |
| 
 | |
| static inline int pio_outb (const Port port, u_char val, u_long addr);
 | |
| static inline int pio_inb (const Port port, u_char * val, u_long addr);
 | |
| static inline int pio_wait (const Port port, u_char val, u_char mask);
 | |
| static inline void pio_ctrl (const Port port, u_char val);
 | |
| static inline void pio_delay (const Port port);
 | |
| static inline void pio_init (const Port port);
 | |
| static void pio_reset (const Port port);
 | |
| static int pio_write (const Port port, const u_char * buf, int n);
 | |
| static int pio_read (const Port port, u_char * buf, int n);
 | |
| static int pio_open (const char *dev, SANE_Status * status);
 | |
| 
 | |
| static inline int
 | |
| pio_outb (const Port port, u_char val, u_long addr)
 | |
| {
 | |
| 
 | |
|   if (-1 == port->fd)
 | |
|     outb (val, addr);
 | |
|   else
 | |
|     {
 | |
|       if (addr != (u_long)lseek (port->fd, addr, SEEK_SET))
 | |
| 	return -1;
 | |
|       if (1 != write (port->fd, &val, 1))
 | |
| 	return -1;
 | |
|     }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static inline int
 | |
| pio_inb (const Port port, u_char * val, u_long addr)
 | |
| {
 | |
| 
 | |
|   if (-1 == port->fd)
 | |
|     *val = inb (addr);
 | |
|   else
 | |
|     {
 | |
|       if (addr != (u_long)lseek (port->fd, addr, SEEK_SET))
 | |
| 	return -1;
 | |
|       if (1 != read (port->fd, val, 1))
 | |
| 	return -1;
 | |
|     }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static inline int
 | |
| pio_wait (const Port port, u_char val, u_char mask)
 | |
| {
 | |
|   int stat = 0;
 | |
|   long poll_count = 0;
 | |
|   time_t start = time(NULL);
 | |
| 
 | |
|   DBG (DL60, "wait on port 0x%03lx for %02x mask %02x\n",
 | |
|        port->base, (int) val, (int) mask);
 | |
|   DBG (DL61, "   BUSY    %s\n", (mask & PIO_STAT_BUSY) ?
 | |
|        (val & PIO_STAT_BUSY ? "on" : "off") : "-");
 | |
|   DBG (DL61, "   NACKNLG %s\n",
 | |
|        (mask & PIO_STAT_NACKNLG) ? (val & PIO_STAT_NACKNLG ? "on" : "off")
 | |
|        : "-");
 | |
|   for (;;)
 | |
|     {
 | |
|       ++poll_count;
 | |
|       stat = inb (port->base + PIO_STAT);
 | |
|       if ((stat & mask) == (val & mask))
 | |
| 	{
 | |
| 	  DBG (DL60, "got %02x after %ld tries\n", stat, poll_count);
 | |
| 	  DBG (DL61, "   BUSY    %s\n", stat & PIO_STAT_BUSY ? "on" : "off");
 | |
| 	  DBG (DL61, "   NACKNLG %s\n",
 | |
| 	       stat & PIO_STAT_NACKNLG ? "on" : "off");
 | |
| 
 | |
| 	  return stat;
 | |
| 	}
 | |
|       if(poll_count>1000)
 | |
|         {
 | |
|           if ((port->max_time_seconds>0) && (time(NULL)-start >= port->max_time_seconds))
 | |
| 	    break;
 | |
|           usleep(1);
 | |
|         }
 | |
| 
 | |
|     }
 | |
|   DBG (DL60, "got %02x aborting after %ld\n", stat, poll_count);
 | |
|   DBG (DL61, "   BUSY    %s\n", stat & PIO_STAT_BUSY ? "on" : "off");
 | |
|   DBG (DL61, "   NACKNLG %s\n", stat & PIO_STAT_NACKNLG ? "on" : "off");
 | |
|   DBG (1, "polling time out, abort\n");
 | |
|   exit (-1);
 | |
| }
 | |
| 
 | |
| static inline void
 | |
| pio_ctrl (const Port port, u_char val)
 | |
| {
 | |
|   DBG (DL60, "ctrl on port 0x%03lx %02x %02x\n",
 | |
|        port->base, (int) val, (int) val ^ PIO_CTRL_NINIT);
 | |
| 
 | |
|   val ^= PIO_CTRL_NINIT;
 | |
| 
 | |
|   DBG (DL61, "   IE      %s\n", val & PIO_CTRL_IE ? "on" : "off");
 | |
|   DBG (DL61, "   IRQE    %s\n", val & PIO_CTRL_IRQE ? "on" : "off");
 | |
|   DBG (DL61, "   DIR     %s\n", val & PIO_CTRL_DIR ? "on" : "off");
 | |
|   DBG (DL61, "   NINIT   %s\n", val & PIO_CTRL_NINIT ? "on" : "off");
 | |
|   DBG (DL61, "   FDXT    %s\n", val & PIO_CTRL_FDXT ? "on" : "off");
 | |
|   DBG (DL61, "   NSTROBE %s\n", val & PIO_CTRL_NSTROBE ? "on" : "off");
 | |
| 
 | |
|   outb (val, port->base + PIO_CTRL);
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| static inline void
 | |
| pio_delay (const Port port)
 | |
| {
 | |
|   inb (port->base + PIO_STAT);	/* delay */
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| static inline void
 | |
| pio_init (const Port port)
 | |
| {
 | |
|   pio_ctrl (port, PIO_CTRL_IE);
 | |
|   return;
 | |
| }
 | |
| 
 | |
| static void
 | |
| pio_reset (const Port port)
 | |
| {
 | |
|   int n;
 | |
| 
 | |
|   DBG (DL40, "reset\n");
 | |
| 
 | |
|   for (n = PIO_APPLYRESET; --n >= 0;)
 | |
|     {
 | |
|       outb ((PIO_CTRL_IE | PIO_CTRL_NINIT) ^ PIO_CTRL_NINIT,
 | |
| 	    port->base + PIO_CTRL);
 | |
|     }
 | |
|   pio_init (port);
 | |
| 
 | |
|   DBG (DL40, "end reset\n");
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| static int
 | |
| pio_write (const Port port, const u_char * buf, int n)
 | |
| {
 | |
|   int k;
 | |
| 
 | |
|   DBG (DL40, "write\n");
 | |
| 
 | |
|   pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
|   pio_ctrl (port, PIO_CTRL_DIR | PIO_CTRL_IE);		/* praeoutput */
 | |
|   pio_wait (port, PIO_STAT_NACKNLG, PIO_STAT_NACKNLG);	/* acknlg */
 | |
|   pio_ctrl (port, PIO_CTRL_DIR);			/* output */
 | |
| 
 | |
|   for (k = 0; k < n; k++, buf++)
 | |
|     {
 | |
|       DBG (DL40, "write byte\n");
 | |
| #ifdef HANDSHAKE_BUSY
 | |
|       pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
| #else
 | |
|       pio_wait (port, PIO_STAT_BUSY | PIO_STAT_NACKNLG,
 | |
| 		PIO_STAT_BUSY | PIO_STAT_NACKNLG);	/* busyack */
 | |
| #endif
 | |
|       DBG (DL60, "out  %02x\n", (int) *buf);
 | |
| 
 | |
|       outb (*buf, port->base + PIO_IOPORT);
 | |
| 
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_ctrl (port, PIO_CTRL_DIR | PIO_CTRL_NSTROBE);	/* outputstrobe */
 | |
| 
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_ctrl (port, PIO_CTRL_DIR);	/* output */
 | |
| 
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
| 
 | |
|       DBG (DL40, "end write byte\n");
 | |
|     }
 | |
| 
 | |
| #ifdef HANDSHAKE_BUSY
 | |
|   pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
| #else
 | |
|   pio_wait (port, PIO_STAT_BUSY | PIO_STAT_NACKNLG,
 | |
| 	    PIO_STAT_BUSY | PIO_STAT_NACKNLG);	/* busyack */
 | |
| #endif
 | |
| 
 | |
|   pio_ctrl (port, PIO_CTRL_DIR | PIO_CTRL_IE);	/* praeoutput */
 | |
|   DBG (DL40, "end write\n");
 | |
|   return k;
 | |
| }
 | |
| 
 | |
| static int
 | |
| pio_read (const Port port, u_char * buf, int n)
 | |
| {
 | |
|   int k;
 | |
| 
 | |
|   DBG (DL40, "read\n");
 | |
| 
 | |
|   pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
|   pio_ctrl (port, PIO_CTRL_IE);	/* input */
 | |
| 
 | |
|   for (k = 0; k < n; k++, buf++)
 | |
|     {
 | |
|       DBG (DL40, "read byte\n");
 | |
| 
 | |
| #ifdef HANDSHAKE_BUSY
 | |
|       pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
| #else
 | |
|       pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY | PIO_STAT_NACKNLG);
 | |
|       /* busynack */
 | |
| #endif
 | |
|       pio_ctrl (port, PIO_CTRL_IE | PIO_CTRL_NSTROBE);	/* inputstrobe */
 | |
| 
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_delay (port);
 | |
|       pio_ctrl (port, PIO_CTRL_IE);	/* input */
 | |
| #ifdef HANDSHAKE_BUSY
 | |
|       pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
| #else
 | |
|       pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY | PIO_STAT_NACKNLG);
 | |
|       /* busynack */
 | |
| #endif
 | |
| 
 | |
|       *buf = inb (port->base + PIO_IOPORT);
 | |
|       DBG (DL60, "in   %02x\n", (int) *buf);
 | |
|       DBG (DL40, "end read byte\n");
 | |
|     }
 | |
| 
 | |
|   pio_wait (port, PIO_STAT_BUSY, PIO_STAT_BUSY);	/* busy */
 | |
|   pio_ctrl (port, PIO_CTRL_IE);	/* input */
 | |
|   DBG (DL40, "end read\n");
 | |
|   return k;
 | |
| }
 | |
| 
 | |
| /*
 | |
|      Open the device, <dev> must contain a valid port number (as string).
 | |
|  */
 | |
| 
 | |
| static int
 | |
| pio_open (const char *dev, SANE_Status * status)
 | |
| {
 | |
|   static int first_time = 1;
 | |
|   u_long base;
 | |
|   int n;
 | |
| 
 | |
|   if (first_time)
 | |
|     {
 | |
|       first_time = 0;
 | |
| 
 | |
|       DBG_INIT ();
 | |
|       /* set root uid */
 | |
|       if (0 > setuid (0))
 | |
| 	{
 | |
| 	  DBG (1, "sanei_pio_open: setuid failed: errno = %d\n", errno);
 | |
| 	  *status = SANE_STATUS_INVAL;
 | |
| 	  return -1;
 | |
| 	}
 | |
|     }
 | |
|   /* read port number */
 | |
|   {
 | |
|     char *end;
 | |
| 
 | |
|     base = strtol (dev, &end, 0);
 | |
| 
 | |
|     if ((end == dev) || *end)
 | |
|       {
 | |
| 	DBG (1, "sanei_pio_open: `%s' is not a valid port number\n", dev);
 | |
| 	*status = SANE_STATUS_INVAL;
 | |
| 	return -1;
 | |
|       }
 | |
|   }
 | |
| 
 | |
|   if (0 == base)
 | |
|     {
 | |
|       DBG (1, "sanei_pio_open: 0x%03lx is not a valid base address\n", base);
 | |
|       *status = SANE_STATUS_INVAL;
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|   for (n = 0; n < NELEMS (port); n++)
 | |
|     if (port[n].base == base)
 | |
|       break;
 | |
| 
 | |
|   if (NELEMS (port) <= n)
 | |
|     {
 | |
|       DBG (1, "sanei_pio_open: 0x%03lx is not a valid base address\n", base);
 | |
|       *status = SANE_STATUS_INVAL;
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|   if (port[n].in_use)
 | |
|     {
 | |
|       DBG (1, "sanei_pio_open: port 0x%03lx is already in use\n", base);
 | |
|       *status = SANE_STATUS_DEVICE_BUSY;
 | |
|       return -1;
 | |
|     }
 | |
|   port[n].base = base;
 | |
|   port[n].fd = -1;
 | |
|   port[n].max_time_seconds = 10;
 | |
|   port[n].in_use = 1;
 | |
| 
 | |
|   if (ioperm (port[n].base, 3, 1))
 | |
|     {
 | |
|       DBG (1, "sanei_pio_open: cannot get io privilege for port 0x%03lx\n",
 | |
| 	   port[n].base);
 | |
|       *status = SANE_STATUS_IO_ERROR;
 | |
|       return -1;
 | |
|     }
 | |
| 
 | |
|   pio_reset (&port[n]);
 | |
| 
 | |
|   *status = SANE_STATUS_GOOD;
 | |
|   return n;
 | |
| }
 | |
| 
 | |
| SANE_Status
 | |
| sanei_pio_open (const char *dev, int *fdp)
 | |
| {
 | |
|   SANE_Status status;
 | |
| 
 | |
|   *fdp = pio_open (dev, &status);
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| void
 | |
| sanei_pio_close (int fd)
 | |
| {
 | |
|   Port p = port + fd;
 | |
| 
 | |
|   if ((0 > fd) && (NELEMS (port) <= fd))
 | |
|     return;
 | |
| 
 | |
|   if (!p->in_use)
 | |
|     return;
 | |
| 
 | |
|   if (-1 != p->fd)
 | |
|     {
 | |
|       close (p->fd);
 | |
|       p->fd = -1;
 | |
|     }
 | |
| 
 | |
|   p->in_use = 0;
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| int
 | |
| sanei_pio_read (int fd, u_char * buf, int n)
 | |
| {
 | |
|   if ((0 > fd) && (NELEMS (port) <= fd))
 | |
|     return -1;
 | |
| 
 | |
|   if (!port[fd].in_use)
 | |
|     return -1;
 | |
| 
 | |
|   return pio_read (&port[fd], buf, n);
 | |
| }
 | |
| 
 | |
| int
 | |
| sanei_pio_write (int fd, const u_char * buf, int n)
 | |
| {
 | |
|   if ((0 > fd) && (NELEMS (port) <= fd))
 | |
|     return -1;
 | |
| 
 | |
|   if (!port[fd].in_use)
 | |
|     return -1;
 | |
| 
 | |
|   return pio_write (&port[fd], buf, n);
 | |
| }
 | |
| 
 | |
| #else /* !HAVE_IOPERM */
 | |
| 
 | |
| #ifdef __BEOS__
 | |
| 
 | |
| #include <fcntl.h>
 | |
| 
 | |
| SANE_Status
 | |
| sanei_pio_open (const char *dev, int *fdp)
 | |
| {
 | |
| 	int fp;
 | |
| 
 | |
| 	/* open internal parallel port */
 | |
| 	fp=open("/dev/parallel/parallel1",O_RDWR);
 | |
| 
 | |
|   	*fdp=fp;
 | |
|   	if(fp<0) return SANE_STATUS_INVAL;
 | |
|   	return(SANE_STATUS_GOOD);
 | |
| }
 | |
| 
 | |
| 
 | |
| void
 | |
| sanei_pio_close (int fd)
 | |
| {
 | |
| 	close(fd);
 | |
| 	return;
 | |
| }
 | |
| 
 | |
| int
 | |
| sanei_pio_read (int fd, u_char * buf, int n)
 | |
| {
 | |
| 	return(read(fd,buf,n));
 | |
| }
 | |
| 
 | |
| int
 | |
| sanei_pio_write (int fd, const u_char * buf, int n)
 | |
| {
 | |
|   	return(write(fd,buf,n));
 | |
| }
 | |
| 
 | |
| #else /* !__BEOS__ */
 | |
| 
 | |
| SANE_Status
 | |
| sanei_pio_open (const char *dev, int *fdp)
 | |
| {
 | |
|   *fdp = -1;
 | |
|   return SANE_STATUS_INVAL;
 | |
| }
 | |
| 
 | |
| 
 | |
| void
 | |
| sanei_pio_close (int fd)
 | |
| {
 | |
|   return;
 | |
| }
 | |
| 
 | |
| int
 | |
| sanei_pio_read (int fd, u_char * buf, int n)
 | |
| {
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| int
 | |
| sanei_pio_write (int fd, const u_char * buf, int n)
 | |
| {
 | |
|   return -1;
 | |
| }
 | |
| #endif /* __BEOS__ */
 | |
| 
 | |
| #endif /* !HAVE_IOPERM */
 |