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)
/* Set the RX and TX ring ptrs. */
HMD(("ring ptrs rxr[%08x] txr[%08x]\n",
(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_rxd, 0)),
((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0))));
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,
(hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)));
((__u32)hp->hblock_dvma + hblock_offset(happy_meal_txd, 0)));
/* Set the supported burst sizes. */
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)
struct happy_meal *hp;
struct net_device *dev;
int i, qfe_slot = -1;
int err = -ENODEV;
if (is_qfe) {
qp = quattro_sbus_find(sdev);
if (qp == NULL)
return -ENODEV;
goto err_out;
for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
if (qp->happy_meals[qfe_slot] == NULL)
break;
if (qfe_slot == 4)
return -ENODEV;
goto err_out;
}
err = -ENOMEM;
dev = init_etherdev(NULL, sizeof(struct happy_meal));
if (!dev)
return -ENOMEM;
goto err_out;
SET_MODULE_OWNER(dev);
if (hme_version_printed++ == 0)
......@@ -2701,11 +2703,12 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
spin_lock_init(&hp->happy_lock);
err = -ENODEV;
if (sdev->num_registers != 5) {
printk(KERN_ERR "happymeal: Device does not have 5 regs, it has %d.\n",
sdev->num_registers);
printk(KERN_ERR "happymeal: Would you like that for here or to go?\n");
return -ENODEV;
goto err_out_free_netdev;
}
if (qp != NULL) {
......@@ -2719,35 +2722,35 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
GREG_REG_SIZE, "HME Global Regs");
if (!hp->gregs) {
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,
ETX_REG_SIZE, "HME TX Regs");
if (!hp->etxregs) {
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,
ERX_REG_SIZE, "HME RX Regs");
if (!hp->erxregs) {
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,
BMAC_REG_SIZE, "HME BIGMAC Regs");
if (!hp->bigmacregs) {
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,
TCVR_REG_SIZE, "HME Tranceiver Regs");
if (!hp->tcvregs) {
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);
......@@ -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,
PAGE_SIZE,
&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. */
hp->linkcheck = 0;
......@@ -2822,6 +2830,25 @@ static int __init happy_meal_sbus_init(struct sbus_dev *sdev, int is_qfe)
root_happy_dev = hp;
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
......@@ -2838,6 +2865,7 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
unsigned long hpreg_base;
int i, qfe_slot = -1;
char prom_name[64];
int err;
/* Now make sure pci_dev cookie is there. */
#ifdef __sparc__
......@@ -2854,20 +2882,22 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
strcpy(prom_name, "qfe");
#endif
err = -ENODEV;
if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
qp = quattro_pci_find(pdev);
if (qp == NULL)
return -ENODEV;
goto err_out;
for (qfe_slot = 0; qfe_slot < 4; qfe_slot++)
if (qp->happy_meals[qfe_slot] == NULL)
break;
if (qfe_slot == 4)
return -ENODEV;
goto err_out;
}
dev = init_etherdev(NULL, sizeof(struct happy_meal));
err = -ENOMEM;
if (!dev)
return -ENOMEM;
goto err_out;
SET_MODULE_OWNER(dev);
if (hme_version_printed++ == 0)
......@@ -2912,9 +2942,10 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
}
hpreg_base = pci_resource_start(pdev, 0);
err = -ENODEV;
if ((pci_resource_flags(pdev, 0) & IORESOURCE_IO) != 0) {
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) {
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)
hp->happy_block = (struct hmeal_init_block *)
pci_alloc_consistent(pdev, PAGE_SIZE, &hp->hblock_dvma);
err = -ENODEV;
if (!hp->happy_block) {
printk(KERN_ERR "happymeal(PCI): Cannot get hme init block.\n");
return -ENODEV;
goto err_out_iounmap;
}
hp->linkcheck = 0;
......@@ -3034,6 +3066,19 @@ static int __init happy_meal_pci_init(struct pci_dev *pdev)
root_happy_dev = hp;
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
......
......@@ -431,7 +431,7 @@ struct happy_meal {
unsigned long bigmacregs; /* BIGMAC core 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 */
enum happy_transceiver tcvr_type; /* Kind of transceiver in use */
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