aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-02-03 17:08:58 -0500
committerStefan Richter <stefanr@s5r6.in-berlin.de>2008-02-16 09:40:34 -0500
commite0e60215552d4d40caf581a8d3247203fe948fe7 (patch)
tree654aa22d8d13692fe8aa30ea9cd7301fccdb5e67 /drivers/firewire
parentd94a983526cb868658c958ab689410dc1c6a31f3 (diff)
firewire: fw-sbp2: wait for completion of fetch agent reset
Like the old sbp2 driver, wait for the write transaction to the AGENT_RESET to complete before proceeding (after login, after reconnect, or in SCSI error handling). There is one occasion where AGENT_RESET is written to from atomic context when getting DEAD status for a command ORB. There we still continue without waiting for the transaction to complete because this is more difficult to fix... Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/fw-sbp2.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 4a118fbc7b24..32b50f13e7a8 100644
--- a/drivers/firewire/fw-sbp2.c
+++ b/drivers/firewire/fw-sbp2.c
@@ -603,29 +603,46 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id,
603 603
604static void 604static void
605complete_agent_reset_write(struct fw_card *card, int rcode, 605complete_agent_reset_write(struct fw_card *card, int rcode,
606 void *payload, size_t length, void *data) 606 void *payload, size_t length, void *done)
607{ 607{
608 struct fw_transaction *t = data; 608 complete(done);
609}
610
611static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
612{
613 struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
614 DECLARE_COMPLETION_ONSTACK(done);
615 struct fw_transaction t;
616 static u32 z;
609 617
610 kfree(t); 618 fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
619 lu->tgt->node_id, lu->generation, device->max_speed,
620 lu->command_block_agent_address + SBP2_AGENT_RESET,
621 &z, sizeof(z), complete_agent_reset_write, &done);
622 wait_for_completion(&done);
611} 623}
612 624
613static int sbp2_agent_reset(struct sbp2_logical_unit *lu) 625static void
626complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
627 void *payload, size_t length, void *data)
628{
629 kfree(data);
630}
631
632static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
614{ 633{
615 struct fw_device *device = fw_device(lu->tgt->unit->device.parent); 634 struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
616 struct fw_transaction *t; 635 struct fw_transaction *t;
617 static u32 zero; 636 static u32 z;
618 637
619 t = kzalloc(sizeof(*t), GFP_ATOMIC); 638 t = kmalloc(sizeof(*t), GFP_ATOMIC);
620 if (t == NULL) 639 if (t == NULL)
621 return -ENOMEM; 640 return;
622 641
623 fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST, 642 fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
624 lu->tgt->node_id, lu->generation, device->max_speed, 643 lu->tgt->node_id, lu->generation, device->max_speed,
625 lu->command_block_agent_address + SBP2_AGENT_RESET, 644 lu->command_block_agent_address + SBP2_AGENT_RESET,
626 &zero, sizeof(zero), complete_agent_reset_write, t); 645 &z, sizeof(z), complete_agent_reset_write_no_wait, t);
627
628 return 0;
629} 646}
630 647
631static void sbp2_release_target(struct kref *kref) 648static void sbp2_release_target(struct kref *kref)
@@ -1086,7 +1103,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status)
1086 1103
1087 if (status != NULL) { 1104 if (status != NULL) {
1088 if (STATUS_GET_DEAD(*status)) 1105 if (STATUS_GET_DEAD(*status))
1089 sbp2_agent_reset(orb->lu); 1106 sbp2_agent_reset_no_wait(orb->lu);
1090 1107
1091 switch (STATUS_GET_RESPONSE(*status)) { 1108 switch (STATUS_GET_RESPONSE(*status)) {
1092 case SBP2_STATUS_REQUEST_COMPLETE: 1109 case SBP2_STATUS_REQUEST_COMPLETE: