OpenCBM
libiec/util.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-2004 Spiro Trikaliotis
9  *
10  */
11 
20 #include <wdm.h>
21 #include "cbm_driver.h"
22 #include "i_iec.h"
23 
33 VOID
34 cbmiec_schedule_timeout(IN ULONG Howlong)
35 {
36  LARGE_INTEGER li;
37  NTSTATUS ntStatus;
38  KTIMER cbmTimer;
39 
40  FUNC_ENTER();
41 
42  // Note: The following timer is NEVER fired! We just use it
43  // to allow a KeWaitForSingleObject()-determined timeout!
44 
45  KeInitializeTimer (&cbmTimer);
46 
47  li.QuadPart = - (LONG) Howlong;
48  li.QuadPart *= 10i64;
49 
50  ntStatus = KeWaitForSingleObject(&cbmTimer, UserRequest,
51  KernelMode, FALSE, &li);
52 
53  FUNC_LEAVE();
54 }
55 
65 VOID
66 cbmiec_udelay(IN ULONG Howlong)
67 {
68  LARGE_INTEGER li;
69  NTSTATUS ntStatus;
70 
71  FUNC_ENTER();
72 
73 #if 1
74  KeStallExecutionProcessor(Howlong);
75 #else
76  li.QuadPart = - (LONG) Howlong;
77  li.QuadPart *= 10i64;
78 
79  ntStatus = KeDelayExecutionThread(KernelMode, FALSE, &li);
80 #endif
81 
82  FUNC_LEAVE();
83 }
84 
85 
93 VOID
94 cbmiec_block_irq(PDEVICE_EXTENSION Pdx)
95 {
96  KIRQL irql; // do not use Irql directly, but only indirectly,
97  // as suggested by Doron Holan at
98  // http://blogs.msdn.com/doronh/archive/2006/03/08/546934.aspx
99 
100  FUNC_ENTER();
101 
102  DBGDO(DBG_ASSERT(InterlockedIncrement(&Pdx->IecBlockIrqUsageCount)==1));
103 
104  KeRaiseIrql(HIGH_LEVEL, &irql);
105  Pdx->IecBlockIrqPreviousIrql = irql;
106 
107  CLI();
108 
109  FUNC_LEAVE();
110 }
111 
117 VOID
118 cbmiec_release_irq(PDEVICE_EXTENSION Pdx)
119 {
120  FUNC_ENTER();
121 
122  STI();
123 
124  KeLowerIrql(Pdx->IecBlockIrqPreviousIrql);
125 
126  DBGDO(DBG_ASSERT(InterlockedDecrement(&Pdx->IecBlockIrqUsageCount)==0));
127 
128  FUNC_LEAVE();
129 }
#define DBGDO(_xxx)
Definition: debug.h:409
VOID CLI(VOID)
Stop interrupts with CLI assembler command.
Definition: amd64/clisti.c:28
VOID cbmiec_release_irq(PDEVICE_EXTENSION Pdx)
Release the interrupts.
Definition: libiec/util.c:118
#define FUNC_LEAVE()
Definition: debug.h:349
VOID cbmiec_udelay(IN ULONG Howlong)
Wait for a timeout.
Definition: libiec/util.c:66
Internal functions and definitions of the libiec library.
#define DBG_ASSERT(_xxx)
Definition: debug.h:401
VOID cbmiec_schedule_timeout(IN ULONG Howlong)
Schedule a timeout.
Definition: libiec/util.c:34
VOID STI(VOID)
Restart interrupts with STI assembler command.
Definition: amd64/clisti.c:38
#define FUNC_ENTER()
Definition: debug.h:347
Definitions for the opencbm driver.
VOID cbmiec_block_irq(PDEVICE_EXTENSION Pdx)
Block all interrupts.
Definition: libiec/util.c:94