diff options
Diffstat (limited to 'drivers/firewire/fw-cdev.c')
| -rw-r--r-- | drivers/firewire/fw-cdev.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/firewire/fw-cdev.c b/drivers/firewire/fw-cdev.c index dda14015e873..c639915fc3cb 100644 --- a/drivers/firewire/fw-cdev.c +++ b/drivers/firewire/fw-cdev.c | |||
| @@ -205,6 +205,7 @@ fw_device_op_read(struct file *file, | |||
| 205 | return dequeue_event(client, buffer, count); | 205 | return dequeue_event(client, buffer, count); |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | /* caller must hold card->lock so that node pointers can be dereferenced here */ | ||
| 208 | static void | 209 | static void |
| 209 | fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, | 210 | fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, |
| 210 | struct client *client) | 211 | struct client *client) |
| @@ -214,7 +215,6 @@ fill_bus_reset_event(struct fw_cdev_event_bus_reset *event, | |||
| 214 | event->closure = client->bus_reset_closure; | 215 | event->closure = client->bus_reset_closure; |
| 215 | event->type = FW_CDEV_EVENT_BUS_RESET; | 216 | event->type = FW_CDEV_EVENT_BUS_RESET; |
| 216 | event->generation = client->device->generation; | 217 | event->generation = client->device->generation; |
| 217 | smp_rmb(); /* node_id must not be older than generation */ | ||
| 218 | event->node_id = client->device->node_id; | 218 | event->node_id = client->device->node_id; |
| 219 | event->local_node_id = card->local_node->node_id; | 219 | event->local_node_id = card->local_node->node_id; |
| 220 | event->bm_node_id = 0; /* FIXME: We don't track the BM. */ | 220 | event->bm_node_id = 0; /* FIXME: We don't track the BM. */ |
| @@ -274,6 +274,7 @@ static int ioctl_get_info(struct client *client, void *buffer) | |||
| 274 | { | 274 | { |
| 275 | struct fw_cdev_get_info *get_info = buffer; | 275 | struct fw_cdev_get_info *get_info = buffer; |
| 276 | struct fw_cdev_event_bus_reset bus_reset; | 276 | struct fw_cdev_event_bus_reset bus_reset; |
| 277 | struct fw_card *card = client->device->card; | ||
| 277 | unsigned long ret = 0; | 278 | unsigned long ret = 0; |
| 278 | 279 | ||
| 279 | client->version = get_info->version; | 280 | client->version = get_info->version; |
| @@ -299,13 +300,17 @@ static int ioctl_get_info(struct client *client, void *buffer) | |||
| 299 | client->bus_reset_closure = get_info->bus_reset_closure; | 300 | client->bus_reset_closure = get_info->bus_reset_closure; |
| 300 | if (get_info->bus_reset != 0) { | 301 | if (get_info->bus_reset != 0) { |
| 301 | void __user *uptr = u64_to_uptr(get_info->bus_reset); | 302 | void __user *uptr = u64_to_uptr(get_info->bus_reset); |
| 303 | unsigned long flags; | ||
| 302 | 304 | ||
| 305 | spin_lock_irqsave(&card->lock, flags); | ||
| 303 | fill_bus_reset_event(&bus_reset, client); | 306 | fill_bus_reset_event(&bus_reset, client); |
| 307 | spin_unlock_irqrestore(&card->lock, flags); | ||
| 308 | |||
| 304 | if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) | 309 | if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) |
| 305 | return -EFAULT; | 310 | return -EFAULT; |
| 306 | } | 311 | } |
| 307 | 312 | ||
| 308 | get_info->card = client->device->card->index; | 313 | get_info->card = card->index; |
| 309 | 314 | ||
| 310 | return 0; | 315 | return 0; |
| 311 | } | 316 | } |
