scsi_cmdparse.c (84199) | scsi_cmdparse.c (88090) |
---|---|
1/* 2 * Taken from the original FreeBSD user SCSI library. 3 */ 4/* Copyright (c) 1994 HD Associates 5 * (contact: dufault@hda.com) 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 21 unchanged lines hidden (view full) --- 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * From: scsi.c,v 1.8 1997/02/22 15:07:54 peter Exp $ 35 */ 36 37#include <sys/cdefs.h> | 1/* 2 * Taken from the original FreeBSD user SCSI library. 3 */ 4/* Copyright (c) 1994 HD Associates 5 * (contact: dufault@hda.com) 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 21 unchanged lines hidden (view full) --- 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * From: scsi.c,v 1.8 1997/02/22 15:07:54 peter Exp $ 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/lib/libcam/scsi_cmdparse.c 84199 2001-09-30 21:13:43Z dillon $"); | 38__FBSDID("$FreeBSD: head/lib/libcam/scsi_cmdparse.c 88090 2001-12-18 00:48:44Z kbyanc $"); |
39 40#include <stdlib.h> 41#include <stdio.h> 42#include <ctype.h> 43#include <string.h> 44#include <sys/errno.h> 45#include <stdarg.h> 46#include <fcntl.h> --- 48 unchanged lines hidden (view full) --- 95 * BUGS: 96 * i and b types are promoted to ints. 97 * 98 */ 99 100static int 101do_buff_decode(u_int8_t *databuf, size_t len, 102 void (*arg_put)(void *, int , void *, int, char *), | 39 40#include <stdlib.h> 41#include <stdio.h> 42#include <ctype.h> 43#include <string.h> 44#include <sys/errno.h> 45#include <stdarg.h> 46#include <fcntl.h> --- 48 unchanged lines hidden (view full) --- 95 * BUGS: 96 * i and b types are promoted to ints. 97 * 98 */ 99 100static int 101do_buff_decode(u_int8_t *databuf, size_t len, 102 void (*arg_put)(void *, int , void *, int, char *), |
103 void *puthook, char *fmt, va_list ap) | 103 void *puthook, const char *fmt, va_list ap) |
104{ 105 int assigned = 0; 106 int width; 107 int suppress; 108 int plus; 109 int done = 0; 110 static u_char mask[] = {0, 0x01, 0x03, 0x07, 0x0f, 111 0x1f, 0x3f, 0x7f, 0xff}; 112 int value; 113 u_char *base = databuf; | 104{ 105 int assigned = 0; 106 int width; 107 int suppress; 108 int plus; 109 int done = 0; 110 static u_char mask[] = {0, 0x01, 0x03, 0x07, 0x0f, 111 0x1f, 0x3f, 0x7f, 0xff}; 112 int value; 113 u_char *base = databuf; |
114 char *intendp; |
|
114 char letter; 115 char field_name[80]; 116 117# define ARG_PUT(ARG) \ 118 do \ 119 { \ 120 if (!suppress) \ 121 { \ --- 51 unchanged lines hidden (view full) --- 173 fmt++; /* Skip '}' */ 174 field_name[i] = 0; 175 break; 176 } 177 178 case 't': /* Bit (field) */ 179 case 'b': /* Bits */ 180 fmt++; | 115 char letter; 116 char field_name[80]; 117 118# define ARG_PUT(ARG) \ 119 do \ 120 { \ 121 if (!suppress) \ 122 { \ --- 51 unchanged lines hidden (view full) --- 174 fmt++; /* Skip '}' */ 175 field_name[i] = 0; 176 break; 177 } 178 179 case 't': /* Bit (field) */ 180 case 'b': /* Bits */ 181 fmt++; |
181 width = strtol(fmt, &fmt, 10); | 182 width = strtol(fmt, &intendp, 10); 183 fmt = intendp; |
182 if (width > 8) 183 done = 1; 184 else { 185 if (shift <= 0) { 186 bits = *databuf++; 187 shift = 8; 188 } 189 value = (bits >> (shift - width)) & --- 8 unchanged lines hidden (view full) --- 198 199 shift -= width; 200 } 201 break; 202 203 case 'i': /* Integral values */ 204 shift = 0; 205 fmt++; | 184 if (width > 8) 185 done = 1; 186 else { 187 if (shift <= 0) { 188 bits = *databuf++; 189 shift = 8; 190 } 191 value = (bits >> (shift - width)) & --- 8 unchanged lines hidden (view full) --- 200 201 shift -= width; 202 } 203 break; 204 205 case 'i': /* Integral values */ 206 shift = 0; 207 fmt++; |
206 width = strtol(fmt, &fmt, 10); | 208 width = strtol(fmt, &intendp, 10); 209 fmt = intendp; |
207 switch(width) { 208 case 1: 209 ARG_PUT(*databuf); 210 databuf++; 211 break; 212 213 case 2: 214 ARG_PUT((*databuf) << 8 | *(databuf + 1)); --- 21 unchanged lines hidden (view full) --- 236 237 break; 238 239 case 'c': /* Characters (i.e., not swapped) */ 240 case 'z': /* Characters with zeroed trailing 241 spaces */ 242 shift = 0; 243 fmt++; | 210 switch(width) { 211 case 1: 212 ARG_PUT(*databuf); 213 databuf++; 214 break; 215 216 case 2: 217 ARG_PUT((*databuf) << 8 | *(databuf + 1)); --- 21 unchanged lines hidden (view full) --- 239 240 break; 241 242 case 'c': /* Characters (i.e., not swapped) */ 243 case 'z': /* Characters with zeroed trailing 244 spaces */ 245 shift = 0; 246 fmt++; |
244 width = strtol(fmt, &fmt, 10); | 247 width = strtol(fmt, &intendp, 10); 248 fmt = intendp; |
245 if (!suppress) { 246 if (arg_put) 247 (*arg_put)(puthook, 248 (letter == 't' ? 'b' : letter), 249 databuf, width, field_name); 250 else { 251 char *dest; 252 dest = va_arg(ap, char *); --- 25 unchanged lines hidden (view full) --- 278 if (tolower(*fmt) == 'v') { 279 /* 280 * You can't suppress a seek value. You also 281 * can't have a variable seek when you are using 282 * "arg_put". 283 */ 284 width = (arg_put) ? 0 : va_arg(ap, int); 285 fmt++; | 249 if (!suppress) { 250 if (arg_put) 251 (*arg_put)(puthook, 252 (letter == 't' ? 'b' : letter), 253 databuf, width, field_name); 254 else { 255 char *dest; 256 dest = va_arg(ap, char *); --- 25 unchanged lines hidden (view full) --- 282 if (tolower(*fmt) == 'v') { 283 /* 284 * You can't suppress a seek value. You also 285 * can't have a variable seek when you are using 286 * "arg_put". 287 */ 288 width = (arg_put) ? 0 : va_arg(ap, int); 289 fmt++; |
286 } else 287 width = strtol(fmt, &fmt, 10); | 290 } else { 291 width = strtol(fmt, &intendp, 10); 292 fmt = intendp; 293 } |
288 289 if (plus) 290 databuf += width; /* Relative seek */ 291 else 292 databuf = base + width; /* Absolute seek */ 293 294 break; 295 --- 40 unchanged lines hidden (view full) --- 336 * The function returns the value: 337 * 0: For reached end, with error_p set if an error was found 338 * 1: For valid stuff setup 339 * 2: For "v" was entered as the value (implies use varargs) 340 * 341 */ 342 343static int | 294 295 if (plus) 296 databuf += width; /* Relative seek */ 297 else 298 databuf = base + width; /* Absolute seek */ 299 300 break; 301 --- 40 unchanged lines hidden (view full) --- 342 * The function returns the value: 343 * 0: For reached end, with error_p set if an error was found 344 * 1: For valid stuff setup 345 * 2: For "v" was entered as the value (implies use varargs) 346 * 347 */ 348 349static int |
344next_field(char **pp, char *fmt, int *width_p, int *value_p, char *name, | 350next_field(const char **pp, char *fmt, int *width_p, int *value_p, char *name, |
345 int n_name, int *error_p, int *suppress_p) 346{ | 351 int n_name, int *error_p, int *suppress_p) 352{ |
347 char *p = *pp; | 353 const char *p = *pp; 354 char *intendp; |
348 349 int something = 0; 350 351 enum { 352 BETWEEN_FIELDS, 353 START_FIELD, 354 GET_FIELD, 355 DONE, --- 43 unchanged lines hidden (view full) --- 399 400 if (*p == '}') 401 p++; 402 } else if (*p == '*') { 403 p++; 404 suppress = 1; 405 } else if (isxdigit(*p)) { 406 something = 1; | 355 356 int something = 0; 357 358 enum { 359 BETWEEN_FIELDS, 360 START_FIELD, 361 GET_FIELD, 362 DONE, --- 43 unchanged lines hidden (view full) --- 406 407 if (*p == '}') 408 p++; 409 } else if (*p == '*') { 410 p++; 411 suppress = 1; 412 } else if (isxdigit(*p)) { 413 something = 1; |
407 value = strtol(p, &p, 16); | 414 value = strtol(p, &intendp, 16); 415 p = intendp; |
408 state = START_FIELD; 409 } else if (tolower(*p) == 'v') { 410 p++; 411 something = 2; 412 value = *value_p; 413 state = START_FIELD; 414 } else if (tolower(*p) == 'i') { 415 /* 416 * Try to work without the "v". 417 */ 418 something = 2; 419 value = *value_p; 420 p++; 421 422 *fmt = 'i'; 423 field_size = 8; | 416 state = START_FIELD; 417 } else if (tolower(*p) == 'v') { 418 p++; 419 something = 2; 420 value = *value_p; 421 state = START_FIELD; 422 } else if (tolower(*p) == 'i') { 423 /* 424 * Try to work without the "v". 425 */ 426 something = 2; 427 value = *value_p; 428 p++; 429 430 *fmt = 'i'; 431 field_size = 8; |
424 field_width = strtol(p, &p, 10); | 432 field_width = strtol(p, &intendp, 10); 433 p = intendp; |
425 state = DONE; 426 427 } else if (tolower(*p) == 't') { 428 /* 429 * XXX: B can't work: Sees the 'b' as a 430 * hex digit in "isxdigit". try "t" for 431 * bit field. 432 */ 433 something = 2; 434 value = *value_p; 435 p++; 436 437 *fmt = 'b'; 438 field_size = 1; | 434 state = DONE; 435 436 } else if (tolower(*p) == 't') { 437 /* 438 * XXX: B can't work: Sees the 'b' as a 439 * hex digit in "isxdigit". try "t" for 440 * bit field. 441 */ 442 something = 2; 443 value = *value_p; 444 p++; 445 446 *fmt = 'b'; 447 field_size = 1; |
439 field_width = strtol(p, &p, 10); | 448 field_width = strtol(p, &intendp, 10); 449 p = intendp; |
440 state = DONE; 441 } else if (tolower(*p) == 's') { 442 /* Seek */ 443 *fmt = 's'; 444 p++; 445 if (tolower(*p) == 'v') { 446 p++; 447 something = 2; 448 value = *value_p; 449 } else { 450 something = 1; | 450 state = DONE; 451 } else if (tolower(*p) == 's') { 452 /* Seek */ 453 *fmt = 's'; 454 p++; 455 if (tolower(*p) == 'v') { 456 p++; 457 something = 2; 458 value = *value_p; 459 } else { 460 something = 1; |
451 value = strtol(p, &p, 0); | 461 value = strtol(p, &intendp, 0); 462 p = intendp; |
452 } 453 state = DONE; 454 } else { 455 fprintf(stderr, "Invalid starting " 456 "character: %c\n", *p); 457 is_error = 1; 458 state = DONE; 459 } --- 8 unchanged lines hidden (view full) --- 468 } else 469 state = DONE; 470 break; 471 472 case GET_FIELD: 473 if (isdigit(*p)) { 474 *fmt = 'b'; 475 field_size = 1; | 463 } 464 state = DONE; 465 } else { 466 fprintf(stderr, "Invalid starting " 467 "character: %c\n", *p); 468 is_error = 1; 469 state = DONE; 470 } --- 8 unchanged lines hidden (view full) --- 479 } else 480 state = DONE; 481 break; 482 483 case GET_FIELD: 484 if (isdigit(*p)) { 485 *fmt = 'b'; 486 field_size = 1; |
476 field_width = strtol(p, &p, 10); | 487 field_width = strtol(p, &intendp, 10); 488 p = intendp; |
477 state = DONE; 478 } else if (*p == 'i') { 479 480 /* Integral (bytes) */ 481 p++; 482 483 *fmt = 'i'; 484 field_size = 8; | 489 state = DONE; 490 } else if (*p == 'i') { 491 492 /* Integral (bytes) */ 493 p++; 494 495 *fmt = 'i'; 496 field_size = 8; |
485 field_width = strtol(p, &p, 10); | 497 field_width = strtol(p, &intendp, 10); 498 p = intendp; |
486 state = DONE; 487 } else if (*p == 'b') { 488 489 /* Bits */ 490 p++; 491 492 *fmt = 'b'; 493 field_size = 1; | 499 state = DONE; 500 } else if (*p == 'b') { 501 502 /* Bits */ 503 p++; 504 505 *fmt = 'b'; 506 field_size = 1; |
494 field_width = strtol(p, &p, 10); | 507 field_width = strtol(p, &intendp, 10); 508 p = intendp; |
495 state = DONE; 496 } else { 497 fprintf(stderr, "Invalid startfield %c " 498 "(%02x)\n", *p, *p); 499 is_error = 1; 500 state = DONE; 501 } 502 break; --- 14 unchanged lines hidden (view full) --- 517 *value_p = value; 518 *suppress_p = suppress; 519 520 return (something); 521} 522 523static int 524do_encode(u_char *buff, size_t vec_max, size_t *used, | 509 state = DONE; 510 } else { 511 fprintf(stderr, "Invalid startfield %c " 512 "(%02x)\n", *p, *p); 513 is_error = 1; 514 state = DONE; 515 } 516 break; --- 14 unchanged lines hidden (view full) --- 531 *value_p = value; 532 *suppress_p = suppress; 533 534 return (something); 535} 536 537static int 538do_encode(u_char *buff, size_t vec_max, size_t *used, |
525 int (*arg_get)(void *, char *), void *gethook, char *fmt, va_list ap) | 539 int (*arg_get)(void *, char *), void *gethook, const char *fmt, 540 va_list ap) |
526{ 527 int ind; 528 int shift; 529 u_char val; 530 int ret; 531 int width, value, error, suppress; 532 char c; 533 int encoded = 0; --- 103 unchanged lines hidden (view full) --- 637 638 if (error) 639 return -1; 640 641 return encoded; 642} 643 644int | 541{ 542 int ind; 543 int shift; 544 u_char val; 545 int ret; 546 int width, value, error, suppress; 547 char c; 548 int encoded = 0; --- 103 unchanged lines hidden (view full) --- 652 653 if (error) 654 return -1; 655 656 return encoded; 657} 658 659int |
645csio_decode(struct ccb_scsiio *csio, char *fmt, ...) | 660csio_decode(struct ccb_scsiio *csio, const char *fmt, ...) |
646{ 647 va_list ap; 648 649 va_start(ap, fmt); 650 651 return(do_buff_decode(csio->data_ptr, (size_t)csio->dxfer_len, 652 0, 0, fmt, ap)); 653} 654 655int | 661{ 662 va_list ap; 663 664 va_start(ap, fmt); 665 666 return(do_buff_decode(csio->data_ptr, (size_t)csio->dxfer_len, 667 0, 0, fmt, ap)); 668} 669 670int |
656csio_decode_visit(struct ccb_scsiio *csio, char *fmt, | 671csio_decode_visit(struct ccb_scsiio *csio, const char *fmt, |
657 void (*arg_put)(void *, int, void *, int, char *), 658 void *puthook) 659{ 660 va_list ap; 661 662 /* 663 * We need some way to output things; we can't do it without 664 * the arg_put function. 665 */ 666 if (arg_put == NULL) 667 return(-1); 668 669 bzero(&ap, sizeof(ap)); 670 671 return(do_buff_decode(csio->data_ptr, (size_t)csio->dxfer_len, 672 arg_put, puthook, fmt, ap)); 673} 674 675int | 672 void (*arg_put)(void *, int, void *, int, char *), 673 void *puthook) 674{ 675 va_list ap; 676 677 /* 678 * We need some way to output things; we can't do it without 679 * the arg_put function. 680 */ 681 if (arg_put == NULL) 682 return(-1); 683 684 bzero(&ap, sizeof(ap)); 685 686 return(do_buff_decode(csio->data_ptr, (size_t)csio->dxfer_len, 687 arg_put, puthook, fmt, ap)); 688} 689 690int |
676buff_decode(u_int8_t *buff, size_t len, char *fmt, ...) | 691buff_decode(u_int8_t *buff, size_t len, const char *fmt, ...) |
677{ 678 va_list ap; 679 680 va_start(ap, fmt); 681 682 return(do_buff_decode(buff, len, 0, 0, fmt, ap)); 683} 684 685int | 692{ 693 va_list ap; 694 695 va_start(ap, fmt); 696 697 return(do_buff_decode(buff, len, 0, 0, fmt, ap)); 698} 699 700int |
686buff_decode_visit(u_int8_t *buff, size_t len, char *fmt, | 701buff_decode_visit(u_int8_t *buff, size_t len, const char *fmt, |
687 void (*arg_put)(void *, int, void *, int, char *), 688 void *puthook) 689{ 690 va_list ap; 691 692 /* 693 * We need some way to output things; we can't do it without 694 * the arg_put function. --- 7 unchanged lines hidden (view full) --- 702} 703 704/* 705 * Build a SCSI CCB, given the command and data pointers and a format 706 * string describing the 707 */ 708int 709csio_build(struct ccb_scsiio *csio, u_int8_t *data_ptr, u_int32_t dxfer_len, | 702 void (*arg_put)(void *, int, void *, int, char *), 703 void *puthook) 704{ 705 va_list ap; 706 707 /* 708 * We need some way to output things; we can't do it without 709 * the arg_put function. --- 7 unchanged lines hidden (view full) --- 717} 718 719/* 720 * Build a SCSI CCB, given the command and data pointers and a format 721 * string describing the 722 */ 723int 724csio_build(struct ccb_scsiio *csio, u_int8_t *data_ptr, u_int32_t dxfer_len, |
710 u_int32_t flags, int retry_count, int timeout, char *cmd_spec, ...) | 725 u_int32_t flags, int retry_count, int timeout, const char *cmd_spec, 726 ...) |
711{ 712 size_t cmdlen; 713 int retval; 714 va_list ap; 715 716 if (csio == NULL) 717 return(0); 718 --- 17 unchanged lines hidden (view full) --- 736 /* timeout */ timeout ? timeout : 5000); 737 738 return(retval); 739} 740 741int 742csio_build_visit(struct ccb_scsiio *csio, u_int8_t *data_ptr, 743 u_int32_t dxfer_len, u_int32_t flags, int retry_count, | 727{ 728 size_t cmdlen; 729 int retval; 730 va_list ap; 731 732 if (csio == NULL) 733 return(0); 734 --- 17 unchanged lines hidden (view full) --- 752 /* timeout */ timeout ? timeout : 5000); 753 754 return(retval); 755} 756 757int 758csio_build_visit(struct ccb_scsiio *csio, u_int8_t *data_ptr, 759 u_int32_t dxfer_len, u_int32_t flags, int retry_count, |
744 int timeout, char *cmd_spec, | 760 int timeout, const char *cmd_spec, |
745 int (*arg_get)(void *hook, char *field_name), void *gethook) 746{ 747 va_list ap; 748 size_t cmdlen; 749 int retval; 750 751 if (csio == NULL) 752 return(0); --- 23 unchanged lines hidden (view full) --- 776 /* sense_len */ SSD_FULL_SIZE, 777 /* cdb_len */ cmdlen, 778 /* timeout */ timeout ? timeout : 5000); 779 780 return(retval); 781} 782 783int | 761 int (*arg_get)(void *hook, char *field_name), void *gethook) 762{ 763 va_list ap; 764 size_t cmdlen; 765 int retval; 766 767 if (csio == NULL) 768 return(0); --- 23 unchanged lines hidden (view full) --- 792 /* sense_len */ SSD_FULL_SIZE, 793 /* cdb_len */ cmdlen, 794 /* timeout */ timeout ? timeout : 5000); 795 796 return(retval); 797} 798 799int |
784csio_encode(struct ccb_scsiio *csio, char *fmt, ...) | 800csio_encode(struct ccb_scsiio *csio, const char *fmt, ...) |
785{ 786 va_list ap; 787 788 if (csio == NULL) 789 return(0); 790 791 va_start(ap, fmt); 792 793 return(do_encode(csio->data_ptr, csio->dxfer_len, 0, 0, 0, fmt, ap)); 794} 795 796int | 801{ 802 va_list ap; 803 804 if (csio == NULL) 805 return(0); 806 807 va_start(ap, fmt); 808 809 return(do_encode(csio->data_ptr, csio->dxfer_len, 0, 0, 0, fmt, ap)); 810} 811 812int |
797buff_encode_visit(u_int8_t *buff, size_t len, char *fmt, | 813buff_encode_visit(u_int8_t *buff, size_t len, const char *fmt, |
798 int (*arg_get)(void *hook, char *field_name), void *gethook) 799{ 800 va_list ap; 801 802 /* 803 * We need something to encode, but we can't get it without the 804 * arg_get function. 805 */ 806 if (arg_get == NULL) 807 return(-1); 808 809 bzero(&ap, sizeof(ap)); 810 811 return(do_encode(buff, len, 0, arg_get, gethook, fmt, ap)); 812} 813 814int | 814 int (*arg_get)(void *hook, char *field_name), void *gethook) 815{ 816 va_list ap; 817 818 /* 819 * We need something to encode, but we can't get it without the 820 * arg_get function. 821 */ 822 if (arg_get == NULL) 823 return(-1); 824 825 bzero(&ap, sizeof(ap)); 826 827 return(do_encode(buff, len, 0, arg_get, gethook, fmt, ap)); 828} 829 830int |
815csio_encode_visit(struct ccb_scsiio *csio, char *fmt, | 831csio_encode_visit(struct ccb_scsiio *csio, const char *fmt, |
816 int (*arg_get)(void *hook, char *field_name), void *gethook) 817{ 818 va_list ap; 819 820 /* 821 * We need something to encode, but we can't get it without the 822 * arg_get function. 823 */ 824 if (arg_get == NULL) 825 return(-1); 826 827 bzero(&ap, sizeof(ap)); 828 829 return(do_encode(csio->data_ptr, csio->dxfer_len, 0, arg_get, 830 gethook, fmt, ap)); 831} | 832 int (*arg_get)(void *hook, char *field_name), void *gethook) 833{ 834 va_list ap; 835 836 /* 837 * We need something to encode, but we can't get it without the 838 * arg_get function. 839 */ 840 if (arg_get == NULL) 841 return(-1); 842 843 bzero(&ap, sizeof(ap)); 844 845 return(do_encode(csio->data_ptr, csio->dxfer_len, 0, arg_get, 846 gethook, fmt, ap)); 847} |