Make it possible to override the number of retries for the CD media.

When trying to read scratched or damaged CDs and DVDs, the default
mechanism is sub-optimal.  Programs like ddrescue do much better if
you turn off retries entirely, since their algorithms are designed
scan big areas fast, then winnow the areas down.  Turning off retries
speeds these programs up by as much as 20x, since the drive is able to
'stream past' many small errors...

The sysctl/tunable kern.cam.cd.retry_count controls this.  That
defaults to '4' (for a total of 5 attempts).  Setting to 0 turns off
all retry attempts.

Reviewed by:	scottl@
This commit is contained in:
Warner Losh 2009-01-08 00:45:47 +00:00
parent 5f82a460f8
commit 8550170477
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=186882

View File

@ -292,6 +292,9 @@ static struct periph_driver cddriver =
PERIPHDRIVER_DECLARE(cd, cddriver);
#ifndef CD_DEFAULT_RETRY
#define CD_DEFAULT_RETRY 4
#endif
#ifndef CHANGER_MIN_BUSY_SECONDS
#define CHANGER_MIN_BUSY_SECONDS 5
#endif
@ -299,11 +302,15 @@ PERIPHDRIVER_DECLARE(cd, cddriver);
#define CHANGER_MAX_BUSY_SECONDS 15
#endif
static int cd_retry_count = CD_DEFAULT_RETRY;
static int changer_min_busy_seconds = CHANGER_MIN_BUSY_SECONDS;
static int changer_max_busy_seconds = CHANGER_MAX_BUSY_SECONDS;
SYSCTL_NODE(_kern_cam, OID_AUTO, cd, CTLFLAG_RD, 0, "CAM CDROM driver");
SYSCTL_NODE(_kern_cam_cd, OID_AUTO, changer, CTLFLAG_RD, 0, "CD Changer");
SYSCTL_INT(_kern_cam_cd, OID_AUTO, retry_count, CTLFLAG_RW,
&cd_retry_count, 0, "Normal I/O retry count");
TUNABLE_INT("kern.cam.cd.retry_count", &cd_retry_count);
SYSCTL_INT(_kern_cam_cd_changer, OID_AUTO, min_busy_seconds, CTLFLAG_RW,
&changer_min_busy_seconds, 0, "Minimum changer scheduling quantum");
TUNABLE_INT("kern.cam.cd.changer.min_busy_seconds", &changer_min_busy_seconds);
@ -1454,7 +1461,7 @@ cdstart(struct cam_periph *periph, union ccb *start_ccb)
devstat_start_transaction_bio(softc->disk->d_devstat, bp);
scsi_read_write(&start_ccb->csio,
/*retries*/4,
/*retries*/cd_retry_count,
/* cbfcnp */ cddone,
MSG_SIMPLE_Q_TAG,
/* read */bp->bio_cmd == BIO_READ,