Fix scsi sector size confusion (Blue Swirl).
[qemu] / hw / scsi-disk.c
1 /*
2  * SCSI Device emulation
3  *
4  * Copyright (c) 2006 CodeSourcery.
5  * Based on code by Fabrice Bellard
6  *
7  * Written by Paul Brook
8  *
9  * This code is licenced under the LGPL.
10  */
11
12 //#define DEBUG_SCSI
13
14 #ifdef DEBUG_SCSI
15 #define DPRINTF(fmt, args...) \
16 do { printf("scsi-disk: " fmt , ##args); } while (0)
17 #else
18 #define DPRINTF(fmt, args...) do {} while(0)
19 #endif
20
21 #define BADF(fmt, args...) \
22 do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
23
24 #include "vl.h"
25
26 #define SENSE_NO_SENSE        0
27 #define SENSE_ILLEGAL_REQUEST 5
28
29 struct SCSIDevice
30 {
31     int command;
32     uint32_t tag;
33     BlockDriverState *bdrv;
34     /* The qemu block layer uses a fixed 512 byte sector size.
35        This is the number of 512 byte blocks in a single scsi sector.  */
36     int cluster_size;
37     /* When transfering data buf_pos and buf_len contain a partially
38        transferred block of data (or response to a command), and
39        sector/sector_count identify any remaining sectors.
40        Both sector and sector_count are in terms of qemu 512 byte blocks.  */
41     /* ??? We should probably keep track of whether the data trasfer is
42        a read or a write.  Currently we rely on the host getting it right.  */
43     int sector;
44     int sector_count;
45     int buf_pos;
46     int buf_len;
47     int sense;
48     char buf[512];
49     scsi_completionfn completion;
50     void *opaque;
51 };
52
53 static void scsi_command_complete(SCSIDevice *s, int sense)
54 {
55     s->sense = sense;
56     s->completion(s->opaque, s->tag, sense != SENSE_NO_SENSE);
57 }
58
59 /* Read data from a scsi device.  Returns nonzero on failure.  */
60 int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len)
61 {
62     uint32_t n;
63
64     DPRINTF("Read %d (%d/%d)\n", len, s->buf_len, s->sector_count);
65     if (s->buf_len == 0 && s->sector_count == 0)
66         return 1;
67
68     if (s->buf_len) {
69         n = s->buf_len;
70         if (n > len)
71             n = len;
72         memcpy(data, s->buf + s->buf_pos, n);
73         s->buf_pos += n;
74         s->buf_len -= n;
75         data += n;
76         len -= n;
77         if (s->buf_len == 0)
78             s->buf_pos = 0;
79     }
80
81     n = len / 512;
82     if (n > s->sector_count)
83       n = s->sector_count;
84
85     if (n != 0) {
86         bdrv_read(s->bdrv, s->sector, data, n);
87         data += n * 512;
88         len -= n * 512;
89         s->sector += n;
90         s->sector_count -= n;
91     }
92
93     if (len && s->sector_count) {
94         bdrv_read(s->bdrv, s->sector, s->buf, 512);
95         s->sector++;
96         s->sector_count--;
97         s->buf_pos = 0;
98         s->buf_len = 512;
99         /* Recurse to complete the partial read.  */
100         return scsi_read_data(s, data, len);
101     }
102
103     if (len != 0)
104         return 1;
105
106     if (s->buf_len == 0 && s->sector_count == 0)
107         scsi_command_complete(s, SENSE_NO_SENSE);
108
109     return 0;
110 }
111
112 /* Read data to a scsi device.  Returns nonzero on failure.  */
113 int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len)
114 {
115     uint32_t n;
116
117     DPRINTF("Write %d (%d/%d)\n", len, s->buf_len, s->sector_count);
118     if (s->buf_pos != 0) {
119         BADF("Bad state on write\n");
120         return 1;
121     }
122
123     if (s->sector_count == 0)
124         return 1;
125
126     if (s->buf_len != 0 || len < 512) {
127         n = 512 - s->buf_len;
128         if (n > len)
129             n = len;
130
131         memcpy(s->buf + s->buf_len, data, n);
132         data += n;
133         s->buf_len += n;
134         len -= n;
135         if (s->buf_len == 512) {
136             /* A full sector has been accumulated. Write it to disk.  */
137             bdrv_write(s->bdrv, s->sector, s->buf, 1);
138             s->buf_len = 0;
139             s->sector++;
140             s->sector_count--;
141         }
142     }
143
144     n = len / 512;
145     if (n > s->sector_count)
146         n = s->sector_count;
147
148     if (n != 0) {
149         bdrv_write(s->bdrv, s->sector, data, n);
150         data += n * 512;
151         len -= n * 512;
152         s->sector += n;
153         s->sector_count -= n;
154     }
155
156     if (len >= 512)
157         return 1;
158
159     if (len && s->sector_count) {
160         /* Recurse to complete the partial write.  */
161         return scsi_write_data(s, data, len);
162     }
163
164     if (len != 0)
165         return 1;
166
167     if (s->sector_count == 0)
168         scsi_command_complete(s, SENSE_NO_SENSE);
169
170     return 0;
171 }
172
173 /* Execute a scsi command.  Returns the length of the data expected by the
174    command.  This will be Positive for data transfers from the device
175    (eg. disk reads), negative for transfers to the device (eg. disk writes),
176    and zero if the command does not transfer any data.  */
177
178 int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf)
179 {
180     int64_t nb_sectors;
181     uint32_t lba;
182     uint32_t len;
183     int cmdlen;
184     int is_write;
185
186     s->command = buf[0];
187     s->tag = tag;
188     s->sector_count = 0;
189     s->buf_pos = 0;
190     s->buf_len = 0;
191     is_write = 0;
192     DPRINTF("Command: 0x%02x", buf[0]);
193     switch (s->command >> 5) {
194     case 0:
195         lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
196         len = buf[4];
197         cmdlen = 6;
198         break;
199     case 1:
200     case 2:
201         lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
202         len = buf[8] | (buf[7] << 8);
203         cmdlen = 10;
204         break;
205     case 4:
206         lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
207         len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
208         cmdlen = 16;
209         break;
210     case 5:
211         lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
212         len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
213         cmdlen = 12;
214         break;
215     default:
216         BADF("Unsupported command length\n");
217         goto fail;
218     }
219 #ifdef DEBUG_SCSI
220     {
221         int i;
222         for (i = 1; i < cmdlen; i++) {
223             printf(" 0x%02x", buf[i]);
224         }
225         printf("\n");
226     }
227 #endif
228     if (buf[1] >> 5) {
229         /* Only LUN 0 supported.  */
230         goto fail;
231     }
232     switch (s->command) {
233     case 0x0:
234         DPRINTF("Test Unit Ready\n");
235         break;
236     case 0x03:
237         DPRINTF("Request Sense (len %d)\n", len);
238         if (len < 4)
239             goto fail;
240         memset(buf, 0, 4);
241         s->buf[0] = 0xf0;
242         s->buf[1] = 0;
243         s->buf[2] = s->sense;
244         s->buf_len = 4;
245         break;
246     case 0x12:
247         DPRINTF("Inquiry (len %d)\n", len);
248         if (len < 36) {
249             BADF("Inquiry buffer too small (%d)\n", len);
250         }
251         memset(s->buf, 0, 36);
252         if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
253             s->buf[0] = 5;
254             s->buf[1] = 0x80;
255             memcpy(&s->buf[16], "QEMU CDROM     ", 16);
256         } else {
257             s->buf[0] = 0;
258             memcpy(&s->buf[16], "QEMU HARDDISK  ", 16);
259         }
260         memcpy(&s->buf[8], "QEMU   ", 8);
261         s->buf[2] = 3; /* SCSI-3 */
262         s->buf[3] = 2; /* Format 2 */
263         s->buf[4] = 32;
264         s->buf_len = 36;
265         break;
266     case 0x16:
267         DPRINTF("Reserve(6)\n");
268         if (buf[1] & 1)
269             goto fail;
270         break;
271     case 0x17:
272         DPRINTF("Release(6)\n");
273         if (buf[1] & 1)
274             goto fail;
275         break;
276     case 0x1a:
277         DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf[2], len);
278         memset(s->buf, 0, 4);
279         s->buf[0] = 0x16; /* Mode data length (4 + 0x12).  */
280         s->buf[1] = 0; /* Default media type.  */
281         s->buf[2] = 0; /* Write enabled.  */
282         s->buf[3] = 0; /* Block descriptor length.  */
283         /* Caching page.  */
284         s->buf[4 + 0] = 8;
285         s->buf[4 + 1] = 0x12;
286         s->buf[4 + 2] = 4; /* WCE */
287         if (len > 0x16)
288             len = 0x16;
289         s->buf_len = len;
290         break;
291     case 0x25:
292         DPRINTF("Read Capacity\n");
293         /* The normal LEN field for this command is zero.  */
294         memset(s->buf, 0, 8);
295         bdrv_get_geometry(s->bdrv, &nb_sectors);
296         s->buf[0] = (nb_sectors >> 24) & 0xff;
297         s->buf[1] = (nb_sectors >> 16) & 0xff;
298         s->buf[2] = (nb_sectors >> 8) & 0xff;
299         s->buf[3] = nb_sectors & 0xff;
300         s->buf[4] = 0;
301         s->buf[5] = 0;
302         s->buf[6] = s->cluster_size * 2;
303         s->buf[7] = 0;
304         s->buf_len = 8;
305         break;
306     case 0x08:
307     case 0x28:
308         DPRINTF("Read (sector %d, count %d)\n", lba, len);
309         s->sector = lba * s->cluster_size;
310         s->sector_count = len * s->cluster_size;
311         break;
312     case 0x0a:
313     case 0x2a:
314         DPRINTF("Write (sector %d, count %d)\n", lba, len);
315         s->sector = lba * s->cluster_size;
316         s->sector_count = len * s->cluster_size;
317         is_write = 1;
318         break;
319     case 0x43:
320         {
321             int start_track, format, msf, toclen;
322
323             msf = buf[1] & 2;
324             format = buf[2] & 0xf;
325             start_track = buf[6];
326             bdrv_get_geometry(s->bdrv, &nb_sectors);
327             DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
328             switch(format) {
329             case 0:
330                 toclen = cdrom_read_toc(nb_sectors, s->buf, msf, start_track);
331                 break;
332             case 1:
333                 /* multi session : only a single session defined */
334                 toclen = 12;
335                 memset(s->buf, 0, 12);
336                 s->buf[1] = 0x0a;
337                 s->buf[2] = 0x01;
338                 s->buf[3] = 0x01;
339                 break;
340             case 2:
341                 toclen = cdrom_read_toc_raw(nb_sectors, s->buf, msf, start_track);
342                 break;
343             default:
344                 goto error_cmd;
345             }
346             if (toclen > 0) {
347                 if (len > toclen)
348                   len = toclen;
349                 s->buf_len = len;
350                 break;
351             }
352         error_cmd:
353             DPRINTF("Read TOC error\n");
354             goto fail;
355         }
356     case 0x56:
357         DPRINTF("Reserve(10)\n");
358         if (buf[1] & 3)
359             goto fail;
360         break;
361     case 0x57:
362         DPRINTF("Release(10)\n");
363         if (buf[1] & 3)
364             goto fail;
365         break;
366     case 0xa0:
367         DPRINTF("Report LUNs (len %d)\n", len);
368         if (len < 16)
369             goto fail;
370         memset(s->buf, 0, 16);
371         s->buf[3] = 8;
372         s->buf_len = 16;
373         break;
374     default:
375         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
376     fail:
377         scsi_command_complete(s, SENSE_ILLEGAL_REQUEST);
378         return 0;
379     }
380     if (s->sector_count == 0 && s->buf_len == 0) {
381         scsi_command_complete(s, SENSE_NO_SENSE);
382     }
383     len = s->sector_count * 512 + s->buf_len;
384     return is_write ? -len : len;
385 }
386
387 void scsi_disk_destroy(SCSIDevice *s)
388 {
389     bdrv_close(s->bdrv);
390     qemu_free(s);
391 }
392
393 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
394                            scsi_completionfn completion,
395                            void *opaque)
396 {
397     SCSIDevice *s;
398
399     s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
400     s->bdrv = bdrv;
401     s->completion = completion;
402     s->opaque = opaque;
403     if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
404         s->cluster_size = 4;
405     } else {
406         s->cluster_size = 1;
407     }
408
409     return s;
410 }
411