1 /************************************************************************** 2 * 3 * isapnp.h -- Etherboot isapnp support for the 3Com 3c515 4 * Written 2002-2003 by Timothy Legge <tlegge (at) rogers.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 * Portions of this code: 21 * Copyright (C) 2001 P.J.H.Fox (fox (at) roestock.demon.co.uk) 22 * 23 * 24 * 25 * REVISION HISTORY: 26 * ================ 27 * Version 0.1 April 26, 2002 TJL 28 * Version 0.2 01/08/2003 TJL Renamed from 3c515_isapnp.h 29 * 30 * 31 * Generalised into an ISAPnP bus that can be used by more than just 32 * the 3c515 by Michael Brown <mbrown (at) fensystems.co.uk> 33 * 34 ***************************************************************************/ 35 36 FILE_LICENCE ( GPL2_OR_LATER ); 37 38 #ifndef ISAPNP_H 39 #define ISAPNP_H 40 41 #include <stdint.h> 42 #include <gpxe/isa_ids.h> 43 #include <gpxe/device.h> 44 #include <gpxe/tables.h> 45 46 /* 47 * ISAPnP constants 48 * 49 */ 50 51 /* Port addresses */ 52 #define ISAPNP_ADDRESS 0x279 53 #define ISAPNP_WRITE_DATA 0xa79 54 #define ISAPNP_READ_PORT_MIN 0x203 55 #define ISAPNP_READ_PORT_START 0x213 /* ISAPnP spec says 0x203, but 56 * Linux ISAPnP starts at 57 * 0x213 with no explanatory 58 * comment. 0x203 probably 59 * clashes with something. */ 60 #define ISAPNP_READ_PORT_MAX 0x3ff 61 #define ISAPNP_READ_PORT_STEP 0x10 /* Can be any multiple of 4 62 * according to the spec, but 63 * since ISA I/O addresses are 64 * allocated in blocks of 16, 65 * it makes no sense to use 66 * any value less than 16. 67 */ 68 69 /* Card select numbers */ 70 #define ISAPNP_CSN_MIN 0x01 71 #define ISAPNP_CSN_MAX 0x0f 72 73 /* Registers */ 74 #define ISAPNP_READPORT 0x00 75 #define ISAPNP_SERIALISOLATION 0x01 76 #define ISAPNP_CONFIGCONTROL 0x02 77 #define ISAPNP_WAKE 0x03 78 #define ISAPNP_RESOURCEDATA 0x04 79 #define ISAPNP_STATUS 0x05 80 #define ISAPNP_CARDSELECTNUMBER 0x06 81 #define ISAPNP_LOGICALDEVICENUMBER 0x07 82 #define ISAPNP_ACTIVATE 0x30 83 #define ISAPNP_IORANGECHECK 0x31 84 #define ISAPNP_IOBASE(n) ( 0x60 + ( (n) * 2 ) ) 85 #define ISAPNP_IRQNO(n) ( 0x70 + ( (n) * 2 ) ) 86 #define ISAPNP_IRQTYPE(n) ( 0x71 + ( (n) * 2 ) ) 87 88 /* Bits in the CONFIGCONTROL register */ 89 #define ISAPNP_CONFIG_RESET ( 1 << 0 ) 90 #define ISAPNP_CONFIG_WAIT_FOR_KEY ( 1 << 1 ) 91 #define ISAPNP_CONFIG_RESET_CSN ( 1 << 2 ) 92 #define ISAPNP_CONFIG_RESET_DRV ( ISAPNP_CONFIG_RESET | \ 93 ISAPNP_CONFIG_WAIT_FOR_KEY | \ 94 ISAPNP_CONFIG_RESET_CSN ) 95 96 /* The LFSR used for the initiation key and for checksumming */ 97 #define ISAPNP_LFSR_SEED 0x6a 98 99 /* Small tags */ 100 #define ISAPNP_IS_SMALL_TAG(tag) ( ! ( (tag) & 0x80 ) ) 101 #define ISAPNP_SMALL_TAG_NAME(tag) ( ( (tag) >> 3 ) & 0xf ) 102 #define ISAPNP_SMALL_TAG_LEN(tag) ( ( (tag) & 0x7 ) ) 103 #define ISAPNP_TAG_PNPVERNO 0x01 104 #define ISAPNP_TAG_LOGDEVID 0x02 105 #define ISAPNP_TAG_COMPATDEVID 0x03 106 #define ISAPNP_TAG_IRQ 0x04 107 #define ISAPNP_TAG_DMA 0x05 108 #define ISAPNP_TAG_STARTDEP 0x06 109 #define ISAPNP_TAG_ENDDEP 0x07 110 #define ISAPNP_TAG_IOPORT 0x08 111 #define ISAPNP_TAG_FIXEDIO 0x09 112 #define ISAPNP_TAG_RSVDSHORTA 0x0A 113 #define ISAPNP_TAG_RSVDSHORTB 0x0B 114 #define ISAPNP_TAG_RSVDSHORTC 0x0C 115 #define ISAPNP_TAG_RSVDSHORTD 0x0D 116 #define ISAPNP_TAG_VENDORSHORT 0x0E 117 #define ISAPNP_TAG_END 0x0F 118 /* Large tags */ 119 #define ISAPNP_IS_LARGE_TAG(tag) ( ( (tag) & 0x80 ) ) 120 #define ISAPNP_LARGE_TAG_NAME(tag) (tag) 121 #define ISAPNP_TAG_MEMRANGE 0x81 122 #define ISAPNP_TAG_ANSISTR 0x82 123 #define ISAPNP_TAG_UNICODESTR 0x83 124 #define ISAPNP_TAG_VENDORLONG 0x84 125 #define ISAPNP_TAG_MEM32RANGE 0x85 126 #define ISAPNP_TAG_FIXEDMEM32RANGE 0x86 127 #define ISAPNP_TAG_RSVDLONG0 0xF0 128 #define ISAPNP_TAG_RSVDLONG1 0xF1 129 #define ISAPNP_TAG_RSVDLONG2 0xF2 130 #define ISAPNP_TAG_RSVDLONG3 0xF3 131 #define ISAPNP_TAG_RSVDLONG4 0xF4 132 #define ISAPNP_TAG_RSVDLONG5 0xF5 133 #define ISAPNP_TAG_RSVDLONG6 0xF6 134 #define ISAPNP_TAG_RSVDLONG7 0xF7 135 #define ISAPNP_TAG_RSVDLONG8 0xF8 136 #define ISAPNP_TAG_RSVDLONG9 0xF9 137 #define ISAPNP_TAG_RSVDLONGA 0xFA 138 #define ISAPNP_TAG_RSVDLONGB 0xFB 139 #define ISAPNP_TAG_RSVDLONGC 0xFC 140 #define ISAPNP_TAG_RSVDLONGD 0xFD 141 #define ISAPNP_TAG_RSVDLONGE 0xFE 142 #define ISAPNP_TAG_RSVDLONGF 0xFF 143 #define ISAPNP_TAG_PSEUDO_NEWBOARD 0x100 144 145 /** An ISAPnP serial identifier */ 146 struct isapnp_identifier { 147 /** Vendor ID */ 148 uint16_t vendor_id; 149 /** Product ID */ 150 uint16_t prod_id; 151 /** Serial number */ 152 uint32_t serial; 153 /** Checksum */ 154 uint8_t checksum; 155 } __attribute__ (( packed )); 156 157 /** An ISAPnP logical device ID structure */ 158 struct isapnp_logdevid { 159 /** Vendor ID */ 160 uint16_t vendor_id; 161 /** Product ID */ 162 uint16_t prod_id; 163 /** Flags */ 164 uint16_t flags; 165 } __attribute__ (( packed )); 166 167 /** An ISAPnP device ID list entry */ 168 struct isapnp_device_id { 169 /** Name */ 170 const char *name; 171 /** Vendor ID */ 172 uint16_t vendor_id; 173 /** Product ID */ 174 uint16_t prod_id; 175 }; 176 177 /** An ISAPnP device */ 178 struct isapnp_device { 179 /** Generic device */ 180 struct device dev; 181 /** Vendor ID */ 182 uint16_t vendor_id; 183 /** Product ID */ 184 uint16_t prod_id; 185 /** I/O address */ 186 uint16_t ioaddr; 187 /** Interrupt number */ 188 uint8_t irqno; 189 /** Card Select Number */ 190 uint8_t csn; 191 /** Logical Device ID */ 192 uint8_t logdev; 193 /** Driver for this device */ 194 struct isapnp_driver *driver; 195 /** Driver-private data 196 * 197 * Use isapnp_set_drvdata() and isapnp_get_drvdata() to access 198 * this field. 199 */ 200 void *priv; 201 /** Driver name */ 202 const char *driver_name; 203 }; 204 205 /** An ISAPnP driver */ 206 struct isapnp_driver { 207 /** ISAPnP ID table */ 208 struct isapnp_device_id *ids; 209 /** Number of entries in ISAPnP ID table */ 210 unsigned int id_count; 211 /** 212 * Probe device 213 * 214 * @v isapnp ISAPnP device 215 * @v id Matching entry in ID table 216 * @ret rc Return status code 217 */ 218 int ( * probe ) ( struct isapnp_device *isapnp, 219 const struct isapnp_device_id *id ); 220 /** 221 * Remove device 222 * 223 * @v isapnp ISAPnP device 224 */ 225 void ( * remove ) ( struct isapnp_device *isapnp ); 226 }; 227 228 /** ISAPnP driver table */ 229 #define ISAPNP_DRIVERS __table ( struct isapnp_driver, "isapnp_drivers" ) 230 231 /** Declare an ISAPnP driver */ 232 #define __isapnp_driver __table_entry ( ISAPNP_DRIVERS, 01 ) 233 234 extern uint16_t isapnp_read_port; 235 236 extern void isapnp_device_activation ( struct isapnp_device *isapnp, 237 int activation ); 238 239 /** 240 * Activate ISAPnP device 241 * 242 * @v isapnp ISAPnP device 243 */ 244 static inline void activate_isapnp_device ( struct isapnp_device *isapnp ) { 245 isapnp_device_activation ( isapnp, 1 ); 246 } 247 248 /** 249 * Deactivate ISAPnP device 250 * 251 * @v isapnp ISAPnP device 252 */ 253 static inline void deactivate_isapnp_device ( struct isapnp_device *isapnp ) { 254 isapnp_device_activation ( isapnp, 0 ); 255 } 256 257 /** 258 * Set ISAPnP driver-private data 259 * 260 * @v isapnp ISAPnP device 261 * @v priv Private data 262 */ 263 static inline void isapnp_set_drvdata ( struct isapnp_device *isapnp, 264 void *priv ) { 265 isapnp->priv = priv; 266 } 267 268 /** 269 * Get ISAPnP driver-private data 270 * 271 * @v isapnp ISAPnP device 272 * @ret priv Private data 273 */ 274 static inline void * isapnp_get_drvdata ( struct isapnp_device *isapnp ) { 275 return isapnp->priv; 276 } 277 278 #endif /* ISAPNP_H */ 279