summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/atm/ueagle-atm.c94
-rw-r--r--drivers/usb/host/max3421-hcd.c8
2 files changed, 46 insertions, 56 deletions
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index f3ae72feb5bf..1e12fc19f872 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -51,12 +51,6 @@
"[ueagle-atm vdbg] " format, ##args); \
} while (0)
-#define uea_enters(usb_dev) \
- uea_vdbg(usb_dev, "entering %s\n" , __func__)
-
-#define uea_leaves(usb_dev) \
- uea_vdbg(usb_dev, "leaving %s\n" , __func__)
-
#define uea_err(usb_dev, format, args...) \
dev_err(&(usb_dev)->dev , "[UEAGLE-ATM] " format , ##args)
@@ -600,13 +594,14 @@ static int uea_send_modem_cmd(struct usb_device *usb,
static void uea_upload_pre_firmware(const struct firmware *fw_entry,
void *context)
{
- struct usb_device *usb = context;
+ struct usb_interface *intf = context;
+ struct usb_device *usb = interface_to_usbdev(intf);
+ struct completion *fw_done = usb_get_intfdata(intf);
const u8 *pfw;
u8 value;
u32 crc = 0;
int ret, size;
- uea_enters(usb);
if (!fw_entry) {
uea_err(usb, "firmware is not available\n");
goto err;
@@ -670,18 +665,18 @@ err_fw_corrupted:
uea_err(usb, "firmware is corrupted\n");
err:
release_firmware(fw_entry);
- uea_leaves(usb);
+ complete(fw_done);
}
/*
* uea_load_firmware - Load usb firmware for pre-firmware devices.
*/
-static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
+static int uea_load_firmware(struct usb_interface *intf, unsigned int ver)
{
int ret;
char *fw_name = EAGLE_FIRMWARE;
+ struct usb_device *usb = interface_to_usbdev(intf);
- uea_enters(usb);
uea_info(usb, "pre-firmware device, uploading firmware\n");
switch (ver) {
@@ -703,14 +698,13 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver)
}
ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev,
- GFP_KERNEL, usb,
+ GFP_KERNEL, intf,
uea_upload_pre_firmware);
if (ret)
uea_err(usb, "firmware %s is not available\n", fw_name);
else
uea_info(usb, "loading firmware %s\n", fw_name);
- uea_leaves(usb);
return ret;
}
@@ -1137,7 +1131,6 @@ static int uea_cmv_e1(struct uea_softc *sc,
struct cmv_e1 cmv;
int ret;
- uea_enters(INS_TO_USBDEV(sc));
uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, "
"offset : 0x%04x, data : 0x%08x\n",
E1_FUNCTION_TYPE(function),
@@ -1164,9 +1157,8 @@ static int uea_cmv_e1(struct uea_softc *sc,
sizeof(cmv), &cmv);
if (ret < 0)
return ret;
- ret = wait_cmv_ack(sc);
- uea_leaves(INS_TO_USBDEV(sc));
- return ret;
+
+ return wait_cmv_ack(sc);
}
static int uea_cmv_e4(struct uea_softc *sc,
@@ -1175,7 +1167,6 @@ static int uea_cmv_e4(struct uea_softc *sc,
struct cmv_e4 cmv;
int ret;
- uea_enters(INS_TO_USBDEV(sc));
memset(&cmv, 0, sizeof(cmv));
uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Group : 0x%04x, "
@@ -1199,9 +1190,8 @@ static int uea_cmv_e4(struct uea_softc *sc,
sizeof(cmv), &cmv);
if (ret < 0)
return ret;
- ret = wait_cmv_ack(sc);
- uea_leaves(INS_TO_USBDEV(sc));
- return ret;
+
+ return wait_cmv_ack(sc);
}
static inline int uea_read_cmv_e1(struct uea_softc *sc,
@@ -1295,7 +1285,6 @@ static int uea_stat_e1(struct uea_softc *sc)
u32 data;
int ret;
- uea_enters(INS_TO_USBDEV(sc));
data = sc->stats.phy.state;
ret = uea_read_cmv_e1(sc, E1_SA_STAT, 0, &sc->stats.phy.state);
@@ -1438,7 +1427,6 @@ static int uea_stat_e4(struct uea_softc *sc)
u32 tmp_arr[2];
int ret;
- uea_enters(INS_TO_USBDEV(sc));
data = sc->stats.phy.state;
/* XXX only need to be done before operationnal... */
@@ -1805,7 +1793,6 @@ static int uea_start_reset(struct uea_softc *sc)
u16 zero = 0; /* ;-) */
int ret;
- uea_enters(INS_TO_USBDEV(sc));
uea_info(INS_TO_USBDEV(sc), "(re)booting started\n");
/* mask interrupt */
@@ -1873,7 +1860,6 @@ static int uea_start_reset(struct uea_softc *sc)
return ret;
sc->reset = 0;
- uea_leaves(INS_TO_USBDEV(sc));
return ret;
}
@@ -1889,7 +1875,6 @@ static int uea_kthread(void *data)
int ret = -EAGAIN;
set_freezable();
- uea_enters(INS_TO_USBDEV(sc));
while (!kthread_should_stop()) {
if (ret < 0 || sc->reset)
ret = uea_start_reset(sc);
@@ -1898,7 +1883,7 @@ static int uea_kthread(void *data)
if (ret != -EAGAIN)
uea_wait(sc, 0, msecs_to_jiffies(1000));
}
- uea_leaves(INS_TO_USBDEV(sc));
+
return ret;
}
@@ -1911,8 +1896,6 @@ static int load_XILINX_firmware(struct uea_softc *sc)
u8 value;
char *fw_name = FPGA930_FIRMWARE;
- uea_enters(INS_TO_USBDEV(sc));
-
ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev);
if (ret) {
uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n",
@@ -1956,7 +1939,6 @@ static int load_XILINX_firmware(struct uea_softc *sc)
err1:
release_firmware(fw_entry);
err0:
- uea_leaves(INS_TO_USBDEV(sc));
return ret;
}
@@ -1966,7 +1948,6 @@ static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr)
struct cmv_dsc_e1 *dsc = &sc->cmv_dsc.e1;
struct cmv_e1 *cmv = &intr->u.e1.s2.cmv;
- uea_enters(INS_TO_USBDEV(sc));
if (le16_to_cpu(cmv->wPreamble) != E1_PREAMBLE)
goto bad1;
@@ -1990,7 +1971,6 @@ static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr)
if (cmv->bFunction == E1_MAKEFUNCTION(E1_ADSLDIRECTIVE,
E1_MODEMREADY)) {
wake_up_cmv_ack(sc);
- uea_leaves(INS_TO_USBDEV(sc));
return;
}
@@ -2004,7 +1984,6 @@ static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr)
sc->data = sc->data << 16 | sc->data >> 16;
wake_up_cmv_ack(sc);
- uea_leaves(INS_TO_USBDEV(sc));
return;
bad2:
@@ -2012,14 +1991,12 @@ bad2:
"Function : %d, Subfunction : %d\n",
E1_FUNCTION_TYPE(cmv->bFunction),
E1_FUNCTION_SUBTYPE(cmv->bFunction));
- uea_leaves(INS_TO_USBDEV(sc));
return;
bad1:
uea_err(INS_TO_USBDEV(sc), "invalid cmv received, "
"wPreamble %d, bDirection %d\n",
le16_to_cpu(cmv->wPreamble), cmv->bDirection);
- uea_leaves(INS_TO_USBDEV(sc));
}
/* The modem send us an ack. First with check if it right */
@@ -2028,7 +2005,6 @@ static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr)
struct cmv_dsc_e4 *dsc = &sc->cmv_dsc.e4;
struct cmv_e4 *cmv = &intr->u.e4.s2.cmv;
- uea_enters(INS_TO_USBDEV(sc));
uea_dbg(INS_TO_USBDEV(sc), "cmv %x %x %x %x %x %x\n",
be16_to_cpu(cmv->wGroup), be16_to_cpu(cmv->wFunction),
be16_to_cpu(cmv->wOffset), be16_to_cpu(cmv->wAddress),
@@ -2040,7 +2016,6 @@ static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr)
if (be16_to_cpu(cmv->wFunction) == E4_MAKEFUNCTION(E4_ADSLDIRECTIVE,
E4_MODEMREADY, 1)) {
wake_up_cmv_ack(sc);
- uea_leaves(INS_TO_USBDEV(sc));
return;
}
@@ -2053,7 +2028,6 @@ static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr)
sc->data = be32_to_cpu(cmv->dwData[0]);
sc->data1 = be32_to_cpu(cmv->dwData[1]);
wake_up_cmv_ack(sc);
- uea_leaves(INS_TO_USBDEV(sc));
return;
bad2:
@@ -2061,7 +2035,6 @@ bad2:
"Function : %d, Subfunction : %d\n",
E4_FUNCTION_TYPE(cmv->wFunction),
E4_FUNCTION_SUBTYPE(cmv->wFunction));
- uea_leaves(INS_TO_USBDEV(sc));
return;
}
@@ -2089,8 +2062,6 @@ static void uea_intr(struct urb *urb)
struct intr_pkt *intr = urb->transfer_buffer;
int status = urb->status;
- uea_enters(INS_TO_USBDEV(sc));
-
if (unlikely(status < 0)) {
uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n",
status);
@@ -2130,8 +2101,6 @@ static int uea_boot(struct uea_softc *sc, struct usb_interface *intf)
int ret = -ENOMEM;
int size;
- uea_enters(INS_TO_USBDEV(sc));
-
if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {
size = E4_INTR_PKT_SIZE;
sc->dispatch_cmv = uea_dispatch_cmv_e4;
@@ -2188,7 +2157,6 @@ static int uea_boot(struct uea_softc *sc, struct usb_interface *intf)
goto err2;
}
- uea_leaves(INS_TO_USBDEV(sc));
return 0;
err2:
@@ -2198,7 +2166,6 @@ err1:
sc->urb_int = NULL;
kfree(intr);
err0:
- uea_leaves(INS_TO_USBDEV(sc));
return ret;
}
@@ -2208,7 +2175,7 @@ err0:
static void uea_stop(struct uea_softc *sc)
{
int ret;
- uea_enters(INS_TO_USBDEV(sc));
+
ret = kthread_stop(sc->kthread);
uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);
@@ -2222,7 +2189,6 @@ static void uea_stop(struct uea_softc *sc)
flush_work(&sc->task);
release_firmware(sc->dsp_firm);
- uea_leaves(INS_TO_USBDEV(sc));
}
/* syfs interface */
@@ -2495,8 +2461,6 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;
unsigned int alt;
- uea_enters(usb);
-
/* interface 0 is for firmware/monitoring */
if (ifnum != UEA_INTR_IFACE_NO)
return -ENODEV;
@@ -2589,8 +2553,7 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
struct usb_device *usb = interface_to_usbdev(intf);
int ret;
- uea_enters(usb);
- uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",
+ uea_dbg(usb, "ADSL device found with vid (%#X) pid (%#X) Rev (%#X): %s\n",
le16_to_cpu(usb->descriptor.idVendor),
le16_to_cpu(usb->descriptor.idProduct),
le16_to_cpu(usb->descriptor.bcdDevice),
@@ -2598,8 +2561,23 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
usb_reset_device(usb);
- if (UEA_IS_PREFIRM(id))
- return uea_load_firmware(usb, UEA_CHIP_VERSION(id));
+ if (UEA_IS_PREFIRM(id)) {
+ struct completion *fw_done;
+
+ /* Wait for the firmware load to be done, in .disconnect() */
+ fw_done = kzalloc_obj(*fw_done);
+ if (!fw_done)
+ return -ENOMEM;
+
+ init_completion(fw_done);
+ usb_set_intfdata(intf, fw_done);
+
+ ret = uea_load_firmware(intf, UEA_CHIP_VERSION(id));
+ if (ret)
+ kfree(fw_done);
+
+ return ret;
+ }
ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver);
if (ret == 0) {
@@ -2620,7 +2598,6 @@ static void uea_disconnect(struct usb_interface *intf)
{
struct usb_device *usb = interface_to_usbdev(intf);
int ifnum = intf->altsetting->desc.bInterfaceNumber;
- uea_enters(usb);
/* ADI930 has 2 interfaces and eagle 3 interfaces.
* Pre-firmware device has one interface
@@ -2630,9 +2607,14 @@ static void uea_disconnect(struct usb_interface *intf)
usbatm_usb_disconnect(intf);
mutex_unlock(&uea_mutex);
uea_info(usb, "ADSL device removed\n");
- }
+ } else if (usb->config->desc.bNumInterfaces == 1) {
+ struct completion *fw_done = usb_get_intfdata(intf);
- uea_leaves(usb);
+ uea_dbg(usb, "pre-firmware device, waiting firmware upload\n");
+ wait_for_completion(fw_done);
+ uea_dbg(usb, "pre-firmware device, finished waiting\n");
+ kfree(fw_done);
+ }
}
/*
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c
index 0e17c988d36a..73e76d0e6973 100644
--- a/drivers/usb/host/max3421-hcd.c
+++ b/drivers/usb/host/max3421-hcd.c
@@ -1685,6 +1685,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
case ClearHubFeature:
break;
case ClearPortFeature:
+ if (index != 1)
+ goto error;
switch (value) {
case USB_PORT_FEAT_SUSPEND:
break;
@@ -1694,6 +1696,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
!pdata->vbus_active_level);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
max3421_hcd->port_status &= ~(1 << value);
}
break;
@@ -1726,6 +1730,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
break;
case SetPortFeature:
+ if (index != 1)
+ goto error;
switch (value) {
case USB_PORT_FEAT_LINK_STATE:
case USB_PORT_FEAT_U1_TIMEOUT:
@@ -1747,6 +1753,8 @@ max3421_hub_control(struct usb_hcd *hcd, u16 type_req, u16 value, u16 index,
max3421_reset_port(hcd);
fallthrough;
default:
+ if (value >= 32)
+ goto error;
if ((max3421_hcd->port_status & USB_PORT_STAT_POWER)
!= 0)
max3421_hcd->port_status |= (1 << value);