From owner-p4-projects@FreeBSD.ORG Fri Nov 11 06:07:38 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id D14F116A421; Fri, 11 Nov 2005 06:07:37 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A70B116A41F for ; Fri, 11 Nov 2005 06:07:37 +0000 (GMT) (envelope-from scottl@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 533BB43D45 for ; Fri, 11 Nov 2005 06:07:37 +0000 (GMT) (envelope-from scottl@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id jAB67bTo068998 for ; Fri, 11 Nov 2005 06:07:37 GMT (envelope-from scottl@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id jAB67aRR068995 for perforce@freebsd.org; Fri, 11 Nov 2005 06:07:36 GMT (envelope-from scottl@freebsd.org) Date: Fri, 11 Nov 2005 06:07:36 GMT Message-Id: <200511110607.jAB67aRR068995@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to scottl@freebsd.org using -f From: Scott Long To: Perforce Change Reviews Cc: Subject: PERFORCE change 86632 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Nov 2005 06:07:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=86632 Change 86632 by scottl@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 #include #include +#include #include #include @@ -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 #include @@ -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 #include @@ -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 #include @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -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 #include #include +#include #include #include @@ -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) <<<