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

📄 ide-cd.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
#if ! STANDARD_ATAPI	if (CDROM_CONFIG_FLAGS (drive)->toctracks_as_bcd) {		toc->hdr.first_track = bcd2bin (toc->hdr.first_track);		toc->hdr.last_track  = bcd2bin (toc->hdr.last_track);	}#endif  /* not STANDARD_ATAPI */	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;	if (ntracks <= 0) return -EIO;	if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;	/* Now read the whole schmeer. */	stat = cdrom_read_tocentry (drive, 0, 1, 0, (char *)&toc->hdr,				    sizeof (struct atapi_toc_header) +				    (ntracks+1) *				      sizeof (struct atapi_toc_entry),				    reqbuf);	if (stat) return stat;	toc->hdr.toc_length = ntohs (toc->hdr.toc_length);#if ! STANDARD_ATAPI	if (CDROM_CONFIG_FLAGS (drive)->toctracks_as_bcd) {		toc->hdr.first_track = bcd2bin (toc->hdr.first_track);		toc->hdr.last_track  = bcd2bin (toc->hdr.last_track);	}#endif  /* not STANDARD_ATAPI */	for (i=0; i<=ntracks; i++) {#if ! STANDARD_ATAPI		if (CDROM_CONFIG_FLAGS (drive)->tocaddr_as_bcd) {			if (CDROM_CONFIG_FLAGS (drive)->toctracks_as_bcd)				toc->ent[i].track = bcd2bin (toc->ent[i].track);			msf_from_bcd (&toc->ent[i].addr.msf);		}#endif  /* not STANDARD_ATAPI */		toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,						   toc->ent[i].addr.msf.second,						   toc->ent[i].addr.msf.frame);	}	/* Read the multisession information. */	stat = cdrom_read_tocentry (drive, 0, 1, 1,				    (char *)&ms_tmp, sizeof (ms_tmp),				    reqbuf);	if (stat) return stat;#if ! STANDARD_ATAPI	if (CDROM_CONFIG_FLAGS (drive)->tocaddr_as_bcd)		msf_from_bcd (&ms_tmp.ent.addr.msf);#endif  /* not STANDARD_ATAPI */	toc->last_session_lba = msf_to_lba (ms_tmp.ent.addr.msf.minute,					    ms_tmp.ent.addr.msf.second,					    ms_tmp.ent.addr.msf.frame);	toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);	/* Now try to get the total cdrom capacity. */	stat = cdrom_read_capacity (drive, &toc->capacity, reqbuf);	if (stat) toc->capacity = 0x1fffff;	HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS]		= (toc->capacity * SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);	drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;	/* Remember that we've read this stuff. */	CDROM_STATE_FLAGS (drive)->toc_valid = 1;	return 0;}static intcdrom_read_subchannel (ide_drive_t *drive, int format,                       char *buf, int buflen,		       struct atapi_request_sense *reqbuf){	struct packet_command pc;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	pc.buffer =  buf;	pc.buflen = buflen;	pc.c[0] = SCMD_READ_SUBCHANNEL;	pc.c[1] = 2;     /* MSF addressing */	pc.c[2] = 0x40;  /* request subQ data */	pc.c[3] = format;	pc.c[7] = (buflen >> 8);	pc.c[8] = (buflen & 0xff);	return cdrom_queue_packet_command (drive, &pc);}/* modeflag: 0 = current, 1 = changeable mask, 2 = default, 3 = saved */static intcdrom_mode_sense (ide_drive_t *drive, int pageno, int modeflag,                  char *buf, int buflen,		  struct atapi_request_sense *reqbuf){	struct packet_command pc;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	pc.buffer =  buf;	pc.buflen = buflen;	pc.c[0] = MODE_SENSE_10;	pc.c[2] = pageno | (modeflag << 6);	pc.c[7] = (buflen >> 8);	pc.c[8] = (buflen & 0xff);	return cdrom_queue_packet_command (drive, &pc);}static intcdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen,		   struct atapi_request_sense *reqbuf){	struct packet_command pc;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	pc.buffer =  buf;	pc.buflen = - buflen;	pc.c[0] = MODE_SELECT_10;	pc.c[1] = 0x10;	pc.c[2] = pageno;	pc.c[7] = (buflen >> 8);	pc.c[8] = (buflen & 0xff);	return cdrom_queue_packet_command (drive, &pc);}/* ATAPI cdrom drives are free to select the speed you request or any slower   rate :-( Requesting too fast a speed will _not_ produce an error. */static intcdrom_select_speed (ide_drive_t *drive, int speed,                   struct atapi_request_sense *reqbuf){	struct packet_command pc;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	if (speed == 0)	    speed = 0xffff; /* set to max */	else	    speed *= 177;   /* Nx to kbytes/s */	pc.c[0] = SET_CD_SPEED;	/* Read Drive speed in kbytes/second MSB */	pc.c[2] = (speed >> 8) & 0xff;		/* Read Drive speed in kbytes/second LSB */	pc.c[3] = speed & 0xff;	if ( CDROM_CONFIG_FLAGS(drive)->cd_r ||                   CDROM_CONFIG_FLAGS(drive)->cd_rw ) {		/* Write Drive speed in kbytes/second MSB */		pc.c[4] = (speed >> 8) & 0xff;		/* Write Drive speed in kbytes/second LSB */		pc.c[5] = speed & 0xff;       }	return cdrom_queue_packet_command (drive, &pc);}static intcdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,			    struct atapi_request_sense *reqbuf){	struct packet_command pc;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	pc.c[0] = SCMD_PLAYAUDIO_MSF;	lba_to_msf (lba_start, &pc.c[3], &pc.c[4], &pc.c[5]);	lba_to_msf (lba_end-1, &pc.c[6], &pc.c[7], &pc.c[8]);#if ! STANDARD_ATAPI	if (CDROM_CONFIG_FLAGS (drive)->playmsf_as_bcd) {		pc.c[3] = bin2bcd (pc.c[3]);		pc.c[4] = bin2bcd (pc.c[4]);		pc.c[5] = bin2bcd (pc.c[5]);		pc.c[6] = bin2bcd (pc.c[6]);		pc.c[7] = bin2bcd (pc.c[7]);		pc.c[8] = bin2bcd (pc.c[8]);	}#endif /* not STANDARD_ATAPI */	return cdrom_queue_packet_command (drive, &pc);}/* Play audio starting at LBA LBA_START and finishing with the   LBA before LBA_END. */static intcdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,		      struct atapi_request_sense *reqbuf){	int i, stat;	struct atapi_request_sense my_reqbuf;	if (reqbuf == NULL)		reqbuf = &my_reqbuf;	/* Some drives, will, for certain audio cds,	   give an error if you ask them to play the entire cd using the	   values which are returned in the TOC.  The play will succeed,	   however, if the ending address is adjusted downwards	   by a few frames. */	for (i=0; i<75; i++) {		stat = cdrom_play_lba_range_1 (drive, lba_start, lba_end,					       reqbuf);		if (stat == 0 ||		    !(reqbuf->sense_key == ILLEGAL_REQUEST &&		      reqbuf->asc == 0x24))			return stat;		--lba_end;		if (lba_end <= lba_start) break;	}	return stat;}staticint cdrom_get_toc_entry (ide_drive_t *drive, int track,                         struct atapi_toc_entry **ent,			 struct atapi_request_sense *reqbuf){	struct cdrom_info *info = drive->driver_data;	int stat, ntracks;	struct atapi_toc *toc;	/* Make sure our saved TOC is valid. */	stat = cdrom_read_toc (drive, reqbuf);	if (stat) return stat;	toc = info->toc;	/* Check validity of requested track number. */	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;	if (track == CDROM_LEADOUT)		*ent = &toc->ent[ntracks];	else if (track < toc->hdr.first_track ||		 track > toc->hdr.last_track)		return -EINVAL;	else		*ent = &toc->ent[track - toc->hdr.first_track];	return 0;}static intcdrom_read_block (ide_drive_t *drive, int format, int lba, int nblocks,		  char *buf, int buflen,		  struct atapi_request_sense *reqbuf){	struct packet_command pc;	struct atapi_request_sense my_reqbuf;	if (reqbuf == NULL)		reqbuf = &my_reqbuf;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	pc.buffer = buf;	pc.buflen = buflen;#if ! STANDARD_ATAPI	if (CDROM_CONFIG_FLAGS (drive)->nec260)		pc.c[0] = 0xd4;	else#endif  /* not STANDARD_ATAPI */		pc.c[0] = READ_CD;	pc.c[1] = (format << 2);	put_unaligned(htonl(lba), (unsigned int *) &pc.c[2]);	pc.c[8] = (nblocks & 0xff);	pc.c[7] = ((nblocks>>8) & 0xff);	pc.c[6] = ((nblocks>>16) & 0xff);	if (format <= 1)		pc.c[9] = 0xf8;         /* returns 2352 for any format */	else		pc.c[9] = 0x10;	return cdrom_queue_packet_command (drive, &pc);}/* If SLOT<0, unload the current slot.  Otherwise, try to load SLOT. */static intcdrom_load_unload (ide_drive_t *drive, int slot,		   struct atapi_request_sense *reqbuf){#if ! STANDARD_ATAPI	/* if the drive is a Sanyo 3 CD changer then TEST_UNIT_READY           (used in the cdrom_check_status function) is used to            switch CDs instead of LOAD_UNLOAD */	if (CDROM_STATE_FLAGS (drive)->sanyo_slot > 0) {        	if ((slot == 1) || (slot == 2))			CDROM_STATE_FLAGS (drive)->sanyo_slot = slot;		else if (slot >= 0)			CDROM_STATE_FLAGS (drive)->sanyo_slot = 3;		else			return 0;		return cdrom_check_status (drive, reqbuf);	}	else#endif /*not STANDARD_ATAPI */	{		/* ATAPI Rev. 2.2+ standard for requesting switching of                   CDs in a multiplatter device */		struct packet_command pc;		memset (&pc, 0, sizeof (pc));		pc.sense_data = reqbuf;		pc.c[0] = LOAD_UNLOAD;		pc.c[4] = 2 + (slot >= 0);		pc.c[8] = slot;		return cdrom_queue_packet_command (drive, &pc);	}}/* This gets the mechanism status per ATAPI draft spec 2.6 */static intcdrom_read_mech_status (ide_drive_t *drive, char *buf, int buflen,			struct atapi_request_sense *reqbuf){	struct packet_command pc;	memset (&pc, 0, sizeof (pc));	pc.sense_data = reqbuf;	pc.buffer = buf;	pc.buflen = buflen;	pc.c[0] = MECHANISM_STATUS;	pc.c[8] = (buflen >> 8);	pc.c[9] = (buflen & 0xff);	return cdrom_queue_packet_command (drive, &pc);}/* Read the drive mechanism status and slot table into our internal buffer.   If the buffer does not yet exist, allocate it. */static intcdrom_read_changer_info (ide_drive_t *drive){	int nslots;	struct cdrom_info *info = drive->driver_data;	if (info->changer_info)		nslots = info->changer_info->hdr.nslots;	else {		struct atapi_mechstat_header mechbuf;		int stat;		stat = cdrom_read_mech_status (drive,					       (char *)&mechbuf,					       sizeof (mechbuf),					       NULL);		if (stat)			return stat;		nslots = mechbuf.nslots;		info->changer_info =			(struct atapi_changer_info *)			kmalloc (sizeof (struct atapi_changer_info) +				 nslots * sizeof (struct atapi_slot),				 GFP_KERNEL);		if (info->changer_info == NULL)			return -ENOMEM;	}	return cdrom_read_mech_status		(drive,		 (char *)&info->changer_info->hdr,		 sizeof (struct atapi_mechstat_header) +		 nslots * sizeof (struct atapi_slot),		 NULL);}staticint ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,			 unsigned int cmd, unsigned long arg)			 {	ide_drive_t *drive = (ide_drive_t*) cdi->handle;	struct cdrom_info *info = drive->driver_data;	switch (cmd) {	case CDROMREADRAW:	case CDROMREADMODE1:	case CDROMREADMODE2: {		struct cdrom_msf msf;		int blocksize, format, stat, lba;		struct atapi_toc *toc;		char *buf;		if (cmd == CDROMREADMODE1) {			blocksize = CD_FRAMESIZE;			format = 2;		} else {	/* for RAW and MODE2. */			blocksize = CD_FRAMESIZE_RAW;			format = 0;		}				copy_from_user_ret(&msf, (void

⌨️ 快捷键说明

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