2
* Driver for SEGA Dreamcast Visual Memory Unit
4
* Copyright (c) Adrian McMenamin 2002 - 2009
5
* Copyright (c) Paul Mundt 2001
7
* Licensed under version 2 of the
8
* GNU General Public Licence
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>
19
unsigned char *buffer; /* Cache */
20
unsigned int block; /* Which block was cached */
21
unsigned long jiffies_atc; /* When was it cached? */
26
struct maple_device *mdev;
35
struct vmu_cache *pcache;
48
unsigned char *blockread;
49
struct vmupart *parts;
54
unsigned int num; /* block number */
55
unsigned int ofs; /* block offset */
58
static struct vmu_block *ofs_to_block(unsigned long src_ofs,
59
struct mtd_info *mtd, int partition)
61
struct vmu_block *vblock;
62
struct maple_device *mdev;
64
struct mdev_part *mpart;
69
card = maple_get_drvdata(mdev);
71
if (src_ofs >= card->parts[partition].numblocks * card->blocklen)
74
num = src_ofs / card->blocklen;
75
if (num > card->parts[partition].numblocks)
78
vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL);
83
vblock->ofs = src_ofs % card->blocklen;
90
/* Maple bus callback function for reads */
91
static void vmu_blockread(struct mapleq *mq)
93
struct maple_device *mdev;
97
card = maple_get_drvdata(mdev);
98
/* copy the read in data */
100
if (unlikely(!card->blockread))
103
memcpy(card->blockread, mq->recvbuf->buf + 12,
104
card->blocklen/card->readcnt);
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)
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;
124
partition = mpart->partition;
125
card = maple_get_drvdata(mdev);
126
pcache = card->parts[partition].pcache;
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,
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
146
for (x = 0; x < card->readcnt; x++) {
147
sendbuf = cpu_to_be32(partition << 24 | x << 16 | num);
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);
160
atomic_set(&mdev->busy, 1);
161
blockread = kmalloc(card->blocklen/card->readcnt, GFP_KERNEL);
164
atomic_set(&mdev->busy, 0);
167
card->blockread = blockread;
169
maple_getcond_callback(mdev, vmu_blockread, 0,
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);
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)
182
if (error || atomic_read(&mdev->busy) == 2) {
183
if (atomic_read(&mdev->busy) == 2)
185
atomic_set(&mdev->busy, 0);
186
card->blockread = NULL;
189
if (wait == 0 || wait == -ERESTARTSYS) {
190
card->blockread = NULL;
191
atomic_set(&mdev->busy, 0);
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);
201
dev_notice(&mdev->dev, "VMU read on (%d, %d)"
202
" timed out on block 0x%X\n",
203
mdev->port, mdev->unit, num);
207
memcpy(buf + (card->blocklen/card->readcnt) * x, blockread,
208
card->blocklen/card->readcnt);
210
memcpy(pcache->buffer + (card->blocklen/card->readcnt) * x,
211
card->blockread, card->blocklen/card->readcnt);
212
card->blockread = NULL;
214
pcache->jiffies_atc = jiffies;
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)
231
struct memcard *card;
232
struct mdev_part *mpart;
233
struct maple_device *mdev;
234
int partition, error, locking, x, phaselen, wait;
239
partition = mpart->partition;
240
card = maple_get_drvdata(mdev);
242
phaselen = card->blocklen/card->writecnt;
244
sendbuf = kmalloc(phaselen + 4, GFP_KERNEL);
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) {
259
dev_notice(&mdev->dev, "VMU write at (%d, %d)"
260
"failed - device is busy\n",
261
mdev->port, mdev->unit);
265
atomic_set(&mdev->busy, 1);
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);
273
atomic_set(&mdev->busy, 0);
276
if (atomic_read(&mdev->busy) == 2) {
277
atomic_set(&mdev->busy, 0);
278
} else if (wait == 0 || wait == -ERESTARTSYS) {
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,
284
atomic_set(&mdev->busy, 0);
285
kfree(mdev->mq->sendbuf);
286
mdev->mq->sendbuf = NULL;
287
list_del_init(&(mdev->mq->list));
293
return card->blocklen;
298
dev_err(&mdev->dev, "VMU (%d, %d): write failed\n", mdev->port,
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)
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;
316
partition = mpart->partition;
317
card = maple_get_drvdata(mdev);
320
buf = kmalloc(card->blocklen, GFP_KERNEL);
327
vblock = ofs_to_block(ofs, mtd, partition);
334
error = maple_vmu_read_block(vblock->num, buf, mtd);
341
ret = buf[vblock->ofs];
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)
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;
368
partition = mpart->partition;
369
card = maple_get_drvdata(mdev);
371
numblocks = card->parts[partition].numblocks;
372
if (from + len > numblocks * card->blocklen)
373
len = numblocks * card->blocklen - from;
376
/* Have we cached this bit already? */
377
pcache = card->parts[partition].pcache;
379
vblock = ofs_to_block(from + index, mtd, partition);
382
/* Have we cached this and is the cache valid and timely? */
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 */
391
pcache->buffer + vblock->ofs,
395
/* otherwise copy remainder of whole block */
396
memcpy(buf + index, pcache->buffer +
397
vblock->ofs, leftover);
402
* Not cached so read one byte -
403
* but cache the rest of the block
405
cx = vmu_flash_read_char(from + index, &retval, mtd);
411
memset(buf + index, cx, 1);
415
} while (len > index);
421
static int vmu_flash_write(struct mtd_info *mtd, loff_t to, size_t len,
422
size_t *retlen, const u_char *buf)
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;
434
partition = mpart->partition;
435
card = maple_get_drvdata(mdev);
437
/* simple sanity checks */
442
numblocks = card->parts[partition].numblocks;
443
if (to + len > numblocks * card->blocklen)
444
len = numblocks * card->blocklen - to;
450
vblock = ofs_to_block(to, mtd, partition);
456
buffer = kmalloc(card->blocklen, GFP_KERNEL);
463
/* Read in the block we are to write to */
464
error = maple_vmu_read_block(vblock->num, buffer, mtd);
469
buffer[vblock->ofs] = buf[index];
474
} while (vblock->ofs < card->blocklen);
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;
482
if (error != card->blocklen)
487
} while (len > index);
499
dev_err(&mdev->dev, "VMU write failing with error %d\n", error);
503
static void vmu_flash_sync(struct mtd_info *mtd)
505
/* Do nothing here */
508
/* Maple bus callback function to recursively query hardware details */
509
static void vmu_queryblocks(struct mapleq *mq)
511
struct maple_device *mdev;
513
struct memcard *card;
515
struct vmu_cache *pcache;
516
struct mdev_part *mpart;
517
struct mtd_info *mtd_cur;
518
struct vmupart *part_cur;
522
card = maple_get_drvdata(mdev);
523
res = (unsigned short *) (mq->recvbuf->buf);
524
card->tempA = res[12];
525
card->tempB = res[6];
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);
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);
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;
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;
552
mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL);
557
mpart->partition = card->partition;
558
mtd_cur->priv = mpart;
559
mtd_cur->owner = THIS_MODULE;
561
pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL);
563
goto fail_cache_create;
564
part_cur->pcache = pcache;
566
error = mtd_device_register(mtd_cur, NULL, 0);
568
goto fail_mtd_register;
570
maple_getcond_callback(mdev, NULL, 0,
574
* Set up a recursive call to the (probably theoretical)
575
* second or more partition
577
if (++card->partition < card->partitions) {
578
partnum = cpu_to_be32(card->partition << 24);
579
maple_getcond_callback(mdev, vmu_queryblocks, 0,
581
maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
582
MAPLE_COMMAND_GETMINFO, 2, &partnum);
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;
595
for (error = 0; error <= card->partition; error++) {
596
kfree(((card->mtd)[error]).priv);
597
((card->mtd)[error]).priv = NULL;
599
maple_getcond_callback(mdev, NULL, 0,
601
kfree(part_cur->name);
606
/* Handles very basic info about the flash, queries for details */
607
static int __devinit vmu_connect(struct maple_device *mdev)
609
unsigned long test_flash_data, basic_flash_data;
611
struct memcard *card;
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
618
c = hweight_long(test_flash_data);
620
basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]);
622
card = kmalloc(sizeof(struct memcard), GFP_KERNEL);
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;
637
* Not sure there are actually any multi-partition devices in the
638
* real world, but the hardware supports them, so, so will we
640
card->parts = kmalloc(sizeof(struct vmupart) * card->partitions,
644
goto fail_partitions;
647
card->mtd = kmalloc(sizeof(struct mtd_info) * card->partitions,
654
maple_set_drvdata(mdev, card);
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
661
maple_getcond_callback(mdev, vmu_queryblocks, 0,
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);
672
goto fail_device_busy;
676
atomic_set(&mdev->busy, 1);
679
* Set up the minfo call: vmu_queryblocks will handle
680
* the information passed back
682
error = maple_add_packet(mdev, MAPLE_FUNC_MEMCARD,
683
MAPLE_COMMAND_GETMINFO, 2, &partnum);
685
dev_err(&mdev->dev, "Could not lock VMU at (%d, %d)"
686
" error is 0x%X\n", mdev->port, mdev->unit, error);
701
static void __devexit vmu_disconnect(struct maple_device *mdev)
703
struct memcard *card;
704
struct mdev_part *mpart;
707
mdev->callback = NULL;
708
card = maple_get_drvdata(mdev);
709
for (x = 0; x < card->partitions; x++) {
710
mpart = ((card->mtd)[x]).priv;
712
mtd_device_unregister(&((card->mtd)[x]));
713
kfree(((card->parts)[x]).name);
720
/* Callback to handle eccentricities of both mtd subsystem
721
* and general flakyness of Dreamcast VMUs
723
static int vmu_can_unload(struct maple_device *mdev)
725
struct memcard *card;
727
struct mtd_info *mtd;
729
card = maple_get_drvdata(mdev);
730
for (x = 0; x < card->partitions; x++) {
731
mtd = &((card->mtd)[x]);
732
if (mtd->usecount > 0)
738
#define ERRSTR "VMU at (%d, %d) file error -"
740
static void vmu_file_error(struct maple_device *mdev, void *recvbuf)
742
enum maple_file_errors error = ((int *)recvbuf)[1];
746
case MAPLE_FILEERR_INVALID_PARTITION:
747
dev_notice(&mdev->dev, ERRSTR " invalid partition number\n",
748
mdev->port, mdev->unit);
751
case MAPLE_FILEERR_PHASE_ERROR:
752
dev_notice(&mdev->dev, ERRSTR " phase error\n",
753
mdev->port, mdev->unit);
756
case MAPLE_FILEERR_INVALID_BLOCK:
757
dev_notice(&mdev->dev, ERRSTR " invalid block number\n",
758
mdev->port, mdev->unit);
761
case MAPLE_FILEERR_WRITE_ERROR:
762
dev_notice(&mdev->dev, ERRSTR " write error\n",
763
mdev->port, mdev->unit);
766
case MAPLE_FILEERR_INVALID_WRITE_LENGTH:
767
dev_notice(&mdev->dev, ERRSTR " invalid write length\n",
768
mdev->port, mdev->unit);
771
case MAPLE_FILEERR_BAD_CRC:
772
dev_notice(&mdev->dev, ERRSTR " bad CRC\n",
773
mdev->port, mdev->unit);
777
dev_notice(&mdev->dev, ERRSTR " 0x%X\n",
778
mdev->port, mdev->unit, error);
783
static int __devinit probe_maple_vmu(struct device *dev)
786
struct maple_device *mdev = to_maple_dev(dev);
787
struct maple_driver *mdrv = to_maple_driver(dev->driver);
789
mdev->can_unload = vmu_can_unload;
790
mdev->fileerr_handler = vmu_file_error;
793
error = vmu_connect(mdev);
800
static int __devexit remove_maple_vmu(struct device *dev)
802
struct maple_device *mdev = to_maple_dev(dev);
804
vmu_disconnect(mdev);
808
static struct maple_driver vmu_flash_driver = {
809
.function = MAPLE_FUNC_MEMCARD,
811
.name = "Dreamcast_visual_memory",
812
.probe = probe_maple_vmu,
813
.remove = __devexit_p(remove_maple_vmu),
817
static int __init vmu_flash_map_init(void)
819
return maple_driver_register(&vmu_flash_driver);
822
static void __exit vmu_flash_map_exit(void)
824
maple_driver_unregister(&vmu_flash_driver);
827
module_init(vmu_flash_map_init);
828
module_exit(vmu_flash_map_exit);
830
MODULE_LICENSE("GPL");
831
MODULE_AUTHOR("Adrian McMenamin");
832
MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");