X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Ffirewire%2Ffw-transaction.c;h=ccf0e4cf108f4b65298f1cde98041cc08027d7e2;hb=36a23fc8aa0c72ecafe7aaee0a823b03b301e1df;hp=c00d4a9b39e5861980d884823e9d46d41c18a61f;hpb=95b00786f3b8fa99f53931361beeb4c10504ad87;p=linux-2.6 diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c index c00d4a9b39..ccf0e4cf10 100644 --- a/drivers/firewire/fw-transaction.c +++ b/drivers/firewire/fw-transaction.c @@ -18,6 +18,7 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include #include @@ -28,7 +29,6 @@ #include #include #include -#include #include "fw-transaction.h" #include "fw-topology.h" @@ -153,7 +153,7 @@ fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, int ext_tcode; if (tcode > 0x10) { - ext_tcode = tcode - 0x10; + ext_tcode = tcode & ~0x10; tcode = TCODE_LOCK_REQUEST; } else ext_tcode = 0; @@ -294,42 +294,40 @@ fw_send_request(struct fw_card *card, struct fw_transaction *t, } EXPORT_SYMBOL(fw_send_request); +struct fw_phy_packet { + struct fw_packet packet; + struct completion done; +}; + static void transmit_phy_packet_callback(struct fw_packet *packet, struct fw_card *card, int status) { - kfree(packet); -} - -static void send_phy_packet(struct fw_card *card, u32 data, int generation) -{ - struct fw_packet *packet; + struct fw_phy_packet *p = + container_of(packet, struct fw_phy_packet, packet); - packet = kzalloc(sizeof(*packet), GFP_ATOMIC); - if (packet == NULL) - return; - - packet->header[0] = data; - packet->header[1] = ~data; - packet->header_length = 8; - packet->payload_length = 0; - packet->speed = SCODE_100; - packet->generation = generation; - packet->callback = transmit_phy_packet_callback; - - card->driver->send_request(card, packet); + complete(&p->done); } void fw_send_phy_config(struct fw_card *card, int node_id, int generation, int gap_count) { - u32 q; - - q = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | - PHY_CONFIG_ROOT_ID(node_id) | - PHY_CONFIG_GAP_COUNT(gap_count); - - send_phy_packet(card, q, generation); + struct fw_phy_packet p; + u32 data = PHY_IDENTIFIER(PHY_PACKET_CONFIG) | + PHY_CONFIG_ROOT_ID(node_id) | + PHY_CONFIG_GAP_COUNT(gap_count); + + p.packet.header[0] = data; + p.packet.header[1] = ~data; + p.packet.header_length = 8; + p.packet.payload_length = 0; + p.packet.speed = SCODE_100; + p.packet.generation = generation; + p.packet.callback = transmit_phy_packet_callback; + init_completion(&p.done); + + card->driver->send_request(card, &p.packet); + wait_for_completion(&p.done); } void fw_flush_transactions(struct fw_card *card) @@ -389,21 +387,21 @@ lookup_enclosing_address_handler(struct list_head *list, static DEFINE_SPINLOCK(address_handler_lock); static LIST_HEAD(address_handler_list); -const struct fw_address_region fw_low_memory_region = - { .start = 0x000000000000ULL, .end = 0x000100000000ULL, }; const struct fw_address_region fw_high_memory_region = { .start = 0x000100000000ULL, .end = 0xffffe0000000ULL, }; +EXPORT_SYMBOL(fw_high_memory_region); + +#if 0 +const struct fw_address_region fw_low_memory_region = + { .start = 0x000000000000ULL, .end = 0x000100000000ULL, }; const struct fw_address_region fw_private_region = { .start = 0xffffe0000000ULL, .end = 0xfffff0000000ULL, }; const struct fw_address_region fw_csr_region = - { .start = 0xfffff0000000ULL, .end = 0xfffff0000800ULL, }; + { .start = CSR_REGISTER_BASE, + .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM_END, }; const struct fw_address_region fw_unit_space_region = { .start = 0xfffff0000900ULL, .end = 0x1000000000000ULL, }; -EXPORT_SYMBOL(fw_low_memory_region); -EXPORT_SYMBOL(fw_high_memory_region); -EXPORT_SYMBOL(fw_private_region); -EXPORT_SYMBOL(fw_csr_region); -EXPORT_SYMBOL(fw_unit_space_region); +#endif /* 0 */ /** * Allocate a range of addresses in the node space of the OHCI @@ -650,7 +648,7 @@ fw_core_handle_request(struct fw_card *card, struct fw_packet *p) 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]); + source = HEADER_GET_SOURCE(p->header[1]); spin_lock_irqsave(&address_handler_lock, flags); handler = lookup_enclosing_address_handler(&address_handler_list, @@ -736,12 +734,19 @@ fw_core_handle_response(struct fw_card *card, struct fw_packet *p) break; } + /* + * The response handler may be executed while the request handler + * is still pending. Cancel the request handler. + */ + card->driver->cancel_packet(card, &t->packet); + t->callback(card, rcode, data, data_length, t->callback_data); } EXPORT_SYMBOL(fw_core_handle_response); static const struct fw_address_region topology_map_region = - { .start = 0xfffff0001000ull, .end = 0xfffff0001400ull, }; + { .start = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP, + .end = CSR_REGISTER_BASE | CSR_TOPOLOGY_MAP_END, }; static void handle_topology_map(struct fw_card *card, struct fw_request *request, @@ -751,7 +756,7 @@ handle_topology_map(struct fw_card *card, struct fw_request *request, void *payload, size_t length, void *callback_data) { int i, start, end; - u32 *map; + __be32 *map; if (!TCODE_IS_READ_REQUEST(tcode)) { fw_send_response(card, request, RCODE_TYPE_ERROR); @@ -779,7 +784,8 @@ static struct fw_address_handler topology_map = { }; static const struct fw_address_region registers_region = - { .start = 0xfffff0000000ull, .end = 0xfffff0000400ull, }; + { .start = CSR_REGISTER_BASE, + .end = CSR_REGISTER_BASE | CSR_CONFIG_ROM, }; static void handle_registers(struct fw_card *card, struct fw_request *request, @@ -788,7 +794,7 @@ handle_registers(struct fw_card *card, struct fw_request *request, unsigned long long offset, void *payload, size_t length, void *callback_data) { - int reg = offset - CSR_REGISTER_BASE; + int reg = offset & ~CSR_REGISTER_BASE; unsigned long long bus_time; __be32 *data = payload;