2010年4月30日

Ubuntu 10.04與sk98lin

前面來點前言,我用的主機板是P5Q-E,這塊主機板不錯,C/P值也頗高,內建的Gigabit LAN Controller是MARVELL,要說差也不差,但Linux內建的Driver(skge/sky2)就是很鳥,因此都得用原廠的sk98lin,但每次kernel一升級,就經常無法編譯通過,這次Ubuntu 10.04同樣遇到了!
因為Ubuntu 10.04還太新了,目前沒google到patch,我所幸自己試著抓抓改改,目前看來應該ok!

安裝時編譯錯誤程式碼如下:
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c: In function 『SkGeTestIsr』:
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c:1750: error: 『TASK_NORMAL』 undeclared (first use in this function)
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c:1750: error: (Each undeclared identifier is reported only once
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c:1750: error: for each function it appears in.)
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c: In function 『SkGeTestMsi』:
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c:1780: warning: passing argument 2 of 『request_irq』 from incompatible pointer type
include/linux/interrupt.h:117: note: expected 『irq_handler_t』 but argument is of type 『int (*)(int, void *)』
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c:1790: error: 『TASK_UNINTERRUPTIBLE』 undeclared (first use in this function)
/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.c:1790: error: implicit declaration of function 『schedule_timeout』
make[2]: *** [/tmp/Sk98IpXJpMHrIbXnZSVQLQbMS/all/skge.o] Error 1
make[2]: *** Waiting for unfinished jobs....


注意到,
Q1:
TASK_NORMAL、TASK_UNINTERRUPTIBLE 沒定義

Q2:
schedule_timeout 無法被skge.c直接呼叫

cscope之後發現 TASK_NORMAL、TASK_UNINTERRUPTIBLE、schedule_timeout 都在 sched.h中。

因此,修改 DriverInstall/sk98lin.tar.bz2 壓縮檔中的 2.6/skge.c
(DriverInstall/sk98lin.tar.bz2:/2.6/skge.c)
.....
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
static int __devinit SkGeTestIsr(int irq, void *dev_id)
#else
static int __devinit SkGeTestIsr(int irq, void *dev_id, struct pt_regs *ptregs)
#endif
{
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
.....
static int __devinit SkGeTestMsi(struct SK_NET_DEVICE *dev, SK_AC *pAC)
{
#define TASK_UNINTERRUPTIBLE 2

struct pci_dev *pdev = pAC->PciDev;
.....
SK_OUT8(pAC->IoBase, B0_CTST, CS_ST_SW_IRQ);
SK_IN8(pAC->IoBase, B0_CTST, &test8);

extern signed long schedule_timeout(signed long timeout);
extern signed long schedule_timeout_interruptible(signed long timeout);
extern signed long schedule_timeout_killable(signed long timeout);
extern signed long schedule_timeout_uninterruptible(signed long timeout);

wait_event_timeout(pAC->msi_wait, (pAC->AllocFlag & SK_ALLOC_MSI), HZ/10);
.....


skge.patch
--- skge.old 2010-04-30 20:31:24.502166321 +0800
+++ skge.c 2010-04-30 20:34:07.902165413 +0800
@@ -1732,6 +1732,9 @@
static int __devinit SkGeTestIsr(int irq, void *dev_id, struct pt_regs *ptregs)
#endif
{
+#define TASK_INTERRUPTIBLE 1
+#define TASK_UNINTERRUPTIBLE 2
+#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
struct SK_NET_DEVICE *dev = (struct SK_NET_DEVICE *)dev_id;
DEV_NET *pNet;
SK_AC *pAC;
@@ -1768,6 +1771,8 @@
*/
static int __devinit SkGeTestMsi(struct SK_NET_DEVICE *dev, SK_AC *pAC)
{
+#define TASK_UNINTERRUPTIBLE 2
+
struct pci_dev *pdev = pAC->PciDev;
int Ret;
SK_U32 test32;
@@ -1787,6 +1792,11 @@
SK_OUT8(pAC->IoBase, B0_CTST, CS_ST_SW_IRQ);
SK_IN8(pAC->IoBase, B0_CTST, &test8);

+extern signed long schedule_timeout(signed long timeout);
+extern signed long schedule_timeout_interruptible(signed long timeout);
+extern signed long schedule_timeout_killable(signed long timeout);
+extern signed long schedule_timeout_uninterruptible(signed long timeout);
+
wait_event_timeout(pAC->msi_wait, (pAC->AllocFlag & SK_ALLOC_MSI), HZ/10);

if (!(pAC->AllocFlag & SK_ALLOC_MSI)) {


最後附上幾個改過得檔案連結:
skge.patch
sk98lin.tar.bz2

沒有留言: