2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 /****************************************************************************************/
14 #include <exec/resident.h>
15 #include <exec/interrupts.h>
16 #include <exec/semaphores.h>
17 #include <exec/initializers.h>
18 #include <devices/serial.h>
19 #include <devices/newstyle.h>
20 #include <proto/exec.h>
21 #include <proto/dos.h>
22 #include <proto/input.h>
23 #include <proto/oop.h>
24 #include <proto/utility.h>
25 #include <exec/memory.h>
26 #include <exec/errors.h>
28 #include <hidd/serial.h>
29 #include <utility/tagitem.h>
30 #include <aros/libcall.h>
31 #include <aros/symbolsets.h>
32 #include <exec/lists.h>
33 #if defined(__GNUC__) || defined(__INTEL_COMPILER)
34 # include "serial_intern.h"
38 # include <aros/debug.h>
40 #include LC_LIBDEFS_FILE
42 /****************************************************************************************/
44 #define NEWSTYLE_DEVICE 1
46 struct serialbase
* pubSerialBase
;
48 /****************************************************************************************/
52 static const UWORD SupportedCommands
[] =
68 /****************************************************************************************/
70 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR SerialDevice
)
72 D(bug("serial device: init\n"));
74 pubSerialBase
= SerialDevice
;
76 /* open the serial hidd */
77 if (NULL
== SerialDevice
->SerialHidd
)
79 SerialDevice
->SerialHidd
= OpenLibrary("DRIVERS:serial.hidd",0);
80 D(bug("serial.hidd base: 0x%x\n",SerialDevice
->SerialHidd
));
81 if (NULL
== SerialDevice
->SerialHidd
)
84 if (NULL
== SerialDevice
->oopBase
)
85 SerialDevice
->oopBase
= OpenLibrary(AROSOOP_NAME
, 0);
86 if (NULL
== SerialDevice
->oopBase
)
88 CloseLibrary(SerialDevice
->SerialHidd
);
89 SerialDevice
->SerialHidd
= FALSE
;
93 SerialDevice
->SerialObject
= OOP_NewObject(NULL
, CLID_Hidd_Serial
, NULL
);
94 D(bug("serialHidd Object: 0x%x\n",SerialDevice
->SerialObject
));
95 if (NULL
== SerialDevice
->SerialObject
)
97 CloseLibrary(SerialDevice
->oopBase
);
98 SerialDevice
->oopBase
= NULL
;
99 CloseLibrary(SerialDevice
->SerialHidd
);
100 SerialDevice
->SerialHidd
= NULL
;
105 NEWLIST(&SerialDevice
->UnitList
);
110 /****************************************************************************************/
112 static int GM_UNIQUENAME(Open
)
114 LIBBASETYPEPTR SerialDevice
,
115 struct IORequest
*ioreq
,
120 struct SerialUnit
* SU
= NULL
;
122 D(bug("serial device: Open unit %d\n",unitnum
));
124 if (ioreq
->io_Message
.mn_Length
< sizeof(struct IOExtSer
))
126 D(bug("serial.device/open: IORequest structure passed to OpenDevice is too small!\n"));
127 ioreq
->io_Error
= IOERR_OPENFAIL
;
131 ioreq
->io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
133 /* I have one more opener. */
135 /* In the list of available units look for the one with the same
136 UnitNumber as the given one */
137 if (0 == ioreq
->io_Error
)
139 SU
= findUnit(SerialDevice
, unitnum
);
141 /* If there is no such unit, yet, then create it */
144 D(bug("Creating Unit %d\n",unitnum
));
145 SU
= AllocMem(sizeof(struct SerialUnit
), MEMF_CLEAR
|MEMF_PUBLIC
);
148 SU
->su_OpenerCount
= 1;
149 SU
->su_UnitNum
= unitnum
;
150 SU
->su_SerFlags
= ((struct IOExtSer
*)ioreq
)->io_SerFlags
;
151 SU
->su_InputBuffer
= AllocMem(MINBUFSIZE
, MEMF_PUBLIC
);
153 if (NULL
!= SU
->su_InputBuffer
)
155 SU
->su_InBufLength
= MINBUFSIZE
;
156 ((struct IOExtSer
*)ioreq
)->io_RBufLen
= MINBUFSIZE
;
159 ** Initialize the message ports
161 NEWLIST(&SU
->su_QReadCommandPort
.mp_MsgList
);
162 SU
->su_QReadCommandPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
164 NEWLIST(&SU
->su_QWriteCommandPort
.mp_MsgList
);
165 SU
->su_QWriteCommandPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
167 InitSemaphore(&SU
->su_Lock
);
168 /* do further initilization here. Like getting the SerialUnit Object etc. */
170 SU
->su_Unit
= HIDD_Serial_NewUnit(SerialDevice
->SerialObject
, unitnum
);
171 if (NULL
!= SU
->su_Unit
)
173 HIDD_SerialUnit_Init(SU
->su_Unit
, RBF_InterruptHandler
, NULL
,
174 WBE_InterruptHandler
, NULL
);
175 ioreq
->io_Device
= (struct Device
*)SerialDevice
;
176 ioreq
->io_Unit
= (struct Unit
*)SU
;
179 ** put it in the list of open units
181 AddHead(&SerialDevice
->UnitList
, (struct Node
*)SU
);
187 D(bug("SerialUnit could not be created!\n"));
188 ioreq
->io_Error
= SerErr_DevBusy
;
190 FreeMem(SU
->su_InputBuffer
, MINBUFSIZE
);
193 FreeMem(SU
, sizeof(struct SerialUnit
));
195 ioreq
->io_Error
= SerErr_DevBusy
;
200 /* the unit does already exist. */
202 ** Check whether one more opener to this unit is tolerated
204 if (0 != (SU
->su_SerFlags
& SERF_SHARED
))
207 ** This unit is in shared mode and one more opener
210 ioreq
->io_Device
= (struct Device
*)SerialDevice
;
211 ioreq
->io_Unit
= (struct Unit
*)SU
;
214 SU
->su_OpenerCount
++;
219 ** I don't allow another opener
221 ioreq
->io_Error
= SerErr_DevBusy
;
226 return ioreq
->io_Error
== 0;
229 /****************************************************************************************/
231 static int GM_UNIQUENAME(Close
)
233 LIBBASETYPEPTR SerialDevice
,
234 struct IORequest
*ioreq
237 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->io_Unit
;
240 ** Check whether I am the last opener to this unit
242 if (1 == SU
->su_OpenerCount
)
245 ** I was the last opener. So let's get rid of it.
248 ** Remove the unit from the list
250 Remove((struct Node
*)&SU
->su_Node
);
252 HIDD_Serial_DisposeUnit(SerialDevice
->SerialObject
, SU
->su_Unit
);
254 if (NULL
!= SU
->su_InputBuffer
&& 0 != SU
->su_InBufLength
)
256 FreeMem(SU
->su_InputBuffer
,
260 FreeMem(SU
, sizeof(struct SerialUnit
));
266 ** There are still openers. Decrease the counter.
268 SU
->su_OpenerCount
--;
274 /****************************************************************************************/
277 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR SerialDevice
)
279 if (NULL
!= SerialDevice
->SerialObject
)
282 ** Throw away the HIDD object and close the library
284 OOP_DisposeObject(SerialDevice
->SerialObject
);
285 CloseLibrary(SerialDevice
->oopBase
);
286 CloseLibrary(SerialDevice
->SerialHidd
);
287 SerialDevice
->SerialHidd
= NULL
;
288 SerialDevice
->oopBase
= NULL
;
289 SerialDevice
->SerialObject
= NULL
;
295 /****************************************************************************************/
297 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
298 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)
299 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
300 ADD2CLOSEDEV(GM_UNIQUENAME(Close
), 0)
302 /****************************************************************************************/
304 #define ioStd(x) ((struct IOStdReq *)x)
305 AROS_LH1(void, beginio
,
306 AROS_LHA(struct IOExtSer
*, ioreq
, A1
),
307 struct serialbase
*, SerialDevice
, 5, Serial
)
312 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->IOSer
.io_Unit
;
314 D(bug("serial device: beginio(ioreq=%p)\n", ioreq
));
316 /* WaitIO will look into this */
317 ioreq
->IOSer
.io_Message
.mn_Node
.ln_Type
=NT_MESSAGE
;
320 ** As a lot of "public" data can be modified in the following lines
321 ** I protect it from other tasks by this semaphore
323 ObtainSemaphore(&SU
->su_Lock
);
325 switch (ioreq
->IOSer
.io_Command
)
328 case NSCMD_DEVICEQUERY
:
329 if(ioreq
->IOSer
.io_Length
< ((LONG
)OFFSET(NSDeviceQueryResult
, SupportedCommands
)) + sizeof(UWORD
*))
331 ioreq
->IOSer
.io_Error
= IOERR_BADLENGTH
;
335 struct NSDeviceQueryResult
*d
;
337 d
= (struct NSDeviceQueryResult
*)ioreq
->IOSer
.io_Data
;
339 d
->DevQueryFormat
= 0;
340 d
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
341 d
->DeviceType
= NSDEVTYPE_SERIAL
;
342 d
->DeviceSubType
= 0;
343 d
->SupportedCommands
= (UWORD
*)SupportedCommands
;
345 ioreq
->IOSer
.io_Actual
= sizeof(struct NSDeviceQueryResult
);
346 ioreq
->IOSer
.io_Error
= 0;
349 ** The request could be completed immediately.
350 ** Check if I have to reply the message
352 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
353 ReplyMsg(&ioreq
->IOSer
.io_Message
);
358 /*******************************************************************/
361 ** Let me see whether I can copy any data at all and
362 ** whether nobody else is using this device now
364 ioreq
->IOSer
.io_Actual
= 0;
368 if (SU
->su_InputFirst
!= SU
->su_InputNextPos
&&
369 0 == (SU
->su_Status
& STATUS_READS_PENDING
) )
371 D(bug("There are data in the receive buffer!\n"));
373 No matter how many bytes are in the input buffer,
374 I will copy them into the IORequest buffer immediately.
375 This way I can satisfy requests that are larger than
376 the input buffer, because the Interrupt will have
377 to put its bytes directly into the buffer of the
380 if (-1 == ioreq
->IOSer
.io_Length
)
382 if (TRUE
== copyInDataUntilZero(SU
, (struct IOStdReq
*)ioreq
))
385 ** it could be completed immediately.
386 ** Check if I have to reply the message.
388 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
389 ReplyMsg(&ioreq
->IOSer
.io_Message
);
397 D(bug("Calling copyInData!\n"));
398 if (TRUE
== copyInData(SU
, (struct IOStdReq
*)ioreq
))
401 ** it could be completed immediately.
402 ** Check if I have to reply the message.
404 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
405 ReplyMsg(&ioreq
->IOSer
.io_Message
);
412 if (NULL
!= SU
->su_ActiveRead
)
414 kprintf("READ: error in datastructure!");
420 D(bug("Setting STATUS_READS_PENDING\n"));
422 SU
->su_Status
|= STATUS_READS_PENDING
;
424 D(bug("The read request (%p) could not be satisfied! Queuing it.\n",ioreq
));
426 ** Everything that falls down here could not be completely
429 if (NULL
!= SU
->su_ActiveRead
) {
430 SU
->su_ActiveRead
= (struct Message
*)ioreq
;
432 PutMsg(&SU
->su_QReadCommandPort
,
433 (struct Message
*)ioreq
);
439 ** As I am returning immediately I will tell that this
440 ** could not be done QUICK
442 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
445 /*******************************************************************/
448 /* Write data to the SerialUnit */
449 ioreq
->IOSer
.io_Actual
= 0;
453 /* Check whether I can write some data immediately */
454 if (0 == (SU
->su_Status
& STATUS_WRITES_PENDING
))
457 BOOL complete
= FALSE
;
459 Writing the first few bytes to the UART has to have the
460 effect that whenever the UART can receive new data
461 a HW interrupt must happen. So this writing to the
462 UART should get the sequence of HW-interrupts going
463 until there is no more data to write
465 if (-1 == ioreq
->IOSer
.io_Length
)
467 int stringlen
= strlen(ioreq
->IOSer
.io_Data
);
468 D(bug("Transmitting NULL termninated string.\n"));
470 ** Supposed to write the buffer to the port until a '\0'
474 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
475 ioreq
->IOSer
.io_Data
,
477 if (writtenbytes
== stringlen
)
480 SU
->su_WriteLength
= stringlen
-writtenbytes
;
484 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
485 ioreq
->IOSer
.io_Data
,
486 ioreq
->IOSer
.io_Length
);
487 if (writtenbytes
== ioreq
->IOSer
.io_Length
)
490 SU
->su_WriteLength
= ioreq
->IOSer
.io_Length
-writtenbytes
;
493 ** A consistency check between the STATUS_WRITES_PENDING flag
494 ** and the pointer SU->su_ActiveWrite which both have to be
495 ** set or cleared at the same time.
497 if (NULL
!= SU
->su_ActiveWrite
)
502 if (complete
== TRUE
)
504 D(bug("completely sended the stream!\n"));
506 ** The request could be completed immediately.
507 ** Check if I have to reply the message
509 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
510 ReplyMsg(&ioreq
->IOSer
.io_Message
);
515 ** The request could not be completed immediately
518 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
519 SU
->su_ActiveWrite
= (struct Message
*)ioreq
;
520 SU
->su_Status
|= STATUS_WRITES_PENDING
;
521 SU
->su_NextToWrite
= writtenbytes
;
527 I could not write the data immediately as another request
528 is already there. So I will make this
529 the responsibility of the interrupt handler to use this
530 request once it is done with the active request.
532 PutMsg(&SU
->su_QWriteCommandPort
,
533 (struct Message
*)ioreq
);
534 SU
->su_Status
|= STATUS_WRITES_PENDING
;
536 ** As I am returning immediately I will tell that this
537 ** could not be done QUICK
539 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
547 /* Simply reset the input buffer pointer no matter what */
549 SU
->su_InputNextPos
= 0;
550 SU
->su_InputFirst
= 0;
551 SU
->su_Status
&= ~STATUS_BUFFEROVERFLOW
;
552 ioreq
->IOSer
.io_Error
= 0;
555 ** The request could be completed immediately.
556 ** Check if I have to reply the message
558 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
559 ReplyMsg(&ioreq
->IOSer
.io_Message
);
562 /*******************************************************************/
566 /* All IORequests, including the active ones, are aborted */
567 /* Abort the active IORequests */
568 SU
->su_Status
&= ~(STATUS_READS_PENDING
|STATUS_WRITES_PENDING
);
570 if (NULL
!= SU
->su_ActiveRead
)
572 ((struct IOStdReq
*)SU
->su_ActiveRead
)->io_Error
= IOERR_ABORTED
;
573 ReplyMsg(SU
->su_ActiveRead
);
576 if (NULL
!= SU
->su_ActiveWrite
)
578 ((struct IOStdReq
*)SU
->su_ActiveWrite
)->io_Error
= IOERR_ABORTED
;
579 ReplyMsg(SU
->su_ActiveWrite
);
582 /* change the Buffer pointers to reset position */
583 SU
->su_InputFirst
= 0;
584 SU
->su_InputNextPos
= 0;
586 /* check the buffer for correct init size */
587 if (MINBUFSIZE
!= SU
->su_InBufLength
)
589 BYTE
* oldBuffer
= SU
->su_InputBuffer
;
590 BYTE
* newBuffer
= (BYTE
*)AllocMem(MINBUFSIZE
,MEMF_PUBLIC
);
591 if (NULL
!= newBuffer
)
593 SU
->su_InputBuffer
= newBuffer
;
594 FreeMem(oldBuffer
, SU
->su_InBufLength
);
595 /* write new buffersize */
596 SU
->su_InBufLength
= MINBUFSIZE
;
600 /* Buffer could not be allocated */
604 /* now fall through to CMD_FLUSH */
607 /*******************************************************************/
611 ** Clear all queued IO request for the given serial unit except
612 ** for the active ones.
618 struct IOStdReq
* iosreq
=
619 (struct IOStdReq
*)GetMsg(&SU
->su_QReadCommandPort
);
622 iosreq
->io_Error
= IOERR_ABORTED
;
623 ReplyMsg((struct Message
*)iosreq
);
628 struct IOStdReq
* iosreq
=
629 (struct IOStdReq
*)GetMsg(&SU
->su_QWriteCommandPort
);
632 iosreq
->io_Error
= IOERR_ABORTED
;
633 ReplyMsg((struct Message
*)iosreq
);
635 ioreq
->IOSer
.io_Error
= 0;
640 ** The request could be completed immediately.
641 ** Check if I have to reply the message
643 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
644 ReplyMsg(&ioreq
->IOSer
.io_Message
);
647 /*******************************************************************/
651 * Start the serial port IO. Tell the hidd to do that.
654 HIDD_SerialUnit_Start(SU
->su_Unit
);
656 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
657 ReplyMsg(&ioreq
->IOSer
.io_Message
);
658 ioreq
->IOSer
.io_Flags
|= IOF_QUICK
;
661 /*******************************************************************/
664 * Stop any serial port IO going on. Tell the hidd to do that.
667 HIDD_SerialUnit_Stop(SU
->su_Unit
);
669 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
670 ReplyMsg(&ioreq
->IOSer
.io_Message
);
671 ioreq
->IOSer
.io_Flags
|= IOF_QUICK
;
674 /*******************************************************************/
679 ** set the io_Status to the status of the serial port
681 ioreq
->io_Status
= HIDD_SerialUnit_GetStatus(SU
->su_Unit
);
682 if (0 != (SU
->su_Status
& STATUS_BUFFEROVERFLOW
))
684 ioreq
->io_Status
|= IO_STATF_OVERRUN
;
685 ioreq
->IOSer
.io_Actual
= 0;
689 /* pass back the number of unread input characters */
690 int unread
= SU
->su_InputNextPos
- SU
->su_InputFirst
;
692 ioreq
->IOSer
.io_Actual
= SU
->su_InBufLength
+ unread
;
694 ioreq
->IOSer
.io_Actual
= unread
;
697 ioreq
->IOSer
.io_Error
= 0;
700 ** The request could be completed immediately.
701 ** Check if I have to reply the message
703 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
704 ReplyMsg(&ioreq
->IOSer
.io_Message
);
708 /*******************************************************************/
710 case SDCMD_SETPARAMS
:
712 /* Change of buffer size for input buffer? */
715 if (ioreq
->io_RBufLen
>= MINBUFSIZE
&&
716 ioreq
->io_RBufLen
!= SU
->su_InBufLength
)
719 ** The other ones I will only do if I am not busy with
720 ** reading or writing data right now
722 if (0 == (SU
->su_Status
& (STATUS_READS_PENDING
|
723 STATUS_WRITES_PENDING
) ))
725 /* the user requests a different inputbuffer size.
727 int OldInBufLength
= SU
->su_InBufLength
;
728 BYTE
* OldInBuf
= SU
->su_InputBuffer
;
731 NewInBuf
= AllocMem(ioreq
->io_RBufLen
, MEMF_PUBLIC
);
732 if (NULL
!= NewInBuf
)
734 /* we got a new buffer */
735 /* just in case the interrupt wants to write data to
736 the input buffer, tell it that it cannot do this right
737 now as I am changing the buffer */
738 SU
->su_Status
|= STATUS_CHANGING_IN_BUFFER
;
739 SU
->su_InputNextPos
= 0;
740 SU
->su_InputFirst
= 0;
741 SU
->su_InputBuffer
= NewInBuf
;
742 SU
->su_InBufLength
= ioreq
->io_RBufLen
;
743 SU
->su_Status
&= ~STATUS_CHANGING_IN_BUFFER
;
745 /* free the old buffer */
746 FreeMem(OldInBuf
, OldInBufLength
);
750 ioreq
->IOSer
.io_Error
= SerErr_BufErr
;
753 /* end of buffer changing buiseness */
757 /* Changing the break time */
758 if (ioreq
->io_BrkTime
!= 0)
759 SU
->su_BrkTime
= ioreq
->io_BrkTime
;
761 /* Copy the Flags from the iorequest to the Unit's Flags */
762 SU
->su_SerFlags
= ioreq
->io_SerFlags
;
764 /* Change baudrate if necessary and possible */
765 if (SU
->su_Baud
!= ioreq
->io_Baud
)
767 /* Change the Baudrate */
768 D(bug("Setting baudrate on SerialUnit!\n"));
769 success
= HIDD_SerialUnit_SetBaudrate(SU
->su_Unit
,
772 if (FALSE
== success
)
774 D(bug("Setting baudrate didn't work!\n"));
775 /* this Baudrate is not supported */
776 ioreq
->IOSer
.io_Error
= SerErr_BaudMismatch
;
779 SU
->su_Baud
= ioreq
->io_Baud
;
780 } /* Baudrate changing */
782 /* Copy the TermArray */
783 SU
->su_TermArray
= ioreq
->io_TermArray
;
785 /* copy the readlen and writelen */
786 if (SU
->su_ReadLen
!= ioreq
->io_ReadLen
||
787 SU
->su_WriteLen
!= ioreq
->io_WriteLen
||
788 SU
->su_StopBits
!= ioreq
->io_StopBits
)
790 struct TagItem tags
[] =
791 {{TAG_DATALENGTH
, ioreq
->io_ReadLen
},
792 {TAG_STOP_BITS
, ioreq
->io_StopBits
},
793 {TAG_SKIP
, 0}, // !!! PARITY!!!
795 success
= HIDD_SerialUnit_SetParameters(SU
->su_Unit
,
797 if (FALSE
== success
) {
798 ioreq
->IOSer
.io_Error
= SerErr_InvParam
;
799 kprintf("HIDD_SerialUnit_SetParameters() failed.\n");
802 SU
->su_ReadLen
= ioreq
->io_ReadLen
;
803 SU
->su_WriteLen
= ioreq
->io_WriteLen
;
804 SU
->su_StopBits
= ioreq
->io_StopBits
;
807 SU
->su_CtlChar
= ioreq
->io_CtlChar
;
811 ** The request could be completed immediately.
812 ** Check if I have to reply the message
814 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
815 ReplyMsg(&ioreq
->IOSer
.io_Message
);
818 /*******************************************************************/
822 if (0 != (ioreq
->io_SerFlags
& SERF_QUEUEDBRK
))
824 /* might have to queue that request */
825 if (0 != (SU
->su_Status
& STATUS_WRITES_PENDING
))
827 kprintf("%s: Queuing SDCMD_BREAK! This probably doesn't work correctly!\n");
828 PutMsg(&SU
->su_QWriteCommandPort
,
829 (struct Message
*)ioreq
);
830 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
834 /* Immediately execute this command */
835 ioreq
->IOSer
.io_Error
= HIDD_SerialUnit_SendBreak(SU
->su_Unit
,
839 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
840 ReplyMsg(&ioreq
->IOSer
.io_Message
);
844 /*******************************************************************/
847 /* unknown command */
848 ioreq
->IOSer
.io_Error
= IOERR_NOCMD
;
851 ** The request could be completed immediately.
852 ** Check if I have to reply the message
854 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
855 ReplyMsg(&ioreq
->IOSer
.io_Message
);
860 ReleaseSemaphore(&SU
->su_Lock
);
862 D(bug("id: Return from BeginIO()\n"));
867 /****************************************************************************************/
869 AROS_LH1(LONG
, abortio
,
870 AROS_LHA(struct IORequest
*, ioreq
, A1
),
871 struct serialbase
*, SerialDevice
, 6, Serial
)
875 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->io_Unit
;
878 ** is it the active request?
882 if ((struct Message
*)ioreq
== SU
->su_ActiveRead
)
885 ** It's the active reuquest. I make the next available
886 ** one the active request.
888 SU
->su_ActiveRead
= GetMsg(&SU
->su_QReadCommandPort
);
889 ReplyMsg(&ioreq
->io_Message
);
894 ** It's not the active request. So I'll take it out of the
895 ** list of queued messages and reply the message.
897 Remove(&ioreq
->io_Message
.mn_Node
);
898 ReplyMsg(&ioreq
->io_Message
);
906 /****************************************************************************************/