Loading drivers/firewire/fw-ohci.c +41 −20 Original line number Diff line number Diff line Loading @@ -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; tcode = (ctx->buffer[0] >> 4) & 0x0f; if (TCODE_IS_BLOCK_PACKET(tcode)) ctx->buffer[3] = le32_to_cpu(ctx->buffer[3]); 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; } 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 Loading @@ -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); Loading Loading @@ -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 Loading drivers/firewire/fw-transaction.c +47 −52 Original line number Diff line number Diff line Loading @@ -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) | Loading Loading @@ -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: Loading @@ -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: Loading @@ -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: Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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, Loading @@ -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; Loading @@ -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) { Loading @@ -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; Loading @@ -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: Loading drivers/firewire/fw-transaction.h +4 −9 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ struct fw_packet { * must never block. */ fw_packet_callback_t callback; int status; int ack; struct list_head link; }; Loading Loading @@ -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 */ Loading
drivers/firewire/fw-ohci.c +41 −20 Original line number Diff line number Diff line Loading @@ -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; tcode = (ctx->buffer[0] >> 4) & 0x0f; if (TCODE_IS_BLOCK_PACKET(tcode)) ctx->buffer[3] = le32_to_cpu(ctx->buffer[3]); 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; } 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 Loading @@ -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); Loading Loading @@ -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 Loading
drivers/firewire/fw-transaction.c +47 −52 Original line number Diff line number Diff line Loading @@ -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) | Loading Loading @@ -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: Loading @@ -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: Loading @@ -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: Loading @@ -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; } Loading Loading @@ -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; Loading @@ -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, Loading @@ -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; Loading @@ -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) { Loading @@ -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; Loading @@ -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: Loading
drivers/firewire/fw-transaction.h +4 −9 Original line number Diff line number Diff line Loading @@ -180,7 +180,7 @@ struct fw_packet { * must never block. */ fw_packet_callback_t callback; int status; int ack; struct list_head link; }; Loading Loading @@ -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 */