Revision e1a064f9 hw/ide/atapi.c
b/hw/ide/atapi.c | ||
---|---|---|
533 | 533 |
return 8; /* We wrote to 4 extra bytes from the header */ |
534 | 534 |
} |
535 | 535 |
|
536 |
static void handle_get_event_status_notification(IDEState *s, |
|
537 |
uint8_t *buf, |
|
538 |
const uint8_t *packet) |
|
536 |
static void cmd_get_event_status_notification(IDEState *s, |
|
537 |
uint8_t *buf) |
|
539 | 538 |
{ |
539 |
const uint8_t *packet = buf; |
|
540 |
|
|
540 | 541 |
struct { |
541 | 542 |
uint8_t opcode; |
542 | 543 |
uint8_t polled; /* lsb bit is polled; others are reserved */ |
... | ... | |
1064 | 1065 |
ide_atapi_cmd_ok(s); |
1065 | 1066 |
} |
1066 | 1067 |
|
1068 |
enum { |
|
1069 |
/* |
|
1070 |
* Only commands flagged as ALLOW_UA are allowed to run under a |
|
1071 |
* unit attention condition. (See MMC-5, section 4.1.6.1) |
|
1072 |
*/ |
|
1073 |
ALLOW_UA = 0x01, |
|
1074 |
}; |
|
1075 |
|
|
1076 |
static const struct { |
|
1077 |
void (*handler)(IDEState *s, uint8_t *buf); |
|
1078 |
int flags; |
|
1079 |
} atapi_cmd_table[0x100] = { |
|
1080 |
[ 0x00 ] = { cmd_test_unit_ready, 0 }, |
|
1081 |
[ 0x03 ] = { cmd_request_sense, ALLOW_UA }, |
|
1082 |
[ 0x12 ] = { cmd_inquiry, ALLOW_UA }, |
|
1083 |
[ 0x1a ] = { cmd_mode_sense, /* (6) */ 0 }, |
|
1084 |
[ 0x1b ] = { cmd_start_stop_unit, 0 }, |
|
1085 |
[ 0x1e ] = { cmd_prevent_allow_medium_removal, 0 }, |
|
1086 |
[ 0x25 ] = { cmd_read_cdvd_capacity, 0 }, |
|
1087 |
[ 0x28 ] = { cmd_read, /* (10) */ 0 }, |
|
1088 |
[ 0x2b ] = { cmd_seek, 0 }, |
|
1089 |
[ 0x43 ] = { cmd_read_toc_pma_atip, 0 }, |
|
1090 |
[ 0x46 ] = { cmd_get_configuration, ALLOW_UA }, |
|
1091 |
[ 0x4a ] = { cmd_get_event_status_notification, ALLOW_UA }, |
|
1092 |
[ 0x5a ] = { cmd_mode_sense, /* (10) */ 0 }, |
|
1093 |
[ 0xa8 ] = { cmd_read, /* (12) */ 0 }, |
|
1094 |
[ 0xad ] = { cmd_read_dvd_structure, 0 }, |
|
1095 |
[ 0xbb ] = { cmd_set_speed, 0 }, |
|
1096 |
[ 0xbd ] = { cmd_mechanism_status, 0 }, |
|
1097 |
[ 0xbe ] = { cmd_read_cd, 0 }, |
|
1098 |
}; |
|
1099 |
|
|
1067 | 1100 |
void ide_atapi_cmd(IDEState *s) |
1068 | 1101 |
{ |
1069 | 1102 |
const uint8_t *packet; |
... | ... | |
1082 | 1115 |
} |
1083 | 1116 |
#endif |
1084 | 1117 |
/* |
1085 |
* If there's a UNIT_ATTENTION condition pending, only |
|
1086 |
* REQUEST_SENSE, INQUIRY, GET_CONFIGURATION and |
|
1087 |
* GET_EVENT_STATUS_NOTIFICATION commands are allowed to complete. |
|
1088 |
* MMC-5, section 4.1.6.1 lists only these commands being allowed |
|
1089 |
* to complete, with other commands getting a CHECK condition |
|
1090 |
* response unless a higher priority status, defined by the drive |
|
1118 |
* If there's a UNIT_ATTENTION condition pending, only command flagged with |
|
1119 |
* ALLOW_UA are allowed to complete. with other commands getting a CHECK |
|
1120 |
* condition response unless a higher priority status, defined by the drive |
|
1091 | 1121 |
* here, is pending. |
1092 | 1122 |
*/ |
1093 | 1123 |
if (s->sense_key == SENSE_UNIT_ATTENTION && |
1094 |
s->io_buffer[0] != GPCMD_REQUEST_SENSE && |
|
1095 |
s->io_buffer[0] != GPCMD_INQUIRY && |
|
1096 |
s->io_buffer[0] != GPCMD_GET_EVENT_STATUS_NOTIFICATION) { |
|
1124 |
!(atapi_cmd_table[s->io_buffer[0]].flags & ALLOW_UA)) { |
|
1097 | 1125 |
ide_atapi_cmd_check_status(s); |
1098 | 1126 |
return; |
1099 | 1127 |
} |
1128 |
|
|
1100 | 1129 |
if (bdrv_is_inserted(s->bs) && s->cdrom_changed) { |
1101 | 1130 |
ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT); |
1102 | 1131 |
|
... | ... | |
1105 | 1134 |
s->asc = ASC_MEDIUM_MAY_HAVE_CHANGED; |
1106 | 1135 |
return; |
1107 | 1136 |
} |
1108 |
switch(s->io_buffer[0]) { |
|
1109 |
case GPCMD_TEST_UNIT_READY: |
|
1110 |
cmd_test_unit_ready(s, buf); |
|
1111 |
break; |
|
1112 |
case GPCMD_MODE_SENSE_6: |
|
1113 |
case GPCMD_MODE_SENSE_10: |
|
1114 |
cmd_mode_sense(s, buf); |
|
1115 |
break; |
|
1116 |
case GPCMD_REQUEST_SENSE: |
|
1117 |
cmd_request_sense(s, buf); |
|
1118 |
break; |
|
1119 |
case GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL: |
|
1120 |
cmd_prevent_allow_medium_removal(s, buf); |
|
1121 |
break; |
|
1122 |
case GPCMD_READ_10: |
|
1123 |
case GPCMD_READ_12: |
|
1124 |
cmd_read(s, buf); |
|
1125 |
break; |
|
1126 |
case GPCMD_READ_CD: |
|
1127 |
cmd_read_cd(s, buf); |
|
1128 |
break; |
|
1129 |
case GPCMD_SEEK: |
|
1130 |
cmd_seek(s, buf); |
|
1131 |
break; |
|
1132 |
case GPCMD_START_STOP_UNIT: |
|
1133 |
cmd_start_stop_unit(s, buf); |
|
1134 |
break; |
|
1135 |
case GPCMD_MECHANISM_STATUS: |
|
1136 |
cmd_mechanism_status(s, buf); |
|
1137 |
break; |
|
1138 |
case GPCMD_READ_TOC_PMA_ATIP: |
|
1139 |
cmd_read_toc_pma_atip(s, buf); |
|
1140 |
break; |
|
1141 |
case GPCMD_READ_CDVD_CAPACITY: |
|
1142 |
cmd_read_cdvd_capacity(s, buf); |
|
1143 |
break; |
|
1144 |
case GPCMD_READ_DVD_STRUCTURE: |
|
1145 |
cmd_read_dvd_structure(s, buf); |
|
1146 |
break; |
|
1147 |
case GPCMD_SET_SPEED: |
|
1148 |
cmd_set_speed(s, buf); |
|
1149 |
break; |
|
1150 |
case GPCMD_INQUIRY: |
|
1151 |
cmd_inquiry(s, buf); |
|
1152 |
break; |
|
1153 |
case GPCMD_GET_CONFIGURATION: |
|
1154 |
cmd_get_configuration(s, buf); |
|
1155 |
break; |
|
1156 |
case GPCMD_GET_EVENT_STATUS_NOTIFICATION: |
|
1157 |
handle_get_event_status_notification(s, buf, packet); |
|
1158 |
break; |
|
1159 |
default: |
|
1160 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, |
|
1161 |
ASC_ILLEGAL_OPCODE); |
|
1162 |
break; |
|
1137 |
|
|
1138 |
/* Execute the command */ |
|
1139 |
if (atapi_cmd_table[s->io_buffer[0]].handler) { |
|
1140 |
atapi_cmd_table[s->io_buffer[0]].handler(s, buf); |
|
1141 |
return; |
|
1163 | 1142 |
} |
1143 |
|
|
1144 |
ide_atapi_cmd_error(s, SENSE_ILLEGAL_REQUEST, ASC_ILLEGAL_OPCODE); |
|
1164 | 1145 |
} |
Also available in: Unified diff