|
@@ -414,7 +414,7 @@ static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data)
|
|
|
* ================
|
|
|
*
|
|
|
* Overview:
|
|
|
- * Retrieves the address range used to access control and status
|
|
|
+ * Retrieves the address ranges used to access control and status
|
|
|
* registers.
|
|
|
*
|
|
|
* Returns:
|
|
@@ -422,8 +422,8 @@ static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data)
|
|
|
*
|
|
|
* Arguments:
|
|
|
* bdev - pointer to device information
|
|
|
- * bar_start - pointer to store the start address
|
|
|
- * bar_len - pointer to store the length of the area
|
|
|
+ * bar_start - pointer to store the start addresses
|
|
|
+ * bar_len - pointer to store the lengths of the areas
|
|
|
*
|
|
|
* Assumptions:
|
|
|
* I am sure there are some.
|
|
@@ -442,8 +442,10 @@ static void dfx_get_bars(struct device *bdev,
|
|
|
if (dfx_bus_pci) {
|
|
|
int num = dfx_use_mmio ? 0 : 1;
|
|
|
|
|
|
- *bar_start = pci_resource_start(to_pci_dev(bdev), num);
|
|
|
- *bar_len = pci_resource_len(to_pci_dev(bdev), num);
|
|
|
+ bar_start[0] = pci_resource_start(to_pci_dev(bdev), num);
|
|
|
+ bar_len[0] = pci_resource_len(to_pci_dev(bdev), num);
|
|
|
+ bar_start[2] = bar_start[1] = 0;
|
|
|
+ bar_len[2] = bar_len[1] = 0;
|
|
|
}
|
|
|
if (dfx_bus_eisa) {
|
|
|
unsigned long base_addr = to_eisa_device(bdev)->base_addr;
|
|
@@ -457,24 +459,30 @@ static void dfx_get_bars(struct device *bdev,
|
|
|
bar_lo <<= 8;
|
|
|
bar_lo |= inb(base_addr + PI_ESIC_K_MEM_ADD_LO_CMP_0);
|
|
|
bar_lo <<= 8;
|
|
|
- *bar_start = bar_lo;
|
|
|
+ bar_start[0] = bar_lo;
|
|
|
bar_hi = inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_2);
|
|
|
bar_hi <<= 8;
|
|
|
bar_hi |= inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_1);
|
|
|
bar_hi <<= 8;
|
|
|
bar_hi |= inb(base_addr + PI_ESIC_K_MEM_ADD_HI_CMP_0);
|
|
|
bar_hi <<= 8;
|
|
|
- *bar_len = ((bar_hi - bar_lo) | PI_MEM_ADD_MASK_M) + 1;
|
|
|
+ bar_len[0] = ((bar_hi - bar_lo) | PI_MEM_ADD_MASK_M) +
|
|
|
+ 1;
|
|
|
} else {
|
|
|
- *bar_start = base_addr;
|
|
|
- *bar_len = PI_ESIC_K_CSR_IO_LEN +
|
|
|
- PI_ESIC_K_BURST_HOLDOFF_LEN;
|
|
|
+ bar_start[0] = base_addr;
|
|
|
+ bar_len[0] = PI_ESIC_K_CSR_IO_LEN;
|
|
|
}
|
|
|
+ bar_start[1] = base_addr + PI_DEFEA_K_BURST_HOLDOFF;
|
|
|
+ bar_len[1] = PI_ESIC_K_BURST_HOLDOFF_LEN;
|
|
|
+ bar_start[2] = base_addr + PI_ESIC_K_ESIC_CSR;
|
|
|
+ bar_len[2] = PI_ESIC_K_ESIC_CSR_LEN;
|
|
|
}
|
|
|
if (dfx_bus_tc) {
|
|
|
- *bar_start = to_tc_dev(bdev)->resource.start +
|
|
|
- PI_TC_K_CSR_OFFSET;
|
|
|
- *bar_len = PI_TC_K_CSR_LEN;
|
|
|
+ bar_start[0] = to_tc_dev(bdev)->resource.start +
|
|
|
+ PI_TC_K_CSR_OFFSET;
|
|
|
+ bar_len[0] = PI_TC_K_CSR_LEN;
|
|
|
+ bar_start[2] = bar_start[1] = 0;
|
|
|
+ bar_len[2] = bar_len[1] = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -525,8 +533,8 @@ static int dfx_register(struct device *bdev)
|
|
|
const char *print_name = dev_name(bdev);
|
|
|
struct net_device *dev;
|
|
|
DFX_board_t *bp; /* board pointer */
|
|
|
- resource_size_t bar_start = 0; /* pointer to port */
|
|
|
- resource_size_t bar_len = 0; /* resource length */
|
|
|
+ resource_size_t bar_start[3]; /* pointers to ports */
|
|
|
+ resource_size_t bar_len[3]; /* resource length */
|
|
|
int alloc_size; /* total buffer size used */
|
|
|
struct resource *region;
|
|
|
int err = 0;
|
|
@@ -559,8 +567,8 @@ static int dfx_register(struct device *bdev)
|
|
|
bp->bus_dev = bdev;
|
|
|
dev_set_drvdata(bdev, dev);
|
|
|
|
|
|
- dfx_get_bars(bdev, &bar_start, &bar_len);
|
|
|
- if (dfx_bus_eisa && dfx_use_mmio && bar_start == 0) {
|
|
|
+ dfx_get_bars(bdev, bar_start, bar_len);
|
|
|
+ if (dfx_bus_eisa && dfx_use_mmio && bar_start[0] == 0) {
|
|
|
pr_err("%s: Cannot use MMIO, no address set, aborting\n",
|
|
|
print_name);
|
|
|
pr_err("%s: Run ECU and set adapter's MMIO location\n",
|
|
@@ -572,28 +580,49 @@ static int dfx_register(struct device *bdev)
|
|
|
}
|
|
|
|
|
|
if (dfx_use_mmio)
|
|
|
- region = request_mem_region(bar_start, bar_len, print_name);
|
|
|
+ region = request_mem_region(bar_start[0], bar_len[0],
|
|
|
+ print_name);
|
|
|
else
|
|
|
- region = request_region(bar_start, bar_len, print_name);
|
|
|
+ region = request_region(bar_start[0], bar_len[0], print_name);
|
|
|
if (!region) {
|
|
|
- printk(KERN_ERR "%s: Cannot reserve I/O resource "
|
|
|
- "0x%lx @ 0x%lx, aborting\n",
|
|
|
- print_name, (long)bar_len, (long)bar_start);
|
|
|
+ pr_err("%s: Cannot reserve %s resource 0x%lx @ 0x%lx, "
|
|
|
+ "aborting\n", dfx_use_mmio ? "MMIO" : "I/O", print_name,
|
|
|
+ (long)bar_len[0], (long)bar_start[0]);
|
|
|
err = -EBUSY;
|
|
|
goto err_out_disable;
|
|
|
}
|
|
|
+ if (bar_start[1] != 0) {
|
|
|
+ region = request_region(bar_start[1], bar_len[1], print_name);
|
|
|
+ if (!region) {
|
|
|
+ pr_err("%s: Cannot reserve I/O resource "
|
|
|
+ "0x%lx @ 0x%lx, aborting\n", print_name,
|
|
|
+ (long)bar_len[1], (long)bar_start[1]);
|
|
|
+ err = -EBUSY;
|
|
|
+ goto err_out_csr_region;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (bar_start[2] != 0) {
|
|
|
+ region = request_region(bar_start[2], bar_len[2], print_name);
|
|
|
+ if (!region) {
|
|
|
+ pr_err("%s: Cannot reserve I/O resource "
|
|
|
+ "0x%lx @ 0x%lx, aborting\n", print_name,
|
|
|
+ (long)bar_len[2], (long)bar_start[2]);
|
|
|
+ err = -EBUSY;
|
|
|
+ goto err_out_bh_region;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/* Set up I/O base address. */
|
|
|
if (dfx_use_mmio) {
|
|
|
- bp->base.mem = ioremap_nocache(bar_start, bar_len);
|
|
|
+ bp->base.mem = ioremap_nocache(bar_start[0], bar_len[0]);
|
|
|
if (!bp->base.mem) {
|
|
|
printk(KERN_ERR "%s: Cannot map MMIO\n", print_name);
|
|
|
err = -ENOMEM;
|
|
|
- goto err_out_region;
|
|
|
+ goto err_out_esic_region;
|
|
|
}
|
|
|
} else {
|
|
|
- bp->base.port = bar_start;
|
|
|
- dev->base_addr = bar_start;
|
|
|
+ bp->base.port = bar_start[0];
|
|
|
+ dev->base_addr = bar_start[0];
|
|
|
}
|
|
|
|
|
|
/* Initialize new device structure */
|
|
@@ -602,7 +631,7 @@ static int dfx_register(struct device *bdev)
|
|
|
if (dfx_bus_pci)
|
|
|
pci_set_master(to_pci_dev(bdev));
|
|
|
|
|
|
- if (dfx_driver_init(dev, print_name, bar_start) != DFX_K_SUCCESS) {
|
|
|
+ if (dfx_driver_init(dev, print_name, bar_start[0]) != DFX_K_SUCCESS) {
|
|
|
err = -ENODEV;
|
|
|
goto err_out_unmap;
|
|
|
}
|
|
@@ -630,11 +659,19 @@ err_out_unmap:
|
|
|
if (dfx_use_mmio)
|
|
|
iounmap(bp->base.mem);
|
|
|
|
|
|
-err_out_region:
|
|
|
+err_out_esic_region:
|
|
|
+ if (bar_start[2] != 0)
|
|
|
+ release_region(bar_start[2], bar_len[2]);
|
|
|
+
|
|
|
+err_out_bh_region:
|
|
|
+ if (bar_start[1] != 0)
|
|
|
+ release_region(bar_start[1], bar_len[1]);
|
|
|
+
|
|
|
+err_out_csr_region:
|
|
|
if (dfx_use_mmio)
|
|
|
- release_mem_region(bar_start, bar_len);
|
|
|
+ release_mem_region(bar_start[0], bar_len[0]);
|
|
|
else
|
|
|
- release_region(bar_start, bar_len);
|
|
|
+ release_region(bar_start[0], bar_len[0]);
|
|
|
|
|
|
err_out_disable:
|
|
|
if (dfx_bus_pci)
|
|
@@ -1085,8 +1122,8 @@ static int dfx_driver_init(struct net_device *dev, const char *print_name,
|
|
|
board_name = "DEFEA";
|
|
|
if (dfx_bus_pci)
|
|
|
board_name = "DEFPA";
|
|
|
- pr_info("%s: %s at %saddr = 0x%llx, IRQ = %d, Hardware addr = %pMF\n",
|
|
|
- print_name, board_name, dfx_use_mmio ? "" : "I/O ",
|
|
|
+ pr_info("%s: %s at %s addr = 0x%llx, IRQ = %d, Hardware addr = %pMF\n",
|
|
|
+ print_name, board_name, dfx_use_mmio ? "MMIO" : "I/O",
|
|
|
(long long)bar_start, dev->irq, dev->dev_addr);
|
|
|
|
|
|
/*
|
|
@@ -3660,8 +3697,8 @@ static void dfx_unregister(struct device *bdev)
|
|
|
int dfx_bus_pci = dev_is_pci(bdev);
|
|
|
int dfx_bus_tc = DFX_BUS_TC(bdev);
|
|
|
int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
|
|
|
- resource_size_t bar_start = 0; /* pointer to port */
|
|
|
- resource_size_t bar_len = 0; /* resource length */
|
|
|
+ resource_size_t bar_start[3]; /* pointers to ports */
|
|
|
+ resource_size_t bar_len[3]; /* resource lengths */
|
|
|
int alloc_size; /* total buffer size used */
|
|
|
|
|
|
unregister_netdev(dev);
|
|
@@ -3679,12 +3716,16 @@ static void dfx_unregister(struct device *bdev)
|
|
|
|
|
|
dfx_bus_uninit(dev);
|
|
|
|
|
|
- dfx_get_bars(bdev, &bar_start, &bar_len);
|
|
|
+ dfx_get_bars(bdev, bar_start, bar_len);
|
|
|
+ if (bar_start[2] != 0)
|
|
|
+ release_region(bar_start[2], bar_len[2]);
|
|
|
+ if (bar_start[1] != 0)
|
|
|
+ release_region(bar_start[1], bar_len[1]);
|
|
|
if (dfx_use_mmio) {
|
|
|
iounmap(bp->base.mem);
|
|
|
- release_mem_region(bar_start, bar_len);
|
|
|
+ release_mem_region(bar_start[0], bar_len[0]);
|
|
|
} else
|
|
|
- release_region(bar_start, bar_len);
|
|
|
+ release_region(bar_start[0], bar_len[0]);
|
|
|
|
|
|
if (dfx_bus_pci)
|
|
|
pci_disable_device(to_pci_dev(bdev));
|