コード例 #1
0
ファイル: powertec.c プロジェクト: Dronevery/JetsonTK1-kernel
static int __devinit
powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	struct Scsi_Host *host;
	struct powertec_info *info;
	unsigned long resbase, reslen;
	void __iomem *base;
	int ret;

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST);
	reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST);
	base = ioremap(resbase, reslen);
	if (!base) {
		ret = -ENOMEM;
		goto out_region;
	}

	host = scsi_host_alloc(&powertecscsi_template,
			       sizeof (struct powertec_info));
	if (!host) {
		ret = -ENOMEM;
		goto out_unmap;
	}

	ecard_set_drvdata(ec, host);

	info = (struct powertec_info *)host->hostdata;
	info->base = base;
	powertecscsi_terminator_ctl(host, term[ec->slot_no]);

	info->info.scsi.io_base		= base + POWERTEC_FAS216_OFFSET;
	info->info.scsi.io_shift	= POWERTEC_FAS216_SHIFT;
	info->info.scsi.irq		= ec->irq;
	info->info.scsi.dma		= ec->dma;
	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;

	ec->irqaddr	= base + POWERTEC_INTR_STATUS;
	ec->irqmask	= POWERTEC_INTR_BIT;
	ec->irq_data	= info;
	ec->ops		= &powertecscsi_ops;

	device_create_file(&ec->dev, &dev_attr_bus_term);

	ret = fas216_init(host);
	if (ret)
		goto out_free;

	ret = request_irq(ec->irq, powertecscsi_intr,
			  SA_INTERRUPT, "powertec", info);
	if (ret) {
		printk("scsi%d: IRQ%d not free: %d\n",
		       host->host_no, ec->irq, ret);
		goto out_release;
	}

	if (info->info.scsi.dma != NO_DMA) {
		if (request_dma(info->info.scsi.dma, "powertec")) {
			printk("scsi%d: DMA%d not free, using PIO\n",
			       host->host_no, info->info.scsi.dma);
			info->info.scsi.dma = NO_DMA;
		} else {
			set_dma_speed(info->info.scsi.dma, 180);
			info->info.ifcfg.capabilities |= FASCAP_DMA;
		}
	}

	ret = fas216_add(host, &ec->dev);
	if (ret == 0)
		goto out;

	if (info->info.scsi.dma != NO_DMA)
		free_dma(info->info.scsi.dma);
	free_irq(ec->irq, host);

 out_release:
	fas216_release(host);

 out_free:
	device_remove_file(&ec->dev, &dev_attr_bus_term);
	scsi_host_put(host);

 out_unmap:
	iounmap(base);

 out_region:
	ecard_release_resources(ec);

 out:
	return ret;
}
コード例 #2
0
ファイル: powertec.c プロジェクト: Brainiarc7/ralink_sdk
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;
}
コード例 #3
0
ファイル: eesox.c プロジェクト: 03199618/linux
static int eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	struct Scsi_Host *host;
	struct eesoxscsi_info *info;
	void __iomem *base;
	int ret;

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
	if (!base) {
		ret = -ENOMEM;
		goto out_region;
	}

	host = scsi_host_alloc(&eesox_template,
			       sizeof(struct eesoxscsi_info));
	if (!host) {
		ret = -ENOMEM;
		goto out_region;
	}

	ecard_set_drvdata(ec, host);

	info = (struct eesoxscsi_info *)host->hostdata;
	info->ec	= ec;
	info->base	= base;
	info->ctl_port	= base + EESOX_CONTROL;
	info->control	= term[ec->slot_no] ? EESOX_TERM_ENABLE : 0;
	writeb(info->control, info->ctl_port);

	info->info.scsi.io_base		= base + EESOX_FAS216_OFFSET;
	info->info.scsi.io_shift	= EESOX_FAS216_SHIFT;
	info->info.scsi.irq		= ec->irq;
	info->info.scsi.dma		= ec->dma;
	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_FASTSCSI | CNTL3_FASTCLK;
	info->info.ifcfg.disconnect_ok	= 1;
	info->info.ifcfg.wide_max_size	= 0;
	info->info.ifcfg.capabilities	= FASCAP_PSEUDODMA;
	info->info.dma.setup		= eesoxscsi_dma_setup;
	info->info.dma.pseudo		= eesoxscsi_dma_pseudo;
	info->info.dma.stop		= eesoxscsi_dma_stop;

	ec->irqaddr	= base + EESOX_DMASTAT;
	ec->irqmask	= EESOX_STAT_INTR;

	ecard_setirq(ec, &eesoxscsi_ops, info);

	device_create_file(&ec->dev, &dev_attr_bus_term);

	ret = fas216_init(host);
	if (ret)
		goto out_free;

	ret = request_irq(ec->irq, eesoxscsi_intr, 0, "eesoxscsi", info);
	if (ret) {
		printk("scsi%d: IRQ%d not free: %d\n",
		       host->host_no, ec->irq, ret);
		goto out_remove;
	}

	if (info->info.scsi.dma != NO_DMA) {
		if (request_dma(info->info.scsi.dma, "eesox")) {
			printk("scsi%d: DMA%d not free, DMA disabled\n",
			       host->host_no, info->info.scsi.dma);
			info->info.scsi.dma = NO_DMA;
		} else {
			set_dma_speed(info->info.scsi.dma, 180);
			info->info.ifcfg.capabilities |= FASCAP_DMA;
			info->info.ifcfg.cntl3 |= CNTL3_BS8;
		}
	}

	ret = fas216_add(host, &ec->dev);
	if (ret == 0)
		goto out;

	if (info->info.scsi.dma != NO_DMA)
		free_dma(info->info.scsi.dma);
	free_irq(ec->irq, host);

 out_remove:
	fas216_remove(host);

 out_free:
	device_remove_file(&ec->dev, &dev_attr_bus_term);
	scsi_host_put(host);

 out_region:
	ecard_release_resources(ec);

 out:
	return ret;
}