The ISDN code in the stock 2.2 kernel may not work for you. If it
doesn't, look in ftp://ftp.suse.com/pub/isdn4linux for updated versions.
+ In 2.0.x the kernel could be configured to drop source routed IP
+packets via a compile time configuration option. In 2.2.x, this has
+been replaced by a sysctl. See Documentation/networking/ip-sysctl.txt
+for more information.
+
Memory
======
larger swap spaces, you need the new mkswap found in util-linux. You
also need to upgrade util-linux to get the latest version of mount.
+ Partitions on 2048 byte sectored media (certain magneto opticals
+most prominently) were broken throughout the whole of 2.1 kernel
+series, meaning that you will be unable to use 2.1-partitioned media on
+Linux 2.2. This is not a 2.2 bug - 2.2 finally does the right thing!
+[If you have to interchange media between Linux 2.1 and 2.2, your best
+bet is to not use partitions at all but create the filesystem on the
+raw device (e.g. /dev/sda) instead. This is also known as the
+superfloppy format.]
+
+ To properly create partitions on 2048 byte sectored media with Linux
+2.2, be sure to use no less than fdisk version 2.9i and invoke fdisk
+using '-b 2048' as an option.
+
+
RPM
===
--- /dev/null
+In Documentation/sound/README.OSS was a remark saying noone was sure the
+mixer on the PCM1-pro worked with the ACI driver. Well, it does.
+I've been using the drivers for the MAD16 and the driver for the mixer
+since kernel 2.0.32 with a MiroSound PCM1-pro and it works great.
+
+I've got it working with the following configuration:
+
+MAD16 audio I/O base = 530
+MAD16 audio IRQ = 7
+MAD16 Audio DMA = 1
+MAD16 MIDI I/O = 330
+MAD16 MIDI IRQ = 9
+
+And I've enabled the ACI mixer (miro PCM12) .
+
+
+Bas van der Linden.
How to try to survive an IBM Mwave under Linux SB drivers
-* IBM refuses to provide documentation. If anyone can ever find out what
- MWD50430.EXE actually does to load firmware then this comedy could go
- away.
-
-* If you'd like to ask IBM why they don't release Mwave information.
- phone IBM (425-556-8822) and ask them why they still haven't
- released any documentation.
- [http://204.200.238.31/cgi-bin/link.pl?co=i&cl=/ts/ibm/contact.html]
++ IBM have now released documentation of sorts and Torsten is busy
+ trying to make the Mwave work. This is not however a trivial task.
----------------------------------------------------------------------------
ifeq ($(CONFIG_BLK_DEV_PS2),y)
L_OBJS += ps2esdi.o
+else
+ ifeq ($(CONFIG_BLK_DEV_PS2),m)
+ M_OBJS += ps2esdi.o
+ endif
endif
ifeq ($(CONFIG_BLK_DEV_XD),y)
#endif /* CONFIG_SUN_PARTITION */
#ifdef CONFIG_SGI_PARTITION
+#include <asm/byteorder.h>
static int sgi_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
{
int i, csum;
unsigned int *ui;
+ unsigned int start, blocks, cs;
+ int magic;
struct buffer_head *bh;
struct sgi_disklabel {
int magic_mushroom; /* Big fat spliff... */
}
label = (struct sgi_disklabel *) bh->b_data;
p = &label->partitions[0];
- if(label->magic_mushroom != SGI_LABEL_MAGIC) {
+ magic = label->magic_mushroom;
+ if(be32_to_cpu(magic) != SGI_LABEL_MAGIC) {
printk("Dev %s SGI disklabel: bad magic %08x\n",
- kdevname(dev), label->magic_mushroom);
+ kdevname(dev), magic);
brelse(bh);
return 0;
}
ui = ((unsigned int *) (label + 1)) - 1;
- for(csum = 0; ui >= ((unsigned int *) label);)
- csum += *ui--;
+ for(csum = 0; ui >= ((unsigned int *) label);) {
+ cs = *ui--;
+ csum += be32_to_cpu(cs);
+ }
if(csum) {
printk("Dev %s SGI disklabel: csum bad, label corrupted\n",
kdevname(dev));
* current_minor.
*/
for(i = 0; i < 16; i++, p++) {
- if(!(p->num_blocks))
+ blocks = be32_to_cpu(p->num_blocks);
+ start = be32_to_cpu(p->first_block);
+ if(!blocks)
continue;
- add_partition(hd, current_minor, p->first_block, p->num_blocks);
+ add_partition(hd, current_minor, start, blocks);
current_minor++;
}
printk("\n");
CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
- else if (!strcmp (drive->id->model, "GCD-R580B"))
- CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
- /* 124/SECTORS_PER_FRAME; ? */
}
#if ! STANDARD_ATAPI
fi
fi
tristate 'Mitsumi (standard) [no XA/Multisession] CDROM support' CONFIG_MCD
+if [ "$CONFIG_MCD" != "n" ]; then
+ int 'MCD IRQ' CONFIG_MCD_IRQ 11
+ hex 'MCD I/O base' CONFIG_MCD_BASE 300
+fi
tristate 'Mitsumi [XA/MultiSession] CDROM support' CONFIG_MCDX
tristate 'Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD
tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206
a CD.
November 1997 -- ported to the Uniform CD-ROM driver by Erik Andersen.
+ March 1999 -- made io base and irq CONFIG_ options (Tigran Aivazian).
*/
#include <linux/module.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/config.h>
/* #define REALLY_SLOW_IO */
#include <asm/system.h>
int mitsumi_bug_93_wait = 0;
#endif /* WORK_AROUND_MITSUMI_BUG_93 */
-static short mcd_port = MCD_BASE_ADDR; /* used as "mcd" by "insmod" */
-static int mcd_irq = MCD_INTR_NR; /* must directly follow mcd_port */
+static short mcd_port = CONFIG_MCD_BASE; /* used as "mcd" by "insmod" */
+static int mcd_irq = CONFIG_MCD_IRQ; /* must directly follow mcd_port */
MODULE_PARM(mcd, "1-2i");
static int McdTimeout, McdTries;
*
*/
-/* *** change this to set the I/O port address */
-#define MCD_BASE_ADDR 0x300
-
-/* *** change this to set the interrupt number */
-#define MCD_INTR_NR 11
-
-/* *** make the following line uncommented, if you're sure,
- * *** all configuration is done */
-
-/* #define I_WAS_HERE */
-
-
-
-
/* Increase this if you get lots of timeouts */
#define MCD_STATUS_DELAY 1000
struct msf trackTime;
struct msf diskTime;
};
-
-#ifndef I_WAS_HERE
-#warning You have not edited mcd.h
-#warning Perhaps irq and i/o settings are wrong.
-#endif
* Allow only to set io base address on command line: sjcd=<io_base>
* Changes to Documentation/cdrom/sjcd
* Added cleanup after any error in the initialisation.
+ * 1.7 Added code to set the sector size tables to prevent the bug present in
+ * the previous version of this driver. Coded added by Anthony Barbachan
+ * from bugfix tip originally suggested by Alan Cox.
*
*/
#define SJCD_VERSION_MAJOR 1
-#define SJCD_VERSION_MINOR 6
+#define SJCD_VERSION_MINOR 7
#ifdef MODULE
#include <linux/module.h>
NULL /* revalidate */
};
+static int blksize = 2048;
+static int secsize = 2048;
+
/*
* Following stuff is intended for initialization of the cdrom. It
* first looks for presence of device. If the device is present, it
printk("SJCD: sjcd=0x%x: ", sjcd_base);
#endif
+ hardsect_size[MAJOR_NR] = &secsize;
+ blksize_size[MAJOR_NR] = &blksize;
+
if( register_blkdev( MAJOR_NR, "sjcd", &sjcd_fops ) != 0 ){
printk( "SJCD: Unable to get major %d for Sanyo CD-ROM\n", MAJOR_NR );
return( -EIO );
{ 3, 1, 0, 2, 7, { 2, 3, 1, 1}, { 0, 1, 2, 3, 4}},
/* Zoltrix TV-Max */
{ 3, 1, 0, 2,15, { 2, 3, 1, 1}, { 0, 0, 0, 0, 0}},
+ /* Pixelview PlayTV (bt878) */
+ { 3, 4, 0, 2, 0x01e000, { 2, 0, 1, 1}, {0x01c000, 0, 0x018000, 0x014000, 0x002000, 0 }},
};
#define TVCARDS (sizeof(tvcards)/sizeof(tvcard))
btv->user--;
btv->radio = 0;
- audio(btv, AUDIO_MUTE);
+ /*audio(btv, AUDIO_MUTE);*/
MOD_DEC_USE_COUNT;
}
btv->pll.pll_crystal=BT848_IFORM_XT0;
}
}
+
+ if (btv->type == BTTV_PIXVIEWPLAYTV) {
+ btv->pll.pll_ifreq=28636363;
+ btv->pll.pll_crystal=BT848_IFORM_XT0;
+ }
+
if(btv->type==BTTV_AVERMEDIA98)
{
btv->pll.pll_ifreq=28636363;
#define BTTV_AVERMEDIA98 0x0d
#define BTTV_VHX 0x0e
#define BTTV_ZOLTRIX 0x0f
+#define BTTV_PIXVIEWPLAYTV 0x10
#define AUDIO_TUNER 0x00
#define AUDIO_RADIO 0x01
#ifdef ISICOM_DEBUG
printk(KERN_DEBUG "ISILoad:Firmware loader Opened!!!\n");
#endif
+ MOD_INC_USE_COUNT;
return 0;
}
#ifdef ISICOM_DEBUG
printk(KERN_DEBUG "ISILoad:Firmware loader Close(Release)d\n",);
#endif
+ MOD_DEC_USE_COUNT;
return 0;
}
default:
return -ENOIOCTLCMD;
case WDIOC_GETSUPPORT:
- i = verify_area(VERIFY_WRITE, (void*) arg, sizeof(struct watchdog_info));
- if (i)
- return i;
- else
- return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
+ if(copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident)))
+ return -EFAULT;
+ return 0;
case WDIOC_GETSTATUS:
case WDIOC_GETBOOTSTATUS:
return put_user(0,(int *)arg);
** *************************************************************************
**
**
-** R C L A N M T L . C $Revision: 5 $
+** R C L A N M T L . C $Revision: 6 $
**
**
** RedCreek I2O LAN Message Transport Layer program module.
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** 1998-1999, LAN API was modified and enhanced by Alice Hennessy.
+**
+** Sometime in 1997, LAN API was written from scratch by Wendell Nichols.
** *************************************************************************
*/
/* Special TID Assignments */
#define I2O_IOP_TID 0
-#define I2O_HOST_TID 1
+#define I2O_HOST_TID 0xB91
/* RedCreek I2O private message codes */
#define RC_PRIVATE_GET_MAC_ADDR 0x0001/**/ /* OBSOLETE */
** *************************************************************************
**
**
-** R C L A N M T L . H $Revision: 5 $
+** R C L A N M T L . H $Revision: 6 $
**
**
** RedCreek I2O LAN Message Transport Layer header file.
/*
+**
** RCpci45.c
**
**
**
**
** Pete Popov, January 11,99: Fixed a couple of 2.1.x problems
-** (virt_to_bus() not called), tested it under 2.2pre5, and added a
-** #define to enable the use of the same file for both, the 2.0.x kernels
-** as well as the 2.1.x.
+** (virt_to_bus() not called), tested it under 2.2pre5 (as a module), and
+** added a #define(s) to enable the use of the same file for both, the 2.0.x
+** kernels as well as the 2.1.x.
**
** Ported to 2.1.x by Alan Cox 1998/12/9.
**
+** Sometime in mid 1998, written by Pete Popov and Brian Moyle.
+**
***************************************************************************/
static char *version =
-"RedCreek Communications PCI linux driver version 2.00\n";
+"RedCreek Communications PCI linux driver version 2.02\n";
#include <linux/module.h>
};
-static int RCscan(void);
-static struct device
-*RCfound_device(struct device *, int, int, int, int, int, int);
+static int RCinit(struct device *dev);
+static int RCscan(struct device *dev);
+static int RCfound_device(struct device *, int, int, int, int, int, int);
-static int RCprobe1(struct device *);
static int RCopen(struct device *);
static int RC_xmit_packet(struct sk_buff *, struct device *);
static void RCinterrupt(int, void *, struct pt_regs *);
#ifdef MODULE
int init_module(void)
#else
-int rcpci_probe(struct netdevice *dev)
+int rcpci_probe(struct device *dev)
#endif
{
int cards_found;
- printk(version);
-
- root_RCdev = NULL;
- cards_found = RCscan();
#ifdef MODULE
- return cards_found ? 0 : -ENODEV;
+ cards_found = RCscan(NULL);
#else
- return -1;
+ cards_found = RCscan(dev);
#endif
+ if (cards_found)
+ printk(version);
+ return cards_found ? 0 : -ENODEV;
}
-static int RCscan()
+static int RCscan(struct device *dev)
{
int cards_found = 0;
- struct device *dev = 0;
+ static int pci_index = 0;
+
+ if (!pcibios_present())
+ return cards_found;
- if (pcibios_present())
+ for (;pci_index < 0x8; pci_index++)
{
- static int pci_index = 0;
unsigned char pci_bus, pci_device_fn;
int scan_status;
int board_index = 0;
-
- for (;pci_index < 0xff; pci_index++)
- {
- unsigned char pci_irq_line;
- unsigned short pci_command, vendor, device, class;
- unsigned int pci_ioaddr;
+ unsigned char pci_irq_line;
+ unsigned short pci_command, vendor, device, class;
+ unsigned int pci_ioaddr;
- scan_status =
- (pcibios_find_device (RC_PCI45_VENDOR_ID,
- RC_PCI45_DEVICE_ID,
- pci_index,
- &pci_bus,
- &pci_device_fn));
+ scan_status =
+ (pcibios_find_device (RC_PCI45_VENDOR_ID,
+ RC_PCI45_DEVICE_ID,
+ pci_index,
+ &pci_bus,
+ &pci_device_fn));
#ifdef RCDEBUG
- printk("rc scan_status = 0x%X\n", scan_status);
+ printk("rc scan_status = 0x%X\n", scan_status);
#endif
- if (scan_status != PCIBIOS_SUCCESSFUL)
- break;
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_DEVICE_ID, &device);
- pcibios_read_config_byte(pci_bus,
- pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- pcibios_read_config_dword(pci_bus,
- pci_device_fn,
- PCI_BASE_ADDRESS_0, &pci_ioaddr);
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_CLASS_DEVICE, &class);
-
- pci_ioaddr &= ~0xf;
+ if (scan_status != PCIBIOS_SUCCESSFUL)
+ break;
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_VENDOR_ID, &vendor);
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_DEVICE_ID, &device);
+ pcibios_read_config_byte(pci_bus,
+ pci_device_fn,
+ PCI_INTERRUPT_LINE, &pci_irq_line);
+ pcibios_read_config_dword(pci_bus,
+ pci_device_fn,
+ PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_CLASS_DEVICE, &class);
+
+ pci_ioaddr &= ~0xf;
#ifdef RCDEBUG
- printk("rc: Found RedCreek PCI adapter\n");
- printk("rc: pci class = 0x%x 0x%x \n", class, class>>8);
- printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn);
- printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
- printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
+ printk("rc: Found RedCreek PCI adapter\n");
+ printk("rc: pci class = 0x%x 0x%x \n", class, class>>8);
+ printk("rc: pci_bus = %d, pci_device_fn = %d\n", pci_bus, pci_device_fn);
+ printk("rc: pci_irq_line = 0x%x \n", pci_irq_line);
+ printk("rc: pci_ioaddr = 0x%x\n", pci_ioaddr);
#endif
-#if 1
- if (check_region(pci_ioaddr, 2*32768))
- {
- printk("rc: check_region failed\n");
- continue;
- }
- else
- {
- printk("rc: check_region passed\n");
- }
+ if (check_region(pci_ioaddr, 2*32768))
+ {
+ printk("rc: check_region failed\n");
+ continue;
+ }
+#ifdef RCDEBUG
+ else
+ {
+ printk("rc: check_region passed\n");
+ }
#endif
-
+
+ /*
+ * Get and check the bus-master and latency values.
+ * Some PCI BIOSes fail to set the master-enable bit.
+ */
+
+ pcibios_read_config_word(pci_bus,
+ pci_device_fn,
+ PCI_COMMAND,
+ &pci_command);
+ if ( ! (pci_command & PCI_COMMAND_MASTER)) {
+ printk("rc: PCI Master Bit has not been set!\n");
+
+ pci_command |= PCI_COMMAND_MASTER;
+ pcibios_write_config_word(pci_bus,
+ pci_device_fn,
+ PCI_COMMAND,
+ pci_command);
+ }
+ if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
/*
- * Get and check the bus-master and latency values.
- * Some PCI BIOSes fail to set the master-enable bit.
+ * If the BIOS did not set the memory enable bit, what else
+ * did it not initialize? Skip this adapter.
*/
-
- pcibios_read_config_word(pci_bus,
- pci_device_fn,
- PCI_COMMAND,
- &pci_command);
- if ( ! (pci_command & PCI_COMMAND_MASTER)) {
- printk("rc: PCI Master Bit has not been set!\n");
-
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pci_bus,
- pci_device_fn,
- PCI_COMMAND,
- pci_command);
- }
- if ( ! (pci_command & PCI_COMMAND_MEMORY)) {
- /*
- * If the BIOS did not set the memory enable bit, what else
- * did it not initialize? Skip this adapter.
- */
- printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
- cards_found);
- printk("rc: Bios problem? \n");
- continue;
- }
-
- dev = RCfound_device(dev, pci_ioaddr, pci_irq_line,
- pci_bus, pci_device_fn,
- board_index++, cards_found);
-
- if (dev) {
- dev = 0;
- cards_found++;
- }
+ printk("rc: Adapter %d, PCI Memory Bit has not been set!\n",
+ cards_found);
+ printk("rc: Bios problem? \n");
+ continue;
+ }
+
+ if (!RCfound_device(dev, pci_ioaddr, pci_irq_line,
+ pci_bus, pci_device_fn,
+ board_index++, cards_found))
+ {
+ dev = 0;
+ cards_found++;
}
}
+#ifdef RCDEBUG
printk("rc: found %d cards \n", cards_found);
+#endif
return cards_found;
}
-static struct device *
+static int RCinit(struct device *dev)
+{
+ dev->open = &RCopen;
+ dev->hard_start_xmit = &RC_xmit_packet;
+ dev->stop = &RCclose;
+ dev->get_stats = &RCget_stats;
+ dev->do_ioctl = &RCioctl;
+ dev->set_config = &RCconfig;
+ return 0;
+}
+
+static int
RCfound_device(struct device *dev, int memaddr, int irq,
int bus, int function, int product_index, int card_idx)
{
* assigned to DPA; and finally, the rest will be assigned to the
* the LAN API layer.
*/
+
+#ifdef MODULE
dev = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+ if (!dev)
+ {
+ printk("rc: unable to kmalloc dev\n");
+ return 1;
+ }
memset(dev, 0, dev_size);
-#ifdef RCDEBUG
- printk("rc: dev = 0x%08X\n", (uint)dev);
-#endif
-
/*
* dev->priv will point to the start of DPA.
*/
dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
+#else
+ dev->priv = 0;
+ dev->priv = (struct device *) kmalloc(dev_size, GFP_DMA | GFP_KERNEL |GFP_ATOMIC);
+ if (!dev->priv)
+ {
+ printk("rc: unable to kmalloc private area\n");
+ return 1;
+ }
+ memset(dev->priv, 0, dev_size);
+#endif
+
+#ifdef RCDEBUG
+ printk("rc: dev = 0x%x, dev->priv = 0x%x\n", (uint)dev, (uint)dev->priv);
+#endif
+
pDpa = dev->priv;
- dev->name = pDpa->devname;
+ if (!dev->name)
+ dev->name = pDpa->devname;
pDpa->dev = dev; /* this is just for easy reference */
pDpa->function = function;
printk( "RC PCI 45: %s: unable to get IRQ %d\n", (PU8)dev->name, (uint)dev->irq );
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr,
- pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
- (PFNTXCALLBACK)RCxmit_callback,
- (PFNRXCALLBACK)RCrecv_callback,
- (PFNCALLBACK)RCreboot_callback);
-#ifdef RCDEBUG
- printk("rc: I2O msg initted: status = 0x%x\n", init_status);
-#endif
+ pDpa->PLanApiPA, (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+ (PFNTXCALLBACK)RCxmit_callback,
+ (PFNRXCALLBACK)RCrecv_callback,
+ (PFNCALLBACK)RCreboot_callback);
if (init_status)
{
printk("rc: Unable to initialize msg layer\n");
free_irq(dev->irq, dev);
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
if (RCGetMAC(pDpa->id, dev->dev_addr, NULL))
{
free_irq(dev->irq, dev);
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
DriverControlWord |= WARM_REBOOT_CAPABLE;
RCReportDriverCapability(pDpa->id, DriverControlWord);
- dev->init = RCprobe1;
+ dev->init = &RCinit;
ether_setup(dev); /* linux kernel interface */
pDpa->next = root_RCdev;
root_RCdev = dev;
+#ifdef MODULE
if (register_netdev(dev) != 0) /* linux kernel interface */
{
printk("rc: unable to register device \n");
free_irq(dev->irq, dev);
iounmap(vaddr);
kfree(dev);
- return 0;
+ return 1;
}
- return dev;
-}
+#else
+ RCinit(dev);
+#endif
+ printk("%s: RedCreek Communications IPSEC VPN adapter\n",
+ dev->name);
-static int RCprobe1(struct device *dev)
-{
- dev->open = RCopen;
- dev->hard_start_xmit = RC_xmit_packet;
- dev->stop = RCclose;
- dev->get_stats = RCget_stats;
- dev->do_ioctl = RCioctl;
- dev->set_config = RCconfig;
- return 0;
+ return 0; /* success */
}
static int
#ifdef RCDEBUG
printk("rc: RC_xmit_packet: tbusy!\n");
#endif
+ dev->tbusy = 1;
return 1;
}
RCShutdownLANCard(pDpa->id,0,0,0);
printk("rc: scheduling timer...\n");
init_timer(&pDpa->timer);
- pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
+ pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 4 sec. */
pDpa->timer.data = (unsigned long)dev;
pDpa->timer.function = &rc_timer; /* timer handler */
add_timer(&pDpa->timer);
if (!pDpa->shutdown && !pDpa->reboot)
printk("rc: RCrecv error: status = 0x%x\n", (uint)Status);
+#ifdef RCDEBUG
else
printk("rc: Returning %d buffers, status = 0x%x\n",
PktCount, (uint)Status);
+#endif
/*
* TO DO: check the nature of the failure and put the adapter in
* failed mode if it's a hard failure. Send a reset to the adapter
(uint)skb->data[0], (uint)skb->data[1], (uint)skb->data[2],
(uint)skb->data[3], (uint)skb->data[4], (uint)skb->data[5]);
#endif
+
+#ifdef PROMISCUOUS_BY_DEFAULT /* early 2.x firmware */
if ( (memcmp(dev->dev_addr, skb->data, 6)) &&
(!broadcast_packet(skb->data)))
{
}
}
else
+#endif /* PROMISCUOUS_BY_DEFAULT */
{
len = PacketDescBlock[2];
skb->dev = dev;
pDpa = (PDPA) (dev->priv);
+#ifdef RCDEBUG
if (pDpa->shutdown)
printk("rc: shutdown: service irq\n");
-#ifdef RCDEBUG
printk("RC irq: pDpa = 0x%x, dev = 0x%x, id = %d\n",
(uint)pDpa, (uint)dev, (uint)pDpa->id);
printk("dev = 0x%x\n", (uint)dev);
return;
}
-#define REBOOT_REINIT_RETRY_LIMIT 10
+
+#define REBOOT_REINIT_RETRY_LIMIT 4
static void rc_timer(unsigned long data)
{
struct device *dev = (struct device *)data;
if (pDpa->reboot)
{
-
init_status = RCInitI2OMsgLayer(pDpa->id, dev->base_addr,
- pDpa->PLanApiPA, pDpa->PLanApiPA,
- (PFNTXCALLBACK)RCxmit_callback,
- (PFNRXCALLBACK)RCrecv_callback,
- (PFNCALLBACK)RCreboot_callback);
+ pDpa->PLanApiPA,
+ (PU8)virt_to_bus((void *)pDpa->PLanApiPA),
+ (PFNTXCALLBACK)RCxmit_callback,
+ (PFNRXCALLBACK)RCrecv_callback,
+ (PFNCALLBACK)RCreboot_callback);
switch(init_status)
{
(uint)pDpa->numOutRcvBuffers);
}
printk("rc: Initialization done.\n");
+ dev->tbusy=0;
+ retry=0;
return;
case RC_RTN_FREE_Q_EMPTY:
retry++;
- printk("rc: inbound free q emtpy\n");
+ printk("rc: inbound free q empty\n");
break;
default:
retry++;
- printk("rc: unexpected bad status after reboot\n");
+ printk("rc: bad status after reboot: %d\n", init_status);
break;
}
{
printk("rc: rescheduling timer...\n");
init_timer(&pDpa->timer);
- pDpa->timer.expires = RUN_AT((30*HZ)/10); /* 3 sec. */
+ pDpa->timer.expires = RUN_AT((40*HZ)/10); /* 3 sec. */
pDpa->timer.data = (unsigned long)dev;
pDpa->timer.function = &rc_timer; /* timer handler */
add_timer(&pDpa->timer);
return 0;
}
+
+#ifdef MODULE
void
cleanup_module(void)
{
root_RCdev = next;
}
}
+#endif
+
static int
RC_allocate_and_post_buffers(struct device *dev, int numBuffers)
u8 data8;
priv->tlanFullDuplex = FALSE;
+ priv->phyOnline=0;
/* 1. Assert reset bit. */
data = inl(dev->base_addr + TLAN_HOST_CMD);
spin_lock_irqsave(&z8530_buffer_lock, flags);
c->netdevice->tbusy=0;
- /* Can't happen */
+ /* Actually this can happen.*/
if(c->tx_skb==NULL)
{
spin_unlock_irqrestore(&z8530_buffer_lock, flags);
- printk(KERN_WARNING "%s: spurious tx done\n", c->dev->name);
return;
}
skb=c->tx_skb;
#include <linux/wait.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
+#include <linux/interrupt.h>
#include "aha152x.h"
#include <linux/stat.h>
int ext_trans;
int swint;
+ int service;
unsigned char syncrate[8];
#endif
};
-void aha152x_intr(int irq, void *dev_id, struct pt_regs *);
+static void aha152x_intr(int irq, void *dev_id, struct pt_regs *);
void aha152x_done(struct Scsi_Host *shpnt, int error);
void aha152x_setup(char *str, int *ints);
int aha152x_checksetup(struct aha152x_setup *setup);
aha152x_panic(shpnt, "done() called outside of command");
}
+
+static void aha152x_complete(struct Scsi_Host *);
+
+static struct tq_struct aha152x_tq;
+
/*
- * Interrupts handler (main routine of the driver)
+ * Run service completions on the card with interrupts enabled.
*/
-void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs)
+
+static void aha152x_run(void)
{
- struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
- unsigned int flags;
- int done=0, phase;
+ int i;
+ for(i=0;i<IRQS;i++)
+ {
+ struct Scsi_Host *shpnt=aha152x_host[i];
+ if(shpnt && HOSTDATA(shpnt)->service)
+ {
+ HOSTDATA(shpnt)->service=0;
+ aha152x_complete(shpnt);
+ }
+ }
+}
+
+/*
+ * Interrupts handler (main routine of the driver)
+ */
+
+static void aha152x_intr(int irqno, void *dev_id, struct pt_regs * regs)
+{
+ struct Scsi_Host *shpnt = aha152x_host[irqno-IRQ_MIN];
#if defined(DEBUG_RACE)
- enter_driver("intr");
+ enter_driver("intr");
#else
#if defined(DEBUG_INTR)
- if(HOSTDATA(shpnt)->debug & debug_intr)
- printk("\naha152x: intr(), ");
+ if(HOSTDATA(shpnt)->debug & debug_intr)
+ printk("\naha152x: intr(), ");
#endif
#endif
- if(!shpnt)
- panic("aha152x: catched interrupt for unknown controller.\n");
-
- /* no more interrupts from the controller, while we're busy.
- INTEN has to be restored, when we're ready to leave
- intr(). To avoid race conditions, we have to return
- immediately afterwards. */
- CLRBITS(DMACNTRL0, INTEN);
- /* sti(); FIXME!!! Yes, sti() really needs to be here if we want to lock up */
-
- /* disconnected target is trying to reconnect.
- Only possible, if we have disconnected nexuses and
- nothing is occupying the bus.
- */
+ if(!shpnt)
+ panic("aha152x: catched interrupt for unknown controller.\n");
+
+ /* no more interrupts from the controller, while we're busy.
+ INTEN is restored by the BH handler */
+
+ CLRBITS(DMACNTRL0, INTEN);
+
+ /* Poke the BH handler */
+
+ HOSTDATA(shpnt)->service=1;
+ aha152x_tq.routine = (void *)aha152x_run;
+ queue_task(&aha152x_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
+
+static void aha152x_complete(struct Scsi_Host *shpnt)
+{
+ unsigned int flags;
+ int done=0, phase;
+
+ /* disconnected target is trying to reconnect.
+ Only possible, if we have disconnected nexuses and
+ nothing is occupying the bus.
+ */
+
if(TESTHI(SSTAT0, SELDI) &&
DISCONNECTED_SC &&
(!CURRENT_SC || (CURRENT_SC->SCp.phase & in_selection)) ) {
if (tmp == cmd) {
if (prev)
prev->host_scribble = cmd->host_scribble;
+ else
+ hostdata->input_Q = (Scsi_Cmnd *)cmd->host_scribble;
cmd->host_scribble = NULL;
cmd->result = DID_ABORT << 16;
printk("scsi%d: Abort - removing command %ld from input_Q. ",
#define io_Status(d) ((d)->base+2)
#define io_Polled_IO(d) ((d)->base+3)
+static struct {
+ unsigned char flags;
+#define CAP_F_TIMER 0x01
+} capabilities [9 /*devc->model */ ] = {
+ {0}
+ ,{0} /* MD_1848 */
+ ,{CAP_F_TIMER} /* MD_4231 */
+ ,{CAP_F_TIMER} /* MD_4231A */
+ ,{CAP_F_TIMER} /* MD_1845 */
+ ,{CAP_F_TIMER} /* MD_4232 */
+ ,{0} /* MD_C930 */
+ ,{CAP_F_TIMER} /* MD_IWAVE */
+ ,{0} /* MD_4235 */
+};
+
static int ad1848_open(int dev, int mode);
static void ad1848_close(int dev);
static void ad1848_output_block(int dev, unsigned long buf, int count, int intrflag);
/* Don't free it either then.. */
devc->irq = 0;
}
- if (devc->model != MD_1848 && devc->model != MD_C930)
+ if (capabilities[devc->model].flags & CAP_F_TIMER)
{
#ifndef __SMP__
int x;
irq2dev[-irq] = devc->dev_no = my_dev;
#if defined(CONFIG_SEQUENCER) && !defined(EXCLUDE_TIMERS)
- if (devc->model != MD_1848 &&
- devc->model != MD_C930 && devc->irq_ok)
+ if ((capabilities[devc->model].flags & CAP_F_TIMER) &&
+ devc->irq_ok)
ad1848_tmr_install(my_dev);
#endif
else
return audio_devs[dev]->local_format;
- return audio_devs[dev]->local_format;
+ if (audio_devs[dev]->local_conversion)
+ return audio_devs[dev]->local_conversion;
+ else
+ return audio_devs[dev]->local_format;
}
int audio_open(int dev, struct file *file)
return 0;
case SNDCTL_DSP_GETFMTS:
- val = audio_devs[dev]->format_mask;
+ val = audio_devs[dev]->format_mask | AFMT_MU_LAW;
break;
case SNDCTL_DSP_SETFMT:
memset((char *) op, 0, sizeof(struct audio_operations));
init_waitqueue(&op->in_sleeper);
init_waitqueue(&op->out_sleeper);
+ init_waitqueue(&op->poll_sleeper);
if (driver_size < sizeof(struct audio_driver))
memset((char *) d, 0, sizeof(struct audio_driver));
/* fields formerly in dmabuf.c */
struct wait_queue *in_sleeper;
struct wait_queue *out_sleeper;
+ struct wait_queue *poll_sleeper;
/* fields formerly in audio.c */
int audio_mode;
if (dmap->audio_callback != NULL)
dmap->audio_callback(dev, dmap->callback_parm);
wake_up(&adev->out_sleeper);
+ wake_up(&adev->poll_sleeper);
}
static void do_outputintr(int dev, int dummy)
}
dmap->flags |= DMA_ACTIVE;
if (dmap->qlen > 0)
+ {
wake_up(&adev->in_sleeper);
+ wake_up(&adev->poll_sleeper);
+ }
}
void DMAbuf_inputintr(int dev)
if (!(adev->open_mode & OPEN_READ))
return 0;
if (dmap->mapping_flags & DMA_MAP_MAPPED) {
- poll_wait(file, &adev->in_sleeper, wait);
if (dmap->qlen)
return POLLIN | POLLRDNORM;
return 0;
!dmap->qlen && adev->go) {
unsigned long flags;
- poll_wait(file, &adev->in_sleeper, wait);
save_flags(flags);
cli();
DMAbuf_activate_recording(dev, dmap);
}
return 0;
}
- poll_wait(file, &adev->in_sleeper, wait);
if (!dmap->qlen)
return 0;
return POLLIN | POLLRDNORM;
if (!(adev->open_mode & OPEN_WRITE))
return 0;
if (dmap->mapping_flags & DMA_MAP_MAPPED) {
- poll_wait(file, &adev->out_sleeper, wait);
if (dmap->qlen)
return POLLOUT | POLLWRNORM;
return 0;
}
if (dmap->dma_mode == DMODE_INPUT)
return 0;
- poll_wait(file, &adev->out_sleeper, wait);
if (dmap->dma_mode == DMODE_NONE)
return POLLOUT | POLLWRNORM;
if (!DMAbuf_space_in_queue(dev))
unsigned int DMAbuf_poll(struct file * file, int dev, poll_table *wait)
{
+ struct audio_operations *adev = audio_devs[dev];
+ poll_wait(file, &adev->poll_sleeper, wait);
return poll_input(file, dev, wait) | poll_output(file, dev, wait);
}
/*
* es1370.c -- Ensoniq ES1370/Asahi Kasei AK4531 audio driver.
*
- * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* reported by Johan Maes <joma@telindus.be>
* 22.03.99 0.19 return EAGAIN instead of EBUSY when O_NONBLOCK
* read/write cannot be executed
+ * 07.04.99 0.20 implemented the following ioctl's: SOUND_PCM_READ_RATE,
+ * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS;
+ * Alpha fixes reported by Peter Jones <pjones@redhat.com>
+ * Note: joystick address handling might still be wrong on archs
+ * other than i386
*
* some important things missing in Ensoniq documentation:
*
int dev_midi;
/* hardware resources */
- unsigned int io, irq;
+ unsigned long io; /* long for SPARC */
+ unsigned int irq;
/* mixer registers; there is no HW readback */
struct {
s->dma_dac2.subdivision = val;
return 0;
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_RATE:
+ return put_user(DAC2_DIVTOSR((s->ctrl & CTRL_PCLKDIV) >> CTRL_SH_PCLKDIV), (int *)arg);
+
case SOUND_PCM_READ_CHANNELS:
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ?
+ 2 : 1, (int *)arg);
+
case SOUND_PCM_READ_BITS:
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ?
+ 16 : 8, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_FILTER:
return -EINVAL;
s->dma_dac1.subdivision = val;
return 0;
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_RATE:
+ return put_user(dac1_samplerate[(s->ctrl & CTRL_WTSRSEL) >> CTRL_SH_WTSRSEL], (int *)arg);
+
case SOUND_PCM_READ_CHANNELS:
+ return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+
case SOUND_PCM_READ_BITS:
+ return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_FILTER:
return -EINVAL;
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "es1370: version v0.19 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "es1370: version v0.20 time " __TIME__ " " __DATE__ "\n");
while (index < NR_DEVICE &&
(pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1370, pcidev))) {
if (pcidev->base_address[0] == 0 ||
s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
s->irq = pcidev->irq;
if (check_region(s->io, ES1370_EXTENT)) {
- printk(KERN_ERR "es1370: io ports %#x-%#x in use\n", s->io, s->io+ES1370_EXTENT-1);
+ printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1);
goto err_region;
}
request_region(s->io, ES1370_EXTENT, "es1370");
if (micz[index])
s->ctrl |= CTRL_XCTL1;
s->sctrl = 0;
- printk(KERN_INFO "es1370: found adapter at io %#06x irq %u\n"
+ printk(KERN_INFO "es1370: found adapter at io %#lx irq %u\n"
KERN_INFO "es1370: features: joystick %s, line %s, mic impedance %s\n",
s->io, s->irq, (s->ctrl & CTRL_JYSTK_EN) ? "on" : "off",
(s->ctrl & CTRL_XCTL0) ? "out" : "in",
* reported by Johan Maes <joma@telindus.be>
* 22.03.99 0.10 return EAGAIN instead of EBUSY when O_NONBLOCK
* read/write cannot be executed
+ * 07.04.99 0.11 implemented the following ioctl's: SOUND_PCM_READ_RATE,
+ * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS;
+ * Alpha fixes reported by Peter Jones <pjones@redhat.com>
+ * Another Alpha fix (wait_src_ready in init routine)
+ * reported by "Ivan N. Kokshaysky" <ink@jurassic.park.msu.ru>
+ * Note: joystick address handling might still be wrong on archs
+ * other than i386
*
*/
int dev_midi;
/* hardware resources */
- unsigned int io, irq;
+ unsigned long io; /* long for SPARC */
+ unsigned int irq;
/* mixer registers; there is no HW readback */
struct {
s->dma_dac2.subdivision = val;
return 0;
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_RATE:
+ return put_user((file->f_mode & FMODE_READ) ? s->adcrate : s->dac2rate, (int *)arg);
+
case SOUND_PCM_READ_CHANNELS:
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SMB : SCTRL_P2SMB)) ? 2 : 1, (int *)arg);
+
case SOUND_PCM_READ_BITS:
+ return put_user((s->sctrl & ((file->f_mode & FMODE_READ) ? SCTRL_R1SEB : SCTRL_P2SEB)) ? 16 : 8, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_FILTER:
return -EINVAL;
s->dma_dac1.subdivision = val;
return 0;
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_RATE:
+ return put_user(s->dac1rate, (int *)arg);
+
case SOUND_PCM_READ_CHANNELS:
+ return put_user((s->sctrl & SCTRL_P1SMB) ? 2 : 1, (int *)arg);
+
case SOUND_PCM_READ_BITS:
+ return put_user((s->sctrl & SCTRL_P1SEB) ? 16 : 8, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_FILTER:
return -EINVAL;
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "es1371: version v0.10 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "es1371: version v0.11 time " __TIME__ " " __DATE__ "\n");
while (index < NR_DEVICE &&
(pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) {
if (pcidev->base_address[0] == 0 ||
s->io = pcidev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
s->irq = pcidev->irq;
if (check_region(s->io, ES1371_EXTENT)) {
- printk(KERN_ERR "es1371: io ports %#x-%#x in use\n", s->io, s->io+ES1371_EXTENT-1);
+ printk(KERN_ERR "es1371: io ports %#lx-%#lx in use\n", s->io, s->io+ES1371_EXTENT-1);
goto err_region;
}
request_region(s->io, ES1371_EXTENT, "es1371");
printk(KERN_ERR "es1371: irq %u in use\n", s->irq);
goto err_irq;
}
- printk(KERN_INFO "es1371: found adapter at io %#06x irq %u\n"
+ printk(KERN_INFO "es1371: found adapter at io %#lx irq %u\n"
KERN_INFO "es1371: features: joystick 0x%x\n", s->io, s->irq, joystick[index]);
/* register devices */
if ((s->dev_audio = register_sound_dsp(&es1371_audio_fops, -1)) < 0)
* be stuck high, and I've found no way to rectify this other than
* power cycle)
*/
+ wait_src_ready(s);
outl(0, s->io+ES1371_REG_SRCONV);
/* codec init */
wrcodec(s, 0x00, 0); /* reset codec */
#define MDL_ES1868MIDI 14 /* MIDI port of ESS1868 */
#define MDL_AEDSP 15 /* Audio Excel DSP 16 */
#define MDL_ESSPCI 16 /* ESS PCI card */
+#define MDL_YMPCI 17 /* Yamaha PCI sb in emulation */
#define SUBMDL_ALS007 42 /* ALS-007 differs from SB16 only in mixer */
/* register assignment */
EXPORT_SYMBOL(probe_sb);
EXPORT_SYMBOL(unload_sb);
EXPORT_SYMBOL(sb_be_quiet);
+EXPORT_SYMBOL(attach_sbmpu);
+EXPORT_SYMBOL(probe_sbmpu);
+EXPORT_SYMBOL(unload_sbmpu);
#endif
}
}
}
- DDB(printk("DSP version %d.%d\n", devc->major, devc->minor));
+ DDB(printk("DSP version %d.%02d\n", devc->major, devc->minor));
restore_flags(flags);
}
if(pci == SB_PCI_YAMAHA)
{
+ devc->model = MDL_YMPCI;
devc->caps |= SB_PCI_IRQ;
hw_config->driver_use_1 |= SB_PCI_IRQ;
+ hw_config->card_subtype = MDL_YMPCI;
+
+ printk("Yamaha PCI mode.\n");
}
if (acer)
if(devc->type == MDL_ESSPCI)
devc->model = MDL_ESSPCI;
+ if(devc->type == MDL_YMPCI)
+ {
+ printk("YMPCI selected\n");
+ devc->model = MDL_YMPCI;
+ }
+
/*
* Save device information for sb_dsp_init()
*/
return 0;
}
memcpy((char *) detected_devc, (char *) devc, sizeof(sb_devc));
- MDB(printk(KERN_INFO "SB %d.%d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));
+ MDB(printk(KERN_INFO "SB %d.%02d detected OK (%x)\n", devc->major, devc->minor, hw_config->io_base));
return 1;
}
devc->caps = hw_config->driver_use_1;
- if (!(devc->caps & SB_NO_AUDIO && devc->caps & SB_NO_MIDI) && hw_config->irq > 0)
+ if (!((devc->caps & SB_NO_AUDIO) && (devc->caps & SB_NO_MIDI)) && hw_config->irq > 0)
{ /* IRQ setup */
/*
if (hw_config->name == NULL)
hw_config->name = "Sound Blaster (8 BIT/MONO ONLY)";
- sprintf(name, "%s (%d.%d)", hw_config->name, devc->major, devc->minor);
+ sprintf(name, "%s (%d.%02d)", hw_config->name, devc->major, devc->minor);
conf_printf(name, hw_config);
/*
}
else if (!sb_be_quiet && devc->model == MDL_SBPRO)
{
- printk(KERN_INFO "SB DSP version is just %d.%d which means that your card is\n", devc->major, devc->minor);
+ printk(KERN_INFO "SB DSP version is just %d.%02d which means that your card is\n", devc->major, devc->minor);
printk(KERN_INFO "several years old (8 bit only device) or alternatively the sound driver\n");
printk(KERN_INFO "is incorrectly configured.\n");
}
return 0;
break;
+ case MDL_YMPCI:
+ hw_config->name = "Yamaha PCI Legacy";
+ printk("Yamaha PCI legacy UART401 check.\n");
+ break;
default:
return 0;
}
switch (devc->model)
{
case MDL_ESSPCI:
+ case MDL_YMPCI:
case MDL_SBPRO:
case MDL_AZTECH:
case MDL_JAZZ:
/*
* sonicvibes.c -- S3 Sonic Vibes audio driver.
*
- * Copyright (C) 1998 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ * Copyright (C) 1998-1999 Thomas Sailer (sailer@ife.ee.ethz.ch)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* reported by Johan Maes <joma@telindus.be>
* 22.03.99 0.12 return EAGAIN instead of EBUSY when O_NONBLOCK
* read/write cannot be executed
+ * 05.04.99 0.13 added code to sv_read and sv_write which should detect
+ * lockups of the sound chip and revive it. This is basically
+ * an ugly hack, but at least applications using this driver
+ * won't hang forever. I don't know why these lockups happen,
+ * it might well be the motherboard chipset (an early 486 PCI
+ * board with ALI chipset), since every busmastering 100MB
+ * ethernet card I've tried (Realtek 8139 and Macronix tulip clone)
+ * exhibit similar behaviour (they work for a couple of packets
+ * and then lock up and can be revived by ifconfig down/up).
+ * 07.04.99 0.14 implemented the following ioctl's: SOUND_PCM_READ_RATE,
+ * SOUND_PCM_READ_CHANNELS, SOUND_PCM_READ_BITS;
+ * Alpha fixes reported by Peter Jones <pjones@redhat.com>
+ * Note: dmaio hack might still be wrong on archs other than i386
*
*/
int dev_dmfm;
/* hardware resources */
- unsigned int iosb, ioenh, iosynth, iomidi, iogame, iodmaa, iodmac, irq;
+ unsigned long iosb, ioenh, iosynth, iomidi, iogame; /* long for SPARC */
+ unsigned int iodmaa, iodmac, irq;
/* mixer stuff */
struct {
start_adc(s);
if (file->f_flags & O_NONBLOCK)
return ret ? ret : -EAGAIN;
- interruptible_sleep_on(&s->dma_adc.wait);
+ if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {
+ printk(KERN_DEBUG "sv: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+ s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count,
+ s->dma_adc.hwptr, s->dma_adc.swptr);
+ stop_adc(s);
+ spin_lock_irqsave(&s->lock, flags);
+ set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);
+ /* program enhanced mode registers */
+ wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);
+ wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1);
+ s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;
+ spin_unlock_irqrestore(&s->lock, flags);
+ }
if (signal_pending(current))
return ret ? ret : -ERESTARTSYS;
continue;
start_dac(s);
if (file->f_flags & O_NONBLOCK)
return ret ? ret : -EAGAIN;
- interruptible_sleep_on(&s->dma_dac.wait);
+ if (!interruptible_sleep_on_timeout(&s->dma_dac.wait, HZ)) {
+ printk(KERN_DEBUG "sv: write: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+ s->dma_dac.dmasize, s->dma_dac.fragsize, s->dma_dac.count,
+ s->dma_dac.hwptr, s->dma_dac.swptr);
+ stop_dac(s);
+ spin_lock_irqsave(&s->lock, flags);
+ set_dmaa(s, virt_to_bus(s->dma_dac.rawbuf), s->dma_dac.numfrag << s->dma_dac.fragshift);
+ /* program enhanced mode registers */
+ wrindir(s, SV_CIDMAABASECOUNT1, (s->dma_dac.fragsamples-1) >> 8);
+ wrindir(s, SV_CIDMAABASECOUNT0, s->dma_dac.fragsamples-1);
+ s->dma_dac.count = s->dma_dac.hwptr = s->dma_dac.swptr = 0;
+ spin_unlock_irqrestore(&s->lock, flags);
+ }
if (signal_pending(current))
return ret ? ret : -ERESTARTSYS;
continue;
s->dma_dac.subdivision = val;
return 0;
- case SOUND_PCM_WRITE_FILTER:
- case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_RATE:
+ return put_user((file->f_mode & FMODE_READ) ? s->rateadc : s->ratedac, (int *)arg);
+
case SOUND_PCM_READ_CHANNELS:
+ return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_STEREO << SV_CFMT_CSHIFT)
+ : (SV_CFMT_STEREO << SV_CFMT_ASHIFT))) ? 2 : 1, (int *)arg);
+
case SOUND_PCM_READ_BITS:
+ return put_user((s->fmt & ((file->f_mode & FMODE_READ) ? (SV_CFMT_16BIT << SV_CFMT_CSHIFT)
+ : (SV_CFMT_16BIT << SV_CFMT_ASHIFT))) ? 16 : 8, (int *)arg);
+
+ case SOUND_PCM_WRITE_FILTER:
+ case SNDCTL_DSP_SETSYNCRO:
case SOUND_PCM_READ_FILTER:
return -EINVAL;
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
- printk(KERN_INFO "sv: version v0.12 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "sv: version v0.14 time " __TIME__ " " __DATE__ "\n");
#if 0
if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
}
pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */
pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */
- printk(KERN_DEBUG "sv: io ports: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#lx %#x %#x\n",
s->iosb, s->ioenh, s->iosynth, s->iomidi, s->iogame, s->iodmaa, s->iodmac);
if (s->ioenh == 0 || s->iodmaa == 0 || s->iodmac == 0)
continue;
pci_write_config_dword(pcidev, 0x60, wavetable_mem >> 12); /* wavetable base address */
if (check_region(s->ioenh, SV_EXTENT_ENH)) {
- printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1);
+ printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->ioenh, s->ioenh+SV_EXTENT_ENH-1);
goto err_region5;
}
request_region(s->ioenh, SV_EXTENT_ENH, "S3 SonicVibes PCM");
}
request_region(s->iodmac, SV_EXTENT_DMA, "S3 SonicVibes DMAC");
if (check_region(s->iomidi, SV_EXTENT_MIDI)) {
- printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1);
+ printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iomidi, s->iomidi+SV_EXTENT_MIDI-1);
goto err_region2;
}
request_region(s->iomidi, SV_EXTENT_MIDI, "S3 SonicVibes Midi");
if (check_region(s->iosynth, SV_EXTENT_SYNTH)) {
- printk(KERN_ERR "sv: io ports %#x-%#x in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1);
+ printk(KERN_ERR "sv: io ports %#lx-%#lx in use\n", s->iosynth, s->iosynth+SV_EXTENT_SYNTH-1);
goto err_region1;
}
request_region(s->iosynth, SV_EXTENT_SYNTH, "S3 SonicVibes Synth");
printk(KERN_ERR "sv: irq %u in use\n", s->irq);
goto err_irq;
}
- printk(KERN_INFO "sv: found adapter at io %#06x irq %u dmaa %#06x dmac %#06x revision %u\n",
+ printk(KERN_INFO "sv: found adapter at io %#lx irq %u dmaa %#06x dmac %#06x revision %u\n",
s->ioenh, s->irq, s->iodmaa, s->iodmac, rdindir(s, SV_CIREVISION));
/* register devices */
if ((s->dev_audio = register_sound_dsp(&sv_audio_fops, -1)) < 0)
mpu_config.irq = mpu_irq;
mpu_config.io_base = mpu_io;
-
+ /* WEH - Try to get right dma channel */
+ mpu_config.dma = dma;
+
if(spea != -1)
{
old_hardware = spea;
/* Clear the capabilities if we switch to a non-root user */
if (current->uid)
cap_clear(current->cap_effective);
-
+ else
+ current->cap_effective = current->cap_permitted;
+
dentry = namei(filename);
res = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
res = permission(dentry->d_inode, mode);
+ /* SuS v2 requires we report a read only fs too */
+ if(!res && (mode & S_IWOTH) && IS_RDONLY(dentry->d_inode))
+ res = -EROFS;
dput(dentry);
}
path = tmp;
} else {
path = d_path(dentry, tmp, PAGE_SIZE);
- len = tmp + PAGE_SIZE - path;
+ len = tmp + PAGE_SIZE - 1 - path;
}
if (len < buflen)
static void killseg (int id);
static void shm_open (struct vm_area_struct *shmd);
static void shm_close (struct vm_area_struct *shmd);
-static pte_t shm_swap_in(struct vm_area_struct *, unsigned long, unsigned long);
+static unsigned long shm_nopage(struct vm_area_struct *, unsigned long, int);
+static int shm_swapout(struct vm_area_struct *, struct page *);
static int shm_tot = 0; /* total number of shared memory pages */
static int shm_rss = 0; /* number of shared memory pages that are in memory */
NULL, /* protect */
NULL, /* sync */
NULL, /* advise */
- NULL, /* nopage (done with swapin) */
+ shm_nopage, /* nopage */
NULL, /* wppage */
- NULL, /* swapout (hardcoded right now) */
- shm_swap_in /* swapin */
+ shm_swapout, /* swapout */
+ NULL /* swapin */
};
/* Insert shmd into the list shp->attaches */
*/
static int shm_map (struct vm_area_struct *shmd)
{
- pgd_t *page_dir;
- pmd_t *page_middle;
- pte_t *page_table;
- unsigned long tmp, shm_sgn;
- int error;
+ unsigned long tmp;
/* clear old mappings */
do_munmap(shmd->vm_start, shmd->vm_end - shmd->vm_start);
insert_vm_struct(current->mm, shmd);
merge_segments(current->mm, shmd->vm_start, shmd->vm_end);
- /* map page range */
- error = 0;
- shm_sgn = shmd->vm_pte +
- SWP_ENTRY(0, (shmd->vm_offset >> PAGE_SHIFT) << SHM_IDX_SHIFT);
- flush_cache_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end);
- for (tmp = shmd->vm_start;
- tmp < shmd->vm_end;
- tmp += PAGE_SIZE, shm_sgn += SWP_ENTRY(0, 1 << SHM_IDX_SHIFT))
- {
- page_dir = pgd_offset(shmd->vm_mm,tmp);
- page_middle = pmd_alloc(page_dir,tmp);
- if (!page_middle) {
- error = -ENOMEM;
- break;
- }
- page_table = pte_alloc(page_middle,tmp);
- if (!page_table) {
- error = -ENOMEM;
- break;
- }
- set_pte(page_table, __pte(shm_sgn));
- }
- flush_tlb_range(shmd->vm_mm, shmd->vm_start, shmd->vm_end);
- return error;
+ return 0;
}
/*
return 0;
}
+/*
+ * Enter the shm page into the SHM data structures.
+ *
+ * The way "nopage" is done, we don't actually have to
+ * do anything here: nopage will have filled in the shm
+ * data structures already, and shm_swap_out() will just
+ * work off them..
+ */
+static int shm_swapout(struct vm_area_struct * vma, struct page * page)
+{
+ return 0;
+}
+
/*
* page not present ... go through shm_pages
*/
-static pte_t shm_swap_in(struct vm_area_struct * shmd, unsigned long offset, unsigned long code)
+static unsigned long shm_nopage(struct vm_area_struct * shmd, unsigned long address, int no_share)
{
pte_t pte;
struct shmid_kernel *shp;
unsigned int id, idx;
- id = SWP_OFFSET(code) & SHM_ID_MASK;
+ id = SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK;
+ idx = (address - shmd->vm_start + shmd->vm_offset) >> PAGE_SHIFT;
+
#ifdef DEBUG_SHM
- if (id != (SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK)) {
- printk ("shm_swap_in: code id = %d and shmd id = %ld differ\n",
- id, SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK);
- return BAD_PAGE;
- }
if (id > max_shmid) {
- printk ("shm_swap_in: id=%d too big. proc mem corrupted\n", id);
- return BAD_PAGE;
+ printk ("shm_nopage: id=%d too big. proc mem corrupted\n", id);
+ return 0;
}
#endif
shp = shm_segs[id];
#ifdef DEBUG_SHM
if (shp == IPC_UNUSED || shp == IPC_NOID) {
- printk ("shm_swap_in: id=%d invalid. Race.\n", id);
- return BAD_PAGE;
- }
-#endif
- idx = (SWP_OFFSET(code) >> SHM_IDX_SHIFT) & SHM_IDX_MASK;
-#ifdef DEBUG_SHM
- if (idx != (offset >> PAGE_SHIFT)) {
- printk ("shm_swap_in: code idx = %u and shmd idx = %lu differ\n",
- idx, offset >> PAGE_SHIFT);
- return BAD_PAGE;
+ printk ("shm_nopage: id=%d invalid. Race.\n", id);
+ return 0;
}
if (idx >= shp->shm_npages) {
- printk ("shm_swap_in : too large page index. id=%d\n", id);
- return BAD_PAGE;
+ printk ("shm_nopage : too large page index. id=%d\n", id);
+ return 0;
}
#endif
unsigned long page = get_free_page(GFP_KERNEL);
if (!page) {
oom(current);
- return BAD_PAGE;
+ return 0;
}
pte = __pte(shp->shm_pages[idx]);
if (pte_present(pte)) {
done: /* pte_val(pte) == shp->shm_pages[idx] */
current->min_flt++;
atomic_inc(&mem_map[MAP_NR(pte_page(pte))].count);
- return pte_modify(pte, shmd->vm_page_prot);
+ return pte_page(pte);
}
/*
{
pte_t page;
struct shmid_kernel *shp;
- struct vm_area_struct *shmd;
unsigned long swap_nr;
unsigned long id, idx;
int loop = 0;
swap_free (swap_nr);
return 0;
}
- if (shp->attaches)
- for (shmd = shp->attaches; ; ) {
- do {
- pgd_t *page_dir;
- pmd_t *page_middle;
- pte_t *page_table, pte;
- unsigned long tmp;
-
- if ((SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK) != id) {
- printk ("shm_swap: id=%ld does not match shmd->vm_pte.id=%ld\n",
- id, SWP_OFFSET(shmd->vm_pte) & SHM_ID_MASK);
- continue;
- }
- tmp = shmd->vm_start + (idx << PAGE_SHIFT) - shmd->vm_offset;
- if (!(tmp >= shmd->vm_start && tmp < shmd->vm_end))
- continue;
- page_dir = pgd_offset(shmd->vm_mm,tmp);
- if (pgd_none(*page_dir) || pgd_bad(*page_dir)) {
- printk("shm_swap: bad pgtbl! id=%ld start=%lx idx=%ld\n",
- id, shmd->vm_start, idx);
- pgd_clear(page_dir);
- continue;
- }
- page_middle = pmd_offset(page_dir,tmp);
- if (pmd_none(*page_middle) || pmd_bad(*page_middle)) {
- printk("shm_swap: bad pgmid! id=%ld start=%lx idx=%ld\n",
- id, shmd->vm_start, idx);
- pmd_clear(page_middle);
- continue;
- }
- page_table = pte_offset(page_middle,tmp);
- pte = *page_table;
- if (!pte_present(pte))
- continue;
- if (pte_young(pte)) {
- set_pte(page_table, pte_mkold(pte));
- continue;
- }
- if (pte_page(pte) != pte_page(page))
- printk("shm_swap_out: page and pte mismatch %lx %lx\n",
- pte_page(pte),pte_page(page));
- flush_cache_page(shmd, tmp);
- set_pte(page_table,
- __pte(shmd->vm_pte + SWP_ENTRY(0, idx << SHM_IDX_SHIFT)));
- atomic_dec(&mem_map[MAP_NR(pte_page(pte))].count);
- if (shmd->vm_mm->rss > 0)
- shmd->vm_mm->rss--;
- flush_tlb_page(shmd, tmp);
- /* continue looping through the linked list */
- } while (0);
- shmd = shmd->vm_next_share;
- if (!shmd)
- break;
- }
-
if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) != 1)
goto check_table;
shp->shm_pages[idx] = swap_nr;
return 0;
}
if (!pte_none(*pte)) {
- printk("put_dirty_page: page already exists\n");
+ printk("put_dirty_page: pte %08lx already exists\n",
+ pte_val(*pte));
free_page(page);
return 0;
}
if (!prev)
goto no_mmaps;
if (prev->vm_end > start) {
- if (last > prev->vm_end)
- last = prev->vm_end;
+ if (last > prev->vm_start)
+ last = prev->vm_start;
goto no_mmaps;
}
}
lapb g4klx@g4klx.demon.co.uk
netrom g4klx@g4klx.demon.co.uk
rose g4klx@g4klx.demon.co.uk
-wanrouter genek@compuserve.com and dm@sangoma.com
+wanrouter gene@compuserve.com, jaspreet@sangoma and dm@sangoma.com
unix alan@lxorguk.ukuu.org.uk
x25 g4klx@g4klx.demon.co.uk
skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
+ skb->protocol = htons(ETH_P_ATALK);
+ skb->nh.raw = skb->h.raw = (void *) eah;
skb->dev = dev;
/*
skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
+ skb->protocol = htons(ETH_P_ATALK);
+ skb->nh.raw = skb->h.raw = (void *) eah;
skb->dev = dev;
/*
skb_reserve(skb,dev->hard_header_len+aarp_dl->header_length);
eah = (struct elapaarp *)skb_put(skb,sizeof(struct elapaarp));
-
+ skb->protocol = htons(ETH_P_ATALK);
+ skb->nh.raw = skb->h.raw = (void *) eah;
skb->dev = dev;
/*
aarp_expire_timer(&unresolved[ct]);
aarp_expire_timer(&proxies[ct]);
}
- del_timer(&aarp_timer);
- if(unresolved_count==0)
- aarp_timer.expires=jiffies+sysctl_aarp_expiry_time;
- else
- aarp_timer.expires=jiffies+sysctl_aarp_tick_time;
- add_timer(&aarp_timer);
+
+ mod_timer(&aarp_timer, jiffies +
+ (unresolved_count ? sysctl_aarp_tick_time:
+ sysctl_aarp_expiry_time));
}
/*
if(unresolved_count==1)
{
- del_timer(&aarp_timer);
- aarp_timer.expires=jiffies+sysctl_aarp_tick_time;
- add_timer(&aarp_timer);
+ mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time);
}
/*
aarp_resolved(&unresolved[hash],a,hash);
if(unresolved_count==0)
{
- del_timer(&aarp_timer);
- aarp_timer.expires=jiffies+sysctl_aarp_expiry_time;
- add_timer(&aarp_timer);
+ mod_timer(&aarp_timer, jiffies +
+ sysctl_aarp_expiry_time);
}
break;