Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / rom / isapnp / pnp.c
blobb7de922ec9abf74d09819a23ae85f65836d4b90a
1 /* $Id$ */
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-2013 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 AROS_LH0(BOOL, ISAPNP_ScanCards,
707 struct ISAPNPBase *, res, 26, ISAPNP)
709 AROS_LIBFUNC_INIT
711 int read_port_value;
712 int cards = 0;
714 SendInitiationKey( res );
716 // Make all cards lose their CSN
718 SetPnPReg( PNPISA_REG_CONFIG_CONTROL,
719 PNPISA_CCF_RESET_CSN,
720 res );
722 for( read_port_value = 0x80;
723 read_port_value <= 0xff;
724 read_port_value += 0x10 )
726 cards = AddCards( read_port_value, res );
728 if( cards > 0 )
730 break;
734 // Reset all cards
736 SetPnPReg( PNPISA_REG_CONFIG_CONTROL,
737 PNPISA_CCF_RESET |
738 PNPISA_CCF_WAIT_FOR_KEY |
739 PNPISA_CCF_RESET_CSN,
740 res );
742 return cards != 0;
744 AROS_LIBFUNC_EXIT
748 /******************************************************************************
749 ** Configure all cards ********************************************************
750 ******************************************************************************/
753 static BOOL
754 FindNextCardConfiguration( struct ISAPNP_Device* dev,
755 struct ResourceContext* ctx,
756 struct ISAPNPBase* res );
759 int cp = 0;
761 static BOOL
762 FindConfiguration( struct ISAPNP_Device* dev,
763 struct ResourceContext* ctx,
764 struct ISAPNPBase* res )
766 BOOL rc = FALSE;
768 struct ISAPNP_ResourceGroup* rg;
769 struct ResourceIteratorList* ril = NULL;
771 if( dev->isapnpd_Disabled || dev->isapnpd_Card->isapnpc_Disabled )
773 // Skip to next device
775 return FindNextCardConfiguration( dev, ctx, res );
778 ril = AllocResourceIteratorList( &dev->isapnpd_Options->isapnprg_Resources, ctx );
780 if( ril != NULL )
782 BOOL ril_iter_ok = TRUE;
784 while( ! rc && ril_iter_ok )
786 if( dev->isapnpd_Options->isapnprg_ResourceGroups.mlh_Head->mln_Succ != NULL )
788 // Handle resource options as well
790 for( rg = (struct ISAPNP_ResourceGroup*)
791 dev->isapnpd_Options->isapnprg_ResourceGroups.mlh_Head;
792 ! rc && rg->isapnprg_MinNode.mln_Succ != NULL;
793 rg = (struct ISAPNP_ResourceGroup*) rg->isapnprg_MinNode.mln_Succ )
795 struct ResourceIteratorList* ril_option = NULL;
797 ril_option = AllocResourceIteratorList( &rg->isapnprg_Resources, ctx );
799 if( ril_option != NULL )
801 BOOL ril2_iter_ok = TRUE;
803 while( ! rc && ril2_iter_ok )
805 rc = FindNextCardConfiguration( dev, ctx, res );
807 //if( cp > 2 ) return FALSE; else ++cp;
809 if( ! rc )
811 ril2_iter_ok = IncResourceIteratorList( ril_option, ctx );
813 else
815 // Allocate resources for current iterators
817 rc = CreateResouces( ril_option,
818 (struct List*) &dev->isapnpd_Resources,
819 res );
820 break;
824 if( ! FreeResourceIteratorList( ril_option, ctx ) )
826 break;
831 else
833 // Fixed resources only
835 rc = FindNextCardConfiguration( dev, ctx, res );
838 if( ! rc )
840 ril_iter_ok = IncResourceIteratorList( ril, ctx );
842 else
844 // Allocate resources for current iterators
846 // NOTE! These resources muct be FIRST in the resource list
847 // in order to maintain the descriptor order.
849 struct MinList tmp;
850 struct Node* n;
852 NewList( (struct List* ) &tmp );
854 rc = CreateResouces( ril, (struct List*) &tmp,
855 res );
857 while( ( n = RemTail( (struct List* ) &tmp ) ) != NULL )
859 AddHead( (struct List*) &dev->isapnpd_Resources, n );
862 break;
866 FreeResourceIteratorList( ril, ctx );
869 return rc;
873 static BOOL
874 FindNextCardConfiguration( struct ISAPNP_Device* dev,
875 struct ResourceContext* ctx,
876 struct ISAPNPBase* res )
878 BOOL rc = FALSE;
880 // Configure next logical device, if any
882 if( dev->isapnpd_Node.ln_Succ->ln_Succ != NULL )
884 // Same card, next device
885 rc = FindConfiguration( (struct ISAPNP_Device*) dev->isapnpd_Node.ln_Succ,
886 ctx, res );
888 else
890 struct ISAPNP_Card* next_card = (struct ISAPNP_Card*)
891 dev->isapnpd_Card->isapnpc_Node.ln_Succ;
893 if( next_card->isapnpc_Node.ln_Succ != NULL &&
894 next_card->isapnpc_Devices.lh_Head->ln_Succ != NULL )
897 rc = FindConfiguration( (struct ISAPNP_Device*)
898 next_card->isapnpc_Devices.lh_Head,
899 ctx, res );
901 else
903 // This was the last device on the last card!
905 rc = TRUE;
909 return rc;
913 BOOL
914 ProgramConfiguration( struct ISAPNPBase* res )
916 struct ISAPNP_Device* dev = NULL;
918 UBYTE csn = 0;
920 while( ( dev = ISAPNP_FindDevice( dev, -1, -1, -1, res ) ) != NULL )
922 struct ISAPNP_Resource* resource;
924 UBYTE mem_reg = PNPISA_REG_MEMORY_BASE_ADDRESS_HIGH_0;
925 UBYTE io_reg = PNPISA_REG_IO_PORT_BASE_ADDRESS_HIGH_0;
926 UBYTE int_reg = PNPISA_REG_INTERRUPT_REQUEST_LEVEL_SELECT_0;
927 UBYTE dma_reg = PNPISA_REG_DMA_CHANNEL_SELECT_0;
929 if( dev->isapnpd_Card->isapnpc_CSN != 0 )
931 // Don't program non-pnp devices!
933 if( dev->isapnpd_Card->isapnpc_CSN != csn )
935 csn = dev->isapnpd_Card->isapnpc_CSN;
937 // Wake the new card
939 D(bug( "Woke up card %ld\n", dev->isapnpd_Card->isapnpc_CSN ));
940 SetPnPReg( PNPISA_REG_WAKE, dev->isapnpd_Card->isapnpc_CSN, res );
943 // Select logical device
945 D(bug( "Selected device %ld\n", dev->isapnpd_DeviceNumber ));
946 SetPnPReg( PNPISA_REG_LOGICAL_DEVICE_NUMBER, dev->isapnpd_DeviceNumber, res );
948 for( resource = (struct ISAPNP_Resource*) dev->isapnpd_Resources.mlh_Head;
949 resource->isapnpr_MinNode.mln_Succ != NULL;
950 resource = (struct ISAPNP_Resource*) resource->isapnpr_MinNode.mln_Succ )
952 switch( resource->isapnpr_Type )
954 case ISAPNP_NT_IRQ_RESOURCE:
956 struct ISAPNP_IRQResource* r = (struct ISAPNP_IRQResource*) resource;
957 int b;
959 for( b = 0; b < 16; ++b )
961 if( r->isapnpirqr_IRQMask & ( 1 << b ) )
963 D(bug( "Programmed interrupt %ld in %lx\n", b, int_reg ));
964 SetPnPReg( int_reg, b, res);
965 break;
969 b = 0;
971 if( ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_HIGH_EDGE ) ||
972 ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_HIGH_LEVEL ) )
974 b |= 2;
977 if( ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_HIGH_LEVEL ) ||
978 ( r->isapnpirqr_IRQType & ISAPNP_IRQRESOURCE_ITF_LOW_LEVEL ) )
980 b |= 1;
983 D(bug( "Programmed interrupt mode %ld in %lx\n", b, int_reg + 1 ));
984 SetPnPReg( int_reg + 1, b, res );
986 int_reg += 2;
988 break;
991 case ISAPNP_NT_DMA_RESOURCE:
993 struct ISAPNP_DMAResource* r = (struct ISAPNP_DMAResource*) resource;
994 int b;
996 for( b = 0; b < 8; ++b )
998 if( r->isapnpdmar_ChannelMask & ( 1 << b ) )
1000 D(bug( "Programmed dma channel %ld in %lx\n", b, dma_reg ));
1001 SetPnPReg( dma_reg, b, res );
1002 break;
1006 dma_reg += 1;
1008 break;
1011 case ISAPNP_NT_IO_RESOURCE:
1013 struct ISAPNP_IOResource* r = (struct ISAPNP_IOResource*) resource;
1015 D(bug( "Programmed IO base %04lx in %lx\n", r->isapnpior_MinBase, io_reg ));
1017 SetPnPReg( io_reg, r->isapnpior_MinBase >> 8, res );
1018 SetPnPReg( io_reg + 1, r->isapnpior_MinBase & 0xff, res );
1020 io_reg += 2;
1022 break;
1025 default:
1026 bug( "Unsupported resource!\n" );
1027 return FALSE;
1031 // Activate the device
1032 D(bug( "Activated the device\n" ));
1033 SetPnPReg( PNPISA_REG_ACTIVATE, 1, res );
1037 // Move all cards to the wfk state
1039 D(bug( "Moved cards to wfk\n" ));
1041 SetPnPReg( PNPISA_REG_CONFIG_CONTROL,
1042 PNPISA_CCF_WAIT_FOR_KEY,
1043 res );
1045 return TRUE;
1049 AROS_LH0(BOOL, ISAPNP_ConfigureCards,
1050 struct ISAPNPBase *, res, 27, ISAPNP)
1052 AROS_LIBFUNC_INIT
1054 BOOL rc = FALSE;
1056 struct ISAPNP_Device* dev;
1058 dev = ISAPNP_FindDevice( NULL, -1, -1, -1, res );
1060 if( dev != NULL )
1062 struct ResourceContext* ctx;
1064 ctx = AllocResourceIteratorContext();
1066 if( ctx != NULL )
1068 if( ! FindConfiguration( dev, ctx, res ) )
1070 D(bug( "Unable to find a usable configuration.\n" ));
1072 else
1074 if( ! ProgramConfiguration( res ) )
1076 D(bug( "Failed to program configuration!\n" ));
1078 else
1080 rc = TRUE;
1084 FreeResourceIteratorContext( ctx );
1088 return rc;
1090 AROS_LIBFUNC_EXIT