aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-cdev.c
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-03-24 15:54:28 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-04-18 11:55:36 -0400
commitc9755e14a01987ada4063e8b4c50c2b6738d879e (patch)
tree41a593c4b9ac10ccc4ad031510438e4551e51b5b /drivers/firewire/fw-cdev.c
parent1dadff71d6356ebb804c3f4f1d3049247e16111c (diff)
firewire: reread config ROM when device reset the bus
When a device changes its configuration ROM, it announces this with a bus reset. firewire-core has to check which node initiated a bus reset and whether any unit directories went away or were added on this node. Tested with an IOI FWB-IDE01AB which has its link-on bit set if bus power is available but does not respond to ROM read requests if self power is off. This implements - recognition of the units if self power is switched on after fw-core gave up the initial attempt to read the config ROM, - shutdown of the units when self power is switched off. Also tested with a second PC running Linux/ieee1394. When the eth1394 driver is inserted and removed on that node, fw-core now notices the addition and removal of the IPv4 unit on the ieee1394 node. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-cdev.c')
-rw-r--r--drivers/firewire/fw-cdev.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c
index 46bc197a047f..4a541921a14a 100644
--- a/drivers/firewire/fw-cdev.c
+++ b/drivers/firewire/fw-cdev.c
@@ -269,21 +269,28 @@ static int ioctl_get_info(struct client *client, void *buffer)
269{ 269{
270 struct fw_cdev_get_info *get_info = buffer; 270 struct fw_cdev_get_info *get_info = buffer;
271 struct fw_cdev_event_bus_reset bus_reset; 271 struct fw_cdev_event_bus_reset bus_reset;
272 unsigned long ret = 0;
272 273
273 client->version = get_info->version; 274 client->version = get_info->version;
274 get_info->version = FW_CDEV_VERSION; 275 get_info->version = FW_CDEV_VERSION;
275 276
277 down_read(&fw_device_rwsem);
278
276 if (get_info->rom != 0) { 279 if (get_info->rom != 0) {
277 void __user *uptr = u64_to_uptr(get_info->rom); 280 void __user *uptr = u64_to_uptr(get_info->rom);
278 size_t want = get_info->rom_length; 281 size_t want = get_info->rom_length;
279 size_t have = client->device->config_rom_length * 4; 282 size_t have = client->device->config_rom_length * 4;
280 283
281 if (copy_to_user(uptr, client->device->config_rom, 284 ret = copy_to_user(uptr, client->device->config_rom,
282 min(want, have))) 285 min(want, have));
283 return -EFAULT;
284 } 286 }
285 get_info->rom_length = client->device->config_rom_length * 4; 287 get_info->rom_length = client->device->config_rom_length * 4;
286 288
289 up_read(&fw_device_rwsem);
290
291 if (ret != 0)
292 return -EFAULT;
293
287 client->bus_reset_closure = get_info->bus_reset_closure; 294 client->bus_reset_closure = get_info->bus_reset_closure;
288 if (get_info->bus_reset != 0) { 295 if (get_info->bus_reset != 0) {
289 void __user *uptr = u64_to_uptr(get_info->bus_reset); 296 void __user *uptr = u64_to_uptr(get_info->bus_reset);