Revision 2e5d83bb

b/Makefile.target
306 306
SOUND_HW += fmopl.o adlib.o
307 307
endif
308 308

  
309
# SCSI layer
310
VL_OBJS+= scsi-disk.o cdrom.o
311

  
309 312
# USB layer
310
VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o
313
VL_OBJS+= usb.o usb-hub.o usb-linux.o usb-hid.o usb-ohci.o usb-msd.o
311 314

  
312 315
# PCI network cards
313 316
VL_OBJS+= ne2000.o rtl8139.o
b/hw/cdrom.c
1
/*
2
 * QEMU ATAPI CD-ROM Emulator
3
 * 
4
 * Copyright (c) 2006 Fabrice Bellard
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

  
25
/* ??? Most of the ATAPI emulation is still in ide.c.  It should be moved
26
   here.  */
27

  
28
#include <vl.h>
29

  
30
static void lba_to_msf(uint8_t *buf, int lba)
31
{
32
    lba += 150;
33
    buf[0] = (lba / 75) / 60;
34
    buf[1] = (lba / 75) % 60;
35
    buf[2] = lba % 75;
36
}
37

  
38
/* same toc as bochs. Return -1 if error or the toc length */
39
/* XXX: check this */
40
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
41
{
42
    uint8_t *q;
43
    int len;
44
    
45
    if (start_track > 1 && start_track != 0xaa)
46
        return -1;
47
    q = buf + 2;
48
    *q++ = 1; /* first session */
49
    *q++ = 1; /* last session */
50
    if (start_track <= 1) {
51
        *q++ = 0; /* reserved */
52
        *q++ = 0x14; /* ADR, control */
53
        *q++ = 1;    /* track number */
54
        *q++ = 0; /* reserved */
55
        if (msf) {
56
            *q++ = 0; /* reserved */
57
            lba_to_msf(q, 0);
58
            q += 3;
59
        } else {
60
            /* sector 0 */
61
            cpu_to_be32wu((uint32_t *)q, 0);
62
            q += 4;
63
        }
64
    }
65
    /* lead out track */
66
    *q++ = 0; /* reserved */
67
    *q++ = 0x16; /* ADR, control */
68
    *q++ = 0xaa; /* track number */
69
    *q++ = 0; /* reserved */
70
    if (msf) {
71
        *q++ = 0; /* reserved */
72
        lba_to_msf(q, nb_sectors);
73
        q += 3;
74
    } else {
75
        cpu_to_be32wu((uint32_t *)q, nb_sectors);
76
        q += 4;
77
    }
78
    len = q - buf;
79
    cpu_to_be16wu((uint16_t *)buf, len - 2);
80
    return len;
81
}
82

  
83
/* mostly same info as PearPc */
84
int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
85
{
86
    uint8_t *q;
87
    int len;
88
    
89
    q = buf + 2;
90
    *q++ = 1; /* first session */
91
    *q++ = 1; /* last session */
92

  
93
    *q++ = 1; /* session number */
94
    *q++ = 0x14; /* data track */
95
    *q++ = 0; /* track number */
96
    *q++ = 0xa0; /* lead-in */
97
    *q++ = 0; /* min */
98
    *q++ = 0; /* sec */
99
    *q++ = 0; /* frame */
100
    *q++ = 0;
101
    *q++ = 1; /* first track */
102
    *q++ = 0x00; /* disk type */
103
    *q++ = 0x00;
104
    
105
    *q++ = 1; /* session number */
106
    *q++ = 0x14; /* data track */
107
    *q++ = 0; /* track number */
108
    *q++ = 0xa1;
109
    *q++ = 0; /* min */
110
    *q++ = 0; /* sec */
111
    *q++ = 0; /* frame */
112
    *q++ = 0;
113
    *q++ = 1; /* last track */
114
    *q++ = 0x00;
115
    *q++ = 0x00;
116
    
117
    *q++ = 1; /* session number */
118
    *q++ = 0x14; /* data track */
119
    *q++ = 0; /* track number */
120
    *q++ = 0xa2; /* lead-out */
121
    *q++ = 0; /* min */
122
    *q++ = 0; /* sec */
123
    *q++ = 0; /* frame */
124
    if (msf) {
125
        *q++ = 0; /* reserved */
126
        lba_to_msf(q, nb_sectors);
127
        q += 3;
128
    } else {
129
        cpu_to_be32wu((uint32_t *)q, nb_sectors);
130
        q += 4;
131
    }
132

  
133
    *q++ = 1; /* session number */
134
    *q++ = 0x14; /* ADR, control */
135
    *q++ = 0;    /* track number */
136
    *q++ = 1;    /* point */
137
    *q++ = 0; /* min */
138
    *q++ = 0; /* sec */
139
    *q++ = 0; /* frame */
140
    if (msf) {
141
        *q++ = 0; 
142
        lba_to_msf(q, 0);
143
        q += 3;
144
    } else {
145
        *q++ = 0; 
146
        *q++ = 0; 
147
        *q++ = 0; 
148
        *q++ = 0; 
149
    }
150

  
151
    len = q - buf;
152
    cpu_to_be16wu((uint16_t *)buf, len - 2);
153
    return len;
154
}
155

  
156

  
b/hw/esp.c
38 38
#define ESPDMA_REGS 4
39 39
#define ESPDMA_MAXADDR (ESPDMA_REGS * 4 - 1)
40 40
#define ESP_MAXREG 0x3f
41
#define TI_BUFSZ 1024*1024 // XXX
41
#define TI_BUFSZ 32
42 42
#define DMA_VER 0xa0000000
43 43
#define DMA_INTR 1
44 44
#define DMA_INTREN 0x10
45
#define DMA_WRITE_MEM 0x100
45 46
#define DMA_LOADED 0x04000000
46 47
typedef struct ESPState ESPState;
47 48

  
48
typedef int ESPDMAFunc(ESPState *s, 
49
                       target_phys_addr_t phys_addr, 
50
                       int transfer_size1);
51

  
52 49
struct ESPState {
53 50
    BlockDriverState **bd;
54 51
    uint8_t rregs[ESP_MAXREG];
......
57 54
    uint32_t espdmaregs[ESPDMA_REGS];
58 55
    uint32_t ti_size;
59 56
    uint32_t ti_rptr, ti_wptr;
60
    int ti_dir;
61 57
    uint8_t ti_buf[TI_BUFSZ];
62 58
    int dma;
63
    ESPDMAFunc *dma_cb;
64
    int64_t offset, len;
65
    int target;
59
    SCSIDevice *scsi_dev[MAX_DISKS];
60
    SCSIDevice *current_dev;
66 61
};
67 62

  
68 63
#define STAT_DO 0x00
......
83 78
#define SEQ_0 0x0
84 79
#define SEQ_CD 0x4
85 80

  
86
/* XXX: stolen from ide.c, move to common ATAPI/SCSI library */
87
static void lba_to_msf(uint8_t *buf, int lba)
88
{
89
    lba += 150;
90
    buf[0] = (lba / 75) / 60;
91
    buf[1] = (lba / 75) % 60;
92
    buf[2] = lba % 75;
93
}
94

  
95
static inline void cpu_to_ube16(uint8_t *buf, int val)
96
{
97
    buf[0] = val >> 8;
98
    buf[1] = val;
99
}
100

  
101
static inline void cpu_to_ube32(uint8_t *buf, unsigned int val)
102
{
103
    buf[0] = val >> 24;
104
    buf[1] = val >> 16;
105
    buf[2] = val >> 8;
106
    buf[3] = val;
107
}
108

  
109
/* same toc as bochs. Return -1 if error or the toc length */
110
/* XXX: check this */
111
static int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
112
{
113
    uint8_t *q;
114
    int len;
115
    
116
    if (start_track > 1 && start_track != 0xaa)
117
        return -1;
118
    q = buf + 2;
119
    *q++ = 1; /* first session */
120
    *q++ = 1; /* last session */
121
    if (start_track <= 1) {
122
        *q++ = 0; /* reserved */
123
        *q++ = 0x14; /* ADR, control */
124
        *q++ = 1;    /* track number */
125
        *q++ = 0; /* reserved */
126
        if (msf) {
127
            *q++ = 0; /* reserved */
128
            lba_to_msf(q, 0);
129
            q += 3;
130
        } else {
131
            /* sector 0 */
132
            cpu_to_ube32(q, 0);
133
            q += 4;
134
        }
135
    }
136
    /* lead out track */
137
    *q++ = 0; /* reserved */
138
    *q++ = 0x16; /* ADR, control */
139
    *q++ = 0xaa; /* track number */
140
    *q++ = 0; /* reserved */
141
    if (msf) {
142
        *q++ = 0; /* reserved */
143
        lba_to_msf(q, nb_sectors);
144
        q += 3;
145
    } else {
146
        cpu_to_ube32(q, nb_sectors);
147
        q += 4;
148
    }
149
    len = q - buf;
150
    cpu_to_ube16(buf, len - 2);
151
    return len;
152
}
153

  
154
/* mostly same info as PearPc */
155
static int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, 
156
                              int session_num)
157
{
158
    uint8_t *q;
159
    int len;
160
    
161
    q = buf + 2;
162
    *q++ = 1; /* first session */
163
    *q++ = 1; /* last session */
164

  
165
    *q++ = 1; /* session number */
166
    *q++ = 0x14; /* data track */
167
    *q++ = 0; /* track number */
168
    *q++ = 0xa0; /* lead-in */
169
    *q++ = 0; /* min */
170
    *q++ = 0; /* sec */
171
    *q++ = 0; /* frame */
172
    *q++ = 0;
173
    *q++ = 1; /* first track */
174
    *q++ = 0x00; /* disk type */
175
    *q++ = 0x00;
176
    
177
    *q++ = 1; /* session number */
178
    *q++ = 0x14; /* data track */
179
    *q++ = 0; /* track number */
180
    *q++ = 0xa1;
181
    *q++ = 0; /* min */
182
    *q++ = 0; /* sec */
183
    *q++ = 0; /* frame */
184
    *q++ = 0;
185
    *q++ = 1; /* last track */
186
    *q++ = 0x00;
187
    *q++ = 0x00;
188
    
189
    *q++ = 1; /* session number */
190
    *q++ = 0x14; /* data track */
191
    *q++ = 0; /* track number */
192
    *q++ = 0xa2; /* lead-out */
193
    *q++ = 0; /* min */
194
    *q++ = 0; /* sec */
195
    *q++ = 0; /* frame */
196
    if (msf) {
197
        *q++ = 0; /* reserved */
198
        lba_to_msf(q, nb_sectors);
199
        q += 3;
200
    } else {
201
        cpu_to_ube32(q, nb_sectors);
202
        q += 4;
203
    }
204

  
205
    *q++ = 1; /* session number */
206
    *q++ = 0x14; /* ADR, control */
207
    *q++ = 0;    /* track number */
208
    *q++ = 1;    /* point */
209
    *q++ = 0; /* min */
210
    *q++ = 0; /* sec */
211
    *q++ = 0; /* frame */
212
    if (msf) {
213
        *q++ = 0; 
214
        lba_to_msf(q, 0);
215
        q += 3;
216
    } else {
217
        *q++ = 0; 
218
        *q++ = 0; 
219
        *q++ = 0; 
220
        *q++ = 0; 
221
    }
222

  
223
    len = q - buf;
224
    cpu_to_ube16(buf, len - 2);
225
    return len;
226
}
227

  
228
static int esp_write_dma_cb(ESPState *s, 
229
                            target_phys_addr_t phys_addr, 
230
                            int transfer_size1)
231
{
232
    int len;
233
    if (bdrv_get_type_hint(s->bd[s->target]) == BDRV_TYPE_CDROM) {
234
        len = transfer_size1/2048;
235
    } else {
236
        len = transfer_size1/512;
237
    }
238
    DPRINTF("Write callback (offset %lld len %lld size %d trans_size %d)\n",
239
            s->offset, s->len, s->ti_size, transfer_size1);
240

  
241
    bdrv_write(s->bd[s->target], s->offset, s->ti_buf+s->ti_rptr, len);
242
    s->offset+=len;
243
    return 0;
244
}
245

  
246 81
static void handle_satn(ESPState *s)
247 82
{
248 83
    uint8_t buf[32];
249 84
    uint32_t dmaptr, dmalen;
250
    unsigned int i;
251
    int64_t nb_sectors;
252 85
    int target;
86
    int32_t datalen;
253 87

  
254 88
    dmalen = s->wregs[0] | (s->wregs[1] << 8);
255 89
    target = s->wregs[4] & 7;
256 90
    DPRINTF("Select with ATN len %d target %d\n", dmalen, target);
257 91
    if (s->dma) {
258 92
	dmaptr = iommu_translate(s->espdmaregs[1]);
259
	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr);
93
	DPRINTF("DMA Direction: %c, addr 0x%8.8x\n",
94
                s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', dmaptr);
260 95
	cpu_physical_memory_read(dmaptr, buf, dmalen);
261 96
    } else {
262 97
	buf[0] = 0;
263 98
	memcpy(&buf[1], s->ti_buf, dmalen);
264 99
	dmalen++;
265 100
    }
266
    for (i = 0; i < dmalen; i++) {
267
	DPRINTF("Command %2.2x\n", buf[i]);
268
    }
269
    s->ti_dir = 0;
101

  
270 102
    s->ti_size = 0;
271 103
    s->ti_rptr = 0;
272 104
    s->ti_wptr = 0;
273 105

  
274
    if (target >= 4 || !s->bd[target]) { // No such drive
106
    if (target >= 4 || !s->scsi_dev[target]) {
107
        // No such drive
275 108
	s->rregs[4] = STAT_IN;
276 109
	s->rregs[5] = INTR_DC;
277 110
	s->rregs[6] = SEQ_0;
......
279 112
	pic_set_irq(s->irq, 1);
280 113
	return;
281 114
    }
282
    switch (buf[1]) {
283
    case 0x0:
284
	DPRINTF("Test Unit Ready (len %d)\n", buf[5]);
285
	break;
286
    case 0x12:
287
	DPRINTF("Inquiry (len %d)\n", buf[5]);
288
	memset(s->ti_buf, 0, 36);
289
	if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
290
	    s->ti_buf[0] = 5;
291
	    memcpy(&s->ti_buf[16], "QEMU CDROM     ", 16);
292
	} else {
293
	    s->ti_buf[0] = 0;
294
	    memcpy(&s->ti_buf[16], "QEMU HARDDISK  ", 16);
295
	}
296
	memcpy(&s->ti_buf[8], "QEMU   ", 8);
297
	s->ti_buf[2] = 1;
298
	s->ti_buf[3] = 2;
299
	s->ti_buf[4] = 32;
300
	s->ti_dir = 1;
301
	s->ti_size = 36;
302
	break;
303
    case 0x1a:
304
	DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf[3], buf[5]);
305
	break;
306
    case 0x25:
307
	DPRINTF("Read Capacity (len %d)\n", buf[5]);
308
	memset(s->ti_buf, 0, 8);
309
	bdrv_get_geometry(s->bd[target], &nb_sectors);
310
	s->ti_buf[0] = (nb_sectors >> 24) & 0xff;
311
	s->ti_buf[1] = (nb_sectors >> 16) & 0xff;
312
	s->ti_buf[2] = (nb_sectors >> 8) & 0xff;
313
	s->ti_buf[3] = nb_sectors & 0xff;
314
	s->ti_buf[4] = 0;
315
	s->ti_buf[5] = 0;
316
	if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM)
317
	    s->ti_buf[6] = 8; // sector size 2048
318
	else
319
	    s->ti_buf[6] = 2; // sector size 512
320
	s->ti_buf[7] = 0;
321
	s->ti_dir = 1;
322
	s->ti_size = 8;
323
	break;
324
    case 0x28:
325
	{
326
	    int64_t offset, len;
327

  
328
	    if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
329
		offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]) * 4;
330
		len = ((buf[8] << 8) | buf[9]) * 4;
331
		s->ti_size = len * 2048;
332
	    } else {
333
		offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6];
334
		len = (buf[8] << 8) | buf[9];
335
		s->ti_size = len * 512;
336
	    }
337
	    DPRINTF("Read (10) (offset %lld len %lld)\n", offset, len);
338
            if (s->ti_size > TI_BUFSZ) {
339
                DPRINTF("size too large %d\n", s->ti_size);
340
            }
341
	    bdrv_read(s->bd[target], offset, s->ti_buf, len);
342
	    // XXX error handling
343
	    s->ti_dir = 1;
344
	    s->ti_rptr = 0;
345
	    break;
346
	}
347
    case 0x2a:
348
	{
349
	    int64_t offset, len;
350

  
351
	    if (bdrv_get_type_hint(s->bd[target]) == BDRV_TYPE_CDROM) {
352
		offset = ((buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6]) * 4;
353
		len = ((buf[8] << 8) | buf[9]) * 4;
354
		s->ti_size = len * 2048;
355
	    } else {
356
		offset = (buf[3] << 24) | (buf[4] << 16) | (buf[5] << 8) | buf[6];
357
		len = (buf[8] << 8) | buf[9];
358
		s->ti_size = len * 512;
359
	    }
360
	    DPRINTF("Write (10) (offset %lld len %lld)\n", offset, len);
361
            if (s->ti_size > TI_BUFSZ) {
362
                DPRINTF("size too large %d\n", s->ti_size);
363
            }
364
            s->dma_cb = esp_write_dma_cb;
365
            s->offset = offset;
366
            s->len = len;
367
            s->target = target;
368
            s->ti_rptr = 0;
369
	    // XXX error handling
370
	    s->ti_dir = 0;
371
	    break;
372
	}
373
    case 0x43:
374
        {
375
            int start_track, format, msf, len;
376

  
377
            msf = buf[2] & 2;
378
            format = buf[3] & 0xf;
379
            start_track = buf[7];
380
            bdrv_get_geometry(s->bd[target], &nb_sectors);
381
            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
382
            switch(format) {
383
            case 0:
384
                len = cdrom_read_toc(nb_sectors, buf, msf, start_track);
385
                if (len < 0)
386
                    goto error_cmd;
387
                s->ti_size = len;
388
                break;
389
            case 1:
390
                /* multi session : only a single session defined */
391
                memset(buf, 0, 12);
392
                buf[1] = 0x0a;
393
                buf[2] = 0x01;
394
                buf[3] = 0x01;
395
                s->ti_size = 12;
396
                break;
397
            case 2:
398
                len = cdrom_read_toc_raw(nb_sectors, buf, msf, start_track);
399
                if (len < 0)
400
                    goto error_cmd;
401
                s->ti_size = len;
402
                break;
403
            default:
404
            error_cmd:
405
                DPRINTF("Read TOC error\n");
406
                // XXX error handling
407
                break;
408
            }
409
	    s->ti_dir = 1;
410
            break;
115
    s->current_dev = s->scsi_dev[target];
116
    datalen = scsi_send_command(s->current_dev, 0, &buf[1]);
117
    if (datalen == 0) {
118
        s->ti_size = 0;
119
    } else {
120
        s->rregs[4] = STAT_IN | STAT_TC;
121
        if (datalen > 0) {
122
            s->rregs[4] |= STAT_DI;
123
            s->ti_size = datalen;
124
        } else {
125
            s->rregs[4] |= STAT_DO;
126
            s->ti_size = -datalen;
411 127
        }
412
    default:
413
	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[1]);
414
	break;
415 128
    }
416
    s->rregs[4] = STAT_IN | STAT_TC | STAT_DI;
417 129
    s->rregs[5] = INTR_BS | INTR_FC;
418 130
    s->rregs[6] = SEQ_CD;
419 131
    s->espdmaregs[0] |= DMA_INTR;
......
427 139
    DPRINTF("Transfer status len %d\n", len);
428 140
    if (s->dma) {
429 141
	dmaptr = iommu_translate(s->espdmaregs[1]);
430
	DPRINTF("DMA Direction: %c\n", s->espdmaregs[0] & 0x100? 'w': 'r');
142
	DPRINTF("DMA Direction: %c\n",
143
                s->espdmaregs[0] & DMA_WRITE_MEM ? 'w': 'r');
431 144
	cpu_physical_memory_write(dmaptr, buf, len);
432 145
	s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
433 146
	s->rregs[5] = INTR_BS | INTR_FC;
......
446 159

  
447 160
static const uint8_t okbuf[] = {0, 0};
448 161

  
162
static void esp_command_complete(void *opaque, uint32_t tag, int fail)
163
{
164
    ESPState *s = (ESPState *)opaque;
165

  
166
    DPRINTF("SCSI Command complete\n");
167
    if (s->ti_size != 0)
168
        DPRINTF("SCSI command completed unexpectedly\n");
169
    s->ti_size = 0;
170
    /* ??? Report failures.  */
171
    if (fail)
172
        DPRINTF("Command failed\n");
173
    s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
174
}
175

  
449 176
static void handle_ti(ESPState *s)
450 177
{
451 178
    uint32_t dmaptr, dmalen, minlen, len, from, to;
452 179
    unsigned int i;
180
    int to_device;
181
    uint8_t buf[TARGET_PAGE_SIZE];
453 182

  
454 183
    dmalen = s->wregs[0] | (s->wregs[1] << 8);
455 184
    if (dmalen==0) {
......
460 189
    DPRINTF("Transfer Information len %d\n", minlen);
461 190
    if (s->dma) {
462 191
	dmaptr = iommu_translate(s->espdmaregs[1]);
463
	DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x %d %d\n", s->espdmaregs[0] & 0x100? 'w': 'r', dmaptr, s->ti_size, s->ti_rptr, s->ti_dir);
192
        /* Check if the transfer writes to to reads from the device.  */
193
        to_device = (s->espdmaregs[0] & DMA_WRITE_MEM) == 0;
194
	DPRINTF("DMA Direction: %c, addr 0x%8.8x %08x\n",
195
                to_device ? 'r': 'w', dmaptr, s->ti_size);
464 196
	from = s->espdmaregs[1];
465 197
	to = from + minlen;
466 198
	for (i = 0; i < minlen; i += len, from += len) {
......
471 203
	       len = to - from;
472 204
            }
473 205
            DPRINTF("DMA address p %08x v %08x len %08x, from %08x, to %08x\n", dmaptr, s->espdmaregs[1] + i, len, from, to);
474
	    if (s->ti_dir)
475
		cpu_physical_memory_write(dmaptr, &s->ti_buf[s->ti_rptr + i], len);
476
	    else
477
		cpu_physical_memory_read(dmaptr, &s->ti_buf[s->ti_rptr + i], len);
206
            s->ti_size -= len;
207
            if (to_device) {
208
                cpu_physical_memory_read(dmaptr, buf, len);
209
                scsi_write_data(s->current_dev, buf, len);
210
            } else {
211
                scsi_read_data(s->current_dev, buf, len);
212
                cpu_physical_memory_write(dmaptr, buf, len);
213
            }
478 214
	}
479
        if (s->dma_cb) {
480
            s->dma_cb(s, s->espdmaregs[1], minlen);
481
        }
482
        if (minlen < s->ti_size) {
483
	    s->rregs[4] = STAT_IN | STAT_TC | (s->ti_dir ? STAT_DO : STAT_DI);
215
        if (s->ti_size) {
216
	    s->rregs[4] = STAT_IN | STAT_TC | (to_device ? STAT_DO : STAT_DI);
484 217
	    s->ti_size -= minlen;
485
	    s->ti_rptr += minlen;
486
        } else {
487
	    s->rregs[4] = STAT_IN | STAT_TC | STAT_ST;
488
            s->dma_cb = NULL;
489
            s->offset = 0;
490
            s->len = 0;
491
            s->target = 0;
492
            s->ti_rptr = 0;
493 218
        }
494 219
        s->rregs[5] = INTR_BS;
495 220
	s->rregs[6] = 0;
496 221
	s->rregs[7] = 0;
497 222
	s->espdmaregs[0] |= DMA_INTR;
498
    } else {
499
	s->ti_size = minlen;
500
	s->ti_rptr = 0;
501
	s->ti_wptr = 0;
502
	s->rregs[7] = minlen;
503 223
    }	
504 224
    pic_set_irq(s->irq, 1);
505 225
}
......
514 234
    s->ti_size = 0;
515 235
    s->ti_rptr = 0;
516 236
    s->ti_wptr = 0;
517
    s->ti_dir = 0;
518 237
    s->dma = 0;
519
    s->dma_cb = NULL;
520 238
}
521 239

  
522 240
static uint32_t esp_mem_readb(void *opaque, target_phys_addr_t addr)
......
531 249
	// FIFO
532 250
	if (s->ti_size > 0) {
533 251
	    s->ti_size--;
534
	    s->rregs[saddr] = s->ti_buf[s->ti_rptr++];
252
            if ((s->rregs[4] & 6) == 0) {
253
                /* Data in/out.  */
254
                scsi_read_data(s->current_dev, &s->rregs[2], 0);
255
            } else {
256
                s->rregs[2] = s->ti_buf[s->ti_rptr++];
257
            }
535 258
	    pic_set_irq(s->irq, 1);
536 259
	}
537 260
	if (s->ti_size == 0) {
......
566 289
        break;
567 290
    case 2:
568 291
	// FIFO
569
	s->ti_size++;
570
	s->ti_buf[s->ti_wptr++] = val & 0xff;
292
        if ((s->rregs[4] & 6) == 0) {
293
            uint8_t buf;
294
            buf = val & 0xff;
295
            s->ti_size--;
296
            scsi_write_data(s->current_dev, &buf, 0);
297
        } else {
298
            s->ti_size++;
299
            s->ti_buf[s->ti_wptr++] = val & 0xff;
300
        }
571 301
	break;
572 302
    case 3:
573 303
        s->rregs[saddr] = val;
......
723 453
    qemu_put_be32s(f, &s->ti_size);
724 454
    qemu_put_be32s(f, &s->ti_rptr);
725 455
    qemu_put_be32s(f, &s->ti_wptr);
726
    qemu_put_be32s(f, &s->ti_dir);
727 456
    qemu_put_buffer(f, s->ti_buf, TI_BUFSZ);
728 457
    qemu_put_be32s(f, &s->dma);
729 458
}
......
744 473
    qemu_get_be32s(f, &s->ti_size);
745 474
    qemu_get_be32s(f, &s->ti_rptr);
746 475
    qemu_get_be32s(f, &s->ti_wptr);
747
    qemu_get_be32s(f, &s->ti_dir);
748 476
    qemu_get_buffer(f, s->ti_buf, TI_BUFSZ);
749 477
    qemu_get_be32s(f, &s->dma);
750 478

  
......
755 483
{
756 484
    ESPState *s;
757 485
    int esp_io_memory, espdma_io_memory;
486
    int i;
758 487

  
759 488
    s = qemu_mallocz(sizeof(ESPState));
760 489
    if (!s)
......
773 502

  
774 503
    register_savevm("esp", espaddr, 1, esp_save, esp_load, s);
775 504
    qemu_register_reset(esp_reset, s);
505
    for (i = 0; i < MAX_DISKS; i++) {
506
        if (bs_table[i]) {
507
            s->scsi_dev[i] =
508
                scsi_disk_init(bs_table[i], esp_command_complete, s);
509
        }
510
    }
776 511
}
777 512

  
b/hw/ide.c
1082 1082
    }
1083 1083
}
1084 1084

  
1085
/* same toc as bochs. Return -1 if error or the toc length */
1086
/* XXX: check this */
1087
static int cdrom_read_toc(IDEState *s, uint8_t *buf, int msf, int start_track)
1088
{
1089
    uint8_t *q;
1090
    int nb_sectors, len;
1091
    
1092
    if (start_track > 1 && start_track != 0xaa)
1093
        return -1;
1094
    q = buf + 2;
1095
    *q++ = 1; /* first session */
1096
    *q++ = 1; /* last session */
1097
    if (start_track <= 1) {
1098
        *q++ = 0; /* reserved */
1099
        *q++ = 0x14; /* ADR, control */
1100
        *q++ = 1;    /* track number */
1101
        *q++ = 0; /* reserved */
1102
        if (msf) {
1103
            *q++ = 0; /* reserved */
1104
            lba_to_msf(q, 0);
1105
            q += 3;
1106
        } else {
1107
            /* sector 0 */
1108
            cpu_to_ube32(q, 0);
1109
            q += 4;
1110
        }
1111
    }
1112
    /* lead out track */
1113
    *q++ = 0; /* reserved */
1114
    *q++ = 0x16; /* ADR, control */
1115
    *q++ = 0xaa; /* track number */
1116
    *q++ = 0; /* reserved */
1117
    nb_sectors = s->nb_sectors >> 2;
1118
    if (msf) {
1119
        *q++ = 0; /* reserved */
1120
        lba_to_msf(q, nb_sectors);
1121
        q += 3;
1122
    } else {
1123
        cpu_to_ube32(q, nb_sectors);
1124
        q += 4;
1125
    }
1126
    len = q - buf;
1127
    cpu_to_ube16(buf, len - 2);
1128
    return len;
1129
}
1130

  
1131
/* mostly same info as PearPc */
1132
static int cdrom_read_toc_raw(IDEState *s, uint8_t *buf, int msf, 
1133
                              int session_num)
1134
{
1135
    uint8_t *q;
1136
    int nb_sectors, len;
1137
    
1138
    q = buf + 2;
1139
    *q++ = 1; /* first session */
1140
    *q++ = 1; /* last session */
1141

  
1142
    *q++ = 1; /* session number */
1143
    *q++ = 0x14; /* data track */
1144
    *q++ = 0; /* track number */
1145
    *q++ = 0xa0; /* lead-in */
1146
    *q++ = 0; /* min */
1147
    *q++ = 0; /* sec */
1148
    *q++ = 0; /* frame */
1149
    *q++ = 0;
1150
    *q++ = 1; /* first track */
1151
    *q++ = 0x00; /* disk type */
1152
    *q++ = 0x00;
1153
    
1154
    *q++ = 1; /* session number */
1155
    *q++ = 0x14; /* data track */
1156
    *q++ = 0; /* track number */
1157
    *q++ = 0xa1;
1158
    *q++ = 0; /* min */
1159
    *q++ = 0; /* sec */
1160
    *q++ = 0; /* frame */
1161
    *q++ = 0;
1162
    *q++ = 1; /* last track */
1163
    *q++ = 0x00;
1164
    *q++ = 0x00;
1165
    
1166
    *q++ = 1; /* session number */
1167
    *q++ = 0x14; /* data track */
1168
    *q++ = 0; /* track number */
1169
    *q++ = 0xa2; /* lead-out */
1170
    *q++ = 0; /* min */
1171
    *q++ = 0; /* sec */
1172
    *q++ = 0; /* frame */
1173
    nb_sectors = s->nb_sectors >> 2;
1174
    if (msf) {
1175
        *q++ = 0; /* reserved */
1176
        lba_to_msf(q, nb_sectors);
1177
        q += 3;
1178
    } else {
1179
        cpu_to_ube32(q, nb_sectors);
1180
        q += 4;
1181
    }
1182

  
1183
    *q++ = 1; /* session number */
1184
    *q++ = 0x14; /* ADR, control */
1185
    *q++ = 0;    /* track number */
1186
    *q++ = 1;    /* point */
1187
    *q++ = 0; /* min */
1188
    *q++ = 0; /* sec */
1189
    *q++ = 0; /* frame */
1190
    if (msf) {
1191
        *q++ = 0; 
1192
        lba_to_msf(q, 0);
1193
        q += 3;
1194
    } else {
1195
        *q++ = 0; 
1196
        *q++ = 0; 
1197
        *q++ = 0; 
1198
        *q++ = 0; 
1199
    }
1200

  
1201
    len = q - buf;
1202
    cpu_to_ube16(buf, len - 2);
1203
    return len;
1204
}
1205

  
1206 1085
static void ide_atapi_cmd(IDEState *s)
1207 1086
{
1208 1087
    const uint8_t *packet;
......
1449 1328
            start_track = packet[6];
1450 1329
            switch(format) {
1451 1330
            case 0:
1452
                len = cdrom_read_toc(s, buf, msf, start_track);
1331
                len = cdrom_read_toc(s->nb_sectors >> 2, buf, msf, start_track);
1453 1332
                if (len < 0)
1454 1333
                    goto error_cmd;
1455 1334
                ide_atapi_cmd_reply(s, len, max_len);
......
1463 1342
                ide_atapi_cmd_reply(s, 12, max_len);
1464 1343
                break;
1465 1344
            case 2:
1466
                len = cdrom_read_toc_raw(s, buf, msf, start_track);
1345
                len = cdrom_read_toc_raw(s->nb_sectors >> 2, buf, msf, start_track);
1467 1346
                if (len < 0)
1468 1347
                    goto error_cmd;
1469 1348
                ide_atapi_cmd_reply(s, len, max_len);
b/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
    int sector_size;
35
    /* When transfering data buf_pos and buf_len contain a partially
36
       transferred block of data (or response to a command), and
37
       sector/sector_count identify any remaining sectors.  */
38
    /* ??? We should probably keep track of whether the data trasfer is
39
       a read or a write.  Currently we rely on the host getting it right.  */
40
    int sector;
41
    int sector_count;
42
    int buf_pos;
43
    int buf_len;
44
    int sense;
45
    char buf[2048];
46
    scsi_completionfn completion;
47
    void *opaque;
48
};
49

  
50
static void scsi_command_complete(SCSIDevice *s, int sense)
51
{
52
    s->sense = sense;
53
    s->completion(s->opaque, s->tag, sense != SENSE_NO_SENSE);
54
}
55

  
56
/* Read data from a scsi device.  Returns nonzero on failure.  */
57
int scsi_read_data(SCSIDevice *s, uint8_t *data, uint32_t len)
58
{
59
    uint32_t n;
60

  
61
    DPRINTF("Read %d (%d/%d)\n", len, s->buf_len, s->sector_count);
62
    if (s->buf_len == 0 && s->sector_count == 0)
63
        return 1;
64

  
65
    if (s->buf_len) {
66
        n = s->buf_len;
67
        if (n > len)
68
            n = len;
69
        memcpy(data, s->buf + s->buf_pos, n);
70
        s->buf_pos += n;
71
        s->buf_len -= n;
72
        data += n;
73
        len -= n;
74
        if (s->buf_len == 0)
75
            s->buf_pos = 0;
76
    }
77

  
78
    n = len / s->sector_size;
79
    if (n > s->sector_count)
80
      n = s->sector_count;
81

  
82
    if (n != 0) {
83
        bdrv_read(s->bdrv, s->sector, data, n);
84
        data += n * s->sector_size;
85
        len -= n * s->sector_size;
86
        s->sector += n;
87
        s->sector_count -= n;
88
    }
89

  
90
    if (len && s->sector_count) {
91
        bdrv_read(s->bdrv, s->sector, s->buf, 1);
92
        s->sector++;
93
        s->sector_count--;
94
        s->buf_pos = 0;
95
        s->buf_len = s->sector_size;
96
        /* Recurse to complete the partial read.  */
97
        return scsi_read_data(s, data, len);
98
    }
99

  
100
    if (len != 0)
101
        return 1;
102

  
103
    if (s->buf_len == 0 && s->sector_count == 0)
104
        scsi_command_complete(s, SENSE_NO_SENSE);
105

  
106
    return 0;
107
}
108

  
109
/* Read data to a scsi device.  Returns nonzero on failure.  */
110
int scsi_write_data(SCSIDevice *s, uint8_t *data, uint32_t len)
111
{
112
    uint32_t n;
113

  
114
    DPRINTF("Write %d (%d/%d)\n", len, s->buf_len, s->sector_count);
115
    if (s->buf_pos != 0) {
116
        BADF("Bad state on write\n");
117
        return 1;
118
    }
119

  
120
    if (s->sector_count == 0)
121
        return 1;
122

  
123
    if (s->buf_len != 0 || len < s->sector_size) {
124
        n = s->sector_size - s->buf_len;
125
        if (n > len)
126
            n = len;
127

  
128
        memcpy(s->buf + s->buf_len, data, n);
129
        data += n;
130
        s->buf_len += n;
131
        len -= n;
132
        if (s->buf_len == s->sector_size) {
133
            /* A full sector has been accumulated. Write it to disk.  */
134
            bdrv_write(s->bdrv, s->sector, s->buf, 1);
135
            s->buf_len = 0;
136
            s->sector++;
137
            s->sector_count--;
138
        }
139
    }
140

  
141
    n = len / s->sector_size;
142
    if (n > s->sector_count)
143
        n = s->sector_count;
144

  
145
    if (n != 0) {
146
        bdrv_write(s->bdrv, s->sector, data, n);
147
        data += n * s->sector_size;
148
        len -= n * s->sector_size;
149
        s->sector += n;
150
        s->sector_count -= n;
151
    }
152

  
153
    if (len >= s->sector_size)
154
        return 1;
155

  
156
    if (len && s->sector_count) {
157
        /* Recurse to complete the partial write.  */
158
        return scsi_write_data(s, data, len);
159
    }
160

  
161
    if (len != 0)
162
        return 1;
163

  
164
    if (s->sector_count == 0)
165
        scsi_command_complete(s, SENSE_NO_SENSE);
166

  
167
    return 0;
168
}
169

  
170
/* Execute a scsi command.  Returns the length of the data expected by the
171
   command.  This will be Positive for data transfers from the device
172
   (eg. disk reads), negative for transfers to the device (eg. disk writes),
173
   and zero if the command does not transfer any data.  */
174

  
175
int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf)
176
{
177
    int64_t nb_sectors;
178
    uint32_t lba;
179
    uint32_t len;
180
    int cmdlen;
181
    int is_write;
182

  
183
    s->command = buf[0];
184
    s->tag = tag;
185
    s->sector_count = 0;
186
    s->buf_pos = 0;
187
    s->buf_len = 0;
188
    is_write = 0;
189
    DPRINTF("Command: 0x%02x", buf[0]);
190
    switch (s->command >> 5) {
191
    case 0:
192
        lba = buf[3] | (buf[2] << 8) | ((buf[1] & 0x1f) << 16);
193
        len = buf[4];
194
        cmdlen = 6;
195
        break;
196
    case 1:
197
    case 2:
198
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
199
        len = buf[8] | (buf[7] << 8);
200
        cmdlen = 10;
201
        break;
202
    case 4:
203
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
204
        len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
205
        cmdlen = 16;
206
        break;
207
    case 5:
208
        lba = buf[5] | (buf[4] << 8) | (buf[3] << 16) | (buf[2] << 24);
209
        len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
210
        cmdlen = 12;
211
        break;
212
    default:
213
        BADF("Unsupported command length\n");
214
        goto fail;
215
    }
216
#ifdef DEBUG_SCSI
217
    {
218
        int i;
219
        for (i = 1; i < cmdlen; i++) {
220
            printf(" 0x%02x", buf[i]);
221
        }
222
        printf("\n");
223
    }
224
#endif
225
    if (buf[1] >> 5) {
226
        /* Only LUN 0 supported.  */
227
        goto fail;
228
    }
229
    switch (s->command) {
230
    case 0x0:
231
	DPRINTF("Test Unit Ready\n");
232
	break;
233
    case 0x03:
234
        DPRINTF("Request Sense (len %d)\n", len);
235
        if (len < 4)
236
            goto fail;
237
        memset(buf, 0, 4);
238
        s->buf[0] = 0xf0;
239
        s->buf[1] = 0;
240
        s->buf[2] = s->sense;
241
        s->buf_len = 4;
242
        break;
243
    case 0x12:
244
	DPRINTF("Inquiry (len %d)\n", len);
245
        if (len < 36) {
246
            BADF("Inquiry buffer too small (%d)\n", len);
247
        }
248
	memset(s->buf, 0, 36);
249
	if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
250
	    s->buf[0] = 5;
251
            s->buf[1] = 0x80;
252
	    memcpy(&s->buf[16], "QEMU CDROM     ", 16);
253
	} else {
254
	    s->buf[0] = 0;
255
	    memcpy(&s->buf[16], "QEMU HARDDISK  ", 16);
256
	}
257
	memcpy(&s->buf[8], "QEMU   ", 8);
258
	s->buf[2] = 3; /* SCSI-3 */
259
	s->buf[3] = 2; /* Format 2 */
260
	s->buf[4] = 32;
261
	s->buf_len = 36;
262
	break;
263
    case 0x16:
264
        DPRINTF("Reserve(6)\n");
265
        if (buf[1] & 1)
266
            goto fail;
267
        break;
268
    case 0x17:
269
        DPRINTF("Release(6)\n");
270
        if (buf[1] & 1)
271
            goto fail;
272
        break;
273
    case 0x1a:
274
	DPRINTF("Mode Sense(6) (page %d, len %d)\n", buf[2], len);
275
        memset(s->buf, 0, 4);
276
        s->buf[0] = 0x16; /* Mode data length (4 + 0x12).  */
277
        s->buf[1] = 0; /* Default media type.  */
278
        s->buf[2] = 0; /* Write enabled.  */
279
        s->buf[3] = 0; /* Block descriptor length.  */
280
        /* Caching page.  */
281
        s->buf[4 + 0] = 8;
282
        s->buf[4 + 1] = 0x12;
283
        s->buf[4 + 2] = 4; /* WCE */
284
        if (len > 0x16)
285
            len = 0x16;
286
        s->buf_len = len;
287
	break;
288
    case 0x25:
289
	DPRINTF("Read Capacity\n");
290
        /* The normal LEN field for this command is zero.  */
291
	memset(s->buf, 0, 8);
292
	bdrv_get_geometry(s->bdrv, &nb_sectors);
293
	s->buf[0] = (nb_sectors >> 24) & 0xff;
294
	s->buf[1] = (nb_sectors >> 16) & 0xff;
295
	s->buf[2] = (nb_sectors >> 8) & 0xff;
296
	s->buf[3] = nb_sectors & 0xff;
297
	s->buf[4] = 0;
298
	s->buf[5] = 0;
299
        s->buf[6] = s->sector_size >> 8;
300
	s->buf[7] = s->sector_size & 0xff;
301
	s->buf_len = 8;
302
	break;
303
    case 0x08:
304
    case 0x28:
305
        DPRINTF("Read (sector %d, count %d)\n", lba, len);
306
        s->sector = lba;
307
        s->sector_count = len;
308
        break;
309
    case 0x0a:
310
    case 0x2a:
311
        DPRINTF("Write (sector %d, count %d)\n", lba, len);
312
        s->sector = lba;
313
        s->sector_count = len;
314
        is_write = 1;
315
        break;
316
    case 0x43:
317
        {
318
            int start_track, format, msf;
319

  
320
            msf = buf[1] & 2;
321
            format = buf[2] & 0xf;
322
            start_track = buf[6];
323
            bdrv_get_geometry(s->bdrv, &nb_sectors);
324
            DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1);
325
            switch(format) {
326
            case 0:
327
                len = cdrom_read_toc(nb_sectors, s->buf, msf, start_track);
328
                if (len < 0)
329
                    goto error_cmd;
330
                s->buf_len = len;
331
                break;
332
            case 1:
333
                /* multi session : only a single session defined */
334
                memset(s->buf, 0, 12);
335
                s->buf[1] = 0x0a;
336
                s->buf[2] = 0x01;
337
                s->buf[3] = 0x01;
338
                s->buf_len = 12;
339
                break;
340
            case 2:
341
                len = cdrom_read_toc_raw(nb_sectors, s->buf, msf, start_track);
342
                if (len < 0)
343
                    goto error_cmd;
344
                s->buf_len = len;
345
                break;
346
            default:
347
            error_cmd:
348
                DPRINTF("Read TOC error\n");
349
                goto fail;
350
            }
351
            break;
352
        }
353
    case 0x56:
354
        DPRINTF("Reserve(10)\n");
355
        if (buf[1] & 3)
356
            goto fail;
357
        break;
358
    case 0x57:
359
        DPRINTF("Release(10)\n");
360
        if (buf[1] & 3)
361
            goto fail;
362
        break;
363
    case 0xa0:
364
        DPRINTF("Report LUNs (len %d)\n", len);
365
        if (len < 16)
366
            goto fail;
367
        memset(s->buf, 0, 16);
368
        s->buf[3] = 8;
369
        s->buf_len = 16;
370
        break;
371
    default:
372
	DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
373
    fail:
374
        scsi_command_complete(s, SENSE_ILLEGAL_REQUEST);
375
	return 0;
376
    }
377
    if (s->sector_count == 0 && s->buf_len == 0) {
378
        scsi_command_complete(s, SENSE_NO_SENSE);
379
    }
380
    len = s->sector_count * s->sector_size + s->buf_len;
381
    return is_write ? -len : len;
382
}
383

  
384
void scsi_disk_destroy(SCSIDevice *s)
385
{
386
    bdrv_close(s->bdrv);
387
    qemu_free(s);
388
}
389

  
390
SCSIDevice *scsi_disk_init(BlockDriverState *bdrv,
391
                           scsi_completionfn completion,
392
                           void *opaque)
393
{
394
    SCSIDevice *s;
395

  
396
    s = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
397
    s->bdrv = bdrv;
398
    s->completion = completion;
399
    s->opaque = opaque;
400
    if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) {
401
        s->sector_size = 2048;
402
    } else {
403
        s->sector_size = 512;
404
    }
405

  
406
    return s;
407
}
408

  
b/hw/usb-hid.c
323 323
    return l;
324 324
}
325 325

  
326
static void usb_mouse_handle_reset(USBDevice *dev)
326
static void usb_mouse_handle_reset(USBDevice *dev, int destroy)
327 327
{
328 328
    USBMouseState *s = (USBMouseState *)dev;
329 329

  
330
    if (destroy) {
331
        qemu_add_mouse_event_handler(NULL, NULL, 0);
332
        qemu_free(s);
333
        return;
334
    }
335

  
330 336
    s->dx = 0;
331 337
    s->dy = 0;
332 338
    s->dz = 0;
b/hw/usb-hub.c
199 199
    }
200 200
}
201 201

  
202
static void usb_hub_handle_reset(USBDevice *dev)
202
static void usb_hub_handle_reset(USBDevice *dev, int destroy)
203 203
{
204 204
    /* XXX: do it */
205
    if (destroy)
206
        qemu_free(dev);
205 207
}
206 208

  
207 209
static int usb_hub_handle_control(USBDevice *dev, int request, int value,
b/hw/usb-msd.c
1
/* 
2
 * USB Mass Storage Device emulation
3
 *
4
 * Copyright (c) 2006 CodeSourcery.
5
 * Written by Paul Brook
6
 *
7
 * This code is licenced under the LGPL.
8
 */
9

  
10
#include "vl.h"
11

  
12
//#define DEBUG_MSD
13

  
14
#ifdef DEBUG_MSD
15
#define DPRINTF(fmt, args...) \
16
do { printf("usb-msd: " fmt , ##args); } while (0)
17
#else
18
#define DPRINTF(fmt, args...) do {} while(0)
19
#endif
20

  
21
/* USB requests.  */
22
#define MassStorageReset  0xff
23
#define GetMaxLun         0xfe
24

  
25
enum USBMSDMode {
26
    USB_MSDM_CBW, /* Command Block.  */
27
    USB_MSDM_DATAOUT, /* Tranfer data to device.  */
28
    USB_MSDM_DATAIN, /* Transfer data from device.  */
29
    USB_MSDM_CSW /* Command Status.  */
30
};
31

  
32
typedef struct {
33
    USBDevice dev;
34
    enum USBMSDMode mode;
35
    uint32_t data_len;
36
    uint32_t tag;
37
    SCSIDevice *scsi_dev;
38
    int result;
39
} MSDState;
40

  
41
static const uint8_t qemu_msd_dev_descriptor[] = {
42
	0x12,       /*  u8 bLength; */
43
	0x01,       /*  u8 bDescriptorType; Device */
44
	0x10, 0x00, /*  u16 bcdUSB; v1.0 */
45

  
46
	0x00,	    /*  u8  bDeviceClass; */
47
	0x00,	    /*  u8  bDeviceSubClass; */
48
	0x00,       /*  u8  bDeviceProtocol; [ low/full speeds only ] */
49
	0x08,       /*  u8  bMaxPacketSize0; 8 Bytes */
50

  
51
        /* Vendor and product id are arbitrary.  */
52
	0x00, 0x00, /*  u16 idVendor; */
53
 	0x00, 0x00, /*  u16 idProduct; */
54
	0x00, 0x00, /*  u16 bcdDevice */
55

  
56
	0x01,       /*  u8  iManufacturer; */
57
	0x02,       /*  u8  iProduct; */
58
	0x03,       /*  u8  iSerialNumber; */
59
	0x01        /*  u8  bNumConfigurations; */
60
};
61

  
62
static const uint8_t qemu_msd_config_descriptor[] = {
63

  
64
	/* one configuration */
65
	0x09,       /*  u8  bLength; */
66
	0x02,       /*  u8  bDescriptorType; Configuration */
67
	0x20, 0x00, /*  u16 wTotalLength; */
68
	0x01,       /*  u8  bNumInterfaces; (1) */
69
	0x01,       /*  u8  bConfigurationValue; */
70
	0x00,       /*  u8  iConfiguration; */
71
	0xc0,       /*  u8  bmAttributes; 
72
				 Bit 7: must be set,
73
				     6: Self-powered,
74
				     5: Remote wakeup,
75
				     4..0: resvd */
76
	0x00,       /*  u8  MaxPower; */
77
      
78
	/* one interface */
79
	0x09,       /*  u8  if_bLength; */
80
	0x04,       /*  u8  if_bDescriptorType; Interface */
81
	0x00,       /*  u8  if_bInterfaceNumber; */
82
	0x00,       /*  u8  if_bAlternateSetting; */
83
	0x02,       /*  u8  if_bNumEndpoints; */
84
	0x08,       /*  u8  if_bInterfaceClass; MASS STORAGE */
85
	0x06,       /*  u8  if_bInterfaceSubClass; SCSI */
86
	0x50,       /*  u8  if_bInterfaceProtocol; Bulk Only */
87
	0x00,       /*  u8  if_iInterface; */
88
     
89
	/* Bulk-In endpoint */
90
	0x07,       /*  u8  ep_bLength; */
91
	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
92
	0x81,       /*  u8  ep_bEndpointAddress; IN Endpoint 1 */
93
 	0x02,       /*  u8  ep_bmAttributes; Bulk */
94
 	0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
95
	0x00,       /*  u8  ep_bInterval; */
96

  
97
	/* Bulk-Out endpoint */
98
	0x07,       /*  u8  ep_bLength; */
99
	0x05,       /*  u8  ep_bDescriptorType; Endpoint */
100
	0x02,       /*  u8  ep_bEndpointAddress; OUT Endpoint 2 */
101
 	0x02,       /*  u8  ep_bmAttributes; Bulk */
102
 	0x40, 0x00, /*  u16 ep_wMaxPacketSize; */
103
	0x00        /*  u8  ep_bInterval; */
104
};
105

  
106
static void usb_msd_command_complete(void *opaque, uint32_t tag, int fail)
107
{
108
    MSDState *s = (MSDState *)opaque;
109

  
110
    DPRINTF("Command complete\n");
111
    s->result = fail;
112
    s->mode = USB_MSDM_CSW;
113
}
114

  
115
static void usb_msd_handle_reset(USBDevice *dev, int destroy)
116
{
117
    MSDState *s = (MSDState *)dev;
118

  
119
    DPRINTF("Reset\n");
120
    s->mode = USB_MSDM_CBW;
121
    if (destroy) {
122
        scsi_disk_destroy(s->scsi_dev);
123
        qemu_free(s);
124
    }
125
}
126

  
127
static int usb_msd_handle_control(USBDevice *dev, int request, int value,
128
                                  int index, int length, uint8_t *data)
129
{
130
    MSDState *s = (MSDState *)dev;
131
    int ret = 0;
132

  
133
    switch (request) {
134
    case DeviceRequest | USB_REQ_GET_STATUS:
135
        data[0] = (1 << USB_DEVICE_SELF_POWERED) |
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff