- Fixes wrongly set context in scst_tgt_cmd_done()
[mirror/scst/.git] / scst / src / dev_handlers / scst_processor.c
1 /*
2  *  scst_processor.c
3  *  
4  *  Copyright (C) 2004-2006 Vladislav Bolkhovitin <vst@vlnb.net>
5  *                 and Leonid Stoljar
6  *
7  *  SCSI medium processor (type 3) dev handler
8  *  
9  *  This program is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU General Public License
11  *  as published by the Free Software Foundation, version 2
12  *  of the License.
13  * 
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  *  GNU General Public License for more details.
18  */
19
20 #define LOG_PREFIX "dev_processor"
21 #include "scst_debug.h"
22 #include "scsi_tgt.h"
23 #include "scst_dev_handler.h"
24
25 #include "scst_debug.c"
26
27 #define PROCESSOR_NAME  "dev_processor"
28
29 #define PROCESSOR_TYPE {        \
30   name:     PROCESSOR_NAME,     \
31   type:     TYPE_PROCESSOR,     \
32   parse_atomic:     1,          \
33 /*  dev_done_atomic:  1,*/              \
34   attach:   processor_attach,   \
35 /*  detach:   processor_detach,*/ \
36   parse:    processor_parse,    \
37 /*  dev_done: processor_done*/  \
38 }
39
40 #define PROCESSOR_RETRIES       2
41 #define PROCESSOR_TIMEOUT      (3 * HZ)
42 #define PROCESSOR_LONG_TIMEOUT (14000 * HZ)
43 #define READ_CAP_LEN          8
44
45 int processor_attach(struct scst_device *);
46 void processor_detach(struct scst_device *);
47 int processor_parse(struct scst_cmd *, const struct scst_info_cdb *);
48 int processor_done(struct scst_cmd *);
49
50 #if defined(DEBUG) || defined(TRACING)
51 unsigned long trace_flag = SCST_DEFAULT_DEV_LOG_FLAGS;
52 #endif
53
54 static struct scst_dev_type processor_devtype = PROCESSOR_TYPE;
55
56 /**************************************************************
57  *  Function:  processor_attach
58  *
59  *  Argument:  
60  *
61  *  Returns :  1 if attached, error code otherwise
62  *
63  *  Description:  
64  *************************************************************/
65 int processor_attach(struct scst_device *dev)
66 {
67         int res = 0;
68         int retries;
69
70         TRACE_ENTRY();
71
72         if (dev->scsi_dev == NULL ||
73             dev->scsi_dev->type != dev->handler->type) {
74                 PRINT_ERROR_PR("%s", "SCSI device not define or illegal type");
75                 res = -ENODEV;
76                 goto out;
77         }
78
79         /*
80          * If the device is offline, don't try to read capacity or any
81          * of the other stuff
82          */
83         if (dev->scsi_dev->sdev_state == SDEV_OFFLINE)
84         {
85                 TRACE_DBG("%s", "Device is offline");
86                 res = -ENODEV;
87                 goto out;
88         }
89
90         retries = SCST_DEV_UA_RETRIES;
91         do {
92                 TRACE_DBG("%s", "Doing TEST_UNIT_READY");
93                 res = scsi_test_unit_ready(dev->scsi_dev, PROCESSOR_TIMEOUT, 
94                                            PROCESSOR_RETRIES);
95                 TRACE_DBG("TEST_UNIT_READY done: %x", res);
96         } while ((--retries > 0) && res);
97         if (res) 
98                 res = -ENODEV;
99
100 out:
101         TRACE_EXIT();
102         return res;
103 }
104
105 /************************************************************
106  *  Function:  processor_detach
107  *
108  *  Argument: 
109  *
110  *  Returns :  None
111  *
112  *  Description:  Called to detach this device type driver
113  ************************************************************/
114 void processor_detach(struct scst_device *dev)
115 {
116         TRACE_ENTRY();
117
118         TRACE_EXIT();
119         return;
120 }
121
122 /********************************************************************
123  *  Function:  processor_parse
124  *
125  *  Argument:  
126  *
127  *  Returns :  The state of the command
128  *
129  *  Description:  This does the parsing of the command
130  *
131  *  Note:  Not all states are allowed on return
132  ********************************************************************/
133 int processor_parse(struct scst_cmd *cmd, const struct scst_info_cdb *info_cdb)
134 {
135         int res = SCST_CMD_STATE_DEFAULT;
136
137         TRACE_ENTRY();
138
139         /*
140          * SCST sets good defaults for cmd->data_direction and cmd->bufflen
141          * based on info_cdb, therefore change them only if necessary
142          */
143
144         cmd->retries = 1;
145
146         if (info_cdb->flags & SCST_LONG_TIMEOUT) {
147                 cmd->timeout = PROCESSOR_LONG_TIMEOUT;
148         } else {
149                 cmd->timeout = PROCESSOR_TIMEOUT;
150         }
151
152         TRACE_DBG("op_name <%s> direct %d flags %d transfer_len %d",
153               info_cdb->op_name,
154               info_cdb->direction, info_cdb->flags, info_cdb->transfer_len);
155 #if 0
156         switch (cmd->cdb[0]) {
157         default:
158                 /* It's all good */
159                 break;
160         }
161 #endif
162         TRACE_DBG("res %d bufflen %zd direct %d",
163               res, cmd->bufflen, cmd->data_direction);
164
165         TRACE_EXIT();
166
167         return res;
168 }
169
170 /********************************************************************
171  *  Function:  processor_done
172  *
173  *  Argument:  
174  *
175  *  Returns :  
176  *
177  *  Description:  This is the completion routine for the command,
178  *                it is used to extract any necessary information
179  *                about a command. 
180  ********************************************************************/
181 int processor_done(struct scst_cmd *cmd)
182 {
183         int res = SCST_CMD_STATE_DEFAULT;
184
185         TRACE_ENTRY();
186
187         if (unlikely(cmd->sg == NULL))
188                 goto out;
189
190         /*
191          * SCST sets good defaults for cmd->tgt_resp_flags and cmd->resp_data_len
192          * based on cmd->masked_status and cmd->data_direction, therefore change
193          * them only if necessary
194          */
195
196 #if 0
197         switch (cmd->cdb[0]) {
198         default:
199                 /* It's all good */
200                 break;
201         }
202 #endif
203
204 out:
205         TRACE_EXIT();
206         return res;
207 }
208
209 static int __init processor_init(void)
210 {
211         int res = 0;
212
213         TRACE_ENTRY();
214         
215         processor_devtype.module = THIS_MODULE;
216         if (scst_register_dev_driver(&processor_devtype) < 0) {
217                 res = -ENODEV;
218                 goto out;
219         }
220         
221         res = scst_dev_handler_build_std_proc(&processor_devtype);
222         if (res != 0)
223                 goto out_err;
224
225 out:
226         TRACE_EXIT_RES(res);
227         return res;
228
229 out_err:
230         scst_unregister_dev_driver(&processor_devtype);
231         goto out;
232 }
233
234 static void __exit processor_exit(void)
235 {
236         TRACE_ENTRY();
237         scst_dev_handler_destroy_std_proc(&processor_devtype);
238         scst_unregister_dev_driver(&processor_devtype);
239         TRACE_EXIT();
240         return;
241 }
242
243 module_init(processor_init);
244 module_exit(processor_exit);
245
246 MODULE_LICENSE("GPL");