diff options
| author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2013-03-08 10:45:50 +0900 | 
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2013-03-13 16:11:12 +0100 | 
| commit | 111534cd7a376b75e72ddea0c6d00ec956ce3343 (patch) | |
| tree | ee49c45f44b9945a2110f6167cf878a404a47c74 /drivers/firewire/net.c | |
| parent | eac31d58ca2818e3fdc7a6e78fa1b56965f604e9 (diff) | |
| download | olio-linux-3.10-111534cd7a376b75e72ddea0c6d00ec956ce3343.tar.xz olio-linux-3.10-111534cd7a376b75e72ddea0c6d00ec956ce3343.zip  | |
firewire net: Introduce fwnet_broadcast_stop() to destroy broadcast resources.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/net.c')
| -rw-r--r-- | drivers/firewire/net.c | 68 | 
1 files changed, 36 insertions, 32 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 21210fb9476..ca41446d62f 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; - -			fw_iso_context_stop(dev->broadcast_rcv_context); +		fwnet_broadcast_stop(dev); -			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);  |