Date: Fri, 26 Jan 2007 00:37:57 -0500 From: Kristian =?utf-8?B?SMO4Z3NiZXJn?= Subject: [PATCH 2/10] firewire: Use struct fw_packet for incoming packets too in controller interface. Signed-off-by: Kristian Høgsberg Signed-off-by: Stefan Richter --- drivers/firewire/fw-ohci.c | 61 +++++++++++++++------- drivers/firewire/fw-transaction.c | 99 +++++++++++++++++------------------- drivers/firewire/fw-transaction.h | 13 ++--- 3 files changed, 92 insertions(+), 81 deletions(-) diff --git a/drivers/firewire/fw-ohci.c b/drivers/firewire/fw-ohci.c index d6f0644..8dc872a 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) { struct ar_context *ctx = (struct ar_context *)data; struct fw_ohci *ohci = ctx->ohci; - u32 status; - int length, speed, ack, timestamp, tcode; + struct fw_packet p; + u32 status, length, tcode; /* FIXME: What to do about evt_* errors? */ length = le16_to_cpu(ctx->descriptor.req_count) - le16_to_cpu(ctx->descriptor.res_count) - 4; status = le32_to_cpu(ctx->buffer[length / 4]); - ack = ((status >> 16) & 0x1f) - 16; - speed = (status >> 21) & 0x7; - timestamp = status & 0xffff; - ctx->buffer[0] = le32_to_cpu(ctx->buffer[0]); - ctx->buffer[1] = le32_to_cpu(ctx->buffer[1]); - ctx->buffer[2] = le32_to_cpu(ctx->buffer[2]); + p.ack = ((status >> 16) & 0x1f) - 16; + p.speed = (status >> 21) & 0x7; + p.timestamp = status & 0xffff; + p.generation = ohci->request_generation; + + p.header[0] = le32_to_cpu(ctx->buffer[0]); + p.header[1] = le32_to_cpu(ctx->buffer[1]); + p.header[2] = le32_to_cpu(ctx->buffer[2]); + + tcode = (p.header[0] >> 4) & 0x0f; + switch (tcode) { + case TCODE_WRITE_QUADLET_REQUEST: + case TCODE_READ_QUADLET_RESPONSE: + p.header[3] = ctx->buffer[3]; + p.header_length = 16; + break; + + case TCODE_WRITE_BLOCK_REQUEST: + case TCODE_READ_BLOCK_REQUEST : + case TCODE_READ_BLOCK_RESPONSE: + case TCODE_LOCK_REQUEST: + case TCODE_LOCK_RESPONSE: + p.header[3] = le32_to_cpu(ctx->buffer[3]); + p.header_length = 16; + break; + + case TCODE_WRITE_RESPONSE: + case TCODE_READ_QUADLET_REQUEST: + p.header_length = 12; + break; + } - tcode = (ctx->buffer[0] >> 4) & 0x0f; - if (TCODE_IS_BLOCK_PACKET(tcode)) - ctx->buffer[3] = le32_to_cpu(ctx->buffer[3]); + p.payload = (void *) ctx->buffer + p.header_length; + p.payload_length = length - p.header_length; /* The OHCI bus reset handler synthesizes a phy packet with * the new generation number when a bus reset happens (see @@ -248,15 +272,12 @@ static void ar_context_tasklet(unsigned long data) * we use the unique tlabel for finding the matching * request. */ - if (ack + 16 == 0x09) + if (p.ack + 16 == 0x09) ohci->request_generation = (ctx->buffer[2] >> 16) & 0xff; else if (ctx == &ohci->ar_request_ctx) - fw_core_handle_request(&ohci->card, speed, ack, timestamp, - ohci->request_generation, - length, ctx->buffer); + fw_core_handle_request(&ohci->card, &p); else - fw_core_handle_response(&ohci->card, speed, ack, timestamp, - length, ctx->buffer); + fw_core_handle_response(&ohci->card, &p); ctx->descriptor.data_address = cpu_to_le32(ctx->buffer_bus); 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) struct fw_packet *p, *next; list_for_each_entry_safe(p, next, list, link) - p->callback(p, &ohci->card, p->status); + p->callback(p, &ohci->card, p->ack); } static void complete_transmission(struct fw_packet *packet, - int status, struct list_head *list) + int ack, struct list_head *list) { list_move_tail(&packet->link, list); - packet->status = status; + packet->ack = ack; } /* This function prepares the first packet in the context queue for diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index 57ecf95..4ca39f0 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -426,15 +426,15 @@ free_response_callback(struct fw_packet *packet, static void fw_fill_response(struct fw_packet *response, - u32 *request, u32 *data, size_t length) + struct fw_packet *request, void *data) { int tcode, tlabel, extended_tcode, source, destination; - tcode = header_get_tcode(request[0]); - tlabel = header_get_tlabel(request[0]); - source = header_get_destination(request[0]); - destination = header_get_source(request[1]); - extended_tcode = header_get_extended_tcode(request[3]); + tcode = header_get_tcode(request->header[0]); + tlabel = header_get_tlabel(request->header[0]); + source = header_get_destination(request->header[0]); + destination = header_get_source(request->header[1]); + extended_tcode = header_get_extended_tcode(request->header[3]); response->header[0] = header_retry(RETRY_1) | @@ -463,11 +463,11 @@ fw_fill_response(struct fw_packet *response, case TCODE_LOCK_REQUEST: response->header[0] |= header_tcode(tcode + 2); response->header[3] = - header_data_length(length) | + header_data_length(request->payload_length) | header_extended_tcode(extended_tcode); response->header_length = 16; response->payload = data; - response->payload_length = length; + response->payload_length = request->payload_length; break; default: @@ -477,24 +477,23 @@ fw_fill_response(struct fw_packet *response, } static struct fw_request * -allocate_request(u32 *header, int ack, - int speed, int timestamp, int generation) +allocate_request(struct fw_packet *p) { struct fw_request *request; u32 *data, length; - int request_tcode; + int request_tcode, t; - request_tcode = header_get_tcode(header[0]); + request_tcode = header_get_tcode(p->header[0]); switch (request_tcode) { case TCODE_WRITE_QUADLET_REQUEST: - data = &header[3]; + data = &p->header[3]; length = 4; break; case TCODE_WRITE_BLOCK_REQUEST: case TCODE_LOCK_REQUEST: - data = &header[4]; - length = header_get_data_length(header[3]); + data = p->payload; + length = header_get_data_length(p->header[3]); break; case TCODE_READ_QUADLET_REQUEST: @@ -504,7 +503,7 @@ allocate_request(u32 *header, int ack, case TCODE_READ_BLOCK_REQUEST: data = NULL; - length = header_get_data_length(header[3]); + length = header_get_data_length(p->header[3]); break; default: @@ -516,16 +515,22 @@ allocate_request(u32 *header, int ack, if (request == NULL) return NULL; - request->response.speed = speed; - request->response.timestamp = timestamp; - request->response.generation = generation; + t = (p->timestamp & 0x1fff) + 4000; + if (t >= 8000) + t = (p->timestamp & ~0x1fff) + 0x2000 + t - 8000; + else + t = (p->timestamp & ~0x1fff) + t; + + request->response.speed = p->speed; + request->response.timestamp = t; + request->response.generation = p->generation; request->response.callback = free_response_callback; - request->ack = ack; - request->length = length; + request->ack = p->ack; + request->length = p->payload_length; if (data) - memcpy(request->data, data, length); + memcpy(request->data, p->payload, p->payload_length); - fw_fill_response(&request->response, header, request->data, length); + fw_fill_response(&request->response, p, request->data); return request; } @@ -554,31 +559,23 @@ fw_send_response(struct fw_card *card, struct fw_request *request, int rcode) EXPORT_SYMBOL(fw_send_response); void -fw_core_handle_request(struct fw_card *card, - int speed, int ack, int timestamp, - int generation, u32 length, u32 *header) +fw_core_handle_request(struct fw_card *card, struct fw_packet *p) { struct fw_address_handler *handler; struct fw_request *request; unsigned long long offset; unsigned long flags; - int tcode, destination, source, t; + int tcode, destination, source; - if (length > 2048) { + if (p->payload_length > 2048) { /* FIXME: send error response. */ return; } - if (ack != ACK_PENDING && ack != ACK_COMPLETE) + if (p->ack != ACK_PENDING && p->ack != ACK_COMPLETE) return; - t = (timestamp & 0x1fff) + 4000; - if (t >= 8000) - t = (timestamp & ~0x1fff) + 0x2000 + t - 8000; - else - t = (timestamp & ~0x1fff) + t; - - request = allocate_request(header, ack, speed, t, generation); + request = allocate_request(p); if (request == NULL) { /* FIXME: send statically allocated busy packet. */ return; @@ -586,10 +583,10 @@ fw_core_handle_request(struct fw_card *card, offset = ((unsigned long long) - header_get_offset_high(header[1]) << 32) | header[2]; - tcode = header_get_tcode(header[0]); - destination = header_get_destination(header[0]); - source = header_get_source(header[0]); + header_get_offset_high(p->header[1]) << 32) | p->header[2]; + tcode = header_get_tcode(p->header[0]); + destination = header_get_destination(p->header[0]); + source = header_get_source(p->header[0]); spin_lock_irqsave(&address_handler_lock, flags); handler = lookup_enclosing_address_handler(&address_handler_list, @@ -607,16 +604,14 @@ fw_core_handle_request(struct fw_card *card, else handler->address_callback(card, request, tcode, destination, source, - generation, speed, offset, + p->generation, p->speed, offset, request->data, request->length, handler->callback_data); } EXPORT_SYMBOL(fw_core_handle_request); void -fw_core_handle_response(struct fw_card *card, - int speed, int ack, int timestamp, - u32 length, u32 *header) +fw_core_handle_response(struct fw_card *card, struct fw_packet *p) { struct fw_transaction *t; unsigned long flags; @@ -624,11 +619,11 @@ fw_core_handle_response(struct fw_card *card, size_t data_length; int tcode, tlabel, destination, source, rcode; - tcode = header_get_tcode(header[0]); - tlabel = header_get_tlabel(header[0]); - destination = header_get_destination(header[0]); - source = header_get_source(header[1]); - rcode = header_get_rcode(header[1]); + tcode = header_get_tcode(p->header[0]); + tlabel = header_get_tlabel(p->header[0]); + destination = header_get_destination(p->header[0]); + source = header_get_source(p->header[1]); + rcode = header_get_rcode(p->header[1]); spin_lock_irqsave(&card->lock, flags); list_for_each_entry(t, &card->transaction_list, link) { @@ -650,7 +645,7 @@ fw_core_handle_response(struct fw_card *card, switch (tcode) { case TCODE_READ_QUADLET_RESPONSE: - data = (u32 *) &header[3]; + data = (u32 *) &p->header[3]; data_length = 4; break; @@ -661,8 +656,8 @@ fw_core_handle_response(struct fw_card *card, case TCODE_READ_BLOCK_RESPONSE: case TCODE_LOCK_RESPONSE: - data = &header[4]; - data_length = header_get_data_length(header[3]); + data = &p->header[4]; + data_length = header_get_data_length(p->header[3]); break; default: diff --git a/drivers/firewire/fw-transaction.h b/drivers/firewire/fw-transaction.h index df65245..903235b 100644 --- a/drivers/firewire/fw-transaction.h +++ b/drivers/firewire/fw-transaction.h @@ -180,7 +180,7 @@ struct fw_packet { * must never block. */ fw_packet_callback_t callback; - int status; + int ack; struct list_head link; }; @@ -415,14 +415,9 @@ fw_core_handle_bus_reset(struct fw_card *card, int node_id, int generation, int self_id_count, u32 *self_ids); void -fw_core_handle_request(struct fw_card *card, - int speed, int ack, int timestamp, - int generation, - u32 length, u32 *payload); -void -fw_core_handle_response(struct fw_card *card, - int speed, int ack, int timestamp, - u32 length, u32 *payload); +fw_core_handle_request(struct fw_card *card, struct fw_packet *request); +void +fw_core_handle_response(struct fw_card *card, struct fw_packet *packet); #endif /* __fw_transaction_h */ --