Date: Sun, 7 Apr 2002 14:36:44 +0200 (CEST) From: Philipp Mergenthaler <philipp.mergenthaler@stud.uni-karlsruhe.de> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/36845: Add ioctls CDRIOCREADSPEED/WRITESPEED to the scsi cd driver Message-ID: <200204071236.g37CaiN0000964@i609a.hadiko.de>
next in thread | raw e-mail | index | archive | help
>Number: 36845
>Category: kern
>Synopsis: Add ioctls CDRIOCREADSPEED/WRITESPEED to the scsi cd driver
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sun Apr 07 05:40:02 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Philipp Mergenthaler
>Release: FreeBSD 5.0-CURRENT i386
>Organization:
University of Karlsruhe
>Environment:
System: FreeBSD i609a.hadiko.de 5.0-CURRENT FreeBSD 5.0-CURRENT #528: Sun Apr 7 11:36:14 CEST 2002 p@i609a.hadiko.de:/usr/src/sys/i386/compile/I609 i386
>Description:
This patch adds the ioctls CDRIOCREADSPEED and CDRIOCWRITESPEED to the
scsi driver, which allow to set the drive's speed.
>How-To-Repeat:
To test this, you may want to use the patch to cdcontrol from
PR kern/35512.
To test whether your drive offers this capability, use
camcontrol cmd cd0 -v -c 'bb 0 v:i2 0:i2 0 0 0 0 0 0' 2000
where the last number (here: 2000) is the speed in kB/s.
(But apparently there are drives which have a vendor specific command
for this and for which this patch may not work.)
>Fix:
Index: sys/cam/scsi/scsi_cd.c
===================================================================
RCS file: /ncvs/src/sys/cam/scsi/scsi_cd.c,v
retrieving revision 1.58
diff -u -r1.58 scsi_cd.c
--- sys/cam/scsi/scsi_cd.c 22 Feb 2002 09:18:43 -0000 1.58
+++ sys/cam/scsi/scsi_cd.c 6 Apr 2002 19:18:23 -0000
@@ -56,6 +56,7 @@
#include <sys/disk.h>
#include <sys/malloc.h>
#include <sys/cdio.h>
+#include <sys/cdrio.h>
#include <sys/dvdio.h>
#include <sys/devicestat.h>
#include <sys/sysctl.h>
@@ -231,6 +232,8 @@
static int cdpause(struct cam_periph *periph, u_int32_t go);
static int cdstopunit(struct cam_periph *periph, u_int32_t eject);
static int cdstartunit(struct cam_periph *periph);
+static int cdsetspeed(struct cam_periph *periph,
+ u_int16_t rdspeed, u_int16_t wrspeed);
static int cdreportkey(struct cam_periph *periph,
struct dvd_authinfo *authinfo);
static int cdsendkey(struct cam_periph *periph,
@@ -2427,6 +2430,12 @@
/* return (cd_reset(periph)); */
error = ENOTTY;
break;
+ case CDRIOCREADSPEED:
+ error = cdsetspeed(periph, *(u_int16_t *)addr, -1);
+ break;
+ case CDRIOCWRITESPEED:
+ error = cdsetspeed(periph, -1, *(u_int16_t *)addr);
+ break;
case DVDIOCSENDKEY:
case DVDIOCREPORTKEY: {
struct dvd_authinfo *authinfo;
@@ -3066,6 +3075,48 @@
/* immediate */ FALSE,
/* sense_len */ SSD_FULL_SIZE,
/* timeout */ 50000);
+
+ error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO,
+ /*sense_flags*/SF_RETRY_UA);
+
+ xpt_release_ccb(ccb);
+
+ return(error);
+}
+
+static int
+cdsetspeed(struct cam_periph *periph, u_int16_t rdspeed, u_int16_t wrspeed)
+{
+ struct scsi_set_speed *scsi_cmd;
+ struct ccb_scsiio *csio;
+ union ccb *ccb;
+ int error;
+
+ error = 0;
+
+ ccb = cdgetccb(periph, /* priority */ 1);
+
+ csio = &ccb->csio;
+
+ cam_fill_csio(csio,
+ /* retries */ 1,
+ /* cbfcnp */ cddone,
+ /* flags */ CAM_DIR_NONE,
+ /* tag_action */ MSG_SIMPLE_Q_TAG,
+ /* data_ptr */ NULL,
+ /* dxfer_len */ 0,
+ /* sense_len */ SSD_FULL_SIZE,
+ sizeof(struct scsi_set_speed),
+ /* timeout */ 50000);
+
+ scsi_cmd = (struct scsi_set_speed *)&csio->cdb_io.cdb_bytes;
+ bzero (scsi_cmd, sizeof(*scsi_cmd));
+
+ scsi_cmd->op_code = SET_CD_SPEED;
+ scsi_cmd->readspeed[0]=rdspeed >> 8 & 0xff;
+ scsi_cmd->readspeed[1]=rdspeed & 0xff;
+ scsi_cmd->writespeed[0]=wrspeed >> 8 & 0xff;
+ scsi_cmd->writespeed[1]=wrspeed & 0xff;
error = cdrunccb(ccb, cderror, /*cam_flags*/CAM_RETRY_SELTO,
/*sense_flags*/SF_RETRY_UA);
Index: sys/cam/scsi/scsi_cd.h
===================================================================
RCS file: /ncvs/src/sys/cam/scsi/scsi_cd.h,v
retrieving revision 1.5
diff -u -r1.5 scsi_cd.h
--- sys/cam/scsi/scsi_cd.h 10 Feb 2002 21:36:13 -0000 1.5
+++ sys/cam/scsi/scsi_cd.h 7 Apr 2002 09:26:29 -0000
@@ -169,6 +169,16 @@
u_int8_t control;
};
+struct scsi_set_speed
+{
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t readspeed[2];
+ u_int8_t writespeed[2];
+ u_int8_t unused[5];
+ u_int8_t control;
+};
+
struct scsi_report_key
{
u_int8_t opcode;
@@ -251,6 +261,7 @@
#define PLAY_12 0xa5 /* cdrom pause in 'play audio' mode */
#define PLAY_TRACK_REL_BIG 0xa9 /* cdrom play track/index mode */
#define READ_DVD_STRUCTURE 0xad /* read dvd structure */
+#define SET_CD_SPEED 0xbb /* set c/dvd speed */
struct scsi_report_key_data_header
{
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200204071236.g37CaiN0000964>
