419 lines
22 KiB
HTML
419 lines
22 KiB
HTML
|
<?xml version="1.0" encoding="UTF-8"?>
|
||
|
<!DOCTYPE html
|
||
|
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html lang="en-us" xml:lang="en-us">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<meta name="security" content="public" />
|
||
|
<meta name="Robots" content="index,follow" />
|
||
|
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
|
||
|
<meta name="DC.Type" content="reference" />
|
||
|
<meta name="DC.Title" content="Example: Using the control device (QTACTLDV) API" />
|
||
|
<meta name="abstract" content="This example shows how the QTACTLDV (Control Device) API could be used to send a diagnostic command to a tape device." />
|
||
|
<meta name="description" content="This example shows how the QTACTLDV (Control Device) API could be used to send a diagnostic command to a tape device." />
|
||
|
<meta name="DC.Relation" scheme="URI" content="apiexmp.htm" />
|
||
|
<meta name="copyright" content="(C) Copyright IBM Corporation 1998, 2006" />
|
||
|
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 1998, 2006" />
|
||
|
<meta name="DC.Format" content="XHTML" />
|
||
|
<meta name="DC.Identifier" content="apiexusdev" />
|
||
|
<meta name="DC.Language" content="en-us" />
|
||
|
<!-- All rights reserved. Licensed Materials Property of IBM -->
|
||
|
<!-- US Government Users Restricted Rights -->
|
||
|
<!-- Use, duplication or disclosure restricted by -->
|
||
|
<!-- GSA ADP Schedule Contract with IBM Corp. -->
|
||
|
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
|
||
|
<link rel="stylesheet" type="text/css" href="./ic.css" />
|
||
|
<title>Example: Using the control device (QTACTLDV) API</title>
|
||
|
</head>
|
||
|
<body id="apiexusdev"><a name="apiexusdev"><!-- --></a>
|
||
|
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
|
||
|
<h1 class="topictitle1">Example: Using the control device (QTACTLDV) API</h1>
|
||
|
<div><p>This example shows how the QTACTLDV (Control Device) API could
|
||
|
be used to send a diagnostic command to a tape device.</p>
|
||
|
<div class="section"><div class="note"><span class="notetitle">Note:</span> Read the <a href="codedisclaimer.htm">Code license and disclaimer information</a> for important
|
||
|
legal information.</div>
|
||
|
<pre>/* Usage example 1 for QTACTLDV API */
|
||
|
/* */
|
||
|
/* */
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <qtactldv.h>
|
||
|
#include <qusec.h>
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Typedef structure for QTACTLDV */
|
||
|
/********************************************************************/
|
||
|
typedef struct { /* QTACTLDV command data */
|
||
|
Qta_CTLD0100_t data; /* command data */
|
||
|
char cmd_str[6]; /* command string */
|
||
|
} cmd_struct;
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Typedef structure for Error code */
|
||
|
/********************************************************************/
|
||
|
typedef struct { /* Error code structure */
|
||
|
Qus_EC_t Edata; /* Error code data */
|
||
|
/* CPF67C8 excp data */
|
||
|
char dev_nam[10]; /* Device name */
|
||
|
char reason_cd[3]; /* Reason code */
|
||
|
char resv1[3]; /* Reserved */
|
||
|
} EC_struct;
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Constants */
|
||
|
/********************************************************************/
|
||
|
|
||
|
#define SNDRSNS "\x03\x00\x00\x00\x12\x00" /* Request sense */
|
||
|
/* command string */
|
||
|
#define SNDDIAG "\x1D\x04\x00\x00\x00\x00" /* Send diagnostic */
|
||
|
/* command string */
|
||
|
|
||
|
|
||
|
main(int argc,char *argv[])
|
||
|
{
|
||
|
/********************************************************************/
|
||
|
/* */
|
||
|
/* START OF MAINLINE */
|
||
|
/* */
|
||
|
/********************************************************************/
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Variables for QTACTLDV */
|
||
|
/********************************************************************/
|
||
|
char device[10]; /* device name */
|
||
|
char send_buff[256]; /* send buffer */
|
||
|
int send_buff_len; /* length of send buffer */
|
||
|
char recv_buff[256]; /* receive buffer */
|
||
|
int recv_buff_len; /* length of recv buffer */
|
||
|
int cmd_data_len; /* length of command data */
|
||
|
int i; /* counter variable */
|
||
|
|
||
|
EC_struct EC; /* error code structure */
|
||
|
cmd_struct Cmd; /* struct for QTACTLDV */
|
||
|
|
||
|
memcpy(device,argv[1],10); /* copy device name */
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* OPEN connection */
|
||
|
/********************************************************************/
|
||
|
send_buff_len = 0; /* no send buffer */
|
||
|
recv_buff_len = 0; /* no receive buffer */
|
||
|
cmd_data_len = 0; /* no command data */
|
||
|
EC.Edata.Bytes_Provided = 32; /* No exceptions */
|
||
|
|
||
|
QTACTLDV(device, /* device name */
|
||
|
FUNOPEN, /* requested function */
|
||
|
send_buff, /* send buffer */
|
||
|
send_buff_len, /* length of send buffer */
|
||
|
recv_buff, /* receive buffer */
|
||
|
recv_buff_len, /* length of receive buffer */
|
||
|
CTLD0100, /* command format */
|
||
|
&Cmd, /* command data */
|
||
|
cmd_data_len, /* length of command data */
|
||
|
&EC); /* Error Code */
|
||
|
|
||
|
if (EC.Edata.Bytes_Available>0) /* If there was an error */
|
||
|
{
|
||
|
/* Handle the error */
|
||
|
}
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Send Diagnostic command */
|
||
|
/********************************************************************/
|
||
|
send_buff_len = 0; /* no send buffer */
|
||
|
recv_buff_len = 0; /* no recv buffer */
|
||
|
cmd_data_len = sizeof(Cmd); /* size of command struct */
|
||
|
EC.Edata.Bytes_Provided = 32; /* No exceptions */
|
||
|
Cmd.data.Data_transfer_direction = XFRNONE; /* No data transfer */
|
||
|
Cmd.data.Requested_transfer_length = 0; /* 0 transfer length */
|
||
|
Cmd.data.Ignore_length_errors = RPTLERR; /* report length errs */
|
||
|
Cmd.data.Command_timeout = 600; /* 10 minute timeout */
|
||
|
Cmd.data.Type_of_command = CMDSCSI; /* SCSI command */
|
||
|
Cmd.data.Offset_to_command_string = 32; /* offset 32 */
|
||
|
Cmd.data.Length_of_command_string = 6; /* 6 byte command */
|
||
|
Cmd.data.Reserved1=0; /* reserved */
|
||
|
memcpy(&Cmd.cmd_str, SNDDIAG, 6); /* command string */
|
||
|
|
||
|
QTACTLDV(device, /* device name */
|
||
|
FUNCMD, /* requested function */
|
||
|
send_buff, /* send buffer */
|
||
|
send_buff_len, /* length of send buffer */
|
||
|
recv_buff, /* receive buffer */
|
||
|
recv_buff_len, /* length of receive buffer */
|
||
|
CTLD0100, /* command format */
|
||
|
&Cmd, /* command data */
|
||
|
cmd_data_len, /* length of command data */
|
||
|
&EC); /* Error code */
|
||
|
|
||
|
if (EC.Edata.Bytes_Available>0) /* If there was an error */
|
||
|
{
|
||
|
/* See what message was returned */
|
||
|
if (strncmp(EC.Edata.Exception_Id,"CPF67C8",7)==0) /* Command
|
||
|
failed msg */
|
||
|
{
|
||
|
/****************************************************************/
|
||
|
/* Check the data returned with CPF67C8 */
|
||
|
/****************************************************************/
|
||
|
|
||
|
if (strncmp(EC.reason_cd,"\x02\xC0", 2) == 0) /* Device detected
|
||
|
error */
|
||
|
{
|
||
|
/* Check the SCSI completion status */
|
||
|
if (EC.reason_cd[2]=='\x02') /* Check condition status */
|
||
|
{
|
||
|
/************************************************************/
|
||
|
/* Send Request Sense command */
|
||
|
/************************************************************/
|
||
|
send_buff_len = 0; /* no send buffer */
|
||
|
recv_buff_len = 18; /* length of recv buffer */
|
||
|
cmd_data_len = sizeof(Cmd); /* size of command struct */
|
||
|
Cmd.data.Data_transfer_direction = XFRRECV; /* receive */
|
||
|
Cmd.data.Requested_transfer_length = 18; /* 18 bytes */
|
||
|
Cmd.data.Ignore_length_errors = IGNLERR; /* ignore length
|
||
|
errors */
|
||
|
Cmd.data.Command_timeout = 60; /* 60 sec timeout */
|
||
|
Cmd.data.Type_of_command = CMDSCSI; /* SCSI command */
|
||
|
Cmd.data.Offset_to_command_string = 32; /* offset 32 */
|
||
|
Cmd.data.Length_of_command_string = 6; /* 6 byte cmd */
|
||
|
Cmd.data.Reserved1=0; /* reserved */
|
||
|
memcpy(&Cmd.cmd_str, SNDRSNS, 6); /* command string */
|
||
|
|
||
|
EC.Edata.Bytes_Provided = 32; /* No exceptions */
|
||
|
|
||
|
QTACTLDV(device, /* device name */
|
||
|
FUNCMD, /* requested function */
|
||
|
send_buff, /* send buffer */
|
||
|
send_buff_len, /* length of send buffer */
|
||
|
recv_buff, /* receive buffer */
|
||
|
recv_buff_len, /* length of receive buffer */
|
||
|
CTLD0100, /* command format */
|
||
|
&Cmd, /* command data */
|
||
|
cmd_data_len, /* length of command data */
|
||
|
&EC); /* Error code */
|
||
|
|
||
|
if (EC.Edata.Bytes_Available>0) /* If there was an error */
|
||
|
{
|
||
|
/* Handle error on request sense command */
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* Parse the request sense data to determine what action */
|
||
|
/* to take. */
|
||
|
}
|
||
|
}
|
||
|
else if (EC.reason_cd[2]=='\x08') /* Busy status */
|
||
|
{
|
||
|
/* Try the command again later */
|
||
|
}
|
||
|
else /* Unexpected completion status */
|
||
|
{
|
||
|
/* Send error message for unexpected completion status */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else if (strncmp(EC.reason_cd,"\x02\xC1\x00", 3) == 0)
|
||
|
/* Selection timeout */
|
||
|
{
|
||
|
/* Send message that device might be powered off */
|
||
|
}
|
||
|
|
||
|
/* Add else if for the other reason codes here */
|
||
|
|
||
|
else
|
||
|
{
|
||
|
/* Send error message for unexpected reason code */
|
||
|
}
|
||
|
}
|
||
|
|
||
|
else
|
||
|
{
|
||
|
/* Handle other messages */
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
/* No error */
|
||
|
}
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* CLOSE connection */
|
||
|
/********************************************************************/
|
||
|
send_buff_len = 0; /* no send buffer */
|
||
|
recv_buff_len = 0; /* no receive buffer */
|
||
|
cmd_data_len = 0; /* no command data */
|
||
|
EC.Edata.Bytes_Provided = 32; /* No exceptions */
|
||
|
|
||
|
QTACTLDV(device, /* device name */
|
||
|
FUNCLOS, /* requested function */
|
||
|
send_buff, /* send buffer */
|
||
|
send_buff_len, /* length of send buffer */
|
||
|
recv_buff, /* receive buffer */
|
||
|
recv_buff_len, /* length of receive buffer */
|
||
|
CTLD0100, /* command format */
|
||
|
&Cmd, /* command data */
|
||
|
cmd_data_len, /* length of command data */
|
||
|
&EC.Edata); /* Error code */
|
||
|
|
||
|
if (EC.Edata.Bytes_Available>0) /* If there was an error */
|
||
|
{
|
||
|
/* Handle the error */
|
||
|
}
|
||
|
|
||
|
}</pre>
|
||
|
<p>This example shows how the QTACTLDV (Control
|
||
|
Device) API could be used to display the tape device firmware level. </p>
|
||
|
<pre>/* Usage example 2 for QTACTLDV API */
|
||
|
/* */
|
||
|
/* */
|
||
|
|
||
|
#include // Control Device API
|
||
|
#include // Error code header
|
||
|
#include // String Header File
|
||
|
#include // Standard I/O Header
|
||
|
#include // Standard Library Header
|
||
|
#include // Exception & cancel declares
|
||
|
|
||
|
/*********************************************************************/
|
||
|
/* Type definitions */
|
||
|
/*********************************************************************/
|
||
|
// Define the command structure for sending commands using QTACTLDV API.
|
||
|
typedef struct { // Command Structure
|
||
|
Qta_CTLD0100_t hdr; // Header
|
||
|
char cmd_str[6]; // Command String
|
||
|
} ctldv_cmd_t;
|
||
|
|
||
|
/**********************************************************************/
|
||
|
/* Entry point to program. */
|
||
|
/**********************************************************************/
|
||
|
int main (int argc, char *argv[])
|
||
|
{
|
||
|
char device[10]; // Device name to get FM level
|
||
|
int deviceLen; // Length of device name to cop
|
||
|
char send_buff[1]; // Send buffer
|
||
|
int send_buff_len; // Length of send buffer
|
||
|
char recv_buff[50]; // Receive buffer
|
||
|
int recv_buff_len; // Length of receive buffer
|
||
|
ctldv_cmd_t ctldv_cmd; // Command variable
|
||
|
int ctldv_cmd_len; // Length of command string
|
||
|
char tempChar; // Used to conver ASCII to EBCD
|
||
|
Qus_EC_t EC; // Error code for qtactldv
|
||
|
char code[4]; // EBCDIC code level
|
||
|
int i; // Iterator to move ASCII to EB
|
||
|
|
||
|
EC.Bytes_Provided = 0; // Return errors to user
|
||
|
memset(device, ' ', sizeof(device)); // Set to blanks
|
||
|
deviceLen=strlen(argv[1]);
|
||
|
if (deviceLen>10)
|
||
|
deviceLen=10;
|
||
|
memcpy(device, argv[1], deviceLen); // Copy up to 10 chars
|
||
|
|
||
|
memset(code, ' ', sizeof(code)); // Clear code level
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Open the pipe. */
|
||
|
/********************************************************************/
|
||
|
send_buff_len = 0; // No send buffer
|
||
|
recv_buff_len = 0; // No receive buffer
|
||
|
ctldv_cmd_len = 0; // No command
|
||
|
|
||
|
#pragma exception_handler(PipeFailed, 0, 0, _C2_MH_ESCAPE, _CTLA_HANDLE)
|
||
|
QTACTLDV(device, // Device name
|
||
|
FUNOPEN, // Function requested
|
||
|
send_buff, // Send buffer
|
||
|
send_buff_len, // Send buffer length
|
||
|
recv_buff, // Receive buffer
|
||
|
recv_buff_len, // Receive buffer length
|
||
|
CTLD0100, // Command structure
|
||
|
&cldv_cmd, // Command data
|
||
|
ctldv_cmd_len, // Command data length
|
||
|
&EC); // Error structure
|
||
|
#pragma disable_handler
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Get the drive VPD */
|
||
|
/********************************************************************/
|
||
|
recv_buff_len = 16; // Receive buffer for VPD
|
||
|
send_buff_len = 0; // No send buffer
|
||
|
ctldv_cmd_len = 32 + 6; // Reserve command size
|
||
|
ctldv_cmd.hdr.Command_timeout = 600; // 10 minute timeout
|
||
|
ctldv_cmd.hdr.Type_of_command = 0; // SCSI Command
|
||
|
ctldv_cmd.hdr.Offset_to_command_string = sizeof(ctldv_cmd.hdr); // Offset 32
|
||
|
ctldv_cmd.hdr.Length_of_command_string = 6; // 6 byte command
|
||
|
ctldv_cmd.hdr.Reserved1 = 0; // Reserved
|
||
|
ctldv_cmd.hdr.Data_transfer_direction=XFRRECV; // Receiving inquiry data
|
||
|
ctldv_cmd.hdr.Requested_transfer_length=16; // Number of bytes to transfer
|
||
|
ctldv_cmd.hdr.Ignore_length_errors = RPTLERR; // Report length errors
|
||
|
memset(ctldv_cmd.cmd_str, 0x00, 6); // clear command
|
||
|
ctldv_cmd.cmd_str[0] = 0x12; // set to Inquiry command
|
||
|
ctldv_cmd.cmd_str[1] = 0x01; // set EVPD mode
|
||
|
ctldv_cmd.cmd_str[2] = 0x03; // Set code page - VPD
|
||
|
ctldv_cmd.cmd_str[4] = 0x10; // Allocation length
|
||
|
|
||
|
#pragma exception_handler(PipeClose, 0, 0, _C2_MH_ESCAPE, _CTLA_HANDLE)
|
||
|
QTACTLDV(device, // Device name
|
||
|
FUNCMD, // Function requested
|
||
|
send_buff, // Send buffer
|
||
|
send_buff_len, // Send buffer length
|
||
|
recv_buff, // Receive buffer
|
||
|
recv_buff_len, // Receive buffer length
|
||
|
CTLD0100, // Command structure
|
||
|
&cldv_cmd, // Command data
|
||
|
ctldv_cmd_len, // Command data length
|
||
|
&EC); // Error structure
|
||
|
#pragma disable_handler
|
||
|
|
||
|
/********************************************************************/
|
||
|
/* Convert the level to EBSDIC */
|
||
|
/********************************************************************/
|
||
|
for (i = 0; (i < sizeof(code)); i++)
|
||
|
{
|
||
|
tempChar = recv_buff[12+i]; // Code offest in VPD data
|
||
|
if (tempChar < 0x41) // is it a number?
|
||
|
tempChar = tempChar - 0x30 + 0xF0; // ASCII to EBCDII 0-9
|
||
|
else {
|
||
|
tempChar = tempChar & 0xDF; // Convert to ASCII uppercase
|
||
|
if (tempChar < 0x4A) // is char < J ?
|
||
|
tempChar = tempChar - 0x41 + 0xC1; // ASCII to EBCDII A-I
|
||
|
else if (tempChar < 0x53) // is char < S
|
||
|
tempChar = tempChar - 0x4A + 0xD1; // ASCII to EBCDII J-R
|
||
|
else
|
||
|
tempChar = tempChar - 0x53 + 0xE2; // ASCII to EBCDII S-Z
|
||
|
}
|
||
|
code[i] = tempChar; // Output the EBCDIC char
|
||
|
}
|
||
|
printf("The code level is: %s\n", code);
|
||
|
|
||
|
/*********************************************************************/
|
||
|
/* Close the pipe. */
|
||
|
/*********************************************************************/
|
||
|
PipeClose:
|
||
|
send_buff_len = 0; // No send buffer
|
||
|
recv_buff_len = 0; // No receive buffer
|
||
|
ctldv_cmd_len = 0; // No command
|
||
|
|
||
|
#pragma exception_handler(PipeFailed, 0, 0, _C2_MH_ESCAPE, _CTLA_HANDLE)
|
||
|
QTACTLDV(device, // Device name
|
||
|
FUNCLOS, // Function requested
|
||
|
send_buff, // Send buffer
|
||
|
send_buff_len, // Send buffer length
|
||
|
recv_buff, // Receive buffer
|
||
|
recv_buff_len, // Receive buffer length
|
||
|
CTLD0100, // Command structure
|
||
|
&cldv_cmd, // Command data
|
||
|
ctldv_cmd_len, // Command data length
|
||
|
&EC); // Error structure
|
||
|
#pragma disable_handler
|
||
|
|
||
|
PipeFailed:
|
||
|
return 0; // return to user
|
||
|
}</pre>
|
||
|
</div>
|
||
|
</div>
|
||
|
<div>
|
||
|
<div class="familylinks">
|
||
|
<div class="parentlink"><strong>Parent topic:</strong> <a href="apiexmp.htm" title="Contains example programs that use APIs and exit programs.">Examples: APIs</a></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|