Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/ide-2.6
authorDavid S. Miller <davem@davemloft.net>
Wed, 3 Mar 2010 07:57:59 +0000 (23:57 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Mar 2010 07:57:59 +0000 (23:57 -0800)
1  2 
drivers/ide/cmd640.c
drivers/ide/icside.c
drivers/ide/pdc202xx_old.c
drivers/ide/scc_pata.c

diff --combined drivers/ide/cmd640.c
index c7d46a3d347a6410b054ffcd3a63354792b4eaf9,cb11938ba684e7fd8865bfb5f1315118676d3578..d2b8b272bc27810a5dcfa4571e0eeb789ffd0e88
@@@ -572,10 -572,9 +572,10 @@@ static void cmd640_set_mode(ide_drive_
        program_drive_counts(drive, index);
  }
  
 -static void cmd640_set_pio_mode(ide_drive_t *drive, const u8 pio)
 +static void cmd640_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
  {
        unsigned int index = 0, cycle_time;
 +      const u8 pio = drive->pio_mode - XFER_PIO_0;
        u8 b;
  
        switch (pio) {
  }
  #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */
  
- static void cmd640_init_dev(ide_drive_t *drive)
+ static void __init cmd640_init_dev(ide_drive_t *drive)
  {
        unsigned int i = drive->hwif->channel * 2 + (drive->dn & 1);
  
diff --combined drivers/ide/icside.c
index 26b6c0a1f772751956817a0489a003d7f52fcd50,d7e6f09aa86bff58e2035fdd3916fc7d4740d494..4a697a238e280e2ce14c627d0d1f4bf053b86b45
@@@ -65,6 -65,8 +65,8 @@@ static struct cardinfo icside_cardinfo_
  };
  
  struct icside_state {
+       unsigned int channel;
+       unsigned int enabled;
        void __iomem *irq_port;
        void __iomem *ioc_base;
        unsigned int sel;
@@@ -114,11 -116,18 +116,18 @@@ static void icside_irqenable_arcin_v6 (
        struct icside_state *state = ec->irq_data;
        void __iomem *base = state->irq_port;
  
-       writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
-       readb(base + ICS_ARCIN_V6_INTROFFSET_2);
+       state->enabled = 1;
  
-       writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
-       readb(base + ICS_ARCIN_V6_INTROFFSET_1);
+       switch (state->channel) {
+       case 0:
+               writeb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
+               readb(base + ICS_ARCIN_V6_INTROFFSET_2);
+               break;
+       case 1:
+               writeb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
+               readb(base + ICS_ARCIN_V6_INTROFFSET_1);
+               break;
+       }
  }
  
  /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
@@@ -128,6 -137,8 +137,8 @@@ static void icside_irqdisable_arcin_v6 
  {
        struct icside_state *state = ec->irq_data;
  
+       state->enabled = 0;
        readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
        readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
  }
@@@ -149,6 -160,44 +160,44 @@@ static const expansioncard_ops_t icside
        .irqpending     = icside_irqpending_arcin_v6,
  };
  
+ /*
+  * Handle routing of interrupts.  This is called before
+  * we write the command to the drive.
+  */
+ static void icside_maskproc(ide_drive_t *drive, int mask)
+ {
+       ide_hwif_t *hwif = drive->hwif;
+       struct expansion_card *ec = ECARD_DEV(hwif->dev);
+       struct icside_state *state = ecard_get_drvdata(ec);
+       unsigned long flags;
+       local_irq_save(flags);
+       state->channel = hwif->channel;
+       if (state->enabled && !mask) {
+               switch (hwif->channel) {
+               case 0:
+                       writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+                       readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+                       break;
+               case 1:
+                       writeb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+                       readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+                       break;
+               }
+       } else {
+               readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
+               readb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
+       }
+       local_irq_restore(flags);
+ }
+ static const struct ide_port_ops icside_v6_no_dma_port_ops = {
+       .maskproc               = icside_maskproc,
+ };
  #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
  /*
   * SG-DMA support.
   *    MW1     80      50      50      150     C
   *    MW2     70      25      25      120     C
   */
 -static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode)
 +static void icside_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
  {
        unsigned long cycle_time;
        int use_dma_info = 0;
 +      const u8 xfer_mode = drive->dma_mode;
  
        switch (xfer_mode) {
        case XFER_MW_DMA_2:
  
  static const struct ide_port_ops icside_v6_port_ops = {
        .set_dma_mode           = icside_set_dma_mode,
+       .maskproc               = icside_maskproc,
  };
  
  static void icside_dma_host_set(ide_drive_t *drive, int on)
@@@ -272,6 -321,11 +322,11 @@@ static int icside_dma_setup(ide_drive_
         */
        BUG_ON(dma_channel_active(ec->dma));
  
+       /*
+        * Ensure that we have the right interrupt routed.
+        */
+       icside_maskproc(drive, 0);
        /*
         * Route the DMA signals to the correct interface.
         */
@@@ -400,6 -454,7 +455,7 @@@ err_free
  
  static const struct ide_port_info icside_v6_port_info __initdata = {
        .init_dma               = icside_dma_off_init,
+       .port_ops               = &icside_v6_no_dma_port_ops,
        .dma_ops                = &icside_v6_dma_ops,
        .host_flags             = IDE_HFLAG_SERIALIZE | IDE_HFLAG_MMIO,
        .mwdma_mask             = ATA_MWDMA2,
index 07cd37516ba6bf9db87239f13d16ce63c549d3e6,e3bca38a03f228adc7f9f30121e6482dd962ca00..c5f3841af360da3d8d62a4fc10bb10b7160f21e0
@@@ -1,7 -1,7 +1,7 @@@
  /*
   *  Copyright (C) 1998-2002           Andre Hedrick <andre@linux-ide.org>
   *  Copyright (C) 2006-2007, 2009     MontaVista Software, Inc.
 - *  Copyright (C) 2007                        Bartlomiej Zolnierkiewicz
 + *  Copyright (C) 2007-2010           Bartlomiej Zolnierkiewicz
   *
   *  Portions Copyright (C) 1999 Promise Technology, Inc.
   *  Author: Frank Tiernan (frankt@promise.com)
  
  #define DRV_NAME "pdc202xx_old"
  
 -static void pdc_old_disable_66MHz_clock(ide_hwif_t *);
 -
 -static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed)
 +static void pdc202xx_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
  {
 -      ide_hwif_t *hwif        = drive->hwif;
        struct pci_dev *dev     = to_pci_dev(hwif->dev);
        u8 drive_pci            = 0x60 + (drive->dn << 2);
 +      const u8 speed          = drive->dma_mode;
  
        u8                      AP = 0, BP = 0, CP = 0;
        u8                      TA = 0, TB = 0, TC = 0;
  
 -      /*
 -       * TODO: do this once per channel
 -       */
 -      if (dev->device != PCI_DEVICE_ID_PROMISE_20246)
 -              pdc_old_disable_66MHz_clock(hwif);
 -
        pci_read_config_byte(dev, drive_pci,     &AP);
        pci_read_config_byte(dev, drive_pci + 1, &BP);
        pci_read_config_byte(dev, drive_pci + 2, &CP);
        }
  }
  
 -static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio)
 +static void pdc202xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
  {
 -      pdc202xx_set_mode(drive, XFER_PIO_0 + pio);
 +      drive->dma_mode = drive->pio_mode;
 +      pdc202xx_set_mode(hwif, drive);
  }
  
  static int pdc202xx_test_irq(ide_hwif_t *hwif)
                 * bit 7: error, bit 6: interrupting,
                 * bit 5: FIFO full, bit 4: FIFO empty
                 */
-               return ((sc1d & 0x50) == 0x40) ? 1 : 0;
+               return ((sc1d & 0x50) == 0x50) ? 1 : 0;
        } else  {
                /*
                 * bit 3: error, bit 2: interrupting,
                 * bit 1: FIFO full, bit 0: FIFO empty
                 */
-               return ((sc1d & 0x05) == 0x04) ? 1 : 0;
+               return ((sc1d & 0x05) == 0x05) ? 1 : 0;
        }
  }
  
@@@ -138,11 -145,6 +138,11 @@@ static void pdc_old_disable_66MHz_clock
        outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
  }
  
 +static void pdc2026x_init_hwif(ide_hwif_t *hwif)
 +{
 +      pdc_old_disable_66MHz_clock(hwif);
 +}
 +
  static void pdc202xx_dma_start(ide_drive_t *drive)
  {
        if (drive->current_speed > XFER_UDMA_2)
@@@ -259,7 -261,6 +259,7 @@@ static const struct ide_dma_ops pdc2026
        { \
                .name           = DRV_NAME, \
                .init_chipset   = init_chipset_pdc202xx, \
 +              .init_hwif      = pdc2026x_init_hwif, \
                .port_ops       = &pdc2026x_port_ops, \
                .dma_ops        = &pdc2026x_dma_ops, \
                .host_flags     = IDE_HFLAGS_PDC202XX, \
@@@ -355,6 -356,6 +355,6 @@@ static void __exit pdc202xx_ide_exit(vo
  module_init(pdc202xx_ide_init);
  module_exit(pdc202xx_ide_exit);
  
 -MODULE_AUTHOR("Andre Hedrick, Frank Tiernan");
 +MODULE_AUTHOR("Andre Hedrick, Frank Tiernan, Bartlomiej Zolnierkiewicz");
  MODULE_DESCRIPTION("PCI driver module for older Promise IDE");
  MODULE_LICENSE("GPL");
diff --combined drivers/ide/scc_pata.c
index e9d4b441d1c355bdd1329925c341acc275c1dc88,8066168992d7329972c7bbaa97b61014eefa1472..b7f5b0c4310c2e18558f222b217b1ed9a4f3e0b4
@@@ -199,15 -199,16 +199,15 @@@ scc_ide_outsl(unsigned long port, void 
  
  /**
   *    scc_set_pio_mode        -       set host controller for PIO mode
 + *    @hwif: port
   *    @drive: drive
 - *    @pio: PIO mode number
   *
   *    Load the timing settings for this device mode into the
   *    controller.
   */
  
 -static void scc_set_pio_mode(ide_drive_t *drive, const u8 pio)
 +static void scc_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
  {
 -      ide_hwif_t *hwif = drive->hwif;
        struct scc_ports *ports = ide_get_hwifdata(hwif);
        unsigned long ctl_base = ports->ctl;
        unsigned long cckctrl_port = ctl_base + 0xff0;
        unsigned long pioct_port = ctl_base + 0x004;
        unsigned long reg;
        int offset;
 +      const u8 pio = drive->pio_mode - XFER_PIO_0;
  
        reg = in_be32((void __iomem *)cckctrl_port);
        if (reg & CCKCTRL_ATACLKOEN) {
  
  /**
   *    scc_set_dma_mode        -       set host controller for DMA mode
 + *    @hwif: port
   *    @drive: drive
 - *    @speed: DMA mode
   *
   *    Load the timing settings for this device mode into the
   *    controller.
   */
  
 -static void scc_set_dma_mode(ide_drive_t *drive, const u8 speed)
 +static void scc_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
  {
 -      ide_hwif_t *hwif = drive->hwif;
        struct scc_ports *ports = ide_get_hwifdata(hwif);
        unsigned long ctl_base = ports->ctl;
        unsigned long cckctrl_port = ctl_base + 0xff0;
        int offset, idx;
        unsigned long reg;
        unsigned long jcactsel;
 +      const u8 speed = drive->dma_mode;
  
        reg = in_be32((void __iomem *)cckctrl_port);
        if (reg & CCKCTRL_ATACLKOEN) {
@@@ -872,20 -872,18 +872,18 @@@ static struct pci_driver scc_pci_drive
        .remove = __devexit_p(scc_remove),
  };
  
- static int scc_ide_init(void)
+ static int __init scc_ide_init(void)
  {
        return ide_pci_register_driver(&scc_pci_driver);
  }
  
- module_init(scc_ide_init);
- /* -- No exit code?
- static void scc_ide_exit(void)
+ static void __exit scc_ide_exit(void)
  {
-       ide_pci_unregister_driver(&scc_pci_driver);
+       pci_unregister_driver(&scc_pci_driver);
  }
- module_exit(scc_ide_exit);
-  */
  
+ module_init(scc_ide_init);
+ module_exit(scc_ide_exit);
  
  MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
  MODULE_LICENSE("GPL");