diff options
Diffstat (limited to 'drivers/atm/idt77252.c')
| -rw-r--r-- | drivers/atm/idt77252.c | 120 |
1 files changed, 62 insertions, 58 deletions
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 60bacba03d17..f2e91b7d79f0 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -134,7 +134,7 @@ static int idt77252_proc_read(struct atm_dev *dev, loff_t * pos, static void idt77252_softint(struct work_struct *work); -static struct atmdev_ops idt77252_ops = +static const struct atmdev_ops idt77252_ops = { .dev_close = idt77252_dev_close, .open = idt77252_open, @@ -641,8 +641,8 @@ alloc_scq(struct idt77252_dev *card, int class) scq = kzalloc(sizeof(struct scq_info), GFP_KERNEL); if (!scq) return NULL; - scq->base = dma_zalloc_coherent(&card->pcidev->dev, SCQ_SIZE, - &scq->paddr, GFP_KERNEL); + scq->base = dma_alloc_coherent(&card->pcidev->dev, SCQ_SIZE, + &scq->paddr, GFP_KERNEL); if (scq->base == NULL) { kfree(scq); return NULL; @@ -835,6 +835,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc, unsigned long flags; int error; int aal; + u32 word4; if (skb->len == 0) { printk("%s: invalid skb->len (%d)\n", card->name, skb->len); @@ -846,9 +847,13 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc, tbd = &IDT77252_PRV_TBD(skb); vcc = ATM_SKB(skb)->vcc; + word4 = (skb->data[0] << 24) | (skb->data[1] << 16) | + (skb->data[2] << 8) | (skb->data[3] << 0); IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data, skb->len, DMA_TO_DEVICE); + if (dma_mapping_error(&card->pcidev->dev, IDT77252_PRV_PADDR(skb))) + return -ENOMEM; error = -EINVAL; @@ -859,8 +864,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc, tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU; tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4; tbd->word_3 = 0x00000000; - tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) | - (skb->data[2] << 8) | (skb->data[3] << 0); + tbd->word_4 = word4; if (test_bit(VCF_RSV, &vc->flags)) vc = card->vcs[0]; @@ -890,8 +894,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc, tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4; tbd->word_3 = 0x00000000; - tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) | - (skb->data[2] << 8) | (skb->data[3] << 0); + tbd->word_4 = word4; break; case ATM_AAL5: @@ -971,8 +974,8 @@ init_rsq(struct idt77252_dev *card) { struct rsq_entry *rsqe; - card->rsq.base = dma_zalloc_coherent(&card->pcidev->dev, RSQSIZE, - &card->rsq.paddr, GFP_KERNEL); + card->rsq.base = dma_alloc_coherent(&card->pcidev->dev, RSQSIZE, + &card->rsq.paddr, GFP_KERNEL); if (card->rsq.base == NULL) { printk("%s: can't allocate RSQ.\n", card->name); return -1; @@ -1117,8 +1120,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) rpp->len += skb->len; if (stat & SAR_RSQE_EPDU) { + unsigned int len, truesize; unsigned char *l1l2; - unsigned int len; l1l2 = (unsigned char *) ((unsigned long) skb->data + skb->len - 6); @@ -1188,14 +1191,15 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) ATM_SKB(skb)->vcc = vcc; __net_timestamp(skb); + truesize = skb->truesize; vcc->push(vcc, skb); atomic_inc(&vcc->stats->rx); - if (skb->truesize > SAR_FB_SIZE_3) + if (truesize > SAR_FB_SIZE_3) add_rx_skb(card, 3, SAR_FB_SIZE_3, 1); - else if (skb->truesize > SAR_FB_SIZE_2) + else if (truesize > SAR_FB_SIZE_2) add_rx_skb(card, 2, SAR_FB_SIZE_2, 1); - else if (skb->truesize > SAR_FB_SIZE_1) + else if (truesize > SAR_FB_SIZE_1) add_rx_skb(card, 1, SAR_FB_SIZE_1, 1); else add_rx_skb(card, 0, SAR_FB_SIZE_0, 1); @@ -1379,7 +1383,6 @@ init_tsq(struct idt77252_dev *card) printk("%s: can't allocate TSQ.\n", card->name); return -1; } - memset(card->tsq.base, 0, TSQSIZE); card->tsq.last = card->tsq.base + TSQ_NUM_ENTRIES - 1; card->tsq.next = card->tsq.last; @@ -1528,9 +1531,9 @@ idt77252_tx(struct idt77252_dev *card) static void -tst_timer(unsigned long data) +tst_timer(struct timer_list *t) { - struct idt77252_dev *card = (struct idt77252_dev *)data; + struct idt77252_dev *card = timer_container_of(card, t, tst_timer); unsigned long base, idle, jump; unsigned long flags; u32 pc; @@ -1784,12 +1787,6 @@ set_tct(struct idt77252_dev *card, struct vc_map *vc) /*****************************************************************************/ static __inline__ int -idt77252_fbq_level(struct idt77252_dev *card, int queue) -{ - return (readl(SAR_REG_STAT) >> (16 + (queue << 2))) & 0x0f; -} - -static __inline__ int idt77252_fbq_full(struct idt77252_dev *card, int queue) { return (readl(SAR_REG_STAT) >> (16 + (queue << 2))) == 0x0f; @@ -1862,6 +1859,8 @@ add_rx_skb(struct idt77252_dev *card, int queue, paddr = dma_map_single(&card->pcidev->dev, skb->data, skb_end_pointer(skb) - skb->data, DMA_FROM_DEVICE); + if (dma_mapping_error(&card->pcidev->dev, paddr)) + goto outpoolrm; IDT77252_PRV_PADDR(skb) = paddr; if (push_rx_skb(card, skb, queue)) { @@ -1876,6 +1875,7 @@ outunmap: dma_unmap_single(&card->pcidev->dev, IDT77252_PRV_PADDR(skb), skb_end_pointer(skb) - skb->data, DMA_FROM_DEVICE); +outpoolrm: handle = IDT77252_PRV_POOL(skb); card->sbpool[POOL_QUEUE(handle)].skb[POOL_INDEX(handle)] = NULL; @@ -2073,21 +2073,19 @@ idt77252_rate_logindex(struct idt77252_dev *card, int pcr) } static void -idt77252_est_timer(unsigned long data) +idt77252_est_timer(struct timer_list *t) { - struct vc_map *vc = (struct vc_map *)data; + struct rate_estimator *est = timer_container_of(est, t, timer); + struct vc_map *vc = est->vc; struct idt77252_dev *card = vc->card; - struct rate_estimator *est; unsigned long flags; u32 rate, cps; u64 ncells; u8 lacr; spin_lock_irqsave(&vc->lock, flags); - est = vc->estimator; - if (!est) + if (!vc->estimator) goto out; - ncells = est->cells; rate = ((u32)(ncells - est->last_cells)) << (7 - est->interval); @@ -2126,10 +2124,11 @@ idt77252_init_est(struct vc_map *vc, int pcr) est->maxcps = pcr < 0 ? -pcr : pcr; est->cps = est->maxcps; est->avcps = est->cps << 5; + est->vc = vc; est->interval = 2; /* XXX: make this configurable */ est->ewma_log = 2; /* XXX: make this configurable */ - setup_timer(&est->timer, idt77252_est_timer, (unsigned long)vc); + timer_setup(&est->timer, idt77252_est_timer, 0); mod_timer(&est->timer, jiffies + ((HZ / 4) << est->interval)); return est; @@ -2209,16 +2208,20 @@ static int idt77252_init_ubr(struct idt77252_dev *card, struct vc_map *vc, struct atm_vcc *vcc, struct atm_qos *qos) { + struct rate_estimator *est = NULL; unsigned long flags; int tcr; spin_lock_irqsave(&vc->lock, flags); if (vc->estimator) { - del_timer(&vc->estimator->timer); - kfree(vc->estimator); + est = vc->estimator; vc->estimator = NULL; } spin_unlock_irqrestore(&vc->lock, flags); + if (est) { + timer_shutdown_sync(&est->timer); + kfree(est); + } tcr = atm_pcr_goal(&qos->txtp); if (tcr == 0) @@ -2533,7 +2536,7 @@ done: vc->tx_vcc = NULL; if (vc->estimator) { - del_timer(&vc->estimator->timer); + timer_shutdown(&vc->estimator->timer); kfree(vc->estimator); vc->estimator = NULL; } @@ -2912,6 +2915,7 @@ close_card_oam(struct idt77252_dev *card) recycle_rx_pool_skb(card, &vc->rcv.rx_pool); } + kfree(vc); } } } @@ -2932,6 +2936,8 @@ open_card_ubr0(struct idt77252_dev *card) vc->scq = alloc_scq(card, vc->class); if (!vc->scq) { printk("%s: can't get SCQ.\n", card->name); + kfree(card->vcs[0]); + card->vcs[0] = NULL; return -ENOMEM; } @@ -2955,6 +2961,15 @@ open_card_ubr0(struct idt77252_dev *card) return 0; } +static void +close_card_ubr0(struct idt77252_dev *card) +{ + struct vc_map *vc = card->vcs[0]; + + free_scq(card, vc->scq); + kfree(vc); +} + static int idt77252_dev_open(struct idt77252_dev *card) { @@ -3004,6 +3019,7 @@ static void idt77252_dev_close(struct atm_dev *dev) struct idt77252_dev *card = dev->dev_data; u32 conf; + close_card_ubr0(card); close_card_oam(card); conf = SAR_CFG_RXPTH | /* enable receive path */ @@ -3170,14 +3186,10 @@ static void init_sram(struct idt77252_dev *card) (u32) 0xffffffff); } - writel((SAR_FBQ0_LOW << 28) | 0x00000000 | 0x00000000 | - (SAR_FB_SIZE_0 / 48), SAR_REG_FBQS0); - writel((SAR_FBQ1_LOW << 28) | 0x00000000 | 0x00000000 | - (SAR_FB_SIZE_1 / 48), SAR_REG_FBQS1); - writel((SAR_FBQ2_LOW << 28) | 0x00000000 | 0x00000000 | - (SAR_FB_SIZE_2 / 48), SAR_REG_FBQS2); - writel((SAR_FBQ3_LOW << 28) | 0x00000000 | 0x00000000 | - (SAR_FB_SIZE_3 / 48), SAR_REG_FBQS3); + writel((SAR_FBQ0_LOW << 28) | (SAR_FB_SIZE_0 / 48), SAR_REG_FBQS0); + writel((SAR_FBQ1_LOW << 28) | (SAR_FB_SIZE_1 / 48), SAR_REG_FBQS1); + writel((SAR_FBQ2_LOW << 28) | (SAR_FB_SIZE_2 / 48), SAR_REG_FBQS2); + writel((SAR_FBQ3_LOW << 28) | (SAR_FB_SIZE_3 / 48), SAR_REG_FBQS3); /* Initialize rate table */ for (i = 0; i < 256; i++) { @@ -3391,10 +3403,10 @@ static int init_card(struct atm_dev *dev) writel(0, SAR_REG_GP); /* Initialize RAW Cell Handle Register */ - card->raw_cell_hnd = dma_zalloc_coherent(&card->pcidev->dev, - 2 * sizeof(u32), - &card->raw_cell_paddr, - GFP_KERNEL); + card->raw_cell_hnd = dma_alloc_coherent(&card->pcidev->dev, + 2 * sizeof(u32), + &card->raw_cell_paddr, + GFP_KERNEL); if (!card->raw_cell_hnd) { printk("%s: memory allocation failure.\n", card->name); deinit_card(card); @@ -3543,7 +3555,7 @@ static int idt77252_preset(struct idt77252_dev *card) return -1; } if (!(pci_command & PCI_COMMAND_IO)) { - printk("%s: PCI_COMMAND: %04x (???)\n", + printk("%s: PCI_COMMAND: %04x (?)\n", card->name, pci_command); deinit_card(card); return (-1); @@ -3608,7 +3620,7 @@ static int idt77252_init_one(struct pci_dev *pcidev, if ((err = dma_set_mask_and_coherent(&pcidev->dev, DMA_BIT_MASK(32)))) { printk("idt77252: can't enable DMA for PCI device at %s\n", pci_name(pcidev)); - return err; + goto err_out_disable_pdev; } card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); @@ -3631,7 +3643,7 @@ static int idt77252_init_one(struct pci_dev *pcidev, spin_lock_init(&card->cmd_lock); spin_lock_init(&card->tst_lock); - setup_timer(&card->tst_timer, tst_timer, (unsigned long)card); + timer_setup(&card->tst_timer, tst_timer, 0); /* Do the I/O remapping... */ card->membase = ioremap(membase, 1024); @@ -3725,7 +3737,7 @@ err_out_disable_pdev: return err; } -static struct pci_device_id idt77252_pci_tbl[] = +static const struct pci_device_id idt77252_pci_tbl[] = { { PCI_VDEVICE(IDT, PCI_DEVICE_ID_IDT_IDT77252), 0 }, { 0, } @@ -3744,16 +3756,7 @@ static int __init idt77252_init(void) struct sk_buff *skb; printk("%s: at %p\n", __func__, idt77252_init); - - if (sizeof(skb->cb) < sizeof(struct atm_skb_data) + - sizeof(struct idt77252_skb_prv)) { - printk(KERN_ERR "%s: skb->cb is too small (%lu < %lu)\n", - __func__, (unsigned long) sizeof(skb->cb), - (unsigned long) sizeof(struct atm_skb_data) + - sizeof(struct idt77252_skb_prv)); - return -EIO; - } - + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct idt77252_skb_prv) + sizeof(struct atm_skb_data)); return pci_register_driver(&idt77252_driver); } @@ -3768,6 +3771,7 @@ static void __exit idt77252_exit(void) card = idt77252_chain; dev = card->atmdev; idt77252_chain = card->next; + timer_shutdown_sync(&card->tst_timer); if (dev->phy->stop) dev->phy->stop(dev); |
