ctl.c (269497) | ctl.c (269622) |
---|---|
1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 28 unchanged lines hidden (view full) --- 37 * CAM Target Layer, a SCSI device emulation subsystem. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#define _CTL_C 43 44#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2012 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Edward Tomasz Napierala 7 * under sponsorship from the FreeBSD Foundation. 8 * --- 28 unchanged lines hidden (view full) --- 37 * CAM Target Layer, a SCSI device emulation subsystem. 38 * 39 * Author: Ken Merry <ken@FreeBSD.org> 40 */ 41 42#define _CTL_C 43 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 269497 2014-08-04 01:16:20Z mav $"); | 45__FBSDID("$FreeBSD: head/sys/cam/ctl/ctl.c 269622 2014-08-06 08:54:31Z mav $"); |
46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/types.h> 51#include <sys/kthread.h> 52#include <sys/bio.h> 53#include <sys/fcntl.h> --- 261 unchanged lines hidden (view full) --- 315SYSCTL_INT(_kern_cam_ctl, OID_AUTO, worker_threads, CTLFLAG_RDTUN, 316 &worker_threads, 1, "Number of worker threads"); 317static int verbose = 0; 318SYSCTL_INT(_kern_cam_ctl, OID_AUTO, verbose, CTLFLAG_RWTUN, 319 &verbose, 0, "Show SCSI errors returned to initiator"); 320 321/* 322 * Supported pages (0x00), Serial number (0x80), Device ID (0x83), | 46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/kernel.h> 50#include <sys/types.h> 51#include <sys/kthread.h> 52#include <sys/bio.h> 53#include <sys/fcntl.h> --- 261 unchanged lines hidden (view full) --- 315SYSCTL_INT(_kern_cam_ctl, OID_AUTO, worker_threads, CTLFLAG_RDTUN, 316 &worker_threads, 1, "Number of worker threads"); 317static int verbose = 0; 318SYSCTL_INT(_kern_cam_ctl, OID_AUTO, verbose, CTLFLAG_RWTUN, 319 &verbose, 0, "Show SCSI errors returned to initiator"); 320 321/* 322 * Supported pages (0x00), Serial number (0x80), Device ID (0x83), |
323 * SCSI Ports (0x88), Third-party Copy (0x8F), Block limits (0xB0) and 324 * Logical Block Provisioning (0xB2) | 323 * SCSI Ports (0x88), Third-party Copy (0x8F), Block limits (0xB0), 324 * Block Device Characteristics (0xB1) and Logical Block Provisioning (0xB2) |
325 */ | 325 */ |
326#define SCSI_EVPD_NUM_SUPPORTED_PAGES 7 | 326#define SCSI_EVPD_NUM_SUPPORTED_PAGES 8 |
327 328static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, 329 int param); 330static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest); 331static int ctl_init(void); 332void ctl_shutdown(void); 333static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td); 334static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td); --- 43 unchanged lines hidden (view full) --- 378static void ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg); 379static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len); 380static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len); 381static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len); 382static int ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, 383 int alloc_len); 384static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, 385 int alloc_len); | 327 328static void ctl_isc_event_handler(ctl_ha_channel chanel, ctl_ha_event event, 329 int param); 330static void ctl_copy_sense_data(union ctl_ha_msg *src, union ctl_io *dest); 331static int ctl_init(void); 332void ctl_shutdown(void); 333static int ctl_open(struct cdev *dev, int flags, int fmt, struct thread *td); 334static int ctl_close(struct cdev *dev, int flags, int fmt, struct thread *td); --- 43 unchanged lines hidden (view full) --- 378static void ctl_hndl_per_res_out_on_other_sc(union ctl_ha_msg *msg); 379static int ctl_inquiry_evpd_supported(struct ctl_scsiio *ctsio, int alloc_len); 380static int ctl_inquiry_evpd_serial(struct ctl_scsiio *ctsio, int alloc_len); 381static int ctl_inquiry_evpd_devid(struct ctl_scsiio *ctsio, int alloc_len); 382static int ctl_inquiry_evpd_scsi_ports(struct ctl_scsiio *ctsio, 383 int alloc_len); 384static int ctl_inquiry_evpd_block_limits(struct ctl_scsiio *ctsio, 385 int alloc_len); |
386static int ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len); |
|
386static int ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len); 387static int ctl_inquiry_evpd(struct ctl_scsiio *ctsio); 388static int ctl_inquiry_std(struct ctl_scsiio *ctsio); 389static int ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint32_t *len); 390static ctl_action ctl_extent_check(union ctl_io *io1, union ctl_io *io2); 391static ctl_action ctl_check_for_blockage(union ctl_io *pending_io, 392 union ctl_io *ooa_io); 393static ctl_action ctl_check_ooa(struct ctl_lun *lun, union ctl_io *pending_io, --- 6853 unchanged lines hidden (view full) --- 7247 ctsio->kern_sg_entries = 0; 7248 7249 scsi_u64to8b(lun->be_lun->maxlba, data->addr); 7250 /* XXX KDM this may not be 512 bytes... */ 7251 scsi_ulto4b(lun->be_lun->blocksize, data->length); 7252 data->prot_lbppbe = lun->be_lun->pblockexp & SRC16_LBPPBE; 7253 scsi_ulto2b(lun->be_lun->pblockoff & SRC16_LALBA_A, data->lalba_lbp); 7254 if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) | 387static int ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len); 388static int ctl_inquiry_evpd(struct ctl_scsiio *ctsio); 389static int ctl_inquiry_std(struct ctl_scsiio *ctsio); 390static int ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint32_t *len); 391static ctl_action ctl_extent_check(union ctl_io *io1, union ctl_io *io2); 392static ctl_action ctl_check_for_blockage(union ctl_io *pending_io, 393 union ctl_io *ooa_io); 394static ctl_action ctl_check_ooa(struct ctl_lun *lun, union ctl_io *pending_io, --- 6853 unchanged lines hidden (view full) --- 7248 ctsio->kern_sg_entries = 0; 7249 7250 scsi_u64to8b(lun->be_lun->maxlba, data->addr); 7251 /* XXX KDM this may not be 512 bytes... */ 7252 scsi_ulto4b(lun->be_lun->blocksize, data->length); 7253 data->prot_lbppbe = lun->be_lun->pblockexp & SRC16_LBPPBE; 7254 scsi_ulto2b(lun->be_lun->pblockoff & SRC16_LALBA_A, data->lalba_lbp); 7255 if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) |
7255 data->lalba_lbp[0] |= SRC16_LBPME; | 7256 data->lalba_lbp[0] |= SRC16_LBPME | SRC16_LBPRZ; |
7256 7257 ctsio->scsi_status = SCSI_STATUS_OK; 7258 7259 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 7260 ctsio->be_move_done = ctl_config_move_done; 7261 ctl_datamove((union ctl_io *)ctsio); 7262 7263 return (CTL_RETVAL_COMPLETE); --- 2540 unchanged lines hidden (view full) --- 9804 /* Device Identification */ 9805 pages->page_list[2] = SVPD_DEVICE_ID; 9806 /* SCSI Ports */ 9807 pages->page_list[3] = SVPD_SCSI_PORTS; 9808 /* Third-party Copy */ 9809 pages->page_list[4] = SVPD_SCSI_TPC; 9810 /* Block limits */ 9811 pages->page_list[5] = SVPD_BLOCK_LIMITS; | 7257 7258 ctsio->scsi_status = SCSI_STATUS_OK; 7259 7260 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 7261 ctsio->be_move_done = ctl_config_move_done; 7262 ctl_datamove((union ctl_io *)ctsio); 7263 7264 return (CTL_RETVAL_COMPLETE); --- 2540 unchanged lines hidden (view full) --- 9805 /* Device Identification */ 9806 pages->page_list[2] = SVPD_DEVICE_ID; 9807 /* SCSI Ports */ 9808 pages->page_list[3] = SVPD_SCSI_PORTS; 9809 /* Third-party Copy */ 9810 pages->page_list[4] = SVPD_SCSI_TPC; 9811 /* Block limits */ 9812 pages->page_list[5] = SVPD_BLOCK_LIMITS; |
9813 /* Block Device Characteristics */ 9814 pages->page_list[6] = SVPD_BDC; |
|
9812 /* Logical Block Provisioning */ | 9815 /* Logical Block Provisioning */ |
9813 pages->page_list[6] = SVPD_LBP; | 9816 pages->page_list[7] = SVPD_LBP; |
9814 9815 ctsio->scsi_status = SCSI_STATUS_OK; 9816 9817 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 9818 ctsio->be_move_done = ctl_config_move_done; 9819 ctl_datamove((union ctl_io *)ctsio); 9820 9821 return (CTL_RETVAL_COMPLETE); --- 339 unchanged lines hidden (view full) --- 10161 bl_ptr->max_cmp_write_len = 0xff; 10162 scsi_ulto4b(0xffffffff, bl_ptr->max_txfer_len); 10163 if (lun != NULL) { 10164 bs = lun->be_lun->blocksize; 10165 scsi_ulto4b(MAXPHYS / bs, bl_ptr->opt_txfer_len); 10166 if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { 10167 scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt); 10168 scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt); | 9817 9818 ctsio->scsi_status = SCSI_STATUS_OK; 9819 9820 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 9821 ctsio->be_move_done = ctl_config_move_done; 9822 ctl_datamove((union ctl_io *)ctsio); 9823 9824 return (CTL_RETVAL_COMPLETE); --- 339 unchanged lines hidden (view full) --- 10164 bl_ptr->max_cmp_write_len = 0xff; 10165 scsi_ulto4b(0xffffffff, bl_ptr->max_txfer_len); 10166 if (lun != NULL) { 10167 bs = lun->be_lun->blocksize; 10168 scsi_ulto4b(MAXPHYS / bs, bl_ptr->opt_txfer_len); 10169 if (lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { 10170 scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_lba_cnt); 10171 scsi_ulto4b(0xffffffff, bl_ptr->max_unmap_blk_cnt); |
10172 if (lun->be_lun->pblockexp != 0) { 10173 scsi_ulto4b((1 << lun->be_lun->pblockexp), 10174 bl_ptr->opt_unmap_grain); 10175 scsi_ulto4b(0x80000000 | lun->be_lun->pblockoff, 10176 bl_ptr->unmap_grain_align); 10177 } |
|
10169 } 10170 } 10171 scsi_u64to8b(UINT64_MAX, bl_ptr->max_write_same_length); 10172 10173 ctsio->scsi_status = SCSI_STATUS_OK; 10174 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 10175 ctsio->be_move_done = ctl_config_move_done; 10176 ctl_datamove((union ctl_io *)ctsio); 10177 10178 return (CTL_RETVAL_COMPLETE); 10179} 10180 10181static int | 10178 } 10179 } 10180 scsi_u64to8b(UINT64_MAX, bl_ptr->max_write_same_length); 10181 10182 ctsio->scsi_status = SCSI_STATUS_OK; 10183 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 10184 ctsio->be_move_done = ctl_config_move_done; 10185 ctl_datamove((union ctl_io *)ctsio); 10186 10187 return (CTL_RETVAL_COMPLETE); 10188} 10189 10190static int |
10191ctl_inquiry_evpd_bdc(struct ctl_scsiio *ctsio, int alloc_len) 10192{ 10193 struct scsi_vpd_block_device_characteristics *bdc_ptr; 10194 struct ctl_lun *lun; 10195 10196 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 10197 10198 ctsio->kern_data_ptr = malloc(sizeof(*bdc_ptr), M_CTL, M_WAITOK | M_ZERO); 10199 bdc_ptr = (struct scsi_vpd_block_device_characteristics *)ctsio->kern_data_ptr; 10200 ctsio->kern_sg_entries = 0; 10201 10202 if (sizeof(*bdc_ptr) < alloc_len) { 10203 ctsio->residual = alloc_len - sizeof(*bdc_ptr); 10204 ctsio->kern_data_len = sizeof(*bdc_ptr); 10205 ctsio->kern_total_len = sizeof(*bdc_ptr); 10206 } else { 10207 ctsio->residual = 0; 10208 ctsio->kern_data_len = alloc_len; 10209 ctsio->kern_total_len = alloc_len; 10210 } 10211 ctsio->kern_data_resid = 0; 10212 ctsio->kern_rel_offset = 0; 10213 ctsio->kern_sg_entries = 0; 10214 10215 /* 10216 * The control device is always connected. The disk device, on the 10217 * other hand, may not be online all the time. Need to change this 10218 * to figure out whether the disk device is actually online or not. 10219 */ 10220 if (lun != NULL) 10221 bdc_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 10222 lun->be_lun->lun_type; 10223 else 10224 bdc_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 10225 bdc_ptr->page_code = SVPD_BDC; 10226 scsi_ulto2b(sizeof(*bdc_ptr) - 4, bdc_ptr->page_length); 10227 scsi_ulto2b(SVPD_NON_ROTATING, bdc_ptr->medium_rotation_rate); 10228 bdc_ptr->flags = SVPD_FUAB | SVPD_VBULS; 10229 10230 ctsio->scsi_status = SCSI_STATUS_OK; 10231 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 10232 ctsio->be_move_done = ctl_config_move_done; 10233 ctl_datamove((union ctl_io *)ctsio); 10234 10235 return (CTL_RETVAL_COMPLETE); 10236} 10237 10238static int |
|
10182ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) 10183{ 10184 struct scsi_vpd_logical_block_prov *lbp_ptr; 10185 struct ctl_lun *lun; 10186 10187 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 10188 10189 ctsio->kern_data_ptr = malloc(sizeof(*lbp_ptr), M_CTL, M_WAITOK | M_ZERO); --- 20 unchanged lines hidden (view full) --- 10210 */ 10211 if (lun != NULL) 10212 lbp_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 10213 lun->be_lun->lun_type; 10214 else 10215 lbp_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 10216 10217 lbp_ptr->page_code = SVPD_LBP; | 10239ctl_inquiry_evpd_lbp(struct ctl_scsiio *ctsio, int alloc_len) 10240{ 10241 struct scsi_vpd_logical_block_prov *lbp_ptr; 10242 struct ctl_lun *lun; 10243 10244 lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 10245 10246 ctsio->kern_data_ptr = malloc(sizeof(*lbp_ptr), M_CTL, M_WAITOK | M_ZERO); --- 20 unchanged lines hidden (view full) --- 10267 */ 10268 if (lun != NULL) 10269 lbp_ptr->device = (SID_QUAL_LU_CONNECTED << 5) | 10270 lun->be_lun->lun_type; 10271 else 10272 lbp_ptr->device = (SID_QUAL_LU_OFFLINE << 5) | T_DIRECT; 10273 10274 lbp_ptr->page_code = SVPD_LBP; |
10218 if (lun != NULL && lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) 10219 lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 | SVPD_LBP_WS10; | 10275 scsi_ulto2b(sizeof(*lbp_ptr) - 4, lbp_ptr->page_length); 10276 if (lun != NULL && lun->be_lun->flags & CTL_LUN_FLAG_UNMAP) { 10277 lbp_ptr->flags = SVPD_LBP_UNMAP | SVPD_LBP_WS16 | 10278 SVPD_LBP_WS10 | SVPD_LBP_RZ | SVPD_LBP_ANC_SUP; 10279 lbp_ptr->prov_type = SVPD_LBP_RESOURCE; 10280 } |
10220 10221 ctsio->scsi_status = SCSI_STATUS_OK; 10222 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 10223 ctsio->be_move_done = ctl_config_move_done; 10224 ctl_datamove((union ctl_io *)ctsio); 10225 10226 return (CTL_RETVAL_COMPLETE); 10227} --- 26 unchanged lines hidden (view full) --- 10254 retval = ctl_inquiry_evpd_scsi_ports(ctsio, alloc_len); 10255 break; 10256 case SVPD_SCSI_TPC: 10257 retval = ctl_inquiry_evpd_tpc(ctsio, alloc_len); 10258 break; 10259 case SVPD_BLOCK_LIMITS: 10260 retval = ctl_inquiry_evpd_block_limits(ctsio, alloc_len); 10261 break; | 10281 10282 ctsio->scsi_status = SCSI_STATUS_OK; 10283 ctsio->io_hdr.flags |= CTL_FLAG_ALLOCATED; 10284 ctsio->be_move_done = ctl_config_move_done; 10285 ctl_datamove((union ctl_io *)ctsio); 10286 10287 return (CTL_RETVAL_COMPLETE); 10288} --- 26 unchanged lines hidden (view full) --- 10315 retval = ctl_inquiry_evpd_scsi_ports(ctsio, alloc_len); 10316 break; 10317 case SVPD_SCSI_TPC: 10318 retval = ctl_inquiry_evpd_tpc(ctsio, alloc_len); 10319 break; 10320 case SVPD_BLOCK_LIMITS: 10321 retval = ctl_inquiry_evpd_block_limits(ctsio, alloc_len); 10322 break; |
10323 case SVPD_BDC: 10324 retval = ctl_inquiry_evpd_bdc(ctsio, alloc_len); 10325 break; |
|
10262 case SVPD_LBP: 10263 retval = ctl_inquiry_evpd_lbp(ctsio, alloc_len); 10264 break; 10265 default: 10266 ctl_set_invalid_field(ctsio, 10267 /*sks_valid*/ 1, 10268 /*command*/ 1, 10269 /*field*/ 2, --- 3839 unchanged lines hidden --- | 10326 case SVPD_LBP: 10327 retval = ctl_inquiry_evpd_lbp(ctsio, alloc_len); 10328 break; 10329 default: 10330 ctl_set_invalid_field(ctsio, 10331 /*sks_valid*/ 1, 10332 /*command*/ 1, 10333 /*field*/ 2, --- 3839 unchanged lines hidden --- |