Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / devs / serial / serial_init.c
blob6802ffee260edc1fc22979a88142d7d5127dce49
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Serial device
6 Lang: english
7 */
9 /****************************************************************************************/
12 #include <string.h>
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>
27 #include <oop/oop.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"
35 #endif
37 # define DEBUG 0
38 # include <aros/debug.h>
40 #include LC_LIBDEFS_FILE
42 /****************************************************************************************/
44 #define NEWSTYLE_DEVICE 1
46 struct serialbase * pubSerialBase;
48 /****************************************************************************************/
50 #if NEWSTYLE_DEVICE
52 static const UWORD SupportedCommands[] =
54 CMD_READ,
55 CMD_WRITE,
56 CMD_CLEAR,
57 CMD_RESET,
58 CMD_FLUSH,
59 SDCMD_QUERY,
60 SDCMD_SETPARAMS,
61 SDCMD_BREAK,
62 NSCMD_DEVICEQUERY,
66 #endif
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)
82 return FALSE;
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;
90 return 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;
101 return FALSE;
105 NEWLIST(&SerialDevice->UnitList);
106 return TRUE;
110 /****************************************************************************************/
112 static int GM_UNIQUENAME(Open)
114 LIBBASETYPEPTR SerialDevice,
115 struct IORequest *ioreq,
116 ULONG unitnum,
117 ULONG flags
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;
128 return FALSE;
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 */
142 if (NULL == SU)
144 D(bug("Creating Unit %d\n",unitnum));
145 SU = AllocMem(sizeof(struct SerialUnit), MEMF_CLEAR|MEMF_PUBLIC);
146 if (NULL != SU)
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);
183 ioreq->io_Error = 0;
184 return TRUE;
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;
198 else
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
208 ** won't hurt.
210 ioreq->io_Device = (struct Device *)SerialDevice;
211 ioreq->io_Unit = (struct Unit *)SU;
212 ioreq->io_Error = 0;
214 SU->su_OpenerCount++;
215 D(bug("%s: Opened %d on unit %d\n", __func__, SU->su_OpenerCount, unitnum));
217 else
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,
259 SU->su_InBufLength);
262 FreeMem(SU, sizeof(struct SerialUnit));
265 else
268 ** There are still openers. Decrease the counter.
270 SU->su_OpenerCount--;
273 return TRUE;
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;
294 return TRUE;
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)
311 AROS_LIBFUNC_INIT
313 BOOL success;
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)
329 #if NEWSTYLE_DEVICE
330 case NSCMD_DEVICEQUERY:
331 if(ioreq->IOSer.io_Length < ((IPTR)OFFSET(NSDeviceQueryResult, SupportedCommands)) + sizeof(UWORD *))
333 ioreq->IOSer.io_Error = IOERR_BADLENGTH;
335 else
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);
357 break;
358 #endif
360 /*******************************************************************/
361 case CMD_READ:
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;
368 Disable();
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
380 request from now on.
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);
393 Enable();
394 break;
397 else
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);
409 Enable();
410 break;
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
429 ** satisfied
431 if (NULL != SU->su_ActiveRead) {
432 SU->su_ActiveRead = (struct Message *)ioreq;
433 } else {
434 PutMsg(&SU->su_QReadCommandPort,
435 (struct Message *)ioreq);
438 Enable();
441 ** As I am returning immediately I will tell that this
442 ** could not be done QUICK
444 ioreq->IOSer.io_Flags &= ~IOF_QUICK;
445 break;
447 /*******************************************************************/
449 case CMD_WRITE:
450 /* Write data to the SerialUnit */
451 ioreq->IOSer.io_Actual = 0;
453 Disable();
455 /* Check whether I can write some data immediately */
456 if (0 == (SU->su_Status & STATUS_WRITES_PENDING))
458 ULONG writtenbytes;
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'
473 ** is encountered.
476 writtenbytes = HIDD_SerialUnit_Write(SU->su_Unit,
477 ioreq->IOSer.io_Data,
478 stringlen);
479 if (writtenbytes == stringlen)
480 complete = TRUE;
481 else
482 SU->su_WriteLength = stringlen-writtenbytes;
484 else
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)
490 complete = TRUE;
491 else
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)
501 D(bug("error!!"));
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);
514 else
517 ** The request could not be completed immediately
518 ** Clear the flag.
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;
526 else
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;
544 Enable();
546 break;
548 case CMD_CLEAR:
549 /* Simply reset the input buffer pointer no matter what */
550 Disable();
551 SU->su_InputNextPos = 0;
552 SU->su_InputFirst = 0;
553 SU->su_Status &= ~STATUS_BUFFEROVERFLOW;
554 ioreq->IOSer.io_Error = 0;
555 Enable();
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);
562 break;
564 /*******************************************************************/
566 case CMD_RESET:
567 Disable();
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;
600 else
602 /* Buffer could not be allocated */
605 Enable();
606 /* now fall through to CMD_FLUSH */
609 /*******************************************************************/
611 case CMD_FLUSH:
613 ** Clear all queued IO request for the given serial unit except
614 ** for the active ones.
616 Disable();
618 while (TRUE)
620 struct IOStdReq * iosreq =
621 (struct IOStdReq *)GetMsg(&SU->su_QReadCommandPort);
622 if (NULL == iosreq)
623 break;
624 iosreq->io_Error = IOERR_ABORTED;
625 ReplyMsg((struct Message *)iosreq);
628 while (TRUE)
630 struct IOStdReq * iosreq =
631 (struct IOStdReq *)GetMsg(&SU->su_QWriteCommandPort);
632 if (NULL == iosreq)
633 break;
634 iosreq->io_Error = IOERR_ABORTED;
635 ReplyMsg((struct Message *)iosreq);
637 ioreq->IOSer.io_Error = 0;
639 Enable();
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);
647 break;
649 /*******************************************************************/
651 case CMD_START:
653 * Start the serial port IO. Tell the hidd to do that.
655 Disable();
656 HIDD_SerialUnit_Start(SU->su_Unit);
657 Enable();
658 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
659 ReplyMsg(&ioreq->IOSer.io_Message);
660 ioreq->IOSer.io_Flags |= IOF_QUICK;
661 break;
663 /*******************************************************************/
664 case CMD_STOP:
666 * Stop any serial port IO going on. Tell the hidd to do that.
668 Disable();
669 HIDD_SerialUnit_Stop(SU->su_Unit);
670 Enable();
671 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
672 ReplyMsg(&ioreq->IOSer.io_Message);
673 ioreq->IOSer.io_Flags |= IOF_QUICK;
674 break;
676 /*******************************************************************/
678 case SDCMD_QUERY:
679 Disable();
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;
689 else
691 /* pass back the number of unread input characters */
692 int unread = SU->su_InputNextPos - SU->su_InputFirst;
693 if (unread < 0)
694 ioreq->IOSer.io_Actual = SU->su_InBufLength + unread;
695 else
696 ioreq->IOSer.io_Actual = unread;
699 ioreq->IOSer.io_Error = 0;
700 Enable();
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);
708 break;
710 /*******************************************************************/
712 case SDCMD_SETPARAMS:
714 /* Change of buffer size for input buffer? */
715 Disable();
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.
728 he shall have it. */
729 int OldInBufLength = SU->su_InBufLength;
730 BYTE * OldInBuf = SU->su_InputBuffer;
732 BYTE * NewInBuf;
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);
750 else
752 ioreq->IOSer.io_Error = SerErr_BufErr;
753 return;
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,
772 ioreq->io_Baud);
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;
779 return;
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!!!
796 {TAG_END , 0}};
797 success = HIDD_SerialUnit_SetParameters(SU->su_Unit,
798 tags);
799 if (FALSE == success) {
800 ioreq->IOSer.io_Error = SerErr_InvParam;
801 kprintf("HIDD_SerialUnit_SetParameters() failed.\n");
802 return;
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;
810 Enable();
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);
818 break;
820 /*******************************************************************/
822 case SDCMD_BREAK:
823 Disable();
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;
833 break;
836 /* Immediately execute this command */
837 ioreq->IOSer.io_Error = HIDD_SerialUnit_SendBreak(SU->su_Unit,
838 SU->su_BrkTime);
839 Enable();
841 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
842 ReplyMsg(&ioreq->IOSer.io_Message);
844 break;
846 /*******************************************************************/
848 default:
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);
860 } /* switch () */
862 ReleaseSemaphore(&SU->su_Lock);
864 D(bug("id: Return from BeginIO()\n"));
866 AROS_LIBFUNC_EXIT
869 /****************************************************************************************/
871 AROS_LH1(LONG, abortio,
872 AROS_LHA(struct IORequest *, ioreq, A1),
873 struct serialbase *, SerialDevice, 6, Serial)
875 AROS_LIBFUNC_INIT
877 struct SerialUnit * SU = (struct SerialUnit *)ioreq->io_Unit;
880 ** is it the active request?
883 Disable();
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);
893 else
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);
902 Enable();
904 return 0;
905 AROS_LIBFUNC_EXIT
908 /****************************************************************************************/