Annotation of embedaddon/pciutils/lib/access.c, revision 1.1
1.1 ! misho 1: /*
! 2: * The PCI Library -- User Access
! 3: *
! 4: * Copyright (c) 1997--2008 Martin Mares <mj@ucw.cz>
! 5: *
! 6: * Can be freely distributed and used under the terms of the GNU GPL.
! 7: */
! 8:
! 9: #include <stdio.h>
! 10: #include <stdlib.h>
! 11: #include <stdarg.h>
! 12: #include <string.h>
! 13:
! 14: #include "internal.h"
! 15:
! 16: void
! 17: pci_scan_bus(struct pci_access *a)
! 18: {
! 19: a->methods->scan(a);
! 20: }
! 21:
! 22: struct pci_dev *
! 23: pci_alloc_dev(struct pci_access *a)
! 24: {
! 25: struct pci_dev *d = pci_malloc(a, sizeof(struct pci_dev));
! 26:
! 27: memset(d, 0, sizeof(*d));
! 28: d->access = a;
! 29: d->methods = a->methods;
! 30: d->hdrtype = -1;
! 31: if (d->methods->init_dev)
! 32: d->methods->init_dev(d);
! 33: return d;
! 34: }
! 35:
! 36: int
! 37: pci_link_dev(struct pci_access *a, struct pci_dev *d)
! 38: {
! 39: d->next = a->devices;
! 40: a->devices = d;
! 41:
! 42: return 1;
! 43: }
! 44:
! 45: struct pci_dev *
! 46: pci_get_dev(struct pci_access *a, int domain, int bus, int dev, int func)
! 47: {
! 48: struct pci_dev *d = pci_alloc_dev(a);
! 49:
! 50: d->domain = domain;
! 51: d->bus = bus;
! 52: d->dev = dev;
! 53: d->func = func;
! 54: return d;
! 55: }
! 56:
! 57: void pci_free_dev(struct pci_dev *d)
! 58: {
! 59: if (d->methods->cleanup_dev)
! 60: d->methods->cleanup_dev(d);
! 61: pci_free_caps(d);
! 62: pci_mfree(d->phy_slot);
! 63: pci_mfree(d);
! 64: }
! 65:
! 66: static inline void
! 67: pci_read_data(struct pci_dev *d, void *buf, int pos, int len)
! 68: {
! 69: if (pos & (len-1))
! 70: d->access->error("Unaligned read: pos=%02x, len=%d", pos, len);
! 71: if (pos + len <= d->cache_len)
! 72: memcpy(buf, d->cache + pos, len);
! 73: else if (!d->methods->read(d, pos, buf, len))
! 74: memset(buf, 0xff, len);
! 75: }
! 76:
! 77: byte
! 78: pci_read_byte(struct pci_dev *d, int pos)
! 79: {
! 80: byte buf;
! 81: pci_read_data(d, &buf, pos, 1);
! 82: return buf;
! 83: }
! 84:
! 85: word
! 86: pci_read_word(struct pci_dev *d, int pos)
! 87: {
! 88: word buf;
! 89: pci_read_data(d, &buf, pos, 2);
! 90: return le16_to_cpu(buf);
! 91: }
! 92:
! 93: u32
! 94: pci_read_long(struct pci_dev *d, int pos)
! 95: {
! 96: u32 buf;
! 97: pci_read_data(d, &buf, pos, 4);
! 98: return le32_to_cpu(buf);
! 99: }
! 100:
! 101: int
! 102: pci_read_block(struct pci_dev *d, int pos, byte *buf, int len)
! 103: {
! 104: return d->methods->read(d, pos, buf, len);
! 105: }
! 106:
! 107: int
! 108: pci_read_vpd(struct pci_dev *d, int pos, byte *buf, int len)
! 109: {
! 110: return d->methods->read_vpd ? d->methods->read_vpd(d, pos, buf, len) : 0;
! 111: }
! 112:
! 113: static inline int
! 114: pci_write_data(struct pci_dev *d, void *buf, int pos, int len)
! 115: {
! 116: if (pos & (len-1))
! 117: d->access->error("Unaligned write: pos=%02x,len=%d", pos, len);
! 118: if (pos + len <= d->cache_len)
! 119: memcpy(d->cache + pos, buf, len);
! 120: return d->methods->write(d, pos, buf, len);
! 121: }
! 122:
! 123: int
! 124: pci_write_byte(struct pci_dev *d, int pos, byte data)
! 125: {
! 126: return pci_write_data(d, &data, pos, 1);
! 127: }
! 128:
! 129: int
! 130: pci_write_word(struct pci_dev *d, int pos, word data)
! 131: {
! 132: word buf = cpu_to_le16(data);
! 133: return pci_write_data(d, &buf, pos, 2);
! 134: }
! 135:
! 136: int
! 137: pci_write_long(struct pci_dev *d, int pos, u32 data)
! 138: {
! 139: u32 buf = cpu_to_le32(data);
! 140: return pci_write_data(d, &buf, pos, 4);
! 141: }
! 142:
! 143: int
! 144: pci_write_block(struct pci_dev *d, int pos, byte *buf, int len)
! 145: {
! 146: if (pos < d->cache_len)
! 147: {
! 148: int l = (pos + len >= d->cache_len) ? (d->cache_len - pos) : len;
! 149: memcpy(d->cache + pos, buf, l);
! 150: }
! 151: return d->methods->write(d, pos, buf, len);
! 152: }
! 153:
! 154: int
! 155: pci_fill_info_v31(struct pci_dev *d, int flags)
! 156: {
! 157: if (flags & PCI_FILL_RESCAN)
! 158: {
! 159: flags &= ~PCI_FILL_RESCAN;
! 160: d->known_fields = 0;
! 161: pci_free_caps(d);
! 162: }
! 163: if (flags & ~d->known_fields)
! 164: d->known_fields |= d->methods->fill_info(d, flags & ~d->known_fields);
! 165: return d->known_fields;
! 166: }
! 167:
! 168: /* In version 3.1, pci_fill_info got new flags => versioned alias */
! 169: STATIC_ALIAS(int pci_fill_info(struct pci_dev *d, int flags), pci_fill_info_v31(d,flags));
! 170: DEFINE_ALIAS(int pci_fill_info_v30(struct pci_dev *d, int flags), pci_fill_info_v31);
! 171: SYMBOL_VERSION(pci_fill_info_v30, pci_fill_info@LIBPCI_3.0);
! 172: SYMBOL_VERSION(pci_fill_info_v31, pci_fill_info@@LIBPCI_3.1);
! 173:
! 174: void
! 175: pci_setup_cache(struct pci_dev *d, byte *cache, int len)
! 176: {
! 177: d->cache = cache;
! 178: d->cache_len = len;
! 179: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>