Commit 433b8708 authored by Linus Torvalds's avatar Linus Torvalds

Import 2.3.20pre2

parent a3c57c1b
......@@ -1053,14 +1053,17 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d)
*/
if ((d->class >> 8) != PCI_CLASS_STORAGE_IDE)
return;
/* This just can't be right even with the fixes */
#if 0
DBG("PCI: IDE base address fixup for %s\n", d->slot_name);
for(i=0; i<4; i += 2) {
for(i=0; i<4; i++) {
struct resource *r = &d->resource[i];
if (r->start) {
if ((r->start & ~0x80) == 0x374) {
r->start += 2;
r->end = r->start;
}
}
#endif
}
struct pci_fixup pcibios_fixups[] = {
......
......@@ -11,7 +11,7 @@ SUB_DIRS := block char net parport sound misc
MOD_SUB_DIRS := $(SUB_DIRS)
ALL_SUB_DIRS := $(SUB_DIRS) pci sgi scsi sbus cdrom isdn pnp i2o \
macintosh video dio zorro fc4 usb \
nubus tc ap1000 atm
nubus tc ap1000 atm pcmcia
ifdef CONFIG_DIO
SUB_DIRS += dio
......@@ -22,8 +22,12 @@ ifdef CONFIG_PCI
SUB_DIRS += pci
endif
ifdef CONFIG_PCMCIA
ifeq ($(CONFIG_PCMCIA),y)
SUB_DIRS += pcmcia
else
ifeq ($(CONFIG_PCMCIA),m)
MOD_SUB_DIRS += pcmcia
endif
endif
ifdef CONFIG_SBUS
......@@ -117,7 +121,6 @@ endif
ifeq ($(CONFIG_AP1000),y)
SUB_DIRS += ap1000
ALL_SUB_DIRS += ap1000
endif
ifeq ($(CONFIG_FC4),y)
......
......@@ -34,8 +34,12 @@
* YIELD parport_yield_blocking
* WCTLONIRQ on interrupt, set control lines
* CLRIRQ clear (and return) interrupt count
* SETTIME sets device timeout (struct timeval)
* GETTIME gets device timeout (struct timeval)
* read/write read or write in current IEEE 1284 protocol
* select wait for interrupt (in readfds)
*
* Added SETTIME/GETTIME ioctl, Fred Barnes 1999.
*/
#include <linux/module.h>
......@@ -74,6 +78,9 @@ struct pp_struct {
#define PP_BUFFER_SIZE 256
#define PARDEVICE_MAX 8
/* ROUND_UP macro from fs/select.c */
#define ROUND_UP(x,y) (((x)+(y)-1)/(y))
static inline void enable_irq (struct pp_struct *pp)
{
struct parport *port = pp->pdev->port;
......@@ -356,6 +363,8 @@ static int pp_ioctl(struct inode *inode, struct file *file,
unsigned char mask;
int mode;
int ret;
struct timeval par_timeout;
long to_jiffies;
case PPRSTATUS:
reg = parport_read_status (port);
......@@ -451,6 +460,33 @@ static int pp_ioctl(struct inode *inode, struct file *file,
atomic_sub (ret, &pp->irqc);
return 0;
case PPSETTIME:
if (copy_from_user (&par_timeout, (struct timeval *)arg,
sizeof(struct timeval))) {
return -EFAULT;
}
/* Convert to jiffies, place in pp->pdev->timeout */
if ((par_timeout.tv_sec < 0) || (par_timeout.tv_usec < 0)) {
return -EINVAL;
}
to_jiffies = ROUND_UP(par_timeout.tv_usec, 1000000/HZ);
to_jiffies += par_timeout.tv_sec * (long)HZ;
if (to_jiffies <= 0) {
return -EINVAL;
}
pp->pdev->timeout = to_jiffies;
return 0;
case PPGETTIME:
to_jiffies = pp->pdev->timeout;
par_timeout.tv_sec = to_jiffies / HZ;
par_timeout.tv_usec = (to_jiffies % (long)HZ) * (1000000/HZ);
if (copy_to_user ((struct timeval *)arg, &par_timeout,
sizeof(struct timeval))) {
return -EFAULT;
}
return 0;
default:
printk (KERN_DEBUG CHRDEV "%x: What? (cmd=0x%x)\n", minor,
cmd);
......
......@@ -10,6 +10,7 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Added PPGETTIME/PPSETTIME, Fred Barnes, 1999
*/
#define PP_MAJOR 99
......@@ -72,3 +73,9 @@ struct ppdev_frob_struct {
/* Set the IEEE 1284 phase that we're in (e.g. IEEE1284_PH_FWD_IDLE) */
#define PPSETPHASE _IOW(PP_IOCTL, 0x94, int)
/* Set and get port timeout (struct timeval's) */
#define PPGETTIME _IOW(PP_IOCTL, 0x95, struct timeval)
#define PPSETTIME _IOR(PP_IOCTL, 0x96, struct timeval)
......@@ -91,6 +91,8 @@ static int __init parport_setup (char *str)
if (sep++) {
if (!strncmp (sep, "auto", 4))
dma[parport_setup_ptr] = PARPORT_DMA_AUTO;
else if (!strncmp (sep, "nofifo", 6))
dma[parport_setup_ptr] = PARPORT_DMA_NOFIFO;
else if (strncmp (sep, "none", 4)) {
val = simple_strtoul (sep, &endptr, 0);
if (endptr == sep) {
......
......@@ -1604,7 +1604,8 @@ struct parport *__maybe_init parport_pc_probe_port (unsigned long int base,
p->dma = PARPORT_DMA_NONE;
#ifdef CONFIG_PARPORT_PC_FIFO
if (priv->fifo_depth > 0 && p->irq != PARPORT_IRQ_NONE) {
if (p->dma != PARPORT_DMA_NOFIFO &&
priv->fifo_depth > 0 && p->irq != PARPORT_IRQ_NONE) {
p->ops->compat_write_data = parport_pc_compat_write_block_pio;
#ifdef CONFIG_PARPORT_1284
p->ops->ecp_write_data = parport_pc_ecp_write_block_pio;
......
......@@ -633,7 +633,7 @@ void parport_release(struct pardevice *dev)
}
static int parport_parse_params (int nports, const char *str[], int val[],
int automatic, int none)
int automatic, int none, int nofifo)
{
unsigned int i;
for (i = 0; i < nports && str[i]; i++) {
......@@ -641,6 +641,8 @@ static int parport_parse_params (int nports, const char *str[], int val[],
val[i] = automatic;
else if (!strncmp(str[i], "none", 4))
val[i] = none;
else if (nofifo && !strncmp(str[i], "nofifo", 4))
val[i] = nofifo;
else {
char *ep;
unsigned long r = simple_strtoul(str[i], &ep, 0);
......@@ -659,11 +661,11 @@ static int parport_parse_params (int nports, const char *str[], int val[],
int parport_parse_irqs(int nports, const char *irqstr[], int irqval[])
{
return parport_parse_params (nports, irqstr, irqval, PARPORT_IRQ_AUTO,
PARPORT_IRQ_NONE);
PARPORT_IRQ_NONE, 0);
}
int parport_parse_dmas(int nports, const char *dmastr[], int dmaval[])
{
return parport_parse_params (nports, dmastr, dmaval, PARPORT_DMA_AUTO,
PARPORT_DMA_NONE);
PARPORT_DMA_NONE, PARPORT_DMA_NOFIFO);
}
......@@ -25,7 +25,7 @@ ifdef CONFIG_PROC_FS
L_OBJS += proc.o
endif
L_OBJS += compat.o quirks.o names.o
L_OBJS += compat.o quirks.o names.o helper.o
ifndef CONFIG_X86
L_OBJS += syscall.o setup.o
......
/*
* $Id$
*
* drivers/pci/helper.c
*
* Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
* This software is free. See the file COPYING for licensing details.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
int pci_simple_probe (struct pci_simple_probe_entry *list, size_t match_limit,
pci_simple_probe_callback cb, void *drvr_data)
{
struct pci_dev *dev;
struct pci_simple_probe_entry *ent;
size_t matches = 0;
unsigned short vendor, device;
int rc;
if (!list || !cb)
return -1;
dev = pci_find_device (PCI_ANY_ID, PCI_ANY_ID, NULL);
while (dev) {
ent = list;
while (ent->vendor && ent->device) {
vendor = ent->vendor;
device = ent->device;
if (((vendor != 0xFFFF) &&
(vendor != dev->vendor)) ||
((device != 0xFFFF) &&
(device != dev->device))) {
ent++;
continue;
}
if (((ent->subsys_vendor) &&
(ent->subsys_vendor != dev->subsystem_vendor)) ||
((ent->subsys_device) &&
(ent->subsys_device != dev->subsystem_device))) {
ent++;
continue;
}
rc = (* cb) (dev, matches, ent, drvr_data);
if (rc < 0)
return rc;
matches++;
if (match_limit && match_limit == matches)
return matches;
ent++;
}
dev = pci_find_device (PCI_ANY_ID, PCI_ANY_ID, dev);
}
return matches;
}
......@@ -58,6 +58,8 @@
* replaced current->state = x with set_current_state(x)
* 03.09.99 0.8 change read semantics for MIDI to match
* OSS more closely; remove possible wakeup race
* 07.10.99 0.9 Fix initialization; complain if sequencer writes time out
* Revised resource grabbing for the FM synthesizer
*
*/
......@@ -108,6 +110,7 @@
#define MPUBASE_EXTENT 4
#define GPBASE_EXTENT 4
#define FMSYNTH_EXTENT 4
/* MIDI buffer sizes */
......@@ -207,7 +210,7 @@ extern inline void write_seq(struct solo1_state *s, unsigned char data)
{
int i;
unsigned long flags;
/* the __cli stunt is to send the data within the command window */
for (i = 0; i < 0xffff; i++) {
__save_flags(flags);
......@@ -219,6 +222,8 @@ extern inline void write_seq(struct solo1_state *s, unsigned char data)
}
__restore_flags(flags);
}
printk(KERN_ERR "esssolo1: write_seq timeout\n");
outb(data, s->sbbase+0xc);
}
extern inline int read_seq(struct solo1_state *s, unsigned char *data)
......@@ -232,6 +237,7 @@ extern inline int read_seq(struct solo1_state *s, unsigned char *data)
*data = inb(s->sbbase+0xa);
return 1;
}
printk(KERN_ERR "esssolo1: read_seq timeout\n");
return 0;
}
......@@ -1993,6 +1999,12 @@ static int solo1_dmfm_open(struct inode *inode, struct file *file)
return -ERESTARTSYS;
down(&s->open_sem);
}
if (check_region(s->sbbase, FMSYNTH_EXTENT)) {
up(&s->open_sem);
printk(KERN_ERR "solo1: FM synth io ports in use, opl3 loaded?\n");
return -EBUSY;
}
request_region(s->sbbase, FMSYNTH_EXTENT, "ESS Solo1");
/* init the stuff */
outb(1, s->sbbase);
outb(0x20, s->sbbase+1); /* enable waveforms */
......@@ -2020,6 +2032,7 @@ static int solo1_dmfm_release(struct inode *inode, struct file *file)
outb(regb, s->sbbase+2);
outb(0, s->sbbase+3);
}
release_region(s->sbbase, FMSYNTH_EXTENT);
up(&s->open_sem);
wake_up(&s->open_wait);
MOD_DEC_USE_COUNT;
......@@ -2113,14 +2126,14 @@ static int __init init_solo1(void)
s->gpbase = RSRCADDRESS(pcidev, 4);
s->irq = pcidev->irq;
if (check_region(s->iobase, IOBASE_EXTENT) ||
check_region(s->sbbase+4, SBBASE_EXTENT-4) ||
check_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT) ||
check_region(s->ddmabase, DDMABASE_EXTENT) ||
check_region(s->mpubase, MPUBASE_EXTENT)) {
printk(KERN_ERR "solo1: io ports in use\n");
goto err_region;
}
request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1");
request_region(s->sbbase+4, SBBASE_EXTENT-4, "ESS Solo1"); /* allow OPL3 synth module */
request_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT, "ESS Solo1");
request_region(s->ddmabase, DDMABASE_EXTENT, "ESS Solo1");
request_region(s->mpubase, MPUBASE_EXTENT, "ESS Solo1");
if (request_irq(s->irq, solo1_interrupt, SA_SHIRQ, "ESS Solo1", s)) {
......@@ -2147,6 +2160,10 @@ static int __init init_solo1(void)
if ((s->dev_dmfm = register_sound_special(&solo1_dmfm_fops, 15 /* ?? */)) < 0)
goto err_dev4;
/* initialize the chips */
if (!reset_ctrl(s)) {
printk(KERN_ERR "esssolo1: cannot reset controller\n");
goto err;
}
outb(0xb0, s->iobase+7); /* enable A1, A2, MPU irq's */
/* initialize mixer regs */
......@@ -2181,6 +2198,8 @@ static int __init init_solo1(void)
index++;
continue;
err:
unregister_sound_dsp(s->dev_dmfm);
err_dev4:
unregister_sound_dsp(s->dev_midi);
err_dev3:
......@@ -2192,7 +2211,7 @@ static int __init init_solo1(void)
free_irq(s->irq, s);
err_irq:
release_region(s->iobase, IOBASE_EXTENT);
release_region(s->sbbase+4, SBBASE_EXTENT-4);
release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
release_region(s->ddmabase, DDMABASE_EXTENT);
release_region(s->mpubase, MPUBASE_EXTENT);
err_region:
......@@ -2222,7 +2241,7 @@ static void __exit cleanup_solo1(void)
pci_write_config_word(s->pcidev, 0x60, 0); /* turn off DDMA controller address space */
free_irq(s->irq, s);
release_region(s->iobase, IOBASE_EXTENT);
release_region(s->sbbase+4, SBBASE_EXTENT-4);
release_region(s->sbbase+FMSYNTH_EXTENT, SBBASE_EXTENT-FMSYNTH_EXTENT);
release_region(s->ddmabase, DDMABASE_EXTENT);
release_region(s->mpubase, MPUBASE_EXTENT);
unregister_sound_dsp(s->dev_audio);
......
......@@ -13,6 +13,7 @@
#define PARPORT_DMA_NONE -1
#define PARPORT_IRQ_AUTO -2
#define PARPORT_DMA_AUTO -2
#define PARPORT_DMA_NOFIFO -3
#define PARPORT_DISABLE -2
#define PARPORT_IRQ_PROBEONLY -3
......
......@@ -470,6 +470,28 @@ void pci_set_bus_ranges(void);
void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *),
int (*)(struct pci_dev *, u8, u8));
/*
* simple PCI probing for drivers
*/
struct pci_simple_probe_entry;
typedef int (*pci_simple_probe_callback) (struct pci_dev *dev, int match_num,
const struct pci_simple_probe_entry *ent,
void *drvr_data);
struct pci_simple_probe_entry {
unsigned short vendor; /* vendor id, PCI_ANY_ID, or 0 for last entry */
unsigned short device; /* device id, PCI_ANY_ID, or 0 for last entry */
unsigned short subsys_vendor; /* subsystem vendor id, 0 for don't care */
unsigned short subsys_device; /* subsystem device id, 0 for don't care */
void *dev_data; /* driver-private, entry-specific data */
};
int pci_simple_probe (struct pci_simple_probe_entry *list, size_t match_limit,
pci_simple_probe_callback cb, void *drvr_data);
/*
* If the system does not have PCI, clearly these return errors. Define
* these as simple inline functions to avoid hair in drivers.
......@@ -505,6 +527,9 @@ unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from)
extern inline void pci_set_master(struct pci_dev *dev)
{ return; }
extern inline int pci_simple_probe (struct pci_simple_probe_entry *list, size_t match_limit,
pci_simple_probe_callback cb, void *drvr_data)
{ return 0; }
#endif /* !CONFIG_PCI */
......
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