Initial addition of ``Patrol Read'' support in bio(4), biocto(8), and
authoruebayasi <uebayasi@openbsd.org>
Fri, 29 May 2015 00:33:37 +0000 (00:33 +0000)
committeruebayasi <uebayasi@openbsd.org>
Fri, 29 May 2015 00:33:37 +0000 (00:33 +0000)
mfi(4).  Based on FreeBSD, but done without mfiutil(8).

OK deraadt@

sbin/bioctl/bioctl.8
sbin/bioctl/bioctl.c
sys/dev/bio.c
sys/dev/biovar.h
sys/dev/i2c/i2c_scan.c
sys/dev/ic/mfi.c
sys/dev/ic/mfireg.h
sys/dev/pci/if_vic.c
sys/dev/pci/if_vmx.c

index 2eb5bcb..2a4e1b7 100644 (file)
@@ -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]
index c7c905d..e17101b 100644 (file)
@@ -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)
index 42956d5..c0bb3aa 100644 (file)
@@ -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);
index 4c4bcc4..e083c62 100644 (file)
@@ -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
index 01064cb..66fa92f 100644 (file)
@@ -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 <deraadt@openbsd.org>
@@ -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++) {
index 535a30b..3da6e73 100644 (file)
@@ -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 <marco@peereboom.us>
  *
@@ -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)
 {
index 64fb22f..3035140 100644 (file)
@@ -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 <marco@peereboom.us>
  *
 #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
 #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
 #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;
index b724dcb..68c6755 100644 (file)
@@ -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 <reyk@openbsd.org>
@@ -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);
 
index 13d595c..a617f6e 100644 (file)
@@ -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)) {