revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / serial / serial_init.c
blobba4bdcd83198168c9478677c57c24458fadbabe9
1 /*
2 Copyright © 1995-2017, 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 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);
185 ioreq->io_Error = 0;
186 return TRUE;
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;
200 else
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
210 ** won't hurt.
212 ioreq->io_Device = (struct Device *)SerialDevice;
213 ioreq->io_Unit = (struct Unit *)SU;
214 ioreq->io_Error = 0;
216 SU->su_OpenerCount++;
217 D(bug("%s: Opened %d on unit %d\n", __func__, SU->su_OpenerCount, unitnum));
219 else
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,
261 SU->su_InBufLength);
264 FreeMem(SU, sizeof(struct SerialUnit));
267 else
270 ** There are still openers. Decrease the counter.
272 SU->su_OpenerCount--;
275 return TRUE;
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;
296 return TRUE;
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)
313 AROS_LIBFUNC_INIT
315 BOOL success;
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)
331 #if NEWSTYLE_DEVICE
332 case NSCMD_DEVICEQUERY:
333 if(ioreq->IOSer.io_Length < ((IPTR)OFFSET(NSDeviceQueryResult, SupportedCommands)) + sizeof(UWORD *))
335 ioreq->IOSer.io_Error = IOERR_BADLENGTH;
337 else
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);
359 break;
360 #endif
362 /*******************************************************************/
363 case CMD_READ:
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;
370 Disable();
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
382 request from now on.
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);
395 Enable();
396 break;
399 else
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);
411 Enable();
412 break;
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
431 ** satisfied
433 if (NULL != SU->su_ActiveRead) {
434 SU->su_ActiveRead = (struct Message *)ioreq;
435 } else {
436 PutMsg(&SU->su_QReadCommandPort,
437 (struct Message *)ioreq);
440 Enable();
443 ** As I am returning immediately I will tell that this
444 ** could not be done QUICK
446 ioreq->IOSer.io_Flags &= ~IOF_QUICK;
447 break;
449 /*******************************************************************/
451 case CMD_WRITE:
452 /* Write data to the SerialUnit */
453 ioreq->IOSer.io_Actual = 0;
455 Disable();
457 /* Check whether I can write some data immediately */
458 if (0 == (SU->su_Status & STATUS_WRITES_PENDING))
460 ULONG writtenbytes;
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'
475 ** is encountered.
478 writtenbytes = HIDD_SerialUnit_Write(SU->su_Unit,
479 ioreq->IOSer.io_Data,
480 stringlen);
481 if (writtenbytes == stringlen)
482 complete = TRUE;
483 else
484 SU->su_WriteLength = stringlen-writtenbytes;
486 else
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)
492 complete = TRUE;
493 else
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)
503 D(bug("error!!"));
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);
516 else
519 ** The request could not be completed immediately
520 ** Clear the flag.
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;
528 else
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;
546 Enable();
548 break;
550 case CMD_CLEAR:
551 /* Simply reset the input buffer pointer no matter what */
552 Disable();
553 SU->su_InputNextPos = 0;
554 SU->su_InputFirst = 0;
555 SU->su_Status &= ~STATUS_BUFFEROVERFLOW;
556 ioreq->IOSer.io_Error = 0;
557 Enable();
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);
564 break;
566 /*******************************************************************/
568 case CMD_RESET:
569 Disable();
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;
602 else
604 /* Buffer could not be allocated */
607 Enable();
608 /* now fall through to CMD_FLUSH */
611 /*******************************************************************/
613 case CMD_FLUSH:
615 ** Clear all queued IO request for the given serial unit except
616 ** for the active ones.
618 Disable();
620 while (TRUE)
622 struct IOStdReq * iosreq =
623 (struct IOStdReq *)GetMsg(&SU->su_QReadCommandPort);
624 if (NULL == iosreq)
625 break;
626 iosreq->io_Error = IOERR_ABORTED;
627 ReplyMsg((struct Message *)iosreq);
630 while (TRUE)
632 struct IOStdReq * iosreq =
633 (struct IOStdReq *)GetMsg(&SU->su_QWriteCommandPort);
634 if (NULL == iosreq)
635 break;
636 iosreq->io_Error = IOERR_ABORTED;
637 ReplyMsg((struct Message *)iosreq);
639 ioreq->IOSer.io_Error = 0;
641 Enable();
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);
649 break;
651 /*******************************************************************/
653 case CMD_START:
655 * Start the serial port IO. Tell the hidd to do that.
657 Disable();
658 HIDD_SerialUnit_Start(SU->su_Unit);
659 Enable();
660 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
661 ReplyMsg(&ioreq->IOSer.io_Message);
662 ioreq->IOSer.io_Flags |= IOF_QUICK;
663 break;
665 /*******************************************************************/
666 case CMD_STOP:
668 * Stop any serial port IO going on. Tell the hidd to do that.
670 Disable();
671 HIDD_SerialUnit_Stop(SU->su_Unit);
672 Enable();
673 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
674 ReplyMsg(&ioreq->IOSer.io_Message);
675 ioreq->IOSer.io_Flags |= IOF_QUICK;
676 break;
678 /*******************************************************************/
680 case SDCMD_QUERY:
681 Disable();
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;
691 else
693 /* pass back the number of unread input characters */
694 int unread = SU->su_InputNextPos - SU->su_InputFirst;
695 if (unread < 0)
696 ioreq->IOSer.io_Actual = SU->su_InBufLength + unread;
697 else
698 ioreq->IOSer.io_Actual = unread;
701 ioreq->IOSer.io_Error = 0;
702 Enable();
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);
710 break;
712 /*******************************************************************/
714 case SDCMD_SETPARAMS:
716 /* Change of buffer size for input buffer? */
717 Disable();
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.
730 he shall have it. */
731 int OldInBufLength = SU->su_InBufLength;
732 BYTE * OldInBuf = SU->su_InputBuffer;
734 BYTE * NewInBuf;
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);
752 else
754 ioreq->IOSer.io_Error = SerErr_BufErr;
755 return;
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,
774 ioreq->io_Baud);
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;
781 return;
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!!!
798 {TAG_END , 0}};
799 success = HIDD_SerialUnit_SetParameters(SU->su_Unit,
800 tags);
801 if (FALSE == success) {
802 ioreq->IOSer.io_Error = SerErr_InvParam;
803 kprintf("HIDD_SerialUnit_SetParameters() failed.\n");
804 return;
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;
812 Enable();
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);
820 break;
822 /*******************************************************************/
824 case SDCMD_BREAK:
825 Disable();
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;
835 break;
838 /* Immediately execute this command */
839 ioreq->IOSer.io_Error = HIDD_SerialUnit_SendBreak(SU->su_Unit,
840 SU->su_BrkTime);
841 Enable();
843 if (0 == (ioreq->IOSer.io_Flags & IOF_QUICK))
844 ReplyMsg(&ioreq->IOSer.io_Message);
846 break;
848 /*******************************************************************/
850 default:
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);
862 } /* switch () */
864 ReleaseSemaphore(&SU->su_Lock);
866 D(bug("id: Return from BeginIO()\n"));
868 AROS_LIBFUNC_EXIT
871 /****************************************************************************************/
873 AROS_LH1(LONG, abortio,
874 AROS_LHA(struct IORequest *, ioreq, A1),
875 struct serialbase *, SerialDevice, 6, Serial)
877 AROS_LIBFUNC_INIT
879 struct SerialUnit * SU = (struct SerialUnit *)ioreq->io_Unit;
882 ** is it the active request?
885 Disable();
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);
895 else
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);
904 Enable();
906 return 0;
907 AROS_LIBFUNC_EXIT
910 /****************************************************************************************/