Logo Search packages:      
Sourcecode: acorn-fdisk version File versions  Download package

write.c

/*
 * blkio/read.c
 *
 * Copyright (C) 1998 Russell King
 *
 * The block I/O interface allows an OS-independent method to access devices
 *
 * Write data to device on RiscOS architecture
 */
#include "util/debug.h"
#include "util/error.h"
#include "blkio.h"
#include "filecore.h"

#ifdef RISCOS
#include "!Swi.h"

static u_int write_block(blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks)
{
  _kernel_oserror *ret;
  u_int swino, sector, nr, limit, res = 0;
  const char *what, *swiname;

  if (blkio->swi_sectorop) {
    swino   = blkio->swi_sectorop;
    sector  = block * (blkio->blocksize >> blkio->disc_record->d.log2secsize);
    nr      = nr_blocks * blkio->blocksize;
    limit   = 0x20000000;
    what    = "sector";
    swiname = "sectorop";
  } else {
    swino   = blkio->swi_discop;
    sector  = block * blkio->blocksize;
    nr      = nr_blocks * blkio->blocksize;
    limit   = 0x20000000 / blkio->blocksize;
    what    = "discaddr";
    swiname = "discop";
  }

  do {
    if (block >= limit) {
      set_error ("Unable to write %s 0x%X above limit 0x%X", what, block, limit);
      break;
    }
    dbg_printf ("-%s: [r1=0x%X r2=0x%X r3=%p r4=0x%X]", swiname,
            (((unsigned int)blkio->disc_record) << 6)|2,
            (blkio->drive << 29) | (sector & 0x1fffffff), data, nr);

    ret = swix (swino, rin(r1|r2|r3|r4), (((unsigned int)blkio->disc_record) << 6)|2,
            (blkio->drive << 29) | (sector & 0x1fffffff), data, nr);
    if (ret) {
      set_error ("%s", ret->errmess);
      break;
    }

    res = nr_blocks;
  } while (0);

  return res;
}
#endif

#ifdef UNIX
#include <unistd.h>
#include <syscall.h>

#undef SYS__llseek
#define SYS__llseek (__NR__llseek - __NR_SYSCALL_BASE)

static inline
_syscall5(int,_llseek,int,fd,u_int,off_high,u_int,off_low,loff_t *,loff,int,whence);

static loff_t my_llseek(int fd, loff_t off, int whence)
{
  u_int off_high, off_low;

  off_high = off >> 32;
  off_low = off & 0xffffffff;

  _llseek(fd, off_high, off_low, &off, whence);

  return off;
}

static u_int write_block(blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks)
{
  u_int len, res = 0;
  loff_t loff;

  loff = (loff_t)block * blkio->blocksize;
  len = nr_blocks * blkio->blocksize;

  do {
    if (my_llseek(blkio->fd, loff, SEEK_SET) != loff)
      break;

    if (write(blkio->fd, data, len) != len)
      break;

    res = nr_blocks;
  } while (0);

  return res;
}
#endif

/* Function: u_int blkio_write (blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks)
 * Purpose : Write `nr_blocks' blocks starting at `block' from the device previously opened
 *           with blkio_open into memory area `data'
 * Params  : blkio     - structure returned by blkio_open
 *         : data      - memory area to write data from
 *         : block     - block number to write
 *         : nr_blocks - number of blocks to write
 * Returns : number of blocks actually written
 */
u_int blkio_write (blkio_t *blkio, const void *data, blk_t block, u_int nr_blocks)
{
  u_int res;

  dbg_printf ("blkio_write(%p 0x%X +0x%X)", data, block, nr_blocks);
  dbg_level_up ();

  res = write_block(blkio, data, block, nr_blocks);

  dbg_level_down ();
  dbg_printf ("ret=%d", res);

  return res;
}

Generated by  Doxygen 1.6.0   Back to index