diff options
Diffstat (limited to 'linux/dev')
-rw-r--r-- | linux/dev/drivers/block/ahci.c | 35 |
1 files changed, 33 insertions, 2 deletions
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"; |