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