Page MenuHomeFreeBSD

D52328.id171895.diff
No OneTemporary

D52328.id171895.diff

diff --git a/sys/dev/tpm/tpm20.h b/sys/dev/tpm/tpm20.h
--- a/sys/dev/tpm/tpm20.h
+++ b/sys/dev/tpm/tpm20.h
@@ -105,6 +105,12 @@
MALLOC_DECLARE(M_TPM20);
+struct tpm_priv {
+ uint8_t buf[TPM_BUFSIZE];
+ size_t offset;
+ size_t len;
+};
+
struct tpm_sc {
device_t dev;
@@ -116,18 +122,13 @@
struct cdev *sc_cdev;
struct sx dev_lock;
- struct cv buf_cv;
void *intr_cookie;
int intr_type; /* Current event type */
bool interrupts;
- uint8_t *buf;
- size_t pending_data_length;
- size_t total_length;
- lwpid_t owner_tid;
+ struct tpm_priv *internal_priv;
- struct callout discard_buffer_callout;
#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM
struct timeout_task harvest_task;
#endif
diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c
--- a/sys/dev/tpm/tpm20.c
+++ b/sys/dev/tpm/tpm20.c
@@ -67,25 +67,21 @@
tpm20_read(struct cdev *dev, struct uio *uio, int flags)
{
struct tpm_sc *sc;
+ struct tpm_priv *priv;
size_t bytes_to_transfer;
size_t offset;
int result = 0;
sc = (struct tpm_sc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&priv);
- callout_stop(&sc->discard_buffer_callout);
sx_xlock(&sc->dev_lock);
- if (sc->owner_tid != uio->uio_td->td_tid) {
- sx_xunlock(&sc->dev_lock);
- return (EPERM);
- }
-
- bytes_to_transfer = MIN(sc->pending_data_length, uio->uio_resid);
- offset = sc->total_length - sc->pending_data_length;
+ offset = priv->offset;
+ bytes_to_transfer = MIN(priv->len, uio->uio_resid);
if (bytes_to_transfer > 0) {
- result = uiomove((caddr_t) sc->buf + offset, bytes_to_transfer, uio);
- sc->pending_data_length -= bytes_to_transfer;
- cv_signal(&sc->buf_cv);
+ result = uiomove((caddr_t) priv->buf + offset, bytes_to_transfer, uio);
+ priv->offset += bytes_to_transfer;
+ priv->len -= bytes_to_transfer;
} else {
result = ETIMEDOUT;
}
@@ -99,10 +95,12 @@
tpm20_write(struct cdev *dev, struct uio *uio, int flags)
{
struct tpm_sc *sc;
+ struct tpm_priv *priv;
size_t byte_count;
int result = 0;
sc = (struct tpm_sc *)dev->si_drv1;
+ devfs_get_cdevpriv((void **)&priv);
byte_count = uio->uio_resid;
if (byte_count < TPM_HEADER_SIZE) {
@@ -119,52 +117,42 @@
sx_xlock(&sc->dev_lock);
- while (sc->pending_data_length != 0)
- cv_wait(&sc->buf_cv, &sc->dev_lock);
-
- result = uiomove(sc->buf, byte_count, uio);
+ result = uiomove(priv->buf, byte_count, uio);
if (result != 0) {
sx_xunlock(&sc->dev_lock);
return (result);
}
- result = TPM_TRANSMIT(sc->dev, byte_count);
-
- if (result == 0) {
- callout_reset(&sc->discard_buffer_callout,
- TPM_READ_TIMEOUT / tick, tpm20_discard_buffer, sc);
- sc->owner_tid = uio->uio_td->td_tid;
- }
+ result = TPM_TRANSMIT(sc->dev, priv, byte_count);
sx_xunlock(&sc->dev_lock);
return (result);
}
-static void
-tpm20_discard_buffer(void *arg)
+static struct tpm_priv *
+tpm20_priv_alloc(void)
{
- struct tpm_sc *sc;
-
- sc = (struct tpm_sc *)arg;
- if (callout_pending(&sc->discard_buffer_callout))
- return;
+ struct tpm_priv *priv;
- sx_xlock(&sc->dev_lock);
-
- memset(sc->buf, 0, TPM_BUFSIZE);
- sc->pending_data_length = 0;
- sc->total_length = 0;
+ priv = malloc(sizeof (*priv), M_TPM20, M_WAITOK | M_ZERO);
+ return (priv);
+}
- cv_signal(&sc->buf_cv);
- sx_xunlock(&sc->dev_lock);
+static void
+tpm20_priv_dtor(void *data)
+{
+ struct tpm_priv *priv = data;
- device_printf(sc->dev,
- "User failed to read buffer in time\n");
+ free(priv->buf, M_TPM20);
}
int
tpm20_open(struct cdev *dev, int flag, int mode, struct thread *td)
{
+ struct tpm_priv *priv;
+
+ priv = tpm20_priv_alloc();
+ devfs_set_cdevpriv(priv, tpm20_priv_dtor);
return (0);
}
@@ -197,10 +185,7 @@
struct make_dev_args args;
int result;
- cv_init(&sc->buf_cv, "TPM buffer cv");
- callout_init(&sc->discard_buffer_callout, 1);
- sc->pending_data_length = 0;
- sc->total_length = 0;
+ sc->internal_priv = tpm20_priv_alloc();
make_dev_args_init(&args);
args.mda_devsw = &tpm20_cdevsw;
@@ -233,11 +218,8 @@
random_source_deregister(&random_tpm);
#endif
- if (sc->buf != NULL)
- free(sc->buf, M_TPM20);
-
+ tpm20_priv_dtor(sc->internal_priv);
sx_destroy(&sc->dev_lock);
- cv_destroy(&sc->buf_cv);
if (sc->sc_cdev != NULL)
destroy_dev(sc->sc_cdev);
}
@@ -263,6 +245,7 @@
tpm20_harvest(void *arg, int unused)
{
struct tpm_sc *sc;
+ struct tpm_priv *priv;
unsigned char entropy[TPM_HARVEST_SIZE];
uint16_t entropy_size;
int result;
@@ -275,26 +258,22 @@
sc = arg;
sx_xlock(&sc->dev_lock);
- while (sc->pending_data_length != 0)
- cv_wait(&sc->buf_cv, &sc->dev_lock);
- memcpy(sc->buf, cmd, sizeof(cmd));
- result = TPM_TRANSMIT(sc->dev, sizeof(cmd));
+ priv = sc->internal_priv;
+ memcpy(priv->buf, cmd, sizeof(cmd));
+
+ result = TPM_TRANSMIT(sc->dev, priv, sizeof(cmd));
if (result != 0) {
sx_xunlock(&sc->dev_lock);
return;
}
- /* Ignore response size */
- sc->pending_data_length = 0;
- sc->total_length = 0;
-
/* The number of random bytes we got is placed right after the header */
- entropy_size = (uint16_t) sc->buf[TPM_HEADER_SIZE + 1];
+ entropy_size = (uint16_t) priv->buf[TPM_HEADER_SIZE + 1];
if (entropy_size > 0) {
entropy_size = MIN(entropy_size, TPM_HARVEST_SIZE);
memcpy(entropy,
- sc->buf + TPM_HEADER_SIZE + sizeof(uint16_t),
+ priv->buf + TPM_HEADER_SIZE + sizeof(uint16_t),
entropy_size);
}
@@ -311,6 +290,7 @@
tpm20_save_state(device_t dev, bool suspend)
{
struct tpm_sc *sc;
+ struct tpm_priv *priv;
uint8_t save_cmd[] = {
0x80, 0x01, /* TPM_ST_NO_SESSIONS tag*/
0x00, 0x00, 0x00, 0x0C, /* cmd length */
@@ -326,13 +306,14 @@
if (suspend)
save_cmd[11] = 1; /* TPM_SU_STATE */
- if (sc == NULL || sc->buf == NULL)
+ if (sc == NULL)
return (0);
sx_xlock(&sc->dev_lock);
- memcpy(sc->buf, save_cmd, sizeof(save_cmd));
- TPM_TRANSMIT(sc->dev, sizeof(save_cmd));
+ priv = sc->internal_priv;
+ memcpy(priv->buf, save_cmd, sizeof(save_cmd));
+ TPM_TRANSMIT(sc->dev, priv, sizeof(save_cmd));
sx_xunlock(&sc->dev_lock);
diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c
--- a/sys/dev/tpm/tpm_crb.c
+++ b/sys/dev/tpm/tpm_crb.c
@@ -127,7 +127,7 @@
size_t rsp_buf_size;
};
-int tpmcrb_transmit(device_t dev, size_t size);
+int tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t size);
static int tpmcrb_acpi_probe(device_t dev);
static int tpmcrb_attach(device_t dev);
@@ -257,7 +257,6 @@
sc->dev = dev;
sx_init(&sc->dev_lock, "TPM driver lock");
- sc->buf = malloc(TPM_BUFSIZE, M_TPM20, M_WAITOK);
sc->mem_rid = 0;
sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
@@ -480,7 +479,7 @@
}
int
-tpmcrb_transmit(device_t dev, size_t length)
+tpmcrb_transmit(device_t dev, struct tpm_priv *priv, size_t length)
{
struct tpmcrb_sc *crb_sc;
struct tpm_sc *sc;
@@ -531,12 +530,12 @@
* Calculate timeout for current command.
* Command code is passed in bytes 6-10.
*/
- curr_cmd = be32toh(*(uint32_t *) (&sc->buf[6]));
+ curr_cmd = be32toh(*(uint32_t *) (&priv->buf[6]));
timeout = tpm20_get_timeout(curr_cmd);
/* Send command and tell device to process it. */
bus_write_region_stream_1(sc->mem_res, crb_sc->cmd_off,
- sc->buf, length);
+ priv->buf, length);
TPM_WRITE_BARRIER(dev, crb_sc->cmd_off, length);
TPM_WRITE_4(dev, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD);
@@ -559,8 +558,8 @@
/* Read response header. Length is passed in bytes 2 - 6. */
bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off,
- sc->buf, TPM_HEADER_SIZE);
- bytes_available = be32toh(*(uint32_t *) (&sc->buf[2]));
+ priv->buf, TPM_HEADER_SIZE);
+ bytes_available = be32toh(*(uint32_t *) (&priv->buf[2]));
if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
device_printf(dev,
@@ -570,7 +569,7 @@
}
bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE,
- &sc->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
+ &priv->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
/*
* No need to wait for the transition to idle on the way out, we can
@@ -583,8 +582,8 @@
}
tpmcrb_relinquish_locality(sc);
- sc->pending_data_length = bytes_available;
- sc->total_length = bytes_available;
+ priv->offset = 0;
+ priv->len = bytes_available;
return (0);
}
diff --git a/sys/dev/tpm/tpm_if.m b/sys/dev/tpm/tpm_if.m
--- a/sys/dev/tpm/tpm_if.m
+++ b/sys/dev/tpm/tpm_if.m
@@ -28,6 +28,10 @@
#include <sys/bus.h>
#include <dev/tpm/tpm20.h>
+HEADER {
+ struct tpm_priv;
+};
+
INTERFACE tpm;
#
@@ -35,6 +39,7 @@
#
METHOD int transmit {
device_t dev;
+ struct tpm_priv *priv;
size_t length;
};
diff --git a/sys/dev/tpm/tpm_tis_core.c b/sys/dev/tpm/tpm_tis_core.c
--- a/sys/dev/tpm/tpm_tis_core.c
+++ b/sys/dev/tpm/tpm_tis_core.c
@@ -73,7 +73,7 @@
#define TPM_STS_BURST_MASK 0xFFFF00
#define TPM_STS_BURST_OFFSET 0x8
-static int tpmtis_transmit(device_t dev, size_t length);
+static int tpmtis_transmit(device_t dev, struct tpm_priv *priv, size_t length);
static int tpmtis_detach(device_t dev);
@@ -104,7 +104,6 @@
sc->intr_type = -1;
sx_init(&sc->dev_lock, "TPM driver lock");
- sc->buf = malloc(TPM_BUFSIZE, M_TPM20, M_WAITOK);
resource_int_value("tpm", device_get_unit(dev), "use_polling", &poll);
if (poll != 0) {
@@ -164,6 +163,7 @@
static void
tpmtis_test_intr(struct tpm_sc *sc)
{
+ struct tpm_priv *priv;
uint8_t cmd[] = {
0x80, 0x01, /* TPM_ST_NO_SESSIONS tag*/
0x00, 0x00, 0x00, 0x0c, /* cmd length */
@@ -172,9 +172,9 @@
};
sx_xlock(&sc->dev_lock);
- memcpy(sc->buf, cmd, sizeof(cmd));
- tpmtis_transmit(sc->dev, sizeof(cmd));
- sc->pending_data_length = 0;
+ priv = sc->internal_priv;
+ memcpy(priv->buf, cmd, sizeof(cmd));
+ tpmtis_transmit(sc->dev, priv, sizeof(cmd));
sx_xunlock(&sc->dev_lock);
}
@@ -384,7 +384,7 @@
}
static int
-tpmtis_transmit(device_t dev, size_t length)
+tpmtis_transmit(device_t dev, struct tpm_priv *priv, size_t length)
{
struct tpm_sc *sc;
size_t bytes_available;
@@ -404,7 +404,7 @@
"Failed to switch to ready state\n");
return (EIO);
}
- if (!tpmtis_write_bytes(sc, length, sc->buf)) {
+ if (!tpmtis_write_bytes(sc, length, priv->buf)) {
device_printf(dev,
"Failed to write cmd to device\n");
return (EIO);
@@ -428,7 +428,7 @@
* Calculate timeout for current command.
* Command code is passed in bytes 6-10.
*/
- curr_cmd = be32toh(*(uint32_t *) (&sc->buf[6]));
+ curr_cmd = be32toh(*(uint32_t *) (&priv->buf[6]));
timeout = tpm20_get_timeout(curr_cmd);
TPM_WRITE_4(dev, TPM_STS, TPM_STS_CMD_START);
@@ -455,12 +455,12 @@
return (EIO);
}
/* Read response header. Length is passed in bytes 2 - 6. */
- if(!tpmtis_read_bytes(sc, TPM_HEADER_SIZE, sc->buf)) {
+ if (!tpmtis_read_bytes(sc, TPM_HEADER_SIZE, priv->buf)) {
device_printf(dev,
"Failed to read response header\n");
return (EIO);
}
- bytes_available = be32toh(*(uint32_t *) (&sc->buf[2]));
+ bytes_available = be32toh(*(uint32_t *) (&priv->buf[2]));
if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
device_printf(dev,
@@ -468,15 +468,15 @@
bytes_available);
return (EIO);
}
- if(!tpmtis_read_bytes(sc, bytes_available - TPM_HEADER_SIZE,
- &sc->buf[TPM_HEADER_SIZE])) {
+ if (!tpmtis_read_bytes(sc, bytes_available - TPM_HEADER_SIZE,
+ &priv->buf[TPM_HEADER_SIZE])) {
device_printf(dev,
"Failed to read response\n");
return (EIO);
}
tpmtis_relinquish_locality(sc);
- sc->pending_data_length = bytes_available;
- sc->total_length = bytes_available;
+ priv->offset = 0;
+ priv->len = bytes_available;
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 15, 11:24 AM (3 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28739051
Default Alt Text
D52328.id171895.diff (11 KB)

Event Timeline