aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2005-10-20 00:23:46 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-20 02:04:30 -0400
commit4a9949d7ac9e2bc51939f27b184be6e1bd99004e (patch)
tree85f67b527d3ff5a550ada8e08600f1400ddc5960 /drivers/ieee1394
parentc367c21c93ccdaf7e1e124891633d89f9ae77f54 (diff)
[PATCH] raw1394: fix locking in the presence of SMP and interrupts
Changes all spinlocks that can be held during an irq handler to disable interrupts while the lock is held. Changes spin_[un]lock_irq to use the irqsave/irqrestore variants for robustness and readability. In raw1394.c:handle_iso_listen(), don't grab host_info_lock at all -- we're not accessing host_info_list or host_count, and holding this lock while trying to tasklet_kill the iso tasklet this can cause an ABBA deadlock if ohci:dma_rcv_tasklet is running and tries to grab host_info_lock in raw1394.c:receive_iso. Test program attached reliably deadlocks all SMP machines I have been able to test without this patch. Signed-off-by: Andy Wingo <wingo@pobox.com> Acked-by: Ben Collins <bcollins@ubuntu.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/ohci1394.c6
-rw-r--r--drivers/ieee1394/raw1394.c100
2 files changed, 57 insertions, 49 deletions
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c
index 6a6acbd80af4..4cf9b8f3e336 100644
--- a/drivers/ieee1394/ohci1394.c
+++ b/drivers/ieee1394/ohci1394.c
@@ -2283,8 +2283,9 @@ static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci,
2283{ 2283{
2284 struct ohci1394_iso_tasklet *t; 2284 struct ohci1394_iso_tasklet *t;
2285 unsigned long mask; 2285 unsigned long mask;
2286 unsigned long flags;
2286 2287
2287 spin_lock(&ohci->iso_tasklet_list_lock); 2288 spin_lock_irqsave(&ohci->iso_tasklet_list_lock, flags);
2288 2289
2289 list_for_each_entry(t, &ohci->iso_tasklet_list, link) { 2290 list_for_each_entry(t, &ohci->iso_tasklet_list, link) {
2290 mask = 1 << t->context; 2291 mask = 1 << t->context;
@@ -2295,8 +2296,7 @@ static void ohci_schedule_iso_tasklets(struct ti_ohci *ohci,
2295 tasklet_schedule(&t->tasklet); 2296 tasklet_schedule(&t->tasklet);
2296 } 2297 }
2297 2298
2298 spin_unlock(&ohci->iso_tasklet_list_lock); 2299 spin_unlock_irqrestore(&ohci->iso_tasklet_list_lock, flags);
2299
2300} 2300}
2301 2301
2302static irqreturn_t ohci_irq_handler(int irq, void *dev_id, 2302static irqreturn_t ohci_irq_handler(int irq, void *dev_id,
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 315f5ca8bedb..0470f77a9cd1 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -412,6 +412,7 @@ static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
412static ssize_t raw1394_read(struct file *file, char __user * buffer, 412static ssize_t raw1394_read(struct file *file, char __user * buffer,
413 size_t count, loff_t * offset_is_ignored) 413 size_t count, loff_t * offset_is_ignored)
414{ 414{
415 unsigned long flags;
415 struct file_info *fi = (struct file_info *)file->private_data; 416 struct file_info *fi = (struct file_info *)file->private_data;
416 struct list_head *lh; 417 struct list_head *lh;
417 struct pending_request *req; 418 struct pending_request *req;
@@ -435,10 +436,10 @@ static ssize_t raw1394_read(struct file *file, char __user * buffer,
435 } 436 }
436 } 437 }
437 438
438 spin_lock_irq(&fi->reqlists_lock); 439 spin_lock_irqsave(&fi->reqlists_lock, flags);
439 lh = fi->req_complete.next; 440 lh = fi->req_complete.next;
440 list_del(lh); 441 list_del(lh);
441 spin_unlock_irq(&fi->reqlists_lock); 442 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
442 443
443 req = list_entry(lh, struct pending_request, list); 444 req = list_entry(lh, struct pending_request, list);
444 445
@@ -486,6 +487,7 @@ static int state_opened(struct file_info *fi, struct pending_request *req)
486 487
487static int state_initialized(struct file_info *fi, struct pending_request *req) 488static int state_initialized(struct file_info *fi, struct pending_request *req)
488{ 489{
490 unsigned long flags;
489 struct host_info *hi; 491 struct host_info *hi;
490 struct raw1394_khost_list *khl; 492 struct raw1394_khost_list *khl;
491 493
@@ -499,7 +501,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
499 501
500 switch (req->req.type) { 502 switch (req->req.type) {
501 case RAW1394_REQ_LIST_CARDS: 503 case RAW1394_REQ_LIST_CARDS:
502 spin_lock_irq(&host_info_lock); 504 spin_lock_irqsave(&host_info_lock, flags);
503 khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count, 505 khl = kmalloc(sizeof(struct raw1394_khost_list) * host_count,
504 SLAB_ATOMIC); 506 SLAB_ATOMIC);
505 507
@@ -513,7 +515,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
513 khl++; 515 khl++;
514 } 516 }
515 } 517 }
516 spin_unlock_irq(&host_info_lock); 518 spin_unlock_irqrestore(&host_info_lock, flags);
517 519
518 if (khl != NULL) { 520 if (khl != NULL) {
519 req->req.error = RAW1394_ERROR_NONE; 521 req->req.error = RAW1394_ERROR_NONE;
@@ -528,7 +530,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
528 break; 530 break;
529 531
530 case RAW1394_REQ_SET_CARD: 532 case RAW1394_REQ_SET_CARD:
531 spin_lock_irq(&host_info_lock); 533 spin_lock_irqsave(&host_info_lock, flags);
532 if (req->req.misc < host_count) { 534 if (req->req.misc < host_count) {
533 list_for_each_entry(hi, &host_info_list, list) { 535 list_for_each_entry(hi, &host_info_list, list) {
534 if (!req->req.misc--) 536 if (!req->req.misc--)
@@ -550,7 +552,7 @@ static int state_initialized(struct file_info *fi, struct pending_request *req)
550 } else { 552 } else {
551 req->req.error = RAW1394_ERROR_INVALID_ARG; 553 req->req.error = RAW1394_ERROR_INVALID_ARG;
552 } 554 }
553 spin_unlock_irq(&host_info_lock); 555 spin_unlock_irqrestore(&host_info_lock, flags);
554 556
555 req->req.length = 0; 557 req->req.length = 0;
556 break; 558 break;
@@ -569,7 +571,6 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
569{ 571{
570 int channel = req->req.misc; 572 int channel = req->req.misc;
571 573
572 spin_lock_irq(&host_info_lock);
573 if ((channel > 63) || (channel < -64)) { 574 if ((channel > 63) || (channel < -64)) {
574 req->req.error = RAW1394_ERROR_INVALID_ARG; 575 req->req.error = RAW1394_ERROR_INVALID_ARG;
575 } else if (channel >= 0) { 576 } else if (channel >= 0) {
@@ -601,7 +602,6 @@ static void handle_iso_listen(struct file_info *fi, struct pending_request *req)
601 602
602 req->req.length = 0; 603 req->req.length = 0;
603 queue_complete_req(req); 604 queue_complete_req(req);
604 spin_unlock_irq(&host_info_lock);
605} 605}
606 606
607static void handle_fcp_listen(struct file_info *fi, struct pending_request *req) 607static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
@@ -627,6 +627,7 @@ static void handle_fcp_listen(struct file_info *fi, struct pending_request *req)
627static int handle_async_request(struct file_info *fi, 627static int handle_async_request(struct file_info *fi,
628 struct pending_request *req, int node) 628 struct pending_request *req, int node)
629{ 629{
630 unsigned long flags;
630 struct hpsb_packet *packet = NULL; 631 struct hpsb_packet *packet = NULL;
631 u64 addr = req->req.address & 0xffffffffffffULL; 632 u64 addr = req->req.address & 0xffffffffffffULL;
632 633
@@ -761,9 +762,9 @@ static int handle_async_request(struct file_info *fi,
761 hpsb_set_packet_complete_task(packet, 762 hpsb_set_packet_complete_task(packet,
762 (void (*)(void *))queue_complete_cb, req); 763 (void (*)(void *))queue_complete_cb, req);
763 764
764 spin_lock_irq(&fi->reqlists_lock); 765 spin_lock_irqsave(&fi->reqlists_lock, flags);
765 list_add_tail(&req->list, &fi->req_pending); 766 list_add_tail(&req->list, &fi->req_pending);
766 spin_unlock_irq(&fi->reqlists_lock); 767 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
767 768
768 packet->generation = req->req.generation; 769 packet->generation = req->req.generation;
769 770
@@ -779,6 +780,7 @@ static int handle_async_request(struct file_info *fi,
779static int handle_iso_send(struct file_info *fi, struct pending_request *req, 780static int handle_iso_send(struct file_info *fi, struct pending_request *req,
780 int channel) 781 int channel)
781{ 782{
783 unsigned long flags;
782 struct hpsb_packet *packet; 784 struct hpsb_packet *packet;
783 785
784 packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f, 786 packet = hpsb_make_isopacket(fi->host, req->req.length, channel & 0x3f,
@@ -804,9 +806,9 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
804 (void (*)(void *))queue_complete_req, 806 (void (*)(void *))queue_complete_req,
805 req); 807 req);
806 808
807 spin_lock_irq(&fi->reqlists_lock); 809 spin_lock_irqsave(&fi->reqlists_lock, flags);
808 list_add_tail(&req->list, &fi->req_pending); 810 list_add_tail(&req->list, &fi->req_pending);
809 spin_unlock_irq(&fi->reqlists_lock); 811 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
810 812
811 /* Update the generation of the packet just before sending. */ 813 /* Update the generation of the packet just before sending. */
812 packet->generation = req->req.generation; 814 packet->generation = req->req.generation;
@@ -821,6 +823,7 @@ static int handle_iso_send(struct file_info *fi, struct pending_request *req,
821 823
822static int handle_async_send(struct file_info *fi, struct pending_request *req) 824static int handle_async_send(struct file_info *fi, struct pending_request *req)
823{ 825{
826 unsigned long flags;
824 struct hpsb_packet *packet; 827 struct hpsb_packet *packet;
825 int header_length = req->req.misc & 0xffff; 828 int header_length = req->req.misc & 0xffff;
826 int expect_response = req->req.misc >> 16; 829 int expect_response = req->req.misc >> 16;
@@ -867,9 +870,9 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
867 hpsb_set_packet_complete_task(packet, 870 hpsb_set_packet_complete_task(packet,
868 (void (*)(void *))queue_complete_cb, req); 871 (void (*)(void *))queue_complete_cb, req);
869 872
870 spin_lock_irq(&fi->reqlists_lock); 873 spin_lock_irqsave(&fi->reqlists_lock, flags);
871 list_add_tail(&req->list, &fi->req_pending); 874 list_add_tail(&req->list, &fi->req_pending);
872 spin_unlock_irq(&fi->reqlists_lock); 875 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
873 876
874 /* Update the generation of the packet just before sending. */ 877 /* Update the generation of the packet just before sending. */
875 packet->generation = req->req.generation; 878 packet->generation = req->req.generation;
@@ -885,6 +888,7 @@ static int handle_async_send(struct file_info *fi, struct pending_request *req)
885static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer, 888static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
886 u64 addr, size_t length, u16 flags) 889 u64 addr, size_t length, u16 flags)
887{ 890{
891 unsigned long irqflags;
888 struct pending_request *req; 892 struct pending_request *req;
889 struct host_info *hi; 893 struct host_info *hi;
890 struct file_info *fi = NULL; 894 struct file_info *fi = NULL;
@@ -899,7 +903,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
899 "addr: %4.4x %8.8x length: %Zu", nodeid, 903 "addr: %4.4x %8.8x length: %Zu", nodeid,
900 (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), 904 (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
901 length); 905 length);
902 spin_lock(&host_info_lock); 906 spin_lock_irqsave(&host_info_lock, irqflags);
903 hi = find_host_info(host); /* search address-entry */ 907 hi = find_host_info(host); /* search address-entry */
904 if (hi != NULL) { 908 if (hi != NULL) {
905 list_for_each_entry(fi, &hi->file_info_list, list) { 909 list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -924,7 +928,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
924 if (!found) { 928 if (!found) {
925 printk(KERN_ERR "raw1394: arm_read FAILED addr_entry not found" 929 printk(KERN_ERR "raw1394: arm_read FAILED addr_entry not found"
926 " -> rcode_address_error\n"); 930 " -> rcode_address_error\n");
927 spin_unlock(&host_info_lock); 931 spin_unlock_irqrestore(&host_info_lock, irqflags);
928 return (RCODE_ADDRESS_ERROR); 932 return (RCODE_ADDRESS_ERROR);
929 } else { 933 } else {
930 DBGMSG("arm_read addr_entry FOUND"); 934 DBGMSG("arm_read addr_entry FOUND");
@@ -954,7 +958,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
954 req = __alloc_pending_request(SLAB_ATOMIC); 958 req = __alloc_pending_request(SLAB_ATOMIC);
955 if (!req) { 959 if (!req) {
956 DBGMSG("arm_read -> rcode_conflict_error"); 960 DBGMSG("arm_read -> rcode_conflict_error");
957 spin_unlock(&host_info_lock); 961 spin_unlock_irqrestore(&host_info_lock, irqflags);
958 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 962 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
959 The request may be retried */ 963 The request may be retried */
960 } 964 }
@@ -974,7 +978,7 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
974 if (!(req->data)) { 978 if (!(req->data)) {
975 free_pending_request(req); 979 free_pending_request(req);
976 DBGMSG("arm_read -> rcode_conflict_error"); 980 DBGMSG("arm_read -> rcode_conflict_error");
977 spin_unlock(&host_info_lock); 981 spin_unlock_irqrestore(&host_info_lock, irqflags);
978 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 982 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
979 The request may be retried */ 983 The request may be retried */
980 } 984 }
@@ -1031,13 +1035,14 @@ static int arm_read(struct hpsb_host *host, int nodeid, quadlet_t * buffer,
1031 sizeof(struct arm_request)); 1035 sizeof(struct arm_request));
1032 queue_complete_req(req); 1036 queue_complete_req(req);
1033 } 1037 }
1034 spin_unlock(&host_info_lock); 1038 spin_unlock_irqrestore(&host_info_lock, irqflags);
1035 return (rcode); 1039 return (rcode);
1036} 1040}
1037 1041
1038static int arm_write(struct hpsb_host *host, int nodeid, int destid, 1042static int arm_write(struct hpsb_host *host, int nodeid, int destid,
1039 quadlet_t * data, u64 addr, size_t length, u16 flags) 1043 quadlet_t * data, u64 addr, size_t length, u16 flags)
1040{ 1044{
1045 unsigned long irqflags;
1041 struct pending_request *req; 1046 struct pending_request *req;
1042 struct host_info *hi; 1047 struct host_info *hi;
1043 struct file_info *fi = NULL; 1048 struct file_info *fi = NULL;
@@ -1052,7 +1057,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
1052 "addr: %4.4x %8.8x length: %Zu", nodeid, 1057 "addr: %4.4x %8.8x length: %Zu", nodeid,
1053 (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF), 1058 (u16) ((addr >> 32) & 0xFFFF), (u32) (addr & 0xFFFFFFFF),
1054 length); 1059 length);
1055 spin_lock(&host_info_lock); 1060 spin_lock_irqsave(&host_info_lock, irqflags);
1056 hi = find_host_info(host); /* search address-entry */ 1061 hi = find_host_info(host); /* search address-entry */
1057 if (hi != NULL) { 1062 if (hi != NULL) {
1058 list_for_each_entry(fi, &hi->file_info_list, list) { 1063 list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -1077,7 +1082,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
1077 if (!found) { 1082 if (!found) {
1078 printk(KERN_ERR "raw1394: arm_write FAILED addr_entry not found" 1083 printk(KERN_ERR "raw1394: arm_write FAILED addr_entry not found"
1079 " -> rcode_address_error\n"); 1084 " -> rcode_address_error\n");
1080 spin_unlock(&host_info_lock); 1085 spin_unlock_irqrestore(&host_info_lock, irqflags);
1081 return (RCODE_ADDRESS_ERROR); 1086 return (RCODE_ADDRESS_ERROR);
1082 } else { 1087 } else {
1083 DBGMSG("arm_write addr_entry FOUND"); 1088 DBGMSG("arm_write addr_entry FOUND");
@@ -1106,7 +1111,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
1106 req = __alloc_pending_request(SLAB_ATOMIC); 1111 req = __alloc_pending_request(SLAB_ATOMIC);
1107 if (!req) { 1112 if (!req) {
1108 DBGMSG("arm_write -> rcode_conflict_error"); 1113 DBGMSG("arm_write -> rcode_conflict_error");
1109 spin_unlock(&host_info_lock); 1114 spin_unlock_irqrestore(&host_info_lock, irqflags);
1110 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 1115 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
1111 The request my be retried */ 1116 The request my be retried */
1112 } 1117 }
@@ -1118,7 +1123,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
1118 if (!(req->data)) { 1123 if (!(req->data)) {
1119 free_pending_request(req); 1124 free_pending_request(req);
1120 DBGMSG("arm_write -> rcode_conflict_error"); 1125 DBGMSG("arm_write -> rcode_conflict_error");
1121 spin_unlock(&host_info_lock); 1126 spin_unlock_irqrestore(&host_info_lock, irqflags);
1122 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 1127 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
1123 The request may be retried */ 1128 The request may be retried */
1124 } 1129 }
@@ -1165,7 +1170,7 @@ static int arm_write(struct hpsb_host *host, int nodeid, int destid,
1165 sizeof(struct arm_request)); 1170 sizeof(struct arm_request));
1166 queue_complete_req(req); 1171 queue_complete_req(req);
1167 } 1172 }
1168 spin_unlock(&host_info_lock); 1173 spin_unlock_irqrestore(&host_info_lock, irqflags);
1169 return (rcode); 1174 return (rcode);
1170} 1175}
1171 1176
@@ -1173,6 +1178,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
1173 u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode, 1178 u64 addr, quadlet_t data, quadlet_t arg, int ext_tcode,
1174 u16 flags) 1179 u16 flags)
1175{ 1180{
1181 unsigned long irqflags;
1176 struct pending_request *req; 1182 struct pending_request *req;
1177 struct host_info *hi; 1183 struct host_info *hi;
1178 struct file_info *fi = NULL; 1184 struct file_info *fi = NULL;
@@ -1198,7 +1204,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
1198 (u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF, 1204 (u32) (addr & 0xFFFFFFFF), ext_tcode & 0xFF,
1199 be32_to_cpu(data), be32_to_cpu(arg)); 1205 be32_to_cpu(data), be32_to_cpu(arg));
1200 } 1206 }
1201 spin_lock(&host_info_lock); 1207 spin_lock_irqsave(&host_info_lock, irqflags);
1202 hi = find_host_info(host); /* search address-entry */ 1208 hi = find_host_info(host); /* search address-entry */
1203 if (hi != NULL) { 1209 if (hi != NULL) {
1204 list_for_each_entry(fi, &hi->file_info_list, list) { 1210 list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -1224,7 +1230,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
1224 if (!found) { 1230 if (!found) {
1225 printk(KERN_ERR "raw1394: arm_lock FAILED addr_entry not found" 1231 printk(KERN_ERR "raw1394: arm_lock FAILED addr_entry not found"
1226 " -> rcode_address_error\n"); 1232 " -> rcode_address_error\n");
1227 spin_unlock(&host_info_lock); 1233 spin_unlock_irqrestore(&host_info_lock, irqflags);
1228 return (RCODE_ADDRESS_ERROR); 1234 return (RCODE_ADDRESS_ERROR);
1229 } else { 1235 } else {
1230 DBGMSG("arm_lock addr_entry FOUND"); 1236 DBGMSG("arm_lock addr_entry FOUND");
@@ -1307,7 +1313,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
1307 req = __alloc_pending_request(SLAB_ATOMIC); 1313 req = __alloc_pending_request(SLAB_ATOMIC);
1308 if (!req) { 1314 if (!req) {
1309 DBGMSG("arm_lock -> rcode_conflict_error"); 1315 DBGMSG("arm_lock -> rcode_conflict_error");
1310 spin_unlock(&host_info_lock); 1316 spin_unlock_irqrestore(&host_info_lock, irqflags);
1311 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 1317 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
1312 The request may be retried */ 1318 The request may be retried */
1313 } 1319 }
@@ -1316,7 +1322,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
1316 if (!(req->data)) { 1322 if (!(req->data)) {
1317 free_pending_request(req); 1323 free_pending_request(req);
1318 DBGMSG("arm_lock -> rcode_conflict_error"); 1324 DBGMSG("arm_lock -> rcode_conflict_error");
1319 spin_unlock(&host_info_lock); 1325 spin_unlock_irqrestore(&host_info_lock, irqflags);
1320 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 1326 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
1321 The request may be retried */ 1327 The request may be retried */
1322 } 1328 }
@@ -1382,7 +1388,7 @@ static int arm_lock(struct hpsb_host *host, int nodeid, quadlet_t * store,
1382 sizeof(struct arm_response) + 2 * sizeof(*store)); 1388 sizeof(struct arm_response) + 2 * sizeof(*store));
1383 queue_complete_req(req); 1389 queue_complete_req(req);
1384 } 1390 }
1385 spin_unlock(&host_info_lock); 1391 spin_unlock_irqrestore(&host_info_lock, irqflags);
1386 return (rcode); 1392 return (rcode);
1387} 1393}
1388 1394
@@ -1390,6 +1396,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
1390 u64 addr, octlet_t data, octlet_t arg, int ext_tcode, 1396 u64 addr, octlet_t data, octlet_t arg, int ext_tcode,
1391 u16 flags) 1397 u16 flags)
1392{ 1398{
1399 unsigned long irqflags;
1393 struct pending_request *req; 1400 struct pending_request *req;
1394 struct host_info *hi; 1401 struct host_info *hi;
1395 struct file_info *fi = NULL; 1402 struct file_info *fi = NULL;
@@ -1422,7 +1429,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
1422 (u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF), 1429 (u32) ((be64_to_cpu(arg) >> 32) & 0xFFFFFFFF),
1423 (u32) (be64_to_cpu(arg) & 0xFFFFFFFF)); 1430 (u32) (be64_to_cpu(arg) & 0xFFFFFFFF));
1424 } 1431 }
1425 spin_lock(&host_info_lock); 1432 spin_lock_irqsave(&host_info_lock, irqflags);
1426 hi = find_host_info(host); /* search addressentry in file_info's for host */ 1433 hi = find_host_info(host); /* search addressentry in file_info's for host */
1427 if (hi != NULL) { 1434 if (hi != NULL) {
1428 list_for_each_entry(fi, &hi->file_info_list, list) { 1435 list_for_each_entry(fi, &hi->file_info_list, list) {
@@ -1449,7 +1456,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
1449 printk(KERN_ERR 1456 printk(KERN_ERR
1450 "raw1394: arm_lock64 FAILED addr_entry not found" 1457 "raw1394: arm_lock64 FAILED addr_entry not found"
1451 " -> rcode_address_error\n"); 1458 " -> rcode_address_error\n");
1452 spin_unlock(&host_info_lock); 1459 spin_unlock_irqrestore(&host_info_lock, irqflags);
1453 return (RCODE_ADDRESS_ERROR); 1460 return (RCODE_ADDRESS_ERROR);
1454 } else { 1461 } else {
1455 DBGMSG("arm_lock64 addr_entry FOUND"); 1462 DBGMSG("arm_lock64 addr_entry FOUND");
@@ -1533,7 +1540,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
1533 DBGMSG("arm_lock64 -> entering notification-section"); 1540 DBGMSG("arm_lock64 -> entering notification-section");
1534 req = __alloc_pending_request(SLAB_ATOMIC); 1541 req = __alloc_pending_request(SLAB_ATOMIC);
1535 if (!req) { 1542 if (!req) {
1536 spin_unlock(&host_info_lock); 1543 spin_unlock_irqrestore(&host_info_lock, irqflags);
1537 DBGMSG("arm_lock64 -> rcode_conflict_error"); 1544 DBGMSG("arm_lock64 -> rcode_conflict_error");
1538 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 1545 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
1539 The request may be retried */ 1546 The request may be retried */
@@ -1542,7 +1549,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
1542 req->data = kmalloc(size, SLAB_ATOMIC); 1549 req->data = kmalloc(size, SLAB_ATOMIC);
1543 if (!(req->data)) { 1550 if (!(req->data)) {
1544 free_pending_request(req); 1551 free_pending_request(req);
1545 spin_unlock(&host_info_lock); 1552 spin_unlock_irqrestore(&host_info_lock, irqflags);
1546 DBGMSG("arm_lock64 -> rcode_conflict_error"); 1553 DBGMSG("arm_lock64 -> rcode_conflict_error");
1547 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected. 1554 return (RCODE_CONFLICT_ERROR); /* A resource conflict was detected.
1548 The request may be retried */ 1555 The request may be retried */
@@ -1609,7 +1616,7 @@ static int arm_lock64(struct hpsb_host *host, int nodeid, octlet_t * store,
1609 sizeof(struct arm_response) + 2 * sizeof(*store)); 1616 sizeof(struct arm_response) + 2 * sizeof(*store));
1610 queue_complete_req(req); 1617 queue_complete_req(req);
1611 } 1618 }
1612 spin_unlock(&host_info_lock); 1619 spin_unlock_irqrestore(&host_info_lock, irqflags);
1613 return (rcode); 1620 return (rcode);
1614} 1621}
1615 1622
@@ -1980,6 +1987,7 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
1980 struct hpsb_packet *packet = NULL; 1987 struct hpsb_packet *packet = NULL;
1981 int retval = 0; 1988 int retval = 0;
1982 quadlet_t data; 1989 quadlet_t data;
1990 unsigned long flags;
1983 1991
1984 data = be32_to_cpu((u32) req->req.sendb); 1992 data = be32_to_cpu((u32) req->req.sendb);
1985 DBGMSG("write_phypacket called - quadlet 0x%8.8x ", data); 1993 DBGMSG("write_phypacket called - quadlet 0x%8.8x ", data);
@@ -1990,9 +1998,9 @@ static int write_phypacket(struct file_info *fi, struct pending_request *req)
1990 req->packet = packet; 1998 req->packet = packet;
1991 hpsb_set_packet_complete_task(packet, 1999 hpsb_set_packet_complete_task(packet,
1992 (void (*)(void *))queue_complete_cb, req); 2000 (void (*)(void *))queue_complete_cb, req);
1993 spin_lock_irq(&fi->reqlists_lock); 2001 spin_lock_irqsave(&fi->reqlists_lock, flags);
1994 list_add_tail(&req->list, &fi->req_pending); 2002 list_add_tail(&req->list, &fi->req_pending);
1995 spin_unlock_irq(&fi->reqlists_lock); 2003 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
1996 packet->generation = req->req.generation; 2004 packet->generation = req->req.generation;
1997 retval = hpsb_send_packet(packet); 2005 retval = hpsb_send_packet(packet);
1998 DBGMSG("write_phypacket send_packet called => retval: %d ", retval); 2006 DBGMSG("write_phypacket send_packet called => retval: %d ", retval);
@@ -2659,14 +2667,15 @@ static unsigned int raw1394_poll(struct file *file, poll_table * pt)
2659{ 2667{
2660 struct file_info *fi = file->private_data; 2668 struct file_info *fi = file->private_data;
2661 unsigned int mask = POLLOUT | POLLWRNORM; 2669 unsigned int mask = POLLOUT | POLLWRNORM;
2670 unsigned long flags;
2662 2671
2663 poll_wait(file, &fi->poll_wait_complete, pt); 2672 poll_wait(file, &fi->poll_wait_complete, pt);
2664 2673
2665 spin_lock_irq(&fi->reqlists_lock); 2674 spin_lock_irqsave(&fi->reqlists_lock, flags);
2666 if (!list_empty(&fi->req_complete)) { 2675 if (!list_empty(&fi->req_complete)) {
2667 mask |= POLLIN | POLLRDNORM; 2676 mask |= POLLIN | POLLRDNORM;
2668 } 2677 }
2669 spin_unlock_irq(&fi->reqlists_lock); 2678 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
2670 2679
2671 return mask; 2680 return mask;
2672} 2681}
@@ -2710,6 +2719,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
2710 struct arm_addr *arm_addr = NULL; 2719 struct arm_addr *arm_addr = NULL;
2711 int another_host; 2720 int another_host;
2712 int csr_mod = 0; 2721 int csr_mod = 0;
2722 unsigned long flags;
2713 2723
2714 if (fi->iso_state != RAW1394_ISO_INACTIVE) 2724 if (fi->iso_state != RAW1394_ISO_INACTIVE)
2715 raw1394_iso_shutdown(fi); 2725 raw1394_iso_shutdown(fi);
@@ -2720,13 +2730,11 @@ static int raw1394_release(struct inode *inode, struct file *file)
2720 } 2730 }
2721 } 2731 }
2722 2732
2723 spin_lock_irq(&host_info_lock); 2733 spin_lock_irqsave(&host_info_lock, flags);
2724 fi->listen_channels = 0; 2734 fi->listen_channels = 0;
2725 spin_unlock_irq(&host_info_lock);
2726 2735
2727 fail = 0; 2736 fail = 0;
2728 /* set address-entries invalid */ 2737 /* set address-entries invalid */
2729 spin_lock_irq(&host_info_lock);
2730 2738
2731 while (!list_empty(&fi->addr_list)) { 2739 while (!list_empty(&fi->addr_list)) {
2732 another_host = 0; 2740 another_host = 0;
@@ -2777,14 +2785,14 @@ static int raw1394_release(struct inode *inode, struct file *file)
2777 vfree(addr->addr_space_buffer); 2785 vfree(addr->addr_space_buffer);
2778 kfree(addr); 2786 kfree(addr);
2779 } /* while */ 2787 } /* while */
2780 spin_unlock_irq(&host_info_lock); 2788 spin_unlock_irqrestore(&host_info_lock, flags);
2781 if (fail > 0) { 2789 if (fail > 0) {
2782 printk(KERN_ERR "raw1394: during addr_list-release " 2790 printk(KERN_ERR "raw1394: during addr_list-release "
2783 "error(s) occurred \n"); 2791 "error(s) occurred \n");
2784 } 2792 }
2785 2793
2786 while (!done) { 2794 while (!done) {
2787 spin_lock_irq(&fi->reqlists_lock); 2795 spin_lock_irqsave(&fi->reqlists_lock, flags);
2788 2796
2789 while (!list_empty(&fi->req_complete)) { 2797 while (!list_empty(&fi->req_complete)) {
2790 lh = fi->req_complete.next; 2798 lh = fi->req_complete.next;
@@ -2798,7 +2806,7 @@ static int raw1394_release(struct inode *inode, struct file *file)
2798 if (list_empty(&fi->req_pending)) 2806 if (list_empty(&fi->req_pending))
2799 done = 1; 2807 done = 1;
2800 2808
2801 spin_unlock_irq(&fi->reqlists_lock); 2809 spin_unlock_irqrestore(&fi->reqlists_lock, flags);
2802 2810
2803 if (!done) 2811 if (!done)
2804 down_interruptible(&fi->complete_sem); 2812 down_interruptible(&fi->complete_sem);
@@ -2828,9 +2836,9 @@ static int raw1394_release(struct inode *inode, struct file *file)
2828 fi->host->id); 2836 fi->host->id);
2829 2837
2830 if (fi->state == connected) { 2838 if (fi->state == connected) {
2831 spin_lock_irq(&host_info_lock); 2839 spin_lock_irqsave(&host_info_lock, flags);
2832 list_del(&fi->list); 2840 list_del(&fi->list);
2833 spin_unlock_irq(&host_info_lock); 2841 spin_unlock_irqrestore(&host_info_lock, flags);
2834 2842
2835 put_device(&fi->host->device); 2843 put_device(&fi->host->device);
2836 } 2844 }