int scsi_persistent_reserve_in_read_keys(int fd) { unsigned char cdb[]={0x5e,0,0,0,0,0,0,0,0,0}; unsigned int data_size=0x00ff; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=0; int res, i; unsigned long prgeneration, additional_length; cdb[1]=service_action; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; printf("PRESISTENT RESERVE IN: READ KEYS\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } /* PRGeneration */ prgeneration=data[0]; prgeneration<<=8;prgeneration|=data[1]; prgeneration<<=8;prgeneration|=data[2]; prgeneration<<=8;prgeneration|=data[3]; printf("PRGeneration:%lu\n", prgeneration); /* Additional Length */ additional_length=data[4]; additional_length<<=8;additional_length|=data[5]; additional_length<<=8;additional_length|=data[6]; additional_length<<=8;additional_length|=data[7]; printf("Additional Length:%lu\n", additional_length); /* print the registered keys */ for(i=0;i<additional_length;i+=8){ printf("Key:%02x%02x%02x%02x%02x%02x%02x%02x\n", data[i+8], data[i+9], data[i+10], data[i+11], data[i+12], data[i+13], data[i+14], data[i+15]); } return 0; }
int scsi_persistent_reserve_in_read_reservation(int fd) { unsigned char cdb[]={0x5e,0,0,0,0,0,0,0,0,0}; unsigned int data_size=0x00ff; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; unsigned char service_action=1; int res; unsigned long prgeneration, additional_length; cdb[1]=service_action; cdb[7]=(data_size>>8)&0xff; cdb[8]=data_size&0xff; printf("PRESISTENT RESERVE IN: READ RESERVATION\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } /* PRGeneration */ prgeneration=data[0]; prgeneration<<=8;prgeneration|=data[1]; prgeneration<<=8;prgeneration|=data[2]; prgeneration<<=8;prgeneration|=data[3]; printf("PRGeneration:%lu\n", prgeneration); /* Additional Length */ additional_length=data[4]; additional_length<<=8;additional_length|=data[5]; additional_length<<=8;additional_length|=data[6]; additional_length<<=8;additional_length|=data[7]; printf("Additional Length:%lu\n", additional_length); if(additional_length==16){ printf("Key:%02x%02x%02x%02x%02x%02x%02x%02x\n", data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); printf("Scope:%xh Type:%xh\n",data[21]>>4,data[21]&0x0f); }
int scsi_inquiry_supported_vpd_pages(int fd) { unsigned char cdb[]={0x12,0x01,0,0,0,0}; unsigned int data_size=0xff; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; int res, pl, i; cdb[3]=(data_size>>8)&0xff; cdb[4]=data_size&0xff; printf("INQUIRY Supported VPD Pages:\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } /* Page Length */ pl=data[3]; /* Pages */ for(i=4;i<(pl+4);i++){ printf("Page:%02xh (%s)\n", data[i], val_to_str(vpd_pages, data[i])); } return 0; }
int scsi_inquiry_unit_serial_number(int fd) { unsigned char cdb[]={0x12,0x01,0x80,0,0,0}; unsigned int data_size=0x00ff; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; int res, pl, i; cdb[3]=(data_size>>8)&0xff; cdb[4]=data_size&0xff; printf("INQUIRY Unit Serial Number:\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } /* Page Length */ pl=data[3]; /* Unit Serial Number */ printf("Unit Serial Number:"); for(i=4;i<(pl+4);i++)printf("%c",data[i]&0xff);printf("\n"); return 0; }
//----------------------------------------------------------- static int Jorway73ADoIo( CamKey Key, BYTE A, BYTE F, int Count, BYTE *Data, BYTE Mem, TranslatedIosb *iosb, int dmode, int Enhanced ) { char dev_name[7]; int IsDataCommand, scsiDevice; int xfer_data_length; int status; unsigned char *cmd; unsigned char cmdlen; int direction; unsigned int bytcnt; int reqbytcnt = 0; J73ASenseData sense; char sensretlen; int online; int enhanced; struct { __u8 opcode; __u8 f : 5; __u8 lu : 3; __u8 n : 5; __u8 bs : 1; __u8 m : 2; __u8 a : 4; __u8 zero1 : 4; __u8 transfer_len; __u8 zero2; } NONDATAcommand = {1,0,0,0,0,0,0,0,0,0}; struct { __u8 opcode; __u8 f : 5; __u8 lu : 3; __u8 n : 5; __u8 bs : 1; __u8 m : 2; __u8 a : 4; __u8 zero1 : 4; __u8 transfer_len; __u8 zero2; } ShortDATAcommand = {1,0,0,0,0,0,0,0,0,0}; struct { __u8 opcode; __u8 zero1 : 5; __u8 lu : 3; __u8 f : 5; __u8 zero2 : 3; __u8 n : 5; __u8 bs : 1; __u8 m : 2; __u8 a : 4; __u8 zero3 : 4; __u8 zero4; __u8 transfer_len[3]; __u8 zero5; } LongDATAcommand = {0x21,0,0,0,0,0,0,0,0,0}; static char modes[4] = {2,2,3,1}; /* QStop, QIgnore, QRep, QScan */ static char singlemodes[4] = {0,2,3,1}; if( MSGLVL(FUNCTION_NAME) ) printf( "%s()\n", J_ROUTINE_NAME ); //printf( "%s(iosb is %sNULL)\n", J_ROUTINE_NAME, (iosb)?"NOT ":"" ); // [2002.12.13] sprintf(dev_name, "GK%c%d%02d", Key.scsi_port, Key.scsi_address, Key.crate); if( (scsiDevice = get_scsi_device_number( dev_name, &enhanced, &online )) < 0 ) { if( MSGLVL(IMPORTANT) ) fprintf( stderr, "%s(): error -- no scsi device found for '%s'\n", J_ROUTINE_NAME, dev_name ); status = NO_DEVICE; goto Jorway73ADoIo_Exit; } if (!online && Key.slot != 30) return CamOFFLINE; if (online && Key.slot == 30 && F == 1 && A == 0) { *(short *)Data = 0x30; return CamDONE_Q; } if( MSGLVL(DETAILS) ) printf( "%s(): device '%s' = '/dev/sg%d'\n", J_ROUTINE_NAME, dev_name, scsiDevice ); IsDataCommand = (F & 0x08) ? FALSE : TRUE; if( IsDataCommand ) { union { BYTE b[4]; unsigned int l; } transfer_len; reqbytcnt = transfer_len.l = Count * ((Mem == 24) ? 4 : 2); direction = (F < 8) ? 1 : 2; if (reqbytcnt < 256) { cmd = (char *)&ShortDATAcommand; cmdlen = sizeof(ShortDATAcommand); ShortDATAcommand.f = F; ShortDATAcommand.bs = Mem == 24; ShortDATAcommand.n = Key.slot; ShortDATAcommand.m = Count > 1 ? modes[dmode] : singlemodes[dmode]; ShortDATAcommand.a = A; ShortDATAcommand.transfer_len = transfer_len.l; } else { cmd = (char *)&LongDATAcommand; cmdlen = sizeof(LongDATAcommand); LongDATAcommand.f = F; LongDATAcommand.bs = Mem == 24; LongDATAcommand.n = Key.slot; LongDATAcommand.m = modes[dmode]; LongDATAcommand.a = A; LongDATAcommand.transfer_len[0] = transfer_len.b[2]; // NB! order reversal LongDATAcommand.transfer_len[1] = transfer_len.b[1]; LongDATAcommand.transfer_len[2] = transfer_len.b[0]; } } else { NONDATAcommand.f = F; NONDATAcommand.n = Key.slot; NONDATAcommand.a = A; cmd = (unsigned char *)&NONDATAcommand; cmdlen = sizeof(NONDATAcommand); direction = 0; } scsi_lock(scsiDevice,1); status = scsi_io( scsiDevice, direction, cmd, cmdlen, Data, reqbytcnt, (unsigned char *)&sense, sizeof(sense), &sensretlen, &bytcnt); scsi_lock(scsiDevice,0); status = Jorway73ATranslateIosb(IsDataCommand, reqbytcnt,&sense,status); if ( iosb ) *iosb = LastIosb; // [2002.12.11] Jorway73ADoIo_Exit: if( MSGLVL(FUNCTION_NAME+1) ) { // This is only rough - depends on the nature of the "overloaded" vars printf("scsi_mode opcode=%d, dmode=%d, modes[dmode]=%d, [1]=%d, [3]=%d, [5]=%d [7]=%d\n", cmd[0], dmode, modes[dmode], cmd[1], cmd[3], cmd[5], cmd[7]); if (!iosb) {printf("Jorway73ADoIo_Exit: Null pointer to iosb\n"); } else { printf( "%s(): iosb->status [0x%x]\n", J_ROUTINE_NAME, iosb->status ); printf( "%s(): iosb->x [0x%x]\n", J_ROUTINE_NAME, iosb->x ); printf( "%s(): iosb->q [0x%x]\n", J_ROUTINE_NAME, iosb->q ); //printf( "%s(): iosb->bytcnt [%d]\n", J_ROUTINE_NAME, iosb->bytcnt); // [2002.12.11] } } //printf("Jorway73ADoIo(iosb)::->> bytecount= %d\n", iosb->bytcnt); // [2002.12.13] return status; }
//----------------------------------------------------------- static int JorwayDoIo( CamKey Key, BYTE A, BYTE F, int Count, BYTE *Data, BYTE Mem, TranslatedIosb *iosb, int dmode, int Enhanced ) { char dev_name[7]; int IsDataCommand, scsiDevice; int xfer_data_length; int status; unsigned char *cmd; unsigned char cmdlen; int direction; unsigned int bytcnt; int reqbytcnt = 0; SenseData sense; char sensretlen; int online; int enhanced; CDBCamacDataCommand( DATAcommand ); CDBCamacNonDataCommand( NONDATAcommand ); if( MSGLVL(FUNCTION_NAME) ) printf( "%s()\n", J_ROUTINE_NAME ); //printf( "%s(iosb is %sNULL)\n", J_ROUTINE_NAME, (iosb)?"NOT ":"" ); // [2002.12.13] sprintf(dev_name, "GK%c%d%02d", Key.scsi_port, Key.scsi_address, Key.crate); if( (scsiDevice = get_scsi_device_number( dev_name, &enhanced, &online )) < 0 ) { if( MSGLVL(IMPORTANT) ) fprintf( stderr, "%s(): error -- no scsi device found for '%s'\n", J_ROUTINE_NAME, dev_name ); status = NO_DEVICE; goto JorwayDoIo_Exit; } if (!online && Key.slot != 30) return CamOFFLINE; if (!Enhanced) enhanced = 0; if( MSGLVL(DETAILS) ) printf( "%s(): device '%s' = '/dev/sg%d'\n", J_ROUTINE_NAME, dev_name, scsiDevice ); IsDataCommand = (F & 0x08) ? FALSE : TRUE; if( IsDataCommand ) { union { BYTE b[4]; unsigned int l; } transfer_len; DATAcommand.f = F; DATAcommand.bs = Mem == 24; DATAcommand.n = Key.slot; DATAcommand.m = JORWAYMODE(dmode, enhanced, Count > 1); DATAcommand.a = A; DATAcommand.sncx = 0; DATAcommand.scs = 0; reqbytcnt = transfer_len.l = Count * ((Mem == 24) ? 4 : 2); # if JORWAY_DISCONNECT # ifdef SG_BIG_BUFF DATAcommand.dd = transfer_len.l > SG_BIG_BUFF; # else DATAcommand.dd = transfer_len.l > 4096; # endif # else DATAcommand.dd = 0; # endif DATAcommand.crate = Key.crate; DATAcommand.sp = HIGHWAY_SERIAL; DATAcommand.transfer_len[0] = transfer_len.b[2]; // NB! order reversal DATAcommand.transfer_len[1] = transfer_len.b[1]; DATAcommand.transfer_len[2] = transfer_len.b[0]; cmd = (unsigned char *)&DATAcommand; cmdlen = sizeof(DATAcommand); direction = (F < 8) ? 1 : 2; } else { NONDATAcommand.bytes[1] = F; NONDATAcommand.bytes[2] = Key.slot; NONDATAcommand.bytes[3] = A; NONDATAcommand.bytes[4] = (HIGHWAY_SERIAL << 7) | Key.crate; cmd = (unsigned char *)&NONDATAcommand; cmdlen = sizeof(NONDATAcommand); direction = 0; } memset(&sense,0,sizeof(sense)); sensretlen=0; bytcnt=0; scsi_lock(scsiDevice,1); status = scsi_io( scsiDevice, direction, cmd, cmdlen, Data, reqbytcnt, (unsigned char *)&sense, sizeof(sense), &sensretlen, &bytcnt); scsi_lock(scsiDevice,0); status = JorwayTranslateIosb(reqbytcnt,&sense,sensretlen,bytcnt,status); if ( iosb ) *iosb = LastIosb; // [2002.12.11] JorwayDoIo_Exit: if( MSGLVL(DETAILS) ) { printf( "%s(): iosb->status [0x%x]\n", J_ROUTINE_NAME, iosb->status ); printf( "%s(): iosb->x [0x%x]\n", J_ROUTINE_NAME, iosb->x ); printf( "%s(): iosb->q [0x%x]\n", J_ROUTINE_NAME, iosb->q ); //printf( "%s(): iosb->bytcnt [%d]\n", J_ROUTINE_NAME, iosb->bytcnt); // [2002.12.11] } //printf("JorwayDoIo(iosb)::->> bytecount= %d\n", iosb->bytcnt); // [2002.12.13] return status; }
int scsi_inquiry(int fd) { unsigned char cdb[]={0x12,0,0,0,0,0}; unsigned int data_size=96; unsigned char data[data_size]; unsigned int sense_len=32; unsigned char sense[sense_len]; int res, alen, i; cdb[3]=(data_size>>8)&0xff; cdb[4]=data_size&0xff; printf("Standard INQUIRY Data:\n"); res=scsi_io(fd, cdb, sizeof(cdb), SG_DXFER_FROM_DEV, data, &data_size, sense, &sense_len); if(res){ printf("SCSI_IO failed\n"); return -1; } if(sense_len){ print_sense_data(sense, sense_len); return -1; } /* Peripheral Qualifier */ printf("Peripheral Qualifier:%c%c%cb\n", '0'+!!(data[0]&0x80), '0'+!!(data[0]&0x40), '0'+!!(data[0]&0x20)); /* Peripheral Device Type */ printf("Peripheral Device Type: 0x%02x (%s)\n", data[0]&0x1f, val_to_str(peripheral_device_types, data[0]&0x1f)); /* RMB */ printf("RMB: %s device\n", data[1]&0x80?"REMOVABLE":"NON-REMOVABLE"); /* SCSI Version */ printf("SCSI Version: 0x%02x (%s)\n", data[2], val_to_str(scsi_versions, data[2])); /* NormACA, HiSUP, Response Data Format */ printf("NormACA:%d HiSup:%d ResponseDataFormat:%d\n", !!(data[3]&0x20), !!(data[3]&0x10), data[3]&0x0f); /* Additional Length */ alen=data[4]; switch(data[3]&0x0f){ /*SPC-2/SPC-3/SPC-4*/ case 2: /*SPC (not strictly correct but we print it like 2 anyway)*/ case 1: /* SCCS ... */ printf("SCCS:%d ACC:%d TPGS:%c%cb 3PC:%d PROTECT:%d\n", !!(data[5]&0x80), !!(data[5]&0x40), '0'+!!(data[5]&0x20), '0'+!!(data[5]&0x10), !!(data[5]&0x08), !!(data[5]&0x01)); /* Encserv ... */ printf("Encserv:%d VS:%d MultiP:%d ADDR16:%d\n", !!(data[6]&0x40), !!(data[6]&0x20), !!(data[6]&0x10), !!(data[6]&0x01)); /* WBUS16 ... */ printf("WBUS16:%d SYNC:%d CmdQue:%d VS:%d\n", !!(data[7]&0x20), !!(data[7]&0x10), !!(data[7]&0x02), !!(data[7]&0x01)); /* T10 vendor Identification */ printf("Vendor:"); for(i=0;i<8;i++)printf("%c",data[8+i]);printf("\n"); /* Product Identification */ printf("Product:"); for(i=0;i<16;i++)printf("%c",data[16+i]);printf("\n"); /* Product Revision Level */ printf("Product Revision:"); for(i=0;i<4;i++)printf("%c",data[32+i]);printf("\n"); break; } return 0; }
static void sim_action( ide_bus_info *bus, CCB_HEADER *ccb ) { SHOW_FLOW( 3, "func_code=%i, device=%i:%i", (int)ccb->cam_func_code, (int)ccb->cam_target_id, (int)ccb->cam_target_lun ); if( bus->disconnected ) goto disconnected; switch( ccb->cam_func_code ) { case XPT_NOOP: // the only valid field is the path id // we are supposed to return immediately if the path is valid // (well, else we wouldn't be here, would we) ccb->cam_status = CAM_REQ_CMP; xpt->done( ccb ); return; case XPT_SCSI_IO: scsi_io( bus, ccb ); return; case XPT_GDEV_TYPE: // handled by XPT - this code is for safety only ccb->cam_status = CAM_REQ_INVALID; xpt->done( ccb ); return; case XPT_PATH_INQ: path_inquiry( bus, ccb ); return; case XPT_REL_SIMQ: case XPT_SASYNC_CB: case XPT_SDEV_TYPE: ccb->cam_status = CAM_REQ_INVALID; xpt->done( ccb ); return; case XPT_SCAN_BUS: scan_bus( bus, ccb ); return; case XPT_ABORT: // we cannot abort specific commands, so just ignore // fall through case XPT_TERM_IO: // same as abort ccb->cam_status = CAM_REQ_CMP; xpt->done( ccb ); return; case XPT_RESET_BUS: // no, we don't want to do that ccb->cam_status = CAM_REQ_INVALID; xpt->done( ccb ); return; case XPT_RESET_DEV: // XXX to do ccb->cam_status = CAM_REQ_INVALID; xpt->done( ccb ); return; case XPT_SCAN_LUN: // currently not called by XPT; only SCAN BUS leads to a rescan // (probably we'll remove this function from public XPT access) ccb->cam_status = CAM_REQ_INVALID; xpt->done( ccb ); return; case XPT_INQUIRY_PARAMS: { CAM_INQUIRY_PARAMS *params = (CAM_INQUIRY_PARAMS *)ccb; CAM_SIM_PARAMS *sim_params = ¶ms->sim_params; sim_params->dma_alignment = bus->controller_params.dma_alignment; sim_params->dma_boundary = bus->controller_params.dma_boundary; sim_params->dma_boundary_solid = bus->controller_params.dma_boundary_solid; sim_params->max_sg_num = bus->controller_params.max_sg_num; sim_params->max_blocks = 256; ccb->cam_status = CAM_REQ_CMP; xpt->done( ccb ); return; } default: // we don't support engine stuff nor target mode ccb->cam_status = CAM_REQ_INVALID; xpt->done( ccb ); return; } return; disconnected: ccb->cam_status = CAM_NO_HBA; xpt->done( ccb ); return; }