Orange Pi5 kernel

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

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Generic Generic NCR5380 driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright 1993, Drew Eckhardt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Visionary Computing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * (Unix and Linux consulting and custom programming)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * drew@colorado.edu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * +1 (303) 440-4894
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * K.Lentin@cs.monash.edu.au
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * NCR53C400A extensions (c) 1996, Ingmar Baumgart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * ingmar@gonzo.schwaben.de
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * DTC3181E extensions (c) 1997, Ronald van Cuijlenborg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * ronald.van.cuijlenborg@tip.nl or nutty@dds.nl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Added ISAPNP support for DTC436 adapters,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Thomas Sailer, sailer@ife.ee.ethz.ch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * See Documentation/scsi/g_NCR5380.rst for more info.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/isa.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/pnp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) /* Definitions for the core NCR5380 driver. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define NCR5380_read(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	ioread8(hostdata->io + hostdata->offset + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define NCR5380_write(reg, value) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	iowrite8(value, hostdata->io + hostdata->offset + (reg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define NCR5380_implementation_fields \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	int offset; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	int c400_ctl_status; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	int c400_blk_cnt; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	int c400_host_buf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	int io_width; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	int pdma_residual; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	int board
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define NCR5380_dma_xfer_len            generic_NCR5380_dma_xfer_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define NCR5380_dma_recv_setup          generic_NCR5380_precv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define NCR5380_dma_send_setup          generic_NCR5380_psend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define NCR5380_dma_residual            generic_NCR5380_dma_residual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define NCR5380_intr                    generic_NCR5380_intr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define NCR5380_queue_command           generic_NCR5380_queue_command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define NCR5380_abort                   generic_NCR5380_abort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define NCR5380_host_reset              generic_NCR5380_host_reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define NCR5380_info                    generic_NCR5380_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define NCR5380_io_delay(x)             udelay(x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #include "NCR5380.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define DRV_MODULE_NAME "g_NCR5380"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define NCR53C400_mem_base 0x3880
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define NCR53C400_host_buffer 0x3900
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define NCR53C400_region_size 0x3a00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define BOARD_NCR5380 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #define BOARD_NCR53C400 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define BOARD_NCR53C400A 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define BOARD_DTC3181E 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define BOARD_HP_C2502 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define IRQ_AUTO 254
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define MAX_CARDS 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define DMA_MAX_SIZE 32768
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /* old-style parameters for compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) static int ncr_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) static int ncr_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static int ncr_5380;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) static int ncr_53c400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static int ncr_53c400a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) static int dtc_3181e;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) static int hp_c2502;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) module_param_hw(ncr_irq, int, irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) module_param_hw(ncr_addr, int, ioport, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) module_param(ncr_5380, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) module_param(ncr_53c400, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) module_param(ncr_53c400a, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) module_param(dtc_3181e, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) module_param(hp_c2502, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int irq[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) module_param_hw_array(irq, int, irq, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) MODULE_PARM_DESC(irq, "IRQ number(s) (0=none, 254=auto [default])");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int base[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) module_param_hw_array(base, int, ioport, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) MODULE_PARM_DESC(base, "base address(es)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static int card[] = { -1, -1, -1, -1, -1, -1, -1, -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) module_param_array(card, int, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) MODULE_PARM_DESC(card, "card type (0=NCR5380, 1=NCR53C400, 2=NCR53C400A, 3=DTC3181E, 4=HP C2502)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) MODULE_ALIAS("g_NCR5380_mmio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void g_NCR5380_trigger_irq(struct Scsi_Host *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	 * An interrupt is triggered whenever BSY = false, SEL = true
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	 * and a bit set in the SELECT_ENABLE_REG is asserted on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	 * SCSI bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	 * Note that the bus is only driven when the phase control signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	 * (I/O, C/D, and MSG) match those in the TCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	NCR5380_write(TARGET_COMMAND_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	              PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	NCR5380_write(INITIATOR_COMMAND_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	              ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	NCR5380_write(SELECT_ENABLE_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	NCR5380_write(TARGET_COMMAND_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * g_NCR5380_probe_irq - find the IRQ of a NCR5380 or equivalent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * @instance: SCSI host instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * Autoprobe for the IRQ line used by the card by triggering an IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * and then looking to see what interrupt actually turned up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int g_NCR5380_probe_irq(struct Scsi_Host *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	int irq_mask, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	irq_mask = probe_irq_on();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	g_NCR5380_trigger_irq(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	irq = probe_irq_off(irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	NCR5380_read(RESET_PARITY_INTERRUPT_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (irq <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return NO_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)  * Configure I/O address of 53C400A or DTC436 by writing magic numbers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)  * to ports 0x779 and 0x379.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void magic_configure(int idx, u8 irq, u8 magic[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	u8 cfg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	outb(magic[0], 0x779);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	outb(magic[1], 0x379);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	outb(magic[2], 0x379);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	outb(magic[3], 0x379);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	outb(magic[4], 0x379);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (irq == 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		irq = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (idx >= 0 && idx <= 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		cfg = 0x80 | idx | (irq << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	outb(cfg, 0x379);
^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) static irqreturn_t legacy_empty_irq_handler(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int legacy_find_free_irq(int *irq_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	while (*irq_table != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		if (!request_irq(*irq_table, legacy_empty_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		                 IRQF_PROBE_SHARED, "Test IRQ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		                 (void *)irq_table)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			free_irq(*irq_table, (void *) irq_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			return *irq_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		irq_table++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	return -1;
^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) static unsigned int ncr_53c400a_ports[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static unsigned int dtc_3181e_ports[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	0x220, 0x240, 0x280, 0x2a0, 0x2c0, 0x300, 0x320, 0x340, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static u8 ncr_53c400a_magic[] = {	/* 53C400A & DTC436 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	0x59, 0xb9, 0xc5, 0xae, 0xa6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static u8 hp_c2502_magic[] = {	/* HP C2502 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	0x0f, 0x22, 0xf0, 0x20, 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int hp_c2502_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	9, 5, 7, 3, 4, -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) static int generic_NCR5380_init_one(struct scsi_host_template *tpnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 			struct device *pdev, int base, int irq, int board)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	bool is_pmio = base <= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	unsigned int *ports = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	u8 *magic = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	int port_idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	unsigned long region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	struct Scsi_Host *instance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	struct NCR5380_hostdata *hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	u8 __iomem *iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	switch (board) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	case BOARD_NCR5380:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	case BOARD_NCR53C400A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		ports = ncr_53c400a_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		magic = ncr_53c400a_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	case BOARD_HP_C2502:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		ports = ncr_53c400a_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		magic = hp_c2502_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	case BOARD_DTC3181E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		ports = dtc_3181e_ports;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		magic = ncr_53c400a_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (is_pmio && ports && magic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		/* wakeup sequence for the NCR53C400A and DTC3181E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		/* Disable the adapter and look for a free io port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		magic_configure(-1, 0, magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		region_size = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		if (base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			for (i = 0; ports[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 				if (base == ports[i]) {	/* index found */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 					if (!request_region(ports[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 							    region_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 							    "ncr53c80"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 						return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			for (i = 0; ports[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 				if (!request_region(ports[i], region_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 						    "ncr53c80"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 					continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 				if (inb(ports[i]) == 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 				release_region(ports[i], region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		if (ports[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			/* At this point we have our region reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			magic_configure(i, 0, magic); /* no IRQ yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			base = ports[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			outb(0xc0, base + 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			if (inb(base + 9) != 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 				goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			port_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	} else if (is_pmio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		/* NCR5380 - no configuration, just grab */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		region_size = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		if (!base || !request_region(base, region_size, "ncr5380"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	} else {	/* MMIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		region_size = NCR53C400_region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		if (!request_mem_region(base, region_size, "ncr5380"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	if (is_pmio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		iomem = ioport_map(base, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		iomem = ioremap(base, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	if (!iomem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	instance = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	if (instance == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		goto out_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	hostdata = shost_priv(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	hostdata->board = board;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	hostdata->io = iomem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	hostdata->region_size = region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	if (is_pmio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		hostdata->io_port = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		hostdata->io_width = 1; /* 8-bit PDMA by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		hostdata->offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		 * On NCR53C400 boards, NCR5380 registers are mapped 8 past
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		 * the base address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		switch (board) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		case BOARD_NCR53C400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			hostdata->io_port += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			hostdata->c400_ctl_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 			hostdata->c400_blk_cnt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 			hostdata->c400_host_buf = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		case BOARD_DTC3181E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			hostdata->io_width = 2;	/* 16-bit PDMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		case BOARD_NCR53C400A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		case BOARD_HP_C2502:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			hostdata->c400_ctl_status = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			hostdata->c400_blk_cnt = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 			hostdata->c400_host_buf = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		hostdata->base = base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		hostdata->offset = NCR53C400_mem_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		switch (board) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		case BOARD_NCR53C400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			hostdata->c400_ctl_status = 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 			hostdata->c400_blk_cnt = 0x101;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			hostdata->c400_host_buf = 0x104;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		case BOARD_DTC3181E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		case BOARD_NCR53C400A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		case BOARD_HP_C2502:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 			pr_err(DRV_MODULE_NAME ": unknown register offsets\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			goto out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	/* Check for vacant slot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	NCR5380_write(MODE_REG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (NCR5380_read(MODE_REG) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		goto out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 		goto out_unregister;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	switch (board) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	case BOARD_NCR53C400:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	case BOARD_DTC3181E:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	case BOARD_NCR53C400A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	case BOARD_HP_C2502:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	NCR5380_maybe_reset_bus(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	/* Compatibility with documented NCR5380 kernel parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	if (irq == 255 || irq == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		irq = NO_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	else if (irq == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		irq = IRQ_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	if (board == BOARD_HP_C2502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		int *irq_table = hp_c2502_irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		int board_irq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		switch (irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		case NO_IRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			board_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		case IRQ_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			board_irq = legacy_find_free_irq(irq_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			while (*irq_table != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 				if (*irq_table++ == irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 					board_irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		if (board_irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 			board_irq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 			irq = NO_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		magic_configure(port_idx, board_irq, magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	if (irq == IRQ_AUTO) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		instance->irq = g_NCR5380_probe_irq(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		if (instance->irq == NO_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 			shost_printk(KERN_INFO, instance, "no irq detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		instance->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		if (instance->irq == NO_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			shost_printk(KERN_INFO, instance, "no irq provided\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	if (instance->irq != NO_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		if (request_irq(instance->irq, generic_NCR5380_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				0, "NCR5380", instance)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			instance->irq = NO_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			shost_printk(KERN_INFO, instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			             "irq %d denied\n", instance->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 			shost_printk(KERN_INFO, instance,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			             "irq %d acquired\n", instance->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	ret = scsi_add_host(instance, pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		goto out_free_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	scsi_scan_host(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	dev_set_drvdata(pdev, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) out_free_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	if (instance->irq != NO_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		free_irq(instance->irq, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	NCR5380_exit(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) out_unregister:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	scsi_host_put(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) out_unmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	iounmap(iomem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (is_pmio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		release_region(base, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		release_mem_region(base, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) static void generic_NCR5380_release_resources(struct Scsi_Host *instance)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	void __iomem *iomem = hostdata->io;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	unsigned long io_port = hostdata->io_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	unsigned long base = hostdata->base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	unsigned long region_size = hostdata->region_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	scsi_remove_host(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	if (instance->irq != NO_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		free_irq(instance->irq, instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	NCR5380_exit(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	scsi_host_put(instance);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	iounmap(iomem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	if (io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		release_region(io_port, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		release_mem_region(base, region_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* wait_for_53c80_access - wait for 53C80 registers to become accessible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)  * @hostdata: scsi host private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)  * The registers within the 53C80 logic block are inaccessible until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)  * bit 7 in the 53C400 control status register gets asserted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static void wait_for_53c80_access(struct NCR5380_hostdata *hostdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	int count = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		if (hostdata->board == BOARD_DTC3181E)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 			udelay(4); /* DTC436 chip hangs without this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	} while (--count > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	scmd_printk(KERN_ERR, hostdata->connected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	            "53c80 registers not accessible, device will be reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)  * generic_NCR5380_precv - pseudo DMA receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)  * @hostdata: scsi host private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)  * @dst: buffer to write into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)  * @len: transfer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)  * Perform a pseudo DMA mode receive from a 53C400 or equivalent device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static inline int generic_NCR5380_precv(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)                                         unsigned char *dst, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	int residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	int start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	NCR5380_write(hostdata->c400_blk_cnt, len / 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		if (start == len - 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			/* Ignore End of DMA interrupt for the final buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 			if (NCR5380_poll_politely(hostdata, hostdata->c400_ctl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			                          CSR_HOST_BUF_NOT_RDY, 0, HZ / 64) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			                           CSR_HOST_BUF_NOT_RDY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			                           hostdata->c400_ctl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			                           CSR_GATED_53C80_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			                           CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			    NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		if (hostdata->io_port && hostdata->io_width == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			insw(hostdata->io_port + hostdata->c400_host_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 			     dst + start, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		else if (hostdata->io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			insb(hostdata->io_port + hostdata->c400_host_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			     dst + start, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 			memcpy_fromio(dst + start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 				hostdata->io + NCR53C400_host_buffer, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		start += 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	} while (start < len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	residual = len - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	if (residual != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		/* 53c80 interrupt or transfer timeout. Reset 53c400 logic. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	wait_for_53c80_access(hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (residual == 0 && NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	                                           BASR_END_DMA_TRANSFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	                                           BASR_END_DMA_TRANSFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	                                           HZ / 64) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		scmd_printk(KERN_ERR, hostdata->connected, "%s: End of DMA timeout\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		            __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	hostdata->pdma_residual = residual;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)  * generic_NCR5380_psend - pseudo DMA send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)  * @hostdata: scsi host private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)  * @src: buffer to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)  * @len: transfer size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)  * Perform a pseudo DMA mode send to a 53C400 or equivalent device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)                                         unsigned char *src, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	int residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	int start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	NCR5380_write(hostdata->c400_blk_cnt, len / 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		if (NCR5380_poll_politely2(hostdata, hostdata->c400_ctl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		                           CSR_HOST_BUF_NOT_RDY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 		                           hostdata->c400_ctl_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		                           CSR_GATED_53C80_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		                           CSR_GATED_53C80_IRQ, HZ / 64) < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		    NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			/* Both 128 B buffers are in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			if (start >= 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 				start -= 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			if (start >= 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 				start -= 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 		if (start >= len && NCR5380_read(hostdata->c400_blk_cnt) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 			/* Host buffer is empty, other one is in use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 			if (start >= 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 				start -= 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 		if (start >= len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 		if (hostdata->io_port && hostdata->io_width == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			outsw(hostdata->io_port + hostdata->c400_host_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 			      src + start, 64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		else if (hostdata->io_port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 			outsb(hostdata->io_port + hostdata->c400_host_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 			      src + start, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 			memcpy_toio(hostdata->io + NCR53C400_host_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 			            src + start, 128);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		start += 128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	} while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	residual = len - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	if (residual != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		/* 53c80 interrupt or transfer timeout. Reset 53c400 logic. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		NCR5380_write(hostdata->c400_ctl_status, CSR_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		NCR5380_write(hostdata->c400_ctl_status, CSR_BASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	wait_for_53c80_access(hostdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	if (residual == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 		if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		                          TCR_LAST_BYTE_SENT, TCR_LAST_BYTE_SENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		                          HZ / 64) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 			scmd_printk(KERN_ERR, hostdata->connected,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			            "%s: Last Byte Sent timeout\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 		if (NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		                          BASR_END_DMA_TRANSFER, BASR_END_DMA_TRANSFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 		                          HZ / 64) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			scmd_printk(KERN_ERR, hostdata->connected, "%s: End of DMA timeout\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 			            __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	hostdata->pdma_residual = residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)                                         struct scsi_cmnd *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 	int transfersize = cmd->SCp.this_residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	/* 53C400 datasheet: non-modulo-128-byte transfers should use PIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	if (transfersize % 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	/* Limit PDMA send to 512 B to avoid random corruption on DTC3181E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	if (hostdata->board == BOARD_DTC3181E &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	    cmd->sc_data_direction == DMA_TO_DEVICE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		transfersize = min(cmd->SCp.this_residual, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	return min(transfersize, DMA_MAX_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static int generic_NCR5380_dma_residual(struct NCR5380_hostdata *hostdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	return hostdata->pdma_residual;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* Include the core driver code. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) #include "NCR5380.c"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static struct scsi_host_template driver_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	.module			= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	.proc_name		= DRV_MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	.name			= "Generic NCR5380/NCR53C400 SCSI",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	.info			= generic_NCR5380_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	.queuecommand		= generic_NCR5380_queue_command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	.eh_abort_handler	= generic_NCR5380_abort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	.eh_host_reset_handler	= generic_NCR5380_host_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	.can_queue		= 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	.this_id		= 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	.sg_tablesize		= SG_ALL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	.cmd_per_lun		= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	.dma_boundary		= PAGE_SIZE - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	.cmd_size		= NCR5380_CMD_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	.max_sectors		= 128,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) static int generic_NCR5380_isa_match(struct device *pdev, unsigned int ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	int ret = generic_NCR5380_init_one(&driver_template, pdev, base[ndev],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	                                   irq[ndev], card[ndev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 		if (base[ndev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 			printk(KERN_WARNING "Card not found at address 0x%03x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 			       base[ndev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) static int generic_NCR5380_isa_remove(struct device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)                                       unsigned int ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	generic_NCR5380_release_resources(dev_get_drvdata(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	dev_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static struct isa_driver generic_NCR5380_isa_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 	.match		= generic_NCR5380_isa_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	.remove		= generic_NCR5380_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		.name	= DRV_MODULE_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static const struct pnp_device_id generic_NCR5380_pnp_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	{ .id = "DTC436e", .driver_data = BOARD_DTC3181E },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	{ .id = "" }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) MODULE_DEVICE_TABLE(pnp, generic_NCR5380_pnp_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) static int generic_NCR5380_pnp_probe(struct pnp_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)                                      const struct pnp_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	int base, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	if (pnp_activate_dev(pdev) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	base = pnp_port_start(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 	irq = pnp_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 	return generic_NCR5380_init_one(&driver_template, &pdev->dev, base, irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	                                id->driver_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) static void generic_NCR5380_pnp_remove(struct pnp_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	generic_NCR5380_release_resources(pnp_get_drvdata(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	pnp_set_drvdata(pdev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static struct pnp_driver generic_NCR5380_pnp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	.name		= DRV_MODULE_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 	.id_table	= generic_NCR5380_pnp_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 	.probe		= generic_NCR5380_pnp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 	.remove		= generic_NCR5380_pnp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) #endif /* defined(CONFIG_PNP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int pnp_registered, isa_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) static int __init generic_NCR5380_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	/* compatibility with old-style parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 	if (irq[0] == -1 && base[0] == 0 && card[0] == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 		irq[0] = ncr_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 		base[0] = ncr_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		if (ncr_5380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			card[0] = BOARD_NCR5380;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 		if (ncr_53c400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 			card[0] = BOARD_NCR53C400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 		if (ncr_53c400a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 			card[0] = BOARD_NCR53C400A;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 		if (dtc_3181e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			card[0] = BOARD_DTC3181E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		if (hp_c2502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 			card[0] = BOARD_HP_C2502;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	if (!pnp_register_driver(&generic_NCR5380_pnp_driver))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 		pnp_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	ret = isa_register_driver(&generic_NCR5380_isa_driver, MAX_CARDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 		isa_registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	return (pnp_registered || isa_registered) ? 0 : ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) static void __exit generic_NCR5380_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) #ifdef CONFIG_PNP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 	if (pnp_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 		pnp_unregister_driver(&generic_NCR5380_pnp_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	if (isa_registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 		isa_unregister_driver(&generic_NCR5380_isa_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) module_init(generic_NCR5380_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) module_exit(generic_NCR5380_exit);