Нужно переписать следующие куски кода на баше, успешно работающие в юзерспейсе, на Си для использования в ядерном модуле. Никогда раньше с этим не сталкивался, гугление не дало ничего вразумительного. Как это правильно сделать?
echo -n manual > /sys/bus/serio/devices/serio1/bind_mode
echo -n serio1 > /sys/bus/serio/drivers/psmouse/unbind
echo -n manual > /sys/bus/serio/devices/serio1/bind_mode
echo -n none > /sys/bus/serio/drivers/psmouse/drvctl
echo -n auto > /sys/bus/serio/devices/serio1/bind_mode
echo -n reconnect > /sys/bus/serio/drivers/psmouse/drvctl
echo -n manual > /sys/bus/serio/devices/serio1/bind_mode
echo -n psmouse > /sys/bus/serio/devices/serio1/drvctl
if (fDetach)
{
char* szCmdBuf;
char* szFileBuf;
struct file* pFile;
int iCmdLen;
const int cMaxBuf = 128;
const struct cred *pOldCreds;
struct cred *pNewCreds;
/*
* Now perform kernel analog of:
*
* echo -n "10de 040a" > /sys/bus/pci/drivers/pci-stub/new_id
* echo -n 0000:03:00.0 > /sys/bus/pci/drivers/nvidia/unbind
* echo -n 0000:03:00.0 > /sys/bus/pci/drivers/pci-stub/bind
*
* We do this way, as this interface is presumingly more stable than
* in-kernel ones.
*/
szCmdBuf = kmalloc(cMaxBuf, GFP_KERNEL);
szFileBuf = kmalloc(cMaxBuf, GFP_KERNEL);
if (!szCmdBuf || !szFileBuf)
goto done;
/* Somewhat ugly hack - override current credentials */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
pNewCreds = prepare_creds();
if (!pNewCreds)
goto done;
pNewCreds->fsuid = 0;
pOldCreds = override_creds(pNewCreds);
#endif
RTStrPrintf(szFileBuf, cMaxBuf,
"/sys/bus/pci/drivers/%s/new_id",
PCI_STUB_MODULE);
pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
if (pFile)
{
iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf,
"%04x %04x",
uVendor, uDevice);
/* Don't write trailing \0 */
vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
vboxPciFileClose(pFile);
}
else
printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
iCmdLen = RTStrPrintf(szCmdBuf, cMaxBuf,
"0000:%02x:%02x.%d",
uBus, uDevFn>>3, uDevFn&7);
/* Unbind if bound to smth */
if (pIns->szPrevDriver[0])
{
RTStrPrintf(szFileBuf, cMaxBuf,
"/sys/bus/pci/drivers/%s/unbind",
pIns->szPrevDriver);
pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
if (pFile)
{
/* Don't write trailing \0 */
vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
vboxPciFileClose(pFile);
}
else
printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
}
RTStrPrintf(szFileBuf, cMaxBuf,
"/sys/bus/pci/drivers/%s/bind",
PCI_STUB_MODULE);
pFile = vboxPciFileOpen(szFileBuf, O_WRONLY);
if (pFile)
{
/* Don't write trailing \0 */
vboxPciFileWrite(pFile, 0, szCmdBuf, iCmdLen);
vboxPciFileClose(pFile);
}
else
printk(KERN_DEBUG "vboxpci: cannot open %s\n", szFileBuf);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)
revert_creds(pOldCreds);
put_cred(pNewCreds);
#endif
done:
kfree(szCmdBuf);
kfree(szFileBuf);
}