int san_dev_attach(void *hw, u_int8_t *devname, int namelen) { sdla_t *card; wanpipe_common_t *common = NULL; int err = 0; card=malloc(sizeof(sdla_t), M_DEVBUF, M_NOWAIT); if (!card) { log(LOG_INFO, "%s: Failed allocate new card!\n", san_drvname); return (EINVAL); } bzero(card, sizeof(sdla_t)); card->magic = WANPIPE_MAGIC; wanpipe_generic_name(card, card->devname, sizeof(card->devname)); strlcpy(devname, card->devname, namelen); card->hw = hw; LIST_INIT(&card->dev_head); sdla_getcfg(card->hw, SDLA_CARDTYPE, &card->type); if (sdla_is_te1(card->hw)) sdla_te_defcfg(&card->fe_te.te_cfg); err = sdla_setup(card->hw); if (err) { log(LOG_INFO, "%s: Hardware setup Failed %d\n", card->devname,err); return (EINVAL); } err = sdla_intr_establish(card->hw, sdla_isr, (void*)card); if (err) { log(LOG_INFO, "%s: Failed set interrupt handler!\n", card->devname); sdla_down(card->hw); return (EINVAL); } switch (card->type) { case SDLA_AFT: #if defined(DEBUG_INIT) log(LOG_INFO, "%s: Starting AFT Hardware Init.\n", card->devname); #endif common = wan_xilinx_init(card); break; } if (common == NULL) { release_hw(card); card->configured = 0; return (EINVAL); } LIST_INSERT_HEAD(&card->dev_head, common, next); /* Reserve I/O region and schedule background task */ card->critical = 0; card->state = WAN_DISCONNECTED; card->ioctl = wan_ioctl; return (0); }
static void release_hw(sdla_t *card) { log(LOG_INFO, "%s: Master shutting down\n",card->devname); sdla_down(card->hw); sdla_intr_disestablish(card->hw); card->configured = 0; return; }
int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len) { unsigned* irq_opt = NULL; /* IRQ options */ unsigned* dpmbase_opt = NULL; /* DPM window base options */ unsigned* pclk_opt = NULL; /* CPU clock rate options */ int err; if (sdla_detect(hw)) { printk(KERN_ERR "%s: adapter S%04u not found at port 0x%X!\n", modname, hw->type, hw->port) ; return -EINVAL; } printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n", modname, hw->type, hw->port) ; hw->dpmsize = SDLA_WINDOWSIZE; switch (hw->type) { case SDLA_S502A: hw->io_range = S502A_IORANGE; irq_opt = s502a_irq_options; dpmbase_opt = s502a_dpmbase_options; pclk_opt = s502a_pclk_options; break; case SDLA_S502E: hw->io_range = S502E_IORANGE; irq_opt = s502e_irq_options; dpmbase_opt = s508_dpmbase_options; pclk_opt = s502e_pclk_options; break; case SDLA_S503: hw->io_range = S503_IORANGE; irq_opt = s503_irq_options; dpmbase_opt = s508_dpmbase_options; pclk_opt = s503_pclk_options; break; case SDLA_S507: hw->io_range = S507_IORANGE; irq_opt = s508_irq_options; dpmbase_opt = s507_dpmbase_options; pclk_opt = s507_pclk_options; break; case SDLA_S508: hw->io_range = S508_IORANGE; irq_opt = s508_irq_options; dpmbase_opt = s508_dpmbase_options; pclk_opt = s508_pclk_options; break; } /* Verify IRQ configuration options */ if (!get_option_index(irq_opt, hw->irq)) { printk(KERN_ERR "%s: IRQ %d is illegal!\n", modname, hw->irq) ; return -EINVAL; } /* Verify CPU clock rate configuration options */ if (hw->pclk == 0) hw->pclk = pclk_opt[1] /* use default */ ; else if (!get_option_index(pclk_opt, hw->pclk)) { printk(KERN_ERR "%s: CPU clock %u is illegal!\n", modname, hw->pclk) ; return -EINVAL; } printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n", modname, hw->pclk) ; /* Setup adapter dual-port memory window and test memory */ if (hw->dpmbase == 0) { err = sdla_autodpm(hw); if (err) { printk(KERN_ERR "%s: can't find available memory region!\n", modname) ; return err; } } else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase))) { printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n", modname, virt_to_phys(hw->dpmbase)) ; return -EINVAL; } else if (sdla_setdpm(hw)) { printk(KERN_ERR "%s: 8K memory region at 0x%lX is not available!\n", modname, virt_to_phys(hw->dpmbase)); return -EINVAL; } printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n", modname, virt_to_phys(hw->dpmbase)); printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n", modname, hw->memory / 1024); /* Load firmware. If loader fails then shut down adapter */ err = sdla_load(hw, sfm, len); if (err) sdla_down(hw); /* shutdown adapter */ return err; }