sr_ioctl.c

来自「GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目」· C语言 代码 · 共 608 行 · 第 1/2 页

C
608
字号
	sr_cmd[4] = 0x03;	        if ((result = do_ioctl(target, sr_cmd, NULL, 255)))          return result;        /* Gather information about newly inserted disc */        check_disk_change (inode->i_rdev);        sr_ioctl (inode, NULL, SCSI_IOCTL_DOORLOCK, 0);        sr_photocd (inode);        if (scsi_CDs[MINOR(inode->i_rdev)].needs_sector_size)          get_sectorsize (MINOR(inode->i_rdev));        return 0;    case CDROMEJECT:        /*         * Allow 0 for access count for auto-eject feature.         */	if (scsi_CDs[target].device -> access_count > 1)	    return -EBUSY;		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 CDROMEJECT_SW:        scsi_CDs[target].auto_eject = !!arg;        return 0;    case CDROMVOLCTRL:    {	char * buffer, * mask;	struct cdrom_volctrl volctrl;	        err = verify_area (VERIFY_READ, (void *) arg, sizeof (struct cdrom_volctrl));        if (err) return err;	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;		buffer = (unsigned char *) scsi_malloc(512);	if(!buffer) return -ENOMEM;		if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {	    printk ("Hosed while obtaining audio mode page\n");	    scsi_free(buffer, 512);	    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;		mask = (unsigned char *) scsi_malloc(512);	if(!mask) {	    scsi_free(buffer, 512);	    return -ENOMEM;	};	if ((result = do_ioctl (target, sr_cmd, mask, 28))) {	    printk ("Hosed while obtaining mask for audio mode page\n");	    scsi_free(buffer, 512);	    scsi_free(mask, 512);	    return result;	}		/* Now mask and substitute our own volume and reuse the rest */	buffer[0] = 0;  /* Clear reserved field */		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, 28);	scsi_free(buffer, 512);	scsi_free(mask, 512);	return result;    }	    case CDROMVOLREAD:    {	char * buffer;	struct cdrom_volctrl volctrl;	        err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_volctrl));        if (err) return err;		/* Get the current params */		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;		buffer = (unsigned char *) scsi_malloc(512);	if(!buffer) return -ENOMEM;		if ((result = do_ioctl (target, sr_cmd, buffer, 28))) {	    printk ("(CDROMVOLREAD) Hosed while obtaining audio mode page\n");	    scsi_free(buffer, 512);	    return result;	}	volctrl.channel0 = buffer[21];	volctrl.channel1 = buffer[23];	volctrl.channel2 = buffer[25];	volctrl.channel3 = buffer[27];	memcpy_tofs ((void *) arg, &volctrl, sizeof (struct cdrom_volctrl));	scsi_free(buffer, 512);	return 0;    }	    case CDROMSUBCHNL:    {	struct cdrom_subchnl subchnl;	char * buffer;		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;		buffer = (unsigned char*) scsi_malloc(512);	if(!buffer) return -ENOMEM;		result = do_ioctl(target, sr_cmd, buffer, 16);		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];		scsi_free(buffer, 512);		err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_subchnl));	if (err)	    return err;	memcpy_tofs ((void *) arg, &subchnl, sizeof (struct cdrom_subchnl));	return result;    }	    case CDROM_GET_UPC:    {	struct cdrom_mcn mcn;	char * buffer;		sr_cmd[0] = SCMD_READ_SUBCHANNEL;	sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5);	sr_cmd[2] = 0x40;    /* I do want the subchannel info */	sr_cmd[3] = 0x02;    /* Give me medium catalog number info */	sr_cmd[4] = sr_cmd[5] = 0;	sr_cmd[6] = 0;	sr_cmd[7] = 0;	sr_cmd[8] = 24;	sr_cmd[9] = 0;		buffer = (unsigned char*) scsi_malloc(512);	if(!buffer) return -ENOMEM;		result = do_ioctl(target, sr_cmd, buffer, 24);		memcpy (mcn.medium_catalog_number, buffer + 9, 13);        mcn.medium_catalog_number[13] = 0;	scsi_free(buffer, 512);		err = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct cdrom_mcn));	if (err)	    return err;	memcpy_tofs ((void *) arg, &mcn, sizeof (struct cdrom_mcn));	return result;    }	    /* these are compatible with the ide-cd driver */    case CDROMREADRAW:    case CDROMREADMODE1:    case CDROMREADMODE2:	return -EINVAL;		/* block-copy from ../block/sbpcd.c with some adjustments... */    case CDROMMULTISESSION: /* tell start-of-last-session to user */    {	struct cdrom_multisession  ms_info;	long                       lba;		err = verify_area(VERIFY_READ, (void *) arg,			  sizeof(struct cdrom_multisession));	if (err) return (err);		memcpy_fromfs(&ms_info, (void *) arg, sizeof(struct cdrom_multisession));		if (ms_info.addr_format==CDROM_MSF) { /* MSF-bin requested */	    lba = scsi_CDs[target].mpcd_sector+CD_BLOCK_OFFSET;	    ms_info.addr.msf.minute = lba / (CD_SECS*CD_FRAMES);	    lba %= CD_SECS*CD_FRAMES;	    ms_info.addr.msf.second = lba / CD_FRAMES;	    ms_info.addr.msf.frame  = lba % CD_FRAMES;	} else if (ms_info.addr_format==CDROM_LBA) /* lba requested */	    ms_info.addr.lba=scsi_CDs[target].mpcd_sector;	else return (-EINVAL);		ms_info.xa_flag=scsi_CDs[target].xa_flags & 0x01;		err=verify_area(VERIFY_WRITE,(void *) arg,			sizeof(struct cdrom_multisession));	if (err) return (err);		memcpy_tofs((void *) arg, &ms_info, sizeof(struct cdrom_multisession));	return (0);    }	    case BLKRAGET:	if (!arg)		return -EINVAL;	err = verify_area(VERIFY_WRITE, (int *) arg, sizeof(int));	if (err)		return err;	put_user(read_ahead[MAJOR(inode->i_rdev)], (int *) arg);	return 0;    case BLKRASET:	if(!suser())        	return -EACCES;	if(!(inode->i_rdev))        	return -EINVAL;	if(arg > 0xff)        	return -EINVAL;	read_ahead[MAJOR(inode->i_rdev)] = arg;	return 0;    RO_IOCTLS(dev,arg);    case CDROMRESET:	invalidate_buffers(inode->i_rdev);	return 0;    default:	return scsi_ioctl(scsi_CDs[target].device,cmd,(void *) arg);    }}/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: nil * tab-width: 8 * End: */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?