
/** linux/pci.h overrides **/
struct pci_dev<`a::A> {
  struct list_head global_list;	/* node in list of all PCI devices */
  struct list_head bus_list;	/* node in per-bus list */
  struct pci_bus<`a>  *bus;		/* bus this device is on */
  struct pci_bus<`a>  *subordinate;	/* bus this device bridges to */

  void		*sysdata;	/* hook for sys-specific extension */
  struct proc_dir_entry *procent;	/* device entry in /proc/bus/pci */

  unsigned int	devfn;		/* encoded device & function index */
  unsigned short	vendor;
  unsigned short	device;
  unsigned short	subsystem_vendor;
  unsigned short	subsystem_device;
  unsigned int	class;		/* 3 bytes: (base,sub,prog-if) */
  u8		hdr_type;	/* PCI header type (`multi' flag masked out) */
  u8		rom_base_reg;	/* which config register controls the ROM */

  struct pci_driver<`a> *driver;	/* which driver has allocated this device */
  `a              *driver_data;	/* data private to the driver */
  u64		dma_mask;	/* Mask of the bits of bus address this
				   device implements.  Normally this is
				   0xffffffff.  You only need to change
				   this if your device has broken DMA
				   or supports 64-bit transfers.  */

  u32             current_state;  /* Current operating state. In ACPI-speak,
				     this is D0-D3, D0 being fully functional,
				     and D3 being off. */

  /* device is compatible with these IDs */
  unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE];
  unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE];

  /*
   * Instead of touching interrupt line and base address registers
   * directly, use the values stored here. They might be different!
   */
  unsigned int	irq;
  struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */
  struct resource dma_resource[DEVICE_COUNT_DMA];
  struct resource irq_resource[DEVICE_COUNT_IRQ];

  char		name[90]@zeroterm;	/* device name */
  char		slot_name[8]@zeroterm;	/* slot name */
  int		active;		/* ISAPnP: device is active */
  int		ro;		/* ISAPnP: read only */
  unsigned short	regs;		/* ISAPnP: supported registers */

  /* These fields are used by common fixups */
  unsigned short	transparent;	/* Transparent PCI bridge */ //skip width

  int (*prepare)(struct pci_dev<`a> *dev);	/* ISAPnP hooks */
  int (*activate)(struct pci_dev<`a> *dev);
  int (*deactivate)(struct pci_dev<`a> *dev);
};
//recursive polymorphism requires manual
struct pci_bus<`a::A> {
	struct list_head node;		/* node in list of buses */
	struct pci_bus<`a> *parent;	/* parent bus this bridge is on */
	struct list_head children;	/* list of child buses */
	struct list_head devices;	/* list of devices on this bus */
	struct pci_dev<`a>	*self;		/* bridge device as seen by parent */
	struct resource	*resource[4];	/* address space routed to this bus */

	struct pci_ops  *ops;		/* configuration access functions */
	void		*sysdata;	/* hook for sys-specific extension */
	struct proc_dir_entry *procdir;	/* directory entry in /proc/bus/pci */

	unsigned char	number;		/* bus number */
	unsigned char	primary;	/* number of primary bridge */
	unsigned char	secondary;	/* number of secondary bridge */
	unsigned char	subordinate;	/* max number of subordinate buses */

	char		name[48];
	unsigned short	vendor;
	unsigned short	device;
	unsigned int	serial;		/* serial number */
	unsigned char	pnpver;		/* Plug & Play version */
	unsigned char	productver;	/* product version */
	unsigned char	checksum;	/* if zero - checksum passed */
	unsigned char	pad1;
};

struct pci_driver<`a::A> {
  struct list_head node;
  char *@zeroterm name;
  const struct pci_device_id *id_table;
  int (*probe) (struct pci_dev<`a> *dev, const struct pci_device_id * id) __attribute__((no_throw));
  void (*remove) (struct pci_dev<`a> *dev)  __attribute__((no_throw));
  int (*save_state) (struct pci_dev<`a> *dev, u32 state)  __attribute__((no_throw));
  int (*suspend) (struct pci_dev<`a> *dev, u32 state)  __attribute__((no_throw));
  int (*resume) (struct pci_dev<`a> *dev)  __attribute__((no_throw));
  int (*enable_wake) (struct pci_dev<`a> *dev, u32 state, int enable)  __attribute__((no_throw));
};

//void pcibios_fixup_bus(struct pci_bus<`a> *);
static `a* pci_get_drvdata (struct pci_dev<`a> *pdev);
static  void pci_set_drvdata (struct pci_dev<`a> *pdev, `a *`r data) __attribute__((no_throw));
int pci_read_config_byte(struct pci_dev<`a> *dev, int where, u8 *@nozeroterm val);


/* asm/pci.h */
extern u8 *pci_alloc_consistent(struct pci_dev<`a> *hwdev, size_t size,
					   dma_addr_t *dma_handle);
extern void pci_free_consistent(struct pci_dev<`a> *hwdev, size_t size,
                                void *vaddr, dma_addr_t dma_handle);

int pci_register_driver(struct pci_driver<`a> *) __attribute__((no_throw));
void pci_unregister_driver(struct pci_driver<`a> *) __attribute__((no_throw));
int pci_enable_device(struct pci_dev<`a> *dev);
void pci_disable_device(struct pci_dev<`a> *dev);
int pci_set_dma_mask(struct pci_dev<`a> *dev, u64 mask);
void pci_set_master(struct pci_dev<`a> *dev);
int pci_save_state(struct pci_dev<`a> *dev, u32 *buffer);
int pci_set_power_state(struct pci_dev<`a> *dev, int state);
int pci_restore_state(struct pci_dev<`a> *dev, u32 *buffer);
//asm/io.h!!
//static inline u8 *@nozeroterm ioremap (unsigned long offset, unsigned long size);

