summaryrefslogtreecommitdiff
path: root/sys/dev/mly
diff options
context:
space:
mode:
authorScott Long <scottl@FreeBSD.org>2003-02-06 23:46:32 +0000
committerScott Long <scottl@FreeBSD.org>2003-02-06 23:46:32 +0000
commitff1e67ab93b687713a7db64e757c10beeefa2a3b (patch)
treefbd8a1d143b689a14f38f67fdf3515dab271c860 /sys/dev/mly
parent2d979824f5b3f13b7a82da5d185c40a92cae2926 (diff)
Notes
Diffstat (limited to 'sys/dev/mly')
-rw-r--r--sys/dev/mly/mly.c46
-rw-r--r--sys/dev/mly/mlyvar.h2
2 files changed, 48 insertions, 0 deletions
diff --git a/sys/dev/mly/mly.c b/sys/dev/mly/mly.c
index 50b81ac30cb2..a91b2956158a 100644
--- a/sys/dev/mly/mly.c
+++ b/sys/dev/mly/mly.c
@@ -121,6 +121,7 @@ static void mly_print_packet(struct mly_command *mc);
static void mly_panic(struct mly_softc *sc, char *reason);
#endif
void mly_print_controller(int controller);
+static int mly_timeout(struct mly_softc *sc);
static d_open_t mly_user_open;
@@ -129,6 +130,7 @@ static d_ioctl_t mly_user_ioctl;
static int mly_user_command(struct mly_softc *sc, struct mly_user_command *uc);
static int mly_user_health(struct mly_softc *sc, struct mly_user_health *uh);
+#define MLY_CMD_TIMEOUT 20
static device_method_t mly_methods[] = {
/* Device interface */
@@ -330,6 +332,10 @@ mly_attach(device_t dev)
/* enable interrupts now */
MLY_UNMASK_INTERRUPTS(sc);
+#ifdef MLY_DEBUG
+ timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz);
+#endif
+
out:
if (error != 0)
mly_free(sc);
@@ -1473,6 +1479,10 @@ mly_start(struct mly_command *mc)
mly_map_command(mc);
mc->mc_packet->generic.command_id = mc->mc_slot;
+#ifdef MLY_DEBUG
+ mc->mc_timestamp = time_second;
+#endif
+
s = splcam();
/*
@@ -2173,6 +2183,7 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
struct mly_command_scsi_small *ss;
int bus, target;
int error;
+ int s;
bus = cam_sim_bus(sim);
target = csio->ccb_h.target_id;
@@ -2231,8 +2242,11 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
* Get a command, or push the ccb back to CAM and freeze the queue.
*/
if ((error = mly_alloc_command(sc, &mc))) {
+ s = splcam();
xpt_freeze_simq(sim, 1);
csio->ccb_h.status |= CAM_REQUEUE_REQ;
+ sc->mly_qfrzn_cnt++;
+ splx(s);
return(error);
}
@@ -2276,8 +2290,11 @@ mly_cam_action_io(struct cam_sim *sim, struct ccb_scsiio *csio)
/* give the command to the controller */
if ((error = mly_start(mc))) {
+ s = splcam();
xpt_freeze_simq(sim, 1);
csio->ccb_h.status |= CAM_REQUEUE_REQ;
+ sc->mly_qfrzn_cnt++;
+ splx(s);
return(error);
}
@@ -2309,6 +2326,7 @@ mly_cam_complete(struct mly_command *mc)
struct mly_btl *btl;
u_int8_t cmd;
int bus, target;
+ int s;
debug_called(2);
@@ -2360,6 +2378,14 @@ mly_cam_complete(struct mly_command *mc)
csio->ccb_h.status = CAM_REQ_CMP_ERR;
break;
}
+
+ s = splcam();
+ if (sc->mly_qfrzn_cnt) {
+ csio->ccb_h.status |= CAM_RELEASE_SIMQ;
+ sc->mly_qfrzn_cnt--;
+ }
+ splx(s);
+
xpt_done((union ccb *)csio);
mly_release_command(mc);
}
@@ -2945,3 +2971,23 @@ mly_user_health(struct mly_softc *sc, struct mly_user_health *uh)
sizeof(uh->HealthStatusBuffer));
return(error);
}
+
+static int
+mly_timeout(struct mly_softc *sc)
+{
+ struct mly_command *mc;
+ int deadline;
+
+ deadline = time_second - MLY_CMD_TIMEOUT;
+ TAILQ_FOREACH(mc, &sc->mly_busy, mc_link) {
+ if ((mc->mc_timestamp < deadline)) {
+ device_printf(sc->mly_dev,
+ "COMMAND %p TIMEOUT AFTER %d SECONDS\n", mc,
+ (int)(time_second - mc->mc_timestamp));
+ }
+ }
+
+ timeout((timeout_t *)mly_timeout, sc, MLY_CMD_TIMEOUT * hz);
+
+ return (0);
+}
diff --git a/sys/dev/mly/mlyvar.h b/sys/dev/mly/mlyvar.h
index 7dfdbcf7a14c..c994d429233a 100644
--- a/sys/dev/mly/mlyvar.h
+++ b/sys/dev/mly/mlyvar.h
@@ -148,6 +148,7 @@ struct mly_command {
void (* mc_complete)(struct mly_command *mc); /* completion handler */
void *mc_private; /* caller-private data */
+ int mc_timestamp;
};
/*
@@ -237,6 +238,7 @@ struct mly_softc {
/* command-completion task */
struct task mly_task_complete; /* deferred-completion task */
#endif
+ int mly_qfrzn_cnt; /* Track simq freezes */
};
/*