Subversion Repositories HelenOS

Rev

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
 *