unixio.device, intended to replace duplicated code in UNIX-hosted parallel and serial...
[AROS.git] / arch / all-unix / devs / unixio / deviceutil.c
blobc1da8b3e2b74fa5813e8ab53c9e92ae15b66c646
1 static int unixio_Open(struct unixioDev *, struct IORequest *ioreq, IPTR unit, ULONG flags)
3 struct UnitData *data;
5 D(bug("unixio.device: Open unit %s\n",unit));
7 if (ioreq->io_Message.mn_Length < sizeof(struct IOStdReq))
9 D(bug("unixio.device/open: IORequest structure passed to OpenDevice is too small!\n"));
11 ioreq->io_Error = IOERR_OPENFAIL;
12 return FALSE;
15 ioreq->io_Message.mn_Node.ln_Type = NT_REPLYMSG;
18 * In the list of available units look for the one with the same
19 UnitNumber as the given one */
20 if (0 == ioreq->io_Error)
22 PU = findUnit(ParallelDevice, unitnum);
24 /* If there is no such unit, yet, then create it */
25 if (NULL == PU)
27 D(bug("Creating Unit %d\n",unitnum));
28 PU = AllocMem(sizeof(struct ParallelUnit), MEMF_CLEAR|MEMF_PUBLIC);
29 if (NULL != PU)
31 PU->pu_OpenerCount = 1;
32 PU->pu_UnitNum = unitnum;
33 PU->pu_Flags = ioreq->io_Flags;
36 ** Initialize the message ports
38 NEWLIST(&PU->pu_QReadCommandPort.mp_MsgList);
39 PU->pu_QReadCommandPort.mp_Node.ln_Type = NT_MSGPORT;
41 NEWLIST(&PU->pu_QWriteCommandPort.mp_MsgList);
42 PU->pu_QWriteCommandPort.mp_Node.ln_Type= NT_MSGPORT;
44 InitSemaphore(&PU->pu_Lock);
45 /* do further initilization here. Like getting the ParallelUnit Object etc. */
47 PU->pu_Unit = HIDD_Parallel_NewUnit(ParallelDevice->ParallelObject, unitnum);
48 if (NULL != PU->pu_Unit)
50 HIDD_ParallelUnit_Init(PU->pu_Unit, RBF_InterruptHandler, NULL, WBE_InterruptHandler, NULL);
51 ioreq->io_Device = (struct Device *)ParallelDevice;
52 ioreq->io_Unit = (struct Unit *)PU;
55 ** put it in the list of open units
57 AddHead(&ParallelDevice->UnitList, (struct Node *)PU);
59 ioreq->io_Error = 0;
61 return TRUE;
64 D(bug("ParallelUnit could not be created!\n"));
66 FreeMem(PU, sizeof(struct ParallelUnit));
68 ioreq->io_Error = ParErr_DevBusy;
71 else
73 /* the unit does already exist. */
74 /*
75 ** Check whether one more opener to this unit is tolerated
77 if (0 != (PU->pu_Flags & PARF_SHARED))
80 ** This unit is in shared mode and one more opener
81 ** won't hurt.
83 ioreq->io_Device = (struct Device *)ParallelDevice;
84 ioreq->io_Unit = (struct Unit *)PU;
85 ioreq->io_Error = 0;
87 PU->pu_OpenerCount++;
89 else
92 ** I don't allow another opener
94 ioreq->io_Error = ParErr_DevBusy;
99 return TRUE;
103 /****************************************************************************************/
105 static int GM_UNIQUENAME(Close)
107 LIBBASETYPEPTR ParallelDevice,
108 struct IORequest *ioreq
111 struct ParallelUnit * PU = (struct ParallelUnit *)ioreq->io_Unit;
114 ** Check whether I am the last opener to this unit
116 if (1 == PU->pu_OpenerCount)
119 ** I was the last opener. So let's get rid of it.
122 ** Remove the unit from the list
124 Remove((struct Node *)&PU->pu_Node);
126 HIDD_Parallel_DisposeUnit(ParallelDevice->ParallelObject, PU->pu_Unit);
128 FreeMem(PU, sizeof(struct ParallelUnit));
131 else
134 ** There are still openers. Decrease the counter.
136 PU->pu_OpenerCount--;
139 return TRUE;
142 /****************************************************************************************/