|
|
1.1 ! root 1: /* ! 2: * drivers/scsi/sd_ioctl.c ! 3: * ! 4: * ioctl handling for SCSI disks ! 5: */ ! 6: ! 7: #include <linux/kernel.h> ! 8: #include <linux/sched.h> ! 9: #include <linux/mm.h> ! 10: #include <linux/fs.h> ! 11: #include <linux/hdreg.h> ! 12: #include <linux/errno.h> ! 13: ! 14: #include <asm/segment.h> ! 15: ! 16: #include <linux/blk.h> ! 17: #include "scsi.h" ! 18: #include <scsi/scsi_ioctl.h> ! 19: #include "hosts.h" ! 20: #include "sd.h" ! 21: #include <scsi/scsicam.h> /* must follow "hosts.h" */ ! 22: ! 23: int sd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) ! 24: { ! 25: kdev_t dev = inode->i_rdev; ! 26: int error; ! 27: struct Scsi_Host * host; ! 28: int diskinfo[4]; ! 29: struct hd_geometry *loc = (struct hd_geometry *) arg; ! 30: ! 31: switch (cmd) { ! 32: case HDIO_GETGEO: /* Return BIOS disk parameters */ ! 33: if (!loc) return -EINVAL; ! 34: #ifndef MACH ! 35: error = verify_area(VERIFY_WRITE, loc, sizeof(*loc)); ! 36: if (error) ! 37: return error; ! 38: #endif ! 39: host = rscsi_disks[MINOR(dev) >> 4].device->host; ! 40: ! 41: /* default to most commonly used values */ ! 42: ! 43: diskinfo[0] = 0x40; ! 44: diskinfo[1] = 0x20; ! 45: diskinfo[2] = rscsi_disks[MINOR(dev) >> 4].capacity >> 11; ! 46: ! 47: /* override with calculated, extended default, or driver values */ ! 48: ! 49: if(host->hostt->bios_param != NULL) ! 50: host->hostt->bios_param(&rscsi_disks[MINOR(dev) >> 4], ! 51: dev, ! 52: &diskinfo[0]); ! 53: else scsicam_bios_param(&rscsi_disks[MINOR(dev) >> 4], ! 54: dev, &diskinfo[0]); ! 55: ! 56: #ifdef MACH ! 57: loc->heads = diskinfo[0]; ! 58: loc->sectors = diskinfo[1]; ! 59: loc->cylinders = diskinfo[2]; ! 60: loc->start = sd[MINOR(inode->i_rdev)].start_sect; ! 61: #else ! 62: put_user(diskinfo[0], &loc->heads); ! 63: put_user(diskinfo[1], &loc->sectors); ! 64: put_user(diskinfo[2], &loc->cylinders); ! 65: put_user(sd[MINOR(inode->i_rdev)].start_sect, &loc->start); ! 66: #endif ! 67: return 0; ! 68: case BLKGETSIZE: /* Return device size */ ! 69: if (!arg) return -EINVAL; ! 70: error = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); ! 71: if (error) ! 72: return error; ! 73: put_user(sd[MINOR(inode->i_rdev)].nr_sects, ! 74: (long *) arg); ! 75: return 0; ! 76: ! 77: case BLKRASET: ! 78: if (!suser()) ! 79: return -EACCES; ! 80: if(!(inode->i_rdev)) return -EINVAL; ! 81: if(arg > 0xff) return -EINVAL; ! 82: read_ahead[MAJOR(inode->i_rdev)] = arg; ! 83: return 0; ! 84: ! 85: case BLKRAGET: ! 86: if (!arg) ! 87: return -EINVAL; ! 88: error = verify_area(VERIFY_WRITE, (int *) arg, sizeof(int)); ! 89: if (error) ! 90: return error; ! 91: put_user(read_ahead[MAJOR(inode->i_rdev)], (int *) arg); ! 92: return 0; ! 93: ! 94: case BLKFLSBUF: ! 95: if(!suser()) return -EACCES; ! 96: if(!(inode->i_rdev)) return -EINVAL; ! 97: fsync_dev(inode->i_rdev); ! 98: invalidate_buffers(inode->i_rdev); ! 99: return 0; ! 100: ! 101: case BLKRRPART: /* Re-read partition tables */ ! 102: return revalidate_scsidisk(dev, 1); ! 103: ! 104: RO_IOCTLS(dev, arg); ! 105: ! 106: default: ! 107: return scsi_ioctl(rscsi_disks[MINOR(dev) >> 4].device , cmd, (void *) arg); ! 108: } ! 109: } ! 110: ! 111: /* ! 112: * Overrides for Emacs so that we follow Linus's tabbing style. ! 113: * Emacs will notice this stuff at the end of the file and automatically ! 114: * adjust the settings for this buffer only. This must remain at the end ! 115: * of the file. ! 116: * --------------------------------------------------------------------------- ! 117: * Local variables: ! 118: * c-indent-level: 4 ! 119: * c-brace-imaginary-offset: 0 ! 120: * c-brace-offset: -4 ! 121: * c-argdecl-indent: 4 ! 122: * c-label-offset: -4 ! 123: * c-continued-statement-offset: 4 ! 124: * c-continued-brace-offset: 0 ! 125: * indent-tabs-mode: nil ! 126: * tab-width: 8 ! 127: * End: ! 128: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.