1229997Sken/*- 2229997Sken * Implementation of Utility functions for all SCSI device types. 3229997Sken * 4229997Sken * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs. 5229997Sken * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry. 6229997Sken * All rights reserved. 7229997Sken * 8229997Sken * Redistribution and use in source and binary forms, with or without 9229997Sken * modification, are permitted provided that the following conditions 10229997Sken * are met: 11229997Sken * 1. Redistributions of source code must retain the above copyright 12229997Sken * notice, this list of conditions, and the following disclaimer, 13229997Sken * without modification, immediately at the beginning of the file. 14229997Sken * 2. The name of the author may not be used to endorse or promote products 15229997Sken * derived from this software without specific prior written permission. 16229997Sken * 17229997Sken * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18229997Sken * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19229997Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20229997Sken * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21229997Sken * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22229997Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23229997Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24229997Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25229997Sken * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26229997Sken * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27229997Sken * SUCH DAMAGE. 28229997Sken * 29229997Sken * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_scsi_all.c#2 $ 30229997Sken */ 31229997Sken 32229997Sken#include <sys/param.h> 33229997Sken 34229997Sken__FBSDID("$FreeBSD$"); 35229997Sken 36229997Sken#include <sys/types.h> 37229997Sken#ifdef _KERNEL 38229997Sken#include <sys/systm.h> 39229997Sken#include <sys/libkern.h> 40229997Sken#include <sys/kernel.h> 41229997Sken#include <sys/sysctl.h> 42229997Sken#else 43229997Sken#include <errno.h> 44229997Sken#include <stdio.h> 45229997Sken#include <stdlib.h> 46229997Sken#include <string.h> 47229997Sken#include <inttypes.h> 48229997Sken#endif 49229997Sken 50229997Sken#include <cam/cam.h> 51229997Sken#include <cam/cam_ccb.h> 52229997Sken#include <cam/cam_queue.h> 53229997Sken#include <cam/cam_xpt.h> 54229997Sken#include <cam/scsi/scsi_all.h> 55229997Sken 56229997Sken#include <cam/ctl/ctl_io.h> 57229997Sken#include <cam/ctl/ctl_scsi_all.h> 58229997Sken#include <sys/sbuf.h> 59229997Sken#ifndef _KERNEL 60229997Sken#include <camlib.h> 61229997Sken#endif 62229997Sken 63229997Skenconst char * 64229997Skenctl_scsi_status_string(struct ctl_scsiio *ctsio) 65229997Sken{ 66229997Sken switch(ctsio->scsi_status) { 67229997Sken case SCSI_STATUS_OK: 68229997Sken return("OK"); 69229997Sken case SCSI_STATUS_CHECK_COND: 70229997Sken return("Check Condition"); 71229997Sken case SCSI_STATUS_BUSY: 72229997Sken return("Busy"); 73229997Sken case SCSI_STATUS_INTERMED: 74229997Sken return("Intermediate"); 75229997Sken case SCSI_STATUS_INTERMED_COND_MET: 76229997Sken return("Intermediate-Condition Met"); 77229997Sken case SCSI_STATUS_RESERV_CONFLICT: 78229997Sken return("Reservation Conflict"); 79229997Sken case SCSI_STATUS_CMD_TERMINATED: 80229997Sken return("Command Terminated"); 81229997Sken case SCSI_STATUS_QUEUE_FULL: 82229997Sken return("Queue Full"); 83229997Sken case SCSI_STATUS_ACA_ACTIVE: 84229997Sken return("ACA Active"); 85229997Sken case SCSI_STATUS_TASK_ABORTED: 86229997Sken return("Task Aborted"); 87229997Sken default: { 88229997Sken static char unkstr[64]; 89229997Sken snprintf(unkstr, sizeof(unkstr), "Unknown %#x", 90229997Sken ctsio->scsi_status); 91229997Sken return(unkstr); 92229997Sken } 93229997Sken } 94229997Sken} 95229997Sken 96229997Sken/* 97229997Sken * scsi_command_string() returns 0 for success and -1 for failure. 98229997Sken */ 99229997Skenint 100229997Skenctl_scsi_command_string(struct ctl_scsiio *ctsio, 101229997Sken struct scsi_inquiry_data *inq_data, struct sbuf *sb) 102229997Sken{ 103229997Sken char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1]; 104229997Sken 105229997Sken sbuf_printf(sb, "%s. CDB: %s", 106229997Sken scsi_op_desc(ctsio->cdb[0], inq_data), 107229997Sken scsi_cdb_string(ctsio->cdb, cdb_str, sizeof(cdb_str))); 108229997Sken 109229997Sken return(0); 110229997Sken} 111229997Sken 112229997Skenvoid 113229997Skenctl_scsi_path_string(union ctl_io *io, char *path_str, int len) 114229997Sken{ 115273163Smav 116273163Smav snprintf(path_str, len, "(%u:%u:%u/%u): ", 117287620Smav io->io_hdr.nexus.initid, io->io_hdr.nexus.targ_port, 118273163Smav io->io_hdr.nexus.targ_lun, io->io_hdr.nexus.targ_mapped_lun); 119229997Sken} 120229997Sken 121229997Sken/* 122229997Sken * ctl_scsi_sense_sbuf() returns 0 for success and -1 for failure. 123229997Sken */ 124229997Skenint 125229997Skenctl_scsi_sense_sbuf(struct ctl_scsiio *ctsio, 126229997Sken struct scsi_inquiry_data *inq_data, struct sbuf *sb, 127229997Sken scsi_sense_string_flags flags) 128229997Sken{ 129229997Sken char path_str[64]; 130229997Sken 131229997Sken if ((ctsio == NULL) || (sb == NULL)) 132229997Sken return(-1); 133229997Sken 134229997Sken ctl_scsi_path_string((union ctl_io *)ctsio, path_str, sizeof(path_str)); 135229997Sken 136229997Sken if (flags & SSS_FLAG_PRINT_COMMAND) { 137229997Sken 138229997Sken sbuf_cat(sb, path_str); 139229997Sken 140229997Sken ctl_scsi_command_string(ctsio, inq_data, sb); 141229997Sken 142229997Sken sbuf_printf(sb, "\n"); 143229997Sken } 144229997Sken 145229997Sken scsi_sense_only_sbuf(&ctsio->sense_data, ctsio->sense_len, sb, 146229997Sken path_str, inq_data, ctsio->cdb, ctsio->cdb_len); 147229997Sken 148229997Sken return(0); 149229997Sken} 150229997Sken 151229997Skenchar * 152229997Skenctl_scsi_sense_string(struct ctl_scsiio *ctsio, 153229997Sken struct scsi_inquiry_data *inq_data, char *str, 154229997Sken int str_len) 155229997Sken{ 156229997Sken struct sbuf sb; 157229997Sken 158229997Sken sbuf_new(&sb, str, str_len, 0); 159229997Sken 160229997Sken ctl_scsi_sense_sbuf(ctsio, inq_data, &sb, SSS_FLAG_PRINT_COMMAND); 161229997Sken 162229997Sken sbuf_finish(&sb); 163229997Sken 164229997Sken return(sbuf_data(&sb)); 165229997Sken} 166229997Sken 167229997Sken#ifdef _KERNEL 168229997Skenvoid 169229997Skenctl_scsi_sense_print(struct ctl_scsiio *ctsio, 170229997Sken struct scsi_inquiry_data *inq_data) 171229997Sken{ 172229997Sken struct sbuf sb; 173229997Sken char str[512]; 174229997Sken 175229997Sken sbuf_new(&sb, str, sizeof(str), 0); 176229997Sken 177229997Sken ctl_scsi_sense_sbuf(ctsio, inq_data, &sb, SSS_FLAG_PRINT_COMMAND); 178229997Sken 179229997Sken sbuf_finish(&sb); 180229997Sken 181229997Sken printf("%s", sbuf_data(&sb)); 182229997Sken} 183229997Sken 184229997Sken#else /* _KERNEL */ 185229997Skenvoid 186229997Skenctl_scsi_sense_print(struct ctl_scsiio *ctsio, 187229997Sken struct scsi_inquiry_data *inq_data, FILE *ofile) 188229997Sken{ 189229997Sken struct sbuf sb; 190229997Sken char str[512]; 191229997Sken 192229997Sken if ((ctsio == NULL) || (ofile == NULL)) 193229997Sken return; 194229997Sken 195229997Sken sbuf_new(&sb, str, sizeof(str), 0); 196229997Sken 197229997Sken ctl_scsi_sense_sbuf(ctsio, inq_data, &sb, SSS_FLAG_PRINT_COMMAND); 198229997Sken 199229997Sken sbuf_finish(&sb); 200229997Sken 201229997Sken fprintf(ofile, "%s", sbuf_data(&sb)); 202229997Sken} 203229997Sken 204229997Sken#endif /* _KERNEL */ 205229997Sken 206