Emulex Logo
OneCore™ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_ramd.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @file
35  * SCSI RAMD target-service declarations.
36  */
37 
38 #if !defined(__OCS_RAMD_H__)
39 #define __OCS_RAMD_H__
40 
41 #include "ocs_ramdisc.h"
42 #include "ocs_dif.h"
43 #include "scsi_asc_ascq.h"
44 #include "ocs_ramd_thread.h"
45 
46 /* Command error codes */
47 
48 /* Sense Keys */
49 #define SNS_ILLEGAL_REQ 0x05 /* sense key is byte 3 ([2]) */
50 #define SNS_UNIT_ATTENTION 0x06
51 #define SNS_ABORTED_CMD 0x0B /* sense key - aborted command */
52 
53 /* Additional Sense Codes */
54 #define SNSCODE_INV_CMDIU 0x0E /* INVALID FIELD IN COMMAND IU */
55 #define SNSCODE_DIF_ERR 0x10 /* ID CRC OR ECC ERROR */
56 #define SNSCODE_BAD_CMD 0x20 /* INVALID COMMAND OPERATION CODE */
57 #define SNSCODE_LBA_OOR 0x21 /* LOGICAL BLOCK ADDRESS OUT OF RANGE */
58 #define SNSCODE_INV_CDB 0x24 /* INVALID FIELD IN CDB */
59 #define SNSCODE_INV_PRM 0x26 /* INVALID FIELD IN PARAMETER LIST */
60 #define SNSCODE_ABORTED_CMD 0x47 /* Aborted command */
61 #define SNSCODE_OFF_ERR 0x4B /* DATA PHASE ERROR */
62 #define SNSCODE_SAVE_NOT_SUPPORTED 0x39 /* SAVING PARAMETERS NOT SUPPORTED */
63 
64 /* Additional Sense Code Qualifiers */
65 #define SNSCODEQUAL_INV_CMDIU 0x03 /* INVALID FIELD IN COMMAND IU */
66 
67 
68 #define scsi_pack_result(key, code, qualifier) (((key & 0xff) << 16) | ((code && 0xff) << 8) | (qualifier & 0xff))
69 
70 /* Handler return codes */
71 typedef enum {
79 
80 extern int32_t _ocs_scsi_recv_cmd(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags);
81 extern int32_t ocs_scsi_recv_cmd_common(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags,
82  uint8_t has_first_burst,
83  ocs_dma_t first_burst_buffers[], uint32_t first_burst_bytes);
84 extern ocs_ramd_hndlr_rtn_e ocs_ramd_check_cond(ocs_io_t *io, uint8_t sense_key, uint8_t asc, uint8_t ascq);
86 extern ocs_ramd_hndlr_rtn_e ocs_ramd_good_status(ocs_io_t *io);
87 int32_t scsi_io_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg);
88 int32_t _scsi_io_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg);
89 extern int32_t scsi_dataphase_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg);
90 extern int32_t _scsi_dataphase_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg);
91 extern ocs_ramdisc_t *ocs_ramd_lookup(ocs_io_t *io, uint32_t lun);
92 extern ocs_ramdisc_t *ocs_ramd_lookup_by_tgt(ocs_t *ocs, uint32_t tgt, uint32_t lun);
93 extern void ocs_ramd_post_ua(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint8_t asc, uint8_t ascq, ocs_node_t *except_node);
94 extern int32_t ocs_ramd_get_ua(ocs_t *ocs, ocs_node_t *node, uint32_t lun, uint8_t *asc, uint8_t *ascq);
95 extern void ocs_ramd_clear_ua(ocs_t *ocs, ocs_node_t *node, uint32_t lun, uint8_t asc, uint8_t ascq);
96 
97 /* exported from mode_sense6.c */
98 extern ocs_ramd_hndlr_rtn_e ocs_ramd_mode_sense6(ocs_io_t *io, uint8_t cdb[]);
99 extern ocs_ramd_hndlr_rtn_e ocs_ramd_mode_sense10(ocs_io_t *io, uint8_t cdb[]);
100 
101 extern int32_t ocs_port_rdisc_init(ocs_t *ocs);
102 extern void ocs_port_rdisc_free(ocs_t *ocs);
103 extern int32_t ocs_port_rdisc_find(ocs_t *ocs, uint32_t tgt_id, ocs_ramdisc_t ***rdisc, uint32_t *rdisc_count);
104 extern int32_t ocs_port_rdisc_save(ocs_t *ocs, uint32_t tgt_id, ocs_ramdisc_t **rdisc, uint32_t rdisc_count);
105 
106 #endif // __OCS_RAMD_H__
107 
108 
109 /**
110  * @page ramd_api_overview Back-end Target (RAMD) APIs and State Machine Functions
111  * - @ref scsi_api_target
112  * - @ref scsi_cmd
113  * - @ref io_sm
114  * - @ref ramdisc
115  *
116  * <div class="overview">
117  * <img src="elx_ramd_tgt.jpg" alt="RAMD" title="RAMD" align="right"/>
118  *
119  * <h2>Target (RAMD)</h2>
120  * The RAMD target of the OneCore Storage driver
121  * implements a non-persistent RAM drive. The driver implements a number of SCSI commands,
122  * and appears to initiators as a valid SCSI block device.<br><br>
123  *
124  * The RAMD consists of four main components: the SCSI Target, SCSI
125  * Command Processing, RAMD Target IO State Machine, and the
126  * RAMdisc.<br><br>
127  *
128  * When the driver is initially loaded, there is a driver-wide
129  * initialization for the RAMD (ocs_scsi_tgt_driver_init()).
130  * After the driver is loaded, the devices are enumerated. The
131  * ocs_pci_probe() function calls ocs_scsi_tgt_new_device()
132  * to create a new SCSI target.<br><br>
133  *
134  * Memory is allocated to hold the data for a ramdisc instance(s),
135  * also called a LUN(s). Each default ramdisc instance (LUN) is 50 MB, consisting of 512-byte
136  * blocks. This 50 MB area is further divided into segments of 64K,
137  * resulting in a default ramdisc instance size up to 800 segments,
138  * each with 128 blocks.
139  * The ramdisc size and ramdisc block size can be changed using the
140  * ramdisc_size and ramdisc_blocksize module parameters.
141  * The ramdisc block size can be also changed using the FORMAT UNIT SCSI command,
142  * but reverts to 512-byte blocks if the driver is reloaded.<br><br>
143  *
144  * Once initialized, the target performs the following functions:
145  * <ul><li>Command parsing – commands are received as unsolicited FCP frames and the
146  * CDB opcode is parsed.</li>
147  * <li>Command dispatch – a table of SCSI command handler functions determines
148  * the specific functions that are called to handle the specific commands.</li>
149  * <li>Data transport – for SCSI READ and SCSI WRITE commands, data is DMA’d
150  * directly to and from the memory buffers of the RAM drive.</li>
151  * <li>Acts as a SCSI block device – SCSI configuration and informational
152  * commands such as TEST UNIT READY, INQUIRY, MODE SELECT, and
153  * MODE SENSE are implemented to allow the driver to respond, as if it were an
154  * actual SCSI block device.</li></ul>
155  *
156  * To exit, the ocs_scsi_tgt_driver_exit() is called when the driver is unloaded (which
157  * occurs after ocs_scsi_tgt_del_device()).
158  *
159  * <h3>Supported SCSI Commands</h3>
160  * <ul><li>FORMAT UNIT</li>
161  * <li>INQUIRY (Standard Inquiry, VPD pages 0x00, 0x80, 0x83, 0x86)</li>
162  * <li>MODE SELECT (6), MODE SELECT 10 (for setting block size)</li>
163  * <li>MODE SENSE (6) (limited pages), MODE SENSE (10) (limited pages)</li>
164  * <li>READ (6), READ (10), READ (12), READ (16), READ (32)</li>
165  * <li>READ CAPACITY (10), READ CAPACITY (16)</li>
166  * <li>READ LONG (10), READ LONG (16)</li>
167  * <li>REPORT LUNS</li>
168  * <li>REQUEST SENSE</li>
169  * <li>TEST UNIT READY</li>
170  * <li>WRITE (6), WRITE (10), WRITE (12), WRITE (16), WRITE (32)</li>
171  * <li>WRITE AND VERIFY (10), WRITE AND VERIFY (12), WRITE AND VERIFY (16)</li>
172  * <li>WRITE LONG (10), WRITE LONG (16)</li>
173  * <li>WRITE SAME (10), WRITE SAME (16), WRITE SAME (32)</li></ul>
174  * </div><!-- overview -->
175  */
176 
int32_t ocs_port_rdisc_init(ocs_t *ocs)
Initialize per port ramdisc structure.
Definition: ocs_ramd.c:7140
int32_t _scsi_io_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Response phase callback.
Definition: ocs_ramd.c:2846
void ocs_ramd_clear_ua(ocs_t *ocs, ocs_node_t *node, uint32_t lun, uint8_t asc, uint8_t ascq)
Clear a Unit Attention condition.
Definition: ocs_ramd.c:6945
int32_t _ocs_scsi_recv_cmd(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags)
Receive an FCP SCSI command.
Definition: ocs_ramd.c:1207
int32_t _scsi_dataphase_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
Command data phase callback.
Definition: ocs_ramd.c:2875
ramdisc instance structure
Definition: ocs_ramdisc.h:88
int32_t ocs_ramd_get_ua(ocs_t *ocs, ocs_node_t *node, uint32_t lun, uint8_t *asc, uint8_t *ascq)
Get a pending Unit Attention, if any.
Definition: ocs_ramd.c:6899
int32_t ocs_scsi_recv_cmd_common(ocs_io_t *io, uint32_t lun, uint8_t *cdb, uint32_t cdb_len, uint32_t flags, uint8_t has_first_burst, ocs_dma_t first_burst_buffers[], uint32_t first_burst_bytes)
Common code used by ocs_scsi_recv_cmd() and ocs_scsi_recv_cmd_first_burst().
Definition: ocs_ramd.c:1302
ocs_ramd_hndlr_rtn_e ocs_ramd_mode_sense10(ocs_io_t *io, uint8_t cdb[])
Process SCSI Mode Sense 10 command.
Definition: mode_sense.c:396
int32_t ocs_port_rdisc_save(ocs_t *ocs, uint32_t tgt_id, ocs_ramdisc_t **rdisc, uint32_t rdisc_count)
Save a per port ramdisc.
Definition: ocs_ramd.c:7220
void ocs_ramd_post_ua(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint8_t asc, uint8_t ascq, ocs_node_t *except_node)
Post a Unit Attention condition to a ramdisc.
Definition: ocs_ramd.c:6826
ocs_ramd_hndlr_rtn_e ocs_ramd_mode_sense6(ocs_io_t *io, uint8_t cdb[])
Process SCSI Mode Sense 6 command.
Definition: mode_sense.c:379
ocs_ramdisc_t * ocs_ramd_lookup_by_tgt(ocs_t *ocs, uint32_t tgt, uint32_t lun)
Given an TGT number and a LUN number, return the corresponding ramdisc.
Definition: ocs_ramd.c:519
ocs_ramd_hndlr_rtn_e
Definition: ocs_ramd.h:71
ocs_ramdisc_t * ocs_ramd_lookup(ocs_io_t *io, uint32_t lun)
Given an IO and a LUN number, return the ramdisc to which the IO is directed.
Definition: ocs_ramd.c:471
int32_t scsi_io_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
ocs_ramd_hndlr_rtn_e ocs_ramd_check_cond(ocs_io_t *io, uint8_t sense_key, uint8_t asc, uint8_t ascq)
Send a SCSI check condition.
Definition: ocs_ramd.c:2551
void ocs_port_rdisc_free(ocs_t *ocs)
Free per port ramdisc structure.
Definition: ocs_ramd.c:7158
int32_t ocs_port_rdisc_find(ocs_t *ocs, uint32_t tgt_id, ocs_ramdisc_t ***rdisc, uint32_t *rdisc_count)
Find a per port ramdisc instance.
Definition: ocs_ramd.c:7188
ocs_scsi_io_status_e
Definition: ocs_scsi.h:105
ocs_ramd_hndlr_rtn_e ocs_ramd_task_set_full_or_busy(ocs_io_t *io)
Send a SCSI task set full or busy status.
Definition: ocs_ramd.c:2599
int32_t scsi_dataphase_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg)
ocs_ramd_hndlr_rtn_e ocs_ramd_good_status(ocs_io_t *io)
Send a good SCSI status.
Definition: ocs_ramd.c:2519