Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (48 commits) USB: Fix Corruption issue in USB ftdi driver ftdi_sio.c USB: option: add PID of Huawei E173s 3G modem OHCI: final fix for NVIDIA problems (I hope) USB: option: release new PID for ZTE 3G modem usb: Netlogic: Fix HC_LENGTH call in ehci-xls.c USB: storage: ene_ub6250: fix compile warnings USB: option: add id for 3G dongle Model VT1000 of Viettel USB: serial: pl2303: rm duplicate id USB: pch_udc: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor USB: pch_udc: Support new device LAPIS Semiconductor ML7831 IOH usb-storage: Accept 8020i-protocol commands longer than 12 bytes USB: quirks: adding more quirky webcams to avoid squeaky audio powerpc/usb: fix type cast for address of ioremap to compatible with 64-bit USB: at91: at91-ohci: fix set/get power USB: cdc-acm: Fix disconnect() vs close() race USB: add quirk for Logitech C600 web cam USB: EHCI: fix HUB TT scheduling issue with iso transfer USB: XHCI: resume root hubs when the controller resumes USB: workaround for bug in old version of GCC USB: ark3116 initialisation fix ...
This commit is contained in:
commit
3c688149ce
|
@ -539,7 +539,6 @@ static void acm_port_down(struct acm *acm)
|
|||
{
|
||||
int i;
|
||||
|
||||
mutex_lock(&open_mutex);
|
||||
if (acm->dev) {
|
||||
usb_autopm_get_interface(acm->control);
|
||||
acm_set_control(acm, acm->ctrlout = 0);
|
||||
|
@ -551,14 +550,15 @@ static void acm_port_down(struct acm *acm)
|
|||
acm->control->needs_remote_wakeup = 0;
|
||||
usb_autopm_put_interface(acm->control);
|
||||
}
|
||||
mutex_unlock(&open_mutex);
|
||||
}
|
||||
|
||||
static void acm_tty_hangup(struct tty_struct *tty)
|
||||
{
|
||||
struct acm *acm = tty->driver_data;
|
||||
tty_port_hangup(&acm->port);
|
||||
mutex_lock(&open_mutex);
|
||||
acm_port_down(acm);
|
||||
mutex_unlock(&open_mutex);
|
||||
}
|
||||
|
||||
static void acm_tty_close(struct tty_struct *tty, struct file *filp)
|
||||
|
@ -569,8 +569,9 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
|
|||
shutdown */
|
||||
if (!acm)
|
||||
return;
|
||||
|
||||
mutex_lock(&open_mutex);
|
||||
if (tty_port_close_start(&acm->port, tty, filp) == 0) {
|
||||
mutex_lock(&open_mutex);
|
||||
if (!acm->dev) {
|
||||
tty_port_tty_set(&acm->port, NULL);
|
||||
acm_tty_unregister(acm);
|
||||
|
@ -582,6 +583,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp)
|
|||
acm_port_down(acm);
|
||||
tty_port_close_end(&acm->port, tty);
|
||||
tty_port_tty_set(&acm->port, NULL);
|
||||
mutex_unlock(&open_mutex);
|
||||
}
|
||||
|
||||
static int acm_tty_write(struct tty_struct *tty,
|
||||
|
|
|
@ -813,6 +813,12 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
|
|||
USB_PORT_FEAT_C_PORT_LINK_STATE);
|
||||
}
|
||||
|
||||
if ((portchange & USB_PORT_STAT_C_BH_RESET) &&
|
||||
hub_is_superspeed(hub->hdev)) {
|
||||
need_debounce_delay = true;
|
||||
clear_port_feature(hub->hdev, port1,
|
||||
USB_PORT_FEAT_C_BH_PORT_RESET);
|
||||
}
|
||||
/* We can forget about a "removed" device when there's a
|
||||
* physical disconnect or the connect status changes.
|
||||
*/
|
||||
|
|
|
@ -50,15 +50,42 @@ static const struct usb_device_id usb_quirk_list[] = {
|
|||
/* Logitech Webcam B/C500 */
|
||||
{ USB_DEVICE(0x046d, 0x0807), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C600 */
|
||||
{ USB_DEVICE(0x046d, 0x0808), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam Pro 9000 */
|
||||
{ USB_DEVICE(0x046d, 0x0809), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C905 */
|
||||
{ USB_DEVICE(0x046d, 0x080a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C210 */
|
||||
{ USB_DEVICE(0x046d, 0x0819), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C260 */
|
||||
{ USB_DEVICE(0x046d, 0x081a), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C310 */
|
||||
{ USB_DEVICE(0x046d, 0x081b), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C910 */
|
||||
{ USB_DEVICE(0x046d, 0x0821), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C160 */
|
||||
{ USB_DEVICE(0x046d, 0x0824), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Webcam C270 */
|
||||
{ USB_DEVICE(0x046d, 0x0825), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam Pro 9000 */
|
||||
{ USB_DEVICE(0x046d, 0x0990), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam E3500 */
|
||||
{ USB_DEVICE(0x046d, 0x09a4), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Quickcam Vision Pro */
|
||||
{ USB_DEVICE(0x046d, 0x09a6), .driver_info = USB_QUIRK_RESET_RESUME },
|
||||
|
||||
/* Logitech Harmony 700-series */
|
||||
{ USB_DEVICE(0x046d, 0xc122), .driver_info = USB_QUIRK_DELAY_INIT },
|
||||
|
||||
|
|
|
@ -1284,6 +1284,7 @@ static int __devinit dwc3_gadget_init_endpoints(struct dwc3 *dwc)
|
|||
int ret;
|
||||
|
||||
dep->endpoint.maxpacket = 1024;
|
||||
dep->endpoint.max_streams = 15;
|
||||
dep->endpoint.ops = &dwc3_gadget_ep_ops;
|
||||
list_add_tail(&dep->endpoint.ep_list,
|
||||
&dwc->gadget.ep_list);
|
||||
|
|
|
@ -469,7 +469,7 @@ config USB_LANGWELL
|
|||
gadget drivers to also be dynamically linked.
|
||||
|
||||
config USB_EG20T
|
||||
tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH UDC"
|
||||
tristate "Intel EG20T PCH/LAPIS Semiconductor IOH(ML7213/ML7831) UDC"
|
||||
depends on PCI
|
||||
select USB_GADGET_DUALSPEED
|
||||
help
|
||||
|
@ -485,10 +485,11 @@ config USB_EG20T
|
|||
This driver dose not support interrupt transfer or isochronous
|
||||
transfer modes.
|
||||
|
||||
This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
|
||||
This driver also can be used for LAPIS Semiconductor's ML7213 which is
|
||||
for IVI(In-Vehicle Infotainment) use.
|
||||
ML7213 is companion chip for Intel Atom E6xx series.
|
||||
ML7213 is completely compatible for Intel EG20T PCH.
|
||||
ML7831 is for general purpose use.
|
||||
ML7213/ML7831 is companion chip for Intel Atom E6xx series.
|
||||
ML7213/ML7831 is completely compatible for Intel EG20T PCH.
|
||||
|
||||
config USB_CI13XXX_MSM
|
||||
tristate "MIPS USB CI13xxx for MSM"
|
||||
|
|
|
@ -122,3 +122,5 @@ static int __init ci13xxx_msm_init(void)
|
|||
return platform_driver_register(&ci13xxx_msm_driver);
|
||||
}
|
||||
module_init(ci13xxx_msm_init);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
/******************************************************************************
|
||||
* DEFINE
|
||||
*****************************************************************************/
|
||||
|
||||
#define DMA_ADDR_INVALID (~(dma_addr_t)0)
|
||||
|
||||
/* ctrl register bank access */
|
||||
static DEFINE_SPINLOCK(udc_lock);
|
||||
|
||||
|
@ -1434,7 +1437,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
|
|||
return -EALREADY;
|
||||
|
||||
mReq->req.status = -EALREADY;
|
||||
if (length && !mReq->req.dma) {
|
||||
if (length && mReq->req.dma == DMA_ADDR_INVALID) {
|
||||
mReq->req.dma = \
|
||||
dma_map_single(mEp->device, mReq->req.buf,
|
||||
length, mEp->dir ? DMA_TO_DEVICE :
|
||||
|
@ -1453,7 +1456,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
|
|||
dma_unmap_single(mEp->device, mReq->req.dma,
|
||||
length, mEp->dir ? DMA_TO_DEVICE :
|
||||
DMA_FROM_DEVICE);
|
||||
mReq->req.dma = 0;
|
||||
mReq->req.dma = DMA_ADDR_INVALID;
|
||||
mReq->map = 0;
|
||||
}
|
||||
return -ENOMEM;
|
||||
|
@ -1549,7 +1552,7 @@ static int _hardware_dequeue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
|
|||
if (mReq->map) {
|
||||
dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
|
||||
mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||
mReq->req.dma = 0;
|
||||
mReq->req.dma = DMA_ADDR_INVALID;
|
||||
mReq->map = 0;
|
||||
}
|
||||
|
||||
|
@ -1610,7 +1613,6 @@ __acquires(mEp->lock)
|
|||
* @gadget: gadget
|
||||
*
|
||||
* This function returns an error code
|
||||
* Caller must hold lock
|
||||
*/
|
||||
static int _gadget_stop_activity(struct usb_gadget *gadget)
|
||||
{
|
||||
|
@ -2189,6 +2191,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags)
|
|||
mReq = kzalloc(sizeof(struct ci13xxx_req), gfp_flags);
|
||||
if (mReq != NULL) {
|
||||
INIT_LIST_HEAD(&mReq->queue);
|
||||
mReq->req.dma = DMA_ADDR_INVALID;
|
||||
|
||||
mReq->ptr = dma_pool_alloc(mEp->td_pool, gfp_flags,
|
||||
&mReq->dma);
|
||||
|
@ -2328,7 +2331,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
|
|||
if (mReq->map) {
|
||||
dma_unmap_single(mEp->device, mReq->req.dma, mReq->req.length,
|
||||
mEp->dir ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
|
||||
mReq->req.dma = 0;
|
||||
mReq->req.dma = DMA_ADDR_INVALID;
|
||||
mReq->map = 0;
|
||||
}
|
||||
req->status = -ECONNRESET;
|
||||
|
@ -2500,12 +2503,12 @@ static int ci13xxx_wakeup(struct usb_gadget *_gadget)
|
|||
spin_lock_irqsave(udc->lock, flags);
|
||||
if (!udc->remote_wakeup) {
|
||||
ret = -EOPNOTSUPP;
|
||||
dbg_trace("remote wakeup feature is not enabled\n");
|
||||
trace("remote wakeup feature is not enabled\n");
|
||||
goto out;
|
||||
}
|
||||
if (!hw_cread(CAP_PORTSC, PORTSC_SUSP)) {
|
||||
ret = -EINVAL;
|
||||
dbg_trace("port is not suspended\n");
|
||||
trace("port is not suspended\n");
|
||||
goto out;
|
||||
}
|
||||
hw_cwrite(CAP_PORTSC, PORTSC_FPR, PORTSC_FPR);
|
||||
|
@ -2703,7 +2706,9 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver)
|
|||
if (udc->udc_driver->notify_event)
|
||||
udc->udc_driver->notify_event(udc,
|
||||
CI13XXX_CONTROLLER_STOPPED_EVENT);
|
||||
spin_unlock_irqrestore(udc->lock, flags);
|
||||
_gadget_stop_activity(&udc->gadget);
|
||||
spin_lock_irqsave(udc->lock, flags);
|
||||
pm_runtime_put(&udc->gadget.dev);
|
||||
}
|
||||
|
||||
|
@ -2850,7 +2855,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev,
|
|||
struct ci13xxx *udc;
|
||||
int retval = 0;
|
||||
|
||||
trace("%p, %p, %p", dev, regs, name);
|
||||
trace("%p, %p, %p", dev, regs, driver->name);
|
||||
|
||||
if (dev == NULL || regs == NULL || driver == NULL ||
|
||||
driver->name == NULL)
|
||||
|
|
|
@ -624,7 +624,8 @@ static int fsg_setup(struct usb_function *f,
|
|||
if (ctrl->bRequestType !=
|
||||
(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
|
||||
break;
|
||||
if (w_index != fsg->interface_number || w_value != 0)
|
||||
if (w_index != fsg->interface_number || w_value != 0 ||
|
||||
w_length != 0)
|
||||
return -EDOM;
|
||||
|
||||
/*
|
||||
|
@ -639,7 +640,8 @@ static int fsg_setup(struct usb_function *f,
|
|||
if (ctrl->bRequestType !=
|
||||
(USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
|
||||
break;
|
||||
if (w_index != fsg->interface_number || w_value != 0)
|
||||
if (w_index != fsg->interface_number || w_value != 0 ||
|
||||
w_length != 1)
|
||||
return -EDOM;
|
||||
VDBG(fsg, "get max LUN\n");
|
||||
*(u8 *)req->buf = fsg->common->nluns - 1;
|
||||
|
|
|
@ -95,7 +95,6 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req);
|
|||
|
||||
DECLARE_UAC_AC_HEADER_DESCRIPTOR(1);
|
||||
DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
|
||||
DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(16);
|
||||
DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
|
||||
|
||||
/* B.3.1 Standard AC Interface Descriptor */
|
||||
|
@ -140,26 +139,6 @@ static struct usb_ms_header_descriptor ms_header_desc __initdata = {
|
|||
/* .wTotalLength = DYNAMIC */
|
||||
};
|
||||
|
||||
/* B.4.3 Embedded MIDI IN Jack Descriptor */
|
||||
static struct usb_midi_in_jack_descriptor jack_in_emb_desc = {
|
||||
.bLength = USB_DT_MIDI_IN_SIZE,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_MIDI_IN_JACK,
|
||||
.bJackType = USB_MS_EMBEDDED,
|
||||
/* .bJackID = DYNAMIC */
|
||||
};
|
||||
|
||||
/* B.4.4 Embedded MIDI OUT Jack Descriptor */
|
||||
static struct usb_midi_out_jack_descriptor_16 jack_out_emb_desc = {
|
||||
/* .bLength = DYNAMIC */
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_MIDI_OUT_JACK,
|
||||
.bJackType = USB_MS_EMBEDDED,
|
||||
/* .bJackID = DYNAMIC */
|
||||
/* .bNrInputPins = DYNAMIC */
|
||||
/* .pins = DYNAMIC */
|
||||
};
|
||||
|
||||
/* B.5.1 Standard Bulk OUT Endpoint Descriptor */
|
||||
static struct usb_endpoint_descriptor bulk_out_desc = {
|
||||
.bLength = USB_DT_ENDPOINT_AUDIO_SIZE,
|
||||
|
@ -758,9 +737,11 @@ fail:
|
|||
static int __init
|
||||
f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_descriptor_header *midi_function[(MAX_PORTS * 2) + 12];
|
||||
struct usb_descriptor_header **midi_function;
|
||||
struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
|
||||
struct usb_midi_in_jack_descriptor jack_in_emb_desc[MAX_PORTS];
|
||||
struct usb_midi_out_jack_descriptor_1 jack_out_ext_desc[MAX_PORTS];
|
||||
struct usb_midi_out_jack_descriptor_1 jack_out_emb_desc[MAX_PORTS];
|
||||
struct usb_composite_dev *cdev = c->cdev;
|
||||
struct f_midi *midi = func_to_midi(f);
|
||||
int status, n, jack = 1, i = 0;
|
||||
|
@ -798,6 +779,14 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
goto fail;
|
||||
midi->out_ep->driver_data = cdev; /* claim */
|
||||
|
||||
/* allocate temporary function list */
|
||||
midi_function = kcalloc((MAX_PORTS * 4) + 9, sizeof(midi_function),
|
||||
GFP_KERNEL);
|
||||
if (!midi_function) {
|
||||
status = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* construct the function's descriptor set. As the number of
|
||||
* input and output MIDI ports is configurable, we have to do
|
||||
|
@ -811,73 +800,74 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
|
||||
/* calculate the header's wTotalLength */
|
||||
n = USB_DT_MS_HEADER_SIZE
|
||||
+ (1 + midi->in_ports) * USB_DT_MIDI_IN_SIZE
|
||||
+ (1 + midi->out_ports) * USB_DT_MIDI_OUT_SIZE(1);
|
||||
+ (midi->in_ports + midi->out_ports) *
|
||||
(USB_DT_MIDI_IN_SIZE + USB_DT_MIDI_OUT_SIZE(1));
|
||||
ms_header_desc.wTotalLength = cpu_to_le16(n);
|
||||
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &ms_header_desc;
|
||||
|
||||
/* we have one embedded IN jack */
|
||||
jack_in_emb_desc.bJackID = jack++;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &jack_in_emb_desc;
|
||||
|
||||
/* and a dynamic amount of external IN jacks */
|
||||
/* configure the external IN jacks, each linked to an embedded OUT jack */
|
||||
for (n = 0; n < midi->in_ports; n++) {
|
||||
struct usb_midi_in_jack_descriptor *ext = &jack_in_ext_desc[n];
|
||||
struct usb_midi_in_jack_descriptor *in_ext = &jack_in_ext_desc[n];
|
||||
struct usb_midi_out_jack_descriptor_1 *out_emb = &jack_out_emb_desc[n];
|
||||
|
||||
ext->bLength = USB_DT_MIDI_IN_SIZE;
|
||||
ext->bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK;
|
||||
ext->bJackType = USB_MS_EXTERNAL;
|
||||
ext->bJackID = jack++;
|
||||
ext->iJack = 0;
|
||||
in_ext->bLength = USB_DT_MIDI_IN_SIZE;
|
||||
in_ext->bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
in_ext->bDescriptorSubtype = USB_MS_MIDI_IN_JACK;
|
||||
in_ext->bJackType = USB_MS_EXTERNAL;
|
||||
in_ext->bJackID = jack++;
|
||||
in_ext->iJack = 0;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) in_ext;
|
||||
|
||||
midi_function[i++] = (struct usb_descriptor_header *) ext;
|
||||
out_emb->bLength = USB_DT_MIDI_OUT_SIZE(1);
|
||||
out_emb->bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
out_emb->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK;
|
||||
out_emb->bJackType = USB_MS_EMBEDDED;
|
||||
out_emb->bJackID = jack++;
|
||||
out_emb->bNrInputPins = 1;
|
||||
out_emb->pins[0].baSourcePin = 1;
|
||||
out_emb->pins[0].baSourceID = in_ext->bJackID;
|
||||
out_emb->iJack = 0;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) out_emb;
|
||||
|
||||
/* link it to the endpoint */
|
||||
ms_in_desc.baAssocJackID[n] = out_emb->bJackID;
|
||||
}
|
||||
|
||||
/* one embedded OUT jack ... */
|
||||
jack_out_emb_desc.bLength = USB_DT_MIDI_OUT_SIZE(midi->in_ports);
|
||||
jack_out_emb_desc.bJackID = jack++;
|
||||
jack_out_emb_desc.bNrInputPins = midi->in_ports;
|
||||
/* ... which referencess all external IN jacks */
|
||||
for (n = 0; n < midi->in_ports; n++) {
|
||||
jack_out_emb_desc.pins[n].baSourceID = jack_in_ext_desc[n].bJackID;
|
||||
jack_out_emb_desc.pins[n].baSourcePin = 1;
|
||||
}
|
||||
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &jack_out_emb_desc;
|
||||
|
||||
/* and multiple external OUT jacks ... */
|
||||
/* configure the external OUT jacks, each linked to an embedded IN jack */
|
||||
for (n = 0; n < midi->out_ports; n++) {
|
||||
struct usb_midi_out_jack_descriptor_1 *ext = &jack_out_ext_desc[n];
|
||||
int m;
|
||||
struct usb_midi_in_jack_descriptor *in_emb = &jack_in_emb_desc[n];
|
||||
struct usb_midi_out_jack_descriptor_1 *out_ext = &jack_out_ext_desc[n];
|
||||
|
||||
ext->bLength = USB_DT_MIDI_OUT_SIZE(1);
|
||||
ext->bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK;
|
||||
ext->bJackType = USB_MS_EXTERNAL;
|
||||
ext->bJackID = jack++;
|
||||
ext->bNrInputPins = 1;
|
||||
ext->iJack = 0;
|
||||
/* ... which all reference the same embedded IN jack */
|
||||
for (m = 0; m < midi->out_ports; m++) {
|
||||
ext->pins[m].baSourceID = jack_in_emb_desc.bJackID;
|
||||
ext->pins[m].baSourcePin = 1;
|
||||
}
|
||||
in_emb->bLength = USB_DT_MIDI_IN_SIZE;
|
||||
in_emb->bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
in_emb->bDescriptorSubtype = USB_MS_MIDI_IN_JACK;
|
||||
in_emb->bJackType = USB_MS_EMBEDDED;
|
||||
in_emb->bJackID = jack++;
|
||||
in_emb->iJack = 0;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) in_emb;
|
||||
|
||||
midi_function[i++] = (struct usb_descriptor_header *) ext;
|
||||
out_ext->bLength = USB_DT_MIDI_OUT_SIZE(1);
|
||||
out_ext->bDescriptorType = USB_DT_CS_INTERFACE;
|
||||
out_ext->bDescriptorSubtype = USB_MS_MIDI_OUT_JACK;
|
||||
out_ext->bJackType = USB_MS_EXTERNAL;
|
||||
out_ext->bJackID = jack++;
|
||||
out_ext->bNrInputPins = 1;
|
||||
out_ext->iJack = 0;
|
||||
out_ext->pins[0].baSourceID = in_emb->bJackID;
|
||||
out_ext->pins[0].baSourcePin = 1;
|
||||
midi_function[i++] = (struct usb_descriptor_header *) out_ext;
|
||||
|
||||
/* link it to the endpoint */
|
||||
ms_out_desc.baAssocJackID[n] = in_emb->bJackID;
|
||||
}
|
||||
|
||||
/* configure the endpoint descriptors ... */
|
||||
ms_out_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->in_ports);
|
||||
ms_out_desc.bNumEmbMIDIJack = midi->in_ports;
|
||||
for (n = 0; n < midi->in_ports; n++)
|
||||
ms_out_desc.baAssocJackID[n] = jack_in_emb_desc.bJackID;
|
||||
|
||||
ms_in_desc.bLength = USB_DT_MS_ENDPOINT_SIZE(midi->out_ports);
|
||||
ms_in_desc.bNumEmbMIDIJack = midi->out_ports;
|
||||
for (n = 0; n < midi->out_ports; n++)
|
||||
ms_in_desc.baAssocJackID[n] = jack_out_emb_desc.bJackID;
|
||||
|
||||
/* ... and add them to the list */
|
||||
midi_function[i++] = (struct usb_descriptor_header *) &bulk_out_desc;
|
||||
|
@ -901,6 +891,8 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
|||
f->descriptors = usb_copy_descriptors(midi_function);
|
||||
}
|
||||
|
||||
kfree(midi_function);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
|
|
@ -859,7 +859,7 @@ static int class_setup_req(struct fsg_dev *fsg,
|
|||
if (ctrl->bRequestType != (USB_DIR_OUT |
|
||||
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
|
||||
break;
|
||||
if (w_index != 0 || w_value != 0) {
|
||||
if (w_index != 0 || w_value != 0 || w_length != 0) {
|
||||
value = -EDOM;
|
||||
break;
|
||||
}
|
||||
|
@ -875,7 +875,7 @@ static int class_setup_req(struct fsg_dev *fsg,
|
|||
if (ctrl->bRequestType != (USB_DIR_IN |
|
||||
USB_TYPE_CLASS | USB_RECIP_INTERFACE))
|
||||
break;
|
||||
if (w_index != 0 || w_value != 0) {
|
||||
if (w_index != 0 || w_value != 0 || w_length != 1) {
|
||||
value = -EDOM;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2480,8 +2480,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev)
|
|||
|
||||
#ifndef CONFIG_ARCH_MXC
|
||||
if (pdata->have_sysif_regs)
|
||||
usb_sys_regs = (struct usb_sys_interface *)
|
||||
((u32)dr_regs + USB_DR_SYS_OFFSET);
|
||||
usb_sys_regs = (void *)dr_regs + USB_DR_SYS_OFFSET;
|
||||
#endif
|
||||
|
||||
/* Initialize USB clocks */
|
||||
|
|
|
@ -1730,8 +1730,9 @@ static void
|
|||
gadgetfs_disconnect (struct usb_gadget *gadget)
|
||||
{
|
||||
struct dev_data *dev = get_gadget_data (gadget);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock (&dev->lock);
|
||||
spin_lock_irqsave (&dev->lock, flags);
|
||||
if (dev->state == STATE_DEV_UNCONNECTED)
|
||||
goto exit;
|
||||
dev->state = STATE_DEV_UNCONNECTED;
|
||||
|
@ -1740,7 +1741,7 @@ gadgetfs_disconnect (struct usb_gadget *gadget)
|
|||
next_event (dev, GADGETFS_DISCONNECT);
|
||||
ep0_readable (dev);
|
||||
exit:
|
||||
spin_unlock (&dev->lock);
|
||||
spin_unlock_irqrestore (&dev->lock, flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
|
||||
* Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -354,6 +354,7 @@ struct pch_udc_dev {
|
|||
#define PCI_DEVICE_ID_INTEL_EG20T_UDC 0x8808
|
||||
#define PCI_VENDOR_ID_ROHM 0x10DB
|
||||
#define PCI_DEVICE_ID_ML7213_IOH_UDC 0x801D
|
||||
#define PCI_DEVICE_ID_ML7831_IOH_UDC 0x8808
|
||||
|
||||
static const char ep0_string[] = "ep0in";
|
||||
static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */
|
||||
|
@ -2970,6 +2971,11 @@ static DEFINE_PCI_DEVICE_TABLE(pch_udc_pcidev_id) = {
|
|||
.class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
|
||||
.class_mask = 0xffffffff,
|
||||
},
|
||||
{
|
||||
PCI_DEVICE(PCI_VENDOR_ID_ROHM, PCI_DEVICE_ID_ML7831_IOH_UDC),
|
||||
.class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe,
|
||||
.class_mask = 0xffffffff,
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
|
@ -2999,5 +3005,5 @@ static void __exit pch_udc_pci_exit(void)
|
|||
module_exit(pch_udc_pci_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Intel EG20T USB Device Controller");
|
||||
MODULE_AUTHOR("OKI SEMICONDUCTOR, <toshiharu-linux@dsn.okisemi.com>");
|
||||
MODULE_AUTHOR("LAPIS Semiconductor, <tomoya-linux@dsn.lapis-semi.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -1718,6 +1718,8 @@ static void r8a66597_fifo_flush(struct usb_ep *_ep)
|
|||
if (list_empty(&ep->queue) && !ep->busy) {
|
||||
pipe_stop(ep->r8a66597, ep->pipenum);
|
||||
r8a66597_bclr(ep->r8a66597, BCLR, ep->fifoctr);
|
||||
r8a66597_write(ep->r8a66597, ACLRM, ep->pipectr);
|
||||
r8a66597_write(ep->r8a66597, 0, ep->pipectr);
|
||||
}
|
||||
spin_unlock_irqrestore(&ep->r8a66597->lock, flags);
|
||||
}
|
||||
|
@ -1742,7 +1744,6 @@ static int r8a66597_start(struct usb_gadget *gadget,
|
|||
struct usb_gadget_driver *driver)
|
||||
{
|
||||
struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget);
|
||||
int retval;
|
||||
|
||||
if (!driver
|
||||
|| driver->speed != USB_SPEED_HIGH
|
||||
|
@ -1752,16 +1753,7 @@ static int r8a66597_start(struct usb_gadget *gadget,
|
|||
return -ENODEV;
|
||||
|
||||
/* hook up the driver */
|
||||
driver->driver.bus = NULL;
|
||||
r8a66597->driver = driver;
|
||||
r8a66597->gadget.dev.driver = &driver->driver;
|
||||
|
||||
retval = device_add(&r8a66597->gadget.dev);
|
||||
if (retval) {
|
||||
dev_err(r8a66597_to_dev(r8a66597), "device_add error (%d)\n",
|
||||
retval);
|
||||
goto error;
|
||||
}
|
||||
|
||||
init_controller(r8a66597);
|
||||
r8a66597_bset(r8a66597, VBSE, INTENB0);
|
||||
|
@ -1775,12 +1767,6 @@ static int r8a66597_start(struct usb_gadget *gadget,
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
r8a66597->driver = NULL;
|
||||
r8a66597->gadget.dev.driver = NULL;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int r8a66597_stop(struct usb_gadget *gadget,
|
||||
|
@ -1794,7 +1780,6 @@ static int r8a66597_stop(struct usb_gadget *gadget,
|
|||
disable_controller(r8a66597);
|
||||
spin_unlock_irqrestore(&r8a66597->lock, flags);
|
||||
|
||||
device_del(&r8a66597->gadget.dev);
|
||||
r8a66597->driver = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1845,6 +1830,7 @@ static int __exit r8a66597_remove(struct platform_device *pdev)
|
|||
clk_put(r8a66597->clk);
|
||||
}
|
||||
#endif
|
||||
device_unregister(&r8a66597->gadget.dev);
|
||||
kfree(r8a66597);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1924,13 +1910,17 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||
r8a66597->irq_sense_low = irq_trigger == IRQF_TRIGGER_LOW;
|
||||
|
||||
r8a66597->gadget.ops = &r8a66597_gadget_ops;
|
||||
device_initialize(&r8a66597->gadget.dev);
|
||||
dev_set_name(&r8a66597->gadget.dev, "gadget");
|
||||
r8a66597->gadget.is_dualspeed = 1;
|
||||
r8a66597->gadget.dev.parent = &pdev->dev;
|
||||
r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask;
|
||||
r8a66597->gadget.dev.release = pdev->dev.release;
|
||||
r8a66597->gadget.name = udc_name;
|
||||
ret = device_register(&r8a66597->gadget.dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "device_register failed\n");
|
||||
goto clean_up;
|
||||
}
|
||||
|
||||
init_timer(&r8a66597->timer);
|
||||
r8a66597->timer.function = r8a66597_timer;
|
||||
|
@ -1945,7 +1935,7 @@ static int __init r8a66597_probe(struct platform_device *pdev)
|
|||
dev_err(&pdev->dev, "cannot get clock \"%s\"\n",
|
||||
clk_name);
|
||||
ret = PTR_ERR(r8a66597->clk);
|
||||
goto clean_up;
|
||||
goto clean_up_dev;
|
||||
}
|
||||
clk_enable(r8a66597->clk);
|
||||
}
|
||||
|
@ -2014,7 +2004,9 @@ clean_up2:
|
|||
clk_disable(r8a66597->clk);
|
||||
clk_put(r8a66597->clk);
|
||||
}
|
||||
clean_up_dev:
|
||||
#endif
|
||||
device_unregister(&r8a66597->gadget.dev);
|
||||
clean_up:
|
||||
if (r8a66597) {
|
||||
if (r8a66597->sudmac_reg)
|
||||
|
|
|
@ -210,10 +210,10 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
|
|||
kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
|
||||
|
||||
if (udc_is_newstyle(udc)) {
|
||||
usb_gadget_disconnect(udc->gadget);
|
||||
udc->driver->disconnect(udc->gadget);
|
||||
udc->driver->unbind(udc->gadget);
|
||||
usb_gadget_udc_stop(udc->gadget, udc->driver);
|
||||
|
||||
usb_gadget_disconnect(udc->gadget);
|
||||
} else {
|
||||
usb_gadget_stop(udc->gadget, udc->driver);
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_unregister_driver);
|
|||
static ssize_t usb_udc_srp_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t n)
|
||||
{
|
||||
struct usb_udc *udc = dev_get_drvdata(dev);
|
||||
struct usb_udc *udc = container_of(dev, struct usb_udc, dev);
|
||||
|
||||
if (sysfs_streq(buf, "1"))
|
||||
usb_gadget_wakeup(udc->gadget);
|
||||
|
@ -378,7 +378,7 @@ static ssize_t usb_udc_speed_show(struct device *dev,
|
|||
return snprintf(buf, PAGE_SIZE, "%s\n",
|
||||
usb_speed_string(udc->gadget->speed));
|
||||
}
|
||||
static DEVICE_ATTR(speed, S_IRUSR, usb_udc_speed_show, NULL);
|
||||
static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL);
|
||||
|
||||
#define USB_UDC_ATTR(name) \
|
||||
ssize_t usb_udc_##name##_show(struct device *dev, \
|
||||
|
@ -389,7 +389,7 @@ ssize_t usb_udc_##name##_show(struct device *dev, \
|
|||
\
|
||||
return snprintf(buf, PAGE_SIZE, "%d\n", gadget->name); \
|
||||
} \
|
||||
static DEVICE_ATTR(name, S_IRUSR, usb_udc_##name##_show, NULL)
|
||||
static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL)
|
||||
|
||||
static USB_UDC_ATTR(is_dualspeed);
|
||||
static USB_UDC_ATTR(is_otg);
|
||||
|
|
|
@ -1479,10 +1479,15 @@ iso_stream_schedule (
|
|||
|
||||
/* NOTE: assumes URB_ISO_ASAP, to limit complexity/bugs */
|
||||
|
||||
/* find a uframe slot with enough bandwidth */
|
||||
next = start + period;
|
||||
for (; start < next; start++) {
|
||||
|
||||
/* find a uframe slot with enough bandwidth.
|
||||
* Early uframes are more precious because full-speed
|
||||
* iso IN transfers can't use late uframes,
|
||||
* and therefore they should be allocated last.
|
||||
*/
|
||||
next = start;
|
||||
start += period;
|
||||
do {
|
||||
start--;
|
||||
/* check schedule: enough space? */
|
||||
if (stream->highspeed) {
|
||||
if (itd_slot_ok(ehci, mod, start,
|
||||
|
@ -1495,7 +1500,7 @@ iso_stream_schedule (
|
|||
start, sched, period))
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (start > next);
|
||||
|
||||
/* no room in the schedule */
|
||||
if (start == next) {
|
||||
|
|
|
@ -19,7 +19,7 @@ static int ehci_xls_setup(struct usb_hcd *hcd)
|
|||
|
||||
ehci->caps = hcd->regs;
|
||||
ehci->regs = hcd->regs +
|
||||
HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
|
||||
dbg_hcs_params(ehci, "reset");
|
||||
dbg_hcc_params(ehci, "reset");
|
||||
|
||||
|
|
|
@ -223,6 +223,9 @@ static void ohci_at91_usb_set_power(struct at91_usbh_data *pdata, int port, int
|
|||
if (port < 0 || port >= 2)
|
||||
return;
|
||||
|
||||
if (pdata->vbus_pin[port] <= 0)
|
||||
return;
|
||||
|
||||
gpio_set_value(pdata->vbus_pin[port], !pdata->vbus_pin_inverted ^ enable);
|
||||
}
|
||||
|
||||
|
@ -231,6 +234,9 @@ static int ohci_at91_usb_get_power(struct at91_usbh_data *pdata, int port)
|
|||
if (port < 0 || port >= 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (pdata->vbus_pin[port] <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
return gpio_get_value(pdata->vbus_pin[port]) ^ !pdata->vbus_pin_inverted;
|
||||
}
|
||||
|
||||
|
|
|
@ -389,17 +389,14 @@ ohci_shutdown (struct usb_hcd *hcd)
|
|||
struct ohci_hcd *ohci;
|
||||
|
||||
ohci = hcd_to_ohci (hcd);
|
||||
ohci_writel (ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable);
|
||||
ohci->hc_control = ohci_readl(ohci, &ohci->regs->control);
|
||||
ohci_writel(ohci, (u32) ~0, &ohci->regs->intrdisable);
|
||||
|
||||
/* If the SHUTDOWN quirk is set, don't put the controller in RESET */
|
||||
ohci->hc_control &= (ohci->flags & OHCI_QUIRK_SHUTDOWN ?
|
||||
OHCI_CTRL_RWC | OHCI_CTRL_HCFS :
|
||||
OHCI_CTRL_RWC);
|
||||
ohci_writel(ohci, ohci->hc_control, &ohci->regs->control);
|
||||
/* Software reset, after which the controller goes into SUSPEND */
|
||||
ohci_writel(ohci, OHCI_HCR, &ohci->regs->cmdstatus);
|
||||
ohci_readl(ohci, &ohci->regs->cmdstatus); /* flush the writes */
|
||||
udelay(10);
|
||||
|
||||
/* flush the writes */
|
||||
(void) ohci_readl (ohci, &ohci->regs->control);
|
||||
ohci_writel(ohci, ohci->fminterval, &ohci->regs->fminterval);
|
||||
}
|
||||
|
||||
static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
|
||||
|
|
|
@ -175,28 +175,6 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* nVidia controllers continue to drive Reset signalling on the bus
|
||||
* even after system shutdown, wasting power. This flag tells the
|
||||
* shutdown routine to leave the controller OPERATIONAL instead of RESET.
|
||||
*/
|
||||
static int ohci_quirk_nvidia_shutdown(struct usb_hcd *hcd)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
|
||||
|
||||
/* Evidently nVidia fixed their later hardware; this is a guess at
|
||||
* the changeover point.
|
||||
*/
|
||||
#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB 0x026d
|
||||
|
||||
if (pdev->device < PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_USB) {
|
||||
ohci->flags |= OHCI_QUIRK_SHUTDOWN;
|
||||
ohci_dbg(ohci, "enabled nVidia shutdown quirk\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sb800_prefetch(struct ohci_hcd *ohci, int on)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
@ -260,10 +238,6 @@ static const struct pci_device_id ohci_pci_quirks[] = {
|
|||
PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
|
||||
.driver_data = (unsigned long)ohci_quirk_amd700,
|
||||
},
|
||||
{
|
||||
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
|
||||
.driver_data = (unsigned long) ohci_quirk_nvidia_shutdown,
|
||||
},
|
||||
|
||||
/* FIXME for some of the early AMD 760 southbridges, OHCI
|
||||
* won't work at all. blacklist them.
|
||||
|
|
|
@ -403,7 +403,6 @@ struct ohci_hcd {
|
|||
#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
|
||||
#define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/
|
||||
#define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */
|
||||
#define OHCI_QUIRK_SHUTDOWN 0x800 /* nVidia power bug */
|
||||
// there are also chip quirks/bugs in init logic
|
||||
|
||||
struct work_struct nec_work; /* Worker for NEC quirk */
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#define OHCI_INTRENABLE 0x10
|
||||
#define OHCI_INTRDISABLE 0x14
|
||||
#define OHCI_FMINTERVAL 0x34
|
||||
#define OHCI_HCFS (3 << 6) /* hc functional state */
|
||||
#define OHCI_HCR (1 << 0) /* host controller reset */
|
||||
#define OHCI_OCR (1 << 3) /* ownership change request */
|
||||
#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */
|
||||
|
@ -466,6 +467,8 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
|||
{
|
||||
void __iomem *base;
|
||||
u32 control;
|
||||
u32 fminterval;
|
||||
int cnt;
|
||||
|
||||
if (!mmio_resource_enabled(pdev, 0))
|
||||
return;
|
||||
|
@ -498,41 +501,32 @@ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* reset controller, preserving RWC (and possibly IR) */
|
||||
writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
|
||||
readl(base + OHCI_CONTROL);
|
||||
/* disable interrupts */
|
||||
writel((u32) ~0, base + OHCI_INTRDISABLE);
|
||||
|
||||
/* Some NVIDIA controllers stop working if kept in RESET for too long */
|
||||
if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
|
||||
u32 fminterval;
|
||||
int cnt;
|
||||
/* Reset the USB bus, if the controller isn't already in RESET */
|
||||
if (control & OHCI_HCFS) {
|
||||
/* Go into RESET, preserving RWC (and possibly IR) */
|
||||
writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
|
||||
readl(base + OHCI_CONTROL);
|
||||
|
||||
/* drive reset for at least 50 ms (7.1.7.5) */
|
||||
/* drive bus reset for at least 50 ms (7.1.7.5) */
|
||||
msleep(50);
|
||||
|
||||
/* software reset of the controller, preserving HcFmInterval */
|
||||
fminterval = readl(base + OHCI_FMINTERVAL);
|
||||
writel(OHCI_HCR, base + OHCI_CMDSTATUS);
|
||||
|
||||
/* reset requires max 10 us delay */
|
||||
for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
|
||||
if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
writel(fminterval, base + OHCI_FMINTERVAL);
|
||||
|
||||
/* Now we're in the SUSPEND state with all devices reset
|
||||
* and wakeups and interrupts disabled
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* disable interrupts
|
||||
*/
|
||||
writel(~(u32)0, base + OHCI_INTRDISABLE);
|
||||
writel(~(u32)0, base + OHCI_INTRSTATUS);
|
||||
/* software reset of the controller, preserving HcFmInterval */
|
||||
fminterval = readl(base + OHCI_FMINTERVAL);
|
||||
writel(OHCI_HCR, base + OHCI_CMDSTATUS);
|
||||
|
||||
/* reset requires max 10 us delay */
|
||||
for (cnt = 30; cnt > 0; --cnt) { /* ... allow extra time */
|
||||
if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
|
||||
break;
|
||||
udelay(1);
|
||||
}
|
||||
writel(fminterval, base + OHCI_FMINTERVAL);
|
||||
|
||||
/* Now the controller is safely in SUSPEND and nothing can wake it up */
|
||||
iounmap(base);
|
||||
}
|
||||
|
||||
|
@ -627,7 +621,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
|||
void __iomem *base, *op_reg_base;
|
||||
u32 hcc_params, cap, val;
|
||||
u8 offset, cap_length;
|
||||
int wait_time, delta, count = 256/4;
|
||||
int wait_time, count = 256/4;
|
||||
|
||||
if (!mmio_resource_enabled(pdev, 0))
|
||||
return;
|
||||
|
@ -673,11 +667,10 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev)
|
|||
writel(val, op_reg_base + EHCI_USBCMD);
|
||||
|
||||
wait_time = 2000;
|
||||
delta = 100;
|
||||
do {
|
||||
writel(0x3f, op_reg_base + EHCI_USBSTS);
|
||||
udelay(delta);
|
||||
wait_time -= delta;
|
||||
udelay(100);
|
||||
wait_time -= 100;
|
||||
val = readl(op_reg_base + EHCI_USBSTS);
|
||||
if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) {
|
||||
break;
|
||||
|
|
|
@ -982,7 +982,6 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
|
|||
struct xhci_virt_device *dev;
|
||||
struct xhci_ep_ctx *ep0_ctx;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
u32 port_num;
|
||||
struct usb_device *top_dev;
|
||||
|
||||
|
@ -994,12 +993,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
|
|||
return -EINVAL;
|
||||
}
|
||||
ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);
|
||||
slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx);
|
||||
|
||||
/* 2) New slot context and endpoint 0 context are valid*/
|
||||
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
|
||||
|
||||
/* 3) Only the control endpoint is valid - one endpoint context */
|
||||
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | udev->route);
|
||||
switch (udev->speed) {
|
||||
|
|
|
@ -816,23 +816,24 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
|
|||
struct xhci_ring *ring;
|
||||
struct xhci_td *cur_td;
|
||||
int ret, i, j;
|
||||
unsigned long flags;
|
||||
|
||||
ep = (struct xhci_virt_ep *) arg;
|
||||
xhci = ep->xhci;
|
||||
|
||||
spin_lock(&xhci->lock);
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
|
||||
ep->stop_cmds_pending--;
|
||||
if (xhci->xhc_state & XHCI_STATE_DYING) {
|
||||
xhci_dbg(xhci, "Stop EP timer ran, but another timer marked "
|
||||
"xHCI as DYING, exiting.\n");
|
||||
spin_unlock(&xhci->lock);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
return;
|
||||
}
|
||||
if (!(ep->stop_cmds_pending == 0 && (ep->ep_state & EP_HALT_PENDING))) {
|
||||
xhci_dbg(xhci, "Stop EP timer ran, but no command pending, "
|
||||
"exiting.\n");
|
||||
spin_unlock(&xhci->lock);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -844,11 +845,11 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
|
|||
xhci->xhc_state |= XHCI_STATE_DYING;
|
||||
/* Disable interrupts from the host controller and start halting it */
|
||||
xhci_quiesce(xhci);
|
||||
spin_unlock(&xhci->lock);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
|
||||
ret = xhci_halt(xhci);
|
||||
|
||||
spin_lock(&xhci->lock);
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
if (ret < 0) {
|
||||
/* This is bad; the host is not responding to commands and it's
|
||||
* not allowing itself to be halted. At least interrupts are
|
||||
|
@ -896,7 +897,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
|
|||
}
|
||||
}
|
||||
}
|
||||
spin_unlock(&xhci->lock);
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
xhci_dbg(xhci, "Calling usb_hc_died()\n");
|
||||
usb_hc_died(xhci_to_hcd(xhci)->primary_hcd);
|
||||
xhci_dbg(xhci, "xHCI host controller is dead.\n");
|
||||
|
|
|
@ -799,7 +799,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
u32 command, temp = 0;
|
||||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
struct usb_hcd *secondary_hcd;
|
||||
int retval;
|
||||
int retval = 0;
|
||||
|
||||
/* Wait a bit if either of the roothubs need to settle from the
|
||||
* transition into bus suspend.
|
||||
|
@ -809,6 +809,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
xhci->bus_state[1].next_statechange))
|
||||
msleep(100);
|
||||
|
||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
|
||||
|
||||
spin_lock_irq(&xhci->lock);
|
||||
if (xhci->quirks & XHCI_RESET_ON_RESUME)
|
||||
hibernated = true;
|
||||
|
@ -878,20 +881,13 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)
|
|||
return retval;
|
||||
xhci_dbg(xhci, "Start the primary HCD\n");
|
||||
retval = xhci_run(hcd->primary_hcd);
|
||||
if (retval)
|
||||
goto failed_restart;
|
||||
|
||||
xhci_dbg(xhci, "Start the secondary HCD\n");
|
||||
retval = xhci_run(secondary_hcd);
|
||||
if (!retval) {
|
||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
||||
set_bit(HCD_FLAG_HW_ACCESSIBLE,
|
||||
&xhci->shared_hcd->flags);
|
||||
xhci_dbg(xhci, "Start the secondary HCD\n");
|
||||
retval = xhci_run(secondary_hcd);
|
||||
}
|
||||
failed_restart:
|
||||
hcd->state = HC_STATE_SUSPENDED;
|
||||
xhci->shared_hcd->state = HC_STATE_SUSPENDED;
|
||||
return retval;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* step 4: set Run/Stop bit */
|
||||
|
@ -910,11 +906,14 @@ failed_restart:
|
|||
* Running endpoints by ringing their doorbells
|
||||
*/
|
||||
|
||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
|
||||
set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags);
|
||||
|
||||
spin_unlock_irq(&xhci->lock);
|
||||
return 0;
|
||||
|
||||
done:
|
||||
if (retval == 0) {
|
||||
usb_hcd_resume_root_hub(hcd);
|
||||
usb_hcd_resume_root_hub(xhci->shared_hcd);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
@ -3504,6 +3503,10 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
|||
/* Otherwise, update the control endpoint ring enqueue pointer. */
|
||||
else
|
||||
xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev);
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
|
||||
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
|
||||
ctrl_ctx->drop_flags = 0;
|
||||
|
||||
xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
|
||||
xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
|
||||
|
||||
|
@ -3585,7 +3588,6 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
|
|||
virt_dev->address = (le32_to_cpu(slot_ctx->dev_state) & DEV_ADDR_MASK)
|
||||
+ 1;
|
||||
/* Zero the input context control for later use */
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
|
||||
ctrl_ctx->add_flags = 0;
|
||||
ctrl_ctx->drop_flags = 0;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ config USB_MUSB_HDRC
|
|||
select TWL4030_USB if MACH_OMAP_3430SDP
|
||||
select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA
|
||||
select USB_OTG_UTILS
|
||||
select USB_GADGET_DUALSPEED
|
||||
tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)'
|
||||
help
|
||||
Say Y here if your system has a dual role high speed USB
|
||||
|
@ -60,7 +61,7 @@ config USB_MUSB_BLACKFIN
|
|||
|
||||
config USB_MUSB_UX500
|
||||
tristate "U8500 and U5500"
|
||||
depends on (ARCH_U8500 && AB8500_USB) || (ARCH_U5500)
|
||||
depends on (ARCH_U8500 && AB8500_USB)
|
||||
|
||||
endchoice
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
|
@ -1477,8 +1477,7 @@ static int __init musb_core_init(u16 musb_type, struct musb *musb)
|
|||
/*-------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_SOC_OMAP2430) || defined(CONFIG_SOC_OMAP3430) || \
|
||||
defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500) || \
|
||||
defined(CONFIG_ARCH_U5500)
|
||||
defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_U8500)
|
||||
|
||||
static irqreturn_t generic_interrupt(int irq, void *__hci)
|
||||
{
|
||||
|
|
|
@ -1999,10 +1999,6 @@ static void stop_activity(struct musb *musb, struct usb_gadget_driver *driver)
|
|||
nuke(&hw_ep->ep_out, -ESHUTDOWN);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&musb->lock);
|
||||
driver->disconnect(&musb->g);
|
||||
spin_lock(&musb->lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -405,7 +405,7 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev)
|
|||
/*
|
||||
* platform functions
|
||||
*/
|
||||
static int __devinit usbhs_probe(struct platform_device *pdev)
|
||||
static int usbhs_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct renesas_usbhs_platform_info *info = pdev->dev.platform_data;
|
||||
struct renesas_usbhs_driver_callback *dfunc;
|
||||
|
|
|
@ -820,7 +820,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
|
|||
if (len % 4) /* 32bit alignment */
|
||||
goto usbhsf_pio_prepare_push;
|
||||
|
||||
if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
|
||||
if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
|
||||
goto usbhsf_pio_prepare_push;
|
||||
|
||||
/* get enable DMA fifo */
|
||||
|
@ -897,7 +897,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done)
|
|||
if (!fifo)
|
||||
goto usbhsf_pio_prepare_pop;
|
||||
|
||||
if ((*(u32 *) pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
|
||||
if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */
|
||||
goto usbhsf_pio_prepare_pop;
|
||||
|
||||
ret = usbhsf_fifo_select(pipe, fifo, 0);
|
||||
|
|
|
@ -143,8 +143,8 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod);
|
|||
*/
|
||||
#if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \
|
||||
defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE)
|
||||
extern int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv);
|
||||
extern int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv);
|
||||
extern int usbhs_mod_host_probe(struct usbhs_priv *priv);
|
||||
extern int usbhs_mod_host_remove(struct usbhs_priv *priv);
|
||||
#else
|
||||
static inline int usbhs_mod_host_probe(struct usbhs_priv *priv)
|
||||
{
|
||||
|
@ -157,8 +157,8 @@ static inline void usbhs_mod_host_remove(struct usbhs_priv *priv)
|
|||
|
||||
#if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \
|
||||
defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE)
|
||||
extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv);
|
||||
extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv);
|
||||
extern int usbhs_mod_gadget_probe(struct usbhs_priv *priv);
|
||||
extern void usbhs_mod_gadget_remove(struct usbhs_priv *priv);
|
||||
#else
|
||||
static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
|
||||
{
|
||||
|
|
|
@ -830,7 +830,7 @@ static int usbhsg_stop(struct usbhs_priv *priv)
|
|||
return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED);
|
||||
}
|
||||
|
||||
int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv)
|
||||
int usbhs_mod_gadget_probe(struct usbhs_priv *priv)
|
||||
{
|
||||
struct usbhsg_gpriv *gpriv;
|
||||
struct usbhsg_uep *uep;
|
||||
|
@ -927,7 +927,7 @@ usbhs_mod_gadget_probe_err_gpriv:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv)
|
||||
void usbhs_mod_gadget_remove(struct usbhs_priv *priv)
|
||||
{
|
||||
struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv);
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ struct usbhsh_hpriv {
|
|||
|
||||
u32 port_stat; /* USB_PORT_STAT_xxx */
|
||||
|
||||
struct completion *done;
|
||||
struct completion setup_ack_done;
|
||||
|
||||
/* see usbhsh_req_alloc/free */
|
||||
struct list_head ureq_link_active;
|
||||
|
@ -355,6 +355,7 @@ static void usbhsh_device_free(struct usbhsh_hpriv *hpriv,
|
|||
struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
||||
struct usbhsh_device *udev,
|
||||
struct usb_host_endpoint *ep,
|
||||
int dir_in_req,
|
||||
gfp_t mem_flags)
|
||||
{
|
||||
struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv);
|
||||
|
@ -364,27 +365,38 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
|||
struct usbhs_pipe *pipe, *best_pipe;
|
||||
struct device *dev = usbhsh_hcd_to_dev(hcd);
|
||||
struct usb_endpoint_descriptor *desc = &ep->desc;
|
||||
int type, i;
|
||||
int type, i, dir_in;
|
||||
unsigned int min_usr;
|
||||
|
||||
dir_in_req = !!dir_in_req;
|
||||
|
||||
uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags);
|
||||
if (!uep) {
|
||||
dev_err(dev, "usbhsh_ep alloc fail\n");
|
||||
return NULL;
|
||||
}
|
||||
type = usb_endpoint_type(desc);
|
||||
|
||||
if (usb_endpoint_xfer_control(desc)) {
|
||||
best_pipe = usbhsh_hpriv_to_dcp(hpriv);
|
||||
goto usbhsh_endpoint_alloc_find_pipe;
|
||||
}
|
||||
|
||||
/*
|
||||
* find best pipe for endpoint
|
||||
* see
|
||||
* HARDWARE LIMITATION
|
||||
*/
|
||||
type = usb_endpoint_type(desc);
|
||||
min_usr = ~0;
|
||||
best_pipe = NULL;
|
||||
usbhs_for_each_pipe_with_dcp(pipe, priv, i) {
|
||||
usbhs_for_each_pipe(pipe, priv, i) {
|
||||
if (!usbhs_pipe_type_is(pipe, type))
|
||||
continue;
|
||||
|
||||
dir_in = !!usbhs_pipe_is_dir_in(pipe);
|
||||
if (0 != (dir_in - dir_in_req))
|
||||
continue;
|
||||
|
||||
info = usbhsh_pipe_info(pipe);
|
||||
|
||||
if (min_usr > info->usr_cnt) {
|
||||
|
@ -398,7 +410,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
|||
kfree(uep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
usbhsh_endpoint_alloc_find_pipe:
|
||||
/*
|
||||
* init uep
|
||||
*/
|
||||
|
@ -423,6 +435,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
|||
* see
|
||||
* DCPMAXP/PIPEMAXP
|
||||
*/
|
||||
usbhs_pipe_sequence_data0(uep->pipe);
|
||||
usbhs_pipe_config_update(uep->pipe,
|
||||
usbhsh_device_number(hpriv, udev),
|
||||
usb_endpoint_num(desc),
|
||||
|
@ -430,7 +443,7 @@ struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv,
|
|||
|
||||
dev_dbg(dev, "%s [%d-%s](%p)\n", __func__,
|
||||
usbhsh_device_number(hpriv, udev),
|
||||
usbhs_pipe_name(pipe), uep);
|
||||
usbhs_pipe_name(uep->pipe), uep);
|
||||
|
||||
return uep;
|
||||
}
|
||||
|
@ -549,8 +562,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
|
|||
* usbhsh_irq_setup_ack()
|
||||
* usbhsh_irq_setup_err()
|
||||
*/
|
||||
DECLARE_COMPLETION(done);
|
||||
hpriv->done = &done;
|
||||
init_completion(&hpriv->setup_ack_done);
|
||||
|
||||
/* copy original request */
|
||||
memcpy(&req, urb->setup_packet, sizeof(struct usb_ctrlrequest));
|
||||
|
@ -572,8 +584,7 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv,
|
|||
/*
|
||||
* wait setup packet ACK
|
||||
*/
|
||||
wait_for_completion(&done);
|
||||
hpriv->done = NULL;
|
||||
wait_for_completion(&hpriv->setup_ack_done);
|
||||
|
||||
dev_dbg(dev, "%s done\n", __func__);
|
||||
}
|
||||
|
@ -724,11 +735,11 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
|
|||
struct usbhsh_device *udev, *new_udev = NULL;
|
||||
struct usbhs_pipe *pipe;
|
||||
struct usbhsh_ep *uep;
|
||||
int is_dir_in = usb_pipein(urb->pipe);
|
||||
|
||||
int ret;
|
||||
|
||||
dev_dbg(dev, "%s (%s)\n",
|
||||
__func__, usb_pipein(urb->pipe) ? "in" : "out");
|
||||
dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out");
|
||||
|
||||
ret = usb_hcd_link_urb_to_ep(hcd, urb);
|
||||
if (ret)
|
||||
|
@ -751,7 +762,8 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd,
|
|||
*/
|
||||
uep = usbhsh_ep_to_uep(ep);
|
||||
if (!uep) {
|
||||
uep = usbhsh_endpoint_alloc(hpriv, udev, ep, mem_flags);
|
||||
uep = usbhsh_endpoint_alloc(hpriv, udev, ep,
|
||||
is_dir_in, mem_flags);
|
||||
if (!uep)
|
||||
goto usbhsh_urb_enqueue_error_free_device;
|
||||
}
|
||||
|
@ -1095,10 +1107,7 @@ static int usbhsh_irq_setup_ack(struct usbhs_priv *priv,
|
|||
|
||||
dev_dbg(dev, "setup packet OK\n");
|
||||
|
||||
if (unlikely(!hpriv->done))
|
||||
dev_err(dev, "setup ack happen without necessary data\n");
|
||||
else
|
||||
complete(hpriv->done); /* see usbhsh_urb_enqueue() */
|
||||
complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1111,10 +1120,7 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv,
|
|||
|
||||
dev_dbg(dev, "setup packet Err\n");
|
||||
|
||||
if (unlikely(!hpriv->done))
|
||||
dev_err(dev, "setup err happen without necessary data\n");
|
||||
else
|
||||
complete(hpriv->done); /* see usbhsh_urb_enqueue() */
|
||||
complete(&hpriv->setup_ack_done); /* see usbhsh_urb_enqueue() */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1221,8 +1227,18 @@ static int usbhsh_stop(struct usbhs_priv *priv)
|
|||
{
|
||||
struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
|
||||
struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
|
||||
struct usbhs_mod *mod = usbhs_mod_get_current(priv);
|
||||
struct device *dev = usbhs_priv_to_dev(priv);
|
||||
|
||||
/*
|
||||
* disable irq callback
|
||||
*/
|
||||
mod->irq_attch = NULL;
|
||||
mod->irq_dtch = NULL;
|
||||
mod->irq_sack = NULL;
|
||||
mod->irq_sign = NULL;
|
||||
usbhs_irq_callback_update(priv, mod);
|
||||
|
||||
usb_remove_hcd(hcd);
|
||||
|
||||
/* disable sys */
|
||||
|
@ -1235,7 +1251,7 @@ static int usbhsh_stop(struct usbhs_priv *priv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)
|
||||
int usbhs_mod_host_probe(struct usbhs_priv *priv)
|
||||
{
|
||||
struct usbhsh_hpriv *hpriv;
|
||||
struct usb_hcd *hcd;
|
||||
|
@ -1279,7 +1295,6 @@ int __devinit usbhs_mod_host_probe(struct usbhs_priv *priv)
|
|||
hpriv->mod.stop = usbhsh_stop;
|
||||
hpriv->pipe_info = pipe_info;
|
||||
hpriv->pipe_size = pipe_size;
|
||||
hpriv->done = NULL;
|
||||
usbhsh_req_list_init(hpriv);
|
||||
usbhsh_port_stat_init(hpriv);
|
||||
|
||||
|
@ -1299,7 +1314,7 @@ usbhs_mod_host_probe_err:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int __devexit usbhs_mod_host_remove(struct usbhs_priv *priv)
|
||||
int usbhs_mod_host_remove(struct usbhs_priv *priv)
|
||||
{
|
||||
struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv);
|
||||
struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv);
|
||||
|
|
|
@ -42,7 +42,7 @@ static int debug;
|
|||
* Version information
|
||||
*/
|
||||
|
||||
#define DRIVER_VERSION "v0.6"
|
||||
#define DRIVER_VERSION "v0.7"
|
||||
#define DRIVER_AUTHOR "Bart Hartgers <bart.hartgers+ark3116@gmail.com>"
|
||||
#define DRIVER_DESC "USB ARK3116 serial/IrDA driver"
|
||||
#define DRIVER_DEV_DESC "ARK3116 RS232/IrDA"
|
||||
|
@ -380,10 +380,6 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
/* setup termios */
|
||||
if (tty)
|
||||
ark3116_set_termios(tty, port, NULL);
|
||||
|
||||
/* remove any data still left: also clears error state */
|
||||
ark3116_read_reg(serial, UART_RX, buf);
|
||||
|
||||
|
@ -406,6 +402,10 @@ static int ark3116_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
/* enable DMA */
|
||||
ark3116_write_reg(port->serial, UART_FCR, UART_FCR_DMA_SELECT);
|
||||
|
||||
/* setup termios */
|
||||
if (tty)
|
||||
ark3116_set_termios(tty, port, NULL);
|
||||
|
||||
err_out:
|
||||
kfree(buf);
|
||||
return result;
|
||||
|
|
|
@ -2104,13 +2104,19 @@ static void ftdi_set_termios(struct tty_struct *tty,
|
|||
|
||||
cflag = termios->c_cflag;
|
||||
|
||||
/* FIXME -For this cut I don't care if the line is really changing or
|
||||
not - so just do the change regardless - should be able to
|
||||
compare old_termios and tty->termios */
|
||||
if (old_termios->c_cflag == termios->c_cflag
|
||||
&& old_termios->c_ispeed == termios->c_ispeed
|
||||
&& old_termios->c_ospeed == termios->c_ospeed)
|
||||
goto no_c_cflag_changes;
|
||||
|
||||
/* NOTE These routines can get interrupted by
|
||||
ftdi_sio_read_bulk_callback - need to examine what this means -
|
||||
don't see any problems yet */
|
||||
|
||||
if ((old_termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)) ==
|
||||
(termios->c_cflag & (CSIZE|PARODD|PARENB|CMSPAR|CSTOPB)))
|
||||
goto no_data_parity_stop_changes;
|
||||
|
||||
/* Set number of data bits, parity, stop bits */
|
||||
|
||||
urb_value = 0;
|
||||
|
@ -2151,6 +2157,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
|
|||
}
|
||||
|
||||
/* Now do the baudrate */
|
||||
no_data_parity_stop_changes:
|
||||
if ((cflag & CBAUD) == B0) {
|
||||
/* Disable flow control */
|
||||
if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
|
||||
|
@ -2178,6 +2185,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
|
|||
|
||||
/* Set flow control */
|
||||
/* Note device also supports DTR/CD (ugh) and Xon/Xoff in hardware */
|
||||
no_c_cflag_changes:
|
||||
if (cflag & CRTSCTS) {
|
||||
dbg("%s Setting to CRTSCTS flow control", __func__);
|
||||
if (usb_control_msg(dev,
|
||||
|
|
|
@ -156,6 +156,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define HUAWEI_PRODUCT_K4511 0x14CC
|
||||
#define HUAWEI_PRODUCT_ETS1220 0x1803
|
||||
#define HUAWEI_PRODUCT_E353 0x1506
|
||||
#define HUAWEI_PRODUCT_E173S 0x1C05
|
||||
|
||||
#define QUANTA_VENDOR_ID 0x0408
|
||||
#define QUANTA_PRODUCT_Q101 0xEA02
|
||||
|
@ -316,6 +317,9 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define ZTE_PRODUCT_AC8710 0xfff1
|
||||
#define ZTE_PRODUCT_AC2726 0xfff5
|
||||
#define ZTE_PRODUCT_AC8710T 0xffff
|
||||
#define ZTE_PRODUCT_MC2718 0xffe8
|
||||
#define ZTE_PRODUCT_AD3812 0xffeb
|
||||
#define ZTE_PRODUCT_MC2716 0xffed
|
||||
|
||||
#define BENQ_VENDOR_ID 0x04a5
|
||||
#define BENQ_PRODUCT_H10 0x4068
|
||||
|
@ -468,6 +472,10 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define YUGA_PRODUCT_CLU528 0x260D
|
||||
#define YUGA_PRODUCT_CLU526 0x260F
|
||||
|
||||
/* Viettel products */
|
||||
#define VIETTEL_VENDOR_ID 0x2262
|
||||
#define VIETTEL_PRODUCT_VT1000 0x0002
|
||||
|
||||
/* some devices interfaces need special handling due to a number of reasons */
|
||||
enum option_blacklist_reason {
|
||||
OPTION_BLACKLIST_NONE = 0,
|
||||
|
@ -500,6 +508,18 @@ static const struct option_blacklist_info zte_k3765_z_blacklist = {
|
|||
.reserved = BIT(4),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_ad3812_z_blacklist = {
|
||||
.sendsetup = BIT(0) | BIT(1) | BIT(2),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_mc2718_z_blacklist = {
|
||||
.sendsetup = BIT(1) | BIT(2) | BIT(3) | BIT(4),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_mc2716_z_blacklist = {
|
||||
.sendsetup = BIT(1) | BIT(2) | BIT(3),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info huawei_cdc12_blacklist = {
|
||||
.reserved = BIT(1) | BIT(2),
|
||||
};
|
||||
|
@ -622,6 +642,7 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff),
|
||||
|
@ -1043,6 +1064,12 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710T, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2718, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_mc2718_z_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AD3812, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist },
|
||||
{ USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) },
|
||||
{ USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) },
|
||||
{ USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */
|
||||
|
@ -1141,6 +1168,7 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU516) },
|
||||
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU528) },
|
||||
{ USB_DEVICE(YUGA_VENDOR_ID, YUGA_PRODUCT_CLU526) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(VIETTEL_VENDOR_ID, VIETTEL_PRODUCT_VT1000, 0xff, 0xff, 0xff) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, option_ids);
|
||||
|
|
|
@ -91,7 +91,6 @@ static const struct usb_device_id id_table[] = {
|
|||
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
|
||||
{ USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) },
|
||||
{ USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) },
|
||||
{ USB_DEVICE(WINCHIPHEAD_VENDOR_ID, WINCHIPHEAD_USBSER_PRODUCT_ID) },
|
||||
{ USB_DEVICE(SMART_VENDOR_ID, SMART_PRODUCT_ID) },
|
||||
{ } /* Terminating entry */
|
||||
};
|
||||
|
|
|
@ -145,10 +145,6 @@
|
|||
#define ADLINK_VENDOR_ID 0x0b63
|
||||
#define ADLINK_ND6530_PRODUCT_ID 0x6530
|
||||
|
||||
/* WinChipHead USB->RS 232 adapter */
|
||||
#define WINCHIPHEAD_VENDOR_ID 0x4348
|
||||
#define WINCHIPHEAD_USBSER_PRODUCT_ID 0x5523
|
||||
|
||||
/* SMART USB Serial Adapter */
|
||||
#define SMART_VENDOR_ID 0x0b8c
|
||||
#define SMART_PRODUCT_ID 0x2303
|
||||
|
|
|
@ -1762,10 +1762,9 @@ static int ms_scsi_write(struct us_data *us, struct scsi_cmnd *srb)
|
|||
result = ene_send_scsi_cmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
|
||||
} else {
|
||||
void *buf;
|
||||
int offset;
|
||||
int offset = 0;
|
||||
u16 PhyBlockAddr;
|
||||
u8 PageNum;
|
||||
u32 result;
|
||||
u16 len, oldphy, newphy;
|
||||
|
||||
buf = kmalloc(blenByte, GFP_KERNEL);
|
||||
|
|
|
@ -59,7 +59,9 @@
|
|||
|
||||
void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
|
||||
{
|
||||
/* Pad the SCSI command with zeros out to 12 bytes
|
||||
/*
|
||||
* Pad the SCSI command with zeros out to 12 bytes. If the
|
||||
* command already is 12 bytes or longer, leave it alone.
|
||||
*
|
||||
* NOTE: This only works because a scsi_cmnd struct field contains
|
||||
* a unsigned char cmnd[16], so we know we have storage available
|
||||
|
@ -67,9 +69,6 @@ void usb_stor_pad12_command(struct scsi_cmnd *srb, struct us_data *us)
|
|||
for (; srb->cmd_len<12; srb->cmd_len++)
|
||||
srb->cmnd[srb->cmd_len] = 0;
|
||||
|
||||
/* set command length to 12 bytes */
|
||||
srb->cmd_len = 12;
|
||||
|
||||
/* send the command to the transport layer */
|
||||
usb_stor_invoke_transport(srb, us);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue