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 --- |