tpm_nsc.c (8cfffc9d4d3786d3b496a021d7224e06328bac7d) | tpm_nsc.c (ee1779840d093ebf6893c97115422fb5171b54d7) |
---|---|
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> --- 50 unchanged lines hidden (view full) --- 59}; 60 61/* command bits */ 62enum tpm_nsc_cmd_mode { 63 NSC_COMMAND_NORMAL = 0x01, /* normal mode */ 64 NSC_COMMAND_EOC = 0x03, 65 NSC_COMMAND_CANCEL = 0x22 66}; | 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> --- 50 unchanged lines hidden (view full) --- 59}; 60 61/* command bits */ 62enum tpm_nsc_cmd_mode { 63 NSC_COMMAND_NORMAL = 0x01, /* normal mode */ 64 NSC_COMMAND_EOC = 0x03, 65 NSC_COMMAND_CANCEL = 0x22 66}; |
67 68struct tpm_nsc_priv { 69 unsigned long base; 70}; 71 72static inline struct tpm_nsc_priv *nsc_get_priv(struct tpm_chip *chip) 73{ 74 return chip->vendor.priv; 75} 76 |
|
67/* 68 * Wait for a certain status to appear 69 */ 70static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) 71{ 72 unsigned long stop; 73 74 /* status immediately available check */ | 77/* 78 * Wait for a certain status to appear 79 */ 80static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) 81{ 82 unsigned long stop; 83 84 /* status immediately available check */ |
75 *data = inb(chip->vendor.base + NSC_STATUS); | 85 *data = inb(nsc_get_priv(chip)->base + NSC_STATUS); |
76 if ((*data & mask) == val) 77 return 0; 78 79 /* wait for status */ 80 stop = jiffies + 10 * HZ; 81 do { 82 msleep(TPM_TIMEOUT); | 86 if ((*data & mask) == val) 87 return 0; 88 89 /* wait for status */ 90 stop = jiffies + 10 * HZ; 91 do { 92 msleep(TPM_TIMEOUT); |
83 *data = inb(chip->vendor.base + 1); | 93 *data = inb(nsc_get_priv(chip)->base + 1); |
84 if ((*data & mask) == val) 85 return 0; 86 } 87 while (time_before(jiffies, stop)); 88 89 return -EBUSY; 90} 91 92static int nsc_wait_for_ready(struct tpm_chip *chip) 93{ 94 int status; 95 unsigned long stop; 96 97 /* status immediately available check */ | 94 if ((*data & mask) == val) 95 return 0; 96 } 97 while (time_before(jiffies, stop)); 98 99 return -EBUSY; 100} 101 102static int nsc_wait_for_ready(struct tpm_chip *chip) 103{ 104 int status; 105 unsigned long stop; 106 107 /* status immediately available check */ |
98 status = inb(chip->vendor.base + NSC_STATUS); | 108 status = inb(nsc_get_priv(chip)->base + NSC_STATUS); |
99 if (status & NSC_STATUS_OBF) | 109 if (status & NSC_STATUS_OBF) |
100 status = inb(chip->vendor.base + NSC_DATA); | 110 status = inb(nsc_get_priv(chip)->base + NSC_DATA); |
101 if (status & NSC_STATUS_RDY) 102 return 0; 103 104 /* wait for status */ 105 stop = jiffies + 100; 106 do { 107 msleep(TPM_TIMEOUT); | 111 if (status & NSC_STATUS_RDY) 112 return 0; 113 114 /* wait for status */ 115 stop = jiffies + 100; 116 do { 117 msleep(TPM_TIMEOUT); |
108 status = inb(chip->vendor.base + NSC_STATUS); | 118 status = inb(nsc_get_priv(chip)->base + NSC_STATUS); |
109 if (status & NSC_STATUS_OBF) | 119 if (status & NSC_STATUS_OBF) |
110 status = inb(chip->vendor.base + NSC_DATA); | 120 status = inb(nsc_get_priv(chip)->base + NSC_DATA); |
111 if (status & NSC_STATUS_RDY) 112 return 0; 113 } 114 while (time_before(jiffies, stop)); 115 116 dev_info(&chip->dev, "wait for ready failed\n"); 117 return -EBUSY; 118} --- 8 unchanged lines hidden (view full) --- 127 128 if (count < 6) 129 return -EIO; 130 131 if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { 132 dev_err(&chip->dev, "F0 timeout\n"); 133 return -EIO; 134 } | 121 if (status & NSC_STATUS_RDY) 122 return 0; 123 } 124 while (time_before(jiffies, stop)); 125 126 dev_info(&chip->dev, "wait for ready failed\n"); 127 return -EBUSY; 128} --- 8 unchanged lines hidden (view full) --- 137 138 if (count < 6) 139 return -EIO; 140 141 if (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0) { 142 dev_err(&chip->dev, "F0 timeout\n"); 143 return -EIO; 144 } |
135 if ((data = 136 inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) { | 145 146 data = inb(nsc_get_priv(chip)->base + NSC_DATA); 147 if (data != NSC_COMMAND_NORMAL) { |
137 dev_err(&chip->dev, "not in normal mode (0x%x)\n", 138 data); 139 return -EIO; 140 } 141 142 /* read the whole packet */ 143 for (p = buffer; p < &buffer[count]; p++) { 144 if (wait_for_stat 145 (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { 146 dev_err(&chip->dev, 147 "OBF timeout (while reading data)\n"); 148 return -EIO; 149 } 150 if (data & NSC_STATUS_F0) 151 break; | 148 dev_err(&chip->dev, "not in normal mode (0x%x)\n", 149 data); 150 return -EIO; 151 } 152 153 /* read the whole packet */ 154 for (p = buffer; p < &buffer[count]; p++) { 155 if (wait_for_stat 156 (chip, NSC_STATUS_OBF, NSC_STATUS_OBF, &data) < 0) { 157 dev_err(&chip->dev, 158 "OBF timeout (while reading data)\n"); 159 return -EIO; 160 } 161 if (data & NSC_STATUS_F0) 162 break; |
152 *p = inb(chip->vendor.base + NSC_DATA); | 163 *p = inb(nsc_get_priv(chip)->base + NSC_DATA); |
153 } 154 155 if ((data & NSC_STATUS_F0) == 0 && 156 (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { 157 dev_err(&chip->dev, "F0 not set\n"); 158 return -EIO; 159 } | 164 } 165 166 if ((data & NSC_STATUS_F0) == 0 && 167 (wait_for_stat(chip, NSC_STATUS_F0, NSC_STATUS_F0, &data) < 0)) { 168 dev_err(&chip->dev, "F0 not set\n"); 169 return -EIO; 170 } |
160 if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) { | 171 172 data = inb(nsc_get_priv(chip)->base + NSC_DATA); 173 if (data != NSC_COMMAND_EOC) { |
161 dev_err(&chip->dev, 162 "expected end of command(0x%x)\n", data); 163 return -EIO; 164 } 165 166 native_size = (__force __be32 *) (buf + 2); 167 size = be32_to_cpu(*native_size); 168 --- 9 unchanged lines hidden (view full) --- 178 int i; 179 180 /* 181 * If we hit the chip with back to back commands it locks up 182 * and never set IBF. Hitting it with this "hammer" seems to 183 * fix it. Not sure why this is needed, we followed the flow 184 * chart in the manual to the letter. 185 */ | 174 dev_err(&chip->dev, 175 "expected end of command(0x%x)\n", data); 176 return -EIO; 177 } 178 179 native_size = (__force __be32 *) (buf + 2); 180 size = be32_to_cpu(*native_size); 181 --- 9 unchanged lines hidden (view full) --- 191 int i; 192 193 /* 194 * If we hit the chip with back to back commands it locks up 195 * and never set IBF. Hitting it with this "hammer" seems to 196 * fix it. Not sure why this is needed, we followed the flow 197 * chart in the manual to the letter. 198 */ |
186 outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND); | 199 outb(NSC_COMMAND_CANCEL, nsc_get_priv(chip)->base + NSC_COMMAND); |
187 188 if (nsc_wait_for_ready(chip) != 0) 189 return -EIO; 190 191 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 192 dev_err(&chip->dev, "IBF timeout\n"); 193 return -EIO; 194 } 195 | 200 201 if (nsc_wait_for_ready(chip) != 0) 202 return -EIO; 203 204 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 205 dev_err(&chip->dev, "IBF timeout\n"); 206 return -EIO; 207 } 208 |
196 outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND); | 209 outb(NSC_COMMAND_NORMAL, nsc_get_priv(chip)->base + NSC_COMMAND); |
197 if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { 198 dev_err(&chip->dev, "IBR timeout\n"); 199 return -EIO; 200 } 201 202 for (i = 0; i < count; i++) { 203 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 204 dev_err(&chip->dev, 205 "IBF timeout (while writing data)\n"); 206 return -EIO; 207 } | 210 if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { 211 dev_err(&chip->dev, "IBR timeout\n"); 212 return -EIO; 213 } 214 215 for (i = 0; i < count; i++) { 216 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 217 dev_err(&chip->dev, 218 "IBF timeout (while writing data)\n"); 219 return -EIO; 220 } |
208 outb(buf[i], chip->vendor.base + NSC_DATA); | 221 outb(buf[i], nsc_get_priv(chip)->base + NSC_DATA); |
209 } 210 211 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 212 dev_err(&chip->dev, "IBF timeout\n"); 213 return -EIO; 214 } | 222 } 223 224 if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { 225 dev_err(&chip->dev, "IBF timeout\n"); 226 return -EIO; 227 } |
215 outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND); | 228 outb(NSC_COMMAND_EOC, nsc_get_priv(chip)->base + NSC_COMMAND); |
216 217 return count; 218} 219 220static void tpm_nsc_cancel(struct tpm_chip *chip) 221{ | 229 230 return count; 231} 232 233static void tpm_nsc_cancel(struct tpm_chip *chip) 234{ |
222 outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND); | 235 outb(NSC_COMMAND_CANCEL, nsc_get_priv(chip)->base + NSC_COMMAND); |
223} 224 225static u8 tpm_nsc_status(struct tpm_chip *chip) 226{ | 236} 237 238static u8 tpm_nsc_status(struct tpm_chip *chip) 239{ |
227 return inb(chip->vendor.base + NSC_STATUS); | 240 return inb(nsc_get_priv(chip)->base + NSC_STATUS); |
228} 229 230static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status) 231{ 232 return (status == NSC_STATUS_RDY); 233} 234 235static const struct tpm_class_ops tpm_nsc = { --- 8 unchanged lines hidden (view full) --- 244 245static struct platform_device *pdev = NULL; 246 247static void tpm_nsc_remove(struct device *dev) 248{ 249 struct tpm_chip *chip = dev_get_drvdata(dev); 250 251 tpm_chip_unregister(chip); | 241} 242 243static bool tpm_nsc_req_canceled(struct tpm_chip *chip, u8 status) 244{ 245 return (status == NSC_STATUS_RDY); 246} 247 248static const struct tpm_class_ops tpm_nsc = { --- 8 unchanged lines hidden (view full) --- 257 258static struct platform_device *pdev = NULL; 259 260static void tpm_nsc_remove(struct device *dev) 261{ 262 struct tpm_chip *chip = dev_get_drvdata(dev); 263 264 tpm_chip_unregister(chip); |
252 release_region(chip->vendor.base, 2); | 265 release_region(nsc_get_priv(chip)->base, 2); |
253} 254 255static SIMPLE_DEV_PM_OPS(tpm_nsc_pm, tpm_pm_suspend, tpm_pm_resume); 256 257static struct platform_driver nsc_drv = { 258 .driver = { 259 .name = "tpm_nsc", 260 .pm = &tpm_nsc_pm, 261 }, 262}; 263 264static int __init init_nsc(void) 265{ 266 int rc = 0; 267 int lo, hi, err; 268 int nscAddrBase = TPM_ADDR; 269 struct tpm_chip *chip; 270 unsigned long base; | 266} 267 268static SIMPLE_DEV_PM_OPS(tpm_nsc_pm, tpm_pm_suspend, tpm_pm_resume); 269 270static struct platform_driver nsc_drv = { 271 .driver = { 272 .name = "tpm_nsc", 273 .pm = &tpm_nsc_pm, 274 }, 275}; 276 277static int __init init_nsc(void) 278{ 279 int rc = 0; 280 int lo, hi, err; 281 int nscAddrBase = TPM_ADDR; 282 struct tpm_chip *chip; 283 unsigned long base; |
284 struct tpm_nsc_priv *priv; |
|
271 272 /* verify that it is a National part (SID) */ 273 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { 274 nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| 275 (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); 276 if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) 277 return -ENODEV; 278 } --- 17 unchanged lines hidden (view full) --- 296 297 pdev->num_resources = 0; 298 pdev->dev.driver = &nsc_drv.driver; 299 pdev->dev.release = tpm_nsc_remove; 300 301 if ((rc = platform_device_add(pdev)) < 0) 302 goto err_put_dev; 303 | 285 286 /* verify that it is a National part (SID) */ 287 if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { 288 nscAddrBase = (tpm_read_index(TPM_SUPERIO_ADDR, 0x2C)<<8)| 289 (tpm_read_index(TPM_SUPERIO_ADDR, 0x2B)&0xFE); 290 if (tpm_read_index(nscAddrBase, NSC_SID_INDEX) != 0xF6) 291 return -ENODEV; 292 } --- 17 unchanged lines hidden (view full) --- 310 311 pdev->num_resources = 0; 312 pdev->dev.driver = &nsc_drv.driver; 313 pdev->dev.release = tpm_nsc_remove; 314 315 if ((rc = platform_device_add(pdev)) < 0) 316 goto err_put_dev; 317 |
318 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 319 if (!priv) { 320 rc = -ENOMEM; 321 goto err_del_dev; 322 } 323 324 priv->base = base; 325 |
|
304 if (request_region(base, 2, "tpm_nsc0") == NULL ) { 305 rc = -EBUSY; 306 goto err_del_dev; 307 } 308 309 chip = tpmm_chip_alloc(&pdev->dev, &tpm_nsc); 310 if (IS_ERR(chip)) { 311 rc = -ENODEV; 312 goto err_rel_reg; 313 } 314 | 326 if (request_region(base, 2, "tpm_nsc0") == NULL ) { 327 rc = -EBUSY; 328 goto err_del_dev; 329 } 330 331 chip = tpmm_chip_alloc(&pdev->dev, &tpm_nsc); 332 if (IS_ERR(chip)) { 333 rc = -ENODEV; 334 goto err_rel_reg; 335 } 336 |
337 chip->vendor.priv = priv; 338 |
|
315 rc = tpm_chip_register(chip); 316 if (rc) 317 goto err_rel_reg; 318 319 dev_dbg(&pdev->dev, "NSC TPM detected\n"); 320 dev_dbg(&pdev->dev, 321 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", 322 tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), --- 21 unchanged lines hidden (view full) --- 344 tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5), 345 tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), 346 tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); 347 348 dev_info(&pdev->dev, 349 "NSC TPM revision %d\n", 350 tpm_read_index(nscAddrBase, 0x27) & 0x1F); 351 | 339 rc = tpm_chip_register(chip); 340 if (rc) 341 goto err_rel_reg; 342 343 dev_dbg(&pdev->dev, "NSC TPM detected\n"); 344 dev_dbg(&pdev->dev, 345 "NSC LDN 0x%x, SID 0x%x, SRID 0x%x\n", 346 tpm_read_index(nscAddrBase,0x07), tpm_read_index(nscAddrBase,0x20), --- 21 unchanged lines hidden (view full) --- 368 tpm_read_index(nscAddrBase,0xF4), tpm_read_index(nscAddrBase,0xF5), 369 tpm_read_index(nscAddrBase,0xF6), tpm_read_index(nscAddrBase,0xF7), 370 tpm_read_index(nscAddrBase,0xF8), tpm_read_index(nscAddrBase,0xF9)); 371 372 dev_info(&pdev->dev, 373 "NSC TPM revision %d\n", 374 tpm_read_index(nscAddrBase, 0x27) & 0x1F); 375 |
352 chip->vendor.base = base; 353 | |
354 return 0; 355 356err_rel_reg: 357 release_region(base, 2); 358err_del_dev: 359 platform_device_del(pdev); 360err_put_dev: 361 platform_device_put(pdev); --- 22 unchanged lines hidden --- | 376 return 0; 377 378err_rel_reg: 379 release_region(base, 2); 380err_del_dev: 381 platform_device_del(pdev); 382err_put_dev: 383 platform_device_put(pdev); --- 22 unchanged lines hidden --- |