Commit 3935761c authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/gregkh/linux/pci-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 65458f96 c1cdc0d2
......@@ -204,7 +204,7 @@ GENKSYMS = scripts/genksyms/genksyms
DEPMOD = /sbin/depmod
KALLSYMS = scripts/kallsyms
PERL = perl
CHECK = /home/torvalds/parser/check
CHECK = sparse
MODFLAGS = -DMODULE
CFLAGS_MODULE = $(MODFLAGS)
AFLAGS_MODULE = $(MODFLAGS)
......
......@@ -11,7 +11,6 @@
#include <linux/config.h>
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <asm/leds.h>
#include <asm/system.h>
......@@ -66,13 +65,6 @@ int suspend(void)
*/
device_resume(RESUME_POWER_ON);
/*
* Restore the CPU frequency settings.
*/
#ifdef CONFIG_CPU_FREQ
cpufreq_restore();
#endif
/*
* Resume LDM devices.
*/
......
......@@ -25,6 +25,9 @@
#include <linux/interrupt.h>
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/sysdev.h>
#include <linux/module.h>
#include <asm/atomic.h>
#include <asm/smp.h>
......@@ -460,9 +463,6 @@ void __init setup_local_APIC (void)
#ifdef CONFIG_PM
#include <linux/device.h>
#include <linux/module.h>
static struct {
/* 'active' is true if the local APIC was enabled by us and
not the BIOS; this signifies that we are also responsible
......@@ -484,13 +484,11 @@ static struct {
unsigned int apic_thmr;
} apic_pm_state;
static int lapic_suspend(struct device *dev, u32 state, u32 level)
static int lapic_suspend(struct sys_device *dev, u32 state)
{
unsigned int l, h;
unsigned long flags;
if (level != SUSPEND_POWER_DOWN)
return 0;
if (!apic_pm_state.active)
return 0;
......@@ -517,13 +515,11 @@ static int lapic_suspend(struct device *dev, u32 state, u32 level)
return 0;
}
static int lapic_resume(struct device *dev, u32 level)
static int lapic_resume(struct sys_device *dev)
{
unsigned int l, h;
unsigned long flags;
if (level != RESUME_POWER_ON)
return 0;
if (!apic_pm_state.active)
return 0;
......@@ -557,38 +553,37 @@ static int lapic_resume(struct device *dev, u32 level)
return 0;
}
static struct device_driver lapic_driver = {
.name = "lapic",
.bus = &system_bus_type,
static struct sysdev_class lapic_sysclass = {
set_kset_name("lapic"),
.resume = lapic_resume,
.suspend = lapic_suspend,
};
/* not static, needed by child devices */
struct sys_device device_lapic = {
.name = "lapic",
.id = 0,
.dev = {
.name = "lapic",
.driver = &lapic_driver,
},
static struct sys_device device_lapic = {
.id = 0,
.cls = &lapic_sysclass,
};
EXPORT_SYMBOL(device_lapic);
static void __init apic_pm_activate(void)
{
apic_pm_state.active = 1;
}
static int __init init_lapic_devicefs(void)
static int __init init_lapic_sysfs(void)
{
int error;
if (!cpu_has_apic)
return 0;
/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
driver_register(&lapic_driver);
return sys_device_register(&device_lapic);
error = sysdev_class_register(&lapic_sysclass);
if (!error)
error = sys_device_register(&device_lapic);
return error;
}
device_initcall(init_lapic_devicefs);
device_initcall(init_lapic_sysfs);
#else /* CONFIG_PM */
......
......@@ -35,6 +35,7 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/cpu.h>
#include <asm/mtrr.h>
......@@ -546,6 +547,58 @@ static void init_other_cpus(void)
}
}
struct mtrr_value {
mtrr_type ltype;
unsigned long lbase;
unsigned int lsize;
};
static struct mtrr_value * mtrr_state;
static int mtrr_save(struct sys_device * sysdev, u32 state)
{
int i;
int size = num_var_ranges * sizeof(struct mtrr_value);
mtrr_state = kmalloc(size,GFP_KERNEL);
if (mtrr_state)
memset(mtrr_state,0,size);
else
return -ENOMEM;
for (i = 0; i < num_var_ranges; i++) {
mtrr_if->get(i,
&mtrr_state[i].lbase,
&mtrr_state[i].lsize,
&mtrr_state[i].ltype);
}
return 0;
}
static int mtrr_restore(struct sys_device * sysdev)
{
int i;
for (i = 0; i < num_var_ranges; i++) {
if (mtrr_state[i].lsize)
set_mtrr(i,
mtrr_state[i].lbase,
mtrr_state[i].lsize,
mtrr_state[i].ltype);
}
kfree(mtrr_state);
return 0;
}
static struct sysdev_driver mtrr_sysdev_driver = {
.save = mtrr_save,
.restore = mtrr_restore,
};
/**
* mtrr_init - initialie mtrrs on the boot CPU
*
......@@ -630,8 +683,11 @@ static int __init mtrr_init(void)
set_num_var_ranges();
init_table();
init_other_cpus();
return sysdev_driver_register(&cpu_sysdev_class,
&mtrr_sysdev_driver);
}
return mtrr_if ? -ENXIO : 0;
return -ENXIO;
}
char *mtrr_strings[MTRR_NUM_TYPES] =
......@@ -645,5 +701,5 @@ char *mtrr_strings[MTRR_NUM_TYPES] =
"write-back", /* 6 */
};
core_initcall(mtrr_init);
subsys_initcall(mtrr_init);
......@@ -10,7 +10,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <asm/atomic.h>
#include <asm/system.h>
......@@ -238,35 +238,31 @@ void mask_and_ack_8259A(unsigned int irq)
}
}
static int i8259A_resume(struct device *dev, u32 level)
static int i8259A_resume(struct sys_device *dev)
{
if (level == RESUME_POWER_ON)
init_8259A(0);
init_8259A(0);
return 0;
}
static struct device_driver i8259A_driver = {
.name = "pic",
.bus = &system_bus_type,
.resume = i8259A_resume,
static struct sysdev_class i8259_sysdev_class = {
set_kset_name("i8259"),
.resume = i8259A_resume,
};
static struct sys_device device_i8259A = {
.name = "pic",
.id = 0,
.dev = {
.name = "i8259A PIC",
.driver = &i8259A_driver,
},
.id = 0,
.cls = &i8259_sysdev_class,
};
static int __init init_8259A_devicefs(void)
static int __init i8259A_init_sysfs(void)
{
driver_register(&i8259A_driver);
return sys_device_register(&device_i8259A);
int error = sysdev_class_register(&i8259_sysdev_class);
if (!error)
error = sys_device_register(&device_i8259A);
return error;
}
device_initcall(init_8259A_devicefs);
device_initcall(i8259A_init_sysfs);
void init_8259A(int auto_eoi)
{
......@@ -385,35 +381,31 @@ static void setup_timer(void)
spin_unlock_irqrestore(&i8253_lock, flags);
}
static int timer_resume(struct device *dev, u32 level)
static int timer_resume(struct sys_device *dev)
{
if (level == RESUME_POWER_ON)
setup_timer();
setup_timer();
return 0;
}
static struct device_driver timer_driver = {
.name = "timer",
.bus = &system_bus_type,
.resume = timer_resume,
static struct sysdev_class timer_sysclass = {
set_kset_name("timer"),
.resume = timer_resume,
};
static struct sys_device device_timer = {
.name = "timer",
.id = 0,
.dev = {
.name = "timer",
.driver = &timer_driver,
},
.id = 0,
.cls = &timer_sysclass,
};
static int __init init_timer_devicefs(void)
static int __init init_timer_sysfs(void)
{
driver_register(&timer_driver);
return sys_device_register(&device_timer);
int error = sysdev_class_register(&timer_sysclass);
if (!error)
error = sys_device_register(&device_timer);
return error;
}
device_initcall(init_timer_devicefs);
device_initcall(init_timer_sysfs);
void __init init_IRQ(void)
{
......
......@@ -23,6 +23,7 @@
#include <linux/mc146818rtc.h>
#include <linux/kernel_stat.h>
#include <linux/module.h>
#include <linux/sysdev.h>
#include <asm/smp.h>
#include <asm/mtrr.h>
......@@ -180,53 +181,48 @@ void enable_lapic_nmi_watchdog(void)
#ifdef CONFIG_PM
#include <linux/device.h>
static int nmi_pm_active; /* nmi_active before suspend */
static int lapic_nmi_suspend(struct device *dev, u32 state, u32 level)
static int lapic_nmi_suspend(struct sys_device *dev, u32 state)
{
if (level != SUSPEND_POWER_DOWN)
return 0;
nmi_pm_active = nmi_active;
disable_lapic_nmi_watchdog();
return 0;
}
static int lapic_nmi_resume(struct device *dev, u32 level)
static int lapic_nmi_resume(struct sys_device *dev)
{
if (level != RESUME_POWER_ON)
return 0;
if (nmi_pm_active > 0)
enable_lapic_nmi_watchdog();
return 0;
}
static struct device_driver lapic_nmi_driver = {
.name = "lapic_nmi",
.bus = &system_bus_type,
static struct sysdev_class nmi_sysclass = {
set_kset_name("lapic_nmi"),
.resume = lapic_nmi_resume,
.suspend = lapic_nmi_suspend,
};
static struct sys_device device_lapic_nmi = {
.name = "lapic_nmi",
.id = 0,
.dev = {
.name = "lapic_nmi",
.driver = &lapic_nmi_driver,
.parent = &device_lapic.dev,
},
.id = 0,
.cls = &nmi_sysclass,
};
static int __init init_lapic_nmi_devicefs(void)
static int __init init_lapic_nmi_sysfs(void)
{
int error;
if (nmi_active == 0)
return 0;
driver_register(&lapic_nmi_driver);
return sys_device_register(&device_lapic_nmi);
error = sysdev_class_register(&nmi_sysclass);
if (!error)
error = sys_device_register(&device_lapic_nmi);
return error;
}
/* must come after the local APIC's device_initcall() */
late_initcall(init_lapic_nmi_devicefs);
late_initcall(init_lapic_nmi_sysfs);
#endif /* CONFIG_PM */
......
......@@ -42,7 +42,7 @@
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/bcd.h>
#include <asm/io.h>
......@@ -278,18 +278,22 @@ unsigned long get_cmos_time(void)
return retval;
}
static struct sysdev_class rtc_sysclass = {
set_kset_name("rtc"),
};
/* XXX this driverfs stuff should probably go elsewhere later -john */
static struct sys_device device_i8253 = {
.name = "rtc",
.id = 0,
.dev = {
.name = "i8253 Real Time Clock",
},
.cls = &rtc_sysclass,
};
static int time_init_device(void)
{
return sys_device_register(&device_i8253);
int error = sysdev_class_register(&rtc_sysclass);
if (!error)
error = sys_device_register(&device_i8253);
return error;
}
device_initcall(time_init_device);
......
......@@ -11,7 +11,7 @@
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/oprofile.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
......@@ -31,53 +31,48 @@ static int nmi_enabled = 0;
#ifdef CONFIG_PM
static int nmi_suspend(struct device *dev, u32 state, u32 level)
static int nmi_suspend(struct sys_device *dev, u32 state)
{
if (level != SUSPEND_POWER_DOWN)
return 0;
if (nmi_enabled == 1)
nmi_stop();
return 0;
}
static int nmi_resume(struct device *dev, u32 level)
static int nmi_resume(struct sys_device *dev)
{
if (level != RESUME_POWER_ON)
return 0;
if (nmi_enabled == 1)
nmi_start();
return 0;
}
static struct device_driver nmi_driver = {
.name = "oprofile",
.bus = &system_bus_type,
static struct sysdev_class oprofile_sysclass = {
set_kset_name("oprofile"),
.resume = nmi_resume,
.suspend = nmi_suspend,
};
static struct device device_nmi = {
.name = "oprofile",
.bus_id = "oprofile",
.driver = &nmi_driver,
.parent = &device_lapic.dev,
static struct sys_device device_oprofile = {
.id = 0,
.cls = &oprofile_sysclass,
};
static int __init init_driverfs(void)
{
driver_register(&nmi_driver);
return device_register(&device_nmi);
int error;
if (!(error = sysdev_class_register(&oprofile_sysclass)))
error = sys_device_register(&device_oprofile);
return error;
}
static void __exit exit_driverfs(void)
{
device_unregister(&device_nmi);
driver_unregister(&nmi_driver);
sys_device_unregister(&device_oprofile);
sysdev_class_unregister(&oprofile_sysclass);
}
#else
......
......@@ -11,7 +11,7 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/device.h>
#include <linux/sysdev.h>
#include <asm/atomic.h>
#include <asm/system.h>
......@@ -413,35 +413,31 @@ static void setup_timer(void)
outb(LATCH >> 8 , 0x40); /* MSB */
}
static int timer_resume(struct device *dev, u32 level)
static int timer_resume(struct sys_device *dev)
{
if (level == RESUME_POWER_ON)
setup_timer();
setup_timer();
return 0;
}
static struct device_driver timer_driver = {
.name = "timer",
.bus = &system_bus_type,
static struct sysdev_class timer_sysclass = {
set_kset_name("timer"),
.resume = timer_resume,
};
static struct sys_device device_timer = {
.name = "timer",
.id = 0,
.dev = {
.name = "timer",
.driver = &timer_driver,
},
.cls &timer_sysclass,
};
static int __init init_timer_devicefs(void)
static int __init init_timer_sysfs(void)
{
driver_register(&timer_driver);
return sys_device_register(&device_timer);
int error = sysdev_class_register(&timer_sysclass);
if (!error)
error = sys_device_register(&device_timer);
return error;
}
device_initcall(init_timer_devicefs);
device_initcall(init_timer_sysfs);
void __init init_IRQ(void)
{
......
......@@ -2,23 +2,18 @@
* drivers/base/cpu.c - basic CPU class support
*/
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/cpu.h>
#include <linux/topology.h>
struct class cpu_class = {
.name = "cpu",
struct sysdev_class cpu_sysdev_class = {
set_kset_name("cpu"),
};
struct device_driver cpu_driver = {
.name = "cpu",
.bus = &system_bus_type,
};
/*
* register_cpu - Setup a driverfs device for a CPU.
* @num - CPU number to use when creating the device.
......@@ -27,42 +22,15 @@ struct device_driver cpu_driver = {
*/
int __init register_cpu(struct cpu *cpu, int num, struct node *root)
{
int retval;
cpu->node_id = cpu_to_node(num);
cpu->sysdev.name = "cpu";
cpu->sysdev.id = num;
if (root)
cpu->sysdev.root = &root->sysroot;
snprintf(cpu->sysdev.dev.name, DEVICE_NAME_SIZE, "CPU %u", num);
cpu->sysdev.dev.driver = &cpu_driver;
retval = sys_device_register(&cpu->sysdev);
if (retval)
return retval;
memset(&cpu->sysdev.class_dev, 0x00, sizeof(struct class_device));
cpu->sysdev.class_dev.dev = &cpu->sysdev.dev;
cpu->sysdev.class_dev.class = &cpu_class;
snprintf(cpu->sysdev.class_dev.class_id, BUS_ID_SIZE, "cpu%d", num);
retval = class_device_register(&cpu->sysdev.class_dev);
if (retval) {
sys_device_unregister(&cpu->sysdev);
return retval;
}
return 0;
cpu->sysdev.cls = &cpu_sysdev_class;
return sys_device_register(&cpu->sysdev);
}
int __init cpu_dev_init(void)
{
int error;
error = class_register(&cpu_class);
if (error)
goto out;
error = driver_register(&cpu_driver);
if (error)
class_unregister(&cpu_class);
out:
return error;
return sysdev_class_register(&cpu_sysdev_class);
}
......@@ -2,7 +2,6 @@
* drivers/base/memblk.c - basic Memory Block class support
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/memblk.h>
......@@ -10,8 +9,8 @@
#include <linux/topology.h>
static struct class memblk_class = {
.name = "memblk",
static struct sysdev_class memblk_class = {
set_kset_name("memblk"),
};
......@@ -29,27 +28,23 @@ static struct device_driver memblk_driver = {
*/
int __init register_memblk(struct memblk *memblk, int num, struct node *root)
{
int error;
memblk->node_id = memblk_to_node(num);
memblk->sysdev.name = "memblk";
memblk->sysdev.cls = &memblk_class,
memblk->sysdev.id = num;
if (root)
memblk->sysdev.root = &root->sysroot;
snprintf(memblk->sysdev.dev.name, DEVICE_NAME_SIZE, "Memory Block %u", num);
memblk->sysdev.dev.driver = &memblk_driver;
return sys_device_register(&memblk->sysdev);
error = sys_device_register(&memblk->sysdev);
if (!error)
error = sysfs_create_link(&root->sysdev.kobj,
&memblk->sysdev,kobj,
memblk->sysdev.kobj.name);
return error;
}
int __init register_memblk_type(void)
{
int error;
error = class_register(&memblk_class);
if (!error) {
error = driver_register(&memblk_driver);
if (error)
class_unregister(&memblk_class);
}
return error;
return sysdev_class_register(&memblk_class);
}
postcore_initcall(register_memblk_type);
......@@ -9,15 +9,8 @@
#include <linux/node.h>
#include <linux/topology.h>
static struct class node_class = {
.name = "node",
};
static struct device_driver node_driver = {
.name = "node",
.bus = &system_bus_type,
static struct sysdev_class node_class = {
set_kset_name("node"),
};
......@@ -26,7 +19,7 @@ static ssize_t node_read_cpumap(struct device * dev, char * buf)
struct node *node_dev = to_node(to_root(dev));
return sprintf(buf,"%lx\n",node_dev->cpumap);
}
static DEVICE_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
static SYSDEV_ATTR(cpumap,S_IRUGO,node_read_cpumap,NULL);
#define K(x) ((x) << (PAGE_SHIFT - 10))
static ssize_t node_read_meminfo(struct device * dev, char * buf)
......@@ -52,7 +45,7 @@ static ssize_t node_read_meminfo(struct device * dev, char * buf)
nid, K(i.freeram-i.freehigh));
}
#undef K
static DEVICE_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
static SYSDEV_ATTR(meminfo,S_IRUGO,node_read_meminfo,NULL);
/*
......@@ -66,17 +59,13 @@ int __init register_node(struct node *node, int num, struct node *parent)
int error;
node->cpumap = node_to_cpumask(num);
node->sysroot.id = num;
if (parent)
node->sysroot.dev.parent = &parent->sysroot.sysdev;
snprintf(node->sysroot.dev.name, DEVICE_NAME_SIZE, "Node %u", num);
snprintf(node->sysroot.dev.bus_id, BUS_ID_SIZE, "node%u", num);
node->sysroot.dev.driver = &node_driver;
node->sysroot.dev.bus = &system_bus_type;
error = sys_register_root(&node->sysroot);
node->sysdev.id = num;
node->sysdev.cls = &node_class;
error = sys_device_register(&node->sysdev);
if (!error){
device_create_file(&node->sysroot.dev, &dev_attr_cpumap);
device_create_file(&node->sysroot.dev, &dev_attr_meminfo);
sys_device_create_file(&node->sysroot.dev, &attr_cpumap);
sys_device_create_file(&node->sysroot.dev, &attr_meminfo);
}
return error;
}
......@@ -84,14 +73,6 @@ int __init register_node(struct node *node, int num, struct node *parent)
int __init register_node_type(void)
{
int error;
error = class_register(&node_class);
if (!error) {
error = driver_register(&node_driver);
if (error)
class_unregister(&node_class);
}
return error;
return sysdev_class_register(&node_class);
}
postcore_initcall(register_node_type);
......@@ -21,6 +21,21 @@
extern struct subsystem devices_subsys;
/**
* We handle system devices differently - we suspend and shut them
* down first and resume them first. That way, we do anything stupid like
* shutting down the interrupt controller before any devices..
*
* Note that there are not different stages for power management calls -
* they only get one called once when interrupts are disabled.
*/
extern int sysdev_shutdown(void);
extern int sysdev_save(u32 state);
extern int sysdev_suspend(u32 state);
extern int sysdev_resume(void);
extern int sysdev_restore(void);
/**
* device_suspend - suspend/remove all devices on the device ree
* @state: state we're entering
......@@ -50,6 +65,21 @@ int device_suspend(u32 state, u32 level)
}
}
up_write(&devices_subsys.rwsem);
/*
* Make sure system devices are suspended.
*/
switch(level) {
case SUSPEND_SAVE_STATE:
sysdev_save(state);
break;
case SUSPEND_POWER_DOWN:
sysdev_suspend(state);
break;
default:
break;
}
return error;
}
......@@ -65,6 +95,17 @@ void device_resume(u32 level)
{
struct list_head * node;
switch (level) {
case RESUME_POWER_ON:
sysdev_resume();
break;
case RESUME_RESTORE_STATE:
sysdev_restore();
break;
default:
break;
}
down_write(&devices_subsys.rwsem);
list_for_each_prev(node,&devices_subsys.kset.list) {
struct device * dev = to_dev(node);
......@@ -98,6 +139,8 @@ void device_shutdown(void)
pr_debug("Ignored.\n");
}
up_write(&devices_subsys.rwsem);
sysdev_shutdown();
}
EXPORT_SYMBOL(device_suspend);
......
This diff is collapsed.
......@@ -34,7 +34,7 @@
#include <linux/blk.h>
#include <linux/blkpg.h>
#include <linux/hdreg.h> /* HDIO_GETGEO */
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/bio.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/uaccess.h>
......@@ -48,12 +48,14 @@
#define PRINT_WARN(x...) printk(KERN_WARNING XPRAM_NAME " warning:" x)
#define PRINT_ERR(x...) printk(KERN_ERR XPRAM_NAME " error:" x)
static struct sysdev_class xpram_sysclass = {
set_kset_name("xpram"),
};
static struct sys_device xpram_sys_device = {
.name = "S/390 expanded memory RAM disk",
.dev = {
.name = "S/390 expanded memory RAM disk",
.bus_id = "xpram",
},
.id = 0,
.cls = &xpram_sysclass,
};
typedef struct {
......@@ -485,6 +487,7 @@ static void __exit xpram_exit(void)
unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
devfs_remove("slram");
sys_device_unregister(&xpram_sys_device);
sysdev_class_unregister(&xpram_sys_class);
}
static int __init xpram_init(void)
......@@ -502,9 +505,15 @@ static int __init xpram_init(void)
rc = xpram_setup_sizes(xpram_pages);
if (rc)
return rc;
rc = sys_device_register(&xpram_sys_device);
rc = sysdev_class_register(&xpram_sysclass);
if (rc)
return rc;
rc = sys_device_register(&xpram_sys_device);
if (rc) {
sysdev_class_unregister(&xpram_syclass);
return rc;
}
rc = xpram_setup_blkdev();
if (rc)
sys_device_unregister(&xpram_sys_device);
......
......@@ -444,7 +444,7 @@ static char *usb_dump_string(char *start, char *end, const struct usb_device *de
* skip_bytes - the number of bytes to skip before writing anything
* file_offset - the offset into the devices file on completion
*/
static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
{
int chix;
......@@ -554,7 +554,7 @@ static ssize_t usb_device_dump(char **buffer, size_t *nbytes, loff_t *skip_bytes
return total_written;
}
static ssize_t usb_device_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
struct list_head *buslist;
struct usb_bus *bus;
......
This diff is collapsed.
This diff is collapsed.
......@@ -174,7 +174,12 @@ struct usb_hub {
struct urb *urb; /* for interrupt polling pipe */
/* buffer for urb ... 1 bit each for hub and children, rounded up */
char buffer[(USB_MAXCHILDREN + 1 + 7) / 8];
char (*buffer)[(USB_MAXCHILDREN + 1 + 7) / 8];
dma_addr_t buffer_dma; /* DMA address for buffer */
union {
struct usb_hub_status hub;
struct usb_port_status port;
} *status; /* buffer for status reports */
int error; /* last reported error */
int nerrors; /* track consecutive errors */
......
......@@ -282,13 +282,13 @@ static int usbfs_rmdir(struct inode *dir, struct dentry *dentry)
/* default file operations */
static ssize_t default_read_file (struct file *file, char *buf,
static ssize_t default_read_file (struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
return 0;
}
static ssize_t default_write_file (struct file *file, const char *buf,
static ssize_t default_write_file (struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
return count;
......
......@@ -20,10 +20,12 @@
* short OUT transfers happen.) Drivers can use the req->no_interrupt
* hint to completely eliminate some IRQs, if a later IRQ is guaranteed
* and DMA chaining is enabled.
*
* Note that almost all the errata workarounds here are only needed for
* rev1 chips. Rev1a silicon (0110) fixes almost all of them.
*/
// #define NET2280_DMA_OUT_WORKAROUND
// #define USE_DMA_CHAINING
#define USE_DMA_CHAINING
/*
......@@ -180,6 +182,13 @@ net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
* kicking in the "toggle-irrelevant" mode.
*/
tmp = USB_ENDPOINT_XFER_BULK;
} else if (tmp == USB_ENDPOINT_XFER_BULK) {
/* catch some particularly blatant driver bugs */
if ((dev->gadget.speed == USB_SPEED_HIGH
&& max != 512)
|| (dev->gadget.speed == USB_SPEED_FULL
&& max > 64))
return -ERANGE;
}
ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0;
tmp <<= ENDPOINT_TYPE;
......@@ -252,9 +261,6 @@ static int handshake (u32 *ptr, u32 mask, u32 done, int usec)
udelay (1);
usec--;
} while (usec > 0);
#ifdef DEBUG
if (done == 0) dump_stack (); /* ignore out_flush timeout */
#endif
return -ETIMEDOUT;
}
......@@ -917,6 +923,8 @@ net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
*/
if (read_fifo (ep, req)) {
done (ep, req, 0);
if (ep->num == 0)
allow_status (ep);
/* don't queue it */
req = 0;
} else
......@@ -1194,9 +1202,12 @@ net2280_set_halt (struct usb_ep *_ep, int value)
VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
/* set/clear, then synch memory views with the device */
if (value)
set_halt (ep);
else
if (value) {
if (ep->num == 0)
ep->dev->protocol_stall = 1;
else
set_halt (ep);
} else
clear_halt (ep);
(void) readl (&ep->regs->ep_rsp);
......@@ -2042,7 +2053,8 @@ static void handle_ep_small (struct net2280_ep *ep)
* can decide to stall ep0 after that done() returns,
* from non-irq context
*/
allow_status (ep);
if (!ep->stopped)
allow_status (ep);
req = 0;
} else {
if (!list_empty (&ep->queue) && !ep->stopped)
......
......@@ -377,12 +377,8 @@ static struct ed *ed_get (
ed->type = type;
}
/* FIXME: Don't do this without knowing it's safe to clobber this
* state/mode info. Currently the upper layers don't support such
* guarantees; we're lucky changing config/altsetting is rare.
* The state/mode info also changes during enumeration: set_address
* uses the 'wrong' device address, and ep0 maxpacketsize will often
* improve on the initial value.
/* NOTE: only ep0 currently needs this "re"init logic, during
* enumeration (after set_address, or if ep0 maxpacket >8).
*/
if (ed->state == ED_IDLE) {
u32 info;
......
......@@ -45,7 +45,7 @@ hpusbscsi_usb_probe(struct usb_interface *intf,
struct usb_host_interface *altsetting = intf->altsetting;
struct hpusbscsi *new;
int error = -ENOMEM;
int i, result;
int i;
if (altsetting->desc.bNumEndpoints != 3) {
printk (KERN_ERR "Wrong number of endpoints\n");
......
......@@ -1101,6 +1101,52 @@ static int vicam_read_proc_gain(char *page, char **start, off_t off,
((struct vicam_camera *)data)->gain);
}
static int
vicam_write_proc_shutter(struct file *file, const char *buffer,
unsigned long count, void *data)
{
u16 stmp;
char kbuf[8];
struct vicam_camera *cam = (struct vicam_camera *) data;
if (count > 6)
return -EINVAL;
if (copy_from_user(kbuf, buffer, count))
return -EFAULT;
stmp = (u16) simple_strtoul(kbuf, NULL, 10);
if (stmp < 4 || stmp > 32000)
return -EINVAL;
cam->shutter_speed = stmp;
return count;
}
static int
vicam_write_proc_gain(struct file *file, const char *buffer,
unsigned long count, void *data)
{
u16 gtmp;
char kbuf[8];
struct vicam_camera *cam = (struct vicam_camera *) data;
if (count > 4)
return -EINVAL;
if (copy_from_user(kbuf, buffer, count))
return -EFAULT;
gtmp = (u16) simple_strtoul(kbuf, NULL, 10);
if (gtmp > 255)
return -EINVAL;
cam->gain = gtmp;
return count;
}
static void
vicam_create_proc_root(void)
{
......@@ -1142,18 +1188,21 @@ vicam_create_proc_entry(struct vicam_camera *cam)
if ( !cam->proc_dir )
return; // FIXME: We should probably return an error here
ent =
create_proc_entry("shutter", S_IFREG | S_IRUGO, cam->proc_dir);
ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
cam->proc_dir);
if (ent) {
ent->data = cam;
ent->read_proc = vicam_read_proc_shutter;
ent->write_proc = vicam_write_proc_shutter;
ent->size = 64;
}
ent = create_proc_entry("gain", S_IFREG | S_IRUGO , cam->proc_dir);
if ( ent ) {
ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,
cam->proc_dir);
if (ent) {
ent->data = cam;
ent->read_proc = vicam_read_proc_gain;
ent->write_proc = vicam_write_proc_gain;
ent->size = 64;
}
}
......
......@@ -63,6 +63,8 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
static const char driver_name[] = "catc";
/*
* Some defines.
*/
......@@ -677,7 +679,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
/* get driver info */
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strncpy(info.driver, SHORT_DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
usb_make_path (catc->usbdev, info.bus_info, sizeof info.bus_info);
if (copy_to_user(useraddr, &info, sizeof(info)))
......@@ -978,7 +980,7 @@ MODULE_DEVICE_TABLE(usb, catc_id_table);
static struct usb_driver catc_driver = {
.owner = THIS_MODULE,
.name = "catc",
.name = driver_name,
.probe = catc_probe,
.disconnect = catc_disconnect,
.id_table = catc_id_table,
......
......@@ -114,6 +114,8 @@ MODULE_AUTHOR("Michael Zappe <zapman@interlan.net>, Stephane Alnet <stephane@u-p
MODULE_DESCRIPTION("KL5USB101 USB Ethernet driver");
MODULE_LICENSE("GPL");
static const char driver_name[] = "kaweth";
static int kaweth_probe(
struct usb_interface *intf,
const struct usb_device_id *id /* from id_table */
......@@ -169,7 +171,7 @@ MODULE_DEVICE_TABLE (usb, usb_klsi_table);
****************************************************************/
static struct usb_driver kaweth_driver = {
.owner = THIS_MODULE,
.name = "kaweth",
.name = driver_name,
.probe = kaweth_probe,
.disconnect = kaweth_disconnect,
.id_table = usb_klsi_table,
......@@ -670,7 +672,7 @@ static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
switch (ethcmd) {
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strlcpy(info.driver, "kaweth", sizeof(info.driver));
strlcpy(info.driver, driver_name, sizeof(info.driver));
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
......
/*
* Copyright (c) 1999-2002 Petko Manolov (petkan@users.sourceforge.net)
* Copyright (c) 1999-2003 Petko Manolov (petkan@users.sourceforge.net)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
......@@ -45,7 +45,7 @@
/*
* Version Information
*/
#define DRIVER_VERSION "v0.5.10 (2003/04/01)"
#define DRIVER_VERSION "v0.5.12 (2003/06/06)"
#define DRIVER_AUTHOR "Petko Manolov <petkan@users.sourceforge.net>"
#define DRIVER_DESC "Pegasus/Pegasus II USB Ethernet driver"
......@@ -564,7 +564,14 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
dbg("%s: reset MAC", net->name);
pegasus->flags &= ~PEGASUS_RX_BUSY;
break;
case -EPIPE: /* stall, or disconnect from TT */
/* FIXME schedule work to clear the halt */
warn("%s: no rx stall recovery", net->name);
return;
case -ENOENT:
case -ECONNRESET:
case -ESHUTDOWN:
dbg("%s: rx unlink, %d", net->name, urb->status);
return;
default:
dbg("%s: RX status %d", net->name, urb->status);
......@@ -604,6 +611,9 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
pegasus->stats.rx_packets++;
pegasus->stats.rx_bytes += pkt_len;
if (pegasus->flags & PEGASUS_UNPLUG)
return;
spin_lock(&pegasus->rx_pool_lock);
pegasus->rx_skb = pull_skb(pegasus);
spin_unlock(&pegasus->rx_pool_lock);
......@@ -631,24 +641,24 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs)
static void rx_fixup(unsigned long data)
{
pegasus_t *pegasus;
unsigned long flags;
pegasus = (pegasus_t *) data;
if (pegasus->flags & PEGASUS_UNPLUG)
return;
spin_lock_irq(&pegasus->rx_pool_lock);
spin_lock_irqsave(&pegasus->rx_pool_lock, flags);
fill_skb_pool(pegasus);
spin_unlock_irq(&pegasus->rx_pool_lock);
if (pegasus->flags & PEGASUS_RX_URB_FAIL)
if (pegasus->rx_skb)
goto try_again;
if (pegasus->rx_skb == NULL) {
spin_lock_irq(&pegasus->rx_pool_lock);
pegasus->rx_skb = pull_skb(pegasus);
spin_unlock_irq(&pegasus->rx_pool_lock);
}
if (pegasus->rx_skb == NULL) {
warn("wow, low on memory");
tasklet_schedule(&pegasus->rx_tl);
return;
goto done;
}
usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb,
usb_rcvbulkpipe(pegasus->usb, 1),
......@@ -661,23 +671,41 @@ static void rx_fixup(unsigned long data)
} else {
pegasus->flags &= ~PEGASUS_RX_URB_FAIL;
}
done:
spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags);
}
static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
{
pegasus_t *pegasus = urb->context;
struct net_device *net = pegasus->net;
if (!pegasus || !(pegasus->flags & PEGASUS_RUNNING))
return;
if (!netif_device_present(pegasus->net))
if (!netif_device_present(net))
return;
if (urb->status)
info("%s: TX status %d", pegasus->net->name, urb->status);
switch (urb->status) {
case -EPIPE:
/* FIXME schedule_work() to clear the tx halt */
netif_stop_queue(net);
warn("%s: no tx stall recovery", net->name);
return;
case -ENOENT:
case -ECONNRESET:
case -ESHUTDOWN:
dbg("%s: tx unlink, %d", net->name, urb->status);
return;
default:
info("%s: TX status %d", net->name, urb->status);
/* FALL THROUGH */
case 0:
break;
}
pegasus->net->trans_start = jiffies;
netif_wake_queue(pegasus->net);
net->trans_start = jiffies;
netif_wake_queue(net);
}
static void intr_callback(struct urb *urb, struct pt_regs *regs)
......@@ -754,8 +782,16 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
write_bulk_callback, pegasus);
if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) {
warn("failed tx_urb %d", res);
pegasus->stats.tx_errors++;
netif_start_queue(net);
switch (res) {
case -EPIPE: /* stall, or disconnect from TT */
/* cleanup should already have been scheduled */
break;
case -ENODEV: /* disconnect() upcoming */
break;
default:
pegasus->stats.tx_errors++;
netif_start_queue(net);
}
} else {
pegasus->stats.tx_packets++;
pegasus->stats.tx_bytes += skb->len;
......@@ -903,6 +939,7 @@ static int pegasus_close(struct net_device *net)
netif_stop_queue(net);
if (!(pegasus->flags & PEGASUS_UNPLUG))
disable_net_traffic(pegasus);
tasklet_kill(&pegasus->rx_tl);
unlink_all_urbs(pegasus);
return 0;
......@@ -920,11 +957,15 @@ static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
switch (ethcmd) {
/* get driver-specific version/etc. info */
case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strlcpy(info.driver, driver_name,
sizeof (info.driver));
strlcpy(info.version, DRIVER_VERSION,
sizeof (info.version));
struct ethtool_drvinfo info;
memset (&info, 0, sizeof (info));
info.cmd = ETHTOOL_GDRVINFO;
strncpy(info.driver, driver_name,
sizeof (info.driver) - 1);
strncpy(info.version, DRIVER_VERSION,
sizeof (info.version) - 1);
usb_make_path(pegasus->usb, info.bus_info,
sizeof (info.bus_info));
if (copy_to_user(useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
......@@ -993,12 +1034,15 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
return -EFAULT;
switch (cmd) {
case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strncpy(info.driver, driver_name, sizeof info.driver);
struct ethtool_drvinfo info;
memset (&info, 0, sizeof (info));
info.cmd = ETHTOOL_GDRVINFO;
strncpy(info.driver, driver_name,
sizeof (info.driver) - 1);
strncpy(info.version, DRIVER_VERSION,
ETHTOOL_BUSINFO_LEN);
sizeof (info.version) - 1);
usb_make_path(pegasus->usb, info.bus_info,
sizeof info.bus_info);
sizeof (info.bus_info));
if (copy_to_user(uaddr, &info, sizeof (info)))
return -EFAULT;
return 0;
......@@ -1006,15 +1050,20 @@ static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
case ETHTOOL_GSET:{
struct ethtool_cmd ecmd;
short lpa, bmcr;
u8 port;
memset(&ecmd, 0, sizeof ecmd);
memset(&ecmd, 0, sizeof (ecmd));
ecmd.supported = (SUPPORTED_10baseT_Half |
SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
SUPPORTED_Autoneg |
SUPPORTED_TP | SUPPORTED_MII);
ecmd.port = PORT_TP;
get_registers(pegasus, Reg7b, 1, &port);
if (port == 0)
ecmd.port = PORT_MII;
else
ecmd.port = PORT_TP;
ecmd.transceiver = XCVR_INTERNAL;
ecmd.phy_address = pegasus->phy;
read_mii_word(pegasus, pegasus->phy, MII_BMCR, &bmcr);
......@@ -1132,7 +1181,10 @@ static inline void setup_pegasus_II(pegasus_t * pegasus)
set_register(pegasus, Reg1d, 0);
set_register(pegasus, Reg7b, 1);
mdelay(100);
set_register(pegasus, Reg7b, 2);
if ((pegasus->features & HAS_HOME_PNA) && mii_mode)
set_register(pegasus, Reg7b, 0);
else
set_register(pegasus, Reg7b, 2);
set_register(pegasus, 0x83, data);
get_registers(pegasus, 0x83, 1, &data);
......@@ -1253,7 +1305,6 @@ static void pegasus_disconnect(struct usb_interface *intf)
pegasus->flags |= PEGASUS_UNPLUG;
unregister_netdev(pegasus->net);
usb_put_dev(interface_to_usbdev(intf));
unlink_all_urbs(pegasus);
free_all_urbs(pegasus);
free_skb_pool(pegasus);
if (pegasus->rx_skb)
......@@ -1263,7 +1314,6 @@ static void pegasus_disconnect(struct usb_interface *intf)
}
static struct usb_driver pegasus_driver = {
.owner = THIS_MODULE,
.name = driver_name,
.probe = pegasus_probe,
.disconnect = pegasus_disconnect,
......
/*
* Copyright (c) 1999-2002 Petko Manolov - Petkan (petkan@users.sourceforge.net)
* Copyright (c) 1999-2003 Petko Manolov - Petkan (petkan@users.sourceforge.net)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
......@@ -129,6 +129,7 @@ struct usb_eth_dev {
#define VENDOR_ELCON 0x0db7
#define VENDOR_ELSA 0x05cc
#define VENDOR_HAWKING 0x0e66
#define VENDOR_HP 0x03f0
#define VENDOR_IODATA 0x04bb
#define VENDOR_KINGSTON 0x0951
#define VENDOR_LANEED 0x056e
......@@ -223,6 +224,8 @@ PEGASUS_DEV( "Elsa Micolink USB2Ethernet", VENDOR_ELSA, 0x3000,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "Hawking UF100 10/100 Ethernet", VENDOR_HAWKING, 0x400c,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "HP hn210c Ethernet USB", VENDOR_HP, 0x811c,
DEFAULT_GPIO_RESET | PEGASUS_II )
PEGASUS_DEV( "IO DATA USB ET/TX", VENDOR_IODATA, 0x0904,
DEFAULT_GPIO_RESET )
PEGASUS_DEV( "IO DATA USB ET/TX-S", VENDOR_IODATA, 0x0913,
......
......@@ -113,9 +113,11 @@ static void rtl8150_disconnect(struct usb_interface *intf);
static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id);
static const char driver_name [] = "rtl8150";
static struct usb_driver rtl8150_driver = {
.owner = THIS_MODULE,
.name = "rtl8150",
.name = driver_name,
.probe = rtl8150_probe,
.disconnect = rtl8150_disconnect,
.id_table = rtl8150_table,
......@@ -684,7 +686,7 @@ static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr)
case ETHTOOL_GDRVINFO:{
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strncpy(info.driver, DRIVER_DESC, ETHTOOL_BUSINFO_LEN);
strncpy(info.driver, driver_name, ETHTOOL_BUSINFO_LEN);
strncpy(info.version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN);
usb_make_path(dev->udev, info.bus_info, sizeof info.bus_info);
if (copy_to_user(uaddr, &info, sizeof(info)))
......
......@@ -48,6 +48,7 @@
#include <linux/config.h>
#include "transport.h"
#include "protocol.h"
#include "scsiglue.h"
#include "usb.h"
#include "debug.h"
......@@ -303,6 +304,11 @@ static int interpret_urb_result(struct us_data *us, unsigned int pipe,
US_DEBUGP("-- device NAKed\n");
return USB_STOR_XFER_ERROR;
/* babble - the device tried to send more than we wanted to read */
case -EOVERFLOW:
US_DEBUGP("-- Babble\n");
return USB_STOR_XFER_LONG;
/* the transfer was cancelled, presumably by an abort */
case -ECONNRESET:
US_DEBUGP("-- transfer cancelled\n");
......@@ -525,6 +531,12 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
return;
}
/* if the transport provided its own sense data, don't auto-sense */
if (result == USB_STOR_TRANSPORT_NO_SENSE) {
srb->result = SAM_STAT_CHECK_CONDITION;
return;
}
/* Determine if we need to auto-sense
*
* I normally don't use a flag like this, but it's almost impossible
......@@ -764,7 +776,7 @@ int usb_stor_CBI_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->request_buffer, transfer_length,
srb->use_sg, &srb->resid);
US_DEBUGP("CBI data stage result is 0x%x\n", result);
if (result == USB_STOR_XFER_ERROR)
if (result > USB_STOR_XFER_STALLED)
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -854,7 +866,7 @@ int usb_stor_CB_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->request_buffer, transfer_length,
srb->use_sg, &srb->resid);
US_DEBUGP("CB data stage result is 0x%x\n", result);
if (result == USB_STOR_XFER_ERROR)
if (result > USB_STOR_XFER_STALLED)
return USB_STOR_TRANSPORT_ERROR;
}
......@@ -899,6 +911,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
struct bulk_cs_wrap bcs;
unsigned int transfer_length = srb->request_bufflen;
int result;
int fake_sense = 0;
/* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
......@@ -936,6 +949,15 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("Bulk data transfer result 0x%x\n", result);
if (result == USB_STOR_XFER_ERROR)
return USB_STOR_TRANSPORT_ERROR;
/* If the device tried to send back more data than the
* amount requested, the spec requires us to transfer
* the CSW anyway. Since there's no point retrying the
* the command, we'll return fake sense data indicating
* Illegal Request, Invalid Field in CDB.
*/
if (result == USB_STOR_XFER_LONG)
fake_sense = 1;
}
/* See flow chart on pg 15 of the Bulk Only Transport spec for
......@@ -975,6 +997,14 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* based on the status code, we report good or bad */
switch (bcs.Status) {
case US_BULK_STAT_OK:
/* device babbled -- return fake sense data */
if (fake_sense) {
memcpy(srb->sense_buffer,
usb_stor_sense_invalidCDB,
sizeof(usb_stor_sense_invalidCDB));
return USB_STOR_TRANSPORT_NO_SENSE;
}
/* command good -- note that data could be short */
return USB_STOR_TRANSPORT_GOOD;
......
......@@ -122,7 +122,8 @@ struct bulk_cs_wrap {
#define USB_STOR_XFER_GOOD 0 /* good transfer */
#define USB_STOR_XFER_SHORT 1 /* transferred less than expected */
#define USB_STOR_XFER_STALLED 2 /* endpoint stalled */
#define USB_STOR_XFER_ERROR 3 /* transfer died in the middle */
#define USB_STOR_XFER_LONG 3 /* device tried to send too much */
#define USB_STOR_XFER_ERROR 4 /* transfer died in the middle */
/*
* Transport return codes
......@@ -130,7 +131,8 @@ struct bulk_cs_wrap {
#define USB_STOR_TRANSPORT_GOOD 0 /* Transport good, command good */
#define USB_STOR_TRANSPORT_FAILED 1 /* Transport good, command failed */
#define USB_STOR_TRANSPORT_ERROR 2 /* Transport bad (i.e. device dead) */
#define USB_STOR_TRANSPORT_NO_SENSE 2 /* Command failed, no auto-sense */
#define USB_STOR_TRANSPORT_ERROR 3 /* Transport bad (i.e. device dead) */
/*
* We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
......
This diff is collapsed.
......@@ -107,6 +107,7 @@ struct us_data {
*/
struct semaphore dev_semaphore; /* protect pusb_dev */
struct usb_device *pusb_dev; /* this usb_device */
struct usb_interface *pusb_intf; /* this interface */
unsigned long flags; /* from filter initially */
unsigned int send_bulk_pipe; /* cached pipe values */
unsigned int recv_bulk_pipe;
......@@ -114,7 +115,7 @@ struct us_data {
unsigned int recv_ctrl_pipe;
unsigned int recv_intr_pipe;
/* information about the device -- always good */
/* information about the device */
char vendor[USB_STOR_STRING_LEN];
char product[USB_STOR_STRING_LEN];
char serial[USB_STOR_STRING_LEN];
......@@ -124,11 +125,7 @@ struct us_data {
u8 protocol;
u8 max_lun;
/* information about the device -- only good if device is attached */
u8 ifnum; /* interface number */
u8 ep_in; /* bulk in endpoint */
u8 ep_out; /* bulk out endpoint */
u8 ep_int; /* interrupt endpoint */
u8 ep_bInterval; /* interrupt interval */
/* function pointers for this device */
......
......@@ -84,7 +84,7 @@ static int fill_read_buffer(struct file * file, struct sysfs_buffer * buffer)
ssize_t count;
if (!buffer->page)
buffer->page = (char *) __get_free_page(GFP_KERNEL);
buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
if (!buffer->page)
return -ENOMEM;
......@@ -174,7 +174,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char * buf, size_t count)
int error;
if (!buffer->page)
buffer->page = (char *)__get_free_page(GFP_KERNEL);
buffer->page = (char *)get_zeroed_page(GFP_KERNEL);
if (!buffer->page)
return -ENOMEM;
......
......@@ -19,7 +19,7 @@
#ifndef _LINUX_CPU_H_
#define _LINUX_CPU_H_
#include <linux/device.h>
#include <linux/sysdev.h>
#include <linux/node.h>
#include <asm/semaphore.h>
......@@ -29,8 +29,6 @@ struct cpu {
};
extern int register_cpu(struct cpu *, int, struct node *);
extern struct class cpu_class;
struct notifier_block;
#ifdef CONFIG_SMP
......@@ -48,6 +46,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb)
{
}
#endif /* CONFIG_SMP */
extern struct sysdev_class cpu_sysdev_class;
/* Stop CPUs going up and down. */
extern struct semaphore cpucontrol;
......
......@@ -205,10 +205,6 @@ struct freq_attr {
int cpufreq_set_policy(struct cpufreq_policy *policy);
int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu);
#ifdef CONFIG_PM
int cpufreq_restore(void);
#endif
/* the proc_intf.c needs this */
int cpufreq_parse_governor (char *str_governor, unsigned int *policy, struct cpufreq_governor **governor);
......
......@@ -351,30 +351,6 @@ extern int (*platform_notify_remove)(struct device * dev);
extern struct device * get_device(struct device * dev);
extern void put_device(struct device * dev);
/* drivers/base/sys.c */
struct sys_root {
u32 id;
struct device dev;
struct device sysdev;
};
extern int sys_register_root(struct sys_root *);
extern void sys_unregister_root(struct sys_root *);
struct sys_device {
char * name;
u32 id;
struct sys_root * root;
struct device dev;
struct class_device class_dev;
};
extern int sys_device_register(struct sys_device *);
extern void sys_device_unregister(struct sys_device *);
extern struct bus_type system_bus_type;
/* drivers/base/platform.c */
......
......@@ -118,6 +118,14 @@ static inline struct kobj_type * get_ktype(struct kobject * k)
extern struct kobject * kset_find_obj(struct kset *, const char *);
/**
* Use this when initializing an embedded kset with no other
* fields to initialize.
*/
#define set_kset_name(str) .kset = { .kobj = { .name = str } }
struct subsystem {
struct kset kset;
struct rw_semaphore rwsem;
......
......@@ -309,6 +309,20 @@ static inline void list_splice_init(struct list_head *list,
pos = list_entry(pos->member.next, typeof(*pos), member), \
prefetch(pos->member.next))
/**
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
prefetch(pos->member.prev); \
&pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member), \
prefetch(pos->member.prev))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
......
......@@ -19,11 +19,11 @@
#ifndef _LINUX_NODE_H_
#define _LINUX_NODE_H_
#include <linux/device.h>
#include <linux/sysdev.h>
struct node {
unsigned long cpumap; /* Bitmap of CPUs on the Node */
struct sys_root sysroot;
struct sys_device sysdev;
};
extern int register_node(struct node *, int, struct node *);
......
/**
* System devices follow a slightly different driver model.
* They don't need to do dynammic driver binding, can't be probed,
* and don't reside on any type of peripheral bus.
* So, we represent and treat them a little differently.
*
* We still have a notion of a driver for a system device, because we still
* want to perform basic operations on these devices.
*
* We also support auxillary drivers binding to devices of a certain class.
*
* This allows configurable drivers to register themselves for devices of
* a certain type. And, it allows class definitions to reside in generic
* code while arch-specific code can register specific drivers.
*
* Auxillary drivers registered with a NULL cls are registered as drivers
* for all system devices, and get notification calls for each device.
*/
#ifndef _SYSDEV_H_
#define _SYSDEV_H_
#include <linux/kobject.h>
struct sys_device;
struct sysdev_class {
struct list_head drivers;
/* Default operations for these types of devices */
int (*shutdown)(struct sys_device *);
int (*save)(struct sys_device *, u32 state);
int (*suspend)(struct sys_device *, u32 state);
int (*resume)(struct sys_device *);
int (*restore)(struct sys_device *);
struct kset kset;
};
extern int sysdev_class_register(struct sysdev_class *);
extern void sysdev_class_unregister(struct sysdev_class *);
/**
* Auxillary system device drivers.
*/
struct sysdev_driver {
struct list_head entry;
int (*add)(struct sys_device *);
int (*remove)(struct sys_device *);
int (*shutdown)(struct sys_device *);
int (*save)(struct sys_device *, u32 state);
int (*suspend)(struct sys_device *, u32 state);
int (*resume)(struct sys_device *);
int (*restore)(struct sys_device *);
};
extern int sysdev_driver_register(struct sysdev_class *, struct sysdev_driver *);
extern void sysdev_driver_unregister(struct sysdev_class *, struct sysdev_driver *);
/**
* sys_devices can be simplified a lot from regular devices, because they're
* simply not as versatile.
*/
struct sys_device {
u32 id;
struct sysdev_class * cls;
struct kobject kobj;
};
extern int sys_device_register(struct sys_device *);
extern void sys_device_unregister(struct sys_device *);
struct sysdev_attribute {
struct attribute attr;
ssize_t (*show)(struct sys_device *, char *);
ssize_t (*store)(struct sys_device *, const char *, size_t);
};
#define SYSDEV_ATTR(_name,_mode,_show,_store) \
struct sysdev_attribute attr_##_name = { \
.attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \
.store = _store, \
};
extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
#endif /* _SYSDEV_H_ */
......@@ -136,7 +136,7 @@ static inline void *usb_get_intfdata (struct usb_interface *intf)
static inline void usb_set_intfdata (struct usb_interface *intf, void *data)
{
return dev_set_drvdata (&intf->dev, data);
dev_set_drvdata(&intf->dev, data);
}
/* USB_DT_CONFIG: Configuration descriptor information.
......
......@@ -46,14 +46,14 @@ struct usbdevfs_ctrltransfer {
__u16 wIndex;
__u16 wLength;
__u32 timeout; /* in milliseconds */
void *data;
void __user *data;
};
struct usbdevfs_bulktransfer {
unsigned int ep;
unsigned int len;
unsigned int timeout; /* in milliseconds */
void *data;
void __user *data;
};
struct usbdevfs_setinterface {
......@@ -97,7 +97,7 @@ struct usbdevfs_urb {
unsigned char endpoint;
int status;
unsigned int flags;
void *buffer;
void __user *buffer;
int buffer_length;
int actual_length;
int start_frame;
......@@ -113,7 +113,7 @@ struct usbdevfs_ioctl {
int ifno; /* interface 0..N ; negative numbers reserved */
int ioctl_code; /* MUST encode size + direction of data so the
* macros in <asm/ioctl.h> give correct values */
void *data; /* param buffer (in, or out) */
void __user *data; /* param buffer (in, or out) */
};
/* You can do most things with hubs just through control messages,
......
......@@ -49,8 +49,6 @@ static DECLARE_RWSEM (cpufreq_notifier_rwsem);
static LIST_HEAD(cpufreq_governor_list);
static DECLARE_MUTEX (cpufreq_governor_sem);
static struct class_interface cpufreq_interface;
static int cpufreq_cpu_get(unsigned int cpu)
{
if (cpu >= NR_CPUS)
......@@ -113,24 +111,8 @@ int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
EXPORT_SYMBOL_GPL(cpufreq_parse_governor);
/* forward declarations */
static int cpufreq_add_dev (struct class_device * dev);
static void cpufreq_remove_dev (struct class_device * dev);
/* drivers/base/cpu.c */
extern struct device_class cpu_devclass;
static struct class_interface cpufreq_interface = {
.class = &cpu_class,
.add = &cpufreq_add_dev,
.remove = &cpufreq_remove_dev,
};
static inline int to_cpu_nr (struct class_device *dev)
{
struct sys_device * cpu_sys_dev = container_of(dev->dev, struct sys_device, dev);
return (cpu_sys_dev->id);
}
extern struct sysdev_class cpu_sysdev_class;
/**
......@@ -331,9 +313,9 @@ static struct kobj_type ktype_cpufreq = {
*
* Adds the cpufreq interface for a CPU device.
*/
static int cpufreq_add_dev (struct class_device * class_dev)
static int cpufreq_add_dev (struct sys_device * sys_dev)
{
unsigned int cpu = to_cpu_nr(class_dev);
unsigned int cpu = sys_dev->id;
int ret = 0;
struct cpufreq_policy new_policy;
struct cpufreq_policy *policy;
......@@ -358,14 +340,12 @@ static int cpufreq_add_dev (struct class_device * class_dev)
memcpy(&new_policy,
policy,
sizeof(struct cpufreq_policy));
class_set_devdata(class_dev, policy);
up(&cpufreq_driver_sem);
init_MUTEX(&policy->lock);
/* prepare interface data */
policy->kobj.parent = &class_dev->kobj;
policy->kobj.parent = &sys_dev->kobj;
policy->kobj.ktype = &ktype_cpufreq;
// policy->dev = dev->dev;
strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
ret = kobject_register(&policy->kobj);
......@@ -396,12 +376,12 @@ static int cpufreq_add_dev (struct class_device * class_dev)
*
* Removes the cpufreq interface for a CPU device.
*/
static void cpufreq_remove_dev (struct class_device * class_dev)
static int cpufreq_remove_dev (struct sys_device * sys_dev)
{
unsigned int cpu = to_cpu_nr(class_dev);
unsigned int cpu = sys_dev->id;
if (!kobject_get(&cpufreq_driver->policy[cpu].kobj))
return;
return -EFAULT;
down(&cpufreq_driver_sem);
if ((cpufreq_driver->target) &&
......@@ -421,9 +401,17 @@ static void cpufreq_remove_dev (struct class_device * class_dev)
up(&cpufreq_driver_sem);
kobject_put(&cpufreq_driver->policy[cpu].kobj);
return;
return 0;
}
static int cpufreq_restore(struct sys_device *);
static struct sysdev_driver cpufreq_sysdev_driver = {
.add = cpufreq_add_dev,
.remove = cpufreq_remove_dev,
.restore = cpufreq_restore,
};
/*********************************************************************
* NOTIFIER LISTS INTERFACE *
......@@ -843,7 +831,7 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
memset(cpufreq_driver->policy, 0, NR_CPUS * sizeof(struct cpufreq_policy));
return class_interface_register(&cpufreq_interface);
return sysdev_driver_register(&cpu_sysdev_class,&cpufreq_sysdev_driver);
}
EXPORT_SYMBOL_GPL(cpufreq_register_driver);
......@@ -861,7 +849,7 @@ int cpufreq_unregister_driver(struct cpufreq_driver *driver)
if (!cpufreq_driver || (driver != cpufreq_driver))
return -EINVAL;
class_interface_unregister(&cpufreq_interface);
sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
down(&cpufreq_driver_sem);
kfree(cpufreq_driver->policy);
......@@ -874,41 +862,34 @@ EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
#ifdef CONFIG_PM
/**
* cpufreq_restore - restore the CPU clock frequency after resume
*
* Restore the CPU clock frequency so that our idea of the current
* frequency reflects the actual hardware.
*/
int cpufreq_restore(void)
static int cpufreq_restore(struct sys_device * sysdev)
{
struct cpufreq_policy policy;
unsigned int i;
int cpu = sysdev->id;
unsigned int ret = 0;
struct cpufreq_policy policy;
if (in_interrupt())
panic("cpufreq_restore() called from interrupt context!");
if (!try_module_get(cpufreq_driver->owner))
goto error_out;
for (i=0;i<NR_CPUS;i++) {
if (!cpu_online(i) || !cpufreq_cpu_get(i))
continue;
if (cpu_online(cpu) && cpufreq_cpu_get(cpu)) {
down(&cpufreq_driver_sem);
memcpy(&policy, &cpufreq_driver->policy[i], sizeof(struct cpufreq_policy));
memcpy(&policy, &cpufreq_driver->policy[cpu],
sizeof(struct cpufreq_policy));
up(&cpufreq_driver_sem);
ret += cpufreq_set_policy(&policy);
cpufreq_cpu_put(i);
ret = cpufreq_set_policy(&policy);
cpufreq_cpu_put(cpu);
}
module_put(cpufreq_driver->owner);
error_out:
return ret;
}
EXPORT_SYMBOL_GPL(cpufreq_restore);
#else
#define cpufreq_restore() do {} while (0)
static int cpufreq_restore(struct sys_device * sysdev)
{
return 0;
}
#endif /* CONFIG_PM */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment