diff options
| -rw-r--r-- | drivers/char/tpm/tpm.c | 24 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm.h | 9 | ||||
| -rw-r--r-- | drivers/char/tpm/tpm_ppi.c | 18 |
3 files changed, 33 insertions, 18 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index f26afdb1a702..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); |
| @@ -1259,6 +1266,7 @@ void tpm_remove_hardware(struct device *dev) | |||
| 1259 | 1266 | ||
| 1260 | misc_deregister(&chip->vendor.miscdev); | 1267 | misc_deregister(&chip->vendor.miscdev); |
| 1261 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); | 1268 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); |
| 1269 | tpm_remove_ppi(&dev->kobj); | ||
| 1262 | tpm_bios_log_teardown(chip->bios_dir); | 1270 | tpm_bios_log_teardown(chip->bios_dir); |
| 1263 | 1271 | ||
| 1264 | /* write it this way to be explicit (chip->dev == dev) */ | 1272 | /* write it this way to be explicit (chip->dev == dev) */ |
| @@ -1476,7 +1484,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, | |||
| 1476 | goto put_device; | 1484 | goto put_device; |
| 1477 | } | 1485 | } |
| 1478 | 1486 | ||
| 1479 | if (sys_add_ppi(&dev->kobj)) { | 1487 | if (tpm_add_ppi(&dev->kobj)) { |
| 1480 | misc_deregister(&chip->vendor.miscdev); | 1488 | misc_deregister(&chip->vendor.miscdev); |
| 1481 | goto put_device; | 1489 | goto put_device; |
| 1482 | } | 1490 | } |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 02c266aa2bf7..8ef7649a50aa 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
| @@ -329,10 +329,15 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, | |||
| 329 | wait_queue_head_t *); | 329 | wait_queue_head_t *); |
| 330 | 330 | ||
| 331 | #ifdef CONFIG_ACPI | 331 | #ifdef CONFIG_ACPI |
| 332 | extern ssize_t sys_add_ppi(struct kobject *parent); | 332 | extern int tpm_add_ppi(struct kobject *); |
| 333 | extern void tpm_remove_ppi(struct kobject *); | ||
| 333 | #else | 334 | #else |
| 334 | static inline ssize_t sys_add_ppi(struct kobject *parent) | 335 | static inline int tpm_add_ppi(struct kobject *parent) |
| 335 | { | 336 | { |
| 336 | return 0; | 337 | return 0; |
| 337 | } | 338 | } |
| 339 | |||
| 340 | static inline void tpm_remove_ppi(struct kobject *parent) | ||
| 341 | { | ||
| 342 | } | ||
| 338 | #endif | 343 | #endif |
diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index f27b58cfae98..720ebcf29fdf 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c | |||
| @@ -444,18 +444,20 @@ static struct attribute *ppi_attrs[] = { | |||
| 444 | &dev_attr_vs_operations.attr, NULL, | 444 | &dev_attr_vs_operations.attr, NULL, |
| 445 | }; | 445 | }; |
| 446 | static struct attribute_group ppi_attr_grp = { | 446 | static struct attribute_group ppi_attr_grp = { |
| 447 | .name = "ppi", | ||
| 447 | .attrs = ppi_attrs | 448 | .attrs = ppi_attrs |
| 448 | }; | 449 | }; |
| 449 | 450 | ||
| 450 | ssize_t sys_add_ppi(struct kobject *parent) | 451 | int tpm_add_ppi(struct kobject *parent) |
| 451 | { | 452 | { |
| 452 | struct kobject *ppi; | 453 | return sysfs_create_group(parent, &ppi_attr_grp); |
| 453 | ppi = kobject_create_and_add("ppi", parent); | 454 | } |
| 454 | if (sysfs_create_group(ppi, &ppi_attr_grp)) | 455 | EXPORT_SYMBOL_GPL(tpm_add_ppi); |
| 455 | return -EFAULT; | 456 | |
| 456 | else | 457 | void tpm_remove_ppi(struct kobject *parent) |
| 457 | return 0; | 458 | { |
| 459 | sysfs_remove_group(parent, &ppi_attr_grp); | ||
| 458 | } | 460 | } |
| 459 | EXPORT_SYMBOL_GPL(sys_add_ppi); | 461 | EXPORT_SYMBOL_GPL(tpm_remove_ppi); |
| 460 | 462 | ||
| 461 | MODULE_LICENSE("GPL"); | 463 | MODULE_LICENSE("GPL"); |
