Changeset 63b1537 in mainline for kernel/arch/sparc64/src/drivers/sgcn.c
- Timestamp:
- 2009-03-11T17:26:48Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- de88998
- Parents:
- 04d672c3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/src/drivers/sgcn.c
r04d672c3 r63b1537 35 35 */ 36 36 37 #include <arch.h> 37 38 #include <arch/drivers/sgcn.h> 38 39 #include <arch/drivers/kbd.h> … … 42 43 #include <print.h> 43 44 #include <mm/page.h> 44 #include <ipc/irq.h> 45 #include <ddi/ddi.h> 46 #include <ddi/device.h> 45 #include <proc/thread.h> 47 46 #include <console/chardev.h> 48 47 #include <console/console.h> 49 #include <ddi/device.h>50 48 #include <sysinfo/sysinfo.h> 51 49 #include <synch/spinlock.h> 50 51 #define POLL_INTERVAL 10000 52 52 53 53 /* … … 83 83 #define SGCN_BUFFER_MAGIC "CON" 84 84 85 /**86 * The driver is polling based, but in order to notify the userspace87 * of a key being pressed, we need to supply the interface with some88 * interrupt number. The interrupt number can be arbitrary as it it89 * will never be used for identifying HW interrupts, but only in90 * notifying the userspace.91 */92 #define FICTIONAL_INR 193 94 95 85 /* 96 86 * Returns a pointer to the object of a given type which is placed at the given … … 124 114 static uintptr_t sgcn_buffer_begin; 125 115 126 /** 127 * SGCN IRQ structure. So far used only for notifying the userspace of the 128 * key being pressed, not for kernel being informed about keyboard interrupts. 129 */ 130 static irq_t sgcn_irq; 131 132 // TODO think of a way how to synchronize accesses to SGCN buffer between the kernel and the userspace 116 /* true iff the kernel driver should ignore pressed keys */ 117 static bool kbd_disabled; 133 118 134 119 /* … … 309 294 310 295 /** 311 * The driver works in polled mode, so no interrupt should be handled by it.312 */313 static irq_ownership_t sgcn_claim(irq_t *irq)314 {315 return IRQ_DECLINE;316 }317 318 /**319 * The driver works in polled mode, so no interrupt should be handled by it.320 */321 static void sgcn_irq_handler(irq_t *irq)322 {323 panic("Not yet implemented, SGCN works in polled mode.");324 }325 326 /**327 296 * Grabs the input for kernel. 328 297 */ 329 298 void sgcn_grab(void) 330 299 { 331 ipl_t ipl = interrupts_disable(); 332 333 volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr); 334 volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); 335 336 /* skip all the user typed before the grab and hasn't been processed */ 337 spinlock_lock(&sgcn_input_lock); 338 *in_rdptr_ptr = *in_wrptr_ptr; 339 spinlock_unlock(&sgcn_input_lock); 340 341 spinlock_lock(&sgcn_irq.lock); 342 sgcn_irq.notif_cfg.notify = false; 343 spinlock_unlock(&sgcn_irq.lock); 344 345 interrupts_restore(ipl); 300 kbd_disabled = true; 346 301 } 347 302 … … 351 306 void sgcn_release(void) 352 307 { 353 ipl_t ipl = interrupts_disable(); 354 spinlock_lock(&sgcn_irq.lock); 355 if (sgcn_irq.notif_cfg.answerbox) 356 sgcn_irq.notif_cfg.notify = true; 357 spinlock_unlock(&sgcn_irq.lock); 358 interrupts_restore(ipl); 308 kbd_disabled = true; 359 309 } 360 310 … … 364 314 * and sends them to the upper layers of HelenOS. 365 315 */ 366 void sgcn_poll(void)316 static void sgcn_poll() 367 317 { 368 318 uint32_t begin = SGCN_BUFFER_HEADER->in_begin; 369 319 uint32_t end = SGCN_BUFFER_HEADER->in_end; 370 320 uint32_t size = end - begin; 371 321 372 322 spinlock_lock(&sgcn_input_lock); 373 323 374 324 ipl_t ipl = interrupts_disable(); 375 spinlock_lock(&sgcn_irq.lock); 325 326 if (kbd_disabled) { 327 interrupts_restore(ipl); 328 return; 329 } 376 330 377 331 /* we need pointers to volatile variables */ … … 381 335 volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr); 382 336 383 if (*in_rdptr_ptr != *in_wrptr_ptr) {384 /* XXX: send notification to userspace */385 }386 387 spinlock_unlock(&sgcn_irq.lock);388 interrupts_restore(ipl);389 390 337 while (*in_rdptr_ptr != *in_wrptr_ptr) { 391 338 … … 400 347 chardev_push_character(&sgcn_io, c); 401 348 } 402 349 350 interrupts_restore(ipl); 403 351 spinlock_unlock(&sgcn_input_lock); 352 } 353 354 /** 355 * Polling thread function. 356 */ 357 static void kkbdpoll(void *arg) { 358 while (1) { 359 if (!silent) { 360 sgcn_poll(); 361 } 362 thread_usleep(POLL_INTERVAL); 363 } 404 364 } 405 365 … … 414 374 kbd_type = KBD_SGCN; 415 375 416 devno_t devno = device_assign_devno();417 irq_initialize(&sgcn_irq);418 sgcn_irq.devno = devno;419 sgcn_irq.inr = FICTIONAL_INR;420 sgcn_irq.claim = sgcn_claim;421 sgcn_irq.handler = sgcn_irq_handler;422 irq_register(&sgcn_irq);423 424 376 sysinfo_set_item_val("kbd", NULL, true); 425 377 sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN); 426 sysinfo_set_item_val("kbd.devno", NULL, devno);427 sysinfo_set_item_val("kbd.inr", NULL, FICTIONAL_INR);428 378 sysinfo_set_item_val("fb.kind", NULL, 4); 379 380 thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); 381 if (!t) 382 panic("Cannot create kkbdpoll."); 383 thread_ready(t); 429 384 430 385 chardev_initialize("sgcn_io", &sgcn_io, &sgcn_ops);
Note:
See TracChangeset
for help on using the changeset viewer.