Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Generic Generic NCR5380 driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright 1995-2002, Russell King
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/ecard.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define priv(host)			((struct NCR5380_hostdata *)(host)->hostdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define NCR5380_read(reg)		cumanascsi_read(hostdata, reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define NCR5380_write(reg, value)	cumanascsi_write(hostdata, reg, value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define NCR5380_dma_xfer_len		cumanascsi_dma_xfer_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define NCR5380_dma_recv_setup		cumanascsi_pread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define NCR5380_dma_send_setup		cumanascsi_pwrite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define NCR5380_dma_residual		NCR5380_dma_residual_none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define NCR5380_intr			cumanascsi_intr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define NCR5380_queue_command		cumanascsi_queue_command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define NCR5380_info			cumanascsi_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define NCR5380_implementation_fields	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	unsigned ctrl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) struct NCR5380_hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) static u8 cumanascsi_read(struct NCR5380_hostdata *, unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static void cumanascsi_write(struct NCR5380_hostdata *, unsigned int, u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include "../NCR5380.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define CTRL	0x16fc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define STAT	0x2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define L(v)	(((v)<<16)|((v) & 0x0000ffff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define H(v)	(((v)>>16)|((v) & 0xffff0000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static inline int cumanascsi_pwrite(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45)                                     unsigned char *addr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47)   unsigned long *laddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48)   u8 __iomem *base = hostdata->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)   u8 __iomem *dma = hostdata->pdma_io + 0x2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)   if(!len) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)   writeb(0x02, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)   laddr = (unsigned long *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)   while(len >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)     unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58)     unsigned long v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59)     status = readb(base + STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)     if(status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)       goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)     if(!(status & 0x40))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)       continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)     v=*laddr++; writew(L(v), dma); writew(H(v), dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)     len -= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)     if(len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)   addr = (unsigned char *)laddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)   writeb(0x12, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)   while(len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)     unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)     status = readb(base + STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)     if(status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)       goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)     if(status & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)       writeb(*addr++, dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)       if(--len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)         break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)     status = readb(base + STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)     if(status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)       goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)     if(status & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)       writeb(*addr++, dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)       if(--len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)         break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)   writeb(hostdata->ctrl | 0x40, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) static inline int cumanascsi_pread(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)                                    unsigned char *addr, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)   unsigned long *laddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)   u8 __iomem *base = hostdata->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)   u8 __iomem *dma = hostdata->pdma_io + 0x2000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)   if(!len) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)   writeb(0x00, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)   laddr = (unsigned long *)addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)   while(len >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)     unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)     status = readb(base + STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)     if(status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)       goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)     if(!(status & 0x40))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)       continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)     *laddr++ = readw(dma) | (readw(dma) << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)     len -= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)     if(len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)       break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)   addr = (unsigned char *)laddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)   writeb(0x10, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)   while(len > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)   {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)     unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)     status = readb(base + STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)     if(status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)       goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)     if(status & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)       *addr++ = readb(dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)       if(--len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)         break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)     status = readb(base + STAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)     if(status & 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)       goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)     if(status & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)     {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)       *addr++ = readb(dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)       if(--len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)         break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)     }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)   }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)   writeb(hostdata->ctrl | 0x40, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int cumanascsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)                                    struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	return cmd->transfersize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static u8 cumanascsi_read(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)                           unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	u8 __iomem *base = hostdata->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	writeb(0, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	val = readb(base + 0x2100 + (reg << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	hostdata->ctrl = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	writeb(0x40, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static void cumanascsi_write(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)                              unsigned int reg, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	u8 __iomem *base = hostdata->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	writeb(0, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	writeb(value, base + 0x2100 + (reg << 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	hostdata->ctrl = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	writeb(0x40, base + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #include "../NCR5380.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static struct scsi_host_template cumanascsi_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	.module			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	.name			= "Cumana 16-bit SCSI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	.info			= cumanascsi_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	.queuecommand		= cumanascsi_queue_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	.eh_abort_handler	= NCR5380_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	.eh_host_reset_handler	= NCR5380_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	.can_queue		= 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	.this_id		= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	.sg_tablesize		= SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	.cmd_per_lun		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	.proc_name		= "CumanaSCSI-1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	.cmd_size		= NCR5380_CMD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	.max_sectors		= 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	.dma_boundary		= PAGE_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int cumanascsi1_probe(struct expansion_card *ec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			     const struct ecard_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	ret = ecard_request_resources(ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	if (!host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	priv(host)->io = ioremap(ecard_resource_start(ec, ECARD_RES_IOCSLOW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	                         ecard_resource_len(ec, ECARD_RES_IOCSLOW));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	priv(host)->pdma_io = ioremap(ecard_resource_start(ec, ECARD_RES_MEMC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	                              ecard_resource_len(ec, ECARD_RES_MEMC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (!priv(host)->io || !priv(host)->pdma_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	host->irq = ec->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	ret = NCR5380_init(host, FLAG_DMA_FIXUP | FLAG_LATE_DMA_SETUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	NCR5380_maybe_reset_bus(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)         priv(host)->ctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)         writeb(0, priv(host)->io + CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	ret = request_irq(host->irq, cumanascsi_intr, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			  "CumanaSCSI-1", host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		printk("scsi%d: IRQ%d not free: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		    host->host_no, host->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		goto out_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	ret = scsi_add_host(host, &ec->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		goto out_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  out_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	free_irq(host->irq, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  out_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	NCR5380_exit(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	iounmap(priv(host)->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	iounmap(priv(host)->pdma_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	ecard_release_resources(ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void cumanascsi1_remove(struct expansion_card *ec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	struct Scsi_Host *host = ecard_get_drvdata(ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	void __iomem *base = priv(host)->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	void __iomem *dma = priv(host)->pdma_io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	ecard_set_drvdata(ec, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	scsi_remove_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	free_irq(host->irq, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	NCR5380_exit(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	iounmap(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	iounmap(dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	ecard_release_resources(ec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static const struct ecard_id cumanascsi1_cids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	{ MANU_CUMANA, PROD_CUMANA_SCSI_1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	{ 0xffff, 0xffff }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) static struct ecard_driver cumanascsi1_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	.probe		= cumanascsi1_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	.remove		= cumanascsi1_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	.id_table	= cumanascsi1_cids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	.drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		.name		= "cumanascsi1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static int __init cumanascsi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	return ecard_register_driver(&cumanascsi1_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) static void __exit cumanascsi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	ecard_remove_driver(&cumanascsi1_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) module_init(cumanascsi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) module_exit(cumanascsi_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) MODULE_DESCRIPTION("Cumana SCSI-1 driver for Acorn machines");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) MODULE_LICENSE("GPL");