3 #include <linux/module.h>
4 #include <linux/smp_lock.h>
5 #include <linux/types.h>
6 #include <linux/errno.h>
7 #include <linux/miscdevice.h>
8 #include <linux/fcntl.h>
9 #include <linux/poll.h>
10 #include <linux/init.h>
11 #include <linux/string.h>
12 #include <linux/genhd.h>
13 #include <linux/blkdev.h>
14 #include <asm/uaccess.h>
15 #include <asm/pgtable.h>
18 #include <asm/oplib.h>
20 #include <asm/jsflash.h> /* ioctl arguments. <linux/> ?? */
21 #define JSFIDSZ (sizeof(struct jsflash_ident_arg))
22 #define JSFPRGSZ (sizeof(struct jsflash_program_arg))
25 * Our device numbers have no business in system headers.
26 * The only thing a user knows is the device name /dev/jsflash.
28 * Block devices are laid out like this:
29 * minor+0 - Bootstrap, for 8MB SIMM 0x20400000[0x800000]
30 * minor+1 - Filesystem to mount, normally 0x20400400[0x7ffc00]
31 * minor+2 - Whole flash area for any case... 0x20000000[0x01000000]
32 * Total 3 minors per flash device.
34 * It is easier to have static size vectors, so we define
35 * a total minor range JSF_MAX, which must cover all minors.
37 /* character device */
38 #define JSF_MINOR 178 /* 178 is registered with hpa */
40 #define JSF_MAX 3 /* 3 minors wasted total so far. */
41 #define JSF_NPART 3 /* 3 minors per flash device */
42 #define JSF_PART_BITS 2 /* 2 bits of minors to cover JSF_NPART */
43 #define JSF_PART_MASK 0x3 /* 2 bits mask */
47 * We could ioremap(), but it's easier this way.
49 static unsigned int jsf_inl(unsigned long addr
)
53 __asm__
__volatile__("lda [%1] %2, %0\n\t" :
55 "r" (addr
), "i" (ASI_M_BYPASS
));
59 static void jsf_outl(unsigned long addr
, __u32 data
)
62 __asm__
__volatile__("sta %0, [%1] %2\n\t" : :
63 "r" (data
), "r" (addr
), "i" (ASI_M_BYPASS
) :
79 unsigned long busy
; /* In use? */
80 struct jsflash_ident_arg id
;
81 /* int mbase; */ /* Minor base, typically zero */
82 struct jsfd_part dv
[JSF_NPART
];
86 * We do not map normal memory or obio as a safety precaution.
87 * But offsets are real, for ease of userland programming.
89 #define JSF_BASE_TOP 0x30000000
90 #define JSF_BASE_ALL 0x20000000
92 #define JSF_BASE_JK 0x20400000
96 static struct gendisk
*jsfd_disk
[JSF_MAX
];
99 * Let's pretend we may have several of these...
101 static struct jsflash jsf0
;
103 static void jsf_wait(unsigned long p
) {
109 if ((x1
& 0x40404040) == (x2
& 0x40404040)) return;
114 * Programming will only work if Flash is clean,
115 * we leave it to the programmer application.
117 * AMD must be programmed one byte at a time;
118 * thus, Simple Tech SIMM must be written 4 bytes at a time.
120 * Write waits for the chip to become ready after the write
121 * was finished. This is done so that application would read
122 * consistent data after the write is done.
124 static void jsf_write4(unsigned long fa
, u32 data
) {
126 jsf_outl(fa
, 0xAAAAAAAA); /* Unlock 1 Write 1 */
127 jsf_outl(fa
, 0x55555555); /* Unlock 1 Write 2 */
128 jsf_outl(fa
, 0xA0A0A0A0); /* Byte Program */
136 static void jsfd_read(char *buf
, unsigned long p
, size_t togo
) {
151 static void jsfd_do_request(struct request_queue
*q
)
155 req
= blk_fetch_request(q
);
157 struct jsfd_part
*jdp
= req
->rq_disk
->private_data
;
158 unsigned long offset
= blk_rq_pos(req
) << 9;
159 size_t len
= blk_rq_cur_bytes(req
);
162 if ((offset
+ len
) > jdp
->dsize
)
165 if (rq_data_dir(req
) != READ
) {
166 printk(KERN_ERR
"jsfd: write\n");
170 if ((jdp
->dbase
& 0xff000000) != 0x20000000) {
171 printk(KERN_ERR
"jsfd: bad base %x\n", (int)jdp
->dbase
);
175 jsfd_read(req
->buffer
, jdp
->dbase
+ offset
, len
);
178 if (!__blk_end_request_cur(req
, err
))
179 req
= blk_fetch_request(q
);
184 * The memory devices use the full 32/64 bits of the offset, and so we cannot
185 * check against negative addresses: they are ok. The return value is weird,
186 * though, in that case (0).
188 * also note that seeking relative to the "end of file" isn't supported:
189 * it has no meaning, so it returns -EINVAL.
191 static loff_t
jsf_lseek(struct file
* file
, loff_t offset
, int orig
)
198 file
->f_pos
= offset
;
202 file
->f_pos
+= offset
;
213 * OS SIMM Cannot be read in other size but a 32bits word.
215 static ssize_t
jsf_read(struct file
* file
, char __user
* buf
,
216 size_t togo
, loff_t
*ppos
)
218 unsigned long p
= *ppos
;
219 char __user
*tmp
= buf
;
226 if (p
< JSF_BASE_ALL
|| p
>= JSF_BASE_TOP
) {
230 if ((p
+ togo
) < p
/* wrap */
231 || (p
+ togo
) >= JSF_BASE_TOP
) {
232 togo
= JSF_BASE_TOP
- p
;
235 if (p
< JSF_BASE_ALL
&& togo
!= 0) {
237 * Implementation of clear_user() calls __bzero
238 * without regard to modversions,
239 * so we cannot build a module.
247 if (copy_to_user(tmp
, b
.s
, 4))
258 static ssize_t
jsf_write(struct file
* file
, const char __user
* buf
,
259 size_t count
, loff_t
*ppos
)
266 static int jsf_ioctl_erase(unsigned long arg
)
270 /* p = jsf0.base; hits wrong bank */
273 jsf_outl(p
, 0xAAAAAAAA); /* Unlock 1 Write 1 */
274 jsf_outl(p
, 0x55555555); /* Unlock 1 Write 2 */
275 jsf_outl(p
, 0x80808080); /* Erase setup */
276 jsf_outl(p
, 0xAAAAAAAA); /* Unlock 2 Write 1 */
277 jsf_outl(p
, 0x55555555); /* Unlock 2 Write 2 */
278 jsf_outl(p
, 0x10101010); /* Chip erase */
286 * Program a block of flash.
287 * Very simple because we can do it byte by byte anyway.
289 static int jsf_ioctl_program(void __user
*arg
)
291 struct jsflash_program_arg abuf
;
300 if (copy_from_user(&abuf
, arg
, JSFPRGSZ
))
304 if ((togo
& 3) || (p
& 3)) return -EINVAL
;
306 uptr
= (char __user
*) (unsigned long) abuf
.data
;
309 if (copy_from_user(&b
.s
[0], uptr
, 4))
319 static long jsf_ioctl(struct file
*f
, unsigned int cmd
, unsigned long arg
)
323 void __user
*argp
= (void __user
*)arg
;
325 if (!capable(CAP_SYS_ADMIN
)) {
331 if (copy_to_user(argp
, &jsf0
.id
, JSFIDSZ
)) {
337 error
= jsf_ioctl_erase(arg
);
339 case JSFLASH_PROGRAM
:
340 error
= jsf_ioctl_program(argp
);
348 static int jsf_mmap(struct file
* file
, struct vm_area_struct
* vma
)
353 static int jsf_open(struct inode
* inode
, struct file
* filp
)
356 if (jsf0
.base
== 0) {
360 if (test_and_set_bit(0, (void *)&jsf0
.busy
) != 0) {
369 static int jsf_release(struct inode
*inode
, struct file
*file
)
375 static const struct file_operations jsf_fops
= {
376 .owner
= THIS_MODULE
,
380 .unlocked_ioctl
= jsf_ioctl
,
383 .release
= jsf_release
,
386 static struct miscdevice jsf_dev
= { JSF_MINOR
, "jsflash", &jsf_fops
};
388 static const struct block_device_operations jsfd_fops
= {
389 .owner
= THIS_MODULE
,
392 static int jsflash_init(void)
398 struct linux_prom_registers reg0
;
400 node
= prom_getchild(prom_root_node
);
401 node
= prom_searchsiblings(node
, "flash-memory");
402 if (node
!= 0 && node
!= -1) {
403 if (prom_getproperty(node
, "reg",
404 (char *)®0
, sizeof(reg0
)) == -1) {
405 printk("jsflash: no \"reg\" property\n");
408 if (reg0
.which_io
!= 0) {
409 printk("jsflash: bus number nonzero: 0x%x:%x\n",
410 reg0
.which_io
, reg0
.phys_addr
);
414 * Flash may be somewhere else, for instance on Ebus.
415 * So, don't do the following check for IIep flash space.
417 if ((int)reg0
.reg_size
<= 0) {
418 printk("jsflash: bad size 0x%x\n", (int)reg0
.reg_size
);
422 printk("jsflash: no /flash-memory node, use PROLL >= 12\n");
423 prom_getproperty(prom_root_node
, "banner-name", banner
, 128);
424 if (strcmp (banner
, "JavaStation-NC") != 0 &&
425 strcmp (banner
, "JavaStation-E") != 0) {
429 reg0
.phys_addr
= 0x20400000;
430 reg0
.reg_size
= 0x00800000;
433 /* Let us be really paranoid for modifications to probing code. */
434 /* extern enum sparc_cpu sparc_cpu_model; */ /* in <asm/system.h> */
435 if (sparc_cpu_model
!= sun4m
) {
436 /* We must be on sun4m because we use MMU Bypass ASI. */
440 if (jsf0
.base
== 0) {
443 jsf
->base
= reg0
.phys_addr
;
444 jsf
->size
= reg0
.reg_size
;
446 jsf
->id
.off
= JSF_BASE_ALL
;
447 jsf
->id
.size
= 0x01000000; /* 16M - all segments */
448 strcpy(jsf
->id
.name
, "Krups_all");
450 jsf
->dv
[0].dbase
= jsf
->base
;
451 jsf
->dv
[0].dsize
= jsf
->size
;
452 jsf
->dv
[1].dbase
= jsf
->base
+ 1024;
453 jsf
->dv
[1].dsize
= jsf
->size
- 1024;
454 jsf
->dv
[2].dbase
= JSF_BASE_ALL
;
455 jsf
->dv
[2].dsize
= 0x01000000;
457 printk("Espresso Flash @0x%lx [%d MB]\n", jsf
->base
,
458 (int) (jsf
->size
/ (1024*1024)));
461 if ((rc
= misc_register(&jsf_dev
)) != 0) {
462 printk(KERN_ERR
"jsf: unable to get misc minor %d\n",
471 static struct request_queue
*jsf_queue
;
473 static int jsfd_init(void)
475 static DEFINE_SPINLOCK(lock
);
477 struct jsfd_part
*jdp
;
485 for (i
= 0; i
< JSF_MAX
; i
++) {
486 struct gendisk
*disk
= alloc_disk(1);
492 if (register_blkdev(JSFD_MAJOR
, "jsfd")) {
497 jsf_queue
= blk_init_queue(jsfd_do_request
, &lock
);
500 unregister_blkdev(JSFD_MAJOR
, "jsfd");
504 for (i
= 0; i
< JSF_MAX
; i
++) {
505 struct gendisk
*disk
= jsfd_disk
[i
];
506 if ((i
& JSF_PART_MASK
) >= JSF_NPART
) continue;
507 jsf
= &jsf0
; /* actually, &jsfv[i >> JSF_PART_BITS] */
508 jdp
= &jsf
->dv
[i
&JSF_PART_MASK
];
510 disk
->major
= JSFD_MAJOR
;
511 disk
->first_minor
= i
;
512 sprintf(disk
->disk_name
, "jsfd%d", i
);
513 disk
->fops
= &jsfd_fops
;
514 set_capacity(disk
, jdp
->dsize
>> 9);
515 disk
->private_data
= jdp
;
516 disk
->queue
= jsf_queue
;
518 set_disk_ro(disk
, 1);
523 put_disk(jsfd_disk
[i
]);
527 MODULE_LICENSE("GPL");
529 static int __init
jsflash_init_module(void) {
532 if ((rc
= jsflash_init()) == 0) {
539 static void __exit
jsflash_cleanup_module(void)
543 for (i
= 0; i
< JSF_MAX
; i
++) {
544 if ((i
& JSF_PART_MASK
) >= JSF_NPART
) continue;
545 del_gendisk(jsfd_disk
[i
]);
546 put_disk(jsfd_disk
[i
]);
549 printk("jsf0: cleaning busy unit\n");
553 misc_deregister(&jsf_dev
);
554 unregister_blkdev(JSFD_MAJOR
, "jsfd");
555 blk_cleanup_queue(jsf_queue
);
558 module_init(jsflash_init_module
);
559 module_exit(jsflash_cleanup_module
);