Changeset 4868 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Sep 17, 2007 7:30:19 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/solaris/SUPDrv-solaris.c
r4851 r4868 210 210 } 211 211 212 /**213 * User context entry points214 */215 static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred)216 {217 int rc;218 PSUPDRVSESSION pSession;219 dprintf(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev));220 221 #ifndef USE_SESSION_HASH222 /*223 * Locate a new device open instance.224 *225 * For each open call we'll allocate an item in the soft state of the device.226 * The item index is stored in the dev_t. I hope this is ok...227 */228 vbox_devstate_t *pState = NULL;229 unsigned iOpenInstance;230 for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++)231 {232 if ( !ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance) /* faster */233 && ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, iOpenInstance) == DDI_SUCCESS)234 {235 pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance);236 break;237 }238 }239 if (!pState)240 {241 cmn_err(CE_NOTE,"VBoxDrvSolarisOpen: too many open instances.");242 return ENXIO;243 }244 245 /*246 * Create a new session.247 */248 rc = supdrvCreateSession(&g_DevExt, &pSession);249 if (RT_SUCCESS(rc))250 {251 pState->pSession = pSession;252 *pDev = makedevice(getmajor(*pDev), iOpenInstance);253 dprintf(("VBoxDrvSolarisOpen: returns pDev=%#x pSession=%p pState=%p\n", *pDev, pSession, pState));254 return 0;255 }256 257 /* failed - clean up */258 ddi_soft_state_free(g_pVBoxDrvSolarisState, iOpenInstance);259 260 #else261 /*262 * Create a new session.263 * Sessions in Solaris driver are mostly useless. It's however needed264 * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl()265 */266 rc = supdrvCreateSession(&g_DevExt, &pSession);267 if (RT_SUCCESS(rc))268 {269 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;270 unsigned iHash;271 272 pSession->Uid = crgetuid(pCred);273 pSession->Gid = crgetgid(pCred);274 pSession->Process = RTProcSelf();275 pSession->R0Process = RTR0ProcHandleSelf();276 277 /*278 * Insert it into the hash table.279 */280 iHash = SESSION_HASH(pSession->Process);281 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);282 pSession->pNextHash = g_apSessionHashTab[iHash];283 g_apSessionHashTab[iHash] = pSession;284 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);285 cmn_err(CE_NOTE,"VBoxDrvSolarisOpen success");286 }287 288 int instance;289 for (instance = 0; instance < DEVICE_MAXINSTANCES; instance++)290 {291 vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance);292 if (pState)293 break;294 }295 296 if (instance >= DEVICE_MAXINSTANCES)297 {298 cmn_err(CE_NOTE, "VBoxDrvSolarisOpen: All instances exhausted\n");299 return ENXIO;300 }301 302 *pDev = makedevice(getmajor(*pDev), instance);303 304 return VBoxSupDrvErr2SolarisErr(rc);305 #endif306 }307 308 309 static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred)310 {311 dprintf(("VBoxDrvSolarisClose: Dev=%#x\n", Dev));312 #ifndef USE_SESSION_HASH313 /*314 * Get the session and free the soft state item.315 */316 vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev));317 if (!pState)318 {319 OSDBGPRINT(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev)));320 return DDI_SUCCESS;321 }322 323 PSUPDRVSESSION pSession = pState->pSession;324 pState->pSession = NULL;325 ddi_soft_state_free(g_pVBoxDrvSolarisState, getminor(Dev));326 327 if (!pSession)328 {329 OSDBGPRINT(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev)));330 return DDI_SUCCESS;331 }332 333 #else334 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER;335 const RTPROCESS Process = RTProcSelf();336 const unsigned iHash = SESSION_HASH(Process);337 PSUPDRVSESSION pSession;338 339 /*340 * Remove from the hash table.341 */342 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp);343 pSession = g_apSessionHashTab[iHash];344 if (pSession)345 {346 if (pSession->Process == Process)347 {348 g_apSessionHashTab[iHash] = pSession->pNextHash;349 pSession->pNextHash = NULL;350 }351 else352 {353 PSUPDRVSESSION pPrev = pSession;354 pSession = pSession->pNextHash;355 while (pSession)356 {357 if (pSession->Process == Process)358 {359 pPrev->pNextHash = pSession->pNextHash;360 pSession->pNextHash = NULL;361 break;362 }363 364 /* next */365 pPrev = pSession;366 pSession = pSession->pNextHash;367 }368 }369 }370 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp);371 if (!pSession)372 {373 OSDBGPRINT(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n",374 (int)Process));375 return DDI_FAILURE;376 }377 #endif378 379 /*380 * Close the session.381 */382 supdrvCloseSession(&g_DevExt, pSession);383 return DDI_SUCCESS;384 }385 386 387 static int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred)388 {389 cmn_err(CE_CONT, "VBoxDrvSolarisRead");390 return DDI_SUCCESS;391 }392 393 394 static int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred)395 {396 cmn_err(CE_CONT, "VBoxDrvSolarisWrite");397 return DDI_SUCCESS;398 }399 212 400 213 /** … … 487 300 } 488 301 302 489 303 /** 490 304 * Detach entry point, to detach a device to the system or suspend it. … … 531 345 } 532 346 } 347 348 349 350 /** 351 * User context entry points 352 */ 353 static int VBoxDrvSolarisOpen(dev_t *pDev, int fFlag, int fType, cred_t *pCred) 354 { 355 int rc; 356 PSUPDRVSESSION pSession; 357 dprintf(("VBoxDrvSolarisOpen: pDev=%p:%#x\n", pDev, *pDev)); 358 359 #ifndef USE_SESSION_HASH 360 /* 361 * Locate a new device open instance. 362 * 363 * For each open call we'll allocate an item in the soft state of the device. 364 * The item index is stored in the dev_t. I hope this is ok... 365 */ 366 vbox_devstate_t *pState = NULL; 367 unsigned iOpenInstance; 368 for (iOpenInstance = 0; iOpenInstance < 4096; iOpenInstance++) 369 { 370 if ( !ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance) /* faster */ 371 && ddi_soft_state_zalloc(g_pVBoxDrvSolarisState, iOpenInstance) == DDI_SUCCESS) 372 { 373 pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, iOpenInstance); 374 break; 375 } 376 } 377 if (!pState) 378 { 379 cmn_err(CE_NOTE,"VBoxDrvSolarisOpen: too many open instances."); 380 return ENXIO; 381 } 382 383 /* 384 * Create a new session. 385 */ 386 rc = supdrvCreateSession(&g_DevExt, &pSession); 387 if (RT_SUCCESS(rc)) 388 { 389 pState->pSession = pSession; 390 *pDev = makedevice(getmajor(*pDev), iOpenInstance); 391 dprintf(("VBoxDrvSolarisOpen: returns pDev=%#x pSession=%p pState=%p\n", *pDev, pSession, pState)); 392 return 0; 393 } 394 395 /* failed - clean up */ 396 ddi_soft_state_free(g_pVBoxDrvSolarisState, iOpenInstance); 397 398 #else 399 /* 400 * Create a new session. 401 * Sessions in Solaris driver are mostly useless. It's however needed 402 * in VBoxDrvSolarisIOCtlSlow() while calling supdrvIOCtl() 403 */ 404 rc = supdrvCreateSession(&g_DevExt, &pSession); 405 if (RT_SUCCESS(rc)) 406 { 407 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 408 unsigned iHash; 409 410 pSession->Uid = crgetuid(pCred); 411 pSession->Gid = crgetgid(pCred); 412 pSession->Process = RTProcSelf(); 413 pSession->R0Process = RTR0ProcHandleSelf(); 414 415 /* 416 * Insert it into the hash table. 417 */ 418 iHash = SESSION_HASH(pSession->Process); 419 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp); 420 pSession->pNextHash = g_apSessionHashTab[iHash]; 421 g_apSessionHashTab[iHash] = pSession; 422 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp); 423 cmn_err(CE_NOTE,"VBoxDrvSolarisOpen success"); 424 } 425 426 int instance; 427 for (instance = 0; instance < DEVICE_MAXINSTANCES; instance++) 428 { 429 vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, instance); 430 if (pState) 431 break; 432 } 433 434 if (instance >= DEVICE_MAXINSTANCES) 435 { 436 cmn_err(CE_NOTE, "VBoxDrvSolarisOpen: All instances exhausted\n"); 437 return ENXIO; 438 } 439 440 *pDev = makedevice(getmajor(*pDev), instance); 441 442 return VBoxSupDrvErr2SolarisErr(rc); 443 #endif 444 } 445 446 447 static int VBoxDrvSolarisClose(dev_t Dev, int flag, int otyp, cred_t *cred) 448 { 449 dprintf(("VBoxDrvSolarisClose: Dev=%#x\n", Dev)); 450 #ifndef USE_SESSION_HASH 451 /* 452 * Get the session and free the soft state item. 453 */ 454 vbox_devstate_t *pState = ddi_get_soft_state(g_pVBoxDrvSolarisState, getminor(Dev)); 455 if (!pState) 456 { 457 OSDBGPRINT(("VBoxDrvSolarisClose: no state data for %#x (%d)\n", Dev, getminor(Dev))); 458 return DDI_SUCCESS; 459 } 460 461 PSUPDRVSESSION pSession = pState->pSession; 462 pState->pSession = NULL; 463 ddi_soft_state_free(g_pVBoxDrvSolarisState, getminor(Dev)); 464 465 if (!pSession) 466 { 467 OSDBGPRINT(("VBoxDrvSolarisClose: no session in state data for %#x (%d)\n", Dev, getminor(Dev))); 468 return DDI_SUCCESS; 469 } 470 471 #else 472 RTSPINLOCKTMP Tmp = RTSPINLOCKTMP_INITIALIZER; 473 const RTPROCESS Process = RTProcSelf(); 474 const unsigned iHash = SESSION_HASH(Process); 475 PSUPDRVSESSION pSession; 476 477 /* 478 * Remove from the hash table. 479 */ 480 RTSpinlockAcquireNoInts(g_Spinlock, &Tmp); 481 pSession = g_apSessionHashTab[iHash]; 482 if (pSession) 483 { 484 if (pSession->Process == Process) 485 { 486 g_apSessionHashTab[iHash] = pSession->pNextHash; 487 pSession->pNextHash = NULL; 488 } 489 else 490 { 491 PSUPDRVSESSION pPrev = pSession; 492 pSession = pSession->pNextHash; 493 while (pSession) 494 { 495 if (pSession->Process == Process) 496 { 497 pPrev->pNextHash = pSession->pNextHash; 498 pSession->pNextHash = NULL; 499 break; 500 } 501 502 /* next */ 503 pPrev = pSession; 504 pSession = pSession->pNextHash; 505 } 506 } 507 } 508 RTSpinlockReleaseNoInts(g_Spinlock, &Tmp); 509 if (!pSession) 510 { 511 OSDBGPRINT(("VBoxDrvSolarisClose: WHAT?!? pSession == NULL! This must be a mistake... pid=%d (close)\n", 512 (int)Process)); 513 return DDI_FAILURE; 514 } 515 #endif 516 517 /* 518 * Close the session. 519 */ 520 supdrvCloseSession(&g_DevExt, pSession); 521 return DDI_SUCCESS; 522 } 523 524 525 static int VBoxDrvSolarisRead(dev_t Dev, struct uio *pUio, cred_t *pCred) 526 { 527 cmn_err(CE_CONT, "VBoxDrvSolarisRead"); 528 return DDI_SUCCESS; 529 } 530 531 532 static int VBoxDrvSolarisWrite(dev_t Dev, struct uio *pUio, cred_t *pCred) 533 { 534 cmn_err(CE_CONT, "VBoxDrvSolarisWrite"); 535 return DDI_SUCCESS; 536 } 537 533 538 534 539 /** … … 733 738 } 734 739 740 735 741 /** 736 742 * Initializes any OS specific object creator fields.
Note:
See TracChangeset
for help on using the changeset viewer.