diff options
author | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-09-06 12:51:27 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-09-12 08:48:40 -0400 |
commit | 094614fc14966bc6a6259ade55f051fe17f36122 (patch) | |
tree | 36ccc96edeb9dff1f947de727599b3d33a2efdd4 /drivers/firewire/sbp2.c | |
parent | 85cb9b68640cf467a99d4b6d518f1293222dbc9e (diff) |
firewire: sbp2: fix status reception
Per SBP-2 clause 5.3, a target shall store 8...32 bytes of status
information. Trailing zeros after the first 8 bytes don't need to be
stored, they are implicit. Fix the status write handler to clear all
unwritten status data.
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/sbp2.c')
-rw-r--r-- | drivers/firewire/sbp2.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index e5df822a8130..8f83bffb43e7 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -425,19 +425,20 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, | |||
425 | struct sbp2_logical_unit *lu = callback_data; | 425 | struct sbp2_logical_unit *lu = callback_data; |
426 | struct sbp2_orb *orb; | 426 | struct sbp2_orb *orb; |
427 | struct sbp2_status status; | 427 | struct sbp2_status status; |
428 | size_t header_size; | ||
429 | unsigned long flags; | 428 | unsigned long flags; |
430 | 429 | ||
431 | if (tcode != TCODE_WRITE_BLOCK_REQUEST || | 430 | if (tcode != TCODE_WRITE_BLOCK_REQUEST || |
432 | length == 0 || length > sizeof(status)) { | 431 | length < 8 || length > sizeof(status)) { |
433 | fw_send_response(card, request, RCODE_TYPE_ERROR); | 432 | fw_send_response(card, request, RCODE_TYPE_ERROR); |
434 | return; | 433 | return; |
435 | } | 434 | } |
436 | 435 | ||
437 | header_size = min(length, 2 * sizeof(u32)); | 436 | status.status = be32_to_cpup(payload); |
438 | fw_memcpy_from_be32(&status, payload, header_size); | 437 | status.orb_low = be32_to_cpup(payload + 4); |
439 | if (length > header_size) | 438 | memset(status.data, 0, sizeof(status.data)); |
440 | memcpy(status.data, payload + 8, length - header_size); | 439 | if (length > 8) |
440 | memcpy(status.data, payload + 8, length - 8); | ||
441 | |||
441 | if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) { | 442 | if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) { |
442 | fw_notify("non-orb related status write, not handled\n"); | 443 | fw_notify("non-orb related status write, not handled\n"); |
443 | fw_send_response(card, request, RCODE_COMPLETE); | 444 | fw_send_response(card, request, RCODE_COMPLETE); |