mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-17 10:41:26 +00:00
- First step to SCSI_ID support
- Set correct response data length for emulated commands. Mostly done by Ming Zhang. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@59 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -51,6 +51,8 @@
|
||||
#define READ_CAP_LEN 8
|
||||
#define READ_CAP16_LEN 32
|
||||
|
||||
#define MAX_USN_LEN 20
|
||||
|
||||
#define BYTCHK 0x02
|
||||
|
||||
#define INQ_BUF_SZ 128
|
||||
@@ -100,6 +102,7 @@ struct scst_fileio_dev {
|
||||
char name[16+1]; /* Name of virtual device,
|
||||
must be <= SCSI Model + 1 */
|
||||
char *file_name; /* File name */
|
||||
char *usn;
|
||||
struct list_head fileio_dev_list_entry;
|
||||
struct list_head ftgt_list;
|
||||
struct semaphore ftgt_list_mutex;
|
||||
@@ -863,7 +866,6 @@ static inline void fileio_queue_cmd(struct scst_cmd *cmd)
|
||||
wake_up(&ftgt_dev->fdev_waitQ);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************************
|
||||
* Function: disk_fileio_exec
|
||||
*
|
||||
@@ -1136,7 +1138,7 @@ out:
|
||||
|
||||
static void fileio_exec_inquiry(struct scst_cmd *cmd)
|
||||
{
|
||||
int32_t length, len, i;
|
||||
int32_t length, len, i, resp_len = 0;
|
||||
uint8_t *address;
|
||||
uint8_t *buf;
|
||||
struct scst_fileio_dev *virt_dev =
|
||||
@@ -1169,7 +1171,6 @@ static void fileio_exec_inquiry(struct scst_cmd *cmd)
|
||||
|
||||
/*
|
||||
* ToDo: write through/back flags as well as read only one.
|
||||
* Also task queue size should be set on some value.
|
||||
*/
|
||||
|
||||
if (cmd->cdb[1] & CMDDT) {
|
||||
@@ -1199,10 +1200,23 @@ static void fileio_exec_inquiry(struct scst_cmd *cmd)
|
||||
buf[4] = 0x0; /* this page */
|
||||
buf[5] = 0x80; /* unit serial number */
|
||||
buf[6] = 0x83; /* device identification */
|
||||
resp_len = buf[3] + 4;
|
||||
} else if (0x80 == cmd->cdb[2]) { /* unit serial number */
|
||||
buf[1] = 0x80;
|
||||
buf[3] = len;
|
||||
memcpy(&buf[4], dev_id_str, len);
|
||||
if (virt_dev->usn == NULL) {
|
||||
buf[3] = MAX_USN_LEN;
|
||||
memset(&buf[4], 0x20, MAX_USN_LEN);
|
||||
} else {
|
||||
int usn_len;
|
||||
|
||||
if (strlen(virt_dev->usn) > MAX_USN_LEN)
|
||||
usn_len = MAX_USN_LEN;
|
||||
else
|
||||
usn_len = len;
|
||||
buf[3] = usn_len;
|
||||
strncpy(&buf[4], virt_dev->usn, usn_len);
|
||||
}
|
||||
resp_len = buf[3] + 4;
|
||||
} else if (0x83 == cmd->cdb[2]) { /* device identification */
|
||||
int num = 4;
|
||||
|
||||
@@ -1234,7 +1248,8 @@ static void fileio_exec_inquiry(struct scst_cmd *cmd)
|
||||
buf[num + 10] = (dev_id_num >> 8) & 0xff;
|
||||
buf[num + 11] = dev_id_num & 0xff;
|
||||
|
||||
buf[3] = num + 12 - 4;
|
||||
*((u16*)&buf[2]) = cpu_to_be16(num + 12 - 4);
|
||||
resp_len = be16_to_cpu(*((u16*)&buf[2])) + 4;
|
||||
} else {
|
||||
TRACE_DBG("INQUIRY: Unsupported EVPD page %x",
|
||||
cmd->cdb[2]);
|
||||
@@ -1266,12 +1281,18 @@ static void fileio_exec_inquiry(struct scst_cmd *cmd)
|
||||
|
||||
/* 4 byte ASCII Product Revision Level of the target - left aligned */
|
||||
memcpy(&buf[32], SCST_FIO_REV, 4);
|
||||
resp_len = buf[4] + 5;
|
||||
}
|
||||
|
||||
memcpy(address, buf, length < INQ_BUF_SZ ? length : INQ_BUF_SZ);
|
||||
|
||||
sBUG_ON(resp_len >= INQ_BUF_SZ);
|
||||
if (length > resp_len)
|
||||
length = resp_len;
|
||||
memcpy(address, buf, length);
|
||||
|
||||
out_put:
|
||||
scst_put_buf(cmd, address);
|
||||
if (length < cmd->resp_data_len)
|
||||
scst_set_resp_data_len(cmd, length);
|
||||
|
||||
out_free:
|
||||
kfree(buf);
|
||||
@@ -1377,7 +1398,7 @@ static void fileio_exec_mode_sense(struct scst_cmd *cmd)
|
||||
unsigned char dbd, type;
|
||||
int pcontrol, pcode, subpcode;
|
||||
unsigned char dev_spec;
|
||||
int msense_6, offset, len;
|
||||
int msense_6, offset = 0, len;
|
||||
unsigned char *bp;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -1506,10 +1527,14 @@ static void fileio_exec_mode_sense(struct scst_cmd *cmd)
|
||||
buf[1] = (offset - 2) & 0xff;
|
||||
}
|
||||
|
||||
memcpy(address, buf, min(length, offset));
|
||||
|
||||
if (offset > length)
|
||||
offset = length;
|
||||
memcpy(address, buf, offset);
|
||||
|
||||
out_put:
|
||||
scst_put_buf(cmd, address);
|
||||
if (offset < cmd->resp_data_len)
|
||||
scst_set_resp_data_len(cmd, offset);
|
||||
|
||||
out_free:
|
||||
kfree(buf);
|
||||
@@ -1681,10 +1706,15 @@ static void fileio_exec_read_capacity(struct scst_cmd *cmd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(address, buffer, length < READ_CAP_LEN ? length : READ_CAP_LEN);
|
||||
|
||||
if (length > READ_CAP_LEN)
|
||||
length = READ_CAP_LEN;
|
||||
memcpy(address, buffer, length);
|
||||
|
||||
scst_put_buf(cmd, address);
|
||||
|
||||
if (length < cmd->resp_data_len)
|
||||
scst_set_resp_data_len(cmd, length);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
@@ -1722,11 +1752,15 @@ static void fileio_exec_read_capacity16(struct scst_cmd *cmd)
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(address, buffer, length < READ_CAP16_LEN ?
|
||||
length : READ_CAP16_LEN);
|
||||
|
||||
if (length > READ_CAP16_LEN)
|
||||
length = READ_CAP16_LEN;
|
||||
memcpy(address, buffer, length);
|
||||
|
||||
scst_put_buf(cmd, address);
|
||||
|
||||
if (length < cmd->resp_data_len)
|
||||
scst_set_resp_data_len(cmd, length);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
@@ -1805,10 +1839,15 @@ static void fileio_exec_read_toc(struct scst_cmd *cmd)
|
||||
|
||||
buffer[1] = off - 2; /* Data Length */
|
||||
|
||||
memcpy(address, buffer, (length < off) ? length : off);
|
||||
|
||||
if (off > length)
|
||||
off = length;
|
||||
memcpy(address, buffer, off);
|
||||
|
||||
scst_put_buf(cmd, address);
|
||||
|
||||
if (off < cmd->resp_data_len)
|
||||
scst_set_resp_data_len(cmd, off);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
@@ -3094,12 +3133,6 @@ static void __exit exit_scst_fileio_driver(void)
|
||||
{
|
||||
exit_scst_fileio(&disk_devtype_fileio, &disk_fileio_dev_list);
|
||||
exit_scst_fileio(&cdrom_devtype_fileio, &cdrom_fileio_dev_list);
|
||||
|
||||
/*
|
||||
* Wait for one sec. to allow the thread(s) actually exit,
|
||||
* otherwise we can get Oops. Any better way?
|
||||
*/
|
||||
schedule_timeout(HZ);
|
||||
}
|
||||
|
||||
module_init(init_scst_fileio_driver);
|
||||
|
||||
Reference in New Issue
Block a user