xref: /openbsd-src/sys/dev/acpi/tpm.c (revision 4e1ee0786f11cc571bd0be17d38e46f635c719fc)
1 /* $OpenBSD: tpm.c,v 1.12 2021/09/11 23:22:38 deraadt Exp $ */
2 
3 /*
4  * Minimal interface to Trusted Platform Module chips implementing the
5  * TPM Interface Spec 1.2, just enough to tell the TPM to save state before
6  * a system suspend.
7  *
8  * Copyright (c) 2008, 2009 Michael Shalayeff
9  * Copyright (c) 2009, 2010 Hans-Joerg Hoexer
10  * Copyright (c) 2016 joshua stein <jcs@openbsd.org>
11  * All rights reserved.
12  *
13  * Permission to use, copy, modify, and distribute this software for any
14  * purpose with or without fee is hereby granted, provided that the above
15  * copyright notice and this permission notice appear in all copies.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
22  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
23  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24  */
25 
26 #include <sys/param.h>
27 #include <sys/systm.h>
28 #include <sys/device.h>
29 #include <sys/malloc.h>
30 
31 #include <machine/bus.h>
32 #include <machine/apmvar.h>
33 
34 #include <dev/acpi/acpireg.h>
35 #include <dev/acpi/acpivar.h>
36 #include <dev/acpi/acpidev.h>
37 #include <dev/acpi/amltypes.h>
38 #include <dev/acpi/dsdt.h>
39 
40 /* #define TPM_DEBUG */
41 
42 #ifdef TPM_DEBUG
43 #define DPRINTF(x) printf x
44 #else
45 #define DPRINTF(x)
46 #endif
47 
48 #define TPM_BUFSIZ			1024
49 #define TPM_HDRSIZE			10
50 #define TPM_PARAM_SIZE			0x0001
51 
52 #define TPM_ACCESS			0x0000	/* access register */
53 #define TPM_ACCESS_ESTABLISHMENT	0x01	/* establishment */
54 #define TPM_ACCESS_REQUEST_USE		0x02	/* request using locality */
55 #define TPM_ACCESS_REQUEST_PENDING	0x04	/* pending request */
56 #define TPM_ACCESS_SEIZE		0x08	/* request locality seize */
57 #define TPM_ACCESS_SEIZED		0x10	/* locality has been seized */
58 #define TPM_ACCESS_ACTIVE_LOCALITY	0x20	/* locality is active */
59 #define TPM_ACCESS_VALID		0x80	/* bits are valid */
60 #define TPM_ACCESS_BITS	\
61     "\020\01EST\02REQ\03PEND\04SEIZE\05SEIZED\06ACT\010VALID"
62 
63 #define TPM_INTERRUPT_ENABLE		0x0008
64 #define TPM_GLOBAL_INT_ENABLE		0x80000000 /* enable ints */
65 #define TPM_CMD_READY_INT		0x00000080 /* cmd ready enable */
66 #define TPM_INT_EDGE_FALLING		0x00000018
67 #define TPM_INT_EDGE_RISING		0x00000010
68 #define TPM_INT_LEVEL_LOW		0x00000008
69 #define TPM_INT_LEVEL_HIGH		0x00000000
70 #define TPM_LOCALITY_CHANGE_INT		0x00000004 /* locality change enable */
71 #define TPM_STS_VALID_INT		0x00000002 /* int on TPM_STS_VALID is set */
72 #define TPM_DATA_AVAIL_INT		0x00000001 /* int on TPM_STS_DATA_AVAIL is set */
73 #define TPM_INTERRUPT_ENABLE_BITS \
74     "\020\040ENA\010RDY\03LOCH\02STSV\01DRDY"
75 
76 #define TPM_INT_VECTOR			0x000c	/* 8 bit reg for 4 bit irq vector */
77 #define TPM_INT_STATUS			0x0010	/* bits are & 0x87 from TPM_INTERRUPT_ENABLE */
78 
79 #define TPM_INTF_CAPABILITIES		0x0014	/* capability register */
80 #define TPM_INTF_BURST_COUNT_STATIC	0x0100	/* TPM_STS_BMASK static */
81 #define TPM_INTF_CMD_READY_INT		0x0080	/* int on ready supported */
82 #define TPM_INTF_INT_EDGE_FALLING	0x0040	/* falling edge ints supported */
83 #define TPM_INTF_INT_EDGE_RISING	0x0020	/* rising edge ints supported */
84 #define TPM_INTF_INT_LEVEL_LOW		0x0010	/* level-low ints supported */
85 #define TPM_INTF_INT_LEVEL_HIGH		0x0008	/* level-high ints supported */
86 #define TPM_INTF_LOCALITY_CHANGE_INT	0x0004	/* locality-change int (mb 1) */
87 #define TPM_INTF_STS_VALID_INT		0x0002	/* TPM_STS_VALID int supported */
88 #define TPM_INTF_DATA_AVAIL_INT		0x0001	/* TPM_STS_DATA_AVAIL int supported (mb 1) */
89 #define TPM_CAPSREQ \
90   (TPM_INTF_DATA_AVAIL_INT|TPM_INTF_LOCALITY_CHANGE_INT|TPM_INTF_INT_LEVEL_LOW)
91 #define TPM_CAPBITS \
92   "\020\01IDRDY\02ISTSV\03ILOCH\04IHIGH\05ILOW\06IEDGE\07IFALL\010IRDY\011BCST"
93 
94 #define TPM_STS				0x0018	   /* status register */
95 #define TPM_STS_MASK			0x000000ff /* status bits */
96 #define TPM_STS_BMASK			0x00ffff00 /* ro io burst size */
97 #define TPM_STS_VALID			0x00000080 /* ro other bits are valid */
98 #define TPM_STS_CMD_READY		0x00000040 /* rw chip/signal ready */
99 #define TPM_STS_GO			0x00000020 /* wo start the command */
100 #define TPM_STS_DATA_AVAIL		0x00000010 /* ro data available */
101 #define TPM_STS_DATA_EXPECT		0x00000008 /* ro more data to be written */
102 #define TPM_STS_RESP_RETRY		0x00000002 /* wo resend the response */
103 #define TPM_STS_BITS	"\020\010VALID\07RDY\06GO\05DRDY\04EXPECT\02RETRY"
104 
105 #define TPM_DATA			0x0024
106 #define TPM_ID				0x0f00
107 #define TPM_REV				0x0f04
108 #define TPM_SIZE			0x5000	/* five pages of the above */
109 
110 #define TPM_ACCESS_TMO			2000	/* 2sec */
111 #define TPM_READY_TMO			2000	/* 2sec */
112 #define TPM_READ_TMO			120000	/* 2 minutes */
113 #define TPM_BURST_TMO			2000	/* 2sec */
114 
115 struct tpm_softc {
116 	struct device		sc_dev;
117 
118 	bus_space_tag_t		sc_bt;
119 	bus_space_handle_t	sc_bh;
120 
121 	struct acpi_softc	*sc_acpi;
122 	struct aml_node		*sc_devnode;
123 
124 	uint32_t		sc_devid;
125 	uint32_t		sc_rev;
126 	int			sc_tpm20;
127 
128 	int			sc_enabled;
129 };
130 
131 const struct {
132 	uint32_t devid;
133 	char name[32];
134 } tpm_devs[] = {
135 	{ 0x000615d1, "Infineon SLD9630 1.1" },
136 	{ 0x000b15d1, "Infineon SLB9635 1.2" },
137 	{ 0x100214e4, "Broadcom BCM0102" },
138 	{ 0x00fe1050, "WEC WPCT200" },
139 	{ 0x687119fa, "SNS SSX35" },
140 	{ 0x2e4d5453, "STM ST19WP18" },
141 	{ 0x32021114, "Atmel 97SC3203" },
142 	{ 0x10408086, "Intel INTC0102" },
143 	{ 0, "" },
144 };
145 
146 int	tpm_match(struct device *, void *, void *);
147 void	tpm_attach(struct device *, struct device *, void *);
148 int	tpm_activate(struct device *, int);
149 
150 int	tpm_probe(bus_space_tag_t, bus_space_handle_t);
151 int	tpm_init(struct tpm_softc *);
152 int	tpm_read(struct tpm_softc *, void *, int, size_t *, int);
153 int	tpm_write(struct tpm_softc *, void *, int);
154 int	tpm_suspend(struct tpm_softc *);
155 int	tpm_resume(struct tpm_softc *);
156 
157 int	tpm_waitfor(struct tpm_softc *, uint8_t, int);
158 int	tpm_request_locality(struct tpm_softc *, int);
159 void	tpm_release_locality(struct tpm_softc *);
160 int	tpm_getburst(struct tpm_softc *);
161 uint8_t	tpm_status(struct tpm_softc *);
162 
163 struct cfattach tpm_ca = {
164 	sizeof(struct tpm_softc),
165 	tpm_match,
166 	tpm_attach,
167 	NULL,
168 	tpm_activate
169 };
170 
171 struct cfdriver tpm_cd = {
172 	NULL, "tpm", DV_DULL
173 };
174 
175 const char *tpm_hids[] = {
176 	"PNP0C31",
177 	"ATM1200",
178 	"IFX0102",
179 	"BCM0101",
180 	"BCM0102",
181 	"NSC1200",
182 	"ICO0102",
183 	"MSFT0101",
184 	NULL
185 };
186 
187 int
188 tpm_match(struct device *parent, void *match, void *aux)
189 {
190 	struct acpi_attach_args	*aa = aux;
191 	struct cfdata		*cf = match;
192 
193 	return (acpi_matchhids(aa, tpm_hids, cf->cf_driver->cd_name));
194 }
195 
196 void
197 tpm_attach(struct device *parent, struct device *self, void *aux)
198 {
199 	struct tpm_softc	*sc = (struct tpm_softc *)self;
200 	struct acpi_attach_args *aaa = aux;
201 	int64_t			sta;
202 
203 	sc->sc_acpi = (struct acpi_softc *)parent;
204 	sc->sc_devnode = aaa->aaa_node;
205 	sc->sc_enabled = 0;
206 
207 	printf(" %s", sc->sc_devnode->name);
208 
209 	if (strcmp(aaa->aaa_dev, "MSFT0101") == 0 ||
210 	    strcmp(aaa->aaa_cdev, "MSFT0101") == 0)
211 		sc->sc_tpm20 = 1;
212 
213 	sta = acpi_getsta(sc->sc_acpi, sc->sc_devnode);
214 	if ((sta & (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) !=
215 	    (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) {
216 		printf(": not enabled\n");
217 		return;
218 	}
219 
220 	if (aaa->aaa_naddr < 1) {
221 		printf(": no registers\n");
222 		return;
223 	}
224 
225 	printf(" addr 0x%llx/0x%llx", aaa->aaa_addr[0], aaa->aaa_size[0]);
226 
227 	sc->sc_bt = aaa->aaa_bst[0];
228 	if (bus_space_map(sc->sc_bt, aaa->aaa_addr[0], aaa->aaa_size[0],
229 	    0, &sc->sc_bh)) {
230 		printf(": can't map registers\n");
231 		return;
232 	}
233 
234 	if (!tpm_probe(sc->sc_bt, sc->sc_bh)) {
235 		printf(": probe failed\n");
236 		return;
237 	}
238 
239 	if (tpm_init(sc) != 0) {
240 		printf(": init failed\n");
241 		return;
242 	}
243 
244 	printf("\n");
245 	sc->sc_enabled = 1;
246 }
247 
248 int
249 tpm_activate(struct device *self, int act)
250 {
251 	struct tpm_softc	*sc = (struct tpm_softc *)self;
252 
253 	switch (act) {
254 	case DVACT_SUSPEND:
255 		if (!sc->sc_enabled) {
256 			DPRINTF(("%s: suspend, but not enabled\n",
257 			    sc->sc_dev.dv_xname));
258 			return 0;
259 		}
260 		tpm_suspend(sc);
261 		break;
262 
263 	case DVACT_WAKEUP:
264 		if (!sc->sc_enabled) {
265 			DPRINTF(("%s: wakeup, but not enabled\n",
266 			    sc->sc_dev.dv_xname));
267 			return 0;
268 		}
269 		tpm_resume(sc);
270 		break;
271 	}
272 
273 	return 0;
274 }
275 
276 int
277 tpm_suspend(struct tpm_softc *sc)
278 {
279 	uint8_t command1[] = {
280 	    0, 0xc1,		/* TPM_TAG_RQU_COMMAND */
281 	    0, 0, 0, 10,	/* Length in bytes */
282 	    0, 0, 0, 0x98	/* TPM_ORD_SaveStates */
283 	};
284 	uint8_t command2[] = {
285 	    0x80, 0x01,		/* TPM_ST_COMMAND_TAG */
286 	    0, 0, 0, 12,	/* Length in bytes */
287 	    0, 0, 0x01, 0x45,	/* TPM_CC_Shutdown */
288 	    0x00, 0x01
289 	};
290 	uint8_t *command;
291 	size_t commandlen;
292 
293 	DPRINTF(("%s: saving state preparing for suspend\n",
294 	    sc->sc_dev.dv_xname));
295 
296 	if (sc->sc_tpm20) {
297 		command = command2;
298 		commandlen = sizeof(command2);
299 	} else {
300 		command = command1;
301 		commandlen = sizeof(command1);
302 	}
303 
304 	/*
305 	 * Tell the chip to save its state so the BIOS can then restore it upon
306 	 * resume.
307 	 */
308 	tpm_write(sc, command, commandlen);
309 	tpm_read(sc, command, commandlen, NULL, TPM_HDRSIZE);
310 
311 	return 0;
312 }
313 
314 int
315 tpm_resume(struct tpm_softc *sc)
316 {
317 	/*
318 	 * TODO: The BIOS should have restored the chip's state for us already,
319 	 * but we should tell the chip to do a self-test here (according to the
320 	 * Linux driver).
321 	 */
322 
323 	DPRINTF(("%s: resume\n", sc->sc_dev.dv_xname));
324 	return 0;
325 }
326 
327 int
328 tpm_probe(bus_space_tag_t bt, bus_space_handle_t bh)
329 {
330 	uint32_t r;
331 	int tries = 10000;
332 
333 	/* wait for chip to settle */
334 	while (tries--) {
335 		if (bus_space_read_1(bt, bh, TPM_ACCESS) & TPM_ACCESS_VALID)
336 			break;
337 		else if (!tries) {
338 			printf(": timed out waiting for validity\n");
339 			return 1;
340 		}
341 
342 		DELAY(10);
343 	}
344 
345 	r = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITIES);
346 	if (r == 0xffffffff)
347 		return 0;
348 
349 	return 1;
350 }
351 
352 int
353 tpm_init(struct tpm_softc *sc)
354 {
355 	uint32_t r, intmask;
356 	int i;
357 
358 	r = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTF_CAPABILITIES);
359 	if ((r & TPM_CAPSREQ) != TPM_CAPSREQ ||
360 	    !(r & (TPM_INTF_INT_EDGE_RISING | TPM_INTF_INT_LEVEL_LOW))) {
361 		DPRINTF((": caps too low (caps=%b)\n", r, TPM_CAPBITS));
362 		return 0;
363 	}
364 
365 	/* ack and disable all interrupts, we'll be using polling only */
366 	intmask = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE);
367 	intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT |
368 	    TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT;
369 	intmask &= ~TPM_GLOBAL_INT_ENABLE;
370 	bus_space_write_4(sc->sc_bt, sc->sc_bh, TPM_INTERRUPT_ENABLE, intmask);
371 
372 	if (tpm_request_locality(sc, 0)) {
373 		printf(", requesting locality failed\n");
374 		return 1;
375 	}
376 
377 	sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID);
378 	sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV);
379 
380 	for (i = 0; tpm_devs[i].devid; i++)
381 		if (tpm_devs[i].devid == sc->sc_devid)
382 			break;
383 
384 	if (tpm_devs[i].devid)
385 		printf(", %s rev 0x%x", tpm_devs[i].name, sc->sc_rev);
386 	else
387 		printf(", device 0x%08x rev 0x%x", sc->sc_devid, sc->sc_rev);
388 
389 	return 0;
390 }
391 
392 int
393 tpm_request_locality(struct tpm_softc *sc, int l)
394 {
395 	uint32_t r;
396 	int to;
397 
398 	if (l != 0)
399 		return EINVAL;
400 
401 	if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
402 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) ==
403 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
404 		return 0;
405 
406 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
407 	    TPM_ACCESS_REQUEST_USE);
408 
409 	to = TPM_ACCESS_TMO * 100;	/* steps of 10 microseconds */
410 
411 	while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
412 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
413 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) {
414 		DELAY(10);
415 	}
416 
417 	if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
418 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
419 		DPRINTF(("%s: %s: access %b\n", sc->sc_dev.dv_xname, __func__,
420 		    r, TPM_ACCESS_BITS));
421 		return EBUSY;
422 	}
423 
424 	return 0;
425 }
426 
427 void
428 tpm_release_locality(struct tpm_softc *sc)
429 {
430 	if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
431 	    (TPM_ACCESS_REQUEST_PENDING|TPM_ACCESS_VALID)) ==
432 	    (TPM_ACCESS_REQUEST_PENDING|TPM_ACCESS_VALID)) {
433 		DPRINTF(("%s: releasing locality\n", sc->sc_dev.dv_xname));
434 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
435 		    TPM_ACCESS_ACTIVE_LOCALITY);
436 	}
437 }
438 
439 int
440 tpm_getburst(struct tpm_softc *sc)
441 {
442 	int burst, burst2, to;
443 
444 	to = TPM_BURST_TMO * 100;	/* steps of 10 microseconds */
445 
446 	burst = 0;
447 	while (burst == 0 && to--) {
448 		/*
449 		 * Burst count has to be read from bits 8 to 23 without
450 		 * touching any other bits, eg. the actual status bits 0 to 7.
451 		 */
452 		burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1);
453 		DPRINTF(("%s: %s: read1(0x%x): 0x%x\n", sc->sc_dev.dv_xname,
454 		    __func__, TPM_STS + 1, burst));
455 		burst2 = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2);
456 		DPRINTF(("%s: %s: read1(0x%x): 0x%x\n", sc->sc_dev.dv_xname,
457 		    __func__, TPM_STS + 2, burst2));
458 		burst |= burst2 << 8;
459 		if (burst)
460 			return burst;
461 
462 		DELAY(10);
463 	}
464 
465 	DPRINTF(("%s: getburst timed out\n", sc->sc_dev.dv_xname));
466 
467 	return 0;
468 }
469 
470 uint8_t
471 tpm_status(struct tpm_softc *sc)
472 {
473 	return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) & TPM_STS_MASK;
474 }
475 
476 int
477 tpm_waitfor(struct tpm_softc *sc, uint8_t mask, int msecs)
478 {
479 	int usecs;
480 	uint8_t status;
481 
482 	usecs = msecs * 1000;
483 
484 	while (((status = tpm_status(sc)) & mask) != mask) {
485 		if (usecs == 0) {
486 			DPRINTF(("%s: %s: timed out, status 0x%x != 0x%x\n",
487 			    sc->sc_dev.dv_xname, __func__, status, mask));
488 			return status;
489 		}
490 
491 		usecs--;
492 		DELAY(1);
493 	}
494 
495 	return 0;
496 }
497 
498 int
499 tpm_read(struct tpm_softc *sc, void *buf, int len, size_t *count,
500     int flags)
501 {
502 	uint8_t *p = buf;
503 	uint8_t c;
504 	size_t cnt;
505 	int rv, n, bcnt;
506 
507 	DPRINTF(("%s: %s %d:", sc->sc_dev.dv_xname, __func__, len));
508 
509 	cnt = 0;
510 	while (len > 0) {
511 		if ((rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
512 		    TPM_READ_TMO)))
513 			return rv;
514 
515 		bcnt = tpm_getburst(sc);
516 		n = MIN(len, bcnt);
517 
518 		for (; n--; len--) {
519 			c = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA);
520 			DPRINTF((" %02x", c));
521 			*p++ = c;
522 			cnt++;
523 		}
524 
525 		if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6)
526 			break;
527 	}
528 
529 	DPRINTF(("\n"));
530 
531 	if (count)
532 		*count = cnt;
533 
534 	return 0;
535 }
536 
537 int
538 tpm_write(struct tpm_softc *sc, void *buf, int len)
539 {
540 	uint8_t *p = buf;
541 	uint8_t status;
542 	size_t count = 0;
543 	int rv, r;
544 
545 	if ((rv = tpm_request_locality(sc, 0)) != 0)
546 		return rv;
547 
548 	DPRINTF(("%s: %s %d:", sc->sc_dev.dv_xname, __func__, len));
549 	for (r = 0; r < len; r++)
550 		DPRINTF((" %02x", (uint8_t)(*(p + r))));
551 	DPRINTF(("\n"));
552 
553 	/* read status */
554 	status = tpm_status(sc);
555 	if ((status & TPM_STS_CMD_READY) == 0) {
556 		/* abort! */
557 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
558 		    TPM_STS_CMD_READY);
559 		if ((rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READ_TMO))) {
560 			DPRINTF(("%s: failed waiting for ready after abort "
561 			    "(0x%x)\n", sc->sc_dev.dv_xname, rv));
562 			return rv;
563 		}
564 	}
565 
566 	while (count < len - 1) {
567 		for (r = tpm_getburst(sc); r > 0 && count < len - 1; r--) {
568 			DPRINTF(("%s: %s: write1(0x%x, 0x%x)\n",
569 			    sc->sc_dev.dv_xname, __func__, TPM_DATA, *p));
570 			bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
571 			count++;
572 		}
573 		if ((rv = tpm_waitfor(sc, TPM_STS_VALID | TPM_STS_DATA_EXPECT,
574 		    TPM_READ_TMO))) {
575 			DPRINTF(("%s: %s: failed waiting for next byte (%d)\n",
576 			    sc->sc_dev.dv_xname, __func__, rv));
577 			return rv;
578 		}
579 	}
580 
581 	DPRINTF(("%s: %s: write1(0x%x, 0x%x)\n", sc->sc_dev.dv_xname, __func__,
582 	    TPM_DATA, *p));
583 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p);
584 	count++;
585 
586 	if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO))) {
587 		DPRINTF(("%s: %s: failed after last byte (%d)\n",
588 		    sc->sc_dev.dv_xname, __func__, rv));
589 		return rv;
590 	}
591 
592 	if ((status = tpm_status(sc)) & TPM_STS_DATA_EXPECT) {
593 		DPRINTF(("%s: %s: final status still expecting data: %b\n",
594 		    sc->sc_dev.dv_xname, __func__, status, TPM_STS_BITS));
595 		return status;
596 	}
597 
598 	DPRINTF(("%s: final status after write: %b\n", sc->sc_dev.dv_xname,
599 	    status, TPM_STS_BITS));
600 
601 	/* XXX: are we ever sending non-command data? */
602 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_GO);
603 
604 	return 0;
605 }
606