grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / serial / serial_interrupthandlers.c
blob5c71c2adb376915595dbaf70c5a8976839ce7099
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <aros/asmcall.h>
7 #include <aros/libcall.h>
8 #include <stdio.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>
15 #include <string.h>
16 #include "serial_intern.h"
18 #define DEBUG 0
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;
26 ULONG index = 0;
28 D(bug("!Received %d bytes on unit %d\n",length,unitnum));
30 SU = findUnit(pubSerialBase, unitnum);
32 if (NULL != SU) {
33 if (0 != (SU->su_Status & STATUS_READS_PENDING)) {
34 struct IOStdReq * ioreq;
35 ioreq = (struct IOStdReq *)SU->su_ActiveRead;
37 if (NULL == ioreq) {
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
49 UBYTE * destBuf;
50 UWORD indexDestBuf;
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];
61 index++;
62 indexDestBuf++;
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;
82 break;
86 if (index == length && NULL != ioreq) {
87 ioreq->io_Actual = indexDestBuf;
88 break;
91 if (NULL == ioreq)
92 SU->su_Status &= ~STATUS_READS_PENDING;
95 } /* if (NULL != su) */
97 if (index < length) {
99 ** there's no more IORequest, so I have to copy into the
100 ** genearal buffer
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];
110 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));
118 } else {
119 SU->su_Status |= STATUS_BUFFEROVERFLOW;
120 break;
123 } else
124 break;
127 return length;
131 * The write buffer empty interrupt handler
133 ULONG WBE_InterruptHandler( ULONG unitnum, APTR userdata)
135 ULONG total = 0;
136 struct SerialUnit * SU;
138 SU = findUnit(pubSerialBase, unitnum);
140 if (NULL != SU) {
142 * First get any active write
144 struct IOExtSer * ioserreq = (struct IOExtSer *)SU->su_ActiveWrite;
146 while (1) {
148 * Try to transmit the active write request
150 if (NULL != ioserreq) {
151 ULONG writtenbytes;
152 writtenbytes = HIDD_SerialUnit_Write(SU->su_Unit,
153 &((char *)ioserreq->IOSer.io_Data)[SU->su_NextToWrite],
154 SU->su_WriteLength);
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);
162 } else {
164 * Not completed, yet.
166 SU->su_WriteLength -= writtenbytes;
167 SU->su_NextToWrite += writtenbytes;
169 * Get out of the loop
171 break;
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;
184 break;
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);
193 } else {
194 SU->su_WriteLength = ioserreq->IOSer.io_Length;
197 * And repeat the loop with this request
201 return total;