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