summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Tettamanti <kronos@kronoz.cjb.net>2004-12-18 01:17:44 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-12-18 01:17:44 -0800
commit47227f5db3c418fd97c06bd29e670c0da79d0030 (patch)
tree4ed78903cf8b58d899f2e64bedffc4ced448faa6
parentd2dc1db05062089d6cef496a6c214a3825c3024d (diff)
[PATCH] ide-cd: Unable to read multisession DVDs
cdrom_read_toc (ide-cd.c) always reads the TOC using MSF format. If the last session of the disk starts beyond block 1152000 (LBA) there's an overflow in the MSF format and kernel complains: Unable to identify CD-ROM format. I reported this bug a while ago (see bug #1930 on bugzilla) and Andy Polyakov tracked it down. Read the multi-session TOC in LBA format in order to avoid an overflow in MSF format when the last session starts beyond block 1152000 (LBA). Signed-off-by: Luca Tettamanti <kronos@kronoz.cjb.net> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/ide/ide-cd.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 63551e19e514..2dae7b293314 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -2359,25 +2359,31 @@ static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
/* Read the multisession information. */
if (toc->hdr.first_track != CDROM_LEADOUT) {
/* Read the multisession information. */
- stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
+ stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
sizeof(ms_tmp), sense);
if (stat) return stat;
+
+ toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
} else {
- ms_tmp.ent.addr.msf.minute = 0;
- ms_tmp.ent.addr.msf.second = 2;
- ms_tmp.ent.addr.msf.frame = 0;
ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
+ toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
}
#if ! STANDARD_ATAPI
- if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd)
+ if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) {
+ /* Re-read multisession information using MSF format */
+ stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
+ sizeof(ms_tmp), sense);
+ if (stat)
+ return stat;
+
msf_from_bcd (&ms_tmp.ent.addr.msf);
+ toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
+ ms_tmp.ent.addr.msf.second,
+ ms_tmp.ent.addr.msf.frame);
+ }
#endif /* not STANDARD_ATAPI */
- toc->last_session_lba = msf_to_lba (ms_tmp.ent.addr.msf.minute,
- ms_tmp.ent.addr.msf.second,
- ms_tmp.ent.addr.msf.frame);
-
toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
/* Now try to get the total cdrom capacity. */