9
0
Fork 0

Merge branch 'for-next/block'

This commit is contained in:
Sascha Hauer 2013-06-02 12:35:47 +02:00
commit 5e7f855847
6 changed files with 130 additions and 13 deletions

View File

@ -176,7 +176,7 @@ static void *block_get(struct block_device *blk, int block)
return outdata; return outdata;
} }
static ssize_t block_read(struct cdev *cdev, void *buf, size_t count, static ssize_t block_op_read(struct cdev *cdev, void *buf, size_t count,
loff_t offset, unsigned long flags) loff_t offset, unsigned long flags)
{ {
struct block_device *blk = cdev->priv; struct block_device *blk = cdev->priv;
@ -253,7 +253,7 @@ static int block_put(struct block_device *blk, const void *buf, int block)
return 0; return 0;
} }
static ssize_t block_write(struct cdev *cdev, const void *buf, size_t count, static ssize_t block_op_write(struct cdev *cdev, const void *buf, size_t count,
loff_t offset, ulong flags) loff_t offset, ulong flags)
{ {
struct block_device *blk = cdev->priv; struct block_device *blk = cdev->priv;
@ -310,14 +310,14 @@ static ssize_t block_write(struct cdev *cdev, const void *buf, size_t count,
} }
#endif #endif
static int block_close(struct cdev *cdev) static int block_op_close(struct cdev *cdev)
{ {
struct block_device *blk = cdev->priv; struct block_device *blk = cdev->priv;
return writebuffer_flush(blk); return writebuffer_flush(blk);
} }
static int block_flush(struct cdev *cdev) static int block_op_flush(struct cdev *cdev)
{ {
struct block_device *blk = cdev->priv; struct block_device *blk = cdev->priv;
@ -325,12 +325,12 @@ static int block_flush(struct cdev *cdev)
} }
static struct file_operations block_ops = { static struct file_operations block_ops = {
.read = block_read, .read = block_op_read,
#ifdef CONFIG_BLOCK_WRITE #ifdef CONFIG_BLOCK_WRITE
.write = block_write, .write = block_op_write,
#endif #endif
.close = block_close, .close = block_op_close,
.flush = block_flush, .flush = block_op_flush,
.lseek = dev_lseek_default, .lseek = dev_lseek_default,
}; };
@ -387,3 +387,25 @@ int blockdevice_unregister(struct block_device *blk)
return 0; return 0;
} }
int block_read(struct block_device *blk, void *buf, int block, int num_blocks)
{
int ret;
ret = cdev_read(&blk->cdev, buf,
num_blocks << blk->blockbits,
(loff_t)block << blk->blockbits, 0);
return ret < 0 ? ret : 0;
}
int block_write(struct block_device *blk, void *buf, int block, int num_blocks)
{
int ret;
ret = cdev_write(&blk->cdev, buf,
num_blocks << blk->blockbits,
(loff_t)block << blk->blockbits, 0);
return ret < 0 ? ret : 0;
}

View File

@ -128,7 +128,7 @@ int parse_partition_table(struct block_device *blk)
pdesc = xzalloc(sizeof(*pdesc)); pdesc = xzalloc(sizeof(*pdesc));
buf = dma_alloc(SECTOR_SIZE * 2); buf = dma_alloc(SECTOR_SIZE * 2);
rc = blk->ops->read(blk, buf, 0, 2); rc = block_read(blk, buf, 0, 2);
if (rc != 0) { if (rc != 0) {
dev_err(blk->dev, "Cannot read MBR/partition table\n"); dev_err(blk->dev, "Cannot read MBR/partition table\n");
goto on_error; goto on_error;

View File

@ -1,5 +1,6 @@
config PARTITION_DISK config PARTITION_DISK
depends on PARTITION depends on PARTITION
depends on BLOCK
bool "DISK partition support" bool "DISK partition support"
help help
Add support for handling common partition tables on all kind of disk Add support for handling common partition tables on all kind of disk

View File

@ -16,6 +16,8 @@
#include <disks.h> #include <disks.h>
#include <init.h> #include <init.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <dma.h>
#include <linux/err.h>
#include "parser.h" #include "parser.h"
@ -40,6 +42,74 @@ static int disk_guess_size(struct device_d *dev, struct partition_entry *table)
return (int)size; return (int)size;
} }
static void *read_mbr(struct block_device *blk)
{
void *buf = dma_alloc(SECTOR_SIZE);
int ret;
ret = block_read(blk, buf, 0, 1);
if (ret) {
free(buf);
return NULL;
}
return buf;
}
static int write_mbr(struct block_device *blk, void *buf)
{
int ret;
ret = block_write(blk, buf, 0, 1);
if (ret)
return ret;
return block_flush(blk);
}
struct disk_signature_priv {
uint32_t signature;
struct block_device *blk;
};
static int dos_set_disk_signature(struct param_d *p, void *_priv)
{
struct disk_signature_priv *priv = _priv;
struct block_device *blk = priv->blk;
void *buf;
__le32 *disksigp;
int ret;
buf = read_mbr(blk);
if (!buf)
return -EIO;
disksigp = buf + 0x1b8;
*disksigp = cpu_to_le32(priv->signature);
ret = write_mbr(blk, buf);
free(buf);
return ret;
}
static int dos_get_disk_signature(struct param_d *p, void *_priv)
{
struct disk_signature_priv *priv = _priv;
struct block_device *blk = priv->blk;
void *buf;
buf = read_mbr(blk);
if (!buf)
return -EIO;
priv->signature = le32_to_cpup((__le32 *)(buf + 0x1b8));
return 0;
}
/** /**
* Check if a DOS like partition describes this block device * Check if a DOS like partition describes this block device
* @param blk Block device to register to * @param blk Block device to register to
@ -55,6 +125,7 @@ static void dos_partition(void *buf, struct block_device *blk,
struct partition pentry; struct partition pentry;
uint8_t *buffer = buf; uint8_t *buffer = buf;
int i; int i;
struct disk_signature_priv *dsp;
table = (struct partition_entry *)&buffer[446]; table = (struct partition_entry *)&buffer[446];
@ -74,6 +145,23 @@ static void dos_partition(void *buf, struct block_device *blk,
dev_dbg(blk->dev, "Skipping empty partition %d\n", i); dev_dbg(blk->dev, "Skipping empty partition %d\n", i);
} }
} }
dsp = xzalloc(sizeof(*dsp));
dsp->blk = blk;
/*
* This parameter contains the NT disk signature. This allows to
* to specify the Linux rootfs using the following syntax:
*
* root=PARTUUID=ssssssss-pp
*
* where ssssssss is a zero-filled hex representation of the 32-bit
* signature and pp is a zero-filled hex representation of the 1-based
* partition number.
*/
dev_add_param_int(blk->dev, "nt_signature",
dos_set_disk_signature, dos_get_disk_signature,
&dsp->signature, "%08x", dsp);
} }
static struct partition_parser dos = { static struct partition_parser dos = {

View File

@ -86,7 +86,7 @@ static gpt_entry *alloc_read_gpt_entries(struct block_device *blk,
from = le64_to_cpu(pgpt_head->partition_entry_lba); from = le64_to_cpu(pgpt_head->partition_entry_lba);
size = count / GPT_BLOCK_SIZE; size = count / GPT_BLOCK_SIZE;
ret = blk->ops->read(blk, pte, from, size); ret = block_read(blk, pte, from, size);
if (ret) { if (ret) {
kfree(pte); kfree(pte);
pte=NULL; pte=NULL;
@ -121,7 +121,7 @@ static gpt_header *alloc_read_gpt_header(struct block_device *blk,
if (!gpt) if (!gpt)
return NULL; return NULL;
ret = blk->ops->read(blk, gpt, lba, 1); ret = block_read(blk, gpt, lba, 1);
if (ret) { if (ret) {
kfree(gpt); kfree(gpt);
gpt=NULL; gpt=NULL;

View File

@ -8,8 +8,6 @@ struct block_device;
struct block_device_ops { struct block_device_ops {
int (*read)(struct block_device *, void *buf, int block, int num_blocks); int (*read)(struct block_device *, void *buf, int block, int num_blocks);
int (*write)(struct block_device *, const void *buf, int block, int num_blocks); int (*write)(struct block_device *, const void *buf, int block, int num_blocks);
int (*read_start)(struct block_device *, void *buf, int block, int num_blocks);
int (*read_done)(struct block_device *);
}; };
struct chunk; struct chunk;
@ -31,4 +29,12 @@ struct block_device {
int blockdevice_register(struct block_device *blk); int blockdevice_register(struct block_device *blk);
int blockdevice_unregister(struct block_device *blk); int blockdevice_unregister(struct block_device *blk);
int block_read(struct block_device *blk, void *buf, int block, int num_blocks);
int block_write(struct block_device *blk, void *buf, int block, int num_blocks);
static inline int block_flush(struct block_device *blk)
{
return cdev_flush(&blk->cdev);
}
#endif /* __BLOCK_H */ #endif /* __BLOCK_H */