Changeset 44184 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Dec 19, 2012 7:48:22 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 82894
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c
r44173 r44184 96 96 static int VBoxDrvLinuxInit(void); 97 97 static void VBoxDrvLinuxUnload(void); 98 static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp); 98 static int VBoxDrvLinuxCreateSys(struct inode *pInode, struct file *pFilp); 99 static int VBoxDrvLinuxCreateUsr(struct inode *pInode, struct file *pFilp); 99 100 static int VBoxDrvLinuxClose(struct inode *pInode, struct file *pFilp); 100 101 #ifdef HAVE_UNLOCKED_IOCTL … … 103 104 static int VBoxDrvLinuxIOCtl(struct inode *pInode, struct file *pFilp, unsigned int uCmd, unsigned long ulArg); 104 105 #endif 105 static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg );106 static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg, PSUPDRVSESSION pSession); 106 107 static int VBoxDrvLinuxErr2LinuxErr(int); 107 108 #ifdef VBOX_WITH_SUSPEND_NOTIFICATION … … 127 128 128 129 #ifndef CONFIG_VBOXDRV_AS_MISC 129 /** Module major number */ 130 #define DEVICE_MAJOR 234 131 /** Saved major device number */ 132 static int g_iModuleMajor; 130 /** Module major number for vboxdrv. */ 131 #define DEVICE_MAJOR_SYS 234 132 /** Saved major device number for vboxdrv. */ 133 static int g_iModuleMajorSys; 134 /** Module major number for vboxdrvu. */ 135 #define DEVICE_MAJOR_USR 235 136 /** Saved major device number for vboxdrvu. */ 137 static int g_iModuleMajorUsr; 133 138 #endif /* !CONFIG_VBOXDRV_AS_MISC */ 134 139 … … 137 142 static int force_async_tsc = 0; 138 143 139 /** The module name. */ 140 #define DEVICE_NAME "vboxdrv" 144 /** The system device name. */ 145 #define DEVICE_NAME_SYS "vboxdrvu" 146 /** The user device name. */ 147 #define DEVICE_NAME_USR "vboxdrv" 141 148 142 149 #if defined(RT_ARCH_AMD64) && !defined(CONFIG_DEBUG_SET_MODULE_RONX) … … 156 163 157 164 /** The file_operations structure. */ 158 static struct file_operations gFileOpsVBoxDrv =165 static struct file_operations gFileOpsVBoxDrvSys = 159 166 { 160 167 owner: THIS_MODULE, 161 open: VBoxDrvLinuxCreate ,168 open: VBoxDrvLinuxCreateSys, 162 169 release: VBoxDrvLinuxClose, 163 170 #ifdef HAVE_UNLOCKED_IOCTL … … 168 175 }; 169 176 177 /** The file_operations structure. */ 178 static struct file_operations gFileOpsVBoxDrvUsr = 179 { 180 owner: THIS_MODULE, 181 open: VBoxDrvLinuxCreateUsr, 182 release: VBoxDrvLinuxClose, 183 #ifdef HAVE_UNLOCKED_IOCTL 184 unlocked_ioctl: VBoxDrvLinuxIOCtl, 185 #else 186 ioctl: VBoxDrvLinuxIOCtl, 187 #endif 188 }; 189 170 190 #ifdef CONFIG_VBOXDRV_AS_MISC 171 /** The miscdevice structure . */172 static struct miscdevice gMiscDevice =191 /** The miscdevice structure for vboxdrv. */ 192 static struct miscdevice gMiscDeviceSys = 173 193 { 174 194 minor: MISC_DYNAMIC_MINOR, 175 name: DEVICE_NAME ,176 fops: &gFileOpsVBoxDrv ,195 name: DEVICE_NAME_SYS, 196 fops: &gFileOpsVBoxDrvSys, 177 197 # if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17) 178 devfs_name: DEVICE_NAME, 198 devfs_name: DEVICE_NAME_SYS, 199 # endif 200 }; 201 /** The miscdevice structure for vboxdrvu. */ 202 static struct miscdevice gMiscDeviceUsr = 203 { 204 minor: MISC_DYNAMIC_MINOR, 205 name: DEVICE_NAME_USR, 206 fops: &gFileOpsVBoxDrvUsr, 207 # if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 17) 208 devfs_name: DEVICE_NAME_USR, 179 209 # endif 180 210 }; … … 260 290 * Check for synchronous/asynchronous TSC mode. 261 291 */ 262 printk(KERN_DEBUG DEVICE_NAME ": Found %u processor cores.\n", (unsigned)RTMpGetOnlineCount());292 printk(KERN_DEBUG "vboxdrv: Found %u processor cores.\n", (unsigned)RTMpGetOnlineCount()); 263 293 #ifdef CONFIG_VBOXDRV_AS_MISC 264 rc = misc_register(&gMiscDevice );294 rc = misc_register(&gMiscDeviceSys); 265 295 if (rc) 266 296 { 267 printk(KERN_ERR DEVICE_NAME ": Can't registermisc device! rc=%d\n", rc);297 printk(KERN_ERR "vboxdrv: Can't register system misc device! rc=%d\n", rc); 268 298 return rc; 269 299 } 300 rc = misc_register(&gMiscDeviceUsr); 301 if (rc) 302 { 303 printk(KERN_ERR "vboxdrv: Can't register user misc device! rc=%d\n", rc); 304 misc_deregister(&gMiscDeviceSys); 305 return rc; 306 } 270 307 #else /* !CONFIG_VBOXDRV_AS_MISC */ 271 308 /* 272 * Register character device. 273 */ 274 g_iModuleMajor = DEVICE_MAJOR; 275 rc = register_chrdev((dev_t)g_iModuleMajor, DEVICE_NAME, &gFileOpsVBoxDrv); 309 * Register character devices and save the returned major numbers. 310 */ 311 /* /dev/vboxdrv */ 312 g_iModuleMajorSys = DEVICE_MAJOR_SYS; 313 rc = register_chrdev((dev_t)g_iModuleMajorSys, DEVICE_NAME_SYS, &gFileOpsVBoxDrvSys); 276 314 if (rc < 0) 277 315 { 278 Log(("register_chrdev() failed with rc=%#x !\n", rc));316 Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc)); 279 317 return rc; 280 318 } 281 282 /* 283 * Save returned module major number 284 */ 285 if (DEVICE_MAJOR != 0) 286 g_iModuleMajor = DEVICE_MAJOR; 319 if (DEVICE_MAJOR_SYS != 0) 320 g_iModuleMajorSys = DEVICE_MAJOR_SYS; 287 321 else 288 g_iModuleMajor = rc; 322 g_iModuleMajorSys = rc; 323 324 /* /dev/vboxdrvu */ 325 /** @todo Use a minor number of this bugger (not sure if this code is used 326 * though, so not bothering right now.) */ 327 g_iModuleMajorUsr = DEVICE_MAJOR_USR; 328 rc = register_chrdev((dev_t)g_iModuleMajorUsr, DEVICE_NAME_USR, &gFileOpsVBoxDrvUsr); 329 if (rc < 0) 330 { 331 Log(("register_chrdev() failed with rc=%#x for vboxdrv!\n", rc)); 332 return rc; 333 } 334 if (DEVICE_MAJOR_USR != 0) 335 g_iModuleMajorUsr = DEVICE_MAJOR_USR; 336 else 337 g_iModuleMajorUsr = rc; 289 338 rc = 0; 290 339 … … 293 342 * Register a device entry 294 343 */ 295 if (devfs_mk_cdev(MKDEV(DEVICE_MAJOR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME) != 0) 344 if ( devfs_mk_cdev(MKDEV(DEVICE_MAJOR_SYS, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_SYS) != 0 345 || devfs_mk_cdev(MKDEV(DEVICE_MAJOR_USR, 0), S_IFCHR | VBOX_DEV_FMASK, DEVICE_NAME_USR) != 0) 296 346 { 297 347 Log(("devfs_register failed!\n")); … … 330 380 #endif 331 381 { 332 printk(KERN_INFO DEVICE_NAME ": TSC mode is %s, kernel timer mode is 'normal'.\n",382 printk(KERN_INFO "vboxdrv: TSC mode is %s, kernel timer mode is 'normal'.\n", 333 383 g_DevExt.pGip->u32Mode == SUPGIPMODE_SYNC_TSC ? "'synchronous'" : "'asynchronous'"); 334 384 LogFlow(("VBoxDrv::ModuleInit returning %#x\n", rc)); 335 printk(KERN_DEBUG DEVICE_NAME ": Successfully loaded version "385 printk(KERN_DEBUG "vboxdrv: Successfully loaded version " 336 386 VBOX_VERSION_STRING " (interface " RT_XSTR(SUPDRV_IOC_VERSION) ").\n"); 337 387 return rc; … … 354 404 */ 355 405 #if defined(CONFIG_DEVFS_FS) && !defined(CONFIG_VBOXDRV_AS_MISC) 356 devfs_remove(DEVICE_NAME); 406 devfs_remove(DEVICE_NAME_SYS); 407 devfs_remove(DEVICE_NAME_USR); 357 408 #endif 358 409 } 359 410 #ifdef CONFIG_VBOXDRV_AS_MISC 360 misc_deregister(&gMiscDevice); 361 Log(("VBoxDrv::ModuleInit returning %#x (minor:%d)\n", rc, gMiscDevice.minor)); 411 misc_deregister(&gMiscDeviceSys); 412 misc_deregister(&gMiscDeviceUsr); 413 Log(("VBoxDrv::ModuleInit returning %#x (minor:%d & %d)\n", rc, gMiscDeviceSys.minor, gMiscDeviceUsr.minor)); 362 414 #else 363 unregister_chrdev(g_iModuleMajor, DEVICE_NAME); 364 Log(("VBoxDrv::ModuleInit returning %#x (major:%d)\n", rc, g_iModuleMajor)); 415 unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR); 416 unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS); 417 Log(("VBoxDrv::ModuleInit returning %#x (major:%d & %d)\n", rc, g_iModuleMajorSys, g_iModuleMajorUsr)); 365 418 #endif 366 419 return rc; … … 387 440 */ 388 441 #ifdef CONFIG_VBOXDRV_AS_MISC 389 rc = misc_deregister(&gMiscDevice );442 rc = misc_deregister(&gMiscDeviceUsr); 390 443 if (rc < 0) 391 444 { 392 Log(("misc_deregister failed with rc=%#x\n", rc)); 445 Log(("misc_deregister failed with rc=%#x on vboxdrvu\n", rc)); 446 } 447 rc = misc_deregister(&gMiscDeviceSys); 448 if (rc < 0) 449 { 450 Log(("misc_deregister failed with rc=%#x on vboxdrv\n", rc)); 393 451 } 394 452 #else /* !CONFIG_VBOXDRV_AS_MISC */ … … 397 455 * Unregister a device entry 398 456 */ 399 devfs_remove(DEVICE_NAME); 457 devfs_remove(DEVICE_NAME_USR); 458 devfs_remove(DEVICE_NAME_SYS); 400 459 # endif /* devfs */ 401 unregister_chrdev(g_iModuleMajor, DEVICE_NAME); 460 unregister_chrdev(g_iModuleMajorUsr, DEVICE_NAME_USR); 461 unregister_chrdev(g_iModuleMajorSys, DEVICE_NAME_SYS); 402 462 #endif /* !CONFIG_VBOXDRV_AS_MISC */ 403 463 … … 411 471 412 472 /** 413 * Device open. Called on open /dev/vboxdrv 414 * 415 * @param pInode Pointer to inode info structure. 416 * @param pFilp Associated file pointer. 417 */ 418 static int VBoxDrvLinuxCreate(struct inode *pInode, struct file *pFilp) 473 * Common open code. 474 * 475 * @param pInode Pointer to inode info structure. 476 * @param pFilp Associated file pointer. 477 * @param fUnrestricted Indicates which device node which was opened. 478 */ 479 static int VBoxDrvLinuxCreateCommon(struct inode *pInode, struct file *pFilp, bool fUnrestricted) 419 480 { 420 481 int rc; … … 436 497 * Call common code for the rest. 437 498 */ 438 rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);499 rc = supdrvCreateSession(&g_DevExt, true /* fUser */, fUnrestricted, &pSession); 439 500 if (!rc) 440 501 { … … 449 510 RTProcSelf(), current->pid, current->comm)); 450 511 return VBoxDrvLinuxErr2LinuxErr(rc); 512 } 513 514 515 /** /dev/vboxdrv. */ 516 static int VBoxDrvLinuxCreateSys(struct inode *pInode, struct file *pFilp) 517 { 518 return vboxdrvLinuxCreateCommon(pInode, pFilp, true); 519 } 520 521 522 /** /dev/vboxdrvu. */ 523 static int VBoxDrvLinuxCreateUsr(struct inode *pInode, struct file *pFilp) 524 { 525 return vboxdrvLinuxCreateCommon(pInode, pFilp, false); 451 526 } 452 527 … … 534 609 #endif 535 610 { 611 PSUPDRVSESSION pSession = (PSUPDRVSESSION)pFilp->private_data; 612 536 613 /* 537 614 * Deal with the two high-speed IOCtl that takes it's arguments from … … 539 616 */ 540 617 #ifdef HAVE_UNLOCKED_IOCTL 541 if (RT_LIKELY( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 542 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN 543 || uCmd == SUP_IOCTL_FAST_DO_NOP)) 544 return supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data); 545 return VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg); 618 if (RT_LIKELY( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 619 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN 620 || uCmd == SUP_IOCTL_FAST_DO_NOP) 621 && pSession->fUnrestricted == true)) 622 return supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, pSession); 623 return VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg, pSession); 546 624 547 625 #else /* !HAVE_UNLOCKED_IOCTL */ … … 549 627 int rc; 550 628 unlock_kernel(); 551 if (RT_LIKELY( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 552 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN 553 || uCmd == SUP_IOCTL_FAST_DO_NOP)) 554 rc = supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data); 629 if (RT_LIKELY( ( uCmd == SUP_IOCTL_FAST_DO_RAW_RUN 630 || uCmd == SUP_IOCTL_FAST_DO_HM_RUN 631 || uCmd == SUP_IOCTL_FAST_DO_NOP) 632 && pSession->fUnrestricted == true)) 633 rc = supdrvIOCtlFast(uCmd, ulArg, &g_DevExt, pSession); 555 634 else 556 rc = VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg );635 rc = VBoxDrvLinuxIOCtlSlow(pFilp, uCmd, ulArg, pSession); 557 636 lock_kernel(); 558 637 return rc; … … 567 646 * @param uCmd The function specified to ioctl(). 568 647 * @param ulArg The argument specified to ioctl(). 569 */ 570 static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg) 648 * @param pSession The session instance. 649 */ 650 static int VBoxDrvLinuxIOCtlSlow(struct file *pFilp, unsigned int uCmd, unsigned long ulArg, PSUPDRVSESSION pSession) 571 651 { 572 652 int rc; … … 621 701 * Process the IOCtl. 622 702 */ 623 rc = supdrvIOCtl(uCmd, &g_DevExt, (PSUPDRVSESSION)pFilp->private_data, pHdr);703 rc = supdrvIOCtl(uCmd, &g_DevExt, pSession, pHdr); 624 704 625 705 /*
Note:
See TracChangeset
for help on using the changeset viewer.