summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/core-cdev.c18
-rw-r--r--include/linux/firewire-cdev.h3
2 files changed, 13 insertions, 8 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 9b5915ebeb35..e6ad3bb6c1a6 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -253,14 +253,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
init_waitqueue_head(&client->wait);
init_waitqueue_head(&client->tx_flush_wait);
INIT_LIST_HEAD(&client->phy_receiver_link);
+ INIT_LIST_HEAD(&client->link);
kref_init(&client->kref);
file->private_data = client;
- mutex_lock(&device->client_list_mutex);
- list_add_tail(&client->link, &device->client_list);
- mutex_unlock(&device->client_list_mutex);
-
return nonseekable_open(inode, file);
}
@@ -451,15 +448,20 @@ static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
if (ret != 0)
return -EFAULT;
+ mutex_lock(&client->device->client_list_mutex);
+
client->bus_reset_closure = a->bus_reset_closure;
if (a->bus_reset != 0) {
fill_bus_reset_event(&bus_reset, client);
- if (copy_to_user(u64_to_uptr(a->bus_reset),
- &bus_reset, sizeof(bus_reset)))
- return -EFAULT;
+ ret = copy_to_user(u64_to_uptr(a->bus_reset),
+ &bus_reset, sizeof(bus_reset));
}
+ if (ret == 0 && list_empty(&client->link))
+ list_add_tail(&client->link, &client->device->client_list);
- return 0;
+ mutex_unlock(&client->device->client_list_mutex);
+
+ return ret ? -EFAULT : 0;
}
static int add_client_resource(struct client *client,
diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h
index 4ff09889c5c0..55814aa33be2 100644
--- a/include/linux/firewire-cdev.h
+++ b/include/linux/firewire-cdev.h
@@ -475,6 +475,9 @@ union fw_cdev_event {
* of the bus. This does not cause a bus reset to happen.
* @bus_reset_closure: Value of &closure in this and subsequent bus reset events
* @card: The index of the card this device belongs to
+ *
+ * As a side effect, reception of %FW_CDEV_EVENT_BUS_RESET events to be read(2)
+ * is started by this ioctl.
*/
struct fw_cdev_get_info {
__u32 version;