Changeset 17853 in vbox for trunk/src/VBox/Additions/linux/module/vboxmod.c
- Timestamp:
- Mar 13, 2009 5:42:43 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/linux/module/vboxmod.c
r16315 r17853 901 901 } 902 902 903 /** strategy handlers (file operations)*/904 static struct file_operations vbox _fops =903 /** file operations for the vboxadd device */ 904 static struct file_operations vboxadd_fops = 905 905 { 906 906 .owner = THIS_MODULE, … … 914 914 }; 915 915 916 static struct miscdevice gMiscDevice = 916 /** Miscellaneous device allocation for vboxadd */ 917 static struct miscdevice gMiscVBoxAdd = 917 918 { 918 919 minor: MISC_DYNAMIC_MINOR, 919 name: "vboxadd",920 fops: &vbox _fops920 name: VBOXADD_NAME, 921 fops: &vboxadd_fops 921 922 }; 922 923 … … 1169 1170 static __init int init(void) 1170 1171 { 1171 int err;1172 int rcVBox;1172 int rc = 0, rcVBox = VINF_SUCCESS; 1173 bool haveVBoxAdd = false, haveGuestLib = false; 1173 1174 struct pci_dev *pcidev = NULL; 1174 VMMDevReportGuestInfo *infoReq = NULL; 1175 1176 if (vboxadd_cmc_init ()) 1177 { 1178 printk (KERN_ERR "vboxadd: could not init cmc.\n"); 1179 return -ENODEV; 1180 } 1181 1182 /* 1183 * Detect PCI device 1184 */ 1185 pcidev = PCI_DEV_GET(VMMDEV_VENDORID, VMMDEV_DEVICEID, pcidev); 1186 if (!pcidev) 1187 { 1188 printk(KERN_ERR "vboxadd: VirtualBox PCI device not found.\n"); 1189 return -ENODEV; 1190 } 1191 1192 err = pci_enable_device (pcidev); 1193 if (err) 1194 { 1195 Log(("vboxadd: could not enable device: %d\n", err)); 1196 PCI_DEV_PUT(pcidev); 1197 return -ENODEV; 1198 } 1199 1200 LogRel(("Starting VirtualBox version %s Guest Additions\n", 1201 VBOX_VERSION_STRING)); 1202 /* register a character device */ 1203 if (vbox_major > 0) 1204 { 1205 err = register_chrdev(vbox_major, "vboxadd", &vbox_fops); 1206 if (err < 0 || (vbox_major & err) || (!vbox_major && !err)) 1207 { 1208 LogRelFunc(("register_chrdev failed: vbox_major: %d, err = %d\n", 1209 vbox_major, err)); 1210 PCI_DEV_PUT(pcidev); 1211 return -ENODEV; 1212 } 1213 /* if no major code was set, take the return value */ 1214 if (!vbox_major) 1215 vbox_major = err; 1216 } 1217 else 1218 { 1219 err = misc_register(&gMiscDevice); 1220 if (err) 1221 { 1222 LogRelFunc(("misc_register failed (rc=%d)\n", err)); 1223 return -ENODEV; 1224 } 1225 } 1175 1176 rcVBox = vboxadd_cmc_init(); 1177 if (RT_FAILURE(rcVBox)) 1178 { 1179 printk (KERN_ERR "vboxadd: could not init cmc, VBox error code %d.\n", rcVBox); 1180 rc = -RTErrConvertToErrno(rcVBox); 1181 } 1182 1183 /* Detect PCI device */ 1184 if (!rc) 1185 { 1186 pcidev = PCI_DEV_GET(VMMDEV_VENDORID, VMMDEV_DEVICEID, pcidev); 1187 if (!pcidev) 1188 { 1189 printk(KERN_ERR "vboxadd: VirtualBox Guest PCI device not found.\n"); 1190 rc = -ENODEV; 1191 } 1192 } 1193 1194 if (!rc) 1195 { 1196 rc = pci_enable_device (pcidev); 1197 if (rc) 1198 LogRel(("vboxadd: could not enable device: %d\n", rc)); 1199 } 1200 if (rc) 1201 LogRel(("Starting VirtualBox version %s Guest Additions\n", 1202 VBOX_VERSION_STRING)); 1203 1204 /* Register vboxadd */ 1205 if (!rc && vbox_major > 0) /* Register as a character device in this case */ 1206 { 1207 rc = register_chrdev(vbox_major, VBOXADD_NAME, &vboxadd_fops); 1208 if (rc) /* As we pass a non-zero major, rc should be zero on success. */ 1209 LogRel(("vboxadd: register_chrdev failed: vbox_major: %d, err = %d\n", 1210 vbox_major, rc)); 1211 } 1212 else if (!rc) /* Register as a miscellaneous device otherwise */ 1213 { 1214 rc = misc_register(&gMiscVBoxAdd); 1215 if (rc) 1216 LogRel(("vboxadd: misc_register failed for %s (rc=%d)\n", 1217 VBOXADD_NAME, rc)); 1218 } 1219 if (!rc) 1220 haveVBoxAdd = true; 1226 1221 1227 1222 /* allocate and initialize device extension */ 1228 vboxDev = kmalloc(sizeof(*vboxDev), GFP_KERNEL); 1229 if (!vboxDev) 1230 { 1231 LogRelFunc(("cannot allocate device!\n")); 1232 err = -ENOMEM; 1233 goto fail; 1234 } 1235 memset(vboxDev, 0, sizeof(*vboxDev)); 1236 snprintf(vboxDev->name, sizeof(vboxDev->name), "vboxadd"); 1237 1238 /* get the IO port region */ 1239 vboxDev->io_port = pci_resource_start(pcidev, 0); 1240 1241 /* get the memory region */ 1242 vboxDev->vmmdevmem = pci_resource_start(pcidev, 1); 1243 vboxDev->vmmdevmem_size = pci_resource_len(pcidev, 1); 1244 1245 /* all resources found? */ 1246 if (!vboxDev->io_port || !vboxDev->vmmdevmem || !vboxDev->vmmdevmem_size) 1247 { 1248 LogRelFunc(("did not find expected hardware resources!\n")); 1249 err = -ENXIO; 1250 goto fail; 1223 if (!rc) 1224 { 1225 vboxDev = kmalloc(sizeof(*vboxDev), GFP_KERNEL); 1226 if (vboxDev) 1227 memset(vboxDev, 0, sizeof(*vboxDev)); 1228 else 1229 { 1230 LogRel(("vboxadd: could not allocate private device structure\n")); 1231 rc = -ENOMEM; 1232 } 1233 } 1234 1235 if (!rc) 1236 { 1237 /* get the IO port region */ 1238 vboxDev->io_port = pci_resource_start(pcidev, 0); 1239 1240 /* get the memory region */ 1241 vboxDev->vmmdevmem = pci_resource_start(pcidev, 1); 1242 vboxDev->vmmdevmem_size = pci_resource_len(pcidev, 1); 1243 1244 /* all resources found? */ 1245 if (!vboxDev->io_port || !vboxDev->vmmdevmem || !vboxDev->vmmdevmem_size) 1246 { 1247 LogRel(("vboxadd: did not find expected hardware resources\n")); 1248 rc = -ENXIO; 1249 } 1251 1250 } 1252 1251 1253 1252 /* request ownership of adapter memory */ 1254 if ( request_mem_region(vboxDev->vmmdevmem, vboxDev->vmmdevmem_size, "vboxadd") == 0)1255 {1256 LogRelFunc(("failed to request adapter memory!\n"));1257 err = -ENXIO;1258 goto fail;1253 if (!rc && !request_mem_region(vboxDev->vmmdevmem, vboxDev->vmmdevmem_size, 1254 VBOXADD_NAME)) 1255 { 1256 LogRel(("vboxadd: failed to obtain adapter memory\n")); 1257 rc = -EBUSY; 1259 1258 } 1260 1259 1261 1260 /* map adapter memory into kernel address space and check version */ 1262 vboxDev->pVMMDevMemory = (VMMDevMemory *) ioremap(vboxDev->vmmdevmem, 1261 if (!rc) 1262 { 1263 vboxDev->pVMMDevMemory = (VMMDevMemory *) ioremap(vboxDev->vmmdevmem, 1263 1264 vboxDev->vmmdevmem_size); 1264 if (!vboxDev->pVMMDevMemory) 1265 { 1266 LogRelFunc(("ioremap failed\n")); 1267 err = -ENOMEM; 1268 goto fail; 1269 } 1270 1271 if (vboxDev->pVMMDevMemory->u32Version != VMMDEV_MEMORY_VERSION) 1272 { 1273 LogRelFunc(("invalid VMM device memory version! (got 0x%x, expected 0x%x)\n", 1274 vboxDev->pVMMDevMemory->u32Version, VMMDEV_MEMORY_VERSION)); 1275 err = -ENXIO; 1276 goto fail; 1277 } 1278 1279 /* initialize VBGL subsystem */ 1280 rcVBox = VbglInit(vboxDev->io_port, vboxDev->pVMMDevMemory); 1281 if (RT_FAILURE(rcVBox)) 1282 { 1283 LogRelFunc(("could not initialize VBGL subsystem! rc = %Rrc\n", rcVBox)); 1284 err = -ENXIO; 1285 goto fail; 1286 } 1265 if (!vboxDev->pVMMDevMemory) 1266 { 1267 LogRel(("vboxadd: ioremap failed\n")); 1268 rc = -ENOMEM; 1269 } 1270 } 1271 1272 if (!rc && (vboxDev->pVMMDevMemory->u32Version != VMMDEV_MEMORY_VERSION)) 1273 { 1274 LogRel(("vboxadd: invalid VMM device memory version! (got 0x%x, expected 0x%x)\n", 1275 vboxDev->pVMMDevMemory->u32Version, VMMDEV_MEMORY_VERSION)); 1276 rc = -ENXIO; 1277 } 1278 1279 /* initialize ring 0 guest library */ 1280 if (!rc) 1281 { 1282 rcVBox = VbglInit(vboxDev->io_port, vboxDev->pVMMDevMemory); 1283 if (RT_FAILURE(rcVBox)) 1284 { 1285 LogRel(("vboxadd: could not initialize VBGL subsystem: %Rrc\n", 1286 rcVBox)); 1287 rc = -RTErrConvertToErrno(rcVBox); 1288 } 1289 } 1290 if (!rc) 1291 haveGuestLib = true; 1287 1292 1288 1293 /* report guest information to host, this must be done as the very first request */ 1289 rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&infoReq, 1290 sizeof(VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo); 1291 if (RT_FAILURE(rcVBox)) 1292 { 1293 LogRelFunc(("could not allocate request structure! rc = %Rrc\n", rcVBox)); 1294 err = -ENOMEM; 1295 goto fail; 1296 } 1297 1298 /* report guest version to host, the VMMDev requires that to be done first */ 1299 infoReq->guestInfo.additionsVersion = VMMDEV_VERSION; 1294 if (!rc) 1295 { 1296 VMMDevReportGuestInfo *infoReq = NULL; 1297 1298 rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&infoReq, 1299 sizeof(VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo); 1300 if (RT_FAILURE(rcVBox)) 1301 { 1302 LogRel(("vboxadd: could not allocate request structure: %Rrc\n", rcVBox)); 1303 rc = -RTErrConvertToErrno(rcVBox); 1304 } 1305 /* report guest version to host, the VMMDev requires that to be done 1306 * before any other VMMDev operations. */ 1307 if (infoReq) 1308 { 1309 infoReq->guestInfo.additionsVersion = VMMDEV_VERSION; 1300 1310 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) 1301 infoReq->guestInfo.osType = VBOXOSTYPE_Linux26;1311 infoReq->guestInfo.osType = VBOXOSTYPE_Linux26; 1302 1312 #else 1303 infoReq->guestInfo.osType = VBOXOSTYPE_Linux24;1313 infoReq->guestInfo.osType = VBOXOSTYPE_Linux24; 1304 1314 #endif 1305 rcVBox = VbglGRPerform(&infoReq->header); 1306 if (RT_FAILURE(rcVBox) || RT_FAILURE(infoReq->header.rc)) 1307 { 1308 LogRelFunc(("error reporting guest info to host! rc = %Rrc, header.rc = %Rrc\n", 1309 rcVBox, infoReq->header.rc)); 1310 VbglGRFree(&infoReq->header); 1311 err = -ENXIO; 1312 goto fail; 1313 } 1314 VbglGRFree(&infoReq->header); 1315 rcVBox = VbglGRPerform(&infoReq->header); 1316 } 1317 if (infoReq && (RT_FAILURE(rcVBox) || RT_FAILURE(infoReq->header.rc))) 1318 { 1319 LogRel(("vboxadd: error reporting guest information to host: %Rrc, header: %Rrc\n", 1320 rcVBox, infoReq->header.rc)); 1321 rc = RT_FAILURE(rcVBox) ? -RTErrConvertToErrno(rcVBox) 1322 : -RTErrConvertToErrno(infoReq->header.rc); 1323 } 1324 if (infoReq) 1325 VbglGRFree(&infoReq->header); 1326 } 1315 1327 1316 1328 /* Unset the graphics capability until/unless X is loaded. */ 1317 1329 /** @todo check the error code once we bump the additions version. 1318 1330 For now we ignore it for compatibility with older hosts. */ 1331 if (!rc) 1319 1332 { 1320 1333 VMMDevReqGuestCapabilities2 *vmmreqGuestCaps; 1321 1322 1334 1323 1335 rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&vmmreqGuestCaps, … … 1326 1338 if (RT_FAILURE(rcVBox)) 1327 1339 { 1328 LogRelFunc(("could not allocate request structure! rc = %Rrc\n", rcVBox)); 1329 err = -ENOMEM; 1330 goto fail; 1331 } 1332 vmmreqGuestCaps->u32OrMask = 0; 1333 vmmreqGuestCaps->u32NotMask = VMMDEV_GUEST_SUPPORTS_GRAPHICS; 1334 rcVBox = VbglGRPerform(&vmmreqGuestCaps->header); 1335 VbglGRFree(&vmmreqGuestCaps->header); 1340 LogRel(("vboxadd: could not allocate request structure: %Rrc\n", 1341 rcVBox)); 1342 rc = -RTErrConvertToErrno(rcVBox); 1343 } 1344 else 1345 { 1346 vmmreqGuestCaps->u32OrMask = 0; 1347 vmmreqGuestCaps->u32NotMask = VMMDEV_GUEST_SUPPORTS_GRAPHICS; 1348 rcVBox = VbglGRPerform(&vmmreqGuestCaps->header); 1349 if (RT_FAILURE(rcVBox)) 1350 { 1351 LogRel(("vboxadd: could not allocate request structure: %Rrc\n", 1352 rcVBox)); 1353 rc = -RTErrConvertToErrno(rcVBox); 1354 } 1355 VbglGRFree(&vmmreqGuestCaps->header); 1356 } 1357 } 1358 1359 /* perform hypervisor address space reservation */ 1360 if (!rc && vboxadd_reserve_hypervisor()) 1361 { 1362 /* we just ignore the error, no address window reservation, non fatal */ 1363 } 1364 1365 /* allocate a VMM request structure for use in the ISR */ 1366 if (!rc) 1367 { 1368 rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&vboxDev->irqAckRequest, 1369 sizeof(VMMDevEvents), VMMDevReq_AcknowledgeEvents); 1336 1370 if (RT_FAILURE(rcVBox)) 1337 1371 { 1338 err = -ENXIO; 1339 goto fail; 1340 } 1341 } 1342 1343 /* perform hypervisor address space reservation */ 1344 if (vboxadd_reserve_hypervisor()) 1345 { 1346 /* we just ignore the error, no address window reservation, non fatal */ 1347 } 1348 1349 /* allocate a VMM request structure for use in the ISR */ 1350 rcVBox = VbglGRAlloc((VMMDevRequestHeader**)&vboxDev->irqAckRequest, 1351 sizeof(VMMDevEvents), VMMDevReq_AcknowledgeEvents); 1352 if (RT_FAILURE(rcVBox)) 1353 { 1354 LogRelFunc(("could not allocate request structure! rc = %Rrc\n", rcVBox)); 1355 err = -ENOMEM; 1356 goto fail; 1372 LogRel(("vboxadd: could not allocate request structure: %Rrc\n", 1373 rcVBox)); 1374 rc = -RTErrConvertToErrno(rcVBox); 1375 } 1357 1376 } 1358 1377 1359 1378 /* get ISR */ 1360 err = request_irq(pcidev->irq, vboxadd_irq_handler, 1379 if (!rc) 1380 { 1381 rc = request_irq(pcidev->irq, vboxadd_irq_handler, 1361 1382 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20) 1362 IRQF_SHARED,1383 IRQF_SHARED, 1363 1384 #else 1364 SA_SHIRQ,1385 SA_SHIRQ, 1365 1386 #endif 1366 "vboxadd", vboxDev); 1367 if (err) 1368 { 1369 LogRelFunc(("could not request IRQ %d, err: %d\n", pcidev->irq, err)); 1370 goto fail; 1371 } 1372 vboxDev->irq = pcidev->irq; 1373 1374 init_waitqueue_head (&vboxDev->eventq); 1375 1376 { 1387 VBOXADD_NAME, vboxDev); 1388 if (rc) 1389 LogRel(("vboxadd: could not request IRQ %d, err: %d\n", pcidev->irq, rc)); 1390 else 1391 vboxDev->irq = pcidev->irq; 1392 } 1393 1394 if (!rc) 1395 { 1396 VBoxGuestFilterMaskInfo info; 1397 1398 init_waitqueue_head (&vboxDev->eventq); 1377 1399 /* Register for notification when the host absolute pointer position 1378 1400 * changes. */ 1379 VBoxGuestFilterMaskInfo info;1380 1401 info.u32OrMask = VMMDEV_EVENT_MOUSE_POSITION_CHANGED; 1381 1402 info.u32NotMask = 0; … … 1383 1404 if (!RT_SUCCESS(rcVBox)) 1384 1405 { 1385 LogRelFunc(("failed to register for VMMDEV_EVENT_MOUSE_POSITION_CHANGED events\n")); 1386 err = -RTErrConvertToErrno(rcVBox); 1387 goto fail; 1388 } 1389 } 1390 1391 /* some useful information for the user but don't show this on the console */ 1392 LogRel(("VirtualBox device settings: major %d, IRQ %d, " 1406 LogRel(("vboxadd: failed to register for VMMDEV_EVENT_MOUSE_POSITION_CHANGED events: %Rrc\n", 1407 rcVBox)); 1408 rc = -RTErrConvertToErrno(rcVBox); 1409 } 1410 } 1411 1412 if (!rc) 1413 { 1414 /* some useful information for the user but don't show this on the console */ 1415 LogRel(("VirtualBox device settings: major %d, IRQ %d, " 1393 1416 "I/O port 0x%x, MMIO at 0x%x (size 0x%x), " 1394 1417 "hypervisor window at 0x%p (size 0x%x)\n", … … 1396 1419 vboxDev->vmmdevmem, vboxDev->vmmdevmem_size, 1397 1420 vboxDev->hypervisorStart, vboxDev->hypervisorSize)); 1398 printk(KERN_DEBUG "vboxadd: Successfully loaded version " 1399 VBOX_VERSION_STRING " (interface " xstr(VMMDEV_VERSION) ")\n"); 1400 1401 /* successful return */ 1402 PCI_DEV_PUT(pcidev); 1403 return 0; 1404 1405 fail: 1406 PCI_DEV_PUT(pcidev); 1407 free_resources(); 1421 printk(KERN_DEBUG "vboxadd: Successfully loaded version " 1422 VBOX_VERSION_STRING " (interface " xstr(VMMDEV_VERSION) ")\n"); 1423 } 1424 else /* Clean up on failure */ 1425 { 1426 if (haveGuestLib) 1427 VbglTerminate(); 1428 if (vboxDev) 1429 free_resources(); 1430 if (haveVBoxAdd && vbox_major > 0) 1431 unregister_chrdev(vbox_major, VBOXADD_NAME); 1432 else if (haveVBoxAdd) 1433 misc_deregister(&gMiscVBoxAdd); 1434 } 1435 /* We always release this. Presumably because we no longer need to do 1436 * anything with the device structure. */ 1437 if (pcidev) 1438 PCI_DEV_PUT(pcidev); 1439 return rc; 1440 } 1441 1442 /** 1443 * Module termination 1444 * 1445 */ 1446 static __exit void fini(void) 1447 { 1408 1448 if (vbox_major > 0) 1409 unregister_chrdev(vbox_major, "vboxadd");1449 unregister_chrdev(vbox_major, VBOXADD_NAME); 1410 1450 else 1411 misc_deregister(&gMiscDevice); 1412 return err; 1413 } 1414 1415 /** 1416 * Module termination 1417 * 1418 */ 1419 static __exit void fini(void) 1420 { 1421 if (vbox_major > 0) 1422 unregister_chrdev(vbox_major, "vboxadd"); 1423 else 1424 misc_deregister(&gMiscDevice); 1451 misc_deregister(&gMiscVBoxAdd); 1425 1452 free_resources(); 1426 1453 vboxadd_cmc_fini ();
Note:
See TracChangeset
for help on using the changeset viewer.