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: Michael Schmitz <schmitz@debian.org> Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
8d41f0e8d5
commit
fb810d121b
|
@ -1649,7 +1649,7 @@ config OKTAGON_SCSI
|
||||||
|
|
||||||
config ATARI_SCSI
|
config ATARI_SCSI
|
||||||
tristate "Atari native SCSI support"
|
tristate "Atari native SCSI support"
|
||||||
depends on ATARI && SCSI && BROKEN
|
depends on ATARI && SCSI
|
||||||
select SCSI_SPI_ATTRS
|
select SCSI_SPI_ATTRS
|
||||||
---help---
|
---help---
|
||||||
If you have an Atari with built-in NCR5380 SCSI controller (TT,
|
If you have an Atari with built-in NCR5380 SCSI controller (TT,
|
||||||
|
|
|
@ -264,7 +264,7 @@ static struct scsi_host_template *the_template = NULL;
|
||||||
(struct NCR5380_hostdata *)(in)->hostdata
|
(struct NCR5380_hostdata *)(in)->hostdata
|
||||||
#define HOSTDATA(in) ((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 NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble))
|
||||||
|
|
||||||
#define HOSTNO instance->host_no
|
#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");
|
printk("NCR5380_print_status: no memory for print buffer\n");
|
||||||
return;
|
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;
|
pr_bfr[len] = 0;
|
||||||
printk("\n%s\n", pr_bfr);
|
printk("\n%s\n", pr_bfr);
|
||||||
free_page((unsigned long) pr_bfr);
|
free_page((unsigned long) pr_bfr);
|
||||||
|
@ -877,6 +877,46 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags)
|
||||||
return 0;
|
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,
|
* Function : int NCR5380_queue_command (Scsi_Cmnd *cmd,
|
||||||
* void (*done)(Scsi_Cmnd *))
|
* void (*done)(Scsi_Cmnd *))
|
||||||
|
@ -902,7 +942,7 @@ int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
|
||||||
Scsi_Cmnd *tmp;
|
Scsi_Cmnd *tmp;
|
||||||
int oldto;
|
int oldto;
|
||||||
unsigned long flags;
|
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)
|
#if (NDEBUG & NDEBUG_NO_WRITE)
|
||||||
switch (cmd->cmnd[0]) {
|
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.
|
* alter queues and touch the lock.
|
||||||
*/
|
*/
|
||||||
if (!IS_A_TT()) {
|
if (!IS_A_TT()) {
|
||||||
oldto = update_timeout(cmd, 0);
|
oldto = atari_scsi_update_timeout(cmd, 0);
|
||||||
falcon_get_lock();
|
falcon_get_lock();
|
||||||
update_timeout(cmd, oldto);
|
atari_scsi_update_timeout(cmd, oldto);
|
||||||
}
|
}
|
||||||
if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
|
if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) {
|
||||||
LIST(cmd, hostdata->issue_queue);
|
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);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
/* Wait for arbitration logic to complete */
|
/* Wait for arbitration logic to complete */
|
||||||
#if NCR_TIMEOUT
|
#if defined(NCR_TIMEOUT)
|
||||||
{
|
{
|
||||||
unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
|
unsigned long timeout = jiffies + 2*NCR_TIMEOUT;
|
||||||
|
|
||||||
|
|
|
@ -395,7 +395,7 @@ static irqreturn_t scsi_tt_intr (int irq, void *dummy)
|
||||||
|
|
||||||
#endif /* REAL_DMA */
|
#endif /* REAL_DMA */
|
||||||
|
|
||||||
NCR5380_intr (0, 0, 0);
|
NCR5380_intr(0, 0);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* To be sure the int is not masked */
|
/* 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 */
|
#endif /* REAL_DMA */
|
||||||
|
|
||||||
NCR5380_intr (0, 0, 0);
|
NCR5380_intr(0, 0);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -557,11 +557,11 @@ static void falcon_get_lock( void )
|
||||||
|
|
||||||
local_irq_save(flags);
|
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 );
|
sleep_on( &falcon_fairness_wait );
|
||||||
|
|
||||||
while (!falcon_got_lock) {
|
while (!falcon_got_lock) {
|
||||||
if (in_interrupt())
|
if (in_irq())
|
||||||
panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" );
|
panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" );
|
||||||
if (!falcon_trying_lock) {
|
if (!falcon_trying_lock) {
|
||||||
falcon_trying_lock = 1;
|
falcon_trying_lock = 1;
|
||||||
|
@ -763,7 +763,6 @@ int atari_scsi_detect (struct scsi_host_template *host)
|
||||||
return( 1 );
|
return( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE
|
|
||||||
int atari_scsi_release (struct Scsi_Host *sh)
|
int atari_scsi_release (struct Scsi_Host *sh)
|
||||||
{
|
{
|
||||||
if (IS_A_TT())
|
if (IS_A_TT())
|
||||||
|
@ -772,7 +771,6 @@ int atari_scsi_release (struct Scsi_Host *sh)
|
||||||
atari_stram_free (atari_dma_buffer);
|
atari_stram_free (atari_dma_buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void __init atari_scsi_setup(char *str, int *ints)
|
void __init atari_scsi_setup(char *str, int *ints)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,11 +21,7 @@
|
||||||
int atari_scsi_detect (struct scsi_host_template *);
|
int atari_scsi_detect (struct scsi_host_template *);
|
||||||
const char *atari_scsi_info (struct Scsi_Host *);
|
const char *atari_scsi_info (struct Scsi_Host *);
|
||||||
int atari_scsi_reset (Scsi_Cmnd *, unsigned int);
|
int atari_scsi_reset (Scsi_Cmnd *, unsigned int);
|
||||||
#ifdef MODULE
|
|
||||||
int atari_scsi_release (struct Scsi_Host *);
|
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
|
/* 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!) */
|
* 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) \
|
#define NCR5380_dma_xfer_len(i,cmd,phase) \
|
||||||
atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1)
|
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:
|
/* Debugging printk definitions:
|
||||||
*
|
*
|
||||||
* ARB -> arbitration
|
* ARB -> arbitration
|
||||||
|
|
Loading…
Reference in New Issue