Commit 9118e7f08f39001c92d595090b41305ef45c200a
1 parent
f07b6003
windows cdrom cache flush (Stefano Stabellini)
Windows only flushes its cache of a CDROM if it gets a SENSE_UNIT_ATTENTION CHECK_CONDITION response to a REQUEST_SENSE command. Make sure it does so after we change the CD. Tab damage fixed by Anthony Liguori Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com> Signed-off-by: Steven Smith <steven.smith@citrix.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5698 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
27 additions
and
1 deletions
hw/ide.c
| ... | ... | @@ -351,6 +351,7 @@ |
| 351 | 351 | #define ASC_ILLEGAL_OPCODE 0x20 |
| 352 | 352 | #define ASC_LOGICAL_BLOCK_OOR 0x21 |
| 353 | 353 | #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 |
| 354 | +#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 | |
| 354 | 355 | #define ASC_INCOMPATIBLE_FORMAT 0x30 |
| 355 | 356 | #define ASC_MEDIUM_NOT_PRESENT 0x3a |
| 356 | 357 | #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 |
| ... | ... | @@ -1106,6 +1107,17 @@ static void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc) |
| 1106 | 1107 | ide_set_irq(s); |
| 1107 | 1108 | } |
| 1108 | 1109 | |
| 1110 | +static void ide_atapi_cmd_check_status(IDEState *s) | |
| 1111 | +{ | |
| 1112 | +#ifdef DEBUG_IDE_ATAPI | |
| 1113 | + printf("atapi_cmd_check_status\n"); | |
| 1114 | +#endif | |
| 1115 | + s->error = MC_ERR | (SENSE_UNIT_ATTENTION << 4); | |
| 1116 | + s->status = ERR_STAT; | |
| 1117 | + s->nsector = 0; | |
| 1118 | + ide_set_irq(s); | |
| 1119 | +} | |
| 1120 | + | |
| 1109 | 1121 | static inline void cpu_to_ube16(uint8_t *buf, int val) |
| 1110 | 1122 | { |
| 1111 | 1123 | buf[0] = val >> 8; |
| ... | ... | @@ -1528,6 +1540,14 @@ static void ide_atapi_cmd(IDEState *s) |
| 1528 | 1540 | printf("\n"); |
| 1529 | 1541 | } |
| 1530 | 1542 | #endif |
| 1543 | + /* If there's a UNIT_ATTENTION condition pending, only | |
| 1544 | + REQUEST_SENSE and INQUIRY commands are allowed to complete. */ | |
| 1545 | + if (s->sense_key == SENSE_UNIT_ATTENTION && | |
| 1546 | + s->io_buffer[0] != GPCMD_REQUEST_SENSE && | |
| 1547 | + s->io_buffer[0] != GPCMD_INQUIRY) { | |
| 1548 | + ide_atapi_cmd_check_status(s); | |
| 1549 | + return; | |
| 1550 | + } | |
| 1531 | 1551 | switch(s->io_buffer[0]) { |
| 1532 | 1552 | case GPCMD_TEST_UNIT_READY: |
| 1533 | 1553 | if (bdrv_is_inserted(s->bs)) { |
| ... | ... | @@ -1623,6 +1643,8 @@ static void ide_atapi_cmd(IDEState *s) |
| 1623 | 1643 | buf[2] = s->sense_key; |
| 1624 | 1644 | buf[7] = 10; |
| 1625 | 1645 | buf[12] = s->asc; |
| 1646 | + if (s->sense_key == SENSE_UNIT_ATTENTION) | |
| 1647 | + s->sense_key = SENSE_NONE; | |
| 1626 | 1648 | ide_atapi_cmd_reply(s, 18, max_len); |
| 1627 | 1649 | break; |
| 1628 | 1650 | case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: |
| ... | ... | @@ -1974,9 +1996,13 @@ static void cdrom_change_cb(void *opaque) |
| 1974 | 1996 | IDEState *s = opaque; |
| 1975 | 1997 | uint64_t nb_sectors; |
| 1976 | 1998 | |
| 1977 | - /* XXX: send interrupt too */ | |
| 1978 | 1999 | bdrv_get_geometry(s->bs, &nb_sectors); |
| 1979 | 2000 | s->nb_sectors = nb_sectors; |
| 2001 | + | |
| 2002 | + s->sense_key = SENSE_UNIT_ATTENTION; | |
| 2003 | + s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED; | |
| 2004 | + | |
| 2005 | + ide_set_irq(s); | |
| 1980 | 2006 | } |
| 1981 | 2007 | |
| 1982 | 2008 | static void ide_cmd_lba48_transform(IDEState *s, int lba48) | ... | ... |