]> mj.ucw.cz Git - pciutils.git/blobdiff - lib/nbsd-libpci.c
Unify usage of u8 vs. byte.
[pciutils.git] / lib / nbsd-libpci.c
index 60ba57530ba7cc9e86c63851430b9a2bf37f3053..2d24c4cee69d96c92b421c126999adf1bede471b 100644 (file)
@@ -4,6 +4,7 @@
  *
  *     Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
  *      Copyright (c) 2002 Quentin Garnier <cube@cubidou.net>
+ *     Copyright (c) 2002 Martin Mares <mj@ucw.cz>
  *
  *     Can be freely distributed and used under the terms of the GNU GPL.
  */
 static void
 nbsd_config(struct pci_access *a)
 {
-  a->method_params[PCI_ACCESS_NBSD_LIBPCI] = PATH_NBSD_DEVICE;
+  pci_define_param(a, "nbsd.path", PCI_PATH_NBSD_DEVICE, "Path to the NetBSD PCI device");
 }
 
 static int
 nbsd_detect(struct pci_access *a)
 {
-  char *name = a->method_params[PCI_ACCESS_NBSD_LIBPCI];
+  char *name = pci_get_param(a, "nbsd.path");
 
   if (access(name, R_OK))
     {
       a->warning("Cannot open %s", name);
       return 0;
     }
+
+  if (!access(name, W_OK))
+    a->writeable = O_RDWR;
   a->debug("...using %s", name);
   return 1;
 }
@@ -44,13 +48,12 @@ nbsd_detect(struct pci_access *a)
 static void
 nbsd_init(struct pci_access *a)
 {
-  char *name = a->method_params[PCI_ACCESS_NBSD_LIBPCI];
+  char *name = pci_get_param(a, "nbsd.path");
+  int mode = a->writeable ? O_RDWR : O_RDONLY;
 
-  a->fd = open(name, O_RDWR, 0);
+  a->fd = open(name, mode, 0);
   if (a->fd < 0)
-    {
-      a->error("nbsd_init: %s open failed", name);
-    }
+    a->error("nbsd_init: %s open failed", name);
 }
 
 static void
@@ -63,26 +66,30 @@ static int
 nbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
 {
   pcireg_t val;
+  int shift;
 
   if (!(len == 1 || len == 2 || len == 4))
-    {
-      return pci_generic_block_read(d, pos, buf, len);
-    }
+    return pci_generic_block_read(d, pos, buf, len);
+
+  if (pos >= 256)
+    return 0;
+
+  shift = 8*(pos % 4);
+  pos &= ~3;
 
-       
   if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
     d->access->error("nbsd_read: pci_bus_conf_read() failed");
-  
+
   switch (len)
     {
     case 1:
-      buf[0] = (u8) ((val>>16) & 0xff);
+      *buf = val >> shift;
       break;
     case 2:
-      ((u16 *) buf)[0] = (u16) val;
+      *(u16*)buf = cpu_to_le16(val >> shift);
       break;
     case 4:
-      ((u32 *) buf)[0] = (u32) val;
+      *(u32*)buf = cpu_to_le32(val);
       break;
     }
   return 1;
@@ -91,26 +98,42 @@ nbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
 static int
 nbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
 {
-  pcireg_t val;
+  pcireg_t val = 0;
+  int shift;
 
   if (!(len == 1 || len == 2 || len == 4))
+    return pci_generic_block_write(d, pos, buf, len);
+
+  if (pos >= 256)
+    return 0;
+
+  /*
+   *  BEWARE: NetBSD seems to support only 32-bit access, so we have
+   *  to emulate byte and word writes by read-modify-write, possibly
+   *  causing troubles.
+   */
+
+  shift = 8*(pos % 4);
+  pos &= ~3;
+  if (len != 4)
     {
-      return pci_generic_block_write(d, pos, buf, len);
+      if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
+       d->access->error("nbsd_write: pci_bus_conf_read() failed");
     }
 
   switch (len)
     {
     case 1:
-      val = buf[0];
+      val = (val & ~(0xff << shift)) | (buf[0] << shift);
       break;
     case 2:
-      val = ((u16 *) buf)[0];
+      val = (val & ~(0xffff << shift)) | (le16_to_cpu(*(u16*)buf) << shift);
       break;
     case 4:
-      val = ((u32 *) buf)[0];
+      val = le32_to_cpu(*(u32*)buf);
       break;
     }
-  
+
   if (pcibus_conf_write(d->access->fd, d->bus, d->dev, d->func, pos, val) < 0)
     d->access->error("nbsd_write: pci_bus_conf_write() failed");
 
@@ -118,7 +141,8 @@ nbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
 }
 
 struct pci_methods pm_nbsd_libpci = {
-  "NetBSD-libpci",
+  "nbsd-libpci",
+  "NetBSD libpci",
   nbsd_config,
   nbsd_detect,
   nbsd_init,