aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 11:08:44 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 11:08:44 -0500
commitc1dcb4bb1e3e16e9baee578d9bb040e5fba1063e (patch)
tree1bba995740aed8ef9a47111c1ee6ceeda84af836 /drivers/firewire
parent60f8a8d4c6c46bb080e8e65d30be31b172a39a78 (diff)
parent6fdb2ee243404c7cbf530387bf904ad1841ebf5b (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: (23 commits) firewire: ohci: extend initialization log message firewire: ohci: fix IR/IT context mask mixup firewire: ohci: add module parameter to activate quirk fixes firewire: ohci: use an ID table for quirks detection firewire: ohci: reorder struct fw_ohci for better cache efficiency firewire: ohci: remove unused dualbuffer IR code firewire: core: combine a bit of repeated code firewire: core: change type of a data buffer firewire: cdev: increment ABI version number firewire: cdev: add more flexible cycle timer ioctl firewire: core: rename an internal function firewire: core: fix an information leak firewire: core: increase stack size of config ROM reader firewire: core: don't fail device creation in case of too large config ROM blocks firewire: core: fix "giving up on config rom" with Panasonic AG-DV2500 firewire: remove incomplete Bus_Time CSR support firewire: get_cycle_timer optimization and cleanup firewire: ohci: enable cycle timer fix on ALi and NEC controllers firewire: ohci: work around cycle timer bugs on VIA controllers firewire: make PCI device id constant ...
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/core-cdev.c368
-rw-r--r--drivers/firewire/core-device.c198
-rw-r--r--drivers/firewire/core-transaction.c17
-rw-r--r--drivers/firewire/core.h2
-rw-r--r--drivers/firewire/ohci.c364
-rw-r--r--drivers/firewire/sbp2.c5
6 files changed, 447 insertions, 507 deletions
diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c
index 4eeaed57e219..8be720b278b7 100644
--- a/drivers/firewire/core-cdev.c
+++ b/drivers/firewire/core-cdev.c
@@ -25,6 +25,7 @@
25#include <linux/firewire.h> 25#include <linux/firewire.h>
26#include <linux/firewire-cdev.h> 26#include <linux/firewire-cdev.h>
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <linux/irqflags.h>
28#include <linux/jiffies.h> 29#include <linux/jiffies.h>
29#include <linux/kernel.h> 30#include <linux/kernel.h>
30#include <linux/kref.h> 31#include <linux/kref.h>
@@ -32,7 +33,6 @@
32#include <linux/module.h> 33#include <linux/module.h>
33#include <linux/mutex.h> 34#include <linux/mutex.h>
34#include <linux/poll.h> 35#include <linux/poll.h>
35#include <linux/preempt.h>
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/spinlock.h> 37#include <linux/spinlock.h>
38#include <linux/string.h> 38#include <linux/string.h>
@@ -368,39 +368,56 @@ void fw_device_cdev_remove(struct fw_device *device)
368 for_each_client(device, wake_up_client); 368 for_each_client(device, wake_up_client);
369} 369}
370 370
371static int ioctl_get_info(struct client *client, void *buffer) 371union ioctl_arg {
372 struct fw_cdev_get_info get_info;
373 struct fw_cdev_send_request send_request;
374 struct fw_cdev_allocate allocate;
375 struct fw_cdev_deallocate deallocate;
376 struct fw_cdev_send_response send_response;
377 struct fw_cdev_initiate_bus_reset initiate_bus_reset;
378 struct fw_cdev_add_descriptor add_descriptor;
379 struct fw_cdev_remove_descriptor remove_descriptor;
380 struct fw_cdev_create_iso_context create_iso_context;
381 struct fw_cdev_queue_iso queue_iso;
382 struct fw_cdev_start_iso start_iso;
383 struct fw_cdev_stop_iso stop_iso;
384 struct fw_cdev_get_cycle_timer get_cycle_timer;
385 struct fw_cdev_allocate_iso_resource allocate_iso_resource;
386 struct fw_cdev_send_stream_packet send_stream_packet;
387 struct fw_cdev_get_cycle_timer2 get_cycle_timer2;
388};
389
390static int ioctl_get_info(struct client *client, union ioctl_arg *arg)
372{ 391{
373 struct fw_cdev_get_info *get_info = buffer; 392 struct fw_cdev_get_info *a = &arg->get_info;
374 struct fw_cdev_event_bus_reset bus_reset; 393 struct fw_cdev_event_bus_reset bus_reset;
375 unsigned long ret = 0; 394 unsigned long ret = 0;
376 395
377 client->version = get_info->version; 396 client->version = a->version;
378 get_info->version = FW_CDEV_VERSION; 397 a->version = FW_CDEV_VERSION;
379 get_info->card = client->device->card->index; 398 a->card = client->device->card->index;
380 399
381 down_read(&fw_device_rwsem); 400 down_read(&fw_device_rwsem);
382 401
383 if (get_info->rom != 0) { 402 if (a->rom != 0) {
384 void __user *uptr = u64_to_uptr(get_info->rom); 403 size_t want = a->rom_length;
385 size_t want = get_info->rom_length;
386 size_t have = client->device->config_rom_length * 4; 404 size_t have = client->device->config_rom_length * 4;
387 405
388 ret = copy_to_user(uptr, client->device->config_rom, 406 ret = copy_to_user(u64_to_uptr(a->rom),
389 min(want, have)); 407 client->device->config_rom, min(want, have));
390 } 408 }
391 get_info->rom_length = client->device->config_rom_length * 4; 409 a->rom_length = client->device->config_rom_length * 4;
392 410
393 up_read(&fw_device_rwsem); 411 up_read(&fw_device_rwsem);
394 412
395 if (ret != 0) 413 if (ret != 0)
396 return -EFAULT; 414 return -EFAULT;
397 415
398 client->bus_reset_closure = get_info->bus_reset_closure; 416 client->bus_reset_closure = a->bus_reset_closure;
399 if (get_info->bus_reset != 0) { 417 if (a->bus_reset != 0) {
400 void __user *uptr = u64_to_uptr(get_info->bus_reset);
401
402 fill_bus_reset_event(&bus_reset, client); 418 fill_bus_reset_event(&bus_reset, client);
403 if (copy_to_user(uptr, &bus_reset, sizeof(bus_reset))) 419 if (copy_to_user(u64_to_uptr(a->bus_reset),
420 &bus_reset, sizeof(bus_reset)))
404 return -EFAULT; 421 return -EFAULT;
405 } 422 }
406 423
@@ -571,11 +588,9 @@ static int init_request(struct client *client,
571 return ret; 588 return ret;
572} 589}
573 590
574static int ioctl_send_request(struct client *client, void *buffer) 591static int ioctl_send_request(struct client *client, union ioctl_arg *arg)
575{ 592{
576 struct fw_cdev_send_request *request = buffer; 593 switch (arg->send_request.tcode) {
577
578 switch (request->tcode) {
579 case TCODE_WRITE_QUADLET_REQUEST: 594 case TCODE_WRITE_QUADLET_REQUEST:
580 case TCODE_WRITE_BLOCK_REQUEST: 595 case TCODE_WRITE_BLOCK_REQUEST:
581 case TCODE_READ_QUADLET_REQUEST: 596 case TCODE_READ_QUADLET_REQUEST:
@@ -592,7 +607,7 @@ static int ioctl_send_request(struct client *client, void *buffer)
592 return -EINVAL; 607 return -EINVAL;
593 } 608 }
594 609
595 return init_request(client, request, client->device->node_id, 610 return init_request(client, &arg->send_request, client->device->node_id,
596 client->device->max_speed); 611 client->device->max_speed);
597} 612}
598 613
@@ -683,9 +698,9 @@ static void release_address_handler(struct client *client,
683 kfree(r); 698 kfree(r);
684} 699}
685 700
686static int ioctl_allocate(struct client *client, void *buffer) 701static int ioctl_allocate(struct client *client, union ioctl_arg *arg)
687{ 702{
688 struct fw_cdev_allocate *request = buffer; 703 struct fw_cdev_allocate *a = &arg->allocate;
689 struct address_handler_resource *r; 704 struct address_handler_resource *r;
690 struct fw_address_region region; 705 struct fw_address_region region;
691 int ret; 706 int ret;
@@ -694,13 +709,13 @@ static int ioctl_allocate(struct client *client, void *buffer)
694 if (r == NULL) 709 if (r == NULL)
695 return -ENOMEM; 710 return -ENOMEM;
696 711
697 region.start = request->offset; 712 region.start = a->offset;
698 region.end = request->offset + request->length; 713 region.end = a->offset + a->length;
699 r->handler.length = request->length; 714 r->handler.length = a->length;
700 r->handler.address_callback = handle_request; 715 r->handler.address_callback = handle_request;
701 r->handler.callback_data = r; 716 r->handler.callback_data = r;
702 r->closure = request->closure; 717 r->closure = a->closure;
703 r->client = client; 718 r->client = client;
704 719
705 ret = fw_core_add_address_handler(&r->handler, &region); 720 ret = fw_core_add_address_handler(&r->handler, &region);
706 if (ret < 0) { 721 if (ret < 0) {
@@ -714,27 +729,25 @@ static int ioctl_allocate(struct client *client, void *buffer)
714 release_address_handler(client, &r->resource); 729 release_address_handler(client, &r->resource);
715 return ret; 730 return ret;
716 } 731 }
717 request->handle = r->resource.handle; 732 a->handle = r->resource.handle;
718 733
719 return 0; 734 return 0;
720} 735}
721 736
722static int ioctl_deallocate(struct client *client, void *buffer) 737static int ioctl_deallocate(struct client *client, union ioctl_arg *arg)
723{ 738{
724 struct fw_cdev_deallocate *request = buffer; 739 return release_client_resource(client, arg->deallocate.handle,
725