Deleted Added
full compact
scsi_cmds.c (157670) scsi_cmds.c (162704)
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 157670 2006-04-11 21:36:43Z mjacob $
28 * $FreeBSD: head/share/examples/scsi_target/scsi_cmds.c 162704 2006-09-27 15:38:13Z mjacob $
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>
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 <unistd.h>
38#include <assert.h>
39#include <sys/param.h>
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>

--- 309 unchanged lines hidden (view full) ---

355 */
356 if ((req_flags & SID_Addr16) != 0) {
357 sim_flags |= SID_Addr16;
358 warnx("Not sure SIM supports Addr16 but enabling it anyway");
359 }
360
361 /* Advertise only what the SIM can actually support */
362 req_flags &= sim_flags;
39#include <assert.h>
40#include <sys/param.h>
41#include <sys/types.h>
42
43#include <cam/cam.h>
44#include <cam/cam_ccb.h>
45#include <cam/scsi/scsi_all.h>
46#include <cam/scsi/scsi_targetio.h>

--- 309 unchanged lines hidden (view full) ---

356 */
357 if ((req_flags & SID_Addr16) != 0) {
358 sim_flags |= SID_Addr16;
359 warnx("Not sure SIM supports Addr16 but enabling it anyway");
360 }
361
362 /* Advertise only what the SIM can actually support */
363 req_flags &= sim_flags;
363 scsi_ulto2b(req_flags, &inq->reserved[1]);
364 scsi_ulto2b(req_flags, &inq->spc2_flags);
364
365 inq->response_format = 2; /* SCSI2 Inquiry Format */
366 inq->additional_length = SHORT_INQUIRY_LENGTH -
367 offsetof(struct scsi_inquiry_data, additional_length);
368 bcopy("FreeBSD ", inq->vendor, SID_VENDOR_SIZE);
369 bcopy("Emulated Disk ", inq->product, SID_PRODUCT_SIZE);
370 bcopy("0.1 ", inq->revision, SID_REVISION_SIZE);
371 return (0);

--- 119 unchanged lines hidden (view full) ---

491 }
492 }
493 ctio->ccb_h.flags |= a_descr->flags;
494
495 /* Call appropriate work function */
496 if ((a_descr->flags & CAM_DIR_IN) != 0) {
497 ret = start_io(atio, ctio, CAM_DIR_IN);
498 if (debug)
365
366 inq->response_format = 2; /* SCSI2 Inquiry Format */
367 inq->additional_length = SHORT_INQUIRY_LENGTH -
368 offsetof(struct scsi_inquiry_data, additional_length);
369 bcopy("FreeBSD ", inq->vendor, SID_VENDOR_SIZE);
370 bcopy("Emulated Disk ", inq->product, SID_PRODUCT_SIZE);
371 bcopy("0.1 ", inq->revision, SID_REVISION_SIZE);
372 return (0);

--- 119 unchanged lines hidden (view full) ---

492 }
493 }
494 ctio->ccb_h.flags |= a_descr->flags;
495
496 /* Call appropriate work function */
497 if ((a_descr->flags & CAM_DIR_IN) != 0) {
498 ret = start_io(atio, ctio, CAM_DIR_IN);
499 if (debug)
499#if __FreeBSD_version >= 500000
500 warnx("Starting DIR_IN @%jd:%u",
501#else
502 warnx("Starting DIR_IN @%lld:%u",
503#endif
504 c_descr->offset, a_descr->targ_req);
500 warnx("Starting %p DIR_IN @" OFF_FMT ":%u",
501 a_descr, c_descr->offset, a_descr->targ_req);
505 } else {
506 ret = start_io(atio, ctio, CAM_DIR_OUT);
507 if (debug)
502 } else {
503 ret = start_io(atio, ctio, CAM_DIR_OUT);
504 if (debug)
508#if __FreeBSD_version >= 500000
509 warnx("Starting DIR_OUT @%jd:%u",
510#else
511 warnx("Starting DIR_OUT @%lld:%u",
512#endif
513 c_descr->offset, a_descr->init_req);
505 warnx("Starting %p DIR_OUT @" OFF_FMT ":%u",
506 a_descr, c_descr->offset, a_descr->init_req);
514 }
515
516 return (ret);
517}
518
519static int
520tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio)
521{

--- 45 unchanged lines hidden (view full) ---

567 return (0);
568 }
569
570 /* Get an (overall) data length and set direction */
571 a_descr->base_off = ((off_t)blkno) * sector_size;
572 a_descr->total_len = count * sector_size;
573 if (a_descr->total_len == 0) {
574 if (debug)
507 }
508
509 return (ret);
510}
511
512static int
513tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio)
514{

--- 45 unchanged lines hidden (view full) ---

560 return (0);
561 }
562
563 /* Get an (overall) data length and set direction */
564 a_descr->base_off = ((off_t)blkno) * sector_size;
565 a_descr->total_len = count * sector_size;
566 if (a_descr->total_len == 0) {
567 if (debug)
575#if __FreeBSD_version >= 500000
576 warnx("r/w 0 blocks @ blkno %ju", blkno);
577#else
578 warnx("r/w 0 blocks @ blkno %llu", blkno);
579#endif
568 warnx("r/w 0 blocks @ blkno " OFF_FMT, blkno);
580 tcmd_null_ok(atio, ctio);
581 return (0);
582 } else if (cdb[0] == WRITE_6 || cdb[0] == WRITE_10) {
583 a_descr->flags |= CAM_DIR_OUT;
584 if (debug)
569 tcmd_null_ok(atio, ctio);
570 return (0);
571 } else if (cdb[0] == WRITE_6 || cdb[0] == WRITE_10) {
572 a_descr->flags |= CAM_DIR_OUT;
573 if (debug)
585#if __FreeBSD_version >= 500000
586 warnx("write %u blocks @ blkno %ju", count, blkno);
587#else
588 warnx("write %u blocks @ blkno %llu", count, blkno);
589#endif
574 warnx("write %u blocks @ blkno " OFF_FMT, count, blkno);
590 } else {
591 a_descr->flags |= CAM_DIR_IN;
592 if (debug)
575 } else {
576 a_descr->flags |= CAM_DIR_IN;
577 if (debug)
593#if __FreeBSD_version >= 500000
594 warnx("read %u blocks @ blkno %ju", count, blkno);
595#else
596 warnx("read %u blocks @ blkno %llu", count, blkno);
597#endif
578 warnx("read %u blocks @ blkno " OFF_FMT, count, blkno);
598 }
599 return (1);
600}
601
602static int
603start_io(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio, int dir)
604{
605 struct atio_descr *a_descr;

--- 15 unchanged lines hidden (view full) ---

621 assert(ctio->dxfer_len >= 0);
622
623 c_descr->aiocb.aio_offset = c_descr->offset;
624 c_descr->aiocb.aio_nbytes = ctio->dxfer_len;
625
626 /* If DIR_IN, start read from target, otherwise begin CTIO xfer. */
627 ret = 1;
628 if (dir == CAM_DIR_IN) {
579 }
580 return (1);
581}
582
583static int
584start_io(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio, int dir)
585{
586 struct atio_descr *a_descr;

--- 15 unchanged lines hidden (view full) ---

602 assert(ctio->dxfer_len >= 0);
603
604 c_descr->aiocb.aio_offset = c_descr->offset;
605 c_descr->aiocb.aio_nbytes = ctio->dxfer_len;
606
607 /* If DIR_IN, start read from target, otherwise begin CTIO xfer. */
608 ret = 1;
609 if (dir == CAM_DIR_IN) {
629 if (aio_read(&c_descr->aiocb) < 0)
630 err(1, "aio_read"); /* XXX */
610 if (notaio) {
611 if (debug)
612 warnx("read sync %lud @ block " OFF_FMT,
613 (unsigned long)
614 (ctio->dxfer_len / sector_size),
615 c_descr->offset / sector_size);
616 if (lseek(c_descr->aiocb.aio_fildes,
617 c_descr->aiocb.aio_offset, SEEK_SET) < 0) {
618 perror("lseek");
619 err(1, "lseek");
620 }
621 if (read(c_descr->aiocb.aio_fildes,
622 (void *)c_descr->aiocb.aio_buf,
623 ctio->dxfer_len) != ctio->dxfer_len) {
624 err(1, "read");
625 }
626 } else {
627 if (debug)
628 warnx("read async %lud @ block " OFF_FMT,
629 (unsigned long)
630 (ctio->dxfer_len / sector_size),
631 c_descr->offset / sector_size);
632 if (aio_read(&c_descr->aiocb) < 0) {
633 err(1, "aio_read"); /* XXX */
634 }
635 }
631 a_descr->targ_req += ctio->dxfer_len;
636 a_descr->targ_req += ctio->dxfer_len;
637 /* if we're done, we can mark the CCB as to send status */
632 if (a_descr->targ_req == a_descr->total_len) {
633 ctio->ccb_h.flags |= CAM_SEND_STATUS;
634 ctio->scsi_status = SCSI_STATUS_OK;
635 ret = 0;
636 }
638 if (a_descr->targ_req == a_descr->total_len) {
639 ctio->ccb_h.flags |= CAM_SEND_STATUS;
640 ctio->scsi_status = SCSI_STATUS_OK;
641 ret = 0;
642 }
643 if (notaio)
644 tcmd_rdwr_done(atio, ctio, AIO_DONE);
637 } else {
638 if (a_descr->targ_ack == a_descr->total_len)
639 tcmd_null_ok(atio, ctio);
640 a_descr->init_req += ctio->dxfer_len;
641 if (a_descr->init_req == a_descr->total_len &&
642 ctio->dxfer_len > 0) {
643 /*
644 * If data phase done, remove atio from workq.

--- 15 unchanged lines hidden (view full) ---

660 struct atio_descr *a_descr;
661 struct ctio_descr *c_descr;
662
663 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
664 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
665
666 switch (event) {
667 case AIO_DONE:
645 } else {
646 if (a_descr->targ_ack == a_descr->total_len)
647 tcmd_null_ok(atio, ctio);
648 a_descr->init_req += ctio->dxfer_len;
649 if (a_descr->init_req == a_descr->total_len &&
650 ctio->dxfer_len > 0) {
651 /*
652 * If data phase done, remove atio from workq.

--- 15 unchanged lines hidden (view full) ---

668 struct atio_descr *a_descr;
669 struct ctio_descr *c_descr;
670
671 a_descr = (struct atio_descr *)atio->ccb_h.targ_descr;
672 c_descr = (struct ctio_descr *)ctio->ccb_h.targ_descr;
673
674 switch (event) {
675 case AIO_DONE:
668 if (aio_return(&c_descr->aiocb) < 0) {
676 if (!notaio && aio_return(&c_descr->aiocb) < 0) {
669 warn("aio_return error");
670 /* XXX */
671 tcmd_sense(ctio->init_id, ctio,
672 SSD_KEY_MEDIUM_ERROR, 0, 0);
673 send_ccb((union ccb *)ctio, /*priority*/1);
674 break;
675 }
676 a_descr->targ_ack += ctio->dxfer_len;
677 if ((a_descr->flags & CAM_DIR_IN) != 0) {
677 warn("aio_return error");
678 /* XXX */
679 tcmd_sense(ctio->init_id, ctio,
680 SSD_KEY_MEDIUM_ERROR, 0, 0);
681 send_ccb((union ccb *)ctio, /*priority*/1);
682 break;
683 }
684 a_descr->targ_ack += ctio->dxfer_len;
685 if ((a_descr->flags & CAM_DIR_IN) != 0) {
678 if (debug)
679 warnx("sending CTIO for AIO read");
686 if (debug) {
687 if (notaio)
688 warnx("sending CTIO for AIO read");
689 else
690 warnx("sending CTIO for sync read");
691 }
680 a_descr->init_req += ctio->dxfer_len;
681 send_ccb((union ccb *)ctio, /*priority*/1);
682 } else {
683 /* Use work function to send final status */
684 if (a_descr->init_req == a_descr->total_len)
685 work_atio(atio);
686 if (debug)
687 warnx("AIO done freeing CTIO");

--- 17 unchanged lines hidden (view full) ---

705 }
706 return;
707 default:
708 errx(1, "CTIO failed, status %#x", ctio->ccb_h.status);
709 }
710 a_descr->init_ack += ctio->dxfer_len;
711 if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT &&
712 ctio->dxfer_len > 0) {
692 a_descr->init_req += ctio->dxfer_len;
693 send_ccb((union ccb *)ctio, /*priority*/1);
694 } else {
695 /* Use work function to send final status */
696 if (a_descr->init_req == a_descr->total_len)
697 work_atio(atio);
698 if (debug)
699 warnx("AIO done freeing CTIO");

--- 17 unchanged lines hidden (view full) ---

717 }
718 return;
719 default:
720 errx(1, "CTIO failed, status %#x", ctio->ccb_h.status);
721 }
722 a_descr->init_ack += ctio->dxfer_len;
723 if ((a_descr->flags & CAM_DIR_MASK) == CAM_DIR_OUT &&
724 ctio->dxfer_len > 0) {
713 if (debug)
714 warnx("sending AIO for CTIO write");
715 a_descr->targ_req += ctio->dxfer_len;
725 a_descr->targ_req += ctio->dxfer_len;
716 if (aio_write(&c_descr->aiocb) < 0)
717 err(1, "aio_write"); /* XXX */
726 if (notaio) {
727 if (debug)
728 warnx("write sync %lud @ block "
729 OFF_FMT, (unsigned long)
730 (ctio->dxfer_len / sector_size),
731 c_descr->offset / sector_size);
732 if (lseek(c_descr->aiocb.aio_fildes,
733 c_descr->aiocb.aio_offset, SEEK_SET) < 0) {
734 perror("lseek");
735 err(1, "lseek");
736 }
737 if (write(c_descr->aiocb.aio_fildes,
738 (void *) c_descr->aiocb.aio_buf,
739 ctio->dxfer_len) != ctio->dxfer_len) {
740 err(1, "write");
741 }
742 tcmd_rdwr_done(atio, ctio, AIO_DONE);
743 } else {
744 if (debug)
745 warnx("write async %lud @ block "
746 OFF_FMT, (unsigned long)
747 (ctio->dxfer_len / sector_size),
748 c_descr->offset / sector_size);
749 if (aio_write(&c_descr->aiocb) < 0) {
750 err(1, "aio_write"); /* XXX */
751 }
752 }
718 } else {
719 if (debug)
720 warnx("CTIO done freeing CTIO");
721 free_ccb((union ccb *)ctio);
722 }
723 break;
724 default:
725 warnx("Unknown completion code %d", event);

--- 53 unchanged lines hidden ---
753 } else {
754 if (debug)
755 warnx("CTIO done freeing CTIO");
756 free_ccb((union ccb *)ctio);
757 }
758 break;
759 default:
760 warnx("Unknown completion code %d", event);

--- 53 unchanged lines hidden ---