__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); }
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; }
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len) { int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl; int oldctrl = *ctrl; unsigned long *laddr; #ifdef NOT_EFFICIENT int iobase = instance->io_port; int dma_io = iobase & ~(0x3C0000>>2); #else volatile unsigned char *iobase = (unsigned char *)ioaddr(instance->io_port); volatile unsigned char *dma_io = (unsigned char *)((int)iobase & ~0x3C0000); #endif if(!len) return 0; CTRL(iobase, 0x02); laddr = (unsigned long *)addr; while(len >= 32) { int status; unsigned long v; status = STAT(iobase); if(status & 0x80) goto end; if(!(status & 0x40)) continue; v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); len -= 32; if(len == 0) break; } addr = (unsigned char *)laddr; CTRL(iobase, 0x12); while(len > 0) { int status; status = STAT(iobase); if(status & 0x80) goto end; if(status & 0x40) { OUT(*addr++, dma_io); if(--len == 0) break; } status = STAT(iobase); if(status & 0x80) goto end; if(status & 0x40) { OUT(*addr++, dma_io); if(--len == 0) break; } } end: CTRL(iobase, oldctrl|0x40); return len; }
/* 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; }