2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
5 Desc: Parallel Unit hidd class implementation.
9 #define __OOP_NOATTRBASES__
11 /* Some POSIX includes */
16 #include "unix_funcs.h"
19 /* the rest are Amiga includes */
20 #define timeval aros_timeval
21 #include <proto/exec.h>
22 #include <proto/utility.h>
23 #include <proto/oop.h>
24 #include <proto/alib.h>
25 #include <exec/libraries.h>
26 #include <exec/ports.h>
27 #include <exec/memory.h>
28 #include <exec/interrupts.h>
29 #include <exec/lists.h>
31 #include <utility/tagitem.h>
32 #include <hidd/parallel.h>
33 #include <hidd/unixio.h>
35 #include <aros/symbolsets.h>
37 #include "parallel_intern.h"
40 #include LC_LIBDEFS_FILE
46 #include <aros/debug.h>
48 void parallelunit_receive_data();
49 void parallelunit_write_more_data();
51 static char * unitname
[] =
58 /*************************** Classes *****************************/
60 static OOP_AttrBase HiddParallelUnitAB
;
62 static struct OOP_ABDescr attrbases
[] =
64 { IID_Hidd_ParallelUnit
, &HiddParallelUnitAB
},
68 /******* ParallelUnit::New() ***********************************/
69 OOP_Object
*UXParUnit__Root__New(OOP_Class
*cl
, OOP_Object
*obj
, struct pRoot_New
*msg
)
71 struct HIDDParallelUnitData
* data
;
72 static const struct TagItem tags
[] = {{ TAG_END
, 0}};
73 struct TagItem
*tag
, *tstate
;
76 EnterFunc(bug("ParallelUnit::New()\n"));
78 tstate
= msg
->attrList
;
79 while ((tag
= NextTagItem((const struct TagItem
**)&tstate
))) {
82 if (IS_HIDDPARALLELUNIT_ATTR(tag
->ti_Tag
, idx
)) {
84 case aoHidd_ParallelUnit_Unit
:
85 unitnum
= (ULONG
)tag
->ti_Data
;
90 } /* while (tags to process) */
92 D(bug("!!!!Request for unit number %d\n",unitnum
));
94 obj
= (OOP_Object
*)OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
)msg
);
97 data
= OOP_INST_DATA(cl
, obj
);
99 data
->unitnum
= unitnum
;
101 D(bug("Opening %s.\n",unitname
[data
->unitnum
]));
103 data
->filedescriptor
= unix_open_nonblock(unitname
[data
->unitnum
]);
105 D(bug("Opened %s on handle %d\n",unitname
[data
->unitnum
], data
->filedescriptor
));
107 if (-1 != data
->filedescriptor
) {
109 ** Configure the tty driver ?!?!?!
112 data
->replyport_read
= AllocMem(sizeof(struct MsgPort
), MEMF_PUBLIC
|MEMF_CLEAR
);
113 data
->replyport_write
= AllocMem(sizeof(struct MsgPort
), MEMF_PUBLIC
|MEMF_CLEAR
);
115 if (data
->replyport_read
&& data
->replyport_write
) {
117 ** Init the msg ports. They don't need a signal to be allocated
119 NEWLIST(&data
->replyport_read
->mp_MsgList
);
120 data
->replyport_read
->mp_Node
.ln_Type
= NT_MSGPORT
;
122 NEWLIST(&data
->replyport_write
->mp_MsgList
);
123 data
->replyport_write
->mp_Node
.ln_Type
= NT_MSGPORT
;
125 data
->softint_read
= AllocMem(sizeof(struct Interrupt
), MEMF_CLEAR
);
126 data
->softint_write
= AllocMem(sizeof(struct Interrupt
), MEMF_CLEAR
);
128 if (data
->softint_read
&& data
->softint_write
) {
129 data
->softint_read
->is_Data
= data
;
130 data
->softint_read
->is_Code
= parallelunit_receive_data
;
132 data
->softint_write
->is_Data
= data
;
133 data
->softint_write
->is_Code
= parallelunit_write_more_data
;
135 data
->replyport_read
->mp_Flags
= PA_SOFTINT
;
136 data
->replyport_read
->mp_SoftInt
= data
->softint_read
;
138 data
->replyport_write
->mp_Flags
= PA_SOFTINT
;
139 data
->replyport_write
->mp_SoftInt
= data
->softint_write
;
141 data
->unixio_read
= OOP_NewObject(NULL
, CLID_Hidd_UnixIO
, (struct TagItem
*)tags
);
142 data
->unixio_write
= OOP_NewObject(NULL
, CLID_Hidd_UnixIO
, (struct TagItem
*)tags
);
144 if (NULL
!= data
->unixio_read
&& NULL
!= data
->unixio_write
) {
146 D(bug("Creating UnixIO AsyncIO command!\n"));
148 error
= Hidd_UnixIO_AsyncIO(data
->unixio_read
,
149 data
->filedescriptor
,
150 vHidd_UnixIO_Terminal
,
151 data
->replyport_read
,
152 vHidd_UnixIO_Read
| vHidd_UnixIO_Keep
,
155 error
= Hidd_UnixIO_AsyncIO(data
->unixio_write
,
156 data
->filedescriptor
,
157 vHidd_UnixIO_Terminal
,
158 data
->replyport_write
,
159 vHidd_UnixIO_Write
| vHidd_UnixIO_Keep
,
165 if (NULL
!= data
->unixio_read
)
166 OOP_DisposeObject(data
->unixio_read
);
168 if (NULL
!= data
->unixio_write
)
169 OOP_DisposeObject(data
->unixio_write
);
172 if (data
->softint_read
)
173 FreeMem(data
->softint_read
, sizeof(struct Interrupt
));
174 if (data
->softint_write
)
175 FreeMem(data
->softint_write
, sizeof(struct Interrupt
));
178 if (data
->replyport_read
)
179 FreeMem(data
->replyport_read
, sizeof(struct MsgPort
));
180 if (data
->replyport_write
)
181 FreeMem(data
->replyport_write
, sizeof(struct MsgPort
));
185 close(data
->filedescriptor
);
188 OOP_DisposeObject(obj
);
192 D(bug("%s - an error occurred!\n",__FUNCTION__
));
195 ReturnPtr("ParallelUnit::New()", OOP_Object
*, obj
);
198 /******* ParallelUnit::Dispose() ***********************************/
199 OOP_Object
*UXParUnit__Root__Dispose(OOP_Class
*cl
, OOP_Object
*obj
, OOP_Msg msg
)
201 struct HIDDParallelUnitData
* data
;
202 EnterFunc(bug("ParallelUnit::Dispose()\n"));
204 data
= OOP_INST_DATA(cl
, obj
);
205 D(bug("Freeing filedescriptor (%d)!\n",data
->filedescriptor
));
207 if (-1 != data
->filedescriptor
) {
208 Hidd_UnixIO_AbortAsyncIO(data
->unixio_read
,
209 data
->filedescriptor
,
212 close(data
->filedescriptor
);
214 FreeMem(data
->replyport_read
, sizeof(struct MsgPort
));
215 FreeMem(data
->replyport_write
, sizeof(struct MsgPort
));
217 FreeMem(data
->softint_read
, sizeof(struct Interrupt
));
218 FreeMem(data
->softint_write
, sizeof(struct Interrupt
));
220 OOP_DisposeObject(data
->unixio_read
);
221 OOP_DisposeObject(data
->unixio_write
);
223 OOP_DoSuperMethod(cl
, obj
, (OOP_Msg
)msg
);
224 ReturnPtr("ParallelUnit::Dispose()", OOP_Object
*, obj
);
229 /******* ParallelUnit::Init() **********************************/
230 BOOL
UXParUnit__Hidd_ParallelUnit__Init(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Init
*msg
)
232 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
234 EnterFunc(bug("ParallelUnit::Init()\n"));
235 data
->DataReceivedCallBack
= msg
->DataReceived
;
236 data
->DataReceivedUserData
= msg
->DataReceivedUserData
;
237 data
->DataWriteCallBack
= msg
->WriteData
;
238 data
->DataWriteUserData
= msg
->WriteDataUserData
;
240 ReturnBool("ParallelUnit::Init()", TRUE
);
243 /******* ParallelUnit::Write() **********************************/
244 ULONG
UXParUnit__Hidd_ParallelUnit__Write(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Write
*msg
)
246 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
249 EnterFunc(bug("ParallelUnit::Write()\n"));
251 if (TRUE
== data
->stopped
)
254 D(bug("Writing %d bytes to fd %d (stream: %s)\n",
256 data
->filedescriptor
,
259 len
= write(data
->filedescriptor
,
264 ReturnInt("ParallelUnit::Write()",ULONG
, len
);
267 /******* ParallelUnit::Start() **********************************/
268 VOID
UXParUnit__Hidd_ParallelUnit__Start(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Start
*msg
)
270 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
273 * Allow or start feeding the UART with data. Get the data
276 if (TRUE
== data
->stopped
) {
277 if (NULL
!= data
->DataWriteCallBack
)
278 data
->DataWriteCallBack(data
->unitnum
, data
->DataWriteUserData
);
280 * Also mark the stopped flag as FALSE.
282 data
->stopped
= FALSE
;
286 /******* ParallelUnit::Stop() **********************************/
287 VOID
UXParUnit__Hidd_ParallelUnit__Stop(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_Stop
*msg
)
289 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
292 * The next time the interrupt comes along and asks for
293 * more data we just don't do anything...
295 data
->stopped
= TRUE
;
298 /****** ParallelUnit::GetStatus ********************************/
299 UWORD
UXParUnit__Hidd_ParallelUnit__GetStatus(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_ParallelUnit_GetStatus
*msg
)
302 struct HIDDParallelUnitData
* data
= OOP_INST_DATA(cl
, o
);
309 /************* The software interrupt handler that gets data from PORT *****/
312 #define READBUFFER_SIZE 513
314 AROS_UFH3(void, parallelunit_receive_data
,
315 AROS_UFHA(APTR
, iD
, A1
),
316 AROS_UFHA(APTR
, iC
, A5
),
317 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
321 struct HIDDParallelUnitData
* data
= iD
;
323 UBYTE buffer
[READBUFFER_SIZE
];
326 ** Read the data from the port ...
328 len
= read(data
->filedescriptor
, buffer
, READBUFFER_SIZE
);
330 ** ... and deliver them to whoever is interested.
333 if (NULL
!= data
->DataReceivedCallBack
)
334 data
->DataReceivedCallBack(buffer
, len
, data
->unitnum
, data
->DataReceivedUserData
);
339 AROS_UFH3(void, parallelunit_write_more_data
,
340 AROS_UFHA(APTR
, iD
, A1
),
341 AROS_UFHA(APTR
, iC
, A5
),
342 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
346 struct HIDDParallelUnitData
* data
= iD
;
347 struct Message
* msg
;
350 ** Ask for more data be written to the unit
352 D(bug("Asking for more data to be written to unit %d\n",data
->unitnum
));
354 if (NULL
!= data
->DataWriteCallBack
)
355 data
->DataWriteCallBack(data
->unitnum
, data
->DataWriteUserData
);
361 /******* init_parallelunitclass ********************************/
363 static int UXParUnit_InitAttrBases(LIBBASETYPEPTR LIBBASE
)
365 return OOP_ObtainAttrBases(attrbases
);
369 static int UXParUnit_ExpungeAttrBases(LIBBASETYPEPTR LIBBASE
)
371 OOP_ReleaseAttrBases(attrbases
);
375 ADD2INITLIB(UXParUnit_InitAttrBases
, 0)
376 ADD2EXPUNGELIB(UXParUnit_ExpungeAttrBases
, 0)