@@ -430,17 +430,27 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
430430#define TPM_GET_CAP_RET_UINT32_2_IDX 18
431431#define TPM_GET_CAP_RET_UINT32_3_IDX 22
432432#define TPM_GET_CAP_RET_UINT32_4_IDX 26
433+ #define TPM_GET_CAP_PERM_DISABLE_IDX 16
434+ #define TPM_GET_CAP_PERM_INACTIVE_IDX 18
435+ #define TPM_GET_CAP_RET_BOOL_1_IDX 14
436+ #define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
433437
434438#define TPM_CAP_IDX 13
435439#define TPM_CAP_SUBCAP_IDX 21
436440
437441enum tpm_capabilities {
442+ TPM_CAP_FLAG = 4 ,
438443 TPM_CAP_PROP = 5 ,
439444};
440445
441446enum tpm_sub_capabilities {
442447 TPM_CAP_PROP_PCR = 0x1 ,
443448 TPM_CAP_PROP_MANUFACTURER = 0x3 ,
449+ TPM_CAP_FLAG_PERM = 0x8 ,
450+ TPM_CAP_FLAG_VOL = 0x9 ,
451+ TPM_CAP_PROP_OWNER = 0x11 ,
452+ TPM_CAP_PROP_TIS_TIMEOUT = 0x15 ,
453+ TPM_CAP_PROP_TIS_DURATION = 0x20 ,
444454};
445455
446456/*
@@ -474,6 +484,180 @@ static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
474484 return 0 ;
475485}
476486
487+ void tpm_gen_interrupt (struct tpm_chip * chip )
488+ {
489+ u8 data [max_t (int , ARRAY_SIZE (tpm_cap ), 30 )];
490+ ssize_t rc ;
491+
492+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
493+ data [TPM_CAP_IDX ] = TPM_CAP_PROP ;
494+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_PROP_TIS_TIMEOUT ;
495+
496+ rc = transmit_cmd (chip , data , sizeof (data ),
497+ "attempting to determine the timeouts" );
498+ }
499+ EXPORT_SYMBOL_GPL (tpm_gen_interrupt );
500+
501+ void tpm_get_timeouts (struct tpm_chip * chip )
502+ {
503+ u8 data [max_t (int , ARRAY_SIZE (tpm_cap ), 30 )];
504+ ssize_t rc ;
505+ u32 timeout ;
506+
507+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
508+ data [TPM_CAP_IDX ] = TPM_CAP_PROP ;
509+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_PROP_TIS_TIMEOUT ;
510+
511+ rc = transmit_cmd (chip , data , sizeof (data ),
512+ "attempting to determine the timeouts" );
513+ if (rc )
514+ goto duration ;
515+
516+ if (be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_SIZE_IDX )))
517+ != 4 * sizeof (u32 ))
518+ goto duration ;
519+
520+ /* Don't overwrite default if value is 0 */
521+ timeout =
522+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_1_IDX )));
523+ if (timeout )
524+ chip -> vendor .timeout_a = timeout ;
525+ timeout =
526+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_2_IDX )));
527+ if (timeout )
528+ chip -> vendor .timeout_b = timeout ;
529+ timeout =
530+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_3_IDX )));
531+ if (timeout )
532+ chip -> vendor .timeout_c = timeout ;
533+ timeout =
534+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_4_IDX )));
535+ if (timeout )
536+ chip -> vendor .timeout_d = timeout ;
537+
538+ duration :
539+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
540+ data [TPM_CAP_IDX ] = TPM_CAP_PROP ;
541+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_PROP_TIS_DURATION ;
542+
543+ rc = transmit_cmd (chip , data , sizeof (data ),
544+ "attempting to determine the durations" );
545+ if (rc )
546+ return ;
547+
548+ if (be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_SIZE_IDX )))
549+ != 3 * sizeof (u32 ))
550+ return ;
551+
552+ chip -> vendor .duration [TPM_SHORT ] =
553+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_1_IDX )));
554+ chip -> vendor .duration [TPM_MEDIUM ] =
555+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_2_IDX )));
556+ chip -> vendor .duration [TPM_LONG ] =
557+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_3_IDX )));
558+ }
559+ EXPORT_SYMBOL_GPL (tpm_get_timeouts );
560+
561+ void tpm_continue_selftest (struct tpm_chip * chip )
562+ {
563+ u8 data [] = {
564+ 0 , 193 , /* TPM_TAG_RQU_COMMAND */
565+ 0 , 0 , 0 , 10 , /* length */
566+ 0 , 0 , 0 , 83 , /* TPM_ORD_GetCapability */
567+ };
568+
569+ tpm_transmit (chip , data , sizeof (data ));
570+ }
571+ EXPORT_SYMBOL_GPL (tpm_continue_selftest );
572+
573+ ssize_t tpm_show_enabled (struct device * dev , struct device_attribute * attr ,
574+ char * buf )
575+ {
576+ u8 data [max_t (int , ARRAY_SIZE (tpm_cap ), 35 )];
577+ ssize_t rc ;
578+
579+ struct tpm_chip * chip = dev_get_drvdata (dev );
580+ if (chip == NULL )
581+ return - ENODEV ;
582+
583+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
584+ data [TPM_CAP_IDX ] = TPM_CAP_FLAG ;
585+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_FLAG_PERM ;
586+
587+ rc = transmit_cmd (chip , data , sizeof (data ),
588+ "attemtping to determine the permanent state" );
589+ if (rc )
590+ return 0 ;
591+ return sprintf (buf , "%d\n" , !data [TPM_GET_CAP_PERM_DISABLE_IDX ]);
592+ }
593+ EXPORT_SYMBOL_GPL (tpm_show_enabled );
594+
595+ ssize_t tpm_show_active (struct device * dev , struct device_attribute * attr ,
596+ char * buf )
597+ {
598+ u8 data [max_t (int , ARRAY_SIZE (tpm_cap ), 35 )];
599+ ssize_t rc ;
600+
601+ struct tpm_chip * chip = dev_get_drvdata (dev );
602+ if (chip == NULL )
603+ return - ENODEV ;
604+
605+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
606+ data [TPM_CAP_IDX ] = TPM_CAP_FLAG ;
607+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_FLAG_PERM ;
608+
609+ rc = transmit_cmd (chip , data , sizeof (data ),
610+ "attemtping to determine the permanent state" );
611+ if (rc )
612+ return 0 ;
613+ return sprintf (buf , "%d\n" , !data [TPM_GET_CAP_PERM_INACTIVE_IDX ]);
614+ }
615+ EXPORT_SYMBOL_GPL (tpm_show_active );
616+
617+ ssize_t tpm_show_owned (struct device * dev , struct device_attribute * attr ,
618+ char * buf )
619+ {
620+ u8 data [sizeof (tpm_cap )];
621+ ssize_t rc ;
622+
623+ struct tpm_chip * chip = dev_get_drvdata (dev );
624+ if (chip == NULL )
625+ return - ENODEV ;
626+
627+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
628+ data [TPM_CAP_IDX ] = TPM_CAP_PROP ;
629+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_PROP_OWNER ;
630+
631+ rc = transmit_cmd (chip , data , sizeof (data ),
632+ "attempting to determine the owner state" );
633+ if (rc )
634+ return 0 ;
635+ return sprintf (buf , "%d\n" , data [TPM_GET_CAP_RET_BOOL_1_IDX ]);
636+ }
637+ EXPORT_SYMBOL_GPL (tpm_show_owned );
638+
639+ ssize_t tpm_show_temp_deactivated (struct device * dev ,
640+ struct device_attribute * attr , char * buf )
641+ {
642+ u8 data [sizeof (tpm_cap )];
643+ ssize_t rc ;
644+
645+ struct tpm_chip * chip = dev_get_drvdata (dev );
646+ if (chip == NULL )
647+ return - ENODEV ;
648+
649+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
650+ data [TPM_CAP_IDX ] = TPM_CAP_FLAG ;
651+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_FLAG_VOL ;
652+
653+ rc = transmit_cmd (chip , data , sizeof (data ),
654+ "attempting to determine the temporary state" );
655+ if (rc )
656+ return 0 ;
657+ return sprintf (buf , "%d\n" , data [TPM_GET_CAP_TEMP_INACTIVE_IDX ]);
658+ }
659+ EXPORT_SYMBOL_GPL (tpm_show_temp_deactivated );
660+
477661static const u8 pcrread [] = {
478662 0 , 193 , /* TPM_TAG_RQU_COMMAND */
479663 0 , 0 , 0 , 14 , /* length */
@@ -484,7 +668,7 @@ static const u8 pcrread[] = {
484668ssize_t tpm_show_pcrs (struct device * dev , struct device_attribute * attr ,
485669 char * buf )
486670{
487- u8 data [30 ];
671+ u8 data [max_t ( int , max ( ARRAY_SIZE ( tpm_cap ), ARRAY_SIZE ( pcrread )), 30 ) ];
488672 ssize_t rc ;
489673 int i , j , num_pcrs ;
490674 __be32 index ;
@@ -588,6 +772,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
588772EXPORT_SYMBOL_GPL (tpm_show_pubek );
589773
590774#define CAP_VERSION_1_1 6
775+ #define CAP_VERSION_1_2 0x1A
591776#define CAP_VERSION_IDX 13
592777static const u8 cap_version [] = {
593778 0 , 193 , /* TPM_TAG_RQU_COMMAND */
@@ -600,7 +785,7 @@ static const u8 cap_version[] = {
600785ssize_t tpm_show_caps (struct device * dev , struct device_attribute * attr ,
601786 char * buf )
602787{
603- u8 data [30 ];
788+ u8 data [max_t ( int , max ( ARRAY_SIZE ( tpm_cap ), ARRAY_SIZE ( cap_version )), 30 ) ];
604789 ssize_t rc ;
605790 char * str = buf ;
606791
@@ -637,6 +822,52 @@ ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
637822}
638823EXPORT_SYMBOL_GPL (tpm_show_caps );
639824
825+ ssize_t tpm_show_caps_1_2 (struct device * dev ,
826+ struct device_attribute * attr , char * buf )
827+ {
828+ u8 data [max_t (int , max (ARRAY_SIZE (tpm_cap ), ARRAY_SIZE (cap_version )), 30 )];
829+ ssize_t len ;
830+ char * str = buf ;
831+
832+ struct tpm_chip * chip = dev_get_drvdata (dev );
833+ if (chip == NULL )
834+ return - ENODEV ;
835+
836+ memcpy (data , tpm_cap , sizeof (tpm_cap ));
837+ data [TPM_CAP_IDX ] = TPM_CAP_PROP ;
838+ data [TPM_CAP_SUBCAP_IDX ] = TPM_CAP_PROP_MANUFACTURER ;
839+
840+ if ((len = tpm_transmit (chip , data , sizeof (data ))) <=
841+ TPM_ERROR_SIZE ) {
842+ dev_dbg (chip -> dev , "A TPM error (%d) occurred "
843+ "attempting to determine the manufacturer\n" ,
844+ be32_to_cpu (* ((__be32 * ) (data + TPM_RET_CODE_IDX ))));
845+ return 0 ;
846+ }
847+
848+ str += sprintf (str , "Manufacturer: 0x%x\n" ,
849+ be32_to_cpu (* ((__be32 * ) (data + TPM_GET_CAP_RET_UINT32_1_IDX ))));
850+
851+ memcpy (data , cap_version , sizeof (cap_version ));
852+ data [CAP_VERSION_IDX ] = CAP_VERSION_1_2 ;
853+
854+ if ((len = tpm_transmit (chip , data , sizeof (data ))) <=
855+ TPM_ERROR_SIZE ) {
856+ dev_err (chip -> dev , "A TPM error (%d) occurred "
857+ "attempting to determine the 1.2 version\n" ,
858+ be32_to_cpu (* ((__be32 * ) (data + TPM_RET_CODE_IDX ))));
859+ goto out ;
860+ }
861+ str += sprintf (str ,
862+ "TCG version: %d.%d\nFirmware version: %d.%d\n" ,
863+ (int ) data [16 ], (int ) data [17 ], (int ) data [18 ],
864+ (int ) data [19 ]);
865+
866+ out :
867+ return str - buf ;
868+ }
869+ EXPORT_SYMBOL_GPL (tpm_show_caps_1_2 );
870+
640871ssize_t tpm_store_cancel (struct device * dev , struct device_attribute * attr ,
641872 const char * buf , size_t count )
642873{
0 commit comments