firewire: Use struct fw_packet for incoming packets too in controller interface.
authorKristian Høgsberg <krh@localhost.localdomain>
Fri, 26 Jan 2007 05:37:57 +0000 (00:37 -0500)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Fri, 9 Mar 2007 21:02:45 +0000 (22:02 +0100)
Signed-off-by: Kristian Høgsberg <krh@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
drivers/firewire/fw-ohci.c
drivers/firewire/fw-transaction.c
drivers/firewire/fw-transaction.h

index d6f0644b05d46223243e4cf16f6b8c1de22cd201..8dc872aedce797113b8e953017bef5690f3143ed 100644 (file)
@@ -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
index 57ecf95e52710cec8b56775f3a6c91ee0a774281..4ca39f09f58a756c09afa26a047058c352e6f973 100644 (file)
@@ -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:
index df652452bdb5114307ce2b3026ebf1aa0b32359c..903235b142f28aee6fd9b4426a57957754169c78 100644 (file)
@@ -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 */