Example #1
0
/*! \brief Write some bytes to the IEC bus

 \param Pdx
   Pointer to the device extension.

 \param Buffer
   Pointer to a buffer where the read bytes are written to.

 \param Size
   Maximum number of characters to read from the bus.

 \param Written
   Pointer to the variable which will hold the number of written bytes.

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it
   returns one of the error status values.

 ATN is released on return of this routine
*/
NTSTATUS
cbmiec_raw_write(IN PDEVICE_EXTENSION Pdx, 
                 IN const PUCHAR Buffer, IN ULONG Size, 
                 OUT ULONG *Written)
{
    NTSTATUS ntStatus;

#if DBG
    unsigned i;
#endif

    FUNC_ENTER();

    PERF_EVENT_VERBOSE(0x1000, 0);

    FUNC_PARAM((DBG_PREFIX "Buffer = 0x%p, Size = 0x%04x", Buffer, Size));

#if DBG
    for (i=0;i<Size;i++)
    {
        FUNC_PARAM((DBG_PREFIX "   output %2u: 0x%02x '%c'", i, (unsigned int) Buffer[i], (UCHAR) Buffer[i]));
    }
#endif

    PERF_EVENT_VERBOSE(0x1001, 0);

    ntStatus = cbmiec_i_raw_write(Pdx, Buffer, Size, Written, 0, 0);

    PERF_EVENT_VERBOSE(0x1002, 0);

    FUNC_LEAVE_NTSTATUS(ntStatus);
}
Example #2
0
/*! \brief Read some bytes from the IEC bus

 This function reads some bytes from the IEC bus. 
 If debugging of function parameters is defined, output the
 given parameters and the returned values.

 \param Pdx
   Pointer to the device extension.

 \param Buffer
   Pointer to a buffer where the read bytes are written to.

 \param Size
   Maximum number of characters to read from the bus.

 \param Read
   Pointer to the variable which will hold the read bytes.

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it
   returns one of the error status values.
*/
NTSTATUS cbmiec_raw_read(IN PDEVICE_EXTENSION Pdx, 
						 OUT PUCHAR Buffer, IN ULONG Size, 
						 OUT ULONG* Read)
{
    NTSTATUS ntStatus;

#if DBG
    USHORT i;
#endif

    FUNC_ENTER();

    FUNC_PARAM((DBG_PREFIX "Buffer = 0x%p, Size = 0x%04x", Buffer, Size));

    ntStatus = cbmiec_i_raw_read(Pdx, Buffer, Size, Read);

#if DBG
    for (i=0;i<*Read;i++)
    {
        FUNC_PARAM((DBG_PREFIX "   input %2u: 0x%02x '%c'", i, (unsigned int) Buffer[i], (UCHAR) Buffer[i]));
    }
#endif

    FUNC_LEAVE_NTSTATUS(ntStatus);
}
Example #3
0
/*! \brief Wait for a line to have a specific value

 This function waits until a listener is ready.

 \param Pdx
   Pointer to the device extension.

 \param Line
   Which line has to be monitored (one of IEC_DATA, IEC_CLOCK, IEC_ATN)

 \param State
   Type of wait
   \n =1: Wait until that line is set
   \n =0: Wait until that line is unset

 \param Result
   Pointer to a variable which will hold the value of the IEC bus
*/
NTSTATUS
cbmiec_iec_wait(IN PDEVICE_EXTENSION Pdx, IN UCHAR Line, IN UCHAR State, OUT PUCHAR Result)
{
    NTSTATUS ntStatus;
    UCHAR mask;
    ULONG i;

    FUNC_ENTER();

    FUNC_PARAM((DBG_PREFIX "line = 0x%02x, state = 0x%02x", Line, State));

    // Find the correct mask for the line which has to be tested

    switch (Line)
    {
        case IEC_LINE_DATA:
           mask = PP_DATA_IN;
           break;

        case IEC_LINE_CLOCK:
           mask = PP_CLK_IN;
           break;

        case IEC_LINE_ATN:
           mask = PP_ATN_IN;
           break;

        default:
           FUNC_LEAVE_NTSTATUS_CONST(STATUS_INVALID_PARAMETER);
    }

    // For which state do we have to wait: Set (= mask) or unset

    State = State ? mask : 0;

    i = 0;

    while ((READ_PORT_UCHAR(IN_PORT) & mask) == State)
    {
        if(i >= 20)
        {
            cbmiec_schedule_timeout(libiec_global_timeouts.T_8_IEC_WAIT_LONG_DELAY);

            if (QueueShouldCancelCurrentIrp(&Pdx->IrpQueue))
            {
                FUNC_LEAVE_NTSTATUS_CONST(STATUS_TIMEOUT);
            }
        }
        else
        {
            i++;
            cbmiec_udelay(libiec_global_timeouts.T_8_IEC_WAIT_SHORT_DELAY);
        }
    }

    ntStatus = cbmiec_iec_poll(Pdx, Result);
    FUNC_LEAVE_NTSTATUS(ntStatus);
}
Example #4
0
/*! \brief Activate and deactive a line on the IEC serial bus

 This function activates (sets to 0V, L) and deactivates 
 (set to 5V, H) lines on the IEC serial bus.

 \param Pdx
   Pointer to the device extension.

 \param Set
   The mask of which lines should be set. This has to be a bitwise OR
   between the constants IEC_DATA, IEC_CLOCK, IEC_ATN, and IEC_RESET

 \param Release
   The mask of which lines should be released. This has to be a bitwise
   OR between the constants IEC_DATA, IEC_CLOCK, IEC_ATN, and IEC_RESET

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it
   returns one of the error status values.

 \remark
   If a bit is specified in the Set as well as in the Release mask, the
   effect is undefined.
*/
NTSTATUS
cbmiec_iec_setrelease(IN PDEVICE_EXTENSION Pdx, IN USHORT Set, IN USHORT Release)
{
    NTSTATUS ntStatus;

    FUNC_ENTER();

    FUNC_PARAM((DBG_PREFIX "set = 0x%02x, release = 0x%02x", Set, Release));

    ntStatus = STATUS_SUCCESS;

    DBG_ASSERT((Set & Release) == 0);

    // Set the correct line as given by the call

    if ( (Set & ~(IEC_LINE_DATA | IEC_LINE_CLOCK | IEC_LINE_ATN | IEC_LINE_RESET))
        || (Release & ~(IEC_LINE_DATA | IEC_LINE_CLOCK | IEC_LINE_ATN | IEC_LINE_RESET)))
    {
        // there was some bit set that is not recognized, return
        // with an error
        ntStatus = STATUS_INVALID_PARAMETER;
    }
    else
    {
        ULONG set_mask = 0;
        ULONG release_mask = 0;

        SET_RELEASE_LINE(DATA,  DATA);
        SET_RELEASE_LINE(CLOCK, CLK);
        SET_RELEASE_LINE(ATN,   ATN);
        SET_RELEASE_LINE(RESET, RESET);

#ifdef TEST_BIDIR

        #define PP_BIDIR_OUT   PP_LP_BIDIR
        #define IEC_LINE_BIDIR PP_BIDIR_OUT

        SET_RELEASE_LINE(BIDIR, BIDIR);

        #undef PP_BIDIR_OUT
        #undef IEC_LINE_BIDIR

#endif // #ifdef TEST_BIDIR

        CBMIEC_SET_RELEASE(set_mask, release_mask);

    }

    FUNC_LEAVE_NTSTATUS(ntStatus );
}
Example #5
0
//
//  INIT_WORD_INDEX_Debug: C
//
void INIT_WORD_INDEX_Debug(RELVAL *v, REBCNT i)
{
    assert(ANY_WORD(v));
    assert(GET_VAL_FLAG((v), WORD_FLAG_BOUND));
    if (IS_RELATIVE(v))
        assert(
            VAL_WORD_CANON(v)
            == VAL_PARAM_CANON(FUNC_PARAM(VAL_WORD_FUNC(v), i))
        );
    else
        assert(
            VAL_WORD_CANON(v)
            == CTX_KEY_CANON(VAL_WORD_CONTEXT(KNOWN(v)), i)
        );
    v->payload.any_word.index = i;
}
Example #6
0
/*! \brief Send a TALK over the IEC bus

 This function sends a TALK to the IEC bus.

 \param Pdx
   Pointer to the device extension.

 \param Device
   Device (primary) address

 \param Secaddr
   Secondary address

 \return 
   If the routine succeeds, it returns STATUS_SUCCESS. Otherwise, it
   returns one of the error status values.
*/
NTSTATUS
cbmiec_talk(IN PDEVICE_EXTENSION Pdx, IN UCHAR Device, IN UCHAR Secaddr)
{
    NTSTATUS ntStatus;
    ULONG sent;
    UCHAR buffer[2];

    FUNC_ENTER();

    FUNC_PARAM((DBG_PREFIX "Device = 0x%02x, Secaddr = 0x%02x", (int)Device, (int)Secaddr));

    // send a 0x4x / 0x6y (talk device x, secaddr y) under control of ATN

    buffer[0] = 0x40 | Device;
    buffer[1] = 0x60 | Secaddr;
    ntStatus = cbmiec_i_raw_write(Pdx, buffer, 2, &sent, 1, 1);

    Pdx->DoNotReleaseBus = TRUE;

    FUNC_LEAVE_NTSTATUS(ntStatus);
}