Author: trasz
Date: Sun Feb  8 19:15:14 2015
New Revision: 278397
URL: https://svnweb.freebsd.org/changeset/base/278397

Log:
  Extend ICL to add receive offload methods.  For software ICL backend
  they are no-ops.
  
  MFC after:    1 month
  Sponsored by: The FreeBSD Foundation

Modified:
  head/sys/cam/ctl/ctl_frontend_iscsi.c
  head/sys/cam/ctl/ctl_frontend_iscsi.h
  head/sys/dev/iscsi/icl_conn_if.m
  head/sys/dev/iscsi/icl_soft.c
  head/sys/dev/iscsi/icl_wrappers.h
  head/sys/dev/iscsi/iscsi.c
  head/sys/dev/iscsi/iscsi.h

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.c
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.c       Sun Feb  8 19:12:38 2015        
(r278396)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.c       Sun Feb  8 19:15:14 2015        
(r278397)
@@ -164,6 +164,12 @@ static void        cfiscsi_pdu_handle_task_requ
 static void    cfiscsi_pdu_handle_data_out(struct icl_pdu *request);
 static void    cfiscsi_pdu_handle_logout_request(struct icl_pdu *request);
 static void    cfiscsi_session_terminate(struct cfiscsi_session *cs);
+static struct cfiscsi_data_wait        *cfiscsi_data_wait_new(
+                   struct cfiscsi_session *cs, union ctl_io *io,
+                   uint32_t initiator_task_tag,
+                   uint32_t *target_transfer_tagp);
+static void    cfiscsi_data_wait_free(struct cfiscsi_session *cs,
+                   struct cfiscsi_data_wait *cdw);
 static struct cfiscsi_target   *cfiscsi_target_find(struct cfiscsi_softc
                    *softc, const char *name, uint16_t tag);
 static struct cfiscsi_target   *cfiscsi_target_find_or_create(
@@ -929,7 +935,7 @@ cfiscsi_pdu_handle_data_out(struct icl_p
                CFISCSI_SESSION_UNLOCK(cs);
                done = (io->scsiio.ext_data_filled != cdw->cdw_r2t_end ||
                    io->scsiio.ext_data_filled == io->scsiio.kern_data_len);
-               uma_zfree(cfiscsi_data_wait_zone, cdw);
+               cfiscsi_data_wait_free(cs, cdw);
                if (done)
                        io->scsiio.be_move_done(io);
                else
@@ -1067,6 +1073,45 @@ cfiscsi_callout(void *context)
        cfiscsi_pdu_queue(cp);
 }
 
+static struct cfiscsi_data_wait *
+cfiscsi_data_wait_new(struct cfiscsi_session *cs, union ctl_io *io,
+    uint32_t initiator_task_tag, uint32_t *target_transfer_tagp)
+{
+       struct cfiscsi_data_wait *cdw;
+       int error;
+
+       cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO);
+       if (cdw == NULL) {
+               CFISCSI_SESSION_WARN(cs,
+                   "failed to allocate %zd bytes", sizeof(*cdw));
+               return (NULL);
+       }
+
+       error = icl_conn_transfer_setup(cs->cs_conn, io, target_transfer_tagp,
+           &cdw->cdw_icl_prv);
+       if (error != 0) {
+               CFISCSI_SESSION_WARN(cs,
+                   "icl_conn_transfer_setup() failed with error %d", error);
+               uma_zfree(cfiscsi_data_wait_zone, cdw);
+               return (NULL);
+       }
+
+       cdw->cdw_ctl_io = io;
+       cdw->cdw_target_transfer_tag = *target_transfer_tagp;
+       cdw->cdw_initiator_task_tag = initiator_task_tag;
+
+       return (cdw);
+}
+
+static void
+cfiscsi_data_wait_free(struct cfiscsi_session *cs,
+    struct cfiscsi_data_wait *cdw)
+{
+
+       icl_conn_transfer_done(cs->cs_conn, cdw->cdw_icl_prv);
+       uma_zfree(cfiscsi_data_wait_zone, cdw);
+}
+
 static void
 cfiscsi_session_terminate_tasks(struct cfiscsi_session *cs)
 {
@@ -1106,7 +1151,7 @@ cfiscsi_session_terminate_tasks(struct c
                 */
                cdw->cdw_ctl_io->scsiio.io_hdr.port_status = 42;
                cdw->cdw_ctl_io->scsiio.be_move_done(cdw->cdw_ctl_io);
-               uma_zfree(cfiscsi_data_wait_zone, cdw);
+               cfiscsi_data_wait_free(cs, cdw);
                CFISCSI_SESSION_LOCK(cs);
        }
        CFISCSI_SESSION_UNLOCK(cs);
@@ -2600,13 +2645,8 @@ cfiscsi_datamove_out(union ctl_io *io)
 
        target_transfer_tag =
            atomic_fetchadd_32(&cs->cs_target_transfer_tag, 1);
-
-#if 0
-       CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
-           "task tag 0x%x, target transfer tag 0x%x",
-           bhssc->bhssc_initiator_task_tag, target_transfer_tag);
-#endif
-       cdw = uma_zalloc(cfiscsi_data_wait_zone, M_NOWAIT | M_ZERO);
+       cdw = cfiscsi_data_wait_new(cs, io, bhssc->bhssc_initiator_task_tag,
+           &target_transfer_tag);
        if (cdw == NULL) {
                CFISCSI_SESSION_WARN(cs, "failed to "
                    "allocate memory; dropping connection");
@@ -2615,6 +2655,12 @@ cfiscsi_datamove_out(union ctl_io *io)
                cfiscsi_session_terminate(cs);
                return;
        }
+#if 0
+       CFISCSI_SESSION_DEBUG(cs, "expecting Data-Out with initiator "
+           "task tag 0x%x, target transfer tag 0x%x",
+           bhssc->bhssc_initiator_task_tag, target_transfer_tag);
+#endif
+
        cdw->cdw_ctl_io = io;
        cdw->cdw_target_transfer_tag = target_transfer_tag;
        cdw->cdw_initiator_task_tag = bhssc->bhssc_initiator_task_tag;
@@ -2651,7 +2697,7 @@ cfiscsi_datamove_out(union ctl_io *io)
            icl_pdu_data_segment_length(request)) {
                done = cfiscsi_handle_data_segment(request, cdw);
                if (done) {
-                       uma_zfree(cfiscsi_data_wait_zone, cdw);
+                       cfiscsi_data_wait_free(cs, cdw);
                        io->scsiio.be_move_done(io);
                        return;
                }
@@ -2854,7 +2900,7 @@ cfiscsi_task_management_done(union ctl_i
                        TAILQ_REMOVE(&cs->cs_waiting_for_data_out,
                            cdw, cdw_next);
                        cdw->cdw_ctl_io->scsiio.be_move_done(cdw->cdw_ctl_io);
-                       uma_zfree(cfiscsi_data_wait_zone, cdw);
+                       cfiscsi_data_wait_free(cs, cdw);
                }
                CFISCSI_SESSION_UNLOCK(cs);
        }

Modified: head/sys/cam/ctl/ctl_frontend_iscsi.h
==============================================================================
--- head/sys/cam/ctl/ctl_frontend_iscsi.h       Sun Feb  8 19:12:38 2015        
(r278396)
+++ head/sys/cam/ctl/ctl_frontend_iscsi.h       Sun Feb  8 19:15:14 2015        
(r278397)
@@ -59,6 +59,7 @@ struct cfiscsi_data_wait {
        size_t                          cdw_sg_len;
        uint32_t                        cdw_r2t_end;
        uint32_t                        cdw_datasn;
+       void                            *cdw_icl_prv;
 };
 
 #define CFISCSI_SESSION_STATE_INVALID          0

Modified: head/sys/dev/iscsi/icl_conn_if.m
==============================================================================
--- head/sys/dev/iscsi/icl_conn_if.m    Sun Feb  8 19:12:38 2015        
(r278396)
+++ head/sys/dev/iscsi/icl_conn_if.m    Sun Feb  8 19:15:14 2015        
(r278397)
@@ -85,3 +85,27 @@ METHOD void close {
 METHOD bool connected {
        struct icl_conn *_ic;
 };
+
+METHOD int task_setup {
+       struct icl_conn *_ic;
+       struct ccb_scsiio *_csio;
+       uint32_t *_task_tag;
+       void **_prvp;
+};
+
+METHOD void task_done {
+       struct icl_conn *_ic;
+       void *_prv;
+};
+
+METHOD int transfer_setup {
+       struct icl_conn *_ic;
+       union ctl_io *_io;
+       uint32_t *_transfer_tag;
+       void **_prvp;
+};
+
+METHOD void transfer_done {
+       struct icl_conn *_ic;
+       void *_prv;
+};

Modified: head/sys/dev/iscsi/icl_soft.c
==============================================================================
--- head/sys/dev/iscsi/icl_soft.c       Sun Feb  8 19:12:38 2015        
(r278396)
+++ head/sys/dev/iscsi/icl_soft.c       Sun Feb  8 19:15:14 2015        
(r278397)
@@ -98,6 +98,10 @@ static icl_conn_handoff_t    icl_soft_conn_
 static icl_conn_free_t         icl_soft_conn_free;
 static icl_conn_close_t                icl_soft_conn_close;
 static icl_conn_connected_t    icl_soft_conn_connected;
+static icl_conn_task_setup_t   icl_soft_conn_task_setup;
+static icl_conn_task_done_t    icl_soft_conn_task_done;
+static icl_conn_transfer_setup_t       icl_soft_conn_transfer_setup;
+static icl_conn_transfer_done_t        icl_soft_conn_transfer_done;
 
 static kobj_method_t icl_soft_methods[] = {
        KOBJMETHOD(icl_conn_new_pdu, icl_soft_conn_new_pdu),
@@ -111,6 +115,10 @@ static kobj_method_t icl_soft_methods[] 
        KOBJMETHOD(icl_conn_free, icl_soft_conn_free),
        KOBJMETHOD(icl_conn_close, icl_soft_conn_close),
        KOBJMETHOD(icl_conn_connected, icl_soft_conn_connected),
+       KOBJMETHOD(icl_conn_task_setup, icl_soft_conn_task_setup),
+       KOBJMETHOD(icl_conn_task_done, icl_soft_conn_task_done),
+       KOBJMETHOD(icl_conn_transfer_setup, icl_soft_conn_transfer_setup),
+       KOBJMETHOD(icl_conn_transfer_done, icl_soft_conn_transfer_done),
        { 0, 0 }
 };
 
@@ -1435,6 +1443,32 @@ icl_soft_conn_connected(struct icl_conn 
        return (true);
 }
 
+int
+icl_soft_conn_task_setup(struct icl_conn *ic, struct ccb_scsiio *csio,
+    uint32_t *task_tagp, void **prvp)
+{
+
+       return (0);
+}
+
+void
+icl_soft_conn_task_done(struct icl_conn *ic, void *prv)
+{
+}
+
+int
+icl_soft_conn_transfer_setup(struct icl_conn *ic, union ctl_io *io,
+    uint32_t *transfer_tag, void **prvp)
+{
+
+       return (0);
+}
+
+void
+icl_soft_conn_transfer_done(struct icl_conn *ic, void *prv)
+{
+}
+
 static int
 icl_soft_limits(size_t *limitp)
 {

Modified: head/sys/dev/iscsi/icl_wrappers.h
==============================================================================
--- head/sys/dev/iscsi/icl_wrappers.h   Sun Feb  8 19:12:38 2015        
(r278396)
+++ head/sys/dev/iscsi/icl_wrappers.h   Sun Feb  8 19:15:14 2015        
(r278397)
@@ -112,4 +112,34 @@ icl_conn_connected(struct icl_conn *ic)
        return (ICL_CONN_CONNECTED(ic));
 }
 
+static inline int
+icl_conn_task_setup(struct icl_conn *ic, struct ccb_scsiio *csio,
+    uint32_t *task_tagp, void **prvp)
+{
+
+       return (ICL_CONN_TASK_SETUP(ic, csio, task_tagp, prvp));
+}
+
+static inline void
+icl_conn_task_done(struct icl_conn *ic, void *prv)
+{
+
+       ICL_CONN_TASK_DONE(ic, prv);
+}
+
+static inline int
+icl_conn_transfer_setup(struct icl_conn *ic, union ctl_io *io,
+    uint32_t *transfer_tagp, void **prvp)
+{
+
+       return (ICL_CONN_TRANSFER_SETUP(ic, io, transfer_tagp, prvp));
+}
+
+static inline void
+icl_conn_transfer_done(struct icl_conn *ic, void *prv)
+{
+
+       ICL_CONN_TRANSFER_DONE(ic, prv);
+}
+
 #endif /* !ICL_WRAPPERS_H */

Modified: head/sys/dev/iscsi/iscsi.c
==============================================================================
--- head/sys/dev/iscsi/iscsi.c  Sun Feb  8 19:12:38 2015        (r278396)
+++ head/sys/dev/iscsi/iscsi.c  Sun Feb  8 19:15:14 2015        (r278397)
@@ -169,7 +169,7 @@ static void iscsi_poll(struct cam_sim *s
 static struct iscsi_outstanding        *iscsi_outstanding_find(struct 
iscsi_session *is,
                    uint32_t initiator_task_tag);
 static struct iscsi_outstanding        *iscsi_outstanding_add(struct 
iscsi_session *is,
-                   uint32_t initiator_task_tag, union ccb *ccb);
+                   union ccb *ccb, uint32_t *initiator_task_tagp);
 static void    iscsi_outstanding_remove(struct iscsi_session *is,
                    struct iscsi_outstanding *io);
 
@@ -1993,21 +1993,33 @@ iscsi_outstanding_find_ccb(struct iscsi_
 
 static struct iscsi_outstanding *
 iscsi_outstanding_add(struct iscsi_session *is,
-    uint32_t initiator_task_tag, union ccb *ccb)
+    union ccb *ccb, uint32_t *initiator_task_tagp)
 {
        struct iscsi_outstanding *io;
+       int error;
 
        ISCSI_SESSION_LOCK_ASSERT(is);
 
-       KASSERT(iscsi_outstanding_find(is, initiator_task_tag) == NULL,
-           ("initiator_task_tag 0x%x already added", initiator_task_tag));
-
        io = uma_zalloc(iscsi_outstanding_zone, M_NOWAIT | M_ZERO);
        if (io == NULL) {
-               ISCSI_SESSION_WARN(is, "failed to allocate %zd bytes", 
sizeof(*io));
+               ISCSI_SESSION_WARN(is, "failed to allocate %zd bytes",
+                   sizeof(*io));
+               return (NULL);
+       }
+
+       error = icl_conn_task_setup(is->is_conn, &ccb->csio,
+           initiator_task_tagp, &io->io_icl_prv);
+       if (error != 0) {
+               ISCSI_SESSION_WARN(is,
+                   "icl_conn_task_setup() failed with error %d", error);
+               uma_zfree(iscsi_outstanding_zone, io);
                return (NULL);
        }
-       io->io_initiator_task_tag = initiator_task_tag;
+
+       KASSERT(iscsi_outstanding_find(is, *initiator_task_tagp) == NULL,
+           ("initiator_task_tag 0x%x already added", *initiator_task_tagp));
+
+       io->io_initiator_task_tag = *initiator_task_tagp;
        io->io_ccb = ccb;
        TAILQ_INSERT_TAIL(&is->is_outstanding, io, io_next);
        return (io);
@@ -2019,6 +2031,7 @@ iscsi_outstanding_remove(struct iscsi_se
 
        ISCSI_SESSION_LOCK_ASSERT(is);
 
+       icl_conn_task_done(is->is_conn, io->io_icl_prv);
        TAILQ_REMOVE(&is->is_outstanding, io, io_next);
        uma_zfree(iscsi_outstanding_zone, io);
 }
@@ -2030,6 +2043,7 @@ iscsi_action_abort(struct iscsi_session 
        struct iscsi_bhs_task_management_request *bhstmr;
        struct ccb_abort *cab = &ccb->cab;
        struct iscsi_outstanding *io, *aio;
+       uint32_t initiator_task_tag;
 
        ISCSI_SESSION_LOCK_ASSERT(is);
 
@@ -2057,16 +2071,9 @@ iscsi_action_abort(struct iscsi_session 
                return;
        }
 
-       bhstmr = (struct iscsi_bhs_task_management_request *)request->ip_bhs;
-       bhstmr->bhstmr_opcode = ISCSI_BHS_OPCODE_TASK_REQUEST;
-       bhstmr->bhstmr_function = 0x80 | BHSTMR_FUNCTION_ABORT_TASK;
-
-       bhstmr->bhstmr_lun = 
htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
-       bhstmr->bhstmr_initiator_task_tag = is->is_initiator_task_tag;
-       is->is_initiator_task_tag++;
-       bhstmr->bhstmr_referenced_task_tag = aio->io_initiator_task_tag;
+       initiator_task_tag = is->is_initiator_task_tag++;
 
-       io = iscsi_outstanding_add(is, bhstmr->bhstmr_initiator_task_tag, NULL);
+       io = iscsi_outstanding_add(is, NULL, &initiator_task_tag);
        if (io == NULL) {
                icl_pdu_free(request);
                ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
@@ -2074,6 +2081,14 @@ iscsi_action_abort(struct iscsi_session 
                return;
        }
        io->io_datasn = aio->io_initiator_task_tag;
+
+       bhstmr = (struct iscsi_bhs_task_management_request *)request->ip_bhs;
+       bhstmr->bhstmr_opcode = ISCSI_BHS_OPCODE_TASK_REQUEST;
+       bhstmr->bhstmr_function = 0x80 | BHSTMR_FUNCTION_ABORT_TASK;
+       bhstmr->bhstmr_lun = 
htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
+       bhstmr->bhstmr_initiator_task_tag = initiator_task_tag;
+       bhstmr->bhstmr_referenced_task_tag = aio->io_initiator_task_tag;
+
        iscsi_pdu_queue_locked(request);
 }
 
@@ -2085,6 +2100,7 @@ iscsi_action_scsiio(struct iscsi_session
        struct ccb_scsiio *csio;
        struct iscsi_outstanding *io;
        size_t len;
+       uint32_t initiator_task_tag;
        int error;
 
        ISCSI_SESSION_LOCK_ASSERT(is);
@@ -2115,6 +2131,19 @@ iscsi_action_scsiio(struct iscsi_session
                return;
        }
 
+       initiator_task_tag = is->is_initiator_task_tag++;
+       io = iscsi_outstanding_add(is, ccb, &initiator_task_tag);
+       if (io == NULL) {
+               icl_pdu_free(request);
+               if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
+                       xpt_freeze_devq(ccb->ccb_h.path, 1);
+                       ISCSI_SESSION_DEBUG(is, "freezing devq");
+               }
+               ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN;
+               xpt_done(ccb);
+               return;
+       }
+
        csio = &ccb->csio;
        bhssc = (struct iscsi_bhs_scsi_command *)request->ip_bhs;
        bhssc->bhssc_opcode = ISCSI_BHS_OPCODE_SCSI_COMMAND;
@@ -2148,8 +2177,7 @@ iscsi_action_scsiio(struct iscsi_session
                bhssc->bhssc_flags |= BHSSC_FLAGS_ATTR_UNTAGGED;
 
        bhssc->bhssc_lun = 
htobe64(CAM_EXTLUN_BYTE_SWIZZLE(ccb->ccb_h.target_lun));
-       bhssc->bhssc_initiator_task_tag = is->is_initiator_task_tag;
-       is->is_initiator_task_tag++;
+       bhssc->bhssc_initiator_task_tag = initiator_task_tag;
        bhssc->bhssc_expected_data_transfer_length = htonl(csio->dxfer_len);
        KASSERT(csio->cdb_len <= sizeof(bhssc->bhssc_cdb),
            ("unsupported CDB size %zd", (size_t)csio->cdb_len));
@@ -2159,18 +2187,6 @@ iscsi_action_scsiio(struct iscsi_session
        else
                memcpy(&bhssc->bhssc_cdb, csio->cdb_io.cdb_bytes, 
csio->cdb_len);
 
-       io = iscsi_outstanding_add(is, bhssc->bhssc_initiator_task_tag, ccb);
-       if (io == NULL) {
-               icl_pdu_free(request);
-               if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) {
-                       xpt_freeze_devq(ccb->ccb_h.path, 1);
-                       ISCSI_SESSION_DEBUG(is, "freezing devq");
-               }
-               ccb->ccb_h.status = CAM_RESRC_UNAVAIL | CAM_DEV_QFRZN;
-               xpt_done(ccb);
-               return;
-       }
-
        if (is->is_immediate_data &&
            (csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) {
                len = csio->dxfer_len;

Modified: head/sys/dev/iscsi/iscsi.h
==============================================================================
--- head/sys/dev/iscsi/iscsi.h  Sun Feb  8 19:12:38 2015        (r278396)
+++ head/sys/dev/iscsi/iscsi.h  Sun Feb  8 19:15:14 2015        (r278397)
@@ -45,6 +45,7 @@ struct iscsi_outstanding {
        size_t                          io_received;
        uint32_t                        io_initiator_task_tag;
        uint32_t                        io_datasn;
+       void                            *io_icl_prv;
 };
 
 struct iscsi_session {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to