Annotation of embedaddon/pciutils/lib/nbsd-libpci.c, revision 1.1
1.1 ! misho 1: /*
! 2: * The PCI Library -- NetBSD libpci access
! 3: * (based on FreeBSD /dev/pci access)
! 4: *
! 5: * Copyright (c) 1999 Jari Kirma <kirma@cs.hut.fi>
! 6: * Copyright (c) 2002 Quentin Garnier <cube@cubidou.net>
! 7: * Copyright (c) 2002 Martin Mares <mj@ucw.cz>
! 8: *
! 9: * Can be freely distributed and used under the terms of the GNU GPL.
! 10: */
! 11:
! 12: /*
! 13: * Read functionality of this driver is briefly tested, and seems
! 14: * to supply basic information correctly, but I promise no more.
! 15: */
! 16:
! 17: #include <fcntl.h>
! 18: #include <string.h>
! 19: #include <unistd.h>
! 20:
! 21: #include <pci.h>
! 22:
! 23: #include "internal.h"
! 24:
! 25: static void
! 26: nbsd_config(struct pci_access *a)
! 27: {
! 28: pci_define_param(a, "nbsd.path", PCI_PATH_NBSD_DEVICE, "Path to the NetBSD PCI device");
! 29: }
! 30:
! 31: static int
! 32: nbsd_detect(struct pci_access *a)
! 33: {
! 34: char *name = pci_get_param(a, "nbsd.path");
! 35:
! 36: if (access(name, R_OK))
! 37: {
! 38: a->warning("Cannot open %s", name);
! 39: return 0;
! 40: }
! 41:
! 42: if (!access(name, W_OK))
! 43: a->writeable = O_RDWR;
! 44: a->debug("...using %s", name);
! 45: return 1;
! 46: }
! 47:
! 48: static void
! 49: nbsd_init(struct pci_access *a)
! 50: {
! 51: char *name = pci_get_param(a, "nbsd.path");
! 52: int mode = a->writeable ? O_RDWR : O_RDONLY;
! 53:
! 54: a->fd = open(name, mode, 0);
! 55: if (a->fd < 0)
! 56: a->error("nbsd_init: %s open failed", name);
! 57: }
! 58:
! 59: static void
! 60: nbsd_cleanup(struct pci_access *a)
! 61: {
! 62: close(a->fd);
! 63: }
! 64:
! 65: static int
! 66: nbsd_read(struct pci_dev *d, int pos, byte *buf, int len)
! 67: {
! 68: pcireg_t val;
! 69: int shift;
! 70:
! 71: if (!(len == 1 || len == 2 || len == 4))
! 72: return pci_generic_block_read(d, pos, buf, len);
! 73:
! 74: if (pos >= 256)
! 75: return 0;
! 76:
! 77: shift = 8*(pos % 4);
! 78: pos &= ~3;
! 79:
! 80: if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
! 81: d->access->error("nbsd_read: pci_bus_conf_read() failed");
! 82:
! 83: switch (len)
! 84: {
! 85: case 1:
! 86: *buf = val >> shift;
! 87: break;
! 88: case 2:
! 89: *(u16*)buf = cpu_to_le16(val >> shift);
! 90: break;
! 91: case 4:
! 92: *(u32*)buf = cpu_to_le32(val);
! 93: break;
! 94: }
! 95: return 1;
! 96: }
! 97:
! 98: static int
! 99: nbsd_write(struct pci_dev *d, int pos, byte *buf, int len)
! 100: {
! 101: pcireg_t val = 0;
! 102: int shift;
! 103:
! 104: if (!(len == 1 || len == 2 || len == 4))
! 105: return pci_generic_block_write(d, pos, buf, len);
! 106:
! 107: if (pos >= 256)
! 108: return 0;
! 109:
! 110: /*
! 111: * BEWARE: NetBSD seems to support only 32-bit access, so we have
! 112: * to emulate byte and word writes by read-modify-write, possibly
! 113: * causing troubles.
! 114: */
! 115:
! 116: shift = 8*(pos % 4);
! 117: pos &= ~3;
! 118: if (len != 4)
! 119: {
! 120: if (pcibus_conf_read(d->access->fd, d->bus, d->dev, d->func, pos, &val) < 0)
! 121: d->access->error("nbsd_write: pci_bus_conf_read() failed");
! 122: }
! 123:
! 124: switch (len)
! 125: {
! 126: case 1:
! 127: val = (val & ~(0xff << shift)) | (buf[0] << shift);
! 128: break;
! 129: case 2:
! 130: val = (val & ~(0xffff << shift)) | (le16_to_cpu(*(u16*)buf) << shift);
! 131: break;
! 132: case 4:
! 133: val = le32_to_cpu(*(u32*)buf);
! 134: break;
! 135: }
! 136:
! 137: if (pcibus_conf_write(d->access->fd, d->bus, d->dev, d->func, pos, val) < 0)
! 138: d->access->error("nbsd_write: pci_bus_conf_write() failed");
! 139:
! 140: return 1;
! 141: }
! 142:
! 143: struct pci_methods pm_nbsd_libpci = {
! 144: "nbsd-libpci",
! 145: "NetBSD libpci",
! 146: nbsd_config,
! 147: nbsd_detect,
! 148: nbsd_init,
! 149: nbsd_cleanup,
! 150: pci_generic_scan,
! 151: pci_generic_fill_info,
! 152: nbsd_read,
! 153: nbsd_write,
! 154: NULL, /* read_vpd */
! 155: NULL, /* dev_init */
! 156: NULL /* dev_cleanup */
! 157: };
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>