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

i_rawwrite.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 
00054 NTSTATUS
00055 cbmiec_i_raw_write(PDEVICE_EXTENSION Pdx, const UCHAR *Buffer, ULONG Count, ULONG *Sent, BOOLEAN Atn, BOOLEAN Talk)
00056 {
00057     NTSTATUS ntStatus;
00058     ULONG sent;
00059     UCHAR c;
00060     ULONG i;
00061     LONG ret;
00062 
00063     FUNC_ENTER();
00064 
00065     ntStatus = STATUS_SUCCESS;
00066     sent = 0;
00067 
00068     Pdx->Eoi = 0;
00069 
00070     PERF_EVENT_VERBOSE(0x1010, 0);
00071 
00072     ret = InterlockedExchange(&Pdx->IrqCount, 0);
00073     DBG_ASSERT(ret == 0);
00074 
00075     DBG_IEC((DBG_PREFIX "About to send %d bytes%s", Count, Atn ? " with ATN" : ""));
00076 
00077     PERF_EVENT_VERBOSE(0x1011, 0);
00078 
00079     if (Atn)
00080     {
00081         CBMIEC_SET(PP_ATN_OUT);
00082     }
00083 
00084     // Signal: We have something to send
00085 
00086     CBMIEC_SET(PP_CLK_OUT);
00087     CBMIEC_RELEASE(PP_DATA_OUT);
00088 
00089     // Wait for DATA to be set by the drive(s)
00090 
00091     PERF_EVENT_VERBOSE(0x1012, 0);
00092 
00093     for(i=0; (i<libiec_global_timeouts.T_9_Times) && !CBMIEC_GET(PP_DATA_IN); i++)
00094     {
00095         cbmiec_udelay(libiec_global_timeouts.T_9_SEND_WAIT_DEVICES_T_AT);
00096     }
00097 
00098     PERF_EVENT_VERBOSE(0x1013, 0);
00099 
00100     // cbmiec_show_state(Pdx,"!GET(PP_DATA_IN)");
00101 
00102     // If DATA was not set, there is no device present
00103 
00104     if(!CBMIEC_GET(PP_DATA_IN))
00105     {
00106         PERF_EVENT_VERBOSE(0x1014, 1);
00107         DBG_ERROR((DBG_PREFIX "no devices found!"));
00108         CBMIEC_RELEASE(PP_CLK_OUT | PP_ATN_OUT);
00109         ntStatus = STATUS_NO_SUCH_DEVICE;
00110     }
00111     else
00112     {
00113         PERF_EVENT_VERBOSE(0x1014, 0);
00114         if (Pdx->IsSMP)
00115         {
00116             cbmiec_udelay(libiec_global_timeouts.T_10_SEND_BEFORE_1ST_BYTE);
00117         }
00118         else
00119         {
00120             cbmiec_schedule_timeout(libiec_global_timeouts.T_10_SEND_BEFORE_1ST_BYTE);
00121         }
00122     }
00123 
00124     PERF_EVENT_VERBOSE(0x1015, 0);
00125 
00126     while(sent < Count && ntStatus == STATUS_SUCCESS)
00127     {
00128         c = *Buffer++;
00129 
00130         PERF_EVENT_WRITE_BYTE_NO(sent);
00131         PERF_EVENT_WRITE_BYTE(c);
00132 
00133         PERF_EVENT_VERBOSE(0x1016, sent);
00134 
00135         cbmiec_udelay(libiec_global_timeouts.T_11_SEND_BEFORE_BYTE_DELAY);
00136 
00137         PERF_EVENT_VERBOSE(0x1017, sent);
00138 
00139         if(CBMIEC_GET(PP_DATA_IN))
00140         {
00141             // Wait for the listener
00142             // We might have to signal an EOI. That is signaled
00143             // *before* the last byte has been sent.
00144             // Anyway, if we are sending with ATN asserted, then
00145             // no EOI signaling is allowed.
00146 
00147             PERF_EVENT_VERBOSE(0x1018, sent);
00148 
00149             cbmiec_wait_for_listener(Pdx, 
00150                 ((sent == (Count-1)) && (Atn == 0)) ? TRUE : FALSE);
00151 
00152             PERF_EVENT_VERBOSE(0x1019, sent);
00153 
00154             if(QueueShouldCancelCurrentIrp(&Pdx->IrpQueue))
00155             {
00156                 PERF_EVENT_VERBOSE(0x1020, 1);
00157 
00158                 ntStatus = STATUS_CANCELLED;
00159             }
00160             else
00161             {
00162                 PERF_EVENT_VERBOSE(0x1020, 0);
00163 
00164                 if(cbmiec_send_byte(Pdx,c))
00165                 {
00166                     sent++;
00167                     PERF_EVENT_VERBOSE(0x1021, 0);
00168                     cbmiec_udelay(libiec_global_timeouts.T_12_SEND_AFTER_BYTE_DELAY);
00169                     PERF_EVENT_VERBOSE(0x1022, 0);
00170                 }
00171                 else
00172                 {
00173                     PERF_EVENT_VERBOSE(0x1021, 1);
00174                     DBG_ERROR((DBG_PREFIX "I/O error on cbmiec_send_byte()"));
00175                     ntStatus = STATUS_NO_SUCH_DEVICE;
00176                     PERF_EVENT_VERBOSE(0x1022, 1);
00177                 }
00178             }
00179         }
00180         else
00181         {
00182             DBG_ERROR((DBG_PREFIX "device not present"));
00183             ntStatus = STATUS_NO_SUCH_DEVICE;
00184         }
00185     }
00186 
00187 #if DBG
00188     if (ntStatus == STATUS_SUCCESS)
00189     {
00190         DBG_SUCCESS((DBG_PREFIX "%d bytes sent", sent));
00191     }
00192     else
00193     {
00194         DBG_ERROR((DBG_PREFIX "%d bytes sent, Status=%s", sent, DebugNtStatus(ntStatus)));
00195     }
00196 #endif
00197 
00198     if (ntStatus == STATUS_SUCCESS && Talk)
00199     {
00200         // Talk-attention turn around (reverse Talker and Listener)
00201 
00202         PERF_EVENT_VERBOSE(0x1030, 0);
00203 
00204         cbmiec_block_irq(Pdx);
00205 
00206         PERF_EVENT_VERBOSE(0x1031, 0);
00207 
00208         CBMIEC_SET(PP_DATA_OUT);
00209         CBMIEC_RELEASE(PP_ATN_OUT);
00210 
00211         PERF_EVENT_VERBOSE(0x1032, 0);
00212 
00213         cbmiec_udelay(libiec_global_timeouts.T_13_SEND_TURN_AROUND_LISTENER_TALKER_T_TK);
00214 
00215         PERF_EVENT_VERBOSE(0x1033, 0);
00216 
00217         CBMIEC_RELEASE(PP_CLK_OUT);
00218 
00219         PERF_EVENT_VERBOSE(0x1034, 0);
00220 
00221         cbmiec_release_irq(Pdx);
00222 
00223         PERF_EVENT_VERBOSE(0x1035, 0);
00224     }
00225     else
00226     {
00227         CBMIEC_RELEASE(PP_ATN_OUT);
00228     }
00229     PERF_EVENT_VERBOSE(0x1036, 0);
00230     cbmiec_udelay(libiec_global_timeouts.T_14_SEND_AT_END_DELAY);
00231     PERF_EVENT_VERBOSE(0x1037, 0);
00232 
00233     DBG_ASSERT(Sent != NULL);
00234     *Sent = sent;
00235 
00236     FUNC_LEAVE_NTSTATUS(ntStatus);
00237 }

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