~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/usb/gadget_printer.rst

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php