sfdc: experimental extension which creates
[AROS.git] / rom / isapnp / devices.c
blob820493c469ce89c9e22e0979ef315ac424a9b893
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 #include "CompilerSpecific.h"
26 #include <exec/memory.h>
28 #include <proto/exec.h>
30 #include <stdlib.h>
32 #include <resources/isapnp.h>
33 #include "isapnp_private.h"
36 /******************************************************************************
37 ** Find a PNP ISA card *******************************************************
38 ******************************************************************************/
40 AROS_LH5(struct ISAPNP_Card *, ISAPNP_FindCard,
41 AROS_LHA(struct ISAPNP_Card *, last_card, A0),
42 AROS_LHA(LONG, manufacturer, D0),
43 AROS_LHA(WORD, product, D1),
44 AROS_LHA(BYTE, revision, D2),
45 AROS_LHA(LONG, serial, D3),
46 struct ISAPNPBase *, res, 28, ISAPNP)
48 AROS_LIBFUNC_INIT
50 struct ISAPNP_Card* card;
52 if( last_card == NULL )
54 card = (struct ISAPNP_Card*) res->m_Cards.lh_Head;
56 else
58 card = (struct ISAPNP_Card*) last_card->isapnpc_Node.ln_Succ;
61 while( card->isapnpc_Node.ln_Succ != NULL )
63 if( manufacturer == -1 ||
64 ISAPNP_MAKE_ID( card->isapnpc_ID.isapnpid_Vendor[ 0 ],
65 card->isapnpc_ID.isapnpid_Vendor[ 1 ],
66 card->isapnpc_ID.isapnpid_Vendor[ 2 ] ) == manufacturer )
68 if( product == -1 || card->isapnpc_ID.isapnpid_ProductID == product )
70 if( revision == -1 || card->isapnpc_ID.isapnpid_Revision == revision )
72 if( serial == -1 || (LONG) card->isapnpc_SerialNumber == serial )
74 return card;
80 card = (struct ISAPNP_Card*) card->isapnpc_Node.ln_Succ;
83 return NULL;
85 AROS_LIBFUNC_EXIT
89 /******************************************************************************
90 ** Find a PNP ISA device *****************************************************
91 ******************************************************************************/
93 AROS_LH4(struct ISAPNP_Device *, ISAPNP_FindDevice,
94 AROS_LHA(struct ISAPNP_Device *, last_device, A0),
95 AROS_LHA(LONG, manufacturer, D0),
96 AROS_LHA(WORD, product, D1),
97 AROS_LHA(BYTE, revision, D2),
98 struct ISAPNPBase *, res, 29, ISAPNP)
100 AROS_LIBFUNC_INIT
102 struct ISAPNP_Card* card;
103 struct ISAPNP_Device* dev;
105 if( last_device == NULL )
107 card = (struct ISAPNP_Card*) res->m_Cards.lh_Head;
108 dev = (struct ISAPNP_Device*) card->isapnpc_Devices.lh_Head;
110 else
112 card = (struct ISAPNP_Card*) last_device->isapnpd_Card;
113 dev = (struct ISAPNP_Device*) last_device->isapnpd_Node.ln_Succ;
116 while( card->isapnpc_Node.ln_Succ != NULL )
118 while( dev->isapnpd_Node.ln_Succ != NULL )
120 struct ISAPNP_Identifier* id;
122 for( id = (struct ISAPNP_Identifier*) dev->isapnpd_IDs.mlh_Head;
123 id->isapnpid_MinNode.mln_Succ != NULL;
124 id = (struct ISAPNP_Identifier*) id->isapnpid_MinNode.mln_Succ )
126 if( manufacturer == -1 ||
127 ISAPNP_MAKE_ID( id->isapnpid_Vendor[ 0 ],
128 id->isapnpid_Vendor[ 1 ],
129 id->isapnpid_Vendor[ 2 ] ) == manufacturer )
131 if( product == -1 || id->isapnpid_ProductID == product )
133 if( revision == -1 || id->isapnpid_Revision == revision )
135 return dev;
141 dev = (struct ISAPNP_Device*) dev->isapnpd_Node.ln_Succ;
144 card = (struct ISAPNP_Card*) card->isapnpc_Node.ln_Succ;
145 dev = (struct ISAPNP_Device*) card->isapnpc_Devices.lh_Head;
148 return NULL;
150 AROS_LIBFUNC_EXIT
155 /******************************************************************************
156 ** Helper functions for the card/device locking functions *********************
157 ******************************************************************************/
159 static int
160 ComparePtr( const void* a,
161 const void* b )
163 struct ISAPNP_Card* p1 = *( (struct ISAPNP_Card**) a );
164 struct ISAPNP_Card* p2 = *( (struct ISAPNP_Card**) b );
166 return p1 - p2;
170 static void**
171 MakeSortedArray( void** ptrs, struct ISAPNPBase *res)
173 int size;
174 void** ptrs_ptr;
175 void** result;
177 // Find number of pointers to sort
179 size = 0;
180 ptrs_ptr = ptrs;
182 while( *ptrs_ptr != NULL )
184 ++size;
185 ++ptrs_ptr;
188 result = AllocVec( sizeof( *ptrs_ptr ) * size + 1, MEMF_PUBLIC );
190 if( result != NULL )
192 ptrs_ptr = result;
194 while( *ptrs != NULL )
196 *ptrs_ptr = *ptrs;
197 ++ptrs;
198 ++ptrs_ptr;
201 qsort( result, size, sizeof( *result ), ComparePtr );
203 result[ size ] = NULL;
206 return result;
210 /******************************************************************************
211 ** Lock one or more PNP ISA cards ********************************************
212 ******************************************************************************/
214 AROS_LH2(APTR, ISAPNP_LockCardsA,
215 AROS_LHA(ULONG, flags, D0),
216 AROS_LHA(struct ISAPNP_Card **, cards, A0),
217 struct ISAPNPBase *, res, 30, ISAPNP)
219 AROS_LIBFUNC_INIT
221 struct ISAPNP_Card** cards_ptr;
222 struct ISAPNP_Card** result;
224 result = (struct ISAPNP_Card**) MakeSortedArray( (void**) cards, res );
226 if( result != NULL )
228 for( cards_ptr = result;
229 *cards_ptr != NULL;
230 ++cards_ptr )
232 if( flags & ISAPNP_LOCKF_NONBLOCKING )
234 if( ! AttemptSemaphore( &(*cards_ptr)->isapnpc_Lock ) )
236 struct ISAPNP_Card** cards_end;
238 // Oops! Failed to lock one of the cards!
240 cards_end = cards_ptr;
242 for( cards_ptr = result;
243 cards_ptr != cards_end;
244 ++cards_ptr );
246 ReleaseSemaphore( &(*cards_ptr)->isapnpc_Lock );
249 FreeVec( result );
250 result = NULL;
251 break;
254 else
256 ObtainSemaphore( &(*cards_ptr)->isapnpc_Lock );
261 return (APTR) result;
263 AROS_LIBFUNC_EXIT
267 /******************************************************************************
268 ** Unlock one or more PNP ISA cards ******************************************
269 ******************************************************************************/
271 AROS_LH1(void, ISAPNP_UnlockCards,
272 AROS_LHA(APTR, card_lock_handle, A0),
273 struct ISAPNPBase *, res, 31, ISAPNP)
275 AROS_LIBFUNC_INIT
277 struct ISAPNP_Card** cards_ptr;
279 if( card_lock_handle == NULL )
281 return;
284 for( cards_ptr = (struct ISAPNP_Card**) card_lock_handle;
285 *cards_ptr != NULL;
286 ++cards_ptr )
288 ReleaseSemaphore( &(*cards_ptr)->isapnpc_Lock );
291 FreeVec( card_lock_handle );
293 AROS_LIBFUNC_EXIT
297 /******************************************************************************
298 ** Lock one or more PNP ISA devices *******************************************
299 ******************************************************************************/
301 AROS_LH2(APTR, ISAPNP_LockDevicesA,
302 AROS_LHA(ULONG, flags, D0),
303 AROS_LHA(struct ISAPNP_Device **, devices, A0),
304 struct ISAPNPBase *, res, 32, ISAPNP)
306 AROS_LIBFUNC_INIT
308 struct ISAPNP_Device** devices_ptr;
309 struct ISAPNP_Device** result;
311 result = (struct ISAPNP_Device**) MakeSortedArray( (void**) devices, res );
313 if( result != NULL )
315 for( devices_ptr = result;
316 *devices_ptr != NULL;
317 ++devices_ptr )
319 if( flags & ISAPNP_LOCKF_NONBLOCKING )
321 if( ! AttemptSemaphore( &(*devices_ptr)->isapnpd_Lock ) )
323 struct ISAPNP_Device** devices_end;
325 // Oops! Failed to lock one of the devices!
327 devices_end = devices_ptr;
329 for( devices_ptr = result;
330 devices_ptr != devices_end;
331 ++devices_ptr );
333 ReleaseSemaphore( &(*devices_ptr)->isapnpd_Lock );
336 FreeVec( result );
337 result = NULL;
338 break;
341 else
343 ObtainSemaphore( &(*devices_ptr)->isapnpd_Lock );
348 return (APTR) result;
350 AROS_LIBFUNC_EXIT
354 /******************************************************************************
355 ** Unlock one or more PNP ISA devices ****************************************
356 ******************************************************************************/
358 AROS_LH1(void, ISAPNP_UnlockDevices,
359 AROS_LHA(APTR, device_lock_handle, A0),
360 struct ISAPNPBase *, res , 33, ISAPNP)
362 AROS_LIBFUNC_INIT
364 struct ISAPNP_Device** devices_ptr;
366 if( device_lock_handle == NULL )
368 return;
371 for( devices_ptr = (struct ISAPNP_Device**) device_lock_handle;
372 *devices_ptr != NULL;
373 ++devices_ptr )
375 ReleaseSemaphore( &(*devices_ptr)->isapnpd_Lock );
378 FreeVec( device_lock_handle );
380 AROS_LIBFUNC_EXIT