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