diff options
author | Alexander Yurchenko <grange@cvs.openbsd.org> | 2009-03-19 21:52:44 +0000 |
---|---|---|
committer | Alexander Yurchenko <grange@cvs.openbsd.org> | 2009-03-19 21:52:44 +0000 |
commit | e9465316ae9fc28f82535273101cb54464756139 (patch) | |
tree | 3a041bbd53b1c59d26b82b89026351c8056dc0fc /sys/dev | |
parent | 24d087fb560500611230c7a9de4d3627c02f5e66 (diff) |
For rebuilds use a special REBUILD command instead of a generic
SETSTATE, for some reason it works better on lpinto's machine.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/ips.c | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/sys/dev/pci/ips.c b/sys/dev/pci/ips.c index 50c43b81efe..0a25aa020e0 100644 --- a/sys/dev/pci/ips.c +++ b/sys/dev/pci/ips.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ips.c,v 1.77 2009/03/19 16:19:51 grange Exp $ */ +/* $OpenBSD: ips.c,v 1.78 2009/03/19 21:52:43 grange Exp $ */ /* * Copyright (c) 2006, 2007, 2009 Alexander Yurchenko <grange@openbsd.org> @@ -82,6 +82,7 @@ int ips_debug = IPS_D_ERR; #define IPS_CMD_FLUSH 0x0a #define IPS_CMD_REBUILDSTATUS 0x0c #define IPS_CMD_SETSTATE 0x10 +#define IPS_CMD_REBUILD 0x16 #define IPS_CMD_ERRORTABLE 0x17 #define IPS_CMD_GETDRIVEINFO 0x19 #define IPS_CMD_RESETCHAN 0x1a @@ -464,6 +465,7 @@ int ips_getconf(struct ips_softc *, int); int ips_getrblstat(struct ips_softc *, int); int ips_getpg5(struct ips_softc *, int); int ips_setstate(struct ips_softc *, int, int, int, int); +int ips_rebuild(struct ips_softc *, int, int, int, int, int); void ips_copperhead_exec(struct ips_softc *, struct ips_ccb *); void ips_copperhead_intren(struct ips_softc *); @@ -1245,8 +1247,8 @@ ips_ioctl_setstate(struct ips_softc *sc, struct bioc_setstate *bs) state = IPS_SS_HOTSPARE; break; case BIOC_SSREBUILD: - state = IPS_SS_REBUILD; - break; + return (ips_rebuild(sc, bs->bs_channel, bs->bs_target, + bs->bs_channel, bs->bs_target, 0)); default: return (EINVAL); } @@ -1862,6 +1864,32 @@ ips_setstate(struct ips_softc *sc, int chan, int target, int state, int flags) return (ips_cmd(sc, ccb)); } +int +ips_rebuild(struct ips_softc *sc, int chan, int target, int nchan, + int ntarget, int flags) +{ + struct ips_ccb *ccb; + struct ips_cmd *cmd; + int s; + + s = splbio(); + ccb = ips_ccb_get(sc); + splx(s); + if (ccb == NULL) + return (1); + + ccb->c_flags = SCSI_POLL | flags; + ccb->c_done = ips_done_mgmt; + + cmd = ccb->c_cmdbva; + cmd->code = IPS_CMD_REBUILD; + cmd->drive = chan; + cmd->sgcnt = target; + cmd->seccnt = htole16(ntarget << 8 | nchan); + + return (ips_cmd(sc, ccb)); +} + void ips_copperhead_exec(struct ips_softc *sc, struct ips_ccb *ccb) { |