aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/atm/zatm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/atm/zatm.c')
-rw-r--r--drivers/atm/zatm.c107
1 files changed, 61 insertions, 46 deletions
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c
index afcf1ada5547..a2b236a966e0 100644
--- a/drivers/atm/zatm.c
+++ b/drivers/atm/zatm.c
@@ -16,9 +16,9 @@
16#include <linux/skbuff.h> 16#include <linux/skbuff.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/ioport.h> /* for request_region */
20#include <linux/uio.h> 19#include <linux/uio.h>
21#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/dma-mapping.h>
22#include <linux/atm_zatm.h> 22#include <linux/atm_zatm.h>
23#include <linux/capability.h> 23#include <linux/capability.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
@@ -1257,22 +1257,22 @@ static int __init zatm_init(struct atm_dev *dev)
1257 1257
1258static int __init zatm_start(struct atm_dev *dev) 1258static int __init zatm_start(struct atm_dev *dev)
1259{ 1259{
1260 struct zatm_dev *zatm_dev; 1260 struct zatm_dev *zatm_dev = ZATM_DEV(dev);
1261 struct pci_dev *pdev = zatm_dev->pci_dev;
1261 unsigned long curr; 1262 unsigned long curr;
1262 int pools,vccs,rx; 1263 int pools,vccs,rx;
1263 int error,i,ld; 1264 int error, i, ld;
1264 1265
1265 DPRINTK("zatm_start\n"); 1266 DPRINTK("zatm_start\n");
1266 zatm_dev = ZATM_DEV(dev);
1267 zatm_dev->rx_map = zatm_dev->tx_map = NULL; 1267 zatm_dev->rx_map = zatm_dev->tx_map = NULL;
1268 for (i = 0; i < NR_MBX; i++) 1268 for (i = 0; i < NR_MBX; i++)
1269 zatm_dev->mbx_start[i] = 0; 1269 zatm_dev->mbx_start[i] = 0;
1270 if (request_irq(zatm_dev->irq,&zatm_int,SA_SHIRQ,DEV_LABEL,dev)) { 1270 error = request_irq(zatm_dev->irq, zatm_int, SA_SHIRQ, DEV_LABEL, dev);
1271 printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n", 1271 if (error < 0) {
1272 dev->number,zatm_dev->irq); 1272 printk(KERN_ERR DEV_LABEL "(itf %d): IRQ%d is already in use\n",
1273 return -EAGAIN; 1273 dev->number,zatm_dev->irq);
1274 goto done;
1274 } 1275 }
1275 request_region(zatm_dev->base,uPD98401_PORTS,DEV_LABEL);
1276 /* define memory regions */ 1276 /* define memory regions */
1277 pools = NR_POOLS; 1277 pools = NR_POOLS;
1278 if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE) 1278 if (NR_SHAPERS*SHAPER_SIZE > pools*POOL_SIZE)
@@ -1299,51 +1299,66 @@ static int __init zatm_start(struct atm_dev *dev)
1299 "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx, 1299 "%ld VCs\n",dev->number,NR_SHAPERS,pools,rx,
1300 (zatm_dev->mem-curr*4)/VC_SIZE); 1300 (zatm_dev->mem-curr*4)/VC_SIZE);
1301 /* create mailboxes */ 1301 /* create mailboxes */
1302 for (i = 0; i < NR_MBX; i++) 1302 for (i = 0; i < NR_MBX; i++) {
1303 if (mbx_entries[i]) { 1303 void *mbx;
1304 unsigned long here; 1304 dma_addr_t mbx_dma;
1305 1305
1306 here = (unsigned long) kmalloc(2*MBX_SIZE(i), 1306 if (!mbx_entries[i])
1307 GFP_KERNEL); 1307 continue;
1308 if (!here) { 1308 mbx = pci_alloc_consistent(pdev, 2*MBX_SIZE(i), &mbx_dma);
1309 error = -ENOMEM; 1309 if (!mbx) {
1310 goto out; 1310 error = -ENOMEM;
1311 } 1311 goto out;
1312 if ((here^(here+MBX_SIZE(i))) & ~0xffffUL)/* paranoia */
1313 here = (here & ~0xffffUL)+0x10000;
1314 zatm_dev->mbx_start[i] = here;
1315 if ((here^virt_to_bus((void *) here)) & 0xffff) {
1316 printk(KERN_ERR DEV_LABEL "(itf %d): system "
1317 "bus incompatible with driver\n",
1318 dev->number);
1319 error = -ENODEV;
1320 goto out;
1321 }
1322 DPRINTK("mbx@0x%08lx-0x%08lx\n",here,here+MBX_SIZE(i));
1323 zatm_dev->mbx_end[i] = (here+MBX_SIZE(i)) & 0xffff;
1324 zout(virt_to_bus((void *) here) >> 16,MSH(i));
1325 zout(virt_to_bus((void *) here),MSL(i));
1326 zout((here+MBX_SIZE(i)) & 0xffff,MBA(i));
1327 zout(here & 0xffff,MTA(i));
1328 zout(here & 0xffff,MWA(i));
1329 } 1312 }
1313 /*
1314 * Alignment provided by pci_alloc_consistent() isn't enough
1315 * for this device.
1316 */
1317 if (((unsigned long)mbx ^ mbx_dma) & 0xffff) {
1318 printk(KERN_ERR DEV_LABEL "(itf %d): system "
1319 "bus incompatible with driver\n", dev->number);
1320 pci_free_consistent(pdev, 2*MBX_SIZE(i), mbx, mbx_dma);
1321 error = -ENODEV;
1322 goto out;
1323 }
1324 DPRINTK("mbx@0x%08lx-0x%08lx\n", mbx, mbx + MBX_SIZE(i));
1325 zatm_dev->mbx_start[i] = (unsigned long)mbx;
1326 zatm_dev->mbx_dma[i] = mbx_dma;
1327 zatm_dev->mbx_end[i] = (zatm_dev->mbx_start[i] + MBX_SIZE(i)) &
1328 0xffff;
1329 zout(mbx_dma >> 16, MSH(i));
1330 zout(mbx_dma, MSL(i));
1331 zout(zatm_dev->mbx_end[i], MBA(i));
1332 zout((unsigned long)mbx & 0xffff, MTA(i));
1333 zout((unsigned long)mbx & 0xffff, MWA(i));
1334 }
1330 error = start_tx(dev); 1335 error = start_tx(dev);
1331 if (error) goto out; 1336 if (error)
1337 goto out;
1332 error = start_rx(dev); 1338 error = start_rx(dev);
1333 if (error) goto out; 1339 if (error)
1340 goto out_tx;
1334 error = dev->phy->start(dev); 1341 error = dev->phy->start(dev);
1335 if (error) goto out; 1342 if (error)
1343 goto out_rx;
1336 zout(0xffffffff,IMR); /* enable interrupts */ 1344 zout(0xffffffff,IMR); /* enable interrupts */
1337 /* enable TX & RX */ 1345 /* enable TX & RX */
1338 zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR); 1346 zout(zin(GMR) | uPD98401_GMR_SE | uPD98401_GMR_RE,GMR);
1339 return 0; 1347done:
1340 out: 1348 return error;
1341 for (i = 0; i < NR_MBX; i++) 1349
1342 kfree(&zatm_dev->mbx_start[i]); 1350out_rx:
1343 kfree(zatm_dev->rx_map); 1351 kfree(zatm_dev->rx_map);
1352out_tx:
1344 kfree(zatm_dev->tx_map); 1353 kfree(zatm_dev->tx_map);
1354out:
1355 while (i-- > 0) {
1356 pci_free_consistent(pdev, 2*MBX_SIZE(i),
1357 (void *)zatm_dev->mbx_start[i],
1358 zatm_dev->mbx_dma[i]);
1359 }
1345 free_irq(zatm_dev->irq, dev); 1360 free_irq(zatm_dev->irq, dev);
1346 return error; 1361 goto done;
1347} 1362}
1348 1363
1349 1364