From f925d0efa2161aef215f858347a9036f1153c4b2 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 24 Jun 2013 15:02:09 +0200 Subject: Add partitioning reload support to ahci * linux/dev/drivers/block/ahci.c (port): Add `gd' field. (ahci_ioctl): New function. (ahci_fops): Fill `ioctl' field with `ahci_ioctl'. (ahci_probe_pci): Fill `gd' field with `gd'. --- linux/dev/drivers/block/ahci.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'linux/dev/drivers/block/ahci.c') diff --git a/linux/dev/drivers/block/ahci.c b/linux/dev/drivers/block/ahci.c index ceded7c..2c573ac 100644 --- a/linux/dev/drivers/block/ahci.c +++ b/linux/dev/drivers/block/ahci.c @@ -248,6 +248,7 @@ static struct port { unsigned lba48; /* Whether LBA48 is supported */ unsigned identify; /* Whether we are just identifying at boot */ + struct gendisk *gd; } ports[MAX_PORTS]; @@ -471,6 +472,34 @@ static void ahci_interrupt (int irq, void *host, struct pt_regs *regs) /* unlock */ } +static int ahci_ioctl (struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int major, unit; + + if (!inode || !inode->i_rdev) + return -EINVAL; + + major = MAJOR(inode->i_rdev); + if (major != MAJOR_NR) + return -ENOTTY; + + unit = DEVICE_NR(inode->i_rdev); + if (unit >= MAX_PORTS) + return -EINVAL; + + switch (cmd) { + case BLKRRPART: + if (!suser()) return -EACCES; + if (!ports[unit].gd) + return -EINVAL; + resetup_one_dev(ports[unit].gd, unit); + return 0; + default: + return -EPERM; + } +} + static int ahci_open (struct inode *inode, struct file *file) { int target; @@ -504,7 +533,7 @@ static struct file_operations ahci_fops = { .write = block_write, .readdir = NULL, .select = NULL, - .ioctl = NULL, + .ioctl = ahci_ioctl, .mmap = NULL, .open = ahci_open, .release = ahci_release, @@ -875,8 +904,10 @@ void ahci_probe_pci(void) memset(gd->part, 0, nminors * sizeof(*gd->part)); - for (unit = 0; unit < nports; unit++) + for (unit = 0; unit < nports; unit++) { + ports[unit].gd = gd; ports[unit].part = &gd->part[unit << PARTN_BITS]; + } gd->major = MAJOR_NR; gd->major_name = "sd"; -- cgit v1.2.3