?? tapeinfo.c
字號:
/* Copyright 2000 Enhanced Software Technologies Inc. * Released under terms of the GNU General Public License as * required by the license on 'mtxl.c'. * $Date: 2001/06/19 21:51:32 $ * $Revision: 1.2 $ *//*#define DEBUG_PARTITION *//*#define DEBUG 1 *//* What this does: This basically dumps out the contents of the following * pages: * * Inquiry -- prints full inquiry info. If it's not a tape drive, this is * the end of things. * DeviceType: * Manufacturer: * ProdID: * ProdRevision: * * Log Sense: TapeAlert Page (if supported): * TapeAlert:[message#]<Message> e.g. "TapeAlert:[22]Cleaning Cartridge Worn Out" * * Mode Sense: * Data Compression Page: * DataCompEnabled:<yes|no> * DataCompCapable:<yes|no> * DataDeCompEnabled:<yes|no> * CompType:<number> * DeCompType:<number> * * Device Configuration Page: * ActivePartition:<#> * DevConfigComp:<#> -- the compression byte in device config page. * EarlyWarningSize:<#> -- size of early warning buffer? * * Medium Partition Page: * NumPartitions:<#> * MaxPartitions:<#> * Partition[0]:<size> * Partition[1]:<size>... * * Read Block Limits command: * MinBlock:<#> -- Minimum block size. * MaxBlock:<#> -- Maximum block size. */#include <stdio.h>#include <string.h>#include "mtx.h"#include "mtxl.h"char *argv0;void usage(void) { FatalError("Usage: tapeinfo -f <generic-device>\n");}/* A table for printing out the peripheral device type as ASCII. */ static char *PeripheralDeviceType[32] = { "Disk Drive", "Tape Drive", "Printer", "Processor", "Write-once", "CD-ROM", "Scanner", "Optical", "Medium Changer", "Communications", "ASC IT8", "ASC IT8", "RAID Array", "Enclosure Services", "OCR/W", "Bridging Expander", /* 0x10 */ "Reserved", /* 0x11 */ "Reserved", /* 0x12 */ "Reserved", /* 0x13 */ "Reserved", /* 0x14 */ "Reserved", /* 0x15 */ "Reserved", /* 0x16 */ "Reserved", /* 0x17 */ "Reserved", /* 0x18 */ "Reserved", /* 0x19 */ "Reserved", /* 0x1a */ "Reserved", /* 0x1b */ "Reserved", /* 0x1c */ "Reserved", /* 0x1d */ "Reserved", /* 0x1e */ "Unknown" /* 0x1f */};/* we call it MediumChangerFD for history reasons, sigh. *//* now to print inquiry information: Copied from other one.... */static void ReportInquiry(DEVICE_TYPE MediumChangerFD){ RequestSense_T RequestSense; Inquiry_T *Inquiry; int i; Inquiry = RequestInquiry(MediumChangerFD,&RequestSense); if (Inquiry == NULL) { PrintRequestSense(&RequestSense); FatalError("INQUIRY Command Failed\n"); } printf("Product Type: %s\n",PeripheralDeviceType[Inquiry->PeripheralDeviceType]); printf("Vendor ID: '"); for (i = 0; i < sizeof(Inquiry->VendorIdentification); i++) printf("%c", Inquiry->VendorIdentification[i]); printf("'\nProduct ID: '"); for (i = 0; i < sizeof(Inquiry->ProductIdentification); i++) printf("%c", Inquiry->ProductIdentification[i]); printf("'\nRevision: '"); for (i = 0; i < sizeof(Inquiry->ProductRevisionLevel); i++) printf("%c", Inquiry->ProductRevisionLevel[i]); printf("'\n");\ if (Inquiry->MChngr) { /* check the attached-media-changer bit... */ printf("Attached Changer: Yes\n"); } else { printf("Attached Changer: No\n"); } free(Inquiry); /* well, we're about to exit, but ... */}/* Okay, now for the Log Sense Tape Alert Page (if supported): */#define TAPEALERT_SIZE 2048 /* max size of tapealert buffer. */ #define MAX_TAPE_ALERT 0x41static char *tapealert_messages[]= { "Undefined", /* 0 */ " Read: Having problems reading (slowing down)", /* 1 */ " Write: Having problems writing (losing capacity)", /* 2 */ " Hard Error: Uncorrectable read/write error", /* 3 */ " Media: Media Performance Degraded, Data Is At Risk", /* 4 */ " Read Failure: Tape faulty or tape drive broken", /* 5 */ "Write Failure: Tape faulty or tape drive broken", /* 6 */ " Media Life: The tape has reached the end of its useful life", /* 7 */ "Not Data Grade:Replace cartridge with one containing data grade tape",/*8*/ "Write Protect: Attempted to write to a write-protected cartridge",/*9 */ " No Removal: Cannot unload, initiator is preventing media removal", /*a*/ "Cleaning Media:Cannot back up or restore to a cleaning cartridge", /* b */ " Bad Format: The loaded tape contains data in an unsupported format", /*c */ " Snapped Tape: The data cartridge contains a broken tape", /* d */ "Undefined", /* e */ "Undefined", /* f */ "Undefined", /* 10 */ "Undefined", /* 11 */ "Undefined", /* 12 */ "Undefined", /* 13 */ " Clean Now: The tape drive neads cleaning NOW", /* 0x14 */ "Clean Periodic:The tape drive needs to be cleaned at next opportunity", /* 0x15 */ "Cleaning Media:Cannot clean because cleaning cartridge used up, insert new cleaning cartridge to clean the drive", /* 0x16 */ "Undefined", /* 0x17 */ "Undefined", /* 0x18 */ "Undefined", /* 0x19 */ "Undefined", /* 0x1a */ "Undefined", /* 0x1b */ "Undefined", /* 0x1c */ "Undefined", /* 0x1d */ " Hardware A: Tape drive has a problem not read/write related", /* 0x1e */ " Hardware B: Tape drive has a problem not read/write related", /* 0x1f */ " Interface: Problem with SCSI interface between tape drive and initiator", /* 0x20 */ " Eject Media: The current operation has failed. Eject and reload media", /* 0x21 */ "Download Fail: Attempt to download new firmware failed", /* 0x22 */ "Undefined", /* 0x23 */ "Undefined", /* 0x24 */ "Undefined", /* 0x25 */ "Undefined", /* 0x26 */ "Undefined", /* 0x27 */ "Loader Hardware A: Changer having problems communicating with tape drive", /* 0x28 40 */ "Loader Stray Tape: Stray tape left in drive from prior error", /* 0x29 41 */ "Loader Hardware B: Autoloader mechanism has a fault", /* 0x2a 42 */ " Loader Door: Loader door is open, please close it", /* 0x2b 43 */ "Undefined", /* 0x2c */ "Undefined", /* 0x2d */ "Undefined", /* 0x2e */ "Undefined", /* 0x2f */ "Undefined", /* 0x30 */ "Undefined", /* 0x31 */ "Undefined", /* 0x32 */ "Undefined", /* 0x33 */ "Undefined", /* 0x34 */ "Undefined", /* 0x35 */ "Undefined", /* 0x36 */ "Undefined", /* 0x37 */ "Undefined", /* 0x38 */ "Undefined", /* 0x39 */ "Undefined", /* 0x3a */ "Undefined", /* 0x3b */ "Undefined", /* 0x3c */ "Undefined", /* 0x3d */ "Undefined", /* 0x3e */ "Undefined", /* 0x3f */ "Undefined" /* 0x40 */};struct tapealert_struct { int length; unsigned char *data;}; static struct tapealert_struct *RequestTapeAlert(DEVICE_TYPE fd, RequestSense_T *sense) { CDB_T CDB; struct tapealert_struct *result; int i,tapealert_len,result_idx; unsigned char buffer[TAPEALERT_SIZE]; unsigned char *walkptr; slow_bzero(buffer,TAPEALERT_SIZE); /*zero it... */ /* now to create the CDB block: */ CDB[0]=0x4d; /* Log Sense */ CDB[1]=0; CDB[2]=0x2e; /* Tape Alert Page. */ CDB[3]=0; CDB[4]=0; CDB[5]=0; CDB[6]=0; CDB[7]=TAPEALERT_SIZE>>8 & 0xff; /* hi byte, allocation size */ CDB[8]=TAPEALERT_SIZE & 0xff; /* lo byte, allocation size */ CDB[9]=0; /* reserved */ if (SCSI_ExecuteCommand(fd,Input,&CDB,10,buffer,TAPEALERT_SIZE,sense)!=0){ return NULL; } result=xmalloc(sizeof(struct tapealert_struct)); /* okay, we have stuff in the result buffer: the first 4 bytes are a header: * byte 0 should be 0x2e, byte 1 == 0, bytes 2,3 tell how long the * tapealert page is. */ if ((buffer[0]&0x3f) != 0x2e) { result->data=NULL; result->length=0; return result; } tapealert_len=(((int)buffer[2])<<8) + buffer[3]; if (!tapealert_len) { result->length=0; result->data=NULL; return result; } /* okay, now allocate data and move the buffer over there: */ result->length=MAX_TAPE_ALERT; result->data=xzmalloc(MAX_TAPE_ALERT); /* alloc & zero. */ walkptr=&buffer[4]; i=0; while (i<tapealert_len) { result_idx=(((int)walkptr[0])<<8) + walkptr[1]; /* the parameter #. */ if (result_idx > 0 && result_idx < MAX_TAPE_ALERT) { if (walkptr[4]) { result->data[result_idx]=1; } else { result->data[result_idx]=0; }#ifdef DEBUGOLD1 fprintf(stderr,"Alert[0x%x]=%d\n",result_idx,result->data[result_idx]); fflush(stderr);#endif } else { FatalError("Invalid tapealert page: %d\n",result_idx); } i=i+4+walkptr[3]; /* length byte! */ walkptr=walkptr+4+walkptr[3]; /* next! */ } return result;}static void ReportTapeAlert(DEVICE_TYPE fd) { /* we actually ignore a bad sense reading, like might happen if the * tape drive does not support the tapealert page. */ RequestSense_T RequestSense; struct tapealert_struct *result; int i; result=RequestTapeAlert(fd,&RequestSense); if (!result) return; /* sorry. Don't print sense here. */ if (!result->length) return; /* sorry, no alerts valid. */ for (i=0;i<result->length;i++) { if (result->data[i]) { printf("TapeAlert[%d]:%s.\n",i,tapealert_messages[i]); } } free(result->data); free(result); return;}static unsigned char*mode_sense(DEVICE_TYPE fd, int pagenum, int alloc_len, RequestSense_T *RequestSense) { CDB_T CDB; unsigned char *input_buffer; /*the input buffer -- has junk prepended to * actual sense page. */ unsigned char *tmp; unsigned char *retval; /* the return value. */ int i,pagelen; if (alloc_len > 255) { FatalError("mode_sense(6) can only read up to 255 characters!\n"); } input_buffer=(unsigned char *)xzmalloc(256); /* overdo it, eh? */ /* clear the sense buffer: */ slow_bzero((char *)RequestSense,sizeof(RequestSense_T)); /* returns an array of bytes in the page, or, if not possible, NULL. */ CDB[0]=0x1a; /* Mode Sense(6) */ CDB[1]=0; CDB[2]=pagenum; /* the page to read. */ CDB[3]=0; CDB[4]=255; /* allocation length. This does max of 256 bytes! */ CDB[5]=0; if (SCSI_ExecuteCommand(fd,Input,&CDB,6, input_buffer,255,RequestSense) != 0) {#ifdef DEBUG_MODE_SENSE fprintf(stderr,"Could not execute mode sense...\n"); fflush(stderr);#endif return NULL; /* sorry, couldn't do it. */ } /* Oh hell, write protect is the only thing I have: always print * it if our mode page was 0x0fh, before skipping past buffer: * if the media is *NOT* write protected, just skip, sigh. * * Oh poops, the blocksize is reported in the block descriptor header< * too. Again, just print if our mode page was 0x0f... */ if (pagenum == 0x0f) { int blocklen; if (input_buffer[2] & 0x80) { printf("WriteProtect: yes\n"); } if (input_buffer[2] & 0x70) { printf("BufferedMode: yes\n"); } if (input_buffer[1] ) { printf("Medium Type: 0x%x\n", input_buffer[1]); } else { printf("Medium Type: Not Loaded\n"); } printf("Density Code: 0x%x\n", input_buffer[4]); /* Put out the block size: */ blocklen=((int)input_buffer[9]<<16)+ ((int)input_buffer[10]<<8)+ input_buffer[11];
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -