From a9dd74ee84294c89e91fc3a7c80de3664b21186c Mon Sep 17 00:00:00 2001 From: mav Date: Tue, 29 Sep 2015 09:09:37 +0000 Subject: [PATCH] Add CD/DVD Capabilities and Mechanical Status Page. This page is obsolete since MMC-4, but still used by some software. --- sys/cam/ctl/ctl.c | 63 +++++++++++++++++++++++++++++++++++++++ sys/cam/ctl/ctl_private.h | 8 +++++ sys/cam/scsi/scsi_cd.h | 31 +++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c index 97147f1cbafc..9181d3e133b2 100644 --- a/sys/cam/ctl/ctl.c +++ b/sys/cam/ctl/ctl.c @@ -354,6 +354,52 @@ const static struct ctl_logical_block_provisioning_page lbp_page_changeable = {{ } }; +const static struct scsi_cddvd_capabilities_page cddvd_page_default = { + /*page_code*/SMS_CDDVD_CAPS_PAGE, + /*page_length*/sizeof(struct scsi_cddvd_capabilities_page) - 2, + /*caps1*/0x3f, + /*caps2*/0x00, + /*caps3*/0xf0, + /*caps4*/0x00, + /*caps5*/0x29, + /*caps6*/0x00, + /*obsolete*/{0, 0}, + /*nvol_levels*/{0, 0}, + /*buffer_size*/{8, 0}, + /*obsolete2*/{0, 0}, + /*reserved*/0, + /*digital*/0, + /*obsolete3*/0, + /*copy_management*/0, + /*reserved2*/0, + /*rotation_control*/0, + /*cur_write_speed*/0, + /*num_speed_descr*/0, +}; + +const static struct scsi_cddvd_capabilities_page cddvd_page_changeable = { + /*page_code*/SMS_CDDVD_CAPS_PAGE, + /*page_length*/sizeof(struct scsi_cddvd_capabilities_page) - 2, + /*caps1*/0, + /*caps2*/0, + /*caps3*/0, + /*caps4*/0, + /*caps5*/0, + /*caps6*/0, + /*obsolete*/{0, 0}, + /*nvol_levels*/{0, 0}, + /*buffer_size*/{0, 0}, + /*obsolete2*/{0, 0}, + /*reserved*/0, + /*digital*/0, + /*obsolete3*/0, + /*copy_management*/0, + /*reserved2*/0, + /*rotation_control*/0, + /*cur_write_speed*/0, + /*num_speed_descr*/0, +}; + SYSCTL_NODE(_kern_cam, OID_AUTO, ctl, CTLFLAG_RD, 0, "CAM Target Layer"); static int worker_threads = -1; SYSCTL_INT(_kern_cam_ctl, OID_AUTO, worker_threads, CTLFLAG_RDTUN, @@ -4119,6 +4165,23 @@ ctl_init_page_index(struct ctl_lun *lun) }} break; } + case SMS_CDDVD_CAPS_PAGE:{ + memcpy(&lun->mode_pages.cddvd_page[CTL_PAGE_DEFAULT], + &cddvd_page_default, + sizeof(cddvd_page_default)); + memcpy(&lun->mode_pages.cddvd_page[ + CTL_PAGE_CHANGEABLE], &cddvd_page_changeable, + sizeof(cddvd_page_changeable)); + memcpy(&lun->mode_pages.cddvd_page[CTL_PAGE_SAVED], + &cddvd_page_default, + sizeof(cddvd_page_default)); + memcpy(&lun->mode_pages.cddvd_page[CTL_PAGE_CURRENT], + &lun->mode_pages.cddvd_page[CTL_PAGE_SAVED], + sizeof(cddvd_page_default)); + page_index->page_data = + (uint8_t *)lun->mode_pages.cddvd_page; + break; + } case SMS_VENDOR_SPECIFIC_PAGE:{ switch (page_index->subpage) { case DBGCNF_SUBPAGE_CODE: { diff --git a/sys/cam/ctl/ctl_private.h b/sys/cam/ctl/ctl_private.h index 63709ab0e041..04fab607e44b 100644 --- a/sys/cam/ctl/ctl_private.h +++ b/sys/cam/ctl/ctl_private.h @@ -40,6 +40,10 @@ #ifndef _CTL_PRIVATE_H_ #define _CTL_PRIVATE_H_ +#include +#include +#include + /* * SCSI vendor and product names. */ @@ -286,6 +290,9 @@ static const struct ctl_page_index page_index_template[] = { {SMS_INFO_EXCEPTIONS_PAGE | SMPH_SPF, 0x02, sizeof(struct ctl_logical_block_provisioning_page), NULL, CTL_PAGE_FLAG_DIRECT, NULL, NULL}, + {SMS_CDDVD_CAPS_PAGE, 0, + sizeof(struct scsi_cddvd_capabilities_page), NULL, + CTL_PAGE_FLAG_CDROM, NULL, NULL}, {SMS_VENDOR_SPECIFIC_PAGE | SMPH_SPF, DBGCNF_SUBPAGE_CODE, sizeof(struct copan_debugconf_subpage), NULL, CTL_PAGE_FLAG_ALL, ctl_debugconf_sp_sense_handler, ctl_debugconf_sp_select_handler}, @@ -303,6 +310,7 @@ struct ctl_mode_pages { struct scsi_control_ext_page control_ext_page[4]; struct scsi_info_exceptions_page ie_page[4]; struct ctl_logical_block_provisioning_page lbp_page[4]; + struct scsi_cddvd_capabilities_page cddvd_page[4]; struct copan_debugconf_subpage debugconf_subpage[4]; struct ctl_page_index index[CTL_NUM_MODE_PAGES]; }; diff --git a/sys/cam/scsi/scsi_cd.h b/sys/cam/scsi/scsi_cd.h index e14140445e6d..cf8baaf7ed78 100644 --- a/sys/cam/scsi/scsi_cd.h +++ b/sys/cam/scsi/scsi_cd.h @@ -783,6 +783,37 @@ struct cd_audio_page #define RIGHT_PORT 1 }; +struct scsi_cddvd_capabilities_page_sd { + uint8_t reserved; + uint8_t rotation_control; + uint8_t write_speed_supported[2]; +}; + +struct scsi_cddvd_capabilities_page { + uint8_t page_code; +#define SMS_CDDVD_CAPS_PAGE 0x2a + uint8_t page_length; + uint8_t caps1; + uint8_t caps2; + uint8_t caps3; + uint8_t caps4; + uint8_t caps5; + uint8_t caps6; + uint8_t obsolete[2]; + uint8_t nvol_levels[2]; + uint8_t buffer_size[2]; + uint8_t obsolete2[2]; + uint8_t reserved; + uint8_t digital; + uint8_t obsolete3; + uint8_t copy_management; + uint8_t reserved2; + uint8_t rotation_control; + uint8_t cur_write_speed; + uint8_t num_speed_descr; + struct scsi_cddvd_capabilities_page_sd speed_descr[]; +}; + union cd_pages { struct cd_audio_page audio;