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/sched.h>
12 #include <linux/delay.h>
13 #include <linux/maple.h>
14 #include <linux/mtd/mtd.h>
15 #include <linux/mtd/map.h>
18 unsigned char *buffer
; /* Cache */
19 unsigned int block
; /* Which block was cached */
20 unsigned long jiffies_atc
; /* When was it cached? */
25 struct maple_device
*mdev
;
34 struct vmu_cache
*pcache
;
47 unsigned char *blockread
;
48 struct vmupart
*parts
;
53 unsigned int num
; /* block number */
54 unsigned int ofs
; /* block offset */
57 static struct vmu_block
*ofs_to_block(unsigned long src_ofs
,
58 struct mtd_info
*mtd
, int partition
)
60 struct vmu_block
*vblock
;
61 struct maple_device
*mdev
;
63 struct mdev_part
*mpart
;
68 card
= maple_get_drvdata(mdev
);
70 if (src_ofs
>= card
->parts
[partition
].numblocks
* card
->blocklen
)
73 num
= src_ofs
/ card
->blocklen
;
74 if (num
> card
->parts
[partition
].numblocks
)
77 vblock
= kmalloc(sizeof(struct vmu_block
), GFP_KERNEL
);
82 vblock
->ofs
= src_ofs
% card
->blocklen
;
89 /* Maple bus callback function for reads */
90 static void vmu_blockread(struct mapleq
*mq
)
92 struct maple_device
*mdev
;
96 card
= maple_get_drvdata(mdev
);
97 /* copy the read in data */
99 if (unlikely(!card
->blockread
))
102 memcpy(card
->blockread
, mq
->recvbuf
->buf
+ 12,
103 card
->blocklen
/card
->readcnt
);
107 /* Interface with maple bus to read blocks
108 * caching the results so that other parts
109 * of the driver can access block reads */
110 static int maple_vmu_read_block(unsigned int num
, unsigned char *buf
,
111 struct mtd_info
*mtd
)
113 struct memcard
*card
;
114 struct mdev_part
*mpart
;
115 struct maple_device
*mdev
;
116 int partition
, error
= 0, x
, wait
;
117 unsigned char *blockread
= NULL
;
118 struct vmu_cache
*pcache
;
123 partition
= mpart
->partition
;
124 card
= maple_get_drvdata(mdev
);
125 pcache
= card
->parts
[partition
].pcache
;
128 /* prepare the cache for this block */
129 if (!pcache
->buffer
) {
130 pcache
->buffer
= kmalloc(card
->blocklen
, GFP_KERNEL
);
131 if (!pcache
->buffer
) {
132 dev_err(&mdev
->dev
, "VMU at (%d, %d) - read fails due"
133 " to lack of memory\n", mdev
->port
,
141 * Reads may be phased - again the hardware spec
142 * supports this - though may not be any devices in
143 * the wild that implement it, but we will here
145 for (x
= 0; x
< card
->readcnt
; x
++) {
146 sendbuf
= cpu_to_be32(partition
<< 24 | x
<< 16 | num
);
148 if (atomic_read(&mdev
->busy
) == 1) {
149 wait_event_interruptible_timeout(mdev
->maple_wait
,
150 atomic_read(&mdev
->busy
) == 0, HZ
);
151 if (atomic_read(&mdev
->busy
) == 1) {
152 dev_notice(&mdev
->dev
, "VMU at (%d, %d)"
153 " is busy\n", mdev
->port
, mdev
->unit
);
159 atomic_set(&mdev
->busy
, 1);
160 blockread
= kmalloc(card
->blocklen
/card
->readcnt
, GFP_KERNEL
);
163 atomic_set(&mdev
->busy
, 0);
166 card
->blockread
= blockread
;
168 maple_getcond_callback(mdev
, vmu_blockread
, 0,
170 error
= maple_add_packet(mdev
, MAPLE_FUNC_MEMCARD
,
171 MAPLE_COMMAND_BREAD
, 2, &sendbuf
);
172 /* Very long timeouts seem to be needed when box is stressed */
173 wait
= wait_event_interruptible_timeout(mdev
->maple_wait
,
174 (atomic_read(&mdev
->busy
) == 0 ||
175 atomic_read(&mdev
->busy
) == 2), HZ
* 3);
177 * MTD layer does not handle hotplugging well
178 * so have to return errors when VMU is unplugged
179 * in the middle of a read (busy == 2)
181 if (error
|| atomic_read(&mdev
->busy
) == 2) {
182 if (atomic_read(&mdev
->busy
) == 2)
184 atomic_set(&mdev
->busy
, 0);
185 card
->blockread
= NULL
;
188 if (wait
== 0 || wait
== -ERESTARTSYS
) {
189 card
->blockread
= NULL
;
190 atomic_set(&mdev
->busy
, 0);
192 list_del_init(&(mdev
->mq
->list
));
193 kfree(mdev
->mq
->sendbuf
);
194 mdev
->mq
->sendbuf
= NULL
;
195 if (wait
== -ERESTARTSYS
) {
196 dev_warn(&mdev
->dev
, "VMU read on (%d, %d)"
197 " interrupted on block 0x%X\n",
198 mdev
->port
, mdev
->unit
, num
);
200 dev_notice(&mdev
->dev
, "VMU read on (%d, %d)"
201 " timed out on block 0x%X\n",
202 mdev
->port
, mdev
->unit
, num
);
206 memcpy(buf
+ (card
->blocklen
/card
->readcnt
) * x
, blockread
,
207 card
->blocklen
/card
->readcnt
);
209 memcpy(pcache
->buffer
+ (card
->blocklen
/card
->readcnt
) * x
,
210 card
->blockread
, card
->blocklen
/card
->readcnt
);
211 card
->blockread
= NULL
;
213 pcache
->jiffies_atc
= jiffies
;
226 /* communicate with maple bus for phased writing */
227 static int maple_vmu_write_block(unsigned int num
, const unsigned char *buf
,
228 struct mtd_info
*mtd
)
230 struct memcard
*card
;
231 struct mdev_part
*mpart
;
232 struct maple_device
*mdev
;
233 int partition
, error
, locking
, x
, phaselen
, wait
;
238 partition
= mpart
->partition
;
239 card
= maple_get_drvdata(mdev
);
241 phaselen
= card
->blocklen
/card
->writecnt
;
243 sendbuf
= kmalloc(phaselen
+ 4, GFP_KERNEL
);
248 for (x
= 0; x
< card
->writecnt
; x
++) {
249 sendbuf
[0] = cpu_to_be32(partition
<< 24 | x
<< 16 | num
);
250 memcpy(&sendbuf
[1], buf
+ phaselen
* x
, phaselen
);
251 /* wait until the device is not busy doing something else
252 * or 1 second - which ever is longer */
253 if (atomic_read(&mdev
->busy
) == 1) {
254 wait_event_interruptible_timeout(mdev
->maple_wait
,
255 atomic_read(&mdev
->busy
) == 0, HZ
);
256 if (atomic_read(&mdev
->busy
) == 1) {
258 dev_notice(&mdev
->dev
, "VMU write at (%d, %d)"
259 "failed - device is busy\n",
260 mdev
->port
, mdev
->unit
);
264 atomic_set(&mdev
->busy
, 1);
266 locking
= maple_add_packet(mdev
, MAPLE_FUNC_MEMCARD
,
267 MAPLE_COMMAND_BWRITE
, phaselen
/ 4 + 2, sendbuf
);
268 wait
= wait_event_interruptible_timeout(mdev
->maple_wait
,
269 atomic_read(&mdev
->busy
) == 0, HZ
/10);
272 atomic_set(&mdev
->busy
, 0);
275 if (atomic_read(&mdev
->busy
) == 2) {
276 atomic_set(&mdev
->busy
, 0);
277 } else if (wait
== 0 || wait
== -ERESTARTSYS
) {
279 dev_warn(&mdev
->dev
, "Write at (%d, %d) of block"
280 " 0x%X at phase %d failed: could not"
281 " communicate with VMU", mdev
->port
,
283 atomic_set(&mdev
->busy
, 0);
284 kfree(mdev
->mq
->sendbuf
);
285 mdev
->mq
->sendbuf
= NULL
;
286 list_del_init(&(mdev
->mq
->list
));
292 return card
->blocklen
;
297 dev_err(&mdev
->dev
, "VMU (%d, %d): write failed\n", mdev
->port
,
302 /* mtd function to simulate reading byte by byte */
303 static unsigned char vmu_flash_read_char(unsigned long ofs
, int *retval
,
304 struct mtd_info
*mtd
)
306 struct vmu_block
*vblock
;
307 struct memcard
*card
;
308 struct mdev_part
*mpart
;
309 struct maple_device
*mdev
;
310 unsigned char *buf
, ret
;
311 int partition
, error
;
315 partition
= mpart
->partition
;
316 card
= maple_get_drvdata(mdev
);
319 buf
= kmalloc(card
->blocklen
, GFP_KERNEL
);
326 vblock
= ofs_to_block(ofs
, mtd
, partition
);
333 error
= maple_vmu_read_block(vblock
->num
, buf
, mtd
);
340 ret
= buf
[vblock
->ofs
];
350 /* mtd higher order function to read flash */
351 static int vmu_flash_read(struct mtd_info
*mtd
, loff_t from
, size_t len
,
352 size_t *retlen
, u_char
*buf
)
354 struct maple_device
*mdev
;
355 struct memcard
*card
;
356 struct mdev_part
*mpart
;
357 struct vmu_cache
*pcache
;
358 struct vmu_block
*vblock
;
359 int index
= 0, retval
, partition
, leftover
, numblocks
;
367 partition
= mpart
->partition
;
368 card
= maple_get_drvdata(mdev
);
370 numblocks
= card
->parts
[partition
].numblocks
;
371 if (from
+ len
> numblocks
* card
->blocklen
)
372 len
= numblocks
* card
->blocklen
- from
;
375 /* Have we cached this bit already? */
376 pcache
= card
->parts
[partition
].pcache
;
378 vblock
= ofs_to_block(from
+ index
, mtd
, partition
);
381 /* Have we cached this and is the cache valid and timely? */
383 time_before(jiffies
, pcache
->jiffies_atc
+ HZ
) &&
384 (pcache
->block
== vblock
->num
)) {
385 /* we have cached it, so do necessary copying */
386 leftover
= card
->blocklen
- vblock
->ofs
;
387 if (vblock
->ofs
+ len
- index
< card
->blocklen
) {
388 /* only a bit of this block to copy */
390 pcache
->buffer
+ vblock
->ofs
,
394 /* otherwise copy remainder of whole block */
395 memcpy(buf
+ index
, pcache
->buffer
+
396 vblock
->ofs
, leftover
);
401 * Not cached so read one byte -
402 * but cache the rest of the block
404 cx
= vmu_flash_read_char(from
+ index
, &retval
, mtd
);
410 memset(buf
+ index
, cx
, 1);
414 } while (len
> index
);
420 static int vmu_flash_write(struct mtd_info
*mtd
, loff_t to
, size_t len
,
421 size_t *retlen
, const u_char
*buf
)
423 struct maple_device
*mdev
;
424 struct memcard
*card
;
425 struct mdev_part
*mpart
;
426 int index
= 0, partition
, error
= 0, numblocks
;
427 struct vmu_cache
*pcache
;
428 struct vmu_block
*vblock
;
429 unsigned char *buffer
;
433 partition
= mpart
->partition
;
434 card
= maple_get_drvdata(mdev
);
436 /* simple sanity checks */
441 numblocks
= card
->parts
[partition
].numblocks
;
442 if (to
+ len
> numblocks
* card
->blocklen
)
443 len
= numblocks
* card
->blocklen
- to
;
449 vblock
= ofs_to_block(to
, mtd
, partition
);
455 buffer
= kmalloc(card
->blocklen
, GFP_KERNEL
);
462 /* Read in the block we are to write to */
463 error
= maple_vmu_read_block(vblock
->num
, buffer
, mtd
);
468 buffer
[vblock
->ofs
] = buf
[index
];
473 } while (vblock
->ofs
< card
->blocklen
);
475 /* write out new buffer */
476 error
= maple_vmu_write_block(vblock
->num
, buffer
, mtd
);
477 /* invalidate the cache */
478 pcache
= card
->parts
[partition
].pcache
;
481 if (error
!= card
->blocklen
)
486 } while (len
> index
);
498 dev_err(&mdev
->dev
, "VMU write failing with error %d\n", error
);
502 static void vmu_flash_sync(struct mtd_info
*mtd
)
504 /* Do nothing here */
507 /* Maple bus callback function to recursively query hardware details */
508 static void vmu_queryblocks(struct mapleq
*mq
)
510 struct maple_device
*mdev
;
512 struct memcard
*card
;
514 struct vmu_cache
*pcache
;
515 struct mdev_part
*mpart
;
516 struct mtd_info
*mtd_cur
;
517 struct vmupart
*part_cur
;
521 card
= maple_get_drvdata(mdev
);
522 res
= (unsigned short *) (mq
->recvbuf
->buf
);
523 card
->tempA
= res
[12];
524 card
->tempB
= res
[6];
526 dev_info(&mdev
->dev
, "VMU device at partition %d has %d user "
527 "blocks with a root block at %d\n", card
->partition
,
528 card
->tempA
, card
->tempB
);
530 part_cur
= &card
->parts
[card
->partition
];
531 part_cur
->user_blocks
= card
->tempA
;
532 part_cur
->root_block
= card
->tempB
;
533 part_cur
->numblocks
= card
->tempB
+ 1;
534 part_cur
->name
= kmalloc(12, GFP_KERNEL
);
538 sprintf(part_cur
->name
, "vmu%d.%d.%d",
539 mdev
->port
, mdev
->unit
, card
->partition
);
540 mtd_cur
= &card
->mtd
[card
->partition
];
541 mtd_cur
->name
= part_cur
->name
;
543 mtd_cur
->flags
= MTD_WRITEABLE
|MTD_NO_ERASE
;
544 mtd_cur
->size
= part_cur
->numblocks
* card
->blocklen
;
545 mtd_cur
->erasesize
= card
->blocklen
;
546 mtd_cur
->write
= vmu_flash_write
;
547 mtd_cur
->read
= vmu_flash_read
;
548 mtd_cur
->sync
= vmu_flash_sync
;
549 mtd_cur
->writesize
= card
->blocklen
;
551 mpart
= kmalloc(sizeof(struct mdev_part
), GFP_KERNEL
);
556 mpart
->partition
= card
->partition
;
557 mtd_cur
->priv
= mpart
;
558 mtd_cur
->owner
= THIS_MODULE
;
560 pcache
= kzalloc(sizeof(struct vmu_cache
), GFP_KERNEL
);
562 goto fail_cache_create
;
563 part_cur
->pcache
= pcache
;
565 error
= add_mtd_device(mtd_cur
);
567 goto fail_mtd_register
;
569 maple_getcond_callback(mdev
, NULL
, 0,
573 * Set up a recursive call to the (probably theoretical)
574 * second or more partition
576 if (++card
->partition
< card
->partitions
) {
577 partnum
= cpu_to_be32(card
->partition
<< 24);
578 maple_getcond_callback(mdev
, vmu_queryblocks
, 0,
580 maple_add_packet(mdev
, MAPLE_FUNC_MEMCARD
,
581 MAPLE_COMMAND_GETMINFO
, 2, &partnum
);
586 dev_err(&mdev
->dev
, "Could not register maple device at (%d, %d)"
587 "error is 0x%X\n", mdev
->port
, mdev
->unit
, error
);
588 for (error
= 0; error
<= card
->partition
; error
++) {
589 kfree(((card
->parts
)[error
]).pcache
);
590 ((card
->parts
)[error
]).pcache
= NULL
;
594 for (error
= 0; error
<= card
->partition
; error
++) {
595 kfree(((card
->mtd
)[error
]).priv
);
596 ((card
->mtd
)[error
]).priv
= NULL
;
598 maple_getcond_callback(mdev
, NULL
, 0,
600 kfree(part_cur
->name
);
605 /* Handles very basic info about the flash, queries for details */
606 static int __devinit
vmu_connect(struct maple_device
*mdev
)
608 unsigned long test_flash_data
, basic_flash_data
;
610 struct memcard
*card
;
613 test_flash_data
= be32_to_cpu(mdev
->devinfo
.function
);
614 /* Need to count how many bits are set - to find out which
615 * function_data element has details of the memory card
617 c
= hweight_long(test_flash_data
);
619 basic_flash_data
= be32_to_cpu(mdev
->devinfo
.function_data
[c
- 1]);
621 card
= kmalloc(sizeof(struct memcard
), GFP_KERNEL
);
627 card
->partitions
= (basic_flash_data
>> 24 & 0xFF) + 1;
628 card
->blocklen
= ((basic_flash_data
>> 16 & 0xFF) + 1) << 5;
629 card
->writecnt
= basic_flash_data
>> 12 & 0xF;
630 card
->readcnt
= basic_flash_data
>> 8 & 0xF;
631 card
->removeable
= basic_flash_data
>> 7 & 1;
636 * Not sure there are actually any multi-partition devices in the
637 * real world, but the hardware supports them, so, so will we
639 card
->parts
= kmalloc(sizeof(struct vmupart
) * card
->partitions
,
643 goto fail_partitions
;
646 card
->mtd
= kmalloc(sizeof(struct mtd_info
) * card
->partitions
,
653 maple_set_drvdata(mdev
, card
);
656 * We want to trap meminfo not get cond
657 * so set interval to zero, but rely on maple bus
658 * driver to pass back the results of the meminfo
660 maple_getcond_callback(mdev
, vmu_queryblocks
, 0,
663 /* Make sure we are clear to go */
664 if (atomic_read(&mdev
->busy
) == 1) {
665 wait_event_interruptible_timeout(mdev
->maple_wait
,
666 atomic_read(&mdev
->busy
) == 0, HZ
);
667 if (atomic_read(&mdev
->busy
) == 1) {
668 dev_notice(&mdev
->dev
, "VMU at (%d, %d) is busy\n",
669 mdev
->port
, mdev
->unit
);
671 goto fail_device_busy
;
675 atomic_set(&mdev
->busy
, 1);
678 * Set up the minfo call: vmu_queryblocks will handle
679 * the information passed back
681 error
= maple_add_packet(mdev
, MAPLE_FUNC_MEMCARD
,
682 MAPLE_COMMAND_GETMINFO
, 2, &partnum
);
684 dev_err(&mdev
->dev
, "Could not lock VMU at (%d, %d)"
685 " error is 0x%X\n", mdev
->port
, mdev
->unit
, error
);
700 static void __devexit
vmu_disconnect(struct maple_device
*mdev
)
702 struct memcard
*card
;
703 struct mdev_part
*mpart
;
706 mdev
->callback
= NULL
;
707 card
= maple_get_drvdata(mdev
);
708 for (x
= 0; x
< card
->partitions
; x
++) {
709 mpart
= ((card
->mtd
)[x
]).priv
;
711 del_mtd_device(&((card
->mtd
)[x
]));
712 kfree(((card
->parts
)[x
]).name
);
719 /* Callback to handle eccentricities of both mtd subsystem
720 * and general flakyness of Dreamcast VMUs
722 static int vmu_can_unload(struct maple_device
*mdev
)
724 struct memcard
*card
;
726 struct mtd_info
*mtd
;
728 card
= maple_get_drvdata(mdev
);
729 for (x
= 0; x
< card
->partitions
; x
++) {
730 mtd
= &((card
->mtd
)[x
]);
731 if (mtd
->usecount
> 0)
737 #define ERRSTR "VMU at (%d, %d) file error -"
739 static void vmu_file_error(struct maple_device
*mdev
, void *recvbuf
)
741 enum maple_file_errors error
= ((int *)recvbuf
)[1];
745 case MAPLE_FILEERR_INVALID_PARTITION
:
746 dev_notice(&mdev
->dev
, ERRSTR
" invalid partition number\n",
747 mdev
->port
, mdev
->unit
);
750 case MAPLE_FILEERR_PHASE_ERROR
:
751 dev_notice(&mdev
->dev
, ERRSTR
" phase error\n",
752 mdev
->port
, mdev
->unit
);
755 case MAPLE_FILEERR_INVALID_BLOCK
:
756 dev_notice(&mdev
->dev
, ERRSTR
" invalid block number\n",
757 mdev
->port
, mdev
->unit
);
760 case MAPLE_FILEERR_WRITE_ERROR
:
761 dev_notice(&mdev
->dev
, ERRSTR
" write error\n",
762 mdev
->port
, mdev
->unit
);
765 case MAPLE_FILEERR_INVALID_WRITE_LENGTH
:
766 dev_notice(&mdev
->dev
, ERRSTR
" invalid write length\n",
767 mdev
->port
, mdev
->unit
);
770 case MAPLE_FILEERR_BAD_CRC
:
771 dev_notice(&mdev
->dev
, ERRSTR
" bad CRC\n",
772 mdev
->port
, mdev
->unit
);
776 dev_notice(&mdev
->dev
, ERRSTR
" 0x%X\n",
777 mdev
->port
, mdev
->unit
, error
);
782 static int __devinit
probe_maple_vmu(struct device
*dev
)
785 struct maple_device
*mdev
= to_maple_dev(dev
);
786 struct maple_driver
*mdrv
= to_maple_driver(dev
->driver
);
788 mdev
->can_unload
= vmu_can_unload
;
789 mdev
->fileerr_handler
= vmu_file_error
;
792 error
= vmu_connect(mdev
);
799 static int __devexit
remove_maple_vmu(struct device
*dev
)
801 struct maple_device
*mdev
= to_maple_dev(dev
);
803 vmu_disconnect(mdev
);
807 static struct maple_driver vmu_flash_driver
= {
808 .function
= MAPLE_FUNC_MEMCARD
,
810 .name
= "Dreamcast_visual_memory",
811 .probe
= probe_maple_vmu
,
812 .remove
= __devexit_p(remove_maple_vmu
),
816 static int __init
vmu_flash_map_init(void)
818 return maple_driver_register(&vmu_flash_driver
);
821 static void __exit
vmu_flash_map_exit(void)
823 maple_driver_unregister(&vmu_flash_driver
);
826 module_init(vmu_flash_map_init
);
827 module_exit(vmu_flash_map_exit
);
829 MODULE_LICENSE("GPL");
830 MODULE_AUTHOR("Adrian McMenamin");
831 MODULE_DESCRIPTION("Flash mapping for Sega Dreamcast visual memory");