Can now boot newer versions of Puppy.
static int atapi_update_req_len(struct ide_internal * ide, struct ide_channel * channel, uint_t xfer_len) {
struct ide_drive * drive = get_selected_drive(channel);
- // PrintDebug("Updating request length (pre=%d)\n", drive->req_len);
+ //PrintDebug("\tUpdating request length (pre=%d)\n", drive->req_len);
if (drive->req_len == 0) {
PrintError("ATAPI Error: request of length 0\n");
}
// if the device can't return as much as the OS requested
+ // this is actually a decrement of the req_len by the amount requested by the OS
if (drive->req_len > xfer_len) {
drive->req_len = xfer_len;
}
- // PrintDebug("Updating request length (post=%d)\n", drive->req_len);
+ // PrintDebug("\tUpdating request length (post=%d)\n", drive->req_len);
return 0;
}
err = (struct atapi_error_recovery *)(drive->data_buf +
sizeof(struct atapi_mode_sense_hdr));
+
memcpy(err, &(drive->cd_state.err_recovery), sizeof(struct atapi_error_recovery));
resp_len += sizeof(struct atapi_error_recovery);
+ PrintError("mode sense (error recovery) resp_len=%d\n", resp_len);
+
+
hdr->mode_data_len = le_to_be_16(resp_len - 2);
break;
}
case 0x2a: { // CDROM caps and mech. status
+
+ uint8_t * buf = drive->data_buf;
+
+
+
+ PrintError("mode sense (caps/mechs v2) resp_len=%d\n", resp_len);
+
+ *((uint16_t *)buf) = le_to_be_16(28 + 6);
+ buf[2] = 0x70;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = 0;
+ buf[7] = 0;
+
+ buf[8] = 0x2a;
+ buf[9] = 0x12;
+ buf[10] = 0x00;
+ buf[11] = 0x00;
+
+ /* Claim PLAY_AUDIO capability (0x01) since some Linux
+ code checks for this to automount media. */
+ buf[12] = 0x71;
+ buf[13] = 3 << 5;
+ buf[14] = (1 << 0) | (1 << 3) | (1 << 5);
+
+ buf[6] |= 1 << 1;
+ buf[15] = 0x00;
+ *((uint16_t *)&(buf[16])) = le_to_be_16(706);
+ buf[18] = 0;
+ buf[19] = 2;
+ *((uint16_t *)&(buf[20])) = le_to_be_16(512);
+ *((uint16_t *)&(buf[22])) = le_to_be_16(706);
+ buf[24] = 0;
+ buf[25] = 0;
+ buf[26] = 0;
+ buf[27] = 0;
+
+ resp_len = 28;
+
+#if 0
struct atapi_cdrom_caps * caps = NULL;
caps = (struct atapi_cdrom_caps *)(drive->data_buf + sizeof(struct atapi_mode_sense_hdr));
+
+
memset(caps, 0, sizeof(struct atapi_cdrom_caps));
resp_len += sizeof(struct atapi_cdrom_caps);
hdr->mode_data_len = le_to_be_16(resp_len - 2);
+
+ PrintError("mode sense (caps/mechs v2) resp_len=%d\n", resp_len);
+
caps->page_code = 0x2a;
caps->page_len = 0x12;
caps->mode2_form1 = 1;
caps->lun_buf_size = le_to_be_16(512);
caps->obsolete2 = le_to_be_16(0x2c2);
+#endif
+
break;
}
case 0x0d:
// We do this after error checking, because its only valid if everything worked
- memset(hdr, 0, sizeof(struct atapi_mode_sense_hdr));
- hdr->media_type_code = 0x70;
+ // memset(hdr, 0, sizeof(struct atapi_mode_sense_hdr));
+ // hdr->media_type_code = 0x70;
PrintDebug("resp_len=%d\n", resp_len);
*/
break;
case 0x03: // request sense
+ PrintError("IDE: Requesting Sense (0x3)\n");
atapi_req_sense(ide, channel);
break;
drive_id->dword_io = 1;
// enable DMA access
+ /* Disabled until command packet DMA is fixed */
drive_id->dma_enable = 1;
// enable LBA access
drive_id->rw_multiples = 0x80ff;
// words 64-70, 54-58 valid
- drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
+ /* Disabled until command packet DMA is fixed */
+ drive_id->field_valid = 0x0007; // DMA + pkg cmd valid
// copied from CFA540A
- drive_id->buf[63] = 0x0103; // variable (DMA stuff)
- //drive_id->buf[63] = 0x0000; // variable (DMA stuff)
-
- // drive_id->buf[64] = 0x0001; // PIO
+ /* Disabled until command packet DMA is fixed */
+ drive_id->buf[63] = 0x0103; // variable (DMA stuff)
+
+
+ /* uncommented to disable dma(?) */
+ // drive_id->buf[64] = 0x0001; // PIO
+
+
drive_id->buf[65] = 0x00b4;
drive_id->buf[66] = 0x00b4;
drive_id->buf[67] = 0x012c;
// drive_id->buf[80] = 0x1e; // supports up to ATA/ATAPI-4
drive_id->major_rev_num = 0x0040; // supports up to ATA/ATAPI-6
+ /* Disabled until command packet DMA is fixed */
drive_id->dma_ultra = 0x2020; // Ultra_DMA_Mode_5_Selected | Ultra_DMA_Mode_5_Supported;
}
}
PrintDebug("\tPRD Addr: %x, PRD Len: %d, EOT: %d\n",
- prd_entry.base_addr, prd_entry.size, prd_entry.end_of_table);
+ prd_entry.base_addr,
+ (prd_entry.size == 0) ? 0x10000 : prd_entry.size,
+ prd_entry.end_of_table);
if (prd_entry.end_of_table) {
break;
// loop through the PRD data....
- prd_bytes_left = prd_entry.size;
+ if (prd_entry.size == 0) {
+ // a size of 0 means 64k
+ prd_bytes_left = 0x10000;
+ } else {
+ prd_bytes_left = prd_entry.size;
+ }
while (prd_bytes_left > 0) {
return -1;
}
} else {
- PrintDebug("DMA of command packet\n");
- PrintError("How does this work???\n");
+ /*
+ PrintError("DMA of command packet\n");
+ PrintError("How does this work (ATAPI CMD=%x)???\n", drive->cd_state.atapi_cmd);
return -1;
+ */
+ int cmd_ret = 0;
+
bytes_to_write = (prd_bytes_left > bytes_left) ? bytes_left : prd_bytes_left;
prd_bytes_left = bytes_to_write;
+
+ cmd_ret = v3_write_gpa_memory(core, prd_entry.base_addr + prd_offset,
+ bytes_to_write, drive->data_buf);
+
+ // check cmd_ret
+
+
+ bytes_to_write = 0;
+ prd_bytes_left = 0;
+ drive->transfer_index += bytes_to_write;
+
+ channel->status.busy = 0;
+ channel->status.ready = 1;
+ channel->status.data_req = 0;
+ channel->status.error = 0;
+ channel->status.seek_complete = 1;
+
+ channel->dma_status.active = 0;
+ channel->dma_status.err = 0;
+
+ ide_raise_irq(ide, channel);
+
+ return 0;
}
}
static int read_cd_data(uint8_t * dst, uint_t length, struct ide_internal * ide, struct ide_channel * channel) {
struct ide_drive * drive = get_selected_drive(channel);
int data_offset = drive->transfer_index % ATAPI_BLOCK_SIZE;
- int req_offset = drive->transfer_index % drive->req_len;
+ // int req_offset = drive->transfer_index % drive->req_len;
if (drive->cd_state.atapi_cmd != 0x28) {
PrintDebug("IDE: Reading CD Data (len=%d) (req_len=%d)\n", length, drive->req_len);
+ PrintDebug("IDE: transfer len=%d, transfer idx=%d\n", drive->transfer_length, drive->transfer_index);
}
+
+
if (drive->transfer_index >= drive->transfer_length) {
PrintError("Buffer Overrun... (xfer_len=%d) (cur_idx=%d) (post_idx=%d)\n",
drive->transfer_length, drive->transfer_index,
// Should the req_offset be recalculated here?????
- if ((req_offset == 0) && (drive->transfer_index > 0)) {
+ if (/*(req_offset == 0) &&*/ (drive->transfer_index > 0)) {
if (drive->transfer_index < drive->transfer_length) {
// An increment is complete, but there is still more data to be transferred...
struct ide_channel * channel = get_selected_channel(ide, port);
struct ide_drive * drive = get_selected_drive(channel);
- PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
+ // PrintDebug("IDE: Reading Data Port %x (len=%d)\n", port, length);
if ((channel->cmd_reg == 0xec) ||
(channel->cmd_reg == 0xa1)) {
if (drive->drive_type == BLOCK_CDROM) {
if (read_cd_data((uint8_t *)dst, length, ide, channel) == -1) {
- PrintError("IDE: Could not read CD Data\n");
+ PrintError("IDE: Could not read CD Data (atapi cmd=%x)\n", drive->cd_state.atapi_cmd);
return -1;
}
} else if (drive->drive_type == BLOCK_DISK) {
disk->socket = v3_create_tcp_socket(disk->vm);
- PrintDebug("DISK socket: %d\n", disk->socket);
+ PrintDebug("DISK socket: %p\n", disk->socket);
PrintDebug("Connecting to: %s:%d\n", v3_inet_ntoa(disk->ip_addr), disk->port);
v3_connect_to_ip(disk->socket, v3_ntohl(disk->ip_addr), disk->port);