⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sr_ioctl.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	sr_cmd[9] = 0;	result = sr_do_ioctl(MINOR(cdi->dev), sr_cmd, buffer, 24, 0, SCSI_DATA_READ, NULL);	memcpy(mcn->medium_catalog_number, buffer + 9, 13);	mcn->medium_catalog_number[13] = 0;	return result;}int sr_reset(struct cdrom_device_info *cdi){	invalidate_buffers(cdi->dev);	return 0;}int sr_select_speed(struct cdrom_device_info *cdi, int speed){	u_char sr_cmd[MAX_COMMAND_SIZE];	if (speed == 0)		speed = 0xffff;	/* set to max */	else		speed *= 177;	/* Nx to kbyte/s */	memset(sr_cmd, 0, MAX_COMMAND_SIZE);	sr_cmd[0] = GPCMD_SET_SPEED;	/* SET CD SPEED */	sr_cmd[1] = (scsi_CDs[MINOR(cdi->dev)].device->lun) << 5;	sr_cmd[2] = (speed >> 8) & 0xff;	/* MSB for speed (in kbytes/sec) */	sr_cmd[3] = speed & 0xff;	/* LSB */	if (sr_do_ioctl(MINOR(cdi->dev), sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL))		return -EIO;	return 0;}/* ----------------------------------------------------------------------- *//* this is called by the generic cdrom driver. arg is a _kernel_ pointer,  *//* because the generic cdrom driver does the user access stuff for us.     *//* only cdromreadtochdr and cdromreadtocentry are left - for use with the  *//* sr_disk_status interface for the generic cdrom driver.                  */int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg){	u_char sr_cmd[10];	int result, target = MINOR(cdi->dev);	unsigned char buffer[32];	memset(sr_cmd, 0, sizeof(sr_cmd));	switch (cmd) {	case CDROMREADTOCHDR:		{			struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg;			sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP;			sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5);			sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;			sr_cmd[8] = 12;		/* LSB of length */			result = sr_do_ioctl(target, sr_cmd, buffer, 12, 1, SCSI_DATA_READ, NULL);			tochdr->cdth_trk0 = buffer[2];			tochdr->cdth_trk1 = buffer[3];			break;		}	case CDROMREADTOCENTRY:		{			struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg;			sr_cmd[0] = GPCMD_READ_TOC_PMA_ATIP;			sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) |			    (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);			sr_cmd[2] = sr_cmd[3] = sr_cmd[4] = sr_cmd[5] = 0;			sr_cmd[6] = tocentry->cdte_track;			sr_cmd[8] = 12;		/* LSB of length */			result = sr_do_ioctl(target, sr_cmd, buffer, 12, 0, SCSI_DATA_READ, NULL);			tocentry->cdte_ctrl = buffer[5] & 0xf;			tocentry->cdte_adr = buffer[5] >> 4;			tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0;			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];			} else				tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8)					+ buffer[10]) << 8) + buffer[11];			break;		}	case CDROMPLAYTRKIND: {		struct cdrom_ti* ti = (struct cdrom_ti*)arg;		sr_cmd[0] = GPCMD_PLAYAUDIO_TI;		sr_cmd[1] = scsi_CDs[target].device->lun << 5;		sr_cmd[4] = ti->cdti_trk0;		sr_cmd[5] = ti->cdti_ind0;		sr_cmd[7] = ti->cdti_trk1;		sr_cmd[8] = ti->cdti_ind1;		result = sr_do_ioctl(target, sr_cmd, NULL, 0, 0, SCSI_DATA_NONE, NULL);		if (result == -EDRIVE_CANT_DO_THIS)			result = sr_fake_playtrkind(cdi, ti);		break;	}	default:		return -EINVAL;	}#if 0	if (result)		printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result);#endif	return result;}/* ----------------------------------------------------------------------- * a function to read all sorts of funny cdrom sectors using the READ_CD * scsi-3 mmc command * * lba:     linear block address * format:  0 = data (anything) *          1 = audio *          2 = data (mode 1) *          3 = data (mode 2) *          4 = data (mode 2 form1) *          5 = data (mode 2 form2) * blksize: 2048 | 2336 | 2340 | 2352 */int sr_read_cd(int minor, unsigned char *dest, int lba, int format, int blksize){	unsigned char cmd[MAX_COMMAND_SIZE];#ifdef DEBUG	printk("sr%d: sr_read_cd lba=%d format=%d blksize=%d\n",	       minor, lba, format, blksize);#endif	memset(cmd, 0, MAX_COMMAND_SIZE);	cmd[0] = GPCMD_READ_CD;	/* READ_CD */	cmd[1] = (scsi_CDs[minor].device->lun << 5) | ((format & 7) << 2);	cmd[2] = (unsigned char) (lba >> 24) & 0xff;	cmd[3] = (unsigned char) (lba >> 16) & 0xff;	cmd[4] = (unsigned char) (lba >> 8) & 0xff;	cmd[5] = (unsigned char) lba & 0xff;	cmd[8] = 1;	switch (blksize) {	case 2336:		cmd[9] = 0x58;		break;	case 2340:		cmd[9] = 0x78;		break;	case 2352:		cmd[9] = 0xf8;		break;	default:		cmd[9] = 0x10;		break;	}	return sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);}/* * read sectors with blocksizes other than 2048 */int sr_read_sector(int minor, int lba, int blksize, unsigned char *dest){	unsigned char cmd[MAX_COMMAND_SIZE];	/* the scsi-command */	int rc;	/* we try the READ CD command first... */	if (scsi_CDs[minor].readcd_known) {		rc = sr_read_cd(minor, dest, lba, 0, blksize);		if (-EDRIVE_CANT_DO_THIS != rc)			return rc;		scsi_CDs[minor].readcd_known = 0;		printk("CDROM does'nt support READ CD (0xbe) command\n");		/* fall & retry the other way */	}	/* ... if this fails, we switch the blocksize using MODE SELECT */	if (blksize != scsi_CDs[minor].device->sector_size) {		if (0 != (rc = sr_set_blocklength(minor, blksize)))			return rc;	}#ifdef DEBUG	printk("sr%d: sr_read_sector lba=%d blksize=%d\n", minor, lba, blksize);#endif	memset(cmd, 0, MAX_COMMAND_SIZE);	cmd[0] = GPCMD_READ_10;	cmd[1] = (scsi_CDs[minor].device->lun << 5);	cmd[2] = (unsigned char) (lba >> 24) & 0xff;	cmd[3] = (unsigned char) (lba >> 16) & 0xff;	cmd[4] = (unsigned char) (lba >> 8) & 0xff;	cmd[5] = (unsigned char) lba & 0xff;	cmd[8] = 1;	rc = sr_do_ioctl(minor, cmd, dest, blksize, 0, SCSI_DATA_READ, NULL);	return rc;}/* * read a sector in raw mode to check the sector format * ret: 1 == mode2 (XA), 0 == mode1, <0 == error  */int sr_is_xa(int minor){	unsigned char *raw_sector;	int is_xa;	if (!xa_test)		return 0;	raw_sector = (unsigned char *) scsi_malloc(2048 + 512);	if (!raw_sector)		return -ENOMEM;	if (0 == sr_read_sector(minor, scsi_CDs[minor].ms_offset + 16,				CD_FRAMESIZE_RAW1, raw_sector)) {		is_xa = (raw_sector[3] == 0x02) ? 1 : 0;	} else {		/* read a raw sector failed for some reason. */		is_xa = -1;	}	scsi_free(raw_sector, 2048 + 512);#ifdef DEBUG	printk("sr%d: sr_is_xa: %d\n", minor, is_xa);#endif	return is_xa;}int sr_dev_ioctl(struct cdrom_device_info *cdi,		 unsigned int cmd, unsigned long arg){	int target;	target = MINOR(cdi->dev);	switch (cmd) {	case BLKROSET:	case BLKROGET:	case BLKRASET:	case BLKRAGET:	case BLKFLSBUF:	case BLKSSZGET:		return blk_ioctl(cdi->dev, cmd, arg);	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 + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -