| 1 | /****************************************************************************** |
|---|
| 2 | *.Copyright (c) 1999-2006 DST Technologies Inc. All rights reserved. |
|---|
| 3 | * |
|---|
| 4 | * MODULE: |
|---|
| 5 | * dst_module.c |
|---|
| 6 | * |
|---|
| 7 | * DESCRIPTION: |
|---|
| 8 | * Linux kernel loadable module for low level DST hardware access |
|---|
| 9 | ******************************************************************************/ |
|---|
| 10 | #ifndef __KERNEL__ |
|---|
| 11 | #define __KERNEL__ |
|---|
| 12 | #endif |
|---|
| 13 | |
|---|
| 14 | #define CONFIG_DEVFS_FS 1 |
|---|
| 15 | |
|---|
| 16 | #ifndef MODULE |
|---|
| 17 | #define MODULE |
|---|
| 18 | #endif |
|---|
| 19 | |
|---|
| 20 | /*======================== |
|---|
| 21 | * Includes |
|---|
| 22 | *=======================*/ |
|---|
| 23 | #include "lld_os.h" |
|---|
| 24 | #include "lld_local.h" |
|---|
| 25 | #include "dst_kernel.h" |
|---|
| 26 | #include "dstmodule.h" |
|---|
| 27 | |
|---|
| 28 | #if KERNEL_2_4_0 |
|---|
| 29 | //#include <linux/devfs_fs_kernel.h> |
|---|
| 30 | #endif |
|---|
| 31 | |
|---|
| 32 | /*======================== |
|---|
| 33 | * Local defines |
|---|
| 34 | *=======================*/ |
|---|
| 35 | #define DEVICE_NAME DST_DEV_NAME |
|---|
| 36 | #define DST_DEV_PERM 0666 |
|---|
| 37 | |
|---|
| 38 | #define KSEG0_START 0x80000000 |
|---|
| 39 | |
|---|
| 40 | #define GET_DS_U8_0(x) (unsigned int)((x>>24)&0xFF) |
|---|
| 41 | #define GET_DS_U8_1(x) (unsigned int)((x>>16)&0xFF) |
|---|
| 42 | #define GET_DS_U8_2(x) (unsigned int)((x>>8)&0xFF) |
|---|
| 43 | #define GET_DS_U8_3(x) (unsigned int)((x)&0xFF) |
|---|
| 44 | |
|---|
| 45 | /*======================== |
|---|
| 46 | * Local Prototypes |
|---|
| 47 | *=======================*/ |
|---|
| 48 | static DS_U32 lld_dlevel (DS_U32 level); |
|---|
| 49 | static int device_open (struct inode *inode, struct file *file); |
|---|
| 50 | static int device_close (struct inode *inode, struct file *file); |
|---|
| 51 | static int device_ioctl (struct inode *inode, struct file *file, |
|---|
| 52 | unsigned int ioctl_num, unsigned long ioctl_param); |
|---|
| 53 | static __s64 dst_do_gettimeofday(void); |
|---|
| 54 | |
|---|
| 55 | /*======================== |
|---|
| 56 | * Global variables |
|---|
| 57 | *=======================*/ |
|---|
| 58 | |
|---|
| 59 | /*======================== |
|---|
| 60 | * Local variables |
|---|
| 61 | *=======================*/ |
|---|
| 62 | static int lld_debug = 0; |
|---|
| 63 | |
|---|
| 64 | MODULE_AUTHOR ("DS Technology Inc."); |
|---|
| 65 | MODULE_DESCRIPTION ("DS Kernel Module for Linux Platform"); |
|---|
| 66 | //MODULE_PARM (debug, "i"); |
|---|
| 67 | |
|---|
| 68 | DST_DEVICE_INFO dst_device[MAX_DEVICES]; |
|---|
| 69 | DS_U32 current_filp=KERNEL_PID; |
|---|
| 70 | |
|---|
| 71 | struct file_operations dst_fops = |
|---|
| 72 | { |
|---|
| 73 | #if KERNEL_2_4_0 |
|---|
| 74 | owner: THIS_MODULE, |
|---|
| 75 | #endif |
|---|
| 76 | ioctl: device_ioctl, |
|---|
| 77 | mmap: NULL, |
|---|
| 78 | open: device_open, |
|---|
| 79 | release: device_close, |
|---|
| 80 | }; |
|---|
| 81 | |
|---|
| 82 | static int dsthwacc_major_num = 0; |
|---|
| 83 | |
|---|
| 84 | /****************************************************************************** |
|---|
| 85 | * Interrupt setup for kernel |
|---|
| 86 | * |
|---|
| 87 | * |
|---|
| 88 | * |
|---|
| 89 | *****************************************************************************^^*/ |
|---|
| 90 | static int DevOpenForKernel (DST_DEVICE_INFO *pdevice) |
|---|
| 91 | { |
|---|
| 92 | struct file KFileH; |
|---|
| 93 | |
|---|
| 94 | KFileH.private_data = pdevice; |
|---|
| 95 | return (0); |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | /****************************************************************************** |
|---|
| 99 | * Interrupt cleanup for kernel |
|---|
| 100 | * |
|---|
| 101 | * |
|---|
| 102 | * |
|---|
| 103 | *****************************************************************************^^*/ |
|---|
| 104 | static int DevCloseForKernel (DST_DEVICE_INFO *pdevice) |
|---|
| 105 | { |
|---|
| 106 | struct file KFileH; |
|---|
| 107 | |
|---|
| 108 | KFileH.private_data = pdevice; |
|---|
| 109 | return (0); |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | /****************************************************************************** |
|---|
| 113 | * DS_U32 lld_GetVersion (void); |
|---|
| 114 | * |
|---|
| 115 | * Purpose: Return the version for this module |
|---|
| 116 | * |
|---|
| 117 | * Inputs: None |
|---|
| 118 | * |
|---|
| 119 | * Outputs: Version number |
|---|
| 120 | * |
|---|
| 121 | *****************************************************************************^^*/ |
|---|
| 122 | DS_U32 lld_GetVersion (void) |
|---|
| 123 | { |
|---|
| 124 | return (DSTMOD_VERSION_NUMBER); |
|---|
| 125 | } |
|---|
| 126 | |
|---|
| 127 | static int lld_get_info (char *page, char **start, off_t offset, int count, int *eof, void *data) |
|---|
| 128 | { |
|---|
| 129 | int len = 0; |
|---|
| 130 | int limit = count - 80; /* don't print more than this */ |
|---|
| 131 | static int ref_count=0; |
|---|
| 132 | unsigned int i; |
|---|
| 133 | DST_DEVICE_INFO *pdevice = (DST_DEVICE_INFO *) data; |
|---|
| 134 | |
|---|
| 135 | ref_count++; |
|---|
| 136 | |
|---|
| 137 | for (i = 0; i < MAX_DEVICES; i++) |
|---|
| 138 | { |
|---|
| 139 | if ( limit > len ) |
|---|
| 140 | len += sprintf(page+len, "dstmod[%d]: refcount = %i\n", i, ref_count); |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | *eof = 1; |
|---|
| 144 | pdevice = pdevice; |
|---|
| 145 | |
|---|
| 146 | return (len); |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | /*^^*************************************************************************** |
|---|
| 150 | * static DS_U32 lld_dlevel (DS_U32 level) |
|---|
| 151 | * |
|---|
| 152 | * Description: |
|---|
| 153 | * Set debug level in LLD and HKD |
|---|
| 154 | * |
|---|
| 155 | * Entry : level = new debug level |
|---|
| 156 | * |
|---|
| 157 | * Return: Old debug level |
|---|
| 158 | * |
|---|
| 159 | **************************************************************************^^*/ |
|---|
| 160 | static DS_U32 lld_dlevel (DS_U32 level) |
|---|
| 161 | { |
|---|
| 162 | DS_U32 old_level; |
|---|
| 163 | |
|---|
| 164 | old_level = lld_debug; |
|---|
| 165 | lld_debug = level; |
|---|
| 166 | |
|---|
| 167 | return old_level; |
|---|
| 168 | } |
|---|
| 169 | |
|---|
| 170 | /****************************************************************************** |
|---|
| 171 | * init_module (void) |
|---|
| 172 | * |
|---|
| 173 | * Purpose: Initializes the module, registers the device |
|---|
| 174 | * Inputs: NONE |
|---|
| 175 | * Outputs: int - 0 on success, non zero on failure |
|---|
| 176 | ******************************************************************************/ |
|---|
| 177 | int init_module (void) |
|---|
| 178 | { |
|---|
| 179 | printk( DEVICE_NAME ": " DSTMOD_VERSION_STRING ", Copyright (c) 2005-2006, Digital Stream Technology.\n"); |
|---|
| 180 | printk( DEVICE_NAME ": generated on " __DATE__ " at " __TIME__ " \n"); |
|---|
| 181 | |
|---|
| 182 | memset (dst_device, 0, sizeof (dst_device)); |
|---|
| 183 | |
|---|
| 184 | #if (KERNEL_2_4_0) && defined (CONFIG_DEVFS_FS) |
|---|
| 185 | dsthwacc_major_num = devfs_register_chrdev (DST_MAJOR_DEV_NUM, DEVICE_NAME, &dst_fops); |
|---|
| 186 | #else |
|---|
| 187 | dsthwacc_major_num = register_chrdev (DST_MAJOR_DEV_NUM, DEVICE_NAME, &dst_fops); |
|---|
| 188 | #endif |
|---|
| 189 | |
|---|
| 190 | if (dsthwacc_major_num < 0) { |
|---|
| 191 | printk(DEVICE_NAME ": Error registering device: %d\n", dsthwacc_major_num); |
|---|
| 192 | return (dsthwacc_major_num); |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | printk( KERN_DEBUG DEVICE_NAME ": Major device number is %d.\n", dsthwacc_major_num); |
|---|
| 196 | |
|---|
| 197 | #if (KERNEL_2_4_0) && defined (CONFIG_DEVFS_FS) |
|---|
| 198 | devfs_register_series (NULL, DEVICE_NAME"%u", MAX_DEVICES, |
|---|
| 199 | DEVFS_FL_DEFAULT, dsthwacc_major_num, 0, |
|---|
| 200 | S_IFCHR | S_IRUSR | S_IWUSR | DST_DEV_PERM, |
|---|
| 201 | &dst_fops, NULL); |
|---|
| 202 | #endif |
|---|
| 203 | |
|---|
| 204 | /*============================ |
|---|
| 205 | * Init sem and event libs |
|---|
| 206 | *===========================*/ |
|---|
| 207 | SemInit(); |
|---|
| 208 | EventInit(); |
|---|
| 209 | |
|---|
| 210 | DevOpenForKernel(&dst_device[0]); |
|---|
| 211 | create_proc_read_entry (DST_DEV_NAME, 0, NULL, lld_get_info, (void *) dst_device); |
|---|
| 212 | |
|---|
| 213 | return (0); |
|---|
| 214 | } |
|---|
| 215 | |
|---|
| 216 | /****************************************************************************** |
|---|
| 217 | * cleanup_module (void) |
|---|
| 218 | * |
|---|
| 219 | * Purpose: unregisters the device, frees memory and I/O ranges |
|---|
| 220 | * used by the device. |
|---|
| 221 | * Inputs: NONE |
|---|
| 222 | * Outputs: NONE |
|---|
| 223 | ******************************************************************************/ |
|---|
| 224 | void cleanup_module (void) |
|---|
| 225 | { |
|---|
| 226 | int retval; |
|---|
| 227 | #if (KERNEL_2_4_0) && defined (CONFIG_DEVFS_FS) |
|---|
| 228 | int i; |
|---|
| 229 | char dst_dev[16]; |
|---|
| 230 | devfs_handle_t de; |
|---|
| 231 | #endif |
|---|
| 232 | |
|---|
| 233 | printk( DEVICE_NAME ": Shutting down module.\n"); |
|---|
| 234 | |
|---|
| 235 | DevCloseForKernel(&dst_device[0]); |
|---|
| 236 | |
|---|
| 237 | #if (KERNEL_2_4_0) && defined (CONFIG_DEVFS_FS) |
|---|
| 238 | retval = devfs_unregister_chrdev (dsthwacc_major_num, DEVICE_NAME); |
|---|
| 239 | #else |
|---|
| 240 | retval = unregister_chrdev (dsthwacc_major_num, DEVICE_NAME); |
|---|
| 241 | #endif |
|---|
| 242 | |
|---|
| 243 | if (retval < 0) |
|---|
| 244 | { |
|---|
| 245 | printk( DEVICE_NAME ": Error in unregister_chrdev: %d\n", retval); |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | #if (KERNEL_2_4_0) && defined (CONFIG_DEVFS_FS) |
|---|
| 249 | for (i = 0; i <= MAX_DEVICES; i++) |
|---|
| 250 | { |
|---|
| 251 | sprintf(dst_dev, DEVICE_NAME"%u", i); |
|---|
| 252 | de = devfs_find_handle (NULL, dst_dev, 0, 0, |
|---|
| 253 | DEVFS_SPECIAL_CHR, 0); |
|---|
| 254 | devfs_unregister(de); |
|---|
| 255 | } |
|---|
| 256 | #endif |
|---|
| 257 | SemCleanup(); |
|---|
| 258 | EventCleanup(); |
|---|
| 259 | remove_proc_entry (DST_DEV_NAME, NULL); |
|---|
| 260 | memset (dst_device, 0, sizeof (dst_device)); |
|---|
| 261 | } |
|---|
| 262 | |
|---|
| 263 | /****************************************************************************** |
|---|
| 264 | *.open_device (struct inode *inode, struct file *filp) |
|---|
| 265 | * Function: Opens the device, increments the module count |
|---|
| 266 | * Inputs: struct inode *inode |
|---|
| 267 | * struct file *filp |
|---|
| 268 | * Outputs: int - returns 0 on success, the defined error otherwise |
|---|
| 269 | ******************************************************************************/ |
|---|
| 270 | static int open_device (struct inode *inode, struct file *filp) |
|---|
| 271 | { |
|---|
| 272 | unsigned int device_minor; |
|---|
| 273 | DST_DEVICE_INFO *pdevice; |
|---|
| 274 | |
|---|
| 275 | /* Ensure that the requested minor device number exists and is valid */ |
|---|
| 276 | |
|---|
| 277 | device_minor = MINOR (inode->i_rdev); |
|---|
| 278 | pdevice = &dst_device[device_minor]; |
|---|
| 279 | |
|---|
| 280 | printk( KERN_DEBUG DEVICE_NAME ": %s open for pid %d\n", pdevice->name, mCurrentTid); |
|---|
| 281 | |
|---|
| 282 | filp->private_data = pdevice; |
|---|
| 283 | |
|---|
| 284 | pdevice->refcount += 1; /* Increment counter */ |
|---|
| 285 | //MOD_INC_USE_COUNT; |
|---|
| 286 | return (0); |
|---|
| 287 | } |
|---|
| 288 | |
|---|
| 289 | /****************************************************************************** |
|---|
| 290 | *.close_device (struct inode *inode, struct file *filp) |
|---|
| 291 | * Function: Closes the device, decrements the module count |
|---|
| 292 | * Inputs: struct inode *inode |
|---|
| 293 | * struct file *filp |
|---|
| 294 | * Outputs: NONE |
|---|
| 295 | ******************************************************************************/ |
|---|
| 296 | static int close_device (struct inode *inode, struct file *filp) |
|---|
| 297 | { |
|---|
| 298 | DST_DEVICE_INFO *pdevice = filp->private_data; |
|---|
| 299 | |
|---|
| 300 | printk( KERN_DEBUG DEVICE_NAME ": %s close for pid %d - refcount = %d\n", pdevice->name, mCurrentTid, (int)(pdevice->refcount)); |
|---|
| 301 | |
|---|
| 302 | SemProcessExit(); |
|---|
| 303 | EventProcessExit(); |
|---|
| 304 | |
|---|
| 305 | /*=============================== |
|---|
| 306 | * decrement reference counter |
|---|
| 307 | *==============================*/ |
|---|
| 308 | if (pdevice->refcount > 0) |
|---|
| 309 | { |
|---|
| 310 | pdevice->refcount -= 1; |
|---|
| 311 | } |
|---|
| 312 | if (pdevice->refcount == 0) |
|---|
| 313 | { |
|---|
| 314 | filp->private_data = NULL; |
|---|
| 315 | } |
|---|
| 316 | //MOD_DEC_USE_COUNT; |
|---|
| 317 | return (0); |
|---|
| 318 | } |
|---|
| 319 | |
|---|
| 320 | /****************************************************************************** |
|---|
| 321 | *.device_open (struct inode *inode, struct file *filp) |
|---|
| 322 | * Function: Opens the device, increments the module count |
|---|
| 323 | * Inputs: struct inode *inode |
|---|
| 324 | * struct file *filp |
|---|
| 325 | * Outputs: int - returns 0 on success, the defined error otherwise |
|---|
| 326 | ******************************************************************************/ |
|---|
| 327 | static int device_open (struct inode *inode, struct file *filp) |
|---|
| 328 | { |
|---|
| 329 | int i; |
|---|
| 330 | DS_U32 org_filp; |
|---|
| 331 | |
|---|
| 332 | org_filp = current_filp; |
|---|
| 333 | current_filp = (DS_U32)filp; |
|---|
| 334 | i = open_device (inode, filp); |
|---|
| 335 | current_filp = org_filp; |
|---|
| 336 | return (i); |
|---|
| 337 | } |
|---|
| 338 | |
|---|
| 339 | /****************************************************************************** |
|---|
| 340 | *.device_close (struct inode *inode, struct file *filp); |
|---|
| 341 | * Function: Closes the device, decrements the module count |
|---|
| 342 | * Inputs: struct inode *inode |
|---|
| 343 | * struct file *filp |
|---|
| 344 | * Outputs: NONE |
|---|
| 345 | ******************************************************************************/ |
|---|
| 346 | static int device_close (struct inode *inode, struct file *filp) |
|---|
| 347 | { |
|---|
| 348 | int i; |
|---|
| 349 | DS_U32 org_filp; |
|---|
| 350 | |
|---|
| 351 | org_filp = current_filp; |
|---|
| 352 | current_filp = (DS_U32)filp; |
|---|
| 353 | i = close_device (inode, filp); |
|---|
| 354 | current_filp = org_filp; |
|---|
| 355 | return (i); |
|---|
| 356 | } |
|---|
| 357 | |
|---|
| 358 | /******************************************************************************* |
|---|
| 359 | *.ioctl_device (struct inode *inode, struct file *filp, |
|---|
| 360 | * unsigned int ioctl_num, unsigned long ioctl_param) |
|---|
| 361 | * Function: Entry point for the programs calling the specific |
|---|
| 362 | * IOCTLs. |
|---|
| 363 | * Inputs: struct inode *inode |
|---|
| 364 | * struct file *filp |
|---|
| 365 | * unsigned int ioctl_num - the number of the IOCTL being called |
|---|
| 366 | * unsigned int ioctl_param - the 'extra' data being sent |
|---|
| 367 | * Outputs: int |
|---|
| 368 | ******************************************************************************/ |
|---|
| 369 | //extern char LoaderVer[]; |
|---|
| 370 | static int ioctl_device (struct inode *inode, struct file *filp, |
|---|
| 371 | unsigned int ioctl_num, unsigned long ioctl_param) |
|---|
| 372 | { |
|---|
| 373 | DS_U32 i; |
|---|
| 374 | DST_DEVICE_INFO *pdevice = filp->private_data; |
|---|
| 375 | __s64 time_stamp; |
|---|
| 376 | OBJ_OPER ObjOper; |
|---|
| 377 | DS_U32 flags; |
|---|
| 378 | DS_U8 *pbAddr; |
|---|
| 379 | DS_U16 *pwAddr; |
|---|
| 380 | DS_U32 *pdwAddr; |
|---|
| 381 | DS_U8 bTemp = 0; |
|---|
| 382 | |
|---|
| 383 | switch (ioctl_num) |
|---|
| 384 | { |
|---|
| 385 | case DSTHWIOC_SEM_OP: |
|---|
| 386 | copy_from_user (&ObjOper, (char *) ioctl_param, sizeof(OBJ_OPER)); |
|---|
| 387 | i = SemOperation (&ObjOper); |
|---|
| 388 | copy_to_user ((char *)ioctl_param, &ObjOper, sizeof(OBJ_OPER)); |
|---|
| 389 | return (i); |
|---|
| 390 | break; |
|---|
| 391 | |
|---|
| 392 | case DSTHWIOC_EVENT_OP: |
|---|
| 393 | copy_from_user (&ObjOper, (char *) ioctl_param, sizeof(OBJ_OPER)); |
|---|
| 394 | i = EventOperation (&ObjOper); |
|---|
| 395 | copy_to_user ((char *)ioctl_param, &ObjOper, sizeof(OBJ_OPER)); |
|---|
| 396 | return (i); |
|---|
| 397 | break; |
|---|
| 398 | |
|---|
| 399 | case DSTHWIOC_GET_VERSION: |
|---|
| 400 | copy_from_user (&i, (char *)ioctl_param, sizeof(DS_U32)); |
|---|
| 401 | i = lld_GetVersion(); |
|---|
| 402 | copy_to_user ((char *)ioctl_param, &i, sizeof (DS_U32)); |
|---|
| 403 | break; |
|---|
| 404 | |
|---|
| 405 | case DSTHWIOC_GET_LOADER_VER: |
|---|
| 406 | //printk("\nLoader Version %s\n",LoaderVer); |
|---|
| 407 | //i = *(int *)LoaderVer; |
|---|
| 408 | i=0; |
|---|
| 409 | i = ((GET_DS_U8_0(i) - 48) << 24 ) | ((GET_DS_U8_1(i) - 48) << 16 ) | ((GET_DS_U8_2(i) - 48) << 8 ) | ((GET_DS_U8_3(i) - 48) ); |
|---|
| 410 | return i; |
|---|
| 411 | break; |
|---|
| 412 | |
|---|
| 413 | case DSTHWIOC_TIME_STAMP: |
|---|
| 414 | time_stamp = dst_do_gettimeofday(); |
|---|
| 415 | copy_to_user((char *)ioctl_param, &time_stamp, sizeof(__s64)); |
|---|
| 416 | return(-1); |
|---|
| 417 | |
|---|
| 418 | case DSTHWIOC_SET_DBG_LEVEL: |
|---|
| 419 | { |
|---|
| 420 | DST_SET_DBG_LEVEL_MESSAGE_PARAMS params; |
|---|
| 421 | |
|---|
| 422 | copy_from_user ((char *) ¶ms, (char *) ioctl_param, sizeof (params)); |
|---|
| 423 | lld_dlevel (params.level); |
|---|
| 424 | break; |
|---|
| 425 | } |
|---|
| 426 | |
|---|
| 427 | case DSTHWIOC_IRQ_DISABLE: |
|---|
| 428 | flags = lld_os_disable_ints(); // disable interrupts |
|---|
| 429 | |
|---|
| 430 | copy_to_user ((char*)ioctl_param, (char*)&flags, sizeof(DS_U32)); |
|---|
| 431 | |
|---|
| 432 | break; |
|---|
| 433 | |
|---|
| 434 | case DSTHWIOC_IRQ_ENABLE: |
|---|
| 435 | lld_os_enable_ints(); // enable interrupts |
|---|
| 436 | |
|---|
| 437 | break; |
|---|
| 438 | |
|---|
| 439 | case DSTHWIOC_IRQ_RESTORE: |
|---|
| 440 | copy_from_user ((char*)&flags, (char*)ioctl_param, sizeof(DS_U32)); |
|---|
| 441 | |
|---|
| 442 | lld_os_restore_ints(flags); // restore interrupt status |
|---|
| 443 | |
|---|
| 444 | break; |
|---|
| 445 | |
|---|
| 446 | case DSTHWIOC_ATOMIC_REG_ACCESS: |
|---|
| 447 | copy_from_user (&ObjOper, (char *) ioctl_param, sizeof(OBJ_OPER)); |
|---|
| 448 | |
|---|
| 449 | if ( ObjOper.Opcode == OBJ_OPCODE_READ ) { |
|---|
| 450 | switch( ObjOper.Prm2 ) { |
|---|
| 451 | case 1: |
|---|
| 452 | if ( ObjOper.Prm1 >= 0xB5021300 && ObjOper.Prm1 <= 0xB50213FF) { |
|---|
| 453 | bTemp = *((DS_U8 *)0xB50213DF); |
|---|
| 454 | *((DS_U8 *)0xB50213DF) = 0; |
|---|
| 455 | } |
|---|
| 456 | |
|---|
| 457 | pbAddr = (DS_U8 *)ObjOper.Prm1; |
|---|
| 458 | ObjOper.Prm2 = *pbAddr; |
|---|
| 459 | |
|---|
| 460 | if ( ObjOper.Prm1 >= 0xB5021300 && ObjOper.Prm1 <= 0xB50213FF) { |
|---|
| 461 | *((DS_U8 *)0xB50213DF) |= bTemp & 1; |
|---|
| 462 | } |
|---|
| 463 | break; |
|---|
| 464 | |
|---|
| 465 | case 2: |
|---|
| 466 | pwAddr = (DS_U16 *)ObjOper.Prm1; |
|---|
| 467 | ObjOper.Prm2 = *pwAddr; |
|---|
| 468 | break; |
|---|
| 469 | |
|---|
| 470 | case 4: |
|---|
| 471 | default: |
|---|
| 472 | pdwAddr = (DS_U32 *)ObjOper.Prm1; |
|---|
| 473 | ObjOper.Prm2 = *pdwAddr; |
|---|
| 474 | } |
|---|
| 475 | } else { |
|---|
| 476 | switch( ObjOper.RetCode ) { |
|---|
| 477 | case 1: |
|---|
| 478 | if ( ObjOper.Prm1 >= 0xB5021300 && ObjOper.Prm1 <= 0xB50213FF) { |
|---|
| 479 | bTemp = *((DS_U8 *)0xB50213DF); |
|---|
| 480 | *((DS_U8 *)0xB50213DF) = 0; |
|---|
| 481 | } |
|---|
| 482 | |
|---|
| 483 | pbAddr = (DS_U8 *)ObjOper.Prm1; |
|---|
| 484 | *pbAddr = ObjOper.Prm2; |
|---|
| 485 | |
|---|
| 486 | if ( ObjOper.Prm1 >= 0xB5021300 && ObjOper.Prm1 <= 0xB50213FF) { |
|---|
| 487 | *((DS_U8 *)0xB50213DF) |= bTemp & 1; |
|---|
| 488 | } |
|---|
| 489 | |
|---|
| 490 | break; |
|---|
| 491 | |
|---|
| 492 | case 2: |
|---|
| 493 | pwAddr = (DS_U16 *)ObjOper.Prm1; |
|---|
| 494 | *pwAddr = ObjOper.Prm2; |
|---|
| 495 | break; |
|---|
| 496 | |
|---|
| 497 | case 4: |
|---|
| 498 | default: |
|---|
| 499 | pdwAddr = (DS_U32 *)ObjOper.Prm1; |
|---|
| 500 | *pdwAddr = ObjOper.Prm2; |
|---|
| 501 | } |
|---|
| 502 | } |
|---|
| 503 | |
|---|
| 504 | ObjOper.RetCode = OBJ_OK; |
|---|
| 505 | |
|---|
| 506 | copy_to_user ((char *)ioctl_param, &ObjOper, sizeof(OBJ_OPER)); |
|---|
| 507 | return (0); |
|---|
| 508 | break; |
|---|
| 509 | |
|---|
| 510 | default: |
|---|
| 511 | break; |
|---|
| 512 | } |
|---|
| 513 | |
|---|
| 514 | pdevice = pdevice; |
|---|
| 515 | return (0); |
|---|
| 516 | } |
|---|
| 517 | |
|---|
| 518 | /****************************************************************************** |
|---|
| 519 | *.device_ioctl (struct inode *inode, struct file *filp, |
|---|
| 520 | * unsigned int ioctl_num, unsigned long ioctl_param) |
|---|
| 521 | * Function: Entry point for the programs calling the specific |
|---|
| 522 | * IOCTLs. |
|---|
| 523 | * Inputs: struct inode *inode |
|---|
| 524 | * struct file *filp |
|---|
| 525 | * unsigned int ioctl_num - the number of the IOCTL being called |
|---|
| 526 | * unsigned int ioctl_param - the 'extra' data being sent |
|---|
| 527 | * Outputs: int |
|---|
| 528 | ******************************************************************************/ |
|---|
| 529 | static int device_ioctl (struct inode *inode, struct file *filp, |
|---|
| 530 | unsigned int ioctl_num, unsigned long ioctl_param) |
|---|
| 531 | { |
|---|
| 532 | int i; |
|---|
| 533 | DS_U32 org_filp; |
|---|
| 534 | |
|---|
| 535 | org_filp = current_filp; |
|---|
| 536 | current_filp = (DS_U32)filp; |
|---|
| 537 | i = ioctl_device (inode, filp, ioctl_num, ioctl_param); |
|---|
| 538 | current_filp = org_filp; |
|---|
| 539 | return (i); |
|---|
| 540 | } |
|---|
| 541 | |
|---|
| 542 | /****************************************************************************** |
|---|
| 543 | *.dst_do_gettimeofday() |
|---|
| 544 | * Function: Get the time of day |
|---|
| 545 | * Inputs: NONE |
|---|
| 546 | * Outputs: __s64 |
|---|
| 547 | ******************************************************************************/ |
|---|
| 548 | static __s64 dst_do_gettimeofday(void) |
|---|
| 549 | { |
|---|
| 550 | struct timeval t; |
|---|
| 551 | __s64 stamp; |
|---|
| 552 | do_gettimeofday(&t); |
|---|
| 553 | stamp = (__s64)t.tv_sec * 1000000 + t.tv_usec; |
|---|
| 554 | stamp *= 1000; |
|---|
| 555 | return stamp; |
|---|
| 556 | } |
|---|
| 557 | |
|---|