Merge tag 'armsoc-arm64' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[cascardo/linux.git] / drivers / scsi / g_NCR5380.c
index 90091e6..516bd6c 100644 (file)
  *
  * Added ISAPNP support for DTC436 adapters,
  * Thomas Sailer, sailer@ife.ee.ethz.ch
- */
-
-/* 
- * TODO : flesh out DMA support, find some one actually using this (I have
- *     a memory mapped Trantor board that works fine)
- */
-
-/*
- * The card is detected and initialized in one of several ways : 
- * 1.  With command line overrides - NCR5380=port,irq may be 
- *     used on the LILO command line to override the defaults.
- *
- * 2.  With the GENERIC_NCR5380_OVERRIDE compile time define.  This is 
- *     specified as an array of address, irq, dma, board tuples.  Ie, for
- *     one board at 0x350, IRQ5, no dma, I could say  
- *     -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
- * 
- * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an 
- *     IRQ line if overridden on the command line.
  *
- * 3.  When included as a module, with arguments passed on the command line:
- *         ncr_irq=xx  the interrupt
- *         ncr_addr=xx  the port or base address (for port or memory
- *                     mapped, resp.)
- *         ncr_dma=xx  the DMA
- *         ncr_5380=1  to set up for a NCR5380 board
- *         ncr_53c400=1        to set up for a NCR53C400 board
- *     e.g.
- *     modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
- *       for a port mapped NCR5380 board or
- *     modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
- *       for a memory mapped NCR53C400 board with interrupts disabled.
- * 
- * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an 
- *     IRQ line if overridden on the command line.
- *     
+ * See Documentation/scsi/g_NCR5380.txt for more info.
  */
 
-#define AUTOPROBE_IRQ
-
-#ifdef CONFIG_SCSI_GENERIC_NCR53C400
-#define PSEUDO_DMA
-#endif
-
 #include <asm/io.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
@@ -270,7 +230,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #ifndef SCSI_G_NCR5380_MEM
        int i;
        int port_idx = -1;
-       unsigned long region_size = 16;
+       unsigned long region_size;
 #endif
        static unsigned int __initdata ncr_53c400a_ports[] = {
                0x280, 0x290, 0x300, 0x310, 0x330, 0x340, 0x348, 0x350, 0
@@ -290,6 +250,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #ifdef SCSI_G_NCR5380_MEM
        unsigned long base;
        void __iomem *iomem;
+       resource_size_t iomem_size;
 #endif
 
        if (ncr_irq)
@@ -350,25 +311,17 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                flags = 0;
                switch (overrides[current_override].board) {
                case BOARD_NCR5380:
-                       flags = FLAG_NO_PSEUDO_DMA;
-                       break;
-               case BOARD_NCR53C400:
-#ifdef PSEUDO_DMA
-                       flags = FLAG_NO_DMA_FIXUP;
-#endif
+                       flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP;
                        break;
                case BOARD_NCR53C400A:
-                       flags = FLAG_NO_DMA_FIXUP;
                        ports = ncr_53c400a_ports;
                        magic = ncr_53c400a_magic;
                        break;
                case BOARD_HP_C2502:
-                       flags = FLAG_NO_DMA_FIXUP;
                        ports = ncr_53c400a_ports;
                        magic = hp_c2502_magic;
                        break;
                case BOARD_DTC3181E:
-                       flags = FLAG_NO_DMA_FIXUP;
                        ports = dtc_3181e_ports;
                        magic = ncr_53c400a_magic;
                        break;
@@ -381,20 +334,22 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                        /* Disable the adapter and look for a free io port */
                        magic_configure(-1, 0, magic);
 
+                       region_size = 16;
+
                        if (overrides[current_override].NCR5380_map_name != PORT_AUTO)
                                for (i = 0; ports[i]; i++) {
-                                       if (!request_region(ports[i],  16, "ncr53c80"))
+                                       if (!request_region(ports[i], region_size, "ncr53c80"))
                                                continue;
                                        if (overrides[current_override].NCR5380_map_name == ports[i])
                                                break;
-                                       release_region(ports[i], 16);
+                                       release_region(ports[i], region_size);
                        } else
                                for (i = 0; ports[i]; i++) {
-                                       if (!request_region(ports[i],  16, "ncr53c80"))
+                                       if (!request_region(ports[i], region_size, "ncr53c80"))
                                                continue;
                                        if (inb(ports[i]) == 0xff)
                                                break;
-                                       release_region(ports[i], 16);
+                                       release_region(ports[i], region_size);
                                }
                        if (ports[i]) {
                                /* At this point we have our region reserved */
@@ -410,17 +365,19 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                else
                {
                        /* Not a 53C400A style setup - just grab */
-                       if(!(request_region(overrides[current_override].NCR5380_map_name, NCR5380_region_size, "ncr5380")))
+                       region_size = 8;
+                       if (!request_region(overrides[current_override].NCR5380_map_name,
+                                           region_size, "ncr5380"))
                                continue;
-                       region_size = NCR5380_region_size;
                }
 #else
                base = overrides[current_override].NCR5380_map_name;
-               if (!request_mem_region(base, NCR5380_region_size, "ncr5380"))
+               iomem_size = NCR53C400_region_size;
+               if (!request_mem_region(base, iomem_size, "ncr5380"))
                        continue;
-               iomem = ioremap(base, NCR5380_region_size);
+               iomem = ioremap(base, iomem_size);
                if (!iomem) {
-                       release_mem_region(base, NCR5380_region_size);
+                       release_mem_region(base, iomem_size);
                        continue;
                }
 #endif
@@ -458,6 +415,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #else
                instance->base = overrides[current_override].NCR5380_map_name;
                hostdata->iomem = iomem;
+               hostdata->iomem_size = iomem_size;
                switch (overrides[current_override].board) {
                case BOARD_NCR53C400:
                        hostdata->c400_ctl_status = 0x100;
@@ -472,7 +430,7 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                }
 #endif
 
-               if (NCR5380_init(instance, flags))
+               if (NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP))
                        goto out_unregister;
 
                switch (overrides[current_override].board) {
@@ -524,7 +482,7 @@ out_release:
        release_region(overrides[current_override].NCR5380_map_name, region_size);
 #else
        iounmap(iomem);
-       release_mem_region(base, NCR5380_region_size);
+       release_mem_region(base, iomem_size);
 #endif
        return count;
 }
@@ -546,45 +504,18 @@ static int generic_NCR5380_release_resources(struct Scsi_Host *instance)
 #ifndef SCSI_G_NCR5380_MEM
        release_region(instance->io_port, instance->n_io_port);
 #else
-       iounmap(((struct NCR5380_hostdata *)instance->hostdata)->iomem);
-       release_mem_region(instance->base, NCR5380_region_size);
-#endif
-       return 0;
-}
-
-#ifdef BIOSPARAM
-/**
- *     generic_NCR5380_biosparam
- *     @disk: disk to compute geometry for
- *     @dev: device identifier for this disk
- *     @ip: sizes to fill in
- *
- *     Generates a BIOS / DOS compatible H-C-S mapping for the specified 
- *     device / size.
- * 
- *     XXX Most SCSI boards use this mapping, I could be incorrect.  Someone
- *     using hard disks on a trantor should verify that this mapping
- *     corresponds to that used by the BIOS / ASPI driver by running the linux
- *     fdisk program and matching the H_C_S coordinates to what DOS uses.
- *
- *     Locks: none
- */
+       {
+               struct NCR5380_hostdata *hostdata = shost_priv(instance);
 
-static int
-generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
-                         sector_t capacity, int *ip)
-{
-       ip[0] = 64;
-       ip[1] = 32;
-       ip[2] = capacity >> 11;
+               iounmap(hostdata->iomem);
+               release_mem_region(instance->base, hostdata->iomem_size);
+       }
+#endif
        return 0;
 }
-#endif
-
-#ifdef PSEUDO_DMA
 
 /**
- *     NCR5380_pread           -       pseudo DMA read
+ *     generic_NCR5380_pread - pseudo DMA read
  *     @instance: adapter to read from
  *     @dst: buffer to read into
  *     @len: buffer length
@@ -593,7 +524,8 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev,
  *     controller
  */
  
-static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
+static inline int generic_NCR5380_pread(struct Scsi_Host *instance,
+                                        unsigned char *dst, int len)
 {
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int blocks = len / 128;
@@ -661,7 +593,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
 }
 
 /**
- *     NCR5380_write           -       pseudo DMA write
+ *     generic_NCR5380_pwrite - pseudo DMA write
  *     @instance: adapter to read from
  *     @dst: buffer to read into
  *     @len: buffer length
@@ -670,7 +602,8 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
  *     controller
  */
 
-static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
+static inline int generic_NCR5380_pwrite(struct Scsi_Host *instance,
+                                         unsigned char *src, int len)
 {
        struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int blocks = len / 128;
@@ -738,10 +671,15 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
        return 0;
 }
 
-static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
+static int generic_NCR5380_dma_xfer_len(struct Scsi_Host *instance,
+                                        struct scsi_cmnd *cmd)
 {
+       struct NCR5380_hostdata *hostdata = shost_priv(instance);
        int transfersize = cmd->transfersize;
 
+       if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
+               return 0;
+
        /* Limit transfers to 32K, for xx400 & xx406
         * pseudoDMA that transfers in 128 bytes blocks.
         */
@@ -756,8 +694,6 @@ static int generic_NCR5380_dma_xfer_len(struct scsi_cmnd *cmd)
        return transfersize;
 }
 
-#endif /* PSEUDO_DMA */
-
 /*
  *     Include the NCR5380 core code that we build our driver around   
  */
@@ -773,7 +709,6 @@ static struct scsi_host_template driver_template = {
        .queuecommand           = generic_NCR5380_queue_command,
        .eh_abort_handler       = generic_NCR5380_abort,
        .eh_bus_reset_handler   = generic_NCR5380_bus_reset,
-       .bios_param             = NCR5380_BIOSPARAM,
        .can_queue              = 16,
        .this_id                = 7,
        .sg_tablesize           = SG_ALL,