move delay code into separate function.
[AROS.git] / rom / isapnp / expansion_init.c
blob7cda8c2e13a879d3deb7c9532405a5c2f05741e3
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"
50 void
51 ReqA( const char* text, APTR args );
53 #define IntReq( text, args...) \
54 ( { ULONG _args[] = { args }; ReqA( (text), (APTR) _args ); } )
56 /******************************************************************************
57 ** ReqA ***********************************************************************
58 ******************************************************************************/
60 void
61 ReqA( const char* text, APTR args, struct ISAPNPBase *res )
63 struct EasyStruct es =
65 sizeof (struct EasyStruct),
67 (STRPTR) ISAPNPNAME " " VERS,
68 (STRPTR) text,
69 "OK"
71 struct IntuitionBase *IntuitionBase;
73 IntuitionBase = (struct IntuitionBase *)OpenLibrary("intution.library", 36);
74 if( IntuitionBase != NULL )
76 EasyRequestArgs( NULL, &es, NULL, args );
77 CloseLibrary(&IntuitionBase->LibNode);
81 void Req(const char *text, struct ISAPNPBase *res)
83 ReqA(text, NULL, res);
86 /******************************************************************************
87 ** Handle the tool types ******************************************************
88 ******************************************************************************/
90 static int
91 HexToInt( UBYTE c )
93 if( c >= '0' && c <= '9' )
95 return c - '0';
97 else if( c >= 'A' && c <= 'F' )
99 return c - 'A' + 10;
101 else if( c >= 'a' && c <= 'f' )
103 return c - 'a' + 10;
105 else
107 return -1;
111 // CTL0048 => "CTL\0" 4 8 -1 -1
112 // CTL0048/1236 => "CTL\0" 4 8 1236 -1
113 // CTL0048:0 => "CTL\0" 4 8 -1 0
114 // CTL0048/1236:0 => "CTL\0" 4 8 1236 0
116 static int
117 ParseID( UBYTE* string,
118 LONG* manufacturer,
119 WORD* product,
120 BYTE* revision,
121 LONG* serial,
122 WORD* logical_device )
124 int chars = 0;
125 LONG ser = -1;
126 LONG dev = -1;
128 *manufacturer = ISAPNP_MAKE_ID( ToUpper( string[ 0 ] ),
129 ToUpper( string[ 1 ] ),
130 ToUpper( string[ 2 ] ) );
132 *product = ( HexToInt( string[ 3 ] ) << 8 ) |
133 ( HexToInt( string[ 4 ] ) << 4 ) |
134 ( HexToInt( string[ 5 ] ) );
137 if( *product == -1 )
139 return 0;
142 *revision = HexToInt( string[ 6 ] );
144 if( *revision == -1 )
146 return 0;
149 chars = 7;
151 if( string[ chars ] == '/' )
153 int conv;
155 if( serial == NULL )
157 // Not allowed if we don't ask for it
158 return NULL;
161 conv = StrToLong( string + chars + 1, &ser );
163 if( conv == -1 )
165 return 0;
167 else
169 chars += conv + 1;
174 if( serial != NULL )
176 *serial = ser;
179 if( string[ chars ] == ':' )
181 int conv;
183 if( logical_device == NULL )
185 // Not allowed if we don't ask for it
186 return NULL;
189 conv = StrToLong( string + chars + 1, &dev );
191 if( conv == -1 )
193 return 0;
195 else
197 chars += conv + 1;
202 if( logical_device != NULL )
204 *logical_device = dev;
207 if( string[ chars ] != 0 && string[ chars ] != ' ' )
209 return 0;
212 return chars;
216 BOOL
217 HandleStartArgs( struct ISAPNP_Card* card,
218 struct ISAPNPBase* res )
220 UBYTE **tool_types = current_binding.cb_ToolTypes;
222 while( *tool_types )
224 if( Strnicmp( *tool_types, "DISABLE_CARD=", 13 ) == 0 )
226 LONG manufacturer;
227 WORD product;
228 BYTE revision;
229 LONG serial;
231 if( ParseID( *tool_types + 13,
232 &manufacturer, &product, &revision, &serial, NULL ) )
234 struct ISAPNP_Card* card = NULL;
236 while( ( card = ISAPNP_FindCard( card,
237 manufacturer,
238 product,
239 revision,
240 serial,
241 res ) ) != NULL )
243 card->isapnpc_Disabled = TRUE;
246 else
248 Req( "Illegal tool type: %s\n", (ULONG) *tool_types );
249 return FALSE;
252 else if( Strnicmp( *tool_types, "DISABLE_DEVICE=", 15 ) == 0 )
254 LONG manufacturer;
255 WORD product;
256 BYTE revision;
257 LONG serial;
258 WORD log_dev;
260 if( ParseID( *tool_types + 15,
261 &manufacturer, &product, &revision, &serial, &log_dev ) )
263 if( log_dev == -1 )
265 struct ISAPNP_Device* dev = NULL;
267 while( ( dev = ISAPNP_FindDevice( dev,
268 manufacturer,
269 product,
270 revision,
271 res ) ) != NULL )
273 dev->isapnpd_Disabled = TRUE;
276 else
278 struct ISAPNP_Card* card = NULL;
280 while( ( card = ISAPNP_FindCard( card,
281 manufacturer,
282 product,
283 revision,
284 serial,
285 res ) ) != NULL )
287 struct ISAPNP_Device* dev;
289 for( dev = (struct ISAPNP_Device*) card->isapnpc_Devices.lh_Head;
290 dev->isapnpd_Node.ln_Succ != NULL;
291 dev = (struct ISAPNP_Device*) dev->isapnpd_Node.ln_Succ )
293 if( dev->isapnpd_DeviceNumber == (UWORD) log_dev )
295 dev->isapnpd_Disabled = TRUE;
301 else
303 Req( "Illegal tool type value: %s\n", (ULONG) *tool_types );
304 return FALSE;
307 else if( Strnicmp( *tool_types, "LEGACY_DEVICE=", 14 ) == 0 )
309 UBYTE* str;
310 int conv;
311 LONG manufacturer;
312 WORD product;
313 BYTE revision;
314 UWORD dev_num = 0;
316 str = *tool_types + 14;
317 conv = ParseID( str, &manufacturer, &product, &revision, NULL, NULL );
319 str += conv;
321 if( conv != 0 )
323 struct ISAPNP_Device* dev;
324 struct ISAPNP_Identifier* id;
326 dev = ISAPNP_AllocDevice( res );
328 if( dev == NULL )
330 Req( "Out of memory!" );
331 return FALSE;
334 dev->isapnpd_Card = card;
336 id = AllocVec( sizeof( *id ), MEMF_PUBLIC | MEMF_CLEAR );
338 if( id == NULL )
340 Req( "Out of memory!" );
341 ISAPNP_FreeDevice( dev, res );
342 return FALSE;
345 id->isapnpid_Vendor[ 0 ] = ( manufacturer >> 24 ) & 0xff;
346 id->isapnpid_Vendor[ 1 ] = ( manufacturer >> 16 ) & 0xff;
347 id->isapnpid_Vendor[ 2 ] = ( manufacturer >> 8 ) & 0xff;
348 id->isapnpid_Vendor[ 3 ] = 0;
350 id->isapnpid_ProductID = product;
351 id->isapnpid_Revision = revision;
353 AddTail( (struct List*) &dev->isapnpd_IDs, (struct Node*) id );
355 if( card->isapnpc_Devices.lh_Head->ln_Succ != NULL )
357 dev_num = ( (struct ISAPNP_Device*)
358 card->isapnpc_Devices.lh_TailPred )->isapnpd_DeviceNumber;
359 ++dev_num;
362 dev->isapnpd_DeviceNumber = dev_num;
364 AddTail( &card->isapnpc_Devices, (struct Node*) dev );
366 while( *str != 0 )
368 if( *str != ' ' )
370 if( Strnicmp( str, "IRQ=", 4 ) == 0 )
372 int irq;
374 irq = strtol( str + 4, (char**) &str, 0 );
376 if( irq <= 0 || irq >= 16 )
378 Req( "Invalid IRQ value '%ld' in tooltype line\n"
379 "'%s'",
380 irq,
381 (ULONG) *tool_types );
382 return FALSE;
384 else
386 struct ISAPNP_IRQResource* r;
388 r = (struct ISAPNP_IRQResource*)
389 ISAPNP_AllocResource( ISAPNP_NT_IRQ_RESOURCE, res );
391 if( r == NULL )
393 Req( "Out of memory!" );
394 return FALSE;
397 r->isapnpirqr_IRQMask = 1 << irq;
398 r->isapnpirqr_IRQType = ISAPNP_IRQRESOURCE_ITF_HIGH_EDGE;
400 AddTail( (struct List*) &dev->isapnpd_Options->isapnprg_Resources,
401 (struct Node*) r );
404 else if( Strnicmp( str, "DMA=", 4 ) == 0 )
406 int dma;
408 dma = strtol( str + 4, (char**) &str, 0 );
410 if( dma <= 0 || dma >= 8 )
412 Req( "Invalid DMA value '%ld' in tooltype line\n"
413 "'%s'",
414 dma,
415 (ULONG) *tool_types );
416 return FALSE;
418 else
420 struct ISAPNP_DMAResource* r;
422 r = (struct ISAPNP_DMAResource*)
423 ISAPNP_AllocResource( ISAPNP_NT_DMA_RESOURCE, res );
425 if( r == NULL )
427 Req( "Out of memory!" );
428 return FALSE;
431 r->isapnpdmar_ChannelMask = 1 << dma;
432 r->isapnpdmar_Flags = 0;
434 AddTail( (struct List*) &dev->isapnpd_Options->isapnprg_Resources,
435 (struct Node*) r );
438 else if( Strnicmp( str, "IO=", 3 ) == 0 )
440 int base;
441 int length;
443 struct ISAPNP_IOResource* r;
445 base = strtol( str + 3, (char**) &str, 0 );
447 if( *str != '/' )
449 Req( "Length missing from IO value in tooltype line\n"
450 "'%s'",
451 (ULONG) *tool_types );
452 return FALSE;
455 ++str;
457 length = strtol( str, (char**) &str, 0 );
459 if( base <= 0 || base >= 0xffff )
461 Req( "Invalid IO base value '%ld' in tooltype line\n"
462 "'%s'",
463 base,
464 (ULONG) *tool_types );
465 return FALSE;
468 if( length <= 0 || length >= 0xffff )
470 Req( "Invalid IO length value '%ld' in tooltype line\n"
471 "'%s'",
472 length,
473 (ULONG) *tool_types );
474 return FALSE;
477 r = (struct ISAPNP_IOResource*)
478 ISAPNP_AllocResource( ISAPNP_NT_IO_RESOURCE, res );
480 if( r == NULL )
482 Req( "Out of memory!" );
483 return FALSE;
486 r->isapnpior_MinBase = base;
487 r->isapnpior_MaxBase = base;
488 r->isapnpior_Length = length;
489 r->isapnpior_Alignment = 1;
491 AddTail( (struct List*) &dev->isapnpd_Options->isapnprg_Resources,
492 (struct Node*) r );
494 else
496 Req( "Parse error near '%s'\n"
497 "in tooltype line\n"
498 "'%s'",
499 (ULONG) str,
500 (ULONG) *tool_types );
501 return FALSE;
505 if( *str )
507 ++str;
511 else
513 Req( "Illegal tool type: '%s'\n", (ULONG) *tool_types );
514 return FALSE;
517 else
519 // Ignore unknown tool types
522 ++tool_types;
525 return TRUE;