Commit 39074c8c authored by James Simmons's avatar James Simmons

Merge kozmo.(none):/usr/src/linus-2.5

into kozmo.(none):/usr/src/fbdev-2.5
parents 808c8a58 21347414
......@@ -2750,6 +2750,10 @@ E: wsalamon@tislabs.com
E: wsalamon@nai.com
D: portions of the Linux Security Module (LSM) framework and security modules
N: Robert Sanders
E: gt8134b@prism.gatech.edu
D: Dosemu
N: Duncan Sands
E: duncan.sands@wanadoo.fr
W: http://topo.math.u-psud.fr/~sands
......@@ -2758,10 +2762,6 @@ S: 69 rue Dunois
S: 75013 Paris
S: France
N: Robert Sanders
E: gt8134b@prism.gatech.edu
D: Dosemu
N: Hannu Savolainen
E: hannu@opensound.com
D: Maintainer of the sound drivers until 2.1.x days.
......
This diff is collapsed.
......@@ -598,7 +598,7 @@ static struct kobj_type ktype_edd = {
.default_attrs = def_attrs,
};
static decl_subsys(edd,&ktype_edd);
static decl_subsys(edd,&ktype_edd,NULL);
/**
......
......@@ -676,7 +676,7 @@ acpi_bus_init (void)
return_VALUE(-ENODEV);
}
decl_subsys(acpi,NULL);
decl_subsys(acpi,NULL,NULL);
static int __init acpi_init (void)
{
......
......@@ -18,13 +18,8 @@ extern void interface_remove_dev(struct device *);
#ifdef CONFIG_HOTPLUG
extern int dev_hotplug(struct device *dev, const char *action);
extern int class_hotplug(struct device *dev, const char *action);
#else
static inline int dev_hotplug(struct device *dev, const char *action)
{
return 0;
}
static inline int class_hotplug(struct device *dev, const char *action)
{
return 0;
......
......@@ -132,7 +132,7 @@ static struct kobj_type ktype_bus = {
};
decl_subsys(bus,&ktype_bus);
decl_subsys(bus,&ktype_bus,NULL);
/**
* bus_for_each_dev - device iterator.
......
......@@ -49,7 +49,9 @@ static struct kobj_type ktype_devclass = {
.sysfs_ops = &class_sysfs_ops,
};
static decl_subsys(class,&ktype_devclass);
/* Classes can't use the kobject hotplug logic, as
* they do not add new kobjects to the system */
static decl_subsys(class,&ktype_devclass,NULL);
static int devclass_dev_link(struct device_class * cls, struct device * dev)
......
......@@ -23,13 +23,12 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
DECLARE_MUTEX(device_sem);
#define to_dev(obj) container_of(obj,struct device,kobj)
/*
* sysfs bindings for devices.
*/
#define to_dev(obj) container_of(obj,struct device,kobj)
#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
extern struct attribute * dev_default_attrs[];
......@@ -86,11 +85,55 @@ static struct kobj_type ktype_device = {
.default_attrs = dev_default_attrs,
};
static int dev_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
if (ktype == &ktype_device) {
struct device *dev = to_dev(kobj);
if (dev->bus)
return 1;
}
return 0;
}
static char *dev_hotplug_name(struct kset *kset, struct kobject *kobj)
{
struct device *dev = to_dev(kobj);
return dev->bus->name;
}
static int dev_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
int num_envp, char *buffer, int buffer_size)
{
struct device *dev = to_dev(kobj);
int retval = 0;
if (dev->bus->hotplug) {
/* have the bus specific function add its stuff */
retval = dev->bus->hotplug (dev, envp, num_envp, buffer, buffer_size);
if (retval) {
pr_debug ("%s - hotplug() returned %d\n",
__FUNCTION__, retval);
}
}
return retval;
}
static struct kset_hotplug_ops device_hotplug_ops = {
.filter = dev_hotplug_filter,
.name = dev_hotplug_name,
.hotplug = dev_hotplug,
};
/**
* device_subsys - structure to be registered with kobject core.
*/
decl_subsys(devices,&ktype_device);
decl_subsys(devices, &ktype_device, &device_hotplug_ops);
/**
......@@ -192,9 +235,6 @@ int device_add(struct device *dev)
if (platform_notify)
platform_notify(dev);
/* notify userspace of device entry */
dev_hotplug(dev, "add");
devclass_add_device(dev);
register_done:
if (error && parent)
......@@ -278,9 +318,6 @@ void device_del(struct device * dev)
if (platform_notify_remove)
platform_notify_remove(dev);
/* notify userspace that this device is about to disappear */
dev_hotplug (dev, "remove");
bus_remove_device(dev);
kobject_del(&dev->kobj);
......
......@@ -6,7 +6,7 @@
#include <linux/module.h>
#include <linux/init.h>
static decl_subsys(firmware,NULL);
static decl_subsys(firmware,NULL,NULL);
int firmware_register(struct subsystem * s)
{
......
......@@ -2,8 +2,8 @@
* drivers/base/hotplug.c - hotplug call code
*
* Copyright (c) 2000-2001 David Brownell
* Copyright (c) 2002 Greg Kroah-Hartman
* Copyright (c) 2002 IBM Corp.
* Copyright (c) 2002-2003 Greg Kroah-Hartman
* Copyright (c) 2002-2003 IBM Corp.
*
* Based off of drivers/usb/core/usb.c:call_agent(), which was
* written by David Brownell.
......@@ -53,17 +53,6 @@ static int do_hotplug (struct device *dev, char *argv1, const char *action,
if (!hotplug_path [0])
return -ENODEV;
if (in_interrupt ()) {
pr_debug ("%s - in_interrupt, not allowed!", __FUNCTION__);
return -EIO;
}
if (!current->fs->root) {
/* don't try to do anything unless we have a root partition */
pr_debug ("%s - %s -- no FS yet\n", __FUNCTION__, action);
return -EIO;
}
envp = (char **) kmalloc (NUM_ENVP * sizeof (char *), GFP_KERNEL);
if (!envp)
return -ENOMEM;
......@@ -128,23 +117,6 @@ static int do_hotplug (struct device *dev, char *argv1, const char *action,
return retval;
}
/*
* dev_hotplug - called when any device is added or removed from a bus
*/
int dev_hotplug (struct device *dev, const char *action)
{
pr_debug ("%s\n", __FUNCTION__);
if (!dev)
return -ENODEV;
if (!dev->bus)
return -ENODEV;
return do_hotplug (dev, dev->bus->name, action, dev->bus->hotplug);
}
/*
* class_hotplug - called when a class is added or removed from a device
*/
......
......@@ -525,9 +525,21 @@ static struct kobj_type ktype_block = {
.default_attrs = default_attrs,
};
extern struct kobj_type ktype_part;
static int block_hotplug_filter(struct kset *kset, struct kobject *kobj)
{
struct kobj_type *ktype = get_ktype(kobj);
return ((ktype == &ktype_block) || (ktype == &ktype_part));
}
static struct kset_hotplug_ops block_hotplug_ops = {
.filter = block_hotplug_filter,
};
/* declare block_subsys. */
static decl_subsys(block,&ktype_block);
static decl_subsys(block, &ktype_block, &block_hotplug_ops);
struct gendisk *alloc_disk(int minors)
......
......@@ -100,7 +100,7 @@ static struct kobj_type hotplug_slot_ktype = {
.sysfs_ops = &hotplug_slot_sysfs_ops
};
static decl_subsys(hotplug_slots, &hotplug_slot_ktype);
static decl_subsys(hotplug_slots, &hotplug_slot_ktype, NULL);
/* these strings match up with the values in pci_bus_speed */
......
......@@ -142,6 +142,17 @@ config I2C_ELEKTOR
<file:Documentation/modules.txt>.
The module will be called i2c-elektor.
config I2C_KEYWEST
tristate "Powermac Keywest I2C interface"
depends on I2C && ALL_PPC
help
This supports the use of the I2C interface in the combo-I/O
chip on recent Apple machines. Say Y if you have such a machine.
This driver is also available as a module. If you want to compile
it as a module, say M here and read Documentation/modules.txt.
The module will be called i2c-keywest.
config ITE_I2C_ALGO
tristate "ITE I2C Algorithm"
depends on MIPS_ITE8172 && I2C
......
......@@ -10,6 +10,7 @@ obj-$(CONFIG_I2C_ELV) += i2c-elv.o
obj-$(CONFIG_I2C_VELLEMAN) += i2c-velleman.o
obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o
obj-$(CONFIG_ITE_I2C_ALGO) += i2c-algo-ite.o
obj-$(CONFIG_ITE_I2C_ADAP) += i2c-adap-ite.o
obj-$(CONFIG_SCx200_I2C) += scx200_i2c.o
......
......@@ -116,5 +116,31 @@ config I2C_PIIX4
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
config I2C_VIAPRO
tristate " VIA 82C596/82C686/823x"
depends on I2C && PCI && EXPERIMENTAL
help
If you say yes to this option, support will be included for the VIA
82C596/82C686/823x I2C interfaces. Specifically, the following
chipsets are supported:
82C596A/B
82C686A/B
8231
8233
8233A
8235
This can also be built as a module which can be inserted and removed
while the kernel is running. If you want to compile it as a module,
say M here and read <file:Documentation/modules.txt>.
The module will be called i2c-viapro.
You will also need the latest user-space utilties: you can find them
in the lm_sensors package, which you can download at
http://www.lm-sensors.nu
endmenu
......@@ -8,3 +8,4 @@ obj-$(CONFIG_I2C_AMD8111) += i2c-amd8111.o
obj-$(CONFIG_I2C_I801) += i2c-i801.o
obj-$(CONFIG_I2C_ISA) += i2c-isa.o
obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
This diff is collapsed.
......@@ -66,7 +66,8 @@ config SENSORS_W83781D
config I2C_SENSOR
tristate
depends on SENSORS_ADM1021 || SENSORS_LM75 || SENSORS_VIA686A || SENSORS_W83781D
default m
default y if SENSORS_ADM1021=y || SENSORS_LM75=y || SENSORS_VIA686A=y || SENSORS_W83781D=y
default m if SENSORS_ADM1021=m || SENSORS_LM75=m || SENSORS_VIA686A=m || SENSORS_W83781D=m
default n
endmenu
This diff is collapsed.
......@@ -364,7 +364,7 @@ static ssize_t show_##reg (struct device *dev, char *buf, int nr) \
\
w83781d_update_client(client); \
\
return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr])); \
return sprintf(buf,"%ld\n", (long)IN_FROM_REG(data->reg[nr] * 10)); \
}
show_in_reg(in);
show_in_reg(in_min);
......@@ -378,7 +378,7 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count
u32 val; \
\
val = simple_strtoul(buf, NULL, 10); \
data->in_##reg[nr] = IN_TO_REG(val); \
data->in_##reg[nr] = (IN_TO_REG(val) / 10); \
w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
\
return count; \
......@@ -712,7 +712,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83781d_data *data = i2c_get_clientdata(client);
u32 val, old, old2, old3;
u32 val, old, old2, old3 = 0;
val = simple_strtoul(buf, NULL, 10);
old = w83781d_read_value(client, W83781D_REG_VID_FANDIV);
......
......@@ -196,9 +196,11 @@ static struct i2c_algo_iic_data iic_ite_data = {
static struct i2c_adapter iic_ite_ops = {
.owner = THIS_MODULE,
.name = "ITE IIC adapter",
.id = I2C_HW_I_IIC,
.algo_data = &iic_ite_data,
.dev = {
.name = "ITE IIC adapter",
},
};
/* Called when the module is loaded. This function starts the
......
......@@ -77,7 +77,7 @@ static struct i2c_adapter *i2cdev_adaps[I2CDEV_ADAPS_MAX];
static struct i2c_driver i2cdev_driver = {
.owner = THIS_MODULE,
.name = "i2c-dev dummy driver",
.name = "dev driver",
.id = I2C_DRIVERID_I2CDEV,
.flags = I2C_DF_DUMMY,
.attach_adapter = i2cdev_attach_adapter,
......@@ -100,10 +100,6 @@ static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
char *tmp;
int ret;
#ifdef DEBUG
struct inode *inode = file->f_dentry->d_inode;
#endif /* DEBUG */
struct i2c_client *client = (struct i2c_client *)file->private_data;
if (count > 8192)
......@@ -114,10 +110,8 @@ static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
if (tmp==NULL)
return -ENOMEM;
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: i2c-%d reading %d bytes.\n",minor(inode->i_rdev),
count);
#endif
pr_debug("i2c-dev.o: i2c-%d reading %d bytes.\n",
minor(file->f_dentry->d_inode->i_rdev), count);
ret = i2c_master_recv(client,tmp,count);
if (ret >= 0)
......@@ -133,10 +127,6 @@ static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
char *tmp;
struct i2c_client *client = (struct i2c_client *)file->private_data;
#ifdef DEBUG
struct inode *inode = file->f_dentry->d_inode;
#endif /* DEBUG */
if (count > 8192)
count = 8192;
......@@ -149,10 +139,9 @@ static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
return -EFAULT;
}
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: i2c-%d writing %d bytes.\n",minor(inode->i_rdev),
count);
#endif
pr_debug("i2c-dev.o: i2c-%d writing %d bytes.\n",
minor(file->f_dentry->d_inode->i_rdev), count);
ret = i2c_master_send(client,tmp,count);
kfree(tmp);
return ret;
......@@ -169,10 +158,8 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
int i,datasize,res;
unsigned long funcs;
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
minor(inode->i_rdev),cmd, arg);
#endif /* DEBUG */
pr_debug("i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
minor(inode->i_rdev),cmd, arg);
switch ( cmd ) {
case I2C_SLAVE:
......@@ -207,6 +194,11 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
sizeof(rdwr_arg)))
return -EFAULT;
/* Put an arbritrary limit on the number of messages that can
* be sent at once */
if (rdwr_arg.nmsgs > 42)
return -EINVAL;
rdwr_pa = (struct i2c_msg *)
kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
GFP_KERNEL);
......@@ -214,38 +206,43 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
if (rdwr_pa == NULL) return -ENOMEM;
res = 0;
for( i=0; i<rdwr_arg.nmsgs; i++ )
{
for( i=0; i<rdwr_arg.nmsgs; i++ ) {
if(copy_from_user(&(rdwr_pa[i]),
&(rdwr_arg.msgs[i]),
sizeof(rdwr_pa[i])))
{
sizeof(rdwr_pa[i]))) {
res = -EFAULT;
break;
}
/* Limit the size of the message to a sane amount */
if (rdwr_pa[i].len > 8192) {
res = -EINVAL;
break;
}
rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
if(rdwr_pa[i].buf == NULL)
{
if(rdwr_pa[i].buf == NULL) {
res = -ENOMEM;
break;
}
if(copy_from_user(rdwr_pa[i].buf,
rdwr_arg.msgs[i].buf,
rdwr_pa[i].len))
{
kfree(rdwr_pa[i].buf);
rdwr_pa[i].len)) {
res = -EFAULT;
break;
}
}
if (!res)
{
if (res < 0) {
int j;
for (j = 0; j < i; ++j)
kfree(rdwr_pa[j].buf);
kfree(rdwr_pa);
return res;
}
if (!res) {
res = i2c_transfer(client->adapter,
rdwr_pa,
rdwr_arg.nmsgs);
}
while(i-- > 0)
{
while(i-- > 0) {
if( res>=0 && (rdwr_pa[i].flags & I2C_M_RD))
{
if(copy_to_user(
......@@ -274,20 +271,18 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
(data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
(data_arg.size != I2C_SMBUS_I2C_BLOCK_DATA) &&
(data_arg.size != I2C_SMBUS_BLOCK_PROC_CALL)) {
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: size out of range (%x) in ioctl I2C_SMBUS.\n",
data_arg.size);
#endif
dev_dbg(&client->dev,
"size out of range (%x) in ioctl I2C_SMBUS.\n",
data_arg.size);
return -EINVAL;
}
/* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
so the check is valid if size==I2C_SMBUS_QUICK too. */
if ((data_arg.read_write != I2C_SMBUS_READ) &&
(data_arg.read_write != I2C_SMBUS_WRITE)) {
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n",
data_arg.read_write);
#endif
dev_dbg(&client->dev,
"read_write out of range (%x) in ioctl I2C_SMBUS.\n",
data_arg.read_write);
return -EINVAL;
}
......@@ -298,15 +293,14 @@ int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
(data_arg.read_write == I2C_SMBUS_WRITE)))
/* These are special: we do not use data */
return i2c_smbus_xfer(client->adapter, client->addr,
client->flags,
data_arg.read_write,
data_arg.command,
data_arg.size, NULL);
client->flags,
data_arg.read_write,
data_arg.command,
data_arg.size, NULL);
if (data_arg.data == NULL) {
#ifdef DEBUG
printk(KERN_DEBUG "i2c-dev.o: data is NULL pointer in ioctl I2C_SMBUS.\n");
#endif
dev_dbg(&client->dev,
"data is NULL pointer in ioctl I2C_SMBUS.\n");
return -EINVAL;
}
......@@ -365,7 +359,7 @@ static int i2cdev_open(struct inode *inode, struct file *file)
return 0;
out_kfree:
out_kfree:
kfree(client);
return -ENODEV;
}
......@@ -428,7 +422,8 @@ int __init i2c_dev_init(void)
{
int res;
printk(KERN_INFO "i2c-dev.o: i2c /dev entries driver module version %s (%s)\n", I2C_VERSION, I2C_DATE);
printk(KERN_INFO "i2c /dev entries driver module version %s (%s)\n",
I2C_VERSION, I2C_DATE);
if (register_chrdev(I2C_MAJOR,"i2c",&i2cdev_fops)) {
printk(KERN_ERR "i2c-dev.o: unable to get major %d for i2c bus\n",
......
......@@ -59,9 +59,11 @@ static struct i2c_algo_bit_data bit_frodo_data = {
static struct i2c_adapter frodo_ops = {
.owner = THIS_MODULE,
.name = "Frodo adapter driver",
.id = I2C_HW_B_FRODO,
.algo_data = &bit_frodo_data,
.dev = {
.name = "Frodo adapter driver",
},
};
static int __init i2c_frodo_init (void)
......
This diff is collapsed.
#ifndef __I2C_KEYWEST_H__
#define __I2C_KEYWEST_H__
/* The Tumbler audio equalizer can be really slow sometimes */
#define POLL_TIMEOUT (2*HZ)
/* Register indices */
typedef enum {
reg_mode = 0,
reg_control,
reg_status,
reg_isr,
reg_ier,
reg_addr,
reg_subaddr,
reg_data
} reg_t;
/* Mode register */
#define KW_I2C_MODE_100KHZ 0x00
#define KW_I2C_MODE_50KHZ 0x01
#define KW_I2C_MODE_25KHZ 0x02
#define KW_I2C_MODE_DUMB 0x00
#define KW_I2C_MODE_STANDARD 0x04
#define KW_I2C_MODE_STANDARDSUB 0x08
#define KW_I2C_MODE_COMBINED 0x0C
#define KW_I2C_MODE_MODE_MASK 0x0C
#define KW_I2C_MODE_CHAN_MASK 0xF0
/* Control register */
#define KW_I2C_CTL_AAK 0x01
#define KW_I2C_CTL_XADDR 0x02
#define KW_I2C_CTL_STOP 0x04
#define KW_I2C_CTL_START 0x08
/* Status register */
#define KW_I2C_STAT_BUSY 0x01
#define KW_I2C_STAT_LAST_AAK 0x02
#define KW_I2C_STAT_LAST_RW 0x04
#define KW_I2C_STAT_SDA 0x08
#define KW_I2C_STAT_SCL 0x10
/* IER & ISR registers */
#define KW_I2C_IRQ_DATA 0x01
#define KW_I2C_IRQ_ADDR 0x02
#define KW_I2C_IRQ_STOP 0x04
#define KW_I2C_IRQ_START 0x08
#define KW_I2C_IRQ_MASK 0x0F
/* Physical interface */
struct keywest_iface
{
unsigned long base;
unsigned bsteps;
int irq;
struct semaphore sem;
spinlock_t lock;
struct keywest_chan* channels;
unsigned chan_count;
u8 cur_mode;
char read_write;
u8* data;
unsigned datalen;
int state;
int result;
int stopretry;
struct timer_list timeout_timer;
struct completion complete;
struct keywest_iface* next;
};
enum {
state_idle,
state_addr,
state_read,
state_write,
state_stop,
state_dead
};
/* Channel on an interface */
struct keywest_chan
{
struct i2c_adapter adapter;
struct keywest_iface* iface;
unsigned chan_no;
};
/* Register access */
static inline u8 __read_reg(struct keywest_iface *iface, reg_t reg)
{
return in_8(((volatile u8 *)iface->base)
+ (((unsigned)reg) << iface->bsteps));
}
static inline void __write_reg(struct keywest_iface *iface, reg_t reg, u8 val)
{
out_8(((volatile u8 *)iface->base)
+ (((unsigned)reg) << iface->bsteps), val);
(void)__read_reg(iface, reg);
udelay(10);
}
#define write_reg(reg, val) __write_reg(iface, reg, val)
#define read_reg(reg) __read_reg(iface, reg)
#endif /* __I2C_KEYWEST_H__ */
......@@ -82,9 +82,11 @@ static struct i2c_algo_bit_data scx200_i2c_data = {
static struct i2c_adapter scx200_i2c_ops = {
.owner = THIS_MODULE,
.name = "NatSemi SCx200 I2C",
.id = I2C_HW_B_VELLE,
.algo_data = &scx200_i2c_data,
.dev = {
.name = "NatSemi SCx200 I2C",
},
};
int scx200_i2c_init(void)
......@@ -110,7 +112,7 @@ int scx200_i2c_init(void)
if (i2c_bit_add_bus(&scx200_i2c_ops) < 0) {
printk(KERN_ERR NAME ": adapter %s registration failed\n",
scx200_i2c_ops.name);
scx200_i2c_ops.dev.name);
return -ENODEV;
}
......
......@@ -18,7 +18,8 @@
*/
#include <linux/string.h>
#include <linux/module.h> /* needed for MODULE_PARM */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include "ieee1394_types.h"
#include "hosts.h"
......@@ -27,9 +28,10 @@
/* Module Parameters */
/* this module parameter can be used to disable mapping of the FCP registers */
MODULE_PARM(fcp,"i");
MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0).");
static int fcp = 1;
module_param(fcp, int, 0444);
MODULE_PARM_DESC(fcp, "Map FCP registers (default = 1, disable = 0).");
static u16 csr_crc16(unsigned *data, int length)
{
......
......@@ -2919,11 +2919,7 @@ static int __init dv1394_init_module(void)
}
#ifdef CONFIG_DEVFS_FS
if (!devfs_mk_dir("ieee1394/dv")) {
printk(KERN_ERR "dv1394: unable to create /dev/ieee1394/dv\n");
ieee1394_unregister_chardev(IEEE1394_MINOR_BLOCK_DV1394);
return -ENOMEM;
}
devfs_mk_dir("ieee1394/dv");
#endif
#ifdef CONFIG_PROC_FS
......
......@@ -57,7 +57,8 @@ struct hpsb_highlevel *hpsb_register_highlevel(const char *name,
list_add_tail(&hl->hl_list, &hl_drivers);
up(&hl_drivers_lock);
hl_all_hosts(hl->op->add_host);
if (hl->op->add_host)
hl_all_hosts(hl->op->add_host);
return hl;
}
......@@ -98,6 +99,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
struct hpsb_address_serve *as;
struct list_head *entry;
int retval = 0;
unsigned long flags;
if (((start|end) & 3) || (start >= end) || (end > 0x1000000000000ULL)) {
HPSB_ERR("%s called with invalid addresses", __FUNCTION__);
......@@ -116,7 +118,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
as->start = start;
as->end = end;
write_lock_irq(&addr_space_lock);
write_lock_irqsave(&addr_space_lock, flags);
entry = addr_space.next;
while (list_entry(entry, struct hpsb_address_serve, as_list)->end <= start) {
......@@ -128,7 +130,7 @@ int hpsb_register_addrspace(struct hpsb_highlevel *hl,
}
entry = entry->next;
}
write_unlock_irq(&addr_space_lock);
write_unlock_irqrestore(&addr_space_lock, flags);
if (retval == 0) {
kfree(as);
......@@ -142,8 +144,9 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
int retval = 0;
struct hpsb_address_serve *as;
struct list_head *entry;
unsigned long flags;
write_lock_irq(&addr_space_lock);
write_lock_irqsave(&addr_space_lock, flags);
entry = hl->addr_list.next;
......@@ -159,7 +162,7 @@ int hpsb_unregister_addrspace(struct hpsb_highlevel *hl, u64 start)
}
}
write_unlock_irq(&addr_space_lock);
write_unlock_irqrestore(&addr_space_lock, flags);
return retval;
}
......@@ -202,7 +205,8 @@ void highlevel_add_host(struct hpsb_host *host)
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
hl->op->add_host(host);
if (hl->op->add_host)
hl->op->add_host(host);
}
up(&hl_drivers_lock);
}
......@@ -237,48 +241,40 @@ void highlevel_host_reset(struct hpsb_host *host)
up(&hl_drivers_lock);
}
void highlevel_iso_receive(struct hpsb_host *host, quadlet_t *data,
void highlevel_iso_receive(struct hpsb_host *host, void *data,
unsigned int length)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
int channel = (data[0] >> 8) & 0x3f;
int channel = (((quadlet_t *)data)[0] >> 8) & 0x3f;
down(&hl_drivers_lock);
entry = hl_drivers.next;
while (entry != &hl_drivers) {
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->iso_receive) {
if (hl->op->iso_receive)
hl->op->iso_receive(host, channel, data, length);
}
entry = entry->next;
}
up(&hl_drivers_lock);
}
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
u8 *data, unsigned int length)
void *data, unsigned int length)
{
struct list_head *entry;
struct hpsb_highlevel *hl;
int cts = data[0] >> 4;
int cts = ((quadlet_t *)data)[0] >> 4;
down(&hl_drivers_lock);
entry = hl_drivers.next;
while (entry != &hl_drivers) {
list_for_each(entry, &hl_drivers) {
hl = list_entry(entry, struct hpsb_highlevel, hl_list);
if (hl->op->fcp_request) {
hl->op->fcp_request(host, nodeid, direction, cts, data,
length);
}
entry = entry->next;
if (hl->op->fcp_request)
hl->op->fcp_request(host, nodeid, direction, cts, data, length);
}
up(&hl_drivers_lock);
}
int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
u64 addr, unsigned int length, u16 flags)
{
struct hpsb_address_serve *as;
......@@ -295,13 +291,14 @@ int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
if (as->end > addr) {
partlength = min(as->end - addr, (u64) length);
if (as->op->read != NULL) {
rcode = as->op->read(host, nodeid, buffer,
if (as->op->read) {
rcode = as->op->read(host, nodeid, data,
addr, partlength, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
(u8 *)data += partlength;
length -= partlength;
addr += partlength;
......@@ -324,7 +321,7 @@ int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
}
int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length, u16 flags)
void *data, u64 addr, unsigned int length, u16 flags)
{
struct hpsb_address_serve *as;
struct list_head *entry;
......@@ -340,13 +337,14 @@ int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
if (as->end > addr) {
partlength = min(as->end - addr, (u64) length);
if (as->op->write != NULL) {
if (as->op->write) {
rcode = as->op->write(host, nodeid, destid,
data, addr, partlength, flags);
} else {
rcode = RCODE_TYPE_ERROR;
}
(u8 *)data += partlength;
length -= partlength;
addr += partlength;
......@@ -383,7 +381,7 @@ int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
while (as->start <= addr) {
if (as->end > addr) {
if (as->op->lock != NULL) {
if (as->op->lock) {
rcode = as->op->lock(host, nodeid, store, addr,
data, arg, ext_tcode, flags);
} else {
......@@ -416,7 +414,7 @@ int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
while (as->start <= addr) {
if (as->end > addr) {
if (as->op->lock64 != NULL) {
if (as->op->lock64) {
rcode = as->op->lock64(host, nodeid, store,
addr, data, arg,
ext_tcode, flags);
......
......@@ -108,19 +108,19 @@ void highlevel_host_reset(struct hpsb_host *host);
later case, no response will be sent and the driver, that handled the request
will send the response itself.
*/
int highlevel_read(struct hpsb_host *host, int nodeid, quadlet_t *buffer,
int highlevel_read(struct hpsb_host *host, int nodeid, void *data,
u64 addr, unsigned int length, u16 flags);
int highlevel_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length, u16 flags);
void *data, u64 addr, unsigned int length, u16 flags);
int highlevel_lock(struct hpsb_host *host, int nodeid, quadlet_t *store,
u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, u16 flags);
int highlevel_lock64(struct hpsb_host *host, int nodeid, octlet_t *store,
u64 addr, octlet_t data, octlet_t arg, int ext_tcode, u16 flags);
void highlevel_iso_receive(struct hpsb_host *host, quadlet_t *data,
void highlevel_iso_receive(struct hpsb_host *host, void *data,
unsigned int length);
void highlevel_fcp_request(struct hpsb_host *host, int nodeid, int direction,
u8 *data, unsigned int length);
void *data, unsigned int length);
/*
......
#ifndef _IEEE1394_HOSTS_H
#define _IEEE1394_HOSTS_H
#include <linux/device.h>
#include <linux/wait.h>
#include <linux/list.h>
#include <asm/semaphore.h>
......@@ -64,6 +65,8 @@ struct hpsb_host {
struct hpsb_host_driver *driver;
struct pci_dev *pdev;
struct device device;
};
......
......@@ -46,9 +46,13 @@
#define ACKX_TIMEOUT (-4)
#define SPEED_100 0x0
#define SPEED_200 0x1
#define SPEED_400 0x2
#define SPEED_100 0x00
#define SPEED_200 0x01
#define SPEED_400 0x02
#define SPEED_800 0x03
#define SPEED_1600 0x04
#define SPEED_3200 0x05
/* Maps speed values above to a string representation */
extern const char *hpsb_speedto_str[];
......
......@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
......@@ -48,13 +49,9 @@
/*
* Disable the nodemgr detection and config rom reading functionality.
*/
MODULE_PARM(disable_nodemgr, "i");
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
static int disable_nodemgr = 0;
MODULE_PARM(disable_hotplug, "i");
MODULE_PARM_DESC(disable_hotplug, "Disable hotplug for detected nodes.");
static int disable_hotplug = 0;
module_param(disable_nodemgr, int, 0444);
MODULE_PARM_DESC(disable_nodemgr, "Disable nodemgr functionality.");
/* We are GPL, so treat us special */
MODULE_LICENSE("GPL");
......@@ -62,7 +59,7 @@ MODULE_LICENSE("GPL");
static kmem_cache_t *hpsb_packet_cache;
/* Some globals used */
const char *hpsb_speedto_str[] = { "S100", "S200", "S400" };
const char *hpsb_speedto_str[] = { "S100", "S200", "S400", "S800", "S1600", "S3200" };
static void dump_packet(const char *text, quadlet_t *data, int size)
{
......@@ -130,9 +127,8 @@ struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
{
struct hpsb_packet *packet = NULL;
void *data = NULL;
int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
packet = kmem_cache_alloc(hpsb_packet_cache, kmflags);
packet = kmem_cache_alloc(hpsb_packet_cache, GFP_ATOMIC);
if (packet == NULL)
return NULL;
......@@ -140,7 +136,7 @@ struct hpsb_packet *alloc_hpsb_packet(size_t data_size)
packet->header = packet->embedded_header;
if (data_size) {
data = kmalloc(data_size + 8, kmflags);
data = kmalloc(data_size + 8, GFP_ATOMIC);
if (data == NULL) {
kmem_cache_free(hpsb_packet_cache, packet);
return NULL;
......@@ -496,8 +492,7 @@ int hpsb_send_packet(struct hpsb_packet *packet)
quadlet_t *data;
size_t size=packet->data_size+packet->header_size;
int kmflags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
data = kmalloc(packet->header_size + packet->data_size, kmflags);
data = kmalloc(packet->header_size + packet->data_size, GFP_ATOMIC);
if (!data) {
HPSB_ERR("unable to allocate memory for concatenating header and data");
return 0;
......@@ -1120,7 +1115,7 @@ static int ieee1394_dispatch_open(struct inode *inode, struct file *file)
/* follow through with the open() */
retval = file_ops->open(inode, file);
if(retval == 0) {
if (retval == 0) {
/* If the open() succeeded, then ieee1394 will be left
* with an extra module reference, so we discard it here.
......@@ -1166,7 +1161,7 @@ static int __init ieee1394_init(void)
#ifdef CONFIG_PROC_FS
/* Must be done before we start everything else, since the drivers
* may use it. */
ieee1394_procfs_entry = proc_mkdir( "ieee1394", proc_bus);
ieee1394_procfs_entry = proc_mkdir("ieee1394", proc_bus);
if (ieee1394_procfs_entry == NULL) {
HPSB_ERR("unable to create /proc/bus/ieee1394\n");
unregister_chrdev(IEEE1394_MAJOR, "ieee1394");
......@@ -1179,7 +1174,7 @@ static int __init ieee1394_init(void)
init_hpsb_highlevel();
init_csr();
if (!disable_nodemgr)
init_ieee1394_nodemgr(disable_hotplug);
init_ieee1394_nodemgr();
else
HPSB_INFO("nodemgr functionality disabled");
......@@ -1273,7 +1268,7 @@ EXPORT_SYMBOL(hpsb_node_write);
EXPORT_SYMBOL(hpsb_node_lock);
EXPORT_SYMBOL(hpsb_register_protocol);
EXPORT_SYMBOL(hpsb_unregister_protocol);
EXPORT_SYMBOL(hpsb_release_unit_directory);
EXPORT_SYMBOL(ieee1394_bus_type);
/** csr.c **/
EXPORT_SYMBOL(hpsb_update_config_rom);
......
......@@ -231,4 +231,7 @@ extern devfs_handle_t ieee1394_devfs_handle;
/* the proc_fs entry for /proc/ieee1394 */
extern struct proc_dir_entry *ieee1394_procfs_entry;
/* Our sysfs bus entry */
extern struct bus_type ieee1394_bus_type;
#endif /* _IEEE1394_CORE_H */
#ifndef _IEEE1394_HOTPLUG_H
#define _IEEE1394_HOTPLUG_H
#include <linux/device.h>
#include "ieee1394_core.h"
#include "nodemgr.h"
......@@ -31,26 +33,6 @@ struct hpsb_protocol_driver {
*/
struct ieee1394_device_id *id_table;
/*
* The probe function is called when a device is added to the
* bus and the nodemgr finds a matching entry in the drivers
* device id table or when registering this driver and a
* previously unhandled device can be handled. The driver may
* decline to handle the device based on further investigation
* of the device (or whatever reason) in which case a negative
* error code should be returned, otherwise 0 should be
* returned. The driver may use the driver_data field in the
* unit directory to store per device driver specific data.
*/
int (*probe)(struct unit_directory *ud);
/*
* The disconnect function is called when a device is removed
* from the bus or if it wasn't possible to read the guid
* after the last bus reset.
*/
void (*disconnect)(struct unit_directory *ud);
/*
* The update function is called when the node has just
* survived a bus reset, i.e. it is still present on the bus.
......@@ -59,18 +41,12 @@ struct hpsb_protocol_driver {
*/
void (*update)(struct unit_directory *ud);
/* Driver in list of all registered drivers */
struct list_head list;
/* The list of unit directories managed by this driver */
struct list_head unit_directories;
/* Our LDM structure */
struct device_driver driver;
};
int hpsb_register_protocol(struct hpsb_protocol_driver *driver);
void hpsb_unregister_protocol(struct hpsb_protocol_driver *driver);
int hpsb_claim_unit_directory(struct unit_directory *ud,
struct hpsb_protocol_driver *driver);
void hpsb_release_unit_directory(struct unit_directory *ud);
#endif /* _IEEE1394_HOTPLUG_H */
......@@ -146,10 +146,10 @@ int hpsb_get_tlabel(struct hpsb_packet *packet, int wait)
spin_lock_irqsave(&tp->lock, flags);
packet->tlabel = find_next_zero_bit(&tp->pool, 64, tp->next);
packet->tlabel = find_next_zero_bit(tp->pool, 64, tp->next);
tp->next = (packet->tlabel + 1) % 64;
/* Should _never_ happen */
BUG_ON(test_and_set_bit(packet->tlabel, &tp->pool));
BUG_ON(test_and_set_bit(packet->tlabel, tp->pool));
tp->allocations++;
spin_unlock_irqrestore(&tp->lock, flags);
......@@ -177,7 +177,7 @@ void hpsb_free_tlabel(struct hpsb_packet *packet)
BUG_ON(packet->tlabel > 63 || packet->tlabel < 0);
spin_lock_irqsave(&tp->lock, flags);
BUG_ON(!test_and_clear_bit(packet->tlabel, &tp->pool));
BUG_ON(!test_and_clear_bit(packet->tlabel, tp->pool));
spin_unlock_irqrestore(&tp->lock, flags);
up(&tp->count);
......
......@@ -72,19 +72,20 @@
/* Transaction Label handling */
struct hpsb_tlabel_pool {
u64 pool;
DECLARE_BITMAP(pool, 64);
spinlock_t lock;
u8 next;
u32 allocations;
struct semaphore count;
};
#define HPSB_TPOOL_INIT(_tp) \
do { \
sema_init(&(_tp)->count, 63); \
spin_lock_init(&(_tp)->lock); \
(_tp)->next = 0; \
(_tp)->pool = 0; \
#define HPSB_TPOOL_INIT(_tp) \
do { \
CLEAR_BITMAP((_tp)->pool, 64); \
spin_lock_init(&(_tp)->lock); \
(_tp)->next = 0; \
(_tp)->allocations = 0; \
sema_init(&(_tp)->count, 63); \
} while(0)
......
......@@ -14,7 +14,7 @@
void hpsb_iso_stop(struct hpsb_iso *iso)
{
if(!iso->flags & HPSB_ISO_DRIVER_STARTED)
if (!(iso->flags & HPSB_ISO_DRIVER_STARTED))
return;
iso->host->driver->isoctl(iso, iso->type == HPSB_ISO_XMIT ?
......
This diff is collapsed.
......@@ -20,6 +20,8 @@
#ifndef _IEEE1394_NODEMGR_H
#define _IEEE1394_NODEMGR_H
#include <linux/device.h>
#define CONFIG_ROM_BUS_INFO_LENGTH(q) ((q) >> 24)
#define CONFIG_ROM_BUS_CRC_LENGTH(q) (((q) >> 16) & 0xff)
#define CONFIG_ROM_BUS_CRC(q) ((q) & 0xffff)
......@@ -76,6 +78,12 @@ struct bus_options {
u16 max_rec; /* Maximum packet size node can receive */
};
enum {
DEV_CLASS_NODE,
DEV_CLASS_UNIT_DIRECTORY,
DEV_CLASS_HOST,
};
#define UNIT_DIRECTORY_VENDOR_ID 0x01
#define UNIT_DIRECTORY_MODEL_ID 0x02
#define UNIT_DIRECTORY_SPECIFIER_ID 0x04
......@@ -87,18 +95,16 @@ struct bus_options {
* A unit directory corresponds to a protocol supported by the
* node. If a node supports eg. IP/1394 and AV/C, its config rom has a
* unit directory for each of these protocols.
*
* Unit directories appear on two types of lists: for each node we
* maintain a list of the unit directories found in its config rom and
* for each driver we maintain a list of the unit directories
* (ie. devices) the driver manages.
*/
struct unit_directory {
struct node_entry *ne; /* The node which this directory belongs to */
octlet_t address; /* Address of the unit directory on the node */
u8 flags; /* Indicates which entries were read */
quadlet_t vendor_id;
const char *vendor_name;
const char *vendor_oui;
int vendor_name_size;
quadlet_t model_id;
const char *model_name;
......@@ -106,22 +112,21 @@ struct unit_directory {
quadlet_t specifier_id;
quadlet_t version;
struct hpsb_protocol_driver *driver;
void *driver_data;
unsigned int id;
/* For linking the nodes managed by the driver, or unmanaged nodes */
struct list_head driver_list;
int length; /* Number of quadlets */
/* For linking directories belonging to a node */
struct list_head node_list;
struct device device;
int count; /* Number of quadlets */
/* XXX Must be last in the struct! */
quadlet_t quadlets[0];
};
struct node_entry {
struct list_head list;
u64 guid; /* GUID of this node */
u32 guid_vendor_id; /* Top 24bits of guid */
const char *guid_vendor_oui; /* OUI name of guid vendor id */
struct hpsb_host *host; /* Host this node is attached to */
nodeid_t nodeid; /* NodeID */
struct bus_options busopt; /* Bus Options */
......@@ -129,14 +134,16 @@ struct node_entry {
/* The following is read from the config rom */
u32 vendor_id;
const char *vendor_name;
const char *vendor_oui;
u32 capabilities;
struct list_head unit_directories;
struct hpsb_tlabel_pool *tpool;
const char *vendor_name;
char *oui_name;
struct device device;
/* XXX Must be last in the struct! */
quadlet_t quadlets[0];
};
......@@ -154,11 +161,11 @@ struct node_entry *hpsb_guid_get_entry(u64 guid);
/* Same as above, but use the nodeid to get an node entry. This is not
* fool-proof by itself, since the nodeid can change. */
struct node_entry *hpsb_nodeid_get_entry(nodeid_t nodeid);
struct node_entry *hpsb_nodeid_get_entry(struct hpsb_host *host, nodeid_t nodeid);
/* Same as above except that it will not block waiting for the nodemgr
* serialize semaphore. */
struct node_entry *hpsb_check_nodeid(nodeid_t nodeid);
struct node_entry *hpsb_check_nodeid(struct hpsb_host *host, nodeid_t nodeid);
/*
* If the entry refers to a local host, this function will return the pointer
......@@ -188,7 +195,7 @@ int hpsb_node_lock(struct node_entry *ne, u64 addr,
int extcode, quadlet_t *data, quadlet_t arg);
void init_ieee1394_nodemgr(int disable_hotplug);
void init_ieee1394_nodemgr(void);
void cleanup_ieee1394_nodemgr(void);
#endif /* _IEEE1394_NODEMGR_H */
......@@ -80,6 +80,10 @@
* Manfred Weihs <weihs@ict.tuwien.ac.at>
* . Reworked code for initiating bus resets
* (long, short, with or without hold-off)
*
* Nandu Santhi <contactnandu@users.sourceforge.net>
* . Added support for nVidia nForce2 onboard Firewire chipset
*
*/
#include <linux/config.h>
......@@ -90,6 +94,7 @@
#include <linux/wait.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h>
#include <linux/fs.h>
#include <linux/poll.h>
......@@ -145,7 +150,7 @@ printk(KERN_INFO "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
#define OHCI_DMA_FREE(fmt, args...) \
HPSB_ERR("%s(%s)free(%d): "fmt, OHCI1394_DRIVER_NAME, __FUNCTION__, \
--global_outstanding_dmas, ## args)
u32 global_outstanding_dmas = 0;
static int global_outstanding_dmas = 0;
#else
#define OHCI_DMA_ALLOC(fmt, args...)
#define OHCI_DMA_FREE(fmt, args...)
......@@ -160,12 +165,12 @@ printk(level "%s: " fmt "\n" , OHCI1394_DRIVER_NAME , ## args)
printk(level "%s_%d: " fmt "\n" , OHCI1394_DRIVER_NAME, card , ## args)
static char version[] __devinitdata =
"$Rev: 801 $ Ben Collins <bcollins@debian.org>";
"$Rev: 858 $ Ben Collins <bcollins@debian.org>";
/* Module Parameters */
MODULE_PARM(phys_dma,"i");
MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
static int phys_dma = 1;
module_param(phys_dma, int, 0644);
MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1).");
static void dma_trm_tasklet(unsigned long data);
static void dma_trm_reset(struct dma_trm_ctx *d);
......@@ -354,10 +359,10 @@ static void handle_selfid(struct ti_ohci *ohci, struct hpsb_host *host,
static void ohci_soft_reset(struct ti_ohci *ohci) {
int i;
reg_write(ohci, OHCI1394_HCControlSet, 0x00010000);
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_softReset);
for (i = 0; i < OHCI_LOOP_COUNT; i++) {
if (reg_read(ohci, OHCI1394_HCControlSet) & 0x00010000)
if (!reg_read(ohci, OHCI1394_HCControlSet) & OHCI1394_HCControl_softReset)
break;
mdelay(1);
}
......@@ -514,7 +519,7 @@ static void ohci_initialize(struct ti_ohci *ohci)
reg_write(ohci, OHCI1394_NodeID, 0x0000ffc0);
/* Enable posted writes */
reg_write(ohci, OHCI1394_HCControlSet, 0x00040000);
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_postedWriteEnable);
/* Clear link control register */
reg_write(ohci, OHCI1394_LinkControlClear, 0xffffffff);
......@@ -577,7 +582,7 @@ static void ohci_initialize(struct ti_ohci *ohci)
(OHCI1394_MAX_PHYS_RESP_RETRIES<<8));
/* We don't want hardware swapping */
reg_write(ohci, OHCI1394_HCControlClear, 0x40000000);
reg_write(ohci, OHCI1394_HCControlClear, OHCI1394_HCControl_noByteSwap);
/* Enable interrupts */
reg_write(ohci, OHCI1394_IntMaskSet,
......@@ -594,7 +599,7 @@ static void ohci_initialize(struct ti_ohci *ohci)
OHCI1394_cycleInconsistent);
/* Enable link */
reg_write(ohci, OHCI1394_HCControlSet, 0x00020000);
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_linkEnable);
buf = reg_read(ohci, OHCI1394_Version);
PRINT(KERN_INFO, ohci->id, "OHCI-1394 %d.%d (PCI): IRQ=[%d] "
......@@ -1190,10 +1195,11 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso)
/* iso->irq_interval is in packets - translate that to blocks */
/* (err, sort of... 1 is always the safest value) */
recv->block_irq_interval = iso->irq_interval / recv->nblocks;
if(recv->block_irq_interval*4 > recv->nblocks)
recv->block_irq_interval = recv->nblocks/4;
if(recv->block_irq_interval < 1)
recv->block_irq_interval = 1;
else if(recv->block_irq_interval*4 > recv->nblocks)
recv->block_irq_interval = recv->nblocks/4;
} else {
int max_packet_size;
......@@ -2291,17 +2297,35 @@ static void ohci_irq_handler(int irq, void *dev_id,
* selfID phase, so we disable busReset interrupts, to
* avoid burying the cpu in interrupt requests. */
spin_lock_irqsave(&ohci->event_lock, flags);
reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
if (ohci->dev->vendor == PCI_VENDOR_ID_APPLE &&
ohci->dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) {
udelay(10);
while(reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
reg_write(ohci, OHCI1394_IntMaskClear, OHCI1394_busReset);
if (ohci->check_busreset) {
int loop_count = 0;
udelay(10);
while (reg_read(ohci, OHCI1394_IntEventSet) & OHCI1394_busReset) {
reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_busReset);
spin_unlock_irqrestore(&ohci->event_lock, flags);
udelay(10);
udelay(10);
spin_lock_irqsave(&ohci->event_lock, flags);
}
}
/* The loop counter check is to prevent the driver
* from remaining in this state forever. For the
* initial bus reset, the loop continues for ever
* and the system hangs, until some device is plugged-in
* or out manually into a port! The forced reset seems
* to solve this problem. This mainly effects nForce2. */
if (loop_count > 10000) {
hpsb_reset_bus(host, 1);
DBGMSG(ohci->id, "Detected bus-reset loop. Forced a bus reset!");
loop_count = 0;
}
loop_count++;
}
}
spin_unlock_irqrestore(&ohci->event_lock, flags);
if (!host->in_bus_reset) {
DBGMSG(ohci->id, "irq_handler: Bus reset requested");
......@@ -2438,6 +2462,8 @@ static void ohci_irq_handler(int irq, void *dev_id,
if (event)
PRINT(KERN_ERR, ohci->id, "Unhandled interrupt(s) 0x%08x",
event);
return;
}
/* Put the buffer back into the dma context */
......@@ -3277,6 +3303,18 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
ohci->selfid_swap = 1;
#endif
#ifndef PCI_DEVICE_ID_NVIDIA_NFORCE2_FW
#define PCI_DEVICE_ID_NVIDIA_NFORCE2_FW 0x006e
#endif
/* These chipsets require a bit of extra care when checking after
* a busreset. */
if ((dev->vendor == PCI_VENDOR_ID_APPLE &&
dev->device == PCI_DEVICE_ID_APPLE_UNI_N_FW) ||
(dev->vendor == PCI_VENDOR_ID_NVIDIA &&
dev->device == PCI_DEVICE_ID_NVIDIA_NFORCE2_FW))
ohci->check_busreset = 1;
/* We hardwire the MMIO length, since some CardBus adaptors
* fail to report the right length. Anyway, the ohci spec
* clearly says it's 2kb, so this shouldn't be a problem. */
......@@ -3363,7 +3401,7 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev,
* accessing registers in the SClk domain without LPS enabled
* will lock up the machine. Wait 50msec to make sure we have
* full link enabled. */
reg_write(ohci, OHCI1394_HCControlSet, 0x00080000);
reg_write(ohci, OHCI1394_HCControlSet, OHCI1394_HCControl_LPS);
mdelay(50);
/* Determine the number of available IR and IT contexts. */
......@@ -3489,7 +3527,7 @@ static void ohci1394_pci_remove(struct pci_dev *pdev)
static struct pci_device_id ohci1394_pci_tbl[] __devinitdata = {
{
.class = PCI_CLASS_FIREWIRE_OHCI,
.class_mask = ~0,
.class_mask = PCI_ANY_ID,
.vendor = PCI_ANY_ID,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
......
......@@ -233,6 +233,9 @@ struct ti_ohci {
unsigned int selfid_swap:1;
/* Some Apple chipset seem to swap incoming headers for us */
unsigned int no_swap_incoming:1;
/* Force extra paranoia checking on bus-reset handling */
unsigned int check_busreset:1;
};
static inline int cross_bound(unsigned long addr, unsigned int size)
......@@ -288,6 +291,13 @@ static inline u32 reg_read(const struct ti_ohci *ohci, int offset)
#define OHCI1394_VendorID 0x040
#define OHCI1394_HCControlSet 0x050
#define OHCI1394_HCControlClear 0x054
#define OHCI1394_HCControl_noByteSwap 0x40000000
#define OHCI1394_HCControl_programPhyEnable 0x00800000
#define OHCI1394_HCControl_aPhyEnhanceEnable 0x00400000
#define OHCI1394_HCControl_LPS 0x00080000
#define OHCI1394_HCControl_postedWriteEnable 0x00040000
#define OHCI1394_HCControl_linkEnable 0x00020000
#define OHCI1394_HCControl_softReset 0x00010000
#define OHCI1394_SelfIDBuffer 0x064
#define OHCI1394_SelfIDCount 0x068
#define OHCI1394_IRMultiChanMaskHiSet 0x070
......
......@@ -37,6 +37,7 @@
#include <linux/wait.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/fs.h>
......@@ -71,8 +72,8 @@
/* Module Parameters */
MODULE_PARM(skip_eeprom,"i");
MODULE_PARM_DESC(skip_eeprom, "Do not try to read bus info block from serial eeprom, but user generic one (default = 0).");
module_param(skip_eeprom, int, 0444);
MODULE_PARM_DESC(skip_eeprom, "Use generic bus info block instead of serial eeprom (default = 0).");
static int skip_eeprom = 0;
......@@ -983,8 +984,9 @@ loff_t mem_llseek(struct file *file, loff_t offs, int orig)
* on performance - the value 2400 was found by experiment and may not work
* everywhere as good as here - use mem_mindma option for modules to change
*/
short mem_mindma = 2400;
MODULE_PARM(mem_mindma, "h");
static short mem_mindma = 2400;
module_param(mem_mindma, short, 0444);
MODULE_PARM_DESC(mem_mindma, "Minimum amount of data required to use DMA");
static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count,
int offset)
......
This diff is collapsed.
......@@ -238,7 +238,7 @@ struct sbp2_status_block {
*/
#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
#define SBP2SCSI_MAX_SCSI_IDS 16 /* Max sbp2 device instances supported */
#define SBP2SCSI_MAX_SCSI_IDS 32 /* Max sbp2 device instances supported */
#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
#ifndef TYPE_SDAD
......@@ -320,6 +320,10 @@ struct sbp2_command_info {
#define SBP2_BREAKAGE_128K_MAX_TRANSFER 0x1
#define SBP2_BREAKAGE_INQUIRY_HACK 0x2
struct sbp2scsi_host_info;
/*
* Information needed on a per scsi id basis (one for each sbp2 device)
*/
......@@ -375,6 +379,9 @@ struct scsi_id_instance_data {
/* Node entry, as retrieved from NodeMgr entries */
struct node_entry *ne;
/* A backlink to our host_info */
struct sbp2scsi_host_info *hi;
/* Device specific workarounds/brokeness */
u32 workarounds;
};
......@@ -406,7 +413,6 @@ struct sbp2scsi_host_info {
* SCSI ID instance data (one for each sbp2 device instance possible)
*/
struct scsi_id_instance_data *scsi_id[SBP2SCSI_MAX_SCSI_IDS];
};
/*
......@@ -416,30 +422,30 @@ struct sbp2scsi_host_info {
/*
* Various utility prototypes
*/
static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_id, struct sbp2scsi_host_info *hi);
static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_id, struct sbp2scsi_host_info *hi);
static int sbp2util_create_command_orb_pool(struct scsi_id_instance_data *scsi_id);
static void sbp2util_remove_command_orb_pool(struct scsi_id_instance_data *scsi_id);
static struct sbp2_command_info *sbp2util_find_command_for_orb(struct scsi_id_instance_data *scsi_id, dma_addr_t orb);
static struct sbp2_command_info *sbp2util_find_command_for_SCpnt(struct scsi_id_instance_data *scsi_id, void *SCpnt);
static struct sbp2_command_info *sbp2util_allocate_command_orb(struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *Current_SCpnt,
void (*Current_done)(Scsi_Cmnd *),
struct sbp2scsi_host_info *hi);
void (*Current_done)(Scsi_Cmnd *));
static void sbp2util_mark_command_completed(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command);
/*
* IEEE-1394 core driver related prototypes
*/
static void sbp2_add_host(struct hpsb_host *host);
static struct sbp2scsi_host_info *sbp2_add_host(struct hpsb_host *host);
static struct sbp2scsi_host_info *sbp2_find_host_info(struct hpsb_host *host);
static void sbp2_remove_host(struct hpsb_host *host);
static int sbp2_probe(struct unit_directory *ud);
static void sbp2_disconnect(struct unit_directory *ud);
static int sbp2_probe(struct device *dev);
static int sbp2_remove(struct device *dev);
static void sbp2_update(struct unit_directory *ud);
static int sbp2_start_device(struct sbp2scsi_host_info *hi,
struct unit_directory *ud);
static void sbp2_remove_device(struct sbp2scsi_host_info *hi,
struct scsi_id_instance_data *scsi_id);
static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id);
#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
static int sbp2_handle_physdma_write(struct hpsb_host *host, int nodeid, int destid, quadlet_t *data,
......@@ -451,29 +457,28 @@ static int sbp2_handle_physdma_read(struct hpsb_host *host, int nodeid, quadlet_
/*
* SBP-2 protocol related prototypes
*/
static int sbp2_login_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_reconnect_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_logout_device(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_login_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id);
static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid,
quadlet_t *data, u64 addr, unsigned int length, u16 flags);
static int sbp2_agent_reset(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id, int wait);
static int sbp2_create_command_orb(struct sbp2scsi_host_info *hi,
struct scsi_id_instance_data *scsi_id,
static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait);
static int sbp2_create_command_orb(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command,
unchar *scsi_cmd,
unsigned int scsi_use_sg,
unsigned int scsi_request_bufflen,
void *scsi_request_buffer,
unsigned char scsi_dir);
static int sbp2_link_orb_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
struct sbp2_command_info *command);
static int sbp2_send_command(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id,
static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *));
static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense_data);
static void sbp2_check_sbp2_command(struct scsi_id_instance_data *scsi_id, unchar *cmd);
static void sbp2_check_sbp2_response(struct scsi_id_instance_data *scsi_id, Scsi_Cmnd *SCpnt);
static void sbp2_parse_unit_directory(struct scsi_id_instance_data *scsi_id);
static int sbp2_set_busy_timeout(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_max_speed_and_size(struct sbp2scsi_host_info *hi, struct scsi_id_instance_data *scsi_id);
static int sbp2_set_busy_timeout(struct scsi_id_instance_data *scsi_id);
static int sbp2_max_speed_and_size(struct scsi_id_instance_data *scsi_id);
#endif /* SBP2_H */
......@@ -99,6 +99,8 @@
* for abs. Bug report by Andrew Morton <andrewm@uow.edu.au>
* 2001-06-16: Bryce Nesbitt <bryce@obviously.com>
* Fix SNDCTL_DSP_STEREO API violation
* 2003-04-08: Oliver Neukum (oliver@neukum.name):
* Setting a configuration is done by usbcore and must not be overridden
*/
/*
......@@ -3790,10 +3792,6 @@ static int usb_audio_probe(struct usb_interface *intf,
*/
i = dev->actconfig - config;
if (usb_set_configuration(dev, config->desc.bConfigurationValue) < 0) {
printk(KERN_ERR "usbaudio: set_configuration failed (ConfigValue 0x%x)\n", config->desc.bConfigurationValue);
return -EIO;
}
ret = usb_get_descriptor(dev, USB_DT_CONFIG, i, buf, 8);
if (ret < 0) {
printk(KERN_ERR "usbaudio: cannot get first 8 bytes of config descriptor %d of device %d (error %d)\n", i, dev->devnum, ret);
......
......@@ -1806,22 +1806,6 @@ static int detect_yamaha_device( struct usb_device *d, unsigned int ifnum, struc
printk(KERN_INFO "usb-midi: Found YAMAHA USB-MIDI device on dev %04x:%04x, iface %d\n",
d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
for ( i=0 ; i < d->descriptor.bNumConfigurations ; i++ ) {
if ( d->config+i == c ) goto configfound;
}
printk(KERN_INFO "usb-midi: Config not found.\n");
return -EINVAL;
configfound:
/* this may not be necessary. */
if ( usb_set_configuration( d, c->desc.bConfigurationValue ) < 0 ) {
printk(KERN_INFO "usb-midi: Could not set config.\n");
return -EINVAL;
}
ret = usb_get_descriptor( d, USB_DT_CONFIG, i, buf, USB_DT_CONFIG_SIZE );
if ( ret < 0 ) {
printk(KERN_INFO "usb-midi: Could not get config (error=%d).\n", ret);
......@@ -1916,21 +1900,6 @@ static int detect_midi_subclass(struct usb_device *d, unsigned int ifnum, struct
printk(KERN_INFO "usb-midi: Found MIDISTREAMING on dev %04x:%04x, iface %d\n",
d->descriptor.idVendor, d->descriptor.idProduct, ifnum);
for ( i=0 ; i < d->descriptor.bNumConfigurations ; i++ ) {
if ( d->config+i == c ) goto configfound;
}
printk(KERN_INFO "usb-midi: Config not found.\n");
return -EINVAL;
configfound:
/* this may not be necessary. */
if ( usb_set_configuration( d, c->desc.bConfigurationValue ) < 0 ) {
printk(KERN_INFO "usb-midi: Could not set config.\n");
return -EINVAL;
}
/* From USB Spec v2.0, Section 9.5.
If the class or vendor specific descriptors use the same format
......
This diff is collapsed.
......@@ -930,6 +930,8 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
/* reset more hc/hcd endpoint state */
dev->toggle[0] = 0;
dev->toggle[1] = 0;
dev->halted[0] = 0;
dev->halted[1] = 0;
usb_set_maxpacket(dev);
return 0;
......
This diff is collapsed.
......@@ -62,6 +62,7 @@ static inline void ehci_qtd_init (struct ehci_qtd *qtd, dma_addr_t dma)
{
memset (qtd, 0, sizeof *qtd);
qtd->qtd_dma = dma;
qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
qtd->hw_next = EHCI_LIST_END;
qtd->hw_alt_next = EHCI_LIST_END;
INIT_LIST_HEAD (&qtd->qtd_list);
......
This diff is collapsed.
This diff is collapsed.
......@@ -446,6 +446,8 @@ static void start_urb_unlink (struct ohci_hcd *ohci, struct ed *ed)
if (!ohci->sleeping) {
writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
writel (OHCI_INTR_SF, &ohci->regs->intrenable);
// flush those pci writes
(void) readl (&ohci->regs->control);
}
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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