Changeset 75751db6 in mainline
- Timestamp:
- 2014-08-29T20:32:20Z (10 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- af0a2c7
- Parents:
- 312e5ff
- Location:
- uspace
- Files:
-
- 1 added
- 10 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/Makefile.common
r312e5ff r75751db6 195 195 196 196 ifeq ($(CONFIG_OPTIMIZE_FOR_SIZE),y) 197 OPTIMIZATION = s198 else 199 OPTIMIZATION = 3197 OPTIMIZATION = 0 198 else 199 OPTIMIZATION = 0 200 200 endif 201 201 -
uspace/drv/char/i8042/i8042.c
r312e5ff r75751db6 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 3 * Copyright (c) 2006 Josef Cejka 4 * Copyright (c) 20 09Jiri Svoboda4 * Copyright (c) 2014 Jiri Svoboda 5 5 * Copyright (c) 2011 Jan Vesely 6 6 * All rights reserved. … … 39 39 */ 40 40 41 #include <ddf/log.h> 42 #include <ddf/interrupt.h> 43 #include <ddi.h> 41 44 #include <device/hw_res.h> 42 #include <ddi.h>43 45 #include <errno.h> 44 46 #include <str_error.h> 45 47 #include <inttypes.h> 46 #include < ddf/log.h>47 #include <ddf/interrupt.h> 48 #include <io/chardev_srv.h> 49 48 50 #include "i8042.h" 49 51 … … 64 66 #define i8042_KBD_TRANSLATE 0x40 /* Use this to switch to XT scancodes */ 65 67 66 static void default_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 67 68 /** Port function operations. */ 69 static ddf_dev_ops_t ops = { 70 .default_handler = default_handler 68 static void i8042_char_conn(ipc_callid_t, ipc_call_t *, void *); 69 static int i8042_read(chardev_srv_t *, void *, size_t); 70 static int i8042_write(chardev_srv_t *, const void *, size_t); 71 72 static chardev_ops_t i8042_chardev_ops = { 73 .read = i8042_read, 74 .write = i8042_write 71 75 }; 72 76 … … 106 110 }; 107 111 108 /** Get i8042 soft state from device node. */109 static i8042_t *dev_i8042(ddf_dev_t *dev)110 {111 return ddf_dev_data_get(dev);112 }113 114 112 /** Wait until it is safe to write to the device. */ 115 113 static void wait_ready(i8042_t *dev) … … 131 129 ddf_dev_t *dev) 132 130 { 133 i8042_t *controller = d ev_i8042(dev);131 i8042_t *controller = ddf_dev_data_get(dev); 134 132 135 133 const uint8_t status = IPC_GET_ARG1(*call); … … 186 184 }; 187 185 186 dev->kbd = ddf_fun_data_alloc(dev->kbd_fun, sizeof(i8042_port_t)); 187 if (dev->kbd == NULL) { 188 rc = ENOMEM; 189 goto error; 190 } 191 192 dev->kbd->ctl = dev; 193 chardev_srvs_init(&dev->kbd->cds); 194 dev->kbd->cds.ops = &i8042_chardev_ops; 195 dev->kbd->cds.sarg = dev->kbd; 196 188 197 rc = ddf_fun_add_match_id(dev->kbd_fun, "char/xtkbd", 90); 189 198 if (rc != EOK) … … 196 205 } 197 206 207 dev->aux = ddf_fun_data_alloc(dev->aux_fun, sizeof(i8042_port_t)); 208 if (dev->aux == NULL) { 209 rc = ENOMEM; 210 goto error; 211 } 212 213 dev->aux->ctl = dev; 214 chardev_srvs_init(&dev->aux->cds); 215 dev->aux->cds.ops = &i8042_chardev_ops; 216 dev->aux->cds.sarg = dev->aux; 217 198 218 rc = ddf_fun_add_match_id(dev->aux_fun, "char/ps2mouse", 90); 199 219 if (rc != EOK) 200 220 goto error; 201 221 202 ddf_fun_set_ ops(dev->kbd_fun, &ops);203 ddf_fun_set_ ops(dev->aux_fun, &ops);222 ddf_fun_set_conn_handler(dev->kbd_fun, i8042_char_conn); 223 ddf_fun_set_conn_handler(dev->aux_fun, i8042_char_conn); 204 224 205 225 buffer_init(&dev->kbd_buffer, dev->kbd_data, BUFFER_SIZE); … … 298 318 } 299 319 300 // FIXME TODO use shared instead this301 enum {302 IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,303 IPC_CHAR_WRITE,304 };305 306 320 /** Write data to i8042 port. 307 321 * 308 * @param fun DDF function.309 * @param buffer Data source .310 * @param size Data size .322 * @param srv Connection-specific data 323 * @param buffer Data source 324 * @param size Data size 311 325 * 312 326 * @return Bytes written. 313 327 * 314 328 */ 315 static int i8042_write(ddf_fun_t *fun, char *buffer, size_t size) 316 { 317 i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun)); 318 fibril_mutex_lock(&controller->write_guard); 329 static int i8042_write(chardev_srv_t *srv, const void *data, size_t size) 330 { 331 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; 332 i8042_t *i8042 = port->ctl; 333 const char *dp = (const char *)data; 334 335 fibril_mutex_lock(&i8042->write_guard); 319 336 320 337 for (size_t i = 0; i < size; ++i) { 321 if ( controller->aux_fun == fun) {322 wait_ready( controller);323 pio_write_8(& controller->regs->status,338 if (port == i8042->aux) { 339 wait_ready(i8042); 340 pio_write_8(&i8042->regs->status, 324 341 i8042_CMD_WRITE_AUX); 325 342 } 326 343 327 wait_ready( controller);328 pio_write_8(& controller->regs->data, buffer[i]);329 } 330 331 fibril_mutex_unlock(& controller->write_guard);344 wait_ready(i8042); 345 pio_write_8(&i8042->regs->data, dp[i]); 346 } 347 348 fibril_mutex_unlock(&i8042->write_guard); 332 349 return size; 333 350 } … … 335 352 /** Read data from i8042 port. 336 353 * 337 * @param fun DDF function.338 * @param buffer Data place .339 * @param size Data place size .354 * @param srv Connection-specific data 355 * @param buffer Data place 356 * @param size Data place size 340 357 * 341 358 * @return Bytes read. 342 359 * 343 360 */ 344 static int i8042_read(ddf_fun_t *fun, char *data, size_t size) 345 { 346 i8042_t *controller = dev_i8042(ddf_fun_get_dev(fun)); 347 buffer_t *buffer = (fun == controller->aux_fun) ? 348 &controller->aux_buffer : &controller->kbd_buffer; 361 static int i8042_read(chardev_srv_t *srv, void *dest, size_t size) 362 { 363 i8042_port_t *port = (i8042_port_t *)srv->srvs->sarg; 364 i8042_t *i8042 = port->ctl; 365 uint8_t *destp = (uint8_t *)dest; 366 367 buffer_t *buffer = (port == i8042->aux) ? 368 &i8042->aux_buffer : &i8042->kbd_buffer; 349 369 350 370 for (size_t i = 0; i < size; ++i) 351 *d ata++ = buffer_read(buffer);371 *destp++ = buffer_read(buffer); 352 372 353 373 return size; … … 356 376 /** Handle data requests. 357 377 * 358 * @param fun ddf_fun_t function.359 378 * @param id callid 360 379 * @param call IPC request. 361 * 362 */ 363 static void default_handler(ddf_fun_t *fun, ipc_callid_t id, ipc_call_t *call) 364 { 365 const sysarg_t method = IPC_GET_IMETHOD(*call); 366 const size_t size = IPC_GET_ARG1(*call); 367 368 switch (method) { 369 case IPC_CHAR_READ: 370 if (size <= 4 * sizeof(sysarg_t)) { 371 sysarg_t message[4] = {}; 372 373 i8042_read(fun, (char *) message, size); 374 async_answer_4(id, size, message[0], message[1], 375 message[2], message[3]); 376 } else 377 async_answer_0(id, ELIMIT); 378 break; 379 380 case IPC_CHAR_WRITE: 381 if (size <= 3 * sizeof(sysarg_t)) { 382 const sysarg_t message[3] = { 383 IPC_GET_ARG2(*call), 384 IPC_GET_ARG3(*call), 385 IPC_GET_ARG4(*call) 386 }; 387 388 i8042_write(fun, (char *) message, size); 389 async_answer_0(id, size); 390 } else 391 async_answer_0(id, ELIMIT); 392 393 default: 394 async_answer_0(id, EINVAL); 395 } 380 * @param arg ddf_fun_t function. 381 */ 382 void i8042_char_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg) 383 { 384 i8042_port_t *port = ddf_fun_data_get((ddf_fun_t *)arg); 385 386 chardev_conn(iid, icall, &port->cds); 396 387 } 397 388 -
uspace/drv/char/i8042/i8042.h
r312e5ff r75751db6 40 40 #define i8042_H_ 41 41 42 #include <io/chardev_srv.h> 42 43 #include <sys/types.h> 43 44 #include <fibril_synch.h> … … 56 57 } __attribute__ ((packed)) i8042_regs_t; 57 58 58 /** i8042 driver structure. */ 59 /** i8042 Port. */ 60 typedef struct { 61 struct i8042 *ctl; /**< Controller */ 62 chardev_srvs_t cds; /**< Character device server data */ 63 } i8042_port_t; 64 65 /** i8042 Controller. */ 59 66 typedef struct i8042 { 60 67 i8042_regs_t *regs; /**< I/O registers. */ … … 65 72 uint8_t aux_data[BUFFER_SIZE]; /**< Primary port buffer space. */ 66 73 uint8_t kbd_data[BUFFER_SIZE]; /**< Aux. port buffer space. */ 74 i8042_port_t *kbd; 75 i8042_port_t *aux; 67 76 fibril_mutex_t write_guard; /**< Prevents simultanous port writes.*/ 68 77 } i8042_t; 78 69 79 70 80 extern int i8042_init(i8042_t *, addr_range_t *, int, int, ddf_dev_t *); -
uspace/drv/char/pl050/pl050.c
r312e5ff r75751db6 38 38 #include <ddf/log.h> 39 39 #include <device/hw_res_parsed.h> 40 #include <io/chardev_srv.h> 40 41 41 42 #define NAME "pl050" … … 45 46 46 47 #define PL050_STAT_RXFULL (1 << 4) 47 48 enum {49 IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD,50 IPC_CHAR_WRITE,51 };52 48 53 49 enum { … … 59 55 static int pl050_fun_offline(ddf_fun_t *); 60 56 static void pl050_char_conn(ipc_callid_t, ipc_call_t *, void *); 57 static int pl050_read(chardev_srv_t *, void *, size_t); 58 static int pl050_write(chardev_srv_t *, const void *, size_t); 61 59 62 60 static driver_ops_t driver_ops = { … … 71 69 }; 72 70 71 static chardev_ops_t pl050_chardev_ops = { 72 .read = pl050_read, 73 .write = pl050_write 74 }; 75 73 76 typedef struct { 77 async_sess_t *parent_sess; 74 78 ddf_dev_t *dev; 79 75 80 ddf_fun_t *fun_a; 76 async_sess_t *parent_sess; 81 chardev_srvs_t cds; 82 77 83 uintptr_t iobase; 78 84 size_t iosize; … … 135 141 size_t nidx; 136 142 143 ddf_msg(LVL_NOTE, "Interrupt"); 144 137 145 fibril_mutex_lock(&pl050->buf_lock); 138 146 nidx = (pl050->buf_wp + 1) % buffer_size; … … 209 217 } 210 218 211 static int pl050_read(pl050_t *pl050, void *buffer, size_t size) 212 { 219 static int pl050_read(chardev_srv_t *srv, void *buffer, size_t size) 220 { 221 pl050_t *pl050 = (pl050_t *)srv->srvs->sarg; 213 222 uint8_t *bp = buffer; 223 size_t left; 214 224 fibril_mutex_lock(&pl050->buf_lock); 215 225 216 while (size > 0) { 226 left = size; 227 while (left > 0) { 217 228 while (pl050->buf_rp == pl050->buf_wp) 218 229 fibril_condvar_wait(&pl050->buf_cv, &pl050->buf_lock); 219 230 *bp++ = pl050->buffer[pl050->buf_rp]; 220 -- size;231 --left; 221 232 pl050->buf_rp = (pl050->buf_rp + 1) % buffer_size; 222 233 } … … 224 235 fibril_mutex_unlock(&pl050->buf_lock); 225 236 226 return EOK;227 } 228 229 static int pl050_write( pl050_t *pl050,void *data, size_t size)230 { 231 return EOK;237 return size; 238 } 239 240 static int pl050_write(chardev_srv_t *srv, const void *data, size_t size) 241 { 242 return size; 232 243 } 233 244 … … 236 247 pl050_t *pl050 = pl050_from_fun((ddf_fun_t *)arg); 237 248 238 /* Accept the connection */ 239 async_answer_0(iid, EOK); 240 241 while (true) { 242 ipc_call_t call; 243 ipc_callid_t callid = async_get_call(&call); 244 sysarg_t method = IPC_GET_IMETHOD(call); 245 size_t size = IPC_GET_ARG1(call); 246 247 if (!method) { 248 /* The other side has hung up */ 249 async_answer_0(callid, EOK); 250 break; 251 } 252 253 switch (method) { 254 case IPC_CHAR_READ: 255 if (size <= 4 * sizeof(sysarg_t)) { 256 sysarg_t message[4] = {}; 257 258 pl050_read(pl050, (char *) message, size); 259 async_answer_4(callid, size, message[0], message[1], 260 message[2], message[3]); 261 } else 262 async_answer_0(callid, ELIMIT); 263 break; 264 265 case IPC_CHAR_WRITE: 266 if (size <= 3 * sizeof(sysarg_t)) { 267 const sysarg_t message[3] = { 268 IPC_GET_ARG2(call), 269 IPC_GET_ARG3(call), 270 IPC_GET_ARG4(call) 271 }; 272 273 pl050_write(pl050, (char *) message, size); 274 async_answer_0(callid, size); 275 } else 276 async_answer_0(callid, ELIMIT); 277 278 default: 279 async_answer_0(callid, EINVAL); 280 } 281 } 249 chardev_conn(iid, icall, &pl050->cds); 282 250 } 283 251 … … 289 257 int rc; 290 258 291 ddf_msg(LVL_ DEBUG, "pl050_dev_add()");259 ddf_msg(LVL_NOTE, "pl050_dev_add()"); 292 260 293 261 pl050 = ddf_dev_data_alloc(dev, sizeof(pl050_t)); … … 308 276 pl050->dev = dev; 309 277 278 if (1) { 310 279 rc = pl050_init(pl050); 311 280 if (rc != EOK) 312 281 goto error; 313 282 } 314 283 rc = ddf_fun_add_match_id(fun_a, "char/xtkbd", 10); 315 284 if (rc != EOK) { … … 319 288 } 320 289 290 ddf_msg(LVL_NOTE, "Init srvs"); 291 if (1) { 292 chardev_srvs_init(&pl050->cds); 293 pl050->cds.ops = &pl050_chardev_ops; 294 pl050->cds.sarg = pl050; 295 321 296 ddf_fun_set_conn_handler(fun_a, pl050_char_conn); 322 297 } 323 298 rc = ddf_fun_bind(fun_a); 324 299 if (rc != EOK) { … … 328 303 } 329 304 305 ddf_msg(LVL_NOTE, "Device added"); 330 306 ddf_msg(LVL_DEBUG, "Device added."); 331 307 return EOK; -
uspace/drv/char/ps2mouse/Makefile
r312e5ff r75751db6 33 33 34 34 SOURCES = \ 35 chardev.c \36 35 main.c \ 37 36 ps2mouse.c -
uspace/drv/char/ps2mouse/ps2mouse.c
r312e5ff r75751db6 37 37 #include <ddf/log.h> 38 38 #include <io/keycode.h> 39 #include <io/chardev.h> 39 40 #include <io/console.h> 40 41 #include <ipc/mouseev.h> … … 42 43 43 44 #include "ps2mouse.h" 44 #include "chardev.h"45 45 46 46 #define PS2_MOUSE_GET_DEVICE_ID 0xf2 -
uspace/drv/char/xtkbd/Makefile
r312e5ff r75751db6 33 33 34 34 SOURCES = \ 35 chardev.c \36 35 main.c \ 37 36 xtkbd.c -
uspace/drv/char/xtkbd/xtkbd.c
r312e5ff r75751db6 36 36 #include <ddf/log.h> 37 37 #include <io/keycode.h> 38 #include <io/chardev.h> 38 39 #include <io/console.h> 39 40 #include <ipc/kbdev.h> 40 41 #include <abi/ipc/methods.h> 41 42 42 #include "chardev.h"43 43 #include "xtkbd.h" 44 44 -
uspace/lib/c/Makefile
r312e5ff r75751db6 92 92 generic/io/input.c \ 93 93 generic/io/io.c \ 94 generic/io/chardev.c \ 95 generic/io/chardev_srv.c \ 94 96 generic/io/chargrid.c \ 95 97 generic/io/output.c \ -
uspace/lib/c/generic/bd_srv.c
r312e5ff r75751db6 209 209 bd_srv_t *srv; 210 210 211 srv = calloc(1, sizeof( srv));211 srv = calloc(1, sizeof(bd_srv_t)); 212 212 if (srv == NULL) 213 213 return NULL; -
uspace/lib/c/generic/io/chardev.c
r312e5ff r75751db6 29 29 #include <errno.h> 30 30 #include <mem.h> 31 #include <ipc/dev_iface.h> 32 #include <ddf/log.h> 33 34 #include "chardev.h" 35 36 // TODO make this shared 37 enum { 38 IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD, 39 IPC_CHAR_WRITE, 40 }; 31 #include <io/chardev.h> 32 #include <ipc/chardev.h> 41 33 42 34 ssize_t chardev_read(async_exch_t *exch, void *data, size_t size) … … 48 40 49 41 sysarg_t message[4] = { 0 }; 50 const ssize_t ret = async_req_1_4(exch, IPC_CHAR_READ, size,42 const ssize_t ret = async_req_1_4(exch, CHARDEV_READ, size, 51 43 &message[0], &message[1], &message[2], &message[3]); 52 44 if (ret > 0 && (size_t)ret <= size) … … 64 56 sysarg_t message[3] = { 0 }; 65 57 memcpy(message, data, size); 66 return async_req_4_0(exch, IPC_CHAR_WRITE, size,58 return async_req_4_0(exch, CHARDEV_WRITE, size, 67 59 message[0], message[1], message[2]); 68 60 } -
uspace/lib/c/include/io/chardev.h
r312e5ff r75751db6 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvkbd28 /** @addtogroup libc 29 29 * @{ 30 30 */ 31 /** @file32 * @brief ps/2 mouse driver.33 */34 31 35 #ifndef _CHARDEV_H_36 #define _CHARDEV_H_32 #ifndef LIBC_IO_CHARDEV_H_ 33 #define LIBC_IO_CHARDEV_H_ 37 34 38 35 #include <libarch/types.h> -
uspace/lib/c/include/io/chardev_srv.h
r312e5ff r75751db6 1 1 /* 2 * Copyright (c) 201 1 Jan Vesely2 * Copyright (c) 2014 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 #include <errno.h> 30 #include <mem.h> 31 #include <ipc/dev_iface.h> 32 #include <ddf/log.h> 29 /** @addtogroup libc 30 * @{ 31 */ 32 /** @file 33 */ 33 34 34 #include "chardev.h" 35 #ifndef LIBC_IO_CHARDEV_SRV_H_ 36 #define LIBC_IO_CHARDEV_SRV_H_ 35 37 36 // TODO make this shared 37 enum { 38 IPC_CHAR_READ = DEV_FIRST_CUSTOM_METHOD, 39 IPC_CHAR_WRITE, 38 #include <adt/list.h> 39 #include <async.h> 40 #include <fibril_synch.h> 41 #include <stdbool.h> 42 #include <sys/types.h> 43 44 typedef struct chardev_ops chardev_ops_t; 45 46 /** Service setup (per sevice) */ 47 typedef struct { 48 chardev_ops_t *ops; 49 void *sarg; 50 } chardev_srvs_t; 51 52 /** Server structure (per client session) */ 53 typedef struct { 54 chardev_srvs_t *srvs; 55 void *carg; 56 } chardev_srv_t; 57 58 struct chardev_ops { 59 int (*open)(chardev_srvs_t *, chardev_srv_t *); 60 int (*close)(chardev_srv_t *); 61 int (*read)(chardev_srv_t *, void *, size_t); 62 int (*write)(chardev_srv_t *, const void *, size_t); 40 63 }; 41 64 42 ssize_t chardev_read(async_exch_t *exch, void *data, size_t size) 43 { 44 if (!exch) 45 return EBADMEM; 46 if (size > 4 * sizeof(sysarg_t)) 47 return ELIMIT; 65 extern void chardev_srvs_init(chardev_srvs_t *); 48 66 49 sysarg_t message[4] = { 0 }; 50 const ssize_t ret = async_req_1_4(exch, IPC_CHAR_READ, size, 51 &message[0], &message[1], &message[2], &message[3]); 52 if (ret > 0 && (size_t)ret <= size) 53 memcpy(data, message, size); 54 return ret; 55 } 67 extern int chardev_conn(ipc_callid_t, ipc_call_t *, chardev_srvs_t *); 56 68 57 ssize_t chardev_write(async_exch_t *exch, const void *data, size_t size) 58 { 59 if (!exch) 60 return EBADMEM; 61 if (size > 3 * sizeof(sysarg_t)) 62 return ELIMIT; 69 #endif 63 70 64 sysarg_t message[3] = { 0 }; 65 memcpy(message, data, size); 66 return async_req_4_0(exch, IPC_CHAR_WRITE, size, 67 message[0], message[1], message[2]); 68 } 71 /** @} 72 */ -
uspace/lib/c/include/ipc/chardev.h
r312e5ff r75751db6 1 1 /* 2 * Copyright (c) 201 1 Jan Vesely2 * Copyright (c) 2014 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /** @addtogroup drvmouse 28 29 /** @addtogroup libcipc 29 30 * @{ 30 31 */ 31 32 /** @file 32 * @brief ps/2 mouse driver.33 * @brief Character device interface. 33 34 */ 34 35 35 #ifndef _CHARDEV_H_36 #define _CHARDEV_H_36 #ifndef LIBC_IPC_CHARDEV_H_ 37 #define LIBC_IPC_CHARDEV_H_ 37 38 38 #include <libarch/types.h> 39 #include <async.h> 39 #include <ipc/common.h> 40 40 41 ssize_t chardev_read(async_exch_t *, void *, size_t); 42 ssize_t chardev_write(async_exch_t *, const void *, size_t); 41 typedef enum { 42 CHARDEV_READ = IPC_FIRST_USER_METHOD, 43 CHARDEV_WRITE 44 } chardev_request_t; 43 45 44 46 #endif 45 /** 46 47 48 /** @} 47 49 */
Note:
See TracChangeset
for help on using the changeset viewer.