summaryrefslogtreecommitdiffstats
path: root/src/include/gpxe
diff options
context:
space:
mode:
authorMichael Brown2006-04-24 17:42:49 +0200
committerMichael Brown2006-04-24 17:42:49 +0200
commit824d6ffa7f3d52ce165419356bfe28eaaf36a81b (patch)
treec00a6a1cf46de5248259afd51fe64147e4b311d0 /src/include/gpxe
parentNetwork API now allows for multiple network devices (although the (diff)
downloadipxe-824d6ffa7f3d52ce165419356bfe28eaaf36a81b.tar.gz
ipxe-824d6ffa7f3d52ce165419356bfe28eaaf36a81b.tar.xz
ipxe-824d6ffa7f3d52ce165419356bfe28eaaf36a81b.zip
Header rearrangement.
I want to get to the point where any header in include/ reflects a standard user-level header (e.g. a POSIX header), while everything that's specific to gPXE lives in include/gpxe/. Headers that reflect a Linux header (e.g. if_ether.h) should also be in include/gpxe/, with the same name as the Linux header and, preferably, the same names used for the definitions.
Diffstat (limited to 'src/include/gpxe')
-rw-r--r--src/include/gpxe/hello.h4
-rw-r--r--src/include/gpxe/if_arp.h6
-rw-r--r--src/include/gpxe/if_ether.h6
-rw-r--r--src/include/gpxe/in.h13
-rw-r--r--src/include/gpxe/ip.h6
-rw-r--r--src/include/gpxe/iscsi.h6
-rw-r--r--src/include/gpxe/pci.h366
-rw-r--r--src/include/gpxe/pci_ids.h348
-rw-r--r--src/include/gpxe/scsi.h6
-rw-r--r--src/include/gpxe/tables.h229
-rw-r--r--src/include/gpxe/tcp.h6
11 files changed, 971 insertions, 25 deletions
diff --git a/src/include/gpxe/hello.h b/src/include/gpxe/hello.h
index 23ee336f1..de8127bf4 100644
--- a/src/include/gpxe/hello.h
+++ b/src/include/gpxe/hello.h
@@ -1,5 +1,5 @@
-#ifndef _HELLO_H
-#define _HELLO_H
+#ifndef _GPXE_HELLO_H
+#define _GPXE_HELLO_H
/** @file
*
diff --git a/src/include/gpxe/if_arp.h b/src/include/gpxe/if_arp.h
index 31e993dee..5b2503379 100644
--- a/src/include/gpxe/if_arp.h
+++ b/src/include/gpxe/if_arp.h
@@ -1,5 +1,5 @@
-#ifndef _IF_ARP_H
-#define _IF_ARP_H
+#ifndef _GPXE_IF_ARP_H
+#define _GPXE_IF_ARP_H
/** @file
*
@@ -97,4 +97,4 @@ static inline void * arp_target_pa ( struct arphdr *arphdr ) {
return ( arp_target_ha ( arphdr ) + arphdr->ar_hln );
}
-#endif /* _IF_ARP_H */
+#endif /* _GPXE_IF_ARP_H */
diff --git a/src/include/gpxe/if_ether.h b/src/include/gpxe/if_ether.h
index f199220fd..4d35bdf43 100644
--- a/src/include/gpxe/if_ether.h
+++ b/src/include/gpxe/if_ether.h
@@ -1,5 +1,5 @@
-#ifndef _IF_ETHER_H
-#define _IF_ETHER_H
+#ifndef _GPXE_IF_ETHER_H
+#define _GPXE_IF_ETHER_H
#include <stdint.h>
@@ -29,4 +29,4 @@ struct ethhdr {
uint16_t h_protocol;
} __attribute__ ((packed));
-#endif /* _IF_ETHER_H */
+#endif /* _GPXE_IF_ETHER_H */
diff --git a/src/include/gpxe/in.h b/src/include/gpxe/in.h
index e1bdde931..08fd76e2d 100644
--- a/src/include/gpxe/in.h
+++ b/src/include/gpxe/in.h
@@ -1,5 +1,5 @@
-#ifndef _IN_H
-#define _IN_H
+#ifndef _GPXE_IN_H
+#define _GPXE_IN_H
#include <stdint.h>
@@ -8,8 +8,11 @@
#define IP_TCP 6
#define IP_UDP 17
-/* Same after going through htonl */
-#define IP_BROADCAST 0xFFFFFFFF
+#define INADDR_NONE 0xffffffff
+
+#define INADDR_BROADCAST 0xffffffff
+
+#define IN_MULTICAST(addr) ( ( (addr) & 0xf0000000 ) == 0xe0000000 )
struct in_addr {
uint32_t s_addr;
@@ -27,4 +30,4 @@ struct sockaddr_in {
extern int inet_aton ( const char *cp, struct in_addr *inp );
extern char * inet_ntoa ( struct in_addr in );
-#endif /* _IN_H */
+#endif /* _GPXE_IN_H */
diff --git a/src/include/gpxe/ip.h b/src/include/gpxe/ip.h
index 29aae5176..94f906b58 100644
--- a/src/include/gpxe/ip.h
+++ b/src/include/gpxe/ip.h
@@ -1,5 +1,5 @@
-#ifndef _IP_H
-#define _IP_H
+#ifndef _GPXE_IP_H
+#define _GPXE_IP_H
/** @file
*
@@ -17,4 +17,4 @@ extern void set_gateway ( struct in_addr address );
extern void init_tcpip ( void );
extern void run_tcpip ( void );
-#endif /* _IP_H */
+#endif /* _GPXE_IP_H */
diff --git a/src/include/gpxe/iscsi.h b/src/include/gpxe/iscsi.h
index 639da5e57..ab7b0a073 100644
--- a/src/include/gpxe/iscsi.h
+++ b/src/include/gpxe/iscsi.h
@@ -1,5 +1,5 @@
-#ifndef _ISCSI_H
-#define _ISCSI_H
+#ifndef _GPXE_ISCSI_H
+#define _GPXE_ISCSI_H
/** @file
*
@@ -457,4 +457,4 @@ static inline int iscsi_error ( struct iscsi_session *iscsi ) {
return ( iscsi->state == ISCSI_STATE_FAILED );
}
-#endif /* _ISCSI_H */
+#endif /* _GPXE_ISCSI_H */
diff --git a/src/include/gpxe/pci.h b/src/include/gpxe/pci.h
new file mode 100644
index 000000000..4322202cc
--- /dev/null
+++ b/src/include/gpxe/pci.h
@@ -0,0 +1,366 @@
+#ifndef _GPXEPCI_H
+#define _GPXEPCI_H
+
+/*
+** Support for NE2000 PCI clones added David Monro June 1997
+** Generalised for other PCI NICs by Ken Yap July 1997
+**
+** Most of this is taken from:
+**
+** /usr/src/linux/drivers/pci/pci.c
+** /usr/src/linux/include/linux/pci.h
+** /usr/src/linux/arch/i386/bios32.c
+** /usr/src/linux/include/linux/bios32.h
+** /usr/src/linux/drivers/net/ne.c
+*/
+
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2, or (at
+ * your option) any later version.
+ */
+
+#include <stdint.h>
+#include "pci_ids.h"
+
+#define PCI_BUS_TYPE 1
+
+/*
+ * PCI constants
+ *
+ */
+
+#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
+#define PCI_COMMAND_MEM 0x2 /* Enable response in mem space */
+#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
+#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
+#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
+#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
+#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
+#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
+#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
+#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
+#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
+
+
+#define PCI_VENDOR_ID 0x00 /* 16 bits */
+#define PCI_DEVICE_ID 0x02 /* 16 bits */
+#define PCI_COMMAND 0x04 /* 16 bits */
+
+#define PCI_STATUS 0x06 /* 16 bits */
+#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
+#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
+#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
+#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
+#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
+#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
+#define PCI_STATUS_DEVSEL_FAST 0x000
+#define PCI_STATUS_DEVSEL_MEDIUM 0x200
+#define PCI_STATUS_DEVSEL_SLOW 0x400
+#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
+#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
+#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
+#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
+#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
+
+#define PCI_REVISION 0x08 /* 8 bits */
+#define PCI_REVISION_ID 0x08 /* 8 bits */
+#define PCI_CLASS_REVISION 0x08 /* 32 bits */
+#define PCI_CLASS_CODE 0x0b /* 8 bits */
+#define PCI_SUBCLASS_CODE 0x0a /* 8 bits */
+#define PCI_HEADER_TYPE 0x0e /* 8 bits */
+#define PCI_HEADER_TYPE_NORMAL 0
+#define PCI_HEADER_TYPE_BRIDGE 1
+#define PCI_HEADER_TYPE_CARDBUS 2
+
+
+/* Header type 0 (normal devices) */
+#define PCI_CARDBUS_CIS 0x28
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID 0x2e
+
+#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
+#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits */
+#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits */
+#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
+#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
+#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
+
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
+#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
+#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
+
+#ifndef PCI_BASE_ADDRESS_IO_MASK
+#define PCI_BASE_ADDRESS_IO_MASK (~0x03)
+#endif
+#ifndef PCI_BASE_ADDRESS_MEM_MASK
+#define PCI_BASE_ADDRESS_MEM_MASK (~0x0f)
+#endif
+#define PCI_BASE_ADDRESS_SPACE_IO 0x01
+#define PCI_ROM_ADDRESS 0x30 /* 32 bits */
+#define PCI_ROM_ADDRESS_ENABLE 0x01 /* Write 1 to enable ROM,
+ bits 31..11 are address,
+ 10..2 are reserved */
+
+#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
+
+#define PCI_INTERRUPT_LINE 0x3c /* IRQ number (0-15) */
+#define PCI_INTERRUPT_PIN 0x3d /* IRQ pin on PCI bus (A-D) */
+
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
+#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
+#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
+#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
+#define PCI_IO_LIMIT 0x1d
+#define PCI_IO_RANGE_TYPE_MASK 0x0f /* I/O bridging type */
+#define PCI_IO_RANGE_TYPE_16 0x00
+#define PCI_IO_RANGE_TYPE_32 0x01
+#define PCI_IO_RANGE_MASK ~0x0f
+#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
+#define PCI_MEMORY_LIMIT 0x22
+#define PCI_MEMORY_RANGE_TYPE_MASK 0x0f
+#define PCI_MEMORY_RANGE_MASK ~0x0f
+#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT 0x26
+#define PCI_PREF_RANGE_TYPE_MASK 0x0f
+#define PCI_PREF_RANGE_TYPE_32 0x00
+#define PCI_PREF_RANGE_TYPE_64 0x01
+#define PCI_PREF_RANGE_MASK ~0x0f
+#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16 0x32
+/* 0x34 same as for htype 0 */
+/* 0x35-0x3b is reserved */
+#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
+/* 0x3c-0x3d are same as for htype 0 */
+#define PCI_BRIDGE_CONTROL 0x3e
+#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
+#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
+#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */
+#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
+#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
+#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
+#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
+
+#define PCI_CB_CAPABILITY_LIST 0x14
+
+/* Capability lists */
+
+#define PCI_CAP_LIST_ID 0 /* Capability ID */
+#define PCI_CAP_ID_PM 0x01 /* Power Management */
+#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
+#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
+#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
+#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
+#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
+#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
+#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
+#define PCI_CAP_SIZEOF 4
+
+/* Power Management Registers */
+
+#define PCI_PM_PMC 2 /* PM Capabilities Register */
+#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
+#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
+#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
+#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
+#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */
+#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
+#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
+#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
+#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
+#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
+#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
+#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
+#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
+#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
+#define PCI_PM_CTRL 4 /* PM control and status register */
+#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
+#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
+#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
+#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
+#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
+#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
+#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
+#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
+#define PCI_PM_DATA_REGISTER 7 /* (??) */
+#define PCI_PM_SIZEOF 8
+
+/* AGP registers */
+
+#define PCI_AGP_VERSION 2 /* BCD version number */
+#define PCI_AGP_RFU 3 /* Rest of capability flags */
+#define PCI_AGP_STATUS 4 /* Status register */
+#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
+#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
+#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
+#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
+#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
+#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
+#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
+#define PCI_AGP_COMMAND 8 /* Control register */
+#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
+#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
+#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
+#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
+#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
+#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
+#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
+#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
+#define PCI_AGP_SIZEOF 12
+
+/* Slot Identification */
+
+#define PCI_SID_ESR 2 /* Expansion Slot Register */
+#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
+#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
+#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
+
+/* Message Signalled Interrupts registers */
+
+#define PCI_MSI_FLAGS 2 /* Various flags */
+#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
+#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
+#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
+#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
+#define PCI_MSI_RFU 3 /* Rest of capability flags */
+#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
+#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
+#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
+#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
+/*
+ * A location on a PCI bus
+ *
+ */
+struct pci_loc {
+ uint16_t busdevfn;
+};
+
+/*
+ * A physical PCI device
+ *
+ */
+struct pci_device {
+ const char * name;
+ uint32_t membase; /* BAR 1 */
+ uint32_t ioaddr; /* first IO BAR */
+ uint16_t vendor_id, device_id;
+ uint16_t class;
+ uint16_t busdevfn;
+ uint8_t revision;
+ uint8_t irq;
+ void *priv;
+};
+
+/*
+ * Useful busdevfn calculations
+ *
+ */
+#define PCI_BUS(busdevfn) ( ( uint8_t ) ( ( (busdevfn) >> 8 ) & 0xff ) )
+#define PCI_DEV(busdevfn) ( ( uint8_t ) ( ( (busdevfn) >> 3 ) & 0x1f ) )
+#define PCI_FUNC(busdevfn) ( ( uint8_t ) ( (busdevfn) & 0x07 ) )
+#define PCI_FN0(busdevfn) ( ( uint16_t ) ( (busdevfn) & 0xfff8 ) )
+#define PCI_MAX_BUSDEVFN 0xffff
+
+/*
+ * An individual PCI device identified by vendor and device IDs
+ *
+ */
+struct pci_id {
+ unsigned short vendor_id, device_id;
+ const char *name;
+};
+
+/*
+ * PCI_ROM is used to build up entries in a struct pci_id array. It
+ * is also parsed by parserom.pl to generate Makefile rules and files
+ * for rom-o-matic.
+ */
+#define PCI_ROM( _vendor_id, _device_id, _name, _description ) { \
+ .vendor_id = _vendor_id, \
+ .device_id = _device_id, \
+ .name = _name, \
+}
+
+/*
+ * A PCI driver information table, with a device ID (struct pci_id)
+ * table and an optional class.
+ *
+ * Set the class to something other than PCI_NO_CLASS if the driver
+ * can handle an entire class of devices.
+ *
+ */
+struct pci_driver {
+ struct pci_id *ids;
+ unsigned int id_count;
+ uint16_t class;
+};
+#define PCI_NO_CLASS 0
+
+/*
+ * Define a PCI driver.
+ *
+ */
+#define PCI_DRIVER( _name, _ids, _class ) \
+ static struct pci_driver _name = { \
+ .ids = _ids, \
+ .id_count = sizeof ( _ids ) / sizeof ( _ids[0] ), \
+ .class = _class, \
+ }
+
+/*
+ * These are the functions we expect pci_io.c to provide.
+ *
+ */
+extern int pci_read_config_byte ( struct pci_device *pci, unsigned int where,
+ uint8_t *value );
+extern int pci_write_config_byte ( struct pci_device *pci, unsigned int where,
+ uint8_t value );
+extern int pci_read_config_word ( struct pci_device *pci, unsigned int where,
+ uint16_t *value );
+extern int pci_write_config_word ( struct pci_device *pci, unsigned int where,
+ uint16_t value );
+extern int pci_read_config_dword ( struct pci_device *pci, unsigned int where,
+ uint32_t *value );
+extern int pci_write_config_dword ( struct pci_device *pci, unsigned int where,
+ uint32_t value );
+extern unsigned long pci_bus_base ( struct pci_device *pci );
+
+/*
+ * pci_io.c is allowed to overwrite pci_max_bus if it knows what the
+ * highest bus in the system will be.
+ *
+ */
+extern unsigned int pci_max_bus;
+
+/*
+ * Functions in pci.c
+ *
+ */
+extern void adjust_pci_device ( struct pci_device *pci );
+extern unsigned long pci_bar_start ( struct pci_device *pci,
+ unsigned int bar );
+extern unsigned long pci_bar_size ( struct pci_device *pci, unsigned int bar );
+extern int pci_find_capability ( struct pci_device *pci, int capability );
+
+/*
+ * PCI bus global definition
+ *
+ */
+extern struct bus_driver pci_driver;
+
+static inline void pci_set_drvdata ( struct pci_device *pci, void *priv ) {
+ pci->priv = priv;
+}
+
+static inline void * pci_get_drvdata ( struct pci_device *pci ) {
+ return pci->priv;
+}
+
+#endif /* _GPXE_PCI_H */
diff --git a/src/include/gpxe/pci_ids.h b/src/include/gpxe/pci_ids.h
new file mode 100644
index 000000000..075ff96bc
--- /dev/null
+++ b/src/include/gpxe/pci_ids.h
@@ -0,0 +1,348 @@
+#ifndef _GPXE_PCI_IDS_H
+#define _GPXE_PCI_IDS_H
+
+/*
+ * PCI Class, Vendor and Device IDs
+ *
+ * Please keep sorted.
+ */
+
+/* Device classes and subclasses */
+
+#define PCI_CLASS_NOT_DEFINED 0x0000
+#define PCI_CLASS_NOT_DEFINED_VGA 0x0001
+
+#define PCI_BASE_CLASS_STORAGE 0x01
+#define PCI_CLASS_STORAGE_SCSI 0x0100
+#define PCI_CLASS_STORAGE_IDE 0x0101
+#define PCI_CLASS_STORAGE_FLOPPY 0x0102
+#define PCI_CLASS_STORAGE_IPI 0x0103
+#define PCI_CLASS_STORAGE_RAID 0x0104
+#define PCI_CLASS_STORAGE_OTHER 0x0180
+
+#define PCI_BASE_CLASS_NETWORK 0x02
+#define PCI_CLASS_NETWORK_ETHERNET 0x0200
+#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201
+#define PCI_CLASS_NETWORK_FDDI 0x0202
+#define PCI_CLASS_NETWORK_ATM 0x0203
+#define PCI_CLASS_NETWORK_OTHER 0x0280
+
+#define PCI_BASE_CLASS_DISPLAY 0x03
+#define PCI_CLASS_DISPLAY_VGA 0x0300
+#define PCI_CLASS_DISPLAY_XGA 0x0301
+#define PCI_CLASS_DISPLAY_3D 0x0302
+#define PCI_CLASS_DISPLAY_OTHER 0x0380
+
+#define PCI_BASE_CLASS_MULTIMEDIA 0x04
+#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400
+#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
+#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402
+#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480
+
+#define PCI_BASE_CLASS_MEMORY 0x05
+#define PCI_CLASS_MEMORY_RAM 0x0500
+#define PCI_CLASS_MEMORY_FLASH 0x0501
+#define PCI_CLASS_MEMORY_OTHER 0x0580
+
+#define PCI_BASE_CLASS_BRIDGE 0x06
+#define PCI_CLASS_BRIDGE_HOST 0x0600
+#define PCI_CLASS_BRIDGE_ISA 0x0601
+#define PCI_CLASS_BRIDGE_EISA 0x0602
+#define PCI_CLASS_BRIDGE_MC 0x0603
+#define PCI_CLASS_BRIDGE_PCI 0x0604
+#define PCI_CLASS_BRIDGE_PCMCIA 0x0605
+#define PCI_CLASS_BRIDGE_NUBUS 0x0606
+#define PCI_CLASS_BRIDGE_CARDBUS 0x0607
+#define PCI_CLASS_BRIDGE_RACEWAY 0x0608
+#define PCI_CLASS_BRIDGE_OTHER 0x0680
+
+#define PCI_BASE_CLASS_COMMUNICATION 0x07
+#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
+#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701
+#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702
+#define PCI_CLASS_COMMUNICATION_MODEM 0x0703
+#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
+
+#define PCI_BASE_CLASS_SYSTEM 0x08
+#define PCI_CLASS_SYSTEM_PIC 0x0800
+#define PCI_CLASS_SYSTEM_DMA 0x0801
+#define PCI_CLASS_SYSTEM_TIMER 0x0802
+#define PCI_CLASS_SYSTEM_RTC 0x0803
+#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804
+#define PCI_CLASS_SYSTEM_OTHER 0x0880
+
+#define PCI_BASE_CLASS_INPUT 0x09
+#define PCI_CLASS_INPUT_KEYBOARD 0x0900
+#define PCI_CLASS_INPUT_PEN 0x0901
+#define PCI_CLASS_INPUT_MOUSE 0x0902
+#define PCI_CLASS_INPUT_SCANNER 0x0903
+#define PCI_CLASS_INPUT_GAMEPORT 0x0904
+#define PCI_CLASS_INPUT_OTHER 0x0980
+
+#define PCI_BASE_CLASS_DOCKING 0x0a
+#define PCI_CLASS_DOCKING_GENERIC 0x0a00
+#define PCI_CLASS_DOCKING_OTHER 0x0a80
+
+#define PCI_BASE_CLASS_PROCESSOR 0x0b
+#define PCI_CLASS_PROCESSOR_386 0x0b00
+#define PCI_CLASS_PROCESSOR_486 0x0b01
+#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02
+#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10
+#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
+#define PCI_CLASS_PROCESSOR_MIPS 0x0b30
+#define PCI_CLASS_PROCESSOR_CO 0x0b40
+
+#define PCI_BASE_CLASS_SERIAL 0x0c
+#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00
+#define PCI_CLASS_SERIAL_ACCESS 0x0c01
+#define PCI_CLASS_SERIAL_SSA 0x0c02
+#define PCI_CLASS_SERIAL_USB 0x0c03
+#define PCI_CLASS_SERIAL_FIBER 0x0c04
+#define PCI_CLASS_SERIAL_SMBUS 0x0c05
+
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
+
+#define PCI_BASE_CLASS_SATELLITE 0x0f
+#define PCI_CLASS_SATELLITE_TV 0x0f00
+#define PCI_CLASS_SATELLITE_AUDIO 0x0f01
+#define PCI_CLASS_SATELLITE_VOICE 0x0f03
+#define PCI_CLASS_SATELLITE_DATA 0x0f04
+
+#define PCI_BASE_CLASS_CRYPT 0x10
+#define PCI_CLASS_CRYPT_NETWORK 0x1000
+#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001
+#define PCI_CLASS_CRYPT_OTHER 0x1080
+
+#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11
+#define PCI_CLASS_SP_DPIO 0x1100
+#define PCI_CLASS_SP_OTHER 0x1180
+
+#define PCI_CLASS_OTHERS 0xff
+
+/* Vendors */
+
+#define PCI_VENDOR_ID_DYNALINK 0x0675
+#define PCI_VENDOR_ID_BERKOM 0x0871
+#define PCI_VENDOR_ID_COMPAQ 0x0e11
+#define PCI_VENDOR_ID_NCR 0x1000
+#define PCI_VENDOR_ID_LSI_LOGIC 0x1000
+#define PCI_VENDOR_ID_ATI 0x1002
+#define PCI_VENDOR_ID_VLSI 0x1004
+#define PCI_VENDOR_ID_ADL 0x1005
+#define PCI_VENDOR_ID_NS 0x100b
+#define PCI_VENDOR_ID_TSENG 0x100c
+#define PCI_VENDOR_ID_WEITEK 0x100e
+#define PCI_VENDOR_ID_DEC 0x1011
+#define PCI_VENDOR_ID_CIRRUS 0x1013
+#define PCI_VENDOR_ID_IBM 0x1014
+#define PCI_VENDOR_ID_COMPEX2 0x101a
+/* pci.ids says "AT&T GIS (NCR)" */
+#define PCI_VENDOR_ID_WD 0x101c
+#define PCI_VENDOR_ID_AMI 0x101e
+#define PCI_VENDOR_ID_AMD 0x1022
+#define PCI_VENDOR_ID_TRIDENT 0x1023
+#define PCI_VENDOR_ID_AI 0x1025
+#define PCI_VENDOR_ID_DELL 0x1028
+#define PCI_VENDOR_ID_MATROX 0x102B
+#define PCI_VENDOR_ID_CT 0x102c
+#define PCI_VENDOR_ID_MIRO 0x1031
+#define PCI_VENDOR_ID_NEC 0x1033
+#define PCI_VENDOR_ID_FD 0x1036
+#define PCI_VENDOR_ID_SIS 0x1039
+#define PCI_VENDOR_ID_SI 0x1039
+#define PCI_VENDOR_ID_HP 0x103c
+#define PCI_VENDOR_ID_PCTECH 0x1042
+#define PCI_VENDOR_ID_ASUSTEK 0x1043
+#define PCI_VENDOR_ID_DPT 0x1044
+#define PCI_VENDOR_ID_OPTI 0x1045
+#define PCI_VENDOR_ID_ELSA 0x1048
+#define PCI_VENDOR_ID_ELSA 0x1048
+#define PCI_VENDOR_ID_SGS 0x104a
+#define PCI_VENDOR_ID_BUSLOGIC 0x104B
+#define PCI_VENDOR_ID_TI 0x104c
+#define PCI_VENDOR_ID_SONY 0x104d
+#define PCI_VENDOR_ID_OAK 0x104e
+/* Winbond have two vendor IDs! See 0x10ad as well */
+#define PCI_VENDOR_ID_WINBOND2 0x1050
+#define PCI_VENDOR_ID_ANIGMA 0x1051
+#define PCI_VENDOR_ID_EFAR 0x1055
+#define PCI_VENDOR_ID_MOTOROLA 0x1057
+#define PCI_VENDOR_ID_MOTOROLA_OOPS 0x1507
+#define PCI_VENDOR_ID_PROMISE 0x105a
+#define PCI_VENDOR_ID_N9 0x105d
+#define PCI_VENDOR_ID_UMC 0x1060
+#define PCI_VENDOR_ID_X 0x1061
+#define PCI_VENDOR_ID_MYLEX 0x1069
+#define PCI_VENDOR_ID_PICOP 0x1066
+#define PCI_VENDOR_ID_APPLE 0x106b
+#define PCI_VENDOR_ID_YAMAHA 0x1073
+#define PCI_VENDOR_ID_NEXGEN 0x1074
+#define PCI_VENDOR_ID_QLOGIC 0x1077
+#define PCI_VENDOR_ID_CYRIX 0x1078
+#define PCI_VENDOR_ID_LEADTEK 0x107d
+#define PCI_VENDOR_ID_INTERPHASE 0x107e
+#define PCI_VENDOR_ID_CONTAQ 0x1080
+#define PCI_VENDOR_ID_FOREX 0x1083
+#define PCI_VENDOR_ID_OLICOM 0x108d
+#define PCI_VENDOR_ID_SUN 0x108e
+#define PCI_VENDOR_ID_CMD 0x1095
+#define PCI_VENDOR_ID_VISION 0x1098
+#define PCI_VENDOR_ID_BROOKTREE 0x109e
+#define PCI_VENDOR_ID_SIERRA 0x10a8
+#define PCI_VENDOR_ID_SGI 0x10a9
+#define PCI_VENDOR_ID_ACC 0x10aa
+#define PCI_VENDOR_ID_WINBOND 0x10ad
+#define PCI_VENDOR_ID_DATABOOK 0x10b3
+#define PCI_VENDOR_ID_PLX 0x10b5
+#define PCI_VENDOR_ID_MADGE 0x10b6
+#define PCI_VENDOR_ID_3COM 0x10b7
+#define PCI_VENDOR_ID_SMC 0x10b8
+#define PCI_VENDOR_ID_SUNDANCE 0x13F0
+#define PCI_VENDOR_ID_AL 0x10b9
+#define PCI_VENDOR_ID_MITSUBISHI 0x10ba
+#define PCI_VENDOR_ID_SURECOM 0x10bd
+#define PCI_VENDOR_ID_NEOMAGIC 0x10c8
+#define PCI_VENDOR_ID_ASP 0x10cd
+#define PCI_VENDOR_ID_MACRONIX 0x10d9
+#define PCI_VENDOR_ID_TCONRAD 0x10da
+#define PCI_VENDOR_ID_CERN 0x10dc
+#define PCI_VENDOR_ID_NVIDIA 0x10de
+#define PCI_VENDOR_ID_IMS 0x10e0
+#define PCI_VENDOR_ID_TEKRAM2 0x10e1
+#define PCI_VENDOR_ID_TUNDRA 0x10e3
+#define PCI_VENDOR_ID_AMCC 0x10e8
+#define PCI_VENDOR_ID_INTERG 0x10ea
+#define PCI_VENDOR_ID_REALTEK 0x10ec
+#define PCI_VENDOR_ID_XILINX 0x10ee
+#define PCI_VENDOR_ID_TRUEVISION 0x10fa
+#define PCI_VENDOR_ID_INIT 0x1101
+#define PCI_VENDOR_ID_CREATIVE 0x1102
+/* duplicate: ECTIVA */
+#define PCI_VENDOR_ID_ECTIVA 0x1102
+/* duplicate: CREATIVE */
+#define PCI_VENDOR_ID_TTI 0x1103
+#define PCI_VENDOR_ID_VIA 0x1106
+#define PCI_VENDOR_ID_VIATEC 0x1106
+#define PCI_VENDOR_ID_SIEMENS 0x110A
+#define PCI_VENDOR_ID_SMC2 0x1113
+#define PCI_VENDOR_ID_VORTEX 0x1119
+#define PCI_VENDOR_ID_EF 0x111a
+#define PCI_VENDOR_ID_IDT 0x111d
+#define PCI_VENDOR_ID_FORE 0x1127
+#define PCI_VENDOR_ID_IMAGINGTECH 0x112f
+#define PCI_VENDOR_ID_PHILIPS 0x1131
+#define PCI_VENDOR_ID_EICON 0x1133
+#define PCI_VENDOR_ID_CYCLONE 0x113c
+#define PCI_VENDOR_ID_ALLIANCE 0x1142
+#define PCI_VENDOR_ID_SYSKONNECT 0x1148
+#define PCI_VENDOR_ID_VMIC 0x114a
+#define PCI_VENDOR_ID_DIGI 0x114f
+#define PCI_VENDOR_ID_MUTECH 0x1159
+#define PCI_VENDOR_ID_XIRCOM 0x115d
+#define PCI_VENDOR_ID_RENDITION 0x1163
+#define PCI_VENDOR_ID_SERVERWORKS 0x1166
+#define PCI_VENDOR_ID_SBE 0x1176
+#define PCI_VENDOR_ID_TOSHIBA 0x1179
+#define PCI_VENDOR_ID_RICOH 0x1180
+#define PCI_VENDOR_ID_DLINK 0x1186
+#define PCI_VENDOR_ID_ARTOP 0x1191
+#define PCI_VENDOR_ID_ZEITNET 0x1193
+#define PCI_VENDOR_ID_OMEGA 0x119b
+#define PCI_VENDOR_ID_FUJITSU_ME 0x119e
+#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9
+#define PCI_VENDOR_ID_GALILEO 0x11ab
+#define PCI_VENDOR_ID_LINKSYS 0x11ad
+#define PCI_VENDOR_ID_LITEON 0x11ad
+#define PCI_VENDOR_ID_V3 0x11b0
+#define PCI_VENDOR_ID_NP 0x11bc
+#define PCI_VENDOR_ID_ATT 0x11c1
+#define PCI_VENDOR_ID_SPECIALIX 0x11cb
+#define PCI_VENDOR_ID_AURAVISION 0x11d1
+#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4
+#define PCI_VENDOR_ID_IKON 0x11d5
+#define PCI_VENDOR_ID_ZORAN 0x11de
+#define PCI_VENDOR_ID_KINETIC 0x11f4
+#define PCI_VENDOR_ID_COMPEX 0x11f6
+#define PCI_VENDOR_ID_RP 0x11fe
+#define PCI_VENDOR_ID_CYCLADES 0x120e
+#define PCI_VENDOR_ID_ESSENTIAL 0x120f
+#define PCI_VENDOR_ID_O2 0x1217
+#define PCI_VENDOR_ID_3DFX 0x121a
+#define PCI_VENDOR_ID_SIGMADES 0x1236
+#define PCI_VENDOR_ID_CCUBE 0x123f
+#define PCI_VENDOR_ID_AVM 0x1244
+#define PCI_VENDOR_ID_DIPIX 0x1246
+#define PCI_VENDOR_ID_STALLION 0x124d
+#define PCI_VENDOR_ID_OPTIBASE 0x1255
+#define PCI_VENDOR_ID_ESS 0x125d
+#define PCI_VENDOR_ID_HARRIS 0x1260
+#define PCI_VENDOR_ID_SATSAGEM 0x1267
+#define PCI_VENDOR_ID_HUGHES 0x1273
+#define PCI_VENDOR_ID_ENSONIQ 0x1274
+#define PCI_VENDOR_ID_ROCKWELL 0x127A
+#define PCI_VENDOR_ID_DAVICOM 0x1282
+#define PCI_VENDOR_ID_ITE 0x1283
+/* formerly Platform Tech */
+#define PCI_VENDOR_ID_ESS_OLD 0x1285
+#define PCI_VENDOR_ID_ALTEON 0x12ae
+#define PCI_VENDOR_ID_USR 0x12B9
+#define PCI_VENDOR_ID_HOLTEK 0x12c3
+#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4
+#define PCI_VENDOR_ID_PICTUREL 0x12c5
+#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2
+#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0
+#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D
+#define PCI_VENDOR_ID_AUREAL 0x12eb
+#define PCI_VENDOR_ID_CBOARDS 0x1307
+#define PCI_VENDOR_ID_SIIG 0x131f
+#define PCI_VENDOR_ID_ADMTEK 0x1317
+#define PCI_VENDOR_ID_DOMEX 0x134a
+#define PCI_VENDOR_ID_QUATECH 0x135C
+#define PCI_VENDOR_ID_SEALEVEL 0x135e
+#define PCI_VENDOR_ID_HYPERCOPE 0x1365
+#define PCI_VENDOR_ID_KAWASAKI 0x136b
+#define PCI_VENDOR_ID_LMC 0x1376
+#define PCI_VENDOR_ID_NETGEAR 0x1385
+#define PCI_VENDOR_ID_APPLICOM 0x1389
+#define PCI_VENDOR_ID_MOXA 0x1393
+#define PCI_VENDOR_ID_CCD 0x1397
+#define PCI_VENDOR_ID_MICROGATE 0x13c0
+#define PCI_VENDOR_ID_3WARE 0x13C1
+#define PCI_VENDOR_ID_ABOCOM 0x13D1
+#define PCI_VENDOR_ID_CMEDIA 0x13f6
+#define PCI_VENDOR_ID_LAVA 0x1407
+#define PCI_VENDOR_ID_TIMEDIA 0x1409
+#define PCI_VENDOR_ID_OXSEMI 0x1415
+#define PCI_VENDOR_ID_AIRONET 0x14b9
+#define PCI_VENDOR_ID_TITAN 0x14D2
+#define PCI_VENDOR_ID_PANACOM 0x14d4
+#define PCI_VENDOR_ID_BROADCOM 0x14e4
+#define PCI_VENDOR_ID_SYBA 0x1592
+#define PCI_VENDOR_ID_MORETON 0x15aa
+#define PCI_VENDOR_ID_ZOLTRIX 0x15b0
+#define PCI_VENDOR_ID_PDC 0x15e9
+#define PCI_VENDOR_ID_FSC 0x1734
+#define PCI_VENDOR_ID_SYMPHONY 0x1c1c
+#define PCI_VENDOR_ID_TEKRAM 0x1de1
+#define PCI_VENDOR_ID_3DLABS 0x3d3d
+#define PCI_VENDOR_ID_AVANCE 0x4005
+#define PCI_VENDOR_ID_AKS 0x416c
+#define PCI_VENDOR_ID_NETVIN 0x4a14
+#define PCI_VENDOR_ID_S3 0x5333
+#define PCI_VENDOR_ID_DCI 0x6666
+#define PCI_VENDOR_ID_GENROCO 0x5555
+#define PCI_VENDOR_ID_INTEL 0x8086
+#define PCI_VENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e
+#define PCI_VENDOR_ID_KTI 0x8e2e
+#define PCI_VENDOR_ID_ADAPTEC 0x9004
+#define PCI_VENDOR_ID_ADAPTEC2 0x9005
+#define PCI_VENDOR_ID_ATRONICS 0x907f
+#define PCI_VENDOR_ID_HOLTEK2 0x9412
+#define PCI_VENDOR_ID_NETMOS 0x9710
+#define PCI_SUBVENDOR_ID_EXSYS 0xd84d
+#define PCI_VENDOR_ID_TIGERJET 0xe159
+#define PCI_VENDOR_ID_ARK 0xedd8
+
+#endif /* _GPXE_PCI_IDS_H */
diff --git a/src/include/gpxe/scsi.h b/src/include/gpxe/scsi.h
index 05f9010ce..be71bab3d 100644
--- a/src/include/gpxe/scsi.h
+++ b/src/include/gpxe/scsi.h
@@ -1,5 +1,5 @@
-#ifndef _SCSI_H
-#define _SCSI_H
+#ifndef _GPXE_SCSI_H
+#define _GPXE_SCSI_H
#include <stdint.h>
@@ -31,4 +31,4 @@ union scsi_cdb {
char bytes[16];
};
-#endif /* _SCSI_H */
+#endif /* _GPXE_SCSI_H */
diff --git a/src/include/gpxe/tables.h b/src/include/gpxe/tables.h
new file mode 100644
index 000000000..a565eba7d
--- /dev/null
+++ b/src/include/gpxe/tables.h
@@ -0,0 +1,229 @@
+#ifndef _GPXE_TABLES_H
+#define _GPXE_TABLES_H
+
+/** @page ifdef_harmful #ifdef considered harmful
+ *
+ * Overuse of @c #ifdef has long been a problem in Etherboot.
+ * Etherboot provides a rich array of features, but all these features
+ * take up valuable space in a ROM image. The traditional solution to
+ * this problem has been for each feature to have its own @c #ifdef
+ * option, allowing the feature to be compiled in only if desired.
+ *
+ * The problem with this is that it becomes impossible to compile, let
+ * alone test, all possible versions of Etherboot. Code that is not
+ * typically used tends to suffer from bit-rot over time. It becomes
+ * extremely difficult to predict which combinations of compile-time
+ * options will result in code that can even compile and link
+ * correctly.
+ *
+ * To solve this problem, we have adopted a new approach from
+ * Etherboot 5.5 onwards. @c #ifdef is now "considered harmful", and
+ * its use should be minimised. Separate features should be
+ * implemented in separate @c .c files, and should \b always be
+ * compiled (i.e. they should \b not be guarded with a @c #ifdef @c
+ * MY_PET_FEATURE statement). By making (almost) all code always
+ * compile, we avoid the problem of bit-rot in rarely-used code.
+ *
+ * The file config.h, in combination with the @c make command line,
+ * specifies the objects that will be included in any particular build
+ * of Etherboot. For example, suppose that config.h includes the line
+ *
+ * @code
+ *
+ * #define CONSOLE_SERIAL
+ * #define DOWNLOAD_PROTO_TFTP
+ *
+ * @endcode
+ *
+ * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is
+ * built, the options specified in config.h are used to drag in the
+ * relevant objects at link-time. For the above example, serial.o and
+ * tftp.o would be linked in.
+ *
+ * There remains one problem to solve: how do these objects get used?
+ * Traditionally, we had code such as
+ *
+ * @code
+ *
+ * #ifdef CONSOLE_SERIAL
+ * serial_init();
+ * #endif
+ *
+ * @endcode
+ *
+ * in main.c, but this reintroduces @c #ifdef and so is a Bad Idea.
+ * We cannot simply remove the @c #ifdef and make it
+ *
+ * @code
+ *
+ * serial_init();
+ *
+ * @endcode
+ *
+ * because then serial.o would end up always being linked in.
+ *
+ * The solution is to use @link tables.h linker tables @endlink.
+ *
+ */
+
+/** @file
+ *
+ * Linker tables
+ *
+ * Read @ref ifdef_harmful first for some background on the motivation
+ * for using linker tables.
+ *
+ * This file provides macros for dealing with linker-generated tables
+ * of fixed-size symbols. We make fairly extensive use of these in
+ * order to avoid @c #ifdef spaghetti and/or linker symbol pollution.
+ * For example, instead of having code such as
+ *
+ * @code
+ *
+ * #ifdef CONSOLE_SERIAL
+ * serial_init();
+ * #endif
+ *
+ * @endcode
+ *
+ * we make serial.c generate an entry in the initialisation function
+ * table, and then have a function call_init_fns() that simply calls
+ * all functions present in this table. If and only if serial.o gets
+ * linked in, then its initialisation function will be called. We
+ * avoid linker symbol pollution (i.e. always dragging in serial.o
+ * just because of a call to serial_init()) and we also avoid @c
+ * #ifdef spaghetti (having to conditionalise every reference to
+ * functions in serial.c).
+ *
+ * The linker script takes care of assembling the tables for us. All
+ * our table sections have names of the format @c .tbl.NAME.NN where
+ * @c NAME designates the data structure stored in the table (e.g. @c
+ * init_fn) and @c NN is a two-digit decimal number used to impose an
+ * ordering upon the tables if required. @c NN=00 is reserved for the
+ * symbol indicating "table start", and @c NN=99 is reserved for the
+ * symbol indicating "table end".
+ *
+ * As an example, suppose that we want to create a "frobnicator"
+ * feature framework, and allow for several independent modules to
+ * provide frobnicating services. Then we would create a frob.h
+ * header file containing e.g.
+ *
+ * @code
+ *
+ * struct frobnicator {
+ * const char *name; // Name of the frobnicator
+ * void ( *frob ) ( void ); // The frobnicating function itself
+ * };
+ *
+ * #define __frobnicator __table ( frobnicators, 01 )
+ *
+ * @endcode
+ *
+ * Any module providing frobnicating services would look something
+ * like
+ *
+ * @code
+ *
+ * #include "frob.h"
+ *
+ * static void my_frob ( void ) {
+ * // Do my frobnicating
+ * ...
+ * }
+ *
+ * static struct frob my_frobnicator __frobnicator = {
+ * .name = "my_frob",
+ * .frob = my_frob,
+ * };
+ *
+ * @endcode
+ *
+ * The central frobnicator code (frob.c) would use the frobnicating
+ * modules as follows
+ *
+ * @code
+ *
+ * #include "frob.h"
+ *
+ * static struct frob frob_start[0] __table_start ( frobnicators );
+ * static struct frob frob_end[0] __table_end ( frobnicators );
+ *
+ * // Call all linked-in frobnicators
+ * void frob_all ( void ) {
+ * struct frob *frob;
+ *
+ * for ( frob = frob_start ; frob < frob_end ; frob++ ) {
+ * printf ( "Calling frobnicator \"%s\"\n", frob->name );
+ * frob->frob ();
+ * }
+ * }
+ *
+ * @endcode
+ *
+ * See init.h and init.c for a real-life example.
+ *
+ */
+
+#ifdef DOXYGEN
+#define __attribute__(x)
+#endif
+
+#define __table_str(x) #x
+#define __table_section(table,idx) \
+ __section__ ( ".tbl." __table_str(table) "." __table_str(idx) )
+
+#define __table_section_start(table) __table_section(table,00)
+#define __table_section_end(table) __table_section(table,99)
+
+
+/**
+ * Linker table entry.
+ *
+ * Declares a data structure to be part of a linker table. Use as
+ * e.g.
+ *
+ * @code
+ *
+ * static struct my_foo __table ( foo, 01 ) = {
+ * ...
+ * };
+ *
+ * @endcode
+ *
+ */
+#define __table(table,idx) \
+ __attribute__ (( unused, __table_section(table,idx) ))
+
+/**
+ * Linker table start marker.
+ *
+ * Declares a data structure (usually an empty data structure) to be
+ * the start of a linker table. Use as e.g.
+ *
+ * @code
+ *
+ * static struct foo_start[0] __table_start ( foo );
+ *
+ * @endcode
+ *
+ */
+#define __table_start(table) \
+ __attribute__ (( unused, __table_section_start(table) ))
+
+/**
+ * Linker table end marker.
+ *
+ * Declares a data structure (usually an empty data structure) to be
+ * the end of a linker table. Use as e.g.
+ *
+ * @code
+ *
+ * static struct foo_end[0] __table_end ( foo );
+ *
+ * @endcode
+ *
+ */
+#define __table_end(table) \
+ __attribute__ (( unused, __table_section_end(table) ))
+
+#endif /* _GPXE_TABLES_H */
diff --git a/src/include/gpxe/tcp.h b/src/include/gpxe/tcp.h
index bcb153651..0aa209b7c 100644
--- a/src/include/gpxe/tcp.h
+++ b/src/include/gpxe/tcp.h
@@ -1,5 +1,5 @@
-#ifndef _TCP_H
-#define _TCP_H
+#ifndef _GPXE_TCP_H
+#define _GPXE_TCP_H
/** @file
*
@@ -99,4 +99,4 @@ extern void tcp_send ( struct tcp_connection *conn, const void *data,
size_t len );
extern void tcp_close ( struct tcp_connection *conn );
-#endif /* _TCP_H */
+#endif /* _GPXE_TCP_H */