2
* (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
3
* This code is licenced under the GPL.
5
* heavily based on code from kernel/iscsi.c:
6
* Copyright (C) 2002-2003 Ardis Technolgies <roman@ardistech.com>,
7
* licensed under the terms of the GNU GPL v2.0,
10
#include <linux/ctype.h>
11
#include <scsi/scsi.h>
14
#include "iscsi_dbg.h"
16
static int insert_disconnect_pg(u8 *ptr)
18
unsigned char disconnect_pg[] = {0x02, 0x0e, 0x80, 0x80, 0x00, 0x0a, 0x00, 0x00,
19
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
21
memcpy(ptr, disconnect_pg, sizeof(disconnect_pg));
22
return sizeof(disconnect_pg);
25
static int insert_caching_pg(u8 *ptr, int wcache, int rcache)
27
unsigned char caching_pg[] = {0x08, 0x12, 0x10, 0x00, 0xff, 0xff, 0x00, 0x00,
28
0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0x00, 0x00,
29
0x00, 0x00, 0x00, 0x00};
31
memcpy(ptr, caching_pg, sizeof(caching_pg));
33
ptr[2] |= 0x04; /* set WCE bit if we're caching writes */
35
ptr[2] |= 0x01; /* Read Cache Disable */
37
return sizeof(caching_pg);
40
static int insert_ctrl_m_pg(u8 *ptr)
42
unsigned char ctrl_m_pg[] = {0x0a, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
43
0x00, 0x00, 0x02, 0x4b};
45
memcpy(ptr, ctrl_m_pg, sizeof(ctrl_m_pg));
46
return sizeof(ctrl_m_pg);
49
static int insert_iec_m_pg(u8 *ptr)
51
unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0x00, 0x00, 0x00, 0x00,
52
0x00, 0x00, 0x00, 0x00, 0x00};
54
memcpy(ptr, iec_m_pg, sizeof(iec_m_pg));
55
return sizeof(iec_m_pg);
58
static int insert_format_m_pg(u8 *ptr, u32 sector_size)
60
unsigned char format_m_pg[] = {0x03, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
62
0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00};
64
memcpy(ptr, format_m_pg, sizeof(format_m_pg));
65
ptr[12] = (sector_size >> 8) & 0xff;
66
ptr[13] = sector_size & 0xff;
67
return sizeof(format_m_pg);
70
static int insert_geo_m_pg(u8 *ptr, u64 sec)
72
unsigned char geo_m_pg[] = {0x04, 0x16, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
73
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74
0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00};
78
/* assume 0xff heads, 15krpm. */
79
memcpy(ptr, geo_m_pg, sizeof(geo_m_pg));
80
ncyl = sec >> 14; /* 256 * 64 */
81
memcpy(&n, ptr+1, sizeof(u32));
82
n = n | cpu_to_be32(ncyl);
83
memcpy(ptr+1, &n, sizeof(u32));
84
return sizeof(geo_m_pg);
87
static void build_mode_sense_response(struct iscsi_cmnd *cmnd)
89
struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
90
struct tio *tio = cmnd->tio;
91
u8 *data, *scb = req->scb;
95
/* changeable parameter mode pages are unsupported */
96
if ((scb[2] & 0xc0) >> 6 == 0x1)
99
pcode = req->scb[2] & 0x3f;
102
tio = cmnd->tio = tio_alloc(1);
103
data = page_address(tio->pvec[0]);
107
if (LUReadonly(cmnd->lun))
115
*(u32 *)(data + 4) = (cmnd->lun->blk_cnt >> 32) ?
116
cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt);
117
*(u32 *)(data + 8) = cpu_to_be32(1 << cmnd->lun->blk_shift);
124
len += insert_disconnect_pg(data + len);
127
len += insert_format_m_pg(data + len, 1 << cmnd->lun->blk_shift);
130
len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt);
133
len += insert_caching_pg(data + len, LUWCache(cmnd->lun),
134
LURCache(cmnd->lun));
137
len += insert_ctrl_m_pg(data + len);
140
len += insert_iec_m_pg(data + len);
143
len += insert_disconnect_pg(data + len);
144
len += insert_format_m_pg(data + len, 1 << cmnd->lun->blk_shift);
145
len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt);
146
len += insert_caching_pg(data + len, LUWCache(cmnd->lun),
147
LURCache(cmnd->lun));
148
len += insert_ctrl_m_pg(data + len);
149
len += insert_iec_m_pg(data + len);
157
tio_set(tio, len, 0);
164
/* Invalid Field In CDB */
165
iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
168
static void build_inquiry_response(struct iscsi_cmnd *cmnd)
170
struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
171
struct tio *tio = cmnd->tio;
177
* - CmdDt and EVPD both set or EVPD and Page Code set: illegal
178
* - CmdDt set: not supported
180
if ((scb[1] & 0x3) > 0x1 || (!(scb[1] & 0x3) && scb[2]))
184
tio = cmnd->tio = tio_alloc(1);
185
data = page_address(tio->pvec[0]);
189
if (!(scb[1] & 0x3)) {
194
memset(data + 8, 0x20, 28);
196
VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8));
198
PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16));
200
PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4));
209
} else if (scb[1] & 0x1) {
219
} else if (scb[2] == 0x80) {
223
if (strlen(cmnd->lun->scsi_sn) <= 16)
231
memset(data + 4, 0x20, len);
233
size_t offset = len -
234
strlen(cmnd->lun->scsi_sn);
235
memcpy(data + 4 + offset, cmnd->lun->scsi_sn,
236
strlen(cmnd->lun->scsi_sn));
238
tio_set(tio, len + 4, 0);
240
} else if (scb[2] == 0x83) {
241
u32 len = SCSI_ID_LEN + 8;
248
if (cmnd->lun) { /* We need this ? */
249
memset(data + 8, 0x00, 8);
250
memcpy(data + 8, VENDOR_ID,
251
min_t(size_t, strlen(VENDOR_ID), 8));
252
memcpy(data + 16, cmnd->lun->scsi_id,
255
tio_set(tio, len + 8, 0);
261
tio_set(tio, min_t(u8, tio->size, scb[4]), 0);
263
data[0] = TYPE_NO_LUN;
270
/* Invalid Field In CDB */
271
iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
274
static void build_report_luns_response(struct iscsi_cmnd *cmnd)
276
struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
277
struct tio *tio = cmnd->tio;
278
u32 *data, size, len;
279
struct iet_volume *lun;
282
size = (u32)req->scb[6] << 24 | (u32)req->scb[7] << 16 |
283
(u32)req->scb[8] << 8 | (u32)req->scb[9];
285
/* Invalid Field In CDB */
286
iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
290
len = atomic_read(&cmnd->conn->session->target->nr_volumes) * 8;
291
size = min(size & ~(8 - 1), len + 8);
294
tio = cmnd->tio = tio_alloc(get_pgcnt(size, 0));
295
tio_set(tio, size, 0);
297
data = page_address(tio->pvec[idx]);
299
*data++ = cpu_to_be32(len);
302
rest = PAGE_CACHE_SIZE - 8;
303
list_for_each_entry(lun, &cmnd->conn->session->target->volumes, list) {
304
if (lun->l_state != IDEV_RUNNING)
307
*data++ = cpu_to_be32((0x3ff & lun->lun) << 16 |
308
((lun->lun > 0xff) ? (0x1 << 30) : 0));
310
if ((size -= 8) == 0)
312
if ((rest -= 8) == 0) {
314
data = page_address(tio->pvec[idx]);
315
rest = PAGE_CACHE_SIZE;
320
static void build_read_capacity_response(struct iscsi_cmnd *cmnd)
322
struct tio *tio = cmnd->tio;
326
tio = cmnd->tio = tio_alloc(1);
327
data = page_address(tio->pvec[0]);
331
data[0] = (cmnd->lun->blk_cnt >> 32) ?
332
cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt - 1);
333
data[1] = cpu_to_be32(1U << cmnd->lun->blk_shift);
338
static void build_request_sense_response(struct iscsi_cmnd *cmnd)
340
struct tio *tio = cmnd->tio;
344
tio = cmnd->tio = tio_alloc(1);
345
data = page_address(tio->pvec[0]);
355
static void build_service_action_in_response(struct iscsi_cmnd *cmnd)
357
struct tio *tio = cmnd->tio;
363
/* only READ_CAPACITY_16 service action is currently supported */
364
if ((cmnd_hdr(cmnd)->scb[1] & 0x1F) != 0x10) {
365
/* Invalid Field In CDB */
366
iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
370
tio = cmnd->tio = tio_alloc(1);
371
data = page_address(tio->pvec[0]);
374
data64 = (u64*) data;
375
data64[0] = cpu_to_be64(cmnd->lun->blk_cnt - 1);
376
data[2] = cpu_to_be32(1UL << cmnd->lun->blk_shift);
381
static void build_read_response(struct iscsi_cmnd *cmnd)
383
struct tio *tio = cmnd->tio;
388
if (tio_read(cmnd->lun, tio))
389
/* Medium Error/Unrecovered Read Error */
390
iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x11, 0x0);
393
static void build_write_response(struct iscsi_cmnd *cmnd)
396
struct tio *tio = cmnd->tio;
401
list_del_init(&cmnd->list);
402
err = tio_write(cmnd->lun, tio);
403
if (!err && !LUWCache(cmnd->lun))
404
err = tio_sync(cmnd->lun, tio);
407
/* Medium Error/Write Fault */
408
iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x03, 0x0);
411
static void build_sync_cache_response(struct iscsi_cmnd *cmnd)
414
if (tio_sync(cmnd->lun, NULL))
415
/* Medium Error/Write Fault */
416
iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x03, 0x0);
419
static void build_generic_response(struct iscsi_cmnd *cmnd)
424
static void build_reserve_response(struct iscsi_cmnd *cmnd)
426
switch (volume_reserve(cmnd->lun, cmnd->conn->session->sid)) {
428
/* Logical Unit Not Supported (?) */
429
iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x25, 0x0);
432
cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
439
static void build_release_response(struct iscsi_cmnd *cmnd)
441
int ret = volume_release(cmnd->lun,
442
cmnd->conn->session->sid, 0);
445
/* Logical Unit Not Supported (?) */
446
iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x25, 0x0);
449
cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
456
static void build_reservation_conflict_response(struct iscsi_cmnd *cmnd)
458
cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
461
static int disk_check_ua(struct iscsi_cmnd *cmnd)
463
struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
466
if (cmnd->lun && ua_pending(cmnd->conn->session, cmnd->lun->lun)) {
472
ua = ua_get_match(cmnd->conn->session,
474
/* reported luns data has changed */
479
ua = ua_get_first(cmnd->conn->session, cmnd->lun->lun);
480
iscsi_cmnd_set_sense(cmnd, UNIT_ATTENTION, ua->asc,
483
send_scsi_rsp(cmnd, build_generic_response);
490
static int disk_check_reservation(struct iscsi_cmnd *cmnd)
492
struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
494
int ret = is_volume_reserved(cmnd->lun,
495
cmnd->conn->session->sid);
497
switch (req->scb[0]) {
503
/* allowed commands when reserved */
505
case SERVICE_ACTION_IN:
506
if ((cmnd_hdr(cmnd)->scb[1] & 0x1F) == 0x10)
510
/* return reservation conflict for all others */
512
build_reservation_conflict_response);
520
static int disk_execute_cmnd(struct iscsi_cmnd *cmnd)
522
struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
524
req->opcode &= ISCSI_OPCODE_MASK;
526
if (disk_check_ua(cmnd))
529
if (disk_check_reservation(cmnd))
532
switch (req->scb[0]) {
534
send_data_rsp(cmnd, build_inquiry_response);
537
send_data_rsp(cmnd, build_report_luns_response);
540
send_data_rsp(cmnd, build_read_capacity_response);
543
send_data_rsp(cmnd, build_mode_sense_response);
546
send_data_rsp(cmnd, build_request_sense_response);
548
case SERVICE_ACTION_IN:
549
send_data_rsp(cmnd, build_service_action_in_response);
554
send_data_rsp(cmnd, build_read_response);
560
send_scsi_rsp(cmnd, build_write_response);
562
case SYNCHRONIZE_CACHE:
563
send_scsi_rsp(cmnd, build_sync_cache_response);
566
send_scsi_rsp(cmnd, build_reserve_response);
569
send_scsi_rsp(cmnd, build_release_response);
572
case TEST_UNIT_READY:
575
send_scsi_rsp(cmnd, build_generic_response);
578
eprintk("%s\n", "we should not come here!");
585
struct target_type disk_ops =
588
.execute_cmnd = disk_execute_cmnd,