aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/firewire/core-transaction.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c
index 87d6f2d2f02d..d39cfa45817a 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -31,6 +31,7 @@
31#include <linux/kernel.h> 31#include <linux/kernel.h>
32#include <linux/list.h> 32#include <linux/list.h>
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/rculist.h>
34#include <linux/slab.h> 35#include <linux/slab.h>
35#include <linux/spinlock.h> 36#include <linux/spinlock.h>
36#include <linux/string.h> 37#include <linux/string.h>
@@ -489,7 +490,7 @@ static struct fw_address_handler *lookup_overlapping_address_handler(
489{ 490{
490 struct fw_address_handler *handler; 491 struct fw_address_handler *handler;
491 492
492 list_for_each_entry(handler, list, link) { 493 list_for_each_entry_rcu(handler, list, link) {
493 if (handler->offset < offset + length && 494 if (handler->offset < offset + length &&
494 offset < handler->offset + handler->length) 495 offset < handler->offset + handler->length)
495 return handler; 496 return handler;
@@ -510,7 +511,7 @@ static struct fw_address_handler *lookup_enclosing_address_handler(
510{ 511{
511 struct fw_address_handler *handler; 512 struct fw_address_handler *handler;
512 513
513 list_for_each_entry(handler, list, link) { 514 list_for_each_entry_rcu(handler, list, link) {
514 if (is_enclosing_handler(handler, offset, length)) 515 if (is_enclosing_handler(handler, offset, length))
515 return handler; 516 return handler;
516 } 517 }
@@ -588,7 +589,7 @@ int fw_core_add_address_handler(struct fw_address_handler *handler,
588 if (other != NULL) { 589 if (other != NULL) {
589 handler->offset += other->length; 590 handler->offset += other->length;
590 } else { 591 } else {
591 list_add_tail(&handler->link, &address_handler_list); 592 list_add_tail_rcu(&handler->link, &address_handler_list);
592 ret = 0; 593 ret = 0;
593 break; 594 break;
594 } 595 }
@@ -609,8 +610,9 @@ EXPORT_SYMBOL(fw_core_add_address_handler);
609void fw_core_remove_address_handler(struct fw_address_handler *handler) 610void fw_core_remove_address_handler(struct fw_address_handler *handler)
610{ 611{
611 spin_lock_bh(&address_handler_lock); 612 spin_lock_bh(&address_handler_lock);
612 list_del(&handler->link); 613 list_del_rcu(&handler->link);
613 spin_unlock_bh(&address_handler_lock); 614 spin_unlock_bh(&address_handler_lock);
615 synchronize_rcu();
614} 616}
615EXPORT_SYMBOL(fw_core_remove_address_handler); 617EXPORT_SYMBOL(fw_core_remove_address_handler);
616 618
@@ -844,7 +846,7 @@ static void handle_exclusive_region_request(struct fw_card *card,
844 if (tcode == TCODE_LOCK_REQUEST) 846 if (tcode == TCODE_LOCK_REQUEST)
845 tcode = 0x10 + HEADER_GET_EXTENDED_TCODE(p->header[3]); 847 tcode = 0x10 + HEADER_GET_EXTENDED_TCODE(p->header[3]);
846 848
847 spin_lock_bh(&address_handler_lock); 849 rcu_read_lock();
848 handler = lookup_enclosing_address_handler(&address_handler_list, 850 handler = lookup_enclosing_address_handler(&address_handler_list,
849 offset, request->length); 851 offset, request->length);
850 if (handler) 852 if (handler)
@@ -853,7 +855,7 @@ static void handle_exclusive_region_request(struct fw_card *card,
853 p->generation, offset, 855 p->generation, offset,
854 request->data, request->length, 856 request->data, request->length,
855 handler->callback_data); 857 handler->callback_data);
856 spin_unlock_bh(&address_handler_lock); 858 rcu_read_unlock();
857 859
858 if (!handler) 860 if (!handler)
859 fw_send_response(card, request, RCODE_ADDRESS_ERROR); 861 fw_send_response(card, request, RCODE_ADDRESS_ERROR);
@@ -886,8 +888,8 @@ static void handle_fcp_region_request(struct fw_card *card,
886 return; 888 return;
887 } 889 }
888 890
889 spin_lock_bh(&address_handler_lock); 891 rcu_read_lock();
890 list_for_each_entry(handler, &address_handler_list, link) { 892 list_for_each_entry_rcu(handler, &address_handler_list, link) {
891 if (is_enclosing_handler(handler, offset, request->length)) 893 if (is_enclosing_handler(handler, offset, request->length))
892 handler->address_callback(card, NULL, tcode, 894 handler->address_callback(card, NULL, tcode,
893 destination, source, 895 destination, source,
@@ -896,7 +898,7 @@ static void handle_fcp_region_request(struct fw_card *card,
896 request->length, 898 request->length,
897 handler->callback_data); 899 handler->callback_data);
898 } 900 }
899 spin_unlock_bh(&address_handler_lock); 901 rcu_read_unlock();
900 902
901 fw_send_response(card, request, RCODE_COMPLETE); 903 fw_send_response(card, request, RCODE_COMPLETE);
902} 904}