New bitmap method SetRGBConversionFunction which can be used to
[tangerine.git] / arch / all-unix / hidd / unixio / unixio_class.c
blob33eb62ce445c2b0c969335f87317ce8fce955783
1 /*
2 Copyright © 1995-2006, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Unix filedescriptor/socket IO
6 Lang: english
7 */
9 #include <exec/types.h>
10 #include <exec/lists.h>
11 #include <exec/interrupts.h>
12 #include <exec/execbase.h>
13 #include <exec/semaphores.h>
14 #include <exec/memory.h>
15 #include <exec/resident.h>
16 #include <exec/alerts.h>
17 #include <exec/tasks.h>
18 #include <exec/ports.h>
19 #include <exec/nodes.h>
20 #include <utility/tagitem.h>
21 #include <utility/hooks.h>
22 #include <hidd/unixio.h>
23 #include <aros/asmcall.h>
24 #include <aros/symbolsets.h>
25 #include <hardware/intbits.h>
26 #include <hardware/custom.h>
28 #include <oop/oop.h>
29 #include <proto/exec.h>
30 #include <proto/oop.h>
31 #include <proto/utility.h>
32 #include <proto/alib.h>
34 #include <devices/timer.h>
36 /* Unix includes */
37 #define timeval sys_timeval /* We don't want the unix timeval to interfere with the AROS one */
38 #include <sys/types.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <sys/stat.h>
42 #include <sys/time.h>
43 #include <sys/ioctl.h>
44 #include <string.h>
45 #include <errno.h>
46 #undef timeval
48 #include "unixio.h"
50 #include LC_LIBDEFS_FILE
52 #ifdef __AROS__
53 #include <aros/asmcall.h>
55 #define SDEBUG 0
56 #define DEBUG 0
57 #include <aros/debug.h>
58 #endif /* __AROS__ */
60 struct newMemList
62 struct Node nml_Node;
63 UWORD nml_NumEntries;
64 struct MemEntry nml_ME[2];
67 static const struct newMemList MemTemplate =
69 { 0, },
72 { { MEMF_CLEAR|MEMF_PUBLIC }, sizeof(struct Task) },
73 { { MEMF_CLEAR }, 0 }
78 /************************************************************************/
80 AROS_UFH5 (void, SigIO_IntServer,
81 AROS_UFHA (ULONG ,dummy, D0),
82 AROS_UFHA (struct Custom *,custom, A0),
83 AROS_UFHA (struct List *,intList,A1),
84 AROS_UFHA (APTR ,ivCode, A5),
85 AROS_UFHA (struct ExecBase *,SysBase,A6)
88 AROS_USERFUNC_INIT
90 struct uio_data * ud = (struct uio_data *) intList;
92 Signal (ud -> ud_WaitForIO, SIGBREAKF_CTRL_C);
94 AROS_USERFUNC_EXIT
98 #ifdef __linux__
99 static int unixio_start_timer(struct timerequest * timerio)
101 int rc = FALSE;
103 if (NULL != timerio) {
104 timerio->tr_node.io_Command = TR_ADDREQUEST;
105 timerio->tr_time.tv_secs = 0;
106 timerio->tr_time.tv_micro = 250000;
108 SendIO(&timerio->tr_node);
109 rc = TRUE;
111 return rc;
113 #endif
115 /******************
116 ** UnixIO task **
117 ******************/
118 static void WaitForIO (void)
120 struct uio_data * ud = FindTask(NULL)->tc_UserData;
121 int maxfd;
122 int selecterr;
123 int err;
124 fd_set rfds, wfds, efds;
125 fd_set * rp, * wp, * ep;
126 struct sys_timeval tv;
127 struct List waitList;
128 struct uioMessage * msg, * nextmsg;
129 ULONG rmask;
130 int flags;
131 pid_t my_pid = getpid();
132 #ifdef __linux__
133 int terminals_write_counter = 0;
134 struct MsgPort * timer_port = NULL;
135 struct timerequest * timerio = NULL;
136 #endif
138 * Since the signal was allocated by other task, but really is mine
139 * I need to allocate it here 'manually'. Otherwise the CreateMsgPort()
140 * would get the wrong signal.
142 AllocSignal(ud->ud_Port -> mp_SigBit);
144 #ifdef __linux__
145 timer_port = CreateMsgPort();
146 timerio = (struct timerequest *)CreateIORequest(timer_port, sizeof(struct timerequest));
147 OpenDevice("timer.device", UNIT_VBLANK, &timerio->tr_node, 0);
148 #endif
150 NEWLIST (&waitList);
152 D(bug("wfio: UnixIO.hidd ready ud=%08lx\n", ud));
154 for (;;)
156 if (IsListEmpty (&waitList))
158 D(bug("wfio: Waiting for message for task %s\n",ud->ud_WaitForIO->tc_Node.ln_Name));
159 WaitPort (ud->ud_Port);
160 D(bug("wfio: Got messages\n"));
162 else
164 #if 0
165 kprintf("FLAGS FOR FDS: ");
166 ForeachNode (&waitList, msg) {
167 int flags;
169 flags = fcntl (msg->fd, F_GETFL);
170 kprintf("fd %d: %d", msg->fd, flags);
171 if (flags & FASYNC)
172 kprintf(" ASYNC SET, ");
173 else
174 kprintf(" ASYNC NOT SET, ");
177 kprintf("\n");
178 #endif
180 D(bug("wfio: Waiting for message or signal for task %s\n",ud->ud_WaitForIO->tc_Node.ln_Name));
181 #ifdef __linux__
182 rmask =
183 Wait
185 (1UL << ud->ud_Port->mp_SigBit)
187 (1UL << timer_port->mp_SigBit)
189 SIGBREAKF_CTRL_C
192 if (rmask & 1 << timer_port -> mp_SigBit)
195 * Must take the message from the timer port.
196 * Will be sending it again.
198 GetMsg(timer_port);
200 if (terminals_write_counter > 0) {
201 //kprintf("RE STARTING TIMER! (%d)\n",terminals_write_counter);
202 unixio_start_timer(timerio);
203 } else {
204 //kprintf("NOT RE STARTING TIMER!\n");
207 else
208 #else
209 rmask = Wait((1UL << ud->ud_Port->mp_SigBit) | SIGBREAKF_CTRL_C);
210 #endif
212 if (rmask & 1 << ud->ud_Port -> mp_SigBit)
214 D(bug("wfio: Got message\n"));
216 else if (rmask & SIGBREAKF_CTRL_C)
218 D(bug("wfio: Got signal\n"));
222 while ((msg = (struct uioMessage *)GetMsg (ud->ud_Port)))
224 if (msg->mode != vHidd_UnixIO_Abort)
227 D(bug("wfio: Got msg fd=%ld mode=%ld\n", msg->fd, msg->mode));
228 AddTail (&waitList, (struct Node *)msg);
230 fcntl (msg->fd, F_SETOWN, my_pid);
231 flags = fcntl (msg->fd, F_GETFL);
232 fcntl (msg->fd, F_SETFL, flags | FASYNC | O_NONBLOCK);
233 #ifdef __linux__
234 if (msg->mode & vHidd_UnixIO_Write &&
235 msg->fd_type & vHidd_UnixIO_Terminal) {
236 terminals_write_counter++;
237 if (1 == terminals_write_counter) {
238 unixio_start_timer(timerio);
241 #endif
243 else
246 ** I must look for all messages that tell me to watch on this
247 ** filedescriptor.
249 struct uioMessage * umsg, *_umsg;
251 ForeachNodeSafe(&waitList, umsg, _umsg)
253 if (umsg->fd == msg->fd)
255 #ifdef __linux__
256 if (umsg->mode & vHidd_UnixIO_Write &&
257 umsg->fd_type & vHidd_UnixIO_Terminal) {
258 terminals_write_counter--;
259 #if 1
260 if (0 == terminals_write_counter) {
261 if (!CheckIO(&timerio->tr_node))
262 AbortIO(&timerio->tr_node);
263 WaitIO(&timerio->tr_node);
264 SetSignal(0, 1L << timer_port->mp_SigBit);
265 //kprintf("KIIIIILLLED!\n");
267 #endif
269 #endif
271 Remove((struct Node *)umsg);
272 FreeMem(umsg, sizeof(struct uioMessage));
275 ReplyMsg((struct Message *)msg);
277 } /* while (there are messages) */
279 FD_ZERO (&rfds);
280 FD_ZERO (&wfds);
281 FD_ZERO (&efds);
283 rp = wp = ep = NULL;
285 maxfd = 0;
287 D(bug("Waiting on fd "));
289 ForeachNode (&waitList, msg)
291 D(bug("%d, ", msg->fd));
292 if (msg->mode & vHidd_UnixIO_Read)
294 FD_SET (msg->fd, &rfds);
295 rp = &rfds;
298 if (msg->mode & vHidd_UnixIO_Write)
300 FD_SET (msg->fd, &wfds);
301 wp = &wfds;
304 FD_SET (msg->fd, &efds);
305 ep = &efds;
307 if (maxfd < msg->fd)
308 maxfd = msg->fd;
310 D(bug("\n"));
312 tv.tv_sec = 0;
313 tv.tv_usec = 0;
315 errno = 0; /* set errno to zero before select() call */
316 selecterr = select (maxfd+1, rp, wp, ep, &tv);
317 err = errno;
319 #if 1
320 D(bug("wfio: got io sel=%ld err=%ld\n", selecterr, err));
321 #endif
323 if (selecterr < 0 && err == EINTR)
324 continue;
326 if (selecterr >= 0)
328 ForeachNodeSafe (&waitList, msg, nextmsg)
330 if (FD_ISSET (msg->fd, &efds))
332 msg->result = err;
333 goto reply;
335 else if ((vHidd_UnixIO_Read & msg->mode) &&
336 FD_ISSET (msg->fd, &rfds))
338 if (msg->callback)
340 if ( ((int (*)(int, void *))msg->callback)(msg->fd, msg->callbackdata) )
342 msg->result = 0;
343 goto reply;
346 else
348 msg->result = 0;
349 goto reply;
352 else if ((vHidd_UnixIO_Write & msg->mode) &&
353 FD_ISSET (msg->fd, &wfds))
355 msg->result = 0;
356 reply:
357 D(bug("wfio: Reply: fd=%ld res=%ld replying to task %s on port %x\n", msg->fd, msg->result, ((struct Task *)((struct Message *)msg)->mn_ReplyPort->mp_SigTask)->tc_Node.ln_Name,((struct Message *)msg)->mn_ReplyPort));
359 kprintf("\tUnixIO task: Replying a message from task %s (%x) to port %x (flags : 0x%0x)\n",((struct Task *)((struct Message *)msg)->mn_ReplyPort->mp_SigTask)->tc_Node.ln_Name,((struct Message *)msg)->mn_ReplyPort->mp_SigTask,((struct Message *)msg)->mn_ReplyPort,((struct Message *)msg)->mn_ReplyPort->mp_Flags);
361 if (0 == (msg->mode & vHidd_UnixIO_Keep)) {
362 Remove ((struct Node *)msg);
363 flags = fcntl (msg->fd, F_GETFL);
364 fcntl (msg->fd, F_SETFL, flags & ~FASYNC);
365 ReplyMsg ((struct Message *)msg);
366 #ifdef __linux__
367 if ((msg->mode & vHidd_UnixIO_Write) &&
368 (msg->fd_type & vHidd_UnixIO_Terminal)) /* stegerg: CHECKME added vHidd_Unixio_terminal check */
370 terminals_write_counter--;
371 if (terminals_write_counter == 0) {
372 if (!CheckIO(&timerio->tr_node))
373 AbortIO(&timerio->tr_node);
374 WaitIO(&timerio->tr_node);
375 SetSignal(0, 1L << timer_port->mp_SigBit);
379 #endif
380 } else {
382 * Since I am supposed to keep the message
383 * I cannot use ReplyMsg() on it, because that
384 * would put it on the reply port's message port.
385 * So I am doing things 'manually' here what
386 * ReplyMsg() does internally, except for putting
387 * the message onto the message port.
389 struct MsgPort *port;
390 Disable();
391 port=((struct Message *)msg)->mn_ReplyPort;
392 if(port->mp_SigTask)
394 /* And trigger the arrival action. */
395 switch(port->mp_Flags&PF_ACTION)
397 case PA_SIGNAL:
398 /* Send a signal */
399 Signal((struct Task *)port->mp_SigTask,1<<port->mp_SigBit);
400 break;
402 case PA_SOFTINT:
403 /* Raise a software interrupt */
404 Cause((struct Interrupt *)port->mp_SoftInt);
405 break;
407 case PA_IGNORE:
408 /* Do nothing */
409 break;
412 Enable();
417 else
419 D(bug("wfio: Timeout sel=%ld err=%ld\n", selecterr, err));
421 } /* Forever */
424 /* This is the dispatcher for the UnixIO HIDD class. */
427 /********************
428 ** UnixIO::New() **
429 ********************/
430 OOP_Object *UXIO__Root__New(OOP_Class *cl, OOP_Object *o, struct pRoot_New *msg)
432 EnterFunc(bug("UnixIO::New(cl=%s)\n", cl->ClassNode.ln_Name));
433 D(bug("DoSuperMethod:%p\n", cl->DoSuperMethod));
434 o =(OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
436 if (o)
438 struct UnixIOData *id;
439 ULONG dispose_mid;
441 id = OOP_INST_DATA(cl, o);
442 D(bug("inst: %p, o: %p\n", id, o));
444 id->uio_ReplyPort = CreatePort (NULL, 0);
445 if (id->uio_ReplyPort)
448 kprintf("\tUnixIO::New(): Task %s (%x) Replyport: %x\n",FindTask(NULL)->tc_Node.ln_Name,FindTask(NULL),id->uio_ReplyPort);
450 D(bug("Port created at %x\n",id->uio_ReplyPort));
451 ReturnPtr("UnixIO::New", Object *, o);
455 dispose_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
456 OOP_CoerceMethod(cl, o, (OOP_Msg)&dispose_mid);
458 ReturnPtr("UnixIO::New", OOP_Object *, NULL);
461 /***********************
462 ** UnixIO::Dispose() **
463 ***********************/
464 IPTR UXIO__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
466 struct UnixIOData *id = OOP_INST_DATA(cl, o);
468 if (id -> uio_ReplyPort)
469 DeletePort (id->uio_ReplyPort);
471 return OOP_DoSuperMethod(cl, o, msg);
474 /*********************
475 ** UnixIO::Wait() **
476 *********************/
477 IPTR UXIO__Hidd_UnixIO__Wait(OOP_Class *cl, OOP_Object *o, struct uioMsg *msg)
479 IPTR retval = 0UL;
480 // struct UnixIOData *id = OOP_INST_DATA(cl, o);
481 struct uioMessage * umsg = AllocMem (sizeof (struct uioMessage), MEMF_CLEAR|MEMF_PUBLIC);
482 struct MsgPort * port = CreatePort(NULL, 0);
483 struct uio_data *ud = UD(cl);
485 if (umsg && port)
487 port->mp_Flags = PA_SIGNAL;
488 port->mp_SigTask = FindTask (NULL);
490 umsg->Message.mn_ReplyPort = port;
491 umsg->fd = ((struct uioMsg *)msg)->um_Filedesc;
492 umsg->fd_type = vHidd_UnixIO_Socket;
493 umsg->mode = ((struct uioMsg *)msg)->um_Mode;
494 umsg->callback = ((struct uioMsg *)msg)->um_CallBack;
495 umsg->callbackdata = ((struct uioMsg *)msg)->um_CallBackData;
497 D(bug("UnixIO::Wait() Sending msg fd=%ld mode=%ld to port %x\n", umsg->fd, umsg->mode, ud->ud_Port));
500 kprintf("\tUnixIO::Wait() Task %s (%x) waiting on port %x\n",FindTask(NULL)->tc_Node.ln_Name,FindTask(NULL),port);
502 PutMsg (ud->ud_Port, (struct Message *)umsg);
503 WaitPort (port);
504 GetMsg (port);
506 DeletePort(port);
508 D(bug("Get msg fd=%ld mode=%ld res=%ld\n", umsg->fd, umsg->mode, umsg->result));
509 retval = umsg->result;
511 else
512 retval = ENOMEM;
514 if (umsg)
515 FreeMem (umsg, sizeof (struct uioMessage));
517 return retval;
520 /************************
521 ** UnixIO::AsyncIO() **
522 ************************/
523 IPTR UXIO__Hidd_UnixIO__AsyncIO(OOP_Class *cl, OOP_Object *o, struct uioMsgAsyncIO *msg)
525 IPTR retval = 0UL;
526 struct uioMessage * umsg = AllocMem (sizeof (struct uioMessage), MEMF_CLEAR|MEMF_PUBLIC);
527 struct MsgPort * port = msg->um_ReplyPort;
528 struct uio_data *ud = UD(cl);
530 if (umsg)
532 /* nlorentz: What action should be taken on reply of this message
533 should be the choice of the caller. (The caller might want
534 a signal instead of a softint)
536 port->mp_Flags = PA_SOFTINT;
540 umsg->Message.mn_ReplyPort = port;
541 umsg->fd = ((struct uioMsg *)msg)->um_Filedesc;
542 umsg->fd_type = ((struct uioMsg *)msg)->um_Filedesc_Type;
543 umsg->mode = ((struct uioMsg *)msg)->um_Mode;
544 umsg->callback = NULL;
545 umsg->callbackdata = NULL;
547 D(bug("Sending msg fd=%ld mode=%ld to port %x\n", umsg->fd, umsg->mode, ud->ud_Port));
550 ** Just send the message and leave
551 ** When the message arrives on the port the user must free
552 ** the message!
554 PutMsg (ud->ud_Port, (struct Message *)umsg);
557 else
558 retval = ENOMEM;
560 return retval;
564 /*****************************
565 ** UnixIO::AbortAsyncIO() **
566 *****************************/
567 VOID UXIO__Hidd_UnixIO__AbortAsyncIO(OOP_Class *cl, OOP_Object *o, struct uioMsgAbortAsyncIO *msg)
569 struct uioMessage * umsg = AllocMem (sizeof (struct uioMessage), MEMF_CLEAR|MEMF_PUBLIC);
570 struct uio_data *ud = UD(cl);
571 struct MsgPort * port = CreatePort(NULL, 0);
573 if (umsg && port)
575 umsg->Message.mn_ReplyPort = port;
576 umsg->fd = ((struct uioMsg *)msg)->um_Filedesc;
577 umsg->mode = vHidd_UnixIO_Abort;
579 PutMsg (ud->ud_Port, (struct Message *)umsg);
581 WaitPort (port);
582 GetMsg (port);
586 if (umsg)
587 FreeMem (umsg, sizeof (struct uioMessage));
589 if (port)
590 DeletePort(port);
593 /*****************************
594 ** UnixIO::OpenFile() **
595 *****************************/
596 APTR UXIO__Hidd_UnixIO__OpenFile(OOP_Class *cl, OOP_Object *o, struct uioMsgOpenFile *msg)
598 APTR retval = (APTR)open((const char *)msg->um_FileName, (int)msg->um_Flags, (int)msg->um_Mode);
600 if (msg->um_ErrNoPtr) *msg->um_ErrNoPtr = errno;
602 return retval;
605 /*****************************
606 ** UnixIO::CloseFile() **
607 *****************************/
608 VOID UXIO__Hidd_UnixIO__CloseFile(OOP_Class *cl, OOP_Object *o, struct uioMsgCloseFile *msg)
610 if (msg->um_FD != (APTR)-1) close((int)msg->um_FD);
611 if (msg->um_ErrNoPtr) *msg->um_ErrNoPtr = errno;
614 /*****************************
615 ** UnixIO::ReadFile() **
616 *****************************/
617 IPTR UXIO__Hidd_UnixIO__ReadFile(OOP_Class *cl, OOP_Object *o, struct uioMsgReadFile *msg)
619 IPTR retval = (IPTR)-1;
621 if (msg->um_FD != (APTR)-1)
625 retval = (IPTR)read((int)msg->um_FD, (void *)msg->um_Buffer, (size_t)msg->um_Count);
626 //kprintf(" UXIO__Hidd_UnixIO__ReadFile[%04ld]: retval %d errno %d buff %x count %d\n", count++, retval, errno, msg->um_Buffer, msg->um_Count);
628 if (msg->um_ErrNoPtr) break;
630 } while(((int)errno == EINTR) || ((int)errno == EAGAIN));
633 if (msg->um_ErrNoPtr) *msg->um_ErrNoPtr = errno;
635 //if ((int)retval == -1) kprintf("UXIO__Hidd_UnixIO__ReadFile: errno %d buff %x count %d\n", errno, msg->um_Buffer, msg->um_Count);
637 return retval;
640 /*****************************
641 ** UnixIO::WriteFile() **
642 *****************************/
643 IPTR UXIO__Hidd_UnixIO__WriteFile(OOP_Class *cl, OOP_Object *o, struct uioMsgWriteFile *msg)
645 IPTR retval = (IPTR)-1;
647 if (msg->um_FD != (APTR)-1)
651 retval = (IPTR)write((int)msg->um_FD, (const void *)msg->um_Buffer, (size_t)msg->um_Count);
652 //kprintf(" UXIO__Hidd_UnixIO__WriteFile[%04ld]: retval %d errno %d buff %x count %d\n", count++, retval, errno, msg->um_Buffer, msg->um_Count);
654 if (msg->um_ErrNoPtr) break;
656 } while(((int)retval < 1) && (((int)errno == EINTR) || ((int)errno == EAGAIN) || (errno == 0)));
659 if (msg->um_ErrNoPtr) *msg->um_ErrNoPtr = errno;
661 //if ((int)retval == -1) kprintf("UXIO__Hidd_UnixIO__WriteFile: errno %d buff %x count %d\n", errno, msg->um_Buffer, msg->um_Count);
663 return retval;
666 /*****************************
667 ** UnixIO::IOControlFile() **
668 *****************************/
669 IPTR UXIO__Hidd_UnixIO__IOControlFile(OOP_Class *cl, OOP_Object *o, struct uioMsgIOControlFile *msg)
671 IPTR retval = (IPTR)-1;
673 if (msg->um_FD != (APTR)-1)
675 retval = (IPTR)ioctl((int)msg->um_FD, (int)msg->um_Request, msg->um_Param);
678 if (msg->um_ErrNoPtr) *msg->um_ErrNoPtr = errno;
680 return retval;
683 /* This is the initialisation code for the HIDD class itself. */
685 static int UXIO_Init(LIBBASETYPEPTR LIBBASE)
687 struct Task * newtask,
688 * task2 = NULL; /* keep compiler happy */
689 struct newMemList nml;
690 struct MemList * ml;
691 struct Interrupt * is;
693 LIBBASE->uio_csd.ud_Port = CreatePort (NULL, 0);
694 if(LIBBASE->uio_csd.ud_Port == NULL)
696 /* If you are not running from ROM, don't use Alert() */
697 Alert(AT_DeadEnd | AG_NoMemory | AN_Unknown);
698 return FALSE;
701 nml = MemTemplate;
704 The original stack size was 8192, however some emulated systems
705 require a large stack during signal handlers. FreeBSD in fact
706 says that it requires 8192 just FOR the signal handler. I have
707 changed this to AROS_STACKSIZE for that reason.
709 nml.nml_ME[1].me_Length = AROS_STACKSIZE;
711 if (NewAllocEntry((struct MemList *)&nml, &ml, NULL))
713 newtask = ml->ml_ME[0].me_Addr;
715 newtask->tc_Node.ln_Type = NT_TASK;
716 newtask->tc_Node.ln_Pri = 30;
717 newtask->tc_Node.ln_Name = "UnixIO.task";
719 newtask->tc_SPReg = (APTR)((ULONG)ml->ml_ME[1].me_Addr + AROS_STACKSIZE);
720 newtask->tc_SPLower = ml->ml_ME[1].me_Addr;
721 newtask->tc_SPUpper = newtask->tc_SPReg;
723 newtask->tc_UserData = &LIBBASE->uio_csd;
725 NEWLIST (&newtask->tc_MemEntry);
726 AddHead (&newtask->tc_MemEntry, (struct Node *)ml);
728 task2 = (struct Task *)AddTask (newtask, WaitForIO, 0);
730 if (SysBase->LibNode.lib_Version>36 && !task2)
732 FreeEntry (ml);
733 newtask = NULL;
736 else
737 newtask = NULL;
739 if (!newtask)
741 /* If you are not running from ROM, don't use Alert() */
742 Alert(AT_DeadEnd | AG_NoMemory | AN_Unknown);
743 return FALSE;
746 LIBBASE->uio_csd.ud_WaitForIO = task2;
748 LIBBASE->uio_csd.ud_Port->mp_Flags = PA_SIGNAL;
749 LIBBASE->uio_csd.ud_Port->mp_SigTask = task2;
751 is=(struct Interrupt *)AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC);
752 if (!is)
754 Alert(AT_DeadEnd | AG_NoMemory | AN_Unknown);
755 return FALSE;
757 is->is_Code=(void (*)())&SigIO_IntServer;
758 is->is_Data=(APTR)&LIBBASE->uio_csd;
759 SetIntVector(INTB_DSKBLK,is);
761 return TRUE;
764 ADD2INITLIB(UXIO_Init, 0)