Skip to content

Commit

Permalink
checkpoint current iscsi changes
Browse files Browse the repository at this point in the history
  • Loading branch information
kmacy committed May 4, 2012
1 parent 6254db1 commit 129c149
Show file tree
Hide file tree
Showing 8 changed files with 348 additions and 106 deletions.
77 changes: 68 additions & 9 deletions sys/dev/iscsi/initiator/isc_cam.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");

#include "opt_iscsi_initiator.h"


#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/callout.h>
Expand All @@ -45,6 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/uio.h>
#include <sys/sysctl.h>
#include <sys/socketvar.h>
#include <sys/sx.h>

#include <cam/cam.h>
Expand All @@ -54,6 +56,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_periph.h>

#include <dev/iscsi/initiator/iscsi.h>
#include <dev/iscsi/initiator/iscsiopt.h>
#include <dev/iscsi/initiator/iscsivar.h>

static void
Expand All @@ -74,7 +77,7 @@ _inq(struct cam_sim *sim, union ccb *ccb)
cpi->initiator_id = ISCSI_MAX_TARGETS;
cpi->max_lun = sp->opt.maxluns - 1;
cpi->bus_id = cam_sim_bus(sim);
cpi->base_transfer_speed = 3300; // 40000; // XXX:
cpi->base_transfer_speed = 3300000; // 40000; // XXX:
strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
strncpy(cpi->hba_vid, "iSCSI", HBA_IDLEN);
strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
Expand Down Expand Up @@ -197,10 +200,25 @@ ic_action(struct cam_sim *sim, union ccb *ccb)
return;
}
switch(ccb_h->func_code) {
case XPT_PATH_INQ:
_inq(sim, ccb);
break;

case XPT_PATH_INQ:
{
struct ccb_pathinq *cpi = &ccb->cpi;

_inq(sim, ccb);
cpi->version_num = 1;
cpi->target_sprt = 0;
cpi->hba_misc = 0;
cpi->unit_number = cam_sim_unit(sim);
cpi->bus_id = cam_sim_bus(sim);
cpi->base_transfer_speed = 132 * 1024; /* XXX what to set this to? */
cpi->transport = XPORT_SPI;
cpi->transport_version = 2;
cpi->protocol = PROTO_SCSI;
cpi->protocol_version = SCSI_REV_2;
cpi->maxio = 128*PAGE_SIZE;
ccb->ccb_h.status = CAM_REQ_CMP;
break;
}
case XPT_RESET_BUS: // (can just be a stub that does nothing and completes)
{
struct ccb_pathinq *cpi = &ccb->cpi;
Expand All @@ -213,6 +231,7 @@ ic_action(struct cam_sim *sim, union ccb *ccb)
case XPT_SCSI_IO:
{
struct ccb_scsiio* csio = &ccb->csio;
int status, rc;

debug(4, "XPT_SCSI_IO cmd=0x%x", csio->cdb_io.cdb_bytes[0]);
if(sp == NULL) {
Expand All @@ -225,8 +244,24 @@ ic_action(struct cam_sim *sim, union ccb *ccb)
ccb_h->status = CAM_LUN_INVALID;
break;
}
if(_scsi_encap(sim, ccb) != 0)
return;

rc = _scsi_encap(sim, ccb);
if (rc == 0)
return;

if (rc == EWOULDBLOCK) {
if (sim->devq->send_queue.qfrozen_cnt[0] == 0) {
xpt_freeze_simq(sim, 1);
CAM_UNLOCK(sp);
SOCKBUF_LOCK(&sp->soc->so_snd);
soupcall_set(sp->soc, SO_SND, isc_so_snd_upcall, sp);
SOCKBUF_UNLOCK(&sp->soc->so_snd);
CAM_LOCK(sp);
}
status = ccb->ccb_h.status &= ~CAM_STATUS_MASK;
csio->ccb_h.status = status | CAM_REQUEUE_REQ;
break;
}
break;
}

Expand Down Expand Up @@ -268,6 +303,30 @@ ic_action(struct cam_sim *sim, union ccb *ccb)
}

case XPT_GET_TRAN_SETTINGS:
{
struct ccb_trans_settings *cts = &ccb->cts;
int bus, target;
struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi;
struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi;

bus = cam_sim_bus(sim);
target = cts->ccb_h.target_id;

debug(1, "XPT_GET_TRAN_SETTINGS %d:%d", bus, target);
/* disconnect always OK */
cts->protocol = PROTO_SCSI;
cts->protocol_version = SCSI_REV_2;
cts->transport = XPORT_SPI;
cts->transport_version = 2;
spi->valid = CTS_SPI_VALID_DISC;
spi->flags = CTS_SPI_FLAGS_DISC_ENB;

scsi->valid = CTS_SCSI_VALID_TQ;
scsi->flags = CTS_SCSI_FLAGS_TAG_ENB;

cts->ccb_h.status = CAM_REQ_CMP;
break;
}
default:
ccb_h->status = CAM_REQ_INVALID;
break;
Expand Down Expand Up @@ -348,8 +407,8 @@ ic_init(isc_session_t *sp)
#if __FreeBSD_version >= 700000
&sp->cam_mtx,
#endif
1, // max_dev_transactions
0, // max_tagged_dev_transactions
256, // max_dev_transactions
256, // max_tagged_dev_transactions
devq);
if(sim == NULL) {
cam_simq_free(devq);
Expand Down
148 changes: 123 additions & 25 deletions sys/dev/iscsi/initiator/isc_sm.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
#include <sys/protosw.h>
#include <sys/proc.h>
#include <sys/ioccom.h>
#include <sys/queue.h>
#include <sys/kthread.h>
#include <sys/syslog.h>
#include <sys/mbuf.h>
Expand All @@ -63,8 +62,35 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_periph.h>

#include <dev/iscsi/initiator/iscsi.h>
#include <dev/iscsi/initiator/iscsiopt.h>
#include <dev/iscsi/initiator/iscsivar.h>

static int proc_out(isc_session_t *sp);

void
pdu_free(struct isc_softc *isc, pduq_t *pq)
{
KASSERT(pq->pq_link.tqe_next == NULL ||
pq->pq_link.tqe_next == (void *) -1,
("tqe_next still set %p", pq->pq_link.tqe_next));
KASSERT(pq->pq_link.tqe_prev == NULL ||
pq->pq_link.tqe_prev == (void *) -1,
("tqe_prev still set %p", pq->pq_link.tqe_prev));
if(pq->mp)
m_freem(pq->mp);
#ifdef NO_USE_MBUF
if(pq->buf != NULL)
free(pq->buf, M_ISCSIBUF);
#endif
uma_zfree(isc->pdu_zone, pq);
#ifdef ISCSI_INITIATOR_DEBUG
mtx_lock(&iscsi_dbg_mtx);
isc->npdu_alloc--;
mtx_unlock(&iscsi_dbg_mtx);
#endif
}


static void
_async(isc_session_t *sp, pduq_t *pq)
{
Expand Down Expand Up @@ -112,7 +138,7 @@ _r2t(isc_session_t *sp, pduq_t *pq)
debug_called(8);
opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1);
if(opq != NULL) {
iscsi_r2t(sp, opq, pq);
iscsi_r2t(sp, opq, pq);
}
else {
r2t_t *r2t = &pq->pdu.ipdu.r2t;
Expand Down Expand Up @@ -188,7 +214,6 @@ _nop_out(isc_session_t *sp)
nop_out->F = 1;
if(isc_qout(sp, pq) != 0) {
sdebug(1, "failed");
pdu_free(sp->isc, pq);
}
}
}
Expand Down Expand Up @@ -302,15 +327,67 @@ i_prepPDU(isc_session_t *sp, pduq_t *pq)
}

int
isc_qout(isc_session_t *sp, pduq_t *pq)
isc_sowouldblock(isc_session_t *sp, union ccb *ccb)
{
int error = 0;
struct ccb_scsiio *csio = &ccb->csio;
int space_needed;

if (ccb == NULL)
return (0);

space_needed = 256 + csio->cdb_len;
if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
space_needed += csio->dxfer_len;
if (space_needed > sp->soc->so_snd.sb_mbmax)
sp->soc->so_snd.sb_mbmax = space_needed + PAGE_SIZE;
if (space_needed > sp->soc->so_snd.sb_hiwat)
sp->soc->so_snd.sb_hiwat = space_needed + PAGE_SIZE;
debug(4, "space_needed=%d sbspace=%ld",
space_needed, sbspace(&sp->soc->so_snd));
if ((space_needed > sbspace(&sp->soc->so_snd)) &&
(space_needed > sp->space_needed))
sp->space_needed = space_needed;
return (space_needed > sbspace(&sp->soc->so_snd));
}

debug_called(8);

if(pq->len == 0 && (error = i_prepPDU(sp, pq)))
return error;
int
isc_so_snd_upcall(struct socket *so, void *arg, int flags)
{
isc_session_t *sp = arg;

if (sbspace(&so->so_snd) < sp->space_needed)
return (SU_OK);

soupcall_clear(so, SO_SND);
sp->space_needed = 0;

mtx_lock(sp->cam_sim->mtx);
xpt_release_simq(sp->cam_sim, 0);
mtx_unlock(sp->cam_sim->mtx);
return (SU_OK);
}

int
isc_qout(isc_session_t *sp, pduq_t *pq)
{
int txed = 0, error = 0;

debug_called(8);

if(pq->len == 0 && (error = i_prepPDU(sp, pq))) {
pdu_free(sp->isc, pq);
return (error);
}
if ((sp->flags & ISC_HOLD) || (sp->soc == NULL)) {
pdu_free(sp->isc, pq);
return (EWOULDBLOCK);
}
if (isc_sowouldblock(sp, pq->ccb)) {
pdu_free(sp->isc, pq);
return (EWOULDBLOCK);
}

if(pq->pdu.ipdu.bhs.I)
i_nqueue_isnd(sp, pq);
else
Expand All @@ -321,12 +398,16 @@ isc_qout(isc_session_t *sp, pduq_t *pq)

sdebug(5, "enqued: pq=%p", pq);

mtx_lock(&sp->io_mtx);
sp->flags |= ISC_OQNOTEMPTY;
if(sp->flags & ISC_OWAITING)
wakeup(&sp->flags);
mtx_unlock(&sp->io_mtx);

if (sx_try_xlock(&sp->tx_sx)) {
error = proc_out(sp);
txed = 1;
sx_xunlock(&sp->tx_sx);
}
if (txed == 0) {
mtx_lock(&sp->io_mtx);
sp->flags |= ISC_OQNOTEMPTY;
mtx_unlock(&sp->io_mtx);
}
return error;
}
/*
Expand Down Expand Up @@ -425,11 +506,12 @@ proc_out(isc_session_t *sp)
{
sn_t *sn = &sp->sn;
pduq_t *pq;
int error, which;
int error, which, flags;

debug_called(8);
error = 0;

restart:
while(sp->flags & ISC_LINK_UP) {
pdu_t *pp;
bhs_t *bhs;
Expand Down Expand Up @@ -509,15 +591,26 @@ proc_out(isc_session_t *sp)
default:
if(pq->ccb) {
xdebug("back to cam");
pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error?
XPT_DONE(sp, pq->ccb);
pdu_free(sp->isc, pq);
if (error == ENOBUFS || error == EHOSTUNREACH ||
error == EPIPE || error == ENETDOWN)
error = EWOULDBLOCK;
return (error);
}
else
xdebug("we lost it!");
}
}
}
if (error == 0) {
mtx_lock(&sp->io_mtx);
flags = sp->flags;
sp->flags &= ~ISC_OQNOTEMPTY;
mtx_unlock(&sp->io_mtx);
if ((flags & (ISC_LINK_UP|ISC_OQNOTEMPTY)) ==
(ISC_LINK_UP|ISC_OQNOTEMPTY))
goto restart;
}

return error;
}

Expand All @@ -535,20 +628,23 @@ ism_out(void *vp)
sp->flags |= ISC_SM_RUNNING;
sdebug(3, "started sp->flags=%x", sp->flags);
do {
if((sp->flags & ISC_HOLD) == 0) {
error = proc_out(sp);
if(error) {
sdebug(3, "error=%d", error);
}
}
if((sp->flags & ISC_HOLD) == 0) {
error = 0;
if (sx_try_xlock(&sp->tx_sx)) {
error = proc_out(sp);
sx_xunlock(&sp->tx_sx);
}
if(error) {
sdebug(3, "error=%d", error);
}
}
mtx_lock(&sp->io_mtx);
if((sp->flags & ISC_LINK_UP) == 0) {
sdebug(3, "ISC_LINK_UP==0, sp->flags=%x ", sp->flags);
if(sp->soc != NULL)
sdebug(3, "so_state=%x", sp->soc->so_state);
wakeup(&sp->soc);
}

if(!(sp->flags & ISC_OQNOTEMPTY)) {
sp->flags |= ISC_OWAITING;
if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) {
Expand Down Expand Up @@ -743,6 +839,7 @@ ism_stop(isc_session_t *sp)
mtx_destroy(&sp->hld_mtx);
mtx_destroy(&sp->snd_mtx);
mtx_destroy(&sp->io_mtx);
sx_destroy(&sp->tx_sx);

i_freeopt(&sp->opt);

Expand Down Expand Up @@ -771,6 +868,7 @@ ism_start(isc_session_t *sp)
mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_DEF);
mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_DEF);
mtx_init(&sp->io_mtx, "iscsi-io", NULL, MTX_DEF);
sx_init(&sp->tx_sx, "iscsi-tx");

isc_add_sysctls(sp);

Expand Down
Loading

0 comments on commit 129c149

Please sign in to comment.