svn commit: r185015 - head/sys/dev/cardbus

Warner Losh imp at FreeBSD.org
Sun Nov 16 17:32:30 PST 2008


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 *);


More information about the svn-src-all mailing list