53#define M_PRINTF(format, args...) \
54 printf(MODNAME ": " format, ##args)
56#define BANNER "ATA device driver %s - Copyright (c) 2003 Marcus R. Brown\n"
59#define ATA_XFER_MODE_PIO 0x08
61#define ATA_XFER_MODE_MDMA 0x20
63#define ATA_XFER_MODE_UDMA 0x40
65#define ATA_EV_TIMEOUT 1
66#define ATA_EV_COMPLETE 2
68static int ata_devinfo_init = 0;
69static int ata_evflg = -1;
72static u8 ata_dvrp_workaround = 0;
74#ifdef ATA_GAMESTAR_WORKAROUND
75static u8 ata_gamestar_workaround = 0;
84static u16 ata_param[256];
95 {ATA_C_CFA_REQUEST_EXTENDED_ERROR_CODE, 1},
96 {ATA_C_DEVICE_RESET, 5},
97 {ATA_C_READ_SECTOR, 2},
98 {ATA_C_READ_SECTOR_EXT, 0x82},
99 {ATA_C_READ_DMA_EXT, 0x84},
100 {ATA_C_READ_NATIVE_MAX_ADDRESS_EXT, 0x81},
101 {ATA_C_READ_MULTIPLE_EXT, 0x82},
102 {ATA_C_WRITE_SECTOR, 3},
103 {ATA_C_WRITE_LONG, 8},
104 {ATA_C_WRITE_SECTOR_EXT, 0x83},
105 {ATA_C_WRITE_DMA_EXT, 0x84},
106 {ATA_C_SET_MAX_ADDRESS_EXT, 0x81},
107 {ATA_C_CFA_WRITE_SECTORS_WITHOUT_ERASE, 3},
108 {ATA_C_WRITE_MULTIPLE_EXT, 0x83},
109 {ATA_C_READ_VERIFY_SECTOR, 1},
110 {ATA_C_READ_VERIFY_SECTOR_EXT, 0x81},
112 {ATA_C_CFA_TRANSLATE_SECTOR, 2},
113 {ATA_C_SCE_SECURITY_CONTROL, 7},
114 {ATA_C_EXECUTE_DEVICE_DIAGNOSTIC, 6},
115 {ATA_C_INITIALIZE_DEVICE_PARAMETERS, 1},
116 {ATA_C_DOWNLOAD_MICROCODE, 3},
117 {ATA_C_IDENTIFY_PACKET_DEVICE, 2},
119 {ATA_C_CFA_ERASE_SECTORS, 1},
120 {ATA_C_READ_MULTIPLE, 2},
121 {ATA_C_WRITE_MULTIPLE, 3},
122 {ATA_C_SET_MULTIPLE_MODE, 1},
124 {ATA_C_WRITE_DMA, 4},
125 {ATA_C_CFA_WRITE_MULTIPLE_WITHOUT_ERASE, 3},
126 {ATA_C_GET_MEDIA_STATUS, 1},
127 {ATA_C_MEDIA_LOCK, 1},
128 {ATA_C_MEDIA_UNLOCK, 1},
129 {ATA_C_STANDBY_IMMEDIATE, 1},
130 {ATA_C_IDLE_IMMEDIATE, 1},
133 {ATA_C_READ_BUFFER, 2},
134 {ATA_C_CHECK_POWER_MODE, 1},
136 {ATA_C_FLUSH_CACHE, 1},
137 {ATA_C_WRITE_BUFFER, 3},
138 {ATA_C_FLUSH_CACHE_EXT, 1},
139 {ATA_C_IDENTIFY_DEVICE, 2},
140 {ATA_C_MEDIA_EJECT, 1},
141 {ATA_C_SET_FEATURES, 1},
142 {ATA_C_SECURITY_SET_PASSWORD, 3},
143 {ATA_C_SECURITY_UNLOCK, 3},
144 {ATA_C_SECURITY_ERASE_PREPARE, 1},
145 {ATA_C_SECURITY_ERASE_UNIT, 3},
146 {ATA_C_SECURITY_FREEZE_LOCK, 1},
147 {ATA_C_SECURITY_DISABLE_PASSWORD, 3},
148 {ATA_C_READ_NATIVE_MAX_ADDRESS, 1},
149 {ATA_C_SET_MAX_ADDRESS, 1}};
150#define ATA_CMD_TABLE_SIZE (sizeof ata_cmd_table / sizeof(ata_cmd_info_t))
153 {ATA_SCE_IDENTIFY_DRIVE, 2},
154 {ATA_SCE_SECURITY_ERASE_PREPARE, 1},
155 {ATA_SCE_SECURITY_ERASE_UNIT, 1},
156 {ATA_SCE_SECURITY_FREEZE_LOCK, 1},
157 {ATA_SCE_SECURITY_SET_PASSWORD, 3},
158 {ATA_SCE_SECURITY_UNLOCK, 3},
159 {ATA_SCE_SECURITY_WRITE_ID, 3},
160 {ATA_SCE_SECURITY_READ_ID, 2}};
161#define SEC_CTRL_CMD_TABLE_SIZE (sizeof sec_ctrl_cmd_table / sizeof(ata_cmd_info_t))
164 {ATA_S_SMART_READ_DATA, 2},
165 {ATA_S_SMART_ENABLE_DISABLE_AUTOSAVE, 1},
166 {ATA_S_SMART_SAVE_ATTRIBUTE_VALUES, 1},
167 {ATA_S_SMART_EXECUTE_OFF_LINE, 1},
168 {ATA_S_SMART_READ_LOG, 2},
169 {ATA_S_SMART_WRITE_LOG, 3},
170 {ATA_S_SMART_ENABLE_OPERATIONS, 1},
171 {ATA_S_SMART_DISABLE_OPERATIONS, 1},
172 {ATA_S_SMART_RETURN_STATUS, 1}};
173#define SMART_CMD_TABLE_SIZE (sizeof smart_cmd_table / sizeof(ata_cmd_info_t))
193#define ATA_BD_SECTOR_SIZE 512
198static int ata_intr_cb(
int flag);
200#ifdef ATA_USE_AIFDEV9
201static int ata_intr_cb(
void);
203static unsigned int ata_alarm_cb(
void *unused);
205#ifdef ATA_USE_AIFDEV9
206static void aif_tune_drive(
int unit,
int mode);
210static void ata_set_dir(
int dir);
212static void ata_pio_mode(
int mode);
213#ifdef ATA_MWDMA_MODES
214static void ata_multiword_dma_mode(
int mode);
216static void ata_ultra_dma_mode(
int mode);
218static void ata_shutdown_cb(
void);
220int ata_device_sector_io64(
int device,
void *buf, u64 lba, u32 nsectors,
int dir);
223static int ata_bd_read(
struct block_device *bd, u64 sector,
void *buffer, u16
count);
224static int ata_bd_write(
struct block_device *bd, u64 sector,
const void *buffer, u16
count);
233static void ata_pre_dma_cb(
int bcr,
int dir)
240 SPD_REG16(SPD_R_XFR_CTRL) |= 0x80;
243static void ata_post_dma_cb(
int bcr,
int dir)
250 SPD_REG16(SPD_R_XFR_CTRL) &= ~0x80;
254static int ata_create_event_flag(
void)
260 return CreateEventFlag(&
event);
263int _start(
int argc,
char *argv[])
268#ifdef ATA_USE_AIFDEV9
276 printf(BANNER, VERSION);
278 res = MODULE_NO_RESIDENT_END;
281 if (!(SPD_REG16(SPD_R_REV_3) & SPD_CAPS_ATA) || !(SPD_REG16(SPD_R_REV_8) & 0x02)) {
282 M_PRINTF(
"HDD is not connected, exiting.\n");
297 ata_dvrp_workaround = (SPD_REG16(SPD_R_REV_3) & SPD_CAPS_DVR) ? 1 : 0;
300#ifdef ATA_USE_AIFDEV9
301 if (!aifIsDetected()) {
302 M_PRINTF(
"AIF HDD: controller not found.\n");
305 aif_regs[AIF_ATA_TCFG] = 0;
309#ifdef ATA_GAMESTAR_WORKAROUND
314 if (SPD_REG16(0x20) != 1) {
315 ata_gamestar_workaround = 1;
316 M_PRINTF(
"Compatible adaptor detected.\n");
318 ata_gamestar_workaround = 0;
323 if ((ata_evflg = ata_create_event_flag()) < 0) {
324 M_PRINTF(
"Couldn't create event flag, exiting.\n");
330 SpdRegisterIntrHandler(1, &ata_intr_cb);
331 SpdRegisterIntrHandler(0, &ata_intr_cb);
332#ifdef ATA_GAMESTAR_WORKAROUND
333 if (!ata_gamestar_workaround) {
335 dev9RegisterPreDmaCb(0, &ata_pre_dma_cb);
336 dev9RegisterPostDmaCb(0, &ata_post_dma_cb);
337#ifdef ATA_GAMESTAR_WORKAROUND
341 Dev9RegisterPowerOffHandler(15, &ata_shutdown_cb);
344#ifdef ATA_USE_AIFDEV9
345 aifRegisterIntrCb(AIF_INUM_ATA0, &ata_intr_cb);
346 aifRegisterShutdownCb(AIF_INUM_ATA0, &ata_shutdown_cb);
348 M_PRINTF(
"AIF HDD initialized.\n");
355 for (i = 0; i < NUM_DEVICES; ++i) {
356 g_ata_bd[i].priv = (
void *)&atad_devinfo[i];
357 g_ata_bd[i].name =
"ata";
358 g_ata_bd[i].devNr = i;
359 g_ata_bd[i].parNr = 0;
360 g_ata_bd[i].parId = 0x00;
361 g_ata_bd[i].sectorSize = 512;
362 g_ata_bd[i].sectorOffset = 0;
363 g_ata_bd[i].sectorCount = 0;
365 g_ata_bd[i].read = ata_bd_read;
366 g_ata_bd[i].write = ata_bd_write;
367 g_ata_bd[i].flush = ata_bd_flush;
368 g_ata_bd[i].stop = ata_bd_stop;
376 if (RegisterLibraryEntries(&_exp_atad) != 0) {
377 M_PRINTF(
"Library is already registered, exiting.\n");
381 res = MODULE_RESIDENT_END;
382 M_PRINTF(
"Driver loaded.\n");
387int _exit(
void) {
return MODULE_RESIDENT_END; }
390static int ata_intr_cb(
int flag)
393 memset(atad_devinfo, 0,
sizeof atad_devinfo);
395 SpdIntrDisable(SPD_INTR_ATA);
396 iSetEventFlag(ata_evflg, ATA_EV_COMPLETE);
403#ifdef ATA_USE_AIFDEV9
404static int ata_intr_cb(
void)
406 aifIntrDisable(AIF_INTR_ATA0);
407 iSetEventFlag(ata_evflg, ATA_EV_COMPLETE);
413static unsigned int ata_alarm_cb(
void *unused)
417 iSetEventFlag(ata_evflg, ATA_EV_TIMEOUT);
422int sceAtaGetError(
void)
427#ifdef ATA_USE_AIFDEV9
430 return ata_hwport->r_error & 0xff;
433#define ATA_WAIT_BUSY 0x80
434#define ATA_WAIT_BUSBUSY 0x88
436#define ata_wait_busy() gen_ata_wait_busy(ATA_WAIT_BUSY)
437#define ata_wait_bus_busy() gen_ata_wait_busy(ATA_WAIT_BUSBUSY)
441static int gen_ata_wait_busy(
int bits)
446#ifdef ATA_USE_AIFDEV9
451 for (i = 0; i < 80; i++) {
454 if (!(ata_hwport->r_control & bits))
480 M_PRINTF(
"Timeout while waiting on busy (0x%02x).\n", bits);
481 return ATA_RES_ERR_TIMEOUT;
484static int ata_device_select(
int device)
489#ifdef ATA_USE_AIFDEV9
494 if ((res = ata_wait_bus_busy()) < 0)
498 if (((ata_hwport->r_select >> 4) & 1) == device)
502 ata_hwport->r_select = (device & 1) << 4;
503 (void)(ata_hwport->r_control);
504 (void)(ata_hwport->r_control);
506 return ata_wait_bus_busy();
519int sceAtaExecCmd(
void *buf, u32 blkcount, u16 feature, u16 nsector, u16 sector, u16 lcyl, u16 hcyl, u16 select, u16 command)
524#ifdef ATA_USE_AIFDEV9
529 int i, res, type, cmd_table_size;
530 int using_timeout, device = (select >> 4) & 1;
533 ClearEventFlag(ata_evflg, 0);
535 if (!atad_devinfo[device].exists)
536 return ATA_RES_ERR_NODEV;
538 if ((res = ata_device_select(device)) != 0)
543 if (command == ATA_C_SCE_SECURITY_CONTROL) {
544 cmd_table = sec_ctrl_cmd_table;
545 cmd_table_size = SEC_CTRL_CMD_TABLE_SIZE;
546 searchcmd = (u8)feature;
547 }
else if (command == ATA_C_SMART) {
548 cmd_table = smart_cmd_table;
549 cmd_table_size = SMART_CMD_TABLE_SIZE;
550 searchcmd = (u8)feature;
552 cmd_table = ata_cmd_table;
553 cmd_table_size = ATA_CMD_TABLE_SIZE;
554 searchcmd = (u8)command;
558 for (i = 0; i < cmd_table_size; i++) {
559 if (searchcmd == cmd_table[i].command) {
560 type = cmd_table[i].type;
565 if (!(atad_cmd_state.type = type & 0x7F))
566 return ATA_RES_ERR_CMD;
568 atad_cmd_state.buf = buf;
569 atad_cmd_state.blkcount = blkcount;
572 if (!(ata_hwport->r_control & 0x40)) {
574 case ATA_C_DEVICE_RESET:
575 case ATA_C_EXECUTE_DEVICE_DIAGNOSTIC:
576 case ATA_C_INITIALIZE_DEVICE_PARAMETERS:
578 case ATA_C_IDENTIFY_PACKET_DEVICE:
581 M_PRINTF(
"Error: Device %d is not ready.\n", device);
582 return ATA_RES_ERR_NOTREADY;
588 switch (type & 0x7F) {
594 atad_cmd_state.dir = (command != ATA_C_READ_DMA && command != ATA_C_READ_DMA_EXT);
600 cmd_timeout.lo = 0x41eb0000;
604 if (command == ATA_C_SCE_SECURITY_CONTROL && feature == ATA_SCE_SECURITY_ERASE_UNIT)
605 USec2SysClock(180000000, &cmd_timeout);
607 if ((res = SetAlarm(&cmd_timeout, &ata_alarm_cb, NULL)) < 0)
612 if ((type & 0x7F) == 1) {
614 SpdIntrEnable(SPD_INTR_ATA0);
616#ifdef ATA_USE_AIFDEV9
617 aifIntrEnable(AIF_INTR_ATA0);
622 ata_hwport->r_control = (using_timeout == 0) << 1;
629 ata_hwport->r_feature = (feature >> 8) & 0xff;
630 ata_hwport->r_nsector = (nsector >> 8) & 0xff;
631 ata_hwport->r_sector = (sector >> 8) & 0xff;
632 ata_hwport->r_lcyl = (lcyl >> 8) & 0xff;
633 ata_hwport->r_hcyl = (hcyl >> 8) & 0xff;
636 ata_hwport->r_feature = feature & 0xff;
637 ata_hwport->r_nsector = nsector & 0xff;
638 ata_hwport->r_sector = sector & 0xff;
639 ata_hwport->r_lcyl = lcyl & 0xff;
640 ata_hwport->r_hcyl = hcyl & 0xff;
641 ata_hwport->r_select = (select | ATA_SEL_LBA) & 0xff;
642 ata_hwport->r_command = command & 0xff;
658#ifdef ATA_USE_AIFDEV9
663 u16 status = ata_hwport->r_status & 0xff;
665 if (status & ATA_STAT_ERR) {
666 M_PRINTF(
"Error: PIO cmd error: status 0x%02x, error 0x%02x.\n", status, sceAtaGetError());
667 return ATA_RES_ERR_IO;
671 if (!(status & ATA_STAT_DRQ))
672 return ATA_RES_ERR_NODATA;
674 type = cmd_state->type;
676 if (type == 3 || type == 8) {
678 buf16 = cmd_state->buf16;
679 for (i = 0; i < 256; i++) {
680 ata_hwport->r_data = *buf16;
681 cmd_state->buf16 = ++buf16;
683 if (cmd_state->type == 8) {
686 buf8 = cmd_state->buf8;
687 for (i = 0; i < 4; i++) {
688 ata_hwport->r_data = *buf8;
689 cmd_state->buf8 = ++buf8;
692 }
else if (type == 2) {
694 buf16 = cmd_state->buf16;
695 for (i = 0; i < 256; i++) {
696 *buf16 = ata_hwport->r_data;
697 cmd_state->buf16 = ++buf16;
706static int ata_dma_complete(
void *buf, u32 blkcount,
int dir)
710 u32 bits,
count, nbytes;
715 for (i = 0; i < 20; i++)
716 if ((dma_stat = SPD_REG16(0x38) & 0x1f))
722 SpdIntrEnable(SPD_INTR_ATA);
724 WaitEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits);
726 if (bits & ATA_EV_TIMEOUT) {
727 M_PRINTF(
"Error: DMA timeout.\n");
728 return ATA_RES_ERR_TIMEOUT;
731 if (!(SPD_REG16(SPD_R_INTR_STAT) & 0x02)) {
732 if (ata_hwport->r_control & 0x01) {
733 M_PRINTF(
"Error: Command error while doing DMA.\n");
734 M_PRINTF(
"Error: Command error status 0x%02x, error 0x%02x.\n", ata_hwport->r_status, sceAtaGetError());
736 return ((sceAtaGetError() & ATA_ERR_ICRC) ? ATA_RES_ERR_ICRC : ATA_RES_ERR_IO);
738 M_PRINTF(
"Warning: Got command interrupt, but not an error.\n");
743 dma_stat = SPD_REG16(0x38) & 0x1f;
746 count = (blkcount < dma_stat) ? blkcount : dma_stat;
747 nbytes =
count * 512;
748 if ((res = SpdDmaTransfer(0, buf, (nbytes << 9) | 32, dir)) < 0)
751 buf = (
void *)((u8 *)buf + nbytes);
760int sceAtaWaitResult(
void)
766#ifdef ATA_USE_AIFDEV9
771 int res = 0, type = cmd_state->type;
774 if (type == 1 || type == 6) {
775 WaitEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits);
776 if (bits & ATA_EV_TIMEOUT) {
777 M_PRINTF(
"Error: ATA timeout on a non-data command.\n");
778 return ATA_RES_ERR_TIMEOUT;
780 }
else if (type == 4) {
784 if ((res = ata_dma_complete(cmd_state->buf, cmd_state->blkcount,
785 cmd_state->dir)) < 0)
788 for (i = 0; i < 100; i++)
789 if ((stat = SPD_REG16(SPD_R_INTR_STAT) & 0x01))
792 SpdIntrEnable(SPD_INTR_ATA0);
793 WaitEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits);
794 if (bits & ATA_EV_TIMEOUT) {
795 M_PRINTF(
"Error: ATA timeout on DMA completion, buffer stat %04x\n", SPD_REG16(0x38));
796 M_PRINTF(
"Error: istat %x, ienable %x\n", SPD_REG16(SPD_R_INTR_STAT), SPD_REG16(SPD_R_INTR_MASK));
797 res = ATA_RES_ERR_TIMEOUT;
801#ifdef ATA_USE_AIFDEV9
805 stat = ata_hwport->r_control;
806 if ((res = ata_wait_busy()) < 0)
810 while ((
int)(--cmd_state->blkcount) != -1) {
811 if ((res = ata_pio_transfer(cmd_state)) < 0)
813 if ((res = ata_wait_busy()) < 0)
822 if (ata_hwport->r_status & ATA_STAT_BUSY)
823 res = ata_wait_busy();
824 if ((stat = ata_hwport->r_status) & ATA_STAT_ERR) {
825 M_PRINTF(
"Error: Command error: status 0x%02x, error 0x%02x.\n", stat, sceAtaGetError());
827 res = (sceAtaGetError() & ATA_ERR_ICRC) ? ATA_RES_ERR_ICRC : ATA_RES_ERR_IO;
832 CancelAlarm(&ata_alarm_cb, NULL);
839 M_PRINTF(
"error: ATA failed, %d\n", res);
845static int ata_bus_reset(
void)
849 SPD_REG16(SPD_R_IF_CTRL) = SPD_IF_ATA_RESET;
851 SPD_REG16(SPD_R_IF_CTRL) = 0;
852 SPD_REG16(SPD_R_IF_CTRL) = 0x48;
855 return ata_wait_busy();
859int sceAtaSoftReset(
void)
864#ifdef ATA_USE_AIFDEV9
868 if (ata_hwport->r_control & 0x80)
869 return ATA_RES_ERR_NOTREADY;
872 ata_hwport->r_control = 6;
876 ata_hwport->r_control = 2;
879 return ata_wait_busy();
883int sceAtaFlushCache(
int device)
887 if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, (atad_devinfo[device].lba48 && !ata_dvrp_workaround) ? ATA_C_FLUSH_CACHE_EXT : ATA_C_FLUSH_CACHE)))
888 res = sceAtaWaitResult();
894int sceAtaIdle(
int device,
int period)
898 if (!(res = sceAtaExecCmd(NULL, 1, 0, period & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDLE)))
899 res = sceAtaWaitResult();
904static int ata_device_identify(
int device,
void *
info)
908 if (!(res = sceAtaExecCmd(
info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDENTIFY_DEVICE)))
909 res = sceAtaWaitResult();
914static int ata_device_pkt_identify(
int device,
void *
info)
918 res = sceAtaExecCmd(
info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDENTIFY_PACKET_DEVICE);
920 return sceAtaWaitResult();
925int sceAtaGetSceId(
int device,
void *data)
929 if (!(res = sceAtaExecCmd(data, 1, ATA_SCE_IDENTIFY_DRIVE, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)))
930 res = sceAtaWaitResult();
935static int ata_device_smart_enable(
int device)
939 if (!(res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_ENABLE_OPERATIONS, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART)))
940 res = sceAtaWaitResult();
946int sceAtaSmartSaveAttr(
int device)
950 if (!(res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_SAVE_ATTRIBUTE_VALUES, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART)))
951 res = sceAtaWaitResult();
957int sceAtaSmartReturnStatus(
int device)
962 res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_RETURN_STATUS, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART);
966 res = sceAtaWaitResult();
971 if (((ata_hwport->r_lcyl & 0xFF) != 0x4f) || ((ata_hwport->r_hcyl & 0xFF) != 0xc2)) {
972 M_PRINTF(
"Error: SMART report exceeded threshold.\n");
980static int ata_device_set_transfer_mode(
int device,
int type,
int mode)
984 res = sceAtaExecCmd(NULL, 1, 3, (type | mode) & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SET_FEATURES);
988 res = sceAtaWaitResult();
994#ifdef ATA_MWDMA_MODES
995 case ATA_XFER_MODE_MDMA:
996 ata_multiword_dma_mode(mode);
999 case ATA_XFER_MODE_UDMA:
1000 ata_ultra_dma_mode(mode);
1002 case ATA_XFER_MODE_PIO:
1006#ifdef ATA_USE_AIFDEV9
1007 case ATA_XFER_MODE_PIO:
1008 aif_tune_drive(0, mode);
1018int sceAtaDmaTransfer(
int device,
void *buf, u32 lba, u32 nsectors,
int dir)
1020 return ata_device_sector_io64(device, buf, (u64)lba, nsectors, dir);
1023int ata_device_sector_io64(
int device,
void *buf, u64 lba, u32 nsectors,
int dir)
1026 int res = 0, retries;
1027 u16 sector, lcyl, hcyl, select, command, len;
1029 while (res == 0 && nsectors > 0) {
1031 if (atad_devinfo[device].lba48 && (ata_dvrp_workaround ? (lba >= atad_devinfo[device].total_sectors) : 1)) {
1033 len = (nsectors > 65536) ? 65536 : nsectors;
1036 sector = ((lba >> 16) & 0xff00) | (lba & 0xff);
1037 lcyl = ((lba >> 24) & 0xff00) | ((lba >> 8) & 0xff);
1038 hcyl = ((lba >> 32) & 0xff00) | ((lba >> 16) & 0xff);
1041 select = (device << 4) & 0xffff;
1042 command = (dir == 1) ? ATA_C_WRITE_DMA_EXT : ATA_C_READ_DMA_EXT;
1045 len = (nsectors > 256) ? 256 : nsectors;
1046 sector = lba & 0xff;
1047 lcyl = (lba >> 8) & 0xff;
1048 hcyl = (lba >> 16) & 0xff;
1051 select = ((device << 4) | ((lba >> 24) & 0xf)) & 0xffff;
1052 command = (dir == 1) ? ATA_C_WRITE_DMA : ATA_C_READ_DMA;
1055 for (retries = 3; retries > 0; retries--) {
1057#ifdef ATA_GAMESTAR_WORKAROUND
1059 if (ata_gamestar_workaround)
1064 if ((res = sceAtaExecCmd(buf, len, 0, len, sector, lcyl, hcyl, select, command)) != 0)
1068#ifdef ATA_GAMESTAR_WORKAROUND
1069 if (!ata_gamestar_workaround)
1077 res = sceAtaWaitResult();
1080 SPD_REG16(SPD_R_IF_CTRL) &= ~SPD_IF_DMA_ENABLE;
1082 if (res != ATA_RES_ERR_ICRC)
1086 buf = (
void *)((u8 *)buf + len * 512);
1094static void ata_get_security_status(
int device,
ata_devinfo_t *devinfo, u16 *param)
1096 if (ata_device_identify(device, param) == 0)
1101int sceAtaSecuritySetPassword(
int device,
void *password)
1104 u16 *param = ata_param;
1107 if (devinfo[device].security_status & ATA_F_SEC_ENABLED)
1110 memset(param, 0, 512);
1111 memcpy(param + 1, password, 32);
1113 res = sceAtaExecCmd(param, 1, ATA_SCE_SECURITY_SET_PASSWORD, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL);
1115 res = sceAtaWaitResult();
1117 ata_get_security_status(device, devinfo, param);
1122int sceAtaSecurityUnLock(
int device,
void *password)
1125 u16 *param = ata_param;
1128 if (!(devinfo[device].security_status & ATA_F_SEC_LOCKED))
1131 memset(param, 0, 512);
1132 memcpy(param + 1, password, 32);
1134 if ((res = sceAtaExecCmd(param, 1, ATA_SCE_SECURITY_UNLOCK, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)) != 0)
1136 if ((res = sceAtaWaitResult()) != 0)
1140 ata_get_security_status(device, devinfo, param);
1141 if (devinfo[device].security_status & ATA_F_SEC_LOCKED)
1142 return ATA_RES_ERR_LOCKED;
1148int sceAtaSecurityEraseUnit(
int device)
1153 if (!(devinfo[device].security_status & ATA_F_SEC_ENABLED) || !(devinfo[device].security_status & ATA_F_SEC_LOCKED))
1157 if ((res = sceAtaExecCmd(NULL, 1, ATA_SCE_SECURITY_ERASE_PREPARE, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)) != 0)
1159 if ((res = sceAtaWaitResult()) != 0)
1162 if ((res = sceAtaExecCmd(NULL, 1, ATA_SCE_SECURITY_ERASE_UNIT, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)) == 0)
1163 res = sceAtaWaitResult();
1166 ata_get_security_status(device, devinfo, NULL);
1175#ifdef ATA_USE_AIFDEV9
1178 u16 nsector, sector, lcyl, hcyl;
1183 if (ata_hwport->r_control & 0x88)
1186 nsector = ata_hwport->r_nsector & 0xff;
1187 sector = ata_hwport->r_sector & 0xff;
1188 lcyl = ata_hwport->r_lcyl & 0xff;
1189 hcyl = ata_hwport->r_hcyl & 0xff;
1190 (void)ata_hwport->r_select;
1192 if ((nsector != 1) || (sector != 1))
1196 if ((lcyl == 0x00) && (hcyl == 0x00))
1198 else if ((lcyl == 0x14) && (hcyl == 0xeb))
1203 ata_hwport->r_lcyl = 0x55;
1204 ata_hwport->r_hcyl = 0xaa;
1205 lcyl = ata_hwport->r_lcyl & 0xff;
1206 hcyl = ata_hwport->r_hcyl & 0xff;
1208 if ((lcyl != 0x55) || (hcyl != 0xaa))
1217#ifdef ATA_USE_AIFDEV9
1221 u32 total_sectors_nonlba48, total_sectors_lba48;
1223 if ((res = sceAtaSoftReset()) != 0)
1226 ata_device_probe(&devinfo[0]);
1227 if (!devinfo[0].exists) {
1228 M_PRINTF(
"Error: Unable to detect HDD 0.\n");
1230 return ATA_RES_ERR_NODEV;
1234 if ((res = ata_device_select(1)) != 0)
1236 if (ata_hwport->r_control & 0xff)
1237 ata_device_probe(&devinfo[1]);
1245 for (i = 0; i < 2; i++) {
1246 if (!devinfo[i].exists)
1251 if (!devinfo[i].has_packet) {
1252 res = ata_device_identify(i, ata_param);
1253 devinfo[i].
exists = (res == 0);
1254 }
else if (devinfo[i].has_packet == 1) {
1257 res = ata_device_pkt_identify(i, ata_param);
1258 devinfo[i].
exists = (res == 0);
1264 if (!devinfo[i].exists || devinfo[i].has_packet)
1270 devinfo[i].
lba48 = (ata_param[ATA_ID_COMMAND_SETS_SUPPORTED] & 0x0400) != 0;
1273 total_sectors_nonlba48 = (ata_param[ATA_ID_SECTOTAL_HI] << 16) | ata_param[ATA_ID_SECTOTAL_LO];
1274 if (ata_param[ATA_ID_48BIT_SECTOTAL_HI]) {
1275 total_sectors_lba48 = 0xffffffff;
1277 total_sectors_lba48 = (ata_param[ATA_ID_48BIT_SECTOTAL_MI] << 16) | ata_param[ATA_ID_48BIT_SECTOTAL_LO];
1284#ifdef ATA_ENABLE_MAXUDMA
1291 for (
int j = maxUDMA; j >= 0; j--) {
1293 if (((ata_param[ATA_ID_UDMA_CONTROL] & 0xFF) & (1 << j)) != 0) {
1298 ata_device_set_transfer_mode(i, ATA_XFER_MODE_UDMA, udmaMode);
1300#ifdef ATA_USE_AIFDEV9
1302 ata_device_set_transfer_mode(i, ATA_XFER_MODE_PIO, 4);
1304 ata_device_smart_enable(i);
1306 sceAtaIdle(i, 0xff);
1308 if (devinfo[i].lba48) {
1310 if (ata_dvrp_workaround) {
1322#ifdef ATA_SCE_AUTH_HDD
1323 if (sceAtaGetSceId(i, ata_param) != 0) {
1324 M_PRINTF(
"error: This is not SCE genuine HDD.\n");
1325 memset(&devinfo[i], 0,
sizeof(devinfo[i]));
1329#ifdef ATA_ENABLE_BDM
1331 bdm_connect_bd(&g_ata_bd[i]);
1340 if (!ata_devinfo_init) {
1341 ata_devinfo_init = 1;
1342 if (ata_bus_reset() || ata_init_devices(atad_devinfo))
1346 return &atad_devinfo[device];
1350static void ata_set_dir(
int dir)
1355 SPD_REG16(0x38) = 3;
1356 val = SPD_REG16(SPD_R_IF_CTRL) & 1;
1357 val |= (dir == ATA_DIR_WRITE) ? 0x4c : 0x4e;
1358 SPD_REG16(SPD_R_IF_CTRL) = val;
1359#ifdef ATA_GAMESTAR_WORKAROUND
1360 SPD_REG16(SPD_R_XFR_CTRL) = dir | (ata_gamestar_workaround ? 0x86 : 0x6);
1362 SPD_REG16(SPD_R_XFR_CTRL) = dir | 0x6;
1366static void ata_pio_mode(
int mode)
1370#ifdef ATA_ALL_PIO_MODES
1390 SPD_REG16(SPD_R_PIO_MODE) = val;
1393 SPD_REG16(SPD_R_PIO_MODE) = 0x92;
1397#ifdef ATA_MWDMA_MODES
1398static void ata_multiword_dma_mode(
int mode)
1414 SPD_REG16(SPD_R_MWDMA_MODE) = val;
1415 SPD_REG16(SPD_R_IF_CTRL) = (SPD_REG16(SPD_R_IF_CTRL) & 0xfffe) | 0x48;
1419static void ata_ultra_dma_mode(
int mode)
1441 SPD_REG16(SPD_R_UDMA_MODE) = val;
1442 SPD_REG16(SPD_R_IF_CTRL) |= 0x49;
1446#ifdef ATA_USE_AIFDEV9
1447static void aif_tune_drive(
int unit,
int mode)
1450 unsigned int use_iordy, value;
1453 value = (use_iordy << 3) | mode;
1454 M_PRINTF(
"AIF HDD: tune unit%d, mode=%u\n", unit, value);
1458 aif_regs[AIF_ATA_TCFG] = (aif_regs[AIF_ATA_TCFG] & 0xf0) + value;
1461 aif_regs[AIF_ATA_TCFG] = (aif_regs[AIF_ATA_TCFG] & 0x0f) + (value << 4);
1468int sceAtaIdleImmediate(
int device)
1472 if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xFFFF, ATA_C_IDLE_IMMEDIATE)))
1473 res = sceAtaWaitResult();
1478static int ata_device_standby_immediate(
int device)
1482 if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xFFFF, ATA_C_STANDBY_IMMEDIATE)))
1483 res = sceAtaWaitResult();
1488static void ata_shutdown_cb(
void)
1492 for (i = 0; i < 2; i++) {
1493 if (atad_devinfo[i].exists)
1494 ata_device_standby_immediate(i);
1498#ifdef ATA_ENABLE_BDM
1502static int ata_bd_read(
struct block_device *bd, u64 sector,
void *buffer, u16
count)
1504 if (ata_device_sector_io64(bd->devNr, buffer, sector,
count, ATA_DIR_READ) != 0) {
1511static int ata_bd_write(
struct block_device *bd, u64 sector,
const void *buffer, u16
count)
1513 if (ata_device_sector_io64(bd->devNr, (
void *)buffer, sector,
count, ATA_DIR_WRITE) != 0) {
1522 sceAtaFlushCache(bd->devNr);
1527 ata_device_standby_immediate(bd->devNr);
u32 count
start sector of fragmented bd/file