18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Sun3 SCSI stuff by Erik Verbruggen (erik@bigmama.xtdnet.nl) 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Sun3 DMA routines added by Sam Creasey (sammy@sammy.net) 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * VME support added by Sam Creasey 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * TODO: modify this driver to support multiple Sun3 SCSI VME boards 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Adapted from mac_scsinew.c: 128c2ecf20Sopenharmony_ci */ 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Generic Macintosh NCR5380 driver 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Copyright 1998, Michael Schmitz <mschmitz@lbl.gov> 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * derived in part from: 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ci/* 218c2ecf20Sopenharmony_ci * Generic Generic NCR5380 driver 228c2ecf20Sopenharmony_ci * 238c2ecf20Sopenharmony_ci * Copyright 1995, Russell King 248c2ecf20Sopenharmony_ci */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci#include <linux/types.h> 278c2ecf20Sopenharmony_ci#include <linux/delay.h> 288c2ecf20Sopenharmony_ci#include <linux/module.h> 298c2ecf20Sopenharmony_ci#include <linux/ioport.h> 308c2ecf20Sopenharmony_ci#include <linux/init.h> 318c2ecf20Sopenharmony_ci#include <linux/blkdev.h> 328c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include <asm/io.h> 358c2ecf20Sopenharmony_ci#include <asm/dvma.h> 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci#include <scsi/scsi_host.h> 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* minimum number of bytes to do dma on */ 408c2ecf20Sopenharmony_ci#define DMA_MIN_SIZE 129 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* Definitions for the core NCR5380 driver. */ 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#define NCR5380_implementation_fields /* none */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#define NCR5380_read(reg) in_8(hostdata->io + (reg)) 478c2ecf20Sopenharmony_ci#define NCR5380_write(reg, value) out_8(hostdata->io + (reg), value) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define NCR5380_queue_command sun3scsi_queue_command 508c2ecf20Sopenharmony_ci#define NCR5380_host_reset sun3scsi_host_reset 518c2ecf20Sopenharmony_ci#define NCR5380_abort sun3scsi_abort 528c2ecf20Sopenharmony_ci#define NCR5380_info sun3scsi_info 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci#define NCR5380_dma_xfer_len sun3scsi_dma_xfer_len 558c2ecf20Sopenharmony_ci#define NCR5380_dma_recv_setup sun3scsi_dma_count 568c2ecf20Sopenharmony_ci#define NCR5380_dma_send_setup sun3scsi_dma_count 578c2ecf20Sopenharmony_ci#define NCR5380_dma_residual sun3scsi_dma_residual 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#include "NCR5380.h" 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* dma regs start at regbase + 8, directly after the NCR regs */ 628c2ecf20Sopenharmony_cistruct sun3_dma_regs { 638c2ecf20Sopenharmony_ci unsigned short dma_addr_hi; /* vme only */ 648c2ecf20Sopenharmony_ci unsigned short dma_addr_lo; /* vme only */ 658c2ecf20Sopenharmony_ci unsigned short dma_count_hi; /* vme only */ 668c2ecf20Sopenharmony_ci unsigned short dma_count_lo; /* vme only */ 678c2ecf20Sopenharmony_ci unsigned short udc_data; /* udc dma data reg (obio only) */ 688c2ecf20Sopenharmony_ci unsigned short udc_addr; /* uda dma addr reg (obio only) */ 698c2ecf20Sopenharmony_ci unsigned short fifo_data; /* fifo data reg, 708c2ecf20Sopenharmony_ci * holds extra byte on odd dma reads 718c2ecf20Sopenharmony_ci */ 728c2ecf20Sopenharmony_ci unsigned short fifo_count; 738c2ecf20Sopenharmony_ci unsigned short csr; /* control/status reg */ 748c2ecf20Sopenharmony_ci unsigned short bpack_hi; /* vme only */ 758c2ecf20Sopenharmony_ci unsigned short bpack_lo; /* vme only */ 768c2ecf20Sopenharmony_ci unsigned short ivect; /* vme only */ 778c2ecf20Sopenharmony_ci unsigned short fifo_count_hi; /* vme only */ 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci/* ucd chip specific regs - live in dvma space */ 818c2ecf20Sopenharmony_cistruct sun3_udc_regs { 828c2ecf20Sopenharmony_ci unsigned short rsel; /* select regs to load */ 838c2ecf20Sopenharmony_ci unsigned short addr_hi; /* high word of addr */ 848c2ecf20Sopenharmony_ci unsigned short addr_lo; /* low word */ 858c2ecf20Sopenharmony_ci unsigned short count; /* words to be xfer'd */ 868c2ecf20Sopenharmony_ci unsigned short mode_hi; /* high word of channel mode */ 878c2ecf20Sopenharmony_ci unsigned short mode_lo; /* low word of channel mode */ 888c2ecf20Sopenharmony_ci}; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* addresses of the udc registers */ 918c2ecf20Sopenharmony_ci#define UDC_MODE 0x38 928c2ecf20Sopenharmony_ci#define UDC_CSR 0x2e /* command/status */ 938c2ecf20Sopenharmony_ci#define UDC_CHN_HI 0x26 /* chain high word */ 948c2ecf20Sopenharmony_ci#define UDC_CHN_LO 0x22 /* chain lo word */ 958c2ecf20Sopenharmony_ci#define UDC_CURA_HI 0x1a /* cur reg A high */ 968c2ecf20Sopenharmony_ci#define UDC_CURA_LO 0x0a /* cur reg A low */ 978c2ecf20Sopenharmony_ci#define UDC_CURB_HI 0x12 /* cur reg B high */ 988c2ecf20Sopenharmony_ci#define UDC_CURB_LO 0x02 /* cur reg B low */ 998c2ecf20Sopenharmony_ci#define UDC_MODE_HI 0x56 /* mode reg high */ 1008c2ecf20Sopenharmony_ci#define UDC_MODE_LO 0x52 /* mode reg low */ 1018c2ecf20Sopenharmony_ci#define UDC_COUNT 0x32 /* words to xfer */ 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* some udc commands */ 1048c2ecf20Sopenharmony_ci#define UDC_RESET 0 1058c2ecf20Sopenharmony_ci#define UDC_CHN_START 0xa0 /* start chain */ 1068c2ecf20Sopenharmony_ci#define UDC_INT_ENABLE 0x32 /* channel 1 int on */ 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci/* udc mode words */ 1098c2ecf20Sopenharmony_ci#define UDC_MODE_HIWORD 0x40 1108c2ecf20Sopenharmony_ci#define UDC_MODE_LSEND 0xc2 1118c2ecf20Sopenharmony_ci#define UDC_MODE_LRECV 0xd2 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci/* udc reg selections */ 1148c2ecf20Sopenharmony_ci#define UDC_RSEL_SEND 0x282 1158c2ecf20Sopenharmony_ci#define UDC_RSEL_RECV 0x182 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/* bits in csr reg */ 1188c2ecf20Sopenharmony_ci#define CSR_DMA_ACTIVE 0x8000 1198c2ecf20Sopenharmony_ci#define CSR_DMA_CONFLICT 0x4000 1208c2ecf20Sopenharmony_ci#define CSR_DMA_BUSERR 0x2000 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci#define CSR_FIFO_EMPTY 0x400 /* fifo flushed? */ 1238c2ecf20Sopenharmony_ci#define CSR_SDB_INT 0x200 /* sbc interrupt pending */ 1248c2ecf20Sopenharmony_ci#define CSR_DMA_INT 0x100 /* dma interrupt pending */ 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci#define CSR_LEFT 0xc0 1278c2ecf20Sopenharmony_ci#define CSR_LEFT_3 0xc0 1288c2ecf20Sopenharmony_ci#define CSR_LEFT_2 0x80 1298c2ecf20Sopenharmony_ci#define CSR_LEFT_1 0x40 1308c2ecf20Sopenharmony_ci#define CSR_PACK_ENABLE 0x20 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci#define CSR_DMA_ENABLE 0x10 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci#define CSR_SEND 0x8 /* 1 = send 0 = recv */ 1358c2ecf20Sopenharmony_ci#define CSR_FIFO 0x2 /* reset fifo */ 1368c2ecf20Sopenharmony_ci#define CSR_INTR 0x4 /* interrupt enable */ 1378c2ecf20Sopenharmony_ci#define CSR_SCSI 0x1 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci#define VME_DATA24 0x3d00 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ciextern int sun3_map_test(unsigned long, char *); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_cistatic int setup_can_queue = -1; 1448c2ecf20Sopenharmony_cimodule_param(setup_can_queue, int, 0); 1458c2ecf20Sopenharmony_cistatic int setup_cmd_per_lun = -1; 1468c2ecf20Sopenharmony_cimodule_param(setup_cmd_per_lun, int, 0); 1478c2ecf20Sopenharmony_cistatic int setup_sg_tablesize = -1; 1488c2ecf20Sopenharmony_cimodule_param(setup_sg_tablesize, int, 0); 1498c2ecf20Sopenharmony_cistatic int setup_hostid = -1; 1508c2ecf20Sopenharmony_cimodule_param(setup_hostid, int, 0); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci/* ms to wait after hitting dma regs */ 1538c2ecf20Sopenharmony_ci#define SUN3_DMA_DELAY 10 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci/* dvma buffer to allocate -- 32k should hopefully be more than sufficient */ 1568c2ecf20Sopenharmony_ci#define SUN3_DVMA_BUFSIZE 0xe000 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic struct scsi_cmnd *sun3_dma_setup_done; 1598c2ecf20Sopenharmony_cistatic volatile struct sun3_dma_regs *dregs; 1608c2ecf20Sopenharmony_cistatic struct sun3_udc_regs *udc_regs; 1618c2ecf20Sopenharmony_cistatic unsigned char *sun3_dma_orig_addr; 1628c2ecf20Sopenharmony_cistatic unsigned long sun3_dma_orig_count; 1638c2ecf20Sopenharmony_cistatic int sun3_dma_active; 1648c2ecf20Sopenharmony_cistatic unsigned long last_residual; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#ifndef SUN3_SCSI_VME 1678c2ecf20Sopenharmony_ci/* dma controller register access functions */ 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_cistatic inline unsigned short sun3_udc_read(unsigned char reg) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci unsigned short ret; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci dregs->udc_addr = UDC_CSR; 1748c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 1758c2ecf20Sopenharmony_ci ret = dregs->udc_data; 1768c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci return ret; 1798c2ecf20Sopenharmony_ci} 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_cistatic inline void sun3_udc_write(unsigned short val, unsigned char reg) 1828c2ecf20Sopenharmony_ci{ 1838c2ecf20Sopenharmony_ci dregs->udc_addr = reg; 1848c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 1858c2ecf20Sopenharmony_ci dregs->udc_data = val; 1868c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci#endif 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci// safe bits for the CSR 1918c2ecf20Sopenharmony_ci#define CSR_GOOD 0x060f 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic irqreturn_t scsi_sun3_intr(int irq, void *dev) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct Scsi_Host *instance = dev; 1968c2ecf20Sopenharmony_ci unsigned short csr = dregs->csr; 1978c2ecf20Sopenharmony_ci int handled = 0; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 2008c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_DMA_ENABLE; 2018c2ecf20Sopenharmony_ci#endif 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci if(csr & ~CSR_GOOD) { 2048c2ecf20Sopenharmony_ci if (csr & CSR_DMA_BUSERR) 2058c2ecf20Sopenharmony_ci shost_printk(KERN_ERR, instance, "bus error in DMA\n"); 2068c2ecf20Sopenharmony_ci if (csr & CSR_DMA_CONFLICT) 2078c2ecf20Sopenharmony_ci shost_printk(KERN_ERR, instance, "DMA conflict\n"); 2088c2ecf20Sopenharmony_ci handled = 1; 2098c2ecf20Sopenharmony_ci } 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci if(csr & (CSR_SDB_INT | CSR_DMA_INT)) { 2128c2ecf20Sopenharmony_ci NCR5380_intr(irq, dev); 2138c2ecf20Sopenharmony_ci handled = 1; 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci return IRQ_RETVAL(handled); 2178c2ecf20Sopenharmony_ci} 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci/* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ 2208c2ecf20Sopenharmony_cistatic int sun3scsi_dma_setup(struct NCR5380_hostdata *hostdata, 2218c2ecf20Sopenharmony_ci unsigned char *data, int count, int write_flag) 2228c2ecf20Sopenharmony_ci{ 2238c2ecf20Sopenharmony_ci void *addr; 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci if(sun3_dma_orig_addr != NULL) 2268c2ecf20Sopenharmony_ci dvma_unmap(sun3_dma_orig_addr); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 2298c2ecf20Sopenharmony_ci addr = (void *)dvma_map_vme((unsigned long) data, count); 2308c2ecf20Sopenharmony_ci#else 2318c2ecf20Sopenharmony_ci addr = (void *)dvma_map((unsigned long) data, count); 2328c2ecf20Sopenharmony_ci#endif 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci sun3_dma_orig_addr = addr; 2358c2ecf20Sopenharmony_ci sun3_dma_orig_count = count; 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci#ifndef SUN3_SCSI_VME 2388c2ecf20Sopenharmony_ci dregs->fifo_count = 0; 2398c2ecf20Sopenharmony_ci sun3_udc_write(UDC_RESET, UDC_CSR); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci /* reset fifo */ 2428c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_FIFO; 2438c2ecf20Sopenharmony_ci dregs->csr |= CSR_FIFO; 2448c2ecf20Sopenharmony_ci#endif 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci /* set direction */ 2478c2ecf20Sopenharmony_ci if(write_flag) 2488c2ecf20Sopenharmony_ci dregs->csr |= CSR_SEND; 2498c2ecf20Sopenharmony_ci else 2508c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_SEND; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 2538c2ecf20Sopenharmony_ci dregs->csr |= CSR_PACK_ENABLE; 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci dregs->dma_addr_hi = ((unsigned long)addr >> 16); 2568c2ecf20Sopenharmony_ci dregs->dma_addr_lo = ((unsigned long)addr & 0xffff); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci dregs->dma_count_hi = 0; 2598c2ecf20Sopenharmony_ci dregs->dma_count_lo = 0; 2608c2ecf20Sopenharmony_ci dregs->fifo_count_hi = 0; 2618c2ecf20Sopenharmony_ci dregs->fifo_count = 0; 2628c2ecf20Sopenharmony_ci#else 2638c2ecf20Sopenharmony_ci /* byte count for fifo */ 2648c2ecf20Sopenharmony_ci dregs->fifo_count = count; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci sun3_udc_write(UDC_RESET, UDC_CSR); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci /* reset fifo */ 2698c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_FIFO; 2708c2ecf20Sopenharmony_ci dregs->csr |= CSR_FIFO; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci if(dregs->fifo_count != count) { 2738c2ecf20Sopenharmony_ci shost_printk(KERN_ERR, hostdata->host, 2748c2ecf20Sopenharmony_ci "FIFO mismatch %04x not %04x\n", 2758c2ecf20Sopenharmony_ci dregs->fifo_count, (unsigned int) count); 2768c2ecf20Sopenharmony_ci NCR5380_dprint(NDEBUG_DMA, hostdata->host); 2778c2ecf20Sopenharmony_ci } 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci /* setup udc */ 2808c2ecf20Sopenharmony_ci udc_regs->addr_hi = (((unsigned long)(addr) & 0xff0000) >> 8); 2818c2ecf20Sopenharmony_ci udc_regs->addr_lo = ((unsigned long)(addr) & 0xffff); 2828c2ecf20Sopenharmony_ci udc_regs->count = count/2; /* count in words */ 2838c2ecf20Sopenharmony_ci udc_regs->mode_hi = UDC_MODE_HIWORD; 2848c2ecf20Sopenharmony_ci if(write_flag) { 2858c2ecf20Sopenharmony_ci if(count & 1) 2868c2ecf20Sopenharmony_ci udc_regs->count++; 2878c2ecf20Sopenharmony_ci udc_regs->mode_lo = UDC_MODE_LSEND; 2888c2ecf20Sopenharmony_ci udc_regs->rsel = UDC_RSEL_SEND; 2898c2ecf20Sopenharmony_ci } else { 2908c2ecf20Sopenharmony_ci udc_regs->mode_lo = UDC_MODE_LRECV; 2918c2ecf20Sopenharmony_ci udc_regs->rsel = UDC_RSEL_RECV; 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci /* announce location of regs block */ 2958c2ecf20Sopenharmony_ci sun3_udc_write(((dvma_vtob(udc_regs) & 0xff0000) >> 8), 2968c2ecf20Sopenharmony_ci UDC_CHN_HI); 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci sun3_udc_write((dvma_vtob(udc_regs) & 0xffff), UDC_CHN_LO); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci /* set dma master on */ 3018c2ecf20Sopenharmony_ci sun3_udc_write(0xd, UDC_MODE); 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci /* interrupt enable */ 3048c2ecf20Sopenharmony_ci sun3_udc_write(UDC_INT_ENABLE, UDC_CSR); 3058c2ecf20Sopenharmony_ci#endif 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci return count; 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic int sun3scsi_dma_count(struct NCR5380_hostdata *hostdata, 3128c2ecf20Sopenharmony_ci unsigned char *data, int count) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci return count; 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic inline int sun3scsi_dma_recv_setup(struct NCR5380_hostdata *hostdata, 3188c2ecf20Sopenharmony_ci unsigned char *data, int count) 3198c2ecf20Sopenharmony_ci{ 3208c2ecf20Sopenharmony_ci return sun3scsi_dma_setup(hostdata, data, count, 0); 3218c2ecf20Sopenharmony_ci} 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cistatic inline int sun3scsi_dma_send_setup(struct NCR5380_hostdata *hostdata, 3248c2ecf20Sopenharmony_ci unsigned char *data, int count) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci return sun3scsi_dma_setup(hostdata, data, count, 1); 3278c2ecf20Sopenharmony_ci} 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_cistatic int sun3scsi_dma_residual(struct NCR5380_hostdata *hostdata) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci return last_residual; 3328c2ecf20Sopenharmony_ci} 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_cistatic int sun3scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata, 3358c2ecf20Sopenharmony_ci struct scsi_cmnd *cmd) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci int wanted_len = cmd->SCp.this_residual; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if (wanted_len < DMA_MIN_SIZE || blk_rq_is_passthrough(cmd->request)) 3408c2ecf20Sopenharmony_ci return 0; 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci return wanted_len; 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cistatic inline int sun3scsi_dma_start(unsigned long count, unsigned char *data) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 3488c2ecf20Sopenharmony_ci unsigned short csr; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci csr = dregs->csr; 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci dregs->dma_count_hi = (sun3_dma_orig_count >> 16); 3538c2ecf20Sopenharmony_ci dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci dregs->fifo_count_hi = (sun3_dma_orig_count >> 16); 3568c2ecf20Sopenharmony_ci dregs->fifo_count = (sun3_dma_orig_count & 0xffff); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci/* if(!(csr & CSR_DMA_ENABLE)) 3598c2ecf20Sopenharmony_ci * dregs->csr |= CSR_DMA_ENABLE; 3608c2ecf20Sopenharmony_ci */ 3618c2ecf20Sopenharmony_ci#else 3628c2ecf20Sopenharmony_ci sun3_udc_write(UDC_CHN_START, UDC_CSR); 3638c2ecf20Sopenharmony_ci#endif 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci return 0; 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci/* clean up after our dma is done */ 3698c2ecf20Sopenharmony_cistatic int sun3scsi_dma_finish(int write_flag) 3708c2ecf20Sopenharmony_ci{ 3718c2ecf20Sopenharmony_ci unsigned short __maybe_unused count; 3728c2ecf20Sopenharmony_ci unsigned short fifo; 3738c2ecf20Sopenharmony_ci int ret = 0; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci sun3_dma_active = 0; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 3788c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_DMA_ENABLE; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci fifo = dregs->fifo_count; 3818c2ecf20Sopenharmony_ci if (write_flag) { 3828c2ecf20Sopenharmony_ci if ((fifo > 0) && (fifo < sun3_dma_orig_count)) 3838c2ecf20Sopenharmony_ci fifo++; 3848c2ecf20Sopenharmony_ci } 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci last_residual = fifo; 3878c2ecf20Sopenharmony_ci /* empty bytes from the fifo which didn't make it */ 3888c2ecf20Sopenharmony_ci if ((!write_flag) && (dregs->csr & CSR_LEFT)) { 3898c2ecf20Sopenharmony_ci unsigned char *vaddr; 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci vaddr = (unsigned char *)dvma_vmetov(sun3_dma_orig_addr); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci vaddr += (sun3_dma_orig_count - fifo); 3948c2ecf20Sopenharmony_ci vaddr--; 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci switch (dregs->csr & CSR_LEFT) { 3978c2ecf20Sopenharmony_ci case CSR_LEFT_3: 3988c2ecf20Sopenharmony_ci *vaddr = (dregs->bpack_lo & 0xff00) >> 8; 3998c2ecf20Sopenharmony_ci vaddr--; 4008c2ecf20Sopenharmony_ci fallthrough; 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci case CSR_LEFT_2: 4038c2ecf20Sopenharmony_ci *vaddr = (dregs->bpack_hi & 0x00ff); 4048c2ecf20Sopenharmony_ci vaddr--; 4058c2ecf20Sopenharmony_ci fallthrough; 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci case CSR_LEFT_1: 4088c2ecf20Sopenharmony_ci *vaddr = (dregs->bpack_hi & 0xff00) >> 8; 4098c2ecf20Sopenharmony_ci break; 4108c2ecf20Sopenharmony_ci } 4118c2ecf20Sopenharmony_ci } 4128c2ecf20Sopenharmony_ci#else 4138c2ecf20Sopenharmony_ci // check to empty the fifo on a read 4148c2ecf20Sopenharmony_ci if(!write_flag) { 4158c2ecf20Sopenharmony_ci int tmo = 20000; /* .2 sec */ 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ci while(1) { 4188c2ecf20Sopenharmony_ci if(dregs->csr & CSR_FIFO_EMPTY) 4198c2ecf20Sopenharmony_ci break; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci if(--tmo <= 0) { 4228c2ecf20Sopenharmony_ci printk("sun3scsi: fifo failed to empty!\n"); 4238c2ecf20Sopenharmony_ci return 1; 4248c2ecf20Sopenharmony_ci } 4258c2ecf20Sopenharmony_ci udelay(10); 4268c2ecf20Sopenharmony_ci } 4278c2ecf20Sopenharmony_ci } 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_ci dregs->udc_addr = 0x32; 4308c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 4318c2ecf20Sopenharmony_ci count = 2 * dregs->udc_data; 4328c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci fifo = dregs->fifo_count; 4358c2ecf20Sopenharmony_ci last_residual = fifo; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci /* empty bytes from the fifo which didn't make it */ 4388c2ecf20Sopenharmony_ci if((!write_flag) && (count - fifo) == 2) { 4398c2ecf20Sopenharmony_ci unsigned short data; 4408c2ecf20Sopenharmony_ci unsigned char *vaddr; 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ci data = dregs->fifo_data; 4438c2ecf20Sopenharmony_ci vaddr = (unsigned char *)dvma_btov(sun3_dma_orig_addr); 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci vaddr += (sun3_dma_orig_count - fifo); 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci vaddr[-2] = (data & 0xff00) >> 8; 4488c2ecf20Sopenharmony_ci vaddr[-1] = (data & 0xff); 4498c2ecf20Sopenharmony_ci } 4508c2ecf20Sopenharmony_ci#endif 4518c2ecf20Sopenharmony_ci 4528c2ecf20Sopenharmony_ci dvma_unmap(sun3_dma_orig_addr); 4538c2ecf20Sopenharmony_ci sun3_dma_orig_addr = NULL; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 4568c2ecf20Sopenharmony_ci dregs->dma_addr_hi = 0; 4578c2ecf20Sopenharmony_ci dregs->dma_addr_lo = 0; 4588c2ecf20Sopenharmony_ci dregs->dma_count_hi = 0; 4598c2ecf20Sopenharmony_ci dregs->dma_count_lo = 0; 4608c2ecf20Sopenharmony_ci 4618c2ecf20Sopenharmony_ci dregs->fifo_count = 0; 4628c2ecf20Sopenharmony_ci dregs->fifo_count_hi = 0; 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_SEND; 4658c2ecf20Sopenharmony_ci/* dregs->csr |= CSR_DMA_ENABLE; */ 4668c2ecf20Sopenharmony_ci#else 4678c2ecf20Sopenharmony_ci sun3_udc_write(UDC_RESET, UDC_CSR); 4688c2ecf20Sopenharmony_ci dregs->fifo_count = 0; 4698c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_SEND; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_ci /* reset fifo */ 4728c2ecf20Sopenharmony_ci dregs->csr &= ~CSR_FIFO; 4738c2ecf20Sopenharmony_ci dregs->csr |= CSR_FIFO; 4748c2ecf20Sopenharmony_ci#endif 4758c2ecf20Sopenharmony_ci 4768c2ecf20Sopenharmony_ci sun3_dma_setup_done = NULL; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci return ret; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci} 4818c2ecf20Sopenharmony_ci 4828c2ecf20Sopenharmony_ci#include "NCR5380.c" 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 4858c2ecf20Sopenharmony_ci#define SUN3_SCSI_NAME "Sun3 NCR5380 VME SCSI" 4868c2ecf20Sopenharmony_ci#define DRV_MODULE_NAME "sun3_scsi_vme" 4878c2ecf20Sopenharmony_ci#else 4888c2ecf20Sopenharmony_ci#define SUN3_SCSI_NAME "Sun3 NCR5380 SCSI" 4898c2ecf20Sopenharmony_ci#define DRV_MODULE_NAME "sun3_scsi" 4908c2ecf20Sopenharmony_ci#endif 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci#define PFX DRV_MODULE_NAME ": " 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_cistatic struct scsi_host_template sun3_scsi_template = { 4958c2ecf20Sopenharmony_ci .module = THIS_MODULE, 4968c2ecf20Sopenharmony_ci .proc_name = DRV_MODULE_NAME, 4978c2ecf20Sopenharmony_ci .name = SUN3_SCSI_NAME, 4988c2ecf20Sopenharmony_ci .info = sun3scsi_info, 4998c2ecf20Sopenharmony_ci .queuecommand = sun3scsi_queue_command, 5008c2ecf20Sopenharmony_ci .eh_abort_handler = sun3scsi_abort, 5018c2ecf20Sopenharmony_ci .eh_host_reset_handler = sun3scsi_host_reset, 5028c2ecf20Sopenharmony_ci .can_queue = 16, 5038c2ecf20Sopenharmony_ci .this_id = 7, 5048c2ecf20Sopenharmony_ci .sg_tablesize = 1, 5058c2ecf20Sopenharmony_ci .cmd_per_lun = 2, 5068c2ecf20Sopenharmony_ci .dma_boundary = PAGE_SIZE - 1, 5078c2ecf20Sopenharmony_ci .cmd_size = NCR5380_CMD_SIZE, 5088c2ecf20Sopenharmony_ci}; 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_cistatic int __init sun3_scsi_probe(struct platform_device *pdev) 5118c2ecf20Sopenharmony_ci{ 5128c2ecf20Sopenharmony_ci struct Scsi_Host *instance; 5138c2ecf20Sopenharmony_ci struct NCR5380_hostdata *hostdata; 5148c2ecf20Sopenharmony_ci int error; 5158c2ecf20Sopenharmony_ci struct resource *irq, *mem; 5168c2ecf20Sopenharmony_ci void __iomem *ioaddr; 5178c2ecf20Sopenharmony_ci int host_flags = 0; 5188c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 5198c2ecf20Sopenharmony_ci int i; 5208c2ecf20Sopenharmony_ci#endif 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_ci if (setup_can_queue > 0) 5238c2ecf20Sopenharmony_ci sun3_scsi_template.can_queue = setup_can_queue; 5248c2ecf20Sopenharmony_ci if (setup_cmd_per_lun > 0) 5258c2ecf20Sopenharmony_ci sun3_scsi_template.cmd_per_lun = setup_cmd_per_lun; 5268c2ecf20Sopenharmony_ci if (setup_sg_tablesize > 0) 5278c2ecf20Sopenharmony_ci sun3_scsi_template.sg_tablesize = setup_sg_tablesize; 5288c2ecf20Sopenharmony_ci if (setup_hostid >= 0) 5298c2ecf20Sopenharmony_ci sun3_scsi_template.this_id = setup_hostid & 7; 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 5328c2ecf20Sopenharmony_ci ioaddr = NULL; 5338c2ecf20Sopenharmony_ci for (i = 0; i < 2; i++) { 5348c2ecf20Sopenharmony_ci unsigned char x; 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_ci irq = platform_get_resource(pdev, IORESOURCE_IRQ, i); 5378c2ecf20Sopenharmony_ci mem = platform_get_resource(pdev, IORESOURCE_MEM, i); 5388c2ecf20Sopenharmony_ci if (!irq || !mem) 5398c2ecf20Sopenharmony_ci break; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci ioaddr = sun3_ioremap(mem->start, resource_size(mem), 5428c2ecf20Sopenharmony_ci SUN3_PAGE_TYPE_VME16); 5438c2ecf20Sopenharmony_ci dregs = (struct sun3_dma_regs *)(ioaddr + 8); 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci if (sun3_map_test((unsigned long)dregs, &x)) { 5468c2ecf20Sopenharmony_ci unsigned short oldcsr; 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_ci oldcsr = dregs->csr; 5498c2ecf20Sopenharmony_ci dregs->csr = 0; 5508c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 5518c2ecf20Sopenharmony_ci if (dregs->csr == 0x1400) 5528c2ecf20Sopenharmony_ci break; 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci dregs->csr = oldcsr; 5558c2ecf20Sopenharmony_ci } 5568c2ecf20Sopenharmony_ci 5578c2ecf20Sopenharmony_ci iounmap(ioaddr); 5588c2ecf20Sopenharmony_ci ioaddr = NULL; 5598c2ecf20Sopenharmony_ci } 5608c2ecf20Sopenharmony_ci if (!ioaddr) 5618c2ecf20Sopenharmony_ci return -ENODEV; 5628c2ecf20Sopenharmony_ci#else 5638c2ecf20Sopenharmony_ci irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 5648c2ecf20Sopenharmony_ci mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 5658c2ecf20Sopenharmony_ci if (!irq || !mem) 5668c2ecf20Sopenharmony_ci return -ENODEV; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci ioaddr = ioremap(mem->start, resource_size(mem)); 5698c2ecf20Sopenharmony_ci dregs = (struct sun3_dma_regs *)(ioaddr + 8); 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci udc_regs = dvma_malloc(sizeof(struct sun3_udc_regs)); 5728c2ecf20Sopenharmony_ci if (!udc_regs) { 5738c2ecf20Sopenharmony_ci pr_err(PFX "couldn't allocate DVMA memory!\n"); 5748c2ecf20Sopenharmony_ci iounmap(ioaddr); 5758c2ecf20Sopenharmony_ci return -ENOMEM; 5768c2ecf20Sopenharmony_ci } 5778c2ecf20Sopenharmony_ci#endif 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci instance = scsi_host_alloc(&sun3_scsi_template, 5808c2ecf20Sopenharmony_ci sizeof(struct NCR5380_hostdata)); 5818c2ecf20Sopenharmony_ci if (!instance) { 5828c2ecf20Sopenharmony_ci error = -ENOMEM; 5838c2ecf20Sopenharmony_ci goto fail_alloc; 5848c2ecf20Sopenharmony_ci } 5858c2ecf20Sopenharmony_ci 5868c2ecf20Sopenharmony_ci instance->irq = irq->start; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci hostdata = shost_priv(instance); 5898c2ecf20Sopenharmony_ci hostdata->base = mem->start; 5908c2ecf20Sopenharmony_ci hostdata->io = ioaddr; 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci error = NCR5380_init(instance, host_flags); 5938c2ecf20Sopenharmony_ci if (error) 5948c2ecf20Sopenharmony_ci goto fail_init; 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci error = request_irq(instance->irq, scsi_sun3_intr, 0, 5978c2ecf20Sopenharmony_ci "NCR5380", instance); 5988c2ecf20Sopenharmony_ci if (error) { 5998c2ecf20Sopenharmony_ci pr_err(PFX "scsi%d: IRQ %d not free, bailing out\n", 6008c2ecf20Sopenharmony_ci instance->host_no, instance->irq); 6018c2ecf20Sopenharmony_ci goto fail_irq; 6028c2ecf20Sopenharmony_ci } 6038c2ecf20Sopenharmony_ci 6048c2ecf20Sopenharmony_ci dregs->csr = 0; 6058c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 6068c2ecf20Sopenharmony_ci dregs->csr = CSR_SCSI | CSR_FIFO | CSR_INTR; 6078c2ecf20Sopenharmony_ci udelay(SUN3_DMA_DELAY); 6088c2ecf20Sopenharmony_ci dregs->fifo_count = 0; 6098c2ecf20Sopenharmony_ci#ifdef SUN3_SCSI_VME 6108c2ecf20Sopenharmony_ci dregs->fifo_count_hi = 0; 6118c2ecf20Sopenharmony_ci dregs->dma_addr_hi = 0; 6128c2ecf20Sopenharmony_ci dregs->dma_addr_lo = 0; 6138c2ecf20Sopenharmony_ci dregs->dma_count_hi = 0; 6148c2ecf20Sopenharmony_ci dregs->dma_count_lo = 0; 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci dregs->ivect = VME_DATA24 | (instance->irq & 0xff); 6178c2ecf20Sopenharmony_ci#endif 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci NCR5380_maybe_reset_bus(instance); 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci error = scsi_add_host(instance, NULL); 6228c2ecf20Sopenharmony_ci if (error) 6238c2ecf20Sopenharmony_ci goto fail_host; 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci platform_set_drvdata(pdev, instance); 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci scsi_scan_host(instance); 6288c2ecf20Sopenharmony_ci return 0; 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_cifail_host: 6318c2ecf20Sopenharmony_ci free_irq(instance->irq, instance); 6328c2ecf20Sopenharmony_cifail_irq: 6338c2ecf20Sopenharmony_ci NCR5380_exit(instance); 6348c2ecf20Sopenharmony_cifail_init: 6358c2ecf20Sopenharmony_ci scsi_host_put(instance); 6368c2ecf20Sopenharmony_cifail_alloc: 6378c2ecf20Sopenharmony_ci if (udc_regs) 6388c2ecf20Sopenharmony_ci dvma_free(udc_regs); 6398c2ecf20Sopenharmony_ci iounmap(ioaddr); 6408c2ecf20Sopenharmony_ci return error; 6418c2ecf20Sopenharmony_ci} 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_cistatic int __exit sun3_scsi_remove(struct platform_device *pdev) 6448c2ecf20Sopenharmony_ci{ 6458c2ecf20Sopenharmony_ci struct Scsi_Host *instance = platform_get_drvdata(pdev); 6468c2ecf20Sopenharmony_ci struct NCR5380_hostdata *hostdata = shost_priv(instance); 6478c2ecf20Sopenharmony_ci void __iomem *ioaddr = hostdata->io; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci scsi_remove_host(instance); 6508c2ecf20Sopenharmony_ci free_irq(instance->irq, instance); 6518c2ecf20Sopenharmony_ci NCR5380_exit(instance); 6528c2ecf20Sopenharmony_ci scsi_host_put(instance); 6538c2ecf20Sopenharmony_ci if (udc_regs) 6548c2ecf20Sopenharmony_ci dvma_free(udc_regs); 6558c2ecf20Sopenharmony_ci iounmap(ioaddr); 6568c2ecf20Sopenharmony_ci return 0; 6578c2ecf20Sopenharmony_ci} 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_cistatic struct platform_driver sun3_scsi_driver = { 6608c2ecf20Sopenharmony_ci .remove = __exit_p(sun3_scsi_remove), 6618c2ecf20Sopenharmony_ci .driver = { 6628c2ecf20Sopenharmony_ci .name = DRV_MODULE_NAME, 6638c2ecf20Sopenharmony_ci }, 6648c2ecf20Sopenharmony_ci}; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_cimodule_platform_driver_probe(sun3_scsi_driver, sun3_scsi_probe); 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ciMODULE_ALIAS("platform:" DRV_MODULE_NAME); 6698c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 670