2 Copyright © 1995-2017, 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 memset( &SU
->su_QReadCommandPort
, 0, sizeof( SU
->su_QReadCommandPort
) );
162 NEWLIST(&SU
->su_QReadCommandPort
.mp_MsgList
);
163 SU
->su_QReadCommandPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
165 memset( &SU
->su_QWriteCommandPort
, 0, sizeof( SU
->su_QWriteCommandPort
) );
166 NEWLIST(&SU
->su_QWriteCommandPort
.mp_MsgList
);
167 SU
->su_QWriteCommandPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
169 InitSemaphore(&SU
->su_Lock
);
170 /* do further initilization here. Like getting the SerialUnit Object etc. */
172 SU
->su_Unit
= HIDD_Serial_NewUnit(SerialDevice
->SerialObject
, unitnum
);
173 if (NULL
!= SU
->su_Unit
)
175 HIDD_SerialUnit_Init(SU
->su_Unit
, RBF_InterruptHandler
, NULL
,
176 WBE_InterruptHandler
, NULL
);
177 ioreq
->io_Device
= (struct Device
*)SerialDevice
;
178 ioreq
->io_Unit
= (struct Unit
*)SU
;
181 ** put it in the list of open units
183 AddHead(&SerialDevice
->UnitList
, (struct Node
*)SU
);
189 D(bug("SerialUnit could not be created!\n"));
190 ioreq
->io_Error
= SerErr_DevBusy
;
192 FreeMem(SU
->su_InputBuffer
, MINBUFSIZE
);
195 FreeMem(SU
, sizeof(struct SerialUnit
));
197 ioreq
->io_Error
= SerErr_DevBusy
;
202 /* the unit does already exist. */
204 ** Check whether one more opener to this unit is tolerated
206 if (0 != (SU
->su_SerFlags
& SERF_SHARED
))
209 ** This unit is in shared mode and one more opener
212 ioreq
->io_Device
= (struct Device
*)SerialDevice
;
213 ioreq
->io_Unit
= (struct Unit
*)SU
;
216 SU
->su_OpenerCount
++;
217 D(bug("%s: Opened %d on unit %d\n", __func__
, SU
->su_OpenerCount
, unitnum
));
222 ** I don't allow another opener
224 D(bug("%s: Exclusive access is set for unit %d\n", __func__
, unitnum
));
225 ioreq
->io_Error
= SerErr_DevBusy
;
230 return ioreq
->io_Error
== 0;
233 /****************************************************************************************/
235 static int GM_UNIQUENAME(Close
)
237 LIBBASETYPEPTR SerialDevice
,
238 struct IORequest
*ioreq
241 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->io_Unit
;
244 ** Check whether I am the last opener to this unit
246 if (1 == SU
->su_OpenerCount
)
249 ** I was the last opener. So let's get rid of it.
252 ** Remove the unit from the list
254 Remove((struct Node
*)&SU
->su_Node
);
256 HIDD_Serial_DisposeUnit(SerialDevice
->SerialObject
, SU
->su_Unit
);
258 if (NULL
!= SU
->su_InputBuffer
&& 0 != SU
->su_InBufLength
)
260 FreeMem(SU
->su_InputBuffer
,
264 FreeMem(SU
, sizeof(struct SerialUnit
));
270 ** There are still openers. Decrease the counter.
272 SU
->su_OpenerCount
--;
278 /****************************************************************************************/
281 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR SerialDevice
)
283 if (NULL
!= SerialDevice
->SerialObject
)
286 ** Throw away the HIDD object and close the library
288 OOP_DisposeObject(SerialDevice
->SerialObject
);
289 CloseLibrary(SerialDevice
->oopBase
);
290 CloseLibrary(SerialDevice
->SerialHidd
);
291 SerialDevice
->SerialHidd
= NULL
;
292 SerialDevice
->oopBase
= NULL
;
293 SerialDevice
->SerialObject
= NULL
;
299 /****************************************************************************************/
301 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
302 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)
303 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
304 ADD2CLOSEDEV(GM_UNIQUENAME(Close
), 0)
306 /****************************************************************************************/
308 #define ioStd(x) ((struct IOStdReq *)x)
309 AROS_LH1(void, beginio
,
310 AROS_LHA(struct IOExtSer
*, ioreq
, A1
),
311 struct serialbase
*, SerialDevice
, 5, Serial
)
316 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->IOSer
.io_Unit
;
318 D(bug("serial device: beginio(ioreq=%p)\n", ioreq
));
320 /* WaitIO will look into this */
321 ioreq
->IOSer
.io_Message
.mn_Node
.ln_Type
=NT_MESSAGE
;
324 ** As a lot of "public" data can be modified in the following lines
325 ** I protect it from other tasks by this semaphore
327 ObtainSemaphore(&SU
->su_Lock
);
329 switch (ioreq
->IOSer
.io_Command
)
332 case NSCMD_DEVICEQUERY
:
333 if(ioreq
->IOSer
.io_Length
< ((IPTR
)OFFSET(NSDeviceQueryResult
, SupportedCommands
)) + sizeof(UWORD
*))
335 ioreq
->IOSer
.io_Error
= IOERR_BADLENGTH
;
339 struct NSDeviceQueryResult
*d
;
341 d
= (struct NSDeviceQueryResult
*)ioreq
->IOSer
.io_Data
;
343 d
->DevQueryFormat
= 0;
344 d
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
345 d
->DeviceType
= NSDEVTYPE_SERIAL
;
346 d
->DeviceSubType
= 0;
347 d
->SupportedCommands
= (UWORD
*)SupportedCommands
;
349 ioreq
->IOSer
.io_Actual
= sizeof(struct NSDeviceQueryResult
);
350 ioreq
->IOSer
.io_Error
= 0;
353 ** The request could be completed immediately.
354 ** Check if I have to reply the message
356 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
357 ReplyMsg(&ioreq
->IOSer
.io_Message
);
362 /*******************************************************************/
365 ** Let me see whether I can copy any data at all and
366 ** whether nobody else is using this device now
368 ioreq
->IOSer
.io_Actual
= 0;
372 if (SU
->su_InputFirst
!= SU
->su_InputNextPos
&&
373 0 == (SU
->su_Status
& STATUS_READS_PENDING
) )
375 D(bug("There are data in the receive buffer!\n"));
377 No matter how many bytes are in the input buffer,
378 I will copy them into the IORequest buffer immediately.
379 This way I can satisfy requests that are larger than
380 the input buffer, because the Interrupt will have
381 to put its bytes directly into the buffer of the
384 if (-1 == ioreq
->IOSer
.io_Length
)
386 if (TRUE
== copyInDataUntilZero(SU
, (struct IOStdReq
*)ioreq
))
389 ** it could be completed immediately.
390 ** Check if I have to reply the message.
392 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
393 ReplyMsg(&ioreq
->IOSer
.io_Message
);
401 D(bug("Calling copyInData!\n"));
402 if (TRUE
== copyInData(SU
, (struct IOStdReq
*)ioreq
))
405 ** it could be completed immediately.
406 ** Check if I have to reply the message.
408 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
409 ReplyMsg(&ioreq
->IOSer
.io_Message
);
416 if (NULL
!= SU
->su_ActiveRead
)
418 kprintf("READ: error in datastructure!");
424 D(bug("Setting STATUS_READS_PENDING\n"));
426 SU
->su_Status
|= STATUS_READS_PENDING
;
428 D(bug("The read request (%p) could not be satisfied! Queuing it.\n",ioreq
));
430 ** Everything that falls down here could not be completely
433 if (NULL
!= SU
->su_ActiveRead
) {
434 SU
->su_ActiveRead
= (struct Message
*)ioreq
;
436 PutMsg(&SU
->su_QReadCommandPort
,
437 (struct Message
*)ioreq
);
443 ** As I am returning immediately I will tell that this
444 ** could not be done QUICK
446 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
449 /*******************************************************************/
452 /* Write data to the SerialUnit */
453 ioreq
->IOSer
.io_Actual
= 0;
457 /* Check whether I can write some data immediately */
458 if (0 == (SU
->su_Status
& STATUS_WRITES_PENDING
))
461 BOOL complete
= FALSE
;
463 Writing the first few bytes to the UART has to have the
464 effect that whenever the UART can receive new data
465 a HW interrupt must happen. So this writing to the
466 UART should get the sequence of HW-interrupts going
467 until there is no more data to write
469 if (-1 == ioreq
->IOSer
.io_Length
)
471 int stringlen
= strlen(ioreq
->IOSer
.io_Data
);
472 D(bug("Transmitting NULL termninated string.\n"));
474 ** Supposed to write the buffer to the port until a '\0'
478 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
479 ioreq
->IOSer
.io_Data
,
481 if (writtenbytes
== stringlen
)
484 SU
->su_WriteLength
= stringlen
-writtenbytes
;
488 writtenbytes
= HIDD_SerialUnit_Write(SU
->su_Unit
,
489 ioreq
->IOSer
.io_Data
,
490 ioreq
->IOSer
.io_Length
);
491 if (writtenbytes
== ioreq
->IOSer
.io_Length
)
494 SU
->su_WriteLength
= ioreq
->IOSer
.io_Length
-writtenbytes
;
497 ** A consistency check between the STATUS_WRITES_PENDING flag
498 ** and the pointer SU->su_ActiveWrite which both have to be
499 ** set or cleared at the same time.
501 if (NULL
!= SU
->su_ActiveWrite
)
506 if (complete
== TRUE
)
508 D(bug("completely sended the stream!\n"));
510 ** The request could be completed immediately.
511 ** Check if I have to reply the message
513 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
514 ReplyMsg(&ioreq
->IOSer
.io_Message
);
519 ** The request could not be completed immediately
522 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
523 SU
->su_ActiveWrite
= (struct Message
*)ioreq
;
524 SU
->su_Status
|= STATUS_WRITES_PENDING
;
525 SU
->su_NextToWrite
= writtenbytes
;
531 I could not write the data immediately as another request
532 is already there. So I will make this
533 the responsibility of the interrupt handler to use this
534 request once it is done with the active request.
536 PutMsg(&SU
->su_QWriteCommandPort
,
537 (struct Message
*)ioreq
);
538 SU
->su_Status
|= STATUS_WRITES_PENDING
;
540 ** As I am returning immediately I will tell that this
541 ** could not be done QUICK
543 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
551 /* Simply reset the input buffer pointer no matter what */
553 SU
->su_InputNextPos
= 0;
554 SU
->su_InputFirst
= 0;
555 SU
->su_Status
&= ~STATUS_BUFFEROVERFLOW
;
556 ioreq
->IOSer
.io_Error
= 0;
559 ** The request could be completed immediately.
560 ** Check if I have to reply the message
562 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
563 ReplyMsg(&ioreq
->IOSer
.io_Message
);
566 /*******************************************************************/
570 /* All IORequests, including the active ones, are aborted */
571 /* Abort the active IORequests */
572 SU
->su_Status
&= ~(STATUS_READS_PENDING
|STATUS_WRITES_PENDING
);
574 if (NULL
!= SU
->su_ActiveRead
)
576 ((struct IOStdReq
*)SU
->su_ActiveRead
)->io_Error
= IOERR_ABORTED
;
577 ReplyMsg(SU
->su_ActiveRead
);
580 if (NULL
!= SU
->su_ActiveWrite
)
582 ((struct IOStdReq
*)SU
->su_ActiveWrite
)->io_Error
= IOERR_ABORTED
;
583 ReplyMsg(SU
->su_ActiveWrite
);
586 /* change the Buffer pointers to reset position */
587 SU
->su_InputFirst
= 0;
588 SU
->su_InputNextPos
= 0;
590 /* check the buffer for correct init size */
591 if (MINBUFSIZE
!= SU
->su_InBufLength
)
593 BYTE
* oldBuffer
= SU
->su_InputBuffer
;
594 BYTE
* newBuffer
= (BYTE
*)AllocMem(MINBUFSIZE
,MEMF_PUBLIC
);
595 if (NULL
!= newBuffer
)
597 SU
->su_InputBuffer
= newBuffer
;
598 FreeMem(oldBuffer
, SU
->su_InBufLength
);
599 /* write new buffersize */
600 SU
->su_InBufLength
= MINBUFSIZE
;
604 /* Buffer could not be allocated */
608 /* now fall through to CMD_FLUSH */
611 /*******************************************************************/
615 ** Clear all queued IO request for the given serial unit except
616 ** for the active ones.
622 struct IOStdReq
* iosreq
=
623 (struct IOStdReq
*)GetMsg(&SU
->su_QReadCommandPort
);
626 iosreq
->io_Error
= IOERR_ABORTED
;
627 ReplyMsg((struct Message
*)iosreq
);
632 struct IOStdReq
* iosreq
=
633 (struct IOStdReq
*)GetMsg(&SU
->su_QWriteCommandPort
);
636 iosreq
->io_Error
= IOERR_ABORTED
;
637 ReplyMsg((struct Message
*)iosreq
);
639 ioreq
->IOSer
.io_Error
= 0;
644 ** The request could be completed immediately.
645 ** Check if I have to reply the message
647 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
648 ReplyMsg(&ioreq
->IOSer
.io_Message
);
651 /*******************************************************************/
655 * Start the serial port IO. Tell the hidd to do that.
658 HIDD_SerialUnit_Start(SU
->su_Unit
);
660 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
661 ReplyMsg(&ioreq
->IOSer
.io_Message
);
662 ioreq
->IOSer
.io_Flags
|= IOF_QUICK
;
665 /*******************************************************************/
668 * Stop any serial port IO going on. Tell the hidd to do that.
671 HIDD_SerialUnit_Stop(SU
->su_Unit
);
673 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
674 ReplyMsg(&ioreq
->IOSer
.io_Message
);
675 ioreq
->IOSer
.io_Flags
|= IOF_QUICK
;
678 /*******************************************************************/
683 ** set the io_Status to the status of the serial port
685 ioreq
->io_Status
= HIDD_SerialUnit_GetStatus(SU
->su_Unit
);
686 if (0 != (SU
->su_Status
& STATUS_BUFFEROVERFLOW
))
688 ioreq
->io_Status
|= IO_STATF_OVERRUN
;
689 ioreq
->IOSer
.io_Actual
= 0;
693 /* pass back the number of unread input characters */
694 int unread
= SU
->su_InputNextPos
- SU
->su_InputFirst
;
696 ioreq
->IOSer
.io_Actual
= SU
->su_InBufLength
+ unread
;
698 ioreq
->IOSer
.io_Actual
= unread
;
701 ioreq
->IOSer
.io_Error
= 0;
704 ** The request could be completed immediately.
705 ** Check if I have to reply the message
707 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
708 ReplyMsg(&ioreq
->IOSer
.io_Message
);
712 /*******************************************************************/
714 case SDCMD_SETPARAMS
:
716 /* Change of buffer size for input buffer? */
719 if (ioreq
->io_RBufLen
>= MINBUFSIZE
&&
720 ioreq
->io_RBufLen
!= SU
->su_InBufLength
)
723 ** The other ones I will only do if I am not busy with
724 ** reading or writing data right now
726 if (0 == (SU
->su_Status
& (STATUS_READS_PENDING
|
727 STATUS_WRITES_PENDING
) ))
729 /* the user requests a different inputbuffer size.
731 int OldInBufLength
= SU
->su_InBufLength
;
732 BYTE
* OldInBuf
= SU
->su_InputBuffer
;
735 NewInBuf
= AllocMem(ioreq
->io_RBufLen
, MEMF_PUBLIC
);
736 if (NULL
!= NewInBuf
)
738 /* we got a new buffer */
739 /* just in case the interrupt wants to write data to
740 the input buffer, tell it that it cannot do this right
741 now as I am changing the buffer */
742 SU
->su_Status
|= STATUS_CHANGING_IN_BUFFER
;
743 SU
->su_InputNextPos
= 0;
744 SU
->su_InputFirst
= 0;
745 SU
->su_InputBuffer
= NewInBuf
;
746 SU
->su_InBufLength
= ioreq
->io_RBufLen
;
747 SU
->su_Status
&= ~STATUS_CHANGING_IN_BUFFER
;
749 /* free the old buffer */
750 FreeMem(OldInBuf
, OldInBufLength
);
754 ioreq
->IOSer
.io_Error
= SerErr_BufErr
;
757 /* end of buffer changing buiseness */
761 /* Changing the break time */
762 if (ioreq
->io_BrkTime
!= 0)
763 SU
->su_BrkTime
= ioreq
->io_BrkTime
;
765 /* Copy the Flags from the iorequest to the Unit's Flags */
766 SU
->su_SerFlags
= ioreq
->io_SerFlags
;
768 /* Change baudrate if necessary and possible */
769 if (SU
->su_Baud
!= ioreq
->io_Baud
)
771 /* Change the Baudrate */
772 D(bug("Setting baudrate on SerialUnit!\n"));
773 success
= HIDD_SerialUnit_SetBaudrate(SU
->su_Unit
,
776 if (FALSE
== success
)
778 D(bug("Setting baudrate didn't work!\n"));
779 /* this Baudrate is not supported */
780 ioreq
->IOSer
.io_Error
= SerErr_BaudMismatch
;
783 SU
->su_Baud
= ioreq
->io_Baud
;
784 } /* Baudrate changing */
786 /* Copy the TermArray */
787 SU
->su_TermArray
= ioreq
->io_TermArray
;
789 /* copy the readlen and writelen */
790 if (SU
->su_ReadLen
!= ioreq
->io_ReadLen
||
791 SU
->su_WriteLen
!= ioreq
->io_WriteLen
||
792 SU
->su_StopBits
!= ioreq
->io_StopBits
)
794 struct TagItem tags
[] =
795 {{TAG_DATALENGTH
, ioreq
->io_ReadLen
},
796 {TAG_STOP_BITS
, ioreq
->io_StopBits
},
797 {TAG_SKIP
, 0}, // !!! PARITY!!!
799 success
= HIDD_SerialUnit_SetParameters(SU
->su_Unit
,
801 if (FALSE
== success
) {
802 ioreq
->IOSer
.io_Error
= SerErr_InvParam
;
803 kprintf("HIDD_SerialUnit_SetParameters() failed.\n");
806 SU
->su_ReadLen
= ioreq
->io_ReadLen
;
807 SU
->su_WriteLen
= ioreq
->io_WriteLen
;
808 SU
->su_StopBits
= ioreq
->io_StopBits
;
811 SU
->su_CtlChar
= ioreq
->io_CtlChar
;
815 ** The request could be completed immediately.
816 ** Check if I have to reply the message
818 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
819 ReplyMsg(&ioreq
->IOSer
.io_Message
);
822 /*******************************************************************/
826 if (0 != (ioreq
->io_SerFlags
& SERF_QUEUEDBRK
))
828 /* might have to queue that request */
829 if (0 != (SU
->su_Status
& STATUS_WRITES_PENDING
))
831 kprintf("%s: Queuing SDCMD_BREAK! This probably doesn't work correctly!\n");
832 PutMsg(&SU
->su_QWriteCommandPort
,
833 (struct Message
*)ioreq
);
834 ioreq
->IOSer
.io_Flags
&= ~IOF_QUICK
;
838 /* Immediately execute this command */
839 ioreq
->IOSer
.io_Error
= HIDD_SerialUnit_SendBreak(SU
->su_Unit
,
843 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
844 ReplyMsg(&ioreq
->IOSer
.io_Message
);
848 /*******************************************************************/
851 /* unknown command */
852 ioreq
->IOSer
.io_Error
= IOERR_NOCMD
;
855 ** The request could be completed immediately.
856 ** Check if I have to reply the message
858 if (0 == (ioreq
->IOSer
.io_Flags
& IOF_QUICK
))
859 ReplyMsg(&ioreq
->IOSer
.io_Message
);
864 ReleaseSemaphore(&SU
->su_Lock
);
866 D(bug("id: Return from BeginIO()\n"));
871 /****************************************************************************************/
873 AROS_LH1(LONG
, abortio
,
874 AROS_LHA(struct IORequest
*, ioreq
, A1
),
875 struct serialbase
*, SerialDevice
, 6, Serial
)
879 struct SerialUnit
* SU
= (struct SerialUnit
*)ioreq
->io_Unit
;
882 ** is it the active request?
886 if ((struct Message
*)ioreq
== SU
->su_ActiveRead
)
889 ** It's the active reuquest. I make the next available
890 ** one the active request.
892 SU
->su_ActiveRead
= GetMsg(&SU
->su_QReadCommandPort
);
893 ReplyMsg(&ioreq
->io_Message
);
898 ** It's not the active request. So I'll take it out of the
899 ** list of queued messages and reply the message.
901 Remove(&ioreq
->io_Message
.mn_Node
);
902 ReplyMsg(&ioreq
->io_Message
);
910 /****************************************************************************************/