mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Added SCSI MODE SENSE report to DiscImageChef.Device.Report.
This commit is contained in:
@@ -8,8 +8,12 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "scsi.h"
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
||||
int SendScsiCommand(int fd, void *cdb, unsigned char cdb_len, unsigned char *buffer, unsigned int buffer_len, unsigned char **senseBuffer, int direction)
|
||||
{
|
||||
if(buffer == NULL || cdb == NULL)
|
||||
@@ -62,5 +66,200 @@ int Inquiry(int fd, unsigned char **buffer, unsigned char **senseBuffer)
|
||||
cdb[4] = pagesLength;
|
||||
error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, pagesLength, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int PreventMediumRemoval(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return PreventAllowMediumRemoval(fd, senseBuffer, FALSE, TRUE);
|
||||
}
|
||||
|
||||
int AllowMediumRemoval(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return PreventAllowMediumRemoval(fd, senseBuffer, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int PreventAllowMediumRemoval(int fd, unsigned char **senseBuffer, int persistent, int prevent)
|
||||
{
|
||||
unsigned char cmd_len = 6;
|
||||
char cdb[] = {SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0};
|
||||
unsigned char *buffer = malloc(0);
|
||||
|
||||
if(prevent)
|
||||
cdb[4] += 0x01;
|
||||
if(persistent)
|
||||
cdb[4] += 0x02;
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int LoadTray(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return StartStopUnit(fd, senseBuffer, FALSE, 0, 0, FALSE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
int EjectTray(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return StartStopUnit(fd, senseBuffer, FALSE, 0, 0, FALSE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
int StartUnit(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return StartStopUnit(fd, senseBuffer, FALSE, 0, 0, FALSE, FALSE, TRUE);
|
||||
}
|
||||
|
||||
int StopUnit(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return StartStopUnit(fd, senseBuffer, FALSE, 0, 0, FALSE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int StartStopUnit(int fd, unsigned char **senseBuffer, int immediate, uint8_t formatLayer, uint8_t powerConditions, int changeFormatLayer, int loadEject, int start)
|
||||
{
|
||||
unsigned char cmd_len = 6;
|
||||
char cdb[] = {SCSI_START_STOP_UNIT, 0, 0, 0, 0, 0};
|
||||
unsigned char *buffer = malloc(0);
|
||||
|
||||
if(immediate)
|
||||
cdb[1] += 0x01;
|
||||
if(changeFormatLayer)
|
||||
{
|
||||
cdb[3] = (formatLayer & 0x03);
|
||||
cdb[4] += 0x04;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(loadEject)
|
||||
cdb[4] += 0x02;
|
||||
if(start)
|
||||
cdb[4] += 0x01;
|
||||
}
|
||||
cdb[4] += ((powerConditions & 0x0F) << 4);
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int SpcPreventMediumRemoval(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return SpcPreventAllowMediumRemoval(fd, senseBuffer, 0x01);
|
||||
}
|
||||
|
||||
int SpcAllowMediumRemoval(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return SpcPreventAllowMediumRemoval(fd, senseBuffer, 0x00);
|
||||
}
|
||||
|
||||
int SpcPreventAllowMediumRemoval(int fd, unsigned char **senseBuffer, uint8_t preventMode)
|
||||
{
|
||||
unsigned char cmd_len = 6;
|
||||
char cdb[] = {SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0};
|
||||
unsigned char *buffer = malloc(0);
|
||||
cdb[4] = (preventMode & 0x03);
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int Load(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return LoadUnload(fd, senseBuffer, FALSE, TRUE, FALSE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int Unload(int fd, unsigned char **senseBuffer)
|
||||
{
|
||||
return LoadUnload(fd, senseBuffer, FALSE, FALSE, FALSE, FALSE, FALSE);
|
||||
}
|
||||
|
||||
int LoadUnload(int fd, unsigned char **senseBuffer, int immediate, int load, int retense, int endOfTape, int hold)
|
||||
{
|
||||
unsigned char cmd_len = 6;
|
||||
char cdb[] = {SCSI_LOAD_UNLOAD, 0, 0, 0, 0, 0};
|
||||
unsigned char *buffer = malloc(0);
|
||||
if(immediate)
|
||||
cdb[1] = 0x01;
|
||||
if(load)
|
||||
cdb[4] += 0x01;
|
||||
if(retense)
|
||||
cdb[4] += 0x02;
|
||||
if(endOfTape)
|
||||
cdb[4] += 0x04;
|
||||
if(hold)
|
||||
cdb[4] += 0x08;
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, buffer, 0, senseBuffer, SG_DXFER_NONE);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int ModeSense6(int fd, unsigned char **buffer, unsigned char **senseBuffer, int DBD, uint8_t pageControl, uint8_t pageCode, uint8_t subPageCode)
|
||||
{
|
||||
unsigned char cmd_len = 6;
|
||||
unsigned int buffer_len = 255;
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
|
||||
unsigned char cdb[] = {SCSI_MODE_SENSE, 0, 0, 0, 0, 0};
|
||||
if(DBD)
|
||||
cdb[1] |= 0x08;
|
||||
cdb[2] |= pageControl;
|
||||
cdb[2] |= (pageCode & 0x3F);
|
||||
cdb[3] = subPageCode;
|
||||
cdb[4] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
buffer_len = (unsigned int)*(*buffer + 0) + 1;
|
||||
|
||||
free(*buffer);
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
cdb[4] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int ModeSense10(int fd, unsigned char **buffer, unsigned char **senseBuffer, int LLBAA, int DBD, uint8_t pageControl, uint8_t pageCode, uint8_t subPageCode)
|
||||
{
|
||||
unsigned char cmd_len = 10;
|
||||
unsigned int buffer_len = 4096;
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
|
||||
unsigned char cdb[] = {SCSI_MODE_SENSE_10, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
if(LLBAA)
|
||||
cdb[1] |= 0x10;
|
||||
if(DBD)
|
||||
cdb[1] |= 0x08;
|
||||
cdb[2] |= pageControl;
|
||||
cdb[2] |= (pageCode & 0x3F);
|
||||
cdb[3] = subPageCode;
|
||||
cdb[7] = (uint8_t)((buffer_len & 0xFF00) >> 8);
|
||||
cdb[8] = (uint8_t)(buffer_len & 0xFF);
|
||||
cdb[9] = 0;
|
||||
|
||||
int error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
if(error)
|
||||
return error;
|
||||
|
||||
buffer_len = (unsigned int)(*(*buffer + 0) << 8) + *(*buffer + 1) + 2;
|
||||
|
||||
free(*buffer);
|
||||
*buffer = malloc(buffer_len);
|
||||
memset(*buffer, 0, buffer_len);
|
||||
cdb[7] = (uint8_t)((buffer_len & 0xFF00) >> 8);
|
||||
cdb[8] = (uint8_t)(buffer_len & 0xFF);
|
||||
|
||||
error = SendScsiCommand(fd, &cdb, cmd_len, *buffer, buffer_len, senseBuffer, SG_DXFER_FROM_DEV);
|
||||
|
||||
return error;
|
||||
}
|
||||
Reference in New Issue
Block a user