提交 62cd2fa8 编写于 作者: D Dave Airlie

Merge branch 'console-fixes' into drm-next

(not the fbcon maintainer pull 2)

fix bug in vgacon on bootup and fbcon losing fonts on startup.

* console-fixes: (50 commits)
  fbcon: don't lose the console font across generic->chip driver switch
  vgacon/vt: clear buffer attributes when we load a 512 character font (v2)
...@@ -1489,7 +1489,7 @@ AVR32 ARCHITECTURE ...@@ -1489,7 +1489,7 @@ AVR32 ARCHITECTURE
M: Haavard Skinnemoen <hskinnemoen@gmail.com> M: Haavard Skinnemoen <hskinnemoen@gmail.com>
M: Hans-Christian Egtvedt <egtvedt@samfundet.no> M: Hans-Christian Egtvedt <egtvedt@samfundet.no>
W: http://www.atmel.com/products/AVR32/ W: http://www.atmel.com/products/AVR32/
W: http://avr32linux.org/ W: http://mirror.egtvedt.no/avr32linux.org/
W: http://avrfreaks.net/ W: http://avrfreaks.net/
S: Maintained S: Maintained
F: arch/avr32/ F: arch/avr32/
......
...@@ -336,4 +336,14 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, ...@@ -336,4 +336,14 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
/* drivers/base/dma-mapping.c */
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size);
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size);
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
#endif /* __ASM_AVR32_DMA_MAPPING_H */ #endif /* __ASM_AVR32_DMA_MAPPING_H */
...@@ -154,4 +154,14 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, ...@@ -154,4 +154,14 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
_dma_sync((dma_addr_t)vaddr, size, dir); _dma_sync((dma_addr_t)vaddr, size, dir);
} }
/* drivers/base/dma-mapping.c */
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size);
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size);
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
#endif /* _BLACKFIN_DMA_MAPPING_H */ #endif /* _BLACKFIN_DMA_MAPPING_H */
...@@ -89,4 +89,19 @@ extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); ...@@ -89,4 +89,19 @@ extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t);
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f)) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h)) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h))
/* Not supported for now */
static inline int dma_mmap_coherent(struct device *dev,
struct vm_area_struct *vma, void *cpu_addr,
dma_addr_t dma_addr, size_t size)
{
return -EINVAL;
}
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size)
{
return -EINVAL;
}
#endif /* _ASM_C6X_DMA_MAPPING_H */ #endif /* _ASM_C6X_DMA_MAPPING_H */
...@@ -158,5 +158,15 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, ...@@ -158,5 +158,15 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
{ {
} }
/* drivers/base/dma-mapping.c */
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size);
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size);
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
#endif #endif
...@@ -132,4 +132,19 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size, ...@@ -132,4 +132,19 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
flush_write_buffers(); flush_write_buffers();
} }
/* Not supported for now */
static inline int dma_mmap_coherent(struct device *dev,
struct vm_area_struct *vma, void *cpu_addr,
dma_addr_t dma_addr, size_t size)
{
return -EINVAL;
}
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size)
{
return -EINVAL;
}
#endif /* _ASM_DMA_MAPPING_H */ #endif /* _ASM_DMA_MAPPING_H */
...@@ -115,4 +115,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t handle) ...@@ -115,4 +115,14 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t handle)
#include <asm-generic/dma-mapping-broken.h> #include <asm-generic/dma-mapping-broken.h>
#endif #endif
/* drivers/base/dma-mapping.c */
extern int dma_common_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size);
extern int dma_common_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size);
#define dma_mmap_coherent(d, v, c, h, s) dma_common_mmap(d, v, c, h, s)
#define dma_get_sgtable(d, t, v, h, s) dma_common_get_sgtable(d, t, v, h, s)
#endif /* _M68K_DMA_MAPPING_H */ #endif /* _M68K_DMA_MAPPING_H */
...@@ -168,4 +168,19 @@ void dma_cache_sync(void *vaddr, size_t size, ...@@ -168,4 +168,19 @@ void dma_cache_sync(void *vaddr, size_t size,
mn10300_dcache_flush_inv(); mn10300_dcache_flush_inv();
} }
/* Not supported for now */
static inline int dma_mmap_coherent(struct device *dev,
struct vm_area_struct *vma, void *cpu_addr,
dma_addr_t dma_addr, size_t size)
{
return -EINVAL;
}
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size)
{
return -EINVAL;
}
#endif #endif
...@@ -238,4 +238,19 @@ void * sba_get_iommu(struct parisc_device *dev); ...@@ -238,4 +238,19 @@ void * sba_get_iommu(struct parisc_device *dev);
/* At the moment, we panic on error for IOMMU resource exaustion */ /* At the moment, we panic on error for IOMMU resource exaustion */
#define dma_mapping_error(dev, x) 0 #define dma_mapping_error(dev, x) 0
/* This API cannot be supported on PA-RISC */
static inline int dma_mmap_coherent(struct device *dev,
struct vm_area_struct *vma, void *cpu_addr,
dma_addr_t dma_addr, size_t size)
{
return -EINVAL;
}
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size)
{
return -EINVAL;
}
#endif #endif
...@@ -170,4 +170,19 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size, ...@@ -170,4 +170,19 @@ dma_cache_sync(struct device *dev, void *vaddr, size_t size,
consistent_sync(vaddr, size, direction); consistent_sync(vaddr, size, direction);
} }
/* Not supported for now */
static inline int dma_mmap_coherent(struct device *dev,
struct vm_area_struct *vma, void *cpu_addr,
dma_addr_t dma_addr, size_t size)
{
return -EINVAL;
}
static inline int dma_get_sgtable(struct device *dev, struct sg_table *sgt,
void *cpu_addr, dma_addr_t dma_addr,
size_t size)
{
return -EINVAL;
}
#endif /* _XTENSA_DMA_MAPPING_H */ #endif /* _XTENSA_DMA_MAPPING_H */
...@@ -374,6 +374,7 @@ static int usb_keene_probe(struct usb_interface *intf, ...@@ -374,6 +374,7 @@ static int usb_keene_probe(struct usb_interface *intf,
radio->vdev.ioctl_ops = &usb_keene_ioctl_ops; radio->vdev.ioctl_ops = &usb_keene_ioctl_ops;
radio->vdev.lock = &radio->lock; radio->vdev.lock = &radio->lock;
radio->vdev.release = video_device_release_empty; radio->vdev.release = video_device_release_empty;
radio->vdev.vfl_dir = VFL_DIR_TX;
radio->usbdev = interface_to_usbdev(intf); radio->usbdev = interface_to_usbdev(intf);
radio->intf = intf; radio->intf = intf;
......
...@@ -250,6 +250,7 @@ static struct video_device radio_si4713_vdev_template = { ...@@ -250,6 +250,7 @@ static struct video_device radio_si4713_vdev_template = {
.name = "radio-si4713", .name = "radio-si4713",
.release = video_device_release, .release = video_device_release,
.ioctl_ops = &radio_si4713_ioctl_ops, .ioctl_ops = &radio_si4713_ioctl_ops,
.vfl_dir = VFL_DIR_TX,
}; };
/* Platform driver interface */ /* Platform driver interface */
......
...@@ -1971,6 +1971,7 @@ static struct video_device wl1273_viddev_template = { ...@@ -1971,6 +1971,7 @@ static struct video_device wl1273_viddev_template = {
.ioctl_ops = &wl1273_ioctl_ops, .ioctl_ops = &wl1273_ioctl_ops,
.name = WL1273_FM_DRIVER_NAME, .name = WL1273_FM_DRIVER_NAME,
.release = wl1273_vdev_release, .release = wl1273_vdev_release,
.vfl_dir = VFL_DIR_TX,
}; };
static int wl1273_fm_radio_remove(struct platform_device *pdev) static int wl1273_fm_radio_remove(struct platform_device *pdev)
......
...@@ -518,6 +518,16 @@ static struct video_device fm_viddev_template = { ...@@ -518,6 +518,16 @@ static struct video_device fm_viddev_template = {
.ioctl_ops = &fm_drv_ioctl_ops, .ioctl_ops = &fm_drv_ioctl_ops,
.name = FM_DRV_NAME, .name = FM_DRV_NAME,
.release = video_device_release, .release = video_device_release,
/*
* To ensure both the tuner and modulator ioctls are accessible we
* set the vfl_dir to M2M to indicate this.
*
* It is not really a mem2mem device of course, but it can both receive
* and transmit using the same radio device. It's the only radio driver
* that does this and it should really be split in two radio devices,
* but that would affect applications using this driver.
*/
.vfl_dir = VFL_DIR_M2M,
}; };
int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
......
...@@ -506,6 +506,7 @@ isl1208_rtc_interrupt(int irq, void *data) ...@@ -506,6 +506,7 @@ isl1208_rtc_interrupt(int irq, void *data)
{ {
unsigned long timeout = jiffies + msecs_to_jiffies(1000); unsigned long timeout = jiffies + msecs_to_jiffies(1000);
struct i2c_client *client = data; struct i2c_client *client = data;
struct rtc_device *rtc = i2c_get_clientdata(client);
int handled = 0, sr, err; int handled = 0, sr, err;
/* /*
...@@ -528,6 +529,8 @@ isl1208_rtc_interrupt(int irq, void *data) ...@@ -528,6 +529,8 @@ isl1208_rtc_interrupt(int irq, void *data)
if (sr & ISL1208_REG_SR_ALM) { if (sr & ISL1208_REG_SR_ALM) {
dev_dbg(&client->dev, "alarm!\n"); dev_dbg(&client->dev, "alarm!\n");
rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);
/* Clear the alarm */ /* Clear the alarm */
sr &= ~ISL1208_REG_SR_ALM; sr &= ~ISL1208_REG_SR_ALM;
sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr); sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#define RTC_YMR 0x34 /* Year match register */ #define RTC_YMR 0x34 /* Year match register */
#define RTC_YLR 0x38 /* Year data load register */ #define RTC_YLR 0x38 /* Year data load register */
#define RTC_CR_EN (1 << 0) /* counter enable bit */
#define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */ #define RTC_CR_CWEN (1 << 26) /* Clockwatch enable bit */
#define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */ #define RTC_TCR_EN (1 << 1) /* Periodic timer enable bit */
...@@ -320,7 +321,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -320,7 +321,7 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
struct pl031_local *ldata; struct pl031_local *ldata;
struct pl031_vendor_data *vendor = id->data; struct pl031_vendor_data *vendor = id->data;
struct rtc_class_ops *ops = &vendor->ops; struct rtc_class_ops *ops = &vendor->ops;
unsigned long time; unsigned long time, data;
ret = amba_request_regions(adev, NULL); ret = amba_request_regions(adev, NULL);
if (ret) if (ret)
...@@ -345,10 +346,11 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id) ...@@ -345,10 +346,11 @@ static int pl031_probe(struct amba_device *adev, const struct amba_id *id)
dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev)); dev_dbg(&adev->dev, "designer ID = 0x%02x\n", amba_manf(adev));
dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev)); dev_dbg(&adev->dev, "revision = 0x%01x\n", amba_rev(adev));
data = readl(ldata->base + RTC_CR);
/* Enable the clockwatch on ST Variants */ /* Enable the clockwatch on ST Variants */
if (vendor->clockwatch) if (vendor->clockwatch)
writel(readl(ldata->base + RTC_CR) | RTC_CR_CWEN, data |= RTC_CR_CWEN;
ldata->base + RTC_CR); writel(data | RTC_CR_EN, ldata->base + RTC_CR);
/* /*
* On ST PL031 variants, the RTC reset value does not provide correct * On ST PL031 variants, the RTC reset value does not provide correct
......
...@@ -137,7 +137,7 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm) ...@@ -137,7 +137,7 @@ static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
return -EINVAL; return -EINVAL;
} }
writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S) writel((bin2bcd(tm->tm_year % 100) << DATE_YEAR_S)
| (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S) | (bin2bcd(tm->tm_mon + 1) << DATE_MONTH_S)
| (bin2bcd(tm->tm_mday)) | (bin2bcd(tm->tm_mday))
| ((tm->tm_year >= 200) << DATE_CENTURY_S), | ((tm->tm_year >= 200) << DATE_CENTURY_S),
......
...@@ -638,7 +638,7 @@ static inline void save_screen(struct vc_data *vc) ...@@ -638,7 +638,7 @@ static inline void save_screen(struct vc_data *vc)
* Redrawing of screen * Redrawing of screen
*/ */
static void clear_buffer_attributes(struct vc_data *vc) void clear_buffer_attributes(struct vc_data *vc)
{ {
unsigned short *p = (unsigned short *)vc->vc_origin; unsigned short *p = (unsigned short *)vc->vc_origin;
int count = vc->vc_screenbuf_size / 2; int count = vc->vc_screenbuf_size / 2;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/pm_runtime.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/usb/hcd.h> #include <linux/usb/hcd.h>
...@@ -1025,6 +1026,49 @@ static int register_root_hub(struct usb_hcd *hcd) ...@@ -1025,6 +1026,49 @@ static int register_root_hub(struct usb_hcd *hcd)
return retval; return retval;
} }
/*
* usb_hcd_start_port_resume - a root-hub port is sending a resume signal
* @bus: the bus which the root hub belongs to
* @portnum: the port which is being resumed
*
* HCDs should call this function when they know that a resume signal is
* being sent to a root-hub port. The root hub will be prevented from
* going into autosuspend until usb_hcd_end_port_resume() is called.
*
* The bus's private lock must be held by the caller.
*/
void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum)
{
unsigned bit = 1 << portnum;
if (!(bus->resuming_ports & bit)) {
bus->resuming_ports |= bit;
pm_runtime_get_noresume(&bus->root_hub->dev);
}
}
EXPORT_SYMBOL_GPL(usb_hcd_start_port_resume);
/*
* usb_hcd_end_port_resume - a root-hub port has stopped sending a resume signal
* @bus: the bus which the root hub belongs to
* @portnum: the port which is being resumed
*
* HCDs should call this function when they know that a resume signal has
* stopped being sent to a root-hub port. The root hub will be allowed to
* autosuspend again.
*
* The bus's private lock must be held by the caller.
*/
void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum)
{
unsigned bit = 1 << portnum;
if (bus->resuming_ports & bit) {
bus->resuming_ports &= ~bit;
pm_runtime_put_noidle(&bus->root_hub->dev);
}
}
EXPORT_SYMBOL_GPL(usb_hcd_end_port_resume);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev) ...@@ -2838,6 +2838,23 @@ void usb_enable_ltm(struct usb_device *udev)
EXPORT_SYMBOL_GPL(usb_enable_ltm); EXPORT_SYMBOL_GPL(usb_enable_ltm);
#ifdef CONFIG_USB_SUSPEND #ifdef CONFIG_USB_SUSPEND
/*
* usb_disable_function_remotewakeup - disable usb3.0
* device's function remote wakeup
* @udev: target device
*
* Assume there's only one function on the USB 3.0
* device and disable remote wake for the first
* interface. FIXME if the interface association
* descriptor shows there's more than one function.
*/
static int usb_disable_function_remotewakeup(struct usb_device *udev)
{
return usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
USB_REQ_CLEAR_FEATURE, USB_RECIP_INTERFACE,
USB_INTRF_FUNC_SUSPEND, 0, NULL, 0,
USB_CTRL_SET_TIMEOUT);
}
/* /*
* usb_port_suspend - suspend a usb device's upstream port * usb_port_suspend - suspend a usb device's upstream port
...@@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) ...@@ -2955,12 +2972,19 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n",
port1, status); port1, status);
/* paranoia: "should not happen" */ /* paranoia: "should not happen" */
if (udev->do_remote_wakeup) if (udev->do_remote_wakeup) {
(void) usb_control_msg(udev, usb_sndctrlpipe(udev, 0), if (!hub_is_superspeed(hub->hdev)) {
USB_REQ_CLEAR_FEATURE, USB_RECIP_DEVICE, (void) usb_control_msg(udev,
USB_DEVICE_REMOTE_WAKEUP, 0, usb_sndctrlpipe(udev, 0),
NULL, 0, USB_REQ_CLEAR_FEATURE,
USB_CTRL_SET_TIMEOUT); USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0,
USB_CTRL_SET_TIMEOUT);
} else
(void) usb_disable_function_remotewakeup(udev);
}
/* Try to enable USB2 hardware LPM again */ /* Try to enable USB2 hardware LPM again */
if (udev->usb2_hw_lpm_capable == 1) if (udev->usb2_hw_lpm_capable == 1)
...@@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev) ...@@ -3052,20 +3076,30 @@ static int finish_port_resume(struct usb_device *udev)
* udev->reset_resume * udev->reset_resume
*/ */
} else if (udev->actconfig && !udev->reset_resume) { } else if (udev->actconfig && !udev->reset_resume) {
le16_to_cpus(&devstatus); if (!hub_is_superspeed(udev->parent)) {
if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { le16_to_cpus(&devstatus);
status = usb_control_msg(udev, if (devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP))
usb_sndctrlpipe(udev, 0), status = usb_control_msg(udev,
USB_REQ_CLEAR_FEATURE, usb_sndctrlpipe(udev, 0),
USB_REQ_CLEAR_FEATURE,
USB_RECIP_DEVICE, USB_RECIP_DEVICE,
USB_DEVICE_REMOTE_WAKEUP, 0, USB_DEVICE_REMOTE_WAKEUP, 0,
NULL, 0, NULL, 0,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
if (status) } else {
dev_dbg(&udev->dev, status = usb_get_status(udev, USB_RECIP_INTERFACE, 0,
"disable remote wakeup, status %d\n", &devstatus);
status); le16_to_cpus(&devstatus);
if (!status && devstatus & (USB_INTRF_STAT_FUNC_RW_CAP
| USB_INTRF_STAT_FUNC_RW))
status =
usb_disable_function_remotewakeup(udev);
} }
if (status)
dev_dbg(&udev->dev,
"disable remote wakeup, status %d\n",
status);
status = 0; status = 0;
} }
return status; return status;
......
...@@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) ...@@ -797,6 +797,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
ehci->reset_done[i] = jiffies + msecs_to_jiffies(25); ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
set_bit(i, &ehci->resuming_ports); set_bit(i, &ehci->resuming_ports);
ehci_dbg (ehci, "port %d remote wakeup\n", i + 1); ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
usb_hcd_start_port_resume(&hcd->self, i);
mod_timer(&hcd->rh_timer, ehci->reset_done[i]); mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
} }
} }
......
...@@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) ...@@ -649,7 +649,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
status = STS_PCD; status = STS_PCD;
} }
} }
/* FIXME autosuspend idle root hubs */
/* If a resume is in progress, make sure it can finish */
if (ehci->resuming_ports)
mod_timer(&hcd->rh_timer, jiffies + msecs_to_jiffies(25));
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
return status ? retval : 0; return status ? retval : 0;
} }
...@@ -851,6 +855,7 @@ static int ehci_hub_control ( ...@@ -851,6 +855,7 @@ static int ehci_hub_control (
/* resume signaling for 20 msec */ /* resume signaling for 20 msec */
ehci->reset_done[wIndex] = jiffies ehci->reset_done[wIndex] = jiffies
+ msecs_to_jiffies(20); + msecs_to_jiffies(20);
usb_hcd_start_port_resume(&hcd->self, wIndex);
/* check the port again */ /* check the port again */
mod_timer(&ehci_to_hcd(ehci)->rh_timer, mod_timer(&ehci_to_hcd(ehci)->rh_timer,
ehci->reset_done[wIndex]); ehci->reset_done[wIndex]);
...@@ -862,6 +867,7 @@ static int ehci_hub_control ( ...@@ -862,6 +867,7 @@ static int ehci_hub_control (
clear_bit(wIndex, &ehci->suspended_ports); clear_bit(wIndex, &ehci->suspended_ports);
set_bit(wIndex, &ehci->port_c_suspend); set_bit(wIndex, &ehci->port_c_suspend);
ehci->reset_done[wIndex] = 0; ehci->reset_done[wIndex] = 0;
usb_hcd_end_port_resume(&hcd->self, wIndex);
/* stop resume signaling */ /* stop resume signaling */
temp = ehci_readl(ehci, status_reg); temp = ehci_readl(ehci, status_reg);
...@@ -950,6 +956,7 @@ static int ehci_hub_control ( ...@@ -950,6 +956,7 @@ static int ehci_hub_control (
ehci->reset_done[wIndex] = 0; ehci->reset_done[wIndex] = 0;
if (temp & PORT_PE) if (temp & PORT_PE)
set_bit(wIndex, &ehci->port_c_suspend); set_bit(wIndex, &ehci->port_c_suspend);
usb_hcd_end_port_resume(&hcd->self, wIndex);
} }
if (temp & PORT_OC) if (temp & PORT_OC)
......
...@@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested) ...@@ -1197,17 +1197,26 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested)
if (ehci->async_iaa || ehci->async_unlinking) if (ehci->async_iaa || ehci->async_unlinking)
return; return;
/* Do all the waiting QHs at once */
ehci->async_iaa = ehci->async_unlink;
ehci->async_unlink = NULL;
/* If the controller isn't running, we don't have to wait for it */ /* If the controller isn't running, we don't have to wait for it */
if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) { if (unlikely(ehci->rh_state < EHCI_RH_RUNNING)) {
/* Do all the waiting QHs */
ehci->async_iaa = ehci->async_unlink;
ehci->async_unlink = NULL;
if (!nested) /* Avoid recursion */ if (!nested) /* Avoid recursion */
end_unlink_async(ehci); end_unlink_async(ehci);
/* Otherwise start a new IAA cycle */ /* Otherwise start a new IAA cycle */
} else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) { } else if (likely(ehci->rh_state == EHCI_RH_RUNNING)) {
struct ehci_qh *qh;
/* Do only the first waiting QH (nVidia bug?) */
qh = ehci->async_unlink;
ehci->async_iaa = qh;
ehci->async_unlink = qh->unlink_next;
qh->unlink_next = NULL;
/* Make sure the unlinks are all visible to the hardware */ /* Make sure the unlinks are all visible to the hardware */
wmb(); wmb();
...@@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci) ...@@ -1255,34 +1264,35 @@ static void end_unlink_async(struct ehci_hcd *ehci)
} }
} }
static void start_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh);
static void unlink_empty_async(struct ehci_hcd *ehci) static void unlink_empty_async(struct ehci_hcd *ehci)
{ {
struct ehci_qh *qh, *next; struct ehci_qh *qh;
bool stopped = (ehci->rh_state < EHCI_RH_RUNNING); struct ehci_qh *qh_to_unlink = NULL;
bool check_unlinks_later = false; bool check_unlinks_later = false;
int count = 0;
/* Unlink all the async QHs that have been empty for a timer cycle */ /* Find the last async QH which has been empty for a timer cycle */
next = ehci->async->qh_next.qh; for (qh = ehci->async->qh_next.qh; qh; qh = qh->qh_next.qh) {
while (next) {
qh = next;
next = qh->qh_next.qh;
if (list_empty(&qh->qtd_list) && if (list_empty(&qh->qtd_list) &&
qh->qh_state == QH_STATE_LINKED) { qh->qh_state == QH_STATE_LINKED) {
if (!stopped && qh->unlink_cycle == ++count;
ehci->async_unlink_cycle) if (qh->unlink_cycle == ehci->async_unlink_cycle)
check_unlinks_later = true; check_unlinks_later = true;
else else
single_unlink_async(ehci, qh); qh_to_unlink = qh;
} }
} }
/* Start a new IAA cycle if any QHs are waiting for it */ /* If nothing else is being unlinked, unlink the last empty QH */
if (ehci->async_unlink) if (!ehci->async_iaa && !ehci->async_unlink && qh_to_unlink) {
start_iaa_cycle(ehci, false); start_unlink_async(ehci, qh_to_unlink);
--count;
}
/* QHs that haven't been empty for long enough will be handled later */ /* Other QHs will be handled later */
if (check_unlinks_later) { if (count > 0) {
ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true); ehci_enable_event(ehci, EHCI_HRTIMER_ASYNC_UNLINKS, true);
++ehci->async_unlink_cycle; ++ehci->async_unlink_cycle;
} }
......
...@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask) ...@@ -213,7 +213,7 @@ static inline unsigned char tt_start_uframe(struct ehci_hcd *ehci, __hc32 mask)
} }
static const unsigned char static const unsigned char
max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 30, 0 }; max_tt_usecs[] = { 125, 125, 125, 125, 125, 125, 125, 25 };
/* carryover low/fullspeed bandwidth that crosses uframe boundries */ /* carryover low/fullspeed bandwidth that crosses uframe boundries */
static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8]) static inline void carryover_tt_bandwidth(unsigned short tt_usecs[8])
...@@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci) ...@@ -2212,11 +2212,11 @@ static void scan_isoc(struct ehci_hcd *ehci)
} }
ehci->now_frame = now_frame; ehci->now_frame = now_frame;
frame = ehci->last_iso_frame;
for (;;) { for (;;) {
union ehci_shadow q, *q_p; union ehci_shadow q, *q_p;
__hc32 type, *hw_p; __hc32 type, *hw_p;
frame = ehci->last_iso_frame;
restart: restart:
/* scan each element in frame's queue for completions */ /* scan each element in frame's queue for completions */
q_p = &ehci->pshadow [frame]; q_p = &ehci->pshadow [frame];
...@@ -2321,6 +2321,9 @@ static void scan_isoc(struct ehci_hcd *ehci) ...@@ -2321,6 +2321,9 @@ static void scan_isoc(struct ehci_hcd *ehci)
/* Stop when we have reached the current frame */ /* Stop when we have reached the current frame */
if (frame == now_frame) if (frame == now_frame)
break; break;
ehci->last_iso_frame = (frame + 1) & fmask;
/* The last frame may still have active siTDs */
ehci->last_iso_frame = frame;
frame = (frame + 1) & fmask;
} }
} }
...@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci) ...@@ -113,14 +113,15 @@ static void ehci_poll_ASS(struct ehci_hcd *ehci)
if (want != actual) { if (want != actual) {
/* Poll again later, but give up after about 20 ms */ /* Poll again later */
if (ehci->ASS_poll_count++ < 20) { ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true);
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_ASS, true); ++ehci->ASS_poll_count;
return; return;
}
ehci_dbg(ehci, "Waited too long for the async schedule status (%x/%x), giving up\n",
want, actual);
} }
if (ehci->ASS_poll_count > 20)
ehci_dbg(ehci, "ASS poll count reached %d\n",
ehci->ASS_poll_count);
ehci->ASS_poll_count = 0; ehci->ASS_poll_count = 0;
/* The status is up-to-date; restart or stop the schedule as needed */ /* The status is up-to-date; restart or stop the schedule as needed */
...@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci) ...@@ -159,14 +160,14 @@ static void ehci_poll_PSS(struct ehci_hcd *ehci)
if (want != actual) { if (want != actual) {
/* Poll again later, but give up after about 20 ms */ /* Poll again later */
if (ehci->PSS_poll_count++ < 20) { ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true);
ehci_enable_event(ehci, EHCI_HRTIMER_POLL_PSS, true); return;
return;
}
ehci_dbg(ehci, "Waited too long for the periodic schedule status (%x/%x), giving up\n",
want, actual);
} }
if (ehci->PSS_poll_count > 20)
ehci_dbg(ehci, "PSS poll count reached %d\n",
ehci->PSS_poll_count);
ehci->PSS_poll_count = 0; ehci->PSS_poll_count = 0;
/* The status is up-to-date; restart or stop the schedule as needed */ /* The status is up-to-date; restart or stop the schedule as needed */
......
...@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) ...@@ -780,6 +780,7 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev)
"defaulting to EHCI.\n"); "defaulting to EHCI.\n");
dev_warn(&xhci_pdev->dev, dev_warn(&xhci_pdev->dev,
"USB 3.0 devices will work at USB 2.0 speeds.\n"); "USB 3.0 devices will work at USB 2.0 speeds.\n");
usb_disable_xhci_ports(xhci_pdev);
return; return;
} }
......
...@@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port, ...@@ -116,6 +116,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
} }
} }
clear_bit(port, &uhci->resuming_ports); clear_bit(port, &uhci->resuming_ports);
usb_hcd_end_port_resume(&uhci_to_hcd(uhci)->self, port);
} }
/* Wait for the UHCI controller in HP's iLO2 server management chip. /* Wait for the UHCI controller in HP's iLO2 server management chip.
...@@ -167,6 +168,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci) ...@@ -167,6 +168,8 @@ static void uhci_check_ports(struct uhci_hcd *uhci)
set_bit(port, &uhci->resuming_ports); set_bit(port, &uhci->resuming_ports);
uhci->ports_timeout = jiffies + uhci->ports_timeout = jiffies +
msecs_to_jiffies(25); msecs_to_jiffies(25);
usb_hcd_start_port_resume(
&uhci_to_hcd(uhci)->self, port);
/* Make sure we see the port again /* Make sure we see the port again
* after the resuming period is over. */ * after the resuming period is over. */
......
...@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci, ...@@ -1698,7 +1698,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
faked_port_index + 1); faked_port_index + 1);
if (slot_id && xhci->devs[slot_id]) if (slot_id && xhci->devs[slot_id])
xhci_ring_device(xhci, slot_id); xhci_ring_device(xhci, slot_id);
if (bus_state->port_remote_wakeup && (1 << faked_port_index)) { if (bus_state->port_remote_wakeup & (1 << faked_port_index)) {
bus_state->port_remote_wakeup &= bus_state->port_remote_wakeup &=
~(1 << faked_port_index); ~(1 << faked_port_index);
xhci_test_and_clear_bit(xhci, port_array, xhci_test_and_clear_bit(xhci, port_array,
...@@ -2589,6 +2589,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, ...@@ -2589,6 +2589,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
(trb_comp_code != COMP_STALL && (trb_comp_code != COMP_STALL &&
trb_comp_code != COMP_BABBLE)) trb_comp_code != COMP_BABBLE))
xhci_urb_free_priv(xhci, urb_priv); xhci_urb_free_priv(xhci, urb_priv);
else
kfree(urb_priv);
usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb);
if ((urb->actual_length != urb->transfer_buffer_length && if ((urb->actual_length != urb->transfer_buffer_length &&
...@@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len, ...@@ -3108,7 +3110,7 @@ static u32 xhci_v1_0_td_remainder(int running_total, int trb_buff_len,
* running_total. * running_total.
*/ */
packets_transferred = (running_total + trb_buff_len) / packets_transferred = (running_total + trb_buff_len) /
usb_endpoint_maxp(&urb->ep->desc); GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc));
if ((total_packet_count - packets_transferred) > 31) if ((total_packet_count - packets_transferred) > 31)
return 31 << 17; return 31 << 17;
...@@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3642,7 +3644,8 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
td_len = urb->iso_frame_desc[i].length; td_len = urb->iso_frame_desc[i].length;
td_remain_len = td_len; td_remain_len = td_len;
total_packet_count = DIV_ROUND_UP(td_len, total_packet_count = DIV_ROUND_UP(td_len,
usb_endpoint_maxp(&urb->ep->desc)); GET_MAX_PACKET(
usb_endpoint_maxp(&urb->ep->desc)));
/* A zero-length transfer still involves at least one packet. */ /* A zero-length transfer still involves at least one packet. */
if (total_packet_count == 0) if (total_packet_count == 0)
total_packet_count++; total_packet_count++;
...@@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, ...@@ -3664,9 +3667,11 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
td = urb_priv->td[i]; td = urb_priv->td[i];
for (j = 0; j < trbs_per_td; j++) { for (j = 0; j < trbs_per_td; j++) {
u32 remainder = 0; u32 remainder = 0;
field = TRB_TBC(burst_count) | TRB_TLBPC(residue); field = 0;
if (first_trb) { if (first_trb) {
field = TRB_TBC(burst_count) |
TRB_TLBPC(residue);
/* Queue the isoc TRB */ /* Queue the isoc TRB */
field |= TRB_TYPE(TRB_ISOC); field |= TRB_TYPE(TRB_ISOC);
/* Assume URB_ISO_ASAP is set */ /* Assume URB_ISO_ASAP is set */
......
...@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = { ...@@ -60,6 +60,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
{ USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */ { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
{ USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */ { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
{ USB_DEVICE(0x0FDE, 0xCA05) }, /* OWL Wireless Electricity Monitor CM-160 */
{ USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */
{ USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */
{ USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */ { USB_DEVICE(0x10B5, 0xAC70) }, /* Nokia CA-42 USB */
......
...@@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -584,6 +584,7 @@ static struct usb_device_id id_table_combined [] = {
/* /*
* ELV devices: * ELV devices:
*/ */
{ USB_DEVICE(FTDI_ELV_VID, FTDI_ELV_WS300_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) },
...@@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -670,6 +671,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_5_PID) },
{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_6_PID) },
{ USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) }, { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_7_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_OMNI1509) },
{ USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) },
{ USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) }, { USB_DEVICE(FTDI_VID, FTDI_MHAM_KW_PID) },
......
...@@ -147,6 +147,11 @@ ...@@ -147,6 +147,11 @@
#define XSENS_CONVERTER_6_PID 0xD38E #define XSENS_CONVERTER_6_PID 0xD38E
#define XSENS_CONVERTER_7_PID 0xD38F #define XSENS_CONVERTER_7_PID 0xD38F
/**
* Zolix (www.zolix.com.cb) product ids
*/
#define FTDI_OMNI1509 0xD491 /* Omni1509 embedded USB-serial */
/* /*
* NDI (www.ndigital.com) product ids * NDI (www.ndigital.com) product ids
*/ */
...@@ -204,7 +209,7 @@ ...@@ -204,7 +209,7 @@
/* /*
* ELV USB devices submitted by Christian Abt of ELV (www.elv.de). * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
* All of these devices use FTDI's vendor ID (0x0403). * Almost all of these devices use FTDI's vendor ID (0x0403).
* Further IDs taken from ELV Windows .inf file. * Further IDs taken from ELV Windows .inf file.
* *
* The previously included PID for the UO 100 module was incorrect. * The previously included PID for the UO 100 module was incorrect.
...@@ -212,6 +217,8 @@ ...@@ -212,6 +217,8 @@
* *
* Armin Laeuger originally sent the PID for the UM 100 module. * Armin Laeuger originally sent the PID for the UM 100 module.
*/ */
#define FTDI_ELV_VID 0x1B1F /* ELV AG */
#define FTDI_ELV_WS300_PID 0xC006 /* eQ3 WS 300 PC II */
#define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */ #define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */
#define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */ #define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */
#define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */ #define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */
......
...@@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb); ...@@ -242,6 +242,7 @@ static void option_instat_callback(struct urb *urb);
#define TELIT_PRODUCT_CC864_DUAL 0x1005 #define TELIT_PRODUCT_CC864_DUAL 0x1005
#define TELIT_PRODUCT_CC864_SINGLE 0x1006 #define TELIT_PRODUCT_CC864_SINGLE 0x1006
#define TELIT_PRODUCT_DE910_DUAL 0x1010 #define TELIT_PRODUCT_DE910_DUAL 0x1010
#define TELIT_PRODUCT_LE920 0x1200
/* ZTE PRODUCTS */ /* ZTE PRODUCTS */
#define ZTE_VENDOR_ID 0x19d2 #define ZTE_VENDOR_ID 0x19d2
...@@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb); ...@@ -453,6 +454,10 @@ static void option_instat_callback(struct urb *urb);
#define TPLINK_VENDOR_ID 0x2357 #define TPLINK_VENDOR_ID 0x2357
#define TPLINK_PRODUCT_MA180 0x0201 #define TPLINK_PRODUCT_MA180 0x0201
/* Changhong products */
#define CHANGHONG_VENDOR_ID 0x2077
#define CHANGHONG_PRODUCT_CH690 0x7001
/* some devices interfaces need special handling due to a number of reasons */ /* some devices interfaces need special handling due to a number of reasons */
enum option_blacklist_reason { enum option_blacklist_reason {
OPTION_BLACKLIST_NONE = 0, OPTION_BLACKLIST_NONE = 0,
...@@ -534,6 +539,11 @@ static const struct option_blacklist_info zte_1255_blacklist = { ...@@ -534,6 +539,11 @@ static const struct option_blacklist_info zte_1255_blacklist = {
.reserved = BIT(3) | BIT(4), .reserved = BIT(3) | BIT(4),
}; };
static const struct option_blacklist_info telit_le920_blacklist = {
.sendsetup = BIT(0),
.reserved = BIT(1) | BIT(5),
};
static const struct usb_device_id option_ids[] = { static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
...@@ -784,6 +794,8 @@ static const struct usb_device_id option_ids[] = { ...@@ -784,6 +794,8 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) }, { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf1_blacklist }, .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
...@@ -1318,6 +1330,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -1318,6 +1330,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) }, { USB_DEVICE(PETATEL_VENDOR_ID, PETATEL_PRODUCT_NP10T) },
{ USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180), { USB_DEVICE(TPLINK_VENDOR_ID, TPLINK_PRODUCT_MA180),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist }, .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE(CHANGHONG_VENDOR_ID, CHANGHONG_PRODUCT_CH690) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
MODULE_DEVICE_TABLE(usb, option_ids); MODULE_DEVICE_TABLE(usb, option_ids);
......
...@@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = { ...@@ -53,6 +53,7 @@ static const struct usb_device_id id_table[] = {
{DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */ {DEVICE_G1K(0x05c6, 0x9221)}, /* Generic Gobi QDL device */
{DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */ {DEVICE_G1K(0x05c6, 0x9231)}, /* Generic Gobi QDL device */
{DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */ {DEVICE_G1K(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */
{DEVICE_G1K(0x1bc7, 0x900e)}, /* Telit Gobi QDL device */
/* Gobi 2000 devices */ /* Gobi 2000 devices */
{USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */ {USB_DEVICE(0x1410, 0xa010)}, /* Novatel Gobi 2000 QDL device */
......
...@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) ...@@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us)
return 0; return 0;
} }
/* This places the HUAWEI E220 devices in multi-port mode */ /* This places the HUAWEI usb dongles in multi-port mode */
int usb_stor_huawei_e220_init(struct us_data *us) static int usb_stor_huawei_feature_init(struct us_data *us)
{ {
int result; int result;
...@@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us) ...@@ -104,3 +104,75 @@ int usb_stor_huawei_e220_init(struct us_data *us)
US_DEBUGP("Huawei mode set result is %d\n", result); US_DEBUGP("Huawei mode set result is %d\n", result);
return 0; return 0;
} }
/*
* It will send a scsi switch command called rewind' to huawei dongle.
* When the dongle receives this command at the first time,
* it will reboot immediately. After rebooted, it will ignore this command.
* So it is unnecessary to read its response.
*/
static int usb_stor_huawei_scsi_init(struct us_data *us)
{
int result = 0;
int act_len = 0;
struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
bcbw->Tag = 0;
bcbw->DataTransferLength = 0;
bcbw->Flags = bcbw->Lun = 0;
bcbw->Length = sizeof(rewind_cmd);
memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
US_BULK_CB_WRAP_LEN, &act_len);
US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result);
return result;
}
/*
* It tries to find the supported Huawei USB dongles.
* In Huawei, they assign the following product IDs
* for all of their mobile broadband dongles,
* including the new dongles in the future.
* So if the product ID is not included in this list,
* it means it is not Huawei's mobile broadband dongles.
*/
static int usb_stor_huawei_dongles_pid(struct us_data *us)
{
struct usb_interface_descriptor *idesc;
int idProduct;
idesc = &us->pusb_intf->cur_altsetting->desc;
idProduct = us->pusb_dev->descriptor.idProduct;
/* The first port is CDROM,
* means the dongle in the single port mode,
* and a switch command is required to be sent. */
if (idesc && idesc->bInterfaceNumber == 0) {
if ((idProduct == 0x1001)
|| (idProduct == 0x1003)
|| (idProduct == 0x1004)
|| (idProduct >= 0x1401 && idProduct <= 0x1500)
|| (idProduct >= 0x1505 && idProduct <= 0x1600)
|| (idProduct >= 0x1c02 && idProduct <= 0x2202)) {
return 1;
}
}
return 0;
}
int usb_stor_huawei_init(struct us_data *us)
{
int result = 0;
if (usb_stor_huawei_dongles_pid(us)) {
if (us->pusb_dev->descriptor.idProduct >= 0x1446)
result = usb_stor_huawei_scsi_init(us);
else
result = usb_stor_huawei_feature_init(us);
}
return result;
}
...@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); ...@@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us);
* flash reader */ * flash reader */
int usb_stor_ucr61s2b_init(struct us_data *us); int usb_stor_ucr61s2b_init(struct us_data *us);
/* This places the HUAWEI E220 devices in multi-port mode */ /* This places the HUAWEI usb dongles in multi-port mode */
int usb_stor_huawei_e220_init(struct us_data *us); int usb_stor_huawei_init(struct us_data *us);
...@@ -1527,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, ...@@ -1527,335 +1527,10 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100,
/* Reported by fangxiaozhi <huananhu@huawei.com> /* Reported by fangxiaozhi <huananhu@huawei.com>
* This brings the HUAWEI data card devices into multi-port mode * This brings the HUAWEI data card devices into multi-port mode
*/ */
UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
"HUAWEI MOBILE", "HUAWEI MOBILE",
"Mass Storage", "Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000,
"HUAWEI MOBILE",
"Mass Storage",
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0), 0),
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
......
...@@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); ...@@ -120,6 +120,17 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks");
.useTransport = use_transport, \ .useTransport = use_transport, \
} }
#define UNUSUAL_VENDOR_INTF(idVendor, cl, sc, pr, \
vendor_name, product_name, use_protocol, use_transport, \
init_function, Flags) \
{ \
.vendorName = vendor_name, \
.productName = product_name, \
.useProtocol = use_protocol, \
.useTransport = use_transport, \
.initFunction = init_function, \
}
static struct us_unusual_dev us_unusual_dev_list[] = { static struct us_unusual_dev us_unusual_dev_list[] = {
# include "unusual_devs.h" # include "unusual_devs.h"
{ } /* Terminating entry */ { } /* Terminating entry */
...@@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids = ...@@ -131,6 +142,7 @@ static struct us_unusual_dev for_dynamic_ids =
#undef UNUSUAL_DEV #undef UNUSUAL_DEV
#undef COMPLIANT_DEV #undef COMPLIANT_DEV
#undef USUAL_DEV #undef USUAL_DEV
#undef UNUSUAL_VENDOR_INTF
#ifdef CONFIG_LOCKDEP #ifdef CONFIG_LOCKDEP
......
...@@ -41,6 +41,20 @@ ...@@ -41,6 +41,20 @@
#define USUAL_DEV(useProto, useTrans) \ #define USUAL_DEV(useProto, useTrans) \
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) } { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans) }
/* Define the device is matched with Vendor ID and interface descriptors */
#define UNUSUAL_VENDOR_INTF(id_vendor, cl, sc, pr, \
vendorName, productName, useProtocol, useTransport, \
initFunction, flags) \
{ \
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO \
| USB_DEVICE_ID_MATCH_VENDOR, \
.idVendor = (id_vendor), \
.bInterfaceClass = (cl), \
.bInterfaceSubClass = (sc), \
.bInterfaceProtocol = (pr), \
.driver_info = (flags) \
}
struct usb_device_id usb_storage_usb_ids[] = { struct usb_device_id usb_storage_usb_ids[] = {
# include "unusual_devs.h" # include "unusual_devs.h"
{ } /* Terminating entry */ { } /* Terminating entry */
...@@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); ...@@ -50,6 +64,7 @@ MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
#undef UNUSUAL_DEV #undef UNUSUAL_DEV
#undef COMPLIANT_DEV #undef COMPLIANT_DEV
#undef USUAL_DEV #undef USUAL_DEV
#undef UNUSUAL_VENDOR_INTF
/* /*
* The table of devices to ignore * The table of devices to ignore
......
...@@ -1017,7 +1017,7 @@ static const char *fbcon_startup(void) ...@@ -1017,7 +1017,7 @@ static const char *fbcon_startup(void)
} }
/* Setup default font */ /* Setup default font */
if (!p->fontdata) { if (!p->fontdata && !vc->vc_font.data) {
if (!fontname[0] || !(font = find_font(fontname))) if (!fontname[0] || !(font = find_font(fontname)))
font = get_default_font(info->var.xres, font = get_default_font(info->var.xres,
info->var.yres, info->var.yres,
...@@ -1027,6 +1027,8 @@ static const char *fbcon_startup(void) ...@@ -1027,6 +1027,8 @@ static const char *fbcon_startup(void)
vc->vc_font.height = font->height; vc->vc_font.height = font->height;
vc->vc_font.data = (void *)(p->fontdata = font->data); vc->vc_font.data = (void *)(p->fontdata = font->data);
vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */ vc->vc_font.charcount = 256; /* FIXME Need to support more fonts */
} else {
p->fontdata = vc->vc_font.data;
} }
cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
...@@ -1186,9 +1188,9 @@ static void fbcon_init(struct vc_data *vc, int init) ...@@ -1186,9 +1188,9 @@ static void fbcon_init(struct vc_data *vc, int init)
ops->p = &fb_display[fg_console]; ops->p = &fb_display[fg_console];
} }
static void fbcon_free_font(struct display *p) static void fbcon_free_font(struct display *p, bool freefont)
{ {
if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0))
kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int));
p->fontdata = NULL; p->fontdata = NULL;
p->userfont = 0; p->userfont = 0;
...@@ -1200,8 +1202,8 @@ static void fbcon_deinit(struct vc_data *vc) ...@@ -1200,8 +1202,8 @@ static void fbcon_deinit(struct vc_data *vc)
struct fb_info *info; struct fb_info *info;
struct fbcon_ops *ops; struct fbcon_ops *ops;
int idx; int idx;
bool free_font = true;
fbcon_free_font(p);
idx = con2fb_map[vc->vc_num]; idx = con2fb_map[vc->vc_num];
if (idx == -1) if (idx == -1)
...@@ -1212,6 +1214,8 @@ static void fbcon_deinit(struct vc_data *vc) ...@@ -1212,6 +1214,8 @@ static void fbcon_deinit(struct vc_data *vc)
if (!info) if (!info)
goto finished; goto finished;
if (info->flags & FBINFO_MISC_FIRMWARE)
free_font = false;
ops = info->fbcon_par; ops = info->fbcon_par;
if (!ops) if (!ops)
...@@ -1223,6 +1227,8 @@ static void fbcon_deinit(struct vc_data *vc) ...@@ -1223,6 +1227,8 @@ static void fbcon_deinit(struct vc_data *vc)
ops->flags &= ~FBCON_FLAGS_INIT; ops->flags &= ~FBCON_FLAGS_INIT;
finished: finished:
fbcon_free_font(p, free_font);
if (!con_is_bound(&fb_con)) if (!con_is_bound(&fb_con))
fbcon_exit(); fbcon_exit();
......
...@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) ...@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
unsigned short video_port_status = vga_video_port_reg + 6; unsigned short video_port_status = vga_video_port_reg + 6;
int font_select = 0x00, beg, i; int font_select = 0x00, beg, i;
char *charmap; char *charmap;
bool clear_attribs = false;
if (vga_video_type != VIDEO_TYPE_EGAM) { if (vga_video_type != VIDEO_TYPE_EGAM) {
charmap = (char *) VGA_MAP_MEM(colourmap, 0); charmap = (char *) VGA_MAP_MEM(colourmap, 0);
beg = 0x0e; beg = 0x0e;
...@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) ...@@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
/* if 512 char mode is already enabled don't re-enable it. */ /* if 512 char mode is already enabled don't re-enable it. */
if ((set) && (ch512 != vga_512_chars)) { if ((set) && (ch512 != vga_512_chars)) {
/* attribute controller */
for (i = 0; i < MAX_NR_CONSOLES; i++) {
struct vc_data *c = vc_cons[i].d;
if (c && c->vc_sw == &vga_con)
c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
}
vga_512_chars = ch512; vga_512_chars = ch512;
/* 256-char: enable intensity bit /* 256-char: enable intensity bit
512-char: disable intensity bit */ 512-char: disable intensity bit */
...@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) ...@@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512)
it means, but it works, and it appears necessary */ it means, but it works, and it appears necessary */
inb_p(video_port_status); inb_p(video_port_status);
vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
clear_attribs = true;
} }
raw_spin_unlock_irq(&vga_lock); raw_spin_unlock_irq(&vga_lock);
if (clear_attribs) {
for (i = 0; i < MAX_NR_CONSOLES; i++) {
struct vc_data *c = vc_cons[i].d;
if (c && c->vc_sw == &vga_con) {
/* force hi font mask to 0, so we always clear
the bit on either transition */
c->vc_hi_font_mask = 0x00;
clear_buffer_attributes(c);
c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
}
}
}
return 0; return 0;
} }
......
...@@ -503,11 +503,11 @@ static ssize_t device_write(struct file *file, const char __user *buf, ...@@ -503,11 +503,11 @@ static ssize_t device_write(struct file *file, const char __user *buf,
#endif #endif
return -EINVAL; return -EINVAL;
#ifdef CONFIG_COMPAT /*
if (count > sizeof(struct dlm_write_request32) + DLM_RESNAME_MAXLEN) * can't compare against COMPAT/dlm_write_request32 because
#else * we don't yet know if is64bit is zero
*/
if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN) if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
#endif
return -EINVAL; return -EINVAL;
kbuf = kzalloc(count + 1, GFP_NOFS); kbuf = kzalloc(count + 1, GFP_NOFS);
......
...@@ -664,8 +664,11 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp, ...@@ -664,8 +664,11 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
if (ret < 0) if (ret < 0)
printk(KERN_ERR "NILFS: GC failed during preparation: " printk(KERN_ERR "NILFS: GC failed during preparation: "
"cannot read source blocks: err=%d\n", ret); "cannot read source blocks: err=%d\n", ret);
else else {
if (nilfs_sb_need_update(nilfs))
set_nilfs_discontinued(nilfs);
ret = nilfs_clean_segments(inode->i_sb, argv, kbufs); ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
}
nilfs_remove_all_gcinodes(nilfs); nilfs_remove_all_gcinodes(nilfs);
clear_nilfs_gc_running(nilfs); clear_nilfs_gc_running(nilfs);
......
...@@ -429,7 +429,7 @@ extern int memcg_limited_groups_array_size; ...@@ -429,7 +429,7 @@ extern int memcg_limited_groups_array_size;
* the slab_mutex must be held when looping through those caches * the slab_mutex must be held when looping through those caches
*/ */
#define for_each_memcg_cache_index(_idx) \ #define for_each_memcg_cache_index(_idx) \
for ((_idx) = 0; i < memcg_limited_groups_array_size; (_idx)++) for ((_idx) = 0; (_idx) < memcg_limited_groups_array_size; (_idx)++)
static inline bool memcg_kmem_enabled(void) static inline bool memcg_kmem_enabled(void)
{ {
......
...@@ -151,7 +151,7 @@ struct mmu_notifier_ops { ...@@ -151,7 +151,7 @@ struct mmu_notifier_ops {
* Therefore notifier chains can only be traversed when either * Therefore notifier chains can only be traversed when either
* *
* 1. mmap_sem is held. * 1. mmap_sem is held.
* 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->mutex). * 2. One of the reverse map locks is held (i_mmap_mutex or anon_vma->rwsem).
* 3. No other concurrent thread can access the list (release) * 3. No other concurrent thread can access the list (release)
*/ */
struct mmu_notifier { struct mmu_notifier {
......
...@@ -357,6 +357,8 @@ struct usb_bus { ...@@ -357,6 +357,8 @@ struct usb_bus {
int bandwidth_int_reqs; /* number of Interrupt requests */ int bandwidth_int_reqs; /* number of Interrupt requests */
int bandwidth_isoc_reqs; /* number of Isoc. requests */ int bandwidth_isoc_reqs; /* number of Isoc. requests */
unsigned resuming_ports; /* bit array: resuming root-hub ports */
#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE)
struct mon_bus *mon_bus; /* non-null when associated */ struct mon_bus *mon_bus; /* non-null when associated */
int monitored; /* non-zero when monitored */ int monitored; /* non-zero when monitored */
......
...@@ -430,6 +430,9 @@ extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd); ...@@ -430,6 +430,9 @@ extern void usb_hcd_poll_rh_status(struct usb_hcd *hcd);
extern void usb_wakeup_notification(struct usb_device *hdev, extern void usb_wakeup_notification(struct usb_device *hdev,
unsigned int portnum); unsigned int portnum);
extern void usb_hcd_start_port_resume(struct usb_bus *bus, int portnum);
extern void usb_hcd_end_port_resume(struct usb_bus *bus, int portnum);
/* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */ /* The D0/D1 toggle bits ... USE WITH CAUTION (they're almost hcd-internal) */
#define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1) #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> (ep)) & 1)
#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep))) #define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << (ep)))
......
...@@ -47,6 +47,7 @@ int con_set_cmap(unsigned char __user *cmap); ...@@ -47,6 +47,7 @@ int con_set_cmap(unsigned char __user *cmap);
int con_get_cmap(unsigned char __user *cmap); int con_get_cmap(unsigned char __user *cmap);
void scrollback(struct vc_data *vc, int lines); void scrollback(struct vc_data *vc, int lines);
void scrollfront(struct vc_data *vc, int lines); void scrollfront(struct vc_data *vc, int lines);
void clear_buffer_attributes(struct vc_data *vc);
void update_region(struct vc_data *vc, unsigned long start, int count); void update_region(struct vc_data *vc, unsigned long start, int count);
void redraw_screen(struct vc_data *vc, int is_switch); void redraw_screen(struct vc_data *vc, int is_switch);
#define update_screen(x) redraw_screen(x, 0) #define update_screen(x) redraw_screen(x, 0)
......
...@@ -152,6 +152,12 @@ ...@@ -152,6 +152,12 @@
#define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0)) #define USB_INTRF_FUNC_SUSPEND_LP (1 << (8 + 0))
#define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1)) #define USB_INTRF_FUNC_SUSPEND_RW (1 << (8 + 1))
/*
* Interface status, Figure 9-5 USB 3.0 spec
*/
#define USB_INTRF_STAT_FUNC_RW_CAP 1
#define USB_INTRF_STAT_FUNC_RW 2
#define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */ #define USB_ENDPOINT_HALT 0 /* IN/OUT will STALL */
/* Bit array elements as returned by the USB_REQ_GET_STATUS request. */ /* Bit array elements as returned by the USB_REQ_GET_STATUS request. */
......
...@@ -1257,6 +1257,10 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, ...@@ -1257,6 +1257,10 @@ struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
if (flags & FOLL_WRITE && !pmd_write(*pmd)) if (flags & FOLL_WRITE && !pmd_write(*pmd))
goto out; goto out;
/* Avoid dumping huge zero page */
if ((flags & FOLL_DUMP) && is_huge_zero_pmd(*pmd))
return ERR_PTR(-EFAULT);
page = pmd_page(*pmd); page = pmd_page(*pmd);
VM_BUG_ON(!PageHead(page)); VM_BUG_ON(!PageHead(page));
if (flags & FOLL_TOUCH) { if (flags & FOLL_TOUCH) {
......
...@@ -3033,6 +3033,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma, ...@@ -3033,6 +3033,7 @@ unsigned long hugetlb_change_protection(struct vm_area_struct *vma,
if (!huge_pte_none(huge_ptep_get(ptep))) { if (!huge_pte_none(huge_ptep_get(ptep))) {
pte = huge_ptep_get_and_clear(mm, address, ptep); pte = huge_ptep_get_and_clear(mm, address, ptep);
pte = pte_mkhuge(pte_modify(pte, newprot)); pte = pte_mkhuge(pte_modify(pte, newprot));
pte = arch_make_huge_pte(pte, vma, NULL, 0);
set_huge_pte_at(mm, address, ptep, pte); set_huge_pte_at(mm, address, ptep, pte);
pages++; pages++;
} }
......
...@@ -160,8 +160,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma, ...@@ -160,8 +160,10 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
if (is_write_migration_entry(entry)) if (is_write_migration_entry(entry))
pte = pte_mkwrite(pte); pte = pte_mkwrite(pte);
#ifdef CONFIG_HUGETLB_PAGE #ifdef CONFIG_HUGETLB_PAGE
if (PageHuge(new)) if (PageHuge(new)) {
pte = pte_mkhuge(pte); pte = pte_mkhuge(pte);
pte = arch_make_huge_pte(pte, vma, new, 0);
}
#endif #endif
flush_cache_page(vma, addr, pte_pfn(pte)); flush_cache_page(vma, addr, pte_pfn(pte));
set_pte_at(mm, addr, ptep, pte); set_pte_at(mm, addr, ptep, pte);
......
...@@ -2943,7 +2943,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping) ...@@ -2943,7 +2943,7 @@ static void vm_lock_mapping(struct mm_struct *mm, struct address_space *mapping)
* vma in this mm is backed by the same anon_vma or address_space. * vma in this mm is backed by the same anon_vma or address_space.
* *
* We can take all the locks in random order because the VM code * We can take all the locks in random order because the VM code
* taking i_mmap_mutex or anon_vma->mutex outside the mmap_sem never * taking i_mmap_mutex or anon_vma->rwsem outside the mmap_sem never
* takes more than one of them in a row. Secondly we're protected * takes more than one of them in a row. Secondly we're protected
* against a concurrent mm_take_all_locks() by the mm_all_locks_mutex. * against a concurrent mm_take_all_locks() by the mm_all_locks_mutex.
* *
......
...@@ -19,6 +19,7 @@ bpf-direct-objs := bpf-direct.o ...@@ -19,6 +19,7 @@ bpf-direct-objs := bpf-direct.o
# Try to match the kernel target. # Try to match the kernel target.
ifndef CONFIG_64BIT ifndef CONFIG_64BIT
ifndef CROSS_COMPILE
# s390 has -m31 flag to build 31 bit binaries # s390 has -m31 flag to build 31 bit binaries
ifndef CONFIG_S390 ifndef CONFIG_S390
...@@ -35,6 +36,7 @@ HOSTLOADLIBES_bpf-direct += $(MFLAG) ...@@ -35,6 +36,7 @@ HOSTLOADLIBES_bpf-direct += $(MFLAG)
HOSTLOADLIBES_bpf-fancy += $(MFLAG) HOSTLOADLIBES_bpf-fancy += $(MFLAG)
HOSTLOADLIBES_dropper += $(MFLAG) HOSTLOADLIBES_dropper += $(MFLAG)
endif endif
endif
# Tell kbuild to always build the programs # Tell kbuild to always build the programs
always := $(hostprogs-y) always := $(hostprogs-y)
...@@ -230,12 +230,12 @@ our $Inline = qr{inline|__always_inline|noinline}; ...@@ -230,12 +230,12 @@ our $Inline = qr{inline|__always_inline|noinline};
our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
our $Lval = qr{$Ident(?:$Member)*}; our $Lval = qr{$Ident(?:$Member)*};
our $Float_hex = qr{(?i:0x[0-9a-f]+p-?[0-9]+[fl]?)}; our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
our $Float_dec = qr{(?i:((?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?))}; our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
our $Float_int = qr{(?i:[0-9]+e-?[0-9]+[fl]?)}; our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
our $Float = qr{$Float_hex|$Float_dec|$Float_int}; our $Float = qr{$Float_hex|$Float_dec|$Float_int};
our $Constant = qr{(?:$Float|(?i:(?:0x[0-9a-f]+|[0-9]+)[ul]*))}; our $Constant = qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*};
our $Assignment = qr{(?:\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=)}; our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
our $Compare = qr{<=|>=|==|!=|<|>}; our $Compare = qr{<=|>=|==|!=|<|>};
our $Operators = qr{ our $Operators = qr{
<=|>=|==|!=| <=|>=|==|!=|
......
slabinfo
page-types
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册