Rev 4263 | Go to most recent revision | 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 | * |