Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=e0e60215552d4d40caf581a8d3247203fe948fe7
Commit:     e0e60215552d4d40caf581a8d3247203fe948fe7
Parent:     d94a983526cb868658c958ab689410dc1c6a31f3
Author:     Stefan Richter <[EMAIL PROTECTED]>
AuthorDate: Sun Feb 3 23:08:58 2008 +0100
Committer:  Stefan Richter <[EMAIL PROTECTED]>
CommitDate: Sat Feb 16 15:40:34 2008 +0100

    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 <[EMAIL PROTECTED]>
---
 drivers/firewire/fw-sbp2.c |   39 ++++++++++++++++++++++++++++-----------
 1 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c
index 4a118fb..32b50f1 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,
 
 static void
 complete_agent_reset_write(struct fw_card *card, int rcode,
-                          void *payload, size_t length, void *data)
+                          void *payload, size_t length, void *done)
 {
-       struct fw_transaction *t = data;
+       complete(done);
+}
+
+static void sbp2_agent_reset(struct sbp2_logical_unit *lu)
+{
+       struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
+       DECLARE_COMPLETION_ONSTACK(done);
+       struct fw_transaction t;
+       static u32 z;
 
-       kfree(t);
+       fw_send_request(device->card, &t, TCODE_WRITE_QUADLET_REQUEST,
+                       lu->tgt->node_id, lu->generation, device->max_speed,
+                       lu->command_block_agent_address + SBP2_AGENT_RESET,
+                       &z, sizeof(z), complete_agent_reset_write, &done);
+       wait_for_completion(&done);
 }
 
-static int sbp2_agent_reset(struct sbp2_logical_unit *lu)
+static void
+complete_agent_reset_write_no_wait(struct fw_card *card, int rcode,
+                                  void *payload, size_t length, void *data)
+{
+       kfree(data);
+}
+
+static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu)
 {
        struct fw_device *device = fw_device(lu->tgt->unit->device.parent);
        struct fw_transaction *t;
-       static u32 zero;
+       static u32 z;
 
-       t = kzalloc(sizeof(*t), GFP_ATOMIC);
+       t = kmalloc(sizeof(*t), GFP_ATOMIC);
        if (t == NULL)
-               return -ENOMEM;
+               return;
 
        fw_send_request(device->card, t, TCODE_WRITE_QUADLET_REQUEST,
                        lu->tgt->node_id, lu->generation, device->max_speed,
                        lu->command_block_agent_address + SBP2_AGENT_RESET,
-                       &zero, sizeof(zero), complete_agent_reset_write, t);
-
-       return 0;
+                       &z, sizeof(z), complete_agent_reset_write_no_wait, t);
 }
 
 static void sbp2_release_target(struct kref *kref)
@@ -1086,7 +1103,7 @@ complete_command_orb(struct sbp2_orb *base_orb, struct 
sbp2_status *status)
 
        if (status != NULL) {
                if (STATUS_GET_DEAD(*status))
-                       sbp2_agent_reset(orb->lu);
+                       sbp2_agent_reset_no_wait(orb->lu);
 
                switch (STATUS_GET_RESPONSE(*status)) {
                case SBP2_STATUS_REQUEST_COMPLETE:
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to