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

📄 scsi-bsd.c

📁 另一种方法编辑刻录程序的代码!要的与偶联系呀
💻 C
📖 第 1 页 / 共 2 页
字号:
 * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */#undef	sense#define scsi_sense CAM_scsi_sense#define scsi_inquiry CAM_scsi_inquiry#include <sys/param.h>#include <cam/cam.h>#include <cam/cam_ccb.h>#include <cam/scsi/scsi_message.h>#include <cam/scsi/scsi_pass.h>#include <camlib.h>#define CAM_MAXDEVS	128struct cam_device *cam_devices[CAM_MAXDEVS + 1];/* * Build a list of everything we can find. */EXPORTint scsi_open(device, busno, tgt, tlun)	char	*device;	int	busno;	int	tgt;	int	tlun;{	struct cam_device		*dev;	char				name[16];	int				unit;	int				nopen = 0;	union ccb			ccb;	int				bufsize;	struct periph_match_pattern	*match_pat;	int				fd;	for (unit = 0; unit <= CAM_MAXDEVS; unit++) {		cam_devices[unit] = (struct cam_device *)-1;	}	/*	 * If we're not scanning the bus, just open one device.	 */	if (busno >= 0 && tgt >= 0 && tlun >= 0) {		cam_devices[0] = cam_open_btl(busno, tgt, tlun, O_RDWR, NULL);		if (cam_devices[0] == NULL)			return(-1);		nopen++;		return(nopen);	}	/*	 * First open the transport layer device.  There's no point in the	 * rest of this if we can't open it.	 */	if ((fd = open(XPT_DEVICE, O_RDWR)) < 0) {		errmsg("Open of %s failed.\n", XPT_DEVICE);	/* XXX Should be removed */		return(-1);	}	fillbytes(&ccb, sizeof(union ccb), '\0');	/*	 * Get a list of up to CAM_MAXDEVS passthrough devices in the	 * system.	 */	ccb.ccb_h.func_code = XPT_DEV_MATCH;	/*	 * Setup the result buffer.	 */	bufsize = sizeof(struct dev_match_result) * CAM_MAXDEVS;	ccb.cdm.match_buf_len = bufsize;	ccb.cdm.matches = (struct dev_match_result *)malloc(bufsize);	if (ccb.cdm.matches == NULL) {		errmsg("Couldn't malloc match buffer.\n");	/* XXX Should be removed */		close(fd);		return(-1);	}	ccb.cdm.num_matches = 0;	/*	 * Setup the pattern buffer.  We're matching against all	 * peripherals named "pass".	 */	ccb.cdm.num_patterns = 1;	ccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern);	ccb.cdm.patterns = (struct dev_match_pattern *)malloc(		sizeof(struct dev_match_pattern));	if (ccb.cdm.patterns == NULL) {		errmsg("Couldn't malloc pattern buffer.\n");	/* XXX Should be removed */		close(fd);		free(ccb.cdm.matches);		return(-1);	}	ccb.cdm.patterns[0].type = DEV_MATCH_PERIPH;	match_pat = &ccb.cdm.patterns[0].pattern.periph_pattern;	sprintf(match_pat->periph_name, "pass");	match_pat->flags = PERIPH_MATCH_NAME;	if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) {		errmsg("CAMIOCOMMAND ioctl failed.\n");		/* XXX Should be removed */		close(fd);		free(ccb.cdm.matches);		free(ccb.cdm.patterns);		return(-1);	}	if ((ccb.ccb_h.status != CAM_REQ_CMP)	 || ((ccb.cdm.status != CAM_DEV_MATCH_LAST)	    && (ccb.cdm.status != CAM_DEV_MATCH_MORE))) {		errmsgno(EX_BAD, "Got CAM error 0x%X, CDM error %d.\n",			ccb.ccb_h.status, ccb.cdm.status);		close(fd);		free(ccb.cdm.matches);		free(ccb.cdm.patterns);		return(-1);	}	free(ccb.cdm.patterns);	close(fd);	for (unit = 0; unit < MIN(CAM_MAXDEVS, ccb.cdm.num_matches); unit++) {		struct periph_match_result *periph_result;		/*		 * We shouldn't have anything other than peripheral		 * matches in here.  If we do, it means an error in the		 * device matching code in the transport layer.		 */		if (ccb.cdm.matches[unit].type != DEV_MATCH_PERIPH) {			errmsgno(EX_BAD,				"Kernel error! got periph match type %d!!\n",				ccb.cdm.matches[unit].type);			free(ccb.cdm.matches);			return(-1);		}		periph_result = &ccb.cdm.matches[unit].result.periph_result;		sprintf(name, "/dev/%s%d", periph_result->periph_name,			periph_result->unit_number);		/*		 * cam_open_pass() avoids all lookup and translation from		 * "regular device name" to passthrough unit number and		 * just opens the device in question as a passthrough device.		 */		cam_devices[unit] = cam_open_pass(name, O_RDWR, NULL);		/*		 * If we get back NULL from the open routine, it wasn't		 * able to open the given passthrough device for one reason		 * or another.		 */		if (cam_devices[unit] == NULL) {			errmsgno(EX_BAD, "Error opening /dev/%s%d\n",				periph_result->periph_name,				periph_result->unit_number);			errmsgno(EX_BAD, "%s\n", cam_errbuf);			break;		}		nopen++;	}	free(ccb.cdm.matches);	return (nopen);}LOCALlong scsi_maxdma(){	return (MAXPHYS);}EXPORT void *scsi_getbuf(amt)	long	amt;{	void	*ret;	if (scg_maxdma == 0)		scg_maxdma = MAXPHYS;	if (amt <= 0 || amt > scg_maxdma)		return ((void *)0);	if (debug)		printf("scsi_getbuf: %ld bytes\n", amt);	ret = valloc((size_t)(amt));	return (ret);}EXPORTBOOL scsi_havebus(int busno){	int		unit;	/*	 * There's a "cleaner" way to do this, using the matching code, but	 * it would involve more code than this solution...	 */	for (unit = 0; cam_devices[unit] != (struct cam_device *)-1; unit++) {		if (cam_devices[unit] == NULL)			continue;		if (cam_devices[unit]->path_id == busno)			return (TRUE);	}	return (FALSE);}EXPORTint scsi_fileno(bus, unit, lun){	int		i;	for (i = 0; cam_devices[i] != (struct cam_device *)-1; i++) {		if (cam_devices[i] == NULL)			continue;		if ((cam_devices[i]->path_id == bus) &&		    (cam_devices[i]->target_id == unit) &&		    (cam_devices[i]->target_lun == lun))			return (i);	}	return (-1);}EXPORTint scsi_isatapi(){	return (FALSE);}EXPORTint scsireset(){	/* XXX synchronous reset command - is this wise? */	return (-1);}LOCAL intscsi_send(int unit, struct scg_cmd *sp){	struct cam_device	*dev;	union ccb		ccb_space;	union ccb		*ccb = &ccb_space;	int			rv, result;	u_int32_t		ccb_flags;	if (unit < 0) {#if 0		fprintf(stderr, "attempt to reference invalid unit %d\n", unit);#endif		sp->error = SCG_FATAL;		return (0);	}	dev = cam_devices[unit];	fillbytes(&ccb->ccb_h, sizeof(struct ccb_hdr), '\0');	ccb->ccb_h.path_id = dev->path_id;	ccb->ccb_h.target_id = dev->target_id;	ccb->ccb_h.target_lun = dev->target_lun;	/* Build the CCB */	fillbytes(&(&ccb->ccb_h)[1], sizeof(struct ccb_scsiio), '\0');	movebytes(sp->cdb.cmd_cdb, &ccb->csio.cdb_io.cdb_bytes, sp->cdb_len);	/*	 * Set the data direction flags.	 */	if (sp->size != 0) {		ccb_flags = (sp->flags & SCG_RECV_DATA) ? CAM_DIR_IN :							   CAM_DIR_OUT;	} else {		ccb_flags = CAM_DIR_NONE;	}	ccb_flags |= CAM_DEV_QFRZDIS;	/*	 * If you don't want to bother with sending tagged commands under CAM,	 * we don't need to do anything to cdrecord.  If you want to send	 * tagged commands to those devices that support it, we'll need to set	 * the tag action valid field like this in scsi_send(): 	 *         	 *        ccb_flags |= CAM_DEV_QFRZDIS | CAM_TAG_ACTION_VALID;	 */	cam_fill_csio(&ccb->csio,		      /* retries */ 1,		      /* cbfncp */ NULL,		      /* flags */ ccb_flags,		      /* tag_action */ MSG_SIMPLE_Q_TAG,		      /* data_ptr */ (u_int8_t *)sp->addr,		      /* dxfer_len */ sp->size,		      /* sense_len */ SSD_FULL_SIZE,		      /* cdb_len */ sp->cdb_len,		      /* timeout */ sp->timeout * 1000);	/* Run the command */	errno = 0;	if ((rv = cam_send_ccb(dev, ccb)) == -1) {		return (rv);	} else {		/*		 * Check for command status.  Selection timeouts are fatal.		 * For command timeouts, we pass back the appropriate		 * error.  If we completed successfully, there's (obviously)		 * no error.  We declare anything else "retryable".		 */		switch(ccb->ccb_h.status & CAM_STATUS_MASK) {			case CAM_SEL_TIMEOUT:				result = SCG_FATAL;				break;			case CAM_CMD_TIMEOUT:				result = SCG_TIMEOUT;				break;			case CAM_REQ_CMP:				result = SCG_NO_ERROR;				break;			default:				result = SCG_RETRYABLE;				break;		}	}	sp->error = result;	if (result != SCG_NO_ERROR)		sp->ux_errno = EIO;	/* Pass the result back up */	fillbytes(&sp->scb, sizeof(sp->scb), '\0');	fillbytes(&sp->u_sense.cmd_sense, sizeof(sp->u_sense.cmd_sense), '\0');	sp->resid = ccb->csio.resid;	sp->sense_count = SSD_FULL_SIZE - ccb->csio.sense_resid;	/*	 * Determine how much room we have for sense data.	 */	if (sp->sense_count > SCG_MAX_SENSE)		sp->sense_count = SCG_MAX_SENSE;	/* Copy the sense data out */	movebytes(&ccb->csio.sense_data, &sp->u_sense.cmd_sense, sp->sense_count);	sp->u_scb.cmd_scb[0] = ccb->csio.scsi_status;	return (0);}#undef scsi_sense#undef scsi_inquiry#define sense u_sense.Sense#endif /* BSD_CAM */

⌨️ 快捷键说明

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