summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
commitf969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch)
treeb3530d803df59d726afaabebc6626987dee1ca05 /drivers/scsi/sd.c
parenta10ce7ef2066b455d69187643ddf2073bfc4db24 (diff)
Merge with 2.3.27.
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c90
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)