home *** CD-ROM | disk | FTP | other *** search
/ Whiteline: Alpha / Whiteline Alpha.iso / linux / atari / source / source.lzh / atari-linux-0.01pl3 / drivers / scsi / atari_sc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-11  |  22.5 KB  |  772 lines

  1. /*
  2.  * atari_scsi.c -- Device dependant functions for the Atari generic SCSI port
  3.  *
  4.  * Copyright 1994 Roman Hodek
  5.  *   EMail: rnhodek@cip.informatik.uni-erlangen.de (Internet)
  6.  *      or: Roman_Hodek@n.maus.de (MausNet, NO mail > 16 KB!)
  7.  *
  8.  *   Loosely based on the work of Robert De Vries' team and added:
  9.  *    - working real DMA
  10.  *    - Falcon support (untested yet!)   ++bjoern fixed and now it works
  11.  *    - lots of extensions and bug fixes.
  12.  *
  13.  * This file is subject to the terms and conditions of the GNU General Public
  14.  * License.  See the file README.legal in the main directory of this archive
  15.  * for more details.
  16.  *
  17.  */
  18.  
  19.  
  20. /**************************************************************************/
  21. /*                                                                        */
  22. /* Notes for Falcon SCSI:                                                 */
  23. /* ----------------------                                                 */
  24. /*                                                                        */
  25. /* Since the Falcon SCSI uses the ST-DMA chip, that is shared among       */
  26. /* several device drivers, locking and unlocking the access to this       */
  27. /* chip is required. But locking is not possible from an interrupt,       */
  28. /* since it puts the process to sleep if the lock is not available.       */
  29. /* This prevents "late" locking of the DMA chip, i.e. locking it just     */
  30. /* before using it, since in case of disconnection-reconnection           */
  31. /* commands, the DMA is started from the reselection interrupt.           */
  32. /*                                                                        */
  33. /* Two possible schemes for ST-DMA-locking would be:                      */
  34. /*  1) The lock is taken for each command separately and disconnecting    */
  35. /*     is forbidden (i.e. can_queue = 1).                                 */
  36. /*  2) The DMA chip is locked when the first command comes in and         */
  37. /*     released when the last command is finished and all queues are      */
  38. /*     empty.                                                             */
  39. /* The first alternative would result in bad performance, since the       */
  40. /* interleaving of commands would not be used. The second is unfair to    */
  41. /* other drivers using the ST-DMA, because the queues will seldom be      */
  42. /* totally empty if there is a lot of disk traffic.                       */
  43. /*                                                                        */
  44. /* For this reasons I decided to employ a more elaborate scheme:          */
  45. /*  - First, we give up the lock everytime we can (for fairness), this    */
  46. /*    means every time a command finishes and there are no other commands */
  47. /*    on the disconnected queue.                                          */
  48. /*  - If there are others waiting to lock the DMA chip, we stop           */
  49. /*    issueing commands, i.e. moving them onto the issue queue.           */
  50. /*    Because of that, the disconnected queue will run empty in a         */
  51. /*    while. Instead we go to sleep on a 'fairness_queue'.                */
  52. /*  - If the lock is released, all processes waiting on the fairness      */
  53. /*    queue will be woken. The first of them trys to re-lock the DMA,     */
  54. /*    the others wait for the first to finish this task. After that,      */
  55. /*    they can all run on and do their commands...                        */
  56. /* This sounds complicated (and it is it :-(), but it seems to be a       */
  57. /* good compromise between fairness and performance: As long as noone     */
  58. /* else wants to work with the ST-DMA chip, SCSI can go along as          */
  59. /* usual. If now someone else comes, this behaviour is changed to a       */
  60. /* "fairness mode": just already initiated commands are finished and      */
  61. /* then the lock is released. The other one waiting will probably win     */
  62. /* the race for locking the DMA, since it was waiting for longer. And     */
  63. /* after it has finished, SCSI can go ahead again. Finally: I hope I      */
  64. /* have not produced any deadlock possibilites!                           */
  65. /*                                                                        */
  66. /**************************************************************************/
  67.  
  68.  
  69.  
  70. #include <linux/config.h>
  71.  
  72. #ifdef CONFIG_ATARI_SCSI
  73.  
  74. /* #define NDEBUG (NDEBUG_DMA) */
  75.  
  76. #define AUTOSENSE
  77. /* For the Atari version, use only polled IO or REAL_DMA */
  78. #define    REAL_DMA
  79.  
  80. #if I_HAVE_OVERRUNS == 1 || I_HAVE_OVERRUNS == 2
  81. #define    READ_OVERRUNS
  82. #endif
  83.  
  84. #include <linux/stddef.h>
  85. #include <linux/interrupt.h>
  86. #include <linux/bootinfo.h>
  87. #include <linux/atarihw.h>
  88. #include <linux/atariints.h>
  89. #include "../block/blk.h"
  90. #include "scsi.h"
  91. #include "hosts.h"
  92. #include "atari_scsi.h"
  93. #include "NCR5380.h"
  94. #include "constants.h"
  95. #include <linux/atari_stdma.h>
  96.  
  97.  
  98. #define    IS_A_TT()    (boot_info.bi_atari.model == ATARI_TT)
  99.  
  100. #define    SCSI_DMA_WRITE_P(elt,val)                                    \
  101.     __asm__ __volatile__ ( "movepl %0,%1@(0)" : : "d" (val),        \
  102.                                "a" (&tt_scsi_dma.elt) );
  103.  
  104. #define    SCSI_DMA_READ_P(elt) ({                                            \
  105.     unsigned long __val;                                                \
  106.     __asm__ __volatile__ ( "movepl %1@(0),%0"                            \
  107.                            : "=d" (__val) : "a" (&tt_scsi_dma.elt));    \
  108.     __val; })
  109.  
  110. #define    SCSI_DMA_SETADR(adr)                    \
  111.     do {                                        \
  112.         unsigned long __adr = (adr);            \
  113.         st_dma.dma_lo = (unsigned char)__adr;    \
  114.         __adr >>= 8;                            \
  115.         st_dma.dma_md = (unsigned char)__adr;    \
  116.         __adr >>= 8;                            \
  117.         st_dma.dma_hi = (unsigned char)__adr;    \
  118.     } while(0)
  119.  
  120. #define    SCSI_DMA_GETADR() ({                    \
  121.     unsigned long    __adr;                        \
  122.     __adr = st_dma.dma_lo;                        \
  123.     __asm__ __volatile__ ("nop");                \
  124.     __adr |= (st_dma.dma_md & 0xff) << 8;        \
  125.     __adr |= (st_dma.dma_hi & 0xff) << 16;        \
  126.     __adr;                                        \
  127. })
  128.  
  129.  
  130.  
  131. /***************************** Prototypes *****************************/
  132.  
  133. static void scsi_dma_buserr( struct intframe *fp, void *data);
  134. static void scsi_tt_intr( struct intframe *fp, void *data);
  135. static void scsi_falcon_intr( struct intframe *fp, void *data);
  136. static void atari_scsi_fetch_restbytes( void );
  137. static void falcon_release_lock_if_possible( struct NCR5380_hostdata *
  138.                                              hostdata );
  139. static void falcon_get_lock( void );
  140. static long atari_scsi_dma_residual( struct Scsi_Host *instance );
  141. static unsigned long atari_dma_xfer_len( unsigned long wanted_len );
  142. static unsigned char atari_scsi_tt_reg_read( unsigned char reg );
  143. static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value
  144.                                      );
  145. static unsigned char atari_scsi_falcon_reg_read( unsigned char reg );
  146. static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char
  147.                                          value );
  148.  
  149. /************************* End of Prototypes **************************/
  150.  
  151.  
  152. static struct Scsi_Host *atari_scsi_host = NULL;
  153. static unsigned char (*atari_scsi_reg_read)( unsigned char reg );
  154. static void (*atari_scsi_reg_write)( unsigned char reg, unsigned char value );
  155.  
  156. #ifdef REAL_DMA
  157. static unsigned long    atari_dma_residual, atari_dma_startaddr;
  158. static short            atari_dma_active;
  159. #endif
  160.  
  161.  
  162. #if defined(REAL_DMA)
  163.  
  164. static int scsi_dma_is_ignored_buserr( unsigned char dma_stat )
  165.  
  166. {    int                i;
  167.     unsigned long    addr = SCSI_DMA_READ_P( dma_addr_hi ), end_addr;
  168.  
  169.     if (dma_stat & 0x01) {
  170.  
  171.         /* A bus error happens when DMA-ing from the last page of a
  172.          * physical memory chunk (DMA prefetch!), but that doesn't hurt.
  173.          * Check for this case:
  174.          */
  175.         
  176.         for( i = 0; i < boot_info.num_memory; ++i ) {
  177.             end_addr = boot_info.memory[i].addr +
  178.                 boot_info.memory[i].size;
  179.             if (end_addr <= addr && addr <= end_addr + 4)
  180.                 return( 1 );
  181.         }
  182.     }
  183.     return( 0 );
  184. }
  185.  
  186.  
  187. static void scsi_dma_buserr (struct intframe *fp, void *data)
  188.  
  189. {    unsigned char    dma_stat = tt_scsi_dma.dma_ctrl;
  190.  
  191.     printk( "Bad SCSI DMA inmterrupt! dma_addr=0x%08lx dma_stat=%02x dma_cnt=%08lx\n",
  192.             SCSI_DMA_READ_P( dma_addr_hi ), dma_stat, SCSI_DMA_READ_P( dma_cnt_hi ) );
  193.     if (dma_stat & 0x80) {
  194.         if (!scsi_dma_is_ignored_buserr( dma_stat ))
  195.             panic( "SCSI DMA bus error -- bad DMA programming!" );
  196.     }
  197.     else {
  198.         /* Under normal circumstances we never should get to this point,
  199.          * since both interrupts are triggered simultaneosly and the 5380
  200.          * int has more priotity. When this irq is handled, that DMA
  201.          * interrupt is cleared. So a warning message is printed here.
  202.          */
  203.         printk( "SCSI DMA intr ?? -- this shouldn't happen!\n" );
  204.     }
  205. }
  206.  
  207. #endif
  208.  
  209. #undef    LOST_INTR
  210.  
  211. #ifdef LOST_INTR
  212. extern volatile unsigned long intr_count;
  213. unsigned long curr_intr_count;
  214.  
  215. #define    CHECK_ICNT(pos) do {                    \
  216.  if (intr_count != curr_intr_count) {            \
  217.      printk( "INTR_COUNT changed before " pos    \
  218.              ": curr_cnt=%lu intr_cnt=%lu\n",    \
  219.              curr_intr_count, intr_count );        \
  220.  }                                                \
  221. } while( 0 )
  222.  
  223. #else
  224.  
  225. #define    CHECK_ICNT(pos)
  226.  
  227. #endif
  228.  
  229.  
  230. static void scsi_tt_intr (struct intframe *fp, void *data)
  231.  
  232. {    int                dma_stat;
  233.     unsigned long    flags;
  234. #ifdef LOST_INTR
  235.     unsigned long    prev_intr_count;
  236.  
  237.     prev_intr_count = curr_intr_count;
  238.     curr_intr_count = intr_count;
  239. #endif
  240.     
  241. #ifdef REAL_DMA
  242.  
  243.     dma_stat = tt_scsi_dma.dma_ctrl;
  244.  
  245. #if (NDEBUG & NDEBUG_INTR)
  246.     printk( "scsi%d: NCR5380 interupt, DMA status = %02x\n",
  247.             atari_scsi_host->host_no, dma_stat & 0xff );
  248. #endif
  249.  
  250.     /* Look if it was the DMA that has interrupted: First possibility
  251.      * is that a bus error occured...
  252.      */
  253.     if (dma_stat & 0x80) {
  254.         if (!scsi_dma_is_ignored_buserr( dma_stat )) {
  255.             printk( "SCSI DMA caused bus error near 0x%08lx\n",
  256.                     SCSI_DMA_READ_P( dma_addr_hi ));
  257.             panic( "SCSI DMA bus error -- bad DMA programming!" );
  258.         }
  259.     }
  260.  
  261.     /* If the DMA is active but not finished, we have the the case
  262.      * that some other 5380 interrupt occured within the DMA transfer.
  263.      * This means we have residual bytes, if the desired end address
  264.      * is not yet reached. Maybe we have to fetch some bytes from the
  265.      * rest data register, too. The residual must be calculated from
  266.      * the address pointer, not the counter register, because only the
  267.      * addr reg counts bytes not yet written and pending in the rest
  268.      * data reg!
  269.      */
  270.     if ((dma_stat & 0x02) && !(dma_stat & 0x40)) {
  271.         atari_dma_residual =
  272.             ((struct NCR5380_hostdata *)(atari_scsi_host->hostdata))->dma_len -
  273.                 (SCSI_DMA_READ_P( dma_addr_hi ) - atari_dma_startaddr);
  274. #if (NDEBUG & NDEBUG_DMA)
  275.         printk( "SCSI DMA: There are %ld residual bytes.\n",
  276.                 atari_dma_residual );
  277. #endif
  278.         atari_scsi_fetch_restbytes();
  279.         tt_scsi_dma.dma_ctrl = 0;
  280.     }
  281.  
  282.     /* If the DMA is finished, fetch the rest bytes and turn it off */
  283.     if (dma_stat & 0x40) {
  284.         atari_dma_residual = 0;
  285.         atari_scsi_fetch_restbytes();
  286.         tt_scsi_dma.dma_ctrl = 0;
  287.     }
  288.  
  289. #endif /* REAL_DMA */
  290.     
  291.     /* If we got this interrupt, we don't need the other one any more */
  292.     tt_mfp.int_pn_b = (unsigned char)~0x80;
  293.  
  294.     CHECK_ICNT("calling NCR5380_intr");
  295.  
  296.     save_flags(flags);
  297.     NCR5380_intr( 0 );
  298.     restore_flags(flags);
  299.  
  300. #ifdef LOST_INTR
  301.     CHECK_ICNT("returning, after NCR5380_intr");
  302.     curr_intr_count = prev_intr_count;
  303. #endif
  304. }
  305.  
  306.  
  307. static void scsi_falcon_intr (struct intframe *fp, void *data)
  308.  
  309. {    int                dma_stat;
  310.     unsigned long    flags;
  311. #ifdef LOST_INTR
  312.     unsigned long    prev_intr_count;
  313.  
  314.     prev_intr_count = curr_intr_count;
  315.     curr_intr_count = intr_count;
  316. #endif
  317.     
  318. #ifdef REAL_DMA
  319.  
  320.     /* Turn off DMA and select sector counter register before
  321.      * accessing the status register (Atari recommendation!)
  322.      */
  323.     st_dma.dma_mode_status = 0x90;
  324.     dma_stat = st_dma.dma_mode_status;
  325.  
  326.     /* Bit 0 indicates some error in the DMA process... don't know
  327.      * what happened exactly (no further docu).
  328.      */
  329.     if (!(dma_stat & 0x01)) {
  330.         /* DMA error */
  331.         printk( "SCSI DMA error near 0x%08lx!\n", SCSI_DMA_GETADR() );
  332.     }
  333.  
  334.     /* If the DMA was active, but now bit 1 is not clear, it is some
  335.      * other 5380 interrupt that finishes the DMA transfer. We have to
  336.      * calculate the number of residual bytes and give a warning if
  337.      * bytes are stuck in the ST-DMA fifo (there's no way to reach them!)
  338.      */
  339.     if (atari_dma_active && (dma_stat & 0x02)) {
  340.         unsigned long    transferred;
  341.  
  342.         transferred = SCSI_DMA_GETADR() - atari_dma_startaddr;
  343.         /* The ST-DMA address is incremented in 2-byte steps, but the
  344.          * data are written only in 16-byte chunks. If the number of
  345.          * transferred bytes is not divisible by 16, the remainder is
  346.          * lost somewhere in outer space.
  347.          */
  348.         if (transferred & 15)
  349.             printk( "SCSI DMA error: %ld bytes lost in ST-DMA fifo :-((\n",
  350.                     transferred & 15 );
  351.  
  352.         atari_dma_residual =
  353.             ((struct NCR5380_hostdata *)(atari_scsi_host->hostdata))->dma_len -
  354.                 transferred;
  355. #if (NDEBUG & NDEBUG_DMA)
  356.         printk( "SCSI DMA: There are %ld residual bytes.\n",
  357.                 atari_dma_residual );
  358. #endif
  359.     }
  360.     else
  361.         atari_dma_residual = 0;
  362.     atari_dma_active = 0;
  363.     
  364. #endif /* REAL_DMA */
  365.  
  366.     CHECK_ICNT("calling NCR5380_intr");
  367.  
  368.     save_flags(flags);
  369.     NCR5380_intr( 0 );
  370.     restore_flags(flags);
  371.  
  372. #ifdef LOST_INTR
  373.     CHECK_ICNT("returning, after NCR5380_intr");
  374.     curr_intr_count = prev_intr_count;
  375. #endif
  376. }
  377.  
  378.  
  379. static void atari_scsi_fetch_restbytes( void )
  380.  
  381. {    int        nr;
  382.     char    *src, *dst;
  383.  
  384.     /* fetch rest bytes in the DMA register */
  385.     dst = (char *)SCSI_DMA_READ_P( dma_addr_hi );
  386.     if ((nr = ((long)dst & 3))) {
  387.         /* there are 'nr' bytes left for the last long address before the
  388.            DMA pointer */
  389.         dst = (char *)( (unsigned long)dst & ~3 );
  390. #if (NDEBUG & NDEBUG_DMA)
  391.         printk( "SCSI DMA: there are %d rest bytes for phys addr 0x%08lx",
  392.                 nr, (long)dst );
  393. #endif
  394.         dst = (char *)PTOV(dst);  /* The content of the DMA pointer
  395.                                    * is a physical address! */
  396. #if (NDEBUG & NDEBUG_DMA)
  397.         printk( " = virt addr 0x%08lx\n", (long)dst );
  398. #endif
  399.         for( src = (char *)&tt_scsi_dma.dma_restdata; nr > 0; --nr )
  400.             *dst++ = *src++;
  401.     }
  402. }
  403.  
  404.  
  405. static int                    falcon_got_lock = 0;
  406. static struct wait_queue    *falcon_fairness_wait = NULL;
  407. static int                    falcon_trying_lock = 0;
  408. static struct wait_queue    *falcon_try_wait = NULL;
  409.  
  410. /* This function releases the lock on the DMA chip if there is no
  411.  * connected command and the disconnected queue is empty. On
  412.  * releasing, instances of falcon_get_lock are awoken, that put
  413.  * themselves to sleep for fairness. They can now try to get the lock
  414.  * again (but others waiting longer more probably will win).
  415.  */
  416.  
  417. static void
  418. falcon_release_lock_if_possible( struct NCR5380_hostdata * hostdata )
  419.  
  420. {
  421.     if (IS_A_TT()) return;
  422.     
  423.     if (falcon_got_lock &&
  424.         !hostdata->disconnected_queue &&
  425.         !hostdata->issue_queue &&
  426.         !hostdata->connected) {
  427.  
  428.         unsigned long    oldflags;
  429.  
  430.         save_flags(oldflags);
  431.         cli();
  432.         
  433.         falcon_got_lock = 0;
  434.         stdma_release();
  435.         wake_up( &falcon_fairness_wait );
  436.  
  437.         restore_flags(oldflags);
  438.     }
  439. }
  440.  
  441. /* This function manages the locking of the ST-DMA.
  442.  * If the DMA isn't locked already for SCSI, it trys to lock it by
  443.  * calling stdma_lock(). But if the DMA is locked by the SCSI code and
  444.  * there are other drivers waiting for the chip, we do not issue the
  445.  * command immediatly but wait on 'falcon_fairness_queue'. We will be
  446.  * waked up when the DMA is unlocked by some SCSI interrupt. After that
  447.  * we try to get the lock again.
  448.  * But we must be prepared that more then one instance of
  449.  * falcon_get_lock() is waiting on the fairness queue. They should not
  450.  * try all at once to call stdma_lock(), one is enough! For that, the
  451.  * first one sets 'falcon_trying_lock', others that see that variable
  452.  * set wait on the queue 'falcon_try_wait'.
  453.  * Complicated, complicated.... Sigh...
  454.  */
  455.  
  456. static void falcon_get_lock( void )
  457.  
  458. {
  459.     unsigned long    oldflags;
  460.     
  461.     if (IS_A_TT()) return;
  462.  
  463.     save_flags(oldflags);
  464.     cli();
  465.     
  466.     while( falcon_got_lock && stdma_others_waiting() )
  467.         sleep_on( &falcon_fairness_wait );
  468.  
  469.     if (!falcon_got_lock) {
  470.         if (!falcon_trying_lock) {
  471.             falcon_trying_lock = 1;
  472.             stdma_lock( scsi_falcon_intr, 0 );
  473.             falcon_got_lock = 1;
  474.             falcon_trying_lock = 0;
  475.             wake_up( &falcon_try_wait );
  476.         }
  477.         else {
  478.             sleep_on( &falcon_try_wait );
  479.         }
  480.     }    
  481.  
  482.     restore_flags(oldflags);
  483. }
  484.  
  485.  
  486. /* This is the wrapper function for NCR5380_queue_command(). It just
  487.  * trys to get the lock on the ST-DMA (see above) and then calls the
  488.  * original function.
  489.  */
  490.  
  491. int atari_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *))
  492.  
  493. {
  494.     falcon_get_lock();
  495.     return( NCR5380_queue_command( cmd, done ) );
  496. }
  497.  
  498.  
  499.                    
  500. int atari_scsi_detect (int hostno)
  501.  
  502. {    static int called = 0;
  503.     struct Scsi_Host *instance;
  504.  
  505.     if (boot_info.machtype != MACH_ATARI || called)
  506.         return( 0 );
  507.     
  508.     atari_scsi_reg_read  = IS_A_TT() ? atari_scsi_tt_reg_read :
  509.                                        atari_scsi_falcon_reg_read;
  510.     atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write :
  511.                                        atari_scsi_falcon_reg_write;
  512.  
  513.     instance = scsi_register (hostno, sizeof (struct NCR5380_hostdata));
  514.     atari_scsi_host = instance;
  515.  
  516.     NCR5380_init (instance);
  517.     instance->irq = 0;    /* not needed, but tested in NCR5380.c */
  518.  
  519.     if (IS_A_TT()) {
  520.         
  521.         add_isr( IRQ_TT_MFP_SCSI, scsi_tt_intr, 0, NULL);
  522.         tt_mfp.active_edge |= 0x80;        /* SCSI int on L->H */
  523.         tt_mfp.int_en_a |= 0x80;        /* enabled */
  524.         tt_mfp.int_mk_a |= 0x80;        /* not masked */
  525. #ifdef REAL_DMA
  526.         /* On the TT, we got a second interrupt for DMA ready and DMA buserror.
  527.          * Since on DMA ready we get a "normal" interrupt, too, the service
  528.          * routine for the second int just checks for buserrs.
  529.          */
  530.         add_isr( IRQ_TT_MFP_SCSIDMA, scsi_dma_buserr, 0, NULL);
  531.         tt_mfp.active_edge &= ~0x20;    /* DMA int on H->L */
  532.         tt_mfp.int_en_b |= 0x80;        /* enabled */
  533.         tt_mfp.int_mk_b |= 0x80;        /* not masked */
  534.  
  535.         tt_scsi_dma.dma_ctrl = 0;
  536.         atari_dma_residual = 0;
  537. #endif /* REAL_DMA */
  538.  
  539.     }
  540.     else { /* ! IS_A_TT */
  541.         
  542.         /* Nothing to do for the interrupt: the ST-DMA is initialized
  543.          * already by atari_init_INTS()
  544.          */
  545.  
  546. #ifdef REAL_DMA
  547.         atari_dma_residual = 0;
  548.         atari_dma_active = 0;
  549. #endif
  550.  
  551.         /* Falcon's ST-DMA can work only in lower 16 MB, so
  552.          * unchecked_isa_dma has to be set. But... the high level
  553.          * codes allocates lots (!) of memory for buffers if this is
  554.          * done. So the values for sg_tablesize and cmd_per_lun get
  555.          * lowered a bit (you can leave this out if you have 16MB of
  556.          * ST-Ram).
  557.          */
  558.         atari_scsi_host->unchecked_isa_dma =
  559.         atari_scsi_host->hostt->unchecked_isa_dma = 1;
  560. #if I_HAVE_OVERRUNS == 3
  561.         atari_scsi_host->sg_tablesize =
  562.         atari_scsi_host->hostt->sg_tablesize = SG_NONE;
  563. #else
  564.         atari_scsi_host->sg_tablesize =
  565.         atari_scsi_host->hostt->sg_tablesize = 8;
  566. #endif
  567.         atari_scsi_host->hostt->cmd_per_lun = 8;
  568.     }
  569.     
  570.     printk( "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCATTERGATHER=%d",
  571.             instance->host_no, instance->hostt->can_queue,
  572.             instance->hostt->cmd_per_lun,
  573.             instance->hostt->sg_tablesize );
  574.     NCR5380_print_options (instance);
  575.     printk ("\n");
  576.  
  577.     called = 1;
  578.  
  579.     return( 1 );
  580. }
  581.  
  582. int atari_scsi_reset( Scsi_Cmnd *cmd )
  583.  
  584. {    int        rv;
  585.     
  586.     /* For doing the reset, SCSI interrupts must be disabled first,
  587.      * since the 5380 raises its IRQ line while _RST is active and we
  588.      * can't disable interrupts completely, since we need the timer.
  589.      */
  590.     
  591.     if (IS_A_TT())
  592.         tt_mfp.int_en_a &= ~0x80;
  593.     else
  594.         mfp.int_en_b &= ~0x80;
  595.     
  596.     rv = NCR5380_reset( cmd );
  597.  
  598.     /* Re-enable ints and abort a maybe active DMA transfer */
  599.     if (IS_A_TT()) {
  600. #ifdef REAL_DMA
  601.         tt_scsi_dma.dma_ctrl = 0;
  602. #endif /* REAL_DMA */
  603.         tt_mfp.int_en_a |= 0x80;
  604.     }
  605.     else {
  606. #ifdef REAL_DMA
  607.         st_dma.dma_mode_status = 0x90;
  608.         atari_dma_active = 0;
  609. #endif /* REAL_DMA */
  610.         mfp.int_en_b |= 0x80;
  611.     }
  612.  
  613.     return( rv );
  614. }
  615.  
  616.     
  617. const char * atari_scsi_info( void )
  618.  
  619. {    /* atari_scsi_detect() is verbose enough... */
  620.     static const char string[] = "";
  621.     return string;
  622. }
  623.  
  624.  
  625. #if defined(REAL_DMA) || defined(REAL_DMA_POLL) || defined(PSEUDO_DMA)
  626.  
  627. unsigned long atari_scsi_dma_setup( struct Scsi_Host *instance, void *data,
  628.                                     unsigned long count, int dir )
  629. {
  630.     unsigned long addr = VTOP( data ),
  631.                   cando = atari_dma_xfer_len( count );
  632.  
  633. #if (NDEBUG & NDEBUG_DMA)
  634.     printk ("scsi%d: setting up dma, data = %p, phys = %lx, count = %ld, cando = %ld, dir = %d\n",
  635.             instance->host_no, data, addr, count, cando, dir);
  636. #endif
  637.  
  638.     atari_dma_startaddr = addr;    /* Needed for calculating residual later. */
  639.   
  640.     if (dir)
  641.         /* write: push any dirty cache out before sending it to the
  642.          * peripheral. (Must be done before DMA setup, since at least the
  643.          * ST-DMA begins to fill internal buffers right after setup.
  644.          */
  645.         cache_push( addr, cando );
  646.     else
  647.         /* read: invalidate any cache, may be altered after DMA without CPU
  648.          * knowledge
  649.          */
  650.         cache_clear( addr, cando );
  651.  
  652.     if (cando == 0)
  653.         printk( "SCSI warning: DMA programed for 0 bytes !\n" );
  654.  
  655.     if (IS_A_TT()) {
  656.     
  657.         tt_scsi_dma.dma_ctrl = dir;
  658.         SCSI_DMA_WRITE_P( dma_addr_hi, addr );
  659.         SCSI_DMA_WRITE_P( dma_cnt_hi, cando );
  660.         tt_scsi_dma.dma_ctrl = dir | 2;
  661.     }
  662.     else { /* ! IS_A_TT */
  663.   
  664.         /* set address */
  665.         SCSI_DMA_SETADR( addr );
  666.  
  667.         /* toggle direction bit to clear FIFO and set DMA direction */
  668.         dir <<= 8;
  669.         st_dma.dma_mode_status = 0x90 | dir;
  670.         st_dma.dma_mode_status = 0x90 | (dir ^ 0x100);
  671.         st_dma.dma_mode_status = 0x90 | dir;
  672.         st_dma.fdc_acces_seccount = cando >> 9;
  673.  
  674.         st_dma.dma_mode_status = 0x10 | dir;
  675.         /* need not restore value of dir, only boolean value is tested */
  676.         atari_dma_active = 1;
  677.     }
  678.     
  679.     return( cando );
  680. }
  681.  
  682.  
  683. static long atari_scsi_dma_residual( struct Scsi_Host *instance )
  684.  
  685. {
  686.     return( atari_dma_residual );
  687. }
  688.  
  689. /* This function calculates the number of bytes that can be transferred
  690.  * via DMA. On the TT, this is arbitrary, but on the Falcon we have to use
  691.  * the ST-DMA chip. There are only multiples of 512 bytes possible and
  692.  * max. 256*512 bytes :-( This means also, that defining READ_OVERRUNS is
  693.  * not possible, since that would require to program the DMA for n*512 - 2
  694.  * bytes.
  695.  */
  696.  
  697. static unsigned long atari_dma_xfer_len( unsigned long wanted_len )
  698.  
  699. {
  700.     unsigned long    possible_len;
  701.  
  702.     if (IS_A_TT())
  703.         /* TT SCSI DMA can transfer arbitrary #bytes */
  704.         return( wanted_len );
  705.     
  706.     /* ST DMA chip is stupid -- only multiples of 512 bytes! (and max.
  707.      * 255*512 bytes, but this should be enough)
  708.      */
  709.     possible_len =wanted_len & ~0x1ff;
  710.     if (possible_len > 255*512)
  711.         possible_len = 255*512;
  712.  
  713. #if (NDEBUG & NDEBUG_DMA)
  714.     if (possible_len != wanted_len)
  715.         printk( "Sorry, must cut DMA transfer size to %ld bytes instead of %ld\n",
  716.                 possible_len, wanted_len );
  717. #endif
  718.  
  719.     return( possible_len );
  720. }
  721.  
  722.  
  723. #endif    /* REAL_DMA || REAL_DMA_POLL || PSEUDO_DMA */
  724.  
  725.  
  726. /* NCR5380 register access functions
  727.  *
  728.  * There are seperate functions for TT and Falcon, because the access
  729.  * methods are quite different. The calling macros NCR5380_read and
  730.  * NCR5380_write call these functions via function pointers.
  731.  */
  732.  
  733. static unsigned char atari_scsi_tt_reg_read( unsigned char reg )
  734.  
  735. {
  736.     return( tt_scsi_regp[reg * 2] );
  737. }
  738.  
  739. static void atari_scsi_tt_reg_write( unsigned char reg, unsigned char value )
  740.  
  741. {
  742.     tt_scsi_regp[reg * 2] = value;
  743. }
  744.  
  745. static unsigned char atari_scsi_falcon_reg_read( unsigned char reg )
  746.  
  747. {
  748.     dma_wd.dma_mode_status= (u_short)(0x88 + reg);
  749.     return( (u_char)dma_wd.fdc_acces_seccount );
  750. }
  751.  
  752. static void atari_scsi_falcon_reg_write( unsigned char reg, unsigned char value )
  753.  
  754. {
  755.     dma_wd.dma_mode_status = (u_short)(0x88 + reg);
  756.     dma_wd.fdc_acces_seccount = (u_short)value;
  757. }
  758.  
  759.  
  760. #include "atari_NCR5380.c"
  761.  
  762. #endif /* CONFIG_ATARI_*_SCSI */
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.