Пример #1
0
static int 
efipart_strategy(void *devdata, int rw, daddr_t blk, size_t size, char *buf,
    size_t *rsize)
{
	struct devdesc *dev = (struct devdesc *)devdata;
	EFI_BLOCK_IO *blkio;
	off_t off;
	char *blkbuf;
	size_t blkoff, blksz;
	int error;

	if (dev == NULL || blk < 0)
		return (EINVAL);

	blkio = dev->d_opendata;
	if (blkio == NULL)
		return (ENXIO);

	if (size == 0 || (size % 512) != 0)
		return (EIO);

	if (rsize != NULL)
		*rsize = size;

	if (blkio->Media->BlockSize == 512)
		return (efipart_readwrite(blkio, rw, blk, size / 512, buf));

	/*
	 * The block size of the media is not 512B per sector.
	 */
	blkbuf = malloc(blkio->Media->BlockSize);
	if (blkbuf == NULL)
		return (ENOMEM);

	error = 0;
	off = blk * 512;
	blk = off / blkio->Media->BlockSize;
	blkoff = off % blkio->Media->BlockSize;
	blksz = blkio->Media->BlockSize - blkoff;
	while (size > 0) {
		error = efipart_readwrite(blkio, rw, blk, 1, blkbuf);
		if (error)
			break;
		if (size < blksz)
			blksz = size;
		bcopy(blkbuf + blkoff, buf, blksz);
		buf += blksz;
		size -= blksz;
		blk++;
		blkoff = 0;
		blksz = blkio->Media->BlockSize;
	}

	free(blkbuf);
	return (error);
}
Пример #2
0
static int
efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t offset,
    size_t size, char *buf, size_t *rsize)
{
	struct devdesc *dev = (struct devdesc *)devdata;
	EFI_BLOCK_IO *blkio;
	off_t off;
	char *blkbuf;
	size_t blkoff, blksz;
	int error;

	if (dev == NULL || blk < 0)
		return (EINVAL);

	blkio = dev->d_opendata;
	if (blkio == NULL)
		return (ENXIO);

	if (size == 0 || (size % 512) != 0)
		return (EIO);

	off = blk * 512;
	/* make sure we don't read past disk end */
	if ((off + size) / blkio->Media->BlockSize - 1 >
	    blkio->Media->LastBlock) {
		size = blkio->Media->LastBlock + 1 -
		    off / blkio->Media->BlockSize;
		size = size * blkio->Media->BlockSize;
	}

	if (rsize != NULL)
		*rsize = size;

        if ((size % blkio->Media->BlockSize == 0) &&
	    ((blk * 512) % blkio->Media->BlockSize == 0))
                return (efipart_readwrite(blkio, rw,
		    blk * 512 / blkio->Media->BlockSize,
		    size / blkio->Media->BlockSize, buf));

	/*
	 * The block size of the media is not a multiple of I/O.
	 */
	blkbuf = malloc(blkio->Media->BlockSize);
	if (blkbuf == NULL)
		return (ENOMEM);

	error = 0;
	blk = off / blkio->Media->BlockSize;
	blkoff = off % blkio->Media->BlockSize;
	blksz = blkio->Media->BlockSize - blkoff;
	while (size > 0) {
		error = efipart_readwrite(blkio, rw, blk, 1, blkbuf);
		if (error)
			break;
		if (size < blksz)
			blksz = size;
		bcopy(blkbuf + blkoff, buf, blksz);
		buf += blksz;
		size -= blksz;
		blk++;
		blkoff = 0;
		blksz = blkio->Media->BlockSize;
	}

	free(blkbuf);
	return (error);
}