summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/atm/usbatm.c5
-rw-r--r--drivers/usb/core/hcd.c3
-rw-r--r--drivers/usb/core/hub.c39
-rw-r--r--drivers/usb/core/inode.c2
-rw-r--r--drivers/usb/gadget/fsl_usb2_udc.c2
-rw-r--r--drivers/usb/gadget/omap_udc.c4
-rw-r--r--drivers/usb/host/ehci-hcd.c26
-rw-r--r--drivers/usb/host/ehci-ixp4xx.c2
-rw-r--r--drivers/usb/host/ehci-sched.c32
-rw-r--r--drivers/usb/host/ehci.h138
-rw-r--r--drivers/usb/host/ohci-pxa27x.c259
-rw-r--r--drivers/usb/host/sl811_cs.c133
-rw-r--r--drivers/usb/musb/Kconfig1
-rw-r--r--drivers/usb/musb/musb_core.c4
-rw-r--r--drivers/usb/musb/omap2430.c4
-rw-r--r--drivers/usb/musb/omap2430.h4
-rw-r--r--drivers/usb/serial/aircable.c15
-rw-r--r--drivers/usb/serial/belkin_sa.c3
-rw-r--r--drivers/usb/serial/console.c8
-rw-r--r--drivers/usb/serial/cp2101.c3
-rw-r--r--drivers/usb/serial/cyberjack.c3
-rw-r--r--drivers/usb/serial/cypress_m8.c5
-rw-r--r--drivers/usb/serial/digi_acceleport.c19
-rw-r--r--drivers/usb/serial/empeg.c8
-rw-r--r--drivers/usb/serial/ftdi_sio.c28
-rw-r--r--drivers/usb/serial/ftdi_sio.h5
-rw-r--r--drivers/usb/serial/garmin_gps.c3
-rw-r--r--drivers/usb/serial/generic.c3
-rw-r--r--drivers/usb/serial/io_edgeport.c43
-rw-r--r--drivers/usb/serial/io_ti.c26
-rw-r--r--drivers/usb/serial/ipaq.c3
-rw-r--r--drivers/usb/serial/ipw.c3
-rw-r--r--drivers/usb/serial/ir-usb.c3
-rw-r--r--drivers/usb/serial/iuu_phoenix.c3
-rw-r--r--drivers/usb/serial/keyspan.c77
-rw-r--r--drivers/usb/serial/keyspan_pda.c16
-rw-r--r--drivers/usb/serial/kl5kusb105.c3
-rw-r--r--drivers/usb/serial/kobil_sct.c3
-rw-r--r--drivers/usb/serial/mct_u232.c6
-rw-r--r--drivers/usb/serial/mos7720.c36
-rw-r--r--drivers/usb/serial/mos7840.c7
-rw-r--r--drivers/usb/serial/navman.c3
-rw-r--r--drivers/usb/serial/omninet.c10
-rw-r--r--drivers/usb/serial/option.c20
-rw-r--r--drivers/usb/serial/oti6858.c7
-rw-r--r--drivers/usb/serial/pl2303.c15
-rw-r--r--drivers/usb/serial/safe_serial.c11
-rw-r--r--drivers/usb/serial/sierra.c28
-rw-r--r--drivers/usb/serial/spcp8x5.c3
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c46
-rw-r--r--drivers/usb/serial/usb-serial.c28
-rw-r--r--drivers/usb/serial/visor.c18
-rw-r--r--drivers/usb/serial/whiteheat.c8
-rw-r--r--drivers/usb/storage/Kconfig12
-rw-r--r--drivers/usb/storage/Makefile3
-rw-r--r--drivers/usb/storage/unusual_devs.h30
-rw-r--r--drivers/usb/storage/usb.c2
57 files changed, 649 insertions, 585 deletions
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 07228721cafe..0da2c25bab3b 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -640,14 +640,13 @@ static void usbatm_cancel_send(struct usbatm_data *instance,
atm_dbg(instance, "%s entered\n", __func__);
spin_lock_irq(&instance->sndqueue.lock);
- for (skb = instance->sndqueue.next, n = skb->next;
- skb != (struct sk_buff *)&instance->sndqueue;
- skb = n, n = skb->next)
+ skb_queue_walk_safe(&instance->sndqueue, skb, n) {
if (UDSL_SKB(skb)->atm.vcc == vcc) {
atm_dbg(instance, "%s: popping skb 0x%p\n", __func__, skb);
__skb_unlink(skb, &instance->sndqueue);
usbatm_pop(vcc, skb);
}
+ }
spin_unlock_irq(&instance->sndqueue.lock);
tasklet_disable(&instance->tx_channel.tasklet);
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 8abd4e59bf4a..8ab389dca2b9 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1876,7 +1876,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
* with IRQF_SHARED. As usb_hcd_irq() will always disable
* interrupts we can remove it here.
*/
- irqflags &= ~IRQF_DISABLED;
+ if (irqflags & IRQF_SHARED)
+ irqflags &= ~IRQF_DISABLED;
snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
hcd->driver->description, hcd->self.busnum);
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 6a5cb018383d..d99963873e37 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2683,35 +2683,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
USB_PORT_STAT_C_ENABLE);
#endif
- /* Try to use the debounce delay for protection against
- * port-enable changes caused, for example, by EMI.
- */
- if (portchange & (USB_PORT_STAT_C_CONNECTION |
- USB_PORT_STAT_C_ENABLE)) {
- status = hub_port_debounce(hub, port1);
- if (status < 0) {
- if (printk_ratelimit())
- dev_err (hub_dev, "connect-debounce failed, "
- "port %d disabled\n", port1);
- portstatus &= ~USB_PORT_STAT_CONNECTION;
- } else {
- portstatus = status;
- }
- }
-
/* Try to resuscitate an existing device */
udev = hdev->children[port1-1];
if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
udev->state != USB_STATE_NOTATTACHED) {
-
usb_lock_device(udev);
if (portstatus & USB_PORT_STAT_ENABLE) {
status = 0; /* Nothing to do */
- } else if (!udev->persist_enabled) {
- status = -ENODEV; /* Mustn't resuscitate */
#ifdef CONFIG_USB_SUSPEND
- } else if (udev->state == USB_STATE_SUSPENDED) {
+ } else if (udev->state == USB_STATE_SUSPENDED &&
+ udev->persist_enabled) {
/* For a suspended device, treat this as a
* remote wakeup event.
*/
@@ -2726,7 +2708,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
#endif
} else {
- status = usb_reset_device(udev);
+ status = -ENODEV; /* Don't resuscitate */
}
usb_unlock_device(udev);
@@ -2741,6 +2723,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
usb_disconnect(&hdev->children[port1-1]);
clear_bit(port1, hub->change_bits);
+ if (portchange & (USB_PORT_STAT_C_CONNECTION |
+ USB_PORT_STAT_C_ENABLE)) {
+ status = hub_port_debounce(hub, port1);
+ if (status < 0) {
+ if (printk_ratelimit())
+ dev_err(hub_dev, "connect-debounce failed, "
+ "port %d disabled\n", port1);
+ portstatus &= ~USB_PORT_STAT_CONNECTION;
+ } else {
+ portstatus = status;
+ }
+ }
+
/* Return now if debouncing failed or nothing is connected */
if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
@@ -2748,7 +2743,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
&& !(portstatus & (1 << USB_PORT_FEAT_POWER)))
set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
-
+
if (portstatus & USB_PORT_STAT_ENABLE)
goto done;
return;
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c
index db410e92c80d..77fa7a080801 100644
--- a/drivers/usb/core/inode.c
+++ b/drivers/usb/core/inode.c
@@ -97,7 +97,7 @@ enum {
Opt_err,
};
-static match_table_t tokens = {
+static const match_table_t tokens = {
{Opt_devuid, "devuid=%u"},
{Opt_devgid, "devgid=%u"},
{Opt_devmode, "devmode=%o"},
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c
index 1cfccf102a2d..45ad556169f1 100644
--- a/drivers/usb/gadget/fsl_usb2_udc.c
+++ b/drivers/usb/gadget/fsl_usb2_udc.c
@@ -223,7 +223,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
fsl_writel(tmp, &dr_regs->endpointlistaddr);
VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x",
- (int)udc->ep_qh, (int)tmp,
+ udc->ep_qh, (int)tmp,
fsl_readl(&dr_regs->endpointlistaddr));
/* Config PHY interface */
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 574c53831a05..bb54cca4c543 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -787,7 +787,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
omap_set_dma_dest_params(ep->lch,
OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT,
- (unsigned long) io_v2p(UDC_DATA_DMA),
+ UDC_DATA_DMA,
0, 0);
}
} else {
@@ -804,7 +804,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
omap_set_dma_src_params(ep->lch,
OMAP_DMA_PORT_TIPB,
OMAP_DMA_AMODE_CONSTANT,
- (unsigned long) io_v2p(UDC_DATA_DMA),
+ UDC_DATA_DMA,
0, 0);
/* EMIFF or SDRC */
omap_set_dma_dest_burst_mode(ep->lch,
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d9d53f289caf..8409e0705d63 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -145,16 +145,6 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
return -ETIMEDOUT;
}
-static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
- u32 mask, u32 done, int usec)
-{
- int error = handshake(ehci, ptr, mask, done, usec);
- if (error)
- ehci_to_hcd(ehci)->state = HC_STATE_HALT;
-
- return error;
-}
-
/* force HC to halt state from unknown (EHCI spec section 2.3) */
static int ehci_halt (struct ehci_hcd *ehci)
{
@@ -173,6 +163,22 @@ static int ehci_halt (struct ehci_hcd *ehci)
STS_HALT, STS_HALT, 16 * 125);
}
+static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
+ u32 mask, u32 done, int usec)
+{
+ int error;
+
+ error = handshake(ehci, ptr, mask, done, usec);
+ if (error) {
+ ehci_halt(ehci);
+ ehci_to_hcd(ehci)->state = HC_STATE_HALT;
+ ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n",
+ ptr, mask, done, error);
+ }
+
+ return error;
+}
+
/* put TDI/ARC silicon into EHCI mode */
static void tdi_reset (struct ehci_hcd *ehci)
{
diff --git a/drivers/usb/host/ehci-ixp4xx.c b/drivers/usb/host/ehci-ixp4xx.c
index f9575c409124..9c32063a0c2f 100644
--- a/drivers/usb/host/ehci-ixp4xx.c
+++ b/drivers/usb/host/ehci-ixp4xx.c
@@ -1,7 +1,7 @@
/*
* IXP4XX EHCI Host Controller Driver
*
- * Author: Vladimir Barinov <vbarinov@ru.mvista.com>
+ * Author: Vladimir Barinov <vbarinov@embeddedalley.com>
*
* Based on "ehci-fsl.c" by Randy Vinson <rvinson@mvista.com>
*
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index b7853c8bac0f..4a0c5a78b2ed 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -437,6 +437,9 @@ static int enable_periodic (struct ehci_hcd *ehci)
u32 cmd;
int status;
+ if (ehci->periodic_sched++)
+ return 0;
+
/* did clearing PSE did take effect yet?
* takes effect only at frame boundaries...
*/
@@ -461,6 +464,9 @@ static int disable_periodic (struct ehci_hcd *ehci)
u32 cmd;
int status;
+ if (--ehci->periodic_sched)
+ return 0;
+
/* did setting PSE not take effect yet?
* takes effect only at frame boundaries...
*/
@@ -544,13 +550,10 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
: (qh->usecs * 8);
/* maybe enable periodic schedule processing */
- if (!ehci->periodic_sched++)
- return enable_periodic (ehci);
-
- return 0;
+ return enable_periodic(ehci);
}
-static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
{
unsigned i;
unsigned period;
@@ -586,9 +589,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
qh_put (qh);
/* maybe turn off periodic schedule */
- ehci->periodic_sched--;
- if (!ehci->periodic_sched)
- (void) disable_periodic (ehci);
+ return disable_periodic(ehci);
}
static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
@@ -1562,9 +1563,7 @@ itd_link_urb (
urb->hcpriv = NULL;
timer_action (ehci, TIMER_IO_WATCHDOG);
- if (unlikely (!ehci->periodic_sched++))
- return enable_periodic (ehci);
- return 0;
+ return enable_periodic(ehci);
}
#define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
@@ -1642,7 +1641,7 @@ itd_complete (
ehci_urb_done(ehci, urb, 0);
retval = true;
urb = NULL;
- ehci->periodic_sched--;
+ (void) disable_periodic(ehci);
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
if (unlikely (list_empty (&stream->td_list))) {
@@ -1951,9 +1950,7 @@ sitd_link_urb (
urb->hcpriv = NULL;
timer_action (ehci, TIMER_IO_WATCHDOG);
- if (!ehci->periodic_sched++)
- return enable_periodic (ehci);
- return 0;
+ return enable_periodic(ehci);
}
/*-------------------------------------------------------------------------*/
@@ -2019,7 +2016,7 @@ sitd_complete (
ehci_urb_done(ehci, urb, 0);
retval = true;
urb = NULL;
- ehci->periodic_sched--;
+ (void) disable_periodic(ehci);
ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
if (list_empty (&stream->td_list)) {
@@ -2243,8 +2240,7 @@ restart:
if (unlikely (modified)) {
if (likely(ehci->periodic_sched > 0))
goto restart;
- /* maybe we can short-circuit this scan! */
- disable_periodic(ehci);
+ /* short-circuit this scan */
now_uframe = clock;
break;
}
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 5799298364fb..b697a13364ec 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -210,143 +210,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
/*-------------------------------------------------------------------------*/
-/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */
-
-/* Section 2.2 Host Controller Capability Registers */
-struct ehci_caps {
- /* these fields are specified as 8 and 16 bit registers,
- * but some hosts can't perform 8 or 16 bit PCI accesses.
- */
- u32 hc_capbase;
-#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */
-#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */
- u32 hcs_params; /* HCSPARAMS - offset 0x4 */
-#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */
-#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */
-#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */
-#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */
-#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */
-#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */
-#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */
-
- u32 hcc_params; /* HCCPARAMS - offset 0x8 */
-#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */
-#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */
-#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */
-#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */
-#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/
-#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */
- u8 portroute [8]; /* nibbles for routing - offset 0xC */
-} __attribute__ ((packed));
-
-
-/* Section 2.3 Host Controller Operational Registers */
-struct ehci_regs {
-
- /* USBCMD: offset 0x00 */
- u32 command;
-/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */
-#define CMD_PARK (1<<11) /* enable "park" on async qh */
-#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */
-#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */
-#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */
-#define CMD_ASE (1<<5) /* async schedule enable */
-#define CMD_PSE (1<<4) /* periodic schedule enable */
-/* 3:2 is periodic frame list size */
-#define CMD_RESET (1<<1) /* reset HC not bus */
-#define CMD_RUN (1<<0) /* start/stop HC */
-
- /* USBSTS: offset 0x04 */
- u32 status;
-#define STS_ASS (1<<15) /* Async Schedule Status */
-#define STS_PSS (1<<14) /* Periodic Schedule Status */
-#define STS_RECL (1<<13) /* Reclamation */
-#define STS_HALT (1<<12) /* Not running (any reason) */
-/* some bits reserved */
- /* these STS_* flags are also intr_enable bits (USBINTR) */
-#define STS_IAA (1<<5) /* Interrupted on async advance */
-#define STS_FATAL (1<<4) /* such as some PCI access errors */
-#define STS_FLR (1<<3) /* frame list rolled over */
-#define STS_PCD (1<<2) /* port change detect */
-#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */
-#define STS_INT (1<<0) /* "normal" completion (short, ...) */
-
- /* USBINTR: offset 0x08 */
- u32 intr_enable;
-
- /* FRINDEX: offset 0x0C */
- u32 frame_index; /* current microframe number */
- /* CTRLDSSEGMENT: offset 0x10 */
- u32 segment; /* address bits 63:32 if needed */
- /* PERIODICLISTBASE: offset 0x14 */
- u32 frame_list; /* points to periodic list */
- /* ASYNCLISTADDR: offset 0x18 */
- u32 async_next; /* address of next async queue head */
-
- u32 reserved [9];
-
- /* CONFIGFLAG: offset 0x40 */
- u32 configured_flag;
-#define FLAG_CF (1<<0) /* true: we'll support "high speed" */
-
- /* PORTSC: offset 0x44 */
- u32 port_status [0]; /* up to N_PORTS */
-/* 31:23 reserved */
-#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */
-#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */
-#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */
-/* 19:16 for port testing */
-#define PORT_LED_OFF (0<<14)
-#define PORT_LED_AMBER (1<<14)
-#define PORT_LED_GREEN (2<<14)
-#define PORT_LED_MASK (3<<14)
-#define PORT_OWNER (1<<13) /* true: companion hc owns this port */
-#define PORT_POWER (1<<12) /* true: has power (see PPC) */
-#define PORT_USB11(x) (((x)&(3<<10))==(1<<10)) /* USB 1.1 device */
-/* 11:10 for detecting lowspeed devices (reset vs release ownership) */
-/* 9 reserved */
-#define PORT_RESET (1<<8) /* reset port */
-#define PORT_SUSPEND (1<<7) /* suspend port */
-#define PORT_RESUME (1<<6) /* resume it */
-#define PORT_OCC (1<<5) /* over current change */
-#define PORT_OC (1<<4) /* over current active */
-#define PORT_PEC (1<<3) /* port enable change */
-#define PORT_PE (1<<2) /* port enable */
-#define PORT_CSC (1<<1) /* connect status change */
-#define PORT_CONNECT (1<<0) /* device connected */
-#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC)
-} __attribute__ ((packed));
-
-#define USBMODE 0x68 /* USB Device mode */
-#define USBMODE_SDIS (1<<3) /* Stream disable */
-#define USBMODE_BE (1<<2) /* BE/LE endianness select */
-#define USBMODE_CM_HC (3<<0) /* host controller mode */
-#define USBMODE_CM_IDLE (0<<0) /* idle state */
-
-/* Appendix C, Debug port ... intended for use with special "debug devices"
- * that can help if there's no serial console. (nonstandard enumeration.)
- */
-struct ehci_dbg_port {
- u32 control;
-#define DBGP_OWNER (1<<30)
-#define DBGP_ENABLED (1<<28)
-#define DBGP_DONE (1<<16)
-#define DBGP_INUSE (1<<10)
-#define DBGP_ERRCODE(x) (((x)>>7)&0x07)
-# define DBGP_ERR_BAD 1
-# define DBGP_ERR_SIGNAL 2
-#define DBGP_ERROR (1<<6)
-#define DBGP_GO (1<<5)
-#define DBGP_OUT (1<<4)
-#define DBGP_LEN(x) (((x)>>0)&0x0f)
- u32 pids;
-#define DBGP_PID_GET(x) (((x)>>16)&0xff)
-#define DBGP_PID_SET(data,tok) (((data)<<8)|(tok))
- u32 data03;
- u32 data47;
- u32 address;
-#define DBGP_EPADDR(dev,ep) (((dev)<<8)|(ep))
-} __attribute__ ((packed));
+#include <linux/usb/ehci_def.h>
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c
index 7f0f35c78185..e294d430733b 100644
--- a/drivers/usb/host/ohci-pxa27x.c
+++ b/drivers/usb/host/ohci-pxa27x.c
@@ -23,17 +23,90 @@
#include <linux/signal.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
-
-#include <mach/hardware.h>
-#include <mach/pxa-regs.h>
-#include <mach/pxa2xx-regs.h> /* FIXME: for PSSR */
#include <mach/ohci.h>
+/*
+ * UHC: USB Host Controller (OHCI-like) register definitions
+ */
+#define UHCREV (0x0000) /* UHC HCI Spec Revision */
+#define UHCHCON (0x0004) /* UHC Host Control Register */
+#define UHCCOMS (0x0008) /* UHC Command Status Register */
+#define UHCINTS (0x000C) /* UHC Interrupt Status Register */
+#define UHCINTE (0x0010) /* UHC Interrupt Enable */
+#define UHCINTD (0x0014) /* UHC Interrupt Disable */
+#define UHCHCCA (0x0018) /* UHC Host Controller Comm. Area */
+#define UHCPCED (0x001C) /* UHC Period Current Endpt Descr */
+#define UHCCHED (0x0020) /* UHC Control Head Endpt Descr */
+#define UHCCCED (0x0024) /* UHC Control Current Endpt Descr */
+#define UHCBHED (0x0028) /* UHC Bulk Head Endpt Descr */
+#define UHCBCED (0x002C) /* UHC Bulk Current Endpt Descr */
+#define UHCDHEAD (0x0030) /* UHC Done Head */
+#define UHCFMI (0x0034) /* UHC Frame Interval */
+#define UHCFMR (0x0038) /* UHC Frame Remaining */
+#define UHCFMN (0x003C) /* UHC Frame Number */
+#define UHCPERS (0x0040) /* UHC Periodic Start */
+#define UHCLS (0x0044) /* UHC Low Speed Threshold */
+
+#define UHCRHDA (0x0048) /* UHC Root Hub Descriptor A */
+#define UHCRHDA_NOCP (1 << 12) /* No over current protection */
+#define UHCRHDA_OCPM (1 << 11) /* Over Current Protection Mode */
+#define UHCRHDA_POTPGT(x) \
+ (((x) & 0xff) << 24) /* Power On To Power Good Time */
+
+#define UHCRHDB (0x004C) /* UHC Root Hub Descriptor B */
+#define UHCRHS (0x0050) /* UHC Root Hub Status */
+#define UHCRHPS1 (0x0054) /* UHC Root Hub Port 1 Status */
+#define UHCRHPS2 (0x0058) /* UHC Root Hub Port 2 Status */
+#define UHCRHPS3 (0x005C) /* UHC Root Hub Port 3 Status */
+
+#define UHCSTAT (0x0060) /* UHC Status Register */
+#define UHCSTAT_UPS3 (1 << 16) /* USB Power Sense Port3 */
+#define UHCSTAT_SBMAI (1 << 15) /* System Bus Master Abort Interrupt*/
+#define UHCSTAT_SBTAI (1 << 14) /* System Bus Target Abort Interrupt*/
+#define UHCSTAT_UPRI (1 << 13) /* USB Port Resume Interrupt */
+#define UHCSTAT_UPS2 (1 << 12) /* USB Power Sense Port 2 */
+#define UHCSTAT_UPS1 (1 << 11) /* USB Power Sense Port 1 */
+#define UHCSTAT_HTA (1 << 10) /* HCI Target Abort */
+#define UHCSTAT_HBA (1 << 8) /* HCI Buffer Active */
+#define UHCSTAT_RWUE (1 << 7) /* HCI Remote Wake Up Event */
+
+#define UHCHR (0x0064) /* UHC Reset Register */
+#define UHCHR_SSEP3 (1 << 11) /* Sleep Standby Enable for Port3 */
+#define UHCHR_SSEP2 (1 << 10) /* Sleep Standby Enable for Port2 */
+#define UHCHR_SSEP1 (1 << 9) /* Sleep Standby Enable for Port1 */
+#define UHCHR_PCPL (1 << 7) /* Power control polarity low */
+#define UHCHR_PSPL (1 << 6) /* Power sense polarity low */
+#define UHCHR_SSE (1 << 5) /* Sleep Standby Enable */
+#define UHCHR_UIT (1 << 4) /* USB Interrupt Test */
+#define UHCHR_SSDC (1 << 3) /* Simulation Scale Down Clock */
+#define UHCHR_CGR (1 << 2) /* Clock Generation Reset */
+#define UHCHR_FHR (1 << 1) /* Force Host Controller Reset */
+#define UHCHR_FSBIR (1 << 0) /* Force System Bus Iface Reset */
+
+#define UHCHIE (0x0068) /* UHC Interrupt Enable Register*/
+#define UHCHIE_UPS3IE (1 << 14) /* Power Sense Port3 IntEn */
+#define UHCHIE_UPRIE (1 << 13) /* Port Resume IntEn */
+#define UHCHIE_UPS2IE (1 << 12) /* Power Sense Port2 IntEn */
+#define UHCHIE_UPS1IE (1 << 11) /* Power Sense Port1 IntEn */
+#define UHCHIE_TAIE (1 << 10) /* HCI Interface Transfer Abort
+ Interrupt Enable*/
+#define UHCHIE_HBAIE (1 << 8) /* HCI Buffer Active IntEn */
+#define UHCHIE_RWIE (1 << 7) /* Remote Wake-up IntEn */
+
+#define UHCHIT (0x006C) /* UHC Interrupt Test register */
+
#define PXA_UHC_MAX_PORTNUM 3
-#define UHCRHPS(x) __REG2( 0x4C000050, (x)<<2 )
+struct pxa27x_ohci {
+ /* must be 1st member here for hcd_to_ohci() to work */
+ struct ohci_hcd ohci;
+
+ struct device *dev;
+ struct clk *clk;
+ void __iomem *mmio_base;
+};
-static struct clk *usb_clk;
+#define to_pxa27x_ohci(hcd) (struct pxa27x_ohci *)hcd_to_ohci(hcd)
/*
PMM_NPS_MODE -- PMM Non-power switching mode
@@ -45,30 +118,35 @@ static struct clk *usb_clk;
PMM_PERPORT_MODE -- PMM per port switching mode
Ports are powered individually.
*/
-static int pxa27x_ohci_select_pmm( int mode )
+static int pxa27x_ohci_select_pmm(struct pxa27x_ohci *ohci, int mode)
{
- switch ( mode ) {
+ uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+ uint32_t uhcrhdb = __raw_readl(ohci->mmio_base + UHCRHDB);
+
+ switch (mode) {
case PMM_NPS_MODE:
- UHCRHDA |= RH_A_NPS;
+ uhcrhda |= RH_A_NPS;
break;
case PMM_GLOBAL_MODE:
- UHCRHDA &= ~(RH_A_NPS & RH_A_PSM);
+ uhcrhda &= ~(RH_A_NPS & RH_A_PSM);
break;
case PMM_PERPORT_MODE:
- UHCRHDA &= ~(RH_A_NPS);
- UHCRHDA |= RH_A_PSM;
+ uhcrhda &= ~(RH_A_NPS);
+ uhcrhda |= RH_A_PSM;
/* Set port power control mask bits, only 3 ports. */
- UHCRHDB |= (0x7<<17);
+ uhcrhdb |= (0x7<<17);
break;
default:
printk( KERN_ERR
"Invalid mode %d, set to non-power switch mode.\n",
mode );
- UHCRHDA |= RH_A_NPS;
+ uhcrhda |= RH_A_NPS;
}
+ __raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+ __raw_writel(uhcrhdb, ohci->mmio_base + UHCRHDB);
return 0;
}
@@ -76,57 +154,110 @@ extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/
-static int pxa27x_start_hc(struct device *dev)
+static inline void pxa27x_setup_hc(struct pxa27x_ohci *ohci,
+ struct pxaohci_platform_data *inf)
+{
+ uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+ uint32_t uhcrhda = __raw_readl(ohci->mmio_base + UHCRHDA);
+
+ if (inf->flags & ENABLE_PORT1)
+ uhchr &= ~UHCHR_SSEP1;
+
+ if (inf->flags & ENABLE_PORT2)
+ uhchr &= ~UHCHR_SSEP2;
+
+ if (inf->flags & ENABLE_PORT3)
+ uhchr &= ~UHCHR_SSEP3;
+
+ if (inf->flags & POWER_CONTROL_LOW)
+ uhchr |= UHCHR_PCPL;
+
+ if (inf->flags & POWER_SENSE_LOW)
+ uhchr |= UHCHR_PSPL;
+
+ if (inf->flags & NO_OC_PROTECTION)
+ uhcrhda |= UHCRHDA_NOCP;
+
+ if (inf->flags & OC_MODE_PERPORT)
+ uhcrhda |= UHCRHDA_OCPM;
+
+ if (inf->power_on_delay) {
+ uhcrhda &= ~UHCRHDA_POTPGT(0xff);
+ uhcrhda |= UHCRHDA_POTPGT(inf->power_on_delay / 2);
+ }
+
+ __raw_writel(uhchr, ohci->mmio_base + UHCHR);
+ __raw_writel(uhcrhda, ohci->mmio_base + UHCRHDA);
+}
+
+static inline void pxa27x_reset_hc(struct pxa27x_ohci *ohci)
+{
+ uint32_t uhchr = __raw_readl(ohci->mmio_base + UHCHR);
+
+ __raw_writel(uhchr | UHCHR_FHR, ohci->mmio_base + UHCHR);
+ udelay(11);
+ __raw_writel(uhchr & ~UHCHR_FHR, ohci->mmio_base + UHCHR);
+}
+
+#ifdef CONFIG_CPU_PXA27x
+extern void pxa27x_clear_otgph(void);
+#else
+#define pxa27x_clear_otgph() do {} while (0)
+#endif
+
+static int pxa27x_start_hc(struct pxa27x_ohci *ohci, struct device *dev)
{
int retval = 0;
struct pxaohci_platform_data *inf;
+ uint32_t uhchr;
inf = dev->platform_data;
- clk_enable(usb_clk);
+ clk_enable(ohci->clk);
- UHCHR |= UHCHR_FHR;
- udelay(11);
- UHCHR &= ~UHCHR_FHR;
+ pxa27x_reset_hc(ohci);
+
+ uhchr = __raw_readl(ohci->mmio_base + UHCHR) | UHCHR_FSBIR;
+ __raw_writel(uhchr, ohci->mmio_base + UHCHR);
- UHCHR |= UHCHR_FSBIR;
- while (UHCHR & UHCHR_FSBIR)
+ while (__raw_readl(ohci->mmio_base + UHCHR) & UHCHR_FSBIR)
cpu_relax();
+ pxa27x_setup_hc(ohci, inf);
+
if (inf->init)
retval = inf->init(dev);
if (retval < 0)
return retval;
- UHCHR &= ~UHCHR_SSE;
-
- UHCHIE = (UHCHIE_UPRIE | UHCHIE_RWIE);
+ uhchr = __raw_readl(ohci->mmio_base + UHCHR) & ~UHCHR_SSE;
+ __raw_writel(uhchr, ohci->mmio_base + UHCHR);
+ __raw_writel(UHCHIE_UPRIE | UHCHIE_RWIE, ohci->mmio_base + UHCHIE);
/* Clear any OTG Pin Hold */
- if (cpu_is_pxa27x() && (PSSR & PSSR_OTGPH))
- PSSR |= PSSR_OTGPH;
-
+ pxa27x_clear_otgph();
return 0;
}
-static void pxa27x_stop_hc(struct device *dev)
+static void pxa27x_stop_hc(struct pxa27x_ohci *ohci, struct device *dev)
{
struct pxaohci_platform_data *inf;
+ uint32_t uhccoms;
inf = dev->platform_data;
if (inf->exit)
inf->exit(dev);
- UHCHR |= UHCHR_FHR;
- udelay(11);
- UHCHR &= ~UHCHR_FHR;
+ pxa27x_reset_hc(ohci);
- UHCCOMS |= 1;
+ /* Host Controller Reset */
+ uhccoms = __raw_readl(ohci->mmio_base + UHCCOMS) | 0x01;
+ __raw_writel(uhccoms, ohci->mmio_base + UHCCOMS);
udelay(10);
- clk_disable(usb_clk);
+ clk_disable(ohci->clk);
}
@@ -147,18 +278,22 @@ static void pxa27x_stop_hc(struct device *dev)
*/
int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device *pdev)
{
- int retval;
+ int retval, irq;
struct usb_hcd *hcd;
struct pxaohci_platform_data *inf;
+ struct pxa27x_ohci *ohci;
+ struct resource *r;
+ struct clk *usb_clk;
inf = pdev->dev.platform_data;
if (!inf)
return -ENODEV;
- if (pdev->resource[1].flags != IORESOURCE_IRQ) {
- pr_debug ("resource[1] is not IORESOURCE_IRQ");
- return -ENOMEM;
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ pr_err("no resource of IORESOURCE_IRQ");
+ return -ENXIO;
}
usb_clk = clk_get(&pdev->dev, "USBCLK");
@@ -168,8 +303,16 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
hcd = usb_create_hcd (driver, &pdev->dev, "pxa27x");
if (!hcd)
return -ENOMEM;
- hcd->rsrc_start = pdev->resource[0].start;
- hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ pr_err("no resource of IORESOURCE_MEM");
+ retval = -ENXIO;
+ goto err1;
+ }
+
+ hcd->rsrc_start = r->start;
+ hcd->rsrc_len = resource_size(r);
if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
pr_debug("request_mem_region failed");
@@ -184,24 +327,30 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
goto err2;
}
- if ((retval = pxa27x_start_hc(&pdev->dev)) < 0) {
+ /* initialize "struct pxa27x_ohci" */
+ ohci = (struct pxa27x_ohci *)hcd_to_ohci(hcd);
+ ohci->dev = &pdev->dev;
+ ohci->clk = usb_clk;
+ ohci->mmio_base = (void __iomem *)hcd->regs;
+
+ if ((retval = pxa27x_start_hc(ohci, &pdev->dev)) < 0) {
pr_debug("pxa27x_start_hc failed");
goto err3;
}
/* Select Power Management Mode */
- pxa27x_ohci_select_pmm(inf->port_mode);
+ pxa27x_ohci_select_pmm(ohci, inf->port_mode);
if (inf->power_budget)
hcd->power_budget = inf->power_budget;
ohci_hcd_init(hcd_to_ohci(hcd));
- retval = usb_add_hcd(hcd, pdev->resource[1].start, IRQF_DISABLED);
+ retval = usb_add_hcd(hcd, irq, IRQF_DISABLED);
if (retval == 0)
return retval;
- pxa27x_stop_hc(&pdev->dev);
+ pxa27x_stop_hc(ohci, &pdev->dev);
err3:
iounmap(hcd->regs);
err2:
@@ -228,12 +377,14 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device
*/
void usb_hcd_pxa27x_remove (struct usb_hcd *hcd, struct platform_device *pdev)
{
+ struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
+
usb_remove_hcd(hcd);
- pxa27x_stop_hc(&pdev->dev);
+ pxa27x_stop_hc(ohci, &pdev->dev);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
- clk_put(usb_clk);
+ clk_put(ohci->clk);
}
/*-------------------------------------------------------------------------*/
@@ -266,7 +417,7 @@ ohci_pxa27x_start (struct usb_hcd *hcd)
static const struct hc_driver ohci_pxa27x_hc_driver = {
.description = hcd_name,
.product_desc = "PXA27x OHCI",
- .hcd_priv_size = sizeof(struct ohci_hcd),
+ .hcd_priv_size = sizeof(struct pxa27x_ohci),
/*
* generic hardware linkage
@@ -330,13 +481,13 @@ static int ohci_hcd_pxa27x_drv_remove(struct platform_device *pdev)
static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_t state)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
- if (time_before(jiffies, ohci->next_statechange))
+ if (time_before(jiffies, ohci->ohci.next_statechange))
msleep(5);
- ohci->next_statechange = jiffies;
+ ohci->ohci.next_statechange = jiffies;
- pxa27x_stop_hc(&pdev->dev);
+ pxa27x_stop_hc(ohci, &pdev->dev);
hcd->state = HC_STATE_SUSPENDED;
return 0;
@@ -345,14 +496,14 @@ static int ohci_hcd_pxa27x_drv_suspend(struct platform_device *pdev, pm_message_
static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ struct pxa27x_ohci *ohci = to_pxa27x_ohci(hcd);
int status;
- if (time_before(jiffies, ohci->next_statechange))
+ if (time_before(jiffies, ohci->ohci.next_statechange))
msleep(5);
- ohci->next_statechange = jiffies;
+ ohci->ohci.next_statechange = jiffies;
- if ((status = pxa27x_start_hc(&pdev->dev)) < 0)
+ if ((status = pxa27x_start_hc(ohci, &pdev->dev)) < 0)
return status;
ohci_finish_controller_resume(hcd);
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c
index 5da63f535005..516848dd9b48 100644
--- a/drivers/usb/host/sl811_cs.c
+++ b/drivers/usb/host/sl811_cs.c
@@ -112,7 +112,8 @@ static struct platform_device platform_dev = {
.num_resources = ARRAY_SIZE(resources),
};
-static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq)
+static int sl811_hc_init(struct device *parent, resource_size_t base_addr,
+ int irq)
{
if (platform_dev.dev.parent)
return -EBUSY;
@@ -155,97 +156,72 @@ static void sl811_cs_release(struct pcmcia_device * link)
platform_device_unregister(&platform_dev);
}
+static int sl811_cs_config_check(struct pcmcia_device *p_dev,
+ cistpl_cftable_entry_t *cfg,
+ cistpl_cftable_entry_t *dflt,
+ unsigned int vcc,
+ void *priv_data)
+{
+ if (cfg->index == 0)
+ return -ENODEV;
+
+ /* Use power settings for Vcc and Vpp if present */
+ /* Note that the CIS values need to be rescaled */
+ if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+ if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
+ return -ENODEV;
+ } else if (dflt->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+ if (dflt->vcc.param[CISTPL_POWER_VNOM]/10000 != vcc)
+ return -ENODEV;
+ }
+
+ if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
+ p_dev->conf.Vpp =
+ cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
+ else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
+ p_dev->conf.Vpp =
+ dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;
+
+ /* we need an interrupt */
+ if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
+ p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
+
+ p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->io.BasePort1 = io->win[0].base;
+ p_dev->io.NumPorts1 = io->win[0].len;
+
+ return pcmcia_request_io(p_dev, &p_dev->io);
+ }
+ pcmcia_disable_device(p_dev);
+ return -ENODEV;
+}
+
+
static int sl811_cs_config(struct pcmcia_device *link)
{
struct device *parent = &handle_to_dev(link);
local_info_t *dev = link->priv;
- tuple_t tuple;
- cisparse_t parse;
int last_fn, last_ret;
- u_char buf[64];
- config_info_t conf;
- cistpl_cftable_entry_t dflt = { 0 };
DBG(0, "sl811_cs_config(0x%p)\n", link);
- /* Look up the current Vcc */
- CS_CHECK(GetConfigurationInfo,
- pcmcia_get_configuration_info(link, &conf));
-
- tuple.Attributes = 0;
- tuple.TupleData = buf;
- tuple.TupleDataMax = sizeof(buf);
- tuple.TupleOffset = 0;
- tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
- CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-
- if (pcmcia_get_tuple_data(link, &tuple) != 0
- || pcmcia_parse_tuple(link, &tuple, &parse)
- != 0)
- goto next_entry;
-
- if (cfg->flags & CISTPL_CFTABLE_DEFAULT) {
- dflt = *cfg;
- }
-
- if (cfg->index == 0)
- goto next_entry;
-
- link->conf.ConfigIndex = cfg->index;
-
- /* Use power settings for Vcc and Vpp if present */
- /* Note that the CIS values need to be rescaled */
- if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
- if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000
- != conf.Vcc)
- goto next_entry;
- } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
- if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000
- != conf.Vcc)
- goto next_entry;
- }
-
- if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
- link->conf.Vpp =
- cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
- else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
- link->conf.Vpp =
- dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
-
- /* we need an interrupt */
- if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
- link->conf.Attributes |= CONF_ENABLE_IRQ;
-
- /* IO window settings */
- link->io.NumPorts1 = link->io.NumPorts2 = 0;
- if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
- cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
-
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- link->io.BasePort1 = io->win[0].base;
- link->io.NumPorts1 = io->win[0].len;
-
- if (pcmcia_request_io(link, &link->io) != 0)
- goto next_entry;
- }
- break;
-
-next_entry:
- pcmcia_disable_device(link);
- last_ret = pcmcia_get_next_tuple(link, &tuple);
- }
+ if (pcmcia_loop_config(link, sl811_cs_config_check, NULL))
+ goto failed;
/* require an IRQ and two registers */
if (!link->io.NumPorts1 || link->io.NumPorts1 < 2)
- goto cs_failed;
+ goto failed;
if (link->conf.Attributes & CONF_ENABLE_IRQ)
CS_CHECK(RequestIRQ,
pcmcia_request_irq(link, &link->irq));
else
- goto cs_failed;
+ goto failed;
CS_CHECK(RequestConfiguration,
pcmcia_request_configuration(link, &link->conf));
@@ -266,8 +242,9 @@ next_entry:
if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ)
< 0) {
cs_failed:
- printk("sl811_cs_config failed\n");
cs_error(link, last_fn, last_ret);
+failed:
+ printk(KERN_WARNING "sl811_cs_config failed\n");
sl811_cs_release(link);
return -ENODEV;
}
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
index a0017486ad4e..58b2b8fc9439 100644
--- a/drivers/usb/musb/Kconfig
+++ b/drivers/usb/musb/Kconfig
@@ -9,6 +9,7 @@ comment "Enable Host or Gadget support to see Inventra options"
# (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
config USB_MUSB_HDRC
depends on (USB || USB_GADGET) && HAVE_CLK
+ depends on !SUPERH
select TWL4030_USB if MACH_OMAP_3430SDP
tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
help
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index c5b8f0296fcf..128e949db47c 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -100,8 +100,8 @@
#include <linux/io.h>
#ifdef CONFIG_ARM
-#include <asm/arch/hardware.h>
-#include <asm/arch/memory.h>
+#include <mach/hardware.h>
+#include <mach/memory.h>
#include <asm/mach-types.h>
#endif
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 298b22e6ad0d..9d2dcb121c5e 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -35,8 +35,8 @@
#include <linux/io.h>
#include <asm/mach-types.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/mux.h>
+#include <mach/hardware.h>
+#include <mach/mux.h>
#include "musb_core.h"
#include "omap2430.h"
diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h
index 786a62071f72..dc7670718cd2 100644
--- a/drivers/usb/musb/omap2430.h
+++ b/drivers/usb/musb/omap2430.h
@@ -11,8 +11,8 @@
#define __MUSB_OMAP243X_H__
#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
-#include <asm/arch/hardware.h>
-#include <asm/arch/usb.h>
+#include <mach/hardware.h>
+#include <mach/usb.h>
/*
* OMAP2430-specific definitions
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index 79ea98c66fa8..99fb7dc59c45 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -272,7 +272,7 @@ static void aircable_read(struct work_struct *work)
* 64 bytes, to ensure I do not get throttled.
* Ask USB mailing list for better aproach.
*/
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
schedule_work(&priv->rx_work);
@@ -283,12 +283,13 @@ static void aircable_read(struct work_struct *work)
count = min(64, serial_buf_data_avail(priv->rx_buf));
if (count <= 0)
- return; /* We have finished sending everything. */
+ goto out; /* We have finished sending everything. */
tty_prepare_flip_string(tty, &data, count);
if (!data) {
- err("%s- kzalloc(%d) failed.", __func__, count);
- return;
+ dev_err(&port->dev, "%s- kzalloc(%d) failed.",
+ __func__, count);
+ goto out;
}
serial_buf_get(priv->rx_buf, data, count);
@@ -297,7 +298,8 @@ static void aircable_read(struct work_struct *work)
if (serial_buf_data_avail(priv->rx_buf))
schedule_work(&priv->rx_work);
-
+out:
+ tty_kref_put(tty);
return;
}
/* End of private methods */
@@ -495,7 +497,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, urb->transfer_buffer);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
if (urb->actual_length <= 2) {
/* This is an incomplete package */
@@ -527,6 +529,7 @@ static void aircable_read_bulk_callback(struct urb *urb)
}
aircable_read(&priv->rx_work);
}
+ tty_kref_put(tty);
/* Schedule the next read _if_ we are still open */
if (port->port.count) {
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 2ebe06c3405a..1913bc7c5f0b 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -322,7 +322,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
* to look in to this before committing any code.
*/
if (priv->last_lsr & BELKIN_SA_LSR_ERR) {
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
/* Overrun Error */
if (priv->last_lsr & BELKIN_SA_LSR_OE) {
}
@@ -335,6 +335,7 @@ static void belkin_sa_read_int_callback(struct urb *urb)
/* Break Indicator */
if (priv->last_lsr & BELKIN_SA_LSR_BI) {
}
+ tty_kref_put(tty);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index e980766bb84b..5b20de130e08 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -117,7 +117,7 @@ static int usb_console_setup(struct console *co, char *options)
}
port = serial->port[0];
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
info->port = port;
@@ -143,7 +143,7 @@ static int usb_console_setup(struct console *co, char *options)
}
memset(&dummy, 0, sizeof(struct ktermios));
tty->termios = termios;
- port->port.tty = tty;
+ tty_port_tty_set(&port->port, tty);
}
/* only call the device specific open if this
@@ -163,7 +163,7 @@ static int usb_console_setup(struct console *co, char *options)
tty_termios_encode_baud_rate(termios, baud, baud);
serial->type->set_termios(tty, port, &dummy);
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
kfree(termios);
kfree(tty);
}
@@ -176,7 +176,7 @@ out:
return retval;
free_termios:
kfree(termios);
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
free_tty:
kfree(tty);
reset_open_count:
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 442cba69cce5..1279553381e3 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -72,6 +72,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
{ USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
{ USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
+ { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
{ USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
{ USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
{ USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
@@ -83,6 +84,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
+ { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
@@ -93,6 +95,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
{ USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
{ } /* Terminating Entry */
};
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index b4d72351cb96..94ef36c4764b 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -384,7 +384,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
return;
}
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
dbg("%s - ignoring since device not open\n", __func__);
return;
@@ -394,6 +394,7 @@ static void cyberjack_read_bulk_callback(struct urb *urb)
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
spin_lock(&priv->lock);
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 22837a3f2f89..f3514a91f915 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -1286,7 +1286,7 @@ static void cypress_read_int_callback(struct urb *urb)
}
spin_unlock_irqrestore(&priv->lock, flags);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
dbg("%s - bad tty pointer - exiting", __func__);
return;
@@ -1362,7 +1362,7 @@ static void cypress_read_int_callback(struct urb *urb)
data[i]);
tty_insert_flip_char(tty, data[i], tty_flag);
}
- tty_flip_buffer_push(port->port.tty);
+ tty_flip_buffer_push(tty);
}
spin_lock_irqsave(&priv->lock, flags);
@@ -1371,6 +1371,7 @@ static void cypress_read_int_callback(struct urb *urb)
spin_unlock_irqrestore(&priv->lock, flags);
continue_read:
+ tty_kref_put(tty);
/* Continue trying to always read... unless the port has closed. */
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 240aad1acaab..5756ac6d6c92 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -604,7 +604,9 @@ static void digi_wakeup_write_lock(struct work_struct *work)
static void digi_wakeup_write(struct usb_serial_port *port)
{
- tty_wakeup(port->port.tty);
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ tty_wakeup(tty);
+ tty_kref_put(tty);
}
@@ -1668,7 +1670,7 @@ static int digi_read_inb_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty;
struct digi_port *priv = usb_get_serial_port_data(port);
int opcode = ((unsigned char *)urb->transfer_buffer)[0];
int len = ((unsigned char *)urb->transfer_buffer)[1];
@@ -1692,6 +1694,7 @@ static int digi_read_inb_callback(struct urb *urb)
return -1;
}
+ tty = tty_port_tty_get(&port->port);
spin_lock(&priv->dp_port_lock);
/* check for throttle; if set, do not resubmit read urb */
@@ -1735,6 +1738,7 @@ static int digi_read_inb_callback(struct urb *urb)
}
}
spin_unlock(&priv->dp_port_lock);
+ tty_kref_put(tty);
if (opcode == DIGI_CMD_RECEIVE_DISABLE)
dbg("%s: got RECEIVE_DISABLE", __func__);
@@ -1760,6 +1764,7 @@ static int digi_read_oob_callback(struct urb *urb)
struct usb_serial_port *port = urb->context;
struct usb_serial *serial = port->serial;
+ struct tty_struct *tty;
struct digi_port *priv = usb_get_serial_port_data(port);
int opcode, line, status, val;
int i;
@@ -1787,10 +1792,11 @@ static int digi_read_oob_callback(struct urb *urb)
if (priv == NULL)
return -1;
+ tty = tty_port_tty_get(&port->port);
rts = 0;
if (port->port.count)
- rts = port->port.tty->termios->c_cflag & CRTSCTS;
-
+ rts = tty->termios->c_cflag & CRTSCTS;
+
if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
spin_lock(&priv->dp_port_lock);
/* convert from digi flags to termiox flags */
@@ -1798,14 +1804,14 @@ static int digi_read_oob_callback(struct urb *urb)
priv->dp_modem_signals |= TIOCM_CTS;
/* port must be open to use tty struct */
if (rts) {
- port->port.tty->hw_stopped = 0;
+ tty->hw_stopped = 0;
digi_wakeup_write(port);
}
} else {
priv->dp_modem_signals &= ~TIOCM_CTS;
/* port must be open to use tty struct */
if (rts)
- port->port.tty->hw_stopped = 1;
+ tty->hw_stopped = 1;
}
if (val & DIGI_READ_INPUT_SIGNALS_DSR)
priv->dp_modem_signals |= TIOCM_DSR;
@@ -1830,6 +1836,7 @@ static int digi_read_oob_callback(struct urb *urb)
} else if (opcode == DIGI_CMD_IFLUSH_FIFO) {
wake_up_interruptible(&priv->dp_flush_wait);
}
+ tty_kref_put(tty);
}
return 0;
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index a6ab5b58d9ca..1072e847280f 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -33,9 +33,8 @@
* Moved MOD_DEC_USE_COUNT to end of empeg_close().
*
* (12/03/2000) gb
- * Added port->port.tty->ldisc.set_termios(port->port.tty, NULL) to
- * empeg_open(). This notifies the tty driver that the termios have
- * changed.
+ * Added tty->ldisc.set_termios(port, tty, NULL) to empeg_open().
+ * This notifies the tty driver that the termios have changed.
*
* (11/13/2000) gb
* Moved tty->low_latency = 1 from empeg_read_bulk_callback() to
@@ -354,7 +353,7 @@ static void empeg_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
@@ -362,6 +361,7 @@ static void empeg_read_bulk_callback(struct urb *urb)
tty_flip_buffer_push(tty);
bytes_in += urb->actual_length;
}
+ tty_kref_put(tty);
/* Continue trying to always read */
usb_fill_bulk_urb(
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 984f6eff4c47..c2ac129557aa 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -654,6 +654,9 @@ static struct usb_device_id id_table_combined [] = {
.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
+ { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
@@ -857,7 +860,7 @@ static int update_mctrl(struct usb_serial_port *port, unsigned int set,
kfree(buf);
if (rv < 0) {
- err("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
+ dbg("%s Error from MODEM_CTRL urb: DTR %s, RTS %s",
__func__,
(set & TIOCM_DTR) ? "HIGH" :
(clear & TIOCM_DTR) ? "LOW" : "unchanged",
@@ -1805,7 +1808,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
if (port->port.count <= 0)
return;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
dbg("%s - bad tty pointer - exiting", __func__);
return;
@@ -1814,7 +1817,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
priv = usb_get_serial_port_data(port);
if (!priv) {
dbg("%s - bad port private data pointer - exiting", __func__);
- return;
+ goto out;
}
if (urb != port->read_urb)
@@ -1824,7 +1827,7 @@ static void ftdi_read_bulk_callback(struct urb *urb)
/* This will happen at close every time so it is a dbg not an
err */
dbg("(this is ok on close) nonzero read bulk status received: %d", status);
- return;
+ goto out;
}
/* count data bytes, but not status bytes */
@@ -1835,7 +1838,8 @@ static void ftdi_read_bulk_callback(struct urb *urb)
spin_unlock_irqrestore(&priv->rx_lock, flags);
ftdi_process_read(&priv->rx_work.work);
-
+out:
+ tty_kref_put(tty);
} /* ftdi_read_bulk_callback */
@@ -1860,7 +1864,7 @@ static void ftdi_process_read(struct work_struct *work)
if (port->port.count <= 0)
return;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty) {
dbg("%s - bad tty pointer - exiting", __func__);
return;
@@ -1869,13 +1873,13 @@ static void ftdi_process_read(struct work_struct *work)
priv = usb_get_serial_port_data(port);
if (!priv) {
dbg("%s - bad port private data pointer - exiting", __func__);
- return;
+ goto out;
}
urb = port->read_urb;
if (!urb) {
dbg("%s - bad read_urb pointer - exiting", __func__);
- return;
+ goto out;
}
data = urb->transfer_buffer;
@@ -2017,7 +2021,7 @@ static void ftdi_process_read(struct work_struct *work)
schedule_delayed_work(&priv->rx_work, 1);
else
dbg("%s - port is closed", __func__);
- return;
+ goto out;
}
/* urb is completely processed */
@@ -2038,6 +2042,8 @@ static void ftdi_process_read(struct work_struct *work)
err("%s - failed resubmitting read urb, error %d",
__func__, result);
}
+out:
+ tty_kref_put(tty);
} /* ftdi_process_read */
@@ -2253,7 +2259,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
0, 0,
buf, 1, WDR_TIMEOUT);
if (ret < 0) {
- err("%s Could not get modem status of device - err: %d", __func__,
+ dbg("%s Could not get modem status of device - err: %d", __func__,
ret);
return ret;
}
@@ -2272,7 +2278,7 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file)
0, priv->interface,
buf, 2, WDR_TIMEOUT);
if (ret < 0) {
- err("%s Could not get modem status of device - err: %d", __func__,
+ dbg("%s Could not get modem status of device - err: %d", __func__,
ret);
return ret;
}
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h
index 382265bba969..8a5b6df3a976 100644
--- a/drivers/usb/serial/ftdi_sio.h
+++ b/drivers/usb/serial/ftdi_sio.h
@@ -750,6 +750,7 @@
#define PAPOUCH_VID 0x5050 /* Vendor ID */
#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */
+#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */
/*
* ACG Identification Technologies GmbH products (http://www.acg.de/).
@@ -838,6 +839,10 @@
/* Rig Expert Ukraine devices */
#define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */
+/* Domintell products http://www.domintell.com */
+#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */
+#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */
+
/* Commands */
#define FTDI_SIO_RESET 0 /* Reset the port */
#define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index d95382088075..2ad0569bcf19 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -276,7 +276,7 @@ static inline int isAbortTrfCmnd(const unsigned char *buf)
static void send_to_tty(struct usb_serial_port *port,
char *data, unsigned int actual_length)
{
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
if (tty && actual_length) {
@@ -287,6 +287,7 @@ static void send_to_tty(struct usb_serial_port *port,
tty_insert_flip_string(tty, data, actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
}
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index fe84c88ec20c..814909f1ee63 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -330,7 +330,7 @@ static void resubmit_read_urb(struct usb_serial_port *port, gfp_t mem_flags)
static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
{
struct urb *urb = port->read_urb;
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
int room;
/* Push data to tty */
@@ -341,6 +341,7 @@ static void flush_and_resubmit_read_urb(struct usb_serial_port *port)
tty_flip_buffer_push(tty);
}
}
+ tty_kref_put(tty);
resubmit_read_urb(port, GFP_ATOMIC);
}
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index bfa508ddb0fe..611f97fd62f1 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -600,6 +600,7 @@ static void edge_interrupt_callback(struct urb *urb)
struct edgeport_serial *edge_serial = urb->context;
struct edgeport_port *edge_port;
struct usb_serial_port *port;
+ struct tty_struct *tty;
unsigned char *data = urb->transfer_buffer;
int length = urb->actual_length;
int bytes_avail;
@@ -675,9 +676,12 @@ static void edge_interrupt_callback(struct urb *urb)
/* tell the tty driver that something
has changed */
- if (edge_port->port->port.tty)
- tty_wakeup(edge_port->port->port.tty);
-
+ tty = tty_port_tty_get(
+ &edge_port->port->port);
+ if (tty) {
+ tty_wakeup(tty);
+ tty_kref_put(tty);
+ }
/* Since we have more credit, check
if more data can be sent */
send_more_port_data(edge_serial,
@@ -778,13 +782,14 @@ static void edge_bulk_out_data_callback(struct urb *urb)
__func__, status);
}
- tty = edge_port->port->port.tty;
+ tty = tty_port_tty_get(&edge_port->port->port);
if (tty && edge_port->open) {
/* let the tty driver wakeup if it has a special
write_wakeup function */
tty_wakeup(tty);
}
+ tty_kref_put(tty);
/* Release the Write URB */
edge_port->write_in_progress = false;
@@ -826,11 +831,12 @@ static void edge_bulk_out_cmd_callback(struct urb *urb)
}
/* Get pointer to tty */
- tty = edge_port->port->port.tty;
+ tty = tty_port_tty_get(&edge_port->port->port);
/* tell the tty driver that something has changed */
if (tty && edge_port->open)
tty_wakeup(tty);
+ tty_kref_put(tty);
/* we have completed the command */
edge_port->commandPending = false;
@@ -1932,11 +1938,13 @@ static void process_rcvd_data(struct edgeport_serial *edge_serial,
edge_serial->rxPort];
edge_port = usb_get_serial_port_data(port);
if (edge_port->open) {
- tty = edge_port->port->port.tty;
+ tty = tty_port_tty_get(
+ &edge_port->port->port);
if (tty) {
dbg("%s - Sending %d bytes to TTY for port %d",
__func__, rxLen, edge_serial->rxPort);
edge_tty_recv(&edge_serial->serial->dev->dev, tty, buffer, rxLen);
+ tty_kref_put(tty);
}
edge_port->icount.rx += rxLen;
}
@@ -1971,6 +1979,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
{
struct usb_serial_port *port;
struct edgeport_port *edge_port;
+ struct tty_struct *tty;
__u8 code = edge_serial->rxStatusCode;
/* switch the port pointer to the one being currently talked about */
@@ -2020,10 +2029,12 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
/* send the current line settings to the port so we are
in sync with any further termios calls */
- /* FIXME: locking on tty */
- if (edge_port->port->port.tty)
- change_port_settings(edge_port->port->port.tty,
- edge_port, edge_port->port->port.tty->termios);
+ tty = tty_port_tty_get(&edge_port->port->port);
+ if (tty) {
+ change_port_settings(tty,
+ edge_port, tty->termios);
+ tty_kref_put(tty);
+ }
/* we have completed the open */
edge_port->openPending = false;
@@ -2163,10 +2174,14 @@ static void handle_new_lsr(struct edgeport_port *edge_port, __u8 lsrData,
}
/* Place LSR data byte into Rx buffer */
- if (lsrData && edge_port->port->port.tty)
- edge_tty_recv(&edge_port->port->dev,
- edge_port->port->port.tty, &data, 1);
-
+ if (lsrData) {
+ struct tty_struct *tty =
+ tty_port_tty_get(&edge_port->port->port);
+ if (tty) {
+ edge_tty_recv(&edge_port->port->dev, tty, &data, 1);
+ tty_kref_put(tty);
+ }
+ }
/* update input line counters */
icount = &edge_port->icount;
if (newLsr & LSR_BREAK)
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index cb4c54316cf5..541dd8e6e7a2 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -572,7 +572,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
int flush)
{
int baud_rate;
- struct tty_struct *tty = port->port->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->port->port);
wait_queue_t wait;
unsigned long flags;
@@ -599,6 +599,7 @@ static void chase_port(struct edgeport_port *port, unsigned long timeout,
if (flush)
edge_buf_clear(port->ep_out_buf);
spin_unlock_irqrestore(&port->ep_lock, flags);
+ tty_kref_put(tty);
/* wait for data to drain from the device */
timeout += jiffies;
@@ -1554,7 +1555,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
/* Save the new modem status */
edge_port->shadow_msr = msr & 0xf0;
- tty = edge_port->port->port.tty;
+ tty = tty_port_tty_get(&edge_port->port->port);
/* handle CTS flow control */
if (tty && C_CRTSCTS(tty)) {
if (msr & EDGEPORT_MSR_CTS) {
@@ -1564,6 +1565,7 @@ static void handle_new_msr(struct edgeport_port *edge_port, __u8 msr)
tty->hw_stopped = 1;
}
}
+ tty_kref_put(tty);
return;
}
@@ -1574,6 +1576,7 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
struct async_icount *icount;
__u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR |
LSR_FRM_ERR | LSR_BREAK));
+ struct tty_struct *tty;
dbg("%s - %02x", __func__, new_lsr);
@@ -1587,8 +1590,13 @@ static void handle_new_lsr(struct edgeport_port *edge_port, int lsr_data,
new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
/* Place LSR data byte into Rx buffer */
- if (lsr_data && edge_port->port->port.tty)
- edge_tty_recv(&edge_port->port->dev, edge_port->port->port.tty, &data, 1);
+ if (lsr_data) {
+ tty = tty_port_tty_get(&edge_port->port->port);
+ if (tty) {
+ edge_tty_recv(&edge_port->port->dev, tty, &data, 1);
+ tty_kref_put(tty);
+ }
+ }
/* update input line counters */
icount = &edge_port->icount;
@@ -1749,7 +1757,7 @@ static void edge_bulk_in_callback(struct urb *urb)
++data;
}
- tty = edge_port->port->port.tty;
+ tty = tty_port_tty_get(&edge_port->port->port);
if (tty && urb->actual_length) {
usb_serial_debug_data(debug, &edge_port->port->dev,
__func__, urb->actual_length, data);
@@ -1761,6 +1769,7 @@ static void edge_bulk_in_callback(struct urb *urb)
urb->actual_length);
edge_port->icount.rx += urb->actual_length;
}
+ tty_kref_put(tty);
exit:
/* continue read unless stopped */
@@ -1796,6 +1805,7 @@ static void edge_bulk_out_callback(struct urb *urb)
struct usb_serial_port *port = urb->context;
struct edgeport_port *edge_port = usb_get_serial_port_data(port);
int status = urb->status;
+ struct tty_struct *tty;
dbg("%s - port %d", __func__, port->number);
@@ -1818,7 +1828,9 @@ static void edge_bulk_out_callback(struct urb *urb)
}
/* send any buffered data */
- edge_send(port->port.tty);
+ tty = tty_port_tty_get(&port->port);
+ edge_send(tty);
+ tty_kref_put(tty);
}
static int edge_open(struct tty_struct *tty,
@@ -1876,7 +1888,7 @@ static int edge_open(struct tty_struct *tty,
/* set up the port settings */
if (tty)
- edge_set_termios(tty, port, port->port.tty->termios);
+ edge_set_termios(tty, port, tty->termios);
/* open up the port */
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index cd9a2e138c8b..2affa9c118b2 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -764,13 +764,14 @@ static void ipaq_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
bytes_in += urb->actual_length;
}
+ tty_kref_put(tty);
/* Continue trying to always read */
usb_fill_bulk_urb(port->read_urb, port->serial->dev,
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index a842025b9b57..480cac27d646 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -170,12 +170,13 @@ static void ipw_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* Continue trying to always read */
usb_fill_bulk_urb(port->read_urb, port->serial->dev,
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index e59155c6607d..45d4043e04ab 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -465,11 +465,12 @@ static void ir_read_bulk_callback(struct urb *urb)
ir_baud = *data & 0x0f;
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty_buffer_request_room(tty, urb->actual_length - 1)) {
tty_insert_flip_string(tty, data+1, urb->actual_length - 1);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/*
* No break here.
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index ddff37fa6339..53710aa7eadd 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -629,13 +629,14 @@ static void read_buf_callback(struct urb *urb)
}
dbg("%s - %i chars to write", __func__, urb->actual_length);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (data == NULL)
dbg("%s - data is NULL !!!", __func__);
if (tty && urb->actual_length && data) {
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
iuu_led_activity_on(urb);
}
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 704716f6f6d3..15447af48691 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -430,7 +430,7 @@ static void usa26_indat_callback(struct urb *urb)
}
port = urb->context;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
/* 0x80 bit is error flag */
if ((data[0] & 0x80) == 0) {
@@ -459,6 +459,7 @@ static void usa26_indat_callback(struct urb *urb)
}
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
@@ -513,6 +514,7 @@ static void usa26_instat_callback(struct urb *urb)
struct usb_serial *serial;
struct usb_serial_port *port;
struct keyspan_port_private *p_priv;
+ struct tty_struct *tty;
int old_dcd_state, err;
int status = urb->status;
@@ -553,12 +555,11 @@ static void usa26_instat_callback(struct urb *urb)
p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty)
- && old_dcd_state != p_priv->dcd_state) {
- if (old_dcd_state)
- tty_hangup(port->port.tty);
- /* else */
- /* wake_up_interruptible(&p_priv->open_wait); */
+ if (old_dcd_state != p_priv->dcd_state) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty))
+ tty_hangup(tty);
+ tty_kref_put(tty);
}
/* Resubmit urb so we continue receiving */
@@ -604,11 +605,12 @@ static void usa28_indat_callback(struct urb *urb)
p_priv = usb_get_serial_port_data(port);
data = urb->transfer_buffer;
- tty = port->port.tty;
- if (urb->actual_length) {
+ tty =tty_port_tty_get(&port->port);
+ if (tty && urb->actual_length) {
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
@@ -652,6 +654,7 @@ static void usa28_instat_callback(struct urb *urb)
struct usb_serial *serial;
struct usb_serial_port *port;
struct keyspan_port_private *p_priv;
+ struct tty_struct *tty;
int old_dcd_state;
int status = urb->status;
@@ -689,12 +692,11 @@ static void usa28_instat_callback(struct urb *urb)
p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty)
- && old_dcd_state != p_priv->dcd_state) {
- if (old_dcd_state)
- tty_hangup(port->port.tty);
- /* else */
- /* wake_up_interruptible(&p_priv->open_wait); */
+ if( old_dcd_state != p_priv->dcd_state && old_dcd_state) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty))
+ tty_hangup(tty);
+ tty_kref_put(tty);
}
/* Resubmit urb so we continue receiving */
@@ -785,12 +787,11 @@ static void usa49_instat_callback(struct urb *urb)
p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty)
- && old_dcd_state != p_priv->dcd_state) {
- if (old_dcd_state)
- tty_hangup(port->port.tty);
- /* else */
- /* wake_up_interruptible(&p_priv->open_wait); */
+ if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty))
+ tty_hangup(tty);
+ tty_kref_put(tty);
}
/* Resubmit urb so we continue receiving */
@@ -827,7 +828,7 @@ static void usa49_indat_callback(struct urb *urb)
}
port = urb->context;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
/* 0x80 bit is error flag */
if ((data[0] & 0x80) == 0) {
@@ -850,6 +851,7 @@ static void usa49_indat_callback(struct urb *urb)
}
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* Resubmit urb so we continue receiving */
urb->dev = port->serial->dev;
@@ -893,7 +895,7 @@ static void usa49wg_indat_callback(struct urb *urb)
return;
}
port = serial->port[data[i++]];
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
len = data[i++];
/* 0x80 bit is error flag */
@@ -927,6 +929,7 @@ static void usa49wg_indat_callback(struct urb *urb)
}
if (port->port.count)
tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
}
}
@@ -967,8 +970,8 @@ static void usa90_indat_callback(struct urb *urb)
port = urb->context;
p_priv = usb_get_serial_port_data(port);
- tty = port->port.tty;
if (urb->actual_length) {
+ tty = tty_port_tty_get(&port->port);
/* if current mode is DMA, looks like usa28 format
otherwise looks like usa26 data format */
@@ -1004,6 +1007,7 @@ static void usa90_indat_callback(struct urb *urb)
}
}
tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
}
/* Resubmit urb so we continue receiving */
@@ -1025,6 +1029,7 @@ static void usa90_instat_callback(struct urb *urb)
struct usb_serial *serial;
struct usb_serial_port *port;
struct keyspan_port_private *p_priv;
+ struct tty_struct *tty;
int old_dcd_state, err;
int status = urb->status;
@@ -1053,12 +1058,11 @@ static void usa90_instat_callback(struct urb *urb)
p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
p_priv->ri_state = ((msg->ri) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty)
- && old_dcd_state != p_priv->dcd_state) {
- if (old_dcd_state)
- tty_hangup(port->port.tty);
- /* else */
- /* wake_up_interruptible(&p_priv->open_wait); */
+ if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty))
+ tty_hangup(tty);
+ tty_kref_put(tty);
}
/* Resubmit urb so we continue receiving */
@@ -1130,12 +1134,11 @@ static void usa67_instat_callback(struct urb *urb)
p_priv->cts_state = ((msg->hskia_cts) ? 1 : 0);
p_priv->dcd_state = ((msg->gpia_dcd) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty)
- && old_dcd_state != p_priv->dcd_state) {
- if (old_dcd_state)
- tty_hangup(port->port.tty);
- /* else */
- /* wake_up_interruptible(&p_priv->open_wait); */
+ if (old_dcd_state != p_priv->dcd_state && old_dcd_state) {
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty))
+ tty_hangup(tty);
+ tty_kref_put(tty);
}
/* Resubmit urb so we continue receiving */
@@ -1332,7 +1335,7 @@ static void keyspan_close(struct tty_struct *tty,
stop_urb(p_priv->out_urbs[i]);
}
}
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
}
/* download the firmware to a pre-renumeration device */
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index 040040a267d9..99e9a14c5bf6 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -172,8 +172,9 @@ static void keyspan_pda_wakeup_write(struct work_struct *work)
struct keyspan_pda_private *priv =
container_of(work, struct keyspan_pda_private, wakeup_work);
struct usb_serial_port *port = priv->port;
-
- tty_wakeup(port->port.tty);
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ tty_wakeup(tty);
+ tty_kref_put(tty);
}
static void keyspan_pda_request_unthrottle(struct work_struct *work)
@@ -205,7 +206,7 @@ static void keyspan_pda_request_unthrottle(struct work_struct *work)
static void keyspan_pda_rx_interrupt(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
unsigned char *data = urb->transfer_buffer;
int retval;
int status = urb->status;
@@ -222,7 +223,7 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
/* this urb is terminated, clean up */
dbg("%s - urb shutting down with status: %d",
__func__, status);
- return;
+ goto out;
default:
dbg("%s - nonzero urb status received: %d",
__func__, status);
@@ -261,8 +262,11 @@ static void keyspan_pda_rx_interrupt(struct urb *urb)
exit:
retval = usb_submit_urb(urb, GFP_ATOMIC);
if (retval)
- err("%s - usb_submit_urb failed with result %d",
- __func__, retval);
+ dev_err(&port->dev,
+ "%s - usb_submit_urb failed with result %d",
+ __func__, retval);
+out:
+ tty_kref_put(tty);
}
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index b84dddc71124..ff3a07f5102f 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -658,7 +658,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb)
} else {
int bytes_sent = ((__u8 *) data)[0] +
((unsigned int) ((__u8 *) data)[1] << 8);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
/* we should immediately resubmit the URB, before attempting
* to pass the data on to the tty layer. But that needs locking
* against re-entry an then mixed-up data because of
@@ -679,6 +679,7 @@ static void klsi_105_read_bulk_callback(struct urb *urb)
tty_buffer_request_room(tty, bytes_sent);
tty_insert_flip_string(tty, data + 2, bytes_sent);
tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
/* again lockless, but debug info only */
priv->bytes_in += bytes_sent;
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c
index deba28ec77e8..cfcf37c2b957 100644
--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -383,7 +383,7 @@ static void kobil_read_int_callback(struct urb *urb)
return;
}
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (urb->actual_length) {
/* BEGIN DEBUG */
@@ -405,6 +405,7 @@ static void kobil_read_int_callback(struct urb *urb)
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* someone sets the dev to 0 if the close method has been called */
port->interrupt_in_urb->dev = port->serial->dev;
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index 0ded8bd6ec85..9b2cef81cde0 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -563,10 +563,11 @@ static void mct_u232_read_int_callback(struct urb *urb)
* Work-a-round: handle the 'usual' bulk-in pipe here
*/
if (urb->transfer_buffer_length > 2) {
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (urb->actual_length) {
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
}
goto exit;
}
@@ -591,7 +592,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
* to look in to this before committing any code.
*/
if (priv->last_lsr & MCT_U232_LSR_ERR) {
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
/* Overrun Error */
if (priv->last_lsr & MCT_U232_LSR_OE) {
}
@@ -604,6 +605,7 @@ static void mct_u232_read_int_callback(struct urb *urb)
/* Break Indicator */
if (priv->last_lsr & MCT_U232_LSR_BI) {
}
+ tty_kref_put(tty);
}
#endif
spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 7c4917d77c0a..7b538caec37f 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -216,12 +216,13 @@ static void mos7720_bulk_in_callback(struct urb *urb)
data = urb->transfer_buffer;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
if (!port->read_urb) {
dbg("URB KILLED !!!");
@@ -262,10 +263,11 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
dbg("Entering .........");
- tty = mos7720_port->port->port.tty;
+ tty = tty_port_tty_get(&mos7720_port->port->port);
if (tty && mos7720_port->open)
tty_wakeup(tty);
+ tty_kref_put(tty);
}
/*
@@ -1267,29 +1269,6 @@ static int get_lsr_info(struct tty_struct *tty,
return 0;
}
-/*
- * get_number_bytes_avail - get number of bytes available
- *
- * Purpose: Let user call ioctl to get the count of number of bytes available.
- */
-static int get_number_bytes_avail(struct moschip_port *mos7720_port,
- unsigned int __user *value)
-{
- unsigned int result = 0;
- struct tty_struct *tty = mos7720_port->port->port.tty;
-
- if (!tty)
- return -ENOIOCTLCMD;
-
- result = tty->read_cnt;
-
- dbg("%s(%d) = %d", __func__, mos7720_port->port->number, result);
- if (copy_to_user(value, &result, sizeof(int)))
- return -EFAULT;
-
- return -ENOIOCTLCMD;
-}
-
static int set_modem_info(struct moschip_port *mos7720_port, unsigned int cmd,
unsigned int __user *value)
{
@@ -1409,13 +1388,6 @@ static int mos7720_ioctl(struct tty_struct *tty, struct file *file,
dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
switch (cmd) {
- case TIOCINQ:
- /* return number of bytes available */
- dbg("%s (%d) TIOCINQ", __func__, port->number);
- return get_number_bytes_avail(mos7720_port,
- (unsigned int __user *)arg);
- break;
-
case TIOCSERGETLSR:
dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
return get_lsr_info(tty, mos7720_port,
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 09d82062b973..60543d79ef56 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -709,12 +709,13 @@ static void mos7840_bulk_in_callback(struct urb *urb)
dbg("%s", "Entering ........... \n");
if (urb->actual_length) {
- tty = mos7840_port->port->port.tty;
+ tty = tty_port_tty_get(&mos7840_port->port->port);
if (tty) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
dbg(" %s \n", data);
tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
}
mos7840_port->icount.rx += urb->actual_length;
smp_wmb();
@@ -773,10 +774,10 @@ static void mos7840_bulk_out_data_callback(struct urb *urb)
dbg("%s \n", "Entering .........");
- tty = mos7840_port->port->port.tty;
-
+ tty = tty_port_tty_get(&mos7840_port->port->port);
if (tty && mos7840_port->open)
tty_wakeup(tty);
+ tty_kref_put(tty);
}
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index d6736531a0fa..bcdcbb822705 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -64,12 +64,13 @@ static void navman_read_int_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
exit:
result = usb_submit_urb(urb, GFP_ATOMIC);
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index ae8e227f3db2..c4d70b0f1e48 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -172,7 +172,7 @@ static int omninet_open(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
wport = serial->port[1];
- wport->port.tty = tty; /* FIXME */
+ tty_port_tty_set(&wport->port, tty);
/* Start reading from the device */
usb_fill_bulk_urb(port->read_urb, serial->dev,
@@ -229,9 +229,11 @@ static void omninet_read_bulk_callback(struct urb *urb)
}
if (urb->actual_length && header->oh_len) {
- tty_insert_flip_string(port->port.tty,
- data + OMNINET_DATAOFFSET, header->oh_len);
- tty_flip_buffer_push(port->port.tty);
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ tty_insert_flip_string(tty, data + OMNINET_DATAOFFSET,
+ header->oh_len);
+ tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
}
/* Continue trying to always read */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 9f9cd36455f4..6b1727e751e3 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -218,6 +218,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
/* ZTE PRODUCTS */
#define ZTE_VENDOR_ID 0x19d2
#define ZTE_PRODUCT_MF628 0x0015
+#define ZTE_PRODUCT_CDMA_TECH 0xfffe
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -347,6 +348,7 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
{ USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
+ { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, option_ids);
@@ -569,14 +571,14 @@ static void option_indat_callback(struct urb *urb)
dbg("%s: nonzero status: %d on endpoint %02x.",
__func__, status, endpoint);
} else {
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
- } else {
+ } else
dbg("%s: empty read urb received", __func__);
- }
+ tty_kref_put(tty);
/* Resubmit urb so we continue receiving */
if (port->port.count && status != -ESHUTDOWN) {
@@ -645,9 +647,13 @@ static void option_instat_callback(struct urb *urb)
portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
portdata->ri_state = ((signals & 0x08) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty) &&
- old_dcd_state && !portdata->dcd_state)
- tty_hangup(port->port.tty);
+ if (old_dcd_state && !portdata->dcd_state) {
+ struct tty_struct *tty =
+ tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty))
+ tty_hangup(tty);
+ tty_kref_put(tty);
+ }
} else {
dbg("%s: type %x req %x", __func__,
req_pkt->bRequestType, req_pkt->bRequest);
@@ -791,7 +797,7 @@ static void option_close(struct tty_struct *tty,
for (i = 0; i < N_OUT_URB; i++)
usb_kill_urb(portdata->out_urbs[i]);
}
- port->port.tty = NULL; /* FIXME */
+ tty_port_tty_set(&port->port, NULL);
}
/* Helper functions used by option_setup_urbs */
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 81db5715ee25..ba551f00f16f 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -224,10 +224,6 @@ struct oti6858_private {
struct usb_serial_port *port; /* USB port with which associated */
};
-#undef dbg
-/* #define dbg(format, arg...) printk(KERN_INFO "%s: " format "\n", __FILE__, ## arg) */
-#define dbg(format, arg...) printk(KERN_INFO "" format "\n", ## arg)
-
static void setup_line(struct work_struct *work)
{
struct oti6858_private *priv = container_of(work,
@@ -1002,11 +998,12 @@ static void oti6858_read_bulk_callback(struct urb *urb)
return;
}
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty != NULL && urb->actual_length > 0) {
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* schedule the interrupt urb if we are still open */
if (port->port.count != 0) {
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 1ede1441cb1b..908437847165 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -154,7 +154,6 @@ struct pl2303_private {
wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
- u8 termios_initialized;
enum pl2303_type type;
};
@@ -526,16 +525,6 @@ static void pl2303_set_termios(struct tty_struct *tty,
dbg("%s - port %d", __func__, port->number);
- spin_lock_irqsave(&priv->lock, flags);
- if (!priv->termios_initialized) {
- *(tty->termios) = tty_std_termios;
- tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- tty->termios->c_ispeed = 9600;
- tty->termios->c_ospeed = 9600;
- priv->termios_initialized = 1;
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-
/* The PL2303 is reported to lose bytes if you change
serial settings even to the same values as before. Thus
we actually need to filter in this specific case */
@@ -1057,7 +1046,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
tty_flag = TTY_FRAME;
dbg("%s - tty_flag = %d", __func__, tty_flag);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
@@ -1067,7 +1056,7 @@ static void pl2303_read_bulk_callback(struct urb *urb)
tty_insert_flip_char(tty, data[i], tty_flag);
tty_flip_buffer_push(tty);
}
-
+ tty_kref_put(tty);
/* Schedule the next read _if_ we are still open */
if (port->port.count) {
urb->dev = port->serial->dev;
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index def52d07a4ea..72903ac9f5c0 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -217,6 +217,7 @@ static void safe_read_bulk_callback(struct urb *urb)
struct usb_serial_port *port = urb->context;
unsigned char *data = urb->transfer_buffer;
unsigned char length = urb->actual_length;
+ struct tty_struct *tty;
int result;
int status = urb->status;
@@ -242,6 +243,7 @@ static void safe_read_bulk_callback(struct urb *urb)
printk("\n");
}
#endif
+ tty = tty_port_tty_get(&port->port);
if (safe) {
__u16 fcs;
fcs = fcs_compute10(data, length, CRC10_INITFCS);
@@ -250,9 +252,9 @@ static void safe_read_bulk_callback(struct urb *urb)
if (actual_length <= (length - 2)) {
info("%s - actual: %d", __func__,
actual_length);
- tty_insert_flip_string(port->port.tty,
+ tty_insert_flip_string(tty,
data, actual_length);
- tty_flip_buffer_push(port->port.tty);
+ tty_flip_buffer_push(tty);
} else {
err("%s - inconsistent lengths %d:%d",
__func__, actual_length, length);
@@ -261,9 +263,10 @@ static void safe_read_bulk_callback(struct urb *urb)
err("%s - bad CRC %x", __func__, fcs);
}
} else {
- tty_insert_flip_string(port->port.tty, data, length);
- tty_flip_buffer_push(port->port.tty);
+ tty_insert_flip_string(tty, data, length);
+ tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* Continue trying to always read */
usb_fill_bulk_urb(urb, port->serial->dev,
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 706033753adb..8b9eaf383679 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -14,7 +14,7 @@
Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
*/
-#define DRIVER_VERSION "v.1.2.13a"
+#define DRIVER_VERSION "v.1.3.2"
#define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
#define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
@@ -30,9 +30,6 @@
#define SWIMS_USB_REQUEST_SetPower 0x00
#define SWIMS_USB_REQUEST_SetNmea 0x07
-#define SWIMS_USB_REQUEST_SetMode 0x0B
-#define SWIMS_USB_REQUEST_GetSwocInfo 0x0A
-#define SWIMS_SET_MODE_Modem 0x0001
/* per port private data */
#define N_IN_URB 4
@@ -163,7 +160,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
{ USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
{ USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
- { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
+ { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
{ USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
{ USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
{ USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
@@ -175,6 +172,8 @@ static struct usb_device_id id_table [] = {
/* Sierra Wireless Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
{ USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
+ { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
+ { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
{ USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
{ USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -187,6 +186,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
{ USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
{ USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
+ { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
{ USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
{ USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
{ USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
@@ -204,6 +204,8 @@ static struct usb_device_id id_table [] = {
/* Sierra Wireless Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
/* Sierra Wireless Device */
+ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
+ /* Sierra Wireless Device */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
@@ -438,14 +440,14 @@ static void sierra_indat_callback(struct urb *urb)
dbg("%s: nonzero status: %d on endpoint %02x.",
__func__, status, endpoint);
} else {
- tty = port->port.tty;
if (urb->actual_length) {
+ tty = tty_port_tty_get(&port->port);
tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
- } else {
+ tty_kref_put(tty);
+ } else
dbg("%s: empty read urb received", __func__);
- }
/* Resubmit urb so we continue receiving */
if (port->port.count && status != -ESHUTDOWN) {
@@ -483,6 +485,7 @@ static void sierra_instat_callback(struct urb *urb)
unsigned char signals = *((unsigned char *)
urb->transfer_buffer +
sizeof(struct usb_ctrlrequest));
+ struct tty_struct *tty;
dbg("%s: signal x%x", __func__, signals);
@@ -492,9 +495,11 @@ static void sierra_instat_callback(struct urb *urb)
portdata->dsr_state = ((signals & 0x02) ? 1 : 0);
portdata->ri_state = ((signals & 0x08) ? 1 : 0);
- if (port->port.tty && !C_CLOCAL(port->port.tty) &&
+ tty = tty_port_tty_get(&port->port);
+ if (tty && !C_CLOCAL(tty) &&
old_dcd_state && !portdata->dcd_state)
- tty_hangup(port->port.tty);
+ tty_hangup(tty);
+ tty_kref_put(tty);
} else {
dbg("%s: type %x req %x", __func__,
req_pkt->bRequestType, req_pkt->bRequest);
@@ -614,8 +619,7 @@ static void sierra_close(struct tty_struct *tty,
}
usb_kill_urb(port->interrupt_in_urb);
-
- port->port.tty = NULL; /* FIXME */
+ tty_port_tty_set(&port->port, NULL);
}
static int sierra_startup(struct usb_serial *serial)
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 283cf6b36b2c..1533d6e12238 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -755,7 +755,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
tty_flag = TTY_FRAME;
dev_dbg(&port->dev, "tty_flag = %d\n", tty_flag);
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length + 1);
/* overrun is special, not associated with a char */
@@ -765,6 +765,7 @@ static void spcp8x5_read_bulk_callback(struct urb *urb)
tty_insert_flip_char(tty, data[i], tty_flag);
tty_flip_buffer_push(tty);
}
+ tty_kref_put(tty);
/* Schedule the next read _if_ we are still open */
if (port->port.count) {
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index e39c779e4160..c90237d48b0e 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -179,7 +179,7 @@ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr);
static int ti_get_lsr(struct ti_port *tport);
static int ti_get_serial_info(struct ti_port *tport,
struct serial_struct __user *ret_arg);
-static int ti_set_serial_info(struct ti_port *tport,
+static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
struct serial_struct __user *new_arg);
static void ti_handle_new_msr(struct ti_port *tport, __u8 msr);
@@ -857,8 +857,8 @@ static int ti_ioctl(struct tty_struct *tty, struct file *file,
(struct serial_struct __user *)arg);
case TIOCSSERIAL:
dbg("%s - (%d) TIOCSSERIAL", __func__, port->number);
- return ti_set_serial_info(tport,
- (struct serial_struct __user *)arg);
+ return ti_set_serial_info(tty, tport,
+ (struct serial_struct __user *)arg);
case TIOCMIWAIT:
dbg("%s - (%d) TIOCMIWAIT", __func__, port->number);
cprev = tport->tp_icount;
@@ -1211,6 +1211,7 @@ static void ti_bulk_in_callback(struct urb *urb)
struct device *dev = &urb->dev->dev;
int status = urb->status;
int retval = 0;
+ struct tty_struct *tty;
dbg("%s", __func__);
@@ -1239,20 +1240,22 @@ static void ti_bulk_in_callback(struct urb *urb)
return;
}
- if (port->port.tty && urb->actual_length) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty && urb->actual_length) {
usb_serial_debug_data(debug, dev, __func__,
urb->actual_length, urb->transfer_buffer);
if (!tport->tp_is_open)
dbg("%s - port closed, dropping data", __func__);
else
- ti_recv(&urb->dev->dev, port->port.tty,
+ ti_recv(&urb->dev->dev, tty,
urb->transfer_buffer,
urb->actual_length);
spin_lock(&tport->tp_lock);
tport->tp_icount.rx += urb->actual_length;
spin_unlock(&tport->tp_lock);
+ tty_kref_put(tty);
}
exit:
@@ -1330,7 +1333,7 @@ static void ti_send(struct ti_port *tport)
{
int count, result;
struct usb_serial_port *port = tport->tp_port;
- struct tty_struct *tty = port->port.tty; /* FIXME */
+ struct tty_struct *tty = tty_port_tty_get(&port->port); /* FIXME */
unsigned long flags;
@@ -1338,19 +1341,15 @@ static void ti_send(struct ti_port *tport)
spin_lock_irqsave(&tport->tp_lock, flags);
- if (tport->tp_write_urb_in_use) {
- spin_unlock_irqrestore(&tport->tp_lock, flags);
- return;
- }
+ if (tport->tp_write_urb_in_use)
+ goto unlock;
count = ti_buf_get(tport->tp_write_buf,
port->write_urb->transfer_buffer,
port->bulk_out_size);
- if (count == 0) {
- spin_unlock_irqrestore(&tport->tp_lock, flags);
- return;
- }
+ if (count == 0)
+ goto unlock;
tport->tp_write_urb_in_use = 1;
@@ -1380,7 +1379,13 @@ static void ti_send(struct ti_port *tport)
/* more room in the buffer for new writes, wakeup */
if (tty)
tty_wakeup(tty);
+ tty_kref_put(tty);
wake_up_interruptible(&tport->tp_write_wait);
+ return;
+unlock:
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+ tty_kref_put(tty);
+ return;
}
@@ -1464,20 +1469,16 @@ static int ti_get_serial_info(struct ti_port *tport,
}
-static int ti_set_serial_info(struct ti_port *tport,
+static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
struct serial_struct __user *new_arg)
{
- struct usb_serial_port *port = tport->tp_port;
struct serial_struct new_serial;
if (copy_from_user(&new_serial, new_arg, sizeof(new_serial)))
return -EFAULT;
tport->tp_flags = new_serial.flags & TI_SET_SERIAL_FLAGS;
- /* FIXME */
- if (port->port.tty)
- port->port.tty->low_latency =
- (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+ tty->low_latency = (tport->tp_flags & ASYNC_LOW_LATENCY) ? 1 : 0;
tport->tp_closing_wait = new_serial.closing_wait;
return 0;
@@ -1510,7 +1511,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
tport->tp_msr = msr & TI_MSR_MASK;
/* handle CTS flow control */
- tty = tport->tp_port->port.tty;
+ tty = tty_port_tty_get(&tport->tp_port->port);
if (tty && C_CRTSCTS(tty)) {
if (msr & TI_MSR_CTS) {
tty->hw_stopped = 0;
@@ -1519,6 +1520,7 @@ static void ti_handle_new_msr(struct ti_port *tport, __u8 msr)
tty->hw_stopped = 1;
}
}
+ tty_kref_put(tty);
}
@@ -1744,7 +1746,7 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
if (buffer) {
memcpy(buffer, fw_p->data, fw_p->size);
memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
- ti_do_download(dev, pipe, buffer, fw_p->size);
+ status = ti_do_download(dev, pipe, buffer, fw_p->size);
kfree(buffer);
}
release_firmware(fw_p);
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index b157c48e8b78..e7d4246027b2 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -214,7 +214,7 @@ static int serial_open (struct tty_struct *tty, struct file *filp)
/* set up our port structure making the tty driver
* remember our port object, and us it */
tty->driver_data = port;
- port->port.tty = tty;
+ tty_port_tty_set(&port->port, tty);
if (port->port.count == 1) {
@@ -246,7 +246,7 @@ bailout_module_put:
bailout_mutex_unlock:
port->port.count = 0;
tty->driver_data = NULL;
- port->port.tty = NULL;
+ tty_port_tty_set(&port->port, NULL);
mutex_unlock(&port->mutex);
bailout_kref_put:
usb_serial_put(serial);
@@ -276,10 +276,11 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
port->serial->type->close(tty, port, filp);
if (port->port.count == (port->console? 1 : 0)) {
- if (port->port.tty) {
- if (port->port.tty->driver_data)
- port->port.tty->driver_data = NULL;
- port->port.tty = NULL;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ if (tty->driver_data)
+ tty->driver_data = NULL;
+ tty_port_tty_set(&port->port, NULL);
}
}
@@ -508,11 +509,12 @@ static void usb_serial_port_work(struct work_struct *work)
if (!port)
return;
- tty = port->port.tty;
+ tty = tty_port_tty_get(&port->port);
if (!tty)
return;
tty_wakeup(tty);
+ tty_kref_put(tty);
}
static void port_release(struct device *dev)
@@ -733,7 +735,9 @@ int usb_serial_probe(struct usb_interface *interface,
((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
(le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
- (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) {
+ (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) ||
+ ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
+ (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) {
if (interface != dev->actconfig->interface[0]) {
/* check out the endpoints of the other interface*/
iface_desc = dev->actconfig->interface[0]->cur_altsetting;
@@ -817,6 +821,7 @@ int usb_serial_probe(struct usb_interface *interface,
port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
if (!port)
goto probe_error;
+ tty_port_init(&port->port);
port->serial = serial;
spin_lock_init(&port->lock);
mutex_init(&port->mutex);
@@ -1038,8 +1043,11 @@ void usb_serial_disconnect(struct usb_interface *interface)
for (i = 0; i < serial->num_ports; ++i) {
port = serial->port[i];
if (port) {
- if (port->port.tty)
- tty_hangup(port->port.tty);
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ tty_hangup(tty);
+ tty_kref_put(tty);
+ }
kill_traffic(port);
}
}
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index cf8924f9a2cc..a6d1c75a1c89 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -499,7 +499,7 @@ static void visor_read_bulk_callback(struct urb *urb)
int status = urb->status;
struct tty_struct *tty;
int result;
- int available_room;
+ int available_room = 0;
dbg("%s - port %d", __func__, port->number);
@@ -512,13 +512,17 @@ static void visor_read_bulk_callback(struct urb *urb)
usb_serial_debug_data(debug, &port->dev, __func__,
urb->actual_length, data);
- tty = port->port.tty;
- if (tty && urb->actual_length) {
- available_room = tty_buffer_request_room(tty,
+ if (urb->actual_length) {
+ tty = tty_port_tty_get(&port->port);
+ if (tty) {
+ available_room = tty_buffer_request_room(tty,
urb->actual_length);
- if (available_room) {
- tty_insert_flip_string(tty, data, available_room);
- tty_flip_buffer_push(tty);
+ if (available_room) {
+ tty_insert_flip_string(tty, data,
+ available_room);
+ tty_flip_buffer_push(tty);
+ }
+ tty_kref_put(tty);
}
spin_lock(&priv->lock);
priv->bytes_in += available_room;
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 3a9d14384a43..11c8b97a5177 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -1481,7 +1481,7 @@ static void rx_data_softint(struct work_struct *work)
struct whiteheat_private *info =
container_of(work, struct whiteheat_private, rx_work);
struct usb_serial_port *port = info->port;
- struct tty_struct *tty = port->port.tty;
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
struct whiteheat_urb_wrap *wrap;
struct urb *urb;
unsigned long flags;
@@ -1493,7 +1493,7 @@ static void rx_data_softint(struct work_struct *work)
spin_lock_irqsave(&info->lock, flags);
if (info->flags & THROTTLED) {
spin_unlock_irqrestore(&info->lock, flags);
- return;
+ goto out;
}
list_for_each_safe(tmp, tmp2, &info->rx_urb_q) {
@@ -1513,7 +1513,7 @@ static void rx_data_softint(struct work_struct *work)
spin_unlock_irqrestore(&info->lock, flags);
tty_flip_buffer_push(tty);
schedule_work(&info->rx_work);
- return;
+ goto out;
}
tty_insert_flip_string(tty, urb->transfer_buffer, len);
sent += len;
@@ -1536,6 +1536,8 @@ static void rx_data_softint(struct work_struct *work)
if (sent)
tty_flip_buffer_push(tty);
+out:
+ tty_kref_put(tty);
}
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig
index c76034672c18..3d9249632ae1 100644
--- a/drivers/usb/storage/Kconfig
+++ b/drivers/usb/storage/Kconfig
@@ -146,18 +146,6 @@ config USB_STORAGE_KARMA
on the resulting scsi device node returns the Karma to normal
operation.
-config USB_STORAGE_SIERRA
- bool "Sierra Wireless TRU-Install Feature Support"
- depends on USB_STORAGE
- help
- Say Y here to include additional code to support Sierra Wireless
- products with the TRU-Install feature (e.g., AC597E, AC881U).
-
- This code switches the Sierra Wireless device from being in
- Mass Storage mode to Modem mode. It also has the ability to
- support host software upgrades should full Linux support be added
- to TRU-Install.
-
config USB_STORAGE_CYPRESS_ATACB
bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
depends on USB_STORAGE
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile
index bc3415b475c9..7f8beb5366ae 100644
--- a/drivers/usb/storage/Makefile
+++ b/drivers/usb/storage/Makefile
@@ -21,11 +21,10 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o
usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o
usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA) += sierra_ms.o
usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \
- initializers.o $(usb-storage-obj-y)
+ initializers.o sierra_ms.o $(usb-storage-obj-y)
ifneq ($(CONFIG_USB_LIBUSUAL),)
obj-$(CONFIG_USB) += libusual.o
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index ba412e68d474..cd155475cb6e 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -160,6 +160,13 @@ UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0592,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_MAX_SECTORS_64 ),
+/* Reported by Filip Joelsson <filip@blueturtle.nu> */
+UNUSUAL_DEV( 0x0421, 0x005d, 0x0001, 0x0600,
+ "Nokia",
+ "Nokia 3110c",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
/* Reported by Mario Rettig <mariorettig@web.de> */
UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100,
"Nokia",
@@ -232,6 +239,20 @@ UNUSUAL_DEV( 0x0421, 0x04b9, 0x0551, 0x0551,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/* Reported by Richard Nauber <RichardNauber@web.de> */
+UNUSUAL_DEV( 0x0421, 0x04fa, 0x0601, 0x0601,
+ "Nokia",
+ "6300",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
+/* Patch for Nokia 5310 capacity */
+UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591,
+ "Nokia",
+ "5310",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_CAPACITY ),
+
/* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210,
"SMSC",
@@ -987,6 +1008,13 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001,
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ),
+/* Reported by Adrian Pilchowiec <adi1981@epf.pl> */
+UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000,
+ "RockChip",
+ "MP3",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+
/* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
* This USB MP3/AVI player device fails and disconnects if more than 128
* sectors (64kB) are read/written in a single command, and may be present
@@ -1576,7 +1604,6 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100,
US_SC_DEVICE, US_PR_DEVICE, NULL,
0),
-#ifdef CONFIG_USB_STORAGE_SIERRA
/* Reported by Kevin Lloyd <linux@sierrawireless.com>
* Entry is needed for the initializer function override,
* which instructs the device to load as a modem
@@ -1587,7 +1614,6 @@ UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999,
"USB MMC Storage",
US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init,
0),
-#endif
/* Reported by Jaco Kroon <jaco@kroon.co.za>
* The usb-storage module found on the Digitech GNX4 (and supposedly other
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 73679aa506de..27016fd2cad1 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -102,9 +102,7 @@
#ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
#include "cypress_atacb.h"
#endif
-#ifdef CONFIG_USB_STORAGE_SIERRA
#include "sierra_ms.h"
-#endif
/* Some informational data */
MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");