Revision 17acfe32 hw/scsi-disk.c
b/hw/scsi-disk.c | ||
---|---|---|
213 | 213 |
cmdlen = 12; |
214 | 214 |
break; |
215 | 215 |
default: |
216 |
BADF("Unsupported command length\n");
|
|
216 |
BADF("Unsupported command length, command %x\n", s->command);
|
|
217 | 217 |
goto fail; |
218 | 218 |
} |
219 | 219 |
#ifdef DEBUG_SCSI |
... | ... | |
260 | 260 |
} |
261 | 261 |
memcpy(&s->buf[8], "QEMU ", 8); |
262 | 262 |
memcpy(&s->buf[32], QEMU_VERSION, 4); |
263 |
s->buf[2] = 3; /* SCSI-3 */ |
|
263 |
/* Identify device as SCSI-3 rev 1. |
|
264 |
Some later commands are also implemented. */ |
|
265 |
s->buf[2] = 3; |
|
264 | 266 |
s->buf[3] = 2; /* Format 2 */ |
265 | 267 |
s->buf[4] = 32; |
266 | 268 |
s->buf_len = 36; |
... | ... | |
277 | 279 |
break; |
278 | 280 |
case 0x1a: |
279 | 281 |
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). */ |
|
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 | 290 |
s->buf[1] = 0; /* Default media type. */ |
291 |
s->buf[2] = 0; /* Write enabled. */ |
|
292 | 291 |
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; |
|
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; |
|
299 | 337 |
} |
300 |
s->buf_len = len; |
|
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); |
|
301 | 345 |
break; |
302 | 346 |
case 0x25: |
303 | 347 |
DPRINTF("Read Capacity\n"); |
... | ... | |
368 | 412 |
DPRINTF("Read TOC error\n"); |
369 | 413 |
goto fail; |
370 | 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; |
|
371 | 423 |
case 0x56: |
372 | 424 |
DPRINTF("Reserve(10)\n"); |
373 | 425 |
if (buf[1] & 3) |
Also available in: Unified diff