Skip to content

Commit

Permalink
Merge branches 'fixes' and 'fwnet' of git://git.kernel.org/pub/scm/li…
Browse files Browse the repository at this point in the history
…nux/kernel/git/ieee1394/linux1394-2.6

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: core: fix unstable I/O with Canon camcorder

* 'fwnet' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394-2.6:
  firewire: net: is not experimental anymore
  firewire: net: invalidate ARP entries of removed nodes
  • Loading branch information
torvalds committed Jan 21, 2011
3 parents 7971b96 + 6044565 + 3247199 commit a1d3f5b
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 7 deletions.
6 changes: 2 additions & 4 deletions drivers/firewire/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,13 @@ config FIREWIRE_SBP2
configuration section.

config FIREWIRE_NET
tristate "IP networking over 1394 (EXPERIMENTAL)"
depends on FIREWIRE && INET && EXPERIMENTAL
tristate "IP networking over 1394"
depends on FIREWIRE && INET
help
This enables IPv4 over IEEE 1394, providing IP connectivity with
other implementations of RFC 2734 as found on several operating
systems. Multicast support is currently limited.

NOTE, this driver is not stable yet!

To compile this driver as a module, say M here: The module will be
called firewire-net.

Expand Down
11 changes: 9 additions & 2 deletions drivers/firewire/core-card.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ static size_t config_rom_length = 1 + 4 + 1 + 1;
#define BIB_IRMC ((1) << 31)
#define NODE_CAPABILITIES 0x0c0083c0 /* per IEEE 1394 clause 8.3.2.6.5.2 */

#define CANON_OUI 0x000085

static void generate_config_rom(struct fw_card *card, __be32 *config_rom)
{
struct fw_descriptor *desc;
Expand Down Expand Up @@ -284,6 +286,7 @@ static void bm_work(struct work_struct *work)
bool root_device_is_running;
bool root_device_is_cmc;
bool irm_is_1394_1995_only;
bool keep_this_irm;

spin_lock_irq(&card->lock);

Expand All @@ -305,6 +308,10 @@ static void bm_work(struct work_struct *work)
irm_is_1394_1995_only = irm_device && irm_device->config_rom &&
(irm_device->config_rom[2] & 0x000000f0) == 0;

/* Canon MV5i works unreliably if it is not root node. */
keep_this_irm = irm_device && irm_device->config_rom &&
irm_device->config_rom[3] >> 8 == CANON_OUI;

root_id = root_node->node_id;
irm_id = card->irm_node->node_id;
local_id = card->local_node->node_id;
Expand Down Expand Up @@ -333,7 +340,7 @@ static void bm_work(struct work_struct *work)
goto pick_me;
}

if (irm_is_1394_1995_only) {
if (irm_is_1394_1995_only && !keep_this_irm) {
new_root_id = local_id;
fw_notify("%s, making local node (%02x) root.\n",
"IRM is not 1394a compliant", new_root_id);
Expand Down Expand Up @@ -382,7 +389,7 @@ static void bm_work(struct work_struct *work)

spin_lock_irq(&card->lock);

if (rcode != RCODE_COMPLETE) {
if (rcode != RCODE_COMPLETE && !keep_this_irm) {
/*
* The lock request failed, maybe the IRM
* isn't really IRM capable after all. Let's
Expand Down
9 changes: 8 additions & 1 deletion drivers/firewire/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ struct fwnet_peer {
struct fwnet_device *dev;
u64 guid;
u64 fifo;
__be32 ip;

/* guarded by dev->lock */
struct list_head pd_list; /* received partial datagrams */
Expand Down Expand Up @@ -570,6 +571,8 @@ static int fwnet_finish_incoming_packet(struct net_device *net,
peer->speed = sspd;
if (peer->max_payload > max_payload)
peer->max_payload = max_payload;

peer->ip = arp1394->sip;
}
spin_unlock_irqrestore(&dev->lock, flags);

Expand Down Expand Up @@ -1470,6 +1473,7 @@ static int fwnet_add_peer(struct fwnet_device *dev,
peer->dev = dev;
peer->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4];
peer->fifo = FWNET_NO_FIFO_ADDR;
peer->ip = 0;
INIT_LIST_HEAD(&peer->pd_list);
peer->pdg_size = 0;
peer->datagram_label = 0;
Expand Down Expand Up @@ -1589,10 +1593,13 @@ static int fwnet_remove(struct device *_dev)

mutex_lock(&fwnet_device_mutex);

net = dev->netdev;
if (net && peer->ip)
arp_invalidate(net, peer->ip);

fwnet_remove_peer(peer, dev);

if (list_empty(&dev->peer_list)) {
net = dev->netdev;
unregister_netdev(net);

if (dev->local_fifo != FWNET_NO_FIFO_ADDR)
Expand Down

0 comments on commit a1d3f5b

Please sign in to comment.