Changeset b1f44b4 in mainline
- Timestamp:
- 2011-12-25T19:51:11Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a8f7029
- Parents:
- 5960b48
- Location:
- uspace/drv/char/i8042
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/char/i8042/i8042.c
r5960b48 rb1f44b4 38 38 39 39 #include <ddi.h> 40 #include <devman.h> 41 #include <device/hw_res.h> 40 42 #include <libarch/ddi.h> 41 43 #include <loc.h> … … 52 54 53 55 #define NAME "i8042" 54 #define NAMESPACE "char"55 56 56 57 /* Interesting bits for status register */ … … 97 98 }; 98 99 99 static i8042_t device;100 101 100 static void wait_ready(i8042_t *dev) 102 101 { … … 105 104 } 106 105 107 static void i8042_irq_handler(ddf_dev_t *dev, 108 ipc_callid_t iid, ipc_call_t *call); 109 static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg); 110 static void i8042_port_write(i8042_t *dev, int devid, uint8_t data); 111 106 static void i8042_irq_handler( 107 ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 108 { 109 110 const int status = IPC_GET_ARG1(*call); 111 const int data = IPC_GET_ARG2(*call); 112 const int devid = (status & i8042_AUX_DATA) ? DEVID_AUX : DEVID_PRI; 113 ddf_msg(LVL_WARN, "Unhandled %s data: %x , status: %x.", 114 (devid == DEVID_AUX) ? "AUX" : "PRIMARY", data, status); 115 #if 0 116 if (!dev || !dev->driver_data) 117 return; 118 119 if (device.port[devid].client_sess != NULL) { 120 async_exch_t *exch = 121 async_exchange_begin(device.port[devid].client_sess); 122 if (exch) { 123 async_msg_1(exch, IPC_FIRST_USER_METHOD, data); 124 async_exchange_end(exch); 125 } 126 } else { 127 ddf_msg(LVL_WARN, "No client session.\n"); 128 } 129 #endif 130 } 131 /*----------------------------------------------------------------------------*/ 112 132 int i8042_init(i8042_t *dev, void *regs, size_t reg_size, int irq_kbd, 113 133 int irq_mouse, ddf_dev_t *ddf_dev) … … 177 197 } \ 178 198 } else (void)0 199 179 200 const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t); 180 201 irq_cmd_t cmds[cmd_count]; … … 184 205 185 206 irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = cmds }; 186 ddf_msg(LVL_DEBUG,187 "Registering interrupt handler for device %s on irq %d.\n",188 ddf_dev->name, irq_kbd);189 207 ret = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler, 190 208 &irq_code); … … 192 210 "Failed set handler for kbd: %s.\n", str_error(ret)); 193 211 194 ddf_msg(LVL_DEBUG,195 "Registering interrupt handler for device %s on irq %d.\n",196 ddf_dev->name, irq_mouse);197 212 ret = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler, 198 213 &irq_code); … … 200 215 "Failed set handler for mouse: %s.\n", str_error(ret)); 201 216 217 #if 0 202 218 ret = ddf_fun_add_to_category(dev->kbd_fun, "keyboard"); 203 219 if (ret != EOK) … … 206 222 if (ret != EOK) 207 223 ddf_msg(LVL_WARN, "Failed to register mouse fun to category.\n"); 208 209 // TODO: Don't rely on kernel enabling interrupts do it yourself. 224 #endif 225 /* Enable interrupts */ 226 async_sess_t *parent_sess = 227 devman_parent_device_connect(EXCHANGE_SERIALIZE, ddf_dev->handle, 228 IPC_FLAG_BLOCKING); 229 ret = parent_sess ? EOK : ENOMEM; 230 CHECK_RET_UNBIND_DESTROY(ret, "Failed to create parent connection.\n"); 231 const bool enabled = hw_res_enable_interrupt(parent_sess); 232 async_hangup(parent_sess); 233 ret = enabled ? EOK : EIO; 234 CHECK_RET_UNBIND_DESTROY(ret, "Failed to enable interrupts: %s.\n"); 235 210 236 211 237 wait_ready(dev); … … 215 241 i8042_AUX_IE); 216 242 217 // TODO: Plug in connection. 218 219 return ret; 220 (void)i8042_connection; 243 return EOK; 221 244 } 222 245 223 246 /** Character device connection handler */ 247 #if 0 224 248 static void i8042_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 225 249 { … … 288 312 } 289 313 } 290 291 314 void i8042_port_write(i8042_t *dev, int devid, uint8_t data) 292 315 { … … 300 323 pio_write_8(&dev->regs->data, data); 301 324 } 302 303 void i8042_irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call) 304 { 305 ddf_msg(LVL_FATAL, "IRQ!!!.\n"); 306 if (!dev || !dev->driver_data) 307 return; 308 309 const int status = IPC_GET_ARG1(*call); 310 const int data = IPC_GET_ARG2(*call); 311 const int devid = (status & i8042_AUX_DATA) ? DEVID_AUX : DEVID_PRI; 312 313 if (device.port[devid].client_sess != NULL) { 314 async_exch_t *exch = 315 async_exchange_begin(device.port[devid].client_sess); 316 if (exch) { 317 async_msg_1(exch, IPC_FIRST_USER_METHOD, data); 318 async_exchange_end(exch); 319 } 320 } else { 321 ddf_msg(LVL_WARN, "No client session.\n"); 322 } 323 } 325 #endif 324 326 325 327 /** -
uspace/drv/char/i8042/i8042.h
r5960b48 rb1f44b4 42 42 #include <libarch/ddi.h> 43 43 #include <async.h> 44 #include <fibril_synch.h> 44 45 #include <ddf/driver.h> 45 46 … … 52 53 53 54 /** Softstate structure, one for each serial port (primary and aux). */ 55 /* 54 56 typedef struct { 55 57 service_id_t service_id; 56 58 async_sess_t *client_sess; 57 59 } i8042_port_t; 60 */ 61 62 typedef struct i8042 i8042_t; 58 63 59 64 enum { … … 63 68 }; 64 69 65 typedef struct{70 struct i8042 { 66 71 i8042_regs_t *regs; 67 i8042_port_t port[MAX_DEVS];72 // i8042_port_t port[MAX_DEVS]; 68 73 ddf_fun_t *kbd_fun; 69 74 ddf_fun_t *mouse_fun; 70 } i8042_t; 75 fibril_mutex_t guard; 76 fibril_condvar_t data_avail; 77 }; 71 78 72 79 int i8042_init(i8042_t *, void *, size_t, int, int, ddf_dev_t *); 80 int i8042_write_kbd(i8042_t *, uint8_t); 81 int i8042_read_kbd(i8042_t *, uint8_t *); 82 int i8042_write_aux(i8042_t *, uint8_t); 83 int i8042_read_aux(i8042_t *, uint8_t *); 73 84 74 85 #endif -
uspace/drv/char/i8042/main.c
r5960b48 rb1f44b4 114 114 return EOK; 115 115 } 116 116 /*----------------------------------------------------------------------------*/ 117 117 /** Get address of I/O registers. 118 118 * … … 161 161 return EOK; 162 162 } 163 164 163 /** 165 164 * @}
Note:
See TracChangeset
for help on using the changeset viewer.