diff options
| author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2013-03-07 20:45:50 -0500 |
|---|---|---|
| committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2013-03-13 11:11:12 -0400 |
| commit | 111534cd7a376b75e72ddea0c6d00ec956ce3343 (patch) | |
| tree | ee49c45f44b9945a2110f6167cf878a404a47c74 | |
| parent | eac31d58ca2818e3fdc7a6e78fa1b56965f604e9 (diff) | |
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>
| -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 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) | |||
| 1146 | return 0; | 1146 | return 0; |
| 1147 | } | 1147 | } |
| 1148 | 1148 | ||
| 1149 | static void __fwnet_broadcast_stop(struct fwnet_device *dev) | ||
| 1150 | { | ||
| 1151 | unsigned u; | ||
| 1152 | |||
| 1153 | if (dev->broadcast_state != FWNET_BROADCAST_ERROR) { | ||
| 1154 | for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) | ||
| 1155 | kunmap(dev->broadcast_rcv_buffer.pages[u]); | ||
| 1156 | fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); | ||
| 1157 | } | ||
| 1158 | if (dev->broadcast_rcv_context) { | ||
| 1159 | fw_iso_context_destroy(dev->broadcast_rcv_context); | ||
| 1160 | dev->broadcast_rcv_context = NULL; | ||
| 1161 | } | ||
| 1162 | kfree(dev->broadcast_rcv_buffer_ptrs); | ||
| 1163 | dev->broadcast_rcv_buffer_ptrs = NULL; | ||
| 1164 | dev->broadcast_state = FWNET_BROADCAST_ERROR; | ||
| 1165 | } | ||
| 1166 | |||
| 1167 | static void fwnet_broadcast_stop(struct fwnet_device *dev) | ||
| 1168 | { | ||
| 1169 | if (dev->broadcast_state == FWNET_BROADCAST_ERROR) | ||
| 1170 | return; | ||
| 1171 | fw_iso_context_stop(dev->broadcast_rcv_context); | ||
| 1172 | __fwnet_broadcast_stop(dev); | ||
| 1173 | } | ||
| 1174 | |||
| 1149 | static int fwnet_broadcast_start(struct fwnet_device *dev) | 1175 | static int fwnet_broadcast_start(struct fwnet_device *dev) |
| 1150 | { | 1176 | { |
| 1151 | struct fw_iso_context *context; | 1177 | struct fw_iso_context *context; |
| @@ -1166,7 +1192,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
| 1166 | ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); | 1192 | ptrptr = kmalloc(sizeof(void *) * num_packets, GFP_KERNEL); |
| 1167 | if (!ptrptr) { | 1193 | if (!ptrptr) { |
| 1168 | retval = -ENOMEM; | 1194 | retval = -ENOMEM; |
| 1169 | goto failed_ptrs_alloc; | 1195 | goto failed; |
| 1170 | } | 1196 | } |
| 1171 | dev->broadcast_rcv_buffer_ptrs = ptrptr; | 1197 | dev->broadcast_rcv_buffer_ptrs = ptrptr; |
| 1172 | 1198 | ||
| @@ -1176,13 +1202,15 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
| 1176 | fwnet_receive_broadcast, dev); | 1202 | fwnet_receive_broadcast, dev); |
| 1177 | if (IS_ERR(context)) { | 1203 | if (IS_ERR(context)) { |
| 1178 | retval = PTR_ERR(context); | 1204 | retval = PTR_ERR(context); |
| 1179 | goto failed_context_create; | 1205 | goto failed; |
| 1180 | } | 1206 | } |
| 1181 | 1207 | ||
| 1182 | retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card, | 1208 | retval = fw_iso_buffer_init(&dev->broadcast_rcv_buffer, dev->card, |
| 1183 | FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); | 1209 | FWNET_ISO_PAGE_COUNT, DMA_FROM_DEVICE); |
| 1184 | if (retval < 0) | 1210 | if (retval < 0) |
| 1185 | goto failed_buffer_init; | 1211 | goto failed; |
| 1212 | |||
| 1213 | dev->broadcast_state = FWNET_BROADCAST_STOPPED; | ||
| 1186 | 1214 | ||
| 1187 | for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { | 1215 | for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) { |
| 1188 | void *ptr; | 1216 | void *ptr; |
| @@ -1206,7 +1234,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
| 1206 | retval = fw_iso_context_queue(context, &packet, | 1234 | retval = fw_iso_context_queue(context, &packet, |
| 1207 | &dev->broadcast_rcv_buffer, offset); | 1235 | &dev->broadcast_rcv_buffer, offset); |
| 1208 | if (retval < 0) | 1236 | if (retval < 0) |
| 1209 | goto failed_rcv_queue; | 1237 | goto failed; |
| 1210 | 1238 | ||
| 1211 | offset += max_receive; | 1239 | offset += max_receive; |
| 1212 | } | 1240 | } |
| @@ -1216,7 +1244,7 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
| 1216 | retval = fw_iso_context_start(context, -1, 0, | 1244 | retval = fw_iso_context_start(context, -1, 0, |
| 1217 | FW_ISO_CONTEXT_MATCH_ALL_TAGS); /* ??? sync */ | 1245 | FW_ISO_CONTEXT_MATCH_ALL_TAGS); /* ??? sync */ |
| 1218 | if (retval < 0) | 1246 | if (retval < 0) |
| 1219 | goto failed_rcv_queue; | 1247 | goto failed; |
| 1220 | 1248 | ||
| 1221 | /* FIXME: adjust it according to the min. speed of all known peers? */ | 1249 | /* FIXME: adjust it according to the min. speed of all known peers? */ |
| 1222 | dev->broadcast_xmt_max_payload = IEEE1394_MAX_PAYLOAD_S100 | 1250 | dev->broadcast_xmt_max_payload = IEEE1394_MAX_PAYLOAD_S100 |
| @@ -1225,18 +1253,8 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) | |||
| 1225 | 1253 | ||
| 1226 | return 0; | 1254 | return 0; |
| 1227 | 1255 | ||
| 1228 | failed_rcv_queue: | 1256 | failed: |
| 1229 | for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) | 1257 | __fwnet_broadcast_stop(dev); |
| 1230 | kunmap(dev->broadcast_rcv_buffer.pages[u]); | ||
| 1231 | fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, dev->card); | ||
| 1232 | failed_buffer_init: | ||
| 1233 | fw_iso_context_destroy(context); | ||
| 1234 | dev->broadcast_rcv_context = NULL; | ||
| 1235 | failed_context_create: | ||
| 1236 | kfree(dev->broadcast_rcv_buffer_ptrs); | ||
| 1237 | dev->broadcast_rcv_buffer_ptrs = NULL; | ||
| 1238 | failed_ptrs_alloc: | ||
| 1239 | |||
| 1240 | return retval; | 1258 | return retval; |
| 1241 | } | 1259 | } |
| 1242 | 1260 | ||
| @@ -1621,22 +1639,8 @@ static int fwnet_remove(struct device *_dev) | |||
| 1621 | unregister_netdev(net); | 1639 | unregister_netdev(net); |
| 1622 | 1640 | ||
| 1623 | fwnet_fifo_stop(dev); | 1641 | fwnet_fifo_stop(dev); |
| 1624 | if (dev->broadcast_rcv_context) { | 1642 | fwnet_broadcast_stop(dev); |
| 1625 | unsigned u; | ||
| 1626 | |||
| 1627 | fw_iso_context_stop(dev->broadcast_rcv_context); | ||
| 1628 | 1643 | ||
| 1629 | for (u = 0; u < FWNET_ISO_PAGE_COUNT; u++) | ||
| 1630 | kunmap(dev->broadcast_rcv_buffer.pages[u]); | ||
| 1631 | |||
| 1632 | fw_iso_buffer_destroy(&dev->broadcast_rcv_buffer, | ||
| 1633 | dev->card); | ||
| 1634 | fw_iso_context_destroy(dev->broadcast_rcv_context); | ||
| 1635 | dev->broadcast_rcv_context = NULL; | ||
| 1636 | kfree(dev->broadcast_rcv_buffer_ptrs); | ||
| 1637 | dev->broadcast_rcv_buffer_ptrs = NULL; | ||
| 1638 | dev->broadcast_state = FWNET_BROADCAST_ERROR; | ||
| 1639 | } | ||
| 1640 | for (i = 0; dev->queued_datagrams && i < 5; i++) | 1644 | for (i = 0; dev->queued_datagrams && i < 5; i++) |
| 1641 | ssleep(1); | 1645 | ssleep(1); |
| 1642 | WARN_ON(dev->queued_datagrams); | 1646 | WARN_ON(dev->queued_datagrams); |
