Fix SCSI off-by-one device size.
[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);
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, 1);
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, int lun)
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, command %x\n", s->command);
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 (lun || buf[1] >> 5) {
229         /* Only LUN 0 supported.  */
230         DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
231         goto fail;
232     }
233     switch (s->command) {
234     case 0x0:
235         DPRINTF("Test Unit Ready\n");
236         break;
237     case 0x03:
238         DPRINTF("Request Sense (len %d)\n", len);
239         if (len < 4)
240             goto fail;
241         memset(buf, 0, 4);
242         s->buf[0] = 0xf0;
243         s->buf[1] = 0;
244         s->buf[2] = s->sense;
245         s->buf_len = 4;
246         break;
247     case 0x12:
248         DPRINTF("Inquiry (len %d)\n", len);
249         if (len < 36) {
250             BADF("Inquiry buffer too small (%d)\n", len);
251         }
252         memset(s->buf, 0, 36);
253         if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
254             s->buf[0] = 5;
255             s->buf[1] = 0x80;
256             memcpy(&s->buf[16], "QEMU CD-ROM    ", 16);
257         } else {
258             s->buf[0] = 0;
259             memcpy(&s->buf[16], "QEMU HARDDISK  ", 16);
260         }
261         memcpy(&s->buf[8], "QEMU   ", 8);
262         memcpy(&s->buf[32], QEMU_VERSION, 4);
263         /* Identify device as SCSI-3 rev 1.
264            Some later commands are also implemented. */
265         s->buf[2] = 3;
266         s->buf[3] = 2; /* Format 2 */
267         s->buf[4] = 32;
268         s->buf_len = 36;
269         break;
270     case 0x16:
271         DPRINTF("Reserve(6)\n");
272         if (buf[1] & 1)
273             goto fail;
274         break;
275     case 0x17:
276         DPRINTF("Release(6)\n");
277         if (buf[1] & 1)
278             goto fail;
279         break;
280     case 0x1a:
281     case 0x5a:
282         {
283             char *p;
284             int page;
285
286             page = buf[2] & 0x3f;
287             DPRINTF("Mode Sense (page %d, len %d)\n", page, len);
288             p = s->buf;
289             memset(p, 0, 4);
290             s->buf[1] = 0; /* Default media type.  */
291             s->buf[3] = 0; /* Block descriptor length.  */
292             if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
293                 s->buf[2] = 0x80; /* Readonly.  */
294             }
295             p += 4;
296             if ((page == 8 || page == 0x3f)) {
297                 /* Caching page.  */
298                 p[0] = 8;
299                 p[1] = 0x12;
300                 p[2] = 4; /* WCE */
301                 p += 19;
302             }
303             if ((page == 0x3f || page == 0x2a)
304                     && (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM)) {
305                 /* CD Capabilities and Mechanical Status page. */
306                 p[0] = 0x2a;
307                 p[1] = 0x14;
308                 p[2] = 3; // CD-R & CD-RW read
309                 p[3] = 0; // Writing not supported
310                 p[4] = 0x7f; /* Audio, composite, digital out,
311                                          mode 2 form 1&2, multi session */
312                 p[5] = 0xff; /* CD DA, DA accurate, RW supported,
313                                          RW corrected, C2 errors, ISRC,
314                                          UPC, Bar code */
315                 p[6] = 0x2d | (bdrv_is_locked(s->bdrv)? 2 : 0);
316                 /* Locking supported, jumper present, eject, tray */
317                 p[7] = 0; /* no volume & mute control, no
318                                       changer */
319                 p[8] = (50 * 176) >> 8; // 50x read speed
320                 p[9] = (50 * 176) & 0xff;
321                 p[10] = 0 >> 8; // No volume
322                 p[11] = 0 & 0xff;
323                 p[12] = 2048 >> 8; // 2M buffer
324                 p[13] = 2048 & 0xff;
325                 p[14] = (16 * 176) >> 8; // 16x read speed current
326                 p[15] = (16 * 176) & 0xff;
327                 p[18] = (16 * 176) >> 8; // 16x write speed
328                 p[19] = (16 * 176) & 0xff;
329                 p[20] = (16 * 176) >> 8; // 16x write speed current
330                 p[21] = (16 * 176) & 0xff;
331                 p += 21;
332             }
333             s->buf_len = p - s->buf;
334             s->buf[0] = s->buf_len - 4;
335             if (s->buf_len > len)
336                 s->buf_len = len;
337         }
338         break;
339     case 0x1b:
340         DPRINTF("Start Stop Unit\n");
341         break;
342     case 0x1e:
343         DPRINTF("Prevent Allow Medium Removal (prevent = %d)\n", buf[4] & 3);
344         bdrv_set_locked(s->bdrv, buf[4] & 1);
345         break;
346     case 0x25:
347         DPRINTF("Read Capacity\n");
348         /* The normal LEN field for this command is zero.  */
349         memset(s->buf, 0, 8);
350         bdrv_get_geometry(s->bdrv, &nb_sectors);
351         /* Returned value is the address of the last sector.  */
352         if (nb_sectors) {
353             nb_sectors--;
354             s->buf[0] = (nb_sectors >> 24) & 0xff;
355             s->buf[1] = (nb_sectors >> 16) & 0xff;
356             s->buf[2] = (nb_sectors >> 8) & 0xff;
357             s->buf[3] = nb_sectors & 0xff;
358             s->buf[4] = 0;
359             s->buf[5] = 0;
360             s->buf[6] = s->cluster_size * 2;
361             s->buf[7] = 0;
362             s->buf_len = 8;
363         } else {
364             scsi_command_complete(s, SENSE_NOT_READY);
365         }
366         break;
367     case 0x08:
368     case 0x28:
369         DPRINTF("Read (sector %d, count %d)\n", lba, len);
370         s->sector = lba * s->cluster_size;
371         s->sector_count = len * s->cluster_size;
372         break;
373     case 0x0a:
374     case 0x2a:
375         DPRINTF("Write (sector %d, count %d)\n", lba, len);
376         s->sector = lba * s->cluster_size;
377         s->sector_count = len * s->cluster_size;
378         is_write = 1;
379         break;
380     case 0x35:
381         DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
382         bdrv_flush(s->bdrv);
383         break;
384     case 0x43:
385         {
386             int start_track, format, msf, toclen;
387
388             msf = buf[1] & 2;
389             format = buf[2] & 0xf;
390             start_track = buf[6];
391             bdrv_get_geometry(s->bdrv, &nb_sectors);
392             DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
393             switch(format) {
394             case 0:
395                 toclen = cdrom_read_toc(nb_sectors, s->buf, msf, start_track);
396                 break;
397             case 1:
398                 /* multi session : only a single session defined */
399                 toclen = 12;
400                 memset(s->buf, 0, 12);
401                 s->buf[1] = 0x0a;
402                 s->buf[2] = 0x01;
403                 s->buf[3] = 0x01;
404                 break;
405             case 2:
406                 toclen = cdrom_read_toc_raw(nb_sectors, s->buf, msf, start_track);
407                 break;
408             default:
409                 goto error_cmd;
410             }
411             if (toclen > 0) {
412                 if (len > toclen)
413                   len = toclen;
414                 s->buf_len = len;
415                 break;
416             }
417         error_cmd:
418             DPRINTF("Read TOC error\n");
419             goto fail;
420         }
421     case 0x46:
422         DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
423         memset(s->buf, 0, 8);
424         /* ??? This shoud probably return much more information.  For now
425            just return the basic header indicating the CD-ROM profile.  */
426         s->buf[7] = 8; // CD-ROM
427         s->buf_len = 8;
428         break;
429     case 0x56:
430         DPRINTF("Reserve(10)\n");
431         if (buf[1] & 3)
432             goto fail;
433         break;
434     case 0x57:
435         DPRINTF("Release(10)\n");
436         if (buf[1] & 3)
437             goto fail;
438         break;
439     case 0xa0:
440         DPRINTF("Report LUNs (len %d)\n", len);
441         if (len < 16)
442             goto fail;
443         memset(s->buf, 0, 16);
444         s->buf[3] = 8;
445         s->buf_len = 16;
446         break;
447     default:
448         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
449     fail:
450         scsi_command_complete(s, SENSE_ILLEGAL_REQUEST);
451         return 0;
452     }
453     if (s->sector_count == 0 && s->buf_len == 0) {
454         scsi_command_complete(s, SENSE_NO_SENSE);
455     }
456     len = s->sector_count * 512 + s->buf_len;
457     return is_write ? -len : len;
458 }
459
460 void scsi_disk_destroy(SCSIDevice *s)
461 {
462     bdrv_close(s->bdrv);
463     qemu_free(s);
464 }
465
466 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
467                            scsi_completionfn completion,
468                            void *opaque)
469 {
470     SCSIDevice *s;
471
472     s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
473     s->bdrv = bdrv;
474     s->completion = completion;
475     s->opaque = opaque;
476     if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
477         s->cluster_size = 4;
478     } else {
479         s->cluster_size = 1;
480     }
481
482     return s;
483 }
484