Commit 8b801ead authored by Russell King's avatar Russell King Committed by Russell King

[ARM] rpc: update Acorn SCSI drivers to modern ecard interfaces

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 13d5fadf
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define CUMANASCSI_PUBLIC_RELEASE 1 #define CUMANASCSI_PUBLIC_RELEASE 1
#define NCR5380_implementation_fields int port, ctrl #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_local_declare() struct Scsi_Host *_instance #define NCR5380_local_declare() struct Scsi_Host *_instance
#define NCR5380_setup(instance) _instance = instance #define NCR5380_setup(instance) _instance = instance
#define NCR5380_read(reg) cumanascsi_read(_instance, reg) #define NCR5380_read(reg) cumanascsi_read(_instance, reg)
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
#define NCR5380_queue_command cumanascsi_queue_command #define NCR5380_queue_command cumanascsi_queue_command
#define NCR5380_proc_info cumanascsi_proc_info #define NCR5380_proc_info cumanascsi_proc_info
#define NCR5380_implementation_fields \
unsigned ctrl; \
void __iomem *base; \
void __iomem *dma
#define BOARD_NORMAL 0 #define BOARD_NORMAL 0
#define BOARD_NCR53C400 1 #define BOARD_NCR53C400 1
...@@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt) ...@@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt)
return ""; return "";
} }
#ifdef NOT_EFFICIENT #define CTRL 0x16fc
#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) #define STAT 0x2004
#define STAT(p) inb((p)+1) #define L(v) (((v)<<16)|((v) & 0x0000ffff))
#define IN(p) inb((p)) #define H(v) (((v)>>16)|((v) & 0xffff0000))
#define OUT(v,p) outb((v), (p))
#else
#define CTRL(p,v) (p[-2308] = (*ctrl = (v)))
#define STAT(p) (p[4])
#define IN(p) (*(p))
#define IN2(p) ((unsigned short)(*(volatile unsigned long *)(p)))
#define OUT(v,p) (*(p) = (v))
#define OUT2(v,p) (*((volatile unsigned long *)(p)) = (v))
#endif
#define L(v) (((v)<<16)|((v) & 0x0000ffff))
#define H(v) (((v)>>16)|((v) & 0xffff0000))
static inline int static inline int
NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, int len) NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr, int len)
{ {
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
int oldctrl = *ctrl;
unsigned long *laddr; unsigned long *laddr;
#ifdef NOT_EFFICIENT void __iomem *dma = priv(host)->dma + 0x2000;
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; if(!len) return 0;
CTRL(iobase, 0x02); writeb(0x02, priv(host)->base + CTRL);
laddr = (unsigned long *)addr; laddr = (unsigned long *)addr;
while(len >= 32) while(len >= 32)
{ {
int status; unsigned int status;
unsigned long v; unsigned long v;
status = STAT(iobase); status = readb(priv(host)->base + STAT);
if(status & 0x80) if(status & 0x80)
goto end; goto end;
if(!(status & 0x40)) if(!(status & 0x40))
continue; continue;
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io); v=*laddr++; writew(L(v), dma); writew(H(v), dma);
len -= 32; len -= 32;
if(len == 0) if(len == 0)
break; break;
} }
addr = (unsigned char *)laddr; addr = (unsigned char *)laddr;
CTRL(iobase, 0x12); writeb(0x12, priv(host)->base + CTRL);
while(len > 0) while(len > 0)
{ {
int status; unsigned int status;
status = STAT(iobase); status = readb(priv(host)->base + STAT);
if(status & 0x80) if(status & 0x80)
goto end; goto end;
if(status & 0x40) if(status & 0x40)
{ {
OUT(*addr++, dma_io); writeb(*addr++, dma);
if(--len == 0) if(--len == 0)
break; break;
} }
status = STAT(iobase); status = readb(priv(host)->base + STAT);
if(status & 0x80) if(status & 0x80)
goto end; goto end;
if(status & 0x40) if(status & 0x40)
{ {
OUT(*addr++, dma_io); writeb(*addr++, dma);
if(--len == 0) if(--len == 0)
break; break;
} }
} }
end: end:
CTRL(iobase, oldctrl|0x40); writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
return len; return len;
} }
static inline int static inline int
NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, int len) NCR5380_pread(struct Scsi_Host *host, unsigned char *addr, int len)
{ {
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
int oldctrl = *ctrl;
unsigned long *laddr; unsigned long *laddr;
#ifdef NOT_EFFICIENT void __iomem *dma = priv(host)->dma + 0x2000;
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; if(!len) return 0;
CTRL(iobase, 0x00); writeb(0x00, priv(host)->base + CTRL);
laddr = (unsigned long *)addr; laddr = (unsigned long *)addr;
while(len >= 32) while(len >= 32)
{ {
int status; unsigned int status;
status = STAT(iobase); status = readb(priv(host)->base + STAT);
if(status & 0x80) if(status & 0x80)
goto end; goto end;
if(!(status & 0x40)) if(!(status & 0x40))
continue; continue;
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
*laddr++ = IN2(dma_io)|(IN2(dma_io)<<16); *laddr++ = readw(dma) | (readw(dma) << 16);
len -= 32; len -= 32;
if(len == 0) if(len == 0)
break; break;
} }
addr = (unsigned char *)laddr; addr = (unsigned char *)laddr;
CTRL(iobase, 0x10); writeb(0x10, priv(host)->base + CTRL);
while(len > 0) while(len > 0)
{ {
int status; unsigned int status;
status = STAT(iobase); status = readb(priv(host)->base + STAT);
if(status & 0x80) if(status & 0x80)
goto end; goto end;
if(status & 0x40) if(status & 0x40)
{ {
*addr++ = IN(dma_io); *addr++ = readb(dma);
if(--len == 0) if(--len == 0)
break; break;
} }
status = STAT(iobase); status = readb(priv(host)->base + STAT);
if(status & 0x80) if(status & 0x80)
goto end; goto end;
if(status & 0x40) if(status & 0x40)
{ {
*addr++ = IN(dma_io); *addr++ = readb(dma);
if(--len == 0) if(--len == 0)
break; break;
} }
} }
end: end:
CTRL(iobase, oldctrl|0x40); writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
return len; return len;
} }
#undef STAT static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
#undef CTRL {
#undef IN void __iomem *base = priv(host)->base;
#undef OUT unsigned char val;
#define CTRL(p,v) outb(*ctrl = (v), (p) - 577) writeb(0, base + CTRL);
static char cumanascsi_read(struct Scsi_Host *instance, int reg) val = readb(base + 0x2100 + (reg << 2));
{
unsigned int iobase = instance->io_port;
int i;
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
CTRL(iobase, 0); priv(host)->ctrl = 0x40;
i = inb(iobase + 64 + reg); writeb(0x40, base + CTRL);
CTRL(iobase, 0x40);
return i; return val;
} }
static void cumanascsi_write(struct Scsi_Host *instance, int reg, int value) static void cumanascsi_write(struct Scsi_Host *host, unsigned int reg, unsigned int value)
{ {
int iobase = instance->io_port; void __iomem *base = priv(host)->base;
int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
CTRL(iobase, 0); writeb(0, base + CTRL);
outb(value, iobase + 64 + reg);
CTRL(iobase, 0x40);
}
#undef CTRL writeb(value, base + 0x2100 + (reg << 2));
priv(host)->ctrl = 0x40;
writeb(0x40, base + CTRL);
}
#include "../NCR5380.c" #include "../NCR5380.c"
...@@ -256,32 +231,46 @@ static int __devinit ...@@ -256,32 +231,46 @@ static int __devinit
cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
{ {
struct Scsi_Host *host; struct Scsi_Host *host;
int ret = -ENOMEM; int ret;
host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata)); ret = ecard_request_resources(ec);
if (!host) if (ret)
goto out; goto out;
host->io_port = ecard_address(ec, ECARD_IOC, ECARD_SLOW) + 0x800; host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
if (!host) {
ret = -ENOMEM;
goto out_release;
}
priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
ecard_resource_len(ec, ECARD_RES_IOCSLOW));
priv(host)->dma = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
ecard_resource_len(ec, ECARD_RES_MEMC));
if (!priv(host)->base || !priv(host)->dma) {
ret = -ENOMEM;
goto out_unmap;
}
host->irq = ec->irq; host->irq = ec->irq;
NCR5380_init(host, 0); NCR5380_init(host, 0);
priv(host)->ctrl = 0;
writeb(0, priv(host)->base + CTRL);
host->n_io_port = 255; host->n_io_port = 255;
if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) { if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
ret = -EBUSY; ret = -EBUSY;
goto out_free; goto out_unmap;
} }
((struct NCR5380_hostdata *)host->hostdata)->ctrl = 0;
outb(0x00, host->io_port - 577);
ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED, ret = request_irq(host->irq, cumanascsi_intr, IRQF_DISABLED,
"CumanaSCSI-1", host); "CumanaSCSI-1", host);
if (ret) { if (ret) {
printk("scsi%d: IRQ%d not free: %d\n", printk("scsi%d: IRQ%d not free: %d\n",
host->host_no, host->irq, ret); host->host_no, host->irq, ret);
goto out_release; goto out_unmap;
} }
printk("scsi%d: at port 0x%08lx irq %d", printk("scsi%d: at port 0x%08lx irq %d",
...@@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
out_free_irq: out_free_irq:
free_irq(host->irq, host); free_irq(host->irq, host);
out_release: out_unmap:
release_region(host->io_port, host->n_io_port); iounmap(priv(host)->base);
out_free: iounmap(priv(host)->dma);
scsi_host_put(host); scsi_host_put(host);
out_release:
ecard_release_resources(ec);
out: out:
return ret; return ret;
} }
...@@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec) ...@@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec)
scsi_remove_host(host); scsi_remove_host(host);
free_irq(host->irq, host); free_irq(host->irq, host);
NCR5380_exit(host); NCR5380_exit(host);
release_region(host->io_port, host->n_io_port); iounmap(priv(host)->base);
iounmap(priv(host)->dma);
scsi_host_put(host); scsi_host_put(host);
ecard_release_resources(ec);
} }
static const struct ecard_id cumanascsi1_cids[] = { static const struct ecard_id cumanascsi1_cids[] = {
......
...@@ -34,35 +34,25 @@ ...@@ -34,35 +34,25 @@
#include "../scsi.h" #include "../scsi.h"
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#define NCR5380_implementation_fields int port, ctrl #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_local_declare() struct Scsi_Host *_instance
#define NCR5380_setup(instance) _instance = instance
#define NCR5380_read(reg) ecoscsi_read(_instance, reg) #define NCR5380_local_declare() void __iomem *_base
#define NCR5380_write(reg, value) ecoscsi_write(_instance, reg, value) #define NCR5380_setup(host) _base = priv(host)->base
#define NCR5380_read(reg) ({ writeb(reg | 8, _base); readb(_base + 4); })
#define NCR5380_write(reg, value) ({ writeb(reg | 8, _base); writeb(value, _base + 4); })
#define NCR5380_intr ecoscsi_intr #define NCR5380_intr ecoscsi_intr
#define NCR5380_queue_command ecoscsi_queue_command #define NCR5380_queue_command ecoscsi_queue_command
#define NCR5380_proc_info ecoscsi_proc_info #define NCR5380_proc_info ecoscsi_proc_info
#define NCR5380_implementation_fields \
void __iomem *base
#include "../NCR5380.h" #include "../NCR5380.h"
#define ECOSCSI_PUBLIC_RELEASE 1 #define ECOSCSI_PUBLIC_RELEASE 1
static char ecoscsi_read(struct Scsi_Host *instance, int reg)
{
int iobase = instance->io_port;
outb(reg | 8, iobase);
return inb(iobase + 1);
}
static void ecoscsi_write(struct Scsi_Host *instance, int reg, int value)
{
int iobase = instance->io_port;
outb(reg | 8, iobase);
outb(value, iobase + 1);
}
/* /*
* Function : ecoscsi_setup(char *str, int *ints) * Function : ecoscsi_setup(char *str, int *ints)
* *
...@@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt) ...@@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt)
return ""; return "";
} }
#if 0
#define STAT(p) inw(p + 144)
static inline int NCR5380_pwrite(struct Scsi_Host *host, unsigned char *addr,
int len)
{
int iobase = host->io_port;
printk("writing %p len %d\n",addr, len);
if(!len) return -1;
while(1)
{
int status;
while(((status = STAT(iobase)) & 0x100)==0);
}
}
static inline int NCR5380_pread(struct Scsi_Host *host, unsigned char *addr,
int len)
{
int iobase = host->io_port;
int iobase2= host->io_port + 0x100;
unsigned char *start = addr;
int s;
printk("reading %p len %d\n",addr, len);
outb(inb(iobase + 128), iobase + 135);
while(len > 0)
{
int status,b,i, timeout;
timeout = 0x07FFFFFF;
while(((status = STAT(iobase)) & 0x100)==0)
{
timeout--;
if(status & 0x200 || !timeout)
{
printk("status = %p\n",status);
outb(0, iobase + 135);
return 1;
}
}
if(len >= 128)
{
for(i=0; i<64; i++)
{
b = inw(iobase + 136);
*addr++ = b;
*addr++ = b>>8;
}
len -= 128;
}
else
{
b = inw(iobase + 136);
*addr ++ = b;
len -= 1;
if(len)
*addr ++ = b>>8;
len -= 1;
}
}
outb(0, iobase + 135);
printk("first bytes = %02X %02X %02X %20X %02X %02X %02X\n",*start, start[1], start[2], start[3], start[4], start[5], start[6]);
return 1;
}
#endif
#undef STAT
#define BOARD_NORMAL 0 #define BOARD_NORMAL 0
#define BOARD_NCR53C400 1 #define BOARD_NCR53C400 1
...@@ -173,25 +96,36 @@ static struct Scsi_Host *host; ...@@ -173,25 +96,36 @@ static struct Scsi_Host *host;
static int __init ecoscsi_init(void) static int __init ecoscsi_init(void)
{ {
void __iomem *_base;
int ret;
host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) {
if (!host) ret = -EBUSY;
return 0; goto out;
}
host->io_port = 0x80ce8000; _base = ioremap(0x33a0000, 4096);
host->n_io_port = 144; if (!_base) {
host->irq = IRQ_NONE; ret = -ENOMEM;
goto out_release;
}
if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) ) NCR5380_write(MODE_REG, 0x20); /* Is it really SCSI? */
goto unregister_scsi; if (NCR5380_read(MODE_REG) != 0x20) /* Write to a reg. */
goto out_unmap;
ecoscsi_write(host, MODE_REG, 0x20); /* Is it really SCSI? */ NCR5380_write(MODE_REG, 0x00); /* it back. */
if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg. */ if (NCR5380_read(MODE_REG) != 0x00)
goto release_reg; goto out_unmap;
ecoscsi_write(host, MODE_REG, 0x00 ); /* it back. */ host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
if (ecoscsi_read(host, MODE_REG) != 0x00) if (!host) {
goto release_reg; ret = -ENOMEM;
goto out_unmap;
}
priv(host)->base = _base;
host->irq = IRQ_NONE;
NCR5380_init(host, 0); NCR5380_init(host, 0);
...@@ -206,24 +140,20 @@ static int __init ecoscsi_init(void) ...@@ -206,24 +140,20 @@ static int __init ecoscsi_init(void)
scsi_scan_host(host); scsi_scan_host(host);
return 0; return 0;
release_reg: out_unmap:
release_region(host->io_port, host->n_io_port); iounmap(_base);
unregister_scsi: out_release:
scsi_host_put(host); release_mem_region(0x33a0000, 4096);
return -ENODEV; out:
return ret;
} }
static void __exit ecoscsi_exit(void) static void __exit ecoscsi_exit(void)
{ {
scsi_remove_host(host); scsi_remove_host(host);
if (shpnt->irq != IRQ_NONE)
free_irq(shpnt->irq, NULL);
NCR5380_exit(host); NCR5380_exit(host);
if (shpnt->io_port)
release_region(shpnt->io_port, shpnt->n_io_port);
scsi_host_put(host); scsi_host_put(host);
release_mem_region(0x33a0000, 4096);
return 0; return 0;
} }
......
...@@ -23,15 +23,18 @@ ...@@ -23,15 +23,18 @@
#define OAKSCSI_PUBLIC_RELEASE 1 #define OAKSCSI_PUBLIC_RELEASE 1
#define NCR5380_read(reg) oakscsi_read(_instance, reg) #define priv(host) ((struct NCR5380_hostdata *)(host)->hostdata)
#define NCR5380_write(reg, value) oakscsi_write(_instance, reg, value) #define NCR5380_local_declare() void __iomem *_base
#define NCR5380_setup(host) _base = priv(host)->base
#define NCR5380_read(reg) readb(_base + ((reg) << 2))
#define NCR5380_write(reg, value) writeb(value, _base + ((reg) << 2))
#define NCR5380_intr oakscsi_intr #define NCR5380_intr oakscsi_intr
#define NCR5380_queue_command oakscsi_queue_command #define NCR5380_queue_command oakscsi_queue_command
#define NCR5380_proc_info oakscsi_proc_info #define NCR5380_proc_info oakscsi_proc_info
#define NCR5380_implementation_fields int port, ctrl #define NCR5380_implementation_fields \
#define NCR5380_local_declare() struct Scsi_Host *_instance void __iomem *base
#define NCR5380_setup(instance) _instance = instance
#define BOARD_NORMAL 0 #define BOARD_NORMAL 0
#define BOARD_NCR53C400 1 #define BOARD_NCR53C400 1
...@@ -39,60 +42,62 @@ ...@@ -39,60 +42,62 @@
#include "../NCR5380.h" #include "../NCR5380.h"
#undef START_DMA_INITIATOR_RECEIVE_REG #undef START_DMA_INITIATOR_RECEIVE_REG
#define START_DMA_INITIATOR_RECEIVE_REG (7 + 128) #define START_DMA_INITIATOR_RECEIVE_REG (128 + 7)
const char * oakscsi_info (struct Scsi_Host *spnt) const char * oakscsi_info (struct Scsi_Host *spnt)
{ {
return ""; return "";
} }
#define STAT(p) inw(p + 144) #define STAT ((128 + 16) << 2)
extern void inswb(int from, void *to, int len); #define DATA ((128 + 8) << 2)
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr, static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
int len) int len)
{ {
int iobase = instance->io_port; void __iomem *base = priv(instance)->base;
printk("writing %p len %d\n",addr, len); printk("writing %p len %d\n",addr, len);
if(!len) return -1; if(!len) return -1;
while(1) while(1)
{ {
int status; int status;
while(((status = STAT(iobase)) & 0x100)==0); while (((status = readw(base + STAT)) & 0x100)==0);
} }
} }
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr, static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *addr,
int len) int len)
{ {
int iobase = instance->io_port; void __iomem *base = priv(instance)->base;
printk("reading %p len %d\n", addr, len); printk("reading %p len %d\n", addr, len);
while(len > 0) while(len > 0)
{ {
int status, timeout; unsigned int status, timeout;
unsigned long b; unsigned long b;
timeout = 0x01FFFFFF; timeout = 0x01FFFFFF;
while(((status = STAT(iobase)) & 0x100)==0) while (((status = readw(base + STAT)) & 0x100)==0)
{ {
timeout--; timeout--;
if(status & 0x200 || !timeout) if(status & 0x200 || !timeout)
{ {
printk("status = %08X\n",status); printk("status = %08X\n", status);
return 1; return 1;
} }
} }
if(len >= 128) if(len >= 128)
{ {
inswb(iobase + 136, addr, 128); readsw(base + DATA, addr, 128);
addr += 128; addr += 128;
len -= 128; len -= 128;
} }
else else
{ {
b = (unsigned long) inw(iobase + 136); b = (unsigned long) readw(base + DATA);
*addr ++ = b; *addr ++ = b;
len -= 1; len -= 1;
if(len) if(len)
...@@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len); ...@@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len);
return 0; return 0;
} }
#define oakscsi_read(instance,reg) (inb((instance)->io_port + (reg)))
#define oakscsi_write(instance,reg,val) (outb((val), (instance)->io_port + (reg)))
#undef STAT #undef STAT
#undef DATA
#include "../NCR5380.c" #include "../NCR5380.c"
...@@ -132,18 +135,26 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -132,18 +135,26 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
struct Scsi_Host *host; struct Scsi_Host *host;
int ret = -ENOMEM; int ret = -ENOMEM;
host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata)); ret = ecard_request_resources(ec);
if (!host) if (ret)
goto out; goto out;
host->io_port = ecard_address(ec, ECARD_MEMC, 0); host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
if (!host) {
ret = -ENOMEM;
goto release;
}
priv(host)->base = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
ecard_resource_len(ec, ECARD_RES_MEMC));
if (!priv(host)->base) {
ret = -ENOMEM;
goto unreg;
}
host->irq = IRQ_NONE; host->irq = IRQ_NONE;
host->n_io_port = 255; host->n_io_port = 255;
ret = -EBUSY;
if (!request_region (host->io_port, host->n_io_port, "Oak SCSI"))
goto unreg;
NCR5380_init(host, 0); NCR5380_init(host, 0);
printk("scsi%d: at port 0x%08lx irqs disabled", printk("scsi%d: at port 0x%08lx irqs disabled",
...@@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id) ...@@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
ret = scsi_add_host(host, &ec->dev); ret = scsi_add_host(host, &ec->dev);
if (ret) if (ret)
goto out_release; goto out_unmap;
scsi_scan_host(host); scsi_scan_host(host);
goto out; goto out;
out_release: out_unmap:
release_region(host->io_port, host->n_io_port); iounmap(priv(host)->base);
unreg: unreg:
scsi_host_put(host); scsi_host_put(host);
release:
ecard_release_resources(ec);
out: out:
return ret; return ret;
} }
...@@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec) ...@@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec)
scsi_remove_host(host); scsi_remove_host(host);
NCR5380_exit(host); NCR5380_exit(host);
release_region(host->io_port, host->n_io_port); iounmap(priv(host)->base);
scsi_host_put(host); scsi_host_put(host);
ecard_release_resources(ec);
} }
static const struct ecard_id oakscsi_cids[] = { static const struct ecard_id oakscsi_cids[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment