freemyipod r966 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r965‎ | r966 | r967 >
Date:23:57, 20 July 2014
Author:theseven
Status:new
Tags:
Comment:
emCORE: iPod Classic: Add userspace ATA access interface
Modified paths:
  • /emcore/trunk/export/syscallapi.h (modified) (history)
  • /emcore/trunk/target/ipodclassic/config.h (modified) (history)
  • /emcore/trunk/target/ipodclassic/storage_ata-target.h (modified) (history)
  • /emcore/trunk/target/ipodclassic/storage_ata.c (modified) (history)

Diff [purge]

Index: emcore/trunk/target/ipodclassic/storage_ata.c
@@ -92,6 +92,10 @@
9393 .bbt_reload = ata_bbt_reload,
9494 .bbt_disable = ata_bbt_disable,
9595 #endif
 96+ .soft_reset = ata_soft_reset,
 97+ .hard_reset = ata_hard_reset,
 98+ .read_taskfile = ata_read_taskfile,
 99+ .raw_cmd = ata_raw_cmd,
96100 };
97101
98102
@@ -465,7 +469,7 @@
466470 return 0;
467471 }
468472
469 -int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long timeout)
 473+int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, uint32_t blksize, long timeout)
470474 {
471475 mmc_discard_irq();
472476 uint32_t responsetype;
@@ -485,7 +489,7 @@
486490 direction = MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_DIRECTION_READ;
487491 invalidate_dcache();
488492 }
489 - SDCI_DMASIZE = 0x200;
 493+ SDCI_DMASIZE = blksize;
490494 SDCI_DMAADDR = buf;
491495 SDCI_DMACOUNT = count;
492496 SDCI_DCTRL = SDCI_DCTRL_TXFIFORST | SDCI_DCTRL_RXFIFORST;
@@ -519,15 +523,16 @@
520524 ceata_taskfile[0xf] = 0xec;
521525 PASS_RC(ceata_wait_idle(), 2, 0);
522526 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
523 - PASS_RC(ceata_rw_multiple_block(false, buf, 1, CEATA_COMMAND_TIMEOUT), 2, 2);
 527+ PASS_RC(ceata_rw_multiple_block(false, buf, 1, 256, CEATA_COMMAND_TIMEOUT), 2, 2);
524528 }
525529 else
526530 {
527 - PASS_RC(ata_wait_for_not_bsy(10000000), 1, 0);
 531+ PASS_RC(ata_wait_for_not_bsy(10000000), 2, 0);
528532 ata_write_cbr(&ATA_PIO_DVR, 0);
529533 ata_write_cbr(&ATA_PIO_CSD, 0xec);
530 - PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
 534+ PASS_RC(ata_wait_for_start_of_transfer(10000000), 2, 1);
531535 for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR);
 536+ PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 2);
532537 }
533538 return 0;
534539 }
@@ -741,7 +746,7 @@
742747 ceata_taskfile[0xf] = write ? 0x35 : 0x25;
743748 PASS_RC(ceata_wait_idle(), 2, 0);
744749 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
745 - PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT), 2, 2);
 750+ PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, 512, CEATA_COMMAND_TIMEOUT), 2, 2);
746751 }
747752 else
748753 {
@@ -1013,6 +1018,184 @@
10141019 return rc;
10151020 }
10161021
 1022+int ata_read_taskfile(struct ata_raw_cmd_t* cmd)
 1023+{
 1024+ mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
 1025+ if (!ata_powered) PASS_RC(ata_power_up(), 1, 0);
 1026+ ata_set_active();
 1027+ cmd->result_valid = false;
 1028+ if (ceata)
 1029+ {
 1030+ PASS_RC_MTX(ceata_read_multiple_register(0, ceata_taskfile, 16), 1, 1, &ata_mutex);
 1031+ cmd->feature = ceata_taskfile[0x9];
 1032+ cmd->count = ceata_taskfile[0xa];
 1033+ cmd->lba_low = ceata_taskfile[0xb];
 1034+ cmd->lba_mid = ceata_taskfile[0xc];
 1035+ cmd->lba_high = ceata_taskfile[0xd];
 1036+ cmd->device = ceata_taskfile[0xe];
 1037+ cmd->command = ceata_taskfile[0xf];
 1038+ if (cmd->lba48)
 1039+ {
 1040+ cmd->feature |= ceata_taskfile[0x1] << 8;
 1041+ cmd->count |= ceata_taskfile[0x2] << 8;
 1042+ cmd->lba_low |= ceata_taskfile[0x3] << 8;
 1043+ cmd->lba_mid |= ceata_taskfile[0x4] << 8;
 1044+ cmd->lba_high |= ceata_taskfile[0x5] << 8;
 1045+ }
 1046+ }
 1047+ else
 1048+ {
 1049+ cmd->feature = ata_read_cbr(&ATA_PIO_FED);
 1050+ cmd->count = ata_read_cbr(&ATA_PIO_SCR);
 1051+ cmd->lba_low = ata_read_cbr(&ATA_PIO_LLR);
 1052+ cmd->lba_mid = ata_read_cbr(&ATA_PIO_LMR);
 1053+ cmd->lba_high = ata_read_cbr(&ATA_PIO_LHR);
 1054+ cmd->device = ata_read_cbr(&ATA_PIO_DVR);
 1055+ cmd->command = ata_read_cbr(&ATA_PIO_CSD);
 1056+ if (cmd->lba48)
 1057+ {
 1058+ ata_write_cbr(&ATA_PIO_DAD, BIT(7));
 1059+ cmd->feature |= ata_read_cbr(&ATA_PIO_FED) << 8;
 1060+ cmd->count |= ata_read_cbr(&ATA_PIO_SCR) << 8;
 1061+ cmd->lba_low |= ata_read_cbr(&ATA_PIO_LLR) << 8;
 1062+ cmd->lba_mid |= ata_read_cbr(&ATA_PIO_LMR) << 8;
 1063+ cmd->lba_high |= ata_read_cbr(&ATA_PIO_LHR) << 8;
 1064+ ata_write_cbr(&ATA_PIO_DAD, 0);
 1065+ }
 1066+ }
 1067+ cmd->result_valid = true;
 1068+ ata_set_active();
 1069+ mutex_unlock(&ata_mutex);
 1070+ return 0;
 1071+}
 1072+
 1073+int ata_raw_cmd(struct ata_raw_cmd_t* cmd)
 1074+{
 1075+ mutex_lock(&ata_mutex, TIMEOUT_BLOCK);
 1076+ if (!ata_powered) PASS_RC(ata_power_up(), 3, 0);
 1077+ ata_set_active();
 1078+ int rc = 0, rc2 = 0;
 1079+ cmd->result_valid = false;
 1080+ if (ceata)
 1081+ {
 1082+ memset(ceata_taskfile, 0, 16);
 1083+ if (cmd->lba48)
 1084+ {
 1085+ ceata_taskfile[0x1] = cmd->feature >> 8;
 1086+ ceata_taskfile[0x2] = cmd->count >> 8;
 1087+ ceata_taskfile[0x3] = cmd->lba_low >> 8;
 1088+ ceata_taskfile[0x4] = cmd->lba_mid >> 8;
 1089+ ceata_taskfile[0x5] = cmd->lba_high >> 8;
 1090+ }
 1091+ ceata_taskfile[0x9] = cmd->feature & 0xff;
 1092+ ceata_taskfile[0xa] = cmd->count & 0xff;
 1093+ ceata_taskfile[0xb] = cmd->lba_low & 0xff;
 1094+ ceata_taskfile[0xc] = cmd->lba_mid & 0xff;
 1095+ ceata_taskfile[0xd] = cmd->lba_high & 0xff;
 1096+ ceata_taskfile[0xe] = cmd->device;
 1097+ ceata_taskfile[0xf] = cmd->command;
 1098+ PASS_RC_MTX(ceata_wait_idle(), 3, 1, &ata_mutex);
 1099+ PASS_RC_MTX(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2, &ata_mutex);
 1100+ if (cmd->transfer)
 1101+ rc = ceata_rw_multiple_block(cmd->send, cmd->buffer, cmd->size, cmd->blksize, CEATA_COMMAND_TIMEOUT);
 1102+ else rc = ceata_wait_idle();
 1103+ if (IS_ERR(rc)) rc = ERR_RC((rc << 3) | 3);
 1104+ rc2 = ata_read_taskfile(cmd);
 1105+ if (IS_ERR(rc2) && !IS_ERR(rc)) rc = ERR_RC((rc2 << 3) | 4);
 1106+ }
 1107+ else
 1108+ {
 1109+ PASS_RC_MTX(ata_wait_for_rdy(100000), 3, 1, &ata_mutex);
 1110+ ata_write_cbr(&ATA_PIO_DVR, 0);
 1111+ if (cmd->lba48)
 1112+ {
 1113+ ata_write_cbr(&ATA_PIO_FED, cmd->feature >> 8);
 1114+ ata_write_cbr(&ATA_PIO_SCR, cmd->count >> 8);
 1115+ ata_write_cbr(&ATA_PIO_LLR, cmd->lba_low >> 8);
 1116+ ata_write_cbr(&ATA_PIO_LMR, cmd->lba_mid >> 8);
 1117+ ata_write_cbr(&ATA_PIO_LHR, cmd->lba_high >> 8);
 1118+ }
 1119+ ata_write_cbr(&ATA_PIO_FED, cmd->feature & 0xff);
 1120+ ata_write_cbr(&ATA_PIO_SCR, cmd->count & 0xff);
 1121+ ata_write_cbr(&ATA_PIO_LLR, cmd->lba_low & 0xff);
 1122+ ata_write_cbr(&ATA_PIO_LMR, cmd->lba_mid & 0xff);
 1123+ ata_write_cbr(&ATA_PIO_LHR, cmd->lba_high & 0xff);
 1124+ ata_write_cbr(&ATA_PIO_DVR, cmd->device);
 1125+ ata_write_cbr(&ATA_PIO_CSD, cmd->command);
 1126+ sleep(cmd->delay);
 1127+ if (cmd->transfer)
 1128+ {
 1129+ if (cmd->dma)
 1130+ {
 1131+ rc = ata_wait_for_start_of_transfer(500000);
 1132+ if (IS_ERR(rc)) rc = ERR_RC((rc << 3) | 2);
 1133+ else
 1134+ {
 1135+ if (cmd->send)
 1136+ {
 1137+ clean_dcache();
 1138+ ATA_SBUF_START = cmd->buffer;
 1139+ ATA_SBUF_SIZE = cmd->size * cmd->blksize;
 1140+ ATA_CFG |= BIT(4);
 1141+ }
 1142+ else
 1143+ {
 1144+ invalidate_dcache();
 1145+ ATA_TBUF_START = cmd->buffer;
 1146+ ATA_TBUF_SIZE = cmd->size * cmd->blksize;
 1147+ ATA_CFG &= ~BIT(4);
 1148+ }
 1149+ ATA_XFR_NUM = cmd->blksize * cmd->size - 1;
 1150+ ATA_CFG |= ata_dma_flags;
 1151+ ATA_CFG &= ~(BIT(7) | BIT(8));
 1152+ wakeup_wait(&ata_wakeup, TIMEOUT_NONE);
 1153+ ATA_IRQ = BITRANGE(0, 4);
 1154+ ATA_IRQ_MASK = BIT(0);
 1155+ ATA_COMMAND = BIT(0);
 1156+ if (wakeup_wait(&ata_wakeup, 500000) == THREAD_TIMEOUT) rc = ERR_RC(3);
 1157+ ATA_COMMAND = BIT(1);
 1158+ ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
 1159+ }
 1160+ }
 1161+ else
 1162+ {
 1163+ ATA_CFG &= ~ata_dma_flags;
 1164+ while (cmd->size--)
 1165+ {
 1166+ rc = ata_wait_for_start_of_transfer(500000);
 1167+ if (IS_ERR(rc))
 1168+ {
 1169+ rc = ERR_RC((rc << 3) | 4);
 1170+ break;
 1171+ }
 1172+ int i;
 1173+ if (cmd->send)
 1174+ for (i = 0; i < (cmd->blksize >> 1); i++)
 1175+ ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)cmd->buffer)[i]);
 1176+ else
 1177+ for (i = 0; i < (cmd->blksize >> 1); i++)
 1178+ ((uint16_t*)cmd->buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
 1179+ cmd->buffer += cmd->blksize;
 1180+ }
 1181+ }
 1182+ if (!IS_ERR(rc))
 1183+ {
 1184+ rc = ata_wait_for_end_of_transfer(100000);
 1185+ if (IS_ERR(rc)) rc = ERR_RC((rc << 3) | 5);
 1186+ }
 1187+ }
 1188+ else
 1189+ {
 1190+ rc = ata_wait_for_rdy(500000);
 1191+ if (IS_ERR(rc)) rc = ERR_RC((rc << 3) | 6);
 1192+ }
 1193+ ata_read_taskfile(cmd); // Cannot fail for PATA
 1194+ }
 1195+ ata_set_active();
 1196+ mutex_unlock(&ata_mutex);
 1197+ return rc;
 1198+}
 1199+
10171200 int ata_read_sectors(IF_MD2(int drive,) unsigned long start, int incount,
10181201 void* inbuf)
10191202 {
Index: emcore/trunk/target/ipodclassic/config.h
@@ -38,6 +38,7 @@
3939
4040
4141 #define ATA_HAVE_BBT
 42+#define TEST_FAT
4243
4344
4445 #endif
Index: emcore/trunk/target/ipodclassic/storage_ata-target.h
@@ -27,6 +27,27 @@
2828 #include "../global.h"
2929
3030
 31+struct __attribute__((packed)) ata_raw_cmd_t
 32+{
 33+ uint8_t lba48;
 34+ uint8_t transfer;
 35+ uint8_t send;
 36+ uint8_t dma;
 37+ uint32_t delay;
 38+ void* buffer;
 39+ uint32_t size;
 40+ uint32_t blksize;
 41+ uint16_t feature;
 42+ uint16_t count;
 43+ uint16_t lba_low;
 44+ uint16_t lba_mid;
 45+ uint16_t lba_high;
 46+ uint8_t device;
 47+ uint8_t command;
 48+ uint8_t result_valid;
 49+ uint8_t reserved[3];
 50+};
 51+
3152 struct ata_target_driverinfo
3253 {
3354 void (*srst_after_error)(bool enable);
@@ -34,6 +55,10 @@
3556 int (*bbt_translate)(uint64_t sector, uint32_t count, uint64_t* phys, uint32_t* physcount);
3657 int (*bbt_reload)();
3758 void (*bbt_disable)();
 59+ int (*soft_reset)();
 60+ int (*hard_reset)();
 61+ int (*read_taskfile)(struct ata_raw_cmd_t* cmd);
 62+ int (*raw_cmd)(struct ata_raw_cmd_t* cmd);
3863 };
3964
4065
@@ -41,8 +66,12 @@
4267 extern uint64_t ata_total_sectors;
4368 extern struct mutex ata_mutex;
4469
45 -void ata_set_retries(int retries);
46 -void ata_srst_after_error(bool enable);
 70+extern void ata_set_retries(int retries);
 71+extern void ata_srst_after_error(bool enable);
 72+extern int ata_soft_reset();
 73+extern int ata_hard_reset();
 74+extern int ata_read_taskfile(struct ata_raw_cmd_t* cmd);
 75+extern int ata_raw_cmd(struct ata_raw_cmd_t* cmd);
4776
4877 #ifdef ATA_HAVE_BBT
4978 extern uint16_t (*ata_bbt)[0x20];
Index: emcore/trunk/export/syscallapi.h
@@ -74,7 +74,7 @@
7575 #endif
7676
7777 /* increase this every time the api struct changes */
78 -#define EMCORE_API_VERSION 8
 78+#define EMCORE_API_VERSION 9
7979
8080 /* update this to latest version if a change to the api struct breaks
8181 backwards compatibility (and please take the opportunity to sort in any