Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c6092bb744 | |||
| 49a1ecd51a | |||
| 8b87061014 | |||
| 0651bd3e20 | |||
| f3b01b793c | |||
| b3f3b814ad | |||
| c4a3b46029 | |||
| e3052eb712 | |||
| 1c4fc5e51d | |||
| 5006010c7a | |||
| d18c73f23f | |||
| b2be9b06f9 | |||
| edbce27e33 | |||
| 0ee643c288 | |||
| 762083a99a | |||
| 9c9cc09d08 | |||
| 27356a5bb5 | |||
| 743e705ee4 | |||
| efdd902a13 | |||
| 409939cebe | |||
| 4cac0c9a73 | |||
| 9155bc2acd | |||
| f366ac017f | |||
| 1a7dcc9ae2 | |||
| 8002daf988 | |||
| ee537508bd | |||
| 2b66cca800 | |||
| d128a53449 | |||
| f83994f3e2 | |||
| ec2cbc5e8d | |||
| ea0337dea7 | |||
| 320e71f47b | |||
| 2975303676 | |||
| 43f7940638 | |||
| c08f21a001 | |||
| 115df7d533 | |||
| 5ded9348b7 | |||
| f680d99156 | |||
| d980f62588 | |||
| 10b96fa9ff | |||
| 79abf50396 | |||
| c8181245e0 | |||
| 4c68fab02c | |||
| 22d0fff157 | |||
| 63c50ecb1e | |||
| 42ff6af381 | |||
| 46b91997f6 | |||
| 3d6cbe2361 | |||
| cef87aeb39 | |||
| ccc3dda4b1 | |||
| 782d8021f3 | |||
| 57bbde3fc3 | |||
| 7135bbef51 | |||
| 0eccd99ec8 | |||
| 2f710e1def | |||
| cd46958d3b | |||
| 96266edf0e |
@@ -1,6 +1,6 @@
|
||||
VERSION = 3
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 0
|
||||
SUBLEVEL = 1
|
||||
EXTRAVERSION =
|
||||
NAME = Terrified Chipmunk
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@
|
||||
#define OMAP_UART_WER_MOD_WKUP 0X7F
|
||||
|
||||
/* Enable XON/XOFF flow control on output */
|
||||
#define OMAP_UART_SW_TX 0x04
|
||||
#define OMAP_UART_SW_TX 0x8
|
||||
|
||||
/* Enable XON/XOFF flow control on input */
|
||||
#define OMAP_UART_SW_RX 0x04
|
||||
#define OMAP_UART_SW_RX 0x2
|
||||
|
||||
#define OMAP_UART_SYSC_RESET 0X07
|
||||
#define OMAP_UART_TCR_TRIG 0X0F
|
||||
|
||||
@@ -67,7 +67,7 @@ static int tpk_printk(const unsigned char *buf, int count)
|
||||
tmp[tpk_curr + 1] = '\0';
|
||||
printk(KERN_INFO "%s%s", tpk_tag, tmp);
|
||||
tpk_curr = 0;
|
||||
if (buf[i + 1] == '\n')
|
||||
if ((i + 1) < count && buf[i + 1] == '\n')
|
||||
i++;
|
||||
break;
|
||||
case '\n':
|
||||
|
||||
@@ -435,12 +435,23 @@ efivar_attr_read(struct efivar_entry *entry, char *buf)
|
||||
if (status != EFI_SUCCESS)
|
||||
return -EIO;
|
||||
|
||||
if (var->Attributes & 0x1)
|
||||
if (var->Attributes & EFI_VARIABLE_NON_VOLATILE)
|
||||
str += sprintf(str, "EFI_VARIABLE_NON_VOLATILE\n");
|
||||
if (var->Attributes & 0x2)
|
||||
if (var->Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS)
|
||||
str += sprintf(str, "EFI_VARIABLE_BOOTSERVICE_ACCESS\n");
|
||||
if (var->Attributes & 0x4)
|
||||
if (var->Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
|
||||
str += sprintf(str, "EFI_VARIABLE_RUNTIME_ACCESS\n");
|
||||
if (var->Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
|
||||
str += sprintf(str, "EFI_VARIABLE_HARDWARE_ERROR_RECORD\n");
|
||||
if (var->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
|
||||
str += sprintf(str,
|
||||
"EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS\n");
|
||||
if (var->Attributes &
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
|
||||
str += sprintf(str,
|
||||
"EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS\n");
|
||||
if (var->Attributes & EFI_VARIABLE_APPEND_WRITE)
|
||||
str += sprintf(str, "EFI_VARIABLE_APPEND_WRITE\n");
|
||||
return str - buf;
|
||||
}
|
||||
|
||||
|
||||
+15
-5
@@ -757,6 +757,7 @@ int hid_open_report(struct hid_device *device)
|
||||
struct hid_item item;
|
||||
unsigned int size;
|
||||
__u8 *start;
|
||||
__u8 *buf;
|
||||
__u8 *end;
|
||||
int ret;
|
||||
static int (*dispatch_type[])(struct hid_parser *parser,
|
||||
@@ -775,12 +776,21 @@ int hid_open_report(struct hid_device *device)
|
||||
return -ENODEV;
|
||||
size = device->dev_rsize;
|
||||
|
||||
if (device->driver->report_fixup)
|
||||
start = device->driver->report_fixup(device, start, &size);
|
||||
|
||||
device->rdesc = kmemdup(start, size, GFP_KERNEL);
|
||||
if (device->rdesc == NULL)
|
||||
buf = kmemdup(start, size, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (device->driver->report_fixup)
|
||||
start = device->driver->report_fixup(device, buf, &size);
|
||||
else
|
||||
start = buf;
|
||||
|
||||
start = kmemdup(start, size, GFP_KERNEL);
|
||||
kfree(buf);
|
||||
if (start == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
device->rdesc = start;
|
||||
device->rsize = size;
|
||||
|
||||
parser = vzalloc(sizeof(struct hid_parser));
|
||||
|
||||
@@ -1415,20 +1415,20 @@ static int hid_post_reset(struct usb_interface *intf)
|
||||
* configuration descriptors passed, we already know that
|
||||
* the size of the HID report descriptor has not changed.
|
||||
*/
|
||||
rdesc = kmalloc(hid->rsize, GFP_KERNEL);
|
||||
rdesc = kmalloc(hid->dev_rsize, GFP_KERNEL);
|
||||
if (!rdesc) {
|
||||
dbg_hid("couldn't allocate rdesc memory (post_reset)\n");
|
||||
return 1;
|
||||
}
|
||||
status = hid_get_class_descriptor(dev,
|
||||
interface->desc.bInterfaceNumber,
|
||||
HID_DT_REPORT, rdesc, hid->rsize);
|
||||
HID_DT_REPORT, rdesc, hid->dev_rsize);
|
||||
if (status < 0) {
|
||||
dbg_hid("reading report descriptor failed (post_reset)\n");
|
||||
kfree(rdesc);
|
||||
return 1;
|
||||
}
|
||||
status = memcmp(rdesc, hid->rdesc, hid->rsize);
|
||||
status = memcmp(rdesc, hid->dev_rdesc, hid->dev_rsize);
|
||||
kfree(rdesc);
|
||||
if (status != 0) {
|
||||
dbg_hid("report descriptor changed\n");
|
||||
|
||||
@@ -186,8 +186,9 @@ int qib_lkey_ok(struct qib_lkey_table *rkt, struct qib_pd *pd,
|
||||
goto bail;
|
||||
|
||||
off = sge->addr - mr->user_base;
|
||||
if (unlikely(sge->addr < mr->iova || off + sge->length > mr->length ||
|
||||
(mr->access_flags & acc) == 0))
|
||||
if (unlikely(sge->addr < mr->user_base ||
|
||||
off + sge->length > mr->length ||
|
||||
(mr->access_flags & acc) != acc))
|
||||
goto bail;
|
||||
if (unlikely(!atomic_inc_not_zero(&mr->refcount)))
|
||||
goto bail;
|
||||
|
||||
@@ -150,7 +150,7 @@ static int ipoib_stop(struct net_device *dev)
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
ipoib_ib_dev_down(dev, 0);
|
||||
ipoib_ib_dev_down(dev, 1);
|
||||
ipoib_ib_dev_stop(dev, 0);
|
||||
|
||||
if (!test_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags)) {
|
||||
|
||||
@@ -175,7 +175,9 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
|
||||
|
||||
mcast->mcmember = *mcmember;
|
||||
|
||||
/* Set the cached Q_Key before we attach if it's the broadcast group */
|
||||
/* Set the multicast MTU and cached Q_Key before we attach if it's
|
||||
* the broadcast group.
|
||||
*/
|
||||
if (!memcmp(mcast->mcmember.mgid.raw, priv->dev->broadcast + 4,
|
||||
sizeof (union ib_gid))) {
|
||||
spin_lock_irq(&priv->lock);
|
||||
@@ -183,10 +185,17 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
|
||||
spin_unlock_irq(&priv->lock);
|
||||
return -EAGAIN;
|
||||
}
|
||||
priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu));
|
||||
priv->qkey = be32_to_cpu(priv->broadcast->mcmember.qkey);
|
||||
spin_unlock_irq(&priv->lock);
|
||||
priv->tx_wr.wr.ud.remote_qkey = priv->qkey;
|
||||
set_qkey = 1;
|
||||
|
||||
if (!ipoib_cm_admin_enabled(dev)) {
|
||||
rtnl_lock();
|
||||
dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu));
|
||||
rtnl_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
if (!test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) {
|
||||
@@ -574,14 +583,6 @@ void ipoib_mcast_join_task(struct work_struct *work)
|
||||
return;
|
||||
}
|
||||
|
||||
priv->mcast_mtu = IPOIB_UD_MTU(ib_mtu_enum_to_int(priv->broadcast->mcmember.mtu));
|
||||
|
||||
if (!ipoib_cm_admin_enabled(dev)) {
|
||||
rtnl_lock();
|
||||
dev_set_mtu(dev, min(priv->mcast_mtu, priv->admin_mtu));
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
ipoib_dbg_mcast(priv, "successfully joined all multicast groups\n");
|
||||
|
||||
clear_bit(IPOIB_MCAST_RUN, &priv->flags);
|
||||
|
||||
@@ -638,9 +638,9 @@ static void srp_reset_req(struct srp_target_port *target, struct srp_request *re
|
||||
struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL);
|
||||
|
||||
if (scmnd) {
|
||||
srp_free_req(target, req, scmnd, 0);
|
||||
scmnd->result = DID_RESET << 16;
|
||||
scmnd->scsi_done(scmnd);
|
||||
srp_free_req(target, req, scmnd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1687,6 +1687,7 @@ static int srp_abort(struct scsi_cmnd *scmnd)
|
||||
SRP_TSK_ABORT_TASK);
|
||||
srp_free_req(target, req, scmnd, 0);
|
||||
scmnd->result = DID_ABORT << 16;
|
||||
scmnd->scsi_done(scmnd);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -53,14 +53,19 @@
|
||||
#define ABS_POS_BITS 13
|
||||
|
||||
/*
|
||||
* Any position values from the hardware above the following limits are
|
||||
* treated as "wrapped around negative" values that have been truncated to
|
||||
* the 13-bit reporting range of the hardware. These are just reasonable
|
||||
* guesses and can be adjusted if hardware is found that operates outside
|
||||
* of these parameters.
|
||||
* These values should represent the absolute maximum value that will
|
||||
* be reported for a positive position value. Some Synaptics firmware
|
||||
* uses this value to indicate a finger near the edge of the touchpad
|
||||
* whose precise position cannot be determined.
|
||||
*
|
||||
* At least one touchpad is known to report positions in excess of this
|
||||
* value which are actually negative values truncated to the 13-bit
|
||||
* reporting range. These values have never been observed to be lower
|
||||
* than 8184 (i.e. -8), so we treat all values greater than 8176 as
|
||||
* negative and any other value as positive.
|
||||
*/
|
||||
#define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2)
|
||||
#define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2)
|
||||
#define X_MAX_POSITIVE 8176
|
||||
#define Y_MAX_POSITIVE 8176
|
||||
|
||||
/*****************************************************************************
|
||||
* Stuff we need even when we do not want native Synaptics support
|
||||
@@ -604,11 +609,21 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
|
||||
hw->right = (buf[0] & 0x02) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Convert wrap-around values to negative */
|
||||
/*
|
||||
* Convert wrap-around values to negative. (X|Y)_MAX_POSITIVE
|
||||
* is used by some firmware to indicate a finger at the edge of
|
||||
* the touchpad whose precise position cannot be determined, so
|
||||
* convert these values to the maximum axis value.
|
||||
*/
|
||||
if (hw->x > X_MAX_POSITIVE)
|
||||
hw->x -= 1 << ABS_POS_BITS;
|
||||
else if (hw->x == X_MAX_POSITIVE)
|
||||
hw->x = XMAX;
|
||||
|
||||
if (hw->y > Y_MAX_POSITIVE)
|
||||
hw->y -= 1 << ABS_POS_BITS;
|
||||
else if (hw->y == Y_MAX_POSITIVE)
|
||||
hw->y = YMAX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -975,7 +975,7 @@ static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai,
|
||||
return err;
|
||||
goto adjust_mean_ec;
|
||||
case UBI_IO_FF:
|
||||
if (ec_err)
|
||||
if (ec_err || bitflips)
|
||||
err = add_to_list(ai, pnum, UBI_UNKNOWN,
|
||||
UBI_UNKNOWN, ec, 1, &ai->erase);
|
||||
else
|
||||
|
||||
@@ -759,6 +759,11 @@ static int autoresize(struct ubi_device *ubi, int vol_id)
|
||||
struct ubi_volume *vol = ubi->volumes[vol_id];
|
||||
int err, old_reserved_pebs = vol->reserved_pebs;
|
||||
|
||||
if (ubi->ro_mode) {
|
||||
ubi_warn("skip auto-resize because of R/O mode");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the auto-resize flag in the volume in-memory copy of the
|
||||
* volume table, and 'ubi_resize_volume()' will propagate this change
|
||||
|
||||
@@ -181,7 +181,7 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
|
||||
|
||||
if (!clock_name || !strcmp(clock_name, "sys")) {
|
||||
sys_clk = clk_get(&ofdev->dev, "sys_clk");
|
||||
if (!sys_clk) {
|
||||
if (IS_ERR(sys_clk)) {
|
||||
dev_err(&ofdev->dev, "couldn't get sys_clk\n");
|
||||
goto exit_unmap;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev,
|
||||
|
||||
if (clocksrc < 0) {
|
||||
ref_clk = clk_get(&ofdev->dev, "ref_clk");
|
||||
if (!ref_clk) {
|
||||
if (IS_ERR(ref_clk)) {
|
||||
dev_err(&ofdev->dev, "couldn't get ref_clk\n");
|
||||
goto exit_unmap;
|
||||
}
|
||||
|
||||
@@ -127,8 +127,9 @@ static void ath_pci_aspm_init(struct ath_common *common)
|
||||
if (!parent)
|
||||
return;
|
||||
|
||||
if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) {
|
||||
/* Bluetooth coexistance requires disabling ASPM. */
|
||||
if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) &&
|
||||
(AR_SREV_9285(ah))) {
|
||||
/* Bluetooth coexistance requires disabling ASPM for AR9285. */
|
||||
pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm);
|
||||
aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1);
|
||||
pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm);
|
||||
|
||||
@@ -3894,6 +3894,8 @@ static void b43legacy_remove(struct ssb_device *dev)
|
||||
cancel_work_sync(&wl->firmware_load);
|
||||
|
||||
B43legacy_WARN_ON(!wl);
|
||||
if (!wldev->fw.ucode)
|
||||
return; /* NULL if fw never loaded */
|
||||
if (wl->current_dev == wldev)
|
||||
ieee80211_unregister_hw(wl->hw);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ config REMOTEPROC
|
||||
tristate
|
||||
depends on EXPERIMENTAL
|
||||
select FW_CONFIG
|
||||
select VIRTIO
|
||||
|
||||
config OMAP_REMOTEPROC
|
||||
tristate "OMAP remoteproc support"
|
||||
|
||||
@@ -545,17 +545,10 @@ static int rproc_handle_carveout(struct rproc *rproc,
|
||||
dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
|
||||
rsc->da, rsc->pa, rsc->len, rsc->flags);
|
||||
|
||||
mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
|
||||
if (!mapping) {
|
||||
dev_err(dev, "kzalloc mapping failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
|
||||
if (!carveout) {
|
||||
dev_err(dev, "kzalloc carveout failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto free_mapping;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
|
||||
@@ -585,11 +578,18 @@ static int rproc_handle_carveout(struct rproc *rproc,
|
||||
* physical address in this case.
|
||||
*/
|
||||
if (rproc->domain) {
|
||||
mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
|
||||
if (!mapping) {
|
||||
dev_err(dev, "kzalloc mapping failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto dma_free;
|
||||
}
|
||||
|
||||
ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
|
||||
rsc->flags);
|
||||
if (ret) {
|
||||
dev_err(dev, "iommu_map failed: %d\n", ret);
|
||||
goto dma_free;
|
||||
goto free_mapping;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -634,12 +634,12 @@ static int rproc_handle_carveout(struct rproc *rproc,
|
||||
|
||||
return 0;
|
||||
|
||||
free_mapping:
|
||||
kfree(mapping);
|
||||
dma_free:
|
||||
dma_free_coherent(dev->parent, rsc->len, va, dma);
|
||||
free_carv:
|
||||
kfree(carveout);
|
||||
free_mapping:
|
||||
kfree(mapping);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -641,8 +641,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
|
||||
h->state = TPGS_STATE_STANDBY;
|
||||
break;
|
||||
case TPGS_STATE_OFFLINE:
|
||||
case TPGS_STATE_UNAVAILABLE:
|
||||
/* Path unusable for unavailable/offline */
|
||||
/* Path unusable */
|
||||
err = SCSI_DH_DEV_OFFLINED;
|
||||
break;
|
||||
default:
|
||||
|
||||
+1
-1
@@ -3266,7 +3266,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h,
|
||||
c->Request.Timeout = 0; /* Don't time out */
|
||||
memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
|
||||
c->Request.CDB[0] = cmd;
|
||||
c->Request.CDB[1] = 0x03; /* Reset target above */
|
||||
c->Request.CDB[1] = HPSA_RESET_TYPE_LUN;
|
||||
/* If bytes 4-7 are zero, it means reset the */
|
||||
/* LunID device */
|
||||
c->Request.CDB[4] = 0x00;
|
||||
|
||||
@@ -1541,6 +1541,9 @@ static int ibmvscsi_do_host_config(struct ibmvscsi_host_data *hostdata,
|
||||
|
||||
host_config = &evt_struct->iu.mad.host_config;
|
||||
|
||||
/* The transport length field is only 16-bit */
|
||||
length = min(0xffff, length);
|
||||
|
||||
/* Set up a lun reset SRP command */
|
||||
memset(host_config, 0x00, sizeof(*host_config));
|
||||
host_config->common.type = VIOSRP_HOST_CONFIG_TYPE;
|
||||
|
||||
@@ -644,7 +644,6 @@ static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_devic
|
||||
orom->hdr.version)) {
|
||||
dev_warn(&pdev->dev,
|
||||
"[%d]: invalid oem parameters detected, falling back to firmware\n", i);
|
||||
devm_kfree(&pdev->dev, orom);
|
||||
orom = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -104,7 +104,6 @@ struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
|
||||
|
||||
if (i >= len) {
|
||||
dev_err(&pdev->dev, "oprom parse error\n");
|
||||
devm_kfree(&pdev->dev, rom);
|
||||
rom = NULL;
|
||||
}
|
||||
pci_unmap_biosrom(oprom);
|
||||
|
||||
+14
-16
@@ -1031,33 +1031,31 @@ static void __scsi_remove_target(struct scsi_target *starget)
|
||||
void scsi_remove_target(struct device *dev)
|
||||
{
|
||||
struct Scsi_Host *shost = dev_to_shost(dev->parent);
|
||||
struct scsi_target *starget, *found;
|
||||
struct scsi_target *starget, *last = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
restart:
|
||||
found = NULL;
|
||||
/* remove targets being careful to lookup next entry before
|
||||
* deleting the last
|
||||
*/
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
list_for_each_entry(starget, &shost->__targets, siblings) {
|
||||
if (starget->state == STARGET_DEL)
|
||||
continue;
|
||||
if (starget->dev.parent == dev || &starget->dev == dev) {
|
||||
found = starget;
|
||||
found->reap_ref++;
|
||||
break;
|
||||
/* assuming new targets arrive at the end */
|
||||
starget->reap_ref++;
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
if (last)
|
||||
scsi_target_reap(last);
|
||||
last = starget;
|
||||
__scsi_remove_target(starget);
|
||||
spin_lock_irqsave(shost->host_lock, flags);
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
|
||||
if (found) {
|
||||
__scsi_remove_target(found);
|
||||
scsi_target_reap(found);
|
||||
/* in the case where @dev has multiple starget children,
|
||||
* continue removing.
|
||||
*
|
||||
* FIXME: does such a case exist?
|
||||
*/
|
||||
goto restart;
|
||||
}
|
||||
if (last)
|
||||
scsi_target_reap(last);
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_remove_target);
|
||||
|
||||
|
||||
@@ -951,7 +951,7 @@ static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn,
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
ret = s->async->inttrig(dev, s, insn->data[0]);
|
||||
ret = s->async->inttrig(dev, s, data[0]);
|
||||
if (ret >= 0)
|
||||
ret = 1;
|
||||
break;
|
||||
@@ -1196,7 +1196,6 @@ static int do_cmd_ioctl(struct comedi_device *dev,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
kfree(async->cmd.chanlist);
|
||||
async->cmd = user_cmd;
|
||||
async->cmd.data = NULL;
|
||||
/* load channel/gain list */
|
||||
@@ -2033,6 +2032,8 @@ void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
|
||||
if (async) {
|
||||
comedi_reset_async_buf(async);
|
||||
async->inttrig = NULL;
|
||||
kfree(async->cmd.chanlist);
|
||||
async->cmd.chanlist = NULL;
|
||||
} else {
|
||||
printk(KERN_ERR
|
||||
"BUG: (?) do_become_nonbusy called with async=0\n");
|
||||
|
||||
@@ -884,7 +884,7 @@ static int jr3_pci_attach(struct comedi_device *dev,
|
||||
}
|
||||
|
||||
/* Reset DSP card */
|
||||
devpriv->iobase->channel[0].reset = 0;
|
||||
writel(0, &devpriv->iobase->channel[0].reset);
|
||||
|
||||
result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware);
|
||||
dev_dbg(dev->class_dev, "Firmare load %d\n", result);
|
||||
|
||||
@@ -1868,7 +1868,7 @@ static int s626_enc_insn_config(struct comedi_device *dev,
|
||||
/* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
|
||||
|
||||
k->SetMode(dev, k, Setup, TRUE);
|
||||
Preload(dev, k, *(insn->data));
|
||||
Preload(dev, k, data[0]);
|
||||
k->PulseIndex(dev, k);
|
||||
SetLatchSource(dev, k, valueSrclatch);
|
||||
k->SetEnable(dev, k, (uint16_t) (enab != 0));
|
||||
|
||||
@@ -1127,6 +1127,9 @@ static void recv_tasklet(void *priv)
|
||||
recvbuf2recvframe(padapter, pskb);
|
||||
skb_reset_tail_pointer(pskb);
|
||||
pskb->len = 0;
|
||||
skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
|
||||
if (!skb_cloned(pskb))
|
||||
skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
|
||||
else
|
||||
consume_skb(pskb);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ static int softsynth_is_alive(struct spk_synth *synth);
|
||||
static unsigned char get_index(void);
|
||||
|
||||
static struct miscdevice synth_device;
|
||||
static int initialized;
|
||||
static int init_pos;
|
||||
static int misc_registered;
|
||||
|
||||
static struct var_t vars[] = {
|
||||
@@ -194,7 +194,7 @@ static int softsynth_close(struct inode *inode, struct file *fp)
|
||||
unsigned long flags;
|
||||
spk_lock(flags);
|
||||
synth_soft.alive = 0;
|
||||
initialized = 0;
|
||||
init_pos = 0;
|
||||
spk_unlock(flags);
|
||||
/* Make sure we let applications go before leaving */
|
||||
speakup_start_ttys();
|
||||
@@ -239,13 +239,8 @@ static ssize_t softsynth_read(struct file *fp, char *buf, size_t count,
|
||||
ch = '\x18';
|
||||
} else if (synth_buffer_empty()) {
|
||||
break;
|
||||
} else if (!initialized) {
|
||||
if (*init) {
|
||||
ch = *init;
|
||||
init++;
|
||||
} else {
|
||||
initialized = 1;
|
||||
}
|
||||
} else if (init[init_pos]) {
|
||||
ch = init[init_pos++];
|
||||
} else {
|
||||
ch = synth_buffer_getc();
|
||||
}
|
||||
|
||||
+20
-6
@@ -875,7 +875,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
|
||||
|
||||
/* dlci->skb is locked by tx_lock */
|
||||
if (dlci->skb == NULL) {
|
||||
dlci->skb = skb_dequeue(&dlci->skb_list);
|
||||
dlci->skb = skb_dequeue_tail(&dlci->skb_list);
|
||||
if (dlci->skb == NULL)
|
||||
return 0;
|
||||
first = 1;
|
||||
@@ -899,8 +899,11 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm,
|
||||
|
||||
/* FIXME: need a timer or something to kick this so it can't
|
||||
get stuck with no work outstanding and no buffer free */
|
||||
if (msg == NULL)
|
||||
if (msg == NULL) {
|
||||
skb_queue_tail(&dlci->skb_list, dlci->skb);
|
||||
dlci->skb = NULL;
|
||||
return -ENOMEM;
|
||||
}
|
||||
dp = msg->data;
|
||||
|
||||
if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */
|
||||
@@ -971,16 +974,19 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm)
|
||||
static void gsm_dlci_data_kick(struct gsm_dlci *dlci)
|
||||
{
|
||||
unsigned long flags;
|
||||
int sweep;
|
||||
|
||||
spin_lock_irqsave(&dlci->gsm->tx_lock, flags);
|
||||
/* If we have nothing running then we need to fire up */
|
||||
sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO);
|
||||
if (dlci->gsm->tx_bytes == 0) {
|
||||
if (dlci->net)
|
||||
gsm_dlci_data_output_framed(dlci->gsm, dlci);
|
||||
else
|
||||
gsm_dlci_data_output(dlci->gsm, dlci);
|
||||
} else if (dlci->gsm->tx_bytes < TX_THRESH_LO)
|
||||
gsm_dlci_data_sweep(dlci->gsm);
|
||||
}
|
||||
if (sweep)
|
||||
gsm_dlci_data_sweep(dlci->gsm);
|
||||
spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags);
|
||||
}
|
||||
|
||||
@@ -1190,6 +1196,8 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
|
||||
u8 *data, int clen)
|
||||
{
|
||||
u8 buf[1];
|
||||
unsigned long flags;
|
||||
|
||||
switch (command) {
|
||||
case CMD_CLD: {
|
||||
struct gsm_dlci *dlci = gsm->dlci[0];
|
||||
@@ -1215,7 +1223,9 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command,
|
||||
gsm->constipated = 0;
|
||||
gsm_control_reply(gsm, CMD_FCOFF, NULL, 0);
|
||||
/* Kick the link in case it is idling */
|
||||
spin_lock_irqsave(&gsm->tx_lock, flags);
|
||||
gsm_data_kick(gsm);
|
||||
spin_unlock_irqrestore(&gsm->tx_lock, flags);
|
||||
break;
|
||||
case CMD_MSC:
|
||||
/* Out of band modem line change indicator for a DLCI */
|
||||
@@ -2377,12 +2387,12 @@ static void gsmld_write_wakeup(struct tty_struct *tty)
|
||||
|
||||
/* Queue poll */
|
||||
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
|
||||
spin_lock_irqsave(&gsm->tx_lock, flags);
|
||||
gsm_data_kick(gsm);
|
||||
if (gsm->tx_bytes < TX_THRESH_LO) {
|
||||
spin_lock_irqsave(&gsm->tx_lock, flags);
|
||||
gsm_dlci_data_sweep(gsm);
|
||||
spin_unlock_irqrestore(&gsm->tx_lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&gsm->tx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2889,6 +2899,10 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
|
||||
gsm = gsm_mux[mux];
|
||||
if (gsm->dead)
|
||||
return -EL2HLT;
|
||||
/* If DLCI 0 is not yet fully open return an error. This is ok from a locking
|
||||
perspective as we don't have to worry about this if DLCI0 is lost */
|
||||
if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN)
|
||||
return -EL2NSYNC;
|
||||
dlci = gsm->dlci[line];
|
||||
if (dlci == NULL)
|
||||
dlci = gsm_dlci_alloc(gsm, line);
|
||||
|
||||
+2
-1
@@ -1728,7 +1728,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
|
||||
|
||||
do_it_again:
|
||||
|
||||
BUG_ON(!tty->read_buf);
|
||||
if (WARN_ON(!tty->read_buf))
|
||||
return -EAGAIN;
|
||||
|
||||
c = job_control(tty, file);
|
||||
if (c < 0)
|
||||
|
||||
@@ -1164,6 +1164,8 @@ pci_xr17c154_setup(struct serial_private *priv,
|
||||
#define PCI_SUBDEVICE_ID_OCTPRO422 0x0208
|
||||
#define PCI_SUBDEVICE_ID_POCTAL232 0x0308
|
||||
#define PCI_SUBDEVICE_ID_POCTAL422 0x0408
|
||||
#define PCI_SUBDEVICE_ID_SIIG_DUAL_00 0x2500
|
||||
#define PCI_SUBDEVICE_ID_SIIG_DUAL_30 0x2530
|
||||
#define PCI_VENDOR_ID_ADVANTECH 0x13fe
|
||||
#define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
|
||||
#define PCI_DEVICE_ID_ADVANTECH_PCI3620 0x3620
|
||||
@@ -3232,8 +3234,11 @@ static struct pci_device_id serial_pci_tbl[] = {
|
||||
* For now just used the hex ID 0x950a.
|
||||
*/
|
||||
{ PCI_VENDOR_ID_OXSEMI, 0x950a,
|
||||
PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL, 0, 0,
|
||||
pbn_b0_2_115200 },
|
||||
PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_00,
|
||||
0, 0, pbn_b0_2_115200 },
|
||||
{ PCI_VENDOR_ID_OXSEMI, 0x950a,
|
||||
PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_DUAL_30,
|
||||
0, 0, pbn_b0_2_115200 },
|
||||
{ PCI_VENDOR_ID_OXSEMI, 0x950a,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
pbn_b0_2_1130000 },
|
||||
|
||||
@@ -1603,13 +1603,26 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios,
|
||||
old_cr &= ~ST_UART011_CR_OVSFACT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Workaround for the ST Micro oversampling variants to
|
||||
* increase the bitrate slightly, by lowering the divisor,
|
||||
* to avoid delayed sampling of start bit at high speeds,
|
||||
* else we see data corruption.
|
||||
*/
|
||||
if (uap->vendor->oversampling) {
|
||||
if ((baud >= 3000000) && (baud < 3250000) && (quot > 1))
|
||||
quot -= 1;
|
||||
else if ((baud > 3250000) && (quot > 2))
|
||||
quot -= 2;
|
||||
}
|
||||
/* Set baud rate */
|
||||
writew(quot & 0x3f, port->membase + UART011_FBRD);
|
||||
writew(quot >> 6, port->membase + UART011_IBRD);
|
||||
|
||||
/*
|
||||
* ----------v----------v----------v----------v-----
|
||||
* NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
|
||||
* NOTE: lcrh_tx and lcrh_rx MUST BE WRITTEN AFTER
|
||||
* UART011_FBRD & UART011_IBRD.
|
||||
* ----------^----------^----------^----------^-----
|
||||
*/
|
||||
writew(lcr_h, port->membase + uap->lcrh_rx);
|
||||
|
||||
@@ -667,19 +667,19 @@ serial_omap_configure_xonxoff
|
||||
|
||||
/*
|
||||
* IXON Flag:
|
||||
* Enable XON/XOFF flow control on output.
|
||||
* Transmit XON1, XOFF1
|
||||
* Flow control for OMAP.TX
|
||||
* OMAP.RX should listen for XON/XOFF
|
||||
*/
|
||||
if (termios->c_iflag & IXON)
|
||||
up->efr |= OMAP_UART_SW_TX;
|
||||
up->efr |= OMAP_UART_SW_RX;
|
||||
|
||||
/*
|
||||
* IXOFF Flag:
|
||||
* Enable XON/XOFF flow control on input.
|
||||
* Receiver compares XON1, XOFF1.
|
||||
* Flow control for OMAP.RX
|
||||
* OMAP.TX should send XON/XOFF
|
||||
*/
|
||||
if (termios->c_iflag & IXOFF)
|
||||
up->efr |= OMAP_UART_SW_RX;
|
||||
up->efr |= OMAP_UART_SW_TX;
|
||||
|
||||
serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
|
||||
serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
|
||||
|
||||
@@ -1049,13 +1049,10 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data)
|
||||
*/
|
||||
int vt_get_leds(int console, int flag)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct kbd_struct * kbd = kbd_table + console;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&kbd_event_lock, flags);
|
||||
ret = vc_kbd_led(kbd, flag);
|
||||
spin_unlock_irqrestore(&kbd_event_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -141,18 +141,14 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR);
|
||||
* descriptors are built on demand.
|
||||
*/
|
||||
|
||||
#define STRING_MANUFACTURER 1
|
||||
#define STRING_PRODUCT 2
|
||||
#define STRING_SERIALNUM 3
|
||||
#define STRING_MANUFACTURER 0
|
||||
#define STRING_PRODUCT 1
|
||||
#define STRING_SERIALNUM 2
|
||||
|
||||
/* holds our biggest descriptor */
|
||||
#define USB_DESC_BUFSIZE 256
|
||||
#define USB_BUFSIZE 8192
|
||||
|
||||
/* This device advertises one configuration. */
|
||||
#define DEV_CONFIG_VALUE 1
|
||||
#define PRINTER_INTERFACE 0
|
||||
|
||||
static struct usb_device_descriptor device_desc = {
|
||||
.bLength = sizeof device_desc,
|
||||
.bDescriptorType = USB_DT_DEVICE,
|
||||
@@ -162,16 +158,12 @@ static struct usb_device_descriptor device_desc = {
|
||||
.bDeviceProtocol = 0,
|
||||
.idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
|
||||
.idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
|
||||
.iManufacturer = STRING_MANUFACTURER,
|
||||
.iProduct = STRING_PRODUCT,
|
||||
.iSerialNumber = STRING_SERIALNUM,
|
||||
.bNumConfigurations = 1
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor intf_desc = {
|
||||
.bLength = sizeof intf_desc,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
.bInterfaceNumber = PRINTER_INTERFACE,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_PRINTER,
|
||||
.bInterfaceSubClass = 1, /* Printer Sub-Class */
|
||||
@@ -260,9 +252,9 @@ static char pnp_string [1024] =
|
||||
|
||||
/* static strings, in UTF-8 */
|
||||
static struct usb_string strings [] = {
|
||||
{ STRING_MANUFACTURER, manufacturer, },
|
||||
{ STRING_PRODUCT, product_desc, },
|
||||
{ STRING_SERIALNUM, serial_num, },
|
||||
[STRING_MANUFACTURER].s = manufacturer,
|
||||
[STRING_PRODUCT].s = product_desc,
|
||||
[STRING_SERIALNUM].s = serial_num,
|
||||
{ } /* end of list */
|
||||
};
|
||||
|
||||
@@ -871,25 +863,13 @@ static int set_interface(struct printer_dev *dev, unsigned number)
|
||||
int result = 0;
|
||||
|
||||
/* Free the current interface */
|
||||
switch (dev->interface) {
|
||||
case PRINTER_INTERFACE:
|
||||
printer_reset_interface(dev);
|
||||
break;
|
||||
}
|
||||
printer_reset_interface(dev);
|
||||
|
||||
switch (number) {
|
||||
case PRINTER_INTERFACE:
|
||||
result = set_printer_interface(dev);
|
||||
if (result) {
|
||||
printer_reset_interface(dev);
|
||||
} else {
|
||||
dev->interface = PRINTER_INTERFACE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = -EINVAL;
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
result = set_printer_interface(dev);
|
||||
if (result)
|
||||
printer_reset_interface(dev);
|
||||
else
|
||||
dev->interface = number;
|
||||
|
||||
if (!result)
|
||||
INFO(dev, "Using interface %x\n", number);
|
||||
@@ -972,7 +952,7 @@ static int printer_func_setup(struct usb_function *f,
|
||||
switch (ctrl->bRequest) {
|
||||
case 0: /* Get the IEEE-1284 PNP String */
|
||||
/* Only one printer interface is supported. */
|
||||
if ((wIndex>>8) != PRINTER_INTERFACE)
|
||||
if ((wIndex>>8) != dev->interface)
|
||||
break;
|
||||
|
||||
value = (pnp_string[0]<<8)|pnp_string[1];
|
||||
@@ -983,7 +963,7 @@ static int printer_func_setup(struct usb_function *f,
|
||||
|
||||
case 1: /* Get Port Status */
|
||||
/* Only one printer interface is supported. */
|
||||
if (wIndex != PRINTER_INTERFACE)
|
||||
if (wIndex != dev->interface)
|
||||
break;
|
||||
|
||||
*(u8 *)req->buf = dev->printer_status;
|
||||
@@ -992,7 +972,7 @@ static int printer_func_setup(struct usb_function *f,
|
||||
|
||||
case 2: /* Soft Reset */
|
||||
/* Only one printer interface is supported. */
|
||||
if (wIndex != PRINTER_INTERFACE)
|
||||
if (wIndex != dev->interface)
|
||||
break;
|
||||
|
||||
printer_soft_reset(dev);
|
||||
@@ -1020,6 +1000,37 @@ unknown:
|
||||
static int __init printer_func_bind(struct usb_configuration *c,
|
||||
struct usb_function *f)
|
||||
{
|
||||
struct printer_dev *dev = container_of(f, struct printer_dev, function);
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct usb_ep *in_ep, *out_ep;
|
||||
int id;
|
||||
|
||||
id = usb_interface_id(c, f);
|
||||
if (id < 0)
|
||||
return id;
|
||||
intf_desc.bInterfaceNumber = id;
|
||||
|
||||
/* all we really need is bulk IN/OUT */
|
||||
in_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_in_desc);
|
||||
if (!in_ep) {
|
||||
autoconf_fail:
|
||||
dev_err(&cdev->gadget->dev, "can't autoconfigure on %s\n",
|
||||
cdev->gadget->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
in_ep->driver_data = in_ep; /* claim */
|
||||
|
||||
out_ep = usb_ep_autoconfig(cdev->gadget, &fs_ep_out_desc);
|
||||
if (!out_ep)
|
||||
goto autoconf_fail;
|
||||
out_ep->driver_data = out_ep; /* claim */
|
||||
|
||||
/* assumes that all endpoints are dual-speed */
|
||||
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
|
||||
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
|
||||
|
||||
dev->in_ep = in_ep;
|
||||
dev->out_ep = out_ep;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1035,7 +1046,8 @@ static int printer_func_set_alt(struct usb_function *f,
|
||||
int ret = -ENOTSUPP;
|
||||
|
||||
if (!alt)
|
||||
ret = set_interface(dev, PRINTER_INTERFACE);
|
||||
ret = set_interface(dev, intf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1107,13 +1119,14 @@ static int __init printer_bind_config(struct usb_configuration *c)
|
||||
{
|
||||
struct usb_gadget *gadget = c->cdev->gadget;
|
||||
struct printer_dev *dev;
|
||||
struct usb_ep *in_ep, *out_ep;
|
||||
int status = -ENOMEM;
|
||||
int gcnum;
|
||||
size_t len;
|
||||
u32 i;
|
||||
struct usb_request *req;
|
||||
|
||||
usb_ep_autoconfig_reset(gadget);
|
||||
|
||||
dev = &usb_printer_gadget;
|
||||
|
||||
dev->function.name = shortname;
|
||||
@@ -1125,6 +1138,10 @@ static int __init printer_bind_config(struct usb_configuration *c)
|
||||
dev->function.set_alt = printer_func_set_alt;
|
||||
dev->function.disable = printer_func_disable;
|
||||
|
||||
status = usb_add_function(c, &dev->function);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Setup the sysfs files for the printer gadget. */
|
||||
dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
|
||||
NULL, "g_printer");
|
||||
@@ -1169,26 +1186,6 @@ static int __init printer_bind_config(struct usb_configuration *c)
|
||||
pnp_string[0] = (len >> 8) & 0xFF;
|
||||
pnp_string[1] = len & 0xFF;
|
||||
|
||||
/* all we really need is bulk IN/OUT */
|
||||
usb_ep_autoconfig_reset(gadget);
|
||||
in_ep = usb_ep_autoconfig(gadget, &fs_ep_in_desc);
|
||||
if (!in_ep) {
|
||||
autoconf_fail:
|
||||
dev_err(&gadget->dev, "can't autoconfigure on %s\n",
|
||||
gadget->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
in_ep->driver_data = in_ep; /* claim */
|
||||
|
||||
out_ep = usb_ep_autoconfig(gadget, &fs_ep_out_desc);
|
||||
if (!out_ep)
|
||||
goto autoconf_fail;
|
||||
out_ep->driver_data = out_ep; /* claim */
|
||||
|
||||
/* assumes that all endpoints are dual-speed */
|
||||
hs_ep_in_desc.bEndpointAddress = fs_ep_in_desc.bEndpointAddress;
|
||||
hs_ep_out_desc.bEndpointAddress = fs_ep_out_desc.bEndpointAddress;
|
||||
|
||||
usb_gadget_set_selfpowered(gadget);
|
||||
|
||||
if (gadget->is_otg) {
|
||||
@@ -1215,9 +1212,6 @@ autoconf_fail:
|
||||
dev->current_rx_bytes = 0;
|
||||
dev->current_rx_buf = NULL;
|
||||
|
||||
dev->in_ep = in_ep;
|
||||
dev->out_ep = out_ep;
|
||||
|
||||
for (i = 0; i < QLEN; i++) {
|
||||
req = printer_req_alloc(dev->in_ep, USB_BUFSIZE, GFP_KERNEL);
|
||||
if (!req) {
|
||||
@@ -1250,8 +1244,6 @@ autoconf_fail:
|
||||
dev->gadget = gadget;
|
||||
|
||||
INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
|
||||
INFO(dev, "using %s, OUT %s IN %s\n", gadget->name, out_ep->name,
|
||||
in_ep->name);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
@@ -1266,7 +1258,17 @@ static int printer_unbind(struct usb_composite_dev *cdev)
|
||||
|
||||
static int __init printer_bind(struct usb_composite_dev *cdev)
|
||||
{
|
||||
return usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
|
||||
int ret;
|
||||
|
||||
ret = usb_string_ids_tab(cdev, strings);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
device_desc.iManufacturer = strings[STRING_MANUFACTURER].id;
|
||||
device_desc.iProduct = strings[STRING_PRODUCT].id;
|
||||
device_desc.iSerialNumber = strings[STRING_SERIALNUM].id;
|
||||
|
||||
ret = usb_add_config(cdev, &printer_cfg_driver, printer_bind_config);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct usb_composite_driver printer_driver = {
|
||||
|
||||
@@ -1977,7 +1977,6 @@ static struct usb_interface_descriptor bot_intf_desc = {
|
||||
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
|
||||
.bInterfaceSubClass = USB_SC_SCSI,
|
||||
.bInterfaceProtocol = USB_PR_BULK,
|
||||
.iInterface = USB_G_STR_INT_UAS,
|
||||
};
|
||||
|
||||
static struct usb_interface_descriptor uasp_intf_desc = {
|
||||
@@ -1988,7 +1987,6 @@ static struct usb_interface_descriptor uasp_intf_desc = {
|
||||
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
|
||||
.bInterfaceSubClass = USB_SC_SCSI,
|
||||
.bInterfaceProtocol = USB_PR_UAS,
|
||||
.iInterface = USB_G_STR_INT_BBB,
|
||||
};
|
||||
|
||||
static struct usb_endpoint_descriptor uasp_bi_desc = {
|
||||
@@ -2209,20 +2207,16 @@ static struct usb_device_descriptor usbg_device_desc = {
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
.idVendor = cpu_to_le16(UAS_VENDOR_ID),
|
||||
.idProduct = cpu_to_le16(UAS_PRODUCT_ID),
|
||||
.iManufacturer = USB_G_STR_MANUFACTOR,
|
||||
.iProduct = USB_G_STR_PRODUCT,
|
||||
.iSerialNumber = USB_G_STR_SERIAL,
|
||||
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
static struct usb_string usbg_us_strings[] = {
|
||||
{ USB_G_STR_MANUFACTOR, "Target Manufactor"},
|
||||
{ USB_G_STR_PRODUCT, "Target Product"},
|
||||
{ USB_G_STR_SERIAL, "000000000001"},
|
||||
{ USB_G_STR_CONFIG, "default config"},
|
||||
{ USB_G_STR_INT_UAS, "USB Attached SCSI"},
|
||||
{ USB_G_STR_INT_BBB, "Bulk Only Transport"},
|
||||
[USB_G_STR_MANUFACTOR].s = "Target Manufactor",
|
||||
[USB_G_STR_PRODUCT].s = "Target Product",
|
||||
[USB_G_STR_SERIAL].s = "000000000001",
|
||||
[USB_G_STR_CONFIG].s = "default config",
|
||||
[USB_G_STR_INT_UAS].s = "USB Attached SCSI",
|
||||
[USB_G_STR_INT_BBB].s = "Bulk Only Transport",
|
||||
{ },
|
||||
};
|
||||
|
||||
@@ -2244,7 +2238,6 @@ static int guas_unbind(struct usb_composite_dev *cdev)
|
||||
static struct usb_configuration usbg_config_driver = {
|
||||
.label = "Linux Target",
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = USB_G_STR_CONFIG,
|
||||
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
|
||||
};
|
||||
|
||||
@@ -2417,6 +2410,9 @@ static int usbg_cfg_bind(struct usb_configuration *c)
|
||||
fu->function.disable = usbg_disable;
|
||||
fu->tpg = the_only_tpg_I_currently_have;
|
||||
|
||||
bot_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_BBB].id;
|
||||
uasp_intf_desc.iInterface = usbg_us_strings[USB_G_STR_INT_UAS].id;
|
||||
|
||||
ret = usb_add_function(c, &fu->function);
|
||||
if (ret)
|
||||
goto err;
|
||||
@@ -2431,6 +2427,17 @@ static int usb_target_bind(struct usb_composite_dev *cdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = usb_string_ids_tab(cdev, usbg_us_strings);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
usbg_device_desc.iManufacturer =
|
||||
usbg_us_strings[USB_G_STR_MANUFACTOR].id;
|
||||
usbg_device_desc.iProduct = usbg_us_strings[USB_G_STR_PRODUCT].id;
|
||||
usbg_device_desc.iSerialNumber = usbg_us_strings[USB_G_STR_SERIAL].id;
|
||||
usbg_config_driver.iConfiguration =
|
||||
usbg_us_strings[USB_G_STR_CONFIG].id;
|
||||
|
||||
ret = usb_add_config(cdev, &usbg_config_driver,
|
||||
usbg_cfg_bind);
|
||||
return 0;
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
#define UASP_SS_EP_COMP_LOG_STREAMS 4
|
||||
#define UASP_SS_EP_COMP_NUM_STREAMS (1 << UASP_SS_EP_COMP_LOG_STREAMS)
|
||||
|
||||
#define USB_G_STR_MANUFACTOR 1
|
||||
#define USB_G_STR_PRODUCT 2
|
||||
#define USB_G_STR_SERIAL 3
|
||||
#define USB_G_STR_CONFIG 4
|
||||
#define USB_G_STR_INT_UAS 5
|
||||
#define USB_G_STR_INT_BBB 6
|
||||
enum {
|
||||
USB_G_STR_MANUFACTOR,
|
||||
USB_G_STR_PRODUCT,
|
||||
USB_G_STR_SERIAL,
|
||||
USB_G_STR_CONFIG,
|
||||
USB_G_STR_INT_UAS,
|
||||
USB_G_STR_INT_BBB,
|
||||
};
|
||||
|
||||
#define USB_G_ALT_INT_BBB 0
|
||||
#define USB_G_ALT_INT_UAS 1
|
||||
|
||||
@@ -118,7 +118,8 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
|
||||
return;
|
||||
}
|
||||
ehci_warn(ehci, "Waited too long for the async schedule status, giving up\n");
|
||||
ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
|
||||
want, actual);
|
||||
}
|
||||
ehci->ASS_poll_count = 0;
|
||||
|
||||
@@ -163,7 +164,8 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
|
||||
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
|
||||
return;
|
||||
}
|
||||
ehci_warn(ehci, "Waited too long for the periodic schedule status, giving up\n");
|
||||
ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
|
||||
want, actual);
|
||||
}
|
||||
ehci->PSS_poll_count = 0;
|
||||
|
||||
|
||||
@@ -1772,6 +1772,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
|
||||
struct dev_info *dev_info, *next;
|
||||
struct xhci_cd *cur_cd, *next_cd;
|
||||
unsigned long flags;
|
||||
int size;
|
||||
int i, j, num_ports;
|
||||
@@ -1795,6 +1796,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
|
||||
xhci_ring_free(xhci, xhci->cmd_ring);
|
||||
xhci->cmd_ring = NULL;
|
||||
xhci_dbg(xhci, "Freed command ring\n");
|
||||
list_for_each_entry_safe(cur_cd, next_cd,
|
||||
&xhci->cancel_cmd_list, cancel_cmd_list) {
|
||||
list_del(&cur_cd->cancel_cmd_list);
|
||||
kfree(cur_cd);
|
||||
}
|
||||
|
||||
for (i = 1; i < MAX_HC_SLOTS; ++i)
|
||||
xhci_free_virt_device(xhci, i);
|
||||
@@ -2340,6 +2346,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
|
||||
xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
|
||||
if (!xhci->cmd_ring)
|
||||
goto fail;
|
||||
INIT_LIST_HEAD(&xhci->cancel_cmd_list);
|
||||
xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
|
||||
xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
|
||||
(unsigned long long)xhci->cmd_ring->first_seg->dma);
|
||||
|
||||
@@ -103,6 +103,7 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
|
||||
* PPT chipsets.
|
||||
*/
|
||||
xhci->quirks |= XHCI_SPURIOUS_REBOOT;
|
||||
xhci->quirks |= XHCI_AVOID_BEI;
|
||||
}
|
||||
if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
|
||||
pdev->device == PCI_DEVICE_ID_ASROCK_P67) {
|
||||
|
||||
@@ -280,12 +280,123 @@ static inline int room_on_ring(struct xhci_hcd *xhci, struct xhci_ring *ring,
|
||||
/* Ring the host controller doorbell after placing a command on the ring */
|
||||
void xhci_ring_cmd_db(struct xhci_hcd *xhci)
|
||||
{
|
||||
if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING))
|
||||
return;
|
||||
|
||||
xhci_dbg(xhci, "// Ding dong!\n");
|
||||
xhci_writel(xhci, DB_VALUE_HOST, &xhci->dba->doorbell[0]);
|
||||
/* Flush PCI posted writes */
|
||||
xhci_readl(xhci, &xhci->dba->doorbell[0]);
|
||||
}
|
||||
|
||||
static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
|
||||
{
|
||||
u64 temp_64;
|
||||
int ret;
|
||||
|
||||
xhci_dbg(xhci, "Abort command ring\n");
|
||||
|
||||
if (!(xhci->cmd_ring_state & CMD_RING_STATE_RUNNING)) {
|
||||
xhci_dbg(xhci, "The command ring isn't running, "
|
||||
"Have the command ring been stopped?\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
|
||||
if (!(temp_64 & CMD_RING_RUNNING)) {
|
||||
xhci_dbg(xhci, "Command ring had been stopped\n");
|
||||
return 0;
|
||||
}
|
||||
xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
|
||||
xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
|
||||
&xhci->op_regs->cmd_ring);
|
||||
|
||||
/* Section 4.6.1.2 of xHCI 1.0 spec says software should
|
||||
* time the completion od all xHCI commands, including
|
||||
* the Command Abort operation. If software doesn't see
|
||||
* CRR negated in a timely manner (e.g. longer than 5
|
||||
* seconds), then it should assume that the there are
|
||||
* larger problems with the xHC and assert HCRST.
|
||||
*/
|
||||
ret = handshake(xhci, &xhci->op_regs->cmd_ring,
|
||||
CMD_RING_RUNNING, 0, 5 * 1000 * 1000);
|
||||
if (ret < 0) {
|
||||
xhci_err(xhci, "Stopped the command ring failed, "
|
||||
"maybe the host is dead\n");
|
||||
xhci->xhc_state |= XHCI_STATE_DYING;
|
||||
xhci_quiesce(xhci);
|
||||
xhci_halt(xhci);
|
||||
return -ESHUTDOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xhci_queue_cd(struct xhci_hcd *xhci,
|
||||
struct xhci_command *command,
|
||||
union xhci_trb *cmd_trb)
|
||||
{
|
||||
struct xhci_cd *cd;
|
||||
cd = kzalloc(sizeof(struct xhci_cd), GFP_ATOMIC);
|
||||
if (!cd)
|
||||
return -ENOMEM;
|
||||
INIT_LIST_HEAD(&cd->cancel_cmd_list);
|
||||
|
||||
cd->command = command;
|
||||
cd->cmd_trb = cmd_trb;
|
||||
list_add_tail(&cd->cancel_cmd_list, &xhci->cancel_cmd_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cancel the command which has issue.
|
||||
*
|
||||
* Some commands may hang due to waiting for acknowledgement from
|
||||
* usb device. It is outside of the xHC's ability to control and
|
||||
* will cause the command ring is blocked. When it occurs software
|
||||
* should intervene to recover the command ring.
|
||||
* See Section 4.6.1.1 and 4.6.1.2
|
||||
*/
|
||||
int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command,
|
||||
union xhci_trb *cmd_trb)
|
||||
{
|
||||
int retval = 0;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
||||
if (xhci->xhc_state & XHCI_STATE_DYING) {
|
||||
xhci_warn(xhci, "Abort the command ring,"
|
||||
" but the xHCI is dead.\n");
|
||||
retval = -ESHUTDOWN;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* queue the cmd desriptor to cancel_cmd_list */
|
||||
retval = xhci_queue_cd(xhci, command, cmd_trb);
|
||||
if (retval) {
|
||||
xhci_warn(xhci, "Queuing command descriptor failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* abort command ring */
|
||||
retval = xhci_abort_cmd_ring(xhci);
|
||||
if (retval) {
|
||||
xhci_err(xhci, "Abort command ring failed\n");
|
||||
if (unlikely(retval == -ESHUTDOWN)) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
|
||||
xhci_dbg(xhci, "xHCI host controller is dead.\n");
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
return retval;
|
||||
}
|
||||
|
||||
void xhci_ring_ep_doorbell(struct xhci_hcd *xhci,
|
||||
unsigned int slot_id,
|
||||
unsigned int ep_index,
|
||||
@@ -1059,6 +1170,20 @@ static void handle_reset_ep_completion(struct xhci_hcd *xhci,
|
||||
}
|
||||
}
|
||||
|
||||
/* Complete the command and detele it from the devcie's command queue.
|
||||
*/
|
||||
static void xhci_complete_cmd_in_cmd_wait_list(struct xhci_hcd *xhci,
|
||||
struct xhci_command *command, u32 status)
|
||||
{
|
||||
command->status = status;
|
||||
list_del(&command->cmd_list);
|
||||
if (command->completion)
|
||||
complete(command->completion);
|
||||
else
|
||||
xhci_free_command(xhci, command);
|
||||
}
|
||||
|
||||
|
||||
/* Check to see if a command in the device's command queue matches this one.
|
||||
* Signal the completion or free the command, and return 1. Return 0 if the
|
||||
* completed command isn't at the head of the command list.
|
||||
@@ -1077,15 +1202,144 @@ static int handle_cmd_in_cmd_wait_list(struct xhci_hcd *xhci,
|
||||
if (xhci->cmd_ring->dequeue != command->command_trb)
|
||||
return 0;
|
||||
|
||||
command->status = GET_COMP_CODE(le32_to_cpu(event->status));
|
||||
list_del(&command->cmd_list);
|
||||
if (command->completion)
|
||||
complete(command->completion);
|
||||
else
|
||||
xhci_free_command(xhci, command);
|
||||
xhci_complete_cmd_in_cmd_wait_list(xhci, command,
|
||||
GET_COMP_CODE(le32_to_cpu(event->status)));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finding the command trb need to be cancelled and modifying it to
|
||||
* NO OP command. And if the command is in device's command wait
|
||||
* list, finishing and freeing it.
|
||||
*
|
||||
* If we can't find the command trb, we think it had already been
|
||||
* executed.
|
||||
*/
|
||||
static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd)
|
||||
{
|
||||
struct xhci_segment *cur_seg;
|
||||
union xhci_trb *cmd_trb;
|
||||
u32 cycle_state;
|
||||
|
||||
if (xhci->cmd_ring->dequeue == xhci->cmd_ring->enqueue)
|
||||
return;
|
||||
|
||||
/* find the current segment of command ring */
|
||||
cur_seg = find_trb_seg(xhci->cmd_ring->first_seg,
|
||||
xhci->cmd_ring->dequeue, &cycle_state);
|
||||
|
||||
/* find the command trb matched by cd from command ring */
|
||||
for (cmd_trb = xhci->cmd_ring->dequeue;
|
||||
cmd_trb != xhci->cmd_ring->enqueue;
|
||||
next_trb(xhci, xhci->cmd_ring, &cur_seg, &cmd_trb)) {
|
||||
/* If the trb is link trb, continue */
|
||||
if (TRB_TYPE_LINK_LE32(cmd_trb->generic.field[3]))
|
||||
continue;
|
||||
|
||||
if (cur_cd->cmd_trb == cmd_trb) {
|
||||
|
||||
/* If the command in device's command list, we should
|
||||
* finish it and free the command structure.
|
||||
*/
|
||||
if (cur_cd->command)
|
||||
xhci_complete_cmd_in_cmd_wait_list(xhci,
|
||||
cur_cd->command, COMP_CMD_STOP);
|
||||
|
||||
/* get cycle state from the origin command trb */
|
||||
cycle_state = le32_to_cpu(cmd_trb->generic.field[3])
|
||||
& TRB_CYCLE;
|
||||
|
||||
/* modify the command trb to NO OP command */
|
||||
cmd_trb->generic.field[0] = 0;
|
||||
cmd_trb->generic.field[1] = 0;
|
||||
cmd_trb->generic.field[2] = 0;
|
||||
cmd_trb->generic.field[3] = cpu_to_le32(
|
||||
TRB_TYPE(TRB_CMD_NOOP) | cycle_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void xhci_cancel_cmd_in_cd_list(struct xhci_hcd *xhci)
|
||||
{
|
||||
struct xhci_cd *cur_cd, *next_cd;
|
||||
|
||||
if (list_empty(&xhci->cancel_cmd_list))
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(cur_cd, next_cd,
|
||||
&xhci->cancel_cmd_list, cancel_cmd_list) {
|
||||
xhci_cmd_to_noop(xhci, cur_cd);
|
||||
list_del(&cur_cd->cancel_cmd_list);
|
||||
kfree(cur_cd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* traversing the cancel_cmd_list. If the command descriptor according
|
||||
* to cmd_trb is found, the function free it and return 1, otherwise
|
||||
* return 0.
|
||||
*/
|
||||
static int xhci_search_cmd_trb_in_cd_list(struct xhci_hcd *xhci,
|
||||
union xhci_trb *cmd_trb)
|
||||
{
|
||||
struct xhci_cd *cur_cd, *next_cd;
|
||||
|
||||
if (list_empty(&xhci->cancel_cmd_list))
|
||||
return 0;
|
||||
|
||||
list_for_each_entry_safe(cur_cd, next_cd,
|
||||
&xhci->cancel_cmd_list, cancel_cmd_list) {
|
||||
if (cur_cd->cmd_trb == cmd_trb) {
|
||||
if (cur_cd->command)
|
||||
xhci_complete_cmd_in_cmd_wait_list(xhci,
|
||||
cur_cd->command, COMP_CMD_STOP);
|
||||
list_del(&cur_cd->cancel_cmd_list);
|
||||
kfree(cur_cd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the cmd_trb_comp_code is COMP_CMD_ABORT, we just check whether the
|
||||
* trb pointed by the command ring dequeue pointer is the trb we want to
|
||||
* cancel or not. And if the cmd_trb_comp_code is COMP_CMD_STOP, we will
|
||||
* traverse the cancel_cmd_list to trun the all of the commands according
|
||||
* to command descriptor to NO-OP trb.
|
||||
*/
|
||||
static int handle_stopped_cmd_ring(struct xhci_hcd *xhci,
|
||||
int cmd_trb_comp_code)
|
||||
{
|
||||
int cur_trb_is_good = 0;
|
||||
|
||||
/* Searching the cmd trb pointed by the command ring dequeue
|
||||
* pointer in command descriptor list. If it is found, free it.
|
||||
*/
|
||||
cur_trb_is_good = xhci_search_cmd_trb_in_cd_list(xhci,
|
||||
xhci->cmd_ring->dequeue);
|
||||
|
||||
if (cmd_trb_comp_code == COMP_CMD_ABORT)
|
||||
xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
|
||||
else if (cmd_trb_comp_code == COMP_CMD_STOP) {
|
||||
/* traversing the cancel_cmd_list and canceling
|
||||
* the command according to command descriptor
|
||||
*/
|
||||
xhci_cancel_cmd_in_cd_list(xhci);
|
||||
|
||||
xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
|
||||
/*
|
||||
* ring command ring doorbell again to restart the
|
||||
* command ring
|
||||
*/
|
||||
if (xhci->cmd_ring->dequeue != xhci->cmd_ring->enqueue)
|
||||
xhci_ring_cmd_db(xhci);
|
||||
}
|
||||
return cur_trb_is_good;
|
||||
}
|
||||
|
||||
static void handle_cmd_completion(struct xhci_hcd *xhci,
|
||||
struct xhci_event_cmd *event)
|
||||
{
|
||||
@@ -1111,6 +1365,22 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
|
||||
xhci->error_bitmask |= 1 << 5;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_ABORT) ||
|
||||
(GET_COMP_CODE(le32_to_cpu(event->status)) == COMP_CMD_STOP)) {
|
||||
/* If the return value is 0, we think the trb pointed by
|
||||
* command ring dequeue pointer is a good trb. The good
|
||||
* trb means we don't want to cancel the trb, but it have
|
||||
* been stopped by host. So we should handle it normally.
|
||||
* Otherwise, driver should invoke inc_deq() and return.
|
||||
*/
|
||||
if (handle_stopped_cmd_ring(xhci,
|
||||
GET_COMP_CODE(le32_to_cpu(event->status)))) {
|
||||
inc_deq(xhci, xhci->cmd_ring);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (le32_to_cpu(xhci->cmd_ring->dequeue->generic.field[3])
|
||||
& TRB_TYPE_BITMASK) {
|
||||
case TRB_TYPE(TRB_ENABLE_SLOT):
|
||||
@@ -3400,7 +3670,9 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
|
||||
} else {
|
||||
td->last_trb = ep_ring->enqueue;
|
||||
field |= TRB_IOC;
|
||||
if (xhci->hci_version == 0x100) {
|
||||
if (xhci->hci_version == 0x100 &&
|
||||
!(xhci->quirks &
|
||||
XHCI_AVOID_BEI)) {
|
||||
/* Set BEI bit except for the last td */
|
||||
if (i < num_tds - 1)
|
||||
field |= TRB_BEI;
|
||||
|
||||
+27
-11
@@ -52,7 +52,7 @@ MODULE_PARM_DESC(link_quirk, "Don't clear the chain bit on a link TRB");
|
||||
* handshake done). There are two failure modes: "usec" have passed (major
|
||||
* hardware flakeout), or the register reads as all-ones (hardware removed).
|
||||
*/
|
||||
static int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
||||
int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
||||
u32 mask, u32 done, int usec)
|
||||
{
|
||||
u32 result;
|
||||
@@ -105,9 +105,10 @@ int xhci_halt(struct xhci_hcd *xhci)
|
||||
|
||||
ret = handshake(xhci, &xhci->op_regs->status,
|
||||
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
xhci->xhc_state |= XHCI_STATE_HALTED;
|
||||
else
|
||||
xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
|
||||
} else
|
||||
xhci_warn(xhci, "Host not halted after %u microseconds.\n",
|
||||
XHCI_MAX_HALT_USEC);
|
||||
return ret;
|
||||
@@ -470,6 +471,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
|
||||
|
||||
dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
|
||||
dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR);
|
||||
if (!dmi_product_name || !dmi_sys_vendor)
|
||||
return false;
|
||||
|
||||
if (!(strstr(dmi_sys_vendor, "Hewlett-Packard")))
|
||||
return false;
|
||||
@@ -581,6 +584,7 @@ static int xhci_run_finished(struct xhci_hcd *xhci)
|
||||
return -ENODEV;
|
||||
}
|
||||
xhci->shared_hcd->state = HC_STATE_RUNNING;
|
||||
xhci->cmd_ring_state = CMD_RING_STATE_RUNNING;
|
||||
|
||||
if (xhci->quirks & XHCI_NEC_HOST)
|
||||
xhci_ring_cmd_db(xhci);
|
||||
@@ -886,7 +890,7 @@ int xhci_suspend(struct xhci_hcd *xhci)
|
||||
command &= ~CMD_RUN;
|
||||
xhci_writel(xhci, command, &xhci->op_regs->command);
|
||||
if (handshake(xhci, &xhci->op_regs->status,
|
||||
STS_HALT, STS_HALT, 100*100)) {
|
||||
STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC)) {
|
||||
xhci_warn(xhci, "WARN: xHC CMD_RUN timeout\n");
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
return -ETIMEDOUT;
|
||||
@@ -2521,6 +2525,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
|
||||
struct completion *cmd_completion;
|
||||
u32 *cmd_status;
|
||||
struct xhci_virt_device *virt_dev;
|
||||
union xhci_trb *cmd_trb;
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
virt_dev = xhci->devs[udev->slot_id];
|
||||
@@ -2566,6 +2571,7 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
|
||||
}
|
||||
init_completion(cmd_completion);
|
||||
|
||||
cmd_trb = xhci->cmd_ring->dequeue;
|
||||
if (!ctx_change)
|
||||
ret = xhci_queue_configure_endpoint(xhci, in_ctx->dma,
|
||||
udev->slot_id, must_succeed);
|
||||
@@ -2587,14 +2593,17 @@ static int xhci_configure_endpoint(struct xhci_hcd *xhci,
|
||||
/* Wait for the configure endpoint command to complete */
|
||||
timeleft = wait_for_completion_interruptible_timeout(
|
||||
cmd_completion,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
XHCI_CMD_DEFAULT_TIMEOUT);
|
||||
if (timeleft <= 0) {
|
||||
xhci_warn(xhci, "%s while waiting for %s command\n",
|
||||
timeleft == 0 ? "Timeout" : "Signal",
|
||||
ctx_change == 0 ?
|
||||
"configure endpoint" :
|
||||
"evaluate context");
|
||||
/* FIXME cancel the configure endpoint command */
|
||||
/* cancel the configure endpoint command */
|
||||
ret = xhci_cancel_cmd(xhci, command, cmd_trb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
@@ -3543,8 +3552,10 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
unsigned long flags;
|
||||
int timeleft;
|
||||
int ret;
|
||||
union xhci_trb *cmd_trb;
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
cmd_trb = xhci->cmd_ring->dequeue;
|
||||
ret = xhci_queue_slot_control(xhci, TRB_ENABLE_SLOT, 0);
|
||||
if (ret) {
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
@@ -3556,12 +3567,12 @@ int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
|
||||
/* XXX: how much time for xHC slot assignment? */
|
||||
timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
XHCI_CMD_DEFAULT_TIMEOUT);
|
||||
if (timeleft <= 0) {
|
||||
xhci_warn(xhci, "%s while waiting for a slot\n",
|
||||
timeleft == 0 ? "Timeout" : "Signal");
|
||||
/* FIXME cancel the enable slot request */
|
||||
return 0;
|
||||
/* cancel the enable slot request */
|
||||
return xhci_cancel_cmd(xhci, NULL, cmd_trb);
|
||||
}
|
||||
|
||||
if (!xhci->slot_id) {
|
||||
@@ -3622,6 +3633,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
u64 temp_64;
|
||||
union xhci_trb *cmd_trb;
|
||||
|
||||
if (!udev->slot_id) {
|
||||
xhci_dbg(xhci, "Bad Slot ID %d\n", udev->slot_id);
|
||||
@@ -3660,6 +3672,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
|
||||
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
cmd_trb = xhci->cmd_ring->dequeue;
|
||||
ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
|
||||
udev->slot_id);
|
||||
if (ret) {
|
||||
@@ -3672,7 +3685,7 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
|
||||
/* ctrl tx can take up to 5 sec; XXX: need more time for xHC? */
|
||||
timeleft = wait_for_completion_interruptible_timeout(&xhci->addr_dev,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
XHCI_CMD_DEFAULT_TIMEOUT);
|
||||
/* FIXME: From section 4.3.4: "Software shall be responsible for timing
|
||||
* the SetAddress() "recovery interval" required by USB and aborting the
|
||||
* command on a timeout.
|
||||
@@ -3680,7 +3693,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
||||
if (timeleft <= 0) {
|
||||
xhci_warn(xhci, "%s while waiting for address device command\n",
|
||||
timeleft == 0 ? "Timeout" : "Signal");
|
||||
/* FIXME cancel the address device command */
|
||||
/* cancel the address device command */
|
||||
ret = xhci_cancel_cmd(xhci, NULL, cmd_trb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
|
||||
@@ -1256,6 +1256,16 @@ struct xhci_td {
|
||||
union xhci_trb *last_trb;
|
||||
};
|
||||
|
||||
/* xHCI command default timeout value */
|
||||
#define XHCI_CMD_DEFAULT_TIMEOUT (5 * HZ)
|
||||
|
||||
/* command descriptor */
|
||||
struct xhci_cd {
|
||||
struct list_head cancel_cmd_list;
|
||||
struct xhci_command *command;
|
||||
union xhci_trb *cmd_trb;
|
||||
};
|
||||
|
||||
struct xhci_dequeue_state {
|
||||
struct xhci_segment *new_deq_seg;
|
||||
union xhci_trb *new_deq_ptr;
|
||||
@@ -1421,6 +1431,11 @@ struct xhci_hcd {
|
||||
/* data structures */
|
||||
struct xhci_device_context_array *dcbaa;
|
||||
struct xhci_ring *cmd_ring;
|
||||
unsigned int cmd_ring_state;
|
||||
#define CMD_RING_STATE_RUNNING (1 << 0)
|
||||
#define CMD_RING_STATE_ABORTED (1 << 1)
|
||||
#define CMD_RING_STATE_STOPPED (1 << 2)
|
||||
struct list_head cancel_cmd_list;
|
||||
unsigned int cmd_ring_reserved_trbs;
|
||||
struct xhci_ring *event_ring;
|
||||
struct xhci_erst erst;
|
||||
@@ -1496,6 +1511,7 @@ struct xhci_hcd {
|
||||
#define XHCI_INTEL_HOST (1 << 12)
|
||||
#define XHCI_SPURIOUS_REBOOT (1 << 13)
|
||||
#define XHCI_COMP_MODE_QUIRK (1 << 14)
|
||||
#define XHCI_AVOID_BEI (1 << 15)
|
||||
unsigned int num_active_eps;
|
||||
unsigned int limit_active_eps;
|
||||
/* There are two roothubs to keep track of bus suspend info for */
|
||||
@@ -1704,6 +1720,8 @@ static inline void xhci_unregister_plat(void)
|
||||
|
||||
/* xHCI host controller glue */
|
||||
typedef void (*xhci_get_quirks_t)(struct device *, struct xhci_hcd *);
|
||||
int handshake(struct xhci_hcd *xhci, void __iomem *ptr,
|
||||
u32 mask, u32 done, int usec);
|
||||
void xhci_quiesce(struct xhci_hcd *xhci);
|
||||
int xhci_halt(struct xhci_hcd *xhci);
|
||||
int xhci_reset(struct xhci_hcd *xhci);
|
||||
@@ -1794,6 +1812,8 @@ void xhci_queue_config_ep_quirk(struct xhci_hcd *xhci,
|
||||
unsigned int slot_id, unsigned int ep_index,
|
||||
struct xhci_dequeue_state *deq_state);
|
||||
void xhci_stop_endpoint_command_watchdog(unsigned long arg);
|
||||
int xhci_cancel_cmd(struct xhci_hcd *xhci, struct xhci_command *command,
|
||||
union xhci_trb *cmd_trb);
|
||||
void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, unsigned int slot_id,
|
||||
unsigned int ep_index, unsigned int stream_id);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define DRIVER_NAME "mxs_phy"
|
||||
|
||||
@@ -34,9 +35,16 @@
|
||||
#define BM_USBPHY_CTRL_ENUTMILEVEL2 BIT(14)
|
||||
#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT BIT(1)
|
||||
|
||||
/*
|
||||
* Amount of delay in miliseconds to safely enable ENHOSTDISCONDETECT bit
|
||||
* so that connection and reset processing can be completed for the root hub.
|
||||
*/
|
||||
#define MXY_PHY_ENHOSTDISCONDETECT_DELAY 250
|
||||
|
||||
struct mxs_phy {
|
||||
struct usb_phy phy;
|
||||
struct clk *clk;
|
||||
struct delayed_work enhostdiscondetect_work;
|
||||
};
|
||||
|
||||
#define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
|
||||
@@ -62,6 +70,7 @@ static int mxs_phy_init(struct usb_phy *phy)
|
||||
|
||||
clk_prepare_enable(mxs_phy->clk);
|
||||
mxs_phy_hw_init(mxs_phy);
|
||||
INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -76,13 +85,34 @@ static void mxs_phy_shutdown(struct usb_phy *phy)
|
||||
clk_disable_unprepare(mxs_phy->clk);
|
||||
}
|
||||
|
||||
static void mxs_phy_enhostdiscondetect_delay(struct work_struct *ws)
|
||||
{
|
||||
struct mxs_phy *mxs_phy = container_of(ws, struct mxs_phy,
|
||||
enhostdiscondetect_work.work);
|
||||
|
||||
/* Enable HOSTDISCONDETECT after delay. */
|
||||
dev_dbg(mxs_phy->phy.dev, "Setting ENHOSTDISCONDETECT\n");
|
||||
writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
|
||||
mxs_phy->phy.io_priv + HW_USBPHY_CTRL_SET);
|
||||
}
|
||||
|
||||
static int mxs_phy_on_connect(struct usb_phy *phy, int port)
|
||||
{
|
||||
struct mxs_phy *mxs_phy = to_mxs_phy(phy);
|
||||
|
||||
dev_dbg(phy->dev, "Connect on port %d\n", port);
|
||||
|
||||
mxs_phy_hw_init(to_mxs_phy(phy));
|
||||
writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
|
||||
phy->io_priv + HW_USBPHY_CTRL_SET);
|
||||
mxs_phy_hw_init(mxs_phy);
|
||||
|
||||
/*
|
||||
* Delay enabling ENHOSTDISCONDETECT so that connection and
|
||||
* reset processing can be completed for the root hub.
|
||||
*/
|
||||
dev_dbg(phy->dev, "Delaying setting ENHOSTDISCONDETECT\n");
|
||||
PREPARE_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work,
|
||||
mxs_phy_enhostdiscondetect_delay);
|
||||
schedule_delayed_work(&mxs_phy->enhostdiscondetect_work,
|
||||
msecs_to_jiffies(MXY_PHY_ENHOSTDISCONDETECT_DELAY));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -91,6 +121,8 @@ static int mxs_phy_on_disconnect(struct usb_phy *phy, int port)
|
||||
{
|
||||
dev_dbg(phy->dev, "Disconnect on port %d\n", port);
|
||||
|
||||
/* No need to delay before clearing ENHOSTDISCONDETECT. */
|
||||
dev_dbg(phy->dev, "Clearing ENHOSTDISCONDETECT\n");
|
||||
writel_relaxed(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
|
||||
phy->io_priv + HW_USBPHY_CTRL_CLR);
|
||||
|
||||
|
||||
@@ -584,6 +584,8 @@ static struct usb_device_id id_table_combined [] = {
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TAVIR_STK500_PID) },
|
||||
{ USB_DEVICE(FTDI_VID, FTDI_TIAO_UMPA_PID),
|
||||
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
|
||||
/*
|
||||
* ELV devices:
|
||||
*/
|
||||
|
||||
@@ -517,6 +517,11 @@
|
||||
*/
|
||||
#define FTDI_TAVIR_STK500_PID 0xFA33 /* STK500 AVR programmer */
|
||||
|
||||
/*
|
||||
* TIAO product ids (FTDI_VID)
|
||||
* http://www.tiaowiki.com/w/Main_Page
|
||||
*/
|
||||
#define FTDI_TIAO_UMPA_PID 0x8a98 /* TIAO/DIYGADGET USB Multi-Protocol Adapter */
|
||||
|
||||
|
||||
/********************************/
|
||||
|
||||
@@ -870,7 +870,8 @@ static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
|
||||
|
||||
@@ -36,8 +36,6 @@
|
||||
#define UTSTARCOM_PRODUCT_UM175_V1 0x3712
|
||||
#define UTSTARCOM_PRODUCT_UM175_V2 0x3714
|
||||
#define UTSTARCOM_PRODUCT_UM175_ALLTEL 0x3715
|
||||
#define PANTECH_PRODUCT_UML190_VZW 0x3716
|
||||
#define PANTECH_PRODUCT_UML290_VZW 0x3718
|
||||
|
||||
/* CMOTECH devices */
|
||||
#define CMOTECH_VENDOR_ID 0x16d8
|
||||
@@ -68,11 +66,9 @@ static struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML190_VZW, 0xff, 0xfe, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfd, 0xff) }, /* NMEA */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xfe, 0xff) }, /* WMC */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, PANTECH_PRODUCT_UML290_VZW, 0xff, 0xff, 0xff) }, /* DIAG */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */
|
||||
{ USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
|
||||
@@ -1426,9 +1426,10 @@ int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[]
|
||||
|
||||
/* we only set the reset_resume field if the serial_driver has one */
|
||||
for (sd = serial_drivers; *sd; ++sd) {
|
||||
if ((*sd)->reset_resume)
|
||||
if ((*sd)->reset_resume) {
|
||||
udriver->reset_resume = usb_serial_reset_resume;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rc = usb_register(udriver);
|
||||
|
||||
@@ -362,6 +362,7 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)
|
||||
else {
|
||||
dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n");
|
||||
__pci_reset_function_locked(dev);
|
||||
pci_restore_state(dev);
|
||||
}
|
||||
/* Now disable the device (this also ensures some private device
|
||||
* data is setup before we export)
|
||||
|
||||
+4
-15
@@ -1696,30 +1696,19 @@ static int elf_note_info_init(struct elf_note_info *info)
|
||||
return 0;
|
||||
info->psinfo = kmalloc(sizeof(*info->psinfo), GFP_KERNEL);
|
||||
if (!info->psinfo)
|
||||
goto notes_free;
|
||||
return 0;
|
||||
info->prstatus = kmalloc(sizeof(*info->prstatus), GFP_KERNEL);
|
||||
if (!info->prstatus)
|
||||
goto psinfo_free;
|
||||
return 0;
|
||||
info->fpu = kmalloc(sizeof(*info->fpu), GFP_KERNEL);
|
||||
if (!info->fpu)
|
||||
goto prstatus_free;
|
||||
return 0;
|
||||
#ifdef ELF_CORE_COPY_XFPREGS
|
||||
info->xfpu = kmalloc(sizeof(*info->xfpu), GFP_KERNEL);
|
||||
if (!info->xfpu)
|
||||
goto fpu_free;
|
||||
return 0;
|
||||
#endif
|
||||
return 1;
|
||||
#ifdef ELF_CORE_COPY_XFPREGS
|
||||
fpu_free:
|
||||
kfree(info->fpu);
|
||||
#endif
|
||||
prstatus_free:
|
||||
kfree(info->prstatus);
|
||||
psinfo_free:
|
||||
kfree(info->psinfo);
|
||||
notes_free:
|
||||
kfree(info->notes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_note_info(struct elfhdr *elf, int phdrs,
|
||||
|
||||
@@ -1847,7 +1847,6 @@
|
||||
#define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081
|
||||
#define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082
|
||||
#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050
|
||||
#define PCI_SUBDEVICE_ID_SIIG_DUAL_SERIAL 0x2530
|
||||
|
||||
#define PCI_VENDOR_ID_RADISYS 0x1331
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
if (arg2 == 0) {
|
||||
yama_ptracer_del(NULL, myself);
|
||||
rc = 0;
|
||||
} else if (arg2 == PR_SET_PTRACER_ANY) {
|
||||
} else if (arg2 == PR_SET_PTRACER_ANY || (int)arg2 == -1) {
|
||||
rc = yama_ptracer_add(NULL, myself);
|
||||
} else {
|
||||
struct task_struct *tracer;
|
||||
|
||||
+31
-14
@@ -106,7 +106,7 @@ static void kvp_acquire_lock(int pool)
|
||||
|
||||
if (fcntl(kvp_file_info[pool].fd, F_SETLKW, &fl) == -1) {
|
||||
syslog(LOG_ERR, "Failed to acquire the lock pool: %d", pool);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ static void kvp_release_lock(int pool)
|
||||
if (fcntl(kvp_file_info[pool].fd, F_SETLK, &fl) == -1) {
|
||||
perror("fcntl");
|
||||
syslog(LOG_ERR, "Failed to release the lock pool: %d", pool);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,14 +137,19 @@ static void kvp_update_file(int pool)
|
||||
if (!filep) {
|
||||
kvp_release_lock(pool);
|
||||
syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
bytes_written = fwrite(kvp_file_info[pool].records,
|
||||
sizeof(struct kvp_record),
|
||||
kvp_file_info[pool].num_records, filep);
|
||||
|
||||
fflush(filep);
|
||||
if (ferror(filep) || fclose(filep)) {
|
||||
kvp_release_lock(pool);
|
||||
syslog(LOG_ERR, "Failed to write file, pool: %d", pool);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
kvp_release_lock(pool);
|
||||
}
|
||||
|
||||
@@ -163,14 +168,19 @@ static void kvp_update_mem_state(int pool)
|
||||
if (!filep) {
|
||||
kvp_release_lock(pool);
|
||||
syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
while (!feof(filep)) {
|
||||
for (;;) {
|
||||
readp = &record[records_read];
|
||||
records_read += fread(readp, sizeof(struct kvp_record),
|
||||
ENTRIES_PER_BLOCK * num_blocks,
|
||||
filep);
|
||||
|
||||
if (ferror(filep)) {
|
||||
syslog(LOG_ERR, "Failed to read file, pool: %d", pool);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!feof(filep)) {
|
||||
/*
|
||||
* We have more data to read.
|
||||
@@ -180,7 +190,7 @@ static void kvp_update_mem_state(int pool)
|
||||
|
||||
if (record == NULL) {
|
||||
syslog(LOG_ERR, "malloc failed");
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -191,6 +201,7 @@ static void kvp_update_mem_state(int pool)
|
||||
kvp_file_info[pool].records = record;
|
||||
kvp_file_info[pool].num_records = records_read;
|
||||
|
||||
fclose(filep);
|
||||
kvp_release_lock(pool);
|
||||
}
|
||||
static int kvp_file_init(void)
|
||||
@@ -208,7 +219,7 @@ static int kvp_file_init(void)
|
||||
if (access("/var/opt/hyperv", F_OK)) {
|
||||
if (mkdir("/var/opt/hyperv", S_IRUSR | S_IWUSR | S_IROTH)) {
|
||||
syslog(LOG_ERR, " Failed to create /var/opt/hyperv");
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,12 +243,18 @@ static int kvp_file_init(void)
|
||||
fclose(filep);
|
||||
return 1;
|
||||
}
|
||||
while (!feof(filep)) {
|
||||
for (;;) {
|
||||
readp = &record[records_read];
|
||||
records_read += fread(readp, sizeof(struct kvp_record),
|
||||
ENTRIES_PER_BLOCK,
|
||||
filep);
|
||||
|
||||
if (ferror(filep)) {
|
||||
syslog(LOG_ERR, "Failed to read file, pool: %d",
|
||||
i);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (!feof(filep)) {
|
||||
/*
|
||||
* We have more data to read.
|
||||
@@ -657,13 +674,13 @@ int main(void)
|
||||
|
||||
if (kvp_file_init()) {
|
||||
syslog(LOG_ERR, "Failed to initialize the pools");
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
|
||||
if (fd < 0) {
|
||||
syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
addr.nl_family = AF_NETLINK;
|
||||
addr.nl_pad = 0;
|
||||
@@ -675,7 +692,7 @@ int main(void)
|
||||
if (error < 0) {
|
||||
syslog(LOG_ERR, "bind failed; error:%d", error);
|
||||
close(fd);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
sock_opt = addr.nl_groups;
|
||||
setsockopt(fd, 270, 1, &sock_opt, sizeof(sock_opt));
|
||||
@@ -695,7 +712,7 @@ int main(void)
|
||||
if (len < 0) {
|
||||
syslog(LOG_ERR, "netlink_send failed; error:%d", len);
|
||||
close(fd);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pfd.fd = fd;
|
||||
@@ -863,7 +880,7 @@ kvp_done:
|
||||
len = netlink_send(fd, incoming_cn_msg);
|
||||
if (len < 0) {
|
||||
syslog(LOG_ERR, "net_link send failed; error:%d", len);
|
||||
exit(-1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user