SD card reader driver [IBM x60s - Ricoh] and MMC detach patch
Andrea Bittau
a.bittau at cs.ucl.ac.uk
Sat Feb 3 02:19:56 UTC 2007
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 at 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 \
More information about the freebsd-mobile
mailing list