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.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index 56b303da8d..681160cf01 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -66,6 +66,74 @@
66#define ATA_POWER_OFF_TIMEOUT 2*HZ 66#define ATA_POWER_OFF_TIMEOUT 2*HZ
67#endif 67#endif
68 68
69#ifdef MAX_PHYS_SECTOR_SIZE
70/* Hack - what's the deal with 5g? */
71struct ata_lock
72{
73 struct thread_entry *thread;
74 int count;
75 volatile unsigned char locked;
76 IF_COP( struct corelock cl; )
77};
78
79static void ata_lock_init(struct ata_lock *l)
80{
81 corelock_init(&l->cl);
82 l->locked = 0;
83 l->count = 0;
84 l->thread = NULL;
85}
86
87static void ata_lock_lock(struct ata_lock *l)
88{
89 struct thread_entry * const current = thread_get_current();
90
91 if (current == l->thread)
92 {
93 l->count++;
94 return;
95 }
96
97 corelock_lock(&l->cl);
98
99 IF_PRIO( current->skip_count = -1; )
100
101 while (l->locked != 0)
102 {
103 corelock_unlock(&l->cl);
104 switch_thread();
105 corelock_lock(&l->cl);
106 }
107
108 l->locked = 1;
109 l->thread = current;
110 corelock_unlock(&l->cl);
111}
112
113static void ata_lock_unlock(struct ata_lock *l)
114{
115 if (l->count > 0)
116 {
117 l->count--;
118 return;
119 }
120
121 corelock_lock(&l->cl);
122
123 IF_PRIO( l->thread->skip_count = 0; )
124
125 l->thread = NULL;
126 l->locked = 0;
127
128 corelock_unlock(&l->cl);
129}
130
131#define mutex ata_lock
132#define mutex_init ata_lock_init
133#define mutex_lock ata_lock_lock
134#define mutex_unlock ata_lock_unlock
135#endif /* MAX_PHYS_SECTOR_SIZE */
136
69static struct mutex ata_mtx NOCACHEBSS_ATTR; 137static struct mutex ata_mtx NOCACHEBSS_ATTR;
70int ata_device; /* device 0 (master) or 1 (slave) */ 138int ata_device; /* device 0 (master) or 1 (slave) */
71 139