29 #include <linux/module.h>
31 #include <linux/types.h>
32 #include <linux/errno.h>
34 #include <linux/fcntl.h>
35 #include <linux/poll.h>
37 #include <linux/string.h>
40 #include <asm/uaccess.h>
41 #include <asm/pgtable.h>
44 #include <asm/oplib.h>
47 #define JSFIDSZ (sizeof(struct jsflash_ident_arg))
48 #define JSFPRGSZ (sizeof(struct jsflash_program_arg))
68 #define JSF_PART_BITS 2
69 #define JSF_PART_MASK 0x3
77 static unsigned int jsf_inl(
unsigned long addr)
81 __asm__ __volatile__(
"lda [%1] %2, %0\n\t" :
87 static void jsf_outl(
unsigned long addr,
__u32 data)
90 __asm__ __volatile__(
"sta %0, [%1] %2\n\t" : :
117 #define JSF_BASE_TOP 0x30000000
118 #define JSF_BASE_ALL 0x20000000
120 #define JSF_BASE_JK 0x20400000
124 static struct gendisk *jsfd_disk[
JSF_MAX];
138 static void jsf_wait(
unsigned long p) {
144 if ((x1 & 0x40404040) == (x2 & 0x40404040))
return;
159 static void jsf_write4(
unsigned long fa,
u32 data) {
161 jsf_outl(fa, 0xAAAAAAAA);
162 jsf_outl(fa, 0x55555555);
163 jsf_outl(fa, 0xA0A0A0A0);
171 static void jsfd_read(
char *
buf,
unsigned long p,
size_t togo) {
192 struct jsfd_part *jdp = req->rq_disk->private_data;
193 unsigned long offset = blk_rq_pos(req) << 9;
194 size_t len = blk_rq_cur_bytes(req);
197 if ((offset + len) > jdp->
dsize)
200 if (rq_data_dir(req) !=
READ) {
205 if ((jdp->
dbase & 0xff000000) != 0x20000000) {
210 jsfd_read(req->buffer, jdp->
dbase + offset, len);
226 static loff_t jsf_lseek(
struct file *
file, loff_t offset,
int orig)
250 static ssize_t jsf_read(
struct file * file,
char __user * buf,
251 size_t togo, loff_t *ppos)
253 unsigned long p = *ppos;
273 if (x > togo) x = togo;
306 static ssize_t jsf_write(
struct file * file,
const char __user * buf,
307 size_t count, loff_t *ppos)
314 static int jsf_ioctl_erase(
unsigned long arg)
321 jsf_outl(p, 0xAAAAAAAA);
322 jsf_outl(p, 0x55555555);
323 jsf_outl(p, 0x80808080);
324 jsf_outl(p, 0xAAAAAAAA);
325 jsf_outl(p, 0x55555555);
326 jsf_outl(p, 0x10101010);
336 for (i = 0; i < 1000000; i++) {
338 if ((x & 0x80808080) == 0x80808080)
break;
340 if ((x & 0x80808080) != 0x80808080) {
341 printk(
"jsf0: erase timeout with 0x%08x\n", x);
343 printk(
"jsf0: erase done with 0x%08x\n", x);
357 static int jsf_ioctl_program(
void __user *arg)
372 if ((togo & 3) || (p & 3))
return -
EINVAL;
374 uptr = (
char __user *) (
unsigned long) abuf.data;
387 static long jsf_ioctl(
struct file *
f,
unsigned int cmd,
unsigned long arg)
405 error = jsf_ioctl_erase(arg);
408 error = jsf_ioctl_program(argp);
416 static int jsf_mmap(
struct file * file,
struct vm_area_struct * vma)
421 static int jsf_open(
struct inode *
inode,
struct file * filp)
424 if (jsf0.base == 0) {
437 static int jsf_release(
struct inode *inode,
struct file *file)
448 .unlocked_ioctl = jsf_ioctl,
451 .release = jsf_release,
456 static const struct block_device_operations jsfd_fops = {
460 static int jsflash_init(
void)
470 if (node != 0 && (
s32)node != -1) {
472 (
char *)&
reg0,
sizeof(
reg0)) == -1) {
473 printk(
"jsflash: no \"reg\" property\n");
476 if (
reg0.which_io != 0) {
477 printk(
"jsflash: bus number nonzero: 0x%x:%x\n",
486 if ((
reg0.phys_addr >> 24) != 0x20) {
487 printk(
"jsflash: suspicious address: 0x%x:%x\n",
492 if ((
int)
reg0.reg_size <= 0) {
493 printk(
"jsflash: bad size 0x%x\n", (
int)
reg0.reg_size);
498 printk(
"jsflash: no /flash-memory node, use PROLL >= 12\n");
500 if (
strcmp (banner,
"JavaStation-NC") != 0 &&
501 strcmp (banner,
"JavaStation-E") != 0) {
505 reg0.phys_addr = 0x20400000;
506 reg0.reg_size = 0x00800000;
516 if (jsf0.base == 0) {
524 jsf->
id.size = 0x01000000;
527 jsf->
dv[0].dbase = jsf->
base;
528 jsf->
dv[0].dsize = jsf->
size;
529 jsf->
dv[1].dbase = jsf->
base + 1024;
530 jsf->
dv[1].dsize = jsf->
size - 1024;
532 jsf->
dv[2].dsize = 0x01000000;
534 printk(
"Espresso Flash @0x%lx [%d MB]\n", jsf->
base,
535 (
int) (jsf->
size / (1024*1024)));
550 static int jsfd_init(
void)
562 for (i = 0; i <
JSF_MAX; i++) {
581 for (i = 0; i <
JSF_MAX; i++) {
582 struct gendisk *disk = jsfd_disk[
i];
588 disk->first_minor =
i;
589 sprintf(disk->disk_name,
"jsfd%d", i);
590 disk->fops = &jsfd_fops;
591 set_capacity(disk, jdp->
dsize >> 9);
592 disk->private_data = jdp;
593 disk->queue = jsf_queue;
606 static int __init jsflash_init_module(
void) {
609 if ((rc = jsflash_init()) == 0) {
616 static void __exit jsflash_cleanup_module(
void)
620 for (i = 0; i <
JSF_MAX; i++) {
626 printk(
"jsf0: cleaning busy unit\n");