scsi_cmds.c (120428) | scsi_cmds.c (121184) |
---|---|
1/* 2 * SCSI Disk Emulator 3 * 4 * Copyright (c) 2002 Nate Lawson. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * | 1/* 2 * SCSI Disk Emulator 3 * 4 * Copyright (c) 2002 Nate Lawson. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 11 unchanged lines hidden (view full) --- 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/share/examples/scsi_target/scsi_cmds.c 120428 2003-09-25 05:43:26Z simokawa $ | 28 * $FreeBSD: head/share/examples/scsi_target/scsi_cmds.c 121184 2003-10-18 04:54:08Z simokawa $ |
29 */ 30 31#include <stdio.h> 32#include <stddef.h> 33#include <stdarg.h> 34#include <stdlib.h> 35#include <string.h> 36#include <err.h> 37#include <aio.h> 38#include <assert.h> | 29 */ 30 31#include <stdio.h> 32#include <stddef.h> 33#include <stdarg.h> 34#include <stdlib.h> 35#include <string.h> 36#include <err.h> 37#include <aio.h> 38#include <assert.h> |
39#include <sys/param.h> |
|
39#include <sys/types.h> 40 41#include <cam/cam.h> 42#include <cam/cam_ccb.h> 43#include <cam/scsi/scsi_all.h> 44#include <cam/scsi/scsi_targetio.h> 45#include "scsi_target.h" 46 --- 6 unchanged lines hidden (view full) --- 53 targ_start_func *start; 54 targ_done_func *done; 55#define ILLEGAL_CDB 0xFF 56}; 57 58static targ_start_func tcmd_inquiry; 59static targ_start_func tcmd_req_sense; 60static targ_start_func tcmd_rd_cap; | 40#include <sys/types.h> 41 42#include <cam/cam.h> 43#include <cam/cam_ccb.h> 44#include <cam/scsi/scsi_all.h> 45#include <cam/scsi/scsi_targetio.h> 46#include "scsi_target.h" 47 --- 6 unchanged lines hidden (view full) --- 54 targ_start_func *start; 55 targ_done_func *done; 56#define ILLEGAL_CDB 0xFF 57}; 58 59static targ_start_func tcmd_inquiry; 60static targ_start_func tcmd_req_sense; 61static targ_start_func tcmd_rd_cap; |
62#ifdef READ_16 63static targ_start_func tcmd_rd_cap16; 64#endif |
|
61static targ_start_func tcmd_rdwr; 62static targ_start_func tcmd_rdwr_decode; 63static targ_done_func tcmd_rdwr_done; 64static targ_start_func tcmd_null_ok; 65static targ_start_func tcmd_illegal_req; 66static int start_io(struct ccb_accept_tio *atio, 67 struct ccb_scsiio *ctio, int dir); 68static int init_inquiry(u_int16_t req_flags, u_int16_t sim_flags); --- 9 unchanged lines hidden (view full) --- 78 { INQUIRY, tcmd_inquiry, NULL }, 79 { REQUEST_SENSE, tcmd_req_sense, NULL }, 80 { READ_CAPACITY, tcmd_rd_cap, NULL }, 81 { TEST_UNIT_READY, tcmd_null_ok, NULL }, 82 { START_STOP_UNIT, tcmd_null_ok, NULL }, 83 { SYNCHRONIZE_CACHE, tcmd_null_ok, NULL }, 84 { MODE_SENSE_6, tcmd_illegal_req, NULL }, 85 { MODE_SELECT_6, tcmd_illegal_req, NULL }, | 65static targ_start_func tcmd_rdwr; 66static targ_start_func tcmd_rdwr_decode; 67static targ_done_func tcmd_rdwr_done; 68static targ_start_func tcmd_null_ok; 69static targ_start_func tcmd_illegal_req; 70static int start_io(struct ccb_accept_tio *atio, 71 struct ccb_scsiio *ctio, int dir); 72static int init_inquiry(u_int16_t req_flags, u_int16_t sim_flags); --- 9 unchanged lines hidden (view full) --- 82 { INQUIRY, tcmd_inquiry, NULL }, 83 { REQUEST_SENSE, tcmd_req_sense, NULL }, 84 { READ_CAPACITY, tcmd_rd_cap, NULL }, 85 { TEST_UNIT_READY, tcmd_null_ok, NULL }, 86 { START_STOP_UNIT, tcmd_null_ok, NULL }, 87 { SYNCHRONIZE_CACHE, tcmd_null_ok, NULL }, 88 { MODE_SENSE_6, tcmd_illegal_req, NULL }, 89 { MODE_SELECT_6, tcmd_illegal_req, NULL }, |
90#ifdef READ_16 91 { READ_16, tcmd_rdwr, tcmd_rdwr_done }, 92 { WRITE_16, tcmd_rdwr, tcmd_rdwr_done }, 93 { SERVICE_ACTION_IN, tcmd_rd_cap16, NULL }, 94#endif |
|
86 { ILLEGAL_CDB, NULL, NULL } 87}; 88 89static struct scsi_inquiry_data inq_data; 90static struct initiator_state istates[MAX_INITIATORS]; 91extern int debug; | 95 { ILLEGAL_CDB, NULL, NULL } 96}; 97 98static struct scsi_inquiry_data inq_data; 99static struct initiator_state istates[MAX_INITIATORS]; 100extern int debug; |
92extern u_int32_t volume_size; | 101extern uint64_t volume_size; |
93extern size_t sector_size; 94extern size_t buf_size; 95 96cam_status 97tcmd_init(u_int16_t req_inq_flags, u_int16_t sim_inq_flags) 98{ 99 struct initiator_state *istate; 100 int i, ret; --- 292 unchanged lines hidden (view full) --- 393 return (0); 394} 395 396static int 397tcmd_rd_cap(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 398{ 399 struct scsi_read_capacity_data *srp; 400 struct atio_descr *a_descr; | 102extern size_t sector_size; 103extern size_t buf_size; 104 105cam_status 106tcmd_init(u_int16_t req_inq_flags, u_int16_t sim_inq_flags) 107{ 108 struct initiator_state *istate; 109 int i, ret; --- 292 unchanged lines hidden (view full) --- 402 return (0); 403} 404 405static int 406tcmd_rd_cap(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 407{ 408 struct scsi_read_capacity_data *srp; 409 struct atio_descr *a_descr; |
410 uint32_t vsize; |
|
401 402 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 403 srp = (struct scsi_read_capacity_data *)ctio->data_ptr; 404 | 411 412 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 413 srp = (struct scsi_read_capacity_data *)ctio->data_ptr; 414 |
415 if (volume_size > 0xffffffff) 416 vsize = 0xffffffff; 417 else 418 vsize = (uint32_t)(volume_size - 1); 419 |
|
405 if (debug) { 406 cdb_debug(a_descr->cdb, "READ CAP from %u (%u, %u): ", | 420 if (debug) { 421 cdb_debug(a_descr->cdb, "READ CAP from %u (%u, %u): ", |
422 atio->init_id, vsize, sector_size); 423 } 424 425 bzero(srp, sizeof(*srp)); 426 scsi_ulto4b(vsize, srp->addr); 427 scsi_ulto4b(sector_size, srp->length); 428 429 ctio->dxfer_len = sizeof(*srp); 430 ctio->ccb_h.flags |= CAM_DIR_IN | CAM_SEND_STATUS; 431 ctio->scsi_status = SCSI_STATUS_OK; 432 return (0); 433} 434 435#ifdef READ_16 436static int 437tcmd_rd_cap16(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 438{ 439 struct scsi_read_capacity_16 *scsi_cmd; 440 struct scsi_read_capacity_data_long *srp; 441 struct atio_descr *a_descr; 442 443 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 444 scsi_cmd = (struct scsi_read_capacity_16 *)a_descr->cdb; 445 srp = (struct scsi_read_capacity_data_long *)ctio->data_ptr; 446 447 if (scsi_cmd->service_action != SRC16_SERVICE_ACTION) { 448 tcmd_illegal_req(atio, ctio); 449 return (0); 450 } 451 452 if (debug) { 453 cdb_debug(a_descr->cdb, "READ CAP16 from %u (%u, %u): ", |
|
407 atio->init_id, volume_size - 1, sector_size); 408 } 409 410 bzero(srp, sizeof(*srp)); | 454 atio->init_id, volume_size - 1, sector_size); 455 } 456 457 bzero(srp, sizeof(*srp)); |
411 scsi_ulto4b(volume_size - 1, srp->addr); | 458 scsi_u64to8b(volume_size - 1, srp->addr); |
412 scsi_ulto4b(sector_size, srp->length); 413 414 ctio->dxfer_len = sizeof(*srp); 415 ctio->ccb_h.flags |= CAM_DIR_IN | CAM_SEND_STATUS; 416 ctio->scsi_status = SCSI_STATUS_OK; 417 return (0); 418} | 459 scsi_ulto4b(sector_size, srp->length); 460 461 ctio->dxfer_len = sizeof(*srp); 462 ctio->ccb_h.flags |= CAM_DIR_IN | CAM_SEND_STATUS; 463 ctio->scsi_status = SCSI_STATUS_OK; 464 return (0); 465} |
466#endif |
|
419 420static int 421tcmd_rdwr(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 422{ 423 struct atio_descr *a_descr; 424 struct ctio_descr *c_descr; 425 int ret; 426 --- 11 unchanged lines hidden (view full) --- 438 } 439 } 440 ctio->ccb_h.flags |= a_descr->flags; 441 442 /* Call appropriate work function */ 443 if ((a_descr->flags & CAM_DIR_IN) != 0) { 444 ret = start_io(atio, ctio, CAM_DIR_IN); 445 if (debug) | 467 468static int 469tcmd_rdwr(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 470{ 471 struct atio_descr *a_descr; 472 struct ctio_descr *c_descr; 473 int ret; 474 --- 11 unchanged lines hidden (view full) --- 486 } 487 } 488 ctio->ccb_h.flags |= a_descr->flags; 489 490 /* Call appropriate work function */ 491 if ((a_descr->flags & CAM_DIR_IN) != 0) { 492 ret = start_io(atio, ctio, CAM_DIR_IN); 493 if (debug) |
446 warnx("Starting DIR_IN @%lld:%u", c_descr->offset, 447 a_descr->targ_req); | 494#if __FreeBSD_version >= 500000 495 warnx("Starting DIR_IN @%jd:%u", 496#else 497 warnx("Starting DIR_IN @%lld:%u", 498#endif 499 c_descr->offset, a_descr->targ_req); |
448 } else { 449 ret = start_io(atio, ctio, CAM_DIR_OUT); 450 if (debug) | 500 } else { 501 ret = start_io(atio, ctio, CAM_DIR_OUT); 502 if (debug) |
451 warnx("Starting DIR_OUT @%lld:%u", c_descr->offset, 452 a_descr->init_req); | 503#if __FreeBSD_version >= 500000 504 warnx("Starting DIR_OUT @%jd:%u", 505#else 506 warnx("Starting DIR_OUT @%lld:%u", 507#endif 508 c_descr->offset, a_descr->init_req); |
453 } 454 455 return (ret); 456} 457 458static int 459tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 460{ | 509 } 510 511 return (ret); 512} 513 514static int 515tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) 516{ |
461 u_int32_t blkno, count; | 517 uint64_t blkno; 518 uint32_t count; |
462 struct atio_descr *a_descr; 463 u_int8_t *cdb; 464 465 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 466 cdb = a_descr->cdb; 467 if (debug) 468 cdb_debug(cdb, "R/W from %u: ", atio->init_id); 469 | 519 struct atio_descr *a_descr; 520 u_int8_t *cdb; 521 522 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr; 523 cdb = a_descr->cdb; 524 if (debug) 525 cdb_debug(cdb, "R/W from %u: ", atio->init_id); 526 |
470 if (cdb[0] == READ_6 || cdb[0] == WRITE_6) { | 527 switch (cdb[0]) { 528 case READ_6: 529 case WRITE_6: 530 { |
471 struct scsi_rw_6 *rw_6 = (struct scsi_rw_6 *)cdb; 472 blkno = scsi_3btoul(rw_6->addr); 473 count = rw_6->length; | 531 struct scsi_rw_6 *rw_6 = (struct scsi_rw_6 *)cdb; 532 blkno = scsi_3btoul(rw_6->addr); 533 count = rw_6->length; |
474 } else { | 534 break; 535 } 536 case READ_10: 537 case WRITE_10: 538 { |
475 struct scsi_rw_10 *rw_10 = (struct scsi_rw_10 *)cdb; 476 blkno = scsi_4btoul(rw_10->addr); 477 count = scsi_2btoul(rw_10->length); | 539 struct scsi_rw_10 *rw_10 = (struct scsi_rw_10 *)cdb; 540 blkno = scsi_4btoul(rw_10->addr); 541 count = scsi_2btoul(rw_10->length); |
542 break; |
|
478 } | 543 } |
544#ifdef READ_16 545 case READ_16: 546 case WRITE_16: 547 { 548 struct scsi_rw_16 *rw_16 = (struct scsi_rw_16 *)cdb; 549 blkno = scsi_8btou64(rw_16->addr); 550 count = scsi_4btoul(rw_16->length); 551 break; 552 } 553#endif 554 default: 555 tcmd_illegal_req(atio, ctio); 556 return (0); 557 } |
|
479 if (blkno + count > volume_size) { 480 warnx("Attempt to access past end of volume"); 481 tcmd_sense(ctio->init_id, ctio, 482 SSD_KEY_ILLEGAL_REQUEST, 0x21, 0); 483 return (0); 484 } 485 486 /* Get an (overall) data length and set direction */ 487 a_descr->base_off = ((off_t)blkno) * sector_size; 488 a_descr->total_len = count * sector_size; 489 if (a_descr->total_len == 0) { 490 if (debug) | 558 if (blkno + count > volume_size) { 559 warnx("Attempt to access past end of volume"); 560 tcmd_sense(ctio->init_id, ctio, 561 SSD_KEY_ILLEGAL_REQUEST, 0x21, 0); 562 return (0); 563 } 564 565 /* Get an (overall) data length and set direction */ 566 a_descr->base_off = ((off_t)blkno) * sector_size; 567 a_descr->total_len = count * sector_size; 568 if (a_descr->total_len == 0) { 569 if (debug) |
491 warnx("r/w 0 blocks @ blkno %u", blkno); | 570#if __FreeBSD_version >= 500000 571 warnx("r/w 0 blocks @ blkno %ju", blkno); 572#else 573 warnx("r/w 0 blocks @ blkno %llu", blkno); 574#endif |
492 tcmd_null_ok(atio, ctio); 493 return (0); 494 } else if (cdb[0] == WRITE_6 || cdb[0] == WRITE_10) { 495 a_descr->flags |= CAM_DIR_OUT; 496 if (debug) | 575 tcmd_null_ok(atio, ctio); 576 return (0); 577 } else if (cdb[0] == WRITE_6 || cdb[0] == WRITE_10) { 578 a_descr->flags |= CAM_DIR_OUT; 579 if (debug) |
497 warnx("write %u blocks @ blkno %u", count, blkno); | 580#if __FreeBSD_version >= 500000 581 warnx("write %u blocks @ blkno %ju", count, blkno); 582#else 583 warnx("write %u blocks @ blkno %llu", count, blkno); 584#endif |
498 } else { 499 a_descr->flags |= CAM_DIR_IN; 500 if (debug) | 585 } else { 586 a_descr->flags |= CAM_DIR_IN; 587 if (debug) |
501 warnx("read %u blocks @ blkno %u", count, blkno); | 588#if __FreeBSD_version >= 500000 589 warnx("read %u blocks @ blkno %ju", count, blkno); 590#else 591 warnx("read %u blocks @ blkno %llu", count, blkno); 592#endif |
502 } 503 return (1); 504} 505 506static int 507start_io(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio, int dir) 508{ 509 struct atio_descr *a_descr; --- 159 unchanged lines hidden --- | 593 } 594 return (1); 595} 596 597static int 598start_io(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio, int dir) 599{ 600 struct atio_descr *a_descr; --- 159 unchanged lines hidden --- |