Skip to content

Commit

Permalink
firewire: fw-sbp2: wait for completion of fetch agent reset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Stefan Richter committed Feb 16, 2008
1 parent d94a983 commit e0e6021
Showing 1 changed file with 28 additions and 11 deletions.
39 changes: 28 additions & 11 deletions drivers/firewire/fw-sbp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit e0e6021

Please sign in to comment.