~ubuntu-branches/ubuntu/quantal/linux-linaro-mx51/quantal

« back to all changes in this revision

Viewing changes to ubuntu/iscsitarget/target_disk.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-3o58a3c1bj7x00rs
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * (C) 2004 - 2005 FUJITA Tomonori <tomof@acm.org>
3
 
 * This code is licenced under the GPL.
4
 
 *
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,
8
 
 */
9
 
 
10
 
#include <linux/ctype.h>
11
 
#include <scsi/scsi.h>
12
 
 
13
 
#include "iscsi.h"
14
 
#include "iscsi_dbg.h"
15
 
 
16
 
static int insert_disconnect_pg(u8 *ptr)
17
 
{
18
 
        unsigned char disconnect_pg[] = {0x02, 0x0e, 0x80, 0x80, 0x00, 0x0a, 0x00, 0x00,
19
 
                                         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
20
 
 
21
 
        memcpy(ptr, disconnect_pg, sizeof(disconnect_pg));
22
 
        return sizeof(disconnect_pg);
23
 
}
24
 
 
25
 
static int insert_caching_pg(u8 *ptr, int wcache, int rcache)
26
 
{
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};
30
 
 
31
 
        memcpy(ptr, caching_pg, sizeof(caching_pg));
32
 
        if (wcache)
33
 
                ptr[2] |= 0x04; /* set WCE bit if we're caching writes */
34
 
        if (!rcache)
35
 
                ptr[2] |= 0x01; /* Read Cache Disable */
36
 
 
37
 
        return sizeof(caching_pg);
38
 
}
39
 
 
40
 
static int insert_ctrl_m_pg(u8 *ptr)
41
 
{
42
 
        unsigned char ctrl_m_pg[] = {0x0a, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
43
 
                                     0x00, 0x00, 0x02, 0x4b};
44
 
 
45
 
        memcpy(ptr, ctrl_m_pg, sizeof(ctrl_m_pg));
46
 
        return sizeof(ctrl_m_pg);
47
 
}
48
 
 
49
 
static int insert_iec_m_pg(u8 *ptr)
50
 
{
51
 
        unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0x00, 0x00, 0x00, 0x00,
52
 
                                    0x00, 0x00, 0x00, 0x00, 0x00};
53
 
 
54
 
        memcpy(ptr, iec_m_pg, sizeof(iec_m_pg));
55
 
        return sizeof(iec_m_pg);
56
 
}
57
 
 
58
 
static int insert_format_m_pg(u8 *ptr, u32 sector_size)
59
 
{
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};
63
 
 
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);
68
 
}
69
 
 
70
 
static int insert_geo_m_pg(u8 *ptr, u64 sec)
71
 
{
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};
75
 
        u32 ncyl;
76
 
        u32 n;
77
 
 
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);
85
 
}
86
 
 
87
 
static void build_mode_sense_response(struct iscsi_cmnd *cmnd)
88
 
{
89
 
        struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
90
 
        struct tio *tio = cmnd->tio;
91
 
        u8 *data, *scb = req->scb;
92
 
        int len = 4, err = 0;
93
 
        u8 pcode;
94
 
 
95
 
        /* changeable parameter mode pages are unsupported */
96
 
        if ((scb[2] & 0xc0) >> 6 == 0x1)
97
 
                goto set_sense;
98
 
 
99
 
        pcode = req->scb[2] & 0x3f;
100
 
 
101
 
        assert(!tio);
102
 
        tio = cmnd->tio = tio_alloc(1);
103
 
        data = page_address(tio->pvec[0]);
104
 
        assert(data);
105
 
        clear_page(data);
106
 
 
107
 
        if (LUReadonly(cmnd->lun))
108
 
                data[2] = 0x80;
109
 
 
110
 
        if ((scb[1] & 0x8))
111
 
                data[3] = 0;
112
 
        else {
113
 
                data[3] = 8;
114
 
                len += 8;
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);
118
 
        }
119
 
 
120
 
        switch (pcode) {
121
 
        case 0x0:
122
 
                break;
123
 
        case 0x2:
124
 
                len += insert_disconnect_pg(data + len);
125
 
                break;
126
 
        case 0x3:
127
 
                len += insert_format_m_pg(data + len, 1 << cmnd->lun->blk_shift);
128
 
                break;
129
 
        case 0x4:
130
 
                len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt);
131
 
                break;
132
 
        case 0x8:
133
 
                len += insert_caching_pg(data + len, LUWCache(cmnd->lun),
134
 
                                         LURCache(cmnd->lun));
135
 
                break;
136
 
        case 0xa:
137
 
                len += insert_ctrl_m_pg(data + len);
138
 
                break;
139
 
        case 0x1c:
140
 
                len += insert_iec_m_pg(data + len);
141
 
                break;
142
 
        case 0x3f:
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);
150
 
                break;
151
 
        default:
152
 
                err = -1;
153
 
        }
154
 
 
155
 
        if (!err) {
156
 
                data[0] = len - 1;
157
 
                tio_set(tio, len, 0);
158
 
                return;
159
 
        }
160
 
 
161
 
        tio_put(tio);
162
 
        cmnd->tio = NULL;
163
 
 set_sense:
164
 
        /* Invalid Field In CDB */
165
 
        iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
166
 
}
167
 
 
168
 
static void build_inquiry_response(struct iscsi_cmnd *cmnd)
169
 
{
170
 
        struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
171
 
        struct tio *tio = cmnd->tio;
172
 
        u8 *data;
173
 
        u8 *scb = req->scb;
174
 
        int err = -1;
175
 
 
176
 
        /*
177
 
         * - CmdDt and EVPD both set or EVPD and Page Code set: illegal
178
 
         * - CmdDt set: not supported
179
 
         */
180
 
        if ((scb[1] & 0x3) > 0x1 || (!(scb[1] & 0x3) && scb[2]))
181
 
                goto set_sense;
182
 
 
183
 
        assert(!tio);
184
 
        tio = cmnd->tio = tio_alloc(1);
185
 
        data = page_address(tio->pvec[0]);
186
 
        assert(data);
187
 
        clear_page(data);
188
 
 
189
 
        if (!(scb[1] & 0x3)) {
190
 
                data[2] = 4;
191
 
                data[3] = 0x52;
192
 
                data[4] = 59;
193
 
                data[7] = 0x02;
194
 
                memset(data + 8, 0x20, 28);
195
 
                memcpy(data + 8,
196
 
                        VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8));
197
 
                memcpy(data + 16,
198
 
                        PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16));
199
 
                memcpy(data + 32,
200
 
                        PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4));
201
 
                data[58] = 0x03;
202
 
                data[59] = 0x20;
203
 
                data[60] = 0x09;
204
 
                data[61] = 0x60;
205
 
                data[62] = 0x03;
206
 
                data[63] = 0x00;
207
 
                tio_set(tio, 64, 0);
208
 
                err = 0;
209
 
        } else if (scb[1] & 0x1) {
210
 
                /* EVPD bit set */
211
 
                if (scb[2] == 0x0) {
212
 
                        data[1] = 0x0;
213
 
                        data[3] = 3;
214
 
                        data[4] = 0x0;
215
 
                        data[5] = 0x80;
216
 
                        data[6] = 0x83;
217
 
                        tio_set(tio, 7, 0);
218
 
                        err = 0;
219
 
                } else if (scb[2] == 0x80) {
220
 
                        u32 len = 4;
221
 
 
222
 
                        if (cmnd->lun) {
223
 
                                if (strlen(cmnd->lun->scsi_sn) <= 16)
224
 
                                        len = 16;
225
 
                                else
226
 
                                        len = SCSI_SN_LEN;
227
 
                        }
228
 
 
229
 
                        data[1] = 0x80;
230
 
                        data[3] = len;
231
 
                        memset(data + 4, 0x20, len);
232
 
                        if (cmnd->lun) {
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));
237
 
                        }
238
 
                        tio_set(tio, len + 4, 0);
239
 
                        err = 0;
240
 
                } else if (scb[2] == 0x83) {
241
 
                        u32 len = SCSI_ID_LEN + 8;
242
 
 
243
 
                        data[1] = 0x83;
244
 
                        data[3] = len + 4;
245
 
                        data[4] = 0x1;
246
 
                        data[5] = 0x1;
247
 
                        data[7] = len;
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,
253
 
                                                                SCSI_ID_LEN);
254
 
                        }
255
 
                        tio_set(tio, len + 8, 0);
256
 
                        err = 0;
257
 
                }
258
 
        }
259
 
 
260
 
        if (!err) {
261
 
                tio_set(tio, min_t(u8, tio->size, scb[4]), 0);
262
 
                if (!cmnd->lun)
263
 
                        data[0] = TYPE_NO_LUN;
264
 
                return;
265
 
        }
266
 
 
267
 
        tio_put(tio);
268
 
        cmnd->tio = NULL;
269
 
 set_sense:
270
 
        /* Invalid Field In CDB */
271
 
        iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
272
 
}
273
 
 
274
 
static void build_report_luns_response(struct iscsi_cmnd *cmnd)
275
 
{
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;
280
 
        int rest, idx = 0;
281
 
 
282
 
        size = (u32)req->scb[6] << 24 | (u32)req->scb[7] << 16 |
283
 
                (u32)req->scb[8] << 8 | (u32)req->scb[9];
284
 
        if (size < 16) {
285
 
                /* Invalid Field In CDB */
286
 
                iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x24, 0x0);
287
 
                return;
288
 
        }
289
 
 
290
 
        len = atomic_read(&cmnd->conn->session->target->nr_volumes) * 8;
291
 
        size = min(size & ~(8 - 1), len + 8);
292
 
 
293
 
        assert(!tio);
294
 
        tio = cmnd->tio = tio_alloc(get_pgcnt(size, 0));
295
 
        tio_set(tio, size, 0);
296
 
 
297
 
        data = page_address(tio->pvec[idx]);
298
 
        assert(data);
299
 
        *data++ = cpu_to_be32(len);
300
 
        *data++ = 0;
301
 
        size -= 8;
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)
305
 
                        continue;
306
 
 
307
 
                *data++ = cpu_to_be32((0x3ff & lun->lun) << 16 |
308
 
                                      ((lun->lun > 0xff) ? (0x1 << 30) : 0));
309
 
                *data++ = 0;
310
 
                if ((size -= 8) == 0)
311
 
                        break;
312
 
                if ((rest -= 8) == 0) {
313
 
                        idx++;
314
 
                        data = page_address(tio->pvec[idx]);
315
 
                        rest = PAGE_CACHE_SIZE;
316
 
                }
317
 
        }
318
 
}
319
 
 
320
 
static void build_read_capacity_response(struct iscsi_cmnd *cmnd)
321
 
{
322
 
        struct tio *tio = cmnd->tio;
323
 
        u32 *data;
324
 
 
325
 
        assert(!tio);
326
 
        tio = cmnd->tio = tio_alloc(1);
327
 
        data = page_address(tio->pvec[0]);
328
 
        assert(data);
329
 
        clear_page(data);
330
 
 
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);
334
 
 
335
 
        tio_set(tio, 8, 0);
336
 
}
337
 
 
338
 
static void build_request_sense_response(struct iscsi_cmnd *cmnd)
339
 
{
340
 
        struct tio *tio = cmnd->tio;
341
 
        u8 *data;
342
 
 
343
 
        assert(!tio);
344
 
        tio = cmnd->tio = tio_alloc(1);
345
 
        data = page_address(tio->pvec[0]);
346
 
        assert(data);
347
 
        memset(data, 0, 18);
348
 
        data[0] = 0xf0;
349
 
        data[1] = 0;
350
 
        data[2] = NO_SENSE;
351
 
        data[7] = 10;
352
 
        tio_set(tio, 18, 0);
353
 
}
354
 
 
355
 
static void build_service_action_in_response(struct iscsi_cmnd *cmnd)
356
 
{
357
 
        struct tio *tio = cmnd->tio;
358
 
        u32 *data;
359
 
        u64 *data64;
360
 
 
361
 
        assert(!tio);
362
 
 
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);
367
 
                return;
368
 
        }
369
 
 
370
 
        tio = cmnd->tio = tio_alloc(1);
371
 
        data = page_address(tio->pvec[0]);
372
 
        assert(data);
373
 
        clear_page(data);
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);
377
 
 
378
 
        tio_set(tio, 12, 0);
379
 
}
380
 
 
381
 
static void build_read_response(struct iscsi_cmnd *cmnd)
382
 
{
383
 
        struct tio *tio = cmnd->tio;
384
 
 
385
 
        assert(tio);
386
 
        assert(cmnd->lun);
387
 
 
388
 
        if (tio_read(cmnd->lun, tio))
389
 
                /* Medium Error/Unrecovered Read Error */
390
 
                iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x11, 0x0);
391
 
}
392
 
 
393
 
static void build_write_response(struct iscsi_cmnd *cmnd)
394
 
{
395
 
        int err;
396
 
        struct tio *tio = cmnd->tio;
397
 
 
398
 
        assert(tio);
399
 
        assert(cmnd->lun);
400
 
 
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);
405
 
 
406
 
        if (err)
407
 
                /* Medium Error/Write Fault */
408
 
                iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x03, 0x0);
409
 
}
410
 
 
411
 
static void build_sync_cache_response(struct iscsi_cmnd *cmnd)
412
 
{
413
 
        assert(cmnd->lun);
414
 
        if (tio_sync(cmnd->lun, NULL))
415
 
                /* Medium Error/Write Fault */
416
 
                iscsi_cmnd_set_sense(cmnd, MEDIUM_ERROR, 0x03, 0x0);
417
 
}
418
 
 
419
 
static void build_generic_response(struct iscsi_cmnd *cmnd)
420
 
{
421
 
        return;
422
 
}
423
 
 
424
 
static void build_reserve_response(struct iscsi_cmnd *cmnd)
425
 
{
426
 
        switch (volume_reserve(cmnd->lun, cmnd->conn->session->sid)) {
427
 
        case -ENOENT:
428
 
                /* Logical Unit Not Supported (?) */
429
 
                iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x25, 0x0);
430
 
                break;
431
 
        case -EBUSY:
432
 
                cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
433
 
                break;
434
 
        default:
435
 
                break;
436
 
        }
437
 
}
438
 
 
439
 
static void build_release_response(struct iscsi_cmnd *cmnd)
440
 
{
441
 
        int ret = volume_release(cmnd->lun,
442
 
                                 cmnd->conn->session->sid, 0);
443
 
        switch (ret) {
444
 
        case -ENOENT:
445
 
                /* Logical Unit Not Supported (?) */
446
 
                iscsi_cmnd_set_sense(cmnd, ILLEGAL_REQUEST, 0x25, 0x0);
447
 
                break;
448
 
        case -EBUSY:
449
 
                cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
450
 
                break;
451
 
        default:
452
 
                break;
453
 
        }
454
 
}
455
 
 
456
 
static void build_reservation_conflict_response(struct iscsi_cmnd *cmnd)
457
 
{
458
 
        cmnd->status = SAM_STAT_RESERVATION_CONFLICT;
459
 
}
460
 
 
461
 
static int disk_check_ua(struct iscsi_cmnd *cmnd)
462
 
{
463
 
        struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
464
 
        struct ua_entry *ua;
465
 
 
466
 
        if (cmnd->lun && ua_pending(cmnd->conn->session, cmnd->lun->lun)) {
467
 
                switch(req->scb[0]){
468
 
                case INQUIRY:
469
 
                case REQUEST_SENSE:
470
 
                        break;
471
 
                case REPORT_LUNS:
472
 
                        ua = ua_get_match(cmnd->conn->session,
473
 
                                          cmnd->lun->lun,
474
 
                                          /* reported luns data has changed */
475
 
                                          0x3f, 0x0e);
476
 
                        ua_free(ua);
477
 
                        break;
478
 
                default:
479
 
                        ua = ua_get_first(cmnd->conn->session, cmnd->lun->lun);
480
 
                        iscsi_cmnd_set_sense(cmnd, UNIT_ATTENTION, ua->asc,
481
 
                                             ua->ascq);
482
 
                        ua_free(ua);
483
 
                        send_scsi_rsp(cmnd, build_generic_response);
484
 
                        return 1;
485
 
                }
486
 
        }
487
 
        return 0;
488
 
}
489
 
 
490
 
static int disk_check_reservation(struct iscsi_cmnd *cmnd)
491
 
{
492
 
        struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
493
 
 
494
 
        int ret = is_volume_reserved(cmnd->lun,
495
 
                                     cmnd->conn->session->sid);
496
 
        if (ret == -EBUSY) {
497
 
                switch (req->scb[0]) {
498
 
                case INQUIRY:
499
 
                case RELEASE:
500
 
                case REPORT_LUNS:
501
 
                case REQUEST_SENSE:
502
 
                case READ_CAPACITY:
503
 
                        /* allowed commands when reserved */
504
 
                        break;
505
 
                case SERVICE_ACTION_IN:
506
 
                        if ((cmnd_hdr(cmnd)->scb[1] & 0x1F) == 0x10)
507
 
                                break;
508
 
                        /* fall through */
509
 
                default:
510
 
                        /* return reservation conflict for all others */
511
 
                        send_scsi_rsp(cmnd,
512
 
                                      build_reservation_conflict_response);
513
 
                        return 1;
514
 
                }
515
 
        }
516
 
 
517
 
        return 0;
518
 
}
519
 
 
520
 
static int disk_execute_cmnd(struct iscsi_cmnd *cmnd)
521
 
{
522
 
        struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd);
523
 
 
524
 
        req->opcode &= ISCSI_OPCODE_MASK;
525
 
 
526
 
        if (disk_check_ua(cmnd))
527
 
                return 0;
528
 
 
529
 
        if (disk_check_reservation(cmnd))
530
 
                return 0;
531
 
 
532
 
        switch (req->scb[0]) {
533
 
        case INQUIRY:
534
 
                send_data_rsp(cmnd, build_inquiry_response);
535
 
                break;
536
 
        case REPORT_LUNS:
537
 
                send_data_rsp(cmnd, build_report_luns_response);
538
 
                break;
539
 
        case READ_CAPACITY:
540
 
                send_data_rsp(cmnd, build_read_capacity_response);
541
 
                break;
542
 
        case MODE_SENSE:
543
 
                send_data_rsp(cmnd, build_mode_sense_response);
544
 
                break;
545
 
        case REQUEST_SENSE:
546
 
                send_data_rsp(cmnd, build_request_sense_response);
547
 
                break;
548
 
        case SERVICE_ACTION_IN:
549
 
                send_data_rsp(cmnd, build_service_action_in_response);
550
 
                break;
551
 
        case READ_6:
552
 
        case READ_10:
553
 
        case READ_16:
554
 
                send_data_rsp(cmnd, build_read_response);
555
 
                break;
556
 
        case WRITE_6:
557
 
        case WRITE_10:
558
 
        case WRITE_16:
559
 
        case WRITE_VERIFY:
560
 
                send_scsi_rsp(cmnd, build_write_response);
561
 
                break;
562
 
        case SYNCHRONIZE_CACHE:
563
 
                send_scsi_rsp(cmnd, build_sync_cache_response);
564
 
                break;
565
 
        case RESERVE:
566
 
                send_scsi_rsp(cmnd, build_reserve_response);
567
 
                break;
568
 
        case RELEASE:
569
 
                send_scsi_rsp(cmnd, build_release_response);
570
 
                break;
571
 
        case START_STOP:
572
 
        case TEST_UNIT_READY:
573
 
        case VERIFY:
574
 
        case VERIFY_16:
575
 
                send_scsi_rsp(cmnd, build_generic_response);
576
 
                break;
577
 
        default:
578
 
                eprintk("%s\n", "we should not come here!");
579
 
                break;
580
 
        }
581
 
 
582
 
        return 0;
583
 
}
584
 
 
585
 
struct target_type disk_ops =
586
 
{
587
 
        .id = 0,
588
 
        .execute_cmnd = disk_execute_cmnd,
589
 
};