in lanai.c [2106:2241]
static int lanai_dev_open(struct atm_dev *atmdev)
{
struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data;
unsigned long raw_base;
int result;
DPRINTK("In lanai_dev_open()\n");
/* Basic device fields */
lanai->number = atmdev->number;
lanai->num_vci = NUM_VCI;
bitmap_zero(lanai->backlog_vccs, NUM_VCI);
bitmap_zero(lanai->transmit_ready, NUM_VCI);
lanai->naal0 = 0;
#ifdef USE_POWERDOWN
lanai->nbound = 0;
#endif
lanai->cbrvcc = NULL;
memset(&lanai->stats, 0, sizeof lanai->stats);
spin_lock_init(&lanai->endtxlock);
spin_lock_init(&lanai->servicelock);
atmdev->ci_range.vpi_bits = 0;
atmdev->ci_range.vci_bits = 0;
while (1 << atmdev->ci_range.vci_bits < lanai->num_vci)
atmdev->ci_range.vci_bits++;
atmdev->link_rate = ATM_25_PCR;
/* 3.2: PCI initialization */
if ((result = lanai_pci_start(lanai)) != 0)
goto error;
raw_base = lanai->pci->resource[0].start;
lanai->base = (bus_addr_t) ioremap(raw_base, LANAI_MAPPING_SIZE);
if (lanai->base == NULL) {
printk(KERN_ERR DEV_LABEL ": couldn't remap I/O space\n");
result = -ENOMEM;
goto error_pci;
}
/* 3.3: Reset lanai and PHY */
reset_board(lanai);
lanai->conf1 = reg_read(lanai, Config1_Reg);
lanai->conf1 &= ~(CONFIG1_GPOUT1 | CONFIG1_POWERDOWN |
CONFIG1_MASK_LEDMODE);
lanai->conf1 |= CONFIG1_SET_LEDMODE(LEDMODE_NOT_SOOL);
reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
udelay(1000);
conf1_write(lanai);
/*
* 3.4: Turn on endian mode for big-endian hardware
* We don't actually want to do this - the actual bit fields
* in the endian register are not documented anywhere.
* Instead we do the bit-flipping ourselves on big-endian
* hardware.
*
* 3.5: get the board ID/rev by reading the reset register
*/
result = check_board_id_and_rev("register",
reg_read(lanai, Reset_Reg), &lanai->board_rev);
if (result != 0)
goto error_unmap;
/* 3.6: read EEPROM */
if ((result = eeprom_read(lanai)) != 0)
goto error_unmap;
if ((result = eeprom_validate(lanai)) != 0)
goto error_unmap;
/* 3.7: re-reset PHY, do loopback tests, setup PHY */
reg_write(lanai, lanai->conf1 | CONFIG1_GPOUT1, Config1_Reg);
udelay(1000);
conf1_write(lanai);
/* TODO - loopback tests */
lanai->conf1 |= (CONFIG1_GPOUT2 | CONFIG1_GPOUT3 | CONFIG1_DMA_ENABLE);
conf1_write(lanai);
/* 3.8/3.9: test and initialize card SRAM */
if ((result = sram_test_and_clear(lanai)) != 0)
goto error_unmap;
/* 3.10: initialize lanai registers */
lanai->conf1 |= CONFIG1_DMA_ENABLE;
conf1_write(lanai);
if ((result = service_buffer_allocate(lanai)) != 0)
goto error_unmap;
if ((result = vcc_table_allocate(lanai)) != 0)
goto error_service;
lanai->conf2 = (lanai->num_vci >= 512 ? CONFIG2_HOWMANY : 0) |
CONFIG2_HEC_DROP | /* ??? */ CONFIG2_PTI7_MODE;
conf2_write(lanai);
reg_write(lanai, TX_FIFO_DEPTH, TxDepth_Reg);
reg_write(lanai, 0, CBR_ICG_Reg); /* CBR defaults to no limit */
if ((result = request_irq(lanai->pci->irq, lanai_int, IRQF_SHARED,
DEV_LABEL, lanai)) != 0) {
printk(KERN_ERR DEV_LABEL ": can't allocate interrupt\n");
goto error_vcctable;
}
mb(); /* Make sure that all that made it */
intr_enable(lanai, INT_ALL & ~(INT_PING | INT_WAKE));
/* 3.11: initialize loop mode (i.e. turn looping off) */
lanai->conf1 = (lanai->conf1 & ~CONFIG1_MASK_LOOPMODE) |
CONFIG1_SET_LOOPMODE(LOOPMODE_NORMAL) |
CONFIG1_GPOUT2 | CONFIG1_GPOUT3;
conf1_write(lanai);
lanai->status = reg_read(lanai, Status_Reg);
/* We're now done initializing this card */
#ifdef USE_POWERDOWN
lanai->conf1 |= CONFIG1_POWERDOWN;
conf1_write(lanai);
#endif
memcpy(atmdev->esi, eeprom_mac(lanai), ESI_LEN);
lanai_timed_poll_start(lanai);
printk(KERN_NOTICE DEV_LABEL "(itf %d): rev.%d, base=%p, irq=%u "
"(%pMF)\n", lanai->number, (int) lanai->pci->revision,
lanai->base, lanai->pci->irq, atmdev->esi);
printk(KERN_NOTICE DEV_LABEL "(itf %d): LANAI%s, serialno=%u(0x%X), "
"board_rev=%d\n", lanai->number,
lanai->type==lanai2 ? "2" : "HB", (unsigned int) lanai->serialno,
(unsigned int) lanai->serialno, lanai->board_rev);
return 0;
error_vcctable:
vcc_table_deallocate(lanai);
error_service:
service_buffer_deallocate(lanai);
error_unmap:
reset_board(lanai);
#ifdef USE_POWERDOWN
lanai->conf1 = reg_read(lanai, Config1_Reg) | CONFIG1_POWERDOWN;
conf1_write(lanai);
#endif
iounmap(lanai->base);
lanai->base = NULL;
error_pci:
pci_disable_device(lanai->pci);
error:
return result;
}