]> err.no Git - linux-2.6/blob - drivers/char/tpm/tpm_nsc.c
24832abe0b2dfbf55ec9647d8b559c7f192490d0
[linux-2.6] / drivers / char / tpm / tpm_nsc.c
1 /*
2  * Copyright (C) 2004 IBM Corporation
3  *
4  * Authors:
5  * Leendert van Doorn <leendert@watson.ibm.com>
6  * Dave Safford <safford@watson.ibm.com>
7  * Reiner Sailer <sailer@watson.ibm.com>
8  * Kylene Hall <kjhall@us.ibm.com>
9  *
10  * Maintained by: <tpmdd_devel@lists.sourceforge.net>
11  *
12  * Device driver for TCG/TCPA TPM (trusted platform module).
13  * Specifications at www.trustedcomputinggroup.org       
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License as
17  * published by the Free Software Foundation, version 2 of the
18  * License.
19  * 
20  */
21
22 #include "tpm.h"
23
24 /* National definitions */
25 enum tpm_nsc_addr {
26         TPM_NSC_BASE = 0x360,
27         TPM_NSC_IRQ = 0x07
28 };
29
30 enum tpm_nsc_index {
31         NSC_LDN_INDEX = 0x07,
32         NSC_SID_INDEX = 0x20,
33         NSC_LDC_INDEX = 0x30,
34         NSC_DIO_INDEX = 0x60,
35         NSC_CIO_INDEX = 0x62,
36         NSC_IRQ_INDEX = 0x70,
37         NSC_ITS_INDEX = 0x71
38 };
39
40 enum tpm_nsc_status_loc {
41         NSC_STATUS = 0x01,
42         NSC_COMMAND = 0x01,
43         NSC_DATA = 0x00
44 };
45
46 /* status bits */
47 enum tpm_nsc_status{
48         NSC_STATUS_OBF = 0x01,  /* output buffer full */
49         NSC_STATUS_IBF = 0x02,  /* input buffer full */
50         NSC_STATUS_F0 = 0x04,   /* F0 */
51         NSC_STATUS_A2 = 0x08,   /* A2 */
52         NSC_STATUS_RDY = 0x10,  /* ready to receive command */
53         NSC_STATUS_IBR = 0x20   /* ready to receive data */
54 };
55 /* command bits */
56 enum tpm_nsc_cmd_mode {
57         NSC_COMMAND_NORMAL = 0x01,      /* normal mode */
58         NSC_COMMAND_EOC = 0x03,
59         NSC_COMMAND_CANCEL = 0x22
60 };
61 /*
62  * Wait for a certain status to appear
63  */
64 static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
65 {
66         unsigned long stop;
67
68         /* status immediately available check */
69         *data = inb(chip->vendor->base + NSC_STATUS);
70         if ((*data & mask) == val)
71                 return 0;
72
73         /* wait for status */
74         stop = jiffies + 10 * HZ;
75         do {
76                 msleep(TPM_TIMEOUT);
77                 *data = inb(chip->vendor->base + 1);
78                 if ((*data & mask) == val)
79                         return 0;
80         }
81         while (time_before(jiffies, stop));
82
83         return -EBUSY;
84 }
85
86 static int nsc_wait_for_ready(struct tpm_chip *chip)
87 {
88         int status;
89         unsigned long stop;
90
91         /* status immediately available check */
92         status = inb(chip->vendor->base + NSC_STATUS);
93         if (status & NSC_STATUS_OBF)
94                 status = inb(chip->vendor->base + NSC_DATA);
95         if (status & NSC_STATUS_RDY)
96                 return 0;
97
98         /* wait for status */
99         stop = jiffies + 100;
100         do {
101                 msleep(TPM_TIMEOUT);
102                 status = inb(chip->vendor->base + NSC_STATUS);
103                 if (status & NSC_STATUS_OBF)
104                         status = inb(chip->vendor->base + NSC_DATA);
105                 if (status & NSC_STATUS_RDY)
106                         return 0;
107         }
108         while (time_before(jiffies, stop));
109
110         dev_info(&chip->pci_dev->dev, "wait for ready failed\n");
111         return -EBUSY;
112 }
113
114
115 static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
116 {
117         u8 *buffer = buf;
118         u8 data, *p;
119         u32 size;
120         __be32 *native_size;
121
122         if (count < 6)
123                 return -EIO;
124
125         if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) {
126                 dev_err(&chip->pci_dev->dev, "F0 timeout\n");
127                 return -EIO;
128         }
129         if ((data =
130              inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
131                 dev_err(&chip->pci_dev->dev, "not in normal mode (0x%x)\n",
132                         data);
133                 return -EIO;
134         }
135
136         /* read the whole packet */
137         for (p = buffer; p < &buffer[count]; p++) {
138                 if (wait_for_stat
139                     (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) {
140                         dev_err(&chip->pci_dev->dev,
141                                 "OBF timeout (while reading data)\n");
142                         return -EIO;
143                 }
144                 if (data & NSC_STATUS_F0)
145                         break;
146                 *p = inb(chip->vendor->base + NSC_DATA);
147         }
148
149         if ((data & NSC_STATUS_F0) == 0) {
150                 dev_err(&chip->pci_dev->dev, "F0 not set\n");
151                 return -EIO;
152         }
153         if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
154                 dev_err(&chip->pci_dev->dev,
155                         "expected end of command(0x%x)\n", data);
156                 return -EIO;
157         }
158
159         native_size = (__force __be32 *) (buf + 2);
160         size = be32_to_cpu(*native_size);
161
162         if (count < size)
163                 return -EIO;
164
165         return size;
166 }
167
168 static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
169 {
170         u8 data;
171         int i;
172
173         /*
174          * If we hit the chip with back to back commands it locks up
175          * and never set IBF. Hitting it with this "hammer" seems to
176          * fix it. Not sure why this is needed, we followed the flow
177          * chart in the manual to the letter.
178          */
179         outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
180
181         if (nsc_wait_for_ready(chip) != 0)
182                 return -EIO;
183
184         if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
185                 dev_err(&chip->pci_dev->dev, "IBF timeout\n");
186                 return -EIO;
187         }
188
189         outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
190         if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
191                 dev_err(&chip->pci_dev->dev, "IBR timeout\n");
192                 return -EIO;
193         }
194
195         for (i = 0; i < count; i++) {
196                 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
197                         dev_err(&chip->pci_dev->dev,
198                                 "IBF timeout (while writing data)\n");
199                         return -EIO;
200                 }
201                 outb(buf[i], chip->vendor->base + NSC_DATA);
202         }
203
204         if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
205                 dev_err(&chip->pci_dev->dev, "IBF timeout\n");
206                 return -EIO;
207         }
208         outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
209
210         return count;
211 }
212
213 static void tpm_nsc_cancel(struct tpm_chip *chip)
214 {
215         outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
216 }
217
218 static struct file_operations nsc_ops = {
219         .owner = THIS_MODULE,
220         .llseek = no_llseek,
221         .open = tpm_open,
222         .read = tpm_read,
223         .write = tpm_write,
224         .release = tpm_release,
225 };
226
227 static struct tpm_vendor_specific tpm_nsc = {
228         .recv = tpm_nsc_recv,
229         .send = tpm_nsc_send,
230         .cancel = tpm_nsc_cancel,
231         .req_complete_mask = NSC_STATUS_OBF,
232         .req_complete_val = NSC_STATUS_OBF,
233         .base = TPM_NSC_BASE,
234         .miscdev = { .fops = &nsc_ops, },
235         
236 };
237
238 static int __devinit tpm_nsc_init(struct pci_dev *pci_dev,
239                                   const struct pci_device_id *pci_id)
240 {
241         int rc = 0;
242
243         if (pci_enable_device(pci_dev))
244                 return -EIO;
245
246         if (tpm_lpc_bus_init(pci_dev, TPM_NSC_BASE)) {
247                 rc = -ENODEV;
248                 goto out_err;
249         }
250
251         /* verify that it is a National part (SID) */
252         if (tpm_read_index(NSC_SID_INDEX) != 0xEF) {
253                 rc = -ENODEV;
254                 goto out_err;
255         }
256
257         dev_dbg(&pci_dev->dev, "NSC TPM detected\n");
258         dev_dbg(&pci_dev->dev,
259                 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n",
260                 tpm_read_index(0x07), tpm_read_index(0x20),
261                 tpm_read_index(0x27));
262         dev_dbg(&pci_dev->dev,
263                 "NSC SIOCF1 0x%x SIOCF5 0x%x SIOCF6 0x%x SIOCF8 0x%x\n",
264                 tpm_read_index(0x21), tpm_read_index(0x25),
265                 tpm_read_index(0x26), tpm_read_index(0x28));
266         dev_dbg(&pci_dev->dev, "NSC IO Base0 0x%x\n",
267                 (tpm_read_index(0x60) << 8) | tpm_read_index(0x61));
268         dev_dbg(&pci_dev->dev, "NSC IO Base1 0x%x\n",
269                 (tpm_read_index(0x62) << 8) | tpm_read_index(0x63));
270         dev_dbg(&pci_dev->dev, "NSC Interrupt number and wakeup 0x%x\n",
271                 tpm_read_index(0x70));
272         dev_dbg(&pci_dev->dev, "NSC IRQ type select 0x%x\n",
273                 tpm_read_index(0x71));
274         dev_dbg(&pci_dev->dev,
275                 "NSC DMA channel select0 0x%x, select1 0x%x\n",
276                 tpm_read_index(0x74), tpm_read_index(0x75));
277         dev_dbg(&pci_dev->dev,
278                 "NSC Config "
279                 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
280                 tpm_read_index(0xF0), tpm_read_index(0xF1),
281                 tpm_read_index(0xF2), tpm_read_index(0xF3),
282                 tpm_read_index(0xF4), tpm_read_index(0xF5),
283                 tpm_read_index(0xF6), tpm_read_index(0xF7),
284                 tpm_read_index(0xF8), tpm_read_index(0xF9));
285
286         dev_info(&pci_dev->dev,
287                  "NSC PC21100 TPM revision %d\n",
288                  tpm_read_index(0x27) & 0x1F);
289
290         if (tpm_read_index(NSC_LDC_INDEX) == 0)
291                 dev_info(&pci_dev->dev, ": NSC TPM not active\n");
292
293         /* select PM channel 1 */
294         tpm_write_index(NSC_LDN_INDEX, 0x12);
295         tpm_read_index(NSC_LDN_INDEX);
296
297         /* disable the DPM module */
298         tpm_write_index(NSC_LDC_INDEX, 0);
299         tpm_read_index(NSC_LDC_INDEX);
300
301         /* set the data register base addresses */
302         tpm_write_index(NSC_DIO_INDEX, TPM_NSC_BASE >> 8);
303         tpm_write_index(NSC_DIO_INDEX + 1, TPM_NSC_BASE);
304         tpm_read_index(NSC_DIO_INDEX);
305         tpm_read_index(NSC_DIO_INDEX + 1);
306
307         /* set the command register base addresses */
308         tpm_write_index(NSC_CIO_INDEX, (TPM_NSC_BASE + 1) >> 8);
309         tpm_write_index(NSC_CIO_INDEX + 1, (TPM_NSC_BASE + 1));
310         tpm_read_index(NSC_DIO_INDEX);
311         tpm_read_index(NSC_DIO_INDEX + 1);
312
313         /* set the interrupt number to be used for the host interface */
314         tpm_write_index(NSC_IRQ_INDEX, TPM_NSC_IRQ);
315         tpm_write_index(NSC_ITS_INDEX, 0x00);
316         tpm_read_index(NSC_IRQ_INDEX);
317
318         /* enable the DPM module */
319         tpm_write_index(NSC_LDC_INDEX, 0x01);
320         tpm_read_index(NSC_LDC_INDEX);
321
322         if ((rc = tpm_register_hardware(pci_dev, &tpm_nsc)) < 0)
323                 goto out_err;
324
325         return 0;
326
327 out_err:
328         pci_disable_device(pci_dev);
329         return rc;
330 }
331
332 static struct pci_device_id tpm_pci_tbl[] __devinitdata = {
333         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0)},
334         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12)},
335         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0)},
336         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12)},
337         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0)},
338         {PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_LPC)},
339         {0,}
340 };
341
342 MODULE_DEVICE_TABLE(pci, tpm_pci_tbl);
343
344 static struct pci_driver nsc_pci_driver = {
345         .name = "tpm_nsc",
346         .id_table = tpm_pci_tbl,
347         .probe = tpm_nsc_init,
348         .remove = __devexit_p(tpm_remove),
349         .suspend = tpm_pm_suspend,
350         .resume = tpm_pm_resume,
351 };
352
353 static int __init init_nsc(void)
354 {
355         return pci_register_driver(&nsc_pci_driver);
356 }
357
358 static void __exit cleanup_nsc(void)
359 {
360         pci_unregister_driver(&nsc_pci_driver);
361 }
362
363 module_init(init_nsc);
364 module_exit(cleanup_nsc);
365
366 MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
367 MODULE_DESCRIPTION("TPM Driver");
368 MODULE_VERSION("2.0");
369 MODULE_LICENSE("GPL");