aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/fw-transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/fw-transaction.c')
-rw-r--r--drivers/firewire/fw-transaction.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/firewire/fw-transaction.c b/drivers/firewire/fw-transaction.c
index 03ae8a77c479..40db80752272 100644
--- a/drivers/firewire/fw-transaction.c
+++ b/drivers/firewire/fw-transaction.c
@@ -55,6 +55,9 @@
55#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff) 55#define HEADER_GET_DATA_LENGTH(q) (((q) >> 16) & 0xffff)
56#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff) 56#define HEADER_GET_EXTENDED_TCODE(q) (((q) >> 0) & 0xffff)
57 57
58#define HEADER_DESTINATION_IS_BROADCAST(q) \
59 (((q) & HEADER_DESTINATION(0x3f)) == HEADER_DESTINATION(0x3f))
60
58#define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22)) 61#define PHY_CONFIG_GAP_COUNT(gap_count) (((gap_count) << 16) | (1 << 22))
59#define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23)) 62#define PHY_CONFIG_ROOT_ID(node_id) ((((node_id) & 0x3f) << 24) | (1 << 23))
60#define PHY_IDENTIFIER(id) ((id) << 30) 63#define PHY_IDENTIFIER(id) ((id) << 30)
@@ -624,12 +627,9 @@ allocate_request(struct fw_packet *p)
624void 627void
625fw_send_response(struct fw_card *card, struct fw_request *request, int rcode) 628fw_send_response(struct fw_card *card, struct fw_request *request, int rcode)
626{ 629{
627 /* 630 /* unified transaction or broadcast transaction: don't respond */
628 * Broadcast packets are reported as ACK_COMPLETE, so this 631 if (request->ack != ACK_PENDING ||
629 * check is sufficient to ensure we don't send response to 632 HEADER_DESTINATION_IS_BROADCAST(request->request_header[0])) {
630 * broadcast packets or posted writes.
631 */
632 if (request->ack != ACK_PENDING) {
633 kfree(request); 633 kfree(request);
634 return; 634 return;
635 } 635 }
@@ -817,12 +817,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
817 int reg = offset & ~CSR_REGISTER_BASE; 817 int reg = offset & ~CSR_REGISTER_BASE;
818 unsigned long long bus_time; 818 unsigned long long bus_time;
819 __be32 *data = payload; 819 __be32 *data = payload;
820 int rcode = RCODE_COMPLETE;
820 821
821 switch (reg) { 822 switch (reg) {
822 case CSR_CYCLE_TIME: 823 case CSR_CYCLE_TIME:
823 case CSR_BUS_TIME: 824 case CSR_BUS_TIME:
824 if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) { 825 if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
825 fw_send_response(card, request, RCODE_TYPE_ERROR); 826 rcode = RCODE_TYPE_ERROR;
826 break; 827 break;
827 } 828 }
828 829
@@ -831,7 +832,17 @@ handle_registers(struct fw_card *card, struct fw_request *request,
831 *data = cpu_to_be32(bus_time); 832 *data = cpu_to_be32(bus_time);
832 else 833 else
833 *data = cpu_to_be32(bus_time >> 25); 834 *data = cpu_to_be32(bus_time >> 25);
834 fw_send_response(card, request, RCODE_COMPLETE); 835 break;
836
837 case CSR_BROADCAST_CHANNEL:
838 if (tcode == TCODE_READ_QUADLET_REQUEST)
839 *data = cpu_to_be32(card->broadcast_channel);
840 else if (tcode == TCODE_WRITE_QUADLET_REQUEST)
841 card->broadcast_channel =
842 (be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) |
843 BROADCAST_CHANNEL_INITIAL;
844 else
845 rcode = RCODE_TYPE_ERROR;
835 break; 846 break;
836 847
837 case CSR_BUS_MANAGER_ID: 848 case CSR_BUS_MANAGER_ID:
@@ -850,10 +861,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
850 861
851 case CSR_BUSY_TIMEOUT: 862 case CSR_BUSY_TIMEOUT:
852 /* FIXME: Implement this. */ 863 /* FIXME: Implement this. */
864
853 default: 865 default:
854 fw_send_response(card, request, RCODE_ADDRESS_ERROR); 866 rcode = RCODE_ADDRESS_ERROR;
855 break; 867 break;
856 } 868 }
869
870 fw_send_response(card, request, rcode);
857} 871}
858 872
859static struct fw_address_handler registers = { 873static struct fw_address_handler registers = {