]> err.no Git - linux-2.6/commitdiff
firewire: implement broadcast_channel CSR for 1394a compliance
authorStefan Richter <stefanr@s5r6.in-berlin.de>
Sat, 24 May 2008 14:41:09 +0000 (16:41 +0200)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Mon, 14 Jul 2008 11:06:03 +0000 (13:06 +0200)
See IEEE 1394a clause 8.3.2.3.11.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
drivers/firewire/fw-card.c
drivers/firewire/fw-transaction.c
drivers/firewire/fw-transaction.h

index 5b4c0d9f517346ec79a1426a4d7982ebe07986c8..96340ce690d4c131c9b838bb3d9ba89e65d1e5ae 100644 (file)
@@ -403,6 +403,7 @@ fw_card_initialize(struct fw_card *card, const struct fw_card_driver *driver,
        card->current_tlabel = 0;
        card->tlabel_mask = 0;
        card->color = 0;
+       card->broadcast_channel = BROADCAST_CHANNEL_INITIAL;
 
        INIT_LIST_HEAD(&card->transaction_list);
        spin_lock_init(&card->lock);
index 03ae8a77c479f680da86de9cc1e407336bd23750..2f11ed1acf018d092d4a9ce9d58f473aaddf6f4c 100644 (file)
@@ -817,12 +817,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
        int reg = offset & ~CSR_REGISTER_BASE;
        unsigned long long bus_time;
        __be32 *data = payload;
+       int rcode = RCODE_COMPLETE;
 
        switch (reg) {
        case CSR_CYCLE_TIME:
        case CSR_BUS_TIME:
                if (!TCODE_IS_READ_REQUEST(tcode) || length != 4) {
-                       fw_send_response(card, request, RCODE_TYPE_ERROR);
+                       rcode = RCODE_TYPE_ERROR;
                        break;
                }
 
@@ -831,7 +832,17 @@ handle_registers(struct fw_card *card, struct fw_request *request,
                        *data = cpu_to_be32(bus_time);
                else
                        *data = cpu_to_be32(bus_time >> 25);
-               fw_send_response(card, request, RCODE_COMPLETE);
+               break;
+
+       case CSR_BROADCAST_CHANNEL:
+               if (tcode == TCODE_READ_QUADLET_REQUEST)
+                       *data = cpu_to_be32(card->broadcast_channel);
+               else if (tcode == TCODE_WRITE_QUADLET_REQUEST)
+                       card->broadcast_channel =
+                           (be32_to_cpu(*data) & BROADCAST_CHANNEL_VALID) |
+                           BROADCAST_CHANNEL_INITIAL;
+               else
+                       rcode = RCODE_TYPE_ERROR;
                break;
 
        case CSR_BUS_MANAGER_ID:
@@ -850,10 +861,13 @@ handle_registers(struct fw_card *card, struct fw_request *request,
 
        case CSR_BUSY_TIMEOUT:
                /* FIXME: Implement this. */
+
        default:
-               fw_send_response(card, request, RCODE_ADDRESS_ERROR);
+               rcode = RCODE_ADDRESS_ERROR;
                break;
        }
+
+       fw_send_response(card, request, rcode);
 }
 
 static struct fw_address_handler registers = {
index 04d3854f65600924e53183b63f4001d048d047eb..f3a493d596ccc31ada0433394507ddd2cf717d82 100644 (file)
@@ -80,6 +80,9 @@
 #define CSR_SPEED_MAP                  0x2000
 #define CSR_SPEED_MAP_END              0x3000
 
+#define BROADCAST_CHANNEL_INITIAL      (1 << 31 | 31)
+#define BROADCAST_CHANNEL_VALID                (1 << 30)
+
 #define fw_notify(s, args...) printk(KERN_NOTICE KBUILD_MODNAME ": " s, ## args)
 #define fw_error(s, args...) printk(KERN_ERR KBUILD_MODNAME ": " s, ## args)
 
@@ -236,6 +239,7 @@ struct fw_card {
         */
        int self_id_count;
        u32 topology_map[252 + 3];
+       u32 broadcast_channel;
 
        spinlock_t lock; /* Take this lock when handling the lists in
                          * this struct. */