Put a bit of hysteresis into both BUSY SCSI status returns
authorPeter Avalos <pavalos@dragonflybsd.org>
Sun, 2 Dec 2007 04:54:40 +0000 (04:54 +0000)
committerPeter Avalos <pavalos@dragonflybsd.org>
Sun, 2 Dec 2007 04:54:40 +0000 (04:54 +0000)
and CAM_RESRC_UNAVAIL returns. Delay a tunable amount for
either between retries.

This came up because the MPT IOC was returning "IOC out of
resources" for some FreeBSD users and this caused a CAM_RESRC_UNAVAIL
return. Putting a bit of delay between retries helped them
out.

Obtained-from: FreeBSD

sys/bus/cam/cam_periph.c

index 8e45f68..21143d9 100644 (file)
@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/cam_periph.c,v 1.24.2.3 2003/01/25 19:04:40 dillon Exp $
- * $DragonFly: src/sys/bus/cam/cam_periph.c,v 1.38 2007/12/01 22:54:18 pavalos Exp $
+ * $DragonFly: src/sys/bus/cam/cam_periph.c,v 1.39 2007/12/02 04:54:40 pavalos Exp $
  */
 
 #include <sys/param.h>
@@ -84,6 +84,14 @@ struct periph_driver **periph_drivers;
 
 MALLOC_DEFINE(M_CAMPERIPH, "CAM periph", "CAM peripheral buffers");
 
+static int periph_selto_delay = 1000;
+TUNABLE_INT("kern.cam.periph_selto_delay", &periph_selto_delay);
+static int periph_noresrc_delay = 500;
+TUNABLE_INT("kern.cam.periph_noresrc_delay", &periph_noresrc_delay);
+static int periph_busy_delay = 500;
+TUNABLE_INT("kern.cam.periph_busy_delay", &periph_busy_delay);
+
+
 void
 periphdriver_register(void *data)
 {
@@ -1511,7 +1519,7 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
        int         error, printed = 0;
        int         openings;
        u_int32_t   relsim_flags;
-       u_int32_t   timeout;
+       u_int32_t   timeout = 0;
 
        action_string = NULL;
        status = ccb->ccb_h.status;
@@ -1599,11 +1607,11 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
                                }
 
                                /*
-                                * Wait a second to give the device
+                                * Wait a bit to give the device
                                 * time to recover before we try again.
                                 */
                                relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
-                               timeout = 1000;
+                               timeout = periph_selto_delay;
                                break;
                        }
                }
@@ -1662,8 +1670,16 @@ cam_periph_error(union ccb *ccb, cam_flags camflags,
                }
                break;
        case CAM_RESRC_UNAVAIL:
+               /* Wait a bit for the resource shortage to abate. */
+               timeout = periph_noresrc_delay;
+               /* FALLTHROUGH */
        case CAM_BUSY:
-               /* timeout??? */
+               if (timeout == 0) {
+                       /* Wait a bit for the busy condition to abate. */
+                       timeout = periph_busy_delay;
+               }
+               relsim_flags = RELSIM_RELEASE_AFTER_TIMEOUT;
+               /* FALLTHROUGH */
        default:
                /* decrement the number of retries */
                if (ccb->ccb_h.retry_count > 0) {