File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / pciutils / lib / access.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Feb 17 15:18:43 2012 UTC (13 years, 1 month ago) by misho
Branches: pciutils, MAIN
CVS tags: v3_1_9, HEAD
pciutils

    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>