Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (48 commits) serial: 8250_pci: add support for Cronyx Omega PCI multiserial board. tty/serial: Fix break handling for PORT_TEGRA tty/serial: Add explicit PORT_TEGRA type n_tracerouter and n_tracesink ldisc additions. Intel PTI implementaiton of MIPI 1149.7. Kernel documentation for the PTI feature. export kernel call get_task_comm(). tty: Remove to support serial for S5P6442 pch_phub: Support new device ML7223 8250_pci: Add support for the Digi/IBM PCIe 2-port Adapter ASoC: Update cx20442 for TTY API change pch_uart: Support new device ML7223 IOH parport: Use request_muxed_region for IT87 probe and lock tty/serial: add support for Xilinx PS UART n_gsm: Use print_hex_dump_bytes drivers/tty/moxa.c: Put correct tty value TTY: tty_io, annotate locking functions TTY: serial_core, remove superfluous set_task_state TTY: serial_core, remove invalid test Char: moxa, fix locking in moxa_write ... Fix up trivial conflicts in drivers/bluetooth/hci_ldisc.c and drivers/tty/serial/Makefile. I did the hci_ldisc thing as an evil merge, cleaning things up.
This commit is contained in:
commit
99dff58562
103 changed files with 3349 additions and 518 deletions
99
Documentation/pti/pti_intel_mid.txt
Normal file
99
Documentation/pti/pti_intel_mid.txt
Normal file
|
@ -0,0 +1,99 @@
|
|||
The Intel MID PTI project is HW implemented in Intel Atom
|
||||
system-on-a-chip designs based on the Parallel Trace
|
||||
Interface for MIPI P1149.7 cJTAG standard. The kernel solution
|
||||
for this platform involves the following files:
|
||||
|
||||
./include/linux/pti.h
|
||||
./drivers/.../n_tracesink.h
|
||||
./drivers/.../n_tracerouter.c
|
||||
./drivers/.../n_tracesink.c
|
||||
./drivers/.../pti.c
|
||||
|
||||
pti.c is the driver that enables various debugging features
|
||||
popular on platforms from certain mobile manufacturers.
|
||||
n_tracerouter.c and n_tracesink.c allow extra system information to
|
||||
be collected and routed to the pti driver, such as trace
|
||||
debugging data from a modem. Although n_tracerouter
|
||||
and n_tracesink are a part of the complete PTI solution,
|
||||
these two line disciplines can work separately from
|
||||
pti.c and route any data stream from one /dev/tty node
|
||||
to another /dev/tty node via kernel-space. This provides
|
||||
a stable, reliable connection that will not break unless
|
||||
the user-space application shuts down (plus avoids
|
||||
kernel->user->kernel context switch overheads of routing
|
||||
data).
|
||||
|
||||
An example debugging usage for this driver system:
|
||||
*Hook /dev/ttyPTI0 to syslogd. Opening this port will also start
|
||||
a console device to further capture debugging messages to PTI.
|
||||
*Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW.
|
||||
This is where n_tracerouter and n_tracesink are used.
|
||||
*Hook /dev/pti to a user-level debugging application for writing
|
||||
to PTI HW.
|
||||
*Use mipi_* Kernel Driver API in other device drivers for
|
||||
debugging to PTI by first requesting a PTI write address via
|
||||
mipi_request_masterchannel(1).
|
||||
|
||||
Below is example pseudo-code on how a 'privileged' application
|
||||
can hook up n_tracerouter and n_tracesink to any tty on
|
||||
a system. 'Privileged' means the application has enough
|
||||
privileges to successfully manipulate the ldisc drivers
|
||||
but is not just blindly executing as 'root'. Keep in mind
|
||||
the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter
|
||||
and n_tracesink line discpline drivers but is a generic
|
||||
operation for a program to use a line discpline driver
|
||||
on a tty port other than the default n_tty.
|
||||
|
||||
/////////// To hook up n_tracerouter and n_tracesink /////////
|
||||
|
||||
// Note that n_tracerouter depends on n_tracesink.
|
||||
#include <errno.h>
|
||||
#define ONE_TTY "/dev/ttyOne"
|
||||
#define TWO_TTY "/dev/ttyTwo"
|
||||
|
||||
// needed global to hand onto ldisc connection
|
||||
static int g_fd_source = -1;
|
||||
static int g_fd_sink = -1;
|
||||
|
||||
// these two vars used to grab LDISC values from loaded ldisc drivers
|
||||
// in OS. Look at /proc/tty/ldiscs to get the right numbers from
|
||||
// the ldiscs loaded in the system.
|
||||
int source_ldisc_num, sink_ldisc_num = -1;
|
||||
int retval;
|
||||
|
||||
g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W
|
||||
g_fd_sink = open(TWO_TTY, O_RDWR); // must be R/W
|
||||
|
||||
if (g_fd_source <= 0) || (g_fd_sink <= 0) {
|
||||
// doubt you'll want to use these exact error lines of code
|
||||
printf("Error on open(). errno: %d\n",errno);
|
||||
return errno;
|
||||
}
|
||||
|
||||
retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num);
|
||||
if (retval < 0) {
|
||||
printf("Error on ioctl(). errno: %d\n", errno);
|
||||
return errno;
|
||||
}
|
||||
|
||||
retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num);
|
||||
if (retval < 0) {
|
||||
printf("Error on ioctl(). errno: %d\n", errno);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/////////// To disconnect n_tracerouter and n_tracesink ////////
|
||||
|
||||
// First make sure data through the ldiscs has stopped.
|
||||
|
||||
// Second, disconnect ldiscs. This provides a
|
||||
// little cleaner shutdown on tty stack.
|
||||
sink_ldisc_num = 0;
|
||||
source_ldisc_num = 0;
|
||||
ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num);
|
||||
ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num);
|
||||
|
||||
// Three, program closes connection, and cleanup:
|
||||
close(g_fd_uart);
|
||||
close(g_fd_gadget);
|
||||
g_fd_uart = g_fd_gadget = NULL;
|
|
@ -355,26 +355,29 @@ static void hci_uart_tty_wakeup(struct tty_struct *tty)
|
|||
* flags pointer to flags for data
|
||||
* count count of received data in bytes
|
||||
*
|
||||
* Return Value: None
|
||||
* Return Value: Number of bytes received
|
||||
*/
|
||||
static void hci_uart_tty_receive(struct tty_struct *tty, const u8 *data, char *flags, int count)
|
||||
static unsigned int hci_uart_tty_receive(struct tty_struct *tty,
|
||||
const u8 *data, char *flags, int count)
|
||||
{
|
||||
int ret;
|
||||
struct hci_uart *hu = (void *)tty->disc_data;
|
||||
int received;
|
||||
|
||||
if (!hu || tty != hu->tty)
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
||||
return;
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock(&hu->rx_lock);
|
||||
ret = hu->proto->recv(hu, (void *) data, count);
|
||||
if (ret > 0)
|
||||
hu->hdev->stat.byte_rx += count;
|
||||
received = hu->proto->recv(hu, (void *) data, count);
|
||||
if (received > 0)
|
||||
hu->hdev->stat.byte_rx += received;
|
||||
spin_unlock(&hu->rx_lock);
|
||||
|
||||
tty_unthrottle(tty);
|
||||
|
||||
return received;
|
||||
}
|
||||
|
||||
static int hci_uart_register_dev(struct hci_uart *hu)
|
||||
|
|
|
@ -120,17 +120,21 @@ static void serport_ldisc_close(struct tty_struct *tty)
|
|||
* 'interrupt' routine.
|
||||
*/
|
||||
|
||||
static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
|
||||
static unsigned int serport_ldisc_receive(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct serport *serport = (struct serport*) tty->disc_data;
|
||||
unsigned long flags;
|
||||
unsigned int ch_flags;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&serport->lock, flags);
|
||||
|
||||
if (!test_bit(SERPORT_ACTIVE, &serport->flags))
|
||||
if (!test_bit(SERPORT_ACTIVE, &serport->flags)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
switch (fp[i]) {
|
||||
|
@ -152,6 +156,8 @@ static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *c
|
|||
|
||||
out:
|
||||
spin_unlock_irqrestore(&serport->lock, flags);
|
||||
|
||||
return ret == 0 ? count : ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -674,7 +674,7 @@ gigaset_tty_ioctl(struct tty_struct *tty, struct file *file,
|
|||
* cflags buffer containing error flags for received characters (ignored)
|
||||
* count number of received characters
|
||||
*/
|
||||
static void
|
||||
static unsigned int
|
||||
gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
|
||||
char *cflags, int count)
|
||||
{
|
||||
|
@ -683,12 +683,12 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
|
|||
struct inbuf_t *inbuf;
|
||||
|
||||
if (!cs)
|
||||
return;
|
||||
return -ENODEV;
|
||||
inbuf = cs->inbuf;
|
||||
if (!inbuf) {
|
||||
dev_err(cs->dev, "%s: no inbuf\n", __func__);
|
||||
cs_put(cs);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tail = inbuf->tail;
|
||||
|
@ -725,6 +725,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf,
|
|||
gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
|
||||
gigaset_schedule_event(cs);
|
||||
cs_put(cs);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -144,6 +144,19 @@ config PHANTOM
|
|||
If you choose to build module, its name will be phantom. If unsure,
|
||||
say N here.
|
||||
|
||||
config INTEL_MID_PTI
|
||||
tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
|
||||
default n
|
||||
help
|
||||
The PTI (Parallel Trace Interface) driver directs
|
||||
trace data routed from various parts in the system out
|
||||
through an Intel Penwell PTI port and out of the mobile
|
||||
device for analysis with a debugging tool (Lauterbach or Fido).
|
||||
|
||||
You should select this driver if the target kernel is meant for
|
||||
an Intel Atom (non-netbook) mobile device containing a MIPI
|
||||
P1149.7 standard implementation.
|
||||
|
||||
config SGI_IOC4
|
||||
tristate "SGI IOC4 Base IO support"
|
||||
depends on PCI
|
||||
|
@ -459,7 +472,7 @@ config BMP085
|
|||
module will be called bmp085.
|
||||
|
||||
config PCH_PHUB
|
||||
tristate "PCH Packet Hub of Intel Topcliff / OKI SEMICONDUCTOR ML7213"
|
||||
tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"
|
||||
depends on PCI
|
||||
help
|
||||
This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
|
||||
|
@ -467,10 +480,12 @@ config PCH_PHUB
|
|||
processor. The Topcliff has MAC address and Option ROM data in SROM.
|
||||
This driver can access MAC address and Option ROM data in SROM.
|
||||
|
||||
This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
|
||||
for IVI(In-Vehicle Infotainment) use.
|
||||
ML7213 is companion chip for Intel Atom E6xx series.
|
||||
ML7213 is completely compatible for Intel EG20T PCH.
|
||||
This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
|
||||
Output Hub), ML7213 and ML7223.
|
||||
ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
|
||||
for MP(Media Phone) use.
|
||||
ML7213/ML7223 is companion chip for Intel Atom E6xx series.
|
||||
ML7213/ML7223 is completely compatible for Intel EG20T PCH.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will
|
||||
be called pch_phub.
|
||||
|
|
|
@ -6,6 +6,7 @@ obj-$(CONFIG_IBM_ASM) += ibmasm/
|
|||
obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
|
||||
obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
|
||||
obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
|
||||
0bj-$(CONFIG_INTEL_MID_PTI) += pti.o
|
||||
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
|
||||
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
|
||||
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
|
||||
|
|
|
@ -34,12 +34,18 @@
|
|||
#define PHUB_TIMEOUT 0x05 /* Time out value for Status Register */
|
||||
#define PCH_PHUB_ROM_WRITE_ENABLE 0x01 /* Enabling for writing ROM */
|
||||
#define PCH_PHUB_ROM_WRITE_DISABLE 0x00 /* Disabling for writing ROM */
|
||||
#define PCH_PHUB_MAC_START_ADDR 0x20C /* MAC data area start address offset */
|
||||
#define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset
|
||||
#define PCH_PHUB_MAC_START_ADDR_EG20T 0x14 /* MAC data area start address
|
||||
offset */
|
||||
#define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C /* MAC data area start address
|
||||
offset */
|
||||
#define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
|
||||
(Intel EG20T PCH)*/
|
||||
#define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
|
||||
offset(OKI SEMICONDUCTOR ML7213)
|
||||
*/
|
||||
#define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
|
||||
offset(OKI SEMICONDUCTOR ML7223)
|
||||
*/
|
||||
|
||||
/* MAX number of INT_REDUCE_CONTROL registers */
|
||||
#define MAX_NUM_INT_REDUCE_CONTROL_REG 128
|
||||
|
@ -63,6 +69,10 @@
|
|||
#define PCI_VENDOR_ID_ROHM 0x10db
|
||||
#define PCI_DEVICE_ID_ROHM_ML7213_PHUB 0x801A
|
||||
|
||||
/* Macros for ML7223 */
|
||||
#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB 0x8012 /* for Bus-m */
|
||||
#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB 0x8002 /* for Bus-n */
|
||||
|
||||
/* SROM ACCESS Macro */
|
||||
#define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
|
||||
|
||||
|
@ -100,6 +110,9 @@
|
|||
* @clkcfg_reg: CLK CFG register val
|
||||
* @pch_phub_base_address: Register base address
|
||||
* @pch_phub_extrom_base_address: external rom base address
|
||||
* @pch_mac_start_address: MAC address area start address
|
||||
* @pch_opt_rom_start_address: Option ROM start address
|
||||
* @ioh_type: Save IOH type
|
||||
*/
|
||||
struct pch_phub_reg {
|
||||
u32 phub_id_reg;
|
||||
|
@ -117,6 +130,9 @@ struct pch_phub_reg {
|
|||
u32 clkcfg_reg;
|
||||
void __iomem *pch_phub_base_address;
|
||||
void __iomem *pch_phub_extrom_base_address;
|
||||
u32 pch_mac_start_address;
|
||||
u32 pch_opt_rom_start_address;
|
||||
int ioh_type;
|
||||
};
|
||||
|
||||
/* SROM SPEC for MAC address assignment offset */
|
||||
|
@ -319,7 +335,7 @@ static void pch_phub_read_serial_rom_val(struct pch_phub_reg *chip,
|
|||
{
|
||||
unsigned int mem_addr;
|
||||
|
||||
mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T +
|
||||
mem_addr = chip->pch_mac_start_address +
|
||||
pch_phub_mac_offset[offset_address];
|
||||
|
||||
pch_phub_read_serial_rom(chip, mem_addr, data);
|
||||
|
@ -336,7 +352,7 @@ static int pch_phub_write_serial_rom_val(struct pch_phub_reg *chip,
|
|||
int retval;
|
||||
unsigned int mem_addr;
|
||||
|
||||
mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T +
|
||||
mem_addr = chip->pch_mac_start_address +
|
||||
pch_phub_mac_offset[offset_address];
|
||||
|
||||
retval = pch_phub_write_serial_rom(chip, mem_addr, data);
|
||||
|
@ -384,6 +400,48 @@ static int pch_phub_gbe_serial_rom_conf(struct pch_phub_reg *chip)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
|
||||
* for Gigabit Ethernet MAC address
|
||||
*/
|
||||
static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
|
||||
{
|
||||
int retval;
|
||||
u32 offset_addr;
|
||||
|
||||
offset_addr = 0x200;
|
||||
retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
|
||||
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
|
||||
retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
|
||||
* @offset_address: Gigabit Ethernet MAC address offset value.
|
||||
|
@ -406,7 +464,10 @@ static int pch_phub_write_gbe_mac_addr(struct pch_phub_reg *chip, u8 *data)
|
|||
int retval;
|
||||
int i;
|
||||
|
||||
retval = pch_phub_gbe_serial_rom_conf(chip);
|
||||
if (chip->ioh_type == 1) /* EG20T */
|
||||
retval = pch_phub_gbe_serial_rom_conf(chip);
|
||||
else /* ML7223 */
|
||||
retval = pch_phub_gbe_serial_rom_conf_mp(chip);
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
|
@ -441,12 +502,16 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
|
|||
}
|
||||
|
||||
/* Get Rom signature */
|
||||
pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature);
|
||||
pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
|
||||
(unsigned char *)&rom_signature);
|
||||
rom_signature &= 0xff;
|
||||
pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp);
|
||||
pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
|
||||
(unsigned char *)&tmp);
|
||||
rom_signature |= (tmp & 0xff) << 8;
|
||||
if (rom_signature == 0xAA55) {
|
||||
pch_phub_read_serial_rom(chip, 0x82, &rom_length);
|
||||
pch_phub_read_serial_rom(chip,
|
||||
chip->pch_opt_rom_start_address + 2,
|
||||
&rom_length);
|
||||
orom_size = rom_length * 512;
|
||||
if (orom_size < off) {
|
||||
addr_offset = 0;
|
||||
|
@ -458,8 +523,9 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
|
|||
}
|
||||
|
||||
for (addr_offset = 0; addr_offset < count; addr_offset++) {
|
||||
pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off,
|
||||
&buf[addr_offset]);
|
||||
pch_phub_read_serial_rom(chip,
|
||||
chip->pch_opt_rom_start_address + addr_offset + off,
|
||||
&buf[addr_offset]);
|
||||
}
|
||||
} else {
|
||||
err = -ENODATA;
|
||||
|
@ -502,8 +568,9 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
|
|||
if (PCH_PHUB_OROM_SIZE < off + addr_offset)
|
||||
goto return_ok;
|
||||
|
||||
ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off,
|
||||
buf[addr_offset]);
|
||||
ret = pch_phub_write_serial_rom(chip,
|
||||
chip->pch_opt_rom_start_address + addr_offset + off,
|
||||
buf[addr_offset]);
|
||||
if (ret) {
|
||||
err = ret;
|
||||
goto return_err;
|
||||
|
@ -603,19 +670,22 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
|
|||
dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
|
||||
"in pch_phub_base_address variable is %p\n", __func__,
|
||||
chip->pch_phub_base_address);
|
||||
chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
|
||||
|
||||
if (chip->pch_phub_extrom_base_address == 0) {
|
||||
dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_pci_map;
|
||||
if (id->driver_data != 3) {
|
||||
chip->pch_phub_extrom_base_address =\
|
||||
pci_map_rom(pdev, &rom_size);
|
||||
if (chip->pch_phub_extrom_base_address == 0) {
|
||||
dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
|
||||
ret = -ENOMEM;
|
||||
goto err_pci_map;
|
||||
}
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"pci_map_rom SUCCESS and value in "
|
||||
"pch_phub_extrom_base_address variable is %p\n",
|
||||
__func__, chip->pch_phub_extrom_base_address);
|
||||
}
|
||||
dev_dbg(&pdev->dev, "%s : "
|
||||
"pci_map_rom SUCCESS and value in "
|
||||
"pch_phub_extrom_base_address variable is %p\n", __func__,
|
||||
chip->pch_phub_extrom_base_address);
|
||||
|
||||
if (id->driver_data == 1) {
|
||||
if (id->driver_data == 1) { /* EG20T PCH */
|
||||
retval = sysfs_create_file(&pdev->dev.kobj,
|
||||
&dev_attr_pch_mac.attr);
|
||||
if (retval)
|
||||
|
@ -642,7 +712,9 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
|
|||
iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
|
||||
/* set the interrupt delay value */
|
||||
iowrite32(0x25, chip->pch_phub_base_address + 0x44);
|
||||
} else if (id->driver_data == 2) {
|
||||
chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
|
||||
chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
|
||||
} else if (id->driver_data == 2) { /* ML7213 IOH */
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
|
||||
if (retval)
|
||||
goto err_sysfs_create;
|
||||
|
@ -653,7 +725,38 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
|
|||
* Device8(USB OHCI #0/ USB EHCI #0):a
|
||||
*/
|
||||
iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
|
||||
chip->pch_opt_rom_start_address =\
|
||||
PCH_PHUB_ROM_START_ADDR_ML7213;
|
||||
} else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
|
||||
/* set the prefech value
|
||||
* Device8(GbE)
|
||||
*/
|
||||
iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
|
||||
chip->pch_opt_rom_start_address =\
|
||||
PCH_PHUB_ROM_START_ADDR_ML7223;
|
||||
chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
|
||||
} else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
|
||||
retval = sysfs_create_file(&pdev->dev.kobj,
|
||||
&dev_attr_pch_mac.attr);
|
||||
if (retval)
|
||||
goto err_sysfs_create;
|
||||
retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
|
||||
if (retval)
|
||||
goto exit_bin_attr;
|
||||
/* set the prefech value
|
||||
* Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
|
||||
* Device4(SDIO #0,1):f
|
||||
* Device6(SATA 2):f
|
||||
*/
|
||||
iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
|
||||
/* set the interrupt delay value */
|
||||
iowrite32(0x25, chip->pch_phub_base_address + 0x140);
|
||||
chip->pch_opt_rom_start_address =\
|
||||
PCH_PHUB_ROM_START_ADDR_ML7223;
|
||||
chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
|
||||
}
|
||||
|
||||
chip->ioh_type = id->driver_data;
|
||||
pci_set_drvdata(pdev, chip);
|
||||
|
||||
return 0;
|
||||
|
@ -733,6 +836,8 @@ static int pch_phub_resume(struct pci_dev *pdev)
|
|||
static struct pci_device_id pch_phub_pcidev_id[] = {
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB), 1, },
|
||||
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2, },
|
||||
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3, },
|
||||
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4, },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
|
||||
|
@ -759,5 +864,5 @@ static void __exit pch_phub_pci_exit(void)
|
|||
module_init(pch_phub_pci_init);
|
||||
module_exit(pch_phub_pci_exit);
|
||||
|
||||
MODULE_DESCRIPTION("PCH Packet Hub PCI Driver");
|
||||
MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
980
drivers/misc/pti.c
Normal file
980
drivers/misc/pti.c
Normal file
|
@ -0,0 +1,980 @@
|
|||
/*
|
||||
* pti.c - PTI driver for cJTAG data extration
|
||||
*
|
||||
* Copyright (C) Intel 2010
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* The PTI (Parallel Trace Interface) driver directs trace data routed from
|
||||
* various parts in the system out through the Intel Penwell PTI port and
|
||||
* out of the mobile device for analysis with a debugging tool
|
||||
* (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
|
||||
* compact JTAG, standard.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_driver.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/pti.h>
|
||||
|
||||
#define DRIVERNAME "pti"
|
||||
#define PCINAME "pciPTI"
|
||||
#define TTYNAME "ttyPTI"
|
||||
#define CHARNAME "pti"
|
||||
#define PTITTY_MINOR_START 0
|
||||
#define PTITTY_MINOR_NUM 2
|
||||
#define MAX_APP_IDS 16 /* 128 channel ids / u8 bit size */
|
||||
#define MAX_OS_IDS 16 /* 128 channel ids / u8 bit size */
|
||||
#define MAX_MODEM_IDS 16 /* 128 channel ids / u8 bit size */
|
||||
#define MODEM_BASE_ID 71 /* modem master ID address */
|
||||
#define CONTROL_ID 72 /* control master ID address */
|
||||
#define CONSOLE_ID 73 /* console master ID address */
|
||||
#define OS_BASE_ID 74 /* base OS master ID address */
|
||||
#define APP_BASE_ID 80 /* base App master ID address */
|
||||
#define CONTROL_FRAME_LEN 32 /* PTI control frame maximum size */
|
||||
#define USER_COPY_SIZE 8192 /* 8Kb buffer for user space copy */
|
||||
#define APERTURE_14 0x3800000 /* offset to first OS write addr */
|
||||
#define APERTURE_LEN 0x400000 /* address length */
|
||||
|
||||
struct pti_tty {
|
||||
struct pti_masterchannel *mc;
|
||||
};
|
||||
|
||||
struct pti_dev {
|
||||
struct tty_port port;
|
||||
unsigned long pti_addr;
|
||||
unsigned long aperture_base;
|
||||
void __iomem *pti_ioaddr;
|
||||
u8 ia_app[MAX_APP_IDS];
|
||||
u8 ia_os[MAX_OS_IDS];
|
||||
u8 ia_modem[MAX_MODEM_IDS];
|
||||
};
|
||||
|
||||
/*
|
||||
* This protects access to ia_app, ia_os, and ia_modem,
|
||||
* which keeps track of channels allocated in
|
||||
* an aperture write id.
|
||||
*/
|
||||
static DEFINE_MUTEX(alloclock);
|
||||
|
||||
static struct pci_device_id pci_ids[] __devinitconst = {
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)},
|
||||
{0}
|
||||
};
|
||||
|
||||
static struct tty_driver *pti_tty_driver;
|
||||
static struct pti_dev *drv_data;
|
||||
|
||||
static unsigned int pti_console_channel;
|
||||
static unsigned int pti_control_channel;
|
||||
|
||||
/**
|
||||
* pti_write_to_aperture()- The private write function to PTI HW.
|
||||
*
|
||||
* @mc: The 'aperture'. It's part of a write address that holds
|
||||
* a master and channel ID.
|
||||
* @buf: Data being written to the HW that will ultimately be seen
|
||||
* in a debugging tool (Fido, Lauterbach).
|
||||
* @len: Size of buffer.
|
||||
*
|
||||
* Since each aperture is specified by a unique
|
||||
* master/channel ID, no two processes will be writing
|
||||
* to the same aperture at the same time so no lock is required. The
|
||||
* PTI-Output agent will send these out in the order that they arrived, and
|
||||
* thus, it will intermix these messages. The debug tool can then later
|
||||
* regroup the appropriate message segments together reconstituting each
|
||||
* message.
|
||||
*/
|
||||
static void pti_write_to_aperture(struct pti_masterchannel *mc,
|
||||
u8 *buf,
|
||||
int len)
|
||||
{
|
||||
int dwordcnt;
|
||||
int final;
|
||||
int i;
|
||||
u32 ptiword;
|
||||
u32 __iomem *aperture;
|
||||
u8 *p = buf;
|
||||
|
||||
/*
|
||||
* calculate the aperture offset from the base using the master and
|
||||
* channel id's.
|
||||
*/
|
||||
aperture = drv_data->pti_ioaddr + (mc->master << 15)
|
||||
+ (mc->channel << 8);
|
||||
|
||||
dwordcnt = len >> 2;
|
||||
final = len - (dwordcnt << 2); /* final = trailing bytes */
|
||||
if (final == 0 && dwordcnt != 0) { /* always need a final dword */
|
||||
final += 4;
|
||||
dwordcnt--;
|
||||
}
|
||||
|
||||
for (i = 0; i < dwordcnt; i++) {
|
||||
ptiword = be32_to_cpu(*(u32 *)p);
|
||||
p += 4;
|
||||
iowrite32(ptiword, aperture);
|
||||
}
|
||||
|
||||
aperture += PTI_LASTDWORD_DTS; /* adding DTS signals that is EOM */
|
||||
|
||||
ptiword = 0;
|
||||
for (i = 0; i < final; i++)
|
||||
ptiword |= *p++ << (24-(8*i));
|
||||
|
||||
iowrite32(ptiword, aperture);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_control_frame_built_and_sent()- control frame build and send function.
|
||||
*
|
||||
* @mc: The master / channel structure on which the function
|
||||
* built a control frame.
|
||||
*
|
||||
* To be able to post process the PTI contents on host side, a control frame
|
||||
* is added before sending any PTI content. So the host side knows on
|
||||
* each PTI frame the name of the thread using a dedicated master / channel.
|
||||
* The thread name is retrieved from the 'current' global variable.
|
||||
* This function builds this frame and sends it to a master ID CONTROL_ID.
|
||||
* The overhead is only 32 bytes since the driver only writes to HW
|
||||
* in 32 byte chunks.
|
||||
*/
|
||||
|
||||
static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc)
|
||||
{
|
||||
struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
|
||||
.channel = 0};
|
||||
const char *control_format = "%3d %3d %s";
|
||||
u8 control_frame[CONTROL_FRAME_LEN];
|
||||
|
||||
/*
|
||||
* Since we access the comm member in current's task_struct,
|
||||
* we only need to be as large as what 'comm' in that
|
||||
* structure is.
|
||||
*/
|
||||
char comm[TASK_COMM_LEN];
|
||||
|
||||
if (!in_interrupt())
|
||||
get_task_comm(comm, current);
|
||||
else
|
||||
strncpy(comm, "Interrupt", TASK_COMM_LEN);
|
||||
|
||||
/* Absolutely ensure our buffer is zero terminated. */
|
||||
comm[TASK_COMM_LEN-1] = 0;
|
||||
|
||||
mccontrol.channel = pti_control_channel;
|
||||
pti_control_channel = (pti_control_channel + 1) & 0x7f;
|
||||
|
||||
snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
|
||||
mc->channel, comm);
|
||||
pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_write_full_frame_to_aperture()- high level function to
|
||||
* write to PTI.
|
||||
*
|
||||
* @mc: The 'aperture'. It's part of a write address that holds
|
||||
* a master and channel ID.
|
||||
* @buf: Data being written to the HW that will ultimately be seen
|
||||
* in a debugging tool (Fido, Lauterbach).
|
||||
* @len: Size of buffer.
|
||||
*
|
||||
* All threads sending data (either console, user space application, ...)
|
||||
* are calling the high level function to write to PTI meaning that it is
|
||||
* possible to add a control frame before sending the content.
|
||||
*/
|
||||
static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
|
||||
const unsigned char *buf,
|
||||
int len)
|
||||
{
|
||||
pti_control_frame_built_and_sent(mc);
|
||||
pti_write_to_aperture(mc, (u8 *)buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_id()- Allocate a master and channel ID.
|
||||
*
|
||||
* @id_array: an array of bits representing what channel
|
||||
* id's are allocated for writing.
|
||||
* @max_ids: The max amount of available write IDs to use.
|
||||
* @base_id: The starting SW channel ID, based on the Intel
|
||||
* PTI arch.
|
||||
*
|
||||
* Returns:
|
||||
* pti_masterchannel struct with master, channel ID address
|
||||
* 0 for error
|
||||
*
|
||||
* Each bit in the arrays ia_app and ia_os correspond to a master and
|
||||
* channel id. The bit is one if the id is taken and 0 if free. For
|
||||
* every master there are 128 channel id's.
|
||||
*/
|
||||
static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id)
|
||||
{
|
||||
struct pti_masterchannel *mc;
|
||||
int i, j, mask;
|
||||
|
||||
mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL);
|
||||
if (mc == NULL)
|
||||
return NULL;
|
||||
|
||||
/* look for a byte with a free bit */
|
||||
for (i = 0; i < max_ids; i++)
|
||||
if (id_array[i] != 0xff)
|
||||
break;
|
||||
if (i == max_ids) {
|
||||
kfree(mc);
|
||||
return NULL;
|
||||
}
|
||||
/* find the bit in the 128 possible channel opportunities */
|
||||
mask = 0x80;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if ((id_array[i] & mask) == 0)
|
||||
break;
|
||||
mask >>= 1;
|
||||
}
|
||||
|
||||
/* grab it */
|
||||
id_array[i] |= mask;
|
||||
mc->master = base_id;
|
||||
mc->channel = ((i & 0xf)<<3) + j;
|
||||
/* write new master Id / channel Id allocation to channel control */
|
||||
pti_control_frame_built_and_sent(mc);
|
||||
return mc;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following three functions:
|
||||
* pti_request_mastercahannel(), mipi_release_masterchannel()
|
||||
* and pti_writedata() are an API for other kernel drivers to
|
||||
* access PTI.
|
||||
*/
|
||||
|
||||
/**
|
||||
* pti_request_masterchannel()- Kernel API function used to allocate
|
||||
* a master, channel ID address
|
||||
* to write to PTI HW.
|
||||
*
|
||||
* @type: 0- request Application master, channel aperture ID write address.
|
||||
* 1- request OS master, channel aperture ID write
|
||||
* address.
|
||||
* 2- request Modem master, channel aperture ID
|
||||
* write address.
|
||||
* Other values, error.
|
||||
*
|
||||
* Returns:
|
||||
* pti_masterchannel struct
|
||||
* 0 for error
|
||||
*/
|
||||
struct pti_masterchannel *pti_request_masterchannel(u8 type)
|
||||
{
|
||||
struct pti_masterchannel *mc;
|
||||
|
||||
mutex_lock(&alloclock);
|
||||
|
||||
switch (type) {
|
||||
|
||||
case 0:
|
||||
mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID);
|
||||
break;
|
||||
default:
|
||||
mc = NULL;
|
||||
}
|
||||
|
||||
mutex_unlock(&alloclock);
|
||||
return mc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pti_request_masterchannel);
|
||||
|
||||
/**
|
||||
* pti_release_masterchannel()- Kernel API function used to release
|
||||
* a master, channel ID address
|
||||
* used to write to PTI HW.
|
||||
*
|
||||
* @mc: master, channel apeture ID address to be released.
|
||||
*/
|
||||
void pti_release_masterchannel(struct pti_masterchannel *mc)
|
||||
{
|
||||
u8 master, channel, i;
|
||||
|
||||
mutex_lock(&alloclock);
|
||||
|
||||
if (mc) {
|
||||
master = mc->master;
|
||||
channel = mc->channel;
|
||||
|
||||
if (master == APP_BASE_ID) {
|
||||
i = channel >> 3;
|
||||
drv_data->ia_app[i] &= ~(0x80>>(channel & 0x7));
|
||||
} else if (master == OS_BASE_ID) {
|
||||
i = channel >> 3;
|
||||
drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7));
|
||||
} else {
|
||||
i = channel >> 3;
|
||||
drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7));
|
||||
}
|
||||
|
||||
kfree(mc);
|
||||
}
|
||||
|
||||
mutex_unlock(&alloclock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pti_release_masterchannel);
|
||||
|
||||
/**
|
||||
* pti_writedata()- Kernel API function used to write trace
|
||||
* debugging data to PTI HW.
|
||||
*
|
||||
* @mc: Master, channel aperture ID address to write to.
|
||||
* Null value will return with no write occurring.
|
||||
* @buf: Trace debuging data to write to the PTI HW.
|
||||
* Null value will return with no write occurring.
|
||||
* @count: Size of buf. Value of 0 or a negative number will
|
||||
* return with no write occuring.
|
||||
*/
|
||||
void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count)
|
||||
{
|
||||
/*
|
||||
* since this function is exported, this is treated like an
|
||||
* API function, thus, all parameters should
|
||||
* be checked for validity.
|
||||
*/
|
||||
if ((mc != NULL) && (buf != NULL) && (count > 0))
|
||||
pti_write_to_aperture(mc, buf, count);
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pti_writedata);
|
||||
|
||||
/**
|
||||
* pti_pci_remove()- Driver exit method to remove PTI from
|
||||
* PCI bus.
|
||||
* @pdev: variable containing pci info of PTI.
|
||||
*/
|
||||
static void __devexit pti_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct pti_dev *drv_data;
|
||||
|
||||
drv_data = pci_get_drvdata(pdev);
|
||||
if (drv_data != NULL) {
|
||||
pci_iounmap(pdev, drv_data->pti_ioaddr);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
kfree(drv_data);
|
||||
pci_release_region(pdev, 1);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* for the tty_driver_*() basic function descriptions, see tty_driver.h.
|
||||
* Specific header comments made for PTI-related specifics.
|
||||
*/
|
||||
|
||||
/**
|
||||
* pti_tty_driver_open()- Open an Application master, channel aperture
|
||||
* ID to the PTI device via tty device.
|
||||
*
|
||||
* @tty: tty interface.
|
||||
* @filp: filp interface pased to tty_port_open() call.
|
||||
*
|
||||
* Returns:
|
||||
* int, 0 for success
|
||||
* otherwise, fail value
|
||||
*
|
||||
* The main purpose of using the tty device interface is for
|
||||
* each tty port to have a unique PTI write aperture. In an
|
||||
* example use case, ttyPTI0 gets syslogd and an APP aperture
|
||||
* ID and ttyPTI1 is where the n_tracesink ldisc hooks to route
|
||||
* modem messages into PTI. Modem trace data does not have to
|
||||
* go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct
|
||||
* master IDs. These messages go through the PTI HW and out of
|
||||
* the handheld platform and to the Fido/Lauterbach device.
|
||||
*/
|
||||
static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
/*
|
||||
* we actually want to allocate a new channel per open, per
|
||||
* system arch. HW gives more than plenty channels for a single
|
||||
* system task to have its own channel to write trace data. This
|
||||
* also removes a locking requirement for the actual write
|
||||
* procedure.
|
||||
*/
|
||||
return tty_port_open(&drv_data->port, tty, filp);
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_tty_driver_close()- close tty device and release Application
|
||||
* master, channel aperture ID to the PTI device via tty device.
|
||||
*
|
||||
* @tty: tty interface.
|
||||
* @filp: filp interface pased to tty_port_close() call.
|
||||
*
|
||||
* The main purpose of using the tty device interface is to route
|
||||
* syslog daemon messages to the PTI HW and out of the handheld platform
|
||||
* and to the Fido/Lauterbach device.
|
||||
*/
|
||||
static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
|
||||
{
|
||||
tty_port_close(&drv_data->port, tty, filp);
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_tty_intstall()- Used to set up specific master-channels
|
||||
* to tty ports for organizational purposes when
|
||||
* tracing viewed from debuging tools.
|
||||
*
|
||||
* @driver: tty driver information.
|
||||
* @tty: tty struct containing pti information.
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success
|
||||
* otherwise, error
|
||||
*/
|
||||
static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
|
||||
{
|
||||
int idx = tty->index;
|
||||
struct pti_tty *pti_tty_data;
|
||||
int ret = tty_init_termios(tty);
|
||||
|
||||
if (ret == 0) {
|
||||
tty_driver_kref_get(driver);
|
||||
tty->count++;
|
||||
driver->ttys[idx] = tty;
|
||||
|
||||
pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL);
|
||||
if (pti_tty_data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
if (idx == PTITTY_MINOR_START)
|
||||
pti_tty_data->mc = pti_request_masterchannel(0);
|
||||
else
|
||||
pti_tty_data->mc = pti_request_masterchannel(2);
|
||||
|
||||
if (pti_tty_data->mc == NULL)
|
||||
return -ENXIO;
|
||||
tty->driver_data = pti_tty_data;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_tty_cleanup()- Used to de-allocate master-channel resources
|
||||
* tied to tty's of this driver.
|
||||
*
|
||||
* @tty: tty struct containing pti information.
|
||||
*/
|
||||
static void pti_tty_cleanup(struct tty_struct *tty)
|
||||
{
|
||||
struct pti_tty *pti_tty_data = tty->driver_data;
|
||||
if (pti_tty_data == NULL)
|
||||
return;
|
||||
pti_release_masterchannel(pti_tty_data->mc);
|
||||
kfree(tty->driver_data);
|
||||
tty->driver_data = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_tty_driver_write()- Write trace debugging data through the char
|
||||
* interface to the PTI HW. Part of the misc device implementation.
|
||||
*
|
||||
* @filp: Contains private data which is used to obtain
|
||||
* master, channel write ID.
|
||||
* @data: trace data to be written.
|
||||
* @len: # of byte to write.
|
||||
*
|
||||
* Returns:
|
||||
* int, # of bytes written
|
||||
* otherwise, error
|
||||
*/
|
||||
static int pti_tty_driver_write(struct tty_struct *tty,
|
||||
const unsigned char *buf, int len)
|
||||
{
|
||||
struct pti_tty *pti_tty_data = tty->driver_data;
|
||||
if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) {
|
||||
pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len);
|
||||
return len;
|
||||
}
|
||||
/*
|
||||
* we can't write to the pti hardware if the private driver_data
|
||||
* and the mc address is not there.
|
||||
*/
|
||||
else
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_tty_write_room()- Always returns 2048.
|
||||
*
|
||||
* @tty: contains tty info of the pti driver.
|
||||
*/
|
||||
static int pti_tty_write_room(struct tty_struct *tty)
|
||||
{
|
||||
return 2048;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_char_open()- Open an Application master, channel aperture
|
||||
* ID to the PTI device. Part of the misc device implementation.
|
||||
*
|
||||
* @inode: not used.
|
||||
* @filp: Output- will have a masterchannel struct set containing
|
||||
* the allocated application PTI aperture write address.
|
||||
*
|
||||
* Returns:
|
||||
* int, 0 for success
|
||||
* otherwise, a fail value
|
||||
*/
|
||||
static int pti_char_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct pti_masterchannel *mc;
|
||||
|
||||
/*
|
||||
* We really do want to fail immediately if
|
||||
* pti_request_masterchannel() fails,
|
||||
* before assigning the value to filp->private_data.
|
||||
* Slightly easier to debug if this driver needs debugging.
|
||||
*/
|
||||
mc = pti_request_masterchannel(0);
|
||||
if (mc == NULL)
|
||||
return -ENOMEM;
|
||||
filp->private_data = mc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_char_release()- Close a char channel to the PTI device. Part
|
||||
* of the misc device implementation.
|
||||
*
|
||||
* @inode: Not used in this implementaiton.
|
||||
* @filp: Contains private_data that contains the master, channel
|
||||
* ID to be released by the PTI device.
|
||||
*
|
||||
* Returns:
|
||||
* always 0
|
||||
*/
|
||||
static int pti_char_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
pti_release_masterchannel(filp->private_data);
|
||||
kfree(filp->private_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_char_write()- Write trace debugging data through the char
|
||||
* interface to the PTI HW. Part of the misc device implementation.
|
||||
*
|
||||
* @filp: Contains private data which is used to obtain
|
||||
* master, channel write ID.
|
||||
* @data: trace data to be written.
|
||||
* @len: # of byte to write.
|
||||
* @ppose: Not used in this function implementation.
|
||||
*
|
||||
* Returns:
|
||||
* int, # of bytes written
|
||||
* otherwise, error value
|
||||
*
|
||||
* Notes: From side discussions with Alan Cox and experimenting
|
||||
* with PTI debug HW like Nokia's Fido box and Lauterbach
|
||||
* devices, 8192 byte write buffer used by USER_COPY_SIZE was
|
||||
* deemed an appropriate size for this type of usage with
|
||||
* debugging HW.
|
||||
*/
|
||||
static ssize_t pti_char_write(struct file *filp, const char __user *data,
|
||||
size_t len, loff_t *ppose)
|
||||
{
|
||||
struct pti_masterchannel *mc;
|
||||
void *kbuf;
|
||||
const char __user *tmp;
|
||||
size_t size = USER_COPY_SIZE;
|
||||
size_t n = 0;
|
||||
|
||||
tmp = data;
|
||||
mc = filp->private_data;
|
||||
|
||||
kbuf = kmalloc(size, GFP_KERNEL);
|
||||
if (kbuf == NULL) {
|
||||
pr_err("%s(%d): buf allocation failed\n",
|
||||
__func__, __LINE__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
do {
|
||||
if (len - n > USER_COPY_SIZE)
|
||||
size = USER_COPY_SIZE;
|
||||
else
|
||||
size = len - n;
|
||||
|
||||
if (copy_from_user(kbuf, tmp, size)) {
|
||||
kfree(kbuf);
|
||||
return n ? n : -EFAULT;
|
||||
}
|
||||
|
||||
pti_write_to_aperture(mc, kbuf, size);
|
||||
n += size;
|
||||
tmp += size;
|
||||
|
||||
} while (len > n);
|
||||
|
||||
kfree(kbuf);
|
||||
return len;
|
||||
}
|
||||
|
||||
static const struct tty_operations pti_tty_driver_ops = {
|
||||
.open = pti_tty_driver_open,
|
||||
.close = pti_tty_driver_close,
|
||||
.write = pti_tty_driver_write,
|
||||
.write_room = pti_tty_write_room,
|
||||
.install = pti_tty_install,
|
||||
.cleanup = pti_tty_cleanup
|
||||
};
|
||||
|
||||
static const struct file_operations pti_char_driver_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.write = pti_char_write,
|
||||
.open = pti_char_open,
|
||||
.release = pti_char_release,
|
||||
};
|
||||
|
||||
static struct miscdevice pti_char_driver = {
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
.name = CHARNAME,
|
||||
.fops = &pti_char_driver_ops
|
||||
};
|
||||
|
||||
/**
|
||||
* pti_console_write()- Write to the console that has been acquired.
|
||||
*
|
||||
* @c: Not used in this implementaiton.
|
||||
* @buf: Data to be written.
|
||||
* @len: Length of buf.
|
||||
*/
|
||||
static void pti_console_write(struct console *c, const char *buf, unsigned len)
|
||||
{
|
||||
static struct pti_masterchannel mc = {.master = CONSOLE_ID,
|
||||
.channel = 0};
|
||||
|
||||
mc.channel = pti_console_channel;
|
||||
pti_console_channel = (pti_console_channel + 1) & 0x7f;
|
||||
|
||||
pti_write_full_frame_to_aperture(&mc, buf, len);
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_console_device()- Return the driver tty structure and set the
|
||||
* associated index implementation.
|
||||
*
|
||||
* @c: Console device of the driver.
|
||||
* @index: index associated with c.
|
||||
*
|
||||
* Returns:
|
||||
* always value of pti_tty_driver structure when this function
|
||||
* is called.
|
||||
*/
|
||||
static struct tty_driver *pti_console_device(struct console *c, int *index)
|
||||
{
|
||||
*index = c->index;
|
||||
return pti_tty_driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_console_setup()- Initialize console variables used by the driver.
|
||||
*
|
||||
* @c: Not used.
|
||||
* @opts: Not used.
|
||||
*
|
||||
* Returns:
|
||||
* always 0.
|
||||
*/
|
||||
static int pti_console_setup(struct console *c, char *opts)
|
||||
{
|
||||
pti_console_channel = 0;
|
||||
pti_control_channel = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* pti_console struct, used to capture OS printk()'s and shift
|
||||
* out to the PTI device for debugging. This cannot be
|
||||
* enabled upon boot because of the possibility of eating
|
||||
* any serial console printk's (race condition discovered).
|
||||
* The console should be enabled upon when the tty port is
|
||||
* used for the first time. Since the primary purpose for
|
||||
* the tty port is to hook up syslog to it, the tty port
|
||||
* will be open for a really long time.
|
||||
*/
|
||||
static struct console pti_console = {
|
||||
.name = TTYNAME,
|
||||
.write = pti_console_write,
|
||||
.device = pti_console_device,
|
||||
.setup = pti_console_setup,
|
||||
.flags = CON_PRINTBUFFER,
|
||||
.index = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* pti_port_activate()- Used to start/initialize any items upon
|
||||
* first opening of tty_port().
|
||||
*
|
||||
* @port- The tty port number of the PTI device.
|
||||
* @tty- The tty struct associated with this device.
|
||||
*
|
||||
* Returns:
|
||||
* always returns 0
|
||||
*
|
||||
* Notes: The primary purpose of the PTI tty port 0 is to hook
|
||||
* the syslog daemon to it; thus this port will be open for a
|
||||
* very long time.
|
||||
*/
|
||||
static int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
|
||||
{
|
||||
if (port->tty->index == PTITTY_MINOR_START)
|
||||
console_start(&pti_console);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_port_shutdown()- Used to stop/shutdown any items upon the
|
||||
* last tty port close.
|
||||
*
|
||||
* @port- The tty port number of the PTI device.
|
||||
*
|
||||
* Notes: The primary purpose of the PTI tty port 0 is to hook
|
||||
* the syslog daemon to it; thus this port will be open for a
|
||||
* very long time.
|
||||
*/
|
||||
static void pti_port_shutdown(struct tty_port *port)
|
||||
{
|
||||
if (port->tty->index == PTITTY_MINOR_START)
|
||||
console_stop(&pti_console);
|
||||
}
|
||||
|
||||
static const struct tty_port_operations tty_port_ops = {
|
||||
.activate = pti_port_activate,
|
||||
.shutdown = pti_port_shutdown,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note the _probe() call sets everything up and ties the char and tty
|
||||
* to successfully detecting the PTI device on the pci bus.
|
||||
*/
|
||||
|
||||
/**
|
||||
* pti_pci_probe()- Used to detect pti on the pci bus and set
|
||||
* things up in the driver.
|
||||
*
|
||||
* @pdev- pci_dev struct values for pti.
|
||||
* @ent- pci_device_id struct for pti driver.
|
||||
*
|
||||
* Returns:
|
||||
* 0 for success
|
||||
* otherwise, error
|
||||
*/
|
||||
static int __devinit pti_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
int retval = -EINVAL;
|
||||
int pci_bar = 1;
|
||||
|
||||
dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__,
|
||||
__func__, __LINE__, pdev->vendor, pdev->device);
|
||||
|
||||
retval = misc_register(&pti_char_driver);
|
||||
if (retval) {
|
||||
pr_err("%s(%d): CHAR registration failed of pti driver\n",
|
||||
__func__, __LINE__);
|
||||
pr_err("%s(%d): Error value returned: %d\n",
|
||||
__func__, __LINE__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = pci_enable_device(pdev);
|
||||
if (retval != 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s: pci_enable_device() returned error %d\n",
|
||||
__func__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
|
||||
|
||||
if (drv_data == NULL) {
|
||||
retval = -ENOMEM;
|
||||
dev_err(&pdev->dev,
|
||||
"%s(%d): kmalloc() returned NULL memory.\n",
|
||||
__func__, __LINE__);
|
||||
return retval;
|
||||
}
|
||||
drv_data->pti_addr = pci_resource_start(pdev, pci_bar);
|
||||
|
||||
retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
|
||||
if (retval != 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"%s(%d): pci_request_region() returned error %d\n",
|
||||
__func__, __LINE__, retval);
|
||||
kfree(drv_data);
|
||||
return retval;
|
||||
}
|
||||
drv_data->aperture_base = drv_data->pti_addr+APERTURE_14;
|
||||
drv_data->pti_ioaddr =
|
||||
ioremap_nocache((u32)drv_data->aperture_base,
|
||||
APERTURE_LEN);
|
||||
if (!drv_data->pti_ioaddr) {
|
||||
pci_release_region(pdev, pci_bar);
|
||||
retval = -ENOMEM;
|
||||
kfree(drv_data);
|
||||
return retval;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, drv_data);
|
||||
|
||||
tty_port_init(&drv_data->port);
|
||||
drv_data->port.ops = &tty_port_ops;
|
||||
|
||||
tty_register_device(pti_tty_driver, 0, &pdev->dev);
|
||||
tty_register_device(pti_tty_driver, 1, &pdev->dev);
|
||||
|
||||
register_console(&pti_console);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static struct pci_driver pti_pci_driver = {
|
||||
.name = PCINAME,
|
||||
.id_table = pci_ids,
|
||||
.probe = pti_pci_probe,
|
||||
.remove = pti_pci_remove,
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* pti_init()- Overall entry/init call to the pti driver.
|
||||
* It starts the registration process with the kernel.
|
||||
*
|
||||
* Returns:
|
||||
* int __init, 0 for success
|
||||
* otherwise value is an error
|
||||
*
|
||||
*/
|
||||
static int __init pti_init(void)
|
||||
{
|
||||
int retval = -EINVAL;
|
||||
|
||||
/* First register module as tty device */
|
||||
|
||||
pti_tty_driver = alloc_tty_driver(1);
|
||||
if (pti_tty_driver == NULL) {
|
||||
pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n",
|
||||
__func__, __LINE__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
pti_tty_driver->owner = THIS_MODULE;
|
||||
pti_tty_driver->magic = TTY_DRIVER_MAGIC;
|
||||
pti_tty_driver->driver_name = DRIVERNAME;
|
||||
pti_tty_driver->name = TTYNAME;
|
||||
pti_tty_driver->major = 0;
|
||||
pti_tty_driver->minor_start = PTITTY_MINOR_START;
|
||||
pti_tty_driver->minor_num = PTITTY_MINOR_NUM;
|
||||
pti_tty_driver->num = PTITTY_MINOR_NUM;
|
||||
pti_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
|
||||
pti_tty_driver->subtype = SYSTEM_TYPE_SYSCONS;
|
||||
pti_tty_driver->flags = TTY_DRIVER_REAL_RAW |
|
||||
TTY_DRIVER_DYNAMIC_DEV;
|
||||
pti_tty_driver->init_termios = tty_std_termios;
|
||||
|
||||
tty_set_operations(pti_tty_driver, &pti_tty_driver_ops);
|
||||
|
||||
retval = tty_register_driver(pti_tty_driver);
|
||||
if (retval) {
|
||||
pr_err("%s(%d): TTY registration failed of pti driver\n",
|
||||
__func__, __LINE__);
|
||||
pr_err("%s(%d): Error value returned: %d\n",
|
||||
__func__, __LINE__, retval);
|
||||
|
||||
pti_tty_driver = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
retval = pci_register_driver(&pti_pci_driver);
|
||||
|
||||
if (retval) {
|
||||
pr_err("%s(%d): PCI registration failed of pti driver\n",
|
||||
__func__, __LINE__);
|
||||
pr_err("%s(%d): Error value returned: %d\n",
|
||||
__func__, __LINE__, retval);
|
||||
|
||||
tty_unregister_driver(pti_tty_driver);
|
||||
pr_err("%s(%d): Unregistering TTY part of pti driver\n",
|
||||
__func__, __LINE__);
|
||||
pti_tty_driver = NULL;
|
||||
return retval;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* pti_exit()- Unregisters this module as a tty and pci driver.
|
||||
*/
|
||||
static void __exit pti_exit(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
tty_unregister_device(pti_tty_driver, 0);
|
||||
tty_unregister_device(pti_tty_driver, 1);
|
||||
|
||||
retval = tty_unregister_driver(pti_tty_driver);
|
||||
if (retval) {
|
||||
pr_err("%s(%d): TTY unregistration failed of pti driver\n",
|
||||
__func__, __LINE__);
|
||||
pr_err("%s(%d): Error value returned: %d\n",
|
||||
__func__, __LINE__, retval);
|
||||
}
|
||||
|
||||
pci_unregister_driver(&pti_pci_driver);
|
||||
|
||||
retval = misc_deregister(&pti_char_driver);
|
||||
if (retval) {
|
||||
pr_err("%s(%d): CHAR unregistration failed of pti driver\n",
|
||||
__func__, __LINE__);
|
||||
pr_err("%s(%d): Error value returned: %d\n",
|
||||
__func__, __LINE__, retval);
|
||||
}
|
||||
|
||||
unregister_console(&pti_console);
|
||||
return;
|
||||
}
|
||||
|
||||
module_init(pti_init);
|
||||
module_exit(pti_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Ken Mills, Jay Freyensee");
|
||||
MODULE_DESCRIPTION("PTI Driver");
|
||||
|
|
@ -747,8 +747,8 @@ static void st_tty_close(struct tty_struct *tty)
|
|||
pr_debug("%s: done ", __func__);
|
||||
}
|
||||
|
||||
static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
|
||||
char *tty_flags, int count)
|
||||
static unsigned int st_tty_receive(struct tty_struct *tty,
|
||||
const unsigned char *data, char *tty_flags, int count)
|
||||
{
|
||||
#ifdef VERBOSE
|
||||
print_hex_dump(KERN_DEBUG, ">in>", DUMP_PREFIX_NONE,
|
||||
|
@ -761,6 +761,8 @@ static void st_tty_receive(struct tty_struct *tty, const unsigned char *data,
|
|||
*/
|
||||
st_recv(tty->disc_data, data, count);
|
||||
pr_debug("done %s", __func__);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* wake-up function called in from the TTY layer
|
||||
|
|
|
@ -167,8 +167,8 @@ static inline void debugfs_tx(struct ser_device *ser, const u8 *data, int size)
|
|||
|
||||
#endif
|
||||
|
||||
static void ldisc_receive(struct tty_struct *tty, const u8 *data,
|
||||
char *flags, int count)
|
||||
static unsigned int ldisc_receive(struct tty_struct *tty,
|
||||
const u8 *data, char *flags, int count)
|
||||
{
|
||||
struct sk_buff *skb = NULL;
|
||||
struct ser_device *ser;
|
||||
|
@ -215,6 +215,8 @@ static void ldisc_receive(struct tty_struct *tty, const u8 *data,
|
|||
} else
|
||||
++ser->dev->stats.rx_dropped;
|
||||
update_tty_status(ser);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int handle_tx(struct ser_device *ser)
|
||||
|
|
|
@ -425,16 +425,17 @@ static void slc_setup(struct net_device *dev)
|
|||
* in parallel
|
||||
*/
|
||||
|
||||
static void slcan_receive_buf(struct tty_struct *tty,
|
||||
static unsigned int slcan_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct slcan *sl = (struct slcan *) tty->disc_data;
|
||||
int bytes = count;
|
||||
|
||||
if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
/* Read the characters out of the buffer */
|
||||
while (count--) {
|
||||
while (bytes--) {
|
||||
if (fp && *fp++) {
|
||||
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
|
||||
sl->dev->stats.rx_errors++;
|
||||
|
@ -443,6 +444,8 @@ static void slcan_receive_buf(struct tty_struct *tty,
|
|||
}
|
||||
slcan_unesc(sl, *cp++);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/************************************
|
||||
|
|
|
@ -456,7 +456,7 @@ out:
|
|||
* a block of 6pack data has been received, which can now be decapsulated
|
||||
* and sent on to some IP layer for further processing.
|
||||
*/
|
||||
static void sixpack_receive_buf(struct tty_struct *tty,
|
||||
static unsigned int sixpack_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct sixpack *sp;
|
||||
|
@ -464,11 +464,11 @@ static void sixpack_receive_buf(struct tty_struct *tty,
|
|||
int count1;
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
sp = sp_get(tty);
|
||||
if (!sp)
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
|
||||
|
||||
|
@ -487,6 +487,8 @@ static void sixpack_receive_buf(struct tty_struct *tty,
|
|||
|
||||
sp_put(sp);
|
||||
tty_unthrottle(tty);
|
||||
|
||||
return count1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -923,13 +923,14 @@ static long mkiss_compat_ioctl(struct tty_struct *tty, struct file *file,
|
|||
* a block of data has been received, which can now be decapsulated
|
||||
* and sent on to the AX.25 layer for further processing.
|
||||
*/
|
||||
static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
static unsigned int mkiss_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct mkiss *ax = mkiss_get(tty);
|
||||
int bytes = count;
|
||||
|
||||
if (!ax)
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Argh! mtu change time! - costs us the packet part received
|
||||
|
@ -939,7 +940,7 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
ax_changedmtu(ax);
|
||||
|
||||
/* Read the characters out of the buffer */
|
||||
while (count--) {
|
||||
while (bytes--) {
|
||||
if (fp != NULL && *fp++) {
|
||||
if (!test_and_set_bit(AXF_ERROR, &ax->flags))
|
||||
ax->dev->stats.rx_errors++;
|
||||
|
@ -952,6 +953,8 @@ static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
|
||||
mkiss_put(ax);
|
||||
tty_unthrottle(tty);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -216,23 +216,23 @@ static int irtty_do_write(struct sir_dev *dev, const unsigned char *ptr, size_t
|
|||
* usbserial: urb-complete-interrupt / softint
|
||||
*/
|
||||
|
||||
static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
static unsigned int irtty_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct sir_dev *dev;
|
||||
struct sirtty_cb *priv = tty->disc_data;
|
||||
int i;
|
||||
|
||||
IRDA_ASSERT(priv != NULL, return;);
|
||||
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return;);
|
||||
IRDA_ASSERT(priv != NULL, return -ENODEV;);
|
||||
IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -EINVAL;);
|
||||
|
||||
if (unlikely(count==0)) /* yes, this happens */
|
||||
return;
|
||||
return 0;
|
||||
|
||||
dev = priv->dev;
|
||||
if (!dev) {
|
||||
IRDA_WARNING("%s(), not ready yet!\n", __func__);
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
|
@ -242,11 +242,13 @@ static void irtty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
if (fp && *fp++) {
|
||||
IRDA_DEBUG(0, "Framing or parity error!\n");
|
||||
sirdev_receive(dev, NULL, 0); /* notify sir_dev (updating stats) */
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
sirdev_receive(dev, cp, count);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -340,7 +340,7 @@ ppp_asynctty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
|
|||
}
|
||||
|
||||
/* May sleep, don't call from interrupt level or with interrupts disabled */
|
||||
static void
|
||||
static unsigned int
|
||||
ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
|
||||
char *cflags, int count)
|
||||
{
|
||||
|
@ -348,7 +348,7 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
|
|||
unsigned long flags;
|
||||
|
||||
if (!ap)
|
||||
return;
|
||||
return -ENODEV;
|
||||
spin_lock_irqsave(&ap->recv_lock, flags);
|
||||
ppp_async_input(ap, buf, cflags, count);
|
||||
spin_unlock_irqrestore(&ap->recv_lock, flags);
|
||||
|
@ -356,6 +356,8 @@ ppp_asynctty_receive(struct tty_struct *tty, const unsigned char *buf,
|
|||
tasklet_schedule(&ap->tsk);
|
||||
ap_put(ap);
|
||||
tty_unthrottle(tty);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -381,7 +381,7 @@ ppp_sync_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
|
|||
}
|
||||
|
||||
/* May sleep, don't call from interrupt level or with interrupts disabled */
|
||||
static void
|
||||
static unsigned int
|
||||
ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
|
||||
char *cflags, int count)
|
||||
{
|
||||
|
@ -389,7 +389,7 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
|
|||
unsigned long flags;
|
||||
|
||||
if (!ap)
|
||||
return;
|
||||
return -ENODEV;
|
||||
spin_lock_irqsave(&ap->recv_lock, flags);
|
||||
ppp_sync_input(ap, buf, cflags, count);
|
||||
spin_unlock_irqrestore(&ap->recv_lock, flags);
|
||||
|
@ -397,6 +397,8 @@ ppp_sync_receive(struct tty_struct *tty, const unsigned char *buf,
|
|||
tasklet_schedule(&ap->tsk);
|
||||
sp_put(ap);
|
||||
tty_unthrottle(tty);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -670,16 +670,17 @@ static void sl_setup(struct net_device *dev)
|
|||
* in parallel
|
||||
*/
|
||||
|
||||
static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
static unsigned int slip_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct slip *sl = tty->disc_data;
|
||||
int bytes = count;
|
||||
|
||||
if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev))
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
/* Read the characters out of the buffer */
|
||||
while (count--) {
|
||||
while (bytes--) {
|
||||
if (fp && *fp++) {
|
||||
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
|
||||
sl->dev->stats.rx_errors++;
|
||||
|
@ -693,6 +694,8 @@ static void slip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
#endif
|
||||
slip_unesc(sl, *cp++);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/************************************
|
||||
|
|
|
@ -517,17 +517,18 @@ static int x25_asy_close(struct net_device *dev)
|
|||
* and sent on to some IP layer for further processing.
|
||||
*/
|
||||
|
||||
static void x25_asy_receive_buf(struct tty_struct *tty,
|
||||
static unsigned int x25_asy_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct x25_asy *sl = tty->disc_data;
|
||||
int bytes = count;
|
||||
|
||||
if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
|
||||
return;
|
||||
|
||||
|
||||
/* Read the characters out of the buffer */
|
||||
while (count--) {
|
||||
while (bytes--) {
|
||||
if (fp && *fp++) {
|
||||
if (!test_and_set_bit(SLF_ERROR, &sl->flags))
|
||||
sl->dev->stats.rx_errors++;
|
||||
|
@ -536,6 +537,8 @@ static void x25_asy_receive_buf(struct tty_struct *tty,
|
|||
}
|
||||
x25_asy_unesc(sl, *cp++);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1621,7 +1621,7 @@ static void __devinit detect_and_report_it87(void)
|
|||
u8 origval, r;
|
||||
if (verbose_probing)
|
||||
printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
|
||||
if (!request_region(0x2e, 2, __func__))
|
||||
if (!request_muxed_region(0x2e, 2, __func__))
|
||||
return;
|
||||
origval = inb(0x2e); /* Save original value */
|
||||
outb(0x87, 0x2e);
|
||||
|
|
|
@ -319,3 +319,34 @@ config N_GSM
|
|||
This line discipline provides support for the GSM MUX protocol and
|
||||
presents the mux as a set of 61 individual tty devices.
|
||||
|
||||
config TRACE_ROUTER
|
||||
tristate "Trace data router for MIPI P1149.7 cJTAG standard"
|
||||
depends on TRACE_SINK
|
||||
default n
|
||||
help
|
||||
The trace router uses the Linux tty line discipline framework to
|
||||
route trace data coming from a tty port (say UART for example) to
|
||||
the trace sink line discipline driver and to another tty port (say
|
||||
USB). This is part of a solution for the MIPI P1149.7, compact JTAG,
|
||||
standard, which is for debugging mobile devices. The PTI driver in
|
||||
drivers/misc/pti.c defines the majority of this MIPI solution.
|
||||
|
||||
You should select this driver if the target kernel is meant for
|
||||
a mobile device containing a modem. Then you will need to select
|
||||
"Trace data sink for MIPI P1149.7 cJTAG standard" line discipline
|
||||
driver.
|
||||
|
||||
config TRACE_SINK
|
||||
tristate "Trace data sink for MIPI P1149.7 cJTAG standard"
|
||||
default n
|
||||
help
|
||||
The trace sink uses the Linux line discipline framework to receive
|
||||
trace data coming from the trace router line discipline driver
|
||||
to a user-defined tty port target, like USB.
|
||||
This is to provide a way to extract modem trace data on
|
||||
devices that do not have a PTI HW module, or just need modem
|
||||
trace data to come out of a different HW output port.
|
||||
This is part of a solution for the P1149.7, compact JTAG, standard.
|
||||
|
||||
If you select this option, you need to select
|
||||
"Trace data router for MIPI P1149.7 cJTAG standard".
|
||||
|
|
|
@ -6,6 +6,8 @@ obj-$(CONFIG_AUDIT) += tty_audit.o
|
|||
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
|
||||
obj-$(CONFIG_N_HDLC) += n_hdlc.o
|
||||
obj-$(CONFIG_N_GSM) += n_gsm.o
|
||||
obj-$(CONFIG_TRACE_ROUTER) += n_tracerouter.o
|
||||
obj-$(CONFIG_TRACE_SINK) += n_tracesink.o
|
||||
obj-$(CONFIG_R3964) += n_r3964.o
|
||||
|
||||
obj-y += vt/
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/amiserial.c
|
||||
*
|
||||
* Serial driver for the amiga builtin port.
|
||||
*
|
||||
* This code was created by taking serial.c version 4.30 from kernel
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
#undef Z_EXT_CHARS_IN_BUFFER
|
||||
|
||||
/*
|
||||
* linux/drivers/char/cyclades.c
|
||||
*
|
||||
* This file contains the driver for the Cyclades async multiport
|
||||
* serial boards.
|
||||
*
|
||||
|
@ -1445,13 +1443,11 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
|
|||
{
|
||||
struct cyclades_card *card;
|
||||
unsigned long flags;
|
||||
int channel;
|
||||
|
||||
if (!(info->port.flags & ASYNC_INITIALIZED))
|
||||
return;
|
||||
|
||||
card = info->card;
|
||||
channel = info->line - card->first_line;
|
||||
if (!cy_is_Z(card)) {
|
||||
spin_lock_irqsave(&card->card_lock, flags);
|
||||
|
||||
|
@ -1476,6 +1472,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
|
|||
spin_unlock_irqrestore(&card->card_lock, flags);
|
||||
} else {
|
||||
#ifdef CY_DEBUG_OPEN
|
||||
int channel = info->line - card->first_line;
|
||||
printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
|
||||
"base_addr %p\n", card, channel, card->base_addr);
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#
|
||||
# drivers/char/pcmcia/ipwireless/Makefile
|
||||
#
|
||||
# Makefile for the IPWireless driver
|
||||
#
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ static int moxa_ioctl(struct tty_struct *tty,
|
|||
tmp.cflag = p->cflag;
|
||||
else
|
||||
tmp.cflag = ttyp->termios->c_cflag;
|
||||
tty_kref_put(tty);
|
||||
tty_kref_put(ttyp);
|
||||
copy:
|
||||
if (copy_to_user(argm, &tmp, sizeof(tmp)))
|
||||
return -EFAULT;
|
||||
|
@ -1129,7 +1129,6 @@ static void moxa_shutdown(struct tty_port *port)
|
|||
struct moxa_port *ch = container_of(port, struct moxa_port, port);
|
||||
MoxaPortDisable(ch);
|
||||
MoxaPortFlushData(ch, 2);
|
||||
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
|
||||
}
|
||||
|
||||
static int moxa_carrier_raised(struct tty_port *port)
|
||||
|
@ -1155,7 +1154,6 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
|
|||
struct moxa_board_conf *brd;
|
||||
struct moxa_port *ch;
|
||||
int port;
|
||||
int retval;
|
||||
|
||||
port = tty->index;
|
||||
if (port == MAX_PORTS) {
|
||||
|
@ -1190,10 +1188,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
|
|||
mutex_unlock(&ch->port.mutex);
|
||||
mutex_unlock(&moxa_openlock);
|
||||
|
||||
retval = tty_port_block_til_ready(&ch->port, tty, filp);
|
||||
if (retval == 0)
|
||||
set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
|
||||
return retval;
|
||||
return tty_port_block_til_ready(&ch->port, tty, filp);
|
||||
}
|
||||
|
||||
static void moxa_close(struct tty_struct *tty, struct file *filp)
|
||||
|
@ -1207,14 +1202,15 @@ static int moxa_write(struct tty_struct *tty,
|
|||
const unsigned char *buf, int count)
|
||||
{
|
||||
struct moxa_port *ch = tty->driver_data;
|
||||
unsigned long flags;
|
||||
int len;
|
||||
|
||||
if (ch == NULL)
|
||||
return 0;
|
||||
|
||||
spin_lock_bh(&moxa_lock);
|
||||
spin_lock_irqsave(&moxa_lock, flags);
|
||||
len = MoxaPortWriteData(tty, buf, count);
|
||||
spin_unlock_bh(&moxa_lock);
|
||||
spin_unlock_irqrestore(&moxa_lock, flags);
|
||||
|
||||
set_bit(LOWWAIT, &ch->statusflags);
|
||||
return len;
|
||||
|
@ -1281,10 +1277,8 @@ static int moxa_tiocmset(struct tty_struct *tty,
|
|||
unsigned int set, unsigned int clear)
|
||||
{
|
||||
struct moxa_port *ch;
|
||||
int port;
|
||||
int dtr, rts;
|
||||
|
||||
port = tty->index;
|
||||
mutex_lock(&moxa_openlock);
|
||||
ch = tty->driver_data;
|
||||
if (!ch) {
|
||||
|
@ -1756,11 +1750,9 @@ static int MoxaPortSetTermio(struct moxa_port *port, struct ktermios *termio,
|
|||
speed_t baud)
|
||||
{
|
||||
void __iomem *ofsAddr;
|
||||
tcflag_t cflag;
|
||||
tcflag_t mode = 0;
|
||||
|
||||
ofsAddr = port->tableAddr;
|
||||
cflag = termio->c_cflag; /* termio->c_cflag */
|
||||
|
||||
mode = termio->c_cflag & CSIZE;
|
||||
if (mode == CS5)
|
||||
|
|
|
@ -526,19 +526,6 @@ static int gsm_stuff_frame(const u8 *input, u8 *output, int len)
|
|||
return olen;
|
||||
}
|
||||
|
||||
static void hex_packet(const unsigned char *p, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i && (i % 16) == 0) {
|
||||
pr_cont("\n");
|
||||
pr_debug("");
|
||||
}
|
||||
pr_cont("%02X ", *p++);
|
||||
}
|
||||
pr_cont("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* gsm_send - send a control frame
|
||||
* @gsm: our GSM mux
|
||||
|
@ -685,10 +672,10 @@ static void gsm_data_kick(struct gsm_mux *gsm)
|
|||
len = msg->len + 2;
|
||||
}
|
||||
|
||||
if (debug & 4) {
|
||||
pr_debug("gsm_data_kick:\n");
|
||||
hex_packet(gsm->txframe, len);
|
||||
}
|
||||
if (debug & 4)
|
||||
print_hex_dump_bytes("gsm_data_kick: ",
|
||||
DUMP_PREFIX_OFFSET,
|
||||
gsm->txframe, len);
|
||||
|
||||
if (gsm->output(gsm, gsm->txframe + skip_sof,
|
||||
len - skip_sof) < 0)
|
||||
|
@ -2095,10 +2082,9 @@ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len)
|
|||
set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
|
||||
return -ENOSPC;
|
||||
}
|
||||
if (debug & 4) {
|
||||
pr_debug("-->%d bytes out\n", len);
|
||||
hex_packet(data, len);
|
||||
}
|
||||
if (debug & 4)
|
||||
print_hex_dump_bytes("gsmld_output: ", DUMP_PREFIX_OFFSET,
|
||||
data, len);
|
||||
gsm->tty->ops->write(gsm->tty, data, len);
|
||||
return len;
|
||||
}
|
||||
|
@ -2142,8 +2128,8 @@ static void gsmld_detach_gsm(struct tty_struct *tty, struct gsm_mux *gsm)
|
|||
gsm->tty = NULL;
|
||||
}
|
||||
|
||||
static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
static unsigned int gsmld_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct gsm_mux *gsm = tty->disc_data;
|
||||
const unsigned char *dp;
|
||||
|
@ -2152,10 +2138,9 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
char buf[64];
|
||||
char flags;
|
||||
|
||||
if (debug & 4) {
|
||||
pr_debug("Inbytes %dd\n", count);
|
||||
hex_packet(cp, count);
|
||||
}
|
||||
if (debug & 4)
|
||||
print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET,
|
||||
cp, count);
|
||||
|
||||
for (i = count, dp = cp, f = fp; i; i--, dp++) {
|
||||
flags = *f++;
|
||||
|
@ -2177,6 +2162,8 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
}
|
||||
/* FASYNC if needed ? */
|
||||
/* If clogged call tty_throttle(tty); */
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -188,8 +188,8 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
|
|||
poll_table *wait);
|
||||
static int n_hdlc_tty_open(struct tty_struct *tty);
|
||||
static void n_hdlc_tty_close(struct tty_struct *tty);
|
||||
static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *cp,
|
||||
char *fp, int count);
|
||||
static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
|
||||
const __u8 *cp, char *fp, int count);
|
||||
static void n_hdlc_tty_wakeup(struct tty_struct *tty);
|
||||
|
||||
#define bset(p,b) ((p)[(b) >> 5] |= (1 << ((b) & 0x1f)))
|
||||
|
@ -509,8 +509,8 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty)
|
|||
* Called by tty low level driver when receive data is available. Data is
|
||||
* interpreted as one HDLC frame.
|
||||
*/
|
||||
static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
|
||||
char *flags, int count)
|
||||
static unsigned int n_hdlc_tty_receive(struct tty_struct *tty,
|
||||
const __u8 *data, char *flags, int count)
|
||||
{
|
||||
register struct n_hdlc *n_hdlc = tty2n_hdlc (tty);
|
||||
register struct n_hdlc_buf *buf;
|
||||
|
@ -521,20 +521,20 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
|
|||
|
||||
/* This can happen if stuff comes in on the backup tty */
|
||||
if (!n_hdlc || tty != n_hdlc->tty)
|
||||
return;
|
||||
return -ENODEV;
|
||||
|
||||
/* verify line is using HDLC discipline */
|
||||
if (n_hdlc->magic != HDLC_MAGIC) {
|
||||
printk("%s(%d) line not using HDLC discipline\n",
|
||||
__FILE__,__LINE__);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( count>maxframe ) {
|
||||
if (debuglevel >= DEBUG_LEVEL_INFO)
|
||||
printk("%s(%d) rx count>maxframesize, data discarded\n",
|
||||
__FILE__,__LINE__);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* get a free HDLC buffer */
|
||||
|
@ -550,7 +550,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
|
|||
if (debuglevel >= DEBUG_LEVEL_INFO)
|
||||
printk("%s(%d) no more rx buffers, data discarded\n",
|
||||
__FILE__,__LINE__);
|
||||
return;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* copy received data to HDLC buffer */
|
||||
|
@ -565,6 +565,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
|
|||
if (n_hdlc->tty->fasync != NULL)
|
||||
kill_fasync (&n_hdlc->tty->fasync, SIGIO, POLL_IN);
|
||||
|
||||
return count;
|
||||
|
||||
} /* end of n_hdlc_tty_receive() */
|
||||
|
||||
/**
|
||||
|
|
|
@ -139,8 +139,8 @@ static int r3964_ioctl(struct tty_struct *tty, struct file *file,
|
|||
static void r3964_set_termios(struct tty_struct *tty, struct ktermios *old);
|
||||
static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
|
||||
struct poll_table_struct *wait);
|
||||
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count);
|
||||
static unsigned int r3964_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count);
|
||||
|
||||
static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
|
||||
.owner = THIS_MODULE,
|
||||
|
@ -1239,8 +1239,8 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
static unsigned int r3964_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct r3964_info *pInfo = tty->disc_data;
|
||||
const unsigned char *p;
|
||||
|
@ -1257,6 +1257,8 @@ static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
243
drivers/tty/n_tracerouter.c
Normal file
243
drivers/tty/n_tracerouter.c
Normal file
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* n_tracerouter.c - Trace data router through tty space
|
||||
*
|
||||
* Copyright (C) Intel 2011
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This trace router uses the Linux line discipline framework to route
|
||||
* trace data coming from a HW Modem to a PTI (Parallel Trace Module) port.
|
||||
* The solution is not specific to a HW modem and this line disciple can
|
||||
* be used to route any stream of data in kernel space.
|
||||
* This is part of a solution for the P1149.7, compact JTAG, standard.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_ldisc.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm-generic/bug.h>
|
||||
#include "n_tracesink.h"
|
||||
|
||||
/*
|
||||
* Other ldisc drivers use 65536 which basically means,
|
||||
* 'I can always accept 64k' and flow control is off.
|
||||
* This number is deemed appropriate for this driver.
|
||||
*/
|
||||
#define RECEIVE_ROOM 65536
|
||||
#define DRIVERNAME "n_tracerouter"
|
||||
|
||||
/*
|
||||
* struct to hold private configuration data for this ldisc.
|
||||
* opencalled is used to hold if this ldisc has been opened.
|
||||
* kref_tty holds the tty reference the ldisc sits on top of.
|
||||
*/
|
||||
struct tracerouter_data {
|
||||
u8 opencalled;
|
||||
struct tty_struct *kref_tty;
|
||||
};
|
||||
static struct tracerouter_data *tr_data;
|
||||
|
||||
/* lock for when tty reference is being used */
|
||||
static DEFINE_MUTEX(routelock);
|
||||
|
||||
/**
|
||||
* n_tracerouter_open() - Called when a tty is opened by a SW entity.
|
||||
* @tty: terminal device to the ldisc.
|
||||
*
|
||||
* Return:
|
||||
* 0 for success.
|
||||
*
|
||||
* Caveats: This should only be opened one time per SW entity.
|
||||
*/
|
||||
static int n_tracerouter_open(struct tty_struct *tty)
|
||||
{
|
||||
int retval = -EEXIST;
|
||||
|
||||
mutex_lock(&routelock);
|
||||
if (tr_data->opencalled == 0) {
|
||||
|
||||
tr_data->kref_tty = tty_kref_get(tty);
|
||||
if (tr_data->kref_tty == NULL) {
|
||||
retval = -EFAULT;
|
||||
} else {
|
||||
tr_data->opencalled = 1;
|
||||
tty->disc_data = tr_data;
|
||||
tty->receive_room = RECEIVE_ROOM;
|
||||
tty_driver_flush_buffer(tty);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&routelock);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracerouter_close() - close connection
|
||||
* @tty: terminal device to the ldisc.
|
||||
*
|
||||
* Called when a software entity wants to close a connection.
|
||||
*/
|
||||
static void n_tracerouter_close(struct tty_struct *tty)
|
||||
{
|
||||
struct tracerouter_data *tptr = tty->disc_data;
|
||||
|
||||
mutex_lock(&routelock);
|
||||
WARN_ON(tptr->kref_tty != tr_data->kref_tty);
|
||||
tty_driver_flush_buffer(tty);
|
||||
tty_kref_put(tr_data->kref_tty);
|
||||
tr_data->kref_tty = NULL;
|
||||
tr_data->opencalled = 0;
|
||||
tty->disc_data = NULL;
|
||||
mutex_unlock(&routelock);
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracerouter_read() - read request from user space
|
||||
* @tty: terminal device passed into the ldisc.
|
||||
* @file: pointer to open file object.
|
||||
* @buf: pointer to the data buffer that gets eventually returned.
|
||||
* @nr: number of bytes of the data buffer that is returned.
|
||||
*
|
||||
* function that allows read() functionality in userspace. By default if this
|
||||
* is not implemented it returns -EIO. This module is functioning like a
|
||||
* router via n_tracerouter_receivebuf(), and there is no real requirement
|
||||
* to implement this function. However, an error return value other than
|
||||
* -EIO should be used just to show that there was an intent not to have
|
||||
* this function implemented. Return value based on read() man pages.
|
||||
*
|
||||
* Return:
|
||||
* -EINVAL
|
||||
*/
|
||||
static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file,
|
||||
unsigned char __user *buf, size_t nr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracerouter_write() - Function that allows write() in userspace.
|
||||
* @tty: terminal device passed into the ldisc.
|
||||
* @file: pointer to open file object.
|
||||
* @buf: pointer to the data buffer that gets eventually returned.
|
||||
* @nr: number of bytes of the data buffer that is returned.
|
||||
*
|
||||
* By default if this is not implemented, it returns -EIO.
|
||||
* This should not be implemented, ever, because
|
||||
* 1. this driver is functioning like a router via
|
||||
* n_tracerouter_receivebuf()
|
||||
* 2. No writes to HW will ever go through this line discpline driver.
|
||||
* However, an error return value other than -EIO should be used
|
||||
* just to show that there was an intent not to have this function
|
||||
* implemented. Return value based on write() man pages.
|
||||
*
|
||||
* Return:
|
||||
* -EINVAL
|
||||
*/
|
||||
static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file,
|
||||
const unsigned char *buf, size_t nr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracerouter_receivebuf() - Routing function for driver.
|
||||
* @tty: terminal device passed into the ldisc. It's assumed
|
||||
* tty will never be NULL.
|
||||
* @cp: buffer, block of characters to be eventually read by
|
||||
* someone, somewhere (user read() call or some kernel function).
|
||||
* @fp: flag buffer.
|
||||
* @count: number of characters (aka, bytes) in cp.
|
||||
*
|
||||
* This function takes the input buffer, cp, and passes it to
|
||||
* an external API function for processing.
|
||||
*/
|
||||
static void n_tracerouter_receivebuf(struct tty_struct *tty,
|
||||
const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
{
|
||||
mutex_lock(&routelock);
|
||||
n_tracesink_datadrain((u8 *) cp, count);
|
||||
mutex_unlock(&routelock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush buffer is not impelemented as the ldisc has no internal buffering
|
||||
* so the tty_driver_flush_buffer() is sufficient for this driver's needs.
|
||||
*/
|
||||
|
||||
static struct tty_ldisc_ops tty_ptirouter_ldisc = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = DRIVERNAME,
|
||||
.open = n_tracerouter_open,
|
||||
.close = n_tracerouter_close,
|
||||
.read = n_tracerouter_read,
|
||||
.write = n_tracerouter_write,
|
||||
.receive_buf = n_tracerouter_receivebuf
|
||||
};
|
||||
|
||||
/**
|
||||
* n_tracerouter_init - module initialisation
|
||||
*
|
||||
* Registers this module as a line discipline driver.
|
||||
*
|
||||
* Return:
|
||||
* 0 for success, any other value error.
|
||||
*/
|
||||
static int __init n_tracerouter_init(void)
|
||||
{
|
||||
int retval;
|
||||
|
||||
tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL);
|
||||
if (tr_data == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
/* Note N_TRACEROUTER is defined in linux/tty.h */
|
||||
retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc);
|
||||
if (retval < 0) {
|
||||
pr_err("%s: Registration failed: %d\n", __func__, retval);
|
||||
kfree(tr_data);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracerouter_exit - module unload
|
||||
*
|
||||
* Removes this module as a line discipline driver.
|
||||
*/
|
||||
static void __exit n_tracerouter_exit(void)
|
||||
{
|
||||
int retval = tty_unregister_ldisc(N_TRACEROUTER);
|
||||
|
||||
if (retval < 0)
|
||||
pr_err("%s: Unregistration failed: %d\n", __func__, retval);
|
||||
else
|
||||
kfree(tr_data);
|
||||
}
|
||||
|
||||
module_init(n_tracerouter_init);
|
||||
module_exit(n_tracerouter_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jay Freyensee");
|
||||
MODULE_ALIAS_LDISC(N_TRACEROUTER);
|
||||
MODULE_DESCRIPTION("Trace router ldisc driver");
|
238
drivers/tty/n_tracesink.c
Normal file
238
drivers/tty/n_tracesink.c
Normal file
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
* n_tracesink.c - Trace data router and sink path through tty space.
|
||||
*
|
||||
* Copyright (C) Intel 2011
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* The trace sink uses the Linux line discipline framework to receive
|
||||
* trace data coming from the PTI source line discipline driver
|
||||
* to a user-desired tty port, like USB.
|
||||
* This is to provide a way to extract modem trace data on
|
||||
* devices that do not have a PTI HW module, or just need modem
|
||||
* trace data to come out of a different HW output port.
|
||||
* This is part of a solution for the P1149.7, compact JTAG, standard.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_ldisc.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm-generic/bug.h>
|
||||
#include "n_tracesink.h"
|
||||
|
||||
/*
|
||||
* Other ldisc drivers use 65536 which basically means,
|
||||
* 'I can always accept 64k' and flow control is off.
|
||||
* This number is deemed appropriate for this driver.
|
||||
*/
|
||||
#define RECEIVE_ROOM 65536
|
||||
#define DRIVERNAME "n_tracesink"
|
||||
|
||||
/*
|
||||
* there is a quirk with this ldisc is he can write data
|
||||
* to a tty from anyone calling his kernel API, which
|
||||
* meets customer requirements in the drivers/misc/pti.c
|
||||
* project. So he needs to know when he can and cannot write when
|
||||
* the API is called. In theory, the API can be called
|
||||
* after an init() but before a successful open() which
|
||||
* would crash the system if tty is not checked.
|
||||
*/
|
||||
static struct tty_struct *this_tty;
|
||||
static DEFINE_MUTEX(writelock);
|
||||
|
||||
/**
|
||||
* n_tracesink_open() - Called when a tty is opened by a SW entity.
|
||||
* @tty: terminal device to the ldisc.
|
||||
*
|
||||
* Return:
|
||||
* 0 for success,
|
||||
* -EFAULT = couldn't get a tty kref n_tracesink will sit
|
||||
* on top of
|
||||
* -EEXIST = open() called successfully once and it cannot
|
||||
* be called again.
|
||||
*
|
||||
* Caveats: open() should only be successful the first time a
|
||||
* SW entity calls it.
|
||||
*/
|
||||
static int n_tracesink_open(struct tty_struct *tty)
|
||||
{
|
||||
int retval = -EEXIST;
|
||||
|
||||
mutex_lock(&writelock);
|
||||
if (this_tty == NULL) {
|
||||
this_tty = tty_kref_get(tty);
|
||||
if (this_tty == NULL) {
|
||||
retval = -EFAULT;
|
||||
} else {
|
||||
tty->disc_data = this_tty;
|
||||
tty_driver_flush_buffer(tty);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&writelock);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracesink_close() - close connection
|
||||
* @tty: terminal device to the ldisc.
|
||||
*
|
||||
* Called when a software entity wants to close a connection.
|
||||
*/
|
||||
static void n_tracesink_close(struct tty_struct *tty)
|
||||
{
|
||||
mutex_lock(&writelock);
|
||||
tty_driver_flush_buffer(tty);
|
||||
tty_kref_put(this_tty);
|
||||
this_tty = NULL;
|
||||
tty->disc_data = NULL;
|
||||
mutex_unlock(&writelock);
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracesink_read() - read request from user space
|
||||
* @tty: terminal device passed into the ldisc.
|
||||
* @file: pointer to open file object.
|
||||
* @buf: pointer to the data buffer that gets eventually returned.
|
||||
* @nr: number of bytes of the data buffer that is returned.
|
||||
*
|
||||
* function that allows read() functionality in userspace. By default if this
|
||||
* is not implemented it returns -EIO. This module is functioning like a
|
||||
* router via n_tracesink_receivebuf(), and there is no real requirement
|
||||
* to implement this function. However, an error return value other than
|
||||
* -EIO should be used just to show that there was an intent not to have
|
||||
* this function implemented. Return value based on read() man pages.
|
||||
*
|
||||
* Return:
|
||||
* -EINVAL
|
||||
*/
|
||||
static ssize_t n_tracesink_read(struct tty_struct *tty, struct file *file,
|
||||
unsigned char __user *buf, size_t nr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracesink_write() - Function that allows write() in userspace.
|
||||
* @tty: terminal device passed into the ldisc.
|
||||
* @file: pointer to open file object.
|
||||
* @buf: pointer to the data buffer that gets eventually returned.
|
||||
* @nr: number of bytes of the data buffer that is returned.
|
||||
*
|
||||
* By default if this is not implemented, it returns -EIO.
|
||||
* This should not be implemented, ever, because
|
||||
* 1. this driver is functioning like a router via
|
||||
* n_tracesink_receivebuf()
|
||||
* 2. No writes to HW will ever go through this line discpline driver.
|
||||
* However, an error return value other than -EIO should be used
|
||||
* just to show that there was an intent not to have this function
|
||||
* implemented. Return value based on write() man pages.
|
||||
*
|
||||
* Return:
|
||||
* -EINVAL
|
||||
*/
|
||||
static ssize_t n_tracesink_write(struct tty_struct *tty, struct file *file,
|
||||
const unsigned char *buf, size_t nr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracesink_datadrain() - Kernel API function used to route
|
||||
* trace debugging data to user-defined
|
||||
* port like USB.
|
||||
*
|
||||
* @buf: Trace debuging data buffer to write to tty target
|
||||
* port. Null value will return with no write occurring.
|
||||
* @count: Size of buf. Value of 0 or a negative number will
|
||||
* return with no write occuring.
|
||||
*
|
||||
* Caveat: If this line discipline does not set the tty it sits
|
||||
* on top of via an open() call, this API function will not
|
||||
* call the tty's write() call because it will have no pointer
|
||||
* to call the write().
|
||||
*/
|
||||
void n_tracesink_datadrain(u8 *buf, int count)
|
||||
{
|
||||
mutex_lock(&writelock);
|
||||
|
||||
if ((buf != NULL) && (count > 0) && (this_tty != NULL))
|
||||
this_tty->ops->write(this_tty, buf, count);
|
||||
|
||||
mutex_unlock(&writelock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(n_tracesink_datadrain);
|
||||
|
||||
/*
|
||||
* Flush buffer is not impelemented as the ldisc has no internal buffering
|
||||
* so the tty_driver_flush_buffer() is sufficient for this driver's needs.
|
||||
*/
|
||||
|
||||
/*
|
||||
* tty_ldisc function operations for this driver.
|
||||
*/
|
||||
static struct tty_ldisc_ops tty_n_tracesink = {
|
||||
.owner = THIS_MODULE,
|
||||
.magic = TTY_LDISC_MAGIC,
|
||||
.name = DRIVERNAME,
|
||||
.open = n_tracesink_open,
|
||||
.close = n_tracesink_close,
|
||||
.read = n_tracesink_read,
|
||||
.write = n_tracesink_write
|
||||
};
|
||||
|
||||
/**
|
||||
* n_tracesink_init- module initialisation
|
||||
*
|
||||
* Registers this module as a line discipline driver.
|
||||
*
|
||||
* Return:
|
||||
* 0 for success, any other value error.
|
||||
*/
|
||||
static int __init n_tracesink_init(void)
|
||||
{
|
||||
/* Note N_TRACESINK is defined in linux/tty.h */
|
||||
int retval = tty_register_ldisc(N_TRACESINK, &tty_n_tracesink);
|
||||
|
||||
if (retval < 0)
|
||||
pr_err("%s: Registration failed: %d\n", __func__, retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tracesink_exit - module unload
|
||||
*
|
||||
* Removes this module as a line discipline driver.
|
||||
*/
|
||||
static void __exit n_tracesink_exit(void)
|
||||
{
|
||||
int retval = tty_unregister_ldisc(N_TRACESINK);
|
||||
|
||||
if (retval < 0)
|
||||
pr_err("%s: Unregistration failed: %d\n", __func__, retval);
|
||||
}
|
||||
|
||||
module_init(n_tracesink_init);
|
||||
module_exit(n_tracesink_exit);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Jay Freyensee");
|
||||
MODULE_ALIAS_LDISC(N_TRACESINK);
|
||||
MODULE_DESCRIPTION("Trace sink ldisc driver");
|
36
drivers/tty/n_tracesink.h
Normal file
36
drivers/tty/n_tracesink.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* n_tracesink.h - Kernel driver API to route trace data in kernel space.
|
||||
*
|
||||
* Copyright (C) Intel 2011
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* The PTI (Parallel Trace Interface) driver directs trace data routed from
|
||||
* various parts in the system out through the Intel Penwell PTI port and
|
||||
* out of the mobile device for analysis with a debugging tool
|
||||
* (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
|
||||
* compact JTAG, standard.
|
||||
*
|
||||
* This header file is used by n_tracerouter to be able to send the
|
||||
* data of it's tty port to the tty port this module sits. This
|
||||
* mechanism can also be used independent of the PTI module.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef N_TRACESINK_H_
|
||||
#define N_TRACESINK_H_
|
||||
|
||||
void n_tracesink_datadrain(u8 *buf, int count);
|
||||
|
||||
#endif
|
|
@ -81,38 +81,6 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x,
|
|||
return put_user(x, ptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* n_tty_set__room - receive space
|
||||
* @tty: terminal
|
||||
*
|
||||
* Called by the driver to find out how much data it is
|
||||
* permitted to feed to the line discipline without any being lost
|
||||
* and thus to manage flow control. Not serialized. Answers for the
|
||||
* "instant".
|
||||
*/
|
||||
|
||||
static void n_tty_set_room(struct tty_struct *tty)
|
||||
{
|
||||
/* tty->read_cnt is not read locked ? */
|
||||
int left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
|
||||
int old_left;
|
||||
|
||||
/*
|
||||
* If we are doing input canonicalization, and there are no
|
||||
* pending newlines, let characters through without limit, so
|
||||
* that erase characters will be handled. Other excess
|
||||
* characters will be beeped.
|
||||
*/
|
||||
if (left <= 0)
|
||||
left = tty->icanon && !tty->canon_data;
|
||||
old_left = tty->receive_room;
|
||||
tty->receive_room = left;
|
||||
|
||||
/* Did this open up the receive buffer? We may need to flip */
|
||||
if (left && !old_left)
|
||||
schedule_work(&tty->buf.work);
|
||||
}
|
||||
|
||||
static void put_tty_queue_nolock(unsigned char c, struct tty_struct *tty)
|
||||
{
|
||||
if (tty->read_cnt < N_TTY_BUF_SIZE) {
|
||||
|
@ -184,7 +152,6 @@ static void reset_buffer_flags(struct tty_struct *tty)
|
|||
|
||||
tty->canon_head = tty->canon_data = tty->erasing = 0;
|
||||
memset(&tty->read_flags, 0, sizeof tty->read_flags);
|
||||
n_tty_set_room(tty);
|
||||
check_unthrottle(tty);
|
||||
}
|
||||
|
||||
|
@ -1360,17 +1327,19 @@ static void n_tty_write_wakeup(struct tty_struct *tty)
|
|||
* calls one at a time and in order (or using flush_to_ldisc)
|
||||
*/
|
||||
|
||||
static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
||||
char *fp, int count)
|
||||
static unsigned int n_tty_receive_buf(struct tty_struct *tty,
|
||||
const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
const unsigned char *p;
|
||||
char *f, flags = TTY_NORMAL;
|
||||
int i;
|
||||
char buf[64];
|
||||
unsigned long cpuflags;
|
||||
int left;
|
||||
int ret = 0;
|
||||
|
||||
if (!tty->read_buf)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (tty->real_raw) {
|
||||
spin_lock_irqsave(&tty->read_lock, cpuflags);
|
||||
|
@ -1380,6 +1349,7 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
memcpy(tty->read_buf + tty->read_head, cp, i);
|
||||
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
|
||||
tty->read_cnt += i;
|
||||
ret += i;
|
||||
cp += i;
|
||||
count -= i;
|
||||
|
||||
|
@ -1389,8 +1359,10 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
memcpy(tty->read_buf + tty->read_head, cp, i);
|
||||
tty->read_head = (tty->read_head + i) & (N_TTY_BUF_SIZE-1);
|
||||
tty->read_cnt += i;
|
||||
ret += i;
|
||||
spin_unlock_irqrestore(&tty->read_lock, cpuflags);
|
||||
} else {
|
||||
ret = count;
|
||||
for (i = count, p = cp, f = fp; i; i--, p++) {
|
||||
if (f)
|
||||
flags = *f++;
|
||||
|
@ -1418,8 +1390,6 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
tty->ops->flush_chars(tty);
|
||||
}
|
||||
|
||||
n_tty_set_room(tty);
|
||||
|
||||
if ((!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) ||
|
||||
L_EXTPROC(tty)) {
|
||||
kill_fasync(&tty->fasync, SIGIO, POLL_IN);
|
||||
|
@ -1432,8 +1402,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
|
|||
* mode. We don't want to throttle the driver if we're in
|
||||
* canonical mode and don't have a newline yet!
|
||||
*/
|
||||
if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
|
||||
left = N_TTY_BUF_SIZE - tty->read_cnt - 1;
|
||||
|
||||
if (left < TTY_THRESHOLD_THROTTLE)
|
||||
tty_throttle(tty);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int is_ignored(int sig)
|
||||
|
@ -1477,7 +1451,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|||
if (test_bit(TTY_HW_COOK_IN, &tty->flags)) {
|
||||
tty->raw = 1;
|
||||
tty->real_raw = 1;
|
||||
n_tty_set_room(tty);
|
||||
return;
|
||||
}
|
||||
if (I_ISTRIP(tty) || I_IUCLC(tty) || I_IGNCR(tty) ||
|
||||
|
@ -1530,7 +1503,6 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
|
|||
else
|
||||
tty->real_raw = 0;
|
||||
}
|
||||
n_tty_set_room(tty);
|
||||
/* The termios change make the tty ready for I/O */
|
||||
wake_up_interruptible(&tty->write_wait);
|
||||
wake_up_interruptible(&tty->read_wait);
|
||||
|
@ -1812,8 +1784,6 @@ do_it_again:
|
|||
retval = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
/* FIXME: does n_tty_set_room need locking ? */
|
||||
n_tty_set_room(tty);
|
||||
timeout = schedule_timeout(timeout);
|
||||
continue;
|
||||
}
|
||||
|
@ -1885,10 +1855,8 @@ do_it_again:
|
|||
* longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode,
|
||||
* we won't get any more characters.
|
||||
*/
|
||||
if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) {
|
||||
n_tty_set_room(tty);
|
||||
if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE)
|
||||
check_unthrottle(tty);
|
||||
}
|
||||
|
||||
if (b - buf >= minimum)
|
||||
break;
|
||||
|
@ -1910,7 +1878,6 @@ do_it_again:
|
|||
} else if (test_and_clear_bit(TTY_PUSH, &tty->flags))
|
||||
goto do_it_again;
|
||||
|
||||
n_tty_set_room(tty);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -364,8 +364,6 @@ struct port {
|
|||
u8 toggle_ul;
|
||||
u16 token_dl;
|
||||
|
||||
/* mutex to ensure one access patch to this port */
|
||||
struct mutex tty_sem;
|
||||
wait_queue_head_t tty_wait;
|
||||
struct async_icount tty_icount;
|
||||
|
||||
|
@ -1431,8 +1429,8 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
|||
}
|
||||
|
||||
for (i = PORT_MDM; i < MAX_PORT; i++) {
|
||||
if (kfifo_alloc(&dc->port[i].fifo_ul,
|
||||
FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) {
|
||||
if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_UL,
|
||||
GFP_KERNEL)) {
|
||||
dev_err(&pdev->dev,
|
||||
"Could not allocate kfifo buffer\n");
|
||||
ret = -ENOMEM;
|
||||
|
@ -1474,7 +1472,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev,
|
|||
struct device *tty_dev;
|
||||
struct port *port = &dc->port[i];
|
||||
port->dc = dc;
|
||||
mutex_init(&port->tty_sem);
|
||||
tty_port_init(&port->port);
|
||||
port->port.ops = &noz_tty_port_ops;
|
||||
tty_dev = tty_register_device(ntty_driver, dc->index_start + i,
|
||||
|
@ -1688,13 +1685,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
|
|||
if (!dc || !port)
|
||||
return -ENODEV;
|
||||
|
||||
mutex_lock(&port->tty_sem);
|
||||
|
||||
if (unlikely(!port->port.count)) {
|
||||
DBG1(" ");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
|
||||
|
||||
/* notify card */
|
||||
|
@ -1719,7 +1709,6 @@ static int ntty_write(struct tty_struct *tty, const unsigned char *buffer,
|
|||
spin_unlock_irqrestore(&dc->spin_mutex, flags);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&port->tty_sem);
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
@ -1738,12 +1727,9 @@ static int ntty_write_room(struct tty_struct *tty)
|
|||
int room = 4096;
|
||||
const struct nozomi *dc = get_dc_by_tty(tty);
|
||||
|
||||
if (dc) {
|
||||
mutex_lock(&port->tty_sem);
|
||||
if (port->port.count)
|
||||
room = kfifo_avail(&port->fifo_ul);
|
||||
mutex_unlock(&port->tty_sem);
|
||||
}
|
||||
if (dc)
|
||||
room = kfifo_avail(&port->fifo_ul);
|
||||
|
||||
return room;
|
||||
}
|
||||
|
||||
|
@ -1889,11 +1875,6 @@ static s32 ntty_chars_in_buffer(struct tty_struct *tty)
|
|||
goto exit_in_buffer;
|
||||
}
|
||||
|
||||
if (unlikely(!port->port.count)) {
|
||||
dev_err(&dc->pdev->dev, "No tty open?\n");
|
||||
goto exit_in_buffer;
|
||||
}
|
||||
|
||||
rval = kfifo_len(&port->fifo_ul);
|
||||
|
||||
exit_in_buffer:
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/pty.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*
|
||||
* Added support for a Unix98-style ptmx device.
|
||||
|
@ -295,8 +293,8 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
return -ENOMEM;
|
||||
if (!try_module_get(driver->other->owner)) {
|
||||
/* This cannot in fact currently happen */
|
||||
free_tty_struct(o_tty);
|
||||
return -ENOMEM;
|
||||
retval = -ENOMEM;
|
||||
goto err_free_tty;
|
||||
}
|
||||
initialize_tty_struct(o_tty, driver->other, idx);
|
||||
|
||||
|
@ -304,13 +302,11 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
the easy way .. */
|
||||
retval = tty_init_termios(tty);
|
||||
if (retval)
|
||||
goto free_mem_out;
|
||||
goto err_deinit_tty;
|
||||
|
||||
retval = tty_init_termios(o_tty);
|
||||
if (retval) {
|
||||
tty_free_termios(tty);
|
||||
goto free_mem_out;
|
||||
}
|
||||
if (retval)
|
||||
goto err_free_termios;
|
||||
|
||||
/*
|
||||
* Everything allocated ... set up the o_tty structure.
|
||||
|
@ -327,10 +323,14 @@ static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
tty->count++;
|
||||
driver->ttys[idx] = tty;
|
||||
return 0;
|
||||
free_mem_out:
|
||||
err_free_termios:
|
||||
tty_free_termios(tty);
|
||||
err_deinit_tty:
|
||||
deinitialize_tty_struct(o_tty);
|
||||
module_put(o_tty->driver->owner);
|
||||
err_free_tty:
|
||||
free_tty_struct(o_tty);
|
||||
return -ENOMEM;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int pty_bsd_ioctl(struct tty_struct *tty,
|
||||
|
@ -559,20 +559,19 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
return -ENOMEM;
|
||||
if (!try_module_get(driver->other->owner)) {
|
||||
/* This cannot in fact currently happen */
|
||||
free_tty_struct(o_tty);
|
||||
return -ENOMEM;
|
||||
goto err_free_tty;
|
||||
}
|
||||
initialize_tty_struct(o_tty, driver->other, idx);
|
||||
|
||||
tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
|
||||
if (tty->termios == NULL)
|
||||
goto free_mem_out;
|
||||
goto err_free_mem;
|
||||
*tty->termios = driver->init_termios;
|
||||
tty->termios_locked = tty->termios + 1;
|
||||
|
||||
o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
|
||||
if (o_tty->termios == NULL)
|
||||
goto free_mem_out;
|
||||
goto err_free_mem;
|
||||
*o_tty->termios = driver->other->init_termios;
|
||||
o_tty->termios_locked = o_tty->termios + 1;
|
||||
|
||||
|
@ -591,11 +590,13 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
|
|||
tty->count++;
|
||||
pty_count++;
|
||||
return 0;
|
||||
free_mem_out:
|
||||
err_free_mem:
|
||||
deinitialize_tty_struct(o_tty);
|
||||
kfree(o_tty->termios);
|
||||
module_put(o_tty->driver->owner);
|
||||
free_tty_struct(o_tty);
|
||||
kfree(tty->termios);
|
||||
module_put(o_tty->driver->owner);
|
||||
err_free_tty:
|
||||
free_tty_struct(o_tty);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
@ -1380,7 +1380,6 @@ static void rp_send_xchar(struct tty_struct *tty, char ch)
|
|||
static void rp_throttle(struct tty_struct *tty)
|
||||
{
|
||||
struct r_port *info = tty->driver_data;
|
||||
CHANNEL_t *cp;
|
||||
|
||||
#ifdef ROCKET_DEBUG_THROTTLE
|
||||
printk(KERN_INFO "throttle %s: %d....\n", tty->name,
|
||||
|
@ -1390,7 +1389,6 @@ static void rp_throttle(struct tty_struct *tty)
|
|||
if (rocket_paranoia_check(info, "rp_throttle"))
|
||||
return;
|
||||
|
||||
cp = &info->channel;
|
||||
if (I_IXOFF(tty))
|
||||
rp_send_xchar(tty, STOP_CHAR(tty));
|
||||
|
||||
|
@ -1400,7 +1398,6 @@ static void rp_throttle(struct tty_struct *tty)
|
|||
static void rp_unthrottle(struct tty_struct *tty)
|
||||
{
|
||||
struct r_port *info = tty->driver_data;
|
||||
CHANNEL_t *cp;
|
||||
#ifdef ROCKET_DEBUG_THROTTLE
|
||||
printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
|
||||
tty->ldisc.chars_in_buffer(tty));
|
||||
|
@ -1409,7 +1406,6 @@ static void rp_unthrottle(struct tty_struct *tty)
|
|||
if (rocket_paranoia_check(info, "rp_throttle"))
|
||||
return;
|
||||
|
||||
cp = &info->channel;
|
||||
if (I_IXOFF(tty))
|
||||
rp_send_xchar(tty, START_CHAR(tty));
|
||||
|
||||
|
@ -1722,13 +1718,10 @@ static int rp_write_room(struct tty_struct *tty)
|
|||
static int rp_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
struct r_port *info = tty->driver_data;
|
||||
CHANNEL_t *cp;
|
||||
|
||||
if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
|
||||
return 0;
|
||||
|
||||
cp = &info->channel;
|
||||
|
||||
#ifdef ROCKET_DEBUG_WRITE
|
||||
printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
|
||||
#endif
|
||||
|
@ -1779,7 +1772,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
{
|
||||
int num_aiops, aiop, max_num_aiops, num_chan, chan;
|
||||
unsigned int aiopio[MAX_AIOPS_PER_BOARD];
|
||||
char *str, *board_type;
|
||||
CONTROLLER_t *ctlp;
|
||||
|
||||
int fast_clock = 0;
|
||||
|
@ -1800,7 +1792,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
/* Depending on the model, set up some config variables */
|
||||
switch (dev->device) {
|
||||
case PCI_DEVICE_ID_RP4QUAD:
|
||||
str = "Quadcable";
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 4;
|
||||
rocketModel[i].model = MODEL_RP4QUAD;
|
||||
|
@ -1808,42 +1799,36 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rocketModel[i].numPorts = 4;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP8OCTA:
|
||||
str = "Octacable";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_RP8OCTA;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
|
||||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_URP8OCTA:
|
||||
str = "Octacable";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_UPCI_RP8OCTA;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
|
||||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP8INTF:
|
||||
str = "8";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_RP8INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
|
||||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_URP8INTF:
|
||||
str = "8";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_UPCI_RP8INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
|
||||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP8J:
|
||||
str = "8J";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_RP8J;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
|
||||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP4J:
|
||||
str = "4J";
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 4;
|
||||
rocketModel[i].model = MODEL_RP4J;
|
||||
|
@ -1851,56 +1836,48 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rocketModel[i].numPorts = 4;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP8SNI:
|
||||
str = "8 (DB78 Custom)";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_RP8SNI;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
|
||||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP16SNI:
|
||||
str = "16 (DB78 Custom)";
|
||||
max_num_aiops = 2;
|
||||
rocketModel[i].model = MODEL_RP16SNI;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
|
||||
rocketModel[i].numPorts = 16;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP16INTF:
|
||||
str = "16";
|
||||
max_num_aiops = 2;
|
||||
rocketModel[i].model = MODEL_RP16INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
|
||||
rocketModel[i].numPorts = 16;
|
||||
break;
|
||||
case PCI_DEVICE_ID_URP16INTF:
|
||||
str = "16";
|
||||
max_num_aiops = 2;
|
||||
rocketModel[i].model = MODEL_UPCI_RP16INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
|
||||
rocketModel[i].numPorts = 16;
|
||||
break;
|
||||
case PCI_DEVICE_ID_CRP16INTF:
|
||||
str = "16";
|
||||
max_num_aiops = 2;
|
||||
rocketModel[i].model = MODEL_CPCI_RP16INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
|
||||
rocketModel[i].numPorts = 16;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP32INTF:
|
||||
str = "32";
|
||||
max_num_aiops = 4;
|
||||
rocketModel[i].model = MODEL_RP32INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
|
||||
rocketModel[i].numPorts = 32;
|
||||
break;
|
||||
case PCI_DEVICE_ID_URP32INTF:
|
||||
str = "32";
|
||||
max_num_aiops = 4;
|
||||
rocketModel[i].model = MODEL_UPCI_RP32INTF;
|
||||
strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
|
||||
rocketModel[i].numPorts = 32;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RPP4:
|
||||
str = "Plus Quadcable";
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 4;
|
||||
altChanRingIndicator++;
|
||||
|
@ -1910,7 +1887,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rocketModel[i].numPorts = 4;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RPP8:
|
||||
str = "Plus Octacable";
|
||||
max_num_aiops = 2;
|
||||
ports_per_aiop = 4;
|
||||
altChanRingIndicator++;
|
||||
|
@ -1920,7 +1896,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rocketModel[i].numPorts = 8;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP2_232:
|
||||
str = "Plus 2 (RS-232)";
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 2;
|
||||
altChanRingIndicator++;
|
||||
|
@ -1930,7 +1905,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rocketModel[i].numPorts = 2;
|
||||
break;
|
||||
case PCI_DEVICE_ID_RP2_422:
|
||||
str = "Plus 2 (RS-422)";
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 2;
|
||||
altChanRingIndicator++;
|
||||
|
@ -1943,7 +1917,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 6;
|
||||
str = "6-port";
|
||||
|
||||
/* If revision is 1, the rocketmodem flash must be loaded.
|
||||
* If it is 2 it is a "socketed" version. */
|
||||
|
@ -1961,7 +1934,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
case PCI_DEVICE_ID_RP4M:
|
||||
max_num_aiops = 1;
|
||||
ports_per_aiop = 4;
|
||||
str = "4-port";
|
||||
if (dev->revision == 1) {
|
||||
rcktpt_type[i] = ROCKET_TYPE_MODEMII;
|
||||
rocketModel[i].loadrm2 = 1;
|
||||
|
@ -1974,7 +1946,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rocketModel[i].numPorts = 4;
|
||||
break;
|
||||
default:
|
||||
str = "(unknown/unsupported)";
|
||||
max_num_aiops = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -2000,14 +1971,12 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
if (!
|
||||
(sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
|
||||
PCI_GPIO_CTRL_8PORT)) {
|
||||
str = "Quadcable";
|
||||
ports_per_aiop = 4;
|
||||
rocketModel[i].numPorts = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PCI_DEVICE_ID_UPCI_RM3_8PORT:
|
||||
str = "8 ports";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
|
||||
strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
|
||||
|
@ -2018,7 +1987,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
|
||||
break;
|
||||
case PCI_DEVICE_ID_UPCI_RM3_4PORT:
|
||||
str = "4 ports";
|
||||
max_num_aiops = 1;
|
||||
rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
|
||||
strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
|
||||
|
@ -2032,21 +2000,6 @@ static __init int register_PCI(int i, struct pci_dev *dev)
|
|||
break;
|
||||
}
|
||||
|
||||
switch (rcktpt_type[i]) {
|
||||
case ROCKET_TYPE_MODEM:
|
||||
board_type = "RocketModem";
|
||||
break;
|
||||
case ROCKET_TYPE_MODEMII:
|
||||
board_type = "RocketModem II";
|
||||
break;
|
||||
case ROCKET_TYPE_MODEMIII:
|
||||
board_type = "RocketModem III";
|
||||
break;
|
||||
default:
|
||||
board_type = "RocketPort";
|
||||
break;
|
||||
}
|
||||
|
||||
if (fast_clock) {
|
||||
sClockPrescale = 0x12; /* mod 2 (divide by 3) */
|
||||
rp_baud_base[i] = 921600;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/21285.c
|
||||
*
|
||||
* Driver for the serial port on the 21285 StrongArm-110 core logic chip.
|
||||
*
|
||||
* Based on drivers/char/serial.c
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/8250.c
|
||||
*
|
||||
* Driver for 8250/16550-type serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
@ -273,7 +271,7 @@ static const struct serial8250_config uart_config[] = {
|
|||
.fifo_size = 32,
|
||||
.tx_loadsz = 32,
|
||||
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
|
||||
.flags = UART_CAP_FIFO | UART_CAP_UUE,
|
||||
.flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
|
||||
},
|
||||
[PORT_RM9000] = {
|
||||
.name = "RM9000",
|
||||
|
@ -303,6 +301,14 @@ static const struct serial8250_config uart_config[] = {
|
|||
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
|
||||
.flags = UART_CAP_FIFO | UART_CAP_AFE,
|
||||
},
|
||||
[PORT_TEGRA] = {
|
||||
.name = "Tegra",
|
||||
.fifo_size = 32,
|
||||
.tx_loadsz = 8,
|
||||
.fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
|
||||
UART_FCR_T_TRIG_01,
|
||||
.flags = UART_CAP_FIFO | UART_CAP_RTOIE,
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_MIPS_ALCHEMY)
|
||||
|
@ -1427,6 +1433,27 @@ static void serial8250_enable_ms(struct uart_port *port)
|
|||
serial_out(up, UART_IER, up->ier);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the Tegra rx fifo after a break
|
||||
*
|
||||
* FIXME: This needs to become a port specific callback once we have a
|
||||
* framework for this
|
||||
*/
|
||||
static void clear_rx_fifo(struct uart_8250_port *up)
|
||||
{
|
||||
unsigned int status, tmout = 10000;
|
||||
do {
|
||||
status = serial_in(up, UART_LSR);
|
||||
if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
|
||||
status = serial_in(up, UART_RX);
|
||||
else
|
||||
break;
|
||||
if (--tmout == 0)
|
||||
break;
|
||||
udelay(1);
|
||||
} while (1);
|
||||
}
|
||||
|
||||
static void
|
||||
receive_chars(struct uart_8250_port *up, unsigned int *status)
|
||||
{
|
||||
|
@ -1461,6 +1488,13 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
|
|||
if (lsr & UART_LSR_BI) {
|
||||
lsr &= ~(UART_LSR_FE | UART_LSR_PE);
|
||||
up->port.icount.brk++;
|
||||
/*
|
||||
* If tegra port then clear the rx fifo to
|
||||
* accept another break/character.
|
||||
*/
|
||||
if (up->port.type == PORT_TEGRA)
|
||||
clear_rx_fifo(up);
|
||||
|
||||
/*
|
||||
* We do the SysRQ and SAK checking
|
||||
* here because otherwise the break
|
||||
|
@ -2405,7 +2439,9 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
UART_ENABLE_MS(&up->port, termios->c_cflag))
|
||||
up->ier |= UART_IER_MSI;
|
||||
if (up->capabilities & UART_CAP_UUE)
|
||||
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
|
||||
up->ier |= UART_IER_UUE;
|
||||
if (up->capabilities & UART_CAP_RTOIE)
|
||||
up->ier |= UART_IER_RTOIE;
|
||||
|
||||
serial_out(up, UART_IER, up->ier);
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/8250.h
|
||||
*
|
||||
* Driver for 8250/16550-type serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
@ -44,6 +42,7 @@ struct serial8250_config {
|
|||
#define UART_CAP_SLEEP (1 << 10) /* UART has IER sleep */
|
||||
#define UART_CAP_AFE (1 << 11) /* MCR-based hw flow control */
|
||||
#define UART_CAP_UUE (1 << 12) /* UART needs IER bit 6 set (Xscale) */
|
||||
#define UART_CAP_RTOIE (1 << 13) /* UART needs IER bit 4 set (Xscale, Tegra) */
|
||||
|
||||
#define UART_BUG_QUOT (1 << 0) /* UART has buggy quot LSB */
|
||||
#define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/8250_accent.c
|
||||
*
|
||||
* Copyright (C) 2005 Russell King.
|
||||
* Data taken from include/asm-i386/serial.h
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/8250_boca.c
|
||||
*
|
||||
* Copyright (C) 2005 Russell King.
|
||||
* Data taken from include/asm-i386/serial.h
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/8250_exar.c
|
||||
*
|
||||
* Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
|
||||
* Based on 8250_boca.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/8250_fourport.c
|
||||
*
|
||||
* Copyright (C) 2005 Russell King.
|
||||
* Data taken from include/asm-i386/serial.h
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/8250_hub6.c
|
||||
*
|
||||
* Copyright (C) 2005 Russell King.
|
||||
* Data taken from include/asm-i386/serial.h
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/8250_mca.c
|
||||
*
|
||||
* Copyright (C) 2005 Russell King.
|
||||
* Data taken from include/asm-i386/serial.h
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/8250_pci.c
|
||||
*
|
||||
* Probe module for 8250/16550-type PCI serial ports.
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
@ -973,6 +971,14 @@ ce4100_serial_setup(struct serial_private *priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
pci_omegapci_setup(struct serial_private *priv,
|
||||
struct pciserial_board *board,
|
||||
struct uart_port *port, int idx)
|
||||
{
|
||||
return setup_port(priv, port, 2, idx * 8, 0);
|
||||
}
|
||||
|
||||
static int skip_tx_en_setup(struct serial_private *priv,
|
||||
const struct pciserial_board *board,
|
||||
struct uart_port *port, int idx)
|
||||
|
@ -1012,6 +1018,8 @@ static int skip_tx_en_setup(struct serial_private *priv,
|
|||
#define PCI_DEVICE_ID_TITAN_200EI 0xA016
|
||||
#define PCI_DEVICE_ID_TITAN_200EISI 0xA017
|
||||
#define PCI_DEVICE_ID_OXSEMI_16PCI958 0x9538
|
||||
#define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6
|
||||
#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
|
||||
|
||||
/* Unknown vendors/cards - this should not be in linux/pci_ids.h */
|
||||
#define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584
|
||||
|
@ -1412,7 +1420,7 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
|||
.setup = pci_default_setup,
|
||||
},
|
||||
/*
|
||||
* For Oxford Semiconductor and Mainpine
|
||||
* For Oxford Semiconductor Tornado based devices
|
||||
*/
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_OXSEMI,
|
||||
|
@ -1430,6 +1438,24 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
|
|||
.init = pci_oxsemi_tornado_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_DIGI,
|
||||
.device = PCIE_DEVICE_ID_NEO_2_OX_IBM,
|
||||
.subvendor = PCI_SUBVENDOR_ID_IBM,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.init = pci_oxsemi_tornado_init,
|
||||
.setup = pci_default_setup,
|
||||
},
|
||||
/*
|
||||
* Cronyx Omega PCI (PLX-chip based)
|
||||
*/
|
||||
{
|
||||
.vendor = PCI_VENDOR_ID_PLX,
|
||||
.device = PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
|
||||
.subvendor = PCI_ANY_ID,
|
||||
.subdevice = PCI_ANY_ID,
|
||||
.setup = pci_omegapci_setup,
|
||||
},
|
||||
/*
|
||||
* Default "match everything" terminator entry
|
||||
*/
|
||||
|
@ -1617,6 +1643,7 @@ enum pci_board_num_t {
|
|||
pbn_ADDIDATA_PCIe_4_3906250,
|
||||
pbn_ADDIDATA_PCIe_8_3906250,
|
||||
pbn_ce4100_1_115200,
|
||||
pbn_omegapci,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2312,6 +2339,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
|
|||
.base_baud = 921600,
|
||||
.reg_shift = 2,
|
||||
},
|
||||
[pbn_omegapci] = {
|
||||
.flags = FL_BASE0,
|
||||
.num_ports = 8,
|
||||
.base_baud = 115200,
|
||||
.uart_offset = 0x200,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct pci_device_id softmodem_blacklist[] = {
|
||||
|
@ -3075,6 +3108,14 @@ static struct pci_device_id serial_pci_tbl[] = {
|
|||
{ PCI_VENDOR_ID_MAINPINE, 0x4000, /* IQ Express 8 Port V.34 Super-G3 Fax */
|
||||
PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
|
||||
pbn_oxsemi_8_4000000 },
|
||||
|
||||
/*
|
||||
* Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado
|
||||
*/
|
||||
{ PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM,
|
||||
PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0,
|
||||
pbn_oxsemi_2_4000000 },
|
||||
|
||||
/*
|
||||
* SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
|
||||
* from skokodyn@yahoo.com
|
||||
|
@ -3801,6 +3842,12 @@ static struct pci_device_id serial_pci_tbl[] = {
|
|||
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
pbn_ce4100_1_115200 },
|
||||
|
||||
/*
|
||||
* Cronyx Omega PCI
|
||||
*/
|
||||
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
|
||||
PCI_ANY_ID, PCI_ANY_ID, 0, 0,
|
||||
pbn_omegapci },
|
||||
|
||||
/*
|
||||
* These entries match devices with class COMMUNICATION_SERIAL,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/8250_pnp.c
|
||||
*
|
||||
* Probe module for 8250/16550-type ISAPNP serial ports.
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
|
|
@ -537,7 +537,7 @@ config SERIAL_S3C6400
|
|||
|
||||
config SERIAL_S5PV210
|
||||
tristate "Samsung S5PV210 Serial port support"
|
||||
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_EXYNOS4210)
|
||||
depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210)
|
||||
select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210)
|
||||
default y
|
||||
help
|
||||
|
@ -1585,7 +1585,7 @@ config SERIAL_IFX6X60
|
|||
Support for the IFX6x60 modem devices on Intel MID platforms.
|
||||
|
||||
config SERIAL_PCH_UART
|
||||
tristate "Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH"
|
||||
tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
|
||||
depends on PCI
|
||||
select SERIAL_CORE
|
||||
help
|
||||
|
@ -1593,10 +1593,12 @@ config SERIAL_PCH_UART
|
|||
which is an IOH(Input/Output Hub) for x86 embedded processor.
|
||||
Enabling PCH_DMA, this PCH UART works as DMA mode.
|
||||
|
||||
This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/
|
||||
Output Hub) which is for IVI(In-Vehicle Infotainment) use.
|
||||
ML7213 is companion chip for Intel Atom E6xx series.
|
||||
ML7213 is completely compatible for Intel EG20T PCH.
|
||||
This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
|
||||
Output Hub), ML7213 and ML7223.
|
||||
ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
|
||||
for MP(Media Phone) use.
|
||||
ML7213/ML7223 is companion chip for Intel Atom E6xx series.
|
||||
ML7213/ML7223 is completely compatible for Intel EG20T PCH.
|
||||
|
||||
config SERIAL_MSM_SMD
|
||||
bool "Enable tty device interface for some SMD ports"
|
||||
|
@ -1620,4 +1622,17 @@ config SERIAL_MXS_AUART_CONSOLE
|
|||
help
|
||||
Enable a MXS AUART port to be the system console.
|
||||
|
||||
config SERIAL_XILINX_PS_UART
|
||||
tristate "Xilinx PS UART support"
|
||||
select SERIAL_CORE
|
||||
help
|
||||
This driver supports the Xilinx PS UART port.
|
||||
|
||||
config SERIAL_XILINX_PS_UART_CONSOLE
|
||||
bool "Xilinx PS UART console support"
|
||||
depends on SERIAL_XILINX_PS_UART=y
|
||||
select SERIAL_CORE_CONSOLE
|
||||
help
|
||||
Enable a Xilinx PS UART port to be the system console.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -95,3 +95,4 @@ obj-$(CONFIG_SERIAL_PCH_UART) += pch_uart.o
|
|||
obj-$(CONFIG_SERIAL_MSM_SMD) += msm_smd_tty.o
|
||||
obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
|
||||
obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
|
||||
obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
|
||||
|
|
|
@ -540,11 +540,14 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
|
|||
int i = pdev->id;
|
||||
int ret;
|
||||
|
||||
/* -1 emphasizes that the platform must have one port, no .N suffix */
|
||||
if (i == -1)
|
||||
i = 0;
|
||||
/* if id is -1 scan for a free id and use that one */
|
||||
if (i == -1) {
|
||||
for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++)
|
||||
if (altera_uart_ports[i].port.mapbase == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
|
||||
if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
|
||||
return -EINVAL;
|
||||
|
||||
port = &altera_uart_ports[i].port;
|
||||
|
@ -587,6 +590,8 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
|
|||
port->ops = &altera_uart_ops;
|
||||
port->flags = UPF_BOOT_AUTOCONF;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, port);
|
||||
|
||||
uart_add_one_port(&altera_uart_driver, port);
|
||||
|
||||
return 0;
|
||||
|
@ -594,14 +599,13 @@ static int __devinit altera_uart_probe(struct platform_device *pdev)
|
|||
|
||||
static int __devexit altera_uart_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct uart_port *port;
|
||||
int i = pdev->id;
|
||||
struct uart_port *port = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
if (i == -1)
|
||||
i = 0;
|
||||
|
||||
port = &altera_uart_ports[i].port;
|
||||
uart_remove_one_port(&altera_uart_driver, port);
|
||||
if (port) {
|
||||
uart_remove_one_port(&altera_uart_driver, port);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
port->mapbase = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/amba.c
|
||||
*
|
||||
* Driver for AMBA serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/amba.c
|
||||
*
|
||||
* Driver for AMBA serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/atmel_serial.c
|
||||
*
|
||||
* Driver for Atmel AT91 / AT32 Serial ports
|
||||
* Copyright (C) 2003 Rick Bronson
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/clps711x.c
|
||||
*
|
||||
* Driver for CLPS711x serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/cpm_uart.h
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports
|
||||
*
|
||||
* Copyright (C) 2004 Freescale Semiconductor, Inc.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/cpm_uart.c
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports; core driver
|
||||
*
|
||||
* Based on arch/ppc/cpm2_io/uart.c by Dan Malek
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/cpm_uart.c
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports; CPM1 definitions
|
||||
*
|
||||
* Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports
|
||||
*
|
||||
* definitions for cpm1
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/cpm_uart_cpm2.c
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
|
||||
*
|
||||
* Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
|
||||
*
|
||||
* Driver for CPM (SCC/SMC) serial ports
|
||||
*
|
||||
* definitions for cpm2
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
#include <linux/tty.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/timer.h>
|
||||
|
@ -56,7 +55,6 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/spi/ifx_modem.h>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/imx.c
|
||||
*
|
||||
* Driver for Motorola IMX serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* drivers/serial/msm_serial.c - driver for msm7k serial device and console
|
||||
* Driver for msm7k serial device and console
|
||||
*
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Author: Robert Love <rlove@google.com>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/msm_serial.h
|
||||
*
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Author: Robert Love <rlove@google.com>
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* drivers/tty/serial/msm_smd_tty.c
|
||||
*
|
||||
/*
|
||||
* Copyright (C) 2007 Google, Inc.
|
||||
* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
|
||||
* Author: Brian Swetland <swetland@google.com>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/netx-serial.c
|
||||
*
|
||||
* Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
@ -253,6 +253,8 @@ enum pch_uart_num_t {
|
|||
pch_ml7213_uart0,
|
||||
pch_ml7213_uart1,
|
||||
pch_ml7213_uart2,
|
||||
pch_ml7223_uart0,
|
||||
pch_ml7223_uart1,
|
||||
};
|
||||
|
||||
static struct pch_uart_driver_data drv_dat[] = {
|
||||
|
@ -263,6 +265,8 @@ static struct pch_uart_driver_data drv_dat[] = {
|
|||
[pch_ml7213_uart0] = {PCH_UART_8LINE, 0},
|
||||
[pch_ml7213_uart1] = {PCH_UART_2LINE, 1},
|
||||
[pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
|
||||
[pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
|
||||
[pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
|
||||
};
|
||||
|
||||
static unsigned int default_baud = 9600;
|
||||
|
@ -1534,6 +1538,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {
|
|||
.driver_data = pch_ml7213_uart1},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029),
|
||||
.driver_data = pch_ml7213_uart2},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800C),
|
||||
.driver_data = pch_ml7223_uart0},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
|
||||
.driver_data = pch_ml7223_uart1},
|
||||
{0,},
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/pmac_zilog.c
|
||||
*
|
||||
* Driver for PowerMac Z85c30 based ESCC cell found in the
|
||||
* "macio" ASICs of various PowerMac models
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/serial/pxa.c
|
||||
*
|
||||
* Based on drivers/serial/8250.c by Russell King.
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s3c240.c
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s3c2410.c
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung S3C2410 SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s3c2412.c
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s3c2440.c
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s3c24a0.c
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung S3C24A0 SoC onboard UARTs.
|
||||
*
|
||||
* Based on drivers/serial/s3c2410.c
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s3c6400.c
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
|
||||
*
|
||||
* Copyright 2008 Openmoko, Inc.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/s5pv210.c
|
||||
*
|
||||
/*
|
||||
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com/
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/sa1100.c
|
||||
*
|
||||
* Driver for SA11x0 serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/samsuing.c
|
||||
*
|
||||
/*
|
||||
* Driver core for Samsung SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* linux/drivers/serial/samsung.h
|
||||
*
|
||||
/*
|
||||
* Driver for Samsung SoC onboard UARTs.
|
||||
*
|
||||
* Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/sb1250-duart.c
|
||||
*
|
||||
* Support for the asynchronous serial interface (DUART) included
|
||||
* in the BCM1250 and derived System-On-a-Chip (SOC) devices.
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/core.c
|
||||
*
|
||||
* Driver core for serial ports
|
||||
*
|
||||
* Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
|
||||
|
@ -172,12 +170,16 @@ static int uart_startup(struct tty_struct *tty, struct uart_state *state, int in
|
|||
|
||||
retval = uport->ops->startup(uport);
|
||||
if (retval == 0) {
|
||||
if (init_hw) {
|
||||
/*
|
||||
* Initialise the hardware port settings.
|
||||
*/
|
||||
uart_change_speed(tty, state, NULL);
|
||||
if (uart_console(uport) && uport->cons->cflag) {
|
||||
tty->termios->c_cflag = uport->cons->cflag;
|
||||
uport->cons->cflag = 0;
|
||||
}
|
||||
/*
|
||||
* Initialise the hardware port settings.
|
||||
*/
|
||||
uart_change_speed(tty, state, NULL);
|
||||
|
||||
if (init_hw) {
|
||||
/*
|
||||
* Setup the RTS and DTR signals once the
|
||||
* port is open and ready to respond.
|
||||
|
@ -1240,17 +1242,6 @@ static void uart_set_termios(struct tty_struct *tty,
|
|||
}
|
||||
spin_unlock_irqrestore(&state->uart_port->lock, flags);
|
||||
}
|
||||
#if 0
|
||||
/*
|
||||
* No need to wake up processes in open wait, since they
|
||||
* sample the CLOCAL flag once, and don't recheck it.
|
||||
* XXX It's not clear whether the current behavior is correct
|
||||
* or not. Hence, this may change.....
|
||||
*/
|
||||
if (!(old_termios->c_cflag & CLOCAL) &&
|
||||
(tty->termios->c_cflag & CLOCAL))
|
||||
wake_up_interruptible(&state->uart_port.open_wait);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1423,7 +1414,6 @@ static void __uart_wait_until_sent(struct uart_port *port, int timeout)
|
|||
if (time_after(jiffies, expire))
|
||||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING); /* might not be needed */
|
||||
}
|
||||
|
||||
static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
|
||||
|
@ -1466,45 +1456,6 @@ static void uart_hangup(struct tty_struct *tty)
|
|||
mutex_unlock(&port->mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* uart_update_termios - update the terminal hw settings
|
||||
* @tty: tty associated with UART
|
||||
* @state: UART to update
|
||||
*
|
||||
* Copy across the serial console cflag setting into the termios settings
|
||||
* for the initial open of the port. This allows continuity between the
|
||||
* kernel settings, and the settings init adopts when it opens the port
|
||||
* for the first time.
|
||||
*/
|
||||
static void uart_update_termios(struct tty_struct *tty,
|
||||
struct uart_state *state)
|
||||
{
|
||||
struct uart_port *port = state->uart_port;
|
||||
|
||||
if (uart_console(port) && port->cons->cflag) {
|
||||
tty->termios->c_cflag = port->cons->cflag;
|
||||
port->cons->cflag = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the device failed to grab its irq resources,
|
||||
* or some other error occurred, don't try to talk
|
||||
* to the port hardware.
|
||||
*/
|
||||
if (!(tty->flags & (1 << TTY_IO_ERROR))) {
|
||||
/*
|
||||
* Make termios settings take effect.
|
||||
*/
|
||||
uart_change_speed(tty, state, NULL);
|
||||
|
||||
/*
|
||||
* And finally enable the RTS and DTR signals.
|
||||
*/
|
||||
if (tty->termios->c_cflag & CBAUD)
|
||||
uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
}
|
||||
|
||||
static int uart_carrier_raised(struct tty_port *port)
|
||||
{
|
||||
struct uart_state *state = container_of(port, struct uart_state, port);
|
||||
|
@ -1524,16 +1475,8 @@ static void uart_dtr_rts(struct tty_port *port, int onoff)
|
|||
struct uart_state *state = container_of(port, struct uart_state, port);
|
||||
struct uart_port *uport = state->uart_port;
|
||||
|
||||
if (onoff) {
|
||||
if (onoff)
|
||||
uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
|
||||
|
||||
/*
|
||||
* If this is the first open to succeed,
|
||||
* adjust things to suit.
|
||||
*/
|
||||
if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags))
|
||||
uart_update_termios(port->tty, state);
|
||||
}
|
||||
else
|
||||
uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
|
||||
}
|
||||
|
@ -1585,15 +1528,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
|
|||
BUG_ON(!tty_locked());
|
||||
pr_debug("uart_open(%d) called\n", line);
|
||||
|
||||
/*
|
||||
* tty->driver->num won't change, so we won't fail here with
|
||||
* tty->driver_data set to something non-NULL (and therefore
|
||||
* we won't get caught by uart_close()).
|
||||
*/
|
||||
retval = -ENODEV;
|
||||
if (line >= tty->driver->num)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* We take the semaphore inside uart_get to guarantee that we won't
|
||||
* be re-entered while allocating the state structure, or while we
|
||||
|
@ -1972,13 +1906,9 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
|
|||
struct tty_port *port = &state->port;
|
||||
struct device *tty_dev;
|
||||
struct uart_match match = {uport, drv};
|
||||
struct tty_struct *tty;
|
||||
|
||||
mutex_lock(&port->mutex);
|
||||
|
||||
/* Must be inside the mutex lock until we convert to tty_port */
|
||||
tty = port->tty;
|
||||
|
||||
tty_dev = device_find_child(uport->dev, &match, serial_match_port);
|
||||
if (device_may_wakeup(tty_dev)) {
|
||||
if (!enable_irq_wake(uport->irq))
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/serial_ks8695.c
|
||||
*
|
||||
* Driver for KS8695 serial ports
|
||||
*
|
||||
* Based on drivers/serial/serial_amba.c, by Kam Lee.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/serial_txx9.c
|
||||
*
|
||||
* Derived from many drivers using generic_serial interface,
|
||||
* especially serial_tx3912.c by Steven J. Hill and r39xx_serial.c
|
||||
* (was in Linux/VR tree) by Jim Pick.
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/sh-sci.c
|
||||
*
|
||||
* SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
|
||||
*
|
||||
* Copyright (C) 2002 - 2011 Paul Mundt
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* drivers/serial/vt8500_serial.c
|
||||
*
|
||||
* Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
|
||||
*
|
||||
* Based on msm_serial.c, which is:
|
||||
|
|
1113
drivers/tty/serial/xilinx_uartps.c
Normal file
1113
drivers/tty/serial/xilinx_uartps.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/synclink.c
|
||||
*
|
||||
* $Id: synclink.c,v 4.38 2005/11/07 16:30:34 paulkf Exp $
|
||||
*
|
||||
* Device driver for Microgate SyncLink ISA and PCI
|
||||
|
|
|
@ -416,6 +416,7 @@ static void flush_to_ldisc(struct work_struct *work)
|
|||
struct tty_buffer *head, *tail = tty->buf.tail;
|
||||
int seen_tail = 0;
|
||||
while ((head = tty->buf.head) != NULL) {
|
||||
int copied;
|
||||
int count;
|
||||
char *char_buf;
|
||||
unsigned char *flag_buf;
|
||||
|
@ -442,17 +443,19 @@ static void flush_to_ldisc(struct work_struct *work)
|
|||
line discipline as we want to empty the queue */
|
||||
if (test_bit(TTY_FLUSHPENDING, &tty->flags))
|
||||
break;
|
||||
if (!tty->receive_room || seen_tail)
|
||||
break;
|
||||
if (count > tty->receive_room)
|
||||
count = tty->receive_room;
|
||||
char_buf = head->char_buf_ptr + head->read;
|
||||
flag_buf = head->flag_buf_ptr + head->read;
|
||||
head->read += count;
|
||||
spin_unlock_irqrestore(&tty->buf.lock, flags);
|
||||
disc->ops->receive_buf(tty, char_buf,
|
||||
copied = disc->ops->receive_buf(tty, char_buf,
|
||||
flag_buf, count);
|
||||
spin_lock_irqsave(&tty->buf.lock, flags);
|
||||
|
||||
head->read += copied;
|
||||
|
||||
if (copied == 0 || seen_tail) {
|
||||
schedule_work(&tty->buf.work);
|
||||
break;
|
||||
}
|
||||
}
|
||||
clear_bit(TTY_FLUSHING, &tty->flags);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/tty_io.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
|
@ -964,12 +962,14 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
|
|||
}
|
||||
|
||||
void tty_write_unlock(struct tty_struct *tty)
|
||||
__releases(&tty->atomic_write_lock)
|
||||
{
|
||||
mutex_unlock(&tty->atomic_write_lock);
|
||||
wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
|
||||
}
|
||||
|
||||
int tty_write_lock(struct tty_struct *tty, int ndelay)
|
||||
__acquires(&tty->atomic_write_lock)
|
||||
{
|
||||
if (!mutex_trylock(&tty->atomic_write_lock)) {
|
||||
if (ndelay)
|
||||
|
@ -1391,16 +1391,15 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
|
|||
return ERR_PTR(-ENODEV);
|
||||
|
||||
tty = alloc_tty_struct();
|
||||
if (!tty)
|
||||
goto fail_no_mem;
|
||||
if (!tty) {
|
||||
retval = -ENOMEM;
|
||||
goto err_module_put;
|
||||
}
|
||||
initialize_tty_struct(tty, driver, idx);
|
||||
|
||||
retval = tty_driver_install_tty(driver, tty);
|
||||
if (retval < 0) {
|
||||
free_tty_struct(tty);
|
||||
module_put(driver->owner);
|
||||
return ERR_PTR(retval);
|
||||
}
|
||||
if (retval < 0)
|
||||
goto err_deinit_tty;
|
||||
|
||||
/*
|
||||
* Structures all installed ... call the ldisc open routines.
|
||||
|
@ -1409,15 +1408,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx,
|
|||
*/
|
||||
retval = tty_ldisc_setup(tty, tty->link);
|
||||
if (retval)
|
||||
goto release_mem_out;
|
||||
goto err_release_tty;
|
||||
return tty;
|
||||
|
||||
fail_no_mem:
|
||||
err_deinit_tty:
|
||||
deinitialize_tty_struct(tty);
|
||||
free_tty_struct(tty);
|
||||
err_module_put:
|
||||
module_put(driver->owner);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
return ERR_PTR(retval);
|
||||
|
||||
/* call the tty release_tty routine to clean out this slot */
|
||||
release_mem_out:
|
||||
err_release_tty:
|
||||
if (printk_ratelimit())
|
||||
printk(KERN_INFO "tty_init_dev: ldisc open failed, "
|
||||
"clearing slot %d\n", idx);
|
||||
|
@ -1892,6 +1894,7 @@ got_driver:
|
|||
retval = tty_add_file(tty, filp);
|
||||
if (retval) {
|
||||
tty_unlock();
|
||||
tty_release(inode, filp);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1902,12 +1905,10 @@ got_driver:
|
|||
#ifdef TTY_DEBUG_HANGUP
|
||||
printk(KERN_DEBUG "opening %s...", tty->name);
|
||||
#endif
|
||||
if (!retval) {
|
||||
if (tty->ops->open)
|
||||
retval = tty->ops->open(tty, filp);
|
||||
else
|
||||
retval = -ENODEV;
|
||||
}
|
||||
if (tty->ops->open)
|
||||
retval = tty->ops->open(tty, filp);
|
||||
else
|
||||
retval = -ENODEV;
|
||||
filp->f_flags = saved_flags;
|
||||
|
||||
if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) &&
|
||||
|
@ -2887,6 +2888,20 @@ void initialize_tty_struct(struct tty_struct *tty,
|
|||
tty->dev = tty_get_device(tty);
|
||||
}
|
||||
|
||||
/**
|
||||
* deinitialize_tty_struct
|
||||
* @tty: tty to deinitialize
|
||||
*
|
||||
* This subroutine deinitializes a tty structure that has been newly
|
||||
* allocated but tty_release cannot be called on that yet.
|
||||
*
|
||||
* Locking: none - tty in question must not be exposed at this point
|
||||
*/
|
||||
void deinitialize_tty_struct(struct tty_struct *tty)
|
||||
{
|
||||
tty_ldisc_deinit(tty);
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_put_char - write one character to a tty
|
||||
* @tty: tty
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/tty_ioctl.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds
|
||||
*
|
||||
* Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
|
||||
|
|
|
@ -956,6 +956,19 @@ void tty_ldisc_init(struct tty_struct *tty)
|
|||
tty_ldisc_assign(tty, ld);
|
||||
}
|
||||
|
||||
/**
|
||||
* tty_ldisc_init - ldisc cleanup for new tty
|
||||
* @tty: tty that was allocated recently
|
||||
*
|
||||
* The tty structure must not becompletely set up (tty_ldisc_setup) when
|
||||
* this call is made.
|
||||
*/
|
||||
void tty_ldisc_deinit(struct tty_struct *tty)
|
||||
{
|
||||
put_ldisc(tty->ldisc);
|
||||
tty_ldisc_assign(tty, NULL);
|
||||
}
|
||||
|
||||
void tty_ldisc_begin(void)
|
||||
{
|
||||
/* Setup the default TTY line discipline. */
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
/*
|
||||
* drivers/char/tty_lock.c
|
||||
*/
|
||||
#include <linux/tty.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/keyboard.c
|
||||
*
|
||||
* Written for linux by Johan Myreen as a translation from
|
||||
* the assembly version by Linus (with diacriticals added)
|
||||
*
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/selection.c
|
||||
*
|
||||
* This module exports the functions:
|
||||
*
|
||||
* 'int set_selection(struct tiocl_selection __user *, struct tty_struct *)'
|
||||
|
@ -334,8 +332,7 @@ int paste_selection(struct tty_struct *tty)
|
|||
continue;
|
||||
}
|
||||
count = sel_buffer_lth - pasted;
|
||||
count = min(count, tty->receive_room);
|
||||
tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
|
||||
count = tty->ldisc->ops->receive_buf(tty, sel_buffer + pasted,
|
||||
NULL, count);
|
||||
pasted += count;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/vc_screen.c
|
||||
*
|
||||
* Provide access to virtual console memory.
|
||||
* /dev/vcs0: the screen as it is being viewed right now (possibly scrolled)
|
||||
* /dev/vcsN: the screen of /dev/ttyN (1 <= N <= 63)
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/vt.c
|
||||
*
|
||||
* Copyright (C) 1991, 1992 Linus Torvalds
|
||||
*/
|
||||
|
||||
|
@ -858,7 +856,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
|
|||
{
|
||||
unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
|
||||
unsigned long end;
|
||||
unsigned int old_cols, old_rows, old_row_size, old_screen_size;
|
||||
unsigned int old_rows, old_row_size;
|
||||
unsigned int new_cols, new_rows, new_row_size, new_screen_size;
|
||||
unsigned int user;
|
||||
unsigned short *newscreen;
|
||||
|
@ -887,9 +885,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
|
|||
return -ENOMEM;
|
||||
|
||||
old_rows = vc->vc_rows;
|
||||
old_cols = vc->vc_cols;
|
||||
old_row_size = vc->vc_size_row;
|
||||
old_screen_size = vc->vc_screenbuf_size;
|
||||
|
||||
err = resize_screen(vc, new_cols, new_rows, user);
|
||||
if (err) {
|
||||
|
@ -1197,6 +1193,13 @@ static void csi_J(struct vc_data *vc, int vpar)
|
|||
vc->vc_x + 1);
|
||||
}
|
||||
break;
|
||||
case 3: /* erase scroll-back buffer (and whole display) */
|
||||
scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
|
||||
vc->vc_screenbuf_size >> 1);
|
||||
set_origin(vc);
|
||||
if (CON_IS_VISIBLE(vc))
|
||||
update_screen(vc);
|
||||
/* fall through */
|
||||
case 2: /* erase whole display */
|
||||
count = vc->vc_cols * vc->vc_rows;
|
||||
start = (unsigned short *)vc->vc_origin;
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
/*
|
||||
* linux/drivers/char/vt_ioctl.c
|
||||
*
|
||||
* Copyright (C) 1992 obz under the linux copyright
|
||||
*
|
||||
* Dynamic diacritical handling - aeb@cwi.nl - Dec 1993
|
||||
|
@ -698,10 +696,23 @@ int vt_ioctl(struct tty_struct *tty,
|
|||
break;
|
||||
|
||||
case KDGKBMODE:
|
||||
uival = ((kbd->kbdmode == VC_RAW) ? K_RAW :
|
||||
(kbd->kbdmode == VC_MEDIUMRAW) ? K_MEDIUMRAW :
|
||||
(kbd->kbdmode == VC_UNICODE) ? K_UNICODE :
|
||||
K_XLATE);
|
||||
switch (kbd->kbdmode) {
|
||||
case VC_RAW:
|
||||
uival = K_RAW;
|
||||
break;
|
||||
case VC_MEDIUMRAW:
|
||||
uival = K_MEDIUMRAW;
|
||||
break;
|
||||
case VC_UNICODE:
|
||||
uival = K_UNICODE;
|
||||
break;
|
||||
case VC_OFF:
|
||||
uival = K_OFF;
|
||||
break;
|
||||
default:
|
||||
uival = K_XLATE;
|
||||
break;
|
||||
}
|
||||
goto setint;
|
||||
|
||||
/* this could be folded into KDSKBMODE, but for compatibility
|
||||
|
@ -1499,7 +1510,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
|
|||
{
|
||||
struct vc_data *vc = tty->driver_data;
|
||||
struct console_font_op op; /* used in multiple places here */
|
||||
struct kbd_struct *kbd;
|
||||
unsigned int console;
|
||||
void __user *up = (void __user *)arg;
|
||||
int perm;
|
||||
|
@ -1522,7 +1532,6 @@ long vt_compat_ioctl(struct tty_struct *tty,
|
|||
if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
|
||||
perm = 1;
|
||||
|
||||
kbd = kbd_table + console;
|
||||
switch (cmd) {
|
||||
/*
|
||||
* these need special handlers for incompatible data structures
|
||||
|
|
|
@ -1051,6 +1051,7 @@ char *get_task_comm(char *buf, struct task_struct *tsk)
|
|||
task_unlock(tsk);
|
||||
return buf;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(get_task_comm);
|
||||
|
||||
void set_task_comm(struct task_struct *tsk, char *buf)
|
||||
{
|
||||
|
|
42
include/linux/pti.h
Normal file
42
include/linux/pti.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) Intel 2011
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* The PTI (Parallel Trace Interface) driver directs trace data routed from
|
||||
* various parts in the system out through the Intel Penwell PTI port and
|
||||
* out of the mobile device for analysis with a debugging tool
|
||||
* (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
|
||||
* compact JTAG, standard.
|
||||
*
|
||||
* This header file will allow other parts of the OS to use the
|
||||
* interface to write out it's contents for debugging a mobile system.
|
||||
*/
|
||||
|
||||
#ifndef PTI_H_
|
||||
#define PTI_H_
|
||||
|
||||
/* offset for last dword of any PTI message. Part of MIPI P1149.7 */
|
||||
#define PTI_LASTDWORD_DTS 0x30
|
||||
|
||||
/* basic structure used as a write address to the PTI HW */
|
||||
struct pti_masterchannel {
|
||||
u8 master;
|
||||
u8 channel;
|
||||
};
|
||||
|
||||
/* the following functions are defined in misc/pti.c */
|
||||
void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count);
|
||||
struct pti_masterchannel *pti_request_masterchannel(u8 type);
|
||||
void pti_release_masterchannel(struct pti_masterchannel *mc);
|
||||
|
||||
#endif /*PTI_H_*/
|
|
@ -45,7 +45,8 @@
|
|||
#define PORT_OCTEON 17 /* Cavium OCTEON internal UART */
|
||||
#define PORT_AR7 18 /* Texas Instruments AR7 internal UART */
|
||||
#define PORT_U6_16550A 19 /* ST-Ericsson U6xxx internal UART */
|
||||
#define PORT_MAX_8250 19 /* max port ID */
|
||||
#define PORT_TEGRA 20 /* NVIDIA Tegra internal UART */
|
||||
#define PORT_MAX_8250 20 /* max port ID */
|
||||
|
||||
/*
|
||||
* ARM specific type numbers. These are not currently guaranteed
|
||||
|
@ -202,6 +203,9 @@
|
|||
/* VIA VT8500 SoC */
|
||||
#define PORT_VT8500 97
|
||||
|
||||
/* Xilinx PSS UART */
|
||||
#define PORT_XUARTPS 98
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
* ST16C654: 8 16 56 60 8 16 32 56 PORT_16654
|
||||
* TI16C750: 1 16 32 56 xx xx xx xx PORT_16750
|
||||
* TI16C752: 8 16 56 60 8 16 32 56
|
||||
* Tegra: 1 4 8 14 16 8 4 1 PORT_TEGRA
|
||||
*/
|
||||
#define UART_FCR_R_TRIG_00 0x00
|
||||
#define UART_FCR_R_TRIG_01 0x40
|
||||
|
@ -118,6 +119,7 @@
|
|||
#define UART_MCR_DTR 0x01 /* DTR complement */
|
||||
|
||||
#define UART_LSR 5 /* In: Line Status Register */
|
||||
#define UART_LSR_FIFOE 0x80 /* Fifo error */
|
||||
#define UART_LSR_TEMT 0x40 /* Transmitter empty */
|
||||
#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
|
||||
#define UART_LSR_BI 0x10 /* Break interrupt indicator */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue