Deleted Added
full compact
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 ---