1/*-
2 * Copyright (c) 2004 Silicon Graphics International Corp.
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
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions, and the following disclaimer,
10 *    without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 *    substantially similar to the "NO WARRANTY" disclaimer below
13 *    ("Disclaimer") and any redistribution must be conditioned upon
14 *    including a substantially similar Disclaimer requirement for further
15 *    binary redistribution.
16 *
17 * NO WARRANTY
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGES.
29 *
30 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_frontend_internal.h#1 $
31 * $FreeBSD$
32 */
33/*
34 * CTL kernel internal frontend target driver.  This allows kernel-level
35 * clients to send commands into CTL.
36 *
37 * Author: Ken Merry <ken@FreeBSD.org>
38 */
39
40#ifndef	_CTL_FRONTEND_INTERNAL_H_
41#define	_CTL_FRONTEND_INTERNAL_H_
42
43/*
44 * These are general metatask error codes.  If the error code is CFI_MT_ERROR,
45 * check any metatask-specific status codes for more detail on the problem.
46 */
47typedef enum {
48	CFI_MT_NONE,
49	CFI_MT_PORT_OFFLINE,
50	CFI_MT_ERROR,
51	CFI_MT_SUCCESS
52} cfi_mt_status;
53
54typedef enum {
55	CFI_TASK_NONE,
56	CFI_TASK_SHUTDOWN,
57	CFI_TASK_STARTUP,
58	CFI_TASK_BBRREAD
59} cfi_tasktype;
60
61struct cfi_task_startstop {
62	int total_luns;
63	int luns_complete;
64	int luns_failed;
65};
66
67/*
68 * Error code description:
69 * CFI_BBR_SUCCESS          - the read was successful
70 * CFI_BBR_LUN_UNCONFIG     - CFI probe for this lun hasn't completed
71 * CFI_BBR_NO_LUN           - this lun doesn't exist, as far as CFI knows
72 * CFI_BBR_NO_MEM           - memory allocation error
73 * CFI_BBR_BAD_LEN          - data length isn't a multiple of the blocksize
74 * CFI_BBR_RESERV_CONFLICT  - another initiator has this lun reserved, so
75 *                            we can't issue I/O at all.
76 * CFI_BBR_LUN_STOPPED      - the lun is powered off.
77 * CFI_BBR_LUN_OFFLINE_CTL  - the lun is offline from a CTL standpoint
78 * CFI_BBR_LUN_OFFLINE_RC   - the lun is offline from a RAIDCore standpoint.
79 *                            This is bad, because it basically means we've
80 *                            had a double failure on the LUN.
81 * CFI_BBR_SCSI_ERROR       - generic SCSI error, see status byte and sense
82 *                            data for more resolution if you want it.
83 * CFI_BBR_ERROR            - the catch-all error code.
84 */
85typedef enum {
86	CFI_BBR_SUCCESS,
87	CFI_BBR_LUN_UNCONFIG,
88	CFI_BBR_NO_LUN,
89	CFI_BBR_NO_MEM,
90	CFI_BBR_BAD_LEN,
91	CFI_BBR_RESERV_CONFLICT,
92	CFI_BBR_LUN_STOPPED,
93	CFI_BBR_LUN_OFFLINE_CTL,
94	CFI_BBR_LUN_OFFLINE_RC,
95	CFI_BBR_SCSI_ERROR,
96	CFI_BBR_ERROR,
97} cfi_bbrread_status;
98
99struct cfi_task_bbrread {
100	int			lun_num;      /* lun number */
101	uint64_t		lba;          /* logical block address */
102	int			len;          /* length in bytes */
103	cfi_bbrread_status	status;       /* BBR status */
104	uint8_t			scsi_status;  /* SCSI status */
105	struct scsi_sense_data	sense_data;   /* SCSI sense data */
106};
107
108union cfi_taskinfo {
109	struct cfi_task_startstop startstop;
110	struct cfi_task_bbrread bbrread;
111};
112
113struct cfi_metatask;
114
115typedef void (*cfi_cb_t)(void *arg, struct cfi_metatask *metatask);
116
117struct cfi_metatask {
118	cfi_tasktype		tasktype;	/* passed to CFI */
119	cfi_mt_status		status;		/* returned from CFI */
120	union cfi_taskinfo	taskinfo;	/* returned from CFI */
121	struct ctl_mem_element	*element;	/* used by CFI, don't touch*/
122	cfi_cb_t		callback;	/* passed to CFI */
123	void			*callback_arg;	/* passed to CFI */
124	STAILQ_ENTRY(cfi_metatask) links;	/* used by CFI, don't touch*/
125};
126
127#ifdef _KERNEL
128
129MALLOC_DECLARE(M_CTL_CFI);
130
131/*
132 * This is the API for sending meta commands (commands that are sent to more
133 * than one LUN) to the internal frontend:
134 *  - Allocate a metatask using cfi_alloc_metatask().  can_wait == 0 means
135 *    that you're calling from an interrupt context.  can_wait == 1 means
136 *    that you're calling from a thread context and don't mind waiting to
137 *    allocate memory.
138 *  - Setup the task type, callback and callback argument.
139 *  - Call cfi_action().
140 *  - When the callback comes, note the status and any per-command status
141 *    (see the taskinfo union) and then free the metatask with
142 *    cfi_free_metatask().
143 */
144struct cfi_metatask *cfi_alloc_metatask(int can_wait);
145void cfi_free_metatask(struct cfi_metatask *metatask);
146void cfi_action(struct cfi_metatask *metatask);
147
148#endif /* _KERNEL */
149
150#endif	/* _CTL_FRONTEND_INTERNAL_H_ */
151
152/*
153 * vim: ts=8
154 */
155