diff mbox

[00/71] More fixes, cleanup and modernization for NCR5380 drivers

Message ID 201511260001.21123.linux@rainbow-software.org (mailing list archive)
State Deferred, archived
Headers show

Commit Message

Ondrej Zary Nov. 25, 2015, 11:01 p.m. UTC
On Wednesday 25 November 2015 10:04:10 Ondrej Zary wrote:
> I think that PDMA should work with 53C400A too but seems that the driver was
> never able to do it.
> 
> Although there is code for port-mapped transfer in NCR5380_pread(),
> NCR53C400_register_offset is defined to 0 in the port-mapped case. The C400_
> register offsets are thus defined with negative offset:
> 
> #define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8
> #define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7
> #define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6
> #define C400_HOST_BUFFER         NCR53C400_register_offset-4
> 
> This is probably OK for a port-mapped 53C400 (such card must have some glue
> decoding logic as the 53C400 chip itself can do memory-mapping only) because:
> 
>                 /*
>                  * On NCR53C400 boards, NCR5380 registers are mapped 8 past
>                  * the base address.
>                  */
>                 if (overrides[current_override].board == BOARD_NCR53C400)
>                         instance->io_port += 8;
> 
> This means that on a 53C400, first 5380 register will be at base+8 and first
> C400_ register at base.
> 
> But on a 53C400A, the 5380 registers are mapped on the base address so the
> C400_ registers would be below the base, which is obviously wrong. I hope that
> PDMA will work if I fix the C400_ registers mapping.

A quick hack (breaks other chips, needs more work for proper mapping on all
chips):



And PDMA works on I/O mapped 53C400A (HP C2502)!

# modprobe g_NCR5380 ncr_irq=7 ncr_addr=0x280 ncr_53c400a=1
[ 1799.939856] scsi host4: Generic NCR5380/NCR53C400 SCSI, io_port 0x280, n_io_port 16, base 0x0, irq 0, can_queue 16, cmd_per_lun 2, sg_tablesize 128, this_id 7, flags { NO_DMA_FIXUP }, options { AUTOPROBE_IRQ PSEUDO_DMA }
[ 1816.277018] scsi 4:0:1:0: Direct-Access     QUANTUM  LP240S GM240S01X 4.6  PQ: 0 ANSI: 2 CCS
[ 1897.899648] sd 4:0:1:0: Attached scsi generic sg1 type 0
[ 1897.917842] sd 4:0:1:0: [sdb] 479350 512-byte logical blocks: (245 MB/234 MiB)
[ 1897.920872] sd 4:0:1:0: [sdb] Write Protect is off
[ 1897.924744] sd 4:0:1:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 1897.967857]  sdb: sdb1
[ 1897.993822] sd 4:0:1:0: [sdb] Attached SCSI disk


Nice performance improvement (although it's slower than the memory-mapped
53C400):
# hdparm -t --direct /dev/sdb

/dev/sdb:
 Timing O_DIRECT disk reads:   2 MB in  3.99 seconds = 513.57 kB/sec


And it even fixed the IRQ:
# head /proc/interrupts
           CPU0
  0:     151228    XT-PIC  timer
  1:          9    XT-PIC  i8042
  2:          0    XT-PIC  cascade
  7:        115    XT-PIC  NCR5380
  8:          1    XT-PIC  rtc0
  9:          0    XT-PIC  uhci_hcd:usb1, uhci_hcd:usb2
 10:       3256    XT-PIC  eth0
 12:        136    XT-PIC  i8042
 14:       3833    XT-PIC  pata_via
diff mbox

Patch

--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -163,7 +163,7 @@ 
 /* Write any value to this register to start an ini mode DMA receive */
 #define START_DMA_INITIATOR_RECEIVE_REG 7      /* wo */

-#define C400_CONTROL_STATUS_REG NCR53C400_register_offset-8    /* rw */
+#define C400_CONTROL_STATUS_REG 9      /* rw */

 #define CSR_RESET              0x80    /* wo  Resets 53c400 */
 #define CSR_53C80_REG          0x80    /* ro  5380 registers busy */
@@ -182,13 +182,13 @@ 
 #endif

 /* Number of 128-byte blocks to be transferred */
-#define C400_BLOCK_COUNTER_REG   NCR53C400_register_offset-7   /* rw */
+#define C400_BLOCK_COUNTER_REG   10    /* rw */

 /* Resume transfer after disconnect */
-#define C400_RESUME_TRANSFER_REG NCR53C400_register_offset-6   /* wo */
+#define C400_RESUME_TRANSFER_REG 11    /* wo */

 /* Access to host buffer stack */
-#define C400_HOST_BUFFER         NCR53C400_register_offset-4   /* rw */
+#define C400_HOST_BUFFER         8     /* rw */


 /* Note : PHASE_* macros are based on the values of the STATUS register */
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -323,7 +323,10 @@  static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
 #endif
                        break;
                case BOARD_NCR53C400A:
+                       flags = FLAG_NO_DMA_FIXUP;
+#ifndef PSEUDO_DMA
                        flags = FLAG_NO_PSEUDO_DMA;
+#endif
                        ports = ncr_53c400a_ports;
                        break;
                case BOARD_DTC3181E:
@@ -414,7 +417,8 @@  static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
                if (NCR5380_init(instance, flags))
                        goto out_unregister;

-               if (overrides[current_override].board == BOARD_NCR53C400)
+               if (overrides[current_override].board == BOARD_NCR53C400 ||
+                   overrides[current_override].board == BOARD_NCR53C400A)
                        NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);

                NCR5380_maybe_reset_bus(instance);