diff options
author | gjb <gjb@FreeBSD.org> | 2016-04-16 02:32:12 +0000 |
---|---|---|
committer | gjb <gjb@FreeBSD.org> | 2016-04-16 02:32:12 +0000 |
commit | 6549ef7d128d37c0dfff87f6c1c189b42ed3e1ef (patch) | |
tree | a8871301d693c6d33d43cd3171b1ee4783fec0e4 /usr.sbin | |
parent | ae096a53a90aee9859587d48d5a0279567abb413 (diff) | |
parent | 35691f7a6f04cec368d8636543bca596e870faf3 (diff) | |
download | FreeBSD-src-6549ef7d128d37c0dfff87f6c1c189b42ed3e1ef.zip FreeBSD-src-6549ef7d128d37c0dfff87f6c1c189b42ed3e1ef.tar.gz |
MFH
Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/bhyve/pci_emul.h | 2 | ||||
-rw-r--r-- | usr.sbin/bhyve/pci_passthru.c | 117 | ||||
-rw-r--r-- | usr.sbin/ctm/ctm/ctm.1 | 7 | ||||
-rw-r--r-- | usr.sbin/fdformat/fdformat.c | 6 | ||||
-rw-r--r-- | usr.sbin/fdread/fdread.c | 2 | ||||
-rw-r--r-- | usr.sbin/fdread/fdutil.c | 4 | ||||
-rw-r--r-- | usr.sbin/fmtree/excludes.c | 6 | ||||
-rw-r--r-- | usr.sbin/fstyp/fstyp.c | 2 | ||||
-rw-r--r-- | usr.sbin/keyserv/keyserv.c | 2 | ||||
-rw-r--r-- | usr.sbin/kgmon/kgmon.c | 2 | ||||
-rw-r--r-- | usr.sbin/lmcconfig/lmcconfig.c | 4 | ||||
-rw-r--r-- | usr.sbin/mountd/mountd.c | 6 | ||||
-rw-r--r-- | usr.sbin/nfscbd/nfscbd.c | 2 | ||||
-rw-r--r-- | usr.sbin/nfsd/nfsd.c | 2 | ||||
-rw-r--r-- | usr.sbin/pmcstudy/pmcstudy.c | 2 | ||||
-rw-r--r-- | usr.sbin/portsnap/phttpget/phttpget.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/command.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/filter.c | 2 | ||||
-rw-r--r-- | usr.sbin/ppp/radius.c | 2 | ||||
-rw-r--r-- | usr.sbin/rmt/rmt.c | 8 | ||||
-rw-r--r-- | usr.sbin/tzsetup/tzsetup.c | 16 |
21 files changed, 143 insertions, 55 deletions
diff --git a/usr.sbin/bhyve/pci_emul.h b/usr.sbin/bhyve/pci_emul.h index 6b8c4e0..d6e5490 100644 --- a/usr.sbin/bhyve/pci_emul.h +++ b/usr.sbin/bhyve/pci_emul.h @@ -142,6 +142,8 @@ struct pci_devinst { int pba_size; int function_mask; struct msix_table_entry *table; /* allocated at runtime */ + void *pba_page; + int pba_page_offset; } pi_msix; void *pi_arg; /* devemu-private data */ diff --git a/usr.sbin/bhyve/pci_passthru.c b/usr.sbin/bhyve/pci_passthru.c index 5b52b05..66d31a2 100644 --- a/usr.sbin/bhyve/pci_passthru.c +++ b/usr.sbin/bhyve/pci_passthru.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/types.h> +#include <sys/mman.h> #include <sys/pciio.h> #include <sys/ioctl.h> @@ -59,6 +60,10 @@ __FBSDID("$FreeBSD$"); #define _PATH_DEVIO "/dev/io" #endif +#ifndef _PATH_MEM +#define _PATH_MEM "/dev/mem" +#endif + #define LEGACY_SUPPORT 1 #define MSIX_TABLE_COUNT(ctrl) (((ctrl) & PCIM_MSIXCTRL_TABLE_SIZE) + 1) @@ -66,6 +71,7 @@ __FBSDID("$FreeBSD$"); static int pcifd = -1; static int iofd = -1; +static int memfd = -1; struct passthru_softc { struct pci_devinst *psc_pi; @@ -279,6 +285,35 @@ msix_table_read(struct passthru_softc *sc, uint64_t offset, int size) int index; pi = sc->psc_pi; + if (offset >= pi->pi_msix.pba_offset && + offset < pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { + switch(size) { + case 1: + src8 = (uint8_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src8; + break; + case 2: + src16 = (uint16_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src16; + break; + case 4: + src32 = (uint32_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src32; + break; + case 8: + src64 = (uint64_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + data = *src64; + break; + default: + return (-1); + } + return (data); + } + if (offset < pi->pi_msix.table_offset) return (-1); @@ -320,12 +355,44 @@ msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, { struct pci_devinst *pi; struct msix_table_entry *entry; - uint32_t *dest; + uint8_t *dest8; + uint16_t *dest16; + uint32_t *dest32; + uint64_t *dest64; size_t entry_offset; uint32_t vector_control; int error, index; pi = sc->psc_pi; + if (offset >= pi->pi_msix.pba_offset && + offset < pi->pi_msix.pba_offset + pi->pi_msix.pba_size) { + switch(size) { + case 1: + dest8 = (uint8_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest8 = data; + break; + case 2: + dest16 = (uint16_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest16 = data; + break; + case 4: + dest32 = (uint32_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest32 = data; + break; + case 8: + dest64 = (uint64_t *)(pi->pi_msix.pba_page + offset - + pi->pi_msix.pba_page_offset); + *dest64 = data; + break; + default: + break; + } + return; + } + if (offset < pi->pi_msix.table_offset) return; @@ -342,8 +409,8 @@ msix_table_write(struct vmctx *ctx, int vcpu, struct passthru_softc *sc, assert(entry_offset % 4 == 0); vector_control = entry->vector_control; - dest = (uint32_t *)((void *)entry + entry_offset); - *dest = data; + dest32 = (uint32_t *)((void *)entry + entry_offset); + *dest32 = data; /* If MSI-X hasn't been enabled, do nothing */ if (pi->pi_msix.enabled) { /* If the entry is masked, don't set it up */ @@ -386,28 +453,44 @@ init_msix_table(struct vmctx *ctx, struct passthru_softc *sc, uint64_t base) table_size += pi->pi_msix.table_count * MSIX_TABLE_ENTRY_SIZE; table_size = roundup2(table_size, 4096); + idx = pi->pi_msix.table_bar; + start = pi->pi_bar[idx].addr; + remaining = pi->pi_bar[idx].size; + if (pi->pi_msix.pba_bar == pi->pi_msix.table_bar) { pba_offset = pi->pi_msix.pba_offset; pba_size = pi->pi_msix.pba_size; if (pba_offset >= table_offset + table_size || table_offset >= pba_offset + pba_size) { /* - * The PBA can reside in the same BAR as the MSI-x - * tables as long as it does not overlap with any - * naturally aligned page occupied by the tables. + * If the PBA does not share a page with the MSI-x + * tables, no PBA emulation is required. */ + pi->pi_msix.pba_page = NULL; + pi->pi_msix.pba_page_offset = 0; } else { - /* Need to also emulate the PBA, not supported yet */ - printf("Unsupported MSI-X configuration: %d/%d/%d\n", - b, s, f); - return (-1); + /* + * The PBA overlaps with either the first or last + * page of the MSI-X table region. Map the + * appropriate page. + */ + if (pba_offset <= table_offset) + pi->pi_msix.pba_page_offset = table_offset; + else + pi->pi_msix.pba_page_offset = table_offset + + table_size - 4096; + pi->pi_msix.pba_page = mmap(NULL, 4096, PROT_READ | + PROT_WRITE, MAP_SHARED, memfd, start + + pi->pi_msix.pba_page_offset); + if (pi->pi_msix.pba_page == MAP_FAILED) { + printf( + "Failed to map PBA page for MSI-X on %d/%d/%d: %s\n", + b, s, f, strerror(errno)); + return (-1); + } } } - idx = pi->pi_msix.table_bar; - start = pi->pi_bar[idx].addr; - remaining = pi->pi_bar[idx].size; - /* Map everything before the MSI-X table */ if (table_offset > 0) { len = table_offset; @@ -572,6 +655,12 @@ passthru_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) goto done; } + if (memfd < 0) { + memfd = open(_PATH_MEM, O_RDWR, 0); + if (memfd < 0) + goto done; + } + if (opts == NULL || sscanf(opts, "%d/%d/%d", &bus, &slot, &func) != 3) goto done; diff --git a/usr.sbin/ctm/ctm/ctm.1 b/usr.sbin/ctm/ctm/ctm.1 index 6ba35c9..819a14b 100644 --- a/usr.sbin/ctm/ctm/ctm.1 +++ b/usr.sbin/ctm/ctm/ctm.1 @@ -12,7 +12,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 14, 2015 +.Dd April 14, 2016 .Dt CTM 1 .Os .Sh NAME @@ -308,11 +308,6 @@ options. .Xr ctm_smail 1 , .Xr ctm 5 .Rs -.%B "The FreeBSD Handbook" -.%T "Using CTM" -.%U http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/ctm.html -.Re -.Rs .%T "Miscellaneous CTM on FreeBSD Resources" .%U http://ctm.berklix.org .Re diff --git a/usr.sbin/fdformat/fdformat.c b/usr.sbin/fdformat/fdformat.c index 341a161..b7bab86 100644 --- a/usr.sbin/fdformat/fdformat.c +++ b/usr.sbin/fdformat/fdformat.c @@ -95,7 +95,7 @@ verify_track(int fd, int track, int tracksize) if (bufsz < tracksize) buf = realloc(buf, bufsz = tracksize); - if (buf == 0) + if (buf == NULL) errx(EX_UNAVAILABLE, "out of memory"); if (lseek (fd, (long) track * tracksize, 0) < 0) rv = -1; @@ -205,7 +205,7 @@ main(int argc, char **argv) if (stat(argv[optind], &sb) == -1 && errno == ENOENT) { /* try prepending _PATH_DEV */ device = malloc(strlen(argv[optind]) + sizeof(_PATH_DEV) + 1); - if (device == 0) + if (device == NULL) errx(EX_UNAVAILABLE, "out of memory"); strcpy(device, _PATH_DEV); strcat(device, argv[optind]); @@ -252,7 +252,7 @@ main(int argc, char **argv) if (format) { getname(type, &name, &descr); fdtp = get_fmt(format, type); - if (fdtp == 0) + if (fdtp == NULL) errx(EX_USAGE, "unknown format %d KB for drive type %s", format, name); diff --git a/usr.sbin/fdread/fdread.c b/usr.sbin/fdread/fdread.c index 770f92d..f3c2d91 100644 --- a/usr.sbin/fdread/fdread.c +++ b/usr.sbin/fdread/fdread.c @@ -170,7 +170,7 @@ doread(int fd, FILE *of, const char *_devname) secsize = 128 << fdt.secsize; tracksize = fdt.sectrac * secsize; mediasize = tracksize * fdt.tracks * fdt.heads; - if ((trackbuf = malloc(tracksize)) == 0) + if ((trackbuf = malloc(tracksize)) == NULL) errx(EX_TEMPFAIL, "out of memory"); if (!quiet) diff --git a/usr.sbin/fdread/fdutil.c b/usr.sbin/fdread/fdutil.c index c66b0c1..bdd295a 100644 --- a/usr.sbin/fdread/fdutil.c +++ b/usr.sbin/fdread/fdutil.c @@ -200,10 +200,10 @@ parse_fmt(const char *s, enum fd_drivetype type, *out = in; for (i = 0;; i++) { - if (s == 0) + if (s == NULL) break; - if ((cp = strchr(s, ',')) == 0) { + if ((cp = strchr(s, ',')) == NULL) { s1 = strdup(s); if (s1 == NULL) abort(); diff --git a/usr.sbin/fmtree/excludes.c b/usr.sbin/fmtree/excludes.c index 21a49b0..9f1c564 100644 --- a/usr.sbin/fmtree/excludes.c +++ b/usr.sbin/fmtree/excludes.c @@ -69,10 +69,10 @@ read_excludes_file(const char *name) size_t len; fp = fopen(name, "r"); - if (fp == 0) + if (fp == NULL) err(1, "%s", name); - while ((line = fgetln(fp, &len)) != 0) { + while ((line = fgetln(fp, &len)) != NULL) { if (line[len - 1] == '\n') len--; if (len == 0) @@ -80,7 +80,7 @@ read_excludes_file(const char *name) str = malloc(len + 1); e = malloc(sizeof *e); - if (str == 0 || e == 0) + if (str == NULL || e == NULL) errx(1, "memory allocation error"); e->glob = str; memcpy(str, line, len); diff --git a/usr.sbin/fstyp/fstyp.c b/usr.sbin/fstyp/fstyp.c index cde179f..803a4c8 100644 --- a/usr.sbin/fstyp/fstyp.c +++ b/usr.sbin/fstyp/fstyp.c @@ -82,7 +82,7 @@ read_buf(FILE *fp, off_t off, size_t len) } buf = malloc(len); - if (buf == 0) { + if (buf == NULL) { warn("cannot malloc %zd bytes of memory", len); return (NULL); } diff --git a/usr.sbin/keyserv/keyserv.c b/usr.sbin/keyserv/keyserv.c index 79bf90d..8acbaf6 100644 --- a/usr.sbin/keyserv/keyserv.c +++ b/usr.sbin/keyserv/keyserv.c @@ -440,7 +440,7 @@ key_net_put_2_svc_prog(uid, arg) arg->st_netname, (int)sizeof (arg->st_pub_key), arg->st_pub_key, (int)sizeof (arg->st_priv_key), arg->st_priv_key); - }; + } status = pk_netput(uid, arg); diff --git a/usr.sbin/kgmon/kgmon.c b/usr.sbin/kgmon/kgmon.c index 3bc5351..60c7507 100644 --- a/usr.sbin/kgmon/kgmon.c +++ b/usr.sbin/kgmon/kgmon.c @@ -355,7 +355,7 @@ dumpstate(struct kvmvars *kvp) setprof(kvp, GMON_PROF_OFF); fp = fopen("gmon.out", "w"); - if (fp == 0) { + if (fp == NULL) { warn("gmon.out"); return; } diff --git a/usr.sbin/lmcconfig/lmcconfig.c b/usr.sbin/lmcconfig/lmcconfig.c index 7fbc216..eb80dbe 100644 --- a/usr.sbin/lmcconfig/lmcconfig.c +++ b/usr.sbin/lmcconfig/lmcconfig.c @@ -1528,7 +1528,7 @@ print_test_pattern(int patt) case 11: printf("framed X^23+X^18+1\n"); break; - case 12:; + case 12: printf("framed X^11+X^9+1 w/7ZS\n"); break; case 13: @@ -2008,7 +2008,7 @@ load_xilinx(char *name) int c; if (verbose) printf("Load firmware from file %s...\n", name); - if ((f = fopen(name, "r")) == 0) + if ((f = fopen(name, "r")) == NULL) { perror("Failed to open file"); exit(1); diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index d6da2bc..a9464f6 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -434,7 +434,7 @@ main(int argc, char **argv) break; default: usage(); - }; + } if (modfind("nfsd") < 0) { /* Not present in kernel, try loading it */ @@ -1241,7 +1241,7 @@ xdr_fhs(XDR *xdrsp, caddr_t cp) return (0); return (xdr_long(xdrsp, &auth)); } - }; + } return (0); } @@ -2540,7 +2540,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp, int exflags, *cp = savedc; ret = 1; goto error_exit; - }; + } /* * For V4:, use the nfssvc() syscall, instead of mount(). diff --git a/usr.sbin/nfscbd/nfscbd.c b/usr.sbin/nfscbd/nfscbd.c index c9153b4..4bcfd6ea 100644 --- a/usr.sbin/nfscbd/nfscbd.c +++ b/usr.sbin/nfscbd/nfscbd.c @@ -177,7 +177,7 @@ main(int argc, char *argv[]) default: case '?': usage(); - }; + } argv += optind; argc -= optind; diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index f58ed30..349ba8e 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -214,7 +214,7 @@ main(int argc, char **argv) default: case '?': usage(); - }; + } if (!tcpflag && !udpflag) udpflag = 1; argv += optind; diff --git a/usr.sbin/pmcstudy/pmcstudy.c b/usr.sbin/pmcstudy/pmcstudy.c index 16c9f51..e94addf 100644 --- a/usr.sbin/pmcstudy/pmcstudy.c +++ b/usr.sbin/pmcstudy/pmcstudy.c @@ -2873,7 +2873,7 @@ main(int argc, char **argv) printf("-A -- Run all canned tests\n"); return(0); break; - }; + } } if ((run_all == 0) && (name == NULL) && (filename == NULL) && (test_mode == 0) && (master_exp == NULL)) { diff --git a/usr.sbin/portsnap/phttpget/phttpget.c b/usr.sbin/portsnap/phttpget/phttpget.c index 1bf6d9d..33e969a 100644 --- a/usr.sbin/portsnap/phttpget/phttpget.c +++ b/usr.sbin/portsnap/phttpget/phttpget.c @@ -598,7 +598,7 @@ main(int argc, char *argv[]) fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, 0644); if (fd == -1) errx(1, "open(%s)", fname); - }; + } /* Read the message and send data to fd if appropriate */ if (chunked) { diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c index e90d96b..d0664e8 100644 --- a/usr.sbin/ppp/command.c +++ b/usr.sbin/ppp/command.c @@ -651,7 +651,7 @@ ShellCommand(struct cmdargs const *arg, int bg) if ((shpid = fork()) == 0) { int i, fd; - if ((shell = getenv("SHELL")) == 0) + if ((shell = getenv("SHELL")) == NULL) shell = _PATH_BSHELL; timer_TermService(); diff --git a/usr.sbin/ppp/filter.c b/usr.sbin/ppp/filter.c index f59848e..af5691b 100644 --- a/usr.sbin/ppp/filter.c +++ b/usr.sbin/ppp/filter.c @@ -80,7 +80,7 @@ ParsePort(const char *service, const char *proto) int port; servent = getservbyname(service, proto); - if (servent != 0) + if (servent != NULL) return ntohs(servent->s_port); port = strtol(service, &cp, 0); diff --git a/usr.sbin/ppp/radius.c b/usr.sbin/ppp/radius.c index f798141..12b0c0f 100644 --- a/usr.sbin/ppp/radius.c +++ b/usr.sbin/ppp/radius.c @@ -1150,7 +1150,7 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl, snprintf(ac->multi_session_id, sizeof ac->multi_session_id, "%s", dl->bundle->ncp.mp.active ? dl->bundle->ncp.mp.server.socket.sun_path : ""); - }; + } if (rad_put_string(r->cx.rad, RAD_USER_NAME, ac->user_name) != 0 || rad_put_int(r->cx.rad, RAD_SERVICE_TYPE, RAD_FRAMED) != 0 || diff --git a/usr.sbin/rmt/rmt.c b/usr.sbin/rmt/rmt.c index a5c048f..57c8439 100644 --- a/usr.sbin/rmt/rmt.c +++ b/usr.sbin/rmt/rmt.c @@ -84,8 +84,10 @@ main(int argc, char **argv) argc--, argv++; if (argc > 0) { debug = fopen(*argv, "w"); - if (debug == 0) + if (debug == NULL) { + DEBUG1("rmtd: error to open %s\n", *argv); exit(1); + } (void)setbuf(debug, (char *)0); } top: @@ -226,10 +228,10 @@ checkbuf(char *rec, int size) if (size <= maxrecsize) return (rec); - if (rec != 0) + if (rec != NULL) free(rec); rec = malloc(size); - if (rec == 0) { + if (rec == NULL) { DEBUG("rmtd: cannot allocate buffer space\n"); exit(4); } diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index fc80364..e571d1f 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -344,7 +344,7 @@ read_iso3166_table(void) err(1, "%s", path_iso3166); lineno = 0; - while ((s = fgetln(fp, &len)) != 0) { + while ((s = fgetln(fp, &len)) != NULL) { lineno++; if (s[len - 1] != '\n') errx(1, "%s:%d: invalid format", path_iso3166, lineno); @@ -354,7 +354,7 @@ read_iso3166_table(void) /* Isolate the two-letter code. */ t = strsep(&s, "\t"); - if (t == 0 || strlen(t) != 2) + if (t == NULL || strlen(t) != 2) errx(1, "%s:%d: invalid format", path_iso3166, lineno); if (t[0] < 'A' || t[0] > 'Z' || t[1] < 'A' || t[1] > 'Z') errx(1, "%s:%d: invalid code `%s'", path_iso3166, @@ -362,10 +362,10 @@ read_iso3166_table(void) /* Now skip past the three-letter and numeric codes. */ name = strsep(&s, "\t"); /* 3-let */ - if (name == 0 || strlen(name) != 3) + if (name == NULL || strlen(name) != 3) errx(1, "%s:%d: invalid format", path_iso3166, lineno); name = strsep(&s, "\t"); /* numeric */ - if (name == 0 || strlen(name) != 3) + if (name == NULL || strlen(name) != 3) errx(1, "%s:%d: invalid format", path_iso3166, lineno); name = s; @@ -407,7 +407,7 @@ add_zone_to_country(int lineno, const char *tlc, const char *descr, path_zonetab, lineno); zp = malloc(sizeof(*zp)); - if (zp == 0) + if (zp == NULL) errx(1, "malloc(%zu)", sizeof(*zp)); if (cp->nzones == 0) @@ -483,7 +483,7 @@ read_zones(void) err(1, "%s", path_zonetab); lineno = 0; - while ((line = fgetln(fp, &len)) != 0) { + while ((line = fgetln(fp, &len)) != NULL) { lineno++; if (line[len - 1] != '\n') errx(1, "%s:%d: invalid format", path_zonetab, lineno); @@ -498,7 +498,7 @@ read_zones(void) /* coord = */ strsep(&line, "\t"); /* Unused */ file = strsep(&line, "\t"); p = strchr(file, '/'); - if (p == 0) + if (p == NULL) errx(1, "%s:%d: invalid zone name `%s'", path_zonetab, lineno, file); contbuf[0] = '\0'; @@ -558,7 +558,7 @@ make_menus(void) continent_names[i].continent->menu = malloc(sizeof(dialogMenuItem) * continent_names[i].continent->nitems); - if (continent_names[i].continent->menu == 0) + if (continent_names[i].continent->menu == NULL) errx(1, "malloc for continent menu"); continent_names[i].continent->nitems = 0; continents[i].prompt = continent_items[i].prompt; |