Commit 10cec917 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-4.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg KH:
 "Here are a number of small USB driver fixes and new device ids for
  4.13-rc5. There is the usual gadget driver fixes, some new quirks for
  "messy" hardware, and some new device ids.

  All have been in linux-next with no reported issues"

* tag 'usb-4.13-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: serial: pl2303: add new ATEN device id
  usb: quirks: Add no-lpm quirk for Moshi USB to Ethernet Adapter
  USB: Check for dropped connection before switching to full speed
  usb:xhci:Add quirk for Certain failing HP keyboard on reset after resume
  usb: renesas_usbhs: gadget: fix unused-but-set-variable warning
  usb: renesas_usbhs: Fix UGCTRL2 value for R-Car Gen3
  usb: phy: phy-msm-usb: Fix usage of devm_regulator_bulk_get()
  usb: gadget: udc: renesas_usb3: Fix usb_gadget_giveback_request() calling
  usb: dwc3: gadget: Correct ISOC DATA PIDs for short packets
  USB: serial: option: add D-Link DWM-222 device ID
  usb: musb: fix tx fifo flush handling again
  usb: core: unlink urbs from the tail of the endpoint's urb_list
  usb-storage: fix deadlock involving host lock and scsi_done
  uas: Add US_FL_IGNORE_RESIDUE for Initio Corporation INIC-3069
  USB: hcd: Mark secondary HCD as dead if the primary one died
  USB: serial: cp210x: add support for Qivicon USB ZigBee dongle
parents 89a55278 3b6bcd3d
...@@ -1888,7 +1888,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev, ...@@ -1888,7 +1888,7 @@ void usb_hcd_flush_endpoint(struct usb_device *udev,
/* No more submits can occur */ /* No more submits can occur */
spin_lock_irq(&hcd_urb_list_lock); spin_lock_irq(&hcd_urb_list_lock);
rescan: rescan:
list_for_each_entry (urb, &ep->urb_list, urb_list) { list_for_each_entry_reverse(urb, &ep->urb_list, urb_list) {
int is_in; int is_in;
if (urb->unlinked) if (urb->unlinked)
...@@ -2485,6 +2485,8 @@ void usb_hc_died (struct usb_hcd *hcd) ...@@ -2485,6 +2485,8 @@ void usb_hc_died (struct usb_hcd *hcd)
} }
if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) { if (usb_hcd_is_primary_hcd(hcd) && hcd->shared_hcd) {
hcd = hcd->shared_hcd; hcd = hcd->shared_hcd;
clear_bit(HCD_FLAG_RH_RUNNING, &hcd->flags);
set_bit(HCD_FLAG_DEAD, &hcd->flags);
if (hcd->rh_registered) { if (hcd->rh_registered) {
clear_bit(HCD_FLAG_POLL_RH, &hcd->flags); clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
......
...@@ -4725,7 +4725,8 @@ hub_power_remaining(struct usb_hub *hub) ...@@ -4725,7 +4725,8 @@ hub_power_remaining(struct usb_hub *hub)
static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
u16 portchange) u16 portchange)
{ {
int status, i; int status = -ENODEV;
int i;
unsigned unit_load; unsigned unit_load;
struct usb_device *hdev = hub->hdev; struct usb_device *hdev = hub->hdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus); struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
...@@ -4929,9 +4930,10 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus, ...@@ -4929,9 +4930,10 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
done: done:
hub_port_disable(hub, port1, 1); hub_port_disable(hub, port1, 1);
if (hcd->driver->relinquish_port && !hub->hdev->parent) if (hcd->driver->relinquish_port && !hub->hdev->parent) {
if (status != -ENOTCONN && status != -ENODEV)
hcd->driver->relinquish_port(hcd, port1); hcd->driver->relinquish_port(hcd, port1);
}
} }
/* Handle physical or logical connection change events. /* Handle physical or logical connection change events.
......
...@@ -150,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = { ...@@ -150,6 +150,9 @@ static const struct usb_device_id usb_quirk_list[] = {
/* appletouch */ /* appletouch */
{ USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x05ac, 0x021a), .driver_info = USB_QUIRK_RESET_RESUME },
/* Genesys Logic hub, internally used by Moshi USB to Ethernet Adapter */
{ USB_DEVICE(0x05e3, 0x0616), .driver_info = USB_QUIRK_NO_LPM },
/* Avision AV600U */ /* Avision AV600U */
{ USB_DEVICE(0x0638, 0x0a13), .driver_info = { USB_DEVICE(0x0638, 0x0a13), .driver_info =
USB_QUIRK_STRING_FETCH_255 }, USB_QUIRK_STRING_FETCH_255 },
...@@ -249,6 +252,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = { ...@@ -249,6 +252,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
{ USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x093a, 0x2500), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x093a, 0x2510), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x093a, 0x2521), .driver_info = USB_QUIRK_RESET_RESUME },
{ USB_DEVICE(0x03f0, 0x2b4a), .driver_info = USB_QUIRK_RESET_RESUME },
/* Logitech Optical Mouse M90/M100 */ /* Logitech Optical Mouse M90/M100 */
{ USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME }, { USB_DEVICE(0x046d, 0xc05a), .driver_info = USB_QUIRK_RESET_RESUME },
......
...@@ -896,9 +896,40 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, ...@@ -896,9 +896,40 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
if (!node) { if (!node) {
trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
/*
* USB Specification 2.0 Section 5.9.2 states that: "If
* there is only a single transaction in the microframe,
* only a DATA0 data packet PID is used. If there are
* two transactions per microframe, DATA1 is used for
* the first transaction data packet and DATA0 is used
* for the second transaction data packet. If there are
* three transactions per microframe, DATA2 is used for
* the first transaction data packet, DATA1 is used for
* the second, and DATA0 is used for the third."
*
* IOW, we should satisfy the following cases:
*
* 1) length <= maxpacket
* - DATA0
*
* 2) maxpacket < length <= (2 * maxpacket)
* - DATA1, DATA0
*
* 3) (2 * maxpacket) < length <= (3 * maxpacket)
* - DATA2, DATA1, DATA0
*/
if (speed == USB_SPEED_HIGH) { if (speed == USB_SPEED_HIGH) {
struct usb_ep *ep = &dep->endpoint; struct usb_ep *ep = &dep->endpoint;
trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1); unsigned int mult = ep->mult - 1;
unsigned int maxp = usb_endpoint_maxp(ep->desc);
if (length <= (2 * maxp))
mult--;
if (length <= maxp)
mult--;
trb->size |= DWC3_TRB_SIZE_PCM1(mult);
} }
} else { } else {
trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS; trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
......
...@@ -838,21 +838,32 @@ static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep ...@@ -838,21 +838,32 @@ static struct renesas_usb3_request *usb3_get_request(struct renesas_usb3_ep
return usb3_req; return usb3_req;
} }
static void usb3_request_done(struct renesas_usb3_ep *usb3_ep, static void __usb3_request_done(struct renesas_usb3_ep *usb3_ep,
struct renesas_usb3_request *usb3_req, int status) struct renesas_usb3_request *usb3_req,
int status)
{ {
struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep); struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
unsigned long flags;
dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n", dev_dbg(usb3_to_dev(usb3), "giveback: ep%2d, %u, %u, %d\n",
usb3_ep->num, usb3_req->req.length, usb3_req->req.actual, usb3_ep->num, usb3_req->req.length, usb3_req->req.actual,
status); status);
usb3_req->req.status = status; usb3_req->req.status = status;
spin_lock_irqsave(&usb3->lock, flags);
usb3_ep->started = false; usb3_ep->started = false;
list_del_init(&usb3_req->queue); list_del_init(&usb3_req->queue);
spin_unlock_irqrestore(&usb3->lock, flags); spin_unlock(&usb3->lock);
usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req); usb_gadget_giveback_request(&usb3_ep->ep, &usb3_req->req);
spin_lock(&usb3->lock);
}
static void usb3_request_done(struct renesas_usb3_ep *usb3_ep,
struct renesas_usb3_request *usb3_req, int status)
{
struct renesas_usb3 *usb3 = usb3_ep_to_usb3(usb3_ep);
unsigned long flags;
spin_lock_irqsave(&usb3->lock, flags);
__usb3_request_done(usb3_ep, usb3_req, status);
spin_unlock_irqrestore(&usb3->lock, flags);
} }
static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3) static void usb3_irq_epc_pipe0_status_end(struct renesas_usb3 *usb3)
......
...@@ -98,6 +98,7 @@ enum amd_chipset_gen { ...@@ -98,6 +98,7 @@ enum amd_chipset_gen {
AMD_CHIPSET_HUDSON2, AMD_CHIPSET_HUDSON2,
AMD_CHIPSET_BOLTON, AMD_CHIPSET_BOLTON,
AMD_CHIPSET_YANGTZE, AMD_CHIPSET_YANGTZE,
AMD_CHIPSET_TAISHAN,
AMD_CHIPSET_UNKNOWN, AMD_CHIPSET_UNKNOWN,
}; };
...@@ -141,6 +142,11 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo) ...@@ -141,6 +142,11 @@ static int amd_chipset_sb_type_init(struct amd_chipset_info *pinfo)
pinfo->sb_type.gen = AMD_CHIPSET_SB700; pinfo->sb_type.gen = AMD_CHIPSET_SB700;
else if (rev >= 0x40 && rev <= 0x4f) else if (rev >= 0x40 && rev <= 0x4f)
pinfo->sb_type.gen = AMD_CHIPSET_SB800; pinfo->sb_type.gen = AMD_CHIPSET_SB800;
}
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
0x145c, NULL);
if (pinfo->smbus_dev) {
pinfo->sb_type.gen = AMD_CHIPSET_TAISHAN;
} else { } else {
pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, pinfo->smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD,
PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL); PCI_DEVICE_ID_AMD_HUDSON2_SMBUS, NULL);
...@@ -260,11 +266,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev) ...@@ -260,11 +266,12 @@ int usb_hcd_amd_remote_wakeup_quirk(struct pci_dev *pdev)
{ {
/* Make sure amd chipset type has already been initialized */ /* Make sure amd chipset type has already been initialized */
usb_amd_find_chipset_info(); usb_amd_find_chipset_info();
if (amd_chipset.sb_type.gen != AMD_CHIPSET_YANGTZE) if (amd_chipset.sb_type.gen == AMD_CHIPSET_YANGTZE ||
return 0; amd_chipset.sb_type.gen == AMD_CHIPSET_TAISHAN) {
dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n"); dev_dbg(&pdev->dev, "QUIRK: Enable AMD remote wakeup fix\n");
return 1; return 1;
}
return 0;
} }
EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk); EXPORT_SYMBOL_GPL(usb_hcd_amd_remote_wakeup_quirk);
......
...@@ -139,6 +139,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep) ...@@ -139,6 +139,7 @@ static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
"Could not flush host TX%d fifo: csr: %04x\n", "Could not flush host TX%d fifo: csr: %04x\n",
ep->epnum, csr)) ep->epnum, csr))
return; return;
mdelay(1);
} }
} }
......
...@@ -197,6 +197,7 @@ struct msm_otg { ...@@ -197,6 +197,7 @@ struct msm_otg {
struct regulator *v3p3; struct regulator *v3p3;
struct regulator *v1p8; struct regulator *v1p8;
struct regulator *vddcx; struct regulator *vddcx;
struct regulator_bulk_data supplies[3];
struct reset_control *phy_rst; struct reset_control *phy_rst;
struct reset_control *link_rst; struct reset_control *link_rst;
...@@ -1731,7 +1732,6 @@ static int msm_otg_reboot_notify(struct notifier_block *this, ...@@ -1731,7 +1732,6 @@ static int msm_otg_reboot_notify(struct notifier_block *this,
static int msm_otg_probe(struct platform_device *pdev) static int msm_otg_probe(struct platform_device *pdev)
{ {
struct regulator_bulk_data regs[3];
int ret = 0; int ret = 0;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct msm_otg_platform_data *pdata; struct msm_otg_platform_data *pdata;
...@@ -1817,17 +1817,18 @@ static int msm_otg_probe(struct platform_device *pdev) ...@@ -1817,17 +1817,18 @@ static int msm_otg_probe(struct platform_device *pdev)
return motg->irq; return motg->irq;
} }
regs[0].supply = "vddcx"; motg->supplies[0].supply = "vddcx";
regs[1].supply = "v3p3"; motg->supplies[1].supply = "v3p3";
regs[2].supply = "v1p8"; motg->supplies[2].supply = "v1p8";
ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(motg->supplies),
motg->supplies);
if (ret) if (ret)
return ret; return ret;
motg->vddcx = regs[0].consumer; motg->vddcx = motg->supplies[0].consumer;
motg->v3p3 = regs[1].consumer; motg->v3p3 = motg->supplies[1].consumer;
motg->v1p8 = regs[2].consumer; motg->v1p8 = motg->supplies[2].consumer;
clk_set_rate(motg->clk, 60000000); clk_set_rate(motg->clk, 60000000);
......
...@@ -639,14 +639,11 @@ static int usbhsg_ep_disable(struct usb_ep *ep) ...@@ -639,14 +639,11 @@ static int usbhsg_ep_disable(struct usb_ep *ep)
struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep);
struct usbhs_pipe *pipe; struct usbhs_pipe *pipe;
unsigned long flags; unsigned long flags;
int ret = 0;
spin_lock_irqsave(&uep->lock, flags); spin_lock_irqsave(&uep->lock, flags);
pipe = usbhsg_uep_to_pipe(uep); pipe = usbhsg_uep_to_pipe(uep);
if (!pipe) { if (!pipe)
ret = -EINVAL;
goto out; goto out;
}
usbhsg_pipe_disable(uep); usbhsg_pipe_disable(uep);
usbhs_pipe_free(pipe); usbhs_pipe_free(pipe);
......
...@@ -20,9 +20,13 @@ ...@@ -20,9 +20,13 @@
/* Low Power Status register (LPSTS) */ /* Low Power Status register (LPSTS) */
#define LPSTS_SUSPM 0x4000 #define LPSTS_SUSPM 0x4000
/* USB General control register 2 (UGCTRL2), bit[31:6] should be 0 */ /*
* USB General control register 2 (UGCTRL2)
* Remarks: bit[31:11] and bit[9:6] should be 0
*/
#define UGCTRL2_RESERVED_3 0x00000001 /* bit[3:0] should be B'0001 */ #define UGCTRL2_RESERVED_3 0x00000001 /* bit[3:0] should be B'0001 */
#define UGCTRL2_USB0SEL_OTG 0x00000030 #define UGCTRL2_USB0SEL_OTG 0x00000030
#define UGCTRL2_VBUSSEL 0x00000400
static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data) static void usbhs_write32(struct usbhs_priv *priv, u32 reg, u32 data)
{ {
...@@ -34,7 +38,8 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev, ...@@ -34,7 +38,8 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
{ {
struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev);
usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG); usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG |
UGCTRL2_VBUSSEL);
if (enable) { if (enable) {
usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM); usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
......
...@@ -142,6 +142,7 @@ static const struct usb_device_id id_table[] = { ...@@ -142,6 +142,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */ { USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */ { USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
{ USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */ { USB_DEVICE(0x10C4, 0x8A5E) }, /* CEL EM3588 ZigBee USB Stick Long Range */
{ USB_DEVICE(0x10C4, 0x8B34) }, /* Qivicon ZigBee USB Radio Stick */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
......
...@@ -2025,6 +2025,8 @@ static const struct usb_device_id option_ids[] = { ...@@ -2025,6 +2025,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) }, /* D-Link DWM-158 */
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist }, .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e35, 0xff), /* D-Link DWM-222 */
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x7e11, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/A3 */
......
...@@ -52,6 +52,8 @@ static const struct usb_device_id id_table[] = { ...@@ -52,6 +52,8 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) }, { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID), { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID),
.driver_info = PL2303_QUIRK_ENDPOINT_HACK }, .driver_info = PL2303_QUIRK_ENDPOINT_HACK },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_UC485),
.driver_info = PL2303_QUIRK_ENDPOINT_HACK },
{ USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) }, { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID2) },
{ USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) }, { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
{ USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) }, { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define ATEN_VENDOR_ID 0x0557 #define ATEN_VENDOR_ID 0x0557
#define ATEN_VENDOR_ID2 0x0547 #define ATEN_VENDOR_ID2 0x0547
#define ATEN_PRODUCT_ID 0x2008 #define ATEN_PRODUCT_ID 0x2008
#define ATEN_PRODUCT_UC485 0x2021
#define ATEN_PRODUCT_ID2 0x2118 #define ATEN_PRODUCT_ID2 0x2118
#define IODATA_VENDOR_ID 0x04bb #define IODATA_VENDOR_ID 0x04bb
......
...@@ -124,9 +124,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999, ...@@ -124,9 +124,9 @@ UNUSUAL_DEV(0x0bc2, 0xab2a, 0x0000, 0x9999,
/* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */ /* Reported-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> */
UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999,
"Initio Corporation", "Initio Corporation",
"", "INIC-3069",
USB_SC_DEVICE, USB_PR_DEVICE, NULL, USB_SC_DEVICE, USB_PR_DEVICE, NULL,
US_FL_NO_ATA_1X), US_FL_NO_ATA_1X | US_FL_IGNORE_RESIDUE),
/* Reported-by: Tom Arild Naess <tanaess@gmail.com> */ /* Reported-by: Tom Arild Naess <tanaess@gmail.com> */
UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999, UNUSUAL_DEV(0x152d, 0x0539, 0x0000, 0x9999,
......
...@@ -315,6 +315,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -315,6 +315,7 @@ static int usb_stor_control_thread(void * __us)
{ {
struct us_data *us = (struct us_data *)__us; struct us_data *us = (struct us_data *)__us;
struct Scsi_Host *host = us_to_host(us); struct Scsi_Host *host = us_to_host(us);
struct scsi_cmnd *srb;
for (;;) { for (;;) {
usb_stor_dbg(us, "*** thread sleeping\n"); usb_stor_dbg(us, "*** thread sleeping\n");
...@@ -330,6 +331,7 @@ static int usb_stor_control_thread(void * __us) ...@@ -330,6 +331,7 @@ static int usb_stor_control_thread(void * __us)
scsi_lock(host); scsi_lock(host);
/* When we are called with no command pending, we're done */ /* When we are called with no command pending, we're done */
srb = us->srb;
if (us->srb == NULL) { if (us->srb == NULL) {
scsi_unlock(host); scsi_unlock(host);
mutex_unlock(&us->dev_mutex); mutex_unlock(&us->dev_mutex);
...@@ -398,14 +400,11 @@ static int usb_stor_control_thread(void * __us) ...@@ -398,14 +400,11 @@ static int usb_stor_control_thread(void * __us)
/* lock access to the state */ /* lock access to the state */
scsi_lock(host); scsi_lock(host);
/* indicate that the command is done */ /* was the command aborted? */
if (us->srb->result != DID_ABORT << 16) { if (us->srb->result == DID_ABORT << 16) {
usb_stor_dbg(us, "scsi cmd done, result=0x%x\n",
us->srb->result);
us->srb->scsi_done(us->srb);
} else {
SkipForAbort: SkipForAbort:
usb_stor_dbg(us, "scsi command aborted\n"); usb_stor_dbg(us, "scsi command aborted\n");
srb = NULL; /* Don't call srb->scsi_done() */
} }
/* /*
...@@ -429,6 +428,13 @@ static int usb_stor_control_thread(void * __us) ...@@ -429,6 +428,13 @@ static int usb_stor_control_thread(void * __us)
/* unlock the device pointers */ /* unlock the device pointers */
mutex_unlock(&us->dev_mutex); mutex_unlock(&us->dev_mutex);
/* now that the locks are released, notify the SCSI core */
if (srb) {
usb_stor_dbg(us, "scsi cmd done, result=0x%x\n",
srb->result);
srb->scsi_done(srb);
}
} /* for (;;) */ } /* for (;;) */
/* Wait until we are told to stop */ /* Wait until we are told to stop */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment