}
EXPORT_SYMBOL(fw_csr_iterator_next);
-static int is_fw_unit(struct device *dev);
+static bool is_fw_unit(struct device *dev);
static int match_unit_directory(u32 *directory, u32 match_flags,
const struct ieee1394_device_id *id)
group->groups[0] = &group->group;
group->groups[1] = NULL;
group->group.attrs = group->attrs;
- dev->groups = group->groups;
+ dev->groups = (const struct attribute_group **) group->groups;
}
static ssize_t modalias_show(struct device *dev,
kfree(old_rom);
ret = 0;
- device->cmc = rom[2] >> 30 & 1;
+ device->max_rec = rom[2] >> 12 & 0xf;
+ device->cmc = rom[2] >> 30 & 1;
+ device->irmc = rom[2] >> 31 & 1;
out:
kfree(rom);
.release = fw_unit_release,
};
-static int is_fw_unit(struct device *dev)
+static bool is_fw_unit(struct device *dev)
{
return dev->type == &fw_unit_type;
}
.release = fw_device_release,
};
+static bool is_fw_device(struct device *dev)
+{
+ return dev->type == &fw_device_type;
+}
+
static int update_unit(struct device *dev, void *data)
{
struct fw_unit *unit = fw_unit(dev);
struct fw_card *card = new->card;
int match = 0;
+ if (!is_fw_device(dev))
+ return 0;
+
down_read(&fw_device_rwsem); /* serialize config_rom access */
spin_lock_irq(&card->lock); /* serialize node access */
enum { BC_UNKNOWN = 0, BC_UNIMPLEMENTED, BC_IMPLEMENTED, };
-void fw_device_set_broadcast_channel(struct fw_device *device, int generation)
+static void set_broadcast_channel(struct fw_device *device, int generation)
{
struct fw_card *card = device->card;
__be32 data;
if (!card->broadcast_channel_allocated)
return;
+ /*
+ * The Broadcast_Channel Valid bit is required by nodes which want to
+ * transmit on this channel. Such transmissions are practically
+ * exclusive to IP over 1394 (RFC 2734). IP capable nodes are required
+ * to be IRM capable and have a max_rec of 8 or more. We use this fact
+ * to narrow down to which nodes we send Broadcast_Channel updates.
+ */
+ if (!device->irmc || device->max_rec < 8)
+ return;
+
+ /*
+ * Some 1394-1995 nodes crash if this 1394a-2000 register is written.
+ * Perform a read test first.
+ */
if (device->bc_implemented == BC_UNKNOWN) {
rcode = fw_run_transaction(card, TCODE_READ_QUADLET_REQUEST,
device->node_id, generation, device->max_speed,
}
}
+int fw_device_set_broadcast_channel(struct device *dev, void *gen)
+{
+ if (is_fw_device(dev))
+ set_broadcast_channel(fw_device(dev), (long)gen);
+
+ return 0;
+}
+
static void fw_device_init(struct work_struct *work)
{
struct fw_device *device =
1 << device->max_speed);
device->config_rom_retries = 0;
- fw_device_set_broadcast_channel(device, device->generation);
+ set_broadcast_channel(device, device->generation);
}
/*