diff options
-rw-r--r-- | sys/cam/cam_periph.c | 58 | ||||
-rw-r--r-- | sys/cam/cam_periph.h | 3 |
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 */ |