4 * Copyright (C) 2004-2007 Vladislav Bolkhovitin <vst@vlnb.net>
7 * SCSI disk (type 0) dev handler
9 * SCSI disk (type 0) "performance" device handler (skip all READ and WRITE
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, version 2
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include <scsi/scsi_host.h>
27 #define LOG_PREFIX "dev_disk"
30 #include "scst_dev_handler.h"
32 # define DISK_NAME "dev_disk"
33 # define DISK_PERF_NAME "dev_disk_perf"
39 .dev_done_atomic = 1, \
41 .attach = disk_attach, \
42 .detach = disk_detach, \
43 .parse = disk_parse, \
44 .dev_done = disk_done, \
47 #define DISK_PERF_TYPE { \
48 .name = DISK_PERF_NAME, \
51 .dev_done_atomic = 1, \
53 .attach = disk_attach, \
54 .detach = disk_detach, \
55 .parse = disk_parse, \
56 .dev_done = disk_done, \
60 #define DISK_DEF_BLOCK_SHIFT 9
66 int disk_attach(struct scst_device *dev);
67 void disk_detach(struct scst_device *dev);
68 int disk_parse(struct scst_cmd *cmd);
69 int disk_done(struct scst_cmd *cmd);
70 int disk_exec(struct scst_cmd *cmd);
72 static struct scst_dev_type disk_devtype = DISK_TYPE;
73 static struct scst_dev_type disk_devtype_perf = DISK_PERF_TYPE;
75 static int __init init_scst_disk_driver(void)
81 disk_devtype.module = THIS_MODULE;
83 res = scst_register_dev_driver(&disk_devtype);
87 res = scst_dev_handler_build_std_proc(&disk_devtype);
91 disk_devtype_perf.module = THIS_MODULE;
93 res = scst_register_dev_driver(&disk_devtype_perf);
97 res = scst_dev_handler_build_std_proc(&disk_devtype_perf);
106 scst_dev_handler_destroy_std_proc(&disk_devtype_perf);
109 scst_dev_handler_destroy_std_proc(&disk_devtype);
112 scst_unregister_dev_driver(&disk_devtype);
116 static void __exit exit_scst_disk_driver(void)
119 scst_dev_handler_destroy_std_proc(&disk_devtype_perf);
120 scst_unregister_dev_driver(&disk_devtype_perf);
121 scst_dev_handler_destroy_std_proc(&disk_devtype);
122 scst_unregister_dev_driver(&disk_devtype);
127 module_init(init_scst_disk_driver);
128 module_exit(exit_scst_disk_driver);
130 /**************************************************************
131 * Function: disk_attach
135 * Returns : 1 if attached, error code otherwise
138 *************************************************************/
139 int disk_attach(struct scst_device *dev)
143 const int buffer_size = 512;
144 uint8_t *buffer = NULL;
146 unsigned char sense_buffer[SCST_SENSE_BUFFERSIZE];
147 enum dma_data_direction data_dir;
148 unsigned char *sbuff;
149 struct disk_params *params;
153 if (dev->scsi_dev == NULL ||
154 dev->scsi_dev->type != dev->handler->type) {
155 PRINT_ERROR("%s", "SCSI device not define or illegal type");
160 params = kzalloc(sizeof(*params), GFP_KERNEL);
161 if (params == NULL) {
162 TRACE(TRACE_OUT_OF_MEM, "%s",
163 "Unable to allocate struct disk_params");
168 buffer = kmalloc(buffer_size, GFP_KERNEL);
170 TRACE(TRACE_OUT_OF_MEM, "%s", "Memory allocation failure");
172 goto out_free_params;
175 /* Clear any existing UA's and get disk capacity (disk block size) */
176 memset(cmd, 0, sizeof(cmd));
177 cmd[0] = READ_CAPACITY;
178 cmd[1] = (dev->scsi_dev->scsi_level <= SCSI_2) ?
179 ((dev->scsi_dev->lun << 5) & 0xe0) : 0;
180 retries = SCST_DEV_UA_RETRIES;
182 memset(buffer, 0, buffer_size);
183 data_dir = SCST_DATA_READ;
184 sbuff = sense_buffer;
186 TRACE_DBG("%s", "Doing READ_CAPACITY");
187 res = scsi_execute(dev->scsi_dev, cmd, data_dir, buffer,
189 SCST_GENERIC_DISK_REG_TIMEOUT, 3, 0);
191 TRACE_DBG("READ_CAPACITY done: %x", res);
193 if (!res || (sbuff[12] != 0x28 && sbuff[12] != 0x29))
196 PRINT_ERROR("UA not clear after %d retries",
197 SCST_DEV_UA_RETRIES);
203 int sector_size = ((buffer[4] << 24) | (buffer[5] << 16) |
204 (buffer[6] << 8) | (buffer[7] << 0));
205 if (sector_size == 0)
206 params->block_shift = DISK_DEF_BLOCK_SHIFT;
208 params->block_shift = scst_calc_block_shift(sector_size);
210 TRACE_BUFFER("Sense set", sbuff, SCST_SENSE_BUFFERSIZE);
215 res = scst_obtain_device_parameters(dev);
217 PRINT_ERROR("Failed to obtain control parameters for device "
218 "%d:%d:%d:%d", dev->scsi_dev->host->host_no,
219 dev->scsi_dev->channel, dev->scsi_dev->id,
229 dev->dh_priv = params;
238 /************************************************************
239 * Function: disk_detach
245 * Description: Called to detach this device type driver
246 ************************************************************/
247 void disk_detach(struct scst_device *dev)
249 struct disk_params *params =
250 (struct disk_params *)dev->dh_priv;
261 static int disk_get_block_shift(struct scst_cmd *cmd)
263 struct disk_params *params = (struct disk_params *)cmd->dev->dh_priv;
265 * No need for locks here, since *_detach() can not be
266 * called, when there are existing commands.
268 return params->block_shift;
271 /********************************************************************
272 * Function: disk_parse
276 * Returns : The state of the command
278 * Description: This does the parsing of the command
280 * Note: Not all states are allowed on return
281 ********************************************************************/
282 int disk_parse(struct scst_cmd *cmd)
284 int res = SCST_CMD_STATE_DEFAULT;
286 scst_sbc_generic_parse(cmd, disk_get_block_shift);
288 cmd->retries = SCST_PASSTHROUGH_RETRIES;
293 static void disk_set_block_shift(struct scst_cmd *cmd, int block_shift)
295 struct disk_params *params = (struct disk_params *)cmd->dev->dh_priv;
297 * No need for locks here, since *_detach() can not be
298 * called, when there are existing commands.
300 if (block_shift != 0)
301 params->block_shift = block_shift;
303 params->block_shift = DISK_DEF_BLOCK_SHIFT;
307 /********************************************************************
308 * Function: disk_done
314 * Description: This is the completion routine for the command,
315 * it is used to extract any necessary information
317 ********************************************************************/
318 int disk_done(struct scst_cmd *cmd)
320 int res = SCST_CMD_STATE_DEFAULT;
324 res = scst_block_generic_dev_done(cmd, disk_set_block_shift);
330 /********************************************************************
331 * Function: disk_exec
337 * Description: Make SCST do nothing for data READs and WRITES.
338 * Intended for raw line performance testing
339 ********************************************************************/
340 int disk_exec(struct scst_cmd *cmd)
342 int res = SCST_EXEC_NOT_COMPLETED, rc;
343 int opcode = cmd->cdb[0];
347 rc = scst_check_local_events(cmd);
348 if (unlikely(rc != 0))
353 cmd->host_status = DID_OK;
354 cmd->driver_status = 0;
374 res = SCST_EXEC_COMPLETED;
375 cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT);
379 MODULE_AUTHOR("Vladislav Bolkhovitin & Leonid Stoljar");
380 MODULE_LICENSE("GPL");
381 MODULE_DESCRIPTION("SCSI disk (type 0) dev handler for SCST");
382 MODULE_VERSION(SCST_VERSION_STRING);