Deleted Added
full compact
ctl_frontend_iscsi.c (313362) ctl_frontend_iscsi.c (313364)
1/*-
2 * Copyright (c) 2012 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*-
2 * Copyright (c) 2012 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

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

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: stable/11/sys/cam/ctl/ctl_frontend_iscsi.c 313362 2017-02-07 01:38:48Z mav $
29 * $FreeBSD: stable/11/sys/cam/ctl/ctl_frontend_iscsi.c 313364 2017-02-07 01:42:13Z mav $
30 */
31
32/*
33 * CTL frontend for the iSCSI protocol.
34 */
35
36#include <sys/cdefs.h>
30 */
31
32/*
33 * CTL frontend for the iSCSI protocol.
34 */
35
36#include <sys/cdefs.h>
37__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/ctl_frontend_iscsi.c 313362 2017-02-07 01:38:48Z mav $");
37__FBSDID("$FreeBSD: stable/11/sys/cam/ctl/ctl_frontend_iscsi.c 313364 2017-02-07 01:42:13Z mav $");
38
39#include <sys/param.h>
40#include <sys/capsicum.h>
41#include <sys/condvar.h>
42#include <sys/endian.h>
43#include <sys/file.h>
44#include <sys/kernel.h>
45#include <sys/kthread.h>

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

764 if (copy_len > cdw->cdw_sg_len)
765 copy_len = cdw->cdw_sg_len;
766
767 icl_pdu_get_data(request, off, cdw->cdw_sg_addr, copy_len);
768 cdw->cdw_sg_addr += copy_len;
769 cdw->cdw_sg_len -= copy_len;
770 off += copy_len;
771 io->scsiio.ext_data_filled += copy_len;
38
39#include <sys/param.h>
40#include <sys/capsicum.h>
41#include <sys/condvar.h>
42#include <sys/endian.h>
43#include <sys/file.h>
44#include <sys/kernel.h>
45#include <sys/kthread.h>

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

764 if (copy_len > cdw->cdw_sg_len)
765 copy_len = cdw->cdw_sg_len;
766
767 icl_pdu_get_data(request, off, cdw->cdw_sg_addr, copy_len);
768 cdw->cdw_sg_addr += copy_len;
769 cdw->cdw_sg_len -= copy_len;
770 off += copy_len;
771 io->scsiio.ext_data_filled += copy_len;
772 io->scsiio.kern_data_resid -= copy_len;
772
773 if (cdw->cdw_sg_len == 0) {
774 /*
775 * End of current segment.
776 */
777 if (cdw->cdw_sg_index == ctl_sg_count - 1) {
778 /*
779 * Last segment in scatter/gather list.

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

2500 icl_pdu_free(response);
2501 ctl_set_busy(&io->scsiio);
2502 io->scsiio.be_move_done(io);
2503 cfiscsi_session_terminate(cs);
2504 return;
2505 }
2506 sg_addr += len;
2507 sg_len -= len;
773
774 if (cdw->cdw_sg_len == 0) {
775 /*
776 * End of current segment.
777 */
778 if (cdw->cdw_sg_index == ctl_sg_count - 1) {
779 /*
780 * Last segment in scatter/gather list.

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

2501 icl_pdu_free(response);
2502 ctl_set_busy(&io->scsiio);
2503 io->scsiio.be_move_done(io);
2504 cfiscsi_session_terminate(cs);
2505 return;
2506 }
2507 sg_addr += len;
2508 sg_len -= len;
2509 io->scsiio.kern_data_resid -= len;
2508
2509 KASSERT(buffer_offset + response->ip_data_len <= expected_len,
2510 ("buffer_offset %zd + ip_data_len %zd > expected_len %zd",
2511 buffer_offset, response->ip_data_len, expected_len));
2512 if (buffer_offset + response->ip_data_len == expected_len) {
2513 /*
2514 * Already have the amount of data the initiator wanted.
2515 */

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

2585cfiscsi_datamove_out(union ctl_io *io)
2586{
2587 struct cfiscsi_session *cs;
2588 struct icl_pdu *request, *response;
2589 const struct iscsi_bhs_scsi_command *bhssc;
2590 struct iscsi_bhs_r2t *bhsr2t;
2591 struct cfiscsi_data_wait *cdw;
2592 struct ctl_sg_entry ctl_sg_entry, *ctl_sglist;
2510
2511 KASSERT(buffer_offset + response->ip_data_len <= expected_len,
2512 ("buffer_offset %zd + ip_data_len %zd > expected_len %zd",
2513 buffer_offset, response->ip_data_len, expected_len));
2514 if (buffer_offset + response->ip_data_len == expected_len) {
2515 /*
2516 * Already have the amount of data the initiator wanted.
2517 */

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

2587cfiscsi_datamove_out(union ctl_io *io)
2588{
2589 struct cfiscsi_session *cs;
2590 struct icl_pdu *request, *response;
2591 const struct iscsi_bhs_scsi_command *bhssc;
2592 struct iscsi_bhs_r2t *bhsr2t;
2593 struct cfiscsi_data_wait *cdw;
2594 struct ctl_sg_entry ctl_sg_entry, *ctl_sglist;
2593 uint32_t expected_len, r2t_off, r2t_len;
2595 uint32_t expected_len, datamove_len, r2t_off, r2t_len;
2594 uint32_t target_transfer_tag;
2595 bool done;
2596
2597 request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
2598 cs = PDU_SESSION(request);
2599
2600 bhssc = (const struct iscsi_bhs_scsi_command *)request->ip_bhs;
2601 KASSERT((bhssc->bhssc_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) ==
2602 ISCSI_BHS_OPCODE_SCSI_COMMAND,
2603 ("bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_COMMAND"));
2604
2605 /*
2606 * We need to record it so that we can properly report
2607 * underflow/underflow.
2608 */
2609 PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len;
2610
2611 /*
2596 uint32_t target_transfer_tag;
2597 bool done;
2598
2599 request = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr;
2600 cs = PDU_SESSION(request);
2601
2602 bhssc = (const struct iscsi_bhs_scsi_command *)request->ip_bhs;
2603 KASSERT((bhssc->bhssc_opcode & ~ISCSI_BHS_OPCODE_IMMEDIATE) ==
2604 ISCSI_BHS_OPCODE_SCSI_COMMAND,
2605 ("bhssc->bhssc_opcode != ISCSI_BHS_OPCODE_SCSI_COMMAND"));
2606
2607 /*
2608 * We need to record it so that we can properly report
2609 * underflow/underflow.
2610 */
2611 PDU_TOTAL_TRANSFER_LEN(request) = io->scsiio.kern_total_len;
2612
2613 /*
2612 * Report write underflow as error since CTL and backends don't
2613 * really support it, and SCSI does not tell how to do it right.
2614 * Complete write underflow. Not a single byte to read. Return.
2614 */
2615 expected_len = ntohl(bhssc->bhssc_expected_data_transfer_length);
2615 */
2616 expected_len = ntohl(bhssc->bhssc_expected_data_transfer_length);
2616 if (io->scsiio.kern_rel_offset + io->scsiio.kern_data_len >
2617 expected_len) {
2618 io->scsiio.io_hdr.port_status = 43;
2617 if (io->scsiio.kern_rel_offset >= expected_len) {
2619 io->scsiio.be_move_done(io);
2620 return;
2621 }
2618 io->scsiio.be_move_done(io);
2619 return;
2620 }
2621 datamove_len = MIN(io->scsiio.kern_data_len,
2622 expected_len - io->scsiio.kern_rel_offset);
2622
2623 target_transfer_tag =
2624 atomic_fetchadd_32(&cs->cs_target_transfer_tag, 1);
2625 cdw = cfiscsi_data_wait_new(cs, io, bhssc->bhssc_initiator_task_tag,
2626 &target_transfer_tag);
2627 if (cdw == NULL) {
2628 CFISCSI_SESSION_WARN(cs, "failed to "
2629 "allocate memory; dropping connection");

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

2636 CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
2637 "task tag 0x%x, target transfer tag 0x%x",
2638 bhssc->bhssc_initiator_task_tag, target_transfer_tag);
2639#endif
2640
2641 cdw->cdw_ctl_io = io;
2642 cdw->cdw_target_transfer_tag = target_transfer_tag;
2643 cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
2623
2624 target_transfer_tag =
2625 atomic_fetchadd_32(&cs->cs_target_transfer_tag, 1);
2626 cdw = cfiscsi_data_wait_new(cs, io, bhssc->bhssc_initiator_task_tag,
2627 &target_transfer_tag);
2628 if (cdw == NULL) {
2629 CFISCSI_SESSION_WARN(cs, "failed to "
2630 "allocate memory; dropping connection");

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

2637 CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
2638 "task tag 0x%x, target transfer tag 0x%x",
2639 bhssc->bhssc_initiator_task_tag, target_transfer_tag);
2640#endif
2641
2642 cdw->cdw_ctl_io = io;
2643 cdw->cdw_target_transfer_tag = target_transfer_tag;
2644 cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
2644 cdw->cdw_r2t_end = io->scsiio.kern_data_len;
2645 cdw->cdw_r2t_end = datamove_len;
2645 cdw->cdw_datasn = 0;
2646
2647 /* Set initial data pointer for the CDW respecting ext_data_filled. */
2648 if (io->scsiio.kern_sg_entries > 0) {
2649 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
2650 } else {
2651 ctl_sglist = &ctl_sg_entry;
2652 ctl_sglist->addr = io->scsiio.kern_data_ptr;
2646 cdw->cdw_datasn = 0;
2647
2648 /* Set initial data pointer for the CDW respecting ext_data_filled. */
2649 if (io->scsiio.kern_sg_entries > 0) {
2650 ctl_sglist = (struct ctl_sg_entry *)io->scsiio.kern_data_ptr;
2651 } else {
2652 ctl_sglist = &ctl_sg_entry;
2653 ctl_sglist->addr = io->scsiio.kern_data_ptr;
2653 ctl_sglist->len = io->scsiio.kern_data_len;
2654 ctl_sglist->len = datamove_len;
2654 }
2655 cdw->cdw_sg_index = 0;
2656 cdw->cdw_sg_addr = ctl_sglist[cdw->cdw_sg_index].addr;
2657 cdw->cdw_sg_len = ctl_sglist[cdw->cdw_sg_index].len;
2658 r2t_off = io->scsiio.ext_data_filled;
2659 while (r2t_off > 0) {
2660 if (r2t_off >= cdw->cdw_sg_len) {
2661 r2t_off -= cdw->cdw_sg_len;

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

2676 if (done) {
2677 cfiscsi_data_wait_free(cs, cdw);
2678 io->scsiio.be_move_done(io);
2679 return;
2680 }
2681 }
2682
2683 r2t_off = io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled;
2655 }
2656 cdw->cdw_sg_index = 0;
2657 cdw->cdw_sg_addr = ctl_sglist[cdw->cdw_sg_index].addr;
2658 cdw->cdw_sg_len = ctl_sglist[cdw->cdw_sg_index].len;
2659 r2t_off = io->scsiio.ext_data_filled;
2660 while (r2t_off > 0) {
2661 if (r2t_off >= cdw->cdw_sg_len) {
2662 r2t_off -= cdw->cdw_sg_len;

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

2677 if (done) {
2678 cfiscsi_data_wait_free(cs, cdw);
2679 io->scsiio.be_move_done(io);
2680 return;
2681 }
2682 }
2683
2684 r2t_off = io->scsiio.kern_rel_offset + io->scsiio.ext_data_filled;
2684 r2t_len = MIN(io->scsiio.kern_data_len - io->scsiio.ext_data_filled,
2685 r2t_len = MIN(datamove_len - io->scsiio.ext_data_filled,
2685 cs->cs_max_burst_length);
2686 cdw->cdw_r2t_end = io->scsiio.ext_data_filled + r2t_len;
2687
2688 CFISCSI_SESSION_LOCK(cs);
2689 TAILQ_INSERT_TAIL(&cs->cs_waiting_for_data_out, cdw, cdw_next);
2690 CFISCSI_SESSION_UNLOCK(cs);
2691
2692 /*

--- 278 unchanged lines hidden ---
2686 cs->cs_max_burst_length);
2687 cdw->cdw_r2t_end = io->scsiio.ext_data_filled + r2t_len;
2688
2689 CFISCSI_SESSION_LOCK(cs);
2690 TAILQ_INSERT_TAIL(&cs->cs_waiting_for_data_out, cdw, cdw_next);
2691 CFISCSI_SESSION_UNLOCK(cs);
2692
2693 /*

--- 278 unchanged lines hidden ---