GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / mtd / maps / vmu-flash.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /* vmu-flash.c
3  * Driver for SEGA Dreamcast Visual Memory Unit
4  *
5  * Copyright (c) Adrian McMenamin 2002 - 2009
6  * Copyright (c) Paul Mundt 2001
7  */
8 #include <linux/init.h>
9 #include <linux/slab.h>
10 #include <linux/sched.h>
11 #include <linux/delay.h>
12 #include <linux/maple.h>
13 #include <linux/mtd/mtd.h>
14 #include <linux/mtd/map.h>
15
16 struct vmu_cache {
17         unsigned char *buffer;          /* Cache */
18         unsigned int block;             /* Which block was cached */
19         unsigned long jiffies_atc;      /* When was it cached? */
20         int valid;
21 };
22
23 struct mdev_part {
24         struct maple_device *mdev;
25         int partition;
26 };
27
28 struct vmupart {
29         u16 user_blocks;
30         u16 root_block;
31         u16 numblocks;
32         char *name;
33         struct vmu_cache *pcache;
34 };
35
36 struct memcard {
37         u16 tempA;
38         u16 tempB;
39         u32 partitions;
40         u32 blocklen;
41         u32 writecnt;
42         u32 readcnt;
43         u32 removable;
44         int partition;
45         int read;
46         unsigned char *blockread;
47         struct vmupart *parts;
48         struct mtd_info *mtd;
49 };
50
51 struct vmu_block {
52         unsigned int num; /* block number */
53         unsigned int ofs; /* block offset */
54 };
55
56 static struct vmu_block *ofs_to_block(unsigned long src_ofs,
57         struct mtd_info *mtd, int partition)
58 {
59         struct vmu_block *vblock;
60         struct maple_device *mdev;
61         struct memcard *card;
62         struct mdev_part *mpart;
63         int num;
64
65         mpart = mtd->priv;
66         mdev = mpart->mdev;
67         card = maple_get_drvdata(mdev);
68
69         if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
70                 goto failed;
71
72         num = src_ofs / card->blocklen;
73         if (num > card->parts[partition].numblocks)
74                 goto failed;
75
76         vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
77         if (!vblock)
78                 goto failed;
79
80         vblock->num = num;
81         vblock->ofs = src_ofs % card->blocklen;
82         return vblock;
83
84 failed:
85         return NULL;
86 }
87
88 /* Maple bus callback function for reads */
89 static void vmu_blockread(struct mapleq *mq)
90 {
91         struct maple_device *mdev;
92         struct memcard *card;
93
94         mdev = mq->dev;
95         card = maple_get_drvdata(mdev);
96         /* copy the read in data */
97
98         if (unlikely(!card->blockread))
99                 return;
100
101         memcpy(card->blockread, mq->recvbuf->buf + 12,
102                 card->blocklen/card->readcnt);
103
104 }
105
106 /* Interface with maple bus to read blocks
107  * caching the results so that other parts
108  * of the driver can access block reads */
109 static int maple_vmu_read_block(unsigned int num, unsigned char *buf,
110         struct mtd_info *mtd)
111 {
112         struct memcard *card;
113         struct mdev_part *mpart;
114         struct maple_device *mdev;
115         int partition, error = 0, x, wait;
116         unsigned char *blockread = NULL;
117         struct vmu_cache *pcache;
118         __be32 sendbuf;
119
120         mpart = mtd->priv;
121         mdev = mpart->mdev;
122         partition = mpart->partition;
123         card = maple_get_drvdata(mdev);
124         pcache = card->parts[partition].pcache;
125         pcache->valid = 0;
126
127         /* prepare the cache for this block */
128         if (!pcache->buffer) {
129                 pcache->buffer = kmalloc(card->blocklen, GFP_KERNEL);
130                 if (!pcache->buffer) {
131                         dev_err(&mdev->dev, "VMU at (%d, %d) - read fails due"
132                                 " to lack of memory\n", mdev->port,
133                                 mdev->unit);
134                         error = -ENOMEM;
135                         goto outB;
136                 }
137         }
138
139         /*
140         * Reads may be phased - again the hardware spec
141         * supports this - though may not be any devices in
142         * the wild that implement it, but we will here
143         */
144         for (x = 0; x < card->readcnt; x++) {
145                 sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
146
147                 if (atomic_read(&mdev->busy) == 1) {
148                         wait_event_interruptible_timeout(mdev->maple_wait,
149                                 atomic_read(&mdev->busy) == 0, HZ);
150                         if (atomic_read(&mdev->busy) == 1) {
151                                 dev_notice(&mdev->dev, "VMU at (%d, %d)"
152                                         " is busy\n", mdev->port, mdev->unit);
153                                 error = -EAGAIN;
154                                 goto outB;
155                         }
156                 }
157
158                 atomic_set(&mdev->busy, 1);
159                 blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
160                 if (!blockread) {
161                         error = -ENOMEM;
162                         atomic_set(&mdev->busy, 0);
163                         goto outB;
164                 }
165                 card->blockread = blockread;
166
167                 maple_getcond_callback(mdev, vmu_blockread, 0,
168                         MAPLE_FUNC_MEMCARD);
169                 error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
170                                 MAPLE_COMMAND_BREAD, 2, &sendbuf);
171                 /* Very long timeouts seem to be needed when box is stressed */
172                 wait = wait_event_interruptible_timeout(mdev->maple_wait,
173                         (atomic_read(&mdev->busy) == 0 ||
174                         atomic_read(&mdev->busy) == 2), HZ * 3);
175                 /*
176                 * MTD layer does not handle hotplugging well
177                 * so have to return errors when VMU is unplugged
178                 * in the middle of a read (busy == 2)
179                 */
180                 if (error || atomic_read(&mdev->busy) == 2) {
181                         if (atomic_read(&mdev->busy) == 2)
182                                 error = -ENXIO;
183                         atomic_set(&mdev->busy, 0);
184                         card->blockread = NULL;
185                         goto outA;
186                 }
187                 if (wait == 0 || wait == -ERESTARTSYS) {
188                         card->blockread = NULL;
189                         atomic_set(&mdev->busy, 0);
190                         error = -EIO;
191                         list_del_init(&(mdev->mq->list));
192                         kfree(mdev->mq->sendbuf);
193                         mdev->mq->sendbuf = NULL;
194                         if (wait == -ERESTARTSYS) {
195                                 dev_warn(&mdev->dev, "VMU read on (%d, %d)"
196                                         " interrupted on block 0x%X\n",
197                                         mdev->port, mdev->unit, num);
198                         } else
199                                 dev_notice(&mdev->dev, "VMU read on (%d, %d)"
200                                         " timed out on block 0x%X\n",
201                                         mdev->port, mdev->unit, num);
202                         goto outA;
203                 }
204
205                 memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
206                         card->blocklen/card->readcnt);
207
208                 memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
209                         card->blockread, card->blocklen/card->readcnt);
210                 card->blockread = NULL;
211                 pcache->block = num;
212                 pcache->jiffies_atc = jiffies;
213                 pcache->valid = 1;
214                 kfree(blockread);
215         }
216
217         return error;
218
219 outA:
220         kfree(blockread);
221 outB:
222         return error;
223 }
224
225 /* communicate with maple bus for phased writing */
226 static int maple_vmu_write_block(unsigned int num, const unsigned char *buf,
227         struct mtd_info *mtd)
228 {
229         struct memcard *card;
230         struct mdev_part *mpart;
231         struct maple_device *mdev;
232         int partition, error, locking, x, phaselen, wait;
233         __be32 *sendbuf;
234
235         mpart = mtd->priv;
236         mdev = mpart->mdev;
237         partition = mpart->partition;
238         card = maple_get_drvdata(mdev);
239
240         phaselen = card->blocklen/card->writecnt;
241
242         sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
243         if (!sendbuf) {
244                 error = -ENOMEM;
245                 goto fail_nosendbuf;
246         }
247         for (x = 0; x < card->writecnt; x++) {
248                 sendbuf[0] = cpu_to_be32(partition << 24 | x << 16 | num);
249                 memcpy(&sendbuf[1], buf + phaselen * x, phaselen);
250                 /* wait until the device is not busy doing something else
251                 * or 1 second - which ever is longer */
252                 if (atomic_read(&mdev->busy) == 1) {
253                         wait_event_interruptible_timeout(mdev->maple_wait,
254                                 atomic_read(&mdev->busy) == 0, HZ);
255                         if (atomic_read(&mdev->busy) == 1) {
256                                 error = -EBUSY;
257                                 dev_notice(&mdev->dev, "VMU write at (%d, %d)"
258                                         "failed - device is busy\n",
259                                         mdev->port, mdev->unit);
260                                 goto fail_nolock;
261                         }
262                 }
263                 atomic_set(&mdev->busy, 1);
264
265                 locking = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
266                         MAPLE_COMMAND_BWRITE, phaselen / 4 + 2, sendbuf);
267                 wait = wait_event_interruptible_timeout(mdev->maple_wait,
268                         atomic_read(&mdev->busy) == 0, HZ/10);
269                 if (locking) {
270                         error = -EIO;
271                         atomic_set(&mdev->busy, 0);
272                         goto fail_nolock;
273                 }
274                 if (atomic_read(&mdev->busy) == 2) {
275                         atomic_set(&mdev->busy, 0);
276                 } else if (wait == 0 || wait == -ERESTARTSYS) {
277                         error = -EIO;
278                         dev_warn(&mdev->dev, "Write at (%d, %d) of block"
279                                 " 0x%X at phase %d failed: could not"
280                                 " communicate with VMU", mdev->port,
281                                 mdev->unit, num, x);
282                         atomic_set(&mdev->busy, 0);
283                         kfree(mdev->mq->sendbuf);
284                         mdev->mq->sendbuf = NULL;
285                         list_del_init(&(mdev->mq->list));
286                         goto fail_nolock;
287                 }
288         }
289         kfree(sendbuf);
290
291         return card->blocklen;
292
293 fail_nolock:
294         kfree(sendbuf);
295 fail_nosendbuf:
296         dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
297                 mdev->unit);
298         return error;
299 }
300
301 /* mtd function to simulate reading byte by byte */
302 static unsigned char vmu_flash_read_char(unsigned long ofs, int *retval,
303         struct mtd_info *mtd)
304 {
305         struct vmu_block *vblock;
306         struct memcard *card;
307         struct mdev_part *mpart;
308         struct maple_device *mdev;
309         unsigned char *buf, ret;
310         int partition, error;
311
312         mpart = mtd->priv;
313         mdev = mpart->mdev;
314         partition = mpart->partition;
315         card = maple_get_drvdata(mdev);
316         *retval =  0;
317
318         buf = kmalloc(card->blocklen, GFP_KERNEL);
319         if (!buf) {
320                 *retval = 1;
321                 ret = -ENOMEM;
322                 goto finish;
323         }
324
325         vblock = ofs_to_block(ofs, mtd, partition);
326         if (!vblock) {
327                 *retval = 3;
328                 ret = -ENOMEM;
329                 goto out_buf;
330         }
331
332         error = maple_vmu_read_block(vblock->num, buf, mtd);
333         if (error) {
334                 ret = error;
335                 *retval = 2;
336                 goto out_vblock;
337         }
338
339         ret = buf[vblock->ofs];
340
341 out_vblock:
342         kfree(vblock);
343 out_buf:
344         kfree(buf);
345 finish:
346         return ret;
347 }
348
349 /* mtd higher order function to read flash */
350 static int vmu_flash_read(struct mtd_info *mtd, loff_t from, size_t len,
351         size_t *retlen,  u_char *buf)
352 {
353         struct maple_device *mdev;
354         struct memcard *card;
355         struct mdev_part *mpart;
356         struct vmu_cache *pcache;
357         struct vmu_block *vblock;
358         int index = 0, retval, partition, leftover, numblocks;
359         unsigned char cx;
360
361         mpart = mtd->priv;
362         mdev = mpart->mdev;
363         partition = mpart->partition;
364         card = maple_get_drvdata(mdev);
365
366         numblocks = card->parts[partition].numblocks;
367         if (from + len > numblocks * card->blocklen)
368                 len = numblocks * card->blocklen - from;
369         if (len == 0)
370                 return -EIO;
371         /* Have we cached this bit already? */
372         pcache = card->parts[partition].pcache;
373         do {
374                 vblock =  ofs_to_block(from + index, mtd, partition);
375                 if (!vblock)
376                         return -ENOMEM;
377                 /* Have we cached this and is the cache valid and timely? */
378                 if (pcache->valid &&
379                         time_before(jiffies, pcache->jiffies_atc + HZ) &&
380                         (pcache->block == vblock->num)) {
381                         /* we have cached it, so do necessary copying */
382                         leftover = card->blocklen - vblock->ofs;
383                         if (vblock->ofs + len - index < card->blocklen) {
384                                 /* only a bit of this block to copy */
385                                 memcpy(buf + index,
386                                         pcache->buffer + vblock->ofs,
387                                         len - index);
388                                 index = len;
389                         } else {
390                                 /* otherwise copy remainder of whole block */
391                                 memcpy(buf + index, pcache->buffer +
392                                         vblock->ofs, leftover);
393                                 index += leftover;
394                         }
395                 } else {
396                         /*
397                         * Not cached so read one byte -
398                         * but cache the rest of the block
399                         */
400                         cx = vmu_flash_read_char(from + index, &retval, mtd);
401                         if (retval) {
402                                 *retlen = index;
403                                 kfree(vblock);
404                                 return cx;
405                         }
406                         memset(buf + index, cx, 1);
407                         index++;
408                 }
409                 kfree(vblock);
410         } while (len > index);
411         *retlen = index;
412
413         return 0;
414 }
415
416 static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
417         size_t *retlen, const u_char *buf)
418 {
419         struct maple_device *mdev;
420         struct memcard *card;
421         struct mdev_part *mpart;
422         int index = 0, partition, error = 0, numblocks;
423         struct vmu_cache *pcache;
424         struct vmu_block *vblock;
425         unsigned char *buffer;
426
427         mpart = mtd->priv;
428         mdev = mpart->mdev;
429         partition = mpart->partition;
430         card = maple_get_drvdata(mdev);
431
432         numblocks = card->parts[partition].numblocks;
433         if (to + len > numblocks * card->blocklen)
434                 len = numblocks * card->blocklen - to;
435         if (len == 0) {
436                 error = -EIO;
437                 goto failed;
438         }
439
440         vblock = ofs_to_block(to, mtd, partition);
441         if (!vblock) {
442                 error = -ENOMEM;
443                 goto failed;
444         }
445
446         buffer = kmalloc(card->blocklen, GFP_KERNEL);
447         if (!buffer) {
448                 error = -ENOMEM;
449                 goto fail_buffer;
450         }
451
452         do {
453                 /* Read in the block we are to write to */
454                 error = maple_vmu_read_block(vblock->num, buffer, mtd);
455                 if (error)
456                         goto fail_io;
457
458                 do {
459                         buffer[vblock->ofs] = buf[index];
460                         vblock->ofs++;
461                         index++;
462                         if (index >= len)
463                                 break;
464                 } while (vblock->ofs < card->blocklen);
465
466                 /* write out new buffer */
467                 error = maple_vmu_write_block(vblock->num, buffer, mtd);
468                 /* invalidate the cache */
469                 pcache = card->parts[partition].pcache;
470                 pcache->valid = 0;
471
472                 if (error != card->blocklen)
473                         goto fail_io;
474
475                 vblock->num++;
476                 vblock->ofs = 0;
477         } while (len > index);
478
479         kfree(buffer);
480         *retlen = index;
481         kfree(vblock);
482         return 0;
483
484 fail_io:
485         kfree(buffer);
486 fail_buffer:
487         kfree(vblock);
488 failed:
489         dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
490         return error;
491 }
492
493 static void vmu_flash_sync(struct mtd_info *mtd)
494 {
495         /* Do nothing here */
496 }
497
498 /* Maple bus callback function to recursively query hardware details */
499 static void vmu_queryblocks(struct mapleq *mq)
500 {
501         struct maple_device *mdev;
502         unsigned short *res;
503         struct memcard *card;
504         __be32 partnum;
505         struct vmu_cache *pcache;
506         struct mdev_part *mpart;
507         struct mtd_info *mtd_cur;
508         struct vmupart *part_cur;
509         int error;
510
511         mdev = mq->dev;
512         card = maple_get_drvdata(mdev);
513         res = (unsigned short *) (mq->recvbuf->buf);
514         card->tempA = res[12];
515         card->tempB = res[6];
516
517         dev_info(&mdev->dev, "VMU device at partition %d has %d user "
518                 "blocks with a root block at %d\n", card->partition,
519                 card->tempA, card->tempB);
520
521         part_cur = &card->parts[card->partition];
522         part_cur->user_blocks = card->tempA;
523         part_cur->root_block = card->tempB;
524         part_cur->numblocks = card->tempB + 1;
525         part_cur->name = kmalloc(12, GFP_KERNEL);
526         if (!part_cur->name)
527                 goto fail_name;
528
529         sprintf(part_cur->name, "vmu%d.%d.%d",
530                 mdev->port, mdev->unit, card->partition);
531         mtd_cur = &card->mtd[card->partition];
532         mtd_cur->name = part_cur->name;
533         mtd_cur->type = 8;
534         mtd_cur->flags = MTD_WRITEABLE|MTD_NO_ERASE;
535         mtd_cur->size = part_cur->numblocks * card->blocklen;
536         mtd_cur->erasesize = card->blocklen;
537         mtd_cur->_write = vmu_flash_write;
538         mtd_cur->_read = vmu_flash_read;
539         mtd_cur->_sync = vmu_flash_sync;
540         mtd_cur->writesize = card->blocklen;
541
542         mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
543         if (!mpart)
544                 goto fail_mpart;
545
546         mpart->mdev = mdev;
547         mpart->partition = card->partition;
548         mtd_cur->priv = mpart;
549         mtd_cur->owner = THIS_MODULE;
550
551         pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
552         if (!pcache)
553                 goto fail_cache_create;
554         part_cur->pcache = pcache;
555
556         error = mtd_device_register(mtd_cur, NULL, 0);
557         if (error)
558                 goto fail_mtd_register;
559
560         maple_getcond_callback(mdev, NULL, 0,
561                 MAPLE_FUNC_MEMCARD);
562
563         /*
564         * Set up a recursive call to the (probably theoretical)
565         * second or more partition
566         */
567         if (++card->partition < card->partitions) {
568                 partnum = cpu_to_be32(card->partition << 24);
569                 maple_getcond_callback(mdev, vmu_queryblocks, 0,
570                         MAPLE_FUNC_MEMCARD);
571                 maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
572                         MAPLE_COMMAND_GETMINFO, 2, &partnum);
573         }
574         return;
575
576 fail_mtd_register:
577         dev_err(&mdev->dev, "Could not register maple device at (%d, %d)"
578                 "error is 0x%X\n", mdev->port, mdev->unit, error);
579         for (error = 0; error <= card->partition; error++) {
580                 kfree(((card->parts)[error]).pcache);
581                 ((card->parts)[error]).pcache = NULL;
582         }
583 fail_cache_create:
584 fail_mpart:
585         for (error = 0; error <= card->partition; error++) {
586                 kfree(((card->mtd)[error]).priv);
587                 ((card->mtd)[error]).priv = NULL;
588         }
589         maple_getcond_callback(mdev, NULL, 0,
590                 MAPLE_FUNC_MEMCARD);
591         kfree(part_cur->name);
592 fail_name:
593         return;
594 }
595
596 /* Handles very basic info about the flash, queries for details */
597 static int vmu_connect(struct maple_device *mdev)
598 {
599         unsigned long test_flash_data, basic_flash_data;
600         int c, error;
601         struct memcard *card;
602         u32 partnum = 0;
603
604         test_flash_data = be32_to_cpu(mdev->devinfo.function);
605         /* Need to count how many bits are set - to find out which
606          * function_data element has details of the memory card
607          */
608         c = hweight_long(test_flash_data);
609
610         basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
611
612         card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
613         if (!card) {
614                 error = -ENOMEM;
615                 goto fail_nomem;
616         }
617
618         card->partitions = (basic_flash_data >> 24 & 0xFF) + 1;
619         card->blocklen = ((basic_flash_data >> 16 & 0xFF) + 1) << 5;
620         card->writecnt = basic_flash_data >> 12 & 0xF;
621         card->readcnt = basic_flash_data >> 8 & 0xF;
622         card->removable = basic_flash_data >> 7 & 1;
623
624         card->partition = 0;
625
626         /*
627         * Not sure there are actually any multi-partition devices in the
628         * real world, but the hardware supports them, so, so will we
629         */
630         card->parts = kmalloc_array(card->partitions, sizeof(struct vmupart),
631                                     GFP_KERNEL);
632         if (!card->parts) {
633                 error = -ENOMEM;
634                 goto fail_partitions;
635         }
636
637         card->mtd = kmalloc_array(card->partitions, sizeof(struct mtd_info),
638                                   GFP_KERNEL);
639         if (!card->mtd) {
640                 error = -ENOMEM;
641                 goto fail_mtd_info;
642         }
643
644         maple_set_drvdata(mdev, card);
645
646         /*
647         * We want to trap meminfo not get cond
648         * so set interval to zero, but rely on maple bus
649         * driver to pass back the results of the meminfo
650         */
651         maple_getcond_callback(mdev, vmu_queryblocks, 0,
652                 MAPLE_FUNC_MEMCARD);
653
654         /* Make sure we are clear to go */
655         if (atomic_read(&mdev->busy) == 1) {
656                 wait_event_interruptible_timeout(mdev->maple_wait,
657                         atomic_read(&mdev->busy) == 0, HZ);
658                 if (atomic_read(&mdev->busy) == 1) {
659                         dev_notice(&mdev->dev, "VMU at (%d, %d) is busy\n",
660                                 mdev->port, mdev->unit);
661                         error = -EAGAIN;
662                         goto fail_device_busy;
663                 }
664         }
665
666         atomic_set(&mdev->busy, 1);
667
668         /*
669         * Set up the minfo call: vmu_queryblocks will handle
670         * the information passed back
671         */
672         error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
673                 MAPLE_COMMAND_GETMINFO, 2, &partnum);
674         if (error) {
675                 dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
676                         " error is 0x%X\n", mdev->port, mdev->unit, error);
677                 goto fail_mtd_info;
678         }
679         return 0;
680
681 fail_device_busy:
682         kfree(card->mtd);
683 fail_mtd_info:
684         kfree(card->parts);
685 fail_partitions:
686         kfree(card);
687 fail_nomem:
688         return error;
689 }
690
691 static void vmu_disconnect(struct maple_device *mdev)
692 {
693         struct memcard *card;
694         struct mdev_part *mpart;
695         int x;
696
697         mdev->callback = NULL;
698         card = maple_get_drvdata(mdev);
699         for (x = 0; x < card->partitions; x++) {
700                 mpart = ((card->mtd)[x]).priv;
701                 mpart->mdev = NULL;
702                 mtd_device_unregister(&((card->mtd)[x]));
703                 kfree(((card->parts)[x]).name);
704         }
705         kfree(card->parts);
706         kfree(card->mtd);
707         kfree(card);
708 }
709
710 /* Callback to handle eccentricities of both mtd subsystem
711  * and general flakyness of Dreamcast VMUs
712  */
713 static int vmu_can_unload(struct maple_device *mdev)
714 {
715         struct memcard *card;
716         int x;
717         struct mtd_info *mtd;
718
719         card = maple_get_drvdata(mdev);
720         for (x = 0; x < card->partitions; x++) {
721                 mtd = &((card->mtd)[x]);
722                 if (kref_read(&mtd->refcnt))
723                         return 0;
724         }
725         return 1;
726 }
727
728 #define ERRSTR "VMU at (%d, %d) file error -"
729
730 static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
731 {
732         enum maple_file_errors error = ((int *)recvbuf)[1];
733
734         switch (error) {
735
736         case MAPLE_FILEERR_INVALID_PARTITION:
737                 dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
738                         mdev->port, mdev->unit);
739                 break;
740
741         case MAPLE_FILEERR_PHASE_ERROR:
742                 dev_notice(&mdev->dev, ERRSTR " phase error\n",
743                         mdev->port, mdev->unit);
744                 break;
745
746         case MAPLE_FILEERR_INVALID_BLOCK:
747                 dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
748                         mdev->port, mdev->unit);
749                 break;
750
751         case MAPLE_FILEERR_WRITE_ERROR:
752                 dev_notice(&mdev->dev, ERRSTR " write error\n",
753                         mdev->port, mdev->unit);
754                 break;
755
756         case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
757                 dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
758                         mdev->port, mdev->unit);
759                 break;
760
761         case MAPLE_FILEERR_BAD_CRC:
762                 dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
763                         mdev->port, mdev->unit);
764                 break;
765
766         default:
767                 dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
768                         mdev->port, mdev->unit, error);
769         }
770 }
771
772
773 static int probe_maple_vmu(struct device *dev)
774 {
775         struct maple_device *mdev = to_maple_dev(dev);
776         struct maple_driver *mdrv = to_maple_driver(dev->driver);
777
778         mdev->can_unload = vmu_can_unload;
779         mdev->fileerr_handler = vmu_file_error;
780         mdev->driver = mdrv;
781
782         return vmu_connect(mdev);
783 }
784
785 static int remove_maple_vmu(struct device *dev)
786 {
787         struct maple_device *mdev = to_maple_dev(dev);
788
789         vmu_disconnect(mdev);
790         return 0;
791 }
792
793 static struct maple_driver vmu_flash_driver = {
794         .function =     MAPLE_FUNC_MEMCARD,
795         .drv = {
796                 .name =         "Dreamcast_visual_memory",
797                 .probe =        probe_maple_vmu,
798                 .remove =       remove_maple_vmu,
799         },
800 };
801
802 static int __init vmu_flash_map_init(void)
803 {
804         return maple_driver_register(&vmu_flash_driver);
805 }
806
807 static void __exit vmu_flash_map_exit(void)
808 {
809         maple_driver_unregister(&vmu_flash_driver);
810 }
811
812 module_init(vmu_flash_map_init);
813 module_exit(vmu_flash_map_exit);
814
815 MODULE_LICENSE("GPL");
816 MODULE_AUTHOR("Adrian McMenamin");
817 MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");