1107178Snjl/* 2107178Snjl * SCSI Target Emulator 3107178Snjl * 4107178Snjl * Copyright (c) 2002 Nate Lawson. 5107178Snjl * All rights reserved. 6107178Snjl * 7107178Snjl * Redistribution and use in source and binary forms, with or without 8107178Snjl * modification, are permitted provided that the following conditions 9107178Snjl * are met: 10107178Snjl * 1. Redistributions of source code must retain the above copyright 11107178Snjl * notice, this list of conditions, and the following disclaimer, 12107178Snjl * without modification, immediately at the beginning of the file. 13107178Snjl * 2. The name of the author may not be used to endorse or promote products 14107178Snjl * derived from this software without specific prior written permission. 15107178Snjl * 16107178Snjl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17107178Snjl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18107178Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19107178Snjl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20107178Snjl * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21107178Snjl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22107178Snjl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23107178Snjl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24107178Snjl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25107178Snjl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26107178Snjl * SUCH DAMAGE. 27107178Snjl * 28107178Snjl * $FreeBSD$ 29107178Snjl */ 30107178Snjl 31107178Snjl#ifndef _SCSI_TARGET_H 32107178Snjl#define _SCSI_TARGET_H 33107178Snjl 34107178Snjl/* 35124307Snjl * Maximum number of parallel commands to accept, 36162704Smjacob * 1024 for Fibre Channel (SPI is 16). 37107178Snjl */ 38196955Ssbruno#define MAX_INITIATORS 8 39107178Snjl#define SECTOR_SIZE 512 40107178Snjl#define MAX_EVENTS (MAX_INITIATORS + 5) 41107178Snjl /* kqueue for AIO, signals */ 42107178Snjl 43107178Snjl/* Additional SCSI 3 defines for inquiry response */ 44107178Snjl#define SID_Addr16 0x0100 45107178Snjl 46107178SnjlTAILQ_HEAD(io_queue, ccb_hdr); 47107178Snjl 48107178Snjl/* Offset into the private CCB area for storing our descriptor */ 49107178Snjl#define targ_descr periph_priv.entries[1].ptr 50107178Snjl 51107178Snjl/* Descriptor attached to each ATIO */ 52107178Snjlstruct atio_descr { 53107178Snjl off_t base_off; /* Base offset for ATIO */ 54121184Ssimokawa uint total_len; /* Total xfer len for this ATIO */ 55121184Ssimokawa uint init_req; /* Transfer count requested to/from init */ 56121184Ssimokawa uint init_ack; /* Data transferred ok to/from init */ 57121184Ssimokawa uint targ_req; /* Transfer count requested to/from target */ 58121184Ssimokawa uint targ_ack; /* Data transferred ok to/from target */ 59107178Snjl int flags; /* Flags for CTIOs */ 60107178Snjl u_int8_t *cdb; /* Pointer to received CDB */ 61107178Snjl /* List of completed AIO/CTIOs */ 62107178Snjl struct io_queue cmplt_io; 63107178Snjl}; 64107178Snjl 65107178Snjltypedef enum { 66107178Snjl ATIO_WORK, 67107178Snjl AIO_DONE, 68107178Snjl CTIO_DONE 69107178Snjl} io_ops; 70107178Snjl 71107178Snjl/* Descriptor attached to each CTIO */ 72107178Snjlstruct ctio_descr { 73107178Snjl void *buf; /* Backing store */ 74107178Snjl off_t offset; /* Position in transfer (for file, */ 75107178Snjl /* doesn't start at 0) */ 76107178Snjl struct aiocb aiocb; /* AIO descriptor for this CTIO */ 77107178Snjl struct ccb_accept_tio *atio; 78107178Snjl /* ATIO we are satisfying */ 79107178Snjl io_ops event; /* Event that queued this CTIO */ 80107178Snjl}; 81107178Snjl 82107178Snjltypedef enum { 83107178Snjl UA_NONE = 0x00, 84107178Snjl UA_POWER_ON = 0x01, 85107178Snjl UA_BUS_RESET = 0x02, 86107178Snjl UA_BDR = 0x04 87107178Snjl} ua_types; 88107178Snjl 89107178Snjltypedef enum { 90107178Snjl CA_NONE = 0x00, 91107178Snjl CA_UNIT_ATTN = 0x01, 92107178Snjl CA_CMD_SENSE = 0x02 93107178Snjl} ca_types; 94107178Snjl 95107178Snjlstruct initiator_state { 96107178Snjl ua_types orig_ua; 97107178Snjl ca_types orig_ca; 98107178Snjl ua_types pending_ua; 99107178Snjl ca_types pending_ca; 100107178Snjl struct scsi_sense_data sense_data; 101107178Snjl}; 102107178Snjl 103107178Snjl/* Global functions */ 104107178Snjlextern cam_status tcmd_init(u_int16_t req_inq_flags, 105107178Snjl u_int16_t sim_inq_flags); 106107178Snjlextern int tcmd_handle(struct ccb_accept_tio *atio, 107107178Snjl struct ccb_scsiio *ctio, io_ops event); 108107178Snjlextern void tcmd_sense(u_int init_id, struct ccb_scsiio *ctio, 109107178Snjl u_int8_t flags, 110107178Snjl u_int8_t asc, u_int8_t ascq); 111107178Snjlextern void tcmd_ua(u_int init_id, ua_types new_ua); 112107178Snjlextern int work_atio(struct ccb_accept_tio *atio); 113107178Snjlextern void send_ccb(union ccb *ccb, int priority); 114107178Snjlextern void free_ccb(union ccb *ccb); 115107178Snjlstatic __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); } 116107178Snjl 117162704Smjacob/* Global Data */ 118162704Smjacobextern int notaio; 119162704Smjacob 120162704Smjacob/* 121162704Smjacob * Compat Defines 122162704Smjacob */ 123162704Smjacob#if __FreeBSD_version >= 500000 124162704Smjacob#define OFF_FMT "%ju" 125162704Smjacob#else 126162704Smjacob#define OFF_FMT "%llu" 127162704Smjacob#endif 128162704Smjacob 129107178Snjl#endif /* _SCSI_TARGET_H */ 130