Import from Etherboot 5.4
[people/andreif/gpxe.git] / src / drivers / bus / isapnp.c
1 /**************************************************************************
2 *
3 *    isapnp.c -- Etherboot isapnp support for the 3Com 3c515
4 *    Written 2002-2003 by Timothy Legge <tlegge@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@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@fensystems.co.uk>
33 *
34 ***************************************************************************/
35
36 #include "string.h"
37 #include "timer.h"
38 #include "io.h"
39 #include "console.h"
40 #include "isapnp.h"
41
42 /*
43  * We can have only one ISAPnP bus in a system.  Once the read port is
44  * known and all cards have been allocated CSNs, there's nothing to be
45  * gained by re-scanning for cards.
46  *
47  * However, we shouldn't make scanning the ISAPnP bus an INIT_FN(),
48  * because even ISAPnP probing can still screw up other devices on the
49  * ISA bus.  We therefore probe only when we are first asked to find
50  * an ISAPnP device.
51  *
52  * External code (e.g. the ISAPnP ROM prefix) may already know the
53  * read port address, in which case it can initialise this value.
54  * Note that setting the read port address will prevent further
55  * isolation from taking place; you should set the read port address
56  * only if you know that devices have already been allocated CSNs.
57  *
58  */
59 uint16_t isapnp_read_port;
60
61 /*
62  * Highest assigned CSN.
63  *
64  * Note that *we* do not necessarily assign CSNs; it could be done by
65  * the PnP BIOS instead.  We therefore set this only when we first try
66  * to Wake[CSN] a device and find that there's nothing there.  Page 16
67  * (PDF page 22) of the ISAPnP spec states that "Valid Card Select
68  * Numbers for identified ISA cards range from 1 to 255 and must be
69  * assigned sequentially starting from 1", so we are (theoretically,
70  * at least) safe to assume that there are no ISAPnP cards at CSNs
71  * higher than the first unused CSN.
72  *
73  */
74 static uint8_t isapnp_max_csn = 0xff;
75
76 /*
77  * ISAPnP utility functions
78  *
79  */
80
81 #define ISAPNP_CARD_ID_FMT "ID %hx:%hx (\"%s\") serial %x"
82 #define ISAPNP_CARD_ID_DATA(identifier)                                   \
83         (identifier)->vendor_id, (identifier)->prod_id,                   \
84         isa_id_string ( (identifier)->vendor_id, (identifier)->prod_id ), \
85         (identifier)->serial
86 #define ISAPNP_DEV_ID_FMT "ID %hx:%hx (\"%s\")"
87 #define ISAPNP_DEV_ID_DATA(isapnp)                                        \
88         (isapnp)->vendor_id, (isapnp)->prod_id,                           \
89         isa_id_string ( (isapnp)->vendor_id, (isapnp)->prod_id )
90
91 static inline void isapnp_write_address ( uint8_t address ) {
92         outb ( address, ISAPNP_ADDRESS );
93 }
94
95 static inline void isapnp_write_data ( uint8_t data ) {
96         outb ( data, ISAPNP_WRITE_DATA );
97 }
98
99 static inline uint8_t isapnp_read_data ( void ) {
100         return inb ( isapnp_read_port );
101 }
102
103 static inline void isapnp_write_byte ( uint8_t address, uint8_t value ) {
104         isapnp_write_address ( address );
105         isapnp_write_data ( value );
106 }
107
108 static inline uint8_t isapnp_read_byte ( uint8_t address ) {
109         isapnp_write_address ( address );
110         return isapnp_read_data ();
111 }
112
113 static inline uint16_t isapnp_read_word ( uint8_t address ) {
114         /* Yes, they're in big-endian order */
115         return ( ( isapnp_read_byte ( address ) << 8 )
116                  + isapnp_read_byte ( address + 1 ) );
117 }
118
119 static inline void isapnp_set_read_port ( void ) {
120         isapnp_write_byte ( ISAPNP_READPORT, isapnp_read_port >> 2 );
121 }
122
123 static inline void isapnp_serialisolation ( void ) {
124         isapnp_write_address ( ISAPNP_SERIALISOLATION );
125 }
126
127 static inline void isapnp_wait_for_key ( void ) {
128         isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY );
129 }
130
131 static inline void isapnp_reset_csn ( void ) {
132         isapnp_write_byte ( ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN );
133 }
134
135 static inline void isapnp_wake ( uint8_t csn ) {
136         isapnp_write_byte ( ISAPNP_WAKE, csn );
137 }
138
139 static inline uint8_t isapnp_read_resourcedata ( void ) {
140         return isapnp_read_byte ( ISAPNP_RESOURCEDATA );
141 }
142
143 static inline uint8_t isapnp_read_status ( void ) {
144         return isapnp_read_byte ( ISAPNP_STATUS );
145 }
146
147 static inline void isapnp_write_csn ( uint8_t csn ) {
148         isapnp_write_byte ( ISAPNP_CARDSELECTNUMBER, csn );
149 }
150
151 static inline void isapnp_logicaldevice ( uint8_t logdev ) {
152         isapnp_write_byte ( ISAPNP_LOGICALDEVICENUMBER, logdev );
153 }
154
155 static inline void isapnp_activate ( uint8_t logdev ) {
156         isapnp_logicaldevice ( logdev );
157         isapnp_write_byte ( ISAPNP_ACTIVATE, 1 );
158 }
159
160 static inline void isapnp_deactivate ( uint8_t logdev ) {
161         isapnp_logicaldevice ( logdev );
162         isapnp_write_byte ( ISAPNP_ACTIVATE, 0 );
163 }
164
165 static inline uint16_t isapnp_read_iobase ( unsigned int index ) {
166         return isapnp_read_word ( ISAPNP_IOBASE ( index ) );
167 }
168
169 static inline uint8_t isapnp_read_irqno ( unsigned int index ) {
170         return isapnp_read_byte ( ISAPNP_IRQNO ( index ) );
171 }
172
173 static void isapnp_delay ( void ) {
174         udelay ( 1000 );
175 }
176
177 /*
178  * The linear feedback shift register as described in Appendix B of
179  * the PnP ISA spec.  The hardware implementation uses eight D-type
180  * latches and two XOR gates.  I think this is probably the smallest
181  * possible implementation in software.  Six instructions when input_bit
182  * is a constant 0 (for isapnp_send_key).  :)
183  *
184  */
185 static inline uint8_t isapnp_lfsr_next ( uint8_t lfsr, int input_bit ) {
186         register uint8_t lfsr_next;
187
188         lfsr_next = lfsr >> 1;
189         lfsr_next |= ( ( ( lfsr ^ lfsr_next ) ^ input_bit ) ) << 7;
190         return lfsr_next;
191 }
192
193 /*
194  * Send the ISAPnP initiation key
195  *
196  */
197 static void isapnp_send_key ( void ) {
198         unsigned int i;
199         uint8_t lfsr;
200
201         isapnp_delay();
202         isapnp_write_address ( 0x00 );
203         isapnp_write_address ( 0x00 );
204
205         lfsr = ISAPNP_LFSR_SEED;
206         for ( i = 0 ; i < 32 ; i++ ) {
207                 isapnp_write_address ( lfsr );
208                 lfsr = isapnp_lfsr_next ( lfsr, 0 );
209         }
210 }
211
212 /*
213  *  Compute ISAPnP identifier checksum
214  *
215  */
216 static uint8_t isapnp_checksum ( struct isapnp_identifier *identifier ) {
217         int i, j;
218         uint8_t lfsr;
219         uint8_t byte;
220
221         lfsr = ISAPNP_LFSR_SEED;
222         for ( i = 0 ; i < 8 ; i++ ) {
223                 byte = ( (char *) identifier )[i];
224                 for ( j = 0 ; j < 8 ; j++ ) {
225                         lfsr = isapnp_lfsr_next ( lfsr, byte );
226                         byte >>= 1;
227                 }
228         }
229         return lfsr;
230 }
231
232 /*
233  * Read a byte of resource data from the current location
234  *
235  */
236 static inline uint8_t isapnp_peek_byte ( void ) {
237         int i;
238
239         /* Wait for data to be ready */
240         for ( i = 0 ; i < 20 ; i ++ ) {
241                 if ( isapnp_read_status() & 0x01 ) {
242                         /* Byte ready - read it */
243                         return isapnp_read_resourcedata();
244                 }
245                 isapnp_delay ();
246         }
247         /* Data never became ready - return 0xff */
248         return 0xff;
249 }
250
251 /*
252  * Read n bytes of resource data from the current location.  If buf is
253  * NULL, discard data.
254  *
255  */
256 static void isapnp_peek ( uint8_t *buf, size_t bytes ) {
257         unsigned int i;
258         uint8_t byte;
259
260         for ( i = 0 ; i < bytes ; i++) {
261                 byte = isapnp_peek_byte();
262                 if ( buf ) {
263                         buf[i] = byte;
264                 }
265         }
266 }
267
268 /*
269  * Scan through the resource data until we find a particular tag, and
270  * read its contents into a buffer.
271  *
272  * It is the caller's responsibility to ensure that buf is large
273  * enough to contain a tag of the requested size.
274  *
275  */
276 static int isapnp_find_tag ( uint8_t wanted_tag, uint8_t *buf ) {
277         uint8_t tag;
278         uint16_t len;
279
280         DBG2 ( "ISAPnP read tag" );
281         do {
282                 tag = isapnp_peek_byte();
283                 if ( ISAPNP_IS_SMALL_TAG ( tag ) ) {
284                         len = ISAPNP_SMALL_TAG_LEN ( tag );
285                         tag = ISAPNP_SMALL_TAG_NAME ( tag );
286                 } else {
287                         len = isapnp_peek_byte() + ( isapnp_peek_byte() << 8 );
288                         tag = ISAPNP_LARGE_TAG_NAME ( tag );
289                 }
290                 DBG2 ( " %hhx (%hhx)", tag, len );
291                 if ( tag == wanted_tag ) {
292                         isapnp_peek ( buf, len );
293                         DBG2 ( "\n" );
294                         return 1;
295                 } else {
296                         isapnp_peek ( NULL, len );
297                 }
298         } while ( tag != ISAPNP_TAG_END );
299         DBG2 ( "\n" );
300         return 0;
301 }
302
303 /*
304  * Try isolating ISAPnP cards at the current read port.  Return the
305  * number of ISAPnP cards found.  <0 indicates "try a new read port",
306  * 0 indicates "definitely no cards".
307  *
308  * The state diagram on page 18 (PDF page 24) of the PnP ISA spec
309  * gives the best overview of what happens here.
310  *
311  */
312 static int isapnp_try_isolate ( void ) {
313         struct isapnp_identifier identifier;
314         unsigned int i, j;
315         unsigned int seen_55aa, seen_life;
316         unsigned int csn = 0;
317         uint16_t data;
318         uint8_t byte;
319
320         DBG ( "ISAPnP attempting isolation at read port %hx\n",
321               isapnp_read_port );
322
323         /* Place all cards into the Sleep state, whatever state
324          * they're currently in.
325          */
326         isapnp_wait_for_key ();
327         isapnp_send_key ();
328
329         /* Reset all assigned CSNs */
330         isapnp_reset_csn ();
331         isapnp_delay();
332         isapnp_delay();
333         
334         /* Place all cards into the Isolation state */
335         isapnp_wait_for_key ();
336         isapnp_send_key ();
337         isapnp_wake ( 0x00 );
338         
339         /* Set the read port */
340         isapnp_set_read_port ();
341         isapnp_delay();
342
343         while ( 1 ) {
344
345                 /* All cards that do not have assigned CSNs are
346                  * currently in the Isolation state, each time we go
347                  * through this loop.
348                  */
349
350                 /* Initiate serial isolation */
351                 isapnp_serialisolation ();
352                 isapnp_delay();
353
354                 /* Read identifier serially via the ISAPnP read port. */
355                 memset ( &identifier, 0, sizeof ( identifier ) );
356                 seen_55aa = seen_life = 0;
357                 for ( i = 0 ; i < 9 ; i++ ) {
358                         byte = 0;
359                         for ( j = 0 ; j < 8 ; j++ ) {
360                                 data = isapnp_read_data ();
361                                 isapnp_delay();
362                                 data = ( data << 8 ) | isapnp_read_data ();
363                                 isapnp_delay();
364                                 byte >>= 1;
365                                 if (  data != 0xffff ) {
366                                         seen_life++;
367                                         if ( data == 0x55aa ) {
368                                                 byte |= 0x80;
369                                                 seen_55aa++;
370                                         }
371                                 }
372                         }
373                         ( (char *) &identifier )[i] = byte;
374                 }
375
376                 /* If we didn't see any 55aa patterns, stop here */
377                 if ( ! seen_55aa ) {
378                         if ( csn ) {
379                                 DBG ( "ISAPnP found no more cards\n" );
380                         } else {
381                                 if ( seen_life ) {
382                                         DBG ( "ISAPnP saw life but no cards, "
383                                               "trying new read port\n" );
384                                         csn = -1;
385                                 } else {
386                                         DBG ( "ISAPnP saw no signs of life, "
387                                               "abandoning isolation\n" );
388                                 }
389                         }
390                         break;
391                 }
392
393                 /* If the checksum was invalid stop here */
394                 if ( identifier.checksum != isapnp_checksum ( &identifier) ) {
395                         DBG ( "ISAPnP found malformed card "
396                               ISAPNP_CARD_ID_FMT "\n  with checksum %hhx "
397                               "(should be %hhx), trying new read port\n",
398                               ISAPNP_CARD_ID_DATA ( &identifier ),
399                               identifier.checksum,
400                               isapnp_checksum ( &identifier) );
401                         csn = -1;
402                         break;
403                 }
404
405                 /* Give the device a CSN */
406                 csn++;
407                 DBG ( "ISAPnP found card " ISAPNP_CARD_ID_FMT
408                       ", assigning CSN %hhx\n",
409                       ISAPNP_CARD_ID_DATA ( &identifier ), csn );
410                 
411                 isapnp_write_csn ( csn );
412                 isapnp_delay();
413
414                 /* Send this card back to Sleep and force all cards
415                  * without a CSN into Isolation state
416                  */
417                 isapnp_wake ( 0x00 );
418                 isapnp_delay();
419         }
420
421         /* Place all cards in Wait for Key state */
422         isapnp_wait_for_key ();
423
424         /* Return number of cards found */
425         if ( csn > 0 ) {
426                 DBG ( "ISAPnP found %d cards at read port %hx\n",
427                       csn, isapnp_read_port );
428         }
429         return csn;
430 }
431
432 /*
433  * Isolate all ISAPnP cards, locating a valid read port in the process.
434  *
435  */
436 static void isapnp_isolate ( void ) {
437         for ( isapnp_read_port = ISAPNP_READ_PORT_MIN ;
438               isapnp_read_port <= ISAPNP_READ_PORT_MAX ;
439               isapnp_read_port += ISAPNP_READ_PORT_STEP ) {
440                 /* Avoid problematic locations such as the NE2000
441                  * probe space
442                  */
443                 if ( ( isapnp_read_port >= 0x280 ) &&
444                      ( isapnp_read_port <= 0x380 ) )
445                         continue;
446                 
447                 /* If we detect any ISAPnP cards at this location, stop */
448                 if ( isapnp_try_isolate () >= 0 )
449                         return;
450         }
451 }
452
453 /*
454  * Increment a bus_loc structure to the next possible ISAPnP location.
455  * Leave the structure zeroed and return 0 if there are no more valid
456  * locations.
457  *
458  */
459 static int isapnp_next_location ( struct bus_loc *bus_loc ) {
460         struct isapnp_loc *isapnp_loc = ( struct isapnp_loc * ) bus_loc;
461         
462         /*
463          * Ensure that there is sufficient space in the shared bus
464          * structures for a struct isapnp_loc and a struct isapnp_dev,
465          * as mandated by bus.h.
466          *
467          */
468         BUS_LOC_CHECK ( struct isapnp_loc );
469         BUS_DEV_CHECK ( struct isapnp_device );
470
471         return ( ++isapnp_loc->logdev ? 1 : ++isapnp_loc->csn );
472 }
473
474 /*
475  * Fill in parameters for an ISAPnP device based on CSN
476  *
477  * Return 1 if device present, 0 otherwise
478  *
479  */
480 static int isapnp_fill_device ( struct bus_dev *bus_dev,
481                                 struct bus_loc *bus_loc ) {
482         struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
483         struct isapnp_loc *isapnp_loc = ( struct isapnp_loc * ) bus_loc;
484         unsigned int i;
485         struct isapnp_identifier identifier;
486         struct isapnp_logdevid logdevid;
487         static struct {
488                 uint8_t csn;
489                 uint8_t first_nonexistent_logdev;
490         } cache = { 0, 0 };
491
492         /* Copy CSN and logdev to isapnp_device, set default values */
493         isapnp->csn = isapnp_loc->csn;
494         isapnp->logdev = isapnp_loc->logdev;
495         isapnp->name = "?";
496
497         /* CSN 0 is never valid, but may be passed in */
498         if ( ! isapnp->csn )
499                 return 0;
500
501         /* Check to see if we are already past the maximum CSN */
502         if ( isapnp->csn > isapnp_max_csn )
503                 return 0;
504
505         /* Check cache to see if we are already past the highest
506          * logical device of this CSN
507          */
508         if ( ( isapnp->csn == cache.csn ) &&
509              ( isapnp->logdev >= cache.first_nonexistent_logdev ) )
510                 return 0;
511
512         /* Perform isolation if it hasn't yet been done */
513         if ( ! isapnp_read_port )
514                 isapnp_isolate();
515
516         /* Wake the card */
517         isapnp_wait_for_key ();
518         isapnp_send_key ();
519         isapnp_wake ( isapnp->csn );
520
521         /* Read the card identifier */
522         isapnp_peek ( ( char * ) &identifier, sizeof ( identifier ) );
523
524         /* Need to return 0 if no device exists at this CSN */
525         if ( identifier.vendor_id & 0x80 ) {
526                 isapnp_max_csn = isapnp->csn - 1;
527                 return 0;
528         }
529
530         /* Find the Logical Device ID tag corresponding to this device */
531         for ( i = 0 ; i <= isapnp->logdev ; i++ ) {
532                 if ( ! isapnp_find_tag ( ISAPNP_TAG_LOGDEVID,
533                                          ( char * ) &logdevid ) ) {
534                         /* No tag for this device */
535                         if ( isapnp->logdev == 0 ) {
536                                 DBG ( "ISAPnP found no device %hhx.0 on card "
537                                       ISAPNP_CARD_ID_FMT "\n", isapnp->csn,
538                                       ISAPNP_CARD_ID_DATA ( &identifier ) );
539                         }
540                         cache.csn = isapnp->csn;
541                         cache.first_nonexistent_logdev = isapnp->logdev;
542                         return 0;
543                 }
544         }
545
546         /* Read information from logdevid structure */
547         isapnp->vendor_id = logdevid.vendor_id;
548         isapnp->prod_id = logdevid.prod_id;
549
550         /* Select the logical device */
551         isapnp_logicaldevice ( isapnp->logdev );
552
553         /* Read the current ioaddr and irqno */
554         isapnp->ioaddr = isapnp_read_iobase ( 0 );
555         isapnp->irqno = isapnp_read_irqno ( 0 );
556
557         /* Return all cards to Wait for Key state */
558         isapnp_wait_for_key ();
559
560         DBG ( "ISAPnP found device %hhx.%hhx " ISAPNP_DEV_ID_FMT
561               ", base %hx irq %d\n", isapnp->csn, isapnp->logdev,
562               ISAPNP_DEV_ID_DATA ( isapnp ), isapnp->ioaddr, isapnp->irqno );
563         DBG ( "  on card " ISAPNP_CARD_ID_FMT "\n",
564               ISAPNP_CARD_ID_DATA ( &identifier ) );
565
566         return 1;
567 }
568
569 /*
570  * Test whether or not a driver is capable of driving the device.
571  *
572  */
573 static int isapnp_check_driver ( struct bus_dev *bus_dev,
574                                  struct device_driver *device_driver ) {
575         struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
576         struct isapnp_driver *driver
577                 = ( struct isapnp_driver * ) device_driver->bus_driver_info;
578         unsigned int i;
579
580         /* Compare against driver's ID list */
581         for ( i = 0 ; i < driver->id_count ; i++ ) {
582                 struct isapnp_id *id = &driver->ids[i];
583                 
584                 if ( ( isapnp->vendor_id == id->vendor_id ) &&
585                      ( ISA_PROD_ID ( isapnp->prod_id ) ==
586                        ISA_PROD_ID ( id->prod_id ) ) ) {
587                         DBG ( "ISAPnP found ID %hx:%hx (\"%s\") (device %s) "
588                               "matching driver %s\n",
589                               isapnp->vendor_id, isapnp->prod_id,
590                               isa_id_string( isapnp->vendor_id,
591                                              isapnp->prod_id ),
592                               id->name, device_driver->name );
593                         isapnp->name = id->name;
594                         return 1;
595                 }
596         }
597
598         return 0;
599 }
600
601 /*
602  * Describe an ISAPnP device
603  *
604  */
605 static char * isapnp_describe_device ( struct bus_dev *bus_dev ) {
606         struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
607         static char isapnp_description[] = "ISAPnP 00:00";
608
609         sprintf ( isapnp_description + 7, "%hhx:%hhx",
610                   isapnp->csn, isapnp->logdev );
611         return isapnp_description;
612 }
613
614 /*
615  * Name an ISAPnP device
616  *
617  */
618 static const char * isapnp_name_device ( struct bus_dev *bus_dev ) {
619         struct isapnp_device *isapnp = ( struct isapnp_device * ) bus_dev;
620         
621         return isapnp->name;
622 }
623
624 /*
625  * ISAPnP bus operations table
626  *
627  */
628 struct bus_driver isapnp_driver __bus_driver = {
629         .name                   = "ISAPnP",
630         .next_location          = isapnp_next_location,
631         .fill_device            = isapnp_fill_device,
632         .check_driver           = isapnp_check_driver,
633         .describe_device        = isapnp_describe_device,
634         .name_device            = isapnp_name_device,
635 };
636
637 /*
638  * Activate or deactivate an ISAPnP device
639  *
640  * This routine simply activates the device in its current
641  * configuration.  It does not attempt any kind of resource
642  * arbitration.
643  *
644  */
645 void isapnp_device_activation ( struct isapnp_device *isapnp,
646                                 int activation ) {
647         /* Wake the card and select the logical device */
648         isapnp_wait_for_key ();
649         isapnp_send_key ();
650         isapnp_wake ( isapnp->csn );
651         isapnp_logicaldevice ( isapnp->logdev );
652
653         /* Activate/deactivate the logical device */
654         isapnp_activate ( activation );
655         isapnp_delay();
656
657         /* Return all cards to Wait for Key state */
658         isapnp_wait_for_key ();
659
660         DBG ( "ISAPnP %s device %hhx.%hhx\n",
661               ( activation ? "activated" : "deactivated" ),
662               isapnp->csn, isapnp->logdev );
663 }
664
665 /*
666  * Fill in a nic structure
667  *
668  */
669 void isapnp_fill_nic ( struct nic *nic, struct isapnp_device *isapnp ) {
670
671         /* Fill in ioaddr and irqno */
672         nic->ioaddr = isapnp->ioaddr;
673         nic->irqno = isapnp->irqno;
674
675         /* Fill in DHCP device ID structure */
676         nic->dhcp_dev_id.bus_type = ISA_BUS_TYPE;
677         nic->dhcp_dev_id.vendor_id = htons ( isapnp->vendor_id );
678         nic->dhcp_dev_id.device_id = htons ( isapnp->prod_id );
679 }
680