Changeset 4178 in vbox for trunk/src/VBox/HostDrivers/Support/solaris
- Timestamp:
- Aug 16, 2007 3:07:51 PM (17 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support/solaris
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
r4071 r4178 32 32 #include <sys/ddi.h> 33 33 #include <sys/sunddi.h> 34 #include <sys/file.h> 34 35 35 36 #include "SUPDRV.h" … … 37 38 #include <iprt/process.h> 38 39 #include <iprt/initterm.h> 40 #include <iprt/alloc.h> 39 41 40 42 … … 54 56 static int VBoxDrvSolarisRead(dev_t Dev, struct uio* pUio, cred_t* pCred); 55 57 static int VBoxDrvSolarisWrite(dev_t Dev, struct uio* pUio, cred_t* pCred); 56 static int VBoxDrvSolarisI octl (dev_t Dev, int Cmd, intptr_t Arg, int mode,cred_t* pCred, int* pVal);58 static int VBoxDrvSolarisIOCtl (dev_t Dev, int Cmd, intptr_t pArgs, int mode, cred_t* pCred, int* pVal); 57 59 58 60 static int VBoxDrvSolarisAttach(dev_info_t* pDip, ddi_attach_cmd_t Cmd); 59 61 static int VBoxDrvSolarisDetach(dev_info_t* pDip, ddi_detach_cmd_t Cmd); 60 62 61 static int VBoxDrvSolarisErr2Native(int rc); 63 static int VBoxSupDrvErr2SolarisErr(int rc); 64 static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int Cmd, int Mode, intptr_t pArgs); 62 65 63 66 … … 77 80 VBoxDrvSolarisRead, 78 81 VBoxDrvSolarisWrite, 79 VBoxDrvSolarisI octl,82 VBoxDrvSolarisIOCtl, 80 83 nodev, /* c devmap */ 81 84 nodev, /* c mmap */ … … 100 103 VBoxDrvSolarisAttach, 101 104 VBoxDrvSolarisDetach, 102 nodev, /* reset */105 nodev, /* reset */ 103 106 &g_VBoxDrvSolarisCbOps, 104 107 (struct bus_ops *)0, … … 126 129 }; 127 130 128 /** Track module instances */ 129 dev_info_t* g_pVBoxDrvSolarisDip; 131 /** State info. each our kernel module instances */ 132 typedef struct 133 { 134 dev_info_t* pDip; /* Device handle */ 135 } vbox_devstate_t; 130 136 131 137 /** Opaque pointer to state */ … … 152 158 cmn_err(CE_CONT, "VBoxDrvSolaris _init"); 153 159 154 int e = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof ( g_pVBoxDrvSolarisDip), 1);160 int e = ddi_soft_state_init(&g_pVBoxDrvSolarisState, sizeof (vbox_devstate_t), 1); 155 161 if (e != 0) 156 162 return e; … … 175 181 } 176 182 177 int _info (struct modinfo *pModInfo)183 int _info (struct modinfo *pModInfo) 178 184 { 179 185 cmn_err(CE_CONT, "VBoxDrvSolaris _info"); … … 184 190 * User context entry points 185 191 */ 186 static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)192 static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred) 187 193 { 188 194 cmn_err(CE_CONT, "VBoxDrvSolarisOpen"); … … 193 199 /* 194 200 * Create a new session. 195 */ 196 #if 1 197 rc = VINF_SUCCESS; 198 #else 201 * Sessions in Solaris driver are mostly useless. It's however needed 202 * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl() 203 */ 199 204 rc = supdrvCreateSession(&g_DevExt, &pSession); 200 205 if (RT_SUCCESS(rc)) 201 206 { 207 cmn_err(CE_NOTE,"supdrvCreateSession success"); 202 208 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 203 209 unsigned iHash; … … 216 222 g_apSessionHashTab[iHash] = pSession; 217 223 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp); 218 } 219 #endif 220 return VBoxDrvSolarisErr2Native(rc); 221 } 222 223 static int VBoxDrvSolarisClose(dev_t pDev, int flag, int otyp, cred_t* cred) 224 cmn_err(CE_NOTE,"VBoxDrvSolarisOpen success"); 225 } 226 227 return VBoxSupDrvErr2SolarisErr(rc); 228 } 229 230 static int VBoxDrvSolarisClose(dev_t pDev, int flag, int otyp, cred_t *cred) 224 231 { 225 232 cmn_err(CE_CONT, "VBoxDrvSolarisClose"); 233 234 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 235 const RTPROCESS Process = RTProcSelf(); 236 const unsigned iHash = SESSION_HASH(Process); 237 PSUPDRVSESSION pSession; 238 239 /* 240 * Remove from the hash table. 241 */ 242 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp); 243 pSession = g_apSessionHashTab[iHash]; 244 if (pSession) 245 { 246 if (pSession->Process == Process) 247 { 248 g_apSessionHashTab[iHash] = pSession->pNextHash; 249 pSession->pNextHash = NULL; 250 } 251 else 252 { 253 PSUPDRVSESSION pPrev = pSession; 254 pSession = pSession->pNextHash; 255 while (pSession) 256 { 257 if (pSession->Process == Process) 258 { 259 pPrev->pNextHash = pSession->pNextHash; 260 pSession->pNextHash = NULL; 261 break; 262 } 263 264 /* next */ 265 pPrev = pSession; 266 pSession = pSession->pNextHash; 267 } 268 } 269 } 270 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp); 271 if (!pSession) 272 { 273 OSDBGPRINT(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", 274 (int)Process)); 275 return DDI_FAILURE; 276 } 277 278 /* 279 * Close the session. 280 */ 281 supdrvCloseSession(&g_DevExt, pSession); 226 282 return DDI_SUCCESS; 227 283 } … … 252 308 int rc = VINF_SUCCESS; 253 309 int instance = 0; 254 310 vbox_devstate_t* pState; 311 255 312 switch (enmCmd) 256 313 { … … 258 315 { 259 316 instance = ddi_get_instance (pDip); 260 g_pVBoxDrvSolarisDip = pDip;261 317 262 318 if (ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, instance) != DDI_SUCCESS) … … 265 321 return DDI_FAILURE; 266 322 } 267 323 324 pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); 325 268 326 /* 269 327 * Initialize IPRT R0 driver, which internally calls OS-specific r0 init. … … 281 339 * Initialize the session hash table. 282 340 */ 283 //memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab));284 //rc = RTSpinlockCreate(&g_Spinlock);341 memset(g_apSessionHashTab, 0, sizeof(g_apSessionHashTab)); 342 rc = RTSpinlockCreate(&g_Spinlock); 285 343 if (RT_SUCCESS(rc)) 286 344 { … … 288 346 * Register ourselves as a character device, pseudo-driver 289 347 */ 290 if (ddi_create_minor_node( g_pVBoxDrvSolarisDip, "0", S_IFCHR,348 if (ddi_create_minor_node(pDip, "0", S_IFCHR, 291 349 instance, DDI_PSEUDO, 0) == DDI_SUCCESS) 292 350 { 351 pState->pDip = pDip; 352 ddi_report_dev(pDip); 353 293 354 cmn_err(CE_CONT, "VBoxDrvSolarisAttach: successful."); 294 355 return DDI_SUCCESS; … … 296 357 297 358 /* Is this really necessary? */ 298 ddi_remove_minor_node( g_pVBoxDrvSolarisDip, NULL);359 ddi_remove_minor_node(pDip, NULL); 299 360 cmn_err(CE_NOTE,"VBoxDrvSolarisAttach: ddi_create_minor_node failed."); 300 361 301 //RTSpinlockDestroy(g_Spinlock);302 //g_Spinlock = NIL_RTSPINLOCK;362 RTSpinlockDestroy(g_Spinlock); 363 g_Spinlock = NIL_RTSPINLOCK; 303 364 } 304 365 else 305 366 cmn_err(CE_NOTE, "VBoxDrvSolarisAttach: RTSpinlockCreate failed"); 306 //supdrvDeleteDevExt(&g_DevExt);367 supdrvDeleteDevExt(&g_DevExt); 307 368 } 308 369 else … … 312 373 else 313 374 cmn_err(CE_NOTE, "VBoxDrvSolarisAttach: failed to init R0Drv"); 314 //memset(&g_DevExt, 0, sizeof(g_DevExt));375 memset(&g_DevExt, 0, sizeof(g_DevExt)); 315 376 break; 316 377 } … … 331 392 * @return corresponding solaris error code. 332 393 */ 333 static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd)394 static int VBoxDrvSolarisDetach(dev_info_t *pDip, ddi_detach_cmd_t enmCmd) 334 395 { 335 396 int rc = VINF_SUCCESS; 336 int instance = ddi_get_instance(pDip); 397 int instance; 398 register vbox_devstate_t* pState; 337 399 338 400 cmn_err(CE_CONT, "VBoxDrvSolarisDetach"); … … 341 403 case DDI_DETACH: 342 404 { 343 g_pVBoxDrvSolarisDip = NULL; 344 ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); 405 instance = ddi_get_instance(pDip); 406 pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); 407 345 408 ddi_remove_minor_node(pDip, NULL); 346 409 ddi_soft_state_free(g_pVBoxDrvSolarisState, instance); 410 411 rc = supdrvDeleteDevExt(&g_DevExt); 412 AssertRC(rc); 413 414 rc = RTSpinlockDestroy(g_Spinlock); 415 AssertRC(rc); 416 g_Spinlock = NIL_RTSPINLOCK; 417 418 RTR0Term(); 419 420 memset(&g_DevExt, 0, sizeof(g_DevExt)); 347 421 cmn_err(CE_CONT, "VBoxDrvSolarisDetach: Clean Up Done."); 348 349 //rc = supdrvDeleteDevExt(&g_DevExt);350 //AssertRC(rc);351 352 //rc = RTSpinlockDestroy(g_Spinlock);353 //AssertRC(rc);354 //g_Spinlock = NIL_RTSPINLOCK;355 356 RTR0Term();357 358 memset(&g_DevExt, 0, sizeof(g_DevExt));359 360 422 return DDI_SUCCESS; 361 423 } … … 371 433 * @param Dev Device number 372 434 * @param Cmd Operation identifier 373 * @param ArgArguments from user to driver374 * @param Mode Information bitfield (read/write, address space etc )435 * @param pArg Arguments from user to driver 436 * @param Mode Information bitfield (read/write, address space etc.) 375 437 * @param pCred User credentials 376 438 * @param pVal Return value for calling process. … … 378 440 * @return corresponding solaris error code. 379 441 */ 380 static int VBoxDrvSolarisIoctl(dev_t Dev, int Cmd, intptr_t Arg, int Mode, cred_t* pCred, int* pVal) 381 { 382 cmn_err(CE_CONT, "VBoxDrvSolarisIoctl"); 383 return DDI_SUCCESS; 384 } 385 386 /** 387 * Converts an supdrv error code to a Solaris error code. 388 * 389 * @returns corresponding Solaris error code. 442 static int VBoxDrvSolarisIOCtl (dev_t Dev, int Cmd, intptr_t pArgs, int Mode, cred_t* pCred, int* pVal) 443 { 444 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 445 const RTPROCESS Process = RTProcSelf(); 446 const unsigned iHash = SESSION_HASH(Process); 447 PSUPDRVSESSION pSession; 448 449 cmn_err(CE_CONT, "VBoxDrvSolarisIOCtl\n"); 450 /* 451 * Find the session. 452 */ 453 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp); 454 pSession = g_apSessionHashTab[iHash]; 455 if (pSession && pSession->Process != Process) 456 { 457 do pSession = pSession->pNextHash; 458 while (pSession && pSession->Process != Process); 459 } 460 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp); 461 if (!pSession) 462 { 463 OSDBGPRINT(("VBoxSupDrvIOCtl: WHAT?!? pSession == NULL! This must be a mistake... pid=%d iCmd=%#x\n", 464 (int)Process, Cmd)); 465 return EINVAL; 466 } 467 468 /* 469 * Deal with the two high-speed IOCtl that takes it's arguments from 470 * the session and iCmd, and only returns a VBox status code. 471 */ 472 #ifdef VBOX_WITHOUT_IDT_PATCHING 473 if ( Cmd == SUP_IOCTL_FAST_DO_RAW_RUN 474 || Cmd == SUP_IOCTL_FAST_DO_HWACC_RUN 475 || Cmd == SUP_IOCTL_FAST_DO_NOP) 476 return supdrvIOCtlFast(Cmd, &g_DevExt, pSession); 477 #endif 478 479 return VBoxDrvSolarisIOCtlSlow(pSession, Cmd, Mode, pArgs); 480 } 481 482 /** 483 * Worker for VBoxSupDrvIOCtl that takes the slow IOCtl functions. 484 * 485 * @returns Solaris errno. 486 * 487 * @param pSession The session. 488 * @param Cmd The IOCtl command. 489 * @param Mode Information bitfield (for specifying ownership of data) 490 * @param pArgs Pointer to the kernel copy of the SUPDRVIOCTLDATA buffer. 491 */ 492 static int VBoxDrvSolarisIOCtlSlow(PSUPDRVSESSION pSession, int Cmd, int Mode, intptr_t pArgs) 493 { 494 int rc; 495 void *pvBuf = NULL; 496 unsigned long cbBuf = 0; 497 unsigned cbOut = 0; 498 PSUPDRVIOCTLDATA pArgData = (PSUPDRVIOCTLDATA)pArgs; 499 500 cmn_err(CE_CONT, "VBoxDrvSolarisIOCtlSlow\n"); 501 /* 502 * Allocate and copy user space input data buffer to kernel space. 503 */ 504 if (pArgData->cbIn > 0 || pArgData->cbOut > 0) 505 { 506 cbBuf = max(pArgData->cbIn, pArgData->cbOut); 507 pvBuf = RTMemTmpAlloc(cbBuf); 508 509 if (pvBuf == NULL) 510 { 511 OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: failed to allocate buffer of %d bytes.\n", cbBuf)); 512 return ENOMEM; 513 } 514 515 rc = ddi_copyin(pArgData->pvIn, pvBuf, cbBuf, Mode); 516 517 if (rc != 0) 518 { 519 OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: ddi_copyin(%p,%d) failed.\n", pArgData->pvIn, cbBuf)); 520 521 RTMemTmpFree(pvBuf); 522 return EFAULT; 523 } 524 } 525 526 /* 527 * Process the IOCtl. 528 */ 529 rc = supdrvIOCtl(Cmd, &g_DevExt, pSession, pvBuf, pArgData->cbIn, pvBuf, pArgData->cbOut, &cbOut); 530 531 /* 532 * Copy ioctl data and output buffer back to user space. 533 */ 534 if (rc != 0) 535 rc = VBoxSupDrvErr2SolarisErr(rc); 536 else if (cbOut > 0) 537 { 538 if (pvBuf != NULL && cbOut <= cbBuf) 539 { 540 rc = ddi_copyout(pvBuf, pArgData->pvOut, cbOut, Mode); 541 if (rc != 0) 542 OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: ddi_copyout(,%p,%d) failed.\n", pArgData->pvOut, cbBuf)); 543 } 544 else 545 { 546 OSDBGPRINT(("WHAT!?! supdrvIOCtl messed up! cbOut=%d cbBuf=%d pvBuf=%p\n", cbOut, cbBuf, pvBuf)); 547 rc = EPERM; 548 } 549 } 550 551 OSDBGPRINT(("VBoxDrvSolarisIOCtlSlow: returns %d cbOut=%d\n", rc, cbOut)); 552 return rc; 553 } 554 555 556 /** 557 * Converts an supdrv error code to a solaris error code. 558 * 559 * @returns corresponding solaris error code. 390 560 * @param rc supdrv error code (SUPDRV_ERR_* defines). 391 561 */ 392 static int VBox DrvSolarisErr2Native(int rc)562 static int VBoxSupDrvErr2SolarisErr(int rc) 393 563 { 394 564 switch (rc) … … 408 578 return EPERM; 409 579 } 580 581 /** 582 * Initializes any OS specific object creator fields. 583 */ 584 void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession) 585 { 586 NOREF(pObj); 587 NOREF(pSession); 588 } 589 590 591 /** 592 * Checks if the session can access the object. 593 * 594 * @returns true if a decision has been made. 595 * @returns false if the default access policy should be applied. 596 * 597 * @param pObj The object in question. 598 * @param pSession The session wanting to access the object. 599 * @param pszObjName The object name, can be NULL. 600 * @param prc Where to store the result when returning true. 601 */ 602 bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc) 603 { 604 NOREF(pObj); 605 NOREF(pSession); 606 NOREF(pszObjName); 607 NOREF(prc); 608 return false; 609 } 610 611 RTDECL(int) SUPR0Printf(const char *pszFormat, ...) 612 { 613 va_list args; 614 char szMsg[512]; 615 616 va_start(args, pszFormat); 617 vsnprintf(szMsg, sizeof(szMsg) - 1, pszFormat, args); 618 va_end(args); 619 620 szMsg[sizeof(szMsg) - 1] = '\0'; 621 printf("%s", szMsg); 622 return 0; 623 } -
trunk/src/VBox/HostDrivers/Support/solaris/SUPLib-solaris.cpp
r4071 r4178 1 /* $Id$ */ 1 2 /** @file 2 3 * … … 37 38 #include <sys/fcntl.h> 38 39 #include <sys/ioctl.h> 40 39 41 #include <fcntl.h> 40 42 #include <errno.h> 41 43 #include <unistd.h> 42 44 #include <stdlib.h> 45 #include <stdio.h> 43 46 44 47 … … 46 49 * Defined Constants And Macros * 47 50 *******************************************************************************/ 48 #define DEVICE_NAME "/dev /vboxdrv"51 #define DEVICE_NAME "/devices/pseudo/vboxdrv@0:0" 49 52 50 53 … … 150 153 151 154 if (ioctl(g_hDevice, uFunction, &Args) >= 0) 152 return 0; 153 /* This is the reverse operation of the one found in SUPDrv-linux.c */ 155 return 0; 156 157 /* This is the reverse operation of the one found in SUPDrv-solaris.c */ 154 158 switch (errno) 155 159 { 156 160 case EACCES: return VERR_GENERAL_FAILURE; 157 161 case EINVAL: return VERR_INVALID_PARAMETER; 158 case ENOSYS: return VERR_INVALID_MAGIC; 162 case EILSEQ: return VERR_INVALID_MAGIC; 163 case ENOSYS: return VERR_VERSION_MISMATCH; 159 164 case ENXIO: return VERR_INVALID_HANDLE; 160 165 case EFAULT: return VERR_INVALID_POINTER; 161 166 case ENOLCK: return VERR_LOCK_FAILED; 162 167 case EEXIST: return VERR_ALREADY_LOADED; 168 case EPERM: return VERR_PERMISSION_DENIED; 163 169 } 164 170
Note:
See TracChangeset
for help on using the changeset viewer.