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