USB 3G上网卡的模式切换

本文探讨了为何需要对USB 3G上网卡进行模式切换,并介绍了Linux下两种切换方法:使用用户空间工具usb-modeswitch和修改内核代码。详细解析了内核文件中的相关定义和函数调用过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 为什么要对USB 3G上网卡做模式切换?

从使用过的华为和ZTE的上网卡来看,它们都使用了Zero-CD。例如:在Windows PC上第一次插入上网卡,只有一个用于Mass Storage的Interface,在用户看来也就是显示出来一个U盘或光驱,里面存储的是驱动程序。安装驱动程序,在驱动正常工作后,其余几个Interface就显现出来,于是你看到了Modem,你运行相关的软件就可以拨号上网了。

二. Linux下的模式切换有如下方式。

1. 在用户空间使用 usb-modeswitch 来切换。

工具下载地址:http://www.draisberghof.de/usb_modeswitch


2. 修改内核代码加入对USB 3G上网卡的支持。

linux内核: 2.6.30.9

2.1. 在 unusual_devs.h 中加入如下内容

/* added to support HuaWei dongle 
 * K3765 ---> 0x1520
 * K3520 ---> 0x1001
 * K4505 ---> 0x1521
 * E1756 ---> 0x1446
 */
UNUSUAL_DEV( 0x12d1, 0x1520, 0x0000, 0x0000,
		"HUAWEI",
		"HSPA K3765",
		US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_scsi_init,
		0),
UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
		"HUAWEI",
		"HSPA K3520",
		US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_scsi_init,
		0),
UNUSUAL_DEV( 0x12d1, 0x1C24, 0x0000, 0xffff,
		"HUAWEI",
		"HSPA E173",
		US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_scsi_init,
		0),
UNUSUAL_DEV( 0x12d1, 0x1521, 0x0000, 0x0000,
		"HUAWEI",
		"HSPA K4505",
		US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_scsi_init,
		0),
UNUSUAL_DEV( 0x12d1, 0x1446, 0x0000, 0x0000,
		"HUAWEI",
		"HSPA E1756",
		US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_scsi_init,
		0),


2.2. 在initialize.c 中实现函数 usb_stor_huawei_scsi_init

/* added to support HuaWei dongles. */
int usb_stor_huawei_scsi_init(struct us_data *us) 
{ 
     int result = 0;
     int act_len = 0;
     unsigned char cmd[32] = { 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 
                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 
                               0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                               0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00 };
     
     result = usb_stor_bulk_transfer_buf (us, us->send_bulk_pipe, cmd, 31, &act_len);

     US_DEBUGP("usb_stor_bulk_transfer_buf performing result is %d, transfer the actual length=%d\n", result, act_len);

     return result;
}

在上述2个文件中加入所示代码后,重编内核,即可完成对相应3G上网卡的切换。


3. 分析一下相关代码

在 storage/usual-tables.c 中有如下定义:

struct usb_device_id usb_storage_usb_ids[] = {
#	include "unusual_devs.h"
	{ }		/* Terminating entry */
};
EXPORT_SYMBOL_GPL(usb_storage_usb_ids);

在storage/usb.c 中也有一个类似的定义:

static struct us_unusual_dev us_unusual_dev_list[] = {
#	include "unusual_devs.h" 
	{ }		/* Terminating entry */
};

很显然这应该定义的是2个不同数据类型的数组,但是数组的每一个元素对应到unusual_devs.h中,则是相同的。

即数组中相同index指向了unusual_devs.h 中的同一个东西,但是却各自表述。(很有点92共识的味道。)


当USB 3G上网卡插入的时候,在usb.c 中的函数 storage_probe(struct usb_interface *intf, const struct usb_device_id *id)

会被调用。注意该函数的参数 id, 根据上面的分析,可以很容易的根据这个usb_device_id 找到对应的us_unusual_dev,

(id - usb_storage_usb_ids) + us_unusual_dev_list, 相关代码如下:

/*
         * Call the general probe procedures.
         *
         * The unusual_dev_list array is parallel to the usb_storage_usb_ids
         * table, so we use the index of the id entry to find the
         * corresponding unusual_devs entry.
         */
        result = usb_stor_probe1(&us, intf, id,
                        (id - usb_storage_usb_ids) + us_unusual_dev_list);






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值