Re: linux kernel error reading end of cd/dvd
On Tue 14 October 2003 12:30, Andy Polyakov wrote:
> Meet the players in the field:
> - block buffer which provides for read-ahead, I/O requests'
> slicing and coalescing;
> - value returned by READ CAPACITY command, hereafter simply READ
> - actual lead-out position;
> Rules of the game (please note that I'm not claiming that I know
> all the rules in detail:-):
> - block buffer rearranges I/O depending on *momentary*
> availability of spare memory, e.g. even if you ask for bs=2k, it
> may coalesce them to e.g. 126KB chunks, or it may break larger
> requests to a number of 4KB ones;
> - no requests are posed beyond the READ CAPACITY;
> - READ CAPACITY coincides with lead-out position most of the
> time, *but not always*;
> - CD lead-out position is documented to be inaccurate [with 75
> blocks inaccuracy?], DVD lead-out position is believed to be
> accurate; - CD lead-out is preceded by few unaccesible blocks
> (unless disk is recorded in DAO mode?), lead-out itself is
Thanks for the explanation! That sheds some more light on the case.
I've dug up the ECMA-130 spec (== Yellow Book for all practical
purposes) from www.ecma-international.org and after a bit of
searching I found this (from section 126.96.36.199):
"If set to (A2) the P-MIN, P-SEC and P-FRAC fields specify the
beginning of the Lead-out Track, thus the address of the first
Section of the Lead-out Track."
The TOC basically consists of a list of records, each of which
specifies a track number and a start address in min:sec:frac format
(with a fraction being 1/75th of a second). The last element in the
list describes the start of the Lead-out, as quoted above.
Now the interesting bit is that this is actually section-accurate,
and that each section holds one block (ie 2k) of data. Also note
that the last readable block before the Lead-out is at
address_of_lead_out - 1. At any rate, unless I missed something,
the amount of readable blocks is actually stored on the CD, and the
number is accurate.
Okay, so that's how the information is stored on the disc
physically. A bit of Googling got me to
http://www.t10.org/ftp/t10/document.01/01-246r0.pdf, which states
that the READ CAPACITY SCSI bus command returns a logical block
address (LBA) and a block length in bytes. The LBA is the address
of the last logical block on the disc, so the number of blocks in
total before the Lead-out is actually LBA + 1.
pc.c = GPCMD_READ_CDVD_CAPACITY;
pc.buffer = (char *)&capbuf;
pc.buflen = sizeof(capbuf);
stat = cdrom_queue_packet_command(drive, &pc);
if (stat == 0)
*capacity = 1 + be32_to_cpu(capbuf.lba);
So it seems that as long as the drive gives the correct LBA number
(should be P-MIN * 60 * 75 + P-SEC * 75 + P-FRAC - 1 with values as
above), ide-cd will report the correct media size.
Readcd from cdrecord uses the exact same way to get the capacity
from the drive, and displays the amount of blocks correctly.
According to it, my Nero CD has 169825 blocks.
Unfortunately the -fulltoc option of readcd isn't implemented, so I
can't verify that this matches the information on the disc. Does
anyone know of another way to get to the raw TOC data on a CD?
Now, as I said ide-cd.c reads the amount of blocks the same way, so
it will get the same value. I'm not sure what happens with this
value though, presumably it ends up with the block driver as Andy
described, but I haven't found out how yet.
Looking at the Linux SCSI stuff, I found this in drivers/scsi/sr.c:
* The SCSI specification allows for the value returned
* by READ CAPACITY to be up to 75 2K sectors past the
* last readable block. Therefore, if we hit a medium
* error within the last 75 2K sectors, we decrease the
* saved size value.
if ((error_sector >> 1) < sr_sizes[device_nr] &&
scsi_CDs[device_nr].capacity - error_sector < 4 *75)
sr_sizes[device_nr] = error_sector >> 1;
So it seems that you were correct about that.
> Relevant question is when READ CAPACITY is not equal to lead-out
> offset? I don't know about CD, but in DVD case most units would
> report full media capacity for READ CAPACITY under following
Well, it looks like that's up to the drive's firmware. READ CAPACITY
is pretty much useless, since it's allowed to give wrong
> case. One can wonder if the common block buffer could do better
> job spotting the last addressible sector? Well, yes, but do keep
> in mind that it's a *common* block buffer, which is not aware of
> CD technicalities... So that I'd say that it's perfectly
> legitimate to advice as following. If you really have to checksum
> the whole image, then make sure to bypass the block buffer *and*
> provide sane block count value. A.
Well, it seems to me that the block driver gets the capacity from
the underlying device driver. So if that driver gives the correct
capacity to the block layer, things should actually work fine. The
question is how to get the device driver to give the correct
capacity, if READ CAPACITY doesn't work well enough.
I can see two options:
1) Modify ide-cd.c and sr.c to use READ CAPACITY, and then try to
read the 75 2k sectors before that. Catch the IO error, and adjust
the capacity based on the number of succesfully read sectors.
2) Modify ide-cd.c and sr.c to read the TOC and get the capacity
directly from the disc, thus completely circumventing the READ
GPG public key: http://home.student.utwente.nl/l.e.veen/lourens.key