Hi,
With the attached program I'm trying to send a USCSI command to tape
library robot arm. I'm sending the USCSI command - "identify
yourself". It works fine with a disk device but not with an sg device:
# ./probeforsgen /dev/rdsk/c0t0d0s2
Disk: FUJITSU MAB3091S SUN9.0G 2107 9908K52616
# ./probeforsgen /dev/sg/c4t6l0
ioctl error on /dev/sg/c4t6l0
ioctl: Inappropriate ioctl for device
# ls -l /dev/sg/c4t6l0
lrwxrwxrwx 1 root other 43 Mar 9 2001 /dev/sg/c4t6l0
Would you know what's gone wrong? I seen various newsgroup
conversation indicating that this should work OK. Thanks for any help.
The program is as follows:
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <values.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/scsi/generic/mode.h>
#include <sys/scsi/generic/commands.h>
#include <sys/scsi/generic/status.h>
#include <sys/scsi/impl/types.h>
#include <sys/scsi/impl/uscsi.h>
#include <sys/systeminfo.h>
#include <sys/scsi/impl/types.h>
#include <sys/scsi/impl/uscsi.h>
#define bzero(b,l) memset(b,0,l)
extern int errno;
/*
* Names of SCSI commands
*/
#define SCSI_COMMAND_COUNT 10
static struct scsi_command_name {
u_char command;
char *name;
SCMD_FORMAT, "format",Quote:} scsi_command_names[] = {
SCMD_READ, "read",
SCMD_WRITE, "write",
SCMD_READ|SCMD_GROUP1, "read",
SCMD_WRITE|SCMD_GROUP1, "write",
SCMD_INQUIRY, "inquiry",
SCMD_MODE_SELECT, "mode select",
SCMD_MODE_SENSE, "mode sense",
SCMD_REASSIGN_BLOCK, "reassign block",
SCMD_READ_DEFECT_LIST, "read defect list"
#define DUMMY_SCSI_STATUS 0xffQuote:};
#define MIN_REQUEST_SENSE_LEN 18
#define DISK_STAT_NOTREADY 0x02
/*
* Look up the command name from command code
*/
char *scsi_get_command_name(cmd)
u_int cmd;
{
int i;
int found=0;
for (i==0;i<SCSI_COMMAND_COUNT;++i) {
if (scsi_command_names[i].command==cmd) {found=1;break;};
};
if (found) {return(scsi_command_names[i].name);}
else {return("unknown");};
char *scsi_dtype(dtype)Quote:}
u_int dtype;
{
switch(dtype){
case DTYPE_DIRECT: return("Disk");
case DTYPE_SEQUENTIAL: return("Tape");
case DTYPE_PRINTER: return("Printer");
case DTYPE_PROCESSOR: return("Processor");
case DTYPE_WORM: return("WORM Drive");
case DTYPE_RODIRECT: return("CD-ROM");
case DTYPE_SCANNER: return("Scanner");
case DTYPE_OPTICAL: return("Optical Disk");
case DTYPE_CHANGER: return("Changer");
case DTYPE_COMM: return("Comm");
default: return("Unknown");
}
main(argc, argv)Quote:}
int argc;
char *argv[];
{
#define SCSIBUFLEN 256
#define SENSEBUFLEN 256
char diskname[257];
int disk;
struct uscsi_cmd cmd;
union scsi_cdb cdb;
struct scsi_inquiry *inq;
char iobuff[SCSIBUFLEN];
char sensebuff[SENSEBUFLEN];
struct scsi_extended_sense *ses;
int seslen;
int status;
if (argc!=2) {
printf("Usage: %s <device>\n",argv[0]);
exit(1);
};
strcpy(diskname,argv[1]);
if ((disk=open(diskname,O_RDONLY))==-1) {
perror("Disk drive cannot be openned");
exit(1);
}
inq = (struct scsi_inquiry *)iobuff;
/* set up SCSI inquiry command */
bzero(&cdb, sizeof(cdb));
bzero(inq, sizeof(inq));
cdb.scc_cmd = SCMD_INQUIRY;
FORMG0COUNT(&cdb, (u_char)inq);
cmd.uscsi_cdb=(caddr_t)&cdb;
cmd.uscsi_cdblen=CDB_GROUP0; /* SCSI Group 0 cmd */
cmd.uscsi_bufaddr=(caddr_t)inq;
cmd.uscsi_buflen=SCSIBUFLEN;
cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_SILENT|USCSI_ISOLATE|USCSI_READ;
cmd.uscsi_timeout=30;
status=ioctl(disk, USCSICMD, &cmd);
/* OK */
if ((status==0) && (cmd.uscsi_status==0)) {
printf("%s:\t", scsi_dtype(inq->inq_dtype));
printf("%-8.8s %-16.16s %-4.4s %12.12s\n", inq->inq_vid,
inq->inq_pid, inq->inq_revision, inq->inq_serial);
close(disk);
exit(0);
exit(0);
};
/* Disk not available - busy formatting*/
if (status==-1 && errno==EAGAIN) {
printf("%s is not available - possibly formatting\n",diskname);
close(disk);
exit(1);
};
if ((cmd.uscsi_status & STATUS_MASK)==STATUS_RESERVATION_CONFLICT) {
printf("%s is not available - possibly formatting\n",diskname);
close(disk);
exit(1);
};
/* Disk physically removed or not responding */
if ((status==-1) && (cmd.uscsi_status==0) && (errno == EIO)) {
printf("%s is not responding\n",diskname);
close(disk);
exit(1);
};
printf("ioctl error on %s\n",diskname);
perror("ioctl");
close(disk);
Quote:}