svn commit: r225211 - projects/zfsd/head/sys/cam/scsi
Alexander Motin
mav at FreeBSD.org
Sat Aug 27 12:10:12 UTC 2011
Author: mav
Date: Sat Aug 27 12:10:12 2011
New Revision: 225211
URL: http://svn.freebsd.org/changeset/base/225211
Log:
Fix/Implement I/O errors handling:
- make done() method called even after I/O errors to handle them,
- pass error argument to done() method,
- return error code to user-level.
Modified:
projects/zfsd/head/sys/cam/scsi/scsi_enc.c
projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c
projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc.c Sat Aug 27 12:09:06 2011 (r225210)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc.c Sat Aug 27 12:10:12 2011 (r225211)
@@ -739,6 +739,7 @@ enc_fsm_step(enc_softc_t *enc)
uint8_t *buf;
struct enc_fsm_state *cur_state;
int error;
+ uint32_t xfer_len;
ENC_DLOG(enc, "%s enter %p\n", __func__, enc);
@@ -760,30 +761,27 @@ enc_fsm_step(enc_softc_t *enc)
ccb = cam_periph_getccb(enc->periph, CAM_PRIORITY_NORMAL);
error = cur_state->fill(enc, cur_state, ccb, buf);
- if (error == 0) {
- error = cam_periph_runccb(ccb, cur_state->error,
- ENC_CFLAGS,
- ENC_FLAGS|SF_QUIET_IR, NULL);
- }
- }
+ if (error != 0)
+ goto done;
-
- if (error == 0) {
- uint32_t len;
+ error = cam_periph_runccb(ccb, cur_state->error,
+ ENC_CFLAGS,
+ ENC_FLAGS|SF_QUIET_IR, NULL);
+ }
- len = 0;
- if (ccb != NULL) {
- if (ccb->ccb_h.func_code == XPT_ATA_IO)
- len = ccb->ataio.dxfer_len - ccb->ataio.resid;
- else
- len = ccb->csio.dxfer_len - ccb->csio.resid;
- }
+ if (ccb != NULL) {
+ if (ccb->ccb_h.func_code == XPT_ATA_IO)
+ xfer_len = ccb->ataio.dxfer_len - ccb->ataio.resid;
+ else
+ xfer_len = ccb->csio.dxfer_len - ccb->csio.resid;
+ } else
+ xfer_len = 0;
- cam_periph_unlock(enc->periph);
- cur_state->done(enc, cur_state, ccb, &buf, len);
- cam_periph_lock(enc->periph);
- }
+ cam_periph_unlock(enc->periph);
+ cur_state->done(enc, cur_state, ccb, &buf, error, xfer_len);
+ cam_periph_lock(enc->periph);
+done:
ENC_DLOG(enc, "%s exit - result %d\n", __func__, error);
ENC_FREE_AND_NULL(buf);
if (ccb != NULL)
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h Sat Aug 27 12:09:06 2011 (r225210)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_internal.h Sat Aug 27 12:10:12 2011 (r225211)
@@ -72,7 +72,7 @@ typedef int fsm_error_handler_t(union cc
uint32_t sflags);
typedef int fsm_done_handler_t(enc_softc_t *ssc,
struct enc_fsm_state *state, union ccb *ccb,
- uint8_t **bufp, int xfer_len);
+ uint8_t **bufp, int error, int xfer_len);
struct enc_fsm_state {
const char *name;
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c Sat Aug 27 12:09:06 2011 (r225210)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_safte.c Sat Aug 27 12:10:12 2011 (r225211)
@@ -247,7 +247,7 @@ safte_fill_read_buf_io(enc_softc_t *enc,
static int
safte_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct scfg *cfg;
uint8_t *buf = *bufp;
@@ -256,7 +256,8 @@ safte_process_config(enc_softc_t *enc, s
cfg = enc->enc_private;
if (cfg == NULL)
return (ENXIO);
-
+ if (error != 0)
+ return (error);
if (xfer_len < 6) {
ENC_LOG(enc, "too little data (%d) for configuration\n",
xfer_len);
@@ -320,7 +321,7 @@ safte_process_config(enc_softc_t *enc, s
static int
safte_process_gflags(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct scfg *cfg;
uint8_t *buf = *bufp;
@@ -328,7 +329,8 @@ safte_process_gflags(enc_softc_t *enc, s
cfg = enc->enc_private;
if (cfg == NULL)
return (ENXIO);
-
+ if (error != 0)
+ return (error);
SAFT_BAIL(3, xfer_len);
cfg->flag1 = buf[1];
cfg->flag2 = buf[2];
@@ -344,7 +346,7 @@ safte_process_gflags(enc_softc_t *enc, s
static int
safte_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct scfg *cfg;
uint8_t *buf = *bufp;
@@ -355,6 +357,8 @@ safte_process_status(enc_softc_t *enc, s
cfg = enc->enc_private;
if (cfg == NULL)
return (ENXIO);
+ if (error != 0)
+ return (error);
oid = r = 0;
cfg->enc_status = 0;
@@ -651,7 +655,7 @@ safte_process_status(enc_softc_t *enc, s
static int
safte_process_slotstatus(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct scfg *cfg;
uint8_t *buf = *bufp;
@@ -661,7 +665,8 @@ safte_process_slotstatus(enc_softc_t *en
cfg = enc->enc_private;
if (cfg == NULL)
return (ENXIO);
-
+ if (error != 0)
+ return (error);
cfg->slot_status = 0;
oid = cfg->slotoff;
for (r = i = 0; i < cfg->Nslots; i++, r += 4) {
@@ -940,7 +945,7 @@ safte_fill_control_request(enc_softc_t *
static int
safte_process_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct scfg *cfg;
safte_control_request_t *req;
@@ -950,8 +955,10 @@ safte_process_control_request(enc_softc_
if (cfg == NULL)
return (ENXIO);
+ req = cfg->current_request;
+ if (req->result == 0)
+ req->result = error;
if (++cfg->current_request_stage >= cfg->current_request_stages) {
- req = cfg->current_request;
idx = req->elm_idx;
if (idx == SES_SETSTATUS_ENC_IDX)
type = -1;
@@ -962,7 +969,6 @@ safte_process_control_request(enc_softc_
else
enc_update_request(enc, SAFTE_UPDATE_READENCSTATUS);
cfg->current_request = NULL;
- req->result = 0;
wakeup(req);
} else {
enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
@@ -1046,6 +1052,7 @@ safte_set_enc_status(enc_softc_t *enc, u
req.elm_idx = SES_SETSTATUS_ENC_IDX;
req.elm_stat[0] = encstat & 0xf;
+ req.result = 0;
TAILQ_INSERT_TAIL(&cfg->requests, &req, links);
enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
@@ -1082,6 +1089,7 @@ safte_set_elm_status(enc_softc_t *enc, e
req.elm_idx = elms->elm_idx;
memcpy(&req.elm_stat, elms->cstat, sizeof(req.elm_stat));
+ req.result = 0;
TAILQ_INSERT_TAIL(&cfg->requests, &req, links);
enc_update_request(enc, SAFTE_PROCESS_CONTROL_REQS);
Modified: projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c
==============================================================================
--- projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c Sat Aug 27 12:09:06 2011 (r225210)
+++ projects/zfsd/head/sys/cam/scsi/scsi_enc_ses.c Sat Aug 27 12:10:12 2011 (r225211)
@@ -1234,7 +1234,7 @@ out:
*/
static int
ses_process_pages(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
ses_softc_t *ses;
struct scsi_diag_page *page;
@@ -1245,6 +1245,10 @@ ses_process_pages(enc_softc_t *enc, stru
ses = enc->enc_private;
err = -1;
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
if (xfer_len < sizeof(*page)) {
ENC_LOG(enc, "Unable to parse Diag Pages List Header\n");
err = EIO;
@@ -1283,7 +1287,7 @@ out:
*/
static int
ses_process_config(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct ses_iterator iter;
ses_softc_t *ses;
@@ -1315,6 +1319,10 @@ ses_process_config(enc_softc_t *enc, str
buf = *bufp;
err = -1;;
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
if (xfer_len < sizeof(cfg_page->hdr)) {
ENC_LOG(enc, "Unable to parse SES Config Header\n");
err = EIO;
@@ -1492,7 +1500,7 @@ out:
*/
static int
ses_process_status(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct ses_iterator iter;
enc_element_t *element;
@@ -1515,6 +1523,10 @@ ses_process_status(enc_softc_t *enc, str
page = (struct ses_status_page *)buf;
length = ses_page_length(&page->hdr);
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
/*
* Make sure the length fits in the buffer.
*
@@ -1660,7 +1672,7 @@ static int ses_get_elm_addlstatus_sas(en
*/
static int
ses_process_elm_addlstatus(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct ses_iterator iter;
int eip;
@@ -1679,6 +1691,10 @@ ses_process_elm_addlstatus(enc_softc_t *
buf = *bufp;
err = -1;
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
ses_cache_free_elm_addlstatus(enc, enc_cache);
ses_cache->elm_addlstatus_page =
(struct ses_addl_elem_status_page *)buf;
@@ -1813,7 +1829,7 @@ out:
static int
ses_process_control_request(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
ses_softc_t *ses;
@@ -1823,14 +1839,14 @@ ses_process_control_request(enc_softc_t
* o Generation count wrong.
* o Some SCSI status error.
*/
- ses_terminate_control_requests(&ses->ses_pending_requests, 0);
+ ses_terminate_control_requests(&ses->ses_pending_requests, error);
enc_update_request(enc, SES_UPDATE_GETSTATUS);
return (0);
}
static int
ses_publish_physpaths(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
struct ses_iterator iter;
enc_cache_t *enc_cache;
@@ -1857,7 +1873,7 @@ ses_publish_physpaths(enc_softc_t *enc,
static int
ses_publish_cache(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
sx_xlock(&enc->enc_cache_lock);
@@ -1879,7 +1895,7 @@ ses_publish_cache(enc_softc_t *enc, stru
*/
static int
ses_process_elm_descs(enc_softc_t *enc, struct enc_fsm_state *state,
- union ccb *ccb, uint8_t **bufp, int xfer_len)
+ union ccb *ccb, uint8_t **bufp, int error, int xfer_len)
{
ses_softc_t *ses;
struct ses_iterator iter;
@@ -1900,6 +1916,10 @@ ses_process_elm_descs(enc_softc_t *enc,
buf = *bufp;
err = -1;
+ if (error != 0) {
+ err = error;
+ goto out;
+ }
ses_cache_free_elm_descs(enc, enc_cache);
ses_cache->elm_descs_page = (struct ses_elem_descr_page *)buf;
*bufp = NULL;
More information about the svn-src-projects
mailing list