diff options
Diffstat (limited to 'sys/scsi/cd.c')
-rw-r--r-- | sys/scsi/cd.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index f643c37..00df2f7 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -14,7 +14,7 @@ * * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 * - * $Id: cd.c,v 1.81 1997/03/24 11:24:54 bde Exp $ + * $Id: cd.c,v 1.82 1997/04/02 09:05:38 jmg Exp $ */ #include "opt_bounce.h" @@ -834,6 +834,63 @@ cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p, error = copyout(data.entries, te->data, len); } break; + case CDIOREADTOCENTRY: + { + struct { + struct ioc_toc_header header; + struct cd_toc_entry entry; + } data; + struct ioc_read_toc_single_entry *te = + (struct ioc_read_toc_single_entry *) addr; + struct ioc_toc_header *th; + u_int32_t track; + + if (te->address_format != CD_MSF_FORMAT + && te->address_format != CD_LBA_FORMAT) { + error = EINVAL; + break; + } + + th = &data.header; + error = cd_read_toc(unit, 0, 0, + (struct cd_toc_entry *)th, sizeof (*th)); + if (error) + break; + + if (sc_link->quirks & CD_Q_BCD_TRACKS) { + /* we are going to have to convert the BCD + * encoding on the cd to what is expected + */ + th->starting_track = + bcd2bin(th->starting_track); + th->ending_track = bcd2bin(th->ending_track); + } + + track = te->track; + if (track == 0) + track = th->starting_track; + else if (track == LEADOUT) + /* OK */; + else if (track < th->starting_track || + track > th->ending_track + 1) { + error = EINVAL; + break; + } + + error = cd_read_toc(unit, te->address_format, + track, + (struct cd_toc_entry *)&data, + sizeof data); + if (error) + break; + + if (sc_link->quirks & CD_Q_BCD_TRACKS) + data.entry.track = bcd2bin(data.entry.track); + + bcopy(&data.entry, &te->entry, + sizeof(struct cd_toc_entry)); + } + break; case CDIOCSETPATCH: { struct ioc_patch *arg = (struct ioc_patch *) addr; |