X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Farm%2Feesox.c;h=3f876fb754693c7ab61496ad49dcda5f66656dd0;hb=refs%2Fheads%2Fvserver;hp=de4819fe2bcf0a1fd64dc8c2f4cf5cb50f1a4e12;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index de4819fe2..3f876fb75 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -1,7 +1,7 @@ /* * linux/drivers/acorn/scsi/eesox.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 @@ -35,13 +35,12 @@ #include #include -#include #include #include #include #include "../scsi.h" -#include "../hosts.h" +#include #include "fas216.h" #include "scsi.h" @@ -73,8 +72,8 @@ static int term[MAX_ECARDS] = { 1, 1, 1, 1, 1, 1, 1, 1 }; struct eesoxscsi_info { FAS216_Info info; struct expansion_card *ec; - - void *ctl_port; + void __iomem *base; + void __iomem *ctl_port; unsigned int control; struct scatterlist sg[NR_SG]; /* Scatter DMA list */ }; @@ -139,10 +138,9 @@ eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off) * Purpose : handle interrupts from EESOX SCSI card * Params : irq - interrupt number * dev_id - user-defined (Scsi_Host structure) - * regs - processor registers at interrupt */ static irqreturn_t -eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) +eesoxscsi_intr(int irq, void *dev_id) { struct eesoxscsi_info *info = dev_id; @@ -158,12 +156,12 @@ eesoxscsi_intr(int irq, void *dev_id, struct pt_regs *regs) * Returns : type of transfer to be performed */ static fasdmatype_t -eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, +eesoxscsi_dma_setup(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t direction, fasdmatype_t min_type) { struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; struct device *dev = scsi_get_device(host); - int dmach = host->dma_channel; + int dmach = info->info.scsi.dma; if (dmach != NO_DMA && (min_type == fasdma_real_all || SCp->this_residual >= 512)) { @@ -194,11 +192,11 @@ eesoxscsi_dma_setup(struct Scsi_Host *host, Scsi_Pointer *SCp, return fasdma_pseudo; } -static void eesoxscsi_buffer_in(void *buf, int length, void *base) +static void eesoxscsi_buffer_in(void *buf, int length, void __iomem *base) { - const void *reg_fas = base + EESOX_FAS216_OFFSET; - const void *reg_dmastat = base + EESOX_DMASTAT; - const void *reg_dmadata = base + EESOX_DMADATA; + const void __iomem *reg_fas = base + EESOX_FAS216_OFFSET; + const void __iomem *reg_dmastat = base + EESOX_DMASTAT; + const void __iomem *reg_dmadata = base + EESOX_DMADATA; const register unsigned long mask = 0xffff; do { @@ -231,7 +229,8 @@ static void eesoxscsi_buffer_in(void *buf, int length, void *base) * Align buffer. */ if (((u32)buf) & 2 && status >= 2) { - *((u16 *)buf)++ = readl(reg_dmadata); + *(u16 *)buf = readl(reg_dmadata); + buf += 2; status -= 2; length -= 2; } @@ -243,8 +242,10 @@ static void eesoxscsi_buffer_in(void *buf, int length, void *base) l1 |= readl(reg_dmadata) << 16; l2 = readl(reg_dmadata) & mask; l2 |= readl(reg_dmadata) << 16; - *((u32 *)buf)++ = l1; - *((u32 *)buf)++ = l2; + *(u32 *)buf = l1; + buf += 4; + *(u32 *)buf = l2; + buf += 4; length -= 8; continue; } @@ -255,23 +256,25 @@ static void eesoxscsi_buffer_in(void *buf, int length, void *base) l1 = readl(reg_dmadata) & mask; l1 |= readl(reg_dmadata) << 16; - *((u32 *)buf)++ = l1; + *(u32 *)buf = l1; + buf += 4; length -= 4; continue; } if (status >= 2) { - *((u16 *)buf)++ = readl(reg_dmadata); + *(u16 *)buf = readl(reg_dmadata); + buf += 2; length -= 2; } } while (length); } -static void eesoxscsi_buffer_out(void *buf, int length, void *base) +static void eesoxscsi_buffer_out(void *buf, int length, void __iomem *base) { - const void *reg_fas = base + EESOX_FAS216_OFFSET; - const void *reg_dmastat = base + EESOX_DMASTAT; - const void *reg_dmadata = base + EESOX_DMADATA; + const void __iomem *reg_fas = base + EESOX_FAS216_OFFSET; + const void __iomem *reg_dmastat = base + EESOX_DMASTAT; + const void __iomem *reg_dmadata = base + EESOX_DMADATA; do { unsigned int status; @@ -305,7 +308,8 @@ static void eesoxscsi_buffer_out(void *buf, int length, void *base) * Align buffer. */ if (((u32)buf) & 2 && status >= 2) { - writel(*((u16 *)buf)++ << 16, reg_dmadata); + writel(*(u16 *)buf << 16, reg_dmadata); + buf += 2; status -= 2; length -= 2; } @@ -313,8 +317,10 @@ static void eesoxscsi_buffer_out(void *buf, int length, void *base) if (status >= 8) { unsigned long l1, l2; - l1 = *((u32 *)buf)++; - l2 = *((u32 *)buf)++; + l1 = *(u32 *)buf; + buf += 4; + l2 = *(u32 *)buf; + buf += 4; writel(l1 << 16, reg_dmadata); writel(l1, reg_dmadata); @@ -327,7 +333,8 @@ static void eesoxscsi_buffer_out(void *buf, int length, void *base) if (status >= 4) { unsigned long l1; - l1 = *((u32 *)buf)++; + l1 = *(u32 *)buf; + buf += 4; writel(l1 << 16, reg_dmadata); writel(l1, reg_dmadata); @@ -336,21 +343,22 @@ static void eesoxscsi_buffer_out(void *buf, int length, void *base) } if (status >= 2) { - writel(*((u16 *)buf)++ << 16, reg_dmadata); + writel(*(u16 *)buf << 16, reg_dmadata); + buf += 2; length -= 2; } } while (length); } static void -eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, +eesoxscsi_dma_pseudo(struct Scsi_Host *host, struct scsi_pointer *SCp, fasdmadir_t dir, int transfer_size) { - void *base = (void *)host->base; + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; if (dir == DMA_IN) { - eesoxscsi_buffer_in(SCp->ptr, SCp->this_residual, base); + eesoxscsi_buffer_in(SCp->ptr, SCp->this_residual, info->base); } else { - eesoxscsi_buffer_out(SCp->ptr, SCp->this_residual, base); + eesoxscsi_buffer_out(SCp->ptr, SCp->this_residual, info->base); } } @@ -360,10 +368,11 @@ eesoxscsi_dma_pseudo(struct Scsi_Host *host, Scsi_Pointer *SCp, * SCpnt - command */ static void -eesoxscsi_dma_stop(struct Scsi_Host *host, Scsi_Pointer *SCp) +eesoxscsi_dma_stop(struct Scsi_Host *host, struct scsi_pointer *SCp) { - if (host->dma_channel != NO_DMA) - disable_dma(host->dma_channel); + struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; + if (info->info.scsi.dma != NO_DMA) + disable_dma(info->info.scsi.dma); } /* Prototype: const char *eesoxscsi_info(struct Scsi_Host * host) @@ -455,7 +464,7 @@ int eesoxscsi_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_ return pos; } -static ssize_t eesoxscsi_show_term(struct device *dev, char *buf) +static ssize_t eesoxscsi_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); @@ -464,7 +473,7 @@ static ssize_t eesoxscsi_show_term(struct device *dev, char *buf) return sprintf(buf, "%d\n", info->control & EESOX_TERM_ENABLE ? 1 : 0); } -static ssize_t eesoxscsi_store_term(struct device *dev, const char *buf, size_t len) +static ssize_t eesoxscsi_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); @@ -488,7 +497,7 @@ static ssize_t eesoxscsi_store_term(struct device *dev, const char *buf, size_t static DEVICE_ATTR(bus_term, S_IRUGO | S_IWUSR, eesoxscsi_show_term, eesoxscsi_store_term); -static Scsi_Host_Template eesox_template = { +static struct scsi_host_template eesox_template = { .module = THIS_MODULE, .proc_info = eesoxscsi_proc_info, .name = "EESOX SCSI", @@ -512,17 +521,15 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id) struct Scsi_Host *host; struct eesoxscsi_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, "eesoxscsi")) { - 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; @@ -536,26 +543,19 @@ eesoxscsi_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; - 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); - ec->irqaddr = base + EESOX_DMASTAT; - ec->irqmask = EESOX_STAT_INTR; - ec->irq_data = info; - ec->ops = &eesoxscsi_ops; - info->info.scsi.io_base = base + EESOX_FAS216_OFFSET; info->info.scsi.io_shift = EESOX_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 */ @@ -568,26 +568,31 @@ eesoxscsi_probe(struct expansion_card *ec, const struct ecard_id *id) info->info.dma.pseudo = eesoxscsi_dma_pseudo; info->info.dma.stop = eesoxscsi_dma_stop; + ec->irqaddr = base + EESOX_DMASTAT; + ec->irqmask = EESOX_STAT_INTR; + ec->irq_data = info; + ec->ops = &eesoxscsi_ops; + device_create_file(&ec->dev, &dev_attr_bus_term); ret = fas216_init(host); if (ret) goto out_free; - ret = request_irq(host->irq, eesoxscsi_intr, 0, "eesoxscsi", info); + ret = request_irq(ec->irq, eesoxscsi_intr, 0, "eesoxscsi", 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_remove; } - if (host->dma_channel != NO_DMA) { - if (request_dma(host->dma_channel, "eesox")) { + 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, 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; info->info.ifcfg.cntl3 |= CNTL3_BS8; } @@ -597,9 +602,9 @@ eesoxscsi_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_remove: fas216_remove(host); @@ -612,7 +617,7 @@ eesoxscsi_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; @@ -622,26 +627,21 @@ static void __devexit eesoxscsi_remove(struct expansion_card *ec) { struct Scsi_Host *host = ecard_get_drvdata(ec); struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; - unsigned long resbase, reslen; ecard_set_drvdata(ec, NULL); fas216_remove(host); - if (host->dma_channel != NO_DMA) - free_dma(host->dma_channel); - free_irq(host->irq, info); + if (info->info.scsi.dma != NO_DMA) + free_dma(info->info.scsi.dma); + free_irq(ec->irq, info); device_remove_file(&ec->dev, &dev_attr_bus_term); - iounmap((void *)host->base); - - resbase = ecard_resource_start(ec, ECARD_RES_IOCFAST); - reslen = ecard_resource_len(ec, ECARD_RES_IOCFAST); - - release_mem_region(resbase, reslen); + iounmap(info->base); fas216_release(host); scsi_host_put(host); + ecard_release_resources(ec); } static const struct ecard_id eesoxscsi_cids[] = { @@ -673,7 +673,6 @@ module_exit(eesox_exit); MODULE_AUTHOR("Russell King"); MODULE_DESCRIPTION("EESOX 'Fast' SCSI driver for Acorn machines"); -MODULE_PARM(term, "1-8i"); +module_param_array(term, int, NULL, 0); MODULE_PARM_DESC(term, "SCSI bus termination"); MODULE_LICENSE("GPL"); -