0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/init.h>
0009 #include <linux/slab.h>
0010 #include <linux/sched.h>
0011 #include <linux/delay.h>
0012 #include <linux/maple.h>
0013 #include <linux/mtd/mtd.h>
0014 #include <linux/mtd/map.h>
0015
0016 struct vmu_cache {
0017 unsigned char *buffer;
0018 unsigned int block;
0019 unsigned long jiffies_atc;
0020 int valid;
0021 };
0022
0023 struct mdev_part {
0024 struct maple_device *mdev;
0025 int partition;
0026 };
0027
0028 struct vmupart {
0029 u16 user_blocks;
0030 u16 root_block;
0031 u16 numblocks;
0032 char *name;
0033 struct vmu_cache *pcache;
0034 };
0035
0036 struct memcard {
0037 u16 tempA;
0038 u16 tempB;
0039 u32 partitions;
0040 u32 blocklen;
0041 u32 writecnt;
0042 u32 readcnt;
0043 u32 removable;
0044 int partition;
0045 int read;
0046 unsigned char *blockread;
0047 struct vmupart *parts;
0048 struct mtd_info *mtd;
0049 };
0050
0051 struct vmu_block {
0052 unsigned int num;
0053 unsigned int ofs;
0054 };
0055
0056 static struct vmu_block *ofs_to_block(unsigned long src_ofs,
0057 struct mtd_info *mtd, int partition)
0058 {
0059 struct vmu_block *vblock;
0060 struct maple_device *mdev;
0061 struct memcard *card;
0062 struct mdev_part *mpart;
0063 int num;
0064
0065 mpart = mtd->priv;
0066 mdev = mpart->mdev;
0067 card = maple_get_drvdata(mdev);
0068
0069 if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
0070 goto failed;
0071
0072 num = src_ofs / card->blocklen;
0073 if (num > card->parts[partition].numblocks)
0074 goto failed;
0075
0076 vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
0077 if (!vblock)
0078 goto failed;
0079
0080 vblock->num = num;
0081 vblock->ofs = src_ofs % card->blocklen;
0082 return vblock;
0083
0084 failed:
0085 return NULL;
0086 }
0087
0088
0089 static void vmu_blockread(struct mapleq *mq)
0090 {
0091 struct maple_device *mdev;
0092 struct memcard *card;
0093
0094 mdev = mq->dev;
0095 card = maple_get_drvdata(mdev);
0096
0097
0098 if (unlikely(!card->blockread))
0099 return;
0100
0101 memcpy(card->blockread, mq->recvbuf->buf + 12,
0102 card->blocklen/card->readcnt);
0103
0104 }
0105
0106
0107
0108
0109 static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
0110 struct mtd_info *mtd)
0111 {
0112 struct memcard *card;
0113 struct mdev_part *mpart;
0114 struct maple_device *mdev;
0115 int partition, error = 0, x, wait;
0116 unsigned char *blockread = NULL;
0117 struct vmu_cache *pcache;
0118 __be32 sendbuf;
0119
0120 mpart = mtd->priv;
0121 mdev = mpart->mdev;
0122 partition = mpart->partition;
0123 card = maple_get_drvdata(mdev);
0124 pcache = card->parts[partition].pcache;
0125 pcache->valid = 0;
0126
0127
0128 if (!pcache->buffer) {
0129 pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
0130 if (!pcache->buffer) {
0131 dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
0132 " to lack of memory\n", mdev->port,
0133 mdev->unit);
0134 error = -ENOMEM;
0135 goto outB;
0136 }
0137 }
0138
0139
0140
0141
0142
0143
0144 for (x = 0; x < card->readcnt; x++) {
0145 sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
0146
0147 if (atomic_read(&mdev->busy) == 1) {
0148 wait_event_interruptible_timeout(mdev->maple_wait,
0149 atomic_read(&mdev->busy) == 0, HZ);
0150 if (atomic_read(&mdev->busy) == 1) {
0151 dev_notice(&mdev->dev, "VMU at (%d, %d)"
0152 " is busy\n", mdev->port, mdev->unit);
0153 error = -EAGAIN;
0154 goto outB;
0155 }
0156 }
0157
0158 atomic_set(&mdev->busy, 1);
0159 blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
0160 if (!blockread) {
0161 error = -ENOMEM;
0162 atomic_set(&mdev->busy, 0);
0163 goto outB;
0164 }
0165 card->blockread = blockread;
0166
0167 maple_getcond_callback(mdev, vmu_blockread, 0,
0168 MAPLE_FUNC_MEMCARD);
0169 error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
0170 MAPLE_COMMAND_BREAD, 2, &sendbuf);
0171
0172 wait = wait_event_interruptible_timeout(mdev->maple_wait,
0173 (atomic_read(&mdev->busy) == 0 ||
0174 atomic_read(&mdev->busy) == 2), HZ * 3);
0175
0176
0177
0178
0179
0180 if (error || atomic_read(&mdev->busy) == 2) {
0181 if (atomic_read(&mdev->busy) == 2)
0182 error = -ENXIO;
0183 atomic_set(&mdev->busy, 0);
0184 card->blockread = NULL;
0185 goto outA;
0186 }
0187 if (wait == 0 || wait == -ERESTARTSYS) {
0188 card->blockread = NULL;
0189 atomic_set(&mdev->busy, 0);
0190 error = -EIO;
0191 list_del_init(&(mdev->mq->list));
0192 kfree(mdev->mq->sendbuf);
0193 mdev->mq->sendbuf = NULL;
0194 if (wait == -ERESTARTSYS) {
0195 dev_warn(&mdev->dev, "VMU read on (%d, %d)"
0196 " interrupted on block 0x%X\n",
0197 mdev->port, mdev->unit, num);
0198 } else
0199 dev_notice(&mdev->dev, "VMU read on (%d, %d)"
0200 " timed out on block 0x%X\n",
0201 mdev->port, mdev->unit, num);
0202 goto outA;
0203 }
0204
0205 memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
0206 card->blocklen/card->readcnt);
0207
0208 memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
0209 card->blockread, card->blocklen/card->readcnt);
0210 card->blockread = NULL;
0211 pcache->block = num;
0212 pcache->jiffies_atc = jiffies;
0213 pcache->valid = 1;
0214 kfree(blockread);
0215 }
0216
0217 return error;
0218
0219 outA:
0220 kfree(blockread);
0221 outB:
0222 return error;
0223 }
0224
0225
0226 static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
0227 struct mtd_info *mtd)
0228 {
0229 struct memcard *card;
0230 struct mdev_part *mpart;
0231 struct maple_device *mdev;
0232 int partition, error, locking, x, phaselen, wait;
0233 __be32 *sendbuf;
0234
0235 mpart = mtd->priv;
0236 mdev = mpart->mdev;
0237 partition = mpart->partition;
0238 card = maple_get_drvdata(mdev);
0239
0240 phaselen = card->blocklen/card->writecnt;
0241
0242 sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
0243 if (!sendbuf) {
0244 error = -ENOMEM;
0245 goto fail_nosendbuf;
0246 }
0247 for (x = 0; x < card->writecnt; x++) {
0248 sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
0249 memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
0250
0251
0252 if (atomic_read(&mdev->busy) == 1) {
0253 wait_event_interruptible_timeout(mdev->maple_wait,
0254 atomic_read(&mdev->busy) == 0, HZ);
0255 if (atomic_read(&mdev->busy) == 1) {
0256 error = -EBUSY;
0257 dev_notice(&mdev->dev, "VMU write at (%d, %d)"
0258 "failed - device is busy\n",
0259 mdev->port, mdev->unit);
0260 goto fail_nolock;
0261 }
0262 }
0263 atomic_set(&mdev->busy, 1);
0264
0265 locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
0266 MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
0267 wait = wait_event_interruptible_timeout(mdev->maple_wait,
0268 atomic_read(&mdev->busy) == 0, HZ/10);
0269 if (locking) {
0270 error = -EIO;
0271 atomic_set(&mdev->busy, 0);
0272 goto fail_nolock;
0273 }
0274 if (atomic_read(&mdev->busy) == 2) {
0275 atomic_set(&mdev->busy, 0);
0276 } else if (wait == 0 || wait == -ERESTARTSYS) {
0277 error = -EIO;
0278 dev_warn(&mdev->dev, "Write at (%d, %d) of block"
0279 " 0x%X at phase %d failed: could not"
0280 " communicate with VMU", mdev->port,
0281 mdev->unit, num, x);
0282 atomic_set(&mdev->busy, 0);
0283 kfree(mdev->mq->sendbuf);
0284 mdev->mq->sendbuf = NULL;
0285 list_del_init(&(mdev->mq->list));
0286 goto fail_nolock;
0287 }
0288 }
0289 kfree(sendbuf);
0290
0291 return card->blocklen;
0292
0293 fail_nolock:
0294 kfree(sendbuf);
0295 fail_nosendbuf:
0296 dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
0297 mdev->unit);
0298 return error;
0299 }
0300
0301
0302 static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
0303 struct mtd_info *mtd)
0304 {
0305 struct vmu_block *vblock;
0306 struct memcard *card;
0307 struct mdev_part *mpart;
0308 struct maple_device *mdev;
0309 unsigned char *buf, ret;
0310 int partition, error;
0311
0312 mpart = mtd->priv;
0313 mdev = mpart->mdev;
0314 partition = mpart->partition;
0315 card = maple_get_drvdata(mdev);
0316 *retval = 0;
0317
0318 buf = kmalloc(card->blocklen, GFP_KERNEL);
0319 if (!buf) {
0320 *retval = 1;
0321 ret = -ENOMEM;
0322 goto finish;
0323 }
0324
0325 vblock = ofs_to_block(ofs, mtd, partition);
0326 if (!vblock) {
0327 *retval = 3;
0328 ret = -ENOMEM;
0329 goto out_buf;
0330 }
0331
0332 error = maple_vmu_read_block(vblock->num, buf, mtd);
0333 if (error) {
0334 ret = error;
0335 *retval = 2;
0336 goto out_vblock;
0337 }
0338
0339 ret = buf[vblock->ofs];
0340
0341 out_vblock:
0342 kfree(vblock);
0343 out_buf:
0344 kfree(buf);
0345 finish:
0346 return ret;
0347 }
0348
0349
0350 static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
0351 size_t *retlen, u_char *buf)
0352 {
0353 struct maple_device *mdev;
0354 struct memcard *card;
0355 struct mdev_part *mpart;
0356 struct vmu_cache *pcache;
0357 struct vmu_block *vblock;
0358 int index = 0, retval, partition, leftover, numblocks;
0359 unsigned char cx;
0360
0361 mpart = mtd->priv;
0362 mdev = mpart->mdev;
0363 partition = mpart->partition;
0364 card = maple_get_drvdata(mdev);
0365
0366 numblocks = card->parts[partition].numblocks;
0367 if (from + len > numblocks * card->blocklen)
0368 len = numblocks * card->blocklen - from;
0369 if (len == 0)
0370 return -EIO;
0371
0372 pcache = card->parts[partition].pcache;
0373 do {
0374 vblock = ofs_to_block(from + index, mtd, partition);
0375 if (!vblock)
0376 return -ENOMEM;
0377
0378 if (pcache->valid &&
0379 time_before(jiffies, pcache->jiffies_atc + HZ) &&
0380 (pcache->block == vblock->num)) {
0381
0382 leftover = card->blocklen - vblock->ofs;
0383 if (vblock->ofs + len - index < card->blocklen) {
0384
0385 memcpy(buf + index,
0386 pcache->buffer + vblock->ofs,
0387 len - index);
0388 index = len;
0389 } else {
0390
0391 memcpy(buf + index, pcache->buffer +
0392 vblock->ofs, leftover);
0393 index += leftover;
0394 }
0395 } else {
0396
0397
0398
0399
0400 cx = vmu_flash_read_char(from + index, &retval, mtd);
0401 if (retval) {
0402 *retlen = index;
0403 kfree(vblock);
0404 return cx;
0405 }
0406 memset(buf + index, cx, 1);
0407 index++;
0408 }
0409 kfree(vblock);
0410 } while (len > index);
0411 *retlen = index;
0412
0413 return 0;
0414 }
0415
0416 static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
0417 size_t *retlen, const u_char *buf)
0418 {
0419 struct maple_device *mdev;
0420 struct memcard *card;
0421 struct mdev_part *mpart;
0422 int index = 0, partition, error = 0, numblocks;
0423 struct vmu_cache *pcache;
0424 struct vmu_block *vblock;
0425 unsigned char *buffer;
0426
0427 mpart = mtd->priv;
0428 mdev = mpart->mdev;
0429 partition = mpart->partition;
0430 card = maple_get_drvdata(mdev);
0431
0432 numblocks = card->parts[partition].numblocks;
0433 if (to + len > numblocks * card->blocklen)
0434 len = numblocks * card->blocklen - to;
0435 if (len == 0) {
0436 error = -EIO;
0437 goto failed;
0438 }
0439
0440 vblock = ofs_to_block(to, mtd, partition);
0441 if (!vblock) {
0442 error = -ENOMEM;
0443 goto failed;
0444 }
0445
0446 buffer = kmalloc(card->blocklen, GFP_KERNEL);
0447 if (!buffer) {
0448 error = -ENOMEM;
0449 goto fail_buffer;
0450 }
0451
0452 do {
0453
0454 error = maple_vmu_read_block(vblock->num, buffer, mtd);
0455 if (error)
0456 goto fail_io;
0457
0458 do {
0459 buffer[vblock->ofs] = buf[index];
0460 vblock->ofs++;
0461 index++;
0462 if (index >= len)
0463 break;
0464 } while (vblock->ofs < card->blocklen);
0465
0466
0467 error = maple_vmu_write_block(vblock->num, buffer, mtd);
0468
0469 pcache = card->parts[partition].pcache;
0470 pcache->valid = 0;
0471
0472 if (error != card->blocklen)
0473 goto fail_io;
0474
0475 vblock->num++;
0476 vblock->ofs = 0;
0477 } while (len > index);
0478
0479 kfree(buffer);
0480 *retlen = index;
0481 kfree(vblock);
0482 return 0;
0483
0484 fail_io:
0485 kfree(buffer);
0486 fail_buffer:
0487 kfree(vblock);
0488 failed:
0489 dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
0490 return error;
0491 }
0492
0493 static void vmu_flash_sync(struct mtd_info *mtd)
0494 {
0495
0496 }
0497
0498
0499 static void vmu_queryblocks(struct mapleq *mq)
0500 {
0501 struct maple_device *mdev;
0502 unsigned short *res;
0503 struct memcard *card;
0504 __be32 partnum;
0505 struct vmu_cache *pcache;
0506 struct mdev_part *mpart;
0507 struct mtd_info *mtd_cur;
0508 struct vmupart *part_cur;
0509 int error;
0510
0511 mdev = mq->dev;
0512 card = maple_get_drvdata(mdev);
0513 res = (unsigned short *) (mq->recvbuf->buf);
0514 card->tempA = res[12];
0515 card->tempB = res[6];
0516
0517 dev_info(&mdev->dev, "VMU device at partition %d has %d user "
0518 "blocks with a root block at %d\n", card->partition,
0519 card->tempA, card->tempB);
0520
0521 part_cur = &card->parts[card->partition];
0522 part_cur->user_blocks = card->tempA;
0523 part_cur->root_block = card->tempB;
0524 part_cur->numblocks = card->tempB + 1;
0525 part_cur->name = kmalloc(12, GFP_KERNEL);
0526 if (!part_cur->name)
0527 goto fail_name;
0528
0529 sprintf(part_cur->name, "vmu%d.%d.%d",
0530 mdev->port, mdev->unit, card->partition);
0531 mtd_cur = &card->mtd[card->partition];
0532 mtd_cur->name = part_cur->name;
0533 mtd_cur->type = 8;
0534 mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
0535 mtd_cur->size = part_cur->numblocks * card->blocklen;
0536 mtd_cur->erasesize = card->blocklen;
0537 mtd_cur->_write = vmu_flash_write;
0538 mtd_cur->_read = vmu_flash_read;
0539 mtd_cur->_sync = vmu_flash_sync;
0540 mtd_cur->writesize = card->blocklen;
0541
0542 mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
0543 if (!mpart)
0544 goto fail_mpart;
0545
0546 mpart->mdev = mdev;
0547 mpart->partition = card->partition;
0548 mtd_cur->priv = mpart;
0549 mtd_cur->owner = THIS_MODULE;
0550
0551 pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
0552 if (!pcache)
0553 goto fail_cache_create;
0554 part_cur->pcache = pcache;
0555
0556 error = mtd_device_register(mtd_cur, NULL, 0);
0557 if (error)
0558 goto fail_mtd_register;
0559
0560 maple_getcond_callback(mdev, NULL, 0,
0561 MAPLE_FUNC_MEMCARD);
0562
0563
0564
0565
0566
0567 if (++card->partition < card->partitions) {
0568 partnum = cpu_to_be32(card->partition << 24);
0569 maple_getcond_callback(mdev, vmu_queryblocks, 0,
0570 MAPLE_FUNC_MEMCARD);
0571 maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
0572 MAPLE_COMMAND_GETMINFO, 2, &partnum);
0573 }
0574 return;
0575
0576 fail_mtd_register:
0577 dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
0578 "error is 0x%X\n", mdev->port, mdev->unit, error);
0579 for (error = 0; error <= card->partition; error++) {
0580 kfree(((card->parts)[error]).pcache);
0581 ((card->parts)[error]).pcache = NULL;
0582 }
0583 fail_cache_create:
0584 fail_mpart:
0585 for (error = 0; error <= card->partition; error++) {
0586 kfree(((card->mtd)[error]).priv);
0587 ((card->mtd)[error]).priv = NULL;
0588 }
0589 maple_getcond_callback(mdev, NULL, 0,
0590 MAPLE_FUNC_MEMCARD);
0591 kfree(part_cur->name);
0592 fail_name:
0593 return;
0594 }
0595
0596
0597 static int vmu_connect(struct maple_device *mdev)
0598 {
0599 unsigned long test_flash_data, basic_flash_data;
0600 int c, error;
0601 struct memcard *card;
0602 u32 partnum = 0;
0603
0604 test_flash_data = be32_to_cpu(mdev->devinfo.function);
0605
0606
0607
0608 c = hweight_long(test_flash_data);
0609
0610 basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
0611
0612 card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
0613 if (!card) {
0614 error = -ENOMEM;
0615 goto fail_nomem;
0616 }
0617
0618 card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
0619 card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
0620 card->writecnt = basic_flash_data >> 12 & 0xF;
0621 card->readcnt = basic_flash_data >> 8 & 0xF;
0622 card->removable = basic_flash_data >> 7 & 1;
0623
0624 card->partition = 0;
0625
0626
0627
0628
0629
0630 card->parts = kmalloc_array(card->partitions, sizeof(struct vmupart),
0631 GFP_KERNEL);
0632 if (!card->parts) {
0633 error = -ENOMEM;
0634 goto fail_partitions;
0635 }
0636
0637 card->mtd = kmalloc_array(card->partitions, sizeof(struct mtd_info),
0638 GFP_KERNEL);
0639 if (!card->mtd) {
0640 error = -ENOMEM;
0641 goto fail_mtd_info;
0642 }
0643
0644 maple_set_drvdata(mdev, card);
0645
0646
0647
0648
0649
0650
0651 maple_getcond_callback(mdev, vmu_queryblocks, 0,
0652 MAPLE_FUNC_MEMCARD);
0653
0654
0655 if (atomic_read(&mdev->busy) == 1) {
0656 wait_event_interruptible_timeout(mdev->maple_wait,
0657 atomic_read(&mdev->busy) == 0, HZ);
0658 if (atomic_read(&mdev->busy) == 1) {
0659 dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
0660 mdev->port, mdev->unit);
0661 error = -EAGAIN;
0662 goto fail_device_busy;
0663 }
0664 }
0665
0666 atomic_set(&mdev->busy, 1);
0667
0668
0669
0670
0671
0672 error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
0673 MAPLE_COMMAND_GETMINFO, 2, &partnum);
0674 if (error) {
0675 dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
0676 " error is 0x%X\n", mdev->port, mdev->unit, error);
0677 goto fail_mtd_info;
0678 }
0679 return 0;
0680
0681 fail_device_busy:
0682 kfree(card->mtd);
0683 fail_mtd_info:
0684 kfree(card->parts);
0685 fail_partitions:
0686 kfree(card);
0687 fail_nomem:
0688 return error;
0689 }
0690
0691 static void vmu_disconnect(struct maple_device *mdev)
0692 {
0693 struct memcard *card;
0694 struct mdev_part *mpart;
0695 int x;
0696
0697 mdev->callback = NULL;
0698 card = maple_get_drvdata(mdev);
0699 for (x = 0; x < card->partitions; x++) {
0700 mpart = ((card->mtd)[x]).priv;
0701 mpart->mdev = NULL;
0702 mtd_device_unregister(&((card->mtd)[x]));
0703 kfree(((card->parts)[x]).name);
0704 }
0705 kfree(card->parts);
0706 kfree(card->mtd);
0707 kfree(card);
0708 }
0709
0710
0711
0712
0713 static int vmu_can_unload(struct maple_device *mdev)
0714 {
0715 struct memcard *card;
0716 int x;
0717 struct mtd_info *mtd;
0718
0719 card = maple_get_drvdata(mdev);
0720 for (x = 0; x < card->partitions; x++) {
0721 mtd = &((card->mtd)[x]);
0722 if (mtd->usecount > 0)
0723 return 0;
0724 }
0725 return 1;
0726 }
0727
0728 #define ERRSTR "VMU at (%d, %d) file error -"
0729
0730 static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
0731 {
0732 enum maple_file_errors error = ((int *)recvbuf)[1];
0733
0734 switch (error) {
0735
0736 case MAPLE_FILEERR_INVALID_PARTITION:
0737 dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
0738 mdev->port, mdev->unit);
0739 break;
0740
0741 case MAPLE_FILEERR_PHASE_ERROR:
0742 dev_notice(&mdev->dev, ERRSTR " phase error\n",
0743 mdev->port, mdev->unit);
0744 break;
0745
0746 case MAPLE_FILEERR_INVALID_BLOCK:
0747 dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
0748 mdev->port, mdev->unit);
0749 break;
0750
0751 case MAPLE_FILEERR_WRITE_ERROR:
0752 dev_notice(&mdev->dev, ERRSTR " write error\n",
0753 mdev->port, mdev->unit);
0754 break;
0755
0756 case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
0757 dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
0758 mdev->port, mdev->unit);
0759 break;
0760
0761 case MAPLE_FILEERR_BAD_CRC:
0762 dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
0763 mdev->port, mdev->unit);
0764 break;
0765
0766 default:
0767 dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
0768 mdev->port, mdev->unit, error);
0769 }
0770 }
0771
0772
0773 static int probe_maple_vmu(struct device *dev)
0774 {
0775 struct maple_device *mdev = to_maple_dev(dev);
0776 struct maple_driver *mdrv = to_maple_driver(dev->driver);
0777
0778 mdev->can_unload = vmu_can_unload;
0779 mdev->fileerr_handler = vmu_file_error;
0780 mdev->driver = mdrv;
0781
0782 return vmu_connect(mdev);
0783 }
0784
0785 static int remove_maple_vmu(struct device *dev)
0786 {
0787 struct maple_device *mdev = to_maple_dev(dev);
0788
0789 vmu_disconnect(mdev);
0790 return 0;
0791 }
0792
0793 static struct maple_driver vmu_flash_driver = {
0794 .function = MAPLE_FUNC_MEMCARD,
0795 .drv = {
0796 .name = "Dreamcast_visual_memory",
0797 .probe = probe_maple_vmu,
0798 .remove = remove_maple_vmu,
0799 },
0800 };
0801
0802 static int __init vmu_flash_map_init(void)
0803 {
0804 return maple_driver_register(&vmu_flash_driver);
0805 }
0806
0807 static void __exit vmu_flash_map_exit(void)
0808 {
0809 maple_driver_unregister(&vmu_flash_driver);
0810 }
0811
0812 module_init(vmu_flash_map_init);
0813 module_exit(vmu_flash_map_exit);
0814
0815 MODULE_LICENSE("GPL");
0816 MODULE_AUTHOR("Adrian McMenamin");
0817 MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");