diff options
author | Michael Schmitz <schmitz@opal.biophys.uni-duesseldorf.de> | 2007-05-01 16:32:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-04 20:59:05 -0400 |
commit | fb810d121bceb945c5e576356bccba11cbfad7e3 (patch) | |
tree | 0dcaf0ebdc97e059326ce152e621e04caf9ede12 | |
parent | 8d41f0e8d51742aba5bbcab9acb5238a8578c917 (diff) |
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>
-rw-r--r-- | drivers/scsi/Kconfig | 2 | ||||
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 52 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.c | 10 | ||||
-rw-r--r-- | drivers/scsi/atari_scsi.h | 30 |
4 files changed, 77 insertions, 17 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index fcc4cb6c7f46..e1ebed0f0755 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -1649,7 +1649,7 @@ config OKTAGON_SCSI | |||
1649 | 1649 | ||
1650 | config ATARI_SCSI | 1650 | config ATARI_SCSI |
1651 | tristate "Atari native SCSI support" | 1651 | tristate "Atari native SCSI support" |
1652 | depends on ATARI && SCSI && BROKEN | 1652 | depends on ATARI && SCSI |
1653 | select SCSI_SPI_ATTRS | 1653 | select SCSI_SPI_ATTRS |
1654 | ---help--- | 1654 | ---help--- |
1655 | If you have an Atari with built-in NCR5380 SCSI controller (TT, | 1655 | If you have an Atari with built-in NCR5380 SCSI controller (TT, |
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 0f920c84ac0f..1b4612c71ce2 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -264,7 +264,7 @@ static struct scsi_host_template *the_template = NULL; | |||
264 | (struct NCR5380_hostdata *)(in)->hostdata | 264 | (struct NCR5380_hostdata *)(in)->hostdata |
265 | #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) | 265 | #define HOSTDATA(in) ((struct NCR5380_hostdata *)(in)->hostdata) |
266 | 266 | ||
267 | #define NEXT(cmd) ((Scsi_Cmnd *)((cmd)->host_scribble)) | 267 | #define NEXT(cmd) ((cmd)->host_scribble) |
268 | #define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble)) | 268 | #define NEXTADDR(cmd) ((Scsi_Cmnd **)&((cmd)->host_scribble)) |
269 | 269 | ||
270 | #define HOSTNO instance->host_no | 270 | #define HOSTNO instance->host_no |
@@ -716,7 +716,7 @@ static void NCR5380_print_status (struct Scsi_Host *instance) | |||
716 | printk("NCR5380_print_status: no memory for print buffer\n"); | 716 | printk("NCR5380_print_status: no memory for print buffer\n"); |
717 | return; | 717 | return; |
718 | } | 718 | } |
719 | len = NCR5380_proc_info(pr_bfr, &start, 0, PAGE_SIZE, HOSTNO, 0); | 719 | len = NCR5380_proc_info(instance, pr_bfr, &start, 0, PAGE_SIZE, 0); |
720 | pr_bfr[len] = 0; | 720 | pr_bfr[len] = 0; |
721 | printk("\n%s\n", pr_bfr); | 721 | printk("\n%s\n", pr_bfr); |
722 | free_page((unsigned long) pr_bfr); | 722 | free_page((unsigned long) pr_bfr); |
@@ -878,6 +878,46 @@ static int NCR5380_init (struct Scsi_Host *instance, int flags) | |||
878 | } | 878 | } |
879 | 879 | ||
880 | /* | 880 | /* |
881 | * our own old-style timeout update | ||
882 | */ | ||
883 | /* | ||
884 | * The strategy is to cause the timer code to call scsi_times_out() | ||
885 | * when the soonest timeout is pending. | ||
886 | * The arguments are used when we are queueing a new command, because | ||
887 | * we do not want to subtract the time used from this time, but when we | ||
888 | * set the timer, we want to take this value into account. | ||
889 | */ | ||
890 | |||
891 | int atari_scsi_update_timeout(Scsi_Cmnd * SCset, int timeout) | ||
892 | { | ||
893 | int rtn; | ||
894 | |||
895 | /* | ||
896 | * We are using the new error handling code to actually register/deregister | ||
897 | * timers for timeout. | ||
898 | */ | ||
899 | |||
900 | if (!timer_pending(&SCset->eh_timeout)) { | ||
901 | rtn = 0; | ||
902 | } else { | ||
903 | rtn = SCset->eh_timeout.expires - jiffies; | ||
904 | } | ||
905 | |||
906 | if (timeout == 0) { | ||
907 | del_timer(&SCset->eh_timeout); | ||
908 | SCset->eh_timeout.data = (unsigned long) NULL; | ||
909 | SCset->eh_timeout.expires = 0; | ||
910 | } else { | ||
911 | if (SCset->eh_timeout.data != (unsigned long) NULL) | ||
912 | del_timer(&SCset->eh_timeout); | ||
913 | SCset->eh_timeout.data = (unsigned long) SCset; | ||
914 | SCset->eh_timeout.expires = jiffies + timeout; | ||
915 | add_timer(&SCset->eh_timeout); | ||
916 | } | ||
917 | return rtn; | ||
918 | } | ||
919 | |||
920 | /* | ||
881 | * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, | 921 | * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, |
882 | * void (*done)(Scsi_Cmnd *)) | 922 | * void (*done)(Scsi_Cmnd *)) |
883 | * | 923 | * |
@@ -902,7 +942,7 @@ int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) | |||
902 | Scsi_Cmnd *tmp; | 942 | Scsi_Cmnd *tmp; |
903 | int oldto; | 943 | int oldto; |
904 | unsigned long flags; | 944 | unsigned long flags; |
905 | extern int update_timeout(Scsi_Cmnd * SCset, int timeout); | 945 | // extern int update_timeout(Scsi_Cmnd * SCset, int timeout); |
906 | 946 | ||
907 | #if (NDEBUG & NDEBUG_NO_WRITE) | 947 | #if (NDEBUG & NDEBUG_NO_WRITE) |
908 | switch (cmd->cmnd[0]) { | 948 | switch (cmd->cmnd[0]) { |
@@ -978,9 +1018,9 @@ int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) | |||
978 | * alter queues and touch the lock. | 1018 | * alter queues and touch the lock. |
979 | */ | 1019 | */ |
980 | if (!IS_A_TT()) { | 1020 | if (!IS_A_TT()) { |
981 | oldto = update_timeout(cmd, 0); | 1021 | oldto = atari_scsi_update_timeout(cmd, 0); |
982 | falcon_get_lock(); | 1022 | falcon_get_lock(); |
983 | update_timeout(cmd, oldto); | 1023 | atari_scsi_update_timeout(cmd, oldto); |
984 | } | 1024 | } |
985 | if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { | 1025 | if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { |
986 | LIST(cmd, hostdata->issue_queue); | 1026 | LIST(cmd, hostdata->issue_queue); |
@@ -1435,7 +1475,7 @@ static int NCR5380_select (struct Scsi_Host *instance, Scsi_Cmnd *cmd, int tag) | |||
1435 | local_irq_restore(flags); | 1475 | local_irq_restore(flags); |
1436 | 1476 | ||
1437 | /* Wait for arbitration logic to complete */ | 1477 | /* Wait for arbitration logic to complete */ |
1438 | #if NCR_TIMEOUT | 1478 | #if defined(NCR_TIMEOUT) |
1439 | { | 1479 | { |
1440 | unsigned long timeout = jiffies + 2*NCR_TIMEOUT; | 1480 | unsigned long timeout = jiffies + 2*NCR_TIMEOUT; |
1441 | 1481 | ||
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c index 642de7b2b7a2..85b8acc94034 100644 --- a/drivers/scsi/atari_scsi.c +++ b/drivers/scsi/atari_scsi.c | |||
@@ -395,7 +395,7 @@ static irqreturn_t scsi_tt_intr (int irq, void *dummy) | |||
395 | 395 | ||
396 | #endif /* REAL_DMA */ | 396 | #endif /* REAL_DMA */ |
397 | 397 | ||
398 | NCR5380_intr (0, 0, 0); | 398 | NCR5380_intr(0, 0); |
399 | 399 | ||
400 | #if 0 | 400 | #if 0 |
401 | /* To be sure the int is not masked */ | 401 | /* To be sure the int is not masked */ |
@@ -461,7 +461,7 @@ static irqreturn_t scsi_falcon_intr (int irq, void *dummy) | |||
461 | 461 | ||
462 | #endif /* REAL_DMA */ | 462 | #endif /* REAL_DMA */ |
463 | 463 | ||
464 | NCR5380_intr (0, 0, 0); | 464 | NCR5380_intr(0, 0); |
465 | return IRQ_HANDLED; | 465 | return IRQ_HANDLED; |
466 | } | 466 | } |
467 | 467 | ||
@@ -557,11 +557,11 @@ static void falcon_get_lock( void ) | |||
557 | 557 | ||
558 | local_irq_save(flags); | 558 | local_irq_save(flags); |
559 | 559 | ||
560 | while( !in_interrupt() && falcon_got_lock && stdma_others_waiting() ) | 560 | while (!in_irq() && falcon_got_lock && stdma_others_waiting()) |
561 | sleep_on( &falcon_fairness_wait ); | 561 | sleep_on( &falcon_fairness_wait ); |
562 | 562 | ||
563 | while (!falcon_got_lock) { | 563 | while (!falcon_got_lock) { |
564 | if (in_interrupt()) | 564 | if (in_irq()) |
565 | panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" ); | 565 | panic( "Falcon SCSI hasn't ST-DMA lock in interrupt" ); |
566 | if (!falcon_trying_lock) { | 566 | if (!falcon_trying_lock) { |
567 | falcon_trying_lock = 1; | 567 | falcon_trying_lock = 1; |
@@ -763,7 +763,6 @@ int atari_scsi_detect (struct scsi_host_template *host) | |||
763 | return( 1 ); | 763 | return( 1 ); |
764 | } | 764 | } |
765 | 765 | ||
766 | #ifdef MODULE | ||
767 | int atari_scsi_release (struct Scsi_Host *sh) | 766 | int atari_scsi_release (struct Scsi_Host *sh) |
768 | { | 767 | { |
769 | if (IS_A_TT()) | 768 | if (IS_A_TT()) |
@@ -772,7 +771,6 @@ int atari_scsi_release (struct Scsi_Host *sh) | |||
772 | atari_stram_free (atari_dma_buffer); | 771 | atari_stram_free (atari_dma_buffer); |
773 | return 1; | 772 | return 1; |
774 | } | 773 | } |
775 | #endif | ||
776 | 774 | ||
777 | void __init atari_scsi_setup(char *str, int *ints) | 775 | void __init atari_scsi_setup(char *str, int *ints) |
778 | { | 776 | { |
diff --git a/drivers/scsi/atari_scsi.h b/drivers/scsi/atari_scsi.h index f917bdd09b41..75b549b2dfc1 100644 --- a/drivers/scsi/atari_scsi.h +++ b/drivers/scsi/atari_scsi.h | |||
@@ -21,11 +21,7 @@ | |||
21 | int atari_scsi_detect (struct scsi_host_template *); | 21 | int atari_scsi_detect (struct scsi_host_template *); |
22 | const char *atari_scsi_info (struct Scsi_Host *); | 22 | const char *atari_scsi_info (struct Scsi_Host *); |
23 | int atari_scsi_reset (Scsi_Cmnd *, unsigned int); | 23 | int atari_scsi_reset (Scsi_Cmnd *, unsigned int); |
24 | #ifdef MODULE | ||
25 | int atari_scsi_release (struct Scsi_Host *); | 24 | int atari_scsi_release (struct Scsi_Host *); |
26 | #else | ||
27 | #define atari_scsi_release NULL | ||
28 | #endif | ||
29 | 25 | ||
30 | /* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher | 26 | /* The values for CMD_PER_LUN and CAN_QUEUE are somehow arbitrary. Higher |
31 | * values should work, too; try it! (but cmd_per_lun costs memory!) */ | 27 | * values should work, too; try it! (but cmd_per_lun costs memory!) */ |
@@ -63,6 +59,32 @@ int atari_scsi_release (struct Scsi_Host *); | |||
63 | #define NCR5380_dma_xfer_len(i,cmd,phase) \ | 59 | #define NCR5380_dma_xfer_len(i,cmd,phase) \ |
64 | atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1) | 60 | atari_dma_xfer_len(cmd->SCp.this_residual,cmd,((phase) & SR_IO) ? 0 : 1) |
65 | 61 | ||
62 | /* former generic SCSI error handling stuff */ | ||
63 | |||
64 | #define SCSI_ABORT_SNOOZE 0 | ||
65 | #define SCSI_ABORT_SUCCESS 1 | ||
66 | #define SCSI_ABORT_PENDING 2 | ||
67 | #define SCSI_ABORT_BUSY 3 | ||
68 | #define SCSI_ABORT_NOT_RUNNING 4 | ||
69 | #define SCSI_ABORT_ERROR 5 | ||
70 | |||
71 | #define SCSI_RESET_SNOOZE 0 | ||
72 | #define SCSI_RESET_PUNT 1 | ||
73 | #define SCSI_RESET_SUCCESS 2 | ||
74 | #define SCSI_RESET_PENDING 3 | ||
75 | #define SCSI_RESET_WAKEUP 4 | ||
76 | #define SCSI_RESET_NOT_RUNNING 5 | ||
77 | #define SCSI_RESET_ERROR 6 | ||
78 | |||
79 | #define SCSI_RESET_SYNCHRONOUS 0x01 | ||
80 | #define SCSI_RESET_ASYNCHRONOUS 0x02 | ||
81 | #define SCSI_RESET_SUGGEST_BUS_RESET 0x04 | ||
82 | #define SCSI_RESET_SUGGEST_HOST_RESET 0x08 | ||
83 | |||
84 | #define SCSI_RESET_BUS_RESET 0x100 | ||
85 | #define SCSI_RESET_HOST_RESET 0x200 | ||
86 | #define SCSI_RESET_ACTION 0xff | ||
87 | |||
66 | /* Debugging printk definitions: | 88 | /* Debugging printk definitions: |
67 | * | 89 | * |
68 | * ARB -> arbitration | 90 | * ARB -> arbitration |