diff options
author | Kristian Høgsberg <krh@localhost.localdomain> | 2007-01-26 00:37:57 -0500 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2007-03-09 16:02:45 -0500 |
commit | 2639a6fb268e1f2a7700fe3d31cbca9b39aa3ad9 (patch) | |
tree | d600dd5a4e1c66d4948bef268c11106197517e66 /drivers/firewire/fw-ohci.c | |
parent | 748086eb53cc5f467604c9b46ab48dc3cb771c89 (diff) |
firewire: Use struct fw_packet for incoming packets too in controller interface.
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/fw-ohci.c')
-rw-r--r-- | drivers/firewire/fw-ohci.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index d6f0644b05d4..8dc872aedce7 100644 --- a/drivers/firewire/fw-ohci.c +++ b/drivers/firewire/fw-ohci.c | |||
@@ -221,24 +221,48 @@ static void ar_context_tasklet(unsigned long data) | |||
221 | { | 221 | { |
222 | struct ar_context *ctx = (struct ar_context *)data; | 222 | struct ar_context *ctx = (struct ar_context *)data; |
223 | struct fw_ohci *ohci = ctx->ohci; | 223 | struct fw_ohci *ohci = ctx->ohci; |
224 | u32 status; | 224 | struct fw_packet p; |
225 | int length, speed, ack, timestamp, tcode; | 225 | u32 status, length, tcode; |
226 | 226 | ||
227 | /* FIXME: What to do about evt_* errors? */ | 227 | /* FIXME: What to do about evt_* errors? */ |
228 | length = le16_to_cpu(ctx->descriptor.req_count) - | 228 | length = le16_to_cpu(ctx->descriptor.req_count) - |
229 | le16_to_cpu(ctx->descriptor.res_count) - 4; | 229 | le16_to_cpu(ctx->descriptor.res_count) - 4; |
230 | status = le32_to_cpu(ctx->buffer[length / 4]); | 230 | status = le32_to_cpu(ctx->buffer[length / 4]); |
231 | ack = ((status >> 16) & 0x1f) - 16; | ||
232 | speed = (status >> 21) & 0x7; | ||
233 | timestamp = status & 0xffff; | ||
234 | 231 | ||
235 | ctx->buffer[0] = le32_to_cpu(ctx->buffer[0]); | 232 | p.ack = ((status >> 16) & 0x1f) - 16; |
236 | ctx->buffer[1] = le32_to_cpu(ctx->buffer[1]); | 233 | p.speed = (status >> 21) & 0x7; |
237 | ctx->buffer[2] = le32_to_cpu(ctx->buffer[2]); | 234 | p.timestamp = status & 0xffff; |
235 | p.generation = ohci->request_generation; | ||
236 | |||
237 | p.header[0] = le32_to_cpu(ctx->buffer[0]); | ||
238 | p.header[1] = le32_to_cpu(ctx->buffer[1]); | ||
239 | p.header[2] = le32_to_cpu(ctx->buffer[2]); | ||
240 | |||
241 | tcode = (p.header[0] >> 4) & 0x0f; | ||
242 | switch (tcode) { | ||
243 | case TCODE_WRITE_QUADLET_REQUEST: | ||
244 | case TCODE_READ_QUADLET_RESPONSE: | ||
245 | p.header[3] = ctx->buffer[3]; | ||
246 | p.header_length = 16; | ||
247 | break; | ||
248 | |||
249 | case TCODE_WRITE_BLOCK_REQUEST: | ||
250 | case TCODE_READ_BLOCK_REQUEST : | ||
251 | case TCODE_READ_BLOCK_RESPONSE: | ||
252 | case TCODE_LOCK_REQUEST: | ||
253 | case TCODE_LOCK_RESPONSE: | ||
254 | p.header[3] = le32_to_cpu(ctx->buffer[3]); | ||
255 | p.header_length = 16; | ||
256 | break; | ||
257 | |||
258 | case TCODE_WRITE_RESPONSE: | ||
259 | case TCODE_READ_QUADLET_REQUEST: | ||
260 | p.header_length = 12; | ||
261 | break; | ||
262 | } | ||
238 | 263 | ||
239 | tcode = (ctx->buffer[0] >> 4) & 0x0f; | 264 | p.payload = (void *) ctx->buffer + p.header_length; |
240 | if (TCODE_IS_BLOCK_PACKET(tcode)) | 265 | p.payload_length = length - p.header_length; |
241 | ctx->buffer[3] = le32_to_cpu(ctx->buffer[3]); | ||
242 | 266 | ||
243 | /* The OHCI bus reset handler synthesizes a phy packet with | 267 | /* The OHCI bus reset handler synthesizes a phy packet with |
244 | * the new generation number when a bus reset happens (see | 268 | * the new generation number when a bus reset happens (see |
@@ -248,15 +272,12 @@ static void ar_context_tasklet(unsigned long data) | |||
248 | * we use the unique tlabel for finding the matching | 272 | * we use the unique tlabel for finding the matching |
249 | * request. */ | 273 | * request. */ |
250 | 274 | ||
251 | if (ack + 16 == 0x09) | 275 | if (p.ack + 16 == 0x09) |
252 | ohci->request_generation = (ctx->buffer[2] >> 16) & 0xff; | 276 | ohci->request_generation = (ctx->buffer[2] >> 16) & 0xff; |
253 | else if (ctx == &ohci->ar_request_ctx) | 277 | else if (ctx == &ohci->ar_request_ctx) |
254 | fw_core_handle_request(&ohci->card, speed, ack, timestamp, | 278 | fw_core_handle_request(&ohci->card, &p); |
255 | ohci->request_generation, | ||
256 | length, ctx->buffer); | ||
257 | else | 279 | else |
258 | fw_core_handle_response(&ohci->card, speed, ack, timestamp, | 280 | fw_core_handle_response(&ohci->card, &p); |
259 | length, ctx->buffer); | ||
260 | 281 | ||
261 | ctx->descriptor.data_address = cpu_to_le32(ctx->buffer_bus); | 282 | ctx->descriptor.data_address = cpu_to_le32(ctx->buffer_bus); |
262 | ctx->descriptor.req_count = cpu_to_le16(sizeof ctx->buffer); | 283 | ctx->descriptor.req_count = cpu_to_le16(sizeof ctx->buffer); |
@@ -323,15 +344,15 @@ do_packet_callbacks(struct fw_ohci *ohci, struct list_head *list) | |||
323 | struct fw_packet *p, *next; | 344 | struct fw_packet *p, *next; |
324 | 345 | ||
325 | list_for_each_entry_safe(p, next, list, link) | 346 | list_for_each_entry_safe(p, next, list, link) |
326 | p->callback(p, &ohci->card, p->status); | 347 | p->callback(p, &ohci->card, p->ack); |
327 | } | 348 | } |
328 | 349 | ||
329 | static void | 350 | static void |
330 | complete_transmission(struct fw_packet *packet, | 351 | complete_transmission(struct fw_packet *packet, |
331 | int status, struct list_head *list) | 352 | int ack, struct list_head *list) |
332 | { | 353 | { |
333 | list_move_tail(&packet->link, list); | 354 | list_move_tail(&packet->link, list); |
334 | packet->status = status; | 355 | packet->ack = ack; |
335 | } | 356 | } |
336 | 357 | ||
337 | /* This function prepares the first packet in the context queue for | 358 | /* This function prepares the first packet in the context queue for |