コード例 #1
0
ファイル: nftl.c プロジェクト: dmgerman/original
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
	struct NFTLrecord *nftl;

	nftl = NFTLs[MINOR(inode->i_rdev) / 16];

	if (!nftl) return -EINVAL;

	switch (cmd) {
	case HDIO_GETGEO: {
		struct hd_geometry g;

		g.heads = nftl->heads;
		g.sectors = nftl->sectors;
		g.cylinders = nftl->cylinders;
		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
	}
	case BLKGETSIZE:   /* Return device size */
		if (!arg) return -EINVAL;
		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
                                (long *) arg);
		
	case BLKFLSBUF:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		fsync_dev(inode->i_rdev);
		invalidate_buffers(inode->i_rdev);
		if (nftl->mtd->sync)
			nftl->mtd->sync(nftl->mtd);
		return 0;

	case BLKRRPART:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		if (nftl->usecount > 1) return -EBUSY;
#if LINUX_VERSION_CODE < 0x20328
		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) / 16);
#else
		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) / 16,
				1<<4, nftl->nr_sects);
#endif
		return 0;

#if (LINUX_VERSION_CODE < 0x20303)		
	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
#else
	case BLKROSET:
	case BLKROGET:
	case BLKSSZGET:
		return blk_ioctl(inode->i_rdev, cmd, arg);
#endif

	default:
		return -EINVAL;
	}
}
コード例 #2
0
ファイル: nftlcore.c プロジェクト: romanalexander/Trickles
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
	struct NFTLrecord *nftl;
	int p;

	nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];

	if (!nftl) return -EINVAL;

	switch (cmd) {
	case HDIO_GETGEO: {
		struct hd_geometry g;

		g.heads = nftl->heads;
		g.sectors = nftl->sectors;
		g.cylinders = nftl->cylinders;
		g.start = part_table[MINOR(inode->i_rdev)].start_sect;
		return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
	}
	case BLKGETSIZE:   /* Return device size */
		return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
                                (unsigned long *) arg);

#ifdef BLKGETSIZE64
	case BLKGETSIZE64:
		return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
                                (u64 *)arg);
#endif

	case BLKFLSBUF:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		fsync_dev(inode->i_rdev);
		invalidate_buffers(inode->i_rdev);
		if (nftl->mtd->sync)
			nftl->mtd->sync(nftl->mtd);
		return 0;

	case BLKRRPART:
		if (!capable(CAP_SYS_ADMIN)) return -EACCES;
		if (nftl->usecount > 1) return -EBUSY;
		/* 
		 * We have to flush all buffers and invalidate caches,
		 * or we won't be able to re-use the partitions,
		 * if there was a change and we don't want to reboot
		 */
		p = (1<<NFTL_PARTN_BITS) - 1;
		while (p-- > 0) {
			kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
			if (part_table[p].nr_sects > 0)
				invalidate_device (devp, 1);

			part_table[MINOR(inode->i_dev)+p].start_sect = 0;
			part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
		}
		
#if LINUX_VERSION_CODE < 0x20328
		resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
#else
		grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
				1<<NFTL_PARTN_BITS, nftl->nr_sects);
#endif
		return 0;

#if (LINUX_VERSION_CODE < 0x20303)		
	RO_IOCTLS(inode->i_rdev, arg);  /* ref. linux/blk.h */
#else
	case BLKROSET:
	case BLKROGET:
	case BLKSSZGET:
		return blk_ioctl(inode->i_rdev, cmd, arg);
#endif

	default:
		return -EINVAL;
	}
}
コード例 #3
0
ファイル: sr_ioctl.c プロジェクト: binsys/doc-linux
int sr_ioctl(struct inode * inode, struct file * file, unsigned long cmd, unsigned long arg)
{
	int dev = inode->i_rdev;
	int result;

	target = MINOR(dev);

	switch (cmd) 
		{
		/* linux-specific */
		case CDROMDOORUNLOCK:
		        lock_sr_ioctl();

		        sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
			sr_cmd[1] = scsi_CDs[target].device->lun << 5;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
			sr_cmd[4] = SR_REMOVAL_ALLOW;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;

		case CDROMDOORLOCK:
		        lock_sr_ioctl();

		        sr_cmd[0] = ALLOW_MEDIUM_REMOVAL;
			sr_cmd[1] = scsi_CDs[target].device->lun << 5;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
			sr_cmd[4] = SR_REMOVAL_PREVENT;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;

		/* Sun-compatible */
		case CDROMPAUSE:
			lock_sr_ioctl();

			sr_cmd[0] = SCMD_PAUSE_RESUME;
			sr_cmd[1] = scsi_CDs[target].device->lun << 5;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
			sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
			sr_cmd[8] = 1;
			sr_cmd[9] = 0;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;

		case CDROMRESUME:
			lock_sr_ioctl();

			sr_cmd[0] = SCMD_PAUSE_RESUME;
			sr_cmd[1] = scsi_CDs[target].device->lun << 5;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
			sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
			sr_cmd[8] = 0;
			sr_cmd[9] = 0;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;

		case CDROMPLAYMSF:
			{
			struct cdrom_msf msf;
			lock_sr_ioctl();

			memcpy_fromfs(&msf, (void *) arg, sizeof(msf));

			sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
			sr_cmd[1] = scsi_CDs[target].device->lun << 5;
			sr_cmd[2] = 0;
			sr_cmd[3] = msf.cdmsf_min0;
			sr_cmd[4] = msf.cdmsf_sec0;
			sr_cmd[5] = msf.cdmsf_frame0;
			sr_cmd[6] = msf.cdmsf_min1;
			sr_cmd[7] = msf.cdmsf_sec1;
			sr_cmd[8] = msf.cdmsf_frame1;
			sr_cmd[9] = 0;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;
			}

		case CDROMPLAYTRKIND:
			{
			struct cdrom_ti ti;
			lock_sr_ioctl();

			memcpy_fromfs(&ti, (void *) arg, sizeof(ti));

			sr_cmd[0] = SCMD_PLAYAUDIO_TI;
			sr_cmd[1] = scsi_CDs[target].device->lun << 5;
			sr_cmd[2] = 0;
			sr_cmd[3] = 0;
			sr_cmd[4] = ti.cdti_trk0;
			sr_cmd[5] = ti.cdti_ind0;
			sr_cmd[6] = 0;
			sr_cmd[7] = ti.cdti_trk1;
			sr_cmd[8] = ti.cdti_ind1;
			sr_cmd[9] = 0;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;
			}

		case CDROMREADTOCHDR:
			return -EINVAL;
		case CDROMREADTOCENTRY:
			return -EINVAL;

		case CDROMSTOP:
		        lock_sr_ioctl();

		        sr_cmd[0] = START_STOP;
			sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
			sr_cmd[4] = 0;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;
			
		case CDROMSTART:
		        lock_sr_ioctl();

		        sr_cmd[0] = START_STOP;
			sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
			sr_cmd[4] = 1;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;

		case CDROMEJECT:
		        lock_sr_ioctl();

		        sr_cmd[0] = START_STOP;
			sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
			sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
			sr_cmd[4] = 0x02;

			result = do_ioctl();

			unlock_sr_ioctl();
			return result;

		case CDROMVOLCTRL:
			return -EINVAL;
		case CDROMSUBCHNL:
			return -EINVAL;
		case CDROMREADMODE2:
			return -EINVAL;
		case CDROMREADMODE1:
			return -EINVAL;

		RO_IOCTLS(dev,arg);
		default:
			return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
		}
}
コード例 #4
0
ファイル: sr_ioctl.c プロジェクト: thickforest/SLS-1.02
int sr_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
    u_char 	sr_cmd[10];

    int dev = inode->i_rdev;
    int result, target;

    target = MINOR(dev);
    if (target >= NR_SR) return -ENODEV;

    switch (cmd)
    {
    /* Sun-compatible */
    case CDROMPAUSE:

        sr_cmd[0] = SCMD_PAUSE_RESUME;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
        sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
        sr_cmd[8] = 0;
        sr_cmd[9] = 0;

        result = do_ioctl(target, sr_cmd, NULL, 255);
        return result;

    case CDROMRESUME:

        sr_cmd[0] = SCMD_PAUSE_RESUME;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = 0;
        sr_cmd[5] = sr_cmd[6] = sr_cmd[7] = 0;
        sr_cmd[8] = 1;
        sr_cmd[9] = 0;

        result = do_ioctl(target, sr_cmd, NULL, 255);

        return result;

    case CDROMPLAYMSF:
    {
        struct cdrom_msf msf;
        memcpy_fromfs(&msf, (void *) arg, sizeof(msf));

        sr_cmd[0] = SCMD_PLAYAUDIO_MSF;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        sr_cmd[2] = 0;
        sr_cmd[3] = msf.cdmsf_min0;
        sr_cmd[4] = msf.cdmsf_sec0;
        sr_cmd[5] = msf.cdmsf_frame0;
        sr_cmd[6] = msf.cdmsf_min1;
        sr_cmd[7] = msf.cdmsf_sec1;
        sr_cmd[8] = msf.cdmsf_frame1;
        sr_cmd[9] = 0;

        result = do_ioctl(target, sr_cmd, NULL, 255);
        return result;
    }

    case CDROMPLAYTRKIND:
    {
        struct cdrom_ti ti;
        memcpy_fromfs(&ti, (void *) arg, sizeof(ti));

        sr_cmd[0] = SCMD_PLAYAUDIO_TI;
        sr_cmd[1] = scsi_CDs[target].device->lun << 5;
        sr_cmd[2] = 0;
        sr_cmd[3] = 0;
        sr_cmd[4] = ti.cdti_trk0;
        sr_cmd[5] = ti.cdti_ind0;
        sr_cmd[6] = 0;
        sr_cmd[7] = ti.cdti_trk1;
        sr_cmd[8] = ti.cdti_ind1;
        sr_cmd[9] = 0;

        result = do_ioctl(target, sr_cmd, NULL, 255);

        return result;
    }

    case CDROMREADTOCHDR:
    {
        struct cdrom_tochdr tochdr;
        char buffer[12];

        sr_cmd[0] = SCMD_READ_TOC;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;    /* MSF format */
        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
        sr_cmd[6] = 0;
        sr_cmd[7] = 0;              /* MSB of length (12) */
        sr_cmd[8] = 12;             /* LSB of length */
        sr_cmd[9] = 0;

        result = do_ioctl(target, sr_cmd, buffer, sizeof (buffer));

        tochdr.cdth_trk0 = buffer[2];
        tochdr.cdth_trk1 = buffer[3];

        verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tochdr));
        memcpy_tofs ((void *) arg, &tochdr, sizeof (struct cdrom_tochdr));

        return result;
    }

    case CDROMREADTOCENTRY:
    {
        struct cdrom_tocentry tocentry;
        char buffer[12];

        verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_tocentry));
        memcpy_fromfs (&tocentry, (void *) arg, sizeof (struct cdrom_tocentry));

        sr_cmd[0] = SCMD_READ_TOC;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;    /* MSF format */
        sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;
        sr_cmd[6] = tocentry.cdte_track;
        sr_cmd[7] = 0;             /* MSB of length (12)  */
        sr_cmd[8] = 12;            /* LSB of length */
        sr_cmd[9] = 0;

        result = do_ioctl (target, sr_cmd, buffer, sizeof (buffer));

        if (tocentry.cdte_format == CDROM_MSF) {
            tocentry.cdte_addr.msf.minute = buffer[9];
            tocentry.cdte_addr.msf.second = buffer[10];
            tocentry.cdte_addr.msf.frame = buffer[11];
            tocentry.cdte_ctrl = buffer[5] & 0xf;
        }
        else
            tocentry.cdte_addr.lba = (int) buffer[0];

        verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_tocentry));
        memcpy_tofs ((void *) arg, &tocentry, sizeof (struct cdrom_tocentry));

        return result;
    }

    case CDROMSTOP:
        sr_cmd[0] = START_STOP;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        sr_cmd[4] = 0;

        result = do_ioctl(target, sr_cmd, NULL, 255);
        return result;

    case CDROMSTART:
        sr_cmd[0] = START_STOP;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 1;
        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        sr_cmd[4] = 1;

        result = do_ioctl(target, sr_cmd, NULL, 255);
        return result;

    case CDROMEJECT:
        if (scsi_CDs[target].device -> access_count == 1)
            sr_ioctl (inode, NULL, SCSI_IOCTL_DOORUNLOCK, 0);

        sr_cmd[0] = START_STOP;
        sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 1;
        sr_cmd[2] = sr_cmd[3] = sr_cmd[5] = 0;
        sr_cmd[4] = 0x02;

        if (!(result = do_ioctl(target, sr_cmd, NULL, 255)))
            scsi_CDs[target].device -> changed = 1;

        return result;

    case CDROMVOLCTRL:
    {
        char buffer[28], mask[28];
        struct cdrom_volctrl volctrl;

        verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_volctrl));
        memcpy_fromfs (&volctrl, (void *) arg, sizeof (struct cdrom_volctrl));

        /* First we get the current params so we can just twiddle the volume */

        sr_cmd[0] = MODE_SENSE;
        sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
        sr_cmd[2] = 0xe;    /* Want mode page 0xe, CDROM audio params */
        sr_cmd[3] = 0;
        sr_cmd[4] = 28;
        sr_cmd[5] = 0;

        if ((result = do_ioctl (target, sr_cmd, buffer, sizeof (buffer)))) {
            printk ("Hosed while obtaining audio mode page\n");
            return result;
        }

        sr_cmd[0] = MODE_SENSE;
        sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
        sr_cmd[2] = 0x4e;   /* Want the mask for mode page 0xe */
        sr_cmd[3] = 0;
        sr_cmd[4] = 28;
        sr_cmd[5] = 0;

        if ((result = do_ioctl (target, sr_cmd, mask, sizeof (mask)))) {
            printk ("Hosed while obtaining mask for audio mode page\n");
            return result;
        }

        /* Now mask and substitute our own volume and reuse the rest */

        buffer[21] = volctrl.channel0 & mask[21];
        buffer[23] = volctrl.channel1 & mask[23];
        buffer[25] = volctrl.channel2 & mask[25];
        buffer[27] = volctrl.channel3 & mask[27];

        sr_cmd[0] = MODE_SELECT;
        sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10;    /* Params are SCSI-2 */
        sr_cmd[2] = sr_cmd[3] = 0;
        sr_cmd[4] = 28;
        sr_cmd[5] = 0;

        result = do_ioctl (target, sr_cmd, buffer, sizeof (buffer));
        return result;
    }

    case CDROMSUBCHNL:
    {
        struct cdrom_subchnl subchnl;
        char buffer[16];

        sr_cmd[0] = SCMD_READ_SUBCHANNEL;
        sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02;    /* MSF format */
        sr_cmd[2] = 0x40;    /* I do want the subchannel info */
        sr_cmd[3] = 0x01;    /* Give me current position info */
        sr_cmd[4] = sr_cmd[5] = 0;
        sr_cmd[6] = 0;
        sr_cmd[7] = 0;
        sr_cmd[8] = 16;
        sr_cmd[9] = 0;

        result = do_ioctl(target, sr_cmd, buffer, sizeof (buffer));

        subchnl.cdsc_audiostatus = buffer[1];
        subchnl.cdsc_format = CDROM_MSF;
        subchnl.cdsc_ctrl = buffer[5] & 0xf;
        subchnl.cdsc_trk = buffer[6];
        subchnl.cdsc_ind = buffer[7];

        subchnl.cdsc_reladdr.msf.minute = buffer[13];
        subchnl.cdsc_reladdr.msf.second = buffer[14];
        subchnl.cdsc_reladdr.msf.frame = buffer[15];
        subchnl.cdsc_absaddr.msf.minute = buffer[9];
        subchnl.cdsc_absaddr.msf.second = buffer[10];
        subchnl.cdsc_absaddr.msf.frame = buffer[11];

        verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_subchnl));
        memcpy_tofs ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));
        return result;
    }

    case CDROMREADMODE2:
        return -EINVAL;
    case CDROMREADMODE1:
        return -EINVAL;

        RO_IOCTLS(dev,arg);
    default:
        return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);
    }
}