^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);