aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-03-28 16:29:51 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-03-28 16:29:51 -0400
commited40d0c472b136682b2fcba05f89762859c7374f (patch)
tree076b83a26bcd63d6158463735dd34c10bbc591dc /drivers/char
parent9e495834e59ca9b29f1a1f63b9f5533bb022ac49 (diff)
parent5d80f8e5a9dc9c9a94d4aeaa567e219a808b8a4a (diff)
Merge branch 'origin' into devel
Conflicts: sound/soc/pxa/pxa2xx-i2s.c
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/intel-agp.c21
-rw-r--r--drivers/char/hvc_iucv.c259
-rw-r--r--drivers/char/hw_random/Kconfig14
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c151
-rw-r--r--drivers/char/pcmcia/synclink_cs.c18
-rw-r--r--drivers/char/random.c6
-rw-r--r--drivers/char/sonypi.c7
-rw-r--r--drivers/char/synclink.c18
-rw-r--r--drivers/char/synclink_gt.c18
-rw-r--r--drivers/char/synclinkmp.c18
-rw-r--r--drivers/char/tpm/tpm.c530
-rw-r--r--drivers/char/tpm/tpm.h142
-rw-r--r--drivers/char/tpm/tpm_atmel.c28
-rw-r--r--drivers/char/tpm/tpm_tis.c28
-rw-r--r--drivers/char/tty_io.c5
-rw-r--r--drivers/char/vc_screen.c16
-rw-r--r--drivers/char/vt.c5
18 files changed, 925 insertions, 360 deletions
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 4373adb2119a..9d9490e22e07 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -26,6 +26,10 @@
26#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12 26#define PCI_DEVICE_ID_INTEL_82965GME_IG 0x2A12
27#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC 27#define PCI_DEVICE_ID_INTEL_82945GME_HB 0x27AC
28#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE 28#define PCI_DEVICE_ID_INTEL_82945GME_IG 0x27AE
29#define PCI_DEVICE_ID_INTEL_IGDGM_HB 0xA010
30#define PCI_DEVICE_ID_INTEL_IGDGM_IG 0xA011
31#define PCI_DEVICE_ID_INTEL_IGDG_HB 0xA000
32#define PCI_DEVICE_ID_INTEL_IGDG_IG 0xA001
29#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0 33#define PCI_DEVICE_ID_INTEL_G33_HB 0x29C0
30#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2 34#define PCI_DEVICE_ID_INTEL_G33_IG 0x29C2
31#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0 35#define PCI_DEVICE_ID_INTEL_Q35_HB 0x29B0
@@ -60,7 +64,12 @@
60 64
61#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \ 65#define IS_G33 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G33_HB || \
62 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ 66 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
63 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB) 67 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB || \
68 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
69 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
70
71#define IS_IGD (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDGM_HB || \
72 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDG_HB)
64 73
65#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \ 74#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
66 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \ 75 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
@@ -510,7 +519,7 @@ static void intel_i830_init_gtt_entries(void)
510 size = 512; 519 size = 512;
511 } 520 }
512 size += 4; /* add in BIOS popup space */ 521 size += 4; /* add in BIOS popup space */
513 } else if (IS_G33) { 522 } else if (IS_G33 && !IS_IGD) {
514 /* G33's GTT size defined in gmch_ctrl */ 523 /* G33's GTT size defined in gmch_ctrl */
515 switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { 524 switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) {
516 case G33_PGETBL_SIZE_1M: 525 case G33_PGETBL_SIZE_1M:
@@ -526,7 +535,7 @@ static void intel_i830_init_gtt_entries(void)
526 size = 512; 535 size = 512;
527 } 536 }
528 size += 4; 537 size += 4;
529 } else if (IS_G4X) { 538 } else if (IS_G4X || IS_IGD) {
530 /* On 4 series hardware, GTT stolen is separate from graphics 539 /* On 4 series hardware, GTT stolen is separate from graphics
531 * stolen, ignore it in stolen gtt entries counting. However, 540 * stolen, ignore it in stolen gtt entries counting. However,
532 * 4KB of the stolen memory doesn't get mapped to the GTT. 541 * 4KB of the stolen memory doesn't get mapped to the GTT.
@@ -2161,6 +2170,10 @@ static const struct intel_driver_description {
2161 NULL, &intel_g33_driver }, 2170 NULL, &intel_g33_driver },
2162 { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33", 2171 { PCI_DEVICE_ID_INTEL_Q33_HB, PCI_DEVICE_ID_INTEL_Q33_IG, 0, "Q33",
2163 NULL, &intel_g33_driver }, 2172 NULL, &intel_g33_driver },
2173 { PCI_DEVICE_ID_INTEL_IGDGM_HB, PCI_DEVICE_ID_INTEL_IGDGM_IG, 0, "IGD",
2174 NULL, &intel_g33_driver },
2175 { PCI_DEVICE_ID_INTEL_IGDG_HB, PCI_DEVICE_ID_INTEL_IGDG_IG, 0, "IGD",
2176 NULL, &intel_g33_driver },
2164 { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0, 2177 { PCI_DEVICE_ID_INTEL_GM45_HB, PCI_DEVICE_ID_INTEL_GM45_IG, 0,
2165 "Mobile IntelĀ® GM45 Express", NULL, &intel_i965_driver }, 2178 "Mobile IntelĀ® GM45 Express", NULL, &intel_i965_driver },
2166 { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0, 2179 { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
@@ -2355,6 +2368,8 @@ static struct pci_device_id agp_intel_pci_table[] = {
2355 ID(PCI_DEVICE_ID_INTEL_82945G_HB), 2368 ID(PCI_DEVICE_ID_INTEL_82945G_HB),
2356 ID(PCI_DEVICE_ID_INTEL_82945GM_HB), 2369 ID(PCI_DEVICE_ID_INTEL_82945GM_HB),
2357 ID(PCI_DEVICE_ID_INTEL_82945GME_HB), 2370 ID(PCI_DEVICE_ID_INTEL_82945GME_HB),
2371 ID(PCI_DEVICE_ID_INTEL_IGDGM_HB),
2372 ID(PCI_DEVICE_ID_INTEL_IGDG_HB),
2358 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), 2373 ID(PCI_DEVICE_ID_INTEL_82946GZ_HB),
2359 ID(PCI_DEVICE_ID_INTEL_82G35_HB), 2374 ID(PCI_DEVICE_ID_INTEL_82G35_HB),
2360 ID(PCI_DEVICE_ID_INTEL_82965Q_HB), 2375 ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index a53496828b76..54481a887769 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -13,10 +13,11 @@
13 13
14#include <linux/types.h> 14#include <linux/types.h>
15#include <asm/ebcdic.h> 15#include <asm/ebcdic.h>
16#include <linux/ctype.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/init.h> 18#include <linux/init.h>
18#include <linux/mempool.h> 19#include <linux/mempool.h>
19#include <linux/module.h> 20#include <linux/moduleparam.h>
20#include <linux/tty.h> 21#include <linux/tty.h>
21#include <linux/wait.h> 22#include <linux/wait.h>
22#include <net/iucv/iucv.h> 23#include <net/iucv/iucv.h>
@@ -95,6 +96,12 @@ static unsigned long hvc_iucv_devices = 1;
95/* Array of allocated hvc iucv tty lines... */ 96/* Array of allocated hvc iucv tty lines... */
96static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES]; 97static struct hvc_iucv_private *hvc_iucv_table[MAX_HVC_IUCV_LINES];
97#define IUCV_HVC_CON_IDX (0) 98#define IUCV_HVC_CON_IDX (0)
99/* List of z/VM user ID filter entries (struct iucv_vmid_filter) */
100#define MAX_VMID_FILTER (500)
101static size_t hvc_iucv_filter_size;
102static void *hvc_iucv_filter;
103static const char *hvc_iucv_filter_string;
104static DEFINE_RWLOCK(hvc_iucv_filter_lock);
98 105
99/* Kmem cache and mempool for iucv_tty_buffer elements */ 106/* Kmem cache and mempool for iucv_tty_buffer elements */
100static struct kmem_cache *hvc_iucv_buffer_cache; 107static struct kmem_cache *hvc_iucv_buffer_cache;
@@ -618,6 +625,27 @@ static void hvc_iucv_notifier_del(struct hvc_struct *hp, int id)
618} 625}
619 626
620/** 627/**
628 * hvc_iucv_filter_connreq() - Filter connection request based on z/VM user ID
629 * @ipvmid: Originating z/VM user ID (right padded with blanks)
630 *
631 * Returns 0 if the z/VM user ID @ipvmid is allowed to connection, otherwise
632 * non-zero.
633 */
634static int hvc_iucv_filter_connreq(u8 ipvmid[8])
635{
636 size_t i;
637
638 /* Note: default policy is ACCEPT if no filter is set */
639 if (!hvc_iucv_filter_size)
640 return 0;
641
642 for (i = 0; i < hvc_iucv_filter_size; i++)
643 if (0 == memcmp(ipvmid, hvc_iucv_filter + (8 * i), 8))
644 return 0;
645 return 1;
646}
647
648/**
621 * hvc_iucv_path_pending() - IUCV handler to process a connection request. 649 * hvc_iucv_path_pending() - IUCV handler to process a connection request.
622 * @path: Pending path (struct iucv_path) 650 * @path: Pending path (struct iucv_path)
623 * @ipvmid: z/VM system identifier of originator 651 * @ipvmid: z/VM system identifier of originator
@@ -641,6 +669,7 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
641{ 669{
642 struct hvc_iucv_private *priv; 670 struct hvc_iucv_private *priv;
643 u8 nuser_data[16]; 671 u8 nuser_data[16];
672 u8 vm_user_id[9];
644 int i, rc; 673 int i, rc;
645 674
646 priv = NULL; 675 priv = NULL;
@@ -653,6 +682,20 @@ static int hvc_iucv_path_pending(struct iucv_path *path,
653 if (!priv) 682 if (!priv)
654 return -ENODEV; 683 return -ENODEV;
655 684
685 /* Enforce that ipvmid is allowed to connect to us */
686 read_lock(&hvc_iucv_filter_lock);
687 rc = hvc_iucv_filter_connreq(ipvmid);
688 read_unlock(&hvc_iucv_filter_lock);
689 if (rc) {
690 iucv_path_sever(path, ipuser);
691 iucv_path_free(path);
692 memcpy(vm_user_id, ipvmid, 8);
693 vm_user_id[8] = 0;
694 pr_info("A connection request from z/VM user ID %s "
695 "was refused\n", vm_user_id);
696 return 0;
697 }
698
656 spin_lock(&priv->lock); 699 spin_lock(&priv->lock);
657 700
658 /* If the terminal is already connected or being severed, then sever 701 /* If the terminal is already connected or being severed, then sever
@@ -877,6 +920,171 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
877} 920}
878 921
879/** 922/**
923 * hvc_iucv_parse_filter() - Parse filter for a single z/VM user ID
924 * @filter: String containing a comma-separated list of z/VM user IDs
925 */
926static const char *hvc_iucv_parse_filter(const char *filter, char *dest)
927{
928 const char *nextdelim, *residual;
929 size_t len;
930
931 nextdelim = strchr(filter, ',');
932 if (nextdelim) {
933 len = nextdelim - filter;
934 residual = nextdelim + 1;
935 } else {
936 len = strlen(filter);
937 residual = filter + len;
938 }
939
940 if (len == 0)
941 return ERR_PTR(-EINVAL);
942
943 /* check for '\n' (if called from sysfs) */
944 if (filter[len - 1] == '\n')
945 len--;
946
947 if (len > 8)
948 return ERR_PTR(-EINVAL);
949
950 /* pad with blanks and save upper case version of user ID */
951 memset(dest, ' ', 8);
952 while (len--)
953 dest[len] = toupper(filter[len]);
954 return residual;
955}
956
957/**
958 * hvc_iucv_setup_filter() - Set up z/VM user ID filter
959 * @filter: String consisting of a comma-separated list of z/VM user IDs
960 *
961 * The function parses the @filter string and creates an array containing
962 * the list of z/VM user ID filter entries.
963 * Return code 0 means success, -EINVAL if the filter is syntactically
964 * incorrect, -ENOMEM if there was not enough memory to allocate the
965 * filter list array, or -ENOSPC if too many z/VM user IDs have been specified.
966 */
967static int hvc_iucv_setup_filter(const char *val)
968{
969 const char *residual;
970 int err;
971 size_t size, count;
972 void *array, *old_filter;
973
974 count = strlen(val);
975 if (count == 0 || (count == 1 && val[0] == '\n')) {
976 size = 0;
977 array = NULL;
978 goto out_replace_filter; /* clear filter */
979 }
980
981 /* count user IDs in order to allocate sufficient memory */
982 size = 1;
983 residual = val;
984 while ((residual = strchr(residual, ',')) != NULL) {
985 residual++;
986 size++;
987 }
988
989 /* check if the specified list exceeds the filter limit */
990 if (size > MAX_VMID_FILTER)
991 return -ENOSPC;
992
993 array = kzalloc(size * 8, GFP_KERNEL);
994 if (!array)
995 return -ENOMEM;
996
997 count = size;
998 residual = val;
999 while (*residual && count) {
1000 residual = hvc_iucv_parse_filter(residual,
1001 array + ((size - count) * 8));
1002 if (IS_ERR(residual)) {
1003 err = PTR_ERR(residual);
1004 kfree(array);
1005 goto out_err;
1006 }
1007 count--;
1008 }
1009
1010out_replace_filter:
1011 write_lock_bh(&hvc_iucv_filter_lock);
1012 old_filter = hvc_iucv_filter;
1013 hvc_iucv_filter_size = size;
1014 hvc_iucv_filter = array;
1015 write_unlock_bh(&hvc_iucv_filter_lock);
1016 kfree(old_filter);
1017
1018 err = 0;
1019out_err:
1020 return err;
1021}
1022
1023/**
1024 * param_set_vmidfilter() - Set z/VM user ID filter parameter
1025 * @val: String consisting of a comma-separated list of z/VM user IDs
1026 * @kp: Kernel parameter pointing to hvc_iucv_filter array
1027 *
1028 * The function sets up the z/VM user ID filter specified as comma-separated
1029 * list of user IDs in @val.
1030 * Note: If it is called early in the boot process, @val is stored and
1031 * parsed later in hvc_iucv_init().
1032 */
1033static int param_set_vmidfilter(const char *val, struct kernel_param *kp)
1034{
1035 int rc;
1036
1037 if (!MACHINE_IS_VM || !hvc_iucv_devices)
1038 return -ENODEV;
1039
1040 if (!val)
1041 return -EINVAL;
1042
1043 rc = 0;
1044 if (slab_is_available())
1045 rc = hvc_iucv_setup_filter(val);
1046 else
1047 hvc_iucv_filter_string = val; /* defer... */
1048 return rc;
1049}
1050
1051/**
1052 * param_get_vmidfilter() - Get z/VM user ID filter
1053 * @buffer: Buffer to store z/VM user ID filter,
1054 * (buffer size assumption PAGE_SIZE)
1055 * @kp: Kernel parameter pointing to the hvc_iucv_filter array
1056 *
1057 * The function stores the filter as a comma-separated list of z/VM user IDs
1058 * in @buffer. Typically, sysfs routines call this function for attr show.
1059 */
1060static int param_get_vmidfilter(char *buffer, struct kernel_param *kp)
1061{
1062 int rc;
1063 size_t index, len;
1064 void *start, *end;
1065
1066 if (!MACHINE_IS_VM || !hvc_iucv_devices)
1067 return -ENODEV;
1068
1069 rc = 0;
1070 read_lock_bh(&hvc_iucv_filter_lock);
1071 for (index = 0; index < hvc_iucv_filter_size; index++) {
1072 start = hvc_iucv_filter + (8 * index);
1073 end = memchr(start, ' ', 8);
1074 len = (end) ? end - start : 8;
1075 memcpy(buffer + rc, start, len);
1076 rc += len;
1077 buffer[rc++] = ',';
1078 }
1079 read_unlock_bh(&hvc_iucv_filter_lock);
1080 if (rc)
1081 buffer[--rc] = '\0'; /* replace last comma and update rc */
1082 return rc;
1083}
1084
1085#define param_check_vmidfilter(name, p) __param_check(name, p, void)
1086
1087/**
880 * hvc_iucv_init() - z/VM IUCV HVC device driver initialization 1088 * hvc_iucv_init() - z/VM IUCV HVC device driver initialization
881 */ 1089 */
882static int __init hvc_iucv_init(void) 1090static int __init hvc_iucv_init(void)
@@ -884,24 +1092,53 @@ static int __init hvc_iucv_init(void)
884 int rc; 1092 int rc;
885 unsigned int i; 1093 unsigned int i;
886 1094
1095 if (!hvc_iucv_devices)
1096 return -ENODEV;
1097
887 if (!MACHINE_IS_VM) { 1098 if (!MACHINE_IS_VM) {
888 pr_info("The z/VM IUCV HVC device driver cannot " 1099 pr_notice("The z/VM IUCV HVC device driver cannot "
889 "be used without z/VM\n"); 1100 "be used without z/VM\n");
890 return -ENODEV; 1101 rc = -ENODEV;
1102 goto out_error;
891 } 1103 }
892 1104
893 if (!hvc_iucv_devices) 1105 if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) {
894 return -ENODEV; 1106 pr_err("%lu is not a valid value for the hvc_iucv= "
1107 "kernel parameter\n", hvc_iucv_devices);
1108 rc = -EINVAL;
1109 goto out_error;
1110 }
895 1111
896 if (hvc_iucv_devices > MAX_HVC_IUCV_LINES) 1112 /* parse hvc_iucv_allow string and create z/VM user ID filter list */
897 return -EINVAL; 1113 if (hvc_iucv_filter_string) {
1114 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
1115 switch (rc) {
1116 case 0:
1117 break;
1118 case -ENOMEM:
1119 pr_err("Allocating memory failed with "
1120 "reason code=%d\n", 3);
1121 goto out_error;
1122 case -EINVAL:
1123 pr_err("hvc_iucv_allow= does not specify a valid "
1124 "z/VM user ID list\n");
1125 goto out_error;
1126 case -ENOSPC:
1127 pr_err("hvc_iucv_allow= specifies too many "
1128 "z/VM user IDs\n");
1129 goto out_error;
1130 default:
1131 goto out_error;
1132 }
1133 }
898 1134
899 hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT, 1135 hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT,
900 sizeof(struct iucv_tty_buffer), 1136 sizeof(struct iucv_tty_buffer),
901 0, 0, NULL); 1137 0, 0, NULL);
902 if (!hvc_iucv_buffer_cache) { 1138 if (!hvc_iucv_buffer_cache) {
903 pr_err("Allocating memory failed with reason code=%d\n", 1); 1139 pr_err("Allocating memory failed with reason code=%d\n", 1);
904 return -ENOMEM; 1140 rc = -ENOMEM;
1141 goto out_error;
905 } 1142 }
906 1143
907 hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR, 1144 hvc_iucv_mempool = mempool_create_slab_pool(MEMPOOL_MIN_NR,
@@ -909,7 +1146,8 @@ static int __init hvc_iucv_init(void)
909 if (!hvc_iucv_mempool) { 1146 if (!hvc_iucv_mempool) {
910 pr_err("Allocating memory failed with reason code=%d\n", 2); 1147 pr_err("Allocating memory failed with reason code=%d\n", 2);
911 kmem_cache_destroy(hvc_iucv_buffer_cache); 1148 kmem_cache_destroy(hvc_iucv_buffer_cache);
912 return -ENOMEM; 1149 rc = -ENOMEM;
1150 goto out_error;
913 } 1151 }
914 1152
915 /* register the first terminal device as console 1153 /* register the first terminal device as console
@@ -953,6 +1191,8 @@ out_error_hvc:
953out_error_memory: 1191out_error_memory:
954 mempool_destroy(hvc_iucv_mempool); 1192 mempool_destroy(hvc_iucv_mempool);
955 kmem_cache_destroy(hvc_iucv_buffer_cache); 1193 kmem_cache_destroy(hvc_iucv_buffer_cache);
1194out_error:
1195 hvc_iucv_devices = 0; /* ensure that we do not provide any device */
956 return rc; 1196 return rc;
957} 1197}
958 1198
@@ -968,3 +1208,4 @@ static int __init hvc_iucv_config(char *val)
968 1208
969device_initcall(hvc_iucv_init); 1209device_initcall(hvc_iucv_init);
970__setup("hvc_iucv=", hvc_iucv_config); 1210__setup("hvc_iucv=", hvc_iucv_config);
1211core_param(hvc_iucv_allow, hvc_iucv_filter, vmidfilter, 0640);
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 8822eca58ffa..5fab6470f4b2 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -20,6 +20,20 @@ config HW_RANDOM
20 20
21 If unsure, say Y. 21 If unsure, say Y.
22 22
23config HW_RANDOM_TIMERIOMEM
24 tristate "Timer IOMEM HW Random Number Generator support"
25 depends on HW_RANDOM && HAS_IOMEM
26 ---help---
27 This driver provides kernel-side support for a generic Random
28 Number Generator used by reading a 'dumb' iomem address that
29 is to be read no faster than, for example, once a second;
30 the default FPGA bitstream on the TS-7800 has such functionality.
31
32 To compile this driver as a module, choose M here: the
33 module will be called timeriomem-rng.
34
35 If unsure, say Y.
36
23config HW_RANDOM_INTEL 37config HW_RANDOM_INTEL
24 tristate "Intel HW Random Number Generator support" 38 tristate "Intel HW Random Number Generator support"
25 depends on HW_RANDOM && (X86 || IA64) && PCI 39 depends on HW_RANDOM && (X86 || IA64) && PCI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index b6effb7522c2..e81d21a5f28f 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -4,6 +4,7 @@
4 4
5obj-$(CONFIG_HW_RANDOM) += rng-core.o 5obj-$(CONFIG_HW_RANDOM) += rng-core.o
6rng-core-y := core.o 6rng-core-y := core.o
7obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += timeriomem-rng.o
7obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o 8obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
8obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o 9obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
9obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o 10obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
new file mode 100644
index 000000000000..10ad41be5897
--- /dev/null
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -0,0 +1,151 @@
1/*
2 * drivers/char/hw_random/timeriomem-rng.c
3 *
4 * Copyright (C) 2009 Alexander Clouter <alex@digriz.org.uk>
5 *
6 * Derived from drivers/char/hw_random/omap-rng.c
7 * Copyright 2005 (c) MontaVista Software, Inc.
8 * Author: Deepak Saxena <dsaxena@plexity.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * Overview:
15 * This driver is useful for platforms that have an IO range that provides
16 * periodic random data from a single IO memory address. All the platform
17 * has to do is provide the address and 'wait time' that new data becomes
18 * available.
19 *
20 * TODO: add support for reading sizes other than 32bits and masking
21 */
22
23#include <linux/module.h>
24#include <linux/kernel.h>
25#include <linux/platform_device.h>
26#include <linux/hw_random.h>
27#include <linux/io.h>
28#include <linux/timeriomem-rng.h>
29#include <linux/jiffies.h>
30#include <linux/sched.h>
31#include <linux/timer.h>
32#include <linux/completion.h>
33
34static struct timeriomem_rng_data *timeriomem_rng_data;
35
36static void timeriomem_rng_trigger(unsigned long);
37static DEFINE_TIMER(timeriomem_rng_timer, timeriomem_rng_trigger, 0, 0);
38
39/*
40 * have data return 1, however return 0 if we have nothing
41 */
42static int timeriomem_rng_data_present(struct hwrng *rng, int wait)
43{
44 if (rng->priv == 0)
45 return 1;
46
47 if (!wait || timeriomem_rng_data->present)
48 return timeriomem_rng_data->present;
49
50 wait_for_completion(&timeriomem_rng_data->completion);
51
52 return 1;
53}
54
55static int timeriomem_rng_data_read(struct hwrng *rng, u32 *data)
56{
57 unsigned long cur;
58 s32 delay;
59
60 *data = readl(timeriomem_rng_data->address);
61
62 if (rng->priv != 0) {
63 cur = jiffies;
64
65 delay = cur - timeriomem_rng_timer.expires;
66 delay = rng->priv - (delay % rng->priv);
67
68 timeriomem_rng_timer.expires = cur + delay;
69 timeriomem_rng_data->present = 0;
70
71 init_completion(&timeriomem_rng_data->completion);
72 add_timer(&timeriomem_rng_timer);
73 }
74
75 return 4;
76}
77
78static void timeriomem_rng_trigger(unsigned long dummy)
79{
80 timeriomem_rng_data->present = 1;
81 complete(&timeriomem_rng_data->completion);
82}
83
84static struct hwrng timeriomem_rng_ops = {
85 .name = "timeriomem",
86 .data_present = timeriomem_rng_data_present,
87 .data_read = timeriomem_rng_data_read,
88 .priv = 0,
89};
90
91static int __init timeriomem_rng_probe(struct platform_device *pdev)
92{
93 int ret;
94
95 timeriomem_rng_data = pdev->dev.platform_data;
96
97 if (timeriomem_rng_data->period != 0
98 && usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
99 timeriomem_rng_timer.expires = jiffies;
100
101 timeriomem_rng_ops.priv = usecs_to_jiffies(
102 timeriomem_rng_data->period);
103 }
104 timeriomem_rng_data->present = 1;
105
106 ret = hwrng_register(&timeriomem_rng_ops);
107 if (ret) {
108 dev_err(&pdev->dev, "problem registering\n");
109 return ret;
110 }
111
112 dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
113 timeriomem_rng_data->address,
114 timeriomem_rng_data->period);
115
116 return 0;
117}
118
119static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
120{
121 del_timer_sync(&timeriomem_rng_timer);
122 hwrng_unregister(&timeriomem_rng_ops);
123
124 return 0;
125}
126
127static struct platform_driver timeriomem_rng_driver = {
128 .driver = {
129 .name = "timeriomem_rng",
130 .owner = THIS_MODULE,
131 },
132 .probe = timeriomem_rng_probe,
133 .remove = __devexit_p(timeriomem_rng_remove),
134};
135
136static int __init timeriomem_rng_init(void)
137{
138 return platform_driver_register(&timeriomem_rng_driver);
139}
140
141static void __exit timeriomem_rng_exit(void)
142{
143 platform_driver_unregister(&timeriomem_rng_driver);
144}
145
146module_init(timeriomem_rng_init);
147module_exit(timeriomem_rng_exit);
148
149MODULE_LICENSE("GPL");
150MODULE_AUTHOR("Alexander Clouter <alex@digriz.org.uk>");
151MODULE_DESCRIPTION("Timer IOMEM H/W RNG driver");
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index dc073e167abc..5608a1e5a3b3 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -4311,10 +4311,17 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
4311 dev->stats.rx_bytes += size; 4311 dev->stats.rx_bytes += size;
4312 4312
4313 netif_rx(skb); 4313 netif_rx(skb);
4314
4315 dev->last_rx = jiffies;
4316} 4314}
4317 4315
4316static const struct net_device_ops hdlcdev_ops = {
4317 .ndo_open = hdlcdev_open,
4318 .ndo_stop = hdlcdev_close,
4319 .ndo_change_mtu = hdlc_change_mtu,
4320 .ndo_start_xmit = hdlc_start_xmit,
4321 .ndo_do_ioctl = hdlcdev_ioctl,
4322 .ndo_tx_timeout = hdlcdev_tx_timeout,
4323};
4324
4318/** 4325/**
4319 * called by device driver when adding device instance 4326 * called by device driver when adding device instance
4320 * do generic HDLC initialization 4327 * do generic HDLC initialization
@@ -4341,11 +4348,8 @@ static int hdlcdev_init(MGSLPC_INFO *info)
4341 dev->irq = info->irq_level; 4348 dev->irq = info->irq_level;
4342 4349
4343 /* network layer callbacks and settings */ 4350 /* network layer callbacks and settings */
4344 dev->do_ioctl = hdlcdev_ioctl; 4351 dev->netdev_ops = &hdlcdev_ops;
4345 dev->open = hdlcdev_open; 4352 dev->watchdog_timeo = 10 * HZ;
4346 dev->stop = hdlcdev_close;
4347 dev->tx_timeout = hdlcdev_tx_timeout;
4348 dev->watchdog_timeo = 10*HZ;
4349 dev->tx_queue_len = 50; 4353 dev->tx_queue_len = 50;
4350 4354
4351 /* generic HDLC layer callbacks and settings */ 4355 /* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c13581ca9cd..7c43ae782b26 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -241,6 +241,10 @@
241#include <linux/percpu.h> 241#include <linux/percpu.h>
242#include <linux/cryptohash.h> 242#include <linux/cryptohash.h>
243 243
244#ifdef CONFIG_GENERIC_HARDIRQS
245# include <linux/irq.h>
246#endif
247
244#include <asm/processor.h> 248#include <asm/processor.h>
245#include <asm/uaccess.h> 249#include <asm/uaccess.h>
246#include <asm/irq.h> 250#include <asm/irq.h>
@@ -558,7 +562,7 @@ struct timer_rand_state {
558 unsigned dont_count_entropy:1; 562 unsigned dont_count_entropy:1;
559}; 563};
560 564
561#ifndef CONFIG_SPARSE_IRQ 565#ifndef CONFIG_GENERIC_HARDIRQS
562 566
563static struct timer_rand_state *irq_timer_state[NR_IRQS]; 567static struct timer_rand_state *irq_timer_state[NR_IRQS];
564 568
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index f4374437a033..fd3dced97776 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -888,12 +888,7 @@ found:
888 888
889static int sonypi_misc_fasync(int fd, struct file *filp, int on) 889static int sonypi_misc_fasync(int fd, struct file *filp, int on)
890{ 890{
891 int retval; 891 return fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
892
893 retval = fasync_helper(fd, filp, on, &sonypi_device.fifo_async);
894 if (retval < 0)
895 return retval;
896 return 0;
897} 892}
898 893
899static int sonypi_misc_release(struct inode *inode, struct file *file) 894static int sonypi_misc_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index b8063d4cad32..0057a8f58cb1 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -8007,10 +8007,17 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
8007 dev->stats.rx_bytes += size; 8007 dev->stats.rx_bytes += size;
8008 8008
8009 netif_rx(skb); 8009 netif_rx(skb);
8010
8011 dev->last_rx = jiffies;
8012} 8010}
8013 8011
8012static const struct net_device_ops hdlcdev_ops = {
8013 .ndo_open = hdlcdev_open,
8014 .ndo_stop = hdlcdev_close,
8015 .ndo_change_mtu = hdlc_change_mtu,
8016 .ndo_start_xmit = hdlc_start_xmit,
8017 .ndo_do_ioctl = hdlcdev_ioctl,
8018 .ndo_tx_timeout = hdlcdev_tx_timeout,
8019};
8020
8014/** 8021/**
8015 * called by device driver when adding device instance 8022 * called by device driver when adding device instance
8016 * do generic HDLC initialization 8023 * do generic HDLC initialization
@@ -8038,11 +8045,8 @@ static int hdlcdev_init(struct mgsl_struct *info)
8038 dev->dma = info->dma_level; 8045 dev->dma = info->dma_level;
8039 8046
8040 /* network layer callbacks and settings */ 8047 /* network layer callbacks and settings */
8041 dev->do_ioctl = hdlcdev_ioctl; 8048 dev->netdev_ops = &hdlcdev_ops;
8042 dev->open = hdlcdev_open; 8049 dev->watchdog_timeo = 10 * HZ;
8043 dev->stop = hdlcdev_close;
8044 dev->tx_timeout = hdlcdev_tx_timeout;
8045 dev->watchdog_timeo = 10*HZ;
8046 dev->tx_queue_len = 50; 8050 dev->tx_queue_len = 50;
8047 8051
8048 /* generic HDLC layer callbacks and settings */ 8052 /* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index f329f459817c..efb3dc928a43 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -1763,10 +1763,17 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
1763 dev->stats.rx_bytes += size; 1763 dev->stats.rx_bytes += size;
1764 1764
1765 netif_rx(skb); 1765 netif_rx(skb);
1766
1767 dev->last_rx = jiffies;
1768} 1766}
1769 1767
1768static const struct net_device_ops hdlcdev_ops = {
1769 .ndo_open = hdlcdev_open,
1770 .ndo_stop = hdlcdev_close,
1771 .ndo_change_mtu = hdlc_change_mtu,
1772 .ndo_start_xmit = hdlc_start_xmit,
1773 .ndo_do_ioctl = hdlcdev_ioctl,
1774 .ndo_tx_timeout = hdlcdev_tx_timeout,
1775};
1776
1770/** 1777/**
1771 * called by device driver when adding device instance 1778 * called by device driver when adding device instance
1772 * do generic HDLC initialization 1779 * do generic HDLC initialization
@@ -1794,11 +1801,8 @@ static int hdlcdev_init(struct slgt_info *info)
1794 dev->irq = info->irq_level; 1801 dev->irq = info->irq_level;
1795 1802
1796 /* network layer callbacks and settings */ 1803 /* network layer callbacks and settings */
1797 dev->do_ioctl = hdlcdev_ioctl; 1804 dev->netdev_ops = &hdlcdev_ops;
1798 dev->open = hdlcdev_open; 1805 dev->watchdog_timeo = 10 * HZ;
1799 dev->stop = hdlcdev_close;
1800 dev->tx_timeout = hdlcdev_tx_timeout;
1801 dev->watchdog_timeo = 10*HZ;
1802 dev->tx_queue_len = 50; 1806 dev->tx_queue_len = 50;
1803 1807
1804 /* generic HDLC layer callbacks and settings */ 1808 /* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 7b0c5b2dd263..8eb6c89a980e 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -1907,10 +1907,17 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
1907 dev->stats.rx_bytes += size; 1907 dev->stats.rx_bytes += size;
1908 1908
1909 netif_rx(skb); 1909 netif_rx(skb);
1910
1911 dev->last_rx = jiffies;
1912} 1910}
1913 1911
1912static const struct net_device_ops hdlcdev_ops = {
1913 .ndo_open = hdlcdev_open,
1914 .ndo_stop = hdlcdev_close,
1915 .ndo_change_mtu = hdlc_change_mtu,
1916 .ndo_start_xmit = hdlc_start_xmit,
1917 .ndo_do_ioctl = hdlcdev_ioctl,
1918 .ndo_tx_timeout = hdlcdev_tx_timeout,
1919};
1920
1914/** 1921/**
1915 * called by device driver when adding device instance 1922 * called by device driver when adding device instance
1916 * do generic HDLC initialization 1923 * do generic HDLC initialization
@@ -1938,11 +1945,8 @@ static int hdlcdev_init(SLMP_INFO *info)
1938 dev->irq = info->irq_level; 1945 dev->irq = info->irq_level;
1939 1946
1940 /* network layer callbacks and settings */ 1947 /* network layer callbacks and settings */
1941 dev->do_ioctl = hdlcdev_ioctl; 1948 dev->netdev_ops = &hdlcdev_ops;
1942 dev->open = hdlcdev_open; 1949 dev->watchdog_timeo = 10 * HZ;
1943 dev->stop = hdlcdev_close;
1944 dev->tx_timeout = hdlcdev_tx_timeout;
1945 dev->watchdog_timeo = 10*HZ;
1946 dev->tx_queue_len = 50; 1950 dev->tx_queue_len = 50;
1947 1951
1948 /* generic HDLC layer callbacks and settings */ 1952 /* generic HDLC layer callbacks and settings */
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 9c47dc48c9fd..ccdd828adcef 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -429,134 +429,148 @@ out:
429#define TPM_DIGEST_SIZE 20 429#define TPM_DIGEST_SIZE 20
430#define TPM_ERROR_SIZE 10 430#define TPM_ERROR_SIZE 10
431#define TPM_RET_CODE_IDX 6 431#define TPM_RET_CODE_IDX 6
432#define TPM_GET_CAP_RET_SIZE_IDX 10
433#define TPM_GET_CAP_RET_UINT32_1_IDX 14
434#define TPM_GET_CAP_RET_UINT32_2_IDX 18
435#define TPM_GET_CAP_RET_UINT32_3_IDX 22
436#define TPM_GET_CAP_RET_UINT32_4_IDX 26
437#define TPM_GET_CAP_PERM_DISABLE_IDX 16
438#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
439#define TPM_GET_CAP_RET_BOOL_1_IDX 14
440#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
441
442#define TPM_CAP_IDX 13
443#define TPM_CAP_SUBCAP_IDX 21
444 432
445enum tpm_capabilities { 433enum tpm_capabilities {
446 TPM_CAP_FLAG = 4, 434 TPM_CAP_FLAG = cpu_to_be32(4),
447 TPM_CAP_PROP = 5, 435 TPM_CAP_PROP = cpu_to_be32(5),
436 CAP_VERSION_1_1 = cpu_to_be32(0x06),
437 CAP_VERSION_1_2 = cpu_to_be32(0x1A)
448}; 438};
449 439
450enum tpm_sub_capabilities { 440enum tpm_sub_capabilities {
451 TPM_CAP_PROP_PCR = 0x1, 441 TPM_CAP_PROP_PCR = cpu_to_be32(0x101),
452 TPM_CAP_PROP_MANUFACTURER = 0x3, 442 TPM_CAP_PROP_MANUFACTURER = cpu_to_be32(0x103),
453 TPM_CAP_FLAG_PERM = 0x8, 443 TPM_CAP_FLAG_PERM = cpu_to_be32(0x108),
454 TPM_CAP_FLAG_VOL = 0x9, 444 TPM_CAP_FLAG_VOL = cpu_to_be32(0x109),
455 TPM_CAP_PROP_OWNER = 0x11, 445 TPM_CAP_PROP_OWNER = cpu_to_be32(0x111),
456 TPM_CAP_PROP_TIS_TIMEOUT = 0x15, 446 TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
457 TPM_CAP_PROP_TIS_DURATION = 0x20, 447 TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
458};
459 448
460/*
461 * This is a semi generic GetCapability command for use
462 * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
463 * and their associated sub_capabilities.
464 */
465
466static const u8 tpm_cap[] = {
467 0, 193, /* TPM_TAG_RQU_COMMAND */
468 0, 0, 0, 22, /* length */
469 0, 0, 0, 101, /* TPM_ORD_GetCapability */
470 0, 0, 0, 0, /* TPM_CAP_<TYPE> */
471 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */
472 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
473}; 449};
474 450
475static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len, 451static ssize_t transmit_cmd(struct tpm_chip *chip, struct tpm_cmd_t *cmd,
476 char *desc) 452 int len, const char *desc)
477{ 453{
478 int err; 454 int err;
479 455
480 len = tpm_transmit(chip, data, len); 456 len = tpm_transmit(chip,(u8 *) cmd, len);
481 if (len < 0) 457 if (len < 0)
482 return len; 458 return len;
483 if (len == TPM_ERROR_SIZE) { 459 if (len == TPM_ERROR_SIZE) {
484 err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))); 460 err = be32_to_cpu(cmd->header.out.return_code);
485 dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); 461 dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
486 return err; 462 return err;
487 } 463 }
488 return 0; 464 return 0;
489} 465}
490 466
467#define TPM_INTERNAL_RESULT_SIZE 200
468#define TPM_TAG_RQU_COMMAND cpu_to_be16(193)
469#define TPM_ORD_GET_CAP cpu_to_be32(101)
470
471static const struct tpm_input_header tpm_getcap_header = {
472 .tag = TPM_TAG_RQU_COMMAND,
473 .length = cpu_to_be32(22),
474 .ordinal = TPM_ORD_GET_CAP
475};
476
477ssize_t tpm_getcap(struct device *dev, __be32 subcap_id, cap_t *cap,
478 const char *desc)
479{
480 struct tpm_cmd_t tpm_cmd;
481 int rc;
482 struct tpm_chip *chip = dev_get_drvdata(dev);
483
484 tpm_cmd.header.in = tpm_getcap_header;
485 if (subcap_id == CAP_VERSION_1_1 || subcap_id == CAP_VERSION_1_2) {
486 tpm_cmd.params.getcap_in.cap = subcap_id;
487 /*subcap field not necessary */
488 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(0);
489 tpm_cmd.header.in.length -= cpu_to_be32(sizeof(__be32));
490 } else {
491 if (subcap_id == TPM_CAP_FLAG_PERM ||
492 subcap_id == TPM_CAP_FLAG_VOL)
493 tpm_cmd.params.getcap_in.cap = TPM_CAP_FLAG;
494 else
495 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
496 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
497 tpm_cmd.params.getcap_in.subcap = subcap_id;
498 }
499 rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
500 if (!rc)
501 *cap = tpm_cmd.params.getcap_out.cap;
502 return rc;
503}
504
491void tpm_gen_interrupt(struct tpm_chip *chip) 505void tpm_gen_interrupt(struct tpm_chip *chip)
492{ 506{
493 u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)]; 507 struct tpm_cmd_t tpm_cmd;
494 ssize_t rc; 508 ssize_t rc;
495 509
496 memcpy(data, tpm_cap, sizeof(tpm_cap)); 510 tpm_cmd.header.in = tpm_getcap_header;
497 data[TPM_CAP_IDX] = TPM_CAP_PROP; 511 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
498 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT; 512 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
513 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
499 514
500 rc = transmit_cmd(chip, data, sizeof(data), 515 rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
501 "attempting to determine the timeouts"); 516 "attempting to determine the timeouts");
502} 517}
503EXPORT_SYMBOL_GPL(tpm_gen_interrupt); 518EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
504 519
505void tpm_get_timeouts(struct tpm_chip *chip) 520void tpm_get_timeouts(struct tpm_chip *chip)
506{ 521{
507 u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)]; 522 struct tpm_cmd_t tpm_cmd;
523 struct timeout_t *timeout_cap;
524 struct duration_t *duration_cap;
508 ssize_t rc; 525 ssize_t rc;
509 u32 timeout; 526 u32 timeout;
510 527
511 memcpy(data, tpm_cap, sizeof(tpm_cap)); 528 tpm_cmd.header.in = tpm_getcap_header;
512 data[TPM_CAP_IDX] = TPM_CAP_PROP; 529 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
513 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT; 530 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
531 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
514 532
515 rc = transmit_cmd(chip, data, sizeof(data), 533 rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
516 "attempting to determine the timeouts"); 534 "attempting to determine the timeouts");
517 if (rc) 535 if (rc)
518 goto duration; 536 goto duration;
519 537
520 if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))) 538 if (be32_to_cpu(tpm_cmd.header.out.length)
521 != 4 * sizeof(u32)) 539 != 4 * sizeof(u32))
522 goto duration; 540 goto duration;
523 541
542 timeout_cap = &tpm_cmd.params.getcap_out.cap.timeout;
524 /* Don't overwrite default if value is 0 */ 543 /* Don't overwrite default if value is 0 */
525 timeout = 544 timeout = be32_to_cpu(timeout_cap->a);
526 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
527 if (timeout) 545 if (timeout)
528 chip->vendor.timeout_a = usecs_to_jiffies(timeout); 546 chip->vendor.timeout_a = usecs_to_jiffies(timeout);
529 timeout = 547 timeout = be32_to_cpu(timeout_cap->b);
530 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
531 if (timeout) 548 if (timeout)
532 chip->vendor.timeout_b = usecs_to_jiffies(timeout); 549 chip->vendor.timeout_b = usecs_to_jiffies(timeout);
533 timeout = 550 timeout = be32_to_cpu(timeout_cap->c);
534 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
535 if (timeout) 551 if (timeout)
536 chip->vendor.timeout_c = usecs_to_jiffies(timeout); 552 chip->vendor.timeout_c = usecs_to_jiffies(timeout);
537 timeout = 553 timeout = be32_to_cpu(timeout_cap->d);
538 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
539 if (timeout) 554 if (timeout)
540 chip->vendor.timeout_d = usecs_to_jiffies(timeout); 555 chip->vendor.timeout_d = usecs_to_jiffies(timeout);
541 556
542duration: 557duration:
543 memcpy(data, tpm_cap, sizeof(tpm_cap)); 558 tpm_cmd.header.in = tpm_getcap_header;
544 data[TPM_CAP_IDX] = TPM_CAP_PROP; 559 tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
545 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION; 560 tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
561 tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
546 562
547 rc = transmit_cmd(chip, data, sizeof(data), 563 rc = transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
548 "attempting to determine the durations"); 564 "attempting to determine the durations");
549 if (rc) 565 if (rc)
550 return; 566 return;
551 567
552 if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))) 568 if (be32_to_cpu(tpm_cmd.header.out.return_code)
553 != 3 * sizeof(u32)) 569 != 3 * sizeof(u32))
554 return; 570 return;
555 571 duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
556 chip->vendor.duration[TPM_SHORT] = 572 chip->vendor.duration[TPM_SHORT] =
557 usecs_to_jiffies(be32_to_cpu 573 usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
558 (*((__be32 *) (data +
559 TPM_GET_CAP_RET_UINT32_1_IDX))));
560 /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above 574 /* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
561 * value wrong and apparently reports msecs rather than usecs. So we 575 * value wrong and apparently reports msecs rather than usecs. So we
562 * fix up the resulting too-small TPM_SHORT value to make things work. 576 * fix up the resulting too-small TPM_SHORT value to make things work.
@@ -565,13 +579,9 @@ duration:
565 chip->vendor.duration[TPM_SHORT] = HZ; 579 chip->vendor.duration[TPM_SHORT] = HZ;
566 580
567 chip->vendor.duration[TPM_MEDIUM] = 581 chip->vendor.duration[TPM_MEDIUM] =
568 usecs_to_jiffies(be32_to_cpu 582 usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_medium));
569 (*((__be32 *) (data +
570 TPM_GET_CAP_RET_UINT32_2_IDX))));
571 chip->vendor.duration[TPM_LONG] = 583 chip->vendor.duration[TPM_LONG] =
572 usecs_to_jiffies(be32_to_cpu 584 usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_long));
573 (*((__be32 *) (data +
574 TPM_GET_CAP_RET_UINT32_3_IDX))));
575} 585}
576EXPORT_SYMBOL_GPL(tpm_get_timeouts); 586EXPORT_SYMBOL_GPL(tpm_get_timeouts);
577 587
@@ -587,36 +597,18 @@ void tpm_continue_selftest(struct tpm_chip *chip)
587} 597}
588EXPORT_SYMBOL_GPL(tpm_continue_selftest); 598EXPORT_SYMBOL_GPL(tpm_continue_selftest);
589 599
590#define TPM_INTERNAL_RESULT_SIZE 200
591
592ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, 600ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
593 char *buf) 601 char *buf)
594{ 602{
595 u8 *data; 603 cap_t cap;
596 ssize_t rc; 604 ssize_t rc;
597 605
598 struct tpm_chip *chip = dev_get_drvdata(dev); 606 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
599 if (chip == NULL) 607 "attempting to determine the permanent enabled state");
600 return -ENODEV; 608 if (rc)
601
602 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
603 if (!data)
604 return -ENOMEM;
605
606 memcpy(data, tpm_cap, sizeof(tpm_cap));
607 data[TPM_CAP_IDX] = TPM_CAP_FLAG;
608 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
609
610 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
611 "attemtping to determine the permanent enabled state");
612 if (rc) {
613 kfree(data);
614 return 0; 609 return 0;
615 }
616
617 rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
618 610
619 kfree(data); 611 rc = sprintf(buf, "%d\n", !cap.perm_flags.disable);
620 return rc; 612 return rc;
621} 613}
622EXPORT_SYMBOL_GPL(tpm_show_enabled); 614EXPORT_SYMBOL_GPL(tpm_show_enabled);
@@ -624,31 +616,15 @@ EXPORT_SYMBOL_GPL(tpm_show_enabled);
624ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, 616ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
625 char *buf) 617 char *buf)
626{ 618{
627 u8 *data; 619 cap_t cap;
628 ssize_t rc; 620 ssize_t rc;
629 621
630 struct tpm_chip *chip = dev_get_drvdata(dev); 622 rc = tpm_getcap(dev, TPM_CAP_FLAG_PERM, &cap,
631 if (chip == NULL) 623 "attempting to determine the permanent active state");
632 return -ENODEV; 624 if (rc)
633
634 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
635 if (!data)
636 return -ENOMEM;
637
638 memcpy(data, tpm_cap, sizeof(tpm_cap));
639 data[TPM_CAP_IDX] = TPM_CAP_FLAG;
640 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
641
642 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
643 "attemtping to determine the permanent active state");
644 if (rc) {
645 kfree(data);
646 return 0; 625 return 0;
647 }
648 626
649 rc = sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); 627 rc = sprintf(buf, "%d\n", !cap.perm_flags.deactivated);
650
651 kfree(data);
652 return rc; 628 return rc;
653} 629}
654EXPORT_SYMBOL_GPL(tpm_show_active); 630EXPORT_SYMBOL_GPL(tpm_show_active);
@@ -656,31 +632,15 @@ EXPORT_SYMBOL_GPL(tpm_show_active);
656ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, 632ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
657 char *buf) 633 char *buf)
658{ 634{
659 u8 *data; 635 cap_t cap;
660 ssize_t rc; 636 ssize_t rc;
661 637
662 struct tpm_chip *chip = dev_get_drvdata(dev); 638 rc = tpm_getcap(dev, TPM_CAP_PROP_OWNER, &cap,
663 if (chip == NULL) 639 "attempting to determine the owner state");
664 return -ENODEV; 640 if (rc)
665
666 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
667 if (!data)
668 return -ENOMEM;
669
670 memcpy(data, tpm_cap, sizeof(tpm_cap));
671 data[TPM_CAP_IDX] = TPM_CAP_PROP;
672 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
673
674 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
675 "attempting to determine the owner state");
676 if (rc) {
677 kfree(data);
678 return 0; 641 return 0;
679 }
680
681 rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
682 642
683 kfree(data); 643 rc = sprintf(buf, "%d\n", cap.owned);
684 return rc; 644 return rc;
685} 645}
686EXPORT_SYMBOL_GPL(tpm_show_owned); 646EXPORT_SYMBOL_GPL(tpm_show_owned);
@@ -688,116 +648,180 @@ EXPORT_SYMBOL_GPL(tpm_show_owned);
688ssize_t tpm_show_temp_deactivated(struct device * dev, 648ssize_t tpm_show_temp_deactivated(struct device * dev,
689 struct device_attribute * attr, char *buf) 649 struct device_attribute * attr, char *buf)
690{ 650{
691 u8 *data; 651 cap_t cap;
692 ssize_t rc; 652 ssize_t rc;
693 653
694 struct tpm_chip *chip = dev_get_drvdata(dev); 654 rc = tpm_getcap(dev, TPM_CAP_FLAG_VOL, &cap,
695 if (chip == NULL) 655 "attempting to determine the temporary state");
696 return -ENODEV; 656 if (rc)
657 return 0;
697 658
698 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); 659 rc = sprintf(buf, "%d\n", cap.stclear_flags.deactivated);
699 if (!data) 660 return rc;
700 return -ENOMEM; 661}
662EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
701 663
702 memcpy(data, tpm_cap, sizeof(tpm_cap)); 664/*
703 data[TPM_CAP_IDX] = TPM_CAP_FLAG; 665 * tpm_chip_find_get - return tpm_chip for given chip number
704 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL; 666 */
667static struct tpm_chip *tpm_chip_find_get(int chip_num)
668{
669 struct tpm_chip *pos, *chip = NULL;
705 670
706 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE, 671 rcu_read_lock();
707 "attempting to determine the temporary state"); 672 list_for_each_entry_rcu(pos, &tpm_chip_list, list) {
708 if (rc) { 673 if (chip_num != TPM_ANY_NUM && chip_num != pos->dev_num)
709 kfree(data); 674 continue;
710 return 0; 675
676 if (try_module_get(pos->dev->driver->owner)) {
677 chip = pos;
678 break;
679 }
711 } 680 }
681 rcu_read_unlock();
682 return chip;
683}
712 684
713 rc = sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); 685#define TPM_ORDINAL_PCRREAD cpu_to_be32(21)
686#define READ_PCR_RESULT_SIZE 30
687static struct tpm_input_header pcrread_header = {
688 .tag = TPM_TAG_RQU_COMMAND,
689 .length = cpu_to_be32(14),
690 .ordinal = TPM_ORDINAL_PCRREAD
691};
714 692
715 kfree(data); 693int __tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
694{
695 int rc;
696 struct tpm_cmd_t cmd;
697
698 cmd.header.in = pcrread_header;
699 cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
700 BUILD_BUG_ON(cmd.header.in.length > READ_PCR_RESULT_SIZE);
701 rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
702 "attempting to read a pcr value");
703
704 if (rc == 0)
705 memcpy(res_buf, cmd.params.pcrread_out.pcr_result,
706 TPM_DIGEST_SIZE);
716 return rc; 707 return rc;
717} 708}
718EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
719 709
720static const u8 pcrread[] = { 710/**
721 0, 193, /* TPM_TAG_RQU_COMMAND */ 711 * tpm_pcr_read - read a pcr value
722 0, 0, 0, 14, /* length */ 712 * @chip_num: tpm idx # or ANY
723 0, 0, 0, 21, /* TPM_ORD_PcrRead */ 713 * @pcr_idx: pcr idx to retrieve
724 0, 0, 0, 0 /* PCR index */ 714 * @res_buf: TPM_PCR value
715 * size of res_buf is 20 bytes (or NULL if you don't care)
716 *
717 * The TPM driver should be built-in, but for whatever reason it
718 * isn't, protect against the chip disappearing, by incrementing
719 * the module usage count.
720 */
721int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf)
722{
723 struct tpm_chip *chip;
724 int rc;
725
726 chip = tpm_chip_find_get(chip_num);
727 if (chip == NULL)
728 return -ENODEV;
729 rc = __tpm_pcr_read(chip, pcr_idx, res_buf);
730 module_put(chip->dev->driver->owner);
731 return rc;
732}
733EXPORT_SYMBOL_GPL(tpm_pcr_read);
734
735/**
736 * tpm_pcr_extend - extend pcr value with hash
737 * @chip_num: tpm idx # or AN&
738 * @pcr_idx: pcr idx to extend
739 * @hash: hash value used to extend pcr value
740 *
741 * The TPM driver should be built-in, but for whatever reason it
742 * isn't, protect against the chip disappearing, by incrementing
743 * the module usage count.
744 */
745#define TPM_ORD_PCR_EXTEND cpu_to_be32(20)
746#define EXTEND_PCR_SIZE 34
747static struct tpm_input_header pcrextend_header = {
748 .tag = TPM_TAG_RQU_COMMAND,
749 .length = cpu_to_be32(34),
750 .ordinal = TPM_ORD_PCR_EXTEND
725}; 751};
726 752
753int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
754{
755 struct tpm_cmd_t cmd;
756 int rc;
757 struct tpm_chip *chip;
758
759 chip = tpm_chip_find_get(chip_num);
760 if (chip == NULL)
761 return -ENODEV;
762
763 cmd.header.in = pcrextend_header;
764 BUILD_BUG_ON(be32_to_cpu(cmd.header.in.length) > EXTEND_PCR_SIZE);
765 cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
766 memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
767 rc = transmit_cmd(chip, &cmd, cmd.header.in.length,
768 "attempting extend a PCR value");
769
770 module_put(chip->dev->driver->owner);
771 return rc;
772}
773EXPORT_SYMBOL_GPL(tpm_pcr_extend);
774
727ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, 775ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
728 char *buf) 776 char *buf)
729{ 777{
730 u8 *data; 778 cap_t cap;
779 u8 digest[TPM_DIGEST_SIZE];
731 ssize_t rc; 780 ssize_t rc;
732 int i, j, num_pcrs; 781 int i, j, num_pcrs;
733 __be32 index;
734 char *str = buf; 782 char *str = buf;
735
736 struct tpm_chip *chip = dev_get_drvdata(dev); 783 struct tpm_chip *chip = dev_get_drvdata(dev);
737 if (chip == NULL)
738 return -ENODEV;
739 784
740 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL); 785 rc = tpm_getcap(dev, TPM_CAP_PROP_PCR, &cap,
741 if (!data)
742 return -ENOMEM;
743
744 memcpy(data, tpm_cap, sizeof(tpm_cap));
745 data[TPM_CAP_IDX] = TPM_CAP_PROP;
746 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
747
748 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
749 "attempting to determine the number of PCRS"); 786 "attempting to determine the number of PCRS");
750 if (rc) { 787 if (rc)
751 kfree(data);
752 return 0; 788 return 0;
753 }
754 789
755 num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); 790 num_pcrs = be32_to_cpu(cap.num_pcrs);
756 for (i = 0; i < num_pcrs; i++) { 791 for (i = 0; i < num_pcrs; i++) {
757 memcpy(data, pcrread, sizeof(pcrread)); 792 rc = __tpm_pcr_read(chip, i, digest);
758 index = cpu_to_be32(i);
759 memcpy(data + 10, &index, 4);
760 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
761 "attempting to read a PCR");
762 if (rc) 793 if (rc)
763 goto out; 794 break;
764 str += sprintf(str, "PCR-%02d: ", i); 795 str += sprintf(str, "PCR-%02d: ", i);
765 for (j = 0; j < TPM_DIGEST_SIZE; j++) 796 for (j = 0; j < TPM_DIGEST_SIZE; j++)
766 str += sprintf(str, "%02X ", *(data + 10 + j)); 797 str += sprintf(str, "%02X ", digest[j]);
767 str += sprintf(str, "\n"); 798 str += sprintf(str, "\n");
768 } 799 }
769out:
770 kfree(data);
771 return str - buf; 800 return str - buf;
772} 801}
773EXPORT_SYMBOL_GPL(tpm_show_pcrs); 802EXPORT_SYMBOL_GPL(tpm_show_pcrs);
774 803
775#define READ_PUBEK_RESULT_SIZE 314 804#define READ_PUBEK_RESULT_SIZE 314
776static const u8 readpubek[] = { 805#define TPM_ORD_READPUBEK cpu_to_be32(124)
777 0, 193, /* TPM_TAG_RQU_COMMAND */ 806struct tpm_input_header tpm_readpubek_header = {
778 0, 0, 0, 30, /* length */ 807 .tag = TPM_TAG_RQU_COMMAND,
779 0, 0, 0, 124, /* TPM_ORD_ReadPubek */ 808 .length = cpu_to_be32(30),
809 .ordinal = TPM_ORD_READPUBEK
780}; 810};
781 811
782ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, 812ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
783 char *buf) 813 char *buf)
784{ 814{
785 u8 *data; 815 u8 *data;
816 struct tpm_cmd_t tpm_cmd;
786 ssize_t err; 817 ssize_t err;
787 int i, rc; 818 int i, rc;
788 char *str = buf; 819 char *str = buf;
789 820
790 struct tpm_chip *chip = dev_get_drvdata(dev); 821 struct tpm_chip *chip = dev_get_drvdata(dev);
791 if (chip == NULL)
792 return -ENODEV;
793 822
794 data = kzalloc(READ_PUBEK_RESULT_SIZE, GFP_KERNEL); 823 tpm_cmd.header.in = tpm_readpubek_header;
795 if (!data) 824 err = transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
796 return -ENOMEM;
797
798 memcpy(data, readpubek, sizeof(readpubek));
799
800 err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
801 "attempting to read the PUBEK"); 825 "attempting to read the PUBEK");
802 if (err) 826 if (err)
803 goto out; 827 goto out;
@@ -812,7 +836,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
812 256 byte modulus 836 256 byte modulus
813 ignore checksum 20 bytes 837 ignore checksum 20 bytes
814 */ 838 */
815 839 data = tpm_cmd.params.readpubek_out_buffer;
816 str += 840 str +=
817 sprintf(str, 841 sprintf(str,
818 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n" 842 "Algorithm: %02X %02X %02X %02X\nEncscheme: %02X %02X\n"
@@ -832,65 +856,33 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
832 } 856 }
833out: 857out:
834 rc = str - buf; 858 rc = str - buf;
835 kfree(data);
836 return rc; 859 return rc;
837} 860}
838EXPORT_SYMBOL_GPL(tpm_show_pubek); 861EXPORT_SYMBOL_GPL(tpm_show_pubek);
839 862
840#define CAP_VERSION_1_1 6
841#define CAP_VERSION_1_2 0x1A
842#define CAP_VERSION_IDX 13
843static const u8 cap_version[] = {
844 0, 193, /* TPM_TAG_RQU_COMMAND */
845 0, 0, 0, 18, /* length */
846 0, 0, 0, 101, /* TPM_ORD_GetCapability */
847 0, 0, 0, 0,
848 0, 0, 0, 0
849};
850 863
851ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, 864ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
852 char *buf) 865 char *buf)
853{ 866{
854 u8 *data; 867 cap_t cap;
855 ssize_t rc; 868 ssize_t rc;
856 char *str = buf; 869 char *str = buf;
857 870
858 struct tpm_chip *chip = dev_get_drvdata(dev); 871 rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
859 if (chip == NULL)
860 return -ENODEV;
861
862 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
863 if (!data)
864 return -ENOMEM;
865
866 memcpy(data, tpm_cap, sizeof(tpm_cap));
867 data[TPM_CAP_IDX] = TPM_CAP_PROP;
868 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
869
870 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
871 "attempting to determine the manufacturer"); 872 "attempting to determine the manufacturer");
872 if (rc) { 873 if (rc)
873 kfree(data);
874 return 0; 874 return 0;
875 }
876
877 str += sprintf(str, "Manufacturer: 0x%x\n", 875 str += sprintf(str, "Manufacturer: 0x%x\n",
878 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); 876 be32_to_cpu(cap.manufacturer_id));
879 877
880 memcpy(data, cap_version, sizeof(cap_version)); 878 rc = tpm_getcap(dev, CAP_VERSION_1_1, &cap,
881 data[CAP_VERSION_IDX] = CAP_VERSION_1_1; 879 "attempting to determine the 1.1 version");
882 rc = transmit_cmd(chip, data, TPM_INTERNAL_RESULT_SIZE,
883 "attempting to determine the 1.1 version");
884 if (rc) 880 if (rc)
885 goto out; 881 return 0;
886
887 str += sprintf(str, 882 str += sprintf(str,
888 "TCG version: %d.%d\nFirmware version: %d.%d\n", 883 "TCG version: %d.%d\nFirmware version: %d.%d\n",
889 (int) data[14], (int) data[15], (int) data[16], 884 cap.tpm_version.Major, cap.tpm_version.Minor,
890 (int) data[17]); 885 cap.tpm_version.revMajor, cap.tpm_version.revMinor);
891
892out:
893 kfree(data);
894 return str - buf; 886 return str - buf;
895} 887}
896EXPORT_SYMBOL_GPL(tpm_show_caps); 888EXPORT_SYMBOL_GPL(tpm_show_caps);
@@ -898,51 +890,25 @@ EXPORT_SYMBOL_GPL(tpm_show_caps);
898ssize_t tpm_show_caps_1_2(struct device * dev, 890ssize_t tpm_show_caps_1_2(struct device * dev,
899 struct device_attribute * attr, char *buf) 891 struct device_attribute * attr, char *buf)
900{ 892{
901 u8 *data; 893 cap_t cap;
902 ssize_t len; 894 ssize_t rc;
903 char *str = buf; 895 char *str = buf;
904 896
905 struct tpm_chip *chip = dev_get_drvdata(dev); 897 rc = tpm_getcap(dev, TPM_CAP_PROP_MANUFACTURER, &cap,
906 if (chip == NULL) 898 "attempting to determine the manufacturer");
907 return -ENODEV; 899 if (rc)
908
909 data = kzalloc(TPM_INTERNAL_RESULT_SIZE, GFP_KERNEL);
910 if (!data)
911 return -ENOMEM;
912
913 memcpy(data, tpm_cap, sizeof(tpm_cap));
914 data[TPM_CAP_IDX] = TPM_CAP_PROP;
915 data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
916
917 len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
918 if (len <= TPM_ERROR_SIZE) {
919 dev_dbg(chip->dev, "A TPM error (%d) occurred "
920 "attempting to determine the manufacturer\n",
921 be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
922 kfree(data);
923 return 0; 900 return 0;
924 }
925
926 str += sprintf(str, "Manufacturer: 0x%x\n", 901 str += sprintf(str, "Manufacturer: 0x%x\n",
927 be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); 902 be32_to_cpu(cap.manufacturer_id));
928 903 rc = tpm_getcap(dev, CAP_VERSION_1_2, &cap,
929 memcpy(data, cap_version, sizeof(cap_version)); 904 "attempting to determine the 1.2 version");
930 data[CAP_VERSION_IDX] = CAP_VERSION_1_2; 905 if (rc)
931 906 return 0;
932 len = tpm_transmit(chip, data, TPM_INTERNAL_RESULT_SIZE);
933 if (len <= TPM_ERROR_SIZE) {
934 dev_err(chip->dev, "A TPM error (%d) occurred "
935 "attempting to determine the 1.2 version\n",
936 be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
937 goto out;
938 }
939 str += sprintf(str, 907 str += sprintf(str,
940 "TCG version: %d.%d\nFirmware version: %d.%d\n", 908 "TCG version: %d.%d\nFirmware version: %d.%d\n",
941 (int) data[16], (int) data[17], (int) data[18], 909 cap.tpm_version_1_2.Major, cap.tpm_version_1_2.Minor,
942 (int) data[19]); 910 cap.tpm_version_1_2.revMajor,
943 911 cap.tpm_version_1_2.revMinor);
944out:
945 kfree(data);
946 return str - buf; 912 return str - buf;
947} 913}
948EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); 914EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 8e30df4a4388..8e00b4ddd083 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -26,6 +26,7 @@
26#include <linux/miscdevice.h> 26#include <linux/miscdevice.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/io.h> 28#include <linux/io.h>
29#include <linux/tpm.h>
29 30
30enum tpm_timeout { 31enum tpm_timeout {
31 TPM_TIMEOUT = 5, /* msecs */ 32 TPM_TIMEOUT = 5, /* msecs */
@@ -123,6 +124,147 @@ static inline void tpm_write_index(int base, int index, int value)
123 outb(index, base); 124 outb(index, base);
124 outb(value & 0xFF, base+1); 125 outb(value & 0xFF, base+1);
125} 126}
127struct tpm_input_header {
128 __be16 tag;
129 __be32 length;
130 __be32 ordinal;
131}__attribute__((packed));
132
133struct tpm_output_header {
134 __be16 tag;
135 __be32 length;
136 __be32 return_code;
137}__attribute__((packed));
138
139struct stclear_flags_t {
140 __be16 tag;
141 u8 deactivated;
142 u8 disableForceClear;
143 u8 physicalPresence;
144 u8 physicalPresenceLock;
145 u8 bGlobalLock;
146}__attribute__((packed));
147
148struct tpm_version_t {
149 u8 Major;
150 u8 Minor;
151 u8 revMajor;
152 u8 revMinor;
153}__attribute__((packed));
154
155struct tpm_version_1_2_t {
156 __be16 tag;
157 u8 Major;
158 u8 Minor;
159 u8 revMajor;
160 u8 revMinor;
161}__attribute__((packed));
162
163struct timeout_t {
164 __be32 a;
165 __be32 b;
166 __be32 c;
167 __be32 d;
168}__attribute__((packed));
169
170struct duration_t {
171 __be32 tpm_short;
172 __be32 tpm_medium;
173 __be32 tpm_long;
174}__attribute__((packed));
175
176struct permanent_flags_t {
177 __be16 tag;
178 u8 disable;
179 u8 ownership;
180 u8 deactivated;
181 u8 readPubek;
182 u8 disableOwnerClear;
183 u8 allowMaintenance;
184 u8 physicalPresenceLifetimeLock;
185 u8 physicalPresenceHWEnable;
186 u8 physicalPresenceCMDEnable;
187 u8 CEKPUsed;
188 u8 TPMpost;
189 u8 TPMpostLock;
190 u8 FIPS;
191 u8 operator;
192 u8 enableRevokeEK;
193 u8 nvLocked;
194 u8 readSRKPub;
195 u8 tpmEstablished;
196 u8 maintenanceDone;
197 u8 disableFullDALogicInfo;
198}__attribute__((packed));
199
200typedef union {
201 struct permanent_flags_t perm_flags;
202 struct stclear_flags_t stclear_flags;
203 bool owned;
204 __be32 num_pcrs;
205 struct tpm_version_t tpm_version;
206 struct tpm_version_1_2_t tpm_version_1_2;
207 __be32 manufacturer_id;
208 struct timeout_t timeout;
209 struct duration_t duration;
210} cap_t;
211
212struct tpm_getcap_params_in {
213 __be32 cap;
214 __be32 subcap_size;
215 __be32 subcap;
216}__attribute__((packed));
217
218struct tpm_getcap_params_out {
219 __be32 cap_size;
220 cap_t cap;
221}__attribute__((packed));
222
223struct tpm_readpubek_params_out {
224 u8 algorithm[4];
225 u8 encscheme[2];
226 u8 sigscheme[2];
227 u8 parameters[12]; /*assuming RSA*/
228 __be32 keysize;
229 u8 modulus[256];
230 u8 checksum[20];
231}__attribute__((packed));
232
233typedef union {
234 struct tpm_input_header in;
235 struct tpm_output_header out;
236} tpm_cmd_header;
237
238#define TPM_DIGEST_SIZE 20
239struct tpm_pcrread_out {
240 u8 pcr_result[TPM_DIGEST_SIZE];
241}__attribute__((packed));
242
243struct tpm_pcrread_in {
244 __be32 pcr_idx;
245}__attribute__((packed));
246
247struct tpm_pcrextend_in {
248 __be32 pcr_idx;
249 u8 hash[TPM_DIGEST_SIZE];
250}__attribute__((packed));
251
252typedef union {
253 struct tpm_getcap_params_out getcap_out;
254 struct tpm_readpubek_params_out readpubek_out;
255 u8 readpubek_out_buffer[sizeof(struct tpm_readpubek_params_out)];
256 struct tpm_getcap_params_in getcap_in;
257 struct tpm_pcrread_in pcrread_in;
258 struct tpm_pcrread_out pcrread_out;
259 struct tpm_pcrextend_in pcrextend_in;
260} tpm_cmd_params;
261
262struct tpm_cmd_t {
263 tpm_cmd_header header;
264 tpm_cmd_params params;
265}__attribute__((packed));
266
267ssize_t tpm_getcap(struct device *, __be32, cap_t *, const char *);
126 268
127extern void tpm_get_timeouts(struct tpm_chip *); 269extern void tpm_get_timeouts(struct tpm_chip *);
128extern void tpm_gen_interrupt(struct tpm_chip *); 270extern void tpm_gen_interrupt(struct tpm_chip *);
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index d0e7926eb486..c64a1bc65349 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -168,12 +168,22 @@ static void atml_plat_remove(void)
168 } 168 }
169} 169}
170 170
171static struct device_driver atml_drv = { 171static int tpm_atml_suspend(struct platform_device *dev, pm_message_t msg)
172 .name = "tpm_atmel", 172{
173 .bus = &platform_bus_type, 173 return tpm_pm_suspend(&dev->dev, msg);
174 .owner = THIS_MODULE, 174}
175 .suspend = tpm_pm_suspend, 175
176 .resume = tpm_pm_resume, 176static int tpm_atml_resume(struct platform_device *dev)
177{
178 return tpm_pm_resume(&dev->dev);
179}
180static struct platform_driver atml_drv = {
181 .driver = {
182 .name = "tpm_atmel",
183 .owner = THIS_MODULE,
184 },
185 .suspend = tpm_atml_suspend,
186 .resume = tpm_atml_resume,
177}; 187};
178 188
179static int __init init_atmel(void) 189static int __init init_atmel(void)
@@ -184,7 +194,7 @@ static int __init init_atmel(void)
184 unsigned long base; 194 unsigned long base;
185 struct tpm_chip *chip; 195 struct tpm_chip *chip;
186 196
187 rc = driver_register(&atml_drv); 197 rc = platform_driver_register(&atml_drv);
188 if (rc) 198 if (rc)
189 return rc; 199 return rc;
190 200
@@ -223,13 +233,13 @@ err_rel_reg:
223 atmel_release_region(base, 233 atmel_release_region(base,
224 region_size); 234 region_size);
225err_unreg_drv: 235err_unreg_drv:
226 driver_unregister(&atml_drv); 236 platform_driver_unregister(&atml_drv);
227 return rc; 237 return rc;
228} 238}
229 239
230static void __exit cleanup_atmel(void) 240static void __exit cleanup_atmel(void)
231{ 241{
232 driver_unregister(&atml_drv); 242 platform_driver_unregister(&atml_drv);
233 atml_plat_remove(); 243 atml_plat_remove();
234} 244}
235 245
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 717af7ad1bdf..aec1931608aa 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -654,12 +654,22 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
654 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); 654 sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
655MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); 655MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
656 656
657static struct device_driver tis_drv = { 657static int tpm_tis_suspend(struct platform_device *dev, pm_message_t msg)
658 .name = "tpm_tis", 658{
659 .bus = &platform_bus_type, 659 return tpm_pm_suspend(&dev->dev, msg);
660 .owner = THIS_MODULE, 660}
661 .suspend = tpm_pm_suspend, 661
662 .resume = tpm_pm_resume, 662static int tpm_tis_resume(struct platform_device *dev)
663{
664 return tpm_pm_resume(&dev->dev);
665}
666static struct platform_driver tis_drv = {
667 .driver = {
668 .name = "tpm_tis",
669 .owner = THIS_MODULE,
670 },
671 .suspend = tpm_tis_suspend,
672 .resume = tpm_tis_resume,
663}; 673};
664 674
665static struct platform_device *pdev; 675static struct platform_device *pdev;
@@ -672,14 +682,14 @@ static int __init init_tis(void)
672 int rc; 682 int rc;
673 683
674 if (force) { 684 if (force) {
675 rc = driver_register(&tis_drv); 685 rc = platform_driver_register(&tis_drv);
676 if (rc < 0) 686 if (rc < 0)
677 return rc; 687 return rc;
678 if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0))) 688 if (IS_ERR(pdev=platform_device_register_simple("tpm_tis", -1, NULL, 0)))
679 return PTR_ERR(pdev); 689 return PTR_ERR(pdev);
680 if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) { 690 if((rc=tpm_tis_init(&pdev->dev, TIS_MEM_BASE, TIS_MEM_LEN, 0)) != 0) {
681 platform_device_unregister(pdev); 691 platform_device_unregister(pdev);
682 driver_unregister(&tis_drv); 692 platform_driver_unregister(&tis_drv);
683 } 693 }
684 return rc; 694 return rc;
685 } 695 }
@@ -711,7 +721,7 @@ static void __exit cleanup_tis(void)
711 721
712 if (force) { 722 if (force) {
713 platform_device_unregister(pdev); 723 platform_device_unregister(pdev);
714 driver_unregister(&tis_drv); 724 platform_driver_unregister(&tis_drv);
715 } else 725 } else
716 pnp_unregister_driver(&tis_pnp_driver); 726 pnp_unregister_driver(&tis_pnp_driver);
717} 727}
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index bc84e125c6bc..224f271d8cbe 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2162,13 +2162,12 @@ static int fionbio(struct file *file, int __user *p)
2162 if (get_user(nonblock, p)) 2162 if (get_user(nonblock, p))
2163 return -EFAULT; 2163 return -EFAULT;
2164 2164
2165 /* file->f_flags is still BKL protected in the fs layer - vomit */ 2165 spin_lock(&file->f_lock);
2166 lock_kernel();
2167 if (nonblock) 2166 if (nonblock)
2168 file->f_flags |= O_NONBLOCK; 2167 file->f_flags |= O_NONBLOCK;
2169 else 2168 else
2170 file->f_flags &= ~O_NONBLOCK; 2169 file->f_flags &= ~O_NONBLOCK;
2171 unlock_kernel(); 2170 spin_unlock(&file->f_lock);
2172 return 0; 2171 return 0;
2173} 2172}
2174 2173
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 4f3b3f95fc42..d94d25c12aa8 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -479,18 +479,18 @@ static const struct file_operations vcs_fops = {
479 479
480static struct class *vc_class; 480static struct class *vc_class;
481 481
482void vcs_make_sysfs(struct tty_struct *tty) 482void vcs_make_sysfs(int index)
483{ 483{
484 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL, 484 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 1), NULL,
485 "vcs%u", tty->index + 1); 485 "vcs%u", index + 1);
486 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL, 486 device_create(vc_class, NULL, MKDEV(VCS_MAJOR, index + 129), NULL,
487 "vcsa%u", tty->index + 1); 487 "vcsa%u", index + 1);
488} 488}
489 489
490void vcs_remove_sysfs(struct tty_struct *tty) 490void vcs_remove_sysfs(int index)
491{ 491{
492 device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 1)); 492 device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 1));
493 device_destroy(vc_class, MKDEV(VCS_MAJOR, tty->index + 129)); 493 device_destroy(vc_class, MKDEV(VCS_MAJOR, index + 129));
494} 494}
495 495
496int __init vcs_init(void) 496int __init vcs_init(void)
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7900bd63b36d..2c1d133819b5 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -778,6 +778,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
778 } 778 }
779 vc->vc_kmalloced = 1; 779 vc->vc_kmalloced = 1;
780 vc_init(vc, vc->vc_rows, vc->vc_cols, 1); 780 vc_init(vc, vc->vc_rows, vc->vc_cols, 1);
781 vcs_make_sysfs(currcons);
781 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param); 782 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
782 } 783 }
783 return 0; 784 return 0;
@@ -987,7 +988,9 @@ void vc_deallocate(unsigned int currcons)
987 if (vc_cons_allocated(currcons)) { 988 if (vc_cons_allocated(currcons)) {
988 struct vc_data *vc = vc_cons[currcons].d; 989 struct vc_data *vc = vc_cons[currcons].d;
989 struct vt_notifier_param param = { .vc = vc }; 990 struct vt_notifier_param param = { .vc = vc };
991
990 atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param); 992 atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, &param);
993 vcs_remove_sysfs(currcons);
991 vc->vc_sw->con_deinit(vc); 994 vc->vc_sw->con_deinit(vc);
992 put_pid(vc->vt_pid); 995 put_pid(vc->vt_pid);
993 module_put(vc->vc_sw->owner); 996 module_put(vc->vc_sw->owner);
@@ -2775,7 +2778,6 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2775 tty->termios->c_iflag |= IUTF8; 2778 tty->termios->c_iflag |= IUTF8;
2776 else 2779 else
2777 tty->termios->c_iflag &= ~IUTF8; 2780 tty->termios->c_iflag &= ~IUTF8;
2778 vcs_make_sysfs(tty);
2779 release_console_sem(); 2781 release_console_sem();
2780 return ret; 2782 return ret;
2781 } 2783 }
@@ -2795,7 +2797,6 @@ static void con_shutdown(struct tty_struct *tty)
2795 BUG_ON(vc == NULL); 2797 BUG_ON(vc == NULL);
2796 acquire_console_sem(); 2798 acquire_console_sem();
2797 vc->vc_tty = NULL; 2799 vc->vc_tty = NULL;
2798 vcs_remove_sysfs(tty);
2799 release_console_sem(); 2800 release_console_sem();
2800 tty_shutdown(tty); 2801 tty_shutdown(tty);
2801} 2802}