2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
6 #include <aros/asmcall.h>
7 #include <aros/libcall.h>
9 #include <proto/exec.h>
10 #include <proto/dos.h>
11 #include <exec/types.h>
12 #include <exec/interrupts.h>
13 #include <hidd/serial.h>
14 #include <devices/serial.h>
16 #include "serial_intern.h"
19 #include <aros/debug.h>
21 extern struct serialbase
* pubSerialBase
;
23 ULONG
RBF_InterruptHandler(UBYTE
* data
, ULONG length
, ULONG unitnum
, APTR userdata
)
25 struct SerialUnit
* SU
= NULL
;
28 D(bug("!Received %d bytes on unit %d\n",length
,unitnum
));
30 SU
= findUnit(pubSerialBase
, unitnum
);
33 if (0 != (SU
->su_Status
& STATUS_READS_PENDING
)) {
34 struct IOStdReq
* ioreq
;
35 ioreq
= (struct IOStdReq
*)SU
->su_ActiveRead
;
38 D(bug("\t\tpre lh_Head: %p\n",SU
->su_QReadCommandPort
.mp_MsgList
.lh_Head
));
39 ioreq
= (struct IOStdReq
*)GetMsg(&SU
->su_QReadCommandPort
);
40 D(bug("\t\tpost lh_Head: %p\n",SU
->su_QReadCommandPort
.mp_MsgList
.lh_Head
));
41 SU
->su_ActiveRead
= (struct Message
*)ioreq
;
44 while (NULL
!= ioreq
) {
46 ** Copy the remaining data into a request buffer.
47 ** This loop woll possibly execute several times
51 D(bug("Have a IORequest (%p) for Serial device!\n",ioreq
));
53 destBuf
= ioreq
->io_Data
;
54 indexDestBuf
= ioreq
->io_Actual
;
56 ** I copy as many bytes as I can into this request
58 while (index
< length
) {
59 destBuf
[indexDestBuf
] = data
[index
];
64 D(bug("io_Length %d: io_Actual: %d\n",ioreq
->io_Length
,indexDestBuf
));
66 if ((-1 == ioreq
->io_Length
&& 0 == destBuf
[indexDestBuf
-1]) ||
67 (indexDestBuf
>= ioreq
->io_Length
)) {
69 ** this request is done, I answer the message
71 ioreq
->io_Actual
= indexDestBuf
;
72 ReplyMsg((struct Message
*)ioreq
);
75 ** Get the next request ...
77 D(bug("\t\tpre lh_Head: %p\n",SU
->su_QReadCommandPort
.mp_MsgList
.lh_Head
));
78 ioreq
= (struct IOStdReq
*)GetMsg(&SU
->su_QReadCommandPort
);
79 D(bug("\t\tpost lh_Head: %p\n",SU
->su_QReadCommandPort
.mp_MsgList
.lh_Head
));
80 D(bug("\t\tGot new ioreq (%p) from queue\n",ioreq
));
81 SU
->su_ActiveRead
= (struct Message
*)ioreq
;
86 if (index
== length
&& NULL
!= ioreq
) {
87 ioreq
->io_Actual
= indexDestBuf
;
92 SU
->su_Status
&= ~STATUS_READS_PENDING
;
95 } /* if (NULL != su) */
99 ** there's no more IORequest, so I have to copy into the
103 D(bug("Copying data into general buffer\n"));
105 SU
->su_Status
&= ~STATUS_READS_PENDING
;
106 while (index
< length
) {
107 if (0 == (SU
->su_Status
& STATUS_BUFFEROVERFLOW
)) {
108 UWORD tmp
= (SU
->su_InputNextPos
+ 1) % SU
->su_InBufLength
;
109 SU
->su_InputBuffer
[SU
->su_InputNextPos
] = data
[index
];
113 ** I am advancing the circular index su_InputNextPos
115 if (tmp
!= SU
->su_InputFirst
) {
116 SU
->su_InputNextPos
= tmp
;
117 D(bug("%d %d %d\n",SU
->su_InputNextPos
,SU
->su_InBufLength
,tmp
));
119 SU
->su_Status
|= STATUS_BUFFEROVERFLOW
;
131 * The write buffer empty interrupt handler
133 ULONG
WBE_InterruptHandler( ULONG unitnum
, APTR userdata
)
136 struct SerialUnit
* SU
;
138 SU
= findUnit(pubSerialBase
, unitnum
);
142 * First get any active write
144 struct IOExtSer
* ioserreq
= (struct IOExtSer
*)SU
->su_ActiveWrite
;
148 * Try to transmit the active write request
150 if (NULL
!= ioserreq
) {
152 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
153 &((char *)ioserreq
->IOSer
.io_Data
)[SU
->su_NextToWrite
],
156 * Check whether this was written completely.
158 total
+= writtenbytes
;
159 if (writtenbytes
>= SU
->su_WriteLength
) {
160 /* This one is done */
161 ReplyMsg(&ioserreq
->IOSer
.io_Message
);
164 * Not completed, yet.
166 SU
->su_WriteLength
-= writtenbytes
;
167 SU
->su_NextToWrite
+= writtenbytes
;
169 * Get out of the loop
175 * Get the next request from the queue.
177 ioserreq
= (struct IOExtSer
*)GetMsg(&SU
->su_QWriteCommandPort
);
178 SU
->su_ActiveWrite
= (struct Message
*)ioserreq
;
179 if (NULL
== ioserreq
) {
181 * No more request left. Done.
183 SU
->su_Status
&= ~STATUS_WRITES_PENDING
;
188 * There is a new request.
190 SU
->su_NextToWrite
= 0;
191 if (-1 == ioserreq
->IOSer
.io_Length
) {
192 SU
->su_WriteLength
= strlen(ioserreq
->IOSer
.io_Data
);
194 SU
->su_WriteLength
= ioserreq
->IOSer
.io_Length
;
197 * And repeat the loop with this request