test/library/usereltest.c: Refined test to show that problem is not solved.
[AROS.git] / rom / isapnp / devices.c
blobb06128c4fb0010e343c24ea2873a71a1570ad4a8
1 /* $Id$ */
3 /*
4 ISA-PnP -- A Plug And Play ISA software layer for AmigaOS.
5 Copyright (C) 2001 Martin Blom <martin@blom.org>
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with this library; if not, write to the
19 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Cambridge,
20 MA 02139, USA.
23 #include "CompilerSpecific.h"
25 #include <exec/memory.h>
27 #include <proto/exec.h>
29 #include <stdlib.h>
31 #include <resources/isapnp.h>
32 #include "isapnp_private.h"
35 /******************************************************************************
36 ** Find a PNP ISA card *******************************************************
37 ******************************************************************************/
39 struct ISAPNP_Card* ASMCALL
40 ISAPNP_FindCard( REG( a0, struct ISAPNP_Card* last_card ),
41 REG( d0, LONG manufacturer ),
42 REG( d1, WORD product ),
43 REG( d2, BYTE revision ),
44 REG( d3, LONG serial ),
45 REG( a6, struct ISAPNPBase* res ) )
47 struct ISAPNP_Card* card;
49 if( last_card == NULL )
51 card = (struct ISAPNP_Card*) res->m_Cards.lh_Head;
53 else
55 card = (struct ISAPNP_Card*) last_card->isapnpc_Node.ln_Succ;
58 while( card->isapnpc_Node.ln_Succ != NULL )
60 if( manufacturer == -1 ||
61 ISAPNP_MAKE_ID( card->isapnpc_ID.isapnpid_Vendor[ 0 ],
62 card->isapnpc_ID.isapnpid_Vendor[ 1 ],
63 card->isapnpc_ID.isapnpid_Vendor[ 2 ] ) == manufacturer )
65 if( product == -1 || card->isapnpc_ID.isapnpid_ProductID == product )
67 if( revision == -1 || card->isapnpc_ID.isapnpid_Revision == revision )
69 if( serial == -1 || (LONG) card->isapnpc_SerialNumber == serial )
71 return card;
77 card = (struct ISAPNP_Card*) card->isapnpc_Node.ln_Succ;
80 return NULL;
84 /******************************************************************************
85 ** Find a PNP ISA device *****************************************************
86 ******************************************************************************/
88 struct ISAPNP_Device* ASMCALL
89 ISAPNP_FindDevice( REG( a0, struct ISAPNP_Device* last_device ),
90 REG( d0, LONG manufacturer ),
91 REG( d1, WORD product ),
92 REG( d2, BYTE revision ),
93 REG( a6, struct ISAPNPBase* res ) )
95 struct ISAPNP_Card* card;
96 struct ISAPNP_Device* dev;
98 if( last_device == NULL )
100 card = (struct ISAPNP_Card*) res->m_Cards.lh_Head;
101 dev = (struct ISAPNP_Device*) card->isapnpc_Devices.lh_Head;
103 else
105 card = (struct ISAPNP_Card*) last_device->isapnpd_Card;
106 dev = (struct ISAPNP_Device*) last_device->isapnpd_Node.ln_Succ;
109 while( card->isapnpc_Node.ln_Succ != NULL )
111 while( dev->isapnpd_Node.ln_Succ != NULL )
113 struct ISAPNP_Identifier* id;
115 for( id = (struct ISAPNP_Identifier*) dev->isapnpd_IDs.mlh_Head;
116 id->isapnpid_MinNode.mln_Succ != NULL;
117 id = (struct ISAPNP_Identifier*) id->isapnpid_MinNode.mln_Succ )
119 if( manufacturer == -1 ||
120 ISAPNP_MAKE_ID( id->isapnpid_Vendor[ 0 ],
121 id->isapnpid_Vendor[ 1 ],
122 id->isapnpid_Vendor[ 2 ] ) == manufacturer )
124 if( product == -1 || id->isapnpid_ProductID == product )
126 if( revision == -1 || id->isapnpid_Revision == revision )
128 return dev;
134 dev = (struct ISAPNP_Device*) dev->isapnpd_Node.ln_Succ;
137 card = (struct ISAPNP_Card*) card->isapnpc_Node.ln_Succ;
138 dev = (struct ISAPNP_Device*) card->isapnpc_Devices.lh_Head;
141 return NULL;
146 /******************************************************************************
147 ** Helper functions for the card/device locking functions *********************
148 ******************************************************************************/
150 static int
151 ComparePtr( const void* a,
152 const void* b )
154 struct ISAPNP_Card* p1 = *( (struct ISAPNP_Card**) a );
155 struct ISAPNP_Card* p2 = *( (struct ISAPNP_Card**) b );
157 return p1 - p2;
161 static void**
162 MakeSortedArray( void** ptrs )
164 int size;
165 void** ptrs_ptr;
166 void** result;
168 // Find number of pointers to sort
170 size = 0;
171 ptrs_ptr = ptrs;
173 while( *ptrs_ptr != NULL )
175 ++size;
176 ++ptrs_ptr;
179 result = AllocVec( sizeof( *ptrs_ptr ) * size + 1, MEMF_PUBLIC );
181 if( result != NULL )
183 ptrs_ptr = result;
185 while( *ptrs != NULL )
187 *ptrs_ptr = *ptrs;
188 ++ptrs;
189 ++ptrs_ptr;
192 qsort( result, size, sizeof( *result ), ComparePtr );
194 result[ size ] = NULL;
197 return result;
201 /******************************************************************************
202 ** Lock one or more PNP ISA cards ********************************************
203 ******************************************************************************/
205 APTR ASMCALL
206 ISAPNP_LockCardsA( REG( d0, ULONG flags ),
207 REG( a0, struct ISAPNP_Card** cards ),
208 REG( a6, struct ISAPNPBase* res ) )
210 struct ISAPNP_Card** cards_ptr;
211 struct ISAPNP_Card** result;
213 result = (struct ISAPNP_Card**) MakeSortedArray( (void**) cards );
215 if( result != NULL )
217 for( cards_ptr = result;
218 *cards_ptr != NULL;
219 ++cards_ptr )
221 if( flags & ISAPNP_LOCKF_NONBLOCKING )
223 if( ! AttemptSemaphore( &(*cards_ptr)->isapnpc_Lock ) )
225 struct ISAPNP_Card** cards_end;
227 // Oops! Failed to lock one of the cards!
229 cards_end = cards_ptr;
231 for( cards_ptr = result;
232 cards_ptr != cards_end;
233 ++cards_ptr );
235 ReleaseSemaphore( &(*cards_ptr)->isapnpc_Lock );
238 FreeVec( result );
239 result = NULL;
240 break;
243 else
245 ObtainSemaphore( &(*cards_ptr)->isapnpc_Lock );
250 return (APTR) result;
254 /******************************************************************************
255 ** Unlock one or more PNP ISA cards ******************************************
256 ******************************************************************************/
258 void ASMCALL
259 ISAPNP_UnlockCards( REG( a0, APTR card_lock_handle ),
260 REG( a6, struct ISAPNPBase* res ) )
262 struct ISAPNP_Card** cards_ptr;
264 if( card_lock_handle == NULL )
266 return;
269 for( cards_ptr = (struct ISAPNP_Card**) card_lock_handle;
270 *cards_ptr != NULL;
271 ++cards_ptr )
273 ReleaseSemaphore( &(*cards_ptr)->isapnpc_Lock );
276 FreeVec( card_lock_handle );
280 /******************************************************************************
281 ** Lock one or more PNP ISA devices *******************************************
282 ******************************************************************************/
284 APTR ASMCALL
285 ISAPNP_LockDevicesA( REG( d0, ULONG flags ),
286 REG( a0, struct ISAPNP_Device** devices ),
287 REG( a6, struct ISAPNPBase* res ) )
289 struct ISAPNP_Device** devices_ptr;
290 struct ISAPNP_Device** result;
292 result = (struct ISAPNP_Device**) MakeSortedArray( (void**) devices );
294 if( result != NULL )
296 for( devices_ptr = result;
297 *devices_ptr != NULL;
298 ++devices_ptr )
300 if( flags & ISAPNP_LOCKF_NONBLOCKING )
302 if( ! AttemptSemaphore( &(*devices_ptr)->isapnpd_Lock ) )
304 struct ISAPNP_Device** devices_end;
306 // Oops! Failed to lock one of the devices!
308 devices_end = devices_ptr;
310 for( devices_ptr = result;
311 devices_ptr != devices_end;
312 ++devices_ptr );
314 ReleaseSemaphore( &(*devices_ptr)->isapnpd_Lock );
317 FreeVec( result );
318 result = NULL;
319 break;
322 else
324 ObtainSemaphore( &(*devices_ptr)->isapnpd_Lock );
329 return (APTR) result;
333 /******************************************************************************
334 ** Unlock one or more PNP ISA devices ****************************************
335 ******************************************************************************/
337 void ASMCALL
338 ISAPNP_UnlockDevices( REG( a0, APTR device_lock_handle ),
339 REG( a6, struct ISAPNPBase* res ) )
341 struct ISAPNP_Device** devices_ptr;
343 if( device_lock_handle == NULL )
345 return;
348 for( devices_ptr = (struct ISAPNP_Device**) device_lock_handle;
349 *devices_ptr != NULL;
350 ++devices_ptr )
352 ReleaseSemaphore( &(*devices_ptr)->isapnpd_Lock );
355 FreeVec( device_lock_handle );