33 #ifdef ATA_USE_AIFDEV9
47 #define MODNAME "atad"
51 IRX_ID(MODNAME, 2, 7);
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"
57 #define VERSION "v1.2"
59 #define ATA_XFER_MODE_PIO 0x08
60 #ifdef ATA_MWDMA_MODES
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
68 static int ata_devinfo_init = 0;
69 static int ata_evflg = -1;
72 static u8 ata_dvrp_workaround = 0;
74 #ifdef ATA_GAMESTAR_WORKAROUND
75 static u8 ata_gamestar_workaround = 0;
84 static 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))
191 #ifdef ATA_ENABLE_BDM
192 #define NUM_DEVICES 2
193 #define ATA_BD_SECTOR_SIZE 512
198 static int ata_intr_cb(
int flag);
200 #ifdef ATA_USE_AIFDEV9
201 static int ata_intr_cb(
void);
203 static unsigned int ata_alarm_cb(
void *unused);
205 #ifdef ATA_USE_AIFDEV9
206 static void aif_tune_drive(
int unit,
int mode);
210 static void ata_set_dir(
int dir);
212 static void ata_pio_mode(
int mode);
213 #ifdef ATA_MWDMA_MODES
214 static void ata_multiword_dma_mode(
int mode);
216 static void ata_ultra_dma_mode(
int mode);
218 static void ata_shutdown_cb(
void);
220 int ata_device_sector_io64(
int device,
void *buf, u64 lba, u32 nsectors,
int dir);
222 #ifdef ATA_ENABLE_BDM
223 static int ata_bd_read(
struct block_device *bd, u64 sector,
void *buffer, u16
count);
224 static int ata_bd_write(
struct block_device *bd, u64 sector,
const void *buffer, u16
count);
233 static void ata_pre_dma_cb(
int bcr,
int dir)
240 SPD_REG16(SPD_R_XFR_CTRL) |= 0x80;
243 static void ata_post_dma_cb(
int bcr,
int dir)
250 SPD_REG16(SPD_R_XFR_CTRL) &= ~0x80;
254 static int ata_create_event_flag(
void)
260 return CreateEventFlag(&
event);
263 int _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 ata_gamestar_workaround = (SPD_REG16(0x20) != 1) ? 1 : 0;
315 if (ata_gamestar_workaround) {
316 M_PRINTF(
"Compatible adaptor detected.\n");
319 ata_dvrp_workaround = 0;
324 if ((ata_evflg = ata_create_event_flag()) < 0) {
325 M_PRINTF(
"Couldn't create event flag, exiting.\n");
331 SpdRegisterIntrHandler(1, &ata_intr_cb);
332 SpdRegisterIntrHandler(0, &ata_intr_cb);
333 #ifdef ATA_GAMESTAR_WORKAROUND
334 if (!ata_gamestar_workaround) {
336 dev9RegisterPreDmaCb(0, &ata_pre_dma_cb);
337 dev9RegisterPostDmaCb(0, &ata_post_dma_cb);
338 #ifdef ATA_GAMESTAR_WORKAROUND
342 Dev9RegisterPowerOffHandler(15, &ata_shutdown_cb);
345 #ifdef ATA_USE_AIFDEV9
346 aifRegisterIntrCb(AIF_INUM_ATA0, &ata_intr_cb);
347 aifRegisterShutdownCb(AIF_INUM_ATA0, &ata_shutdown_cb);
349 M_PRINTF(
"AIF HDD initialized.\n");
352 #ifdef ATA_ENABLE_BDM
356 for (i = 0; i < NUM_DEVICES; ++i) {
357 g_ata_bd[i].priv = (
void *)&atad_devinfo[i];
358 g_ata_bd[i].name =
"ata";
359 g_ata_bd[i].path =
"ata";
360 g_ata_bd[i].devNr = i;
361 g_ata_bd[i].parNr = 0;
362 g_ata_bd[i].parId = 0x00;
363 g_ata_bd[i].sectorSize = 512;
364 g_ata_bd[i].sectorOffset = 0;
365 g_ata_bd[i].sectorCount = 0;
367 g_ata_bd[i].read = ata_bd_read;
368 g_ata_bd[i].write = ata_bd_write;
369 g_ata_bd[i].flush = ata_bd_flush;
370 g_ata_bd[i].stop = ata_bd_stop;
378 if (RegisterLibraryEntries(&_exp_atad) != 0) {
379 M_PRINTF(
"Library is already registered, exiting.\n");
383 res = MODULE_RESIDENT_END;
384 M_PRINTF(
"Driver loaded.\n");
389 int _exit(
void) {
return MODULE_RESIDENT_END; }
392 static int ata_intr_cb(
int flag)
395 memset(atad_devinfo, 0,
sizeof atad_devinfo);
397 SpdIntrDisable(SPD_INTR_ATA);
398 iSetEventFlag(ata_evflg, ATA_EV_COMPLETE);
405 #ifdef ATA_USE_AIFDEV9
406 static int ata_intr_cb(
void)
408 aifIntrDisable(AIF_INTR_ATA0);
409 iSetEventFlag(ata_evflg, ATA_EV_COMPLETE);
415 static unsigned int ata_alarm_cb(
void *unused)
419 iSetEventFlag(ata_evflg, ATA_EV_TIMEOUT);
424 int sceAtaGetError(
void)
429 #ifdef ATA_USE_AIFDEV9
432 return ata_hwport->r_error & 0xff;
435 #define ATA_WAIT_BUSY 0x80
436 #define ATA_WAIT_BUSBUSY 0x88
438 #define ata_wait_busy() gen_ata_wait_busy(ATA_WAIT_BUSY)
439 #define ata_wait_bus_busy() gen_ata_wait_busy(ATA_WAIT_BUSBUSY)
443 static int gen_ata_wait_busy(
int bits)
448 #ifdef ATA_USE_AIFDEV9
453 for (i = 0; i < 80; i++) {
456 if (!(ata_hwport->r_control & bits))
482 M_PRINTF(
"Timeout while waiting on busy (0x%02x).\n", bits);
483 return ATA_RES_ERR_TIMEOUT;
486 static int ata_device_select(
int device)
491 #ifdef ATA_USE_AIFDEV9
496 if ((res = ata_wait_bus_busy()) < 0)
500 if (((ata_hwport->r_select >> 4) & 1) == device)
504 ata_hwport->r_select = (device & 1) << 4;
505 (void)(ata_hwport->r_control);
506 (void)(ata_hwport->r_control);
508 return ata_wait_bus_busy();
521 int sceAtaExecCmd(
void *buf, u32 blkcount, u16 feature, u16 nsector, u16 sector, u16 lcyl, u16 hcyl, u16 select, u16 command)
526 #ifdef ATA_USE_AIFDEV9
531 int i, res, type, cmd_table_size;
532 int using_timeout, device = (select >> 4) & 1;
535 ClearEventFlag(ata_evflg, 0);
537 if (!atad_devinfo[device].exists)
538 return ATA_RES_ERR_NODEV;
540 if ((res = ata_device_select(device)) != 0)
545 if (command == ATA_C_SCE_SECURITY_CONTROL) {
546 cmd_table = sec_ctrl_cmd_table;
547 cmd_table_size = SEC_CTRL_CMD_TABLE_SIZE;
548 searchcmd = (u8)feature;
549 }
else if (command == ATA_C_SMART) {
550 cmd_table = smart_cmd_table;
551 cmd_table_size = SMART_CMD_TABLE_SIZE;
552 searchcmd = (u8)feature;
554 cmd_table = ata_cmd_table;
555 cmd_table_size = ATA_CMD_TABLE_SIZE;
556 searchcmd = (u8)command;
560 for (i = 0; i < cmd_table_size; i++) {
561 if (searchcmd == cmd_table[i].command) {
562 type = cmd_table[i].type;
567 if (!(atad_cmd_state.type = type & 0x7F))
568 return ATA_RES_ERR_CMD;
570 atad_cmd_state.buf = buf;
571 atad_cmd_state.blkcount = blkcount;
574 if (!(ata_hwport->r_control & 0x40)) {
576 case ATA_C_DEVICE_RESET:
577 case ATA_C_EXECUTE_DEVICE_DIAGNOSTIC:
578 case ATA_C_INITIALIZE_DEVICE_PARAMETERS:
580 case ATA_C_IDENTIFY_PACKET_DEVICE:
583 M_PRINTF(
"Error: Device %d is not ready.\n", device);
584 return ATA_RES_ERR_NOTREADY;
590 switch (type & 0x7F) {
596 atad_cmd_state.dir = (command != ATA_C_READ_DMA && command != ATA_C_READ_DMA_EXT);
602 cmd_timeout.lo = 0x41eb0000;
606 if (command == ATA_C_SCE_SECURITY_CONTROL && feature == ATA_SCE_SECURITY_ERASE_UNIT)
607 USec2SysClock(180000000, &cmd_timeout);
609 if ((res = SetAlarm(&cmd_timeout, &ata_alarm_cb, NULL)) < 0)
614 if ((type & 0x7F) == 1) {
616 SpdIntrEnable(SPD_INTR_ATA0);
618 #ifdef ATA_USE_AIFDEV9
619 aifIntrEnable(AIF_INTR_ATA0);
624 ata_hwport->r_control = (using_timeout == 0) << 1;
631 ata_hwport->r_feature = (feature >> 8) & 0xff;
632 ata_hwport->r_nsector = (nsector >> 8) & 0xff;
633 ata_hwport->r_sector = (sector >> 8) & 0xff;
634 ata_hwport->r_lcyl = (lcyl >> 8) & 0xff;
635 ata_hwport->r_hcyl = (hcyl >> 8) & 0xff;
638 ata_hwport->r_feature = feature & 0xff;
639 ata_hwport->r_nsector = nsector & 0xff;
640 ata_hwport->r_sector = sector & 0xff;
641 ata_hwport->r_lcyl = lcyl & 0xff;
642 ata_hwport->r_hcyl = hcyl & 0xff;
643 ata_hwport->r_select = (select | ATA_SEL_LBA) & 0xff;
644 ata_hwport->r_command = command & 0xff;
660 #ifdef ATA_USE_AIFDEV9
665 u16 status = ata_hwport->r_status & 0xff;
667 if (status & ATA_STAT_ERR) {
668 M_PRINTF(
"Error: PIO cmd error: status 0x%02x, error 0x%02x.\n", status, sceAtaGetError());
669 return ATA_RES_ERR_IO;
673 if (!(status & ATA_STAT_DRQ))
674 return ATA_RES_ERR_NODATA;
676 type = cmd_state->type;
678 if (type == 3 || type == 8) {
680 buf16 = cmd_state->buf16;
681 for (i = 0; i < 256; i++) {
682 ata_hwport->r_data = *buf16;
683 cmd_state->buf16 = ++buf16;
685 if (cmd_state->type == 8) {
688 buf8 = cmd_state->buf8;
689 for (i = 0; i < 4; i++) {
690 ata_hwport->r_data = *buf8;
691 cmd_state->buf8 = ++buf8;
694 }
else if (type == 2) {
696 buf16 = cmd_state->buf16;
697 for (i = 0; i < 256; i++) {
698 *buf16 = ata_hwport->r_data;
699 cmd_state->buf16 = ++buf16;
708 static int ata_dma_complete(
void *buf, u32 blkcount,
int dir)
712 u32 bits,
count, nbytes;
717 for (i = 0; i < 20; i++)
718 if ((dma_stat = SPD_REG16(0x38) & 0x1f))
724 SpdIntrEnable(SPD_INTR_ATA);
726 WaitEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits);
728 if (bits & ATA_EV_TIMEOUT) {
729 M_PRINTF(
"Error: DMA timeout.\n");
730 return ATA_RES_ERR_TIMEOUT;
733 if (!(SPD_REG16(SPD_R_INTR_STAT) & 0x02)) {
734 if (ata_hwport->r_control & 0x01) {
735 M_PRINTF(
"Error: Command error while doing DMA.\n");
736 M_PRINTF(
"Error: Command error status 0x%02x, error 0x%02x.\n", ata_hwport->r_status, sceAtaGetError());
738 return ((sceAtaGetError() & ATA_ERR_ICRC) ? ATA_RES_ERR_ICRC : ATA_RES_ERR_IO);
740 M_PRINTF(
"Warning: Got command interrupt, but not an error.\n");
745 dma_stat = SPD_REG16(0x38) & 0x1f;
748 count = (blkcount < dma_stat) ? blkcount : dma_stat;
749 nbytes =
count * 512;
750 if ((res = SpdDmaTransfer(0, buf, (nbytes << 9) | 32, dir)) < 0)
753 buf = (
void *)((u8 *)buf + nbytes);
762 int sceAtaWaitResult(
void)
768 #ifdef ATA_USE_AIFDEV9
773 int res = 0, type = cmd_state->type;
776 if (type == 1 || type == 6) {
777 WaitEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits);
778 if (bits & ATA_EV_TIMEOUT) {
779 M_PRINTF(
"Error: ATA timeout on a non-data command.\n");
780 return ATA_RES_ERR_TIMEOUT;
782 }
else if (type == 4) {
786 if ((res = ata_dma_complete(cmd_state->buf, cmd_state->blkcount,
787 cmd_state->dir)) < 0)
790 for (i = 0; i < 100; i++)
791 if ((stat = SPD_REG16(SPD_R_INTR_STAT) & 0x01))
794 SpdIntrEnable(SPD_INTR_ATA0);
795 WaitEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits);
796 if (bits & ATA_EV_TIMEOUT) {
797 M_PRINTF(
"Error: ATA timeout on DMA completion, buffer stat %04x\n", SPD_REG16(0x38));
798 M_PRINTF(
"Error: istat %x, ienable %x\n", SPD_REG16(SPD_R_INTR_STAT), SPD_REG16(SPD_R_INTR_MASK));
799 res = ATA_RES_ERR_TIMEOUT;
803 #ifdef ATA_USE_AIFDEV9
807 stat = ata_hwport->r_control;
808 if ((res = ata_wait_busy()) < 0)
812 while ((
int)(--cmd_state->blkcount) != -1) {
813 if ((res = ata_pio_transfer(cmd_state)) < 0)
815 if ((res = ata_wait_busy()) < 0)
824 if (ata_hwport->r_status & ATA_STAT_BUSY)
825 res = ata_wait_busy();
826 if ((stat = ata_hwport->r_status) & ATA_STAT_ERR) {
827 M_PRINTF(
"Error: Command error: status 0x%02x, error 0x%02x.\n", stat, sceAtaGetError());
829 res = (sceAtaGetError() & ATA_ERR_ICRC) ? ATA_RES_ERR_ICRC : ATA_RES_ERR_IO;
834 CancelAlarm(&ata_alarm_cb, NULL);
841 M_PRINTF(
"error: ATA failed, %d\n", res);
847 static int ata_bus_reset(
void)
851 SPD_REG16(SPD_R_IF_CTRL) = SPD_IF_ATA_RESET;
853 SPD_REG16(SPD_R_IF_CTRL) = 0;
854 SPD_REG16(SPD_R_IF_CTRL) = 0x48;
857 return ata_wait_busy();
861 int sceAtaSoftReset(
void)
866 #ifdef ATA_USE_AIFDEV9
870 if (ata_hwport->r_control & 0x80)
871 return ATA_RES_ERR_NOTREADY;
874 ata_hwport->r_control = 6;
878 ata_hwport->r_control = 2;
881 return ata_wait_busy();
885 int sceAtaFlushCache(
int device)
889 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)))
890 res = sceAtaWaitResult();
896 int sceAtaIdle(
int device,
int period)
900 if (!(res = sceAtaExecCmd(NULL, 1, 0, period & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDLE)))
901 res = sceAtaWaitResult();
906 static int ata_device_identify(
int device,
void *
info)
910 if (!(res = sceAtaExecCmd(
info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDENTIFY_DEVICE)))
911 res = sceAtaWaitResult();
916 static int ata_device_pkt_identify(
int device,
void *
info)
920 res = sceAtaExecCmd(
info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDENTIFY_PACKET_DEVICE);
922 return sceAtaWaitResult();
927 int sceAtaGetSceId(
int device,
void *data)
931 if (!(res = sceAtaExecCmd(data, 1, ATA_SCE_IDENTIFY_DRIVE, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)))
932 res = sceAtaWaitResult();
937 static int ata_device_smart_enable(
int device)
941 if (!(res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_ENABLE_OPERATIONS, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART)))
942 res = sceAtaWaitResult();
948 int sceAtaSmartSaveAttr(
int device)
952 if (!(res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_SAVE_ATTRIBUTE_VALUES, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART)))
953 res = sceAtaWaitResult();
959 int sceAtaSmartReturnStatus(
int device)
964 res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_RETURN_STATUS, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART);
968 res = sceAtaWaitResult();
973 if (((ata_hwport->r_lcyl & 0xFF) != 0x4f) || ((ata_hwport->r_hcyl & 0xFF) != 0xc2)) {
974 M_PRINTF(
"Error: SMART report exceeded threshold.\n");
982 static int ata_device_set_transfer_mode(
int device,
int type,
int mode)
986 res = sceAtaExecCmd(NULL, 1, 3, (type | mode) & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SET_FEATURES);
990 res = sceAtaWaitResult();
996 #ifdef ATA_MWDMA_MODES
997 case ATA_XFER_MODE_MDMA:
998 ata_multiword_dma_mode(mode);
1001 case ATA_XFER_MODE_UDMA:
1002 ata_ultra_dma_mode(mode);
1004 case ATA_XFER_MODE_PIO:
1008 #ifdef ATA_USE_AIFDEV9
1009 case ATA_XFER_MODE_PIO:
1010 aif_tune_drive(0, mode);
1020 int sceAtaDmaTransfer(
int device,
void *buf, u32 lba, u32 nsectors,
int dir)
1022 return ata_device_sector_io64(device, buf, (u64)lba, nsectors, dir);
1025 int ata_device_sector_io64(
int device,
void *buf, u64 lba, u32 nsectors,
int dir)
1028 int res = 0, retries;
1029 u16 sector, lcyl, hcyl, select, command, len;
1032 while (res == 0 && nsectors > 0) {
1034 if (atad_devinfo[device].lba48 && (ata_dvrp_workaround ? (lba >= atad_devinfo[device].total_sectors) : 1)) {
1036 chunk = (nsectors > 65536) ? 65536 : nsectors;
1040 sector = ((lba >> 16) & 0xff00) | (lba & 0xff);
1041 lcyl = ((lba >> 24) & 0xff00) | ((lba >> 8) & 0xff);
1042 hcyl = ((lba >> 32) & 0xff00) | ((lba >> 16) & 0xff);
1045 select = (device << 4) & 0xffff;
1046 command = (dir == 1) ? ATA_C_WRITE_DMA_EXT : ATA_C_READ_DMA_EXT;
1049 chunk = (nsectors > 256) ? 256 : nsectors;
1051 sector = lba & 0xff;
1052 lcyl = (lba >> 8) & 0xff;
1053 hcyl = (lba >> 16) & 0xff;
1056 select = ((device << 4) | ((lba >> 24) & 0xf)) & 0xffff;
1057 command = (dir == 1) ? ATA_C_WRITE_DMA : ATA_C_READ_DMA;
1060 for (retries = 3; retries > 0; retries--) {
1062 #ifdef ATA_GAMESTAR_WORKAROUND
1064 if (ata_gamestar_workaround)
1069 if ((res = sceAtaExecCmd(buf, chunk, 0, len, sector, lcyl, hcyl, select, command)) != 0)
1073 #ifdef ATA_GAMESTAR_WORKAROUND
1074 if (!ata_gamestar_workaround)
1082 res = sceAtaWaitResult();
1085 SPD_REG16(SPD_R_IF_CTRL) &= ~SPD_IF_DMA_ENABLE;
1087 if (res != ATA_RES_ERR_ICRC)
1091 buf = (
void *)((u8 *)buf + chunk * 512);
1099 static void ata_get_security_status(
int device,
ata_devinfo_t *devinfo, u16 *param)
1101 if (ata_device_identify(device, param) == 0)
1106 int sceAtaSecuritySetPassword(
int device,
void *password)
1109 u16 *param = ata_param;
1112 if (devinfo[device].security_status & ATA_F_SEC_ENABLED)
1115 memset(param, 0, 512);
1116 memcpy(param + 1, password, 32);
1118 res = sceAtaExecCmd(param, 1, ATA_SCE_SECURITY_SET_PASSWORD, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL);
1120 res = sceAtaWaitResult();
1122 ata_get_security_status(device, devinfo, param);
1127 int sceAtaSecurityUnLock(
int device,
void *password)
1130 u16 *param = ata_param;
1133 if (!(devinfo[device].security_status & ATA_F_SEC_LOCKED))
1136 memset(param, 0, 512);
1137 memcpy(param + 1, password, 32);
1139 if ((res = sceAtaExecCmd(param, 1, ATA_SCE_SECURITY_UNLOCK, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)) != 0)
1141 if ((res = sceAtaWaitResult()) != 0)
1145 ata_get_security_status(device, devinfo, param);
1146 if (devinfo[device].security_status & ATA_F_SEC_LOCKED)
1147 return ATA_RES_ERR_LOCKED;
1153 int sceAtaSecurityEraseUnit(
int device)
1158 if (!(devinfo[device].security_status & ATA_F_SEC_ENABLED) || !(devinfo[device].security_status & ATA_F_SEC_LOCKED))
1162 if ((res = sceAtaExecCmd(NULL, 1, ATA_SCE_SECURITY_ERASE_PREPARE, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)) != 0)
1164 if ((res = sceAtaWaitResult()) != 0)
1167 if ((res = sceAtaExecCmd(NULL, 1, ATA_SCE_SECURITY_ERASE_UNIT, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SCE_SECURITY_CONTROL)) == 0)
1168 res = sceAtaWaitResult();
1171 ata_get_security_status(device, devinfo, NULL);
1180 #ifdef ATA_USE_AIFDEV9
1183 u16 nsector, sector, lcyl, hcyl;
1188 if (ata_hwport->r_control & 0x88)
1191 nsector = ata_hwport->r_nsector & 0xff;
1192 sector = ata_hwport->r_sector & 0xff;
1193 lcyl = ata_hwport->r_lcyl & 0xff;
1194 hcyl = ata_hwport->r_hcyl & 0xff;
1195 (void)ata_hwport->r_select;
1197 if ((nsector != 1) || (sector != 1))
1201 if ((lcyl == 0x00) && (hcyl == 0x00))
1203 else if ((lcyl == 0x14) && (hcyl == 0xeb))
1208 ata_hwport->r_lcyl = 0x55;
1209 ata_hwport->r_hcyl = 0xaa;
1210 lcyl = ata_hwport->r_lcyl & 0xff;
1211 hcyl = ata_hwport->r_hcyl & 0xff;
1213 if ((lcyl != 0x55) || (hcyl != 0xaa))
1222 #ifdef ATA_USE_AIFDEV9
1226 u32 total_sectors_nonlba48, total_sectors_lba48;
1229 if (!ata_dvrp_workaround) {
1230 for (i = 0; i < 2; i++) {
1231 if ((res = sceAtaSoftReset()) != 0)
1234 ata_device_select(i);
1235 if (ata_hwport->r_control & 0xff)
1236 ata_device_probe(&devinfo[i]);
1241 if ((res = sceAtaSoftReset()) != 0)
1244 ata_device_probe(&devinfo[0]);
1247 if (!devinfo[0].exists) {
1248 M_PRINTF(
"Error: Unable to detect HDD 0.\n");
1250 return ATA_RES_ERR_NODEV;
1253 if (ata_dvrp_workaround) {
1255 if ((res = ata_device_select(1)) != 0)
1257 if (ata_hwport->r_control & 0xff)
1258 ata_device_probe(&devinfo[1]);
1267 for (i = 0; i < 2; i++) {
1268 if (!devinfo[i].exists)
1273 if (!devinfo[i].has_packet) {
1274 res = ata_device_identify(i, ata_param);
1275 devinfo[i].
exists = (res == 0);
1276 }
else if (devinfo[i].has_packet == 1) {
1279 res = ata_device_pkt_identify(i, ata_param);
1280 devinfo[i].
exists = (res == 0);
1286 if (!devinfo[i].exists || devinfo[i].has_packet)
1292 devinfo[i].
lba48 = (ata_param[ATA_ID_COMMAND_SETS_SUPPORTED] & 0x0400) != 0;
1295 total_sectors_nonlba48 = (ata_param[ATA_ID_SECTOTAL_HI] << 16) | ata_param[ATA_ID_SECTOTAL_LO];
1296 if (ata_param[ATA_ID_48BIT_SECTOTAL_HI]) {
1297 total_sectors_lba48 = 0xffffffff;
1299 total_sectors_lba48 = (ata_param[ATA_ID_48BIT_SECTOTAL_MI] << 16) | ata_param[ATA_ID_48BIT_SECTOTAL_LO];
1306 #ifdef ATA_ENABLE_MAXUDMA
1313 for (
int j = maxUDMA; j >= 0; j--) {
1315 if (((ata_param[ATA_ID_UDMA_CONTROL] & 0xFF) & (1 << j)) != 0) {
1320 ata_device_set_transfer_mode(i, ATA_XFER_MODE_UDMA, udmaMode);
1322 #ifdef ATA_USE_AIFDEV9
1324 ata_device_set_transfer_mode(i, ATA_XFER_MODE_PIO, 4);
1326 ata_device_smart_enable(i);
1328 sceAtaIdle(i, 0xff);
1330 if (devinfo[i].lba48) {
1332 if (ata_dvrp_workaround) {
1336 if (ata_param[121] == 0x4456 &&
1337 ata_param[122] == 0x524c &&
1338 ata_param[123] == 0x4241 &&
1339 ata_param[124] == 0x3438) {
1340 M_PRINTF(
"LBA48-capable DVRP firmware detected, disabling the workaround\n");
1341 ata_dvrp_workaround = 0;
1356 #ifdef ATA_SCE_AUTH_HDD
1357 if (sceAtaGetSceId(i, ata_param) != 0) {
1358 M_PRINTF(
"error: This is not SCE genuine HDD.\n");
1359 memset(&devinfo[i], 0,
sizeof(devinfo[i]));
1363 #ifdef ATA_ENABLE_BDM
1365 bdm_connect_bd(&g_ata_bd[i]);
1374 if (!ata_devinfo_init) {
1375 ata_devinfo_init = 1;
1376 if (ata_bus_reset() || ata_init_devices(atad_devinfo))
1380 return &atad_devinfo[device];
1384 static void ata_set_dir(
int dir)
1389 SPD_REG16(0x38) = 3;
1390 val = SPD_REG16(SPD_R_IF_CTRL) & 1;
1391 val |= (dir == ATA_DIR_WRITE) ? 0x4c : 0x4e;
1392 SPD_REG16(SPD_R_IF_CTRL) = val;
1393 #ifdef ATA_GAMESTAR_WORKAROUND
1394 SPD_REG16(SPD_R_XFR_CTRL) = dir | (ata_gamestar_workaround ? 0x86 : 0x6);
1396 SPD_REG16(SPD_R_XFR_CTRL) = dir | 0x6;
1400 static void ata_pio_mode(
int mode)
1404 #ifdef ATA_ALL_PIO_MODES
1424 SPD_REG16(SPD_R_PIO_MODE) = val;
1427 SPD_REG16(SPD_R_PIO_MODE) = 0x92;
1431 #ifdef ATA_MWDMA_MODES
1432 static void ata_multiword_dma_mode(
int mode)
1448 SPD_REG16(SPD_R_MWDMA_MODE) = val;
1449 SPD_REG16(SPD_R_IF_CTRL) = (SPD_REG16(SPD_R_IF_CTRL) & 0xfffe) | 0x48;
1453 static void ata_ultra_dma_mode(
int mode)
1475 SPD_REG16(SPD_R_UDMA_MODE) = val;
1476 SPD_REG16(SPD_R_IF_CTRL) |= 0x49;
1480 #ifdef ATA_USE_AIFDEV9
1481 static void aif_tune_drive(
int unit,
int mode)
1484 unsigned int use_iordy, value;
1487 value = (use_iordy << 3) | mode;
1488 M_PRINTF(
"AIF HDD: tune unit%d, mode=%u\n", unit, value);
1492 aif_regs[AIF_ATA_TCFG] = (aif_regs[AIF_ATA_TCFG] & 0xf0) + value;
1495 aif_regs[AIF_ATA_TCFG] = (aif_regs[AIF_ATA_TCFG] & 0x0f) + (value << 4);
1502 int sceAtaIdleImmediate(
int device)
1506 if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xFFFF, ATA_C_IDLE_IMMEDIATE)))
1507 res = sceAtaWaitResult();
1512 static int ata_device_standby_immediate(
int device)
1516 if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xFFFF, ATA_C_STANDBY_IMMEDIATE)))
1517 res = sceAtaWaitResult();
1522 static void ata_shutdown_cb(
void)
1526 for (i = 0; i < 2; i++) {
1527 if (atad_devinfo[i].exists)
1528 ata_device_standby_immediate(i);
1532 #ifdef ATA_ENABLE_BDM
1536 static int ata_bd_read(
struct block_device *bd, u64 sector,
void *buffer, u16
count)
1538 if (ata_device_sector_io64(bd->devNr, buffer, sector,
count, ATA_DIR_READ) != 0) {
1545 static int ata_bd_write(
struct block_device *bd, u64 sector,
const void *buffer, u16
count)
1547 if (ata_device_sector_io64(bd->devNr, (
void *)buffer, sector,
count, ATA_DIR_WRITE) != 0) {
1556 sceAtaFlushCache(bd->devNr);
1561 ata_device_standby_immediate(bd->devNr);