From 75d0724769a209b767b454fc312e13621a2601cf Mon Sep 17 00:00:00 2001 From: mav Date: Thu, 12 Jan 2012 15:02:51 +0000 Subject: [PATCH] MFC r228808, r228847, 229395: r228808, r228847: Make cd driver to handle Audio CDs, reporting their 2352 bytes sectors to GEOM and using READ CD command for reading data, same as acd driver does. Audio CDs identified by checking respective bit of the control field of the first track in TOC. 229395: Add support for CDRIOCGETBLOCKSIZE and CDRIOCSETBLOCKSIZE IOCTLs to control sector size same as acd driver does. Together with r228808 and r228847 this allows existing multimedia/vlc to play Audio CDs via CAM cd driver. PR: ports/162190 Sponsored by: iXsystems, Inc. git-svn-id: svn://svn.freebsd.org/base/stable/8@230015 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/cam/scsi/scsi_all.h | 1 + sys/cam/scsi/scsi_cd.c | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/sys/cam/scsi/scsi_all.h b/sys/cam/scsi/scsi_all.h index cddf4f9fd..7a44aa198 100644 --- a/sys/cam/scsi/scsi_all.h +++ b/sys/cam/scsi/scsi_all.h @@ -611,6 +611,7 @@ struct ata_pass_16 { #define READ_12 0xA8 #define WRITE_12 0xAA #define READ_ELEMENT_STATUS 0xB8 +#define READ_CD 0xBE /* Maintenance In Service Action Codes */ #define REPORT_IDENTIFYING_INFRMATION 0x05 diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index d9f80b87f..ca9b240eb 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -1475,6 +1475,14 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb) /* dxfer_len */ bp->bio_bcount, /* sense_len */ SSD_FULL_SIZE, /* timeout */ 30000); + /* Use READ CD command for audio tracks. */ + if (softc->params.blksize == 2352) { + start_ccb->csio.cdb_io.cdb_bytes[0] = READ_CD; + start_ccb->csio.cdb_io.cdb_bytes[9] = 0xf8; + start_ccb->csio.cdb_io.cdb_bytes[10] = 0; + start_ccb->csio.cdb_io.cdb_bytes[11] = 0; + start_ccb->csio.cdb_len = 12; + } start_ccb->ccb_h.ccb_state = CD_CCB_BUFFER_IO; @@ -2668,6 +2676,16 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td) error = cdsetspeed(periph, CDR_MAX_SPEED, *(u_int32_t *)addr); cam_periph_unlock(periph); break; + case CDRIOCGETBLOCKSIZE: + *(int *)addr = softc->params.blksize; + break; + case CDRIOCSETBLOCKSIZE: + if (*(int *)addr <= 0) { + error = EINVAL; + break; + } + softc->disk->d_sectorsize = softc->params.blksize = *(int *)addr; + break; case DVDIOCSENDKEY: case DVDIOCREPORTKEY: { struct dvd_authinfo *authinfo; @@ -2871,6 +2889,13 @@ cdcheckmedia(struct cam_periph *periph) softc->flags |= CD_FLAG_VALID_TOC; + /* If the first track is audio, correct sector size. */ + if ((softc->toc.entries[0].control & 4) == 0) { + softc->disk->d_sectorsize = softc->params.blksize = 2352; + softc->disk->d_mediasize = + (off_t)softc->params.blksize * softc->params.disksize; + } + bailout: /* -- 2.45.0