Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/iscsi/iscsi.c
Show First 20 Lines • Show All 1,198 Lines • ▼ Show 20 Lines | if (total_len == 0 || total_len > csio->dxfer_len) { | ||||
return; | return; | ||||
} | } | ||||
//ISCSI_SESSION_DEBUG(is, "r2t; off %zd, len %zd", off, total_len); | //ISCSI_SESSION_DEBUG(is, "r2t; off %zd, len %zd", off, total_len); | ||||
for (;;) { | for (;;) { | ||||
len = total_len; | len = total_len; | ||||
if (len > is->is_max_data_segment_length) | if (len > is->is_max_send_data_segment_length) | ||||
len = is->is_max_data_segment_length; | len = is->is_max_send_data_segment_length; | ||||
if (off + len > csio->dxfer_len) { | if (off + len > csio->dxfer_len) { | ||||
ISCSI_SESSION_WARN(is, "target requested invalid " | ISCSI_SESSION_WARN(is, "target requested invalid " | ||||
"length/offset %zd, buffer is %d; reconnecting", | "length/offset %zd, buffer is %d; reconnecting", | ||||
off + len, csio->dxfer_len); | off + len, csio->dxfer_len); | ||||
icl_pdu_free(response); | icl_pdu_free(response); | ||||
iscsi_session_reconnect(is); | iscsi_session_reconnect(is); | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 91 Lines • ▼ Show 20 Lines | iscsi_pdu_handle_reject(struct icl_pdu *response) | ||||
icl_pdu_free(response); | icl_pdu_free(response); | ||||
} | } | ||||
static int | static int | ||||
iscsi_ioctl_daemon_wait(struct iscsi_softc *sc, | iscsi_ioctl_daemon_wait(struct iscsi_softc *sc, | ||||
struct iscsi_daemon_request *request) | struct iscsi_daemon_request *request) | ||||
{ | { | ||||
struct iscsi_session *is; | struct iscsi_session *is; | ||||
struct icl_drv_limits idl; | |||||
int error; | int error; | ||||
sx_slock(&sc->sc_lock); | sx_slock(&sc->sc_lock); | ||||
for (;;) { | for (;;) { | ||||
TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { | TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { | ||||
ISCSI_SESSION_LOCK(is); | ISCSI_SESSION_LOCK(is); | ||||
if (is->is_conf.isc_enable == 0 && | if (is->is_conf.isc_enable == 0 && | ||||
is->is_conf.isc_discovery == 0) { | is->is_conf.isc_discovery == 0) { | ||||
Show All 23 Lines | for (;;) { | ||||
ISCSI_SESSION_UNLOCK(is); | ISCSI_SESSION_UNLOCK(is); | ||||
request->idr_session_id = is->is_id; | request->idr_session_id = is->is_id; | ||||
memcpy(&request->idr_isid, &is->is_isid, | memcpy(&request->idr_isid, &is->is_isid, | ||||
sizeof(request->idr_isid)); | sizeof(request->idr_isid)); | ||||
request->idr_tsih = 0; /* New or reinstated session. */ | request->idr_tsih = 0; /* New or reinstated session. */ | ||||
memcpy(&request->idr_conf, &is->is_conf, | memcpy(&request->idr_conf, &is->is_conf, | ||||
sizeof(request->idr_conf)); | sizeof(request->idr_conf)); | ||||
error = icl_limits(is->is_conf.isc_offload, | error = icl_limits(is->is_conf.isc_offload, | ||||
is->is_conf.isc_iser, | is->is_conf.isc_iser, &idl); | ||||
&request->idr_limits.isl_max_data_segment_length); | |||||
if (error != 0) { | if (error != 0) { | ||||
ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" " | ISCSI_SESSION_WARN(is, "icl_limits for offload \"%s\" " | ||||
"failed with error %d", is->is_conf.isc_offload, | "failed with error %d", is->is_conf.isc_offload, | ||||
error); | error); | ||||
sx_sunlock(&sc->sc_lock); | sx_sunlock(&sc->sc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
request->idr_limits.isl_max_recv_data_segment_length = | |||||
idl.idl_max_recv_data_segment_length; | |||||
request->idr_limits.isl_max_send_data_segment_length = | |||||
idl.idl_max_recv_data_segment_length; | |||||
request->idr_limits.isl_max_burst_length = | |||||
idl.idl_max_burst_length; | |||||
request->idr_limits.isl_first_burst_length = | |||||
idl.idl_first_burst_length; | |||||
sx_sunlock(&sc->sc_lock); | sx_sunlock(&sc->sc_lock); | ||||
return (0); | return (0); | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc, | iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc, | ||||
Show All 38 Lines | iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc, | ||||
strlcpy(is->is_target_alias, handoff->idh_target_alias, | strlcpy(is->is_target_alias, handoff->idh_target_alias, | ||||
sizeof(is->is_target_alias)); | sizeof(is->is_target_alias)); | ||||
is->is_tsih = handoff->idh_tsih; | is->is_tsih = handoff->idh_tsih; | ||||
is->is_statsn = handoff->idh_statsn; | is->is_statsn = handoff->idh_statsn; | ||||
is->is_initial_r2t = handoff->idh_initial_r2t; | is->is_initial_r2t = handoff->idh_initial_r2t; | ||||
is->is_immediate_data = handoff->idh_immediate_data; | is->is_immediate_data = handoff->idh_immediate_data; | ||||
/* | is->is_max_recv_data_segment_length = | ||||
* Cap MaxRecvDataSegmentLength obtained from the target to the maximum | handoff->idh_max_recv_data_segment_length; | ||||
* size supported by our ICL module. | is->is_max_send_data_segment_length = | ||||
*/ | handoff->idh_max_send_data_segment_length; | ||||
is->is_max_data_segment_length = min(ic->ic_max_data_segment_length, | |||||
handoff->idh_max_data_segment_length); | |||||
is->is_max_burst_length = handoff->idh_max_burst_length; | is->is_max_burst_length = handoff->idh_max_burst_length; | ||||
is->is_first_burst_length = handoff->idh_first_burst_length; | is->is_first_burst_length = handoff->idh_first_burst_length; | ||||
if (handoff->idh_header_digest == ISCSI_DIGEST_CRC32C) | if (handoff->idh_header_digest == ISCSI_DIGEST_CRC32C) | ||||
ic->ic_header_crc32c = true; | ic->ic_header_crc32c = true; | ||||
else | else | ||||
ic->ic_header_crc32c = false; | ic->ic_header_crc32c = false; | ||||
if (handoff->idh_data_digest == ISCSI_DIGEST_CRC32C) | if (handoff->idh_data_digest == ISCSI_DIGEST_CRC32C) | ||||
▲ Show 20 Lines • Show All 195 Lines • ▼ Show 20 Lines | iscsi_ioctl_daemon_send(struct iscsi_softc *sc, | ||||
if (is->is_login_phase == false) | if (is->is_login_phase == false) | ||||
return (EBUSY); | return (EBUSY); | ||||
if (is->is_terminating || is->is_reconnecting) | if (is->is_terminating || is->is_reconnecting) | ||||
return (EIO); | return (EIO); | ||||
datalen = ids->ids_data_segment_len; | datalen = ids->ids_data_segment_len; | ||||
if (datalen > ISCSI_MAX_DATA_SEGMENT_LENGTH) | if (datalen > is->is_max_send_data_segment_length) | ||||
return (EINVAL); | return (EINVAL); | ||||
if (datalen > 0) { | if (datalen > 0) { | ||||
data = malloc(datalen, M_ISCSI, M_WAITOK); | data = malloc(datalen, M_ISCSI, M_WAITOK); | ||||
error = copyin(ids->ids_data_segment, data, datalen); | error = copyin(ids->ids_data_segment, data, datalen); | ||||
if (error != 0) { | if (error != 0) { | ||||
free(data, M_ISCSI); | free(data, M_ISCSI); | ||||
return (error); | return (error); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 282 Lines • ▼ Show 20 Lines | TAILQ_FOREACH(is, &sc->sc_sessions, is_next) { | ||||
else | else | ||||
iss.iss_header_digest = ISCSI_DIGEST_NONE; | iss.iss_header_digest = ISCSI_DIGEST_NONE; | ||||
if (is->is_conn->ic_data_crc32c) | if (is->is_conn->ic_data_crc32c) | ||||
iss.iss_data_digest = ISCSI_DIGEST_CRC32C; | iss.iss_data_digest = ISCSI_DIGEST_CRC32C; | ||||
else | else | ||||
iss.iss_data_digest = ISCSI_DIGEST_NONE; | iss.iss_data_digest = ISCSI_DIGEST_NONE; | ||||
iss.iss_max_data_segment_length = is->is_max_data_segment_length; | iss.iss_max_send_data_segment_length = | ||||
is->is_max_send_data_segment_length; | |||||
iss.iss_max_recv_data_segment_length = | |||||
is->is_max_recv_data_segment_length; | |||||
iss.iss_max_burst_length = is->is_max_burst_length; | iss.iss_max_burst_length = is->is_max_burst_length; | ||||
iss.iss_first_burst_length = is->is_first_burst_length; | iss.iss_first_burst_length = is->is_first_burst_length; | ||||
iss.iss_immediate_data = is->is_immediate_data; | iss.iss_immediate_data = is->is_immediate_data; | ||||
iss.iss_connected = is->is_connected; | iss.iss_connected = is->is_connected; | ||||
error = copyout(&iss, isl->isl_pstates + i, sizeof(iss)); | error = copyout(&iss, isl->isl_pstates + i, sizeof(iss)); | ||||
if (error != 0) { | if (error != 0) { | ||||
sx_sunlock(&sc->sc_lock); | sx_sunlock(&sc->sc_lock); | ||||
return (error); | return (error); | ||||
} | } | ||||
i++; | i++; | ||||
} | } | ||||
sx_sunlock(&sc->sc_lock); | sx_sunlock(&sc->sc_lock); | ||||
▲ Show 20 Lines • Show All 304 Lines • ▼ Show 20 Lines | #endif | ||||
else | else | ||||
memcpy(&bhssc->bhssc_cdb, csio->cdb_io.cdb_bytes, csio->cdb_len); | memcpy(&bhssc->bhssc_cdb, csio->cdb_io.cdb_bytes, csio->cdb_len); | ||||
if (is->is_immediate_data && | if (is->is_immediate_data && | ||||
(csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { | (csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT) { | ||||
len = csio->dxfer_len; | len = csio->dxfer_len; | ||||
//ISCSI_SESSION_DEBUG(is, "adding %zd of immediate data", len); | //ISCSI_SESSION_DEBUG(is, "adding %zd of immediate data", len); | ||||
if (len > is->is_first_burst_length) { | if (len > is->is_first_burst_length) { | ||||
ISCSI_SESSION_DEBUG(is, "len %zd -> %zd", len, is->is_first_burst_length); | ISCSI_SESSION_DEBUG(is, "len %zd -> %d", len, is->is_first_burst_length); | ||||
len = is->is_first_burst_length; | len = is->is_first_burst_length; | ||||
} | } | ||||
if (len > is->is_max_data_segment_length) { | if (len > is->is_max_send_data_segment_length) { | ||||
ISCSI_SESSION_DEBUG(is, "len %zd -> %zd", len, is->is_max_data_segment_length); | ISCSI_SESSION_DEBUG(is, "len %zd -> %d", len, | ||||
len = is->is_max_data_segment_length; | is->is_max_send_data_segment_length); | ||||
len = is->is_max_send_data_segment_length; | |||||
} | } | ||||
error = icl_pdu_append_data(request, csio->data_ptr, len, M_NOWAIT); | error = icl_pdu_append_data(request, csio->data_ptr, len, M_NOWAIT); | ||||
if (error != 0) { | if (error != 0) { | ||||
iscsi_outstanding_remove(is, io); | iscsi_outstanding_remove(is, io); | ||||
icl_pdu_free(request); | icl_pdu_free(request); | ||||
if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { | if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { | ||||
xpt_freeze_devq(ccb->ccb_h.path, 1); | xpt_freeze_devq(ccb->ccb_h.path, 1); | ||||
▲ Show 20 Lines • Show All 280 Lines • Show Last 20 Lines |