WebUSB .claimInterface never returns on Windows - webusb

I have been working on an website that uses WebUSB. The WebUSB library works 100% on Linux and Android. Unfortunately on Windows the promise returned by .claimInterface never returns anything, ever. And when I, for interest sake, run the claimInterface again the returned promise returns the error "An operation that changes state is in progress", confirming that the first claimInterface function is still busy.
The problem only occurs when claiming interface 1, claiming interface 0 works, but this interface is of no use to me. The USB device is not standard (descriptor dieplayed below) so it might be something about the device configuration, but it is really hard to tell with the lack of logs.
I did try and look at chrome://device-log?refresh=1 for additional logs, but only the plug events are dislpayed. I also enabled the new USB backend at chrome://flags/#new-usb-backend to no avail. I also tried running chrome with the --enable-loging --v1, but the only error that seemed relevant is: ERROR:device_event_log_impl.cc(211)] [01:32:33.170] USB: usb_device_handle_win.cc:1020 Failed to read descriptor from node connection: A device attached to the system is not functioning. (0x1F) .
But this error is logged before I have even connected a device, also discussed here, so I do not even know if it is relevant.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 2 Communications
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0xXXXX XXX
idProduct 0xXXXX
bcdDevice 1.01
iManufacturer 1 XXX
iProduct 2 XXX
iSerial 3 XXX
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x0030
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x40
(Missing must-be-set bit!)
Self Powered
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0
bInterfaceProtocol 1
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 32
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 10 CDC Data
bInterfaceSubClass 0
bInterfaceProtocol 1
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 32
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 32
can't get device qualifier: Resource temporarily unavailable
can't get debug descriptor: Resource temporarily unavailable
Device Status: 0x0001
Self Powered
The driver installation is almost identical to the WinUSB predescribed method.
[Version]
DriverVer=XX/XX/XXXX,X.X.X.X
Signature = "$Windows NT$"
Class = USBDevice
ClassGuid = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %ManufacturerName%
CatalogFile = XXX.cat
[ClassInstall32]
AddReg = ClassInstall_AddReg
[ClassInstall_AddReg]
HKR,,,,%ClassName%
HKR,,NoInstallClass,,1
HKR,,IconPath,%REG_MULTI_SZ%,"%systemroot%\system32\setupapi.dll,-20"
HKR,,LowerLogoVersion,,5.2
[WinUSBDeviceClassReg]
HKR,,,0,%ClassName%
HKR,,Icon,,-20
[Manufacturer]
%ManufacturerName% = Standard,NTx86,NTamd64
[Standard.NTx86]
%DeviceName% = USB_Install, USB\%VendorID%&%ProductID%
[Standard.NTamd64]
%DeviceName% = USB_Install, USB\%VendorID%&%ProductID%
[USB_Install]
Include=winusb.inf
Needs=WINUSB.NT
[USB_Install.Services]
Include=winusb.inf
Needs=WINUSB.NT.Services
[USB_Install.HW]
AddReg=Dev_AddReg
[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
[Strings]
ManufacturerName = "XXX"
ClassName="Universal Serial Bus devices"
DeviceName = "XXX"
VendorID = "VID_XXX"
ProductID = "PID_XXX"
As well as a React App I used to test the library.
import { useEffect, useState } from 'react';
export default function App() {
const [devices, setDevices] = useState([]);
useEffect(function () {
update()
navigator.usb.addEventListener("connect", update);
navigator.usb.addEventListener("disconnect", update);
}, [])
return (
<div className="App">
<button onClick={refresh}>
<div>Refresh</div>
</button>
<button onClick={connect}>
<div>Connect</div>
</button>
</div>
);
function connect() {
let _device = devices[0]
if (_device) {
_device
.open()
.then(function () {
_device
.selectConfiguration(1)
.then(function () {
console.log("Connecting to interface")
_device
.claimInterface(1)
.then(function () {
console.log("Success");
})
.catch(console.error);
})
.catch(console.error);
})
.catch(console.error);
}
}
function update() {
navigator.usb.getDevices().then(function (_devices) {
setDevices(_devices)
});
}
function refresh() {
navigator.usb
?.requestDevice({
filters: [{ vendorId: 0xXXXX, productId: 0xXXXX }],
})
.then(update)
.catch(console.error);
}
}

I downloaded goole-chrome canary 89.0.4387.0 and it solved the problem. So I guess that is just google, solving the problem before I even asked the question.

Related

error device-tree: can't request region for resource [mem 0x01c20800-0x01c20aff]

ERROR SHOW:
[ 156.303744] blinkled: loading out-of-tree module taints kernel.
[ 156.303871] blinkled: module verification failed: signature and/or required key missing - tainting kernel
[ 156.304614] Good ! device probed! 65
[ 156.304644] demo_file 1c20800.gpioa7: can't request region for resource [mem 0x01c20800-0x01c20aff]
[ 156.304663] demo_file: probe of 1c20800.gpioa7 failed with error -16
[ 156.304747] The blinkled driver is success
MY CODE DEVICETREE:
gpioa7: gpioa7#1c20800{
reg = < 0x1c20800 0x300 >;
clocks = < 0x03 0x36 0x12 0x13 0x00 >;
clock-names = "apb\0hosc\0losc";
gpio-controller;
#gpio-cells = < 0x03 >;
gpios = < 0x0c 0x07 0x01 0x04 >;
input;
interrupt-controller;
#interrupt-cells = < 0x03 >;
interrupt-parent = < 0x01 >;
interrupts = < 0x01 0x00 0x48 0x08 >;
compatible = "gpio,input-pa7-pin";
status = "okay";
};
Think error is caused because dts has 2 nodes with same address:
soc {
pinctrl#1c20800 {
......
};
};
But i don't know how to fix it? Thanks!

Flags mismatch irq 32 Driver A vs Driver A

Generally flag mismatch is for driver A vs Driver B. Could you give some pointers to solve. We are using imx6ul board.
What is the way to debug this.
I have checked others driver as well and none of them is registering irq 32.
It looks like we are registering same driver twice.
Erorr:
[ 7.315153] input: 20cc000.snvs:snvs-powerkey as /devices/soc0/soc/2000000.aips-bus/20cc000.snvs/20cc000.snvs:snvs-powerkey/input/input0
[ 7.332058] genirq: Flags mismatch irq 32. 00000004 (20cc000.snvs:snvs-powerkey) vs. 00000004 (20cc000.snvs:snvs-powerkey)
[ 7.343879] snvs_pwrkey 20cc000.snvs:snvs-powerkey: interrupt not available.
[ 7.366705] snvs_pwrkey: probe of 20cc000.snvs:snvs-powerkey failed with error -16
[ 7.394971] snvs_rtc 20cc000.snvs:snvs-rtc-lp: registered as rtc0
DTS
snvs: snvs#020cc000 {
compatible = "fsl,sec-v4.0-mon", "syscon", "simple-mfd";
reg = <0x020cc000 0x4000>;
snvs_rtc: snvs-rtc-lp {
compatible = "fsl,sec-v4.0-mon-rtc-lp";
regmap = <&snvs>;
offset = <0x34>;
interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
};
snvs_poweroff: snvs-poweroff {
compatible = "syscon-poweroff";
regmap = <&snvs>;
offset = <0x38>;
value = <0x61>;
mask = <0x61>;
status = "disabled";
};
snvs_pwrkey: snvs-powerkey {
compatible = "fsl,sec-v4.0-pwrkey";
regmap = <&snvs>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
linux,keycode = <KEY_POWER>;
wakeup-source;
};
};

PCI driver 'Oops: Kernel access of bad area' error

I wanted to write a simple PCI express driver for Xilinx FPGA. But I am not able to request memory region for PCI.
Question is: How to claim that I/O memory area for custom driver. I want to write 3. byte of that area using driver.
Below are the details. What am I missing ? Thanks
1-) I am getting this error:
[ 4.345350] Unable to handle kernel paging request for data at address 0x00000005
[ 4.353978] Faulting instruction address: 0x80000000002c9370
[ 4.358337] Oops: Kernel access of bad area, sig: 11 [#1]
[ 4.362426] BE SMP NR_CPUS=24 CoreNet Generic
[ 4.365477] Modules linked in: fpgapcie(O+) ucc_uart
[ 4.369139] CPU: 0 PID: 1999 Comm: udevd Tainted: G O 4.19.26+gc0c2141 #1
[ 4.375924] NIP: 80000000002c9370 LR: 80000000002c9350 CTR: c00000000053acfc
[ 4.381753] REGS: c0000001ee2bb1c0 TRAP: 0300 Tainted: G O (4.19.26+gc0c2141)
[ 4.389146] MSR: 000000008002b000 <CE,EE,FP,ME> CR: 22228242 XER: 20000000
[ 4.394982] DEAR: 0000000000000005 ESR: 0000000000800000 IRQMASK: 0
GPR00: 80000000002c9350 c0000001ee2bb440 80000000002d1f00 000000000000001a
GPR04: 0000000000000001 000000000000022d c000000000f30548 c000000001013000
GPR08: 00000001fec37000 0000000000000003 0000000000000000 0000000000000020
GPR12: 0000000028228444 c000000001013000 0000000000020000 000000013c323ac8
GPR16: 000000013c323ae0 80000000002cc000 c000000000a194b0 c0000001f0eaa1c0
GPR20: 00000000006000c0 c000000000ed9da0 0000000000000000 0000000000000100
GPR24: 000000000000001c 000000000f700000 c0000001f3034880 0000000000000000
GPR28: c0000001f337b800 00000000000000f7 c0000001f337b8a0 0000000000000000
2-) Code piece in PCI probe function:
static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int ret, minor;
struct cdev *cdev;
dev_t devno;
unsigned long pci_io_addr = 0;
/* add this pci device in pci_cdev */
if ((minor = pci_cdev_add(pci_cdev, MAX_DEVICE, dev)) < 0)
goto error;
/* compute major/minor number */
devno = MKDEV(major, minor);
/* allocate struct cdev */
cdev = cdev_alloc();
/* initialise struct cde
cdev_init(cdev, &pci_ops);
cdev->owner = THIS_MODULE;
/* register cdev */
ret = cdev_add(cdev, devno, 1);
if (ret < 0) {
dev_err(&(dev->dev), "Can't register character device\n");
goto error;
}
pci_cdev[minor].cdev = cdev;
dev_info(&(dev->dev), "%s The major device number is %d (%d).\n",
"Registeration is a success", MAJOR(devno), MINOR(devno));
dev_info(&(dev->dev), "If you want to talk to the device driver,\n");
dev_info(&(dev->dev), "you'll have to create a device file. \n");
dev_info(&(dev->dev), "We suggest you use:\n");
dev_info(&(dev->dev), "mknod %s c %d %d\n", DEVICE_NAME, MAJOR(devno), MINOR(devno));
dev_info(&(dev->dev), "The device file name is important, because\n");
dev_info(&(dev->dev), "the ioctl program assumes that's the\n");
dev_info(&(dev->dev), "file you'll use.\n");
/* enable the device */
pci_enable_device(dev);
/* 'alloc' IO to talk with the card */
if (pci_request_region(dev, BAR_IO, "IO-pci") == 0) {
printk(KERN_ALERT "The memory you requested from fpgapcie is already reserved by CORE pci driver.");
}
check that BAR_IO is *really* IO region
if ((pci_resource_flags(dev, BAR_IO) & IORESOURCE_IO) != IORESOURCE_IO) {
dev_err(&(dev->dev), "BAR2 isn't an IO region\n");
cdev_del(cdev);
goto error;
}
pci_io_addr = pci_resource_start(dev,BAR_IO);
printk(KERN_INFO "PCI start adress: %02X", &pci_io_addr);
outb(pci_io_addr+3, 5);
printk(KERN_INFO "Message from PCI device to user: 5");
return 1;
error:
printk(KERN_INFO "An error occuder while probing pci");
return 0;
}
3-) lspci -v output:
0001:01:00.0 Memory controller: Xilinx Corporation Device 7021
Subsystem: Xilinx Corporation Device 0007
Flags: bus master, fast devsel, latency 0, IRQ 41
Memory at c10000000 (32-bit, non-prefetchable) [size=2K]
Capabilities: [40] Power Management version 3
Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
Capabilities: [60] Express Endpoint, MSI 00
Capabilities: [100] Device Serial Number 00-00-00-01-01-00-0a-35
Kernel driver in use: yusufpci
Kernel modules: fpgapcie
4-) full dmesg:
[ 4.285663] Module pci init
[ 4.294787] yusufpci 0001:01:00.0: Registeration is a success The major device number is 247 (0).
[ 4.302367] yusufpci 0001:01:00.0: If you want to talk to the device driver,
[ 4.308116] yusufpci 0001:01:00.0: you'll have to create a device file.
[ 4.313516] yusufpci 0001:01:00.0: We suggest you use:
[ 4.317354] yusufpci 0001:01:00.0: mknod virtual_pci c 247 0
[ 4.321713] yusufpci 0001:01:00.0: The device file name is important, because
[ 4.327553] yusufpci 0001:01:00.0: the ioctl program assumes that's the
[ 4.332866] yusufpci 0001:01:00.0: file you'll use.
[ 4.336459] The memory you requested from fpgapcie is already reserved by CORE pci driver. This is not an error.
[ 4.336463] PCI start adress: EE2BB4B0
[ 4.345350] Unable to handle kernel paging request for data at address 0x00000005
[ 4.353978] Faulting instruction address: 0x80000000002c9370
[ 4.358337] Oops: Kernel access of bad area, sig: 11 [#1]
[ 4.362426] BE SMP NR_CPUS=24 CoreNet Generic
[ 4.365477] Modules linked in: fpgapcie(O+) ucc_uart
[ 4.369139] CPU: 0 PID: 1999 Comm: udevd Tainted: G O 4.19.26+gc0c2141 #1
[ 4.375924] NIP: 80000000002c9370 LR: 80000000002c9350 CTR: c00000000053acfc
[ 4.381753] REGS: c0000001ee2bb1c0 TRAP: 0300 Tainted: G O (4.19.26+gc0c2141)
[ 4.389146] MSR: 000000008002b000 <CE,EE,FP,ME> CR: 22228242 XER: 20000000
[ 4.394982] DEAR: 0000000000000005 ESR: 0000000000800000 IRQMASK: 0
GPR00: 80000000002c9350 c0000001ee2bb440 80000000002d1f00 000000000000001a
GPR04: 0000000000000001 000000000000022d c000000000f30548 c000000001013000
GPR08: 00000001fec37000 0000000000000003 0000000000000000 0000000000000020
GPR12: 0000000028228444 c000000001013000 0000000000020000 000000013c323ac8
GPR16: 000000013c323ae0 80000000002cc000 c000000000a194b0 c0000001f0eaa1c0
GPR20: 00000000006000c0 c000000000ed9da0 0000000000000000 0000000000000100
GPR24: 000000000000001c 000000000f700000 c0000001f3034880 0000000000000000
GPR28: c0000001f337b800 00000000000000f7 c0000001f337b8a0 0000000000000000
[ 4.453632] NIP [80000000002c9370] .pci_probe+0x220/0x2b4 [fpgapcie]
[ 4.458680] LR [80000000002c9350] .pci_probe+0x200/0x2b4 [fpgapcie]
[ 4.463639] Call Trace:
[ 4.464775] [c0000001ee2bb440] [80000000002c9350] .pci_probe+0x200/0x2b4 [fpgapcie] (unreliable)
[ 4.472262] [c0000001ee2bb500] [c0000000004b77c8] .pci_device_probe+0x11c/0x1f4
[ 4.478270] [c0000001ee2bb5a0] [c000000000561ebc] .really_probe+0x26c/0x38c
[ 4.483927] [c0000001ee2bb640] [c0000000005621ac] .driver_probe_device+0x78/0x154
[ 4.490106] [c0000001ee2bb6d0] [c0000000005623d8] .__driver_attach+0x150/0x154
[ 4.496025] [c0000001ee2bb760] [c00000000055f424] .bus_for_each_dev+0x94/0xdc
[ 4.501856] [c0000001ee2bb800] [c0000000005615fc] .driver_attach+0x24/0x38
[ 4.507426] [c0000001ee2bb870] [c000000000560ec8] .bus_add_driver+0x264/0x2a4
[ 4.513258] [c0000001ee2bb910] [c000000000563384] .driver_register+0x88/0x178
[ 4.519089] [c0000001ee2bb990] [c0000000004b5a68] .__pci_register_driver+0x50/0x64
[ 4.525355] [c0000001ee2bba00] [80000000002c9564] .pci_init_module+0xc0/0x444 [fpgapcie]
[ 4.532144] [c0000001ee2bba80] [c0000000000020b4] .do_one_initcall+0x64/0x224
[ 4.537978] [c0000001ee2bbb50] [c0000000000f443c] .do_init_module+0x70/0x260
[ 4.543722] [c0000001ee2bbbf0] [c0000000000f6564] .load_module+0x1e6c/0x2400
[ 4.549467] [c0000001ee2bbd10] [c0000000000f6d28] .__se_sys_finit_module+0xcc/0x100
[ 4.555819] [c0000001ee2bbe30] [c0000000000006b0] system_call+0x60/0x6c
[ 4.561127] Instruction dump:
[ 4.562785] e86a8080 38810070 f9210070 4800041d e8410028 e9210070 3d420000 e94a8088
[ 4.569231] 39290003 5529063e e94a0000 7c0004ac <992a0005> 39200001 3d420000 992d0684
[ 4.575854] ---[ end trace 2d15cff7ba1b3255 ]---
Problem solved. But when I write the third byte of Memory Mapped area, FPGA programmed to answer with lighting its GPIO leds. I tried to write first 15 byte of MMIO but it did not work. The leds did not lighted. But the code stopped giving errors.
I also cannot read the bytes on MMIO space using readb() function. It's
giving
unrecoverable machine check error
Problem solved using this code.
pci_request_regions(dev, "fpgapcie");
pci_io_startaddr = pci_resource_start(dev,BAR_IO);
pci_io_endaddr = pci_resource_end(dev,BAR_IO);
pci_io_size = pci_resource_len(dev,BAR_IO);
printk(KERN_INFO "Region start: %lX, Region end: %lX, Size: % lX",pci_io_startaddr,pci_io_endaddr,pci_io_size);
pci_io_addr = ioremap(pci_io_startaddr, pci_io_endaddr);
printk(KERN_INFO "PCI start adress: %lX", pci_io_addr);
for(i = 0;i<15;i++) /* Write first 15 byte */
{
writeb(2, pci_io_addr+i);
printk(KERN_INFO "%lX, Message from PCI device to user: 2", pci_io_addr+i);
}
and the dmesg output:
fpgapcie: loading out-of-tree module taints kernel.
fpgapcie 0001:01:00.0: Registeration is a success The major device number is 247 (0).
fpgapcie 0001:01:00.0: If you want to talk to the device driver,
fsl-fman-port ffe488000.port fm1-gb0: renamed from eth0
fpgapcie 0001:01:00.0: you'll have to create a device file.
fpgapcie 0001:01:00.0: We suggest you use:
fpgapcie 0001:01:00.0: mknod virtual_pci c 247 0
fpgapcie 0001:01:00.0: The device file name is important, because
fpgapcie 0001:01:00.0: the ioctl program assumes that's the
fpgapcie 0001:01:00.0: file you'll use.
Region start: 210000000, Region end: 2100007FF, Size: 800
PCI start adress: 8000080088900000
8000080088900000, Message from PCI device to user: 2
8000080088900001, Message from PCI device to user: 2
8000080088900002, Message from PCI device to user: 2
8000080088900003, Message from PCI device to user: 2
8000080088900004, Message from PCI device to user: 2
8000080088900005, Message from PCI device to user: 2
8000080088900006, Message from PCI device to user: 2
8000080088900007, Message from PCI device to user: 2
8000080088900008, Message from PCI device to user: 2
8000080088900009, Message from PCI device to user: 2
800008008890000A, Message from PCI device to user: 2
800008008890000B, Message from PCI device to user: 2
800008008890000C, Message from PCI device to user: 2
800008008890000D, Message from PCI device to user: 2
800008008890000E, Message from PCI device to user: 2

PCI driver (request_mem_region fail)

I am trying to get memory resource but for any reason, I cannot. My code is the following:
mmio_base0 = pci_resource_start (dev,0);
mmio_length0 =pci_resource_len(dev,0);
if(!mmio_base0 || ((pci_resource_flags (dev,0) & IORESOURCE_MEM)== 0))
{
dev_err(&(dev->dev), "no mem resource at PCI #0\n");
}
else
{
printk(KERN_ALERT "There is memory at BAR0\n");
if(request_mem_region(mmio_base0,mmio_length0,"driver")==0){
printk(KERN_ALERT "Impossible to get memory\n");
}
}
I always get "Impossible to get memory". So, there are memory but I cannot request it.
cat /proc/iomem
c20000000-c2fffffff : /pcie#ffe250000
c20000000-c2fffffff : PCI Bus 0001:01
c20000000-c200fffff : 0001:01:00.0 //these two memories I want to request
c20100000-c201fffff : 0001:01:00.0
c40000000-c4fffffff : /pcie#ffe270000
c40000000-c4fffffff : PCI Bus 0002:01
There are memories there, but I cannot request them. It always fail! But my uboot detect my device.
PCIe2: Root Complex, x2 gen2, regs # 0xfe250000
02:00.0 - 1957:0808 - Processor
And there is not driver loaded which take these memories:
0001:01:00.0 Power PC: Freescale Semiconductor Inc Device 0808 (rev 10) (prog-if 01)
Flags: bus master, fast devsel, latency 0, IRQ 41
Memory at c20000000 (32-bit, non-prefetchable) [size=1M]
Memory at c20100000 (32-bit, prefetchable) [size=1M]
Capabilities: [44] Power Management version 3
Capabilities: [4c] Express Endpoint, MSI 00
Capabilities: [88] MSI: Enable- Count=1/16 Maskable- 64bit+
Capabilities: [100] Advanced Error Reporting
Any idea what is going on?
BR
I have already solved this problem. I have changed the following:
printk(KERN_ALERT "There is memory at BAR0\n");
if(request_mem_region(mmio_base0,mmio_length0,"driver")==0){
printk(KERN_ALERT "Impossible to get memory\n");
}
to
printk(KERN_ALERT "There is memory at BAR0\n");
if(pci_request_region(dev,0,"mydriver")==0){
printk(KERN_ALERT "Memory reserved properly\n");
}
When the function return 0, the memory is reserved properly. So, you can find in /proc/iomem the memory with a associated name ("mydriver").
Best regards

Why is the probe function in my kernel module not being called?

While following, among others, this tutorial (1) and reading certain chapters in the Linux Device Drivers book, I cannot get the pr_debug() statements in the probe function to show any output in dmesg.
Here's my code:
#include <linux/module.h> /*included for all kernel modules*/
#include <linux/kernel.h> /*included for KERN_DEBUG*/
#include <linux/init.h> /*included for __init and __exit macros*/
#include <linux/usb.h>
#include <linux/usb/input.h>
#include <linux/hid.h>
#define VENDOR_ID 0x0930
#define DEVICE_ID 0x6545
MODULE_LICENSE("GPL");
MODULE_AUTHOR("dev");
MODULE_DESCRIPTION("eusb driver");
static struct usb_device_id eusb_table[] = {
{ USB_DEVICE(VENDOR_ID, DEVICE_ID) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, eusb_table);
static int eusb_probe(struct usb_interface *interface, const struct usb_device_id *id)
{
pr_debug("USB probe function called\n");
return 0;
}
static void eusb_disconnect(struct usb_interface *interface)
{
pr_debug("USB disconnect function called\n");
}
static struct usb_driver eusb_driver = {
//.owner = THIS_MODULE,
.name = "eusb",
.probe = eusb_probe,
.disconnect = eusb_disconnect,
.id_table = eusb_table
};
static int __init eusb_init(void)
{
int result = 0;
pr_debug("Hello world!\n");
result = usb_register(&eusb_driver);
if(result){
pr_debug("error %d while registering usb\n", result);}
else{pr_debug("no error while registering usb\n");}
return 0;
}
static void __exit eusb_exit(void)
{
usb_deregister(&eusb_driver);
pr_debug("Exiting module\n");
}
module_init(eusb_init);
module_exit(eusb_exit);
and Makefile:
obj-m := eusb.o
CFLAGS_eusb.o := -DDEBUG
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
Make finishes without errors, after insmod I can see the module listed in lsmod and the pr_debug() in the init and exit functions show output in dmesg.
When inserting the device however the probe function seems to not get called (or the pr_debug() statements do not show any output in dmesg).
Dmesg output:
[ 7777.521236] Hello world!
[ 7777.521264] usbcore: registered new interface driver eusb
[ 7777.521266] no error while registering usb
[ 7780.597087] usb 1-6: USB disconnect, device number 9
[ 7797.686970] usb 1-6: new high-speed USB device number 10 using xhci_hcd
[ 7797.857324] usb 1-6: New USB device found, idVendor=0930, idProduct=6545
[ 7797.857328] usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 7797.857330] usb 1-6: Product: DataTraveler 2.0
[ 7797.857331] usb 1-6: Manufacturer: Kingston
[ 7797.857333] usb 1-6: SerialNumber: 08606E6D407FED10571E5067
[ 7797.858787] usb-storage 1-6:1.0: USB Mass Storage device detected
[ 7797.858902] scsi host11: usb-storage 1-6:1.0
[ 7798.931417] scsi 11:0:0:0: Direct-Access Kingston DataTraveler 2.0 PMAP PQ: 0 ANSI: 4
[ 7798.931824] sd 11:0:0:0: Attached scsi generic sg3 type 0
[ 7800.184749] sd 11:0:0:0: [sdc] 60964864 512-byte logical blocks: (31.2 GB/29.0 GiB)
[ 7800.186338] sd 11:0:0:0: [sdc] Write Protect is off
[ 7800.186343] sd 11:0:0:0: [sdc] Mode Sense: 23 00 00 00
[ 7800.187948] sd 11:0:0:0: [sdc] No Caching mode page found
[ 7800.187952] sd 11:0:0:0: [sdc] Assuming drive cache: write through
[ 7800.220477] sdc: sdc1 sdc2 sdc3
[ 7800.225068] sd 11:0:0:0: [sdc] Attached SCSI removable disk
[ 7802.798403] ISO 9660 Extensions: Microsoft Joliet Level 3
[ 7802.799507] ISO 9660 Extensions: RRIP_1991A
I have tried with another device, tried with printk() instead of pr_debug(). I found several questions on SO with the same problem, but my code is as far as I can tell almost/completely the same as the code in the answers.
I have also tried with:
USB_INTERFACE_INFO(
USB_INTERFACE_CLASS_HID,
USB_INTERFACE_SUBCLASS_BOOT,
USB_INTERFACE_PROTOCOL_KEYBOARD)
instead of USB_DEVICE() (the other device was a keyboard).
I noticed that some answers talk about platform_driver instead of usb_driver, but I think this is not relevant for me, as it is never mentioned in the tutorials.
Where am I going wrong?
Is your purpose just educational? Otherwise the driver is already there and it's called usb-storage. Seems even that driver enumerates your device first. Try to disable usb-storage and load your driver again. Or better use the virtual machine (KVM / Qemu) to try your drivers.
As you can see your Hello world! was printed which implies the module was loaded successfully. Often all the modules claiming to handle the device via usb_device_id* table are loaded. See 9.3.2.3. Module Loading.
Now, the probe function is called only for the driver the device was bound to. In the case where there is no priority set and two drivers are capable of binding, any of them might get the first opportunity.
I have written a blog post which might clear things further (if not, do comment here).
Further, you might want to go through these two relevant mailing list threads
https://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-October/003639.html
https://marc.info/?l=linux-usb&m=162123892329464&w=2

Resources