mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
firewire: Preserve response data alignment bug when it is harmless
Recently, a bug having to do with the alignment of transaction response data was fixed. However, some apps such as libdc1394 relied on the presence of that bug in order to function correctly. In order to stay compatible with old versions of those apps, this patch preserves the bug in cases where it is harmless to normal operation (such as the single quadlet read) due to a simple duplication of data. This guarantees maximum compatability for those users who are using the old app with the fixed kernel. Signed-off-by: David Moore <dcm@acm.org> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
This commit is contained in:
parent
f05e21b39f
commit
8401d92ba4
1 changed files with 20 additions and 9 deletions
|
@ -369,22 +369,33 @@ complete_transaction(struct fw_card *card, int rcode,
|
|||
struct response *response = data;
|
||||
struct client *client = response->client;
|
||||
unsigned long flags;
|
||||
struct fw_cdev_event_response *r = &response->response;
|
||||
|
||||
if (length < response->response.length)
|
||||
response->response.length = length;
|
||||
if (length < r->length)
|
||||
r->length = length;
|
||||
if (rcode == RCODE_COMPLETE)
|
||||
memcpy(response->response.data, payload,
|
||||
response->response.length);
|
||||
memcpy(r->data, payload, r->length);
|
||||
|
||||
spin_lock_irqsave(&client->lock, flags);
|
||||
list_del(&response->resource.link);
|
||||
spin_unlock_irqrestore(&client->lock, flags);
|
||||
|
||||
response->response.type = FW_CDEV_EVENT_RESPONSE;
|
||||
response->response.rcode = rcode;
|
||||
queue_event(client, &response->event, &response->response,
|
||||
sizeof(response->response) + response->response.length,
|
||||
NULL, 0);
|
||||
r->type = FW_CDEV_EVENT_RESPONSE;
|
||||
r->rcode = rcode;
|
||||
|
||||
/*
|
||||
* In the case that sizeof(*r) doesn't align with the position of the
|
||||
* data, and the read is short, preserve an extra copy of the data
|
||||
* to stay compatible with a pre-2.6.27 bug. Since the bug is harmless
|
||||
* for short reads and some apps depended on it, this is both safe
|
||||
* and prudent for compatibility.
|
||||
*/
|
||||
if (r->length <= sizeof(*r) - offsetof(typeof(*r), data))
|
||||
queue_event(client, &response->event, r, sizeof(*r),
|
||||
r->data, r->length);
|
||||
else
|
||||
queue_event(client, &response->event, r, sizeof(*r) + r->length,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
static int ioctl_send_request(struct client *client, void *buffer)
|
||||
|
|
Loading…
Reference in a new issue