本文介绍Linux4。4内核ISERR()函数。 文件:includelinuxerr。h,定义如下:defineMAXERRNO4095对于64位系统,判断x是否在0xfffffffffffff0010xffffffffffffffffdefineISERRVALUE(x)unlikely((x)(unsignedlong)MAXERRNO)staticinlinelongmustcheckPTRERR(forceconstvoidptr){return(long)}staticinlineboolmustcheckISERR(forceconstvoidptr){returnISERRVALUE((unsignedlong)ptr);}一、功能 功能:判断传入的指针ptr是否有效。 Linux内核指针包括:有效指针、空指针(NULL)和错误指针。 Linux内核用最后4K空间保存指针的出错码,64位的系统地址为:0xfffffffffffff0010xffffffffffffffff。 如果是错误指针,配合PTRERR()函数判断错误代码。 文件:includeuapiasmgenericerrnobase。h,定义如下:defineEPERM1OperationnotpermitteddefineENOENT2NosuchfileordirectorydefineESRCH3NosuchprocessdefineEINTR4InterruptedsystemcalldefineEIO5IOerrordefineENXIO6NosuchdeviceoraddressdefineE2BIG7ArgumentlisttoolongdefineENOEXEC8ExecformaterrordefineEBADF9BadfilenumberdefineECHILD10NochildprocessesdefineEAGAIN11TryagaindefineENOMEM12Outofmemory。。。 文件:includeuapiasmgenericerrno。h,定义如下:defineEDEADLK35ResourcedeadlockwouldoccurdefineENAMETOOLONG36FilenametoolongdefineENOLCK37NorecordlocksavailabledefineENOSYS38InvalidsystemcallnumberdefineENOTEMPTY39DirectorynotemptydefineELOOP40Toomanysymboliclinksencountered。。。 文件:includelinuxerrno。h,定义如下:defineERESTARTSYS512defineERESTARTNOINTR513defineERESTARTNOHAND514restartifnohandler。。defineENOIOCTLCMD515NoioctlcommanddefineERESTARTRESTARTBLOCK516restartbycallingsysrestartsyscalldefineEPROBEDEFER517Driverrequestsproberetry。。。二、说明 1)inline:内联函数。内联函数的代码会直接嵌入到调用它的位置,调用几次就嵌入几次。 2)mustcheck:指调用函数一定要处理函数的返回值,否则编译器会给出警告。 3)force:表示变量可进行强制转换。 4)unlikely后续专门介绍。 4)(unsignedlong)MAXERRNO:用补码的方式表示4095,64位系统为0xfffffffffffff001。三、示例 文件:driversgpudrmrockchiprockchipdrmdrv。cprintk(KERNERRunsignedlong0xlx,(unsignedlong)MAXERRNO);。。。privatedevfreqdevfreqgetdevfreqbyphandle(dev,0);printk(KERNERRISERR(privatedevfreq)d,privatedevfreqp,ISERR(privatedevfreq),privatedevfreq);1、判断是否有效指针if(ISERR(privatedevfreq)){2、判断错误码if(PTRERR(privatedevfreq)EPROBEDEFER){parentnpofparsephandle(np,devfreq,0);if(parentnpofdeviceisavailable(parentnp)){。。。}else{3、运行到此处devinfo(dev,dmcisdisabled);}}else{。。。}。。。}。。。privatehdmipll。plldevmclkget(dev,hdmitmdspll);printk(KERNERRISERR(privatehdmipll。pll)d,privatehdmipll。pllp,ISERR(privatehdmipll。pll),privatehdmipll。pll); 程序运行后,相关日志如下:〔2。270871〕unsignedlong0xfffffffffffff001〔2。271322〕ISERR(privatedevfreq)1,privatedevfreqfffffffffffffdfb〔2。271993〕rockchipdrmdisplaysubsystem:dmcisdisabled〔2。272504〕ISERR(privatehdmipll。pll)0,privatehdmipll。pllffffffc0782e6340 通过上面日志可以看出: 1)privatedevfreq值为0xfffffffffffffdfb(值为517),对应错误码EPROBEDEFER,此时ISERR返回1。 2)privatehdmipll。pll值为0xffffffc0782e6340,是有效指针,ISERR返回0。