Home | History | Annotate | Line # | Download | only in ic
tpm.c revision 1.5
      1 /*	$NetBSD: tpm.c,v 1.5 2012/02/03 04:03:11 christos Exp $	*/
      2 /*
      3  * Copyright (c) 2008, 2009 Michael Shalayeff
      4  * Copyright (c) 2009, 2010 Hans-Jrg Hxer
      5  * All rights reserved.
      6  *
      7  * Permission to use, copy, modify, and distribute this software for any
      8  * purpose with or without fee is hereby granted, provided that the above
      9  * copyright notice and this permission notice appear in all copies.
     10  *
     11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
     16  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
     17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18  */
     19 
     20 #include <sys/cdefs.h>
     21 __KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.5 2012/02/03 04:03:11 christos Exp $");
     22 
     23 #if 1
     24 #define	TPM_DEBUG
     25 #define aprint_debug_dev aprint_error_dev
     26 #endif
     27 
     28 #include <sys/param.h>
     29 #include <sys/systm.h>
     30 #include <sys/kernel.h>
     31 #include <sys/malloc.h>
     32 #include <sys/proc.h>
     33 #include <sys/device.h>
     34 #include <sys/conf.h>
     35 #include <sys/bus.h>
     36 #include <sys/pmf.h>
     37 
     38 #include <dev/ic/tpmreg.h>
     39 #include <dev/ic/tpmvar.h>
     40 
     41 /* Set when enabling legacy interface in host bridge. */
     42 int tpm_enabled;
     43 
     44 const struct {
     45 	uint32_t devid;
     46 	char name[32];
     47 	int flags;
     48 #define TPM_DEV_NOINTS	0x0001
     49 } tpm_devs[] = {
     50 	{ 0x000615d1, "IFX SLD 9630 TT 1.1", 0 },
     51 	{ 0x000b15d1, "IFX SLB 9635 TT 1.2", 0 },
     52 	{ 0x100214e4, "Broadcom BCM0102", TPM_DEV_NOINTS },
     53 	{ 0x00fe1050, "WEC WPCT200", 0 },
     54 	{ 0x687119fa, "SNS SSX35", 0 },
     55 	{ 0x2e4d5453, "STM ST19WP18", 0 },
     56 	{ 0x32021114, "ATML 97SC3203", TPM_DEV_NOINTS },
     57 	{ 0x10408086, "INTEL INTC0102", 0 },
     58 	{ 0, "", TPM_DEV_NOINTS },
     59 };
     60 
     61 int tpm_tis12_irqinit(struct tpm_softc *, int, int);
     62 
     63 int tpm_waitfor_poll(struct tpm_softc *, uint8_t, int, void *);
     64 int tpm_waitfor_int(struct tpm_softc *, uint8_t, int, void *, int);
     65 int tpm_waitfor(struct tpm_softc *, uint8_t, int, void *);
     66 int tpm_request_locality(struct tpm_softc *, int);
     67 int tpm_getburst(struct tpm_softc *);
     68 uint8_t tpm_status(struct tpm_softc *);
     69 int tpm_tmotohz(int);
     70 
     71 static dev_type_open(tpmopen);
     72 static dev_type_close(tpmclose);
     73 static dev_type_read(tpmread);
     74 static dev_type_read(tpmwrite);
     75 static dev_type_ioctl(tpmioctl);
     76 
     77 extern struct cfdriver	tpm_cd;
     78 #define TPMUNIT(a)	minor(a)
     79 
     80 const struct cdevsw tpm_cdevsw = {
     81 	tpmopen, tpmclose, tpmread, tpmwrite, tpmioctl,
     82 	nostop, notty, nopoll, nommap, nokqfilter, D_OTHER,
     83 };
     84 
     85 /* Probe TPM using TIS 1.2 interface. */
     86 int
     87 tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh)
     88 {
     89 	uint32_t r;
     90 	uint8_t save, reg;
     91 
     92 	r = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITIES);
     93 	if (r == 0xffffffff)
     94 		return 0;
     95 
     96 #ifdef TPM_DEBUG
     97 	char buf[128];
     98 	snprintb(buf, sizeof(buf), TPM_CAPBITS, r);
     99 	printf("%s: caps=%s\n", __func__, buf);
    100 #endif
    101 	if ((r & TPM_CAPSREQ) != TPM_CAPSREQ ||
    102 	    !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) {
    103 #ifdef TPM_DEBUG
    104 		printf("%s: caps too low (caps=%s)\n", __func__, buf);
    105 #endif
    106 		return 0;
    107 	}
    108 
    109 	save = bus_space_read_1(bt, bh, TPM_ACCESS);
    110 	bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE);
    111 	reg = bus_space_read_1(bt, bh, TPM_ACCESS);
    112 	if ((reg & TPM_ACCESS_VALID) && (reg & TPM_ACCESS_ACTIVE_LOCALITY) &&
    113 	    bus_space_read_4(bt, bh, TPM_ID) != 0xffffffff)
    114 		return 1;
    115 
    116 	bus_space_write_1(bt, bh, TPM_ACCESS, save);
    117 	return 0;
    118 }
    119 
    120 /*
    121  * Setup interrupt vector if one is provided and interrupts are know to
    122  * work on that particular chip.
    123  */
    124 int
    125 tpm_tis12_irqinit(struct tpm_softc *sc, int irq, int idx)
    126 {
    127 	uint32_t r;
    128 
    129 	if ((irq == -1) || (tpm_devs[idx].flags & TPM_DEV_NOINTS)) {
    130 		sc->sc_vector = -1;
    131 		return 0;
    132 	}
    133 
    134 	/* Ack and disable all interrupts. */
    135 	r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE);
    136 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
    137 	    r & ~TPM_GLOBAL_INT_ENABLE);
    138 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS,
    139 	    bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS));
    140 #ifdef TPM_DEBUG
    141 	char buf[128];
    142 	snprintb(buf, sizeof(buf), TPM_INTERRUPT_ENABLE_BITS, r);
    143 	aprint_debug_dev(sc->sc_dev, "%s: before ien %s\n", __func__, buf);
    144 #endif
    145 
    146 	/* Program interrupt vector. */
    147 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_INT_VECTOR, irq);
    148 	sc->sc_vector = irq;
    149 
    150 	/* Program interrupt type. */
    151 	r &= ~(TPM_INT_EDGE_RISING|TPM_INT_EDGE_FALLING|TPM_INT_LEVEL_HIGH|
    152 	    TPM_INT_LEVEL_LOW);
    153 	r |= TPM_GLOBAL_INT_ENABLE|TPM_CMD_READY_INT|TPM_LOCALITY_CHANGE_INT|
    154 	    TPM_STS_VALID_INT|TPM_DATA_AVAIL_INT;
    155 	if (sc->sc_capabilities & TPM_INTF_INT_EDGE_RISING)
    156 		r |= TPM_INT_EDGE_RISING;
    157 	else if (sc->sc_capabilities & TPM_INTF_INT_EDGE_FALLING)
    158 		r |= TPM_INT_EDGE_FALLING;
    159 	else if (sc->sc_capabilities & TPM_INTF_INT_LEVEL_HIGH)
    160 		r |= TPM_INT_LEVEL_HIGH;
    161 	else
    162 		r |= TPM_INT_LEVEL_LOW;
    163 
    164 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, r);
    165 #ifdef TPM_DEBUG
    166 	snprintb(buf, sizeof(buf), TPM_INTERRUPT_ENABLE_BITS, r);
    167 	aprint_debug_dev(sc->sc_dev, "%s: after ien %s\n", __func__, buf);
    168 #endif
    169 
    170 	return 0;
    171 }
    172 
    173 /* Setup TPM using TIS 1.2 interface. */
    174 int
    175 tpm_tis12_init(struct tpm_softc *sc, int irq, const char *name)
    176 {
    177 	uint32_t r;
    178 	int i;
    179 
    180 	r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTF_CAPABILITIES);
    181 #ifdef TPM_DEBUG
    182 	char cbuf[128];
    183 	snprintb(cbuf, sizeof(cbuf), TPM_CAPBITS, r);
    184 	aprint_debug_dev(sc->sc_dev, "%s: caps=%s ", __func__, cbuf);
    185 #endif
    186 	if ((r & TPM_CAPSREQ) != TPM_CAPSREQ ||
    187 	    !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) {
    188 		char buf[128];
    189 		snprintb(buf, sizeof(buf), TPM_CAPBITS, r);
    190 		aprint_error_dev(sc->sc_dev, "capabilities too low (caps=%s)\n",
    191 		    buf);
    192 		return 1;
    193 	}
    194 	sc->sc_capabilities = r;
    195 
    196 	sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID);
    197 	sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV);
    198 
    199 	for (i = 0; tpm_devs[i].devid; i++)
    200 		if (tpm_devs[i].devid == sc->sc_devid)
    201 			break;
    202 
    203 	if (tpm_devs[i].devid)
    204 		aprint_normal(": %s rev 0x%x\n",
    205 		    tpm_devs[i].name, sc->sc_rev);
    206 	else
    207 		aprint_normal(": device 0x%08x rev 0x%x\n",
    208 		    sc->sc_devid, sc->sc_rev);
    209 
    210 	if (tpm_tis12_irqinit(sc, irq, i))
    211 		return 1;
    212 
    213 	if (tpm_request_locality(sc, 0))
    214 		return 1;
    215 
    216 	/* Abort whatever it thought it was doing. */
    217 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
    218 
    219 	return 0;
    220 }
    221 
    222 int
    223 tpm_request_locality(struct tpm_softc *sc, int l)
    224 {
    225 	uint32_t r;
    226 	int to, rv;
    227 
    228 	if (l != 0)
    229 		return EINVAL;
    230 
    231 	if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
    232 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) ==
    233 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
    234 		return 0;
    235 
    236 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
    237 	    TPM_ACCESS_REQUEST_USE);
    238 
    239 	to = tpm_tmotohz(TPM_ACCESS_TMO);
    240 
    241 	while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
    242 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
    243 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) {
    244 		rv = tsleep(sc->sc_init, PRIBIO | PCATCH, "tpm_locality", 1);
    245 		if (rv &&  rv != EWOULDBLOCK) {
    246 #ifdef TPM_DEBUG
    247 			aprint_debug_dev(sc->sc_dev, "%s: interrupted %d\n",
    248 			    __func__, rv);
    249 #endif
    250 			return rv;
    251 		}
    252 	}
    253 
    254 	if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
    255 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
    256 #ifdef TPM_DEBUG
    257 		char buf[128];
    258 		snprintb(buf, sizeof(buf), TPM_ACCESS_BITS, r);
    259 		aprint_debug_dev(sc->sc_dev, "%s: access %s\n", __func__, buf);
    260 #endif
    261 		return EBUSY;
    262 	}
    263 
    264 	return 0;
    265 }
    266 
    267 int
    268 tpm_getburst(struct tpm_softc *sc)
    269 {
    270 	int burst, to, rv;
    271 
    272 	to = tpm_tmotohz(TPM_BURST_TMO);
    273 
    274 	burst = 0;
    275 	while (burst == 0 && to--) {
    276 		/*
    277 		 * Burst count has to be read from bits 8 to 23 without
    278 		 * touching any other bits, eg. the actual status bits 0
    279 		 * to 7.
    280 		 */
    281 		burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1);
    282 		burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2)
    283 		    << 8;
    284 #ifdef TPM_DEBUG
    285 		aprint_debug_dev(sc->sc_dev, "%s: read %d\n", __func__, burst);
    286 #endif
    287 		if (burst)
    288 			return burst;
    289 
    290 		rv = tsleep(sc, PRIBIO | PCATCH, "tpm_getburst", 1);
    291 		if (rv && rv != EWOULDBLOCK) {
    292 			return 0;
    293 		}
    294 	}
    295 
    296 	return 0;
    297 }
    298 
    299 uint8_t
    300 tpm_status(struct tpm_softc *sc)
    301 {
    302 	return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & TPM_STS_MASK;
    303 }
    304 
    305 int
    306 tpm_tmotohz(int tmo)
    307 {
    308 	struct timeval tv;
    309 
    310 	tv.tv_sec = tmo / 1000;
    311 	tv.tv_usec = 1000 * (tmo % 1000);
    312 
    313 	return tvtohz(&tv);
    314 }
    315 
    316 /* Save TPM state on suspend. */
    317 bool
    318 tpm_suspend(device_t dev, const pmf_qual_t *qual)
    319 {
    320 	struct tpm_softc *sc = device_private(dev);
    321 	static const uint8_t command[] = {
    322 	    0, 193,		/* TPM_TAG_RQU_COMMAND */
    323 	    0, 0, 0, 10,	/* Length in bytes */
    324 	    0, 0, 0, 156	/* TPM_ORD_SaveStates */
    325 	};
    326 	uint8_t scratch[sizeof(command)];
    327 
    328 	/*
    329 	 * Power down:  We have to issue the SaveStates command.
    330 	 */
    331 	(*sc->sc_write)(sc, &command, sizeof(command));
    332 	(*sc->sc_read)(sc, &scratch, sizeof(scratch), NULL, TPM_HDRSIZE);
    333 #ifdef TPM_DEBUG
    334 	aprint_debug_dev(sc->sc_dev, "%s: power down\n", __func__);
    335 #endif
    336 	return 0;
    337 }
    338 
    339 /*
    340  * Handle resume event.  Actually nothing to do as the BIOS is supposed
    341  * to restore the previously saved state.
    342  */
    343 bool
    344 tpm_resume(device_t dev, const pmf_qual_t *qual)
    345 {
    346 #ifdef TPM_DEBUG
    347 	struct tpm_softc *sc = device_private(dev);
    348 	aprint_debug_dev(sc->sc_dev, "%s: resume\n", __func__);
    349 #endif
    350 	return 0;
    351 }
    352 
    353 /* Wait for given status bits using polling. */
    354 int
    355 tpm_waitfor_poll(struct tpm_softc *sc, uint8_t mask, int tmo, void *c)
    356 {
    357 	int rv;
    358 
    359 	/*
    360 	 * Poll until either the requested condition or a time out is
    361 	 * met.
    362 	 */
    363 	while (((sc->sc_stat = tpm_status(sc)) & mask) != mask && tmo--) {
    364 		rv = tsleep(c, PRIBIO | PCATCH, "tpm_poll", 1);
    365 		if (rv && rv != EWOULDBLOCK) {
    366 #ifdef TPM_DEBUG
    367 			aprint_debug_dev(sc->sc_dev,
    368 			    "%s: interrupted %d\n", __func__, rv);
    369 #endif
    370 			return rv;
    371 		}
    372 	}
    373 
    374 	return 0;
    375 }
    376 
    377 /* Wait for given status bits using interrupts. */
    378 int
    379 tpm_waitfor_int(struct tpm_softc *sc, uint8_t mask, int tmo, void *c,
    380     int inttype)
    381 {
    382 	int rv, to;
    383 
    384 	/* Poll and return when condition is already met. */
    385 	sc->sc_stat = tpm_status(sc);
    386 	if ((sc->sc_stat & mask) == mask)
    387 		return 0;
    388 
    389 	/*
    390 	 * Enable interrupt on tpm chip.  Note that interrupts on our
    391 	 * level (SPL_TTY) are disabled (see tpm{read,write} et al) and
    392 	 * will not be delivered to the cpu until we call tsleep(9) below.
    393 	 */
    394 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
    395 	    bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) |
    396 	    inttype);
    397 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
    398 	    bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) |
    399 	    TPM_GLOBAL_INT_ENABLE);
    400 
    401 	/*
    402 	 * Poll once more to remedy the race between previous polling
    403 	 * and enabling interrupts on the tpm chip.
    404 	 */
    405 	sc->sc_stat = tpm_status(sc);
    406 	if ((sc->sc_stat & mask) == mask) {
    407 		rv = 0;
    408 		goto out;
    409 	}
    410 
    411 	to = tpm_tmotohz(tmo);
    412 #ifdef TPM_DEBUG
    413 	aprint_debug_dev(sc->sc_dev,
    414 	    "%s: sleeping for %d ticks on %p\n", __func__, to, c);
    415 #endif
    416 	/*
    417 	 * tsleep(9) enables interrupts on the cpu and returns after
    418 	 * wake up with interrupts disabled again.  Note that interrupts
    419 	 * generated by the tpm chip while being at SPL_TTY are not lost
    420 	 * but held and delivered as soon as the cpu goes below SPL_TTY.
    421 	 */
    422 	rv = tsleep(c, PRIBIO | PCATCH, "tpm_wait", to);
    423 
    424 	sc->sc_stat = tpm_status(sc);
    425 #ifdef TPM_DEBUG
    426 	char buf[128];
    427 	snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
    428 	aprint_debug_dev(sc->sc_dev,
    429 	    "%s: woke up with rv %d stat %s\n", __func__, rv, buf);
    430 #endif
    431 	if ((sc->sc_stat & mask) == mask)
    432 		rv = 0;
    433 
    434 	/* Disable interrupts on tpm chip again. */
    435 out:	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
    436 	    bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) &
    437 	    ~TPM_GLOBAL_INT_ENABLE);
    438 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE,
    439 	    bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE) &
    440 	    ~inttype);
    441 
    442 	return rv;
    443 }
    444 
    445 /*
    446  * Wait on given status bits, uses interrupts where possible, otherwise polls.
    447  */
    448 int
    449 tpm_waitfor(struct tpm_softc *sc, uint8_t b0, int tmo, void *c)
    450 {
    451 	uint8_t b;
    452 	int re, to, rv;
    453 
    454 #ifdef TPM_DEBUG
    455 	char buf[128];
    456 	snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
    457 	aprint_debug_dev(sc->sc_dev, "%s: b0 %s\n", __func__, buf);
    458 #endif
    459 
    460 	/*
    461 	 * If possible, use interrupts, otherwise poll.
    462 	 *
    463 	 * We use interrupts for TPM_STS_VALID and TPM_STS_DATA_AVAIL (if
    464 	 * the tpm chips supports them) as waiting for those can take
    465 	 * really long.  The other TPM_STS* are not needed very often
    466 	 * so we do not support them.
    467 	 */
    468 	if (sc->sc_vector != -1) {
    469 		b = b0;
    470 
    471 		/*
    472 		 * Wait for data ready.  This interrupt only occures
    473 		 * when both TPM_STS_VALID and TPM_STS_DATA_AVAIL are asserted.
    474 		 * Thus we don't have to bother with TPM_STS_VALID
    475 		 * separately and can just return.
    476 		 *
    477 		 * This only holds for interrupts!  When using polling
    478 		 * both flags have to be waited for, see below.
    479 		 */
    480 		if ((b & TPM_STS_DATA_AVAIL) && (sc->sc_capabilities &
    481 		    TPM_INTF_DATA_AVAIL_INT))
    482 			return tpm_waitfor_int(sc, b, tmo, c,
    483 			    TPM_DATA_AVAIL_INT);
    484 
    485 		/* Wait for status valid bit. */
    486 		if ((b & TPM_STS_VALID) && (sc->sc_capabilities &
    487 		    TPM_INTF_STS_VALID_INT)) {
    488 			rv = tpm_waitfor_int(sc, b, tmo, c, TPM_STS_VALID_INT);
    489 			if (rv != 0)
    490 				return rv;
    491 			else
    492 				b = b0 & ~TPM_STS_VALID;
    493 		}
    494 
    495 		/*
    496 		 * When all flags are taken care of, return.  Otherwise
    497 		 * use polling for eg. TPM_STS_CMD_READY.
    498 		 */
    499 		if (b == 0)
    500 			return 0;
    501 	}
    502 
    503 	re = 3;
    504 restart:
    505 	/*
    506 	 * If requested wait for TPM_STS_VALID before dealing with
    507 	 * any other flag.  Eg. when both TPM_STS_DATA_AVAIL and TPM_STS_VALID
    508 	 * are requested, wait for the latter first.
    509 	 */
    510 	b = b0;
    511 	if (b0 & TPM_STS_VALID)
    512 		b = TPM_STS_VALID;
    513 
    514 	to = tpm_tmotohz(tmo);
    515 again:
    516 	if ((rv = tpm_waitfor_poll(sc, b, to, c)) != 0)
    517 		return rv;
    518 
    519 	if ((b & sc->sc_stat) == TPM_STS_VALID) {
    520 		/* Now wait for other flags. */
    521 		b = b0 & ~TPM_STS_VALID;
    522 		to++;
    523 		goto again;
    524 	}
    525 
    526 	if ((sc->sc_stat & b) != b) {
    527 #ifdef TPM_DEBUG
    528 		char bbuf[128], cbuf[128];
    529 		snprintb(bbuf, sizeof(bbuf), TPM_STS_BITS, b);
    530 		snprintb(cbuf, sizeof(cbuf), TPM_STS_BITS, sc->sc_stat);
    531 		aprint_debug_dev(sc->sc_dev,
    532 		    "%s: timeout: stat=%s b=%s\n", __func__, cbuf, bbuf);
    533 #endif
    534 		if (re-- && (b0 & TPM_STS_VALID)) {
    535 			bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
    536 			    TPM_STS_RESP_RETRY);
    537 			goto restart;
    538 		}
    539 		return EIO;
    540 	}
    541 
    542 	return 0;
    543 }
    544 
    545 /* Start transaction. */
    546 int
    547 tpm_tis12_start(struct tpm_softc *sc, int flag)
    548 {
    549 	int rv;
    550 
    551 	if (flag == UIO_READ) {
    552 		rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
    553 		    TPM_READ_TMO, sc->sc_read);
    554 		return rv;
    555 	}
    556 
    557 	/* Own our (0th) locality. */
    558 	if ((rv = tpm_request_locality(sc, 0)) != 0)
    559 		return rv;
    560 
    561 	sc->sc_stat = tpm_status(sc);
    562 	if (sc->sc_stat & TPM_STS_CMD_READY) {
    563 #ifdef TPM_DEBUG
    564 		char buf[128];
    565 		snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
    566 		aprint_debug_dev(sc->sc_dev, "%s: UIO_WRITE status %s\n",
    567 		    __func__, buf);
    568 #endif
    569 		return 0;
    570 	}
    571 
    572 #ifdef TPM_DEBUG
    573 	aprint_debug_dev(sc->sc_dev,
    574 	    "%s: UIO_WRITE readying chip\n", __func__);
    575 #endif
    576 
    577 	/* Abort previous and restart. */
    578 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
    579 	if ((rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO,
    580 	    sc->sc_write))) {
    581 #ifdef TPM_DEBUG
    582 		aprint_debug_dev(sc->sc_dev,
    583 		    "%s: UIO_WRITE readying failed %d\n", __func__, rv);
    584 #endif
    585 		return rv;
    586 	}
    587 
    588 #ifdef TPM_DEBUG
    589 	aprint_debug_dev(sc->sc_dev,
    590 	    "%s: UIO_WRITE readying done\n", __func__);
    591 #endif
    592 
    593 	return 0;
    594 }
    595 
    596 int
    597 tpm_tis12_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count,
    598     int flags)
    599 {
    600 	uint8_t *p = buf;
    601 	size_t cnt;
    602 	int rv, n, bcnt;
    603 
    604 #ifdef TPM_DEBUG
    605 	aprint_debug_dev(sc->sc_dev, "%s: len %zu\n", __func__, len);
    606 #endif
    607 	cnt = 0;
    608 	while (len > 0) {
    609 		if ((rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
    610 		    TPM_READ_TMO, sc->sc_read)))
    611 			return rv;
    612 
    613 		bcnt = tpm_getburst(sc);
    614 		n = MIN(len, bcnt);
    615 #ifdef TPM_DEBUG
    616 		aprint_debug_dev(sc->sc_dev,
    617 		    "%s: fetching %d, burst is %d\n", __func__, n, bcnt);
    618 #endif
    619 		for (; n--; len--) {
    620 			*p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA);
    621 			cnt++;
    622 		}
    623 
    624 		if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6)
    625 			break;
    626 	}
    627 #ifdef TPM_DEBUG
    628 	aprint_debug_dev(sc->sc_dev,
    629 	    "%s: read %zu bytes, len %zu\n", __func__, cnt, len);
    630 #endif
    631 
    632 	if (count)
    633 		*count = cnt;
    634 
    635 	return 0;
    636 }
    637 
    638 int
    639 tpm_tis12_write(struct tpm_softc *sc, const void *buf, size_t len)
    640 {
    641 	const uint8_t *p = buf;
    642 	size_t cnt;
    643 	int rv, r;
    644 
    645 #ifdef TPM_DEBUG
    646 	aprint_debug_dev(sc->sc_dev,
    647 	    "%s: sc %p buf %p len %zu\n", __func__, sc, buf, len);
    648 #endif
    649 	if (len == 0)
    650 		return 0;
    651 
    652 	if ((rv = tpm_request_locality(sc, 0)) != 0)
    653 		return rv;
    654 
    655 	cnt = 0;
    656 	while (cnt < len - 1) {
    657 		for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) {
    658 			bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
    659 			cnt++;
    660 		}
    661 		if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
    662 #ifdef TPM_DEBUG
    663 			aprint_debug_dev(sc->sc_dev,
    664 			    "%s: failed burst rv %d\n", __func__, rv);
    665 #endif
    666 			return rv;
    667 		}
    668 		sc->sc_stat = tpm_status(sc);
    669 		if (!(sc->sc_stat & TPM_STS_DATA_EXPECT)) {
    670 #ifdef TPM_DEBUG
    671 			char sbuf[128];
    672 			snprintb(sbuf, sizeof(sbuf), TPM_STS_BITS, sc->sc_stat);
    673 			aprint_debug_dev(sc->sc_dev,
    674 			    "%s: failed rv %d stat=%s\n", __func__, rv, sbuf);
    675 #endif
    676 			return EIO;
    677 		}
    678 	}
    679 
    680 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
    681 	cnt++;
    682 
    683 	if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
    684 #ifdef TPM_DEBUG
    685 		aprint_debug_dev(sc->sc_dev, "%s: failed last byte rv %d\n",
    686 		    __func__, rv);
    687 #endif
    688 		return rv;
    689 	}
    690 	if ((sc->sc_stat & TPM_STS_DATA_EXPECT) != 0) {
    691 #ifdef TPM_DEBUG
    692 		char sbuf[128];
    693 		snprintb(sbuf, sizeof(sbuf), TPM_STS_BITS, sc->sc_stat);
    694 		aprint_debug_dev(sc->sc_dev,
    695 		    "%s: failed rv %d stat=%s\n", __func__, rv, sbuf);
    696 #endif
    697 		return EIO;
    698 	}
    699 
    700 #ifdef TPM_DEBUG
    701 	aprint_debug_dev(sc->sc_dev, "%s: wrote %zu byte\n", __func__, cnt);
    702 #endif
    703 
    704 	return 0;
    705 }
    706 
    707 /* Finish transaction. */
    708 int
    709 tpm_tis12_end(struct tpm_softc *sc, int flag, int err)
    710 {
    711 	int rv = 0;
    712 
    713 	if (flag == UIO_READ) {
    714 		if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO,
    715 		    sc->sc_read)))
    716 			return rv;
    717 
    718 		/* Still more data? */
    719 		sc->sc_stat = tpm_status(sc);
    720 		if (!err && ((sc->sc_stat & TPM_STS_DATA_AVAIL)
    721 		    == TPM_STS_DATA_AVAIL)) {
    722 #ifdef TPM_DEBUG
    723 			char buf[128];
    724 			snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
    725 			aprint_debug_dev(sc->sc_dev,
    726 			    "%s: read failed stat=%s\n", __func__, buf);
    727 #endif
    728 			rv = EIO;
    729 		}
    730 
    731 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
    732 		    TPM_STS_CMD_READY);
    733 
    734 		/* Release our (0th) locality. */
    735 		bus_space_write_1(sc->sc_bt, sc->sc_bh,TPM_ACCESS,
    736 		    TPM_ACCESS_ACTIVE_LOCALITY);
    737 	} else {
    738 		/* Hungry for more? */
    739 		sc->sc_stat = tpm_status(sc);
    740 		if (!err && (sc->sc_stat & TPM_STS_DATA_EXPECT)) {
    741 #ifdef TPM_DEBUG
    742 			char buf[128];
    743 			snprintb(buf, sizeof(buf), TPM_STS_BITS, sc->sc_stat);
    744 			aprint_debug_dev(sc->sc_dev,
    745 			    "%s: write failed stat=%s\n", __func__, buf);
    746 #endif
    747 			rv = EIO;
    748 		}
    749 
    750 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
    751 		    err ? TPM_STS_CMD_READY : TPM_STS_GO);
    752 	}
    753 
    754 	return rv;
    755 }
    756 
    757 int
    758 tpm_intr(void *v)
    759 {
    760 	struct tpm_softc *sc = v;
    761 	uint32_t r;
    762 #ifdef TPM_DEBUG
    763 	static int cnt = 0;
    764 #endif
    765 
    766 	r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS);
    767 #ifdef TPM_DEBUG
    768 	if (r != 0) {
    769 		char buf[128];
    770 		snprintb(buf, sizeof(buf), TPM_INTERRUPT_ENABLE_BITS, r);
    771 		aprint_debug_dev(sc->sc_dev, "%s: int=%s (%d)\n", __func__,
    772 		    buf, cnt);
    773 	} else
    774 		cnt++;
    775 #endif
    776 	if (!(r & (TPM_CMD_READY_INT | TPM_LOCALITY_CHANGE_INT |
    777 	    TPM_STS_VALID_INT | TPM_DATA_AVAIL_INT)))
    778 #ifdef __FreeBSD__
    779 		return;
    780 #else
    781 		return 0;
    782 #endif
    783 	if (r & TPM_STS_VALID_INT)
    784 		wakeup(sc);
    785 
    786 	if (r & TPM_CMD_READY_INT)
    787 		wakeup(sc->sc_write);
    788 
    789 	if (r & TPM_DATA_AVAIL_INT)
    790 		wakeup(sc->sc_read);
    791 
    792 	if (r & TPM_LOCALITY_CHANGE_INT)
    793 		wakeup(sc->sc_init);
    794 
    795 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INT_STATUS, r);
    796 
    797 	return 1;
    798 }
    799 
    800 /* Read single byte using legacy interface. */
    801 static inline uint8_t
    802 tpm_legacy_in(bus_space_tag_t iot, bus_space_handle_t ioh, int reg)
    803 {
    804 	bus_space_write_1(iot, ioh, 0, reg);
    805 	return bus_space_read_1(iot, ioh, 1);
    806 }
    807 
    808 /* Write single byte using legacy interface. */
    809 static inline void
    810 tpm_legacy_out(bus_space_tag_t iot, bus_space_handle_t ioh, int reg, uint8_t v)
    811 {
    812 	bus_space_write_1(iot, ioh, 0, reg);
    813 	bus_space_write_1(iot, ioh, 1, v);
    814 }
    815 
    816 /* Probe for TPM using legacy interface. */
    817 int
    818 tpm_legacy_probe(bus_space_tag_t iot, bus_addr_t iobase)
    819 {
    820 	bus_space_handle_t ioh;
    821 	uint8_t r, v;
    822 	int i, rv = 0;
    823 	char id[8];
    824 
    825 	if (!tpm_enabled || iobase == -1)
    826 		return 0;
    827 
    828 	if (bus_space_map(iot, iobase, 2, 0, &ioh))
    829 		return 0;
    830 
    831 	v = bus_space_read_1(iot, ioh, 0);
    832 	if (v == 0xff) {
    833 		bus_space_unmap(iot, ioh, 2);
    834 		return 0;
    835 	}
    836 	r = bus_space_read_1(iot, ioh, 1);
    837 
    838 	for (i = sizeof(id); i--; )
    839 		id[i] = tpm_legacy_in(iot, ioh, TPM_ID + i);
    840 
    841 #ifdef TPM_DEBUG
    842 	printf("tpm_legacy_probe %.4s %d.%d.%d.%d\n",
    843 	    &id[4], id[0], id[1], id[2], id[3]);
    844 #endif
    845 	/*
    846 	 * The only chips using the legacy interface we are aware of are
    847 	 * by Atmel.  For other chips more signature would have to be added.
    848 	 */
    849 	if (!bcmp(&id[4], "ATML", 4))
    850 		rv = 1;
    851 
    852 	if (!rv) {
    853 		bus_space_write_1(iot, ioh, r, 1);
    854 		bus_space_write_1(iot, ioh, v, 0);
    855 	}
    856 	bus_space_unmap(iot, ioh, 2);
    857 
    858 	return rv;
    859 }
    860 
    861 /* Setup TPM using legacy interface. */
    862 int
    863 tpm_legacy_init(struct tpm_softc *sc, int irq, const char *name)
    864 {
    865 	char id[8];
    866 	uint8_t ioh, iol;
    867 	int i;
    868 
    869 	if ((i = bus_space_map(sc->sc_batm, tpm_enabled, 2, 0, &sc->sc_bahm))) {
    870 		aprint_debug_dev(sc->sc_dev, "cannot map tpm registers (%d)\n",
    871 		    i);
    872 		tpm_enabled = 0;
    873 		return 1;
    874 	}
    875 
    876 	for (i = sizeof(id); i--; )
    877 		id[i] = tpm_legacy_in(sc->sc_bt, sc->sc_bh, TPM_ID + i);
    878 
    879 	aprint_debug_dev(sc->sc_dev, "%.4s %d.%d @0x%x\n", &id[4], id[0],
    880 	    id[1], tpm_enabled);
    881 	iol = tpm_enabled & 0xff;
    882 	ioh = tpm_enabled >> 16;
    883 	tpm_enabled = 0;
    884 
    885 	return 0;
    886 }
    887 
    888 /* Start transaction. */
    889 int
    890 tpm_legacy_start(struct tpm_softc *sc, int flag)
    891 {
    892 	struct timeval tv;
    893 	uint8_t bits, r;
    894 	int to, rv;
    895 
    896 	bits = flag == UIO_READ ? TPM_LEGACY_DA : 0;
    897 	tv.tv_sec = TPM_LEGACY_TMO;
    898 	tv.tv_usec = 0;
    899 	to = tvtohz(&tv) / TPM_LEGACY_SLEEP;
    900 	while (((r = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1)) &
    901 	    (TPM_LEGACY_BUSY|bits)) != bits && to--) {
    902 		rv = tsleep(sc, PRIBIO | PCATCH, "legacy_tpm_start",
    903 		    TPM_LEGACY_SLEEP);
    904 		if (rv && rv != EWOULDBLOCK)
    905 			return rv;
    906 	}
    907 
    908 #if defined(TPM_DEBUG) && !defined(__FreeBSD__)
    909 	char buf[128];
    910 	snprintb(buf, sizeof(buf), TPM_LEGACY_BITS, r);
    911 	aprint_debug_dev(sc->sc_dev, "%s: bits %s\n", device_xname(sc->sc_dev),
    912 	    buf);
    913 #endif
    914 	if ((r & (TPM_LEGACY_BUSY|bits)) != bits)
    915 		return EIO;
    916 
    917 	return 0;
    918 }
    919 
    920 int
    921 tpm_legacy_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count,
    922     int flags)
    923 {
    924 	uint8_t *p;
    925 	size_t cnt;
    926 	int to, rv;
    927 
    928 	cnt = rv = 0;
    929 	for (p = buf; !rv && len > 0; len--) {
    930 		for (to = 1000;
    931 		    !(bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1) &
    932 		    TPM_LEGACY_DA); DELAY(1))
    933 			if (!to--)
    934 				return EIO;
    935 
    936 		DELAY(TPM_LEGACY_DELAY);
    937 		*p++ = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 0);
    938 		cnt++;
    939 	}
    940 
    941 	*count = cnt;
    942 	return 0;
    943 }
    944 
    945 int
    946 tpm_legacy_write(struct tpm_softc *sc, const void *buf, size_t len)
    947 {
    948 	const uint8_t *p;
    949 	size_t n;
    950 
    951 	for (p = buf, n = len; n--; DELAY(TPM_LEGACY_DELAY)) {
    952 		if (!n && len != TPM_BUFSIZ) {
    953 			bus_space_write_1(sc->sc_batm, sc->sc_bahm, 1,
    954 			    TPM_LEGACY_LAST);
    955 			DELAY(TPM_LEGACY_DELAY);
    956 		}
    957 		bus_space_write_1(sc->sc_batm, sc->sc_bahm, 0, *p++);
    958 	}
    959 
    960 	return 0;
    961 }
    962 
    963 /* Finish transaction. */
    964 int
    965 tpm_legacy_end(struct tpm_softc *sc, int flag, int rv)
    966 {
    967 	struct timeval tv;
    968 	uint8_t r;
    969 	int to;
    970 
    971 	if (rv || flag == UIO_READ)
    972 		bus_space_write_1(sc->sc_batm, sc->sc_bahm, 1, TPM_LEGACY_ABRT);
    973 	else {
    974 		tv.tv_sec = TPM_LEGACY_TMO;
    975 		tv.tv_usec = 0;
    976 		to = tvtohz(&tv) / TPM_LEGACY_SLEEP;
    977 		while(((r = bus_space_read_1(sc->sc_batm, sc->sc_bahm, 1)) &
    978 		    TPM_LEGACY_BUSY) && to--) {
    979 			rv = tsleep(sc, PRIBIO | PCATCH, "legacy_tpm_end",
    980 			    TPM_LEGACY_SLEEP);
    981 			if (rv && rv != EWOULDBLOCK)
    982 				return rv;
    983 		}
    984 
    985 #if defined(TPM_DEBUG) && !defined(__FreeBSD__)
    986 		char buf[128];
    987 		snprintb(buf, sizeof(buf), TPM_LEGACY_BITS, r);
    988 		aprint_debug_dev(sc->sc_dev, "%s: bits %s\n",
    989 		    device_xname(sc->sc_dev), buf);
    990 #endif
    991 		if (r & TPM_LEGACY_BUSY)
    992 			return EIO;
    993 
    994 		if (r & TPM_LEGACY_RE)
    995 			return EIO;	/* XXX Retry the loop? */
    996 	}
    997 
    998 	return rv;
    999 }
   1000 
   1001 int
   1002 tpmopen(dev_t dev, int flag, int mode, struct lwp *l)
   1003 {
   1004 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
   1005 
   1006 	if (!sc)
   1007 		return ENXIO;
   1008 
   1009 	if (sc->sc_flags & TPM_OPEN)
   1010 		return EBUSY;
   1011 
   1012 	sc->sc_flags |= TPM_OPEN;
   1013 
   1014 	return 0;
   1015 }
   1016 
   1017 int
   1018 tpmclose(dev_t dev, int flag, int mode, struct lwp *l)
   1019 {
   1020 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
   1021 
   1022 	if (!sc)
   1023 		return ENXIO;
   1024 
   1025 	if (!(sc->sc_flags & TPM_OPEN))
   1026 		return EINVAL;
   1027 
   1028 	sc->sc_flags &= ~TPM_OPEN;
   1029 
   1030 	return 0;
   1031 }
   1032 
   1033 int
   1034 tpmread(dev_t dev, struct uio *uio, int flags)
   1035 {
   1036 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
   1037 	uint8_t buf[TPM_BUFSIZ], *p;
   1038 	size_t cnt, len, n;
   1039 	int  rv, s;
   1040 
   1041 	if (!sc)
   1042 		return ENXIO;
   1043 
   1044 	s = spltty();
   1045 	if ((rv = (*sc->sc_start)(sc, UIO_READ)))
   1046 		goto out;
   1047 
   1048 #ifdef TPM_DEBUG
   1049 	aprint_debug_dev(sc->sc_dev, "%s: getting header\n", __func__);
   1050 #endif
   1051 	if ((rv = (*sc->sc_read)(sc, buf, TPM_HDRSIZE, &cnt, 0))) {
   1052 		(*sc->sc_end)(sc, UIO_READ, rv);
   1053 		goto out;
   1054 	}
   1055 
   1056 	len = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | buf[5];
   1057 #ifdef TPM_DEBUG
   1058 	aprint_debug_dev(sc->sc_dev, "%s: len %zu, io count %zu\n", __func__,
   1059 	    len, uio->uio_resid);
   1060 #endif
   1061 	if (len > uio->uio_resid) {
   1062 		rv = EIO;
   1063 		(*sc->sc_end)(sc, UIO_READ, rv);
   1064 #ifdef TPM_DEBUG
   1065 		aprint_debug_dev(sc->sc_dev,
   1066 		    "%s: bad residual io count 0x%zx\n", __func__,
   1067 		    uio->uio_resid);
   1068 #endif
   1069 		goto out;
   1070 	}
   1071 
   1072 	/* Copy out header. */
   1073 	if ((rv = uiomove(buf, cnt, uio))) {
   1074 #ifdef TPM_DEBUG
   1075 		aprint_debug_dev(sc->sc_dev,
   1076 		    "%s: uiomove failed %d\n", __func__, rv);
   1077 #endif
   1078 		(*sc->sc_end)(sc, UIO_READ, rv);
   1079 		goto out;
   1080 	}
   1081 
   1082 	/* Get remaining part of the answer (if anything is left). */
   1083 	for (len -= cnt, p = buf, n = sizeof(buf); len > 0; p = buf, len -= n,
   1084 	    n = sizeof(buf)) {
   1085 		n = MIN(n, len);
   1086 #ifdef TPM_DEBUG
   1087 		aprint_debug_dev(sc->sc_dev, "%s: n %zu len %zu\n", __func__,
   1088 		    n, len);
   1089 #endif
   1090 		if ((rv = (*sc->sc_read)(sc, p, n, NULL, TPM_PARAM_SIZE))) {
   1091 			(*sc->sc_end)(sc, UIO_READ, rv);
   1092 			goto out;
   1093 		}
   1094 		p += n;
   1095 		if ((rv = uiomove(buf, p - buf, uio))) {
   1096 #ifdef TPM_DEBUG
   1097 			aprint_debug_dev(sc->sc_dev,
   1098 			    "%s: uiomove failed %d\n", __func__, rv);
   1099 #endif
   1100 			(*sc->sc_end)(sc, UIO_READ, rv);
   1101 			goto out;
   1102 		}
   1103 	}
   1104 
   1105 	rv = (*sc->sc_end)(sc, UIO_READ, rv);
   1106 out:
   1107 	splx(s);
   1108 	return rv;
   1109 }
   1110 
   1111 int
   1112 tpmwrite(dev_t dev, struct uio *uio, int flags)
   1113 {
   1114 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, TPMUNIT(dev));
   1115 	uint8_t buf[TPM_BUFSIZ];
   1116 	int n, rv, s;
   1117 
   1118 	if (!sc)
   1119 		return ENXIO;
   1120 
   1121 	s = spltty();
   1122 
   1123 #ifdef TPM_DEBUG
   1124 	aprint_debug_dev(sc->sc_dev, "%s: io count %zu\n", __func__,
   1125 	    uio->uio_resid);
   1126 #endif
   1127 
   1128 	n = MIN(sizeof(buf), uio->uio_resid);
   1129 	if ((rv = uiomove(buf, n, uio))) {
   1130 #ifdef TPM_DEBUG
   1131 		aprint_debug_dev(sc->sc_dev,
   1132 		    "%s: uiomove failed %d\n", __func__, rv);
   1133 #endif
   1134 		splx(s);
   1135 		return rv;
   1136 	}
   1137 
   1138 	if ((rv = (*sc->sc_start)(sc, UIO_WRITE))) {
   1139 		splx(s);
   1140 		return rv;
   1141 	}
   1142 
   1143 	if ((rv = (*sc->sc_write)(sc, buf, n))) {
   1144 		splx(s);
   1145 		return rv;
   1146 	}
   1147 
   1148 	rv = (*sc->sc_end)(sc, UIO_WRITE, rv);
   1149 	splx(s);
   1150 	return rv;
   1151 }
   1152 
   1153 int
   1154 tpmioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l)
   1155 {
   1156 	return ENOTTY;
   1157 }
   1158