flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
阅读:2124回复:11

大侠求救:编译正确,加载出错。

楼主#
更多 发布于:2003-01-14 09:43
本人想在red hat linux8(kernel 2.4.18-14)下面做个usb驱动,刚开始驱动编译老是出错,索性重新编译内核。结果编译正确了,insmod却出现版本错误:
     usbsample.o:kernel-module version mismatch
     usbsample.o was compiled for kernel version 2.4.18-14custom
    while this kernel is version 2.4.18-14
痛并快乐着!
yftty
驱动牛犊
驱动牛犊
  • 注册日期2002-11-06
  • 最后登录2010-12-07
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望22点
  • 贡献值1点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-01-14 12:10
Modify the /usr/src/linux/include/linux/version.h file.

Erase 2.4.18-3\'s following \"custom\" characters.

Then ok.
/yftty http://www.unix-driver.org
hjmatdd
驱动牛犊
驱动牛犊
  • 注册日期2002-06-27
  • 最后登录2004-07-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-01-14 13:17
你用自己编译的内核起动就可以了
flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-01-14 17:39
谢谢二位,问题解决了,接分。
痛并快乐着!
flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-01-15 11:59
上面的问题解决了,现在又出现了错误,有的函数我明明定义了,编译器却说没有定义。

gcc -Wall -D__KERNEL__ -DMODULE -I/usr/src/linux/include -DMODVERSIONS -include
/usr/src/linux/include/linux/modversions.h -O2 -I..   -c -o usbsample.o usbsample.c
usbsample.c:303: `usbsample_fops\' undeclared here (not in a function)
usbsample.c:303: initializer element is not constant
usbsample.c:303: (near initialization for `usbsample_usb_driver.fops\')
usbsample.c:315: `usbsample_read\' undeclared here (not in a function)
usbsample.c:315: initializer element is not constant
usbsample.c:315: (near initialization for `usbsample_fops.read\')
usbsample.c:316: `usbsample_write\' undeclared here (not in a function)
usbsample.c:316: initializer element is not constant
usbsample.c:316: (near initialization for `usbsample_fops.write\')
usbsample.c:318: `usbsample_ioctl\' undeclared here (not in a function)
usbsample.c:318: initializer element is not constant
usbsample.c:318: (near initialization for `usbsample_fops.ioctl\')
usbsample.c:319: `usbsample_open\' undeclared here (not in a function)
usbsample.c:319: initializer element is not constant
usbsample.c:319: (near initialization for `usbsample_fops.open\')
usbsample.c:320: `usbsample_release\' undeclared here (not in a function)
usbsample.c:320: initializer element is not constant
usbsample.c:320: (near initialization for `usbsample_fops.release\')
usbsample.c: In function `dabusb_free_buffers\':
usbsample.c:392: warning: unused variable `flags\'
usbsample.c: In function `usbsample_release\':
usbsample.c:410: warning: implicit declaration of function `lock_kernel\'
usbsample.c:424: warning: implicit declaration of function `unlock_kernel\'
usbsample.c: In function `usbsample_read\':
usbsample.c:434: warning: unused variable `flags\'
usbsample.c:435: warning: unused variable `ret\'
usbsample.c:436: warning: unused variable `rem\'
usbsample.c:437: warning: unused variable `cnt\'
usbsample.c:438: warning: unused variable `b\'
usbsample.c:439: warning: unused variable `purb\'
usbsample.c: In function `usbsample_write\':
usbsample.c:465: warning: unused variable `flags\'
usbsample.c:466: warning: unused variable `ret\'
usbsample.c:467: warning: unused variable `rem\'
usbsample.c:468: warning: unused variable `cnt\'
usbsample.c:469: warning: unused variable `b\'
usbsample.c:470: warning: unused variable `purb\'
usbsample.c: In function `usbsample_ioctl\':
usbsample.c:516: warning: implicit declaration of function `copy_from_user\'
usbsample.c:496: warning: unused variable `pbulk\'
usbsample.c:498: warning: unused variable `version\'
usbsample.c: At top level:
usbsample.c:311: warning: `usbsample_fops\' defined but not used
usbsample.c:338: warning: `usbsample_open\' defined but not used
usbsample.c:405: warning: `usbsample_release\' defined but not used
usbsample.c:432: warning: `usbsample_read\' defined but not used
usbsample.c:463: warning: `usbsample_write\' defined but not used
usbsample.c:494: warning: `usbsample_ioctl\' defined but not used
usbsample.c:34:1: unterminated #else
痛并快乐着!
ellipse
驱动牛犊
驱动牛犊
  • 注册日期2002-12-02
  • 最后登录2006-04-30
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-01-16 09:37
有些是由于你没有包含必要的头文件,
比如copy_from_user需要包含<linux/uaccess.h>
有些是由于你定义了变量而没有使用,
至于开头定义结构的那个错误,
不太清楚,可不可以把那部分的源代码贴出来呢
flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-01-16 10:37
#ifndef __KERNEL__
#  define __KERNEL__
#endif
#ifndef MODULE
#  define MODULE
#endif

#include <linux/config.h>
#include <linux/module.h>

/* No USB with 2.0, make an explicit error and avoid strange ones */
#if LINUX_VERSION_CODE < 0x020200
#  error \"This module needs kmod, so it won\'t run with 2.0\"
#else


#include <linux/kernel.h>
//#include <linux/malloc.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/usb.h>

#if 0
  #include \"sysdep.h\"
#else
  #include \"usb-sysdep.h\"
#endif


#define _BULK_DATA_LEN 64
typedef struct
{
unsigned char data[_BULK_DATA_LEN];
unsigned int size;
unsigned int pipe;
}bulk_transfer_t,*pbulk_transfer_t;

#define DABUSB_MINOR 240
#define DABUSB_VERSION 0x1000
#define IOCTL_DAB_BULK              _IOWR(\'d\', 0x30, bulk_transfer_t)
#define IOCTL_DAB_OVERRUNS    _IOR(\'d\',  0x15, int)
#define IOCTL_DAB_VERSION           _IOR(\'d\', 0x3f, int)
#define IOCTL_DAB_REMOVED           _IOR(\'d\', 0x40, int)

#ifdef __KERNEL__

typedef enum { _stopped=0, _started } driver_state_t;

typedef struct
{
struct semaphore mutex;
struct usb_device *usbdev;
wait_queue_head_t wait;
wait_queue_head_t remove_ok;
spinlock_t lock;
atomic_t pending_io;
driver_state_t state;
int remove_pending;
int got_mem;
int total_buffer_size;
unsigned int overruns;
int readptr;
int opened;
struct list_head free_buff_list;
struct list_head rec_buff_list;
int  index;                        //address which should be set
} dabusb_t,*pdabusb_t;

typedef struct
{
pdabusb_t s;
purb_t purb;
struct list_head buff_list;
} buff_t,*pbuff_t;

typedef struct
{
wait_queue_head_t wait;
} bulk_completion_context_t, *pbulk_completion_context_t;


#define _DABUSB_IF 2
#define _DABUSB_ISOPIPE 0x09
#define _ISOPIPESIZE 16384

#define _BULK_DATA_LEN 64
// Vendor specific request code for Anchor Upload/Download
// This one is implemented in the core
#define ANCHOR_LOAD_INTERNAL  0xA0

// EZ-USB Control and Status Register.  Bit 0 controls 8051 reset
#define CPUCS_REG    0x7F92
#define _TOTAL_BUFFERS 384

#define MAX_INTEL_HEX_RECORD_LENGTH 16

#ifndef _BYTE_DEFINED
#define _BYTE_DEFINED
typedef unsigned char BYTE;
#endif // !_BYTE_DEFINED

#ifndef _WORD_DEFINED
#define _WORD_DEFINED
typedef unsigned short WORD;
#endif // !_WORD_DEFINED

typedef struct _INTEL_HEX_RECORD
{
BYTE  Length;
WORD  Address;
BYTE  Type;
BYTE  Data[MAX_INTEL_HEX_RECORD_LENGTH];
} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/*
 * We need a local data structure, as it must be allocated for each new
 * mouse device plugged in the USB bus
 */
struct usbsample_device {
    unsigned char data[8];   /* enough for keyboard and mouse protocols */
    char *name;              /* either \"kdb\" or \"mouse\" */
    struct urb urb;          /* USB Request block, to get USB data*/
    int maxp;                /* packet len */
    char output[80];         /* used for printk at irq time */
};

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/*
 * Handler for data sent in by the device. The function is called by
 * the USB kernel subsystem whenever a device spits out new data
 */
static void usbsample_irq(struct urb *urb)
{
    struct usbsample_device *usbsample = urb->context;
    char *pos = usbsample->output;
    int i;

    if (urb->status != USB_ST_NOERROR) return;

    pos += sprintf(pos, \"usbusbsample: data from %-8s =\",
  usbsample->name);
    for (i=0; i<usbsample->maxp; i++) {
pos += sprintf(pos, \" %02x\", usbsample->data);
    }
    printk(KERN_INFO \"%s\\n\", usbsample->output);
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/*
 * These two callbacks are invoked when an USB device is detached or attached
 * to the bus
 */

static void usbsample_disconnect(struct usb_device *udev, void *clientdata)
{
    /* the clientdata is the usbsample_device we passed originally */
    struct usbsample_device *usbsample = clientdata;

    /* remove the URB, remove the input device, free memory */
    usb_unlink_urb(&usbsample->urb);
    kfree(usbsample);
    printk(KERN_INFO \"usbsample: USB %s disconnected\\n\", usbsample->name);

    /*
     * here you might MOD_DEC_USE_COUNT, but only if you increment
     * the count in usbsample_probe() below
     */
    return;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

static void *usbsample_probe(struct usb_device *udev, unsigned int ifnum,
 const struct usb_device_id *id)
{
    /*
     * The probe procedure is pretty standard. Device matching has already
     * been performed based on the id_table structure (defined later)
     */
    struct usb_interface *iface;
    struct usb_interface_descriptor *interface;
    struct usb_endpoint_descriptor *endpoint;
    struct usbsample_device *usbsample;

    printk(KERN_INFO \"usbusbsample: probe called for %s device\\n\",
  (char *)id->driver_info /* \"mouse\" or \"keyboard\" */ );

    iface = &udev->actconfig->interface[ifnum];
    interface = &iface->altsetting[iface->act_altsetting];

    if (interface->bNumEndpoints != 1) return NULL;

    endpoint = interface->endpoint + 0;
    if (!(endpoint->bEndpointAddress & 0x80)) return NULL;
    if ((endpoint->bmAttributes & 3) != 3) return NULL;

    usb_set_protocol(udev, interface->bInterfaceNumber, 0);
    usb_set_idle(udev, interface->bInterfaceNumber, 0, 0);

    /* allocate and zero a new data structure for the new device */
    usbsample = kmalloc(sizeof(struct usbsample_device), GFP_KERNEL);
    if (!usbsample) return NULL; /* failure */
    memset(usbsample, 0, sizeof(*usbsample));
    usbsample->name = (char *)id->driver_info;

    /* fill the URB data structure using the FILL_INT_URB macro */
    {
int pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress);
int maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe));

if (maxp > 8) maxp = 8; usbsample->maxp = maxp; /* remember for later */
FILL_INT_URB(&usbsample->urb, udev, pipe, usbsample->data, maxp,
     usbsample_irq, usbsample, endpoint->bInterval);
    }

    /* register the URB within the USB subsystem */
    if (usb_submit_urb(&usbsample->urb)) {
kfree(usbsample);
return NULL;
    }
    /* announce yourself */
    printk(KERN_INFO \"usbusbsample: probe successful for %s (maxp is %i)\\n\",
  usbsample->name, usbsample->maxp);

    /*
     * here you might MOD_INC_USE_COUNT; if you do, you\'ll need to unplug
     * the device or the devices before being able to unload the module
     */

    /* and return the new structure */
    return usbsample;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/*
 * The id_table, lists all devices that can be handled by this driver.
 * The three numbers are class, subclass, protocol. <linux/usb.h> has
 * more details about interface mathces and vendor/device matches.
 * This feature is not there in version 2.2, see below, usbsample_probe_22()
 * for details. Here we use a fake usb_device_id structure defined in
 * ./usb-sysdep.h
 */
static struct usb_device_id usbsample_id_table [] = {
    {
USB_INTERFACE_INFO(3, 1, 1),
driver_info: (unsigned long)\"keyboard\"
    },
    {
USB_INTERFACE_INFO(3, 1, 2),
driver_info: (unsigned long)\"mouse\"
    },
{
USB_INTERFACE_INFO(3,0,0),
driver_info:(unsigned long)\"usbsample\"
},
    {
0, /* no more matches */
    }
};
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
/*
 * The callbacks are registered within the USB subsystem using the
 * usb_driver data structure
 */
#ifdef LINUX_24
static struct usb_driver usbsample_usb_driver = {
        name:        \"usbsample\",
        probe:       usbsample_probe,
        disconnect:  usbsample_disconnect,
fops: &usbsample_fops,
minor: DABUSB_MINOR,
id_table:    usbsample_id_table,
};

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

static struct file_operations usbsample_fops =
{
owner: THIS_MODULE,
//llseek: usbsample_llseek,
read: usbsample_read,
write:      usbsample_write,
//poll:           usbsample_poll,
ioctl: usbsample_ioctl,
open: usbsample_open,
release: usbsample_release,
};


/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

/*static loff_t usbsample_llseek (struct file *file, loff_t offset, int origin)
{
return -ESPIPE;
}*/
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////


static dabusb_t dabusb;

static int usbsample_open (struct inode *inode, struct file *file)
{
int devnum = MINOR (inode->i_rdev);
pdabusb_t s;

if (devnum != DABUSB_MINOR)
return -EIO;

s = &dabusb;

dbg(\"dabusb_open\");

// down (&s->mutex);
if (!s->usbdev) {
// up (&s->mutex);
return -ENODEV;
}

if(s->opened) {
// up (&s->mutex);
return -EBUSY;
}

if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
err(\"set_interface failed\");
// up (&s->mutex);
return -EINVAL;
}
s->opened = 1;
// up (&s->mutex);
file->f_pos = 0;
file->private_data = s;
MOD_INC_USE_COUNT;
return 0;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

static int dabusb_stop (pdabusb_t s)
{
dbg(\"dabusb_stop\");

s->state = _stopped;
//dabusb_cancel_queue (s, &s->rec_buff_list);

dbg(\"pending_io: %d\", s->pending_io.counter);

s->pending_io.counter = 0;
return 0;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

static int dabusb_free_buffers (pdabusb_t s)
{
unsigned long flags;
dbg(\"dabusb_free_buffers\");
//spin_lock_irqsave(&s->lock, flags);
//dabusb_free_queue (&s->free_buff_list);
//dabusb_free_queue (&s->rec_buff_list);
//spin_unlock_irqrestore(&s->lock, flags);
s->got_mem = 0;
return 0;
}

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
static int usbsample_release (struct inode *inode, struct file *file)
{
pdabusb_t s = (pdabusb_t) file->private_data;

dbg(\"dabusb_release\");

lock_kernel();
// down (&s->mutex);
dabusb_stop (s);
dabusb_free_buffers (s);
// up (&s->mutex);

if (!s->remove_pending) {
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
err(\"set_interface failed\");
}
else
wake_up (&s->remove_ok);

s->opened = 0;
unlock_kernel();
MOD_DEC_USE_COUNT;
return 0;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

static ssize_t usbsample_read (struct file *file, char *buf, size_t count, loff_t * ppos)
{
pdabusb_t s = (pdabusb_t) file->private_data;
unsigned long flags;
unsigned ret = 0;
int rem;
int cnt;
pbuff_t b;
purb_t purb = NULL;

dbg(\"dabusb_read\");

if (*ppos)
return -ESPIPE;

if (s->remove_pending)
return -EIO;


if (!s->usbdev)
return -EIO;

usb_control_msg(s->usbdev,usb_rcvctrlpipe(s->usbdev, 0),
0x16,USB_DIR_IN|USB_RECIP_ENDPOINT,0,0x0000,
buf,count,0);
// down(&s->mutex);


}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
static ssize_t usbsample_write (struct file *file, char *buf, size_t count, loff_t * ppos)
{
pdabusb_t s = (pdabusb_t) file->private_data;
unsigned long flags;
unsigned ret = 0;
int rem;
int cnt;
pbuff_t b;
purb_t purb = NULL;

dbg(\"dabusb_read\");

if (*ppos)
return -ESPIPE;

if (s->remove_pending)
return -EIO;


if (!s->usbdev)
return -EIO;

usb_control_msg(s->usbdev,usb_rcvctrlpipe(s->usbdev, 0),
0x17,USB_RECIP_ENDPOINT,0,0x0000,
buf,count,0);
// down(&s->mutex);


}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
static int usbsample_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
pdabusb_t s = (pdabusb_t) file->private_data;
pbulk_transfer_t pbulk;
int ret = 0;
int version = DABUSB_VERSION;

dbg(\"dabusb_ioctl\");

if (s->remove_pending)
return -EIO;

// down (&s->mutex);

if (!s->usbdev) {
// up (&s->mutex);
return -EIO;
}

switch (cmd) {

case IOCTL_DAB_BULK:
{
   ret = copy_from_user (s->index, (void *) arg, sizeof (int)) ;
break;
}

default:
{
ret = -ENOIOCTLCMD;
break;
}
}
// up (&s->mutex);
return ret;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

#else /* 2.2 */

/*
 * With version 2.2, there is no device_id support: the probe function
 * is called for every device being plugged, and it must select whether
 * the device is going to be handled or not. Here we extract the identification
 * phase (based on class/subclass/protocol in this case) and rely on
 * usbsample_probe() above for the interesting part of the game. Note
 * that a 2.4 driver can use this approach as well, by not defining an
 * id table (and achieving a 2.2 and 2.4 source with less ifdef). We think
 * the id_table way is much cleaner, so we chose to exploit it where available
 */
static void *usbsample_probe_22(struct usb_device *udev, unsigned int ifnum)
{
    struct usb_device_id *id;
    struct usb_interface_descriptor *interface;

    printk(KERN_INFO \"usbsample_probe_22 called\\n\");
    if (udev->descriptor.bNumConfigurations != 1) return NULL;
    interface = udev->config[0].interface[ifnum].altsetting;

    for (id = usbsample_id_table; id->driver_info; id++) {
        if (interface->bInterfaceClass !=    id->class)    continue;
        if (interface->bInterfaceSubClass != id->subclass) continue;
        if (interface->bInterfaceProtocol != id->protocol) continue;
break; /* found */
    }
    if (!id->driver_info)
return NULL; /* not ours */

    return usbsample_probe(udev, ifnum, id);
}

static struct usb_driver usbsample_usb_driver = {
        name:        \"usbsample\",
        probe:       usbsample_probe_22,
        disconnect:  usbsample_disconnect,
/* no id_table field here */
};

#endif /* 2.2 */

/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////

/*
 * Functions called at module load and unload time: only register and
 * unregister the USB callbacks
 */
int usbsample_init(void)
{
    /* just register it, returns 0 or error code */
    return usb_register(&usbsample_usb_driver);
}

void usbsample_exit(void)
{
    usb_deregister(&usbsample_usb_driver);
}

module_init(usbsample_init);
module_exit(usbsample_exit);

#endif /* no 2.0 */
痛并快乐着!
ellipse
驱动牛犊
驱动牛犊
  • 注册日期2002-12-02
  • 最后登录2006-04-30
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-01-16 11:32
你在定义usbsample_usb_driver的时候用到了usbsample_fops
但那个时候你还没有定义过usbsample_fops
同样的,你在定义usbsample_fops的时候也没有定义
usbsample_read等函数,
你试试先定义usbsample_read等函数,再定义usbsample_fops
在定义usbsample_usb_driver
flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-01-16 13:39
太谢谢了ellipse,确实如此,现在问题解决了!  :) :)
痛并快乐着!
flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-01-16 13:47
奇怪,怎么给不了分阿
痛并快乐着!
ellipse
驱动牛犊
驱动牛犊
  • 注册日期2002-12-02
  • 最后登录2006-04-30
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-01-16 15:35
你的这个问题的分都给没有了
 :(
flywithlove
驱动小牛
驱动小牛
  • 注册日期2002-11-05
  • 最后登录2009-10-09
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望18点
  • 贡献值0点
  • 好评度10点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-01-16 17:44
不要急,我看到另外一个帖子你也回答了,那个帖子我给了40分,过两天我就会结帐 :D :D
痛并快乐着!
游客

返回顶部