Disabling auto-refresh of game list by default, as it is causing bugs sometimes
[open-ps2-loader.git] / modules / hdd / atad / atad.c
blob46acd66bca7b3e2504b4cce499b7bcde83d7d318
1 /*
2 # _____ ___ ____ ___ ____
3 # ____| | ____| | | |____|
4 # | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5 #-----------------------------------------------------------------------
6 # Copyright (c) 2003 Marcus R. Brown <mrbrown@0xd6.org>
7 # Licenced under Academic Free License version 2.0
8 # Review ps2sdk README & LICENSE files for further details.
10 # $Id: ps2atad.c 1455 2007-11-04 23:46:27Z roman_ps2dev $
11 # ATA device driver.
12 # This module provides the low-level ATA support for hard disk drives. It is
13 # 100% compatible with its proprietary counterpart called atad.irx.
15 # This module also include support for 48-bit feature set (done by Clement).
18 #include "types.h"
19 #include "defs.h"
20 #include "irx.h"
21 #include "loadcore.h"
22 #include "thbase.h"
23 #include "thevent.h"
24 #include "stdio.h"
25 #include "sysclib.h"
26 #include "dev9.h"
27 #include "atad.h"
29 #include "speedregs.h"
30 #include "atahw.h"
32 #define MODNAME "atad_driver"
33 IRX_ID(MODNAME, 1, 1);
35 #define M_PRINTF(format, args...) \
36 printf(MODNAME ": " format, ## args)
38 #define BANNER "ATA device driver %s - Copyright (c) 2003 Marcus R. Brown\n"
39 #define VERSION "v1.1"
41 static int ata_devinfo_init = 0;
42 static int ata_evflg = -1;
44 /* Used for indicating 48-bit LBA support. */
45 static int lba_48bit[2] = {0, 0};
47 /* This is true if this is a SCEI-modified HDD. */
48 static int is_sony_hdd[2] = {0, 0};
50 /* Local device info kept for drives 0 and 1. */
51 static ata_devinfo_t atad_devinfo[2];
53 /* Data returned from DEVICE IDENTIFY is kept here. Also, this is used by the
54 security commands to set and unlock the password. */
55 static u16 ata_param[256];
57 /* ATA command info. */
58 typedef struct _ata_cmd_info {
59 u8 command;
60 u8 type;
61 } ata_cmd_info_t;
63 static ata_cmd_info_t ata_cmd_table[] = {
64 {0,1},{3,1},{8,5},{0x20,2},{0x30,3},{0x32,8},{0x38,3},{0x40,1},{0x70,1},
65 {0x87,2},{0x8e,7},{0x90,6},{0x91,1},{0x92,3},{0xa1,2},{0xb0,7},{0xc0,1},
66 {0xc4,2},{0xc5,3},{0xc6,1},{0xc8,4},{0xca,4},{0xcd,3},{0xda,1},{0xde,1},
67 {0xdf,1},{0xe0,1},{0xe1,1},{0xe2,1},{0xe3,1},{0xe4,2},{0xe5,1},{0xe6,1},
68 {0xe7,1},{0xe8,3},{0xec,2},{0xed,1},{0xef,1},{0xf1,3},{0xf2,3},{0xf3,1},
69 {0xf4,3},{0xf5,1},{0xf6,3},{0xf8,1},{0xf9,1},{0x25,4},{0x35,4},{0xea,1}
71 #define ATA_CMD_TABLE_SIZE (sizeof ata_cmd_table/sizeof(ata_cmd_info_t))
73 static ata_cmd_info_t sec_ctrl_cmd_table[] = {
74 {0xec,2},{0xf3,1},{0xf4,1},{0xf5,1},{0xf1,3},{0xf2,3},{0x30,3},{0x20,2}
76 #define SEC_CTRL_CMD_TABLE_SIZE (sizeof sec_ctrl_cmd_table/sizeof(ata_cmd_info_t))
78 static ata_cmd_info_t smart_cmd_table[] = {
79 {0xd0,2},{0xd2,1},{0xd3,1},{0xd4,1},{0xd5,2},{0xd6,3},{0xd8,1},{0xd9,1},
80 {0xda,1}
82 #define SMART_CMD_TABLE_SIZE (sizeof smart_cmd_table/sizeof(ata_cmd_info_t))
84 /* This is the state info tracked between ata_io_start() and ata_io_finish(). */
85 typedef struct _ata_cmd_state {
86 int type; /* The ata_cmd_info_t type field. */
87 void *buf;
88 u32 blkcount; /* The number of 512-byte blocks (sectors) to transfer. */
89 int dir; /* DMA direction: 0 - to RAM, 1 - from RAM. */
90 } ata_cmd_state_t;
92 static ata_cmd_state_t atad_cmd_state;
94 static int ata_intr_cb(int flag);
95 static u32 ata_alarm_cb(void *unused);
97 static void ata_dma_set_dir(int dir);
99 static void ata_pio_mode(int mode);
100 static void ata_multiword_dma_mode(int mode);
101 static void ata_ultra_dma_mode(int mode);
103 struct irx_export_table _exp_atad;
105 int _start(int argc, char *argv[])
107 USE_SPD_REGS;
108 iop_event_t event;
109 int res = 1;
111 printf(BANNER, VERSION);
113 if (!(SPD_REG16(SPD_R_REV_3) & SPD_CAPS_ATA) || !(SPD_REG16(SPD_R_REV_8) & 0x02)) {
114 M_PRINTF("HDD is not connected, exiting.\n");
115 goto out;
118 if ((res = RegisterLibraryEntries(&_exp_atad)) != 0) {
119 M_PRINTF("Library is already registered, exiting.\n");
120 goto out;
123 event.attr = 0;
124 event.bits = 0;
125 if ((ata_evflg = CreateEventFlag(&event)) < 0) {
126 M_PRINTF("Couldn't create event flag, exiting.\n");
127 res = 1;
128 goto out;
131 ata_pio_mode(0);
133 dev9RegisterIntrCb(1, ata_intr_cb);
134 dev9RegisterIntrCb(0, ata_intr_cb);
136 res = 0;
137 M_PRINTF("Driver loaded.\n");
138 out:
139 return res;
142 int __attribute__((unused)) shutdown() { return 0; }
144 static int ata_intr_cb(int flag)
146 if (flag == 1) { /* New card, invalidate device info. */
147 memset(atad_devinfo, 0, sizeof atad_devinfo);
148 is_sony_hdd[0] = is_sony_hdd[1] = 0;
149 } else {
150 dev9IntrDisable(SPD_INTR_ATA);
151 iSetEventFlag(ata_evflg, 0x02);
154 return 1;
157 static u32 ata_alarm_cb(void *unused)
159 iSetEventFlag(ata_evflg, 0x01);
160 return 0;
163 /* Export 8 */
164 int ata_get_error()
166 USE_ATA_REGS;
167 return ata_hwport->r_error & 0xff;
170 /* 0x80 for busy, 0x88 for bus busy. */
171 static int ata_wait_busy(int bits)
173 USE_ATA_REGS;
174 int i, didx, delay;
176 for (i = 0; i < 80; i++) {
177 if (!(ata_hwport->r_control & bits))
178 return 0;
180 didx = i / 10;
181 switch (didx) {
182 case 0:
183 continue;
184 case 1:
185 delay = 100;
186 break;
187 case 2:
188 delay = 1000;
189 break;
190 case 3:
191 delay = 10000;
192 break;
193 case 4:
194 delay = 100000;
195 break;
196 default:
197 delay = 1000000;
200 DelayThread(delay);
203 M_PRINTF("Timeout while waiting on busy (0x%02x).\n", bits);
204 return -502;
207 static int ata_device_select(int device)
209 USE_ATA_REGS;
210 int res;
212 if ((res = ata_wait_busy(0x88)) < 0)
213 return res;
215 /* If the device was already selected, nothing to do. */
216 if (((ata_hwport->r_select >> 4) & 1) == device)
217 return 0;
219 /* Select the device. */
220 ata_hwport->r_select = (device & 1) << 4;
221 res = ata_hwport->r_control;
223 return ata_wait_busy(0x88);
226 /* Export 6 */
227 int ata_io_start(void *buf, u32 blkcount, u16 feature, u16 nsector, u16 sector,
228 u16 lcyl, u16 hcyl, u16 select, u16 command)
230 USE_ATA_REGS;
231 USE_SPD_REGS;
232 iop_sys_clock_t cmd_timeout;
233 ata_cmd_info_t *cmd_table;
234 int i, res, type, cmd_table_size;
235 int using_timeout, device = (select >> 4) & 1;
236 u8 searchcmd;
238 ClearEventFlag(ata_evflg, 0);
240 if (!atad_devinfo[device].exists)
241 return -505;
243 if ((res = ata_device_select(device)) != 0)
244 return res;
246 /* For the SCE and SMART commands, we need to search on the subcommand
247 specified in the feature register. */
248 if (command == ATA_C_SCE_SEC_CONTROL) {
249 cmd_table = sec_ctrl_cmd_table;
250 cmd_table_size = SEC_CTRL_CMD_TABLE_SIZE;
251 searchcmd = feature;
252 } else if (command == ATA_C_SMART) {
253 cmd_table = smart_cmd_table;
254 cmd_table_size = SMART_CMD_TABLE_SIZE;
255 searchcmd = feature;
256 } else {
257 cmd_table = ata_cmd_table;
258 cmd_table_size = ATA_CMD_TABLE_SIZE;
259 searchcmd = command & 0xff;
262 type = 0;
263 for (i = 0; i < cmd_table_size; i++) {
264 if (searchcmd == cmd_table[i].command) {
265 type = cmd_table[i].type;
266 break;
270 if (!(atad_cmd_state.type = type))
271 return -506;
273 atad_cmd_state.buf = buf;
274 atad_cmd_state.blkcount = blkcount;
276 /* Check that the device is ready if this the appropiate command. */
277 if (!(ata_hwport->r_control & 0x40)) {
278 switch (command) {
279 case 0x08:
280 case 0x90:
281 case 0x91:
282 case 0xa0:
283 case 0xa1:
284 break;
285 default:
286 M_PRINTF("Error: Device %d is not ready.\n", device);
287 return -501;
291 /* Does this command need a timeout? */
292 using_timeout = 0;
293 switch (type) {
294 case 1:
295 case 6:
296 using_timeout = 1;
297 break;
298 case 4:
299 /* Modified to include ATA_C_READ_DMA_EXT. */
300 atad_cmd_state.dir = ((command != 0xc8) && (command != 0x25));
301 using_timeout = 1;
304 if (using_timeout) {
305 cmd_timeout.lo = 0x41eb0000;
306 cmd_timeout.hi = 0;
308 /* SECURITY ERASE UNIT needs a bit more time. */
309 if ((command == 0xf4) || (command == 0x8e && feature == 0xf4))
310 USec2SysClock(180000000, &cmd_timeout);
312 if ((res = SetAlarm(&cmd_timeout, (void *)ata_alarm_cb, NULL)) < 0)
313 return res;
316 /* Enable the command completion interrupt. */
317 if (type == 1)
318 dev9IntrEnable(SPD_INTR_ATA0);
320 /* Finally! We send off the ATA command with arguments. */
321 ata_hwport->r_control = (using_timeout == 0) << 1;
323 /* 48-bit LBA requires writing to the address registers twice,
324 24 bits of the LBA address is written each time.
325 Writing to registers twice does not affect 28-bit LBA since
326 only the latest data stored in address registers is used. */
327 ata_hwport->r_feature = (feature >> 8) & 0xff;
328 ata_hwport->r_nsector = (nsector >> 8) & 0xff;
329 ata_hwport->r_sector = (sector >> 8) & 0xff;
330 ata_hwport->r_lcyl = (lcyl >> 8) & 0xff;
331 ata_hwport->r_hcyl = (hcyl >> 8) & 0xff;
333 ata_hwport->r_feature = feature & 0xff;
334 ata_hwport->r_nsector = nsector & 0xff;
335 ata_hwport->r_sector = sector & 0xff;
336 ata_hwport->r_lcyl = lcyl & 0xff;
337 ata_hwport->r_hcyl = hcyl & 0xff;
338 ata_hwport->r_select = select & 0xff;
339 ata_hwport->r_command = command & 0xff;
341 /* Turn on the LED. */
342 SPD_REG8(SPD_R_PIO_DIR) = 1;
343 SPD_REG8(SPD_R_PIO_DATA) = 0;
345 return 0;
348 /* Do a PIO transfer, to or from the device. */
349 static int ata_pio_transfer(ata_cmd_state_t *cmd_state)
351 USE_ATA_REGS;
352 void *buf;
353 int i, type;
354 u16 status = ata_hwport->r_status & 0xff;
356 if (status & ATA_STAT_ERR) {
357 M_PRINTF("Error: Command error: status 0x%02x, error 0x%02x.\n",
358 status, ata_get_error());
359 return -503;
362 /* DRQ must be set (data request). */
363 if (!(status & ATA_STAT_DRQ))
364 return -504;
366 type = cmd_state->type;
368 if (type == 3 || type == 8) {
369 /* PIO data out */
370 buf = cmd_state->buf;
371 for (i = 0; i < 256; i++) {
372 ata_hwport->r_data = *(u16 *)buf;
373 cmd_state->buf = ++((u16 *)buf);
375 if (cmd_state->type == 8) {
376 for (i = 0; i < 4; i++) {
377 ata_hwport->r_data = *(u8 *)buf;
378 cmd_state->buf = ++((u8 *)buf);
381 } else if (type == 2) {
382 /* PIO data in */
383 buf = cmd_state->buf;
384 for (i = 0; i < 256; i++) {
385 *(u16 *)buf = ata_hwport->r_data;
386 cmd_state->buf = ++((u16 *)buf);
390 return 0;
393 /* Complete a DMA transfer, to or from the device. */
394 static int ata_dma_complete(void *buf, int blkcount, int dir)
396 USE_ATA_REGS;
397 USE_SPD_REGS;
398 u32 bits, count, nbytes;
399 int i, res;
400 u16 dma_stat;
402 while (blkcount) {
403 for (i = 0; i < 20; i++)
404 if ((dma_stat = SPD_REG16(0x38) & 0x1f))
405 goto next_transfer;
407 if (dma_stat)
408 goto next_transfer;
410 dev9IntrEnable(SPD_INTR_ATA);
411 /* Wait for the previous transfer to complete or a timeout. */
412 WaitEventFlag(ata_evflg, 0x03, 0x11, &bits);
414 if (bits & 0x01) { /* Timeout. */
415 M_PRINTF("Error: DMA timeout.\n");
416 return -502;
418 /* No DMA completion bit? Spurious interrupt. */
419 if (!(SPD_REG16(SPD_R_INTR_STAT) & 0x02)) {
420 if (ata_hwport->r_control & 0x01) {
421 M_PRINTF("Error: Command error while doing DMA.\n");
422 M_PRINTF("Error: Command error status 0x%02x, error 0x%02x.\n",
423 ata_hwport->r_status, ata_get_error());
424 return -503;
425 } else {
426 M_PRINTF("Warning: Got command interrupt, but not an error.\n");
427 continue;
431 dma_stat = SPD_REG16(0x38) & 0x1f;
433 next_transfer:
434 count = (blkcount < dma_stat) ? blkcount : dma_stat;
435 nbytes = count * 512;
436 if ((res = dev9DmaTransfer(0, buf, (nbytes << 9)|32, dir)) < 0)
437 return res;
439 (u8 *)buf += nbytes;
440 blkcount -= count;
443 return 0;
446 /* Export 7 */
447 int ata_io_finish()
449 USE_SPD_REGS;
450 USE_ATA_REGS;
451 ata_cmd_state_t *cmd_state = &atad_cmd_state;
452 u32 bits;
453 int i, res = 0, type = cmd_state->type;
454 u16 stat;
456 if (type == 1 || type == 6) { /* Non-data commands. */
457 WaitEventFlag(ata_evflg, 0x03, 0x11, &bits);
458 if (bits & 0x01) { /* Timeout. */
459 M_PRINTF("Error: ATA timeout on a non-data command.\n");
460 return -502;
462 } else if (type == 4) { /* DMA. */
463 if ((res = ata_dma_complete(cmd_state->buf, cmd_state->blkcount,
464 cmd_state->dir)) < 0)
465 goto finish;
467 for (i = 0; i < 100; i++)
468 if ((stat = SPD_REG16(SPD_R_INTR_STAT) & 0x01))
469 break;
470 if (!stat) {
471 dev9IntrEnable(SPD_INTR_ATA0);
472 WaitEventFlag(ata_evflg, 0x03, 0x11, &bits);
473 if (bits & 0x01) {
474 M_PRINTF("Error: ATA timeout on DMA completion.\n");
475 res = -502;
478 } else { /* PIO transfers. */
479 stat = ata_hwport->r_control;
480 if ((res = ata_wait_busy(0x80)) < 0)
481 goto finish;
483 /* Transfer each PIO data block. */
484 while (--cmd_state->blkcount != -1) {
485 if ((res = ata_pio_transfer(cmd_state)) < 0)
486 goto finish;
487 if ((res = ata_wait_busy(0x80)) < 0)
488 goto finish;
492 if (res)
493 goto finish;
495 /* Wait until the device isn't busy. */
496 if (ata_hwport->r_status & ATA_STAT_BUSY)
497 res = ata_wait_busy(0x80);
498 if ((stat = ata_hwport->r_status) & ATA_STAT_ERR) {
499 M_PRINTF("Error: Command error: status 0x%02x, error 0x%02x.\n",
500 stat, ata_get_error());
501 res = -503;
504 finish:
505 /* The command has completed (with an error or not), so clean things up. */
506 CancelAlarm((void *)ata_alarm_cb, NULL);
507 /* Turn off the LED. */
508 SPD_REG8(SPD_R_PIO_DIR) = 1;
509 SPD_REG8(SPD_R_PIO_DATA) = 1;
511 return res;
514 /* Reset the ATA controller/bus. */
515 static int ata_bus_reset()
517 USE_SPD_REGS;
518 SPD_REG16(SPD_R_IF_CTRL) = SPD_IF_ATA_RESET;
519 DelayThread(100);
520 SPD_REG16(SPD_R_IF_CTRL) = 0x48;
521 DelayThread(3000);
522 return ata_wait_busy(0x80);
525 /* Export 5 */
526 /* Not sure if it's reset, but it disables ATA interrupts. */
527 int ata_reset_devices()
529 USE_ATA_REGS;
531 if (ata_hwport->r_control & 0x80)
532 return -501;
534 /* Dunno what this does. */
535 ata_hwport->r_control = 6;
536 DelayThread(100);
538 /* Disable ATA interrupts. */
539 ata_hwport->r_control = 2;
540 DelayThread(3000);
542 return ata_wait_busy(0x80);
545 /* Export 17 */
546 int ata_device_flush_cache(int device)
548 int res;
550 if (lba_48bit[device]) {
551 res = ata_io_start(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff,
552 ATA_C_FLUSH_CACHE_EXT);
553 } else {
554 res = ata_io_start(NULL, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff,
555 ATA_C_FLUSH_CACHE);
557 if (!res)
558 return ata_io_finish();
559 return res;
562 /* Export 13 */
563 int ata_device_idle(int device, int period)
565 int res;
567 res = ata_io_start(NULL, 1, 0, period & 0xff, 0, 0, 0,
568 (device << 4) & 0xffff, ATA_C_IDLE);
569 if (!res)
570 return ata_io_finish();
571 return res;
574 static int ata_device_identify(int device, void *info)
576 int res;
578 res = ata_io_start(info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff,
579 ATA_C_IDENTIFY_DEVICE);
580 if (!res)
581 return ata_io_finish();
582 return res;
585 static int ata_device_pkt_identify(int device, void *info)
587 int res;
589 res = ata_io_start(info, 1, 0, 0, 0, 0, 0, (device << 4) & 0xffff,
590 ATA_C_IDENTIFY_PKT_DEVICE);
591 if (!res)
592 return ata_io_finish();
593 return res;
596 /* Export 14 */
597 /* I assume 0xec is either init/identify. */
598 int ata_device_sce_security_init(int device, void *data)
600 int res;
602 res = ata_io_start(data, 1, 0xec, 0, 0, 0, 0,
603 (device << 4) & 0xffff, ATA_C_SCE_SEC_CONTROL);
604 if (!res)
605 return ata_io_finish();
606 return res;
609 static int ata_device_smart_enable(int device)
611 int res;
613 res = ata_io_start(NULL, 1, ATA_C_SMART_ENABLE, 0, 0, 0x4f, 0xc2,
614 (device << 4) & 0xffff, ATA_C_SMART);
615 if (!res)
616 return ata_io_finish();
617 return res;
620 /* Export 16 */
621 int ata_device_smart_save_attr(int device)
623 int res;
625 res = ata_io_start(NULL, 1, ATA_C_SMART_SAVE_ATTR, 0, 0, 0x4f, 0xc2,
626 (device << 4) & 0xffff, ATA_C_SMART);
627 if (!res)
628 return ata_io_finish();
629 return res;
632 /* Export 15 */
633 int ata_device_smart_get_status(int device)
635 USE_ATA_REGS;
636 int res;
638 res = ata_io_start(NULL, 1, ATA_C_SMART_GET_STATUS, 0, 0, 0x4f, 0xc2,
639 (device << 4) & 0xffff, ATA_C_SMART);
640 if (res)
641 return res;
643 res = ata_io_finish();
644 if (res)
645 return res;
647 /* Check to see if the report exceeded the threshold. */
648 if ((ata_hwport->r_lcyl != 0x4f) || (ata_hwport->r_hcyl != 0xc2)) {
649 M_PRINTF("Error: SMART report exceeded threshold.\n");
650 return 1;
653 return res;
656 /* Set features - set transfer mode. */
657 int ata_device_set_transfer_mode(int device, int type, int mode)
659 int res;
661 res = ata_io_start(NULL, 1, 3, (type|mode) & 0xff, 0, 0, 0,
662 (device << 4) & 0xffff, ATA_C_SET_FEATURES);
663 if (res)
664 return res;
666 res = ata_io_finish();
667 if (res)
668 return res;
670 if (type == 0x20) /* Multiword DMA. */
671 ata_multiword_dma_mode(mode);
672 else if (type == 0x40) /* Ultra DMA. */
673 ata_ultra_dma_mode(mode);
674 else if (type == 0x08) /* PIO (flow control). */
675 ata_pio_mode(mode);
677 return 0;
680 /* Export 9 */
681 int ata_device_dma_transfer(int device, void *buf, u32 lba, u32 nsectors, int dir)
683 int res = 0;
684 u32 nbytes;
685 u16 sector, lcyl, hcyl, select, command, len;
687 while (nsectors) {
688 len = (nsectors > 256) ? 256 : nsectors;
690 ata_dma_set_dir(dir);
692 /* Variable lba is only 32 bits so no change for lcyl and hcyl. */
693 lcyl = (lba >> 8) & 0xff;
694 hcyl = (lba >> 16) & 0xff;
696 if (lba_48bit[device]) {
697 /* Setup for 48-bit LBA. */
698 /* Combine bits 24-31 and bits 0-7 of lba into sector. */
699 sector = ((lba >> 16) & 0xff00) | (lba & 0xff);
700 /* 0x40 enables LBA. */
701 select = ((device << 4) | 0x40) & 0xffff;
702 command = (dir == 1) ? ATA_C_WRITE_DMA_EXT : ATA_C_READ_DMA_EXT;
703 } else {
704 /* Setup for 28-bit LBA. */
705 sector = lba & 0xff;
706 /* 0x40 enables LBA. */
707 select = ((device << 4) | ((lba >> 24) & 0xf) | 0x40) & 0xffff;
708 command = (dir == 1) ? ATA_C_WRITE_DMA : ATA_C_READ_DMA;
711 if ((res = ata_io_start(buf, len, 0, len, sector, lcyl,
712 hcyl, select, command)) != 0)
713 return res;
714 if ((res = ata_io_finish()) != 0)
715 return res;
717 nbytes = len * 512;
718 (u8 *)buf += nbytes;
719 lba += len;
720 nsectors -= len;
723 return res;
726 static inline void ata_get_security_status(int device, ata_devinfo_t *devinfo, u16 *param)
728 if (ata_device_identify(device, param) == 0)
729 devinfo[device].security_status = param[ATA_ID_SECURITY_STATUS];
732 /* Export 10 */
733 int ata_device_sec_set_password(int device, void *password)
735 ata_devinfo_t *devinfo = atad_devinfo;
736 u16 *param = ata_param;
737 int res;
738 u16 feature = 0, command = ATA_C_SEC_SET_PASSWORD;
740 if (devinfo[device].security_status & ATA_F_SEC_ENABLED)
741 return 0;
743 memset(param, 0, 512);
744 memcpy(param + 1, password, 32);
746 if (is_sony_hdd[device]) {
747 command = ATA_C_SCE_SEC_CONTROL;
748 feature = ATA_C_SEC_SET_PASSWORD;
751 res = ata_io_start(param, 1, feature, 0, 0, 0, 0,
752 (device << 4) & 0xffff, command);
753 if (res == 0)
754 res = ata_io_finish();
756 ata_get_security_status(device, devinfo, param);
757 return res;
760 /* Export 11 */
761 int ata_device_sec_unlock(int device, void *password)
763 ata_devinfo_t *devinfo = atad_devinfo;
764 u16 *param = ata_param;
765 int res;
766 u16 feature = 0, command = ATA_C_SEC_UNLOCK;
768 if (!(devinfo[device].security_status & ATA_F_SEC_LOCKED))
769 return 0;
771 memset(param, 0, 512);
772 memcpy(param + 1, password, 32);
774 if (is_sony_hdd[device]) {
775 command = ATA_C_SCE_SEC_CONTROL;
776 feature = ATA_C_SEC_UNLOCK;
779 if ((res = ata_io_start(param, 1, feature, 0, 0, 0, 0,
780 (device << 4) & 0xffff, command)) != 0)
781 return res;
782 if ((res = ata_io_finish()) != 0)
783 return res;
785 /* Check to see if the drive was actually unlocked. */
786 ata_get_security_status(device, devinfo, param);
787 if (devinfo[device].security_status & ATA_F_SEC_LOCKED)
788 return -509;
790 return 0;
793 /* Export 12 */
794 /* I hope this is handled correctly - Sony's atad doesn't send a password, but
795 I allow for one to conform to the ATA spec.
796 TODO: Make password a vararg. */
797 int ata_device_sec_erase(int device, void *password)
799 ata_devinfo_t *devinfo = atad_devinfo;
800 u16 *param = NULL;
801 int res;
802 u16 feature = 0, command = ATA_C_SEC_ERASE_PREPARE;
804 if (!(devinfo[device].security_status & ATA_F_SEC_ENABLED) ||
805 !(devinfo[device].security_status & ATA_F_SEC_LOCKED))
806 return 0;
808 /* First send the mandatory ERASE PREPARE command. */
809 if (is_sony_hdd[device]) {
810 command = ATA_C_SCE_SEC_CONTROL;
811 feature = ATA_C_SEC_ERASE_PREPARE;
814 if ((res = ata_io_start(NULL, 1, feature, 0, 0, 0, 0,
815 (device << 4) & 0xffff, command)) != 0)
816 goto finish;
817 if ((res = ata_io_finish()) != 0)
818 goto finish;
820 /* If this isn't a Sony HDD, then we will send the password. */
821 if (!is_sony_hdd[device]) {
822 if (password != NULL) {
823 param = ata_param;
824 memset(param, 0, 512);
825 memcpy(param + 1, password, 32);
827 command = ATA_C_SEC_ERASE_UNIT;
828 feature = 0;
829 } else {
830 command = ATA_C_SCE_SEC_CONTROL;
831 feature = ATA_C_SEC_ERASE_UNIT;
834 if ((res = ata_io_start(param, 1, feature, 0, 0, 0, 0,
835 (device << 4) & 0xffff, command)) == 0)
836 res = ata_io_finish();
838 finish:
839 ata_get_security_status(device, devinfo, param);
840 return res;
843 static void ata_device_probe(ata_devinfo_t *devinfo)
845 USE_ATA_REGS;
846 u16 nsector, sector, lcyl, hcyl, select;
848 devinfo->exists = 0;
849 devinfo->has_packet = 0;
851 if (ata_hwport->r_control & 0x88)
852 return;
854 nsector = ata_hwport->r_nsector & 0xff;
855 sector = ata_hwport->r_sector & 0xff;
856 lcyl = ata_hwport->r_lcyl & 0xff;
857 hcyl = ata_hwport->r_hcyl & 0xff;
858 select = ata_hwport->r_select;
860 if ((nsector != 1) || (sector != 1))
861 return;
862 devinfo->exists = 1;
864 if ((lcyl == 0x14) && (hcyl == 0xeb))
865 devinfo->has_packet = 1;
868 static int ata_init_devices(ata_devinfo_t *devinfo)
870 USE_ATA_REGS;
871 int i, res;
873 ata_reset_devices();
875 ata_device_probe(&devinfo[0]);
876 if (!devinfo[0].exists) {
877 M_PRINTF("Error: Unable to detect HDD 0.\n");
878 devinfo[1].exists = 0;
879 return 0;
882 /* If there is a device 1, grab it's info too. */
883 if ((res = ata_device_select(1)) != 0)
884 return res;
885 if (ata_hwport->r_control & 0xff)
886 ata_device_probe(&devinfo[1]);
887 else
888 devinfo[1].exists = 0;
890 for (i = 0; i < 2; i++) {
891 if (!devinfo[i].exists)
892 continue;
894 /* Send the IDENTIFY DEVICE command. if it doesn't succeed
895 devinfo is disabled. */
896 if (!devinfo[i].has_packet) {
897 res = ata_device_identify(i, ata_param);
898 devinfo[i].exists = (res == 0);
899 } else {
900 /* If it's a packet device, send the IDENTIFY PACKET
901 DEVICE command. */
902 res = ata_device_pkt_identify(i, ata_param);
903 devinfo[i].exists = (res == 0);
906 /* This next section is HDD-specific: if no device or it's a
907 packet (ATAPI) device, we're done. */
908 if (!devinfo[i].exists || devinfo[i].has_packet)
909 continue;
911 /* This section is to detect whether the HDD supports 48-bit LBA
912 (IDENITFY DEVICE bit 10 word 83) and get the total sectors from
913 either words(61:60) for 28-bit or words(103:100) for 48-bit. */
914 if (ata_param[ATA_ID_COMMAND_SETS_SUPPORTED] & 0x0400) {
915 lba_48bit[i] = 1;
916 /* I don't think anyone would use a >2TB HDD but just in case. */
917 if (ata_param[ATA_ID_48BIT_SECTOTAL_HI]) {
918 devinfo[i].total_sectors = 0xffffffff;
919 } else {
920 devinfo[i].total_sectors =
921 (ata_param[ATA_ID_48BIT_SECTOTAL_MI] << 16)|
922 ata_param[ATA_ID_48BIT_SECTOTAL_LO];
924 } else {
925 lba_48bit[i] = 0;
926 devinfo[i].total_sectors = (ata_param[ATA_ID_SECTOTAL_HI] << 16)|
927 ata_param[ATA_ID_SECTOTAL_LO];
929 devinfo[i].security_status = ata_param[ATA_ID_SECURITY_STATUS];
931 /* Ultra DMA mode 4. */
932 ata_device_set_transfer_mode(i, 0x40, 4);
933 ata_device_smart_enable(i);
934 /* Set idle timeout period to 21min 15s. */
935 ata_device_idle(i, 0xff);
938 return 0;
941 /* Export 4 */
942 ata_devinfo_t * ata_get_devinfo(int device)
944 if (ata_devinfo_init)
945 return &atad_devinfo[device];
947 if (ata_bus_reset() != 0)
948 return NULL;
950 if (ata_init_devices(atad_devinfo) != 0)
951 return NULL;
953 ata_devinfo_init = 1;
954 return &atad_devinfo[device];
957 static void ata_dma_set_dir(int dir)
959 USE_SPD_REGS;
960 u16 val;
962 SPD_REG16(0x38) = 3;
963 val = SPD_REG16(SPD_R_IF_CTRL) & 1;
964 val |= (dir == 1) ? 0x4c : 0x4e;
965 SPD_REG16(SPD_R_IF_CTRL) = val;
966 SPD_REG16(SPD_R_XFR_CTRL) = dir | 0x86;
969 static void ata_pio_mode(int mode)
971 USE_SPD_REGS;
972 u16 val = 0x92;
974 switch (mode) {
975 case 1:
976 val = 0x72;
977 break;
978 case 2:
979 val = 0x32;
980 break;
981 case 3:
982 val = 0x24;
983 break;
984 case 4:
985 val = 0x23;
986 break;
989 SPD_REG16(SPD_R_PIO_MODE) = val;
992 static void ata_multiword_dma_mode(int mode)
994 USE_SPD_REGS;
995 u16 val = 0xff;
997 if (mode == 1)
998 val = 0x45;
999 else if (mode == 2)
1000 val = 0x24;
1002 SPD_REG16(SPD_R_MWDMA_MODE) = val;
1003 SPD_REG16(SPD_R_IF_CTRL) = (SPD_REG16(SPD_R_IF_CTRL) & 0xfffe)|0x48;
1006 static void ata_ultra_dma_mode(int mode)
1008 USE_SPD_REGS;
1009 u16 val = 0xa7;
1011 switch (mode)
1013 case 1:
1014 val = 0x85;
1015 break;
1016 case 2:
1017 val = 0x63;
1018 break;
1019 case 3:
1020 val = 0x62;
1021 break;
1022 case 4:
1023 val = 0x61;
1024 break;
1027 SPD_REG16(SPD_R_UDMA_MODE) = val;
1028 SPD_REG16(SPD_R_IF_CTRL) |= 0x49;
1031 /* Export 18 */
1032 int ata_device_is_sce(int device)
1034 return is_sony_hdd[device];
1037 /* Export 19 */
1038 int ata_device_is_48bit(int device)
1040 return lba_48bit[device];