2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
5 Desc: Parallel Unit hidd class implementation.
10 * This is the SerialUnitClass as used for Linux. You will have to
11 * modify this code here and make it work with the hardware that
12 * you want to write the hidd for.
13 * I hope the Linux code inside the methods helps a little bit
14 * in explaining what needs to be done inside each method.
19 /* Some POSIX includes */
20 #include <sys/types.h>
29 /* the rest are Amiga includes */
30 #include <proto/exec.h>
31 #include <proto/utility.h>
32 #include <proto/oop.h>
33 #include <proto/alib.h>
34 #include <exec/libraries.h>
35 #include <exec/ports.h>
36 #include <exec/memory.h>
37 #include <exec/interrupts.h>
38 #include <exec/lists.h>
40 #include <utility/tagitem.h>
41 #include <hidd/parallel.h>
42 #include <hidd/unixio.h>
44 #include "parallel_intern.h"
50 #include <aros/debug.h>
52 void parallelunit_receive_data();
53 void parallelunit_write_more_data();
62 /*************************** Classes *****************************/
64 static OOP_AttrBase HiddParallelUnitAB
;
66 static struct OOP_ABDescr attrbases
[] =
68 { IID_Hidd_ParallelUnit
, &HiddParallelUnitAB
},
72 /******* ParallelUnit::New() ***********************************/
73 static OOP_Object
*parallelunit_new(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
75 struct HIDDParallelUnitData
* data
;
76 static const struct TagItem tags
[] = {{ TAG_END
, 0}};
77 struct TagItem
*tag
, *tstate
;
80 EnterFunc(bug("ParallelUnit::New()\n"));
82 tstate
= msg
->attrList
;
83 while ((tag
= NextTagItem((const struct TagItem
**)&tstate
)))
87 if (IS_HIDDPARALLELUNIT_ATTR(tag
->ti_Tag
, idx
))
91 case aoHidd_ParallelUnit_Unit
:
92 unitnum
= (ULONG
)tag
->ti_Data
;
97 } /* while (tags to process) */
99 D(bug("!!!!Request for unit number %d\n",unitnum
));
101 obj
= (OOP_Object
*)OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
)msg
);
105 data
= OOP_INST_DATA(cl
, obj
);
107 data
->unitnum
= unitnum
;
109 D(bug("Opening %s.\n",unitname
[data
->unitnum
]));
111 data
->filedescriptor
= open(unitname
[data
->unitnum
], O_NONBLOCK
|O_RDWR
);
113 D(bug("Opened %s on handle %d\n",unitname
[data
->unitnum
], data
->filedescriptor
));
115 if (-1 != data
->filedescriptor
)
118 ** Configure the tty driver ??!?!?!
121 data
->replyport_read
= AllocMem(sizeof(struct MsgPort
), MEMF_PUBLIC
|MEMF_CLEAR
);
122 data
->replyport_write
= AllocMem(sizeof(struct MsgPort
), MEMF_PUBLIC
|MEMF_CLEAR
);
124 if (data
->replyport_read
&& data
->replyport_write
)
127 ** Init the msg ports. They don't need a signal to be allocated
129 NEWLIST(&data
->replyport_read
->mp_MsgList
);
130 data
->replyport_read
->mp_Node
.ln_Type
= NT_MSGPORT
;
132 NEWLIST(&data
->replyport_write
->mp_MsgList
);
133 data
->replyport_write
->mp_Node
.ln_Type
= NT_MSGPORT
;
135 data
->softint_read
= AllocMem(sizeof(struct Interrupt
), MEMF_CLEAR
);
136 data
->softint_write
= AllocMem(sizeof(struct Interrupt
), MEMF_CLEAR
);
138 if (data
->softint_read
&& data
->softint_write
)
140 data
->softint_read
->is_Data
= data
;
141 data
->softint_read
->is_Code
= parallelunit_receive_data
;
143 data
->softint_write
->is_Data
= data
;
144 data
->softint_write
->is_Code
= parallelunit_write_more_data
;
146 data
->replyport_read
->mp_Flags
= PA_SOFTINT
;
147 data
->replyport_read
->mp_SoftInt
= data
->softint_read
;
149 data
->replyport_write
->mp_Flags
= PA_SOFTINT
;
150 data
->replyport_write
->mp_SoftInt
= data
->softint_write
;
152 data
->unixio_read
= OOP_NewObject(NULL
, CLID_Hidd_UnixIO
, (struct TagItem
*)tags
);
153 data
->unixio_write
= OOP_NewObject(NULL
, CLID_Hidd_UnixIO
, (struct TagItem
*)tags
);
155 if (NULL
!= data
->unixio_read
&& NULL
!= data
->unixio_write
)
158 D(bug("Creating UnixIO AsyncIO command!\n"));
160 error
= Hidd_UnixIO_AsyncIO(data
->unixio_read
,
161 data
->filedescriptor
,
162 data
->replyport_read
,
168 if (NULL
!= data
->unixio_read
)
169 OOP_DisposeObject(data
->unixio_read
);
171 if (NULL
!= data
->unixio_write
)
172 OOP_DisposeObject(data
->unixio_write
);
175 if (data
->softint_read
)
176 FreeMem(data
->softint_read
, sizeof(struct Interrupt
));
177 if (data
->softint_write
)
178 FreeMem(data
->softint_write
, sizeof(struct Interrupt
));
181 if (data
->replyport_read
)
182 FreeMem(data
->replyport_read
, sizeof(struct MsgPort
));
183 if (data
->replyport_write
)
184 FreeMem(data
->replyport_write
, sizeof(struct MsgPort
));
188 close(data
->filedescriptor
);
191 OOP_DisposeObject(obj
);
195 D(bug("%s - an error occurred!\n",__FUNCTION__
));
198 ReturnPtr("ParallelUnit::New()", OOP_Object
*, obj
);
201 /******* ParallelUnit::Dispose() ***********************************/
202 static OOP_Object
*parallelunit_dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
204 struct HIDDParallelUnitData
* data
;
205 EnterFunc(bug("ParallelUnit::Dispose()\n"));
207 data
= OOP_INST_DATA(cl
, obj
);
208 D(bug("Freeing filedescriptor (%d)!\n",data
->filedescriptor
));
210 if (-1 != data
->filedescriptor
)
212 Hidd_UnixIO_AbortAsyncIO(data
->unixio_read
,
213 data
->filedescriptor
);
214 // Hidd_UnixIO_AbortAsyncIONotification(data->unixio_write,
215 // data->filedescriptor);
217 close(data
->filedescriptor
);
219 FreeMem(data
->replyport_read
, sizeof(struct MsgPort
));
220 FreeMem(data
->replyport_write
, sizeof(struct MsgPort
));
222 FreeMem(data
->softint_read
, sizeof(struct Interrupt
));
223 FreeMem(data
->softint_write
, sizeof(struct Interrupt
));
225 OOP_DisposeObject(data
->unixio_read
);
226 OOP_DisposeObject(data
->unixio_write
);
228 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
)msg
);
229 ReturnPtr("ParallelUnit::Dispose()", OOP_Object
*, obj
);
234 /******* ParallelUnit::Init() **********************************/
235 BOOL
parallelunit_init(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Init
*msg
)
237 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
239 EnterFunc(bug("ParallelUnit::Init()\n"));
240 data
->DataReceivedCallBack
= msg
->DataReceived
;
241 data
->DataReceivedUserData
= msg
->DataReceivedUserData
;
242 data
->DataWriteCallBack
= msg
->WriteData
;
243 data
->DataWriteUserData
= msg
->WriteDataUserData
;
245 ReturnBool("ParallelUnit::Init()", TRUE
);
248 /******* ParallelUnit::Write() **********************************/
249 ULONG
parallelunit_write(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Write
*msg
)
251 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
255 EnterFunc(bug("ParallelUnit::Write()\n"));
257 D(bug("Writing %d bytes to fd %d (stream: %s)\n",
259 data
->filedescriptor
,
262 len
= write(data
->filedescriptor
,
266 if (len
< msg
->Length
)
269 // !!!!!! FROM WHAT I CAN TELL THE FOLLOWING LINE
270 // CAUSES PROBLEMS. IT IS NECESSARY TO HAVE IT, THOUGH.
271 error
= Hidd_UnixIO_AsyncIO(data
->unixio_write
,
272 data
->filedescriptor
,
273 data
->replyport_write
,
278 ReturnInt("ParallelUnit::Write()",ULONG
, len
);
281 /************* The software interrupt handler that gets data from PORT *****/
288 #define READBUFFER_SIZE 513
290 AROS_UFH3(void, parallelunit_receive_data
,
291 AROS_UFHA(APTR
, iD
, A1
),
292 AROS_UFHA(APTR
, iC
, A5
),
293 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
296 struct HIDDParallelUnitData
* data
= iD
;
298 UBYTE buffer
[READBUFFER_SIZE
];
299 struct Message
* msg
;
302 ** Get the unixio message from my port and free it
304 msg
= GetMsg(data
->replyport_read
);
305 FreeMem(msg
, sizeof(struct uioMessage
));
308 ** Read the data from the port ...
310 len
= read(data
->filedescriptor
, buffer
, READBUFFER_SIZE
);
312 ** ... and deliver them to whoever is interested.
315 if (NULL
!= data
->DataReceivedCallBack
)
316 data
->DataReceivedCallBack(buffer
, len
, data
->unitnum
, data
->DataReceivedUserData
);
319 ** I want to be notified when the next data are coming in.
321 error
= Hidd_UnixIO_AsyncIO(data
->unixio_read
,
322 data
->filedescriptor
,
323 data
->replyport_read
,
328 AROS_UFH3(void, parallelunit_write_more_data
,
329 AROS_UFHA(APTR
, iD
, A1
),
330 AROS_UFHA(APTR
, iC
, A5
),
331 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
333 struct HIDDParallelUnitData
* data
= iD
;
334 struct Message
* msg
;
337 ** Get the unixio message from my port and free it
339 msg
= GetMsg(data
->replyport_read
);
340 FreeMem(msg
, sizeof(struct uioMessage
));
343 ** Ask for more data be written to the unit
345 D(bug("Asking for more data to be written to unit %d\n",data
->unitnum
));
347 if (NULL
!= data
->DataWriteCallBack
)
348 data
->DataWriteCallBack(data
->unitnum
, data
->DataWriteUserData
);
352 /******* init_parallelunitclass ********************************/
354 #define SysBase (csd->sysbase)
355 #define OOPBase (csd->oopbase)
356 #define UtilityBase (csd->utilitybase)
359 #define NUM_ROOT_METHODS 2
360 #define NUM_PARALLELUNIT_METHODS 2
362 OOP_Class
*init_parallelunitclass (struct class_static_data
*csd
)
364 OOP_Class
*cl
= NULL
;
366 struct OOP_MethodDescr parallelunithiddroot_descr
[NUM_ROOT_METHODS
+ 1] =
368 {(IPTR (*)())parallelunit_new
, moRoot_New
},
369 {(IPTR (*)())parallelunit_dispose
, moRoot_Dispose
},
371 {(IPTR (*)())parallelunit_set, moRoot_Set},
372 {(IPTR (*)())parallelunit_get, moRoot_Get},
377 struct OOP_MethodDescr parallelunithidd_descr
[NUM_PARALLELUNIT_METHODS
+ 1] =
379 {(IPTR (*)())parallelunit_init
, moHidd_ParallelUnit_Init
},
380 {(IPTR (*)())parallelunit_write
, moHidd_ParallelUnit_Write
},
384 struct OOP_InterfaceDescr ifdescr
[] =
386 {parallelunithiddroot_descr
, IID_Root
, NUM_ROOT_METHODS
},
387 {parallelunithidd_descr
, IID_Hidd_ParallelUnit
, NUM_PARALLELUNIT_METHODS
},
391 OOP_AttrBase MetaAttrBase
= OOP_GetAttrBase(IID_Meta
);
393 struct TagItem tags
[] =
395 { aMeta_SuperID
, (IPTR
)CLID_Root
},
396 { aMeta_InterfaceDescr
, (IPTR
)ifdescr
},
397 { aMeta_ID
, (IPTR
)CLID_Hidd_ParallelUnit
},
398 { aMeta_InstSize
, (IPTR
)sizeof (struct HIDDParallelUnitData
) },
403 EnterFunc(bug(" init_parallelunitclass(csd=%p)\n", csd
));
405 cl
= OOP_NewObject(NULL
, CLID_HiddMeta
, tags
);
406 D(bug("Class=%p\n", cl
));
409 if (OOP_ObtainAttrBases(attrbases
))
411 D(bug("ParallelUnit Class ok\n"));
412 cl
->UserData
= (APTR
)csd
;
416 free_parallelunitclass(csd
);
421 ReturnPtr("init_parallelunitclass", OOP_Class
*, cl
);
425 void free_parallelunitclass(struct class_static_data
*csd
)
427 EnterFunc(bug("free_parallelhiddclass(csd=%p)\n", csd
));
431 OOP_RemoveClass(csd
->parallelhiddclass
);
433 if(csd
->parallelhiddclass
) OOP_DisposeObject((OOP_Object
*) csd
->parallelhiddclass
);
434 csd
->parallelhiddclass
= NULL
;
437 ReturnVoid("free_parallelhiddclass");