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

Commit fb810d12 authored by Michael Schmitz's avatar Michael Schmitz Committed by Linus Torvalds
Browse files

m68k: Atari SCSI revival



SCSI should be working on a TT (but someone should really try!) but causes
trouble on a Falcon (as in: it ate a filesystem of mine) at least when
used concurrently with IDE. I have the notion it's because locking of the
ST-DMA interrupt by IDE is broken in 2.6 (the IDE driver always complains
about trying to release an already-released ST-DMA). Needs more work, but
that's on the IDE or m68k interrupt side rather than SCSI.

Signed-off-by: default avatarMichael Schmitz <schmitz@debian.org>
Signed-off-by: default avatarRoman Zippel <zippel@linux-m68k.org>
Signed-off-by: default avatarGeert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 8d41f0e8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1649,7 +1649,7 @@ config OKTAGON_SCSI

config ATARI_SCSI
	tristate "Atari native SCSI support"
	depends on ATARI && SCSI && BROKEN
	depends on ATARI && SCSI
	select SCSI_SPI_ATTRS
	---help---
	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
+46 −6
Original line number Diff line number Diff line
@@ -264,7 +264,7 @@ static struct scsi_host_template *the_template = NULL;
	(struct NCR5380_hostdata *)(in)->hostdata
#define	HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata)

#define	NEXT(cmd)	((Scsi_Cmnd *)((cmd)->host_scribble))
#define	NEXT(cmd)	((cmd)->host_scribble)
#define	NEXTADDR(cmd)	((Scsi_Cmnd **)&((cmd)->host_scribble))

#define	HOSTNO		instance->host_no
@@ -716,7 +716,7 @@ static void NCR5380_print_status (struct Scsi_Host *instance)
	printk("NCR5380_print_status: no memory for print buffer\n");
	return;
    }
    len = NCR5380_proc_info(pr_bfr, &start, 0, PAGE_SIZE, HOSTNO, 0);
    len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0);
    pr_bfr[len] = 0;
    printk("\n%s\n", pr_bfr);
    free_page((unsigned long) pr_bfr);
@@ -877,6 +877,46 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags)
    return 0;
}

/* 
 * our own old-style timeout update
 */
/*
 * The strategy is to cause the timer code to call scsi_times_out()
 * when the soonest timeout is pending.
 * The arguments are used when we are queueing a new command, because
 * we do not want to subtract the time used from this time, but when we
 * set the timer, we want to take this value into account.
 */

int atari_scsi_update_timeout(Scsi_Cmnd * SCset, int timeout)
{
    int rtn;

    /*
     * We are using the new error handling code to actually register/deregister
     * timers for timeout.
     */

    if (!timer_pending(&SCset->eh_timeout)) {
	rtn = 0;
    } else {
	rtn = SCset->eh_timeout.expires - jiffies;
    }

    if (timeout == 0) {
        del_timer(&SCset->eh_timeout);
        SCset->eh_timeout.data = (unsigned long) NULL;
        SCset->eh_timeout.expires = 0;
    } else {
        if (SCset->eh_timeout.data != (unsigned long) NULL) 
            del_timer(&SCset->eh_timeout);
        SCset->eh_timeout.data = (unsigned long) SCset;
        SCset->eh_timeout.expires = jiffies + timeout;
        add_timer(&SCset->eh_timeout);
    }
	return rtn;
}

/* 
 * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, 
 *	void (*done)(Scsi_Cmnd *)) 
@@ -902,7 +942,7 @@ int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
    Scsi_Cmnd *tmp;
    int oldto;
    unsigned long flags;
    extern int update_timeout(Scsi_Cmnd * SCset, int timeout);
    // extern int update_timeout(Scsi_Cmnd * SCset, int timeout);

#if (NDEBUG & NDEBUG_NO_WRITE)
    switch (cmd->cmnd[0]) {
@@ -978,9 +1018,9 @@ int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
     * alter queues and touch the lock.
     */
    if (!IS_A_TT()) {
	oldto = update_timeout(cmd, 0);
	oldto = atari_scsi_update_timeout(cmd, 0);
	falcon_get_lock();
	update_timeout(cmd, oldto);
	atari_scsi_update_timeout(cmd, oldto);
    }
    if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
	LIST(cmd, hostdata->issue_queue);
@@ -1435,7 +1475,7 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag)
    local_irq_restore(flags);

    /* Wait for arbitration logic to complete */
#if NCR_TIMEOUT
#if defined(NCR_TIMEOUT)
    {
      unsigned long timeout = jiffies + 2*NCR_TIMEOUT;

+4 −6
Original line number Diff line number Diff line
@@ -395,7 +395,7 @@ static irqreturn_t scsi_tt_intr (int irq, void *dummy)

#endif /* REAL_DMA */
	
	NCR5380_intr (0, 0, 0);
	NCR5380_intr(0, 0);

#if 0
	/* To be sure the int is not masked */
@@ -461,7 +461,7 @@ static irqreturn_t scsi_falcon_intr (int irq, void *dummy)

#endif /* REAL_DMA */

	NCR5380_intr (0, 0, 0);
	NCR5380_intr(0, 0);
	return IRQ_HANDLED;
}

@@ -557,11 +557,11 @@ static void falcon_get_lock( void )

	local_irq_save(flags);

	while( !in_interrupt() && falcon_got_lock && stdma_others_waiting() )
	while (!in_irq() && falcon_got_lock && stdma_others_waiting())
		sleep_on( &falcon_fairness_wait );

	while (!falcon_got_lock) {
		if (in_interrupt())
		if (in_irq())
			panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" );
		if (!falcon_trying_lock) {
			falcon_trying_lock = 1;
@@ -763,7 +763,6 @@ int atari_scsi_detect (struct scsi_host_template *host)
	return( 1 );
}

#ifdef MODULE
int atari_scsi_release (struct Scsi_Host *sh)
{
	if (IS_A_TT())
@@ -772,7 +771,6 @@ int atari_scsi_release (struct Scsi_Host *sh)
		atari_stram_free (atari_dma_buffer);
	return 1;
}
#endif

void __init atari_scsi_setup(char *str, int *ints)
{
+26 −4
Original line number Diff line number Diff line
@@ -21,11 +21,7 @@
int atari_scsi_detect (struct scsi_host_template *);
const char *atari_scsi_info (struct Scsi_Host *);
int atari_scsi_reset (Scsi_Cmnd *, unsigned int);
#ifdef MODULE
int atari_scsi_release (struct Scsi_Host *);
#else
#define atari_scsi_release NULL
#endif

/* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher
 * values should work, too; try it! (but cmd_per_lun costs memory!) */
@@ -63,6 +59,32 @@ int atari_scsi_release (struct Scsi_Host *);
#define	NCR5380_dma_xfer_len(i,cmd,phase) \
	atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1)

/* former generic SCSI error handling stuff */

#define SCSI_ABORT_SNOOZE 0
#define SCSI_ABORT_SUCCESS 1
#define SCSI_ABORT_PENDING 2
#define SCSI_ABORT_BUSY 3
#define SCSI_ABORT_NOT_RUNNING 4
#define SCSI_ABORT_ERROR 5

#define SCSI_RESET_SNOOZE 0
#define SCSI_RESET_PUNT 1
#define SCSI_RESET_SUCCESS 2
#define SCSI_RESET_PENDING 3
#define SCSI_RESET_WAKEUP 4
#define SCSI_RESET_NOT_RUNNING 5
#define SCSI_RESET_ERROR 6

#define SCSI_RESET_SYNCHRONOUS		0x01
#define SCSI_RESET_ASYNCHRONOUS		0x02
#define SCSI_RESET_SUGGEST_BUS_RESET	0x04
#define SCSI_RESET_SUGGEST_HOST_RESET	0x08

#define SCSI_RESET_BUS_RESET 0x100
#define SCSI_RESET_HOST_RESET 0x200
#define SCSI_RESET_ACTION   0xff

/* Debugging printk definitions:
 *
 *  ARB  -> arbitration