PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
hdproatad.c
1/*
2 Copyright 2011, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4
5 ATA Driver for the HD Pro Kit, based on original & updated ATAD from ps2sdk:
6
7 Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
8 Licenced under Academic Free License version 2.0
9 Review ps2sdk README & LICENSE files for further details.
10
11 ATA device driver.
12*/
13
14#include <types.h>
15#include <defs.h>
16#include <irx.h>
17#include <loadcore.h>
18#include <intrman.h>
19#include <thbase.h>
20#include <thevent.h>
21#include <stdio.h>
22#include <sysclib.h>
23#include <atad.h>
24
25#include <atahw.h>
26
27#define MODNAME "hdcombo_driver"
28IRX_ID(MODNAME, 1, 1);
29
30#define M_PRINTF(format, args...) \
31 printf(MODNAME ": " format, ##args)
32
33#define BANNER "ATA device driver for HD Pro Kit %s\n"
34#define VERSION "v1.0"
35
36#define ATA_XFER_MODE_PIO 0x08
37
38#define ATA_EV_TIMEOUT 1
39#define ATA_EV_COMPLETE 2 // Unused as there is no completion interrupt
40
41// HD Pro Kit is mapping the 1st word in ROM0 seg as a main ATA controller,
42// The pseudo ATA controller registers are accessed (input/ouput) by writing
43// an id to the main ATA controller (id specific to HDpro, see registers id below).
44#define HDPROreg_IO8 (*(vu8 *)0xBFC00000)
45#define HDPROreg_IO32 (*(vu32 *)0xBFC00000)
46
47#define CDVDreg_STATUS (*(vu8 *)0xBF40200A)
48
49// Pseudo ATA controller registers id - Output
50#define ATAreg_CONTROL_RD 0x68
51#define ATAreg_SELECT_RD 0x70
52#define ATAreg_STATUS_RD 0xf0
53#define ATAreg_ERROR_RD 0x90
54#define ATAreg_NSECTOR_RD 0x50
55#define ATAreg_SECTOR_RD 0xd0
56#define ATAreg_LCYL_RD 0x30
57#define ATAreg_HCYL_RD 0xb0
58#define ATAreg_DATA_RD 0x41
59
60// Pseudo ATA controller registers id - Input
61#define ATAreg_CONTROL_WR 0x6a
62#define ATAreg_SELECT_WR 0x72
63#define ATAreg_COMMAND_WR 0xf2
64#define ATAreg_FEATURE_WR 0x92
65#define ATAreg_NSECTOR_WR 0x52
66#define ATAreg_SECTOR_WR 0xd2
67#define ATAreg_LCYL_WR 0x32
68#define ATAreg_HCYL_WR 0xb2
69#define ATAreg_DATA_WR 0x12
70
71static int ata_devinfo_init = 0;
72static int ata_evflg = -1;
73
74/* Local device info kept for drives 0 and 1. */
75static ata_devinfo_t atad_devinfo[2];
76
77/* Data returned from DEVICE IDENTIFY is kept here. Also, this is used by the
78 security commands to set and unlock the password. */
79static u16 ata_param[256];
80
81/* ATA command info. */
82typedef struct _ata_cmd_info
83{
84 u8 command;
85 u8 type;
87
88// DMA commands have been removed, since there is no support for DMA.
89static const ata_cmd_info_t ata_cmd_table[] = {
90 {ATA_C_NOP, 1},
91 {ATA_C_CFA_REQUEST_EXTENDED_ERROR_CODE, 1},
92 {ATA_C_DEVICE_RESET, 5},
93 {ATA_C_READ_SECTOR, 2},
94 {ATA_C_READ_SECTOR_EXT, 0x82},
95 {ATA_C_WRITE_SECTOR, 3},
96 {ATA_C_WRITE_LONG, 8},
97 {ATA_C_WRITE_SECTOR_EXT, 0x83},
98 {ATA_C_CFA_WRITE_SECTORS_WITHOUT_ERASE, 3},
99 {ATA_C_READ_VERIFY_SECTOR, 1},
100 {ATA_C_READ_VERIFY_SECTOR_EXT, 0x81},
101 {ATA_C_SEEK, 1},
102 {ATA_C_CFA_TRANSLATE_SECTOR, 2},
103 {ATA_C_SCE_SECURITY_CONTROL, 7},
104 {ATA_C_EXECUTE_DEVICE_DIAGNOSTIC, 6},
105 {ATA_C_INITIALIZE_DEVICE_PARAMETERS, 1},
106 {ATA_C_DOWNLOAD_MICROCODE, 3},
107 {ATA_C_IDENTIFY_PACKET_DEVICE, 2},
108 {ATA_C_SMART, 7},
109 {ATA_C_CFA_ERASE_SECTORS, 1},
110 {ATA_C_READ_MULTIPLE, 2},
111 {ATA_C_WRITE_MULTIPLE, 3},
112 {ATA_C_SET_MULTIPLE_MODE, 1},
113 {ATA_C_CFA_WRITE_MULTIPLE_WITHOUT_ERASE, 3},
114 {ATA_C_GET_MEDIA_STATUS, 1},
115 {ATA_C_MEDIA_LOCK, 1},
116 {ATA_C_MEDIA_UNLOCK, 1},
117 {ATA_C_STANDBY_IMMEDIATE, 1},
118 {ATA_C_IDLE_IMMEDIATE, 1},
119 {ATA_C_STANDBY, 1},
120 {ATA_C_IDLE, 1},
121 {ATA_C_READ_BUFFER, 2},
122 {ATA_C_CHECK_POWER_MODE, 1},
123 {ATA_C_SLEEP, 1},
124 {ATA_C_FLUSH_CACHE, 1},
125 {ATA_C_WRITE_BUFFER, 3},
126 {ATA_C_FLUSH_CACHE_EXT, 1},
127 {ATA_C_IDENTIFY_DEVICE, 2},
128 {ATA_C_MEDIA_EJECT, 1},
129 {ATA_C_SET_FEATURES, 1},
130 {ATA_C_SECURITY_SET_PASSWORD, 3},
131 {ATA_C_SECURITY_UNLOCK, 3},
132 {ATA_C_SECURITY_ERASE_PREPARE, 1},
133 {ATA_C_SECURITY_ERASE_UNIT, 3},
134 {ATA_C_SECURITY_FREEZE_LOCK, 1},
135 {ATA_C_SECURITY_DISABLE_PASSWORD, 3},
136 {ATA_C_READ_NATIVE_MAX_ADDRESS, 1},
137 {ATA_C_SET_MAX_ADDRESS, 1}};
138#define ATA_CMD_TABLE_SIZE (sizeof ata_cmd_table / sizeof(ata_cmd_info_t))
139
140static const ata_cmd_info_t smart_cmd_table[] = {
141 {ATA_S_SMART_READ_DATA, 2},
142 {ATA_S_SMART_ENABLE_DISABLE_AUTOSAVE, 1},
143 {ATA_S_SMART_SAVE_ATTRIBUTE_VALUES, 1},
144 {ATA_S_SMART_EXECUTE_OFF_LINE, 1},
145 {ATA_S_SMART_READ_LOG, 2},
146 {ATA_S_SMART_WRITE_LOG, 3},
147 {ATA_S_SMART_ENABLE_OPERATIONS, 1},
148 {ATA_S_SMART_DISABLE_OPERATIONS, 1},
149 {ATA_S_SMART_RETURN_STATUS, 1}};
150#define SMART_CMD_TABLE_SIZE (sizeof smart_cmd_table / sizeof(ata_cmd_info_t))
151
152/* This is the state info tracked between sceAtaExecCmd() and sceAtaWaitResult(). */
153typedef struct _ata_cmd_state
154{
155 s32 type; /* The ata_cmd_info_t type field. */
156 union
157 {
158 void *buf;
159 u8 *buf8;
160 u16 *buf16;
161 };
162 u32 blkcount; /* The number of 512-byte blocks (sectors) to transfer. */
164
165static ata_cmd_state_t atad_cmd_state;
166
167static int hdpro_io_active = 0;
168static int intr_suspended = 0;
169static int intr_state;
170
171static int hdpro_io_start(void);
172static int hdpro_io_finish(void);
173static void hdpro_io_write(u8 cmd, u16 val);
174static int hdpro_io_read(u8 cmd);
175static int ata_bus_reset(void);
176static int ata_init_devices(ata_devinfo_t *devinfo);
177static int gen_ata_wait_busy(int bits);
178
179extern struct irx_export_table _exp_atad;
180
181static unsigned int ata_alarm_cb(void *unused)
182{
183 (void)unused;
184
185 iSetEventFlag(ata_evflg, ATA_EV_TIMEOUT);
186 return 0;
187}
188
189static void suspend_intr(void)
190{
191 if (!intr_suspended) {
192 CpuSuspendIntr(&intr_state);
193
194 intr_suspended = 1;
195 }
196}
197
198static void resume_intr(void)
199{
200 if (intr_suspended) {
201 CpuResumeIntr(intr_state);
202
203 intr_suspended = 0;
204 }
205}
206
207static int ata_create_event_flag(void)
208{
210
211 event.attr = EA_SINGLE; // In v1.04, EA_MULTI was specified.
212 event.bits = 0;
213 return CreateEventFlag(&event);
214}
215
216int _start(int argc, char *argv[])
217{
218 int res = MODULE_NO_RESIDENT_END;
219
220 (void)argc;
221 (void)argv;
222
223 printf(BANNER, VERSION);
224
225 if (!hdpro_io_start()) {
226 M_PRINTF("Failed to detect HD Pro, exiting.\n");
227 goto out;
228 }
229
230 hdpro_io_finish();
231
232 if ((ata_evflg = ata_create_event_flag()) < 0) {
233 M_PRINTF("Couldn't create event flag, exiting.\n");
234 goto out;
235 }
236
237 if (RegisterLibraryEntries(&_exp_atad) != 0) {
238 M_PRINTF("Library is already registered, exiting.\n");
239 goto out;
240 }
241
242 res = MODULE_RESIDENT_END;
243 M_PRINTF("Driver loaded.\n");
244
245out:
246 return res;
247}
248
249int shutdown(void)
250{
251 return 0;
252}
253
254/* Export 8 */
255int sceAtaGetError(void)
256{
257 return hdpro_io_read(ATAreg_ERROR_RD) & 0xff;
258}
259
260#define ATA_WAIT_BUSY 0x80
261#define ATA_WAIT_BUSBUSY 0x88
262
263#define ata_wait_busy() gen_ata_wait_busy(ATA_WAIT_BUSY)
264#define ata_wait_bus_busy() gen_ata_wait_busy(ATA_WAIT_BUSBUSY)
265
266/* 0x80 for busy, 0x88 for bus busy.
267 In the original ATAD, the busy and bus-busy functions were separate, but similar. */
268static int gen_ata_wait_busy(int bits)
269{
270 int i, didx, delay;
271 int res = 0;
272
273 for (i = 0; i < 80; i++) {
274
275 hdpro_io_start();
276
277 u16 r_control = hdpro_io_read(ATAreg_CONTROL_RD);
278
279 hdpro_io_finish();
280
281 if (r_control == 0xffff) // Differs from the normal ATAD here.
282 return ATA_RES_ERR_TIMEOUT;
283
284 if (!(r_control & bits))
285 goto out;
286
287 didx = i / 10;
288 switch (didx) {
289 case 0:
290 continue;
291 case 1:
292 delay = 100;
293 break;
294 case 2:
295 delay = 1000;
296 break;
297 case 3:
298 delay = 10000;
299 break;
300 case 4:
301 delay = 100000;
302 break;
303 default:
304 delay = 1000000;
305 }
306
307 DelayThread(delay);
308 }
309
310 res = ATA_RES_ERR_TIMEOUT;
311 M_PRINTF("Timeout while waiting on busy (0x%02x).\n", bits);
312
313out:
314 hdpro_io_start();
315
316 return res;
317}
318
319// Must be called before any I/O is done with HDPro
320static int hdpro_io_start(void)
321{
322 if (hdpro_io_active)
323 return 0;
324
325 hdpro_io_active = 0;
326
327 suspend_intr();
328
329 // HD Pro IO start commands sequence
330 HDPROreg_IO8 = 0x72;
331 CDVDreg_STATUS = 0;
332 HDPROreg_IO8 = 0x34;
333 CDVDreg_STATUS = 0;
334 HDPROreg_IO8 = 0x61;
335 CDVDreg_STATUS = 0;
336 unsigned int res = HDPROreg_IO8;
337 CDVDreg_STATUS = 0;
338
339 resume_intr();
340
341 // check result
342 if ((res & 0xff) == 0xe7)
343 hdpro_io_active = 1;
344
345 return hdpro_io_active;
346}
347
348// Must be called after I/O is done with HDPro
349static int hdpro_io_finish(void)
350{
351 if (!hdpro_io_active)
352 return 0;
353
354 suspend_intr();
355
356 // HD Pro IO finish commands sequence
357 HDPROreg_IO8 = 0xf3;
358 CDVDreg_STATUS = 0;
359
360 resume_intr();
361
362 DelayThread(200);
363
364 if (HDPROreg_IO32 == 0x401a7800) // check the 1st in ROM0 seg get
365 hdpro_io_active = 0; // back to it's original state
366
367 return hdpro_io_active ^ 1;
368}
369
370static void hdpro_io_write(u8 cmd, u16 val)
371{
372 suspend_intr();
373
374 // IO write to HD Pro
375 HDPROreg_IO8 = cmd;
376 CDVDreg_STATUS = 0;
377 HDPROreg_IO8 = val;
378 CDVDreg_STATUS = 0;
379 HDPROreg_IO8 = (val & 0xffff) >> 8;
380 CDVDreg_STATUS = 0;
381
382 resume_intr();
383}
384
385static int hdpro_io_read(u8 cmd)
386{
387 suspend_intr();
388
389 // IO read from HD Pro
390 HDPROreg_IO8 = cmd;
391 CDVDreg_STATUS = 0;
392 unsigned int res0 = HDPROreg_IO8;
393 CDVDreg_STATUS = 0;
394 unsigned int res1 = HDPROreg_IO8;
395 CDVDreg_STATUS = 0;
396 res0 = (res0 & 0xff) | (res1 << 8);
397
398 resume_intr();
399
400 return res0 & 0xffff;
401}
402
403/* Reset the ATA controller/bus. */
404static int ata_bus_reset(void)
405{
406 suspend_intr();
407
408 // HD Pro IO initialization commands sequence
409 HDPROreg_IO8 = 0x13;
410 CDVDreg_STATUS = 0;
411 HDPROreg_IO8 = 0x00;
412 CDVDreg_STATUS = 0;
413
414 resume_intr();
415
416 DelayThread(100);
417
418 suspend_intr();
419
420 HDPROreg_IO8 = 0x13;
421 CDVDreg_STATUS = 0;
422 HDPROreg_IO8 = 0x01;
423 CDVDreg_STATUS = 0;
424
425 resume_intr();
426
427 DelayThread(3000);
428
429 return ata_wait_busy();
430}
431
432static int ata_device_select(int device)
433{
434 int res;
435
436 if ((res = ata_wait_bus_busy()) < 0)
437 return res;
438
439 /* If the device was already selected, nothing to do. */
440 if (((hdpro_io_read(ATAreg_SELECT_RD) >> 4) & 1) == device)
441 return 0;
442
443 /* Select the device. */
444 hdpro_io_write(ATAreg_SELECT_WR, (device & 1) << 4);
445 (void)(hdpro_io_read(ATAreg_CONTROL_RD));
446
447 return ata_wait_bus_busy();
448}
449
450/* Export 6 */
451int sceAtaExecCmd(void *buf, u32 blkcount, u16 feature, u16 nsector, u16 sector, u16 lcyl, u16 hcyl, u16 select, u16 command)
452{
453 iop_sys_clock_t cmd_timeout;
454 const ata_cmd_info_t *cmd_table;
455 int i, res, type, cmd_table_size;
456 int using_timeout, device = (select >> 4) & 1;
457 u8 searchcmd;
458
459 ClearEventFlag(ata_evflg, 0);
460
461 if (!atad_devinfo[device].exists)
462 return ATA_RES_ERR_NODEV;
463
464 if ((res = ata_device_select(device)) != 0)
465 return res;
466
467 /* For the SMART commands, we need to search on the subcommand
468 specified in the feature register. */
469 if (command == ATA_C_SMART) {
470 cmd_table = smart_cmd_table;
471 cmd_table_size = SMART_CMD_TABLE_SIZE;
472 searchcmd = feature;
473 } else {
474 cmd_table = ata_cmd_table;
475 cmd_table_size = ATA_CMD_TABLE_SIZE;
476 searchcmd = command & 0xff;
477 }
478
479 type = 0;
480 for (i = 0; i < cmd_table_size; i++) {
481 if (searchcmd == cmd_table[i].command) {
482 type = cmd_table[i].type;
483 break;
484 }
485 }
486
487 if (!(atad_cmd_state.type = type & 0x7F))
488 return ATA_RES_ERR_CMD;
489
490 atad_cmd_state.buf = buf;
491 atad_cmd_state.blkcount = blkcount;
492
493 /* Check that the device is ready if this the appropiate command. */
494 if (!(hdpro_io_read(ATAreg_CONTROL_RD) & 0x40)) {
495 switch (command) {
496 case ATA_C_DEVICE_RESET:
497 case ATA_C_EXECUTE_DEVICE_DIAGNOSTIC:
498 case ATA_C_INITIALIZE_DEVICE_PARAMETERS:
499 case ATA_C_PACKET:
500 case ATA_C_IDENTIFY_PACKET_DEVICE:
501 break;
502 default:
503 M_PRINTF("Error: Device %d is not ready.\n", device);
504 return ATA_RES_ERR_NOTREADY;
505 }
506 }
507
508 /* Does this command need a timeout? */
509 using_timeout = 0;
510 switch (type & 0x7F) {
511 case 1:
512 case 6:
513 using_timeout = 1;
514 break;
515 // Support for DMA commands (type = 4) is removed because HDPro cannot support DMA. The original HDPro driver still had code for it though.
516 }
517
518 if (using_timeout) {
519 cmd_timeout.lo = 0x41eb0000;
520 cmd_timeout.hi = 0;
521
522 if ((res = SetAlarm(&cmd_timeout, &ata_alarm_cb, NULL)) < 0)
523 return res;
524 }
525
526 /* Enable the command completion interrupt. */
527 suspend_intr();
528 HDPROreg_IO8 = 0x21;
529 CDVDreg_STATUS = 0;
530 (void)(HDPROreg_IO8);
531 CDVDreg_STATUS = 0;
532 resume_intr();
533
534 /* Finally! We send off the ATA command with arguments. */
535 hdpro_io_write(ATAreg_CONTROL_WR, (using_timeout == 0) << 1);
536
537 if (type & 0x80) { // For the sake of achieving improved performance, write the registers twice only if required!
538 /* 48-bit LBA requires writing to the address registers twice,
539 24 bits of the LBA address is written each time.
540 Writing to registers twice does not affect 28-bit LBA since
541 only the latest data stored in address registers is used. */
542 hdpro_io_write(ATAreg_FEATURE_WR, (feature & 0xffff) >> 8);
543 hdpro_io_write(ATAreg_NSECTOR_WR, (nsector & 0xffff) >> 8);
544 hdpro_io_write(ATAreg_SECTOR_WR, (sector & 0xffff) >> 8);
545 hdpro_io_write(ATAreg_LCYL_WR, (lcyl & 0xffff) >> 8);
546 hdpro_io_write(ATAreg_HCYL_WR, (hcyl & 0xffff) >> 8);
547 }
548
549 hdpro_io_write(ATAreg_FEATURE_WR, feature & 0xff);
550 hdpro_io_write(ATAreg_NSECTOR_WR, nsector & 0xff);
551 hdpro_io_write(ATAreg_SECTOR_WR, sector & 0xff);
552 hdpro_io_write(ATAreg_LCYL_WR, lcyl & 0xff);
553 hdpro_io_write(ATAreg_HCYL_WR, hcyl & 0xff);
554
555 hdpro_io_write(ATAreg_SELECT_WR, (select | ATA_SEL_LBA) & 0xff); // In v1.04, LBA was enabled in the sceAtaDmaTransfer function.
556 hdpro_io_write(ATAreg_COMMAND_WR, command & 0xff);
557
558 return 0;
559}
560
561/* Do a PIO transfer, to or from the device. */
562static int ata_pio_transfer(ata_cmd_state_t *cmd_state)
563{
564 u16 *buf16;
565 int i, type;
566 int res = 0, chk = 0;
567 u16 status = hdpro_io_read(ATAreg_STATUS_RD);
568
569 if (status & ATA_STAT_ERR) {
570 M_PRINTF("Error: Command error: status 0x%02x, error 0x%02x.\n", status, sceAtaGetError());
571 return ATA_RES_ERR_IO;
572 }
573
574 /* DRQ must be set (data request). */
575 if (!(status & ATA_STAT_DRQ))
576 return ATA_RES_ERR_NODATA;
577
578 type = cmd_state->type;
579
580 if (type == 3 || type == 8) {
581 /* PIO data out */
582 buf16 = cmd_state->buf16;
583
584 HDPROreg_IO8 = 0x43;
585 CDVDreg_STATUS = 0;
586
587 for (i = 0; i < 256; i++) {
588 u16 r_data = *buf16;
589 hdpro_io_write(ATAreg_DATA_WR, r_data);
590 chk ^= r_data + i;
591 cmd_state->buf = ++buf16;
592 }
593
594 u16 out = hdpro_io_read(ATAreg_DATA_RD) & 0xffff;
595 if (out != (chk & 0xffff))
596 return ATA_RES_ERR_IO;
597
598 if (cmd_state->type == 8) {
599 u8 *buf8;
600
601 buf8 = cmd_state->buf8;
602 for (i = 0; i < 4; i++) {
603 hdpro_io_write(ATAreg_DATA_WR, *buf8);
604 cmd_state->buf = ++buf8;
605 }
606 }
607
608 } else if (type == 2) {
609 /* PIO data in */
610 buf16 = cmd_state->buf16;
611
612 suspend_intr();
613
614 HDPROreg_IO8 = 0x53;
615 CDVDreg_STATUS = 0;
616 CDVDreg_STATUS = 0;
617
618 for (i = 0; i < 256; i++) {
619
620 unsigned int res0 = HDPROreg_IO8;
621 CDVDreg_STATUS = 0;
622 unsigned int res1 = HDPROreg_IO8;
623 CDVDreg_STATUS = 0;
624
625 res0 = (res0 & 0xff) | (res1 << 8);
626 chk ^= res0 + i;
627
628 *buf16 = res0 & 0xffff;
629 cmd_state->buf16 = ++buf16;
630 }
631
632 HDPROreg_IO8 = 0x51;
633 CDVDreg_STATUS = 0;
634 CDVDreg_STATUS = 0;
635
636 resume_intr();
637
638 u16 r_data = hdpro_io_read(ATAreg_DATA_RD) & 0xffff;
639 if (r_data != (chk & 0xffff))
640 return ATA_RES_ERR_IO;
641 }
642
643 return res;
644}
645
646/* Export 5 */
647int sceAtaSoftReset(void)
648{
649 if (hdpro_io_read(ATAreg_CONTROL_RD) & 0x80)
650 return ATA_RES_ERR_NOTREADY;
651
652 /* Disables device interrupt assertion and asserts SRST. */
653 hdpro_io_write(ATAreg_CONTROL_WR, 6);
654 DelayThread(100);
655
656 /* Disable ATA interrupts. */
657 hdpro_io_write(ATAreg_CONTROL_WR, 2);
658 DelayThread(3000);
659
660 return ata_wait_busy();
661}
662
663/* Export 11 */
664int sceAtaSecurityUnLock(int device, void *password)
665{ // Device can always be unlocked.
666 (void)device;
667 (void)password;
668 return 0;
669}
670
671static void ata_device_probe(ata_devinfo_t *devinfo)
672{
673 u16 nsector, lcyl, hcyl, sector;
674
675 devinfo->exists = 0;
676 devinfo->has_packet = 2;
677
678 if (hdpro_io_read(ATAreg_CONTROL_RD) & 0x88)
679 return;
680
681 nsector = hdpro_io_read(ATAreg_NSECTOR_RD) & 0xff;
682 sector = hdpro_io_read(ATAreg_SECTOR_RD) & 0xff;
683 lcyl = hdpro_io_read(ATAreg_LCYL_RD) & 0xff;
684 hcyl = hdpro_io_read(ATAreg_HCYL_RD) & 0xff;
685 (void)(hdpro_io_read(ATAreg_SELECT_RD) & 0xff);
686
687 /* The original HDPro driver did not check sector.
688 However, by the ATA-4 specification (9.1), sector should be 1.
689 So it should be perfectly fine to check. */
690 if ((nsector != 1) || (sector != 1))
691 return;
692 devinfo->exists = 1;
693
694 if ((lcyl == 0x00) && (hcyl == 0x00))
695 devinfo->has_packet = 0;
696 else if ((lcyl == 0x14) && (hcyl == 0xeb))
697 devinfo->has_packet = 1;
698
699 /* Seems to be for ensuring that there is a device connected.
700 Not sure why this has to be done, but is present in v2.4. */
701 hdpro_io_write(ATAreg_LCYL_WR, 0x55);
702 hdpro_io_write(ATAreg_HCYL_WR, 0xaa);
703 lcyl = hdpro_io_read(ATAreg_LCYL_RD) & 0xff;
704 hcyl = hdpro_io_read(ATAreg_HCYL_RD) & 0xff;
705
706 if ((lcyl != 0x55) || (hcyl != 0xaa))
707 devinfo->exists = 0;
708}
709
710/* Export 17 */
711int sceAtaFlushCache(int device)
712{
713 int res;
714
715 if (!hdpro_io_start())
716 return -1;
717
718 if (!(res = sceAtaExecCmd(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, atad_devinfo[device].lba48 ? ATA_C_FLUSH_CACHE_EXT : ATA_C_FLUSH_CACHE)))
719 res = sceAtaWaitResult();
720
721 if (!hdpro_io_finish())
722 return -2;
723
724 return res;
725}
726
727/* Export 13 */
728int ata_device_idle(int device, int period)
729{
730 int res;
731
732 res = sceAtaExecCmd(NULL, 1, 0, period & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDLE);
733 if (res)
734 return res;
735
736 return sceAtaWaitResult();
737}
738
739/* Set features - set transfer mode. */
740static int ata_device_set_transfer_mode(int device, int type, int mode)
741{
742 int res;
743
744 res = sceAtaExecCmd(NULL, 1, 3, (type | mode) & 0xff, 0, 0, 0, (device << 4) & 0xffff, ATA_C_SET_FEATURES);
745 if (res)
746 return res;
747
748 res = sceAtaWaitResult();
749 if (res)
750 return res;
751
752 return 0;
753}
754
755static int ata_device_identify(int device, void *info)
756{
757 int res;
758
759 res = sceAtaExecCmd(info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff, ATA_C_IDENTIFY_DEVICE);
760 if (res)
761 return res;
762
763 return sceAtaWaitResult();
764}
765
766static int ata_device_smart_enable(int device)
767{
768 int res;
769
770 if (!(res = sceAtaExecCmd(NULL, 1, ATA_S_SMART_ENABLE_OPERATIONS, 0, 0, 0x4f, 0xc2, (device << 4) & 0xffff, ATA_C_SMART)))
771 res = sceAtaWaitResult();
772
773 return res;
774}
775
776static int ata_init_devices(ata_devinfo_t *devinfo)
777{
778 int i, res;
779
780 if ((res = sceAtaSoftReset()) != 0)
781 return res;
782
783 ata_device_probe(&devinfo[0]);
784 if (!devinfo[0].exists) {
785 M_PRINTF("Error: Unable to detect HDD 0.\n");
786 devinfo[1].exists = 0;
787 return ATA_RES_ERR_NODEV; // Returns 0 in v1.04.
788 }
789
790 /* If there is a device 1, grab it's info too. */
791 if ((res = ata_device_select(1)) != 0)
792 return res;
793 if (hdpro_io_read(ATAreg_CONTROL_RD) & 0xff)
794 ata_device_probe(&devinfo[1]);
795 else
796 devinfo[1].exists = 0;
797
798 for (i = 0; i < 2; i++) {
799 if (!devinfo[i].exists)
800 continue;
801
802 /* Send the IDENTIFY DEVICE command. if it doesn't succeed
803 devinfo is disabled. */
804 if (!devinfo[i].has_packet) {
805 res = ata_device_identify(i, ata_param);
806 devinfo[i].exists = (res == 0);
807 } else if (devinfo[i].has_packet == 1) {
808 /* If it's a packet device, send the IDENTIFY PACKET
809 DEVICE command. */
810 /* Packet devices are not supported:
811
812 The original HDPro driver issues the IDENTIFY PACKET DEVICE command,
813 but does not export sceAtaExecCmd and sceAtaWaitResult.
814 This makes packet device support impossible. */
815 res = -1;
816 devinfo[i].exists = (res == 0);
817 }
818 /* Otherwise, do nothing if has_packet = 2. */
819
820 /* This next section is HDD-specific: if no device or it's a
821 packet (ATAPI) device, we're done. */
822 if (!devinfo[i].exists || devinfo[i].has_packet)
823 continue;
824
825 /* This section is to detect whether the HDD supports 48-bit LBA
826 (IDENITFY DEVICE bit 10 word 83) and get the total sectors from
827 either words(61:60) for 28-bit or words(103:100) for 48-bit. */
828 if (ata_param[ATA_ID_COMMAND_SETS_SUPPORTED] & 0x0400) {
829 atad_devinfo[i].lba48 = 1;
830 /* I don't think anyone would use a >2TB HDD but just in case. */
831 if (ata_param[ATA_ID_48BIT_SECTOTAL_HI]) {
832 devinfo[i].total_sectors = 0xffffffff;
833 } else {
834 devinfo[i].total_sectors =
835 (ata_param[ATA_ID_48BIT_SECTOTAL_MI] << 16) |
836 ata_param[ATA_ID_48BIT_SECTOTAL_LO];
837 }
838 } else {
839 atad_devinfo[i].lba48 = 0;
840 devinfo[i].total_sectors = (ata_param[ATA_ID_SECTOTAL_HI] << 16) |
841 ata_param[ATA_ID_SECTOTAL_LO];
842 }
843 devinfo[i].security_status = ata_param[ATA_ID_SECURITY_STATUS];
844
845 /* PIO mode 0 (flow control). */
846 ata_device_set_transfer_mode(i, ATA_XFER_MODE_PIO, 0);
847 ata_device_smart_enable(i);
848 /* Disable idle timeout. */
849 ata_device_idle(i, 0);
850 }
851 return 0;
852}
853
854/* Export 7 */
855int sceAtaWaitResult(void)
856{
857 ata_cmd_state_t *cmd_state = &atad_cmd_state;
858 u32 bits;
859 int res = 0, type = cmd_state->type;
860 u16 stat;
861
862 if (type == 1 || type == 6) { /* Non-data commands. */
863
864 // Unlike ATAD, poll until the device either completes its command or times out. There is no completion interrupt.
865 while (1) {
866 suspend_intr();
867
868 HDPROreg_IO8 = 0x21;
869 CDVDreg_STATUS = 0;
870 unsigned int ret = HDPROreg_IO8;
871 CDVDreg_STATUS = 0;
872
873 resume_intr();
874
875 if (((ret & 0xff) & 1) != 0) {
876 // Command completed.
877 break;
878 }
879
880 /* The original did not check on the return value of PollEventFlag,
881 but PollEventFlag does not seem to return the event flag's bits if the wait condition is not satisfied. */
882 if (PollEventFlag(ata_evflg, ATA_EV_TIMEOUT | ATA_EV_COMPLETE, WEF_CLEAR | WEF_OR, &bits) == 0) {
883 if (bits & ATA_EV_TIMEOUT) { /* Timeout. */
884 M_PRINTF("Error: ATA timeout on a non-data command.\n");
885 return ATA_RES_ERR_TIMEOUT;
886 }
887 }
888
889 DelayThread(500);
890 }
891
892 /* Support for DMA commands (type = 4) is removed because HDPro cannot support DMA.
893 The original would return ATA_RES_ERR_TIMEOUT for type = 4. */
894 } else { /* PIO transfers. */
895 stat = hdpro_io_read(ATAreg_CONTROL_RD);
896 if ((res = ata_wait_busy()) < 0)
897 goto finish;
898
899 /* Transfer each PIO data block. */
900 while ((int)(--cmd_state->blkcount) != -1) {
901 if ((res = ata_pio_transfer(cmd_state)) < 0)
902 goto finish;
903 if ((res = ata_wait_busy()) < 0)
904 goto finish;
905 }
906 }
907
908 if (res)
909 goto finish;
910
911 /* Wait until the device isn't busy. */
912 if (hdpro_io_read(ATAreg_STATUS_RD) & ATA_STAT_BUSY)
913 res = ata_wait_busy();
914 if ((stat = hdpro_io_read(ATAreg_STATUS_RD)) & ATA_STAT_ERR) {
915 M_PRINTF("Error: Command error: status 0x%02x, error 0x%02x.\n", stat, sceAtaGetError());
916 res = ATA_RES_ERR_IO;
917 }
918
919finish:
920 /* The command has completed (with an error or not), so clean things up. */
921 CancelAlarm(&ata_alarm_cb, NULL);
922
923 return res;
924}
925
926/* Export 9 */
927int sceAtaDmaTransfer(int device, void *buf, u32 lba, u32 nsectors, int dir)
928{
929 int res = 0;
930 u16 sector, lcyl, hcyl, select, command, len;
931
932 if (!hdpro_io_start())
933 return -1;
934
935 while (nsectors) {
936 len = (nsectors > 256) ? 256 : nsectors;
937
938 /* Variable lba is only 32 bits so no change for lcyl and hcyl. */
939 lcyl = (lba >> 8) & 0xff;
940 hcyl = (lba >> 16) & 0xff;
941
942 if (atad_devinfo[device].lba48) {
943 /* Setup for 48-bit LBA. */
944 /* Combine bits 24-31 and bits 0-7 of lba into sector. */
945 sector = ((lba >> 16) & 0xff00) | (lba & 0xff);
946 /* In v1.04, LBA was enabled here. */
947 select = (device << 4) & 0xffff;
948 command = (dir == 1) ? ATA_C_WRITE_SECTOR_EXT : ATA_C_READ_SECTOR_EXT;
949 } else {
950 /* Setup for 28-bit LBA. */
951 sector = lba & 0xff;
952 /* In v1.04, LBA was enabled here. */
953 select = ((device << 4) | ((lba >> 24) & 0xf)) & 0xffff;
954 command = (dir == 1) ? ATA_C_WRITE_SECTOR : ATA_C_READ_SECTOR;
955 }
956
957 // Unlike ATAD, retry indefinitely until the I/O operation succeeds.
958 if ((res = sceAtaExecCmd(buf, len, 0, len, sector, lcyl,
959 hcyl, select, command)) != 0)
960 continue;
961 if ((res = sceAtaWaitResult()) != 0)
962 continue;
963
964 buf = (void *)((u8 *)buf + len * 512);
965 lba += len;
966 nsectors -= len;
967 }
968
969 if (!hdpro_io_finish())
970 return -2;
971
972 return res;
973}
974
975/* Export 4 */
976ata_devinfo_t *sceAtaInit(int device)
977{
978 if (!ata_devinfo_init) {
979 ata_devinfo_init = 1;
980
981 if (!hdpro_io_start())
982 return NULL;
983
984 HDPROreg_IO8 = 0xe3;
985 CDVDreg_STATUS = 0;
986
987 if ((ata_bus_reset() != 0) || (ata_init_devices(atad_devinfo) != 0) || (!hdpro_io_finish()))
988 return NULL;
989 }
990
991 return &atad_devinfo[device];
992}
u32 security_status
Definition atad.h:35
u32 lba48
Definition atad.h:37
s32 exists
Definition atad.h:29
u32 total_sectors
Definition atad.h:33
s32 has_packet
Definition atad.h:31
int CpuResumeIntr(int state)
Definition intrman.c:227
int CpuSuspendIntr(int *state)
Definition intrman.c:205
#define EA_SINGLE
Definition thevent.h:33