|
@@ -136,9 +136,9 @@
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/bitops.h>
|
|
|
#include <linux/stringify.h>
|
|
|
+#include <linux/io.h>
|
|
|
|
|
|
#include <asm/system.h>
|
|
|
-#include <asm/io.h>
|
|
|
#include <asm/ecard.h>
|
|
|
|
|
|
#include "../scsi.h"
|
|
@@ -198,35 +198,40 @@ static void acornscsi_abortcmd(AS_Host *host, unsigned char tag);
|
|
|
* Miscellaneous
|
|
|
*/
|
|
|
|
|
|
+/* Offsets from MEMC base */
|
|
|
+#define SBIC_REGIDX 0x2000
|
|
|
+#define SBIC_REGVAL 0x2004
|
|
|
+#define DMAC_OFFSET 0x3000
|
|
|
+
|
|
|
+/* Offsets from FAST IOC base */
|
|
|
+#define INT_REG 0x2000
|
|
|
+#define PAGE_REG 0x3000
|
|
|
+
|
|
|
static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value)
|
|
|
{
|
|
|
- __raw_writeb(reg, host->scsi.io_port);
|
|
|
- __raw_writeb(value, host->scsi.io_port + 4);
|
|
|
+ writeb(reg, host->base + SBIC_REGIDX);
|
|
|
+ writeb(value, host->base + SBIC_REGVAL);
|
|
|
}
|
|
|
|
|
|
-#define sbic_arm_writenext(host,val) \
|
|
|
- __raw_writeb((val), (host)->scsi.io_port + 4)
|
|
|
-
|
|
|
static inline int sbic_arm_read(AS_Host *host, unsigned int reg)
|
|
|
{
|
|
|
if(reg == SBIC_ASR)
|
|
|
- return __raw_readl(host->scsi.io_port) & 255;
|
|
|
- __raw_writeb(reg, host->scsi.io_port);
|
|
|
- return __raw_readl(host->scsi.io_port + 4) & 255;
|
|
|
+ return readl(host->base + SBIC_REGIDX) & 255;
|
|
|
+ writeb(reg, host->base + SBIC_REGIDX);
|
|
|
+ return readl(host->base + SBIC_REGVAL) & 255;
|
|
|
}
|
|
|
|
|
|
-#define sbic_arm_readnext(host) \
|
|
|
- __raw_readb((host)->scsi.io_port + 4)
|
|
|
+#define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL)
|
|
|
+#define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL)
|
|
|
|
|
|
#ifdef USE_DMAC
|
|
|
#define dmac_read(host,reg) \
|
|
|
- inb((host)->dma.io_port + (reg))
|
|
|
+ readb((host)->base + DMAC_OFFSET + ((reg) << 2))
|
|
|
|
|
|
#define dmac_write(host,reg,value) \
|
|
|
- ({ outb((value), (host)->dma.io_port + (reg)); })
|
|
|
+ ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); })
|
|
|
|
|
|
-#define dmac_clearintr(host) \
|
|
|
- ({ outb(0, (host)->dma.io_intr_clear); })
|
|
|
+#define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG)
|
|
|
|
|
|
static inline unsigned int dmac_address(AS_Host *host)
|
|
|
{
|
|
@@ -323,20 +328,20 @@ void acornscsi_resetcard(AS_Host *host)
|
|
|
|
|
|
/* assert reset line */
|
|
|
host->card.page_reg = 0x80;
|
|
|
- outb(host->card.page_reg, host->card.io_page);
|
|
|
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
|
|
|
|
|
|
/* wait 3 cs. SCSI standard says 25ms. */
|
|
|
acornscsi_csdelay(3);
|
|
|
|
|
|
host->card.page_reg = 0;
|
|
|
- outb(host->card.page_reg, host->card.io_page);
|
|
|
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
|
|
|
|
|
|
/*
|
|
|
* Should get a reset from the card
|
|
|
*/
|
|
|
timeout = 1000;
|
|
|
do {
|
|
|
- if (inb(host->card.io_intr) & 8)
|
|
|
+ if (readb(host->fast + INT_REG) & 8)
|
|
|
break;
|
|
|
udelay(1);
|
|
|
} while (--timeout);
|
|
@@ -357,7 +362,7 @@ void acornscsi_resetcard(AS_Host *host)
|
|
|
*/
|
|
|
timeout = 1000;
|
|
|
do {
|
|
|
- if (inb(host->card.io_intr) & 8)
|
|
|
+ if (readb(host->fast + INT_REG) & 8)
|
|
|
break;
|
|
|
udelay(1);
|
|
|
} while (--timeout);
|
|
@@ -377,7 +382,7 @@ void acornscsi_resetcard(AS_Host *host)
|
|
|
sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP);
|
|
|
|
|
|
host->card.page_reg = 0x40;
|
|
|
- outb(host->card.page_reg, host->card.io_page);
|
|
|
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
|
|
|
|
|
|
/* setup dmac - uPC71071 */
|
|
|
dmac_write(host, DMAC_INIT, 0);
|
|
@@ -910,13 +915,13 @@ static
|
|
|
void acornscsi_data_read(AS_Host *host, char *ptr,
|
|
|
unsigned int start_addr, unsigned int length)
|
|
|
{
|
|
|
- extern void __acornscsi_in(int port, char *buf, int len);
|
|
|
+ extern void __acornscsi_in(void __iomem *, char *buf, int len);
|
|
|
unsigned int page, offset, len = length;
|
|
|
|
|
|
page = (start_addr >> 12);
|
|
|
offset = start_addr & ((1 << 12) - 1);
|
|
|
|
|
|
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
|
|
|
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
|
|
|
|
|
|
while (len > 0) {
|
|
|
unsigned int this_len;
|
|
@@ -926,7 +931,7 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
|
|
|
else
|
|
|
this_len = len;
|
|
|
|
|
|
- __acornscsi_in(host->card.io_ram + (offset << 1), ptr, this_len);
|
|
|
+ __acornscsi_in(host->base + (offset << 1), ptr, this_len);
|
|
|
|
|
|
offset += this_len;
|
|
|
ptr += this_len;
|
|
@@ -935,10 +940,10 @@ void acornscsi_data_read(AS_Host *host, char *ptr,
|
|
|
if (offset == (1 << 12)) {
|
|
|
offset = 0;
|
|
|
page ++;
|
|
|
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
|
|
|
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
|
|
|
}
|
|
|
}
|
|
|
- outb(host->card.page_reg, host->card.io_page);
|
|
|
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -955,13 +960,13 @@ static
|
|
|
void acornscsi_data_write(AS_Host *host, char *ptr,
|
|
|
unsigned int start_addr, unsigned int length)
|
|
|
{
|
|
|
- extern void __acornscsi_out(int port, char *buf, int len);
|
|
|
+ extern void __acornscsi_out(void __iomem *, char *buf, int len);
|
|
|
unsigned int page, offset, len = length;
|
|
|
|
|
|
page = (start_addr >> 12);
|
|
|
offset = start_addr & ((1 << 12) - 1);
|
|
|
|
|
|
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
|
|
|
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
|
|
|
|
|
|
while (len > 0) {
|
|
|
unsigned int this_len;
|
|
@@ -971,7 +976,7 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
|
|
|
else
|
|
|
this_len = len;
|
|
|
|
|
|
- __acornscsi_out(host->card.io_ram + (offset << 1), ptr, this_len);
|
|
|
+ __acornscsi_out(host->base + (offset << 1), ptr, this_len);
|
|
|
|
|
|
offset += this_len;
|
|
|
ptr += this_len;
|
|
@@ -980,10 +985,10 @@ void acornscsi_data_write(AS_Host *host, char *ptr,
|
|
|
if (offset == (1 << 12)) {
|
|
|
offset = 0;
|
|
|
page ++;
|
|
|
- outb((page & 0x3f) | host->card.page_reg, host->card.io_page);
|
|
|
+ writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG);
|
|
|
}
|
|
|
}
|
|
|
- outb(host->card.page_reg, host->card.io_page);
|
|
|
+ writeb(host->card.page_reg, host->fast + PAGE_REG);
|
|
|
}
|
|
|
|
|
|
/* =========================================================================================
|
|
@@ -2468,11 +2473,11 @@ acornscsi_intr(int irq, void *dev_id)
|
|
|
do {
|
|
|
ret = INTR_IDLE;
|
|
|
|
|
|
- iostatus = inb(host->card.io_intr);
|
|
|
+ iostatus = readb(host->fast + INT_REG);
|
|
|
|
|
|
if (iostatus & 2) {
|
|
|
acornscsi_dma_intr(host);
|
|
|
- iostatus = inb(host->card.io_intr);
|
|
|
+ iostatus = readb(host->fast + INT_REG);
|
|
|
}
|
|
|
|
|
|
if (iostatus & 8)
|
|
@@ -2858,11 +2863,11 @@ int acornscsi_proc_info(struct Scsi_Host *instance, char *buffer, char **start,
|
|
|
#endif
|
|
|
"\n\n", VER_MAJOR, VER_MINOR, VER_PATCH);
|
|
|
|
|
|
- p += sprintf(p, "SBIC: WD33C93A Address: %08X IRQ : %d\n",
|
|
|
- host->scsi.io_port, host->scsi.irq);
|
|
|
+ p += sprintf(p, "SBIC: WD33C93A Address: %p IRQ : %d\n",
|
|
|
+ host->base + SBIC_REGIDX, host->scsi.irq);
|
|
|
#ifdef USE_DMAC
|
|
|
- p += sprintf(p, "DMAC: uPC71071 Address: %08X IRQ : %d\n\n",
|
|
|
- host->dma.io_port, host->scsi.irq);
|
|
|
+ p += sprintf(p, "DMAC: uPC71071 Address: %p IRQ : %d\n\n",
|
|
|
+ host->base + DMAC_OFFSET, host->scsi.irq);
|
|
|
#endif
|
|
|
|
|
|
p += sprintf(p, "Statistics:\n"
|
|
@@ -2964,48 +2969,37 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
|
|
|
{
|
|
|
struct Scsi_Host *host;
|
|
|
AS_Host *ashost;
|
|
|
- int ret = -ENOMEM;
|
|
|
+ int ret;
|
|
|
|
|
|
- host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
|
|
|
- if (!host)
|
|
|
+ ret = ecard_request_resources(ec);
|
|
|
+ if (ret)
|
|
|
goto out;
|
|
|
|
|
|
+ host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
|
|
|
+ if (!host) {
|
|
|
+ ret = -ENOMEM;
|
|
|
+ goto out_release;
|
|
|
+ }
|
|
|
+
|
|
|
ashost = (AS_Host *)host->hostdata;
|
|
|
|
|
|
- host->io_port = ecard_address(ec, ECARD_MEMC, 0);
|
|
|
- host->irq = ec->irq;
|
|
|
+ ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0);
|
|
|
+ ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0);
|
|
|
+ if (!ashost->base || !ashost->fast)
|
|
|
+ goto out_put;
|
|
|
|
|
|
- ashost->host = host;
|
|
|
- ashost->scsi.io_port = ioaddr(host->io_port + 0x800);
|
|
|
- ashost->scsi.irq = host->irq;
|
|
|
- ashost->card.io_intr = POD_SPACE(host->io_port) + 0x800;
|
|
|
- ashost->card.io_page = POD_SPACE(host->io_port) + 0xc00;
|
|
|
- ashost->card.io_ram = ioaddr(host->io_port);
|
|
|
- ashost->dma.io_port = host->io_port + 0xc00;
|
|
|
- ashost->dma.io_intr_clear = POD_SPACE(host->io_port) + 0x800;
|
|
|
+ host->irq = ec->irq;
|
|
|
+ ashost->host = host;
|
|
|
+ ashost->scsi.irq = host->irq;
|
|
|
|
|
|
- ec->irqaddr = (char *)ioaddr(ashost->card.io_intr);
|
|
|
+ ec->irqaddr = ashost->fast + INT_REG;
|
|
|
ec->irqmask = 0x0a;
|
|
|
|
|
|
- ret = -EBUSY;
|
|
|
- if (!request_region(host->io_port + 0x800, 2, "acornscsi(sbic)"))
|
|
|
- goto err_1;
|
|
|
- if (!request_region(ashost->card.io_intr, 1, "acornscsi(intr)"))
|
|
|
- goto err_2;
|
|
|
- if (!request_region(ashost->card.io_page, 1, "acornscsi(page)"))
|
|
|
- goto err_3;
|
|
|
-#ifdef USE_DMAC
|
|
|
- if (!request_region(ashost->dma.io_port, 256, "acornscsi(dmac)"))
|
|
|
- goto err_4;
|
|
|
-#endif
|
|
|
- if (!request_region(host->io_port, 2048, "acornscsi(ram)"))
|
|
|
- goto err_5;
|
|
|
-
|
|
|
ret = request_irq(host->irq, acornscsi_intr, IRQF_DISABLED, "acornscsi", ashost);
|
|
|
if (ret) {
|
|
|
printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n",
|
|
|
host->host_no, ashost->scsi.irq, ret);
|
|
|
- goto err_6;
|
|
|
+ goto out_put;
|
|
|
}
|
|
|
|
|
|
memset(&ashost->stats, 0, sizeof (ashost->stats));
|
|
@@ -3017,27 +3011,22 @@ acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
|
|
|
|
|
|
ret = scsi_add_host(host, &ec->dev);
|
|
|
if (ret)
|
|
|
- goto err_7;
|
|
|
+ goto out_irq;
|
|
|
|
|
|
scsi_scan_host(host);
|
|
|
goto out;
|
|
|
|
|
|
- err_7:
|
|
|
+ out_irq:
|
|
|
free_irq(host->irq, ashost);
|
|
|
- err_6:
|
|
|
- release_region(host->io_port, 2048);
|
|
|
- err_5:
|
|
|
-#ifdef USE_DMAC
|
|
|
- release_region(ashost->dma.io_port, 256);
|
|
|
-#endif
|
|
|
- err_4:
|
|
|
- release_region(ashost->card.io_page, 1);
|
|
|
- err_3:
|
|
|
- release_region(ashost->card.io_intr, 1);
|
|
|
- err_2:
|
|
|
- release_region(host->io_port + 0x800, 2);
|
|
|
- err_1:
|
|
|
+ msgqueue_free(&ashost->scsi.msgs);
|
|
|
+ queue_free(&ashost->queues.disconnected);
|
|
|
+ queue_free(&ashost->queues.issue);
|
|
|
+ out_put:
|
|
|
+ ecardm_iounmap(ec, ashost->fast);
|
|
|
+ ecardm_iounmap(ec, ashost->base);
|
|
|
scsi_host_put(host);
|
|
|
+ out_release:
|
|
|
+ ecard_release_resources(ec);
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|
|
@@ -3053,20 +3042,17 @@ static void __devexit acornscsi_remove(struct expansion_card *ec)
|
|
|
/*
|
|
|
* Put card into RESET state
|
|
|
*/
|
|
|
- outb(0x80, ashost->card.io_page);
|
|
|
+ writeb(0x80, ashost->fast + PAGE_REG);
|
|
|
|
|
|
free_irq(host->irq, ashost);
|
|
|
|
|
|
- release_region(host->io_port + 0x800, 2);
|
|
|
- release_region(ashost->card.io_intr, 1);
|
|
|
- release_region(ashost->card.io_page, 1);
|
|
|
- release_region(ashost->dma.io_port, 256);
|
|
|
- release_region(host->io_port, 2048);
|
|
|
-
|
|
|
msgqueue_free(&ashost->scsi.msgs);
|
|
|
queue_free(&ashost->queues.disconnected);
|
|
|
queue_free(&ashost->queues.issue);
|
|
|
+ ecardm_iounmap(ec, ashost->fast);
|
|
|
+ ecardm_iounmap(ec, ashost->base);
|
|
|
scsi_host_put(host);
|
|
|
+ ecard_release_resources(ec);
|
|
|
}
|
|
|
|
|
|
static const struct ecard_id acornscsi_cids[] = {
|