diff options
| author | James Morris <james.l.morris@oracle.com> | 2012-10-11 06:41:29 -0400 |
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2012-10-11 06:41:29 -0400 |
| commit | 59b69ac2bad602d02904d310ee156e47e74d8109 (patch) | |
| tree | 0111734ea6331072d4991f9b6fb53c996a96bf79 | |
| parent | bb95a0d73bb69d73c16d32c10a0c31a32abddb03 (diff) | |
| parent | abce9ac292e13da367bbd22c1f7669f988d931ac (diff) | |
Merge branch 'tpmdd-next-v3.6' of git://github.com/shpedoikal/linux into for-linus
| -rw-r--r-- | drivers/char/tpm/tpm.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index b429f1ea1b97..93211df52aab 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
| @@ -1182,17 +1182,20 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
| 1182 | size_t size, loff_t *off) | 1182 | size_t size, loff_t *off) |
| 1183 | { | 1183 | { |
| 1184 | struct tpm_chip *chip = file->private_data; | 1184 | struct tpm_chip *chip = file->private_data; |
| 1185 | size_t in_size = size, out_size; | 1185 | size_t in_size = size; |
| 1186 | ssize_t out_size; | ||
| 1186 | 1187 | ||
| 1187 | /* cannot perform a write until the read has cleared | 1188 | /* cannot perform a write until the read has cleared |
| 1188 | either via tpm_read or a user_read_timer timeout */ | 1189 | either via tpm_read or a user_read_timer timeout. |
| 1189 | while (atomic_read(&chip->data_pending) != 0) | 1190 | This also prevents splitted buffered writes from blocking here. |
| 1190 | msleep(TPM_TIMEOUT); | 1191 | */ |
| 1191 | 1192 | if (atomic_read(&chip->data_pending) != 0) | |
| 1192 | mutex_lock(&chip->buffer_mutex); | 1193 | return -EBUSY; |
| 1193 | 1194 | ||
| 1194 | if (in_size > TPM_BUFSIZE) | 1195 | if (in_size > TPM_BUFSIZE) |
| 1195 | in_size = TPM_BUFSIZE; | 1196 | return -E2BIG; |
| 1197 | |||
| 1198 | mutex_lock(&chip->buffer_mutex); | ||
| 1196 | 1199 | ||
| 1197 | if (copy_from_user | 1200 | if (copy_from_user |
| 1198 | (chip->data_buffer, (void __user *) buf, in_size)) { | 1201 | (chip->data_buffer, (void __user *) buf, in_size)) { |
| @@ -1202,6 +1205,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
| 1202 | 1205 | ||
| 1203 | /* atomic tpm command send and result receive */ | 1206 | /* atomic tpm command send and result receive */ |
| 1204 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); | 1207 | out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); |
| 1208 | if (out_size < 0) { | ||
| 1209 | mutex_unlock(&chip->buffer_mutex); | ||
| 1210 | return out_size; | ||
| 1211 | } | ||
| 1205 | 1212 | ||
| 1206 | atomic_set(&chip->data_pending, out_size); | 1213 | atomic_set(&chip->data_pending, out_size); |
| 1207 | mutex_unlock(&chip->buffer_mutex); | 1214 | mutex_unlock(&chip->buffer_mutex); |
