Date: Fri, 26 Jul 2013 15:21:48 GMT From: Brooks Davis <brooks@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 231484 for review Message-ID: <201307261521.r6QFLmA5020171@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@231484?ac=10 Change 231484 by brooks@brooks_zenith on 2013/07/26 15:21:04 Simplify timeout code by switching from struct bintime to sbintime_t. ~1/4ns resolution is more than sufficent for storage device timeouts. Add a missing timeout check when starting a multi-word write. Affected files ... .. //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_core.c#15 edit .. //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_var.h#7 edit Differences ... ==== //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_core.c#15 (text+ko) ==== @@ -260,9 +260,8 @@ cfi_attach(device_t dev) { struct cfi_softc *sc; - struct timeval tv; u_int blksz, blocks; - u_int r, u, usec; + u_int r, u; #ifdef CFI_SUPPORT_STRATAFLASH uint64_t ppr; char name[KENV_MNAMELEN], value[32]; @@ -281,38 +280,26 @@ sc->sc_handle = rman_get_bushandle(sc->sc_res); /* Get time-out values for erase, write, and buffer write. */ - bintime_clear(&sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE]); - usec = 1000 * (1 << cfi_read_qry(sc, CFI_QRY_TTO_ERASE)); - tv.tv_sec = usec / 1000000; - tv.tv_usec = usec % 1000000; - timeval2bintime(&tv, &sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE]); + sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] = + SBT_1MS * (1 << cfi_read_qry(sc, CFI_QRY_TTO_ERASE)); sc->sc_max_timeouts[CFI_TIMEOUT_ERASE] = - sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE]; - bintime_mul(&sc->sc_max_timeouts[CFI_TIMEOUT_ERASE], - 1 << cfi_read_qry(sc, CFI_QRY_MTO_ERASE)); + sc->sc_typical_timeouts[CFI_TIMEOUT_ERASE] * + (1 << cfi_read_qry(sc, CFI_QRY_MTO_ERASE)); - bintime_clear(&sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE]); - usec = 1 << cfi_read_qry(sc, CFI_QRY_TTO_WRITE); - tv.tv_sec = usec / 1000000; - tv.tv_usec = usec % 1000000; - timeval2bintime(&tv, &sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE]); + sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] = + SBT_1US * (1 << cfi_read_qry(sc, CFI_QRY_TTO_WRITE)); sc->sc_max_timeouts[CFI_TIMEOUT_WRITE] = - sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE]; - bintime_mul(&sc->sc_max_timeouts[CFI_TIMEOUT_WRITE], - 1 << cfi_read_qry(sc, CFI_QRY_MTO_WRITE)); + sc->sc_typical_timeouts[CFI_TIMEOUT_WRITE] * + (1 << cfi_read_qry(sc, CFI_QRY_MTO_WRITE)); - bintime_clear(&sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE]); - usec = 1 << cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE); - tv.tv_sec = usec / 1000000; - tv.tv_usec = usec % 1000000; - timeval2bintime(&tv, &sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE]); + sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] = + SBT_1US * (1 << cfi_read_qry(sc, CFI_QRY_TTO_BUFWRITE)); sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE] = - sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE]; - bintime_mul(&sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE], - 1 << cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE)); + sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] * + (1 << cfi_read_qry(sc, CFI_QRY_MTO_BUFWRITE)); /* Get the maximum size of a multibyte program */ - if (bintime_isset(&sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE])) + if (sc->sc_typical_timeouts[CFI_TIMEOUT_BUFWRITE] != 0) sc->sc_maxbuf = 1 << (cfi_read_qry(sc, CFI_QRY_MAXBUF) | cfi_read_qry(sc, CFI_QRY_MAXBUF) << 8); else @@ -384,16 +371,15 @@ } static int -cfi_wait_ready(struct cfi_softc *sc, u_int ofs, struct bintime *start, +cfi_wait_ready(struct cfi_softc *sc, u_int ofs, sbintime_t start, enum cfi_wait_cmd cmd) { int done, error, tto_exceeded; uint32_t st0 = 0, st = 0; - struct bintime mend, now, tend; + sbintime_t mend, now, tend; - tend = mend = *start; - bintime_add(&tend, &sc->sc_typical_timeouts[cmd]); - bintime_add(&mend, &sc->sc_max_timeouts[cmd]); + tend = start + sc->sc_typical_timeouts[cmd]; + mend = start + sc->sc_max_timeouts[cmd]; done = 0; error = 0; @@ -427,11 +413,11 @@ break; } - binuptime(&now); - if (tto_exceeded || bintime_cmp(&now, &tend, >)) { + now = sbinuptime(); + if (tto_exceeded || now > tend) { if (!tto_exceeded) tto_exceeded = 1; - if (bintime_cmp(&now, &mend, >)) { + if (now > mend) { #ifdef CFI_DEBUG_TIMEOUT device_printf(sc->sc_dev, "max timeout exceeded (cmd %d)", cmd); @@ -464,7 +450,7 @@ int error, i, neederase = 0; uint32_t st; u_int wlen; - struct bintime start; + sbintime_t start; /* Intel flash must be unlocked before modification */ switch (sc->sc_cmdset) { @@ -494,7 +480,7 @@ if (neederase) { intr = intr_disable(); - binuptime(&start); + start = sbinuptime(); /* Erase the block. */ switch (sc->sc_cmdset) { case CFI_VEND_INTEL_ECS: @@ -514,7 +500,7 @@ return (ENODEV); } intr_restore(intr); - error = cfi_wait_ready(sc, sc->sc_wrofs, &start, + error = cfi_wait_ready(sc, sc->sc_wrofs, start, CFI_TIMEOUT_ERASE); if (error) goto out; @@ -533,11 +519,14 @@ intr = intr_disable(); - binuptime(&start); + start = sbinuptime(); do { cfi_write(sc, sc->sc_wrofs + i, CFI_BCS_BUF_PROG_SETUP); - /* XXX: do some timeout management */ + if (sbinuptime() > start + sc->sc_max_timeouts[CFI_TIMEOUT_BUFWRITE]) { + error = ETIMEDOUT; + goto out; + } st = cfi_read(sc, sc->sc_wrofs + i); } while (! (st & CFI_INTEL_STATUS_WSMS)); @@ -567,7 +556,9 @@ intr_restore(intr); error = cfi_wait_ready(sc, sc->sc_wrofs + i, - &start, CFI_TIMEOUT_BUFWRITE); + start, CFI_TIMEOUT_BUFWRITE); + if (error != 0) + goto out; } goto out; default: @@ -605,7 +596,7 @@ */ intr = intr_disable(); - binuptime(&start); + start = sbinuptime(); switch (sc->sc_cmdset) { case CFI_VEND_INTEL_ECS: case CFI_VEND_INTEL_SCS: @@ -633,7 +624,7 @@ intr_restore(intr); - error = cfi_wait_ready(sc, sc->sc_wrofs, &start, + error = cfi_wait_ready(sc, sc->sc_wrofs, start, CFI_TIMEOUT_WRITE); if (error) goto out; @@ -732,7 +723,7 @@ #ifdef CFI_ARMEDANDDANGEROUS register_t intr; int i, error; - struct bintime start; + sbintime_t start; #endif if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) @@ -742,11 +733,11 @@ #ifdef CFI_ARMEDANDDANGEROUS for (i = 7; i >= 4; i--, id >>= 16) { intr = intr_disable(); - binuptime(&start); + start = sbinuptime(); cfi_write(sc, 0, CFI_INTEL_PP_SETUP); cfi_put16(sc, CFI_INTEL_PR(i), id&0xffff); intr_restore(intr); - error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, &start, + error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, CFI_TIMEOUT_WRITE); if (error) break; @@ -787,7 +778,7 @@ #ifdef CFI_ARMEDANDDANGEROUS register_t intr; int error; - struct bintime start; + sbintime_t start; #endif if (sc->sc_cmdset != CFI_VEND_INTEL_ECS) return EOPNOTSUPP; @@ -801,7 +792,7 @@ cfi_write(sc, 0, CFI_INTEL_PP_SETUP); cfi_put16(sc, CFI_INTEL_PLR, 0xFFFD); intr_restore(intr); - error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, &start, + error = cfi_wait_ready(sc, CFI_BCS_READ_STATUS, start, CFI_TIMEOUT_WRITE); cfi_write(sc, 0, CFI_BCS_READ_ARRAY); return error; ==== //depot/projects/ctsrd/beribsd/src/sys/dev/cfi/cfi_var.h#7 (text+ko) ==== @@ -57,8 +57,8 @@ struct cfi_region *sc_region; /* Array of region info. */ u_int sc_cmdset; - struct bintime sc_typical_timeouts[3]; - struct bintime sc_max_timeouts[3]; + sbintime_t sc_typical_timeouts[3]; + sbintime_t sc_max_timeouts[3]; u_int sc_maxbuf;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307261521.r6QFLmA5020171>