Author: imp
Date: Mon Nov 17 01:32:29 2008
New Revision: 185015
URL: http://svn.freebsd.org/changeset/base/185015

Log:
  Overhaul of CIS parsing, next step: keep a cached copy of the CIS,
  read before we configure the card, so we can implement
  /dev/cardbus*.cis.  Also, do this on a per-child basis, so we now have
  a different name than before.  I think i'll have to fix that for some
  legacy tools to keep working.
  
  I can now do a dumpcis on my running atheros card and have it still work!

Modified:
  head/sys/dev/cardbus/cardbus.c
  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.c
==============================================================================
--- head/sys/dev/cardbus/cardbus.c      Mon Nov 17 00:50:59 2008        
(r185014)
+++ head/sys/dev/cardbus/cardbus.c      Mon Nov 17 01:32:29 2008        
(r185015)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2003 M. Warner Losh.  All Rights Reserved.
+ * Copyright (c) 2003-2008 M. Warner Losh.  All Rights Reserved.
  * Copyright (c) 2000,2001 Jonathan Chen.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -99,20 +99,18 @@ cardbus_probe(device_t cbdev)
 static int
 cardbus_attach(device_t cbdev)
 {
-       struct cardbus_softc *sc = device_get_softc(cbdev);
+       struct cardbus_softc *sc;
 
+       sc = device_get_softc(cbdev);
        sc->sc_dev = cbdev;
-       cardbus_device_create(sc);
        return (0);
 }
 
 static int
 cardbus_detach(device_t cbdev)
 {
-       struct cardbus_softc *sc = device_get_softc(cbdev);
 
        cardbus_detach_card(cbdev);
-       cardbus_device_destroy(sc);
        return (0);
 }
 
@@ -165,7 +163,9 @@ cardbus_attach_card(device_t cbdev)
        int bus, domain, slot, func;
        int cardattached = 0;
        int cardbusfunchigh = 0;
+       struct cardbus_softc *sc;
 
+       sc = device_get_softc(cbdev);
        cardbus_detach_card(cbdev); /* detach existing cards */
        POWER_ENABLE_SOCKET(brdev, cbdev);
        domain = pcib_get_domain(cbdev);
@@ -192,6 +192,7 @@ cardbus_attach_card(device_t cbdev)
                dinfo->pci.cfg.dev = child;
                resource_list_init(&dinfo->pci.resources);
                device_set_ivars(child, dinfo);
+               cardbus_device_create(sc, dinfo, cbdev, child);
                if (cardbus_do_cis(cbdev, child) != 0)
                        DEVPRINTF((cbdev, "Warning: Bogus CIS ignored\n"));
                pci_cfg_save(dinfo->pci.cfg.dev, &dinfo->pci, 0);
@@ -235,6 +236,7 @@ cardbus_detach_card(device_t cbdev)
                if (status == DS_ATTACHED || status == DS_BUSY)
                        device_detach(devlist[tmp]);
                cardbus_release_all_resources(cbdev, dinfo);
+               cardbus_device_destroy(dinfo);
                device_delete_child(cbdev, devlist[tmp]);
                pci_freecfg((struct pci_devinfo *)dinfo);
        }

Modified: head/sys/dev/cardbus/cardbus_cis.c
==============================================================================
--- head/sys/dev/cardbus/cardbus_cis.c  Mon Nov 17 00:50:59 2008        
(r185014)
+++ head/sys/dev/cardbus/cardbus_cis.c  Mon Nov 17 01:32:29 2008        
(r185015)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2005-2008, M. Warner Losh
  * Copyright (c) 2000,2001 Jonathan Chen.
  * All rights reserved.
  *

Modified: head/sys/dev/cardbus/cardbus_device.c
==============================================================================
--- head/sys/dev/cardbus/cardbus_device.c       Mon Nov 17 00:50:59 2008        
(r185014)
+++ head/sys/dev/cardbus/cardbus_device.c       Mon Nov 17 01:32:29 2008        
(r185015)
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2005, M. Warner Losh
+ * Copyright (c) 2005-2008, M. Warner Losh
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,26 +63,6 @@ static struct cdevsw cardbus_cdevsw = {
        .d_name =       "cardbus"
 };
 
-int
-cardbus_device_create(struct cardbus_softc *sc)
-{
-       uint32_t minor;
-
-       minor = device_get_unit(sc->sc_dev) << 16;
-       sc->sc_cisdev = make_dev(&cardbus_cdevsw, minor, 0, 0, 0666,
-           "cardbus%u.cis", device_get_unit(sc->sc_dev));
-       sc->sc_cisdev->si_drv1 = sc;
-       return (0);
-}
-
-int
-cardbus_device_destroy(struct cardbus_softc *sc)
-{
-       if (sc->sc_cisdev)
-               destroy_dev(sc->sc_cisdev);
-       return (0);
-}
-
 static int
 cardbus_build_cis(device_t cbdev, device_t child, int id,
     int len, uint8_t *tupledata, uint32_t start, uint32_t *off,
@@ -115,7 +95,8 @@ cardbus_build_cis(device_t cbdev, device
 }
 
 static int
-cardbus_device_buffer_cis(device_t parent, device_t child)
+cardbus_device_buffer_cis(device_t parent, device_t child,
+    struct cis_buffer *cbp)
 {
        struct cardbus_softc *sc;
        struct tuple_callbacks cb[] = {
@@ -123,46 +104,44 @@ cardbus_device_buffer_cis(device_t paren
        };
 
        sc = device_get_softc(parent);
-       return (cardbus_parse_cis(parent, child, cb, &sc->sc_cis));
+       return (cardbus_parse_cis(parent, child, cb, cbp));
+}
+
+int
+cardbus_device_create(struct cardbus_softc *sc, struct cardbus_devinfo *devi,
+    device_t parent, device_t child)
+{
+       uint32_t minor;
+
+       cardbus_device_buffer_cis(parent, child, &devi->sc_cis);
+       minor = (device_get_unit(sc->sc_dev) << 8) + devi->pci.cfg.func;
+       devi->sc_cisdev = make_dev(&cardbus_cdevsw, minor, 0, 0, 0666,
+           "cardbus%d.%d.cis", device_get_unit(sc->sc_dev),
+           devi->pci.cfg.func);
+       /* XXX need cardbus%d.cis compat layer here ? */
+       devi->sc_cisdev->si_drv1 = devi;
+       return (0);
+}
+
+int
+cardbus_device_destroy(struct cardbus_devinfo *devi)
+{
+       if (devi->sc_cisdev)
+               destroy_dev(devi->sc_cisdev);
+       return (0);
 }
 
 static int
 cardbus_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
 {
-       device_t parent, child;
-       device_t *kids;
-       int cnt, err;
-       struct cardbus_softc *sc;
 
-       sc = dev->si_drv1;
-       if (sc->sc_cis_open)
-               return (EBUSY);
-       parent = sc->sc_dev;
-       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++;
-               return (0);
-       }
-       child = kids[0];
-       free(kids, M_TEMP);
-       err = cardbus_device_buffer_cis(parent, child);
-       if (err)
-               return (err);
-       sc->sc_cis_open++;
        return (0);
 }
 
 static int
 cardbus_close(struct cdev *dev, int fflags, int devtype, struct thread *td)
 {
-       struct cardbus_softc *sc;
 
-       sc = dev->si_drv1;
-       sc->sc_cis_open = 0;
        return (0);
 }
 
@@ -176,12 +155,12 @@ cardbus_ioctl(struct cdev *dev, u_long c
 static int
 cardbus_read(struct cdev *dev, struct uio *uio, int ioflag)
 {
-       struct cardbus_softc *sc;
+       struct cardbus_devinfo *devi;
 
-       sc = dev->si_drv1;
+       devi = dev->si_drv1;
        /* EOF */
-       if (uio->uio_offset >= sc->sc_cis.len)
+       if (uio->uio_offset >= devi->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(devi->sc_cis.buffer + uio->uio_offset,
+         MIN(uio->uio_resid, devi->sc_cis.len - uio->uio_offset), uio));
 }

Modified: head/sys/dev/cardbus/cardbusvar.h
==============================================================================
--- head/sys/dev/cardbus/cardbusvar.h   Mon Nov 17 00:50:59 2008        
(r185014)
+++ head/sys/dev/cardbus/cardbusvar.h   Mon Nov 17 01:32:29 2008        
(r185015)
@@ -1,4 +1,5 @@
 /*-
+ * Copyright (c) 2008, M. Warner Losh
  * Copyright (c) 2000,2001 Jonathan Chen.
  * All rights reserved.
  *
@@ -29,6 +30,21 @@
 /*
  * Structure definitions for the Cardbus Bus driver
  */
+
+/*
+ * Static copy of the CIS buffer.  Technically, you aren't supposed
+ * to do this.  In practice, however, it works well.
+ */
+struct cis_buffer
+{
+       size_t  len;                    /* Actual length of the CIS */
+       uint8_t buffer[2040];           /* small enough to be 2k */
+};
+
+/*
+ * Per child information for the PCI device.  Cardbus layers on some
+ * additional data.
+ */
 struct cardbus_devinfo
 {
        struct pci_devinfo pci;
@@ -43,36 +59,33 @@ struct cardbus_devinfo
                } lan;
        } funce;
        uint32_t        fepresent;      /* bit mask of funce values present */
+       struct cdev     *sc_cisdev;
+       struct cis_buffer sc_cis;
 };
 
-struct cis_buffer
-{
-       size_t  len;                    /* Actual length of the CIS */
-       uint8_t buffer[2040];           /* small enough to be 2k */
-};
-
+/*
+ * Per cardbus soft info.  Not sure why we even keep this around...
+ */
 struct cardbus_softc 
 {
        device_t        sc_dev;
-       /* The following fields should in be in struct cardbus_devinfo */
-       struct cdev     *sc_cisdev;
-       struct cis_buffer sc_cis;
-       int             sc_cis_open;
 };
 
+/*
+ * Per node callback structures.
+ */
 struct tuple_callbacks;
-
 typedef int (tuple_cb) (device_t cbdev, device_t child, int id, int len,
                 uint8_t *tupledata, uint32_t start, uint32_t *off,
                 struct tuple_callbacks *info, void *);
-
 struct tuple_callbacks {
        int     id;
        char    *name;
        tuple_cb *func;
 };
 
-int    cardbus_device_create(struct cardbus_softc *);
-int    cardbus_device_destroy(struct cardbus_softc *);
+int    cardbus_device_create(struct cardbus_softc *sc,
+           struct cardbus_devinfo *devi, device_t parent, device_t child);
+int    cardbus_device_destroy(struct cardbus_devinfo *devi);
 int    cardbus_parse_cis(device_t cbdev, device_t child,
            struct tuple_callbacks *callbacks, void *);
_______________________________________________
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