xref: /linux/Documentation/usb/gadget_printer.rst (revision 570eb861243c07f2c3923af428ed20cd3f9d0a29)
1*570eb861SMauro Carvalho Chehab===============================
2ecefae6dSMauro Carvalho ChehabLinux USB Printer Gadget Driver
3ecefae6dSMauro Carvalho Chehab===============================
4ecefae6dSMauro Carvalho Chehab
5ecefae6dSMauro Carvalho Chehab06/04/2007
6ecefae6dSMauro Carvalho Chehab
7ecefae6dSMauro Carvalho ChehabCopyright (C) 2007 Craig W. Nadler <craig@nadler.us>
8ecefae6dSMauro Carvalho Chehab
9ecefae6dSMauro Carvalho Chehab
10ecefae6dSMauro Carvalho Chehab
11ecefae6dSMauro Carvalho ChehabGeneral
12ecefae6dSMauro Carvalho Chehab=======
13ecefae6dSMauro Carvalho Chehab
14ecefae6dSMauro Carvalho ChehabThis driver may be used if you are writing printer firmware using Linux as
15ecefae6dSMauro Carvalho Chehabthe embedded OS. This driver has nothing to do with using a printer with
16ecefae6dSMauro Carvalho Chehabyour Linux host system.
17ecefae6dSMauro Carvalho Chehab
18ecefae6dSMauro Carvalho ChehabYou will need a USB device controller and a Linux driver for it that accepts
19ecefae6dSMauro Carvalho Chehaba gadget / "device class" driver using the Linux USB Gadget API. After the
20ecefae6dSMauro Carvalho ChehabUSB device controller driver is loaded then load the printer gadget driver.
21ecefae6dSMauro Carvalho ChehabThis will present a printer interface to the USB Host that your USB Device
22ecefae6dSMauro Carvalho Chehabport is connected to.
23ecefae6dSMauro Carvalho Chehab
24ecefae6dSMauro Carvalho ChehabThis driver is structured for printer firmware that runs in user mode. The
25ecefae6dSMauro Carvalho Chehabuser mode printer firmware will read and write data from the kernel mode
26ecefae6dSMauro Carvalho Chehabprinter gadget driver using a device file. The printer returns a printer status
27ecefae6dSMauro Carvalho Chehabbyte when the USB HOST sends a device request to get the printer status.  The
28ecefae6dSMauro Carvalho Chehabuser space firmware can read or write this status byte using a device file
29ecefae6dSMauro Carvalho Chehab/dev/g_printer . Both blocking and non-blocking read/write calls are supported.
30ecefae6dSMauro Carvalho Chehab
31ecefae6dSMauro Carvalho Chehab
32ecefae6dSMauro Carvalho Chehab
33ecefae6dSMauro Carvalho Chehab
34ecefae6dSMauro Carvalho ChehabHowto Use This Driver
35ecefae6dSMauro Carvalho Chehab=====================
36ecefae6dSMauro Carvalho Chehab
37ecefae6dSMauro Carvalho ChehabTo load the USB device controller driver and the printer gadget driver. The
38ecefae6dSMauro Carvalho Chehabfollowing example uses the Netchip 2280 USB device controller driver::
39ecefae6dSMauro Carvalho Chehab
40ecefae6dSMauro Carvalho Chehab	modprobe net2280
41ecefae6dSMauro Carvalho Chehab	modprobe g_printer
42ecefae6dSMauro Carvalho Chehab
43ecefae6dSMauro Carvalho Chehab
44ecefae6dSMauro Carvalho ChehabThe follow command line parameter can be used when loading the printer gadget
45ecefae6dSMauro Carvalho Chehab(ex: modprobe g_printer idVendor=0x0525 idProduct=0xa4a8 ):
46ecefae6dSMauro Carvalho Chehab
47ecefae6dSMauro Carvalho ChehabidVendor
48ecefae6dSMauro Carvalho Chehab	This is the Vendor ID used in the device descriptor. The default is
49ecefae6dSMauro Carvalho Chehab	the Netchip vendor id 0x0525. YOU MUST CHANGE TO YOUR OWN VENDOR ID
50ecefae6dSMauro Carvalho Chehab	BEFORE RELEASING A PRODUCT. If you plan to release a product and don't
51ecefae6dSMauro Carvalho Chehab	already have a Vendor ID please see www.usb.org for details on how to
52ecefae6dSMauro Carvalho Chehab	get one.
53ecefae6dSMauro Carvalho Chehab
54ecefae6dSMauro Carvalho ChehabidProduct
55ecefae6dSMauro Carvalho Chehab	This is the Product ID used in the device descriptor. The default
56ecefae6dSMauro Carvalho Chehab	is 0xa4a8, you should change this to an ID that's not used by any of
57ecefae6dSMauro Carvalho Chehab	your other USB products if you have any. It would be a good idea to
58ecefae6dSMauro Carvalho Chehab	start numbering your products starting with say 0x0001.
59ecefae6dSMauro Carvalho Chehab
60ecefae6dSMauro Carvalho ChehabbcdDevice
61ecefae6dSMauro Carvalho Chehab	This is the version number of your product. It would be a good idea
62ecefae6dSMauro Carvalho Chehab	to put your firmware version here.
63ecefae6dSMauro Carvalho Chehab
64ecefae6dSMauro Carvalho ChehabiManufacturer
65ecefae6dSMauro Carvalho Chehab	A string containing the name of the Vendor.
66ecefae6dSMauro Carvalho Chehab
67ecefae6dSMauro Carvalho ChehabiProduct
68ecefae6dSMauro Carvalho Chehab	A string containing the Product Name.
69ecefae6dSMauro Carvalho Chehab
70ecefae6dSMauro Carvalho ChehabiSerialNum
71ecefae6dSMauro Carvalho Chehab	A string containing the Serial Number. This should be changed for
72ecefae6dSMauro Carvalho Chehab	each unit of your product.
73ecefae6dSMauro Carvalho Chehab
74ecefae6dSMauro Carvalho ChehabiPNPstring
75ecefae6dSMauro Carvalho Chehab	The PNP ID string used for this printer. You will want to set
76ecefae6dSMauro Carvalho Chehab	either on the command line or hard code the PNP ID string used for
77ecefae6dSMauro Carvalho Chehab	your printer product.
78ecefae6dSMauro Carvalho Chehab
79ecefae6dSMauro Carvalho Chehabqlen
80ecefae6dSMauro Carvalho Chehab	The number of 8k buffers to use per endpoint. The default is 10, you
81ecefae6dSMauro Carvalho Chehab	should tune this for your product. You may also want to tune the
82ecefae6dSMauro Carvalho Chehab	size of each buffer for your product.
83ecefae6dSMauro Carvalho Chehab
84ecefae6dSMauro Carvalho Chehab
85ecefae6dSMauro Carvalho Chehab
86ecefae6dSMauro Carvalho Chehab
87ecefae6dSMauro Carvalho ChehabUsing The Example Code
88ecefae6dSMauro Carvalho Chehab======================
89ecefae6dSMauro Carvalho Chehab
90ecefae6dSMauro Carvalho ChehabThis example code talks to stdout, instead of a print engine.
91ecefae6dSMauro Carvalho Chehab
92ecefae6dSMauro Carvalho ChehabTo compile the test code below:
93ecefae6dSMauro Carvalho Chehab
94ecefae6dSMauro Carvalho Chehab1) save it to a file called prn_example.c
95ecefae6dSMauro Carvalho Chehab2) compile the code with the follow command::
96ecefae6dSMauro Carvalho Chehab
97ecefae6dSMauro Carvalho Chehab	 gcc prn_example.c -o prn_example
98ecefae6dSMauro Carvalho Chehab
99ecefae6dSMauro Carvalho Chehab
100ecefae6dSMauro Carvalho Chehab
101ecefae6dSMauro Carvalho ChehabTo read printer data from the host to stdout::
102ecefae6dSMauro Carvalho Chehab
103ecefae6dSMauro Carvalho Chehab	# prn_example -read_data
104ecefae6dSMauro Carvalho Chehab
105ecefae6dSMauro Carvalho Chehab
106ecefae6dSMauro Carvalho ChehabTo write printer data from a file (data_file) to the host::
107ecefae6dSMauro Carvalho Chehab
108ecefae6dSMauro Carvalho Chehab	# cat data_file | prn_example -write_data
109ecefae6dSMauro Carvalho Chehab
110ecefae6dSMauro Carvalho Chehab
111ecefae6dSMauro Carvalho ChehabTo get the current printer status for the gadget driver:::
112ecefae6dSMauro Carvalho Chehab
113ecefae6dSMauro Carvalho Chehab	# prn_example -get_status
114ecefae6dSMauro Carvalho Chehab
115ecefae6dSMauro Carvalho Chehab	Printer status is:
116ecefae6dSMauro Carvalho Chehab	     Printer is NOT Selected
117ecefae6dSMauro Carvalho Chehab	     Paper is Out
118ecefae6dSMauro Carvalho Chehab	     Printer OK
119ecefae6dSMauro Carvalho Chehab
120ecefae6dSMauro Carvalho Chehab
121ecefae6dSMauro Carvalho ChehabTo set printer to Selected/On-line::
122ecefae6dSMauro Carvalho Chehab
123ecefae6dSMauro Carvalho Chehab	# prn_example -selected
124ecefae6dSMauro Carvalho Chehab
125ecefae6dSMauro Carvalho Chehab
126ecefae6dSMauro Carvalho ChehabTo set printer to Not Selected/Off-line::
127ecefae6dSMauro Carvalho Chehab
128ecefae6dSMauro Carvalho Chehab	# prn_example -not_selected
129ecefae6dSMauro Carvalho Chehab
130ecefae6dSMauro Carvalho Chehab
131ecefae6dSMauro Carvalho ChehabTo set paper status to paper out::
132ecefae6dSMauro Carvalho Chehab
133ecefae6dSMauro Carvalho Chehab	# prn_example -paper_out
134ecefae6dSMauro Carvalho Chehab
135ecefae6dSMauro Carvalho Chehab
136ecefae6dSMauro Carvalho ChehabTo set paper status to paper loaded::
137ecefae6dSMauro Carvalho Chehab
138ecefae6dSMauro Carvalho Chehab	# prn_example -paper_loaded
139ecefae6dSMauro Carvalho Chehab
140ecefae6dSMauro Carvalho Chehab
141ecefae6dSMauro Carvalho ChehabTo set error status to printer OK::
142ecefae6dSMauro Carvalho Chehab
143ecefae6dSMauro Carvalho Chehab	# prn_example -no_error
144ecefae6dSMauro Carvalho Chehab
145ecefae6dSMauro Carvalho Chehab
146ecefae6dSMauro Carvalho ChehabTo set error status to ERROR::
147ecefae6dSMauro Carvalho Chehab
148ecefae6dSMauro Carvalho Chehab	# prn_example -error
149ecefae6dSMauro Carvalho Chehab
150ecefae6dSMauro Carvalho Chehab
151ecefae6dSMauro Carvalho Chehab
152ecefae6dSMauro Carvalho Chehab
153ecefae6dSMauro Carvalho ChehabExample Code
154ecefae6dSMauro Carvalho Chehab============
155ecefae6dSMauro Carvalho Chehab
156ecefae6dSMauro Carvalho Chehab::
157ecefae6dSMauro Carvalho Chehab
158ecefae6dSMauro Carvalho Chehab
159ecefae6dSMauro Carvalho Chehab  #include <stdio.h>
160ecefae6dSMauro Carvalho Chehab  #include <stdlib.h>
161ecefae6dSMauro Carvalho Chehab  #include <fcntl.h>
162ecefae6dSMauro Carvalho Chehab  #include <linux/poll.h>
163ecefae6dSMauro Carvalho Chehab  #include <sys/ioctl.h>
164ecefae6dSMauro Carvalho Chehab  #include <linux/usb/g_printer.h>
165ecefae6dSMauro Carvalho Chehab
166ecefae6dSMauro Carvalho Chehab  #define PRINTER_FILE			"/dev/g_printer"
167ecefae6dSMauro Carvalho Chehab  #define BUF_SIZE			512
168ecefae6dSMauro Carvalho Chehab
169ecefae6dSMauro Carvalho Chehab
170ecefae6dSMauro Carvalho Chehab  /*
171ecefae6dSMauro Carvalho Chehab   * 'usage()' - Show program usage.
172ecefae6dSMauro Carvalho Chehab   */
173ecefae6dSMauro Carvalho Chehab
174ecefae6dSMauro Carvalho Chehab  static void
175ecefae6dSMauro Carvalho Chehab  usage(const char *option)		/* I - Option string or NULL */
176ecefae6dSMauro Carvalho Chehab  {
177ecefae6dSMauro Carvalho Chehab	if (option) {
178ecefae6dSMauro Carvalho Chehab		fprintf(stderr,"prn_example: Unknown option \"%s\"!\n",
179ecefae6dSMauro Carvalho Chehab				option);
180ecefae6dSMauro Carvalho Chehab	}
181ecefae6dSMauro Carvalho Chehab
182ecefae6dSMauro Carvalho Chehab	fputs("\n", stderr);
183ecefae6dSMauro Carvalho Chehab	fputs("Usage: prn_example -[options]\n", stderr);
184ecefae6dSMauro Carvalho Chehab	fputs("Options:\n", stderr);
185ecefae6dSMauro Carvalho Chehab	fputs("\n", stderr);
186ecefae6dSMauro Carvalho Chehab	fputs("-get_status    Get the current printer status.\n", stderr);
187ecefae6dSMauro Carvalho Chehab	fputs("-selected      Set the selected status to selected.\n", stderr);
188ecefae6dSMauro Carvalho Chehab	fputs("-not_selected  Set the selected status to NOT selected.\n",
189ecefae6dSMauro Carvalho Chehab			stderr);
190ecefae6dSMauro Carvalho Chehab	fputs("-error         Set the error status to error.\n", stderr);
191ecefae6dSMauro Carvalho Chehab	fputs("-no_error      Set the error status to NO error.\n", stderr);
192ecefae6dSMauro Carvalho Chehab	fputs("-paper_out     Set the paper status to paper out.\n", stderr);
193ecefae6dSMauro Carvalho Chehab	fputs("-paper_loaded  Set the paper status to paper loaded.\n",
194ecefae6dSMauro Carvalho Chehab			stderr);
195ecefae6dSMauro Carvalho Chehab	fputs("-read_data     Read printer data from driver.\n", stderr);
196ecefae6dSMauro Carvalho Chehab	fputs("-write_data    Write printer sata to driver.\n", stderr);
197ecefae6dSMauro Carvalho Chehab	fputs("-NB_read_data  (Non-Blocking) Read printer data from driver.\n",
198ecefae6dSMauro Carvalho Chehab			stderr);
199ecefae6dSMauro Carvalho Chehab	fputs("\n\n", stderr);
200ecefae6dSMauro Carvalho Chehab
201ecefae6dSMauro Carvalho Chehab	exit(1);
202ecefae6dSMauro Carvalho Chehab  }
203ecefae6dSMauro Carvalho Chehab
204ecefae6dSMauro Carvalho Chehab
205ecefae6dSMauro Carvalho Chehab  static int
206ecefae6dSMauro Carvalho Chehab  read_printer_data()
207ecefae6dSMauro Carvalho Chehab  {
208ecefae6dSMauro Carvalho Chehab	struct pollfd	fd[1];
209ecefae6dSMauro Carvalho Chehab
210ecefae6dSMauro Carvalho Chehab	/* Open device file for printer gadget. */
211ecefae6dSMauro Carvalho Chehab	fd[0].fd = open(PRINTER_FILE, O_RDWR);
212ecefae6dSMauro Carvalho Chehab	if (fd[0].fd < 0) {
213ecefae6dSMauro Carvalho Chehab		printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE);
214ecefae6dSMauro Carvalho Chehab		close(fd[0].fd);
215ecefae6dSMauro Carvalho Chehab		return(-1);
216ecefae6dSMauro Carvalho Chehab	}
217ecefae6dSMauro Carvalho Chehab
218ecefae6dSMauro Carvalho Chehab	fd[0].events = POLLIN | POLLRDNORM;
219ecefae6dSMauro Carvalho Chehab
220ecefae6dSMauro Carvalho Chehab	while (1) {
221ecefae6dSMauro Carvalho Chehab		static char buf[BUF_SIZE];
222ecefae6dSMauro Carvalho Chehab		int bytes_read;
223ecefae6dSMauro Carvalho Chehab		int retval;
224ecefae6dSMauro Carvalho Chehab
225ecefae6dSMauro Carvalho Chehab		/* Wait for up to 1 second for data. */
226ecefae6dSMauro Carvalho Chehab		retval = poll(fd, 1, 1000);
227ecefae6dSMauro Carvalho Chehab
228ecefae6dSMauro Carvalho Chehab		if (retval && (fd[0].revents & POLLRDNORM)) {
229ecefae6dSMauro Carvalho Chehab
230ecefae6dSMauro Carvalho Chehab			/* Read data from printer gadget driver. */
231ecefae6dSMauro Carvalho Chehab			bytes_read = read(fd[0].fd, buf, BUF_SIZE);
232ecefae6dSMauro Carvalho Chehab
233ecefae6dSMauro Carvalho Chehab			if (bytes_read < 0) {
234ecefae6dSMauro Carvalho Chehab				printf("Error %d reading from %s\n",
235ecefae6dSMauro Carvalho Chehab						fd[0].fd, PRINTER_FILE);
236ecefae6dSMauro Carvalho Chehab				close(fd[0].fd);
237ecefae6dSMauro Carvalho Chehab				return(-1);
238ecefae6dSMauro Carvalho Chehab			} else if (bytes_read > 0) {
239ecefae6dSMauro Carvalho Chehab				/* Write data to standard OUTPUT (stdout). */
240ecefae6dSMauro Carvalho Chehab				fwrite(buf, 1, bytes_read, stdout);
241ecefae6dSMauro Carvalho Chehab				fflush(stdout);
242ecefae6dSMauro Carvalho Chehab			}
243ecefae6dSMauro Carvalho Chehab
244ecefae6dSMauro Carvalho Chehab		}
245ecefae6dSMauro Carvalho Chehab
246ecefae6dSMauro Carvalho Chehab	}
247ecefae6dSMauro Carvalho Chehab
248ecefae6dSMauro Carvalho Chehab	/* Close the device file. */
249ecefae6dSMauro Carvalho Chehab	close(fd[0].fd);
250ecefae6dSMauro Carvalho Chehab
251ecefae6dSMauro Carvalho Chehab	return 0;
252ecefae6dSMauro Carvalho Chehab  }
253ecefae6dSMauro Carvalho Chehab
254ecefae6dSMauro Carvalho Chehab
255ecefae6dSMauro Carvalho Chehab  static int
256ecefae6dSMauro Carvalho Chehab  write_printer_data()
257ecefae6dSMauro Carvalho Chehab  {
258ecefae6dSMauro Carvalho Chehab	struct pollfd	fd[1];
259ecefae6dSMauro Carvalho Chehab
260ecefae6dSMauro Carvalho Chehab	/* Open device file for printer gadget. */
261ecefae6dSMauro Carvalho Chehab	fd[0].fd = open (PRINTER_FILE, O_RDWR);
262ecefae6dSMauro Carvalho Chehab	if (fd[0].fd < 0) {
263ecefae6dSMauro Carvalho Chehab		printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE);
264ecefae6dSMauro Carvalho Chehab		close(fd[0].fd);
265ecefae6dSMauro Carvalho Chehab		return(-1);
266ecefae6dSMauro Carvalho Chehab	}
267ecefae6dSMauro Carvalho Chehab
268ecefae6dSMauro Carvalho Chehab	fd[0].events = POLLOUT | POLLWRNORM;
269ecefae6dSMauro Carvalho Chehab
270ecefae6dSMauro Carvalho Chehab	while (1) {
271ecefae6dSMauro Carvalho Chehab		int retval;
272ecefae6dSMauro Carvalho Chehab		static char buf[BUF_SIZE];
273ecefae6dSMauro Carvalho Chehab		/* Read data from standard INPUT (stdin). */
274ecefae6dSMauro Carvalho Chehab		int bytes_read = fread(buf, 1, BUF_SIZE, stdin);
275ecefae6dSMauro Carvalho Chehab
276ecefae6dSMauro Carvalho Chehab		if (!bytes_read) {
277ecefae6dSMauro Carvalho Chehab			break;
278ecefae6dSMauro Carvalho Chehab		}
279ecefae6dSMauro Carvalho Chehab
280ecefae6dSMauro Carvalho Chehab		while (bytes_read) {
281ecefae6dSMauro Carvalho Chehab
282ecefae6dSMauro Carvalho Chehab			/* Wait for up to 1 second to sent data. */
283ecefae6dSMauro Carvalho Chehab			retval = poll(fd, 1, 1000);
284ecefae6dSMauro Carvalho Chehab
285ecefae6dSMauro Carvalho Chehab			/* Write data to printer gadget driver. */
286ecefae6dSMauro Carvalho Chehab			if (retval && (fd[0].revents & POLLWRNORM)) {
287ecefae6dSMauro Carvalho Chehab				retval = write(fd[0].fd, buf, bytes_read);
288ecefae6dSMauro Carvalho Chehab				if (retval < 0) {
289ecefae6dSMauro Carvalho Chehab					printf("Error %d writing to %s\n",
290ecefae6dSMauro Carvalho Chehab							fd[0].fd,
291ecefae6dSMauro Carvalho Chehab							PRINTER_FILE);
292ecefae6dSMauro Carvalho Chehab					close(fd[0].fd);
293ecefae6dSMauro Carvalho Chehab					return(-1);
294ecefae6dSMauro Carvalho Chehab				} else {
295ecefae6dSMauro Carvalho Chehab					bytes_read -= retval;
296ecefae6dSMauro Carvalho Chehab				}
297ecefae6dSMauro Carvalho Chehab
298ecefae6dSMauro Carvalho Chehab			}
299ecefae6dSMauro Carvalho Chehab
300ecefae6dSMauro Carvalho Chehab		}
301ecefae6dSMauro Carvalho Chehab
302ecefae6dSMauro Carvalho Chehab	}
303ecefae6dSMauro Carvalho Chehab
304ecefae6dSMauro Carvalho Chehab	/* Wait until the data has been sent. */
305ecefae6dSMauro Carvalho Chehab	fsync(fd[0].fd);
306ecefae6dSMauro Carvalho Chehab
307ecefae6dSMauro Carvalho Chehab	/* Close the device file. */
308ecefae6dSMauro Carvalho Chehab	close(fd[0].fd);
309ecefae6dSMauro Carvalho Chehab
310ecefae6dSMauro Carvalho Chehab	return 0;
311ecefae6dSMauro Carvalho Chehab  }
312ecefae6dSMauro Carvalho Chehab
313ecefae6dSMauro Carvalho Chehab
314ecefae6dSMauro Carvalho Chehab  static int
315ecefae6dSMauro Carvalho Chehab  read_NB_printer_data()
316ecefae6dSMauro Carvalho Chehab  {
317ecefae6dSMauro Carvalho Chehab	int		fd;
318ecefae6dSMauro Carvalho Chehab	static char	buf[BUF_SIZE];
319ecefae6dSMauro Carvalho Chehab	int		bytes_read;
320ecefae6dSMauro Carvalho Chehab
321ecefae6dSMauro Carvalho Chehab	/* Open device file for printer gadget. */
322ecefae6dSMauro Carvalho Chehab	fd = open(PRINTER_FILE, O_RDWR|O_NONBLOCK);
323ecefae6dSMauro Carvalho Chehab	if (fd < 0) {
324ecefae6dSMauro Carvalho Chehab		printf("Error %d opening %s\n", fd, PRINTER_FILE);
325ecefae6dSMauro Carvalho Chehab		close(fd);
326ecefae6dSMauro Carvalho Chehab		return(-1);
327ecefae6dSMauro Carvalho Chehab	}
328ecefae6dSMauro Carvalho Chehab
329ecefae6dSMauro Carvalho Chehab	while (1) {
330ecefae6dSMauro Carvalho Chehab		/* Read data from printer gadget driver. */
331ecefae6dSMauro Carvalho Chehab		bytes_read = read(fd, buf, BUF_SIZE);
332ecefae6dSMauro Carvalho Chehab		if (bytes_read <= 0) {
333ecefae6dSMauro Carvalho Chehab			break;
334ecefae6dSMauro Carvalho Chehab		}
335ecefae6dSMauro Carvalho Chehab
336ecefae6dSMauro Carvalho Chehab		/* Write data to standard OUTPUT (stdout). */
337ecefae6dSMauro Carvalho Chehab		fwrite(buf, 1, bytes_read, stdout);
338ecefae6dSMauro Carvalho Chehab		fflush(stdout);
339ecefae6dSMauro Carvalho Chehab	}
340ecefae6dSMauro Carvalho Chehab
341ecefae6dSMauro Carvalho Chehab	/* Close the device file. */
342ecefae6dSMauro Carvalho Chehab	close(fd);
343ecefae6dSMauro Carvalho Chehab
344ecefae6dSMauro Carvalho Chehab	return 0;
345ecefae6dSMauro Carvalho Chehab  }
346ecefae6dSMauro Carvalho Chehab
347ecefae6dSMauro Carvalho Chehab
348ecefae6dSMauro Carvalho Chehab  static int
349ecefae6dSMauro Carvalho Chehab  get_printer_status()
350ecefae6dSMauro Carvalho Chehab  {
351ecefae6dSMauro Carvalho Chehab	int	retval;
352ecefae6dSMauro Carvalho Chehab	int	fd;
353ecefae6dSMauro Carvalho Chehab
354ecefae6dSMauro Carvalho Chehab	/* Open device file for printer gadget. */
355ecefae6dSMauro Carvalho Chehab	fd = open(PRINTER_FILE, O_RDWR);
356ecefae6dSMauro Carvalho Chehab	if (fd < 0) {
357ecefae6dSMauro Carvalho Chehab		printf("Error %d opening %s\n", fd, PRINTER_FILE);
358ecefae6dSMauro Carvalho Chehab		close(fd);
359ecefae6dSMauro Carvalho Chehab		return(-1);
360ecefae6dSMauro Carvalho Chehab	}
361ecefae6dSMauro Carvalho Chehab
362ecefae6dSMauro Carvalho Chehab	/* Make the IOCTL call. */
363ecefae6dSMauro Carvalho Chehab	retval = ioctl(fd, GADGET_GET_PRINTER_STATUS);
364ecefae6dSMauro Carvalho Chehab	if (retval < 0) {
365ecefae6dSMauro Carvalho Chehab		fprintf(stderr, "ERROR: Failed to set printer status\n");
366ecefae6dSMauro Carvalho Chehab		return(-1);
367ecefae6dSMauro Carvalho Chehab	}
368ecefae6dSMauro Carvalho Chehab
369ecefae6dSMauro Carvalho Chehab	/* Close the device file. */
370ecefae6dSMauro Carvalho Chehab	close(fd);
371ecefae6dSMauro Carvalho Chehab
372ecefae6dSMauro Carvalho Chehab	return(retval);
373ecefae6dSMauro Carvalho Chehab  }
374ecefae6dSMauro Carvalho Chehab
375ecefae6dSMauro Carvalho Chehab
376ecefae6dSMauro Carvalho Chehab  static int
377ecefae6dSMauro Carvalho Chehab  set_printer_status(unsigned char buf, int clear_printer_status_bit)
378ecefae6dSMauro Carvalho Chehab  {
379ecefae6dSMauro Carvalho Chehab	int	retval;
380ecefae6dSMauro Carvalho Chehab	int	fd;
381ecefae6dSMauro Carvalho Chehab
382ecefae6dSMauro Carvalho Chehab	retval = get_printer_status();
383ecefae6dSMauro Carvalho Chehab	if (retval < 0) {
384ecefae6dSMauro Carvalho Chehab		fprintf(stderr, "ERROR: Failed to get printer status\n");
385ecefae6dSMauro Carvalho Chehab		return(-1);
386ecefae6dSMauro Carvalho Chehab	}
387ecefae6dSMauro Carvalho Chehab
388ecefae6dSMauro Carvalho Chehab	/* Open device file for printer gadget. */
389ecefae6dSMauro Carvalho Chehab	fd = open(PRINTER_FILE, O_RDWR);
390ecefae6dSMauro Carvalho Chehab
391ecefae6dSMauro Carvalho Chehab	if (fd < 0) {
392ecefae6dSMauro Carvalho Chehab		printf("Error %d opening %s\n", fd, PRINTER_FILE);
393ecefae6dSMauro Carvalho Chehab		close(fd);
394ecefae6dSMauro Carvalho Chehab		return(-1);
395ecefae6dSMauro Carvalho Chehab	}
396ecefae6dSMauro Carvalho Chehab
397ecefae6dSMauro Carvalho Chehab	if (clear_printer_status_bit) {
398ecefae6dSMauro Carvalho Chehab		retval &= ~buf;
399ecefae6dSMauro Carvalho Chehab	} else {
400ecefae6dSMauro Carvalho Chehab		retval |= buf;
401ecefae6dSMauro Carvalho Chehab	}
402ecefae6dSMauro Carvalho Chehab
403ecefae6dSMauro Carvalho Chehab	/* Make the IOCTL call. */
404ecefae6dSMauro Carvalho Chehab	if (ioctl(fd, GADGET_SET_PRINTER_STATUS, (unsigned char)retval)) {
405ecefae6dSMauro Carvalho Chehab		fprintf(stderr, "ERROR: Failed to set printer status\n");
406ecefae6dSMauro Carvalho Chehab		return(-1);
407ecefae6dSMauro Carvalho Chehab	}
408ecefae6dSMauro Carvalho Chehab
409ecefae6dSMauro Carvalho Chehab	/* Close the device file. */
410ecefae6dSMauro Carvalho Chehab	close(fd);
411ecefae6dSMauro Carvalho Chehab
412ecefae6dSMauro Carvalho Chehab	return 0;
413ecefae6dSMauro Carvalho Chehab  }
414ecefae6dSMauro Carvalho Chehab
415ecefae6dSMauro Carvalho Chehab
416ecefae6dSMauro Carvalho Chehab  static int
417ecefae6dSMauro Carvalho Chehab  display_printer_status()
418ecefae6dSMauro Carvalho Chehab  {
419ecefae6dSMauro Carvalho Chehab	char	printer_status;
420ecefae6dSMauro Carvalho Chehab
421ecefae6dSMauro Carvalho Chehab	printer_status = get_printer_status();
422ecefae6dSMauro Carvalho Chehab	if (printer_status < 0) {
423ecefae6dSMauro Carvalho Chehab		fprintf(stderr, "ERROR: Failed to get printer status\n");
424ecefae6dSMauro Carvalho Chehab		return(-1);
425ecefae6dSMauro Carvalho Chehab	}
426ecefae6dSMauro Carvalho Chehab
427ecefae6dSMauro Carvalho Chehab	printf("Printer status is:\n");
428ecefae6dSMauro Carvalho Chehab	if (printer_status & PRINTER_SELECTED) {
429ecefae6dSMauro Carvalho Chehab		printf("     Printer is Selected\n");
430ecefae6dSMauro Carvalho Chehab	} else {
431ecefae6dSMauro Carvalho Chehab		printf("     Printer is NOT Selected\n");
432ecefae6dSMauro Carvalho Chehab	}
433ecefae6dSMauro Carvalho Chehab	if (printer_status & PRINTER_PAPER_EMPTY) {
434ecefae6dSMauro Carvalho Chehab		printf("     Paper is Out\n");
435ecefae6dSMauro Carvalho Chehab	} else {
436ecefae6dSMauro Carvalho Chehab		printf("     Paper is Loaded\n");
437ecefae6dSMauro Carvalho Chehab	}
438ecefae6dSMauro Carvalho Chehab	if (printer_status & PRINTER_NOT_ERROR) {
439ecefae6dSMauro Carvalho Chehab		printf("     Printer OK\n");
440ecefae6dSMauro Carvalho Chehab	} else {
441ecefae6dSMauro Carvalho Chehab		printf("     Printer ERROR\n");
442ecefae6dSMauro Carvalho Chehab	}
443ecefae6dSMauro Carvalho Chehab
444ecefae6dSMauro Carvalho Chehab	return(0);
445ecefae6dSMauro Carvalho Chehab  }
446ecefae6dSMauro Carvalho Chehab
447ecefae6dSMauro Carvalho Chehab
448ecefae6dSMauro Carvalho Chehab  int
449ecefae6dSMauro Carvalho Chehab  main(int  argc, char *argv[])
450ecefae6dSMauro Carvalho Chehab  {
451ecefae6dSMauro Carvalho Chehab	int	i;		/* Looping var */
452ecefae6dSMauro Carvalho Chehab	int	retval = 0;
453ecefae6dSMauro Carvalho Chehab
454ecefae6dSMauro Carvalho Chehab	/* No Args */
455ecefae6dSMauro Carvalho Chehab	if (argc == 1) {
456ecefae6dSMauro Carvalho Chehab		usage(0);
457ecefae6dSMauro Carvalho Chehab		exit(0);
458ecefae6dSMauro Carvalho Chehab	}
459ecefae6dSMauro Carvalho Chehab
460ecefae6dSMauro Carvalho Chehab	for (i = 1; i < argc && !retval; i ++) {
461ecefae6dSMauro Carvalho Chehab
462ecefae6dSMauro Carvalho Chehab		if (argv[i][0] != '-') {
463ecefae6dSMauro Carvalho Chehab			continue;
464ecefae6dSMauro Carvalho Chehab		}
465ecefae6dSMauro Carvalho Chehab
466ecefae6dSMauro Carvalho Chehab		if (!strcmp(argv[i], "-get_status")) {
467ecefae6dSMauro Carvalho Chehab			if (display_printer_status()) {
468ecefae6dSMauro Carvalho Chehab				retval = 1;
469ecefae6dSMauro Carvalho Chehab			}
470ecefae6dSMauro Carvalho Chehab
471ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-paper_loaded")) {
472ecefae6dSMauro Carvalho Chehab			if (set_printer_status(PRINTER_PAPER_EMPTY, 1)) {
473ecefae6dSMauro Carvalho Chehab				retval = 1;
474ecefae6dSMauro Carvalho Chehab			}
475ecefae6dSMauro Carvalho Chehab
476ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-paper_out")) {
477ecefae6dSMauro Carvalho Chehab			if (set_printer_status(PRINTER_PAPER_EMPTY, 0)) {
478ecefae6dSMauro Carvalho Chehab				retval = 1;
479ecefae6dSMauro Carvalho Chehab			}
480ecefae6dSMauro Carvalho Chehab
481ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-selected")) {
482ecefae6dSMauro Carvalho Chehab			if (set_printer_status(PRINTER_SELECTED, 0)) {
483ecefae6dSMauro Carvalho Chehab				retval = 1;
484ecefae6dSMauro Carvalho Chehab			}
485ecefae6dSMauro Carvalho Chehab
486ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-not_selected")) {
487ecefae6dSMauro Carvalho Chehab			if (set_printer_status(PRINTER_SELECTED, 1)) {
488ecefae6dSMauro Carvalho Chehab				retval = 1;
489ecefae6dSMauro Carvalho Chehab			}
490ecefae6dSMauro Carvalho Chehab
491ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-error")) {
492ecefae6dSMauro Carvalho Chehab			if (set_printer_status(PRINTER_NOT_ERROR, 1)) {
493ecefae6dSMauro Carvalho Chehab				retval = 1;
494ecefae6dSMauro Carvalho Chehab			}
495ecefae6dSMauro Carvalho Chehab
496ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-no_error")) {
497ecefae6dSMauro Carvalho Chehab			if (set_printer_status(PRINTER_NOT_ERROR, 0)) {
498ecefae6dSMauro Carvalho Chehab				retval = 1;
499ecefae6dSMauro Carvalho Chehab			}
500ecefae6dSMauro Carvalho Chehab
501ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-read_data")) {
502ecefae6dSMauro Carvalho Chehab			if (read_printer_data()) {
503ecefae6dSMauro Carvalho Chehab				retval = 1;
504ecefae6dSMauro Carvalho Chehab			}
505ecefae6dSMauro Carvalho Chehab
506ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-write_data")) {
507ecefae6dSMauro Carvalho Chehab			if (write_printer_data()) {
508ecefae6dSMauro Carvalho Chehab				retval = 1;
509ecefae6dSMauro Carvalho Chehab			}
510ecefae6dSMauro Carvalho Chehab
511ecefae6dSMauro Carvalho Chehab		} else if (!strcmp(argv[i], "-NB_read_data")) {
512ecefae6dSMauro Carvalho Chehab			if (read_NB_printer_data()) {
513ecefae6dSMauro Carvalho Chehab				retval = 1;
514ecefae6dSMauro Carvalho Chehab			}
515ecefae6dSMauro Carvalho Chehab
516ecefae6dSMauro Carvalho Chehab		} else {
517ecefae6dSMauro Carvalho Chehab			usage(argv[i]);
518ecefae6dSMauro Carvalho Chehab			retval = 1;
519ecefae6dSMauro Carvalho Chehab		}
520ecefae6dSMauro Carvalho Chehab	}
521ecefae6dSMauro Carvalho Chehab
522ecefae6dSMauro Carvalho Chehab	exit(retval);
523ecefae6dSMauro Carvalho Chehab  }
524