Commit 3679a65c authored by Dave Jones's avatar Dave Jones Committed by Linus Torvalds

[PATCH] un'fix' NCR scsi driver.

Linus,
 Current driver in your tree has been 'fixed' by someone without
understanding just how broken it was. Numerous fixes were done in 2.4
after the 2.5 split by Alan.

This patch reverts the damage the driver does in your tree, and brings
Alan's 2.4 bits over instead. Downside: It doesn't compile.
Upside: It doesn't pretend to work and corrupt data, and at least
is the right base for people to start fixing.
parent 0170bcbb
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -55,6 +55,8 @@
#define NDEBUG_C400_PWRITE 0x200000
#define NDEBUG_LISTS 0x400000
#define NDEBUG_ANY 0xFFFFFFFFUL
/*
* The contents of the OUTPUT DATA register are asserted on the bus when
* either arbitration is occurring or the phase-indicating signals (
......@@ -62,8 +64,8 @@
* bit in the INITIATOR COMMAND register is set.
*/
#define OUTPUT_DATA_REG 0 /* wo DATA lines on SCSI bus */
#define CURRENT_SCSI_DATA_REG 0 /* ro same */
#define OUTPUT_DATA_REG 0 /* wo DATA lines on SCSI bus */
#define CURRENT_SCSI_DATA_REG 0 /* ro same */
#define INITIATOR_COMMAND_REG 1 /* rw */
#define ICR_ASSERT_RST 0x80 /* rw Set to assert RST */
......@@ -91,10 +93,10 @@
*/
#define MR_BLOCK_DMA_MODE 0x80 /* rw block mode DMA */
#define MR_TARGET 0x40 /* rw target mode */
#define MR_ENABLE_PAR_CHECK 0x20 /* rw enable parity checking */
#define MR_ENABLE_PAR_CHECK 0x20 /* rw enable parity checking */
#define MR_ENABLE_PAR_INTR 0x10 /* rw enable bad parity interrupt */
#define MR_ENABLE_EOP_INTR 0x08 /* rw enable eop interrupt */
#define MR_MONITOR_BSY 0x04 /* rw enable int on unexpected bsy fail */
#define MR_MONITOR_BSY 0x04 /* rw enable int on unexpected bsy fail */
#define MR_DMA_MODE 0x02 /* rw DMA / pseudo DMA mode */
#define MR_ARBITRATE 0x01 /* rw start arbitration */
......@@ -116,7 +118,7 @@
* Note : a set bit indicates an active signal, driven by us or another
* device.
*/
#define SR_RST 0x80
#define SR_RST 0x80
#define SR_BSY 0x40
#define SR_REQ 0x20
#define SR_MSG 0x10
......@@ -159,17 +161,17 @@
/* Write any value to this register to start an ini mode DMA receive */
#define START_DMA_INITIATOR_RECEIVE_REG 7 /* wo */
#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8 /* rw */
#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8 /* rw */
#define CSR_RESET 0x80 /* wo Resets 53c400 */
#define CSR_53C80_REG 0x80 /* ro 5380 registers busy */
#define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
#define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */
#define CSR_53C80_INTR 0x10 /* rw Enable 53c80 interrupts */
#define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */
#define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Is Host buffer ready */
#define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer read */
#define CSR_GATED_53C80_IRQ 0x01 /* ro Last block xferred */
#define CSR_RESET 0x80 /* wo Resets 53c400 */
#define CSR_53C80_REG 0x80 /* ro 5380 registers busy */
#define CSR_TRANS_DIR 0x40 /* rw Data transfer direction */
#define CSR_SCSI_BUFF_INTR 0x20 /* rw Enable int on transfer ready */
#define CSR_53C80_INTR 0x10 /* rw Enable 53c80 interrupts */
#define CSR_SHARED_INTR 0x08 /* rw Interrupt sharing */
#define CSR_HOST_BUF_NOT_RDY 0x04 /* ro Is Host buffer ready */
#define CSR_SCSI_BUF_RDY 0x02 /* ro SCSI buffer read */
#define CSR_GATED_53C80_IRQ 0x01 /* ro Last block xferred */
#if 0
#define CSR_BASE CSR_SCSI_BUFF_INTR | CSR_53C80_INTR
......@@ -178,13 +180,13 @@
#endif
/* Number of 128-byte blocks to be transferred */
#define C400_BLOCK_COUNTER_REG NCR53C400_register_offset-7 /* rw */
#define C400_BLOCK_COUNTER_REG NCR53C400_register_offset-7 /* rw */
/* Resume transfer after disconnect */
#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6 /* wo */
#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6 /* wo */
/* Access to host buffer stack */
#define C400_HOST_BUFFER NCR53C400_register_offset-4 /* rw */
#define C400_HOST_BUFFER NCR53C400_register_offset-4 /* rw */
/* Note : PHASE_* macros are based on the values of the STATUS register */
......@@ -203,8 +205,8 @@
* the target register so we can get phase mismatch interrupts on DMA
* transfers.
*/
#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
#define PHASE_SR_TO_TCR(phase) ((phase) >> 2)
/*
* The internal should_disconnect() function returns these based on the
......@@ -220,7 +222,7 @@
* These are "special" values for the tag parameter passed to NCR5380_select.
*/
#define TAG_NEXT -1 /* Use next free tag */
#define TAG_NEXT -1 /* Use next free tag */
#define TAG_NONE -2 /*
* Establish I_T_L nexus instead of I_T_L_Q
* even on SCSI-II devices.
......@@ -235,7 +237,7 @@
#define DMA_NONE 255
#define IRQ_AUTO 254
#define DMA_AUTO 254
#define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */
#define PORT_AUTO 0xffff /* autoprobe io port for 53c400a */
#define FLAG_HAS_LAST_BYTE_SENT 1 /* NCR53c81 or better */
#define FLAG_CHECK_LAST_BYTE_SENT 2 /* Only test once */
......@@ -245,134 +247,188 @@
#ifndef ASM
struct NCR5380_hostdata {
NCR5380_implementation_fields; /* implementation specific */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected
NCR5380_implementation_fields; /* implementation specific */
unsigned char id_mask, id_higher_mask; /* 1 << id, all bits greater */
unsigned char targets_present; /* targets we have connected
to, so we can call a select
failure a retryable condition */
volatile unsigned char busy[8]; /* index = target, bit = lun */
volatile unsigned char busy[8]; /* index = target, bit = lun */
#if defined(REAL_DMA) || defined(REAL_DMA_POLL)
volatile int dma_len; /* requested length of DMA */
volatile int dma_len; /* requested length of DMA */
#endif
volatile unsigned char last_message; /* last message OUT */
volatile Scsi_Cmnd *connected; /* currently connected command */
volatile Scsi_Cmnd *issue_queue; /* waiting to be issued */
volatile Scsi_Cmnd *disconnected_queue; /* waiting for reconnect */
volatile int restart_select; /* we have disconnected,
volatile unsigned char last_message; /* last message OUT */
volatile Scsi_Cmnd *connected; /* currently connected command */
volatile Scsi_Cmnd *issue_queue; /* waiting to be issued */
volatile Scsi_Cmnd *disconnected_queue; /* waiting for reconnect */
volatile int restart_select; /* we have disconnected,
used to restart
NCR5380_select() */
volatile unsigned aborted:1; /* flag, says aborted */
int flags;
#ifdef USLEEP
unsigned long time_expires; /* in jiffies, set prior to sleeping */
struct Scsi_Host *next_timer;
int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting;
#endif
volatile unsigned aborted:1; /* flag, says aborted */
int flags;
unsigned long time_expires; /* in jiffies, set prior to sleeping */
struct Scsi_Host *next_timer;
int select_time; /* timer in select for target response */
volatile Scsi_Cmnd *selecting;
#ifdef NCR5380_STATS
unsigned timebase; /* Base for time calcs */
long time_read[8]; /* time to do reads */
long time_write[8]; /* time to do writes */
unsigned long bytes_read[8]; /* bytes read */
unsigned long bytes_write[8]; /* bytes written */
unsigned pendingr;
unsigned pendingw;
unsigned timebase; /* Base for time calcs */
long time_read[8]; /* time to do reads */
long time_write[8]; /* time to do writes */
unsigned long bytes_read[8]; /* bytes read */
unsigned long bytes_write[8]; /* bytes written */
unsigned pendingr;
unsigned pendingw;
#endif
};
#ifdef __KERNEL__
static struct Scsi_Host *first_instance; /* linked list of 5380's */
static struct Scsi_Host *first_instance; /* linked list of 5380's */
#define dprintk(a,b) do {} while(0)
#define NCR5380_dprint(a,b) do {} while(0)
#define NCR5380_dprint_phase(a,b) do {} while(0)
#if defined(AUTOPROBE_IRQ)
static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible);
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif
static void NCR5380_init (struct Scsi_Host *instance, int flags);
static void NCR5380_information_transfer (struct Scsi_Host *instance);
static void NCR5380_init(struct Scsi_Host *instance, int flags);
static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR
static void NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
static void do_NCR5380_intr (int irq, void *dev_id, struct pt_regs * regs);
static void NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
static void do_NCR5380_intr(int irq, void *dev_id, struct pt_regs *regs);
#endif
static void NCR5380_main (void);
static void NCR5380_print_options (struct Scsi_Host *instance);
static void NCR5380_print_phase (struct Scsi_Host *instance);
static void NCR5380_print (struct Scsi_Host *instance);
static void NCR5380_main(void);
static void NCR5380_print_options(struct Scsi_Host *instance);
static void NCR5380_print_phase(struct Scsi_Host *instance);
static void NCR5380_print(struct Scsi_Host *instance);
#ifndef NCR5380_abort
static
#endif
int NCR5380_abort (Scsi_Cmnd *cmd);
int NCR5380_abort(Scsi_Cmnd * cmd);
#ifndef NCR5380_reset
static
#endif
int NCR5380_reset (Scsi_Cmnd *cmd, unsigned int reset_flags);
int NCR5380_reset(Scsi_Cmnd * cmd, unsigned int reset_flags);
#ifndef NCR5380_queue_command
static
static
#endif
int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *));
int NCR5380_queue_command(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *));
static void NCR5380_reselect (struct Scsi_Host *instance);
static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag);
static void NCR5380_reselect(struct Scsi_Host *instance);
static int NCR5380_select(struct Scsi_Host *instance, Scsi_Cmnd * cmd, int tag);
#if defined(PSEUDO_DMA) || defined(REAL_DMA) || defined(REAL_DMA_POLL)
static int NCR5380_transfer_dma (struct Scsi_Host *instance,
unsigned char *phase, int *count, unsigned char **data);
static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
#endif
static int NCR5380_transfer_pio (struct Scsi_Host *instance,
unsigned char *phase, int *count, unsigned char **data);
static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data);
#if (defined(REAL_DMA) || defined(REAL_DMA_POLL))
#if defined(i386) || defined(__alpha__)
static __inline__ int NCR5380_pc_dma_setup (struct Scsi_Host *instance,
unsigned char *ptr, unsigned int count, unsigned char mode) {
unsigned limit;
unsigned long bus_addr = virt_to_bus(ptr);
if (instance->dma_channel <=3) {
if (count > 65536)
count = 65536;
limit = 65536 - (bus_addr & 0xFFFF);
} else {
if (count > 65536 * 2)
count = 65536 * 2;
limit = 65536* 2 - (bus_addr & 0x1FFFF);
}
if (count > limit) count = limit;
if ((count & 1) || (bus_addr & 1))
panic ("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
cli();
disable_dma(instance->dma_channel);
clear_dma_ff(instance->dma_channel);
set_dma_addr(instance->dma_channel, bus_addr);
set_dma_count(instance->dma_channel, count);
set_dma_mode(instance->dma_channel, mode);
enable_dma(instance->dma_channel);
sti();
return count;
/**
* NCR5380_pc_dma_setup - setup ISA DMA
* @instance: adapter to set up
* @ptr: block to transfer (virtual address)
* @count: number of bytes to transfer
* @mode: DMA controller mode to use
*
* Program the DMA controller ready to perform an ISA DMA transfer
* on this chip.
*
* Locks: takes and releases the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_setup(struct Scsi_Host *instance, unsigned char *ptr, unsigned int count, unsigned char mode)
{
unsigned limit;
unsigned long bus_addr = virt_to_bus(ptr);
unsigned long flags;
if (instance->dma_channel <= 3) {
if (count > 65536)
count = 65536;
limit = 65536 - (bus_addr & 0xFFFF);
} else {
if (count > 65536 * 2)
count = 65536 * 2;
limit = 65536 * 2 - (bus_addr & 0x1FFFF);
}
if (count > limit)
count = limit;
if ((count & 1) || (bus_addr & 1))
panic("scsi%d : attempted unaligned DMA transfer\n", instance->host_no);
flags=claim_dma_lock();
disable_dma(instance->dma_channel);
clear_dma_ff(instance->dma_channel);
set_dma_addr(instance->dma_channel, bus_addr);
set_dma_count(instance->dma_channel, count);
set_dma_mode(instance->dma_channel, mode);
enable_dma(instance->dma_channel);
release_dma_lock(flags);
return count;
}
static __inline__ int NCR5380_pc_dma_write_setup (struct Scsi_Host *instance,
unsigned char *src, unsigned int count) {
return NCR5380_pc_dma_setup (instance, src, count, DMA_MODE_WRITE);
/**
* NCR5380_pc_dma_write_setup - setup ISA DMA write
* @instance: adapter to set up
* @ptr: block to transfer (virtual address)
* @count: number of bytes to transfer
*
* Program the DMA controller ready to perform an ISA DMA write to the
* SCSI controller.
*
* Locks: called routines take and release the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_write_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
{
return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_WRITE);
}
static __inline__ int NCR5380_pc_dma_read_setup (struct Scsi_Host *instance,
unsigned char *src, unsigned int count) {
return NCR5380_pc_dma_setup (instance, src, count, DMA_MODE_READ);
/**
* NCR5380_pc_dma_read_setup - setup ISA DMA read
* @instance: adapter to set up
* @ptr: block to transfer (virtual address)
* @count: number of bytes to transfer
*
* Program the DMA controller ready to perform an ISA DMA read from the
* SCSI controller.
*
* Locks: called routines take and release the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_read_setup(struct Scsi_Host *instance, unsigned char *src, unsigned int count)
{
return NCR5380_pc_dma_setup(instance, src, count, DMA_MODE_READ);
}
static __inline__ int NCR5380_pc_dma_residual (struct Scsi_Host *instance) {
register int tmp;
cli();
clear_dma_ff(instance->dma_channel);
tmp = get_dma_residue(instance->dma_channel);
sti();
return tmp;
/**
* NCR5380_pc_dma_residual - return bytes left
* @instance: adapter
*
* Reports the number of bytes left over after the DMA was terminated.
*
* Locks: takes and releases the ISA DMA lock.
*/
static __inline__ int NCR5380_pc_dma_residual(struct Scsi_Host *instance)
{
unsigned long flags;
int tmp;
flags = claim_dma_lock();
clear_dma_ff(instance->dma_channel);
tmp = get_dma_residue(instance->dma_channel);
release_dma_lock(flags);
return tmp;
}
#endif /* defined(i386) || defined(__alpha__) */
#endif /* defined(REAL_DMA) */
#endif /* __KERNEL__ */
#endif /* ndef ASM */
#endif /* NCR5380_H */
#endif /* defined(i386) || defined(__alpha__) */
#endif /* defined(REAL_DMA) */
#endif /* __KERNEL__ */
#endif /* ndef ASM */
#endif /* NCR5380_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment