From d865b7d245645b4282007a0c178ef00ccb05fe01 Mon Sep 17 00:00:00 2001 From: uebayasi Date: Fri, 29 May 2015 00:33:37 +0000 Subject: [PATCH] Initial addition of ``Patrol Read'' support in bio(4), biocto(8), and mfi(4). Based on FreeBSD, but done without mfiutil(8). OK deraadt@ --- sbin/bioctl/bioctl.8 | 28 ++++++- sbin/bioctl/bioctl.c | 167 +++++++++++++++++++++++++++++++++++++++-- sys/dev/bio.c | 3 +- sys/dev/biovar.h | 34 ++++++++- sys/dev/i2c/i2c_scan.c | 4 +- sys/dev/ic/mfi.c | 153 ++++++++++++++++++++++++++++++++++++- sys/dev/ic/mfireg.h | 39 +++++++++- sys/dev/pci/if_vic.c | 12 ++- sys/dev/pci/if_vmx.c | 27 ++++++- 9 files changed, 452 insertions(+), 15 deletions(-) diff --git a/sbin/bioctl/bioctl.8 b/sbin/bioctl/bioctl.8 index 2eb5bcba00c..2a4e1b7348e 100644 --- a/sbin/bioctl/bioctl.8 +++ b/sbin/bioctl/bioctl.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: bioctl.8,v 1.95 2015/04/11 16:37:34 jsing Exp $ +.\" $OpenBSD: bioctl.8,v 1.96 2015/05/29 00:33:37 uebayasi Exp $ .\" .\" Copyright (c) 2004, 2005 Marco Peereboom .\" @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: April 11 2015 $ +.Dd $Mdocdate: May 29 2015 $ .Dt BIOCTL 8 .Os .Sh NAME @@ -37,6 +37,7 @@ .Op Fl b Ar channel:target[.lun] .Op Fl H Ar channel:target[.lun] .Op Fl R Ar device | channel:target[.lun] +.Op Fl t Ar patrol-function .Op Fl u Ar channel:target[.lun] .Ar device .Ek @@ -144,6 +145,29 @@ in the volume. .Ar device must be specified as a full path to the chunk device file (e.g. /dev/wd0d). A RAID volume rather than a RAID controller is expected as the final argument. +.It Fl t Ar patrol-function +Control the RAID card's patrol functionality, if supported. +.Ar patrol-function +may be one of: +.Pp +.Bl -tag -width disable -compact +.It Ar stop +Stop the patrol on the RAID controller. +.It Ar start +Start the patrol on the RAID controller. +.It Ar get +Retrieve the current patrol configuration. +.It Ar disable +Disable the patrol functionality. +.It Ar manual +Enable the patrol functionality to start/stop manually. +.It Ar auto[.interval[.start]] +Enable the patrol functionality to start/stop automatically in every +.Ar interval +seconds, starting the first iteration after +.Ar start +seconds. +.El .It Fl u Ar channel:target[.lun] Instruct the device at .Ar channel:target[.lun] diff --git a/sbin/bioctl/bioctl.c b/sbin/bioctl/bioctl.c index c7c905db496..e17101b6d92 100644 --- a/sbin/bioctl/bioctl.c +++ b/sbin/bioctl/bioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bioctl.c,v 1.126 2015/05/11 12:14:22 pelikan Exp $ */ +/* $OpenBSD: bioctl.c,v 1.127 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2004, 2005 Marco Peereboom @@ -53,8 +53,14 @@ struct locator { int lun; }; +struct timing { + int interval; + int start; +}; + void usage(void); const char *str2locator(const char *, struct locator *); +const char *str2patrol(const char *, struct timing *); void bio_status(struct bio_status *); int bio_parse_devlist(char *, dev_t *); void bio_kdf_derive(struct sr_crypto_kdfinfo *, @@ -75,6 +81,7 @@ void bio_changepass(char *); u_int32_t bio_createflags(char *); char *bio_vis(char *); void bio_diskinq(char *); +void bio_patrol(char *); int devh = -1; int human; @@ -106,7 +113,7 @@ main(int argc, char *argv[]) if (argc < 2) usage(); - while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:O:Pp:qr:R:su:v")) != + while ((ch = getopt(argc, argv, "a:b:C:c:dH:hik:l:O:Pp:qr:R:st:u:v")) != -1) { switch (ch) { case 'a': /* alarm */ @@ -185,6 +192,10 @@ main(int argc, char *argv[]) case 's': rpp_flag = RPP_STDIN; break; + case 't': /* patrol */ + func |= BIOC_PATROL; + al_arg = optarg; + break; case 'v': verbose = 1; break; @@ -237,6 +248,8 @@ main(int argc, char *argv[]) bio_alarm(al_arg); } else if (func == BIOC_BLINK) { bio_setblink(devicename, bl_arg, blink); + } else if (func == BIOC_PATROL) { + bio_patrol(al_arg); } else if (func == BIOC_SETSTATE) { bio_setstate(al_arg, ss_func, argv[0]); } else if (func == BIOC_DELETERAID && !biodev) { @@ -271,7 +284,7 @@ usage(void) "\t[-l special[,special,...]] " "[-O device | channel:target[.lun]]\n" "\t[-p passfile] [-R device | channel:target[.lun]]\n" - "\t[-r rounds] " + "\t[-r rounds] [-t patrol-function] " "device\n", __progname, __progname); exit(1); @@ -307,6 +320,39 @@ str2locator(const char *string, struct locator *location) return (NULL); } +const char * +str2patrol(const char *string, struct timing *timing) +{ + const char *errstr; + char parse[80], *interval = NULL, *start = NULL; + + timing->interval = 0; + timing->start = 0; + + strlcpy(parse, string, sizeof parse); + + interval = strchr(parse, '.'); + if (interval != NULL) { + *interval++ = '\0'; + start = strchr(interval, '.'); + if (start != NULL) + *start++ = '\0'; + } + if (interval != NULL) { + /* -1 == continuously */ + timing->interval = strtonum(interval, -1, INT_MAX, &errstr); + if (errstr) + return (errstr); + } + if (start != NULL) { + timing->start = strtonum(start, 0, INT_MAX, &errstr); + if (errstr) + return (errstr); + } + + return (NULL); +} + void bio_status(struct bio_status *bs) { @@ -335,7 +381,7 @@ bio_inq(char *name) { char *status, *cache; char size[64], scsiname[16], volname[32]; - char percent[10], seconds[20]; + char percent[20], seconds[20]; int i, d, volheader, hotspare, unused; char encname[16], serial[32]; struct bioc_inq bi; @@ -461,6 +507,8 @@ bio_inq(char *name) bd.bd_bio.bio_cookie = bio_cookie; bd.bd_diskid = d; bd.bd_volid = i; + bd.bd_patrol.bdp_percent = -1; + bd.bd_patrol.bdp_seconds = 0; if (ioctl(devh, BIOCDISK, &bd)) err(1, "BIOCDISK"); @@ -519,12 +567,21 @@ bio_inq(char *name) else strlcpy(serial, "unknown serial", sizeof serial); + percent[0] = '\0'; + seconds[0] = '\0'; + if (bd.bd_patrol.bdp_percent != -1) + snprintf(percent, sizeof percent, + " patrol %d%% done", bd.bd_patrol.bdp_percent); + if (bd.bd_patrol.bdp_seconds) + snprintf(seconds, sizeof seconds, + " %u seconds", bd.bd_patrol.bdp_seconds); + printf("%11s %-10s %14s %-7s %-6s <%s>\n", volname, status, size, scsiname, encname, bd.bd_vendor); if (verbose) - printf("%11s %-10s %14s %-7s %-6s '%s'\n", - "", "", "", "", "", serial); + printf("%11s %-10s %14s %-7s %-6s '%s'%s%s\n", + "", "", "", "", "", serial, percent, seconds); } } } @@ -1103,6 +1160,104 @@ bio_diskinq(char *sd_dev) bio_vis(di.product), bio_vis(di.revision), bio_vis(di.serial)); } +void +bio_patrol(char *arg) +{ + struct bioc_patrol bp; + struct timing timing; + const char *errstr; + + memset(&bp, 0, sizeof(bp)); + bp.bp_bio.bio_cookie = bio_cookie; + + switch (arg[0]) { + case 'a': + bp.bp_opcode = BIOC_SPAUTO; + break; + + case 'm': + bp.bp_opcode = BIOC_SPMANUAL; + break; + + case 'd': + bp.bp_opcode = BIOC_SPDISABLE; + break; + + case 'g': /* get patrol state */ + bp.bp_opcode = BIOC_GPSTATUS; + break; + + case 's': /* start/stop patrol */ + if (strncmp("sta", arg, 3) == 0) + bp.bp_opcode = BIOC_SPSTART; + else + bp.bp_opcode = BIOC_SPSTOP; + break; + + default: + errx(1, "invalid patrol function: %s", arg); + } + + switch (arg[0]) { + case 'a': + errstr = str2patrol(arg, &timing); + if (errstr) + errx(1, "Patrol %s: %s", arg, errstr); + bp.bp_autoival = timing.interval; + bp.bp_autonext = timing.start; + break; + } + + if (ioctl(devh, BIOCPATROL, &bp)) + err(1, "BIOCPATROL"); + + bio_status(&bp.bp_bio.bio_status); + + if (arg[0] == 'g') { + const char *mode, *status; + char interval[40]; + + interval[0] = '\0'; + + switch (bp.bp_mode) { + case BIOC_SPMAUTO: + mode = "auto"; + snprintf(interval, sizeof interval, + " interval=%d next=%d", bp.bp_autoival, + bp.bp_autonext - bp.bp_autonow); + break; + case BIOC_SPMMANUAL: + mode = "manual"; + break; + case BIOC_SPMDISABLED: + mode = "disabled"; + break; + default: + status = "unknown"; + break; + } + switch (bp.bp_status) { + case BIOC_SPSSTOPPED: + status = "stopped"; + break; + case BIOC_SPSREADY: + status = "ready"; + break; + case BIOC_SPSACTIVE: + status = "active"; + break; + case BIOC_SPSABORTED: + status = "aborted"; + break; + default: + status = "unknown"; + break; + } + printf("patrol mode: %s%s\n", mode, interval); + printf("patrol status: %s\n", status); + } +} + void derive_key_pkcs(int rounds, u_int8_t *key, size_t keysz, u_int8_t *salt, size_t saltsz, char *prompt, int verify) diff --git a/sys/dev/bio.c b/sys/dev/bio.c index 42956d5820b..c0bb3aaf715 100644 --- a/sys/dev/bio.c +++ b/sys/dev/bio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bio.c,v 1.15 2014/07/12 18:48:17 tedu Exp $ */ +/* $OpenBSD: bio.c,v 1.16 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2002 Niklas Hallqvist. All rights reserved. @@ -98,6 +98,7 @@ bioioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) case BIOCCREATERAID: case BIOCDELETERAID: case BIOCDISCIPLINE: + case BIOCPATROL: bio = (struct bio *)addr; if (!bio_validate(bio->bio_cookie)) return (ENOENT); diff --git a/sys/dev/biovar.h b/sys/dev/biovar.h index 4c4bcc4b402..e083c629165 100644 --- a/sys/dev/biovar.h +++ b/sys/dev/biovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: biovar.h,v 1.43 2013/10/23 13:05:38 kettenis Exp $ */ +/* $OpenBSD: biovar.h,v 1.44 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2002 Niklas Hallqvist. All rights reserved. @@ -110,6 +110,11 @@ struct bioc_disk { char bd_vendor[32]; /* scsi string */ char bd_serial[32]; /* serial number */ char bd_procdev[16]; /* processor device */ + + struct { + int bdp_percent; + int bdp_seconds; + } bd_patrol; }; #define BIOCVOL _IOWR('B', 34, struct bioc_vol) @@ -246,6 +251,32 @@ struct bioc_installboot { u_int32_t bb_bootldr_size; }; +#define BIOCPATROL _IOWR('B', 42, struct bioc_patrol) +struct bioc_patrol { + struct bio bp_bio; + int bp_opcode; +#define BIOC_SPSTOP 0x00 /* stop patrol */ +#define BIOC_SPSTART 0x01 /* start patrol */ +#define BIOC_GPSTATUS 0x02 /* get status */ +#define BIOC_SPDISABLE 0x03 /* disable patrol */ +#define BIOC_SPAUTO 0x04 /* enable patrol as auto */ +#define BIOC_SPMANUAL 0x05 /* enable patrol as manual */ + + int bp_mode; +#define BIOC_SPMAUTO 0x00 +#define BIOC_SPMMANUAL 0x01 +#define BIOC_SPMDISABLED 0x02 + int bp_status; /* only used with get state */ +#define BIOC_SPSSTOPPED 0x00 +#define BIOC_SPSREADY 0x01 +#define BIOC_SPSACTIVE 0x02 +#define BIOC_SPSABORTED 0xff + + int bp_autoival; + int bp_autonext; + int bp_autonow; +}; + /* kernel and userspace defines */ #define BIOC_INQ 0x0001 #define BIOC_DISK 0x0002 @@ -257,6 +288,7 @@ struct bioc_installboot { #define BIOC_DELETERAID 0x0080 #define BIOC_DISCIPLINE 0x0100 #define BIOC_INSTALLBOOT 0x0200 +#define BIOC_PATROL 0x0400 /* user space defines */ #define BIOC_DEVLIST 0x10000 diff --git a/sys/dev/i2c/i2c_scan.c b/sys/dev/i2c/i2c_scan.c index 01064cbda45..66fa92f65c8 100644 --- a/sys/dev/i2c/i2c_scan.c +++ b/sys/dev/i2c/i2c_scan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: i2c_scan.c,v 1.143 2014/11/14 07:03:22 jsg Exp $ */ +/* $OpenBSD: i2c_scan.c,v 1.144 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2005 Theo de Raadt @@ -1059,6 +1059,7 @@ iic_scan(struct device *self, struct i2cbus_attach_args *iba) bzero(ignore_addrs, sizeof(ignore_addrs)); for (i = 0; probes[i].probe; i++) { +#if 0 #if NIPMI > 0 extern int ipmi_enabled; @@ -1067,6 +1068,7 @@ iic_scan(struct device *self, struct i2cbus_attach_args *iba) self->dv_xname); continue; } +#endif #endif pl = probes[i].pl; for (j = 0; pl[j].start && pl[j].end; j++) { diff --git a/sys/dev/ic/mfi.c b/sys/dev/ic/mfi.c index 535a30becf8..3da6e73f71b 100644 --- a/sys/dev/ic/mfi.c +++ b/sys/dev/ic/mfi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfi.c,v 1.163 2015/05/18 12:21:04 mikeb Exp $ */ +/* $OpenBSD: mfi.c,v 1.164 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2006 Marco Peereboom * @@ -117,6 +117,7 @@ int mfi_ioctl_disk(struct mfi_softc *, struct bioc_disk *); int mfi_ioctl_alarm(struct mfi_softc *, struct bioc_alarm *); int mfi_ioctl_blink(struct mfi_softc *sc, struct bioc_blink *); int mfi_ioctl_setstate(struct mfi_softc *, struct bioc_setstate *); +int mfi_ioctl_patrol(struct mfi_softc *sc, struct bioc_patrol *); int mfi_bio_hs(struct mfi_softc *, int, int, void *); #ifndef SMALL_KERNEL int mfi_create_sensors(struct mfi_softc *); @@ -1562,6 +1563,11 @@ mfi_ioctl(struct device *dev, u_long cmd, caddr_t addr) error = mfi_ioctl_setstate(sc, (struct bioc_setstate *)addr); break; + case BIOCPATROL: + DNPRINTF(MFI_D_IOCTL, "patrol\n"); + error = mfi_ioctl_patrol(sc, (struct bioc_patrol *)addr); + break; + default: DNPRINTF(MFI_D_IOCTL, " invalid ioctl\n"); error = EINVAL; @@ -1782,6 +1788,8 @@ mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) struct mfi_array *ar; struct mfi_ld_cfg *ld; struct mfi_pd_details *pd; + struct mfi_pd_progress *mfp; + struct mfi_progress *mp; struct scsi_inquiry_data *inqbuf; char vend[8+16+4+1], *vendp; int rv = EINVAL; @@ -1877,6 +1885,13 @@ mfi_ioctl_disk(struct mfi_softc *sc, struct bioc_disk *bd) /* XXX find a way to retrieve serial nr from drive */ /* XXX find a way to get bd_procdev */ + mfp = &pd->mpd_progress; + if (mfp->mfp_in_prog & MFI_PD_PROG_PR) { + mp = &mfp->mfp_patrol_read; + bd->bd_patrol.bdp_percent = (mp->mp_progress * 100) / 0xffff; + bd->bd_patrol.bdp_seconds = mp->mp_elapsed_seconds; + } + rv = 0; freeme: free(pd, M_DEVBUF, 0); @@ -2064,6 +2079,142 @@ done: return (rv); } +int +mfi_ioctl_patrol(struct mfi_softc *sc, struct bioc_patrol *bp) +{ + uint32_t opc, dir = MFI_DATA_NONE; + int rv = 0; + struct mfi_pr_properties prop; + struct mfi_pr_status status; + uint32_t time, exec_freq; + + switch (bp->bp_opcode) { + case BIOC_SPSTOP: + case BIOC_SPSTART: + if (bp->bp_opcode == BIOC_SPSTART) + opc = MR_DCMD_PR_START; + else + opc = MR_DCMD_PR_STOP; + dir = MFI_DATA_IN; + if (mfi_mgmt(sc, opc, dir, 0, NULL, NULL)) + return (EINVAL); + break; + + case BIOC_SPMANUAL: + case BIOC_SPDISABLE: + case BIOC_SPAUTO: + /* Get device's time. */ + opc = MR_DCMD_TIME_SECS_GET; + dir = MFI_DATA_IN; + if (mfi_mgmt(sc, opc, dir, sizeof(time), &time, NULL)) + return (EINVAL); + + opc = MR_DCMD_PR_GET_PROPERTIES; + dir = MFI_DATA_IN; + if (mfi_mgmt(sc, opc, dir, sizeof(prop), &prop, NULL)) + return (EINVAL); + + switch (bp->bp_opcode) { + case BIOC_SPMANUAL: + prop.op_mode = MFI_PR_OPMODE_MANUAL; + break; + case BIOC_SPDISABLE: + prop.op_mode = MFI_PR_OPMODE_DISABLED; + break; + case BIOC_SPAUTO: + if (bp->bp_autoival != 0) { + if (bp->bp_autoival == -1) + /* continuously */ + exec_freq = 0xffffffffU; + else if (bp->bp_autoival > 0) + exec_freq = bp->bp_autoival; + else + return (EINVAL); + prop.exec_freq = exec_freq; + } + if (bp->bp_autonext != 0) { + if (bp->bp_autonext < 0) + return (EINVAL); + else + prop.next_exec = time + bp->bp_autonext; + } + prop.op_mode = MFI_PR_OPMODE_AUTO; + break; + } + + opc = MR_DCMD_PR_SET_PROPERTIES; + dir = MFI_DATA_OUT; + if (mfi_mgmt(sc, opc, dir, sizeof(prop), &prop, NULL)) + return (EINVAL); + + break; + + case BIOC_GPSTATUS: + opc = MR_DCMD_PR_GET_PROPERTIES; + dir = MFI_DATA_IN; + if (mfi_mgmt(sc, opc, dir, sizeof(prop), &prop, NULL)) + return (EINVAL); + + opc = MR_DCMD_PR_GET_STATUS; + dir = MFI_DATA_IN; + if (mfi_mgmt(sc, opc, dir, sizeof(status), &status, NULL)) + return (EINVAL); + + /* Get device's time. */ + opc = MR_DCMD_TIME_SECS_GET; + dir = MFI_DATA_IN; + if (mfi_mgmt(sc, opc, dir, sizeof(time), &time, NULL)) + return (EINVAL); + + switch (prop.op_mode) { + case MFI_PR_OPMODE_AUTO: + bp->bp_mode = BIOC_SPMAUTO; + bp->bp_autoival = prop.exec_freq; + bp->bp_autonext = prop.next_exec; + bp->bp_autonow = time; + break; + case MFI_PR_OPMODE_MANUAL: + bp->bp_mode = BIOC_SPMMANUAL; + break; + case MFI_PR_OPMODE_DISABLED: + bp->bp_mode = BIOC_SPMDISABLED; + break; + default: + printf("%s: unknown patrol mode %d\n", + DEVNAME(sc), prop.op_mode); + break; + } + + switch (status.state) { + case MFI_PR_STATE_STOPPED: + bp->bp_status = BIOC_SPSSTOPPED; + break; + case MFI_PR_STATE_READY: + bp->bp_status = BIOC_SPSREADY; + break; + case MFI_PR_STATE_ACTIVE: + bp->bp_status = BIOC_SPSACTIVE; + break; + case MFI_PR_STATE_ABORTED: + bp->bp_status = BIOC_SPSABORTED; + break; + default: + printf("%s: unknown patrol state %d\n", + DEVNAME(sc), status.state); + break; + } + + break; + + default: + DNPRINTF(MFI_D_IOCTL, "%s: mfi_ioctl_patrol biocpatrol invalid " + "opcode %x\n", DEVNAME(sc), bp->bp_opcode); + return (EINVAL); + } + + return (rv); +} + int mfi_bio_hs(struct mfi_softc *sc, int volid, int type, void *bio_hs) { diff --git a/sys/dev/ic/mfireg.h b/sys/dev/ic/mfireg.h index 64fb22f34dc..30351404289 100644 --- a/sys/dev/ic/mfireg.h +++ b/sys/dev/ic/mfireg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mfireg.h,v 1.42 2015/01/09 11:17:29 yasuoka Exp $ */ +/* $OpenBSD: mfireg.h,v 1.43 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2006 Marco Peereboom * @@ -99,6 +99,15 @@ #define MFI_CMD_SMP 0x07 #define MFI_CMD_STP 0x08 +#define MFI_PR_STATE_STOPPED 0 +#define MFI_PR_STATE_READY 1 +#define MFI_PR_STATE_ACTIVE 2 +#define MFI_PR_STATE_ABORTED 0xff + +#define MFI_PR_OPMODE_AUTO 0x00 +#define MFI_PR_OPMODE_MANUAL 0x01 +#define MFI_PR_OPMODE_DISABLED 0x02 + /* direct commands */ #define MR_DCMD_CTRL_GET_INFO 0x01010000 #define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000 @@ -109,6 +118,12 @@ #define MR_DCMD_CTRL_EVENT_GET_INFO 0x01040100 #define MR_DCMD_CTRL_EVENT_GET 0x01040300 #define MR_DCMD_CTRL_EVENT_WAIT 0x01040500 +#define MR_DCMD_PR_GET_STATUS 0x01070100 +#define MR_DCMD_PR_GET_PROPERTIES 0x01070200 +#define MR_DCMD_PR_SET_PROPERTIES 0x01070300 +#define MR_DCMD_PR_START 0x01070400 +#define MR_DCMD_PR_STOP 0x01070500 +#define MR_DCMD_TIME_SECS_GET 0x01080201 #define MR_DCMD_PD_GET_LIST 0x02010000 #define MR_DCMD_PD_GET_INFO 0x02020000 #define MR_DCMD_PD_SET_STATE 0x02030100 @@ -120,7 +135,10 @@ #define MR_DCMD_LD_GET_INFO 0x03020000 #define MR_DCMD_LD_GET_PROPERTIES 0x03030000 #define MR_DCMD_LD_SET_PROPERTIES 0x03040000 +#define MR_DCMD_LD_DELETE 0x03090000 #define MR_DCMD_CONF_GET 0x04010000 +#define MR_DCMD_CFG_ADD 0x04020000 +#define MR_DCMD_CFG_CLEAR 0x04030000 #define MR_DCMD_BBU_GET_STATUS 0x05010000 #define MR_DCMD_BBU_GET_CAPACITY_INFO 0x05020000 #define MR_DCMD_BBU_GET_DESIGN_INFO 0x05030000 @@ -1128,3 +1146,22 @@ struct mfi_bbu_status { union mfi_bbu_status_detail detail; } __packed; +struct mfi_pr_status { + uint32_t num_iteration; + uint8_t state; + uint8_t num_pd_done; + uint8_t reserved[10]; +} __packed; + +struct mfi_pr_properties { + uint8_t op_mode; + uint8_t max_pd; + uint8_t reserved; + uint8_t exclude_ld_count; + uint16_t excluded_ld[MFI_MAX_LD]; + uint8_t cur_pd_map[MFI_MAX_PD / 8]; + uint8_t last_pd_map[MFI_MAX_PD / 8]; + uint32_t next_exec; + uint32_t exec_freq; + uint32_t clear_freq; +} __packed; diff --git a/sys/dev/pci/if_vic.c b/sys/dev/pci/if_vic.c index b724dcb1fbb..68c6755d15b 100644 --- a/sys/dev/pci/if_vic.c +++ b/sys/dev/pci/if_vic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vic.c,v 1.88 2015/04/30 07:52:00 mpi Exp $ */ +/* $OpenBSD: if_vic.c,v 1.89 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2006 Reyk Floeter @@ -1341,6 +1341,16 @@ void vic_tick(void *arg) { struct vic_softc *sc = (struct vic_softc *)arg; + int s, q; + + /* + * XXX Poll Rx interrupt and process existing packets to work-around + * XXX occasional Rx interrupt lossage. + */ + s = splnet(); + for (q = 0; q < VIC_NRXRINGS; q++) + vic_rx_proc(sc, q); + splx(s); vic_link_state(sc); diff --git a/sys/dev/pci/if_vmx.c b/sys/dev/pci/if_vmx.c index 13d595ca5a6..a617f6e79a0 100644 --- a/sys/dev/pci/if_vmx.c +++ b/sys/dev/pci/if_vmx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vmx.c,v 1.26 2015/05/26 12:29:42 dlg Exp $ */ +/* $OpenBSD: if_vmx.c,v 1.27 2015/05/29 00:33:37 uebayasi Exp $ */ /* * Copyright (c) 2013 Tsubai Masanari @@ -151,6 +151,7 @@ int vmxnet3_alloc_rxring(struct vmxnet3_softc *, int); void vmxnet3_txinit(struct vmxnet3_softc *, struct vmxnet3_txqueue *); void vmxnet3_rxinit(struct vmxnet3_softc *, struct vmxnet3_rxqueue *); void vmxnet3_txstop(struct vmxnet3_softc *, struct vmxnet3_txqueue *); +void vmxnet3_rxdump(struct vmxnet3_softc *); void vmxnet3_rxstop(struct vmxnet3_softc *, struct vmxnet3_rxqueue *); void vmxnet3_link_state(struct vmxnet3_softc *); void vmxnet3_enable_all_intrs(struct vmxnet3_softc *); @@ -516,6 +517,28 @@ vmxnet3_txstop(struct vmxnet3_softc *sc, struct vmxnet3_txqueue *tq) } } +void +vmxnet3_rxdump(struct vmxnet3_softc *sc) +{ +#if 0 + int queue, i; + + for (queue = 0; queue < NRXQUEUE; queue++) { + struct vmxnet3_rxqueue *rq = &sc->sc_rxq[queue]; + + for (i = 0; i < 2; i++) { + struct vmxnet3_rxring *ring = &rq->cmd_ring[i]; + + struct if_rxring *r = &ring->rxr; + printf("ring%d: " + "adjusted=%d alive=%u cwm=%u lwm=%u hwm=%u\n", + i, + r->rxr_adjusted, r->rxr_alive, r->rxr_cwm, r->rxr_lwm, r->rxr_hwm); + } + } +#endif +} + void vmxnet3_rxstop(struct vmxnet3_softc *sc, struct vmxnet3_rxqueue *rq) { @@ -913,6 +936,7 @@ vmxnet3_stop(struct ifnet *ifp) vmxnet3_txstop(sc, &sc->sc_txq[queue]); for (queue = 0; queue < NRXQUEUE; queue++) vmxnet3_rxstop(sc, &sc->sc_rxq[queue]); + vmxnet3_rxdump(sc); } void @@ -941,6 +965,7 @@ vmxnet3_init(struct vmxnet3_softc *sc) vmxnet3_txinit(sc, &sc->sc_txq[queue]); for (queue = 0; queue < NRXQUEUE; queue++) vmxnet3_rxinit(sc, &sc->sc_rxq[queue]); + vmxnet3_rxdump(sc); WRITE_CMD(sc, VMXNET3_CMD_ENABLE); if (READ_BAR1(sc, VMXNET3_BAR1_CMD)) { -- 2.20.1