static int __devinit rapide_probe(struct expansion_card *ec, const struct ecard_id *id) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); hw_regs_t hw; int i, ret; memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = port; port += 1 << 4; } hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; hw.irq = ec->irq; ret = ide_register_hw(&hw, NULL); if (ret) ecard_release(ec); /* * this locks the driver in-core - remove this * comment and the two lines below when we can * safely remove interfaces. */ else MOD_INC_USE_COUNT; return ret; }
static int __devinit cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret = -ENOMEM; host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); if (!host) goto out; host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800; host->irq = ec->irq; NCR5380_init(host, 0); host->n_io_port = 255; if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { ret = -EBUSY; goto out_free; } ((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0; outb(0x00, host->io_port - 577); ret = request_irq(host->irq, cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", host); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); goto out_release; } printk("scsi%d: at port 0x%08lx irq %d", host->host_no, host->io_port, host->irq); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", host->can_queue, host->cmd_per_lun, CUMANASCSI_PUBLIC_RELEASE); printk("\nscsi%d:", host->host_no); NCR5380_print_options(host); printk("\n"); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_free_irq; scsi_scan_host(host); goto out; out_free_irq: free_irq(host->irq, host); out_release: release_region(host->io_port, host->n_io_port); out_free: scsi_host_put(host); out: return ret; }
void cleanup_module (void) { int i; for (i = 0; i < MAX_ECARDS; i++) if (ec[i]) { unsigned long port; port = ecard_address(ec[i], ECARD_MEMC, 0); ide_unregister_port(port, ec[i]->irq, 16); ecard_release(ec[i]); ec[i] = NULL; } }
static inline int rapide_register(struct expansion_card *ec) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); hw_regs_t hw; int i; memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = (ide_ioreg_t)port; port += 1 << 4; } hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; hw.irq = ec->irq; return ide_register_hw(&hw, NULL); }
__initfunc(static void ether3_get_dev(struct device *dev, struct expansion_card *ec)) { ecard_claim(ec); dev->base_addr = ecard_address(ec, ECARD_MEMC, 0); dev->irq = ec->irq; if (ec->cid.manufacturer == MANU_ANT && ec->cid.product == PROD_ANT_ETHERB) { dev->base_addr += 0x200; } ec->irqaddr = (volatile unsigned char *)ioaddr(dev->base_addr); ec->irqmask = 0xf0; ether3_addr(dev->dev_addr, ec); }
/* Prototype: int powertecscsi_release(struct Scsi_Host * host) * Purpose : releases all resources used by this adapter * Params : host - driver host structure to return info for. */ int powertecscsi_release(struct Scsi_Host *host) { int i; fas216_release(host); if (host->irq != NO_IRQ) free_irq(host->irq, host); if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); release_region(host->io_port + POWERTEC_FAS216_OFFSET, 16 << POWERTEC_FAS216_SHIFT); for (i = 0; i < MAX_ECARDS; i++) if (ecs[i] && host->io_port == ecard_address(ecs[i], ECARD_IOC, ECARD_FAST)) ecard_release(ecs[i]); return 0; }
static int __devinit oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) { struct Scsi_Host *host; int ret = -ENOMEM; host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); if (!host) goto out; host->io_port = ecard_address(ec, ECARD_MEMC, 0); host->irq = IRQ_NONE; host->n_io_port = 255; ret = -EBUSY; if (!request_region (host->io_port, host->n_io_port, "Oak SCSI")) goto unreg; NCR5380_init(host, 0); printk("scsi%d: at port 0x%08lx irqs disabled", host->host_no, host->io_port); printk(" options CAN_QUEUE=%d CMD_PER_LUN=%d release=%d", host->can_queue, host->cmd_per_lun, OAKSCSI_PUBLIC_RELEASE); printk("\nscsi%d:", host->host_no); NCR5380_print_options(host); printk("\n"); ret = scsi_add_host(host, &ec->dev); if (ret) goto out_release; scsi_scan_host(host); goto out; out_release: release_region(host->io_port, host->n_io_port); unreg: scsi_host_put(host); out: return ret; }
static int __devinit rapide_probe(struct expansion_card *ec, const struct ecard_id *id) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); hw_regs_t hw; int i, ret; memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = port; port += 1 << 4; } hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; hw.irq = ec->irq; ret = ide_register_hw(&hw, NULL); if (ret) ecard_release(ec); return ret; }
static int powertecscsi_probe(struct expansion_card *ec) { struct Scsi_Host *host; struct powertec_info *info; unsigned long base; int ret; base = ecard_address(ec, ECARD_IOC, ECARD_FAST); request_region(base + POWERTEC_FAS216_OFFSET, 16 << POWERTEC_FAS216_SHIFT, "powertec2-fas"); host = scsi_register(&powertecscsi_template, sizeof (struct powertec_info)); if (!host) { ret = -ENOMEM; goto out_region; } host->io_port = base; host->irq = ec->irq; host->dma_channel = ec->dma; ec->irqaddr = (unsigned char *)ioaddr(base + POWERTEC_INTR_STATUS); ec->irqmask = POWERTEC_INTR_BIT; ec->irq_data = (void *)(base + POWERTEC_INTR_CONTROL); ec->ops = (expansioncard_ops_t *)&powertecscsi_ops; info = (struct powertec_info *)host->hostdata; info->ec = ec; info->term_port = base + POWERTEC_TERM_CONTROL; powertecscsi_terminator_ctl(host, term[ec->slot_no]); info->info.scsi.io_port = host->io_port + POWERTEC_FAS216_OFFSET; info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT; info->info.scsi.irq = host->irq; info->info.ifcfg.clockrate = 40; /* MHz */ info->info.ifcfg.select_timeout = 255; info->info.ifcfg.asyncperiod = 200; /* ns */ info->info.ifcfg.sync_max_depth = 7; info->info.ifcfg.cntl3 = CNTL3_BS8 | CNTL3_FASTSCSI | CNTL3_FASTCLK; info->info.ifcfg.disconnect_ok = 1; info->info.ifcfg.wide_max_size = 0; info->info.ifcfg.capabilities = 0; info->info.dma.setup = powertecscsi_dma_setup; info->info.dma.pseudo = NULL; info->info.dma.stop = powertecscsi_dma_stop; ret = fas216_init(host); if (ret) goto out_free; ret = request_irq(host->irq, powertecscsi_intr, SA_INTERRUPT, "powertec", &info->info); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", host->host_no, host->irq, ret); goto out_release; } if (host->dma_channel != NO_DMA) { if (request_dma(host->dma_channel, "powertec")) { printk("scsi%d: DMA%d not free, using PIO\n", host->host_no, host->dma_channel); host->dma_channel = NO_DMA; } else { set_dma_speed(host->dma_channel, 180); info->info.ifcfg.capabilities |= FASCAP_DMA; } } ret = fas216_add(host); if (ret == 0) goto out; if (host->dma_channel != NO_DMA) free_dma(host->dma_channel); free_irq(host->irq, host); out_release: fas216_release(host); out_free: scsi_unregister(host); out_region: release_region(base + POWERTEC_FAS216_OFFSET, 16 << POWERTEC_FAS216_SHIFT); out: return ret; }
/* Prototype: int powertecscsi_detect(Scsi_Host_Template * tpnt) * Purpose : initialises PowerTec SCSI driver * Params : tpnt - template for this SCSI adapter * Returns : >0 if host found, 0 otherwise. */ int powertecscsi_detect(Scsi_Host_Template *tpnt) { static const card_ids powertecscsi_cids[] = { POWERTECSCSI_LIST, { 0xffff, 0xffff} }; int count = 0; struct Scsi_Host *host; tpnt->proc_dir = &proc_scsi_powertec; memset(ecs, 0, sizeof (ecs)); ecard_startfind(); while (1) { PowerTecScsi_Info *info; ecs[count] = ecard_find(0, powertecscsi_cids); if (!ecs[count]) break; ecard_claim(ecs[count]); host = scsi_register(tpnt, sizeof (PowerTecScsi_Info)); if (!host) { ecard_release(ecs[count]); break; } host->io_port = ecard_address(ecs[count], ECARD_IOC, ECARD_FAST); host->irq = ecs[count]->irq; host->dma_channel = ecs[count]->dma; info = (PowerTecScsi_Info *)host->hostdata; info->control.term_port = host->io_port + POWERTEC_TERM_CONTROL; info->control.terms = term[count] ? POWERTEC_TERM_ENABLE : 0; powertecscsi_terminator_ctl(host, info->control.terms); info->info.scsi.io_port = host->io_port + POWERTEC_FAS216_OFFSET; info->info.scsi.io_shift= POWERTEC_FAS216_SHIFT; info->info.scsi.irq = host->irq; info->info.ifcfg.clockrate = POWERTEC_XTALFREQ; info->info.ifcfg.select_timeout = 255; info->info.ifcfg.asyncperiod = POWERTEC_ASYNC_PERIOD; info->info.ifcfg.sync_max_depth = POWERTEC_SYNC_DEPTH; info->info.ifcfg.cntl3 = /*CNTL3_BS8 |*/ CNTL3_FASTSCSI | CNTL3_FASTCLK; info->info.ifcfg.disconnect_ok = 1; info->info.ifcfg.wide_max_size = 0; info->info.dma.setup = powertecscsi_dma_setup; info->info.dma.pseudo = NULL; info->info.dma.stop = powertecscsi_dma_stop; ecs[count]->irqaddr = (unsigned char *) ioaddr(host->io_port + POWERTEC_INTR_STATUS); ecs[count]->irqmask = POWERTEC_INTR_BIT; ecs[count]->irq_data = (void *) (host->io_port + POWERTEC_INTR_CONTROL); ecs[count]->ops = (expansioncard_ops_t *)&powertecscsi_ops; request_region(host->io_port + POWERTEC_FAS216_OFFSET, 16 << POWERTEC_FAS216_SHIFT, "powertec2-fas"); if (host->irq != NO_IRQ && request_irq(host->irq, powertecscsi_intr, SA_INTERRUPT, "powertec", host)) { printk("scsi%d: IRQ%d not free, interrupts disabled\n", host->host_no, host->irq); host->irq = NO_IRQ; info->info.scsi.irq = NO_IRQ; } if (host->dma_channel != NO_DMA && request_dma(host->dma_channel, "powertec")) { printk("scsi%d: DMA%d not free, DMA disabled\n", host->host_no, host->dma_channel); host->dma_channel = NO_DMA; } fas216_init(host); ++count; } return count; }
/* * Probe for an expansion card. * * If bit 1 of the first byte of the card is set, then the * card does not exist. */ static int __init ecard_probe(int slot, card_type_t type) { ecard_t **ecp; ecard_t *ec; struct ex_ecid cid; int i, rc = -ENOMEM; ec = kmalloc(sizeof(ecard_t), GFP_KERNEL); if (!ec) goto nomem; memset(ec, 0, sizeof(ecard_t)); ec->slot_no = slot; ec->type = type; ec->irq = NO_IRQ; ec->fiq = NO_IRQ; ec->dma = NO_DMA; ec->card_desc = NULL; ec->ops = &ecard_default_ops; rc = -ENODEV; if ((ec->podaddr = ecard_address(ec, type, ECARD_SYNC)) == 0) goto nodev; cid.r_zero = 1; ecard_readbytes(&cid, ec, 0, 16, 0); if (cid.r_zero) goto nodev; ec->cid.id = cid.r_id; ec->cid.cd = cid.r_cd; ec->cid.is = cid.r_is; ec->cid.w = cid.r_w; ec->cid.manufacturer = ecard_getu16(cid.r_manu); ec->cid.product = ecard_getu16(cid.r_prod); ec->cid.country = cid.r_country; ec->cid.irqmask = cid.r_irqmask; ec->cid.irqoff = ecard_gets24(cid.r_irqoff); ec->cid.fiqmask = cid.r_fiqmask; ec->cid.fiqoff = ecard_gets24(cid.r_fiqoff); ec->fiqaddr = ec->irqaddr = (unsigned char *)ioaddr(ec->podaddr); if (ec->cid.is) { ec->irqmask = ec->cid.irqmask; ec->irqaddr += ec->cid.irqoff; ec->fiqmask = ec->cid.fiqmask; ec->fiqaddr += ec->cid.fiqoff; } else { ec->irqmask = 1; ec->fiqmask = 4; } for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++) if (blacklist[i].manufacturer == ec->cid.manufacturer && blacklist[i].product == ec->cid.product) { ec->card_desc = blacklist[i].type; break; } snprintf(ec->dev.bus_id, sizeof(ec->dev.bus_id), "ecard%d", slot); ec->dev.parent = NULL; ec->dev.bus = &ecard_bus_type; ec->dev.dma_mask = &ec->dma_mask; ec->dma_mask = (u64)0xffffffff; ecard_init_resources(ec); /* * hook the interrupt handlers */ ec->irq = 32 + slot; set_irq_chip(ec->irq, &ecard_chip); set_irq_handler(ec->irq, do_level_IRQ); set_irq_flags(ec->irq, IRQF_VALID); for (ecp = &cards; *ecp; ecp = &(*ecp)->next); *ecp = ec; slot_to_expcard[slot] = ec; device_register(&ec->dev); device_create_file(&ec->dev, &dev_attr_dma); device_create_file(&ec->dev, &dev_attr_irq); device_create_file(&ec->dev, &dev_attr_resource); device_create_file(&ec->dev, &dev_attr_vendor); device_create_file(&ec->dev, &dev_attr_device); return 0; nodev: kfree(ec); nomem: return rc; }