Commit 61033167 authored by Jeff Garzik's avatar Jeff Garzik

Merge pobox.com:/spare/repo/linux-2.6

into pobox.com:/spare/repo/net-drivers-2.6
parents 1e3cc3f5 8998ae21
...@@ -1297,6 +1297,13 @@ static int __devinit vortex_probe1(struct device *gendev, ...@@ -1297,6 +1297,13 @@ static int __devinit vortex_probe1(struct device *gendev,
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
} }
/* Unfortunately an all zero eeprom passes the checksum and this
gets found in the wild in failure cases. Crypto is hard 8) */
if (!is_valid_ether_addr(dev->dev_addr)) {
retval = -EINVAL;
printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
goto free_ring; /* With every pack */
}
EL3WINDOW(2); EL3WINDOW(2);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + i); outb(dev->dev_addr[i], ioaddr + i);
......
...@@ -84,7 +84,8 @@ config 3C359 ...@@ -84,7 +84,8 @@ config 3C359
config TMS380TR config TMS380TR
tristate "Generic TMS380 Token Ring ISA/PCI adapter support" tristate "Generic TMS380 Token Ring ISA/PCI adapter support"
depends on TR && (PCI || ISA) depends on TR && (PCI || ISA) && HOTPLUG
select FW_LOADER
---help--- ---help---
This driver provides generic support for token ring adapters This driver provides generic support for token ring adapters
based on the Texas Instruments TMS380 series chipsets. This based on the Texas Instruments TMS380 series chipsets. This
......
...@@ -221,6 +221,8 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device ...@@ -221,6 +221,8 @@ static int __devinit olympic_probe(struct pci_dev *pdev, const struct pci_device
olympic_priv = dev->priv ; olympic_priv = dev->priv ;
spin_lock_init(&olympic_priv->olympic_lock) ;
init_waitqueue_head(&olympic_priv->srb_wait); init_waitqueue_head(&olympic_priv->srb_wait);
init_waitqueue_head(&olympic_priv->trb_wait); init_waitqueue_head(&olympic_priv->trb_wait);
#if OLYMPIC_DEBUG #if OLYMPIC_DEBUG
...@@ -311,7 +313,6 @@ static int __devinit olympic_init(struct net_device *dev) ...@@ -311,7 +313,6 @@ static int __devinit olympic_init(struct net_device *dev)
} }
} }
spin_lock_init(&olympic_priv->olympic_lock) ;
/* Needed for cardbus */ /* Needed for cardbus */
if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) { if(!(readl(olympic_mmio+BCTL) & BCTL_MODE_INDICATOR)) {
...@@ -442,6 +443,8 @@ static int olympic_open(struct net_device *dev) ...@@ -442,6 +443,8 @@ static int olympic_open(struct net_device *dev)
DECLARE_WAITQUEUE(wait,current) ; DECLARE_WAITQUEUE(wait,current) ;
olympic_init(dev);
if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) { if(request_irq(dev->irq, &olympic_interrupt, SA_SHIRQ , "olympic", dev)) {
return -EAGAIN; return -EAGAIN;
} }
...@@ -898,7 +901,10 @@ static void olympic_freemem(struct net_device *dev) ...@@ -898,7 +901,10 @@ static void olympic_freemem(struct net_device *dev)
int i; int i;
for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) { for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]); if (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] != NULL) {
dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] = NULL;
}
if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) { if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
pci_unmap_single(olympic_priv->pdev, pci_unmap_single(olympic_priv->pdev,
le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer), le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
...@@ -944,9 +950,6 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -944,9 +950,6 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
/* Hotswap gives us this on removal */ /* Hotswap gives us this on removal */
if (sisr == 0xffffffff) { if (sisr == 0xffffffff) {
printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ; printk(KERN_WARNING "%s: Hotswap adapter removal.\n",dev->name) ;
olympic_freemem(dev) ;
free_irq(dev->irq, dev) ;
dev->stop = NULL ;
spin_unlock(&olympic_priv->olympic_lock) ; spin_unlock(&olympic_priv->olympic_lock) ;
return IRQ_NONE; return IRQ_NONE;
} }
...@@ -961,9 +964,7 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -961,9 +964,7 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ; printk(KERN_ERR "The adapter must be reset to clear this condition.\n") ;
printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ; printk(KERN_ERR "Please report this error to the driver maintainer and/\n") ;
printk(KERN_ERR "or the linux-tr mailing list.\n") ; printk(KERN_ERR "or the linux-tr mailing list.\n") ;
olympic_freemem(dev) ; wake_up_interruptible(&olympic_priv->srb_wait);
free_irq(dev->irq, dev) ;
dev->stop = NULL ;
spin_unlock(&olympic_priv->olympic_lock) ; spin_unlock(&olympic_priv->olympic_lock) ;
return IRQ_HANDLED; return IRQ_HANDLED;
} /* SISR_ERR */ } /* SISR_ERR */
...@@ -1006,9 +1007,6 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs ...@@ -1006,9 +1007,6 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id, struct pt_regs *regs
writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA); writel(readl(olympic_mmio+LAPWWC),olympic_mmio+LAPA);
adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ; adapter_check_area = olympic_priv->olympic_lap + ((readl(olympic_mmio+LAPWWC)) & (~0xf800)) ;
printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ; printk(KERN_WARNING "%s: Bytes %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",dev->name, readb(adapter_check_area+0), readb(adapter_check_area+1), readb(adapter_check_area+2), readb(adapter_check_area+3), readb(adapter_check_area+4), readb(adapter_check_area+5), readb(adapter_check_area+6), readb(adapter_check_area+7)) ;
olympic_freemem(dev) ;
free_irq(dev->irq, dev) ;
dev->stop = NULL ;
spin_unlock(&olympic_priv->olympic_lock) ; spin_unlock(&olympic_priv->olympic_lock) ;
return IRQ_HANDLED; return IRQ_HANDLED;
} /* SISR_ADAPTER_CHECK */ } /* SISR_ADAPTER_CHECK */
...@@ -1094,34 +1092,32 @@ static int olympic_close(struct net_device *dev) ...@@ -1094,34 +1092,32 @@ static int olympic_close(struct net_device *dev)
writeb(0,srb+1); writeb(0,srb+1);
writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); writeb(OLYMPIC_CLEAR_RET_CODE,srb+2);
add_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_INTERRUPTIBLE) ;
spin_lock_irqsave(&olympic_priv->olympic_lock,flags); spin_lock_irqsave(&olympic_priv->olympic_lock,flags);
olympic_priv->srb_queued=1; olympic_priv->srb_queued=1;
writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM);
spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags); spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
t = jiffies ;
add_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_INTERRUPTIBLE) ;
while(olympic_priv->srb_queued) { while(olympic_priv->srb_queued) {
schedule() ;
t = schedule_timeout(60*HZ);
if(signal_pending(current)) { if(signal_pending(current)) {
printk(KERN_WARNING "%s: SRB timed out.\n",dev->name); printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR)); printk(KERN_WARNING "SISR=%x MISR=%x\n",readl(olympic_mmio+SISR),readl(olympic_mmio+LISR));
olympic_priv->srb_queued=0; olympic_priv->srb_queued=0;
break; break;
} }
if ((jiffies-t) > 60*HZ) {
if (t == 0) {
printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ; printk(KERN_WARNING "%s: SRB timed out. May not be fatal. \n",dev->name) ;
olympic_priv->srb_queued=0;
break ;
} }
set_current_state(TASK_INTERRUPTIBLE) ; olympic_priv->srb_queued=0;
} }
remove_wait_queue(&olympic_priv->srb_wait,&wait) ; remove_wait_queue(&olympic_priv->srb_wait,&wait) ;
set_current_state(TASK_RUNNING) ;
olympic_priv->rx_status_last_received++; olympic_priv->rx_status_last_received++;
olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1; olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
...@@ -1513,29 +1509,6 @@ static void olympic_arb_cmd(struct net_device *dev) ...@@ -1513,29 +1509,6 @@ static void olympic_arb_cmd(struct net_device *dev)
writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL); writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL);
netif_stop_queue(dev); netif_stop_queue(dev);
olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ;
for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) {
dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]);
if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) {
pci_unmap_single(olympic_priv->pdev,
le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer),
olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE);
}
olympic_priv->rx_status_last_received++;
olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1;
}
/* unmap rings */
pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr,
sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE);
pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr,
sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE);
pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr,
sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE);
pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr,
sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE);
free_irq(dev->irq,dev);
dev->stop=NULL;
printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ;
} /* If serious error */ } /* If serious error */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment