} __attribute__((packed));
+struct atapi_mech_status_cmd {
+ uint8_t atapi_cmd; // 0xbd
+ uint8_t rsvd1 : 5;
+ uint8_t lun : 3;
+ uint8_t rsvd2[6];
+ uint16_t alloc_len;
+ uint8_t rsvd3;
+ uint8_t link : 1;
+ uint8_t flag : 1;
+ uint8_t naca : 1;
+ uint8_t rsvd5 : 3;
+ uint8_t vendor_specific : 2;
+} __attribute__((packed));
+
+struct atapi_mech_status_resp {
+ uint8_t cur_slot : 5;
+ uint8_t changer_state : 2;
+ uint8_t fault : 1;
+ uint8_t rsvd1 : 4;
+ uint8_t door_open : 1;
+ uint8_t cd_dvd_mech_state : 3;
+ uint32_t lba;
+ uint8_t num_slots : 6;
+ uint8_t rsvd2 : 2;
+ uint16_t slot_table_len;
+} __attribute__((packed));
+
+
struct atapi_inquiry_cmd {
uint8_t atapi_cmd; // 0x12
uint8_t evpd : 1;
}
+
static int atapi_inquiry(struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
struct atapi_inquiry_cmd * inquiry_cmd = (struct atapi_inquiry_cmd *)(drive->data_buf);
}
+static int atapi_mech_status(struct ide_internal * ide, struct ide_channel * channel) {
+ struct ide_drive * drive = get_selected_drive(channel);
+ struct atapi_mech_status_cmd * status_cmd = (struct atapi_mech_status_cmd *)(drive->data_buf);
+ uint16_t alloc_len = be_to_le_16(status_cmd->alloc_len);
+ struct atapi_mech_status_resp * resp = (struct atapi_mech_status_resp *)(drive->data_buf);
+ int xfer_len = sizeof(struct atapi_mech_status_resp);
+
+ memset(resp, 0, sizeof(struct atapi_mech_status_resp));
+
+ resp->lba = le_to_be_32(1);
+ resp->slot_table_len = le_to_be_16(0);
+
+ if (alloc_len < xfer_len) {
+ xfer_len = alloc_len;
+ }
+
+ atapi_setup_cmd_resp(ide, channel, xfer_len);
+
+ return 0;
+}
+
+
static int atapi_cmd_is_data_op(uint8_t cmd) {
switch (cmd) {
case 0x28: // read (10)
}
break;
+ case 0xbd: // mechanism status
+ if (atapi_mech_status(ide, channel) == -1) {
+ PrintError("IDE: error in ATAPI Mechanism status query (%x)\n", cmd);
+ return -1;
+ }
+ break;
+
+
case 0xa8: // read(12)
case 0x1b: // start/stop drive
- case 0xbd: // mechanism status
case 0xbe: // read cd