summaryrefslogtreecommitdiff
path: root/firmware/drivers/ata.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/ata.c')
-rw-r--r--firmware/drivers/ata.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 63bfc92e92..963929deb7 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -64,10 +64,10 @@
64static struct mutex ata_mtx; 64static struct mutex ata_mtx;
65char ata_device; /* device 0 (master) or 1 (slave) */ 65char ata_device; /* device 0 (master) or 1 (slave) */
66int ata_io_address; /* 0x300 or 0x200, only valid on recorder */ 66int ata_io_address; /* 0x300 or 0x200, only valid on recorder */
67
68static volatile unsigned char* ata_control; 67static volatile unsigned char* ata_control;
69 68
70bool old_recorder = false; 69bool old_recorder = false;
70static bool sleeping = false;
71 71
72static int wait_for_bsy(void) 72static int wait_for_bsy(void)
73{ 73{
@@ -113,6 +113,13 @@ int ata_read_sectors(unsigned long start,
113 int i; 113 int i;
114 int ret = 0; 114 int ret = 0;
115 115
116 if ( sleeping ) {
117 if (ata_soft_reset()) {
118 mutex_unlock(&ata_mtx);
119 return -1;
120 }
121 }
122
116 mutex_lock(&ata_mtx); 123 mutex_lock(&ata_mtx);
117 124
118 if (!wait_for_rdy()) 125 if (!wait_for_rdy())
@@ -164,6 +171,13 @@ int ata_write_sectors(unsigned long start,
164{ 171{
165 int i; 172 int i;
166 173
174 if ( sleeping ) {
175 if (ata_soft_reset()) {
176 mutex_unlock(&ata_mtx);
177 return -1;
178 }
179 }
180
167 mutex_lock(&ata_mtx); 181 mutex_lock(&ata_mtx);
168 182
169 if (!wait_for_rdy()) 183 if (!wait_for_rdy())
@@ -272,6 +286,28 @@ int ata_spindown(int time)
272 return ret; 286 return ret;
273} 287}
274 288
289int ata_sleep(void)
290{
291 int ret = 0;
292
293 mutex_lock(&ata_mtx);
294
295 if(!wait_for_rdy()) {
296 mutex_unlock(&ata_mtx);
297 return -1;
298 }
299
300 ATA_SELECT = ata_device;
301 ATA_COMMAND = CMD_SLEEP;
302
303 if (!wait_for_rdy())
304 ret = -1;
305
306 sleeping = true;
307 mutex_unlock(&ata_mtx);
308 return ret;
309}
310
275int ata_hard_reset(void) 311int ata_hard_reset(void)
276{ 312{
277 int ret; 313 int ret;
@@ -289,6 +325,7 @@ int ata_hard_reset(void)
289 /* Massage the return code so it is 0 on success and -1 on failure */ 325 /* Massage the return code so it is 0 on success and -1 on failure */
290 ret = ret?0:-1; 326 ret = ret?0:-1;
291 327
328 sleeping = false;
292 mutex_unlock(&ata_mtx); 329 mutex_unlock(&ata_mtx);
293 return ret; 330 return ret;
294} 331}
@@ -316,7 +353,8 @@ int ata_soft_reset(void)
316 353
317 /* Massage the return code so it is 0 on success and -1 on failure */ 354 /* Massage the return code so it is 0 on success and -1 on failure */
318 ret = ret?0:-1; 355 ret = ret?0:-1;
319 356
357 sleeping = false;
320 mutex_unlock(&ata_mtx); 358 mutex_unlock(&ata_mtx);
321 return ret; 359 return ret;
322} 360}