summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/cam_periph.c58
-rw-r--r--sys/cam/cam_periph.h3
2 files changed, 59 insertions, 2 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index e260f17..694bc5e 100644
--- a/sys/cam/cam_periph.c
+++ b/sys/cam/cam_periph.c
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cam_periph.c,v 1.2 1998/09/20 07:14:36 gibbs Exp $
+ * $Id: cam_periph.c,v 1.3 1998/09/29 09:18:08 bde Exp $
*/
#include <sys/param.h>
@@ -903,6 +903,8 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
sizeof(union ccb));
+ periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
+
xpt_action(done_ccb);
break;
@@ -969,6 +971,8 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
bcopy(done_ccb->ccb_h.saved_ccb_ptr,
done_ccb, sizeof(union ccb));
+ periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
+
xpt_action(done_ccb);
}
} else {
@@ -981,6 +985,8 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
bcopy(done_ccb->ccb_h.saved_ccb_ptr,
done_ccb, sizeof(union ccb));
+ periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
+
xpt_action(done_ccb);
}
@@ -989,6 +995,8 @@ camperiphdone(struct cam_periph *periph, union ccb *done_ccb)
bcopy(done_ccb->ccb_h.saved_ccb_ptr, done_ccb,
sizeof(union ccb));
+ periph->flags &= ~CAM_PERIPH_RECOVERY_INPROG;
+
xpt_action(done_ccb);
break;
@@ -1084,6 +1092,28 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
&& save_ccb != NULL
&& ccb->ccb_h.retry_count > 0) {
+ /*
+ * Since error recovery is already
+ * in progress, don't attempt to
+ * process this error. It is probably
+ * related to the error that caused
+ * the currently active error recovery
+ * action. Also, we only have
+ * space for one saved CCB, so if we
+ * had two concurrent error recovery
+ * actions, we would end up
+ * over-writing one error recovery
+ * CCB with another one.
+ */
+ if (periph->flags &
+ CAM_PERIPH_RECOVERY_INPROG) {
+ error = ERESTART;
+ break;
+ }
+
+ periph->flags |=
+ CAM_PERIPH_RECOVERY_INPROG;
+
/* decrement the number of retries */
if ((err_action &
SSQ_DECREMENT_COUNT) != 0) {
@@ -1154,6 +1184,19 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
&& ccb->ccb_h.retry_count > 0) {
int le;
+ /*
+ * Only one error recovery action
+ * at a time. See above.
+ */
+ if (periph->flags &
+ CAM_PERIPH_RECOVERY_INPROG) {
+ error = ERESTART;
+ break;
+ }
+
+ periph->flags |=
+ CAM_PERIPH_RECOVERY_INPROG;
+
/* decrement the number of retries */
retry = 1;
ccb->ccb_h.retry_count--;
@@ -1232,6 +1275,19 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
&& ccb->ccb_h.retry_count > 0) {
int le;
+ /*
+ * Only one error recovery action
+ * at a time. See above.
+ */
+ if (periph->flags &
+ CAM_PERIPH_RECOVERY_INPROG) {
+ error = ERESTART;
+ break;
+ }
+
+ periph->flags |=
+ CAM_PERIPH_RECOVERY_INPROG;
+
/* decrement the number of retries */
retry = 1;
ccb->ccb_h.retry_count--;
diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h
index 04437d3..8e81526 100644
--- a/sys/cam/cam_periph.h
+++ b/sys/cam/cam_periph.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: cam_periph.h,v 1.1 1998/09/15 06:33:23 gibbs Exp $
*/
#ifndef _CAM_CAM_PERIPH_H
@@ -83,6 +83,7 @@ struct cam_periph {
#define CAM_PERIPH_LOCK_WANTED 0x04
#define CAM_PERIPH_INVALID 0x08
#define CAM_PERIPH_NEW_DEV_FOUND 0x10
+#define CAM_PERIPH_RECOVERY_INPROG 0x20
u_int32_t immediate_priority;
u_int32_t refcount;
SLIST_HEAD(, ccb_hdr) ccb_list; /* For "immediate" requests */
OpenPOWER on IntegriCloud