Deleted Added
full compact
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 ---