We have an external chassis that connects to a PC via cabled PCIe. The connector in the chassis has a PCIe-PCI bridge, behind which is a proprietary ASIC. As a part of enabling hot-plug, we have an upper filter driver that attaches to the PCIe-PCI bridge in the chassis and sets Removable=TRUE and SurpriseRemovalOK=FALSE during IRP_MN_QUERY_CAPABILITIES. The bridge (representing the chassis) shows up in Safely Remove Hardware. It can be disabled through that interface and the chassis can be powered down and reconfigured. When it is powered up again, the bridge and ASIC are again represented in Device Manager and the bridge again shows up in Safely Remove Hardware.
At least, that’s how it works on Windows 7. On Windows 8, the device initially shows up in Safely Remove Hardware. After a safely remove/turn off/turn on cycle, however, the device no longer shows up there. The device is perfectly usable, it’s just not present in Safely Remove Hardware.
What am I not telling you? Originally, the function driver for the ASIC was wrongly setting SurpriseRemovalOK=TRUE (with Removable=FALSE). When we fixed this, the problem went away, but we are left with a few questions:
(1) On first load on both Windows 7 and Windows 8, the device capabilities for the ASIC (as reflected in Device Manager) were 0. It’s only after the device is removed & readded (again, on both Win7 & Win8) that CM_DEVCAP_SURPRISEREMOVALOK shows up there. We were hardcoding it to TRUE during IRP_MN_QUERY_CAPABILITIES in our driver. Is this a PCI-specific thing? It doesn’t seem to affect similar drivers that we have for devices on other buses.
(2) What are the semantics of having Removable=FALSE and SurpriseRemovalOK=TRUE? Why would a child with this configuration impact the display of the parent node on Windows 8? I would have expected SurpriseRemovalOK to be ignored on a node not marked Removable rather than affecting the parent node.
Thanks in advance for any insight.
–
Gabe
On what point are you modifying the DEVICE_CAPABILITIES structure?
Thanks for the response. We actually set it in the FDO both before sending the IRP down and on its way back up. This code is shared between USB and PCI drivers, and the Win2K USB bus driver would reset SurpriseRemovalOK, so we had set it in both places to be certain.
I can post actual code that we use in handling IRP_MN_QUERY_CAPABILITIES if that would be useful.
–
Gabe
Are you asking why Removable=FALSE with SurpriseRemovalOk=TRUE works inconsistently?
IIRC removable PCIe capability should be normally defined
somewhere in the port config space, and ACPI is involved as well.
You could get away using IRP_MN_QUERY_CAPABILITIES on Win7, but
changes in Win8 could break that.
– pa
On 09-Jan-2014 17:30, gabe.jones@ni.com wrote:
We have an external chassis that connects to a PC via cabled PCIe. The connector in the chassis has a PCIe-PCI bridge, behind which is a proprietary ASIC. As a part of enabling hot-plug, we have an upper filter driver that attaches to the PCIe-PCI bridge in the chassis and sets Removable=TRUE and SurpriseRemovalOK=FALSE during IRP_MN_QUERY_CAPABILITIES. The bridge (representing the chassis) shows up in Safely Remove Hardware. It can be disabled through that interface and the chassis can be powered down and reconfigured. When it is powered up again, the bridge and ASIC are again represented in Device Manager and the bridge again shows up in Safely Remove Hardware.
At least, that’s how it works on Windows 7. On Windows 8, the device initially shows up in Safely Remove Hardware. After a safely remove/turn off/turn on cycle, however, the device no longer shows up there. The device is perfectly usable, it’s just not present in Safely Remove Hardware.
What am I not telling you? Originally, the function driver for the ASIC was wrongly setting SurpriseRemovalOK=TRUE (with Removable=FALSE). When we fixed this, the problem went away, but we are left with a few questions:
(1) On first load on both Windows 7 and Windows 8, the device capabilities for the ASIC (as reflected in Device Manager) were 0. It’s only after the device is removed & readded (again, on both Win7 & Win8) that CM_DEVCAP_SURPRISEREMOVALOK shows up there. We were hardcoding it to TRUE during IRP_MN_QUERY_CAPABILITIES in our driver. Is this a PCI-specific thing? It doesn’t seem to affect similar drivers that we have for devices on other buses.
(2) What are the semantics of having Removable=FALSE and SurpriseRemovalOK=TRUE? Why would a child with this configuration impact the display of the parent node on Windows 8? I would have expected SurpriseRemovalOK to be ignored on a node not marked Removable rather than affecting the parent node.
Thanks in advance for any insight.
> Are you asking why Removable=FALSE with SurpriseRemovalOk=TRUE works inconsistently?
Yes. On both Win7 and Win8, the capabilities are 0 when the device is first enumerated. When the device is removed and readded from Device Manager, the SurpriseRemovalOK bit is then set in the capabilities. We were unconditionally setting SurpriseRemovalOk to TRUE in our driver, so I don’t understand why it would not show up on first enumeration.
IIRC removable PCIe capability should be normally defined somewhere in the port config space,
and ACPI is involved as well. You could get away using IRP_MN_QUERY_CAPABILITIES on
Win7, but changes in Win8 could break that.
This capability was added to existing hardware, so I suspect that the config space support does not exist. Without SurpriseRemovalOK on the child device, our testing seems to work well on Win7 & Win8. My mental model seems incomplete, though–I wouldn’t have expected the child’s SurpriseRemovalOK to affect whether the parent showed up in the systray–and I’m trying to avoid “programming by coincidence.” 
–
Gabe
>Yes.
Because Removable=FALSE with SurpriseRemovalOk=TRUE is a special combination, which may or may not be handled in a special way by a particular OS version.
Removable=TRUE will show the device in the safe removal list, and SurpriseRemovalOk=TRUE will hide it even if Removable=TRUE. But if any child device will have SurpriseRemovalOk=FALSE, this may override TRUE for a removable device. Or not.
> Because Removable=FALSE with SurpriseRemovalOk=TRUE is a special combination,
which may or may not be handled in a special way by a particular OS version.
That makes my head hurt. It’s always fun playing in undocumented turf.
But if any child device will have SurpriseRemovalOk=FALSE, this may override
TRUE for a removable device. Or not.
I would expect (or at least not be surprised by–pun intended) that behavior. SurpriseRemovalOk=FALSE is a stricter requirement than SurpriseRemovalOk=TRUE, so if the child can’t be surprise removed, then it makes sense that the parent cannot be surprise removed. I’d also buy the argument that, since the child specifies Removable=FALSE, its SurpriseRemovalOK would be ignored and just be dictated by the parent’s setting.
The opposite seems to be true in our situation, though. The child has SurpriseRemovalOk=TRUE, the parent has SurpriseRemovalOk=FALSE, and the child setting seems to override the parent. It doesn’t change the parent’s capabilities (they are still listed as just REMOVABLE in Device Manager), but it keeps it from showing up in Safely Remove Hardware.