Module Name: src Committed By: bouyer Date: Wed Oct 28 09:03:42 UTC 2009
Modified Files: src/distrib/sets/lists/man [netbsd-5]: mi src/share/man/man4 [netbsd-5]: Makefile src/sys/arch/amd64/conf [netbsd-5]: GENERIC src/sys/arch/i386/conf [netbsd-5]: ALL GENERIC src/sys/dev/pci [netbsd-5]: files.pci pcidevs Added Files: src/share/man/man4 [netbsd-5]: sdhc.4 src/sys/dev/pci [netbsd-5]: sdhc_pci.c Log Message: Pull up the following revisions, requested by sborrill in ticket #1114: share/man/man4/sdhc.4 1.1-1.2 sys/dev/pci/sdhc_pci.c 1.1-1.3 distrib/sets/lists/man/mi patch share/man/man4/Makefile patch sys/arch/amd64/conf/GENERIC patch sys/arch/i386/conf/ALL patch sys/arch/i386/conf/GENERIC patch sys/dev/pci/files.pci patch sys/dev/pci/pcidevs patch sys/dev/pci/pcidevs.h regen sys/dev/pci/pcidevs_data.h regen Add sdhc(4), a driver for SD controllers following the SD Host Controller Standard Simplified Specification. To generate a diff of this commit: cvs rdiff -u -r1.1109.2.12 -r1.1109.2.13 src/distrib/sets/lists/man/mi cvs rdiff -u -r1.482.2.7 -r1.482.2.8 src/share/man/man4/Makefile cvs rdiff -u -r0 -r1.2.2.2 src/share/man/man4/sdhc.4 cvs rdiff -u -r1.231.4.6 -r1.231.4.7 src/sys/arch/amd64/conf/GENERIC cvs rdiff -u -r1.183.4.6 -r1.183.4.7 src/sys/arch/i386/conf/ALL cvs rdiff -u -r1.915.2.9 -r1.915.2.10 src/sys/arch/i386/conf/GENERIC cvs rdiff -u -r1.308.2.5 -r1.308.2.6 src/sys/dev/pci/files.pci cvs rdiff -u -r1.962.4.5 -r1.962.4.6 src/sys/dev/pci/pcidevs cvs rdiff -u -r0 -r1.3.2.2 src/sys/dev/pci/sdhc_pci.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/man/mi diff -u src/distrib/sets/lists/man/mi:1.1109.2.12 src/distrib/sets/lists/man/mi:1.1109.2.13 --- src/distrib/sets/lists/man/mi:1.1109.2.12 Sun Oct 18 16:50:13 2009 +++ src/distrib/sets/lists/man/mi Wed Oct 28 09:03:41 2009 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1109.2.12 2009/10/18 16:50:13 bouyer Exp $ +# $NetBSD: mi,v 1.1109.2.13 2009/10/28 09:03:41 bouyer Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -1352,6 +1352,7 @@ ./usr/share/man/cat4/scsi.0 man-sys-catman .cat ./usr/share/man/cat4/scsibus.0 man-sys-catman .cat ./usr/share/man/cat4/sd.0 man-sys-catman .cat +./usr/share/man/cat4/sdhc.0 man-sys-catman .cat ./usr/share/man/cat4/sdmmc.0 man-sys-catman .cat ./usr/share/man/cat4/se.0 man-sys-catman .cat ./usr/share/man/cat4/sea.0 man-sys-catman .cat @@ -3829,6 +3830,7 @@ ./usr/share/man/html4/scsi.html man-sys-htmlman html ./usr/share/man/html4/scsibus.html man-sys-htmlman html ./usr/share/man/html4/sd.html man-sys-htmlman html +./usr/share/man/html4/sdhc.html man-sys-htmlman html ./usr/share/man/html4/sdmmc.html man-sys-htmlman html ./usr/share/man/html4/se.html man-sys-htmlman html ./usr/share/man/html4/sea.html man-sys-htmlman html @@ -6218,6 +6220,7 @@ ./usr/share/man/man4/scsi.4 man-sys-man .man ./usr/share/man/man4/scsibus.4 man-sys-man .man ./usr/share/man/man4/sd.4 man-sys-man .man +./usr/share/man/man4/sdhc.4 man-sys-man .man ./usr/share/man/man4/sdmmc.4 man-sys-man .man ./usr/share/man/man4/se.4 man-sys-man .man ./usr/share/man/man4/sea.4 man-sys-man .man Index: src/share/man/man4/Makefile diff -u src/share/man/man4/Makefile:1.482.2.7 src/share/man/man4/Makefile:1.482.2.8 --- src/share/man/man4/Makefile:1.482.2.7 Thu Oct 8 09:47:08 2009 +++ src/share/man/man4/Makefile Wed Oct 28 09:03:42 2009 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.482.2.7 2009/10/08 09:47:08 sborrill Exp $ +# $NetBSD: Makefile,v 1.482.2.8 2009/10/28 09:03:42 bouyer Exp $ # @(#)Makefile 8.1 (Berkeley) 6/18/93 MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \ @@ -46,7 +46,8 @@ qe.4 qec.4 qsphy.4 \ raid.4 ral.4 ray.4 rcons.4 re.4 rgephy.4 rlphy.4 rnd.4 route.4 \ rs5c372rtc.4 rtk.4 rtw.4 rum.4 \ - satalink.4 sbus.4 scc.4 scsi.4 sd.4 sdmmc.4 se.4 seeprom.4 sem.4 \ + satalink.4 sbus.4 scc.4 scsi.4 sd.4 sdhc.4 sdmmc.4 se.4 seeprom.4 \ + sem.4 \ ses.4 sf.4 sfb.4 sgsmix.4 shb.4 \ shpcic.4 siisata.4 siop.4 sip.4 siside.4 sk.4 sl.4 slide.4 \ sm.4 sn.4 sony.4 spc.4 speaker.4 spif.4 sqphy.4 ss.4 \ Index: src/sys/arch/amd64/conf/GENERIC diff -u src/sys/arch/amd64/conf/GENERIC:1.231.4.6 src/sys/arch/amd64/conf/GENERIC:1.231.4.7 --- src/sys/arch/amd64/conf/GENERIC:1.231.4.6 Thu Oct 8 09:47:08 2009 +++ src/sys/arch/amd64/conf/GENERIC Wed Oct 28 09:03:42 2009 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.231.4.6 2009/10/08 09:47:08 sborrill Exp $ +# $NetBSD: GENERIC,v 1.231.4.7 2009/10/28 09:03:42 bouyer Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.231.4.6 $" +#ident "GENERIC-$Revision: 1.231.4.7 $" maxusers 64 # estimated number of users @@ -908,6 +908,10 @@ # SD/MMC/SDIO Controller and Device support +# SD/MMC controller +sdhc* at pci? # SD Host Controller +sdmmc* at sdhc? # SD/MMC bus + ld* at sdmmc? # Audio Devices Index: src/sys/arch/i386/conf/ALL diff -u src/sys/arch/i386/conf/ALL:1.183.4.6 src/sys/arch/i386/conf/ALL:1.183.4.7 --- src/sys/arch/i386/conf/ALL:1.183.4.6 Thu Oct 8 09:47:08 2009 +++ src/sys/arch/i386/conf/ALL Wed Oct 28 09:03:42 2009 @@ -1,4 +1,4 @@ -# $NetBSD: ALL,v 1.183.4.6 2009/10/08 09:47:08 sborrill Exp $ +# $NetBSD: ALL,v 1.183.4.7 2009/10/28 09:03:42 bouyer Exp $ # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp # # ALL machine description file @@ -17,7 +17,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "ALL-$Revision: 1.183.4.6 $" +#ident "ALL-$Revision: 1.183.4.7 $" maxusers 32 # estimated number of users @@ -1259,6 +1259,10 @@ # SD/MMC/SDIO Controller and Device support +# SD/MMC controller +sdhc* at pci? # SD Host Controller +sdmmc* at sdhc? # SD/MMC bus + ld* at sdmmc? # Audio Devices Index: src/sys/arch/i386/conf/GENERIC diff -u src/sys/arch/i386/conf/GENERIC:1.915.2.9 src/sys/arch/i386/conf/GENERIC:1.915.2.10 --- src/sys/arch/i386/conf/GENERIC:1.915.2.9 Thu Oct 8 09:47:09 2009 +++ src/sys/arch/i386/conf/GENERIC Wed Oct 28 09:03:42 2009 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.915.2.9 2009/10/08 09:47:09 sborrill Exp $ +# $NetBSD: GENERIC,v 1.915.2.10 2009/10/28 09:03:42 bouyer Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.915.2.9 $" +#ident "GENERIC-$Revision: 1.915.2.10 $" maxusers 64 # estimated number of users @@ -1255,6 +1255,10 @@ # SD/MMC/SDIO Controller and Device support +# SD/MMC controller +sdhc* at pci? # SD Host Controller +sdmmc* at sdhc? # SD/MMC bus + ld* at sdmmc? # Audio Devices Index: src/sys/dev/pci/files.pci diff -u src/sys/dev/pci/files.pci:1.308.2.5 src/sys/dev/pci/files.pci:1.308.2.6 --- src/sys/dev/pci/files.pci:1.308.2.5 Mon Sep 28 00:27:13 2009 +++ src/sys/dev/pci/files.pci Wed Oct 28 09:03:42 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.pci,v 1.308.2.5 2009/09/28 00:27:13 snj Exp $ +# $NetBSD: files.pci,v 1.308.2.6 2009/10/28 09:03:42 bouyer Exp $ # # Config file and device description for machine-independent PCI code. # Included by ports that need it. Requires that the SCSI files be @@ -909,6 +909,10 @@ attach msk at mskc file dev/pci/if_msk.c mskc | msk +# SD Host Controller +attach sdhc at pci with sdhc_pci +file dev/pci/sdhc_pci.c sdhc_pci + # # Direct Rendering Manager # Index: src/sys/dev/pci/pcidevs diff -u src/sys/dev/pci/pcidevs:1.962.4.5 src/sys/dev/pci/pcidevs:1.962.4.6 --- src/sys/dev/pci/pcidevs:1.962.4.5 Sat Sep 26 20:05:43 2009 +++ src/sys/dev/pci/pcidevs Wed Oct 28 09:03:42 2009 @@ -1,4 +1,4 @@ -$NetBSD: pcidevs,v 1.962.4.5 2009/09/26 20:05:43 snj Exp $ +$NetBSD: pcidevs,v 1.962.4.6 2009/10/28 09:03:42 bouyer Exp $ /* * Copyright (c) 1995, 1996 Christopher G. Demetriou @@ -1811,6 +1811,7 @@ /* ENE Technology products */ product ENE MCR510 0x0510 MCR510 PCI Memory Card Reader Controller +product ENE CB712 0x0550 CB712/714/810 PCI SD Card Reader Controller product ENE CB1211 0x1211 CB1211 CardBus Controller product ENE CB1225 0x1225 CB1225 CardBus Controller product ENE CB1410 0x1410 CB1410 CardBus Controller @@ -3803,6 +3804,7 @@ product TI PCI72111CB 0x8031 PCI7x21/7x11 Cardbus Controller product TI PCI72111FW 0x8032 PCI7x21/7x11 IEEE 1394 Host Controller product TI PCI72111FM 0x8033 PCI7x21/7x11 Integrated FlashMedia Controller +product TI PCI72111SD 0x8034 PCI7x21/7x11 SD Card Controller product TI PCI6515A 0x8036 PCI6515A Cardbus Controller product TI PCI6515ASM 0x8038 PCI6515A Cardbus Controller (Smart Card mode) product TI ACX100A 0x8400 ACX100A 802.11b Added files: Index: src/share/man/man4/sdhc.4 diff -u /dev/null src/share/man/man4/sdhc.4:1.2.2.2 --- /dev/null Wed Oct 28 09:03:43 2009 +++ src/share/man/man4/sdhc.4 Wed Oct 28 09:03:42 2009 @@ -0,0 +1,40 @@ +.\" $NetBSD: sdhc.4,v 1.2.2.2 2009/10/28 09:03:42 bouyer Exp $ +.\" $OpenBSD: sdhc.4,v 1.4 2009/02/14 18:47:45 deraadt Exp $ +.\" +.\" Theo de Raadt, 2006. Public Domain. +.\" +.Dd April 21, 2009 +.Dt SDHC 4 +.Os +.Sh NAME +.Nm sdhc +.Nd SD Host Controller +.Sh SYNOPSIS +.Cd "sdhc* at pci?" +.Cd "sdmmc* at sdhc?" +.Sh DESCRIPTION +The +.Nm +driver provides support for SD controllers following the +SD Host Controller Standard Simplified Specification. +.Pp +The +.Xr sdmmc 4 +subsystem performs SD/MMC transactions to communicate with +whatever MMC, SD, SDHC, or SDIO devices are inserted into the SD slot. +.Sh SEE ALSO +.Xr intro 4 , +.Xr sdmmc 4 +.Sh HISTORY +The +.Nm +driver was written by +.An Uwe Stuehler +.Aq u...@openbsd.org +for +.Ox +and ported to +.Nx +by +.An NONAKA Kimihiro +.Aq non...@netbsd.org . Index: src/sys/dev/pci/sdhc_pci.c diff -u /dev/null src/sys/dev/pci/sdhc_pci.c:1.3.2.2 --- /dev/null Wed Oct 28 09:03:43 2009 +++ src/sys/dev/pci/sdhc_pci.c Wed Oct 28 09:03:42 2009 @@ -0,0 +1,294 @@ +/* $NetBSD: sdhc_pci.c,v 1.3.2.2 2009/10/28 09:03:42 bouyer Exp $ */ +/* $OpenBSD: sdhc_pci.c,v 1.7 2007/10/30 18:13:45 chl Exp $ */ + +/* + * Copyright (c) 2006 Uwe Stuehler <u...@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: sdhc_pci.c,v 1.3.2.2 2009/10/28 09:03:42 bouyer Exp $"); + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/malloc.h> +#include <sys/pmf.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> + +#include <dev/sdmmc/sdhcreg.h> +#include <dev/sdmmc/sdhcvar.h> +#include <dev/sdmmc/sdmmcvar.h> + +/* PCI base address registers */ +#define SDHC_PCI_BAR_START PCI_MAPREG_START +#define SDHC_PCI_BAR_END PCI_MAPREG_END + +/* PCI interface classes */ +#define SDHC_PCI_INTERFACE_NO_DMA 0x00 +#define SDHC_PCI_INTERFACE_DMA 0x01 +#define SDHC_PCI_INTERFACE_VENDOR 0x02 + +/* + * 8-bit PCI configuration register that tells us how many slots there + * are and which BAR entry corresponds to the first slot. + */ +#define SDHC_PCI_CONF_SLOT_INFO 0x40 +#define SDHC_PCI_NUM_SLOTS(info) ((((info) >> 4) & 0x7) + 1) +#define SDHC_PCI_FIRST_BAR(info) ((info) & 0x7) + +struct sdhc_pci_softc { + struct sdhc_softc sc; + void *sc_ih; +}; + +static int sdhc_pci_match(device_t, cfdata_t, void *); +static void sdhc_pci_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(sdhc_pci, sizeof(struct sdhc_pci_softc), + sdhc_pci_match, sdhc_pci_attach, NULL, NULL); + +#ifdef SDHC_DEBUG +#define DPRINTF(s) printf s +#else +#define DPRINTF(s) /**/ +#endif + +static const struct sdhc_pci_quirk { + pci_vendor_id_t vendor; + pci_product_id_t product; + pci_vendor_id_t subvendor; + pci_product_id_t subproduct; + u_int function; + + uint32_t flags; +#define SDHC_PCI_QUIRK_FORCE_DMA (1U << 0) +#define SDHC_PCI_QUIRK_TI_HACK (1U << 1) +#define SDHC_PCI_QUIRK_NO_PWR0 (1U << 2) +} sdhc_pci_quirk_table[] = { + { + PCI_VENDOR_TI, + PCI_PRODUCT_TI_PCI72111SD, + 0xffff, + 0xffff, + 4, + SDHC_PCI_QUIRK_TI_HACK + }, + + { + PCI_VENDOR_ENE, + PCI_PRODUCT_ENE_CB712, + 0xffff, + 0xffff, + 0, + SDHC_PCI_QUIRK_NO_PWR0 + }, +}; + +static void sdhc_pci_quirk_ti_hack(struct pci_attach_args *); + +static uint32_t +sdhc_pci_lookup_quirk_flags(struct pci_attach_args *pa) +{ + const struct sdhc_pci_quirk *q; + pcireg_t id; + pci_vendor_id_t vendor; + pci_product_id_t product; + int i; + + for (i = 0; i < __arraycount(sdhc_pci_quirk_table); i++) { + q = &sdhc_pci_quirk_table[i]; + + if ((PCI_VENDOR(pa->pa_id) == q->vendor) + && (PCI_PRODUCT(pa->pa_id) == q->product)) { + if ((q->function != ~0) + && (pa->pa_function != q->function)) + continue; + + if ((q->subvendor == 0xffff) + && (q->subproduct == 0xffff)) + return q->flags; + + id = pci_conf_read(pa->pa_pc, pa->pa_tag, + PCI_SUBSYS_ID_REG); + vendor = PCI_VENDOR(id); + product = PCI_PRODUCT(id); + + if ((q->subvendor != 0xffff) + && (q->subproduct != 0xffff)) { + if ((vendor == q->subvendor) + && (product == q->subproduct)) + return q->flags; + } else if (q->subvendor != 0xffff) { + if (product == q->subproduct) + return q->flags; + } else { + if (vendor == q->subvendor) + return q->flags; + } + } + } + + return 0; +} + +static int +sdhc_pci_match(device_t parent, cfdata_t cf, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SYSTEM && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SYSTEM_SDHC) + return 1; + + return 0; +} + +static void +sdhc_pci_attach(device_t parent, device_t self, void *aux) +{ + struct sdhc_pci_softc *sc = device_private(self); + struct pci_attach_args *pa = (struct pci_attach_args *)aux; + pci_chipset_tag_t pc = pa->pa_pc; + pcitag_t tag = pa->pa_tag; + pci_intr_handle_t ih; + pcireg_t csr; + pcireg_t slotinfo; + char devinfo[256]; + char const *intrstr; + int nslots; + int reg; + int cnt; + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_size_t size; + uint32_t flags; + + sc->sc.sc_dev = self; + sc->sc.sc_dmat = pa->pa_dmat; + sc->sc.sc_host = NULL; + + pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); + aprint_normal(": %s (rev. 0x%02x)\n", devinfo, + PCI_REVISION(pa->pa_class)); + aprint_naive("\n"); + + /* Some controllers needs special treatment. */ + flags = sdhc_pci_lookup_quirk_flags(pa); + if (ISSET(flags, SDHC_PCI_QUIRK_TI_HACK)) + sdhc_pci_quirk_ti_hack(pa); + if (ISSET(flags, SDHC_PCI_QUIRK_FORCE_DMA)) + SET(sc->sc.sc_flags, SDHC_FLAG_FORCE_DMA); + if (ISSET(flags, SDHC_PCI_QUIRK_NO_PWR0)) + SET(sc->sc.sc_flags, SDHC_FLAG_NO_PWR0); + + /* + * Map and attach all hosts supported by the host controller. + */ + slotinfo = pci_conf_read(pc, tag, SDHC_PCI_CONF_SLOT_INFO); + nslots = SDHC_PCI_NUM_SLOTS(slotinfo); + + /* Allocate an array big enough to hold all the possible hosts */ + sc->sc.sc_host = malloc(sizeof(struct sdhc_host *) * nslots, + M_DEVBUF, M_NOWAIT | M_ZERO); + if (sc->sc.sc_host == NULL) { + aprint_error_dev(self, "couldn't alloc memory\n"); + goto err; + } + + /* Enable the device. */ + csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); + pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, + csr | PCI_COMMAND_MASTER_ENABLE); + + /* Map and establish the interrupt. */ + if (pci_intr_map(pa, &ih)) { + aprint_error_dev(self, "couldn't map interrupt\n"); + goto err; + } + + intrstr = pci_intr_string(pc, ih); + sc->sc_ih = pci_intr_establish(pc, ih, IPL_SDMMC, sdhc_intr, &sc->sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "couldn't establish interrupt\n"); + goto err; + } + aprint_normal_dev(self, "interrupting at %s\n", intrstr); + + /* Enable use of DMA if supported by the interface. */ + if ((PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA)) + SET(sc->sc.sc_flags, SDHC_FLAG_USE_DMA); + + /* XXX: handle 64-bit BARs */ + cnt = 0; + for (reg = SDHC_PCI_BAR_START + SDHC_PCI_FIRST_BAR(slotinfo) * + sizeof(uint32_t); + reg < SDHC_PCI_BAR_END && nslots > 0; + reg += sizeof(uint32_t), nslots--) { + if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_MEM, 0, + &iot, &ioh, NULL, &size)) { + continue; + } + + cnt++; + if (sdhc_host_found(&sc->sc, iot, ioh, size) != 0) { + /* XXX: sc->sc_host leak */ + aprint_error_dev(self, + "couldn't initialize host (0x%x)\n", reg); + } + } + if (cnt == 0) { + aprint_error_dev(self, "couldn't map register\n"); + goto err; + } + + if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume, + sdhc_shutdown)) { + aprint_error_dev(self, "couldn't establish powerhook\n"); + } + + return; + +err: + if (sc->sc.sc_host != NULL) + free(sc->sc.sc_host, M_DEVBUF); +} + +/* TI specific register */ +#define SDHC_PCI_GENERAL_CTL 0x4c +#define MMC_SD_DIS 0x02 + +static void +sdhc_pci_quirk_ti_hack(struct pci_attach_args *pa) +{ + pci_chipset_tag_t pc = pa->pa_pc; + pcitag_t tag; + pcireg_t id, reg; + + /* Look at func 3 for the flash device */ + tag = pci_make_tag(pc, pa->pa_bus, pa->pa_device, 3); + id = pci_conf_read(pc, tag, PCI_ID_REG); + if (PCI_PRODUCT(id) != PCI_PRODUCT_TI_PCI72111FM) + return; + + /* + * Disable MMC/SD on the flash media controller so the + * SD host takes over. + */ + reg = pci_conf_read(pc, tag, SDHC_PCI_GENERAL_CTL); + reg |= MMC_SD_DIS; + pci_conf_write(pc, tag, SDHC_PCI_GENERAL_CTL, reg); +}