summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/arch/unix/blk.c
blob: d0f5c6a42cb8fb82e8f262dc2ee7ae5cefcd9b31 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 *  <arch/unix/blk.c>
 *
 *	block device emulation for unix hosts
 *
 *   Copyright (C) 2004 Stefan Reinauer <stepan@openbios.org>
 *
 *   This program is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU General Public License
 *   version 2
 *
 */

#include "config.h"
#include "libopenbios/bindings.h"
#include "blk.h"

typedef struct {
	int	unit;
	int	channel;
} blk_data_t;


DECLARE_NODE( blk, INSTALL_OPEN, sizeof(blk_data_t), "+/unix/block/disk" );

static void
blk_open( blk_data_t *pb )
{
	phandle_t ph;

	fword("my-unit");

	pb->unit = POP();
	pb->channel = 0;	/* FIXME */

	selfword("open-deblocker");

	/* interpose disk-label */
	ph = find_dev("/packages/disk-label");
	fword("my-args");
	PUSH_ph( ph );
	fword("interpose");

	/* printk("osi-blk: open %d\n", pb->unit ); */

	PUSH( -1 );
}

static void
blk_close( __attribute__((unused)) blk_data_t *pb )
{
	selfword("close-deblocker");
}


/* ( buf blk nblks -- actual ) */
static void
blk_read_blocks( blk_data_t *pb )
{
	cell i, n = POP();
	cell blk = POP();
	char *dest = (char*)POP();

	// printk("blk_read_blocks %x block=%d n=%d\n", (ucell)dest, blk, n );

	for( i=0; i<n; ) {
		char buf[4096];
		ucell m = MIN( n-i, sizeof(buf)/512 );

		if( read_from_disk(pb->channel, pb->unit, blk+i, (ucell)buf, m*512) < 0 ) {
			printk("read_from_disk: error\n");
			RET(0);
		}
		memcpy( dest, buf, m * 512 );
		i += m;
		dest += m * 512;
	}
	PUSH( n );
}

/* ( -- bs ) */
static void
blk_block_size( __attribute__((unused)) blk_data_t *pb )
{
	PUSH( 512 );
}

/* ( -- maxbytes ) */
static void
blk_max_transfer( __attribute__((unused)) blk_data_t *pb )
{
	PUSH( 1024*1024 );
}

static void
blk_initialize( __attribute__((unused)) blk_data_t *pb )
{
	fword("is-deblocker");
}


NODE_METHODS( blk ) = {
	{ NULL,			blk_initialize	},
	{ "open",		blk_open	},
	{ "close",		blk_close	},
	{ "read-blocks",	blk_read_blocks	},
	{ "block-size",		blk_block_size	},
	{ "max-transfer",	blk_max_transfer},
};

void
blk_init( void )
{
	REGISTER_NODE( blk );
}