diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 14:49:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-22 14:49:48 -0700 |
commit | 441c196e84b11aad3123baa9320eee7abc6b5c98 (patch) | |
tree | ea51d689c9ac09cce10a5758f19d6adbd8a7a9d7 /drivers/firewire/core-cdev.c | |
parent | 951cc93a7493a81a47e20231441bc6cf17c98a37 (diff) | |
parent | 9a00c24ae7cb08dcd46edf1327a47871e8466444 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
firewire: document the sysfs ABIs
firewire: cdev: ABI documentation enhancements
firewire: cdev: prevent race between first get_info ioctl and bus reset event queuing
firewire: cdev: return -ENOTTY for unimplemented ioctls, not -EINVAL
firewire: ohci: skip soft reset retries after card ejection
firewire: ohci: fix PHY reg access after card ejection
firewire: ohci: add a comment on PHY reg access serialization
firewire: ohci: reduce potential context_stop latency
firewire: ohci: remove superfluous posted write flushes
firewire: net: replacing deprecated __attribute__((packed)) with __packed
Diffstat (limited to 'drivers/firewire/core-cdev.c')
-rw-r--r-- | drivers/firewire/core-cdev.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index b1c11775839..e6ad3bb6c1a 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, @@ -1583,7 +1585,7 @@ static int dispatch_ioctl(struct client *client, if (_IOC_TYPE(cmd) != '#' || _IOC_NR(cmd) >= ARRAY_SIZE(ioctl_handlers) || _IOC_SIZE(cmd) > sizeof(buffer)) - return -EINVAL; + return -ENOTTY; if (_IOC_DIR(cmd) == _IOC_READ) memset(&buffer, 0, _IOC_SIZE(cmd)); |