/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*LINTLIBRARY*/
/*
* This module is part of the photon Command Line
* Interface program.
*
*/
/*
* I18N message number ranges
* This file: 9500 - 9999
* Shared common messages: 1 - 1999
*/
/* Includes */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <nl_types.h>
#include <l_common.h>
#include <stgcom.h>
#include <l_error.h>
#include <g_state.h>
/* Defines */
/* Global variables */
/* External functions */
extern int rand_r(unsigned int *);
static int
wait_random_time(void)
{
unsigned int seed;
int random;
/*
* Get the system time and use "system seconds"
* as 'seed' to generate a random number. Then,
* wait between 1/10 - 1/2 seconds before retry.
* Get the current process id and ex-or it with
* the seed so that the random number is always
* different even in case of multiple processes
* generate a random number at the same time.
*/
return (errno);
}
return (L_LOCALTIME_ERROR);
}
/* get a random number. */
return (L_SELECT_ERROR);
}
return (0);
}
/*
* Execute a command and determine the result.
*/
int
{
/*
* Set function flags for driver.
*
* Set Automatic request sense enable
*
*/
/* intialize error message array */
errorMsg[0] = '\0';
/* print command for debug */
(flag & USCSI_RESET) ||
(flag & USCSI_RESET_ALL)) {
if (flag & USCSI_RESET) {
(void) printf(" Issuing a SCSI Reset.\n");
}
if (flag & USCSI_RESET_ALL) {
(void) printf(" Issuing a SCSI Reset All.\n");
}
} else {
(void) printf(" Issuing the following "
"SCSI command: %s\n",
for (i = 0; i < (int)command->uscsi_cdblen; i++) {
}
(void) printf("\n\tlen=0x%x bufaddr=0x%x buflen=0x%x"
" flags=0x%x\n",
if ((command->uscsi_buflen > 0) &&
((flag & USCSI_READ) == 0)) {
(void) g_dump(" Buffer data: ",
}
}
}
/*
* Default command timeout in case command left it 0
*/
if (command->uscsi_timeout == 0) {
}
/* Issue command - finally */
if ((command->uscsi_buflen > 0) &&
(flag & USCSI_READ)) {
(void) g_dump("\tData read:",
}
}
return (status);
}
(void) printf("Unexpected USCSICMD ioctl error: %s\n",
}
return (status);
}
/*
* Just a SCSI error, create error message
* Retry once for Unit Attention,
* Not Ready, and Aborted Command
*/
case KEY_NOT_READY:
if (retry_cnt++ < 1) {
ER_DPRINTF("Note: Device Not Ready."
" Retrying...\n");
if ((err = wait_random_time()) == 0) {
goto retry;
} else {
return (err);
}
}
break;
case KEY_UNIT_ATTENTION:
if (retry_cnt++ < 1) {
ER_DPRINTF(" cmd():"
" UNIT_ATTENTION: Retrying...\n");
goto retry;
}
break;
case KEY_ABORTED_COMMAND:
if (retry_cnt++ < 1) {
ER_DPRINTF("Note: Command is aborted."
" Retrying...\n");
goto retry;
}
break;
}
}
} else {
/*
* Retry 5 times in case of BUSY, and only
* once for Reservation-conflict, Command
* Termination and Queue Full. Wait for
* random amount of time (between 1/10 - 1/2 secs.)
* between each retry. This random wait is to avoid
* the multiple threads being executed at the same time
* and also the constraint in Photon IB, where the
* command queue has a depth of one command.
*/
case STATUS_BUSY:
if (retry_cnt++ < 5) {
if ((err = wait_random_time()) == 0) {
R_DPRINTF(" cmd(): No. of retries %d."
" STATUS_BUSY: Retrying...\n",
goto retry;
} else {
return (err);
}
}
break;
if (retry_cnt++ < 1) {
if ((err = wait_random_time()) == 0) {
R_DPRINTF(" cmd():"
" RESERVATION_CONFLICT:"
" Retrying...\n");
goto retry;
} else {
return (err);
}
}
break;
case STATUS_TERMINATED:
if (retry_cnt++ < 1) {
R_DPRINTF("Note: Command Terminated."
" Retrying...\n");
if ((err = wait_random_time()) == 0) {
goto retry;
} else {
return (err);
}
}
break;
case STATUS_QFULL:
if (retry_cnt++ < 1) {
R_DPRINTF("Note: Command Queue is full."
" Retrying...\n");
if ((err = wait_random_time()) == 0) {
goto retry;
} else {
return (err);
}
}
break;
}
}
(errorMsg[0] != '\0')) {
}
}