Call CloseDevice() before DeleteIORequest(), and don't call
[AROS.git] / rom / hidds / hidd / hiddclass.c
blobfa87ef387b4403b7f8d80026fca12a3b6e449207
1 /*
2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Main class for HIDD.
6 Lang: english
7 */
9 #include <exec/types.h>
10 #include <exec/libraries.h>
11 #include <exec/lists.h>
12 #include <exec/semaphores.h>
13 #include <exec/memory.h>
14 #include <exec/alerts.h>
16 #include <utility/tagitem.h>
17 #include <utility/hooks.h>
18 #include <oop/oop.h>
19 #include <hidd/hidd.h>
21 #include <proto/exec.h>
22 #include <proto/oop.h>
23 #include <proto/utility.h>
25 #include <aros/symbolsets.h>
27 #include <string.h>
29 #include "hiddclass_intern.h"
31 #include LC_LIBDEFS_FILE
33 #undef SDEBUG
34 #undef DEBUG
35 #define DEBUG 0
36 #include <aros/debug.h>
38 /*****************************************************************************************
40 NAME
41 --background--
43 LOCATION
44 hiddclass
46 NOTES
47 This class is a base class for all object-oriented hardware drivers in AROS. Its
48 main purpose is to provide some information about the driver itself.
50 At the moment this class is just a primary design. Many defined attributes and
51 methods are drafts and reserved. This documentation includes only already
52 estabilished definitions. Do not use any other methods and attributes, their
53 definitions may change at any moment.
55 *****************************************************************************************/
57 static const char unknown[] = "--unknown device--";
59 #define IS_HIDD_ATTR(attr, idx) ((idx = attr - HiddAttrBase) < num_Hidd_Attrs)
61 /*****************************************************************************************
63 NAME
64 aoHidd_Producer
66 SYNOPSIS
67 [I.G], ULONG
69 LOCATION
70 hiddclass
72 FUNCTION
73 Query hardware manufacturer's numeric ID. This ID may come for example from PCI
74 or Zorro bus configuration data.
76 NOTES
77 It is valid to return 0 if your hardware doesn't provide any ID number.
79 Initial value for this attribute is usually supplied by driver class in its
80 moRoot_New implementation.
82 EXAMPLE
84 BUGS
86 SEE ALSO
87 aoHidd_Product
89 INTERNALS
91 *****************************************************************************************/
93 /*****************************************************************************************
95 NAME
96 aoHidd_Name
98 SYNOPSIS
99 [I.G], STRPTR
101 LOCATION
102 hiddclass
104 FUNCTION
105 Name of the driver instance under which it is known to the OS. This name is
106 provided to OS components that use the driver. For example Intuition's MONITORCLASS
107 expects to find something like "ati_dvi1.monitor", "ati_vga1.monitor" or
108 "pcvga.monitor" here.
110 Note that is is instance name, not class name. Different instances of the driver may
111 need to provide different names for different objects (like in ATI example) in order
112 to let the OS to distinguish between them.
114 The supplied string is internally copied, you may destroy it after object creation.
116 NOTES
117 Initial value for this attribute is usually supplied by driver class in its
118 moRoot_New implementation.
120 EXAMPLE
122 BUGS
124 SEE ALSO
125 aoHidd_HardwareName
127 INTERNALS
129 *****************************************************************************************/
131 /*****************************************************************************************
133 NAME
134 aoHidd_HardwareName
136 SYNOPSIS
137 [I.G], STRPTR
139 LOCATION
140 hiddclass
142 FUNCTION
143 Query hardware name string.
145 NOTES
146 Initial value for this attribute is usually supplied by driver class in its
147 moRoot_New implementation.
149 The supplied string is not copied!
151 EXAMPLE
153 BUGS
155 SEE ALSO
156 aoHidd_Name
158 INTERNALS
160 *****************************************************************************************/
162 /*****************************************************************************************
164 NAME
165 aoHidd_Product
167 SYNOPSIS
168 [I.G], ULONG
170 LOCATION
171 hiddclass
173 FUNCTION
174 Query hardware's numeric produce ID. This ID may come for example from PCI
175 or Zorro bus configuration data.
177 NOTES
178 It is valid to return 0 if your hardware doesn't provide any ID number.
180 Initial value for this attribute is usually supplied by driver class in its
181 moRoot_New implementation.
183 EXAMPLE
185 BUGS
187 SEE ALSO
188 aoHidd_Producer
190 INTERNALS
192 *****************************************************************************************/
194 /*****************************************************************************************
196 NAME
197 aoHidd_ProducerName
199 SYNOPSIS
200 [I.G], STRPTR
202 LOCATION
203 hiddclass
205 FUNCTION
206 Query hardware manufacturer string. NULL is a valid value for this attribute
207 meaning that the information is not specified.
209 NOTES
210 Initial value for this attribute is usually supplied by driver class in its
211 moRoot_New implementation.
213 The supplied string is not copied!
215 EXAMPLE
217 BUGS
219 SEE ALSO
220 aoHidd_HardwareName
222 INTERNALS
224 *****************************************************************************************/
226 /* Implementation of root HIDD class methods. */
227 VOID HIDDCl__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg);
229 /*** HIDD::New() **************************************************************/
231 OOP_Object *HIDDCl__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
233 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
234 EnterFunc(bug("HIDD::New(cl=%s)\n", cl->ClassNode.ln_Name));
235 D(bug("DoSuperMethod:%p\n", cl->DoSuperMethod));
236 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
237 if(o)
239 struct HIDDData *hd;
240 struct TagItem *list = msg->attrList;
241 struct pRoot_Set set_msg;
242 STRPTR name, name2;
244 name = (STRPTR)GetTagData(aHidd_Name, 0, list);
245 if (name) {
246 ULONG l = strlen(name)+1;
248 name2 = AllocVec(l, MEMF_ANY);
249 if (!name2)
250 return NULL;
251 CopyMem(name, name2, l);
252 } else
253 name2 = (STRPTR)unknown;
255 hd = OOP_INST_DATA(cl, o);
257 /* Initialise the HIDD class. These fields are publicly described
258 as not being settable at Init time, however it is the only way to
259 get proper abstraction if you ask me. Plus it does reuse code
260 in a nice way.
262 To pass these into the init code I would recommend that your
263 pass in a TagList of your tags, which is linked to the user's
264 tags by a TAG_MORE. This way you will prevent them from setting
265 these values.
268 hd->hd_Type = GetTagData(aHidd_Type, 0, list);
269 hd->hd_SubType = GetTagData(aHidd_SubType, 0, list);
270 hd->hd_Producer = GetTagData(aHidd_Producer, 0, list);
272 hd->hd_Name = name2;
273 hd->hd_HWName = (STRPTR)GetTagData(aHidd_HardwareName,(IPTR)unknown, list);
274 hd->hd_ProducerName = (STRPTR)GetTagData(aHidd_ProducerName, 0, list);
276 hd->hd_Status = GetTagData(aHidd_Status, vHidd_StatusUnknown, list);
277 hd->hd_Locking = GetTagData(aHidd_Locking, vHidd_LockShared, list);
278 hd->hd_ErrorCode= GetTagData(aHidd_ErrorCode, 0, list);
280 hd->hd_Active = TRUE; /* Set default, GetTagData() comes later */
282 /* Use OM_SET to set the rest */
285 set_msg.attrList = msg->attrList;
286 HIDDCl__Root__Set(cl, o, &set_msg);
289 ReturnPtr("HIDD::New", OOP_Object *, o);
292 /*** HIDD::Dispose() **********************************************************/
293 VOID HIDDCl__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
295 struct HIDDData *hd = OOP_INST_DATA(cl, o);
297 if (hd->hd_Name != (STRPTR)unknown)
298 FreeVec(hd->hd_Name);
300 OOP_DoSuperMethod(cl, o, msg);
303 /*** HIDD::Set() **************************************************************/
305 VOID HIDDCl__Root__Set(OOP_Class *cl, OOP_Object *o, struct pRoot_Set *msg)
307 struct Library *UtilityBase = CSD(cl)->cs_UtilityBase;
308 struct TagItem *tstate = msg->attrList;
309 struct TagItem *tag;
310 struct HIDDData *hd = OOP_INST_DATA(cl, o);
312 EnterFunc(bug("HIDD::Set(cl=%s)\n", cl->ClassNode.ln_Name));
314 while((tag = NextTagItem(&tstate)))
316 ULONG idx;
318 if (IS_HIDD_ATTR(tag->ti_Tag, idx))
320 switch(idx)
322 case aoHidd_Active:
323 hd->hd_Active = tag->ti_Data;
324 break;
330 ReturnVoid("HIDD::Set");
334 /*** HIDD::Get() **************************************************************/
336 VOID HIDDCl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
338 struct HIDDData *hd = OOP_INST_DATA(cl, o);
339 ULONG idx;
341 EnterFunc(bug("HIDD::Get(cl=%s)\n", cl->ClassNode.ln_Name));
343 if (IS_HIDD_ATTR(msg->attrID, idx))
345 switch (idx)
347 case aoHidd_Type : *msg->storage = hd->hd_Type; break;
348 case aoHidd_SubType : *msg->storage = hd->hd_SubType; break;
349 case aoHidd_Producer : *msg->storage = hd->hd_Producer; break;
350 case aoHidd_Name : *msg->storage = (IPTR)hd->hd_Name; break;
351 case aoHidd_HardwareName: *msg->storage = (IPTR)hd->hd_HWName; break;
352 case aoHidd_Active : *msg->storage = hd->hd_Active; break;
353 case aoHidd_Status : *msg->storage = hd->hd_Status; break;
354 case aoHidd_ErrorCode : *msg->storage = hd->hd_ErrorCode; break;
355 case aoHidd_Locking : *msg->storage = hd->hd_Locking; break;
356 case aoHidd_Product:
357 *msg->storage = hd->hd_Product;
358 break;
359 case aoHidd_ProducerName:
360 *msg->storage = (IPTR)hd->hd_ProducerName;
361 break;
362 default : OOP_DoSuperMethod(cl, o, (OOP_Msg) msg); break;
364 } else {
365 OOP_DoSuperMethod(cl, o, (OOP_Msg) msg);
369 ReturnVoid("HIDD::Get");
373 #if 0
374 /***********************************
375 ** Unimplemented methods
381 /* switch(msg->MethodID)
383 case OM_NEW:
384 retval = OOP_DoSuperMethodA(cl, o, msg);
385 if(!retval)
386 break;
388 hd = OOP_INST_DATA(cl, retval);
390 if( hd != NULL)
392 struct TagItem *list = ((struct opSet *)msg)->ops_AttrList;
393 hd->hd_Type = GetTagData(aHidd_Type, 0, list);
394 hd->hd_SubType = GetTagData(aHidd_SubType, 0, list);
395 hd->hd_Producer = GetTagData(aHidd_Producer, 0, list);
396 hd->hd_Name = (STRPTR)GetTagData(aHidd_Name, (IPTR)unknown, list);
397 hd->hd_HWName = (STRPTR)GetTagData(aHidd_HardwareName, (IPTR)unknown, list);
398 hd->hd_Active = TRUE;
399 hd->hd_Status = GetTagData(aHidd_Status, HIDDV_StatusUnknown, list);
400 hd->hd_ErrorCode = GetTagData(aHidd_ErrorCode, 0, list);
401 hd->hd_Locking = GetTagData(aHidd_Locking, HIDDV_LockShared, list);
404 case OM_SET:
406 struct TagItem *tstate = ((struct opSet *)msg)->ops_AttrList;
407 struct TagItem *tag;
409 while((tag = NextTagItem(&tstate)))
411 switch(tag->ti_Tag)
413 case aHidd_Active:
414 hd->hd_Active = tag->ti_Data;
415 break;
418 break;
422 case OM_GET:
424 switch(((struct opGet *)msg)->opg_AttrID)
426 case aHidd_Type:
427 *((struct opGet *)msg)->opg_Storage = hd->hd_Type;
428 break;
430 case aHidd_SubType:
431 *((struct opGet *)msg)->opg_Storage = hd->hd_SubType;
432 break;
434 case aHidd_Producer:
435 *((struct opGet *)msg)->opg_Storage = hd->hd_Producer;
436 break;
438 case aHidd_Name:
439 *((struct opGet *)msg)->opg_Storage = (IPTR)hd->hd_Name;
440 break;
442 case aHidd_HardwareName:
443 *((struct opGet *)msg)->opg_Storage = (IPTR)hd->hd_HWName;
444 break;
446 case aHidd_Active:
447 *((struct opGet *)msg)->opg_Storage = hd->hd_Active;
448 break;
450 case aHidd_Status:
451 *((struct opGet *)msg)->opg_Storage = hd->hd_Status;
452 break;
454 case aHidd_ErrorCode:
455 *((struct opGet *)msg)->opg_Storage = hd->hd_ErrorCode;
456 break;
458 case aHidd_Locking:
459 *((struct opGet *)msg)->opg_Storage = hd->hd_Locking;
460 break;
467 /* These are the "hiddclass" methods. */
469 /* These two are invalid, since we don't have anything to get
470 from a class, so the superclass should handle these.
472 This is especially the case since the only place that we can
473 get the information for these methods is from an object, but
474 we don't have any objects if this method is called.
476 /* case HIDDM_Meta_Get:
477 case HIDDM_Meta_MGet:
478 retval = 0;
479 break;
481 /* Yet to determine the semantics of these so we just let
482 them return 0 for now.
484 /* case HIDDM_BeginIO:
485 case HIDDM_AbortIO:
486 retval = 0;
487 break;
489 case HIDDM_LoadConfigPlugin:
490 case HIDDM_Lock:
491 case HIDDM_Unlock:
492 retval = NULL;
493 break;
495 case HIDDM_AddHIDD:
498 Class *hc = ((hmAdd *)msg)->hma_Class;
500 if( (hc->cl_Flags & CLF_INLIST) == 0 )
503 ObtainSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
504 AddTail(
505 (struct List *)&((struct HCD *)cl->cl_UserData)->hiddList,
506 (struct Node *)hc
508 ReleaseSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
510 hc->cl_Flags |= CLF_INLIST;
511 retval = TRUE;
513 break;
516 case HIDDM_RemoveHIDD:
518 struct IClass *hc = ((hmAdd *)msg)->hma_Class;
520 if( hc->cl_Flags & CLF_INLIST )
522 ObtainSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
523 Remove((struct Node *)hc);
524 ReleaseSemaphore(&((struct HCD *)cl->cl_UserData)->listLock);
525 hc->cl_Flags &= ~CLF_INLIST;
529 case OM_DISPOSE:
531 default:
532 retval = OOP_DoSuperMethod(cl, o, msg);
535 return retval;
538 #endif
541 /*************************** Classes *****************************/
543 #undef csd
545 static int init_hiddclass(LIBBASETYPEPTR lh)
547 struct Library *OOPBase = GM_OOPBASE_FIELD(lh);
548 struct class_static_data *csd;
549 ULONG ok = 0;
551 EnterFunc(bug("HIDD::Init()\n"));
553 /* If you are not running from ROM, don't use Alert() */
555 csd = &lh->hd_csd;
556 csd->cs_UtilityBase = OpenLibrary("utility.library", 36);
557 if (!csd->cs_UtilityBase)
558 return FALSE;
560 NEWLIST(&csd->hiddList);
561 InitSemaphore(&csd->listLock);
563 HiddAttrBase = OOP_ObtainAttrBase(IID_Hidd);
564 if(HiddAttrBase)
566 D(bug("Got HiddAttrBase\n"));
567 ok = 1;
568 } /* if(HiddAttrBase) */
569 else
571 /* If you are not running from ROM, don't use Alert() */
573 Alert(AT_DeadEnd | AN_Unknown | AO_Unknown);
576 ReturnInt("HIDD::Init", ULONG, ok);
580 static int free_hiddclass(LIBBASETYPEPTR lh)
582 struct Library *OOPBase = GM_OOPBASE_FIELD(lh);
583 struct class_static_data *csd = &lh->hd_csd;
585 EnterFunc(bug("HIDD::Free()\n"));
587 if(csd->hiddAttrBase)
589 OOP_ReleaseAttrBase(IID_Hidd);
590 csd->hiddAttrBase = 0;
593 CloseLibrary(csd->cs_UtilityBase);
595 ReturnInt("HIDD::Free", ULONG, TRUE);
598 ADD2INITLIB(init_hiddclass, 0)
599 ADD2EXPUNGELIB(free_hiddclass, 0)