Author: imp
Date: Sat Nov 15 05:22:06 2008
New Revision: 184981
URL: http://svn.freebsd.org/changeset/base/184981

Log:
  First step in cleaning up CIS parsing and /dev/cardbus*.cis: remove
  redundant malloc/free.  Add comments about how this should really be
  done.  Fix an overly verbose comment about under 1MB mapping: go ahead
  and set the bits, but we ignore them.

Modified:
  head/sys/dev/cardbus/cardbus_cis.c
  head/sys/dev/cardbus/cardbus_device.c
  head/sys/dev/cardbus/cardbusvar.h

Modified: head/sys/dev/cardbus/cardbus_cis.c
==============================================================================
--- head/sys/dev/cardbus/cardbus_cis.c  Sat Nov 15 04:43:54 2008        
(r184980)
+++ head/sys/dev/cardbus/cardbus_cis.c  Sat Nov 15 05:22:06 2008        
(r184981)
@@ -318,29 +318,27 @@ decode_tuple_bar(device_t cbdev, device_
        if (type == SYS_RES_MEMORY) {
                if (reg & TPL_BAR_REG_PREFETCHABLE)
                        dinfo->mprefetchable |= (1 << PCI_RID2BAR(bar));
-#if 0
                /*
-                * XXX: It appears from a careful reading of the spec
-                * that we're not supposed to honor this when the bridge
-                * is not on the main system bus.  PCI spec doesn't appear
-                * to allow for memory ranges not listed in the bridge's
-                * decode range to be decoded.  The PC Card spec seems to
-                * indicate that this should only be done on x86 based
-                * machines, which seems to imply that on non-x86 machines
-                * the adddresses can be anywhere.  This further implies that
-                * since the hardware can do it on non-x86 machines, it should
-                * be able to do it on x86 machines.  Therefore, we can and
-                * should ignore this hint.  Furthermore, the PC Card spec
-                * recommends always allocating memory above 1MB, contradicting
-                * the other part of the PC Card spec.
+                * The PC Card spec says we're only supposed to honor this
+                * hint when the cardbus bridge is a child of pci0 (the main
+                * bus).  The PC Card spec seems to indicate that this should
+                * only be done on x86 based machines, which suggests that on
+                * non-x86 machines the adddresses can be anywhere.  Since the
+                * hardware can do it on non-x86 machines, it should be able
+                * to do it on x86 machines too.  Therefore, we can and should
+                * ignore this hint.  Furthermore, the PC Card spec recommends
+                * always allocating memory above 1MB, contradicting the other
+                * part of the PC Card spec, it seems.  We make note of it,
+                * but otherwise don't use this information.
                 *
-                * NetBSD ignores this bit, but it also ignores the
-                * prefetchable bit too, so that's not an indication of
-                * correctness.
+                * Some Realtek cards have this set in their CIS, but fail
+                * to actually work when mapped this way, and experience
+                * has shown ignoring this big to be a wise choice.
+                *
+                * XXX We should cite chapter and verse for standard refs.
                 */
                if (reg & TPL_BAR_REG_BELOW1MB)
                        dinfo->mbelow1mb |= (1 << PCI_RID2BAR(bar));
-#endif
        }
 
        return (0);

Modified: head/sys/dev/cardbus/cardbus_device.c
==============================================================================
--- head/sys/dev/cardbus/cardbus_device.c       Sat Nov 15 04:43:54 2008        
(r184980)
+++ head/sys/dev/cardbus/cardbus_device.c       Sat Nov 15 05:22:06 2008        
(r184981)
@@ -96,13 +96,17 @@ cardbus_build_cis(device_t cbdev, device
         * CISTPL_END is a special case, it has no length field.
         */
        if (id == CISTPL_END) {
-               if (cis->len + 1 > sizeof(cis->buffer))
+               if (cis->len + 1 > sizeof(cis->buffer)) {
+                       cis->len = 0;
                        return (ENOSPC);
+               }
                cis->buffer[cis->len++] = id;
                return (0);
        }
-       if (cis->len + 2 + len > sizeof(cis->buffer))
+       if (cis->len + 2 + len > sizeof(cis->buffer)) {
+               cis->len = 0;
                return (ENOSPC);
+       }
        cis->buffer[cis->len++] = id;
        cis->buffer[cis->len++] = len;
        for (i = 0; i < len; i++)
@@ -110,6 +114,18 @@ cardbus_build_cis(device_t cbdev, device
        return (0);
 }
 
+static int
+cardbus_device_buffer_cis(device_t parent, device_t child)
+{
+       struct cardbus_softc *sc;
+       struct tuple_callbacks cb[] = {
+               {CISTPL_GENERIC, "GENERIC", cardbus_build_cis}
+       };
+
+       sc = device_get_softc(parent);
+       return (cardbus_parse_cis(parent, child, cb, &sc->sc_cis));
+}
+
 static int
 cardbus_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
 {
@@ -117,9 +133,6 @@ cardbus_open(struct cdev *dev, int oflag
        device_t *kids;
        int cnt, err;
        struct cardbus_softc *sc;
-       struct tuple_callbacks cb[] = {
-               {CISTPL_GENERIC, "GENERIC", cardbus_build_cis}
-       };
 
        sc = dev->si_drv1;
        if (sc->sc_cis_open)
@@ -128,21 +141,17 @@ cardbus_open(struct cdev *dev, int oflag
        err = device_get_children(parent, &kids, &cnt);
        if (err)
                return err;
+       sc->sc_cis.len = 0;
        if (cnt == 0) {
                free(kids, M_TEMP);
                sc->sc_cis_open++;
-               sc->sc_cis = NULL;
                return (0);
        }
        child = kids[0];
        free(kids, M_TEMP);
-       sc->sc_cis = malloc(sizeof(*sc->sc_cis), M_TEMP, M_ZERO | M_WAITOK);
-       err = cardbus_parse_cis(parent, child, cb, sc->sc_cis);
-       if (err) {
-               free(sc->sc_cis, M_TEMP);
-               sc->sc_cis = NULL;
+       err = cardbus_device_buffer_cis(parent, child);
+       if (err)
                return (err);
-       }
        sc->sc_cis_open++;
        return (0);
 }
@@ -153,8 +162,6 @@ cardbus_close(struct cdev *dev, int ffla
        struct cardbus_softc *sc;
 
        sc = dev->si_drv1;
-       free(sc->sc_cis, M_TEMP);
-       sc->sc_cis = NULL;
        sc->sc_cis_open = 0;
        return (0);
 }
@@ -173,8 +180,8 @@ cardbus_read(struct cdev *dev, struct ui
 
        sc = dev->si_drv1;
        /* EOF */
-       if (sc->sc_cis == NULL || uio->uio_offset > sc->sc_cis->len)
+       if (uio->uio_offset >= sc->sc_cis.len)
                return (0);
-       return (uiomove(sc->sc_cis->buffer + uio->uio_offset,
-         MIN(uio->uio_resid, sc->sc_cis->len - uio->uio_offset), uio));
+       return (uiomove(sc->sc_cis.buffer + uio->uio_offset,
+         MIN(uio->uio_resid, sc->sc_cis.len - uio->uio_offset), uio));
 }

Modified: head/sys/dev/cardbus/cardbusvar.h
==============================================================================
--- head/sys/dev/cardbus/cardbusvar.h   Sat Nov 15 04:43:54 2008        
(r184980)
+++ head/sys/dev/cardbus/cardbusvar.h   Sat Nov 15 05:22:06 2008        
(r184981)
@@ -34,7 +34,6 @@ struct cardbus_devinfo
        struct pci_devinfo pci;
        uint8_t        mprefetchable; /* bit mask of prefetchable BARs */
        uint8_t        mbelow1mb; /* bit mask of BARs which require below 1Mb */
-       uint8_t        ibelow1mb; /* bit mask of BARs which require below 1Mb */
        uint16_t        mfrid;          /* manufacturer id */
        uint16_t        prodid;         /* product id */
        u_int           funcid;         /* function id */
@@ -54,10 +53,10 @@ struct cis_buffer
 
 struct cardbus_softc 
 {
-       /* XXX need mutex XXX */
        device_t        sc_dev;
+       /* The following fields should in be in struct cardbus_devinfo */
        struct cdev     *sc_cisdev;
-       struct cis_buffer *sc_cis;
+       struct cis_buffer sc_cis;
        int             sc_cis_open;
 };
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to