예제 #1
0
파일: dwipe.c 프로젝트: sTeeLM/dwipe1_5
/** write_sectors in write.c has BUG!!!
 * write_sectors - write several sectors from disk
 * @drive_info:		driveinfo struct describing the disk
 * @lba:		Position to write
 * @data:		Buffer to write
 * @size:		Size of the buffer (number of sectors)
 *
 * Return the number of sectors write on success or -1 on failure.
 * errno_disk contains the error number.
 **/
static int dwipe_write_sectors(const struct driveinfo *drive_info, const unsigned int lba,
		  const void *data, const int size)
{
    com32sys_t inreg, outreg;
    struct ebios_dapa *dapa = __com32.cs_bounce;
    void *buf = (char *)__com32.cs_bounce + size * SECTOR;

    memcpy(buf, data, size * SECTOR);
    memset(&inreg, 0, sizeof inreg);

    if (drive_info->ebios) {
	dapa->len = sizeof(*dapa);
	dapa->count = size;
	dapa->off = OFFS(buf);
	dapa->seg = SEG(buf);
	dapa->lba = lba;

	inreg.esi.w[0] = OFFS(dapa);
	inreg.ds = SEG(dapa);
	inreg.edx.b[0] = drive_info->disk;
	inreg.eax.w[0] = 0x4300;	/* Extended write */
    } else {
	unsigned int c, h, s;

	if (!drive_info->cbios) {	// XXX errno
	    /* We failed to get the geometry */
	    if (lba)
		return -1;	/* Can only write MBR */

	    s = 1;
	    h = 0;
	    c = 0;
	} else
	    lba_to_chs(drive_info, lba, &s, &h, &c);

	// XXX errno
	if (s > 63 || h > 256 || c > 1023)
	    return -1;

	inreg.eax.w[0] = 0x0301;	/* Write one sector */
	inreg.ecx.b[1] = c & 0xff;
	inreg.ecx.b[0] = s + (c >> 6);
	inreg.edx.b[1] = h;
	inreg.edx.b[0] = drive_info->disk;
	inreg.ebx.w[0] = OFFS(buf);
	inreg.es = SEG(buf);
    }

    /* Perform the write */
    if (int13_retry(&inreg, &outreg)) {
	errno_disk = outreg.eax.b[1];
	return -1;		/* Give up */
    } else
	return size;
}
예제 #2
0
파일: read.c 프로젝트: 1stMaster/syslinux
/**
 * read_sectors - read several sectors from disk
 * @drive_info:		driveinfo struct describing the disk
 * @data:		Pre-allocated buffer for output
 * @lba:		Position to read
 * @sectors:		Number of sectors to read
 *
 * Return the number of sectors read on success or -1 on failure.
 * errno_disk contains the error number.
 **/
int read_sectors(struct driveinfo *drive_info, void *data,
		 const unsigned int lba, const int sectors)
{
    com32sys_t inreg, outreg;
    struct ebios_dapa *dapa = __com32.cs_bounce;
    void *buf = (char *)__com32.cs_bounce + sectors * SECTOR;
    char *bufp = data;

    if (get_drive_parameters(drive_info) == -1)
	return -1;

    memset(&inreg, 0, sizeof inreg);

    if (drive_info->ebios) {
	dapa->len = sizeof(*dapa);
	dapa->count = sectors;
	dapa->off = OFFS(buf);
	dapa->seg = SEG(buf);
	dapa->lba = lba;

	inreg.esi.w[0] = OFFS(dapa);
	inreg.ds = SEG(dapa);
	inreg.edx.b[0] = drive_info->disk;
	inreg.eax.b[1] = 0x42;	/* Extended read */
    } else {
	unsigned int c, h, s;

	if (!drive_info->cbios) {	// XXX errno
	    /* We failed to get the geometry */
	    if (lba)
		return -1;	/* Can only read MBR */

	    s = 1;
	    h = 0;
	    c = 0;
	} else
	    lba_to_chs(drive_info, lba, &s, &h, &c);

	// XXX errno
	if (s > 63 || h > 256 || c > 1023)
	    return -1;

	inreg.eax.w[0] = 0x0201;	/* Read one sector */
	inreg.ecx.b[1] = c & 0xff;
	inreg.ecx.b[0] = s + (c >> 6);
	inreg.edx.b[1] = h;
	inreg.edx.b[0] = drive_info->disk;
	inreg.ebx.w[0] = OFFS(buf);
	inreg.es = SEG(buf);
    }

    /* Perform the read */
    if (int13_retry(&inreg, &outreg)) {
	errno_disk = outreg.eax.b[1];
	return -1;		/* Give up */
    }

    memcpy(bufp, buf, sectors * SECTOR);

    return sectors;
}
예제 #3
0
파일: fdisk.c 프로젝트: HarryR/sanos
void add_partition() {
  int off, noff, poff;
  int size, psize;
  int i, partno, type;
  int cyl, head, sect;
  int ch;
  char str[128];

  // Get partition number
  ch = ask("partition number (0-3)? ", "0123\n");
  if (ch == '\n') return;
  partno = ch - '0';
  if (mbr.parttab[partno].systid != 0) {
    printf("error: partition already used\n");
    return;
  }

  // Get partition size
  printf("partition size (KB) (*=max size)? ");
  gets(str);
  size = *str == '*' ? -1 : atoi(str) * 1024 / geom.sectorsize;

  // Get partition type
  printf("partition type (default %x)? ", SANOS_BOOT_PARTITION_ID);
  gets(str);
  type = *str ? strtol(str, NULL, 16) : SANOS_BOOT_PARTITION_ID;

  // Adjust size to be a multiple of the sectors per track
  if (size > 0) {
    size = ALIGN(size, geom.spt);
    if (size < geom.spt) {
      printf("partition size must be at least %d sectors\n", geom.spt);
      return;
    }
  }

  // Search for the next partition in the table
  for (i = partno + 1; i < 4; i++) {
    if (mbr.parttab[i].systid != 0) break;
  }

  if (i >= 4) {
    noff = -1;
  } else {
    noff = mbr.parttab[i].relsect;
  }

  // Search for the previous partition in the table
  for (i = partno - 1; i >= 0; i--) {
    if (mbr.parttab[i].systid != 0) break;
  }

  if (i < 0) {
    poff = -1;
  } else {
    poff = mbr.parttab[i].relsect;
    psize = mbr.parttab[i].numsect;
  }

  // Compute offset of new partition
  if (poff < 0) {
    off = geom.spt;
  } else {
    off = ALIGN(poff + psize, geom.spt);
  }

  // Check whether specified partition will fit, or calculate maximum partition size
  if (size < 0) {
    size = (noff < 0 ? geom.sectors : noff) - off;
  } else {
    if (off + size > (noff < 0 ? geom.sectors : noff)) {
      printf("partition size too large\n");
      return;
    }
  }
  printf("add partition %d offset %d size %d KB\n", partno, off, size / (1024 / geom.sectorsize));

  mbr.parttab[partno].relsect = off;
  mbr.parttab[partno].numsect = size;
  mbr.parttab[partno].systid = type;

  lba_to_chs(off, &cyl, &head, &sect);
  mbr.parttab[partno].begcyl = cyl & 0xFF;
  mbr.parttab[partno].beghead = head;
  mbr.parttab[partno].begsect = sect | ((cyl >> 8) << 6);

  lba_to_chs(off + size - 1, &cyl, &head, &sect);
  mbr.parttab[partno].endcyl = cyl & 0xFF;
  mbr.parttab[partno].endhead = head;
  mbr.parttab[partno].endsect = sect | ((cyl >> 8) << 6);
}
예제 #4
0
파일: fd.c 프로젝트: huangrui/Thunix
/*
 * And now, it's time to implenent the read or write function, that's
 * all the floppy driver mean!
 * 
 * Read/Write one sector once.
 */
static int floppy_rw(int sector, char *buf, int command)
{
	int head;
	char *dma_buffer = buf;
	static char tmp_dma_buffer[512];

	//LOG("TMP dma buffer: %p\n", tmp_dma_buffer);

        lba_to_chs(sector, &head, &track, &sector);
	LOG("head: %d \ttrack: %d \tsector: %d\n", head, track, sector);

        /* turn it on if not */
        motor_on();

        if (inb_p(FD_DIR) & 0x80) {
                changed = TRUE;
                seek(1, head);        /* clear "disk change" status */
                recalibrate();
                motor_off();
                printk("floppy_rw: Disk change detected. You are going to DIE:)\n");
                
                pause();  /* just put it in DIE */
        }

        /* move head to the right track */
        if (!seek(track, head)) {
                motor_off();
                printk("floppy_rw: Error seeking to track#%d\n", track);
                return FALSE;
        }
                
	if ((unsigned long)buf >= 0xff000) {
		dma_buffer = tmp_dma_buffer;
		if (command == FD_WRITE)
			memcpy(dma_buffer, buf, 512);
	}

        setup_DMA((unsigned long)dma_buffer, command);

        send_byte(command);
        send_byte(head<<2 | 0);
        send_byte(track);
        send_byte(head);
	send_byte(sector);
        send_byte(2);           /* sector size = 125 * 2^(2) */
        send_byte(floppy.sector);
        send_byte(0);
        send_byte(0xFF);        /* sector size(only two valid vaules, 0xff when n!=0*/

        if (!wait_fdc(FALSE)) {
                //LOG("wait fdc failed!\n");
                //return 0;
                /*
                printk("Time out, trying operation again after reset() \n");
                reset();
                return floppy_rw(sector, buf, command);
                */
        }

        motor_off();

        if (/*res != 7 || */(ST0 & 0xf8) || (ST1 & 0xbf) || (ST2 & 0x73) ) {
                if (ST1 & 0x02) 
                        LOG("Drive is write protected!\n");
                else
                        LOG("floppy_rw: bad interrupt!\n");

                return -EIO;
        } else {
		LOG("floppy_rw: OK\n");
		if ((unsigned long)buf >= 0xff000 && command == FD_READ)
			memcpy(buf, dma_buffer, 512);
		return 0;
        }
}