* [PATCH 4/7] tpm: return chip from tpm_register_hardware
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, TPM Device Driver List, Marcel Selhorst
Changes in the 1.2 TPM Specification make it necessary to update some
fields of the chip structure in the initialization function after it is
registered with tpm.c thus tpm_register_hardware was modified to return
a pointer to the structure. This patch makes that change and the
associated changes in tpm_atmel and tpm_nsc. The changes to
tpm_infineon will be coming in a patch from Marcel Selhorst.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
drivers/char/tpm/tpm.c | 11 ++++++-----
drivers/char/tpm/tpm.h | 10 +++++-----
drivers/char/tpm/tpm_atmel.c | 32 ++++++++++++++++++++++----------
drivers/char/tpm/tpm_atmel.h | 25 +++++++++++--------------
drivers/char/tpm/tpm_nsc.c | 17 +++++++++++------
5 files changed, 55 insertions(+), 40 deletions(-)
--- linux-2.6.16/drivers/char/tpm/tpm.c 2006-03-30 15:39:35.320462000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c 2006-03-30 16:28:14.690911250 -0600
@@ -558,7 +1095,8 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
* upon errant exit from this function specific probe function should call
* pci_disable_device
*/
-int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
+struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
+ *entry)
{
#define DEVNAME_SIZE 7
@@ -569,7 +1107,7 @@ int tpm_register_hardware(struct device
/* Driver specific per-device data */
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
- return -ENOMEM;
+ return NULL;
init_MUTEX(&chip->buffer_mutex);
init_MUTEX(&chip->tpm_mutex);
@@ -598,7 +1136,7 @@ dev_num_search_complete:
if (chip->dev_num < 0) {
dev_err(dev, "No available tpm device numbers\n");
kfree(chip);
- return -ENODEV;
+ return NULL;
} else if (chip->dev_num == 0)
chip->vendor.miscdev.minor = TPM_MINOR;
else
@@ -619,7 +1157,7 @@ dev_num_search_complete:
put_device(dev);
kfree(chip);
dev_mask[i] &= !(1 << j);
- return -ENODEV;
+ return NULL;
}
spin_lock(&driver_lock);
@@ -634,7 +1172,7 @@ dev_num_search_complete:
chip->bios_dir = tpm_bios_log_setup(devname);
- return 0;
+ return chip;
}
EXPORT_SYMBOL_GPL(tpm_register_hardware);
--- linux-2.6.16/drivers/char/tpm/tpm.h 2006-03-30 15:39:35.320462000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.h 2006-03-29 14:16:30.119053500 -0600
@@ -41,9 +41,9 @@ extern ssize_t tpm_show_pcrs(struct devi
struct tpm_chip;
struct tpm_vendor_specific {
- u8 req_complete_mask;
- u8 req_complete_val;
- u8 req_canceled;
+ const u8 req_complete_mask;
+ const u8 req_complete_val;
+ const u8 req_canceled;
void __iomem *iobase; /* ioremapped address */
unsigned long base; /* TPM base address */
@@ -99,8 +114,8 @@ static inline void tpm_write_index(int b
outb(value & 0xFF, base+1);
}
-extern int tpm_register_hardware(struct device *,
- struct tpm_vendor_specific *);
+extern struct tpm_chip* tpm_register_hardware(struct device *,
+ const struct tpm_vendor_specific *);
extern int tpm_open(struct inode *, struct file *);
extern int tpm_release(struct inode *, struct file *);
extern ssize_t tpm_write(struct file *, const char __user *, size_t,
--- linux-2.6.16/drivers/char/tpm/tpm_atmel.c 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm_atmel.c 2006-03-02 15:04:40.663271500 -0600
@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] =
static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
-static struct tpm_vendor_specific tpm_atmel = {
+static const struct tpm_vendor_specific tpm_atmel = {
.recv = tpm_atml_recv,
.send = tpm_atml_send,
.cancel = tpm_atml_cancel,
@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
static int __init init_atmel(void)
{
int rc = 0;
+ void __iomem *iobase = NULL;
+ int have_region, region_size;
+ unsigned long base;
+ struct tpm_chip *chip;
driver_register(&atml_drv);
- if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
+ if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) {
rc = -ENODEV;
goto err_unreg_drv;
}
- tpm_atmel.have_region =
+ have_region =
(atmel_request_region
- (tpm_atmel.base, tpm_atmel.region_size,
- "tpm_atmel0") == NULL) ? 0 : 1;
+ (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
+
if (IS_ERR
(pdev =
@@ -199,17 +203,25 @@ static int __init init_atmel(void)
goto err_rel_reg;
}
- if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
+ if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
+ rc = -ENODEV;
goto err_unreg_dev;
+ }
+
+ chip->vendor.iobase = iobase;
+ chip->vendor.base = base;
+ chip->vendor.have_region = have_region;
+ chip->vendor.region_size = region_size;
+
return 0;
err_unreg_dev:
platform_device_unregister(pdev);
err_rel_reg:
- atmel_put_base_addr(&tpm_atmel);
- if (tpm_atmel.have_region)
- atmel_release_region(tpm_atmel.base,
- tpm_atmel.region_size);
+ atmel_put_base_addr(iobase);
+ if (have_region)
+ atmel_release_region(base,
+ region_size);
err_unreg_drv:
driver_unregister(&atml_drv);
return rc;
--- linux-2.6.16/drivers/char/tpm/tpm_atmel.h 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm_atmel.h 2006-03-02 14:50:27.725966250 -0600
@@ -28,13 +28,12 @@
#define atmel_request_region request_mem_region
#define atmel_release_region release_mem_region
-static inline void atmel_put_base_addr(struct tpm_vendor_specific
- *vendor)
+static inline void atmel_put_base_addr(void __iomem *iobase)
{
- iounmap(vendor->iobase);
+ iounmap(iobase);
}
-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
{
struct device_node *dn;
unsigned long address, size;
@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_add
else
size = reg[naddrc];
- vendor->base = address;
- vendor->region_size = size;
- return ioremap(vendor->base, vendor->region_size);
+ *base = address;
+ *region_size = size;
+ return ioremap(*base, *region_size);
}
#else
#define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
return 0;
}
-static inline void atmel_put_base_addr(struct tpm_vendor_specific
- *vendor)
+static inline void atmel_put_base_addr(void __iomem *iobase)
{
}
/* Determine where to talk to device */
-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
- *vendor)
+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
{
int lo, hi;
@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_add
lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
- vendor->base = (hi << 8) | lo;
- vendor->region_size = 2;
+ *base = (hi << 8) | lo;
+ *region_size = 2;
- return ioport_map(vendor->base, vendor->region_size);
+ return ioport_map(*base, *region_size);
}
#endif
--- linux-2.6.16/drivers/char/tpm/tpm_nsc.c 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm_nsc.c 2006-03-02 15:06:07.188679000 -0600
@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] =
static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
-static struct tpm_vendor_specific tpm_nsc = {
+static const struct tpm_vendor_specific tpm_nsc = {
.recv = tpm_nsc_recv,
.send = tpm_nsc_send,
.cancel = tpm_nsc_cancel,
@@ -286,7 +286,8 @@ static int __init init_nsc(void)
int rc = 0;
int lo, hi;
int nscAddrBase = TPM_ADDR;
-
+ struct tpm_chip *chip;
+ unsigned long base;
/* verify that it is a National part (SID) */
if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,7 +301,7 @@ static int __init init_nsc(void)
hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
- tpm_nsc.base = (hi<<8) | lo;
+ base = (hi<<8) | lo;
/* enable the DPM module */
tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
@@ -320,13 +321,15 @@ static int __init init_nsc(void)
if ((rc = platform_device_register(pdev)) < 0)
goto err_free_dev;
- if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
+ if (request_region(base, 2, "tpm_nsc0") == NULL ) {
rc = -EBUSY;
goto err_unreg_dev;
}
- if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
+ if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
+ rc = -ENODEV;
goto err_rel_reg;
+ }
dev_dbg(&pdev->dev, "NSC TPM detected\n");
dev_dbg(&pdev->dev,
@@ -361,10 +364,12 @@ static int __init init_nsc(void)
"NSC TPM revision %d\n",
tpm_read_index(nscAddrBase, 0x27) & 0x1F);
+ chip->vendor.base = base;
+
return 0;
err_rel_reg:
- release_region(tpm_nsc.base, 2);
+ release_region(base, 2);
err_unreg_dev:
platform_device_unregister(pdev);
err_free_dev:
^ permalink raw reply
* [PATCH 3/7] tpm: chip struct update
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, TPM Device Driver List, Marcel Selhorst
To assist with chip management and better support the possibility of
having multiple TPMs in the system of the same kind, the struct
tpm_vendor_specific member of the tpm_chip was changed from a pointer to
an instance. This patch changes that declaration and fixes up all
accesses to the structure member except in tpm_infineon which is coming
in a patch from Marcel Selhorst.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
drivers/char/tpm/tpm.c | 48 +++++++++++++++------------------
drivers/char/tpm/tpm.h | 2 -
drivers/char/tpm/tpm_atmel.c | 26 ++++++++---------
drivers/char/tpm/tpm_nsc.c | 32 +++++++++++-----------
4 files changed, 53 insertions(+), 55 deletions(-)
--- linux-2.6.16/drivers/char/tpm/tpm.c 2006-03-30 15:08:43.400724250 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c 2006-03-29 14:17:14.421822250 -0600
@@ -78,21 +385,20 @@ static ssize_t tpm_transmit(struct tpm_c
down(&chip->tpm_mutex);
- if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+ if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
dev_err(chip->dev,
"tpm_transmit: tpm_send: error %zd\n", rc);
goto out;
}
stop = jiffies + 2 * 60 * HZ;
do {
- u8 status = chip->vendor->status(chip);
- if ((status & chip->vendor->req_complete_mask) ==
- chip->vendor->req_complete_val) {
+ u8 status = chip->vendor.status(chip);
+ if ((status & chip->vendor.req_complete_mask) ==
+ chip->vendor.req_complete_val)
goto out_recv;
- }
- if ((status == chip->vendor->req_canceled)) {
+ if ((status == chip->vendor.req_canceled)) {
dev_err(chip->dev, "Operation Canceled\n");
rc = -ECANCELED;
goto out;
@@ -102,14 +411,13 @@ static ssize_t tpm_transmit(struct tpm_c
rmb();
} while (time_before(jiffies, stop));
-
- chip->vendor->cancel(chip);
+ chip->vendor.cancel(chip);
dev_err(chip->dev, "Operation Timed out\n");
rc = -ETIME;
goto out;
out_recv:
- rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+ rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
if (rc < 0)
dev_err(chip->dev,
"tpm_transmit: tpm_recv: error %zd\n", rc);
@@ -344,7 +832,7 @@ ssize_t tpm_store_cancel(struct device *dev
if (chip == NULL)
return 0;
- chip->vendor->cancel(chip);
+ chip->vendor.cancel(chip);
return count;
}
EXPORT_SYMBOL_GPL(tpm_store_cancel);
@@ -369,7 +913,7 @@ int tpm_open(struct inode *inode, struct
spin_lock(&driver_lock);
list_for_each_entry(pos, &tpm_chip_list, list) {
- if (pos->vendor->miscdev.minor == minor) {
+ if (pos->vendor.miscdev.minor == minor) {
chip = pos;
break;
}
@@ -502,14 +1049,14 @@ void tpm_remove_hardware(struct device *
spin_unlock(&driver_lock);
dev_set_drvdata(dev, NULL);
- misc_deregister(&chip->vendor->miscdev);
- kfree(chip->vendor->miscdev.name);
+ misc_deregister(&chip->vendor.miscdev);
+ kfree(chip->vendor.miscdev.name);
- sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
+ sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
tpm_bios_log_teardown(chip->bios_dir);
- dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
- ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+ dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES] &=
+ ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
kfree(chip);
@@ -583,7 +1134,7 @@ int tpm_register_hardware(struct device
chip->user_read_timer.function = user_reader_timeout;
chip->user_read_timer.data = (unsigned long) chip;
- chip->vendor = entry;
+ memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
chip->dev_num = -1;
@@ -602,22 +1153,22 @@ dev_num_search_complete:
kfree(chip);
return -ENODEV;
} else if (chip->dev_num == 0)
- chip->vendor->miscdev.minor = TPM_MINOR;
+ chip->vendor.miscdev.minor = TPM_MINOR;
else
- chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+ chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
- chip->vendor->miscdev.name = devname;
+ chip->vendor.miscdev.name = devname;
- chip->vendor->miscdev.dev = dev;
+ chip->vendor.miscdev.dev = dev;
chip->dev = get_device(dev);
- if (misc_register(&chip->vendor->miscdev)) {
+ if (misc_register(&chip->vendor.miscdev)) {
dev_err(chip->dev,
"unable to misc_register %s, minor %d\n",
- chip->vendor->miscdev.name,
- chip->vendor->miscdev.minor);
+ chip->vendor.miscdev.name,
+ chip->vendor.miscdev.minor);
put_device(dev);
kfree(chip);
dev_mask[i] &= !(1 << j);
@@ -632,7 +1183,7 @@ dev_num_search_complete:
spin_unlock(&driver_lock);
- sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
+ sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
chip->bios_dir = tpm_bios_log_setup(devname);
--- linux-2.6.16/drivers/char/tpm/tpm_atmel.c 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm_atmel.c 2006-03-02 15:04:40.663271500 -0600
@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip
return -EIO;
for (i = 0; i < 6; i++) {
- status = ioread8(chip->vendor->iobase + 1);
+ status = ioread8(chip->vendor.iobase + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
dev_err(chip->dev, "error reading header\n");
return -EIO;
}
- *buf++ = ioread8(chip->vendor->iobase);
+ *buf++ = ioread8(chip->vendor.iobase);
}
/* size of the data received */
@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip
dev_err(chip->dev,
"Recv size(%d) less than available space\n", size);
for (; i < size; i++) { /* clear the waiting data anyway */
- status = ioread8(chip->vendor->iobase + 1);
+ status = ioread8(chip->vendor.iobase + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
dev_err(chip->dev, "error reading data\n");
return -EIO;
@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip
/* read all the data available */
for (; i < size; i++) {
- status = ioread8(chip->vendor->iobase + 1);
+ status = ioread8(chip->vendor.iobase + 1);
if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
dev_err(chip->dev, "error reading data\n");
return -EIO;
}
- *buf++ = ioread8(chip->vendor->iobase);
+ *buf++ = ioread8(chip->vendor.iobase);
}
/* make sure data available is gone */
- status = ioread8(chip->vendor->iobase + 1);
+ status = ioread8(chip->vendor.iobase + 1);
if (status & ATML_STATUS_DATA_AVAIL) {
dev_err(chip->dev, "data available is stuck\n");
@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip
dev_dbg(chip->dev, "tpm_atml_send:\n");
for (i = 0; i < count; i++) {
dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]);
- iowrite8(buf[i], chip->vendor->iobase);
+ iowrite8(buf[i], chip->vendor.iobase);
}
return count;
@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip
static void tpm_atml_cancel(struct tpm_chip *chip)
{
- iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
+ iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
}
static u8 tpm_atml_status(struct tpm_chip *chip)
{
- return ioread8(chip->vendor->iobase + 1);
+ return ioread8(chip->vendor.iobase + 1);
}
static struct file_operations atmel_ops = {
@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
if (chip) {
- if (chip->vendor->have_region)
- atmel_release_region(chip->vendor->base,
- chip->vendor->region_size);
- atmel_put_base_addr(chip->vendor);
+ if (chip->vendor.have_region)
+ atmel_release_region(chip->vendor.base,
+ chip->vendor.region_size);
+ atmel_put_base_addr(chip->vendor.iobase);
tpm_remove_hardware(chip->dev);
platform_device_unregister(pdev);
}
--- linux-2.6.16/drivers/char/tpm/tpm_nsc.c 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm_nsc.c 2006-03-02 15:06:07.188679000 -0600
@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip
unsigned long stop;
/* status immediately available check */
- *data = inb(chip->vendor->base + NSC_STATUS);
+ *data = inb(chip->vendor.base + NSC_STATUS);
if ((*data & mask) == val)
return 0;
@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip
stop = jiffies + 10 * HZ;
do {
msleep(TPM_TIMEOUT);
- *data = inb(chip->vendor->base + 1);
+ *data = inb(chip->vendor.base + 1);
if ((*data & mask) == val)
return 0;
}
@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm
unsigned long stop;
/* status immediately available check */
- status = inb(chip->vendor->base + NSC_STATUS);
+ status = inb(chip->vendor.base + NSC_STATUS);
if (status & NSC_STATUS_OBF)
- status = inb(chip->vendor->base + NSC_DATA);
+ status = inb(chip->vendor.base + NSC_DATA);
if (status & NSC_STATUS_RDY)
return 0;
@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm
stop = jiffies + 100;
do {
msleep(TPM_TIMEOUT);
- status = inb(chip->vendor->base + NSC_STATUS);
+ status = inb(chip->vendor.base + NSC_STATUS);
if (status & NSC_STATUS_OBF)
- status = inb(chip->vendor->base + NSC_DATA);
+ status = inb(chip->vendor.base + NSC_DATA);
if (status & NSC_STATUS_RDY)
return 0;
}
@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip
return -EIO;
}
if ((data =
- inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+ inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
dev_err(chip->dev, "not in normal mode (0x%x)\n",
data);
return -EIO;
@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip
}
if (data & NSC_STATUS_F0)
break;
- *p = inb(chip->vendor->base + NSC_DATA);
+ *p = inb(chip->vendor.base + NSC_DATA);
}
if ((data & NSC_STATUS_F0) == 0 &&
@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip
dev_err(chip->dev, "F0 not set\n");
return -EIO;
}
- if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
+ if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
dev_err(chip->dev,
"expected end of command(0x%x)\n", data);
return -EIO;
@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip
* fix it. Not sure why this is needed, we followed the flow
* chart in the manual to the letter.
*/
- outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+ outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
if (nsc_wait_for_ready(chip) != 0)
return -EIO;
@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip
return -EIO;
}
- outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
+ outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
dev_err(chip->dev, "IBR timeout\n");
return -EIO;
@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip
"IBF timeout (while writing data)\n");
return -EIO;
}
- outb(buf[i], chip->vendor->base + NSC_DATA);
+ outb(buf[i], chip->vendor.base + NSC_DATA);
}
if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
dev_err(chip->dev, "IBF timeout\n");
return -EIO;
}
- outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
+ outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
return count;
}
static void tpm_nsc_cancel(struct tpm_chip *chip)
{
- outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+ outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
}
static u8 tpm_nsc_status(struct tpm_chip *chip)
{
- return inb(chip->vendor->base + NSC_STATUS);
+ return inb(chip->vendor.base + NSC_STATUS);
}
static struct file_operations nsc_ops = {
@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(str
{
struct tpm_chip *chip = dev_get_drvdata(dev);
if ( chip ) {
- release_region(chip->vendor->base, 2);
+ release_region(chip->vendor.base, 2);
tpm_remove_hardware(chip->dev);
}
}
--- linux-2.6.16/drivers/char/tpm/tpm.h 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.h 2006-03-29 14:16:30.119053500 -0600
@@ -80,7 +93,7 @@ struct tpm_chip {
struct work_struct work;
struct semaphore tpm_mutex; /* tpm is processing */
- struct tpm_vendor_specific *vendor;
+ struct tpm_vendor_specific vendor;
struct dentry **bios_dir;
^ permalink raw reply
* Re: Changes over dmix: 1.0.11rc4 and future
From: Takashi Iwai @ 2006-04-03 16:42 UTC (permalink / raw)
To: Lee Revell; +Cc: alsa-devel
In-Reply-To: <1144081766.13151.29.camel@mindpipe>
At Mon, 03 Apr 2006 12:29:25 -0400,
Lee Revell wrote:
>
> On Mon, 2006-04-03 at 11:59 +0200, Takashi Iwai wrote:
> >
> > If you still get an error regarding variable_buffer_size, just remove
> > that line.
> >
> > And note that this won't work with emu10k1.
>
> I now get:
>
> Playing WAVE '/usr/share/sounds/error.wav' : Signed 16 bit Little
> Endian, Rate 44100 Hz, Mono
> ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not
> usable
> aplay: set_params:879: Broken configuration for this PCM: no
> configurations available
>
> Which I think is normal as hw:0,0 on the emu10k1 is only a stereo
> device.
Yes, exactly.
I'll make a patch to support dmix on multiple hw streams, but it'll be
after 1.0.11-final release... Or, at least, after cvs on sourceforge
gets back. I already have too many pending patches on my local tree.
Takashi
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply
* PATCH 6/7] tpm: new 1.2 sysfs files
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, TPM Device Driver List, Marcel Selhorst
In-Reply-To: <20060331202714.GC22987@sergelap.austin.ibm.com>
With the 1.2 TPM Specification there is more useful information
available. This information is exported to the user through sysfs
functions that the 1.2 driver will use.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
drivers/char/tpm/tpm.c | 206 +++++++++++++++++++++++++++++++++++++++
drivers/char/tpm/tpm.h | 7 +
2 files changed, 213 insertions(+)
--- linux-2.6.16/drivers/char/tpm/tpm.c 2006-03-30 16:58:10.715155750 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c 2006-03-30 16:51:48.567273000 -0600
@@ -431,17 +434,27 @@ out:
#define TPM_GET_CAP_RET_UINT32_2_IDX 18
#define TPM_GET_CAP_RET_UINT32_3_IDX 22
#define TPM_GET_CAP_RET_UINT32_4_IDX 26
+#define TPM_GET_CAP_PERM_DISABLE_IDX 16
+#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
+#define TPM_GET_CAP_RET_BOOL_1_IDX 14
+#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
#define TPM_CAP_IDX 13
#define TPM_CAP_SUBCAP_IDX 21
enum tpm_capabilities {
+ TPM_CAP_FLAG = 4,
TPM_CAP_PROP = 5,
};
enum tpm_sub_capabilities {
TPM_CAP_PROP_PCR = 0x1,
TPM_CAP_PROP_MANUFACTURER = 0x3,
+ TPM_CAP_FLAG_PERM = 0x8,
+ TPM_CAP_FLAG_VOL = 0x9,
+ TPM_CAP_PROP_OWNER = 0x11,
+ TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
+ TPM_CAP_PROP_TIS_DURATION = 0x20,
};
/*
@@ -459,6 +472,155 @@ static const u8 tpm_cap[] = {
0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
};
+void tpm_gen_interrupt(struct tpm_chip *chip)
+{
+ u8 data[30];
+ ssize_t len;
+
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data)))
+ <= TPM_ERROR_SIZE)
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the timeouts\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+}
+EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+
+void tpm_get_timeouts(struct tpm_chip *chip)
+{
+ u8 data[30];
+ ssize_t len;
+ u32 timeout;
+
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data)))
+ <= TPM_ERROR_SIZE) {
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the timeouts\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ goto duration;
+ }
+
+ if ((len =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))))
+ != 4 * sizeof(u32))
+ goto duration;
+
+ /* Don't overwrite default if value is 0 */
+ timeout =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+ if (timeout)
+ chip->vendor.timeout_a = timeout;
+ timeout =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+ if (timeout)
+ chip->vendor.timeout_b = timeout;
+ timeout =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+ if (timeout)
+ chip->vendor.timeout_c = timeout;
+ timeout =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+ if (timeout)
+ chip->vendor.timeout_d = timeout;
+
+duration:
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data)))
+ <= TPM_ERROR_SIZE) {
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the durations\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ return;
+ }
+
+ if ((len =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))))
+ != 3 * sizeof(u32))
+ return;
+
+ chip->vendor.duration[TPM_SHORT] =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+ chip->vendor.duration[TPM_MEDIUM] =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+ chip->vendor.duration[TPM_LONG] =
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+}
+EXPORT_SYMBOL_GPL(tpm_get_timeouts);
+
+ssize_t tpm_show_state(struct device * dev, struct device_attribute * attr,
+ char *buf)
+{
+ u8 data[35];
+ ssize_t len;
+ char *str = buf;
+
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if (chip == NULL)
+ return -ENODEV;
+
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data)))
+ <= TPM_ERROR_SIZE)
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the permanent state\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ else {
+ str +=
+ sprintf(str, "%s\n",
+ (data[TPM_GET_CAP_PERM_DISABLE_IDX] ==
+ 1) ? "Disabled" : "Enabled");
+ str +=
+ sprintf(str, "%s\n",
+ (data[TPM_GET_CAP_PERM_INACTIVE_IDX] ==
+ 1) ? "Inactive" : "Active");
+ }
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data)))
+ <= TPM_ERROR_SIZE)
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the owner state\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ else
+ str +=
+ sprintf(str, "%s\n",
+ (data[TPM_GET_CAP_RET_BOOL_1_IDX] ==
+ 1) ? "Owned" : "Unowned");
+
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data)))
+ <= TPM_ERROR_SIZE) {
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the temporary state\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ goto out;
+ }
+
+ if (data[TPM_GET_CAP_TEMP_INACTIVE_IDX] != 0)
+ str += sprintf(str, "Deactivated for this boot\n");
+out:
+ return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_state);
+
static const u8 pcrread[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 14, /* length */
@@ -590,6 +768,7 @@ out:
EXPORT_SYMBOL_GPL(tpm_show_pubek);
#define CAP_VERSION_1_1 6
+#define CAP_VERSION_1_2 0x1A
#define CAP_VERSION_IDX 13
static const u8 cap_version[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
@@ -651,6 +830,52 @@ out:
}
EXPORT_SYMBOL_GPL(tpm_show_caps);
+ssize_t tpm_show_caps_1_2(struct device * dev,
+ struct device_attribute * attr, char *buf)
+{
+ u8 data[30];
+ ssize_t len;
+ char *str = buf;
+
+ struct tpm_chip *chip = dev_get_drvdata(dev);
+ if (chip == NULL)
+ return -ENODEV;
+
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+ TPM_ERROR_SIZE) {
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the manufacturer\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ return 0;
+ }
+
+ str += sprintf(str, "Manufacturer: 0x%x\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
+
+ memcpy(data, cap_version, sizeof(cap_version));
+ data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
+
+ if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+ TPM_ERROR_SIZE) {
+ dev_err(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the 1.2 version\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ goto out;
+ }
+ str += sprintf(str,
+ "TCG version: %d.%d\nFirmware version: %d.%d\n",
+ (int) data[16], (int) data[17], (int) data[18],
+ (int) data[19]);
+
+out:
+ return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
+
ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
--- linux-2.6.16/drivers/char/tpm/tpm.h 2006-03-30 16:58:10.715155750 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.h 2006-03-29 14:16:30.119053500 -0600
@@ -41,8 +41,12 @@ extern ssize_t tpm_show_pcrs(struct devi
char *);
extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
char *);
+extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
+ char *);
extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
const char *, size_t);
+extern ssize_t tpm_show_state(struct device *, struct device_attribute *attr,
+ char *);
struct tpm_chip;
@@ -62,6 +68,7 @@ struct tpm_vendor_specific {
u8 (*status) (struct tpm_chip *);
struct miscdevice miscdev;
struct attribute_group *attr_group;
+ u32 timeout_a, timeout_b, timeout_c, timeout_d;
u32 duration[3];
};
@@ -100,6 +114,8 @@ static inline void tpm_write_index(int b
outb(value & 0xFF, base+1);
}
+extern void tpm_get_timeouts(struct tpm_chip *);
+extern void tpm_gen_interrupt(struct tpm_chip *);
extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
extern struct tpm_chip* tpm_register_hardware(struct device *,
const struct tpm_vendor_specific *);
^ permalink raw reply
* [PATCH 7/7] tpm: Driver for next generation TPM chips
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel
Cc: akpm, TPM Device Driver List, Leendert Van Doorn, Marcel Selhorst
This patch contains the driver for the next generation of TPM chips
version 1.2 including support for interrupts. The Trusted Computing
Group has written the TPM Interface Specification (TIS) which defines a
common interface for all manufacturer's 1.2 TPM's thus the name
tpm_tis.
Signed-off-by: Leendert van Doorn <leendert@watson.ibm.com>
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
drivers/char/tpm/Kconfig | 11
drivers/char/tpm/Makefile | 1
drivers/char/tpm/tpm.c | 3
drivers/char/tpm/tpm.h | 9
drivers/char/tpm/tpm_tis.c | 628 +++++++++++++++++++++++++++++++++++
5 files changed, 651 insertions(+), 1 deletion(-)
--- linux-2.6.16/drivers/char/tpm/tpm.h 2006-03-30 17:08:49.315065750 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.h 2006-03-29 14:16:30.119053500 -0600
@@ -57,6 +57,8 @@ struct tpm_vendor_specific {
void __iomem *iobase; /* ioremapped address */
unsigned long base; /* TPM base address */
+ int irq;
+
int region_size;
int have_region;
@@ -66,8 +68,13 @@ struct tpm_vendor_specific {
u8 (*status) (struct tpm_chip *);
struct miscdevice miscdev;
struct attribute_group *attr_group;
+ struct list_head list;
+ int locality;
u32 timeout_a, timeout_b, timeout_c, timeout_d;
u32 duration[3];
+
+ wait_queue_head_t read_queue;
+ wait_queue_head_t int_queue;
};
struct tpm_chip {
@@ -93,6 +100,8 @@ struct tpm_chip {
struct list_head list;
};
+#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
+
static inline int tpm_read_index(int base, int index)
{
outb(index, base);
--- linux-2.6.16/drivers/char/tpm/tpm.c 2006-03-30 17:08:49.315065750 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c 2006-03-30 16:51:48.567273000 -0600
@@ -391,6 +391,9 @@ static ssize_t tpm_transmit(struct tpm_c
goto out;
}
+ if (chip->vendor.irq)
+ goto out_recv;
+
stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
do {
u8 status = chip->vendor.status(chip);
--- linux-2.6.16/drivers/char/tpm/tpm_tis.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm_tis.c 2006-03-30 10:44:31.874065750 -0600
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2005, 2006 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+#include <linux/pnp.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include "tpm.h"
+
+#define TPM_HEADER_SIZE 10
+
+enum tis_access {
+ TPM_ACCESS_VALID = 0x80,
+ TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+ TPM_ACCESS_REQUEST_PENDING = 0x04,
+ TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum tis_status {
+ TPM_STS_VALID = 0x80,
+ TPM_STS_COMMAND_READY = 0x40,
+ TPM_STS_GO = 0x20,
+ TPM_STS_DATA_AVAIL = 0x10,
+ TPM_STS_DATA_EXPECT = 0x08,
+};
+
+enum tis_int_flags {
+ TPM_GLOBAL_INT_ENABLE = 0x80000000,
+ TPM_INTF_BURST_COUNT_STATIC = 0x100,
+ TPM_INTF_CMD_READY_INT = 0x080,
+ TPM_INTF_INT_EDGE_FALLING = 0x040,
+ TPM_INTF_INT_EDGE_RISING = 0x020,
+ TPM_INTF_INT_LEVEL_LOW = 0x010,
+ TPM_INTF_INT_LEVEL_HIGH = 0x008,
+ TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
+ TPM_INTF_STS_VALID_INT = 0x002,
+ TPM_INTF_DATA_AVAIL_INT = 0x001,
+};
+
+#define TPM_ACCESS(l) (0x0000 | ((l) << 12))
+#define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12))
+#define TPM_INT_VECTOR(l) (0x000C | ((l) << 12))
+#define TPM_INT_STATUS(l) (0x0010 | ((l) << 12))
+#define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12))
+#define TPM_STS(l) (0x0018 | ((l) << 12))
+#define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12))
+
+#define TPM_DID_VID(l) (0x0F00 | ((l) << 12))
+#define TPM_RID(l) (0x0F04 | ((l) << 12))
+
+static LIST_HEAD(tis_chips);
+static DEFINE_SPINLOCK(tis_lock);
+
+static int check_locality(struct tpm_chip *chip, int l)
+{
+ if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
+ return chip->vendor.locality = l;
+
+ return -1;
+}
+
+static void release_locality(struct tpm_chip *chip, int l)
+{
+ if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
+ (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
+ (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
+ iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
+ chip->vendor.iobase + TPM_ACCESS(l));
+}
+
+static int request_locality(struct tpm_chip *chip, int l)
+{
+ unsigned long stop;
+
+ if (check_locality(chip, l) >= 0)
+ return l;
+
+ iowrite8(TPM_ACCESS_REQUEST_USE,
+ chip->vendor.iobase + TPM_ACCESS(l));
+
+ if (chip->vendor.irq) {
+ interruptible_sleep_on_timeout(&chip->vendor.int_queue,
+ HZ *
+ chip->vendor.timeout_a /
+ 1000);
+ if (check_locality(chip, l) >= 0)
+ return l;
+
+ } else {
+ /* wait for burstcount */
+ stop = jiffies + (HZ * chip->vendor.timeout_a / 1000);
+ do {
+ if (check_locality(chip, l) >= 0)
+ return l;
+ msleep(TPM_TIMEOUT);
+ }
+ while (time_before(jiffies, stop));
+ }
+ release_locality(chip, l);
+ return -1;
+}
+
+static u8 tpm_tis_status(struct tpm_chip *chip)
+{
+ return ioread8(chip->vendor.iobase +
+ TPM_STS(chip->vendor.locality));
+}
+
+static void tpm_tis_ready(struct tpm_chip *chip)
+{
+ /* this causes the current command to be aborted */
+ iowrite8(TPM_STS_COMMAND_READY,
+ chip->vendor.iobase + TPM_STS(chip->vendor.locality));
+}
+
+static int get_burstcount(struct tpm_chip *chip)
+{
+ unsigned long stop;
+ int burstcnt;
+
+ /* wait for burstcount */
+ /* which timeout value, spec has 2 answers (c & d) */
+ stop = jiffies + (HZ * chip->vendor.timeout_d / 1000);
+ do {
+ burstcnt = ioread8(chip->vendor.iobase +
+ TPM_STS(chip->vendor.locality) + 1);
+ burstcnt += ioread8(chip->vendor.iobase +
+ TPM_STS(chip->vendor.locality) +
+ 2) << 8;
+ if (burstcnt)
+ return burstcnt;
+ msleep(TPM_TIMEOUT);
+ } while (time_before(jiffies, stop));
+ return -EBUSY;
+}
+
+static int wait_for_stat(struct tpm_chip *chip, u8 mask, u32 timeout,
+ wait_queue_head_t * queue)
+{
+ unsigned long stop;
+ u8 status;
+
+ /* check current status */
+ status = tpm_tis_status(chip);
+ if ((status & mask) == mask)
+ return 0;
+
+ if (chip->vendor.irq) {
+ interruptible_sleep_on_timeout(queue, HZ * timeout / 1000);
+ status = tpm_tis_status(chip);
+ if ((status & mask) == mask)
+ return 0;
+ } else {
+ stop = jiffies + (HZ * timeout / 1000);
+ do {
+ msleep(TPM_TIMEOUT);
+ status = tpm_tis_status(chip);
+ if ((status & mask) == mask)
+ return 0;
+ } while (time_before(jiffies, stop));
+ }
+ return -ETIME;
+}
+
+static int recv_data(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+ int size = 0, burstcnt;
+ while (size < count &&
+ wait_for_stat(chip,
+ TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ chip->vendor.timeout_c,
+ &chip->vendor.read_queue)
+ == 0) {
+ burstcnt = get_burstcount(chip);
+ for (; burstcnt > 0 && size < count; burstcnt--)
+ buf[size++] = ioread8(chip->vendor.iobase +
+ TPM_DATA_FIFO(chip->vendor.
+ locality));
+ }
+ return size;
+}
+
+static int tpm_tis_recv(struct tpm_chip *chip, u8 * buf, size_t count)
+{
+ int size = 0;
+ int expected, status;
+
+ if (count < TPM_HEADER_SIZE) {
+ size = -EIO;
+ goto out;
+ }
+
+ /* read first 10 bytes, including tag, paramsize, and result */
+ if ((size =
+ recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
+ dev_err(chip->dev, "Unable to read header\n");
+ goto out;
+ }
+
+ expected = be32_to_cpu(*(__be32 *) (buf + 2));
+ if (expected > count) {
+ size = -EIO;
+ goto out;
+ }
+
+ if ((size +=
+ recv_data(chip, &buf[TPM_HEADER_SIZE],
+ expected - TPM_HEADER_SIZE)) < expected) {
+ dev_err(chip->dev, "Unable to read remainder of result\n");
+ size = -ETIME;
+ goto out;
+ }
+
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+ &chip->vendor.int_queue);
+ status = tpm_tis_status(chip);
+ if (status & TPM_STS_DATA_AVAIL) { /* retry? */
+ dev_err(chip->dev, "Error left over data\n");
+ size = -EIO;
+ goto out;
+ }
+
+out:
+ tpm_tis_ready(chip);
+ release_locality(chip, chip->vendor.locality);
+ return size;
+}
+
+/*
+ * If interrupts are used (signaled by an irq set in the vendor structure)
+ * tpm.c can skip polling for the data to be available as the interrupt is
+ * waited for here
+ */
+static int tpm_tis_send(struct tpm_chip *chip, u8 * buf, size_t len)
+{
+ int rc, status, burstcnt;
+ size_t count = 0;
+ u32 ordinal;
+
+ if (request_locality(chip, 0) < 0)
+ return -EBUSY;
+
+ status = tpm_tis_status(chip);
+ if ((status & TPM_STS_COMMAND_READY) == 0) {
+ tpm_tis_ready(chip);
+ if (wait_for_stat
+ (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
+ &chip->vendor.int_queue) < 0) {
+ rc = -ETIME;
+ goto out_err;
+ }
+ }
+
+ while (count < len - 1) {
+ burstcnt = get_burstcount(chip);
+ for (; burstcnt > 0 && count < len - 1; burstcnt--) {
+ iowrite8(buf[count], chip->vendor.iobase +
+ TPM_DATA_FIFO(chip->vendor.locality));
+ count++;
+ }
+
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+ &chip->vendor.int_queue);
+ status = tpm_tis_status(chip);
+ if ((status & TPM_STS_DATA_EXPECT) == 0) {
+ rc = -EIO;
+ goto out_err;
+ }
+ }
+
+ /* write last byte */
+ iowrite8(buf[count],
+ chip->vendor.iobase +
+ TPM_DATA_FIFO(chip->vendor.locality));
+ wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+ &chip->vendor.int_queue);
+ status = tpm_tis_status(chip);
+ if ((status & TPM_STS_DATA_EXPECT) != 0) {
+ rc = -EIO;
+ goto out_err;
+ }
+
+ /* go and do it */
+ iowrite8(TPM_STS_GO,
+ chip->vendor.iobase + TPM_STS(chip->vendor.locality));
+
+ if (chip->vendor.irq) {
+ ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
+ if (wait_for_stat
+ (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ tpm_calc_ordinal_duration(chip, ordinal),
+ &chip->vendor.read_queue) < 0) {
+ rc = -ETIME;
+ goto out_err;
+ }
+ }
+ return len;
+out_err:
+ tpm_tis_ready(chip);
+ release_locality(chip, chip->vendor.locality);
+ return rc;
+}
+
+static struct file_operations tis_ops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = tpm_open,
+ .read = tpm_read,
+ .write = tpm_write,
+ .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(state, S_IRUGO, tpm_show_state, NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute *tis_attrs[] = {
+ &dev_attr_pubek.attr, &dev_attr_pcrs.attr,
+ &dev_attr_state.attr, &dev_attr_caps.attr,
+ &dev_attr_cancel.attr, NULL,
+};
+
+static struct attribute_group tis_attr_grp = {
+ .attrs = tis_attrs
+};
+
+static struct tpm_vendor_specific tpm_tis = {
+ .status = tpm_tis_status,
+ .recv = tpm_tis_recv,
+ .send = tpm_tis_send,
+ .cancel = tpm_tis_ready,
+ .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+ .req_canceled = TPM_STS_COMMAND_READY,
+ .attr_group = &tis_attr_grp,
+ .miscdev = {
+ .fops = &tis_ops,},
+};
+
+static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs
+ *regs)
+{
+ struct tpm_chip *chip = (struct tpm_chip *) dev_id;
+ u32 interrupt;
+
+ interrupt = ioread32(chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality));
+
+ if (interrupt == 0)
+ return IRQ_NONE;
+
+ chip->vendor.irq = irq;
+
+ /* Clear interrupts handled with TPM_EOI */
+ iowrite32(interrupt,
+ chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality));
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs
+ *regs)
+{
+ struct tpm_chip *chip = (struct tpm_chip *) dev_id;
+ u32 interrupt;
+ int i;
+
+ interrupt = ioread32(chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality));
+
+ if (interrupt == 0)
+ return IRQ_NONE;
+
+ if (interrupt & TPM_INTF_DATA_AVAIL_INT)
+ wake_up_interruptible(&chip->vendor.read_queue);
+ if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
+ for (i = 0; i < 5; i++)
+ if (check_locality(chip, i) >= 0)
+ break;
+ if (interrupt &
+ (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
+ TPM_INTF_CMD_READY_INT))
+ wake_up_interruptible(&chip->vendor.int_queue);
+
+ /* Clear interrupts handled with TPM_EOI */
+ iowrite32(interrupt,
+ chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality));
+ return IRQ_HANDLED;
+}
+
+static int __devinit tpm_tis_pnp_init(struct pnp_dev
+ *pnp_dev, const struct
+ pnp_device_id
+ *pnp_id)
+{
+ u32 vendor, intfcaps, intmask;
+ int rc, i;
+ unsigned long start, len;
+ struct tpm_chip *chip;
+
+ start = pnp_mem_start(pnp_dev, 0);
+ len = pnp_mem_len(pnp_dev, 0);
+
+ if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
+ return -ENODEV;
+
+ chip->vendor.iobase = ioremap(start, len);
+ if (!chip->vendor.iobase) {
+ rc = -EIO;
+ goto out_err;
+ }
+
+ vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
+ if ((vendor & 0xFFFF) == 0xFFFF) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ /* Default timeouts */
+ chip->vendor.timeout_a = 750; /* ms */
+ chip->vendor.timeout_b = 2000; /* 2 sec */
+ chip->vendor.timeout_c = 750; /* ms */
+ chip->vendor.timeout_d = 750; /* ms */
+
+ dev_info(&pnp_dev->dev,
+ "1.2 TPM (device-id 0x%X, rev-id %d)\n",
+ vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
+
+ /* Figure out the capabilities */
+ intfcaps =
+ ioread32(chip->vendor.iobase +
+ TPM_INTF_CAPS(chip->vendor.locality));
+ dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
+ intfcaps);
+ if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
+ dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
+ if (intfcaps & TPM_INTF_CMD_READY_INT)
+ dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
+ if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
+ dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
+ if (intfcaps & TPM_INTF_INT_EDGE_RISING)
+ dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
+ if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
+ dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
+ if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
+ dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
+ if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
+ dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
+ if (intfcaps & TPM_INTF_STS_VALID_INT)
+ dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
+ if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
+ dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
+
+ if (request_locality(chip, 0) != 0) {
+ rc = -ENODEV;
+ goto out_err;
+ }
+
+ /* INTERRUPT Setup */
+ init_waitqueue_head(&chip->vendor.read_queue);
+ init_waitqueue_head(&chip->vendor.int_queue);
+
+ intmask =
+ ioread32(chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.locality));
+
+ intmask |= TPM_INTF_CMD_READY_INT
+ | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
+ | TPM_INTF_STS_VALID_INT;
+
+ iowrite32(intmask,
+ chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.locality));
+
+ chip->vendor.irq =
+ ioread8(chip->vendor.iobase +
+ TPM_INT_VECTOR(chip->vendor.locality));
+
+ for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
+ iowrite8(i,
+ chip->vendor.iobase +
+ TPM_INT_VECTOR(chip->vendor.locality));
+ if (request_irq
+ (i, tis_int_probe, SA_SHIRQ,
+ chip->vendor.miscdev.name, chip) != 0) {
+ dev_info(chip->dev,
+ "Unable to request irq: %d for probe\n",
+ i);
+ continue;
+ }
+
+ /* Clear all existing */
+ iowrite32(ioread32
+ (chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality)),
+ chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality));
+
+ /* Turn on */
+ iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
+ chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.locality));
+
+ /* Generate Interrupts */
+ tpm_gen_interrupt(chip);
+
+ /* Turn off */
+ iowrite32(intmask,
+ chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.locality));
+ free_irq(i, chip);
+ }
+ if (chip->vendor.irq) {
+ iowrite8(chip->vendor.irq,
+ chip->vendor.iobase +
+ TPM_INT_VECTOR(chip->vendor.locality));
+ if (request_irq
+ (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
+ chip->vendor.miscdev.name, chip) != 0) {
+ dev_info(chip->dev,
+ "Unable to request irq: %d for use\n", i);
+ chip->vendor.irq = 0;
+ } else {
+ /* Clear all existing */
+ iowrite32(ioread32
+ (chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality)),
+ chip->vendor.iobase +
+ TPM_INT_STATUS(chip->vendor.locality));
+
+ /* Turn on */
+ iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
+ chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.locality));
+ }
+ }
+
+ INIT_LIST_HEAD(&chip->vendor.list);
+ spin_lock(&tis_lock);
+ list_add(&chip->vendor.list, &tis_chips);
+ spin_unlock(&tis_lock);
+
+ tpm_get_timeouts(chip);
+
+ return 0;
+out_err:
+ if (chip->vendor.iobase)
+ iounmap(chip->vendor.iobase);
+ tpm_remove_hardware(chip->dev);
+ return rc;
+}
+
+static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
+{
+ return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_pnp_resume(struct pnp_dev *dev)
+{
+ return tpm_pm_resume(&dev->dev);
+}
+
+static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
+ {"PNP0C31", 0}, /* TPM */
+ {"", 0}
+};
+
+static struct pnp_driver tis_pnp_driver = {
+ .name = "tpm_tis",
+ .id_table = tpm_pnp_tbl,
+ .probe = tpm_tis_pnp_init,
+ .suspend = tpm_tis_pnp_suspend,
+ .resume = tpm_tis_pnp_resume,
+};
+
+static int __init init_tis(void)
+{
+ return pnp_register_driver(&tis_pnp_driver);
+}
+
+static void __exit cleanup_tis(void)
+{
+ struct tpm_vendor_specific *i, *j;
+ struct tpm_chip *chip;
+ spin_lock(&tis_lock);
+ list_for_each_entry_safe(i, j, &tis_chips, list) {
+ chip = to_tpm_chip(i);
+ iowrite32(~TPM_GLOBAL_INT_ENABLE &
+ ioread32(chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.
+ locality)),
+ chip->vendor.iobase +
+ TPM_INT_ENABLE(chip->vendor.locality));
+ if (chip->vendor.irq)
+ free_irq(chip->vendor.irq, chip);
+ iounmap(i->iobase);
+ list_del(&i->list);
+ tpm_remove_hardware(chip->dev);
+ }
+ spin_unlock(&tis_lock);
+ pnp_unregister_driver(&tis_pnp_driver);
+}
+
+module_init(init_tis);
+module_exit(cleanup_tis);
+MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
--- linux-2.6.16/drivers/char/tpm/Makefile 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/Makefile 2006-03-02 16:20:06.002087500 -0600
@@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o
ifdef CONFIG_ACPI
obj-$(CONFIG_TCG_TPM) += tpm_bios.o
endif
+obj-$(CONFIG_TCG_TIS) += tpm_tis.o
obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
--- linux-2.6.16/drivers/char/tpm/Kconfig 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/Kconfig 2006-03-02 16:19:05.730320750 -0600
@@ -20,9 +20,18 @@ config TCG_TPM
Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
and CONFIG_PNPACPI.
+config TCG_TIS
+ tristate "TPM Interface Specification 1.2 Interface"
+ depends on TCG_TPM
+ ---help---
+ If you have a TPM security chip that is compliant with the
+ TCG TIS 1.2 TPM specification say Yes and it will be accessible
+ from within Linux. To compile this driver as a module, choose
+ M here; the module will be called tpm_tis.
+
config TCG_NSC
tristate "National Semiconductor TPM Interface"
- depends on TCG_TPM
+ depends on TCG_TPM && PNPACPI
---help---
If you have a TPM security chip from National Semicondutor
say Yes and it will be accessible from within Linux. To
^ permalink raw reply
* [PATCH 2/7] tpm: reorganize sysfs files
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, TPM Device Driver List, Marcel Selhorst
In-Reply-To: <1143823488.2992.166.camel@localhost.localdomain>
Many of the sysfs files were calling the TPM_GetCapability command with
different options and each command layed out in its own static const
array. Since for 1.2 more sysfs files of this type are coming I am
generalizing the array so there can be one array and the unique parts
can be filled in just before the command is called.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
drivers/char/tpm/tpm.c | 116 ++++++++++++++++++++++++---------------
1 files changed, 72 insertions(+), 44 deletions(-)
--- linux-2.6.16/drivers/char/tpm/tpm.c 2006-03-30 12:27:02.858478250 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c 2006-03-29 14:17:14.421822250 -0600
@@ -119,17 +427,41 @@ out:
}
#define TPM_DIGEST_SIZE 20
-#define CAP_PCR_RESULT_SIZE 18
-static const u8 cap_pcr[] = {
+#define TPM_ERROR_SIZE 10
+#define TPM_RET_CODE_IDX 6
+#define TPM_GET_CAP_RET_SIZE_IDX 10
+#define TPM_GET_CAP_RET_UINT32_1_IDX 14
+#define TPM_GET_CAP_RET_UINT32_2_IDX 18
+#define TPM_GET_CAP_RET_UINT32_3_IDX 22
+#define TPM_GET_CAP_RET_UINT32_4_IDX 26
+
+#define TPM_CAP_IDX 13
+#define TPM_CAP_SUBCAP_IDX 21
+
+enum tpm_capabilities {
+ TPM_CAP_PROP = 5,
+};
+
+enum tpm_sub_capabilities {
+ TPM_CAP_PROP_PCR = 0x1,
+ TPM_CAP_PROP_MANUFACTURER = 0x3,
+};
+
+/*
+ * This is a semi generic GetCapability command for use
+ * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
+ * and their associated sub_capabilities.
+ */
+
+static const u8 tpm_cap[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 22, /* length */
0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 5,
- 0, 0, 0, 4,
- 0, 0, 1, 1
+ 0, 0, 0, 0, /* TPM_CAP_<TYPE> */
+ 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */
+ 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */
};
-#define READ_PCR_RESULT_SIZE 30
static const u8 pcrread[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 14, /* length */
@@ -140,7 +649,7 @@ static const u8 pcrread[] = {
ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
char *buf)
{
- u8 data[READ_PCR_RESULT_SIZE];
+ u8 data[30];
ssize_t len;
int i, j, num_pcrs;
__be32 index;
@@ -150,26 +659,28 @@ ssize_t tpm_show_pcrs(struct device *dev
if (chip == NULL)
return -ENODEV;
- memcpy(data, cap_pcr, sizeof(cap_pcr));
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
+
if ((len = tpm_transmit(chip, data, sizeof(data)))
- < CAP_PCR_RESULT_SIZE) {
+ <= TPM_ERROR_SIZE) {
dev_dbg(chip->dev, "A TPM error (%d) occurred "
- "attempting to determine the number of PCRS\n",
- be32_to_cpu(*((__be32 *) (data + 6))));
+ "attempting to determine the number of PCRS\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
return 0;
}
num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
-
for (i = 0; i < num_pcrs; i++) {
memcpy(data, pcrread, sizeof(pcrread));
index = cpu_to_be32(i);
memcpy(data + 10, &index, 4);
if ((len = tpm_transmit(chip, data, sizeof(data)))
- < READ_PCR_RESULT_SIZE){
+ <= TPM_ERROR_SIZE) {
dev_dbg(chip->dev, "A TPM error (%d) occurred"
" attempting to read PCR %d of %d\n",
- be32_to_cpu(*((__be32 *) (data + 6))),
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))),
i, num_pcrs);
goto out;
}
@@ -208,11 +724,11 @@ ssize_t tpm_show_pubek(struct device *de
memcpy(data, readpubek, sizeof(readpubek));
- if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
- READ_PUBEK_RESULT_SIZE) {
+ if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <=
+ TPM_ERROR_SIZE) {
dev_dbg(chip->dev, "A TPM error (%d) occurred "
- "attempting to read the PUBEK\n",
- be32_to_cpu(*((__be32 *) (data + 6))));
+ "attempting to read the PUBEK\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
rc = 0;
goto out;
}
@@ -250,29 +284,20 @@ out:
}
EXPORT_SYMBOL_GPL(tpm_show_pubek);
-#define CAP_VER_RESULT_SIZE 18
+#define CAP_VERSION_1_1 6
+#define CAP_VERSION_IDX 13
static const u8 cap_version[] = {
0, 193, /* TPM_TAG_RQU_COMMAND */
0, 0, 0, 18, /* length */
0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 6,
+ 0, 0, 0, 0,
0, 0, 0, 0
};
-#define CAP_MANUFACTURER_RESULT_SIZE 18
-static const u8 cap_manufacturer[] = {
- 0, 193, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 22, /* length */
- 0, 0, 0, 101, /* TPM_ORD_GetCapability */
- 0, 0, 0, 5,
- 0, 0, 0, 4,
- 0, 0, 1, 3
-};
-
ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
char *buf)
{
- u8 data[sizeof(cap_manufacturer)];
+ u8 data[30];
ssize_t len;
char *str = buf;
@@ -282,26 +793,37 @@ ssize_t tpm_show_caps(struct device *dev
if (chip == NULL)
return -ENODEV;
- memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
+ memcpy(data, tpm_cap, sizeof(tpm_cap));
+ data[TPM_CAP_IDX] = TPM_CAP_PROP;
+ data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
- if ((len = tpm_transmit(chip, data, sizeof(data))) <
- CAP_MANUFACTURER_RESULT_SIZE)
- return len;
+ if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+ TPM_ERROR_SIZE) {
+ dev_dbg(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the manufacturer\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ return 0;
+ }
str += sprintf(str, "Manufacturer: 0x%x\n",
- be32_to_cpu(*((__be32 *) (data + 14))));
+ be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
memcpy(data, cap_version, sizeof(cap_version));
+ data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
+ if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+ TPM_ERROR_SIZE) {
+ dev_err(chip->dev, "A TPM error (%d) occurred "
+ "attempting to determine the 1.1 version\n",
+ be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+ goto out;
+ }
- if ((len = tpm_transmit(chip, data, sizeof(data))) <
- CAP_VER_RESULT_SIZE)
- return len;
-
- str +=
- sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
- (int) data[14], (int) data[15], (int) data[16],
- (int) data[17]);
+ str += sprintf(str,
+ "TCG version: %d.%d\nFirmware version: %d.%d\n",
+ (int) data[14], (int) data[15], (int) data[16],
+ (int) data[17]);
+out:
return str - buf;
}
EXPORT_SYMBOL_GPL(tpm_show_caps);
^ permalink raw reply
* Re: accessed/dirty bit handler tuning
From: David Mosberger-Tang @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-ia64
In-Reply-To: <44157CF1.5060902@bull.net>
On 4/3/06, Zoltan Menyhart <Zoltan.Menyhart@bull.net> wrote:
> The problem is that the most frequently used trap handler contains
> the unsafe walk of the
>
> rx = IA64_KR_PT_BASE -> pgd[i] -> pud[j] -> pmd[k] -> pte[l]
>
> chain...
Please, everybody step back a minute. Hint: consider that x86 does
the page-table walk in hardware...
--david
^ permalink raw reply
* [PATCH 1/7] tpm: spacing cleanups
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, TPM Device Driver List, Marcel Selhorst
This patch fixes minor spacing issues.
Signed-off-by: Kylene Hall <kjhall@us.ibm.com>
---
drivers/char/tpm/tpm.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
--- linux-2.6.16/drivers/char/tpm/tpm.c 2006-03-19 23:53:29.000000000 -0600
+++ linux-2.6.16-rc1-tpm/drivers/char/tpm/tpm.c 2006-03-22 12:05:26.830788000 -0600
@@ -46,7 +326,7 @@ static void user_reader_timeout(unsigned
schedule_work(&chip->work);
}
-static void timeout_work(void * ptr)
+static void timeout_work(void *ptr)
{
struct tpm_chip *chip = ptr;
@@ -425,7 +963,7 @@ int tpm_release(struct inode *inode, str
EXPORT_SYMBOL_GPL(tpm_release);
ssize_t tpm_write(struct file *file, const char __user *buf,
- size_t size, loff_t * off)
+ size_t size, loff_t *off)
{
struct tpm_chip *chip = file->private_data;
int in_size = size, out_size;
@@ -457,11 +995,10 @@ ssize_t tpm_write(struct file *file, con
return in_size;
}
-
EXPORT_SYMBOL_GPL(tpm_write);
-ssize_t tpm_read(struct file * file, char __user *buf,
- size_t size, loff_t * off)
+ssize_t tpm_read(struct file *file, char __user *buf,
+ size_t size, loff_t *off)
{
struct tpm_chip *chip = file->private_data;
int ret_size;
^ permalink raw reply
* [PATCH 0/7] tpm: TPM 1.2 support
From: Kylene Jo Hall @ 2006-04-03 16:42 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, TPM Device Driver List, Marcel Selhorst
The following patch set contains numerous changes to the base tpm
driver
(tpm.c) to support the next generation of TPM chips. The changes
include new sysfs files because of more relevant data being available, a
function to access the timeout and duration values for the chip, and
changes to make use of those duration values. Duration in the TPM
specification is defined as the maximum amount of time the chip could
take to return the results. Commands are in one of three categories
short, medium and long. Also included are cleanups of how the commands
for the sysfs files are composed to reduce a bunch of redundant arrays.
Kylie
^ permalink raw reply
* Re: Patch to xm create search domU config in /etc/xen/auto
From: Anthony Liguori @ 2006-04-03 16:39 UTC (permalink / raw)
To: Itamar Reis Peixoto; +Cc: xen-devel
In-Reply-To: <001901c65733$e270a6e0$0100000a@lualele>
Hope this doesn't appear to be singling you out, but this is a good
opportunity to highlight some patch submitting good practices:
1) Your patch doesn't contain a Signed-off-by line so it cannot be applied.
2) Your patch is attached with an improper MIME type. If you cannot use
a more sane mailer, you should also inline your patches (it's impossible
for me to actually comment on your patch in a note without some nasty
copy-paste stuff).
3) You include no explanation of why your patch is needed. It seems
somewhat arbitrary to add /etc/xen/auto to the default search path. Why
do you need this and why do you think other people would need this?
4) Your patch is based at a weird location (within tools/). It's
usually best to patch at the top of the repository (diff -u
a/tools/xen/xm/create.py b/tools/....). Actually, if you just use hg
export, it'll do the right thing for you.
Please resubmit with the appropriate corrections.
Thanks!
Regards,
Anthony Liguori
Itamar Reis Peixoto wrote:
> attached.
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>
^ permalink raw reply
* Re: Remove unused exports and save 98Kb of kernel size
From: Takashi Iwai @ 2006-04-03 16:38 UTC (permalink / raw)
To: Arjan van de Ven; +Cc: linux-kernel
In-Reply-To: <1143925545.3076.35.camel@laptopd505.fenrus.org>
At Sat, 01 Apr 2006 23:05:45 +0200,
Arjan van de Ven wrote:
>
> Hi,
>
> I've made a patch to remove all EXPORT_SYMBOL's that aren't used in the
> kernel; it's too big for the list so it can be found at
>
> http://www.kernelmorons.org/unexport.patch
>
> -rwxr-xr-x 1 root root 34476416 Apr 1 21:59 vmlinux.before
> -rwxr-xr-x 1 root root 34378112 Apr 1 22:48 vmlinux.after
>
> As you can see this saves 98Kb kernel size... that's not peanuts.
>
> Signed-off-by: Arjan van de Ven <arjan@kernelmorons.org>
Please be careful, many removals in sound will break under certain
kernel config (e.g. CONFIG_ISA).
Takashi
^ permalink raw reply
* see info
From: Rupinder Merkle @ 2006-04-03 16:37 UTC (permalink / raw)
To: alsa-devel
[-- Attachment #1: Type: text/plain, Size: 130 bytes --]
Get ready in 15 minutes - d C x i j a n l o i k s x S a O f F s T n T k
a i b f s go to the site <http://qyhu37.mycarandr.com>
[-- Attachment #2: Type: text/html, Size: 1080 bytes --]
^ permalink raw reply
* Re: patch : hdaps on Thinkpad R52
From: Frank Gevaerts @ 2006-04-03 16:35 UTC (permalink / raw)
To: Jean Delvare; +Cc: Frank Gevaerts, Robert Love, linux-kernel
In-Reply-To: <20060401170422.cc2ff8c2.khali@linux-fr.org>
On Sat, Apr 01, 2006 at 05:04:22PM +0200, Jean Delvare wrote:
> Hi Frank,
>
> > # dmidecode 2.8
> > (...)
> > System Information
> > Manufacturer: IBM
> > Product Name: 1846AQG
> > Version: ThinkPad H
>
> OK, so as strange as it sounds, that's really the string as stored in
> the DMI table. How odd... You have to understand that I'm a bit
> reluctant to adding it officially to the hdaps driver, given that it
> clearly looks like a bogus table in your laptop. I guess that you only
> have one laptop with this string?
I just had a mail from another R52 user, reporting that his system
(also 1846AQG) also reports ThinkPad H.
Frank
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it." - Brian W. Kernighan
^ permalink raw reply
* [PATCH] Replace xmalloc+memset(0) with xcalloc.
From: Peter Eriksen @ 2006-04-03 16:35 UTC (permalink / raw)
To: git
From: Peter Eriksen <s022018@student.dtu.dk>
Date: Mon Apr 3 19:30:46 2006 +0100
Subject: [PATCH] Replace xmalloc+memset(0) with xcalloc.
Signed-off-by: Peter Eriksen <s022018@student.dtu.dk>
---
Is something like this considered a cleaup?
Regards,
Peter
apply.c | 9 +++------
blob.c | 3 +--
commit.c | 3 +--
convert-objects.c | 3 +--
http-push.c | 6 ++----
object.c | 6 ++----
read-tree.c | 9 +++------
tag.c | 3 +--
tree.c | 7 ++-----
update-index.c | 6 ++----
10 files changed, 18 insertions(+), 37 deletions(-)
d5c82aa8a2b9d776bb30efac17d15a8a596b47f4
diff --git a/apply.c b/apply.c
index c50b3a6..6623ae7 100644
--- a/apply.c
+++ b/apply.c
@@ -924,8 +924,7 @@ static int parse_single_patch(char *line
struct fragment *fragment;
int len;
- fragment = xmalloc(sizeof(*fragment));
- memset(fragment, 0, sizeof(*fragment));
+ fragment = xcalloc(1, sizeof(*fragment));
len = parse_fragment(line, size, patch, fragment);
if (len <= 0)
die("corrupt patch at line %d", linenr);
@@ -1651,8 +1650,7 @@ static void add_index_file(const char *p
if (!write_index)
return;
- ce = xmalloc(ce_size);
- memset(ce, 0, ce_size);
+ ce = xcalloc(1, ce_size);
memcpy(ce->name, path, namelen);
ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = htons(namelen);
@@ -1808,8 +1806,7 @@ static int apply_patch(int fd, const cha
struct patch *patch;
int nr;
- patch = xmalloc(sizeof(*patch));
- memset(patch, 0, sizeof(*patch));
+ patch = xcalloc(1, sizeof(*patch));
nr = parse_chunk(buffer + offset, size, patch);
if (nr < 0)
break;
diff --git a/blob.c b/blob.c
index 84ec121..c1fdd86 100644
--- a/blob.c
+++ b/blob.c
@@ -8,8 +8,7 @@ struct blob *lookup_blob(const unsigned
{
struct object *obj = lookup_object(sha1);
if (!obj) {
- struct blob *ret = xmalloc(sizeof(struct blob));
- memset(ret, 0, sizeof(struct blob));
+ struct blob *ret = xcalloc(1, sizeof(struct blob));
created_object(sha1, &ret->object);
ret->object.type = blob_type;
return ret;
diff --git a/commit.c b/commit.c
index eb42d51..d4976fb 100644
--- a/commit.c
+++ b/commit.c
@@ -73,8 +73,7 @@ struct commit *lookup_commit(const unsig
{
struct object *obj = lookup_object(sha1);
if (!obj) {
- struct commit *ret = xmalloc(sizeof(struct commit));
- memset(ret, 0, sizeof(struct commit));
+ struct commit *ret = xcalloc(1, sizeof(struct commit));
created_object(sha1, &ret->object);
ret->object.type = commit_type;
return ret;
diff --git a/convert-objects.c b/convert-objects.c
index b49bce2..b2aafbb 100644
--- a/convert-objects.c
+++ b/convert-objects.c
@@ -18,8 +18,7 @@ static struct entry * convert_entry(unsi
static struct entry *insert_new(unsigned char *sha1, int pos)
{
- struct entry *new = xmalloc(sizeof(struct entry));
- memset(new, 0, sizeof(*new));
+ struct entry *new = xcalloc(1, sizeof(struct entry));
memcpy(new->old_sha1, sha1, 20);
memmove(convert + pos + 1, convert + pos, (nr_convert - pos) * sizeof(struct entry *));
convert[pos] = new;
diff --git a/http-push.c b/http-push.c
index ba7d9de..b60fa8d 100644
--- a/http-push.c
+++ b/http-push.c
@@ -1008,8 +1008,7 @@ static int fetch_indices(void)
struct active_request_slot *slot;
struct slot_results results;
- data = xmalloc(4096);
- memset(data, 0, 4096);
+ data = xcalloc(1, 4096);
buffer.size = 4096;
buffer.posn = 0;
buffer.buffer = data;
@@ -2042,8 +2041,7 @@ static void update_remote_info_refs(stru
char *if_header;
struct curl_slist *dav_headers = NULL;
- buffer.buffer = xmalloc(4096);
- memset(buffer.buffer, 0, 4096);
+ buffer.buffer = xcalloc(1, 4096);
buffer.size = 4096;
buffer.posn = 0;
remote_ls("refs/", (PROCESS_FILES | RECURSIVE),
diff --git a/object.c b/object.c
index c9ca481..71e15e1 100644
--- a/object.c
+++ b/object.c
@@ -85,8 +85,7 @@ struct object_refs *alloc_object_refs(un
struct object_refs *refs;
size_t size = sizeof(*refs) + count*sizeof(struct object *);
- refs = xmalloc(size);
- memset(refs, 0, size);
+ refs = xcalloc(1, size);
refs->count = count;
return refs;
}
@@ -178,8 +177,7 @@ struct object *lookup_unknown_object(con
{
struct object *obj = lookup_object(sha1);
if (!obj) {
- union any_object *ret = xmalloc(sizeof(*ret));
- memset(ret, 0, sizeof(*ret));
+ union any_object *ret = xcalloc(1, sizeof(*ret));
created_object(sha1, &ret->object);
ret->object.type = NULL;
return &ret->object;
diff --git a/read-tree.c b/read-tree.c
index eaff444..58e5636 100644
--- a/read-tree.c
+++ b/read-tree.c
@@ -133,11 +133,9 @@ #endif
pathlen = strlen(first);
ce_size = cache_entry_size(baselen + pathlen);
- src = xmalloc(sizeof(struct cache_entry *) * src_size);
- memset(src, 0, sizeof(struct cache_entry *) * src_size);
+ src = xcalloc(src_size, sizeof(struct cache_entry *));
- subposns = xmalloc(sizeof(struct tree_list_entry *) * len);
- memset(subposns, 0, sizeof(struct tree_list_entry *) * len);
+ subposns = xcalloc(len, sizeof(struct tree_list_entry *));
if (cache_name && !strcmp(cache_name, first)) {
any_files = 1;
@@ -177,8 +175,7 @@ #endif
else
ce_stage = 2;
- ce = xmalloc(ce_size);
- memset(ce, 0, ce_size);
+ ce = xcalloc(1, ce_size);
ce->ce_mode = create_ce_mode(posns[i]->mode);
ce->ce_flags = create_ce_flags(baselen + pathlen,
ce_stage);
diff --git a/tag.c b/tag.c
index ac0e573..f390ee7 100644
--- a/tag.c
+++ b/tag.c
@@ -19,8 +19,7 @@ struct tag *lookup_tag(const unsigned ch
{
struct object *obj = lookup_object(sha1);
if (!obj) {
- struct tag *ret = xmalloc(sizeof(struct tag));
- memset(ret, 0, sizeof(struct tag));
+ struct tag *ret = xcalloc(1, sizeof(struct tag));
created_object(sha1, &ret->object);
ret->object.type = tag_type;
return ret;
diff --git a/tree.c b/tree.c
index 87e0d74..d599fb5 100644
--- a/tree.c
+++ b/tree.c
@@ -18,10 +18,8 @@ static int read_one_entry(unsigned char
len = strlen(pathname);
size = cache_entry_size(baselen + len);
- ce = xmalloc(size);
+ ce = xcalloc(1, size);
- memset(ce, 0, size);
-
ce->ce_mode = create_ce_mode(mode);
ce->ce_flags = create_ce_flags(baselen + len, stage);
memcpy(ce->name, base, baselen);
@@ -130,8 +128,7 @@ struct tree *lookup_tree(const unsigned
{
struct object *obj = lookup_object(sha1);
if (!obj) {
- struct tree *ret = xmalloc(sizeof(struct tree));
- memset(ret, 0, sizeof(struct tree));
+ struct tree *ret = xcalloc(1, sizeof(struct tree));
created_object(sha1, &ret->object);
ret->object.type = tree_type;
return ret;
diff --git a/update-index.c b/update-index.c
index 797245a..1efac27 100644
--- a/update-index.c
+++ b/update-index.c
@@ -114,8 +114,7 @@ static int add_file_to_cache(const char
namelen = strlen(path);
size = cache_entry_size(namelen);
- ce = xmalloc(size);
- memset(ce, 0, size);
+ ce = xcalloc(1, size);
memcpy(ce->name, path, namelen);
ce->ce_flags = htons(namelen);
fill_stat_cache_info(ce, &st);
@@ -312,8 +311,7 @@ static int add_cacheinfo(unsigned int mo
len = strlen(path);
size = cache_entry_size(len);
- ce = xmalloc(size);
- memset(ce, 0, size);
+ ce = xcalloc(1, size);
memcpy(ce->sha1, sha1, 20);
memcpy(ce->name, path, len);
--
1.3.0.rc1.g40e9
^ permalink raw reply related
* Re: accessed/dirty bit handler tuning
From: Zoltan Menyhart @ 2006-04-03 16:33 UTC (permalink / raw)
To: linux-ia64
In-Reply-To: <44157CF1.5060902@bull.net>
Luck, Tony wrote:
>>It is very much curious having so few dirty and i-access traps...
>
>
> Your data collection code has races (ld8, add, st8 on one cpu can
> race with another cpu doing the same). So you'll undercount whenever
> a race happens.
>
> Perhaps you should use per-cpu counters to collect the values, and
> then sum for each cpu in the syscall() before reporting to the user?
It was not very important to count the events precisely.
The lesson I learnt is the VHPT miss handler is the most important
(maybe the D-ACCESS trap handler), the others are "neglectable".
(I have not counted yet the handlers not doing a purge.)
The problem is that the most frequently used trap handler contains
the unsafe walk of the
rx = IA64_KR_PT_BASE -> pgd[i] -> pud[j] -> pmd[k] -> pte[l]
chain...
Zoltan
^ permalink raw reply
* Re: Changes over dmix: 1.0.11rc4 and future
From: Lee Revell @ 2006-04-03 16:29 UTC (permalink / raw)
To: Takashi Iwai; +Cc: alsa-devel
In-Reply-To: <s5h3bgvc739.wl%tiwai@suse.de>
On Mon, 2006-04-03 at 11:59 +0200, Takashi Iwai wrote:
>
> If you still get an error regarding variable_buffer_size, just remove
> that line.
>
> And note that this won't work with emu10k1.
I now get:
Playing WAVE '/usr/share/sounds/error.wav' : Signed 16 bit Little
Endian, Rate 44100 Hz, Mono
ALSA lib pcm_params.c:2152:(snd_pcm_hw_refine_slave) Slave PCM not
usable
aplay: set_params:879: Broken configuration for this PCM: no
configurations available
Which I think is normal as hw:0,0 on the emu10k1 is only a stereo
device.
Lee
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply
* Re: Overhead of Using a Stackable File System(Wrapfs)
From: Erez Zadok @ 2006-04-03 16:27 UTC (permalink / raw)
To: UZAIR LAKHANI; +Cc: linux-fsdevel
In-Reply-To: <20060402093211.27655.qmail@web37911.mail.mud.yahoo.com>
You can find a lot of papers spanning several years and covering a wide
variety of stackable file systems, with detailed performance evaluations,
here:
http://www.filesystems.org/
Erez.
^ permalink raw reply
* Re: git-svn and svn sw --relocate
From: Nicolas Vilz 'niv' @ 2006-04-03 16:20 UTC (permalink / raw)
To: git
In-Reply-To: <20060402222100.GA17888@localdomain>
Eric Wong wrote:
> Nicolas Vilz 'niv' <niv@iaglans.de> wrote:
>>i have now my repository locally and i want to get it remotely on a
>>server, in order to have a few collaborators...
>>
>>the steps on the svn-side are clear. But what do i have todo on the
>>git-svn-side of this life?
>>
>>does a simple "svn sw --relocate" do the job in the git-svn meta-dir?
>
>
> Yes, you'll need to do that in .git/git-svn/tree and also update
> .git/git-svn/info/url by hand.
Will there be any other sha1-sums for that repository so that i have to
merge them again and again? This issue occured to me the last time i
encountered the git-svn-change with the external sources, where i had to
repair my external git-svn-tree, which resulted in new sha1sums
somehow... that was very unpleasant to my collegue..
Although the uuids there should remain the same... so i think, that
would be no problem to try.
Thanks for the tip.
Nicolas
^ permalink raw reply
* [PATCH] fix MIPS PFN/page borkage (take 2)
From: Dave Hansen @ 2006-04-03 16:21 UTC (permalink / raw)
To: ralf; +Cc: linux-kernel, Dave Hansen
The "unify PFN_* macros" patch screwed up and somehow modified
the MIPS code where it shouldn't have. This backs those changes
back out.
Also remember to include the new header in the MIPS files.
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
---
work-dave/arch/mips/mips-boards/generic/memory.c | 5 +++--
work-dave/arch/mips/mips-boards/sim/sim_mem.c | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff -puN arch/mips/mips-boards/generic/memory.c~unify_PFN_macros arch/mips/mips-boards/generic/memory.c
--- work/arch/mips/mips-boards/generic/memory.c~unify_PFN_macros 2006-04-03 09:09:42.000000000 -0700
+++ work-dave/arch/mips/mips-boards/generic/memory.c 2006-04-03 09:20:36.000000000 -0700
@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/pfn.h>
#include <linux/string.h>
#include <asm/bootinfo.h>
@@ -106,10 +107,10 @@ struct prom_pmemblock * __init prom_getm
mdesc[3].type = yamon_dontuse;
mdesc[3].base = 0x00100000;
- mdesc[3].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[3].base;
+ mdesc[3].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[3].base;
mdesc[4].type = yamon_free;
- mdesc[4].base = CPHYSADDR(PAGE_ALIGN(&_end));
+ mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end));
mdesc[4].size = memsize - mdesc[4].base;
return &mdesc[0];
diff -puN arch/mips/mips-boards/sim/sim_mem.c~unify_PFN_macros arch/mips/mips-boards/sim/sim_mem.c
--- work/arch/mips/mips-boards/sim/sim_mem.c~unify_PFN_macros 2006-04-03 09:09:42.000000000 -0700
+++ work-dave/arch/mips/mips-boards/sim/sim_mem.c 2006-04-03 09:20:46.000000000 -0700
@@ -17,6 +17,7 @@
*/
#include <linux/init.h>
#include <linux/mm.h>
+#include <linux/pfn.h>
#include <linux/bootmem.h>
#include <asm/bootinfo.h>
@@ -61,10 +62,10 @@ struct prom_pmemblock * __init prom_getm
mdesc[2].type = simmem_reserved;
mdesc[2].base = 0x00100000;
- mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base;
+ mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base;
mdesc[3].type = simmem_free;
- mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end));
+ mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end));
mdesc[3].size = memsize - mdesc[3].base;
return &mdesc[0];
_
^ permalink raw reply
* Re: [PATCHSET] libata: improve ata_bus_probe failure handling, take 2
From: Jeff Garzik @ 2006-04-03 16:20 UTC (permalink / raw)
To: Greg Freemyer; +Cc: albertl, Tejun Heo, linux-ide, alan
In-Reply-To: <87f94c370604030737y7ef96ed8g5d887ff768845956@mail.gmail.com>
Greg Freemyer wrote:
> On 4/3/06, Jeff Garzik <jgarzik@pobox.com> wrote:
>
>> For the record, I do consider irq-pio upstream ready. It still needs to
>> wait for Tejun's EH work to make it upstream, to give upstream people
>> the test sets of
>>
>> - prep EH (2.6.17-rc1)
>> - EH
>> - NCQ
>> - irq-pio
>>
>> Since each of these sets is staged, upstream testers will be able to say
>> "2.6.17-rc1 works, but 2.6.18-git1 doesn't", which gives us a lot of
>> good info.
>>
>> Jeff
>
> So for those of us anxiously waiting for the above great enhancements
> it looks like it will be 5 months or so before it is in a released
> vanilla kernel? ie. assuming 2 1/2 months per kernel release.
Heavens no :)
The stages above just need to be separated out by a few 2.6.X-gitX or
2.6.X-rcX releases.
Jeff
^ permalink raw reply
* creating partition mappings with different delimiters
From: Eddie Williams @ 2006-04-03 16:19 UTC (permalink / raw)
To: dm-devel
Where/how does kpartx determine the default delimiter when creating the
partition mappings and nodes?
With Red Hat EL 4 Update 3 during bootup the partition mappings are
getting created in rc.sysinit. However I find that some of the mappings
have no delimiter while some have 'p' as the delimiter. I prefer 'p' as
the delimiter.
I have been unsuccessful at finding where kpartx (or is it dmsetup) is
determining what delimiter to use.
Eddie
^ permalink raw reply
* Re: _machine removal breaks kexec?
From: Benjamin Herrenschmidt @ 2006-04-03 16:16 UTC (permalink / raw)
To: Anton Blanchard; +Cc: linuxppc-dev, paulus
In-Reply-To: <20060403014044.GA4704@krispykreme>
On Mon, 2006-04-03 at 11:40 +1000, Anton Blanchard wrote:
> Hi,
>
> It looks like the _machine removal broke kexec:
>
> # kexec -l vmlinux
> /proc/device-tree/chosen/linux,platform: No such file or directory
>
> The kexec tools seem to want the linux,platform property:
>
> /* if LPAR, no need to read any more from /chosen */
> if (platform != PLATFORM_PSERIES) {
> closedir(cdir);
> continue;
> }
Damn.... the platform numbers are gone, we need to fix that. (And nobody
complained when I posted the patch twice over the past couple of monthes
btw).
I suppose kexec needs to look for /rtas/hypertas or such ..
Ben.
^ permalink raw reply
* Re: [PATCH] fix MIPS PFN/page borkage
From: Ralf Baechle @ 2006-04-03 16:16 UTC (permalink / raw)
To: Dave Hansen; +Cc: linux-kernel
In-Reply-To: <20060403161131.0790DD9A@localhost.localdomain>
On Mon, Apr 03, 2006 at 09:11:31AM -0700, Dave Hansen wrote:
> The "unify PFN_* macros" patch screwed up and somehow modified
> the MIPS code where it shouldn't have. This backs those changes
> back out.
You need to include <linux/pfn.h> for this to build.
Ralf
^ permalink raw reply
* Re: alsa cvs broken
From: Takashi Iwai @ 2006-04-03 16:15 UTC (permalink / raw)
To: Rene Herman; +Cc: Jaroslav Kysela, James Courtier-Dutton, alsa-devel
In-Reply-To: <443147CC.40905@keyaccess.nl>
At Mon, 03 Apr 2006 18:05:32 +0200,
Rene Herman wrote:
>
> Jaroslav Kysela wrote:
>
> > I must say that git looks too much "kernel" oriented and sometimes
> > hard-to-use. Mercurial has my sympatics, because it uses Python (on
> > other hand, it might imply some performance issues).
> >
> > I would start with mercurial and we'll see then.
>
> Mind a vote against mercurial, and for GIT? Not because I think GIT is
> necesarily (and at the moment) better -- I in fact don't know either yet
> in any detail.
>
> GIT is the kernel SCM though and unless it's really significantly worse,
> I believe it's better to simply use it. I've been looking to get into
> ALSA a bit for example, and I'd really not appreciate having to learn
> yet another SCM when I'm going to be making use of GIT for all the other
> kernel stuff anyway.
It's true that git would be in favor from the kernel viewpoint.
However, ALSA has pretty many other stuff. The kernel code is even a
small part.
What I'm not quite sure is the push-functionality of git. If we have
a main development tree, the patches are pushed by multiple
developers. It's a different use from kernel trees.
If the multiple push works fine with git, I have nothing against it at
all.
> GIT is also still picking up speed. Keith Packard was even converting X
> CVS for example. Mercurial might be good I guess, but it's also very
> likely going to be one of those "oh no, not yet another" ones, maybe
> even keeping potential developers away.
We can anyway provide a nightly tarball for lazy developers :)
Let's evaluate both first.
Takashi
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
^ permalink raw reply
* Re: False OOM with swappiness == 0
From: Mikulas Patocka @ 2006-04-03 16:13 UTC (permalink / raw)
To: LKML
In-Reply-To: <Pine.LNX.4.64.0604031811270.7588@artax.karlin.mff.cuni.cz>
> Hi
>
> On one our server we've seen that OOM killer kills a process even if there's
> plenty of free swap space. The server had swappiness set to 0 which probably
> triggered the bug.
>
> Mikulas
I forgot to tell kernel version: 2.6.15-gentoo-r1. Dual Opteron with 4G
RAM.
Mikulas
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.