ftp.nice.ch/pub/next/unix/scsi/scsitools.N.bs.tar.gz#/scsitools/sense.c

This is sense.c in view mode; [Download] [Up]

/*
 * sense - dumps SCSI sense page codes
 *      by Charles E. Chambers (chambers@uh.edu)
 *      Mar 20, 1991
 */

/*
                      USE AT YOUR OUR RISK. 
      I NOT NOT BE RESPONSIBLE FOR PROBLEM CAUSED BY THIS PROGRAM.

Note that I have only tested these programs on a small number of drives (see PARAMETERS directories). BE CAREFUL, if you do not know what you are doing, then I recommend that you not use it. But it is very useful for those people that do know.
 */

#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <nextdev/scsireg.h>

static char *dev_name="/dev/sg0";	/* generic scsi interface */

int scsi_open(int target, int lun);
void scsi_show_mode_sense_format(int fd, int lun, int pagecode);
void scsi_show_inquiry(int fd, int lun);
int gs_inquiry(int fd, int lun, int clen, u_char *data);
int gs_mode_sense(int fd, int lun, int ccode, int cfield, int clen, u_char *data);
int gs_mode_select(int fd, int lun, int clen, u_char *data);
int gs_request_sense(int fd, int lun);

main(int argc, char *argv[])
{
	extern int optind;
	extern char *optarg;

	char c;

	int fd;
	int target = -1;
	int lun = -1;
	int pagecode = -1;

	while ((c = getopt(argc, argv, "t:l:p:")) != EOF) {
		switch (c) {
		case 't':
			target = atoi(optarg);
			break;
		case 'l':
			lun = atoi(optarg);
			break;
		case 'p':
			pagecode = atoi(optarg);
			break;
		default:
			fprintf(stderr,
			   "usage: %s -t<target> [-l<lun>] -p<pagecode>\n",
			    argv[0]);
			exit(1);
		
		}
	}
	if (target == -1) {
		fprintf(stderr,
			"usage: %s -t<target> [-l<lun>] -p<pagecode>\n",
			argv[0]);
		exit(1);
	}
	if (lun == -1) {
		lun = 0;
	}
	if (pagecode == -1) {
		fprintf(stderr,
			"usage: %s -t<target> [-l<lun>] -p<pagecode>\n",
			argv[0]);
		exit(1);
	}
	if ((fd = scsi_open(target, lun)) < 0) {
		fputs("error opening scsi device\n", stderr);
		exit(1);
	}
	scsi_show_inquiry(fd, lun);
	scsi_show_mode_sense_format(fd, lun, pagecode);
	exit(0);
}

int scsi_open(int target, int lun)
{
	struct scsi_adr sa;
	int fd;

	if ((fd = open(dev_name, O_RDWR)) < 0) {
		fprintf(stderr,"\nCould not open %s\n",dev_name);
		return(-1);
	}

	sa.sa_target = target;
	sa.sa_lun = lun;
	if (ioctl(fd,SGIOCSTL,&sa) < 0) {
		fprintf(stderr,"Error setting target %d lun %d\n",target,lun);
		close(fd);
		return(-1);
	}

	if(gs_request_sense(fd, lun)) {		/* clear unit attention */
		close(fd);
		return(-1);
	}
	return(fd);
}

void scsi_show_inquiry(int fd, int lun)
{
	u_char data[64];
	int i;
	
	bzero(data, sizeof(data));
	if(gs_inquiry(fd, lun, sizeof(data), data)) {
		fputs("error in inquiry\n", stderr);
		close(fd);
		exit(1);
	}
	fprintf(stdout,"#-INQUIRY data\n"); 
	fprintf(stdout,"# vid   /"); 
	for (i=8;i<16;i++) fprintf(stdout,"%c",data[i]);
	fprintf(stdout,"/\n");
	fprintf(stdout,"# pid   /"); 
	for (i=16;i<32;i++) fprintf(stdout,"%c",data[i]);
	fprintf(stdout,"/\n");
	fprintf(stdout,"# firm  /"); 
	for (i=32;i<36;i++) fprintf(stdout,"%c",data[i]);
	fprintf(stdout,"/\n");
	fprintf(stdout, "-ilen %4.4d\n",sizeof(data));
	for (i = 0; i < sizeof(data); i++)
		fprintf(stdout, "-idat %4.4d %2.2x\n"
		             ,i,data[i]);
}

void scsi_show_mode_sense_format(int fd, int lun, int pagecode)
{
	u_char current[128];
	u_char mask[128];
	u_char deflt[128];
	u_char saved[128];
	int i,j;

	bzero(current, sizeof(current));
	if(gs_mode_sense(fd, lun, pagecode, 0, sizeof(current), current)) {
		fputs("error in mode sense\n", stderr);
		close(fd);
		exit(1);
	}
	bzero(mask, sizeof(mask));
	if(gs_mode_sense(fd, lun, pagecode, 1, sizeof(mask), mask)) {
		fputs("error in mode sense\n", stderr);
		close(fd);
		exit(1);
	}
	bzero(deflt, sizeof(deflt));
	if(gs_mode_sense(fd, lun, pagecode, 2, sizeof(deflt), deflt)) {
		fputs("error in mode sense\n", stderr);
		close(fd);
		exit(1);
	}
	bzero(saved, sizeof(saved));
	if(gs_mode_sense(fd, lun, pagecode, 3, sizeof(saved), saved)) {
		fputs("error in mode sense\n", stderr);
		close(fd);
		exit(1);
	}
	fprintf(stdout,"#-MODE SENSE data\n");
	fprintf(stdout,"-mlen %4.4d\n",saved[0]+1);
	fprintf(stdout,"# Parameter List Header\n");
	fprintf(stdout, "#mhdr offs val msk # cur msk def sav\n");
	for ( i = 0; i <= 3; i++)
		fprintf(stdout, "-mhdr %4.4d  %2.2x  %2.2x #  %2.2x  %2.2x  %2.2x  %2.2x\n"
		             ,i,saved[i]&mask[i],mask[i]
			     ,current[i],mask[i],deflt[i],saved[i]);
	fprintf(stdout,"# Parameter List Block Descriptor Format\n");
	fprintf(stdout, "#mbdf offs val msk # cur msk def sav\n");
	for ( i = 4; i <= saved[3]+3; i++)
		fprintf(stdout, "-mbdf %4.4d  %2.2x  %2.2x #  %2.2x  %2.2x  %2.2x  %2.2x\n"
		             ,i-4,saved[i]&mask[i],mask[i]
			     ,current[i],mask[i],deflt[i],saved[i]);
	for ( i = saved[3]+4; i <= saved[0]; i = i + saved[i+1] + 2) {
		fprintf(stdout, "# Page Code %2.2x\n",saved[i]&63);
		fprintf(stdout, "#mp%2.2d offs val msk # cur msk def sav\n"
		    ,saved[i]&63);
		for ( j = 0; j <= saved[i+1]+1; j++)
			fprintf(stdout, "-mp%2.2d %4.4d  %2.2x  %2.2x #  %2.2x  %2.2x  %2.2x  %2.2x\n"
		             ,(saved[i]&63),j,saved[i+j]&mask[i+j],mask[i+j]
			     ,current[i+j],mask[i+j],deflt[i+j],saved[i+j]);
	}
	close(fd);
}

int gs_inquiry(int fd, int lun, int clen, u_char *data)
{
	struct scsi_req sr;
	struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;

	bzero((char *)&sr, sizeof(sr));
	cdbp->c6_opcode = C6OP_INQUIRY;
	cdbp->c6_lun    = lun;
	cdbp->c6_lba	= 0;
	cdbp->c6_len	= clen;
	sr.sr_dma_dir	= SR_DMA_RD;
	sr.sr_addr	= (caddr_t)data;
	sr.sr_dma_max	= clen;
	sr.sr_ioto	= 10;
	return(do_ioc(fd, &sr));
}


int gs_mode_sense(int fd, int lun, int ccode, int cfield, int clen, u_char *data)
{
	struct scsi_req sr;
	struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;

	bzero((char *)&sr, sizeof(sr));
	cdbp->c6_opcode = C6OP_MODESENSE;
	cdbp->c6_lun    = lun;
	cdbp->c6_lba	= ((cfield << 14) & 0xc000) | ((ccode << 8) & 0x3f00);
	cdbp->c6_len	= clen;
	sr.sr_dma_dir	= SR_DMA_RD;
	sr.sr_addr	= (caddr_t)data;
	sr.sr_dma_max	= clen;
	sr.sr_ioto	= 10;
	return(do_ioc(fd, &sr));
}

int do_ioc(int fd, struct scsi_req *sr)
{
	if (ioctl(fd, SGIOCREQ, sr) < 0) {
		perror("ioctl(SGIOCREQ)");
		return(-1);
	}
	if(sr->sr_io_status) {
		fprintf(stderr,"sr_io_status = 0x%02X\n",sr->sr_io_status);
		if(sr->sr_io_status == SR_IOST_CHKSV) {
			fprintf(stderr,
				"sense key = 0x%02X, sense code = 0x%02X\n",
				sr->sr_esense.er_sensekey,
				sr->sr_esense.er_addsensecode);
		}
		fprintf(stderr,"SCSI status = 0x%02X\n", sr->sr_scsi_status);
		return(-1);
	}
	return(0);
}

int gs_request_sense(int fd, int lun)
{
	struct scsi_req sr;
	struct cdb_6 *cdbp = &sr.sr_cdb.cdb_c6;
	u_char sbuf[128];

	bzero((char *)&sr, sizeof(sr));
	cdbp->c6_opcode = C6OP_REQSENSE;
	cdbp->c6_lun    = lun;
	cdbp->c6_len	= 18;
	sr.sr_dma_dir	= SR_DMA_RD;
	sr.sr_addr	= (caddr_t)sbuf;
	sr.sr_dma_max	= 128;
	sr.sr_ioto	= 10;
	return(do_ioc(fd, &sr));
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.