Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 268837
b: refs/heads/master
c: 5d6abf3
h: refs/heads/master
i:
  268835: a506a21
v: v3
  • Loading branch information
Manohar Vanga authored and Greg Kroah-Hartman committed Oct 17, 2011
1 parent 82774fc commit 5d57804
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 167 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8f966dc444b11adff6011a1d1fce424abdd876d8
refs/heads/master: 5d6abf379d73efe390488e8edba972af4e93cb1c
45 changes: 16 additions & 29 deletions trunk/drivers/staging/vme/devices/vme_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static ssize_t vme_user_write(struct file *, const char __user *, size_t,
static loff_t vme_user_llseek(struct file *, loff_t, int);
static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long);

static int vme_user_match(struct vme_dev *);
static int __devinit vme_user_probe(struct vme_dev *);
static int __devexit vme_user_remove(struct vme_dev *);

Expand Down Expand Up @@ -620,6 +621,7 @@ static void buf_unalloc(int num)

static struct vme_driver vme_user_driver = {
.name = driver_name,
.match = vme_user_match,
.probe = vme_user_probe,
.remove = __devexit_p(vme_user_remove),
};
Expand All @@ -628,8 +630,6 @@ static struct vme_driver vme_user_driver = {
static int __init vme_user_init(void)
{
int retval = 0;
int i;
struct vme_device_id *ids;

printk(KERN_INFO "VME User Space Access Driver\n");

Expand All @@ -649,41 +649,30 @@ static int __init vme_user_init(void)
bus_num = USER_BUS_MAX;
}


/* Dynamically create the bind table based on module parameters */
ids = kzalloc(sizeof(struct vme_device_id) * (bus_num + 1), GFP_KERNEL);
if (ids == NULL) {
printk(KERN_ERR "%s: Unable to allocate ID table\n",
driver_name);
retval = -ENOMEM;
goto err_id;
}

for (i = 0; i < bus_num; i++) {
ids[i].bus = bus[i];
/*
* We register the driver against the slot occupied by *this*
* card, since it's really a low level way of controlling
* the VME bridge
*/
ids[i].slot = VME_SLOT_CURRENT;
}

vme_user_driver.bind_table = ids;

retval = vme_register_driver(&vme_user_driver);
/*
* Here we just register the maximum number of devices we can and
* leave vme_user_match() to allow only 1 to go through to probe().
* This way, if we later want to allow multiple user access devices,
* we just change the code in vme_user_match().
*/
retval = vme_register_driver(&vme_user_driver, VME_MAX_SLOTS);
if (retval != 0)
goto err_reg;

return retval;

err_reg:
kfree(ids);
err_id:
err_nocard:
return retval;
}

static int vme_user_match(struct vme_dev *vdev)
{
if (vdev->id.num >= USER_BUS_MAX)
return 0;
return 1;
}

/*
* In this simple access driver, the old behaviour is being preserved as much
* as practical. We will therefore reserve the buffers and request the images
Expand Down Expand Up @@ -896,8 +885,6 @@ static int __devexit vme_user_remove(struct vme_dev *dev)
static void __exit vme_user_exit(void)
{
vme_unregister_driver(&vme_user_driver);

kfree(vme_user_driver.bind_table);
}


Expand Down
202 changes: 105 additions & 97 deletions trunk/drivers/staging/vme/vme.c
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,7 @@ static int vme_add_bus(struct vme_bridge *bridge)
if ((vme_bus_numbers & (1 << i)) == 0) {
vme_bus_numbers |= (1 << i);
bridge->num = i;
INIT_LIST_HEAD(&bridge->devices);
list_add_tail(&bridge->bus_list, &vme_bus_list);
ret = 0;
break;
Expand All @@ -1329,8 +1330,16 @@ static int vme_add_bus(struct vme_bridge *bridge)

static void vme_remove_bus(struct vme_bridge *bridge)
{
struct vme_dev *vdev;
struct vme_dev *tmp;

mutex_lock(&vme_buses_lock);
vme_bus_numbers &= ~(1 << bridge->num);
list_for_each_entry_safe(vdev, tmp, &bridge->devices, bridge_list) {
list_del(&vdev->drv_list);
list_del(&vdev->bridge_list);
device_unregister(&vdev->dev);
}
list_del(&bridge->bus_list);
mutex_unlock(&vme_buses_lock);
}
Expand All @@ -1342,153 +1351,153 @@ static void vme_dev_release(struct device *dev)

int vme_register_bridge(struct vme_bridge *bridge)
{
struct vme_dev *vdev;
int retval;
int i;
return vme_add_bus(bridge);
}
EXPORT_SYMBOL(vme_register_bridge);

retval = vme_add_bus(bridge);
if (retval)
return retval;
void vme_unregister_bridge(struct vme_bridge *bridge)
{
vme_remove_bus(bridge);
}
EXPORT_SYMBOL(vme_unregister_bridge);

/* This creates 32 vme "slot" devices. This equates to a slot for each
* ID available in a system conforming to the ANSI/VITA 1-1994
* specification.
*/
for (i = 0; i < VME_SLOTS_MAX; i++) {
bridge->dev[i] = kzalloc(sizeof(struct vme_dev), GFP_KERNEL);
if (!bridge->dev[i]) {
retval = -ENOMEM;
/* - Driver Registration --------------------------------------------------- */

static int __vme_register_driver_bus(struct vme_driver *drv,
struct vme_bridge *bridge, unsigned int ndevs)
{
int err;
unsigned int i;
struct vme_dev *vdev;
struct vme_dev *tmp;

for (i = 0; i < ndevs; i++) {
vdev = kzalloc(sizeof(struct vme_dev), GFP_KERNEL);
if (!vdev) {
err = -ENOMEM;
goto err_devalloc;
}
vdev = bridge->dev[i];
memset(vdev, 0, sizeof(struct vme_dev));

vdev->id.num = i;
vdev->id.bus = bridge->num;
vdev->id.slot = i + 1;
vdev->bridge = bridge;
vdev->dev.platform_data = drv;
vdev->dev.release = vme_dev_release;
vdev->dev.parent = bridge->parent;
vdev->dev.bus = &vme_bus_type;
vdev->dev.release = vme_dev_release;
/*
* We save a pointer to the bridge in platform_data so that we
* can get to it later. We keep driver_data for use by the
* driver that binds against the slot
*/
vdev->dev.platform_data = bridge;
dev_set_name(&vdev->dev, "vme-%x.%x", bridge->num, i + 1);
dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, vdev->id.bus,
vdev->id.num);

retval = device_register(&vdev->dev);
if (retval)
err = device_register(&vdev->dev);
if (err)
goto err_reg;
}

return retval;
if (vdev->dev.platform_data) {
list_add_tail(&vdev->drv_list, &drv->devices);
list_add_tail(&vdev->bridge_list, &bridge->devices);
} else
device_unregister(&vdev->dev);
}
return 0;

err_reg:
kfree(vdev);
err_devalloc:
while (--i >= 0) {
vdev = bridge->dev[i];
list_for_each_entry_safe(vdev, tmp, &drv->devices, drv_list) {
list_del(&vdev->drv_list);
list_del(&vdev->bridge_list);
device_unregister(&vdev->dev);
}
vme_remove_bus(bridge);
return retval;
return err;
}
EXPORT_SYMBOL(vme_register_bridge);

void vme_unregister_bridge(struct vme_bridge *bridge)
static int __vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
{
int i;
struct vme_dev *vdev;

struct vme_bridge *bridge;
int err = 0;

for (i = 0; i < VME_SLOTS_MAX; i++) {
vdev = bridge->dev[i];
device_unregister(&vdev->dev);
mutex_lock(&vme_buses_lock);
list_for_each_entry(bridge, &vme_bus_list, bus_list) {
/*
* This cannot cause trouble as we already have vme_buses_lock
* and if the bridge is removed, it will have to go through
* vme_unregister_bridge() to do it (which calls remove() on
* the bridge which in turn tries to acquire vme_buses_lock and
* will have to wait). The probe() called after device
* registration in __vme_register_driver below will also fail
* as the bridge is being removed (since the probe() calls
* vme_bridge_get()).
*/
err = __vme_register_driver_bus(drv, bridge, ndevs);
if (err)
break;
}
vme_remove_bus(bridge);
mutex_unlock(&vme_buses_lock);
return err;
}
EXPORT_SYMBOL(vme_unregister_bridge);


/* - Driver Registration --------------------------------------------------- */

int vme_register_driver(struct vme_driver *drv)
int vme_register_driver(struct vme_driver *drv, unsigned int ndevs)
{
int err;

drv->driver.name = drv->name;
drv->driver.bus = &vme_bus_type;
INIT_LIST_HEAD(&drv->devices);

err = driver_register(&drv->driver);
if (err)
return err;

return driver_register(&drv->driver);
err = __vme_register_driver(drv, ndevs);
if (err)
driver_unregister(&drv->driver);

return err;
}
EXPORT_SYMBOL(vme_register_driver);

void vme_unregister_driver(struct vme_driver *drv)
{
struct vme_dev *dev, *dev_tmp;

mutex_lock(&vme_buses_lock);
list_for_each_entry_safe(dev, dev_tmp, &drv->devices, drv_list) {
list_del(&dev->drv_list);
list_del(&dev->bridge_list);
device_unregister(&dev->dev);
}
mutex_unlock(&vme_buses_lock);

driver_unregister(&drv->driver);
}
EXPORT_SYMBOL(vme_unregister_driver);

/* - Bus Registration ------------------------------------------------------ */

static struct vme_driver *dev_to_vme_driver(struct device *dev)
{
if (dev->driver == NULL)
printk(KERN_ERR "Bugger dev->driver is NULL\n");

return container_of(dev->driver, struct vme_driver, driver);
}

static int vme_bus_match(struct device *dev, struct device_driver *drv)
{
struct vme_dev *vdev;
struct vme_bridge *bridge;
struct vme_driver *driver;
int i, num;

vdev = dev_to_vme_dev(dev);
bridge = vdev->bridge;
driver = container_of(drv, struct vme_driver, driver);
struct vme_driver *vme_drv;

num = vdev->id.slot;
if (num <= 0 || num >= VME_SLOTS_MAX)
goto err_dev;

if (driver->bind_table == NULL) {
dev_err(dev, "Bind table NULL\n");
goto err_table;
}
vme_drv = container_of(drv, struct vme_driver, driver);

i = 0;
while ((driver->bind_table[i].bus != 0) ||
(driver->bind_table[i].slot != 0)) {
if (dev->platform_data == vme_drv) {
struct vme_dev *vdev = dev_to_vme_dev(dev);

if (bridge->num == driver->bind_table[i].bus) {
if (num == driver->bind_table[i].slot)
return 1;
if (vme_drv->match && vme_drv->match(vdev))
return 1;

if (driver->bind_table[i].slot == VME_SLOT_ALL)
return 1;

if ((driver->bind_table[i].slot == VME_SLOT_CURRENT) &&
(num == vme_slot_get(vdev)))
return 1;
}
i++;
dev->platform_data = NULL;
}

err_dev:
err_table:
return 0;
}

static int vme_bus_probe(struct device *dev)
{
struct vme_driver *driver;
struct vme_dev *vdev;
int retval = -ENODEV;
struct vme_driver *driver;
struct vme_dev *vdev = dev_to_vme_dev(dev);

driver = dev_to_vme_driver(dev);
vdev = dev_to_vme_dev(dev);
driver = dev->platform_data;

if (driver->probe != NULL)
retval = driver->probe(vdev);
Expand All @@ -1498,12 +1507,11 @@ static int vme_bus_probe(struct device *dev)

static int vme_bus_remove(struct device *dev)
{
struct vme_driver *driver;
struct vme_dev *vdev;
int retval = -ENODEV;
struct vme_driver *driver;
struct vme_dev *vdev = dev_to_vme_dev(dev);

driver = dev_to_vme_driver(dev);
vdev = dev_to_vme_dev(dev);
driver = dev->platform_data;

if (driver->remove != NULL)
retval = driver->remove(vdev);
Expand Down
Loading

0 comments on commit 5d57804

Please sign in to comment.