SMCIOC_READ_ELEMENT_DEVIDS
This IOCTL command issues the SCSI Read Element Status command with the device ID(DVCID) bit set and returns the element descriptors for the data transfer elements. The element_address field specifies the starting address of the first data transfer element. The number_elements field specifies the number of elements to return. The application must allocate a return buffer large enough for the number of elements that are specified in the input structure.
The input data structure is
struct read_element_devids {
ushort element_address; /* starting element address */
ushort number_elements; /* number of elements */
struct element_devid *drive_devid; /* data transfer element pages */
};
The output data structure is
struct element_devid {
ushort address; /* element address */
uint :4, /* reserved */
access :1, /* robot access allowed */
except :1, /* abnormal element state */
:1, /* reserved */
full :1; /* element contains medium */
unchar resvd1; /* reserved */
unchar asc; /* additional sense code */
unchar ascq; /* additional sense code qualifier */
uint notbus :1, /* element not on same bus as robot */
:1, /* reserved */
idvalid :1, /* element address valid */
luvalid :1, /* logical unit valid */
:1, /* reserved */
lun :3; /* logical unit number */
unchar scsi; /* scsi bus address */
unchar resvd2; /* reserved */
uint svalid :1, /* element address valid */
invert :1, /* medium inverted */
:6; /* reserved */
ushort source; /* source storage element address */
uint :4, /* reserved */
code_set :4; /* code set X'2' is all ASCII identifier*/
uint :4, /* reserved */
ident_type :4; /* identifier type */
unchar resvd3; /* reserved */
unchar ident_len; /* identifier length */
unchar identifier[36]; /* device identification */
};
An example of the SMCIOC_READ_ELEMENT_DEVIDS command
is
#include <sys/IBM_tape.h>
int smcioc_read_element_devids() {
int i;
struct element_devid *elem_devid, *elemp;
struct read_element_devids devids;
struct element_info element_info;
if (ioctl(fd, SMCIOC_ELEMENT_INFO, &element_info)) return errno;
if (element_info.drives) {
elem_devid = malloc(element_info.drives
* sizeof(struct element_devid));
if (elem_devid == NULL) {
errno = ENOMEM;
return errno;
}
bzero((caddr_t)elem_devid,element_info.drives
* sizeof(struct element_devid));
devids.drive_devid = elem_devid;
devids.element_address = element_info.drive_addr;
devids.number_elements = element_info.drives;
printf("Reading element device ids?\n");
if (ioctl (fd, SMCIOC_READ_ELEMENT_DEVIDS, &devids)) {
free(elem_devid);
return errno;
}
elemp = elem_devid;
for (i = 0; i<element_info.drives; i++, elemp++) {
printf("\nDrive Address %d\n",elemp->address);
if (elemp->except)
printf(" Drive State .................... Abnormal\n");
else
printf(" Drive State .................... Normal\n");
if (elemp->asc == 0x81 && elemp->ascq ==0x00)
printf(" ASC/ASCQ ....................... %02X%02X (Drive Present)\n",
elemp->asc,elemp->ascq);
else if (elemp->asc == 0x82 && elemp->ascq ==0x00)
printf(" ASC/ASCQ ....................... %02X%02X (Drive Not Present)\n",
elemp->asc,elemp->ascq);
else
printf(" ASC/ASCQ ....................... %02X%02X\n",
elemp->asc,elemp->ascq);
if (elemp->full)
printf(" Media Present .................. Yes\n");
else
printf(" Media Present .................. No\n");
if (elemp->access)
printf(" Robot Access Allowed ........... Yes\n");
else
printf(" Robot Access Allowed ........... No\n");
if (elemp->svalid)
printf(" Source Element Address ......... %d\n",
elemp->source);
else
printf(" Source Element Address Valid .....No\n");
if (elemp->invert)
printf(" Media Inverted ................. Yes\n");
else
printf(" Media Inverted ................. No\n");
if (elemp->notbus)
printf(" Same Bus as Medium Changer ..... No\n");
else
printf(" Same Bus as Medium Changer ..... Yes\n");
if (elemp->idvalid)
printf(" SCSI Bus Address ............... %d\n",elemp->scsi);
else
printf(" SCSI Bus Address Valid ......... No\n");
if (elemp->luvalid)
printf(" Logical Unit Number ............ %d\n",elemp->lun);
else
printf(" Logical Unit Number Valid ...... No\n");
printf(" Device ID ...................... %0.36s\n",
elemp->identifier);
}
else {
printf("\nNo drives found in element information\n");
}
free(elem_devid);
return errno;
}