#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <gpxe/io.h>
#include <unistd.h>
#include <gpxe/isapnp.h>
Go to the source code of this file.
Defines | |
| #define | ISAPNP_CARD_ID_FMT "ID %04x:%04x (\"%s\") serial %x" |
| #define | ISAPNP_CARD_ID_DATA(identifier) |
| #define | ISAPNP_DEV_ID_FMT "ID %04x:%04x (\"%s\")" |
| #define | ISAPNP_DEV_ID_DATA(isapnp) |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static void | isapnpbus_remove (struct root_device *rootdev) |
| Remove ISAPnP root bus. | |
| static void | isapnp_write_address (unsigned int address) |
| static void | isapnp_write_data (unsigned int data) |
| static unsigned int | isapnp_read_data (void) |
| static void | isapnp_write_byte (unsigned int address, unsigned int value) |
| static unsigned int | isapnp_read_byte (unsigned int address) |
| static unsigned int | isapnp_read_word (unsigned int address) |
| static void | isapnp_set_read_port (void) |
| Inform cards of a new read port address. | |
| static void | isapnp_serialisolation (void) |
| Enter the Isolation state. | |
| static void | isapnp_wait_for_key (void) |
| Enter the Wait for Key state. | |
| static void | isapnp_reset_csn (void) |
| Reset (i.e. | |
| static void | isapnp_wake (uint8_t csn) |
| Place a specified card into the Config state. | |
| static unsigned int | isapnp_read_resourcedata (void) |
| static unsigned int | isapnp_read_status (void) |
| static void | isapnp_write_csn (unsigned int csn) |
| Assign a Card Select Number to a card, and enter the Config state. | |
| static void | isapnp_logicaldevice (unsigned int logdev) |
| static void | isapnp_activate (unsigned int logdev) |
| static void | isapnp_deactivate (unsigned int logdev) |
| static unsigned int | isapnp_read_iobase (unsigned int index) |
| static unsigned int | isapnp_read_irqno (unsigned int index) |
| static void | isapnp_delay (void) |
| static unsigned int | isapnp_lfsr_next (unsigned int lfsr, unsigned int input_bit) |
| Linear feedback shift register. | |
| static void | isapnp_send_key (void) |
| Send the ISAPnP initiation key. | |
| static unsigned int | isapnp_checksum (struct isapnp_identifier *identifier) |
| Compute ISAPnP identifier checksum. | |
| static unsigned int | isapnp_peek_byte (void) |
| static void | isapnp_peek (void *buf, size_t len) |
| Read resource data. | |
| static int | isapnp_find_tag (unsigned int wanted_tag, void *buf, size_t len) |
| Find a tag within the resource data. | |
| static int | isapnp_find_logdevid (unsigned int logdev, struct isapnp_logdevid *logdevid) |
| Find specified Logical Device ID tag. | |
| static int | isapnp_try_isolate (void) |
| Try isolating ISAPnP cards at the current read port. | |
| static void | isapnp_isolate (void) |
| Find a valid read port and isolate all ISAPnP cards. | |
| void | isapnp_device_activation (struct isapnp_device *isapnp, int activation) |
| Activate or deactivate an ISAPnP device. | |
| static int | isapnp_probe (struct isapnp_device *isapnp) |
| Probe an ISAPnP device. | |
| static void | isapnp_remove (struct isapnp_device *isapnp) |
| Remove an ISAPnP device. | |
| static int | isapnpbus_probe (struct root_device *rootdev) |
| Probe ISAPnP root bus. | |
Variables | |
| uint16_t | isapnp_read_port |
| ISAPnP Read Port address. | |
| static struct root_driver | isapnp_root_driver |
| ISAPnP bus root device driver. | |
| struct root_device isapnp_root_device | __root_device |
| ISAPnP bus root device. | |
Etherboot orignally gained ISAPnP support in a very limited way for the 3c515 NIC. The current implementation is almost a complete rewrite based on the ISAPnP specification, with passing reference to the Linux ISAPnP code.
There can be only one ISAPnP bus in a system. Once the read port is known and all cards have been allocated CSNs, there's nothing to be gained by re-scanning for cards.
External code (e.g. the ISAPnP ROM prefix) may already know the read port address, in which case it can store it in isapnp_read_port. Note that setting the read port address in this way will prevent further isolation from taking place; you should set the read port address only if you know that devices have already been allocated CSNs.
Definition in file isapnp.c.
| #define ISAPNP_CARD_ID_FMT "ID %04x:%04x (\"%s\") serial %x" |
| #define ISAPNP_CARD_ID_DATA | ( | identifier | ) |
Value:
(identifier)->vendor_id, (identifier)->prod_id, \ isa_id_string ( (identifier)->vendor_id, (identifier)->prod_id ), \ (identifier)->serial
Definition at line 85 of file isapnp.c.
Referenced by isapnp_try_isolate().
| #define ISAPNP_DEV_ID_DATA | ( | isapnp | ) |
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static void isapnpbus_remove | ( | struct root_device * | rootdev | ) | [static] |
Remove ISAPnP root bus.
| rootdev | ISAPnP bus root device |
Definition at line 733 of file isapnp.c.
References device::children, isapnp_device::dev, root_device::dev, free(), isapnp_remove(), list_del, list_for_each_entry_safe, and device::siblings.
Referenced by isapnpbus_probe().
00733 { 00734 struct isapnp_device *isapnp; 00735 struct isapnp_device *tmp; 00736 00737 list_for_each_entry_safe ( isapnp, tmp, &rootdev->dev.children, 00738 dev.siblings ) { 00739 isapnp_remove ( isapnp ); 00740 list_del ( &isapnp->dev.siblings ); 00741 free ( isapnp ); 00742 } 00743 }
| static void isapnp_write_address | ( | unsigned int | address | ) | [inline, static] |
Definition at line 94 of file isapnp.c.
References ISAPNP_ADDRESS, and outb.
Referenced by isapnp_read_byte(), isapnp_send_key(), isapnp_serialisolation(), and isapnp_write_byte().
00094 { 00095 outb ( address, ISAPNP_ADDRESS ); 00096 }
| static void isapnp_write_data | ( | unsigned int | data | ) | [inline, static] |
Definition at line 98 of file isapnp.c.
References ISAPNP_WRITE_DATA, and outb.
Referenced by isapnp_write_byte().
00098 { 00099 outb ( data, ISAPNP_WRITE_DATA ); 00100 }
| static unsigned int isapnp_read_data | ( | void | ) | [inline, static] |
Definition at line 102 of file isapnp.c.
References inb, and isapnp_read_port.
Referenced by isapnp_read_byte(), and isapnp_try_isolate().
00102 { 00103 return inb ( isapnp_read_port ); 00104 }
| static void isapnp_write_byte | ( | unsigned int | address, | |
| unsigned int | value | |||
| ) | [inline, static] |
Definition at line 106 of file isapnp.c.
References isapnp_write_address(), and isapnp_write_data().
Referenced by isapnp_activate(), isapnp_deactivate(), isapnp_logicaldevice(), isapnp_reset_csn(), isapnp_set_read_port(), isapnp_wait_for_key(), isapnp_wake(), and isapnp_write_csn().
00107 { 00108 isapnp_write_address ( address ); 00109 isapnp_write_data ( value ); 00110 }
| static unsigned int isapnp_read_byte | ( | unsigned int | address | ) | [inline, static] |
Definition at line 112 of file isapnp.c.
References isapnp_read_data(), and isapnp_write_address().
Referenced by isapnp_read_irqno(), isapnp_read_resourcedata(), isapnp_read_status(), and isapnp_read_word().
00112 { 00113 isapnp_write_address ( address ); 00114 return isapnp_read_data (); 00115 }
| static unsigned int isapnp_read_word | ( | unsigned int | address | ) | [inline, static] |
Definition at line 117 of file isapnp.c.
References isapnp_read_byte().
Referenced by isapnp_read_iobase().
00117 { 00118 /* Yes, they're in big-endian order */ 00119 return ( ( isapnp_read_byte ( address ) << 8 ) 00120 | isapnp_read_byte ( address + 1 ) ); 00121 }
| static void isapnp_set_read_port | ( | void | ) | [inline, static] |
Inform cards of a new read port address.
Definition at line 124 of file isapnp.c.
References isapnp_read_port, ISAPNP_READPORT, and isapnp_write_byte().
Referenced by isapnp_try_isolate().
00124 { 00125 isapnp_write_byte ( ISAPNP_READPORT, ( isapnp_read_port >> 2 ) ); 00126 }
| static void isapnp_serialisolation | ( | void | ) | [inline, static] |
Enter the Isolation state.
Only cards currently in the Sleep state will respond to this command.
Definition at line 134 of file isapnp.c.
References ISAPNP_SERIALISOLATION, and isapnp_write_address().
Referenced by isapnp_try_isolate().
00134 { 00135 isapnp_write_address ( ISAPNP_SERIALISOLATION ); 00136 }
| static void isapnp_wait_for_key | ( | void | ) | [inline, static] |
Enter the Wait for Key state.
All cards will respond to this command, regardless of their current state.
Definition at line 144 of file isapnp.c.
References ISAPNP_CONFIG_WAIT_FOR_KEY, ISAPNP_CONFIGCONTROL, and isapnp_write_byte().
Referenced by isapnp_device_activation(), isapnp_try_isolate(), and isapnpbus_probe().
00144 { 00145 isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY ); 00146 }
| static void isapnp_reset_csn | ( | void | ) | [inline, static] |
Reset (i.e.
remove) Card Select Number.
Only cards currently in the Sleep state will respond to this command.
Definition at line 154 of file isapnp.c.
References ISAPNP_CONFIG_RESET_CSN, ISAPNP_CONFIGCONTROL, and isapnp_write_byte().
Referenced by isapnp_try_isolate().
00154 { 00155 isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN ); 00156 }
| static void isapnp_wake | ( | uint8_t | csn | ) | [inline, static] |
Place a specified card into the Config state.
| csn | Card Select Number |
| None | - |
| None | - |
Definition at line 169 of file isapnp.c.
References ISAPNP_WAKE, and isapnp_write_byte().
Referenced by isapnp_device_activation(), isapnp_try_isolate(), and isapnpbus_probe().
00169 { 00170 isapnp_write_byte ( ISAPNP_WAKE, csn ); 00171 }
| static unsigned int isapnp_read_resourcedata | ( | void | ) | [inline, static] |
Definition at line 173 of file isapnp.c.
References isapnp_read_byte(), and ISAPNP_RESOURCEDATA.
Referenced by isapnp_peek_byte().
00173 { 00174 return isapnp_read_byte ( ISAPNP_RESOURCEDATA ); 00175 }
| static unsigned int isapnp_read_status | ( | void | ) | [inline, static] |
Definition at line 177 of file isapnp.c.
References isapnp_read_byte(), and ISAPNP_STATUS.
Referenced by isapnp_peek_byte().
00177 { 00178 return isapnp_read_byte ( ISAPNP_STATUS ); 00179 }
| static void isapnp_write_csn | ( | unsigned int | csn | ) | [inline, static] |
Assign a Card Select Number to a card, and enter the Config state.
| csn | Card Select Number |
Definition at line 191 of file isapnp.c.
References ISAPNP_CARDSELECTNUMBER, and isapnp_write_byte().
Referenced by isapnp_try_isolate().
00191 { 00192 isapnp_write_byte ( ISAPNP_CARDSELECTNUMBER, csn ); 00193 }
| static void isapnp_logicaldevice | ( | unsigned int | logdev | ) | [inline, static] |
Definition at line 195 of file isapnp.c.
References ISAPNP_LOGICALDEVICENUMBER, and isapnp_write_byte().
Referenced by isapnp_activate(), isapnp_deactivate(), isapnp_device_activation(), and isapnpbus_probe().
00195 { 00196 isapnp_write_byte ( ISAPNP_LOGICALDEVICENUMBER, logdev ); 00197 }
| static void isapnp_activate | ( | unsigned int | logdev | ) | [inline, static] |
Definition at line 199 of file isapnp.c.
References ISAPNP_ACTIVATE, isapnp_logicaldevice(), and isapnp_write_byte().
Referenced by isapnp_device_activation().
00199 { 00200 isapnp_logicaldevice ( logdev ); 00201 isapnp_write_byte ( ISAPNP_ACTIVATE, 1 ); 00202 }
| static void isapnp_deactivate | ( | unsigned int | logdev | ) | [inline, static] |
Definition at line 204 of file isapnp.c.
References ISAPNP_ACTIVATE, isapnp_logicaldevice(), and isapnp_write_byte().
00204 { 00205 isapnp_logicaldevice ( logdev ); 00206 isapnp_write_byte ( ISAPNP_ACTIVATE, 0 ); 00207 }
| static unsigned int isapnp_read_iobase | ( | unsigned int | index | ) | [inline, static] |
Definition at line 209 of file isapnp.c.
References ISAPNP_IOBASE, and isapnp_read_word().
Referenced by isapnpbus_probe().
00209 { 00210 return isapnp_read_word ( ISAPNP_IOBASE ( index ) ); 00211 }
| static unsigned int isapnp_read_irqno | ( | unsigned int | index | ) | [inline, static] |
Definition at line 213 of file isapnp.c.
References ISAPNP_IRQNO, and isapnp_read_byte().
Referenced by isapnpbus_probe().
00213 { 00214 return isapnp_read_byte ( ISAPNP_IRQNO ( index ) ); 00215 }
| static void isapnp_delay | ( | void | ) | [static] |
Definition at line 217 of file isapnp.c.
References udelay().
Referenced by isapnp_device_activation(), isapnp_peek_byte(), isapnp_send_key(), and isapnp_try_isolate().
00217 { 00218 udelay ( 1000 ); 00219 }
| static unsigned int isapnp_lfsr_next | ( | unsigned int | lfsr, | |
| unsigned int | input_bit | |||
| ) | [inline, static] |
Linear feedback shift register.
| lfsr | Current value of the LFSR | |
| input_bit | Current input bit to the LFSR |
| lfsr | Next value of the LFSR |
Definition at line 235 of file isapnp.c.
Referenced by isapnp_checksum(), and isapnp_send_key().
00236 { 00237 register uint8_t lfsr_next; 00238 00239 lfsr_next = lfsr >> 1; 00240 lfsr_next |= ( ( ( lfsr ^ lfsr_next ) ^ input_bit ) ) << 7; 00241 return lfsr_next; 00242 }
| static void isapnp_send_key | ( | void | ) | [static] |
Send the ISAPnP initiation key.
Sending the key causes all ISAPnP cards that are currently in the Wait for Key state to transition into the Sleep state.
Definition at line 250 of file isapnp.c.
References isapnp_delay(), isapnp_lfsr_next(), ISAPNP_LFSR_SEED, and isapnp_write_address().
Referenced by isapnp_device_activation(), isapnp_try_isolate(), and isapnpbus_probe().
00250 { 00251 unsigned int i; 00252 unsigned int lfsr; 00253 00254 isapnp_delay(); 00255 isapnp_write_address ( 0x00 ); 00256 isapnp_write_address ( 0x00 ); 00257 00258 lfsr = ISAPNP_LFSR_SEED; 00259 for ( i = 0 ; i < 32 ; i++ ) { 00260 isapnp_write_address ( lfsr ); 00261 lfsr = isapnp_lfsr_next ( lfsr, 0 ); 00262 } 00263 }
| static unsigned int isapnp_checksum | ( | struct isapnp_identifier * | identifier | ) | [static] |
Compute ISAPnP identifier checksum.
| identifier | ISAPnP identifier |
| checksum | Expected checksum value |
Definition at line 271 of file isapnp.c.
References isapnp_lfsr_next(), and ISAPNP_LFSR_SEED.
Referenced by isapnp_try_isolate().
00271 { 00272 unsigned int i, j; 00273 unsigned int lfsr; 00274 unsigned int byte; 00275 00276 lfsr = ISAPNP_LFSR_SEED; 00277 for ( i = 0 ; i < 8 ; i++ ) { 00278 byte = * ( ( ( uint8_t * ) identifier ) + i ); 00279 for ( j = 0 ; j < 8 ; j++ ) { 00280 lfsr = isapnp_lfsr_next ( lfsr, byte ); 00281 byte >>= 1; 00282 } 00283 } 00284 return lfsr; 00285 }
| static unsigned int isapnp_peek_byte | ( | void | ) | [inline, static] |
Definition at line 292 of file isapnp.c.
References isapnp_delay(), isapnp_read_resourcedata(), and isapnp_read_status().
Referenced by isapnp_find_tag(), and isapnp_peek().
00292 { 00293 unsigned int i; 00294 00295 /* Wait for data to be ready */ 00296 for ( i = 0 ; i < 20 ; i++ ) { 00297 if ( isapnp_read_status() & 0x01 ) { 00298 /* Byte ready - read it */ 00299 return isapnp_read_resourcedata(); 00300 } 00301 isapnp_delay(); 00302 } 00303 /* Data never became ready - return 0xff */ 00304 return 0xff; 00305 }
| static void isapnp_peek | ( | void * | buf, | |
| size_t | len | |||
| ) | [static] |
Read resource data.
| buf | Buffer in which to store data, or NULL | |
| bytes | Number of bytes to read |
Definition at line 316 of file isapnp.c.
References isapnp_peek_byte().
Referenced by isapnp_find_tag(), and isapnpbus_probe().
00316 { 00317 unsigned int i; 00318 unsigned int byte; 00319 00320 for ( i = 0 ; i < len ; i++) { 00321 byte = isapnp_peek_byte(); 00322 if ( buf ) 00323 * ( ( uint8_t * ) buf + i ) = byte; 00324 } 00325 }
| static int isapnp_find_tag | ( | unsigned int | wanted_tag, | |
| void * | buf, | |||
| size_t | len | |||
| ) | [static] |
Find a tag within the resource data.
| wanted_tag | The tag that we're looking for | |
| buf | Buffer in which to store the tag's contents | |
| len | Length of buffer |
| rc | Return status code |
Definition at line 338 of file isapnp.c.
References DBG2, ENOENT, ISAPNP_IS_SMALL_TAG, ISAPNP_LARGE_TAG_NAME, isapnp_peek(), isapnp_peek_byte(), ISAPNP_SMALL_TAG_LEN, ISAPNP_SMALL_TAG_NAME, ISAPNP_TAG_END, and NULL.
Referenced by isapnp_find_logdevid().
00338 { 00339 unsigned int tag; 00340 unsigned int tag_len; 00341 00342 DBG2 ( "ISAPnP read tag" ); 00343 do { 00344 tag = isapnp_peek_byte(); 00345 if ( ISAPNP_IS_SMALL_TAG ( tag ) ) { 00346 tag_len = ISAPNP_SMALL_TAG_LEN ( tag ); 00347 tag = ISAPNP_SMALL_TAG_NAME ( tag ); 00348 } else { 00349 tag_len = ( isapnp_peek_byte() + 00350 ( isapnp_peek_byte() << 8 ) ); 00351 tag = ISAPNP_LARGE_TAG_NAME ( tag ); 00352 } 00353 DBG2 ( " %02x (%02x)", tag, tag_len ); 00354 if ( tag == wanted_tag ) { 00355 if ( len > tag_len ) 00356 len = tag_len; 00357 isapnp_peek ( buf, len ); 00358 DBG2 ( "\n" ); 00359 return 0; 00360 } else { 00361 isapnp_peek ( NULL, tag_len ); 00362 } 00363 } while ( tag != ISAPNP_TAG_END ); 00364 DBG2 ( "\n" ); 00365 return -ENOENT; 00366 }
| static int isapnp_find_logdevid | ( | unsigned int | logdev, | |
| struct isapnp_logdevid * | logdevid | |||
| ) | [static] |
Find specified Logical Device ID tag.
| rc | Return status code |
Definition at line 375 of file isapnp.c.
References isapnp_find_tag(), and ISAPNP_TAG_LOGDEVID.
Referenced by isapnpbus_probe().
00376 { 00377 unsigned int i; 00378 int rc; 00379 00380 for ( i = 0 ; i <= logdev ; i++ ) { 00381 if ( ( rc = isapnp_find_tag ( ISAPNP_TAG_LOGDEVID, logdevid, 00382 sizeof ( *logdevid ) ) ) != 0 ) 00383 return rc; 00384 } 00385 return 0; 00386 }
| static int isapnp_try_isolate | ( | void | ) | [static] |
Try isolating ISAPnP cards at the current read port.
| \>0 | Number of ISAPnP cards found | |
| 0 | There are no ISAPnP cards in the system | |
| \<0 | A conflict was detected; try a new read port |
| None | - |
Definition at line 399 of file isapnp.c.
References isapnp_identifier::checksum, DBG, ISAPNP_CARD_ID_DATA, ISAPNP_CARD_ID_FMT, isapnp_checksum(), isapnp_delay(), isapnp_read_data(), isapnp_read_port, isapnp_reset_csn(), isapnp_send_key(), isapnp_serialisolation(), isapnp_set_read_port(), isapnp_wait_for_key(), isapnp_wake(), isapnp_write_csn(), and memset().
Referenced by isapnp_isolate().
00399 { 00400 struct isapnp_identifier identifier; 00401 unsigned int i, j; 00402 unsigned int seen_55aa, seen_life; 00403 unsigned int csn = 0; 00404 unsigned int data; 00405 unsigned int byte; 00406 00407 DBG ( "ISAPnP attempting isolation at read port %04x\n", 00408 isapnp_read_port ); 00409 00410 /* Place all cards into the Sleep state, whatever state 00411 * they're currently in. 00412 */ 00413 isapnp_wait_for_key(); 00414 isapnp_send_key(); 00415 00416 /* Reset all assigned CSNs */ 00417 isapnp_reset_csn(); 00418 isapnp_delay(); 00419 isapnp_delay(); 00420 00421 /* Place all cards into the Isolation state */ 00422 isapnp_wait_for_key (); 00423 isapnp_send_key(); 00424 isapnp_wake ( 0x00 ); 00425 00426 /* Set the read port */ 00427 isapnp_set_read_port(); 00428 isapnp_delay(); 00429 00430 while ( 1 ) { 00431 00432 /* All cards that do not have assigned CSNs are 00433 * currently in the Isolation state, each time we go 00434 * through this loop. 00435 */ 00436 00437 /* Initiate serial isolation */ 00438 isapnp_serialisolation(); 00439 isapnp_delay(); 00440 00441 /* Read identifier serially via the ISAPnP read port. */ 00442 memset ( &identifier, 0, sizeof ( identifier ) ); 00443 seen_55aa = seen_life = 0; 00444 for ( i = 0 ; i < 9 ; i++ ) { 00445 byte = 0; 00446 for ( j = 0 ; j < 8 ; j++ ) { 00447 data = isapnp_read_data(); 00448 isapnp_delay(); 00449 data = ( ( data << 8 ) | isapnp_read_data() ); 00450 isapnp_delay(); 00451 byte >>= 1; 00452 if ( data != 0xffff ) { 00453 seen_life++; 00454 if ( data == 0x55aa ) { 00455 byte |= 0x80; 00456 seen_55aa++; 00457 } 00458 } 00459 } 00460 *( ( ( uint8_t * ) &identifier ) + i ) = byte; 00461 } 00462 00463 /* If we didn't see any 55aa patterns, stop here */ 00464 if ( ! seen_55aa ) { 00465 if ( csn ) { 00466 DBG ( "ISAPnP found no more cards\n" ); 00467 } else { 00468 if ( seen_life ) { 00469 DBG ( "ISAPnP saw life but no cards, " 00470 "trying new read port\n" ); 00471 csn = -1; 00472 } else { 00473 DBG ( "ISAPnP saw no signs of life, " 00474 "abandoning isolation\n" ); 00475 } 00476 } 00477 break; 00478 } 00479 00480 /* If the checksum was invalid stop here */ 00481 if ( identifier.checksum != isapnp_checksum ( &identifier) ) { 00482 DBG ( "ISAPnP found malformed card " 00483 ISAPNP_CARD_ID_FMT "\n with checksum %02x " 00484 "(should be %02x), trying new read port\n", 00485 ISAPNP_CARD_ID_DATA ( &identifier ), 00486 identifier.checksum, 00487 isapnp_checksum ( &identifier) ); 00488 csn = -1; 00489 break; 00490 } 00491 00492 /* Give the device a CSN */ 00493 csn++; 00494 DBG ( "ISAPnP found card " ISAPNP_CARD_ID_FMT 00495 ", assigning CSN %02x\n", 00496 ISAPNP_CARD_ID_DATA ( &identifier ), csn ); 00497 00498 isapnp_write_csn ( csn ); 00499 isapnp_delay(); 00500 00501 /* Send this card back to Sleep and force all cards 00502 * without a CSN into Isolation state 00503 */ 00504 isapnp_wake ( 0x00 ); 00505 isapnp_delay(); 00506 } 00507 00508 /* Place all cards in Wait for Key state */ 00509 isapnp_wait_for_key(); 00510 00511 /* Return number of cards found */ 00512 if ( csn > 0 ) { 00513 DBG ( "ISAPnP found %d cards at read port %04x\n", 00514 csn, isapnp_read_port ); 00515 } 00516 return csn; 00517 }
| static void isapnp_isolate | ( | void | ) | [static] |
Find a valid read port and isolate all ISAPnP cards.
Definition at line 523 of file isapnp.c.
References isapnp_read_port, ISAPNP_READ_PORT_MAX, ISAPNP_READ_PORT_START, ISAPNP_READ_PORT_STEP, and isapnp_try_isolate().
Referenced by isapnpbus_probe().
00523 { 00524 for ( isapnp_read_port = ISAPNP_READ_PORT_START ; 00525 isapnp_read_port <= ISAPNP_READ_PORT_MAX ; 00526 isapnp_read_port += ISAPNP_READ_PORT_STEP ) { 00527 /* Avoid problematic locations such as the NE2000 00528 * probe space 00529 */ 00530 if ( ( isapnp_read_port >= 0x280 ) && 00531 ( isapnp_read_port <= 0x380 ) ) 00532 continue; 00533 00534 /* If we detect any ISAPnP cards at this location, stop */ 00535 if ( isapnp_try_isolate() >= 0 ) 00536 return; 00537 } 00538 }
| void isapnp_device_activation | ( | struct isapnp_device * | isapnp, | |
| int | activation | |||
| ) |
Activate or deactivate an ISAPnP device.
| None | - |
| None | - |
Definition at line 553 of file isapnp.c.
References isapnp_device::csn, DBG, isapnp_activate(), isapnp_delay(), isapnp_logicaldevice(), isapnp_send_key(), isapnp_wait_for_key(), isapnp_wake(), and isapnp_device::logdev.
Referenced by activate_isapnp_device(), and deactivate_isapnp_device().
00554 { 00555 /* Wake the card and select the logical device */ 00556 isapnp_wait_for_key (); 00557 isapnp_send_key (); 00558 isapnp_wake ( isapnp->csn ); 00559 isapnp_logicaldevice ( isapnp->logdev ); 00560 00561 /* Activate/deactivate the logical device */ 00562 isapnp_activate ( activation ); 00563 isapnp_delay(); 00564 00565 /* Return all cards to Wait for Key state */ 00566 isapnp_wait_for_key (); 00567 00568 DBG ( "ISAPnP %s device %02x:%02x\n", 00569 ( activation ? "activated" : "deactivated" ), 00570 isapnp->csn, isapnp->logdev ); 00571 }
| static int isapnp_probe | ( | struct isapnp_device * | isapnp | ) | [static] |
Probe an ISAPnP device.
| isapnp | ISAPnP device |
| rc | Return status code |
Definition at line 582 of file isapnp.c.
References isapnp_device::csn, DBG, isapnp_device::driver, isapnp_device::driver_name, ENOTTY, for_each_table_entry, id, isapnp_driver::id_count, isapnp_driver::ids, isapnp_device::ioaddr, isapnp_device::irqno, isa_id_string(), ISA_PROD_ID, ISAPNP_DRIVERS, isapnp_device::logdev, isapnp_driver::probe, isapnp_device_id::prod_id, isapnp_device::prod_id, isapnp_device_id::vendor_id, and isapnp_device::vendor_id.
Referenced by isapnpbus_probe().
00582 { 00583 struct isapnp_driver *driver; 00584 struct isapnp_device_id *id; 00585 unsigned int i; 00586 int rc; 00587 00588 DBG ( "Adding ISAPnP device %02x:%02x (%04x:%04x (\"%s\") " 00589 "io %x irq %d)\n", isapnp->csn, isapnp->logdev, 00590 isapnp->vendor_id, isapnp->prod_id, 00591 isa_id_string ( isapnp->vendor_id, isapnp->prod_id ), 00592 isapnp->ioaddr, isapnp->irqno ); 00593 00594 for_each_table_entry ( driver, ISAPNP_DRIVERS ) { 00595 for ( i = 0 ; i < driver->id_count ; i++ ) { 00596 id = &driver->ids[i]; 00597 if ( id->vendor_id != isapnp->vendor_id ) 00598 continue; 00599 if ( ISA_PROD_ID ( id->prod_id ) != 00600 ISA_PROD_ID ( isapnp->prod_id ) ) 00601 continue; 00602 isapnp->driver = driver; 00603 isapnp->driver_name = id->name; 00604 DBG ( "...using driver %s\n", isapnp->driver_name ); 00605 if ( ( rc = driver->probe ( isapnp, id ) ) != 0 ) { 00606 DBG ( "......probe failed\n" ); 00607 continue; 00608 } 00609 return 0; 00610 } 00611 } 00612 00613 DBG ( "...no driver found\n" ); 00614 return -ENOTTY; 00615 }
| static void isapnp_remove | ( | struct isapnp_device * | isapnp | ) | [static] |
Remove an ISAPnP device.
| isapnp | ISAPnP device |
Definition at line 622 of file isapnp.c.
References isapnp_device::csn, DBG, isapnp_device::driver, isapnp_device::logdev, and isapnp_driver::remove.
Referenced by isapnpbus_remove().
00622 { 00623 isapnp->driver->remove ( isapnp ); 00624 DBG ( "Removed ISAPnP device %02x:%02x\n", 00625 isapnp->csn, isapnp->logdev ); 00626 }
| static int isapnpbus_probe | ( | struct root_device * | rootdev | ) | [static] |
Probe ISAPnP root bus.
| rootdev | ISAPnP bus root device |
Definition at line 636 of file isapnp.c.
References device_description::bus_type, BUS_TYPE_ISAPNP, device::children, isapnp_device::csn, device::desc, root_device::dev, isapnp_device::dev, device_description::device, ENOMEM, free(), INIT_LIST_HEAD, device_description::ioaddr, isapnp_device::ioaddr, device_description::irq, isapnp_device::irqno, isapnp_find_logdevid(), isapnp_isolate(), isapnp_logicaldevice(), isapnp_peek(), isapnp_probe(), isapnp_read_iobase(), isapnp_read_irqno(), isapnp_read_port, isapnp_send_key(), isapnp_wait_for_key(), isapnp_wake(), isapnpbus_remove(), list_add, list_del, isapnp_device::logdev, malloc(), memset(), device::name, NULL, device::parent, isapnp_logdevid::prod_id, isapnp_device::prod_id, device::siblings, snprintf(), device_description::vendor, isapnp_logdevid::vendor_id, isapnp_device::vendor_id, and isapnp_identifier::vendor_id.
00636 { 00637 struct isapnp_device *isapnp = NULL; 00638 struct isapnp_identifier identifier; 00639 struct isapnp_logdevid logdevid; 00640 unsigned int csn; 00641 unsigned int logdev; 00642 int rc; 00643 00644 /* Perform isolation if it hasn't yet been done */ 00645 if ( ! isapnp_read_port ) 00646 isapnp_isolate(); 00647 00648 for ( csn = 1 ; csn <= 0xff ; csn++ ) { 00649 for ( logdev = 0 ; logdev <= 0xff ; logdev++ ) { 00650 00651 /* Allocate struct isapnp_device */ 00652 if ( ! isapnp ) 00653 isapnp = malloc ( sizeof ( *isapnp ) ); 00654 if ( ! isapnp ) { 00655 rc = -ENOMEM; 00656 goto err; 00657 } 00658 memset ( isapnp, 0, sizeof ( *isapnp ) ); 00659 isapnp->csn = csn; 00660 isapnp->logdev = logdev; 00661 00662 /* Wake the card */ 00663 isapnp_wait_for_key(); 00664 isapnp_send_key(); 00665 isapnp_wake ( csn ); 00666 00667 /* Read the card identifier */ 00668 isapnp_peek ( &identifier, sizeof ( identifier ) ); 00669 00670 /* No card with this CSN; stop here */ 00671 if ( identifier.vendor_id & 0x80 ) 00672 goto done; 00673 00674 /* Find the Logical Device ID tag */ 00675 if ( ( rc = isapnp_find_logdevid ( logdev, 00676 &logdevid ) ) != 0){ 00677 /* No more logical devices; go to next CSN */ 00678 break; 00679 } 00680 00681 /* Select the logical device */ 00682 isapnp_logicaldevice ( logdev ); 00683 00684 /* Populate struct isapnp_device */ 00685 isapnp->vendor_id = logdevid.vendor_id; 00686 isapnp->prod_id = logdevid.prod_id; 00687 isapnp->ioaddr = isapnp_read_iobase ( 0 ); 00688 isapnp->irqno = isapnp_read_irqno ( 0 ); 00689 00690 /* Return all cards to Wait for Key state */ 00691 isapnp_wait_for_key(); 00692 00693 /* Add to device hierarchy */ 00694 snprintf ( isapnp->dev.name, 00695 sizeof ( isapnp->dev.name ), 00696 "ISAPnP%02x:%02x", csn, logdev ); 00697 isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP; 00698 isapnp->dev.desc.vendor = isapnp->vendor_id; 00699 isapnp->dev.desc.device = isapnp->prod_id; 00700 isapnp->dev.desc.ioaddr = isapnp->ioaddr; 00701 isapnp->dev.desc.irq = isapnp->irqno; 00702 isapnp->dev.parent = &rootdev->dev; 00703 list_add ( &isapnp->dev.siblings, 00704 &rootdev->dev.children ); 00705 INIT_LIST_HEAD ( &isapnp->dev.children ); 00706 00707 /* Look for a driver */ 00708 if ( isapnp_probe ( isapnp ) == 0 ) { 00709 /* isapnpdev registered, we can drop our ref */ 00710 isapnp = NULL; 00711 } else { 00712 /* Not registered; re-use struct */ 00713 list_del ( &isapnp->dev.siblings ); 00714 } 00715 } 00716 } 00717 00718 done: 00719 free ( isapnp ); 00720 return 0; 00721 00722 err: 00723 free ( isapnp ); 00724 isapnpbus_remove ( rootdev ); 00725 return rc; 00726 }
ISAPnP Read Port address.
ROM prefix may be able to set this address, which is why this is non-static.
Definition at line 75 of file isapnp.c.
Referenced by isapnp_isolate(), isapnp_read_data(), isapnp_set_read_port(), isapnp_try_isolate(), isapnpbus_probe(), and pxenv_start_undi().
struct root_driver isapnp_root_driver [static] |
Initial value:
{
.probe = isapnpbus_probe,
.remove = isapnpbus_remove,
}
| struct root_device isapnp_root_device __root_device |
Initial value:
{
.dev = { .name = "ISAPnP" },
.driver = &isapnp_root_driver,
}
1.5.7.1