From owner-freebsd-mobile@FreeBSD.ORG Sat Feb 3 02:19:56 2007 Return-Path: X-Original-To: freebsd-mobile@freebsd.org Delivered-To: freebsd-mobile@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 9E38A16A403 for ; Sat, 3 Feb 2007 02:19:56 +0000 (UTC) (envelope-from a.bittau@cs.ucl.ac.uk) Received: from darkircop.org (tapir.cs.ucl.ac.uk [128.16.66.93]) by mx1.freebsd.org (Postfix) with ESMTP id E352113C49D for ; Sat, 3 Feb 2007 02:19:55 +0000 (UTC) (envelope-from a.bittau@cs.ucl.ac.uk) Received: by darkircop.org (Postfix, from userid 0) id D29136D750; Sat, 3 Feb 2007 02:19:30 +0000 (GMT) Date: Sat, 3 Feb 2007 02:19:30 +0000 From: Andrea Bittau To: freebsd-mobile@freebsd.org Message-ID: <20070203021930.GA5626@shorty.sorbonet.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-Echelon: Bush Bomb War KGB Cc: mail@sashi.de Subject: SD card reader driver [IBM x60s - Ricoh] and MMC detach patch X-BeenThere: freebsd-mobile@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Mobile computing with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 03 Feb 2007 02:19:56 -0000 Here is a [usable?] SD card reader driver that uses the freebsd mmc stuff: http://darkircop.org/sdh.tgz I tested it on an IBM/Lenovo Thinkpad x60s. It has this controller: sdh0@pci21:0:2: class=0x080500 card=0x201d17aa chip=0x08221180 rev=0x18 hdr=0x00 vendor = 'Ricoh Company, Ltd.' device = 'SD Bus Host Adapter' class = base peripheral I'm running 7-current. The driver can do 1MB in ~30 seconds (with DMA, transferring single 512 blocks). It's not great, but at least it's a starting point. It should work fine, although doing stuff like pulling the card out half way through a transfer will most likely mess things up. I also have a patch that will allow mmc and mmcsd to be compiled as modules, and to be detached. To use my driver, you need to apply that patch [mmc.diff]. I attach it to this e-mail to ease review. --- Index: conf/files =================================================================== RCS file: /home/ncvs/src/sys/conf/files,v retrieving revision 1.1171 diff -u -p -r1.1171 files --- conf/files 5 Jan 2007 01:46:26 -0000 1.1171 +++ conf/files 3 Feb 2007 01:49:30 -0000 @@ -754,8 +754,8 @@ dev/mlx/mlx_disk.c optional mlx dev/mlx/mlx_pci.c optional mlx pci dev/mly/mly.c optional mly dev/mmc/mmc.c optional mmc -dev/mmc/mmcbr_if.m optional mmc -dev/mmc/mmcbus_if.m optional mmc +dev/mmc/mmcbr_if.m standard +dev/mmc/mmcbus_if.m standard dev/mmc/mmcsd.c optional mmcsd dev/mpt/mpt.c optional mpt dev/mpt/mpt_cam.c optional mpt Index: conf/kmod.mk =================================================================== RCS file: /home/ncvs/src/sys/conf/kmod.mk,v retrieving revision 1.213 diff -u -p -r1.213 kmod.mk --- conf/kmod.mk 20 Oct 2006 07:31:15 -0000 1.213 +++ conf/kmod.mk 3 Feb 2007 01:49:30 -0000 @@ -318,7 +318,7 @@ ${_src}: MFILES?= dev/acpica/acpi_if.m dev/ata/ata_if.m dev/eisa/eisa_if.m \ dev/iicbus/iicbb_if.m dev/iicbus/iicbus_if.m \ - dev/mmc/mmcbr_if.m mmc/mmcbus_if.m \ + dev/mmc/mmcbr_if.m dev/mmc/mmcbus_if.m \ dev/mii/miibus_if.m dev/ofw/ofw_bus_if.m \ dev/pccard/card_if.m dev/pccard/power_if.m dev/pci/pci_if.m \ dev/pci/pcib_if.m dev/ppbus/ppbus_if.m dev/smbus/smbus_if.m \ Index: dev/mmc/mmc.c =================================================================== RCS file: /home/ncvs/src/sys/dev/mmc/mmc.c,v retrieving revision 1.1 diff -u -p -r1.1 mmc.c --- dev/mmc/mmc.c 20 Oct 2006 06:39:59 -0000 1.1 +++ dev/mmc/mmc.c 3 Feb 2007 01:49:37 -0000 @@ -117,7 +117,26 @@ mmc_attach(device_t dev) static int mmc_detach(device_t dev) { - return (EBUSY); /* XXX */ + struct mmc_softc *sc = device_get_softc(dev); + device_t *kids; + int i, nkid; + + /* kill children [ph33r]. -sorbo */ + if (device_get_children(sc->dev, &kids, &nkid) != 0) + return 0; + for (i = 0; i < nkid; i++) { + device_t kid = kids[i]; + void *ivar = device_get_ivars(kid); + + device_detach(kid); + device_delete_child(sc->dev, kid); + free(ivar, M_DEVBUF); + } + free(kids, M_TEMP); + + MMC_LOCK_DESTROY(sc); + + return 0; } static int @@ -553,6 +572,8 @@ mmc_discover_cards(struct mmc_softc *sc) while (1) { ivar = malloc(sizeof(struct mmc_ivars), M_DEVBUF, M_WAITOK); + if (!ivar) + return; err = mmc_all_send_cid(sc, ivar->raw_cid); if (err == MMC_ERR_TIMEOUT) break; @@ -571,10 +592,11 @@ mmc_discover_cards(struct mmc_softc *sc) printf("SD CARD: %lld bytes\n", ivar->csd.capacity); child = device_add_child(sc->dev, NULL, -1); device_set_ivars(child, ivar); - break; + return; } panic("Write MMC card code here"); } + free(ivar, M_DEVBUF); } static void @@ -743,3 +765,4 @@ static devclass_t mmc_devclass; DRIVER_MODULE(mmc, at91_mci, mmc_driver, mmc_devclass, 0, 0); +DRIVER_MODULE(mmc, sdh, mmc_driver, mmc_devclass, 0, 0); Index: dev/mmc/mmcsd.c =================================================================== RCS file: /home/ncvs/src/sys/dev/mmc/mmcsd.c,v retrieving revision 1.1 diff -u -p -r1.1 mmcsd.c --- dev/mmc/mmcsd.c 20 Oct 2006 06:39:59 -0000 1.1 +++ dev/mmc/mmcsd.c 3 Feb 2007 01:49:37 -0000 @@ -50,6 +50,7 @@ struct mmcsd_softc { struct disk *disk; struct proc *p; struct bio_queue_head bio_queue; + int running; }; #define MULTI_BLOCK_READ_BROKEN @@ -104,6 +105,8 @@ mmcsd_attach(device_t dev) sc->disk->d_unit = device_get_unit(dev); disk_create(sc->disk, DISK_VERSION); bioq_init(&sc->bio_queue); + + sc->running = 1; kthread_create(&mmcsd_task, sc, &sc->p, 0, 0, "task: mmc/sd card"); return (0); @@ -112,7 +115,27 @@ mmcsd_attach(device_t dev) static int mmcsd_detach(device_t dev) { - return (EBUSY); /* XXX */ + struct mmcsd_softc *sc = device_get_softc(dev); + + /* kill thread */ + MMCSD_LOCK(sc); + sc->running = 0; + wakeup(sc); + MMCSD_UNLOCK(sc); + + /* wait for thread to finish. XXX probably want timeout. -sorbo */ + MMCSD_LOCK(sc); + while (sc->running != -1) + msleep(sc, &sc->sc_mtx, PRIBIO, "detach", 0); + MMCSD_UNLOCK(sc); + + /* kill disk */ + disk_destroy(sc->disk); + /* XXX destroy anything in queue */ + + MMCSD_LOCK_DESTROY(sc); + + return 0; } static int @@ -153,15 +176,18 @@ mmcsd_task(void *arg) device_t dev; dev = sc->dev; - for (;;) { + while (sc->running) { MMCSD_LOCK(sc); do { bp = bioq_first(&sc->bio_queue); if (bp == NULL) msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0); - } while (bp == NULL); - bioq_remove(&sc->bio_queue, bp); + } while (bp == NULL && sc->running); + if (bp) + bioq_remove(&sc->bio_queue, bp); MMCSD_UNLOCK(sc); + if (!sc->running) + break; MMCBUS_ACQUIRE_BUS(device_get_parent(dev), dev); // printf("mmc_task: request %p for block %lld\n", bp, bp->bio_pblkno); sz = sc->disk->d_sectorsize; @@ -224,6 +250,14 @@ mmcsd_task(void *arg) MMCBUS_RELEASE_BUS(device_get_parent(dev), dev); biodone(bp); } + + /* tell parent we're done */ + MMCSD_LOCK(sc); + sc->running = -1; + wakeup(sc); + MMCSD_UNLOCK(sc); + + kthread_exit(0); } static device_method_t mmcsd_methods[] = { Index: modules/Makefile =================================================================== RCS file: /home/ncvs/src/sys/modules/Makefile,v retrieving revision 1.517 diff -u -p -r1.517 Makefile --- modules/Makefile 18 Dec 2006 18:57:41 -0000 1.517 +++ modules/Makefile 3 Feb 2007 01:49:42 -0000 @@ -158,6 +158,8 @@ SUBDIR= ${_3dfx} \ mii \ mlx \ ${_mly} \ + mmc \ + mmcsd \ mpt \ mqueue \ msdosfs \