summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/mlx/mlx.c289
-rw-r--r--sys/dev/mlx/mlx_disk.c10
-rw-r--r--sys/dev/mlx/mlxio.h48
-rw-r--r--sys/dev/mlx/mlxreg.h11
-rw-r--r--sys/dev/mlx/mlxvar.h12
5 files changed, 235 insertions, 135 deletions
diff --git a/sys/dev/mlx/mlx.c b/sys/dev/mlx/mlx.c
index 7ec3da4..4bfc8b5 100644
--- a/sys/dev/mlx/mlx.c
+++ b/sys/dev/mlx/mlx.c
@@ -111,6 +111,7 @@ static void mlx_pause_done(struct mlx_command *mc);
static void *mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize,
void (*complete)(struct mlx_command *mc));
static int mlx_flush(struct mlx_softc *sc);
+static int mlx_check(struct mlx_softc *sc, int drive);
static int mlx_rebuild(struct mlx_softc *sc, int channel, int target);
static int mlx_wait_command(struct mlx_command *mc);
static int mlx_poll_command(struct mlx_command *mc);
@@ -317,7 +318,6 @@ mlx_attach(struct mlx_softc *sc)
sc->mlx_sg_nseg = MLX_NSEG_NEW;
break;
default:
- device_printf(sc->mlx_dev, "attaching unsupported interface version %d\n", sc->mlx_iftype);
return(ENXIO); /* should never happen */
}
@@ -356,13 +356,13 @@ mlx_attach(struct mlx_softc *sc)
rid = 0;
sc->mlx_irq = bus_alloc_resource(sc->mlx_dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
if (sc->mlx_irq == NULL) {
- device_printf(sc->mlx_dev, "couldn't allocate interrupt\n");
+ device_printf(sc->mlx_dev, "can't allocate interrupt\n");
mlx_free(sc);
return(ENXIO);
}
error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO, mlx_intr, sc, &sc->mlx_intr);
if (error) {
- device_printf(sc->mlx_dev, "couldn't set up interrupt\n");
+ device_printf(sc->mlx_dev, "can't set up interrupt\n");
mlx_free(sc);
return(ENXIO);
}
@@ -390,7 +390,7 @@ mlx_attach(struct mlx_softc *sc)
sc->mlx_maxiop = 8;
error = mlx_sglist_map(sc);
if (error != 0) {
- device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n");
+ device_printf(sc->mlx_dev, "can't make initial s/g list mapping\n");
return(error);
}
@@ -403,7 +403,7 @@ mlx_attach(struct mlx_softc *sc)
/*
* We don't (yet) know where the event log is up to.
*/
- sc->mlx_lastevent = -1;
+ sc->mlx_currevent = -1;
/*
* Do quirk/feature related things.
@@ -446,7 +446,6 @@ mlx_attach(struct mlx_softc *sc)
}
break;
default:
- device_printf(sc->mlx_dev, "interface version corrupted to %d\n", sc->mlx_iftype);
return(ENXIO); /* should never happen */
}
@@ -457,15 +456,15 @@ mlx_attach(struct mlx_softc *sc)
sc->mlx_maxiop = sc->mlx_enq2->me_max_commands;
error = mlx_sglist_map(sc);
if (error != 0) {
- device_printf(sc->mlx_dev, "couldn't make initial s/g list mapping\n");
+ device_printf(sc->mlx_dev, "can't make permanent s/g list mapping\n");
return(error);
}
/*
- * No rebuild or check is in progress.
+ * No user-requested background operation is in progress.
*/
- sc->mlx_rebuild = -1;
- sc->mlx_check = -1;
+ sc->mlx_background = 0;
+ sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
/*
* Create the control device.
@@ -733,13 +732,15 @@ mlx_close(dev_t dev, int flags, int fmt, struct proc *p)
int
mlx_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
{
- int unit = minor(dev);
- struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit);
- int *arg = (int *)addr;
- struct mlx_pause *mp;
- struct mlx_sysdrive *dr;
- struct mlxd_softc *mlxd;
- int i, error;
+ int unit = minor(dev);
+ struct mlx_softc *sc = devclass_get_softc(mlx_devclass, unit);
+ struct mlx_rebuild_request *rb = (struct mlx_rebuild_request *)addr;
+ struct mlx_rebuild_status *rs = (struct mlx_rebuild_status *)addr;
+ int *arg = (int *)addr;
+ struct mlx_pause *mp;
+ struct mlx_sysdrive *dr;
+ struct mlxd_softc *mlxd;
+ int i, error;
switch(cmd) {
/*
@@ -754,7 +755,7 @@ mlx_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
if (sc->mlx_sysdrive[i].ms_disk != 0) {
/* looking for the next one we come across? */
if (*arg == -1) {
- *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk);
+ *arg = device_get_unit(sc->mlx_sysdrive[0].ms_disk);
return(0);
}
/* we want the one after this one */
@@ -849,6 +850,63 @@ mlx_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
case MLX_COMMAND:
return(mlx_user_command(sc, (struct mlx_usercommand *)addr));
+ /*
+ * Start a rebuild on a given SCSI disk
+ */
+ case MLX_REBUILDASYNC:
+ if (sc->mlx_background != 0) {
+ rb->rr_status = 0x0106;
+ return(EBUSY);
+ }
+ rb->rr_status = mlx_rebuild(sc, rb->rr_channel, rb->rr_target);
+ switch (rb->rr_status) {
+ case 0:
+ error = 0;
+ break;
+ case 0x10000:
+ error = ENOMEM; /* couldn't set up the command */
+ break;
+ case 0x0002:
+ error = EBUSY;
+ break;
+ case 0x0104:
+ error = EIO;
+ break;
+ case 0x0105:
+ error = ERANGE;
+ break;
+ case 0x0106:
+ error = EBUSY;
+ break;
+ default:
+ error = EINVAL;
+ break;
+ }
+ if (error == 0)
+ sc->mlx_background = MLX_BACKGROUND_REBUILD;
+ return(error);
+
+ /*
+ * Get the status of the current rebuild or consistency check.
+ */
+ case MLX_REBUILDSTAT:
+ *rs = sc->mlx_rebuildstat;
+ return(0);
+
+ /*
+ * Return the per-controller system drive number matching the
+ * disk device number in (arg), if it happens to belong to us.
+ */
+ case MLX_GET_SYSDRIVE:
+ error = ENOENT;
+ mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg);
+ if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) &&
+ (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) {
+ error = 0;
+ *arg = mlxd->mlxd_drive - sc->mlx_sysdrive;
+ }
+ return(error);
+
default:
return(ENOTTY);
}
@@ -861,10 +919,8 @@ int
mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd,
caddr_t addr, int32_t flag, struct proc *p)
{
- struct mlxd_rebuild *mr = (struct mlxd_rebuild *)addr;
- struct mlxd_rebuild_status *mp = (struct mlxd_rebuild_status *)addr;
int *arg = (int *)addr;
- int error;
+ int error, result;
switch(cmd) {
/*
@@ -875,64 +931,39 @@ mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd,
return(0);
/*
- * Start a background rebuild on this drive.
+ * Start a background consistency check on this drive.
*/
- case MLXD_REBUILDASYNC:
- /* XXX lock? */
- if (sc->mlx_rebuild >= 0)
+ case MLXD_CHECKASYNC: /* start a background consistency check */
+ if (sc->mlx_background != 0) {
+ *arg = 0x0106;
return(EBUSY);
- sc->mlx_rebuild = drive - &sc->mlx_sysdrive[0];
-
- switch (mlx_rebuild(sc, mr->rb_channel, mr->rb_target)) {
+ }
+ result = mlx_check(sc, drive - &sc->mlx_sysdrive[0]);
+ switch (result) {
case 0:
- drive->ms_state = MLX_SYSD_REBUILD;
error = 0;
break;
case 0x10000:
error = ENOMEM; /* couldn't set up the command */
break;
- case 0x0002:
- case 0x0106:
- error = EBUSY;
- break;
- case 0x0004:
+ case 0x0002:
error = EIO;
break;
case 0x0105:
error = ERANGE;
break;
+ case 0x0106:
+ error = EBUSY;
+ break;
default:
error = EINVAL;
break;
}
- if (error != 0)
- sc->mlx_rebuild = -1;
+ if (error == 0)
+ sc->mlx_background = MLX_BACKGROUND_CHECK;
+ *arg = result;
return(error);
- /*
- * Start a background consistency check on this drive.
- */
- case MLXD_CHECKASYNC: /* start a background consistency check */
- /* XXX implement */
- break;
-
- /*
- * Get the status of the current rebuild or consistency check.
- */
- case MLXD_REBUILDSTAT:
-
- if (sc->mlx_rebuild >= 0) { /* may be a second or so out of date */
- mp->rs_drive = sc->mlx_rebuild;
- mp->rs_size = sc->mlx_sysdrive[sc->mlx_rebuild].ms_size;
- mp->rs_remaining = sc->mlx_rebuildstat;
- return(0);
- } else if (sc->mlx_check >= 0) {
- /* XXX implement */
- } else {
- /* XXX should return status of last completed operation? */
- return(EINVAL);
- }
-
}
return(ENOIOCTL);
}
@@ -1004,13 +1035,12 @@ mlx_periodic(void *data)
mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES,
mlx_periodic_enquiry);
- /*
- * Get drive rebuild/check status
- */
- if (sc->mlx_rebuild >= 0)
- mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
}
+ /* get drive rebuild/check status */
+ /* XXX should check sc->mlx_background if this is only valid while in progress */
+ mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
+
/* deal with possibly-missed interrupts and timed-out commands */
mlx_done(sc);
@@ -1082,7 +1112,7 @@ mlx_periodic_enquiry(struct mlx_command *mc)
{
struct mlx_enquiry *me = (struct mlx_enquiry *)mc->mc_data;
- if (sc->mlx_lastevent == -1) {
+ if (sc->mlx_currevent == -1) {
/* initialise our view of the event log */
sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num;
} else if (me->me_event_log_seq_num != sc->mlx_lastevent) {
@@ -1105,24 +1135,21 @@ mlx_periodic_enquiry(struct mlx_command *mc)
(i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
i++) {
- /* if disk is being rebuilt, we should not check it */
- if (dr->ms_state == MLX_SYSD_REBUILD) {
- /* has state been changed by controller? */
- if (dr->ms_state != mes[i].sd_state) {
- switch(mes[i].sd_state) {
- case MLX_SYSD_OFFLINE:
- device_printf(dr->ms_disk, "drive offline\n");
- break;
- case MLX_SYSD_ONLINE:
- device_printf(dr->ms_disk, "drive online\n");
- break;
- case MLX_SYSD_CRITICAL:
- device_printf(dr->ms_disk, "drive critical\n");
- break;
- }
- /* save new state */
- dr->ms_state = mes[i].sd_state;
+ /* has state been changed by controller? */
+ if (dr->ms_state != mes[i].sd_state) {
+ switch(mes[i].sd_state) {
+ case MLX_SYSD_OFFLINE:
+ device_printf(dr->ms_disk, "drive offline\n");
+ break;
+ case MLX_SYSD_ONLINE:
+ device_printf(dr->ms_disk, "drive online\n");
+ break;
+ case MLX_SYSD_CRITICAL:
+ device_printf(dr->ms_disk, "drive critical\n");
+ break;
}
+ /* save new state */
+ dr->ms_state = mes[i].sd_state;
}
}
break;
@@ -1258,6 +1285,8 @@ mlx_periodic_eventlog_respond(struct mlx_command *mc)
}
} else {
device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc));
+ panic("log operation failed: lastevent = %d, currevent = %d",
+ sc->mlx_lastevent, sc->mlx_currevent);
}
/* dispose of command and data */
@@ -1270,29 +1299,42 @@ mlx_periodic_eventlog_respond(struct mlx_command *mc)
}
/********************************************************************************
- * Handle the completion of a rebuild operation.
+ * Handle check/rebuild operations in progress.
*/
static void
mlx_periodic_rebuild(struct mlx_command *mc)
{
struct mlx_softc *sc = mc->mc_sc;
- struct mlx_rebuild_stat *mr = (struct mlx_rebuild_stat *)mc->mc_private;
+ struct mlx_rebuild_status *mr = (struct mlx_rebuild_status *)mc->mc_data;
switch(mc->mc_status) {
- case 0: /* all OK, rebuild still running */
- sc->mlx_rebuildstat = mr->rb_remaining;
+ case 0: /* operation running, update stats */
+ sc->mlx_rebuildstat = *mr;
+
+ /* spontaneous rebuild/check? */
+ if (sc->mlx_background == 0) {
+ sc->mlx_background = MLX_BACKGROUND_SPONTANEOUS;
+ device_printf(sc->mlx_dev, "background check/rebuild operation started\n");
+ }
break;
- case 0x0105: /* rebuild/check finished */
- if (sc->mlx_rebuild >= 0) {
- device_printf(sc->mlx_sysdrive[sc->mlx_rebuild].ms_disk, "rebuild completed\n");
- sc->mlx_rebuild = -1;
- } else if (sc->mlx_check >= 0) {
- device_printf(sc->mlx_sysdrive[sc->mlx_check].ms_disk, "consistency check completed\n");
- sc->mlx_check = -1;
- } else {
- device_printf(sc->mlx_dev, "consistency check completed\n");
+ case 0x0105: /* nothing running, finalise stats and report */
+ switch(sc->mlx_background) {
+ case MLX_BACKGROUND_CHECK:
+ device_printf(sc->mlx_dev, "consistency check completed\n"); /* XXX print drive? */
+ break;
+ case MLX_BACKGROUND_REBUILD:
+ device_printf(sc->mlx_dev, "drive rebuild completed\n"); /* XXX print channel/target? */
+ break;
+ case MLX_BACKGROUND_SPONTANEOUS:
+ default:
+ /* if we have previously been non-idle, report the transition */
+ if (sc->mlx_rebuildstat.rs_code != MLX_REBUILDSTAT_IDLE) {
+ device_printf(sc->mlx_dev, "background check/rebuild operation completed\n");
+ }
}
+ sc->mlx_background = 0;
+ sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
break;
}
free(mc->mc_data, M_DEVBUF);
@@ -1501,7 +1543,50 @@ mlx_flush(struct mlx_softc *sc)
}
/********************************************************************************
- * Start a background rebuild on the nominated controller/channel/target.
+ * Start a background consistency check on (drive).
+ *
+ * May be called with interrupts enabled or disabled; will return as soon as the
+ * operation has started or been refused.
+ */
+static int
+mlx_check(struct mlx_softc *sc, int drive)
+{
+ struct mlx_command *mc;
+ int error;
+
+ debug_called(1);
+
+ /* get ourselves a command buffer */
+ error = 0x10000;
+ if ((mc = mlx_alloccmd(sc)) == NULL)
+ goto out;
+ /* get a command slot */
+ if (mlx_getslot(mc))
+ goto out;
+
+ /* build a checkasync command, set the "fix it" flag */
+ mlx_make_type2(mc, MLX_CMD_CHECKASYNC, 0, 0, 0, 0, 0, drive | 0x80, 0, 0);
+
+ /* start the command and wait for it to be returned */
+ if (mlx_wait_command(mc))
+ goto out;
+
+ /* command completed OK? */
+ if (mc->mc_status != 0) {
+ device_printf(sc->mlx_dev, "CHECK ASYNC failed - %s\n", mlx_diagnose_command(mc));
+ } else {
+ device_printf(sc->mlx_sysdrive[drive].ms_disk, "consistency check started");
+ }
+ error = mc->mc_status;
+
+ out:
+ if (mc != NULL)
+ mlx_releasecmd(mc);
+ return(error);
+}
+
+/********************************************************************************
+ * Start a background rebuild of the physical drive at (channel),(target).
*
* May be called with interrupts enabled or disabled; will return as soon as the
* operation has started or been refused.
@@ -1522,18 +1607,18 @@ mlx_rebuild(struct mlx_softc *sc, int channel, int target)
if (mlx_getslot(mc))
goto out;
- /* build a rebuild command */
+ /* build a checkasync command, set the "fix it" flag */
mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0, 0, 0);
- /* run the command in either polled or wait mode */
- if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc))
+ /* start the command and wait for it to be returned */
+ if (mlx_wait_command(mc))
goto out;
/* command completed OK? */
if (mc->mc_status != 0) {
device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc));
} else {
- device_printf(sc->mlx_sysdrive[sc->mlx_rebuild].ms_disk, "rebuild started");
+ device_printf(sc->mlx_dev, "drive rebuild started for %d:%d\n", channel, target);
}
error = mc->mc_status;
@@ -1607,7 +1692,7 @@ mlx_poll_command(struct mlx_command *mc)
splx(s);
return(0);
}
- device_printf(sc->mlx_dev, "I/O error 0x%x\n", mc->mc_status);
+ device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
return(EIO);
}
diff --git a/sys/dev/mlx/mlx_disk.c b/sys/dev/mlx/mlx_disk.c
index 22328ba..5420326 100644
--- a/sys/dev/mlx/mlx_disk.c
+++ b/sys/dev/mlx/mlx_disk.c
@@ -80,9 +80,8 @@ static struct cdevsw mlxd_cdevsw = {
/* bmaj */ MLXD_BDEV_MAJOR
};
-static devclass_t mlxd_devclass;
+devclass_t mlxd_devclass;
static struct cdevsw mlxddisk_cdevsw;
-static int disks_registered = 0;
static device_method_t mlxd_methods[] = {
DEVMETHOD(device_probe, mlxd_probe),
@@ -272,7 +271,7 @@ mlxd_attach(device_t dev)
dsk = disk_create(sc->mlxd_unit, &sc->mlxd_disk, 0, &mlxd_cdevsw, &mlxddisk_cdevsw);
dsk->si_drv1 = sc;
- disks_registered++;
+ sc->mlxd_dev_t = dsk;
/* set maximum I/O size */
dsk->si_iosize_max = sc->mlxd_controller->mlx_enq2->me_maxblk * MLX_BLKSIZE;
@@ -288,10 +287,7 @@ mlxd_detach(device_t dev)
debug_called(1);
devstat_remove_entry(&sc->mlxd_stats);
-
- /* hack to handle lack of destroy_disk() */
- if (--disks_registered == 0)
- cdevsw_remove(&mlxddisk_cdevsw);
+ disk_destroy(sc->mlxd_dev_t);
return(0);
}
diff --git a/sys/dev/mlx/mlxio.h b/sys/dev/mlx/mlxio.h
index 984b223..f091bef 100644
--- a/sys/dev/mlx/mlxio.h
+++ b/sys/dev/mlx/mlxio.h
@@ -31,32 +31,15 @@
/*
* System Disk ioctls
*/
-struct mlxd_rebuild
-{
- int rb_channel;
- int rb_target;
-};
-struct mlxd_rebuild_status
-{
- int rs_drive;
- int rs_size;
- int rs_remaining;
-};
-
-#define MLXD_STATUS _IOR ('M', 100, int)
-#define MLXD_REBUILDASYNC _IOW ('M', 101, struct mlxd_rebuild)
-#define MLXD_CHECKASYNC _IOW ('M', 102, int)
-#define MLXD_REBUILDSTAT _IOR ('M', 103, struct mlxd_rebuild_status)
-
-/*
- * System Disk status values
- */
+/* system disk status values */
#define MLX_SYSD_ONLINE 0x03
#define MLX_SYSD_CRITICAL 0x04
-#define MLX_SYSD_REBUILD 0xfe
#define MLX_SYSD_OFFLINE 0xff
+#define MLXD_STATUS _IOR ('M', 100, int)
+#define MLXD_CHECKASYNC _IOR ('M', 101, int) /* command result returned in argument */
+
/*
* Controller ioctls
*/
@@ -85,9 +68,30 @@ struct mlx_usercommand
};
+struct mlx_rebuild_request
+{
+ int rr_channel;
+ int rr_target;
+ int rr_status;
+};
+
+struct mlx_rebuild_status
+{
+ u_int16_t rs_code;
+#define MLX_REBUILDSTAT_REBUILDCHECK 0x0000
+#define MLX_REBUILDSTAT_ADDCAPACITY 0x0400
+#define MLX_REBUILDSTAT_ADDCAPACITYINIT 0x0500
+#define MLX_REBUILDSTAT_IDLE 0xffff
+ u_int16_t rs_drive;
+ int rs_size;
+ int rs_remaining;
+};
+
#define MLX_NEXT_CHILD _IOWR('M', 0, int)
#define MLX_RESCAN_DRIVES _IO ('M', 1)
#define MLX_DETACH_DRIVE _IOW ('M', 2, int)
#define MLX_PAUSE_CHANNEL _IOW ('M', 3, struct mlx_pause)
#define MLX_COMMAND _IOWR('M', 4, struct mlx_usercommand)
-
+#define MLX_REBUILDASYNC _IOWR('M', 5, struct mlx_rebuild_request)
+#define MLX_REBUILDSTAT _IOR ('M', 6, struct mlx_rebuild_status)
+#define MLX_GET_SYSDRIVE _IOWR('M', 7, int)
diff --git a/sys/dev/mlx/mlxreg.h b/sys/dev/mlx/mlxreg.h
index c5382bf..382a2fd 100644
--- a/sys/dev/mlx/mlxreg.h
+++ b/sys/dev/mlx/mlxreg.h
@@ -48,6 +48,7 @@
#define MLX_CMD_STARTCHANNEL 0x12
#define MLX_CMD_READ_CONFIG 0x4e
#define MLX_CMD_DIRECT_CDB 0x04
+#define MLX_CMD_DEVICE_STATE 0x50
#ifdef _KERNEL
@@ -483,6 +484,16 @@ struct mlx_dcdb
u_int8_t res1;
} __attribute__ ((packed));
+struct mlx_bbtable_entry
+{
+ u_int32_t bbt_block_number;
+ u_int8_t bbt_extent;
+ u_int8_t res1;
+ u_int8_t bbt_entry_type;
+ u_int8_t bbt_system_drive:5;
+ u_int8_t res2:3;
+} __attribute__ ((packed));
+
#ifdef _KERNEL
/*
* Inlines to build various command structures
diff --git a/sys/dev/mlx/mlxvar.h b/sys/dev/mlx/mlxvar.h
index 7847ca2..cd0cd90 100644
--- a/sys/dev/mlx/mlxvar.h
+++ b/sys/dev/mlx/mlxvar.h
@@ -148,11 +148,13 @@ struct mlx_softc
#define MLX_STATE_SUSPEND (1<<3) /* controller is suspended */
struct callout_handle mlx_timeout; /* periodic status monitor */
time_t mlx_lastpoll; /* last time_second we polled for status */
- int mlx_lastevent; /* sequence number of the last event we recorded */
+ u_int16_t mlx_lastevent; /* sequence number of the last event we recorded */
int mlx_currevent; /* sequence number last time we looked */
- int mlx_rebuild; /* if >= 0, drive is being rebuilt */
- u_int32_t mlx_rebuildstat;/* blocks left to rebuild if active */
- int mlx_check; /* if >= 0, drive is being checked */
+ int mlx_background; /* if != 0 rebuild or check is in progress */
+#define MLX_BACKGROUND_CHECK 1 /* we started a check */
+#define MLX_BACKGROUND_REBUILD 2 /* we started a rebuild */
+#define MLX_BACKGROUND_SPONTANEOUS 3 /* it just happened somehow */
+ struct mlx_rebuild_status mlx_rebuildstat; /* last rebuild status */
struct mlx_pause mlx_pause; /* pending pause operation details */
int mlx_locks; /* reentrancy avoidance */
@@ -213,6 +215,7 @@ extern d_close_t mlx_close;
extern d_ioctl_t mlx_ioctl;
extern devclass_t mlx_devclass;
+extern devclass_t mlxd_devclass;
/*
* Mylex System Disk driver
@@ -220,6 +223,7 @@ extern devclass_t mlx_devclass;
struct mlxd_softc
{
device_t mlxd_dev;
+ dev_t mlxd_dev_t;
struct mlx_softc *mlxd_controller;
struct mlx_sysdrive *mlxd_drive;
struct disk mlxd_disk;
OpenPOWER on IntegriCloud