diff options
| author | Luca Tettamanti <kronos@kronoz.cjb.net> | 2004-12-18 01:17:44 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-12-18 01:17:44 -0800 |
| commit | 47227f5db3c418fd97c06bd29e670c0da79d0030 (patch) | |
| tree | 4ed78903cf8b58d899f2e64bedffc4ced448faa6 | |
| parent | d2dc1db05062089d6cef496a6c214a3825c3024d (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.c | 24 |
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. */ |
