Unified country codes
[AROS.git] / rom / isapnp / init.c
blob815d7e7e9fb41bf26669a466880f2f54b1ebafff
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 <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>*/
37 #include <stdlib.h>
39 #include <resources/isapnp.h>
40 #include "isapnp_private.h"
41 #include "version.h"
43 #include "controller.h"
44 #include "devices.h"
45 #include "init.h"
46 #include "pnp.h"
47 #include "pnp_structs.h"
49 static BOOL
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 =
63 RTC_MATCHWORD,
64 (struct Resident *) &RomTag,
65 (struct Resident *) &LIBEND,
66 RTF_AUTOINIT|RTF_COLDSTART,
67 VERSION,
68 NT_RESOURCE,
69 12, /* priority */
70 (BYTE *) ResName,
71 (BYTE *) IDString,
72 (APTR) &InitTable,
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"));
106 SysBase = sysbase;
108 if(OpenLibs() )
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 ) )
127 // No cards found
129 Req( "No PnP ISA cards found.", res );
130 FreeISAPNPBase( res );
132 else
134 if( ! PatchBrokenCards( res ) )
136 FreeISAPNPBase( res );
138 else
140 struct ISAPNP_Card* card;
142 card = ISAPNP_AllocCard( res );
144 if( card == NULL )
146 Req( "Out of memory!", res );
147 FreeISAPNPBase( res );
149 else
151 static const char descr[] = "Non-PnP devices";
152 char* d;
154 d = AllocVec( sizeof( descr ), MEMF_PUBLIC );
156 if( d != NULL )
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;
167 // Add *first*
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 );
176 else
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 );
188 else
189 ISAPNPBase = res;
196 return ISAPNPBase;
201 /******************************************************************************
202 ** Free all resources from ISAPNPBase *****************************************
203 ******************************************************************************/
205 void
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),
261 (APTR) -1
265 static const APTR InitTable[4] =
267 (APTR) sizeof( struct ISAPNPBase ),
268 (APTR) &funcTable,
270 (APTR) initRoutine
273 /******************************************************************************
274 ** OpenLibs *******************************************************************
275 ******************************************************************************/
277 BOOL
278 OpenLibs( void )
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 )
289 return FALSE;
292 UtilityBase = (struct UtilityBase *) OpenLibrary( "utility.library", 37 );
294 if( UtilityBase == NULL)
296 return FALSE;
299 /* Timer Device */
301 TimerIO = (struct timerequest *) AllocVec( sizeof(struct timerequest),
302 MEMF_PUBLIC | MEMF_CLEAR );
304 if( TimerIO == NULL)
306 return FALSE;
309 if( OpenDevice( "timer.device",
310 UNIT_MICROHZ,
311 (struct IORequest *)
312 TimerIO,
313 0) != 0 )
315 return FALSE;
318 TimerBase = (struct Device *) TimerIO->tr_node.io_Device;
320 return TRUE;
324 /******************************************************************************
325 ** CloseLibs *******************************************************************
326 ******************************************************************************/
328 void
329 CloseLibs( void )
331 if( TimerIO != NULL )
333 CloseDevice( (struct IORequest *) TimerIO );
336 FreeVec( TimerIO );
338 CloseLibrary( (struct Library*) UtilityBase );
339 CloseLibrary( (struct Library*) IntuitionBase );
341 TimerIO = NULL;
342 TimerBase = NULL;
343 /*IntuitionBase = NULL;
344 UtilityBase = NULL;*/
347 /******************************************************************************
348 ** Fix cards that have broken PnP ROMs ****************************************
349 ******************************************************************************/
351 static BOOL
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'),
360 0x002,
362 res ) ) != NULL )
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 ) )
373 != NULL )
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 );
391 return FALSE;
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,
419 (struct Node*) rg );
422 return TRUE;