Merge tag 'pinctrl-v3.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
[cascardo/linux.git] / drivers / scsi / atari_scsi.c
index b522134..d1c37a3 100644 (file)
 /**************************************************************************/
 
 
-
 #include <linux/module.h>
-
-#define AUTOSENSE
-/* For the Atari version, use only polled IO or REAL_DMA */
-#define        REAL_DMA
-/* Support tagged queuing? (on devices that are able to... :-) */
-#define        SUPPORT_TAGS
-#define        MAX_TAGS 32
-
 #include <linux/types.h>
-#include <linux/stddef.h>
-#include <linux/ctype.h>
 #include <linux/delay.h>
-#include <linux/mm.h>
 #include <linux/blkdev.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/nvram.h>
 #include <linux/bitops.h>
 #include <linux/wait.h>
+#include <linux/platform_device.h>
 
 #include <asm/setup.h>
 #include <asm/atarihw.h>
 #include <asm/atariints.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/traps.h>
-
-#include "scsi.h"
-#include <scsi/scsi_host.h>
-#include "atari_scsi.h"
-#include "NCR5380.h"
 #include <asm/atari_stdma.h>
 #include <asm/atari_stram.h>
 #include <asm/io.h>
 
-#include <linux/stat.h>
+#include <scsi/scsi_host.h>
+
+/* Definitions for the core NCR5380 driver. */
+
+#define REAL_DMA
+#define SUPPORT_TAGS
+#define MAX_TAGS                        32
+#define DMA_MIN_SIZE                    32
+
+#define NCR5380_implementation_fields   /* none */
+
+#define NCR5380_read(reg)               atari_scsi_reg_read(reg)
+#define NCR5380_write(reg, value)       atari_scsi_reg_write(reg, value)
+
+#define NCR5380_queue_command           atari_scsi_queue_command
+#define NCR5380_abort                   atari_scsi_abort
+#define NCR5380_show_info               atari_scsi_show_info
+#define NCR5380_info                    atari_scsi_info
+
+#define NCR5380_dma_read_setup(instance, data, count) \
+        atari_scsi_dma_setup(instance, data, count, 0)
+#define NCR5380_dma_write_setup(instance, data, count) \
+        atari_scsi_dma_setup(instance, data, count, 1)
+#define NCR5380_dma_residual(instance) \
+        atari_scsi_dma_residual(instance)
+#define NCR5380_dma_xfer_len(instance, cmd, phase) \
+        atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
+
+#define NCR5380_acquire_dma_irq(instance)      falcon_get_lock(instance)
+#define NCR5380_release_dma_irq(instance)      falcon_release_lock()
+
+#include "NCR5380.h"
+
 
 #define        IS_A_TT()       ATARIHW_PRESENT(TT_SCSI)
 
@@ -149,23 +161,6 @@ static inline unsigned long SCSI_DMA_GETADR(void)
        return adr;
 }
 
-static inline void ENABLE_IRQ(void)
-{
-       if (IS_A_TT())
-               atari_enable_irq(IRQ_TT_MFP_SCSI);
-       else
-               atari_enable_irq(IRQ_MFP_FSCSI);
-}
-
-static inline void DISABLE_IRQ(void)
-{
-       if (IS_A_TT())
-               atari_disable_irq(IRQ_TT_MFP_SCSI);
-       else
-               atari_disable_irq(IRQ_MFP_FSCSI);
-}
-
-
 #define HOSTDATA_DMALEN                (((struct NCR5380_hostdata *) \
                                (atari_scsi_host->hostdata))->dma_len)
 
@@ -178,30 +173,9 @@ static inline void DISABLE_IRQ(void)
 #define        AFTER_RESET_DELAY       (5*HZ/2)
 #endif
 
-/***************************** Prototypes *****************************/
-
 #ifdef REAL_DMA
-static int scsi_dma_is_ignored_buserr(unsigned char dma_stat);
 static void atari_scsi_fetch_restbytes(void);
-static long atari_scsi_dma_residual(struct Scsi_Host *instance);
-static int falcon_classify_cmd(Scsi_Cmnd *cmd);
-static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
-                                       Scsi_Cmnd *cmd, int write_flag);
-#endif
-static irqreturn_t scsi_tt_intr(int irq, void *dummy);
-static irqreturn_t scsi_falcon_intr(int irq, void *dummy);
-static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata);
-static void falcon_get_lock(void);
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-static void atari_scsi_reset_boot(void);
 #endif
-static unsigned char atari_scsi_tt_reg_read(unsigned char reg);
-static void atari_scsi_tt_reg_write(unsigned char reg, unsigned char value);
-static unsigned char atari_scsi_falcon_reg_read(unsigned char reg);
-static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value);
-
-/************************* End of Prototypes **************************/
-
 
 static struct Scsi_Host *atari_scsi_host;
 static unsigned char (*atari_scsi_reg_read)(unsigned char reg);
@@ -226,8 +200,6 @@ static char         *atari_dma_orig_addr;
 /* mask for address bits that can't be used with the ST-DMA */
 static unsigned long   atari_dma_stram_mask;
 #define STRAM_ADDR(a)  (((a) & atari_dma_stram_mask) == 0)
-/* number of bytes to cut from a transfer to handle NCR overruns */
-static int atari_read_overruns;
 #endif
 
 static int setup_can_queue = -1;
@@ -386,10 +358,6 @@ static irqreturn_t scsi_tt_intr(int irq, void *dummy)
 
        NCR5380_intr(irq, dummy);
 
-#if 0
-       /* To be sure the int is not masked */
-       atari_enable_irq(IRQ_TT_MFP_SCSI);
-#endif
        return IRQ_HANDLED;
 }
 
@@ -480,257 +448,35 @@ static void atari_scsi_fetch_restbytes(void)
 #endif /* REAL_DMA */
 
 
-static int falcon_got_lock = 0;
-static DECLARE_WAIT_QUEUE_HEAD(falcon_fairness_wait);
-static int falcon_trying_lock = 0;
-static DECLARE_WAIT_QUEUE_HEAD(falcon_try_wait);
-static int falcon_dont_release = 0;
-
 /* This function releases the lock on the DMA chip if there is no
- * connected command and the disconnected queue is empty. On
- * releasing, instances of falcon_get_lock are awoken, that put
- * themselves to sleep for fairness. They can now try to get the lock
- * again (but others waiting longer more probably will win).
+ * connected command and the disconnected queue is empty.
  */
 
-static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata)
+static void falcon_release_lock(void)
 {
-       unsigned long flags;
-
        if (IS_A_TT())
                return;
 
-       local_irq_save(flags);
-
-       if (falcon_got_lock && !hostdata->disconnected_queue &&
-           !hostdata->issue_queue && !hostdata->connected) {
-
-               if (falcon_dont_release) {
-#if 0
-                       printk("WARNING: Lock release not allowed. Ignored\n");
-#endif
-                       local_irq_restore(flags);
-                       return;
-               }
-               falcon_got_lock = 0;
+       if (stdma_is_locked_by(scsi_falcon_intr))
                stdma_release();
-               wake_up(&falcon_fairness_wait);
-       }
-
-       local_irq_restore(flags);
 }
 
 /* This function manages the locking of the ST-DMA.
  * If the DMA isn't locked already for SCSI, it tries to lock it by
  * calling stdma_lock(). But if the DMA is locked by the SCSI code and
  * there are other drivers waiting for the chip, we do not issue the
- * command immediately but wait on 'falcon_fairness_queue'. We will be
- * waked up when the DMA is unlocked by some SCSI interrupt. After that
- * we try to get the lock again.
- * But we must be prepared that more than one instance of
- * falcon_get_lock() is waiting on the fairness queue. They should not
- * try all at once to call stdma_lock(), one is enough! For that, the
- * first one sets 'falcon_trying_lock', others that see that variable
- * set wait on the queue 'falcon_try_wait'.
- * Complicated, complicated.... Sigh...
+ * command immediately but tell the SCSI mid-layer to defer.
  */
 
-static void falcon_get_lock(void)
+static int falcon_get_lock(struct Scsi_Host *instance)
 {
-       unsigned long flags;
-
        if (IS_A_TT())
-               return;
-
-       local_irq_save(flags);
-
-       wait_event_cmd(falcon_fairness_wait,
-               in_interrupt() || !falcon_got_lock || !stdma_others_waiting(),
-               local_irq_restore(flags),
-               local_irq_save(flags));
-
-       while (!falcon_got_lock) {
-               if (in_irq())
-                       panic("Falcon SCSI hasn't ST-DMA lock in interrupt");
-               if (!falcon_trying_lock) {
-                       falcon_trying_lock = 1;
-                       stdma_lock(scsi_falcon_intr, NULL);
-                       falcon_got_lock = 1;
-                       falcon_trying_lock = 0;
-                       wake_up(&falcon_try_wait);
-               } else {
-                       wait_event_cmd(falcon_try_wait,
-                               falcon_got_lock && !falcon_trying_lock,
-                               local_irq_restore(flags),
-                               local_irq_save(flags));
-               }
-       }
-
-       local_irq_restore(flags);
-       if (!falcon_got_lock)
-               panic("Falcon SCSI: someone stole the lock :-(\n");
-}
-
-
-static int __init atari_scsi_detect(struct scsi_host_template *host)
-{
-       static int called = 0;
-       struct Scsi_Host *instance;
-
-       if (!MACH_IS_ATARI ||
-           (!ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(TT_SCSI)) ||
-           called)
-               return 0;
-
-       host->proc_name = "Atari";
-
-       atari_scsi_reg_read  = IS_A_TT() ? atari_scsi_tt_reg_read :
-                                          atari_scsi_falcon_reg_read;
-       atari_scsi_reg_write = IS_A_TT() ? atari_scsi_tt_reg_write :
-                                          atari_scsi_falcon_reg_write;
-
-       /* setup variables */
-       host->can_queue =
-               (setup_can_queue > 0) ? setup_can_queue :
-               IS_A_TT() ? ATARI_TT_CAN_QUEUE : ATARI_FALCON_CAN_QUEUE;
-       host->cmd_per_lun =
-               (setup_cmd_per_lun > 0) ? setup_cmd_per_lun :
-               IS_A_TT() ? ATARI_TT_CMD_PER_LUN : ATARI_FALCON_CMD_PER_LUN;
-       /* Force sg_tablesize to 0 on a Falcon! */
-       host->sg_tablesize =
-               !IS_A_TT() ? ATARI_FALCON_SG_TABLESIZE :
-               (setup_sg_tablesize >= 0) ? setup_sg_tablesize : ATARI_TT_SG_TABLESIZE;
-
-       if (setup_hostid >= 0)
-               host->this_id = setup_hostid;
-       else {
-               /* use 7 as default */
-               host->this_id = 7;
-               /* Test if a host id is set in the NVRam */
-               if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
-                       unsigned char b = nvram_read_byte( 14 );
-                       /* Arbitration enabled? (for TOS) If yes, use configured host ID */
-                       if (b & 0x80)
-                               host->this_id = b & 7;
-               }
-       }
+               return 1;
 
-#ifdef SUPPORT_TAGS
-       if (setup_use_tagged_queuing < 0)
-               setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;
-#endif
-#ifdef REAL_DMA
-       /* If running on a Falcon and if there's TT-Ram (i.e., more than one
-        * memory block, since there's always ST-Ram in a Falcon), then allocate a
-        * STRAM_BUFFER_SIZE byte dribble buffer for transfers from/to alternative
-        * Ram.
-        */
-       if (MACH_IS_ATARI && ATARIHW_PRESENT(ST_SCSI) &&
-           !ATARIHW_PRESENT(EXTD_DMA) && m68k_num_memory > 1) {
-               atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI");
-               if (!atari_dma_buffer) {
-                       printk(KERN_ERR "atari_scsi_detect: can't allocate ST-RAM "
-                                       "double buffer\n");
-                       return 0;
-               }
-               atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
-               atari_dma_orig_addr = 0;
-       }
-#endif
-       instance = scsi_register(host, sizeof(struct NCR5380_hostdata));
-       if (instance == NULL) {
-               atari_stram_free(atari_dma_buffer);
-               atari_dma_buffer = 0;
-               return 0;
-       }
-       atari_scsi_host = instance;
-       /*
-        * Set irq to 0, to avoid that the mid-level code disables our interrupt
-        * during queue_command calls. This is completely unnecessary, and even
-        * worse causes bad problems on the Falcon, where the int is shared with
-        * IDE and floppy!
-        */
-       instance->irq = 0;
-
-#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
-       atari_scsi_reset_boot();
-#endif
-       NCR5380_init(instance, 0);
-
-       if (IS_A_TT()) {
-
-               /* This int is actually "pseudo-slow", i.e. it acts like a slow
-                * interrupt after having cleared the pending flag for the DMA
-                * interrupt. */
-               if (request_irq(IRQ_TT_MFP_SCSI, scsi_tt_intr, IRQ_TYPE_SLOW,
-                                "SCSI NCR5380", instance)) {
-                       printk(KERN_ERR "atari_scsi_detect: cannot allocate irq %d, aborting",IRQ_TT_MFP_SCSI);
-                       scsi_unregister(atari_scsi_host);
-                       atari_stram_free(atari_dma_buffer);
-                       atari_dma_buffer = 0;
-                       return 0;
-               }
-               tt_mfp.active_edge |= 0x80;             /* SCSI int on L->H */
-#ifdef REAL_DMA
-               tt_scsi_dma.dma_ctrl = 0;
-               atari_dma_residual = 0;
-
-               if (MACH_IS_MEDUSA) {
-                       /* While the read overruns (described by Drew Eckhardt in
-                        * NCR5380.c) never happened on TTs, they do in fact on the Medusa
-                        * (This was the cause why SCSI didn't work right for so long
-                        * there.) Since handling the overruns slows down a bit, I turned
-                        * the #ifdef's into a runtime condition.
-                        *
-                        * In principle it should be sufficient to do max. 1 byte with
-                        * PIO, but there is another problem on the Medusa with the DMA
-                        * rest data register. So 'atari_read_overruns' is currently set
-                        * to 4 to avoid having transfers that aren't a multiple of 4. If
-                        * the rest data bug is fixed, this can be lowered to 1.
-                        */
-                       atari_read_overruns = 4;
-               }
-#endif /*REAL_DMA*/
-       } else { /* ! IS_A_TT */
-
-               /* Nothing to do for the interrupt: the ST-DMA is initialized
-                * already by atari_init_INTS()
-                */
-
-#ifdef REAL_DMA
-               atari_dma_residual = 0;
-               atari_dma_active = 0;
-               atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
-                                       : 0xff000000);
-#endif
-       }
+       if (in_interrupt())
+               return stdma_try_lock(scsi_falcon_intr, instance);
 
-       printk(KERN_INFO "scsi%d: options CAN_QUEUE=%d CMD_PER_LUN=%d SCAT-GAT=%d "
-#ifdef SUPPORT_TAGS
-                       "TAGGED-QUEUING=%s "
-#endif
-                       "HOSTID=%d",
-                       instance->host_no, instance->hostt->can_queue,
-                       instance->hostt->cmd_per_lun,
-                       instance->hostt->sg_tablesize,
-#ifdef SUPPORT_TAGS
-                       setup_use_tagged_queuing ? "yes" : "no",
-#endif
-                       instance->hostt->this_id );
-       NCR5380_print_options(instance);
-       printk("\n");
-
-       called = 1;
-       return 1;
-}
-
-static int atari_scsi_release(struct Scsi_Host *sh)
-{
-       if (IS_A_TT())
-               free_irq(IRQ_TT_MFP_SCSI, sh);
-       if (atari_dma_buffer)
-               atari_stram_free(atari_dma_buffer);
-       NCR5380_exit(sh);
+       stdma_lock(scsi_falcon_intr, instance);
        return 1;
 }
 
@@ -739,7 +485,7 @@ static int __init atari_scsi_setup(char *str)
 {
        /* Format of atascsi parameter is:
         *   atascsi=<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-        * Defaults depend on TT or Falcon, hostid determined at run time.
+        * Defaults depend on TT or Falcon, determined at run time.
         * Negative values mean don't change.
         */
        int ints[6];
@@ -750,36 +496,17 @@ static int __init atari_scsi_setup(char *str)
                printk("atari_scsi_setup: no arguments!\n");
                return 0;
        }
-
-       if (ints[0] >= 1) {
-               if (ints[1] > 0)
-                       /* no limits on this, just > 0 */
-                       setup_can_queue = ints[1];
-       }
-       if (ints[0] >= 2) {
-               if (ints[2] > 0)
-                       setup_cmd_per_lun = ints[2];
-       }
-       if (ints[0] >= 3) {
-               if (ints[3] >= 0) {
-                       setup_sg_tablesize = ints[3];
-                       /* Must be <= SG_ALL (255) */
-                       if (setup_sg_tablesize > SG_ALL)
-                               setup_sg_tablesize = SG_ALL;
-               }
-       }
-       if (ints[0] >= 4) {
-               /* Must be between 0 and 7 */
-               if (ints[4] >= 0 && ints[4] <= 7)
-                       setup_hostid = ints[4];
-               else if (ints[4] > 7)
-                       printk("atari_scsi_setup: invalid host ID %d !\n", ints[4]);
-       }
+       if (ints[0] >= 1)
+               setup_can_queue = ints[1];
+       if (ints[0] >= 2)
+               setup_cmd_per_lun = ints[2];
+       if (ints[0] >= 3)
+               setup_sg_tablesize = ints[3];
+       if (ints[0] >= 4)
+               setup_hostid = ints[4];
 #ifdef SUPPORT_TAGS
-       if (ints[0] >= 5) {
-               if (ints[5] >= 0)
-                       setup_use_tagged_queuing = !!ints[5];
-       }
+       if (ints[0] >= 5)
+               setup_use_tagged_queuing = ints[5];
 #endif
 
        return 1;
@@ -788,45 +515,6 @@ static int __init atari_scsi_setup(char *str)
 __setup("atascsi=", atari_scsi_setup);
 #endif /* !MODULE */
 
-static int atari_scsi_bus_reset(Scsi_Cmnd *cmd)
-{
-       int rv;
-       struct NCR5380_hostdata *hostdata =
-               (struct NCR5380_hostdata *)cmd->device->host->hostdata;
-
-       /* For doing the reset, SCSI interrupts must be disabled first,
-        * since the 5380 raises its IRQ line while _RST is active and we
-        * can't disable interrupts completely, since we need the timer.
-        */
-       /* And abort a maybe active DMA transfer */
-       if (IS_A_TT()) {
-               atari_turnoff_irq(IRQ_TT_MFP_SCSI);
-#ifdef REAL_DMA
-               tt_scsi_dma.dma_ctrl = 0;
-#endif /* REAL_DMA */
-       } else {
-               atari_turnoff_irq(IRQ_MFP_FSCSI);
-#ifdef REAL_DMA
-               st_dma.dma_mode_status = 0x90;
-               atari_dma_active = 0;
-               atari_dma_orig_addr = NULL;
-#endif /* REAL_DMA */
-       }
-
-       rv = NCR5380_bus_reset(cmd);
-
-       /* Re-enable ints */
-       if (IS_A_TT()) {
-               atari_turnon_irq(IRQ_TT_MFP_SCSI);
-       } else {
-               atari_turnon_irq(IRQ_MFP_FSCSI);
-       }
-       if (rv == SUCCESS)
-               falcon_release_lock_if_possible(hostdata);
-
-       return rv;
-}
-
 
 #ifdef CONFIG_ATARI_SCSI_RESET_BOOT
 static void __init atari_scsi_reset_boot(void)
@@ -860,15 +548,6 @@ static void __init atari_scsi_reset_boot(void)
 }
 #endif
 
-
-static const char *atari_scsi_info(struct Scsi_Host *host)
-{
-       /* atari_scsi_detect() is verbose enough... */
-       static const char string[] = "Atari native SCSI";
-       return string;
-}
-
-
 #if defined(REAL_DMA)
 
 static unsigned long atari_scsi_dma_setup(struct Scsi_Host *instance,
@@ -949,7 +628,7 @@ static long atari_scsi_dma_residual(struct Scsi_Host *instance)
 #define        CMD_SURELY_BYTE_MODE    1
 #define        CMD_MODE_UNKNOWN                2
 
-static int falcon_classify_cmd(Scsi_Cmnd *cmd)
+static int falcon_classify_cmd(struct scsi_cmnd *cmd)
 {
        unsigned char opcode = cmd->cmnd[0];
 
@@ -981,7 +660,7 @@ static int falcon_classify_cmd(Scsi_Cmnd *cmd)
  */
 
 static unsigned long atari_dma_xfer_len(unsigned long wanted_len,
-                                       Scsi_Cmnd *cmd, int write_flag)
+                                       struct scsi_cmnd *cmd, int write_flag)
 {
        unsigned long   possible_len, limit;
 
@@ -1099,23 +778,247 @@ static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
 
 #include "atari_NCR5380.c"
 
-static struct scsi_host_template driver_template = {
+static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
+{
+       int rv;
+       unsigned long flags;
+
+       local_irq_save(flags);
+
+#ifdef REAL_DMA
+       /* Abort a maybe active DMA transfer */
+       if (IS_A_TT()) {
+               tt_scsi_dma.dma_ctrl = 0;
+       } else {
+               st_dma.dma_mode_status = 0x90;
+               atari_dma_active = 0;
+               atari_dma_orig_addr = NULL;
+       }
+#endif
+
+       rv = NCR5380_bus_reset(cmd);
+
+       /* The 5380 raises its IRQ line while _RST is active but the ST DMA
+        * "lock" has been released so this interrupt may end up handled by
+        * floppy or IDE driver (if one of them holds the lock). The NCR5380
+        * interrupt flag has been cleared already.
+        */
+
+       local_irq_restore(flags);
+
+       return rv;
+}
+
+#define DRV_MODULE_NAME         "atari_scsi"
+#define PFX                     DRV_MODULE_NAME ": "
+
+static struct scsi_host_template atari_scsi_template = {
+       .module                 = THIS_MODULE,
+       .proc_name              = DRV_MODULE_NAME,
        .show_info              = atari_scsi_show_info,
        .name                   = "Atari native SCSI",
-       .detect                 = atari_scsi_detect,
-       .release                = atari_scsi_release,
        .info                   = atari_scsi_info,
        .queuecommand           = atari_scsi_queue_command,
        .eh_abort_handler       = atari_scsi_abort,
        .eh_bus_reset_handler   = atari_scsi_bus_reset,
-       .can_queue              = 0, /* initialized at run-time */
-       .this_id                = 0, /* initialized at run-time */
-       .sg_tablesize           = 0, /* initialized at run-time */
-       .cmd_per_lun            = 0, /* initialized at run-time */
+       .this_id                = 7,
        .use_clustering         = DISABLE_CLUSTERING
 };
 
+static int __init atari_scsi_probe(struct platform_device *pdev)
+{
+       struct Scsi_Host *instance;
+       int error;
+       struct resource *irq;
+       int host_flags = 0;
+
+       irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!irq)
+               return -ENODEV;
+
+       if (ATARIHW_PRESENT(TT_SCSI)) {
+               atari_scsi_reg_read  = atari_scsi_tt_reg_read;
+               atari_scsi_reg_write = atari_scsi_tt_reg_write;
+       } else {
+               atari_scsi_reg_read  = atari_scsi_falcon_reg_read;
+               atari_scsi_reg_write = atari_scsi_falcon_reg_write;
+       }
+
+       /* 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!)
+        *
+        * But there seems to be a bug somewhere that requires CAN_QUEUE to be
+        * 2*CMD_PER_LUN. At least on a TT, no spurious timeouts seen since
+        * changed CMD_PER_LUN...
+        *
+        * Note: The Falcon currently uses 8/1 setting due to unsolved problems
+        * with cmd_per_lun != 1
+        */
+       if (ATARIHW_PRESENT(TT_SCSI)) {
+               atari_scsi_template.can_queue    = 16;
+               atari_scsi_template.cmd_per_lun  = 8;
+               atari_scsi_template.sg_tablesize = SG_ALL;
+       } else {
+               atari_scsi_template.can_queue    = 8;
+               atari_scsi_template.cmd_per_lun  = 1;
+               atari_scsi_template.sg_tablesize = SG_NONE;
+       }
+
+       if (setup_can_queue > 0)
+               atari_scsi_template.can_queue = setup_can_queue;
+
+       if (setup_cmd_per_lun > 0)
+               atari_scsi_template.cmd_per_lun = setup_cmd_per_lun;
+
+       /* Leave sg_tablesize at 0 on a Falcon! */
+       if (ATARIHW_PRESENT(TT_SCSI) && setup_sg_tablesize >= 0)
+               atari_scsi_template.sg_tablesize = setup_sg_tablesize;
+
+       if (setup_hostid >= 0) {
+               atari_scsi_template.this_id = setup_hostid & 7;
+       } else {
+               /* Test if a host id is set in the NVRam */
+               if (ATARIHW_PRESENT(TT_CLK) && nvram_check_checksum()) {
+                       unsigned char b = nvram_read_byte(14);
+
+                       /* Arbitration enabled? (for TOS)
+                        * If yes, use configured host ID
+                        */
+                       if (b & 0x80)
+                               atari_scsi_template.this_id = b & 7;
+               }
+       }
+
+
+#ifdef REAL_DMA
+       /* If running on a Falcon and if there's TT-Ram (i.e., more than one
+        * memory block, since there's always ST-Ram in a Falcon), then
+        * allocate a STRAM_BUFFER_SIZE byte dribble buffer for transfers
+        * from/to alternative Ram.
+        */
+       if (ATARIHW_PRESENT(ST_SCSI) && !ATARIHW_PRESENT(EXTD_DMA) &&
+           m68k_num_memory > 1) {
+               atari_dma_buffer = atari_stram_alloc(STRAM_BUFFER_SIZE, "SCSI");
+               if (!atari_dma_buffer) {
+                       pr_err(PFX "can't allocate ST-RAM double buffer\n");
+                       return -ENOMEM;
+               }
+               atari_dma_phys_buffer = atari_stram_to_phys(atari_dma_buffer);
+               atari_dma_orig_addr = 0;
+       }
+#endif
+
+       instance = scsi_host_alloc(&atari_scsi_template,
+                                  sizeof(struct NCR5380_hostdata));
+       if (!instance) {
+               error = -ENOMEM;
+               goto fail_alloc;
+       }
+       atari_scsi_host = instance;
+
+#ifdef CONFIG_ATARI_SCSI_RESET_BOOT
+       atari_scsi_reset_boot();
+#endif
+
+       instance->irq = irq->start;
+
+       host_flags |= IS_A_TT() ? 0 : FLAG_LATE_DMA_SETUP;
+
+#ifdef SUPPORT_TAGS
+       host_flags |= setup_use_tagged_queuing > 0 ? FLAG_TAGGED_QUEUING : 0;
+#endif
+
+       NCR5380_init(instance, host_flags);
+
+       if (IS_A_TT()) {
+               error = request_irq(instance->irq, scsi_tt_intr, 0,
+                                   "NCR5380", instance);
+               if (error) {
+                       pr_err(PFX "request irq %d failed, aborting\n",
+                              instance->irq);
+                       goto fail_irq;
+               }
+               tt_mfp.active_edge |= 0x80;     /* SCSI int on L->H */
+#ifdef REAL_DMA
+               tt_scsi_dma.dma_ctrl = 0;
+               atari_dma_residual = 0;
+
+               /* While the read overruns (described by Drew Eckhardt in
+                * NCR5380.c) never happened on TTs, they do in fact on the
+                * Medusa (This was the cause why SCSI didn't work right for
+                * so long there.) Since handling the overruns slows down
+                * a bit, I turned the #ifdef's into a runtime condition.
+                *
+                * In principle it should be sufficient to do max. 1 byte with
+                * PIO, but there is another problem on the Medusa with the DMA
+                * rest data register. So read_overruns is currently set
+                * to 4 to avoid having transfers that aren't a multiple of 4.
+                * If the rest data bug is fixed, this can be lowered to 1.
+                */
+               if (MACH_IS_MEDUSA) {
+                       struct NCR5380_hostdata *hostdata =
+                               shost_priv(instance);
+
+                       hostdata->read_overruns = 4;
+               }
+#endif
+       } else {
+               /* Nothing to do for the interrupt: the ST-DMA is initialized
+                * already.
+                */
+#ifdef REAL_DMA
+               atari_dma_residual = 0;
+               atari_dma_active = 0;
+               atari_dma_stram_mask = (ATARIHW_PRESENT(EXTD_DMA) ? 0x00000000
+                                       : 0xff000000);
+#endif
+       }
+
+       error = scsi_add_host(instance, NULL);
+       if (error)
+               goto fail_host;
+
+       platform_set_drvdata(pdev, instance);
+
+       scsi_scan_host(instance);
+       return 0;
+
+fail_host:
+       if (IS_A_TT())
+               free_irq(instance->irq, instance);
+fail_irq:
+       NCR5380_exit(instance);
+       scsi_host_put(instance);
+fail_alloc:
+       if (atari_dma_buffer)
+               atari_stram_free(atari_dma_buffer);
+       return error;
+}
+
+static int __exit atari_scsi_remove(struct platform_device *pdev)
+{
+       struct Scsi_Host *instance = platform_get_drvdata(pdev);
+
+       scsi_remove_host(instance);
+       if (IS_A_TT())
+               free_irq(instance->irq, instance);
+       NCR5380_exit(instance);
+       scsi_host_put(instance);
+       if (atari_dma_buffer)
+               atari_stram_free(atari_dma_buffer);
+       return 0;
+}
+
+static struct platform_driver atari_scsi_driver = {
+       .remove = __exit_p(atari_scsi_remove),
+       .driver = {
+               .name   = DRV_MODULE_NAME,
+               .owner  = THIS_MODULE,
+       },
+};
 
-#include "scsi_module.c"
+module_platform_driver_probe(atari_scsi_driver, atari_scsi_probe);
 
+MODULE_ALIAS("platform:" DRV_MODULE_NAME);
 MODULE_LICENSE("GPL");