diff options
author | Carsten Leonhardt <leo@debian.org> | 2019-02-27 23:12:40 +0100 |
---|---|---|
committer | Carsten Leonhardt <leo@debian.org> | 2019-02-27 23:12:40 +0100 |
commit | b698d55dd1b2625d218f042cf1bb47b3f8df9518 (patch) | |
tree | fd1ed179b369a43c141cbbff07230f125074cb28 /vms | |
parent | 9526a10abd8bdbd5db202407f499cc0629dd836d (diff) |
Import Upstream version 1.3.11
Diffstat (limited to 'vms')
-rw-r--r-- | vms/scsi.c | 470 |
1 files changed, 249 insertions, 221 deletions
@@ -70,21 +70,21 @@ typedef struct scsi$desc { - unsigned int SCSI$L_OPCODE; /* SCSI Operation Code */ - unsigned int SCSI$L_FLAGS; /* SCSI Flags Bit Map */ - unsigned char *SCSI$A_CMD_ADDR; /* ->SCSI Command Buffer */ - unsigned int SCSI$L_CMD_LEN; /* SCSI Command Length (bytes) */ - unsigned char *SCSI$A_DATA_ADDR; /* ->SCSI Data Buffer */ - unsigned int SCSI$L_DATA_LEN; /* SCSI Data Length (bytes) */ - unsigned int SCSI$L_PAD_LEN; /* SCSI Pad Length (bytes) */ - unsigned int SCSI$L_PH_CH_TMOUT; /* SCSI Phase Change Timeout (seconds) */ - unsigned int SCSI$L_DISCON_TMOUT; /* SCSI Disconnect Timeout (seconds) */ - unsigned int SCSI$L_RES_1; /* Reserved */ - unsigned int SCSI$L_RES_2; /* Reserved */ - unsigned int SCSI$L_RES_3; /* Reserved */ - unsigned int SCSI$L_RES_4; /* Reserved */ - unsigned int SCSI$L_RES_5; /* Reserved */ - unsigned int SCSI$L_RES_6; /* Reserved */ + unsigned int SCSI$L_OPCODE; /* SCSI Operation Code */ + unsigned int SCSI$L_FLAGS; /* SCSI Flags Bit Map */ + unsigned char *SCSI$A_CMD_ADDR; /* ->SCSI Command Buffer */ + unsigned int SCSI$L_CMD_LEN; /* SCSI Command Length (bytes) */ + unsigned char *SCSI$A_DATA_ADDR; /* ->SCSI Data Buffer */ + unsigned int SCSI$L_DATA_LEN; /* SCSI Data Length (bytes) */ + unsigned int SCSI$L_PAD_LEN; /* SCSI Pad Length (bytes) */ + unsigned int SCSI$L_PH_CH_TMOUT; /* SCSI Phase Change Timeout (seconds) */ + unsigned int SCSI$L_DISCON_TMOUT; /* SCSI Disconnect Timeout (seconds) */ + unsigned int SCSI$L_RES_1; /* Reserved */ + unsigned int SCSI$L_RES_2; /* Reserved */ + unsigned int SCSI$L_RES_3; /* Reserved */ + unsigned int SCSI$L_RES_4; /* Reserved */ + unsigned int SCSI$L_RES_5; /* Reserved */ + unsigned int SCSI$L_RES_6; /* Reserved */ } SCSI$DESC; @@ -95,10 +95,10 @@ SCSI$DESC; typedef struct scsi$iosb { - unsigned short SCSI$W_VMS_STAT; /* VMS Status Code */ - unsigned long SCSI$L_IOSB_TFR_CNT; /* Actual Byte Count Transferred */ - unsigned char SCSI$B_IOSB_FILL_1; /* Unused */ - unsigned char SCSI$B_IOSB_STS; /* SCSI Device Status */ + unsigned short SCSI$W_VMS_STAT; /* VMS Status Code */ + unsigned long SCSI$L_IOSB_TFR_CNT; /* Actual Byte Count Transferred */ + unsigned char SCSI$B_IOSB_FILL_1; /* Unused */ + unsigned char SCSI$B_IOSB_STS; /* SCSI Device Status */ } SCSI$IOSB; @@ -133,240 +133,268 @@ SCSI$IOSB; static struct dsc$descriptor_s *descr(char *String) { - static struct dsc$descriptor_s d_descrtbl[DESCR_CNT]; - static unsigned short descridx = 0; - struct dsc$descriptor_s *d_ret = &d_descrtbl[descridx]; - descridx = (descridx + 1) & (DESCR_CNT - 1); - d_ret->dsc$w_length = strlen((const char *) String); - d_ret->dsc$a_pointer = String; - d_ret->dsc$b_class = 0; - d_ret->dsc$b_dtype = 0; - return d_ret; + static struct dsc$descriptor_s d_descrtbl[DESCR_CNT]; + static unsigned short descridx = 0; + struct dsc$descriptor_s *d_ret = &d_descrtbl[descridx]; + descridx = (descridx + 1) & (DESCR_CNT - 1); + d_ret->dsc$w_length = strlen((const char *) String); + d_ret->dsc$a_pointer = String; + d_ret->dsc$b_class = 0; + d_ret->dsc$b_dtype = 0; + + return d_ret; } static int SCSI_OpenDevice(char *DeviceName) { - unsigned long d_dev[2], iosb[2], Status; - union prvdef setprivs, newprivs; - unsigned long ismnt = 0; - unsigned long dvcls = 0; - unsigned long dchr2 = 0; - int DeviceFD = 0; - struct itmlst_3 { - unsigned short ilen; - unsigned short code; - unsigned long *returnP; - unsigned long ignored; - } dvi_itmlst[] = { { 4, DVI$_MNT, 0 /*&ismnt*/, 0 }, - { 4, DVI$_DEVCLASS, 0 /*&dvcls*/, 0 }, - { 4, DVI$_DEVCHAR2, 0 /*&dchr2*/, 0 }, - { 0, 0, 0, 0 } }; - dvi_itmlst[0].returnP = &ismnt; - dvi_itmlst[1].returnP = &dvcls; - dvi_itmlst[2].returnP = &dchr2; - Status = sys$alloc(descr(DeviceName), 0, 0, 0, 0); - if (FailureStatusP(Status)) - { - VMS_ExitCode = Status; - FatalError("cannot allocate device '%s' - %X\n", DeviceName, Status); - } - Status = sys$assign(descr(DeviceName), &DeviceFD, 0, 0); - if (FailureStatusP(Status)) - { - VMS_ExitCode = Status; - FatalError("cannot open device '%s' - %X\n", DeviceName, Status); - } - Status = sys$getdviw(0, DeviceFD, 0, &dvi_itmlst, &iosb, 0, 0, 0); - if (FailureStatusP(Status)) - { - VMS_ExitCode = Status; - FatalError("cannot $getdvi(1) on device '%s' - %X\n", DeviceName, Status); - } - if (FailureStatusP(Status = iosb[0])) - { - VMS_ExitCode = Status; - FatalError("cannot $getdvi(2) on device '%s' - %X\n", DeviceName, Status); - } - if (dvcls != DC$_TAPE) - { - VMS_ExitCode = SS$_IVDEVNAM; - FatalError("specified device is NOT a magtape: operation denied\n"); - } + unsigned long d_dev[2], iosb[2], Status; + union prvdef setprivs, newprivs; + unsigned long ismnt = 0; + unsigned long dvcls = 0; + unsigned long dchr2 = 0; + int DeviceFD = 0; + struct itmlst_3 + { + unsigned short ilen; + unsigned short code; + unsigned long *returnP; + unsigned long ignored; + } + dvi_itmlst[] = { + { 4, DVI$_MNT, 0 /*&ismnt*/, 0 }, + { 4, DVI$_DEVCLASS, 0 /*&dvcls*/, 0 }, + { 4, DVI$_DEVCHAR2, 0 /*&dchr2*/, 0 }, + { 0, 0, 0, 0 } + }; + + dvi_itmlst[0].returnP = &ismnt; + dvi_itmlst[1].returnP = &dvcls; + dvi_itmlst[2].returnP = &dchr2; + + Status = sys$alloc(descr(DeviceName), 0, 0, 0, 0); + + if (FailureStatusP(Status)) + { + VMS_ExitCode = Status; + FatalError("cannot allocate device '%s' - %X\n", DeviceName, Status); + } + + Status = sys$assign(descr(DeviceName), &DeviceFD, 0, 0); + if (FailureStatusP(Status)) + { + VMS_ExitCode = Status; + FatalError("cannot open device '%s' - %X\n", DeviceName, Status); + } + + Status = sys$getdviw(0, DeviceFD, 0, &dvi_itmlst, &iosb, 0, 0, 0); + if (FailureStatusP(Status)) + { + VMS_ExitCode = Status; + FatalError("cannot $getdvi(1) on device '%s' - %X\n", DeviceName, Status); + } + + if (FailureStatusP(Status = iosb[0])) + { + VMS_ExitCode = Status; + FatalError("cannot $getdvi(2) on device '%s' - %X\n", DeviceName, Status); + } + + if (dvcls != DC$_TAPE) + { + VMS_ExitCode = SS$_IVDEVNAM; + FatalError("specified device is NOT a magtape: operation denied\n"); + } #ifndef __DECC #ifndef DEV$M_SCSI #define DEV$M_SCSI 0x1000000 #endif #endif - if (~dchr2 & DEV$M_SCSI) - { - VMS_ExitCode = SS$_IVDEVNAM; - FatalError("specified magtape is NOT a SCSI device: operation denied\n"); - } + if (~dchr2 & DEV$M_SCSI) + { + VMS_ExitCode = SS$_IVDEVNAM; + FatalError("specified magtape is NOT a SCSI device: operation denied\n"); + } #if USING_DEC_DRIVE | USING_LDRSET #ifndef __DECC #ifndef DEV$M_LDR #define DEV$M_LDR 0x100000 #endif #endif - if (~dchr2 & DEV$M_LDR) - { - VMS_ExitCode = SS$_IVDEVNAM; - FatalError( - "specified SCSI magtape does not have a loader: operation denied\n"); - } + if (~dchr2 & DEV$M_LDR) + { + VMS_ExitCode = SS$_IVDEVNAM; + FatalError("specified SCSI magtape does not have a loader: operation denied\n"); + } #endif - if (ismnt) - { - VMS_ExitCode = SS$_DEVMOUNT; - FatalError("specified device is mounted: operation denied\n"); - } - ots$move5(0, 0, 0, sizeof(newprivs), &newprivs); - newprivs.prv$v_diagnose = 1; - newprivs.prv$v_log_io = 1; - newprivs.prv$v_phy_io = 1; - Status = sys$setprv(1, &newprivs, 0, 0); - if (FailureStatusP(Status)) - { - VMS_ExitCode = Status; - FatalError( - "error enabling privs (diagnose,log_io,phy_io): operation denied\n"); - } - Status = sys$setprv(1, 0, 0, &setprivs); - if (FailureStatusP(Status)) - { - VMS_ExitCode = Status; - FatalError("error retrieving current privs: operation denied\n"); - } - if (!setprivs.prv$v_diagnose) - { - VMS_ExitCode = SS$_NODIAGNOSE; - FatalError("DIAGNOSE privilege is required: operation denied\n"); - } - if (!setprivs.prv$v_phy_io && !setprivs.prv$v_log_io) - { - VMS_ExitCode = SS$_NOPHY_IO; - FatalError("PHY_IO or LOG_IO privilege is required: operation denied\n"); - } - return DeviceFD; + if (ismnt) + { + VMS_ExitCode = SS$_DEVMOUNT; + FatalError("specified device is mounted: operation denied\n"); + } + + ots$move5(0, 0, 0, sizeof(newprivs), &newprivs); + newprivs.prv$v_diagnose = 1; + newprivs.prv$v_log_io = 1; + newprivs.prv$v_phy_io = 1; + Status = sys$setprv(1, &newprivs, 0, 0); + + if (FailureStatusP(Status)) + { + VMS_ExitCode = Status; + FatalError("error enabling privs (diagnose,log_io,phy_io): operation denied\n"); + } + + Status = sys$setprv(1, 0, 0, &setprivs); + if (FailureStatusP(Status)) + { + VMS_ExitCode = Status; + FatalError("error retrieving current privs: operation denied\n"); + } + + if (!setprivs.prv$v_diagnose) + { + VMS_ExitCode = SS$_NODIAGNOSE; + FatalError("DIAGNOSE privilege is required: operation denied\n"); + } + + if (!setprivs.prv$v_phy_io && !setprivs.prv$v_log_io) + { + VMS_ExitCode = SS$_NOPHY_IO; + FatalError("PHY_IO or LOG_IO privilege is required: operation denied\n"); + } + + return DeviceFD; } -static void SCSI_CloseDevice(char *DeviceName, - int DeviceFD) +static void SCSI_CloseDevice(char *DeviceName, int DeviceFD) { - unsigned long Status; - Status = sys$dassgn(DeviceFD); - if (FailureStatusP(Status)) - FatalError("cannot close SCSI device '%s' - %X\n", DeviceName, Status); + unsigned long Status; + + Status = sys$dassgn(DeviceFD); + if (FailureStatusP(Status)) + FatalError("cannot close SCSI device '%s' - %X\n", DeviceName, Status); } -static int SCSI_ExecuteCommand(int DeviceFD, - Direction_T Direction, - CDB_T *CDB, - int CDB_Length, - void *DataBuffer, - int DataBufferLength, - RequestSense_T *RequestSense) +static int SCSI_ExecuteCommand( int DeviceFD, + Direction_T Direction, + CDB_T *CDB, + int CDB_Length, + void *DataBuffer, + int DataBufferLength, + RequestSense_T *RequestSense) { - SCSI$DESC cmd_desc; - SCSI$IOSB cmd_iosb; - unsigned long Status; - int Result; - memset(RequestSense, 0, sizeof(RequestSense_T)); - /* Issue the QIO to send the SCSI Command. */ - ots$move5(0, 0, 0, sizeof(cmd_desc), &cmd_desc); - cmd_desc.SCSI$L_OPCODE = 1; /* Only defined SCSI opcode... a VMS thing */ - cmd_desc.SCSI$A_CMD_ADDR = CDB; - cmd_desc.SCSI$L_CMD_LEN = CDB_Length; - cmd_desc.SCSI$A_DATA_ADDR = DataBuffer; - cmd_desc.SCSI$L_DATA_LEN = DataBufferLength; - cmd_desc.SCSI$L_PAD_LEN = 0; - cmd_desc.SCSI$L_PH_CH_TMOUT = 180; /* SCSI Phase Change Timeout (seconds) */ - cmd_desc.SCSI$L_DISCON_TMOUT = 180; /* SCSI Disconnect Timeout (seconds) */ - switch (Direction) - { - /* - NOTE: Do NOT include flag SCSI$K_FL_ENAB_SYNC. - It does NOT work for this case. - */ - case Input: - cmd_desc.SCSI$L_FLAGS = SCSI$K_READ | SCSI$K_FL_ENAB_DIS; - break; - case Output: - cmd_desc.SCSI$L_FLAGS = SCSI$K_WRITE | SCSI$K_FL_ENAB_DIS; - break; - } - /* Issue the SCSI Command. */ - Status = sys$qiow(MK_EFN, DeviceFD, IO$_DIAGNOSE, &cmd_iosb, 0, 0, - &cmd_desc, sizeof(cmd_desc), 0, 0, 0, 0); - Result = SCSI$K_GOOD; - if (Status & 1) - Status = cmd_iosb.SCSI$W_VMS_STAT; - if (Status & 1) - Result = cmd_iosb.SCSI$B_IOSB_STS; - if (Result != SCSI$K_GOOD) - { - unsigned char RequestSenseCDB[6] = - { 0x03 /* REQUEST_SENSE */, 0, 0, 0, sizeof(RequestSense_T), 0 }; - printf("SCSI command error: %d - requesting sense data\n", Result); - /* Execute Request Sense to determine the failure reason. */ - ots$move5(0, 0, 0, sizeof(cmd_desc), &cmd_desc); - cmd_desc.SCSI$L_OPCODE = 1; /* Only defined SCSI opcode... a VMS thing */ - cmd_desc.SCSI$L_FLAGS = SCSI$K_READ | SCSI$K_FL_ENAB_DIS; - cmd_desc.SCSI$A_CMD_ADDR = RequestSenseCDB; - cmd_desc.SCSI$L_CMD_LEN = 6; - cmd_desc.SCSI$A_DATA_ADDR = RequestSense; - cmd_desc.SCSI$L_DATA_LEN = sizeof(RequestSense_T); - cmd_desc.SCSI$L_PH_CH_TMOUT = 180; - cmd_desc.SCSI$L_DISCON_TMOUT = 180; - /* Issue the QIO to send the Request Sense Command. */ - Status = sys$qiow(MK_EFN, DeviceFD, IO$_DIAGNOSE, &cmd_iosb, 0, 0, - &cmd_desc, sizeof(cmd_desc), 0, 0, 0, 0); - if (FailureStatusP(Status)) + SCSI$DESC cmd_desc; + SCSI$IOSB cmd_iosb; + unsigned long Status; + int Result; + memset(RequestSense, 0, sizeof(RequestSense_T)); + /* Issue the QIO to send the SCSI Command. */ + ots$move5(0, 0, 0, sizeof(cmd_desc), &cmd_desc); + cmd_desc.SCSI$L_OPCODE = 1; /* Only defined SCSI opcode... a VMS thing */ + cmd_desc.SCSI$A_CMD_ADDR = CDB; + cmd_desc.SCSI$L_CMD_LEN = CDB_Length; + cmd_desc.SCSI$A_DATA_ADDR = DataBuffer; + cmd_desc.SCSI$L_DATA_LEN = DataBufferLength; + cmd_desc.SCSI$L_PAD_LEN = 0; + cmd_desc.SCSI$L_PH_CH_TMOUT = 180; /* SCSI Phase Change Timeout (seconds) */ + cmd_desc.SCSI$L_DISCON_TMOUT = 180; /* SCSI Disconnect Timeout (seconds) */ + + switch (Direction) { - printf("?Error returned from REQUEST_SENSE(1): %%X%08lX\n", Status); - sys$exit(Status); + /* + NOTE: Do NOT include flag SCSI$K_FL_ENAB_SYNC. + It does NOT work for this case. + */ + case Input: + cmd_desc.SCSI$L_FLAGS = SCSI$K_READ | SCSI$K_FL_ENAB_DIS; + break; + + case Output: + cmd_desc.SCSI$L_FLAGS = SCSI$K_WRITE | SCSI$K_FL_ENAB_DIS; + break; } - /* Check the VMS Status from QIO. */ - Status = cmd_iosb.SCSI$W_VMS_STAT; - if (FailureStatusP(Status)) + + /* Issue the SCSI Command. */ + Status = sys$qiow(MK_EFN, DeviceFD, IO$_DIAGNOSE, &cmd_iosb, 0, 0, + &cmd_desc, sizeof(cmd_desc), 0, 0, 0, 0); + Result = SCSI$K_GOOD; + + if (Status & 1) + Status = cmd_iosb.SCSI$W_VMS_STAT; + + if (Status & 1) + Result = cmd_iosb.SCSI$B_IOSB_STS; + + if (Result != SCSI$K_GOOD) { - printf("?Error returned from REQUEST_SENSE(2): %%X%08lX\n", Status); - sys$exit(Status); + unsigned char RequestSenseCDB[6] = + { 0x03 /* REQUEST_SENSE */, 0, 0, 0, sizeof(RequestSense_T), 0 }; + + printf("SCSI command error: %d - requesting sense data\n", Result); + + /* Execute Request Sense to determine the failure reason. */ + ots$move5(0, 0, 0, sizeof(cmd_desc), &cmd_desc); + cmd_desc.SCSI$L_OPCODE = 1; /* Only defined SCSI opcode... a VMS thing */ + cmd_desc.SCSI$L_FLAGS = SCSI$K_READ | SCSI$K_FL_ENAB_DIS; + cmd_desc.SCSI$A_CMD_ADDR = RequestSenseCDB; + cmd_desc.SCSI$L_CMD_LEN = 6; + cmd_desc.SCSI$A_DATA_ADDR = RequestSense; + cmd_desc.SCSI$L_DATA_LEN = sizeof(RequestSense_T); + cmd_desc.SCSI$L_PH_CH_TMOUT = 180; + cmd_desc.SCSI$L_DISCON_TMOUT = 180; + + /* Issue the QIO to send the Request Sense Command. */ + Status = sys$qiow(MK_EFN, DeviceFD, IO$_DIAGNOSE, &cmd_iosb, 0, 0, + &cmd_desc, sizeof(cmd_desc), 0, 0, 0, 0); + if (FailureStatusP(Status)) + { + printf("?Error returned from REQUEST_SENSE(1): %%X%08lX\n", Status); + sys$exit(Status); + } + + /* Check the VMS Status from QIO. */ + Status = cmd_iosb.SCSI$W_VMS_STAT; + if (FailureStatusP(Status)) + { + printf("?Error returned from REQUEST_SENSE(2): %%X%08lX\n", Status); + sys$exit(Status); + } } - } - return Result; + return Result; } static void VMS_DefineStatusSymbols(void) { - char SymbolName[32], SymbolValue[32]; - int StorageElementNumber; - if (DataTransferElementFull) - { - /* Define MTX_DTE Symbol (environment variable) as 'FULL:n'. */ - sprintf(SymbolValue, "FULL:%d", - DataTransferElementSourceStorageElementNumber); - lib$set_symbol(descr("MTX_DTE"), descr(SymbolValue), &2); - } - else - { - /* Define MTX_DTE Symbol (environment variable) as 'EMPTY'. */ - lib$set_symbol(descr("MTX_DTE"), descr("EMPTY"), &2); - } - /* Define MTX_MSZ Symbol (environment variable) "Magazine SiZe" as 'n'. */ - sprintf(SymbolValue, "%d", StorageElementCount); - lib$set_symbol(descr("MTX_MSZ"), descr(SymbolValue), &2); - for (StorageElementNumber = 1; - StorageElementNumber <= StorageElementCount; - StorageElementNumber++) - { - sprintf(SymbolName, "MTX_STE%02d", StorageElementNumber); - strcpy(SymbolValue, - (StorageElementFull[StorageElementNumber] ? "FULL" : "EMPTY")); - lib$set_symbol(descr(SymbolName), descr(SymbolValue), &2); - } + char SymbolName[32], SymbolValue[32]; + int StorageElementNumber; + + if (DataTransferElementFull) + { + /* Define MTX_DTE Symbol (environment variable) as 'FULL:n'. */ + sprintf(SymbolValue, "FULL:%d", + DataTransferElementSourceStorageElementNumber); + lib$set_symbol(descr("MTX_DTE"), descr(SymbolValue), &2); + } + else + { + /* Define MTX_DTE Symbol (environment variable) as 'EMPTY'. */ + lib$set_symbol(descr("MTX_DTE"), descr("EMPTY"), &2); + } + + /* Define MTX_MSZ Symbol (environment variable) "Magazine SiZe" as 'n'. */ + sprintf(SymbolValue, "%d", StorageElementCount); + lib$set_symbol(descr("MTX_MSZ"), descr(SymbolValue), &2); + for (StorageElementNumber = 1; + StorageElementNumber <= StorageElementCount; + StorageElementNumber++) + { + sprintf(SymbolName, "MTX_STE%02d", StorageElementNumber); + strcpy(SymbolValue, + (StorageElementFull[StorageElementNumber] ? "FULL" : "EMPTY")); + lib$set_symbol(descr(SymbolName), descr(SymbolValue), &2); + } } |