Add a mutex to protect any accesses to maple queue. Signed-off-by: Jörn Engel --- drivers/mtd/maps/vmu_flash.c | 55 ++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 29 deletions(-) --- maple/drivers/mtd/maps/vmu_flash.c~cu8 2008-03-24 17:49:59.000000000 +0100 +++ maple/drivers/mtd/maps/vmu_flash.c 2008-03-24 18:26:56.000000000 +0100 @@ -22,6 +22,8 @@ static DECLARE_WAIT_QUEUE_HEAD(vmu_read); static int block_read; +static DEFINE_MUTEX(dev_mutex); + struct vmu_cache { char *buffer; /* Cache */ unsigned int block; /* Which block was cached */ @@ -133,26 +135,21 @@ static int maple_vmu_read_block(unsigned struct mdev_part *mpart; struct maple_device *mdev; int partition, error = 0; - __be32 *sendbuf; + __be32 sendbuf[2]; mpart = mtd->priv; mdev = mpart->mdev; partition = mpart->partition; card = mdev->private_data; + mutex_lock(&dev_mutex); mdev->mq->command = MAPLE_COMMAND_BREAD; mdev->mq->length = 2; - sendbuf = kzalloc(mdev->mq->length * 4, GFP_KERNEL); - if (!sendbuf) { - error = -ENOMEM; - goto fail_nosendbuf; - } - sendbuf[0] = cpu_to_be32(MAPLE_FUNC_MEMCARD); sendbuf[1] = cpu_to_be32(partition << 24 | num); - mdev->mq->sendbuf = sendbuf; + mdev->mq->sendbuf = &sendbuf; block_read = 0; card->blockread = kmalloc(card->blocklen, GFP_KERNEL); @@ -171,16 +168,12 @@ static int maple_vmu_read_block(unsigned } memcpy(buf, card->blockread, card->blocklen); - kfree(card->blockread); - kfree(sendbuf); - - return 0; + error = 0; fail_blockread: kfree(card->blockread); fail_bralloc: - kfree(sendbuf); -fail_nosendbuf: + mutex_unlock(&dev_mutex); return error; } @@ -191,7 +184,7 @@ static int maple_vmu_write_block(unsigne struct memcard *card; struct mdev_part *mpart; struct maple_device *mdev; - int partition, error, x, phaselen; + int partition, x, phaselen; __be32 *sendbuf; mpart = mtd->priv; @@ -199,16 +192,18 @@ static int maple_vmu_write_block(unsigne partition = mpart->partition; card = mdev->private_data; - phaselen = card->blocklen/card->writecnt; - mdev->mq->command = MAPLE_COMMAND_BWRITE; - mdev->mq->length = phaselen / 4 + 2; - sendbuf = kmalloc(mdev->mq->length * 4, GFP_KERNEL); if (!sendbuf) { - error = -ENOMEM; - goto fail_nosendbuf; + printk("Maple: VMU (%d, %d): write failed\n", mdev->port, + mdev->unit); + return -ENOMEM; } + phaselen = card->blocklen/card->writecnt; + mutex_lock(&dev_mutex); + mdev->mq->command = MAPLE_COMMAND_BWRITE; + mdev->mq->length = phaselen / 4 + 2; + sendbuf[0] = cpu_to_be32(MAPLE_FUNC_MEMCARD); for (x = 0; x < card->writecnt; x++) { @@ -217,14 +212,14 @@ static int maple_vmu_write_block(unsigne mdev->mq->sendbuf = sendbuf; maple_add_packet(mdev->mq); } + /* FIXME: we have to wait for the write to finish before releasing + * the mutex. Requires another callback. + */ + mutex_unlock(&dev_mutex); kfree(sendbuf); return card->blocklen; - -fail_nosendbuf: - printk("Maple: VMU (%d, %d): write failed\n", mdev->port, mdev->unit); - return error; } /* mtd function to simulate reading byte by byte */ @@ -593,15 +588,16 @@ static int vmu_connect(struct maple_devi mdev->private_data = card; - /* Now query the device to find out about blocks */ - mdev->mq->command = MAPLE_COMMAND_GETMINFO; - mdev->mq->length = 2; - sendbuf = kzalloc(mdev->mq->length * 4, GFP_KERNEL); if (!sendbuf) { error = -ENOMEM; goto fail_nosendbuf; } + /* Now query the device to find out about blocks */ + mutex_lock(&dev_mutex); + mdev->mq->command = MAPLE_COMMAND_GETMINFO; + mdev->mq->length = 2; + card->sendbuf = sendbuf; mdev->mq->sendbuf = sendbuf; @@ -611,6 +607,7 @@ static int vmu_connect(struct maple_devi maple_getcond_callback(mdev, vmu_queryblocks, 0, MAPLE_FUNC_MEMCARD); + mutex_unlock(&dev_mutex); return 0; fail_nosendbuf: