A. usbnet是否就是無線上網卡的驅動
大致是廳扒這樣的:
一、linux模擬U盤功能的實現
向內核添加扮鬧昌代碼
#include
#include
#include
修改arch/arm/mach-s3c2410/mach-smdk2410.c
/*USB device上拉電阻處理 */
static void smdk2410_udc_pullup(enum s3c2410_udc_cmd_e cmd)
{
u8 *s3c2410_pullup_info[] = {
" ",
"Pull-up enable",
"Pull-up disable",
"UDC reset, in case of"
};
printk("smdk2410_udc: %s\n",s3c2410_pullup_info[cmd]);
s3c2410_gpio_cfgpin(S3C2410_GPG9, S3C2410_GPG9_OUTP);
switch (cmd)
{
case S3C2410_UDC_P_ENABLE :
s3c2410_gpio_setpin(S3C2410_GPG9, 1); //set gpg9 output HIGH
break;
case S3C2410_UDC_P_DISABLE :
s3c2410_gpio_setpin(S3C2410_GPG9, 0); //set gpg9 output LOW
break;
case S3C2410_UDC_P_RESET :
//FIXME!!!
break;
default:
break;
}
}
static struct s3c2410_udc_mach_info smdk2410_udc_cfg __initdata = {
.udc_command = smdk2410_udc_pullup,
};
static struct platform_device *smdk2410_devices[] __initdata = {
…,
&s3c_device_usbgadget, /*USB gadget device設備登記*/
};
static void __init sdmk2410_init(void)
{
u32 upll_value;
set_s3c2410fb_info(&smdk2410_lcdcfg);
s3c24xx_udc_set_platdata(&smdk2410_udc_cfg); /* 初始化*/
s3c_device_sdi.dev.platform_data = &smdk2410_mmc_cfg;
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
S3C2410_MISCCR_USBSUSPND0 |
S3C2410_MISCCR_USBSUSPND1, 0x0);
/* 設置USB時鍾 */
upll_value = (
0x78 << S3C2410_PLLCON_MDIVSHIFT)
| (0x02 << S3C2410_PLLCON_PDIVSHIFT)
| (0x03 << S3C2410_PLLCON_SDIVSHIFT);
while (upll_value != readl(S3C2410_UPLLCON)) {
writel(upll_value, S3C2410_UPLLCON);
udelay(20);
}
}
修改drivers/usb/gadget/file_storage.c
static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep,
struct usb_request *req, int *pbusy,
enum fsg_buffer_state *state)
{
int rc;
udelay(800);
……
}
配置內核支彎啟持U盤模擬
<*> USB Gadget Support --->
USB Peripheral Controller (S3C2410 USB Device Controller) --->
S3C2410 USB Device Controller
S3C2410 udc debug messages
USB Gadget Drivers
File-backed Storage Gadget
3、編譯內核
#make zImage
#make moles
在目錄drivers/usb/gadget下生成g_file_storage.ko
載入驅動,測試功能
利用前面的生成的內核,啟動系統後,載入g_file_storage.ko
#insmod g_file_storage.ko
# insmod g_file_storage.ko file=/dev/mtdblock2 stall=0 removable=1
0.03 USB: usb_gadget_register_driver() 'g_file_storage'
0.04 USB: binding gadget driver 'g_file_storage'
0.05 USB: s3c2410_set_selfpowered()
g_file_storage gadget: File-backed Storage Gadget, version: 20 October 2004
g_file_storage gadget: Number of LUNs=1
g_file_storage gadget-lun0: ro=0, file: /dev/mtdblock3
0.06 USB: udc_enable called
smdk2410_udc: Pull-up enable
連接設備到windows,windows系統會自動設備到一個新的U盤加入。格式化U盤,存入文件。卸載U盤後,在目標板上執行如下操作:
# mkdir /mnt/gadget
# mount -t vfat /dev/mtdblock2 /mnt/gadget/
#ls
可以看到windows存入U盤的文件。
二、usbnet功能的實現
配置內核支持usbnet
<*> USB Gadget Support --->
USB Peripheral Controller (S3C2410 USB Device Controller) --->
S3C2410 USB Device Controller
S3C2410 udc debug messages
USB Gadget Drivers
Ethernet Gadget (with CDC Ethernet support)
RNDIS support
2、編譯內核
#make zImage
#make moles
在目錄drivers/usb/gadget下生成g_ether.ko
3、載入驅動,測試功能
利用前面的生成的內核,啟動系統後,載入g_ether.ko
#insmod g_ether.ko
#ifconfig usb0 192.168.1.120
……
usb0 Link encap:Ethernet HWaddr 5E:C5:F6:D4:2B:91
inet addr:192.168.1.120 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:253 errors:0 dropped:0 overruns:0 frame:0
TX packets:43 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:35277 (34.4 KiB) TX bytes:10152 (9.9 KiB)
B. 怎樣寫linux下的USB設備驅動程序
寫一個USB的驅動程序最 基本的要做四件事:驅動程序要支持的設備、注冊USB驅動程序、探測和斷開、提交和控制urb(USB請求塊)
驅動程序支持的設備:有一個結構體struct usb_device_id,這個結構體提供了一列不同類型的該驅動程序支持的USB設備,對於一個只控制一個特定的USB設備的驅動程序來說,struct usb_device_id表被定義為:
/* 驅動程序支持的設備列表 */
static struct usb_device_id skel_table [] = {
{ USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
{ } /* 終止入口 */
};
MODULE_DEVICE_TABLE (usb, skel_table);
對 於PC驅動程序,MODULE_DEVICE_TABLE是必需的,而且usb必需為該宏的第一個值,而USB_SKEL_VENDOR_ID和 USB_SKEL_PRODUCT_ID就是這個特殊設備的製造商和產品的ID了,我們在程序中把定義的值改為我們這款USB的,如:
/* 定義製造商和產品的ID號 */
#define USB_SKEL_VENDOR_ID 0x1234
#define USB_SKEL_PRODUCT_ID 0x2345
這兩個值可以通過命令lsusb,當然你得先把USB設備先插到主機上了。或者查看廠商的USB設備的手冊也能得到,在我機器上運行lsusb是這樣的結果:
Bus 004 Device 001: ID 0000:0000
Bus 003 Device 002: ID 1234:2345 Abc Corp.
Bus 002 Device 001: ID 0000:0000
Bus 001 Device 001: ID 0000:0000
得到這兩個值後把它定義到程序里就可以了。
注冊USB驅動程序:所 有的USB驅動程序都必須創建的結構體是struct usb_driver。這個結構體必須由USB驅動程序來填寫,包括許多回調函數和變數,它們向USB核心代碼描述USB驅動程序。創建一個有效的 struct usb_driver結構體,只須要初始化五個欄位就可以了,在框架程序中是這樣的:
static struct usb_driver skel_driver = {
.owner = THIS_MODULE,
.name = "skeleton",
.probe = skel_probe,
.disconnect = skel_disconnect,
.id_table = skel_table,
};
探測和斷開:當 一個設備被安裝而USB核心認為該驅動程序應該處理時,探測函數被調用,探測函數檢查傳遞給它的設備信息,確定驅動程序是否真的適合該設備。當驅動程序因 為某種原因不應該控制設備時,斷開函數被調用,它可以做一些清理工作。探測回調函數中,USB驅動程序初始化任何可能用於控制USB設備的局部結構體,它 還把所需的任何設備相關信息保存到一個局部結構體中,
提交和控制urb:當驅動程序有數據要發送到USB設備時(大多數情況是在驅動程序的寫函數中),要分配一個urb來把數據傳輸給設備:
/* 創建一個urb,並且給它分配一個緩存*/
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
retval = -ENOMEM;
goto error;
}
當urb被成功分配後,還要創建一個DMA緩沖區來以高效的方式發送數據到設備,傳遞給驅動程序的數據要復制到這塊緩沖中去:
buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
retval = -ENOMEM;
goto error;
}
if (_from_user(buf, user_buffer, count)) {
retval = -EFAULT;
goto error;
}
當數據從用戶空間正確復制到局部緩沖區後,urb必須在可以被提交給USB核心之前被正確初始化:
/* 初始化urb */
usb_fill_bulk_urb(urb, dev->udev,
usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
buf, count, skel_write_bulk_callback, dev);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
然後urb就可以被提交給USB核心以傳輸到設備了:
/* 把數據從批量OUT埠發出 */
retval = usb_submit_urb(urb, GFP_KERNEL);
if (retval) {
err("%s - failed submitting write urb, error %d", __FUNCTION__, retval);
goto error;
}
當urb被成功傳輸到USB設備之後,urb回調函數將被USB核心調用,在我們的例子中,我們初始化urb,使它指向skel_write_bulk_callback函數,以下就是該函數:
static void skel_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
{
struct usb_skel *dev;
dev = (struct usb_skel *)urb->context;
if (urb->status &&
!(urb->status == -ENOENT ||
urb->status == -ECONNRESET ||
urb->status == -ESHUTDOWN)) {
dbg("%s - nonzero write bulk status received: %d",
__FUNCTION__, urb->status);
}
/* 釋放已分配的緩沖區 */
usb_buffer_free(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
}
有時候USB驅動程序只是要發送或者接收一些簡單的數據,驅動程序也可以不用urb來進行數據的傳輸,這是里涉及到兩個簡單的介面函數:usb_bulk_msg和usb_control_msg ,在這個USB框架程序里讀操作就是這樣的一個應用:
/* 進行阻塞的批量讀以從設備獲取數據 */
retval = usb_bulk_msg(dev->udev,
usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
dev->bulk_in_buffer,
min(dev->bulk_in_size, count),
&count, HZ*10);
/*如果讀成功,復制到用戶空間 */
if (!retval) {
if (_to_user(buffer, dev->bulk_in_buffer, count))
retval = -EFAULT;
else
retval = count;
}
usb_bulk_msg介面函數的定義如下:
int usb_bulk_msg(struct usb_device *usb_dev,unsigned int pipe,
void *data,int len,int *actual_length,int timeout);
其參數為:
struct usb_device *usb_dev:指向批量消息所發送的目標USB設備指針。
unsigned int pipe:批量消息所發送目標USB設備的特定端點,此值是調用usb_sndbulkpipe或者usb_rcvbulkpipe來創建的。
void *data:如果是一個OUT端點,它是指向即將發送到設備的數據的指針。如果是IN端點,它是指向從設備讀取的數據應該存放的位置的指針。
int len:data參數所指緩沖區的大小。
int *actual_length:指向保存實際傳輸位元組數的位置的指針,至於是傳輸到設備還是從設備接收取決於端點的方向。
int timeout:以Jiffies為單位的等待的超時時間,如果該值為0,該函數一直等待消息的結束。
如果該介面函數調用成功,返回值為0,否則返回一個負的錯誤值。
usb_control_msg介面函數定義如下:
int usb_control_msg(struct usb_device *dev,unsigned int pipe,__u8 request,__u8requesttype,__u16 value,__u16 index,void *data,__u16 size,int timeout)
除了允許驅動程序發送和接收USB控制消息之外,usb_control_msg函數的運作和usb_bulk_msg函數類似,其參數和usb_bulk_msg的參數有幾個重要區別:
struct usb_device *dev:指向控制消息所發送的目標USB設備的指針。
unsigned int pipe:控制消息所發送的目標USB設備的特定端點,該值是調用usb_sndctrlpipe或usb_rcvctrlpipe來創建的。
__u8 request:控制消息的USB請求值。
__u8 requesttype:控制消息的USB請求類型值。
__u16 value:控制消息的USB消息值。
__u16 index:控制消息的USB消息索引值。
void *data:如果是一個OUT端點,它是指身即將發送到設備的數據的指針。如果是一個IN端點,它是指向從設備讀取的數據應該存放的位置的指針。
__u16 size:data參數所指緩沖區的大小。
int timeout:以Jiffies為單位的應該等待的超時時間,如果為0,該函數將一直等待消息結束。
如果該介面函數調用成功,返回傳輸到設備或者從設備讀取的位元組數;如果不成功它返回一個負的錯誤值。
這兩個介面函數都不能在一個中斷上下文中或者持有自旋鎖的情況下調用,同樣,該函數也不能被任何其它函數取消,使用時要謹慎。
我們要給未知的USB設備寫驅動程序,只需要把這個框架程序稍做修改就可以用了,前面我們已經說過要修改製造商和產品的ID號,把0xfff0這兩個值改為未知USB的ID號。
#define USB_SKEL_VENDOR_ID 0xfff0
#define USB_SKEL_PRODUCT_ID 0xfff0
還 有就是在探測函數中把需要探測的介面端點類型寫好,在這個框架程序中只探測了批量(USB_ENDPOINT_XFER_BULK)IN和OUT端點,可 以在此處使用掩碼(USB_ENDPOINT_XFERTYPE_MASK)讓其探測其它的端點類型,驅動程序會對USB設備的每一個介面進行一次探測, 當探測成功後,驅動程序就被綁定到這個介面上。再有就是urb的初始化問題,如果你只寫簡單的USB驅動,這塊不用多加考慮,框架程序里的東西已經夠用 了,這里我們簡單介紹三個初始化urb的輔助函數:
usb_fill_int_urb :它的函數原型是這樣的:
void usb_fill_int_urb(struct urb *urb,struct usb_device *dev,
unsigned int pipe,void *transfer_buff,
int buffer_length,usb_complete_t complete,
void *context,int interval);
這個函數用來正確的初始化即將被發送到USB設備的中斷端點的urb。
usb_fill_bulk_urb :它的函數原型是這樣的:
void usb_fill_bulk_urb(struct urb *urb,struct usb_device *dev,
unsigned int pipe,void *transfer_buffer,
int buffer_length,usb_complete_t complete)
這個函數是用來正確的初始化批量urb端點的。
usb_fill_control_urb :它的函數原型是這樣的:
void usb_fill_control_urb(struct urb *urb,struct usb_device *dev,unsigned int pipe,unsigned char *setup_packet,void *transfer_buffer,int buffer_length,usb_complete_t complete,void *context);
這個函數是用來正確初始化控制urb端點的。
還有一個初始化等時urb的,它現在還沒有初始化函數,所以它們在被提交到USB核心前,必須在驅動程序中手工地進行初始化,可以參考內核源代碼樹下的/usr/src/~/drivers/usb/media下的konicawc.c文件。
C. USB驅動的組成有哪些
在USB規范中把USB分為五個部分:控制器、控制器驅動程序、USB晶元驅動程序、USB設備和針對不同USB設備的客戶驅動程序。第一、 USB晶元驅動程序:這部分組件主要是可以提供對USB的支持。第二、 USB控制器驅動程序:這部分主要是在控制器和USB設備之間建立通信信道。第三、 USB設備:這部分組件包括和PC相連的USB外圍設備,主要分為:設備本身可以再接上其它的USB外圍設備,另外設備本身不能再連接其它外圍設備。即集線器和設備。也可以說集線器是帶有連接其它外圍設備的USB埠,設備是連接在計算機上的用語完成特定功能而且符合USB規范的設備單元。第四、 USB控制器:這部分主要負責執行由USB控制器驅動程序發出的命令。第五、 USB設備驅動程序:這部分組件主要是用來驅動USB設備的程序,一般來說這是由操作系統或者是USB設備製造商提供
D. Linux ksuspend_usbd 是什麼進程
這個佔80埠肯定不對,這是usb初始的進程,不需要可能關掉,或者改埠。
E. linux 如何立刻suspend usb
suspend:
#disableexternalwake-up;dothisonlyonce
echodisabled>/sys/bus/usb/devices/usb1/power/wakeup
echosuspend>/sys/bus/usb/devices/usb1/power/level#turnoff
wake up:
echoon>/sys/bus/usb/devices/usb1/power/level#turnon
根據你的實際情況修版改權usb1為usb n