diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/atm/zatm.c | 107 | ||||
-rw-r--r-- | drivers/atm/zatm.h | 1 |
2 files changed, 62 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 | ||
1258 | static int __init zatm_start(struct atm_dev *dev) | 1258 | static 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; | 1347 | done: |
1340 | out: | 1348 | return error; |
1341 | for (i = 0; i < NR_MBX; i++) | 1349 | |
1342 | kfree(&zatm_dev->mbx_start[i]); | 1350 | out_rx: |
1343 | kfree(zatm_dev->rx_map); | 1351 | kfree(zatm_dev->rx_map); |
1352 | out_tx: | ||
1344 | kfree(zatm_dev->tx_map); | 1353 | kfree(zatm_dev->tx_map); |
1354 | out: | ||
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 | ||
diff --git a/drivers/atm/zatm.h b/drivers/atm/zatm.h index 34a0480f63d6..416fe0fda60c 100644 --- a/drivers/atm/zatm.h +++ b/drivers/atm/zatm.h | |||
@@ -73,6 +73,7 @@ struct zatm_dev { | |||
73 | int chans; /* map size, must be 2^n */ | 73 | int chans; /* map size, must be 2^n */ |
74 | /*-------------------------------- mailboxes */ | 74 | /*-------------------------------- mailboxes */ |
75 | unsigned long mbx_start[NR_MBX];/* start addresses */ | 75 | unsigned long mbx_start[NR_MBX];/* start addresses */ |
76 | dma_addr_t mbx_dma[NR_MBX]; | ||
76 | u16 mbx_end[NR_MBX]; /* end offset (in bytes) */ | 77 | u16 mbx_end[NR_MBX]; /* end offset (in bytes) */ |
77 | /*-------------------------------- other pointers */ | 78 | /*-------------------------------- other pointers */ |
78 | u32 pool_base; /* Free buffer pool dsc (word addr) */ | 79 | u32 pool_base; /* Free buffer pool dsc (word addr) */ |