00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00023 #include <wdm.h>
00024 #include "cbm_driver.h"
00025 #include "i_iec.h"
00026
00045 NTSTATUS
00046 cbmiec_i_raw_read(IN PDEVICE_EXTENSION Pdx, OUT UCHAR *Buffer, ULONG Count, OUT ULONG *Received)
00047 {
00048 NTSTATUS ntStatus;
00049 BOOLEAN ok;
00050 ULONG received;
00051 ULONG bit;
00052 ULONG b;
00053 ULONG i;
00054 ULONG flags;
00055
00056 FUNC_ENTER();
00057
00058 DBG_ASSERT(Received != NULL);
00059
00060 ok = TRUE;
00061 received = 0;
00062 *Received = 0;
00063
00064
00065
00066 if (Pdx->Eoi)
00067 {
00068 FUNC_LEAVE_NTSTATUS_CONST(STATUS_END_OF_FILE);
00069 }
00070
00071
00072
00073 do
00074 {
00075 PERF_EVENT_READ_BYTE_NO(received);
00076
00077 i = 0;
00078 while (CBMIEC_GET(PP_CLK_IN))
00079 {
00080 if (Pdx->IsSMP)
00081 {
00082 cbmiec_udelay(libiec_global_timeouts.T_1_RECV_WAIT_CLK_LOW_DATA_READY_GRANU);
00083 }
00084 else
00085 {
00086 cbmiec_schedule_timeout(libiec_global_timeouts.T_1_RECV_WAIT_CLK_LOW_DATA_READY_GRANU);
00087 }
00088
00089 if (QueueShouldCancelCurrentIrp(&Pdx->IrpQueue))
00090 {
00091 *Received = received;
00092 FUNC_LEAVE_NTSTATUS_CONST(STATUS_TIMEOUT);
00093 }
00094 }
00095
00096
00097
00098 cbmiec_block_irq(Pdx);
00099
00100
00101
00102 CBMIEC_RELEASE(PP_DATA_OUT);
00103
00104
00105
00106 for(i = 0; (i < libiec_global_timeouts.T_2_Times) && !(ok=CBMIEC_GET(PP_CLK_IN)); i++)
00107 {
00108 cbmiec_udelay(libiec_global_timeouts.T_2_RECV_WAIT_CLK_HIGH_T_NE);
00109 }
00110
00111
00112
00113 if (!ok)
00114 {
00115 DBG_IEC((DBG_PREFIX "Got an EOI"));
00116
00117
00118
00119 Pdx->Eoi = TRUE;
00120
00121
00122
00123 CBMIEC_SET(PP_DATA_OUT);
00124 cbmiec_udelay(libiec_global_timeouts.T_3_RECV_EOI_RECOGNIZED);
00125 CBMIEC_RELEASE(PP_DATA_OUT);
00126 }
00127
00128
00129
00130
00131 for (i = 0; (i < libiec_global_timeouts.T_4_Times) && !(ok=CBMIEC_GET(PP_CLK_IN)); i++)
00132 {
00133 DBG_IEC((DBG_PREFIX "Wait after EOI"));
00134 cbmiec_udelay(libiec_global_timeouts.T_4_RECV_WAIT_CLK_HIGH_AFTER_EOI_GRANU);
00135 }
00136
00137 #if DBG
00138 if (!ok)
00139 {
00140 DBG_ERROR((DBG_PREFIX "NOT OK after Wait after EOI"));
00141 }
00142 #endif // #if DBG
00143
00144 for (bit = b = 0; (bit < 8) && ok; bit++)
00145 {
00146 PERF_EVENT_READ_BIT_NO(bit);
00147
00148
00149
00150
00151 for (i = 0; (i < libiec_global_timeouts.T_5_Times) && !(ok=(CBMIEC_GET(PP_CLK_IN)==0)); i++)
00152 {
00153 cbmiec_udelay(libiec_global_timeouts.T_5_RECV_BIT_WAIT_CLK_HIGH);
00154 }
00155
00156
00157
00158 if (ok)
00159 {
00160
00161
00162 b >>= 1;
00163
00164
00165
00166 if (CBMIEC_GET(PP_DATA_IN) == 0)
00167 {
00168
00169 b |= 0x80;
00170 }
00171
00172
00173
00174
00175 for (i = 0; i < libiec_global_timeouts.T_6_Times && !(ok=CBMIEC_GET(PP_CLK_IN)); i++)
00176 {
00177 cbmiec_udelay(libiec_global_timeouts.T_6_RECV_BIT_WAIT_CLK_LOW);
00178 }
00179
00180 #if DBG
00181 if (!ok)
00182 {
00183 DBG_ERROR((DBG_PREFIX "CLK WAS NOT DEACTIVATED AGAIN"));
00184 }
00185 #endif // #if DBG
00186 }
00187 else
00188 {
00189
00190 DBG_ERROR((DBG_PREFIX "BREAKING OUT OF BIT-LOOP, no CLK pulse received. Bit %u, Value = %u", (unsigned int) bit, (unsigned int) b));
00191 break;
00192 }
00193 }
00194
00195
00196
00197 if (ok)
00198 {
00199
00200 CBMIEC_SET(PP_DATA_OUT);
00201 }
00202 #if DBG
00203 else
00204 {
00205 DBG_ERROR((DBG_PREFIX "!OK -> no ACK"));
00206 }
00207 #endif // #if DBG
00208
00209
00210
00211 cbmiec_release_irq(Pdx);
00212
00213
00214
00215 if (ok)
00216 {
00217 PERF_EVENT_READ_BYTE(b);
00218
00219
00220
00221 received++;
00222
00223
00224
00225 *Buffer++ = (UCHAR) b;
00226
00227
00228
00229
00230
00231 if (Count % 256)
00232 {
00233 cbmiec_udelay(libiec_global_timeouts.T_7_RECV_INTER_BYTE_DELAY);
00234 }
00235 else
00236 {
00237 cbmiec_schedule_timeout(libiec_global_timeouts.T_7_RECV_INTER_BYTE_DELAY);
00238 }
00239 }
00240 } while(received < Count && ok && !Pdx->Eoi);
00241
00242
00243 if (ok)
00244 {
00245 DBG_SUCCESS((DBG_PREFIX "received=%d, count=%d, ok=%d, eoi=%d",
00246 received, Count, ok, Pdx->Eoi));
00247
00248 ntStatus = STATUS_SUCCESS;
00249 }
00250 else
00251 {
00252 DBG_ERROR((DBG_PREFIX "I/O error: received=%d, count=%d, ok=%d, eoi=%d",
00253 received, Count, ok, Pdx->Eoi));
00254
00255 Pdx->Eoi = 0;
00256 ntStatus = STATUS_UNEXPECTED_NETWORK_ERROR;
00257 }
00258
00259 DBG_ASSERT(Received != NULL);
00260 *Received = received;
00261
00262 FUNC_LEAVE_NTSTATUS(ntStatus);
00263 }