Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 27 Aug 2011 12:10:12 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r225211 - projects/zfsd/head/sys/cam/scsi
Message-ID:  <201108271210.p7RCACgb002936@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108271210.p7RCACgb002936>