X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Farm%2Fpowertec.c;h=ce159c15bc86eae5e711136616e8f68aaf20f985;hb=refs%2Fheads%2Fvserver;hp=e5dd354c406647925ab1ae81c10ca22bed23ed80;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c index e5dd354c4..ce159c15b 100644 --- a/drivers/scsi/arm/powertec.c +++ b/drivers/scsi/arm/powertec.c @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/powertec.c * - * Copyright (C) 1997-2003 Russell King + * Copyright (C) 1997-2005 Russell King * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -22,11 +22,10 @@ #include #include #include -#include #include #include "../scsi.h" -#include "../hosts.h" +#include #include "fas216.h" #include "scsi.h" @@ -61,7 +60,7 @@ static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; struct powertec_info { FAS216_Info info; struct expansion_card *ec; - void *term_port; + void __iomem *base; unsigned int term_ctl; struct scatterlist sg[NR_SG]; }; @@ -74,7 +73,8 @@ struct powertec_info { static void powertecscsi_irqenable(struct expansion_card *ec, int irqnr) { - writeb(POWERTEC_INTR_ENABLE, ec->irq_data); + struct powertec_info *info = ec->irq_data; + writeb(POWERTEC_INTR_ENABLE, info->base + POWERTEC_INTR_CONTROL); } /* Prototype: void powertecscsi_irqdisable(ec, irqnr) @@ -85,7 +85,8 @@ powertecscsi_irqenable(struct expansion_card *ec, int irqnr) static void powertecscsi_irqdisable(struct expansion_card *ec, int irqnr) { - writeb(POWERTEC_INTR_DISABLE, ec->irq_data); + struct powertec_info *info = ec->irq_data; + writeb(POWERTEC_INTR_DISABLE, info->base + POWERTEC_INTR_CONTROL); } static const expansioncard_ops_t powertecscsi_ops = { @@ -104,17 +105,15 @@ powertecscsi_terminator_ctl(struct Scsi_Host *host, int on_off) struct powertec_info *info = (struct powertec_info *)host->hostdata; info->term_ctl = on_off ? POWERTEC_TERM_ENABLE : 0; - writeb(info->term_ctl, info->term_port); + writeb(info->term_ctl, info->base + POWERTEC_TERM_CONTROL); } /* Prototype: void powertecscsi_intr(irq, *dev_id, *regs) * Purpose : handle interrupts from Powertec SCSI card * Params : irq - interrupt number * dev_id - user-defined (Scsi_Host structure) - * regs - processor registers at interrupt */ -static irqreturn_t -powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) +static irqreturn_t powertecscsi_intr(int irq, void *dev_id) { struct powertec_info *info = dev_id; @@ -130,12 +129,12 @@ powertecscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +powertecscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct powertec_info *info = (struct powertec_info *)host->hostdata; struct device *dev = scsi_get_device(host); - int dmach = host->dma_channel; + int dmach = info->info.scsi.dma; if (info->info.ifcfg.capabilities & FASCAP_DMA && min_type == fasdma_real_all) { @@ -172,10 +171,11 @@ powertecscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -powertecscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +powertecscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { - if (host->dma_channel != NO_DMA) - disable_dma(host->dma_channel); + struct powertec_info *info = (struct powertec_info *)host->hostdata; + if (info->info.scsi.dma != NO_DMA) + disable_dma(info->info.scsi.dma); } /* Prototype: const char *powertecscsi_info(struct Scsi_Host * host) @@ -266,7 +266,7 @@ int powertecscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, o return pos; } -static ssize_t powertecscsi_show_term(struct device *dev, char *buf) +static ssize_t powertecscsi_show_term(struct device *dev, struct device_attribute *attr, char *buf) { struct expansion_card *ec = ECARD_DEV(dev); struct Scsi_Host *host = ecard_get_drvdata(ec); @@ -276,7 +276,7 @@ static ssize_t powertecscsi_show_term(struct device *dev, char *buf) } static ssize_t -powertecscsi_store_term(struct device *dev, const char *buf, size_t len) +powertecscsi_store_term(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct expansion_card *ec = ECARD_DEV(dev); struct Scsi_Host *host = ecard_get_drvdata(ec); @@ -290,7 +290,7 @@ powertecscsi_store_term(struct device *dev, const char *buf, size_t len) static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, powertecscsi_show_term, powertecscsi_store_term); -static Scsi_Host_Template powertecscsi_template = { +static struct scsi_host_template powertecscsi_template = { .module = THIS_MODULE, .proc_info = powertecscsi_proc_info, .name = "PowerTec SCSI", @@ -315,17 +315,15 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) struct Scsi_Host *host; struct powertec_info *info; unsigned long resbase, reslen; - unsigned char *base; + void __iomem *base; int ret; - resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); - reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); - - if (!request_mem_region(resbase, reslen, "powertecscsi")) { - ret = -EBUSY; + 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; @@ -339,26 +337,16 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) goto out_unmap; } - host->base = (unsigned long)base; - host->irq = ec->irq; - host->dma_channel = ec->dma; - - ec->irqaddr = base + POWERTEC_INTR_STATUS; - ec->irqmask = POWERTEC_INTR_BIT; - ec->irq_data = base + POWERTEC_INTR_CONTROL; - ec->ops = &powertecscsi_ops; - ecard_set_drvdata(ec, host); info = (struct powertec_info *)host->hostdata; - info->term_port = base + POWERTEC_TERM_CONTROL; + info->base = base; powertecscsi_terminator_ctl(host, term[ec->slot_no]); - device_create_file(&ec->dev, &dev_attr_bus_term); - info->info.scsi.io_base = base + POWERTEC_FAS216_OFFSET; info->info.scsi.io_shift = POWERTEC_FAS216_SHIFT; - info->info.scsi.irq = host->irq; + 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 */ @@ -371,25 +359,32 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) 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(host->irq, powertecscsi_intr, - SA_INTERRUPT, "powertec", info); + ret = request_irq(ec->irq, powertecscsi_intr, + IRQF_DISABLED, "powertec", info); if (ret) { printk("scsi%d: IRQ%d not free: %d\n", - host->host_no, host->irq, ret); + host->host_no, ec->irq, ret); goto out_release; } - if (host->dma_channel != NO_DMA) { - if (request_dma(host->dma_channel, "powertec")) { + 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, host->dma_channel); - host->dma_channel = NO_DMA; + host->host_no, info->info.scsi.dma); + info->info.scsi.dma = NO_DMA; } else { - set_dma_speed(host->dma_channel, 180); + set_dma_speed(info->info.scsi.dma, 180); info->info.ifcfg.capabilities |= FASCAP_DMA; } } @@ -398,9 +393,9 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) if (ret == 0) goto out; - if (host->dma_channel != NO_DMA) - free_dma(host->dma_channel); - free_irq(host->irq, host); + if (info->info.scsi.dma != NO_DMA) + free_dma(info->info.scsi.dma); + free_irq(ec->irq, host); out_release: fas216_release(host); @@ -413,7 +408,7 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) iounmap(base); out_region: - release_mem_region(resbase, reslen); + ecard_release_resources(ec); out: return ret; @@ -422,27 +417,22 @@ powertecscsi_probe(struct expansion_card *ec, const struct ecard_id *id) static void __devexit powertecscsi_remove(struct expansion_card *ec) { struct Scsi_Host *host = ecard_get_drvdata(ec); - struct powertecscsi_info *info = (struct powertecscsi_info *)host->hostdata; - unsigned long resbase, reslen; + struct powertec_info *info = (struct powertec_info *)host->hostdata; ecard_set_drvdata(ec, NULL); fas216_remove(host); device_remove_file(&ec->dev, &dev_attr_bus_term); - if (host->dma_channel != NO_DMA) - free_dma(host->dma_channel); - free_irq(host->irq, info); - - iounmap((void *)host->base); - - resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); - reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); + if (info->info.scsi.dma != NO_DMA) + free_dma(info->info.scsi.dma); + free_irq(ec->irq, info); - release_mem_region(resbase, reslen); + iounmap(info->base); fas216_release(host); scsi_host_put(host); + ecard_release_resources(ec); } static const struct ecard_id powertecscsi_cids[] = { @@ -474,6 +464,6 @@ module_exit(powertecscsi_exit); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("Powertec SCSI driver"); -MODULE_PARM(term, "1-8i"); +module_param_array(term, int, NULL, 0); MODULE_PARM_DESC(term, "SCSI bus termination"); MODULE_LICENSE("GPL");