PCI SCSI HBA emulation.
[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\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 (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         s->buf[2] = 3; /* SCSI-3 */
264         s->buf[3] = 2; /* Format 2 */
265         s->buf[4] = 32;
266         s->buf_len = 36;
267         break;
268     case 0x16:
269         DPRINTF("Reserve(6)\n");
270         if (buf[1] & 1)
271             goto fail;
272         break;
273     case 0x17:
274         DPRINTF("Release(6)\n");
275         if (buf[1] & 1)
276             goto fail;
277         break;
278     case 0x1a:
279     case 0x5a:
280         DPRINTF("Mode Sense (page %d, len %d)\n", buf[2], len);
281         if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
282             memset(s->buf, 0, 4);
283             s->buf[0] = 4; /* Mode data length.  */
284             s->buf[1] = 0; /* Default media type.  */
285             s->buf[2] = 0x80; /* Readonly.  */
286             s->buf[3] = 0; /* Block descriptor length.  */
287         } else {
288             memset(s->buf, 0, 0x16);
289             s->buf[0] = 0x16; /* Mode data length (4 + 0x12).  */
290             s->buf[1] = 0; /* Default media type.  */
291             s->buf[2] = 0; /* Write enabled.  */
292             s->buf[3] = 0; /* Block descriptor length.  */
293             /* Caching page.  */
294             s->buf[4 + 0] = 8;
295             s->buf[4 + 1] = 0x12;
296             s->buf[4 + 2] = 4; /* WCE */
297             if (len > 0x16)
298                 len = 0x16;
299         }
300         s->buf_len = len;
301         break;
302     case 0x25:
303         DPRINTF("Read Capacity\n");
304         /* The normal LEN field for this command is zero.  */
305         memset(s->buf, 0, 8);
306         bdrv_get_geometry(s->bdrv, &nb_sectors);
307         s->buf[0] = (nb_sectors >> 24) & 0xff;
308         s->buf[1] = (nb_sectors >> 16) & 0xff;
309         s->buf[2] = (nb_sectors >> 8) & 0xff;
310         s->buf[3] = nb_sectors & 0xff;
311         s->buf[4] = 0;
312         s->buf[5] = 0;
313         s->buf[6] = s->cluster_size * 2;
314         s->buf[7] = 0;
315         s->buf_len = 8;
316         break;
317     case 0x08:
318     case 0x28:
319         DPRINTF("Read (sector %d, count %d)\n", lba, len);
320         s->sector = lba * s->cluster_size;
321         s->sector_count = len * s->cluster_size;
322         break;
323     case 0x0a:
324     case 0x2a:
325         DPRINTF("Write (sector %d, count %d)\n", lba, len);
326         s->sector = lba * s->cluster_size;
327         s->sector_count = len * s->cluster_size;
328         is_write = 1;
329         break;
330     case 0x35:
331         DPRINTF("Syncronise cache (sector %d, count %d)\n", lba, len);
332         /* ??? Extend block layer and use fsync to implement this.  */
333         break;
334     case 0x43:
335         {
336             int start_track, format, msf, toclen;
337
338             msf = buf[1] & 2;
339             format = buf[2] & 0xf;
340             start_track = buf[6];
341             bdrv_get_geometry(s->bdrv, &nb_sectors);
342             DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
343             switch(format) {
344             case 0:
345                 toclen = cdrom_read_toc(nb_sectors, s->buf, msf, start_track);
346                 break;
347             case 1:
348                 /* multi session : only a single session defined */
349                 toclen = 12;
350                 memset(s->buf, 0, 12);
351                 s->buf[1] = 0x0a;
352                 s->buf[2] = 0x01;
353                 s->buf[3] = 0x01;
354                 break;
355             case 2:
356                 toclen = cdrom_read_toc_raw(nb_sectors, s->buf, msf, start_track);
357                 break;
358             default:
359                 goto error_cmd;
360             }
361             if (toclen > 0) {
362                 if (len > toclen)
363                   len = toclen;
364                 s->buf_len = len;
365                 break;
366             }
367         error_cmd:
368             DPRINTF("Read TOC error\n");
369             goto fail;
370         }
371     case 0x56:
372         DPRINTF("Reserve(10)\n");
373         if (buf[1] & 3)
374             goto fail;
375         break;
376     case 0x57:
377         DPRINTF("Release(10)\n");
378         if (buf[1] & 3)
379             goto fail;
380         break;
381     case 0xa0:
382         DPRINTF("Report LUNs (len %d)\n", len);
383         if (len < 16)
384             goto fail;
385         memset(s->buf, 0, 16);
386         s->buf[3] = 8;
387         s->buf_len = 16;
388         break;
389     default:
390         DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
391     fail:
392         scsi_command_complete(s, SENSE_ILLEGAL_REQUEST);
393         return 0;
394     }
395     if (s->sector_count == 0 && s->buf_len == 0) {
396         scsi_command_complete(s, SENSE_NO_SENSE);
397     }
398     len = s->sector_count * 512 + s->buf_len;
399     return is_write ? -len : len;
400 }
401
402 void scsi_disk_destroy(SCSIDevice *s)
403 {
404     bdrv_close(s->bdrv);
405     qemu_free(s);
406 }
407
408 SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
409                            scsi_completionfn completion,
410                            void *opaque)
411 {
412     SCSIDevice *s;
413
414     s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
415     s->bdrv = bdrv;
416     s->completion = completion;
417     s->opaque = opaque;
418     if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
419         s->cluster_size = 4;
420     } else {
421         s->cluster_size = 1;
422     }
423
424     return s;
425 }
426