summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/drivers/ata.c5
-rw-r--r--firmware/drivers/ata_mmc.c280
-rw-r--r--firmware/export/config-ondiofm.h3
-rw-r--r--firmware/export/config-ondiosp.h4
4 files changed, 292 insertions, 0 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 05000b02a8..21d97aa939 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -30,6 +30,9 @@
30#include "string.h" 30#include "string.h"
31#include "hwcompat.h" 31#include "hwcompat.h"
32 32
33/* skip whole file for an MMC-based system, FIXME in makefile */
34#ifndef HAVE_MMC
35
33/* Uncomment the matching #define to use plain C code instead if the tweaked 36/* Uncomment the matching #define to use plain C code instead if the tweaked
34 * assembler code for disk reading or writing should cause problems. */ 37 * assembler code for disk reading or writing should cause problems. */
35/* #define PREFER_C_READING */ 38/* #define PREFER_C_READING */
@@ -1170,3 +1173,5 @@ int ata_init(void)
1170 1173
1171 return 0; 1174 return 0;
1172} 1175}
1176
1177#endif /* #ifndef HAVE_MMC */ \ No newline at end of file
diff --git a/firmware/drivers/ata_mmc.c b/firmware/drivers/ata_mmc.c
new file mode 100644
index 0000000000..a3669573e0
--- /dev/null
+++ b/firmware/drivers/ata_mmc.c
@@ -0,0 +1,280 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdbool.h>
20#include "ata.h"
21#include "kernel.h"
22#include "thread.h"
23#include "led.h"
24#include "sh7034.h"
25#include "system.h"
26#include "debug.h"
27#include "panic.h"
28#include "usb.h"
29#include "power.h"
30#include "string.h"
31#include "hwcompat.h"
32
33/* use file for an MMC-based system, FIXME in makefile */
34#ifdef HAVE_MMC
35
36#define SECTOR_SIZE 512
37#define Q_SLEEP 0
38
39/* for compatibility */
40bool old_recorder = false; /* FIXME: get rid of this cross-dependency */
41int ata_spinup_time = 0;
42static int sleep_timeout = 5*HZ;
43char ata_device = 0; /* device 0 (master) or 1 (slave) */
44int ata_io_address = 0; /* 0x300 or 0x200, only valid on recorder */
45static unsigned short identify_info[SECTOR_SIZE];
46
47static struct mutex ata_mtx;
48
49static bool sleeping = true;
50
51static char ata_stack[DEFAULT_STACK_SIZE];
52static const char ata_thread_name[] = "ata";
53static struct event_queue ata_queue;
54static bool initialized = false;
55static bool delayed_write = false;
56static unsigned char delayed_sector[SECTOR_SIZE];
57static int delayed_sector_num;
58
59static long last_user_activity = -1;
60long last_disk_activity = -1;
61
62
63int ata_read_sectors(unsigned long start,
64 int incount,
65 void* inbuf)
66{
67 int ret = 0;
68
69 mutex_lock(&ata_mtx);
70
71 last_disk_activity = current_tick;
72
73 led(true);
74 sleeping = false;
75
76 /* ToDo: action */
77 (void)start;
78 (void)incount;
79 (void)inbuf;
80
81 led(false);
82
83 mutex_unlock(&ata_mtx);
84
85 /* only flush if reading went ok */
86 if ( (ret == 0) && delayed_write )
87 ata_flush();
88
89 return ret;
90}
91
92
93
94int ata_write_sectors(unsigned long start,
95 int count,
96 const void* buf)
97{
98 int ret = 0;
99
100 if (start == 0)
101 panicf("Writing on sector 0\n");
102
103 mutex_lock(&ata_mtx);
104 sleeping = false;
105
106 last_disk_activity = current_tick;
107
108 led(true);
109
110 /* ToDo: action */
111 (void)start;
112 (void)count;
113 (void)buf;
114
115 led(false);
116
117 mutex_unlock(&ata_mtx);
118
119 /* only flush if writing went ok */
120 if ( (ret == 0) && delayed_write )
121 ata_flush();
122
123 return ret;
124}
125
126extern void ata_delayed_write(unsigned long sector, const void* buf)
127{
128 memcpy(delayed_sector, buf, SECTOR_SIZE);
129 delayed_sector_num = sector;
130 delayed_write = true;
131}
132
133extern void ata_flush(void)
134{
135 if ( delayed_write ) {
136 DEBUGF("ata_flush()\n");
137 delayed_write = false;
138 ata_write_sectors(delayed_sector_num, 1, delayed_sector);
139 }
140}
141
142void ata_spindown(int seconds)
143{
144 sleep_timeout = seconds * HZ;
145}
146
147bool ata_disk_is_active(void)
148{
149 return !sleeping;
150}
151
152static int ata_perform_sleep(void)
153{
154 int ret = 0;
155
156 mutex_lock(&ata_mtx);
157
158 /* ToDo: is there an equivalent? */
159
160 sleeping = true;
161 mutex_unlock(&ata_mtx);
162 return ret;
163}
164
165int ata_standby(int time)
166{
167 int ret = 0;
168
169 mutex_lock(&ata_mtx);
170
171 /* ToDo: is there an equivalent? */
172 (void)time;
173
174 mutex_unlock(&ata_mtx);
175 return ret;
176}
177
178int ata_sleep(void)
179{
180 queue_post(&ata_queue, Q_SLEEP, NULL);
181 return 0;
182}
183
184void ata_spin(void)
185{
186 last_user_activity = current_tick;
187}
188
189static void ata_thread(void)
190{
191 static long last_sleep = 0;
192 struct event ev;
193
194 while (1) {
195 while ( queue_empty( &ata_queue ) ) {
196 if ( sleep_timeout && !sleeping &&
197 TIME_AFTER( current_tick,
198 last_user_activity + sleep_timeout ) &&
199 TIME_AFTER( current_tick,
200 last_disk_activity + sleep_timeout ) )
201 {
202 ata_perform_sleep();
203 last_sleep = current_tick;
204 }
205
206 sleep(HZ/4);
207 }
208 queue_wait(&ata_queue, &ev);
209 switch ( ev.id ) {
210#ifndef USB_NONE
211 case SYS_USB_CONNECTED:
212 /* Tell the USB thread that we are safe */
213 DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
214 usb_acknowledge(SYS_USB_CONNECTED_ACK);
215
216 /* Wait until the USB cable is extracted again */
217 usb_wait_for_disconnect(&ata_queue);
218 break;
219#endif
220 case Q_SLEEP:
221 last_disk_activity = current_tick - sleep_timeout + (HZ/2);
222 break;
223 }
224 }
225}
226
227/* Hardware reset protocol as specified in chapter 9.1, ATA spec draft v5 */
228int ata_hard_reset(void)
229{
230 int ret = 0;
231
232 return ret;
233}
234
235int ata_soft_reset(void)
236{
237 int ret = 0;
238
239 return ret;
240}
241
242void ata_enable(bool on)
243{
244 (void)on;
245}
246
247unsigned short* ata_get_identify(void)
248{
249 return identify_info;
250}
251
252int ata_init(void)
253{
254 int rc = 0;
255
256 mutex_init(&ata_mtx);
257
258 led(false);
259
260 /* ToDo: Port setup */
261 // PAIOR |= 0x1680;
262
263
264 sleeping = false;
265 ata_enable(true);
266
267 if ( !initialized ) {
268
269 queue_init(&ata_queue);
270
271 last_disk_activity = current_tick;
272 create_thread(ata_thread, ata_stack,
273 sizeof(ata_stack), ata_thread_name);
274 initialized = true;
275 }
276
277 return rc;
278}
279
280#endif /* #ifdef HAVE_MMC */
diff --git a/firmware/export/config-ondiofm.h b/firmware/export/config-ondiofm.h
index 646deddb69..b7b557e1ec 100644
--- a/firmware/export/config-ondiofm.h
+++ b/firmware/export/config-ondiofm.h
@@ -61,3 +61,6 @@
61/* Define this for different ADC channel assignment */ 61/* Define this for different ADC channel assignment */
62#define HAVE_ONDIO_ADC 62#define HAVE_ONDIO_ADC
63 63
64/* Define this for MMC support instead of ATA harddisk */
65#define HAVE_MMC
66
diff --git a/firmware/export/config-ondiosp.h b/firmware/export/config-ondiosp.h
index 7e364f738c..4189448070 100644
--- a/firmware/export/config-ondiosp.h
+++ b/firmware/export/config-ondiosp.h
@@ -60,3 +60,7 @@
60 60
61/* Define this for different ADC channel assignment */ 61/* Define this for different ADC channel assignment */
62#define HAVE_ONDIO_ADC 62#define HAVE_ONDIO_ADC
63
64/* Define this for MMC support instead of ATA harddisk */
65#define HAVE_MMC
66