diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2009-03-17 10:59:34 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-03-17 10:59:34 -0400 |
commit | 97d759d3e86f9c7ced094352838e7e4d1cf8cddf (patch) | |
tree | 86e5d35322c8f9a90c5b6c783b0950148e2216a0 /drivers/atm/solos-pci.c | |
parent | f87b2ed225c002ea1b1b9994c6608d8b202f865e (diff) |
solos: Reset device on unload, free pending skbs
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/atm/solos-pci.c')
-rw-r--r-- | drivers/atm/solos-pci.c | 30 |
1 files changed, 29 insertions, 1 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index eef920a9c448..1ff730497217 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -1206,10 +1206,28 @@ static void atm_remove(struct solos_card *card) | |||
1206 | 1206 | ||
1207 | for (i = 0; i < card->nr_ports; i++) { | 1207 | for (i = 0; i < card->nr_ports; i++) { |
1208 | if (card->atmdev[i]) { | 1208 | if (card->atmdev[i]) { |
1209 | struct sk_buff *skb; | ||
1210 | |||
1209 | dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number); | 1211 | dev_info(&card->dev->dev, "Unregistering ATM device %d\n", card->atmdev[i]->number); |
1210 | 1212 | ||
1211 | sysfs_remove_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group); | 1213 | sysfs_remove_group(&card->atmdev[i]->class_dev.kobj, &solos_attr_group); |
1212 | atm_dev_deregister(card->atmdev[i]); | 1214 | atm_dev_deregister(card->atmdev[i]); |
1215 | |||
1216 | skb = card->rx_skb[i]; | ||
1217 | if (skb) { | ||
1218 | pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr, | ||
1219 | RX_DMA_SIZE, PCI_DMA_FROMDEVICE); | ||
1220 | dev_kfree_skb(skb); | ||
1221 | } | ||
1222 | skb = card->tx_skb[i]; | ||
1223 | if (skb) { | ||
1224 | pci_unmap_single(card->dev, SKB_CB(skb)->dma_addr, | ||
1225 | skb->len, PCI_DMA_TODEVICE); | ||
1226 | dev_kfree_skb(skb); | ||
1227 | } | ||
1228 | while ((skb = skb_dequeue(&card->tx_queue[i]))) | ||
1229 | dev_kfree_skb(skb); | ||
1230 | |||
1213 | } | 1231 | } |
1214 | } | 1232 | } |
1215 | } | 1233 | } |
@@ -1217,13 +1235,23 @@ static void atm_remove(struct solos_card *card) | |||
1217 | static void fpga_remove(struct pci_dev *dev) | 1235 | static void fpga_remove(struct pci_dev *dev) |
1218 | { | 1236 | { |
1219 | struct solos_card *card = pci_get_drvdata(dev); | 1237 | struct solos_card *card = pci_get_drvdata(dev); |
1238 | |||
1239 | /* Disable IRQs */ | ||
1240 | iowrite32(0, card->config_regs + IRQ_EN_ADDR); | ||
1241 | |||
1242 | /* Reset FPGA */ | ||
1243 | iowrite32(1, card->config_regs + FPGA_MODE); | ||
1244 | (void)ioread32(card->config_regs + FPGA_MODE); | ||
1220 | 1245 | ||
1221 | atm_remove(card); | 1246 | atm_remove(card); |
1222 | 1247 | ||
1223 | iowrite32(0, card->config_regs + IRQ_EN_ADDR); | ||
1224 | free_irq(dev->irq, card); | 1248 | free_irq(dev->irq, card); |
1225 | tasklet_kill(&card->tlet); | 1249 | tasklet_kill(&card->tlet); |
1226 | 1250 | ||
1251 | /* Release device from reset */ | ||
1252 | iowrite32(0, card->config_regs + FPGA_MODE); | ||
1253 | (void)ioread32(card->config_regs + FPGA_MODE); | ||
1254 | |||
1227 | pci_iounmap(dev, card->buffers); | 1255 | pci_iounmap(dev, card->buffers); |
1228 | pci_iounmap(dev, card->config_regs); | 1256 | pci_iounmap(dev, card->config_regs); |
1229 | 1257 | ||