The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/iscsi_initiator/iscsivar.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2005-2011 Daniel Braniss <danny@cs.huji.ac.il>
    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
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR 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$
   29  */
   30 
   31 /*
   32  | $Id: iscsivar.h 743 2009-08-08 10:54:53Z danny $
   33  */
   34 #define ISCSI_MAX_LUNS          128     // don't touch this
   35 #if ISCSI_MAX_LUNS > 8
   36 /*
   37  | for this to work 
   38  | sysctl kern.cam.cam_srch_hi=1
   39  */
   40 #endif
   41 
   42 #ifndef ISCSI_INITIATOR_DEBUG
   43 #define ISCSI_INITIATOR_DEBUG 1
   44 #endif
   45 
   46 #ifdef ISCSI_INITIATOR_DEBUG
   47 extern int iscsi_debug;
   48 #define debug(level, fmt, args...)      do {if(level <= iscsi_debug)\
   49         printf("%s: " fmt "\n", __func__ , ##args);} while(0)
   50 #define sdebug(level, fmt, args...)     do {if(level <= iscsi_debug)\
   51         printf("%d] %s: " fmt "\n", sp->sid, __func__ , ##args);} while(0)
   52 #define debug_called(level)             do {if(level <= iscsi_debug)\
   53         printf("%s: called\n",  __func__);} while(0)
   54 #else
   55 #define debug(level, fmt, args...)
   56 #define debug_called(level)
   57 #define sdebug(level, fmt, args...)
   58 #endif /* ISCSI_INITIATOR_DEBUG */
   59 
   60 #define xdebug(fmt, args...)    printf(">>> %s: " fmt "\n", __func__ , ##args)
   61 
   62 #define MAX_SESSIONS    ISCSI_MAX_TARGETS
   63 #define MAX_PDUS        (MAX_SESSIONS*256) // XXX: at the moment this is arbitrary
   64 
   65 typedef uint32_t digest_t(const void *, int len, uint32_t ocrc);
   66 
   67 MALLOC_DECLARE(M_ISCSI);
   68 MALLOC_DECLARE(M_ISCSIBUF);
   69 
   70 #define ISOK2DIG(dig, pp)       ((dig != NULL) && ((pp->ipdu.bhs.opcode & 0x1f) != ISCSI_LOGIN_CMD))
   71 
   72 #ifndef BIT
   73 #define BIT(n)  (1 <<(n))
   74 #endif
   75 
   76 #define ISC_SM_RUN      BIT(0)
   77 #define ISC_SM_RUNNING  BIT(1)
   78 
   79 #define ISC_LINK_UP     BIT(2)
   80 #define ISC_CON_RUN     BIT(3)
   81 #define ISC_CON_RUNNING BIT(4)
   82 #define ISC_KILL        BIT(5)
   83 #define ISC_OQNOTEMPTY  BIT(6)
   84 #define ISC_OWAITING    BIT(7)
   85 #define ISC_FFPHASE     BIT(8)
   86 
   87 #define ISC_CAMDEVS     BIT(9)
   88 #define ISC_SCANWAIT    BIT(10)
   89 
   90 #define ISC_MEMWAIT     BIT(11)
   91 #define ISC_SIGNALED    BIT(12)
   92 
   93 #define ISC_HOLD        BIT(15)
   94 #define ISC_HOLDED      BIT(16)
   95 
   96 #define ISC_SHUTDOWN    BIT(31)
   97 
   98 /*
   99  | some stats
  100  */
  101 struct i_stats {
  102      int        npdu;   // number of pdus malloc'ed.
  103      int        nrecv;  // unprocessed received pdus
  104      int        nsent;  // sent pdus
  105 
  106      int        nrsp, max_rsp;
  107      int        nrsv, max_rsv;
  108      int        ncsnd, max_csnd;
  109      int        nisnd, max_isnd;
  110      int        nwsnd, max_wsnd;
  111      int        nhld, max_hld;
  112 
  113      struct bintime t_sent;
  114      struct bintime t_recv;
  115 };
  116 
  117 /*
  118  | one per 'session'
  119  */
  120 
  121 typedef TAILQ_HEAD(, pduq) queue_t;
  122 
  123 typedef struct isc_session {
  124      TAILQ_ENTRY(isc_session)   sp_link;
  125      int                flags;
  126      struct cdev        *dev;
  127      struct socket      *soc;
  128      struct file        *fp;
  129      struct thread      *td;
  130 
  131      struct proc        *proc; // the userland process
  132      int                signal;
  133      struct proc        *soc_proc;
  134      struct proc        *stp;   // the sm thread
  135 
  136      struct isc_softc   *isc;
  137 
  138      digest_t           *hdrDigest;     // the digest alg. if any
  139      digest_t           *dataDigest;    // the digest alg. if any
  140 
  141      int                sid;            // Session ID
  142      sn_t               sn;             // sequence number stuff;
  143      int                cws;            // current window size
  144 
  145      int                target_nluns; // this and target_lun are
  146                                       // hopefully temporal till I
  147                                       // figure out a better way.
  148      int                target_lun[ISCSI_MAX_LUNS/(sizeof(int)*8) + 1];
  149 
  150      struct mtx         rsp_mtx;
  151      struct mtx         rsv_mtx;
  152      struct mtx         snd_mtx;
  153      struct mtx         hld_mtx;
  154      struct mtx         io_mtx;
  155      queue_t            rsp;
  156      queue_t            rsv;
  157      queue_t            csnd;
  158      queue_t            isnd;
  159      queue_t            wsnd;
  160      queue_t            hld;                            
  161 
  162      isc_opt_t          opt;    // negotiable values
  163 
  164      struct i_stats     stats;
  165      bhs_t              bhs;
  166      struct uio         uio;
  167      struct iovec       iov;
  168      /*
  169       | cam stuff
  170       */
  171      struct cam_sim     *cam_sim;
  172      struct cam_path    *cam_path;
  173      struct mtx         cam_mtx;
  174      /*
  175       | sysctl stuff
  176       */
  177      struct sysctl_ctx_list     clist;
  178      struct sysctl_oid  *oid;
  179      int        douio;  //XXX: turn on/off uio on read
  180 } isc_session_t;
  181 
  182 typedef struct pduq {
  183      TAILQ_ENTRY(pduq)  pq_link;
  184 
  185      caddr_t            buf;
  186      u_int              len;    // the total length of the pdu
  187      pdu_t              pdu;
  188      union ccb          *ccb;
  189 
  190      struct uio         uio;
  191      struct iovec       iov[5]; // XXX: careful ...
  192      struct mbuf        *mp;
  193      struct bintime     ts;
  194      queue_t            *pduq;          
  195 } pduq_t;
  196 /*
  197  */
  198 struct isc_softc {
  199      struct mtx         isc_mtx;
  200      TAILQ_HEAD(,isc_session)   isc_sess;
  201      int                nsess;
  202      struct cdev        *dev;
  203      char               isid[6];        // Initiator Session ID (48 bits)
  204      struct unrhdr      *unit;
  205      struct sx          unit_sx;
  206 
  207      uma_zone_t         pdu_zone;       // pool of free pdu's
  208      TAILQ_HEAD(,pduq)  freepdu;
  209 
  210 #ifdef  ISCSI_INITIATOR_DEBUG
  211      int                 npdu_alloc, npdu_max; // for instrumentation
  212 #endif
  213 #ifdef DO_EVENTHANDLER
  214      eventhandler_tag   eh;
  215 #endif
  216      /*
  217       | sysctl stuff
  218       */
  219      struct sysctl_ctx_list     clist;
  220      struct sysctl_oid          *oid;
  221 };
  222 
  223 #ifdef  ISCSI_INITIATOR_DEBUG
  224 extern struct mtx iscsi_dbg_mtx;
  225 #endif
  226 
  227 void    isc_start_receiver(isc_session_t *sp);
  228 void    isc_stop_receiver(isc_session_t *sp);
  229 
  230 int     isc_sendPDU(isc_session_t *sp, pduq_t *pq);
  231 int     isc_qout(isc_session_t *sp, pduq_t *pq);
  232 int     i_prepPDU(isc_session_t *sp, pduq_t *pq);
  233 
  234 int     ism_fullfeature(struct cdev *dev, int flag);
  235 
  236 int     i_pdu_flush(isc_session_t *sc);
  237 int     i_setopt(isc_session_t *sp, isc_opt_t *opt);
  238 void    i_freeopt(isc_opt_t *opt);
  239 
  240 int     ic_init(isc_session_t *sp);
  241 void    ic_destroy(isc_session_t *sp);
  242 void    ic_lost_target(isc_session_t *sp, int target);
  243 int     ic_getCamVals(isc_session_t *sp, iscsi_cam_t *cp);
  244 
  245 void    ism_recv(isc_session_t *sp, pduq_t *pq);
  246 int     ism_start(isc_session_t *sp);
  247 void    ism_restart(isc_session_t *sp);
  248 void    ism_stop(isc_session_t *sp);
  249 
  250 int     scsi_encap(struct cam_sim *sim, union ccb *ccb);
  251 int     scsi_decap(isc_session_t *sp, pduq_t *opq, pduq_t *pq);
  252 void    iscsi_r2t(isc_session_t *sp, pduq_t *opq, pduq_t *pq);
  253 void    iscsi_done(isc_session_t *sp, pduq_t *opq, pduq_t *pq);
  254 void    iscsi_reject(isc_session_t *sp, pduq_t *opq, pduq_t *pq);
  255 void    iscsi_async(isc_session_t *sp,  pduq_t *pq);
  256 void    iscsi_cleanup(isc_session_t *sp);
  257 int     iscsi_requeue(isc_session_t *sp);
  258 
  259 // Serial Number Arithmetic
  260 #define _MAXINCR        0x7FFFFFFF      // 2 ^ 31 - 1
  261 #define SNA_GT(i1, i2)  ((i1 != i2) && (\
  262         (i1 < i2 && i2 - i1 > _MAXINCR) ||\
  263         (i1 > i2 && i1 - i2 < _MAXINCR))?1: 0)
  264 
  265 /*
  266  | inlines
  267  */
  268 #ifdef _CAM_CAM_XPT_SIM_H
  269 
  270 #if __FreeBSD_version <  600000
  271 #define CAM_LOCK(arg)
  272 #define CAM_ULOCK(arg)
  273 
  274 static __inline void
  275 XPT_DONE(isc_session_t *sp, union ccb *ccb)
  276 {
  277      mtx_lock(&Giant);
  278      xpt_done(ccb);
  279      mtx_unlock(&Giant);
  280 }
  281 #elif __FreeBSD_version >= 700000
  282 #define CAM_LOCK(arg)   mtx_lock(&arg->cam_mtx)
  283 #define CAM_UNLOCK(arg) mtx_unlock(&arg->cam_mtx)
  284 
  285 static __inline void
  286 XPT_DONE(isc_session_t *sp, union ccb *ccb)
  287 {
  288      CAM_LOCK(sp);
  289      xpt_done(ccb);
  290      CAM_UNLOCK(sp);
  291 }
  292 #else
  293 //__FreeBSD_version >= 600000
  294 #define CAM_LOCK(arg)
  295 #define CAM_UNLOCK(arg)
  296 #define XPT_DONE(ignore, arg)   xpt_done(arg)
  297 #endif
  298 
  299 #endif /* _CAM_CAM_XPT_SIM_H */
  300 
  301 static __inline pduq_t *
  302 pdu_alloc(struct isc_softc *isc, int wait)
  303 {
  304      pduq_t     *pq;
  305 
  306      pq = (pduq_t *)uma_zalloc(isc->pdu_zone, wait /* M_WAITOK or M_NOWAIT*/);
  307      if(pq == NULL) {
  308           debug(7, "out of mem");
  309           return NULL;
  310      }
  311 #ifdef ISCSI_INITIATOR_DEBUG
  312      mtx_lock(&iscsi_dbg_mtx);
  313      isc->npdu_alloc++;
  314      if(isc->npdu_alloc > isc->npdu_max)
  315           isc->npdu_max = isc->npdu_alloc;
  316      mtx_unlock(&iscsi_dbg_mtx);
  317 #endif
  318      memset(pq, 0, sizeof(pduq_t));
  319 
  320      return pq;
  321 }
  322 
  323 static __inline void
  324 pdu_free(struct isc_softc *isc, pduq_t *pq)
  325 {
  326      if(pq->mp)
  327           m_freem(pq->mp);
  328 #ifdef NO_USE_MBUF
  329      if(pq->buf != NULL)
  330           free(pq->buf, M_ISCSIBUF);
  331 #endif
  332      uma_zfree(isc->pdu_zone, pq);
  333 #ifdef ISCSI_INITIATOR_DEBUG
  334      mtx_lock(&iscsi_dbg_mtx);
  335      isc->npdu_alloc--;
  336      mtx_unlock(&iscsi_dbg_mtx);
  337 #endif
  338 }
  339 
  340 static __inline void
  341 i_nqueue_rsp(isc_session_t *sp, pduq_t *pq)
  342 {
  343      mtx_lock(&sp->rsp_mtx);
  344      if(++sp->stats.nrsp > sp->stats.max_rsp)
  345           sp->stats.max_rsp = sp->stats.nrsp;
  346      TAILQ_INSERT_TAIL(&sp->rsp, pq, pq_link);
  347      mtx_unlock(&sp->rsp_mtx);
  348 }
  349 
  350 static __inline pduq_t *
  351 i_dqueue_rsp(isc_session_t *sp)
  352 {
  353      pduq_t *pq;
  354 
  355      mtx_lock(&sp->rsp_mtx);
  356      if((pq = TAILQ_FIRST(&sp->rsp)) != NULL) {
  357           sp->stats.nrsp--;
  358           TAILQ_REMOVE(&sp->rsp, pq, pq_link);
  359      }
  360      mtx_unlock(&sp->rsp_mtx);
  361 
  362      return pq;
  363 }
  364 
  365 static __inline void
  366 i_nqueue_rsv(isc_session_t *sp, pduq_t *pq)
  367 {
  368      mtx_lock(&sp->rsv_mtx);
  369      if(++sp->stats.nrsv > sp->stats.max_rsv)
  370           sp->stats.max_rsv = sp->stats.nrsv;
  371      TAILQ_INSERT_TAIL(&sp->rsv, pq, pq_link);
  372      mtx_unlock(&sp->rsv_mtx);
  373 }
  374 
  375 static __inline pduq_t *
  376 i_dqueue_rsv(isc_session_t *sp)
  377 {
  378      pduq_t *pq;
  379 
  380      mtx_lock(&sp->rsv_mtx);
  381      if((pq = TAILQ_FIRST(&sp->rsv)) != NULL) {
  382           sp->stats.nrsv--;
  383           TAILQ_REMOVE(&sp->rsv, pq, pq_link);
  384      }
  385      mtx_unlock(&sp->rsv_mtx);
  386 
  387      return pq;
  388 }
  389 
  390 static __inline void
  391 i_nqueue_csnd(isc_session_t *sp, pduq_t *pq)
  392 {
  393      mtx_lock(&sp->snd_mtx);
  394      if(++sp->stats.ncsnd > sp->stats.max_csnd)
  395           sp->stats.max_csnd = sp->stats.ncsnd;
  396      TAILQ_INSERT_TAIL(&sp->csnd, pq, pq_link);
  397      mtx_unlock(&sp->snd_mtx);
  398 }
  399 
  400 static __inline pduq_t *
  401 i_dqueue_csnd(isc_session_t *sp)
  402 {
  403      pduq_t *pq;
  404 
  405      mtx_lock(&sp->snd_mtx);
  406      if((pq = TAILQ_FIRST(&sp->csnd)) != NULL) {
  407           sp->stats.ncsnd--;
  408           TAILQ_REMOVE(&sp->csnd, pq, pq_link);
  409      }
  410      mtx_unlock(&sp->snd_mtx);
  411 
  412      return pq;
  413 }
  414 
  415 static __inline void
  416 i_nqueue_isnd(isc_session_t *sp, pduq_t *pq)
  417 {
  418      mtx_lock(&sp->snd_mtx);
  419      if(++sp->stats.nisnd > sp->stats.max_isnd)
  420           sp->stats.max_isnd = sp->stats.nisnd;
  421      TAILQ_INSERT_TAIL(&sp->isnd, pq, pq_link);
  422      mtx_unlock(&sp->snd_mtx);
  423 }
  424 
  425 static __inline pduq_t *
  426 i_dqueue_isnd(isc_session_t *sp)
  427 {
  428      pduq_t *pq;
  429 
  430      mtx_lock(&sp->snd_mtx);
  431      if((pq = TAILQ_FIRST(&sp->isnd)) != NULL) {
  432           sp->stats.nisnd--;
  433           TAILQ_REMOVE(&sp->isnd, pq, pq_link);
  434      }
  435      mtx_unlock(&sp->snd_mtx);
  436 
  437      return pq;
  438 }
  439 
  440 static __inline void
  441 i_nqueue_wsnd(isc_session_t *sp, pduq_t *pq)
  442 {
  443      mtx_lock(&sp->snd_mtx);
  444      if(++sp->stats.nwsnd > sp->stats.max_wsnd)
  445           sp->stats.max_wsnd = sp->stats.nwsnd;
  446      TAILQ_INSERT_TAIL(&sp->wsnd, pq, pq_link);
  447      mtx_unlock(&sp->snd_mtx);
  448 }
  449 
  450 static __inline pduq_t *
  451 i_dqueue_wsnd(isc_session_t *sp)
  452 {
  453      pduq_t *pq;
  454 
  455      mtx_lock(&sp->snd_mtx);
  456      if((pq = TAILQ_FIRST(&sp->wsnd)) != NULL) {
  457           sp->stats.nwsnd--;
  458           TAILQ_REMOVE(&sp->wsnd, pq, pq_link);
  459      }
  460      mtx_unlock(&sp->snd_mtx);
  461 
  462      return pq;
  463 }
  464 
  465 static __inline pduq_t *
  466 i_dqueue_snd(isc_session_t *sp, int which)
  467 {
  468      pduq_t *pq;
  469 
  470      pq = NULL;
  471      mtx_lock(&sp->snd_mtx);
  472      if((which & BIT(0)) && (pq = TAILQ_FIRST(&sp->isnd)) != NULL) {
  473           sp->stats.nisnd--;
  474           TAILQ_REMOVE(&sp->isnd, pq, pq_link);
  475           pq->pduq = &sp->isnd; // remember where you came from
  476      } else
  477      if((which & BIT(1)) && (pq = TAILQ_FIRST(&sp->wsnd)) != NULL) {
  478           sp->stats.nwsnd--;
  479           TAILQ_REMOVE(&sp->wsnd, pq, pq_link);
  480           pq->pduq = &sp->wsnd; // remember where you came from
  481      } else
  482      if((which & BIT(2)) && (pq = TAILQ_FIRST(&sp->csnd)) != NULL) {
  483           sp->stats.ncsnd--;
  484           TAILQ_REMOVE(&sp->csnd, pq, pq_link);
  485           pq->pduq = &sp->csnd; // remember where you came from
  486      }
  487      mtx_unlock(&sp->snd_mtx);
  488 
  489      return pq;
  490 }
  491 
  492 static __inline void
  493 i_rqueue_pdu(isc_session_t *sp, pduq_t *pq)
  494 {
  495      mtx_lock(&sp->snd_mtx);
  496      KASSERT(pq->pduq != NULL, ("pq->pduq is NULL"));
  497      TAILQ_INSERT_TAIL(pq->pduq, pq, pq_link);
  498      mtx_unlock(&sp->snd_mtx);     
  499 }
  500 
  501 /*
  502  | Waiting for ACK (or something :-)
  503  */
  504 static __inline void
  505 i_nqueue_hld(isc_session_t *sp, pduq_t *pq)
  506 {
  507      getbintime(&pq->ts);
  508      mtx_lock(&sp->hld_mtx);
  509      if(++sp->stats.nhld > sp->stats.max_hld)
  510           sp->stats.max_hld = sp->stats.nhld;
  511      TAILQ_INSERT_TAIL(&sp->hld, pq, pq_link);
  512      mtx_unlock(&sp->hld_mtx);
  513      return;
  514 }
  515 
  516 static __inline void
  517 i_remove_hld(isc_session_t *sp, pduq_t *pq)
  518 {
  519      mtx_lock(&sp->hld_mtx);
  520      sp->stats.nhld--;
  521      TAILQ_REMOVE(&sp->hld, pq, pq_link);
  522      mtx_unlock(&sp->hld_mtx);
  523 }
  524 
  525 static __inline pduq_t *
  526 i_dqueue_hld(isc_session_t *sp)
  527 {
  528      pduq_t *pq;
  529 
  530      mtx_lock(&sp->hld_mtx);
  531      if((pq = TAILQ_FIRST(&sp->hld)) != NULL) {
  532           sp->stats.nhld--;
  533           TAILQ_REMOVE(&sp->hld, pq, pq_link);
  534      }
  535      mtx_unlock(&sp->hld_mtx);
  536 
  537      return pq;
  538 }
  539 
  540 static __inline pduq_t *
  541 i_search_hld(isc_session_t *sp, int itt, int keep)
  542 {
  543      pduq_t     *pq, *tmp;
  544 
  545      pq = NULL;
  546 
  547      mtx_lock(&sp->hld_mtx);
  548      TAILQ_FOREACH_SAFE(pq, &sp->hld, pq_link, tmp) {
  549           if(pq->pdu.ipdu.bhs.itt == itt) {
  550                if(!keep) {
  551                     sp->stats.nhld--;
  552                     TAILQ_REMOVE(&sp->hld, pq, pq_link);
  553                }
  554                break;
  555           }
  556      }
  557      mtx_unlock(&sp->hld_mtx);
  558 
  559      return pq;
  560 }
  561 
  562 static __inline void
  563 i_acked_hld(isc_session_t *sp, pdu_t *op)
  564 {
  565      pduq_t     *pq, *tmp;
  566      u_int exp = sp->sn.expCmd;
  567      
  568      pq = NULL;
  569      mtx_lock(&sp->hld_mtx);
  570      TAILQ_FOREACH_SAFE(pq, &sp->hld, pq_link, tmp) {
  571           if((op && op->ipdu.bhs.itt == pq->pdu.ipdu.bhs.itt)
  572              || (pq->ccb == NULL
  573                  && (pq->pdu.ipdu.bhs.opcode != ISCSI_WRITE_DATA)
  574                  && SNA_GT(exp, ntohl(pq->pdu.ipdu.bhs.ExpStSN)))) {
  575                sp->stats.nhld--;
  576                TAILQ_REMOVE(&sp->hld, pq, pq_link);
  577                pdu_free(sp->isc, pq);
  578           }
  579      }
  580      mtx_unlock(&sp->hld_mtx);
  581 }
  582 
  583 static __inline void
  584 i_mbufcopy(struct mbuf *mp, caddr_t dp, int len)
  585 {
  586      struct mbuf *m;
  587      caddr_t bp;
  588 
  589      for(m = mp; m != NULL; m = m->m_next) {
  590           bp = mtod(m, caddr_t);
  591           /*
  592            | the pdu is word (4 octed) aligned
  593            | so len <= packet
  594            */
  595           memcpy(dp, bp, MIN(len, m->m_len));
  596           dp += m->m_len;
  597           len -= m->m_len;
  598           if(len <= 0)
  599                break;
  600      }
  601 }

Cache object: 1fc6256971b18ec46310baa4eb946a89


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.