Revision 7c22dd52
b/hw/scsi-disk.c | ||
---|---|---|
31 | 31 |
int command; |
32 | 32 |
uint32_t tag; |
33 | 33 |
BlockDriverState *bdrv; |
34 |
int sector_size; |
|
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; |
|
35 | 37 |
/* When transfering data buf_pos and buf_len contain a partially |
36 | 38 |
transferred block of data (or response to a command), and |
37 |
sector/sector_count identify any remaining sectors. */ |
|
39 |
sector/sector_count identify any remaining sectors. |
|
40 |
Both sector and sector_count are in terms of qemu 512 byte blocks. */ |
|
38 | 41 |
/* ??? We should probably keep track of whether the data trasfer is |
39 | 42 |
a read or a write. Currently we rely on the host getting it right. */ |
40 | 43 |
int sector; |
... | ... | |
42 | 45 |
int buf_pos; |
43 | 46 |
int buf_len; |
44 | 47 |
int sense; |
45 |
char buf[2048];
|
|
48 |
char buf[512];
|
|
46 | 49 |
scsi_completionfn completion; |
47 | 50 |
void *opaque; |
48 | 51 |
}; |
... | ... | |
75 | 78 |
s->buf_pos = 0; |
76 | 79 |
} |
77 | 80 |
|
78 |
n = len / s->sector_size;
|
|
81 |
n = len / 512;
|
|
79 | 82 |
if (n > s->sector_count) |
80 | 83 |
n = s->sector_count; |
81 | 84 |
|
82 | 85 |
if (n != 0) { |
83 | 86 |
bdrv_read(s->bdrv, s->sector, data, n); |
84 |
data += n * s->sector_size;
|
|
85 |
len -= n * s->sector_size;
|
|
87 |
data += n * 512;
|
|
88 |
len -= n * 512;
|
|
86 | 89 |
s->sector += n; |
87 | 90 |
s->sector_count -= n; |
88 | 91 |
} |
89 | 92 |
|
90 | 93 |
if (len && s->sector_count) { |
91 |
bdrv_read(s->bdrv, s->sector, s->buf, 1);
|
|
94 |
bdrv_read(s->bdrv, s->sector, s->buf, 512);
|
|
92 | 95 |
s->sector++; |
93 | 96 |
s->sector_count--; |
94 | 97 |
s->buf_pos = 0; |
95 |
s->buf_len = s->sector_size;
|
|
98 |
s->buf_len = 512;
|
|
96 | 99 |
/* Recurse to complete the partial read. */ |
97 | 100 |
return scsi_read_data(s, data, len); |
98 | 101 |
} |
... | ... | |
120 | 123 |
if (s->sector_count == 0) |
121 | 124 |
return 1; |
122 | 125 |
|
123 |
if (s->buf_len != 0 || len < s->sector_size) {
|
|
124 |
n = s->sector_size - s->buf_len;
|
|
126 |
if (s->buf_len != 0 || len < 512) {
|
|
127 |
n = 512 - s->buf_len;
|
|
125 | 128 |
if (n > len) |
126 | 129 |
n = len; |
127 | 130 |
|
... | ... | |
129 | 132 |
data += n; |
130 | 133 |
s->buf_len += n; |
131 | 134 |
len -= n; |
132 |
if (s->buf_len == s->sector_size) {
|
|
135 |
if (s->buf_len == 512) {
|
|
133 | 136 |
/* A full sector has been accumulated. Write it to disk. */ |
134 | 137 |
bdrv_write(s->bdrv, s->sector, s->buf, 1); |
135 | 138 |
s->buf_len = 0; |
... | ... | |
138 | 141 |
} |
139 | 142 |
} |
140 | 143 |
|
141 |
n = len / s->sector_size;
|
|
144 |
n = len / 512;
|
|
142 | 145 |
if (n > s->sector_count) |
143 | 146 |
n = s->sector_count; |
144 | 147 |
|
145 | 148 |
if (n != 0) { |
146 | 149 |
bdrv_write(s->bdrv, s->sector, data, n); |
147 |
data += n * s->sector_size;
|
|
148 |
len -= n * s->sector_size;
|
|
150 |
data += n * 512;
|
|
151 |
len -= n * 512;
|
|
149 | 152 |
s->sector += n; |
150 | 153 |
s->sector_count -= n; |
151 | 154 |
} |
152 | 155 |
|
153 |
if (len >= s->sector_size)
|
|
156 |
if (len >= 512)
|
|
154 | 157 |
return 1; |
155 | 158 |
|
156 | 159 |
if (len && s->sector_count) { |
... | ... | |
296 | 299 |
s->buf[3] = nb_sectors & 0xff; |
297 | 300 |
s->buf[4] = 0; |
298 | 301 |
s->buf[5] = 0; |
299 |
s->buf[6] = s->sector_size >> 8;
|
|
300 |
s->buf[7] = s->sector_size & 0xff;
|
|
302 |
s->buf[6] = s->cluster_size * 2;
|
|
303 |
s->buf[7] = 0;
|
|
301 | 304 |
s->buf_len = 8; |
302 | 305 |
break; |
303 | 306 |
case 0x08: |
304 | 307 |
case 0x28: |
305 | 308 |
DPRINTF("Read (sector %d, count %d)\n", lba, len); |
306 |
s->sector = lba; |
|
307 |
s->sector_count = len; |
|
309 |
s->sector = lba * s->cluster_size;
|
|
310 |
s->sector_count = len * s->cluster_size;
|
|
308 | 311 |
break; |
309 | 312 |
case 0x0a: |
310 | 313 |
case 0x2a: |
311 | 314 |
DPRINTF("Write (sector %d, count %d)\n", lba, len); |
312 |
s->sector = lba; |
|
313 |
s->sector_count = len; |
|
315 |
s->sector = lba * s->cluster_size;
|
|
316 |
s->sector_count = len * s->cluster_size;
|
|
314 | 317 |
is_write = 1; |
315 | 318 |
break; |
316 | 319 |
case 0x43: |
317 | 320 |
{ |
318 |
int start_track, format, msf; |
|
321 |
int start_track, format, msf, toclen;
|
|
319 | 322 |
|
320 | 323 |
msf = buf[1] & 2; |
321 | 324 |
format = buf[2] & 0xf; |
... | ... | |
324 | 327 |
DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); |
325 | 328 |
switch(format) { |
326 | 329 |
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; |
|
330 |
toclen = cdrom_read_toc(nb_sectors, s->buf, msf, start_track); |
|
331 | 331 |
break; |
332 | 332 |
case 1: |
333 | 333 |
/* multi session : only a single session defined */ |
334 |
toclen = 12; |
|
334 | 335 |
memset(s->buf, 0, 12); |
335 | 336 |
s->buf[1] = 0x0a; |
336 | 337 |
s->buf[2] = 0x01; |
337 | 338 |
s->buf[3] = 0x01; |
338 |
s->buf_len = 12; |
|
339 | 339 |
break; |
340 | 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; |
|
341 |
toclen = cdrom_read_toc_raw(nb_sectors, s->buf, msf, start_track); |
|
345 | 342 |
break; |
346 | 343 |
default: |
347 |
error_cmd: |
|
348 |
DPRINTF("Read TOC error\n"); |
|
349 |
goto fail; |
|
344 |
goto error_cmd; |
|
345 |
} |
|
346 |
if (toclen > 0) { |
|
347 |
if (len > toclen) |
|
348 |
len = toclen; |
|
349 |
s->buf_len = len; |
|
350 |
break; |
|
350 | 351 |
} |
351 |
break; |
|
352 |
error_cmd: |
|
353 |
DPRINTF("Read TOC error\n"); |
|
354 |
goto fail; |
|
352 | 355 |
} |
353 | 356 |
case 0x56: |
354 | 357 |
DPRINTF("Reserve(10)\n"); |
... | ... | |
377 | 380 |
if (s->sector_count == 0 && s->buf_len == 0) { |
378 | 381 |
scsi_command_complete(s, SENSE_NO_SENSE); |
379 | 382 |
} |
380 |
len = s->sector_count * s->sector_size + s->buf_len;
|
|
383 |
len = s->sector_count * 512 + s->buf_len;
|
|
381 | 384 |
return is_write ? -len : len; |
382 | 385 |
} |
383 | 386 |
|
... | ... | |
398 | 401 |
s->completion = completion; |
399 | 402 |
s->opaque = opaque; |
400 | 403 |
if (bdrv_get_type_hint(s->bdrv) == BDRV_TYPE_CDROM) { |
401 |
s->sector_size = 2048;
|
|
404 |
s->cluster_size = 4;
|
|
402 | 405 |
} else { |
403 |
s->sector_size = 512;
|
|
406 |
s->cluster_size = 1;
|
|
404 | 407 |
} |
405 | 408 |
|
406 | 409 |
return s; |
Also available in: Unified diff