Rev 4263 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 4263 | Rev 4327 | ||
|---|---|---|---|
| Line 128... | Line 128... | ||
| 128 | return code; |
128 | return code; |
| 129 | } |
129 | } |
| 130 | 130 | ||
| 131 | /** Register an answerbox as a receiving end for IRQ notifications. |
131 | /** Register an answerbox as a receiving end for IRQ notifications. |
| 132 | * |
132 | * |
| 133 | * @param box Receiving answerbox. |
133 | * @param box Receiving answerbox. |
| 134 | * @param inr IRQ number. |
134 | * @param inr IRQ number. |
| 135 | * @param devno Device number. |
135 | * @param devno Device number. |
| 136 | * @param method Method to be associated with the notification. |
136 | * @param method Method to be associated with the notification. |
| 137 | * @param ucode Uspace pointer to top-half pseudocode. |
137 | * @param ucode Uspace pointer to top-half pseudocode. |
| - | 138 | * |
|
| - | 139 | * @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
|
| 138 | * |
140 | * |
| 139 | * @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success. |
- | |
| 140 | */ |
141 | */ |
| 141 | int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, |
142 | int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, |
| 142 | unative_t method, irq_code_t *ucode) |
143 | unative_t method, irq_code_t *ucode) |
| 143 | { |
144 | { |
| 144 | ipl_t ipl; |
145 | ipl_t ipl; |
| Line 147... | Line 148... | ||
| 147 | link_t *hlp; |
148 | link_t *hlp; |
| 148 | unative_t key[] = { |
149 | unative_t key[] = { |
| 149 | (unative_t) inr, |
150 | (unative_t) inr, |
| 150 | (unative_t) devno |
151 | (unative_t) devno |
| 151 | }; |
152 | }; |
| 152 | 153 | ||
| 153 | if (ucode) { |
154 | if (ucode) { |
| 154 | code = code_from_uspace(ucode); |
155 | code = code_from_uspace(ucode); |
| 155 | if (!code) |
156 | if (!code) |
| 156 | return EBADMEM; |
157 | return EBADMEM; |
| 157 | } else { |
158 | } else { |
| 158 | code = NULL; |
159 | code = NULL; |
| 159 | } |
160 | } |
| 160 | 161 | ||
| 161 | /* |
162 | /* |
| 162 | * Allocate and populate the IRQ structure. |
163 | * Allocate and populate the IRQ structure. |
| 163 | */ |
164 | */ |
| 164 | irq = malloc(sizeof(irq_t), 0); |
165 | irq = malloc(sizeof(irq_t), 0); |
| 165 | irq_initialize(irq); |
166 | irq_initialize(irq); |
| Line 170... | Line 171... | ||
| 170 | irq->notif_cfg.notify = true; |
171 | irq->notif_cfg.notify = true; |
| 171 | irq->notif_cfg.answerbox = box; |
172 | irq->notif_cfg.answerbox = box; |
| 172 | irq->notif_cfg.method = method; |
173 | irq->notif_cfg.method = method; |
| 173 | irq->notif_cfg.code = code; |
174 | irq->notif_cfg.code = code; |
| 174 | irq->notif_cfg.counter = 0; |
175 | irq->notif_cfg.counter = 0; |
| 175 | 176 | ||
| 176 | /* |
177 | /* |
| 177 | * Enlist the IRQ structure in the uspace IRQ hash table and the |
178 | * Enlist the IRQ structure in the uspace IRQ hash table and the |
| 178 | * answerbox's list. |
179 | * answerbox's list. |
| 179 | */ |
180 | */ |
| 180 | ipl = interrupts_disable(); |
181 | ipl = interrupts_disable(); |
| 181 | spinlock_lock(&irq_uspace_hash_table_lock); |
182 | spinlock_lock(&irq_uspace_hash_table_lock); |
| 182 | hlp = hash_table_find(&irq_uspace_hash_table, key); |
183 | hlp = hash_table_find(&irq_uspace_hash_table, key); |
| 183 | if (hlp) { |
184 | if (hlp) { |
| - | 185 | irq_t *hirq __attribute__((unused)) |
|
| 184 | irq_t *hirq = hash_table_get_instance(hlp, irq_t, link); |
186 | = hash_table_get_instance(hlp, irq_t, link); |
| - | 187 | ||
| 185 | /* hirq is locked */ |
188 | /* hirq is locked */ |
| 186 | spinlock_unlock(&hirq->lock); |
189 | spinlock_unlock(&hirq->lock); |
| 187 | code_free(code); |
190 | code_free(code); |
| 188 | spinlock_unlock(&irq_uspace_hash_table_lock); |
191 | spinlock_unlock(&irq_uspace_hash_table_lock); |
| 189 | free(irq); |
192 | free(irq); |
| 190 | interrupts_restore(ipl); |
193 | interrupts_restore(ipl); |
| 191 | return EEXISTS; |
194 | return EEXISTS; |
| 192 | } |
195 | } |
| - | 196 | ||
| 193 | spinlock_lock(&irq->lock); /* not really necessary, but paranoid */ |
197 | spinlock_lock(&irq->lock); /* Not really necessary, but paranoid */ |
| 194 | spinlock_lock(&box->irq_lock); |
198 | spinlock_lock(&box->irq_lock); |
| 195 | hash_table_insert(&irq_uspace_hash_table, key, &irq->link); |
199 | hash_table_insert(&irq_uspace_hash_table, key, &irq->link); |
| 196 | list_append(&irq->notif_cfg.link, &box->irq_head); |
200 | list_append(&irq->notif_cfg.link, &box->irq_head); |
| 197 | spinlock_unlock(&box->irq_lock); |
201 | spinlock_unlock(&box->irq_lock); |
| 198 | spinlock_unlock(&irq->lock); |
202 | spinlock_unlock(&irq->lock); |
| 199 | spinlock_unlock(&irq_uspace_hash_table_lock); |
203 | spinlock_unlock(&irq_uspace_hash_table_lock); |
| 200 | 204 | ||
| 201 | interrupts_restore(ipl); |
205 | interrupts_restore(ipl); |
| 202 | // explicitly enable irq |
206 | // explicitly enable irq |
| 203 | /* different byteorder? |
- | |
| 204 | * trap_virtual_enable_irqs( 1 << ( irq->inr - 1 )); |
- | |
| 205 | */ |
- | |
| 206 | trap_virtual_enable_irqs( 1 << ( irq->inr + 7 )); |
207 | trap_virtual_enable_irqs( 1 << irq->inr ); |
| 207 | return EOK; |
208 | return EOK; |
| 208 | } |
209 | } |
| 209 | 210 | ||
| 210 | /** Unregister task from IRQ notification. |
211 | /** Unregister task from IRQ notification. |
| 211 | * |
212 | * |