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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) *  sym53c500_cs.c	Bob Tracy (rct@frus.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) *  A rewrite of the pcmcia-cs add-on driver for newer (circa 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) *  New Media Bus Toaster PCMCIA SCSI cards using the Symbios Logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) *  53c500 controller: intended for use with 2.6 and later kernels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) *  The pcmcia-cs add-on version of this driver is not supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) *  beyond 2.4.  It consisted of three files with history/copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) *  information as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) *  SYM53C500.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) *	Bob Tracy (rct@frus.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) *	Original by Tom Corner (tcorner@via.at).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) *	Adapted from NCR53c406a.h which is Copyrighted (C) 1994
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) *	Normunds Saumanis (normunds@rx.tech.swh.lv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) *  SYM53C500.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) *	Bob Tracy (rct@frus.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) *	Original driver by Tom Corner (tcorner@via.at) was adapted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) *	from NCR53c406a.c which is Copyrighted (C) 1994, 1995, 1996 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) *	Normunds Saumanis (normunds@fi.ibm.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) *  sym53c500.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) *	Bob Tracy (rct@frus.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) *	Original by Tom Corner (tcorner@via.at) was adapted from a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) *	driver for the Qlogic SCSI card written by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) *	David Hinds (dhinds@allegro.stanford.edu).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define SYM53C500_DEBUG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define VERBOSE_SYM53C500_DEBUG 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) *  Set this to 0 if you encounter kernel lockups while transferring 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) *  data in PIO mode.  Note this can be changed via "sysfs".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define USE_FAST_PIO 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) /* =============== End of user configurable parameters ============== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <linux/moduleparam.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #include <asm/dma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #include <scsi/scsi_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #include <scsi/scsi_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #include <pcmcia/cistpl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #include <pcmcia/ds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #include <pcmcia/ciscode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /* ================================================================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define SYNC_MODE 0 		/* Synchronous transfer mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) /* Default configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define C1_IMG   0x07		/* ID=7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define C2_IMG   0x48		/* FE SCSI2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define C3_IMG   0x20		/* CDB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) #define C4_IMG   0x04		/* ANE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define C5_IMG   0xa4		/* ? changed from b6= AA PI SIE POL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define C7_IMG   0x80		/* added for SYM53C500 t. corner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) /* Hardware Registers: offsets from io_port (base) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /* Control Register Set 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define TC_LSB		0x00		/* transfer counter lsb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) #define TC_MSB		0x01		/* transfer counter msb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define SCSI_FIFO	0x02		/* scsi fifo register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define CMD_REG		0x03		/* command register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define STAT_REG	0x04		/* status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define DEST_ID		0x04		/* selection/reselection bus id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define INT_REG		0x05		/* interrupt status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) #define SRTIMOUT	0x05		/* select/reselect timeout reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define SEQ_REG		0x06		/* sequence step register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define SYNCPRD		0x06		/* synchronous transfer period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define FIFO_FLAGS	0x07		/* indicates # of bytes in fifo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define SYNCOFF		0x07		/* synchronous offset register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define CONFIG1		0x08		/* configuration register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define CLKCONV		0x09		/* clock conversion register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /* #define TESTREG	0x0A */		/* test mode register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define CONFIG2		0x0B		/* configuration 2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define CONFIG3		0x0C		/* configuration 3 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define CONFIG4		0x0D		/* configuration 4 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define TC_HIGH		0x0E		/* transfer counter high */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* #define FIFO_BOTTOM	0x0F */		/* reserve FIFO byte register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Control Register Set 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /* #define JUMPER_SENSE	0x00 */		/* jumper sense port reg (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* #define SRAM_PTR	0x01 */		/* SRAM address pointer reg (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* #define SRAM_DATA	0x02 */		/* SRAM data register (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define PIO_FIFO	0x04		/* PIO FIFO registers (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* #define PIO_FIFO1	0x05 */		/*  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* #define PIO_FIFO2	0x06 */		/*  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* #define PIO_FIFO3	0x07 */		/*  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define PIO_STATUS	0x08		/* PIO status (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* #define ATA_CMD	0x09 */		/* ATA command/status reg (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /* #define ATA_ERR	0x0A */		/* ATA features/error reg (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define PIO_FLAG	0x0B		/* PIO flag interrupt enable (r/w) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define CONFIG5		0x09		/* configuration 5 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* #define SIGNATURE	0x0E */		/* signature register (r) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* #define CONFIG6	0x0F */		/* configuration 6 register (r) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define CONFIG7		0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* select register set 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define REG0(x)		(outb(C4_IMG, (x) + CONFIG4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* select register set 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define REG1(x)		outb(C7_IMG, (x) + CONFIG7); outb(C5_IMG, (x) + CONFIG5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #if SYM53C500_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define DEB(x) x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define DEB(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #if VERBOSE_SYM53C500_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define VDEB(x) x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define VDEB(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define LOAD_DMA_COUNT(x, count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)   outb(count & 0xff, (x) + TC_LSB); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)   outb((count >> 8) & 0xff, (x) + TC_MSB); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)   outb((count >> 16) & 0xff, (x) + TC_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Chip commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define DMA_OP               0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define SCSI_NOP             0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define FLUSH_FIFO           0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define CHIP_RESET           0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define SCSI_RESET           0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define RESELECT             0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define SELECT_NO_ATN        0x41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define SELECT_ATN           0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define SELECT_ATN_STOP      0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define ENABLE_SEL           0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define DISABLE_SEL          0x45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define SELECT_ATN3          0x46
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define RESELECT3            0x47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define TRANSFER_INFO        0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define INIT_CMD_COMPLETE    0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define MSG_ACCEPT           0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define TRANSFER_PAD         0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define SET_ATN              0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define RESET_ATN            0x1b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define SEND_MSG             0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define SEND_STATUS          0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define SEND_DATA            0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define DISCONN_SEQ          0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define TERMINATE_SEQ        0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define TARG_CMD_COMPLETE    0x25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define DISCONN              0x27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define RECV_MSG             0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define RECV_CMD             0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define RECV_DATA            0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define RECV_CMD_SEQ         0x2b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define TARGET_ABORT_DMA     0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /* ================================================================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct scsi_info_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	struct pcmcia_device	*p_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	unsigned short manf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) *  Repository for per-instance host data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct sym53c500_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	struct scsi_cmnd *current_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	int fast_pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) enum Phase {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)     idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)     data_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)     data_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)     command_ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)     status_ph,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)     message_out,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)     message_in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* ================================================================== */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) chip_init(int io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	REG1(io_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	outb(0x01, io_port + PIO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	outb(0x00, io_port + PIO_FLAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	outb(C4_IMG, io_port + CONFIG4);	/* REG0(io_port); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	outb(C3_IMG, io_port + CONFIG3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	outb(C2_IMG, io_port + CONFIG2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	outb(C1_IMG, io_port + CONFIG1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	outb(0x05, io_port + CLKCONV);	/* clock conversion factor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	outb(0x9C, io_port + SRTIMOUT);	/* Selection timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	outb(0x05, io_port + SYNCPRD);	/* Synchronous transfer period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	outb(SYNC_MODE, io_port + SYNCOFF);	/* synchronous mode */  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) SYM53C500_int_host_reset(int io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	outb(C4_IMG, io_port + CONFIG4);	/* REG0(io_port); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	outb(CHIP_RESET, io_port + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	outb(SCSI_NOP, io_port + CMD_REG);	/* required after reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	outb(SCSI_RESET, io_port + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	chip_init(io_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static __inline__ int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) SYM53C500_pio_read(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	int len;	/* current scsi fifo size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	REG1(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	while (reqlen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		i = inb(base + PIO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		/* VDEB(printk("pio_status=%x\n", i)); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (i & 0x80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		switch (i & 0x1e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		case 0x10:	/* fifo empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		case 0x0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			break; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		case 0x8:	/* fifo 1/3 full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			len = 42;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		case 0xc:	/* fifo 2/3 full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			len = 84;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		case 0xe:	/* fifo full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			len = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occurred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		if (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 			if (len > reqlen) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				len = reqlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 			if (fast_pio && len > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 				insl(base + PIO_FIFO, request, len >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				request += len & 0xfc; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 				reqlen -= len & 0xfc; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 				while (len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 					*request++ = inb(base + PIO_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 					reqlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			} 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static __inline__ int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) SYM53C500_pio_write(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	int len;	/* current scsi fifo size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	REG1(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	while (reqlen && !(i & 0x40)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		i = inb(base + PIO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		/* VDEB(printk("pio_status=%x\n", i)); */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		if (i & 0x80)	/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 		switch (i & 0x1e) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			len = 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		case 0x0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 			len = 84;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		case 0x8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 			len = 42;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		case 0xc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			len = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		case 0xe:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		if (len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 			if (len > reqlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 				len = reqlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 			if (fast_pio && len > 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 				outsl(base + PIO_FIFO, request, len >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 				request += len & 0xfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 				reqlen -= len & 0xfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 				while (len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 					outb(*request++, base + PIO_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 					reqlen--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 				}
^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) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static irqreturn_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) SYM53C500_intr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	struct Scsi_Host *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	DEB(unsigned char fifo_size;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	DEB(unsigned char seq_reg;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	unsigned char status, int_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	unsigned char pio_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	int port_base = dev->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	struct sym53c500_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	    (struct sym53c500_data *)dev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	struct scsi_cmnd *curSC = data->current_SC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	int fast_pio = data->fast_pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	spin_lock_irqsave(dev->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	VDEB(printk("SYM53C500_intr called\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	REG1(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	pio_status = inb(port_base + PIO_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	REG0(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	status = inb(port_base + STAT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	DEB(seq_reg = inb(port_base + SEQ_REG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	int_reg = inb(port_base + INT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	DEB(fifo_size = inb(port_base + FIFO_FLAGS) & 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) #if SYM53C500_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	    status, seq_reg, int_reg, fifo_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	printk(", pio=%02x\n", pio_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) #endif /* SYM53C500_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (int_reg & 0x80) {	/* SCSI reset intr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		DEB(printk("SYM53C500: reset intr received\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		curSC->result = DID_RESET << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		goto idle_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	if (pio_status & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		printk("SYM53C500: Warning: PIO error!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		curSC->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		goto idle_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	if (status & 0x20) {		/* Parity error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		printk("SYM53C500: Warning: parity error!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		curSC->result = DID_PARITY << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		goto idle_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	if (status & 0x40) {		/* Gross error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		printk("SYM53C500: Warning: gross error!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		curSC->result = DID_ERROR << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		goto idle_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	if (int_reg & 0x20) {		/* Disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		DEB(printk("SYM53C500: disconnect intr received\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		if (curSC->SCp.phase != message_in) {	/* Unexpected disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			curSC->result = DID_NO_CONNECT << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		} else {	/* Command complete, return status and message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			curSC->result = (curSC->SCp.Status & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			    | ((curSC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		goto idle_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	switch (status & 0x07) {	/* scsi phase */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	case 0x00:			/* DATA-OUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		if (int_reg & 0x10) {	/* Target requesting info transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			curSC->SCp.phase = data_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			VDEB(printk("SYM53C500: Data-Out phase\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			outb(FLUSH_FIFO, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 			LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC));	/* Max transfer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 				SYM53C500_pio_write(fast_pio, port_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 				    sg_virt(sg), sg->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			REG0(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	case 0x01:		/* DATA-IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (int_reg & 0x10) {	/* Target requesting info transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			struct scatterlist *sg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			curSC->SCp.phase = data_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			VDEB(printk("SYM53C500: Data-In phase\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			outb(FLUSH_FIFO, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			LOAD_DMA_COUNT(port_base, scsi_bufflen(curSC));	/* Max transfer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			outb(TRANSFER_INFO | DMA_OP, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			scsi_for_each_sg(curSC, sg, scsi_sg_count(curSC), i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 				SYM53C500_pio_read(fast_pio, port_base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 					sg_virt(sg), sg->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 			REG0(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	case 0x02:		/* COMMAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		curSC->SCp.phase = command_ph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		printk("SYM53C500: Warning: Unknown interrupt occurred in command phase!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	case 0x03:		/* STATUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		curSC->SCp.phase = status_ph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		VDEB(printk("SYM53C500: Status phase\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		outb(FLUSH_FIFO, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		outb(INIT_CMD_COMPLETE, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	case 0x04:		/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	case 0x05:		/* Reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		printk("SYM53C500: WARNING: Reserved phase!!!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	case 0x06:		/* MESSAGE-OUT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		DEB(printk("SYM53C500: Message-Out phase\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		curSC->SCp.phase = message_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		outb(SET_ATN, port_base + CMD_REG);	/* Reject the message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		outb(MSG_ACCEPT, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	case 0x07:		/* MESSAGE-IN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		VDEB(printk("SYM53C500: Message-In phase\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		curSC->SCp.phase = message_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		curSC->SCp.Status = inb(port_base + SCSI_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		curSC->SCp.Message = inb(port_base + SCSI_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		VDEB(printk("SCSI FIFO size=%d\n", inb(port_base + FIFO_FLAGS) & 0x1f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		DEB(printk("Status = %02x  Message = %02x\n", curSC->SCp.Status, curSC->SCp.Message));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		if (curSC->SCp.Message == SAVE_POINTERS || curSC->SCp.Message == DISCONNECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 			outb(SET_ATN, port_base + CMD_REG);	/* Reject message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			DEB(printk("Discarding SAVE_POINTERS message\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		outb(MSG_ACCEPT, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	spin_unlock_irqrestore(dev->host_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) idle_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	curSC->SCp.phase = idle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	curSC->scsi_done(curSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) SYM53C500_release(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	struct scsi_info_t *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	struct Scsi_Host *shost = info->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	dev_dbg(&link->dev, "SYM53C500_release\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	*  Do this before releasing/freeing resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	scsi_remove_host(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	*  Interrupts getting hosed on card removal.  Try
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	*  the following code, mostly from qlogicfas.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (shost->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		free_irq(shost->irq, shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (shost->io_port && shost->n_io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		release_region(shost->io_port, shost->n_io_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	pcmcia_disable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	scsi_host_put(shost);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) } /* SYM53C500_release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static const char*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) SYM53C500_info(struct Scsi_Host *SChost)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	static char info_msg[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	struct sym53c500_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 	    (struct sym53c500_data *)SChost->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	DEB(printk("SYM53C500_info called\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	(void)snprintf(info_msg, sizeof(info_msg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	    "SYM53C500 at 0x%lx, IRQ %d, %s PIO mode.", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	    SChost->io_port, SChost->irq, data->fast_pio ? "fast" : "slow");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	return (info_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) SYM53C500_queue_lck(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	int port_base = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 	struct sym53c500_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	    (struct sym53c500_data *)SCpnt->device->host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	VDEB(printk("SYM53C500_queue called\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 	DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	    SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->id, 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 		   (u8)SCpnt->device->lun,  scsi_bufflen(SCpnt)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	VDEB(for (i = 0; i < SCpnt->cmd_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	    printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	VDEB(printk("\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	data->current_SC = SCpnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	data->current_SC->scsi_done = done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	data->current_SC->SCp.phase = command_ph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 	data->current_SC->SCp.Status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	data->current_SC->SCp.Message = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	/* We are locked here already by the mid layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	REG0(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	outb(scmd_id(SCpnt), port_base + DEST_ID);	/* set destination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	outb(FLUSH_FIFO, port_base + CMD_REG);	/* reset the fifos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	for (i = 0; i < SCpnt->cmd_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		outb(SCpnt->cmnd[i], port_base + SCSI_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	outb(SELECT_NO_ATN, port_base + CMD_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) static DEF_SCSI_QCMD(SYM53C500_queue)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static int 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	int port_base = SCpnt->device->host->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	DEB(printk("SYM53C500_host_reset called\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	spin_lock_irq(SCpnt->device->host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	SYM53C500_int_host_reset(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	spin_unlock_irq(SCpnt->device->host->host_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	return SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static int 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) SYM53C500_biosparm(struct scsi_device *disk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)     struct block_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)     sector_t capacity, int *info_array)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	DEB(printk("SYM53C500_biosparm called\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	size = capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	info_array[0] = 64;		/* heads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	info_array[1] = 32;		/* sectors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	info_array[2] = size >> 11;	/* cylinders */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	if (info_array[2] > 1024) {	/* big disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		info_array[0] = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 		info_array[1] = 63;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		info_array[2] = size / (255 * 63);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) SYM53C500_show_pio(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 		   char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	struct Scsi_Host *SHp = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	struct sym53c500_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	    (struct sym53c500_data *)SHp->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	return snprintf(buf, 4, "%d\n", data->fast_pio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) SYM53C500_store_pio(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		    const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	int pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	struct Scsi_Host *SHp = class_to_shost(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	struct sym53c500_data *data =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	    (struct sym53c500_data *)SHp->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	pio = simple_strtoul(buf, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	if (pio == 0 || pio == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		data->fast_pio = pio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) *  SCSI HBA device attributes we want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) *  make available via sysfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) static struct device_attribute SYM53C500_pio_attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	.attr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		.name = "fast_pio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 		.mode = (S_IRUGO | S_IWUSR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	.show = SYM53C500_show_pio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	.store = SYM53C500_store_pio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static struct device_attribute *SYM53C500_shost_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	&SYM53C500_pio_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) *  scsi_host_template initializer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static struct scsi_host_template sym53c500_driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)      .module			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)      .name			= "SYM53C500",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)      .info			= SYM53C500_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)      .queuecommand		= SYM53C500_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)      .eh_host_reset_handler	= SYM53C500_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)      .bios_param		= SYM53C500_biosparm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)      .proc_name			= "SYM53C500",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)      .can_queue			= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)      .this_id			= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)      .sg_tablesize		= 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)      .shost_attrs		= SYM53C500_shost_attrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int SYM53C500_config_check(struct pcmcia_device *p_dev, void *priv_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	p_dev->io_lines = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	if (p_dev->resource[0]->start == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 	return pcmcia_request_io(p_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) SYM53C500_config(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	struct scsi_info_t *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	int irq_level, port_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	struct Scsi_Host *host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	struct scsi_host_template *tpnt = &sym53c500_driver_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	struct sym53c500_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	dev_dbg(&link->dev, "SYM53C500_config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	info->manf_id = link->manf_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	ret = pcmcia_loop_config(link, SYM53C500_config_check, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (!link->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	ret = pcmcia_enable_device(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	*  That's the trouble with copying liberally from another driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	*  Some things probably aren't relevant, and I suspect this entire
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	*  section dealing with manufacturer IDs can be scrapped.	--rct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	if ((info->manf_id == MANFID_MACNICA) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	    (info->manf_id == MANFID_PIONEER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 	    (info->manf_id == 0x0098)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		/* set ATAcmd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		outb(0xb4, link->resource[0]->start + 0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		outb(0x24, link->resource[0]->start + 0x9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		outb(0x04, link->resource[0]->start + 0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	*  irq_level == 0 implies tpnt->can_queue == 0, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 	*  is not supported in 2.6.  Thus, only irq_level > 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	*  will be allowed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	*  Possible port_base values are as follows:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	*	0x130, 0x230, 0x280, 0x290,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	*	0x320, 0x330, 0x340, 0x350
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 	port_base = link->resource[0]->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 	irq_level = link->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	DEB(printk("SYM53C500: port_base=0x%x, irq=%d, fast_pio=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	    port_base, irq_level, USE_FAST_PIO);)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 	chip_init(port_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	host = scsi_host_alloc(tpnt, sizeof(struct sym53c500_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 	if (!host) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		printk("SYM53C500: Unable to register host, giving up.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		goto err_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 	data = (struct sym53c500_data *)host->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	if (irq_level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		if (request_irq(irq_level, SYM53C500_intr, IRQF_SHARED, "SYM53C500", host)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 			printk("SYM53C500: unable to allocate IRQ %d\n", irq_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 			goto err_free_scsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		DEB(printk("SYM53C500: allocated IRQ %d\n", irq_level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	} else if (irq_level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		DEB(printk("SYM53C500: No interrupts detected\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		goto err_free_scsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		DEB(printk("SYM53C500: Shouldn't get here!\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		goto err_free_scsi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	host->unique_id = port_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	host->irq = irq_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	host->io_port = port_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	host->n_io_port = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	host->dma_channel = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	*  Note fast_pio is set to USE_FAST_PIO by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	*  default, but can be changed via "sysfs".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 	data->fast_pio = USE_FAST_PIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	info->host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	if (scsi_add_host(host, NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		goto err_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 	scsi_scan_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) err_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	free_irq(irq_level, host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) err_free_scsi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	scsi_host_put(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) err_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 	release_region(port_base, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	printk(KERN_INFO "sym53c500_cs: no SCSI devices found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	SYM53C500_release(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) } /* SYM53C500_config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static int sym53c500_resume(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	struct scsi_info_t *info = link->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	/* See earlier comment about manufacturer IDs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	if ((info->manf_id == MANFID_MACNICA) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	    (info->manf_id == MANFID_PIONEER) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	    (info->manf_id == 0x0098)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		outb(0x80, link->resource[0]->start + 0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		outb(0x24, link->resource[0]->start + 0x9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 		outb(0x04, link->resource[0]->start + 0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	 *  If things don't work after a "resume",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	 *  this is a good place to start looking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	SYM53C500_int_host_reset(link->resource[0]->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) SYM53C500_detach(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	dev_dbg(&link->dev, "SYM53C500_detach\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	SYM53C500_release(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	kfree(link->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 	link->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) } /* SYM53C500_detach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) SYM53C500_probe(struct pcmcia_device *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	struct scsi_info_t *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	dev_dbg(&link->dev, "SYM53C500_attach()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 	/* Create new SCSI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 	info = kzalloc(sizeof(*info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	info->p_dev = link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	link->priv = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 	return SYM53C500_config(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) } /* SYM53C500_attach */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) MODULE_AUTHOR("Bob Tracy <rct@frus.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) MODULE_DESCRIPTION("SYM53C500 PCMCIA SCSI driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static const struct pcmcia_device_id sym53c500_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	PCMCIA_DEVICE_PROD_ID12("BASICS by New Media Corporation", "SCSI Sym53C500", 0x23c78a9d, 0x0099e7f7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "SCSI Bus Toaster Sym53C500", 0x085a850b, 0x45432eb8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	PCMCIA_DEVICE_PROD_ID2("SCSI9000", 0x21648f44),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	PCMCIA_DEVICE_NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) MODULE_DEVICE_TABLE(pcmcia, sym53c500_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static struct pcmcia_driver sym53c500_cs_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	.name		= "sym53c500_cs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	.probe		= SYM53C500_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	.remove		= SYM53C500_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	.id_table       = sym53c500_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	.resume		= sym53c500_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) module_pcmcia_driver(sym53c500_cs_driver);