36e58fe7b0821e333239506e0c3e547585aca21d
[reactos.git] / reactos / drivers / parallel / parallel / parallel.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: services/parallel/parallel.c
5 * PURPOSE: Parallel port driver
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * ??/??/??: Created
9 * 18/06/98: Made more NT like
10 */
11
12 /* FUNCTIONS **************************************************************/
13
14 #include <wdm.h>
15
16 #include "parallel.h"
17
18 #define NDEBUG
19 #include <debug.h>
20
21
22 #define LP_B (0x378)
23 #define LP_S (READ_PORT_UCHAR((PUCHAR)(LP_B+1)))
24 #define LP_C (LP_B+2)
25
26 NTSTATUS NTAPI
27 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
28
29 static void Parallel_Reset(void)
30 /*
31 * FUNCTION: Resets the device attached to the parallel port
32 */
33 {
34 int i;
35
36 WRITE_PORT_UCHAR((PUCHAR)LP_C,0);
37 for (i=0;i<LP_DELAY;i++);
38 WRITE_PORT_UCHAR((PUCHAR)LP_C,LP_PSELECP | LP_PINITP);
39 }
40
41 static void Parallel_putchar(unsigned char ch)
42 /*
43 * FUNCTION: Writes a character to the parallel port
44 * ARGUMENTS:
45 * ch = character to write
46 */
47 {
48
49 int count=0;
50 int status;
51 int wait=0;
52
53 do
54 {
55 status=LP_S;
56 count++;
57 }
58 while ( count < 500000 && !(status & LP_PBUSY) );
59
60 if (count==500000)
61 {
62 DPRINT("printer_putchar(): timed out\n");
63 return;
64 }
65
66 WRITE_PORT_UCHAR((PUCHAR)LP_B,ch);
67 while (wait != 10000) { wait++; }
68 WRITE_PORT_UCHAR((PUCHAR)LP_C, (LP_PSELECP | LP_PINITP | LP_PSTROBE ));
69 while (wait) { wait--; }
70 WRITE_PORT_UCHAR((PUCHAR)LP_C, LP_PSELECP | LP_PINITP);
71 }
72
73 static DRIVER_DISPATCH Dispatch;
74 static NTSTATUS NTAPI
75 Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
76 /*
77 * FUNCTION: Handles user mode requests
78 * ARGUMENTS:
79 * DeviceObject = Device for request
80 * Irp = I/O request packet describing request
81 * RETURNS: Success or failure
82 */
83 {
84 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
85 NTSTATUS status;
86 ULONG i;
87
88 switch (Stack->MajorFunction)
89 {
90 case IRP_MJ_CREATE:
91 DPRINT("(Parallel Port Driver) Creating\n");
92 Parallel_Reset();
93 status = STATUS_SUCCESS;
94 break;
95
96 case IRP_MJ_CLOSE:
97 status = STATUS_SUCCESS;
98 break;
99
100 case IRP_MJ_WRITE:
101 DPRINT("(Parallel Port Driver) Writing %d bytes\n",
102 Stack->Parameters.Write.Length);
103 for (i=0;i<Stack->Parameters.Write.Length;i++)
104 {
105 Parallel_putchar(((char *)Irp->UserBuffer)[i]);
106 }
107 status = STATUS_SUCCESS;
108 break;
109
110 default:
111 status = STATUS_NOT_IMPLEMENTED;
112 break;
113 }
114
115 Irp->IoStatus.Status = status;
116 Irp->IoStatus.Information = 0;
117
118 IoCompleteRequest(Irp, IO_NO_INCREMENT);
119 return(status);
120 }
121
122 NTSTATUS NTAPI
123 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
124 /*
125 * FUNCTION: Called by the system to initalize the driver
126 * ARGUMENTS:
127 * DriverObject = object describing this driver
128 * RegistryPath = path to our configuration entries
129 * RETURNS: Success or failure
130 */
131 {
132 PDEVICE_OBJECT DeviceObject;
133 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Parallel");
134 NTSTATUS Status;
135
136 DPRINT("Parallel Port Driver 0.0.1\n");
137
138 Status = IoCreateDevice(DriverObject,
139 0,
140 &DeviceName,
141 FILE_DEVICE_PARALLEL_PORT,
142 0,
143 FALSE,
144 &DeviceObject);
145 if (!NT_SUCCESS(Status))
146 {
147 return(Status);
148 }
149
150 DeviceObject->Flags=0;
151 DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
152 DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
153 DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
154 DriverObject->DriverUnload = NULL;
155
156 return(STATUS_SUCCESS);
157 }
158
159 /* EOF */