OpenCBM
libiec/init.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version
5  * 2 of the License, or (at your option) any later version.
6  *
7  * Copyright 1999-2004 Michael Klein <michael(dot)klein(at)puffin(dot)lb(dot)shuttle(dot)de>
8  * Copyright 2001-2007,2009 Spiro Trikaliotis
9  *
10  */
11 
22 #include <wdm.h>
23 #include "cbm_driver.h"
24 #include "i_iec.h"
25 
29 
31 #define READ_TIMEOUT_VALUE(_what_, _default_) \
32  do { \
33  libiec_global_timeouts._what_ = _default_; \
34  if (HKey) cbm_registry_read_ulong(*HKey, L#_what_, &libiec_global_timeouts._what_); \
35  } while (0)
36 
37 
46 static VOID
47 cbmiec_timeouts_init(IN PHANDLE HKey)
48 {
49  HANDLE hKey;
50 
51  // reset related
52 
53  READ_TIMEOUT_VALUE(T_holdreset, 100000); // 100 ms
54  READ_TIMEOUT_VALUE(T_afterreset, 2000000); // = 2 s
55 
56  // wait for listener related
57 
58  READ_TIMEOUT_VALUE(T_WaitForListener_Granu_T_H, 10); // us
59 
60  // receive related
61 
62  READ_TIMEOUT_VALUE(T_1_RECV_WAIT_CLK_LOW_DATA_READY_GRANU, 20); // us
63  READ_TIMEOUT_VALUE(T_2_Times, 80);
64  READ_TIMEOUT_VALUE(T_2_RECV_WAIT_CLK_HIGH_T_NE, 10); // us
65  READ_TIMEOUT_VALUE(T_3_RECV_EOI_RECOGNIZED, 70); // us
66  READ_TIMEOUT_VALUE(T_4_Times, 200);
67  READ_TIMEOUT_VALUE(T_4_RECV_WAIT_CLK_HIGH_AFTER_EOI_GRANU, 20); // us
68  READ_TIMEOUT_VALUE(T_5_Times, 5000); // 500 //! x T_5, \todo Was 200
69  READ_TIMEOUT_VALUE(T_5_RECV_BIT_WAIT_CLK_HIGH, 1); // 10 //! us \todo Was 10
70  READ_TIMEOUT_VALUE(T_6_Times, 100); // x T_6
71  READ_TIMEOUT_VALUE(T_6_RECV_BIT_WAIT_CLK_LOW, 20); // us
72  READ_TIMEOUT_VALUE(T_7_RECV_INTER_BYTE_DELAY, 70); // us
73 
74  // IEC_WAIT related
75 
76  READ_TIMEOUT_VALUE(T_8_IEC_WAIT_LONG_DELAY, 20); // us
77  READ_TIMEOUT_VALUE(T_8_IEC_WAIT_SHORT_DELAY, 10); // us
78 
79  // send related
80 
81  READ_TIMEOUT_VALUE(T_9_Times, 100); // x T_9
82  READ_TIMEOUT_VALUE(T_9_SEND_WAIT_DEVICES_T_AT, 10); // us
83  READ_TIMEOUT_VALUE(T_10_SEND_BEFORE_1ST_BYTE, 20); // us
84  READ_TIMEOUT_VALUE(T_11_SEND_BEFORE_BYTE_DELAY, 50); // us
85  READ_TIMEOUT_VALUE(T_12_SEND_AFTER_BYTE_DELAY, 100); // us
86  READ_TIMEOUT_VALUE(T_13_SEND_TURN_AROUND_LISTENER_TALKER_T_TK, 20); // us
87  READ_TIMEOUT_VALUE(T_14_SEND_AT_END_DELAY, 100); // us
88 
89  // sendbyte related:
90 
91  READ_TIMEOUT_VALUE(T_15_SEND_BEFORE_BIT_DELAY_T_S, 70); // us
92  READ_TIMEOUT_VALUE(T_16_SEND_BIT_TIME_T_V, 20); // us
93  READ_TIMEOUT_VALUE(T_17_Times, 20); // x T_17
94  READ_TIMEOUT_VALUE(T_17_SEND_FRAME_HANDSHAKE_T_F, 100); // us
95 
96  // parallel burst related
97 
98  READ_TIMEOUT_VALUE(T_PARALLEL_BURST_READ_BYTE_HANDSHAKED, 3300000); // us
99  READ_TIMEOUT_VALUE(T_PARALLEL_BURST_WRITE_BYTE_HANDSHAKED, 3300000); // us
100 }
101 #undef READ_TIMEOUT_VALUE
102 
103 
115 NTSTATUS
116 cbmiec_cleanup(IN PDEVICE_EXTENSION Pdx)
117 {
118  FUNC_ENTER();
119 
120  if (!Pdx->DoNotReleaseBus)
121  {
122  cbmiec_release_bus(Pdx);
123  }
124 
125  FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
126 }
127 
138 VOID
139 cbmiec_set_cabletype(IN PDEVICE_EXTENSION Pdx, IN IEC_CABLETYPE CableType)
140 {
141  NTSTATUS ntStatus;
142 
143  FUNC_ENTER();
144 
145  Pdx->IecCableUserSet = CableType;
147 
148  FUNC_LEAVE();
149 }
150 
151 /* */
152 static VOID
153 cbm_check_irq_availability(IN PDEVICE_EXTENSION Pdx)
154 {
155  FUNC_ENTER();
156 
157  DBG_CABLE((DBG_PREFIX "*"));
158 
159  //
160  // If we got an interrupt, test if it works
161  //
162 
163  if (Pdx->ParallelPortAllocatedInterrupt)
164  {
165  DBG_IRQ((DBG_PREFIX "* Allocated interrupt"));
166 
167  if (!NT_SUCCESS(cbmiec_test_irq(Pdx, NULL, 0)))
168  {
169  //
170  // Interrupt does not work, free it again.
171  //
172 
173  LogErrorOnly(Pdx->Fdo, CBM_IRQ_DOES_NOT_WORK);
174 
175 // DBG_IRQ((DBG_PREFIX "* Interrupt does not work, release it again"));
176 
177 // ParPortFreeInterrupt(Pdx);
178  }
179 
180  }
181 
182  FUNC_LEAVE();
183 }
184 
198 NTSTATUS
199 cbmiec_init(IN PDEVICE_EXTENSION Pdx)
200 {
201  NTSTATUS ntStatus;
202 
203  FUNC_ENTER();
204 
205  // Initialize the event which is used to wake up the
206  // task in wait_for_listener()
207 
208  DBG_IRQL( == PASSIVE_LEVEL);
209  KeInitializeEvent(&Pdx->EventWaitForListener, SynchronizationEvent, FALSE);
210 
211 #ifdef USE_DPC
212 
213  // Initialize the DPC object which will be used for waking
214  // up cbmiec_wait_for_listener() later
215 
216  DBG_IRQL( == PASSIVE_LEVEL)
217  IoInitializeDpcRequest(Pdx->Fdo, cbmiec_dpc);
218 
219 #endif // #ifdef USE_DPC
220 
221  ntStatus = cbmiec_checkcable(Pdx);
222 
223  if (!NT_SUCCESS(ntStatus)) {
224  FUNC_LEAVE_NTSTATUS(ntStatus);
225  }
226 
227  Pdx->IecBusy = FALSE;
228 
229  if (!Pdx->DoNotReleaseBus)
230  {
232  cbm_check_irq_availability(Pdx);
233  }
234 
235  FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
236 }
237 
250 NTSTATUS
251 cbmiec_global_init(IN PHANDLE HKey)
252 {
253  FUNC_ENTER();
254 
255  //Initialize the timeout values
256 
257  cbmiec_timeouts_init(HKey);
258 
259  FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
260 }
#define PP_ATN_OUT
The ATN OUT bit.
Definition: i_iec.h:39
#define PP_DATA_OUT
The DATA OUT bit.
Definition: i_iec.h:41
IEC_TIMEOUTS libiec_global_timeouts
Definition: libiec/init.c:28
enum iec_cabletype IEC_CABLETYPE
#define PP_RESET_OUT
The RESET OUT bit.
Definition: i_iec.h:42
#define FUNC_LEAVE()
Definition: debug.h:349
Internal functions and definitions of the libiec library.
#define PP_LP_BIDIR
Bit for setting set bidirectional mode of the LPT.
Definition: i_iec.h:46
NTSTATUS cbmiec_cleanup(IN PDEVICE_EXTENSION Pdx)
Cleanup the IEC bus.
Definition: libiec/init.c:116
VOID cbmiec_release_bus(IN PDEVICE_EXTENSION Pdx)
Release the IEC bus.
Definition: releasebus.c:38
#define PP_LP_IRQ
Bit for allowing interrupts of the LPT.
Definition: i_iec.h:45
#define READ_TIMEOUT_VALUE(_what_, _default_)
Definition: libiec/init.c:31
NTSTATUS cbmiec_global_init(IN PHANDLE HKey)
Initialization for libiec which are global in nature.
Definition: libiec/init.c:251
VOID cbmiec_setcablestate(PDEVICE_EXTENSION Pdx, CABLESTATE State)
Set the current state of the cable detection.
Definition: checkcable.c:494
NTSTATUS cbmiec_test_irq(IN PDEVICE_EXTENSION Pdx, OUT PVOID Buffer, IN ULONG BufferLength)
Test for IRQ capabilities.
Definition: testirq.c:41
VOID cbmiec_set_cabletype(IN PDEVICE_EXTENSION Pdx, IN IEC_CABLETYPE CableType)
Set the type of the IEC cable.
Definition: libiec/init.c:139
#define CBMIEC_RELEASE(_rel)
Definition: i_iec.h:66
#define PP_CLK_OUT
The CLOCK OUT bit.
Definition: i_iec.h:40
#define FUNC_ENTER()
Definition: debug.h:347
NTSTATUS cbmiec_checkcable(PDEVICE_EXTENSION Pdx)
Determine the type of cable (XA1541/XM1541) on the IEC bus.
Definition: checkcable.c:334
Definitions for the opencbm driver.
#define DBG_PREFIX
Definition: debug.h:320
#define LogErrorOnly(_Fdo_, _UniqueErrorValue_)
Definition: util.h:35
NTSTATUS cbmiec_init(IN PDEVICE_EXTENSION Pdx)
Initialize the IEC bus.
Definition: libiec/init.c:199