summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
authorken <ken@FreeBSD.org>1998-09-20 22:48:15 +0000
committerken <ken@FreeBSD.org>1998-09-20 22:48:15 +0000
commitdafd644ddde5252ee054b3eede832f6a805e0bf2 (patch)
treebb1c63a15339ad9ce4b67126bc572b6009444fa0 /sys/cam
parent00428fddff8862c2a884e610cd9d03df7c381c0d (diff)
downloadFreeBSD-src-dafd644ddde5252ee054b3eede832f6a805e0bf2.zip
FreeBSD-src-dafd644ddde5252ee054b3eede832f6a805e0bf2.tar.gz
Some fixes to the CD driver that may fix PR kern/7996. The data direction
flags on some of the operations in the driver weren't quite right. Also, clean up scsi_cd.h, change u_char to u_int8_t. I'm surprised this problem didn't show up sooner. (the code has been in there almost a year and a half) PR: 7996 Reviewed by: ken Submitted (mostly) by: gibbs
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/scsi/scsi_cd.c72
-rw-r--r--sys/cam/scsi/scsi_cd.h183
2 files changed, 134 insertions, 121 deletions
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index 4a0ece7..8cb211b 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: scsi_cd.c,v 1.1 1998/09/15 06:36:34 gibbs Exp $
+ * $Id: scsi_cd.c,v 1.2 1998/09/20 07:17:11 gibbs Exp $
*/
/*
* Portions of this driver taken from the original FreeBSD cd driver.
@@ -2765,7 +2765,7 @@ cdsetmode(struct cam_periph *periph, struct cd_mode_data *data)
cam_fill_csio(csio,
/* retries */ 1,
/* cbfcnp */ cddone,
- /* flags */ CAM_DIR_IN,
+ /* flags */ CAM_DIR_OUT,
/* tag_action */ MSG_SIMPLE_Q_TAG,
/* data_ptr */ (u_int8_t *)data,
/* dxfer_len */ sizeof(*data),
@@ -2799,42 +2799,56 @@ cdsetmode(struct cam_periph *periph, struct cd_mode_data *data)
static int
cdplay(struct cam_periph *periph, u_int32_t blk, u_int32_t len)
{
- struct scsi_play *scsi_cmd;
- struct ccb_scsiio *csio;
+ struct ccb_scsiio *csio;
union ccb *ccb;
int error;
+ u_int8_t cdb_len;
error = 0;
-
ccb = cdgetccb(periph, /* priority */ 1);
-
csio = &ccb->csio;
-
- cam_fill_csio(csio,
- /* retries */ 1,
- /* cbfcnp */ cddone,
- /* flags */ CAM_DIR_IN,
- /* tag_action */ MSG_SIMPLE_Q_TAG,
- /* data_ptr */ NULL,
- /* dxfer_len */ 0,
- /* sense_len */ SSD_FULL_SIZE,
- sizeof(struct scsi_play),
- /* timeout */ 50000);
-
- scsi_cmd = (struct scsi_play *)&csio->cdb_io.cdb_bytes;
- bzero (scsi_cmd, sizeof(*scsi_cmd));
-
- scsi_cmd->op_code = PLAY;
- scsi_ulto4b(blk, (u_int8_t *)scsi_cmd->blk_addr);
- scsi_ulto2b(len, (u_int8_t *)scsi_cmd->xfer_len);
+ /*
+ * Use the smallest possible command to perform the operation.
+ */
+ if ((len & 0xffff0000) == 0) {
+ /*
+ * We can fit in a 10 byte cdb.
+ */
+ struct scsi_play_10 *scsi_cmd;
+
+ scsi_cmd = (struct scsi_play_10 *)&csio->cdb_io.cdb_bytes;
+ bzero (scsi_cmd, sizeof(*scsi_cmd));
+ scsi_cmd->op_code = PLAY_10;
+ scsi_ulto4b(blk, (u_int8_t *)scsi_cmd->blk_addr);
+ scsi_ulto2b(len, (u_int8_t *)scsi_cmd->xfer_len);
+ cdb_len = sizeof(*scsi_cmd);
+ } else {
+ struct scsi_play_12 *scsi_cmd;
+
+ scsi_cmd = (struct scsi_play_12 *)&csio->cdb_io.cdb_bytes;
+ bzero (scsi_cmd, sizeof(*scsi_cmd));
+ scsi_cmd->op_code = PLAY_12;
+ scsi_ulto4b(blk, (u_int8_t *)scsi_cmd->blk_addr);
+ scsi_ulto4b(len, (u_int8_t *)scsi_cmd->xfer_len);
+ cdb_len = sizeof(*scsi_cmd);
+ }
+ cam_fill_csio(csio,
+ /*retries*/2,
+ cddone,
+ /*flags*/CAM_DIR_NONE,
+ MSG_SIMPLE_Q_TAG,
+ /*dataptr*/NULL,
+ /*datalen*/0,
+ /*sense_len*/SSD_FULL_SIZE,
+ cdb_len,
+ /*timeout*/50 * 1000);
error = cdrunccb(ccb, cderror, /*cam_flags*/0,
- /*sense_flags*/SF_RETRY_UA);
+ /*sense_flags*/SF_RETRY_UA);
xpt_release_ccb(ccb);
return(error);
-
}
static int
@@ -2855,7 +2869,7 @@ cdplaymsf(struct cam_periph *periph, u_int32_t startm, u_int32_t starts,
cam_fill_csio(csio,
/* retries */ 1,
/* cbfcnp */ cddone,
- /* flags */ CAM_DIR_IN,
+ /* flags */ CAM_DIR_NONE,
/* tag_action */ MSG_SIMPLE_Q_TAG,
/* data_ptr */ NULL,
/* dxfer_len */ 0,
@@ -2901,7 +2915,7 @@ cdplaytracks(struct cam_periph *periph, u_int32_t strack, u_int32_t sindex,
cam_fill_csio(csio,
/* retries */ 1,
/* cbfcnp */ cddone,
- /* flags */ CAM_DIR_IN,
+ /* flags */ CAM_DIR_NONE,
/* tag_action */ MSG_SIMPLE_Q_TAG,
/* data_ptr */ NULL,
/* dxfer_len */ 0,
@@ -2943,7 +2957,7 @@ cdpause(struct cam_periph *periph, u_int32_t go)
cam_fill_csio(csio,
/* retries */ 1,
/* cbfcnp */ cddone,
- /* flags */ CAM_DIR_IN,
+ /* flags */ CAM_DIR_NONE,
/* tag_action */ MSG_SIMPLE_Q_TAG,
/* data_ptr */ NULL,
/* dxfer_len */ 0,
diff --git a/sys/cam/scsi/scsi_cd.h b/sys/cam/scsi/scsi_cd.h
index 8a76b0a..72ddaee 100644
--- a/sys/cam/scsi/scsi_cd.h
+++ b/sys/cam/scsi/scsi_cd.h
@@ -31,168 +31,167 @@
struct scsi_pause
{
- u_char op_code;
- u_char byte2;
- u_char unused[6];
- u_char resume;
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t unused[6];
+ u_int8_t resume;
+ u_int8_t control;
};
#define PA_PAUSE 1
#define PA_RESUME 0
struct scsi_play_msf
{
- u_char op_code;
- u_char byte2;
- u_char unused;
- u_char start_m;
- u_char start_s;
- u_char start_f;
- u_char end_m;
- u_char end_s;
- u_char end_f;
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t unused;
+ u_int8_t start_m;
+ u_int8_t start_s;
+ u_int8_t start_f;
+ u_int8_t end_m;
+ u_int8_t end_s;
+ u_int8_t end_f;
+ u_int8_t control;
};
struct scsi_play_track
{
- u_char op_code;
- u_char byte2;
- u_char unused[2];
- u_char start_track;
- u_char start_index;
- u_char unused1;
- u_char end_track;
- u_char end_index;
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t unused[2];
+ u_int8_t start_track;
+ u_int8_t start_index;
+ u_int8_t unused1;
+ u_int8_t end_track;
+ u_int8_t end_index;
+ u_int8_t control;
};
-struct scsi_play
+struct scsi_play_10
{
- u_char op_code;
- u_char byte2;
- u_char blk_addr[4];
- u_char unused;
- u_char xfer_len[2];
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t blk_addr[4];
+ u_int8_t unused;
+ u_int8_t xfer_len[2];
+ u_int8_t control;
};
-struct scsi_play_big
+struct scsi_play_12
{
- u_char op_code;
- u_char byte2; /* same as above */
- u_char blk_addr[4];
- u_char xfer_len[4];
- u_char unused;
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2; /* same as above */
+ u_int8_t blk_addr[4];
+ u_int8_t xfer_len[4];
+ u_int8_t unused;
+ u_int8_t control;
};
-struct scsi_play_rel_big
+struct scsi_play_rel_12
{
- u_char op_code;
- u_char byte2; /* same as above */
- u_char blk_addr[4];
- u_char xfer_len[4];
- u_char track;
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2; /* same as above */
+ u_int8_t blk_addr[4];
+ u_int8_t xfer_len[4];
+ u_int8_t track;
+ u_int8_t control;
};
struct scsi_read_header
{
- u_char op_code;
- u_char byte2;
- u_char blk_addr[4];
- u_char unused;
- u_char data_len[2];
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t blk_addr[4];
+ u_int8_t unused;
+ u_int8_t data_len[2];
+ u_int8_t control;
};
struct scsi_read_subchannel
{
- u_char op_code;
- u_char byte1;
- u_char byte2;
+ u_int8_t op_code;
+ u_int8_t byte1;
+ u_int8_t byte2;
#define SRS_SUBQ 0x40
- u_char subchan_format;
- u_char unused[2];
- u_char track;
- u_char data_len[2];
- u_char control;
+ u_int8_t subchan_format;
+ u_int8_t unused[2];
+ u_int8_t track;
+ u_int8_t data_len[2];
+ u_int8_t control;
};
struct scsi_read_toc
{
- u_char op_code;
- u_char byte2;
- u_char unused[4];
- u_char from_track;
- u_char data_len[2];
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t unused[4];
+ u_int8_t from_track;
+ u_int8_t data_len[2];
+ u_int8_t control;
};
;
struct scsi_read_cd_capacity
{
- u_char op_code;
- u_char byte2;
- u_char addr_3; /* Most Significant */
- u_char addr_2;
- u_char addr_1;
- u_char addr_0; /* Least Significant */
- u_char unused[3];
- u_char control;
+ u_int8_t op_code;
+ u_int8_t byte2;
+ u_int8_t addr_3; /* Most Significant */
+ u_int8_t addr_2;
+ u_int8_t addr_1;
+ u_int8_t addr_0; /* Least Significant */
+ u_int8_t unused[3];
+ u_int8_t control;
};
/*
* Opcodes
*/
-
#define READ_CD_CAPACITY 0x25 /* slightly different from disk */
#define READ_SUBCHANNEL 0x42 /* cdrom read Subchannel */
#define READ_TOC 0x43 /* cdrom read TOC */
#define READ_HEADER 0x44 /* cdrom read header */
-#define PLAY 0x45 /* cdrom play 'play audio' mode */
+#define PLAY_10 0x45 /* cdrom play 'play audio' mode */
#define PLAY_MSF 0x47 /* cdrom play Min,Sec,Frames mode */
#define PLAY_TRACK 0x48 /* cdrom play track/index mode */
#define PLAY_TRACK_REL 0x49 /* cdrom play track/index mode */
#define PAUSE 0x4b /* cdrom pause in 'play audio' mode */
-#define PLAY_BIG 0xa5 /* cdrom pause in 'play audio' mode */
+#define PLAY_12 0xa5 /* cdrom pause in 'play audio' mode */
#define PLAY_TRACK_REL_BIG 0xa9 /* cdrom play track/index mode */
struct scsi_read_cd_cap_data
{
- u_char addr_3; /* Most significant */
- u_char addr_2;
- u_char addr_1;
- u_char addr_0; /* Least significant */
- u_char length_3; /* Most significant */
- u_char length_2;
- u_char length_1;
- u_char length_0; /* Least significant */
+ u_int8_t addr_3; /* Most significant */
+ u_int8_t addr_2;
+ u_int8_t addr_1;
+ u_int8_t addr_0; /* Least significant */
+ u_int8_t length_3; /* Most significant */
+ u_int8_t length_2;
+ u_int8_t length_1;
+ u_int8_t length_0; /* Least significant */
};
union cd_pages
{
struct audio_page
{
- u_char page_code;
+ u_int8_t page_code;
#define CD_PAGE_CODE 0x3F
#define AUDIO_PAGE 0x0e
#define CD_PAGE_PS 0x80
- u_char param_len;
- u_char flags;
+ u_int8_t param_len;
+ u_int8_t flags;
#define CD_PA_SOTC 0x02
#define CD_PA_IMMED 0x04
- u_char unused[2];
- u_char format_lba;
+ u_int8_t unused[2];
+ u_int8_t format_lba;
#define CD_PA_FORMAT_LBA 0x0F
#define CD_PA_APR_VALID 0x80
- u_char lb_per_sec[2];
+ u_int8_t lb_per_sec[2];
struct port_control
{
- u_char channels;
+ u_int8_t channels;
#define CHANNEL 0x0F
#define CHANNEL_0 1
#define CHANNEL_1 2
@@ -200,7 +199,7 @@ union cd_pages
#define CHANNEL_3 8
#define LEFT_CHANNEL CHANNEL_0
#define RIGHT_CHANNEL CHANNEL_1
- u_char volume;
+ u_int8_t volume;
} port[4];
#define LEFT_PORT 0
#define RIGHT_PORT 1
OpenPOWER on IntegriCloud