Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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

parent 13d5fadf
Loading
Loading
Loading
Loading
+100 −107
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

#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_setup(instance)		_instance = instance
#define NCR5380_read(reg)		cumanascsi_read(_instance, reg)
@@ -33,6 +33,11 @@
#define NCR5380_queue_command		cumanascsi_queue_command
#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_NCR53C400	1

@@ -47,192 +52,162 @@ const char *cumanascsi_info(struct Scsi_Host *spnt)
	return "";
}

#ifdef NOT_EFFICIENT
#define CTRL(p,v)     outb(*ctrl = (v), (p) - 577)
#define STAT(p)       inb((p)+1)
#define IN(p)         inb((p))
#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 CTRL	0x16fc
#define STAT	0x2004
#define L(v)	(((v)<<16)|((v) & 0x0000ffff))
#define H(v)	(((v)>>16)|((v) & 0xffff0000))

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;
#ifdef NOT_EFFICIENT
  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
  void __iomem *dma = priv(host)->dma + 0x2000;

  if(!len) return 0;

  CTRL(iobase, 0x02);
  writeb(0x02, priv(host)->base + CTRL);
  laddr = (unsigned long *)addr;
  while(len >= 32)
  {
    int status;
    unsigned int status;
    unsigned long v;
    status = STAT(iobase);
    status = readb(priv(host)->base + STAT);
    if(status & 0x80)
      goto end;
    if(!(status & 0x40))
      continue;
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; OUT2(L(v),dma_io); OUT2(H(v),dma_io);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    v=*laddr++; writew(L(v), dma); writew(H(v), dma);
    len -= 32;
    if(len == 0)
      break;
  }

  addr = (unsigned char *)laddr;
  CTRL(iobase, 0x12);
  writeb(0x12, priv(host)->base + CTRL);

  while(len > 0)
  {
    int status;
    status = STAT(iobase);
    unsigned int status;
    status = readb(priv(host)->base + STAT);
    if(status & 0x80)
      goto end;
    if(status & 0x40)
    {
      OUT(*addr++, dma_io);
      writeb(*addr++, dma);
      if(--len == 0)
        break;
    }

    status = STAT(iobase);
    status = readb(priv(host)->base + STAT);
    if(status & 0x80)
      goto end;
    if(status & 0x40)
    {
      OUT(*addr++, dma_io);
      writeb(*addr++, dma);
      if(--len == 0)
        break;
    }
  }
end:
  CTRL(iobase, oldctrl|0x40);
  writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
  return len;
}

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;
#ifdef NOT_EFFICIENT
  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
  void __iomem *dma = priv(host)->dma + 0x2000;

  if(!len) return 0;

  CTRL(iobase, 0x00);
  writeb(0x00, priv(host)->base + CTRL);
  laddr = (unsigned long *)addr;
  while(len >= 32)
  {
    int status;
    status = STAT(iobase);
    unsigned int status;
    status = readb(priv(host)->base + STAT);
    if(status & 0x80)
      goto end;
    if(!(status & 0x40))
      continue;
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = IN2(dma_io)|(IN2(dma_io)<<16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    *laddr++ = readw(dma) | (readw(dma) << 16);
    len -= 32;
    if(len == 0)
      break;
  }

  addr = (unsigned char *)laddr;
  CTRL(iobase, 0x10);
  writeb(0x10, priv(host)->base + CTRL);

  while(len > 0)
  {
    int status;
    status = STAT(iobase);
    unsigned int status;
    status = readb(priv(host)->base + STAT);
    if(status & 0x80)
      goto end;
    if(status & 0x40)
    {
      *addr++ = IN(dma_io);
      *addr++ = readb(dma);
      if(--len == 0)
        break;
    }

    status = STAT(iobase);
    status = readb(priv(host)->base + STAT);
    if(status & 0x80)
      goto end;
    if(status & 0x40)
    {
      *addr++ = IN(dma_io);
      *addr++ = readb(dma);
      if(--len == 0)
        break;
    }
  }
end:
  CTRL(iobase, oldctrl|0x40);
  writeb(priv(host)->ctrl | 0x40, priv(host)->base + CTRL);
  return len;
}

#undef STAT
#undef CTRL
#undef IN
#undef OUT
static unsigned char cumanascsi_read(struct Scsi_Host *host, unsigned int reg)
{
	void __iomem *base = priv(host)->base;
	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)
{
	unsigned int iobase = instance->io_port;
	int i;
	int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
	val = readb(base + 0x2100 + (reg << 2));

	CTRL(iobase, 0);
	i = inb(iobase + 64 + reg);
	CTRL(iobase, 0x40);
	priv(host)->ctrl = 0x40;
	writeb(0x40, base + CTRL);

	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;
	int *ctrl = &((struct NCR5380_hostdata *)instance->hostdata)->ctrl;
	void __iomem *base = priv(host)->base;

	CTRL(iobase, 0);
	outb(value, iobase + 64 + reg);
	CTRL(iobase, 0x40);
}
	writeb(0, base + CTRL);

#undef CTRL
	writeb(value, base + 0x2100 + (reg << 2));

	priv(host)->ctrl = 0x40;
	writeb(0x40, base + CTRL);
}

#include "../NCR5380.c"

@@ -256,32 +231,46 @@ static int __devinit
cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	struct Scsi_Host *host;
	int ret = -ENOMEM;
	int ret;

	host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
	if (!host)
	ret = ecard_request_resources(ec);
	if (ret)
		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;

	NCR5380_init(host, 0);

        priv(host)->ctrl = 0;
        writeb(0, priv(host)->base + CTRL);

	host->n_io_port = 255;
	if (!(request_region(host->io_port, host->n_io_port, "CumanaSCSI-1"))) {
		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,
			  "CumanaSCSI-1", host);
	if (ret) {
		printk("scsi%d: IRQ%d not free: %d\n",
		    host->host_no, host->irq, ret);
		goto out_release;
		goto out_unmap;
	}

	printk("scsi%d: at port 0x%08lx irq %d",
@@ -301,10 +290,12 @@ cumanascsi1_probe(struct expansion_card *ec, const struct ecard_id *id)

 out_free_irq:
	free_irq(host->irq, host);
 out_release:
	release_region(host->io_port, host->n_io_port);
 out_free:
 out_unmap:
	iounmap(priv(host)->base);
	iounmap(priv(host)->dma);
	scsi_host_put(host);
 out_release:
	ecard_release_resources(ec);
 out:
	return ret;
}
@@ -318,8 +309,10 @@ static void __devexit cumanascsi1_remove(struct expansion_card *ec)
	scsi_remove_host(host);
	free_irq(host->irq, 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);
	ecard_release_resources(ec);
}

static const struct ecard_id cumanascsi1_cids[] = {
+41 −111
Original line number Diff line number Diff line
@@ -34,35 +34,25 @@
#include "../scsi.h"
#include <scsi/scsi_host.h>

#define NCR5380_implementation_fields	int port, ctrl
#define NCR5380_local_declare()		struct Scsi_Host *_instance
#define NCR5380_setup(instance)		_instance = instance
#define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)

#define NCR5380_read(reg)		ecoscsi_read(_instance, reg)
#define NCR5380_write(reg, value)	ecoscsi_write(_instance, reg, value)
#define NCR5380_local_declare()		void __iomem *_base
#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_queue_command		ecoscsi_queue_command
#define NCR5380_proc_info		ecoscsi_proc_info

#define NCR5380_implementation_fields	\
	void __iomem *base

#include "../NCR5380.h"

#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)
 *
@@ -82,73 +72,6 @@ const char * ecoscsi_info (struct Scsi_Host *spnt)
	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_NCR53C400	1

@@ -173,25 +96,36 @@ static struct Scsi_Host *host;

static int __init ecoscsi_init(void)
{
	void __iomem *_base;
	int ret;

	host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
	if (!host)
		return 0;
	if (!request_mem_region(0x33a0000, 4096, "ecoscsi")) {
		ret = -EBUSY;
		goto out;
	}

	host->io_port = 0x80ce8000;
	host->n_io_port = 144;
	host->irq = IRQ_NONE;
	_base = ioremap(0x33a0000, 4096);
	if (!_base) {
		ret = -ENOMEM;
		goto out_release;
	}

	if (!(request_region(host->io_port, host->n_io_port, "ecoscsi")) )
		goto unregister_scsi;
	NCR5380_write(MODE_REG, 0x20);		/* Is it really SCSI? */
	if (NCR5380_read(MODE_REG) != 0x20)	/* Write to a reg.    */
		goto out_unmap;

	ecoscsi_write(host, MODE_REG, 0x20);		/* Is it really SCSI? */
	if (ecoscsi_read(host, MODE_REG) != 0x20) /* Write to a reg.    */
		goto release_reg;
	NCR5380_write(MODE_REG, 0x00);		/* it back.	      */
	if (NCR5380_read(MODE_REG) != 0x00)
		goto out_unmap;

	host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
	if (!host) {
		ret = -ENOMEM;
		goto out_unmap;
	}

	ecoscsi_write(host, MODE_REG, 0x00 );		/* it back.	      */
	if (ecoscsi_read(host, MODE_REG) != 0x00)
		goto release_reg;
	priv(host)->base = _base;
	host->irq = IRQ_NONE;

	NCR5380_init(host, 0);

@@ -206,24 +140,20 @@ static int __init ecoscsi_init(void)
	scsi_scan_host(host);
	return 0;

release_reg:
	release_region(host->io_port, host->n_io_port);
unregister_scsi:
	scsi_host_put(host);
	return -ENODEV;
 out_unmap:
	iounmap(_base);
 out_release:
	release_mem_region(0x33a0000, 4096);
 out:
	return ret;
}

static void __exit ecoscsi_exit(void)
{
	scsi_remove_host(host);

	if (shpnt->irq != IRQ_NONE)
		free_irq(shpnt->irq, NULL);
	NCR5380_exit(host);
	if (shpnt->io_port)
		release_region(shpnt->io_port, shpnt->n_io_port);

	scsi_host_put(host);
	release_mem_region(0x33a0000, 4096);
	return 0;
}

+44 −30
Original line number Diff line number Diff line
@@ -23,15 +23,18 @@

#define OAKSCSI_PUBLIC_RELEASE 1

#define NCR5380_read(reg)		oakscsi_read(_instance, reg)
#define NCR5380_write(reg, value)	oakscsi_write(_instance, reg, value)
#define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
#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_queue_command		oakscsi_queue_command
#define NCR5380_proc_info		oakscsi_proc_info

#define NCR5380_implementation_fields	int port, ctrl
#define NCR5380_local_declare()		struct Scsi_Host *_instance
#define NCR5380_setup(instance)		_instance = instance
#define NCR5380_implementation_fields	\
	void __iomem *base

#define BOARD_NORMAL	0
#define BOARD_NCR53C400	1
@@ -39,43 +42,44 @@
#include "../NCR5380.h"

#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)
{
	return "";
}

#define STAT(p)   inw(p + 144)
extern void inswb(int from, void *to, int len);
#define STAT	((128 + 16) << 2)
#define DATA	((128 + 8) << 2)

static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *addr,
              int len)
{
  int iobase = instance->io_port;
  void __iomem *base = priv(instance)->base;

printk("writing %p len %d\n",addr, len);
  if(!len) return -1;

  while(1)
  {
    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,
              int len)
{
  int iobase = instance->io_port;
  void __iomem *base = priv(instance)->base;
printk("reading %p len %d\n", addr, len);
  while(len > 0)
  {
    int status, timeout;
    unsigned int status, timeout;
    unsigned long b;
    
    timeout = 0x01FFFFFF;
    
    while(((status = STAT(iobase)) & 0x100)==0)
    while (((status = readw(base + STAT)) & 0x100)==0)
    {
      timeout--;
      if(status & 0x200 || !timeout)
@@ -84,15 +88,16 @@ printk("reading %p len %d\n", addr, len);
        return 1;
      }
    }

    if(len >= 128)
    {
      inswb(iobase + 136, addr, 128);
      readsw(base + DATA, addr, 128);
      addr += 128;
      len -= 128;
    }
    else
    {
      b = (unsigned long) inw(iobase + 136);
      b = (unsigned long) readw(base + DATA);
      *addr ++ = b;
      len -= 1;
      if(len)
@@ -103,10 +108,8 @@ printk("reading %p len %d\n", addr, len);
  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 DATA

#include "../NCR5380.c"

@@ -132,17 +135,25 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
	struct Scsi_Host *host;
	int ret = -ENOMEM;

	host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
	if (!host)
	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	host->io_port = ecard_address(ec, ECARD_MEMC, 0);
	host->irq = IRQ_NONE;
	host->n_io_port = 255;
	host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
	if (!host) {
		ret = -ENOMEM;
		goto release;
	}

	ret = -EBUSY;
	if (!request_region (host->io_port, host->n_io_port, "Oak SCSI"))
	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->n_io_port = 255;

	NCR5380_init(host, 0);

@@ -156,15 +167,17 @@ oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)

	ret = scsi_add_host(host, &ec->dev);
	if (ret)
		goto out_release;
		goto out_unmap;

	scsi_scan_host(host);
	goto out;

 out_release:
	release_region(host->io_port, host->n_io_port);
 out_unmap:
	iounmap(priv(host)->base);
 unreg:
	scsi_host_put(host);
 release:
	ecard_release_resources(ec);
 out:
	return ret;
}
@@ -177,8 +190,9 @@ static void __devexit oakscsi_remove(struct expansion_card *ec)
	scsi_remove_host(host);

	NCR5380_exit(host);
	release_region(host->io_port, host->n_io_port);
	iounmap(priv(host)->base);
	scsi_host_put(host);
	ecard_release_resources(ec);
}

static const struct ecard_id oakscsi_cids[] = {