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