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

📄 sr.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
 */static intsr_start_stop(dev, data)dev_t	dev;caddr_t	data;{	struct uscsi_cmd cblk, *com=&cblk;	char	cdb[6];	bzero((caddr_t)cdb, 6);	cdb[0] = SCMD_START_STOP;	cdb[1] = 0; 	/* immediate bit is set to 0 for now */	cdb[4] = (u_char)data;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 6;	com->uscsi_bufaddr = 0;	com->uscsi_buflen = 0;	com->uscsi_flags = DK_DIAGNOSE|DK_SILENT;	return (srioctl_cmd(dev, (caddr_t)com, SR_USCSI_CDB_KERNEL));}/* * This routine ejects the CDROM disc */static intsr_eject(dev)dev_t	dev;{	int	err;	register struct scsi_device 	*devp;	devp = srunits[SRUNIT(dev)];	/* first, unlocks the eject */	if ((err = sr_medium_removal(dev, SR_REMOVAL_ALLOW)) != 0) {		return (err);	}	/* then ejects the disc */	if ((err = (sr_start_stop(dev, (caddr_t)2))) == 0) {		DPRINTF("%s%d: Caddy ejected\n", DNAME, DUNIT);		sr_ejected(devp);	}	return (err);}#ifdef FIXEDFIRMWARE/* * This routine control the audio output volume */static intsr_volume_ctrl(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	char	cdb[6];	struct cdrom_volctrl	*vol;	caddr_t	buffer;	int	rtn;	DPRINTF("in sr_volume_ctrl\n");	if ((buffer = IOPBALLOC(20)) == (caddr_t)0) {		return (ENOMEM);	}	vol = (struct cdrom_volctrl *)data;	bzero((caddr_t)cdb, 6);	cdb[0] = SCMD_MODE_SELECT;	cdb[4] = 20;	/*	 * fill in the input data. Set the output channel 0, 1 to	 * output port 0, 1 respestively. Set output channel 2, 3 to	 * mute. The function only adjust the output volume for channel	 * 0 and 1.	 */	bzero(buffer, 20);	buffer[4] = 0xe;	buffer[5] = 0xe;	buffer[6] = 0x4;	/* set the immediate bit to 1 */	buffer[12] = 0x01;	buffer[13] = vol->channel0;	buffer[14] = 0x02;	buffer[15] = vol->channel1;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 6;	com->uscsi_bufaddr = buffer;	com->uscsi_buflen = 20;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT;	rtn = (srioctl_cmd(dev, (caddr_t)com,			SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));	IOPBFREE (buffer, 20);	return (rtn);}#else/* * This routine control the audio output volume */static intsr_volume_ctrl(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	char	cdb[10];	struct cdrom_volctrl	*vol;	caddr_t	buffer;	int	rtn;	DPRINTF("in sr_volume_ctrl\n");	if ((buffer = IOPBALLOC(18)) == (caddr_t)0) {		return (ENOMEM);	}	vol = (struct cdrom_volctrl *)data;	bzero(cdb, 10);	cdb[0] = 0xc9;	/* vendor unique command */	cdb[7] = 0;	cdb[8] = 0x12;	/*	 * fill in the input data. Set the output channel 0, 1 to	 * output port 0, 1 respestively. Set output channel 2, 3 to	 * mute. The function only adjust the output volume for channel	 * 0 and 1.	 */	bzero(buffer, 18);	buffer[10] = 0x01;	buffer[11] = vol->channel0;	buffer[12] = 0x02;	buffer[13] = vol->channel1;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 10;	com->uscsi_bufaddr = buffer;	com->uscsi_buflen = 0x12;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT;	rtn = (srioctl_cmd(dev, (caddr_t)com,			SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));	IOPBFREE (buffer, 18);	return (rtn);}#endif FIXEDFIRMWARE#ifdef OLDCODE/* * read the drive's capacity and sector size * This routine is not used by srioctl(). Used when a new media is * inserted or when the device is first opened. */static intsr_read_capacity(dev)dev_t	dev;{	register struct	scsi_disk *un;	register struct	scsi_device *devp;	struct	uscsi_cmd cblk, *com=&cblk;	char	cdb[10];	struct	scsi_capacity *cap;	int	rtn;	DPRINTF("in sr_read_capacity\n");	devp = srunits[SRUNIT(dev)];	un = UPTR;	if ((cap = (struct scsi_capacity *)IOPBALLOC(sizeof		(struct scsi_capacity))) == (struct scsi_capacity *)0) {		return (ENOMEM);	}	bzero(cdb, 10);	cdb[0] = SCMD_READ_CAPACITY;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 10;	com->uscsi_bufaddr = (caddr_t)cap;	com->uscsi_buflen = sizeof (struct scsi_capacity);	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_READ;	rtn = (srioctl_cmd(dev, (caddr_t)com,			SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));	un->un_capacity = cap->capacity+1;	un->un_lbasize = cap->lbasize;	un->un_g.dkg_nsect = un->un_capacity;	DPRINTF("%s%d: capacity is %d\n", DNAME, DUNIT,		un->un_capacity);	IOPBFREE (cap, sizeof (struct scsi_capacity));	return (rtn);}#endif OLDCODEstatic intsr_read_subchannel(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	char	cdb[10];	caddr_t	buffer;	int	rtn;	struct	cdrom_subchnl	*subchnl;	DPRINTF("in sr_read_subchannel\n");	if ((buffer = IOPBALLOC(16)) == (caddr_t)0) {		return (ENOMEM);	}	subchnl = (struct cdrom_subchnl *)data;	bzero((caddr_t)cdb, 10);	cdb[0] = SCMD_READ_SUBCHANNEL;	cdb[1] = (subchnl->cdsc_format & CDROM_LBA) ? 0 : 0x02;	/*	 * set the Q bit in byte 2 to 1.	 */	cdb[2] = 0x40;	/*	 * This byte (byte 3) specifies the return data format. Proposed	 * by Sony. To be added to SCSI-2 Rev 10b	 * Setting it to one tells it to return time-data format	 */	cdb[3] = 0x01;	cdb[8] = 0x10;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 10;	com->uscsi_bufaddr = buffer;	com->uscsi_buflen = 0x10;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_READ;	rtn = (srioctl_cmd(dev, (caddr_t)com,			SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));	subchnl->cdsc_audiostatus = buffer[1];	subchnl->cdsc_trk = buffer[6];	subchnl->cdsc_ind = buffer[7];	subchnl->cdsc_adr = buffer[5] & 0xF0;	subchnl->cdsc_ctrl = buffer[5] & 0x0F;	if (subchnl->cdsc_format & CDROM_LBA) {		subchnl->cdsc_absaddr.lba = ((u_char)buffer[8] << 24) +					((u_char)buffer[9] << 16) +					((u_char)buffer[10] << 8) +					((u_char)buffer[11]);		subchnl->cdsc_reladdr.lba = ((u_char)buffer[12] << 24) +					((u_char)buffer[13] << 16) +					((u_char)buffer[14] << 8) +					((u_char)buffer[15]);	} else {		subchnl->cdsc_absaddr.msf.minute = buffer[9];		subchnl->cdsc_absaddr.msf.second = buffer[10];		subchnl->cdsc_absaddr.msf.frame = buffer[11];		subchnl->cdsc_reladdr.msf.minute = buffer[13];		subchnl->cdsc_reladdr.msf.second = buffer[14];		subchnl->cdsc_reladdr.msf.frame = buffer[15];	}	IOPBFREE (buffer, 16);	return (rtn);}static intsr_read_mode2(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	u_char	cdb[6];	int	rtn;	struct	cdrom_read	*mode2;	DPRINTF("in sr_read_mode2\n");	mode2 = (struct cdrom_read *)data;#ifdef FIVETWELVE	mode2->cdread_lba >>= 2;#endif FIVETWELVE	bzero((caddr_t)cdb, 6);	cdb[0] = SCMD_READ;	cdb[1] = (u_char)((mode2->cdread_lba >> 16) & 0XFF);	cdb[2] = (u_char)((mode2->cdread_lba >> 8) & 0xFF);	cdb[3] = (u_char)(mode2->cdread_lba & 0xFF);	cdb[4] = mode2->cdread_buflen / 2336;	com->uscsi_cdb = (caddr_t)cdb;	com->uscsi_cdblen = 6;	com->uscsi_bufaddr = mode2->cdread_bufaddr;	com->uscsi_buflen = mode2->cdread_buflen;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_READ;	rtn = (srioctl_cmd(dev, (caddr_t)com, SR_USCSI_CDB_KERNEL|SR_MODE2));	return (rtn);}static intsr_read_mode1(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	u_char	cdb[6];	int	rtn;	struct	cdrom_read	*mode1;	DPRINTF("in sr_read_mode1\n");	mode1 = (struct cdrom_read *)data;	bzero((caddr_t)cdb, 6);	cdb[0] = SCMD_READ;	cdb[1] = (u_char)((mode1->cdread_lba >> 16) & 0XFF);	cdb[2] = (u_char)((mode1->cdread_lba >> 8) & 0xFF);	cdb[3] = (u_char)(mode1->cdread_lba & 0xFF);	cdb[4] = mode1->cdread_buflen >> 11;	com->uscsi_cdb = (caddr_t)cdb;	com->uscsi_cdblen = 6;	com->uscsi_bufaddr = mode1->cdread_bufaddr;	com->uscsi_buflen = mode1->cdread_buflen;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_READ;	rtn = (srioctl_cmd(dev, (caddr_t)com, SR_USCSI_CDB_KERNEL));	return (rtn);}static intsr_read_tochdr(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	char	cdb[10];	caddr_t	buffer;	int	rtn;	struct cdrom_tochdr	*hdr;	DPRINTF("in sr_read_tochdr.\n");	if ((buffer = IOPBALLOC(4)) == (caddr_t)0) {		return (ENOMEM);	}	hdr = (struct cdrom_tochdr *)data;	bzero((caddr_t)cdb, 10);	cdb[0] = SCMD_READ_TOC;	cdb[6] = 0x00;	/*	 * byte 7, 8 are the allocation length. In this case, it is 4	 * bytes.	 */	cdb[8] = 0x04;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 10;	com->uscsi_bufaddr = buffer;	com->uscsi_buflen = 0x04;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_READ;	rtn = (srioctl_cmd(dev, (caddr_t)com,			SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));	hdr->cdth_trk0 = buffer[2];	hdr->cdth_trk1 = buffer[3];	IOPBFREE (buffer, 4);	return (rtn);}/* * This routine read the toc of the disc and returns the information * of a particular track. The track number is specified by the ioctl * caller. */static intsr_read_tocentry(dev, data)dev_t	dev;caddr_t	data;{	struct	uscsi_cmd cblk, *com=&cblk;	char	cdb[10];	struct cdrom_tocentry	*entry;	caddr_t	buffer;	int	rtn, rtn1;	int	lba;	DPRINTF("in sr_read_tocentry.\n");	if ((buffer = IOPBALLOC(12)) == (caddr_t)0) {		return (ENOMEM);	}	entry = (struct cdrom_tocentry *)data;	if (!(entry->cdte_format & (CDROM_LBA | CDROM_MSF))) {		return (EINVAL);	}	bzero((caddr_t)cdb, 10);	cdb[0] = SCMD_READ_TOC;	/* set the MSF bit of byte one */	cdb[1] = (entry->cdte_format & CDROM_LBA) ? 0 : 2;	cdb[6] = entry->cdte_track;	/*	 * byte 7, 8 are the allocation length. In this case, it is 4 + 8	 * = 12 bytes, since we only need one entry.	 */	cdb[8] = 0x0C;	com->uscsi_cdb = cdb;	com->uscsi_cdblen = 10;	com->uscsi_bufaddr = buffer;	com->uscsi_buflen = 0x0C;	com->uscsi_flags = USCSI_DIAGNOSE|USCSI_SILENT|USCSI_READ;	rtn = (srioctl_cmd(dev, (caddr_t)com,			SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));	entry->cdte_adr = (buffer[5] & 0xF0) >> 4;	entry->cdte_ctrl = (buffer[5] & 0x0F);	if (entry->cdte_format & CDROM_LBA) {		entry->cdte_addr.lba = ((u_char)buffer[8] << 24) +					((u_char)buffer[9] << 16) +					((u_char)buffer[10] << 8) +					((u_char)buffer[11]);	} else {		entry->cdte_addr.msf.minute = buffer[9];		entry->cdte_addr.msf.second = buffer[10];		entry->cdte_addr.msf.frame = buffer[11];	}	if (rtn) {		IOPBFREE (buffer, 12);		return (rtn);	}	/*	 * Now do a readheader to determine which data mode it is in.	 * ...If the track is a data track	 */	if ((entry->cdte_ctrl & CDROM_DATA_TRACK) &&	    (entry->cdte_track != CDROM_LEADOUT)) {		if (entry->cdte_format & CDROM_LBA) {			lba = entry->cdte_addr.lba;		} else {			lba = (((entry->cdte_addr.msf.minute * 60) +				(entry->cdte_addr.msf.second)) * 75) +				entry->cdte_addr.msf.frame;		}		bzero((caddr_t)cdb, 10);		cdb[0] = SCMD_READ_HEADER;		cdb[2] = (u_char)((lba >> 24) & 0xFF);		cdb[3] = (u_char)((lba >> 16) & 0xFF);		cdb[4] = (u_char)((lba >> 8) & 0xFF);		cdb[5] = (u_char)(lba & 0xFF);		cdb[7] = 0x00;		cdb[8] = 0x08;		com->uscsi_buflen = 0x08;		rtn1 = (srioctl_cmd(dev, (caddr_t)com,				    SR_USCSI_CDB_KERNEL|SR_USCSI_BUF_KERNEL));		if (rtn1) {			IOPBFREE (buffer, 12);			return (rtn1);		}		entry->cdte_datamode = buffer[0];	} else {		entry->cdte_datamode = -1;	}	IOPBFREE (buffer, 12);	return (rtn);}/* * This routine sets the drive to reading mode-2 data tracks */static intsr_mode_2(devp)struct scsi_device	*devp;{	struct	scsi_pkt	*pkt1;	struct	scsi_pkt	*pkt2;	caddr_t	buffer1;	caddr_t	buffer2;	char	cdb[6];	DPRINTF("%s%d: switching to reading mode-2.\n", DNAME, DUNIT);	/*	 * first, do a mode sense of page 1 code	 */	bzero((caddr_t)cdb, 6);	cdb[0] = SCMD_MODE_SENSE;	cdb[2] = 1;	cdb[4] = 20;	pkt1 = get_pktiopb(ROUTE, (caddr_t *)&buffer1, 6, 1, 20, B_READ,			NULL_FUNC);	if (!pkt1) {		return (ENOMEM);	}	makecom_all(pkt1, devp, FLAG_NOINTR, 0, cdb);	if (scsi_poll(pkt1) || SCBP_C(pkt1) != STATUS_GOOD ||	    (pkt1->pkt_state & STATE_XFERRED_DATA) == 0 ||	    (pkt1->pkt_resid != 0)) {		DPRINTF("%s%d: MODE SENSE command failed.\n",			DNAME, DUNIT);		free_pktiopb(pkt1, (caddr_t)buffer1, 20);		return (EIO);	}	DPRINTF("%s%d: Parameter from Mode Sense:\n", DNAME, DUNIT);	if (DEBUGGING) {		int	i;		for (i=0; i!=20; i++) {			printf("0x%x ", buffer1[i]);		}	}	/*	 * then, do a mode select to set to mode-2 read	 */	bzero((caddr_t)cdb, 6);	cdb[0] = SCMD_MODE_SELECT;	cdb[4] = 20;	pkt2 = get_pktiopb(ROUTE, (caddr_t *)&buffer2, 6, 1, 20, B_WRITE,			NULL_FUNC);	if (!pkt2) {		return (ENOMEM);	}	/*	 * fill in the parameter list for mode select command	 */	bzero(buffer2, 20);	buffer2[3] = 0x08;	buffer2[10] = 0x09;	buffer2[11] = 0x20;	buffer2[12] = 0x01;	buffer2[13] = 0x06;	buffer2[14] = buffer1[14] | 0x01;	buffer2[15] = buffer1[15];	/*	 * fire the command	 */	makecom_all(pkt2, devp, FLAG_NOINTR, 0, cdb);	if (scsi_poll(pkt2) || SCBP_C(pkt2) != STATUS_GOOD ||	    (pkt2->pkt_state & STATE_XFERRED_DATA) == 0 ||	    (pkt2->pkt_resid != 0)) {		DPRINTF("%s%d: MODE SELECT command failed.\n",			DNAME, DUNIT);		free_pktiopb(pkt2, (caddr_t)buffer2, 20);		return (EIO);	}	free_pktiopb(pkt1, (caddr_t)buffer1, 20);	free_pktiopb(pkt2, (caddr_t)buffer2, 20);	return (0);}/* * This routine sets the drive to reading mode-1 data tracks */static intsr_mode_1(devp)struct scsi_device	*devp;{	struct	scsi_pkt	*pkt1;	struct	scsi_pkt	*pkt2;	caddr_t	buffer1;	caddr_t	buffer2;	char	cdb[6];	DPRINTF("%s%d: switching to reading mode-1.\n", DNAME, DUNIT);	/*	 * first, do a mode sense of page 1 code	 */	bzero(cdb, 6);	cdb[0] = SCMD_MODE_SENSE;	/* get default page 1 values */

⌨️ 快捷键说明

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