Commit 17acfe326ce2038033934485145ddd2390337986

Authored by pbrook
1 parent 9f149aa9

More SCSI commands (Blue Swirl).


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1948 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 72 additions and 20 deletions
hw/scsi-disk.c
... ... @@ -213,7 +213,7 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
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,7 +260,9 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
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,27 +279,69 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
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,6 +412,14 @@ int32_t scsi_send_command(SCSIDevice *s, uint32_t tag, uint8_t *buf, int lun)
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)
... ...