diff options
Diffstat (limited to 'ider.c')
-rw-r--r-- | ider.c | 31 |
1 files changed, 24 insertions, 7 deletions
@@ -21,12 +21,14 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <stdbool.h> #include <sys/types.h> #include <scsi/scsi.h> #include "redir.h" static int ider_data_to_host(struct redir *r, unsigned int seqno, - unsigned char *data, unsigned int data_len) + unsigned char *data, unsigned int data_len, + bool completed) { unsigned char device = 0xb0; unsigned char *request; @@ -35,6 +37,7 @@ static int ider_data_to_host(struct redir *r, unsigned int seqno, IDER_INTERRUPT_MASK; struct ider_data_to_host_message msg = { .type = IDER_DATA_TO_HOST, + .attributes = completed ? 2 : 0, .input.mask = mask | IDER_BYTE_CNT_LSB_MASK | IDER_BYTE_CNT_MSB_MASK, .input.sector_count = IDER_INTERRUPT_IO, .input.byte_count_lsb = (data_len & 0xff), @@ -66,6 +69,7 @@ static int ider_packet_sense(struct redir *r, unsigned int seqno, IDER_DRIVE_SELECT_MASK | IDER_STATUS_MASK; struct ider_command_response_message msg = { .type = IDER_COMMAND_END_RESPONSE, + .attributes = 2, .output.mask = mask, .output.sector_count = IDER_INTERRUPT_IO | IDER_INTERRUPT_CD, .output.drive_select = device, @@ -88,8 +92,9 @@ int ider_handle_command(struct redir *r, unsigned int seqno, { unsigned char device = 0xb0; unsigned char resp[512]; + uint32_t lba, sector_size; - if (!r->filename) + if (!r->mmap_size) /* NOT READY, MEDIUM NOT PRESENT */ return ider_packet_sense(r, seqno, device, 0x02, 0x3a, 0x0); @@ -99,11 +104,23 @@ int ider_handle_command(struct redir *r, unsigned int seqno, case MODE_SENSE: if (cdb[2] != 0x3f || cdb[3] != 0x00) return ider_packet_sense(r, seqno, device, 0x05, 0x24, 0x00); - resp[0] = 0; - resp[1] = 0x05; - resp[2] = 0x80; - resp[3] = 0; - return ider_data_to_host(r, seqno, resp, 4); + resp[0] = 0; /* Mode data length */ + resp[1] = 0x05; /* Medium type: CD-ROM data only */ + resp[2] = 0x80; /* device-specific parameters: Write Protect */ + resp[3] = 0; /* Block-descriptor length */ + return ider_data_to_host(r, seqno, resp, 4, true); + case READ_CAPACITY: + lba = (r->mmap_size >> 11) - 1; + sector_size = (unsigned int)1 << 11; + resp[0] = (lba >> 24) & 0xff; + resp[1] = (lba >> 16) & 0xff; + resp[2] = (lba >> 8) & 0xff; + resp[3] = lba & 0xff; + resp[4] = (sector_size >> 24) & 0xff; + resp[5] = (sector_size >> 16) & 0xff; + resp[6] = (sector_size >> 8) & 0xff; + resp[7] = sector_size & 0xff; + return ider_data_to_host(r, seqno, resp, 8, true); default: break; } |