Deleted Added
full compact
ctl.c (288262) ctl.c (288310)
1/*-
2 * Copyright (c) 2003-2009 Silicon Graphics International Corp.
3 * Copyright (c) 2012 The FreeBSD Foundation
4 * Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

--- 29 unchanged lines hidden (view full) ---

38 * CAM Target Layer, a SCSI device emulation subsystem.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42
43#define _CTL_C
44
45#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2003-2009 Silicon Graphics International Corp.
3 * Copyright (c) 2012 The FreeBSD Foundation
4 * Copyright (c) 2015 Alexander Motin <mav@FreeBSD.org>
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Edward Tomasz Napierala
8 * under sponsorship from the FreeBSD Foundation.

--- 29 unchanged lines hidden (view full) ---

38 * CAM Target Layer, a SCSI device emulation subsystem.
39 *
40 * Author: Ken Merry <ken@FreeBSD.org>
41 */
42
43#define _CTL_C
44
45#include <sys/cdefs.h>
46__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 288262 2015-09-26 12:53:55Z mav $");
46__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 288310 2015-09-27 13:47:28Z mav $");
47
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/ctype.h>
51#include <sys/kernel.h>
52#include <sys/types.h>
53#include <sys/kthread.h>
54#include <sys/bio.h>

--- 9 unchanged lines hidden (view full) ---

64#include <sys/sbuf.h>
65#include <sys/smp.h>
66#include <sys/endian.h>
67#include <sys/sysctl.h>
68#include <vm/uma.h>
69
70#include <cam/cam.h>
71#include <cam/scsi/scsi_all.h>
47
48#include <sys/param.h>
49#include <sys/systm.h>
50#include <sys/ctype.h>
51#include <sys/kernel.h>
52#include <sys/types.h>
53#include <sys/kthread.h>
54#include <sys/bio.h>

--- 9 unchanged lines hidden (view full) ---

64#include <sys/sbuf.h>
65#include <sys/smp.h>
66#include <sys/endian.h>
67#include <sys/sysctl.h>
68#include <vm/uma.h>
69
70#include <cam/cam.h>
71#include <cam/scsi/scsi_all.h>
72#include <cam/scsi/scsi_cd.h>
72#include <cam/scsi/scsi_da.h>
73#include <cam/ctl/ctl_io.h>
74#include <cam/ctl/ctl.h>
75#include <cam/ctl/ctl_frontend.h>
76#include <cam/ctl/ctl_util.h>
77#include <cam/ctl/ctl_backend.h>
78#include <cam/ctl/ctl_ioctl.h>
79#include <cam/ctl/ctl_ha.h>

--- 3734 unchanged lines hidden (view full) ---

3814 uint64_t ival;
3815
3816 memcpy(&lun->mode_pages.index, page_index_template,
3817 sizeof(page_index_template));
3818
3819 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
3820
3821 page_index = &lun->mode_pages.index[i];
73#include <cam/scsi/scsi_da.h>
74#include <cam/ctl/ctl_io.h>
75#include <cam/ctl/ctl.h>
76#include <cam/ctl/ctl_frontend.h>
77#include <cam/ctl/ctl_util.h>
78#include <cam/ctl/ctl_backend.h>
79#include <cam/ctl/ctl_ioctl.h>
80#include <cam/ctl/ctl_ha.h>

--- 3734 unchanged lines hidden (view full) ---

3815 uint64_t ival;
3816
3817 memcpy(&lun->mode_pages.index, page_index_template,
3818 sizeof(page_index_template));
3819
3820 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
3821
3822 page_index = &lun->mode_pages.index[i];
3822 if (lun->be_lun->lun_type != T_DIRECT &&
3823 (page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
3823 if (lun->be_lun->lun_type == T_DIRECT &&
3824 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
3824 continue;
3825 continue;
3826 if (lun->be_lun->lun_type == T_PROCESSOR &&
3827 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
3828 continue;
3829 if (lun->be_lun->lun_type == T_CDROM &&
3830 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
3831 continue;
3825
3826 switch (page_index->page_code & SMPH_PC_MASK) {
3827 case SMS_RW_ERROR_RECOVERY_PAGE: {
3828 if (page_index->subpage != SMS_SUBPAGE_PAGE_0)
3829 panic("subpage is incorrect!");
3830 memcpy(&lun->mode_pages.rw_er_page[CTL_PAGE_CURRENT],
3831 &rw_er_page_default,
3832 sizeof(rw_er_page_default));

--- 367 unchanged lines hidden (view full) ---

4200
4201 memcpy(&lun->log_pages.index, log_page_index_template,
4202 sizeof(log_page_index_template));
4203
4204 prev = -1;
4205 for (i = 0, j = 0, k = 0; i < CTL_NUM_LOG_PAGES; i++) {
4206
4207 page_index = &lun->log_pages.index[i];
3832
3833 switch (page_index->page_code & SMPH_PC_MASK) {
3834 case SMS_RW_ERROR_RECOVERY_PAGE: {
3835 if (page_index->subpage != SMS_SUBPAGE_PAGE_0)
3836 panic("subpage is incorrect!");
3837 memcpy(&lun->mode_pages.rw_er_page[CTL_PAGE_CURRENT],
3838 &rw_er_page_default,
3839 sizeof(rw_er_page_default));

--- 367 unchanged lines hidden (view full) ---

4207
4208 memcpy(&lun->log_pages.index, log_page_index_template,
4209 sizeof(log_page_index_template));
4210
4211 prev = -1;
4212 for (i = 0, j = 0, k = 0; i < CTL_NUM_LOG_PAGES; i++) {
4213
4214 page_index = &lun->log_pages.index[i];
4208 if (lun->be_lun->lun_type != T_DIRECT &&
4209 (page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
4215 if (lun->be_lun->lun_type == T_DIRECT &&
4216 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
4210 continue;
4217 continue;
4218 if (lun->be_lun->lun_type == T_PROCESSOR &&
4219 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
4220 continue;
4221 if (lun->be_lun->lun_type == T_CDROM &&
4222 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
4223 continue;
4211
4212 if (page_index->page_code == SLS_LOGICAL_BLOCK_PROVISIONING &&
4213 lun->backend->lun_attr == NULL)
4214 continue;
4215
4216 if (page_index->page_code != prev) {
4217 lun->log_pages.pages_page[j] = page_index->page_code;
4218 prev = page_index->page_code;

--- 58 unchanged lines hidden (view full) ---

4277 */
4278static int
4279ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
4280 struct ctl_be_lun *const be_lun)
4281{
4282 struct ctl_lun *nlun, *lun;
4283 struct scsi_vpd_id_descriptor *desc;
4284 struct scsi_vpd_id_t10 *t10id;
4224
4225 if (page_index->page_code == SLS_LOGICAL_BLOCK_PROVISIONING &&
4226 lun->backend->lun_attr == NULL)
4227 continue;
4228
4229 if (page_index->page_code != prev) {
4230 lun->log_pages.pages_page[j] = page_index->page_code;
4231 prev = page_index->page_code;

--- 58 unchanged lines hidden (view full) ---

4290 */
4291static int
4292ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
4293 struct ctl_be_lun *const be_lun)
4294{
4295 struct ctl_lun *nlun, *lun;
4296 struct scsi_vpd_id_descriptor *desc;
4297 struct scsi_vpd_id_t10 *t10id;
4285 const char *eui, *naa, *scsiname, *vendor;
4298 const char *eui, *naa, *scsiname, *vendor, *value;
4286 int lun_number, i, lun_malloced;
4287 int devidlen, idlen1, idlen2 = 0, len;
4288
4289 if (be_lun == NULL)
4290 return (EINVAL);
4291
4292 /*
4293 * We currently only support Direct Access or Processor LUN types.
4294 */
4295 switch (be_lun->lun_type) {
4296 case T_DIRECT:
4299 int lun_number, i, lun_malloced;
4300 int devidlen, idlen1, idlen2 = 0, len;
4301
4302 if (be_lun == NULL)
4303 return (EINVAL);
4304
4305 /*
4306 * We currently only support Direct Access or Processor LUN types.
4307 */
4308 switch (be_lun->lun_type) {
4309 case T_DIRECT:
4297 break;
4298 case T_PROCESSOR:
4310 case T_PROCESSOR:
4311 case T_CDROM:
4299 break;
4300 case T_SEQUENTIAL:
4301 case T_CHANGER:
4302 default:
4303 be_lun->lun_config_status(be_lun->be_lun,
4304 CTL_LUN_CONFIG_FAILURE);
4305 break;
4306 }

--- 136 unchanged lines hidden (view full) ---

4443 lun->flags |= CTL_LUN_STOPPED;
4444
4445 if (be_lun->flags & CTL_LUN_FLAG_INOPERABLE)
4446 lun->flags |= CTL_LUN_INOPERABLE;
4447
4448 if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
4449 lun->flags |= CTL_LUN_PRIMARY_SC;
4450
4312 break;
4313 case T_SEQUENTIAL:
4314 case T_CHANGER:
4315 default:
4316 be_lun->lun_config_status(be_lun->be_lun,
4317 CTL_LUN_CONFIG_FAILURE);
4318 break;
4319 }

--- 136 unchanged lines hidden (view full) ---

4456 lun->flags |= CTL_LUN_STOPPED;
4457
4458 if (be_lun->flags & CTL_LUN_FLAG_INOPERABLE)
4459 lun->flags |= CTL_LUN_INOPERABLE;
4460
4461 if (be_lun->flags & CTL_LUN_FLAG_PRIMARY)
4462 lun->flags |= CTL_LUN_PRIMARY_SC;
4463
4464 value = ctl_get_opt(&be_lun->options, "removable");
4465 if (value != NULL) {
4466 if (strcmp(value, "on") == 0)
4467 lun->flags |= CTL_LUN_REMOVABLE;
4468 } else if (be_lun->lun_type == T_CDROM)
4469 lun->flags |= CTL_LUN_REMOVABLE;
4470
4451 lun->ctl_softc = ctl_softc;
4452#ifdef CTL_TIME_IO
4453 lun->last_busy = getsbinuptime();
4454#endif
4455 TAILQ_INIT(&lun->ooa_queue);
4456 TAILQ_INIT(&lun->blocked_queue);
4457 STAILQ_INIT(&lun->error_list);
4458 ctl_tpc_lun_init(lun);

--- 660 unchanged lines hidden (view full) ---

5119 || (lun->pr_res_idx!=residx && lun->res_type < 4)) {
5120
5121 ctl_set_reservation_conflict(ctsio);
5122 ctl_done((union ctl_io *)ctsio);
5123 return (CTL_RETVAL_COMPLETE);
5124 }
5125 }
5126
4471 lun->ctl_softc = ctl_softc;
4472#ifdef CTL_TIME_IO
4473 lun->last_busy = getsbinuptime();
4474#endif
4475 TAILQ_INIT(&lun->ooa_queue);
4476 TAILQ_INIT(&lun->blocked_queue);
4477 STAILQ_INIT(&lun->error_list);
4478 ctl_tpc_lun_init(lun);

--- 660 unchanged lines hidden (view full) ---

5139 || (lun->pr_res_idx!=residx && lun->res_type < 4)) {
5140
5141 ctl_set_reservation_conflict(ctsio);
5142 ctl_done((union ctl_io *)ctsio);
5143 return (CTL_RETVAL_COMPLETE);
5144 }
5145 }
5146
5127 /*
5128 * If there is no backend on this device, we can't start or stop
5129 * it. In theory we shouldn't get any start/stop commands in the
5130 * first place at this level if the LUN doesn't have a backend.
5131 * That should get stopped by the command decode code.
5132 */
5133 if (lun->backend == NULL) {
5134 ctl_set_invalid_opcode(ctsio);
5147 if ((cdb->how & SSS_LOEJ) &&
5148 (lun->flags & CTL_LUN_REMOVABLE) == 0) {
5149 ctl_set_invalid_field(ctsio,
5150 /*sks_valid*/ 1,
5151 /*command*/ 1,
5152 /*field*/ 4,
5153 /*bit_valid*/ 1,
5154 /*bit*/ 1);
5135 ctl_done((union ctl_io *)ctsio);
5136 return (CTL_RETVAL_COMPLETE);
5137 }
5138
5139 /*
5140 * In the non-immediate case, we send the request to
5141 * the backend and return status to the user when
5142 * it is done.

--- 13 unchanged lines hidden (view full) ---

5156 ctl_done((union ctl_io *)ctsio);
5157 } else {
5158 retval = lun->backend->config_write(
5159 (union ctl_io *)ctsio);
5160 }
5161 return (retval);
5162}
5163
5155 ctl_done((union ctl_io *)ctsio);
5156 return (CTL_RETVAL_COMPLETE);
5157 }
5158
5159 /*
5160 * In the non-immediate case, we send the request to
5161 * the backend and return status to the user when
5162 * it is done.

--- 13 unchanged lines hidden (view full) ---

5176 ctl_done((union ctl_io *)ctsio);
5177 } else {
5178 retval = lun->backend->config_write(
5179 (union ctl_io *)ctsio);
5180 }
5181 return (retval);
5182}
5183
5184int
5185ctl_prevent_allow(struct ctl_scsiio *ctsio)
5186{
5187 struct ctl_lun *lun;
5188 int retval;
5189
5190 CTL_DEBUG_PRINT(("ctl_prevent_allow\n"));
5191
5192 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
5193
5194 if ((lun->flags & CTL_LUN_REMOVABLE) == 0) {
5195 ctl_set_invalid_opcode(ctsio);
5196 ctl_done((union ctl_io *)ctsio);
5197 return (CTL_RETVAL_COMPLETE);
5198 }
5199
5200 retval = lun->backend->config_write((union ctl_io *)ctsio);
5201 return (retval);
5202}
5203
5164/*
5165 * We support the SYNCHRONIZE CACHE command (10 and 16 byte versions), but
5166 * we don't really do anything with the LBA and length fields if the user
5167 * passes them in. Instead we'll just flush out the cache for the entire
5168 * LUN.
5169 */
5170int
5171ctl_sync_cache(struct ctl_scsiio *ctsio)

--- 45 unchanged lines hidden (view full) ---

5217 * to see an error for an out of range LBA.
5218 */
5219 if ((starting_lba + block_count) > (lun->be_lun->maxlba + 1)) {
5220 ctl_set_lba_out_of_range(ctsio);
5221 ctl_done((union ctl_io *)ctsio);
5222 goto bailout;
5223 }
5224
5204/*
5205 * We support the SYNCHRONIZE CACHE command (10 and 16 byte versions), but
5206 * we don't really do anything with the LBA and length fields if the user
5207 * passes them in. Instead we'll just flush out the cache for the entire
5208 * LUN.
5209 */
5210int
5211ctl_sync_cache(struct ctl_scsiio *ctsio)

--- 45 unchanged lines hidden (view full) ---

5257 * to see an error for an out of range LBA.
5258 */
5259 if ((starting_lba + block_count) > (lun->be_lun->maxlba + 1)) {
5260 ctl_set_lba_out_of_range(ctsio);
5261 ctl_done((union ctl_io *)ctsio);
5262 goto bailout;
5263 }
5264
5225 /*
5226 * If this LUN has no backend, we can't flush the cache anyway.
5227 */
5228 if (lun->backend == NULL) {
5229 ctl_set_invalid_opcode(ctsio);
5230 ctl_done((union ctl_io *)ctsio);
5231 goto bailout;
5232 }
5233
5234 lbalen = (struct ctl_lba_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
5235 lbalen->lba = starting_lba;
5236 lbalen->len = block_count;
5237 lbalen->flags = byte2;
5238 retval = lun->backend->config_write((union ctl_io *)ctsio);
5239
5240bailout:
5241 return (retval);

--- 686 unchanged lines hidden (view full) ---

5928 return (CTL_RETVAL_COMPLETE);
5929 }
5930
5931
5932 /*
5933 * XXX KDM should we do something with the block descriptor?
5934 */
5935 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
5265 lbalen = (struct ctl_lba_len_flags *)&ctsio->io_hdr.ctl_private[CTL_PRIV_LBA_LEN];
5266 lbalen->lba = starting_lba;
5267 lbalen->len = block_count;
5268 lbalen->flags = byte2;
5269 retval = lun->backend->config_write((union ctl_io *)ctsio);
5270
5271bailout:
5272 return (retval);

--- 686 unchanged lines hidden (view full) ---

5959 return (CTL_RETVAL_COMPLETE);
5960 }
5961
5962
5963 /*
5964 * XXX KDM should we do something with the block descriptor?
5965 */
5966 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
5936
5937 if (lun->be_lun->lun_type != T_DIRECT &&
5938 (lun->mode_pages.index[i].page_flags &
5939 CTL_PAGE_FLAG_DISK_ONLY))
5967 page_index = &lun->mode_pages.index[i];
5968 if (lun->be_lun->lun_type == T_DIRECT &&
5969 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
5940 continue;
5970 continue;
5971 if (lun->be_lun->lun_type == T_PROCESSOR &&
5972 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
5973 continue;
5974 if (lun->be_lun->lun_type == T_CDROM &&
5975 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
5976 continue;
5941
5977
5942 if ((lun->mode_pages.index[i].page_code & SMPH_PC_MASK) !=
5978 if ((page_index->page_code & SMPH_PC_MASK) !=
5943 (page_header->page_code & SMPH_PC_MASK))
5944 continue;
5945
5946 /*
5947 * If neither page has a subpage code, then we've got a
5948 * match.
5949 */
5979 (page_header->page_code & SMPH_PC_MASK))
5980 continue;
5981
5982 /*
5983 * If neither page has a subpage code, then we've got a
5984 * match.
5985 */
5950 if (((lun->mode_pages.index[i].page_code & SMPH_SPF) == 0)
5986 if (((page_index->page_code & SMPH_SPF) == 0)
5951 && ((page_header->page_code & SMPH_SPF) == 0)) {
5987 && ((page_header->page_code & SMPH_SPF) == 0)) {
5952 page_index = &lun->mode_pages.index[i];
5953 page_len = page_header->page_length;
5954 break;
5955 }
5956
5957 /*
5958 * If both pages have subpages, then the subpage numbers
5959 * have to match.
5960 */
5988 page_len = page_header->page_length;
5989 break;
5990 }
5991
5992 /*
5993 * If both pages have subpages, then the subpage numbers
5994 * have to match.
5995 */
5961 if ((lun->mode_pages.index[i].page_code & SMPH_SPF)
5996 if ((page_index->page_code & SMPH_SPF)
5962 && (page_header->page_code & SMPH_SPF)) {
5963 struct scsi_mode_page_header_sp *sph;
5964
5965 sph = (struct scsi_mode_page_header_sp *)page_header;
5997 && (page_header->page_code & SMPH_SPF)) {
5998 struct scsi_mode_page_header_sp *sph;
5999
6000 sph = (struct scsi_mode_page_header_sp *)page_header;
5966
5967 if (lun->mode_pages.index[i].subpage ==
5968 sph->subpage) {
5969 page_index = &lun->mode_pages.index[i];
6001 if (page_index->subpage == sph->subpage) {
5970 page_len = scsi_2btoul(sph->page_length);
5971 break;
5972 }
5973 }
5974 }
5975
5976 /*
5977 * If we couldn't find the page, or if we don't have a mode select
5978 * handler for it, send back an error to the user.
5979 */
6002 page_len = scsi_2btoul(sph->page_length);
6003 break;
6004 }
6005 }
6006 }
6007
6008 /*
6009 * If we couldn't find the page, or if we don't have a mode select
6010 * handler for it, send back an error to the user.
6011 */
5980 if ((page_index == NULL)
6012 if ((i >= CTL_NUM_MODE_PAGES)
5981 || (page_index->select_handler == NULL)) {
5982 ctl_set_invalid_field(ctsio,
5983 /*sks_valid*/ 1,
5984 /*command*/ 0,
5985 /*field*/ *len_used,
5986 /*bit_valid*/ 0,
5987 /*bit*/ 0);
5988 free(ctsio->kern_data_ptr, M_CTL);

--- 242 unchanged lines hidden (view full) ---

6231 int pc, page_code, dbd, llba, subpage;
6232 int alloc_len, page_len, header_len, total_len;
6233 struct scsi_mode_block_descr *block_desc;
6234 struct ctl_page_index *page_index;
6235
6236 dbd = 0;
6237 llba = 0;
6238 block_desc = NULL;
6013 || (page_index->select_handler == NULL)) {
6014 ctl_set_invalid_field(ctsio,
6015 /*sks_valid*/ 1,
6016 /*command*/ 0,
6017 /*field*/ *len_used,
6018 /*bit_valid*/ 0,
6019 /*bit*/ 0);
6020 free(ctsio->kern_data_ptr, M_CTL);

--- 242 unchanged lines hidden (view full) ---

6263 int pc, page_code, dbd, llba, subpage;
6264 int alloc_len, page_len, header_len, total_len;
6265 struct scsi_mode_block_descr *block_desc;
6266 struct ctl_page_index *page_index;
6267
6268 dbd = 0;
6269 llba = 0;
6270 block_desc = NULL;
6239 page_index = NULL;
6240
6241 CTL_DEBUG_PRINT(("ctl_mode_sense\n"));
6242
6243 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
6244 switch (ctsio->cdb[0]) {
6245 case MODE_SENSE_6: {
6246 struct scsi_mode_sense_6 *cdb;
6247

--- 60 unchanged lines hidden (view full) ---

6308 /*field*/ 3,
6309 /*bit_valid*/ 0,
6310 /*bit*/ 0);
6311 ctl_done((union ctl_io *)ctsio);
6312 return (CTL_RETVAL_COMPLETE);
6313 }
6314
6315 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
6271
6272 CTL_DEBUG_PRINT(("ctl_mode_sense\n"));
6273
6274 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
6275 switch (ctsio->cdb[0]) {
6276 case MODE_SENSE_6: {
6277 struct scsi_mode_sense_6 *cdb;
6278

--- 60 unchanged lines hidden (view full) ---

6339 /*field*/ 3,
6340 /*bit_valid*/ 0,
6341 /*bit*/ 0);
6342 ctl_done((union ctl_io *)ctsio);
6343 return (CTL_RETVAL_COMPLETE);
6344 }
6345
6346 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
6316 if (lun->be_lun->lun_type != T_DIRECT &&
6317 (lun->mode_pages.index[i].page_flags &
6318 CTL_PAGE_FLAG_DISK_ONLY))
6347 page_index = &lun->mode_pages.index[i];
6348
6349 /* Make sure the page is supported for this dev type */
6350 if (lun->be_lun->lun_type == T_DIRECT &&
6351 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
6319 continue;
6352 continue;
6353 if (lun->be_lun->lun_type == T_PROCESSOR &&
6354 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
6355 continue;
6356 if (lun->be_lun->lun_type == T_CDROM &&
6357 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
6358 continue;
6320
6321 /*
6322 * We don't use this subpage if the user didn't
6323 * request all subpages.
6324 */
6359
6360 /*
6361 * We don't use this subpage if the user didn't
6362 * request all subpages.
6363 */
6325 if ((lun->mode_pages.index[i].subpage != 0)
6364 if ((page_index->subpage != 0)
6326 && (subpage == SMS_SUBPAGE_PAGE_0))
6327 continue;
6328
6329#if 0
6330 printf("found page %#x len %d\n",
6365 && (subpage == SMS_SUBPAGE_PAGE_0))
6366 continue;
6367
6368#if 0
6369 printf("found page %#x len %d\n",
6331 lun->mode_pages.index[i].page_code &
6332 SMPH_PC_MASK,
6333 lun->mode_pages.index[i].page_len);
6370 page_index->page_code & SMPH_PC_MASK,
6371 page_index->page_len);
6334#endif
6372#endif
6335 page_len += lun->mode_pages.index[i].page_len;
6373 page_len += page_index->page_len;
6336 }
6337 break;
6338 }
6339 default: {
6340 int i;
6341
6342 page_len = 0;
6343
6344 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
6374 }
6375 break;
6376 }
6377 default: {
6378 int i;
6379
6380 page_len = 0;
6381
6382 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
6383 page_index = &lun->mode_pages.index[i];
6384
6385 /* Make sure the page is supported for this dev type */
6386 if (lun->be_lun->lun_type == T_DIRECT &&
6387 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
6388 continue;
6389 if (lun->be_lun->lun_type == T_PROCESSOR &&
6390 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
6391 continue;
6392 if (lun->be_lun->lun_type == T_CDROM &&
6393 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
6394 continue;
6395
6345 /* Look for the right page code */
6396 /* Look for the right page code */
6346 if ((lun->mode_pages.index[i].page_code &
6347 SMPH_PC_MASK) != page_code)
6397 if ((page_index->page_code & SMPH_PC_MASK) != page_code)
6348 continue;
6349
6350 /* Look for the right subpage or the subpage wildcard*/
6398 continue;
6399
6400 /* Look for the right subpage or the subpage wildcard*/
6351 if ((lun->mode_pages.index[i].subpage != subpage)
6401 if ((page_index->subpage != subpage)
6352 && (subpage != SMS_SUBPAGE_ALL))
6353 continue;
6354
6402 && (subpage != SMS_SUBPAGE_ALL))
6403 continue;
6404
6355 /* Make sure the page is supported for this dev type */
6356 if (lun->be_lun->lun_type != T_DIRECT &&
6357 (lun->mode_pages.index[i].page_flags &
6358 CTL_PAGE_FLAG_DISK_ONLY))
6359 continue;
6360
6361#if 0
6362 printf("found page %#x len %d\n",
6405#if 0
6406 printf("found page %#x len %d\n",
6363 lun->mode_pages.index[i].page_code &
6364 SMPH_PC_MASK,
6365 lun->mode_pages.index[i].page_len);
6407 page_index->page_code & SMPH_PC_MASK,
6408 page_index->page_len);
6366#endif
6367
6409#endif
6410
6368 page_len += lun->mode_pages.index[i].page_len;
6411 page_len += page_index->page_len;
6369 }
6370
6371 if (page_len == 0) {
6372 ctl_set_invalid_field(ctsio,
6373 /*sks_valid*/ 1,
6374 /*command*/ 1,
6375 /*field*/ 2,
6376 /*bit_valid*/ 1,

--- 91 unchanged lines hidden (view full) ---

6468 case SMS_ALL_PAGES_PAGE: {
6469 int i, data_used;
6470
6471 data_used = header_len;
6472 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
6473 struct ctl_page_index *page_index;
6474
6475 page_index = &lun->mode_pages.index[i];
6412 }
6413
6414 if (page_len == 0) {
6415 ctl_set_invalid_field(ctsio,
6416 /*sks_valid*/ 1,
6417 /*command*/ 1,
6418 /*field*/ 2,
6419 /*bit_valid*/ 1,

--- 91 unchanged lines hidden (view full) ---

6511 case SMS_ALL_PAGES_PAGE: {
6512 int i, data_used;
6513
6514 data_used = header_len;
6515 for (i = 0; i < CTL_NUM_MODE_PAGES; i++) {
6516 struct ctl_page_index *page_index;
6517
6518 page_index = &lun->mode_pages.index[i];
6476
6477 if (lun->be_lun->lun_type != T_DIRECT &&
6478 (page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
6519 if (lun->be_lun->lun_type == T_DIRECT &&
6520 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
6479 continue;
6521 continue;
6522 if (lun->be_lun->lun_type == T_PROCESSOR &&
6523 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
6524 continue;
6525 if (lun->be_lun->lun_type == T_CDROM &&
6526 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
6527 continue;
6480
6481 /*
6482 * We don't use this subpage if the user didn't
6483 * request all subpages. We already checked (above)
6484 * to make sure the user only specified a subpage
6485 * of 0 or 0xff in the SMS_ALL_PAGES_PAGE case.
6486 */
6487 if ((page_index->subpage != 0)

--- 30 unchanged lines hidden (view full) ---

6518 continue;
6519
6520 /* Look for the right subpage or the subpage wildcard*/
6521 if ((page_index->subpage != subpage)
6522 && (subpage != SMS_SUBPAGE_ALL))
6523 continue;
6524
6525 /* Make sure the page is supported for this dev type */
6528
6529 /*
6530 * We don't use this subpage if the user didn't
6531 * request all subpages. We already checked (above)
6532 * to make sure the user only specified a subpage
6533 * of 0 or 0xff in the SMS_ALL_PAGES_PAGE case.
6534 */
6535 if ((page_index->subpage != 0)

--- 30 unchanged lines hidden (view full) ---

6566 continue;
6567
6568 /* Look for the right subpage or the subpage wildcard*/
6569 if ((page_index->subpage != subpage)
6570 && (subpage != SMS_SUBPAGE_ALL))
6571 continue;
6572
6573 /* Make sure the page is supported for this dev type */
6526 if (lun->be_lun->lun_type != T_DIRECT &&
6527 (page_index->page_flags & CTL_PAGE_FLAG_DISK_ONLY))
6574 if (lun->be_lun->lun_type == T_DIRECT &&
6575 (page_index->page_flags & CTL_PAGE_FLAG_DIRECT) == 0)
6528 continue;
6576 continue;
6577 if (lun->be_lun->lun_type == T_PROCESSOR &&
6578 (page_index->page_flags & CTL_PAGE_FLAG_PROC) == 0)
6579 continue;
6580 if (lun->be_lun->lun_type == T_CDROM &&
6581 (page_index->page_flags & CTL_PAGE_FLAG_CDROM) == 0)
6582 continue;
6529
6530 /*
6531 * Call the handler, if it exists, to update the
6532 * page to the latest values.
6533 */
6534 if (page_index->sense_handler != NULL)
6535 page_index->sense_handler(ctsio, page_index,pc);
6536

--- 3508 unchanged lines hidden (view full) ---

10045 if ((lun->flags & CTL_LUN_PRIMARY_SC) ||
10046 softc->ha_link >= CTL_HA_LINK_UNKNOWN) {
10047 inq_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
10048 lun->be_lun->lun_type;
10049 } else {
10050 inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) |
10051 lun->be_lun->lun_type;
10052 }
6583
6584 /*
6585 * Call the handler, if it exists, to update the
6586 * page to the latest values.
6587 */
6588 if (page_index->sense_handler != NULL)
6589 page_index->sense_handler(ctsio, page_index,pc);
6590

--- 3508 unchanged lines hidden (view full) ---

10099 if ((lun->flags & CTL_LUN_PRIMARY_SC) ||
10100 softc->ha_link >= CTL_HA_LINK_UNKNOWN) {
10101 inq_ptr->device = (SID_QUAL_LU_CONNECTED << 5) |
10102 lun->be_lun->lun_type;
10103 } else {
10104 inq_ptr->device = (SID_QUAL_LU_OFFLINE << 5) |
10105 lun->be_lun->lun_type;
10106 }
10107 if (lun->flags & CTL_LUN_REMOVABLE)
10108 inq_ptr->dev_qual2 |= SID_RMB;
10053 } else
10054 inq_ptr->device = (SID_QUAL_BAD_LU << 5) | T_NODEVICE;
10055
10056 /* RMB in byte 2 is 0 */
10057 inq_ptr->version = SCSI_REV_SPC4;
10058
10059 /*
10060 * According to SAM-3, even if a device only supports a single

--- 48 unchanged lines hidden (view full) ---

10109 case T_DIRECT:
10110 strncpy(inq_ptr->product, CTL_DIRECT_PRODUCT,
10111 sizeof(inq_ptr->product));
10112 break;
10113 case T_PROCESSOR:
10114 strncpy(inq_ptr->product, CTL_PROCESSOR_PRODUCT,
10115 sizeof(inq_ptr->product));
10116 break;
10109 } else
10110 inq_ptr->device = (SID_QUAL_BAD_LU << 5) | T_NODEVICE;
10111
10112 /* RMB in byte 2 is 0 */
10113 inq_ptr->version = SCSI_REV_SPC4;
10114
10115 /*
10116 * According to SAM-3, even if a device only supports a single

--- 48 unchanged lines hidden (view full) ---

10165 case T_DIRECT:
10166 strncpy(inq_ptr->product, CTL_DIRECT_PRODUCT,
10167 sizeof(inq_ptr->product));
10168 break;
10169 case T_PROCESSOR:
10170 strncpy(inq_ptr->product, CTL_PROCESSOR_PRODUCT,
10171 sizeof(inq_ptr->product));
10172 break;
10173 case T_CDROM:
10174 strncpy(inq_ptr->product, CTL_CDROM_PRODUCT,
10175 sizeof(inq_ptr->product));
10176 break;
10117 default:
10118 strncpy(inq_ptr->product, CTL_UNKNOWN_PRODUCT,
10119 sizeof(inq_ptr->product));
10120 break;
10121 }
10122 } else {
10123 memset(inq_ptr->product, ' ', sizeof(inq_ptr->product));
10124 strncpy(inq_ptr->product, val,

--- 46 unchanged lines hidden (view full) ---

10171 scsi_ulto2b(0x0600, inq_ptr->version4);
10172 } else {
10173 switch (lun->be_lun->lun_type) {
10174 case T_DIRECT:
10175 /* SBC-4 (no version claimed) */
10176 scsi_ulto2b(0x0600, inq_ptr->version4);
10177 break;
10178 case T_PROCESSOR:
10177 default:
10178 strncpy(inq_ptr->product, CTL_UNKNOWN_PRODUCT,
10179 sizeof(inq_ptr->product));
10180 break;
10181 }
10182 } else {
10183 memset(inq_ptr->product, ' ', sizeof(inq_ptr->product));
10184 strncpy(inq_ptr->product, val,

--- 46 unchanged lines hidden (view full) ---

10231 scsi_ulto2b(0x0600, inq_ptr->version4);
10232 } else {
10233 switch (lun->be_lun->lun_type) {
10234 case T_DIRECT:
10235 /* SBC-4 (no version claimed) */
10236 scsi_ulto2b(0x0600, inq_ptr->version4);
10237 break;
10238 case T_PROCESSOR:
10239 break;
10240 case T_CDROM:
10241 /* MMC-6 (no version claimed) */
10242 scsi_ulto2b(0x04E0, inq_ptr->version4);
10243 break;
10179 default:
10180 break;
10181 }
10182 }
10183
10184 ctl_set_success(ctsio);
10185 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
10186 ctsio->be_move_done = ctl_config_move_done;

--- 23 unchanged lines hidden (view full) ---

10210 /*bit*/ 0);
10211 ctl_done((union ctl_io *)ctsio);
10212 return (CTL_RETVAL_COMPLETE);
10213 }
10214
10215 return (retval);
10216}
10217
10244 default:
10245 break;
10246 }
10247 }
10248
10249 ctl_set_success(ctsio);
10250 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
10251 ctsio->be_move_done = ctl_config_move_done;

--- 23 unchanged lines hidden (view full) ---

10275 /*bit*/ 0);
10276 ctl_done((union ctl_io *)ctsio);
10277 return (CTL_RETVAL_COMPLETE);
10278 }
10279
10280 return (retval);
10281}
10282
10283int
10284ctl_get_config(struct ctl_scsiio *ctsio)
10285{
10286 struct scsi_get_config_header *hdr;
10287 struct scsi_get_config_feature *feature;
10288 struct scsi_get_config *cdb;
10289 struct ctl_lun *lun;
10290 uint32_t alloc_len, data_len;
10291 int rt, starting;
10292
10293 lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
10294 cdb = (struct scsi_get_config *)ctsio->cdb;
10295 rt = (cdb->rt & SGC_RT_MASK);
10296 starting = scsi_2btoul(cdb->starting_feature);
10297 alloc_len = scsi_2btoul(cdb->length);
10298
10299 data_len = sizeof(struct scsi_get_config_header) +
10300 sizeof(struct scsi_get_config_feature) + 8 +
10301 sizeof(struct scsi_get_config_feature) + 8 +
10302 sizeof(struct scsi_get_config_feature) + 4 +
10303 sizeof(struct scsi_get_config_feature) + 4 +
10304 sizeof(struct scsi_get_config_feature) + 8 +
10305 sizeof(struct scsi_get_config_feature) +
10306 sizeof(struct scsi_get_config_feature) + 4 +
10307 sizeof(struct scsi_get_config_feature) + 4;
10308 ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
10309 ctsio->kern_sg_entries = 0;
10310 ctsio->kern_data_resid = 0;
10311 ctsio->kern_rel_offset = 0;
10312
10313 hdr = (struct scsi_get_config_header *)ctsio->kern_data_ptr;
10314 if (lun->flags & CTL_LUN_OFFLINE)
10315 scsi_ulto2b(0x0000, hdr->current_profile);
10316 else
10317 scsi_ulto2b(0x0010, hdr->current_profile);
10318 feature = (struct scsi_get_config_feature *)(hdr + 1);
10319
10320 if (starting > 0x001f)
10321 goto done;
10322 if (starting > 0x001e)
10323 goto f1f;
10324 if (starting > 0x001d)
10325 goto f1e;
10326 if (starting > 0x0010)
10327 goto f1d;
10328 if (starting > 0x0003)
10329 goto f10;
10330 if (starting > 0x0002)
10331 goto f3;
10332 if (starting > 0x0001)
10333 goto f2;
10334 if (starting > 0x0000)
10335 goto f1;
10336
10337 /* Profile List */
10338 scsi_ulto2b(0x0000, feature->feature_code);
10339 feature->flags = SGC_F_PERSISTENT | SGC_F_CURRENT;
10340 feature->add_length = 8;
10341 scsi_ulto2b(0x0008, &feature->feature_data[0]); /* CD-ROM */
10342 feature->feature_data[2] = 0x00;
10343 scsi_ulto2b(0x0010, &feature->feature_data[4]); /* DVD-ROM */
10344 feature->feature_data[6] = 0x01;
10345 feature = (struct scsi_get_config_feature *)
10346 &feature->feature_data[feature->add_length];
10347
10348f1: /* Core */
10349 scsi_ulto2b(0x0001, feature->feature_code);
10350 feature->flags = 0x08 | SGC_F_PERSISTENT | SGC_F_CURRENT;
10351 feature->add_length = 8;
10352 scsi_ulto4b(0x00000000, &feature->feature_data[0]);
10353 feature->feature_data[4] = 0x03;
10354 feature = (struct scsi_get_config_feature *)
10355 &feature->feature_data[feature->add_length];
10356
10357f2: /* Morphing */
10358 scsi_ulto2b(0x0002, feature->feature_code);
10359 feature->flags = 0x04 | SGC_F_PERSISTENT | SGC_F_CURRENT;
10360 feature->add_length = 4;
10361 feature->feature_data[0] = 0x02;
10362 feature = (struct scsi_get_config_feature *)
10363 &feature->feature_data[feature->add_length];
10364
10365f3: /* Removable Medium */
10366 scsi_ulto2b(0x0003, feature->feature_code);
10367 feature->flags = 0x04 | SGC_F_PERSISTENT | SGC_F_CURRENT;
10368 feature->add_length = 4;
10369 feature->feature_data[0] = 0x39;
10370 feature = (struct scsi_get_config_feature *)
10371 &feature->feature_data[feature->add_length];
10372
10373 if (rt == SGC_RT_CURRENT && (lun->flags & CTL_LUN_OFFLINE))
10374 goto done;
10375
10376f10: /* Random Read */
10377 scsi_ulto2b(0x0010, feature->feature_code);
10378 feature->flags = 0x00;
10379 if ((lun->flags & CTL_LUN_OFFLINE) == 0)
10380 feature->flags |= SGC_F_CURRENT;
10381 feature->add_length = 8;
10382 scsi_ulto4b(lun->be_lun->blocksize, &feature->feature_data[0]);
10383 scsi_ulto2b(1, &feature->feature_data[4]);
10384 feature->feature_data[6] = 0x00;
10385 feature = (struct scsi_get_config_feature *)
10386 &feature->feature_data[feature->add_length];
10387
10388f1d: /* Multi-Read */
10389 scsi_ulto2b(0x001D, feature->feature_code);
10390 feature->flags = 0x00;
10391 if ((lun->flags & CTL_LUN_OFFLINE) == 0)
10392 feature->flags |= SGC_F_CURRENT;
10393 feature->add_length = 0;
10394 feature = (struct scsi_get_config_feature *)
10395 &feature->feature_data[feature->add_length];
10396
10397f1e: /* CD Read */
10398 scsi_ulto2b(0x001E, feature->feature_code);
10399 feature->flags = 0x00;
10400 if ((lun->flags & CTL_LUN_OFFLINE) == 0)
10401 feature->flags |= SGC_F_CURRENT;
10402 feature->add_length = 4;
10403 feature->feature_data[0] = 0x00;
10404 feature = (struct scsi_get_config_feature *)
10405 &feature->feature_data[feature->add_length];
10406
10407f1f: /* DVD Read */
10408 scsi_ulto2b(0x001F, feature->feature_code);
10409 feature->flags = 0x08;
10410 if ((lun->flags & CTL_LUN_OFFLINE) == 0)
10411 feature->flags |= SGC_F_CURRENT;
10412 feature->add_length = 4;
10413 feature->feature_data[0] = 0x01;
10414 feature->feature_data[2] = 0x03;
10415 feature = (struct scsi_get_config_feature *)
10416 &feature->feature_data[feature->add_length];
10417
10418done:
10419 data_len = (uint8_t *)feature - (uint8_t *)hdr;
10420 if (rt == SGC_RT_SPECIFIC && data_len > 4) {
10421 feature = (struct scsi_get_config_feature *)(hdr + 1);
10422 if (scsi_2btoul(feature->feature_code) == starting)
10423 feature = (struct scsi_get_config_feature *)
10424 &feature->feature_data[feature->add_length];
10425 data_len = (uint8_t *)feature - (uint8_t *)hdr;
10426 }
10427 scsi_ulto4b(data_len - 4, hdr->data_length);
10428 if (data_len < alloc_len) {
10429 ctsio->residual = alloc_len - data_len;
10430 ctsio->kern_data_len = data_len;
10431 ctsio->kern_total_len = data_len;
10432 } else {
10433 ctsio->residual = 0;
10434 ctsio->kern_data_len = alloc_len;
10435 ctsio->kern_total_len = alloc_len;
10436 }
10437
10438 ctl_set_success(ctsio);
10439 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
10440 ctsio->be_move_done = ctl_config_move_done;
10441 ctl_datamove((union ctl_io *)ctsio);
10442 return (CTL_RETVAL_COMPLETE);
10443}
10444
10445int
10446ctl_get_event_status(struct ctl_scsiio *ctsio)
10447{
10448 struct scsi_get_event_status_header *hdr;
10449 struct scsi_get_event_status *cdb;
10450 struct ctl_lun *lun;
10451 uint32_t alloc_len, data_len;
10452 int notif_class;
10453
10454 lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
10455 cdb = (struct scsi_get_event_status *)ctsio->cdb;
10456 if ((cdb->byte2 & SGESN_POLLED) == 0) {
10457 ctl_set_invalid_field(ctsio, /*sks_valid*/ 1, /*command*/ 1,
10458 /*field*/ 1, /*bit_valid*/ 1, /*bit*/ 0);
10459 ctl_done((union ctl_io *)ctsio);
10460 return (CTL_RETVAL_COMPLETE);
10461 }
10462 notif_class = cdb->notif_class;
10463 alloc_len = scsi_2btoul(cdb->length);
10464
10465 data_len = sizeof(struct scsi_get_event_status_header);
10466 ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
10467 ctsio->kern_sg_entries = 0;
10468 ctsio->kern_data_resid = 0;
10469 ctsio->kern_rel_offset = 0;
10470
10471 if (data_len < alloc_len) {
10472 ctsio->residual = alloc_len - data_len;
10473 ctsio->kern_data_len = data_len;
10474 ctsio->kern_total_len = data_len;
10475 } else {
10476 ctsio->residual = 0;
10477 ctsio->kern_data_len = alloc_len;
10478 ctsio->kern_total_len = alloc_len;
10479 }
10480
10481 hdr = (struct scsi_get_event_status_header *)ctsio->kern_data_ptr;
10482 scsi_ulto2b(0, hdr->descr_length);
10483 hdr->nea_class = SGESN_NEA;
10484 hdr->supported_class = 0;
10485
10486 ctl_set_success(ctsio);
10487 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
10488 ctsio->be_move_done = ctl_config_move_done;
10489 ctl_datamove((union ctl_io *)ctsio);
10490 return (CTL_RETVAL_COMPLETE);
10491}
10492
10493int
10494ctl_mechanism_status(struct ctl_scsiio *ctsio)
10495{
10496 struct scsi_mechanism_status_header *hdr;
10497 struct scsi_mechanism_status *cdb;
10498 struct ctl_lun *lun;
10499 uint32_t alloc_len, data_len;
10500
10501 lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
10502 cdb = (struct scsi_mechanism_status *)ctsio->cdb;
10503 alloc_len = scsi_2btoul(cdb->length);
10504
10505 data_len = sizeof(struct scsi_mechanism_status_header);
10506 ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
10507 ctsio->kern_sg_entries = 0;
10508 ctsio->kern_data_resid = 0;
10509 ctsio->kern_rel_offset = 0;
10510
10511 if (data_len < alloc_len) {
10512 ctsio->residual = alloc_len - data_len;
10513 ctsio->kern_data_len = data_len;
10514 ctsio->kern_total_len = data_len;
10515 } else {
10516 ctsio->residual = 0;
10517 ctsio->kern_data_len = alloc_len;
10518 ctsio->kern_total_len = alloc_len;
10519 }
10520
10521 hdr = (struct scsi_mechanism_status_header *)ctsio->kern_data_ptr;
10522 hdr->state1 = 0x00;
10523 hdr->state2 = 0xe0;
10524 scsi_ulto3b(0, hdr->lba);
10525 hdr->slots_num = 0;
10526 scsi_ulto2b(0, hdr->slots_length);
10527
10528 ctl_set_success(ctsio);
10529 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
10530 ctsio->be_move_done = ctl_config_move_done;
10531 ctl_datamove((union ctl_io *)ctsio);
10532 return (CTL_RETVAL_COMPLETE);
10533}
10534
10535static void
10536ctl_ultomsf(uint32_t lba, uint8_t *buf)
10537{
10538
10539 lba += 150;
10540 buf[0] = 0;
10541 buf[1] = bin2bcd((lba / 75) / 60);
10542 buf[2] = bin2bcd((lba / 75) % 60);
10543 buf[3] = bin2bcd(lba % 75);
10544}
10545
10546int
10547ctl_read_toc(struct ctl_scsiio *ctsio)
10548{
10549 struct scsi_read_toc_hdr *hdr;
10550 struct scsi_read_toc_type01_descr *descr;
10551 struct scsi_read_toc *cdb;
10552 struct ctl_lun *lun;
10553 uint32_t alloc_len, data_len;
10554 int format, msf;
10555
10556 lun = ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr;
10557 cdb = (struct scsi_read_toc *)ctsio->cdb;
10558 msf = (cdb->byte2 & CD_MSF) != 0;
10559 format = cdb->format;
10560 alloc_len = scsi_2btoul(cdb->data_len);
10561
10562 data_len = sizeof(struct scsi_read_toc_hdr);
10563 if (format == 0)
10564 data_len += 2 * sizeof(struct scsi_read_toc_type01_descr);
10565 else
10566 data_len += sizeof(struct scsi_read_toc_type01_descr);
10567 ctsio->kern_data_ptr = malloc(data_len, M_CTL, M_WAITOK | M_ZERO);
10568 ctsio->kern_sg_entries = 0;
10569 ctsio->kern_data_resid = 0;
10570 ctsio->kern_rel_offset = 0;
10571
10572 if (data_len < alloc_len) {
10573 ctsio->residual = alloc_len - data_len;
10574 ctsio->kern_data_len = data_len;
10575 ctsio->kern_total_len = data_len;
10576 } else {
10577 ctsio->residual = 0;
10578 ctsio->kern_data_len = alloc_len;
10579 ctsio->kern_total_len = alloc_len;
10580 }
10581
10582 hdr = (struct scsi_read_toc_hdr *)ctsio->kern_data_ptr;
10583 if (format == 0) {
10584 scsi_ulto2b(0x12, hdr->data_length);
10585 hdr->first = 1;
10586 hdr->last = 1;
10587 descr = (struct scsi_read_toc_type01_descr *)(hdr + 1);
10588 descr->addr_ctl = 0x14;
10589 descr->track_number = 1;
10590 if (msf)
10591 ctl_ultomsf(0, descr->track_start);
10592 else
10593 scsi_ulto4b(0, descr->track_start);
10594 descr++;
10595 descr->addr_ctl = 0x14;
10596 descr->track_number = 0xaa;
10597 if (msf)
10598 ctl_ultomsf(lun->be_lun->maxlba+1, descr->track_start);
10599 else
10600 scsi_ulto4b(lun->be_lun->maxlba+1, descr->track_start);
10601 } else {
10602 scsi_ulto2b(0x0a, hdr->data_length);
10603 hdr->first = 1;
10604 hdr->last = 1;
10605 descr = (struct scsi_read_toc_type01_descr *)(hdr + 1);
10606 descr->addr_ctl = 0x14;
10607 descr->track_number = 1;
10608 if (msf)
10609 ctl_ultomsf(0, descr->track_start);
10610 else
10611 scsi_ulto4b(0, descr->track_start);
10612 }
10613
10614 ctl_set_success(ctsio);
10615 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED;
10616 ctsio->be_move_done = ctl_config_move_done;
10617 ctl_datamove((union ctl_io *)ctsio);
10618 return (CTL_RETVAL_COMPLETE);
10619}
10620
10218/*
10219 * For known CDB types, parse the LBA and length.
10220 */
10221static int
10222ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint64_t *len)
10223{
10224 if (io->io_hdr.io_type != CTL_IO_SCSI)
10225 return (1);

--- 1033 unchanged lines hidden (view full) ---

11259 return (entry);
11260}
11261
11262static int
11263ctl_cmd_applicable(uint8_t lun_type, const struct ctl_cmd_entry *entry)
11264{
11265
11266 switch (lun_type) {
10621/*
10622 * For known CDB types, parse the LBA and length.
10623 */
10624static int
10625ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint64_t *len)
10626{
10627 if (io->io_hdr.io_type != CTL_IO_SCSI)
10628 return (1);

--- 1033 unchanged lines hidden (view full) ---

11662 return (entry);
11663}
11664
11665static int
11666ctl_cmd_applicable(uint8_t lun_type, const struct ctl_cmd_entry *entry)
11667{
11668
11669 switch (lun_type) {
11670 case T_DIRECT:
11671 if ((entry->flags & CTL_CMD_FLAG_OK_ON_DIRECT) == 0)
11672 return (0);
11673 break;
11267 case T_PROCESSOR:
11268 if ((entry->flags & CTL_CMD_FLAG_OK_ON_PROC) == 0)
11269 return (0);
11270 break;
11674 case T_PROCESSOR:
11675 if ((entry->flags & CTL_CMD_FLAG_OK_ON_PROC) == 0)
11676 return (0);
11677 break;
11271 case T_DIRECT:
11272 if ((entry->flags & CTL_CMD_FLAG_OK_ON_SLUN) == 0)
11678 case T_CDROM:
11679 if ((entry->flags & CTL_CMD_FLAG_OK_ON_CDROM) == 0)
11273 return (0);
11274 break;
11275 default:
11276 return (0);
11277 }
11278 return (1);
11279}
11280

--- 1944 unchanged lines hidden ---
11680 return (0);
11681 break;
11682 default:
11683 return (0);
11684 }
11685 return (1);
11686}
11687

--- 1944 unchanged lines hidden ---