1 /************************************************************************** 2 * 3 * isapnp.c -- 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 * REVISION HISTORY: 25 * ================ 26 * Version 0.1 April 26, 2002 TJL 27 * Version 0.2 01/08/2003 TJL Moved outside the 3c515.c driver file 28 * Version 0.3 Sept 23, 2003 timlegge Change delay to currticks 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 37 * 38 * ISAPnP bus support 39 * 40 * Etherboot orignally gained ISAPnP support in a very limited way for 41 * the 3c515 NIC. The current implementation is almost a complete 42 * rewrite based on the ISAPnP specification, with passing reference 43 * to the Linux ISAPnP code. 44 * 45 * There can be only one ISAPnP bus in a system. Once the read port 46 * is known and all cards have been allocated CSNs, there's nothing to 47 * be gained by re-scanning for cards. 48 * 49 * External code (e.g. the ISAPnP ROM prefix) may already know the 50 * read port address, in which case it can store it in 51 * #isapnp_read_port. Note that setting the read port address in this 52 * way will prevent further isolation from taking place; you should 53 * set the read port address only if you know that devices have 54 * already been allocated CSNs. 55 * 56 */ 57 58 FILE_LICENCE ( GPL2_OR_LATER ); 59 60 #include <stdint.h> 61 #include <stdlib.h> 62 #include <string.h> 63 #include <stdio.h> 64 #include <errno.h> 65 #include <gpxe/io.h> 66 #include <unistd.h> 67 #include <gpxe/isapnp.h> 68 69 /** 70 * ISAPnP Read Port address. 71 * 72 * ROM prefix may be able to set this address, which is why this is 73 * non-static. 74 */ 75 uint16_t isapnp_read_port; 76 77 static void isapnpbus_remove ( struct root_device *rootdev ); 78 79 /* 80 * ISAPnP utility functions 81 * 82 */ 83 84 #define ISAPNP_CARD_ID_FMT "ID %04x:%04x (\"%s\") serial %x" 85 #define ISAPNP_CARD_ID_DATA(identifier) \ 86 (identifier)->vendor_id, (identifier)->prod_id, \ 87 isa_id_string ( (identifier)->vendor_id, (identifier)->prod_id ), \ 88 (identifier)->serial 89 #define ISAPNP_DEV_ID_FMT "ID %04x:%04x (\"%s\")" 90 #define ISAPNP_DEV_ID_DATA(isapnp) \ 91 (isapnp)->vendor_id, (isapnp)->prod_id, \ 92 isa_id_string ( (isapnp)->vendor_id, (isapnp)->prod_id ) 93 94 static inline void isapnp_write_address ( unsigned int address ) { 95 outb ( address, ISAPNP_ADDRESS ); 96 } 97 98 static inline void isapnp_write_data ( unsigned int data ) { 99 outb ( data, ISAPNP_WRITE_DATA ); 100 } 101 102 static inline unsigned int isapnp_read_data ( void ) { 103 return inb ( isapnp_read_port ); 104 } 105 106 static inline void isapnp_write_byte ( unsigned int address, 107 unsigned int value ) { 108 isapnp_write_address ( address ); 109 isapnp_write_data ( value ); 110 } 111 112 static inline unsigned int isapnp_read_byte ( unsigned int address ) { 113 isapnp_write_address ( address ); 114 return isapnp_read_data (); 115 } 116 117 static inline unsigned int isapnp_read_word ( unsigned int address ) { 118 /* Yes, they're in big-endian order */ 119 return ( ( isapnp_read_byte ( address ) << 8 ) 120 | isapnp_read_byte ( address + 1 ) ); 121 } 122 123 /** Inform cards of a new read port address */ 124 static inline void isapnp_set_read_port ( void ) { 125 isapnp_write_byte ( ISAPNP_READPORT, ( isapnp_read_port >> 2 ) ); 126 } 127 128 /** 129 * Enter the Isolation state. 130 * 131 * Only cards currently in the Sleep state will respond to this 132 * command. 133 */ 134 static inline void isapnp_serialisolation ( void ) { 135 isapnp_write_address ( ISAPNP_SERIALISOLATION ); 136 } 137 138 /** 139 * Enter the Wait for Key state. 140 * 141 * All cards will respond to this command, regardless of their current 142 * state. 143 */ 144 static inline void isapnp_wait_for_key ( void ) { 145 isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY ); 146 } 147 148 /** 149 * Reset (i.e. remove) Card Select Number. 150 * 151 * Only cards currently in the Sleep state will respond to this 152 * command. 153 */ 154 static inline void isapnp_reset_csn ( void ) { 155 isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN ); 156 } 157 158 /** 159 * Place a specified card into the Config state. 160 * 161 * @v csn Card Select Number 162 * @ret None - 163 * @err None - 164 * 165 * Only cards currently in the Sleep, Isolation, or Config states will 166 * respond to this command. The card that has the specified CSN will 167 * enter the Config state, all other cards will enter the Sleep state. 168 */ 169 static inline void isapnp_wake ( uint8_t csn ) { 170 isapnp_write_byte ( ISAPNP_WAKE, csn ); 171 } 172 173 static inline unsigned int isapnp_read_resourcedata ( void ) { 174 return isapnp_read_byte ( ISAPNP_RESOURCEDATA ); 175 } 176 177 static inline unsigned int isapnp_read_status ( void ) { 178 return isapnp_read_byte ( ISAPNP_STATUS ); 179 } 180 181 /** 182 * Assign a Card Select Number to a card, and enter the Config state. 183 * 184 * @v csn Card Select Number 185 * 186 * Only cards in the Isolation state will respond to this command. 187 * The isolation protocol is designed so that only one card will 188 * remain in the Isolation state by the time the isolation protocol 189 * completes. 190 */ 191 static inline void isapnp_write_csn ( unsigned int csn ) { 192 isapnp_write_byte ( ISAPNP_CARDSELECTNUMBER, csn ); 193 } 194 195 static inline void isapnp_logicaldevice ( unsigned int logdev ) { 196 isapnp_write_byte ( ISAPNP_LOGICALDEVICENUMBER, logdev ); 197 } 198 199 static inline void isapnp_activate ( unsigned int logdev ) { 200 isapnp_logicaldevice ( logdev ); 201 isapnp_write_byte ( ISAPNP_ACTIVATE, 1 ); 202 } 203 204 static inline void isapnp_deactivate ( unsigned int logdev ) { 205 isapnp_logicaldevice ( logdev ); 206 isapnp_write_byte ( ISAPNP_ACTIVATE, 0 ); 207 } 208 209 static inline unsigned int isapnp_read_iobase ( unsigned int index ) { 210 return isapnp_read_word ( ISAPNP_IOBASE ( index ) ); 211 } 212 213 static inline unsigned int isapnp_read_irqno ( unsigned int index ) { 214 return isapnp_read_byte ( ISAPNP_IRQNO ( index ) ); 215 } 216 217 static void isapnp_delay ( void ) { 218 udelay ( 1000 ); 219 } 220 221 /** 222 * Linear feedback shift register. 223 * 224 * @v lfsr Current value of the LFSR 225 * @v input_bit Current input bit to the LFSR 226 * @ret lfsr Next value of the LFSR 227 * 228 * This routine implements the linear feedback shift register as 229 * described in Appendix B of the PnP ISA spec. The hardware 230 * implementation uses eight D-type latches and two XOR gates. I 231 * think this is probably the smallest possible implementation in 232 * software. Six instructions when input_bit is a constant 0 (for 233 * isapnp_send_key). :) 234 */ 235 static inline unsigned int isapnp_lfsr_next ( unsigned int lfsr, 236 unsigned int input_bit ) { 237 register uint8_t lfsr_next; 238 239 lfsr_next = lfsr >> 1; 240 lfsr_next |= ( ( ( lfsr ^ lfsr_next ) ^ input_bit ) ) << 7; 241 return lfsr_next; 242 } 243 244 /** 245 * Send the ISAPnP initiation key. 246 * 247 * Sending the key causes all ISAPnP cards that are currently in the 248 * Wait for Key state to transition into the Sleep state. 249 */ 250 static void isapnp_send_key ( void ) { 251 unsigned int i; 252 unsigned int lfsr; 253 254 isapnp_delay(); 255 isapnp_write_address ( 0x00 ); 256 isapnp_write_address ( 0x00 ); 257 258 lfsr = ISAPNP_LFSR_SEED; 259 for ( i = 0 ; i < 32 ; i++ ) { 260 isapnp_write_address ( lfsr ); 261 lfsr = isapnp_lfsr_next ( lfsr, 0 ); 262 } 263 } 264 265 /** 266 * Compute ISAPnP identifier checksum 267 * 268 * @v identifier ISAPnP identifier 269 * @ret checksum Expected checksum value 270 */ 271 static unsigned int isapnp_checksum ( struct isapnp_identifier *identifier ) { 272 unsigned int i, j; 273 unsigned int lfsr; 274 unsigned int byte; 275 276 lfsr = ISAPNP_LFSR_SEED; 277 for ( i = 0 ; i < 8 ; i++ ) { 278 byte = * ( ( ( uint8_t * ) identifier ) + i ); 279 for ( j = 0 ; j < 8 ; j++ ) { 280 lfsr = isapnp_lfsr_next ( lfsr, byte ); 281 byte >>= 1; 282 } 283 } 284 return lfsr; 285 } 286 287 /* 288 * Read a byte of resource data from the current location 289 * 290 * @ret byte Byte of resource data 291 */ 292 static inline unsigned int isapnp_peek_byte ( void ) { 293 unsigned int i; 294 295 /* Wait for data to be ready */ 296 for ( i = 0 ; i < 20 ; i++ ) { 297 if ( isapnp_read_status() & 0x01 ) { 298 /* Byte ready - read it */ 299 return isapnp_read_resourcedata(); 300 } 301 isapnp_delay(); 302 } 303 /* Data never became ready - return 0xff */ 304 return 0xff; 305 } 306 307 /** 308 * Read resource data. 309 * 310 * @v buf Buffer in which to store data, or NULL 311 * @v bytes Number of bytes to read 312 * 313 * Resource data is read from the current location. If #buf is NULL, 314 * the data is discarded. 315 */ 316 static void isapnp_peek ( void *buf, size_t len ) { 317 unsigned int i; 318 unsigned int byte; 319 320 for ( i = 0 ; i < len ; i++) { 321 byte = isapnp_peek_byte(); 322 if ( buf ) 323 * ( ( uint8_t * ) buf + i ) = byte; 324 } 325 } 326 327 /** 328 * Find a tag within the resource data. 329 * 330 * @v wanted_tag The tag that we're looking for 331 * @v buf Buffer in which to store the tag's contents 332 * @v len Length of buffer 333 * @ret rc Return status code 334 * 335 * Scan through the resource data until we find a particular tag, and 336 * read its contents into a buffer. 337 */ 338 static int isapnp_find_tag ( unsigned int wanted_tag, void *buf, size_t len ) { 339 unsigned int tag; 340 unsigned int tag_len; 341 342 DBG2 ( "ISAPnP read tag" ); 343 do { 344 tag = isapnp_peek_byte(); 345 if ( ISAPNP_IS_SMALL_TAG ( tag ) ) { 346 tag_len = ISAPNP_SMALL_TAG_LEN ( tag ); 347 tag = ISAPNP_SMALL_TAG_NAME ( tag ); 348 } else { 349 tag_len = ( isapnp_peek_byte() + 350 ( isapnp_peek_byte() << 8 ) ); 351 tag = ISAPNP_LARGE_TAG_NAME ( tag ); 352 } 353 DBG2 ( " %02x (%02x)", tag, tag_len ); 354 if ( tag == wanted_tag ) { 355 if ( len > tag_len ) 356 len = tag_len; 357 isapnp_peek ( buf, len ); 358 DBG2 ( "\n" ); 359 return 0; 360 } else { 361 isapnp_peek ( NULL, tag_len ); 362 } 363 } while ( tag != ISAPNP_TAG_END ); 364 DBG2 ( "\n" ); 365 return -ENOENT; 366 } 367 368 /** 369 * Find specified Logical Device ID tag 370 * 371 * @v logdev Logical device ID 372 * @v logdevid Logical device ID structure to fill in 373 * @ret rc Return status code 374 */ 375 static int isapnp_find_logdevid ( unsigned int logdev, 376 struct isapnp_logdevid *logdevid ) { 377 unsigned int i; 378 int rc; 379 380 for ( i = 0 ; i <= logdev ; i++ ) { 381 if ( ( rc = isapnp_find_tag ( ISAPNP_TAG_LOGDEVID, logdevid, 382 sizeof ( *logdevid ) ) ) != 0 ) 383 return rc; 384 } 385 return 0; 386 } 387 388 /** 389 * Try isolating ISAPnP cards at the current read port. 390 * 391 * @ret \>0 Number of ISAPnP cards found 392 * @ret 0 There are no ISAPnP cards in the system 393 * @ret \<0 A conflict was detected; try a new read port 394 * @err None - 395 * 396 * The state diagram on page 18 (PDF page 24) of the PnP ISA spec 397 * gives the best overview of what happens here. 398 */ 399 static int isapnp_try_isolate ( void ) { 400 struct isapnp_identifier identifier; 401 unsigned int i, j; 402 unsigned int seen_55aa, seen_life; 403 unsigned int csn = 0; 404 unsigned int data; 405 unsigned int byte; 406 407 DBG ( "ISAPnP attempting isolation at read port %04x\n", 408 isapnp_read_port ); 409 410 /* Place all cards into the Sleep state, whatever state 411 * they're currently in. 412 */ 413 isapnp_wait_for_key(); 414 isapnp_send_key(); 415 416 /* Reset all assigned CSNs */ 417 isapnp_reset_csn(); 418 isapnp_delay(); 419 isapnp_delay(); 420 421 /* Place all cards into the Isolation state */ 422 isapnp_wait_for_key (); 423 isapnp_send_key(); 424 isapnp_wake ( 0x00 ); 425 426 /* Set the read port */ 427 isapnp_set_read_port(); 428 isapnp_delay(); 429 430 while ( 1 ) { 431 432 /* All cards that do not have assigned CSNs are 433 * currently in the Isolation state, each time we go 434 * through this loop. 435 */ 436 437 /* Initiate serial isolation */ 438 isapnp_serialisolation(); 439 isapnp_delay(); 440 441 /* Read identifier serially via the ISAPnP read port. */ 442 memset ( &identifier, 0, sizeof ( identifier ) ); 443 seen_55aa = seen_life = 0; 444 for ( i = 0 ; i < 9 ; i++ ) { 445 byte = 0; 446 for ( j = 0 ; j < 8 ; j++ ) { 447 data = isapnp_read_data(); 448 isapnp_delay(); 449 data = ( ( data << 8 ) | isapnp_read_data() ); 450 isapnp_delay(); 451 byte >>= 1; 452 if ( data != 0xffff ) { 453 seen_life++; 454 if ( data == 0x55aa ) { 455 byte |= 0x80; 456 seen_55aa++; 457 } 458 } 459 } 460 *( ( ( uint8_t * ) &identifier ) + i ) = byte; 461 } 462 463 /* If we didn't see any 55aa patterns, stop here */ 464 if ( ! seen_55aa ) { 465 if ( csn ) { 466 DBG ( "ISAPnP found no more cards\n" ); 467 } else { 468 if ( seen_life ) { 469 DBG ( "ISAPnP saw life but no cards, " 470 "trying new read port\n" ); 471 csn = -1; 472 } else { 473 DBG ( "ISAPnP saw no signs of life, " 474 "abandoning isolation\n" ); 475 } 476 } 477 break; 478 } 479 480 /* If the checksum was invalid stop here */ 481 if ( identifier.checksum != isapnp_checksum ( &identifier) ) { 482 DBG ( "ISAPnP found malformed card " 483 ISAPNP_CARD_ID_FMT "\n with checksum %02x " 484 "(should be %02x), trying new read port\n", 485 ISAPNP_CARD_ID_DATA ( &identifier ), 486 identifier.checksum, 487 isapnp_checksum ( &identifier) ); 488 csn = -1; 489 break; 490 } 491 492 /* Give the device a CSN */ 493 csn++; 494 DBG ( "ISAPnP found card " ISAPNP_CARD_ID_FMT 495 ", assigning CSN %02x\n", 496 ISAPNP_CARD_ID_DATA ( &identifier ), csn ); 497 498 isapnp_write_csn ( csn ); 499 isapnp_delay(); 500 501 /* Send this card back to Sleep and force all cards 502 * without a CSN into Isolation state 503 */ 504 isapnp_wake ( 0x00 ); 505 isapnp_delay(); 506 } 507 508 /* Place all cards in Wait for Key state */ 509 isapnp_wait_for_key(); 510 511 /* Return number of cards found */ 512 if ( csn > 0 ) { 513 DBG ( "ISAPnP found %d cards at read port %04x\n", 514 csn, isapnp_read_port ); 515 } 516 return csn; 517 } 518 519 /** 520 * Find a valid read port and isolate all ISAPnP cards. 521 * 522 */ 523 static void isapnp_isolate ( void ) { 524 for ( isapnp_read_port = ISAPNP_READ_PORT_START ; 525 isapnp_read_port <= ISAPNP_READ_PORT_MAX ; 526 isapnp_read_port += ISAPNP_READ_PORT_STEP ) { 527 /* Avoid problematic locations such as the NE2000 528 * probe space 529 */ 530 if ( ( isapnp_read_port >= 0x280 ) && 531 ( isapnp_read_port <= 0x380 ) ) 532 continue; 533 534 /* If we detect any ISAPnP cards at this location, stop */ 535 if ( isapnp_try_isolate() >= 0 ) 536 return; 537 } 538 } 539 540 /** 541 * Activate or deactivate an ISAPnP device. 542 * 543 * @v isapnp ISAPnP device 544 * @v activation True to enable, False to disable the device 545 * @ret None - 546 * @err None - 547 * 548 * This routine simply activates the device in its current 549 * configuration, or deactivates the device. It does not attempt any 550 * kind of resource arbitration. 551 * 552 */ 553 void isapnp_device_activation ( struct isapnp_device *isapnp, 554 int activation ) { 555 /* Wake the card and select the logical device */ 556 isapnp_wait_for_key (); 557 isapnp_send_key (); 558 isapnp_wake ( isapnp->csn ); 559 isapnp_logicaldevice ( isapnp->logdev ); 560 561 /* Activate/deactivate the logical device */ 562 isapnp_activate ( activation ); 563 isapnp_delay(); 564 565 /* Return all cards to Wait for Key state */ 566 isapnp_wait_for_key (); 567 568 DBG ( "ISAPnP %s device %02x:%02x\n", 569 ( activation ? "activated" : "deactivated" ), 570 isapnp->csn, isapnp->logdev ); 571 } 572 573 /** 574 * Probe an ISAPnP device 575 * 576 * @v isapnp ISAPnP device 577 * @ret rc Return status code 578 * 579 * Searches for a driver for the ISAPnP device. If a driver is found, 580 * its probe() routine is called. 581 */ 582 static int isapnp_probe ( struct isapnp_device *isapnp ) { 583 struct isapnp_driver *driver; 584 struct isapnp_device_id *id; 585 unsigned int i; 586 int rc; 587 588 DBG ( "Adding ISAPnP device %02x:%02x (%04x:%04x (\"%s\") " 589 "io %x irq %d)\n", isapnp->csn, isapnp->logdev, 590 isapnp->vendor_id, isapnp->prod_id, 591 isa_id_string ( isapnp->vendor_id, isapnp->prod_id ), 592 isapnp->ioaddr, isapnp->irqno ); 593 594 for_each_table_entry ( driver, ISAPNP_DRIVERS ) { 595 for ( i = 0 ; i < driver->id_count ; i++ ) { 596 id = &driver->ids[i]; 597 if ( id->vendor_id != isapnp->vendor_id ) 598 continue; 599 if ( ISA_PROD_ID ( id->prod_id ) != 600 ISA_PROD_ID ( isapnp->prod_id ) ) 601 continue; 602 isapnp->driver = driver; 603 isapnp->driver_name = id->name; 604 DBG ( "...using driver %s\n", isapnp->driver_name ); 605 if ( ( rc = driver->probe ( isapnp, id ) ) != 0 ) { 606 DBG ( "......probe failed\n" ); 607 continue; 608 } 609 return 0; 610 } 611 } 612 613 DBG ( "...no driver found\n" ); 614 return -ENOTTY; 615 } 616 617 /** 618 * Remove an ISAPnP device 619 * 620 * @v isapnp ISAPnP device 621 */ 622 static void isapnp_remove ( struct isapnp_device *isapnp ) { 623 isapnp->driver->remove ( isapnp ); 624 DBG ( "Removed ISAPnP device %02x:%02x\n", 625 isapnp->csn, isapnp->logdev ); 626 } 627 628 /** 629 * Probe ISAPnP root bus 630 * 631 * @v rootdev ISAPnP bus root device 632 * 633 * Scans the ISAPnP bus for devices and registers all devices it can 634 * find. 635 */ 636 static int isapnpbus_probe ( struct root_device *rootdev ) { 637 struct isapnp_device *isapnp = NULL; 638 struct isapnp_identifier identifier; 639 struct isapnp_logdevid logdevid; 640 unsigned int csn; 641 unsigned int logdev; 642 int rc; 643 644 /* Perform isolation if it hasn't yet been done */ 645 if ( ! isapnp_read_port ) 646 isapnp_isolate(); 647 648 for ( csn = 1 ; csn <= 0xff ; csn++ ) { 649 for ( logdev = 0 ; logdev <= 0xff ; logdev++ ) { 650 651 /* Allocate struct isapnp_device */ 652 if ( ! isapnp ) 653 isapnp = malloc ( sizeof ( *isapnp ) ); 654 if ( ! isapnp ) { 655 rc = -ENOMEM; 656 goto err; 657 } 658 memset ( isapnp, 0, sizeof ( *isapnp ) ); 659 isapnp->csn = csn; 660 isapnp->logdev = logdev; 661 662 /* Wake the card */ 663 isapnp_wait_for_key(); 664 isapnp_send_key(); 665 isapnp_wake ( csn ); 666 667 /* Read the card identifier */ 668 isapnp_peek ( &identifier, sizeof ( identifier ) ); 669 670 /* No card with this CSN; stop here */ 671 if ( identifier.vendor_id & 0x80 ) 672 goto done; 673 674 /* Find the Logical Device ID tag */ 675 if ( ( rc = isapnp_find_logdevid ( logdev, 676 &logdevid ) ) != 0){ 677 /* No more logical devices; go to next CSN */ 678 break; 679 } 680 681 /* Select the logical device */ 682 isapnp_logicaldevice ( logdev ); 683 684 /* Populate struct isapnp_device */ 685 isapnp->vendor_id = logdevid.vendor_id; 686 isapnp->prod_id = logdevid.prod_id; 687 isapnp->ioaddr = isapnp_read_iobase ( 0 ); 688 isapnp->irqno = isapnp_read_irqno ( 0 ); 689 690 /* Return all cards to Wait for Key state */ 691 isapnp_wait_for_key(); 692 693 /* Add to device hierarchy */ 694 snprintf ( isapnp->dev.name, 695 sizeof ( isapnp->dev.name ), 696 "ISAPnP%02x:%02x", csn, logdev ); 697 isapnp->dev.desc.bus_type = BUS_TYPE_ISAPNP; 698 isapnp->dev.desc.vendor = isapnp->vendor_id; 699 isapnp->dev.desc.device = isapnp->prod_id; 700 isapnp->dev.desc.ioaddr = isapnp->ioaddr; 701 isapnp->dev.desc.irq = isapnp->irqno; 702 isapnp->dev.parent = &rootdev->dev; 703 list_add ( &isapnp->dev.siblings, 704 &rootdev->dev.children ); 705 INIT_LIST_HEAD ( &isapnp->dev.children ); 706 707 /* Look for a driver */ 708 if ( isapnp_probe ( isapnp ) == 0 ) { 709 /* isapnpdev registered, we can drop our ref */ 710 isapnp = NULL; 711 } else { 712 /* Not registered; re-use struct */ 713 list_del ( &isapnp->dev.siblings ); 714 } 715 } 716 } 717 718 done: 719 free ( isapnp ); 720 return 0; 721 722 err: 723 free ( isapnp ); 724 isapnpbus_remove ( rootdev ); 725 return rc; 726 } 727 728 /** 729 * Remove ISAPnP root bus 730 * 731 * @v rootdev ISAPnP bus root device 732 */ 733 static void isapnpbus_remove ( struct root_device *rootdev ) { 734 struct isapnp_device *isapnp; 735 struct isapnp_device *tmp; 736 737 list_for_each_entry_safe ( isapnp, tmp, &rootdev->dev.children, 738 dev.siblings ) { 739 isapnp_remove ( isapnp ); 740 list_del ( &isapnp->dev.siblings ); 741 free ( isapnp ); 742 } 743 } 744 745 /** ISAPnP bus root device driver */ 746 static struct root_driver isapnp_root_driver = { 747 .probe = isapnpbus_probe, 748 .remove = isapnpbus_remove, 749 }; 750 751 /** ISAPnP bus root device */ 752 struct root_device isapnp_root_device __root_device = { 753 .dev = { .name = "ISAPnP" }, 754 .driver = &isapnp_root_driver, 755 }; 756