/* * * * block device emulation for unix hosts * * Copyright (C) 2004 Stefan Reinauer * * 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; ichannel, 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 ); }