Commit 50f253e8 authored by David S. Miller's avatar David S. Miller

Use dma_addr_t for hblock_dvma.

Make device probe failure more robust.
parent 04dcbd00
...@@ -1611,12 +1611,12 @@ static int happy_meal_init(struct happy_meal *hp, int from_irq) ...@@ -1611,12 +1611,12 @@ static int happy_meal_init(struct happy_meal *hp, int from_irq)
/* Set the RX and TX ring ptrs. */ /* Set the RX and TX ring ptrs. */
HMD(("ring ptrs rxr[%08x] txr[%08x]\n", HMD(("ring ptrs rxr[%08x] txr[%08x]\n",
(hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)), ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)),
(hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)))); ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0))));
hme_write32(hp, erxregs + ERX_RING, hme_write32(hp, erxregs + ERX_RING,
(hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0))); ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_rxd, 0)));
hme_write32(hp, etxregs + ETX_RING, hme_write32(hp, etxregs + ETX_RING,
(hp->hblock_dvma + hblock_offset(happy_meal_txd, 0))); ((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)));
/* Set the supported burst sizes. */ /* Set the supported burst sizes. */
HMD(("happy_meal_init: old[%08x] bursts<", HMD(("happy_meal_init: old[%08x] bursts<",
...@@ -2643,21 +2643,23 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) ...@@ -2643,21 +2643,23 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
struct happy_meal *hp; struct happy_meal *hp;
struct net_device *dev; struct net_device *dev;
int i, qfe_slot = -1; int i, qfe_slot = -1;
int err = -ENODEV;
if (is_qfe) { if (is_qfe) {
qp = quattro_sbus_find(sdev); qp = quattro_sbus_find(sdev);
if (qp == NULL) if (qp == NULL)
return -ENODEV; goto err_out;
for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
if (qp->happy_meals[qfe_slot] == NULL) if (qp->happy_meals[qfe_slot] == NULL)
break; break;
if (qfe_slot == 4) if (qfe_slot == 4)
return -ENODEV; goto err_out;
} }
err = -ENOMEM;
dev = init_etherdev(NULL, sizeof(struct happy_meal)); dev = init_etherdev(NULL, sizeof(struct happy_meal));
if (!dev) if (!dev)
return -ENOMEM; goto err_out;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
if (hme_version_printed++ == 0) if (hme_version_printed++ == 0)
...@@ -2701,11 +2703,12 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) ...@@ -2701,11 +2703,12 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
spin_lock_init(&hp->happy_lock); spin_lock_init(&hp->happy_lock);
err = -ENODEV;
if (sdev->num_registers != 5) { if (sdev->num_registers != 5) {
printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n", printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n",
sdev->num_registers); sdev->num_registers);
printk(KERN_ERR "happymeal: Would you like that for here or to go?\n"); printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
return -ENODEV; goto err_out_free_netdev;
} }
if (qp != NULL) { if (qp != NULL) {
...@@ -2719,35 +2722,35 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) ...@@ -2719,35 +2722,35 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
GREG_REG_SIZE, "HME Global Regs"); GREG_REG_SIZE, "HME Global Regs");
if (!hp->gregs) { if (!hp->gregs) {
printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n"); printk(KERN_ERR "happymeal: Cannot map Happy Meal global registers.\n");
return -ENODEV; goto err_out_free_netdev;
} }
hp->etxregs = sbus_ioremap(&sdev->resource[1], 0, hp->etxregs = sbus_ioremap(&sdev->resource[1], 0,
ETX_REG_SIZE, "HME TX Regs"); ETX_REG_SIZE, "HME TX Regs");
if (!hp->etxregs) { if (!hp->etxregs) {
printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n"); printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Transmit registers.\n");
return -ENODEV; goto err_out_iounmap;
} }
hp->erxregs = sbus_ioremap(&sdev->resource[2], 0, hp->erxregs = sbus_ioremap(&sdev->resource[2], 0,
ERX_REG_SIZE, "HME RX Regs"); ERX_REG_SIZE, "HME RX Regs");
if (!hp->erxregs) { if (!hp->erxregs) {
printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n"); printk(KERN_ERR "happymeal: Cannot map Happy Meal MAC Receive registers.\n");
return -ENODEV; goto err_out_iounmap;
} }
hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0, hp->bigmacregs = sbus_ioremap(&sdev->resource[3], 0,
BMAC_REG_SIZE, "HME BIGMAC Regs"); BMAC_REG_SIZE, "HME BIGMAC Regs");
if (!hp->bigmacregs) { if (!hp->bigmacregs) {
printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n"); printk(KERN_ERR "happymeal: Cannot map Happy Meal BIGMAC registers.\n");
return -ENODEV; goto err_out_iounmap;
} }
hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0, hp->tcvregs = sbus_ioremap(&sdev->resource[4], 0,
TCVR_REG_SIZE, "HME Tranceiver Regs"); TCVR_REG_SIZE, "HME Tranceiver Regs");
if (!hp->tcvregs) { if (!hp->tcvregs) {
printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n"); printk(KERN_ERR "happymeal: Cannot map Happy Meal Tranceiver registers.\n");
return -ENODEV; goto err_out_iounmap;
} }
hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff); hp->hm_revision = prom_getintdefault(sdev->prom_node, "hm-rev", 0xff);
...@@ -2770,6 +2773,11 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) ...@@ -2770,6 +2773,11 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
hp->happy_block = sbus_alloc_consistent(hp->happy_dev, hp->happy_block = sbus_alloc_consistent(hp->happy_dev,
PAGE_SIZE, PAGE_SIZE,
&hp->hblock_dvma); &hp->hblock_dvma);
err = -ENOMEM;
if (!hp->happy_block) {
printk(KERN_ERR "happymeal: Cannot allocate descriptors.\n");
goto err_out_iounmap;
}
/* Force check of the link first time we are brought up. */ /* Force check of the link first time we are brought up. */
hp->linkcheck = 0; hp->linkcheck = 0;
...@@ -2822,6 +2830,25 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe) ...@@ -2822,6 +2830,25 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
root_happy_dev = hp; root_happy_dev = hp;
return 0; return 0;
err_out_iounmap:
if (hp->gregs)
sbus_iounmap(hp->gregs, GREG_REG_SIZE);
if (hp->etxregs)
sbus_iounmap(hp->etxregs, ETX_REG_SIZE);
if (hp->erxregs)
sbus_iounmap(hp->erxregs, ERX_REG_SIZE);
if (hp->bigmacregs)
sbus_iounmap(hp->bigmacregs, BMAC_REG_SIZE);
if (hp->tcvregs)
sbus_iounmap(hp->tcvregs, TCVR_REG_SIZE);
err_out_free_netdev:
unregister_netdev(dev);
kfree(dev);
err_out:
return err;
} }
#endif #endif
...@@ -2838,6 +2865,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) ...@@ -2838,6 +2865,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
unsigned long hpreg_base; unsigned long hpreg_base;
int i, qfe_slot = -1; int i, qfe_slot = -1;
char prom_name[64]; char prom_name[64];
int err;
/* Now make sure pci_dev cookie is there. */ /* Now make sure pci_dev cookie is there. */
#ifdef __sparc__ #ifdef __sparc__
...@@ -2854,20 +2882,22 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) ...@@ -2854,20 +2882,22 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
strcpy(prom_name, "qfe"); strcpy(prom_name, "qfe");
#endif #endif
err = -ENODEV;
if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) { if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
qp = quattro_pci_find(pdev); qp = quattro_pci_find(pdev);
if (qp == NULL) if (qp == NULL)
return -ENODEV; goto err_out;
for (qfe_slot = 0; qfe_slot < 4; qfe_slot++) for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
if (qp->happy_meals[qfe_slot] == NULL) if (qp->happy_meals[qfe_slot] == NULL)
break; break;
if (qfe_slot == 4) if (qfe_slot == 4)
return -ENODEV; goto err_out;
} }
dev = init_etherdev(NULL, sizeof(struct happy_meal)); dev = init_etherdev(NULL, sizeof(struct happy_meal));
err = -ENOMEM;
if (!dev) if (!dev)
return -ENOMEM; goto err_out;
SET_MODULE_OWNER(dev); SET_MODULE_OWNER(dev);
if (hme_version_printed++ == 0) if (hme_version_printed++ == 0)
...@@ -2912,9 +2942,10 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) ...@@ -2912,9 +2942,10 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
} }
hpreg_base = pci_resource_start(pdev, 0); hpreg_base = pci_resource_start(pdev, 0);
err = -ENODEV;
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) { if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n"); printk(KERN_ERR "happymeal(PCI): Cannot find proper PCI device base address.\n");
return -ENODEV; goto err_out_clear_quattro;
} }
if ((hpreg_base = (unsigned long) ioremap(hpreg_base, 0x8000)) == 0) { if ((hpreg_base = (unsigned long) ioremap(hpreg_base, 0x8000)) == 0) {
printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n"); printk(KERN_ERR "happymeal(PCI): Unable to remap card memory.\n");
...@@ -2983,9 +3014,10 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) ...@@ -2983,9 +3014,10 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
hp->happy_block = (struct hmeal_init_block *) hp->happy_block = (struct hmeal_init_block *)
pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma); pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma);
err = -ENODEV;
if (!hp->happy_block) { if (!hp->happy_block) {
printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n"); printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n");
return -ENODEV; goto err_out_iounmap;
} }
hp->linkcheck = 0; hp->linkcheck = 0;
...@@ -3034,6 +3066,19 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev) ...@@ -3034,6 +3066,19 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
root_happy_dev = hp; root_happy_dev = hp;
return 0; return 0;
err_out_iounmap:
iounmap((void *)hp->gregs);
err_out_clear_quattro:
if (qp != NULL)
qp->happy_meals[qfe_slot] = NULL;
unregister_netdev(dev);
kfree(dev);
err_out:
return err;
} }
#endif #endif
......
...@@ -431,7 +431,7 @@ struct happy_meal { ...@@ -431,7 +431,7 @@ struct happy_meal {
unsigned long bigmacregs; /* BIGMAC core regs */ unsigned long bigmacregs; /* BIGMAC core regs */
unsigned long tcvregs; /* MIF transceiver regs */ unsigned long tcvregs; /* MIF transceiver regs */
__u32 hblock_dvma; /* DVMA visible address happy block */ dma_addr_t hblock_dvma; /* DVMA visible address happy block */
unsigned int happy_flags; /* Driver state flags */ unsigned int happy_flags; /* Driver state flags */
enum happy_transceiver tcvr_type; /* Kind of transceiver in use */ enum happy_transceiver tcvr_type; /* Kind of transceiver in use */
unsigned int happy_bursts; /* Get your mind out of the gutter */ unsigned int happy_bursts; /* Get your mind out of the gutter */
......
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