summaryrefslogtreecommitdiffstats
path: root/sys/dev/mlx
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2000-04-11 02:52:46 +0000
committermsmith <msmith@FreeBSD.org>2000-04-11 02:52:46 +0000
commit612fc8c5158ae5c2f3017445553eefe095fbbfc1 (patch)
treef329a647fd19231f32b45be5d1325231c626e853 /sys/dev/mlx
parent1f9a3b6ffeeb06ce3881cbb6016adb4f15ef9d81 (diff)
downloadFreeBSD-src-612fc8c5158ae5c2f3017445553eefe095fbbfc1.zip
FreeBSD-src-612fc8c5158ae5c2f3017445553eefe095fbbfc1.tar.gz
Add features required for basic userland management utility:
- implement user-initiated background drive rebuild - implement user-initiated background consistency check - log controller-initiated background rebuild/check operations Try to fix the elusive "invalid log operation" bug, and panic if we do hit this one in the hopes of getting better information. Tidy up diagnostic messages. Try to use disk_create/disk_destroy correctly. This isn't working properly yet, but it's not clear whose fault that is.
Diffstat (limited to 'sys/dev/mlx')
-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