📄 scsi-changer-driver.c
字号:
/* * Now the internal functions *//* * Open the device and placeit in the list of open files * The OS has to decide if it is an SCSI Commands capable device */intOpenDevice( int ip, char * DeviceName, char * ConfigName, char * ident){ extern OpenFiles_T *pDev; char tmpstr[16]; ChangerCMD_T *p = (ChangerCMD_T *)&ChangerIO; if (!ConfigName) return 1; if (!DeviceName) return 1; DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### START OpenDevice\n")); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("OpenDevice : %s\n"), DeviceName); pDev[ip].ConfigName = strdup(ConfigName); pDev[ip].dev = strdup(DeviceName); if (SCSI_OpenDevice(ip) != 0 ) { if (ident != NULL) /* Override by config */ { while(p->ident != NULL) { if (strcmp(ident, p->ident) == 0) { pDev[ip].functions = p; strncpy(pDev[ip].ident, ident, 17); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("override using ident = %s, type = %s\n"),p->ident, p->type); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP OpenDevice\n")); return(1); /*NOTREACHED*/ } p++; } ChgExit("OpenDevice", _("ident not found"), FATAL); /*NOTREACHED*/ } else { while(p->ident != NULL) { if (strcmp(pDev[ip].ident, p->ident) == 0) { pDev[ip].functions = p; DebugPrint(DEBUG_INFO, SECTION_SCSI,_("using ident = %s, type = %s\n"),p->ident, p->type); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP OpenDevice\n")); return(1); /*NOTREACHED*/ } p++; } } /* Nothing matching found, try generic */ /* divide generic in generic_type, where type is the */ /* num returned by the inquiry command */ p = (ChangerCMD_T *)&ChangerIO; g_snprintf(&tmpstr[0], SIZEOF(tmpstr), "%s_%s","generic",pDev[0].type); DebugPrint(DEBUG_INFO, SECTION_SCSI,"##### OpenDevice trying GENERIC Device %s\n",tmpstr); while(p->ident != NULL) { if (strcmp(tmpstr, p->ident) == 0) { pDev[ip].functions = p; DebugPrint(DEBUG_INFO, SECTION_SCSI,_("using ident = %s, type = %s\n"),p->ident, p->type); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP OpenDevice\n")); return(1); /*NOTREACHED*/ } p++; } } else { /* Something failed, lets see what */ DebugPrint(DEBUG_ERROR, SECTION_SCSI,_("##### STOP OpenDevice failed\n")); } pDev[ip].functions = NULL; DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP OpenDevice (nothing found) !!\n")); return(0);}/* * This functions checks if the library has an barcode reader. * fd -> pointer to the internal devie structure pDev */intBarCode( int fd){ int ret; extern OpenFiles_T *pDev; DebugPrint(DEBUG_INFO, SECTION_BARCODE,_("##### START BarCode\n")); DebugPrint(DEBUG_INFO, SECTION_BARCODE,_("%-20s : fd %d\n"), "BarCode", fd); DebugPrint(DEBUG_INFO, SECTION_BARCODE,_("Ident = [%s], function = [%s]\n"), pDev[fd].ident, pDev[fd].functions->ident); ret = pDev[fd].functions->function_barcode(fd); DebugPrint(DEBUG_INFO, SECTION_BARCODE,_("##### STOP BarCode (%d)\n"),ret); return(ret);}/* * This functions check if the tape drive is ready * * fd -> pointer to the internal devie structure pDev * wait -> time to wait for the ready status * */intTape_Ready( int fd, time_t wait_time){ extern OpenFiles_T *pDev; int done; int ret; time_t cnt = 0; RequestSense_T *pRequestSense; DebugPrint(DEBUG_INFO, SECTION_TAPE,_("##### START Tape_Ready\n")); /* * Which device should we use to get the * tape status */ /* * First the ioctl tapedevice */ if (pDev[INDEX_TAPE].avail == 1) { fd = INDEX_TAPE; } /* * But if available and can do SCSI * the scsitapedev */ if (pDev[INDEX_TAPECTL].avail == 1 && pDev[INDEX_TAPECTL].SCSI == 1) { fd = INDEX_TAPECTL; } if (pDev[fd].avail == 1 && pDev[fd].SCSI == 0) { DebugPrint(DEBUG_INFO, SECTION_TAPE,_("Tape_Ready : Can't send SCSI commands, try ioctl\n")); /* * Do we get an non negative result. * If yes this function is available * and we can use it to get the status * of the tape */ ret = Tape_Status(fd); if (ret >= 0) { while (cnt < wait_time) { if ( ret & TAPE_ONLINE) { DebugPrint(DEBUG_INFO, SECTION_TAPE,_("Tape_Ready : Ready after %d seconds\n"),cnt); DebugPrint(DEBUG_INFO, SECTION_TAPE,_("##### STOP Tape_Ready\n")); return(0); /*NOTREACHED*/ } cnt++; sleep(1); ret = Tape_Status(fd); } DebugPrint(DEBUG_INFO, SECTION_TAPE,_("Tape_Ready : not ready, stop after %d seconds\n"),cnt); DebugPrint(DEBUG_INFO, SECTION_TAPE,_("##### STOP Tape_Ready\n")); return(0); /*NOTREACHED*/ } DebugPrint(DEBUG_INFO, SECTION_TAPE,_("Tape_Ready : no ioctl interface, will sleep for %d seconds\n"), wait_time); sleep(wait_time); DebugPrint(DEBUG_INFO, SECTION_TAPE,_("##### STOP Tape_Ready\n")); return(0); /*NOTREACHED*/ } pRequestSense = alloc(SIZEOF(RequestSense_T)); /* * Ignore errors at this point */ GenericRewind(fd); /* * Wait until we get an ready condition */ done = 0; while (!done && (cnt < wait_time)) { ret = SCSI_TestUnitReady(fd, pRequestSense ); switch (ret) { case SCSI_OK: done = 1; break; case SCSI_SENSE: switch (SenseHandler(fd, 0, pRequestSense->SenseKey, pRequestSense->AdditionalSenseCode, pRequestSense->AdditionalSenseCodeQualifier, pRequestSense)) { case SENSE_NO: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) SENSE_NO\n")); done = 1; break; case SENSE_TAPE_NOT_ONLINE: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) SENSE_TAPE_NOT_ONLINE\n")); break; case SENSE_IGNORE: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) SENSE_IGNORE\n")); done = 1; break; case SENSE_ABORT: DebugPrint(DEBUG_ERROR, SECTION_SCSI,_("TapeReady (TestUnitReady) SENSE_ABORT\n")); amfree(pRequestSense); return(-1); /*NOTREACHED*/ case SENSE_RETRY: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) SENSE_RETRY\n")); break; default: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) default (SENSE)\n")); done = 1; break; } break; case SCSI_ERROR: DebugPrint(DEBUG_ERROR, SECTION_SCSI,_("TapeReady (TestUnitReady) SCSI_ERROR\n")); free(pRequestSense); return(-1); /*NOTREACHED*/ case SCSI_BUSY: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) SCSI_BUSY\n")); break; case SCSI_CHECK: DebugPrint(DEBUG_INFO, SECTION_SCSI,_("TapeReady (TestUnitReady) SCSI_CHECK\n")); break; default: DebugPrint(DEBUG_ERROR, SECTION_SCSI,_("TapeReady (TestUnitReady) unknown (%d)\n"),ret); break; } sleep(1); cnt++; } amfree(pRequestSense); DebugPrint(DEBUG_INFO, SECTION_TAPE,_("Tape_Ready after %d sec\n"), cnt); DebugPrint(DEBUG_INFO, SECTION_TAPE,_("##### STOP Tape_Ready\n")); return(0);}intDecodeSCSI( CDB_T CDB, char * string){ SC_COM_T *pSCSICommand; int x; DebugPrint(DEBUG_INFO, SECTION_SCSI, _("##### START DecodeSCSI\n")); pSCSICommand = (SC_COM_T *)&SCSICommand; while (pSCSICommand->name != NULL) { if (CDB[0] == pSCSICommand->command) { DebugPrint(DEBUG_INFO, SECTION_SCSI,_("%s %s"), string, pSCSICommand->name); for (x=0; x < pSCSICommand->length; x++) { DebugPrint(DEBUG_INFO, SECTION_SCSI," %02X", CDB[x]); } DebugPrint(DEBUG_INFO, SECTION_SCSI,"\n"); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP DecodeSCSI\n")); return(0); /*NOTREACHED*/ } pSCSICommand++; } DebugPrint(DEBUG_INFO, SECTION_SCSI,_("Not found %X\n"), CDB[0]); DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### STOP DecodeSCSI\n")); return(0);}intDecodeModeSense( u_char * buffer, size_t offset, char * pstring, char block, FILE * out){ ReadWriteErrorRecoveryPage_T *prp; DisconnectReconnectPage_T *pdrp; size_t length = (size_t)buffer[0] - 4 - offset; (void)pstring; /* Quiet unused parameter warning */ DebugPrint(DEBUG_INFO, SECTION_SCSI,_("##### START DecodeModeSense\n")); dump_hex(buffer, 255, DEBUG_INFO, SECTION_SCSI); /* Jump over the Parameter List header and an offset if we have something * Unknown at the start (ADIC-218) at the moment * */ buffer = buffer + 4 + offset; DebugPrint(DEBUG_INFO, SECTION_SCSI,_("buffer length = %d\n"), length); if (block) /* Do we have an block descriptor page ?*/ { if (out != NULL) g_fprintf(out, _("DecodeModeSense : Density Code %x\n"), (unsigned)buffer[0]); buffer++; if (out != NULL) g_fprintf(out, _("DecodeModeSense : Number of Blocks %d\n"), V3(buffer)); buffer = buffer + 4; if (out != NULL) g_fprintf(out, _("DecodeModeSense : Block Length %d\n"), V3(buffer)); buffer = buffer + 3; } while (length > 0) { switch (*buffer & 0x3f) { case 0: pVendorUnique = buffer; buffer++; break; case 0x1: prp = (ReadWriteErrorRecoveryPage_T *)buffer; if (out != NULL) { g_fprintf(out, _("DecodeModeSense : Read/Write Error Recovery Page\n")); g_fprintf(out,_("\tTransfer Block %d\n"), prp->tb); g_fprintf(out,_("\tEnable Early Recovery %d\n"), prp->eer); g_fprintf(out,_("\tPost Error %d\n"), prp->per); g_fprintf(out,_("\tDisable Transfer on Error %d\n"), prp->dte); g_fprintf(out,_("\tDisable ECC Correction %d\n"), prp->dcr); g_fprintf(out,_("\tRead Retry Count %d\n"), prp->ReadRetryCount); g_fprintf(out,_("\tWrite Retry Count %d\n"), prp->WriteRetryCount); } buffer++; break; case 0x2: pdrp = (DisconnectReconnectPage_T *)buffer; if (out != NULL) { g_fprintf(out, _("DecodeModeSense : Disconnect/Reconnect Page\n")); g_fprintf(out,_("\tBuffer Full Ratio %d\n"), pdrp->BufferFullRatio); g_fprintf(out,_("\tBuffer Empty Ratio %d\n"), pdrp->BufferEmptyRatio); g_fprintf(out,_("\tBus Inactivity Limit %d\n"), V2(pdrp->BusInactivityLimit)); g_fprintf(out,_("\tDisconnect Time Limit %d\n"), V2(pdrp->DisconnectTimeLimit)); g_fprintf(out,_("\tConnect Time Limit %d\n"), V2(pdrp->ConnectTimeLimit)); g_fprintf(out,_("\tMaximum Burst Size %d\n"), V2(pdrp->MaximumBurstSize)); g_fprintf(out,_("\tDTDC %d\n"), pdrp->DTDC); } buffer++; break; case 0x1d: pEAAPage = (EAAPage_T *)buffer; if (out != NULL) { g_fprintf(out,_("DecodeModeSense : Element Address Assignment Page\n")); g_fprintf(out,_("\tMedium Transport Element Address %d\n"), V2(pEAAPage->MediumTransportElementAddress)); g_fprintf(out,_("\tNumber of Medium Transport Elements %d\n"), V2(pEAAPage->NoMediumTransportElements)); g_fprintf(out, _("\tFirst Storage Element Address %d\n"), V2(pEAAPage->FirstStorageElementAddress)); g_fprintf(out, _("\tNumber of Storage Elements %d\n"), V2(pEAAPage->NoStorageElements)); g_fprintf(out, _("\tFirst Import/Export Element Address %d\n"), V2(pEAAPage->FirstImportExportElementAddress)); g_fprintf(out, _("\tNumber of ImportExport Elements %d\n"), V2(pEAAPage->NoImportExportElements)); g_fprintf(out, _("\tFirst Data Transfer Element Address %d\n"), V2(pEAAPage->FirstDataTransferElementAddress)); g_fprintf(out, _("\tNumber of Data Transfer Elements %d\n"), V2(pEAAPage->NoDataTransferElements)); } buffer++; break; case 0x1f: pDeviceCapabilitiesPage = (DeviceCapabilitiesPage_T *)buffer; if (out != NULL) { g_fprintf(out, _("DecodeModeSense : MT can store data cartridges %d\n"), pDeviceCapabilitiesPage->MT); g_fprintf(out, _("DecodeModeSense : ST can store data cartridges %d\n"), pDeviceCapabilitiesPage->ST); g_fprintf(out, _("DecodeModeSense : IE can store data cartridges %d\n"), pDeviceCapabilitiesPage->IE); g_fprintf(out, _("DecodeModeSense : DT can store data cartridges %d\n"), pDeviceCapabilitiesPage->DT); g_fprintf(out, _("DecodeModeSense : MT to MT %d\n"), pDeviceCapabilitiesPage->MT2MT); g_fprintf(out, _("DecodeModeSense : MT to ST %d\n"), pDeviceCapabilitiesPage->MT2ST); g_fprintf(out, _("DecodeModeSense : MT to IE %d\n"), pDeviceCapabilitiesPage->MT2IE); g_fprintf(out, _("DecodeModeSense : MT to DT %d\n"), pDeviceCapabilitiesPage->MT2DT); g_fprintf(out, _("DecodeModeSense : ST to MT %d\n"), pDeviceCapabilitiesPage->ST2ST); g_fprintf(out, _("DecodeModeSense : ST to MT %d\n"), pDeviceCapabilitiesPage->ST2ST); g_fprintf(out, _("DecodeModeSense : ST to DT %d\n"), pDeviceCapabilitiesPage->ST2DT); g_fprintf(out, _("DecodeModeSense : IE to MT %d\n"), pDeviceCapabilitiesPage->IE2MT); g_fprintf(out, _("DecodeModeSense : IE to ST %d\n"), pDeviceCapabilitiesPage->IE2IE); g_fprintf(out, _("DecodeModeSense : IE to ST %d\n"), pDeviceCapabilitiesPage->IE2DT); g_fprintf(out, _("DecodeModeSense : IE to ST %d\n"), pDeviceCapabilitiesPage->IE2DT); g_fprintf(out, _("DecodeModeSense : DT to MT %d\n"), pDeviceCapabilitiesPage->DT2MT); g_fprintf(out, _("DecodeModeSense : DT to ST %d\n"), pDeviceCapabilitiesPage->DT2ST); g_fprintf(out, _("DecodeModeSense : DT to IE %d\n"), pDeviceCapabilitiesPage->DT2IE); g_fprintf(out, _("DecodeModeSense : DT to DT %d\n"), pDeviceCapabilitiesPage->DT2DT); } buffer++; break; default: buffer++; /* set pointer to the length information */ break; } /* Error if *buffer (length) is 0 */ if (*buffer == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -