From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E092AC35247 for ; Tue, 4 Feb 2020 18:23:41 +0000 (UTC) Received: from shelob.surriel.com (shelob.surriel.com [96.67.55.147]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 341FB2087E for ; Tue, 4 Feb 2020 18:23:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 341FB2087E Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linux.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=kernelnewbies-bounces+kernelnewbies=archiver.kernel.org@kernelnewbies.org Received: from localhost ([::1] helo=shelob.surriel.com) by shelob.surriel.com with esmtp (Exim 4.92.3) (envelope-from ) id 1iz2rL-0001sO-3Q for kernelnewbies@archiver.kernel.org; Tue, 04 Feb 2020 13:23:39 -0500 Received: from mail-pg1-f193.google.com ([209.85.215.193]) by shelob.surriel.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) (envelope-from ) id 1iz2pO-0008A2-DP for Kernelnewbies@kernelnewbies.org; Tue, 04 Feb 2020 13:21:38 -0500 Received: by mail-pg1-f193.google.com with SMTP id g3so4351930pgs.11 for ; Tue, 04 Feb 2020 10:21:38 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc; bh=Vg2XQ8fQ31bjD90md/ZSqOC1QA1DlALcpky0XCV37RU=; b=rO4qQhFR5JmOxiNCT+ZeX1uycemtb/mPzUTFqNXjEt5xzisCsue0Y0OFiRgj9tAZmJ rYvn0Cqj/QuDYJFvUE8MLycjlQ800ZmV4EpcFU9uPYAoJEq4QsG8S+8Uqf5ClhX63IWd 3IWfTVO66+S9nkQP2zWyDqaMxeawshdzWG014U19YEEwK3iMAp8hvU+y3MVviPJccoBx FyKiGauFzQw1XAmHW3D7g5c+8zBLupHQMb1gSjlwemITkL3hnNg4OETTZ3QJSqrHbkp3 sACWLKLysizF0AvUGlroSUwgnATAAh+4tPjTgptxJ1pGFw8Q8zRLJcx0kb22RVA95Tc/ YkAg== X-Gm-Message-State: APjAAAWAkG3FG+9jyHC5U9Z225ujJugbUEqTH4d6bFk2Rs3Wisswzz9j aylt44HIVbGVTkTPHN5mee8hF4QSaGc= X-Google-Smtp-Source: APXvYqwHgckCz+sPFrJjgC69ugbvS81OQzU3JmYlv02FU62HSWiqYSvzxkPqDreHP3WE51BPDaPQaA== X-Received: by 2002:a67:ce82:: with SMTP id c2mr1802093vse.30.1580840122425; Tue, 04 Feb 2020 10:15:22 -0800 (PST) Received: from mail-ua1-f43.google.com (mail-ua1-f43.google.com. [209.85.222.43]) by smtp.gmail.com with ESMTPSA id y7sm7491645vkd.38.2020.02.04.10.15.22 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 04 Feb 2020 10:15:22 -0800 (PST) Received: by mail-ua1-f43.google.com with SMTP id 73so7101324uac.6 for ; Tue, 04 Feb 2020 10:15:22 -0800 (PST) X-Received: by 2002:ab0:374a:: with SMTP id i10mr17490165uat.97.1580840121666; Tue, 04 Feb 2020 10:15:21 -0800 (PST) MIME-Version: 1.0 References: <9c5082fe870a01cac0b1a7861c0c5a74e794963f.camel@surriel.com> <20200203201102.GA3888053@kroah.com> In-Reply-To: From: Lucas Tanure Date: Tue, 4 Feb 2020 18:15:10 +0000 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: USB Hid driver Help To: Greg KH Cc: kernelnewbies X-BeenThere: kernelnewbies@kernelnewbies.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Learn about the Linux kernel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: tanure@linux.com Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: kernelnewbies-bounces+kernelnewbies=archiver.kernel.org@kernelnewbies.org On Tue, Feb 4, 2020 at 1:27 PM Lucas Tanure wrote: > > On Mon, Feb 3, 2020 at 10:00 PM Lucas Tanure wrote: > > > > On Mon, Feb 3, 2020 at 8:11 PM Greg KH wrote: > > > > > > On Mon, Feb 03, 2020 at 04:32:46PM +0000, Lucas Tanure wrote: > > > > Hi, > > > > > > > > I'm trying to write a Hid driver for MCP2210. > > > > > > What type of device is this? > > It is a USB <-> SPI converter. > > > > > > > > > But the USB Hid specification is quite complicated. > > > > > > The kernel should do it "all for you" already, why do you need to create > > > a custom HID driver for this device? > > I need a driver that register an SPI controller with in the kernel. > > So this SPI controller would receive regmap reads/writes and translate > > to USB HID packages and send to the SPI device attached in the other > > side of the cable. > > > > > > > > What type of HID reports does the device export and why doesn't the > > > existing kernel drivers work for you? > > I don't know enough yet to answer about HID Reports, but at end of > > this e-mail I attached the lsub -v of the device. > > I want to use this device in kernel space, registering a SPI > > controller. And with this SPI controller another SPI slave device will > > be registered. > > So, for the SPI slave device it will be like there is no USB in > > between itself and the kernel. > > > > > > > > > I would like to know how to send and receive data to the device. Any > > > > links to a good tutorial ? > > > > > > HID has the idea of "reports" and data comes in and out in that specific > > > format, all depending on how the device describes itself. There's isn't > > > usually a normal "send/receive" type of thing, but it all depends on the > > > type of device. > > Ok. Reading the datasheet of this device I need to send some 64 byte > > arrays to configure the SPI bus. > > And after that I start to send reports to communicate with the SPI slave device. > > > > > > > > > This is my current driver is attached. > > > > > > > > Thanks > > > > Lucas > > > > > > > #define DEBUG > > > > #include > > > > #include > > > > #include > > > > > > > > static int mcp2210_probe(struct hid_device *hdev, > > > > const struct hid_device_id *id) > > > > { > > > > struct usb_interface *intf = to_usb_interface(hdev->dev.parent); > > > > int ret = 0; > > > > > > > > hid_dbg(hdev, "%s\n", __FUNCTION__); > > > > > > > > ret = hid_parse(hdev); > > > > if (ret) { > > > > hid_err(hdev, "parse failed\n"); > > > > return ret; > > > > } else { > > > > hid_dbg(hdev, "parse success\n"); > > > > } > > > > > > > > ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); > > > > if (ret) { > > > > hid_err(hdev, "hw start failed\n"); > > > > return ret; > > > > } else { > > > > hid_dbg(hdev, "start success\n"); > > > > } > > > > > > Does this all work? > > For this version, it`s takes precedence from HID generic driver, wich is great. > > > > > > > > What fails? > > If I try to execute small test of data communcation: > > > > u8 *buf = kzalloc (64, GFP_KERNEL); > > buf[0] = 0x50; //read EEPROM command > > buf[1] = 0x03 ; // Address to read > > > > ret = hid_hw_raw_request(hdev, 0, buf, 64, HID_INPUT_REPORT, HID_REQ_GET_REPORT) > > ret is -EPIPE. > > > > > > > > thanks, > > > > > > greg k-h > > > > Many Thanks > > Lucas > > > > Bus 001 Device 008: ID 04d8:00de Microchip Technology, Inc. MCP2210 > > USB to SPI Master > > Couldn't open device, some information will be missing > > Device Descriptor: > > bLength 18 > > bDescriptorType 1 > > bcdUSB 2.00 > > bDeviceClass 0 > > bDeviceSubClass 0 > > bDeviceProtocol 0 > > bMaxPacketSize0 8 > > idVendor 0x04d8 Microchip Technology, Inc. > > idProduct 0x00de > > bcdDevice 0.02 > > iManufacturer 1 > > iProduct 2 > > iSerial 3 > > bNumConfigurations 1 > > Configuration Descriptor: > > bLength 9 > > bDescriptorType 2 > > wTotalLength 0x0029 > > bNumInterfaces 1 > > bConfigurationValue 1 > > iConfiguration 0 > > bmAttributes 0x80 > > (Bus Powered) > > MaxPower 100mA > > Interface Descriptor: > > bLength 9 > > bDescriptorType 4 > > bInterfaceNumber 0 > > bAlternateSetting 0 > > bNumEndpoints 2 > > bInterfaceClass 3 Human Interface Device > > bInterfaceSubClass 0 > > bInterfaceProtocol 0 > > iInterface 0 > > HID Device Descriptor: > > bLength 9 > > bDescriptorType 33 > > bcdHID 1.11 > > bCountryCode 0 Not supported > > bNumDescriptors 1 > > bDescriptorType 34 Report > > wDescriptorLength 29 > > Report Descriptors: > > ** UNAVAILABLE ** > > Endpoint Descriptor: > > bLength 7 > > bDescriptorType 5 > > bEndpointAddress 0x81 EP 1 IN > > bmAttributes 3 > > Transfer Type Interrupt > > Synch Type None > > Usage Type Data > > wMaxPacketSize 0x0040 1x 64 bytes > > bInterval 1 > > Endpoint Descriptor: > > bLength 7 > > bDescriptorType 5 > > bEndpointAddress 0x01 EP 1 OUT > > bmAttributes 3 > > Transfer Type Interrupt > > Synch Type None > > Usage Type Data > > wMaxPacketSize 0x0040 1x 64 bytes > > bInterval 1 > > Hi, > > If I use hid_hw_output_report I can write my 64 bytes buffer to the device. > And I would expect a 64 bytes answer from the device, but I don't know > how to get it. > > How do I know where my output data is going to ? Control Pipe or > Interrupt Pipe ? > How to I get the answer data from the device ? > > Thanks > Lucas > > static int mcp2210_probe(struct hid_device *hdev, > const struct hid_device_id *id) > { > //struct usb_interface *intf = to_usb_interface(hdev->dev.parent); > int ret = 0; > //struct hid_report *report = kzalloc(sizeof(struct > hid_report), GFP_KERNEL); > u8 *buf = kzalloc(64, GFP_KERNEL); > u8 *buf2 = kzalloc(64, GFP_KERNEL); > > hid_dbg(hdev, "%s\n", __FUNCTION__); > > ret = hid_parse(hdev); > if (ret) { > hid_err(hdev, "parse failed\n"); > return ret; > } else { > hid_dbg(hdev, "parse success\n"); > } > > ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); > if (ret) { > hid_err(hdev, "hw start failed\n"); > return ret; > } else { > hid_dbg(hdev, "start success\n"); > } > ret = hid_hw_open(hdev); > hid_dbg(hdev, "hid_hw_open %d\n", ret); > > buf[0] = 0x50; > buf[1] = 0x07; > ret = hid_hw_output_report(hdev, buf, 64); > hid_dbg(hdev, "hid_hw_output_report %d back > [%x][%x][%x][%x]\n", ret, buf[0], buf[1], buf[2], buf[3]); > //dmesg prints ret 0 > > ret = hid_hw_raw_request(hdev, 0x81, buf2, 64, > HID_INPUT_REPORT, HID_REQ_SET_REPORT); > hid_dbg(hdev, "hid_input_report %d back [%x][%x][%x][%x]\n", > ret, buf2[0], buf2[1], buf2[2], buf2[3]); > //dmesg prints ret -32 > > kfree(buf); > kfree(buf2); > > return 0; > } > > Dmesg: > [ 72.991830] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: mcp2210_probe > [ 73.001793] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: parse success > [ 73.020234] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: > hiddev96,hidraw0: USB HID v1.11 Device [Microchip Technology Inc. > MCP2210 USB-to-SPI Master] on usb-3f980000.usb-1.3/input0 > [ 73.039798] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: start success > [ 73.111858] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: hid_hw_open 0 > [ 73.126599] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: > hid_hw_output_report 64 back [50][7][0][0] > [ 73.140170] MCP2210 USB SPI Driver 0003:04D8:00DE.0002: > hid_input_report -32 back [81][0][0][0] Hi, Doing some hacks I can see that using a user space library for this device uses: [ 38.188226] [<806b9728>] (usbhid_output_report) from [<806b7db4>] (hidraw_send_report+0x100/0x180) And the layer between hidraw_send_report and usbhid_output_report is hid_hw_output_report. So the function I should use is hid_hw_output_report. [ 38.137293] usbhid_output_report START ############################################################################### [ 38.137306] usbhid_output_report 30 0 0 0 1 0 0 [ 38.148204] CPU: 3 PID: 475 Comm: hidusbtest Tainted: G C 4.19.69-v7+ #8 [ 38.148210] Hardware name: BCM2835 [ 38.164463] [<80111dac>] (unwind_backtrace) from [<8010d36c>] (show_stack+0x20/0x24) [ 38.172494] [<8010d36c>] (show_stack) from [<808166bc>] (dump_stack+0xcc/0x110) [ 38.179928] [<808166bc>] (dump_stack) from [<806b9728>] (usbhid_output_report+0x94/0x144) [ 38.188226] [<806b9728>] (usbhid_output_report) from [<806b7db4>] (hidraw_send_report+0x100/0x180) [ 38.197311] [<806b7db4>] (hidraw_send_report) from [<806b7e78>] (hidraw_write+0x44/0x58) [ 38.205517] [<806b7e78>] (hidraw_write) from [<802ac2ec>] (__vfs_write+0x48/0x170) [ 38.213193] [<802ac2ec>] (__vfs_write) from [<802ac5fc>] (vfs_write+0xb4/0x1c4) [ 38.220604] [<802ac5fc>] (vfs_write) from [<802ac8d4>] (ksys_write+0x6c/0xec) [ 38.227841] [<802ac8d4>] (ksys_write) from [<802ac96c>] (sys_write+0x18/0x1c) [ 38.235076] [<802ac96c>] (sys_write) from [<80101000>] (ret_fast_syscall+0x0/0x28) [ 38.242750] Exception stack(0xb391ffa8 to 0xb391fff0) [ 38.247869] ffa0: 00000000 00014bec 00000003 7e9ec8b4 00000040 00000000 [ 38.256161] ffc0: 00000000 00014bec 00010f38 00000004 00000000 00000000 76fc9000 7e9ec844 [ 38.264451] ffe0: 0000006c 7e9ec810 00012f00 76cd4944 [ 38.272431] usbhid_output_report END ############################################################################### And after using hid_hw_output_report my driver get a call at mcp2210_raw_event: [ 38.333979] [<7f32a04c>] (mcp2210_raw_event [mcp2210]) from [<806ae188>] (hid_input_report+0xf4/0x18c) So, to receive the success status of the command sent with hid_hw_output_report the driver receives an event. Now I need to understand how to register my driver to receive this event, once the hidraw driver will not be in use. [ 38.284788] hid_irq_in 0 [ 38.284798] mcp2210_raw_event START ############################################################################### [ 38.287370] CPU: 0 PID: 322 Comm: rs:main Q:Reg Tainted: G C 4.19.69-v7+ #8 [ 38.306324] Hardware name: BCM2835 [ 38.309787] [<80111dac>] (unwind_backtrace) from [<8010d36c>] (show_stack+0x20/0x24) [ 38.317642] [<8010d36c>] (show_stack) from [<808166bc>] (dump_stack+0xcc/0x110) [ 38.325062] [<808166bc>] (dump_stack) from [<7f32a04c>] (mcp2210_raw_event+0x4c/0x120 [mcp2210]) [ 38.333979] [<7f32a04c>] (mcp2210_raw_event [mcp2210]) from [<806ae188>] (hid_input_report+0xf4/0x18c) [ 38.343420] [<806ae188>] (hid_input_report) from [<806ba39c>] (hid_irq_in+0x20c/0x248) [ 38.351452] [<806ba39c>] (hid_irq_in) from [<8061bc48>] (__usb_hcd_giveback_urb+0xa0/0x15c) [ 38.359923] [<8061bc48>] (__usb_hcd_giveback_urb) from [<8061befc>] (usb_hcd_giveback_urb+0xd4/0xf4) [ 38.369188] [<8061befc>] (usb_hcd_giveback_urb) from [<80647434>] (completion_tasklet_func+0x8c/0xcc) [ 38.378542] [<80647434>] (completion_tasklet_func) from [<80656374>] (tasklet_callback+0x20/0x24) [ 38.387544] [<80656374>] (tasklet_callback) from [<80126a14>] (tasklet_action_common.constprop.5+0x64/0xec) [ 38.397426] [<80126a14>] (tasklet_action_common.constprop.5) from [<80126af4>] (tasklet_hi_action+0x28/0x30) [ 38.407394] [<80126af4>] (tasklet_hi_action) from [<801023f4>] (__do_softirq+0x184/0x424) [ 38.415687] [<801023f4>] (__do_softirq) from [<801266ac>] (irq_exit+0xf8/0x134) [ 38.423102] [<801266ac>] (irq_exit) from [<8017f710>] (__handle_domain_irq+0x70/0xc4) [ 38.431044] [<8017f710>] (__handle_domain_irq) from [<801021a0>] (bcm2836_arm_irqchip_handle_irq+0x60/0xa8) [ 38.440924] [<801021a0>] (bcm2836_arm_irqchip_handle_irq) from [<801019bc>] (__irq_svc+0x5c/0x7c) [ 38.449919] Exception stack(0xb63e5bf0 to 0xb63e5c38) [ 38.455038] 5be0: b59d022c 00000005 80c66000 b9bb87c0 [ 38.463331] 5c00: b59d00b0 00000400 80c66000 b59d022c b97dc400 b63e5da0 b63e5cd4 b63e5c4c [ 38.471622] 5c20: b63e5c50 b63e5c40 8036a1e4 808322fc 40000013 ffffffff [ 38.478330] [<801019bc>] (__irq_svc) from [<808322fc>] (_raw_spin_lock+0xc/0x54) [ 38.485834] [<808322fc>] (_raw_spin_lock) from [<8036a1e4>] (ext4_mark_iloc_dirty+0x108/0x8c8) [ 38.494569] [<8036a1e4>] (ext4_mark_iloc_dirty) from [<8036aca4>] (ext4_mark_inode_dirty+0x84/0x1f8) [ 38.503832] [<8036aca4>] (ext4_mark_inode_dirty) from [<8037058c>] (ext4_dirty_inode+0x54/0x70) [ 38.512656] [<8037058c>] (ext4_dirty_inode) from [<802de768>] (__mark_inode_dirty+0x50/0x414) [ 38.521305] [<802de768>] (__mark_inode_dirty) from [<802c97a8>] (generic_update_time+0xf4/0x11c) [ 38.530215] [<802c97a8>] (generic_update_time) from [<802c9c88>] (file_update_time+0x128/0x158) [ 38.539039] [<802c9c88>] (file_update_time) from [<8023b158>] (__generic_file_write_iter+0xa0/0x1e0) [ 38.548305] [<8023b158>] (__generic_file_write_iter) from [<80357a20>] (ext4_file_write_iter+0xfc/0x4b8) [ 38.557921] [<80357a20>] (ext4_file_write_iter) from [<802ac3b0>] (__vfs_write+0x10c/0x170) [ 38.566390] [<802ac3b0>] (__vfs_write) from [<802ac5fc>] (vfs_write+0xb4/0x1c4) [ 38.573800] [<802ac5fc>] (vfs_write) from [<802ac8d4>] (ksys_write+0x6c/0xec) [ 38.581034] [<802ac8d4>] (ksys_write) from [<802ac96c>] (sys_write+0x18/0x1c) [ 38.588269] [<802ac96c>] (sys_write) from [<80101000>] (ret_fast_syscall+0x0/0x28) [ 38.595941] Exception stack(0xb63e5fa8 to 0xb63e5ff0) [ 38.601059] 5fa0: 0000004a 75700bc0 00000007 75700bc0 0000004a 00000000 [ 38.609351] 5fc0: 0000004a 75700bc0 00000007 00000004 75700bc0 fffff815 00092410 000924e8 [ 38.617641] 5fe0: 00000002 760fe6e8 00000000 76eeb1bc [ 38.622762] MCP2210 USB SPI Driver 0003:04D8:00DE.0001: mcp2210_raw_event 64 [ 38.629930] MCP2210 USB SPI Driver 0003:04D8:00DE.0001: 30 0 0 0 1 0 2 2 2 2 2 0 0 ff 1 ff 1 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 [ 38.646944] mcp2210_raw_event END ############################################################################### _______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies