diff options
author | ken <ken@FreeBSD.org> | 1998-09-20 22:48:15 +0000 |
---|---|---|
committer | ken <ken@FreeBSD.org> | 1998-09-20 22:48:15 +0000 |
commit | dafd644ddde5252ee054b3eede832f6a805e0bf2 (patch) | |
tree | bb1c63a15339ad9ce4b67126bc572b6009444fa0 /sys/cam | |
parent | 00428fddff8862c2a884e610cd9d03df7c381c0d (diff) | |
download | FreeBSD-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.c | 72 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_cd.h | 183 |
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 |