From 5104a03d7d0ef4b0222155f2fa6902bf727b1005 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:07 +0900 Subject: [PATCH 01/11] firewire net: No need to reset dev->local_fifo after failure of fw_core_add_address_handler(). fwnet_broadcast_start() try to register address handler at first if it was not registered yet; dev->local_fifo == FWNET_NO_FIFO_ADDR. Since dev->local_info not changed if fw_core_add_address_hander() has failed, we do not need to set dev->local_info to FWNET_NO_FIFO_ADDR. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 2b27bff2591a..a7a0e8277147 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1220,8 +1220,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) dev->broadcast_rcv_context = NULL; failed_context_create: fw_core_remove_address_handler(&dev->handler); - failed_initial: dev->local_fifo = FWNET_NO_FIFO_ADDR; + failed_initial: return retval; } From 9d39c90abc6766f875d2855a1a73c43b6ffa09c0 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:26 +0900 Subject: [PATCH 02/11] firewire net: Introduce fwnet_fifo_{start, stop}() helpers. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 51 +++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index a7a0e8277147..96f6ee5bffd4 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1116,6 +1116,36 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask) return 0; } +static void fwnet_fifo_stop(struct fwnet_device *dev) +{ + if (dev->local_fifo == FWNET_NO_FIFO_ADDR) + return; + + fw_core_remove_address_handler(&dev->handler); + dev->local_fifo = FWNET_NO_FIFO_ADDR; +} + +static int fwnet_fifo_start(struct fwnet_device *dev) +{ + int retval; + + if (dev->local_fifo != FWNET_NO_FIFO_ADDR) + return 0; + + dev->handler.length = 4096; + dev->handler.address_callback = fwnet_receive_packet; + dev->handler.callback_data = dev; + + retval = fw_core_add_address_handler(&dev->handler, + &fw_high_memory_region); + if (retval < 0) + return retval; + + dev->local_fifo = dev->handler.offset; + + return 0; +} + static int fwnet_broadcast_start(struct fwnet_device *dev) { struct fw_iso_context *context; @@ -1126,18 +1156,9 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned long offset; unsigned u; - if (dev->local_fifo == FWNET_NO_FIFO_ADDR) { - dev->handler.length = 4096; - dev->handler.address_callback = fwnet_receive_packet; - dev->handler.callback_data = dev; - - retval = fw_core_add_address_handler(&dev->handler, - &fw_high_memory_region); - if (retval < 0) - goto failed_initial; - - dev->local_fifo = dev->handler.offset; - } + retval = fwnet_fifo_start(dev); + if (retval < 0) + goto failed_initial; max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; @@ -1219,8 +1240,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) fw_iso_context_destroy(context); dev->broadcast_rcv_context = NULL; failed_context_create: - fw_core_remove_address_handler(&dev->handler); - dev->local_fifo = FWNET_NO_FIFO_ADDR; + fwnet_fifo_stop(dev); failed_initial: return retval; @@ -1600,8 +1620,7 @@ static int fwnet_remove(struct device *_dev) if (list_empty(&dev->peer_list)) { unregister_netdev(net); - if (dev->local_fifo != FWNET_NO_FIFO_ADDR) - fw_core_remove_address_handler(&dev->handler); + fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { fw_iso_context_stop(dev->broadcast_rcv_context); fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, From b9a8871ac2aab0cc87190f1ab870785b32cc24aa Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:38 +0900 Subject: [PATCH 03/11] firewire net: Setup broadcast and local fifo independently. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 96f6ee5bffd4..fbd07ebd3f5f 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1156,10 +1156,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned long offset; unsigned u; - retval = fwnet_fifo_start(dev); - if (retval < 0) - goto failed_initial; - max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; @@ -1240,8 +1236,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) fw_iso_context_destroy(context); dev->broadcast_rcv_context = NULL; failed_context_create: - fwnet_fifo_stop(dev); - failed_initial: return retval; } @@ -1260,10 +1254,14 @@ static int fwnet_open(struct net_device *net) struct fwnet_device *dev = netdev_priv(net); int ret; + ret = fwnet_fifo_start(dev); + if (ret) + return ret; + if (dev->broadcast_state == FWNET_BROADCAST_ERROR) { ret = fwnet_broadcast_start(dev); if (ret) - return ret; + goto out; } netif_start_queue(net); @@ -1272,6 +1270,9 @@ static int fwnet_open(struct net_device *net) spin_unlock_irq(&dev->lock); return 0; +out: + fwnet_fifo_stop(dev); + return ret; } /* ifdown */ From 2fbd8dfee1dc50407eaf72e30333cf8ce1bba2cb Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:14 +0900 Subject: [PATCH 04/11] firewire net: Check dev->broadcast_state inside fwnet_broadcast_start(). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index fbd07ebd3f5f..9a2634ad6426 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1156,6 +1156,9 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned long offset; unsigned u; + if (dev->broadcast_state != FWNET_BROADCAST_ERROR) + return 0; + max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; @@ -1258,11 +1261,10 @@ static int fwnet_open(struct net_device *net) if (ret) return ret; - if (dev->broadcast_state == FWNET_BROADCAST_ERROR) { - ret = fwnet_broadcast_start(dev); - if (ret) - goto out; - } + ret = fwnet_broadcast_start(dev); + if (ret) + goto out; + netif_start_queue(net); spin_lock_irq(&dev->lock); From 48a8406f5bd5cb49e1c03777ed19638de2628882 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:50 +0900 Subject: [PATCH 05/11] firewire net: Fix memory leakage in fwnet_remove(). Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 9a2634ad6426..d9b2105f22a0 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1626,6 +1626,8 @@ static int fwnet_remove(struct device *_dev) fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { fw_iso_context_stop(dev->broadcast_rcv_context); + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); From f60bac4bc9f8c6b20b27a2be210a69e2f256f0a5 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:42:59 +0900 Subject: [PATCH 06/11] firewire net: Clear dev->broadcast_rcv_context and dev->broadcast_state after destruction of context. Clear dev->broadcast_rcv_context to NULL and set dev->broadcast_state to FWNET_BROADCAST_ERROR after descruction of broadcast context. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index d9b2105f22a0..efed4a65fb06 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1626,11 +1626,14 @@ static int fwnet_remove(struct device *_dev) fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { fw_iso_context_stop(dev->broadcast_rcv_context); + kfree(dev->broadcast_rcv_buffer_ptrs); dev->broadcast_rcv_buffer_ptrs = NULL; fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); + dev->broadcast_rcv_context = NULL; + dev->broadcast_state = FWNET_BROADCAST_ERROR; } for (i = 0; dev->queued_datagrams && i < 5; i++) ssleep(1); From f2090594dd28c033e0a9a267240ffca6d5afbd84 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:25 +0900 Subject: [PATCH 07/11] firewire net: Omit checking dev->broadcast_rcv_context in fwnet_broadcast_start(). dev->broadcast_rcv_context is always non-NULL if dev->broadcast_state is not FWNET_BROADCAST_ERROR. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 65 +++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index efed4a65fb06..d8cb6ac31044 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1154,6 +1154,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) unsigned max_receive; struct fw_iso_packet packet; unsigned long offset; + void **ptrptr; unsigned u; if (dev->broadcast_state != FWNET_BROADCAST_ERROR) @@ -1162,43 +1163,37 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; - if (!dev->broadcast_rcv_context) { - void **ptrptr; - - context = fw_iso_context_create(dev->card, - FW_ISO_CONTEXT_RECEIVE, IEEE1394_BROADCAST_CHANNEL, - dev->card->link_speed, 8, fwnet_receive_broadcast, dev); - if (IS_ERR(context)) { - retval = PTR_ERR(context); - goto failed_context_create; - } - - retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, - dev->card, FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); - if (retval < 0) - goto failed_buffer_init; - - ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); - if (!ptrptr) { - retval = -ENOMEM; - goto failed_ptrs_alloc; - } - - dev->broadcast_rcv_buffer_ptrs = ptrptr; - for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { - void *ptr; - unsigned v; - - ptr = kmap(dev->broadcast_rcv_buffer.pages[u]); - for (v = 0; v < num_packets / FWNET_ISO_PAGE_COUNT; v++) - *ptrptr++ = (void *) - ((char *)ptr + v * max_receive); - } - dev->broadcast_rcv_context = context; - } else { - context = dev->broadcast_rcv_context; + context = fw_iso_context_create(dev->card, FW_ISO_CONTEXT_RECEIVE, + IEEE1394_BROADCAST_CHANNEL, + dev->card->link_speed, 8, + fwnet_receive_broadcast, dev); + if (IS_ERR(context)) { + retval = PTR_ERR(context); + goto failed_context_create; } + retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card, + FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); + if (retval < 0) + goto failed_buffer_init; + + ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); + if (!ptrptr) { + retval = -ENOMEM; + goto failed_ptrs_alloc; + } + + dev->broadcast_rcv_buffer_ptrs = ptrptr; + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { + void *ptr; + unsigned v; + + ptr = kmap(dev->broadcast_rcv_buffer.pages[u]); + for (v = 0; v < num_packets / FWNET_ISO_PAGE_COUNT; v++) + *ptrptr++ = (void *) ((char *)ptr + v * max_receive); + } + dev->broadcast_rcv_context = context; + packet.payload_length = max_receive; packet.interrupt = 1; packet.skip = 0; From d9d2b484e0006d51591c3b9594e9d5f73b1a8d08 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:37 +0900 Subject: [PATCH 08/11] firewire net: Fix leakage of kmap for broadcast receive buffer. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index d8cb6ac31044..0dc2fdf00562 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1228,6 +1228,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) failed_rcv_queue: kfree(dev->broadcast_rcv_buffer_ptrs); dev->broadcast_rcv_buffer_ptrs = NULL; + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) + kunmap(dev->broadcast_rcv_buffer.pages[u]); failed_ptrs_alloc: fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); failed_buffer_init: @@ -1620,10 +1622,15 @@ static int fwnet_remove(struct device *_dev) fwnet_fifo_stop(dev); if (dev->broadcast_rcv_context) { + unsigned u; + fw_iso_context_stop(dev->broadcast_rcv_context); kfree(dev->broadcast_rcv_buffer_ptrs); dev->broadcast_rcv_buffer_ptrs = NULL; + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) + kunmap(dev->broadcast_rcv_buffer.pages[u]); + fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); From eac31d58ca2818e3fdc7a6e78fa1b56965f604e9 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:43:55 +0900 Subject: [PATCH 09/11] firewire net: Allocate dev->broadcast_rcv_buffer_ptrs early. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 0dc2fdf00562..21210fb94762 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1163,6 +1163,13 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) max_receive = 1U << (dev->card->max_receive + 1); num_packets = (FWNET_ISO_PAGE_COUNT * PAGE_SIZE) / max_receive; + ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); + if (!ptrptr) { + retval = -ENOMEM; + goto failed_ptrs_alloc; + } + dev->broadcast_rcv_buffer_ptrs = ptrptr; + context = fw_iso_context_create(dev->card, FW_ISO_CONTEXT_RECEIVE, IEEE1394_BROADCAST_CHANNEL, dev->card->link_speed, 8, @@ -1177,13 +1184,6 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) if (retval < 0) goto failed_buffer_init; - ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); - if (!ptrptr) { - retval = -ENOMEM; - goto failed_ptrs_alloc; - } - - dev->broadcast_rcv_buffer_ptrs = ptrptr; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { void *ptr; unsigned v; @@ -1226,16 +1226,16 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) return 0; failed_rcv_queue: - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) kunmap(dev->broadcast_rcv_buffer.pages[u]); - failed_ptrs_alloc: fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); failed_buffer_init: fw_iso_context_destroy(context); dev->broadcast_rcv_context = NULL; failed_context_create: + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; + failed_ptrs_alloc: return retval; } @@ -1626,8 +1626,6 @@ static int fwnet_remove(struct device *_dev) fw_iso_context_stop(dev->broadcast_rcv_context); - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) kunmap(dev->broadcast_rcv_buffer.pages[u]); @@ -1635,6 +1633,8 @@ static int fwnet_remove(struct device *_dev) dev->card); fw_iso_context_destroy(dev->broadcast_rcv_context); dev->broadcast_rcv_context = NULL; + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; dev->broadcast_state = FWNET_BROADCAST_ERROR; } for (i = 0; dev->queued_datagrams && i < 5; i++) From 111534cd7a376b75e72ddea0c6d00ec956ce3343 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:45:50 +0900 Subject: [PATCH 10/11] firewire net: Introduce fwnet_broadcast_stop() to destroy broadcast resources. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 68 ++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 21210fb94762..ca41446d62f4 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1146,6 +1146,32 @@ static int fwnet_fifo_start(struct fwnet_device *dev) return 0; } +static void __fwnet_broadcast_stop(struct fwnet_device *dev) +{ + unsigned u; + + if (dev->broadcast_state != FWNET_BROADCAST_ERROR) { + for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) + kunmap(dev->broadcast_rcv_buffer.pages[u]); + fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); + } + if (dev->broadcast_rcv_context) { + fw_iso_context_destroy(dev->broadcast_rcv_context); + dev->broadcast_rcv_context = NULL; + } + kfree(dev->broadcast_rcv_buffer_ptrs); + dev->broadcast_rcv_buffer_ptrs = NULL; + dev->broadcast_state = FWNET_BROADCAST_ERROR; +} + +static void fwnet_broadcast_stop(struct fwnet_device *dev) +{ + if (dev->broadcast_state == FWNET_BROADCAST_ERROR) + return; + fw_iso_context_stop(dev->broadcast_rcv_context); + __fwnet_broadcast_stop(dev); +} + static int fwnet_broadcast_start(struct fwnet_device *dev) { struct fw_iso_context *context; @@ -1166,7 +1192,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); if (!ptrptr) { retval = -ENOMEM; - goto failed_ptrs_alloc; + goto failed; } dev->broadcast_rcv_buffer_ptrs = ptrptr; @@ -1176,13 +1202,15 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) fwnet_receive_broadcast, dev); if (IS_ERR(context)) { retval = PTR_ERR(context); - goto failed_context_create; + goto failed; } retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card, FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); if (retval < 0) - goto failed_buffer_init; + goto failed; + + dev->broadcast_state = FWNET_BROADCAST_STOPPED; for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { void *ptr; @@ -1206,7 +1234,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) retval = fw_iso_context_queue(context, &packet, &dev->broadcast_rcv_buffer, offset); if (retval < 0) - goto failed_rcv_queue; + goto failed; offset += max_receive; } @@ -1216,7 +1244,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) retval = fw_iso_context_start(context, -1, 0, FW_ISO_CONTEXT_MATCH_ALL_TAGS); /* ??? sync */ if (retval < 0) - goto failed_rcv_queue; + goto failed; /* FIXME: adjust it according to the min. speed of all known peers? */ dev->broadcast_xmt_max_payload = IEEE1394_MAX_PAYLOAD_S100 @@ -1225,18 +1253,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) return 0; - failed_rcv_queue: - for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) - kunmap(dev->broadcast_rcv_buffer.pages[u]); - fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); - failed_buffer_init: - fw_iso_context_destroy(context); - dev->broadcast_rcv_context = NULL; - failed_context_create: - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; - failed_ptrs_alloc: - + failed: + __fwnet_broadcast_stop(dev); return retval; } @@ -1621,22 +1639,8 @@ static int fwnet_remove(struct device *_dev) unregister_netdev(net); fwnet_fifo_stop(dev); - if (dev->broadcast_rcv_context) { - unsigned u; + fwnet_broadcast_stop(dev); - fw_iso_context_stop(dev->broadcast_rcv_context); - - for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) - kunmap(dev->broadcast_rcv_buffer.pages[u]); - - fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, - dev->card); - fw_iso_context_destroy(dev->broadcast_rcv_context); - dev->broadcast_rcv_context = NULL; - kfree(dev->broadcast_rcv_buffer_ptrs); - dev->broadcast_rcv_buffer_ptrs = NULL; - dev->broadcast_state = FWNET_BROADCAST_ERROR; - } for (i = 0; dev->queued_datagrams && i < 5; i++) ssleep(1); WARN_ON(dev->queued_datagrams); From 8559e7f0694e3fb192aab00a495be5a510afc8c3 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Fri, 8 Mar 2013 10:45:57 +0900 Subject: [PATCH 11/11] firewire net: Release broadcast/fifo resources on ifdown. Since those resources are allocated on ifup, relsase them on ifdown. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index ca41446d62f4..c1898adeb900 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -1295,9 +1295,12 @@ out: /* ifdown */ static int fwnet_stop(struct net_device *net) { + struct fwnet_device *dev = netdev_priv(net); + netif_stop_queue(net); - /* Deallocate iso context for use by other applications? */ + fwnet_broadcast_stop(dev); + fwnet_fifo_stop(dev); return 0; } @@ -1638,9 +1641,6 @@ static int fwnet_remove(struct device *_dev) if (list_empty(&dev->peer_list)) { unregister_netdev(net); - fwnet_fifo_stop(dev); - fwnet_broadcast_stop(dev); - for (i = 0; dev->queued_datagrams && i < 5; i++) ssleep(1); WARN_ON(dev->queued_datagrams);