diff options
-rw-r--r-- | drivers/ata/libata-core.c | 12 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 18 | ||||
-rw-r--r-- | drivers/ata/libata.h | 1 | ||||
-rw-r--r-- | include/linux/ata.h | 22 |
4 files changed, 51 insertions, 2 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 6380726f7538..9b7f3c477730 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -119,6 +119,10 @@ int libata_noacpi = 0; | |||
119 | module_param_named(noacpi, libata_noacpi, int, 0444); | 119 | module_param_named(noacpi, libata_noacpi, int, 0444); |
120 | MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in probe/suspend/resume when set"); | 120 | MODULE_PARM_DESC(noacpi, "Disables the use of ACPI in probe/suspend/resume when set"); |
121 | 121 | ||
122 | int libata_allow_tpm = 0; | ||
123 | module_param_named(allow_tpm, libata_allow_tpm, int, 0444); | ||
124 | MODULE_PARM_DESC(allow_tpm, "Permit the use of TPM commands"); | ||
125 | |||
122 | MODULE_AUTHOR("Jeff Garzik"); | 126 | MODULE_AUTHOR("Jeff Garzik"); |
123 | MODULE_DESCRIPTION("Library module for ATA devices"); | 127 | MODULE_DESCRIPTION("Library module for ATA devices"); |
124 | MODULE_LICENSE("GPL"); | 128 | MODULE_LICENSE("GPL"); |
@@ -2161,8 +2165,14 @@ int ata_dev_configure(struct ata_device *dev) | |||
2161 | "supports DRM functions and may " | 2165 | "supports DRM functions and may " |
2162 | "not be fully accessable.\n"); | 2166 | "not be fully accessable.\n"); |
2163 | snprintf(revbuf, 7, "CFA"); | 2167 | snprintf(revbuf, 7, "CFA"); |
2164 | } else | 2168 | } else { |
2165 | snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); | 2169 | snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); |
2170 | /* Warn the user if the device has TPM extensions */ | ||
2171 | if (ata_id_has_tpm(id)) | ||
2172 | ata_dev_printk(dev, KERN_WARNING, | ||
2173 | "supports DRM functions and may " | ||
2174 | "not be fully accessable.\n"); | ||
2175 | } | ||
2166 | 2176 | ||
2167 | dev->n_sectors = ata_id_n_sectors(id); | 2177 | dev->n_sectors = ata_id_n_sectors(id); |
2168 | 2178 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 14daf4848f09..f802dbce41ae 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -2690,6 +2690,24 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) | |||
2690 | if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) | 2690 | if ((tf->protocol = ata_scsi_map_proto(cdb[1])) == ATA_PROT_UNKNOWN) |
2691 | goto invalid_fld; | 2691 | goto invalid_fld; |
2692 | 2692 | ||
2693 | /* | ||
2694 | * Filter TPM commands by default. These provide an | ||
2695 | * essentially uncontrolled encrypted "back door" between | ||
2696 | * applications and the disk. Set libata.allow_tpm=1 if you | ||
2697 | * have a real reason for wanting to use them. This ensures | ||
2698 | * that installed software cannot easily mess stuff up without | ||
2699 | * user intent. DVR type users will probably ship with this enabled | ||
2700 | * for movie content management. | ||
2701 | * | ||
2702 | * Note that for ATA8 we can issue a DCS change and DCS freeze lock | ||
2703 | * for this and should do in future but that it is not sufficient as | ||
2704 | * DCS is an optional feature set. Thus we also do the software filter | ||
2705 | * so that we comply with the TC consortium stated goal that the user | ||
2706 | * can turn off TC features of their system. | ||
2707 | */ | ||
2708 | if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm) | ||
2709 | goto invalid_fld; | ||
2710 | |||
2693 | /* We may not issue DMA commands if no DMA mode is set */ | 2711 | /* We may not issue DMA commands if no DMA mode is set */ |
2694 | if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) | 2712 | if (tf->protocol == ATA_PROT_DMA && dev->dma_mode == 0) |
2695 | goto invalid_fld; | 2713 | goto invalid_fld; |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index bbe59c2fd1e2..048e26cfb339 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -60,6 +60,7 @@ extern int atapi_dmadir; | |||
60 | extern int atapi_passthru16; | 60 | extern int atapi_passthru16; |
61 | extern int libata_fua; | 61 | extern int libata_fua; |
62 | extern int libata_noacpi; | 62 | extern int libata_noacpi; |
63 | extern int libata_allow_tpm; | ||
63 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); | 64 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); |
64 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, | 65 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, |
65 | u64 block, u32 n_block, unsigned int tf_flags, | 66 | u64 block, u32 n_block, unsigned int tf_flags, |
diff --git a/include/linux/ata.h b/include/linux/ata.h index e672e80202a8..3fbe6d7784ab 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -379,7 +379,6 @@ struct ata_taskfile { | |||
379 | #define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) | 379 | #define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) |
380 | #define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) | 380 | #define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) |
381 | #define ata_id_removeable(id) ((id)[0] & (1 << 7)) | 381 | #define ata_id_removeable(id) ((id)[0] & (1 << 7)) |
382 | #define ata_id_has_dword_io(id) ((id)[48] & (1 << 0)) | ||
383 | #define ata_id_has_atapi_AN(id) \ | 382 | #define ata_id_has_atapi_AN(id) \ |
384 | ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ | 383 | ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \ |
385 | ((id)[78] & (1 << 5)) ) | 384 | ((id)[78] & (1 << 5)) ) |
@@ -415,6 +414,7 @@ static inline bool ata_id_has_dipm(const u16 *id) | |||
415 | return val & (1 << 3); | 414 | return val & (1 << 3); |
416 | } | 415 | } |
417 | 416 | ||
417 | |||
418 | static inline int ata_id_has_fua(const u16 *id) | 418 | static inline int ata_id_has_fua(const u16 *id) |
419 | { | 419 | { |
420 | if ((id[84] & 0xC000) != 0x4000) | 420 | if ((id[84] & 0xC000) != 0x4000) |
@@ -519,6 +519,26 @@ static inline int ata_id_is_sata(const u16 *id) | |||
519 | return ata_id_major_version(id) >= 5 && id[93] == 0; | 519 | return ata_id_major_version(id) >= 5 && id[93] == 0; |
520 | } | 520 | } |
521 | 521 | ||
522 | static inline int ata_id_has_tpm(const u16 *id) | ||
523 | { | ||
524 | /* The TPM bits are only valid on ATA8 */ | ||
525 | if (ata_id_major_version(id) < 8) | ||
526 | return 0; | ||
527 | if ((id[48] & 0xC000) != 0x4000) | ||
528 | return 0; | ||
529 | return id[48] & (1 << 0); | ||
530 | } | ||
531 | |||
532 | static inline int ata_id_has_dword_io(const u16 *id) | ||
533 | { | ||
534 | /* ATA 8 reuses this flag for "trusted" computing */ | ||
535 | if (ata_id_major_version(id) > 7) | ||
536 | return 0; | ||
537 | if (id[48] & (1 << 0)) | ||
538 | return 1; | ||
539 | return 0; | ||
540 | } | ||
541 | |||
522 | static inline int ata_id_current_chs_valid(const u16 *id) | 542 | static inline int ata_id_current_chs_valid(const u16 *id) |
523 | { | 543 | { |
524 | /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command | 544 | /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command |