Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci Fix bug which affects pciide controllers in nati...



details:   https://anonhg.NetBSD.org/src/rev/efeb6169ab11
branches:  trunk
changeset: 502143:efeb6169ab11
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Fri Jan 12 16:03:59 2001 +0000

description:
Fix bug which affects pciide controllers in native mode (found by
Paul Kranenburg, many thanks !): the control register I/O is 4 byte long
although only one is used, but the control register is at offset 2, and not
0 as expected by IC code. Use bus_space_subregion() to get a handle which
points to the control register, and is one byte long.

diffstat:

 sys/dev/pci/pciide.c    |  17 +++++++++++++++--
 sys/dev/pci/pciidevar.h |   9 +++++----
 2 files changed, 20 insertions(+), 6 deletions(-)

diffs (59 lines):

diff -r f546568f1c66 -r efeb6169ab11 sys/dev/pci/pciide.c
--- a/sys/dev/pci/pciide.c      Fri Jan 12 15:24:15 2001 +0000
+++ b/sys/dev/pci/pciide.c      Fri Jan 12 16:03:59 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pciide.c,v 1.104 2001/01/05 18:04:42 bouyer Exp $      */
+/*     $NetBSD: pciide.c,v 1.105 2001/01/12 16:03:59 bouyer Exp $      */
 
 
 /*
@@ -671,12 +671,25 @@
 
        if (pci_mapreg_map(pa, PCIIDE_REG_CTL_BASE(wdc_cp->channel),
            PCI_MAPREG_TYPE_IO, 0,
-           &wdc_cp->ctl_iot, &wdc_cp->ctl_ioh, NULL, ctlsizep) != 0) {
+           &wdc_cp->ctl_iot, &cp->ctl_baseioh, NULL, ctlsizep) != 0) {
                printf("%s: couldn't map %s channel ctl regs\n",
                    sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
                bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep);
                return 0;
        }
+       /*
+        * In native mode, 4 bytes of I/O space are mapped for the control
+        * register, the control register is at offset 2. Pass the generic
+        * code a handle for only one byte at the rigth offset.
+        */
+       if (bus_space_subregion(wdc_cp->ctl_iot, cp->ctl_baseioh, 2, 1,
+           &wdc_cp->ctl_ioh) != 0) {
+               printf("%s: unable to subregion %s channel ctl regs\n",
+                   sc->sc_wdcdev.sc_dev.dv_xname, cp->name);
+               bus_space_unmap(wdc_cp->cmd_iot, wdc_cp->cmd_ioh, *cmdsizep);
+               bus_space_unmap(wdc_cp->cmd_iot, cp->ctl_baseioh, *ctlsizep);
+               return 0;
+       }
        return (1);
 }
 
diff -r f546568f1c66 -r efeb6169ab11 sys/dev/pci/pciidevar.h
--- a/sys/dev/pci/pciidevar.h   Fri Jan 12 15:24:15 2001 +0000
+++ b/sys/dev/pci/pciidevar.h   Fri Jan 12 16:03:59 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pciidevar.h,v 1.5 2000/06/06 17:34:23 thorpej Exp $    */
+/*     $NetBSD: pciidevar.h,v 1.6 2001/01/12 16:04:00 bouyer Exp $     */
 
 /*
  * Copyright (c) 1998 Christopher G. Demetriou.  All rights reserved.
@@ -64,9 +64,10 @@
        struct pciide_channel {                 /* per-channel data */
                struct channel_softc wdc_channel; /* generic part */
                char            *name;
-               int             hw_ok;          /* hardware mapped & OK? */
-               int             compat;         /* is it compat? */
-               void            *ih;            /* compat or pci handle */
+               int             hw_ok;  /* hardware mapped & OK? */
+               int             compat; /* is it compat? */
+               void            *ih;    /* compat or pci handle */
+               bus_space_handle_t ctl_baseioh; /* ctrl regs blk, native mode */
                /* DMA tables and DMA map for xfer, for each drive */
                struct pciide_dma_maps {
                        bus_dmamap_t    dmamap_table;



Home | Main Index | Thread Index | Old Index