From owner-svn-src-head@FreeBSD.ORG Mon Nov 17 01:32:29 2008 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D8A31106564A; Mon, 17 Nov 2008 01:32:29 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 916978FC08; Mon, 17 Nov 2008 01:32:29 +0000 (UTC) (envelope-from imp@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id mAH1WTB0069615; Mon, 17 Nov 2008 01:32:29 GMT (envelope-from imp@svn.freebsd.org) Received: (from imp@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id mAH1WT2j069611; Mon, 17 Nov 2008 01:32:29 GMT (envelope-from imp@svn.freebsd.org) Message-Id: <200811170132.mAH1WT2j069611@svn.freebsd.org> From: Warner Losh Date: Mon, 17 Nov 2008 01:32:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r185015 - head/sys/dev/cardbus X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Nov 2008 01:32:30 -0000 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 *);