diff options
Diffstat (limited to 'drivers/firewire')
-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); |