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
++;
215 D(bug("%s: Opened %d on unit %d\n", __func__
, SU
->su_OpenerCount
, unitnum
));
220 ** I don't allow another opener
222 D(bug("%s: Exclusive access is set for unit %d\n", __func__
, unitnum
));
223 ioreq
->io_Error
= SerErr_DevBusy
;
228 return ioreq
->io_Error
== 0;
231 /****************************************************************************************/
233 static int GM_UNIQUENAME(Close
)
235 LIBBASETYPEPTR SerialDevice
,
236 struct IORequest
*ioreq
239 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->io_Unit
;
242 ** Check whether I am the last opener to this unit
244 if (1 == SU
->su_OpenerCount
)
247 ** I was the last opener. So let's get rid of it.
250 ** Remove the unit from the list
252 Remove((struct Node
*)&SU
->su_Node
);
254 HIDD_Serial_DisposeUnit(SerialDevice
->SerialObject
, SU
->su_Unit
);
256 if (NULL
!= SU
->su_InputBuffer
&& 0 != SU
->su_InBufLength
)
258 FreeMem(SU
->su_InputBuffer
,
262 FreeMem(SU
, sizeof(struct SerialUnit
));
268 ** There are still openers. Decrease the counter.
270 SU
->su_OpenerCount
--;
276 /****************************************************************************************/
279 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR SerialDevice
)
281 if (NULL
!= SerialDevice
->SerialObject
)
284 ** Throw away the HIDD object and close the library
286 OOP_DisposeObject(SerialDevice
->SerialObject
);
287 CloseLibrary(SerialDevice
->oopBase
);
288 CloseLibrary(SerialDevice
->SerialHidd
);
289 SerialDevice
->SerialHidd
= NULL
;
290 SerialDevice
->oopBase
= NULL
;
291 SerialDevice
->SerialObject
= NULL
;
297 /****************************************************************************************/
299 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
300 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)
301 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
302 ADD2CLOSEDEV(GM_UNIQUENAME(Close
), 0)
304 /****************************************************************************************/
306 #define ioStd(x) ((struct IOStdReq *)x)
307 AROS_LH1(void, beginio
,
308 AROS_LHA(struct IOExtSer
*, ioreq
, A1
),
309 struct serialbase
*, SerialDevice
, 5, Serial
)
314 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->IOSer
.io_Unit
;
316 D(bug("serial device: beginio(ioreq=%p)\n", ioreq
));
318 /* WaitIO will look into this */
319 ioreq
->IOSer
.io_Message
.mn_Node
.ln_Type
=NT_MESSAGE
;
322 ** As a lot of "public" data can be modified in the following lines
323 ** I protect it from other tasks by this semaphore
325 ObtainSemaphore(&SU
->su_Lock
);
327 switch (ioreq
->IOSer
.io_Command
)
330 case NSCMD_DEVICEQUERY
:
331 if(ioreq
->IOSer
.io_Length
< ((IPTR
)OFFSET(NSDeviceQueryResult
, SupportedCommands
)) + sizeof(UWORD
*))
333 ioreq
->IOSer
.io_Error
= IOERR_BADLENGTH
;
337 struct NSDeviceQueryResult
*d
;
339 d
= (struct NSDeviceQueryResult
*)ioreq
->IOSer
.io_Data
;
341 d
->DevQueryFormat
= 0;
342 d
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
343 d
->DeviceType
= NSDEVTYPE_SERIAL
;
344 d
->DeviceSubType
= 0;
345 d
->SupportedCommands
= (UWORD
*)SupportedCommands
;
347 ioreq
->IOSer
.io_Actual
= sizeof(struct NSDeviceQueryResult
);
348 ioreq
->IOSer
.io_Error
= 0;
351 ** The request could be completed immediately.
352 ** Check if I have to reply the message
354 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
355 ReplyMsg(&ioreq
->IOSer
.io_Message
);
360 /*******************************************************************/
363 ** Let me see whether I can copy any data at all and
364 ** whether nobody else is using this device now
366 ioreq
->IOSer
.io_Actual
= 0;
370 if (SU
->su_InputFirst
!= SU
->su_InputNextPos
&&
371 0 == (SU
->su_Status
& STATUS_READS_PENDING
) )
373 D(bug("There are data in the receive buffer!\n"));
375 No matter how many bytes are in the input buffer,
376 I will copy them into the IORequest buffer immediately.
377 This way I can satisfy requests that are larger than
378 the input buffer, because the Interrupt will have
379 to put its bytes directly into the buffer of the
382 if (-1 == ioreq
->IOSer
.io_Length
)
384 if (TRUE
== copyInDataUntilZero(SU
, (struct IOStdReq
*)ioreq
))
387 ** it could be completed immediately.
388 ** Check if I have to reply the message.
390 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
391 ReplyMsg(&ioreq
->IOSer
.io_Message
);
399 D(bug("Calling copyInData!\n"));
400 if (TRUE
== copyInData(SU
, (struct IOStdReq
*)ioreq
))
403 ** it could be completed immediately.
404 ** Check if I have to reply the message.
406 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
407 ReplyMsg(&ioreq
->IOSer
.io_Message
);
414 if (NULL
!= SU
->su_ActiveRead
)
416 kprintf("READ: error in datastructure!");
422 D(bug("Setting STATUS_READS_PENDING\n"));
424 SU
->su_Status
|= STATUS_READS_PENDING
;
426 D(bug("The read request (%p) could not be satisfied! Queuing it.\n",ioreq
));
428 ** Everything that falls down here could not be completely
431 if (NULL
!= SU
->su_ActiveRead
) {
432 SU
->su_ActiveRead
= (struct Message
*)ioreq
;
434 PutMsg(&SU
->su_QReadCommandPort
,
435 (struct Message
*)ioreq
);
441 ** As I am returning immediately I will tell that this
442 ** could not be done QUICK
444 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
447 /*******************************************************************/
450 /* Write data to the SerialUnit */
451 ioreq
->IOSer
.io_Actual
= 0;
455 /* Check whether I can write some data immediately */
456 if (0 == (SU
->su_Status
& STATUS_WRITES_PENDING
))
459 BOOL complete
= FALSE
;
461 Writing the first few bytes to the UART has to have the
462 effect that whenever the UART can receive new data
463 a HW interrupt must happen. So this writing to the
464 UART should get the sequence of HW-interrupts going
465 until there is no more data to write
467 if (-1 == ioreq
->IOSer
.io_Length
)
469 int stringlen
= strlen(ioreq
->IOSer
.io_Data
);
470 D(bug("Transmitting NULL termninated string.\n"));
472 ** Supposed to write the buffer to the port until a '\0'
476 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
477 ioreq
->IOSer
.io_Data
,
479 if (writtenbytes
== stringlen
)
482 SU
->su_WriteLength
= stringlen
-writtenbytes
;
486 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
487 ioreq
->IOSer
.io_Data
,
488 ioreq
->IOSer
.io_Length
);
489 if (writtenbytes
== ioreq
->IOSer
.io_Length
)
492 SU
->su_WriteLength
= ioreq
->IOSer
.io_Length
-writtenbytes
;
495 ** A consistency check between the STATUS_WRITES_PENDING flag
496 ** and the pointer SU->su_ActiveWrite which both have to be
497 ** set or cleared at the same time.
499 if (NULL
!= SU
->su_ActiveWrite
)
504 if (complete
== TRUE
)
506 D(bug("completely sended the stream!\n"));
508 ** The request could be completed immediately.
509 ** Check if I have to reply the message
511 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
512 ReplyMsg(&ioreq
->IOSer
.io_Message
);
517 ** The request could not be completed immediately
520 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
521 SU
->su_ActiveWrite
= (struct Message
*)ioreq
;
522 SU
->su_Status
|= STATUS_WRITES_PENDING
;
523 SU
->su_NextToWrite
= writtenbytes
;
529 I could not write the data immediately as another request
530 is already there. So I will make this
531 the responsibility of the interrupt handler to use this
532 request once it is done with the active request.
534 PutMsg(&SU
->su_QWriteCommandPort
,
535 (struct Message
*)ioreq
);
536 SU
->su_Status
|= STATUS_WRITES_PENDING
;
538 ** As I am returning immediately I will tell that this
539 ** could not be done QUICK
541 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
549 /* Simply reset the input buffer pointer no matter what */
551 SU
->su_InputNextPos
= 0;
552 SU
->su_InputFirst
= 0;
553 SU
->su_Status
&= ~STATUS_BUFFEROVERFLOW
;
554 ioreq
->IOSer
.io_Error
= 0;
557 ** The request could be completed immediately.
558 ** Check if I have to reply the message
560 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
561 ReplyMsg(&ioreq
->IOSer
.io_Message
);
564 /*******************************************************************/
568 /* All IORequests, including the active ones, are aborted */
569 /* Abort the active IORequests */
570 SU
->su_Status
&= ~(STATUS_READS_PENDING
|STATUS_WRITES_PENDING
);
572 if (NULL
!= SU
->su_ActiveRead
)
574 ((struct IOStdReq
*)SU
->su_ActiveRead
)->io_Error
= IOERR_ABORTED
;
575 ReplyMsg(SU
->su_ActiveRead
);
578 if (NULL
!= SU
->su_ActiveWrite
)
580 ((struct IOStdReq
*)SU
->su_ActiveWrite
)->io_Error
= IOERR_ABORTED
;
581 ReplyMsg(SU
->su_ActiveWrite
);
584 /* change the Buffer pointers to reset position */
585 SU
->su_InputFirst
= 0;
586 SU
->su_InputNextPos
= 0;
588 /* check the buffer for correct init size */
589 if (MINBUFSIZE
!= SU
->su_InBufLength
)
591 BYTE
* oldBuffer
= SU
->su_InputBuffer
;
592 BYTE
* newBuffer
= (BYTE
*)AllocMem(MINBUFSIZE
,MEMF_PUBLIC
);
593 if (NULL
!= newBuffer
)
595 SU
->su_InputBuffer
= newBuffer
;
596 FreeMem(oldBuffer
, SU
->su_InBufLength
);
597 /* write new buffersize */
598 SU
->su_InBufLength
= MINBUFSIZE
;
602 /* Buffer could not be allocated */
606 /* now fall through to CMD_FLUSH */
609 /*******************************************************************/
613 ** Clear all queued IO request for the given serial unit except
614 ** for the active ones.
620 struct IOStdReq
* iosreq
=
621 (struct IOStdReq
*)GetMsg(&SU
->su_QReadCommandPort
);
624 iosreq
->io_Error
= IOERR_ABORTED
;
625 ReplyMsg((struct Message
*)iosreq
);
630 struct IOStdReq
* iosreq
=
631 (struct IOStdReq
*)GetMsg(&SU
->su_QWriteCommandPort
);
634 iosreq
->io_Error
= IOERR_ABORTED
;
635 ReplyMsg((struct Message
*)iosreq
);
637 ioreq
->IOSer
.io_Error
= 0;
642 ** The request could be completed immediately.
643 ** Check if I have to reply the message
645 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
646 ReplyMsg(&ioreq
->IOSer
.io_Message
);
649 /*******************************************************************/
653 * Start the serial port IO. Tell the hidd to do that.
656 HIDD_SerialUnit_Start(SU
->su_Unit
);
658 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
659 ReplyMsg(&ioreq
->IOSer
.io_Message
);
660 ioreq
->IOSer
.io_Flags
|= IOF_QUICK
;
663 /*******************************************************************/
666 * Stop any serial port IO going on. Tell the hidd to do that.
669 HIDD_SerialUnit_Stop(SU
->su_Unit
);
671 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
672 ReplyMsg(&ioreq
->IOSer
.io_Message
);
673 ioreq
->IOSer
.io_Flags
|= IOF_QUICK
;
676 /*******************************************************************/
681 ** set the io_Status to the status of the serial port
683 ioreq
->io_Status
= HIDD_SerialUnit_GetStatus(SU
->su_Unit
);
684 if (0 != (SU
->su_Status
& STATUS_BUFFEROVERFLOW
))
686 ioreq
->io_Status
|= IO_STATF_OVERRUN
;
687 ioreq
->IOSer
.io_Actual
= 0;
691 /* pass back the number of unread input characters */
692 int unread
= SU
->su_InputNextPos
- SU
->su_InputFirst
;
694 ioreq
->IOSer
.io_Actual
= SU
->su_InBufLength
+ unread
;
696 ioreq
->IOSer
.io_Actual
= unread
;
699 ioreq
->IOSer
.io_Error
= 0;
702 ** The request could be completed immediately.
703 ** Check if I have to reply the message
705 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
706 ReplyMsg(&ioreq
->IOSer
.io_Message
);
710 /*******************************************************************/
712 case SDCMD_SETPARAMS
:
714 /* Change of buffer size for input buffer? */
717 if (ioreq
->io_RBufLen
>= MINBUFSIZE
&&
718 ioreq
->io_RBufLen
!= SU
->su_InBufLength
)
721 ** The other ones I will only do if I am not busy with
722 ** reading or writing data right now
724 if (0 == (SU
->su_Status
& (STATUS_READS_PENDING
|
725 STATUS_WRITES_PENDING
) ))
727 /* the user requests a different inputbuffer size.
729 int OldInBufLength
= SU
->su_InBufLength
;
730 BYTE
* OldInBuf
= SU
->su_InputBuffer
;
733 NewInBuf
= AllocMem(ioreq
->io_RBufLen
, MEMF_PUBLIC
);
734 if (NULL
!= NewInBuf
)
736 /* we got a new buffer */
737 /* just in case the interrupt wants to write data to
738 the input buffer, tell it that it cannot do this right
739 now as I am changing the buffer */
740 SU
->su_Status
|= STATUS_CHANGING_IN_BUFFER
;
741 SU
->su_InputNextPos
= 0;
742 SU
->su_InputFirst
= 0;
743 SU
->su_InputBuffer
= NewInBuf
;
744 SU
->su_InBufLength
= ioreq
->io_RBufLen
;
745 SU
->su_Status
&= ~STATUS_CHANGING_IN_BUFFER
;
747 /* free the old buffer */
748 FreeMem(OldInBuf
, OldInBufLength
);
752 ioreq
->IOSer
.io_Error
= SerErr_BufErr
;
755 /* end of buffer changing buiseness */
759 /* Changing the break time */
760 if (ioreq
->io_BrkTime
!= 0)
761 SU
->su_BrkTime
= ioreq
->io_BrkTime
;
763 /* Copy the Flags from the iorequest to the Unit's Flags */
764 SU
->su_SerFlags
= ioreq
->io_SerFlags
;
766 /* Change baudrate if necessary and possible */
767 if (SU
->su_Baud
!= ioreq
->io_Baud
)
769 /* Change the Baudrate */
770 D(bug("Setting baudrate on SerialUnit!\n"));
771 success
= HIDD_SerialUnit_SetBaudrate(SU
->su_Unit
,
774 if (FALSE
== success
)
776 D(bug("Setting baudrate didn't work!\n"));
777 /* this Baudrate is not supported */
778 ioreq
->IOSer
.io_Error
= SerErr_BaudMismatch
;
781 SU
->su_Baud
= ioreq
->io_Baud
;
782 } /* Baudrate changing */
784 /* Copy the TermArray */
785 SU
->su_TermArray
= ioreq
->io_TermArray
;
787 /* copy the readlen and writelen */
788 if (SU
->su_ReadLen
!= ioreq
->io_ReadLen
||
789 SU
->su_WriteLen
!= ioreq
->io_WriteLen
||
790 SU
->su_StopBits
!= ioreq
->io_StopBits
)
792 struct TagItem tags
[] =
793 {{TAG_DATALENGTH
, ioreq
->io_ReadLen
},
794 {TAG_STOP_BITS
, ioreq
->io_StopBits
},
795 {TAG_SKIP
, 0}, // !!! PARITY!!!
797 success
= HIDD_SerialUnit_SetParameters(SU
->su_Unit
,
799 if (FALSE
== success
) {
800 ioreq
->IOSer
.io_Error
= SerErr_InvParam
;
801 kprintf("HIDD_SerialUnit_SetParameters() failed.\n");
804 SU
->su_ReadLen
= ioreq
->io_ReadLen
;
805 SU
->su_WriteLen
= ioreq
->io_WriteLen
;
806 SU
->su_StopBits
= ioreq
->io_StopBits
;
809 SU
->su_CtlChar
= ioreq
->io_CtlChar
;
813 ** The request could be completed immediately.
814 ** Check if I have to reply the message
816 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
817 ReplyMsg(&ioreq
->IOSer
.io_Message
);
820 /*******************************************************************/
824 if (0 != (ioreq
->io_SerFlags
& SERF_QUEUEDBRK
))
826 /* might have to queue that request */
827 if (0 != (SU
->su_Status
& STATUS_WRITES_PENDING
))
829 kprintf("%s: Queuing SDCMD_BREAK! This probably doesn't work correctly!\n");
830 PutMsg(&SU
->su_QWriteCommandPort
,
831 (struct Message
*)ioreq
);
832 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
836 /* Immediately execute this command */
837 ioreq
->IOSer
.io_Error
= HIDD_SerialUnit_SendBreak(SU
->su_Unit
,
841 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
842 ReplyMsg(&ioreq
->IOSer
.io_Message
);
846 /*******************************************************************/
849 /* unknown command */
850 ioreq
->IOSer
.io_Error
= IOERR_NOCMD
;
853 ** The request could be completed immediately.
854 ** Check if I have to reply the message
856 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
857 ReplyMsg(&ioreq
->IOSer
.io_Message
);
862 ReleaseSemaphore(&SU
->su_Lock
);
864 D(bug("id: Return from BeginIO()\n"));
869 /****************************************************************************************/
871 AROS_LH1(LONG
, abortio
,
872 AROS_LHA(struct IORequest
*, ioreq
, A1
),
873 struct serialbase
*, SerialDevice
, 6, Serial
)
877 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->io_Unit
;
880 ** is it the active request?
884 if ((struct Message
*)ioreq
== SU
->su_ActiveRead
)
887 ** It's the active reuquest. I make the next available
888 ** one the active request.
890 SU
->su_ActiveRead
= GetMsg(&SU
->su_QReadCommandPort
);
891 ReplyMsg(&ioreq
->io_Message
);
896 ** It's not the active request. So I'll take it out of the
897 ** list of queued messages and reply the message.
899 Remove(&ioreq
->io_Message
.mn_Node
);
900 ReplyMsg(&ioreq
->io_Message
);
908 /****************************************************************************************/