Commit 6fb70b47 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.41

parent ee226d67
......@@ -18,7 +18,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
......
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
......
......@@ -14,7 +14,6 @@
* for more details.
*/
#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
......
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <asm/dvma.h>
......
......@@ -447,9 +447,6 @@ static inline void attempt_merge (request_queue_t * q,
{
struct request *next = req->next;
if (req->rq_dev == MKDEV(22, 64))
printk("attempt_merge at %lu %lu\n", req->sector, q->current_request->sector);
if (!next)
return;
if (req->sector + req->nr_sectors != next->sector)
......
......@@ -44,8 +44,8 @@
* int rs_init(void);
*/
static char *serial_version = "4.91";
static char *serial_revdate = "1999-11-17";
static char *serial_version = "4.92";
static char *serial_revdate = "2000-1-27";
/*
* Serial driver configuration section. Here are the various options:
......@@ -74,12 +74,10 @@ static char *serial_revdate = "1999-11-17";
#include <linux/config.h>
#include <linux/version.h>
#include <linux/sysrq.h>
#undef SERIAL_PARANOIA_CHECK
#define CONFIG_SERIAL_NOPAUSE_IO
#define SERIAL_DO_RESTART
#define CONFIG_SERIAL_PCI_MEMMAPPED
#if 0
/* These defines are normally controlled by the autoconf.h */
......@@ -100,6 +98,12 @@ static char *serial_revdate = "1999-11-17";
#endif
#endif
#ifdef CONFIG_ISAPNP
#ifndef ENABLE_SERIAL_PNP
#define ENABLE_SERIAL_PNP
#endif
#endif
/* Set of debugging defines */
#undef SERIAL_DEBUG_INTR
......@@ -133,31 +137,13 @@ static char *serial_revdate = "1999-11-17";
#define SERIAL_INLINE
#endif
#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
#else
#define DBG_CNT(s)
#endif
/*
* End of serial driver configuration section.
*/
#define NEW_MODULES
#ifdef LOCAL_HEADERS /* We're building standalone */
#define MODULE
#endif
#ifdef NEW_MODULES
#ifdef MODVERSIONS
#include <linux/modversions.h>
#endif
#else /* !NEW_MODULES */
#ifdef MODVERSIONS
#define MODULE
#endif
#endif /* NEW_MODULES */
#include <linux/module.h>
#include <linux/types.h>
......@@ -198,13 +184,19 @@ static char *serial_revdate = "1999-11-17";
#ifdef ENABLE_SERIAL_PCI
#include <linux/pci.h>
#endif
#ifdef ENABLE_SERIAL_PNP
#include <linux/isapnp.h>
#endif
#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
#endif
/*
* All of the compatibilty code so we can compile serial.c against
* older kernels is hidden in serial_compat.h
*/
#if (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
#include "serial_compat.h"
#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
#include "serial_compat.h"
#endif
#include <asm/system.h>
......@@ -276,7 +268,7 @@ static struct serial_uart_config uart_config[] = {
UART_STARTECH },
{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
{ "Startech", 1, 0}, /* usurped by cyclades.c */
{ "16C950", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
{ "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO},
{ "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO |
UART_STARTECH },
{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
......@@ -290,16 +282,35 @@ static struct serial_state rs_table[RS_TABLE_SIZE] = {
#define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state))
#ifdef ENABLE_SERIAL_PCI
#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
#define NR_PCI_BOARDS 8
#ifdef MODULE
/* We don't unregister PCI boards right now */
static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS];
static int serial_pci_board_idx = 0;
#ifdef PCI_NUM_RESOURCES
#endif
#ifndef PCI_BASE_ADDRESS
#define PCI_BASE_ADDRESS(dev, r) ((dev)->resource[r].start)
#else
#define PCI_BASE_ADDRESS(dev, r) ((dev)->base_address[r])
#define PCI_BASE_REGION_SIZE(dev, r) ((dev)->resource[r].end - \
(dev)->resource[r].start)
#define IS_PCI_REGION_IOPORT(dev, r) ((dev)->resource[r].flags & \
IORESOURCE_IO)
#endif
#ifndef PCI_IRQ_RESOURCE
#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
#endif
#endif /* ENABLE_SERIAL_PCI */
#ifndef pci_get_subvendor
#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
#define pci_get_subdevice(dev) ((dev)->subsystem_device)
#endif
#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */
#ifndef PREPARE_FUNC
#define PREPARE_FUNC(dev) (dev->prepare)
#define ACTIVATE_FUNC(dev) (dev->activate)
#define DEACTIVATE_FUNC(dev) (dev->deactivate)
#endif
static struct tty_struct *serial_table[NR_PORTS];
static struct termios *serial_termios[NR_PORTS];
......@@ -309,6 +320,13 @@ static struct termios *serial_termios_locked[NR_PORTS];
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
#define DBG_CNT(s) printk("(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
kdevname(tty->device), (info->flags), serial_refcount,info->count,tty->count,s)
#else
#define DBG_CNT(s)
#endif
/*
* tmp_buf is used as a temporary buffer by serial_write. We need to
* lock it in case the copy_from_user blocks while swapping in a page,
......@@ -355,11 +373,9 @@ static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
outb(info->hub6 - 1 + offset, info->port);
return inb(info->port+1);
#endif
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
case SERIAL_IO_MEM:
return readb(info->iomem_base +
(offset<<info->iomem_reg_shift));
#endif
#ifdef CONFIG_SERIAL_GSC
case SERIAL_IO_GSC:
return gsc_readb(info->iomem_base + offset);
......@@ -379,12 +395,10 @@ static _INLINE_ void serial_out(struct async_struct *info, int offset,
outb(value, info->port+1);
break;
#endif
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
case SERIAL_IO_MEM:
writeb(value, info->iomem_base +
(offset<<info->iomem_reg_shift));
break;
#endif
#ifdef CONFIG_SERIAL_GSC
case SERIAL_IO_GSC:
gsc_writeb(value, info->iomem_base + offset);
......@@ -905,11 +919,16 @@ static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
continue;
info = IRQ_ports[irq];
/*
* The user was a bonehead, and misconfigured their
* multiport info. Rather than lock up the kernel
* in an infinite loop, if we loop too many times,
* print a message and break out of the loop.
*/
if (pass_counter++ > RS_ISR_PASS_LIMIT) {
#if 1
printk("rs_multi loop break\n");
#endif
break; /* Prevent infinite loops */
printk("Misconfigured multiport serial info "
"for irq %d. Breaking out irq loop\n", irq);
break;
}
if (multi->port_monitor)
printk("rs port monitor irq %d: 0x%x, 0x%x\n",
......@@ -1540,6 +1559,15 @@ static void change_speed(struct async_struct *info,
/* As a last resort, if the quotient is zero, default to 9600 bps */
if (!quot)
quot = baud_base / 9600;
/*
* Work around a bug in the Oxford Semiconductor 952 rev B
* chip which causes it to seriously miscalculate baud rates
* when DLL is 0.
*/
if (((quot & 0xFF) == 0) && (info->state->type == PORT_16C950) &&
(info->state->revision == 0x5202))
quot++;
info->quot = quot;
info->timeout = ((info->xmit_fifo_size*HZ*bits*quot) / baud_base);
info->timeout += HZ/50; /* Add .02 seconds of slop */
......@@ -2090,6 +2118,8 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
if (arg & TIOCM_OUT2)
info->MCR |= UART_MCR_OUT2;
#endif
if (arg & TIOCM_LOOP)
info->MCR |= UART_MCR_LOOP;
break;
case TIOCMBIC:
if (arg & TIOCM_RTS)
......@@ -2102,6 +2132,8 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
if (arg & TIOCM_OUT2)
info->MCR &= ~UART_MCR_OUT2;
#endif
if (arg & TIOCM_LOOP)
info->MCR &= ~UART_MCR_LOOP;
break;
case TIOCMSET:
info->MCR = ((info->MCR & ~(UART_MCR_RTS |
......@@ -2109,12 +2141,14 @@ static int set_modem_info(struct async_struct * info, unsigned int cmd,
UART_MCR_OUT1 |
UART_MCR_OUT2 |
#endif
UART_MCR_LOOP |
UART_MCR_DTR))
| ((arg & TIOCM_RTS) ? UART_MCR_RTS : 0)
#ifdef TIOCM_OUT1
| ((arg & TIOCM_OUT1) ? UART_MCR_OUT1 : 0)
| ((arg & TIOCM_OUT2) ? UART_MCR_OUT2 : 0)
#endif
| ((arg & TIOCM_LOOP) ? UART_MCR_LOOP : 0)
| ((arg & TIOCM_DTR) ? UART_MCR_DTR : 0));
break;
default:
......@@ -2579,6 +2613,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
return;
}
info->flags |= ASYNC_CLOSING;
restore_flags(flags);
/*
* Save the termios structure, since this port may have
* separate termios for callout and dialin.
......@@ -2630,7 +2665,6 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
ASYNC_CLOSING);
wake_up_interruptible(&info->close_wait);
MOD_DEC_USE_COUNT;
restore_flags(flags);
}
/*
......@@ -2712,6 +2746,8 @@ static void rs_hangup(struct tty_struct *tty)
state = info->state;
rs_flush_buffer(tty);
if (info->flags & ASYNC_CLOSING)
return;
shutdown(info);
info->event = 0;
state->count = 0;
......@@ -2884,10 +2920,8 @@ static int get_async_struct(int line, struct async_struct **ret_info)
info->port = sstate->port;
info->flags = sstate->flags;
info->io_type = sstate->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = sstate->iomem_base;
info->iomem_reg_shift = sstate->iomem_reg_shift;
#endif
info->xmit_fifo_size = sstate->xmit_fifo_size;
info->line = line;
info->tqueue.routine = do_softint;
......@@ -3123,43 +3157,47 @@ int rs_read_proc(char *page, char **start, off_t off, int count,
* number, and identifies which options were configured into this
* driver.
*/
static _INLINE_ void show_serial_version(void)
{
printk(KERN_INFO "%s version %s%s (%s) with", serial_name,
serial_version, LOCAL_VERSTRING, serial_revdate);
static char serial_options[] __initdata =
#ifdef CONFIG_HUB6
printk(" HUB-6");
" HUB-6"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_MANY_PORTS
printk(" MANY_PORTS");
" MANY_PORTS"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_MULTIPORT
printk(" MULTIPORT");
" MULTIPORT"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_SHARE_IRQ
printk(" SHARE_IRQ");
" SHARE_IRQ"
#define SERIAL_OPT
#endif
#ifdef CONFIG_SERIAL_DETECT_IRQ
printk(" DETECT_IRQ");
" DETECT_IRQ"
#define SERIAL_OPT
#endif
#ifdef ENABLE_SERIAL_PCI
printk(" SERIAL_PCI");
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
printk(" PCI_IOMEM");
" SERIAL_PCI"
#define SERIAL_OPT
#endif
#ifdef ENABLE_SERIAL_PNP
" ISAPNP"
#define SERIAL_OPT
#endif
#ifdef SERIAL_OPT
printk(" enabled\n");
" enabled\n";
#else
printk(" no serial options enabled\n");
" no serial options enabled\n";
#endif
#undef SERIAL_OPT
static _INLINE_ void show_serial_version(void)
{
printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
serial_version, LOCAL_VERSTRING, serial_revdate,
serial_options);
}
/*
......@@ -3188,11 +3226,15 @@ static unsigned detect_uart_irq (struct serial_state * state)
}
#endif
scr_info.magic = SERIAL_MAGIC;
scr_info.state = state;
scr_info.port = state->port;
scr_info.flags = state->flags;
#ifdef CONFIG_HUB6
scr_info.hub6 = state->hub6;
#endif
scr_info.io_type = state->io_type;
scr_info.iomem_base = state->iomem_base;
scr_info.iomem_reg_shift = state->iomem_reg_shift;
/* forget possible initially masked and pending IRQ */
probe_irq_off(probe_irq_on());
......@@ -3296,7 +3338,8 @@ static void autoconfig_startech_uarts(struct async_struct *info,
(scratch3 == 0x50 || scratch3 == 0x52 ||
scratch3 == 0x54)) {
state->type = PORT_16C950;
state->revision = serial_icr_read(info, UART_REV);
state->revision = serial_icr_read(info, UART_REV) |
(scratch3 << 8);
return;
}
}
......@@ -3367,10 +3410,8 @@ static void autoconfig(struct serial_state * state)
info->hub6 = state->hub6;
#endif
info->io_type = state->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = state->iomem_base;
info->iomem_reg_shift = state->iomem_reg_shift;
#endif
save_flags(flags); cli();
......@@ -3536,18 +3577,151 @@ static struct symbol_table serial_syms = {
};
#endif
#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
static void __init printk_pnp_dev_id(unsigned short vendor,
unsigned short device)
{
printk("%c%c%c%x%x%x%x",
'A' + ((vendor >> 2) & 0x3f) - 1,
'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
'A' + ((vendor >> 8) & 0x1f) - 1,
(device >> 4) & 0x0f,
device & 0x0f,
(device >> 12) & 0x0f,
(device >> 8) & 0x0f);
}
static _INLINE_ int get_pci_port(struct pci_dev *dev,
struct pci_board *board,
struct serial_struct *state,
int idx)
{
unsigned long port;
int base_idx;
int max_port;
base_idx = SPCI_FL_GET_BASE(board->flags);
if (board->flags & SPCI_FL_BASE_TABLE)
base_idx += idx;
if (board->flags & SPCI_FL_REGION_SZ_CAP) {
max_port = PCI_BASE_REGION_SIZE(dev, base_idx) / 8;
if (idx >= max_port)
return 1;
}
port = PCI_BASE_ADDRESS(dev, base_idx) + board->first_uart_offset;
if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
port += idx * (board->uart_offset ? board->uart_offset : 8);
if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
state->port = port;
return 0;
}
state->io_type = SERIAL_IO_MEM;
state->iomem_base = ioremap(port, board->uart_offset);
state->iomem_reg_shift = board->reg_shift;
state->port = 0;
return 0;
}
static _INLINE_ int get_pci_irq(struct pci_dev *dev,
struct pci_board *board,
int idx)
{
int base_idx;
if ((board->flags & SPCI_FL_IRQRESOURCE) == 0)
return dev->irq;
base_idx = SPCI_FL_GET_IRQBASE(board->flags);
if (board->flags & SPCI_FL_IRQ_TABLE)
base_idx += idx;
return PCI_IRQ_RESOURCE(dev, base_idx);
}
/*
* Common enabler code shared by both PCI and ISAPNP probes
*/
static void __init start_pci_pnp_board(struct pci_dev *dev,
struct pci_board *board)
{
int k, line;
struct serial_struct fake_state;
int base_baud;
if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
printk("SERIAL: PNP device '");
printk_pnp_dev_id(board->vendor, board->device);
printk("' prepare failed\n");
return;
}
if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
printk("SERIAL: PNP device '");
printk_pnp_dev_id(board->vendor, board->device);
printk("' activate failed\n");
return;
}
/*
* Run the initialization function, if any
*/
if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0))
return;
#ifdef MODULE
/*
* Register the serial board in the array if we need to
* shutdown the board on a module unload.
*/
if (DEACTIVATE_FUNC(dev) || board->init_fn) {
if (serial_pci_board_idx >= NR_PCI_BOARDS)
return;
serial_pci_board[serial_pci_board_idx].board = *board;
serial_pci_board[serial_pci_board_idx].dev = dev;
serial_pci_board_idx++;
}
#endif
base_baud = board->base_baud;
if (!base_baud)
base_baud = BASE_BAUD;
memset(&fake_state, 0, sizeof(fake_state));
for (k=0; k < board->num_ports; k++) {
fake_state.irq = get_pci_irq(dev, board, k);
if (get_pci_port(dev, board, &fake_state, k))
break;
fake_state.flags = ASYNC_SKIP_TEST;
#ifdef SERIAL_DEBUG_PCI
printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
fake_state.port, fake_state.irq, fake_state.io_type);
#endif
line = register_serial(&fake_state);
if (line < 0)
break;
rs_table[line].baud_base = base_baud;
}
}
#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */
#ifdef ENABLE_SERIAL_PCI
/*
* Some PCI serial cards using the PLX 9050 PCI interface chip require
* that the card interrupt be explicitly enabled or disabled. This
* seems to be mainly needed on card using the PLX which also use I/O
* mapped memory.
*
* Note that __init is a no-op if MODULE is defined; we depend on this.
*/
static int __init pci_plx9050_fn(struct pci_dev *dev,
struct pci_board *board,
int enable)
static int
#ifndef MODULE
__init
#endif
pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
{
u8 data, *p, scratch;
......@@ -3559,7 +3733,7 @@ static int __init pci_plx9050_fn(struct pci_dev *dev,
/* enable/disable interrupts */
p = ioremap(PCI_BASE_ADDRESS(dev, 0), 0x80);
if (board->vendor == PCI_VENDOR_ID_PANACOM) {
if (dev->vendor == PCI_VENDOR_ID_PANACOM) {
scratch = readl(p + 0x4c);
if (enable)
scratch |= 0x40;
......@@ -3598,9 +3772,11 @@ static int __init pci_plx9050_fn(struct pci_dev *dev,
#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
static int __init pci_siig10x_fn(struct pci_dev *dev,
struct pci_board *board,
int enable)
static int
#ifndef MODULE
__init
#endif
pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
{
u16 data, *p;
......@@ -3628,9 +3804,11 @@ static int __init pci_siig10x_fn(struct pci_dev *dev,
#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
static int __init pci_siig20x_fn(struct pci_dev *dev,
struct pci_board *board,
int enable)
static int
#ifndef MODULE
__init
#endif
pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
{
u8 data;
......@@ -3649,11 +3827,12 @@ static int __init pci_siig20x_fn(struct pci_dev *dev,
return 0;
}
/*
* This is the configuration table for all of the PCI serial boards
* which we support.
*/
static struct pci_board pci_boards[] = {
static struct pci_board pci_boards[] __initdata = {
/*
* Vendor ID, Device ID,
* Subvendor ID, Subdevice ID,
......@@ -3752,7 +3931,7 @@ static struct pci_board pci_boards[] = {
{ PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
PCI_SUBVENDOR_ID_KEYSPAN,
PCI_SUBDEVICE_ID_KEYSPAN_SX2,
SPCI_FL_BASE2 | SPCI_FL_IOMEM, 2, 921600,
SPCI_FL_BASE2, 2, 921600, /* IOMEM */
0x400, 7, pci_plx9050_fn },
{ PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
PCI_ANY_ID, PCI_ANY_ID,
......@@ -3798,18 +3977,47 @@ static struct pci_board pci_boards[] = {
{ PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE1, 8, 115200 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
SPCI_FL_BASE0 , 4, 115200 },
{ PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
SPCI_FL_BASE0 , 4, 921600 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 , 4, 115200 },
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 , 2, 115200 },
/* This board uses the size of PCI Base region 0 to
* signal now many ports are available */
{ PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 },
{ PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 , 2, 921600 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DUAL_SERIAL,
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 },
{ PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 },
{ PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE2, 1, 460800,
......@@ -3945,40 +4153,82 @@ static struct pci_board pci_boards[] = {
/* Computone devices submitted by Doug McNash dmcnash@computone.com */
{ PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
SPCI_FL_IOMEM | SPCI_FL_BASE0, 4, 921600,
SPCI_FL_BASE0, 4, 921600, /* IOMEM */
0x40, 2, NULL, 0x200 },
{ PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
SPCI_FL_IOMEM | SPCI_FL_BASE0, 8, 921600,
SPCI_FL_BASE0, 8, 921600, /* IOMEM */
0x40, 2, NULL, 0x200 },
{ PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
SPCI_FL_IOMEM | SPCI_FL_BASE0, 6, 921600,
SPCI_FL_BASE0, 6, 921600, /* IOMEM */
0x40, 2, NULL, 0x200 },
/*
* Untested PCI modems, sent in from various folks...
*/
/* at+t zoom 56K faxmodem, from dougd@shieldsbag.com */
{ PCI_VENDOR_ID_ATT, 0x442,
/* Digitan DS560-558, from jimd@esoft.com */
{ PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE1, 1, 115200 },
/* at&t unknown modem, from jimd@esoft.com */
{ PCI_VENDOR_ID_ATT, 0x480,
/* 3Com US Robotics 56k Voice Internal PCI model 5610 */
{ PCI_VENDOR_ID_USR, 0x1008,
PCI_ANY_ID, PCI_ANY_ID,
SPCI_FL_BASE1, 1, 115200 },
SPCI_FL_BASE0, 1, 115200 },
/*
* Untested PCI modems, sent in from various folks...
*/
/* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
{ PCI_VENDOR_ID_ROCKWELL, 0x1004,
0x1048, 0x1500,
SPCI_FL_BASE1, 1, 115200 },
/* 3Com US Robotics 56k* Voice Internal PCI, model# 2884 */
/* from evidal@iti.upv.es */
/* XXX complete guess this may not work!!! */
{ PCI_VENDOR_ID_USR, 0x1006,
0x12b9, 0x0060,
SPCI_FL_BASE1 | SPCI_FL_IOMEM, 1, 115200 },
{ 0, }
/* Generic serial board */
{ 0, 0,
0, 0,
SPCI_FL_BASE0, 1, 115200 },
};
/*
* Given a complete unknown PCI device, try to use some hueristics to
* guess what the configuration might be, based on the pitiful PCI
* serial specs. Returns 0 on success, 1 on failure.
*/
static int _INLINE_ serial_guess_board(struct pci_dev *dev,
struct pci_board *board)
{
int num_iomem = 0, num_port = 0, first_port = -1;
int i;
/*
* If it is not a communications device or the programming
* interface is greater than 6, give up.
*
* (Should we try to make guesses for multiport serial devices
* later?)
*/
if ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL ||
(dev->class & 0xff) > 6)
return 1;
for (i=0; i < 6; i++) {
if (IS_PCI_REGION_IOPORT(dev, i)) {
num_port = 0;
if (first_port == -1)
first_port = i;
} else {
num_iomem++;
}
}
/*
* If there is 1 or 0 iomem regions, and exactly one port, use
* it.
*/
if (num_iomem <= 1 && num_port == 1) {
board->flags = first_port;
return 0;
}
return 1;
}
/*
* Query PCI space for known serial boards
* If found, add them to the PCI device space in rs_table[]
......@@ -3986,19 +4236,22 @@ static struct pci_board pci_boards[] = {
* Accept a maximum of eight boards
*
*/
static void probe_serial_pci(void)
static void __init probe_serial_pci(void)
{
int k, line;
struct pci_dev *dev = NULL;
struct pci_board *board;
struct serial_struct fake_state;
int uart_offset, base_baud, base_idx;
unsigned long port;
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG "Entered probe_serial_pci()\n");
#endif
if (!pcibios_present()) {
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG "Leaving probe_serial_pci() (no pcibios)\n");
#endif
return;
}
pci_for_each_dev(dev) {
for (board = pci_boards; board->vendor; board++) {
if (board->vendor != (unsigned short) PCI_ANY_ID &&
......@@ -4008,121 +4261,87 @@ static void probe_serial_pci(void)
dev->device != board->device)
continue;
if (board->subvendor != (unsigned short) PCI_ANY_ID &&
dev->subsystem_vendor != board->subvendor)
pci_get_subvendor(dev) != board->subvendor)
continue;
if (board->subdevice != (unsigned short) PCI_ANY_ID &&
dev->subsystem_device != board->subdevice)
pci_get_subdevice(dev) != board->subdevice)
continue;
break;
}
if (board->vendor == 0) {
if (board->vendor == 0 && serial_guess_board(dev, board))
continue;
start_pci_pnp_board(dev, board);
}
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG
"Found unknown serial board: %x:%x, %x:%x, %x\n",
dev->vendor, dev->device, subvendor, subdevice,
dev->class);
printk(KERN_DEBUG
" Addresses: %lx, %lx, %lx, %lx\n",
PCI_BASE_ADDRESS(dev, 0), PCI_BASE_ADDRESS(dev, 1),
PCI_BASE_ADDRESS(dev, 2), PCI_BASE_ADDRESS(dev, 3));
#endif
continue;
}
printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n");
#endif
return;
}
/*
* Run the initialization function, if any
*/
if (board->init_fn)
if ((board->init_fn)(dev, board, 1) != 0)
continue;
#endif /* ENABLE_SERIAL_PCI */
/*
* Register the serial board in the array so we can
* shutdown the board later, if necessary.
*/
if (serial_pci_board_idx >= NR_PCI_BOARDS)
continue;
serial_pci_board[serial_pci_board_idx].board = board;
serial_pci_board[serial_pci_board_idx].dev = dev;
serial_pci_board_idx++;
#ifdef ENABLE_SERIAL_PNP
static struct pci_board pnp_devices[] __initdata = {
/* Rockwell 56K ACF II Fax+Data+Voice Modem */
{ ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
/* Boca Research 33,600 ACF Modem */
{ ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
/* Best Data Products Inc. Smart One 336F PnP Modem */
{ ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
/* These ID's are taken from M$ documentation */
/* Compaq 14400 Modem */
{ ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
/* Compaq 2400/9600 Modem */
{ ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
/* Generic standard PC COM port */
{ ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
/* Generic 16550A-compatible COM port */
{ ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501), 0, 0,
SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT, 1, 115200 },
{ 0, }
};
base_idx = board->flags & SPCI_FL_BASE_MASK;
port = PCI_BASE_ADDRESS(dev, base_idx) +
board->first_uart_offset;
if (board->flags & SPCI_FL_IOMEM)
port &= PCI_BASE_ADDRESS_MEM_MASK;
else
port &= PCI_BASE_ADDRESS_IO_MASK;
static void __init probe_serial_pnp(void)
{
struct pci_dev *dev = NULL;
struct pci_board *board;
/*
* Set some defaults for the loop below, which
* actually registers each serial port belonging to
* the card.
*/
uart_offset = board->uart_offset;
if (!uart_offset)
uart_offset = 8;
base_baud = board->base_baud;
if (!base_baud)
base_baud = BASE_BAUD;
#ifndef CONFIG_SERIAL_PCI_MEMMAPPED
if (board->flags & SPCI_FL_IOMEM) {
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG
"Can't support memory mapped PCI serial device\n");
#ifdef SERIAL_DEBUG_PNP
printk("Entered probe_serial_pnp()\n");
#endif
continue;
}
if (!isapnp_present()) {
#ifdef SERIAL_DEBUG_PNP
printk("Leaving probe_serial_pnp() (no isapnp)\n");
#endif
memset(&fake_state, 0, sizeof(fake_state));
return;
}
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG
"Found Serial PCI device: %x:%x, %x:%x, %x\n",
dev->vendor, dev->device, subvendor, subdevice,
dev->class);
printk(KERN_DEBUG
" IRQ: %d, base: %lx (%s), num_ports: %d\n",
dev->irq, port, board->flags & SPCI_FL_IOMEM ?
"iomem" : "port", board->num_ports);
#endif
for (board = pnp_devices; board->vendor; board++) {
while ((dev = isapnp_find_dev(NULL, board->vendor,
board->device, dev))) {
start_pci_pnp_board(dev, board);
for (k=0; k < board->num_ports; k++) {
if (board->flags & SPCI_FL_BASE_TABLE) {
port = PCI_BASE_ADDRESS(dev, base_idx++);
if (board->flags & SPCI_FL_IOMEM)
port &= PCI_BASE_ADDRESS_MEM_MASK;
else
port &= PCI_BASE_ADDRESS_IO_MASK;
}
fake_state.irq = dev->irq;
fake_state.port = port;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
if (board->flags & SPCI_FL_IOMEM) {
fake_state.io_type = SERIAL_IO_MEM;
fake_state.iomem_base =
ioremap(port, board->uart_offset);
fake_state.iomem_reg_shift = board->reg_shift;
fake_state.port = 0;
}
#endif
port += uart_offset;
fake_state.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
line = register_serial(&fake_state);
if (line < 0)
break;
rs_table[line].baud_base = base_baud;
}
}
#ifdef SERIAL_DEBUG_PCI
printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n");
}
}
#ifdef SERIAL_DEBUG_PNP
printk("Leaving probe_serial_pnp() (probe finished)\n");
#endif
return;
return;
}
#endif /* ENABLE_SERIAL_PCI */
#endif /* ENABLE_SERIAL_PNP */
/*
* The serial driver boot-time initialization code!
......@@ -4269,6 +4488,9 @@ int __init rs_init(void)
}
#ifdef ENABLE_SERIAL_PCI
probe_serial_pci();
#endif
#ifdef ENABLE_SERIAL_PNP
probe_serial_pnp();
#endif
return 0;
}
......@@ -4282,6 +4504,7 @@ int register_serial(struct serial_struct *req)
int i;
unsigned long flags;
struct serial_state *state;
struct async_struct *info;
save_flags(flags);
cli();
......@@ -4311,13 +4534,17 @@ int register_serial(struct serial_struct *req)
state->port = req->port;
state->flags = req->flags;
state->io_type = req->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
state->iomem_base = req->iomem_base;
state->iomem_reg_shift = req->iomem_reg_shift;
#endif
if (req->baud_base)
state->baud_base = req->baud_base;
if ((info = state->info) != NULL) {
info->port = req->port;
info->flags = req->flags;
info->io_type = req->io_type;
info->iomem_base = req->iomem_base;
info->iomem_reg_shift = req->iomem_reg_shift;
}
autoconfig(state);
if (state->type == PORT_UNKNOWN) {
restore_flags(flags);
......@@ -4387,17 +4614,20 @@ void cleanup_module(void)
}
if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port)
release_region(rs_table[i].port, 8);
#if defined(ENABLE_SERIAL_PCI) && defined (CONFIG_SERIAL_PCI_MEMMAPPED)
#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
if (rs_table[i].iomem_base)
iounmap(rs_table[i].iomem_base);
#endif
}
#ifdef ENABLE_SERIAL_PCI
#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
for (i=0; i < serial_pci_board_idx; i++) {
struct pci_board_inst *brd = &serial_pci_board[i];
if (brd->board->init_fn)
(brd->board->init_fn)(brd->dev, brd->board, 0);
if (brd->board.init_fn)
(brd->board.init_fn)(brd->dev, &brd->board, 0);
if (DEACTIVATE_FUNC(brd->dev))
(DEACTIVATE_FUNC(brd->dev))(brd->dev);
}
#endif
if (tmp_buf) {
......@@ -4599,10 +4829,8 @@ static int __init serial_console_setup(struct console *co, char *options)
info->hub6 = state->hub6;
#endif
info->io_type = state->io_type;
#ifdef CONFIG_SERIAL_PCI_MEMMAPPED
info->iomem_base = state->iomem_base;
info->iomem_reg_shift = state->iomem_reg_shift;
#endif
quot = state->baud_base / baud;
cval = cflag & (CSIZE | CSTOPB);
#if defined(__powerpc__) || defined(__alpha__)
......
......@@ -28,6 +28,7 @@ static const char *cardname = "smctr";
#include <linux/version.h>
#endif
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
......
......@@ -91,7 +91,6 @@
#include <asm/uaccess.h>
#include <linux/if.h>
#include <linux/wanpipe.h>
#include <linux/sdla_ppp.h> /* PPP firmware API definitions */
#include <linux/sdlasfm.h> /* S514 Type Definition */
/****** Defines & Macros ****************************************************/
......
......@@ -84,6 +84,7 @@
#if defined(_LINUX_) /****** Linux *******************************/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h> /* printk(), and other useful stuff */
#include <linux/stddef.h> /* offsetof(), etc. */
......
......@@ -22,7 +22,6 @@
* instead. We should discuss this.
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
......
......@@ -25,6 +25,7 @@
* Added proper detection of the AHA-1640 (MCA version of AHA-1540)
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
......
......@@ -25,7 +25,6 @@
#include <linux/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include "scsi.h"
#include "hosts.h"
......
......@@ -25,7 +25,6 @@
#include <linux/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include "scsi.h"
#include "hosts.h"
......
......@@ -28,7 +28,6 @@
#include <linux/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include "scsi.h"
#include "hosts.h"
......
......@@ -24,7 +24,6 @@
#include <linux/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include "scsi.h"
#include "hosts.h"
......
......@@ -33,7 +33,6 @@
#include <linux/blk.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/init.h>
#include "scsi.h"
#include "hosts.h"
......
......@@ -495,13 +495,6 @@ probe_scanner(struct usb_device *dev, unsigned int ifnum)
return NULL;
}
ident = kmalloc(256, GFP_KERNEL);
if (ident) {
usb_string(dev, dev->descriptor.iProduct, ident, 256);
info("USB Scanner (%s) found at address %d", ident, dev->devnum);
kfree(ident);
}
hps->present = 1;
hps->hpscan_dev = dev;
......
......@@ -165,6 +165,8 @@ void usb_show_string(struct usb_device *dev, char *id, int index)
{
char *buf;
if (!index)
return;
if (!(buf = kmalloc(256, GFP_KERNEL)))
return;
if (usb_string(dev, index, buf, 256) > 0)
......
......@@ -1579,13 +1579,17 @@ int usb_get_configuration(struct usb_device *dev)
return result;
}
/*
* usb_string:
* returns string length (> 0) or error (< 0)
*/
int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
{
unsigned char *tbuf;
int err;
unsigned int u, idx;
if (size <= 0 || !buf)
if (size <= 0 || !buf || !index)
return -EINVAL;
buf[0] = 0;
tbuf = kmalloc(256, GFP_KERNEL);
......@@ -1602,15 +1606,15 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
err = usb_get_string(dev, dev->string_langid, index, tbuf, tbuf[0]);
if (err < 0)
goto errout;
size--;
for (idx = 0, u = 2; u < tbuf[0]; u += 2) {
size--; /* leave room for trailing NULL char in output buffer */
for (idx = 0, u = 2; u < err; u += 2) {
if (idx >= size)
break;
if (tbuf[u+1]) {
buf[idx++] = '?'; /* non ASCII character */
continue;
}
buf[idx++] = tbuf[u];
if (tbuf[u+1]) /* high byte */
buf[idx++] = '?'; /* non-ASCII character */
else
buf[idx++] = tbuf[u];
}
buf[idx] = 0;
err = idx;
......@@ -1721,9 +1725,12 @@ int usb_new_device(struct usb_device *dev)
info("USB device number %d default language ID 0x%x", dev->devnum, dev->string_langid);
}
usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
usb_show_string(dev, "Product", dev->descriptor.iProduct);
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
if (dev->descriptor.iManufacturer)
usb_show_string(dev, "Manufacturer", dev->descriptor.iManufacturer);
if (dev->descriptor.iProduct)
usb_show_string(dev, "Product", dev->descriptor.iProduct);
if (dev->descriptor.iSerialNumber)
usb_show_string(dev, "SerialNumber", dev->descriptor.iSerialNumber);
/* now that the basic setup is over, add a /proc/bus/usb entry */
usbdevfs_add_device(dev);
......
......@@ -1264,6 +1264,7 @@ int usb_stor_proc_info (char *buffer, char **start, off_t offset,
SPRINTF("%s\n", tmp_ptr);
else
SPRINTF("Unknown Product\n");
kfree(tmp_ptr);
}
SPRINTF(" Protocol: ");
......@@ -1494,9 +1495,15 @@ static void * storage_probe(struct usb_device *dev, unsigned int ifnum)
/* clear the GUID and fetch the strings */
GUID_CLEAR(guid);
usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf));
usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod));
usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial));
memset(mf, 0, sizeof(mf));
memset(prod, 0, sizeof(prod));
memset(serial, 0, sizeof(serial));
if (dev->descriptor.iManufacturer)
usb_string(dev, dev->descriptor.iManufacturer, mf, sizeof(mf));
if (dev->descriptor.iProduct)
usb_string(dev, dev->descriptor.iProduct, prod, sizeof(prod));
if (dev->descriptor.iSerialNumber)
usb_string(dev, dev->descriptor.iSerialNumber, serial, sizeof(serial));
/* let's examine the device now */
......
......@@ -114,7 +114,6 @@ int iso_date(char * p, int flag)
crtime = 0;
} else {
int monlen[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
extern struct timezone sys_tz;
days = year * 365;
if (year > 2)
......
......@@ -1341,7 +1341,7 @@ asmlinkage long sys_rename(const char * oldname, const char * newname)
return error;
}
int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, char *link)
int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link)
{
u32 len;
......@@ -1359,7 +1359,7 @@ int vfs_readlink(struct dentry *dentry, char *buffer, int buflen, char *link)
static inline struct dentry *
__vfs_follow_link(struct dentry *dentry, struct dentry *base,
unsigned follow, char *link)
unsigned follow, const char *link)
{
struct dentry *result;
UPDATE_ATIME(dentry->d_inode);
......@@ -1377,7 +1377,7 @@ __vfs_follow_link(struct dentry *dentry, struct dentry *base,
struct dentry *
vfs_follow_link(struct dentry *dentry, struct dentry *base,
unsigned int follow, char *link)
unsigned int follow, const char *link)
{
return __vfs_follow_link(dentry,base,follow,link);
}
......
......@@ -306,11 +306,12 @@ asmlinkage long sys_access(const char * filename, int mode)
struct dentry * dentry;
int old_fsuid, old_fsgid;
kernel_cap_t old_cap;
int res = -EINVAL;
int res;
if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */
return -EINVAL;
lock_kernel();
if (mode != (mode & S_IRWXO)) /* where's F_OK, X_OK, W_OK, R_OK? */
goto out;
old_fsuid = current->fsuid;
old_fsgid = current->fsgid;
old_cap = current->cap_effective;
......@@ -337,7 +338,7 @@ asmlinkage long sys_access(const char * filename, int mode)
current->fsuid = old_fsuid;
current->fsgid = old_fsgid;
current->cap_effective = old_cap;
out:
unlock_kernel();
return res;
}
......
......@@ -61,6 +61,9 @@
# define TIOCM_DSR 0x100
# define TIOCM_CD TIOCM_CAR
# define TIOCM_RI TIOCM_RNG
# define TIOCM_OUT1 0x2000
# define TIOCM_OUT2 0x4000
# define TIOCM_LOOP 0x8000
#define TIOCGSOFTCAR 0x5419
#define TIOCSSOFTCAR 0x541A
......
......@@ -45,6 +45,7 @@ struct termio {
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
......
......@@ -35,6 +35,7 @@ struct termio {
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
......
......@@ -8,7 +8,6 @@
#ifndef _ASM_APOLLO_DMA_H
#define _ASM_APOLLO_DMA_H
#include <linux/config.h>
#include <asm/apollohw.h> /* need byte IO */
#include <asm/spinlock.h> /* And spinlocks */
#include <linux/delay.h>
......
#ifndef _M68K_DMA_H
#define _M68K_DMA_H 1
#include <linux/config.h>
/* it's useless on the m68k, but unfortunately needed by the new
bootmem allocator (but this should do it for this) */
#define MAX_DMA_ADDRESS PAGE_OFFSET
......
......@@ -43,6 +43,9 @@ struct termio {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
......
......@@ -83,6 +83,7 @@ struct termio {
#define TIOCM_DSR 0x400 /* data set ready */
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* line disciplines */
#define N_TTY 0
......
......@@ -166,6 +166,9 @@ struct termio {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
......
......@@ -203,6 +203,9 @@ struct termios {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
......
......@@ -204,6 +204,9 @@ struct termios {
#define TIOCM_DSR 0x100
#define TIOCM_CD TIOCM_CAR
#define TIOCM_RI TIOCM_RNG
#define TIOCM_OUT1 0x2000
#define TIOCM_OUT2 0x4000
#define TIOCM_LOOP 0x8000
/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
......
......@@ -24,7 +24,6 @@
#include <linux/types.h>
#include <linux/ioctl.h>
#ifdef __KERNEL__
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/wait.h>
#endif /* __KERNEL__ */
......
......@@ -998,8 +998,8 @@ extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *);
extern ssize_t generic_file_write(struct file *, const char *, size_t, loff_t *, writepage_t);
extern void do_generic_file_read(struct file *, loff_t *, read_descriptor_t *, read_actor_t);
extern int vfs_readlink(struct dentry *, char *, int, char *);
extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, char *);
extern int vfs_readlink(struct dentry *, char *, int, const char *);
extern struct dentry *vfs_follow_link(struct dentry *, struct dentry *, unsigned, const char *);
extern int page_readlink(struct dentry *, char *, int);
extern struct dentry *page_follow_link(struct dentry *, struct dentry *, unsigned);
......
......@@ -90,7 +90,7 @@ extern struct kernel_param __setup_start, __setup_end;
#define __exit
#define __initdata
#define __exitdata
#define __initcall
#define __initcall(fn)
/* For assembly routines */
#define __INIT
#define __FINIT
......
......@@ -828,6 +828,7 @@
#define PCI_VENDOR_ID_ATT 0x11c1
#define PCI_DEVICE_ID_ATT_L56XMF 0x0440
#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480
#define PCI_VENDOR_ID_SPECIALIX 0x11cb
#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000
......@@ -1019,7 +1020,15 @@
#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a
#define PCI_VENDOR_ID_LAVA 0x1407
#define PCI_DEVICE_ID_LAVA_DUAL_SERIAL 0x0100
#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */
#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */
#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */
#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */
#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */
#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */
#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */
#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */
#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */
#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */
......@@ -1030,6 +1039,8 @@
#define PCI_VENDOR_ID_OXSEMI 0x1415
#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501
#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x950A
#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511
#define PCI_VENDOR_ID_PANACOM 0x14d4
#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400
......
......@@ -21,6 +21,7 @@
#ifndef _LINUX_PM_H
#define _LINUX_PM_H
#include <linux/config.h>
#include <linux/list.h>
/*
......
......@@ -37,20 +37,6 @@ struct serial_struct {
#define ASYNC_CLOSING_WAIT_INF 0
#define ASYNC_CLOSING_WAIT_NONE 65535
/*
* The size of the serial xmit buffer is 1 page, or 4096 bytes
*/
#define SERIAL_XMIT_SIZE 4096
/*
* Counters of the input lines (CTS, DSR, RI, CD) interrupts
*/
struct async_icount {
__u32 cts, dsr, rng, dcd, tx, rx;
__u32 frame, parity, overrun, brk;
__u32 buf_overrun;
};
/*
* These are the supported serial types.
*/
......
......@@ -19,11 +19,18 @@
* For definitions of the flags field, see tty.h
*/
#include <linux/config.h>
#include <linux/termios.h>
#include <linux/tqueue.h>
#include <linux/wait.h>
/*
* Counters of the input lines (CTS, DSR, RI, CD) interrupts
*/
struct async_icount {
__u32 cts, dsr, rng, dcd, tx, rx;
__u32 frame, parity, overrun, brk;
__u32 buf_overrun;
};
struct serial_state {
int magic;
......@@ -158,7 +165,7 @@ struct pci_board {
};
struct pci_board_inst {
struct pci_board *board;
struct pci_board board;
struct pci_dev *dev;
};
......@@ -172,7 +179,28 @@ struct pci_board_inst {
#define SPCI_FL_BASE2 0x0002
#define SPCI_FL_BASE3 0x0003
#define SPCI_FL_BASE4 0x0004
#define SPCI_FL_IOMEM 0x0008 /* Use I/O mapped memory */
#define SPCI_FL_BASE_TABLE 0x0010 /* Use base address table for UART */
#define SPCI_FL_GET_BASE(x) (x & SPCI_FL_BASE_MASK)
#define SPCI_FL_IRQ_MASK (0x0007 << 4)
#define SPCI_FL_IRQBASE0 (0x0000 << 4)
#define SPCI_FL_IRQBASE1 (0x0001 << 4)
#define SPCI_FL_IRQBASE2 (0x0002 << 4)
#define SPCI_FL_IRQBASE3 (0x0003 << 4)
#define SPCI_FL_IRQBASE4 (0x0004 << 4)
#define SPCI_FL_GET_IRQBASE(x) ((x & SPCI_FL_IRQ_MASK) >> 4)
/* Use sucessiveentries base resource table */
#define SPCI_FL_BASE_TABLE 0x0100
/* Use successive entries in the irq resource table */
#define SPCI_FL_IRQ_TABLE 0x0200
/* Use the irq resource table instead of dev->irq */
#define SPCI_FL_IRQRESOURCE 0x0400
/* Use the Base address register size to cap number of ports */
#define SPCI_FL_REGION_SZ_CAP 0x0800
#define SPCI_FL_PNPDEFAULT (SPCI_FL_IRQRESOURCE)
#endif /* _LINUX_SERIAL_H */
Started Jan 2000 by Kanoj Sarcar <kanoj@sgi.com>
Memory balancing is needed for non __GFP_WAIT as well as for non
__GFP_IO allocations.
There are two reasons to be requesting non __GFP_WAIT allocations:
the caller can not sleep (typically intr context), or does not want
to incur cost overheads of page stealing and possible swap io for
whatever reasons.
__GFP_IO allocation requests are made to prevent file system deadlocks.
In the absence of non sleepable allocation requests, it seems detrimental
to be doing balancing. Page reclamation can be kicked off lazily, that
is, only when needed (aka zone free memory is 0), instead of making it
a proactive process.
That being said, the kernel should try to fulfill requests for direct
mapped pages from the direct mapped pool, instead of falling back on
the dma pool, so as to keep the dma pool filled for dma requests (atomic
or not). A similar argument applies to highmem and direct mapped pages.
OTOH, if there is a lot of free dma pages, it is preferable to satisfy
regular memory requests by allocating one from the dma pool, instead
of incurring the overhead of regular zone balancing.
In 2.2, memory balancing/page reclamation would kick off only when the
_total_ number of free pages fell below 1/64 th of total memory. With the
right ratio of dma and regular memory, it is quite possible that balancing
would not be done even when the dma zone was completely empty. 2.2 has
been running production machines of varying memory sizes, and seems to be
doing fine even with the presence of this problem. In 2.3, due to
HIGHMEM, this problem is aggravated.
In 2.3, zone balancing can be done in one of two ways: depending on the
zone size (and possibly of the size of lower class zones), we can decide
at init time how many free pages we should aim for while balancing any
zone. The good part is, while balancing, we do not need to look at sizes
of lower class zones, the bad part is, we might do too frequent balancing
due to ignoring possibly lower usage in the lower class zones. Also,
with a slight change in the allocation routine, it is possible to reduce
the memclass() macro to be a simple equality.
Another possible solution is that we balance only when the free memory
of a zone _and_ all its lower class zones falls below 1/64th of the
total memory in the zone and its lower class zones. This fixes the 2.2
balancing problem, and stays as close to 2.2 behavior as possible. Also,
the balancing algorithm works the same way on the various architectures,
which have different numbers and types of zones. If we wanted to get
fancy, we could assign different weights to free pages in different
zones in the future.
Note that if the size of the regular zone is huge compared to dma zone,
it becomes less significant to consider the free dma pages while
deciding whether to balance the regular zone. The first solution
becomes more attractive then.
The appended patch implements the second solution. It also "fixes" two
problems: first, kswapd is woken up as in 2.2 on low memory conditions
for non-sleepable allocations. Second, the HIGHMEM zone is also balanced,
so as to give a fighting chance for replace_with_highmem() to get a
HIGHMEM page, as well as to ensure that HIGHMEM allocations do not
fall back into regular zone. This also makes sure that HIGHMEM pages
are not leaked (for example, in situations where a HIGHMEM page is in
the swapcache but is not being used by anyone)
kswapd also needs to know about the zones it should balance. kswapd is
primarily needed in a situation where balancing can not be done,
probably because all allocation requests are coming from intr context
and all process contexts are sleeping. For 2.3, kswapd does not really
need to balance the highmem zone, since intr context does not request
highmem pages. A zone aware kswapd still needs to be implemented.
Page stealing from process memory and shm is done if stealing the page would
alleviate memory pressure on any zone in the page's node that has fallen below
its watermark.
(Good) Ideas that I have heard:
1. Dynamic experience should influence balancing: number of failed requests
for a zone can be tracked and fed into the balancing scheme (jalvo@mbay.net)
2. Implement a replace_with_highmem()-like replace_with_regular() to preserve
dma pages. (lkd@tantalophile.demon.co.uk)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment