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