Merge tag 'dlm-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm
[cascardo/linux.git] / drivers / char / tpm / tpm-interface.c
index 1abe2d7..8de6187 100644 (file)
@@ -330,13 +330,16 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 /*
  * Internal kernel interface to transmit TPM commands
  */
-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
-                    size_t bufsiz)
+ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
+                    unsigned int flags)
 {
        ssize_t rc;
        u32 count, ordinal;
        unsigned long stop;
 
+       if (bufsiz < TPM_HEADER_SIZE)
+               return -EINVAL;
+
        if (bufsiz > TPM_BUFSIZE)
                bufsiz = TPM_BUFSIZE;
 
@@ -350,7 +353,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                return -E2BIG;
        }
 
-       mutex_lock(&chip->tpm_mutex);
+       if (!(flags & TPM_TRANSMIT_UNLOCKED))
+               mutex_lock(&chip->tpm_mutex);
 
        rc = chip->ops->send(chip, (u8 *) buf, count);
        if (rc < 0) {
@@ -393,20 +397,21 @@ out_recv:
                dev_err(&chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
 out:
-       mutex_unlock(&chip->tpm_mutex);
+       if (!(flags & TPM_TRANSMIT_UNLOCKED))
+               mutex_unlock(&chip->tpm_mutex);
        return rc;
 }
 
 #define TPM_DIGEST_SIZE 20
 #define TPM_RET_CODE_IDX 6
 
-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
-                        int len, const char *desc)
+ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd,
+                        int len, unsigned int flags, const char *desc)
 {
-       struct tpm_output_header *header;
+       const struct tpm_output_header *header;
        int err;
 
-       len = tpm_transmit(chip, (u8 *) cmd, len);
+       len = tpm_transmit(chip, (const u8 *)cmd, len, flags);
        if (len <  0)
                return len;
        else if (len < TPM_HEADER_SIZE)
@@ -453,26 +458,13 @@ ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
                tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
                tpm_cmd.params.getcap_in.subcap = subcap_id;
        }
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
+       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+                             desc);
        if (!rc)
                *cap = tpm_cmd.params.getcap_out.cap;
        return rc;
 }
-
-void tpm_gen_interrupt(struct tpm_chip *chip)
-{
-       struct  tpm_cmd_t tpm_cmd;
-       ssize_t rc;
-
-       tpm_cmd.header.in = tpm_getcap_header;
-       tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
-       tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
-       tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
-
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
-                             "attempting to determine the timeouts");
-}
-EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+EXPORT_SYMBOL_GPL(tpm_getcap);
 
 #define TPM_ORD_STARTUP cpu_to_be32(153)
 #define TPM_ST_CLEAR cpu_to_be16(1)
@@ -490,7 +482,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
        start_cmd.header.in = tpm_startup_header;
 
        start_cmd.params.startup_in.startup_type = startup_type;
-       return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
+       return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
                                "attempting to start the TPM");
 }
 
@@ -521,7 +513,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
        tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
        tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
        tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL);
+       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+                             NULL);
 
        if (rc == TPM_ERR_INVALID_POSTINIT) {
                /* The TPM is not started, we are the first to talk to it.
@@ -535,7 +528,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
                tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
                tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
                rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
-                                 NULL);
+                                     0, NULL);
        }
        if (rc) {
                dev_err(&chip->dev,
@@ -596,7 +589,7 @@ duration:
        tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
        tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
 
-       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
                              "attempting to determine the durations");
        if (rc)
                return rc;
@@ -633,7 +626,7 @@ EXPORT_SYMBOL_GPL(tpm_get_timeouts);
 #define TPM_ORD_CONTINUE_SELFTEST 83
 #define CONTINUE_SELFTEST_RESULT_SIZE 10
 
-static struct tpm_input_header continue_selftest_header = {
+static const struct tpm_input_header continue_selftest_header = {
        .tag = TPM_TAG_RQU_COMMAND,
        .length = cpu_to_be32(10),
        .ordinal = cpu_to_be32(TPM_ORD_CONTINUE_SELFTEST),
@@ -652,14 +645,14 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
        struct tpm_cmd_t cmd;
 
        cmd.header.in = continue_selftest_header;
-       rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0,
                              "continue selftest");
        return rc;
 }
 
 #define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
 #define READ_PCR_RESULT_SIZE 30
-static struct tpm_input_header pcrread_header = {
+static const struct tpm_input_header pcrread_header = {
        .tag = TPM_TAG_RQU_COMMAND,
        .length = cpu_to_be32(14),
        .ordinal = TPM_ORDINAL_PCRREAD
@@ -672,7 +665,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 
        cmd.header.in = pcrread_header;
        cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
-       rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 0,
                              "attempting to read a pcr value");
 
        if (rc == 0)
@@ -745,7 +738,7 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
  */
 #define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
 #define EXTEND_PCR_RESULT_SIZE 34
-static struct tpm_input_header pcrextend_header = {
+static const struct tpm_input_header pcrextend_header = {
        .tag = TPM_TAG_RQU_COMMAND,
        .length = cpu_to_be32(34),
        .ordinal = TPM_ORD_PCR_EXTEND
@@ -770,7 +763,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
        cmd.header.in = pcrextend_header;
        cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
        memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
-       rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
+       rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
                              "attempting extend a PCR value");
 
        tpm_put_ops(chip);
@@ -792,7 +785,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
        unsigned int loops;
        unsigned int delay_msec = 100;
        unsigned long duration;
-       struct tpm_cmd_t cmd;
+       u8 dummy[TPM_DIGEST_SIZE];
 
        duration = tpm_calc_ordinal_duration(chip, TPM_ORD_CONTINUE_SELFTEST);
 
@@ -807,9 +800,8 @@ int tpm_do_selftest(struct tpm_chip *chip)
 
        do {
                /* Attempt to read a PCR value */
-               cmd.header.in = pcrread_header;
-               cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0);
-               rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE);
+               rc = tpm_pcr_read_dev(chip, 0, dummy);
+
                /* Some buggy TPMs will not respond to tpm_tis_ready() for
                 * around 300ms while the self test is ongoing, keep trying
                 * until the self test duration expires. */
@@ -824,7 +816,6 @@ int tpm_do_selftest(struct tpm_chip *chip)
                if (rc < TPM_HEADER_SIZE)
                        return -EFAULT;
 
-               rc = be32_to_cpu(cmd.header.out.return_code);
                if (rc == TPM_ERR_DISABLED || rc == TPM_ERR_DEACTIVATED) {
                        dev_info(&chip->dev,
                                 "TPM is disabled/deactivated (0x%X)\n", rc);
@@ -879,7 +870,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
        if (chip == NULL)
                return -ENODEV;
 
-       rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
+       rc = tpm_transmit_cmd(chip, cmd, buflen, 0, "attempting tpm_cmd");
 
        tpm_put_ops(chip);
        return rc;
@@ -949,7 +940,7 @@ EXPORT_SYMBOL_GPL(wait_for_tpm_stat);
 #define TPM_ORD_SAVESTATE cpu_to_be32(152)
 #define SAVESTATE_RESULT_SIZE 10
 
-static struct tpm_input_header savestate_header = {
+static const struct tpm_input_header savestate_header = {
        .tag = TPM_TAG_RQU_COMMAND,
        .length = cpu_to_be32(10),
        .ordinal = TPM_ORD_SAVESTATE
@@ -981,14 +972,15 @@ int tpm_pm_suspend(struct device *dev)
                cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
                memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
                       TPM_DIGEST_SIZE);
-               rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
+               rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
                                      "extending dummy pcr before suspend");
        }
 
        /* now do the actual savestate */
        for (try = 0; try < TPM_RETRY; try++) {
                cmd.header.in = savestate_header;
-               rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
+               rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0,
+                                     NULL);
 
                /*
                 * If the TPM indicates that it is too busy to respond to
@@ -1032,7 +1024,7 @@ int tpm_pm_resume(struct device *dev)
 EXPORT_SYMBOL_GPL(tpm_pm_resume);
 
 #define TPM_GETRANDOM_RESULT_SIZE      18
-static struct tpm_input_header tpm_getrandom_header = {
+static const struct tpm_input_header tpm_getrandom_header = {
        .tag = TPM_TAG_RQU_COMMAND,
        .length = cpu_to_be32(14),
        .ordinal = TPM_ORD_GET_RANDOM
@@ -1072,8 +1064,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
                tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
 
                err = tpm_transmit_cmd(chip, &tpm_cmd,
-                                  TPM_GETRANDOM_RESULT_SIZE + num_bytes,
-                                  "attempting get random");
+                                      TPM_GETRANDOM_RESULT_SIZE + num_bytes,
+                                      0, "attempting get random");
                if (err)
                        break;