]> mj.ucw.cz Git - pciutils.git/commitdiff
Rewrote the pread/pwrite things once again. Use pread and pwrite only when we
authorMartin Mares <mj@ucw.cz>
Tue, 20 Jul 1999 12:13:38 +0000 (12:13 +0000)
committerMartin Mares <mj@ucw.cz>
Fri, 5 May 2006 12:10:11 +0000 (14:10 +0200)
are certain it's safe (i.e., glibc 2.1 on all architectures or any libc on a
i386 where we really know how to use syscalls directly). In all other cases,
emulate it with lseek/read/write.

ChangeLog
Makefile
lib/pci.h
lib/proc.c

index 83fae9bd08e2bd309b64d443caabf3fab2e16289..0bd4151335e8abd46967e7e51baf2c4b5099ea78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 Tue Jul 20 13:25:09 1999  Martin Mares  <mj@albireo.ucw.cz>
 
+       * lib/proc.c: Rewrote the pread/pwrite things once again. Use pread
+       and pwrite only when we are certain it's safe (i.e., glibc 2.1
+       on all architectures or any libc on a i386 where we really know
+       how to use syscalls directly). In all other cases, emulate it
+       with lseek/read/write.
+
        * pci.ids: Some more IDs.
 
 Mon Jul 19 14:10:36 1999  Martin Mares  <mj@albireo.ucw.cz>
index 6d936e22725ba2e04f25451363278614037f409f..f8ad9f1cbd4a34934187458e03b01a4f8b408383 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.18 1999/07/07 11:23:03 mj Exp $
+# $Id: Makefile,v 1.19 1999/07/20 12:13:39 mj Exp $
 # Makefile for Linux PCI Utilities
 # (c) 1998--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
 
@@ -9,10 +9,10 @@ CFLAGS=$(OPT) -Wall -W -Wno-parentheses -Wstrict-prototypes -Werror
 ROOT=/
 PREFIX=/usr
 
-VERSION=2.1-pre4
+VERSION=2.1-pre5
 SUFFIX=
 #SUFFIX=-alpha
-DATE=99-05-19
+DATE=99-07-20
 
 export
 
index 168d9ad6c089976ee86e0980b795372e0f4036f2..4fca73eee34d3ce09c0a1b90e7c8c840771a4e68 100644 (file)
--- a/lib/pci.h
+++ b/lib/pci.h
@@ -1,5 +1,5 @@
 /*
- *     $Id: pci.h,v 1.4 1999/07/07 11:23:11 mj Exp $
+ *     $Id: pci.h,v 1.5 1999/07/20 12:13:40 mj Exp $
  *
  *     The PCI Library
  *
@@ -76,6 +76,7 @@ struct pci_access {
   int fd;                              /* proc: fd */
   int fd_rw;                           /* proc: fd opened read-write */
   struct pci_dev *cached_dev;          /* proc: device the fd is for */
+  int fd_pos;                          /* proc: current position */
 };
 
 /* Initialize PCI access */
index 5edc7b0be7992658f52777ada06080fe6da838a4..9f617c38165930a925d839f8a1de6d8d22fcaad7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *     $Id: proc.c,v 1.4 1999/07/07 11:23:12 mj Exp $
+ *     $Id: proc.c,v 1.5 1999/07/20 12:13:42 mj Exp $
  *
  *     The PCI Library -- Configuration Access via /proc/bus/pci
  *
 
 #include "internal.h"
 
-#include <asm/unistd.h>
-#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 1
-#include <syscall-list.h>
-#endif
-
 /*
- * As libc doesn't support pread/pwrite yet, we have to call them directly
- * or use lseek/read/write instead.
+ *  We'd like to use pread/pwrite for configuration space accesses, but
+ *  unfortunately it isn't simple at all since all libc's until glibc 2.1
+ *  don't define it.
  */
-#if !(defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0)
 
-#if defined(__GLIBC__) && !(defined(__powerpc__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+#if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0
+/* glibc 2.1 or newer -> pread/pwrite supported automatically */
+
+#elif defined(i386) && defined(__GLIBC__)
+/* glibc 2.0 on i386 -> call syscalls directly */
+#include <asm/unistd.h>
+#include <syscall-list.h>
 #ifndef SYS_pread
 #define SYS_pread 180
 #endif
-static int
-pread(unsigned int fd, void *buf, size_t size, loff_t where)
-{
-  return syscall(SYS_pread, fd, buf, size, where);
-}
-
+static int pread(unsigned int fd, void *buf, size_t size, loff_t where)
+{ return syscall(SYS_pread, fd, buf, size, where); }
 #ifndef SYS_pwrite
 #define SYS_pwrite 181
 #endif
-static int
-pwrite(unsigned int fd, void *buf, size_t size, loff_t where)
-{
-  return syscall(SYS_pwrite, fd, buf, size, where);
-}
-#else
+static int pwrite(unsigned int fd, void *buf, size_t size, loff_t where)
+{ return syscall(SYS_pwrite, fd, buf, size, where); }
+
+#elif defined(i386)
+/* old libc on i386 -> call syscalls directly the old way */
+#include <asm/unistd.h>
 static _syscall4(int, pread, unsigned int, fd, void *, buf, size_t, size, loff_t, where);
 static _syscall4(int, pwrite, unsigned int, fd, void *, buf, size_t, size, loff_t, where);
+
+#else
+/* In all other cases we use lseek/read/write instead to be safe */
+#define make_rw_glue(op) \
+       static int do_##op(struct pci_dev *d, int fd, void *buf, size_t size, loff_t where)     \
+       {                                                                                       \
+         struct pci_access *a = d->access;                                                     \
+         int r;                                                                                \
+         if (a->fd_pos != where && lseek(fd, where, SEEK_SET) < 0)                             \
+           return -1;                                                                          \
+         r = op(fd, buf, size);                                                                \
+         if (r < 0)                                                                            \
+           a->fd_pos = -1;                                                                     \
+         else                                                                                  \
+           a->fd_pos = where + r;                                                              \
+         return r;                                                                             \
+       }
+make_rw_glue(read)
+make_rw_glue(write)
+#define HAVE_DO_READ
 #endif
 
+#ifndef HAVE_DO_READ
+#define do_read(d,f,b,l,p) pread(f,b,l,p)
+#define do_write(d,f,b,l,p) pwrite(f,b,l,p)
 #endif
 
 static void
@@ -170,6 +190,7 @@ proc_setup(struct pci_dev *d, int rw)
       if (a->fd < 0)
        a->warning("Cannot open %s", buf);
       a->cached_dev = d;
+      a->fd_pos = 0;
     }
   return a->fd;
 }
@@ -182,7 +203,7 @@ proc_read(struct pci_dev *d, int pos, byte *buf, int len)
 
   if (fd < 0)
     return 0;
-  res = pread(fd, buf, len, pos);
+  res = do_read(d, fd, buf, len, pos);
   if (res < 0)
     {
       d->access->warning("proc_read: read failed: %s", strerror(errno));
@@ -204,7 +225,7 @@ proc_write(struct pci_dev *d, int pos, byte *buf, int len)
 
   if (fd < 0)
     return 0;
-  res = pwrite(fd, buf, len, pos);
+  res = do_write(d, fd, buf, len, pos);
   if (res < 0)
     {
       d->access->warning("proc_write: write failed: %s", strerror(errno));