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,
23 #include "CompilerSpecific.h"
25 #include <exec/memory.h>
27 #include <proto/exec.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
;
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
)
77 card
= (struct ISAPNP_Card
*) card
->isapnpc_Node
.ln_Succ
;
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
;
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
)
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
;
146 /******************************************************************************
147 ** Helper functions for the card/device locking functions *********************
148 ******************************************************************************/
151 ComparePtr( const void* a
,
154 struct ISAPNP_Card
* p1
= *( (struct ISAPNP_Card
**) a
);
155 struct ISAPNP_Card
* p2
= *( (struct ISAPNP_Card
**) b
);
162 MakeSortedArray( void** ptrs
)
168 // Find number of pointers to sort
173 while( *ptrs_ptr
!= NULL
)
179 result
= AllocVec( sizeof( *ptrs_ptr
) * size
+ 1, MEMF_PUBLIC
);
185 while( *ptrs
!= NULL
)
192 qsort( result
, size
, sizeof( *result
), ComparePtr
);
194 result
[ size
] = NULL
;
201 /******************************************************************************
202 ** Lock one or more PNP ISA cards ********************************************
203 ******************************************************************************/
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
);
217 for( cards_ptr
= result
;
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
;
235 ReleaseSemaphore( &(*cards_ptr
)->isapnpc_Lock
);
245 ObtainSemaphore( &(*cards_ptr
)->isapnpc_Lock
);
250 return (APTR
) result
;
254 /******************************************************************************
255 ** Unlock one or more PNP ISA cards ******************************************
256 ******************************************************************************/
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
)
269 for( cards_ptr
= (struct ISAPNP_Card
**) card_lock_handle
;
273 ReleaseSemaphore( &(*cards_ptr
)->isapnpc_Lock
);
276 FreeVec( card_lock_handle
);
280 /******************************************************************************
281 ** Lock one or more PNP ISA devices *******************************************
282 ******************************************************************************/
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
);
296 for( devices_ptr
= result
;
297 *devices_ptr
!= NULL
;
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
;
314 ReleaseSemaphore( &(*devices_ptr
)->isapnpd_Lock
);
324 ObtainSemaphore( &(*devices_ptr
)->isapnpd_Lock
);
329 return (APTR
) result
;
333 /******************************************************************************
334 ** Unlock one or more PNP ISA devices ****************************************
335 ******************************************************************************/
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
)
348 for( devices_ptr
= (struct ISAPNP_Device
**) device_lock_handle
;
349 *devices_ptr
!= NULL
;
352 ReleaseSemaphore( &(*devices_ptr
)->isapnpd_Lock
);
355 FreeVec( device_lock_handle
);