Updated PCI IDs to latest snapshot.
[tangerine.git] / workbench / devs / serial / serial_init.c
blob0178bd20da0b166001f7483791d3f2d2ef857c63
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 1
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++;
216 else
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,
257 SU->su_InBufLength);
260 FreeMem(SU, sizeof(struct SerialUnit));
263 else
266 ** There are still openers. Decrease the counter.
268 SU->su_OpenerCount--;
271 return TRUE;
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;
292 return TRUE;
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)
309 AROS_LIBFUNC_INIT
311 BOOL success;
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)
327 #if NEWSTYLE_DEVICE
328 case NSCMD_DEVICEQUERY:
329 if(ioreq->IOSer.io_Length < ((LONG)OFFSET(NSDeviceQueryResult, SupportedCommands)) + sizeof(UWORD *))
331 ioreq->IOSer.io_Error = IOERR_BADLENGTH;
333 else
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);
355 break;
356 #endif
358 /*******************************************************************/
359 case CMD_READ:
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;
366 Disable();
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
378 request from now on.
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);
391 Enable();
392 break;
395 else
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);
407 Enable();
408 break;
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
427 ** satisfied
429 if (NULL != SU->su_ActiveRead) {
430 SU->su_ActiveRead = (struct Message *)ioreq;
431 } else {
432 PutMsg(&SU->su_QReadCommandPort,
433 (struct Message *)ioreq);
436 Enable();
439 ** As I am returning immediately I will tell that this
440 ** could not be done QUICK
442 ioreq->IOSer.io_Flags &= ~IOF_QUICK;
443 break;
445 /*******************************************************************/
447 case CMD_WRITE:
448 /* Write data to the SerialUnit */
449 ioreq->IOSer.io_Actual = 0;
451 Disable();
453 /* Check whether I can write some data immediately */
454 if (0 == (SU->su_Status & STATUS_WRITES_PENDING))
456 ULONG writtenbytes;
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'
471 ** is encountered.
474 writtenbytes = HIDD_SerialUnit_Write(SU->su_Unit,
475 ioreq->IOSer.io_Data,
476 stringlen);
477 if (writtenbytes == stringlen)
478 complete = TRUE;
479 else
480 SU->su_WriteLength = stringlen-writtenbytes;
482 else
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)
488 complete = TRUE;
489 else
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)
499 D(bug("error!!"));
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);
512 else
515 ** The request could not be completed immediately
516 ** Clear the flag.
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;
524 else
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;
542 Enable();
544 break;
546 case CMD_CLEAR:
547 /* Simply reset the input buffer pointer no matter what */
548 Disable();
549 SU->su_InputNextPos = 0;
550 SU->su_InputFirst = 0;
551 SU->su_Status &= ~STATUS_BUFFEROVERFLOW;
552 ioreq->IOSer.io_Error = 0;
553 Enable();
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);
560 break;
562 /*******************************************************************/
564 case CMD_RESET:
565 Disable();
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;
598 else
600 /* Buffer could not be allocated */
603 Enable();
604 /* now fall through to CMD_FLUSH */
607 /*******************************************************************/
609 case CMD_FLUSH:
611 ** Clear all queued IO request for the given serial unit except
612 ** for the active ones.
614 Disable();
616 while (TRUE)
618 struct IOStdReq * iosreq =
619 (struct IOStdReq *)GetMsg(&SU->su_QReadCommandPort);
620 if (NULL == iosreq)
621 break;
622 iosreq->io_Error = IOERR_ABORTED;
623 ReplyMsg((struct Message *)iosreq);
626 while (TRUE)
628 struct IOStdReq * iosreq =
629 (struct IOStdReq *)GetMsg(&SU->su_QWriteCommandPort);
630 if (NULL == iosreq)
631 break;
632 iosreq->io_Error = IOERR_ABORTED;
633 ReplyMsg((struct Message *)iosreq);
635 ioreq->IOSer.io_Error = 0;
637 Enable();
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);
645 break;
647 /*******************************************************************/
649 case CMD_START:
651 * Start the serial port IO. Tell the hidd to do that.
653 Disable();
654 HIDD_SerialUnit_Start(SU->su_Unit);
655 Enable();
656 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
657 ReplyMsg(&ioreq->IOSer.io_Message);
658 ioreq->IOSer.io_Flags |= IOF_QUICK;
659 break;
661 /*******************************************************************/
662 case CMD_STOP:
664 * Stop any serial port IO going on. Tell the hidd to do that.
666 Disable();
667 HIDD_SerialUnit_Stop(SU->su_Unit);
668 Enable();
669 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
670 ReplyMsg(&ioreq->IOSer.io_Message);
671 ioreq->IOSer.io_Flags |= IOF_QUICK;
672 break;
674 /*******************************************************************/
676 case SDCMD_QUERY:
677 Disable();
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;
687 else
689 /* pass back the number of unread input characters */
690 int unread = SU->su_InputNextPos - SU->su_InputFirst;
691 if (unread < 0)
692 ioreq->IOSer.io_Actual = SU->su_InBufLength + unread;
693 else
694 ioreq->IOSer.io_Actual = unread;
697 ioreq->IOSer.io_Error = 0;
698 Enable();
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);
706 break;
708 /*******************************************************************/
710 case SDCMD_SETPARAMS:
712 /* Change of buffer size for input buffer? */
713 Disable();
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.
726 he shall have it. */
727 int OldInBufLength = SU->su_InBufLength;
728 BYTE * OldInBuf = SU->su_InputBuffer;
730 BYTE * NewInBuf;
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);
748 else
750 ioreq->IOSer.io_Error = SerErr_BufErr;
751 return;
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,
770 ioreq->io_Baud);
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;
777 return;
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!!!
794 {TAG_END , 0}};
795 success = HIDD_SerialUnit_SetParameters(SU->su_Unit,
796 tags);
797 if (FALSE == success) {
798 ioreq->IOSer.io_Error = SerErr_InvParam;
799 kprintf("HIDD_SerialUnit_SetParameters() failed.\n");
800 return;
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;
808 Enable();
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);
816 break;
818 /*******************************************************************/
820 case SDCMD_BREAK:
821 Disable();
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;
831 break;
834 /* Immediately execute this command */
835 ioreq->IOSer.io_Error = HIDD_SerialUnit_SendBreak(SU->su_Unit,
836 SU->su_BrkTime);
837 Enable();
839 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
840 ReplyMsg(&ioreq->IOSer.io_Message);
842 break;
844 /*******************************************************************/
846 default:
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);
858 } /* switch () */
860 ReleaseSemaphore(&SU->su_Lock);
862 D(bug("id: Return from BeginIO()\n"));
864 AROS_LIBFUNC_EXIT
867 /****************************************************************************************/
869 AROS_LH1(LONG, abortio,
870 AROS_LHA(struct IORequest *, ioreq, A1),
871 struct serialbase *, SerialDevice, 6, Serial)
873 AROS_LIBFUNC_INIT
875 struct SerialUnit * SU = (struct SerialUnit *)ioreq->io_Unit;
878 ** is it the active request?
881 Disable();
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);
891 else
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);
900 Enable();
902 return 0;
903 AROS_LIBFUNC_EXIT
906 /****************************************************************************************/