Hi,
Here's some PCI and sysfs fixes that are against the latest 2.5.74 bk
tree. They include Matthew Wilcox's set of pci cleanups, and sysfs
fixes for binary files. That led into my sysfs attribute file change,
which required John Stultz's timer build fix. I've also added the
sysfs/kobject/class rename patches based on previously posted patches.
Please pull from:
bk://kernel.bkbits.net/gregkh/linux/pci-2.5
thanks,
greg k-h
p.s. I'll send these as patches in response to this email to lkml for
those who want to see them.
-----
Documentation/pci.txt | 12 ++-
arch/i386/kernel/timers/timer_cyclone.c | 4 -
arch/i386/kernel/timers/timer_tsc.c | 17 ++++-
arch/i386/pci/direct.c | 2
arch/i386/pci/irq.c | 11 +--
arch/i386/pci/legacy.c | 26 +------
arch/sh/kernel/cpu/sh4/pci-sh7751.c | 2
drivers/base/class.c | 20 ++++++
drivers/base/firmware_class.c | 4 -
drivers/pci/hotplug/acpiphp_glue.c | 2
drivers/pci/hotplug/cpci_hotplug_pci.c | 2
drivers/pci/hotplug/ibmphp_core.c | 6 -
drivers/pci/pci-sysfs.c | 105 ++++++++++++++++++++++++++++++++
drivers/pci/pci.h | 1
drivers/pci/probe.c | 13 ---
drivers/pci/search.c | 32 +++++----
fs/sysfs/bin.c | 27 +++-----
fs/sysfs/dir.c | 22 ++++++
fs/sysfs/file.c | 9 ++
include/linux/device.h | 13 ++-
include/linux/kobject.h | 2
include/linux/pci.h | 2
include/linux/sysfs.h | 5 +
lib/kobject.c | 15 ++++
24 files changed, 262 insertions(+), 92 deletions(-)
-----
Greg Kroah-Hartman:
o driver core: add my copyright to class.c
o driver core: added class_device_rename() Based on a patch written by Dan Aloni <[email protected]>
o kobject: add kobject_rename() Based on a patch written by Dan Aloni <[email protected]>
o sysfs: add sysfs_rename_dir() Based on a patch written by Dan Aloni <[email protected]>
o SYSFS: add module referencing to sysfs attribute files
o sysfs: change print() to pr_debug() to not annoy everyone
o PCI: change WARN_ON(irqs_disabled()) to WARN_ON(in_interrupt()) to keep the fusion drivers happy
John Stultz:
o jiffies include fix This patch fixes a bad declaration of jiffies in timer_tsc.c and timer_cyclone.c, replacing it with the proper usage of jiffies.h.
Matthew Wilcox:
o Driver Core: fix firmware binary files Fixes the sysfs binary file bug.
o PCI config space in sysfs
o PCI: arch/i386/pci/legacy.c: use raw_pci_ops Make pcibios_fixup_peer_bridges() use raw_pci_ops directly instead of faking pci_bus and pci_dev.
o PCI: arch/i386/pci/irq.c should use pci_find_bus Use pci_find_bus rather than relying on the return value of pci_scan_bus.
o PCI: Remove pci_bus_exists Convert all callers of pci_bus_exists() to call pci_find_bus() instead.
o PCI: pci_find_bus needs a domain Give pci_find_bus a domain argument and move its declaration to <linux/pci.h>
o PCI: arch/i386/pci/direct.c can use __init, not __devinit pci_sanity_check() is only called from functions marked __init, so it can be __init too.
o PCI: Improve documentation Fix some grammar problems Add a note about Fast Back to Back support Change the slot_name recommendation to pci_name().
ChangeSet 1.1377, 2003/07/03 17:51:08-07:00, [email protected]
driver core: add my copyright to class.c
drivers/base/class.c | 2 ++
1 files changed, 2 insertions(+)
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c Thu Jul 3 18:15:33 2003
+++ b/drivers/base/class.c Thu Jul 3 18:15:33 2003
@@ -3,6 +3,8 @@
*
* Copyright (c) 2002-3 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
+ * Copyright (c) 2003 Greg Kroah-Hartman
+ * Copyright (c) 2003 IBM Corp.
*
* This file is released under the GPLv2
*
ChangeSet 1.1371, 2003/07/03 16:06:08-07:00, [email protected]
[PATCH] sysfs: change print() to pr_debug() to not annoy everyone.
fs/sysfs/bin.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletion(-)
diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c
--- a/fs/sysfs/bin.c Thu Jul 3 18:16:09 2003
+++ b/fs/sysfs/bin.c Thu Jul 3 18:16:09 2003
@@ -2,6 +2,8 @@
* bin.c - binary file operations for sysfs.
*/
+#undef DEBUG
+
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kobject.h>
@@ -48,7 +50,7 @@
if (copy_to_user(userbuf, buffer + offs, count) != 0)
return -EINVAL;
- printk("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
+ pr_debug("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
*off = offs + count;
ChangeSet 1.1375, 2003/07/03 17:43:34-07:00, [email protected]
[PATCH] kobject: add kobject_rename()
Based on a patch written by Dan Aloni <[email protected]>
include/linux/kobject.h | 2 ++
lib/kobject.c | 15 +++++++++++++++
2 files changed, 17 insertions(+)
diff -Nru a/include/linux/kobject.h b/include/linux/kobject.h
--- a/include/linux/kobject.h Thu Jul 3 18:15:44 2003
+++ b/include/linux/kobject.h Thu Jul 3 18:15:44 2003
@@ -39,6 +39,8 @@
extern int kobject_add(struct kobject *);
extern void kobject_del(struct kobject *);
+extern void kobject_rename(struct kobject *, char *new_name);
+
extern int kobject_register(struct kobject *);
extern void kobject_unregister(struct kobject *);
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c Thu Jul 3 18:15:44 2003
+++ b/lib/kobject.c Thu Jul 3 18:15:44 2003
@@ -314,6 +314,21 @@
}
/**
+ * kobject_rename - change the name of an object
+ * @kobj: object in question.
+ * @new_name: object's new name
+ */
+
+void kobject_rename(struct kobject * kobj, char *new_name)
+{
+ kobj = kobject_get(kobj);
+ if (!kobj)
+ return;
+ sysfs_rename_dir(kobj, new_name);
+ kobject_put(kobj);
+}
+
+/**
* kobject_del - unlink kobject from hierarchy.
* @kobj: object.
*/
ChangeSet 1.1376, 2003/07/03 17:43:49-07:00, [email protected]
[PATCH] driver core: added class_device_rename()
Based on a patch written by Dan Aloni <[email protected]>
drivers/base/class.c | 18 ++++++++++++++++++
include/linux/device.h | 2 ++
2 files changed, 20 insertions(+)
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c Thu Jul 3 18:15:38 2003
+++ b/drivers/base/class.c Thu Jul 3 18:15:38 2003
@@ -339,6 +339,24 @@
class_device_put(class_dev);
}
+int class_device_rename(struct class_device *class_dev, char *new_name)
+{
+ class_dev = class_device_get(class_dev);
+ if (!class_dev)
+ return -EINVAL;
+
+ pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
+ new_name);
+
+ strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
+
+ kobject_rename(&class_dev->kobj, new_name);
+
+ class_device_put(class_dev);
+
+ return 0;
+}
+
struct class_device * class_device_get(struct class_device *class_dev)
{
if (class_dev)
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h Thu Jul 3 18:15:38 2003
+++ b/include/linux/device.h Thu Jul 3 18:15:38 2003
@@ -216,6 +216,8 @@
extern int class_device_add(struct class_device *);
extern void class_device_del(struct class_device *);
+extern int class_device_rename(struct class_device *, char *);
+
extern struct class_device * class_device_get(struct class_device *);
extern void class_device_put(struct class_device *);
ChangeSet 1.1364, 2003/07/03 15:50:59-07:00, [email protected]
[PATCH] PCI: arch/i386/pci/direct.c can use __init, not __devinit
pci_sanity_check() is only called from functions marked __init, so it
can be __init too.
arch/i386/pci/direct.c | 2 +-
1 files changed, 1 insertion(+), 1 deletion(-)
diff -Nru a/arch/i386/pci/direct.c b/arch/i386/pci/direct.c
--- a/arch/i386/pci/direct.c Thu Jul 3 18:17:06 2003
+++ b/arch/i386/pci/direct.c Thu Jul 3 18:17:06 2003
@@ -177,7 +177,7 @@
* This should be close to trivial, but it isn't, because there are buggy
* chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
*/
-static int __devinit pci_sanity_check(struct pci_raw_ops *o)
+static int __init pci_sanity_check(struct pci_raw_ops *o)
{
u32 x = 0;
int devfn;
ChangeSet 1.1368, 2003/07/03 15:51:59-07:00, [email protected]
[PATCH] PCI: arch/i386/pci/legacy.c: use raw_pci_ops
Make pcibios_fixup_peer_bridges() use raw_pci_ops directly instead of
faking pci_bus and pci_dev.
arch/i386/pci/legacy.c | 24 +++++-------------------
1 files changed, 5 insertions(+), 19 deletions(-)
diff -Nru a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
--- a/arch/i386/pci/legacy.c Thu Jul 3 18:16:40 2003
+++ b/arch/i386/pci/legacy.c Thu Jul 3 18:16:40 2003
@@ -11,40 +11,26 @@
*/
static void __devinit pcibios_fixup_peer_bridges(void)
{
- int n;
- struct pci_bus *bus;
- struct pci_dev *dev;
- u16 l;
+ int n, devfn;
if (pcibios_last_bus <= 0 || pcibios_last_bus >= 0xff)
return;
DBG("PCI: Peer bridge fixup\n");
- bus = kmalloc(sizeof(*bus), GFP_ATOMIC);
- dev = kmalloc(sizeof(*dev), GFP_ATOMIC);
- if (!bus || !dev) {
- printk(KERN_ERR "Out of memory in %s\n", __FUNCTION__);
- goto exit;
- }
-
for (n=0; n <= pcibios_last_bus; n++) {
+ u32 l;
if (pci_find_bus(0, n))
continue;
- bus->number = n;
- bus->ops = &pci_root_ops;
- dev->bus = bus;
- for (dev->devfn=0; dev->devfn<256; dev->devfn += 8)
- if (!pci_read_config_word(dev, PCI_VENDOR_ID, &l) &&
+ for (devfn = 0; devfn < 256; devfn += 8) {
+ if (!raw_pci_ops->read(0, n, devfn, PCI_VENDOR_ID, 2, &l) &&
l != 0x0000 && l != 0xffff) {
DBG("Found device at %02x:%02x [%04x]\n", n, dev->devfn, l);
printk(KERN_INFO "PCI: Discovered peer bus %02x\n", n);
pci_scan_bus(n, &pci_root_ops, NULL);
break;
}
+ }
}
-exit:
- kfree(dev);
- kfree(bus);
}
static int __init pci_legacy_init(void)
ChangeSet 1.1365, 2003/07/03 15:51:15-07:00, [email protected]
[PATCH] PCI: pci_find_bus needs a domain
Give pci_find_bus a domain argument and move its declaration to <linux/pci.h>
drivers/pci/hotplug/acpiphp_glue.c | 2 +-
drivers/pci/hotplug/cpci_hotplug_pci.c | 2 +-
drivers/pci/hotplug/ibmphp_core.c | 6 +++---
drivers/pci/pci.h | 1 -
drivers/pci/search.c | 18 ++++++++++--------
include/linux/pci.h | 1 +
6 files changed, 16 insertions(+), 14 deletions(-)
diff -Nru a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
--- a/drivers/pci/hotplug/acpiphp_glue.c Thu Jul 3 18:17:01 2003
+++ b/drivers/pci/hotplug/acpiphp_glue.c Thu Jul 3 18:17:01 2003
@@ -385,7 +385,7 @@
bridge->seg = seg;
bridge->bus = bus;
- bridge->pci_bus = pci_find_bus(bus);
+ bridge->pci_bus = pci_find_bus(seg, bus);
bridge->res_lock = SPIN_LOCK_UNLOCKED;
diff -Nru a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c
--- a/drivers/pci/hotplug/cpci_hotplug_pci.c Thu Jul 3 18:17:01 2003
+++ b/drivers/pci/hotplug/cpci_hotplug_pci.c Thu Jul 3 18:17:01 2003
@@ -395,7 +395,7 @@
/* Scan behind bridge */
n = pci_scan_bridge(bus, dev, max, 2);
- child = pci_find_bus(max + 1);
+ child = pci_find_bus(0, max + 1);
if (!child)
return -ENODEV;
pci_proc_attach_bus(child);
diff -Nru a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
--- a/drivers/pci/hotplug/ibmphp_core.c Thu Jul 3 18:17:01 2003
+++ b/drivers/pci/hotplug/ibmphp_core.c Thu Jul 3 18:17:01 2003
@@ -774,7 +774,7 @@
struct pci_dev *dev;
u16 l;
- if (pci_find_bus(busno) || !(ibmphp_find_same_bus_num (busno)))
+ if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num (busno)))
return 1;
bus = kmalloc (sizeof (*bus), GFP_KERNEL);
@@ -819,7 +819,7 @@
func->dev = pci_find_slot (func->busno, PCI_DEVFN(func->device, func->function));
if (func->dev == NULL) {
- struct pci_bus *bus = pci_find_bus(func->busno);
+ struct pci_bus *bus = pci_find_bus(0, func->busno);
if (!bus)
return 0;
@@ -1335,7 +1335,7 @@
goto exit;
}
- bus = pci_find_bus(0);
+ bus = pci_find_bus(0, 0);
if (!bus) {
err ("Can't find the root pci bus, can not continue\n");
rc = -ENODEV;
diff -Nru a/drivers/pci/pci.h b/drivers/pci/pci.h
--- a/drivers/pci/pci.h Thu Jul 3 18:17:01 2003
+++ b/drivers/pci/pci.h Thu Jul 3 18:17:01 2003
@@ -29,7 +29,6 @@
extern unsigned char pci_max_busnr(void);
extern unsigned char pci_bus_max_busnr(struct pci_bus *bus);
extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap);
-extern struct pci_bus *pci_find_bus(unsigned char busnr);
struct pci_dev_wrapped {
struct pci_dev *dev;
diff -Nru a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c Thu Jul 3 18:17:01 2003
+++ b/drivers/pci/search.c Thu Jul 3 18:17:01 2003
@@ -31,22 +31,24 @@
}
/**
- * pci_find_bus - locate PCI bus from a given bus number
+ * pci_find_bus - locate PCI bus from a given domain and bus number
+ * @domain: number of PCI domain to search
* @busnr: number of desired PCI bus
*
- * Given a PCI bus number, the desired PCI bus is located in system
- * global list of PCI buses. If the bus is found, a pointer to its
+ * Given a PCI bus number and domain number, the desired PCI bus is located
+ * in the global list of PCI buses. If the bus is found, a pointer to its
* data structure is returned. If no bus is found, %NULL is returned.
*/
-struct pci_bus *
-pci_find_bus(unsigned char busnr)
+struct pci_bus * pci_find_bus(int domain, int busnr)
{
- struct pci_bus* bus = NULL;
- struct pci_bus* tmp_bus;
+ struct pci_bus *bus = NULL;
+ struct pci_bus *tmp_bus;
while ((bus = pci_find_next_bus(bus)) != NULL) {
+ if (pci_domain_nr(bus) != domain)
+ continue;
tmp_bus = pci_do_find_bus(bus, busnr);
- if(tmp_bus)
+ if (tmp_bus)
return tmp_bus;
}
return NULL;
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h Thu Jul 3 18:17:01 2003
+++ b/include/linux/pci.h Thu Jul 3 18:17:01 2003
@@ -543,6 +543,7 @@
/* Generic PCI functions used internally */
+extern struct pci_bus *pci_find_bus(int domain, int busnr);
int pci_bus_exists(const struct list_head *list, int nr);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
ChangeSet 1.1361, 2003/07/02 11:08:01-07:00, [email protected]
[PATCH] PCI: change WARN_ON(irqs_disabled()) to WARN_ON(in_interrupt()) to keep the fusion drivers happy.
drivers/pci/search.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff -Nru a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c Thu Jul 3 18:17:17 2003
+++ b/drivers/pci/search.c Thu Jul 3 18:17:17 2003
@@ -9,6 +9,7 @@
#include <linux/pci.h>
#include <linux/module.h>
+#include <linux/interrupt.h>
spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
@@ -66,7 +67,7 @@
struct list_head *n;
struct pci_bus *b = NULL;
- WARN_ON(irqs_disabled());
+ WARN_ON(in_interrupt());
spin_lock(&pci_bus_lock);
n = from ? from->node.next : pci_root_buses.next;
if (n != &pci_root_buses)
@@ -125,7 +126,7 @@
struct list_head *n;
struct pci_dev *dev;
- WARN_ON(irqs_disabled());
+ WARN_ON(in_interrupt());
spin_lock(&pci_bus_lock);
n = from ? from->global_list.next : pci_devices.next;
@@ -190,7 +191,7 @@
struct list_head *n;
struct pci_dev *dev;
- WARN_ON(irqs_disabled());
+ WARN_ON(in_interrupt());
spin_lock(&pci_bus_lock);
n = from ? from->global_list.next : pci_devices.next;
@@ -256,7 +257,7 @@
struct list_head *n;
struct pci_dev *dev;
- WARN_ON(irqs_disabled());
+ WARN_ON(in_interrupt());
spin_lock(&pci_bus_lock);
n = from ? from->global_list.prev : pci_devices.prev;
ChangeSet 1.1367, 2003/07/03 15:51:45-07:00, [email protected]
[PATCH] PCI: arch/i386/pci/irq.c should use pci_find_bus
Use pci_find_bus rather than relying on the return value of pci_scan_bus.
arch/i386/pci/irq.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff -Nru a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c Thu Jul 3 18:16:48 2003
+++ b/arch/i386/pci/irq.c Thu Jul 3 18:16:48 2003
@@ -102,13 +102,12 @@
#endif
busmap[e->bus] = 1;
}
- for(i=1; i<256; i++)
- /*
- * It might be a secondary bus, but in this case its parent is already
- * known (ascending bus order) and therefore pci_scan_bus returns immediately.
- */
- if (busmap[i] && pci_scan_bus(i, &pci_root_ops, NULL))
+ for(i = 1; i < 256; i++) {
+ if (!busmap[i] || pci_find_bus(0, i))
+ continue;
+ if (pci_scan_bus(i, &pci_root_ops, NULL))
printk(KERN_INFO "PCI: Discovered primary peer bus %02x [IRQ]\n", i);
+ }
pcibios_last_bus = -1;
}
ChangeSet 1.1373, 2003/07/03 16:39:18-07:00, [email protected]
[PATCH] jiffies include fix
This patch fixes a bad declaration of jiffies in timer_tsc.c and
timer_cyclone.c, replacing it with the proper usage of jiffies.h.
Caught by gregkh.
arch/i386/kernel/timers/timer_cyclone.c | 2 +-
arch/i386/kernel/timers/timer_tsc.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff -Nru a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c
--- a/arch/i386/kernel/timers/timer_cyclone.c Thu Jul 3 18:15:57 2003
+++ b/arch/i386/kernel/timers/timer_cyclone.c Thu Jul 3 18:15:57 2003
@@ -11,6 +11,7 @@
#include <linux/timex.h>
#include <linux/errno.h>
#include <linux/string.h>
+#include <linux/jiffies.h>
#include <asm/timer.h>
#include <asm/io.h>
@@ -18,7 +19,6 @@
#include <asm/fixmap.h>
extern spinlock_t i8253_lock;
-extern unsigned long jiffies;
extern unsigned long calibrate_tsc(void);
/* Number of usecs that the last interrupt was delayed */
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c Thu Jul 3 18:15:57 2003
+++ b/arch/i386/kernel/timers/timer_tsc.c Thu Jul 3 18:15:57 2003
@@ -9,6 +9,7 @@
#include <linux/errno.h>
#include <linux/cpufreq.h>
#include <linux/string.h>
+#include <linux/jiffies.h>
#include <asm/timer.h>
#include <asm/io.h>
@@ -21,7 +22,6 @@
int tsc_disable __initdata = 0;
extern spinlock_t i8253_lock;
-extern unsigned long jiffies;
static int use_tsc;
/* Number of usecs that the last interrupt was delayed */
ChangeSet 1.1378, 2003/07/03 17:52:16-07:00, [email protected]
Merge kroah.com:/home/linux/BK/bleed-2.5
into kroah.com:/home/linux/BK/pci-2.5
arch/i386/kernel/timers/timer_cyclone.c | 2 +-
arch/i386/kernel/timers/timer_tsc.c | 15 +++++++++++++--
2 files changed, 14 insertions(+), 3 deletions(-)
diff -Nru a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c
--- a/arch/i386/kernel/timers/timer_cyclone.c Thu Jul 3 18:15:27 2003
+++ b/arch/i386/kernel/timers/timer_cyclone.c Thu Jul 3 18:15:27 2003
@@ -88,7 +88,7 @@
* between cyclone and pit reads (as noted when
* usec delta is > 90% # of usecs/tick)
*/
- if (abs(delay - delay_at_last_interrupt) > (900000/HZ))
+ if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
jiffies++;
}
diff -Nru a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c
--- a/arch/i386/kernel/timers/timer_tsc.c Thu Jul 3 18:15:27 2003
+++ b/arch/i386/kernel/timers/timer_tsc.c Thu Jul 3 18:15:27 2003
@@ -124,6 +124,7 @@
int countmp;
static int count1 = 0;
unsigned long long this_offset, last_offset;
+ static int lost_count = 0;
write_lock(&monotonic_lock);
last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
@@ -178,9 +179,19 @@
delta += delay_at_last_interrupt;
lost = delta/(1000000/HZ);
delay = delta%(1000000/HZ);
- if (lost >= 2)
+ if (lost >= 2) {
jiffies += lost-1;
+ /* sanity check to ensure we're not always loosing ticks */
+ if (lost_count++ > 100) {
+ printk(KERN_WARNING "Loosing too many ticks!\n");
+ printk(KERN_WARNING "TSC cannot be used as a timesource."
+ " (Are you running with SpeedStep?)\n");
+ printk(KERN_WARNING "Falling back to a sane timesource.\n");
+ clock_fallback();
+ }
+ } else
+ lost_count = 0;
/* update the monotonic base value */
this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
monotonic_base += cycles_2_ns(this_offset - last_offset);
@@ -194,7 +205,7 @@
* between tsc and pit reads (as noted when
* usec delta is > 90% # of usecs/tick)
*/
- if (abs(delay - delay_at_last_interrupt) > (900000/HZ))
+ if (lost && abs(delay - delay_at_last_interrupt) > (900000/HZ))
jiffies++;
}
ChangeSet 1.1370, 2003/07/03 15:52:29-07:00, [email protected]
[PATCH] Driver Core: fix firmware binary files
Fixes the sysfs binary file bug.
drivers/base/firmware_class.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff -Nru a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
--- a/drivers/base/firmware_class.c Thu Jul 3 18:16:20 2003
+++ b/drivers/base/firmware_class.c Thu Jul 3 18:16:20 2003
@@ -149,7 +149,7 @@
if (offset + count > fw->size)
count = fw->size - offset;
- memcpy(buffer, fw->data + offset, count);
+ memcpy(buffer + offset, fw->data + offset, count);
return count;
}
static int
@@ -198,7 +198,7 @@
if (retval)
return retval;
- memcpy(fw->data + offset, buffer, count);
+ memcpy(fw->data + offset, buffer + offset, count);
fw->size = max_t(size_t, offset + count, fw->size);
ChangeSet 1.1369, 2003/07/03 15:52:14-07:00, [email protected]
[PATCH] PCI config space in sysfs
- Fix a couple of bugs in sysfs's handling of binary files (my fault).
- Implement pci config space reads and writes in sysfs
drivers/pci/pci-sysfs.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++
fs/sysfs/bin.c | 23 ++++------
2 files changed, 114 insertions(+), 14 deletions(-)
diff -Nru a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c Thu Jul 3 18:16:32 2003
+++ b/drivers/pci/pci-sysfs.c Thu Jul 3 18:16:32 2003
@@ -3,6 +3,8 @@
*
* (C) Copyright 2002 Greg Kroah-Hartman
* (C) Copyright 2002 IBM Corp.
+ * (C) Copyright 2003 Matthew Wilcox
+ * (C) Copyright 2003 Hewlett-Packard
*
* File attributes for PCI devices
*
@@ -60,6 +62,108 @@
static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);
+static ssize_t
+pci_read_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
+ unsigned int size = 64;
+
+ /* Several chips lock up trying to read undefined config space */
+ if (capable(CAP_SYS_ADMIN)) {
+ size = 256;
+ } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+ size = 128;
+ }
+
+ if (off > size)
+ return 0;
+ if (off + count > size) {
+ size -= off;
+ count = size;
+ } else {
+ size = count;
+ }
+
+ while (off & 3) {
+ unsigned char val;
+ pci_read_config_byte(dev, off, &val);
+ buf[off] = val;
+ off++;
+ if (--size == 0)
+ break;
+ }
+
+ while (size > 3) {
+ unsigned int val;
+ pci_read_config_dword(dev, off, &val);
+ buf[off] = val & 0xff;
+ buf[off + 1] = (val >> 8) & 0xff;
+ buf[off + 2] = (val >> 16) & 0xff;
+ buf[off + 3] = (val >> 24) & 0xff;
+ off += 4;
+ size -= 4;
+ }
+
+ while (size > 0) {
+ unsigned char val;
+ pci_read_config_byte(dev, off, &val);
+ buf[off] = val;
+ off++;
+ --size;
+ }
+
+ return count;
+}
+
+static ssize_t
+pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj));
+ unsigned int size = count;
+
+ if (off > 256)
+ return 0;
+ if (off + count > 256) {
+ size = 256 - off;
+ count = size;
+ }
+
+ while (off & 3) {
+ pci_write_config_byte(dev, off, buf[off]);
+ off++;
+ if (--size == 0)
+ break;
+ }
+
+ while (size > 3) {
+ unsigned int val = buf[off];
+ val |= (unsigned int) buf[off + 1] << 8;
+ val |= (unsigned int) buf[off + 2] << 16;
+ val |= (unsigned int) buf[off + 3] << 24;
+ pci_write_config_dword(dev, off, val);
+ off += 4;
+ size -= 4;
+ }
+
+ while (size > 0) {
+ pci_write_config_byte(dev, off, buf[off]);
+ off++;
+ --size;
+ }
+
+ return count;
+}
+
+static struct bin_attribute pci_config_attr = {
+ .attr = {
+ .name = "config",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .size = 256,
+ .read = pci_read_config,
+ .write = pci_write_config,
+};
+
void pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
struct device *dev = &pdev->dev;
@@ -72,4 +176,5 @@
device_create_file (dev, &dev_attr_class);
device_create_file (dev, &dev_attr_irq);
device_create_file (dev, &dev_attr_resource);
+ sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
}
diff -Nru a/fs/sysfs/bin.c b/fs/sysfs/bin.c
--- a/fs/sysfs/bin.c Thu Jul 3 18:16:32 2003
+++ b/fs/sysfs/bin.c Thu Jul 3 18:16:32 2003
@@ -42,18 +42,17 @@
ret = fill_read(dentry, buffer, offs, count);
if (ret < 0)
- goto Done;
+ return ret;
count = ret;
- ret = -EFAULT;
- if (copy_to_user(userbuf, buffer, count) != 0)
- goto Done;
+ if (copy_to_user(userbuf, buffer + offs, count) != 0)
+ return -EINVAL;
+
+ printk("offs = %lld, *off = %lld, count = %zd\n", offs, *off, count);
*off = offs + count;
- ret = count;
- Done:
- return ret;
+ return count;
}
static int
@@ -72,7 +71,6 @@
struct dentry *dentry = file->f_dentry;
int size = dentry->d_inode->i_size;
loff_t offs = *off;
- int ret;
if (count > PAGE_SIZE)
count = PAGE_SIZE;
@@ -83,16 +81,13 @@
count = size - offs;
}
- ret = -EFAULT;
- if (copy_from_user(buffer, userbuf, count))
- goto Done;
+ if (copy_from_user(buffer + offs, userbuf, count))
+ return -EFAULT;
count = flush_write(dentry, buffer, offs, count);
if (count > 0)
*off = offs + count;
- ret = count;
- Done:
- return ret;
+ return count;
}
static int open(struct inode * inode, struct file * file)
ChangeSet 1.1366, 2003/07/03 15:51:30-07:00, [email protected]
[PATCH] PCI: Remove pci_bus_exists
Convert all callers of pci_bus_exists() to call pci_find_bus() instead.
Since all callers of pci_find_bus() are __init or __devinit, mark it as
__devinit too.
arch/i386/pci/legacy.c | 2 +-
arch/sh/kernel/cpu/sh4/pci-sh7751.c | 2 +-
drivers/pci/probe.c | 13 +------------
drivers/pci/search.c | 5 +++--
include/linux/pci.h | 1 -
5 files changed, 6 insertions(+), 17 deletions(-)
diff -Nru a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c
--- a/arch/i386/pci/legacy.c Thu Jul 3 18:16:55 2003
+++ b/arch/i386/pci/legacy.c Thu Jul 3 18:16:55 2003
@@ -28,7 +28,7 @@
}
for (n=0; n <= pcibios_last_bus; n++) {
- if (pci_bus_exists(&pci_root_buses, n))
+ if (pci_find_bus(0, n))
continue;
bus->number = n;
bus->ops = &pci_root_ops;
diff -Nru a/arch/sh/kernel/cpu/sh4/pci-sh7751.c b/arch/sh/kernel/cpu/sh4/pci-sh7751.c
--- a/arch/sh/kernel/cpu/sh4/pci-sh7751.c Thu Jul 3 18:16:55 2003
+++ b/arch/sh/kernel/cpu/sh4/pci-sh7751.c Thu Jul 3 18:16:55 2003
@@ -200,7 +200,7 @@
return;
PCIDBG(2,"PCI: Peer bridge fixup\n");
for (n=0; n <= pcibios_last_bus; n++) {
- if (pci_bus_exists(&pci_root_buses, n))
+ if (pci_find_bus(0, n))
continue;
bus.number = n;
bus.ops = pci_root_ops;
diff -Nru a/drivers/pci/probe.c b/drivers/pci/probe.c
--- a/drivers/pci/probe.c Thu Jul 3 18:16:55 2003
+++ b/drivers/pci/probe.c Thu Jul 3 18:16:55 2003
@@ -633,22 +633,11 @@
return max;
}
-int __devinit pci_bus_exists(const struct list_head *list, int nr)
-{
- const struct pci_bus *b;
-
- list_for_each_entry(b, list, node) {
- if (b->number == nr || pci_bus_exists(&b->children, nr))
- return 1;
- }
- return 0;
-}
-
struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata)
{
struct pci_bus *b;
- if (pci_bus_exists(&pci_root_buses, bus)) {
+ if (pci_find_bus(0, bus)) {
/* If we already got to this bus through a different bridge, ignore it */
DBG("PCI: Bus %02x already known\n", bus);
return NULL;
diff -Nru a/drivers/pci/search.c b/drivers/pci/search.c
--- a/drivers/pci/search.c Thu Jul 3 18:16:55 2003
+++ b/drivers/pci/search.c Thu Jul 3 18:16:55 2003
@@ -7,13 +7,14 @@
* Copyright 2003 -- Greg Kroah-Hartman <[email protected]>
*/
+#include <linux/init.h>
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/interrupt.h>
spinlock_t pci_bus_lock = SPIN_LOCK_UNLOCKED;
-static struct pci_bus *
+static struct pci_bus * __devinit
pci_do_find_bus(struct pci_bus* bus, unsigned char busnr)
{
struct pci_bus* child;
@@ -39,7 +40,7 @@
* in the global list of PCI buses. If the bus is found, a pointer to its
* data structure is returned. If no bus is found, %NULL is returned.
*/
-struct pci_bus * pci_find_bus(int domain, int busnr)
+struct pci_bus * __devinit pci_find_bus(int domain, int busnr)
{
struct pci_bus *bus = NULL;
struct pci_bus *tmp_bus;
diff -Nru a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h Thu Jul 3 18:16:55 2003
+++ b/include/linux/pci.h Thu Jul 3 18:16:55 2003
@@ -544,7 +544,6 @@
/* Generic PCI functions used internally */
extern struct pci_bus *pci_find_bus(int domain, int busnr);
-int pci_bus_exists(const struct list_head *list, int nr);
struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata);
static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata)
{
ChangeSet 1.1372, 2003/07/03 16:28:49-07:00, [email protected]
[PATCH] SYSFS: add module referencing to sysfs attribute files.
fs/sysfs/file.c | 9 +++++++++
include/linux/device.h | 11 ++++++-----
include/linux/sysfs.h | 2 ++
3 files changed, 17 insertions(+), 5 deletions(-)
diff -Nru a/fs/sysfs/file.c b/fs/sysfs/file.c
--- a/fs/sysfs/file.c Thu Jul 3 18:16:03 2003
+++ b/fs/sysfs/file.c Thu Jul 3 18:16:03 2003
@@ -247,6 +247,12 @@
if (!kobj || !attr)
goto Einval;
+ /* Grab the module reference for this attribute if we have one */
+ if (!try_module_get(attr->owner)) {
+ error = -ENODEV;
+ goto Done;
+ }
+
/* if the kobject has no ktype, then we assume that it is a subsystem
* itself, and use ops for it.
*/
@@ -300,6 +306,7 @@
goto Done;
Eaccess:
error = -EACCES;
+ module_put(attr->owner);
Done:
if (error && kobj)
kobject_put(kobj);
@@ -314,10 +321,12 @@
static int sysfs_release(struct inode * inode, struct file * filp)
{
struct kobject * kobj = filp->f_dentry->d_parent->d_fsdata;
+ struct attribute * attr = filp->f_dentry->d_fsdata;
struct sysfs_buffer * buffer = filp->private_data;
if (kobj)
kobject_put(kobj);
+ module_put(attr->owner);
if (buffer) {
if (buffer->page)
diff -Nru a/include/linux/device.h b/include/linux/device.h
--- a/include/linux/device.h Thu Jul 3 18:16:03 2003
+++ b/include/linux/device.h Thu Jul 3 18:16:03 2003
@@ -18,6 +18,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/ioport.h>
+#include <linux/module.h>
#include <asm/semaphore.h>
#include <asm/atomic.h>
@@ -95,7 +96,7 @@
#define BUS_ATTR(_name,_mode,_show,_store) \
struct bus_attribute bus_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
@@ -136,7 +137,7 @@
#define DRIVER_ATTR(_name,_mode,_show,_store) \
struct driver_attribute driver_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
@@ -176,7 +177,7 @@
#define CLASS_ATTR(_name,_mode,_show,_store) \
struct class_attribute class_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
@@ -226,7 +227,7 @@
#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \
struct class_device_attribute class_device_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
@@ -324,7 +325,7 @@
#define DEVICE_ATTR(_name,_mode,_show,_store) \
struct device_attribute dev_attr_##_name = { \
- .attr = {.name = __stringify(_name), .mode = _mode }, \
+ .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \
.show = _show, \
.store = _store, \
};
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h Thu Jul 3 18:16:03 2003
+++ b/include/linux/sysfs.h Thu Jul 3 18:16:03 2003
@@ -10,9 +10,11 @@
#define _SYSFS_H_
struct kobject;
+struct module;
struct attribute {
char * name;
+ struct module * owner;
mode_t mode;
};
ChangeSet 1.1374, 2003/07/03 17:43:18-07:00, [email protected]
[PATCH] sysfs: add sysfs_rename_dir()
Based on a patch written by Dan Aloni <[email protected]>
fs/sysfs/dir.c | 22 ++++++++++++++++++++++
include/linux/sysfs.h | 3 +++
2 files changed, 25 insertions(+)
diff -Nru a/fs/sysfs/dir.c b/fs/sysfs/dir.c
--- a/fs/sysfs/dir.c Thu Jul 3 18:15:51 2003
+++ b/fs/sysfs/dir.c Thu Jul 3 18:15:51 2003
@@ -121,7 +121,29 @@
dput(parent);
}
+void sysfs_rename_dir(struct kobject * kobj, char *new_name)
+{
+ struct dentry * new_dentry, * parent;
+
+ if (!strcmp(kobj->name, new_name))
+ return;
+
+ if (!kobj->parent)
+ return;
+
+ parent = kobj->parent->dentry;
+
+ down(&parent->d_inode->i_sem);
+
+ new_dentry = sysfs_get_dentry(parent, new_name);
+ d_move(kobj->dentry, new_dentry);
+
+ strlcpy(kobj->name, new_name, KOBJ_NAME_LEN);
+
+ up(&parent->d_inode->i_sem);
+}
EXPORT_SYMBOL(sysfs_create_dir);
EXPORT_SYMBOL(sysfs_remove_dir);
+EXPORT_SYMBOL(sysfs_rename_dir);
diff -Nru a/include/linux/sysfs.h b/include/linux/sysfs.h
--- a/include/linux/sysfs.h Thu Jul 3 18:15:51 2003
+++ b/include/linux/sysfs.h Thu Jul 3 18:15:51 2003
@@ -39,6 +39,9 @@
extern void
sysfs_remove_dir(struct kobject *);
+extern void
+sysfs_rename_dir(struct kobject *, char *new_name);
+
extern int
sysfs_create_file(struct kobject *, struct attribute *);
ChangeSet 1.1363, 2003/07/03 15:50:39-07:00, [email protected]
[PATCH] PCI: Improve documentation
Fix some grammar problems
Add a note about Fast Back to Back support
Change the slot_name recommendation to pci_name().
Documentation/pci.txt | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff -Nru a/Documentation/pci.txt b/Documentation/pci.txt
--- a/Documentation/pci.txt Thu Jul 3 18:17:12 2003
+++ b/Documentation/pci.txt Thu Jul 3 18:17:12 2003
@@ -7,14 +7,14 @@
Different PCI devices have different requirements and different bugs --
because of this, the PCI support layer in Linux kernel is not as trivial
as one would wish. This short pamphlet tries to help all potential driver
-authors to find their way through the deep forests of PCI handling.
+authors find their way through the deep forests of PCI handling.
0. Structure of PCI drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~
There exist two kinds of PCI drivers: new-style ones (which leave most of
probing for devices to the PCI layer and support online insertion and removal
-of devices [thus supporting PCI, hot-pluggable PCI and CardBus in single
+of devices [thus supporting PCI, hot-pluggable PCI and CardBus in a single
driver]) and old-style ones which just do all the probing themselves. Unless
you have a very good reason to do so, please don't use the old way of probing
in any new code. After the driver finds the devices it wishes to operate
@@ -174,7 +174,7 @@
the latency timer value if it's set to something bogus by the BIOS.
If you want to use the PCI Memory-Write-Invalidate transaction,
-call pci_set_mwi(). This enables bit PCI_COMMAND bit for Mem-Wr-Inval
+call pci_set_mwi(). This enables the PCI_COMMAND bit for Mem-Wr-Inval
and also ensures that the cache line size register is set correctly.
Make sure to check the return value of pci_set_mwi(), not all architectures
may support Memory-Write-Invalidate.
@@ -236,7 +236,7 @@
7. Miscellaneous hints
~~~~~~~~~~~~~~~~~~~~~~
When displaying PCI slot names to the user (for example when a driver wants
-to tell the user what card has it found), please use pci_dev->slot_name
+to tell the user what card has it found), please use pci_name(pci_dev)
for this purpose.
Always refer to the PCI devices by a pointer to the pci_dev structure.
@@ -247,6 +247,10 @@
If you're going to use PCI bus mastering DMA, take a look at
Documentation/DMA-mapping.txt.
+
+Don't try to turn on Fast Back to Back writes in your driver. All devices
+on the bus need to be capable of doing it, so this is something which needs
+to be handled by platform and generic code, not individual drivers.
8. Obsolete functions
On Thu, Jul 03, 2003 at 07:06:34PM -0700, Greg KH wrote:
> Hi,
>
> Here's some PCI and sysfs fixes that are against the latest 2.5.74 bk
> tree. They include Matthew Wilcox's set of pci cleanups, and sysfs
> fixes for binary files. That led into my sysfs attribute file change,
> which required John Stultz's timer build fix. I've also added the
> sysfs/kobject/class rename patches based on previously posted patches.
That's good, but I see that you didn't add the call to class_device_rename()
in net/core/dev.c, and that's kinda misses the point ;)
--- linux/net/core/dev.c 2003-06-29 22:16:29.000000000 +0300
+++ linux/net/core/dev.c 2003-06-30 20:57:55.000000000 +0300
@@ -2346,10 +2346,14 @@
return -EEXIST;
memcpy(dev->name, ifr->ifr_newname, IFNAMSIZ);
dev->name[IFNAMSIZ - 1] = 0;
- strlcpy(dev->class_dev.class_id, dev->name, BUS_ID_SIZE);
+
+ err = class_device_rename(&dev->class_dev, dev->name);
+ if (err)
+ printk(KERN_DEBUG "SIOCSIFNAME: error renaming class_device (%d)\n", err);
+
notifier_call_chain(&netdev_chain,
NETDEV_CHANGENAME, dev);
- return 0;
+ return err;
/*
* Unknown or private ioctl
--
Dan Aloni
[email protected]
On Fri, Jul 04, 2003 at 09:52:17AM +0300, Dan Aloni wrote:
> On Thu, Jul 03, 2003 at 07:06:34PM -0700, Greg KH wrote:
> > Hi,
> >
> > Here's some PCI and sysfs fixes that are against the latest 2.5.74 bk
> > tree. They include Matthew Wilcox's set of pci cleanups, and sysfs
> > fixes for binary files. That led into my sysfs attribute file change,
> > which required John Stultz's timer build fix. I've also added the
> > sysfs/kobject/class rename patches based on previously posted patches.
>
> That's good, but I see that you didn't add the call to class_device_rename()
> in net/core/dev.c, and that's kinda misses the point ;)
No, I did that on purpose, send this to David Miller, he's the network
maintainer.
thanks,
greg k-h