From 8f966dc444b11adff6011a1d1fce424abdd876d8 Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Mon, 26 Sep 2011 11:27:15 +0200 Subject: staging: vme: add struct vme_dev for VME devices Instead of using a vanilla 'struct device' for VME devices, add new 'struct vme_dev'. Modifications have been made to the VME framework API as well as all in-tree VME drivers. The new vme_dev structure has the following advantages from the current model used by the driver: * Driver functions (probe, remove) now receive a VME device instead of a pointer to the bridge device (cleaner design) * It's easier to differenciate API calls as bridge-based or device-based (ie. cleaner interface). Signed-off-by: Manohar Vanga Cc: Martyn Welch Reviewed-by: Emilio G. Cota Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme_api.txt | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'drivers/staging/vme/vme_api.txt') diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt index 4910e92c52a..03f48134706 100644 --- a/drivers/staging/vme/vme_api.txt +++ b/drivers/staging/vme/vme_api.txt @@ -20,8 +20,8 @@ registration function. The structure is as follows: struct list_head node; char *name; const struct vme_device_id *bind_table; - int (*probe) (struct device *, int, int); - int (*remove) (struct device *, int, int); + int (*probe) (struct vme_dev *); + int (*remove) (struct vme_dev *); void (*shutdown) (void); struct device_driver driver; }; @@ -33,7 +33,26 @@ to the probe routine. The arguments of the probe routine are as follows: - probe(struct device *dev, int bus, int slot); + probe(struct vme_dev *dev); + +The device structure looks like the following: + + struct vme_dev { + struct vme_device_id id; + struct vme_bridge *bridge; + struct device dev; + }; + +The 'bridge' field contains a pointer to the bridge device. The 'id' field +contains information useful for the probe function: + + struct vme_device_id { + int bus; + int slot; + }; + +'bus' is the number of the bus the device being probed is on. 'slot' refers +to the specific slot on the VME bus. The '.bind_table' is a pointer to an array of type 'vme_device_id': @@ -71,13 +90,13 @@ specific window or DMA channel (which may be used by a different driver) this driver allows a resource to be assigned based on the required attributes of the driver in question: - struct vme_resource * vme_master_request(struct device *dev, + struct vme_resource * vme_master_request(struct vme_dev *dev, vme_address_t aspace, vme_cycle_t cycle, vme_width_t width); - struct vme_resource * vme_slave_request(struct device *dev, + struct vme_resource * vme_slave_request(struct vme_dev *dev, vme_address_t aspace, vme_cycle_t cycle); - struct vme_resource *vme_dma_request(struct device *dev, + struct vme_resource *vme_dma_request(struct vme_dev *dev, vme_dma_route_t route); For slave windows these attributes are split into those of type 'vme_address_t' @@ -301,10 +320,10 @@ status ID combination. Any given combination can only be assigned a single callback function. A void pointer parameter is provided, the value of which is passed to the callback function, the use of this pointer is user undefined: - int vme_irq_request(struct device *dev, int level, int statid, + int vme_irq_request(struct vme_dev *dev, int level, int statid, void (*callback)(int, int, void *), void *priv); - void vme_irq_free(struct device *dev, int level, int statid); + void vme_irq_free(struct vme_dev *dev, int level, int statid); The callback parameters are as follows. Care must be taken in writing a callback function, callback functions run in interrupt context: @@ -318,7 +337,7 @@ Interrupt Generation The following function can be used to generate a VME interrupt at a given VME level and VME status ID: - int vme_irq_generate(struct device *dev, int level, int statid); + int vme_irq_generate(struct vme_dev *dev, int level, int statid); Location monitors @@ -334,7 +353,7 @@ Location Monitor Management The following functions are provided to request the use of a block of location monitors and to free them after they are no longer required: - struct vme_resource * vme_lm_request(struct device *dev); + struct vme_resource * vme_lm_request(struct vme_dev *dev); void vme_lm_free(struct vme_resource * res); @@ -380,4 +399,4 @@ Slot Detection This function returns the slot ID of the provided bridge. - int vme_slot_get(struct device *dev); + int vme_slot_get(struct vme_dev *dev); -- cgit v1.2.3-70-g09d2 From 5d6abf379d73efe390488e8edba972af4e93cb1c Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Mon, 26 Sep 2011 11:27:16 +0200 Subject: staging: vme: make match() driver specific to improve non-VME64x support For jumper based boards (non VME64x), there is no mechanism for detecting the card that is plugged into a specific slot. This leads to issues in non-autodiscovery crates/cards when a card is plugged into a slot that is "claimed" by a different driver. In reality, there is no problem, but the driver rejects such a configuration due to its dependence on the concept of slots. This patch makes the concept of slots less critical and pushes the driver match() to individual drivers (similar to what happens in the ISA bus in driver/base/isa.c). This allows drivers to register the number of devices that they expect without any restrictions. Devices in this new model are now formatted as $driver_name-$bus_id.$device_id (as compared to the earlier vme-$bus_id.$slot_number). This model also makes the device model more logical as devices are only registered when they actually exist whereas earlier, a set of devices were being created automatically regardless of them actually being there. Another change introduced in this patch is that devices are now created within the VME driver structure rather than in the VME bridge structure. This way, things don't go haywire if the bridge driver is removed while a driver is using it. Signed-off-by: Manohar Vanga Cc: Martyn Welch Reviewed-by: Emilio G. Cota Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 45 +++----- drivers/staging/vme/vme.c | 202 +++++++++++++++++---------------- drivers/staging/vme/vme.h | 23 +++- drivers/staging/vme/vme_api.txt | 60 +++++----- drivers/staging/vme/vme_bridge.h | 5 +- 5 files changed, 169 insertions(+), 166 deletions(-) (limited to 'drivers/staging/vme/vme_api.txt') diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index bb33dc2ece4..c658ce9bd61 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -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 *); @@ -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), }; @@ -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"); @@ -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 @@ -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); } diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 4bef7893dde..2abb9ebd3d6 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -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; @@ -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); } @@ -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); @@ -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); diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index d442cce33c0..95224d7452e 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h @@ -88,15 +88,21 @@ struct vme_resource { extern struct bus_type vme_bus_type; +/* VME_MAX_BRIDGES comes from the type of vme_bus_numbers */ +#define VME_MAX_BRIDGES (sizeof(unsigned int)*8) +#define VME_MAX_SLOTS 32 + #define VME_SLOT_CURRENT -1 #define VME_SLOT_ALL -2 /** * VME device identifier structure + * @num: The device ID (ranges from 0 to N-1 for N devices) * @bus: The bus ID of the bus the device is on * @slot: The slot this device is plugged into */ struct vme_device_id { + int num; int bus; int slot; }; @@ -106,21 +112,26 @@ struct vme_device_id { * @id: The ID of the device (currently the bus and slot number) * @bridge: Pointer to the bridge device this device is on * @dev: Internal device structure + * @drv_list: List of devices (per driver) + * @bridge_list: List of devices (per bridge) */ struct vme_dev { struct vme_device_id id; struct vme_bridge *bridge; struct device dev; + struct list_head drv_list; + struct list_head bridge_list; }; struct vme_driver { struct list_head node; const char *name; - const struct vme_device_id *bind_table; - int (*probe) (struct vme_dev *); - int (*remove) (struct vme_dev *); - void (*shutdown) (void); - struct device_driver driver; + int (*match)(struct vme_dev *); + int (*probe)(struct vme_dev *); + int (*remove)(struct vme_dev *); + void (*shutdown)(void); + struct device_driver driver; + struct list_head devices; }; void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); @@ -179,7 +190,7 @@ void vme_lm_free(struct vme_resource *); int vme_slot_get(struct vme_dev *); -int vme_register_driver(struct vme_driver *); +int vme_register_driver(struct vme_driver *, unsigned int); void vme_unregister_driver(struct vme_driver *); diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt index 03f48134706..53abf7e7cb4 100644 --- a/drivers/staging/vme/vme_api.txt +++ b/drivers/staging/vme/vme_api.txt @@ -18,24 +18,37 @@ registration function. The structure is as follows: struct vme_driver { struct list_head node; - char *name; - const struct vme_device_id *bind_table; - int (*probe) (struct vme_dev *); - int (*remove) (struct vme_dev *); - void (*shutdown) (void); - struct device_driver driver; + const char *name; + int (*match)(struct vme_dev *); + int (*probe)(struct vme_dev *); + int (*remove)(struct vme_dev *); + void (*shutdown)(void); + struct device_driver driver; + struct list_head devices; + unsigned int ndev; }; -At the minimum, the '.name', '.probe' and '.bind_table' elements of this -structure should be correctly set. The '.name' element is a pointer to a string -holding the device driver's name. The '.probe' element should contain a pointer -to the probe routine. +At the minimum, the '.name', '.match' and '.probe' elements of this structure +should be correctly set. The '.name' element is a pointer to a string holding +the device driver's name. -The arguments of the probe routine are as follows: +The '.match' function allows controlling the number of devices that need to +be registered. The match function should return 1 if a device should be +probed and 0 otherwise. This example match function (from vme_user.c) limits +the number of devices probed to one: - probe(struct vme_dev *dev); + #define USER_BUS_MAX 1 + ... + static int vme_user_match(struct vme_dev *vdev) + { + if (vdev->id.num >= USER_BUS_MAX) + return 0; + return 1; + } -The device structure looks like the following: +The '.probe' element should contain a pointer to the probe routine. The +probe routine is passed a 'struct vme_dev' pointer as an argument. The +'struct vme_dev' structure looks like the following: struct vme_dev { struct vme_device_id id; @@ -49,25 +62,12 @@ contains information useful for the probe function: struct vme_device_id { int bus; int slot; + int num; }; -'bus' is the number of the bus the device being probed is on. 'slot' refers -to the specific slot on the VME bus. - -The '.bind_table' is a pointer to an array of type 'vme_device_id': - - struct vme_device_id { - int bus; - int slot; - }; - -Each structure in this array should provide a bus and slot number where the core -should probe, using the driver's probe routine, for a device on the specified -VME bus. - -The VME subsystem supports a single VME driver per 'slot'. There are considered -to be 32 slots per bus, one for each slot-ID as defined in the ANSI/VITA 1-1994 -specification and are analogious to the physical slots on the VME backplane. +Here, 'bus' is the number of the bus the device being probed is on. 'slot' +refers to the specific slot on the VME bus. The 'num' field refers to the +sequential device ID for this specific driver. A function is also provided to unregister the driver from the VME core and is usually called from the device driver's exit routine: diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h index 6dd2f4cf8b6..c2deda2c38d 100644 --- a/drivers/staging/vme/vme_bridge.h +++ b/drivers/staging/vme/vme_bridge.h @@ -2,7 +2,6 @@ #define _VME_BRIDGE_H_ #define VME_CRCSR_BUF_SIZE (508*1024) -#define VME_SLOTS_MAX 32 /* * Resource structures */ @@ -108,15 +107,13 @@ struct vme_bridge { struct list_head lm_resources; struct list_head vme_errors; /* List for errors generated on VME */ + struct list_head devices; /* List of devices on this bridge */ /* Bridge Info - XXX Move to private structure? */ struct device *parent; /* Parent device (eg. pdev->dev for PCI) */ void *driver_priv; /* Private pointer for the bridge driver */ struct list_head bus_list; /* list of VME buses */ - struct vme_dev *dev[VME_SLOTS_MAX]; /* Device registered - * on VME bus */ - /* Interrupt callbacks */ struct vme_irq irq[7]; /* Locking for VME irq callback configuration */ -- cgit v1.2.3-70-g09d2 From a916a391d3e19593a104a8c3c4779a3084f1ca5b Mon Sep 17 00:00:00 2001 From: Manohar Vanga Date: Mon, 26 Sep 2011 11:27:17 +0200 Subject: staging: vme: get rid of struct vme_device_id and slots Previously, the device-driver matching mechanism depended on the vme_device_id structure due to the need for a bind table per driver. This method of matching is no longer used so this patch merges the fields of struct vme_device_id into struct vme_dev. Since this also renders the slot field meaningless, it has also been removed in this patch. Signed-off-by: Manohar Vanga Cc: Martyn Welch Reviewed-by: Emilio G. Cota Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 2 +- drivers/staging/vme/vme.c | 8 +++----- drivers/staging/vme/vme.h | 14 +------------- drivers/staging/vme/vme_api.txt | 27 +++++++++++---------------- 4 files changed, 16 insertions(+), 35 deletions(-) (limited to 'drivers/staging/vme/vme_api.txt') diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index c658ce9bd61..9518dda13ea 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -668,7 +668,7 @@ err_nocard: static int vme_user_match(struct vme_dev *vdev) { - if (vdev->id.num >= USER_BUS_MAX) + if (vdev->num >= USER_BUS_MAX) return 0; return 1; } diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 2abb9ebd3d6..b04b4688f70 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -1377,16 +1377,14 @@ static int __vme_register_driver_bus(struct vme_driver *drv, err = -ENOMEM; goto err_devalloc; } - vdev->id.num = i; - vdev->id.bus = bridge->num; - vdev->id.slot = i + 1; + vdev->num = i; 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; - dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, vdev->id.bus, - vdev->id.num); + dev_set_name(&vdev->dev, "%s.%u-%u", drv->name, bridge->num, + vdev->num); err = device_register(&vdev->dev); if (err) diff --git a/drivers/staging/vme/vme.h b/drivers/staging/vme/vme.h index 95224d7452e..e3828badca6 100644 --- a/drivers/staging/vme/vme.h +++ b/drivers/staging/vme/vme.h @@ -95,18 +95,6 @@ extern struct bus_type vme_bus_type; #define VME_SLOT_CURRENT -1 #define VME_SLOT_ALL -2 -/** - * VME device identifier structure - * @num: The device ID (ranges from 0 to N-1 for N devices) - * @bus: The bus ID of the bus the device is on - * @slot: The slot this device is plugged into - */ -struct vme_device_id { - int num; - int bus; - int slot; -}; - /** * Structure representing a VME device * @id: The ID of the device (currently the bus and slot number) @@ -116,7 +104,7 @@ struct vme_device_id { * @bridge_list: List of devices (per bridge) */ struct vme_dev { - struct vme_device_id id; + int num; struct vme_bridge *bridge; struct device dev; struct list_head drv_list; diff --git a/drivers/staging/vme/vme_api.txt b/drivers/staging/vme/vme_api.txt index 53abf7e7cb4..e8ff2151a48 100644 --- a/drivers/staging/vme/vme_api.txt +++ b/drivers/staging/vme/vme_api.txt @@ -51,23 +51,16 @@ probe routine is passed a 'struct vme_dev' pointer as an argument. The 'struct vme_dev' structure looks like the following: struct vme_dev { - struct vme_device_id id; + int num; struct vme_bridge *bridge; struct device dev; + struct list_head drv_list; + struct list_head bridge_list; }; -The 'bridge' field contains a pointer to the bridge device. The 'id' field -contains information useful for the probe function: - - struct vme_device_id { - int bus; - int slot; - int num; - }; - -Here, 'bus' is the number of the bus the device being probed is on. 'slot' -refers to the specific slot on the VME bus. The 'num' field refers to the -sequential device ID for this specific driver. +Here, the 'num' field refers to the sequential device ID for this specific +driver. The bridge number (or bus number) can be accessed using +dev->bridge->num. A function is also provided to unregister the driver from the VME core and is usually called from the device driver's exit routine: @@ -78,9 +71,11 @@ usually called from the device driver's exit routine: Resource management =================== -Once a driver has registered with the VME core the provided probe routine will -be called for each of the bus/slot combination that becomes valid as VME buses -are themselves registered. The probe routine is passed a pointer to the devices +Once a driver has registered with the VME core the provided match routine will +be called the number of times specified during the registration. If a match +succeeds, a non-zero value should be returned. A zero return value indicates +failure. For all successful matches, the probe routine of the corresponding +driver is called. The probe routine is passed a pointer to the devices device structure. This pointer should be saved, it will be required for requesting VME resources. -- cgit v1.2.3-70-g09d2