1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-04 09:09:56 +00:00

Add support for accessing individual tracks on a CD.

This is done by misusing the device minor a bit to encode the
track no there.

So to read track #4 just use /dev/acdNt4 where N is the device #.

The driver no automatically sets the blocksize (sectorsize) to
what the track is set to in the TOC.

This has the nice effect that you can now rip audioi tracks
by simply doing:

dd if=/dev/acdNt2 of=audiotrack2.raw bs=2352

it cant be much simpler than that :)

NOTE: the original acdNa & acdNc device still work as usual,
except the blocksize is set according to track0.
This commit is contained in:
Søren Schmidt 2000-08-11 09:21:36 +00:00
parent 37b087a645
commit 071e6e581e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64530

View File

@ -483,9 +483,17 @@ msf2lba(u_int8_t m, u_int8_t s, u_int8_t f)
static int
acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
struct acd_softc *cdp = dev->si_drv1;
struct acd_softc *cdp;
int track = (dev->si_udev & 0x00ff0000) >> 16;
if (!cdp)
if (track) {
dev_t dev1 = makedev(major(dev), (dev->si_udev & 0xff0000ff));
if (track < ((struct acd_softc *)(dev1->si_drv1))->toc.hdr.ending_track)
dev->si_drv1 = dev1->si_drv1;
}
if (!(cdp = dev->si_drv1))
return ENXIO;
if (flags & FWRITE) {
@ -513,6 +521,9 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
struct acd_softc *cdp = dev->si_drv1;
if (!cdp)
return ENXIO;
if (count_dev(dev) == 1) {
if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
acd_select_slot(cdp);
@ -530,6 +541,9 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
struct acd_softc *cdp = dev->si_drv1;
int32_t error = 0;
if (!cdp)
return ENXIO;
if (cdp->changer_info && cdp->slot != cdp->changer_info->current_slot) {
acd_select_slot(cdp);
tsleep(&cdp->changer_info, PRIBIO, "acdctl", 0);
@ -1079,6 +1093,7 @@ acd_start(struct atapi_softc *atp)
struct bio *bp = bioq_first(&cdp->bio_queue);
u_int32_t lba, count;
int8_t ccb[16];
int track, blocksize;
if (cdp->changer_info) {
int i;
@ -1111,8 +1126,18 @@ acd_start(struct atapi_softc *atp)
}
bzero(ccb, sizeof(ccb));
count = (bp->bio_bcount + (cdp->block_size - 1)) / cdp->block_size;
lba = bp->bio_offset / cdp->block_size;
track = ((bp->bio_dev->si_udev & 0x00ff0000) >> 16) - 1;
if (track) {
lba += ntohl(cdp->toc.tab[track].addr.lba);
blocksize = (cdp->toc.tab[track].control & 4) ? 2048 : 2352;
}
else
blocksize = cdp->block_size;
count = (bp->bio_bcount + (blocksize - 1)) / blocksize;
if (bp->bio_cmd == BIO_READ) {
/* if transfer goes beyond EOM adjust it to be within limits */
@ -1124,7 +1149,7 @@ acd_start(struct atapi_softc *atp)
return;
}
}
if (cdp->block_size == 2048)
if (blocksize == 2048)
ccb[0] = ATAPI_READ_BIG;
else {
ccb[0] = ATAPI_READ_CD;
@ -1144,7 +1169,7 @@ acd_start(struct atapi_softc *atp)
devstat_start_transaction(cdp->stats);
atapi_queue_cmd(cdp->atp, ccb, bp->bio_data, count * cdp->block_size,
atapi_queue_cmd(cdp->atp, ccb, bp->bio_data, count * blocksize,
bp->bio_cmd == BIO_READ ? ATPR_F_READ : 0, 30, acd_done,bp);
}
@ -1215,6 +1240,7 @@ acd_read_toc(struct acd_softc *cdp)
cdp->info.volsize = ntohl(cdp->info.volsize);
cdp->info.blksize = ntohl(cdp->info.blksize);
cdp->block_size = (cdp->toc.tab[0].control & 4) ? 2048 : 2352;
#ifdef ACD_DEBUG
if (cdp->info.volsize && cdp->toc.hdr.ending_track) {