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