Well, not everything as good as it seemed - upgrading JMS539 firmware completely disabled eSATA port on docking station :( So that's another reason to solve this issue inside Linux kernel.
On Thu, 6 Nov 2014 01:26:07 +0300 parafin <para...@paraf.in> wrote: > Update to this issue: > OS X has problems recognizing these devices as well - 10.9 managed to > enumerate it after several attempts, but after upgrade to the latest > release (10.10 Yosemite) OS X only sees these USB devices if they were > connected before booting up (so same as Linux). Windows, of course, has > no such problems (tested with Win 7 Pro). > While googling about possible solutions for OS X, I found out that it > is possible to upgrade firmware of JMS539 chipset inside these docking > stations (of course the utility is Windows-only): > http://www.station-drivers.com/index.php/downloads/Drivers/Jmicron/JMS539-Sata-USB-3.0-Controller/ > Firmware version all previous tests were done with is 255.00.06.00.14, > I've updated it to the latest 255.31.3.41.22 and it solved enumeration > problem on both Linux and OS X! > I left old firmware on one of the devices so I still can test some > patches. I'm not sure though if it is worth fixing now, in the light of > what I wrote above, I would still say yes, because: first of all it > won't be obvious that firmware upgrade is required (or that it's at > all possible) for anyone else encountering this issue; secondly Windows > is required to run firmware upgrade and not everyone has readily access > to it; thirdly there might be other chipsets out there with same quirks > and no available fixes; and finally it worked before, so it is a > regression even though most likely it is the device who's doing the > wrong thing. > > On Wed, 5 Nov 2014 12:50:36 -0800 > Sarah Sharp <sarah.a.sh...@linux.intel.com> wrote: > > > I'm no longer the USB 3.0 driver maintainer. Please work with Mathias > > Nyman to fix this issue. > > > > Sarah Sharp > > > > On Fri, Oct 31, 2014 at 06:01:24PM +0300, parafin wrote: > > > Hi, > > > > > > it was suggested to me that since you are the author of offending > > > commit I should forward this email to you. Also see this bug: > > > https://bugzilla.kernel.org/show_bug.cgi?id=41752 > > > > > > Begin forwarded message: > > > > > > Date: Thu, 30 Oct 2014 22:56:29 +0300 > > > From: parafin <para...@paraf.in> > > > To: <linux-usb@vger.kernel.org> > > > Subject: USB3: unable to enumerate, device not accepting address > > > > > > > > > Hi, > > > > > > I have 2 very similar USB3 devices that stopped working sometime after > > > kernel version 3.3 - they fail to enumerate unless I reload xhci_hcd > > > driver. > > > > > > These are the devices: > > > http://www.agestar.com/en/Products/Docking-Station/USB3-0/974-usb30esata-to-2535-sata-hdd-docking-station.html > > > http://www.agestar.com/en/Products/Docking-Station/USB3-0/980-usb30esata-to-2535-sata-hdd-docking-station.html > > > Basically it's some eSATA->USB3 bridge JMicron chip (I'm guessing it's > > > the same one in both devices): > > > Bus 009 Device 002: ID 152d:2509 JMicron Technology Corp. / JMicron USA > > > Technology Corp. JMS539 SuperSpeed SATA II 3.0G Bridge > > > > > > This is USB controller I am testing them with: > > > 01:00.0 USB controller: NEC Corporation uPD720200 USB 3.0 Host Controller > > > (rev 03) > > > I even tried upgrading firmware, with no result > > > > > > It appears in system as 2 buses (lsusb -t output): > > > /: Bus 09.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M > > > /: Bus 08.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M > > > One for SuperSpeed devices, another for slower. > > > > > > So here's dmesg for when it fails: > > > [ 195.207408] hub 8-0:1.0: unable to enumerate USB device on port 1 > > > [ 196.016556] usb 9-1: device not accepting address 2, error -22 > > > [ 196.520572] hub 9-0:1.0: unable to enumerate USB device on port 1 > > > > > > And here how it should look (when it works): > > > [ 61.686218] hub 8-0:1.0: unable to enumerate USB device on port 1 > > > [ 63.620211] usb 9-1: new SuperSpeed USB device number 2 using xhci_hcd > > > [ 63.636918] usb 9-1: New USB device found, idVendor=152d, > > > idProduct=2509 > > > [ 63.636932] usb 9-1: New USB device strings: Mfr=1, Product=11, > > > SerialNumber=3 > > > [ 63.636942] usb 9-1: Product: Usb production > > > [ 63.636950] usb 9-1: Manufacturer: JMicron > > > [ 63.636956] usb 9-1: SerialNumber: 00A1234578EA > > > [ 63.638549] scsi5 : usb-storage 9-1:1.0 > > > [ 64.926983] scsi 5:0:0:0: Direct-Access Jmicron Corp. > > > 0000 PQ: 0 ANSI: 5 > > > [ 64.927925] sd 5:0:0:0: Attached scsi generic sg6 type 0 > > > [ 64.929912] sd 5:0:0:0: [sdg] Very big device. Trying to use READ > > > CAPACITY(16). > > > [ 64.930353] sd 5:0:0:0: [sdg] 5860533168 512-byte logical blocks: > > > (3.00 TB/2.72 TiB) > > > [ 64.931031] sd 5:0:0:0: [sdg] Write Protect is off > > > [ 64.931042] sd 5:0:0:0: [sdg] Mode Sense: 28 00 00 00 > > > [ 64.931764] sd 5:0:0:0: [sdg] No Caching mode page present > > > [ 64.931772] sd 5:0:0:0: [sdg] Assuming drive cache: write through > > > [ 64.932486] sd 5:0:0:0: [sdg] Very big device. Trying to use READ > > > CAPACITY(16). > > > [ 64.933992] sd 5:0:0:0: [sdg] No Caching mode page present > > > [ 64.933997] sd 5:0:0:0: [sdg] Assuming drive cache: write through > > > [ 64.989015] sdg: sdg1 sdg2 sdg3 sdg4 > > > [ 64.992112] sd 5:0:0:0: [sdg] Very big device. Trying to use READ > > > CAPACITY(16). > > > [ 64.993885] sd 5:0:0:0: [sdg] No Caching mode page present > > > [ 64.993898] sd 5:0:0:0: [sdg] Assuming drive cache: write through > > > [ 64.993909] sd 5:0:0:0: [sdg] Attached SCSI disk > > > First line doesn't always appear, might depend on kernel version, I'm > > > not sure. > > > > > > I managed to bisect this down to this commit: > > > beabe20445c60322719d8f58e9eb9dd4660c1b3e > > > (it's from 3.4 branch, included in 3.4.36 release, upstream commit id > > > from commit message seems to be invalid, at least it's missing one > > > character). > > > I backported reverse of this commit to 3.17.1 (I can't run 3.4 kernel > > > due to different issues) and it helps with this issue. Patch attached > > > in case it is helpful, sorry though for whitespace mess, I used nano:) > > > > > > I doubt that just reverting is acceptable solution for mainstream > > > kernel, so I'm willing to test some other patches (on top of 3.17.1 > > > would be best) or provide additional information so that this issue > > > could be fixed in next releases. > > > > > --- drivers/usb/core/hub.c.orig 2014-10-30 21:44:50.000746074 +0300 > > > +++ drivers/usb/core/hub.c 2014-10-30 22:12:01.561256025 +0300 > > > @@ -2664,56 +2664,95 @@ > > > if ((portstatus & USB_PORT_STAT_RESET)) > > > return -EBUSY; > > > > > > - if (hub_port_warm_reset_required(hub, port1, portstatus)) > > > - return -ENOTCONN; > > > - > > > - /* Device went away? */ > > > - if (!(portstatus & USB_PORT_STAT_CONNECTION)) > > > - return -ENOTCONN; > > > - > > > - /* bomb out completely if the connection bounced. A USB 3.0 > > > - * connection may bounce if multiple warm resets were issued, > > > - * but the device may have successfully re-connected. Ignore it. > > > + /* Some buggy devices require a warm reset to be issued even > > > + * when the port appears not to be connected. > > > */ > > > - if (!hub_is_superspeed(hub->hdev) && > > > - (portchange & USB_PORT_STAT_C_CONNECTION)) > > > - return -ENOTCONN; > > > - > > > - if (!(portstatus & USB_PORT_STAT_ENABLE)) > > > - return -EBUSY; > > > + if (!warm) { > > > + /* > > > + * Some buggy devices can cause an NEC host > > > controller > > > + * to transition to the "Error" state after a hot > > > port > > > + * reset. This will show up as the port state in > > > + * "Inactive", and the port may also report a > > > + * disconnect. Forcing a warm port reset seems > > > to make > > > + * the device work. > > > + * > > > + * See > > > https://bugzilla.kernel.org/show_bug.cgi?id=41752 > > > + */ > > > + if (hub_port_warm_reset_required(hub, port1, > > > portstatus)) { > > > + int ret; > > > + > > > + if ((portchange & > > > USB_PORT_STAT_C_CONNECTION)) > > > + usb_clear_port_feature(hub->hdev, > > > port1, > > > + > > > USB_PORT_FEAT_C_CONNECTION); > > > + if (portchange & > > > USB_PORT_STAT_C_LINK_STATE) > > > + usb_clear_port_feature(hub->hdev, > > > port1, > > > + > > > USB_PORT_FEAT_C_PORT_LINK_STATE); > > > + if (portchange & USB_PORT_STAT_C_RESET) > > > + usb_clear_port_feature(hub->hdev, > > > port1, > > > + > > > USB_PORT_FEAT_C_RESET); > > > + dev_dbg(hub->intfdev, "hot reset failed, > > > warm reset port %d\n", > > > + port1); > > > + ret = hub_port_reset(hub, port1, > > > + udev, HUB_BH_RESET_TIME, > > > + true); > > > + if ((portchange & > > > USB_PORT_STAT_C_CONNECTION)) > > > + usb_clear_port_feature(hub->hdev, > > > port1, > > > + > > > USB_PORT_FEAT_C_CONNECTION); > > > + return ret; > > > + } > > > + /* Device went away? */ > > > + if (!(portstatus & USB_PORT_STAT_CONNECTION)) > > > + return -ENOTCONN; > > > + > > > + /* bomb out completely if the connection bounced > > > */ > > > + if ((portchange & USB_PORT_STAT_C_CONNECTION)) > > > + return -ENOTCONN; > > > + > > > + if ((portstatus & USB_PORT_STAT_ENABLE)) { > > > + if (!udev) > > > + return 0; > > > + > > > + if (hub_is_wusb(hub)) > > > + udev->speed = USB_SPEED_WIRELESS; > > > + else if (hub_is_superspeed(hub->hdev)) > > > + udev->speed = USB_SPEED_SUPER; > > > + else if (portstatus & > > > USB_PORT_STAT_HIGH_SPEED) > > > + udev->speed = USB_SPEED_HIGH; > > > + else if (portstatus & > > > USB_PORT_STAT_LOW_SPEED) > > > + udev->speed = USB_SPEED_LOW; > > > + else > > > + udev->speed = USB_SPEED_FULL; > > > + return 0; > > > + } > > > + } else { > > > + if (!(portstatus & USB_PORT_STAT_CONNECTION) || > > > + hub_port_warm_reset_required(hub, > > > port1, > > > + portstatus)) > > > + return -ENOTCONN; > > > > > > - if (!udev) > > > return 0; > > > - > > > - if (hub_is_wusb(hub)) > > > - udev->speed = USB_SPEED_WIRELESS; > > > - else if (hub_is_superspeed(hub->hdev)) > > > - udev->speed = USB_SPEED_SUPER; > > > - else if (portstatus & USB_PORT_STAT_HIGH_SPEED) > > > - udev->speed = USB_SPEED_HIGH; > > > - else if (portstatus & USB_PORT_STAT_LOW_SPEED) > > > - udev->speed = USB_SPEED_LOW; > > > - else > > > - udev->speed = USB_SPEED_FULL; > > > - return 0; > > > + } > > > + return -EBUSY; > > > } > > > > > > static void hub_port_finish_reset(struct usb_hub *hub, int port1, > > > - struct usb_device *udev, int *status) > > > + struct usb_device *udev, int *status, bool warm) > > > { > > > switch (*status) { > > > case 0: > > > - /* TRSTRCY = 10 ms; plus some extra */ > > > - msleep(10 + 40); > > > - if (udev) { > > > - struct usb_hcd *hcd = bus_to_hcd(udev->bus); > > > - > > > - update_devnum(udev, 0); > > > - /* The xHC may think the device is already reset, > > > - * so ignore the status. > > > - */ > > > - if (hcd->driver->reset_device) > > > - hcd->driver->reset_device(hcd, udev); > > > + if (!warm) { > > > + struct usb_hcd *hcd; > > > + /* TRSTRCY = 10 ms; plus some extra */ > > > + msleep(10 + 40); > > > + if (udev) { > > > + update_devnum(udev, 0); > > > + hcd = bus_to_hcd(udev->bus); > > > + /* The xHC may think the device is already > > > + * reset, so ignore the status. > > > + */ > > > + if (hcd->driver->reset_device) > > > + hcd->driver->reset_device(hcd, > > > udev); > > > + } > > > } > > > /* FALL THROUGH */ > > > case -ENOTCONN: > > > @@ -2725,10 +2764,8 @@ > > > USB_PORT_FEAT_C_BH_PORT_RESET); > > > usb_clear_port_feature(hub->hdev, port1, > > > USB_PORT_FEAT_C_PORT_LINK_STATE); > > > - usb_clear_port_feature(hub->hdev, port1, > > > - USB_PORT_FEAT_C_CONNECTION); > > > } > > > - if (udev) > > > + if (!warm && udev) > > > usb_set_device_state(udev, *status > > > ? USB_STATE_NOTATTACHED > > > : USB_STATE_DEFAULT); > > > @@ -2789,34 +2826,10 @@ > > > status); > > > } > > > > > > - /* Check for disconnect or reset */ > > > + /* return on disconnect or reset */ > > > if (status == 0 || status == -ENOTCONN || status == -ENODEV) { > > > - hub_port_finish_reset(hub, port1, udev, &status); > > > - > > > - if (!hub_is_superspeed(hub->hdev)) > > > - goto done; > > > - > > > - /* > > > - * If a USB 3.0 device migrates from reset to an error > > > - * state, re-issue the warm reset. > > > - */ > > > - if (hub_port_status(hub, port1, > > > - &portstatus, &portchange) < 0) > > > - goto done; > > > - > > > - if (!hub_port_warm_reset_required(hub, port1, > > > - portstatus)) > > > - goto done; > > > - > > > - /* > > > - * If the port is in SS.Inactive or Compliance Mode, the > > > - * hot or warm reset failed. Try another warm reset. > > > - */ > > > - if (!warm) { > > > - dev_dbg(&port_dev->dev, > > > - "hot reset failed, warm > > > reset\n"); > > > - warm = true; > > > - } > > > + hub_port_finish_reset(hub, port1, udev, &status, > > > warm); > > > + goto done; > > > } > > > > > > dev_dbg(&port_dev->dev, > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html