Imported Upstream version 0.72.2
This commit is contained in:
98
scsi-layer.c
98
scsi-layer.c
@@ -1,5 +1,5 @@
|
||||
/* dvdisaster: Additional error correction for optical media.
|
||||
* Copyright (C) 2004-2009 Carsten Gnoerlich.
|
||||
* Copyright (C) 2004-2010 Carsten Gnoerlich.
|
||||
* Project home page: http://www.dvdisaster.com
|
||||
* Email: carsten@dvdisaster.com -or- cgnoerlich@fsfe.org
|
||||
*
|
||||
@@ -55,6 +55,20 @@ void FreeAlignedBuffer(AlignedBuffer *ab)
|
||||
g_free(ab);
|
||||
}
|
||||
|
||||
/*
|
||||
* Align a length to a multiple of 4.
|
||||
* Some broken chipsets fail on DMA otherways.
|
||||
*/
|
||||
|
||||
static void length_align(unsigned int *length)
|
||||
{
|
||||
if(*length & 3)
|
||||
{ Verbose("# Warning: Realigning length from %d to %d\n",
|
||||
*length, *length & ~3);
|
||||
*length &= ~3;
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
*** CD and DVD query routines.
|
||||
***/
|
||||
@@ -143,7 +157,7 @@ static int try_fallback_type_check(DeviceHandle *dh)
|
||||
{ AlignedBuffer *ab;
|
||||
Sense *sense = &dh->sense;
|
||||
unsigned char cmd[MAX_CDB_SIZE];
|
||||
int length;
|
||||
unsigned int length;
|
||||
|
||||
Verbose("# *** try_fallback_type_check(%s) ***\n", dh->devinfo);
|
||||
|
||||
@@ -159,12 +173,12 @@ static int try_fallback_type_check(DeviceHandle *dh)
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 0; /* We want DI (disc information) */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
/*** Only a BD should respond positively here */
|
||||
|
||||
Verbose("# BD: trying READ DVD with BD subcommand for size\n");
|
||||
if(SendPacket(dh, cmd, 12, ab->buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 12, ab->buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{
|
||||
Verbose("# failed -> not a BD type medium.\n");
|
||||
goto try_dvd;
|
||||
@@ -176,6 +190,8 @@ static int try_fallback_type_check(DeviceHandle *dh)
|
||||
|
||||
length = ab->buf[0]<<8 | ab->buf[1];
|
||||
length += 2;
|
||||
length_align(&length);
|
||||
|
||||
if(length != 4100) /* not a BD */
|
||||
{ Verbose("# allocation length = %d != 4100 -> not a BD type medium.\n", length);
|
||||
goto try_dvd;
|
||||
@@ -200,7 +216,7 @@ try_dvd:
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 0; /* We want PHYSICAL info */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
/* Different drives react with different error codes on this request;
|
||||
especially CDROMs seem to react very indeterministic here
|
||||
@@ -208,7 +224,7 @@ try_dvd:
|
||||
So we do not look for specific error and regard any failure as a sign
|
||||
that the medium is not a DVD. */
|
||||
|
||||
if(SendPacket(dh, cmd, 12, ab->buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 12, ab->buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{
|
||||
Verbose("# failed -> not a DVD type medium\n");
|
||||
goto assume_cd;
|
||||
@@ -444,10 +460,10 @@ static int query_cd(DeviceHandle *dh, int probe_only)
|
||||
cmd[2] = 0; /* format; we want the TOC */
|
||||
cmd[6] = 1; /* track/session number */
|
||||
cmd[7] = 0; /* allocation length */
|
||||
cmd[8] = 2;
|
||||
cmd[8] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#CD: querying size of READ TOC/PMA/ATIP (for TOC)\n");
|
||||
if(SendPacket(dh, cmd, 10, buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 10, buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{
|
||||
FreeAlignedBuffer(ab);
|
||||
if(!probe_only)
|
||||
@@ -462,6 +478,8 @@ static int query_cd(DeviceHandle *dh, int probe_only)
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2 ; /* MMC3: "Disc information length excludes itself" */
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#CD: size returned is %d\n", length);
|
||||
|
||||
if(length>1024) /* don't let the drive hack us using a buffer overflow ;-) */
|
||||
@@ -506,10 +524,10 @@ static int query_cd(DeviceHandle *dh, int probe_only)
|
||||
cmd[2] = 2; /* format; we want the full TOC */
|
||||
cmd[6] = 1; /* track/session number */
|
||||
cmd[7] = 0; /* allocation length */
|
||||
cmd[8] = 2;
|
||||
cmd[8] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#CD: querying size of READ TOC/PMA/ATIP (for full TOC)\n");
|
||||
if(SendPacket(dh, cmd, 10, buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 10, buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{ FreeAlignedBuffer(ab);
|
||||
if(!probe_only)
|
||||
Stop(_("%s\nCould not query full TOC length.\n"),
|
||||
@@ -519,6 +537,8 @@ static int query_cd(DeviceHandle *dh, int probe_only)
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2; /* MMC3: "Disc information length excludes itself" */
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#CD: size returned is %d\n", length);
|
||||
|
||||
if(length < 15)
|
||||
@@ -612,10 +632,10 @@ static int query_dvd(DeviceHandle *dh, int probe_only)
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 0; /* We want PHYSICAL info */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#DVD: trying READ DVD for size of PHYSICAL info\n");
|
||||
if(SendPacket(dh, cmd, 12, buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 12, buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{ FreeAlignedBuffer(ab);
|
||||
if(!probe_only)
|
||||
Stop(_("%s\nCould not query dvd structure length.\n"),
|
||||
@@ -625,6 +645,7 @@ static int query_dvd(DeviceHandle *dh, int probe_only)
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2;
|
||||
length_align(&length);
|
||||
|
||||
if(length>4096) /* don't let the drive hack us using a buffer overflow ;-) */
|
||||
{ FreeAlignedBuffer(ab);
|
||||
@@ -735,12 +756,13 @@ static int query_dvd(DeviceHandle *dh, int probe_only)
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 0x11; /* We want the ADIP */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#DVD: trying READ DVD for size of ADIP\n");
|
||||
if(SendPacket(dh, cmd, 12, buf, 2, sense, DATA_READ) == 0)
|
||||
if(SendPacket(dh, cmd, 12, buf, MIN_TRANSFER_LEN, sense, DATA_READ) == 0)
|
||||
{ length = buf[0]<<8 | buf[1];
|
||||
length += 2;
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#DVD: size returned is %d\n", length);
|
||||
|
||||
@@ -784,12 +806,13 @@ static int query_dvd(DeviceHandle *dh, int probe_only)
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 0x0E; /* We want the lead-in info */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#DVD: trying READ DVD for size of lead-in\n");
|
||||
if(SendPacket(dh, cmd, 12, buf, 2, sense, DATA_READ) == 0)
|
||||
if(SendPacket(dh, cmd, 12, buf, MIN_TRANSFER_LEN, sense, DATA_READ) == 0)
|
||||
{ length = buf[0]<<8 | buf[1];
|
||||
length += 2;
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#DVD: size returned is %d\n", length);
|
||||
if(length < 4096)
|
||||
@@ -938,10 +961,10 @@ static int query_bd(DeviceHandle *dh, int probe_only)
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 0; /* We want DI (disc information) */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#BD: trying READ DISC STRUCTURE for size\n");
|
||||
if(SendPacket(dh, cmd, 12, buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 12, buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{ FreeAlignedBuffer(ab);
|
||||
if(!probe_only)
|
||||
Stop(_("%s\nCould not query BD disc structure length.\n"),
|
||||
@@ -951,6 +974,8 @@ static int query_bd(DeviceHandle *dh, int probe_only)
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2;
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#BD: disc structure query succeeded, length %d bytes\n", length);
|
||||
|
||||
/* Do the real query */
|
||||
@@ -1052,10 +1077,10 @@ static int query_type(DeviceHandle *dh, int probe_only)
|
||||
cmd[0] = 0x51; /* READ DISC INFORMATION */
|
||||
cmd[1] = 0; /* standard disc info */
|
||||
cmd[7] = 0; /* Allocation length */
|
||||
cmd[8] = 2;
|
||||
cmd[8] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("# trying READ DISC INFORMATION for size\n");
|
||||
if(SendPacket(dh, cmd, 10, buf, 2, sense, DATA_READ) == 0)
|
||||
if(SendPacket(dh, cmd, 10, buf, MIN_TRANSFER_LEN, sense, DATA_READ) == 0)
|
||||
{ length = buf[0]<<8 | buf[1];
|
||||
|
||||
Verbose("# size returned is %d\n", length);
|
||||
@@ -1158,16 +1183,18 @@ static int query_blank(DeviceHandle *dh)
|
||||
cmd[2] = 4; /* format; we want the ATIP */
|
||||
cmd[6] = 0; /* track/session number */
|
||||
cmd[7] = 0; /* allocation length */
|
||||
cmd[8] = 2;
|
||||
cmd[8] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#CD: querying size of READ TOC/PMA/ATIP (for ATIP)\n");
|
||||
if(SendPacket(dh, cmd, 10, buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 10, buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{ FreeAlignedBuffer(ab);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2; /* MMC3: "Disc information length excludes itself" */
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#CD: size returned is %d\n", length);
|
||||
|
||||
if(length < 15 || length > 1024) /* implausible */
|
||||
@@ -1212,16 +1239,18 @@ static int query_blank(DeviceHandle *dh)
|
||||
cmd[1] = 0x01; /* TCDB (track number) addressing) */
|
||||
cmd[5] = 1; /* we want the first track info */
|
||||
cmd[7] = 0; /* allocation length */
|
||||
cmd[8] = 2;
|
||||
cmd[8] = MIN_TRANSFER_LEN;
|
||||
|
||||
Verbose("#DVD: querying size of READ TRACK INFORMATION\n");
|
||||
if(SendPacket(dh, cmd, 10, buf, 2, sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 10, buf, MIN_TRANSFER_LEN, sense, DATA_READ)<0)
|
||||
{ FreeAlignedBuffer(ab);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2; /* MMC3: "Disc information length excludes itself" */
|
||||
length_align(&length);
|
||||
|
||||
Verbose("#DVD: size returned is %d\n", length);
|
||||
|
||||
memset(cmd, 0, MAX_CDB_SIZE);
|
||||
@@ -1267,6 +1296,7 @@ static int query_blank(DeviceHandle *dh)
|
||||
}
|
||||
|
||||
length = 4+buf[3];
|
||||
length_align(&length);
|
||||
Verbose("#DVD: size returned is %d\n", length);
|
||||
|
||||
memset(cmd, 0, MAX_CDB_SIZE);
|
||||
@@ -1350,6 +1380,7 @@ static int query_blank(DeviceHandle *dh)
|
||||
}
|
||||
|
||||
length = 4+buf[3];
|
||||
length_align(&length);
|
||||
Verbose("#BD: size returned is %d\n", length);
|
||||
|
||||
memset(cmd, 0, MAX_CDB_SIZE);
|
||||
@@ -1639,9 +1670,9 @@ static int query_copyright(DeviceHandle *dh)
|
||||
cmd[6] = 0; /* First layer */
|
||||
cmd[7] = 1; /* We want copyright info */
|
||||
cmd[8] = 0; /* Allocation length */
|
||||
cmd[9] = 2;
|
||||
cmd[9] = MIN_TRANSFER_LEN;
|
||||
|
||||
if(SendPacket(dh, cmd, 12, buf, 2, &sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 12, buf, MIN_TRANSFER_LEN, &sense, DATA_READ)<0)
|
||||
{ FreeAlignedBuffer(ab);
|
||||
Stop(_("%s\nCould not query dvd structure length for format code 1.\n"),
|
||||
GetSenseString(sense.sense_key, sense.asc, sense.ascq, TRUE));
|
||||
@@ -1650,6 +1681,7 @@ static int query_copyright(DeviceHandle *dh)
|
||||
|
||||
length = buf[0]<<8 | buf[1];
|
||||
length += 2;
|
||||
length_align(&length);
|
||||
|
||||
if(length>4096) /* don't let the drive hack us using a buffer overflow ;-) */
|
||||
{ FreeAlignedBuffer(ab);
|
||||
@@ -1871,7 +1903,7 @@ static unsigned int query_size(DeviceHandle *dh)
|
||||
"READ DVD STRUCTURE: %lld sectors\n\n"),
|
||||
dh->readCapacity+1, dh->userAreaSize+1);
|
||||
|
||||
g_string_append_printf(warning, _("Evaluation of returned medium sizes:\n\n"));
|
||||
g_string_append(warning, _("Evaluation of returned medium sizes:\n\n"));
|
||||
|
||||
/*** Look at READ CAPACITY results */
|
||||
|
||||
@@ -2022,7 +2054,7 @@ gint64 CurrentMediumSize(int get_blank_size)
|
||||
|
||||
/*
|
||||
* Spin up drive.
|
||||
* Most drive give a *beep* about sending the START STOP CDB,
|
||||
* Most drives give a *beep* about sending the START STOP CDB,
|
||||
* so we simply nudge them with reading request until the spin up
|
||||
* time is over. Pathetic ;-)
|
||||
*/
|
||||
@@ -2075,7 +2107,7 @@ void LoadMedium(DeviceHandle *dh, int load)
|
||||
cmd[0] = 0x1b; /* START STOP */
|
||||
cmd[4] = load ? 0x03 : 0x02; /* LOEJ=1; START=load/eject */
|
||||
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &sense, DATA_READ)<0
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &sense, DATA_NONE)<0
|
||||
&& (sense.asc != 0x53 || sense.ascq != 0x02))
|
||||
{
|
||||
PrintLog(_("%s\nCould not load/unload the medium.\n"),
|
||||
@@ -2093,7 +2125,7 @@ void LoadMedium(DeviceHandle *dh, int load)
|
||||
memset(cmd, 0, MAX_CDB_SIZE);
|
||||
cmd[0] = 0x1e; /* PREVENT ALLOW MEDIUM REMOVAL */
|
||||
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &sense, DATA_NONE)<0)
|
||||
PrintLog(_("%s\nCould not unlock the medium.\n"),
|
||||
GetSenseString(sense.sense_key, sense.asc, sense.ascq, TRUE));
|
||||
|
||||
@@ -2103,7 +2135,7 @@ void LoadMedium(DeviceHandle *dh, int load)
|
||||
cmd[0] = 0x1b; /* START STOP */
|
||||
cmd[4] = 0x02; /* LOEJ=1; START=eject */
|
||||
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &sense, DATA_READ)<0)
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &sense, DATA_NONE)<0)
|
||||
PrintLog(_("%s\nCould not load/unload the medium.\n"),
|
||||
GetSenseString(sense.sense_key, sense.asc, sense.ascq, TRUE));
|
||||
}
|
||||
@@ -2121,7 +2153,7 @@ int TestUnitReady(DeviceHandle *dh)
|
||||
memset(cmd, 0, MAX_CDB_SIZE);
|
||||
cmd[0] = 0x00; /* TEST UNIT READY */
|
||||
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &dh->sense, DATA_READ) != -1)
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &dh->sense, DATA_NONE) != -1)
|
||||
return TRUE;
|
||||
|
||||
/*** If no medium present, try closing the tray. */
|
||||
@@ -2139,7 +2171,7 @@ int TestUnitReady(DeviceHandle *dh)
|
||||
memset(cmd, 0, MAX_CDB_SIZE);
|
||||
cmd[0] = 0x00; /* TEST UNIT READY */
|
||||
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &dh->sense, DATA_READ) != -1)
|
||||
if(SendPacket(dh, cmd, 6, NULL, 0, &dh->sense, DATA_NONE) != -1)
|
||||
{ if(Closure->guiMode)
|
||||
SetLabelText(Closure->status, "");
|
||||
return TRUE;
|
||||
|
||||
Reference in New Issue
Block a user