tlm_init.c revision 1e05b03fa76ee89d509f0c461b36cb865f1e6794
/*
*/
/*
* BSD 3 Clause License
*
* Copyright (c) 2007, The Storage Networking Industry Association.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* distribution.
*
* - Neither the name of The Storage Networking Industry Association (SNIA)
* nor the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/byteorder.h>
#include <tlm.h>
#include <pthread.h>
#include "tlm_proto.h"
/*
* generic routine to read a SCSI page
*/
int
{
char *dname;
int dev;
return (EINVAL);
/* Lun is in the 5th bit */
}
if (dev == -1) {
return (errno);
}
return (errno);
}
return (uscsi_cmd.uscsi_status);
}
/*
* Read the Inquiry Page.
*/
static int
{
}
/*
* Read the Product Data Page.
*/
static int
{
char cmd[CDB_GROUP0];
cmd[0] = SCMD_INQUIRY;
/* LINTED improper alignment */
}
/*
* Read the Serial Number Page.
*/
static int
{
int rv;
sizeof (scsi_serial_t));
}
/*
* Read the Device Name Page.
*/
static int
{
len) == -1)
return (-1);
return (-1);
return (0);
}
/*
* Formatted print of WWN
*/
static void
{
return;
}
/*
* Extract and print the world wide name (WWN)
*/
int
{
name_ident_t *ident;
int accessed;
return (-1);
return (-1);
}
goto resize;
}
accessed = sizeof (device_ident_header_t);
accessed += sizeof (name_ident_t);
accessed += ident->ni_ident_length;
/*
* Looking for code set 1 (Binary) ident type NAA 64 bit
* address that is associated with the node (0).
*/
if ((ident->ni_code_set == 1) &&
(ident->ni_ident_type == 3)) {
/*
* If assc is zero (Node) this is the one we want.
* If we find that we're done.
*/
if (ident->ni_asso == 0)
break;
}
/*
* If we find a EUI-64 we can use that also.
*/
if ((ident->ni_code_set == 2) &&
(ident->ni_ident_type == 1) &&
(ident->ni_asso == 0) &&
/*
* This isn't our first choice but we'll print it
* in case there is nothing else to use.
*/
ident->ni_ident_length, designator_data);
}
ident =
}
/*
* See if we found something.
* Memset above would leave wwnp not printable.
*/
return (0);
return (-1);
}
/*
* Add the tape library call back function (used while scanning the bus)
*/
static int
{
int l;
int *nlp; /* pointer to library counter */
return (-TLM_INVALID);
}
/* This is a robot, which means this is also a library */
(*nlp)++;
l = tlm_insert_new_library(slink);
}
}
return (TLM_NO_ERRORS);
}
/*
* Create some virutal slots
*/
static int
{
int s;
tlm_slot_t *sp;
if (l <= 0 || !dp) {
return (-TLM_INVALID);
}
if ((s = tlm_insert_new_slot(l)) <= 0)
return (-TLM_NO_MEMORY);
return (-TLM_ERROR_INTERNAL);
}
/*
* For virtual slots element number is 0 and they are always full.
*/
sp->ts_element = 0;
return (TLM_NO_ERRORS);
}
/*
* Make the tape drive not part of a tape library (stand alone)
*/
static int
{
int d;
if (!slink || l <= 0) {
return (-TLM_INVALID);
}
d = tlm_insert_new_drive(l);
return (-TLM_ERROR_INTERNAL);
}
/* For stand-alone drives, the element number is the drive number. */
dp->td_element = d;
/*
* Note: There is no way to remove library elements. We cannot clean
* up if make_virtual_slot() fails.
*/
(void) make_virtual_slot(l, dp);
return (d);
}
/*
* Find the LIBRARY structure that has control of this DRIVE.
*/
static int
{
int d;
/* Walk through all libraries. */
continue;
/* Walk through drives that are already found. */
continue;
return (d);
}
}
/* Not part of any library, this is a newly found tape drive. */
return (0);
}
/*
* Add the tape library call back function (used while scanning the bus)
*/
static int
{
int l, d;
int *vlp; /* pointer to virtual library number */
return (-TLM_INVALID);
}
if (d == 0) {
/* This tape drive was not found inside any robot. */
if (*vlp == 0) {
/*
* First, create a virtual library if it's not
* done yet.
*/
}
/* sorry, we can not clean up the vlib now * */
return (-TLM_INVALID);
}
l = *vlp;
} else
}
}
}
return (TLM_NO_ERRORS);
}
/*
* Scan the specified bus and call the handler function.
*/
static int
{
int nerr;
struct scsi_inquiry scsi_data;
nerr = 0;
nerr++;
else
nerr++;
}
return (nerr);
}
/*
* available on the library
*/
static void
{
char *dname;
int l, d;
if (!(lp = tlm_library(l)))
continue;
if (lp->tl_drive_count <= 0)
continue;
"Warning: The following drives are not accessible:");
if (!(dname = tlm_get_tape_name(l, d))) {
"Error getting drive(%d, %d)", l, d);
} else
/*
* Note: Make the slots inaccessible to prevent running
* discovery on these libraries. The better idea is
* removing these libraries, but we don't have that
* feature available now.
*/
lp->tl_slot_count = 0;
}
}
/*
* Initialize the tape library data structure, asks the libraries what
* equipments they have.
*/
int
tlm_init(void)
{
static int nlibs; /* number of found libraries */
int i, nsa;
int l, vlibs, d;
int rv;
/* Search through all SCSI adapters, look for tape robots. */
nlibs = 0;
/*
* We probe both changers and tape drives here
* but later on this needs to be removed as the
* probe will happen somewhere else.
*/
if (probe_scsi() < 0)
return (-1);
for (i = 0; i < nsa; i++)
if ((sa = scsi_get_adapter(i)))
/* Search through all SCSI adapters, look for tape drives. */
vlibs = 0;
for (i = 0; i < nsa; i++)
if ((sa = scsi_get_adapter(i)))
for (l = 1; l <= tlm_library_count(); l++) {
if (!(lp = tlm_library(l))) {
continue;
}
/*
* Make sure all libraries have tape drives.
*/
if (lp->tl_drive_count == 0)
continue;
/*
* Make sure all tape drives exist. A drive that is not
* linked into the SCSI chain will be seen by the library
* but we cannot talk to it.
*/
l, d);
continue;
}
}
}
if (nlibs > 0)
else
return (rv);
}