linux/Documentation/usb/gadget_printer.txt
<<
>>
Prefs
   1
   2                       Linux USB Printer Gadget Driver
   3                                 06/04/2007
   4
   5              Copyright (C) 2007 Craig W. Nadler <craig@nadler.us>
   6
   7
   8
   9GENERAL
  10=======
  11
  12This driver may be used if you are writing printer firmware using Linux as
  13the embedded OS. This driver has nothing to do with using a printer with
  14your Linux host system.
  15
  16You will need a USB device controller and a Linux driver for it that accepts
  17a gadget / "device class" driver using the Linux USB Gadget API. After the
  18USB device controller driver is loaded then load the printer gadget driver.
  19This will present a printer interface to the USB Host that your USB Device
  20port is connected to.
  21
  22This driver is structured for printer firmware that runs in user mode. The
  23user mode printer firmware will read and write data from the kernel mode
  24printer gadget driver using a device file. The printer returns a printer status
  25byte when the USB HOST sends a device request to get the printer status.  The
  26user space firmware can read or write this status byte using a device file
  27/dev/g_printer . Both blocking and non-blocking read/write calls are supported.
  28
  29
  30
  31
  32HOWTO USE THIS DRIVER
  33=====================
  34
  35To load the USB device controller driver and the printer gadget driver. The
  36following example uses the Netchip 2280 USB device controller driver:
  37
  38modprobe net2280
  39modprobe g_printer
  40
  41
  42The follow command line parameter can be used when loading the printer gadget
  43(ex: modprobe g_printer idVendor=0x0525 idProduct=0xa4a8 ):
  44
  45idVendor - This is the Vendor ID used in the device descriptor. The default is
  46        the Netchip vendor id 0x0525. YOU MUST CHANGE TO YOUR OWN VENDOR ID
  47        BEFORE RELEASING A PRODUCT. If you plan to release a product and don't
  48        already have a Vendor ID please see www.usb.org for details on how to
  49        get one.
  50
  51idProduct - This is the Product ID used in the device descriptor. The default
  52        is 0xa4a8, you should change this to an ID that's not used by any of
  53        your other USB products if you have any. It would be a good idea to
  54        start numbering your products starting with say 0x0001.
  55
  56bcdDevice - This is the version number of your product. It would be a good idea
  57        to put your firmware version here.
  58
  59iManufacturer - A string containing the name of the Vendor.
  60
  61iProduct - A string containing the Product Name.
  62
  63iSerialNum - A string containing the Serial Number. This should be changed for
  64        each unit of your product.
  65
  66iPNPstring -  The PNP ID string used for this printer. You will want to set
  67        either on the command line or hard code the PNP ID string used for
  68        your printer product.
  69
  70qlen - The number of 8k buffers to use per endpoint. The default is 10, you
  71        should tune this for your product. You may also want to tune the
  72        size of each buffer for your product.
  73
  74
  75
  76
  77USING THE EXAMPLE CODE
  78======================
  79
  80This example code talks to stdout, instead of a print engine.
  81
  82To compile the test code below:
  83
  841) save it to a file called prn_example.c
  852) compile the code with the follow command:
  86         gcc prn_example.c -o prn_example
  87
  88
  89
  90To read printer data from the host to stdout:
  91
  92        # prn_example -read_data
  93
  94
  95To write printer data from a file (data_file) to the host:
  96
  97        # cat data_file | prn_example -write_data
  98
  99
 100To get the current printer status for the gadget driver:
 101
 102        # prn_example -get_status
 103
 104        Printer status is:
 105             Printer is NOT Selected
 106             Paper is Out
 107             Printer OK
 108
 109
 110To set printer to Selected/On-line:
 111
 112        # prn_example -selected
 113
 114
 115To set printer to Not Selected/Off-line:
 116
 117        # prn_example -not_selected
 118
 119
 120To set paper status to paper out:
 121
 122        # prn_example -paper_out
 123
 124
 125To set paper status to paper loaded:
 126
 127        # prn_example -paper_loaded
 128
 129
 130To set error status to printer OK:
 131
 132        # prn_example -no_error
 133
 134
 135To set error status to ERROR:
 136
 137        # prn_example -error
 138
 139
 140
 141
 142EXAMPLE CODE
 143============
 144
 145
 146#include <stdio.h>
 147#include <stdlib.h>
 148#include <fcntl.h>
 149#include <linux/poll.h>
 150#include <sys/ioctl.h>
 151#include <linux/usb/g_printer.h>
 152
 153#define PRINTER_FILE                    "/dev/g_printer"
 154#define BUF_SIZE                        512
 155
 156
 157/*
 158 * 'usage()' - Show program usage.
 159 */
 160
 161static void
 162usage(const char *option)               /* I - Option string or NULL */
 163{
 164        if (option) {
 165                fprintf(stderr,"prn_example: Unknown option \"%s\"!\n",
 166                                option);
 167        }
 168
 169        fputs("\n", stderr);
 170        fputs("Usage: prn_example -[options]\n", stderr);
 171        fputs("Options:\n", stderr);
 172        fputs("\n", stderr);
 173        fputs("-get_status    Get the current printer status.\n", stderr);
 174        fputs("-selected      Set the selected status to selected.\n", stderr);
 175        fputs("-not_selected  Set the selected status to NOT selected.\n",
 176                        stderr);
 177        fputs("-error         Set the error status to error.\n", stderr);
 178        fputs("-no_error      Set the error status to NO error.\n", stderr);
 179        fputs("-paper_out     Set the paper status to paper out.\n", stderr);
 180        fputs("-paper_loaded  Set the paper status to paper loaded.\n",
 181                        stderr);
 182        fputs("-read_data     Read printer data from driver.\n", stderr);
 183        fputs("-write_data    Write printer sata to driver.\n", stderr);
 184        fputs("-NB_read_data  (Non-Blocking) Read printer data from driver.\n",
 185                        stderr);
 186        fputs("\n\n", stderr);
 187
 188        exit(1);
 189}
 190
 191
 192static int
 193read_printer_data()
 194{
 195        struct pollfd   fd[1];
 196
 197        /* Open device file for printer gadget. */
 198        fd[0].fd = open(PRINTER_FILE, O_RDWR);
 199        if (fd[0].fd < 0) {
 200                printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE);
 201                close(fd[0].fd);
 202                return(-1);
 203        }
 204
 205        fd[0].events = POLLIN | POLLRDNORM;
 206
 207        while (1) {
 208                static char buf[BUF_SIZE];
 209                int bytes_read;
 210                int retval;
 211
 212                /* Wait for up to 1 second for data. */
 213                retval = poll(fd, 1, 1000);
 214
 215                if (retval && (fd[0].revents & POLLRDNORM)) {
 216
 217                        /* Read data from printer gadget driver. */
 218                        bytes_read = read(fd[0].fd, buf, BUF_SIZE);
 219
 220                        if (bytes_read < 0) {
 221                                printf("Error %d reading from %s\n",
 222                                                fd[0].fd, PRINTER_FILE);
 223                                close(fd[0].fd);
 224                                return(-1);
 225                        } else if (bytes_read > 0) {
 226                                /* Write data to standard OUTPUT (stdout). */
 227                                fwrite(buf, 1, bytes_read, stdout);
 228                                fflush(stdout);
 229                        }
 230
 231                }
 232
 233        }
 234
 235        /* Close the device file. */
 236        close(fd[0].fd);
 237
 238        return 0;
 239}
 240
 241
 242static int
 243write_printer_data()
 244{
 245        struct pollfd   fd[1];
 246
 247        /* Open device file for printer gadget. */
 248        fd[0].fd = open (PRINTER_FILE, O_RDWR);
 249        if (fd[0].fd < 0) {
 250                printf("Error %d opening %s\n", fd[0].fd, PRINTER_FILE);
 251                close(fd[0].fd);
 252                return(-1);
 253        }
 254
 255        fd[0].events = POLLOUT | POLLWRNORM;
 256
 257        while (1) {
 258                int retval;
 259                static char buf[BUF_SIZE];
 260                /* Read data from standard INPUT (stdin). */
 261                int bytes_read = fread(buf, 1, BUF_SIZE, stdin);
 262
 263                if (!bytes_read) {
 264                        break;
 265                }
 266
 267                while (bytes_read) {
 268
 269                        /* Wait for up to 1 second to sent data. */
 270                        retval = poll(fd, 1, 1000);
 271
 272                        /* Write data to printer gadget driver. */
 273                        if (retval && (fd[0].revents & POLLWRNORM)) {
 274                                retval = write(fd[0].fd, buf, bytes_read);
 275                                if (retval < 0) {
 276                                        printf("Error %d writing to %s\n",
 277                                                        fd[0].fd,
 278                                                        PRINTER_FILE);
 279                                        close(fd[0].fd);
 280                                        return(-1);
 281                                } else {
 282                                        bytes_read -= retval;
 283                                }
 284
 285                        }
 286
 287                }
 242statDocum3f class="line" name="L282"> 282   _prin7U="Documentation[0].events = la>        if (fd[4                        PRINTER_FILE);
<0 144
 251     dl        o3ntil          has beenp to er gadget driver. */
fsync           close(fd[0].fd);
  93
                close(fd[0].fd);
 196
 238        return 0;
 282   _prin7U="Documentation[0].ess="line"txt#L199" id="L199" clas2="lin2e" name="L99">  99
 242static int
 243write_printer_data()
 163{
                f   int bytes_read;
 2                  static char buf[BUF_SIZE];
                            int bytes_read;
 237
 247        /* Open device file for printer gadget. */
a>        fd[0].fd = open(PRIN|O_NONBLOCK  close(fd[0].fd);
 249 281                printf("Error %d opening &#", fd[0].fd, PRINTER_FILE);
 212        fd, PRINTER_FILE);
 213                return(-1);
 282   _prin7U="Documentation[0]3t_printer3txt#L215" id="L215" clas3="lin31 name="L155"> 155
 257        while (1) {
 217                /* Read data from printer gadget driver. */
 218                byte = read(fd[0].fd, buf, BUF_SIZE);
 209                if = if (retval < 0) {
 220                        break;
 221 name="L282"> 282   _prin7U="Documentation[0]3t_printer3txt#L222" id="L222" clas3="lin32 name="L262"> 262
 223                /* Write data to standard OUTPUT (stdout). */
 224                fwrite(buf, 1, bytes_read, stdout);
 225                fflush(stdout);
 name="L282"> 282   _prin7U="Documentation[0]3t_printer3txt#L227" id="L227" clas3="lin32 name="L237"> 237
 245        /* Close the device file. */
        fd, PRINTER_FILE);
 230
 238        return 0;
 282   _prin7U="Documentation[0]3t_printer3txt#L233" id="L233" clas3="lin3" name="L133"> 133
 234
 242static int
          bytes_read -= retval;
        f   int bytes_read;
 240
f>        fd[0].fd = open(PRINTER_FILE, O_RDWR);
 249 224                printf("Error %d opening &#", fd[0].fd, PRINTER_FILE);
 225        fd, PRINTER_FILE);
 276                return(-1);
 167        }
   Mak>     IOCTL callr printer gadget. */
         incluyte =GADGET_GET_uot;, fdSTATUS       return(-1);
                if (retval < 0) {
 252                      error  Fa/* or up t  Get the currend openin       return(-1);
 213                return(-1);
 282   _prin7U="Documentation[0]3t_printer3txt#L255" id="L255" clas3="lin3" name="L155"> 155
 245        /* Close the device file. */
        fd, PRINTER_FILE);
             fd, PRINTER_FILE);
 282   _prin7U="Documentation[0]3t_printer3txt#L261" id="L261" clas3="lin36 name="L271"> 271
 262
 242static int
    clearation/usfputs(&_bitte_printer_data()
          bytes_read -= retval;
        f   int bytes_read;
 268
         entation/usfputs(&it  int bytes_read;
 249            if (retval < 0) {
 221                      error  Fa/* or upgt  Get the currend openin       return(-1);
 272                return(-1);
 253        }
 234
 237        /* Open device file for printer gadget. */
f>        fd[0].fd = open(PRINTER_FILE, O_RDWR);
 237
 249 279                printf("Error %d opening &#", fd[0].fd, PRINTER_FILE);
 280        fd, PRINTER_FILE);
 281                return(-1);
 253        }
 133
 164clearation/usfputs(&_bitt (retval < 0) {
 285            = ~         return(-1);
                } else {
 287       |=          return(-1);
 253        }
 242sta3Docum38" name="L99">  99
 23Mak>     IOCTL callr printer gadget. */
 39 name="L251">    incluyte =GADGET_SET_uot;, fdSTATUS, iunsign or    )      ft (retval < 0) {
 252                      error  Fa/* or up t  Get the currend openin       return(-1);
 213                return(-1);
 282   _prin7U="Documentation[0]3t_printer3txt#L195" id="L195" clas3="lin39 name="L155"> 155
 245        /* Close the device file. */
        fd, PRINTER_FILE);
 268
      a>        return 0;
 282   _prin7U="Documentation[0]4t_printer4txt#L201" id="L201" clas4="lin40 name="L271"> 271
 262
 242static int
        tion/usfputs(&        return 0;
 237
tion/usfputs(&   entation/usfputs(&it  int bytes_read;
 249tion/usfputs(&      if (retval < 0) {
 210                      error  Fa/* or upgt  Get the currend openin       return(-1);
 281                return(-1);
 253        }
 133
 249tion/usfputs(&  (fd[0]ot;, fdSELECTEDf (retval < 0) {
 276             6Pet the is S statuss("       return(-1);
                } else {
 218             6Pet the is ecteS statuss("       return(-1);
 282   _prin7U="Documentation[0]4t_printer4txt#L220" id="L220" clas4="lin42 name="L210"> 249tion/usfputs(&  (fd[0]ot;, fdPAP fdEMPTYf (retval < 0) {
 221             6Paper is Outs("       return(-1);
                } else {
 223             6Paper is Ltatuss("       return(-1);
 282   _prin7U="Documentation[0]4t_printer4txt#L225" id="L225" clas4="lin42 name="L215"> 249tion/usfputs(&  (fd[0]ot;, fdect_errorf (retval < 0) {
 226             6Pet the OKs("       return(-1);
                } else {
 228             6Pet the errors("       return(-1);
 282   _prin7U="Documentation[0]4t_printer4txt#L230" id="L230" clas4="lin4" name="L230"> 230
 238 282   _prin7U="Documentation[0]4t_printer4txt#L233" id="L233" clas4="lin4" name="L133"> 133
 234
 242static int
     *argv[]te_printer_data()
        i;L228"> 228/* Ltoprrorv   *e device file. */
                 >        return 0;
 240
 249argc == >        while (1) {
 223usage( poll(fd, 1, 1000);
 224 188< poll(fd, 1, 1000);
 name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L246" id="L246" clas4="lin4" name="L246"> 246
pen (i   1; i      argc      if (re!  bytes i ++        while (1) {
 209    argv[i][0] !=r 	- 	        while (1) {
 250>>>>>>>>continueoll(fd, 1, 1000);
 251 name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L252" id="L252" clas4="lin45 name="L262"> 262
 213     strcmp argv[i]        -entaputs(&"         while (1) {
 274            displayation/usfputs(&it        while (1) {
 275                         1oll(fd, 1, 1000);
 276         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L257" id="L257" clas4="lin45 name="L237"> 237
 258            strcmp argv[i]        -paper_ltatus"         while (1) {
 259            sntation/usfputs(&i]ot;, fdPAP fdEMPTY, >         while (1) {
 260                         1oll(fd, 1, 1000);
 261         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L262" id="L262" clas4="lin4" name="L262"> 262
 263            strcmp argv[i]        -paper_out"         while (1) {
 264            sntation/usfputs(&i]ot;, fdPAP fdEMPTY, 0         while (1) {
 265                         1oll(fd, 1, 1000);
 276         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L267" id="L267" clas4="lin46 name="L237"> 237
 258            strcmp argv[i]        -s status"         while (1) {
 269            sntation/usfputs(&i]ot;, fdSELECTED, 0         while (1) {
 270                         1oll(fd, 1, 1000);
 221         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L272" id="L272" clas4="lin47 name="L262"> 262
 273            strcmp argv[i]        -notap status"         while (1) {
 274            sntation/usfputs(&i]ot;, fdSELECTED, >         while (1) {
 275                         1oll(fd, 1, 1000);
 276         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L277" id="L277" clas4="lin47 name="L237"> 237
 278            strcmp argv[i]        -e  pr"         while (1) {
 279            sntation/usfputs(&i]ot;, fdect_error, >         while (1) {
 280                         1oll(fd, 1, 1000);
 281         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L282" id="L282" clas4="lin48 name="L262"> 262
 283            strcmp argv[i]        -no_e  pr"         while (1) {
 274            sntation/usfputs(&i]ot;, fdect_error, 0         while (1) {
 285                         1oll(fd, 1, 1000);
 276         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L287" id="L287" clas4="lin48 name="L237"> 237
 278            strcmp argv[i]        -="L19data"         while (1) {
 242sta4Docum48 name="L279"> 279            ="L19tion/usfd>writ        while (1) {
 280                         1oll(fd, 1, 1000);
 49 name="L281"> 281         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L192" id="L192" clas4="lin49 name="L262"> 262
 213            strcmp argv[i]        -="L243data"         while (1) {
 274            ="L243"> 243writ        while (1) {
 285                         1oll(fd, 1, 1000);
 276         name="L282"> 282   _prin7U="Documentation[0]4t_printer4txt#L197" id="L197" clas4="lin49 name="L237"> 237
 278            strcmp argv[i]        -NB_="L19data"         while (1) {
 279            ="L19NB3"> 243writ        while (1) {
 280                         1oll(fd, 1, 1000);
 281         name="L282"> 282   _prin7U="Documentation[0]5t_printer5txt#L202" id="L202" clas5="lin50 name="L262"> 262
 213             while (1) {
 274        usage(argv[i]poll(fd, 1, 1000);
 285                 1oll(fd, 1, 1000);
 276 name="L282"> 282   _prin7U="Documentation[0]5t7printer5txt#L197" id="L197" clas5="lin50 name="L167"> 167        }
 188<      fd, PRINTER_FILE);
 282   _prin7U="Documentation[0]5t_printer5txt#L211" id="L211" clas5="lin51 name


The origin LXR software by ame="L282http://sourceforge.net/projects/lxt">LXR communityname, is> 1peri82lxt@d="ux.noname.
lxt.d="ux.no kindly hosted by ame="L282http://www.redpill-d="pro.no">Redpill L="pro ASname, provider of L="ux>consulErroranquot;ra> s ser /* s since 1995.