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,
26 #include "CompilerSpecific.h"
28 #include <aros/libcall.h>
29 #include <exec/memory.h>
30 #include <exec/resident.h>
31 #include <devices/timer.h>
33 #include <clib/alib_protos.h>
34 #include <proto/exec.h>
35 /*#include <proto/utility.h>*/
39 #include <resources/isapnp.h>
40 #include "isapnp_private.h"
43 #include "controller.h"
47 #include "pnp_structs.h"
50 PatchBrokenCards( struct ISAPNPBase
* res
);
52 /******************************************************************************
53 ** Resource resident structure ************************************************
54 ******************************************************************************/
56 extern const char LIBEND
;
57 extern const char ResName
[];
58 extern const char IDString
[];
59 static const APTR InitTable
[4];
61 const struct Resident RomTag
=
64 (struct Resident
*) &RomTag
,
65 (struct Resident
*) &LIBEND
,
66 RTF_AUTOINIT
|RTF_COLDSTART
,
78 /******************************************************************************
79 ** Globals ********************************************************************
80 ******************************************************************************/
82 struct Device
* TimerBase
= NULL
;
83 /*struct ExecBase* SysBase = NULL;*/
84 /*struct IntuitionBase* IntuitionBase = NULL;*/
85 struct ISAPNPBase
* ISAPNPBase
= NULL
;
86 /*struct UtilityBase* UtilityBase = NULL;*/
88 static struct timerequest
*TimerIO
= NULL
;
90 const char ResName
[] = ISAPNPNAME
;
91 const char IDString
[] = ISAPNPNAME
" " VERS
"\r\n";
93 static const char VersTag
[] =
94 "$VER: " ISAPNPNAME
" " VERS
" ©2001 Martin Blom.\r\n";
96 /******************************************************************************
97 ** Resource initialization ****************************************************
98 ******************************************************************************/
100 struct ISAPNPBase
* ASMCALL
101 initRoutine( REG( d0
, struct ISAPNPBase
* res
),
102 REG( a0
, APTR seglist
),
103 REG( a6
, struct ExecBase
* sysbase
) )
105 D(bug("[ISAPNP] Init\n"));
110 // Set up the ISAPNPBase structure
112 res
->m_Library
.lib_Node
.ln_Type
= NT_RESOURCE
;
113 res
->m_Library
.lib_Node
.ln_Name
= (STRPTR
) ResName
;
114 res
->m_Library
.lib_Flags
= LIBF_SUMUSED
| LIBF_CHANGED
;
115 res
->m_Library
.lib_Version
= VERSION
;
116 res
->m_Library
.lib_Revision
= REVISION
;
117 res
->m_Library
.lib_IdString
= (STRPTR
) IDString
;
119 NewList( &res
->m_Cards
);
121 /* Base address, on i386 we don't have any mapping
122 res->m_Base = NULL; */
123 res
->m_RegReadData
= 0x0000;
125 if( ! ISAPNP_ScanCards( res
) )
129 Req( "No PnP ISA cards found.", res
);
130 FreeISAPNPBase( res
);
134 if( ! PatchBrokenCards( res
) )
136 FreeISAPNPBase( res
);
140 struct ISAPNP_Card
* card
;
142 card
= ISAPNP_AllocCard( res
);
146 Req( "Out of memory!", res
);
147 FreeISAPNPBase( res
);
151 static const char descr
[] = "Non-PnP devices";
154 d
= AllocVec( sizeof( descr
), MEMF_PUBLIC
);
158 CopyMem( (void*) descr
, d
, sizeof( descr
) );
159 card
->isapnpc_Node
.ln_Name
= d
;
162 card
->isapnpc_ID
.isapnpid_Vendor
[ 0 ] = '?';
163 card
->isapnpc_ID
.isapnpid_Vendor
[ 1 ] = '?';
164 card
->isapnpc_ID
.isapnpid_Vendor
[ 2 ] = '?';
165 card
->isapnpc_SerialNumber
= -1;
168 AddHead( &res
->m_Cards
, (struct Node
*) card
);
170 // Let's see if we're to disable any cards or devices etc
171 if( ! HandleStartArgs( card
, res
) )
173 // Error requester already displayed.
174 FreeISAPNPBase( res
);
178 if( ! ISAPNP_ConfigureCards( res
) )
180 // Unable to configure cards
182 Req( "Unable to configure the cards. This is most likely\n"
183 "because of an unresolvable hardware conflict.\n\n"
184 "Use the DISABLE_DEVICE tool type to disable one of\n"
185 "the devices in conflict.", res
);
186 FreeISAPNPBase( res
);
201 /******************************************************************************
202 ** Free all resources from ISAPNPBase *****************************************
203 ******************************************************************************/
206 FreeISAPNPBase( struct ISAPNPBase
* res
)
208 struct ISAPNP_Card
* card
;
210 while( ( card
= (struct ISAPNP_Card
*) RemHead( &res
->m_Cards
) ) )
212 ISAPNP_FreeCard( card
, ISAPNPBase
);
217 /******************************************************************************
218 ** Initialization tables ******************************************************
219 ******************************************************************************/
221 static const APTR funcTable
[] =
223 AROS_SLIB_ENTRY(ISAC_SetMasterInt
, ISAPNP
, 1),
224 AROS_SLIB_ENTRY(ISAC_GetMasterInt
, ISAPNP
, 2),
225 AROS_SLIB_ENTRY(ISAC_SetWaitState
, ISAPNP
, 3),
226 AROS_SLIB_ENTRY(ISAC_GetWaitState
, ISAPNP
, 4),
227 AROS_SLIB_ENTRY(ISAC_GetInterruptStatus
, ISAPNP
, 5),
228 AROS_SLIB_ENTRY(ISAC_GetRegByte
, ISAPNP
, 6),
229 AROS_SLIB_ENTRY(ISAC_SetRegByte
, ISAPNP
, 7),
230 AROS_SLIB_ENTRY(ISAC_GetRegWord
, ISAPNP
, 8),
231 AROS_SLIB_ENTRY(ISAC_SetRegWord
, ISAPNP
, 9),
232 AROS_SLIB_ENTRY(ISAC_GetRegLong
, ISAPNP
, 10),
233 AROS_SLIB_ENTRY(ISAC_SetRegLong
, ISAPNP
, 11),
234 AROS_SLIB_ENTRY(ISAC_ReadByte
, ISAPNP
, 12),
235 AROS_SLIB_ENTRY(ISAC_WriteByte
, ISAPNP
, 13),
236 AROS_SLIB_ENTRY(ISAC_ReadWord
, ISAPNP
, 14),
237 AROS_SLIB_ENTRY(ISAC_WriteWord
, ISAPNP
, 15),
238 AROS_SLIB_ENTRY(ISAC_ReadLong
, ISAPNP
, 16),
239 AROS_SLIB_ENTRY(ISAC_WriteLong
, ISAPNP
, 17),
241 AROS_SLIB_ENTRY(ISAPNP_AllocCard
, ISAPNP
, 18),
242 AROS_SLIB_ENTRY(ISAPNP_FreeCard
, ISAPNP
, 19),
243 AROS_SLIB_ENTRY(ISAPNP_AllocDevice
, ISAPNP
, 20),
244 AROS_SLIB_ENTRY(ISAPNP_FreeDevice
, ISAPNP
, 21),
245 AROS_SLIB_ENTRY(ISAPNP_AllocResourceGroup
, ISAPNP
, 22),
246 AROS_SLIB_ENTRY(ISAPNP_FreeResourceGroup
, ISAPNP
, 23),
247 AROS_SLIB_ENTRY(ISAPNP_AllocResource
, ISAPNP
, 24),
248 AROS_SLIB_ENTRY(ISAPNP_FreeResource
, ISAPNP
, 25),
250 AROS_SLIB_ENTRY(ISAPNP_ScanCards
, ISAPNP
, 26),
251 AROS_SLIB_ENTRY(ISAPNP_ConfigureCards
, ISAPNP
, 27),
253 AROS_SLIB_ENTRY(ISAPNP_FindCard
, ISAPNP
, 28),
254 AROS_SLIB_ENTRY(ISAPNP_FindDevice
, ISAPNP
, 29),
256 AROS_SLIB_ENTRY(ISAPNP_LockCardsA
, ISAPNP
, 30),
257 AROS_SLIB_ENTRY(ISAPNP_UnlockCards
, ISAPNP
, 31),
258 AROS_SLIB_ENTRY(ISAPNP_LockDevicesA
, ISAPNP
, 32),
259 AROS_SLIB_ENTRY(ISAPNP_UnlockDevices
, ISAPNP
, 33),
265 static const APTR InitTable
[4] =
267 (APTR
) sizeof( struct ISAPNPBase
),
273 /******************************************************************************
274 ** OpenLibs *******************************************************************
275 ******************************************************************************/
280 /* Utility Library (libnix depends on it, and our startup-code is not
281 executed when BindDriver LoadSeg()s us!) */
283 /* Intuition Library */
285 IntuitionBase = (struct IntuitionBase*) OpenLibrary( "intuition.library", 37 );
287 if( IntuitionBase == NULL )
292 UtilityBase = (struct UtilityBase *) OpenLibrary( "utility.library", 37 );
294 if( UtilityBase == NULL)
301 TimerIO
= (struct timerequest
*) AllocVec( sizeof(struct timerequest
),
302 MEMF_PUBLIC
| MEMF_CLEAR
);
309 if( OpenDevice( "timer.device",
318 TimerBase
= (struct Device
*) TimerIO
->tr_node
.io_Device
;
324 /******************************************************************************
325 ** CloseLibs *******************************************************************
326 ******************************************************************************/
331 if( TimerIO
!= NULL
)
333 CloseDevice( (struct IORequest
*) TimerIO
);
338 CloseLibrary( (struct Library*) UtilityBase );
339 CloseLibrary( (struct Library*) IntuitionBase );
343 /*IntuitionBase = NULL;
344 UtilityBase = NULL;*/
347 /******************************************************************************
348 ** Fix cards that have broken PnP ROMs ****************************************
349 ******************************************************************************/
352 PatchBrokenCards( struct ISAPNPBase
* res
)
354 struct ISAPNP_Device
* dev
= NULL
;
356 // Patch the wavetable device on SB AWE32 and AWE64
358 while( ( dev
= ISAPNP_FindDevice( dev
,
359 ISAPNP_MAKE_ID('C','T','L'),
364 struct ISAPNP_ResourceGroup
* rg
;
365 struct ISAPNP_IOResource
* r1
;
366 struct ISAPNP_IOResource
* r2
;
367 struct ISAPNP_IOResource
* r3
;
369 // Nuke all dependent options
371 while( ( rg
= (struct ISAPNP_ResourceGroup
*)
372 RemHead( (struct List
*) &dev
->isapnpd_Options
->isapnprg_ResourceGroups
) )
375 ISAPNP_FreeResourceGroup( rg
, res
);
378 rg
= ISAPNP_AllocResourceGroup( ISAPNP_RG_PRI_ACCEPTABLE
, res
);
380 r1
= (struct ISAPNP_IOResource
*) ISAPNP_AllocResource( ISAPNP_NT_IO_RESOURCE
, res
);
381 r2
= (struct ISAPNP_IOResource
*) ISAPNP_AllocResource( ISAPNP_NT_IO_RESOURCE
, res
);
382 r3
= (struct ISAPNP_IOResource
*) ISAPNP_AllocResource( ISAPNP_NT_IO_RESOURCE
, res
);
384 if( rg
== NULL
|| r1
== NULL
|| r2
== NULL
|| r3
== NULL
)
386 ISAPNP_FreeResourceGroup( rg
, res
);
387 ISAPNP_FreeResource( (struct ISAPNP_Resource
*) r1
, res
);
388 ISAPNP_FreeResource( (struct ISAPNP_Resource
*) r2
, res
);
389 ISAPNP_FreeResource( (struct ISAPNP_Resource
*) r3
, res
);
394 r1
->isapnpior_Flags
= ISAPNP_IORESOURCE_FF_FULL_DECODE
;
395 r2
->isapnpior_Flags
= ISAPNP_IORESOURCE_FF_FULL_DECODE
;
396 r3
->isapnpior_Flags
= ISAPNP_IORESOURCE_FF_FULL_DECODE
;
398 r1
->isapnpior_Alignment
= 1;
399 r2
->isapnpior_Alignment
= 1;
400 r3
->isapnpior_Alignment
= 1;
402 r1
->isapnpior_Length
= 4;
403 r2
->isapnpior_Length
= 4;
404 r3
->isapnpior_Length
= 4;
406 r1
->isapnpior_MinBase
= 0x620;
407 r2
->isapnpior_MinBase
= 0xa20;
408 r3
->isapnpior_MinBase
= 0xe20;
410 r1
->isapnpior_MaxBase
= 0x620;
411 r2
->isapnpior_MaxBase
= 0xa20;
412 r3
->isapnpior_MaxBase
= 0xe20;
414 AddTail( (struct List
*) &rg
->isapnprg_Resources
, (struct Node
*) r1
);
415 AddTail( (struct List
*) &rg
->isapnprg_Resources
, (struct Node
*) r2
);
416 AddTail( (struct List
*) &rg
->isapnprg_Resources
, (struct Node
*) r3
);
418 AddTail( (struct List
*) &dev
->isapnpd_Options
->isapnprg_ResourceGroups
,