Skip site navigation (1)Skip section navigation (2)
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>