aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/atm/solos-pci.c
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2009-03-17 10:59:34 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-03-17 10:59:34 -0400
commit97d759d3e86f9c7ced094352838e7e4d1cf8cddf (patch)
tree86e5d35322c8f9a90c5b6c783b0950148e2216a0 /drivers/atm/solos-pci.c
parentf87b2ed225c002ea1b1b9994c6608d8b202f865e (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.c30
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)
1217static void fpga_remove(struct pci_dev *dev) 1235static 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