Initial revision
[reactos.git] / reactos / drivers / dd / 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 <ddk/ntddk.h>
15
16 #include "parallel.h"
17
18 #define LP_B (0x378)
19 #define LP_S (inb_p(LP_B+1))
20 #define LP_C (LP_B+2)
21
22 static void Parallel_Reset(void)
23 /*
24 * FUNCTION: Resets the device attached to the parallel port
25 */
26 {
27 int i;
28
29 outb_p(LP_C,0);
30 for (i=0;i<LP_DELAY;i++);
31 outb_p(LP_C,LP_PSELECP | LP_PINITP);
32 }
33
34 static void Parallel_putchar(unsigned char ch)
35 /*
36 * FUNCTION: Writes a character to the parallel port
37 * ARGUMENTS:
38 * ch = character to write
39 */
40 {
41
42 int count=0;
43 int status;
44 int wait=0;
45
46 do
47 {
48 status=LP_S;
49 count++;
50 }
51 while ( count < 500000 && !(status & LP_PBUSY) );
52
53 if (count==500000)
54 {
55 printk("printer_putchar(): timed out\n");
56 return;
57 }
58
59 outb_p(LP_B,ch);
60 while (wait != 10000) { wait++; }
61 outb_p(LP_C, (LP_PSELECP | LP_PINITP | LP_PSTROBE ));
62 while (wait) { wait--; }
63 outb_p(LP_C, LP_PSELECP | LP_PINITP);
64 }
65
66 NTSTATUS Dispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
67 /*
68 * FUNCTION: Handles user mode requests
69 * ARGUMENTS:
70 * DeviceObject = Device for request
71 * Irp = I/O request packet describing request
72 * RETURNS: Success or failure
73 */
74 {
75 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
76 NTSTATUS status;
77 int i;
78
79 switch (Stack->MajorFunction)
80 {
81 case IRP_MJ_CREATE:
82 printk("(Parallel Port Driver) Creating\n");
83 Parallel_Reset();
84 status = STATUS_SUCCESS;
85 break;
86
87 case IRP_MJ_CLOSE:
88 status = STATUS_SUCCESS;
89 break;
90
91 case IRP_MJ_WRITE:
92 printk("(Parallel Port Driver) Writing %d bytes\n",
93 Stack->Parameters.Write.Length);
94 for (i=0;i<Stack->Parameters.Write.Length;i++)
95 {
96 Parallel_putchar(((char *)Irp->UserBuffer)[i]);
97 }
98 status = STATUS_SUCCESS;
99 break;
100
101 default:
102 status = STATUS_NOT_IMPLEMENTED;
103 break;
104 }
105
106 Irp->IoStatus.Status = status;
107 Irp->IoStatus.Information = 0;
108
109 IoCompleteRequest(Irp, IO_NO_INCREMENT);
110 return(status);
111 }
112
113 NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
114 /*
115 * FUNCTION: Called by the system to initalize the driver
116 * ARGUMENTS:
117 * DriverObject = object describing this driver
118 * RegistryPath = path to our configuration entries
119 * RETURNS: Success or failure
120 */
121 {
122 PDEVICE_OBJECT DeviceObject;
123 NTSTATUS ret;
124
125 printk("Parallel Port Driver 0.0.1\n");
126
127
128 ret = IoCreateDevice(DriverObject,0,"\\Device\\Parallel",
129 FILE_DEVICE_PARALLEL_PORT,0,FALSE,&DeviceObject);
130 if (ret!=STATUS_SUCCESS)
131 {
132 return(ret);
133 }
134
135 DeviceObject->Flags=0;
136 DriverObject->MajorFunction[IRP_MJ_CLOSE] = Dispatch;
137 DriverObject->MajorFunction[IRP_MJ_CREATE] = Dispatch;
138 DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
139 DriverObject->MajorFunction[IRP_MJ_WRITE] = Dispatch;
140 DriverObject->DriverUnload = NULL;
141
142 return(STATUS_SUCCESS);
143 }
144