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.