Main Page | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

libiec/init.c

Go to the documentation of this file.
00001 /*
00002  *  This program is free software; you can redistribute it and/or
00003  *  modify it under the terms of the GNU General Public License
00004  *  as published by the Free Software Foundation; either version
00005  *  2 of the License, or (at your option) any later version.
00006  *
00007  *  Copyright 1999-2004 Michael Klein <michael(dot)klein(at)puffin(dot)lb(dot)shuttle(dot)de>
00008  *  Copyright 2001-2004 Spiro Trikaliotis
00009  *
00010  */
00011 
00023 #include <wdm.h>
00024 #include "cbm_driver.h"
00025 #include "i_iec.h"
00026 
00029 IEC_TIMEOUTS libiec_global_timeouts;
00030 
00032 #define READ_TIMEOUT_VALUE(_what_, _default_) \
00033     do { \
00034         libiec_global_timeouts._what_ = _default_; \
00035         if (HKey) cbm_registry_read_ulong(*HKey, L#_what_, &libiec_global_timeouts._what_); \
00036     } while (0)
00037 
00038 
00047 static VOID
00048 cbmiec_timeouts_init(IN PHANDLE HKey)
00049 {
00050     HANDLE hKey;
00051 
00052     // reset related
00053 
00054     READ_TIMEOUT_VALUE(T_holdreset,                             100000); // 100 ms
00055     READ_TIMEOUT_VALUE(T_afterreset,                           2000000); // = 2 s
00056 
00057     // wait for listener related
00058 
00059     READ_TIMEOUT_VALUE(T_WaitForListener_Granu_T_H,                 10); // us
00060 
00061     // receive related
00062 
00063     READ_TIMEOUT_VALUE(T_1_RECV_WAIT_CLK_LOW_DATA_READY_GRANU,      20); // us
00064     READ_TIMEOUT_VALUE(T_2_Times,                                   80); 
00065     READ_TIMEOUT_VALUE(T_2_RECV_WAIT_CLK_HIGH_T_NE,                 10); // us
00066     READ_TIMEOUT_VALUE(T_3_RECV_EOI_RECOGNIZED,                     70); // us
00067     READ_TIMEOUT_VALUE(T_4_Times,                                  200); 
00068     READ_TIMEOUT_VALUE(T_4_RECV_WAIT_CLK_HIGH_AFTER_EOI_GRANU,      20); // us
00069     READ_TIMEOUT_VALUE(T_5_Times,                                 5000); // 500 //! x T_5, \todo Was 200
00070     READ_TIMEOUT_VALUE(T_5_RECV_BIT_WAIT_CLK_HIGH,                   1); // 10  //! us  \todo Was 10
00071     READ_TIMEOUT_VALUE(T_6_Times,                                  100); // x T_6
00072     READ_TIMEOUT_VALUE(T_6_RECV_BIT_WAIT_CLK_LOW,                   20); // us
00073     READ_TIMEOUT_VALUE(T_7_RECV_INTER_BYTE_DELAY,                   70); // us
00074 
00075     // IEC_WAIT related
00076 
00077     READ_TIMEOUT_VALUE(T_8_IEC_WAIT_LONG_DELAY,                     20); // us
00078     READ_TIMEOUT_VALUE(T_8_IEC_WAIT_SHORT_DELAY,                    10); // us
00079 
00080     // send related 
00081 
00082     READ_TIMEOUT_VALUE(T_9_Times,                                  100); // x T_9
00083     READ_TIMEOUT_VALUE(T_9_SEND_WAIT_DEVICES_T_AT,                  10); // us
00084     READ_TIMEOUT_VALUE(T_10_SEND_BEFORE_1ST_BYTE,                   20); // us
00085     READ_TIMEOUT_VALUE(T_11_SEND_BEFORE_BYTE_DELAY,                 50); // us
00086     READ_TIMEOUT_VALUE(T_12_SEND_AFTER_BYTE_DELAY,                 100); // us
00087     READ_TIMEOUT_VALUE(T_13_SEND_TURN_AROUND_LISTENER_TALKER_T_TK,  20); // us
00088     READ_TIMEOUT_VALUE(T_14_SEND_AT_END_DELAY,                     100); // us
00089 
00090     // sendbyte related:
00091 
00092     READ_TIMEOUT_VALUE(T_15_SEND_BEFORE_BIT_DELAY_T_S,              70); // us
00093     READ_TIMEOUT_VALUE(T_16_SEND_BIT_TIME_T_V,                      20); // us
00094     READ_TIMEOUT_VALUE(T_17_Times,                                  20); // x T_17
00095     READ_TIMEOUT_VALUE(T_17_SEND_FRAME_HANDSHAKE_T_F,              100); // us
00096 
00097     // parallel burst related
00098 
00099     READ_TIMEOUT_VALUE(T_PARALLEL_BURST_READ_BYTE_HANDSHAKED,   300000); // us
00100     READ_TIMEOUT_VALUE(T_PARALLEL_BURST_WRITE_BYTE_HANDSHAKED,  300000); // us
00101 }
00102 #undef READ_TIMEOUT_VALUE
00103 
00121 static NTSTATUS
00122 cbmiec_testcable(PDEVICE_EXTENSION Pdx) 
00123 {
00124     const wchar_t *msgAuto = L"";
00125     const wchar_t *msgCable;
00126     UCHAR in, out;
00127 
00128     FUNC_ENTER();
00129 
00132     switch (Pdx->IecCable)
00133     {
00134     case IEC_CABLETYPE_XM:
00135         /* FALL THROUGH */
00136 
00137     case IEC_CABLETYPE_XA:
00138         break;
00139 
00140     default:
00141         in = CBMIEC_GET(PP_ATN_IN);
00142         out = (READ_PORT_UCHAR(OUT_PORT) & PP_ATN_OUT) ? 1 : 0;
00143         Pdx->IecCable = (in != out) ? IEC_CABLETYPE_XA : IEC_CABLETYPE_XM;
00144         msgAuto = L" (auto)";
00145         break;
00146     }
00147 
00148     switch (Pdx->IecCable)
00149     {
00150     case IEC_CABLETYPE_XM:
00151         msgCable = L"passive (XM1541)";
00152         break;
00153 
00154     case IEC_CABLETYPE_XA:
00155         msgCable = L"active (XA1541)";
00156         break;
00157     }
00158 
00159     Pdx->IecOutEor = Pdx->IecCable ? 0xcb : 0xc4;
00160 
00161     DBG_SUCCESS((DBG_PREFIX "using %ws cable%ws",
00162         Pdx->IecCable ? L"active (XA1541)" : L"passive (XM1541)",
00163         msgAuto));
00164 
00165     LogErrorString(Pdx->Fdo, CBM_IEC_INIT, msgCable, msgAuto);
00166 
00167     Pdx->IecOutBits = (READ_PORT_UCHAR(OUT_PORT) ^ Pdx->IecOutEor) 
00168                       & (PP_DATA_OUT|PP_CLK_OUT|PP_ATN_OUT|PP_RESET_OUT);
00169 
00170 /*
00171     if (Pdx->IecOutBits & PP_RESET_OUT)
00172     {
00173        cbmiec_reset(Pdx);
00174     }
00175 */
00176 
00177     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00178 }
00179 
00180 
00192 NTSTATUS
00193 cbmiec_cleanup(IN PDEVICE_EXTENSION Pdx)
00194 {
00195     FUNC_ENTER();
00196 
00197     if (!Pdx->DoNotReleaseBus)
00198     {
00199         cbmiec_release_bus(Pdx);
00200     }
00201 
00202     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00203 }
00204 
00215 NTSTATUS
00216 cbmiec_set_cabletype(IN PDEVICE_EXTENSION Pdx, IN IEC_CABLETYPE CableType)
00217 {
00218     FUNC_ENTER();
00219 
00220     Pdx->IecCable = CableType;
00221 
00222     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00223 }
00224 
00238 NTSTATUS
00239 cbmiec_init(IN PDEVICE_EXTENSION Pdx)
00240 {
00241     NTSTATUS ntStatus;
00242 
00243     FUNC_ENTER();
00244 
00245     // Initialize the event which is used to wake up the
00246     // task in wait_for_listener()
00247 
00248     DBG_IRQL( == PASSIVE_LEVEL);
00249     KeInitializeEvent(&Pdx->EventWaitForListener, SynchronizationEvent, FALSE);
00250 
00251 #ifdef USE_DPC
00252 
00253     // Initialize the DPC object which will be used for waking
00254     // up cbmiec_wait_for_listener() later
00255 
00256     DBG_IRQL( == PASSIVE_LEVEL)
00257     IoInitializeDpcRequest(Pdx->Fdo, cbmiec_dpc);
00258 
00259 #endif // #ifdef USE_DPC
00260 
00261     ntStatus = cbmiec_testcable(Pdx);
00262 
00263     if (!NT_SUCCESS(ntStatus)) {
00264         FUNC_LEAVE_NTSTATUS(ntStatus);
00265     }
00266 
00267     Pdx->IecBusy = FALSE;
00268 
00269     if (!Pdx->DoNotReleaseBus)
00270     {
00271         CBMIEC_RELEASE(PP_RESET_OUT | PP_DATA_OUT | PP_ATN_OUT | PP_LP_BIDIR | PP_LP_IRQ);
00272         CBMIEC_SET(PP_CLK_OUT);
00273     }
00274 
00275     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00276 }
00277 
00290 NTSTATUS
00291 cbmiec_global_init(IN PHANDLE HKey)
00292 {
00293     FUNC_ENTER();
00294 
00295     //Initialize the timeout values
00296 
00297     cbmiec_timeouts_init(HKey);
00298 
00299     FUNC_LEAVE_NTSTATUS_CONST(STATUS_SUCCESS);
00300 }

Generated on Sun Apr 30 18:45:52 2006 for opencbm by  doxygen 1.4.2