7390805d244d5087c4484ec5055c27a8033b38d3
[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         s->buf[0] = (nb_sectors >> 24) & 0xff;
352         s->buf[1] = (nb_sectors >> 16) & 0xff;
353         s->buf[2] = (nb_sectors >> 8) & 0xff;
354         s->buf[3] = nb_sectors & 0xff;
355         s->buf[4] = 0;
356         s->buf[5] = 0;
357         s->buf[6] = s->cluster_size * 2;
358         s->buf[7] = 0;
359         s->buf_len = 8;
360         break;
361     case 0x08:
362     case 0x28:
363         DPRINTF("Read (sector %d, count %d)\n", lba, len);
364         s->sector = lba * s->cluster_size;
365         s->sector_count = len * s->cluster_size;
366         break;
367     case 0x0a:
368     case 0x2a:
369         DPRINTF("Write (sector %d, count %d)\n", lba, len);
370         s->sector = lba * s->cluster_size;
371         s->sector_count = len * s->cluster_size;
372         is_write = 1;
373         break;
374     case 0x35:
375         DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
376         /* ??? Extend block layer and use fsync to implement this.  */
377         break;
378     case 0x43:
379         {
380             int start_track, format, msf, toclen;
381
382             msf = buf[1] & 2;
383             format = buf[2] & 0xf;
384             start_track = buf[6];
385             bdrv_get_geometry(s->bdrv, &nb_sectors);
386             DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
387             switch(format) {
388             case 0:
389                 toclen = cdrom_read_toc(nb_sectors, s->buf, msf, start_track);
390                 break;
391             case 1:
392                 /* multi session : only a single session defined */
393                 toclen = 12;
394                 memset(s->buf, 0, 12);
395                 s->buf[1] = 0x0a;
396                 s->buf[2] = 0x01;
397                 s->buf[3] = 0x01;
398                 break;
399             case 2:
400                 toclen = cdrom_read_toc_raw(nb_sectors, s->buf, msf, start_track);
401                 break;
402             default:
403                 goto error_cmd;
404             }
405             if (toclen > 0) {
406                 if (len > toclen)
407                   len = toclen;
408                 s->buf_len = len;
409                 break;
410             }
411         error_cmd:
412             DPRINTF("Read TOC error\n");
413             goto fail;
414         }
415     case 0x46:
416         DPRINTF("Get Configuration (rt %d, maxlen %d)\n", buf[1] & 3, len);
417         memset(s->buf, 0, 8);
418         /* ??? This shoud probably return much more information.  For now
419            just return the basic header indicating the CD-ROM profile.  */
420         s->buf[7] = 8; // CD-ROM
421         s->buf_len = 8;
422         break;
423     case 0x56:
424         DPRINTF("Reserve(10)\n");
425         if (buf[1] & 3)
426             goto fail;
427         break;
428     case 0x57:
429         DPRINTF("Release(10)\n");
430         if (buf[1] & 3)
431             goto fail;
432         break;
433     case 0xa0:
434         DPRINTF("Report LUNs (len %d)\n", len);
435         if (len < 16)
436             goto fail;
437         memset(s->buf, 0, 16);
438         s->buf[3] = 8;
439         s->buf_len = 16;
440         break;
441     default:
442         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
443     fail:
444         scsi_command_complete(s, SENSE_ILLEGAL_REQUEST);
445         return 0;
446     }
447     if (s->sector_count == 0 && s->buf_len == 0) {
448         scsi_command_complete(s, SENSE_NO_SENSE);
449     }
450     len = s->sector_count * 512 + s->buf_len;
451     return is_write ? -len : len;
452 }
453
454 void scsi_disk_destroy(SCSIDevice *s)
455 {
456     bdrv_close(s->bdrv);
457     qemu_free(s);
458 }
459
460 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
461                            scsi_completionfn completion,
462                            void *opaque)
463 {
464     SCSIDevice *s;
465
466     s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
467     s->bdrv = bdrv;
468     s->completion = completion;
469     s->opaque = opaque;
470     if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
471         s->cluster_size = 4;
472     } else {
473         s->cluster_size = 1;
474     }
475
476     return s;
477 }
478