summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/drivers/ata.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 716af74ae2..95711c60ea 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -37,6 +37,7 @@
37#define ATA_CONTROL (*((volatile unsigned char*)0x06200306)) 37#define ATA_CONTROL (*((volatile unsigned char*)0x06200306))
38#define ATA_ALT_STATUS ATA_CONTROL 38#define ATA_ALT_STATUS ATA_CONTROL
39 39
40#define SELECT_DEVICE1 0x10
40#define SELECT_LBA 0x40 41#define SELECT_LBA 0x40
41 42
42#define STATUS_BSY 0x80 43#define STATUS_BSY 0x80
@@ -54,7 +55,8 @@
54#define CMD_SLEEP 0xE6 55#define CMD_SLEEP 0xE6
55#define CMD_SECURITY_FREEZE_LOCK 0xF5 56#define CMD_SECURITY_FREEZE_LOCK 0xF5
56 57
57struct mutex ata_mtx; 58static struct mutex ata_mtx;
59static char device; /* device 0 (master) or 1 (slave) */
58 60
59static int wait_for_bsy(void) 61static int wait_for_bsy(void)
60{ 62{
@@ -114,7 +116,7 @@ int ata_read_sectors(unsigned long start,
114 ATA_SECTOR = start & 0xff; 116 ATA_SECTOR = start & 0xff;
115 ATA_LCYL = (start >> 8) & 0xff; 117 ATA_LCYL = (start >> 8) & 0xff;
116 ATA_HCYL = (start >> 16) & 0xff; 118 ATA_HCYL = (start >> 16) & 0xff;
117 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA; 119 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | device;
118 ATA_COMMAND = CMD_READ_SECTORS; 120 ATA_COMMAND = CMD_READ_SECTORS;
119 121
120 for (i=0; i<count; i++) { 122 for (i=0; i<count; i++) {
@@ -164,7 +166,7 @@ int ata_write_sectors(unsigned long start,
164 ATA_SECTOR = start & 0xff; 166 ATA_SECTOR = start & 0xff;
165 ATA_LCYL = (start >> 8) & 0xff; 167 ATA_LCYL = (start >> 8) & 0xff;
166 ATA_HCYL = (start >> 16) & 0xff; 168 ATA_HCYL = (start >> 16) & 0xff;
167 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA; 169 ATA_SELECT = ((start >> 24) & 0xf) | SELECT_LBA | device;
168 ATA_COMMAND = CMD_WRITE_SECTORS; 170 ATA_COMMAND = CMD_WRITE_SECTORS;
169 171
170 for (i=0; i<count; i++) { 172 for (i=0; i<count; i++) {
@@ -289,7 +291,7 @@ int ata_soft_reset(void)
289 291
290 mutex_lock(&ata_mtx); 292 mutex_lock(&ata_mtx);
291 293
292 ATA_SELECT = SELECT_LBA; 294 ATA_SELECT = SELECT_LBA | device;
293 ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST; 295 ATA_CONTROL = CONTROL_nIEN|CONTROL_SRST;
294 sleep(HZ/20000); /* >= 5us */ 296 sleep(HZ/20000); /* >= 5us */
295 297
@@ -302,6 +304,27 @@ int ata_soft_reset(void)
302 return ret; 304 return ret;
303} 305}
304 306
307static int master_slave(void)
308{
309 /* master? */
310 ATA_SELECT = 0;
311 if ( ATA_STATUS & STATUS_RDY ) {
312 device = 0;
313 DEBUGF("Found master harddisk\n");
314 }
315 else {
316 /* slave? */
317 ATA_SELECT = SELECT_DEVICE1;
318 if ( ATA_STATUS & STATUS_RDY ) {
319 device = SELECT_DEVICE1;
320 DEBUGF("Found slave harddisk\n");
321 }
322 else
323 return -1;
324 }
325 return 0;
326}
327
305int ata_init(void) 328int ata_init(void)
306{ 329{
307 mutex_init(&ata_mtx); 330 mutex_init(&ata_mtx);
@@ -311,15 +334,21 @@ int ata_init(void)
311 /* activate ATA */ 334 /* activate ATA */
312 PADR &= ~0x80; 335 PADR &= ~0x80;
313 336
314 if (!ata_hard_reset()) 337 if (master_slave())
315 return -1; 338 return -1;
339
340 if (!ata_hard_reset())
341 return -2;
316 342
317 if (!check_registers()) 343 if (!check_registers())
318 return -2; 344 return -3;
319 345
320 if (freeze_lock() < 0) 346 if (freeze_lock() < 0)
321 return -4; 347 return -4;
322 348
349 if (ata_spindown(1) < 0)
350 return -5;
351
323 ATA_SELECT = SELECT_LBA; 352 ATA_SELECT = SELECT_LBA;
324 ATA_CONTROL = CONTROL_nIEN; 353 ATA_CONTROL = CONTROL_nIEN;
325 354