diff options
author | Nishanth Aravamudan <nacc@us.ibm.com> | 2005-06-24 01:01:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-24 03:05:24 -0400 |
commit | 700d8bdcd0fa815b08638b1e4d43b66d60cc6a8d (patch) | |
tree | c3defbf1cb77b9290a002cff04e1b2f054dfcb05 /drivers/char | |
parent | 6a94f9209762a6eb286f668e1346ad87985cc765 (diff) |
[PATCH] char/tpm: use msleep(), clean-up timers,
The TPM driver unnecessarily uses timers when it simply needs to maintain a
maximum delay via time_before(). msleep() is used instead of
schedule_timeout() to guarantee the task delays as expected. While
compile-testing, I found a typo in the driver, using tpm_chp instead of
tpm_chip. Remove the now unused timer callback function and change
TPM_TIMEOUT's units to milliseconds. Patch is compile-tested.
Signed-off-by: Nishanth Aravamudan <nacc@us.ibm.com>
Acked-by: Kylene Hall <kjhall@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/tpm/tpm.c | 35 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 3 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_nsc.c | 32 |
3 files changed, 18 insertions, 52 deletions
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 8ce508b29865..c937ea2bcdbc 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -19,7 +19,7 @@ | |||
19 | * | 19 | * |
20 | * Note, the TPM chip is not interrupt driven (only polling) | 20 | * Note, the TPM chip is not interrupt driven (only polling) |
21 | * and can have very long timeouts (minutes!). Hence the unusual | 21 | * and can have very long timeouts (minutes!). Hence the unusual |
22 | * calls to schedule_timeout. | 22 | * calls to msleep. |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
@@ -52,14 +52,6 @@ static void user_reader_timeout(unsigned long ptr) | |||
52 | up(&chip->buffer_mutex); | 52 | up(&chip->buffer_mutex); |
53 | } | 53 | } |
54 | 54 | ||
55 | void tpm_time_expired(unsigned long ptr) | ||
56 | { | ||
57 | int *exp = (int *) ptr; | ||
58 | *exp = 1; | ||
59 | } | ||
60 | |||
61 | EXPORT_SYMBOL_GPL(tpm_time_expired); | ||
62 | |||
63 | /* | 55 | /* |
64 | * Initialize the LPC bus and enable the TPM ports | 56 | * Initialize the LPC bus and enable the TPM ports |
65 | */ | 57 | */ |
@@ -135,6 +127,7 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
135 | ssize_t len; | 127 | ssize_t len; |
136 | u32 count; | 128 | u32 count; |
137 | __be32 *native_size; | 129 | __be32 *native_size; |
130 | unsigned long stop; | ||
138 | 131 | ||
139 | native_size = (__force __be32 *) (buf + 2); | 132 | native_size = (__force __be32 *) (buf + 2); |
140 | count = be32_to_cpu(*native_size); | 133 | count = be32_to_cpu(*native_size); |
@@ -155,28 +148,16 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
155 | return len; | 148 | return len; |
156 | } | 149 | } |
157 | 150 | ||
158 | down(&chip->timer_manipulation_mutex); | 151 | stop = jiffies + 2 * 60 * HZ; |
159 | chip->time_expired = 0; | ||
160 | init_timer(&chip->device_timer); | ||
161 | chip->device_timer.function = tpm_time_expired; | ||
162 | chip->device_timer.expires = jiffies + 2 * 60 * HZ; | ||
163 | chip->device_timer.data = (unsigned long) &chip->time_expired; | ||
164 | add_timer(&chip->device_timer); | ||
165 | up(&chip->timer_manipulation_mutex); | ||
166 | |||
167 | do { | 152 | do { |
168 | u8 status = inb(chip->vendor->base + 1); | 153 | u8 status = inb(chip->vendor->base + 1); |
169 | if ((status & chip->vendor->req_complete_mask) == | 154 | if ((status & chip->vendor->req_complete_mask) == |
170 | chip->vendor->req_complete_val) { | 155 | chip->vendor->req_complete_val) { |
171 | down(&chip->timer_manipulation_mutex); | ||
172 | del_singleshot_timer_sync(&chip->device_timer); | ||
173 | up(&chip->timer_manipulation_mutex); | ||
174 | goto out_recv; | 156 | goto out_recv; |
175 | } | 157 | } |
176 | set_current_state(TASK_UNINTERRUPTIBLE); | 158 | msleep(TPM_TIMEOUT); /* CHECK */ |
177 | schedule_timeout(TPM_TIMEOUT); | ||
178 | rmb(); | 159 | rmb(); |
179 | } while (!chip->time_expired); | 160 | } while (time_before(jiffies, stop)); |
180 | 161 | ||
181 | 162 | ||
182 | chip->vendor->cancel(chip); | 163 | chip->vendor->cancel(chip); |
@@ -453,10 +434,8 @@ ssize_t tpm_write(struct file * file, const char __user * buf, | |||
453 | 434 | ||
454 | /* cannot perform a write until the read has cleared | 435 | /* cannot perform a write until the read has cleared |
455 | either via tpm_read or a user_read_timer timeout */ | 436 | either via tpm_read or a user_read_timer timeout */ |
456 | while (atomic_read(&chip->data_pending) != 0) { | 437 | while (atomic_read(&chip->data_pending) != 0) |
457 | set_current_state(TASK_UNINTERRUPTIBLE); | 438 | msleep(TPM_TIMEOUT); |
458 | schedule_timeout(TPM_TIMEOUT); | ||
459 | } | ||
460 | 439 | ||
461 | down(&chip->buffer_mutex); | 440 | down(&chip->buffer_mutex); |
462 | 441 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index de0c796fce80..3c4ee433ec7f 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
26 | #include <linux/miscdevice.h> | 26 | #include <linux/miscdevice.h> |
27 | 27 | ||
28 | #define TPM_TIMEOUT msecs_to_jiffies(5) | 28 | #define TPM_TIMEOUT 5 /* msecs */ |
29 | 29 | ||
30 | /* TPM addresses */ | 30 | /* TPM addresses */ |
31 | #define TPM_ADDR 0x4E | 31 | #define TPM_ADDR 0x4E |
@@ -78,7 +78,6 @@ static inline void tpm_write_index(int index, int value) | |||
78 | outb(value & 0xFF, TPM_DATA); | 78 | outb(value & 0xFF, TPM_DATA); |
79 | } | 79 | } |
80 | 80 | ||
81 | extern void tpm_time_expired(unsigned long); | ||
82 | extern int tpm_lpc_bus_init(struct pci_dev *, u16); | 81 | extern int tpm_lpc_bus_init(struct pci_dev *, u16); |
83 | 82 | ||
84 | extern int tpm_register_hardware(struct pci_dev *, | 83 | extern int tpm_register_hardware(struct pci_dev *, |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 9cce833a0923..6e5ffcacea60 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -55,10 +55,7 @@ | |||
55 | */ | 55 | */ |
56 | static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) | 56 | static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) |
57 | { | 57 | { |
58 | int expired = 0; | 58 | unsigned long stop; |
59 | struct timer_list status_timer = | ||
60 | TIMER_INITIALIZER(tpm_time_expired, jiffies + 10 * HZ, | ||
61 | (unsigned long) &expired); | ||
62 | 59 | ||
63 | /* status immediately available check */ | 60 | /* status immediately available check */ |
64 | *data = inb(chip->vendor->base + NSC_STATUS); | 61 | *data = inb(chip->vendor->base + NSC_STATUS); |
@@ -66,17 +63,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) | |||
66 | return 0; | 63 | return 0; |
67 | 64 | ||
68 | /* wait for status */ | 65 | /* wait for status */ |
69 | add_timer(&status_timer); | 66 | stop = jiffies + 10 * HZ; |
70 | do { | 67 | do { |
71 | set_current_state(TASK_UNINTERRUPTIBLE); | 68 | msleep(TPM_TIMEOUT); |
72 | schedule_timeout(TPM_TIMEOUT); | ||
73 | *data = inb(chip->vendor->base + 1); | 69 | *data = inb(chip->vendor->base + 1); |
74 | if ((*data & mask) == val) { | 70 | if ((*data & mask) == val) |
75 | del_singleshot_timer_sync(&status_timer); | ||
76 | return 0; | 71 | return 0; |
77 | } | ||
78 | } | 72 | } |
79 | while (!expired); | 73 | while (time_before(jiffies, stop)); |
80 | 74 | ||
81 | return -EBUSY; | 75 | return -EBUSY; |
82 | } | 76 | } |
@@ -84,10 +78,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) | |||
84 | static int nsc_wait_for_ready(struct tpm_chip *chip) | 78 | static int nsc_wait_for_ready(struct tpm_chip *chip) |
85 | { | 79 | { |
86 | int status; | 80 | int status; |
87 | int expired = 0; | 81 | unsigned long stop; |
88 | struct timer_list status_timer = | ||
89 | TIMER_INITIALIZER(tpm_time_expired, jiffies + 100, | ||
90 | (unsigned long) &expired); | ||
91 | 82 | ||
92 | /* status immediately available check */ | 83 | /* status immediately available check */ |
93 | status = inb(chip->vendor->base + NSC_STATUS); | 84 | status = inb(chip->vendor->base + NSC_STATUS); |
@@ -97,19 +88,16 @@ static int nsc_wait_for_ready(struct tpm_chip *chip) | |||
97 | return 0; | 88 | return 0; |
98 | 89 | ||
99 | /* wait for status */ | 90 | /* wait for status */ |
100 | add_timer(&status_timer); | 91 | stop = jiffies + 100; |
101 | do { | 92 | do { |
102 | set_current_state(TASK_UNINTERRUPTIBLE); | 93 | msleep(TPM_TIMEOUT); |
103 | schedule_timeout(TPM_TIMEOUT); | ||
104 | status = inb(chip->vendor->base + NSC_STATUS); | 94 | status = inb(chip->vendor->base + NSC_STATUS); |
105 | if (status & NSC_STATUS_OBF) | 95 | if (status & NSC_STATUS_OBF) |
106 | status = inb(chip->vendor->base + NSC_DATA); | 96 | status = inb(chip->vendor->base + NSC_DATA); |
107 | if (status & NSC_STATUS_RDY) { | 97 | if (status & NSC_STATUS_RDY) |
108 | del_singleshot_timer_sync(&status_timer); | ||
109 | return 0; | 98 | return 0; |
110 | } | ||
111 | } | 99 | } |
112 | while (!expired); | 100 | while (time_before(jiffies, stop)); |
113 | 101 | ||
114 | dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); | 102 | dev_info(&chip->pci_dev->dev, "wait for ready failed\n"); |
115 | return -EBUSY; | 103 | return -EBUSY; |