Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d2cf867 authored by Finn Thain's avatar Finn Thain Committed by Martin K. Petersen
Browse files

ncr5380: Merge changes from atari_NCR5380.c



In the past, NCR5380.c was overlooked by those working on atari_NCR5380.c
and this caused needless divergence. All of the changes in this patch were
taken from atari_NCR5380.c.

This removes some unimportant discrepancies between the two core driver
forks so that 'diff' can be used to reveal the important ones, to
facilitate reunification.

Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Tested-by: default avatarOndrej Zary <linux@rainbow-software.org>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 594d4ba3
Loading
Loading
Loading
Loading
+87 −68
Original line number Diff line number Diff line
@@ -264,19 +264,6 @@ static inline int NCR5380_poll_politely(struct Scsi_Host *instance,
	                                        reg, bit, val, wait);
}

static struct {
	unsigned char value;
	const char *name;
} phases[] __maybe_unused = {
	{PHASE_DATAOUT, "DATAOUT"},
	{PHASE_DATAIN, "DATAIN"},
	{PHASE_CMDOUT, "CMDOUT"},
	{PHASE_STATIN, "STATIN"},
	{PHASE_MSGOUT, "MSGOUT"},
	{PHASE_MSGIN, "MSGIN"},
	{PHASE_UNKNOWN, "UNKNOWN"}
};

#if NDEBUG
static struct {
	unsigned char mask;
@@ -311,6 +298,7 @@ mrs[] = {
	{MR_TARGET, "MODE TARGET"},
	{MR_ENABLE_PAR_CHECK, "MODE PARITY CHECK"},
	{MR_ENABLE_PAR_INTR, "MODE PARITY INTR"},
	{MR_ENABLE_EOP_INTR, "MODE EOP INTR"},
	{MR_MONITOR_BSY, "MODE MONITOR BSY"},
	{MR_DMA_MODE, "MODE DMA"},
	{MR_ARBITRATE, "MODE ARBITRATION"},
@@ -353,6 +341,18 @@ static void NCR5380_print(struct Scsi_Host *instance)
	printk("\n");
}

static struct {
	unsigned char value;
	const char *name;
} phases[] = {
	{PHASE_DATAOUT, "DATAOUT"},
	{PHASE_DATAIN, "DATAIN"},
	{PHASE_CMDOUT, "CMDOUT"},
	{PHASE_STATIN, "STATIN"},
	{PHASE_MSGOUT, "MSGOUT"},
	{PHASE_MSGIN, "MSGIN"},
	{PHASE_UNKNOWN, "UNKNOWN"}
};

/**
 * NCR5380_print_phase - show SCSI phase
@@ -370,7 +370,9 @@ static void NCR5380_print_phase(struct Scsi_Host *instance)
	if (!(status & SR_REQ))
		shost_printk(KERN_DEBUG, instance, "REQ not asserted, phase unknown.\n");
	else {
		for (i = 0; (phases[i].value != PHASE_UNKNOWN) && (phases[i].value != (status & PHASE_MASK)); ++i);
		for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
		     (phases[i].value != (status & PHASE_MASK)); ++i)
			;
		shost_printk(KERN_DEBUG, instance, "phase %s\n", phases[i].name);
	}
}
@@ -541,10 +543,9 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
	int i;
	unsigned long deadline;

	if(in_interrupt())
		printk(KERN_ERR "NCR5380_init called with interrupts off!\n");

	hostdata->host = instance;
	hostdata->id_mask = 1 << instance->this_id;
	hostdata->id_higher_mask = 0;
	for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
		if (i > hostdata->id_mask)
			hostdata->id_higher_mask |= i;
@@ -569,8 +570,6 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
	if (!hostdata->work_q)
		return -ENOMEM;

	hostdata->host = instance;

	prepare_info(instance);

	NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
@@ -650,6 +649,8 @@ static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
/**
 * NCR5380_exit - remove an NCR5380
 * @instance: adapter to remove
 *
 * Assumes that no more work can be queued (e.g. by NCR5380_intr).
 */

static void NCR5380_exit(struct Scsi_Host *instance)
@@ -1067,7 +1068,9 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
	udelay(3);

	/* Check for lost arbitration */
	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) || (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) || (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
	if ((NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST) ||
	    (NCR5380_read(CURRENT_SCSI_DATA_REG) & hostdata->id_higher_mask) ||
	    (NCR5380_read(INITIATOR_COMMAND_REG) & ICR_ARBITRATION_LOST)) {
		NCR5380_write(MODE_REG, MR_BASE);
		dsprintk(NDEBUG_ARBITRATION, instance, "lost arbitration, deasserting MR_ARBITRATE\n");
		spin_lock_irq(&hostdata->lock);
@@ -1270,7 +1273,7 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
 * bytes to transfer, **data - pointer to data pointer.
 *
 * Returns : -1 when different phase is entered without transferring
 * maximum number of bytes, 0 if all bytes or transferred or exit
 * maximum number of bytes, 0 if all bytes are transferred or exit
 * is in same phase.
 *
 * Also, *phase, *count, *data are modified in place.
@@ -1284,7 +1287,10 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
 * counts, we will always do a pseudo DMA or DMA transfer.
 */

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)
{
	unsigned char p = *phase, tmp;
	int c = *count;
	unsigned char *d = *data;
@@ -1314,6 +1320,7 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase
			NCR5380_dprint_phase(NDEBUG_PIO, instance);
			break;
		}

		/* Do actual transfer from SCSI bus to / from memory */
		if (!(p & SR_IO))
			NCR5380_write(OUTPUT_DATA_REG, *d);
@@ -1451,12 +1458,14 @@ static int do_abort(struct Scsi_Host *instance)
	NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));

	if (tmp != PHASE_MSGOUT) {
		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
		NCR5380_write(INITIATOR_COMMAND_REG,
		              ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
		rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ);
		if (rc < 0)
			goto timeout;
		NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
	}

	tmp = ABORT;
	msgptr = &tmp;
	len = 1;
@@ -1495,7 +1504,11 @@ static int do_abort(struct Scsi_Host *instance)
 */


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)
{
	struct NCR5380_hostdata *hostdata = shost_priv(instance);
	register int c = *count;
	register unsigned char p = *phase;
	register unsigned char *d = *data;
@@ -1506,8 +1519,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
	unsigned char saved_data = 0, overrun = 0, residue;
#endif

	struct NCR5380_hostdata *hostdata = shost_priv(instance);

	if ((tmp = (NCR5380_read(STATUS_REG) & PHASE_MASK)) != p) {
		*phase = tmp;
		return -1;
@@ -1737,7 +1748,8 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase
 * to recover from an unexpected bus free condition.
 */

static void NCR5380_information_transfer(struct Scsi_Host *instance) {
static void NCR5380_information_transfer(struct Scsi_Host *instance)
{
	struct NCR5380_hostdata *hostdata = shost_priv(instance);
	unsigned char msgout = NOP;
	int sink = 0;
@@ -1764,11 +1776,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
				NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp));

				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK);
				while (NCR5380_read(STATUS_REG) & SR_REQ);
				while (NCR5380_read(STATUS_REG) & SR_REQ)
					;
				NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
				sink = 0;
				continue;
			}

			switch (phase) {
			case PHASE_DATAOUT:
#if (NDEBUG & NDEBUG_NO_DATAOUT)
@@ -1794,6 +1808,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
					         cmd->SCp.this_residual,
					         cmd->SCp.buffers_residual);
				}

				/*
				 * The preferred transfer method is going to be
				 * PSEUDO-DMA for systems that are strictly PIO,
@@ -1812,10 +1827,12 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {

				if (transfersize) {
					len = transfersize;
					if (NCR5380_transfer_dma(instance, &phase, &len, (unsigned char **) &cmd->SCp.ptr)) {
					if (NCR5380_transfer_dma(instance, &phase,
					    &len, (unsigned char **)&cmd->SCp.ptr)) {
						/*
						 * If the watchdog timer fires, all future accesses to this
						 * device will use the polled-IO.
						 * If the watchdog timer fires, all future
						 * accesses to this device will use the
						 * polled-IO.
						 */
						scmd_printk(KERN_INFO, cmd,
							"switching to slow handshake\n");
@@ -1894,7 +1911,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
						break;
					}
					break;
				case DISCONNECT:{
				case DISCONNECT:
					/* Accept message by clearing ACK */
					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
					hostdata->connected = NULL;
@@ -1912,7 +1929,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
					/* Enable reselect interrupts */
					NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
					return;
					}
					/*
					 * The SCSI data pointer is *IMPLICITLY* saved on a disconnect
					 * operation, in violation of the SCSI spec so we can safely
@@ -1994,10 +2010,12 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
						printk("\n");
					} else if (tmp != EXTENDED_MESSAGE)
						scmd_printk(KERN_INFO, cmd,
							"rejecting unknown message %02x\n",tmp);
						            "rejecting unknown message %02x\n",
						            tmp);
					else
						scmd_printk(KERN_INFO, cmd,
							"rejecting unknown extended message code %02x, length %d\n", extended_msg[1], extended_msg[0]);
						            "rejecting unknown extended message code %02x, length %d\n",
						            extended_msg[1], extended_msg[0]);

					msgout = MESSAGE_REJECT;
					NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN);
@@ -2056,7 +2074,8 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) {
 * Inputs : instance - this instance of the NCR5380.
 */

static void NCR5380_reselect(struct Scsi_Host *instance) {
static void NCR5380_reselect(struct Scsi_Host *instance)
{
	struct NCR5380_hostdata *hostdata = shost_priv(instance);
	unsigned char target_mask;
	unsigned char lun, phase;
@@ -2153,8 +2172,8 @@ static void NCR5380_reselect(struct Scsi_Host *instance) {
		shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n",
		             target_mask, lun);
		/*
		 * Since we have an established nexus that we can't do anything with,
		 * we must abort it.
		 * Since we have an established nexus that we can't do anything
		 * with, we must abort it.
		 */
		do_abort(instance);
		return;