PERFORCE change 86632 for review

Scott Long scottl at FreeBSD.org
Thu Nov 10 22:07:38 PST 2005


http://perforce.freebsd.org/chv.cgi?CH=86632

Change 86632 by scottl at scottl-junior on 2005/11/11 06:06:39

	iSCSI initiator import patch 12 from Danny.

Affected files ...

.. //depot/projects/iscsi/src/sys/dev/iscsi/isc_cam.c#3 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/isc_sm.c#3 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/isc_soc.c#3 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/isc_subr.c#3 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/iscsi.c#3 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/iscsi.h#2 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/iscsi_subr.c#3 edit
.. //depot/projects/iscsi/src/sys/dev/iscsi/iscsivar.h#2 edit
.. //depot/projects/iscsi/src/usr.sbin/iscontrol/Makefile#2 edit
.. //depot/projects/iscsi/src/usr.sbin/iscontrol/fsm.c#2 edit

Differences ...

==== //depot/projects/iscsi/src/sys/dev/iscsi/isc_cam.c#3 (text+ko) ====

@@ -41,6 +41,7 @@
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
+#include <sys/uio.h>
 
 #include <dev/iscsi/iscsi.h>
 #include <dev/iscsi/iscsivar.h>
@@ -51,11 +52,11 @@
 {
      debug_called(8);
 
+     sdebug(4, "freezing path=%p", sp->cam_path == NULL? 0: sp->cam_path);
      if((sp->cam_path != NULL) && !(sp->flags & ISC_FROZEN)) {
-	  sdebug(3, "freezing path=%p", sp->cam_path);
 	  xpt_freeze_devq(sp->cam_path, 1);
-	  sp->flags |= ISC_FROZEN;
      }
+     sp->flags |= ISC_FROZEN;
 }
 
 // XXX: untested/incomplete
@@ -64,11 +65,11 @@
 {
      debug_called(8);
 
+     sdebug(4, "release path=%p", sp->cam_path == NULL? 0: sp->cam_path);
      if((sp->cam_path != NULL) && (sp->flags & ISC_FROZEN)) {
-	  sdebug(3, "release");
-	  sp->flags &= ~ISC_FROZEN;
 	  xpt_release_devq(sp->cam_path, 1, TRUE);
      }
+     sp->flags &= ~ISC_FROZEN;
 }
 
 void
@@ -91,11 +92,14 @@
 static void
 _scan_callback(struct cam_periph *periph, union ccb *ccb)
 {
-//     isc_session_t *sp = (isc_session_t *)ccb->ccb_h.spriv_ptr0;
+     isc_session_t *sp = (isc_session_t *)ccb->ccb_h.spriv_ptr0;
 
      debug_called(8);
      xpt_free_path(ccb->ccb_h.path);
      free(ccb, M_TEMP);
+
+     if(sp->flags & ISC_FFPWAIT)
+	  wakeup(&sp->flags);
 }
 
 static void
@@ -118,7 +122,7 @@
 	  return;
      }
      xpt_setup_ccb(&ccb->ccb_h, path, 5/*priority (low)*/);
-     ccb->ccb_h.func_code	= XPT_SCAN_LUN;
+     ccb->ccb_h.func_code	= XPT_SCAN_BUS;
      ccb->ccb_h.cbfcnp		= _scan_callback;
      ccb->crcn.flags		= CAM_FLAG_NONE;
      ccb->ccb_h.spriv_ptr0	= sp;
@@ -126,7 +130,7 @@
 }
 
 int
-ic_newdev(struct cdev *dev)
+ic_fullfeature(struct cdev *dev)
 {
      struct isc		*isp = (struct isc *)dev->si_drv1;
      isc_session_t	*sp = (isc_session_t *)dev->si_drv2;
@@ -134,9 +138,19 @@
      debug_called(8);
      sdebug(2, "dev=%d sc=%p", minor(dev), isp);
 
+     sp->flags &= ~ISC_FFPHASE;
+     sp->flags |= ISC_FFPWAIT;
+
      _scan_target(sp, sp->sid);
 
-     return 0;
+     tsleep(&sp->flags, PRIBIO, "ffp", 30*hz); // the timeout time should
+					       // be configurable
+     if(sp->target_nluns > 1) {
+	  sp->flags |= ISC_FFPHASE;
+	  return 0;
+     }
+
+     return ENODEV;
 }
 
 static void
@@ -238,6 +252,11 @@
 	       debug(4, "xpt_done.status=%d", ccb_h->status);
 	       break;
 	  }
+	  if(ccb_h->target_lun == CAM_LUN_WILDCARD) {
+	       debug(3, "target=%d: bad lun (-1)", ccb_h->target_id);
+	       ccb_h->status = CAM_LUN_INVALID;
+	       break;
+	  }
 	  if(scsi_encap(sim, ccb))
 	       return;
 	  break;
@@ -273,12 +292,16 @@
 int
 ic_getCamVals(isc_session_t *sp, iscsi_cam_t *cp)
 {
+     int	i;
+
      debug_called(8);
 
      if(sp && sp->isc->cam_sim) {
 	  cp->path_id = cam_sim_path(sp->isc->cam_sim);
 	  cp->target_id = sp->sid;
-	  cp->target_lun = 0; // XXX: always 0?
+	  cp->target_nluns = sp->target_nluns; // XXX: -1?
+	  for(i = 0; i < cp->target_nluns; i++)
+	       cp->target_lun[i] = sp->target_lun[i];
 	  return 0;
      }
      return ENXIO;

==== //depot/projects/iscsi/src/sys/dev/iscsi/isc_sm.c#3 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 /*
  | iSCSI - Session Manager
- | $Id: isc_sm.c,v 1.19 2005/06/03 12:02:50 danny Exp danny $
+ | $Id: isc_sm.c,v 1.20 2005/09/25 11:56:07 danny Exp danny $
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -144,24 +144,26 @@
 static void
 _nop_out(isc_session_t *sp)
 {
-#if 0
      pduq_t	*pq;
      nop_out_t	*nop_out;
 
      debug_called(8);
-     if((pq = pdu_alloc(sp->isc)) == NULL)
-	  // I guess we ran out of resources
-	  return;
-     nop_out = &pq->pdu.ipdu.nop_out;
-     nop_out->opcode = ISCSI_NOP_OUT;
-     nop_out->itt = htonl(sp->sn.itt);
-     nop_out->ttt = -1;
-     pq->pdu.ipdu.bhs.I = 1;
-     if(isc_qout(sp, pq) != 0) {
-	  sdebug(1, "failed");
-	  pdu_free(sp->isc, pq);
+
+     sdebug(4, "cws=%d", sp->cws);
+     if(sp->cws == 0) {
+	  if((pq = pdu_alloc(sp->isc, 0)) == NULL)
+	       // I guess we ran out of resources
+	       return;
+	  nop_out = &pq->pdu.ipdu.nop_out;
+	  nop_out->opcode = ISCSI_NOP_OUT;
+	  nop_out->itt = htonl(sp->sn.itt);
+	  nop_out->ttt = -1;
+	  pq->pdu.ipdu.bhs.I = 1;
+	  if(isc_qout(sp, pq) != 0) {
+	       sdebug(1, "failed");
+	       pdu_free(sp->isc, pq);
+	  }
      }
-#endif
 }
 
 static void
@@ -277,7 +279,13 @@
 
      if(pq->len == 0 && (error = i_prepPDU(sp, pq)))
 	  return error;
-     i_nqueue_snd(sp, pq);
+     if(pq->pdu.ipdu.bhs.I)
+	  i_nqueue_isnd(sp, pq);
+     else
+     if(pq->pdu.ipdu.data_out.opcode == ISCSI_WRITE_DATA)
+	  i_nqueue_wsnd(sp, pq);
+     else
+	  i_nqueue_csnd(sp, pq);
 
      sdebug(5, "enqued: pq=%p", pq);
 
@@ -295,8 +303,7 @@
      sdebug(3, "start=%d", flag);
 
      if(flag) {
-	  sp->flags |= ISC_FFPHASE;
-	  error = ic_newdev(dev);
+	  error = ic_fullfeature(dev);
      }
      else {
 	  sp->flags &= ~ISC_FFPHASE;
@@ -306,82 +313,80 @@
      return error;
 }
 
-static int
-proc_in(isc_session_t *sp)
+void
+ism_recv(isc_session_t *sp, pduq_t *pq)
 {
-     pduq_t	*pq;
      bhs_t	*bhs;
      sn_t	*sn = &sp->sn;
-     int	statSN, ndone = 0;
+     int	statSN;
 
      debug_called(8);
 
-     while((pq = i_dqueue_rsv(sp)) != NULL) {
-	  ndone++;
-	  bhs = &pq->pdu.ipdu.bhs;
-	  statSN = ntohl(bhs->OpcodeSpecificFields[1]);
-	  sn->maxCmd = ntohl(bhs->MaxCmdSN);
-	  sn->expCmd = ntohl(bhs->ExpStSN);
+     bhs = &pq->pdu.ipdu.bhs;
+     statSN = ntohl(bhs->OpcodeSpecificFields[1]);
 
-	  if(sn->maxCmd + 1 == sn->expCmd) {
-	       sdebug(2, "window closed: 0x%x 0x%x ", sn->maxCmd, sn->expCmd);
+     if(sp->cws == 0) {
+	  if((sp->flags & ISC_FROZEN) == 0) {
+	       //iscsi_debug = 9;
+	       sdebug(3, "window closed: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.",
+		      sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws);
 	       // window closed
 	       ic_freeze(sp);
-	  } else 
+	  }
+     } else 
 	  if(sp->flags & ISC_FROZEN) {
-	       sdebug(2, "window opened: 0x%x 0x%x ", sn->maxCmd, sn->expCmd);
+	       sdebug(3, "window opened: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.",
+		      sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws);
 	       ic_release(sp);
 	  }
 
 #if notyet
-	  if(sp->sn.expCmd != sp->sn.cmd) {
-	       sdebug(1, "we lost something ... exp=0x%x cmd=0x%x",
-		      sp->sn.expCmd, sp->sn.cmd);
-	  }
+     if(sp->sn.expCmd != sn->cmd) {
+	  sdebug(1, "we lost something ... exp=0x%x cmd=0x%x",
+		 sn->expCmd, sn->cmd);
+     }
 #endif
-	  sdebug(5, "opcode=0x%x itt=0x%x stat#0x%x maxcmd=0x%0x",
-		 bhs->opcode, ntohl(bhs->itt), statSN, sp->sn.maxCmd);
+     sdebug(5, "opcode=0x%x itt=0x%x stat#0x%x maxcmd=0x%0x",
+	    bhs->opcode, ntohl(bhs->itt), statSN, sp->sn.maxCmd);
 
-	  switch(bhs->opcode) {
-	  case ISCSI_READ_DATA: {
-	       data_in_t 	*cmd = &pq->pdu.ipdu.data_in;
+     switch(bhs->opcode) {
+     case ISCSI_READ_DATA: {
+	  data_in_t 	*cmd = &pq->pdu.ipdu.data_in;
 
-	       if(cmd->S == 0)
-		    break;
-	  }
+	  if(cmd->S == 0)
+	       break;
+     }
 
-	  default:
-	       if(statSN > (sp->sn.stat + 1)) {
-		    sdebug(1, "we lost some rec=0x%x exp=0x%x",
-			   statSN, sp->sn.stat);
-		    // XXX: must do some error recovery here.
-	       }
-	       sp->sn.stat = statSN;
+     default:
+	  if(statSN > (sp->sn.stat + 1)) {
+	       sdebug(1, "we lost some rec=0x%x exp=0x%x",
+		      statSN, sp->sn.stat);
+	       // XXX: must do some error recovery here.
 	  }
+	  sp->sn.stat = statSN;
+     }
 
-	  switch(bhs->opcode) {
-	  case ISCSI_LOGIN_RSP:
-	  case ISCSI_TEXT_RSP:
-	  case ISCSI_LOGOUT_RSP:
-	       i_nqueue_rsp(sp, pq);
-	       wakeup(&sp->rsp);
-	       break;
+     switch(bhs->opcode) {
+     case ISCSI_LOGIN_RSP:
+     case ISCSI_TEXT_RSP:
+     case ISCSI_LOGOUT_RSP:
+	  i_nqueue_rsp(sp, pq);
+	  wakeup(&sp->rsp);
+	  break;
 
-	  case ISCSI_NOP_IN:	_nop_in(sp, pq);	break;
-	  case ISCSI_SCSI_RSP:	_scsi_rsp(sp, pq);	break;
-	  case ISCSI_READ_DATA:	_read_data(sp, pq);	break;
-	  case ISCSI_R2T:	_r2t(sp, pq);		break;
-	  case ISCSI_REJECT:	_reject(sp, pq);	break;
-	  case ISCSI_ASYNC:	_async(sp, pq);		break;
+     case ISCSI_NOP_IN:	_nop_in(sp, pq);	break;
+     case ISCSI_SCSI_RSP:	_scsi_rsp(sp, pq);	break;
+     case ISCSI_READ_DATA:	_read_data(sp, pq);	break;
+     case ISCSI_R2T:	_r2t(sp, pq);		break;
+     case ISCSI_REJECT:	_reject(sp, pq);	break;
+     case ISCSI_ASYNC:	_async(sp, pq);		break;
 
-	  case ISCSI_TASK_RSP:
-	  default:
-	       sdebug(1, "opcode=0x%x itt=0x%x not implemented yet",
-		      bhs->opcode, ntohl(bhs->itt));
-	       break;
-	  }
+     case ISCSI_TASK_RSP:
+     default:
+	  sdebug(1, "opcode=0x%x itt=0x%x not implemented yet",
+		 bhs->opcode, ntohl(bhs->itt));
+	  break;
      }
-     return ndone;
 }
 
 static int
@@ -390,27 +395,40 @@
      sn_t	*sn = &sp->sn;
      pduq_t	*pq;
      int	error, ndone = 0;
+     int	which;
 
      debug_called(8);
 
-     while((pq = i_dqueue_snd(sp)) != NULL) {
+     which = BIT(0) | BIT(1) | BIT(2); // all queues
+
+     while(1) {
 	  pdu_t *pp;
 	  bhs_t	*bhs;
 
-	  error = 0;
+	  /*
+	   | check if there is outstanding work in:
+	   | 1- the Inmediate queue
+	   | 2- the R2T queue
+	   | 3- the cmd queue, only if the command window allows it.
+	   */
+	  which = BIT(0) | BIT(1);
+	  if(SNA_GT(sn->cmd, sn->maxCmd) == 0)
+	       which |= BIT(2);
+
+	  if((pq = i_dqueue_snd(sp, which)) == NULL)
+	       break;
+
 	  pp = &pq->pdu;
 	  bhs = &pp->ipdu.bhs;
 	  sdebug(5, "opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)",
 		bhs->opcode,
 		sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt);
-	  
 
 	  switch(bhs->opcode) {
 	  case ISCSI_SCSI_CMD:
 	       sn->itt++;
-	       bhs->itt		= htonl(sn->itt);
+	       bhs->itt = htonl(sn->itt);
 
-	  case ISCSI_WRITE_DATA:
 	  case ISCSI_LOGIN_CMD:
 	  case ISCSI_TEXT_CMD:
 	  case ISCSI_LOGOUT_CMD:
@@ -418,15 +436,16 @@
 	  case ISCSI_NOP_OUT:
 	  case ISCSI_TASK_CMD:
 	       bhs->CmdSN = htonl(sn->cmd);
+	       if(bhs->I == 0)
+		    sn->cmd++;
+
+	  case ISCSI_WRITE_DATA:
 	       if(bhs->opcode == ISCSI_NOP_OUT)
 		    bhs->ExpStSN = htonl(sn->stat);
 	       else
 		    bhs->ExpStSN = htonl(sn->stat + 1);
 	       break;
 	  }
-	  if(bhs->I == 0 && (bhs->opcode != ISCSI_WRITE_DATA))
-	       sn->cmd++;
-
 	  if(pq->ccb) 
 	       i_nqueue_hld(sp, pq);
 
@@ -445,34 +464,35 @@
 		    xdebug("error=%d", error);
 	       }
 	  }
-
 	  if(pq->ccb == NULL || error)
 	       pdu_free(sp->isc, pq);
      }
      return ndone;
 }
 /*
- | this is the main 'engine'
- | it survives link breakdowns.
+ | survives link breakdowns.
  */
 static void
 ism_proc(void *vp)
 {
      isc_session_t 	*sp = (isc_session_t *)vp;
-     int		odone, idone;
+     int		odone;
 
      debug_called(8);
      sdebug(2, "started");
 
      sp->flags |= ISC_SM_RUN;
      do {
-	  idone = proc_in(sp);
 	  odone = proc_out(sp);
-	  sdebug(7, "idone=%d odone=%d", idone, odone);
-	  if(!idone && !odone) {
-	       if((tsleep(sp, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK)
+	  sdebug(7, "odone=%d", odone);
+	  if(odone == 0) {
+	       mtx_lock(&sp->io_mtx);
+	       sp->flags |= ISC_IWAITING;
+	       if((msleep(sp, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK)
 		  && (sp->flags & ISC_CON_RUN))
 		    _nop_out(sp);
+	       sp->flags &= ~ISC_IWAITING;
+	       mtx_unlock(&sp->io_mtx);
 	  }
      } while(sp->flags & ISC_SM_RUN);
 
@@ -507,7 +527,9 @@
      */
      TAILQ_INIT(&sp->rsp);
      TAILQ_INIT(&sp->rsv);
-     TAILQ_INIT(&sp->snd);
+     TAILQ_INIT(&sp->csnd);
+     TAILQ_INIT(&sp->isnd);
+     TAILQ_INIT(&sp->wsnd);
      TAILQ_INIT(&sp->hld);
 #if 1
      mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_DEF);

==== //depot/projects/iscsi/src/sys/dev/iscsi/isc_soc.c#3 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 /*
  | iSCSI
- | $Id: isc_soc.c,v 1.15 2005/05/08 10:08:10 danny Exp danny $
+ | $Id: isc_soc.c,v 1.16 2005/09/09 09:44:38 danny Exp danny $
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -57,33 +57,34 @@
  | from the socket.
  */
 static int
-so_getbhs(struct socket *so, bhs_t *bhs)
+so_getbhs(isc_session_t *sp)
 {
-     struct uio		uio;
-     struct iovec	iov;
+     bhs_t *bhs		= &sp->bhs;
+     struct uio		*uio = &sp->uio;
+     struct iovec	*iov = &sp->iov;
      int		error, flags;
 
      debug_called(8);
 
-     iov.iov_base	= bhs;
-     iov.iov_len	= sizeof(bhs_t);
+     iov->iov_base	= bhs;
+     iov->iov_len	= sizeof(bhs_t);
 
-     uio.uio_iov	= &iov;
-     uio.uio_iovcnt	= 1;
-     uio.uio_rw		= UIO_READ;
-     uio.uio_segflg	= UIO_SYSSPACE;
-     uio.uio_td		= curthread; // why ...
-     uio.uio_resid	= sizeof(bhs_t);
+     uio->uio_iov	= iov;
+     uio->uio_iovcnt	= 1;
+     uio->uio_rw	= UIO_READ;
+     uio->uio_segflg	= UIO_SYSSPACE;
+     uio->uio_td	= curthread; // why ...
+     uio->uio_resid	= sizeof(bhs_t);
 
      flags = MSG_WAITALL;
-     error = soreceive(so, NULL, &uio, 0, 0, &flags);
-     if(!error && uio.uio_resid > 0) {
+     error = soreceive(sp->soc, NULL, uio, 0, 0, &flags);
+     if(!error && uio->uio_resid > 0) {
 #if __FreeBSD_version <  600000
-	  debug(5, "so_error=%d uio.uio_resid=%d iov.iov_len=%d",
+	  debug(5, "so_error=%d uio->uio_resid=%d iov.iov_len=%d",
 #else
-	  debug(5, "so_error=%d uio.uio_resid=%d iov.iov_len=%zd",
+	  debug(5, "so_error=%d uio->uio_resid=%d iov.iov_len=%zd",
 #endif
-		so->so_error, uio.uio_resid, iov.iov_len);
+		sp->soc->so_error, uio->uio_resid, iov->iov_len);
 	  error = EPIPE;
      }
      return error;
@@ -97,11 +98,13 @@
 so_recv(isc_session_t *sp, pduq_t *pq)
 {
      struct socket	*so = sp->soc;
-     struct uio		uio;
+     sn_t		*sn = &sp->sn;
+     struct uio		*uio = &pq->uio;
      pdu_t		*pp;
      int		error;
      size_t		n, len;
      bhs_t		*bhs;
+     u_int		max, exp;
 
      debug_called(8);
      /*
@@ -147,20 +150,36 @@
      if(len) {
 	  int	flags;
 
-	  uio.uio_resid = len;
-	  uio.uio_td = curthread; // why ...
+	  uio->uio_resid = len;
+	  uio->uio_td = curthread; // why ...
 	  flags = MSG_WAITALL;
 
-	  error = soreceive(so, NULL, &uio, &pq->mp, NULL, &flags);
-	  if(error || uio.uio_resid)
+	  error = soreceive(so, NULL, uio, &pq->mp, NULL, &flags);
+	  if(error || uio->uio_resid)
 	       goto out;
      }
 
-     sdebug(5, "opcode=%x ahs_len=%x ds_len=%x",
+     sdebug(5, "opcode=0x%x ahs_len=0x%x ds_len=0x%x",
 	    bhs->opcode, pp->ahs_len, pp->ds_len);
-     i_nqueue_rsv(sp, pq);
-     wakeup(sp);
-     sp->stats.nrecv++;
+
+
+     max = ntohl(bhs->MaxCmdSN);
+     exp = ntohl(bhs->ExpStSN);
+
+
+     if(max < exp - 1 &&
+	max > exp - _MAXINCR) {
+	  sdebug(2,  "bad cmd window size");
+	  error = EIO; // XXX: for now;
+	  goto out; // error
+     }
+
+     if(SNA_GT(max, sn->maxCmd))
+	  sn->maxCmd = max;
+
+     if(SNA_GT(exp, sn->expCmd))
+	  sn->expCmd = exp;
+     sp->cws = sn->maxCmd - sn->expCmd + 1;
 
      return 0;
 
@@ -168,7 +187,7 @@
      // XXX: need some work here
      xdebug("have a problem, error=%d", error);
      pdu_free(sp->isc, pq);
-     if(!error && uio.uio_resid > 0)
+     if(!error && uio->uio_resid > 0)
 	  error = EPIPE;
      return error;
 }
@@ -177,22 +196,22 @@
 isc_sendPDU(isc_session_t *sp, pduq_t *pq)
 {
      pdu_t		*pp = &pq->pdu;
-     struct uio		uio;
-     struct iovec	iov[5], *iv;
+     struct uio		*uio = &pq->uio;
+     struct iovec	*iv;
      int		len, error;
 
      debug_called(8);
 
-     bzero(&uio, sizeof(struct uio));
+     bzero(uio, sizeof(struct uio));
 
-     uio.uio_rw		= UIO_WRITE;
-     uio.uio_segflg	= UIO_SYSSPACE;
-     uio.uio_td		= sp->td;
-     uio.uio_iov = iv	= iov;
+     uio->uio_rw	= UIO_WRITE;
+     uio->uio_segflg	= UIO_SYSSPACE;
+     uio->uio_td	= sp->td;
+     uio->uio_iov 	= iv = pq->iov;
 
      iv->iov_base	= &pp->ipdu;
      iv->iov_len	= sizeof(union ipdu_u);
-     uio.uio_resid	= pq->len;
+     uio->uio_resid	= pq->len;
      iv++;
 
      if(pp->ahs_len) {
@@ -201,7 +220,7 @@
 	  iv++;
      }
      if(sp->hdrDigest) {
-	  pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, uio.uio_resid);
+	  pq->pdu.hdr_dig = sp->hdrDigest(&pp->ipdu, uio->uio_resid);
 	  iv->iov_base	= &pp->hdr_dig;
 	  iv->iov_len	= sizeof(int);
 	  iv++;
@@ -209,7 +228,7 @@
      if(pq->pdu.ds) {
 	  iv->iov_base	= pp->ds;
 	  iv->iov_len	= pp->ds_len;
-	  while(iv->iov_len & 03) // the specs say it must be int allingned
+	  while(iv->iov_len & 03) // the specs say it must be int alligned
 	       iv->iov_len++;
 	  iv++;
      }
@@ -219,26 +238,26 @@
 	  iv->iov_len	= sizeof(int);
 	  iv++;
      }
-     uio.uio_iovcnt	= iv - iov;
+     uio->uio_iovcnt	= iv - pq->iov;
      sdebug(5, "opcode=%x iovcnt=%d uio_resid=%d itt=%x",
-	    pp->ipdu.bhs.opcode, uio.uio_iovcnt, uio.uio_resid,
+	    pp->ipdu.bhs.opcode, uio->uio_iovcnt, uio->uio_resid,
 	    ntohl(pp->ipdu.bhs.itt));
+     sp->stats.nsent++;
      do {
-	  len = uio.uio_resid;
-	  error = sosend(sp->soc, NULL, &uio, 0, 0, 0, sp->td);
-	  if(uio.uio_resid == 0 || error || len == uio.uio_resid) {
-	       if(uio.uio_resid != 0) {
-		    sdebug(3, "uio.uio_resid=%d uio.uio_iovcnt=%d error=%d len=%d",
-			   uio.uio_resid, uio.uio_iovcnt, error, len);
+	  len = uio->uio_resid;
+	  error = sosend(sp->soc, NULL, uio, 0, 0, 0, sp->td);
+	  if(uio->uio_resid == 0 || error || len == uio->uio_resid) {
+	       if(uio->uio_resid != 0) {
+		    sdebug(3, "uio->uio_resid=%d uio->uio_iovcnt=%d error=%d len=%d",
+			   uio->uio_resid, uio->uio_iovcnt, error, len);
 	       }
 	       break;
 	  }
-	  // XXX: can this really happen?
-	  sdebug(1, "uio.uio_resid=%d uio.uio_iovcnt=%d",
-		uio.uio_resid, uio.uio_iovcnt);
-	  iv = uio.uio_iov;
-	  len -= uio.uio_resid;
-	  while(uio.uio_iovcnt > 0) {
+	  sdebug(1, "uio->uio_resid=%d uio->uio_iovcnt=%d",
+		uio->uio_resid, uio->uio_iovcnt);
+	  iv = uio->uio_iov;
+	  len -= uio->uio_resid;
+	  while(uio->uio_iovcnt > 0) {
 	       if(iv->iov_len > len) {
 		    caddr_t	bp = (caddr_t)iv->iov_base;
 
@@ -247,18 +266,18 @@
 		    break;
 	       }
 	       len -= iv->iov_len;
-	       uio.uio_iovcnt--;
-	       uio.uio_iov++;
+	       uio->uio_iovcnt--;
+	       uio->uio_iov++;
 	       iv++;
 	  }
-     } while(uio.uio_resid);
+     } while(uio->uio_resid);
 
      return error;
 }
 /*
  | one per active session.
  | wait for something to arrive.
- | and if the pdu is without errors, queue it.
+ | and if the pdu is without errors, process it.
  */
 static void
 isc_soc(void *vp)
@@ -280,27 +299,32 @@
 	  ic_release(sp);
 
      while((sp->flags & ISC_CON_RUN) && (so->so_state & SS_ISCONNECTED)) {
-	  bhs_t		bhs;
 	  /*
 	   | first read in the iSCSI header
 	   */
-	  error = so_getbhs(so, &bhs);
+	  error = so_getbhs(sp);
 	  if(error) {
 	       if(error == EPIPE)
 		    break;
 	  }
 	  else {
-	       if((pq = pdu_alloc(sp->isc)) == NULL) {
-		    // Note: choose a less drastic way out
-		    xdebug("out of pdus");
-		    break;
-	       }
-	       pq->pdu.ipdu.bhs = bhs;
+	       sp->flags |= ISC_MEMWAIT;
+	       pq = pdu_alloc(sp->isc, 1);  // OK to WAIT
+	       sp->flags &= ~ISC_MEMWAIT;
+
+	       pq->pdu.ipdu.bhs = sp->bhs;
 	       if(so_recv(sp, pq)) {
 		    // terminal error
 		    // XXX: close connection and exit
 		    break;
 	       }
+	       ism_recv(sp, pq);
+
+	       mtx_lock(&sp->io_mtx);
+	       if(sp->flags & ISC_IWAITING)
+		    wakeup(sp);
+	       mtx_unlock(&sp->io_mtx);
+	       sp->stats.nrecv++;
 	  }
      }
      sdebug(2, "terminated flags=%x so_count=%d so_state=%x error=%d",

==== //depot/projects/iscsi/src/sys/dev/iscsi/isc_subr.c#3 (text+ko) ====

@@ -67,7 +67,7 @@
 	  pdu_free(sp->isc, pq);
 	  n++;
      }
-     while((pq = i_dqueue_snd(sp)) != NULL) {
+     while((pq = i_dqueue_snd(sp, -1)) != NULL) {
 	  pdu_free(sp->isc, pq);
 	  n++;
      }

==== //depot/projects/iscsi/src/sys/dev/iscsi/iscsi.c#3 (text+ko) ====

@@ -26,7 +26,7 @@
  */
 /*
  | iSCSI
- | $Id: iscsi.c,v 1.25 2005/05/07 07:28:39 danny Exp danny $
+ | $Id: iscsi.c,v 1.26 2005/09/11 12:39:14 danny Exp danny $
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -49,6 +49,7 @@
 #include <sys/mbuf.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
+#include <vm/uma.h>
 
 #include <dev/iscsi/iscsi.h>
 #include <dev/iscsi/iscsivar.h>
@@ -283,38 +284,46 @@
 	       pukeit(i, pq); i++;
 	       uiomove(buf, strlen(buf), uio);
 	  }
-	  sprintf(buf, "/---- rsv -----/\n");
+	  sprintf(buf, "/---- csnd -----/\n");
 	  i = 0;
 	  uiomove(buf, strlen(buf), uio);
-	  TAILQ_FOREACH(pq, &sp->rsv, pq_link) {
+	  TAILQ_FOREACH(pq, &sp->csnd, pq_link) {
 	       if(uio->uio_resid == 0)
 		    return 0;
 	       pukeit(i, pq); i++;
 	       uiomove(buf, strlen(buf), uio);
 	  }
-
-	  sprintf(buf, "/---- snd -----/\n");
+	  sprintf(buf, "/---- wsnd -----/\n");
 	  i = 0;
 	  uiomove(buf, strlen(buf), uio);
-	  TAILQ_FOREACH(pq, &sp->snd, pq_link) {
+	  TAILQ_FOREACH(pq, &sp->wsnd, pq_link) {
 	       if(uio->uio_resid == 0)
 		    return 0;
 	       pukeit(i, pq); i++;
 	       uiomove(buf, strlen(buf), uio);
 	  }
-
-	  sprintf(buf, "/---- pdu free -----/\n");
+	  sprintf(buf, "/---- isnd -----/\n");
 	  i = 0;
 	  uiomove(buf, strlen(buf), uio);
-	  TAILQ_FOREACH(pq, &sc->free_pdus, pq_link) {
+	  TAILQ_FOREACH(pq, &sp->isnd, pq_link) {
 	       if(uio->uio_resid == 0)
 		    return 0;
 	       pukeit(i, pq); i++;
 	       uiomove(buf, strlen(buf), uio);
 	  }
 
-	  sprintf(buf, "last cmd=%x stat=%x itt=%x\n",
-		  sp->sn.cmd, sp->sn.stat, sp->sn.itt);
+	  sprintf(buf, "/---- Stats ---/\n");
+	  uiomove(buf, strlen(buf), uio);
+
+	  sprintf(buf, "recv=%d sent=%d\n", sp->stats.nrecv, sp->stats.nsent);
+	  uiomove(buf, strlen(buf), uio);
+
+	  sprintf(buf, "flags=%x pdus: free=%d alloc=%d max=%d\n", 
+		  sp->flags, sc->npdu_free, sc->npdu_alloc, sc->npdu_max);
+	  uiomove(buf, strlen(buf), uio);
+
+	  sprintf(buf, "cws=%d last cmd=%x exp=%x max=%x stat=%x itt=%x\n",
+		  sp->cws, sp->sn.cmd, sp->sn.expCmd, sp->sn.maxCmd, sp->sn.stat, sp->sn.itt);
 	  uiomove(buf, strlen(buf), uio);
 
 	  sprintf(buf, "/---- socket -----/\nso_count=%d so_state=%x\n", so->so_count, so->so_state);
@@ -345,7 +354,7 @@
 
      debug_called(8);
 
-     if((pq = pdu_alloc(sc)) == NULL)
+     if((pq = pdu_alloc(sc, 0)) == NULL)
 	  return EAGAIN;
      pp = &pq->pdu;
 
@@ -514,8 +523,18 @@
      sc->dev->si_drv1 = sc;
 
      TAILQ_INIT(&sc->isc_sess);
-     TAILQ_INIT(&sc->free_pdus);
-
+     
+     sc->pdu_zone = uma_zcreate("pdu", sizeof(pduq_t),
+				NULL, NULL, NULL, NULL,
+				0, 0);
+     if(sc->pdu_zone == NULL) {
+	  printf("iscsi_initiator: uma_zcreate failed");
+	  // XXX: and now what?
+     }
+     uma_zone_set_max(sc->pdu_zone, MAX_PDUS*2+1);
+#ifdef ISCSI_DEBUG
+     sc->npdu_free = MAX_PDUS*2+1;
+#endif
      mtx_init(&sc->mtx, "iscsi", NULL, MTX_DEF);
      mtx_init(&sc->mtx_pdu, "iscsi pdu pool", NULL, MTX_DEF);
 
@@ -546,6 +565,8 @@
 
      ic_destroy(sc);
 
+     uma_zdestroy(sc->pdu_zone);
+
      if(sc->dev)
 	  destroy_dev(sc->dev);
 }

==== //depot/projects/iscsi/src/sys/dev/iscsi/iscsi.h#2 (text+ko) ====

@@ -37,6 +37,10 @@
 
 #define ISCSIDEV	"iscsi"
 
+#define ISCSI_MAX_TARGETS	4 //64
+	
+#define ISCSI_MAX_LUNS		4
+
 /*
  | iSCSI commands
  */
@@ -394,7 +398,8 @@
 typedef struct iscsi_cam {
      path_id_t		path_id;
      target_id_t	target_id;
-     lun_id_t		target_lun;
+     int		target_nluns;
+     lun_id_t		target_lun[ISCSI_MAX_LUNS];
 } iscsi_cam_t;
 
 #define ISCSIGETCAM	_IOR('i', 32, iscsi_cam_t)

==== //depot/projects/iscsi/src/sys/dev/iscsi/iscsi_subr.c#3 (text+ko) ====

@@ -35,6 +35,7 @@
 #include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
+#include <sys/uio.h>
 
 #include <cam/cam.h>
 #include <cam/cam_ccb.h>
@@ -79,8 +80,9 @@
 	       dsn = 0;
 	       sdebug(5, "edtl=%x ddtl=%x bo=%x dsn=%x bs=%x", edtl, ddtl, bo, dsn, bs);
 	       while(bleft > 0) {
-		    wpq = pdu_alloc(sp->isc);
+		    wpq = pdu_alloc(sp->isc, 1);
 		    if(wpq == NULL) {
+			 // should not happen if above is 1
 			 sdebug(1, "now what?");
 			 return;
 		    }
@@ -252,6 +254,47 @@
 }
 
 /*
+ | deal with lun
+ */
+static int
+dwl(isc_session_t *sp, int lun, u_char *lp)
+{
+     int	i;
+
+     debug_called(8);
+
+     /*
+      | mapping LUN to iSCSI LUN
+      | check the SAM-2 specs
+      | hint: maxLUNS is a small number, cam's LUN is 32bits
+      | iSCSI is 64bits, scsi is ?
+      */
+     // XXX: check if this will pass the endian test
+     if(lun < 256) {
+	  lp[0] = 0;
+	  lp[1] = lun;
+     } else
+     if(lun < 16384) {
+	  lp[0] = (1 << 5) | ((lun >> 8) & 0x3f);
+	  lp[1] = lun & 0xff;
+     } 
+     else {
+	  xdebug("lun %d: is unsupported!", lun);
+	  return -1;
+     }
+
+     for(i = 0; i < sp->target_nluns; i++)
+	  if(sp->target_lun[i] == lun)
+	       return 0;
+     if(sp->target_nluns < ISCSI_MAX_LUNS)
+	  sp->target_lun[sp->target_nluns++] = lun;
+
+     sdebug(3, "nluns=%d lun=%d", sp->target_nluns, lun);
+
+     return 0;
+}
+
+/*
  | encapsulate the scsi command and 
  */
 int
@@ -269,19 +312,19 @@
      debug(6, "ccb->sp=%p", ccb_h->spriv_ptr0);
      sp = ccb_h->spriv_ptr0;
 
-    if((pq = pdu_alloc(isp)) == NULL) {
+     if((pq = pdu_alloc(isp, 1)) == NULL) { // cannot happen
 	  sdebug(3, "freezing");
 	  ccb->ccb_h.status = CAM_REQUEUE_REQ;
 	  ic_freeze(sp);
 	  return 0;
      }
-
+#if 0
      if((sp->flags & ISC_FFPHASE) == 0) {
 	  ccb->ccb_h.status = CAM_DEV_NOT_THERE; // CAM_NO_NEXUS;
 	  sdebug(3, "no active session with target %d", ccb_h->target_id);
 	  goto bad;
      }

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list