diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2005-04-06 02:36:35 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2005-04-06 02:36:35 +0000 |
commit | 71b6fc532007eac550e5c726680f57f395a09f02 (patch) | |
tree | 0bbf8f27e9a79fdb8dec12c5cbfe9ad7f2477db6 | |
parent | 5eb160d5aba50c9e5bf91816cff5e5717e3d5baa (diff) |
Add ses blink crud. Not fully functional yet.
-rw-r--r-- | sbin/bioctl/bioctl.8 | 4 | ||||
-rw-r--r-- | sbin/bioctl/bioctl.c | 179 | ||||
-rw-r--r-- | sbin/bioctl/bioctl.h | 6 |
3 files changed, 184 insertions, 5 deletions
diff --git a/sbin/bioctl/bioctl.8 b/sbin/bioctl/bioctl.8 index d4b73115136..f87c3a56a96 100644 --- a/sbin/bioctl/bioctl.8 +++ b/sbin/bioctl/bioctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bioctl.8,v 1.6 2005/04/05 06:32:16 jmc Exp $ +.\" $OpenBSD: bioctl.8,v 1.7 2005/04/06 02:36:34 marco Exp $ .\" .\" Copyright (c) 2004, 2005 Marco Peereboom .\" @@ -51,7 +51,7 @@ Supported functions are: silence/quiet, enable, disable, get, and test. Or use the first letter of the function. .It Fl b Ar function Blink or unblink hard drive LED, if supported by the enclosure. -Supported functions are: blink and unblink. +Supported functions are: blink, alarm (fault LED) and unblink. Or use the first letter of the function. .It Fl D Enable debug output. diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c index f5d22590b5e..9916941798f 100644 --- a/sbin/bioctl/bioctl.c +++ b/sbin/bioctl/bioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bioctl.c,v 1.6 2005/04/05 20:25:50 marco Exp $ */ +/* $OpenBSD: bioctl.c,v 1.7 2005/04/06 02:36:34 marco Exp $ */ /* * Copyright (c) 2004, 2005 Marco Peereboom * All rights reserved. @@ -443,6 +443,66 @@ bio_alarm(char *arg) } void +bio_blink_userland(u_int8_t opc, u_int8_t c, u_int8_t t) +{ + struct dev *delm; + struct scsi_enc_ctrl_diag_page *cdp; + + u_int8_t rc[SESSIZE]; + + /* FIXME if the raid controllers are clustered we might have more + * than one proc device. */ + + bio_pt_enum(); + + SLIST_FOREACH(delm, &devices, next) { + if (delm->channel != c) + continue; + + if (delm->type != T_PROCESSOR) + continue; + + if (debug) + printf("proc at channel: %d target: %2d\n", + delm->channel, delm->target); + + /* get ses page so that we can modify bits for blink */ + if (!get_ses_page(delm->channel, delm->target, + &rc[0], sizeof(rc))) { + return; + } + + cdp = (struct scsi_enc_ctrl_diag_page *)rc; + + cdp->elmts[0].common_ctrl = 0x80; + switch (opc) { + case BIOCSBLINK_ALERT: + cdp->elmts[0].byte4 = SDECD_RQST_FAULT; + break; + + case BIOCSBLINK_BLINK: + cdp->elmts[0].byte3 = SDECD_RQST_IDENT; + break; + + case BIOCSBLINK_UNBLINK: + cdp->elmts[0].byte3 = 0x00; + cdp->elmts[0].byte4 = 0x00; + break; + + default: + return; + } + + if (!set_ses_page(delm->channel, delm->target, + &rc[0], sizeof(rc))) { + return; + } + + return; /* done */ + } +} + +void bio_blink(char * arg, u_int8_t c, u_int8_t t) { int rv; @@ -454,6 +514,12 @@ bio_blink(char * arg, u_int8_t c, u_int8_t t) bb.cookie = bl.cookie; switch (arg[0]) { + case 'a': /* blink amber or alert led */ + if (debug) + printf("blink alert\n"); + bb.opcode = BIOCSBLINK_ALERT; + break; + case 'b': /* blink hdd */ if (debug) printf("blink\n"); @@ -477,6 +543,7 @@ bio_blink(char * arg, u_int8_t c, u_int8_t t) /* operation is not supported in kernel, do it here */ if (debug) printf("doing blink in userland\n"); + bio_blink_userland(bb.opcode, c, t); } else warnx("bioc_ioctl() call failed"); @@ -715,7 +782,7 @@ bio_pt_enum(void) struct dev *delm; d = 0; - for (c = 0; c < 2 /* FIXME */; c++) { + for (c = 0; c < 4 /* FIXME */; c++) { for (t = 0; t < 16 /* FIXME */; t++) { if (bio_pt_inquire(c, t, F_SILENCE, &inq[0])) { if (inq[0] & SID_QUAL) @@ -824,3 +891,111 @@ void print_cap(u_int64_t cap) printf(" %llu B", cap); } + +#if 0 + /* in case we want to do SAFTE this is the format */ + /* SAF-TE */ + memset(&bpt, 0, sizeof(bpt)); + bpt.cookie = bl.cookie; + bpt.channel = delm->channel; + bpt.target = delm->target; + bpt.cdblen = 10; + bpt.cdb[0] = 0x3c; /* READ BUFFER */ + bpt.cdb[1] = 0x01; /* SAF-TE command */ + bpt.cdb[8] = sizeof(rc); /* LSB size, FIXME */ + bpt.data = &rc[0]; /* set up return data pointer */ + bpt.datalen = sizeof(rc); + bpt.direction = BIOC_DIRIN; + bpt.senselen = 32; /* silly since the kernel overrides it */ +#endif + +int +get_ses_page(u_int8_t c, u_int8_t t, u_int8_t *buf, u_int8_t buflen) +{ + bioc_scsicmd bpt; + int rv; + + memset(&bpt, 0, sizeof(bpt)); + bpt.cookie = bl.cookie; + bpt.channel = c; + bpt.target = t; + bpt.cdblen = 6; + bpt.cdb[0] = RECEIVE_DIAGNOSTIC; + /* FIXME add this cdb struct + #defines to scsi_all.h */ + bpt.cdb[1] = 0x01; /* set PCV bit for SES commands */ + bpt.cdb[2] = 0x02; /* SES page nr */ + bpt.cdb[4] = buflen; + bpt.data = buf; /* set up return data pointer */ + bpt.datalen = buflen; + bpt.direction = BIOC_DIRIN; + bpt.senselen = 32; /* silly since the kernel overrides it */ + + rv = ioctl(devh, BIOCSCSICMD, &bpt); + if (rv == -1) { + warnx("RECEIVE_DIAGNOSTIC failed %x", bpt.status); + return (0); + } + else if (bpt.status) { + if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) + print_sense(&bpt.sensebuf[0], bpt.senselen); + else + printf("channel: %d target: %2d RECEIVE_DIAGNOSTIC " + "failed without sense data\n", c, t); + + return (0); + } + + if (debug) { + /* abuse print sense a little */ + print_sense(buf, bpt.datalen); + } + + return (1); +} + +int +set_ses_page(u_int8_t c, u_int8_t t, u_int8_t *buf, u_int8_t buflen) +{ + bioc_scsicmd bpt; + int rv; + + memset(&bpt, 0, sizeof(bpt)); + bpt.cookie = bl.cookie; + bpt.channel = c; + bpt.target = t; + bpt.cdblen = 6; + bpt.cdb[0] = SEND_DIAGNOSTIC; + bpt.cdb[1] = SSD_PF; + bpt.cdb[4] = buflen; + bpt.data = buf; /* set up return data pointer */ + /* + buf[12] = 0x80; + buf[14] = 0x00; + buf[15] = 0x20; + */ + bpt.datalen = buflen; + bpt.direction = BIOC_DIROUT; + bpt.senselen = 32; /* silly since the kernel overrides it */ + + rv = ioctl(devh, BIOCSCSICMD, &bpt); + if (rv == -1) { + warnx("SEND_DIAGNOSTIC failed %x", bpt.status); + return (0); + } + else if (bpt.status) { + if (bpt.sensebuf[0] == 0x70 || bpt.sensebuf[0] == 0x71) + print_sense(&bpt.sensebuf[0], bpt.senselen); + else + printf("channel: %d target: %2d SEND_DIAGNOSTIC " + "failed without sense data\n", c, t); + + return (0); + } + + if (debug) { + /* abuse print sense a little */ + print_sense(buf, bpt.datalen); + } + + return (1); +} diff --git a/sbin/bioctl/bioctl.h b/sbin/bioctl/bioctl.h index 8effcc93d48..aa4044e499f 100644 --- a/sbin/bioctl/bioctl.h +++ b/sbin/bioctl/bioctl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bioctl.h,v 1.4 2005/04/05 20:25:50 marco Exp $ */ +/* $OpenBSD: bioctl.h,v 1.5 2005/04/06 02:36:34 marco Exp $ */ /* * Copyright (c) 2004, 2005 Marco Peereboom * All rights reserved. @@ -30,6 +30,7 @@ /* misc defines */ #define INQSIZE (36) +#define SESSIZE (255) #define S_TERA (1099511627776llu) #define S_GIGA (1073741824llu) @@ -69,9 +70,12 @@ void parse_devlist(char *); void print_sense(u_int8_t *, u_int8_t); void print_inquiry(u_int8_t, u_int8_t*, u_int8_t); void print_cap(u_int64_t); +int get_ses_page(u_int8_t, u_int8_t, u_int8_t*, u_int8_t); +int set_ses_page(u_int8_t, u_int8_t, u_int8_t*, u_int8_t); int bio_get_capabilities(bioc_capabilities *); void bio_alarm(char *); +void bio_blink_userland(u_int8_t, u_int8_t, u_int8_t); void bio_blink(char *, u_int8_t, u_int8_t); void bio_ping(void); void bio_startstop(char *, u_int8_t, u_int8_t); |