Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-1-5]: src/sys/dev/pci Pull up



details:   https://anonhg.NetBSD.org/src/rev/79be8a59a6f2
branches:  netbsd-1-5
changeset: 488282:79be8a59a6f2
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Tue Jun 27 14:57:05 2000 +0000

description:
Pull up
pciide.c  1.69->1.70,  1.71->1.72
pciide_cmd_reg.h 1.6->1.7
Approved by thorpej:
Add support for the CMD PCI0648/0649 IDE controller.

diffstat:

 sys/dev/pci/pciide.c         |  112 +++++++++++++++++++++++++++++++++---------
 sys/dev/pci/pciide_cmd_reg.h |   37 +++++++++----
 2 files changed, 112 insertions(+), 37 deletions(-)

diffs (259 lines):

diff -r 965323bebbf5 -r 79be8a59a6f2 sys/dev/pci/pciide.c
--- a/sys/dev/pci/pciide.c      Tue Jun 27 14:07:41 2000 +0000
+++ b/sys/dev/pci/pciide.c      Tue Jun 27 14:57:05 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pciide.c,v 1.68.2.1 2000/06/27 14:07:41 bouyer Exp $   */
+/*     $NetBSD: pciide.c,v 1.68.2.2 2000/06/27 14:57:05 bouyer Exp $   */
 
 
 /*
@@ -167,8 +167,8 @@
 void apollo_setup_channel __P((struct channel_softc*));
 
 void cmd_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
-void cmd0643_6_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
-void cmd0643_6_setup_channel __P((struct channel_softc*));
+void cmd0643_9_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
+void cmd0643_9_setup_channel __P((struct channel_softc*));
 void cmd_channel_map __P((struct pci_attach_args *,
                        struct pciide_softc *, int));
 int  cmd_pci_intr __P((void *));
@@ -279,12 +279,22 @@
        { PCI_PRODUCT_CMDTECH_643,
          0,
          "CMD Technology PCI0643",
-         cmd0643_6_chip_map,
+         cmd0643_9_chip_map,
        },
        { PCI_PRODUCT_CMDTECH_646,
          0,
          "CMD Technology PCI0646",
-         cmd0643_6_chip_map,
+         cmd0643_9_chip_map,
+       },
+       { PCI_PRODUCT_CMDTECH_648,
+         IDE_PCI_CLASS_OVERRIDE,
+         "CMD Technology PCI0648",
+         cmd0643_9_chip_map,
+       },
+       { PCI_PRODUCT_CMDTECH_649,
+         IDE_PCI_CLASS_OVERRIDE,
+         "CMD Technology PCI0649",
+         cmd0643_9_chip_map,
        },
        { 0,
          0,
@@ -1991,7 +2001,22 @@
        struct pciide_channel *cp = &sc->pciide_channels[channel];
        bus_size_t cmdsize, ctlsize;
        u_int8_t ctrl = pciide_pci_read(sc->sc_pc, sc->sc_tag, CMD_CTRL);
-       int interface = PCI_INTERFACE(pa->pa_class);
+       int interface;
+
+       /* 
+        * The 0648/0649 can be told to identify as a RAID controller.
+        * In this case, we have to fake interface
+        */
+       if (PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_MASS_STORAGE_IDE) {
+               interface = PCIIDE_INTERFACE_SETTABLE(0) |
+                   PCIIDE_INTERFACE_SETTABLE(1);
+               if (pciide_pci_read(pa->pa_pc, pa->pa_tag, CMD_CONF) &
+                   CMD_CONF_DSA1)
+                       interface |= PCIIDE_INTERFACE_PCI(0) |
+                           PCIIDE_INTERFACE_PCI(1);
+       } else {
+               interface = PCI_INTERFACE(pa->pa_class);
+       }
 
        sc->wdc_chanarray[channel] = &cp->wdc_channel;
        cp->name = PCIIDE_CHANNEL_NAME(channel);
@@ -2111,7 +2136,7 @@
 }
 
 void
-cmd0643_6_chip_map(sc, pa)
+cmd0643_9_chip_map(sc, pa)
        struct pciide_softc *sc;
        struct pci_attach_args *pa;
 {       
@@ -2141,15 +2166,21 @@
        if (sc->sc_dma_ok) {
                sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
                sc->sc_wdcdev.irqack = pciide_irqack;
+               switch (sc->sc_pp->ide_product) {
+               case PCI_PRODUCT_CMDTECH_649:
+               case PCI_PRODUCT_CMDTECH_648:
+                       sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
+                       sc->sc_wdcdev.UDMA_cap = 4;
+               }
        }
 
        sc->sc_wdcdev.channels = sc->wdc_chanarray;
        sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
        sc->sc_wdcdev.PIO_cap = 4;
        sc->sc_wdcdev.DMA_cap = 2;
-       sc->sc_wdcdev.set_modes = cmd0643_6_setup_channel;
+       sc->sc_wdcdev.set_modes = cmd0643_9_setup_channel;
 
-       WDCDEBUG_PRINT(("cmd0643_6_chip_map: old timings reg 0x%x 0x%x\n",
+       WDCDEBUG_PRINT(("cmd0643_9_chip_map: old timings reg 0x%x 0x%x\n",
                pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54),
                pci_conf_read(sc->sc_pc, sc->sc_tag, 0x58)),
                DEBUG_PROBE);
@@ -2159,22 +2190,22 @@
                cmd_channel_map(pa, sc, channel);
                if (cp->hw_ok == 0)
                        continue;
-               cmd0643_6_setup_channel(&cp->wdc_channel);
+               cmd0643_9_setup_channel(&cp->wdc_channel);
        }
        pciide_pci_write(sc->sc_pc, sc->sc_tag, CMD_DMA_MODE, CMD_DMA_MULTIPLE);
-       WDCDEBUG_PRINT(("cmd0643_6_chip_map: timings reg now 0x%x 0x%x\n",
+       WDCDEBUG_PRINT(("cmd0643_9_chip_map: timings reg now 0x%x 0x%x\n",
            pci_conf_read(sc->sc_pc, sc->sc_tag, 0x54),
            pci_conf_read(sc->sc_pc, sc->sc_tag, 0x58)),
            DEBUG_PROBE);
 }
 
 void
-cmd0643_6_setup_channel(chp)
+cmd0643_9_setup_channel(chp)
        struct channel_softc *chp;
 {
        struct ata_drive_datas *drvp;
        u_int8_t tim;
-       u_int32_t idedma_ctl;
+       u_int32_t idedma_ctl, udma_reg;
        int drive;
        struct pciide_channel *cp = (struct pciide_channel*)chp;
        struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
@@ -2189,18 +2220,51 @@
                if ((drvp->drive_flags & DRIVE) == 0)
                        continue;
                /* add timing values, setup DMA if needed */
-               tim = cmd0643_6_data_tim_pio[drvp->PIO_mode];
-               if (drvp->drive_flags & DRIVE_DMA) {
-                       /*
-                        * use Multiword DMA.
-                        * Timings will be used for both PIO and DMA, so adjust
-                        * DMA mode if needed
-                        */
-                       if (drvp->PIO_mode >= 3 &&
-                           (drvp->DMA_mode + 2) > drvp->PIO_mode) {
-                               drvp->DMA_mode = drvp->PIO_mode - 2;
+               tim = cmd0643_9_data_tim_pio[drvp->PIO_mode];
+               if (drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) {
+                       if (drvp->drive_flags & DRIVE_UDMA) {
+                               /* UltraDMA on a 0648 or 0649 */
+                               udma_reg = pciide_pci_read(sc->sc_pc,
+                                   sc->sc_tag, CMD_UDMATIM(chp->channel));
+                               if (drvp->UDMA_mode > 2 &&
+                                   (pciide_pci_read(sc->sc_pc, sc->sc_tag,
+                                   CMD_BICSR) &
+                                   CMD_BICSR_80(chp->channel)) == 0)
+                                       drvp->UDMA_mode = 2;
+                               if (drvp->UDMA_mode > 2)
+                                       udma_reg &= ~CMD_UDMATIM_UDMA33(drive);
+                               else
+                                       udma_reg |= CMD_UDMATIM_UDMA33(drive);
+                               udma_reg |= CMD_UDMATIM_UDMA(drive);
+                               udma_reg &= ~(CMD_UDMATIM_TIM_MASK <<
+                                   CMD_UDMATIM_TIM_OFF(drive));
+                               udma_reg |=
+                                   (cmd0648_9_tim_udma[drvp->UDMA_mode] <<
+                                   CMD_UDMATIM_TIM_OFF(drive));
+                               pciide_pci_write(sc->sc_pc, sc->sc_tag,
+                                   CMD_UDMATIM(chp->channel), udma_reg);
+                       } else {
+                               /*
+                                * use Multiword DMA.
+                                * Timings will be used for both PIO and DMA,
+                                * so adjust DMA mode if needed
+                                * if we have a 0648/9, turn off UDMA
+                                */
+                               if (sc->sc_wdcdev.cap & WDC_CAPABILITY_UDMA) {
+                                       udma_reg = pciide_pci_read(sc->sc_pc,
+                                           sc->sc_tag,
+                                           CMD_UDMATIM(chp->channel));
+                                       udma_reg &= ~CMD_UDMATIM_UDMA(drive);
+                                       pciide_pci_write(sc->sc_pc, sc->sc_tag,
+                                           CMD_UDMATIM(chp->channel),
+                                           udma_reg);
+                               }
+                               if (drvp->PIO_mode >= 3 &&
+                                   (drvp->DMA_mode + 2) > drvp->PIO_mode) {
+                                       drvp->DMA_mode = drvp->PIO_mode - 2;
+                               }
+                               tim = cmd0643_9_data_tim_dma[drvp->DMA_mode];
                        }
-                       tim = cmd0643_6_data_tim_dma[drvp->DMA_mode];
                        idedma_ctl |= IDEDMA_CTL_DRV_DMA(drive);
                }
                pciide_pci_write(sc->sc_pc, sc->sc_tag,
diff -r 965323bebbf5 -r 79be8a59a6f2 sys/dev/pci/pciide_cmd_reg.h
--- a/sys/dev/pci/pciide_cmd_reg.h      Tue Jun 27 14:07:41 2000 +0000
+++ b/sys/dev/pci/pciide_cmd_reg.h      Tue Jun 27 14:57:05 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pciide_cmd_reg.h,v 1.6 2000/05/15 08:46:01 bouyer Exp $        */
+/*     $NetBSD: pciide_cmd_reg.h,v 1.6.4.1 2000/06/27 14:57:07 bouyer Exp $    */
 
 /*
  * Copyright (c) 1998 Manuel Bouyer.
@@ -39,21 +39,21 @@
 
 /* Configuration (RO) */
 #define CMD_CONF 0x50
-#define CMD_CONF_REV_MASK      0x03
+#define CMD_CONF_REV_MASK      0x03 /* 0640/3/6 only */
 #define CMD_CONF_DRV0_INTR     0x04
-#define CMD_CONF_DEVID         0x18
-#define CMD_CONF_VESAPRT       0x20
+#define CMD_CONF_DEVID         0x18 /* 0640/3/6 only */
+#define CMD_CONF_VESAPRT       0x20 /* 0640/3/6 only */
 #define CMD_CONF_DSA1          0x40
-#define CMD_CONF_DSA0          0x80
+#define CMD_CONF_DSA0          0x80 /* 0640/3/6 only */
 
 /* Control register (RW) */
 #define CMD_CTRL 0x51
-#define CMD_CTRL_HR_FIFO               0x01
-#define CMD_CTRL_HW_FIFO               0x02
+#define CMD_CTRL_HR_FIFO               0x01 /* 0640/3/6 only */
+#define CMD_CTRL_HW_FIFO               0x02 /* 0640/3/6 only */
 #define CMD_CTRL_DEVSEL                        0x04
 #define CMD_CTRL_2PORT                 0x08
-#define CMD_CTRL_PAR                   0x10
-#define CMD_CTRL_HW_HLD                        0x20
+#define CMD_CTRL_PAR                   0x10 /* 0640/3/6 only */
+#define CMD_CTRL_HW_HLD                        0x20 /* 0640/3/6 only */
 #define CMD_CTRL_DRV0_RAHEAD           0x40
 #define CMD_CTRL_DRV1_RAHEAD           0x80
 
@@ -77,12 +77,23 @@
 #define CMD_DMA                        0x00
 #define CMD_DMA_MULTIPLE       0x01
 #define CMD_DMA_LINE           0x10
-               
+
+/* the followings are only for 0648/9 */
+/* busmaster control/status register */
+#define CMD_BICSR      0x79
+#define CMD_BICSR_80(chan)     (0x01 << (chan))
+/* Ultra/DMA timings reg */
+#define CMD_UDMATIM(channel)   (0x73 + (8 * (channel)))
+#define CMD_UDMATIM_UDMA(drive)        (0x01 << (drive))
+#define CMD_UDMATIM_UDMA33(drive) (0x04 << (drive))
+#define CMD_UDMATIM_TIM_MASK   0x3
+#define CMD_UDMATIM_TIM_OFF(drive) (4 + ((drive) * 2))
+static int8_t cmd0648_9_tim_udma[] = {0x03, 0x02, 0x01, 0x02, 0x01};
 
 /*
- * timings values for the 0643 and 0x646
+ * timings values for the 0643/6/8/9
  * for all dma_mode we have to have
  * DMA_timings(dma_mode) >= PIO_timings(dma_mode + 2)
  */
-static int8_t cmd0643_6_data_tim_pio[] = {0xA9, 0x57, 0x44, 0x32, 0x3F};
-static int8_t cmd0643_6_data_tim_dma[] = {0x87, 0x32, 0x3F};
+static int8_t cmd0643_9_data_tim_pio[] = {0xA9, 0x57, 0x44, 0x32, 0x3F};
+static int8_t cmd0643_9_data_tim_dma[] = {0x87, 0x32, 0x3F};



Home | Main Index | Thread Index | Old Index