diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/ata.c | 42 | ||||
-rw-r--r-- | firmware/drivers/ata.h | 1 |
2 files changed, 41 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 @@ | |||
64 | static struct mutex ata_mtx; | 64 | static struct mutex ata_mtx; |
65 | char ata_device; /* device 0 (master) or 1 (slave) */ | 65 | char ata_device; /* device 0 (master) or 1 (slave) */ |
66 | int ata_io_address; /* 0x300 or 0x200, only valid on recorder */ | 66 | int ata_io_address; /* 0x300 or 0x200, only valid on recorder */ |
67 | |||
68 | static volatile unsigned char* ata_control; | 67 | static volatile unsigned char* ata_control; |
69 | 68 | ||
70 | bool old_recorder = false; | 69 | bool old_recorder = false; |
70 | static bool sleeping = false; | ||
71 | 71 | ||
72 | static int wait_for_bsy(void) | 72 | static 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 | ||
289 | int 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 | |||
275 | int ata_hard_reset(void) | 311 | int 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 | } |
diff --git a/firmware/drivers/ata.h b/firmware/drivers/ata.h index fb25f711d7..23dd1fac58 100644 --- a/firmware/drivers/ata.h +++ b/firmware/drivers/ata.h | |||
@@ -34,6 +34,7 @@ | |||
34 | */ | 34 | */ |
35 | extern void ata_enable(bool on); | 35 | extern void ata_enable(bool on); |
36 | extern int ata_spindown(int time); | 36 | extern int ata_spindown(int time); |
37 | extern int ata_sleep(void); | ||
37 | extern int ata_hard_reset(void); | 38 | extern int ata_hard_reset(void); |
38 | extern int ata_soft_reset(void); | 39 | extern int ata_soft_reset(void); |
39 | extern int ata_init(void); | 40 | extern int ata_init(void); |