diff options
| author | Søren Schmidt <sos@FreeBSD.org> | 2000-08-11 09:21:36 +0000 |
|---|---|---|
| committer | Søren Schmidt <sos@FreeBSD.org> | 2000-08-11 09:21:36 +0000 |
| commit | 071e6e581e60840feb0f4eec6cb6f12efa778307 (patch) | |
| tree | ad68b79a7fcce62bced2e2ab28265c97b6c72a95 /sys/dev | |
| parent | 37b087a645354d60200c774d51b305b268e41c83 (diff) | |
Notes
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/ata/atapi-cd.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 71c46f3bd319..d36c2d119950 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -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) { |
