xref: /netbsd-src/sys/dev/ic/tpm.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /*	$NetBSD: tpm.c,v 1.16 2019/10/09 14:03:58 maxv Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Maxime Villard.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * Copyright (c) 2008, 2009 Michael Shalayeff
34  * Copyright (c) 2009, 2010 Hans-Joerg Hoexer
35  * All rights reserved.
36  *
37  * Permission to use, copy, modify, and distribute this software for any
38  * purpose with or without fee is hereby granted, provided that the above
39  * copyright notice and this permission notice appear in all copies.
40  *
41  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
42  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
43  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
44  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
45  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
46  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
47  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48  */
49 
50 #include <sys/cdefs.h>
51 __KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.16 2019/10/09 14:03:58 maxv Exp $");
52 
53 #include <sys/param.h>
54 #include <sys/systm.h>
55 #include <sys/kernel.h>
56 #include <sys/malloc.h>
57 #include <sys/proc.h>
58 #include <sys/device.h>
59 #include <sys/conf.h>
60 #include <sys/bus.h>
61 #include <sys/pmf.h>
62 
63 #include <dev/ic/tpmreg.h>
64 #include <dev/ic/tpmvar.h>
65 
66 #include "ioconf.h"
67 
68 CTASSERT(sizeof(struct tpm_header) == 10);
69 
70 #define TPM_BUFSIZ	1024
71 
72 #define TPM_PARAM_SIZE	0x0001	/* that's a flag */
73 
74 /* Timeouts. */
75 #define TPM_ACCESS_TMO	2000	/* 2sec */
76 #define TPM_READY_TMO	2000	/* 2sec */
77 #define TPM_READ_TMO	2000	/* 2sec */
78 #define TPM_BURST_TMO	2000	/* 2sec */
79 
80 #define TPM_CAPS_REQUIRED \
81 	(TPM_INTF_DATA_AVAIL_INT|TPM_INTF_LOCALITY_CHANGE_INT| \
82 	 TPM_INTF_INT_LEVEL_LOW)
83 
84 static inline int
85 tpm_tmotohz(int tmo)
86 {
87 	struct timeval tv;
88 
89 	tv.tv_sec = tmo / 1000;
90 	tv.tv_usec = 1000 * (tmo % 1000);
91 
92 	return tvtohz(&tv);
93 }
94 
95 static int
96 tpm_getburst(struct tpm_softc *sc)
97 {
98 	int burst, to, rv;
99 
100 	to = tpm_tmotohz(TPM_BURST_TMO);
101 
102 	while (to--) {
103 		/*
104 		 * Burst count is in bits 23:8, so read the two higher bytes.
105 		 */
106 		burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1);
107 		burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2)
108 		    << 8;
109 
110 		if (burst)
111 			return burst;
112 
113 		rv = tsleep(sc, PCATCH, "tpm_getburst", 1);
114 		if (rv && rv != EWOULDBLOCK) {
115 			return 0;
116 		}
117 	}
118 
119 	return 0;
120 }
121 
122 static inline uint8_t
123 tpm_status(struct tpm_softc *sc)
124 {
125 	return bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS) &
126 	    TPM_STS_STATUS_BITS;
127 }
128 
129 /* -------------------------------------------------------------------------- */
130 
131 static bool
132 tpm12_suspend(struct tpm_softc *sc)
133 {
134 	static const uint8_t command[10] = {
135 		0x00, 0xC1,		/* TPM_TAG_RQU_COMMAND */
136 		0x00, 0x00, 0x00, 10,	/* Length in bytes */
137 		0x00, 0x00, 0x00, 0x98	/* TPM_ORD_SaveState */
138 	};
139 	struct tpm_header response;
140 
141 	if ((*sc->sc_intf->write)(sc, &command, sizeof(command)) != 0)
142 		return false;
143 	if ((*sc->sc_intf->read)(sc, &response, sizeof(response), NULL, 0) != 0)
144 		return false;
145 	if (TPM_BE32(response.code) != 0)
146 		return false;
147 
148 	return true;
149 }
150 
151 static bool
152 tpm20_suspend(struct tpm_softc *sc)
153 {
154 	static const uint8_t command[12] = {
155 		0x80, 0x01,		/* TPM_ST_NO_SESSIONS */
156 		0x00, 0x00, 0x00, 12,	/* Length in bytes */
157 		0x00, 0x00, 0x01, 0x45,	/* TPM_CC_Shutdown */
158 		0x00, 0x01		/* TPM_SU_STATE */
159 	};
160 	struct tpm_header response;
161 
162 	if ((*sc->sc_intf->write)(sc, &command, sizeof(command)) != 0)
163 		return false;
164 	if ((*sc->sc_intf->read)(sc, &response, sizeof(response), NULL, 0) != 0)
165 		return false;
166 	if (TPM_BE32(response.code) != 0)
167 		return false;
168 
169 	return true;
170 }
171 
172 bool
173 tpm_suspend(device_t dev, const pmf_qual_t *qual)
174 {
175 	struct tpm_softc *sc = device_private(dev);
176 
177 	switch (sc->sc_ver) {
178 	case TPM_1_2:
179 		return tpm12_suspend(sc);
180 	case TPM_2_0:
181 		return tpm20_suspend(sc);
182 	default:
183 		panic("%s: impossible", __func__);
184 	}
185 }
186 
187 bool
188 tpm_resume(device_t dev, const pmf_qual_t *qual)
189 {
190 	/*
191 	 * Don't do anything, the BIOS is supposed to restore the previously
192 	 * saved state.
193 	 */
194 	return true;
195 }
196 
197 /* -------------------------------------------------------------------------- */
198 
199 static int
200 tpm_poll(struct tpm_softc *sc, uint8_t mask, int to, wchan_t chan)
201 {
202 	int rv;
203 
204 	while (((sc->sc_status = tpm_status(sc)) & mask) != mask && to--) {
205 		rv = tsleep(chan, PCATCH, "tpm_poll", 1);
206 		if (rv && rv != EWOULDBLOCK) {
207 			return rv;
208 		}
209 	}
210 
211 	return 0;
212 }
213 
214 static int
215 tpm_waitfor(struct tpm_softc *sc, uint8_t bits, int tmo, wchan_t chan)
216 {
217 	int retry, to, rv;
218 	uint8_t todo;
219 
220 	to = tpm_tmotohz(tmo);
221 	retry = 3;
222 
223 restart:
224 	todo = bits;
225 
226 	/*
227 	 * TPM_STS_VALID has priority over the others.
228 	 */
229 	if (todo & TPM_STS_VALID) {
230 		if ((rv = tpm_poll(sc, TPM_STS_VALID, to+1, chan)) != 0)
231 			return rv;
232 		todo &= ~TPM_STS_VALID;
233 	}
234 
235 	if ((rv = tpm_poll(sc, todo, to, chan)) != 0)
236 		return rv;
237 
238 	if ((todo & sc->sc_status) != todo) {
239 		if ((retry-- > 0) && (bits & TPM_STS_VALID)) {
240 			bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
241 			    TPM_STS_RESP_RETRY);
242 			goto restart;
243 		}
244 		return EIO;
245 	}
246 
247 	return 0;
248 }
249 
250 /* -------------------------------------------------------------------------- */
251 
252 /*
253  * TPM using the TIS 1.2 interface.
254  */
255 
256 static int
257 tpm12_request_locality(struct tpm_softc *sc, int l)
258 {
259 	uint32_t r;
260 	int to, rv;
261 
262 	if (l != 0)
263 		return EINVAL;
264 
265 	if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
266 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) ==
267 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
268 		return 0;
269 
270 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
271 	    TPM_ACCESS_REQUEST_USE);
272 
273 	to = tpm_tmotohz(TPM_ACCESS_TMO);
274 
275 	while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
276 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
277 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) {
278 		rv = tsleep(sc->sc_intf->init, PCATCH, "tpm_locality", 1);
279 		if (rv && rv != EWOULDBLOCK) {
280 			return rv;
281 		}
282 	}
283 
284 	if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
285 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
286 		return EBUSY;
287 	}
288 
289 	return 0;
290 }
291 
292 static int
293 tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh)
294 {
295 	uint32_t cap;
296 	uint8_t reg;
297 	int tmo;
298 
299 	cap = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITY);
300 	if (cap == 0xffffffff)
301 		return EINVAL;
302 	if ((cap & TPM_CAPS_REQUIRED) != TPM_CAPS_REQUIRED)
303 		return ENOTSUP;
304 
305 	/* Request locality 0. */
306 	bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE);
307 
308 	/* Wait for it to become active. */
309 	tmo = TPM_ACCESS_TMO; /* Milliseconds. */
310 	while ((reg = bus_space_read_1(bt, bh, TPM_ACCESS) &
311 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
312 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && tmo--) {
313 		DELAY(1000); /* 1 millisecond. */
314 	}
315 	if ((reg & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
316 	    (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
317 		return ETIMEDOUT;
318 	}
319 
320 	if (bus_space_read_4(bt, bh, TPM_ID) == 0xffffffff)
321 		return EINVAL;
322 
323 	return 0;
324 }
325 
326 static int
327 tpm_tis12_init(struct tpm_softc *sc)
328 {
329 	int rv;
330 
331 	sc->sc_caps = bus_space_read_4(sc->sc_bt, sc->sc_bh,
332 	    TPM_INTF_CAPABILITY);
333 	sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID);
334 	sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV);
335 
336 	aprint_normal_dev(sc->sc_dev, "device 0x%08x rev 0x%x\n",
337 	    sc->sc_devid, sc->sc_rev);
338 
339 	if ((rv = tpm12_request_locality(sc, 0)) != 0)
340 		return rv;
341 
342 	/* Abort whatever it thought it was doing. */
343 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
344 
345 	return 0;
346 }
347 
348 static int
349 tpm_tis12_start(struct tpm_softc *sc, int rw)
350 {
351 	int rv;
352 
353 	if (rw == UIO_READ) {
354 		rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
355 		    TPM_READ_TMO, sc->sc_intf->read);
356 		return rv;
357 	}
358 
359 	/* Request the 0th locality. */
360 	if ((rv = tpm12_request_locality(sc, 0)) != 0)
361 		return rv;
362 
363 	sc->sc_status = tpm_status(sc);
364 	if (sc->sc_status & TPM_STS_CMD_READY)
365 		return 0;
366 
367 	/* Abort previous and restart. */
368 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
369 	rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO, sc->sc_intf->write);
370 	if (rv)
371 		return rv;
372 
373 	return 0;
374 }
375 
376 static int
377 tpm_tis12_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count,
378     int flags)
379 {
380 	uint8_t *p = buf;
381 	size_t cnt;
382 	int rv, n;
383 
384 	cnt = 0;
385 	while (len > 0) {
386 		rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
387 		    TPM_READ_TMO, sc->sc_intf->read);
388 		if (rv)
389 			return rv;
390 
391 		n = MIN(len, tpm_getburst(sc));
392 		while (n > 0) {
393 			*p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA);
394 			cnt++;
395 			len--;
396 			n--;
397 		}
398 
399 		if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6)
400 			break;
401 	}
402 
403 	if (count)
404 		*count = cnt;
405 
406 	return 0;
407 }
408 
409 static int
410 tpm_tis12_write(struct tpm_softc *sc, const void *buf, size_t len)
411 {
412 	const uint8_t *p = buf;
413 	size_t cnt;
414 	int rv, r;
415 
416 	if (len == 0)
417 		return 0;
418 	if ((rv = tpm12_request_locality(sc, 0)) != 0)
419 		return rv;
420 
421 	cnt = 0;
422 	while (cnt < len - 1) {
423 		for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) {
424 			bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
425 			cnt++;
426 		}
427 		if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
428 			return rv;
429 		}
430 		sc->sc_status = tpm_status(sc);
431 		if (!(sc->sc_status & TPM_STS_DATA_EXPECT)) {
432 			return EIO;
433 		}
434 	}
435 
436 	bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
437 	cnt++;
438 
439 	if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
440 		return rv;
441 	}
442 	if ((sc->sc_status & TPM_STS_DATA_EXPECT) != 0) {
443 		return EIO;
444 	}
445 
446 	return 0;
447 }
448 
449 static int
450 tpm_tis12_end(struct tpm_softc *sc, int rw, int err)
451 {
452 	int rv = 0;
453 
454 	if (rw == UIO_READ) {
455 		rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc->sc_intf->read);
456 		if (rv)
457 			return rv;
458 
459 		/* Still more data? */
460 		sc->sc_status = tpm_status(sc);
461 		if (!err && (sc->sc_status & TPM_STS_DATA_AVAIL)) {
462 			rv = EIO;
463 		}
464 
465 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
466 		    TPM_STS_CMD_READY);
467 
468 		/* Release the 0th locality. */
469 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
470 		    TPM_ACCESS_ACTIVE_LOCALITY);
471 	} else {
472 		/* Hungry for more? */
473 		sc->sc_status = tpm_status(sc);
474 		if (!err && (sc->sc_status & TPM_STS_DATA_EXPECT)) {
475 			rv = EIO;
476 		}
477 
478 		bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
479 		    err ? TPM_STS_CMD_READY : TPM_STS_GO);
480 	}
481 
482 	return rv;
483 }
484 
485 const struct tpm_intf tpm_intf_tis12 = {
486 	.version = TIS_1_2,
487 	.probe = tpm_tis12_probe,
488 	.init = tpm_tis12_init,
489 	.start = tpm_tis12_start,
490 	.read = tpm_tis12_read,
491 	.write = tpm_tis12_write,
492 	.end = tpm_tis12_end
493 };
494 
495 /* -------------------------------------------------------------------------- */
496 
497 static dev_type_open(tpmopen);
498 static dev_type_close(tpmclose);
499 static dev_type_read(tpmread);
500 static dev_type_write(tpmwrite);
501 static dev_type_ioctl(tpmioctl);
502 
503 const struct cdevsw tpm_cdevsw = {
504 	.d_open = tpmopen,
505 	.d_close = tpmclose,
506 	.d_read = tpmread,
507 	.d_write = tpmwrite,
508 	.d_ioctl = tpmioctl,
509 	.d_stop = nostop,
510 	.d_tty = notty,
511 	.d_poll = nopoll,
512 	.d_mmap = nommap,
513 	.d_kqfilter = nokqfilter,
514 	.d_discard = nodiscard,
515 	.d_flag = D_OTHER | D_MPSAFE,
516 };
517 
518 static int
519 tpmopen(dev_t dev, int flag, int mode, struct lwp *l)
520 {
521 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
522 	int ret = 0;
523 
524 	if (sc == NULL)
525 		return ENXIO;
526 
527 	mutex_enter(&sc->sc_lock);
528 	if (sc->sc_busy) {
529 		ret = EBUSY;
530 	} else {
531 		sc->sc_busy = true;
532 	}
533 	mutex_exit(&sc->sc_lock);
534 
535 	return ret;
536 }
537 
538 static int
539 tpmclose(dev_t dev, int flag, int mode, struct lwp *l)
540 {
541 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
542 	int ret = 0;
543 
544 	if (sc == NULL)
545 		return ENXIO;
546 
547 	mutex_enter(&sc->sc_lock);
548 	if (!sc->sc_busy) {
549 		ret = EINVAL;
550 	} else {
551 		sc->sc_busy = false;
552 	}
553 	mutex_exit(&sc->sc_lock);
554 
555 	return ret;
556 }
557 
558 static int
559 tpmread(dev_t dev, struct uio *uio, int flags)
560 {
561 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
562 	struct tpm_header hdr;
563 	uint8_t buf[TPM_BUFSIZ];
564 	size_t cnt, len, n;
565 	int rv;
566 
567 	if (sc == NULL)
568 		return ENXIO;
569 
570 	if ((rv = (*sc->sc_intf->start)(sc, UIO_READ)))
571 		return rv;
572 
573 	/* Get the header. */
574 	if ((rv = (*sc->sc_intf->read)(sc, &hdr, sizeof(hdr), &cnt, 0))) {
575 		goto out;
576 	}
577 	len = TPM_BE32(hdr.length);
578 	if (len > uio->uio_resid || len < cnt) {
579 		rv = EIO;
580 		goto out;
581 	}
582 
583 	/* Copy out the header. */
584 	if ((rv = uiomove(&hdr, cnt, uio))) {
585 		goto out;
586 	}
587 
588 	/* Process the rest. */
589 	len -= cnt;
590 	while (len > 0) {
591 		n = MIN(sizeof(buf), len);
592 		if ((rv = (*sc->sc_intf->read)(sc, buf, n, NULL, TPM_PARAM_SIZE))) {
593 			goto out;
594 		}
595 		if ((rv = uiomove(buf, n, uio))) {
596 			goto out;
597 		}
598 		len -= n;
599 	}
600 
601 out:
602 	rv = (*sc->sc_intf->end)(sc, UIO_READ, rv);
603 	return rv;
604 }
605 
606 static int
607 tpmwrite(dev_t dev, struct uio *uio, int flags)
608 {
609 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
610 	uint8_t buf[TPM_BUFSIZ];
611 	int n, rv;
612 
613 	if (sc == NULL)
614 		return ENXIO;
615 
616 	n = MIN(sizeof(buf), uio->uio_resid);
617 	if ((rv = uiomove(buf, n, uio))) {
618 		goto out;
619 	}
620 	if ((rv = (*sc->sc_intf->start)(sc, UIO_WRITE))) {
621 		goto out;
622 	}
623 	if ((rv = (*sc->sc_intf->write)(sc, buf, n))) {
624 		goto out;
625 	}
626 
627 	rv = (*sc->sc_intf->end)(sc, UIO_WRITE, rv);
628 out:
629 	return rv;
630 }
631 
632 static int
633 tpmioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
634 {
635 	struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
636 	struct tpm_ioc_getinfo *info;
637 
638 	if (sc == NULL)
639 		return ENXIO;
640 
641 	switch (cmd) {
642 	case TPM_IOC_GETINFO:
643 		info = addr;
644 		info->api_version = TPM_API_VERSION;
645 		info->tpm_version = sc->sc_ver;
646 		info->itf_version = sc->sc_intf->version;
647 		info->device_id = sc->sc_devid;
648 		info->device_rev = sc->sc_rev;
649 		info->device_caps = sc->sc_caps;
650 		return 0;
651 	default:
652 		break;
653 	}
654 
655 	return ENOTTY;
656 }
657