define __KERNEL_STRICT_NAMES to avoid inclusion of kernel types on systems that carry...
[cake.git] / rom / isapnp / pnp.c
blob852123d37f595a037a786f9f7191a8522d432bad
1 /* $Id: pnp.c,v 1.20 2001/05/10 14:07:27 lcs Exp $ */
3 /*
4 ISA-PnP -- A Plug And Play ISA software layer for AmigaOS.
5 Copyright (C) 2001 Martin Blom <martin@blom.org>
6 Copyright (C) 2009 The AROS Development Team
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with this library; if not, write to the
20 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
21 MA 02139, USA.
24 #define DEBUG 1
26 #include "CompilerSpecific.h"
28 #include <exec/memory.h>
30 #include <clib/alib_protos.h>
31 #include <proto/exec.h>
32 #include <proto/timer.h>
34 #include <resources/isapnp.h>
35 #include "isapnp_private.h"
37 #include "pnpisa.h"
39 #include "controller.h"
40 #include "devices.h"
41 #include "init.h"
42 #include "pnp.h"
43 #include "pnp_iterators.h"
44 #include "pnp_structs.h"
47 /******************************************************************************
48 ** PnP ISA helper functions ***************************************************
49 ******************************************************************************/
51 static UBYTE
52 GetPnPReg( UBYTE pnp_reg,
53 struct ISAPNPBase* res )
55 ISAC_SetRegByte( PNPISA_ADDRESS, pnp_reg, res );
57 return ISAC_GetRegByte( ( res->m_RegReadData << 2 ) | 3, res );
61 static UBYTE
62 GetLastPnPReg( struct ISAPNPBase* res )
64 return ISAC_GetRegByte( ( res->m_RegReadData << 2 ) | 3, res );
68 static void
69 SetPnPReg( UBYTE pnp_reg,
70 UBYTE value,
71 struct ISAPNPBase* res )
73 ISAC_SetRegByte( PNPISA_ADDRESS, pnp_reg, res );
74 ISAC_SetRegByte( PNPISA_WRITE_DATA, value, res );
78 static UBYTE
79 GetNextResourceData( struct ISAPNPBase* res )
81 // Poll for data
82 while( ( GetPnPReg( PNPISA_REG_STATUS, res ) & PNPISA_SF_AVAILABLE ) == 0 );
84 return GetPnPReg( PNPISA_REG_RESOURCE_DATA, res );
89 static void
90 BusyWait( ULONG micro_seconds )
92 typedef unsigned long long uint64_t;
94 ULONG freq;
95 struct EClockVal eclock;
96 uint64_t current;
97 uint64_t end;
99 freq = ReadEClock( &eclock );
101 current = ( ( (uint64_t) eclock.ev_hi ) << 32 ) + eclock.ev_lo;
102 end = current + (uint64_t) freq * micro_seconds / 1000000;
104 while( current < end )
106 ReadEClock( &eclock );
108 current = ( ( (uint64_t) eclock.ev_hi ) << 32 ) + eclock.ev_lo;
113 static BOOL
114 DecodeID( UBYTE* buf, struct ISAPNP_Identifier* id )
116 // Decode information
118 if( buf[ 0 ] & 0x80 )
120 return FALSE;
123 id->isapnpid_Vendor[ 0 ] = 0x40 + ( buf[ 0 ] >> 2 );
124 id->isapnpid_Vendor[ 1 ] = 0x40 + ( ( ( buf[ 0 ] & 0x03 ) << 3 ) |
125 ( buf[ 1 ] >> 5 ) );
126 id->isapnpid_Vendor[ 2 ] = 0x40 + ( buf[ 1 ] & 0x1f );
127 id->isapnpid_Vendor[ 3 ] = 0;
129 id->isapnpid_ProductID = ( buf[ 2 ] << 4 ) | ( buf[ 3 ] >> 4 );
130 id->isapnpid_Revision = buf[ 3 ] & 0x0f;
132 return TRUE;
136 /******************************************************************************
137 ** Move all cards to Sleep state **********************************************
138 ******************************************************************************/
140 static void
141 SendInitiationKey( struct ISAPNPBase* res )
143 static const UBYTE key[] =
145 PNPISA_INITIATION_KEY
148 unsigned int i;
150 // Make sure the LFSR is in its initial state
152 ISAC_SetRegByte( PNPISA_ADDRESS, 0, res );
153 ISAC_SetRegByte( PNPISA_ADDRESS, 0, res );
155 for( i = 0; i < sizeof( key ); ++i )
157 ISAC_SetRegByte( PNPISA_ADDRESS, key[ i ], res );
162 /******************************************************************************
163 ** Read the serial identifier from a card *************************************
164 ******************************************************************************/
166 static BOOL
167 ReadSerialIdentifier( struct ISAPNP_Card* card,
168 struct ISAPNPBase* res )
170 UBYTE buf[ 9 ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
171 int i;
172 UBYTE check_sum;
174 ISAC_SetRegByte( PNPISA_ADDRESS, PNPISA_REG_SERIAL_ISOLATION, res );
176 // Wait 1 ms before we read the first pair
178 BusyWait( 1000 );
180 check_sum = 0x6a;
182 for( i = 0; i < 72; ++i )
184 UBYTE value1;
185 UBYTE value2;
187 value1 = GetLastPnPReg( res );
188 value2 = GetLastPnPReg( res );
190 if( value1 == 0x55 && value2 == 0xaa )
192 buf[ i >> 3 ] |= ( 1 << ( i & 7 ) );
195 if( i < 64 )
197 UBYTE bitten = value1 == 0x55 && value2 == 0xaa ? 1 : 0;
199 check_sum = PNPISA_LFSR( check_sum, bitten );
202 // Wait 250 µs before we read the next pair
204 BusyWait( 250 );
207 if( check_sum != buf[ 8 ] )
209 return FALSE;
212 if( ! DecodeID( buf, &card->isapnpc_ID ) )
214 return FALSE;
217 card->isapnpc_SerialNumber = ( buf[ 7 ] << 25 ) |
218 ( buf[ 6 ] << 16 ) |
219 ( buf[ 5 ] << 8 ) |
220 buf[ 4 ];
222 return TRUE;
226 /******************************************************************************
227 ** Read the resource data from a card *****************************************
228 ******************************************************************************/
230 static BOOL
231 ReadResourceData( struct ISAPNP_Card* card,
232 struct ISAPNPBase* res )
234 UBYTE check_sum = 0;
235 UWORD dev_num = 0;
236 BOOL read_more = TRUE;
237 struct ISAPNP_Device* dev = NULL;
238 struct ISAPNP_ResourceGroup* options = NULL;
239 struct ISAPNP_ResourceGroup* saved_options = NULL;
241 while( read_more )
243 ULONG i;
244 UBYTE rd;
246 UBYTE name;
247 ULONG length;
249 rd = GetNextResourceData( res );
251 check_sum += rd;
253 if( rd & PNPISA_RDF_LARGE )
255 name = PNPISA_RD_LARGE_ITEM_NAME( rd );
256 length = GetNextResourceData( res );
257 length |= GetNextResourceData( res ) << 8;
259 else
261 name = PNPISA_RD_SMALL_ITEM_NAME( rd );
262 length = PNPISA_RD_SMALL_LENGTH( rd );
265 switch( name )
267 case PNPISA_RDN_PNP_VERSION:
269 UBYTE ver;
271 ver = GetNextResourceData( res );
273 card->isapnpc_MinorPnPVersion = ver & 0x0f;
274 card->isapnpc_MajorPnPVersion = ver >> 4;
275 card->isapnpc_VendorPnPVersion = GetNextResourceData( res );
277 length -= 2;
278 break;
281 case PNPISA_RDN_LOGICAL_DEVICE_ID:
283 struct ISAPNP_Identifier* id;
284 UBYTE buf[ 4 ];
286 dev = ISAPNP_AllocDevice( res );
288 if( dev == NULL )
290 break;
293 dev->isapnpd_Card = card;
295 id = AllocVec( sizeof( *id ), MEMF_PUBLIC | MEMF_CLEAR );
297 if( id == NULL )
299 ISAPNP_FreeDevice( dev, res );
300 dev = NULL;
301 break;
304 buf[ 0 ] = GetNextResourceData( res );
305 buf[ 1 ] = GetNextResourceData( res );
306 buf[ 2 ] = GetNextResourceData( res );
307 buf[ 3 ] = GetNextResourceData( res );
309 length -= 4;
311 if( ! DecodeID( buf, id ) )
313 FreeVec( id );
314 ISAPNP_FreeDevice( dev, res );
315 dev = NULL;
316 break;
319 AddTail( (struct List*) &dev->isapnpd_IDs, (struct Node*) id );
321 options = dev->isapnpd_Options;
323 dev->isapnpd_SupportedCommands = GetNextResourceData( res );
324 --length;
326 if( length > 0 )
328 dev->isapnpd_SupportedCommands |= GetNextResourceData( res ) << 8;
331 dev->isapnpd_DeviceNumber = dev_num;
332 ++dev_num;
334 AddTail( &card->isapnpc_Devices, (struct Node*) dev );
336 break;
340 case PNPISA_RDN_COMPATIBLE_DEVICE_ID:
342 struct ISAPNP_Identifier* id;
343 UBYTE buf[ 4 ];
345 if( dev == NULL )
347 break;
350 id = AllocVec( sizeof( *id ), MEMF_PUBLIC | MEMF_CLEAR );
352 if( id == NULL )
354 break;
357 buf[ 0 ] = GetNextResourceData( res );
358 buf[ 1 ] = GetNextResourceData( res );
359 buf[ 2 ] = GetNextResourceData( res );
360 buf[ 3 ] = GetNextResourceData( res );
362 length -= 4;
364 if( ! DecodeID( buf, id ) )
366 FreeVec( id );
367 break;
370 AddTail( (struct List*) &dev->isapnpd_IDs, (struct Node*) id );
372 break;
375 case PNPISA_RDN_IRQ_FORMAT:
377 struct ISAPNP_IRQResource* r;
379 r = (struct ISAPNP_IRQResource*)
380 ISAPNP_AllocResource( ISAPNP_NT_IRQ_RESOURCE, res );
382 if( r == NULL )
384 break;
387 r->isapnpirqr_IRQMask = GetNextResourceData( res );
388 r->isapnpirqr_IRQMask |= GetNextResourceData( res ) << 8;
389 length -= 2;
391 if( length > 0 )
393 r->isapnpirqr_IRQType = GetNextResourceData( res );
394 --length;
396 else
398 r->isapnpirqr_IRQType = ISAPNP_IRQRESOURCE_ITF_HIGH_EDGE;
401 AddTail( (struct List*) &options->isapnprg_Resources, (struct Node*) r );
403 break;
407 case PNPISA_RDN_DMA_FORMAT:
409 struct ISAPNP_DMAResource* r;
411 r = (struct ISAPNP_DMAResource*)
412 ISAPNP_AllocResource( ISAPNP_NT_DMA_RESOURCE, res );
414 if( r == NULL )
416 break;
419 r->isapnpdmar_ChannelMask = GetNextResourceData( res );
420 r->isapnpdmar_Flags = GetNextResourceData( res );
422 length -= 2;
424 AddTail( (struct List*) &options->isapnprg_Resources, (struct Node*) r );
426 break;
429 case PNPISA_RDN_START_DF:
431 struct ISAPNP_ResourceGroup* rg;
432 UBYTE pri;
434 if( length > 0 )
436 pri = GetNextResourceData( res );
437 --length;
439 else
441 pri = 1;
444 switch( pri )
446 case 0:
447 pri = ISAPNP_RG_PRI_GOOD;
448 break;
450 case 1:
451 default:
452 pri = ISAPNP_RG_PRI_ACCEPTABLE;
453 break;
455 case 2:
456 pri = ISAPNP_RG_PRI_SUBOPTIMAL;
457 break;
460 rg = ISAPNP_AllocResourceGroup( pri, res );
462 if( rg == NULL )
464 break;
467 // Insert in priority order
469 if( saved_options == NULL )
471 saved_options = options;
474 Enqueue( (struct List*) &saved_options->isapnprg_ResourceGroups,
475 (struct Node*) rg );
477 options = rg;
479 break;
483 case PNPISA_RDN_END_DF:
485 options = saved_options;
486 saved_options = NULL;
488 break;
491 case PNPISA_RDN_IO_PORT:
493 struct ISAPNP_IOResource* r;
495 r = (struct ISAPNP_IOResource*)
496 ISAPNP_AllocResource( ISAPNP_NT_IO_RESOURCE, res );
498 if( r == NULL )
500 break;
503 r->isapnpior_Flags = GetNextResourceData( res );
505 r->isapnpior_MinBase = GetNextResourceData( res );
506 r->isapnpior_MinBase |= GetNextResourceData( res ) << 8;
508 r->isapnpior_MaxBase = GetNextResourceData( res );
509 r->isapnpior_MaxBase |= GetNextResourceData( res ) << 8;
511 r->isapnpior_Alignment = GetNextResourceData( res );
512 r->isapnpior_Length = GetNextResourceData( res );
514 length -= 7;
516 AddTail( (struct List*) &options->isapnprg_Resources, (struct Node*) r );
518 break;
522 case PNPISA_RDN_FIXED_IO_PORT:
524 struct ISAPNP_IOResource* r;
526 r = (struct ISAPNP_IOResource*)
527 ISAPNP_AllocResource( ISAPNP_NT_IO_RESOURCE, res );
529 if( r == NULL )
531 break;
534 r->isapnpior_Flags = 0;
535 r->isapnpior_MinBase = GetNextResourceData( res );
536 r->isapnpior_MinBase |= GetNextResourceData( res ) << 8;
537 r->isapnpior_MaxBase = r->isapnpior_MinBase;
538 r->isapnpior_Alignment = 1;
539 r->isapnpior_Length = GetNextResourceData( res );
541 length -= 3;
543 AddTail( (struct List*) &options->isapnprg_Resources, (struct Node*) r );
545 break;
549 case PNPISA_RDN_ANSI_IDENTIFIER:
551 STRPTR id = AllocVec( length + 1, MEMF_PUBLIC );
553 if( id == NULL )
555 break;
558 // Attach identifier to either the card or the logical device
560 if( dev == NULL )
562 FreeVec( card->isapnpc_Node.ln_Name );
564 card->isapnpc_Node.ln_Name = id;
566 else
568 FreeVec( dev->isapnpd_Node.ln_Name );
570 dev->isapnpd_Node.ln_Name = id;
573 while( length > 0 )
575 *id = GetNextResourceData( res );
577 ++id;
578 --length;
581 // Terminate the string
583 *id = '\0';
585 break;
589 case PNPISA_RDN_END_TAG:
591 UBYTE cs;
593 cs = GetNextResourceData( res );
594 --length;
596 if( cs == 0 )
598 check_sum = 0;
600 else
602 check_sum += cs;
605 read_more = FALSE;
606 break;
610 default:
611 bug( "UNKNOWN RESOURCE: %02lx, length %ld: ", name, length );
613 while( length > 0 )
615 bug( "%02lx ", GetNextResourceData( res ) );
616 --length;
619 bug( "\n" );
620 break;
623 // Make sure we have read all data for this name
625 while( length > 0 )
627 bug( "*** " );
628 GetNextResourceData( res );
629 --length;
633 D(bug( "Check sum: %ld\n", check_sum ));
635 return TRUE;
639 /******************************************************************************
640 ** Assign a CSN to all cards and build the card/device database ***************
641 ******************************************************************************/
643 static ULONG
644 AddCards( UBYTE rd_data_port_value,
645 struct ISAPNPBase* res )
647 UBYTE csn = 0;
649 while( TRUE )
651 struct ISAPNP_Card* card;
653 // Move all cards (without a CSN) to the isolate state and the card
654 // in config state to the sleep state.
656 SetPnPReg( PNPISA_REG_WAKE, 0, res );
658 // Set port to read from
660 SetPnPReg( PNPISA_REG_SET_RD_DATA_PORT, rd_data_port_value, res );
661 res->m_RegReadData = rd_data_port_value;
663 card = ISAPNP_AllocCard( res );
665 if( card == NULL )
667 break;
670 if( ReadSerialIdentifier( card, res ) )
672 // Assign a CSN to the card and move it to the config state
674 ++csn;
675 SetPnPReg( PNPISA_REG_CARD_SELECT_NUMBER, csn, res );
677 // Read the resource data
679 if( ReadResourceData( card, res ) )
681 card->isapnpc_CSN = csn;
683 AddTail( &res->m_Cards, (struct Node*) card );
685 else
687 ISAPNP_FreeCard( card, res );
690 else
692 ISAPNP_FreeCard( card, res );
694 break;
698 return csn;
702 /******************************************************************************
703 ** Scan for all PNP ISA cards *************************************************
704 ******************************************************************************/
706 BOOL ASMCALL
707 ISAPNP_ScanCards( REG( a6, struct ISAPNPBase* res ) )
709 int read_port_value;
710 int cards = 0;
712 SendInitiationKey( res );
714 // Make all cards lose their CSN
716 SetPnPReg( PNPISA_REG_CONFIG_CONTROL,
717 PNPISA_CCF_RESET_CSN,
718 res );
720 for( read_port_value = 0x80;
721 read_port_value <= 0xff;
722 read_port_value += 0x10 )
724 cards = AddCards( read_port_value, res );
726 if( cards > 0 )
728 break;
732 // Reset all cards
734 SetPnPReg( PNPISA_REG_CONFIG_CONTROL,
735 PNPISA_CCF_RESET |
736 PNPISA_CCF_WAIT_FOR_KEY |
737 PNPISA_CCF_RESET_CSN,
738 res );
740 return cards != 0;
744 /******************************************************************************
745 ** Configure all cards ********************************************************
746 ******************************************************************************/
749 static BOOL
750 FindNextCardConfiguration( struct ISAPNP_Device* dev,
751 struct ResourceContext* ctx,
752 struct ISAPNPBase* res );
755 int cp = 0;
757 static BOOL
758 FindConfiguration( struct ISAPNP_Device* dev,
759 struct ResourceContext* ctx,
760 struct ISAPNPBase* res )
762 BOOL rc = FALSE;
764 struct ISAPNP_ResourceGroup* rg;
765 struct ResourceIteratorList* ril = NULL;
767 if( dev->isapnpd_Disabled || dev->isapnpd_Card->isapnpc_Disabled )
769 // Skip to next device
771 return FindNextCardConfiguration( dev, ctx, res );
774 ril = AllocResourceIteratorList( &dev->isapnpd_Options->isapnprg_Resources, ctx );
776 if( ril != NULL )
778 BOOL ril_iter_ok = TRUE;
780 while( ! rc && ril_iter_ok )
782 if( dev->isapnpd_Options->isapnprg_ResourceGroups.mlh_Head->mln_Succ != NULL )
784 // Handle resource options as well
786 for( rg = (struct ISAPNP_ResourceGroup*)
787 dev->isapnpd_Options->isapnprg_ResourceGroups.mlh_Head;
788 ! rc && rg->isapnprg_MinNode.mln_Succ != NULL;
789 rg = (struct ISAPNP_ResourceGroup*) rg->isapnprg_MinNode.mln_Succ )
791 struct ResourceIteratorList* ril_option = NULL;
793 ril_option = AllocResourceIteratorList( &rg->isapnprg_Resources, ctx );
795 if( ril_option != NULL )
797 BOOL ril2_iter_ok = TRUE;
799 while( ! rc && ril2_iter_ok )
801 rc = FindNextCardConfiguration( dev, ctx, res );
803 //if( cp > 2 ) return FALSE; else ++cp;
805 if( ! rc )
807 ril2_iter_ok = IncResourceIteratorList( ril_option, ctx );
809 else
811 // Allocate resources for current iterators
813 rc = CreateResouces( ril_option,
814 (struct List*) &dev->isapnpd_Resources,
815 res );
816 break;
820 if( ! FreeResourceIteratorList( ril_option, ctx ) )
822 break;
827 else
829 // Fixed resources only
831 rc = FindNextCardConfiguration( dev, ctx, res );
834 if( ! rc )
836 ril_iter_ok = IncResourceIteratorList( ril, ctx );
838 else
840 // Allocate resources for current iterators
842 // NOTE! These resources muct be FIRST in the resource list
843 // in order to maintain the descriptor order.
845 struct MinList tmp;
846 struct Node* n;
848 NewList( (struct List* ) &tmp );
850 rc = CreateResouces( ril, (struct List*) &tmp,
851 res );
853 while( ( n = RemTail( (struct List* ) &tmp ) ) != NULL )
855 AddHead( (struct List*) &dev->isapnpd_Resources, n );
858 break;
862 FreeResourceIteratorList( ril, ctx );
865 return rc;
869 static BOOL
870 FindNextCardConfiguration( struct ISAPNP_Device* dev,
871 struct ResourceContext* ctx,
872 struct ISAPNPBase* res )
874 BOOL rc = FALSE;
876 // Configure next logical device, if any
878 if( dev->isapnpd_Node.ln_Succ->ln_Succ != NULL )
880 // Same card, next device
881 rc = FindConfiguration( (struct ISAPNP_Device*) dev->isapnpd_Node.ln_Succ,
882 ctx, res );
884 else
886 struct ISAPNP_Card* next_card = (struct ISAPNP_Card*)
887 dev->isapnpd_Card->isapnpc_Node.ln_Succ;
889 if( next_card->isapnpc_Node.ln_Succ != NULL &&
890 next_card->isapnpc_Devices.lh_Head->ln_Succ != NULL )
893 rc = FindConfiguration( (struct ISAPNP_Device*)
894 next_card->isapnpc_Devices.lh_Head,
895 ctx, res );
897 else
899 // This was the last device on the last card!
901 rc = TRUE;
905 return rc;
909 BOOL
910 ProgramConfiguration( struct ISAPNPBase* res )
912 struct ISAPNP_Device* dev = NULL;
914 UBYTE csn = 0;
916 while( ( dev = ISAPNP_FindDevice( dev, -1, -1, -1, res ) ) != NULL )
918 struct ISAPNP_Resource* resource;
920 UBYTE mem_reg = PNPISA_REG_MEMORY_BASE_ADDRESS_HIGH_0;
921 UBYTE io_reg = PNPISA_REG_IO_PORT_BASE_ADDRESS_HIGH_0;
922 UBYTE int_reg = PNPISA_REG_INTERRUPT_REQUEST_LEVEL_SELECT_0;
923 UBYTE dma_reg = PNPISA_REG_DMA_CHANNEL_SELECT_0;
925 if( dev->isapnpd_Card->isapnpc_CSN != 0 )
927 // Don't program non-pnp devices!
929 if( dev->isapnpd_Card->isapnpc_CSN != csn )
931 csn = dev->isapnpd_Card->isapnpc_CSN;
933 // Wake the new card
935 D(bug( "Woke up card %ld\n", dev->isapnpd_Card->isapnpc_CSN ));
936 SetPnPReg( PNPISA_REG_WAKE, dev->isapnpd_Card->isapnpc_CSN, res );
939 // Select logical device
941 D(bug( "Selected device %ld\n", dev->isapnpd_DeviceNumber ));
942 SetPnPReg( PNPISA_REG_LOGICAL_DEVICE_NUMBER, dev->isapnpd_DeviceNumber, res );
944 for( resource = (struct ISAPNP_Resource*) dev->isapnpd_Resources.mlh_Head;
945 resource->isapnpr_MinNode.mln_Succ != NULL;
946 resource = (struct ISAPNP_Resource*) resource->isapnpr_MinNode.mln_Succ )
948 switch( resource->isapnpr_Type )
950 case ISAPNP_NT_IRQ_RESOURCE:
952 struct ISAPNP_IRQResource* r = (struct ISAPNP_IRQResource*) resource;
953 int b;
955 for( b = 0; b < 16; ++b )
957 if( r->isapnpirqr_IRQMask & ( 1 << b ) )
959 D(bug( "Programmed interrupt %ld in %lx\n", b, int_reg ));
960 SetPnPReg( int_reg, b, res);
961 break;
965 b = 0;
967 if( ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_HIGH_EDGE ) ||
968 ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_HIGH_LEVEL ) )
970 b |= 2;
973 if( ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_HIGH_LEVEL ) ||
974 ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_LOW_LEVEL ) )
976 b |= 1;
979 D(bug( "Programmed interrupt mode %ld in %lx\n", b, int_reg + 1 ));
980 SetPnPReg( int_reg + 1, b, res );
982 int_reg += 2;
984 break;
987 case ISAPNP_NT_DMA_RESOURCE:
989 struct ISAPNP_DMAResource* r = (struct ISAPNP_DMAResource*) resource;
990 int b;
992 for( b = 0; b < 8; ++b )
994 if( r->isapnpdmar_ChannelMask & ( 1 << b ) )
996 D(bug( "Programmed dma channel %ld in %lx\n", b, dma_reg ));
997 SetPnPReg( dma_reg, b, res );
998 break;
1002 dma_reg += 1;
1004 break;
1007 case ISAPNP_NT_IO_RESOURCE:
1009 struct ISAPNP_IOResource* r = (struct ISAPNP_IOResource*) resource;
1011 D(bug( "Programmed IO base %04lx in %lx\n", r->isapnpior_MinBase, io_reg ));
1013 SetPnPReg( io_reg, r->isapnpior_MinBase >> 8, res );
1014 SetPnPReg( io_reg + 1, r->isapnpior_MinBase & 0xff, res );
1016 io_reg += 2;
1018 break;
1021 default:
1022 bug( "Unsupported resource!\n" );
1023 return FALSE;
1027 // Activate the device
1028 D(bug( "Activated the device\n" ));
1029 SetPnPReg( PNPISA_REG_ACTIVATE, 1, res );
1033 // Move all cards to the wfk state
1035 D(bug( "Moved cards to wfk\n" ));
1037 SetPnPReg( PNPISA_REG_CONFIG_CONTROL,
1038 PNPISA_CCF_WAIT_FOR_KEY,
1039 res );
1041 return TRUE;
1045 BOOL ASMCALL
1046 ISAPNP_ConfigureCards( REG( a6, struct ISAPNPBase* res ) )
1048 BOOL rc = FALSE;
1050 struct ISAPNP_Device* dev;
1052 dev = ISAPNP_FindDevice( NULL, -1, -1, -1, res );
1054 if( dev != NULL )
1056 struct ResourceContext* ctx;
1058 ctx = AllocResourceIteratorContext();
1060 if( ctx != NULL )
1062 if( ! FindConfiguration( dev, ctx, res ) )
1064 D(bug( "Unable to find a usable configuration.\n" ));
1066 else
1068 if( ! ProgramConfiguration( res ) )
1070 D(bug( "Failed to program configuration!\n" ));
1072 else
1074 rc = TRUE;
1078 FreeResourceIteratorContext( ctx );
1082 return rc;