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

📄 scsi_cdr.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		return (-1);	}	if (scgp->verbose) {		scsiprbytes("TOC data: ", (Uchar *)xb,			len > (int)sizeof(xb) - scsigetresid(scgp) ?				sizeof(xb) - scsigetresid(scgp) : len);		tp = &dp->desc[0];		pe = &xb[len];		while ((char *)tp < pe) {			scsiprbytes("ENT: ", (Uchar *)tp, 11);			tp++;		}	}	tp = &dp->desc[0];	pe = &xb[len];	for (; (char *)tp < pe; tp++) {		if (tp->sess_number != dp->hd.last)			continue;		if (tp->point != 0xB0)			continue;		if (scgp->verbose)			scsiprbytes("B0: ", (Uchar *)tp, 11);		if (isbcd) {			l = msf_to_lba(from_bcd(tp->amin),				from_bcd(tp->asec),				from_bcd(tp->aframe), TRUE);		} else {			l = msf_to_lba(tp->amin,				tp->asec,				tp->aframe, TRUE);		}		if (b0p)			*b0p = l;		if (scgp->verbose)			printf("B0 start: %ld\n", l);		if (isbcd) {			l = msf_to_lba(from_bcd(tp->pmin),				from_bcd(tp->psec),				from_bcd(tp->pframe), TRUE);		} else {			l = msf_to_lba(tp->pmin,				tp->psec,				tp->pframe, TRUE);		}		if (scgp->verbose)			printf("B0 lout: %ld\n", l);		if (lop)			*lop = l;		return (0);	}	return (-1);}/* * Return address of first track in last session (SCSI-3/mmc version). */EXPORT intread_session_offset(scgp, offp)	SCSI	*scgp;	long	*offp;{	struct	diskinfo *dp;	char	xb[256];	int	len;	dp = (struct diskinfo *)xb;	fillbytes((caddr_t)xb, sizeof(xb), '\0');	if (read_toc(scgp, (caddr_t)xb, 0, sizeof(struct tocheader), 0, FMT_SINFO) < 0)		return (-1);	if (scgp->verbose)		scsiprbytes("tocheader: ",		(Uchar *)xb, sizeof(struct tocheader) - scsigetresid(scgp));	len = a_to_u_2_byte(dp->hd.len) + sizeof(struct tocheader)-2;	if (len > (int)sizeof(xb)) {		errmsgno(EX_BAD, "Session info too big.\n");		return (-1);	}	if (read_toc(scgp, (caddr_t)xb, 0, len, 0, FMT_SINFO) < 0)		return (-1);	if (scgp->verbose)		scsiprbytes("tocheader: ",			(Uchar *)xb, len - scsigetresid(scgp));	dp = (struct diskinfo *)xb;	if (offp)		*offp = a_to_u_4_byte(dp->desc[0].addr);	return (0);}/* * Return address of first track in last session (pre SCSI-3 version). */EXPORT intread_session_offset_philips(scgp, offp)	SCSI	*scgp;	long	*offp;{	struct	sinfo *sp;	char	xb[256];	int	len;	sp = (struct sinfo *)xb;	fillbytes((caddr_t)xb, sizeof(xb), '\0');	if (read_toc_philips(scgp, (caddr_t)xb, 0, sizeof(struct siheader), 0, FMT_SINFO) < 0)		return (-1);	len = a_to_u_2_byte(sp->hd.len) + sizeof(struct siheader)-2;	if (len > (int)sizeof(xb)) {		errmsgno(EX_BAD, "Session info too big.\n");		return (-1);	}	if (read_toc_philips(scgp, (caddr_t)xb, 0, len, 0, FMT_SINFO) < 0)		return (-1);	/*	 * Old drives return the number of finished sessions in first/finished	 * a descriptor is returned for each session. 	 * New drives return the number of the first and last session	 * one descriptor for the last finished session is returned	 * as in SCSI-3	 * In all cases the lowest session number is set to 1.	 */	sp = (struct sinfo *)xb;	if (offp)		*offp = a_to_u_4_byte(sp->desc[sp->hd.finished-1].addr);	return (0);}EXPORT intsense_secsize(scgp, current)	SCSI	*scgp;	int	current;{	Uchar	mode[0x100];	Uchar	*p;	Uchar	*ep;	int	secsize = -1;	scgp->silent++;	(void)unit_ready(scgp);	scgp->silent--;	/* XXX Quick and dirty, musz verallgemeinert werden !!! */	fillbytes(mode, sizeof(mode), '\0');	scgp->silent++;	if (mode_sense(scgp, mode, 0xFF, 0x3F, current?0:2) < 0) {	/* All Pages */		fillbytes(mode, sizeof(mode), '\0');		if (mode_sense(scgp, mode, 0xFF, 0, current?0:2) < 0)	{/* VU (block desc) */			scgp->silent--;			return (-1);		}	}	scgp->silent--;	ep = mode+mode[0];	/* Points to last byte of data */	p = &mode[4];	p += mode[3];	if (scgp->debug) {		printf("Pages: ");		while (p < ep) {			printf("0x%x ", *p&0x3F);			p += p[1]+2;		}		printf("\n");	}	if (mode[3] == 8) {		if (scgp->debug) {			printf("Density: 0x%x\n", mode[4]);			printf("Blocks:  %ld\n", a_to_u_3_byte(&mode[5]));			printf("Blocklen:%ld\n", a_to_u_3_byte(&mode[9]));		}		secsize = a_to_u_3_byte(&mode[9]);	}	return (secsize);}EXPORT intselect_secsize(scgp, secsize)	SCSI	*scgp;	int	secsize;{	struct scsi_mode_data md;	int	count = sizeof(struct scsi_mode_header) +			sizeof(struct scsi_mode_blockdesc);	(void)test_unit_ready(scgp);	/* clear any error situation */	fillbytes((caddr_t)&md, sizeof(md), '\0');	md.header.blockdesc_len = 8;	i_to_3_byte(md.blockdesc.lblen, secsize);		return (mode_select(scgp, (Uchar *)&md, count, 0, scgp->inq->data_format >= 2));}EXPORT BOOLis_cddrive(scgp)	SCSI	*scgp;{	return (scgp->inq->type == INQ_ROMD || scgp->inq->type == INQ_WORM);}EXPORT BOOLis_unknown_dev(scgp)	SCSI	*scgp;{	return (scgp->dev == DEV_UNKNOWN);}#define	DEBUG#ifdef	DEBUG#define	G0_MAXADDR	0x1FFFFFLEXPORT intread_scsi(scgp, bp, addr, cnt)	SCSI	*scgp;	caddr_t	bp;	long	addr;	int	cnt;{	if(addr <= G0_MAXADDR && cnt < 256 && !is_atapi)		return (read_g0(scgp, bp, addr, cnt));	else		return (read_g1(scgp, bp, addr, cnt));}EXPORT intread_g0(scgp, bp, addr, cnt)	SCSI	*scgp;	caddr_t	bp;	long	addr;	int	cnt;{	register struct	scg_cmd	*scmd = scgp->scmd;	if (scgp->cap->c_bsize <= 0)		raisecond("capacity_not_set", 0L);	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');	scmd->addr = bp;	scmd->size = cnt*scgp->cap->c_bsize;	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;	scmd->cdb_len = SC_G0_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;	scmd->cdb.g0_cdb.cmd = SC_READ;	scmd->cdb.g0_cdb.lun = scgp->lun;	g0_cdbaddr(&scmd->cdb.g0_cdb, addr);	scmd->cdb.g0_cdb.count = cnt;/*	scmd->cdb.g0_cdb.vu_56 = 1;*/		scgp->cmdname = "read_g0";	return (scsicmd(scgp));}EXPORT intread_g1(scgp, bp, addr, cnt)	SCSI	*scgp;	caddr_t	bp;	long	addr;	int	cnt;{	register struct	scg_cmd	*scmd = scgp->scmd;	if (scgp->cap->c_bsize <= 0)		raisecond("capacity_not_set", 0L);	fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');	scmd->addr = bp;	scmd->size = cnt*scgp->cap->c_bsize;	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;	scmd->cdb_len = SC_G1_CDBLEN;	scmd->sense_len = CCS_SENSE_LEN;	scmd->target = scgp->target;	scmd->cdb.g1_cdb.cmd = SC_EREAD;	scmd->cdb.g1_cdb.lun = scgp->lun;	g1_cdbaddr(&scmd->cdb.g1_cdb, addr);	g1_cdblen(&scmd->cdb.g1_cdb, cnt);		scgp->cmdname = "read_g1";	return (scsicmd(scgp));}#endif	/* DEBUG */EXPORT BOOLgetdev(scgp, print)	SCSI	*scgp;	BOOL	print;{		 BOOL	got_inquiry = TRUE;		 char	vendor_info[8+1];		 char	prod_ident[16+1];		 char	prod_revision[4+1];		 int	inq_len = 0;	register struct	scg_cmd	*scmd = scgp->scmd;	register struct scsi_inquiry *inq = scgp->inq;	fillbytes((caddr_t)inq, sizeof(*inq), '\0');	scgp->dev = DEV_UNKNOWN;	scgp->silent++;	(void)unit_ready(scgp);	if (scmd->error >= SCG_FATAL &&				!(scmd->scb.chk && scmd->sense_count > 0)) {		scgp->silent--;		return (FALSE);	}/*	if (scmd->error < SCG_FATAL || scmd->scb.chk && scmd->sense_count > 0){*/	if (inquiry(scgp, (caddr_t)inq, sizeof(*inq)) < 0) {		got_inquiry = FALSE;	} else {		inq_len = sizeof(*inq) - scsigetresid(scgp);	}	if (!got_inquiry) {		if (scgp->verbose) {			printf(		"error: %d scb.chk: %d sense_count: %d sense.code: 0x%x\n",				scmd->error, scmd->scb.chk,				scmd->sense_count, scmd->sense.code);		}			/*			 * Folgende Kontroller kennen das Kommando			 * INQUIRY nicht:			 *			 * ADAPTEC	ACB-4000, ACB-4010, ACB 4070			 * SYSGEN	SC4000			 *			 * Leider reagieren ACB40X0 und ACB5500 identisch			 * wenn drive not ready (code == not ready),			 * sie sind dann nicht zu unterscheiden.			 */		if (scmd->scb.chk && scmd->sense_count == 4) {			/* Test auf SYSGEN				 */			(void)qic02(scgp, 0x12);	/* soft lock on  */			if (qic02(scgp, 1) < 0) {	/* soft lock off */				scgp->dev = DEV_ACB40X0;/*				scgp->dev = acbdev();*/			} else {				scgp->dev = DEV_SC4000;				inq->type = INQ_SEQD;				inq->removable = 1;			}		}	} else if (scgp->verbose) {		int	i;		int	len = inq->add_len + 5;		Uchar	ibuf[256+5];		Uchar	*ip = (Uchar *)inq;		Uchar	c;		if (len > (int)sizeof (*inq) &&				inquiry(scgp, (caddr_t)ibuf, inq->add_len+5) >= 0) {			len = inq->add_len+5 - scsigetresid(scgp);			ip = ibuf;		} else {			len = sizeof (*inq);		}		printf("Inquiry Data   : ");		for (i = 0; i < len; i++) {			c = ip[i];			if (c >= ' ' && c < 0177)				printf("%c", c);			else				printf(".");		}		printf("\n");	}	strncpy(vendor_info, inq->vendor_info, sizeof(inq->vendor_info));	strncpy(prod_ident, inq->prod_ident, sizeof(inq->prod_ident));	strncpy(prod_revision, inq->prod_revision, sizeof(inq->prod_revision));	vendor_info[sizeof(inq->vendor_info)] = '\0';	prod_ident[sizeof(inq->prod_ident)] = '\0';	prod_revision[sizeof(inq->prod_revision)] = '\0';	switch (inq->type) {	case INQ_DASD:		if (inq->add_len == 0 && inq->vendor_info[0] != '\0') {			Uchar	*p;			/*			 * NT-4.0 creates fake inquiry data for IDE disks.			 * Unfortunately, it does not set add_len wo we			 * check if vendor_info, prod_ident and prod_revision			 * contains valid chars for a CCS inquiry.			 */			if (inq_len >= 36)				inq->add_len = 31;			for (p = (Uchar *)&inq->vendor_info[0];					p < (Uchar *)&inq->prod_revision[4];									p++) {				if (*p < 0x20 || *p > 0x7E) {					inq->add_len = 0;					break;				}			}		}		if (inq->add_len == 0) {			if (scgp->dev == DEV_UNKNOWN && got_inquiry) {				scgp->dev = DEV_ACB5500;				strcpy(inq->vendor_info,					"ADAPTEC ACB-5500        FAKE");			} else switch (scgp->dev) {			case DEV_ACB40X0:				strcpy(inq->vendor_info,					"ADAPTEC ACB-40X0        FAKE");				break;			case DEV_ACB4000:				strcpy(inq->vendor_info,					"ADAPTEC ACB-4000        FAKE");				break;			case DEV_ACB4010:				strcpy(inq->vendor_info,					"ADAPTEC ACB-4010        FAKE");				break;			case DEV_ACB4070:				strcpy(inq->vendor_info,					"ADAPTEC ACB-4070        FAKE");				break;			}		} else if (inq->add_len < 31) {			scgp->dev = DEV_NON_CCS_DSK;		} else if (strbeg("EMULEX", vendor_info)) {			if (strbeg("MD21", prod_ident))				scgp->dev = DEV_MD21;			if (strbeg("MD23", prod_ident))				scgp->dev = DEV_MD23;			else				scgp->dev = DEV_CCS_GENDISK;		} else if (strbeg("ADAPTEC", vendor_info)) {			if (strbeg("ACB-4520", prod_ident))				scgp->dev = DEV_ACB4520A;			if (strbeg("ACB-4525", prod_ident))				scgp->dev = DEV_ACB4525;			else				scgp->dev = DEV_CCS_GENDISK;		} else if (strbeg("SONY", vendor_info) &&					strbeg("SMO-C501", prod_ident)) {			scgp->dev = DEV_SONY_SMO;		} else {			scgp->dev = DEV_CCS_GENDISK;		}		break;	case INQ_SEQD:		if (scgp->dev == DEV_SC4000) {			strcpy(inq->vendor_info,				"SYSGEN  SC4000          FAKE");		} else if (inq->add_len == 0 &&					inq->removable &&						inq->ansi_version == 1) {			scgp->dev = DEV_MT02;			strcpy(inq->vendor_info,				"EMULEX  MT02            FAKE");		}		break;/*	case INQ_OPTD:*/	case INQ_ROMD:	case INQ_WORM:		if (strbeg("RXT-800S", prod_ident))			scgp->dev = DEV_RXT800S;		/*		 * Start of CD-Recorders:		 */		if (strbeg("ACER", vendor_info)) { 			if (strbeg("CR-4020C", prod_ident))                                 scgp->dev = DEV_RICOH_RO_1420C;		} else if (strbeg("CREATIVE", vendor_info)) { 			if (strbeg("CDR2000", prod_ident))				scgp->dev = DEV_RICOH_RO_1060C;		} else if (strbeg("GRUNDIG", vendor_info)) { 			if (strbeg("CDR100IPW", prod_ident))				scgp->dev = DEV_CDD_2000;		} else if (strbeg("JVC", vendor_info)) {			if (strbeg("XR-W2001", prod_ident))				scgp->dev = DEV_TEAC_CD_R50S;			else if (strbeg("XR-W2010", prod_ident))				scgp->dev = DEV_TEAC_CD_R50S;			else if (strbeg("R2626", prod_ident))				scgp->dev = DEV_TEAC_CD_R50S;		} else if (strbeg("MITSBISH", vendor_info)) {#ifdef	XXXX_REALLY			/* It's MMC compliant */			if (strbeg("CDRW226", prod_ident))				scgp->dev = DEV_MMC_CDRW;#endif		} else if (strbeg("MITSUMI", vendor_info)) {			/* Don't know any product string */			scgp->dev = DEV_CDD_522;		} else if (strbeg("OPTIMA", vendor_info)) {			if (strbeg("CD-R 650", prod_ident))				scgp->dev = DEV_SONY_CDU_924;		} else if (strbeg("PHILIPS", vendor_info) ||				strbeg("IMS", vendor_info) ||				strbeg("KODAK", vendor_info) ||				strbeg("HP", vendor_info)) {			if (strbeg("CDD521/00", prod_ident))				scgp->dev = DEV_CDD_521_OLD;			else if (strbeg("CDD521/02", prod_ident))				scgp->dev = DEV_CDD_521_OLD;		/* PCD 200R? */

⌨️ 快捷键说明

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