diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-01-29 01:41:54 +0000 |
commit | f969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch) | |
tree | b3530d803df59d726afaabebc6626987dee1ca05 /drivers/scsi/sd.c | |
parent | a10ce7ef2066b455d69187643ddf2073bfc4db24 (diff) |
Merge with 2.3.27.
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 90 |
1 files changed, 83 insertions, 7 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a2876d17c..6c3835089 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -36,21 +36,25 @@ #include <linux/sched.h> #include <linux/mm.h> #include <linux/string.h> +#include <linux/hdreg.h> #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/smp.h> +#include <asm/uaccess.h> #include <asm/system.h> #include <asm/io.h> #define MAJOR_NR SCSI_DISK0_MAJOR #include <linux/blk.h> +#include <linux/blkpg.h> #include "scsi.h" #include "hosts.h" #include "sd.h" #include <scsi/scsi_ioctl.h> #include "constants.h" +#include <scsi/scsicam.h> /* must follow "hosts.h" */ #include <linux/genhd.h> @@ -87,8 +91,6 @@ static int *sd_sizes; static int *sd_blocksizes; static int *sd_hardsizes; /* Hardware sector size */ -extern int sd_ioctl(struct inode *, struct file *, unsigned int, unsigned long); - static int check_scsidisk_media_change(kdev_t); static int fop_revalidate_scsidisk(kdev_t); @@ -102,6 +104,80 @@ static int sd_attach(Scsi_Device *); static int sd_detect(Scsi_Device *); static void sd_detach(Scsi_Device *); +static int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) +{ + kdev_t dev = inode->i_rdev; + struct Scsi_Host * host; + Scsi_Device * SDev; + int diskinfo[4]; + struct hd_geometry *loc = (struct hd_geometry *) arg; + + SDev = rscsi_disks[DEVICE_NR(dev)].device; + /* + * If we are in the middle of error recovery, don't let anyone + * else try and use this device. Also, if error recovery fails, it + * may try and take the device offline, in which case all further + * access to the device is prohibited. + */ + + if( !scsi_block_when_processing_errors(SDev) ) + { + return -ENODEV; + } + + switch (cmd) + { + case HDIO_GETGEO: /* Return BIOS disk parameters */ + if(!loc) + return -EINVAL; + + host = rscsi_disks[DEVICE_NR(dev)].device->host; + + /* default to most commonly used values */ + + diskinfo[0] = 0x40; + diskinfo[1] = 0x20; + diskinfo[2] = rscsi_disks[DEVICE_NR(dev)].capacity >> 11; + + /* override with calculated, extended default, or driver values */ + + if(host->hostt->bios_param != NULL) + host->hostt->bios_param(&rscsi_disks[DEVICE_NR(dev)], + dev, + &diskinfo[0]); + else scsicam_bios_param(&rscsi_disks[DEVICE_NR(dev)], + dev, &diskinfo[0]); + + if (put_user(diskinfo[0], &loc->heads) || + put_user(diskinfo[1], &loc->sectors) || + put_user(diskinfo[2], &loc->cylinders) || + put_user(sd[SD_PARTITION(inode->i_rdev)].start_sect, &loc->start)) + return -EFAULT; + return 0; + case BLKGETSIZE: /* Return device size */ + if (!arg) + return -EINVAL; + return put_user(sd[SD_PARTITION(inode->i_rdev)].nr_sects, (long *) arg); + + case BLKROSET: + case BLKROGET: + case BLKRASET: + case BLKRAGET: + case BLKFLSBUF: + case BLKSSZGET: + case BLKPG: + return blk_ioctl(inode->i_rdev, cmd, arg); + + case BLKRRPART: /* Re-read partition tables */ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + return revalidate_scsidisk(dev, 1); + + default: + return scsi_ioctl(rscsi_disks[DEVICE_NR(dev)].device , cmd, (void *) arg); + } +} + static void sd_devname(unsigned int disknum, char *buffer) { if (disknum < 26) @@ -119,11 +195,11 @@ static void sd_devname(unsigned int disknum, char *buffer) } } -struct Scsi_Device_Template sd_template = -{NULL, "disk", "sd", NULL, TYPE_DISK, - SCSI_DISK0_MAJOR, 0, 0, 0, 1, - sd_detect, sd_init, - sd_finish, sd_attach, sd_detach +struct Scsi_Device_Template sd_template = { + NULL, "disk", "sd", NULL, TYPE_DISK, + SCSI_DISK0_MAJOR, 0, 0, 0, 1, + sd_detect, sd_init, + sd_finish, sd_attach, sd_detach }; static int sd_open(struct inode *inode, struct file *filp) |