summaryrefslogtreecommitdiffstats
path: root/sys/dev/softraid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/softraid.c')
-rw-r--r--sys/dev/softraid.c59
1 files changed, 58 insertions, 1 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index ae42039372c..58f6ca8d485 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.98 2008/02/03 00:25:21 marco Exp $ */
+/* $OpenBSD: softraid.c,v 1.99 2008/02/05 16:15:35 marco Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
*
@@ -2171,6 +2171,63 @@ sr_shutdown(void *arg)
sr_shutdown_discipline(sd);
}
+int
+sr_validate_io(struct sr_workunit *wu, daddr64_t *blk, char *func)
+{
+ struct sr_discipline *sd = wu->swu_dis;
+ struct scsi_xfer *xs = wu->swu_xs;
+ int rv = 1;
+
+ DNPRINTF(SR_D_DIS, "%s: %s 0x%02x\n", DEVNAME(sd->sd_sc), func,
+ xs->cmd->opcode);
+
+ if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
+ DNPRINTF(SR_D_DIS, "%s: %s device offline\n",
+ DEVNAME(sd->sd_sc));
+ goto bad;
+ }
+
+ if (xs->datalen == 0) {
+ printf("%s: %s: illegal block count\n",
+ DEVNAME(sd->sd_sc), func, sd->sd_vol.sv_meta.svm_devname);
+ goto bad;
+ }
+
+ if (xs->cmdlen == 10)
+ *blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
+ else if (xs->cmdlen == 16)
+ *blk = _8btol(((struct scsi_rw_16 *)xs->cmd)->addr);
+ else if (xs->cmdlen == 6)
+ *blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
+ else {
+ printf("%s: %s: illegal cmdlen\n", DEVNAME(sd->sd_sc), func,
+ sd->sd_vol.sv_meta.svm_devname);
+ goto bad;
+ }
+
+ wu->swu_blk_start = *blk;
+ wu->swu_blk_end = *blk + (xs->datalen >> DEV_BSHIFT) - 1;
+
+ if (wu->swu_blk_end > sd->sd_vol.sv_meta.svm_size) {
+ DNPRINTF(SR_D_DIS, "%s: %s out of bounds start: %lld "
+ "end: %lld length: %d\n",
+ DEVNAME(sd->sd_sc), func, wu->swu_blk_start,
+ wu->swu_blk_end, xs->datalen);
+
+ sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT |
+ SSD_ERRCODE_VALID;
+ sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
+ sd->sd_scsi_sense.add_sense_code = 0x21;
+ sd->sd_scsi_sense.add_sense_code_qual = 0x00;
+ sd->sd_scsi_sense.extra_len = 4;
+ goto bad;
+ }
+
+ rv = 0;
+bad:
+ return (rv);
+}
+
#ifndef SMALL_KERNEL
int
sr_create_sensors(struct sr_discipline *sd)