1 /*
2  *  <arch/unix/blk.c>
3  *
4  *	block device emulation for unix hosts
5  *
6  *   Copyright (C) 2004 Stefan Reinauer
7  *
8  *   This program is free software; you can redistribute it and/or
9  *   modify it under the terms of the GNU General Public License
10  *   version 2
11  *
12  */
13 
14 #include "config.h"
15 #include "libopenbios/bindings.h"
16 #include "blk.h"
17 
18 typedef struct {
19 	int	unit;
20 	int	channel;
21 } blk_data_t;
22 
23 
24 DECLARE_NODE( blk, INSTALL_OPEN, sizeof(blk_data_t), "+/unix/block/disk" );
25 
26 static void
blk_open(blk_data_t * pb)27 blk_open( blk_data_t *pb )
28 {
29 	phandle_t ph;
30 
31 	fword("my-unit");
32 
33 	pb->unit = POP();
34 	pb->channel = 0;	/* FIXME */
35 
36 	selfword("open-deblocker");
37 
38 	/* interpose disk-label */
39 	ph = find_dev("/packages/disk-label");
40 	fword("my-args");
41 	PUSH_ph( ph );
42 	fword("interpose");
43 
44 	/* printk("osi-blk: open %d\n", pb->unit ); */
45 
46 	PUSH( -1 );
47 }
48 
49 static void
blk_close(blk_data_t * pb)50 blk_close( __attribute__((unused)) blk_data_t *pb )
51 {
52 	selfword("close-deblocker");
53 }
54 
55 
56 /* ( buf blk nblks -- actual ) */
57 static void
blk_read_blocks(blk_data_t * pb)58 blk_read_blocks( blk_data_t *pb )
59 {
60 	cell i, n = POP();
61 	cell blk = POP();
62 	char *dest = (char*)POP();
63 
64 	// printk("blk_read_blocks %x block=%d n=%d\n", (ucell)dest, blk, n );
65 
66 	for( i=0; i<n; ) {
67 		char buf[4096];
68 		ucell m = MIN( n-i, sizeof(buf)/512 );
69 
70 		if( read_from_disk(pb->channel, pb->unit, blk+i, (ucell)buf, m*512) < 0 ) {
71 			printk("read_from_disk: error\n");
72 			RET(0);
73 		}
74 		memcpy( dest, buf, m * 512 );
75 		i += m;
76 		dest += m * 512;
77 	}
78 	PUSH( n );
79 }
80 
81 /* ( -- bs ) */
82 static void
blk_block_size(blk_data_t * pb)83 blk_block_size( __attribute__((unused)) blk_data_t *pb )
84 {
85 	PUSH( 512 );
86 }
87 
88 /* ( -- maxbytes ) */
89 static void
blk_max_transfer(blk_data_t * pb)90 blk_max_transfer( __attribute__((unused)) blk_data_t *pb )
91 {
92 	PUSH( 1024*1024 );
93 }
94 
95 static void
blk_initialize(blk_data_t * pb)96 blk_initialize( __attribute__((unused)) blk_data_t *pb )
97 {
98 	fword("is-deblocker");
99 }
100 
101 
102 NODE_METHODS( blk ) = {
103 	{ NULL,			blk_initialize	},
104 	{ "open",		blk_open	},
105 	{ "close",		blk_close	},
106 	{ "read-blocks",	blk_read_blocks	},
107 	{ "block-size",		blk_block_size	},
108 	{ "max-transfer",	blk_max_transfer},
109 };
110 
111 void
blk_init(void)112 blk_init( void )
113 {
114 	REGISTER_NODE( blk );
115 }
116