⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtxl.c

📁 通用SCSI设备备份/读写程序
💻 C
📖 第 1 页 / 共 3 页
字号:
  flags->elementtype=StorageElement; /* sigh! */  DataBuffer=SendElementStatusRequest(MediumChangerFD,RequestSense,				      inquiry_info,flags,				      mode_sense->StorageStart,				      /* adjust for import/export. */				      mode_sense->NumStorage-mode_sense->NumImportExport,				      mode_sense->MaxReadElementStatusData);  if (!DataBuffer) {    /* darn. Free up stuff and return. */    /****FIXME**** do a free on element data! */    FreeElementData(ElementStatus);    return NULL;   }   ParseElementStatus(EmptyStorageElementAddress,&EmptyStorageElementCount,		     DataBuffer,ElementStatus,mode_sense);  free(DataBuffer); /* sigh! */  /* --------------IMPORT/EXPORT--------------- */  /* Next let's see if we need to do Import/Export: */  if (mode_sense->NumImportExport > 0) {    flags->elementtype=ImportExportElement;    DataBuffer=SendElementStatusRequest(MediumChangerFD,RequestSense,					inquiry_info,flags,					mode_sense->ImportExportStart,					mode_sense->NumImportExport,					mode_sense->MaxReadElementStatusData);        if (!DataBuffer) {      /* darn. Free up stuff and return. */      /****FIXME**** do a free on element data! */      FreeElementData(ElementStatus);      return NULL;     }     ParseElementStatus(EmptyStorageElementAddress,&EmptyStorageElementCount,		     DataBuffer,ElementStatus,mode_sense);  }    /* ----------------- DRIVES ---------------------- */  flags->elementtype=DataTransferElement; /* sigh! */  DataBuffer=SendElementStatusRequest(MediumChangerFD,RequestSense,				      inquiry_info,flags,				      mode_sense->DataTransferStart,				      mode_sense->NumDataTransfer,				      mode_sense->MaxReadElementStatusData);  if (!DataBuffer) {    /* darn. Free up stuff and return. */    /****FIXME**** do a free on element data! */    FreeElementData(ElementStatus);    return NULL;   }   ParseElementStatus(EmptyStorageElementAddress,&EmptyStorageElementCount,		     DataBuffer,ElementStatus,mode_sense);  free(DataBuffer); /* sigh! */  /* ----------------- Robot Arm(s) -------------------------- */    /* grr, damned brain dead HP doesn't report that it has any! */  if (!mode_sense->NumMediumTransport) {     ElementStatus->TransportElementAddress=0; /* default it sensibly :-(. */  } else {     flags->elementtype=MediumTransportElement; /* sigh! */     DataBuffer=SendElementStatusRequest(MediumChangerFD,RequestSense,				      inquiry_info,flags,				      mode_sense->MediumTransportStart,				      1, /* only get 1, sigh. */				      mode_sense->MaxReadElementStatusData);     if (!DataBuffer) {       /* darn. Free up stuff and return. */       /****FIXME**** do a free on element data! */       FreeElementData(ElementStatus);       return NULL;      }         ParseElementStatus(EmptyStorageElementAddress,&EmptyStorageElementCount,   		     DataBuffer,ElementStatus,mode_sense);     free(DataBuffer); /* sigh! */  }  /*---------------------- Sanity Checking ------------------- */  if (!ElementStatus->DataTransferElementCount)    FatalError("no Data Transfer Element reported\n");  if (ElementStatus->StorageElementCount == 0)    FatalError("no Storage Elements reported\n");  /* ---------------------- Reset SourceStorageElementNumbers ------- */  /* okay, re-write the SourceStorageElementNumber code  *AGAIN*.   * Pass1:   *   Translate from raw element # to our translated # (if possible).   * First, check the SourceStorageElementNumbers against the list of    * filled slots. If the slots indicated are empty, we accept that list as   * valid. Otherwise decide the SourceStorageElementNumbers are invalid.   *   * Pass2:   *   * If we had some invalid (or unknown) SourceStorageElementNumbers   * then we must search for free slots, and assign SourceStorageElementNumbers   * to those free slots. We happen to already built a list of free   * slots as part of the process of reading the storage element numbers   * from the tape. So that's easy enough to do!    */#ifdef DEBUG_TAPELIST  fprintf(stderr,"empty slots: %d\n",EmptyStorageElementCount);  if (EmptyStorageElementCount) {     for (i=0; i<EmptyStorageElementCount; i++) {         fprintf(stderr,"empty: %d\n",EmptyStorageElementAddress[i]);     }  }#endif  /* Okay, now we re-assign origin slots if the "real" origin slot   * is obviously defective:    */  /* pass one: */  invalid_sources=0; /* no invalid sources yet! */  for (i=0;i<ElementStatus->DataTransferElementCount;i++) {    int elnum;    int translated_elnum = -1;    /* if we have an element, then ... */    if (ElementStatus->DataTransferElementFull[i]) {      elnum=ElementStatus->DataTransferElementSourceStorageElementNumber[i];      /* if we have an element number, then ... */      if (elnum >= 0) {         /* Now to translate the elnum: */	 for (j=0; j<ElementStatus->StorageElementCount; j++) {	     if (elnum == ElementStatus->StorageElementAddress[j]) {		 translated_elnum=j; 	     }	 }      /* now see if the element # is already occupied: */	if (ElementStatus->StorageElementFull[translated_elnum]) {	  invalid_sources=1;	  break; /* break out of the loop! */	} else {	   /* properly set the source... */	ElementStatus->DataTransferElementSourceStorageElementNumber[i]=		translated_elnum;	}		       } else {	/* if element # was not >=0, then we had an invalid source anyhow! */	invalid_sources=1;      }    }  }#ifdef DEBUG_TAPELIST   fprintf(stderr,"invalid_sources=%d\n",invalid_sources);#endif  /* Pass2: */  /* okay, we have invalid sources, so let's see what they should be: */  /* Note: If EmptyStorageElementCount is < # of drives, the leftover   * drives will be assigned a -1 (see the initialization loop for   * EmptyStorageElementAddress above), which will be reported as "slot 0"   * by the user interface. This is an invalid value, but more useful for us   * to have than just crapping out here :-(.    */   if (invalid_sources) {    empty_idx=0;    for (i=0;i<ElementStatus->DataTransferElementCount;i++) {      if (ElementStatus->DataTransferElementFull[i]) {#ifdef DEBUG_TAPELIST        fprintf(stderr,"for drive %d, changing source %d to %d (empty slot #%d)\n",	     i,	     ElementStatus->DataTransferElementSourceStorageElementNumber[i],             EmptyStorageElementAddress[empty_idx],             empty_idx);#endif              	ElementStatus->DataTransferElementSourceStorageElementNumber[i]=	  EmptyStorageElementAddress[empty_idx++];      }    }  }  /* and done! */        free(mode_sense);  free(EmptyStorageElementAddress);  return ElementStatus;  }/*************************************************************************//* Now the actual media movement routine! */RequestSense_T *MoveMedium(DEVICE_TYPE MediumChangerFD, int SourceAddress,		       int DestinationAddress, 		       ElementStatus_T *ElementStatus,		       Inquiry_T *inquiry_info, SCSI_Flags_T *flags){  RequestSense_T *RequestSense = xmalloc(sizeof(RequestSense_T));  CDB_T CDB;  if ((inquiry_info->MChngr) && (inquiry_info->PeripheralDeviceType != MEDIUM_CHANGER_TYPE)) {  /* if using the ATTACHED API */    CDB[0]=0xA7;   /* MOVE_MEDIUM_ATTACHED */  } else {    CDB[0] = 0xA5;		/* MOVE MEDIUM */  }  CDB[1] = 0;			/* Reserved */  CDB[2] = (ElementStatus->TransportElementAddress >> 8) & 0xFF;  /* Transport Element Address MSB */  CDB[3] = (ElementStatus->TransportElementAddress) & 0xff;   /* Transport Element Address LSB */  CDB[4] = (SourceAddress >> 8) & 0xFF;	/* Source Address MSB */  CDB[5] = SourceAddress & 0xFF; /* Source Address MSB */  CDB[6] = (DestinationAddress >> 8) & 0xFF; /* Destination Address MSB */  CDB[7] = DestinationAddress & 0xFF; /* Destination Address MSB */  CDB[8] = 0;			/* Reserved */  CDB[9] = 0;			/* Reserved */  if (flags->invert) {    CDB[10] = 1;			/* Reserved */  } else {    CDB[10] = 0;  }  /* eepos controls the tray for import/export elements, sometimes. */  CDB[11] = 0 | (flags->eepos <<6);			/* Control */    if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 12,			  NULL, 0, RequestSense) != 0) {    return RequestSense;  }  free(RequestSense);  return NULL; /* success! */}/* for Linux, this creates a way to do a short erase... the @#$%@ st.c * driver defaults to doing a long erase! */RequestSense_T *Erase(DEVICE_TYPE MediumChangerFD) {  RequestSense_T *RequestSense = xmalloc(sizeof(RequestSense_T));  CDB_T CDB;  CDB[0]=0x19;  CDB[1]=0;  /* Short! */  CDB[2]=CDB[3]=CDB[4]=CDB[5]=0;  if (SCSI_ExecuteCommand(MediumChangerFD, Output, &CDB, 6,			  NULL, 0, RequestSense) != 0) {    return RequestSense;  }  free(RequestSense);  return NULL;  /* Success! */}  #ifdef LONG_PRINT_REQUEST_SENSEstatic char *sense_keys[] = {  "No Sense",  /* 00 */  "Recovered Error", /* 01 */  "Not Ready",  /* 02 */  "Medium Error",  /* 03 */  "Hardware Error",  /* 04 */  "Illegal Request",  /* 05 */  "Unit Attention", /* 06 */  "Data Protect",   /* 07 */  "Blank Check", /* 08 */  "0x09",   /* 09 */  "0x0a",   /* 0a */  "Aborted Command", /* 0b */  "0x0c",  /* 0c */  "Volume Overflow", /* 0d */  "Miscompare",   /* 0e */  "0x0f"  /* 0f */};static char Yes[]="yes";static char No[]="no";void PrintRequestSense(RequestSense_T *RequestSense){  char *msg;  fprintf(stderr, "mtx: Request Sense: Long Report=yes\n");  fprintf(stderr, "mtx: Request Sense: Valid Residual=%s\n", RequestSense->Valid ? Yes : No);  if (RequestSense->ErrorCode==0x70) {     msg = "Current" ;  } else if (RequestSense->ErrorCode==0x71) {     msg = "Deferred" ;  } else {    msg = "Unknown?!" ;  }  fprintf(stderr, "mtx: Request Sense: Error Code=%0x (%s)\n",RequestSense->ErrorCode,msg);  fprintf(stderr, "mtx: Request Sense: Sense Key=%s\n",sense_keys[RequestSense->SenseKey]);  fprintf(stderr, "mtx: Request Sense: FileMark=%s\n", RequestSense->Filemark ? Yes : No);  fprintf(stderr, "mtx: Request Sense: EOM=%s\n", RequestSense->EOM ? Yes : No);  fprintf(stderr, "mtx: Request Sense: ILI=%s\n", RequestSense->ILI ? Yes : No);  if (RequestSense->Valid) {    fprintf(stderr, "mtx: Request Sense: Residual = %02X %02X %02X %02X\n",RequestSense->Information[0],RequestSense->Information[1],RequestSense->Information[2],RequestSense->Information[3]);  }   fprintf(stderr,"mtx: Request Sense: Additional Sense Code = %02X\n", RequestSense->AdditionalSenseCode);  fprintf(stderr,"mtx: Request Sense: Additional Sense Qualifier = %02X\n", RequestSense->AdditionalSenseCodeQualifier);  if (RequestSense->SKSV) {    fprintf(stderr,"mtx: Request Sense: Field in Error = %02X\n",RequestSense->BitPointer);  }  fprintf(stderr,"mtx: Request Sense: BPV=%s\n",RequestSense->BPV ? Yes : No);  fprintf(stderr,"mtx: Request Sense: Error in CDB=%s\n",RequestSense->CommandData ? Yes : No);  fprintf(stderr,"mtx: Request Sense: SKSV=%s\n",RequestSense->SKSV ? Yes : No);  fflush(stderr);  if (RequestSense->BPV || RequestSense -> SKSV) {    fprintf(stderr,"mtx: Request Sense: Field Pointer = %02X %02X\n",RequestSense->FieldData[0],RequestSense->FieldData[1]);  }}#elsevoid PrintRequestSense(RequestSense_T *RequestSense){  int i;  fprintf(stderr, "mtx: Request Sense: %02X",	  ((unsigned char *) RequestSense)[0]);  for (i = 1; i < sizeof(RequestSense_T); i++)    fprintf(stderr, " %02X", ((unsigned char *) RequestSense)[i]);  fprintf(stderr, "\n");}#endif/* $Date: 2002/09/27 17:23:28 $ * $Log: mtxl.c,v $ * Revision 1.8.2.7  2002/09/27 17:23:28  elgreen * Don't dereference pointer in barcode stuff * * Revision 1.8.2.6  2002/09/27 17:20:18  elgreen * doh, get rid of the + from the patch process! * * Revision 1.8.2.5  2002/09/27 17:17:13  elgreen * fix copy_barcode * * Revision 1.8.2.4  2002/09/27 16:49:43  elgreen * copy_barcode was off by one (sigh!) * * Revision 1.8.2.3  2002/02/05 16:51:11  elgreen * mtx 1.2.16pre3 * * Revision 1.8.2.2  2002/01/22 16:27:47  elgreen * Handle too-big transport element descriptor lengths * * Revision 1.8.2.1  2002/01/17 22:24:35  elgreen * Handle ADIC silliness of saying that it has 1 import/export element whose * descriptor is 0 bytes in length * * Revision 1.8  2001/06/25 23:06:22  elgreen * Readying this for 1.2.13 release * * Revision 1.7  2001/06/25 04:56:35  elgreen * Kai to the rescue *again* :-) * * Revision 1.6  2001/06/24 07:02:01  elgreen * Kai's fix was better than mine. * * Revision 1.5  2001/06/24 06:59:19  elgreen * Kai found bug in the barcode backoff. * * Revision 1.4  2001/06/15 18:56:54  elgreen * Arg, it doesn't help to check for 0 robot arms if you force it to 1! * * Revision 1.3  2001/06/15 14:26:09  elgreen * Fixed brain-dead case of HP loaders that report they have no robot arms. * * Revision 1.2  2001/06/09 17:26:26  elgreen * Added 'nobarcode' command to mtx (to skip the initial request asking for * barcodes for mtx status purposes). * * Revision 1.1.1.1  2001/06/05 17:10:25  elgreen * Initial import into SourceForge * * Revision 1.29  2001/05/01 01:39:23  eric * Remove the Exabyte special case code, which seemed to be barfing me :-(. * * Revision 1.28  2001/04/28 00:03:10  eric * update for 1.2.12. * * Revision 1.27  2001/04/18 19:27:39  eric * whoops, move ImportExport parser into the $#%!@ ImportExport test :-(. * * Revision 1.26  2001/04/18 18:55:44  eric * turn too many storage elements into a warning rather than a fatal error (sigh!) * * Revision 1.25  2001/04/18 18:46:54  eric * $%!@# "C" precedence rules. * * Revision 1.24  2001/04/18 17:58:04  eric * initialize EmptyStorageElementCount (sigh) * * Revision 1.23  2001/04/18 16:55:03  eric * hopefully get the initialization for element status straigtened out. * * Revision 1.22  2001/04/18 16:32:59  eric * Cleaned up all -Wall messages. * * Revision 1.21  2001/04/18 16:08:08  eric * after re-arranging & fixing bugs * * Revision 1.20  2001/04/17 21:28:43  eric * mtx 1.2.11 * * Revision 1.19  2001/04/02 20:12:48  eric * checkin, mtx 1.2.11pre6 * * Revision 1.18  2001/03/06 01:37:05  eric * Solaris changes * * Revision 1.17  2001/02/26 20:56:12  eric * added debugging, removed Makefile * * Revision 1.16  2001/02/19 23:22:28  eric * Add E2 bits * * Revision 1.15  2001/02/19 23:02:04  eric * Apply SPARC patch. * * Revision 1.14  2001/01/26 15:58:10  eric * Make work on solaris? * * Revision 1.13  2001/01/17 19:39:01  eric * Changed mtx.h and mtxl.c to use autoconf stuff to figure out which SCSI * routines to use (this way, if we ever port to an OS that has an identical * SCSI interface to one of the supported OS's, we don't have to do anything * special!). * * Revision 1.12  2001/01/17 16:36:26  eric * added date & revision strings as needed * * Revision 1.11  2000/11/30 20:35:18  eric * Added Erase command. * */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -